gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, num-handler, updated. gawk-4.1.0-1272-ga


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, num-handler, updated. gawk-4.1.0-1272-ga2ab9ea
Date: Sun, 05 Apr 2015 10:18:12 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, num-handler has been updated
       via  a2ab9ea617584b92b670c528542fdde10a209457 (commit)
       via  be546b6b216912cb21b72a8f777e313b818f3e03 (commit)
       via  dbf9d5a4fc4b6d6340912395f020019576ed37f6 (commit)
       via  e7ee504434e315852ebd449e20d72929de63cfe6 (commit)
       via  f82aa0619d803ebe0dc1710edf1a3e108a4210c8 (commit)
       via  ddc290584b39bab2c1edcec935a31ea12d343246 (commit)
       via  902b25a40d5cc612dd7a0becb27a5a48afa49716 (commit)
       via  9730efeabb2116fdf7e93b4553825ba147f5f523 (commit)
       via  c3d61778cf747143535320affee0612c4c6d4eb8 (commit)
       via  0ed7e09458bdb6185586a8a0bec747b2f800ca16 (commit)
       via  67d5cc4c4034f16a2390e30d8e988713e5aedb68 (commit)
       via  a47af3141cf4a6b43e20db872e2b45ff9abb071f (commit)
       via  2bdaa6b89e00984d79305ba1066cf98c5674b556 (commit)
       via  2ee1a928483f4fe4f594aebc5c1f8da1253c28b9 (commit)
       via  7d3d7d27391db40c0561ea47e6b8a5a1ae24c6fb (commit)
       via  9d43b510f74f63806279ce40f65245ea7e5b0d53 (commit)
       via  bc1c92f4a9365f799c9c7a78b41a4eb1c40326b7 (commit)
       via  7377dd1648a06b68f45c55fd54e07e6bcf29e66c (commit)
       via  90e1d42a99178608ec22216f7f35dadcad5a8b3a (commit)
       via  6522e5b623e083565229dc742336219a0dda1344 (commit)
       via  0bb831721d3feeac20977e5a14be6b5bbf13e52a (commit)
       via  080694ae82635e76992158591b39a06af7363da0 (commit)
       via  75459887958f5246bc5126261ec92c8f4d366a47 (commit)
       via  02856054ac25477e5913bdee1632d8cb11a184cd (commit)
       via  56e848ab0b55cc98f206ab7e187ba8269f2e8e4c (commit)
       via  981e106b111672aac520fbb397ee82c64f3c4f2a (commit)
       via  a31a42403b841ef05ca9143a431c8b6f1021a958 (commit)
       via  59514868fde1190f719e78d4c4b91bd14a321541 (commit)
       via  480aca31c7772dafeb1b97cd7a768bca2f49d3c7 (commit)
       via  925f9363c4b0a5bb9375298afcdcf404efb32587 (commit)
       via  e0c1194c4348e7adf99802461d45e3dd1bd192ff (commit)
       via  cd2ff61aaf4938092517880ad7655828d99a3cb9 (commit)
       via  cffd09247c1681fbf3d5cad5253b3199704f83e7 (commit)
       via  1b047a42077ca58eeeaa93e0561c0b589350702b (commit)
       via  822d727b719ad486bb5eca0f064c69047a424bf5 (commit)
       via  93a817e1d94bf7227391b131b6df2d1f3e5176cc (commit)
       via  36bf73d7bacb7e38598ce194315dce896a2847a3 (commit)
       via  8c76e6abfa7857da0ecb64cc545b5cbea2a0ca68 (commit)
       via  b6c957dae27d5f10393572391c75c51c85a3a68c (commit)
       via  6965b92f1bc3d5aca7a39d31cc6a7e5fd0e0c1a9 (commit)
       via  dae49acd6f32a875fed4781f33a926f8013c69b4 (commit)
       via  f001d6b9b3e53b3148d2cfe39746ccea90b8fdeb (commit)
       via  6237311c0af460dd0ff5cf2ed4f935a33386375c (commit)
       via  b108a3ba2ab12dd7274589c6fe09c882df02827c (commit)
       via  116c2da32b8a0dd2ab36e273d980696a1db1109b (commit)
       via  4e3f36b3b90aad7c5f392cd493ec10dbad567ce8 (commit)
       via  b8ba9836e05eb96daeed9614f045f5b81a826730 (commit)
       via  9b995ad21b921a502c7c94b3c591735e4f713728 (commit)
       via  8954618d1958e26389519e7322e01ca8caafdf66 (commit)
       via  db6a69baecd9b7a98e6de31eec2e20477130d8ef (commit)
       via  9fa41fc2c183d5920d64e6f34f8a6bb325188443 (commit)
       via  f70c3912a36e8d2ca4e63d0e1d7491f580b5c9f2 (commit)
       via  d8fd5725c32a6aa76eb8438adc0c912e6ad2696b (commit)
       via  2d70e84851f48e1e4091583ea98f7437d4e080ed (commit)
       via  73fe58f8ed3ba97f703d3e516d0f502a6aa5b907 (commit)
       via  06ff159e6744b18a3c15d95f9100b050cd169269 (commit)
       via  64854e87c6b07ddc8d7a687decefaf5ae3a5c9fb (commit)
       via  9adb80ce25def725ddd98d63f62e35a27e04c570 (commit)
       via  765d3a443f5121f148d47ec813069e1257212d5e (commit)
       via  1752d5ee472ce827ee66ea38c33085123575a033 (commit)
       via  9322ab27e20be82722b2db73f74447f2b35c6502 (commit)
       via  33c16c16e6d33118075b196e16b33b342ee462d3 (commit)
       via  dde4cb3f47a675095230fa849995b74e4a38b966 (commit)
       via  78dc6b1d4a6215144a76abc3d384c202a7949c5b (commit)
       via  f2e925905fe241c1723a6597a923dc5f3ebe56bf (commit)
       via  663ba79bb871c41250c605709782be2cfaf27640 (commit)
       via  dba3b902a0b7a4761829541c06466fd6d76c468b (commit)
       via  63cb20557ab9a74eee573d102a753ed34fc0ed59 (commit)
       via  efefbfe40342975cc0ddbd69a9b0f2635d905d3c (commit)
       via  764317bf85e5e63651486933b880a4627529d967 (commit)
       via  54445bc1d185792d6731849310a9d3c7f5c56eb5 (commit)
       via  14b63db90cddd8b437bdf4e7a4547a4c0e75768f (commit)
       via  7804a8c64aa29563134259bb7cb7429046fbd5f7 (commit)
       via  8d95c378d502d561a6be416a67b19b247a53f48a (commit)
       via  6b35b85a86de1bc9d2c7e3b0818baefba933205c (commit)
       via  4c4c0d3820bfc6ac3dce47a51e26ee2a9b593466 (commit)
       via  1da41261fba4cd03a32362d44c8634f599ae64db (commit)
       via  c116a3b0b2b2731fe44372b1c3aa6535717b4dc1 (commit)
       via  19e83a019f11d7ad1a199b7c6842f6184b59755b (commit)
       via  1e593610891a14187d0f44bec56520dfa118a95b (commit)
       via  64c5b3da1b7ebe73fcfb4edd9450382ccf1159fb (commit)
       via  ad2954e3ccd8da60e0d0ce707489071f030cbc59 (commit)
       via  cde238397af273f91deeaadf7e87713fbcb8ffbb (commit)
       via  1d4fd43cb95fed18c9885ba5b30b28eb1f8f713b (commit)
       via  b6061d8bf983dd69909a39f1d323934ee3de8166 (commit)
       via  dea37a9bcb88cf1ba65c7ad5c439425352a01f40 (commit)
       via  7620bc316c7e5bfd18f19c8e2fb09637d9eb8dee (commit)
       via  378e213c953d6482ae4d92a69b526cdeaef1f26f (commit)
       via  f2c0bdf60b053c28d6cde7faf1b014e5b7f7deaf (commit)
       via  2f49027b6d6b1f03ae07c5cd9625b072465079bd (commit)
       via  b3dcca92ca8160c07dad32617339fc5d3c636425 (commit)
       via  6782216a8b5464bb82e6c155a511841123a763c7 (commit)
       via  9478ffc5b7ae6988bb109a7be9189ed02f3720e8 (commit)
       via  e59b2439f336e943a5eb7bd6a9926dc18dd974d8 (commit)
       via  be9670d331c9b70a056f17c030faa8b71d58f675 (commit)
       via  f2e05556f6962e41556c4abb0acc900c82acc672 (commit)
       via  ceac2ed9713ea3be2d18c4dd0606f97bbee6953a (commit)
       via  1f6b16d2d233ecc7f99ea2460098d8eeec382942 (commit)
       via  7f9f66525d7d82816eba352efdf58497373a47bf (commit)
       via  0e38201f5879cc91c90876b2b9b219a308e3a2d2 (commit)
       via  34c33ee0f9d3863f9ef381e499e396c9f447a941 (commit)
       via  2f9c84e82632cbce017a6d342acb3dede5e59e12 (commit)
       via  7306300f662a4fd4adc28e60db6aa0201ec1f5b2 (commit)
       via  efbd4b724d239fa3c2d2929dc50e4bb4703489b9 (commit)
       via  cb4dfe29b4d374925d3bb9aed48cadf8070afc92 (commit)
       via  840a7fd39249c6680e74dd72d1ba0c55174a4996 (commit)
       via  71b7aa032ee4b1679b3475edd0c3442cb85f4a3a (commit)
       via  871e6f0348f8e6ee82a9ddcfcf8f88f4c818e4ae (commit)
       via  0acf419f9452f9f8133214742818d379ef779244 (commit)
       via  1e1bfd963b8b3a1381247d6ddb5734f10b0ed837 (commit)
       via  38162ad82080f1dd6f347fe2bc4e83478a7dc9c4 (commit)
       via  73ae20aa7f21d31907f19d9a47fe00b717fc4d7a (commit)
       via  1736b4db53dc60f1e7a9659dc201e0562d43aa02 (commit)
       via  98c6780098e577324c7642362a689c0d7dbe056d (commit)
       via  fa249bd82dfd16f4589ba2595db08ad13ba01ce7 (commit)
       via  1e4b9e300f6bfb84e3187ba2085723d44af9c50f (commit)
       via  6b63c37981ec6e0fc29d83f396acaa473172083f (commit)
       via  6a4160dab42fb7e952b0b91a99eedd4bb6bb1d67 (commit)
       via  4903b6de82f1ac1318b86fe27e71fea17bbaa9fc (commit)
       via  ec0a8d6c8ed3855b440aeb90b92088115212fb78 (commit)
       via  2473b938036dfdd32ff47833ea032a80a6fa5659 (commit)
       via  545cc9691e3d6479053684815d23e6553a7d0a95 (commit)
       via  bcb51623b8e156b03c2ae588906e4ed25fa3eba2 (commit)
       via  a3eb4b0a735b4fbd60ed66154befd31c56b601db (commit)
       via  86cd3e2cb5117c5800997d3bb363b6d5470be3ce (commit)
       via  1bd1b885c7dd16b5e4ab78c040312f6f7d742784 (commit)
       via  2fc1e9855f7983fb75a7f72d3ec97eec467e4709 (commit)
       via  5153d0f04b7ad460b23ae5a011061f7b93a122ef (commit)
       via  2f80bf28898274324a07d0b0d7c0e955f591c0df (commit)
       via  62fe40d1944810a79c13bd519a5f1157c49cefb6 (commit)
       via  2b9f0aae3eab5715283e843c66e4f02b221493f1 (commit)
       via  762f30020bfa5e333345adc25d34da84918faa96 (commit)
       via  d50e21276ee34fb8044586beb6ab9e85cc169d80 (commit)
       via  547b160b254cc6501578c69ea38228ca2d829c49 (commit)
       via  e7df7131092924b2d4ef1f41bac3d03affa9485b (commit)
       via  b334ca8db1959020a9e35865c78ce81b829b48a9 (commit)
       via  2443fb7afd788395e1c6baf067299f42317df21b (commit)
       via  d8e04682a95d856c0b7c97e5c965ea50bd9ac76b (commit)
       via  00c2e96c7b391c7bc33373397006d7ba2e211113 (commit)
       via  eccbbe18b119f60bcb4e33259f43f6f3cc0d2581 (commit)
       via  48f9d87c455f0804424977e2a2185de94bc2b0a3 (commit)
       via  a2ffcdbb5896779fc28a8d7ec770b87e516bd941 (commit)
       via  65f80a8ce75f050e30a400ff5eee3c08366bb518 (commit)
       via  27522378506a1102a77a15d6db3b6682003f0c99 (commit)
       via  552f2007b31c1df1694e19e1b07fb8a62fd2d816 (commit)
       via  6f220759af1c8e37f56acd334a295daa8c4a2651 (commit)
       via  902fcb22d611b7f9e99369ecab223c00c877b82c (commit)
       via  8e0e08c84626633e1d4b7b431576d4ec7d8f10c4 (commit)
       via  1b2704c322317629cef59d247e45b3dba3c21992 (commit)
       via  6322f5a157959473624345252df752d09e711e88 (commit)
       via  4c01db1833a02173c910d463eaed77ad6ed66195 (commit)
       via  501f5c4fc53a1c74a8a4074832dcc2bd72224ed6 (commit)
       via  f1aae2393344a21675bc3d5f3c24f9b555c5744b (commit)
       via  611ebfe5c55849245d47b4c5878eb85b27861f12 (commit)
       via  1edb5cb33d55a4f866c799d41680088b927f7846 (commit)
       via  2d3f4ffebcb451da84ceb8a4be58bbb23946ee6e (commit)
       via  f77c13a546af58cb8cdb593f49bbfa844b10dd7e (commit)
       via  d680707683794b92f2fc69e71dcb5b2a154598be (commit)
       via  a07103b076a9a88d89bf063396a74f2272749cf4 (commit)
       via  f25f9c52b1ab284ac1055b4f8321a2da33e81fcb (commit)
       via  85699a5cba88f4ee910e2c3ef42b5cc165102b51 (commit)
       via  28f563a6f54c8ea9c63537356966508c4685b538 (commit)
       via  a59a81a68ca26293f8e3df25da2cfe20e61d7c85 (commit)
       via  f18e168ff20217143bd922f158a1c56058795e89 (commit)
       via  c6cc60329c5bfc6c181cc45b09f30ac8a8a20b49 (commit)
       via  16d6377af8d1683a29b9dc7d7ab3e8d4bc1ebd48 (commit)
       via  976be25f6d3ea05f658a43abee336fe7e3bd419d (commit)
       via  0e829ea9a5062cac730f5a8368ab2062c1ef67fd (commit)
       via  f8fecb69346cbcd774a73a49322aeb8ddea73e44 (commit)
       via  41483acb1969b24e336b11aaf3bfdc1dbdfe33a8 (commit)
       via  2ff844d50c0ecbc4dc660cf7e8989476f56fb3e7 (commit)
       via  b1f63ac08d7da89ac7e8af4df5ca835527fc5b24 (commit)
       via  f70399532bd105c5f42ca040846aa537a8fa27bc (commit)
       via  385f22a32c3794615d713e519ae290eb09b2c4d2 (commit)
       via  9fc264e33c0fcc77ed18860a47bea824d75daebd (commit)
       via  55aefdc29dde7eb585b7a553876313ecceec1d68 (commit)
       via  444afe9e4a9c70f0833f6a0a912651dd0d0e57aa (commit)
       via  f38a8f801496ea91cef7a8507e2919f6586d0694 (commit)
       via  9121c3059288f36e004108e02ed4d826b84604e7 (commit)
       via  cb5838c3c261f9a775fae45adfa70e1514e8bfe0 (commit)
       via  a97507159ee06523c9dd6ec809199a0774976498 (commit)
       via  4e952aea89bbfaecd12614f1249c830aff36c551 (commit)
       via  66c827a4607fa11c5c3d26eb8e3a4d63c2b05bef (commit)
       via  e81b32fd38fb79595e7773670818f78e9a3e2df2 (commit)
       via  4323eba6170c7aee1661d834a9b7c177a10b7764 (commit)
       via  0d867aa42ea8c3487678dcceea484c10c88914cb (commit)
       via  a29f6a213fb18c199a4b1358327dc6d21f59eb64 (commit)
       via  903e540568e70f71e0a2911cb5998ac2d82ebbb4 (commit)
       via  e36300be4deb7bbdeff17c8e896ac2f727e1477e (commit)
       via  b97472e2be3aa040e59ac9ca4e54a7639be067ff (commit)
       via  e5f5db59aacd63af3369cb113c1c7b097c2f4be5 (commit)
       via  15a1d8d213380bd99b5dfe7f4cafcd6dedb8f0dc (commit)
       via  5909f454e470d5a1de2aea2451e69455bfb398ad (commit)
       via  f19d6c877ef2e467965b6fec2561be8b8ca5db94 (commit)
       via  4160a0e1fe1aaf4919162010a33550bc22af9454 (commit)
       via  d6e200568261f51fd007895516da1a06851d4481 (commit)
       via  15fba5cef614e836b6ed35543b8e7ae49f52a450 (commit)
       via  27fa47040717ac1b917a083eaac0c8468b4640f4 (commit)
       via  399ec4931adce151b7633f2b66b04d021d3ae78c (commit)
       via  45bba30a98164938c25b6ed3a574e5f8a175bbd7 (commit)
       via  5db85f61829f0b56001884c59c690200eb07742e (commit)
       via  734e898a91dc494506004c8c6a8057a363171bf1 (commit)
       via  969ee3cbf2255a508eca008c0b25d8a1f09bdeb3 (commit)
       via  0585c4e6f3d68846d56fe766675099b539e2cba9 (commit)
       via  5f4811bd1b91dd3b50a30a227e455738f5dcfe36 (commit)
       via  608116b9826d199c2df99d79fe6c0b39c4febb8b (commit)
       via  ba81a835d78656b966a81e3426af82ee903f97de (commit)
       via  06e47b84ed3eb2ec562ee9910d192853f351a0bc (commit)
       via  dcaab6dd8a28be8885ccc508c49b962a61ab09fe (commit)
       via  99c220c921ef24bfea7a1fe425753caf20db7c30 (commit)
       via  a7478f42519382507939db409563753b76cfe140 (commit)
       via  1fc7a1fe6aba3c1ba98c44f8df1926c10ff79c87 (commit)
       via  f9c7ec30542ef2550761f49cd25503e0775ef271 (commit)
       via  2e5a819d44fdc20235c66d95e96c4618d9008f6d (commit)
       via  0d52289482d468c8566976d77c0c6a6a4e602add (commit)
       via  769d7886cceec048dcd4aa67236b5971891418c3 (commit)
       via  fa9d1a09cfe9e7386746a2c6523b5503d1b4aff9 (commit)
       via  edfe2064ee8285ccc70b9254ed191d5cef1de14f (commit)
       via  4518d0d3c80d8c616a8a7f65548fde4866495289 (commit)
       via  c31c6405cf8bccde9ead3268ceebd0e5080ea632 (commit)
       via  4ec42f2201d6d15be74de5d6d34b1baa614a2e9f (commit)
       via  9b3ff12e83ccc37893556a7c4ba98d2e3cd0c581 (commit)
       via  882d4057221d8a9976003214776edd43d2fbf9c4 (commit)
       via  db416985122dccb31bb50f41195e517e2e3bca89 (commit)
       via  50ccd9803efa7e9b1e411d4f43fcd520d41debad (commit)
       via  0cfef8a4298a54a53b9f78c003c8e508f65dad06 (commit)
       via  bf80c70c5aa0a98c02e3ce157153f7a40c516839 (commit)
       via  bf97a0c486d96e13c57e2f716dfacfa07c6394f5 (commit)
       via  3ceedbd1f9a0a1444d13aa64cd85db28cb17d219 (commit)
       via  932e27e10312e5b84afc551bbcd16551b0770f0e (commit)
       via  d07f0f9df7ea216ca579eed7a9b46d3e168619de (commit)
       via  0d9a32b95e932fb47ddfb100056aa6fe527da595 (commit)
       via  a5a031ed51c3236e0d72d766f2ac1d53022ae957 (commit)
       via  5dd46ec03bb3dc945d2f084726aaba79a83e6340 (commit)
       via  2451ae9bb7e5aca7fdbaa139f4692ae9f4b21244 (commit)
       via  7efd4d794abbbd1b6abc2110cd43fd7896e0cb47 (commit)
       via  723446ecab4a6c88ff129d61e360f70bf17a718b (commit)
       via  0b07960513cbb8aa76b6f301b23cf73b5b2019c7 (commit)
       via  2513062a4c89b0b60c3717d506fce841d44d871e (commit)
       via  b15c7145da2b28bdb0f6521428d5f057a7dc8cfb (commit)
       via  838f65088cda84edc2df609d3e388acb3c8eb13d (commit)
       via  a3454a6b0e25a6d1be66b698c52bae9674309c21 (commit)
       via  1fc15398cbd381b83e20bca3913c12ee7aa34bd4 (commit)
       via  a398513aadb70b98e6e0ad04e5821ea0b6eca00c (commit)
       via  cbaeeb232619098a4bdd9ad5d322dd9e3f4f1930 (commit)
       via  d00161ea2a57bcc45a34a35fed0d46c0e3b2de99 (commit)
       via  f49b0b03937c6edfdfba5cfc229557dcfe56b2c7 (commit)
       via  081af8809fd1dc3e05bac3d313fc0a480b0dd5c0 (commit)
       via  f3eec73c3b99d1b688421ca2c3e0cd3117ca452d (commit)
       via  e9f1827fcd3a45cbf5a6df93d9e177e3151e1f56 (commit)
       via  d8035c3f7d40d741d7be27e323dcad5757a32759 (commit)
       via  2ef8920a5dfb2d1975deecb83e8239d90a58600c (commit)
       via  6316df7a19613a47f94366d24f3302daf5d582da (commit)
       via  fa17ad763ec4c001a5d1858832e473a3b0ead0fd (commit)
       via  e13c76601a232b24c99a452d8f3403f87f069c22 (commit)
       via  90001d0580cdba35ed3813396a095bd9f5a9345e (commit)
       via  deb2fe660265860073c5180a5e31c0375cd0d1f1 (commit)
       via  80561e40fab798717fe2d0c217ccaf96e1025def (commit)
       via  f862e8fe648ed66662417bc37b20980fe7780eec (commit)
       via  fed291bee8b64bddbb27537b1ab104cf93b8de01 (commit)
       via  84feadf5595d1bde46d9e93357fe6b094697ac22 (commit)
       via  ac7bcb4c8cdc07f974205709616fda91a447c0f1 (commit)
       via  624caa19ebb5b5a19046f0b0deb96b2e6c093685 (commit)
       via  41da6a35e2cca4ec3c6b7c61e204e51484ecd7eb (commit)
       via  e65bf179b2c804d2af89f938fa7434cb03d3b52b (commit)
       via  46fb38d70fe250f318fb95a6083beaceaaf5155d (commit)
       via  add7cf1fd2229b7245d8a611f98ac7310e157f76 (commit)
       via  73c561d03b0e9a4f2d0bc10d943ec73e002ea48b (commit)
       via  66de65c83fc98ff2745b664f06e6b90a19b90b3b (commit)
       via  f35c7514dda9bf9cf06580ab5870af13e0e58103 (commit)
       via  52edf49564243b1d6392477e7c447eeb0d8558c0 (commit)
       via  c55f68090438121e3bb7c4baa66d5bba6681f277 (commit)
       via  bfb15f15556411332a2c33c2ddf51ca44c7df82f (commit)
       via  6cc74b6a9954bcfcf48aeb6178b3426b5940f928 (commit)
       via  d4397f45eb710a3c24b7b24aa895e8b9323aff4f (commit)
       via  b027c0d5d49cddfb46565d2d572ecf3828b80b1a (commit)
       via  67557ccd7bfedd6656394c42b367493f6eba0bdb (commit)
       via  0ef2d77362b1ac3caae96512c0dbdcda5b87adc5 (commit)
       via  0a0442fb4744b4a6f419b5e341dfb553081cf04e (commit)
       via  ab90088866a262f32c79e4fabc4a63409c9fd4f5 (commit)
       via  6e6d960b0964b43f3c94e19872537f7fd4603f59 (commit)
       via  757eacd6cf522e56df34372ca7e6968817947cbb (commit)
       via  0c9e840515309d37257da568d6b01dad72aa7ebc (commit)
       via  afabab5ec7a8d8500576a3bf39321cb5ca566661 (commit)
       via  2bf2c2b86482c77a8ca3b88df8e2def62e65f903 (commit)
       via  31c6051694d3152e50eb037e20c4734c7321eac6 (commit)
       via  905daf3abd3dc2d0dde5b2009ae00be3da3bf105 (commit)
       via  82e7082d1653a2143fc29d405fe40329188828b5 (commit)
       via  d03f6f66493d8a8a80810f51fb363dfb7bcd02a5 (commit)
       via  ee77f64d563188b6a5d761fd9342df00431e99d8 (commit)
       via  d312241e2ed853effb2d018d50e1362bf21848a0 (commit)
       via  8b863f8852067b0638e09dc7c82355b96381dc12 (commit)
       via  af9cde0a7cf69800ac3ec581a7c2422e955b9a3c (commit)
       via  05de499531bc8fece2625b27a728bd24412ab41a (commit)
       via  20b2458ba07a9190cfd5bc942da604482036a5b0 (commit)
       via  d268465c69afb15db91f9dd0cb07131ef7ba9c45 (commit)
       via  0a050fa206e5d899f553b6ac492d389cb39591a2 (commit)
       via  f23d62da85fad992feeddd630ce07f0214df7029 (commit)
       via  b4cf3cc470eb1200ec90fcc7ad5b2d069059cf7e (commit)
       via  5cd73ffdcdbd5de2d03b9db781ca26c5a5af516d (commit)
       via  350265fafb2a0153d4207c67d626f135b308ad34 (commit)
       via  b549d4314c75c5136bfc5ede78df5ecdfbd85690 (commit)
       via  2375b235875e65e2238b7723d29b9bcb527192e1 (commit)
       via  a9d4cec96e6e37f470ef5bf8ca7b5a6af6a722bc (commit)
       via  e7bf93d184c1aaf14e5f8e5cf8a517582eb49f23 (commit)
       via  f9098699afea06c80045a6e7ab0ff819a29da84f (commit)
       via  0ea9121e4bf07514d75024837fe4dd1c615c8ec0 (commit)
       via  d0299eb46c0f4551d355591a58e88715fee139e7 (commit)
       via  e3f20c041c078eacf648af94d9f012e4906359bb (commit)
       via  c483c50817e8accd0d5052d41d00869330193175 (commit)
       via  42d78c1d49a0b5257eb3fbde733a99732892f47d (commit)
       via  50925902635e9b66288318fd768157dbeb529f08 (commit)
       via  9d32cd025e715630e4665499a93c45b2e5d13bdb (commit)
       via  46a457244070dac0ff575293348748f1d8db4352 (commit)
       via  6a9d48365f5044b64a6c270760808d17d475ca4b (commit)
       via  204bec7af64c61489e37007d45de936482007977 (commit)
       via  c9936ef0d4d7a7f263831bead31c5ffcf8b0a8d3 (commit)
       via  af1cce266d1b6c875cf01db6c47ada89cbf64411 (commit)
       via  c5227d1685aa158e63d4b6a6289063ae985673c1 (commit)
       via  bae708045f36e3a000acd9de74084e48471bf389 (commit)
       via  99d0b82fbf3ff42019fadef5fbb396551aa20070 (commit)
       via  f7904deae23ca465c4035fc913b7dbe1abca19a9 (commit)
       via  2f19ce406c3c350dcf6de6454d5c7e1bd7755c24 (commit)
       via  e8f34d6db9d1c4343ecfacd94cd5d0441ffacee4 (commit)
       via  c2cda8d3736b59738f579fce748e94ca109ccc58 (commit)
       via  e982e87ced45d48d23ffc86fa0b6cf6fabfbef8d (commit)
       via  b75a0f281598a38f64a5b2bc3da40ff2cdac20ca (commit)
       via  ac0717b3ca30f7b250db4d526e98ed3eb8de9953 (commit)
       via  22e694149f4ffb9118de16127169ca80b26137d3 (commit)
       via  af2d598d477dbabdfdb6f730850191017dec625e (commit)
       via  3b13df110f42b26417de73151eb4a03657e85de4 (commit)
       via  b7f2322bfa862bb7b4391392aa914f40f13e9ab3 (commit)
       via  d8018f6f8957cb67920904f08377608a7cc78307 (commit)
       via  0182312b0fc945a20a3d7aeac1488540b5518e3a (commit)
       via  0d487f23486bae6721650e37b746fdb1d1a67977 (commit)
       via  393460d20fcc982c3d71749ca3ef4192cb01defb (commit)
       via  cdafa10657ce3d8be73baa3a18f09045bfdc2ae7 (commit)
       via  ab0f848957a4b9d891e7e793cd232cc4a8e61fac (commit)
       via  8554673ddcb41cad3634eeced649d3ad53b99ee8 (commit)
       via  ae9f4eebdcf5b0e5340480bf71d221e16091266e (commit)
       via  50f8512202d7a52effe43422323e2f0c7184afe0 (commit)
       via  cbecf843696d2574accb198b84d9386eef15341c (commit)
       via  81475535ddd41d5c91b2ea65c22aff3c687dad03 (commit)
       via  2c84999804e28517cf467a6ed6788aea06e146c0 (commit)
       via  a786967e7e5775d6da6fd94e5113c6cb3c7704f2 (commit)
       via  49a291d1713912ffb6801ced6f0c517e430a9a71 (commit)
       via  92b1be4a48425e584f29e223a56b261dddb4cdd5 (commit)
       via  98ba9765f8e6b0cd22e94e226a21a46b1b6eaf9b (commit)
       via  6f373546792c2befaa2d9d0fffb12fda80320042 (commit)
       via  74ee0dcab17240a1626b77ed998b07f0f6560a48 (commit)
       via  d7a6deaeca178a15c600fbc13262aca29fb39753 (commit)
       via  cb9faa8c276efc4e2b24378bdb941d007523fc22 (commit)
       via  2a8c128ca91b42261720368e5d25431ee4362c70 (commit)
       via  8529cd991d329ca9f17da5d75320248a86400f3d (commit)
       via  13bfd4900cb896756442778d82b3be3bac074b32 (commit)
       via  5e73f350819b4cd9efb0d50b8a57e50ab271dcda (commit)
       via  964e19b54a9ee3e03658e2a733c1b50ee8624397 (commit)
       via  de578ef8fa4fecfda01ead45ea24ef3b64b7d1b0 (commit)
       via  2711b6286b4929e20289a318fceac67025db92d6 (commit)
       via  78d374fdffd6d83b559393a00a6f69804d6e5c4d (commit)
       via  3c4daf4e10892a471111a95f62d99d660ab24552 (commit)
       via  e86f9bcc463370f27f005439c2d8bb73a0caafbd (commit)
       via  0e8a103b9aa1f2411fba665d1656f28fa297e874 (commit)
       via  62988ea2ac1f845e30c3986bfc9bf4620693682a (commit)
       via  c86aa5e85c7ced14a81389c0bf96b6c75fe420c9 (commit)
       via  6b818c7f463e1bd6b9470f4bfb694f240ac3e5c2 (commit)
       via  2f7402ec4b65a2546373403fa701a29d7482cf3f (commit)
       via  abce1669d0d0e571687b73db8810a9a3a3a3d8e5 (commit)
       via  5bbb7a9ec75b08d29557876bb77f9c4349e17ce8 (commit)
       via  0054d8fc4f53f27817764dee7bac7ec36fd312f8 (commit)
       via  42bcb6246432790af31958d5445cd035fe9966a5 (commit)
       via  abff9b12506c0b8d971a7b6c9b08ada126d67e0d (commit)
       via  c8a4f8fef51ee2da94cec60017765bba9b1ea61b (commit)
       via  c7a0e4b598a39084c288f975a59549b6068051cf (commit)
       via  4959339c8a962b54bf33fd9e3d9f46b3f1c3c29e (commit)
       via  3225a4e4256d827a521c7127620e34a167f6e195 (commit)
       via  510b5a48ec42ca1335b61421d40f9914db6f9d07 (commit)
       via  da40c668c34535b7068bd1d228d6debaf2fb7bb6 (commit)
       via  bef9bb953fe57ad027d596501b64230b526f0fda (commit)
       via  ed633f19bdbb66ac12aaf66cf46b458558eaedbd (commit)
       via  db0190d23e173d1869906385d00f3cbc01559b72 (commit)
       via  96490f609bec8ee0b1827faf893d0f6daecc9a53 (commit)
       via  7773dc0b5d21792fb55bc52f992c7a5b7239140f (commit)
       via  63cf4c66e97a92f3e553707ecd0bc278a7cc4563 (commit)
       via  a2a68eaafd161190d15a42cb2d54e297c5263860 (commit)
       via  6bdad20131c002ae3d293dcfc98792a197a782dd (commit)
       via  63c4c29e1ebfb0e68fe622bea1c4ed82ac6a6a02 (commit)
       via  d58dd2f32dc90742a9759b70114a39a55550a66a (commit)
       via  2072cca806ac43a5ee0d422749e9e0c5f7611d47 (commit)
       via  abcfb997622f9b65c9f142b178648bbda83acdf1 (commit)
       via  1086474bc51fc31e15d72df27b529b1015cd33aa (commit)
       via  67676f7332c2fa2ab6eb4411993fa77e92df5828 (commit)
       via  af7c51f9bfbded58d306e4f0e05b580457e7e92f (commit)
       via  b8ec82d647b7455cc89fc911eba04513ae6d9653 (commit)
       via  31d26ad56d0616672303d2d949a3772afc35e33b (commit)
       via  df3fe55e08cf4e8575e7b3d6ea38fd1cf9a9ca2e (commit)
       via  591925d885e736007f05854226b5f65ae06ad0a7 (commit)
       via  25a11929d27188ef28be2b671f895df347a15024 (commit)
       via  342139ab3ed41800b6844c11efaaa21b2bc61b36 (commit)
       via  983b6996b019850733fc9cd2ea57352f9dbbf7d8 (commit)
       via  9701514d4ad1152da564ebf6690c514becd4339a (commit)
       via  e71e74ac9af232d58e6c672e37ddf7e8737d68b1 (commit)
       via  66479f2ca1fbbf3b96cd2e1b15c0119b209df54a (commit)
       via  6f66d82e5794022ec2873d1f3ccba8e1267ca9a3 (commit)
       via  eeb0b5d5b0791c580e49e7a6ca4f844f2a0edabb (commit)
       via  c7882f59b6e5e4bb142928939264ca0c9af8e129 (commit)
       via  2a4725673f46d42cddff89b7002b193c67222c85 (commit)
       via  32649f52d26b1c3a6d09ffbca04928b476698713 (commit)
       via  ffab492af7444f26e3eb4945700cf72841a36e6e (commit)
       via  fc9b58482ce186b2fa0461351d4e060735e21b78 (commit)
       via  6641754c13e38dd6198832f23aa2be4b4546b324 (commit)
       via  06e16db227de0422f33b5f83817df55340f11846 (commit)
       via  b4d06df669e1eaf6c98cacb5c5f299bb5324e804 (commit)
       via  ce2747c81b98b70e75ec399c8bdc6c09308380d3 (commit)
       via  eff1b6b21720518f2ea9dbd862fe3844d899db08 (commit)
       via  8b4e8f702df30b2b2238158504de5d8eb436958d (commit)
       via  4dcc853c04e05a88e2c07125bf3e7ab75cbcb6ca (commit)
       via  6b1b9c16a1b55804df36457de0650414ab3f017d (commit)
       via  7ac81efe10795318427ad71f9c05b9c93442acfb (commit)
       via  2323f97d55a79c302457d75443b2ffd529983083 (commit)
       via  bfc92908704856d136b8eee3a03ea7f6bb868c2e (commit)
       via  f671c30534a2e3b0675f81cbb82f0d0e82ace6c3 (commit)
       via  5d0e35df699f96e1f22af4d8f4cffab355c82913 (commit)
       via  6de0102373304c0fdf70a7ddeb17dd1caa3a9b23 (commit)
       via  d7c8dfd41bd5671ddfa6c81b2ef1779cab06e56b (commit)
       via  f7cd8393105d286074d6e1a918b4fd6228f00245 (commit)
       via  01629cb09cce23f1b8c014280b97a2f19ca34e25 (commit)
       via  ae1c0daca3998e5be8369e632e093f9f6dce1a70 (commit)
       via  a1df6304be3c217877919097d2e4b3b16de6cd02 (commit)
       via  1cc790ecafc378da1dbbda8480a2a41f13c1821e (commit)
       via  4282c7757598300ee050374f3649ffee070ed680 (commit)
       via  ae131ae925aa5ba54fb7f8ae105e5cbbf3655f06 (commit)
       via  8006ef4ca16fa8264dcc1e849783e1f4ce4978a1 (commit)
       via  9a7e5828f29d3f5daba5dc5ef1f6b9cd87f596b8 (commit)
       via  8f2c2755573b81c1e2c9ef1c42c529d13396d4d2 (commit)
       via  09dca22666681470a207083f339083a1a4a8c973 (commit)
       via  4425e6c5b88ecc03371b68926ebf89ebe03839ba (commit)
       via  d60fb05cc5db4f1ee1176a9ed7f053011f8521aa (commit)
       via  cafa8fcd5a5d593f4638b199fbf5f94a006a4aac (commit)
       via  de3372f0d98c7137823e7d5630d03429bb77d1f2 (commit)
       via  94e3f93395de538d73826e128281a3ea9591a5a9 (commit)
       via  ebb6772e9eabeb81e3cc9305a6bec7adf7aad450 (commit)
       via  e069c636968370f0899d5e4ebaeb9c2341804245 (commit)
       via  624d70844fe63068132adb7c66ea3f8a231e56a7 (commit)
       via  da83b6857bf0a67b15fc75d31a0b6802ac9baffe (commit)
       via  e149eb882355f427d43928324145c971a0562c5e (commit)
       via  c4300d657ba49db0b6d0f0884f41a29622edc58b (commit)
       via  1457aab67141409f57d25c06f86e227d92808da3 (commit)
       via  afc5c481f97b85b803b9b973d52684deceb715d0 (commit)
       via  69b59a73db108ede65e4dfce90fcfb10723e1feb (commit)
       via  faf3affc19f760a330153b22a8e56fc9a13a0cb6 (commit)
       via  2376c18714fe197fbf56a19f8271e5f256ec7caf (commit)
       via  88b8c03a11e229b29cd985cabe51cb2ed3c24b55 (commit)
       via  633bbb9f481cd72edb7c419941a366d0efbf88b6 (commit)
       via  fe3ad49e37792999b36f1e590974a19a92b7f388 (commit)
       via  6b5925f4c303d43228ffe5e37b84d9017d2ff5e3 (commit)
       via  ad5c8d1f818c96579fa9e7f3c691739e9761e1e7 (commit)
       via  d8bd9f5261761dd4ffca331d9c6055c48a0a332b (commit)
       via  9ee8aeb59ad3b3873d52f3c9a2ab80b28c4c2c20 (commit)
       via  f0391b8a4db649853ecc47a10b09d7c4b04330cf (commit)
       via  6ace1b5a655517a41be7d1633ec7592ad940c0e6 (commit)
       via  a0d911d5920362982fb6a5c1fa6047c69dc26668 (commit)
       via  c5d29ade6407adcec3eeef9e61a1474501acc0d3 (commit)
       via  1f647aac9fa3e412c63a966535de8ee4fec855f2 (commit)
       via  27e1e910147465ad240a3e4393bbd4312937fed5 (commit)
       via  24a57029937207c4fa2ff4acb5a4e1ae1dc9e54b (commit)
       via  e3d803ece7400aeb61e9577346e3de93ae2afccb (commit)
       via  6959e2ab216aeb1d5d8f07ce73cd8b9894b83006 (commit)
      from  29b83492df3195fe9ab1498a572dc2c3d87331e8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=a2ab9ea617584b92b670c528542fdde10a209457

commit a2ab9ea617584b92b670c528542fdde10a209457
Author: Arnold D. Robbins <address@hidden>
Date:   Sun Apr 5 13:17:47 2015 +0300

    Added README.num-handler file.

diff --git a/README.num-handler b/README.num-handler
new file mode 100644
index 0000000..a6654be
--- /dev/null
+++ b/README.num-handler
@@ -0,0 +1,11 @@
+Sun Apr  5 13:15:09 IDT 2015
+============================
+
+This branch is an attempt to generalize number handling in gawk.
+John Haque had it pretty much working when he abandoned the gawk project
+in December 2012 and I have been carrying it forward since.
+
+However, keeping it in sync with master is getting increasingly hard. For
+example, not all the tests pass at this point, and I don't feel like
+trying to make them do so, since it doesn't look like I will ever merge
+this branch in.

http://git.sv.gnu.org/cgit/gawk.git/commit/?id=be546b6b216912cb21b72a8f777e313b818f3e03

commit be546b6b216912cb21b72a8f777e313b818f3e03
Merge: 29b8349 dbf9d5a
Author: Arnold D. Robbins <address@hidden>
Date:   Sun Apr 5 13:14:46 2015 +0300

    Merge branch 'master' into num-handler. Not all tests pass.

diff --cc ChangeLog
index ee54f79,d50e7c2..e0c6db9
--- a/ChangeLog
+++ b/ChangeLog
@@@ -1,10 -1,685 +1,692 @@@
+ 2015-04-05         Arnold D. Robbins     <address@hidden>
+ 
+       * awkgram.y (install_builtins): If do_traditional is true, do not
+       install gawk extensions flagged with GAWKX.  Similarly, if do_posix
+       is true, do not install functions flagged with NOT_POSIX.
+       This fixes a problem with spurious lint complaints about shadowing
+       a global variable that is not valid in traditional or posix mode.
+       Thanks to Andrew Schorr for finding the problem and supplying
+       initial code; I did it slightly differently.
+ 
+ 2015-04-02         Andrew J. Schorr     <address@hidden>
+ 
+       * NEWS: Rename div to intdiv.
+ 
+ 2015-04-02         Arnold D. Robbins     <address@hidden>
+ 
+       Rename div() to intdiv().
+ 
+       * builtin.c (do_intdiv): Renamed from do_div.
+       * mfpr.c (do_mpfr_intdiv): Renamed from do_mpfr_div.
+       * awk.h: Update declarations.
+       * awkgram.y (tokentab, snode): Revise accordingly.
+ 
+ 2015-03-31         Arnold D. Robbins     <address@hidden>
+ 
+       * awk.h (call_sub): Renamed from call_sub_func.
+       (call_match, call_split_func): Declare.
+       * builtin.c (call_sub): Renamed from call_sub_func.
+       (call_match, call_split_func): New functions.
+       * interpret.h (r_interpret): Call new functions as appropriate.
+       * node.c (r_unref): Revert change to handle Node_regex, not needed.
+ 
+ 2015-03-31         Arnold D. Robbins     <address@hidden>
+ 
+       * awk.h (r_get_field): Declare.
+       * builtin.c (call_sub_func): Rearrange the stack to be what
+       the buitin function expects.
+       * eval.c (r_get_field): Make extern.
+ 
+ 2015-03-27         Arnold D. Robbins     <address@hidden>
+ 
+       * io.c (redirect): Change not_string from int to bool.
+       * gawkapi.c (api_get_file): Minor stylistic improvements.
+       * NEWS: Updated for retryable I/O and new API function.
+ 
+ 2015-03-24         Arnold D. Robbins     <address@hidden>
+ 
+       * awkgram.y (make_regnode): Make extern.
+       * awk.h (make_regnode): Declare.
+       * builtin.c (call_sub_func): Start on reworking the stack to
+       be what do_sub() expects. Still needs work.
+       * interpret.h (r_interpret): Add a cast in comparison with do_sub().
+       * node.c (r_unref): Handle Node_regex nodes.
+ 
+ 2015-03-24         Andrew J. Schorr     <address@hidden>
+ 
+       * interpret.h (r_interpret): When Op_K_exit has an argument of
+       Nnull_string, do not update exit_val, since no value was supplied.
+ 
+ 2015-03-24         Arnold D. Robbins     <address@hidden>
+ 
+       * awk.h, gawkapi.c, io.c: Minor code reformatting.
+ 
+ 2015-03-20         Arnold D. Robbins     <address@hidden>
+ 
+       Start on fixing indirect calls of builtins.
+ 
+       * awk.h (call_sub_func): Add declaration.
+       * awkgram.y (lookup_builtin): Handle length, sub functions.
+       (install_builtin): Handle length function.
+       * builtin.c (call_sub_func): New function.
+       * interpret.h (r_interpret): If calling do_sub, do it through
+       call_sub_func().
+ 
+ 2015-03-18         Arnold D. Robbins     <address@hidden>
+ 
+       * config.guess, config.sub: Updated, from libtool 2.4.6.
+ 
+ 2015-03-17         Arnold D. Robbins     <address@hidden>
+ 
+       * profile.c (pp_number): Allocate enough room to print the number
+       in all cases. Was a problem mixing -M with profiling with a really
+       big number. Thanks to Hermann Peifer for the bug report.
+ 
+ 2015-03-08         Arnold D. Robbins     <address@hidden>
+ 
+       * re.c (regexflags2str): Removed. It was redundant.
+ 
+       * io.c (devopen): Change the logic such that if nonfatal is true
+       for the socket, don't do retries.  Also clean up the formatting
+       some.  At strictopen, check if errno is ENOENT and if so, propagate
+       the error from getaddrinfo() up to the caller. Add explanatory
+       comments.
+ 
+ 2015-02-28         Andrew J. Schorr     <address@hidden>
+ 
+       * io.c (pty_vs_pipe): Remove check for NULL PROCINFO_node, since
+       this is now checked inside in_PROCINFO.
+ 
+ 2015-02-27         Andrew J. Schorr     <address@hidden>
+ 
+       * io.c (socketopen): New parameter hard_error; set it if
+       getaddrinfo() fails. Change fatals to warnings.
+       (devopen): Pass in address of boolean hard_error variable
+       and stop trying to open the file if hard_error is true.
+       Save and restore errno around call to socketopen() and
+       use restored errno if open() fails at strictopen.
+ 
+ 2015-02-27         Arnold D. Robbins     <address@hidden>
+ 
+       * symbol.c (check_param_names): Fix argument order in memset() call.
+       * configure.ac: Use AC_SEARCH_LIBS instead of AC_CHECK_LIB. This fixes
+       a long-standing problem where `-lm' was used twice in the final
+       compilation line.
+ 
+ 2015-02-24         Arnold D. Robbins     <address@hidden>
+ 
+       * POSIX.STD: Update copyright year.
+       * awkgram.y (yylex): Allow \r after \\ line continuation everywhere.
+       Thanks to Scott Rush <address@hidden> for the report.
+ 
+ 2015-02-13         Arnold D. Robbins     <address@hidden>
+ 
+       * awkgram.y (yylex): Be more careful about passing true to
+       nextc() when collecting a regexp.  Some systems' iscntrl()
+       are not as forgiving as GLIBC's. E.g., Solaris.
+       Thanks to Dagobert Michelsen <address@hidden> for
+       the bug report and access to systems to check the fix.
+ 
+ 2015-02-12         Arnold D. Robbins     <address@hidden>
+ 
+       * POSIX.STD: Update with info about function parameters.
+       * configure.ac: Remove test for / use of dbug library.
+ 
+ 2015-02-11         Arnold D. Robbins     <address@hidden>
+ 
+       * gawkapi.h: Fix spelling error in comment.
+ 
+ 2015-02-10         Arnold D. Robbins     <address@hidden>
+ 
+       * profile.c (pprint): Restore printing of count for rules.
+       Bug report by Hermann Peifer.
+ 
+ 2015-02-08         Arnold D. Robbins     <address@hidden>
+ 
+       * io.c: Make it "NONFATAL" everywhere.
+ 
+ 2015-02-08         Andrew J. Schorr     <address@hidden>
+ 
+       * awk.h (RED_NON_FATAL): Removed.
+       (redirect): Add new failure_fatal parameter.
+       (is_non_fatal_redirect): Add declaration.
+       * builtin.c (efwrite): Rework check for non-fatal.
+       (do_printf): Adjust calls to redirect.
+       (do_print_rec): Ditto. Move check for redirection error up.
+       * io.c (redflags2str): Remove RED_NON_FATAL.
+       (redirect): Add new failure_fatal parameter. Simplify the code.
+       (is_non_fatal_redirect): New function.
+       (do_getline_redir): Adjust calls to redirect.
+ 
+ 2014-12-27         Arnold D. Robbins     <address@hidden>
+ 
+       * awk.h (is_non_fatal_std): Declare new function.
+       * io.c (is_non_fatal_std): New function.
+       * builtin.c (efwrite): Call it.
+ 
+ 2015-02-07         Arnold D. Robbins     <address@hidden>
+ 
+       * regcomp.c, regex.c, regex.h, regex_internal.c, regex_internal.h,
+       regexec.c: Sync with GLIBC. Mostly copyright date updates.
+ 
+ 2015-02-05         Andrew J. Schorr     <address@hidden>
+ 
+       * eval.c (set_IGNORECASE): If IGNORECASE has a numeric value, try
+       using that before treating it as a string.  This fixes a problem
+       where setting -v IGNORECASE=0 on the command line was not working
+       properly.
+ 
+ 2015-02-01         Arnold D. Robbins     <address@hidden>
+ 
+       Move POSIX requirement for disallowing paramater names with the
+       same name as a function into --posix.
+ 
+       * NEWS: Document it.
+       * awkgram.y (parse_program): Check do_posix before calling
+       check_param_names().
+       * symbol.c (check_param_names): Set up a fake node and call
+       in_array() for function parameter names instead of linear
+       searching the function list a second time. Thanks to Andrew
+       Schorr for the motivation.
+ 
+ 2015-01-30         Arnold D. Robbins     <address@hidden>
+ 
+       Don't allow function parameter names to be the same as function
+       names - required by POSIX. Bug first reported in comp.lang.awk.
+ 
+       In addition, don't allow use of a parameter as a function name
+       in a call (but it's ok in indirect calls).
+ 
+       * NEWS: Updated.
+       * awk.h (check_param_names): Add declaration.
+       * awkgram.y (at_seen): New variable. Communicates between
+       yylex() and the parser.
+       (FUNC_CALL production): Check at_seen and check that the identifier
+       is a function name.
+       (parse_program): Call check_param_names() and set errcount.
+       (yylex): Set at_seen after seeing an at-sign.
+       * symbol.c (check_param_names): New function.
+ 
+ 2015-01-24         Arnold D. Robbins     <address@hidden>
+ 
+       Infrastructure updates.
+ 
+       Bison 3.0.4. Automake 1.15. Gettext 0.19.4.
+ 
+ 2015-01-20         Arnold D. Robbins     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * awkgram.c: Update to bison 3.0.3.
+       * command.c: Ditto.
+       * NEWS: Note same.
+ 
+ 2015-01-16         Stephen Davies        <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       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-08         Andrew J. Schorr     <address@hidden>
+ 
+       Revert changes to API deferred variable creation -- these variables
+       should be created when lookup is called, not when update is called.
+       * awk.h (variable_create): Remove function declaration.
+       * awkgram.y (variable_create): Remove function.
+       (variable): Restore variable_create functionality inline.
+       * gawkapi.c (api_sym_update): Revert to using install_symbol, since the
+       deferred variable check should be done when lookup is called, not here.
+ 
+ 2015-01-07         Andrew J. Schorr     <address@hidden>
+ 
+       * gawkapi.c (api_set_array_element): Remove stray call to
+       make_aname.  I cannot see what purpose this served.  Maybe I am
+       missing something.
+ 
+ 2015-01-07         Arnold D. Robbins     <address@hidden>
+ 
+       * 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.
+ 
+ 2015-01-06         Andrew J. Schorr     <address@hidden>
+ 
+       * gawkapi.c (api_sym_update): If copying a subarray, must update
+       the parent_array pointer.  Also, call the astore hook if non-NULL.
+       (api_set_array_element): Call the astore hook if non-NULL.
+ 
+ 2015-01-06         Andrew J. Schorr     <address@hidden>
+ 
+       * awk.h (variable_create): Now takes a 3rd argument to tell caller
+       whether this is a deferred variable.
+       * awkgram.y (variable_create): Return indicator of whether this is
+       a deferred variable in a newly added 3rd arg.
+       (variable): Pass 3rd arg to variable_create.
+       * gawkapi.c (api_sym_update): If we triggered the creation of a deferred
+       variable, we must merge the extension's array elements into the deffered
+       array, not the other way around.  The ENVIRON array has special funcs
+       to call setenv and unsetenv.
+ 
+ 2015-01-06         Andrew J. Schorr     <address@hidden>
+ 
+       * awk.h (variable_create): Declare new function.
+       * awkgram.y (variable_create): New function to create a variable
+       taking the deferred variable list into consideration.
+       (variable): Call new function variable_create if the variable is
+       not found.
+       * gawkapi.c (api_sym_update): If an array is being created, then
+       call new function variable_create instead of install_symbol.  If this
+       is the first reference to a deferred variable, than the new array
+       may contain elements that must be merged into the array provided by
+       the extension.
+ 
+ 2015-01-05         Andrew J. Schorr     <address@hidden>
+ 
+       * io.c (wait_any): If the `interesting' argument is non-zero, then we
+       must not return until that child process has exited, since the caller
+       gawk_pclose depends on our returning its exit status.  So in that case,
+       do not pass WNOHANG to waitpid.
+ 
+ 2015-01-04         Andrew J. Schorr     <address@hidden>
+ 
+       * gawkapi.h: Fix another comment typo.
+ 
+ 2015-01-04         Andrew J. Schorr     <address@hidden>
+ 
+       * gawkapi.h: Fix typo in comment.
+ 
+ 2015-01-02         Andrew J. Schorr     <address@hidden>
+ 
+       * gawkapi.h (gawk_api): Modify api_get_file to remove the typelen
+       argument.
+       (get_file): Remove typelen argument from the macro.
+       * gawkapi.c (api_get_file): Remove typelen argument.
+ 
+ 2014-12-24         Arnold D. Robbins     <address@hidden>
+ 
+       * profile.c (pprint): Be sure to set ip2 in all paths
+       through the code. Thanks to GCC 4.9 for the warning.
+ 
+ 2014-12-20         Arnold D. Robbins     <address@hidden>
+ 
+       Enable non-fatal output on per-file or global basis,
+       via PROCINFO.
+ 
+       * awk.h (RED_NON_FATAL): New redirection flag.
+       * builtin.c (efwrite): If RED_NON_FATAL set, just set ERRNO and return.
+       (do_printf): Check errflg and if set, set ERRNO and return.
+       (do_print): Ditto.
+       (do_print_rec): Ditto.
+       * io.c (redflags2str): Update table.
+       (redirect): Check for global PROCINFO["nonfatal"] or for
+       PROCINFO[file, "nonfatal"] and don't fail on open if set.
+       Add RED_NON_FATAL to flags.
+       (in_PROCINFO): Make smarter and more general.
+ 
+ 2014-12-12        Stephen Davies         <address@hidden>
+ 
+       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     <address@hidden>
+ 
+       * dfa.c: Sync with GNU grep.
+ 
+ 2014-11-26         Arnold D. Robbins     <address@hidden>
+ 
+       * builtin.c (do_sub): Improve wording of gensub warnings.
+ 
+ 2014-11-25         Arnold D. Robbins     <address@hidden>
+ 
+       * builtin.c (do_sub): For gensub, add more warnings for invalid
+       third argument.
+ 
+ 2014-11-23         Arnold D. Robbins     <address@hidden>
+ 
+       * awk.h: Move all inline functions to the bottom of the file.
+       Keeps modern GCC happier.
+ 
+ 2014-11-22         Arnold D. Robbins     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * 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  <address@hidden>
+ 
+       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     <address@hidden>
+ 
+       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  <address@hidden>
+ 
+       * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.19.3.
+ 
+ 2014-11-16         Arnold D. Robbins     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       Don't let memory used increase linearly in the size of
+       the input.  Problem reported by dragan legic
+       <address@hidden>.
+ 
+       * 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     <address@hidden>
+ 
+       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     <address@hidden>
+ 
+       * 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-06         Andrew J. Schorr     <address@hidden>
+ 
+       * awk.h (redirect_string): First argument should be const.  Add a new
+       extfd argument to enable extensions to create files with pre-opened
+       file descriptors.
+       (after_beginfile): Declare function used in both eval.c and gawkapi.c.
+       * eval.c (after_beginfile): Remove extern declaration now in awk.h.
+       * gawkapi.c (api_get_file): Implement API changes to return
+       awk_input_buf_t and/or awk_output_buf_t info, as well as accept an
+       fd for inserting an opened file into the table.
+       * gawkapi.h (gawk_api): Modify the api_get_file declaration to
+       return awk_bool_t and add 3 new arguments -- a file descriptor
+       for inserting an already opened file, and awk_input_buf_t and
+       awk_output_buf_t to return info about both input and output.
+       (get_file): Add new arguments to the macro.
+       * io.c (redirect_string): First arg should be const, and add a new
+       extfd arg so extensions can pass in a file that has already been
+       opened by the extension.  Use the passed-in fd when appropriate,
+       and pass it into two_way_open.
+       (redirect): Pass new fd -1 arg to redirect_string.
+       (two_way_open): Accept new extension fd parameter and open it
+       as a socket.
+ 
+ 2014-11-05         Andrew J. Schorr     <address@hidden>
+ 
+       * io.c (retryable): New function to indicate whether I/O can be
+       retried for this file instead of throwing a hard error.
+       (get_a_record) Check whether this file is configured for retryable
+       I/O before returning nonstandard -2.
+ 
+ 2014-11-03         Norihiro Tanaka       <address@hidden>
+ 
+       * re.c (research): Use dfa superset to improve matching speed.
+ 
+ 2014-11-02         Arnold D. Robbins     <address@hidden>
+ 
+       * profile.c (div_on_left_mul_on_right): New function.
+       (parenthesize): Call it.
+ 
+ 2014-10-30         Arnold D. Robbins     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * NEWS: Mention installation of /etc/profile.d/gawk.{csh,sh}.
+ 
+ 2014-10-29         Andrew J. Schorr     <address@hidden>
+ 
+       * configure.ac (AC_CONFIG_FILES): Add extras/Makefile.
+       * Makefile.am (SUBDIRS): Add extras.
+       * extras: Add new subdirectory.
+ 
+ 2014-10-29         Arnold D. Robbins     <address@hidden>
+ 
+       * dfa.c: Sync with GNU grep. Again, again.
+ 
+ 2014-10-28         Arnold D. Robbins     <address@hidden>
+ 
+       * dfa.c: Sync with GNU grep. Again.
+ 
+ 2014-10-25         Arnold D. Robbins     <address@hidden>
+ 
+       * dfa.c: Sync with GNU grep.
+ 
+ 2014-10-17         John E. Malmberg      <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       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     <address@hidden>
+ 
+       * 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          <address@hidden>
+ 
+       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     <address@hidden>
+ 
+       * README: Remove Pat Rankin from VMS duties, per his request.
+ 
+ 2014-10-08         Arnold D. Robbins     <address@hidden>
+ 
+       * dfa.c: Sync with GNU grep.
+ 
+ 2014-10-05         Arnold D. Robbins     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * 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 (address@hidden) for the report.
+ 
+ 2014-10-03    Stephen Davies          <address@hidden>
+ 
+       * awkgram.y (program_comment): Renamed from comment0.
+       (function_comment): Renamed from commentf.
+ 
+ 2014-10-02         Arnold D. Robbins     <address@hidden>
+ 
+       * awkgram.y, profile.c: Minor white space cleanups.
+ 
+ 2014-10-01         Arnold D. Robbins     <address@hidden>
+ 
+       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     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * gawkapi.h: Minor edits to sync with documentation. Does not
+       influence the behavior of the API.
+ 
+ 2014-09-28         Arnold D. Robbins     <address@hidden>
+ 
+       * command.y (cmdtab): Add "where" as an alias for "backtrace".
+       Finally!
+ 
+       Unrelated:
+ 
+       * dfa.c: Sync with GNU grep.
+ 
+ 2014-09-27         Arnold D. Robbins     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * 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     <address@hidden>
+ 
+       * awkgram.y: Further commentary as to the treacherousness
+       of isalnum and isalpha.
+ 
 +2014-09-16         Arnold D. Robbins     <address@hidden>
 +
 +      * mpfr.c (cleanup_mpfr): Removed.
 +      (do_mpfp_div): Merged in. Other changes to make things work.
 +      * awkgram.y (tokentab): Need a new flag for "div" instead of
 +      checking the builtin function.
 +
  2014-09-15         Arnold D. Robbins     <address@hidden>
  
        Finish removing use of isalpha and isalnum.
diff --cc awk.h
index e1ec7b9,6f812e7..b1556d5
--- a/awk.h
+++ b/awk.h
@@@ -379,17 -393,8 +377,15 @@@ typedef struct exp_node 
                        size_t slen;
                        long sref;
                        int idx;
- #if MBS_SUPPORT
                        wchar_t *wsp;
                        size_t wslen;
- #endif                
 +                      union {
 +                              AWKNUM fltnum;
 +                              void *pq;
 +                      } nmb;
 +#define numbr sub.val.nmb.fltnum
 +#define       qnumbr  sub.val.nmb.pq
 +
                } val;
        } sub;
        NODETYPE type;
@@@ -1383,20 -1329,25 +1346,20 @@@ extern void shadow_funcs(void)
  extern int check_special(const char *name);
  extern SRCFILE *add_srcfile(enum srctype stype, char *src, SRCFILE *curr, 
bool *already_included, int *errcode);
  extern void free_srcfile(SRCFILE *thisfile);
- extern void register_deferred_variable(const char *name, NODE 
*(*load_func)(void));
  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);
+ extern NODE *make_regnode(int type, NODE *exp);
  /* builtin.c */
 -extern double double_to_int(double d);
 -extern NODE *do_exp(int nargs);
  extern NODE *do_fflush(int nargs);
  extern NODE *do_index(int nargs);
 -extern NODE *do_int(int nargs);
  extern NODE *do_isarray(int nargs);
  extern NODE *do_length(int nargs);
 -extern NODE *do_log(int nargs);
  extern NODE *do_mktime(int nargs);
  extern NODE *do_sprintf(int nargs);
  extern void do_printf(int nargs, int redirtype);
@@@ -1408,8 -1361,25 +1371,11 @@@ extern void do_print(int nargs, int red
  extern void do_print_rec(int args, int redirtype);
  extern NODE *do_tolower(int nargs);
  extern NODE *do_toupper(int nargs);
 -extern NODE *do_atan2(int nargs);
 -extern NODE *do_sin(int nargs);
 -extern NODE *do_cos(int nargs);
 -extern NODE *do_rand(int nargs);
 -extern NODE *do_srand(int nargs);
  extern NODE *do_match(int nargs);
  extern NODE *do_sub(int nargs, unsigned int flags);
+ extern NODE *call_sub(const char *name, int nargs);
+ extern NODE *call_match(int nargs);
+ extern NODE *call_split_func(const char *name, int nargs);
 -extern NODE *format_tree(const char *, size_t, NODE **, long);
 -extern NODE *do_lshift(int nargs);
 -extern NODE *do_rshift(int nargs);
 -extern NODE *do_and(int nargs);
 -extern NODE *do_or(int nargs);
 -extern NODE *do_xor(int nargs);
 -extern NODE *do_compl(int nargs);
 -extern NODE *do_strtonum(int nargs);
 -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);
@@@ -1520,7 -1486,11 +1483,10 @@@ extern void register_output_wrapper(awk
  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 struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg, 
bool failure_fatal);
+ extern struct redirect *redirect_string(const char *redir_exp_str,
+               size_t redir_exp_len, bool not_string_flag, int redirtype,
+               int *errflg, int extfd, bool failure_fatal);
  extern NODE *do_close(int nargs);
  extern int flush_io(void);
  extern int close_io(bool *stdio_problem);
@@@ -1540,7 -1511,40 +1507,8 @@@ extern int is_off_limits_var(const cha
  extern char *estrdup(const char *str, size_t len);
  extern void update_global_values();
  extern long getenv_long(const char *name);
+ extern void after_beginfile(IOBUF **curfile);
  
 -/* 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_exp(int);
 -extern NODE *do_mpfr_int(int);
 -extern NODE *do_mpfr_intdiv(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 final_exit(int status) ATTRIBUTE_NORETURN;
@@@ -1575,8 -1576,6 +1543,7 @@@ extern NODE *r_dupnode(NODE *n)
  extern NODE *make_str_node(const char *s, size_t len, int flags);
  extern void *more_blocks(int id);
  extern int parse_escape(const char **string_ptr);
 +extern int get_numbase(const char *str, bool use_locale);
- #if MBS_SUPPORT
  extern NODE *str2wstr(NODE *n, size_t **ptr);
  extern NODE *wstr2str(NODE *n);
  #define force_wstring(n)      str2wstr(n, NULL)
diff --cc awkgram.c
index 861ab0b,52a17cb..36ed214
--- a/awkgram.c
+++ b/awkgram.c
@@@ -194,7 -202,7 +201,7 @@@ extern double fmod(double x, double y)
  
  #define YYSTYPE INSTRUCTION *
  
- #line 198 "awkgram.c" /* yacc.c:339  */
 -#line 206 "awkgram.c" /* yacc.c:339  */
++#line 205 "awkgram.c" /* yacc.c:339  */
  
  # ifndef YY_NULLPTR
  #  if defined __cplusplus && 201103L <= __cplusplus
@@@ -348,7 -356,7 +355,7 @@@ int yyparse (void)
  
  /* Copy the second part of user declarations.  */
  
- #line 352 "awkgram.c" /* yacc.c:358  */
 -#line 360 "awkgram.c" /* yacc.c:358  */
++#line 359 "awkgram.c" /* yacc.c:358  */
  
  #ifdef short
  # undef short
@@@ -650,25 -658,25 +657,25 @@@ static const yytype_uint8 yytranslate[
    /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
  static const yytype_uint16 yyrline[] =
  {
-        0,   197,   197,   199,   204,   205,   211,   223,   227,   238,
-      244,   249,   257,   265,   267,   272,   280,   282,   288,   289,
-      291,   317,   328,   339,   345,   354,   364,   366,   368,   374,
-      379,   380,   384,   403,   402,   436,   438,   443,   444,   457,
-      462,   463,   467,   469,   471,   478,   568,   610,   652,   765,
-      772,   779,   789,   798,   807,   816,   827,   843,   842,   866,
-      878,   878,   976,   976,  1009,  1039,  1045,  1046,  1052,  1053,
-     1060,  1065,  1077,  1091,  1093,  1101,  1106,  1108,  1116,  1118,
-     1127,  1128,  1136,  1141,  1141,  1152,  1156,  1164,  1165,  1168,
-     1170,  1175,  1176,  1185,  1186,  1191,  1196,  1202,  1204,  1206,
-     1213,  1214,  1220,  1221,  1226,  1228,  1233,  1235,  1243,  1248,
-     1257,  1264,  1266,  1268,  1284,  1294,  1301,  1303,  1308,  1310,
-     1312,  1320,  1322,  1327,  1329,  1334,  1336,  1338,  1388,  1390,
-     1392,  1394,  1396,  1398,  1400,  1402,  1416,  1421,  1426,  1451,
-     1457,  1459,  1461,  1463,  1465,  1467,  1472,  1476,  1508,  1510,
-     1516,  1522,  1535,  1536,  1537,  1542,  1547,  1551,  1555,  1570,
-     1582,  1587,  1623,  1641,  1642,  1648,  1649,  1654,  1656,  1663,
-     1680,  1697,  1699,  1706,  1711,  1719,  1729,  1741,  1750,  1754,
-     1758,  1762,  1766,  1770,  1773,  1775,  1779,  1783,  1787
 -       0,   205,   205,   207,   212,   213,   217,   229,   234,   245,
 -     251,   257,   266,   274,   276,   281,   289,   291,   297,   305,
 -     315,   345,   359,   373,   381,   392,   404,   406,   408,   414,
 -     422,   423,   427,   462,   461,   495,   497,   502,   508,   536,
 -     541,   542,   546,   548,   550,   557,   647,   689,   731,   844,
 -     851,   858,   868,   877,   886,   895,   906,   922,   921,   945,
 -     957,   957,  1055,  1055,  1088,  1118,  1124,  1125,  1131,  1132,
 -    1139,  1144,  1156,  1170,  1172,  1180,  1185,  1187,  1195,  1197,
 -    1206,  1207,  1215,  1220,  1220,  1231,  1235,  1243,  1244,  1247,
 -    1249,  1254,  1255,  1264,  1265,  1270,  1275,  1281,  1283,  1285,
 -    1292,  1293,  1299,  1300,  1305,  1307,  1312,  1314,  1322,  1327,
 -    1336,  1343,  1345,  1347,  1363,  1373,  1380,  1382,  1387,  1389,
 -    1391,  1399,  1401,  1406,  1408,  1413,  1415,  1417,  1467,  1469,
 -    1471,  1473,  1475,  1477,  1479,  1481,  1495,  1500,  1505,  1530,
 -    1536,  1538,  1540,  1542,  1544,  1546,  1551,  1555,  1587,  1589,
 -    1595,  1601,  1614,  1615,  1616,  1621,  1626,  1630,  1634,  1649,
 -    1662,  1667,  1704,  1733,  1734,  1740,  1741,  1746,  1748,  1755,
 -    1772,  1789,  1791,  1798,  1803,  1811,  1821,  1833,  1842,  1846,
 -    1850,  1854,  1858,  1862,  1865,  1867,  1871,  1875,  1879
++       0,   204,   204,   206,   211,   212,   216,   228,   233,   244,
++     250,   256,   265,   273,   275,   280,   288,   290,   296,   304,
++     314,   344,   358,   372,   380,   391,   403,   405,   407,   413,
++     421,   422,   426,   461,   460,   494,   496,   501,   507,   535,
++     540,   541,   545,   547,   549,   556,   646,   688,   730,   843,
++     850,   857,   867,   876,   885,   894,   905,   921,   920,   944,
++     956,   956,  1054,  1054,  1087,  1117,  1123,  1124,  1130,  1131,
++    1138,  1143,  1155,  1169,  1171,  1179,  1184,  1186,  1194,  1196,
++    1205,  1206,  1214,  1219,  1219,  1230,  1234,  1242,  1243,  1246,
++    1248,  1253,  1254,  1263,  1264,  1269,  1274,  1280,  1282,  1284,
++    1291,  1292,  1298,  1299,  1304,  1306,  1311,  1313,  1321,  1326,
++    1335,  1342,  1344,  1346,  1362,  1372,  1379,  1381,  1386,  1388,
++    1390,  1398,  1400,  1405,  1407,  1412,  1414,  1416,  1466,  1468,
++    1470,  1472,  1474,  1476,  1478,  1480,  1494,  1499,  1504,  1529,
++    1535,  1537,  1539,  1541,  1543,  1545,  1550,  1554,  1586,  1588,
++    1594,  1600,  1613,  1614,  1615,  1620,  1625,  1629,  1633,  1648,
++    1660,  1665,  1702,  1731,  1732,  1738,  1739,  1744,  1746,  1753,
++    1770,  1787,  1789,  1796,  1801,  1809,  1819,  1831,  1840,  1844,
++    1848,  1852,  1856,  1860,  1863,  1865,  1869,  1873,  1877
  };
  #endif
  
@@@ -1841,26 -1849,24 +1848,24 @@@ yyreduce
    switch (yyn)
      {
          case 3:
- #line 200 "awkgram.y" /* yacc.c:1646  */
 -#line 208 "awkgram.y" /* yacc.c:1646  */
++#line 207 "awkgram.y" /* yacc.c:1646  */
      {
                rule = 0;
                yyerrok;
          }
- #line 1850 "awkgram.c" /* yacc.c:1646  */
 -#line 1858 "awkgram.c" /* yacc.c:1646  */
++#line 1857 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 5:
- #line 206 "awkgram.y" /* yacc.c:1646  */
 -#line 214 "awkgram.y" /* yacc.c:1646  */
++#line 213 "awkgram.y" /* yacc.c:1646  */
      {
                next_sourcefile();
-               if (sourcefile == srcfiles)
-                       process_deferred();
          }
- #line 1860 "awkgram.c" /* yacc.c:1646  */
 -#line 1866 "awkgram.c" /* yacc.c:1646  */
++#line 1865 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 6:
- #line 212 "awkgram.y" /* yacc.c:1646  */
 -#line 218 "awkgram.y" /* yacc.c:1646  */
++#line 217 "awkgram.y" /* yacc.c:1646  */
      {
                rule = 0;
                /*
@@@ -1869,19 -1875,20 +1874,20 @@@
                 */
                /* yyerrok; */
          }
- #line 1873 "awkgram.c" /* yacc.c:1646  */
 -#line 1879 "awkgram.c" /* yacc.c:1646  */
++#line 1878 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 7:
- #line 224 "awkgram.y" /* yacc.c:1646  */
 -#line 230 "awkgram.y" /* yacc.c:1646  */
++#line 229 "awkgram.y" /* yacc.c:1646  */
      {
                (void) append_rule((yyvsp[-1]), (yyvsp[0]));
+               first_rule = false;
          }
- #line 1881 "awkgram.c" /* yacc.c:1646  */
 -#line 1888 "awkgram.c" /* yacc.c:1646  */
++#line 1887 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 8:
- #line 228 "awkgram.y" /* yacc.c:1646  */
 -#line 235 "awkgram.y" /* yacc.c:1646  */
++#line 234 "awkgram.y" /* yacc.c:1646  */
      {
                if (rule != Rule) {
                        msg(_("%s blocks must have an action part"), 
ruletab[rule]);
@@@ -1892,39 -1899,41 +1898,41 @@@
                } else          /* pattern rule with non-empty pattern */
                        (void) append_rule((yyvsp[-1]), NULL);
          }
- #line 1896 "awkgram.c" /* yacc.c:1646  */
 -#line 1903 "awkgram.c" /* yacc.c:1646  */
++#line 1902 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 9:
- #line 239 "awkgram.y" /* yacc.c:1646  */
 -#line 246 "awkgram.y" /* yacc.c:1646  */
++#line 245 "awkgram.y" /* yacc.c:1646  */
      {
                in_function = NULL;
                (void) mk_function((yyvsp[-1]), (yyvsp[0]));
                yyerrok;
          }
- #line 1906 "awkgram.c" /* yacc.c:1646  */
 -#line 1913 "awkgram.c" /* yacc.c:1646  */
++#line 1912 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 10:
- #line 245 "awkgram.y" /* yacc.c:1646  */
 -#line 252 "awkgram.y" /* yacc.c:1646  */
++#line 251 "awkgram.y" /* yacc.c:1646  */
      {
                want_source = false;
+               at_seen = false;
                yyerrok;
          }
- #line 1915 "awkgram.c" /* yacc.c:1646  */
 -#line 1923 "awkgram.c" /* yacc.c:1646  */
++#line 1922 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 11:
- #line 250 "awkgram.y" /* yacc.c:1646  */
 -#line 258 "awkgram.y" /* yacc.c:1646  */
++#line 257 "awkgram.y" /* yacc.c:1646  */
      {
                want_source = false;
+               at_seen = false;
                yyerrok;
          }
- #line 1924 "awkgram.c" /* yacc.c:1646  */
 -#line 1933 "awkgram.c" /* yacc.c:1646  */
++#line 1932 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 12:
- #line 258 "awkgram.y" /* yacc.c:1646  */
 -#line 267 "awkgram.y" /* yacc.c:1646  */
++#line 266 "awkgram.y" /* yacc.c:1646  */
      {
                if (include_source((yyvsp[0])) < 0)
                        YYABORT;
@@@ -1932,23 -1941,23 +1940,23 @@@
                bcfree((yyvsp[0]));
                (yyval) = NULL;
          }
- #line 1936 "awkgram.c" /* yacc.c:1646  */
 -#line 1945 "awkgram.c" /* yacc.c:1646  */
++#line 1944 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 13:
- #line 266 "awkgram.y" /* yacc.c:1646  */
 -#line 275 "awkgram.y" /* yacc.c:1646  */
++#line 274 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 1942 "awkgram.c" /* yacc.c:1646  */
 -#line 1951 "awkgram.c" /* yacc.c:1646  */
++#line 1950 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 14:
- #line 268 "awkgram.y" /* yacc.c:1646  */
 -#line 277 "awkgram.y" /* yacc.c:1646  */
++#line 276 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 1948 "awkgram.c" /* yacc.c:1646  */
 -#line 1957 "awkgram.c" /* yacc.c:1646  */
++#line 1956 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 15:
- #line 273 "awkgram.y" /* yacc.c:1646  */
 -#line 282 "awkgram.y" /* yacc.c:1646  */
++#line 281 "awkgram.y" /* yacc.c:1646  */
      {
                if (load_library((yyvsp[0])) < 0)
                        YYABORT;
@@@ -1956,35 -1965,49 +1964,49 @@@
                bcfree((yyvsp[0]));
                (yyval) = NULL;
          }
- #line 1960 "awkgram.c" /* yacc.c:1646  */
 -#line 1969 "awkgram.c" /* yacc.c:1646  */
++#line 1968 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 16:
- #line 281 "awkgram.y" /* yacc.c:1646  */
 -#line 290 "awkgram.y" /* yacc.c:1646  */
++#line 289 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 1966 "awkgram.c" /* yacc.c:1646  */
 -#line 1975 "awkgram.c" /* yacc.c:1646  */
++#line 1974 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 17:
- #line 283 "awkgram.y" /* yacc.c:1646  */
 -#line 292 "awkgram.y" /* yacc.c:1646  */
++#line 291 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 1972 "awkgram.c" /* yacc.c:1646  */
 -#line 1981 "awkgram.c" /* yacc.c:1646  */
++#line 1980 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 18:
- #line 288 "awkgram.y" /* yacc.c:1646  */
-     { (yyval) = NULL; rule = Rule; }
- #line 1978 "awkgram.c" /* yacc.c:1646  */
 -#line 297 "awkgram.y" /* yacc.c:1646  */
++#line 296 "awkgram.y" /* yacc.c:1646  */
+     {
+               rule = Rule;
+               if (comment != NULL) {
+                       (yyval) = list_create(comment);
+                       comment = NULL;
+               } else
+                       (yyval) = NULL;
+         }
 -#line 1994 "awkgram.c" /* yacc.c:1646  */
++#line 1993 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 19:
- #line 290 "awkgram.y" /* yacc.c:1646  */
-     { (yyval) = (yyvsp[0]); rule = Rule; }
- #line 1984 "awkgram.c" /* yacc.c:1646  */
 -#line 306 "awkgram.y" /* yacc.c:1646  */
++#line 305 "awkgram.y" /* yacc.c:1646  */
+     {
+               rule = Rule;
+               if (comment != NULL) {
+                       (yyval) = list_prepend((yyvsp[0]), comment);
+                       comment = NULL;
+               } else
+                       (yyval) = (yyvsp[0]);
+         }
 -#line 2007 "awkgram.c" /* yacc.c:1646  */
++#line 2006 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 20:
- #line 292 "awkgram.y" /* yacc.c:1646  */
 -#line 316 "awkgram.y" /* yacc.c:1646  */
++#line 315 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *tp;
  
@@@ -2007,104 -2030,139 +2029,139 @@@
                        ((yyvsp[-3])->nexti + 1)->condpair_left = 
(yyvsp[-3])->lasti;
                        ((yyvsp[-3])->nexti + 1)->condpair_right = 
(yyvsp[0])->lasti;
                }
-               (yyval) = list_append(list_merge((yyvsp[-3]), (yyvsp[0])), 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 2014 "awkgram.c" /* yacc.c:1646  */
 -#line 2041 "awkgram.c" /* yacc.c:1646  */
++#line 2040 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 21:
- #line 318 "awkgram.y" /* yacc.c:1646  */
 -#line 346 "awkgram.y" /* yacc.c:1646  */
++#line 345 "awkgram.y" /* yacc.c:1646  */
      {
                static int begin_seen = 0;
+ 
+               func_first = false;
                if (do_lint_old && ++begin_seen == 2)
                        warning_ln((yyvsp[0])->source_line,
                                _("old awk does not support multiple `BEGIN' or 
`END' rules"));
  
                (yyvsp[0])->in_rule = rule = BEGIN;
                (yyvsp[0])->source_file = source;
+               check_comment();
                (yyval) = (yyvsp[0]);
          }
- #line 2029 "awkgram.c" /* yacc.c:1646  */
 -#line 2059 "awkgram.c" /* yacc.c:1646  */
++#line 2058 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 22:
- #line 329 "awkgram.y" /* yacc.c:1646  */
 -#line 360 "awkgram.y" /* yacc.c:1646  */
++#line 359 "awkgram.y" /* yacc.c:1646  */
      {
                static int end_seen = 0;
+ 
+               func_first = false;
                if (do_lint_old && ++end_seen == 2)
                        warning_ln((yyvsp[0])->source_line,
                                _("old awk does not support multiple `BEGIN' or 
`END' rules"));
  
                (yyvsp[0])->in_rule = rule = END;
                (yyvsp[0])->source_file = source;
+               check_comment();
                (yyval) = (yyvsp[0]);
          }
- #line 2044 "awkgram.c" /* yacc.c:1646  */
 -#line 2077 "awkgram.c" /* yacc.c:1646  */
++#line 2076 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 23:
- #line 340 "awkgram.y" /* yacc.c:1646  */
 -#line 374 "awkgram.y" /* yacc.c:1646  */
++#line 373 "awkgram.y" /* yacc.c:1646  */
      {
+               func_first = false;
                (yyvsp[0])->in_rule = rule = BEGINFILE;
                (yyvsp[0])->source_file = source;
+               check_comment();
                (yyval) = (yyvsp[0]);
          }
- #line 2054 "awkgram.c" /* yacc.c:1646  */
 -#line 2089 "awkgram.c" /* yacc.c:1646  */
++#line 2088 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 24:
- #line 346 "awkgram.y" /* yacc.c:1646  */
 -#line 382 "awkgram.y" /* yacc.c:1646  */
++#line 381 "awkgram.y" /* yacc.c:1646  */
      {
+               func_first = false;
                (yyvsp[0])->in_rule = rule = ENDFILE;
                (yyvsp[0])->source_file = source;
+               check_comment();
                (yyval) = (yyvsp[0]);
          }
- #line 2064 "awkgram.c" /* yacc.c:1646  */
 -#line 2101 "awkgram.c" /* yacc.c:1646  */
++#line 2100 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 25:
- #line 355 "awkgram.y" /* yacc.c:1646  */
 -#line 393 "awkgram.y" /* yacc.c:1646  */
++#line 392 "awkgram.y" /* yacc.c:1646  */
      {
+               INSTRUCTION *ip;
                if ((yyvsp[-3]) == NULL)
-                       (yyval) = list_create(instruction(Op_no_op));
+                       ip = list_create(instruction(Op_no_op));
                else
-                       (yyval) = (yyvsp[-3]);
+                       ip = (yyvsp[-3]);
+               (yyval) = ip;
          }
- #line 2075 "awkgram.c" /* yacc.c:1646  */
 -#line 2114 "awkgram.c" /* yacc.c:1646  */
++#line 2113 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 26:
- #line 365 "awkgram.y" /* yacc.c:1646  */
 -#line 405 "awkgram.y" /* yacc.c:1646  */
++#line 404 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 2081 "awkgram.c" /* yacc.c:1646  */
 -#line 2120 "awkgram.c" /* yacc.c:1646  */
++#line 2119 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 27:
- #line 367 "awkgram.y" /* yacc.c:1646  */
 -#line 407 "awkgram.y" /* yacc.c:1646  */
++#line 406 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 2087 "awkgram.c" /* yacc.c:1646  */
 -#line 2126 "awkgram.c" /* yacc.c:1646  */
++#line 2125 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 28:
- #line 369 "awkgram.y" /* yacc.c:1646  */
 -#line 409 "awkgram.y" /* yacc.c:1646  */
++#line 408 "awkgram.y" /* yacc.c:1646  */
      {
                yyerror(_("`%s' is a built-in function, it cannot be 
redefined"),
                                        tokstart);
                YYABORT;
          }
- #line 2097 "awkgram.c" /* yacc.c:1646  */
 -#line 2136 "awkgram.c" /* yacc.c:1646  */
++#line 2135 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 29:
- #line 375 "awkgram.y" /* yacc.c:1646  */
-     { (yyval) = (yyvsp[0]); }
- #line 2103 "awkgram.c" /* yacc.c:1646  */
 -#line 415 "awkgram.y" /* yacc.c:1646  */
++#line 414 "awkgram.y" /* yacc.c:1646  */
+     {
+               (yyval) = (yyvsp[0]);
+               at_seen = false;
+         }
 -#line 2145 "awkgram.c" /* yacc.c:1646  */
++#line 2144 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 32:
- #line 385 "awkgram.y" /* yacc.c:1646  */
 -#line 428 "awkgram.y" /* yacc.c:1646  */
++#line 427 "awkgram.y" /* yacc.c:1646  */
      {
+               /*
+                *  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;
@@@ -2114,17 -2172,17 +2171,17 @@@
                /* $4 already free'd in install_function */
                (yyval) = (yyvsp[-5]);
          }
- #line 2118 "awkgram.c" /* yacc.c:1646  */
 -#line 2176 "awkgram.c" /* yacc.c:1646  */
++#line 2175 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 33:
- #line 403 "awkgram.y" /* yacc.c:1646  */
 -#line 462 "awkgram.y" /* yacc.c:1646  */
++#line 461 "awkgram.y" /* yacc.c:1646  */
      { want_regexp = true; }
- #line 2124 "awkgram.c" /* yacc.c:1646  */
 -#line 2182 "awkgram.c" /* yacc.c:1646  */
++#line 2181 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 34:
- #line 405 "awkgram.y" /* yacc.c:1646  */
 -#line 464 "awkgram.y" /* yacc.c:1646  */
++#line 463 "awkgram.y" /* yacc.c:1646  */
      {
                  NODE *n, *exp;
                  char *re;
@@@ -2153,69 -2211,89 +2210,89 @@@
                  (yyval)->opcode = Op_match_rec;
                  (yyval)->memory = n;
                }
- #line 2157 "awkgram.c" /* yacc.c:1646  */
 -#line 2215 "awkgram.c" /* yacc.c:1646  */
++#line 2214 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 35:
- #line 437 "awkgram.y" /* yacc.c:1646  */
 -#line 496 "awkgram.y" /* yacc.c:1646  */
++#line 495 "awkgram.y" /* yacc.c:1646  */
      { bcfree((yyvsp[0])); }
- #line 2163 "awkgram.c" /* yacc.c:1646  */
 -#line 2221 "awkgram.c" /* yacc.c:1646  */
++#line 2220 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 37:
- #line 443 "awkgram.y" /* yacc.c:1646  */
-     { (yyval) = NULL; }
- #line 2169 "awkgram.c" /* yacc.c:1646  */
 -#line 502 "awkgram.y" /* yacc.c:1646  */
++#line 501 "awkgram.y" /* yacc.c:1646  */
+     {
+               if (comment != NULL) {
+                       (yyval) = list_create(comment);
+                       comment = NULL;
+               } else (yyval) = NULL;
+         }
 -#line 2232 "awkgram.c" /* yacc.c:1646  */
++#line 2231 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 38:
- #line 445 "awkgram.y" /* yacc.c:1646  */
 -#line 509 "awkgram.y" /* yacc.c:1646  */
++#line 508 "awkgram.y" /* yacc.c:1646  */
      {
-               if ((yyvsp[0]) == NULL)
-                       (yyval) = (yyvsp[-1]);
-               else {
+               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)
-                               (yyval) = (yyvsp[0]);
-                       else
+                       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 2186 "awkgram.c" /* yacc.c:1646  */
 -#line 2264 "awkgram.c" /* yacc.c:1646  */
++#line 2263 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 39:
- #line 458 "awkgram.y" /* yacc.c:1646  */
 -#line 537 "awkgram.y" /* yacc.c:1646  */
++#line 536 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 2192 "awkgram.c" /* yacc.c:1646  */
 -#line 2270 "awkgram.c" /* yacc.c:1646  */
++#line 2269 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 42:
- #line 468 "awkgram.y" /* yacc.c:1646  */
 -#line 547 "awkgram.y" /* yacc.c:1646  */
++#line 546 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 2198 "awkgram.c" /* yacc.c:1646  */
 -#line 2276 "awkgram.c" /* yacc.c:1646  */
++#line 2275 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 43:
- #line 470 "awkgram.y" /* yacc.c:1646  */
 -#line 549 "awkgram.y" /* yacc.c:1646  */
++#line 548 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[-1]); }
- #line 2204 "awkgram.c" /* yacc.c:1646  */
 -#line 2282 "awkgram.c" /* yacc.c:1646  */
++#line 2281 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 44:
- #line 472 "awkgram.y" /* yacc.c:1646  */
 -#line 551 "awkgram.y" /* yacc.c:1646  */
++#line 550 "awkgram.y" /* yacc.c:1646  */
      {
                if (do_pretty_print)
                        (yyval) = list_prepend((yyvsp[0]), 
instruction(Op_exec_count));
                else
                        (yyval) = (yyvsp[0]);
          }
- #line 2215 "awkgram.c" /* yacc.c:1646  */
 -#line 2293 "awkgram.c" /* yacc.c:1646  */
++#line 2292 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 45:
- #line 479 "awkgram.y" /* yacc.c:1646  */
 -#line 558 "awkgram.y" /* yacc.c:1646  */
++#line 557 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
                INSTRUCTION *ip, *nextc, *tbreak;
@@@ -2305,11 -2383,11 +2382,11 @@@
                break_allowed--;                        
                fix_break_continue(ip, tbreak, NULL);
          }
- #line 2309 "awkgram.c" /* yacc.c:1646  */
 -#line 2387 "awkgram.c" /* yacc.c:1646  */
++#line 2386 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 46:
- #line 569 "awkgram.y" /* yacc.c:1646  */
 -#line 648 "awkgram.y" /* yacc.c:1646  */
++#line 647 "awkgram.y" /* yacc.c:1646  */
      { 
                /*
                 *    -----------------
@@@ -2351,11 -2429,11 +2428,11 @@@
                continue_allowed--;
                fix_break_continue(ip, tbreak, tcont);
          }
- #line 2355 "awkgram.c" /* yacc.c:1646  */
 -#line 2433 "awkgram.c" /* yacc.c:1646  */
++#line 2432 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 47:
- #line 611 "awkgram.y" /* yacc.c:1646  */
 -#line 690 "awkgram.y" /* yacc.c:1646  */
++#line 689 "awkgram.y" /* yacc.c:1646  */
      {
                /*
                 *    -----------------
@@@ -2397,11 -2475,11 +2474,11 @@@
                } /* else
                        $1 and $4 are NULLs */
          }
- #line 2401 "awkgram.c" /* yacc.c:1646  */
 -#line 2479 "awkgram.c" /* yacc.c:1646  */
++#line 2478 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 48:
- #line 653 "awkgram.y" /* yacc.c:1646  */
 -#line 732 "awkgram.y" /* yacc.c:1646  */
++#line 731 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *ip;
                char *var_name = (yyvsp[-5])->lextok;
@@@ -2514,44 -2592,44 +2591,44 @@@ regular_loop
                break_allowed--;
                continue_allowed--;
          }
- #line 2518 "awkgram.c" /* yacc.c:1646  */
 -#line 2596 "awkgram.c" /* yacc.c:1646  */
++#line 2595 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 49:
- #line 766 "awkgram.y" /* yacc.c:1646  */
 -#line 845 "awkgram.y" /* yacc.c:1646  */
++#line 844 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = mk_for_loop((yyvsp[-11]), (yyvsp[-9]), (yyvsp[-6]), 
(yyvsp[-3]), (yyvsp[0]));
  
                break_allowed--;
                continue_allowed--;
          }
- #line 2529 "awkgram.c" /* yacc.c:1646  */
 -#line 2607 "awkgram.c" /* yacc.c:1646  */
++#line 2606 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 50:
- #line 773 "awkgram.y" /* yacc.c:1646  */
 -#line 852 "awkgram.y" /* yacc.c:1646  */
++#line 851 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = mk_for_loop((yyvsp[-10]), (yyvsp[-8]), (INSTRUCTION 
*) NULL, (yyvsp[-3]), (yyvsp[0]));
  
                break_allowed--;
                continue_allowed--;
          }
- #line 2540 "awkgram.c" /* yacc.c:1646  */
 -#line 2618 "awkgram.c" /* yacc.c:1646  */
++#line 2617 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 51:
- #line 780 "awkgram.y" /* yacc.c:1646  */
 -#line 859 "awkgram.y" /* yacc.c:1646  */
++#line 858 "awkgram.y" /* yacc.c:1646  */
      {
                if (do_pretty_print)
                        (yyval) = list_prepend((yyvsp[0]), 
instruction(Op_exec_count));
                else
                        (yyval) = (yyvsp[0]);
          }
- #line 2551 "awkgram.c" /* yacc.c:1646  */
 -#line 2629 "awkgram.c" /* yacc.c:1646  */
++#line 2628 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 52:
- #line 790 "awkgram.y" /* yacc.c:1646  */
 -#line 869 "awkgram.y" /* yacc.c:1646  */
++#line 868 "awkgram.y" /* yacc.c:1646  */
      { 
                if (! break_allowed)
                        error_ln((yyvsp[-1])->source_line,
@@@ -2560,11 -2638,11 +2637,11 @@@
                (yyval) = list_create((yyvsp[-1]));
  
          }
- #line 2564 "awkgram.c" /* yacc.c:1646  */
 -#line 2642 "awkgram.c" /* yacc.c:1646  */
++#line 2641 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 53:
- #line 799 "awkgram.y" /* yacc.c:1646  */
 -#line 878 "awkgram.y" /* yacc.c:1646  */
++#line 877 "awkgram.y" /* yacc.c:1646  */
      {
                if (! continue_allowed)
                        error_ln((yyvsp[-1])->source_line,
@@@ -2573,11 -2651,11 +2650,11 @@@
                (yyval) = list_create((yyvsp[-1]));
  
          }
- #line 2577 "awkgram.c" /* yacc.c:1646  */
 -#line 2655 "awkgram.c" /* yacc.c:1646  */
++#line 2654 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 54:
- #line 808 "awkgram.y" /* yacc.c:1646  */
 -#line 887 "awkgram.y" /* yacc.c:1646  */
++#line 886 "awkgram.y" /* yacc.c:1646  */
      {
                /* if inside function (rule = 0), resolve context at run-time */
                if (rule && rule != Rule)
@@@ -2586,11 -2664,11 +2663,11 @@@
                (yyvsp[-1])->target_jmp = ip_rec;
                (yyval) = list_create((yyvsp[-1]));
          }
- #line 2590 "awkgram.c" /* yacc.c:1646  */
 -#line 2668 "awkgram.c" /* yacc.c:1646  */
++#line 2667 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 55:
- #line 817 "awkgram.y" /* yacc.c:1646  */
 -#line 896 "awkgram.y" /* yacc.c:1646  */
++#line 895 "awkgram.y" /* yacc.c:1646  */
      {
                /* if inside function (rule = 0), resolve context at run-time */
                if (rule == BEGIN || rule == END || rule == ENDFILE)
@@@ -2601,11 -2679,11 +2678,11 @@@
                (yyvsp[-1])->target_endfile = ip_endfile;
                (yyval) = list_create((yyvsp[-1]));
          }
- #line 2605 "awkgram.c" /* yacc.c:1646  */
 -#line 2683 "awkgram.c" /* yacc.c:1646  */
++#line 2682 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 56:
- #line 828 "awkgram.y" /* yacc.c:1646  */
 -#line 907 "awkgram.y" /* yacc.c:1646  */
++#line 906 "awkgram.y" /* yacc.c:1646  */
      {
                /* Initialize the two possible jump targets, the actual target
                 * is resolved at run-time. 
@@@ -2620,20 -2698,20 +2697,20 @@@
                } else
                        (yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
          }
- #line 2624 "awkgram.c" /* yacc.c:1646  */
 -#line 2702 "awkgram.c" /* yacc.c:1646  */
++#line 2701 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 57:
- #line 843 "awkgram.y" /* yacc.c:1646  */
 -#line 922 "awkgram.y" /* yacc.c:1646  */
++#line 921 "awkgram.y" /* yacc.c:1646  */
      {
                if (! in_function)
                        yyerror(_("`return' used outside function context"));
          }
- #line 2633 "awkgram.c" /* yacc.c:1646  */
 -#line 2711 "awkgram.c" /* yacc.c:1646  */
++#line 2710 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 58:
- #line 846 "awkgram.y" /* yacc.c:1646  */
 -#line 925 "awkgram.y" /* yacc.c:1646  */
++#line 924 "awkgram.y" /* yacc.c:1646  */
      {
                if ((yyvsp[-1]) == NULL) {
                        (yyval) = list_create((yyvsp[-3]));
@@@ -2654,17 -2732,17 +2731,17 @@@
                        (yyval) = list_append((yyvsp[-1]), (yyvsp[-3]));
                }
          }
- #line 2658 "awkgram.c" /* yacc.c:1646  */
 -#line 2736 "awkgram.c" /* yacc.c:1646  */
++#line 2735 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 60:
- #line 878 "awkgram.y" /* yacc.c:1646  */
 -#line 957 "awkgram.y" /* yacc.c:1646  */
++#line 956 "awkgram.y" /* yacc.c:1646  */
      { in_print = true; in_parens = 0; }
- #line 2664 "awkgram.c" /* yacc.c:1646  */
 -#line 2742 "awkgram.c" /* yacc.c:1646  */
++#line 2741 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 61:
- #line 879 "awkgram.y" /* yacc.c:1646  */
 -#line 958 "awkgram.y" /* yacc.c:1646  */
++#line 957 "awkgram.y" /* yacc.c:1646  */
      {
                /*
                 * Optimization: plain `print' has no expression list, so $3 is 
null.
@@@ -2761,17 -2839,17 +2838,17 @@@ regular_print
                        }
                }
          }
- #line 2765 "awkgram.c" /* yacc.c:1646  */
 -#line 2843 "awkgram.c" /* yacc.c:1646  */
++#line 2842 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 62:
- #line 976 "awkgram.y" /* yacc.c:1646  */
 -#line 1055 "awkgram.y" /* yacc.c:1646  */
++#line 1054 "awkgram.y" /* yacc.c:1646  */
      { sub_counter = 0; }
- #line 2771 "awkgram.c" /* yacc.c:1646  */
 -#line 2849 "awkgram.c" /* yacc.c:1646  */
++#line 2848 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 63:
- #line 977 "awkgram.y" /* yacc.c:1646  */
 -#line 1056 "awkgram.y" /* yacc.c:1646  */
++#line 1055 "awkgram.y" /* yacc.c:1646  */
      {
                char *arr = (yyvsp[-2])->lextok;
  
@@@ -2804,11 -2882,11 +2881,11 @@@
                        (yyval) = list_append(list_append((yyvsp[0]), 
(yyvsp[-2])), (yyvsp[-3]));
                }
          }
- #line 2808 "awkgram.c" /* yacc.c:1646  */
 -#line 2886 "awkgram.c" /* yacc.c:1646  */
++#line 2885 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 64:
- #line 1014 "awkgram.y" /* yacc.c:1646  */
 -#line 1093 "awkgram.y" /* yacc.c:1646  */
++#line 1092 "awkgram.y" /* yacc.c:1646  */
      {
                static bool warned = false;
                char *arr = (yyvsp[-1])->lextok;
@@@ -2834,52 -2912,52 +2911,52 @@@
                                fatal(_("`delete' is not allowed with 
FUNCTAB"));
                }
          }
- #line 2838 "awkgram.c" /* yacc.c:1646  */
 -#line 2916 "awkgram.c" /* yacc.c:1646  */
++#line 2915 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 65:
- #line 1040 "awkgram.y" /* yacc.c:1646  */
 -#line 1119 "awkgram.y" /* yacc.c:1646  */
++#line 1118 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = optimize_assignment((yyvsp[0])); }
- #line 2844 "awkgram.c" /* yacc.c:1646  */
 -#line 2922 "awkgram.c" /* yacc.c:1646  */
++#line 2921 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 66:
- #line 1045 "awkgram.y" /* yacc.c:1646  */
 -#line 1124 "awkgram.y" /* yacc.c:1646  */
++#line 1123 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 2850 "awkgram.c" /* yacc.c:1646  */
 -#line 2928 "awkgram.c" /* yacc.c:1646  */
++#line 2927 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 67:
- #line 1047 "awkgram.y" /* yacc.c:1646  */
 -#line 1126 "awkgram.y" /* yacc.c:1646  */
++#line 1125 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 2856 "awkgram.c" /* yacc.c:1646  */
 -#line 2934 "awkgram.c" /* yacc.c:1646  */
++#line 2933 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 68:
- #line 1052 "awkgram.y" /* yacc.c:1646  */
 -#line 1131 "awkgram.y" /* yacc.c:1646  */
++#line 1130 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 2862 "awkgram.c" /* yacc.c:1646  */
 -#line 2940 "awkgram.c" /* yacc.c:1646  */
++#line 2939 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 69:
- #line 1054 "awkgram.y" /* yacc.c:1646  */
 -#line 1133 "awkgram.y" /* yacc.c:1646  */
++#line 1132 "awkgram.y" /* yacc.c:1646  */
      {
                if ((yyvsp[-1]) == NULL)
                        (yyval) = list_create((yyvsp[0]));
                else
                        (yyval) = list_prepend((yyvsp[-1]), (yyvsp[0]));
          }
- #line 2873 "awkgram.c" /* yacc.c:1646  */
 -#line 2951 "awkgram.c" /* yacc.c:1646  */
++#line 2950 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 70:
- #line 1061 "awkgram.y" /* yacc.c:1646  */
 -#line 1140 "awkgram.y" /* yacc.c:1646  */
++#line 1139 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 2879 "awkgram.c" /* yacc.c:1646  */
 -#line 2957 "awkgram.c" /* yacc.c:1646  */
++#line 2956 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 71:
- #line 1066 "awkgram.y" /* yacc.c:1646  */
 -#line 1145 "awkgram.y" /* yacc.c:1646  */
++#line 1144 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *casestmt = (yyvsp[0]);
                if ((yyvsp[0]) == NULL)
@@@ -2891,11 -2969,11 +2968,11 @@@
                bcfree((yyvsp[-2]));
                (yyval) = (yyvsp[-4]);
          }
- #line 2895 "awkgram.c" /* yacc.c:1646  */
 -#line 2973 "awkgram.c" /* yacc.c:1646  */
++#line 2972 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 72:
- #line 1078 "awkgram.y" /* yacc.c:1646  */
 -#line 1157 "awkgram.y" /* yacc.c:1646  */
++#line 1156 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *casestmt = (yyvsp[0]);
                if ((yyvsp[0]) == NULL)
@@@ -2906,17 -2984,17 +2983,17 @@@
                (yyvsp[-3])->case_stmt = casestmt;
                (yyval) = (yyvsp[-3]);
          }
- #line 2910 "awkgram.c" /* yacc.c:1646  */
 -#line 2988 "awkgram.c" /* yacc.c:1646  */
++#line 2987 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 73:
- #line 1092 "awkgram.y" /* yacc.c:1646  */
 -#line 1171 "awkgram.y" /* yacc.c:1646  */
++#line 1170 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 2916 "awkgram.c" /* yacc.c:1646  */
 -#line 2994 "awkgram.c" /* yacc.c:1646  */
++#line 2993 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 74:
- #line 1094 "awkgram.y" /* yacc.c:1646  */
 -#line 1173 "awkgram.y" /* yacc.c:1646  */
++#line 1172 "awkgram.y" /* yacc.c:1646  */
      { 
                NODE *n = (yyvsp[0])->memory;
                (void) force_number(n);
@@@ -2924,71 -3002,71 +3001,71 @@@
                bcfree((yyvsp[-1]));
                (yyval) = (yyvsp[0]);
          }
- #line 2928 "awkgram.c" /* yacc.c:1646  */
 -#line 3006 "awkgram.c" /* yacc.c:1646  */
++#line 3005 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 75:
- #line 1102 "awkgram.y" /* yacc.c:1646  */
 -#line 1181 "awkgram.y" /* yacc.c:1646  */
++#line 1180 "awkgram.y" /* yacc.c:1646  */
      {
                bcfree((yyvsp[-1]));
                (yyval) = (yyvsp[0]);
          }
- #line 2937 "awkgram.c" /* yacc.c:1646  */
 -#line 3015 "awkgram.c" /* yacc.c:1646  */
++#line 3014 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 76:
- #line 1107 "awkgram.y" /* yacc.c:1646  */
 -#line 1186 "awkgram.y" /* yacc.c:1646  */
++#line 1185 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 2943 "awkgram.c" /* yacc.c:1646  */
 -#line 3021 "awkgram.c" /* yacc.c:1646  */
++#line 3020 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 77:
- #line 1109 "awkgram.y" /* yacc.c:1646  */
 -#line 1188 "awkgram.y" /* yacc.c:1646  */
++#line 1187 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[0])->opcode = Op_push_re;
                (yyval) = (yyvsp[0]);
          }
- #line 2952 "awkgram.c" /* yacc.c:1646  */
 -#line 3030 "awkgram.c" /* yacc.c:1646  */
++#line 3029 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 78:
- #line 1117 "awkgram.y" /* yacc.c:1646  */
 -#line 1196 "awkgram.y" /* yacc.c:1646  */
++#line 1195 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 2958 "awkgram.c" /* yacc.c:1646  */
 -#line 3036 "awkgram.c" /* yacc.c:1646  */
++#line 3035 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 79:
- #line 1119 "awkgram.y" /* yacc.c:1646  */
 -#line 1198 "awkgram.y" /* yacc.c:1646  */
++#line 1197 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 2964 "awkgram.c" /* yacc.c:1646  */
 -#line 3042 "awkgram.c" /* yacc.c:1646  */
++#line 3041 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 81:
- #line 1129 "awkgram.y" /* yacc.c:1646  */
 -#line 1208 "awkgram.y" /* yacc.c:1646  */
++#line 1207 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = (yyvsp[-1]);
          }
- #line 2972 "awkgram.c" /* yacc.c:1646  */
 -#line 3050 "awkgram.c" /* yacc.c:1646  */
++#line 3049 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 82:
- #line 1136 "awkgram.y" /* yacc.c:1646  */
 -#line 1215 "awkgram.y" /* yacc.c:1646  */
++#line 1214 "awkgram.y" /* yacc.c:1646  */
      {
                in_print = false;
                in_parens = 0;
                (yyval) = NULL;
          }
- #line 2982 "awkgram.c" /* yacc.c:1646  */
 -#line 3060 "awkgram.c" /* yacc.c:1646  */
++#line 3059 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 83:
- #line 1141 "awkgram.y" /* yacc.c:1646  */
 -#line 1220 "awkgram.y" /* yacc.c:1646  */
++#line 1219 "awkgram.y" /* yacc.c:1646  */
      { in_print = false; in_parens = 0; }
- #line 2988 "awkgram.c" /* yacc.c:1646  */
 -#line 3066 "awkgram.c" /* yacc.c:1646  */
++#line 3065 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 84:
- #line 1142 "awkgram.y" /* yacc.c:1646  */
 -#line 1221 "awkgram.y" /* yacc.c:1646  */
++#line 1220 "awkgram.y" /* yacc.c:1646  */
      {
                if ((yyvsp[-2])->redir_type == redirect_twoway
                        && (yyvsp[0])->lasti->opcode == Op_K_getline_redir
@@@ -2996,136 -3074,136 +3073,136 @@@
                        yyerror(_("multistage two-way pipelines don't work"));
                (yyval) = list_prepend((yyvsp[0]), (yyvsp[-2]));
          }
- #line 3000 "awkgram.c" /* yacc.c:1646  */
 -#line 3078 "awkgram.c" /* yacc.c:1646  */
++#line 3077 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 85:
- #line 1153 "awkgram.y" /* yacc.c:1646  */
 -#line 1232 "awkgram.y" /* yacc.c:1646  */
++#line 1231 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = mk_condition((yyvsp[-3]), (yyvsp[-5]), (yyvsp[0]), 
NULL, NULL);
          }
- #line 3008 "awkgram.c" /* yacc.c:1646  */
 -#line 3086 "awkgram.c" /* yacc.c:1646  */
++#line 3085 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 86:
- #line 1158 "awkgram.y" /* yacc.c:1646  */
 -#line 1237 "awkgram.y" /* yacc.c:1646  */
++#line 1236 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = mk_condition((yyvsp[-6]), (yyvsp[-8]), (yyvsp[-3]), 
(yyvsp[-2]), (yyvsp[0]));
          }
- #line 3016 "awkgram.c" /* yacc.c:1646  */
 -#line 3094 "awkgram.c" /* yacc.c:1646  */
++#line 3093 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 91:
- #line 1175 "awkgram.y" /* yacc.c:1646  */
 -#line 1254 "awkgram.y" /* yacc.c:1646  */
++#line 1253 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3022 "awkgram.c" /* yacc.c:1646  */
 -#line 3100 "awkgram.c" /* yacc.c:1646  */
++#line 3099 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 92:
- #line 1177 "awkgram.y" /* yacc.c:1646  */
 -#line 1256 "awkgram.y" /* yacc.c:1646  */
++#line 1255 "awkgram.y" /* yacc.c:1646  */
      {
                bcfree((yyvsp[-1]));
                (yyval) = (yyvsp[0]);
          }
- #line 3031 "awkgram.c" /* yacc.c:1646  */
 -#line 3109 "awkgram.c" /* yacc.c:1646  */
++#line 3108 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 93:
- #line 1185 "awkgram.y" /* yacc.c:1646  */
 -#line 1264 "awkgram.y" /* yacc.c:1646  */
++#line 1263 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3037 "awkgram.c" /* yacc.c:1646  */
 -#line 3115 "awkgram.c" /* yacc.c:1646  */
++#line 3114 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 94:
- #line 1187 "awkgram.y" /* yacc.c:1646  */
-     { (yyval) = (yyvsp[0]) ; }
- #line 3043 "awkgram.c" /* yacc.c:1646  */
 -#line 1266 "awkgram.y" /* yacc.c:1646  */
++#line 1265 "awkgram.y" /* yacc.c:1646  */
+     { (yyval) = (yyvsp[0]); }
 -#line 3121 "awkgram.c" /* yacc.c:1646  */
++#line 3120 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 95:
- #line 1192 "awkgram.y" /* yacc.c:1646  */
 -#line 1271 "awkgram.y" /* yacc.c:1646  */
++#line 1270 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[0])->param_count = 0;
                (yyval) = list_create((yyvsp[0]));
          }
- #line 3052 "awkgram.c" /* yacc.c:1646  */
 -#line 3130 "awkgram.c" /* yacc.c:1646  */
++#line 3129 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 96:
- #line 1197 "awkgram.y" /* yacc.c:1646  */
 -#line 1276 "awkgram.y" /* yacc.c:1646  */
++#line 1275 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[0])->param_count =  (yyvsp[-2])->lasti->param_count + 1;
                (yyval) = list_append((yyvsp[-2]), (yyvsp[0]));
                yyerrok;
          }
- #line 3062 "awkgram.c" /* yacc.c:1646  */
 -#line 3140 "awkgram.c" /* yacc.c:1646  */
++#line 3139 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 97:
- #line 1203 "awkgram.y" /* yacc.c:1646  */
 -#line 1282 "awkgram.y" /* yacc.c:1646  */
++#line 1281 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3068 "awkgram.c" /* yacc.c:1646  */
 -#line 3146 "awkgram.c" /* yacc.c:1646  */
++#line 3145 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 98:
- #line 1205 "awkgram.y" /* yacc.c:1646  */
 -#line 1284 "awkgram.y" /* yacc.c:1646  */
++#line 1283 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[-1]); }
- #line 3074 "awkgram.c" /* yacc.c:1646  */
 -#line 3152 "awkgram.c" /* yacc.c:1646  */
++#line 3151 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 99:
- #line 1207 "awkgram.y" /* yacc.c:1646  */
 -#line 1286 "awkgram.y" /* yacc.c:1646  */
++#line 1285 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[-2]); }
- #line 3080 "awkgram.c" /* yacc.c:1646  */
 -#line 3158 "awkgram.c" /* yacc.c:1646  */
++#line 3157 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 100:
- #line 1213 "awkgram.y" /* yacc.c:1646  */
 -#line 1292 "awkgram.y" /* yacc.c:1646  */
++#line 1291 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3086 "awkgram.c" /* yacc.c:1646  */
 -#line 3164 "awkgram.c" /* yacc.c:1646  */
++#line 3163 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 101:
- #line 1215 "awkgram.y" /* yacc.c:1646  */
 -#line 1294 "awkgram.y" /* yacc.c:1646  */
++#line 1293 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3092 "awkgram.c" /* yacc.c:1646  */
 -#line 3170 "awkgram.c" /* yacc.c:1646  */
++#line 3169 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 102:
- #line 1220 "awkgram.y" /* yacc.c:1646  */
 -#line 1299 "awkgram.y" /* yacc.c:1646  */
++#line 1298 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3098 "awkgram.c" /* yacc.c:1646  */
 -#line 3176 "awkgram.c" /* yacc.c:1646  */
++#line 3175 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 103:
- #line 1222 "awkgram.y" /* yacc.c:1646  */
 -#line 1301 "awkgram.y" /* yacc.c:1646  */
++#line 1300 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3104 "awkgram.c" /* yacc.c:1646  */
 -#line 3182 "awkgram.c" /* yacc.c:1646  */
++#line 3181 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 104:
- #line 1227 "awkgram.y" /* yacc.c:1646  */
 -#line 1306 "awkgram.y" /* yacc.c:1646  */
++#line 1305 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = mk_expression_list(NULL, (yyvsp[0])); }
- #line 3110 "awkgram.c" /* yacc.c:1646  */
 -#line 3188 "awkgram.c" /* yacc.c:1646  */
++#line 3187 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 105:
- #line 1229 "awkgram.y" /* yacc.c:1646  */
 -#line 1308 "awkgram.y" /* yacc.c:1646  */
++#line 1307 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
                yyerrok;
          }
- #line 3119 "awkgram.c" /* yacc.c:1646  */
 -#line 3197 "awkgram.c" /* yacc.c:1646  */
++#line 3196 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 106:
- #line 1234 "awkgram.y" /* yacc.c:1646  */
 -#line 1313 "awkgram.y" /* yacc.c:1646  */
++#line 1312 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3125 "awkgram.c" /* yacc.c:1646  */
 -#line 3203 "awkgram.c" /* yacc.c:1646  */
++#line 3202 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 107:
- #line 1236 "awkgram.y" /* yacc.c:1646  */
 -#line 1315 "awkgram.y" /* yacc.c:1646  */
++#line 1314 "awkgram.y" /* yacc.c:1646  */
      {
                /*
                 * Returning the expression list instead of NULL lets
@@@ -3133,52 -3211,52 +3210,52 @@@
                 */
                (yyval) = (yyvsp[-1]);
          }
- #line 3137 "awkgram.c" /* yacc.c:1646  */
 -#line 3215 "awkgram.c" /* yacc.c:1646  */
++#line 3214 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 108:
- #line 1244 "awkgram.y" /* yacc.c:1646  */
 -#line 1323 "awkgram.y" /* yacc.c:1646  */
++#line 1322 "awkgram.y" /* yacc.c:1646  */
      {
                /* Ditto */
                (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
          }
- #line 3146 "awkgram.c" /* yacc.c:1646  */
 -#line 3224 "awkgram.c" /* yacc.c:1646  */
++#line 3223 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 109:
- #line 1249 "awkgram.y" /* yacc.c:1646  */
 -#line 1328 "awkgram.y" /* yacc.c:1646  */
++#line 1327 "awkgram.y" /* yacc.c:1646  */
      {
                /* Ditto */
                (yyval) = (yyvsp[-2]);
          }
- #line 3155 "awkgram.c" /* yacc.c:1646  */
 -#line 3233 "awkgram.c" /* yacc.c:1646  */
++#line 3232 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 110:
- #line 1258 "awkgram.y" /* yacc.c:1646  */
 -#line 1337 "awkgram.y" /* yacc.c:1646  */
++#line 1336 "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 assignment"));
                (yyval) = mk_assignment((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1]));
          }
- #line 3166 "awkgram.c" /* yacc.c:1646  */
 -#line 3244 "awkgram.c" /* yacc.c:1646  */
++#line 3243 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 111:
- #line 1265 "awkgram.y" /* yacc.c:1646  */
 -#line 1344 "awkgram.y" /* yacc.c:1646  */
++#line 1343 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
- #line 3172 "awkgram.c" /* yacc.c:1646  */
 -#line 3250 "awkgram.c" /* yacc.c:1646  */
++#line 3249 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 112:
- #line 1267 "awkgram.y" /* yacc.c:1646  */
 -#line 1346 "awkgram.y" /* yacc.c:1646  */
++#line 1345 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
- #line 3178 "awkgram.c" /* yacc.c:1646  */
 -#line 3256 "awkgram.c" /* yacc.c:1646  */
++#line 3255 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 113:
- #line 1269 "awkgram.y" /* yacc.c:1646  */
 -#line 1348 "awkgram.y" /* yacc.c:1646  */
++#line 1347 "awkgram.y" /* yacc.c:1646  */
      {
                if ((yyvsp[-2])->lasti->opcode == Op_match_rec)
                        warning_ln((yyvsp[-1])->source_line,
@@@ -3194,11 -3272,11 +3271,11 @@@
                        (yyval) = list_append(list_merge((yyvsp[-2]), 
(yyvsp[0])), (yyvsp[-1]));
                }
          }
- #line 3198 "awkgram.c" /* yacc.c:1646  */
 -#line 3276 "awkgram.c" /* yacc.c:1646  */
++#line 3275 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 114:
- #line 1285 "awkgram.y" /* yacc.c:1646  */
 -#line 1364 "awkgram.y" /* yacc.c:1646  */
++#line 1363 "awkgram.y" /* yacc.c:1646  */
      {
                if (do_lint_old)
                        warning_ln((yyvsp[-1])->source_line,
@@@ -3208,91 -3286,91 +3285,91 @@@
                (yyvsp[-1])->expr_count = 1;
                (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1]));
          }
- #line 3212 "awkgram.c" /* yacc.c:1646  */
 -#line 3290 "awkgram.c" /* yacc.c:1646  */
++#line 3289 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 115:
- #line 1295 "awkgram.y" /* yacc.c:1646  */
 -#line 1374 "awkgram.y" /* yacc.c:1646  */
++#line 1373 "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 3223 "awkgram.c" /* yacc.c:1646  */
 -#line 3301 "awkgram.c" /* yacc.c:1646  */
++#line 3300 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 116:
- #line 1302 "awkgram.y" /* yacc.c:1646  */
 -#line 1381 "awkgram.y" /* yacc.c:1646  */
++#line 1380 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = mk_condition((yyvsp[-4]), (yyvsp[-3]), (yyvsp[-2]), 
(yyvsp[-1]), (yyvsp[0])); }
- #line 3229 "awkgram.c" /* yacc.c:1646  */
 -#line 3307 "awkgram.c" /* yacc.c:1646  */
++#line 3306 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 117:
- #line 1304 "awkgram.y" /* yacc.c:1646  */
 -#line 1383 "awkgram.y" /* yacc.c:1646  */
++#line 1382 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3235 "awkgram.c" /* yacc.c:1646  */
 -#line 3313 "awkgram.c" /* yacc.c:1646  */
++#line 3312 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 118:
- #line 1309 "awkgram.y" /* yacc.c:1646  */
 -#line 1388 "awkgram.y" /* yacc.c:1646  */
++#line 1387 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3241 "awkgram.c" /* yacc.c:1646  */
 -#line 3319 "awkgram.c" /* yacc.c:1646  */
++#line 3318 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 119:
- #line 1311 "awkgram.y" /* yacc.c:1646  */
 -#line 1390 "awkgram.y" /* yacc.c:1646  */
++#line 1389 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3247 "awkgram.c" /* yacc.c:1646  */
 -#line 3325 "awkgram.c" /* yacc.c:1646  */
++#line 3324 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 120:
- #line 1313 "awkgram.y" /* yacc.c:1646  */
 -#line 1392 "awkgram.y" /* yacc.c:1646  */
++#line 1391 "awkgram.y" /* yacc.c:1646  */
      { 
                (yyvsp[0])->opcode = Op_assign_quotient;
                (yyval) = (yyvsp[0]);
          }
- #line 3256 "awkgram.c" /* yacc.c:1646  */
 -#line 3334 "awkgram.c" /* yacc.c:1646  */
++#line 3333 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 121:
- #line 1321 "awkgram.y" /* yacc.c:1646  */
 -#line 1400 "awkgram.y" /* yacc.c:1646  */
++#line 1399 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3262 "awkgram.c" /* yacc.c:1646  */
 -#line 3340 "awkgram.c" /* yacc.c:1646  */
++#line 3339 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 122:
- #line 1323 "awkgram.y" /* yacc.c:1646  */
 -#line 1402 "awkgram.y" /* yacc.c:1646  */
++#line 1401 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3268 "awkgram.c" /* yacc.c:1646  */
 -#line 3346 "awkgram.c" /* yacc.c:1646  */
++#line 3345 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 123:
- #line 1328 "awkgram.y" /* yacc.c:1646  */
 -#line 1407 "awkgram.y" /* yacc.c:1646  */
++#line 1406 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3274 "awkgram.c" /* yacc.c:1646  */
 -#line 3352 "awkgram.c" /* yacc.c:1646  */
++#line 3351 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 124:
- #line 1330 "awkgram.y" /* yacc.c:1646  */
 -#line 1409 "awkgram.y" /* yacc.c:1646  */
++#line 1408 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3280 "awkgram.c" /* yacc.c:1646  */
 -#line 3358 "awkgram.c" /* yacc.c:1646  */
++#line 3357 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 125:
- #line 1335 "awkgram.y" /* yacc.c:1646  */
 -#line 1414 "awkgram.y" /* yacc.c:1646  */
++#line 1413 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3286 "awkgram.c" /* yacc.c:1646  */
 -#line 3364 "awkgram.c" /* yacc.c:1646  */
++#line 3363 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 126:
- #line 1337 "awkgram.y" /* yacc.c:1646  */
 -#line 1416 "awkgram.y" /* yacc.c:1646  */
++#line 1415 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3292 "awkgram.c" /* yacc.c:1646  */
 -#line 3370 "awkgram.c" /* yacc.c:1646  */
++#line 3369 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 127:
- #line 1339 "awkgram.y" /* yacc.c:1646  */
 -#line 1418 "awkgram.y" /* yacc.c:1646  */
++#line 1417 "awkgram.y" /* yacc.c:1646  */
      {
                int count = 2;
                bool is_simple_var = false;
@@@ -3339,47 -3417,47 +3416,47 @@@
                                max_args = count;
                }
          }
- #line 3343 "awkgram.c" /* yacc.c:1646  */
 -#line 3421 "awkgram.c" /* yacc.c:1646  */
++#line 3420 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 129:
- #line 1391 "awkgram.y" /* yacc.c:1646  */
 -#line 1470 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3427 "awkgram.c" /* yacc.c:1646  */
++#line 1469 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3349 "awkgram.c" /* yacc.c:1646  */
++#line 3426 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 130:
- #line 1393 "awkgram.y" /* yacc.c:1646  */
 -#line 1472 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3433 "awkgram.c" /* yacc.c:1646  */
++#line 1471 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3355 "awkgram.c" /* yacc.c:1646  */
++#line 3432 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 131:
- #line 1395 "awkgram.y" /* yacc.c:1646  */
 -#line 1474 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3439 "awkgram.c" /* yacc.c:1646  */
++#line 1473 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3361 "awkgram.c" /* yacc.c:1646  */
++#line 3438 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 132:
- #line 1397 "awkgram.y" /* yacc.c:1646  */
 -#line 1476 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3445 "awkgram.c" /* yacc.c:1646  */
++#line 1475 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3367 "awkgram.c" /* yacc.c:1646  */
++#line 3444 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 133:
- #line 1399 "awkgram.y" /* yacc.c:1646  */
 -#line 1478 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3451 "awkgram.c" /* yacc.c:1646  */
++#line 1477 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3373 "awkgram.c" /* yacc.c:1646  */
++#line 3450 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 134:
- #line 1401 "awkgram.y" /* yacc.c:1646  */
 -#line 1480 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3457 "awkgram.c" /* yacc.c:1646  */
++#line 1479 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3379 "awkgram.c" /* yacc.c:1646  */
++#line 3456 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 135:
- #line 1403 "awkgram.y" /* yacc.c:1646  */
 -#line 1482 "awkgram.y" /* yacc.c:1646  */
++#line 1481 "awkgram.y" /* yacc.c:1646  */
      {
                /*
                 * In BEGINFILE/ENDFILE, allow `getline [var] < file'
@@@ -3393,29 -3471,29 +3470,29 @@@
                                _("non-redirected `getline' undefined inside 
END action"));
                (yyval) = mk_getline((yyvsp[-2]), (yyvsp[-1]), (yyvsp[0]), 
redirect_input);
          }
- #line 3397 "awkgram.c" /* yacc.c:1646  */
 -#line 3475 "awkgram.c" /* yacc.c:1646  */
++#line 3474 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 136:
- #line 1417 "awkgram.y" /* yacc.c:1646  */
 -#line 1496 "awkgram.y" /* yacc.c:1646  */
++#line 1495 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[0])->opcode = Op_postincrement;
                (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
          }
- #line 3406 "awkgram.c" /* yacc.c:1646  */
 -#line 3484 "awkgram.c" /* yacc.c:1646  */
++#line 3483 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 137:
- #line 1422 "awkgram.y" /* yacc.c:1646  */
 -#line 1501 "awkgram.y" /* yacc.c:1646  */
++#line 1500 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[0])->opcode = Op_postdecrement;
                (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
          }
- #line 3415 "awkgram.c" /* yacc.c:1646  */
 -#line 3493 "awkgram.c" /* yacc.c:1646  */
++#line 3492 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 138:
- #line 1427 "awkgram.y" /* yacc.c:1646  */
 -#line 1506 "awkgram.y" /* yacc.c:1646  */
++#line 1505 "awkgram.y" /* yacc.c:1646  */
      {
                if (do_lint_old) {
                    warning_ln((yyvsp[-1])->source_line,
@@@ -3435,64 -3513,64 +3512,64 @@@
                        (yyval) = list_append(list_merge(t, (yyvsp[0])), 
(yyvsp[-1]));
                }
          }
- #line 3439 "awkgram.c" /* yacc.c:1646  */
 -#line 3517 "awkgram.c" /* yacc.c:1646  */
++#line 3516 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 139:
- #line 1452 "awkgram.y" /* yacc.c:1646  */
 -#line 1531 "awkgram.y" /* yacc.c:1646  */
++#line 1530 "awkgram.y" /* yacc.c:1646  */
      {
                  (yyval) = mk_getline((yyvsp[-1]), (yyvsp[0]), (yyvsp[-3]), 
(yyvsp[-2])->redir_type);
                  bcfree((yyvsp[-2]));
                }
- #line 3448 "awkgram.c" /* yacc.c:1646  */
 -#line 3526 "awkgram.c" /* yacc.c:1646  */
++#line 3525 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 140:
- #line 1458 "awkgram.y" /* yacc.c:1646  */
 -#line 1537 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3532 "awkgram.c" /* yacc.c:1646  */
++#line 1536 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3454 "awkgram.c" /* yacc.c:1646  */
++#line 3531 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 141:
- #line 1460 "awkgram.y" /* yacc.c:1646  */
 -#line 1539 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3538 "awkgram.c" /* yacc.c:1646  */
++#line 1538 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3460 "awkgram.c" /* yacc.c:1646  */
++#line 3537 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 142:
- #line 1462 "awkgram.y" /* yacc.c:1646  */
 -#line 1541 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3544 "awkgram.c" /* yacc.c:1646  */
++#line 1540 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3466 "awkgram.c" /* yacc.c:1646  */
++#line 3543 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 143:
- #line 1464 "awkgram.y" /* yacc.c:1646  */
 -#line 1543 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3550 "awkgram.c" /* yacc.c:1646  */
++#line 1542 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3472 "awkgram.c" /* yacc.c:1646  */
++#line 3549 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 144:
- #line 1466 "awkgram.y" /* yacc.c:1646  */
 -#line 1545 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3556 "awkgram.c" /* yacc.c:1646  */
++#line 1544 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3478 "awkgram.c" /* yacc.c:1646  */
++#line 3555 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 145:
- #line 1468 "awkgram.y" /* yacc.c:1646  */
 -#line 1547 "awkgram.y" /* yacc.c:1646  */
 -    { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
 -#line 3562 "awkgram.c" /* yacc.c:1646  */
++#line 1546 "awkgram.y" /* yacc.c:1646  */
 +    { (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1])); }
- #line 3484 "awkgram.c" /* yacc.c:1646  */
++#line 3561 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 146:
- #line 1473 "awkgram.y" /* yacc.c:1646  */
 -#line 1552 "awkgram.y" /* yacc.c:1646  */
++#line 1551 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = list_create((yyvsp[0]));
          }
- #line 3492 "awkgram.c" /* yacc.c:1646  */
 -#line 3570 "awkgram.c" /* yacc.c:1646  */
++#line 3569 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 147:
- #line 1477 "awkgram.y" /* yacc.c:1646  */
 -#line 1556 "awkgram.y" /* yacc.c:1646  */
++#line 1555 "awkgram.y" /* yacc.c:1646  */
      {
                if ((yyvsp[0])->opcode == Op_match_rec) {
                        (yyvsp[0])->opcode = Op_nomatch;
@@@ -3524,37 -3602,37 +3601,37 @@@
                        }
                }
           }
- #line 3528 "awkgram.c" /* yacc.c:1646  */
 -#line 3606 "awkgram.c" /* yacc.c:1646  */
++#line 3605 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 148:
- #line 1509 "awkgram.y" /* yacc.c:1646  */
 -#line 1588 "awkgram.y" /* yacc.c:1646  */
++#line 1587 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[-1]); }
- #line 3534 "awkgram.c" /* yacc.c:1646  */
 -#line 3612 "awkgram.c" /* yacc.c:1646  */
++#line 3611 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 149:
- #line 1511 "awkgram.y" /* yacc.c:1646  */
 -#line 1590 "awkgram.y" /* yacc.c:1646  */
++#line 1589 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
                if ((yyval) == NULL)
                        YYABORT;
          }
- #line 3544 "awkgram.c" /* yacc.c:1646  */
 -#line 3622 "awkgram.c" /* yacc.c:1646  */
++#line 3621 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 150:
- #line 1517 "awkgram.y" /* yacc.c:1646  */
 -#line 1596 "awkgram.y" /* yacc.c:1646  */
++#line 1595 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
                if ((yyval) == NULL)
                        YYABORT;
          }
- #line 3554 "awkgram.c" /* yacc.c:1646  */
 -#line 3632 "awkgram.c" /* yacc.c:1646  */
++#line 3631 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 151:
- #line 1523 "awkgram.y" /* yacc.c:1646  */
 -#line 1602 "awkgram.y" /* yacc.c:1646  */
++#line 1601 "awkgram.y" /* yacc.c:1646  */
      {
                static bool warned = false;
  
@@@ -3567,45 -3645,45 +3644,45 @@@
                if ((yyval) == NULL)
                        YYABORT;
          }
- #line 3571 "awkgram.c" /* yacc.c:1646  */
 -#line 3649 "awkgram.c" /* yacc.c:1646  */
++#line 3648 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 154:
- #line 1538 "awkgram.y" /* yacc.c:1646  */
 -#line 1617 "awkgram.y" /* yacc.c:1646  */
++#line 1616 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[-1])->opcode = Op_preincrement;
                (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
          }
- #line 3580 "awkgram.c" /* yacc.c:1646  */
 -#line 3658 "awkgram.c" /* yacc.c:1646  */
++#line 3657 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 155:
- #line 1543 "awkgram.y" /* yacc.c:1646  */
 -#line 1622 "awkgram.y" /* yacc.c:1646  */
++#line 1621 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[-1])->opcode = Op_predecrement;
                (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
          }
- #line 3589 "awkgram.c" /* yacc.c:1646  */
 -#line 3667 "awkgram.c" /* yacc.c:1646  */
++#line 3666 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 156:
- #line 1548 "awkgram.y" /* yacc.c:1646  */
 -#line 1627 "awkgram.y" /* yacc.c:1646  */
++#line 1626 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = list_create((yyvsp[0]));
          }
- #line 3597 "awkgram.c" /* yacc.c:1646  */
 -#line 3675 "awkgram.c" /* yacc.c:1646  */
++#line 3674 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 157:
- #line 1552 "awkgram.y" /* yacc.c:1646  */
 -#line 1631 "awkgram.y" /* yacc.c:1646  */
++#line 1630 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = list_create((yyvsp[0]));
          }
- #line 3605 "awkgram.c" /* yacc.c:1646  */
 -#line 3683 "awkgram.c" /* yacc.c:1646  */
++#line 3682 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 158:
- #line 1556 "awkgram.y" /* yacc.c:1646  */
 -#line 1635 "awkgram.y" /* yacc.c:1646  */
++#line 1634 "awkgram.y" /* yacc.c:1646  */
      {
                if ((yyvsp[0])->lasti->opcode == Op_push_i
                        && ((yyvsp[0])->lasti->memory->flags & (STRCUR|STRING)) 
== 0
@@@ -3620,33 -3698,34 +3697,33 @@@
                        (yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
                }
          }
- #line 3624 "awkgram.c" /* yacc.c:1646  */
 -#line 3702 "awkgram.c" /* yacc.c:1646  */
++#line 3701 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 159:
- #line 1571 "awkgram.y" /* yacc.c:1646  */
 -#line 1650 "awkgram.y" /* yacc.c:1646  */
++#line 1649 "awkgram.y" /* yacc.c:1646  */
      {
            /*
             * was: $$ = $2
             * POSIX semantics: force a conversion to numeric type
             */
 -              (yyvsp[-1])->opcode = Op_plus_i;
 -              (yyvsp[-1])->memory = make_number(0.0);
 +              (yyvsp[-1])->opcode = Op_unary_plus;
                (yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
          }
- #line 3637 "awkgram.c" /* yacc.c:1646  */
 -#line 3716 "awkgram.c" /* yacc.c:1646  */
++#line 3714 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 160:
- #line 1583 "awkgram.y" /* yacc.c:1646  */
 -#line 1663 "awkgram.y" /* yacc.c:1646  */
++#line 1661 "awkgram.y" /* yacc.c:1646  */
      {
                func_use((yyvsp[0])->lasti->func_name, FUNC_USE);
                (yyval) = (yyvsp[0]);
          }
- #line 3646 "awkgram.c" /* yacc.c:1646  */
 -#line 3725 "awkgram.c" /* yacc.c:1646  */
++#line 3723 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 161:
- #line 1588 "awkgram.y" /* yacc.c:1646  */
 -#line 1668 "awkgram.y" /* yacc.c:1646  */
++#line 1666 "awkgram.y" /* yacc.c:1646  */
      {
                /* indirect function call */
                INSTRUCTION *f, *t;
@@@ -3678,13 -3757,25 +3755,25 @@@
                 */
  
                (yyval) = list_prepend((yyvsp[0]), t);
+               at_seen = false;
          }
- #line 3683 "awkgram.c" /* yacc.c:1646  */
 -#line 3763 "awkgram.c" /* yacc.c:1646  */
++#line 3761 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 162:
- #line 1624 "awkgram.y" /* yacc.c:1646  */
 -#line 1705 "awkgram.y" /* yacc.c:1646  */
++#line 1703 "awkgram.y" /* yacc.c:1646  */
      {
+               NODE *n;
+ 
+               if (! at_seen) {
+                       n = lookup((yyvsp[-3])->func_name);
+                       if (n != NULL && n->type != Node_func
+                           && n->type != Node_ext_func && n->type != 
Node_old_ext_func) {
+                               error_ln((yyvsp[-3])->source_line,
+                                       _("attempt to use non-function `%s' in 
function call"),
+                                               (yyvsp[-3])->func_name);
+                       }
+               }
                param_sanity((yyvsp[-1]));
                (yyvsp[-3])->opcode = Op_func_call;
                (yyvsp[-3])->func_body = NULL;
@@@ -3697,49 -3788,49 +3786,49 @@@
                        (yyval) = list_append(t, (yyvsp[-3]));
                }
          }
- #line 3701 "awkgram.c" /* yacc.c:1646  */
 -#line 3792 "awkgram.c" /* yacc.c:1646  */
++#line 3790 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 163:
- #line 1641 "awkgram.y" /* yacc.c:1646  */
 -#line 1733 "awkgram.y" /* yacc.c:1646  */
++#line 1731 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3707 "awkgram.c" /* yacc.c:1646  */
 -#line 3798 "awkgram.c" /* yacc.c:1646  */
++#line 3796 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 164:
- #line 1643 "awkgram.y" /* yacc.c:1646  */
 -#line 1735 "awkgram.y" /* yacc.c:1646  */
++#line 1733 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3713 "awkgram.c" /* yacc.c:1646  */
 -#line 3804 "awkgram.c" /* yacc.c:1646  */
++#line 3802 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 165:
- #line 1648 "awkgram.y" /* yacc.c:1646  */
 -#line 1740 "awkgram.y" /* yacc.c:1646  */
++#line 1738 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3719 "awkgram.c" /* yacc.c:1646  */
 -#line 3810 "awkgram.c" /* yacc.c:1646  */
++#line 3808 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 166:
- #line 1650 "awkgram.y" /* yacc.c:1646  */
 -#line 1742 "awkgram.y" /* yacc.c:1646  */
++#line 1740 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[-1]); }
- #line 3725 "awkgram.c" /* yacc.c:1646  */
 -#line 3816 "awkgram.c" /* yacc.c:1646  */
++#line 3814 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 167:
- #line 1655 "awkgram.y" /* yacc.c:1646  */
 -#line 1747 "awkgram.y" /* yacc.c:1646  */
++#line 1745 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3731 "awkgram.c" /* yacc.c:1646  */
 -#line 3822 "awkgram.c" /* yacc.c:1646  */
++#line 3820 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 168:
- #line 1657 "awkgram.y" /* yacc.c:1646  */
 -#line 1749 "awkgram.y" /* yacc.c:1646  */
++#line 1747 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
          }
- #line 3739 "awkgram.c" /* yacc.c:1646  */
 -#line 3830 "awkgram.c" /* yacc.c:1646  */
++#line 3828 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 169:
- #line 1664 "awkgram.y" /* yacc.c:1646  */
 -#line 1756 "awkgram.y" /* yacc.c:1646  */
++#line 1754 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *ip = (yyvsp[0])->lasti; 
                int count = ip->sub_count;      /* # of SUBSEP-seperated 
expressions */
@@@ -3753,11 -3844,11 +3842,11 @@@
                sub_counter++;  /* count # of dimensions */
                (yyval) = (yyvsp[0]);
          }
- #line 3757 "awkgram.c" /* yacc.c:1646  */
 -#line 3848 "awkgram.c" /* yacc.c:1646  */
++#line 3846 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 170:
- #line 1681 "awkgram.y" /* yacc.c:1646  */
 -#line 1773 "awkgram.y" /* yacc.c:1646  */
++#line 1771 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *t = (yyvsp[-1]);
                if ((yyvsp[-1]) == NULL) {
@@@ -3771,31 -3862,31 +3860,31 @@@
                        (yyvsp[0])->sub_count = count_expressions(&t, false);
                (yyval) = list_append(t, (yyvsp[0]));
          }
- #line 3775 "awkgram.c" /* yacc.c:1646  */
 -#line 3866 "awkgram.c" /* yacc.c:1646  */
++#line 3864 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 171:
- #line 1698 "awkgram.y" /* yacc.c:1646  */
 -#line 1790 "awkgram.y" /* yacc.c:1646  */
++#line 1788 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); }
- #line 3781 "awkgram.c" /* yacc.c:1646  */
 -#line 3872 "awkgram.c" /* yacc.c:1646  */
++#line 3870 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 172:
- #line 1700 "awkgram.y" /* yacc.c:1646  */
 -#line 1792 "awkgram.y" /* yacc.c:1646  */
++#line 1790 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
          }
- #line 3789 "awkgram.c" /* yacc.c:1646  */
 -#line 3880 "awkgram.c" /* yacc.c:1646  */
++#line 3878 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 173:
- #line 1707 "awkgram.y" /* yacc.c:1646  */
 -#line 1799 "awkgram.y" /* yacc.c:1646  */
++#line 1797 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[-1]); }
- #line 3795 "awkgram.c" /* yacc.c:1646  */
 -#line 3886 "awkgram.c" /* yacc.c:1646  */
++#line 3884 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 174:
- #line 1712 "awkgram.y" /* yacc.c:1646  */
 -#line 1804 "awkgram.y" /* yacc.c:1646  */
++#line 1802 "awkgram.y" /* yacc.c:1646  */
      {
                char *var_name = (yyvsp[0])->lextok;
  
@@@ -3803,22 -3894,22 +3892,22 @@@
                (yyvsp[0])->memory = variable((yyvsp[0])->source_line, 
var_name, Node_var_new);
                (yyval) = list_create((yyvsp[0]));
          }
- #line 3807 "awkgram.c" /* yacc.c:1646  */
 -#line 3898 "awkgram.c" /* yacc.c:1646  */
++#line 3896 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 175:
- #line 1720 "awkgram.y" /* yacc.c:1646  */
 -#line 1812 "awkgram.y" /* yacc.c:1646  */
++#line 1810 "awkgram.y" /* yacc.c:1646  */
      {
                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 3818 "awkgram.c" /* yacc.c:1646  */
 -#line 3909 "awkgram.c" /* yacc.c:1646  */
++#line 3907 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 176:
- #line 1730 "awkgram.y" /* yacc.c:1646  */
 -#line 1822 "awkgram.y" /* yacc.c:1646  */
++#line 1820 "awkgram.y" /* yacc.c:1646  */
      {
                INSTRUCTION *ip = (yyvsp[0])->nexti;
                if (ip->opcode == Op_push
@@@ -3830,73 -3921,73 +3919,73 @@@
                } else
                        (yyval) = (yyvsp[0]);
          }
- #line 3834 "awkgram.c" /* yacc.c:1646  */
 -#line 3925 "awkgram.c" /* yacc.c:1646  */
++#line 3923 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 177:
- #line 1742 "awkgram.y" /* yacc.c:1646  */
 -#line 1834 "awkgram.y" /* yacc.c:1646  */
++#line 1832 "awkgram.y" /* yacc.c:1646  */
      {
                (yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
                if ((yyvsp[0]) != NULL)
                        mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
          }
- #line 3844 "awkgram.c" /* yacc.c:1646  */
 -#line 3935 "awkgram.c" /* yacc.c:1646  */
++#line 3933 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 178:
- #line 1751 "awkgram.y" /* yacc.c:1646  */
 -#line 1843 "awkgram.y" /* yacc.c:1646  */
++#line 1841 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[0])->opcode = Op_postincrement;
          }
- #line 3852 "awkgram.c" /* yacc.c:1646  */
 -#line 3943 "awkgram.c" /* yacc.c:1646  */
++#line 3941 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 179:
- #line 1755 "awkgram.y" /* yacc.c:1646  */
 -#line 1847 "awkgram.y" /* yacc.c:1646  */
++#line 1845 "awkgram.y" /* yacc.c:1646  */
      {
                (yyvsp[0])->opcode = Op_postdecrement;
          }
- #line 3860 "awkgram.c" /* yacc.c:1646  */
 -#line 3951 "awkgram.c" /* yacc.c:1646  */
++#line 3949 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 180:
- #line 1758 "awkgram.y" /* yacc.c:1646  */
 -#line 1850 "awkgram.y" /* yacc.c:1646  */
++#line 1848 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = NULL; }
- #line 3866 "awkgram.c" /* yacc.c:1646  */
 -#line 3957 "awkgram.c" /* yacc.c:1646  */
++#line 3955 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 182:
- #line 1766 "awkgram.y" /* yacc.c:1646  */
 -#line 1858 "awkgram.y" /* yacc.c:1646  */
++#line 1856 "awkgram.y" /* yacc.c:1646  */
      { yyerrok; }
- #line 3872 "awkgram.c" /* yacc.c:1646  */
 -#line 3963 "awkgram.c" /* yacc.c:1646  */
++#line 3961 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 183:
- #line 1770 "awkgram.y" /* yacc.c:1646  */
 -#line 1862 "awkgram.y" /* yacc.c:1646  */
++#line 1860 "awkgram.y" /* yacc.c:1646  */
      { yyerrok; }
- #line 3878 "awkgram.c" /* yacc.c:1646  */
 -#line 3969 "awkgram.c" /* yacc.c:1646  */
++#line 3967 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 186:
- #line 1779 "awkgram.y" /* yacc.c:1646  */
 -#line 1871 "awkgram.y" /* yacc.c:1646  */
++#line 1869 "awkgram.y" /* yacc.c:1646  */
      { yyerrok; }
- #line 3884 "awkgram.c" /* yacc.c:1646  */
 -#line 3975 "awkgram.c" /* yacc.c:1646  */
++#line 3973 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 187:
- #line 1783 "awkgram.y" /* yacc.c:1646  */
 -#line 1875 "awkgram.y" /* yacc.c:1646  */
++#line 1873 "awkgram.y" /* yacc.c:1646  */
      { (yyval) = (yyvsp[0]); yyerrok; }
- #line 3890 "awkgram.c" /* yacc.c:1646  */
 -#line 3981 "awkgram.c" /* yacc.c:1646  */
++#line 3979 "awkgram.c" /* yacc.c:1646  */
      break;
  
    case 188:
- #line 1787 "awkgram.y" /* yacc.c:1646  */
 -#line 1879 "awkgram.y" /* yacc.c:1646  */
++#line 1877 "awkgram.y" /* yacc.c:1646  */
      { yyerrok; }
- #line 3896 "awkgram.c" /* yacc.c:1646  */
 -#line 3987 "awkgram.c" /* yacc.c:1646  */
++#line 3985 "awkgram.c" /* yacc.c:1646  */
      break;
  
  
- #line 3900 "awkgram.c" /* yacc.c:1646  */
 -#line 3991 "awkgram.c" /* yacc.c:1646  */
++#line 3989 "awkgram.c" /* yacc.c:1646  */
        default: break;
      }
    /* User semantic actions sometimes alter yychar, and that requires
@@@ -4124,7 -4215,7 +4213,7 @@@ yyreturn
  #endif
    return yyresult;
  }
- #line 1789 "awkgram.y" /* yacc.c:1906  */
 -#line 1881 "awkgram.y" /* yacc.c:1906  */
++#line 1879 "awkgram.y" /* yacc.c:1906  */
  
  
  struct token {
@@@ -4167,89 -4258,93 +4256,88 @@@ 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,      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},
 +static 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 },
  #ifdef ARRAYDEBUG
 -{"adump",     Op_builtin,    LEX_BUILTIN,     GAWKX|A(1)|A(2)|DEBUG_USE,      
do_adump,       0},
 +{"adump",     Op_builtin,    LEX_BUILTIN,     GAWKX|A(1)|A(2)|DEBUG_USE,      
do_adump },
  #endif
 -{"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},
 -{"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)},
 +{"and",               Op_builtin,    LEX_BUILTIN,     GAWKX,          0 },
 +{"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),   0 },
 +{"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),     0 },
 +{"continue",  Op_K_continue, LEX_CONTINUE,    0,              0 },
 +{"cos",               Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   0 },
 +{"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 },
- {"div",               Op_builtin,      LEX_BUILTIN,   GAWKX|A(3)|ARG3_IS_ARR, 
do_div },
 +{"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),           0 },
  #ifdef DYNAMIC
 -{"extension", Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_ext, 
0},
 +{"extension", Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_ext 
},
  #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)},
 -{"intdiv",    Op_builtin,      LEX_BUILTIN,   GAWKX|A(3),     do_intdiv,      
MPF(intdiv)},
 -{"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)},
 +{"fflush",    Op_builtin,      LEX_BUILTIN,   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),   0 },
++{"intdiv",    Op_builtin,      LEX_BUILTIN,   GAWKX|A(3)|ARG3_IS_ARR, 
do_intdiv },
 +{"isarray",   Op_builtin,      LEX_BUILTIN,   GAWKX|A(1),     do_isarray },
 +{"length",    Op_builtin,      LEX_LENGTH,    A(0)|A(1),      do_length },
 +{"load",      Op_symbol,       LEX_LOAD,      GAWKX,          0 },
 +{"log",               Op_builtin,      LEX_BUILTIN,   A(1),           0 },
 +{"lshift",    Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     0 },
 +{"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,    0,              0 },
 +{"or",                Op_builtin,    LEX_BUILTIN,     GAWKX,          0 },
 +{"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),   0 },
 +{"return",    Op_K_return,     LEX_RETURN,    NOT_OLD,        0 },
 +{"rshift",    Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     0 },
 +{"sin",               Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   0 },
 +{"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),           0 },
 +{"srand",     Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(0)|A(1), 0 },
  #if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
 -{"stopme",    Op_builtin,     LEX_BUILTIN,    GAWKX|A(0)|DEBUG_USE,   stopme, 
        0},
 +{"stopme",    Op_builtin,     LEX_BUILTIN,    GAWKX|A(0)|DEBUG_USE,   stopme 
},
  #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)},
 +{"strftime",  Op_builtin,      LEX_BUILTIN,   GAWKX|A(0)|A(1)|A(2)|A(3), 
do_strftime },
 +{"strtonum",  Op_builtin,    LEX_BUILTIN,     GAWKX|A(1),     0 },
 +{"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,          0 },
  };
  
- #if MBS_SUPPORT
  /* Variable containing the current shift state.  */
  static mbstate_t cur_mbstate;
  /* Ring buffer containing current characters.  */
@@@ -7862,9 -8205,26 +8007,21 @@@ lookup_builtin(const char *name
  {
        int mid = check_special(name);
  
-       if (mid == -1 || tokentab[mid].class != LEX_BUILTIN)
+       if (mid == -1)
                return NULL;
  
+       switch (tokentab[mid].class) {
+       case LEX_BUILTIN:
+       case LEX_LENGTH:
+               break;
+       default:
+               return NULL;
+       }
+ 
 -#ifdef HAVE_MPFR
 -      if (do_mpfr)
 -              return tokentab[mid].ptr2;
 -#endif
 -
+       /* And another special case... */
+       if (tokentab[mid].value == Op_sub_builtin)
+               return (builtin_func_t) do_sub;
+ 
        return tokentab[mid].ptr;
  }
  
diff --cc awkgram.y
index eaa615a,d429c9c..be5c8c3
--- a/awkgram.y
+++ b/awkgram.y
@@@ -1828,89 -1920,93 +1918,88 @@@ 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,      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},
 +static 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 },
  #ifdef ARRAYDEBUG
 -{"adump",     Op_builtin,    LEX_BUILTIN,     GAWKX|A(1)|A(2)|DEBUG_USE,      
do_adump,       0},
 +{"adump",     Op_builtin,    LEX_BUILTIN,     GAWKX|A(1)|A(2)|DEBUG_USE,      
do_adump },
  #endif
 -{"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},
 -{"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)},
 +{"and",               Op_builtin,    LEX_BUILTIN,     GAWKX,          0 },
 +{"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),   0 },
 +{"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),     0 },
 +{"continue",  Op_K_continue, LEX_CONTINUE,    0,              0 },
 +{"cos",               Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   0 },
 +{"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 },
- {"div",               Op_builtin,      LEX_BUILTIN,   GAWKX|A(3)|ARG3_IS_ARR, 
do_div },
 +{"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),           0 },
  #ifdef DYNAMIC
 -{"extension", Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_ext, 
0},
 +{"extension", Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_ext 
},
  #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)},
 -{"intdiv",    Op_builtin,      LEX_BUILTIN,   GAWKX|A(3),     do_intdiv,      
MPF(intdiv)},
 -{"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)},
 +{"fflush",    Op_builtin,      LEX_BUILTIN,   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),   0 },
++{"intdiv",    Op_builtin,      LEX_BUILTIN,   GAWKX|A(3)|ARG3_IS_ARR, 
do_intdiv },
 +{"isarray",   Op_builtin,      LEX_BUILTIN,   GAWKX|A(1),     do_isarray },
 +{"length",    Op_builtin,      LEX_LENGTH,    A(0)|A(1),      do_length },
 +{"load",      Op_symbol,       LEX_LOAD,      GAWKX,          0 },
 +{"log",               Op_builtin,      LEX_BUILTIN,   A(1),           0 },
 +{"lshift",    Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     0 },
 +{"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,    0,              0 },
 +{"or",                Op_builtin,    LEX_BUILTIN,     GAWKX,          0 },
 +{"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),   0 },
 +{"return",    Op_K_return,     LEX_RETURN,    NOT_OLD,        0 },
 +{"rshift",    Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     0 },
 +{"sin",               Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   0 },
 +{"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),           0 },
 +{"srand",     Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(0)|A(1), 0 },
  #if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
 -{"stopme",    Op_builtin,     LEX_BUILTIN,    GAWKX|A(0)|DEBUG_USE,   stopme, 
        0},
 +{"stopme",    Op_builtin,     LEX_BUILTIN,    GAWKX|A(0)|DEBUG_USE,   stopme 
},
  #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)},
 +{"strftime",  Op_builtin,      LEX_BUILTIN,   GAWKX|A(0)|A(1)|A(2)|A(3), 
do_strftime },
 +{"strtonum",  Op_builtin,    LEX_BUILTIN,     GAWKX|A(1),     0 },
 +{"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,          0 },
  };
  
- #if MBS_SUPPORT
  /* Variable containing the current shift state.  */
  static mbstate_t cur_mbstate;
  /* Ring buffer containing current characters.  */
@@@ -5523,8 -5867,25 +5669,20 @@@ lookup_builtin(const char *name
  {
        int mid = check_special(name);
  
-       if (mid == -1 || tokentab[mid].class != LEX_BUILTIN)
+       if (mid == -1)
+               return NULL;
+ 
+       switch (tokentab[mid].class) {
+       case LEX_BUILTIN:
+       case LEX_LENGTH:
+               break;
+       default:
                return NULL;
+       }
+ 
 -#ifdef HAVE_MPFR
 -      if (do_mpfr)
 -              return tokentab[mid].ptr2;
 -#endif
 -
+       /* And another special case... */
+       if (tokentab[mid].value == Op_sub_builtin)
+               return (builtin_func_t) do_sub;
  
        return tokentab[mid].ptr;
  }
diff --cc builtin.c
index 4b3670a,b70176d..a3fb7a5
--- a/builtin.c
+++ b/builtin.c
@@@ -111,12 -129,35 +111,16 @@@ wrerror
        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"));
+       if ((rp != NULL) ? is_non_fatal_redirect(rp->value) : 
is_non_fatal_std(fp))
+               update_ERRNO_int(errno);
+       else
+               fatal(_("%s to \"%s\" failed (%s)"), from,
+                       rp ? rp->value : _("standard output"),
+                       errno ? strerror(errno) : _("reason unknown"));
  }
  
 -/* do_exp --- exponential function */
 -
 -NODE *
 -do_exp(int nargs)
 -{
 -      NODE *tmp;
 -      double d, res;
 -
 -      tmp = POP_SCALAR();
 -      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 -              lintwarn(_("exp: received non-numeric argument"));
 -      d = force_number(tmp)->numbr;
 -      DEREF(tmp);
 -      errno = 0;
 -      res = exp(d);
 -      if (errno == ERANGE)
 -              warning(_("exp: argument %g is out of range"), d);
 -      return make_number((AWKNUM) res);
 -}
  
  /* stdfile --- return fp for a standard file */
  
@@@ -743,14 -1859,7 +725,11 @@@ do_substr(int nargs
                *cp = '\0';
                r = make_str_node(substr, cp - substr, ALREADY_MALLOCED);
        }
- #else
-       r = make_string(t1->stptr + indx, length);
- #endif
  
 +finish:
 +      if (t3 != NULL)
 +              DEREF(t3);
 +      DEREF(t2);
        DEREF(t1);
        return r;
  }
@@@ -1794,7 -3072,457 +1773,147 @@@ done
        return make_number((AWKNUM) matches);
  }
  
+ /* call_sub --- call do_sub indirectly */
+ 
+ NODE *
+ call_sub(const char *name, int nargs)
+ {
+       unsigned int flags = 0;
+       NODE *regex, *replace, *glob_flag;
+       NODE **lhs, *rhs;
+       NODE *zero = make_number(0.0);
+       NODE *result;
+ 
+       if (name[0] == 'g') {
+               if (name[1] == 'e')
+                       flags = GENSUB;
+               else
+                       flags = GSUB;
+       }
+ 
+       if (flags == 0 || flags == GSUB) {
+               /* sub or gsub */
+               if (nargs != 2)
+                       fatal(_("%s: can be called indirectly only with two 
arguments"), name);
+ 
+               replace = POP_STRING();
+               regex = POP();  /* the regex */
+               /*
+                * push regex
+                * push replace
+                * push $0
+                */
+               regex = make_regnode(Node_regex, regex);
+               PUSH(regex);
+               PUSH(replace);
+               lhs = r_get_field(zero, (Func_ptr *) 0, true);
+               nargs++;
+               PUSH_ADDRESS(lhs);
+       } else {
+               /* gensub */
+               if (nargs == 4)
+                       rhs = POP();
+               else
+                       rhs = NULL;
+               glob_flag = POP_STRING();
+               replace = POP_STRING();
+               regex = POP();  /* the regex */
+               /*
+                * push regex
+                * push replace
+                * push glob_flag
+                * if (nargs = 3) {
+                *       push $0
+                *       nargs++
+                * }
+                */
+               regex = make_regnode(Node_regex, regex);
+               PUSH(regex);
+               PUSH(replace);
+               PUSH(glob_flag);
+               if (rhs == NULL) {
+                       lhs = r_get_field(zero, (Func_ptr *) 0, true);
+                       rhs = *lhs;
+                       UPREF(rhs);
+                       PUSH(rhs);
+                       nargs++;
+               }
+               PUSH(rhs);
+       }
+ 
+ 
+       unref(zero);
+       result = do_sub(nargs, flags);
+       if (flags != GENSUB)
+               reset_record();
+       return result;
+ }
+ 
+ /* call_match --- call do_match indirectly */
+ 
+ NODE *
+ call_match(int nargs)
+ {
+       NODE *regex, *text, *array;
+       NODE *result;
+ 
+       regex = text = array = NULL;
+       if (nargs == 3)
+               array = POP();
+       regex = POP();
+ 
+       /* Don't need to pop the string just to push it back ... */
+ 
+       regex = make_regnode(Node_regex, regex);
+       PUSH(regex);
+ 
+       if (array)
+               PUSH(array);
+ 
+       result = do_match(nargs);
+       return result;
+ }
+ 
+ /* call_split_func --- call do_split or do_pat_split indirectly */
+ 
+ NODE *
+ call_split_func(const char *name, int nargs)
+ {
+       NODE *regex, *seps;
+       NODE *result;
+ 
+       regex = seps = NULL;
+       if (nargs < 2)
+               fatal(_("indirect call to %s requires at least two arguments"),
+                               name);
+ 
+       if (nargs == 4)
+               seps = POP();
+ 
+       if (nargs >= 3) {
+               regex = POP_STRING();
+               regex = make_regnode(Node_regex, regex);
+       } else {
+               if (name[0] == 's') {
+                       regex = make_regnode(Node_regex, FS_node->var_value);
+                       regex->re_flags |= FS_DFLT;
+               } else
+                       regex = make_regnode(Node_regex, FPAT_node->var_value);
+               nargs++;
+       }
+ 
+       /* Don't need to pop the string or the data array */
+ 
+       PUSH(regex);
+ 
+       if (seps)
+               PUSH(seps);
+ 
+       result = (name[0] == 's') ? do_split(nargs) : do_patsplit(nargs);
+ 
+       return result;
+ }
  
 -/* make_integer - Convert an integer to a number node.  */
 -
 -static NODE *
 -make_integer(uintmax_t n)
 -{
 -      n = adjust_uint(n);
 -
 -      return make_number((AWKNUM) n);
 -}
 -
 -/* do_lshift --- perform a << operation */
 -
 -NODE *
 -do_lshift(int nargs)
 -{
 -      NODE *s1, *s2;
 -      uintmax_t uval, ushift, res;
 -      AWKNUM val, shift;
 -
 -      POP_TWO_SCALARS(s1, s2);
 -      if (do_lint) {
 -              if ((s1->flags & (NUMCUR|NUMBER)) == 0)
 -                      lintwarn(_("lshift: received non-numeric first 
argument"));
 -              if ((s2->flags & (NUMCUR|NUMBER)) == 0)
 -                      lintwarn(_("lshift: received non-numeric second 
argument"));
 -      }
 -      val = force_number(s1)->numbr;
 -      shift = force_number(s2)->numbr;
 -      if (do_lint) {
 -              if (val < 0 || shift < 0)
 -                      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(%f, %f): fractional values will be 
truncated"), val, shift);
 -              if (shift >= sizeof(uintmax_t) * CHAR_BIT)
 -                      lintwarn(_("lshift(%f, %f): too large shift value will 
give strange results"), val, shift);
 -      }
 -
 -      DEREF(s1);
 -      DEREF(s2);
 -
 -      uval = (uintmax_t) val;
 -      ushift = (uintmax_t) shift;
 -
 -      res = uval << ushift;
 -      return make_integer(res);
 -}
 -
 -/* do_rshift --- perform a >> operation */
 -
 -NODE *
 -do_rshift(int nargs)
 -{
 -      NODE *s1, *s2;
 -      uintmax_t uval, ushift, res;
 -      AWKNUM val, shift;
 -
 -      POP_TWO_SCALARS(s1, s2);
 -      if (do_lint) {
 -              if ((s1->flags & (NUMCUR|NUMBER)) == 0)
 -                      lintwarn(_("rshift: received non-numeric first 
argument"));
 -              if ((s2->flags & (NUMCUR|NUMBER)) == 0)
 -                      lintwarn(_("rshift: received non-numeric second 
argument"));
 -      }
 -      val = force_number(s1)->numbr;
 -      shift = force_number(s2)->numbr;
 -      if (do_lint) {
 -              if (val < 0 || shift < 0)
 -                      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(%f, %f): fractional values will be 
truncated"), val, shift);
 -              if (shift >= sizeof(uintmax_t) * CHAR_BIT)
 -                      lintwarn(_("rshift(%f, %f): too large shift value will 
give strange results"), val, shift);
 -      }
 -
 -      DEREF(s1);
 -      DEREF(s2);
 -
 -      uval = (uintmax_t) val;
 -      ushift = (uintmax_t) shift;
 -
 -      res = uval >> ushift;
 -      return make_integer(res);
 -}
 -
 -/* do_and --- perform an & operation */
 -
 -NODE *
 -do_and(int nargs)
 -{
 -      NODE *s1;
 -      uintmax_t res, uval;
 -      AWKNUM val;
 -      int i;
 -
 -      res = ~0;       /* start off with all ones */
 -      if (nargs < 2)
 -              fatal(_("and: called with less than two arguments"));
 -
 -      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;
 -
 -              DEREF(s1);
 -      }
 -
 -      return make_integer(res);
 -}
 -
 -/* do_or --- perform an | operation */
 -
 -NODE *
 -do_or(int nargs)
 -{
 -      NODE *s1;
 -      uintmax_t res, uval;
 -      AWKNUM val;
 -      int i;
 -
 -      res = 0;
 -      if (nargs < 2)
 -              fatal(_("or: called with less than two arguments"));
 -
 -      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);
 -
 -              uval = (uintmax_t) val;
 -              res |= uval;
 -
 -              DEREF(s1);
 -      }
 -
 -      return make_integer(res);
 -}
 -
 -/* do_xor --- perform an ^ operation */
 -
 -NODE *
 -do_xor(int nargs)
 -{
 -      NODE *s1;
 -      uintmax_t res, uval;
 -      AWKNUM val;
 -      int i;
 -
 -      if (nargs < 2)
 -              fatal(_("xor: called with less than two arguments"));
 -
 -      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);
 -
 -              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;
 -
 -              DEREF(s1);
 -      }
 -
 -      return make_integer(res);
 -}
 -
 -/* do_compl --- perform a ~ operation */
 -
 -NODE *
 -do_compl(int nargs)
 -{
 -      NODE *tmp;
 -      double d;
 -      uintmax_t uval;
 -
 -      tmp = POP_SCALAR();
 -      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 -              lintwarn(_("compl: received non-numeric argument"));
 -      d = force_number(tmp)->numbr;
 -      DEREF(tmp);
 -
 -      if (do_lint) {
 -              if (d < 0)
 -                      lintwarn(_("compl(%f): negative value will give strange 
results"), d);
 -              if (double_to_int(d) != d)
 -                      lintwarn(_("compl(%f): fractional value will be 
truncated"), d);
 -      }
 -
 -      uval = (uintmax_t) d;
 -      uval = ~ uval;
 -      return make_integer(uval);
 -}
 -
 -/* do_strtonum --- the strtonum function */
 -
 -NODE *
 -do_strtonum(int nargs)
 -{
 -      NODE *tmp;
 -      AWKNUM d;
 -
 -      tmp = POP_SCALAR();
 -      if ((tmp->flags & (NUMBER|NUMCUR)) != 0)
 -              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)->numbr;
 -
 -      DEREF(tmp);
 -      return make_number((AWKNUM) d);
 -}
 -
 -/* nondec2awknum --- convert octal or hex value to double */
 -
 -/*
 - * Because of awk's concatenation rules and the way awk.y:yylex()
 - * collects a number, this routine has to be willing to stop on the
 - * first invalid character.
 - */
 -
 -AWKNUM
 -nondec2awknum(char *str, size_t len)
 -{
 -      AWKNUM retval = 0.0;
 -      char save;
 -      short val;
 -      char *start = str;
 -
 -      if (*str == '0' && (str[1] == 'x' || str[1] == 'X')) {
 -              /*
 -               * User called strtonum("0x") or some such,
 -               * so just quit early.
 -               */
 -              if (len <= 2)
 -                      return (AWKNUM) 0.0;
 -
 -              for (str += 2, len -= 2; len > 0; len--, str++) {
 -                      switch (*str) {
 -                      case '0':
 -                      case '1':
 -                      case '2':
 -                      case '3':
 -                      case '4':
 -                      case '5':
 -                      case '6':
 -                      case '7':
 -                      case '8':
 -                      case '9':
 -                              val = *str - '0';
 -                              break;
 -                      case 'a':
 -                      case 'b':
 -                      case 'c':
 -                      case 'd':
 -                      case 'e':
 -                      case 'f':
 -                              val = *str - 'a' + 10;
 -                              break;
 -                      case 'A':
 -                      case 'B':
 -                      case 'C':
 -                      case 'D':
 -                      case 'E':
 -                      case 'F':
 -                              val = *str - 'A' + 10;
 -                              break;
 -                      default:
 -                              goto done;
 -                      }
 -                      retval = (retval * 16) + val;
 -              }
 -      } else if (*str == '0') {
 -              for (; len > 0; len--) {
 -                      if (! isdigit((unsigned char) *str))
 -                              goto done;
 -                      else if (*str == '8' || *str == '9') {
 -                              str = start;
 -                              goto decimal;
 -                      }
 -                      retval = (retval * 8) + (*str - '0');
 -                      str++;
 -              }
 -      } else {
 -decimal:
 -              save = str[len];
 -              retval = strtod(str, NULL);
 -              str[len] = save;
 -      }
 -done:
 -      return retval;
 -}
 -
  /* do_dcgettext, do_dcngettext --- handle i18n translations */
  
  #if ENABLE_NLS && defined(LC_MESSAGES) && HAVE_DCGETTEXT
diff --cc debug.c
index d129c4e,58012b7..40ac555
--- a/debug.c
+++ b/debug.c
@@@ -3975,7 -3988,14 +3975,8 @@@ print_instruction(INSTRUCTION *pc, Func
        case Op_match_rec:
        case Op_match:
        case Op_nomatch:
 -      case Op_plus_i:
 -      case Op_minus_i:
 -      case Op_times_i:
 -      case Op_exp_i:
 -      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:
diff --cc double.c
index cfb2fbf,0000000..114ab4f
mode 100644,000000..100644
--- a/double.c
+++ b/double.c
@@@ -1,1641 -1,0 +1,1639 @@@
 +/*
 + * double.c - routines for C double support in gawk.
 + */
 +
 +/* 
 + * 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 <math.h>
 +#include "random.h"
 +#include "floatmagic.h"       /* definition of isnan */
 +
 +#include "format.h"
 +
 +/* Can declare these, since we always use the random shipped with gawk */
 +extern char *initstate(unsigned long seed, char *state, long n);
 +extern char *setstate(char *state);
 +extern long random(void);
 +extern void srandom(unsigned long seed);
 +
 +/*
 + * Since we supply the version of random(), we know what
 + * value to use here.
 + */
 +#define GAWK_RANDOM_MAX 0x7fffffffL
 +
 +/* exported routines */
 +
 +static NODE *make_awknum(AWKNUM);
 +static int cmp_awknums(const NODE *, const NODE *);
 +static void negate_awknum(NODE *);
 +static NODE *str2awknum(char *, char **, int, bool);
 +static NODE *force_awknum(NODE *);
 +static NODE *format_awknum_val(const char *, int, NODE *);
 +static unsigned long awknum_toulong(const NODE *);
 +static long awknum_tolong(const NODE *);
 +static double awknum_todouble(const NODE *);
 +static uintmax_t awknum_touintmax_t(const NODE *);
 +static int awknum_sgn(const NODE *);
 +static bool awknum_isinteger(const NODE *);
 +static bool awknum_isnan(const NODE *);
 +static bool awknum_isinf(const NODE *);
 +static NODE *awknum_copy(const NODE *);
 +static int format_awknum_printf(NODE *, struct format_spec *, struct 
print_fmt_buf *);
 +static bool awknum_init(bltin_t **);
 +static NODE *awknum_add(const NODE *, const NODE *);
 +static NODE *awknum_sub(const NODE *, const NODE *);
 +static NODE *awknum_mul(const NODE *, const NODE *);
 +static NODE *awknum_div(const NODE *, const NODE *);
 +static NODE *awknum_mod(const NODE *, const NODE *);
 +static NODE *awknum_pow(const NODE *, const NODE *);
 +static NODE *awknum_add_long(const NODE *, long);
 +static NODE *awknum_update_var(NODE *);
 +static void awknum_set_var(const NODE *);
 +static long awknum_increment_var(const NODE *, long);
 +static void awknum_init_vars(void);
 +
 +static NODE *do_and(int);
 +static NODE *do_atan2(int);
 +static NODE *do_compl(int);
 +static NODE *do_cos(int);
 +static NODE *do_exp(int);
 +static NODE *do_int(int);
 +static NODE *do_log(int);
 +static NODE *do_lshift(int);
 +static NODE *do_or(int);
 +static NODE *do_rand(int);
 +static NODE *do_rshift(int);
 +static NODE *do_sin(int);
 +static NODE *do_sqrt(int);
 +static NODE *do_srand(int);
 +static NODE *do_strtonum(int);
 +static NODE *do_xor(int);
 +
 +/* internal routines */
 +static double double_to_int(double d);
 +static int is_ieee_magic_val(const char *val);
 +static AWKNUM get_ieee_magic_val(const char *val);
 +static AWKNUM calc_exp(AWKNUM x1, AWKNUM x2);
 +
 +
 +numbr_handler_t awknum_hndlr = {
 +      awknum_init,
 +      NULL,   /* version_str */
 +      NULL,   /* load_procinfo */
 +      make_awknum,
 +      str2awknum,
 +      awknum_copy,
 +      NULL,   /* free_awknum --- not needed for AWKNUM */
 +      force_awknum,
 +      negate_awknum,
 +      cmp_awknums,
 +      awknum_sgn,
 +      awknum_isinteger,
 +      awknum_isnan,
 +      awknum_isinf,
 +      format_awknum_val,
 +      format_awknum_printf,
 +      awknum_todouble,
 +      awknum_tolong,
 +      awknum_toulong,
 +      awknum_touintmax_t,
 +      awknum_add,
 +      awknum_sub,
 +      awknum_mul,
 +      awknum_div,
 +      awknum_mod,
 +      awknum_pow,
 +      awknum_add_long,
 +      awknum_update_var,
 +      awknum_set_var,
 +      awknum_increment_var,
 +      awknum_init_vars,
 +};
 +
 +/* awknum_init --- initialization routine */
 +
 +static bool
 +awknum_init(bltin_t **numbr_bltins)
 +{
 +      static bltin_t awknum_bltins[] = {
 +              { "and",        do_and },
 +              { "atan2",      do_atan2 },
 +              { "compl",      do_compl },
 +              { "cos",        do_cos },
-               { "div",        do_div },
++              { "div",        do_intdiv },
 +              { "exp",        do_exp },
 +              { "int",        do_int },
 +              { "log",        do_log },
 +              { "lshift",     do_lshift },
 +              { "or",         do_or },
 +              { "rand",       do_rand },
 +              { "rshift",     do_rshift },
 +              { "sin",        do_sin },
 +              { "sqrt",       do_sqrt },
 +              { "srand",      do_srand },
 +              { "strtonum",   do_strtonum },
 +              { "xor",        do_xor },
 +              { NULL, NULL },
 +      };
 +
 +      /* set the numeric value of null string */
 +      Nnull_string->numbr = 0.0;
 +      Nnull_string->flags |= (NUMCUR|NUMBER);
 +
 +      /* initialize TRUE and FALSE nodes */
 +      false_node = make_awknum(0.0);
 +      true_node = make_awknum(1.0);
 +      false_node->flags |= NUMINT;
 +      true_node->flags |= NUMINT;
 +
 +      *numbr_bltins = awknum_bltins;
 +      return true;
 +}
 +
 +/* awknum_toulong --- conversion to unsigned long */
 +
 +static unsigned long
 +awknum_toulong(const NODE *n)
 +{
 +      return n->numbr;
 +}
 +
 +/* awknum_tolong --- conversion to long */
 +
 +static long
 +awknum_tolong(const NODE *n)
 +{
 +      return n->numbr;
 +}
 +
 +/* awknum_todouble --- conversion to AWKNUM */
 +
 +static double
 +awknum_todouble(const NODE *n)
 +{
 +      return n->numbr;
 +}
 +
 +/* awknum_touintmax_t --- conversion to uintmax_t */
 +
 +static uintmax_t
 +awknum_touintmax_t(const NODE *n)
 +{
 +      return n->numbr;
 +}
 +
 +/* awknum_sgn --- return 1 if number > 0, zero if number == 0, and -1 if 
number < 0 */
 +
 +static int
 +awknum_sgn(const NODE *n)
 +{
 +      return (n->numbr < 0.0 ? -1 : n->numbr > 0.0);
 +}
 +
 +/* awknum_isinteger --- check if a number is an integer */
 +
 +static bool
 +awknum_isinteger(const NODE *n)
 +{
 +      if (isnan(n->numbr) || isinf(n->numbr))
 +              return false;
 +      return double_to_int(n->numbr) == n->numbr;
 +}
 +
 +/* awknum_isnan --- check if number is NaN */
 +
 +static bool
 +awknum_isnan(const NODE *n)
 +{
 +      return isnan(n->numbr);
 +}
 +
 +/* awknum_isinf --- check if number is infinity */
 +
 +static bool
 +awknum_isinf(const NODE *n)
 +{
 +      return isinf(n->numbr);
 +}
 +
 +
 +/* negate_awknum --- negate AWKNUM in NODE */
 +
 +static void
 +negate_awknum(NODE *n)
 +{
 +      n->numbr = - n->numbr;
 +}
 +
 +/* awknum_add --- add two numbers */
 +
 +static NODE *
 +awknum_add(const NODE *t1, const NODE *t2)
 +{
 +      return make_awknum(t1->numbr + t2->numbr);
 +}
 +
 +/* awknum_sub --- subtract two numbers */
 +
 +static NODE *
 +awknum_sub(const NODE *t1, const NODE *t2)
 +{
 +      return make_awknum(t1->numbr - t2->numbr);
 +}
 +
 +/* awknum_mul --- multiply two numbers */
 +
 +static NODE *
 +awknum_mul(const NODE *t1, const NODE *t2)
 +{
 +      return make_awknum(t1->numbr * t2->numbr);
 +}
 +
 +/* awknum_add --- quotient of two numbers */
 +
 +static NODE *
 +awknum_div(const NODE *t1, const NODE *t2)
 +{
 +      if (t2->numbr == 0)
 +              fatal(_("division by zero attempted"));
 +      return make_awknum(t1->numbr / t2->numbr);
 +}
 +
 +/* awknum_add_long --- add long value to a number */
 +
 +static NODE *
 +awknum_add_long(const NODE *t1, long n)
 +{
 +      return make_awknum(t1->numbr + n);
 +}
 +
 +/* awknum_copy --- copy a number */
 +
 +static NODE *
 +awknum_copy(const NODE *t1)
 +{
 +      return make_awknum(t1->numbr);
 +}
 +
 +/* awknum_update_var --- update a special variable from internal variables */
 +
 +static NODE *
 +awknum_update_var(NODE *var)
 +{
 +      NODE *val = var->var_value;
 +
 +      if (var == NR_node) {
 +              if (val->numbr != NR) {
 +                      unref(val);
 +                      val = NR_node->var_value = make_awknum(NR);
 +              }
 +              return val;
 +      }
 +
 +      assert(var == FNR_node);
 +      if (val->numbr != FNR) {
 +              unref(val);
 +              val = FNR_node->var_value = make_awknum(FNR);
 +      }
 +      return val;
 +}
 +
 +/*
 + * awknum_set_vars --- update internal variables for assignment
 + *    to a special variable.
 + */
 +
 +static void
 +awknum_set_var(const NODE *var)
 +{
 +      NODE *val = var->var_value;
 +      if (var == NR_node)
 +              NR = val->numbr;
 +      else if (var == FNR_node)
 +              FNR = val->numbr;
 +      else {
 +              /* PREC and ROUNMODE */
 +              if (do_lint)
 +                      lintwarn(_("setting `%s' has no effect"),
 +                              var == PREC_node ? "PREC" : "ROUNDMODE");
 +      }
 +}
 +
 +/* awknum_increment_var --- increment NR or FNR */
 +
 +static long
 +awknum_increment_var(const NODE *var ATTRIBUTE_UNUSED, long nr)
 +{
 +      /* var == (F)NR_node */
 +      return ++nr;
 +}
 +
 +/* awknum_init_vars --- initialize special variables */
 +
 +static void
 +awknum_init_vars()
 +{
 +      unref(PREC_node->var_value);
 +        PREC_node->var_value = make_awknum(DBL_MANT_DIG);
 +      PREC_node->var_value->flags |= NUMINT;
 +        unref(ROUNDMODE_node->var_value);
 +        ROUNDMODE_node->var_value = make_string("N", 1);
 +}
 +
 +/* make_awknum --- allocate a node with defined number */
 +
 +static NODE *
 +make_awknum(AWKNUM x)
 +{
 +      NODE *r;
 +      getnode(r);
 +      r->type = Node_val;
 +      r->numbr = x;
 +      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;
 +}
 +
 +/* make_integer - Convert an integer to a number node.  */
 +
 +static inline NODE *
 +make_integer(uintmax_t n)
 +{
 +      n = adjust_uint(n);
 +      return make_awknum(n);
 +}
 +
 +/* do_lshift --- perform a << operation */
 +
 +static NODE *
 +do_lshift(int nargs)
 +{
 +      NODE *s1, *s2;
 +      uintmax_t uval, ushift, res;
 +      AWKNUM val, shift;
 +
 +      s2 = POP_SCALAR();
 +      s1 = POP_SCALAR();
 +      if (do_lint) {
 +              if ((s1->flags & (NUMCUR|NUMBER)) == 0)
 +                      lintwarn(_("lshift: received non-numeric first 
argument"));
 +              if ((s2->flags & (NUMCUR|NUMBER)) == 0)
 +                      lintwarn(_("lshift: received non-numeric second 
argument"));
 +      }
 +      val = force_number(s1)->numbr;
 +      shift = force_number(s2)->numbr;
 +      if (do_lint) {
 +              if (val < 0 || shift < 0)
 +                      lintwarn(_("lshift(%f, %f): negative values will give 
strange results"),
 +                                      (double) val, (double) shift);
 +              if (double_to_int(val) != val || double_to_int(shift) != shift)
 +                      lintwarn(_("lshift(%f, %f): fractional values will be 
truncated"),
 +                                      (double) val, (double) shift);
 +              if (shift >= sizeof(uintmax_t) * CHAR_BIT)
 +                      lintwarn(_("lshift(%f, %f): too large shift value will 
give strange results"),
 +                                      (double) val, (double) shift);
 +      }
 +
 +      DEREF(s1);
 +      DEREF(s2);
 +
 +      uval = (uintmax_t) val;
 +      ushift = (uintmax_t) shift;
 +
 +      res = uval << ushift;
 +      return make_integer(res);
 +}
 +
 +/* do_rshift --- perform a >> operation */
 +
 +static NODE *
 +do_rshift(int nargs)
 +{
 +      NODE *s1, *s2;
 +      uintmax_t uval, ushift, res;
 +      AWKNUM val, shift;
 +
 +      s2 = POP_SCALAR();
 +      s1 = POP_SCALAR();
 +      if (do_lint) {
 +              if ((s1->flags & (NUMCUR|NUMBER)) == 0)
 +                      lintwarn(_("rshift: received non-numeric first 
argument"));
 +              if ((s2->flags & (NUMCUR|NUMBER)) == 0)
 +                      lintwarn(_("rshift: received non-numeric second 
argument"));
 +      }
 +      val = force_number(s1)->numbr;
 +      shift = force_number(s2)->numbr;
 +      if (do_lint) {
 +              if (val < 0 || shift < 0)
 +                      lintwarn(_("rshift(%f, %f): negative values will give 
strange results"),
 +                                      (double) val, (double) shift);
 +              if (double_to_int(val) != val || double_to_int(shift) != shift)
 +                      lintwarn(_("rshift(%f, %f): fractional values will be 
truncated"),
 +                                      (double) val, (double) shift);
 +              if (shift >= sizeof(uintmax_t) * CHAR_BIT)
 +                      lintwarn(_("rshift(%f, %f): too large shift value will 
give strange results"),
 +                                      (double) val, (double) shift);
 +      }
 +
 +      DEREF(s1);
 +      DEREF(s2);
 +
 +      uval = (uintmax_t) val;
 +      ushift = (uintmax_t) shift;
 +
 +      res = uval >> ushift;
 +      return make_integer(res);
 +}
 +
 +/* do_and --- perform an & operation */
 +
 +static NODE *
 +do_and(int nargs)
 +{
 +      NODE *s1;
 +      uintmax_t res, uval;
 +      AWKNUM val;
 +      int i;
 +
 +      res = ~0;       /* start off with all ones */
 +      if (nargs < 2)
 +              fatal(_("and: called with less than two arguments"));
 +
 +      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, (double) val);
 +
 +              uval = (uintmax_t) val;
 +              res &= uval;
 +
 +              DEREF(s1);
 +      }
 +
 +      return make_integer(res);
 +}
 +
 +/* do_or --- perform an | operation */
 +
 +static NODE *
 +do_or(int nargs)
 +{
 +      NODE *s1;
 +      uintmax_t res, uval;
 +      AWKNUM val;
 +      int i;
 +
 +      res = 0;
 +      if (nargs < 2)
 +              fatal(_("or: called with less than two arguments"));
 +
 +      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, (double) val);
 +
 +              uval = (uintmax_t) val;
 +              res |= uval;
 +
 +              DEREF(s1);
 +      }
 +
 +      return make_integer(res);
 +}
 +
 +/* do_xor --- perform an ^ operation */
 +
 +static NODE *
 +do_xor(int nargs)
 +{
 +      NODE *s1;
 +      uintmax_t res, uval;
 +      AWKNUM val;
 +      int i;
 +
 +      if (nargs < 2)
 +              fatal(_("xor: called with less than two arguments"));
 +
 +      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);
 +
 +              val = force_number(s1)->numbr;
 +              if (do_lint && val < 0)
 +                      lintwarn(_("xor: argument %d negative value %g will 
give strange results"),
 +                                      i, (double) val);
 +
 +              uval = (uintmax_t) val;
 +              if (i == 1)
 +                      res = uval;
 +              else
 +                      res ^= uval;
 +
 +              DEREF(s1);
 +      }
 +
 +      return make_integer(res);
 +}
 +
 +/* do_compl --- perform a ~ operation */
 +
 +static NODE *
 +do_compl(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM d;
 +      uintmax_t uval;
 +
 +      tmp = POP_SCALAR();
 +      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 +              lintwarn(_("compl: received non-numeric argument"));
 +      d = force_number(tmp)->numbr;
 +      DEREF(tmp);
 +
 +      if (do_lint) {
 +              if (d < 0)
 +                      lintwarn(_("compl(%f): negative value will give strange 
results"),
 +                                      (double) d);
 +              if (double_to_int(d) != d)
 +                      lintwarn(_("compl(%f): fractional value will be 
truncated"),
 +                                      (double) d);
 +      }
 +
 +      uval = (uintmax_t) d;
 +      uval = ~ uval;
 +      return make_integer(uval);
 +}
 +
 +/* nondec2awknum --- convert octal or hex value to double */
 +
 +/*
 + * Because of awk's concatenation rules and the way awk.y:yylex()
 + * collects a number, this routine has to be willing to stop on the
 + * first invalid character.
 + */
 +
 +static AWKNUM
 +nondec2awknum(char *str, size_t len)
 +{
 +      AWKNUM retval = 0.0;
 +      char save;
 +      short val;
 +      char *start = str;
 +
 +      if (*str == '0' && (str[1] == 'x' || str[1] == 'X')) {
 +              /*
 +               * User called strtonum("0x") or some such,
 +               * so just quit early.
 +               */
 +              if (len <= 2)
 +                      return (AWKNUM) 0.0;
 +
 +              for (str += 2, len -= 2; len > 0; len--, str++) {
 +                      switch (*str) {
 +                      case '0':
 +                      case '1':
 +                      case '2':
 +                      case '3':
 +                      case '4':
 +                      case '5':
 +                      case '6':
 +                      case '7':
 +                      case '8':
 +                      case '9':
 +                              val = *str - '0';
 +                              break;
 +                      case 'a':
 +                      case 'b':
 +                      case 'c':
 +                      case 'd':
 +                      case 'e':
 +                      case 'f':
 +                              val = *str - 'a' + 10;
 +                              break;
 +                      case 'A':
 +                      case 'B':
 +                      case 'C':
 +                      case 'D':
 +                      case 'E':
 +                      case 'F':
 +                              val = *str - 'A' + 10;
 +                              break;
 +                      default:
 +                              goto done;
 +                      }
 +                      retval = (retval * 16) + val;
 +              }
 +      } else if (*str == '0') {
 +              for (; len > 0; len--) {
 +                      if (! isdigit((unsigned char) *str))
 +                              goto done;
 +                      else if (*str == '8' || *str == '9') {
 +                              str = start;
 +                              goto decimal;
 +                      }
 +                      retval = (retval * 8) + (*str - '0');
 +                      str++;
 +              }
 +      } else {
 +decimal:
 +              save = str[len];
 +              retval = strtod(str, NULL);
 +              str[len] = save;
 +      }
 +done:
 +      return retval;
 +}
 +
 +
 +/* do_rand --- do the rand function */
 +
 +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)];
 +static char *const state = (char *const) istate;
 +
 +/* ARGSUSED */
 +static 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;
 +              setstate(state);
 +      }
 +      /*
 +       * Per historical practice and POSIX, return value N is
 +       *
 +       *      0 <= n < 1
 +       */
 +      /*
 +       * Date: Wed, 28 Aug 2013 17:52:46 -0700
 +       * From: Bob Jewett <address@hidden>
 +       *
 +       * 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" <address@hidden>
 +       * (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 {
 +              tmprand = 0.5 + ( (random()/RAND_DIVISOR + random())
 +                                      / RAND_DIVISOR);
 +              tmprand -= 0.5;
 +      } while (tmprand == 1.0);
 +
 +      return make_number((AWKNUM) tmprand);
 +}
 +
 +/* do_srand --- seed the random number generator */
 +
 +static NODE *
 +do_srand(int nargs)
 +{
 +      NODE *tmp;
 +      static long save_seed = 1;
 +      long ret = save_seed;   /* SVR4 awk srand returns previous seed */
 +
 +      if (firstrand) {
 +              (void) initstate((unsigned) 1, state, SIZEOF_STATE);
 +              /* don't need to srandom(1), we're changing the seed below */
 +              firstrand = false;
 +              (void) setstate(state);
 +      }
 +
 +      if (nargs == 0)
 +              srandom((unsigned int) (save_seed = (long) time((time_t *) 0)));
 +      else {
 +              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)->numbr));
 +              DEREF(tmp);
 +      }
 +      return make_awknum((AWKNUM) ret);
 +}
 +
 +
 +/* str2awknum --- create a number node from string */
 +
 +static NODE *
 +str2awknum(char *str, char **endptr, int base, bool is_integer 
ATTRIBUTE_UNUSED)
 +{
 +      NODE *r;
 +      AWKNUM d;
 +
 +      if (base == 0) {
 +              /*
 +               * special case -- only used to parse input in the debugger?
 +               * FIXME: reject ieee specials we don't want and/or use the same
 +               * rules when reading numbers from a source file and nuke this 
case.
 +               */
 +
 +              errno = 0;
 +              d = strtod(str, endptr);
 +              if (errno != 0)
 +                      d = 0;
 +      } else {
 +              if (base == 8 || base == 16)
 +                      d = nondec2awknum(str, strlen(str));
 +              else
 +                      d = atof(str);
 +      }
 +      r = make_awknum(d);
 +      if (d <= INT32_MAX && d >= INT32_MIN && d == (int32_t) d)
 +              r->flags |= NUMINT;
 +      return r;
 +}
 +
 +/* awknum_mod --- remainder from division of two numbers */
 +
 +static NODE *
 +awknum_mod(const NODE *t1, const NODE *t2)
 +{
 +      AWKNUM x;
 +
 +      if (t2->numbr == 0)
 +              fatal(_("division by zero attempted in `%%'"));
 +#ifdef HAVE_FMOD
 +      x = fmod(t1->numbr, t2->numbr);
 +#else /* ! HAVE_FMOD */
 +      (void) modf(t1->numbr / t2->numbr, & x);
 +      x = t1->numbr - x * t2->numbr;
 +#endif        /* ! HAVE_FMOD */
 +      return make_awknum(x);
 +}
 +
 +/* awknum_pow --- power function */
 +
 +static NODE *
 +awknum_pow(const NODE *t1, const NODE *t2)
 +{
 +      return make_awknum(calc_exp(t1->numbr, t2->numbr));
 +}
 +
 +
 +/*
 + * calc_exp_posint --- calculate x^n for positive integral n,
 + *    using exponentiation by squaring without recursion.
 + */
 +
 +static AWKNUM
 +calc_exp_posint(AWKNUM x, long n)
 +{
 +      AWKNUM mult = 1;
 +
 +      while (n > 1) {
 +              if ((n % 2) == 1)
 +                      mult *= x;
 +              x *= x;
 +              n /= 2;
 +      }
 +      return mult * x;
 +}
 +
 +/* calc_exp --- calculate x1^x2 */
 +
 +static AWKNUM
 +calc_exp(AWKNUM x1, AWKNUM x2)
 +{
 +      long lx;
 +
 +      if ((lx = x2) == x2) {          /* integer exponent */
 +              if (lx == 0)
 +                      return 1;
 +              return (lx > 0) ? calc_exp_posint(x1, lx)
 +                              : 1.0 / calc_exp_posint(x1, -lx);
 +      }
 +      return (AWKNUM) pow((double) x1, (double) x2);
 +}
 +
 +/* cmp_awknums --- compare two AWKNUMs */
 +
 +static 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;
 +}
 +
 +/* force_awknum --- force a value to be numeric */
 +
 +static NODE *
 +force_awknum(NODE *n)
 +{
 +      char *cp;
 +      char *cpend;
 +      char save;
 +      char *ptr;
 +      unsigned int newflags;
 +
 +      if ((n->flags & NUMCUR) != 0)
 +              return n;
 +
 +      /* all the conditionals are an attempt to avoid the expensive strtod */
 +
 +      /* Note: only set NUMCUR if we actually convert some digits */
 +
 +      n->numbr = 0.0;
 +
 +      if (n->stlen == 0) {
 +              return n;
 +      }
 +
 +      cp = n->stptr;
 +      /*
 +       * 2/2007:
 +       * POSIX, by way of severe language lawyering, seems to
 +       * allow things like "inf" and "nan" to mean something.
 +       * So if do_posix, the user gets what he deserves.
 +       * This also allows hexadecimal floating point. Ugh.
 +       */
 +      if (! do_posix) {
 +              if (isalpha((unsigned char) *cp)) {
 +                      return n;
 +              } else if (n->stlen == 4 && is_ieee_magic_val(n->stptr)) {
 +                      if ((n->flags & MAYBE_NUM) != 0)
 +                              n->flags &= ~MAYBE_NUM;
 +                      n->flags |= NUMBER|NUMCUR;
 +                      n->numbr = get_ieee_magic_val(n->stptr);
 +                      return n;
 +              }
 +              /* else
 +                      fall through */
 +      }
 +      /* else not POSIX, so
 +              fall through */
 +
 +      cpend = cp + n->stlen;
 +      while (cp < cpend && isspace((unsigned char) *cp))
 +              cp++;
 +
 +      if (   cp == cpend              /* only spaces, or */
 +          || (! do_posix              /* not POSIXLY paranoid and */
 +              && (isalpha((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 n;
 +      }
 +
 +      if ((n->flags & MAYBE_NUM) != 0) {
 +              newflags = NUMBER;
 +              n->flags &= ~MAYBE_NUM;
 +      } else
 +              newflags = 0;
 +
 +      if (cpend - cp == 1) {          /* only one character */
 +              if (isdigit((unsigned char) *cp)) {     /* it's a digit! */
 +                      n->numbr = (AWKNUM)(*cp - '0');
 +                      n->flags |= newflags;
 +                      n->flags |= NUMCUR;
 +                      if (cp == n->stptr)             /* no leading spaces */
 +                              n->flags |= NUMINT;
 +              }
 +              return n;
 +      }
 +
 +      if (do_non_decimal_data) {      /* main.c assures false if do_posix */
 +              errno = 0;
 +              if (! do_traditional && get_numbase(cp, true) != 10) {
 +                      n->numbr = nondec2awknum(cp, cpend - cp);
 +                      n->flags |= NUMCUR;
 +                      ptr = cpend;
 +                      goto finish;
 +              }
 +      }
 +
 +      errno = 0;
 +      save = *cpend;
 +      *cpend = '\0';
 +      n->numbr = (AWKNUM) strtod((const char *) cp, &ptr);
 +
 +      /* POSIX says trailing space is OK for NUMBER */
 +      while (isspace((unsigned char) *ptr))
 +              ptr++;
 +      *cpend = save;
 +finish:
 +      if (errno == 0 && ptr == cpend) {
 +              n->flags |= newflags;
 +              n->flags |= NUMCUR;
 +      } else {
 +              errno = 0;
 +      }
 +
 +      return n;
 +}
 +
 +
 +/*
 + * The following lookup table is used as an optimization in force_string;
 + * (more complicated) variations on this theme didn't seem to pay off, but 
 + * systematic testing might be in order at some point.
 + */
 +static const char *values[] = {
 +      "0",
 +      "1",
 +      "2",
 +      "3",
 +      "4",
 +      "5",
 +      "6",
 +      "7",
 +      "8",
 +      "9",
 +};
 +#define       NVAL    (sizeof(values)/sizeof(values[0]))
 +
 +/* format_awknum_val --- format a numeric value based on format */
 +
 +static NODE *
 +format_awknum_val(const char *format, int index, NODE *s)
 +{
 +      char buf[BUFSIZ];
 +      char *sp = buf;
 +      double val;
 +
 +      /*
 +       * 2/2007: Simplify our lives here. Instead of worrying about
 +       * whether or not the value will fit into a long just so we
 +       * can use sprintf("%ld", val) on it, always format it ourselves.
 +       * The only thing to worry about is that integral values always
 +       * format as integers. %.0f does that very well.
 +       *
 +       * 6/2008: Would that things were so simple. Always using %.0f
 +       * imposes a notable performance penalty for applications that
 +       * do a lot of conversion of integers to strings. So, we reinstate
 +       * the old code, but use %.0f for integral values that are outside
 +       * the range of a long.  This seems a reasonable compromise.
 +       *
 +       * 12/2009: Use <= and >= in the comparisons with LONG_xxx instead of
 +       * < and > so that things work correctly on systems with 64 bit 
integers.
 +       */
 +
 +      if ((s->flags & STRCUR) != 0)
 +              efree(s->stptr);
 +      free_wstr(s);
 +
 +
 +      /* not an integral value, or out of range */
 +      if ((val = double_to_int(s->numbr)) != s->numbr
 +                      || val <= LONG_MIN || val >= LONG_MAX
 +      ) {
 +              struct format_spec spec;
 +              struct print_fmt_buf *outb;
 +
 +              /*
 +               * Once upon a time, we just blindly did this:
 +               *      sprintf(sp, format, s->numbr);
 +               *      s->stlen = strlen(sp);
 +               *      s->stfmt = (char) index;
 +               * but that's no good if, e.g., OFMT is %s. So we punt,
 +               * and just always format the value ourselves.
 +               */
 +
 +              /* XXX: format_spec copied since can be altered in the 
formatting routine */
 +
 +              if (val == s->numbr) {
 +                      /* integral value, but outside range of %ld, use %.0f */
 +                      spec = *fmt_list[INT_0f_FMT_INDEX].spec;
 +                      s->stfmt = -1;
 +              } else {
 +                      assert(fmt_list[index].spec != NULL);   /* or can use 
fmt_parse() --- XXX */
 +                      spec = *fmt_list[index].spec;
 +                      s->stfmt = (char) index;        
 +              }
 +
 +              outb = get_fmt_buf();
 +              (void) format_awknum_printf(s, & spec, outb);
 +              (void) bytes2node(outb, s);
 +              free_fmt_buf(outb);
 +
 +              s->stptr[s->stlen] = '\0';
 +      } else {
 +              /*
 +               * integral value; force conversion to long only once.
 +               */
 +              long num = (long) val;
 +
 +              if (num < NVAL && num >= 0) {
 +                      sp = (char *) values[num];
 +                      s->stlen = 1;
 +              } else {
 +                      (void) sprintf(sp, "%ld", num);
 +                      s->stlen = strlen(sp);
 +              }
 +              s->stfmt = -1;
 +              if ((s->flags & INTIND) != 0) {
 +                      s->flags &= ~(INTIND|NUMBER);
 +                      s->flags |= STRING;
 +              }
 +
 +              emalloc(s->stptr, char *, s->stlen + 2, "format_awknum_val");
 +              memcpy(s->stptr, sp, s->stlen + 1);
 +      }
 +      
 +      s->flags |= STRCUR;
 +      return s;
 +}
 +
 +/* is_ieee_magic_val --- return true for +inf, -inf, +nan, -nan */
 +
 +static int
 +is_ieee_magic_val(const char *val)
 +{
 +      /*
 +       * Avoid strncasecmp: it mishandles ASCII bytes in some locales.
 +       * Assume the length is 4, as the caller checks this.
 +       */
 +      return (   (val[0] == '+' || val[0] == '-')
 +              && (   (   (val[1] == 'i' || val[1] == 'I')
 +                      && (val[2] == 'n' || val[2] == 'N')
 +                      && (val[3] == 'f' || val[3] == 'F'))
 +                  || (   (val[1] == 'n' || val[1] == 'N')
 +                      && (val[2] == 'a' || val[2] == 'A')
 +                      && (val[3] == 'n' || val[3] == 'N'))));
 +}
 +
 +/* get_ieee_magic_val --- return magic value for string */
 +
 +static AWKNUM
 +get_ieee_magic_val(const char *val)
 +{
 +      static bool first = true;
 +      static AWKNUM inf;
 +      static AWKNUM nan;
 +      char *ptr;
 +      AWKNUM v;
 +
 +      v = strtod(val, & ptr);
 +
 +      if (val == ptr) { /* Older strtod implementations don't support inf or 
nan. */
 +              if (first) {
 +                      first = false;
 +                      nan = sqrt(-1.0);
 +                      inf = -log(0.0);
 +              }
 +
 +              v = ((val[1] == 'i' || val[1] == 'I') ? inf : nan);
 +              if (val[0] == '-')
 +                      v = -v;
 +      }
 +
 +      return v;
 +}
 +
 +/* double_to_int --- convert double to int, used in several places */
 +
 +static double
 +double_to_int(double d)
 +{
 +      if (d >= 0)
 +              d = floor(d);
 +      else
 +              d = ceil(d);
 +      return d;
 +}
 +
 +/* do_int --- convert double to int for awk */
 +
 +static NODE *
 +do_int(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM d;
 +
 +      tmp = POP_SCALAR();
 +      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 +              lintwarn(_("int: received non-numeric argument"));
 +      (void) force_number(tmp);
 +      d = tmp->numbr;
 +      DEREF(tmp);
 +      return make_awknum(double_to_int(d));
 +}
 +
 +/* do_log --- the log function */
 +
 +static NODE *
 +do_log(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM d, arg;
 +
 +      tmp = POP_SCALAR();
 +      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 +              lintwarn(_("log: received non-numeric argument"));
 +      arg = force_number(tmp)->numbr;
 +      if (arg < 0.0)
 +              warning(_("log: received negative argument %g"), (double) arg);
 +      d = log(arg);
 +      DEREF(tmp);
 +      return make_awknum(d);
 +}
 +
 +/* do_sqrt --- do the sqrt function */
 +
 +static NODE *
 +do_sqrt(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM arg;
 +
 +      tmp = POP_SCALAR();
 +      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 +              lintwarn(_("sqrt: received non-numeric argument"));
 +      arg = force_number(tmp)->numbr;
 +      DEREF(tmp);
 +      if (arg < 0.0)
 +              warning(_("sqrt: called with negative argument %g"), (double) 
arg);
 +      return make_awknum(sqrt(arg));
 +}
 +
 +/* do_exp --- exponential function */
 +
 +static NODE *
 +do_exp(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM d, res;
 +
 +      tmp = POP_SCALAR();
 +      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 +              lintwarn(_("exp: received non-numeric argument"));
 +      d = force_number(tmp)->numbr;
 +      DEREF(tmp);
 +      errno = 0;
 +      res = exp(d);
 +      if (errno == ERANGE)
 +              warning(_("exp: argument %g is out of range"), (double) d);
 +      return make_awknum(res);
 +}
 +
 +
 +/* do_atan2 --- do the atan2 function */
 +
 +static NODE *
 +do_atan2(int nargs)
 +{
 +      NODE *t1, *t2;
 +      AWKNUM d1, d2;
 +
 +      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"));
 +      }
 +      d1 = force_number(t1)->numbr;
 +      d2 = force_number(t2)->numbr;
 +      DEREF(t1);
 +      DEREF(t2);
 +      return make_awknum(atan2(d1, d2));
 +}
 +
 +/* do_sin --- do the sin function */
 +
 +static NODE *
 +do_sin(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM d;
 +
 +      tmp = POP_SCALAR();
 +      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 +              lintwarn(_("sin: received non-numeric argument"));
 +      d = sin(force_number(tmp)->numbr);
 +      DEREF(tmp);
 +      return make_awknum(d);
 +}
 +
 +/* do_cos --- do the cos function */
 +
 +static NODE *
 +do_cos(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM d;
 +
 +      tmp = POP_SCALAR();
 +      if (do_lint && (tmp->flags & (NUMCUR|NUMBER)) == 0)
 +              lintwarn(_("cos: received non-numeric argument"));
 +      d = cos(force_number(tmp)->numbr);
 +      DEREF(tmp);
 +      return make_awknum(d);
 +}
 +
 +/* do_strtonum --- the strtonum function */
 +
 +static NODE *
 +do_strtonum(int nargs)
 +{
 +      NODE *tmp;
 +      AWKNUM d;
 +
 +      tmp = POP_SCALAR();
 +      if ((tmp->flags & (NUMBER|NUMCUR)) != 0)
 +              d = force_number(tmp)->numbr;
 +      else if (get_numbase(tmp->stptr, use_lc_numeric) != 10)
 +              d = nondec2awknum(tmp->stptr, tmp->stlen);
 +      else
 +              d = force_number(tmp)->numbr;
 +
 +      DEREF(tmp);
 +      return make_awknum(d);
 +}
 +
- /* do_div --- do integer division, return quotient and remainder in dest 
array */
++/* do_intdiv --- 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)
++do_intdiv(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"));
++              fatal(_("intdiv: 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"));
++                      lintwarn(_("intdiv: received non-numeric first 
argument"));
 +              if ((denominator->flags & (NUMCUR|NUMBER)) == 0)
-                       lintwarn(_("div: received non-numeric second 
argument"));
++                      lintwarn(_("intdiv: 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);
 +}
 +
 +/* format_awknum_printf --- format a number for (s)printf */
 +
 +static int
 +format_awknum_printf(NODE *arg, struct format_spec *spec, struct 
print_fmt_buf *outb)
 +{
 +      AWKNUM tmpval;
 +      uintmax_t uval;
 +      bool sgn;
 +      int i, ii, jj;
 +      char *chp, *cp;
 +      char cs1;
 +      int nc;
 +
 +      static char stackbuf[64];       /* temporary buffer for integer 
formatting */ 
 +      static char *intbuf = stackbuf;
 +      size_t intbuf_size = 64;
 +
 +#     define CP               cpbuf_start(outb)
 +#     define CEND             cpbuf_end(outb)
 +#     define CPBUF            cpbuf(outb)
 +
 +
 +      tmpval = arg->numbr;
 +      spec->fill = space_string;
 +      spec->chbuf = lchbuf;
 +
 +      cp = CP;
 +      cs1 = spec->fmtchar;
 +      switch (cs1) {
 +      case 'd':
 +      case 'i':
 +              if (isnan(tmpval) || isinf(tmpval))
 +                      goto out_of_range;
 +              else
 +                      tmpval = double_to_int(tmpval);
 +
 +              /*
 +               * ``The result of converting a zero value with a
 +               * precision of zero is no characters.''
 +               */
 +              if (spec->have_prec && spec->prec == 0 && tmpval == 0) {
 +                      pr_num_tail(cp, spec->prec, spec, outb);
 +                      return 0;
 +              }
 +
 +              if (tmpval < 0) {
 +                      tmpval = -tmpval;
 +                      sgn = true;
 +              } else {
 +                      if (tmpval == -0.0)     /* avoid printing -0 */
 +                              tmpval = 0.0;
 +                      sgn = false;
 +              }
 +
 +              /*
 +               * Use snprintf return value to tell if there
 +               * is enough room in the buffer or not.
 +               */
 +              while ((i = snprintf(intbuf, intbuf_size, "%.0f", tmpval)) >= 
intbuf_size) {
 +                      if (intbuf == stackbuf)
 +                              intbuf = NULL;
 +                      intbuf_size = i + 1;
 +                      erealloc(intbuf, char *, intbuf_size, "format_tree");
 +              }
 +
 +              if (i < 1)
 +                      goto out_of_range;
 +
 +              chp = & intbuf[i-1];
 +              ii = jj = 0;
 +              do {
 +                      tmpbuf_prepend(outb, *chp);
 +                      chp--; i--;
 +#if defined(HAVE_LOCALE_H)
 +                      if (spec->quote_flag && loc.grouping[ii] && ++jj == 
loc.grouping[ii]) {
 +                              if (i)  /* only add if more digits coming */
 +                                      tmpbuf_prepend(outb, 
loc.thousands_sep[0]);     /* XXX - assumption it's one char */
 +                              if (loc.grouping[ii+1] == 0)
 +                                      jj = 0;         /* keep using current 
val in loc.grouping[ii] */
 +                              else if (loc.grouping[ii+1] == CHAR_MAX)
 +                                      spec->quote_flag= false;
 +                              else {                 
 +                                      ii++;
 +                                      jj = 0;
 +                              }
 +                      }
 +#endif
 +              } while (i > 0);
 +
 +
 +              /* add more output digits to match the precision */
 +              if (spec->have_prec) {
 +                      while (CEND - CP < spec->prec)
 +                              tmpbuf_prepend(outb, '0');
 +              }
 +
 +              if (sgn)
 +                      tmpbuf_prepend(outb, '-');
 +              else if (spec->signchar)
 +                      tmpbuf_prepend(outb, spec->signchar);
 +              /*
 +               * When to fill with zeroes is of course not simple.
 +               * First: No zero fill if left-justifying.
 +               * Next: There seem to be two cases:
 +               *      A '0' without a precision, e.g. %06d
 +               *      A precision with no field width, e.g. %.10d
 +               * Any other case, we don't want to fill with zeroes.
 +               */
 +              if (! spec->lj
 +                  && ((spec->zero_flag && ! spec->have_prec)
 +                       || (spec->fw == 0 && spec->have_prec)))
 +                      spec->fill = zero_string;
 +              if (spec->prec > spec->fw)
 +                      spec->fw = spec->prec;
 +              spec->prec = CEND - CP;
 +              if (spec->fw > spec->prec && ! spec->lj && spec->fill != 
space_string
 +                  && (*CP == '-' || spec->signchar)) {
 +                      bchunk_one(outb, CP);
 +                      CP++;
 +                      spec->prec--;
 +                      spec->fw--;
 +              }
 +              cp = CP;
 +
 +              pr_num_tail(CP, spec->prec, spec, outb);
 +              return 0;
 +
 +      case 'X':
 +              spec->chbuf = Uchbuf;
 +              /* FALL THROUGH */
 +      case 'x':
 +              /* FALL THROUGH */
 +      case 'u':
 +              /* FALL THROUGH */
 +      case 'o':
 +              /*
 +               * ``The result of converting a zero value with a
 +               * precision of zero is no characters.''
 +               *
 +               * If I remember the ANSI C standard, though,
 +               * it says that for octal conversions
 +               * the precision is artificially increased
 +               * to add an extra 0 if # is supplied.
 +               * Indeed, in C,
 +               *      printf("%#.0o\n", 0);
 +               * prints a single 0.
 +               */
 +      
 +              if (! spec->alt && spec->have_prec && spec->prec == 0 && tmpval 
== 0) {
 +                      pr_num_tail(cp, spec->prec, spec, outb);
 +                      return 0;
 +              }
 +
 +              if (tmpval < 0) {
 +                      uval = (uintmax_t) (intmax_t) 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;
 +              }
 +
 +              /* spec->fmtchar = cs1; */
 +              format_nondecimal(uval, spec, outb);
 +              return 0;
 +
 +out_of_range:
 +              /* out of range - emergency use of %g format */
 +              if (do_lint)
 +                      lintwarn(_("[s]printf: value %g is out of range for 
`%%%c' format"),
 +                                      (double) tmpval, cs1);
 +              cs1 = 'g';
 +              goto fmt1;
 +
 +      case 'F':
 +#if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
 +              cs1 = 'f';
 +              /* FALL THROUGH */
 +#endif
 +      case 'g':
 +      case 'G':
 +      case 'e':
 +      case 'f':
 +      case 'E':
 +fmt1:
 +              if (! spec->have_prec)
 +                      spec->prec = DEFAULT_G_PRECISION;
 +
 +              chksize(outb, spec->fw + spec->prec + 11);      /* 11 == slop */
 +              cp = CPBUF;     /* XXX --- using the temporary prepend-buffer 
and
 +                               * we know it has enough room (>=11).
 +                                 */
 +              *cp++ = '%';
 +              if (spec->lj)
 +                      *cp++ = '-';
 +              if (spec->signchar)
 +                      *cp++ = spec->signchar;
 +              if (spec->alt)
 +                      *cp++ = '#';
 +              if (spec->zero_flag)
 +                      *cp++ = '0';
 +              if (spec->quote_flag)
 +                      *cp++ = '\'';
 +
 +#if defined(LC_NUMERIC)
 +              if (spec->quote_flag && ! use_lc_numeric)
 +                      setlocale(LC_NUMERIC, "");
 +#endif
 +
 +              sprintf(cp, "*.*%c", cs1);
 +              while ((nc = snprintf(buf_end(outb), buf_space(outb), CPBUF,
 +                              (int) spec->fw, (int) spec->prec, tmpval)) >= 
buf_space(outb))
 +                      chksize(outb, nc + 1);
 +
 +#if defined(LC_NUMERIC)
 +              if (spec->quote_flag && ! use_lc_numeric)
 +                      setlocale(LC_NUMERIC, "C");
 +#endif
 +
 +              buf_adjust(outb, nc); /* adjust data and free space in output 
buffer */
 +              return 0;
 +
 +      default:
 +              cant_happen();  
 +      }
 +
 +      return -1;
 +#undef CP
 +#undef CEND
 +#undef CPBUF
 +}
diff --cc format.c
index 2322d56,0000000..1cc29a8
mode 100644,000000..100644
--- a/format.c
+++ b/format.c
@@@ -1,791 -1,0 +1,779 @@@
 +/*
 + * format.c - routines for (s)printf formatting.
 + */
 +
 +/* 
 + * 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 "format.h"
 +
 +char lchbuf[] = "0123456789abcdef";
 +char Uchbuf[] = "0123456789ABCDEF";
 +char space_string[] = " ";
 +char zero_string[] = "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;
 +
 +      memset(& cur_state, 0, sizeof(cur_state));
 +
 +      assert(gawk_mb_cur_max > 1);
 +      mb_len = mbrlen(ptr, numchars * gawk_mb_cur_max, &cur_state);
 +      if (mb_len <= 0)
 +              return numchars;        /* no valid m.b. char */
 +
 +      for (; numchars > 0; numchars--) {
 +              mb_len = mbrlen(ptr, numchars * gawk_mb_cur_max, &cur_state);
 +              if (mb_len <= 0)
 +                      break;
 +              sum += mb_len;
 +              ptr += mb_len;
 +      }
 +
 +      return sum;
- #else
-       return numchars;
- #endif
 +}
 +
 +/* mbc_char_count --- return number of m.b. chars in string, up to numbytes 
bytes */
 +
 +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;
 +
 +      if (gawk_mb_cur_max == 1)
 +              return numbytes;
 +
 +      memset(& cur_state, 0, sizeof(cur_state));
 +
 +      mb_len = mbrlen(ptr, numbytes * gawk_mb_cur_max, &cur_state);
 +      if (mb_len <= 0)
 +              return numbytes;        /* no valid m.b. char */
 +
 +      for (; numbytes > 0; numbytes--) {
 +              mb_len = mbrlen(ptr, numbytes * gawk_mb_cur_max, &cur_state);
 +              if (mb_len <= 0)
 +                      break;
 +              sum++;
 +              ptr += mb_len;
 +      }
 +
 +      return sum;
- #else
-       return numbytes;
- #endif
 +}
 +
 +
 +#define OUTBUF_INIT_SIZE      510
 +
 +/* chksize__internal --- make room for something LEN big in the output buffer 
*/
 +
 +static void
 +chksize__internal(struct print_fmt_buf *outb, size_t len)
 +{
 +      size_t delta, newsize;
 +
 +      assert(outb->buf != NULL);
 +      delta = outb->dataend - outb->buf;
 +      newsize = delta + len + OUTBUF_INIT_SIZE;
 +      erealloc(outb->buf, char *, newsize + 2, "chksize__internal");
 +      outb->dataend = outb->buf + delta;
 +      outb->bufsize = newsize;
 +      outb->room_left = len + OUTBUF_INIT_SIZE;
 +}
 +
 +/* cpbuf_chksize__internal --- enlarge the temporary buffer */
 +
 +static void
 +cpbuf_chksize__internal(struct print_fmt_buf *outb)
 +{
 +      char *cp, *prev = outb->cpbuf.buf;
 +      size_t oldsize = outb->cpbuf.bufsize;
 +      size_t newsize;
 +
 +      newsize = outb->cpbuf.bufsize = 2 * oldsize;
 +      emalloc(outb->cpbuf.buf, char *, newsize + 2, 
"cpbuf_chksize__internal");
 +      memcpy((cp = outb->cpbuf.buf + oldsize), prev,  oldsize);
 +      efree(prev);
 +      outb->cpbuf.bufend = outb->cpbuf.buf + newsize;
 +      outb->cpbuf.databegin = cp;
 +}
 +
 +static struct print_fmt_buf static_outb;
 +
 +/* get_fmt_buf --- buffer(s) to manage (s)printf formatting */
 + 
 +struct print_fmt_buf *
 +get_fmt_buf()
 +{
 +      struct print_fmt_buf *outb;
 +
 +      if (static_outb.buf == NULL)
 +              outb = & static_outb;
 +      else {
 +              emalloc(outb, struct print_fmt_buf *, sizeof (struct 
print_fmt_buf), "get_fmt_buf");
 +              outb->is_malloced = true;
 +      }
 +
 +      emalloc(outb->buf, char *, OUTBUF_INIT_SIZE + 2, "get_fmt_buf");
 +      outb->bufsize = OUTBUF_INIT_SIZE;
 +      outb->room_left = outb->bufsize;
 +      outb->dataend = outb->buf;
 +      outb->chksize = chksize__internal;
 +
 +      emalloc(outb->cpbuf.buf, char *, 64, "get_fmt_buf");
 +      outb->cpbuf.bufsize = 62;
 +      outb->cpbuf.databegin = outb->cpbuf.bufend = outb->cpbuf.buf + 
outb->cpbuf.bufsize;
 +      outb->cpbuf_chksize = cpbuf_chksize__internal;
 +      return outb;
 +}
 +
 +/* fmt_parse --- parse a single format code */  
 +
 +struct format_spec *
 +fmt_parse(NODE *n, const char *fmt_string, size_t fmt_len)
 +{
 +      struct format_spec *spec = NULL;
 +
 +      spec = (struct format_spec *) format_tree(fmt_string, fmt_len, NULL, 
LONG_MIN);
 +      if (spec != NULL && n == CONVFMT_node
 +              && (spec->fmtchar == 's' || spec->fmtchar == 'c')
 +      ) {
 +              efree(spec);
 +              spec = NULL;
 +      }
 +      return spec;
 +}
 +
 +
 +/* format_nondecimal --- output a nondecimal number according to a format */
 +
 +void
 +format_nondecimal(uintmax_t val, struct format_spec *spec, struct 
print_fmt_buf *outb)
 +{
 +      uintmax_t uval = val;
 +      int ii, jj;
 +      const char *chbuf = spec->chbuf;
 +
 +#     define CP               cpbuf_start(outb)
 +#     define CEND             cpbuf_end(outb)
 +
 +      /*
 +       * When to fill with zeroes is of course not simple.
 +       * First: No zero fill if left-justifying.
 +       * Next: There seem to be two cases:
 +       *      A '0' without a precision, e.g. %06d
 +       *      A precision with no field width, e.g. %.10d
 +       * Any other case, we don't want to fill with zeroes.
 +       */
 +      if (! spec->lj
 +                  && ((spec->zero_flag && ! spec->have_prec)
 +                      || (spec->fw == 0 && spec->have_prec))
 +      )
 +              spec->fill = zero_string;
 +
 +      ii = jj = 0;
 +      do {
 +              tmpbuf_prepend(outb, chbuf[uval % spec->base]);
 +              uval /= spec->base;
 +#if defined(HAVE_LOCALE_H)
 +              if (spec->base == 10 && spec->quote_flag && loc.grouping[ii] && 
++jj == loc.grouping[ii]) {
 +                      if (uval)       /* only add if more digits coming */
 +                              tmpbuf_prepend(outb, loc.thousands_sep[0]);     
/* XXX --- assumption it's one char */
 +                      if (loc.grouping[ii+1] == 0)                            
              
 +                              jj = 0;     /* keep using current val in 
loc.grouping[ii] */
 +                      else if (loc.grouping[ii+1] == CHAR_MAX)                
        
 +                              spec->quote_flag= false;
 +                      else {                 
 +                              ii++;
 +                              jj = 0;
 +                      }
 +              }
 +#endif
 +      } while (uval > 0);
 +
 +      /* add more output digits to match the precision */
 +      if (spec->have_prec) {
 +              while (CEND - CP < spec->prec)
 +                      tmpbuf_prepend(outb, '0');
 +      }
 +
 +      if (spec->alt && val != 0) {
 +              if (spec->base == 16) {
 +                      tmpbuf_prepend(outb, spec->fmtchar);
 +                      tmpbuf_prepend(outb, '0');
 +                      if (spec->fill != space_string) {
 +                              bchunk(outb, CP, 2);
 +                              CP += 2;
 +                              spec->fw -= 2;
 +                      }
 +              } else if (spec->base == 8)
 +                      tmpbuf_prepend(outb, '0');
 +      }
 +
 +      spec->base = 0;
 +      if (spec->prec > spec->fw)
 +              spec->fw = spec->prec;
 +      spec->prec = CEND - CP;
 +      pr_num_tail(CP, spec->prec, spec, outb);
 +
 +#undef CP
 +#undef CEND
 +}
 +
 +
 +/*
 + * format_tree() formats arguments of sprintf,
 + * and accordingly to a fmt_string providing a format like in
 + * printf family from C library.  Returns a string node which value
 + * is a formatted string.  Called by  sprintf function.
 + *
 + * It is one of the uglier parts of gawk.  Thanks to Michal Jaegermann
 + * for taming this beast and making it compatible with ANSI C.
 + */
 +
 +
 +NODE *
 +format_tree(
 +      const char *fmt_string,
 +      size_t n0,
 +      NODE **the_args,
 +      long num_args)
 +{
 +      size_t cur_arg = 0;
 +      NODE *retval = NULL;
 +      bool toofew = false;
 +      const char *s0, *s1;
 +      int cs1;
 +      NODE *arg;
 +      long argnum;
 +
 +      bool used_dollar;
 +      bool big_flag, bigbig_flag, small_flag, need_format;
 +      long *cur = NULL;
 +      uintmax_t uval;
 +      char *cp;
 +      size_t copy_count, char_count;
 +
 +      struct print_fmt_buf *outb;
 +      struct format_spec spec;
 +
 +#     define CP               cpbuf_start(outb)
 +#     define CEND             cpbuf_end(outb)
 +#     define CPBUF            cpbuf(outb)
 +
 +/* parse a single format specifier */
 +#define do_parse_fmt  (num_args == LONG_MIN)
 +
 +      /*
 +       * Check first for use of `count$'.
 +       * If plain argument retrieval was used earlier, choke.
 +       *      Otherwise, return the requested argument.
 +       * If not `count$' now, but it was used earlier, choke.
 +       * If this format is more than total number of args, choke.
 +       * Otherwise, return the current argument.
 +       */
 +#define parse_next_arg() { \
 +      if (do_parse_fmt) \
 +              goto out; \
 +      else if (argnum > 0) { \
 +              if (cur_arg > 1) { \
 +                      msg(_("fatal: must use `count$' on all formats or 
none")); \
 +                      goto out; \
 +              } \
 +              arg = the_args[argnum]; \
 +      } else if (used_dollar) { \
 +              msg(_("fatal: must use `count$' on all formats or none")); \
 +              arg = 0; /* shutup the compiler */ \
 +              goto out; \
 +      } else if (cur_arg >= num_args) { \
 +              arg = 0; /* shutup the compiler */ \
 +              toofew = true; \
 +              break; \
 +      } else { \
 +              arg = the_args[cur_arg]; \
 +              cur_arg++; \
 +      } \
 +}
 +
 +      outb = get_fmt_buf();
 +      cur_arg = 1;
 +
 +      need_format = false;
 +      used_dollar = false;
 +
 +      s0 = s1 = fmt_string;
 +
 +      while (n0-- > 0) {
 +              if (*s1 != '%') {
 +                      s1++;
 +                      continue;
 +              }
 +              need_format = true;
 +              bchunk(outb, s0, s1 - s0);
 +              s0 = s1;
 +              argnum = 0;
 +
 +              memset(& spec, '\0', sizeof (spec));
 +              cur = & spec.fw;
 +              spec.fill = space_string;       /* always space for string */
 +
 +              big_flag = bigbig_flag = small_flag = false;
 +              CP = CEND;
 +              s1++;
 +
 +retry:
 +              if (n0-- == 0)  /* ran out early! */
 +                      break;
 +
 +              switch (cs1 = *s1++) {
 +              case (-1):      /* dummy case to allow for checking */
 +check_pos:
 +                      if (cur != & spec.fw)
 +                              break;          /* reject as a valid format */
 +                      goto retry;
 +              case '%':
 +                      need_format = false;
 +                      /*
 +                       * 29 Oct. 2002:
 +                       * The C99 standard pages 274 and 279 seem to imply that
 +                       * since there's no arg converted, the field width 
doesn't
 +                       * apply.  The code already was that way, but this
 +                       * comment documents it, at least in the code.
 +                       */
 +                      if (do_lint) {
 +                              const char *msg = NULL;
 +
 +                              if (spec.fw && ! spec.have_prec)
 +                                      msg = _("field width is ignored for 
`%%' specifier");
 +                              else if (spec.fw == 0 && spec.have_prec)
 +                                      msg = _("precision is ignored for `%%' 
specifier");
 +                              else if (spec.fw && spec.have_prec)
 +                                      msg = _("field width and precision are 
ignored for `%%' specifier");
 +
 +                              if (msg != NULL)
 +                                      lintwarn("%s", msg);
 +                      }
 +                      bchunk_one(outb, "%");
 +                      s0 = s1;
 +                      break;
 +
 +              case '0':
 +                      /*
 +                       * Only turn on zero_flag if we haven't seen
 +                       * the field width or precision yet.  Otherwise,
 +                       * screws up floating point formatting.
 +                       */
 +                      if (cur == & spec.fw)
 +                              spec.zero_flag = true;
 +                      if (spec.lj)
 +                              goto retry;
 +                      /* FALL through */
 +              case '1':
 +              case '2':
 +              case '3':
 +              case '4':
 +              case '5':
 +              case '6':
 +              case '7':
 +              case '8':
 +              case '9':
 +                      if (cur == NULL)
 +                              break;
 +                      if (spec.prec >= 0)
 +                              *cur = cs1 - '0';
 +                      /*
 +                       * with a negative precision *cur is already set
 +                       * to -1, so it will remain negative, but we have
 +                       * to "eat" precision digits in any case
 +                       */
 +                      while (n0 > 0 && *s1 >= '0' && *s1 <= '9') {
 +                              --n0;
 +                              *cur = *cur * 10 + *s1++ - '0';
 +                      }
 +                      if (spec.prec < 0)      /* negative precision is 
discarded */
 +                              spec.have_prec = false;
 +                      if (cur == & spec.prec)
 +                              cur = NULL;
 +                      if (n0 == 0)    /* badly formatted control string */
 +                              continue;
 +                      goto retry;
 +              case '$':
 +                      if (do_traditional) {
 +                              msg(_("fatal: `$' is not permitted in awk 
formats"));
 +                              goto out;
 +                      }
 +                      if (do_parse_fmt)
 +                              goto out;
 +
 +                      if (cur == & spec.fw) {
 +                              argnum = spec.fw;
 +                              spec.fw = 0;
 +                              used_dollar = true;
 +                              if (argnum <= 0) {
 +                                      msg(_("fatal: arg count with `$' must 
be > 0"));
 +                                      goto out;
 +                              }
 +                              if (argnum >= num_args) {
 +                                      msg(_("fatal: arg count %ld greater 
than total number of supplied arguments"), argnum);
 +                                      goto out;
 +                              }
 +                      } else {
 +                              msg(_("fatal: `$' not permitted after period in 
format"));
 +                              goto out;
 +                      }
 +
 +                      goto retry;
 +              case '*':
 +                      if (cur == NULL)
 +                              break;
 +                      if (! do_traditional && isdigit((unsigned char) *s1)) {
 +                              int val = 0;
 +
 +                              for (; n0 > 0 && *s1 && isdigit((unsigned char) 
*s1); s1++, n0--) {
 +                                      val *= 10;
 +                                      val += *s1 - '0';
 +                              }
 +                              if (*s1 != '$') {
 +                                      msg(_("fatal: no `$' supplied for 
positional field width or precision"));
 +                                      goto out;
 +                              } else {
 +                                      s1++;
 +                                      n0--;
 +                              }
 +                              if (val >= num_args) {
 +                                      toofew = true;
 +                                      break;
 +                              }
 +                              arg = the_args[val];
 +                      } else {
 +                              parse_next_arg();
 +                      }
 +
 +                      (void) force_number(arg);
 +                      *cur = get_number_si(arg);
 +                      if (*cur < 0 && cur == & spec.fw) {
 +                              *cur = -*cur;
 +                              spec.lj++;
 +                      }
 +                      if (cur == & spec.prec) {
 +                              if (*cur >= 0)
 +                                      spec.have_prec = true;
 +                              else
 +                                      spec.have_prec = false;
 +                              cur = NULL;
 +                      }
 +                      goto retry;
 +              case ' ':               /* print ' ' or '-' */
 +                                      /* 'space' flag is ignored */
 +                                      /* if '+' already present  */
 +                      if (spec.signchar != false) 
 +                              goto check_pos;
 +                      /* FALL THROUGH */
 +              case '+':               /* print '+' or '-' */
 +                      spec.signchar = cs1;
 +                      goto check_pos;
 +              case '-':
 +                      if (spec.prec < 0)
 +                              break;
 +                      if (cur == & spec.prec) {
 +                              spec.prec = -1;
 +                              goto retry;
 +                      }
 +                      spec.lj++;              /* filling is ignored */
 +                      goto check_pos;
 +              case '.':
 +                      if (cur != & spec.fw)
 +                              break;
 +                      cur = & spec.prec;
 +                      spec.have_prec = true;
 +                      goto retry;
 +              case '#':
 +                      spec.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')
 +                              spec.quote_flag= true;
 +                      goto check_pos;
 +#else
 +                      goto retry;  
 +#endif
 +              case 'l':
 +                      if (big_flag)
 +                              break;
 +                      else {
 +                              static bool warned = false;
 +                              
 +                              if (do_lint && ! warned) {
 +                                      lintwarn(_("`l' is meaningless in awk 
formats; ignored"));
 +                                      warned = true;
 +                              }
 +                              if (do_posix) {
 +                                      msg(_("fatal: `l' is not permitted in 
POSIX awk formats"));
 +                                      goto out;
 +                              }
 +                      }
 +                      big_flag = true;
 +                      goto retry;
 +              case 'L':
 +                      if (bigbig_flag)
 +                              break;
 +                      else {
 +                              static bool warned = false;
 +                              
 +                              if (do_lint && ! warned) {
 +                                      lintwarn(_("`L' is meaningless in awk 
formats; ignored"));
 +                                      warned = true;
 +                              }
 +                              if (do_posix) {
 +                                      msg(_("fatal: `L' is not permitted in 
POSIX awk formats"));
 +                                      goto out;
 +                              }
 +                      }
 +                      bigbig_flag = true;
 +                      goto retry;
 +              case 'h':
 +                      if (small_flag)
 +                              break;
 +                      else {
 +                              static bool warned = false;
 +                              
 +                              if (do_lint && ! warned) {
 +                                      lintwarn(_("`h' is meaningless in awk 
formats; ignored"));
 +                                      warned = true;
 +                              }
 +                              if (do_posix) {
 +                                      msg(_("fatal: `h' is not permitted in 
POSIX awk formats"));
 +                                      goto out;
 +                              }
 +                      }
 +                      small_flag = true;
 +                      goto retry;
 +              case 'c':
 +                      need_format = false;
 +                      spec.fmtchar = cs1;
 +                      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) != 0) {
 +                              uval = get_number_uj(arg);
- #if MBS_SUPPORT
 +                              if (gawk_mb_cur_max > 1) {
 +                                      char buf[100];
 +                                      wchar_t wc;
 +                                      mbstate_t mbs;
 +                                      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) {
 +                                              if (do_lint)
 +                                                      lintwarn(
 +                                              _("[s]printf: value %g is not a 
valid wide character"),
 +                                                                      
arg->numbr);
 +
 +                                              goto out0;
 +                                      }
 +
 +                                      memcpy(CPBUF, buf, count);
 +                                      spec.prec = count;
 +                                      cp = CPBUF;
 +                                      goto pr_tail;
 +                              }
 +out0:
 +                              ;
 +                              /* else,
 +                                      fall through */
- #endif
 +                              CPBUF[0] = uval;
 +                              spec.prec = 1;
 +                              cp = CPBUF;
 +                              goto pr_tail;
 +                      }
 +                      /*
 +                       * As per POSIX, only output first character of a
 +                       * string value.  Thus, we ignore any provided
 +                       * precision, forcing it to 1.  (Didn't this
 +                       * used to work? 6/2003.)
 +                       */
 +                      cp = arg->stptr;
 +                      spec.prec = 1;
- #if MBS_SUPPORT
 +                      /*
 +                       * First character can be multiple bytes if
 +                       * it's a multibyte character. Grr.
 +                       */
 +                      if (gawk_mb_cur_max > 1) {
 +                              mbstate_t state;
 +                              size_t count;
 +
 +                              memset(& state, 0, sizeof(state));
 +                              count = mbrlen(cp, arg->stlen, & state);
 +                              if (count != (size_t) -1 && count != (size_t) 
-2 && count > 0) {
 +                                      spec.prec = count;
 +                                      /* may need to increase fw so that 
padding happens, see pr_tail code */
 +                                      if (spec.fw > 0)
 +                                              spec.fw += count - 1;
 +                              }
 +                      }
- #endif
 +                      goto pr_tail;
 +              case 's':
 +                      need_format = false;
 +                      spec.fmtchar = cs1;
 +                      parse_next_arg();
 +                      arg = force_string(arg);
 +                      if (spec.fw == 0 && ! spec.have_prec)
 +                              spec.prec = arg->stlen;
 +                      else {
 +                              char_count = mbc_char_count(arg->stptr, 
arg->stlen);
 +                              if (! spec.have_prec || spec.prec > char_count)
 +                                      spec.prec = char_count;
 +                      }
 +                      cp = arg->stptr;
 +      pr_tail:
 +                      if (! spec.lj)
 +                              pr_fill(& spec, outb);
 +
 +                      copy_count = spec.prec;
 +                      if (spec.fw == 0 && ! spec.have_prec)
 +                              ;
 +                      else if (gawk_mb_cur_max > 1) {
 +                              if (cs1 == 's') {
 +                                      assert(cp == arg->stptr || cp == CPBUF);
 +                                      copy_count = mbc_byte_count(arg->stptr, 
spec.prec);
 +                              }
 +                              /* prec was set by code for %c */
 +                              /* else
 +                                      copy_count = prec; */
 +                      }
 +
 +                      bchunk(outb, cp, copy_count);
 +                      pr_fill(& spec, outb);
 +
 +                      s0 = s1;
 +                      break;
 +
 +              case 'X':
 +                      /* FALL THROUGH */
 +              case 'x':
 +                      spec.base += 6;
 +                      /* FALL THROUGH */
 +              case 'u':
 +                      spec.base += 2;
 +                      /* FALL THROUGH */
 +              case 'o':
 +                      spec.base += 8;
 +                      goto fmt1;
 +              case 'F':
 +#if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
 +                      cs1 = 'f';
 +                      /* FALL THROUGH */
 +#endif
 +              case 'g':
 +              case 'G':
 +              case 'e':
 +              case 'f':
 +              case 'E':
 +              case 'd':
 +              case 'i':
 +      fmt1:
 +                      need_format = false;
 +                      spec.fmtchar = cs1;
 +                      parse_next_arg();
 +                      (void) force_number(arg);
 +                      spec.fmtchar = cs1;
 +                      if (format_number_printf(arg, & spec, outb) < 0)
 +                              goto out;
 +
 +                      s0 = s1;
 +                      break;
 +
 +              default:
 +                      if (isalpha(cs1)) {
 +                              if (do_lint)
 +      lintwarn(_("ignoring unknown format specifier character `%c': no 
argument converted"), cs1);
 +                              if (do_parse_fmt)
 +                                      goto out;
 +                      }
 +                      break;
 +              }
 +              if (toofew) {
 +                      msg("%s\n\t`%s'\n\t%*s%s",
 +                            _("fatal: not enough arguments to satisfy format 
string"),
 +                            fmt_string, (int) (s1 - fmt_string - 1), "",
 +                            _("^ ran out for this one"));
 +                      goto out;
 +              }
 +      }
 +
 +      if (do_lint) {
 +              if (need_format)
 +                      lintwarn(_("[s]printf: format specifier does not have 
control letter"));
 +              if (cur_arg < num_args)
 +                      lintwarn(_("too many arguments supplied for format 
string"));
 +      }
 +
 +      bchunk(outb, s0, s1 - s0);
 +      retval = bytes2node(outb, NULL);
 +out:
 +      free_fmt_buf(outb);
 +
 +      if (do_parse_fmt) {
 +              struct format_spec *cp_spec;
 +
 +              assert(retval == NULL);
 +              if (spec.fmtchar == (char) 0)
 +                      return NULL;
 +              emalloc(cp_spec, struct format_spec *, sizeof (*cp_spec), 
"format_tree");
 +              *cp_spec = spec;
 +              return (NODE *) cp_spec;
 +      }
 +
 +      if (retval == NULL)
 +              gawk_exit(EXIT_FATAL);  /* debugger needs this */
 +
 +      return retval;
 +
 +#undef CP
 +#undef CEND
 +#undef CPBUF
 +}
diff --cc io.c
index feef47e,cf9dd94..b9fe232
--- a/io.c
+++ b/io.c
@@@ -569,20 -595,12 +576,21 @@@ inrec(IOBUF *iop, int *errcode
        else 
                cnt = get_a_record(& begin, iop, errcode);
  
-       if (cnt == EOF) {
+       /* Note that get_a_record may return -2 when I/O would block */
+       if (cnt < 0) {
                retval = false;
        } else {
 -              INCREMENT_REC(NR);
 -              INCREMENT_REC(FNR);
 +#if 0
 +              /* XXX: looser if AWKNUM is long double */
 +              if (numbr_hndlr == & awknum_hndlr) {
 +                      NR++;
 +                      FNR++;
 +              } else
 +#endif
 +              {
 +                      NR = numbr_hndlr->increment_var(NR_node, NR);
 +                      FNR = numbr_hndlr->increment_var(FNR_node, FNR);
 +              }
                set_record(begin, cnt);
                if (*errcode > 0)
                        retval = false;
diff --cc main.c
index 4a31459,833aa16..f7909b8
--- a/main.c
+++ b/main.c
@@@ -337,320 -284,124 +297,110 @@@ main(int argc, char **argv
        /* 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;
+       parse_args(argc, argv);
  
-               switch (c) {
-               case 'F':
-                       add_preassign(PRE_ASSIGN_FS, optarg);
-                       break;
+       set_locale_stuff();
  
-               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);
+       /*
+        * 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;
  
-                       break;
+       /* init the cache for checking bytes if they're characters */
+       init_btowc_cache();
  
-               case 'v':
-                       add_preassign(PRE_ASSIGN, optarg);
-                       break;
+       if (do_nostalgia)
+               nostalgia();
  
-               case 'b':
-                       do_binary = true;
-                       break;
+       /* check for POSIXLY_CORRECT environment variable */
+       if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) {
+               do_flags |= DO_POSIX;
+               if (do_lint)
+                       lintwarn(
+       _("environment variable `POSIXLY_CORRECT' set: turning on `--posix'"));
+       }
  
-               case 'c':
+       if (do_posix) {
+               use_lc_numeric = true;
+               if (do_traditional)     /* both on command line */
+                       warning(_("`--posix' overrides `--traditional'"));
+               else
                        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;
+                       /*
+                        * POSIX compliance also implies
+                        * no GNU extensions either.
+                        */
+       }
  
-               case 'D':
-                       do_flags |= DO_DEBUG;
-                       if (optarg != NULL && optarg[0] != '\0')
-                               command_file = optarg;
-                       break;
+       if (do_traditional && do_non_decimal_data) {
+               do_flags &= ~DO_NON_DEC_DATA;
+               warning(_("`--posix'/`--traditional' overrides 
`--non-decimal-data'"));
+       }
  
-               case 'e':
-                       if (optarg[0] == '\0')
-                               warning(_("empty argument to `-e/--source' 
ignored"));
-                       else
-                               (void) add_srcfile(SRC_CMDLINE, optarg, 
srcfiles, NULL, NULL);
-                       break;
+       if (do_lint && os_is_setuid())
+               warning(_("running %s setuid root may be a security problem"), 
myname);
  
-               case 'g':
-                       do_flags |= DO_INTL;
-                       break;
+       if (do_binary) {
+               if (do_posix)
+                       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
+       }
  
-               case 'h':
-                       /* write usage to stdout, per GNU coding stds */
-                       usage(EXIT_SUCCESS, stdout);
-                       break;
++      /* Set up number handler */
++      init_numbr_handler(& numbr_bltins);
 +
-               case 'i':
-                       (void) add_srcfile(SRC_INC, optarg, srcfiles, NULL, 
NULL);
-                       break;
+       if (do_debug)   /* Need to register the debugger pre-exec hook before 
any other */
+               init_debug();
  
-               case 'l':
-                       (void) add_srcfile(SRC_EXTLIB, optarg, srcfiles, NULL, 
NULL);
-                       break;
 -#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();
  
- #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;
 -#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.
+        * Do this before initializing variables, since
+        * they could want to do a regexp compile.
+        */
+       resetup();
  
-               case 't':
-                       do_flags |= DO_LINT_OLD;
-                       break;
- #else
-               case 'L':
-               case 't':
-                       break;
- #endif
+       /* Set up the special variables */
+       init_vars();
  
-               case 'n':
-                       do_flags |= DO_NON_DEC_DATA;
-                       break;
+       /* Set up the field variables */
+       init_fields();
  
-               case 'N':
-                       use_lc_numeric = true;
-                       break;
+       /* Now process the pre-assignments */
+       for (i = 0; i <= numassigns; i++) {
+               if (preassigns[i].type == PRE_ASSIGN)
+                       (void) arg_assign(preassigns[i].val, true);
+               else    /* PRE_ASSIGN_FS */
+                       cmdline_fs(preassigns[i].val);
+               efree(preassigns[i].val);
+       }
  
-               case 'O':
-                       do_optimize = true;
-                       break;
+       if (preassigns != NULL)
+               efree(preassigns);
  
-               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;
+       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 & 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)
+                       fatal(_("can't set binary mode on stderr (%s)"), 
strerror(errno));
+       }
  
-               case 'M':
- #ifdef HAVE_MPFR
-                       numbr_hndlr = & mpfp_hndlr;
- #else
-                       warning(_("-M ignored: MPFR/GMP support not compiled 
in"));
+ #ifdef GAWKDEBUG
+       setbuf(stdout, (char *) NULL);  /* make debugging easier */
  #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':
- #if defined(YYDEBUG) || defined(GAWKDEBUG)
-                       if (c == 'Y') {
-                               yydebug = 2;
-                               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:
- 
-       if (do_nostalgia)
-               nostalgia();
- 
-       /* check for POSIXLY_CORRECT environment variable */
-       if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) {
-               do_flags |= DO_POSIX;
-               if (do_lint)
-                       lintwarn(
-       _("environment variable `POSIXLY_CORRECT' set: turning on `--posix'"));
-       }
- 
-       if (do_posix) {
-               use_lc_numeric = true;
-               if (do_traditional)     /* both on command line */
-                       warning(_("`--posix' overrides `--traditional'"));
-               else
-                       do_flags |= DO_TRADITIONAL;
-                       /*
-                        * POSIX compliance also implies
-                        * no GNU extensions either.
-                        */
-       }
- 
-       if (do_traditional && do_non_decimal_data) {
-               do_flags &= ~DO_NON_DEC_DATA;
-               warning(_("`--posix'/`--traditional' overrides 
`--non-decimal-data'"));
-       }
- 
-       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 
`--characters-as-bytes'"));
-               else
-                       gawk_mb_cur_max = 1;    /* hands off my data! */
- #if defined(LC_ALL)
-               setlocale(LC_ALL, "C");
- #endif
-       }
- #endif
- 
-       /* Set up number handler */
-       init_numbr_handler(& numbr_bltins);
- 
-       if (do_debug)   /* Need to register the debugger pre-exec hook before 
any other */
-               init_debug();
- 
-       /* init array handling. */
-       array_init();
- 
-       /* init the symbol tables */
-       init_symbol_table();
- 
-       /* load group set */
-       init_groupset();
- 
-       /*
-        * Tell the regex routines how they should work.
-        * Do this before initializing variables, since
-        * they could want to do a regexp compile.
-        */
-       resetup();
- 
-       /* Set up the special variables */
-       init_vars();
- 
-       /* Set up the field variables */
-       init_fields();
- 
-       /* Now process the pre-assignments */
-       for (i = 0; i <= numassigns; i++) {
-               if (preassigns[i].type == PRE_ASSIGN)
-                       (void) arg_assign(preassigns[i].val, true);
-               else    /* PRE_ASSIGN_FS */
-                       cmdline_fs(preassigns[i].val);
-               efree(preassigns[i].val);
-       }
- 
-       if (preassigns != NULL)
-               efree(preassigns);
- 
-       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 & 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)
-                       fatal(_("can't set binary mode on stderr (%s)"), 
strerror(errno));
-       }
- 
- #ifdef GAWKDEBUG
-       setbuf(stdout, (char *) NULL);  /* make debugging easier */
- #endif
-       if (os_isatty(fileno(stdout)))
-               output_is_tty = true;
+       if (os_isatty(fileno(stdout)))
+               output_is_tty = true;
  
        /* initialize API before loading extension libraries */
        init_ext_api();
@@@ -1042,12 -794,10 +792,12 @@@ init_vars(
                        (*(vp->assign))();
        }
  
 +      numbr_hndlr->init_numvars();    /* set default values for variables 
e.g. PREC */ 
 +
-       /* 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 */
@@@ -1657,3 -1387,285 +1417,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;
++                      numbr_hndlr = & mpfp_hndlr;
+ #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 --cc mpfr.c
index d7d22b0,080ed7f..2a04ad4
--- a/mpfr.c
+++ b/mpfr.c
@@@ -43,73 -31,19 +43,73 @@@
  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);
 +#define DEFAULT_PREC          53
 +#define DEFAULT_ROUNDMODE     "N"             /* round to nearest */
 +
 +/* exported functions */
 +static NODE *mpfp_make_number(AWKNUM);
 +static int mpfp_compare(const NODE *, const NODE *);
 +static void mpfp_negate_num(NODE *);
 +static NODE *mpfp_str2node(char *, char **, int, bool);
 +static NODE *mpfp_force_number(NODE *);
 +static void mpfp_free_num(NODE *);
 +static NODE *mpfp_format_val(const char *, int, NODE *);
 +static unsigned long mpfp_toulong(const NODE *);
 +static long mpfp_tolong(const NODE *);
 +static double mpfp_todouble(const NODE *);
 +static uintmax_t mpfp_touintmax_t(const NODE *);
 +static int mpfp_sgn(const NODE *);
 +static bool mpfp_isinteger(const NODE *);
 +static bool mpfp_isnan(const NODE *);
 +static bool mpfp_isinf(const NODE *);
 +static NODE *mpfp_copy_number(const NODE *);
 +static int mpfp_format_printf(NODE *, struct format_spec *, struct 
print_fmt_buf *);
 +static bool mpfp_init(bltin_t **);
 +static NODE *mpfp_add(const NODE *, const NODE *);
 +static NODE *mpfp_sub(const NODE *, const NODE *);
 +static NODE *mpfp_mul(const NODE *, const NODE *);
 +static NODE *mpfp_div(const NODE *, const NODE *);
 +static NODE *mpfp_mod(const NODE *, const NODE *);
 +static NODE *mpfp_pow(const NODE *, const NODE *);
 +static NODE *mpfp_add_long(const NODE *, long);
 +static NODE *mpfp_update_var(NODE *);
 +static void mpfp_set_var(const NODE *);
 +static long mpfp_increment_var(const NODE *, long);
 +static void mpfp_init_vars(void);
 +static void mpfp_load_procinfo(void);
 +static const char *mpfp_version_string(void);
 +
 +/* builtins */
 +static NODE *do_mpfp_and(int);
 +static NODE *do_mpfp_atan2(int);
 +static NODE *do_mpfp_compl(int);
 +static NODE *do_mpfp_cos(int);
- static NODE *do_mpfp_div(int);
 +static NODE *do_mpfp_exp(int);
 +static NODE *do_mpfp_int(int);
++static NODE *do_mpfp_intdiv(int);
 +static NODE *do_mpfp_log(int);
 +static NODE *do_mpfp_lshift(int);
 +static NODE *do_mpfp_or(int);
 +static NODE *do_mpfp_rand(int);
 +static NODE *do_mpfp_rshift(int);
 +static NODE *do_mpfp_sin(int);
 +static NODE *do_mpfp_sqrt(int);
 +static NODE *do_mpfp_srand(int);
 +static NODE *do_mpfp_strtonum(int);
 +static NODE *do_mpfp_xor(int);
 +
 +/* internal functions */
 +static NODE *mpfp_make_node(unsigned int type);
 +static int mpfp_format_ieee(mpfr_ptr, int);
 +static const char *mpfp_sprintf(const char *, ...);
 +static int mpfp_strtoui(mpz_ptr, char *, size_t, char **, int);
 +static mpfr_rnd_t mpfp_get_rounding_mode(const char rmode);
 +static mpfr_ptr mpz2mpfr(mpz_ptr mpz_val, mpfr_ptr mpfr_val);
 +
 +static mpfr_rnd_t ROUND_MODE;
 +static mpz_t MNR;
 +static mpz_t MFNR;
 +static bool do_ieee_fmt;      /* emulate IEEE 754 floating-point format */
  
  static mpfr_exp_t min_exp = MPFR_EMIN_DEFAULT;
  static mpfr_exp_t max_exp = MPFR_EMAX_DEFAULT;
@@@ -130,92 -59,24 +130,92 @@@ static mpfr_t _mp2
  
  #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
 +static mpz_t _mpzval; /* GMP type for float to int conversion in 
format_tree() */
 +static mpfr_t _mpfrval;       /* MPFR type for int to float conversion in 
format_tree() */
 +
 +#define IEEE_FMT(r, t)                (void) (do_ieee_fmt && 
mpfp_format_ieee(r, t))
 +
 +#define mpfp_float()          mpfp_make_node(MPFN)
 +#define mpfp_integer()                mpfp_make_node(MPZN)
 +#define is_mpfp_float(n)      (((n)->flags & MPFN) != 0)
 +#define is_mpfp_integer(n)    (((n)->flags & MPZN) != 0)
 +#define is_mpfp_number(n)     (((n)->flags & (MPZN|MPFN)) != 0)
  
  
 -/* init_mpfr --- set up MPFR related variables */
 +/* mpfp_tofloat --- convert GMP integer to MPFR float without loosing any 
precision */
 +
 +static inline mpfr_ptr
 +mpfp_tofloat(const NODE *t, mpfr_ptr pf)
 +{
 +      return is_mpfp_float(t) ? t->qnumbr : mpz2mpfr(t->qnumbr, pf);
 +}
 +
  
 -void
 -init_mpfr(mpfr_prec_t prec, const char *rmode)
 +numbr_handler_t mpfp_hndlr = {
 +      mpfp_init,
 +      mpfp_version_string,
 +      mpfp_load_procinfo,
 +      mpfp_make_number,
 +      mpfp_str2node,
 +      mpfp_copy_number,
 +      mpfp_free_num,
 +      mpfp_force_number,
 +      mpfp_negate_num,
 +      mpfp_compare,
 +      mpfp_sgn,
 +      mpfp_isinteger,
 +      mpfp_isnan,
 +      mpfp_isinf,
 +      mpfp_format_val,
 +      mpfp_format_printf,
 +      mpfp_todouble,
 +      mpfp_tolong,
 +      mpfp_toulong,
 +      mpfp_touintmax_t,
 +      mpfp_add,
 +      mpfp_sub,
 +      mpfp_mul,
 +      mpfp_div,
 +      mpfp_mod,
 +      mpfp_pow,
 +      mpfp_add_long,
 +      mpfp_update_var,
 +      mpfp_set_var,
 +      mpfp_increment_var,
 +      mpfp_init_vars,
 +};
 +
 +
 +/* mpfp_init --- set up MPFR related variables */
 +
 +static bool
 +mpfp_init(bltin_t **numbr_bltins)
  {
 -      mpfr_set_default_prec(prec);
 -      ROUND_MODE = get_rnd_mode(rmode[0]);
 +      static bltin_t mpfp_bltins[] = {
 +              { "and",        do_mpfp_and },
 +              { "atan2",      do_mpfp_atan2 },
 +              { "compl",      do_mpfp_compl },
 +              { "cos",        do_mpfp_cos },
-               { "div",        do_mpfp_div },
 +              { "exp",        do_mpfp_exp },
 +              { "int",        do_mpfp_int },
++              { "intdiv",     do_mpfp_intdiv },
 +              { "log",        do_mpfp_log },
 +              { "lshift",     do_mpfp_lshift },
 +              { "or",         do_mpfp_or },
 +              { "rand",       do_mpfp_rand },
 +              { "rshift",     do_mpfp_rshift },
 +              { "sin",        do_mpfp_sin },
 +              { "sqrt",       do_mpfp_sqrt },
 +              { "srand",      do_mpfp_srand },
 +              { "strtonum",   do_mpfp_strtonum },
 +              { "xor",        do_mpfp_xor },
 +              { NULL, NULL },
 +      };
 +      const char *rndmode = DEFAULT_ROUNDMODE;
 +
 +      mpfr_set_default_prec(DEFAULT_PREC);
 +      ROUND_MODE = mpfp_get_rounding_mode(rndmode[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);
@@@ -350,13 -118,11 +350,11 @@@ mpfp_make_node(unsigned int type
        }
        
        r->valref = 1;
 -      r->flags |= MALLOC|NUMBER|NUMCUR;
 +      r->flags |= (MALLOC|NUMBER|NUMCUR);
        r->stptr = NULL;
        r->stlen = 0;
- #if MBS_SUPPORT
        r->wstptr = NULL;
        r->wstlen = 0;
- #endif /* defined MBS_SUPPORT */
        return r;
  }
  
@@@ -1523,7 -1186,7 +1521,7 @@@ do_mpfp_srand(int nargs
        return res;
  }
  
- /* do_mpfp_div --- do integer division, return quotient and remainder in dest 
array */
 -/* do_mpfr_intdiv --- do integer division, return quotient and remainder in 
dest array */
++/* do_mpfp_intdiv --- do integer division, return quotient and remainder in 
dest array */
  
  /*
   * We define the semantics as:
@@@ -1533,8 -1196,8 +1531,8 @@@
   *    remainder = int(numerator % denomator)
   */
  
 -NODE *
 -do_mpfr_intdiv(int nargs)
 +static NODE *
- do_mpfp_div(int nargs)
++do_mpfp_intdiv(int nargs)
  {
        NODE *numerator, *denominator, *result;
        NODE *num, *denom;
@@@ -1582,18 -1245,18 +1580,18 @@@
                        return denominator;
                }
  
 -              denom = mpg_integer();
 -              mpfr_get_z(denom->mpg_i, denominator->mpg_numbr, MPFR_RNDZ);
 +              denom = mpfp_integer();
 +              mpfr_get_z(denom->qnumbr, denominator->qnumbr, MPFR_RNDZ);
        }
  
 -      if (mpz_sgn(denom->mpg_i) == 0)
 +      if (mpz_sgn(MPZ_T(denom->qnumbr)) == 0)
-               fatal(_("div: division by zero attempted"));
+               fatal(_("intdiv: division by zero attempted"));
  
 -      quotient = mpg_integer();
 -      remainder = mpg_integer();
 +      quotient = mpfp_integer();
 +      remainder = mpfp_integer();
  
        /* do the division */
 -      mpz_tdiv_qr(quotient->mpg_i, remainder->mpg_i, num->mpg_i, 
denom->mpg_i);
 +      mpz_tdiv_qr(quotient->qnumbr, remainder->qnumbr, num->qnumbr, 
denom->qnumbr);
        unref(num);
        unref(denom);
        unref(numerator);
diff --cc node.c
index 81a1e55,507d065..fcbac33
--- a/node.c
+++ b/node.c
@@@ -623,10 -877,52 +612,7 @@@ out:     
  
        return NULL;
  }
- #endif /* MBS_SUPPORT */
- 
  
- #if MBS_SUPPORT
 -/* is_ieee_magic_val --- return true for +inf, -inf, +nan, -nan */
 -
 -static int
 -is_ieee_magic_val(const char *val)
 -{
 -      /*
 -       * Avoid strncasecmp: it mishandles ASCII bytes in some locales.
 -       * Assume the length is 4, as the caller checks this.
 -       */
 -      return (   (val[0] == '+' || val[0] == '-')
 -              && (   (   (val[1] == 'i' || val[1] == 'I')
 -                      && (val[2] == 'n' || val[2] == 'N')
 -                      && (val[3] == 'f' || val[3] == 'F'))
 -                  || (   (val[1] == 'n' || val[1] == 'N')
 -                      && (val[2] == 'a' || val[2] == 'A')
 -                      && (val[3] == 'n' || val[3] == 'N'))));
 -}
 -
 -/* get_ieee_magic_val --- return magic value for string */
 -
 -static AWKNUM
 -get_ieee_magic_val(const char *val)
 -{
 -      static bool first = true;
 -      static AWKNUM inf;
 -      static AWKNUM nan;
 -
 -      char *ptr;
 -      AWKNUM v = strtod(val, &ptr);
 -
 -      if (val == ptr) { /* Older strtod implementations don't support inf or 
nan. */
 -              if (first) {
 -                      first = false;
 -                      nan = sqrt(-1.0);
 -                      inf = -log(0.0);
 -              }
 -
 -              v = ((val[1] == 'i' || val[1] == 'I') ? inf : nan);
 -              if (val[0] == '-')
 -                      v = -v;
 -      }
 -
 -      return v;
 -}
 -
  wint_t btowc_cache[256];
  
  /* init_btowc_cache --- initialize the cache */
diff --cc profile.c
index 6cb4c6a,3e9ef78..1126de1
--- a/profile.c
+++ b/profile.c
@@@ -341,6 -400,6 +379,14 @@@ cleanup
                case Op_exp:
                case Op_quotient:
                case Op_mod:
++                      t2 = pp_pop();
++                      t1 = pp_pop();
++                      if (prec_level(t2->type) > prec_level(t1->type)
++                                      && is_binary(t1->type))  /* (a - b) * 1 
*/
++                              pp_parenthesize(t1);
++                      else
++                              parenthesize(pc->opcode, t1, t2);
++                      goto finish_binary_group;
                case Op_equal:
                case Op_notequal:
                case Op_less:
@@@ -349,7 -408,7 +395,11 @@@
                case Op_geq:
                        t2 = pp_pop();
                        t1 = pp_pop();
++                      if (prec_level(t2->type) > prec_level(t1->type)
++                                      && is_binary(t1->type))  /* (a - b) * 1 
*/
++                              pp_parenthesize(t1);
                        parenthesize(pc->opcode, t1, t2);
++      finish_binary_group:
                        str = pp_group3(t1->pp_str, op2str(pc->opcode), 
t2->pp_str);
                        pp_free(t1);
                        pp_free(t2);
@@@ -372,10 -431,10 +422,11 @@@
                case Op_field_spec:
                case Op_field_spec_lhs:
                case Op_unary_minus:
 +              case Op_unary_plus:
                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 ! */
@@@ -993,21 -1097,29 +1089,24 @@@ prec_level(int type
        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_unary_plus:
        case Op_not:
-               return 11;
+               return 12;
  
        case Op_times:
 -      case Op_times_i:
        case Op_quotient:
 -      case Op_quotient_i:
        case Op_mod:
-               return 10;
 -      case Op_mod_i:
+               return 11;
  
        case Op_plus:
 -      case Op_plus_i:
        case Op_minus:
-               return 9;
 -      case Op_minus_i:
+               return 10;
  
        case Op_concat:
        case Op_assign_concat:
@@@ -1146,6 -1266,26 +1247,24 @@@ 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);
++              return (op2 == Op_times);
+ 
+       default:
+               return false;
+       }
+ }
+ 
  /* parenthesize --- parenthesize two nodes relative to parent node type */
  
  static void

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                             |  819 ++-
 INSTALL                               |    6 +-
 Makefile.am                           |    7 +-
 Makefile.in                           |   60 +-
 NEWS                                  |   60 +-
 POSIX.STD                             |   17 +-
 README                                |    3 -
 README.num-handler                    |   11 +
 TODO                                  |   32 +-
 aclocal.m4                            |  171 +-
 array.c                               |    9 +-
 awk.h                                 |  148 +-
 awkgram.c                             | 1220 ++--
 awkgram.y                             |  499 +-
 awklib/ChangeLog                      |   10 +
 awklib/Makefile.am                    |    4 +-
 awklib/Makefile.in                    |   33 +-
 awklib/eg/lib/assert.awk              |    2 +-
 awklib/eg/lib/bits2str.awk            |    2 +-
 awklib/eg/lib/ctime.awk               |    3 +-
 awklib/eg/lib/div.awk                 |   17 -
 awklib/eg/lib/ftrans.awk              |    4 +-
 awklib/eg/lib/gettime.awk             |    2 +-
 awklib/eg/lib/groupawk.in             |    3 +-
 awklib/eg/lib/inplace.awk             |    9 +-
 awklib/eg/lib/intdiv.awk              |   20 +
 awklib/eg/lib/noassign.awk            |    2 +-
 awklib/eg/lib/processarray.awk        |   12 +
 awklib/eg/lib/quicksort.awk           |    7 +-
 awklib/eg/lib/readable.awk            |    2 +-
 awklib/eg/lib/shellquote.awk          |   22 +
 awklib/eg/lib/strtonum.awk            |    4 +-
 awklib/eg/misc/arraymax.awk           |   10 +-
 awklib/eg/misc/findpat.awk            |   13 +-
 awklib/eg/prog/anagram.awk            |    6 +-
 awklib/eg/prog/cut.awk                |    8 +-
 awklib/eg/prog/egrep.awk              |    7 +-
 awklib/eg/prog/extract.awk            |   11 +-
 awklib/eg/prog/id.awk                 |   22 +-
 awklib/eg/prog/indirectcall.awk       |    2 +-
 awklib/eg/prog/pi.awk                 |   18 +
 awklib/eg/prog/split.awk              |    7 +-
 awklib/eg/prog/translate.awk          |    2 +-
 awklib/eg/prog/uniq.awk               |    5 +-
 builtin.c                             |  259 +-
 command.c                             |    8 +-
 command.y                             |    2 +
 compile                               |  347 +
 config.guess                          |  173 +-
 config.rpath                          |   16 +-
 config.sub                            |   38 +-
 configh.in                            |   12 +-
 configure                             |  676 ++-
 configure.ac                          |   34 +-
 debug.c                               |    1 +
 depcomp                               |   37 +-
 dfa.c                                 |  421 +-
 dfa.h                                 |    2 +-
 doc/ChangeLog                         |  350 +
 doc/Makefile.in                       |   33 +-
 doc/awkcard.in                        |    6 +-
 doc/gawk.1                            |   66 +-
 doc/gawk.info                         |10163 ++++++++++++++------------
 doc/gawk.texi                         | 8672 ++++++++++++----------
 doc/gawkinet.info                     |    6 +-
 doc/gawkinet.texi                     |    2 +-
 doc/gawktexi.in                       | 8383 ++++++++++++----------
 doc/texinfo.tex                       |  271 +-
 double.c                              |   14 +-
 eval.c                                |   26 +-
 ext.c                                 |    3 +
 extension/ChangeLog                   |  236 +
 extension/INSTALL                     |    6 +-
 extension/Makefile.am                 |    6 +-
 extension/Makefile.in                 |  126 +-
 extension/aclocal.m4                  |  187 +-
 extension/build-aux/ChangeLog         |    4 +
 extension/build-aux/ar-lib            |    2 +-
 extension/build-aux/compile           |  347 +
 extension/build-aux/config.guess      |  173 +-
 extension/build-aux/config.sub        |   38 +-
 extension/build-aux/depcomp           |   37 +-
 extension/build-aux/install-sh        |   31 +-
 extension/build-aux/ltmain.sh         |  475 +-
 extension/build-aux/missing           |    6 +-
 extension/configh.in                  |   22 -
 extension/configure                   | 3269 +++------
 extension/configure.ac                |    5 +-
 extension/filefuncs.c                 |    6 +-
 extension/inplace.3am                 |   18 +-
 extension/inplace.c                   |   11 +-
 extension/m4/ChangeLog                |    8 +
 extension/m4/gettext.m4               |  383 -
 extension/m4/iconv.m4                 |  214 -
 extension/m4/intlmacosx.m4            |   51 -
 extension/m4/libtool.m4               |  628 ++-
 extension/m4/ltoptions.m4             |   57 +-
 extension/m4/ltsugar.m4               |    7 +-
 extension/m4/ltversion.m4             |   12 +-
 extension/m4/lt~obsolete.m4           |    7 +-
 extension/m4/po.m4                    |  449 --
 extension/testext.c                   |  213 +-
 extras/ChangeLog                      |    3 +
 extras/Makefile.am                    |   29 +
 extras/Makefile.in                    |  528 ++
 extras/gawk.csh                       |   11 +
 extras/gawk.sh                        |   31 +
 field.c                               |   63 +-
 format.c                              |   12 -
 gawkapi.c                             |  113 +-
 gawkapi.h                             |   54 +-
 gawkmisc.c                            |    2 +
 getopt.c                              |    4 +-
 getopt.h                              |   17 +-
 getopt1.c                             |    2 +-
 getopt_int.h                          |    2 +-
 install-sh                            |   31 +-
 interpret.h                           |   68 +-
 io.c                                  |  384 +-
 m4/ChangeLog                          |   22 +
 m4/gettext.m4                         |   58 +-
 m4/iconv.m4                           |  139 +-
 m4/lib-ld.m4                          |   77 +-
 m4/lib-link.m4                        |   43 +-
 m4/lib-prefix.m4                      |    2 +-
 m4/nls.m4                             |    2 +-
 m4/po.m4                              |   36 +-
 m4/progtest.m4                        |   21 +-
 m4/readline.m4                        |   23 +-
 main.c                                |  776 +-
 mbsupport.h                           |   74 +-
 missing                               |    6 +-
 missing_d/ChangeLog                   |    6 +
 missing_d/getaddrinfo.c               |   16 +-
 missing_d/getaddrinfo.h               |    2 +
 mpfr.c                                |   18 +-
 node.c                                |   17 +-
 pc/ChangeLog                          |   18 +
 pc/Makefile.tst                       |  107 +-
 pc/config.h                           |    6 +
 pc/gawkmisc.pc                        |    4 +-
 po/ChangeLog                          |    9 +
 po/Makefile.in.in                     |   53 +-
 po/Makevars                           |   39 +-
 po/Makevars.template                  |   37 +
 po/POTFILES.in                        |    6 +
 po/Rules-quot                         |   15 +-
 po/ca.gmo                             |  Bin 83005 -> 82049 bytes
 po/ca.po                              | 1077 ++--
 po/da.gmo                             |  Bin 42160 -> 41373 bytes
 po/da.po                              | 1079 ++--
 po/de.gmo                             |  Bin 45199 -> 83971 bytes
 po/de.po                              | 2126 +++---
 po/es.gmo                             |  Bin 44600 -> 43722 bytes
 po/es.po                              | 1084 ++--
 po/fi.gmo                             |  Bin 84555 -> 83703 bytes
 po/fi.po                              | 1082 ++--
 po/fr.gmo                             |  Bin 85628 -> 84606 bytes
 po/fr.po                              | 1077 ++--
 po/gawk.pot                           | 1040 ++--
 po/it.gmo                             |  Bin 81018 -> 81863 bytes
 po/it.po                              | 1175 ++--
 po/ja.gmo                             |  Bin 47970 -> 51602 bytes
 po/ja.po                              | 1355 ++--
 po/ms.gmo                             |  Bin 1184 -> 1183 bytes
 po/ms.po                              | 1038 ++--
 po/nl.gmo                             |  Bin 80863 -> 80070 bytes
 po/nl.po                              | 1082 ++--
 po/pl.gmo                             |  Bin 71101 -> 70252 bytes
 po/pl.po                              | 1082 ++--
 po/sv.gmo                             |  Bin 80916 -> 79966 bytes
 po/sv.po                              | 1106 ++--
 po/vi.gmo                             |  Bin 93025 -> 91989 bytes
 po/vi.po                              | 1077 ++--
 profile.c                             |  331 +-
 re.c                                  |   53 +-
 regcomp.c                             |   20 +-
 regex.c                               |    2 +-
 regex.h                               |    2 +-
 regex_internal.c                      |    2 +-
 regex_internal.h                      |   13 +-
 regexec.c                             |   10 +-
 replace.c                             |    2 +-
 symbol.c                              |   64 +-
 test/ChangeLog                        |  266 +
 test/Gentests                         |    2 +-
 test/Makefile.am                      |  153 +-
 test/Makefile.in                      |  246 +-
 test/Maketests                        |   65 +
 test/badbuild.awk                     |    6 +
 test/badbuild.in                      |    1 +
 test/badbuild.ok                      |    3 +
 test/callparam.awk                    |    6 +
 test/callparam.ok                     |    2 +
 test/crlf.awk                         |   11 +
 test/crlf.ok                          |    3 +
 test/errno.awk                        |   10 +
 test/{clsflnam.in => errno.in}        |    0
 test/errno.ok                         |    3 +
 test/exit.sh                          |    2 +-
 test/exitval3.awk                     |    2 +
 test/exitval3.ok                      |    1 +
 test/fpat4.awk                        |  105 +
 test/fpat4.ok                         |   65 +
 test/genpot.awk                       |    1 +
 test/genpot.ok                        |    5 +
 test/gensub2.ok                       |    1 +
 test/getfile.awk                      |   35 +
 test/getfile.ok                       |   17 +
 test/id.ok                            |    4 +-
 test/indirectbuiltin.awk              |  371 +
 test/indirectbuiltin.ok               |   43 +
 test/inplace1.ok                      |    2 +-
 test/inplace2.ok                      |    2 +-
 test/inplace3.ok                      |    4 +-
 test/mbprintf4.awk                    |   51 +-
 test/mbprintf4.ok                     |  144 +-
 test/mpfrmemok1.awk                   |    7 +
 test/mpfrmemok1.ok                    |    7 +
 test/mpfrsqrt.awk                     |    6 +-
 test/nonfatal1.awk                    |    6 +
 test/nonfatal1.ok                     |    2 +
 test/nonfatal2.awk                    |    5 +
 test/nonfatal2.ok                     |    1 +
 test/nonfatal3.awk                    |    6 +
 test/{arrayprm3.ok => nonfatal3.ok}   |    0
 test/paramasfunc1.awk                 |    9 +
 test/paramasfunc1.ok                  |    3 +
 test/paramasfunc2.awk                 |   10 +
 test/paramasfunc2.ok                  |    3 +
 test/printfbad4.awk                   |    5 +
 test/printfbad4.ok                    |    2 +
 test/profile0.awk                     |    1 +
 test/profile0.in                      |    2 +
 test/profile0.ok                      |    6 +
 test/profile2.ok                      |    2 +-
 test/profile3.ok                      |    2 +-
 test/profile4.ok                      |   18 +-
 test/profile5.ok                      |13092 ++++++++++++++++++---------------
 test/profile6.awk                     |    7 +
 test/profile6.ok                      |   10 +
 test/profile7.awk                     |   12 +
 test/profile7.ok                      |   15 +
 test/profile8.awk                     |    9 +
 test/profile8.ok                      |   14 +
 test/regexpbrack.awk                  |    2 +
 test/{arrayprm2.ok => regexpbrack.in} |    0
 test/{arrayprm2.ok => regexpbrack.ok} |    0
 test/sortglos.awk                     |   51 +
 test/sortglos.in                      |   22 +
 test/sortglos.ok                      |   15 +
 test/testext.ok                       |   13 +
 test/timeout.awk                      |   26 +
 test/timeout.ok                       |   12 +
 vms/ChangeLog                         |   11 +
 vms/config_h.com                      |    2 +-
 vms/vmsbuild.com                      |    6 +-
 vms/vmstest.com                       |    3 +
 ylwrap                                |   59 +-
 259 files changed, 42330 insertions(+), 33137 deletions(-)
 create mode 100644 README.num-handler
 delete mode 100644 awklib/eg/lib/div.awk
 create mode 100644 awklib/eg/lib/intdiv.awk
 create mode 100644 awklib/eg/lib/processarray.awk
 create mode 100644 awklib/eg/lib/shellquote.awk
 create mode 100644 awklib/eg/prog/pi.awk
 create mode 100755 compile
 create mode 100755 extension/build-aux/compile
 delete mode 100644 extension/m4/gettext.m4
 delete mode 100644 extension/m4/iconv.m4
 delete mode 100644 extension/m4/intlmacosx.m4
 delete mode 100644 extension/m4/po.m4
 create mode 100644 extras/ChangeLog
 create mode 100644 extras/Makefile.am
 create mode 100644 extras/Makefile.in
 create mode 100644 extras/gawk.csh
 create mode 100644 extras/gawk.sh
 create mode 100644 test/badbuild.awk
 create mode 100644 test/badbuild.in
 create mode 100644 test/badbuild.ok
 create mode 100644 test/callparam.awk
 create mode 100644 test/callparam.ok
 mode change 100755 => 100644 test/charasbytes.awk
 create mode 100644 test/crlf.awk
 create mode 100644 test/crlf.ok
 create mode 100644 test/errno.awk
 copy test/{clsflnam.in => errno.in} (100%)
 create mode 100644 test/errno.ok
 create mode 100644 test/exitval3.awk
 create mode 100644 test/exitval3.ok
 create mode 100644 test/fpat4.awk
 create mode 100644 test/fpat4.ok
 create mode 100644 test/genpot.awk
 create mode 100644 test/genpot.ok
 create mode 100644 test/getfile.awk
 create mode 100644 test/getfile.ok
 create mode 100644 test/indirectbuiltin.awk
 create mode 100644 test/indirectbuiltin.ok
 create mode 100644 test/mpfrmemok1.awk
 create mode 100644 test/mpfrmemok1.ok
 create mode 100644 test/nonfatal1.awk
 create mode 100644 test/nonfatal1.ok
 create mode 100644 test/nonfatal2.awk
 create mode 100644 test/nonfatal2.ok
 create mode 100644 test/nonfatal3.awk
 copy test/{arrayprm3.ok => nonfatal3.ok} (100%)
 mode change 100755 => 100644 test/ofs1.awk
 create mode 100644 test/paramasfunc1.awk
 create mode 100644 test/paramasfunc1.ok
 create mode 100644 test/paramasfunc2.awk
 create mode 100644 test/paramasfunc2.ok
 create mode 100644 test/printfbad4.awk
 create mode 100644 test/printfbad4.ok
 create mode 100644 test/profile0.awk
 create mode 100644 test/profile0.in
 create mode 100644 test/profile0.ok
 create mode 100644 test/profile6.awk
 create mode 100644 test/profile6.ok
 create mode 100644 test/profile7.awk
 create mode 100644 test/profile7.ok
 create mode 100644 test/profile8.awk
 create mode 100644 test/profile8.ok
 mode change 100755 => 100644 test/range1.awk
 create mode 100644 test/regexpbrack.awk
 copy test/{arrayprm2.ok => regexpbrack.in} (100%)
 copy test/{arrayprm2.ok => regexpbrack.ok} (100%)
 create mode 100644 test/sortglos.awk
 create mode 100644 test/sortglos.in
 create mode 100644 test/sortglos.ok
 create mode 100644 test/timeout.awk
 create mode 100644 test/timeout.ok


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]