From 3337e4c48dce1f8b0d600b83c6033c4573acff7f Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 14 May 2012 23:56:31 +0000 Subject: initial i386-cygwin from kbrown git-svn-id: svn://tug.org/texlive/trunk@26386 c570f23f-e606-0410-a88d-b1316a301751 --- Master/bin/i386-cygwin/afm2pl.exe | Bin 80910 -> 80910 bytes Master/bin/i386-cygwin/afm2tfm.exe | Bin 87054 -> 86030 bytes Master/bin/i386-cygwin/aleph.exe | Bin 500238 -> 499726 bytes Master/bin/i386-cygwin/bbox.exe | Bin 9230 -> 9230 bytes Master/bin/i386-cygwin/bg5conv.exe | Bin 5646 -> 5646 bytes Master/bin/i386-cygwin/bg5latex | 2 +- Master/bin/i386-cygwin/bg5pdflatex | 2 +- Master/bin/i386-cygwin/bibtex.exe | Bin 152590 -> 153102 bytes Master/bin/i386-cygwin/bibtex8.exe | Bin 180750 -> 180750 bytes Master/bin/i386-cygwin/bibtexu.exe | Bin 16454670 -> 13903886 bytes Master/bin/i386-cygwin/cef5conv.exe | Bin 6670 -> 6670 bytes Master/bin/i386-cygwin/cef5latex | 2 +- Master/bin/i386-cygwin/cef5pdflatex | 2 +- Master/bin/i386-cygwin/cefconv.exe | Bin 6158 -> 6158 bytes Master/bin/i386-cygwin/ceflatex | 2 +- Master/bin/i386-cygwin/cefpdflatex | 2 +- Master/bin/i386-cygwin/cefsconv.exe | Bin 6670 -> 6670 bytes Master/bin/i386-cygwin/cefslatex | 2 +- Master/bin/i386-cygwin/cefspdflatex | 2 +- Master/bin/i386-cygwin/cfftot1.exe | Bin 403470 -> 402958 bytes Master/bin/i386-cygwin/chktex.exe | Bin 51726 -> 51214 bytes Master/bin/i386-cygwin/chkweb | 2 +- Master/bin/i386-cygwin/ctangle.exe | Bin 89614 -> 89102 bytes Master/bin/i386-cygwin/ctie.exe | Bin 69134 -> 70158 bytes Master/bin/i386-cygwin/cweave.exe | Bin 121358 -> 122382 bytes Master/bin/i386-cygwin/detex.exe | Bin 96270 -> 96270 bytes Master/bin/i386-cygwin/devnag.exe | Bin 27150 -> 26126 bytes Master/bin/i386-cygwin/disdvi.exe | Bin 14350 -> 14350 bytes Master/bin/i386-cygwin/dt2dv.exe | Bin 33294 -> 33294 bytes Master/bin/i386-cygwin/dv2dt.exe | Bin 11790 -> 11790 bytes Master/bin/i386-cygwin/dvi2tty.exe | Bin 78862 -> 107022 bytes Master/bin/i386-cygwin/dvibook.exe | Bin 25614 -> 25614 bytes Master/bin/i386-cygwin/dviconcat.exe | Bin 23566 -> 23566 bytes Master/bin/i386-cygwin/dvicopy.exe | Bin 107022 -> 106510 bytes Master/bin/i386-cygwin/dvidvi.exe | Bin 15886 -> 15886 bytes Master/bin/i386-cygwin/dvilj.exe | Bin 101902 -> 102414 bytes Master/bin/i386-cygwin/dvilj2p.exe | Bin 101902 -> 102926 bytes Master/bin/i386-cygwin/dvilj4.exe | Bin 109070 -> 109582 bytes Master/bin/i386-cygwin/dvilj4l.exe | Bin 109070 -> 109582 bytes Master/bin/i386-cygwin/dvipdfmx.exe | Bin 727054 -> 732686 bytes Master/bin/i386-cygwin/dvipng.exe | Bin 976910 -> 976910 bytes Master/bin/i386-cygwin/dvipos.exe | Bin 97294 -> 96782 bytes Master/bin/i386-cygwin/dvips.exe | Bin 231950 -> 229390 bytes Master/bin/i386-cygwin/dviselect.exe | Bin 25102 -> 24590 bytes Master/bin/i386-cygwin/dvisvgm.exe | Bin 1486862 -> 1532942 bytes Master/bin/i386-cygwin/dvitodvi.exe | Bin 29198 -> 28686 bytes Master/bin/i386-cygwin/dvitype.exe | Bin 96270 -> 95758 bytes Master/bin/i386-cygwin/epsffit.exe | Bin 9742 -> 9742 bytes Master/bin/i386-cygwin/eptex.exe | Bin 440334 -> 506894 bytes Master/bin/i386-cygwin/euptex.exe | Bin 511502 -> 512014 bytes Master/bin/i386-cygwin/extconv.exe | Bin 5646 -> 5646 bytes Master/bin/i386-cygwin/gbklatex | 2 +- Master/bin/i386-cygwin/gbkpdflatex | 2 +- Master/bin/i386-cygwin/gftodvi.exe | Bin 97806 -> 97806 bytes Master/bin/i386-cygwin/gftopk.exe | Bin 82446 -> 82446 bytes Master/bin/i386-cygwin/gftype.exe | Bin 82958 -> 83470 bytes Master/bin/i386-cygwin/gsftopk.exe | Bin 78350 -> 78862 bytes Master/bin/i386-cygwin/hbf2gf.exe | Bin 91150 -> 88590 bytes Master/bin/i386-cygwin/kpseaccess.exe | Bin 6158 -> 6158 bytes Master/bin/i386-cygwin/kpsereadlink.exe | Bin 6158 -> 6158 bytes Master/bin/i386-cygwin/kpsestat.exe | Bin 6670 -> 6670 bytes Master/bin/i386-cygwin/kpsewhich.exe | Bin 76302 -> 76814 bytes Master/bin/i386-cygwin/lacheck.exe | Bin 55310 -> 54286 bytes Master/bin/i386-cygwin/luatex.exe | Bin 4893198 -> 5282318 bytes Master/bin/i386-cygwin/m-tx | 1 + Master/bin/i386-cygwin/mag.exe | Bin 6158 -> 6158 bytes Master/bin/i386-cygwin/makeindex.exe | Bin 133646 -> 134158 bytes Master/bin/i386-cygwin/makejvf.exe | Bin 93710 -> 106510 bytes Master/bin/i386-cygwin/mendex.exe | Bin 195598 -> 197646 bytes Master/bin/i386-cygwin/mf-nowin.exe | Bin 306702 -> 299534 bytes Master/bin/i386-cygwin/mf.exe | Bin 310798 -> 303118 bytes Master/bin/i386-cygwin/mft.exe | Bin 105486 -> 105998 bytes Master/bin/i386-cygwin/mmafm.exe | Bin 279566 -> 288270 bytes Master/bin/i386-cygwin/mmpfb.exe | Bin 346126 -> 352270 bytes Master/bin/i386-cygwin/mpost.exe | Bin 491022 -> 485390 bytes Master/bin/i386-cygwin/mtxrun | 5250 +++++++++++------------------ Master/bin/i386-cygwin/odvicopy.exe | Bin 110094 -> 110094 bytes Master/bin/i386-cygwin/odvitype.exe | Bin 97294 -> 97806 bytes Master/bin/i386-cygwin/omfonts.exe | Bin 156174 -> 158222 bytes Master/bin/i386-cygwin/otangle.exe | Bin 94734 -> 95246 bytes Master/bin/i386-cygwin/otfinfo.exe | Bin 480270 -> 485902 bytes Master/bin/i386-cygwin/otftotfm.exe | Bin 844814 -> 847886 bytes Master/bin/i386-cygwin/otp2ocp.exe | Bin 83982 -> 83982 bytes Master/bin/i386-cygwin/outocp.exe | Bin 65550 -> 65550 bytes Master/bin/i386-cygwin/patgen.exe | Bin 36878 -> 36878 bytes Master/bin/i386-cygwin/pbibtex.exe | Bin 179726 -> 182798 bytes Master/bin/i386-cygwin/pdfclose.exe | Bin 9230 -> 8718 bytes Master/bin/i386-cygwin/pdfopen.exe | Bin 12302 -> 12814 bytes Master/bin/i386-cygwin/pdftex.exe | Bin 1431566 -> 1519118 bytes Master/bin/i386-cygwin/pdftosrc.exe | Bin 487438 -> 584718 bytes Master/bin/i386-cygwin/pdvitype.exe | Bin 126990 -> 130062 bytes Master/bin/i386-cygwin/pfb2pfa.exe | Bin 8206 -> 8206 bytes Master/bin/i386-cygwin/pk2bm.exe | Bin 11278 -> 11278 bytes Master/bin/i386-cygwin/pktogf.exe | Bin 79374 -> 79886 bytes Master/bin/i386-cygwin/pktype.exe | Bin 74254 -> 75278 bytes Master/bin/i386-cygwin/pltotf.exe | Bin 55310 -> 55822 bytes Master/bin/i386-cygwin/pmx | 1 + Master/bin/i386-cygwin/pmxab.exe | Bin 0 -> 433678 bytes Master/bin/i386-cygwin/pooltype.exe | Bin 21518 -> 21518 bytes Master/bin/i386-cygwin/ppltotf.exe | Bin 139278 -> 143374 bytes Master/bin/i386-cygwin/prepmx.exe | Bin 0 -> 95246 bytes Master/bin/i386-cygwin/ps2pk.exe | Bin 167438 -> 165902 bytes Master/bin/i386-cygwin/psbook.exe | Bin 12302 -> 11790 bytes Master/bin/i386-cygwin/psnup.exe | Bin 19470 -> 19470 bytes Master/bin/i386-cygwin/psresize.exe | Bin 16910 -> 16910 bytes Master/bin/i386-cygwin/psselect.exe | Bin 13326 -> 12814 bytes Master/bin/i386-cygwin/pstops.exe | Bin 17934 -> 17422 bytes Master/bin/i386-cygwin/ptex.exe | Bin 387086 -> 455182 bytes Master/bin/i386-cygwin/ptftopl.exe | Bin 125454 -> 130062 bytes Master/bin/i386-cygwin/scor2prt.exe | Bin 0 -> 66574 bytes Master/bin/i386-cygwin/sjisconv.exe | Bin 5646 -> 5646 bytes Master/bin/i386-cygwin/sjislatex | 2 +- Master/bin/i386-cygwin/sjispdflatex | 2 +- Master/bin/i386-cygwin/synctex.exe | Bin 123406 -> 122382 bytes Master/bin/i386-cygwin/t1ascii.exe | Bin 28174 -> 27662 bytes Master/bin/i386-cygwin/t1asm.exe | Bin 32782 -> 32270 bytes Master/bin/i386-cygwin/t1binary.exe | Bin 27662 -> 27150 bytes Master/bin/i386-cygwin/t1disasm.exe | Bin 32782 -> 31758 bytes Master/bin/i386-cygwin/t1dotlessj.exe | Bin 331790 -> 338958 bytes Master/bin/i386-cygwin/t1lint.exe | Bin 293902 -> 303118 bytes Master/bin/i386-cygwin/t1mac.exe | Bin 36366 -> 35854 bytes Master/bin/i386-cygwin/t1rawafm.exe | Bin 293390 -> 299022 bytes Master/bin/i386-cygwin/t1reencode.exe | Bin 327182 -> 333326 bytes Master/bin/i386-cygwin/t1testpage.exe | Bin 308750 -> 315918 bytes Master/bin/i386-cygwin/t1unmac.exe | Bin 33806 -> 32782 bytes Master/bin/i386-cygwin/t4ht.exe | Bin 82446 -> 81934 bytes Master/bin/i386-cygwin/tangle.exe | Bin 97294 -> 98318 bytes Master/bin/i386-cygwin/teckit_compile.exe | Bin 1339918 -> 1458702 bytes Master/bin/i386-cygwin/tex.exe | Bin 336910 -> 334350 bytes Master/bin/i386-cygwin/tex4ht.exe | Bin 141326 -> 137230 bytes Master/bin/i386-cygwin/texconfig-dialog | 19 +- Master/bin/i386-cygwin/tftopl.exe | Bin 93710 -> 95246 bytes Master/bin/i386-cygwin/tie.exe | Bin 67086 -> 67598 bytes Master/bin/i386-cygwin/ttf2afm.exe | Bin 86542 -> 86542 bytes Master/bin/i386-cygwin/ttf2pk.exe | Bin 230414 -> 219150 bytes Master/bin/i386-cygwin/ttf2tfm.exe | Bin 249358 -> 238094 bytes Master/bin/i386-cygwin/ttfdump.exe | Bin 54286 -> 87566 bytes Master/bin/i386-cygwin/ttftotype42.exe | Bin 340494 -> 348686 bytes Master/bin/i386-cygwin/upbibtex.exe | Bin 186382 -> 186382 bytes Master/bin/i386-cygwin/updvitype.exe | Bin 131598 -> 131598 bytes Master/bin/i386-cygwin/uppltotf.exe | Bin 144398 -> 144398 bytes Master/bin/i386-cygwin/uptex.exe | Bin 459278 -> 459790 bytes Master/bin/i386-cygwin/uptftopl.exe | Bin 131598 -> 131598 bytes Master/bin/i386-cygwin/vftovp.exe | Bin 104462 -> 107022 bytes Master/bin/i386-cygwin/vlna.exe | Bin 12814 -> 12302 bytes Master/bin/i386-cygwin/vptovf.exe | Bin 68110 -> 69134 bytes Master/bin/i386-cygwin/weave.exe | Bin 116750 -> 116238 bytes Master/bin/i386-cygwin/xdvi-xaw.exe | Bin 822798 -> 820238 bytes Master/bin/i386-cygwin/xdvipdfmx.exe | Bin 1294862 -> 1299470 bytes Master/bin/i386-cygwin/xetex.exe | Bin 18087438 -> 16319502 bytes 150 files changed, 1968 insertions(+), 3329 deletions(-) create mode 120000 Master/bin/i386-cygwin/m-tx create mode 120000 Master/bin/i386-cygwin/pmx create mode 100755 Master/bin/i386-cygwin/pmxab.exe create mode 100755 Master/bin/i386-cygwin/prepmx.exe create mode 100755 Master/bin/i386-cygwin/scor2prt.exe (limited to 'Master') diff --git a/Master/bin/i386-cygwin/afm2pl.exe b/Master/bin/i386-cygwin/afm2pl.exe index 6ebd98c990a..92daa9fef4d 100755 Binary files a/Master/bin/i386-cygwin/afm2pl.exe and b/Master/bin/i386-cygwin/afm2pl.exe differ diff --git a/Master/bin/i386-cygwin/afm2tfm.exe b/Master/bin/i386-cygwin/afm2tfm.exe index 5a558151582..89b7d4979ed 100755 Binary files a/Master/bin/i386-cygwin/afm2tfm.exe and b/Master/bin/i386-cygwin/afm2tfm.exe differ diff --git a/Master/bin/i386-cygwin/aleph.exe b/Master/bin/i386-cygwin/aleph.exe index b4032023f3b..6875b96a6b1 100755 Binary files a/Master/bin/i386-cygwin/aleph.exe and b/Master/bin/i386-cygwin/aleph.exe differ diff --git a/Master/bin/i386-cygwin/bbox.exe b/Master/bin/i386-cygwin/bbox.exe index 00bcf78101c..26f413304e0 100755 Binary files a/Master/bin/i386-cygwin/bbox.exe and b/Master/bin/i386-cygwin/bbox.exe differ diff --git a/Master/bin/i386-cygwin/bg5conv.exe b/Master/bin/i386-cygwin/bg5conv.exe index 5f7b5400d4d..244d43e79c5 100755 Binary files a/Master/bin/i386-cygwin/bg5conv.exe and b/Master/bin/i386-cygwin/bg5conv.exe differ diff --git a/Master/bin/i386-cygwin/bg5latex b/Master/bin/i386-cygwin/bg5latex index 30195776a87..1839e354680 100755 --- a/Master/bin/i386-cygwin/bg5latex +++ b/Master/bin/i386-cygwin/bg5latex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/bg5pdflatex b/Master/bin/i386-cygwin/bg5pdflatex index ae165527569..685c3c2228b 100755 --- a/Master/bin/i386-cygwin/bg5pdflatex +++ b/Master/bin/i386-cygwin/bg5pdflatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/bibtex.exe b/Master/bin/i386-cygwin/bibtex.exe index e13ca6ade8e..67b58a0f805 100755 Binary files a/Master/bin/i386-cygwin/bibtex.exe and b/Master/bin/i386-cygwin/bibtex.exe differ diff --git a/Master/bin/i386-cygwin/bibtex8.exe b/Master/bin/i386-cygwin/bibtex8.exe index 662774672c3..2a7977dad67 100755 Binary files a/Master/bin/i386-cygwin/bibtex8.exe and b/Master/bin/i386-cygwin/bibtex8.exe differ diff --git a/Master/bin/i386-cygwin/bibtexu.exe b/Master/bin/i386-cygwin/bibtexu.exe index 39c91a38452..77a89422eb3 100755 Binary files a/Master/bin/i386-cygwin/bibtexu.exe and b/Master/bin/i386-cygwin/bibtexu.exe differ diff --git a/Master/bin/i386-cygwin/cef5conv.exe b/Master/bin/i386-cygwin/cef5conv.exe index c9a7a08ab4c..e3a92498871 100755 Binary files a/Master/bin/i386-cygwin/cef5conv.exe and b/Master/bin/i386-cygwin/cef5conv.exe differ diff --git a/Master/bin/i386-cygwin/cef5latex b/Master/bin/i386-cygwin/cef5latex index 5e609181030..e729c27d4c7 100755 --- a/Master/bin/i386-cygwin/cef5latex +++ b/Master/bin/i386-cygwin/cef5latex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/cef5pdflatex b/Master/bin/i386-cygwin/cef5pdflatex index cd1118cd7c3..7ff040cbfaa 100755 --- a/Master/bin/i386-cygwin/cef5pdflatex +++ b/Master/bin/i386-cygwin/cef5pdflatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/cefconv.exe b/Master/bin/i386-cygwin/cefconv.exe index bcf9c9269fd..8399149c255 100755 Binary files a/Master/bin/i386-cygwin/cefconv.exe and b/Master/bin/i386-cygwin/cefconv.exe differ diff --git a/Master/bin/i386-cygwin/ceflatex b/Master/bin/i386-cygwin/ceflatex index 1b110c613c6..4c1d5eb3936 100755 --- a/Master/bin/i386-cygwin/ceflatex +++ b/Master/bin/i386-cygwin/ceflatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/cefpdflatex b/Master/bin/i386-cygwin/cefpdflatex index 706114a8c77..db653b6f65a 100755 --- a/Master/bin/i386-cygwin/cefpdflatex +++ b/Master/bin/i386-cygwin/cefpdflatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/cefsconv.exe b/Master/bin/i386-cygwin/cefsconv.exe index 16a2469b422..ded90b90e45 100755 Binary files a/Master/bin/i386-cygwin/cefsconv.exe and b/Master/bin/i386-cygwin/cefsconv.exe differ diff --git a/Master/bin/i386-cygwin/cefslatex b/Master/bin/i386-cygwin/cefslatex index db2232d98c6..a7054b3c207 100755 --- a/Master/bin/i386-cygwin/cefslatex +++ b/Master/bin/i386-cygwin/cefslatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/cefspdflatex b/Master/bin/i386-cygwin/cefspdflatex index bc99498f4af..d4cc95bff89 100755 --- a/Master/bin/i386-cygwin/cefspdflatex +++ b/Master/bin/i386-cygwin/cefspdflatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/cfftot1.exe b/Master/bin/i386-cygwin/cfftot1.exe index 001538f42f4..1b77ee84760 100755 Binary files a/Master/bin/i386-cygwin/cfftot1.exe and b/Master/bin/i386-cygwin/cfftot1.exe differ diff --git a/Master/bin/i386-cygwin/chktex.exe b/Master/bin/i386-cygwin/chktex.exe index 753ed384e17..4027407a534 100755 Binary files a/Master/bin/i386-cygwin/chktex.exe and b/Master/bin/i386-cygwin/chktex.exe differ diff --git a/Master/bin/i386-cygwin/chkweb b/Master/bin/i386-cygwin/chkweb index cbc0caa780d..8d6361d1097 100755 --- a/Master/bin/i386-cygwin/chkweb +++ b/Master/bin/i386-cygwin/chkweb @@ -15,7 +15,7 @@ # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # Contact the author at: # Jens Berger diff --git a/Master/bin/i386-cygwin/ctangle.exe b/Master/bin/i386-cygwin/ctangle.exe index f099a88884c..bcc70e119d6 100755 Binary files a/Master/bin/i386-cygwin/ctangle.exe and b/Master/bin/i386-cygwin/ctangle.exe differ diff --git a/Master/bin/i386-cygwin/ctie.exe b/Master/bin/i386-cygwin/ctie.exe index af166c5412d..1264eb3be2c 100755 Binary files a/Master/bin/i386-cygwin/ctie.exe and b/Master/bin/i386-cygwin/ctie.exe differ diff --git a/Master/bin/i386-cygwin/cweave.exe b/Master/bin/i386-cygwin/cweave.exe index 7f66faaadfd..332438f6848 100755 Binary files a/Master/bin/i386-cygwin/cweave.exe and b/Master/bin/i386-cygwin/cweave.exe differ diff --git a/Master/bin/i386-cygwin/detex.exe b/Master/bin/i386-cygwin/detex.exe index ef35a615582..08596c8138f 100755 Binary files a/Master/bin/i386-cygwin/detex.exe and b/Master/bin/i386-cygwin/detex.exe differ diff --git a/Master/bin/i386-cygwin/devnag.exe b/Master/bin/i386-cygwin/devnag.exe index 8d5debb897f..1cc4903df15 100755 Binary files a/Master/bin/i386-cygwin/devnag.exe and b/Master/bin/i386-cygwin/devnag.exe differ diff --git a/Master/bin/i386-cygwin/disdvi.exe b/Master/bin/i386-cygwin/disdvi.exe index f93cbcc5581..0c30a20da61 100755 Binary files a/Master/bin/i386-cygwin/disdvi.exe and b/Master/bin/i386-cygwin/disdvi.exe differ diff --git a/Master/bin/i386-cygwin/dt2dv.exe b/Master/bin/i386-cygwin/dt2dv.exe index f9474437957..1f885b62cd1 100755 Binary files a/Master/bin/i386-cygwin/dt2dv.exe and b/Master/bin/i386-cygwin/dt2dv.exe differ diff --git a/Master/bin/i386-cygwin/dv2dt.exe b/Master/bin/i386-cygwin/dv2dt.exe index ec825a6b2c6..93529d8c22c 100755 Binary files a/Master/bin/i386-cygwin/dv2dt.exe and b/Master/bin/i386-cygwin/dv2dt.exe differ diff --git a/Master/bin/i386-cygwin/dvi2tty.exe b/Master/bin/i386-cygwin/dvi2tty.exe index 7e40d40acf5..fb839a344aa 100755 Binary files a/Master/bin/i386-cygwin/dvi2tty.exe and b/Master/bin/i386-cygwin/dvi2tty.exe differ diff --git a/Master/bin/i386-cygwin/dvibook.exe b/Master/bin/i386-cygwin/dvibook.exe index d23357503b8..6b47205148c 100755 Binary files a/Master/bin/i386-cygwin/dvibook.exe and b/Master/bin/i386-cygwin/dvibook.exe differ diff --git a/Master/bin/i386-cygwin/dviconcat.exe b/Master/bin/i386-cygwin/dviconcat.exe index 47ece04a837..2b331b351d1 100755 Binary files a/Master/bin/i386-cygwin/dviconcat.exe and b/Master/bin/i386-cygwin/dviconcat.exe differ diff --git a/Master/bin/i386-cygwin/dvicopy.exe b/Master/bin/i386-cygwin/dvicopy.exe index fd4e7d25ab8..dfea612b7c2 100755 Binary files a/Master/bin/i386-cygwin/dvicopy.exe and b/Master/bin/i386-cygwin/dvicopy.exe differ diff --git a/Master/bin/i386-cygwin/dvidvi.exe b/Master/bin/i386-cygwin/dvidvi.exe index 53a47d95773..f9685c3ca92 100755 Binary files a/Master/bin/i386-cygwin/dvidvi.exe and b/Master/bin/i386-cygwin/dvidvi.exe differ diff --git a/Master/bin/i386-cygwin/dvilj.exe b/Master/bin/i386-cygwin/dvilj.exe index 7e6267864e6..2176fbdb805 100755 Binary files a/Master/bin/i386-cygwin/dvilj.exe and b/Master/bin/i386-cygwin/dvilj.exe differ diff --git a/Master/bin/i386-cygwin/dvilj2p.exe b/Master/bin/i386-cygwin/dvilj2p.exe index efc93a214c6..8ce02370c2f 100755 Binary files a/Master/bin/i386-cygwin/dvilj2p.exe and b/Master/bin/i386-cygwin/dvilj2p.exe differ diff --git a/Master/bin/i386-cygwin/dvilj4.exe b/Master/bin/i386-cygwin/dvilj4.exe index 6cebaef8721..91c0c8a3613 100755 Binary files a/Master/bin/i386-cygwin/dvilj4.exe and b/Master/bin/i386-cygwin/dvilj4.exe differ diff --git a/Master/bin/i386-cygwin/dvilj4l.exe b/Master/bin/i386-cygwin/dvilj4l.exe index 153e6803075..fdda404fa16 100755 Binary files a/Master/bin/i386-cygwin/dvilj4l.exe and b/Master/bin/i386-cygwin/dvilj4l.exe differ diff --git a/Master/bin/i386-cygwin/dvipdfmx.exe b/Master/bin/i386-cygwin/dvipdfmx.exe index 9defdad8089..5cd1df90ae2 100755 Binary files a/Master/bin/i386-cygwin/dvipdfmx.exe and b/Master/bin/i386-cygwin/dvipdfmx.exe differ diff --git a/Master/bin/i386-cygwin/dvipng.exe b/Master/bin/i386-cygwin/dvipng.exe index 6a37af71a3e..2a1f5e01b70 100755 Binary files a/Master/bin/i386-cygwin/dvipng.exe and b/Master/bin/i386-cygwin/dvipng.exe differ diff --git a/Master/bin/i386-cygwin/dvipos.exe b/Master/bin/i386-cygwin/dvipos.exe index 9c9a6270cd8..6f34e0b7414 100755 Binary files a/Master/bin/i386-cygwin/dvipos.exe and b/Master/bin/i386-cygwin/dvipos.exe differ diff --git a/Master/bin/i386-cygwin/dvips.exe b/Master/bin/i386-cygwin/dvips.exe index e5d881f9c12..90fe102a6ce 100755 Binary files a/Master/bin/i386-cygwin/dvips.exe and b/Master/bin/i386-cygwin/dvips.exe differ diff --git a/Master/bin/i386-cygwin/dviselect.exe b/Master/bin/i386-cygwin/dviselect.exe index d77b7918db3..a8597fdbd7f 100755 Binary files a/Master/bin/i386-cygwin/dviselect.exe and b/Master/bin/i386-cygwin/dviselect.exe differ diff --git a/Master/bin/i386-cygwin/dvisvgm.exe b/Master/bin/i386-cygwin/dvisvgm.exe index 9f6cef5edcd..4bbd4e30252 100755 Binary files a/Master/bin/i386-cygwin/dvisvgm.exe and b/Master/bin/i386-cygwin/dvisvgm.exe differ diff --git a/Master/bin/i386-cygwin/dvitodvi.exe b/Master/bin/i386-cygwin/dvitodvi.exe index 999b69f43df..06535d5cee6 100755 Binary files a/Master/bin/i386-cygwin/dvitodvi.exe and b/Master/bin/i386-cygwin/dvitodvi.exe differ diff --git a/Master/bin/i386-cygwin/dvitype.exe b/Master/bin/i386-cygwin/dvitype.exe index 53cb57ee56d..03359cf18ec 100755 Binary files a/Master/bin/i386-cygwin/dvitype.exe and b/Master/bin/i386-cygwin/dvitype.exe differ diff --git a/Master/bin/i386-cygwin/epsffit.exe b/Master/bin/i386-cygwin/epsffit.exe index 857af194df4..9c77dc38844 100755 Binary files a/Master/bin/i386-cygwin/epsffit.exe and b/Master/bin/i386-cygwin/epsffit.exe differ diff --git a/Master/bin/i386-cygwin/eptex.exe b/Master/bin/i386-cygwin/eptex.exe index db06ea98502..f3b0d153d72 100755 Binary files a/Master/bin/i386-cygwin/eptex.exe and b/Master/bin/i386-cygwin/eptex.exe differ diff --git a/Master/bin/i386-cygwin/euptex.exe b/Master/bin/i386-cygwin/euptex.exe index 8c99876a508..ad6defa7148 100755 Binary files a/Master/bin/i386-cygwin/euptex.exe and b/Master/bin/i386-cygwin/euptex.exe differ diff --git a/Master/bin/i386-cygwin/extconv.exe b/Master/bin/i386-cygwin/extconv.exe index 8978d116ec1..d98b538b34d 100755 Binary files a/Master/bin/i386-cygwin/extconv.exe and b/Master/bin/i386-cygwin/extconv.exe differ diff --git a/Master/bin/i386-cygwin/gbklatex b/Master/bin/i386-cygwin/gbklatex index 4136537872e..9fa75a712e3 100755 --- a/Master/bin/i386-cygwin/gbklatex +++ b/Master/bin/i386-cygwin/gbklatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/gbkpdflatex b/Master/bin/i386-cygwin/gbkpdflatex index e28761ef423..88bd7232116 100755 --- a/Master/bin/i386-cygwin/gbkpdflatex +++ b/Master/bin/i386-cygwin/gbkpdflatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/gftodvi.exe b/Master/bin/i386-cygwin/gftodvi.exe index 4231d2aab3e..2cfd112ddd2 100755 Binary files a/Master/bin/i386-cygwin/gftodvi.exe and b/Master/bin/i386-cygwin/gftodvi.exe differ diff --git a/Master/bin/i386-cygwin/gftopk.exe b/Master/bin/i386-cygwin/gftopk.exe index af79b38993e..f190dd4f501 100755 Binary files a/Master/bin/i386-cygwin/gftopk.exe and b/Master/bin/i386-cygwin/gftopk.exe differ diff --git a/Master/bin/i386-cygwin/gftype.exe b/Master/bin/i386-cygwin/gftype.exe index 8a5c59c75dd..46a15104760 100755 Binary files a/Master/bin/i386-cygwin/gftype.exe and b/Master/bin/i386-cygwin/gftype.exe differ diff --git a/Master/bin/i386-cygwin/gsftopk.exe b/Master/bin/i386-cygwin/gsftopk.exe index 3fe6f4a3043..9944f6aa5aa 100755 Binary files a/Master/bin/i386-cygwin/gsftopk.exe and b/Master/bin/i386-cygwin/gsftopk.exe differ diff --git a/Master/bin/i386-cygwin/hbf2gf.exe b/Master/bin/i386-cygwin/hbf2gf.exe index 9e07224233e..d4667ebc028 100755 Binary files a/Master/bin/i386-cygwin/hbf2gf.exe and b/Master/bin/i386-cygwin/hbf2gf.exe differ diff --git a/Master/bin/i386-cygwin/kpseaccess.exe b/Master/bin/i386-cygwin/kpseaccess.exe index 9bfde0e7f4c..48fadce26a1 100755 Binary files a/Master/bin/i386-cygwin/kpseaccess.exe and b/Master/bin/i386-cygwin/kpseaccess.exe differ diff --git a/Master/bin/i386-cygwin/kpsereadlink.exe b/Master/bin/i386-cygwin/kpsereadlink.exe index 92cc1650b25..abe013b075a 100755 Binary files a/Master/bin/i386-cygwin/kpsereadlink.exe and b/Master/bin/i386-cygwin/kpsereadlink.exe differ diff --git a/Master/bin/i386-cygwin/kpsestat.exe b/Master/bin/i386-cygwin/kpsestat.exe index 3c7d195b9fa..cab0bbd77f0 100755 Binary files a/Master/bin/i386-cygwin/kpsestat.exe and b/Master/bin/i386-cygwin/kpsestat.exe differ diff --git a/Master/bin/i386-cygwin/kpsewhich.exe b/Master/bin/i386-cygwin/kpsewhich.exe index f809e6583ef..49c59dd635b 100755 Binary files a/Master/bin/i386-cygwin/kpsewhich.exe and b/Master/bin/i386-cygwin/kpsewhich.exe differ diff --git a/Master/bin/i386-cygwin/lacheck.exe b/Master/bin/i386-cygwin/lacheck.exe index 55c0bebc315..f2a7284bebc 100755 Binary files a/Master/bin/i386-cygwin/lacheck.exe and b/Master/bin/i386-cygwin/lacheck.exe differ diff --git a/Master/bin/i386-cygwin/luatex.exe b/Master/bin/i386-cygwin/luatex.exe index c6a20d2dfa2..0d03332735e 100755 Binary files a/Master/bin/i386-cygwin/luatex.exe and b/Master/bin/i386-cygwin/luatex.exe differ diff --git a/Master/bin/i386-cygwin/m-tx b/Master/bin/i386-cygwin/m-tx new file mode 120000 index 00000000000..cb99ed8f557 --- /dev/null +++ b/Master/bin/i386-cygwin/m-tx @@ -0,0 +1 @@ +../../texmf-dist/scripts/m-tx/m-tx.lua \ No newline at end of file diff --git a/Master/bin/i386-cygwin/mag.exe b/Master/bin/i386-cygwin/mag.exe index 2f6d5f5f42e..622dfda43ad 100755 Binary files a/Master/bin/i386-cygwin/mag.exe and b/Master/bin/i386-cygwin/mag.exe differ diff --git a/Master/bin/i386-cygwin/makeindex.exe b/Master/bin/i386-cygwin/makeindex.exe index 513954d8f0e..5e22b882a74 100755 Binary files a/Master/bin/i386-cygwin/makeindex.exe and b/Master/bin/i386-cygwin/makeindex.exe differ diff --git a/Master/bin/i386-cygwin/makejvf.exe b/Master/bin/i386-cygwin/makejvf.exe index 1e681338aa7..bcb346695b5 100755 Binary files a/Master/bin/i386-cygwin/makejvf.exe and b/Master/bin/i386-cygwin/makejvf.exe differ diff --git a/Master/bin/i386-cygwin/mendex.exe b/Master/bin/i386-cygwin/mendex.exe index 523f45c0d64..1b7ed27437c 100755 Binary files a/Master/bin/i386-cygwin/mendex.exe and b/Master/bin/i386-cygwin/mendex.exe differ diff --git a/Master/bin/i386-cygwin/mf-nowin.exe b/Master/bin/i386-cygwin/mf-nowin.exe index ac043f4c069..b5fd57c0e1e 100755 Binary files a/Master/bin/i386-cygwin/mf-nowin.exe and b/Master/bin/i386-cygwin/mf-nowin.exe differ diff --git a/Master/bin/i386-cygwin/mf.exe b/Master/bin/i386-cygwin/mf.exe index 8654682b41a..eb699477c12 100755 Binary files a/Master/bin/i386-cygwin/mf.exe and b/Master/bin/i386-cygwin/mf.exe differ diff --git a/Master/bin/i386-cygwin/mft.exe b/Master/bin/i386-cygwin/mft.exe index 517acfd7b70..4585a7a8adc 100755 Binary files a/Master/bin/i386-cygwin/mft.exe and b/Master/bin/i386-cygwin/mft.exe differ diff --git a/Master/bin/i386-cygwin/mmafm.exe b/Master/bin/i386-cygwin/mmafm.exe index 819ca90d219..2ba6a442a4e 100755 Binary files a/Master/bin/i386-cygwin/mmafm.exe and b/Master/bin/i386-cygwin/mmafm.exe differ diff --git a/Master/bin/i386-cygwin/mmpfb.exe b/Master/bin/i386-cygwin/mmpfb.exe index 2819d30e9ba..a0c39a698d1 100755 Binary files a/Master/bin/i386-cygwin/mmpfb.exe and b/Master/bin/i386-cygwin/mmpfb.exe differ diff --git a/Master/bin/i386-cygwin/mpost.exe b/Master/bin/i386-cygwin/mpost.exe index 81005bde70f..c421d60921f 100755 Binary files a/Master/bin/i386-cygwin/mpost.exe and b/Master/bin/i386-cygwin/mpost.exe differ diff --git a/Master/bin/i386-cygwin/mtxrun b/Master/bin/i386-cygwin/mtxrun index 335c4fcb9e0..7adcd3023a8 100755 --- a/Master/bin/i386-cygwin/mtxrun +++ b/Master/bin/i386-cygwin/mtxrun @@ -160,7 +160,7 @@ end -- of closure do -- create closure to overcome 200 locals limit -if not modules then modules = { } end modules ['l-table'] = { +if not modules then modules = { } end modules ['l-lpeg'] = { version = 1.001, comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -168,1633 +168,1408 @@ if not modules then modules = { } end modules ['l-table'] = { license = "see context related readme files" } -local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string -local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove -local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match -local getmetatable, setmetatable = getmetatable, setmetatable -local getinfo = debug.getinfo +local lpeg = require("lpeg") --- Starting with version 5.2 Lua no longer provide ipairs, which makes --- sense. As we already used the for loop and # in most places the --- impact on ConTeXt was not that large; the remaining ipairs already --- have been replaced. In a similar fashion we also hardly used pairs. --- --- Just in case, we provide the fallbacks as discussed in Programming --- in Lua (http://www.lua.org/pil/7.3.html): +local type = type -if not ipairs then +-- Beware, we predefine a bunch of patterns here and one reason for doing so +-- is that we get consistent behaviour in some of the visualizers. - -- for k, v in ipairs(t) do ... end - -- for k=1,#t do local v = t[k] ... end +lpeg.patterns = lpeg.patterns or { } -- so that we can share +local patterns = lpeg.patterns - local function iterate(a,i) - i = i + 1 - local v = a[i] - if v ~= nil then - return i, v --, nil - end - end +local P, R, S, V, match = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match +local Ct, C, Cs, Cc = lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc +local lpegtype = lpeg.type - function ipairs(a) - return iterate, a, 0 - end +local utfcharacters = string.utfcharacters +local utfgmatch = unicode and unicode.utf8.gmatch -end +local anything = P(1) +local endofstring = P(-1) +local alwaysmatched = P(true) -if not pairs then +patterns.anything = anything +patterns.endofstring = endofstring +patterns.beginofstring = alwaysmatched +patterns.alwaysmatched = alwaysmatched - -- for k, v in pairs(t) do ... end - -- for k, v in next, t do ... end +local digit, sign = R('09'), S('+-') +local cr, lf, crlf = P("\r"), P("\n"), P("\r\n") +local newline = crlf + cr + lf +local escaped = P("\\") * anything +local squote = P("'") +local dquote = P('"') +local space = P(" ") - function pairs(t) - return next, t -- , nil - end +local utfbom_32_be = P('\000\000\254\255') +local utfbom_32_le = P('\255\254\000\000') +local utfbom_16_be = P('\255\254') +local utfbom_16_le = P('\254\255') +local utfbom_8 = P('\239\187\191') +local utfbom = utfbom_32_be + utfbom_32_le + + utfbom_16_be + utfbom_16_le + + utfbom_8 +local utftype = utfbom_32_be / "utf-32-be" + utfbom_32_le / "utf-32-le" + + utfbom_16_be / "utf-16-be" + utfbom_16_le / "utf-16-le" + + utfbom_8 / "utf-8" + alwaysmatched / "unknown" -end +local utf8next = R("\128\191") --- Also, unpack has been moved to the table table, and for compatiility --- reasons we provide both now. +patterns.utf8one = R("\000\127") +patterns.utf8two = R("\194\223") * utf8next +patterns.utf8three = R("\224\239") * utf8next * utf8next +patterns.utf8four = R("\240\244") * utf8next * utf8next * utf8next +patterns.utfbom = utfbom +patterns.utftype = utftype -if not table.unpack then - table.unpack = _G.unpack -elseif not unpack then - _G.unpack = table.unpack -end +local utf8char = patterns.utf8one + patterns.utf8two + patterns.utf8three + patterns.utf8four +local validutf8char = utf8char^0 * endofstring * Cc(true) + Cc(false) --- extra functions, some might go (when not used) +patterns.utf8 = utf8char +patterns.utf8char = utf8char +patterns.validutf8 = validutf8char +patterns.validutf8char = validutf8char -function table.strip(tab) - local lst, l = { }, 0 - for i=1,#tab do - local s = gsub(tab[i],"^%s*(.-)%s*$","%1") - if s == "" then - -- skip this one - else - l = l + 1 - lst[l] = s - end - end - return lst +patterns.digit = digit +patterns.sign = sign +patterns.cardinal = sign^0 * digit^1 +patterns.integer = sign^0 * digit^1 +patterns.float = sign^0 * digit^0 * P('.') * digit^1 +patterns.cfloat = sign^0 * digit^0 * P(',') * digit^1 +patterns.number = patterns.float + patterns.integer +patterns.cnumber = patterns.cfloat + patterns.integer +patterns.oct = P("0") * R("07")^1 +patterns.octal = patterns.oct +patterns.HEX = P("0x") * R("09","AF")^1 +patterns.hex = P("0x") * R("09","af")^1 +patterns.hexadecimal = P("0x") * R("09","AF","af")^1 +patterns.lowercase = R("az") +patterns.uppercase = R("AZ") +patterns.letter = patterns.lowercase + patterns.uppercase +patterns.space = space +patterns.tab = P("\t") +patterns.spaceortab = patterns.space + patterns.tab +patterns.eol = S("\n\r") +patterns.spacer = S(" \t\f\v") -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto) +patterns.newline = newline +patterns.emptyline = newline^1 +patterns.nonspacer = 1 - patterns.spacer +patterns.whitespace = patterns.eol + patterns.spacer +patterns.nonwhitespace = 1 - patterns.whitespace +patterns.equal = P("=") +patterns.comma = P(",") +patterns.commaspacer = P(",") * patterns.spacer^0 +patterns.period = P(".") +patterns.colon = P(":") +patterns.semicolon = P(";") +patterns.underscore = P("_") +patterns.escaped = escaped +patterns.squote = squote +patterns.dquote = dquote +patterns.nosquote = (escaped + (1-squote))^0 +patterns.nodquote = (escaped + (1-dquote))^0 +patterns.unsingle = (squote/"") * patterns.nosquote * (squote/"") +patterns.undouble = (dquote/"") * patterns.nodquote * (dquote/"") +patterns.unquoted = patterns.undouble + patterns.unsingle -- more often undouble +patterns.unspacer = ((patterns.spacer^1)/"")^0 + +patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1 +patterns.beginline = #(1-newline) + +local unquoted = Cs(patterns.unquoted * endofstring) -- not C + +function string.unquoted(str) + return match(unquoted,str) or str end -function table.keys(t) - local keys, k = { }, 0 - for key, _ in next, t do - k = k + 1 - keys[k] = key - end - return keys + +function lpeg.anywhere(pattern) --slightly adapted from website + return P { P(pattern) + 1 * V(1) } -- why so complex? end -local function compare(a,b) - local ta, tb = type(a), type(b) -- needed, else 11 < 2 - if ta == tb then - return a < b - else - return tostring(a) < tostring(b) - end +function lpeg.splitter(pattern, action) + return (((1-P(pattern))^1)/action+1)^0 end -local function sortedkeys(tab) - local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed - for key,_ in next, tab do - s = s + 1 - srt[s] = key - if category == 3 then - -- no further check +local splitters_s, splitters_m = { }, { } + +local function splitat(separator,single) + local splitter = (single and splitters_s[separator]) or splitters_m[separator] + if not splitter then + separator = P(separator) + local other = C((1 - separator)^0) + if single then + local any = anything + splitter = other * (separator * C(any^0) + "") -- ? + splitters_s[separator] = splitter else - local tkey = type(key) - if tkey == "string" then - category = (category == 2 and 3) or 1 - elseif tkey == "number" then - category = (category == 1 and 3) or 2 - else - category = 3 - end + splitter = other * (separator * other)^0 + splitters_m[separator] = splitter end end - if category == 0 or category == 3 then - sort(srt,compare) - else - sort(srt) - end - return srt + return splitter end -local function sortedhashkeys(tab) -- fast one - local srt, s = { }, 0 - for key,_ in next, tab do - if key then - s= s + 1 - srt[s] = key - end - end - sort(srt) - return srt -end +lpeg.splitat = splitat -table.sortedkeys = sortedkeys -table.sortedhashkeys = sortedhashkeys -local function nothing() end +local cache = { } -local function sortedhash(t) - if t then - local n, s = 0, sortedkeys(t) -- the robust one - local function kv(s) - n = n + 1 - local k = s[n] - return k, t[k] - end - return kv, s - else - return nothing +function lpeg.split(separator,str) + local c = cache[separator] + if not c then + c = Ct(splitat(separator)) + cache[separator] = c end + return match(c,str) end -table.sortedhash = sortedhash -table.sortedpairs = sortedhash - -function table.append(t, list) - local n = #t - for i=1,#list do - n = n + 1 - t[n] = list[i] +function string.split(str,separator) + local c = cache[separator] + if not c then + c = Ct(splitat(separator)) + cache[separator] = c end - return t + return match(c,str) end -function table.prepend(t, list) - local nl = #list - local nt = nl + #t - for i=#t,1,-1 do - t[nt] = t[i] - nt = nt - 1 - end - for i=1,#list do - t[i] = list[i] - end - return t +local spacing = patterns.spacer^0 * newline -- sort of strip +local empty = spacing * Cc("") +local nonempty = Cs((1-spacing)^1) * spacing^-1 +local content = (empty + nonempty)^1 + +patterns.textline = content + + +local linesplitter = Ct(splitat(newline)) + +patterns.linesplitter = linesplitter + +function string.splitlines(str) + return match(linesplitter,str) end -function table.merge(t, ...) -- first one is target - t = t or { } - local lst = { ... } - for i=1,#lst do - for k, v in next, lst[i] do - t[k] = v - end - end - return t +local utflinesplitter = utfbom^-1 * Ct(splitat(newline)) + +patterns.utflinesplitter = utflinesplitter + +function string.utfsplitlines(str) + return match(utflinesplitter,str) end -function table.merged(...) - local tmp, lst = { }, { ... } - for i=1,#lst do - for k, v in next, lst[i] do - tmp[k] = v - end + +local cache = { } + +function lpeg.checkedsplit(separator,str) + local c = cache[separator] + if not c then + separator = P(separator) + local other = C((1 - separator)^1) + c = Ct(separator^0 * other * (separator^1 * other)^0) + cache[separator] = c end - return tmp + return match(c,str) end -function table.imerge(t, ...) - local lst, nt = { ... }, #t - for i=1,#lst do - local nst = lst[i] - for j=1,#nst do - nt = nt + 1 - t[nt] = nst[j] - end +function string.checkedsplit(str,separator) + local c = cache[separator] + if not c then + separator = P(separator) + local other = C((1 - separator)^1) + c = Ct(separator^0 * other * (separator^1 * other)^0) + cache[separator] = c end - return t + return match(c,str) end -function table.imerged(...) - local tmp, ntmp, lst = { }, 0, {...} - for i=1,#lst do - local nst = lst[i] - for j=1,#nst do - ntmp = ntmp + 1 - tmp[ntmp] = nst[j] + +local f1 = string.byte + +local function f2(s) local c1, c2 = f1(s,1,2) return c1 * 64 + c2 - 12416 end +local function f3(s) local c1, c2, c3 = f1(s,1,3) return (c1 * 64 + c2) * 64 + c3 - 925824 end +local function f4(s) local c1, c2, c3, c4 = f1(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end + +local utf8byte = patterns.utf8one/f1 + patterns.utf8two/f2 + patterns.utf8three/f3 + patterns.utf8four/f4 + +patterns.utf8byte = utf8byte + + + +local cache = { } + +function lpeg.stripper(str) + if type(str) == "string" then + local s = cache[str] + if not s then + s = Cs(((S(str)^1)/"" + 1)^0) + cache[str] = s end + return s + else + return Cs(((str^1)/"" + 1)^0) end - return tmp end -local function fastcopy(old,metatabletoo) -- fast one - if old then - local new = { } - for k,v in next, old do - if type(v) == "table" then - new[k] = fastcopy(v,metatabletoo) -- was just table.copy - else - new[k] = v - end - end - if metatabletoo then - -- optional second arg - local mt = getmetatable(old) - if mt then - setmetatable(new,mt) - end +local cache = { } + +function lpeg.keeper(str) + if type(str) == "string" then + local s = cache[str] + if not s then + s = Cs((((1-S(str))^1)/"" + 1)^0) + cache[str] = s end - return new + return s else - return { } + return Cs((((1-str)^1)/"" + 1)^0) end end --- todo : copy without metatable +function lpeg.frontstripper(str) -- or pattern (yet undocumented) + return (P(str) + P(true)) * Cs(P(1)^0) +end -local function copy(t, tables) -- taken from lua wiki, slightly adapted - tables = tables or { } - local tcopy = {} - if not tables[t] then - tables[t] = tcopy - end - for i,v in next, t do -- brrr, what happens with sparse indexed - if type(i) == "table" then - if tables[i] then - i = tables[i] - else - i = copy(i, tables) +function lpeg.endstripper(str) -- or pattern (yet undocumented) + return Cs((1 - P(str) * P(-1))^0) +end + +-- Just for fun I looked at the used bytecode and +-- p = (p and p + pp) or pp gets one more (testset). + +function lpeg.replacer(one,two) + if type(one) == "table" then + local no = #one + if no > 0 then + local p + for i=1,no do + local o = one[i] + local pp = P(o[1]) / o[2] + if p then + p = p + pp + else + p = pp + end end + return Cs((p + 1)^0) end - if type(v) ~= "table" then - tcopy[i] = v - elseif tables[v] then - tcopy[i] = tables[v] - else - tcopy[i] = copy(v, tables) - end - end - local mt = getmetatable(t) - if mt then - setmetatable(tcopy,mt) + else + two = two or "" + return Cs((P(one)/two + 1)^0) end - return tcopy end -table.fastcopy = fastcopy -table.copy = copy +local splitters_f, splitters_s = { }, { } -function table.derive(parent) - local child = { } - if parent then - setmetatable(child,{ __index = parent }) +function lpeg.firstofsplit(separator) -- always return value + local splitter = splitters_f[separator] + if not splitter then + separator = P(separator) + splitter = C((1 - separator)^0) + splitters_f[separator] = splitter end - return child + return splitter end -function table.tohash(t,value) - local h = { } - if t then - if value == nil then value = true end - for _, v in next, t do -- no ipairs here - h[v] = value - end +function lpeg.secondofsplit(separator) -- nil if not split + local splitter = splitters_s[separator] + if not splitter then + separator = P(separator) + splitter = (1 - separator)^0 * separator * C(anything^0) + splitters_s[separator] = splitter end - return h + return splitter end -function table.fromhash(t) - local hsh, h = { }, 0 - for k, v in next, t do -- no ipairs here - if v then - h = h + 1 - hsh[h] = k - end - end - return hsh +function lpeg.balancer(left,right) + left, right = P(left), P(right) + return P { left * ((1 - left - right) + V(1))^0 * right } end -local noquotes, hexify, handle, reduce, compact, inline, functions -local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key - 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if', - 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while', -} -local function simple_table(t) - if #t > 0 then - local n = 0 - for _,v in next, t do - n = n + 1 - end - if n == #t then - local tt, nt = { }, 0 - for i=1,#t do - local v = t[i] - local tv = type(v) - if tv == "number" then - nt = nt + 1 - if hexify then - tt[nt] = format("0x%04X",v) - else - tt[nt] = tostring(v) -- tostring not needed - end - elseif tv == "boolean" then - nt = nt + 1 - tt[nt] = tostring(v) - elseif tv == "string" then - nt = nt + 1 - tt[nt] = format("%q",v) - else - tt = nil - break - end - end - return tt - end +local nany = utf8char/"" + +function lpeg.counter(pattern) + pattern = Cs((P(pattern)/" " + nany)^0) + return function(str) + return #match(pattern,str) end - return nil end --- Because this is a core function of mkiv I moved some function calls --- inline. --- --- twice as fast in a test: --- --- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) ) - --- problem: there no good number_to_string converter with the best resolution - -local function dummy() end +if utfgmatch then -local function do_serialize(root,name,depth,level,indexed) - if level > 0 then - depth = depth .. " " - if indexed then - handle(format("%s{",depth)) - else - local tn = type(name) - if tn == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s[0x%04X]={",depth,name)) - else - handle(format("%s[%s]={",depth,name)) - end - elseif tn == "string" then - if noquotes and not reserved[name] and find(name,"^%a[%w%_]*$") then - handle(format("%s%s={",depth,name)) - else - handle(format("%s[%q]={",depth,name)) - end - elseif tn == "boolean" then - handle(format("%s[%s]={",depth,tostring(name))) - else - handle(format("%s{",depth)) + function lpeg.count(str,what) -- replaces string.count + if type(what) == "string" then + local n = 0 + for _ in utfgmatch(str,what) do + n = n + 1 end + return n + else -- 4 times slower but still faster than / function + return #match(Cs((P(what)/" " + nany)^0),str) end end - -- we could check for k (index) being number (cardinal) - if root and next(root) then - local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone) - if compact then - -- NOT: for k=1,#root do (we need to quit at nil) - for k,v in ipairs(root) do -- can we use next? - if not first then first = k end - last = last + 1 + +else + + local cache = { } + + function lpeg.count(str,what) -- replaces string.count + if type(what) == "string" then + local p = cache[what] + if not p then + p = Cs((P(what)/" " + nany)^0) + cache[p] = p end + return #match(p,str) + else -- 4 times slower but still faster than / function + return #match(Cs((P(what)/" " + nany)^0),str) end - local sk = sortedkeys(root) - for i=1,#sk do - local k = sk[i] - local v = root[k] - -- circular - local t, tk = type(v), type(k) - if compact and first and tk == "number" and k >= first and k <= last then - if t == "number" then - if hexify then - handle(format("%s 0x%04X,",depth,v)) - else - handle(format("%s %s,",depth,v)) -- %.99g - end - elseif t == "string" then - if reduce and tonumber(v) then - handle(format("%s %s,",depth,v)) - else - handle(format("%s %q,",depth,v)) - end - elseif t == "table" then - if not next(v) then - handle(format("%s {},",depth)) - elseif inline then -- and #t > 0 - local st = simple_table(v) - if st then - handle(format("%s { %s },",depth,concat(st,", "))) - else - do_serialize(v,k,depth,level+1,true) - end - else - do_serialize(v,k,depth,level+1,true) - end - elseif t == "boolean" then - handle(format("%s %s,",depth,tostring(v))) - elseif t == "function" then - if functions then - handle(format('%s loadstring(%q),',depth,dump(v))) - else - handle(format('%s "function",',depth)) - end - else - handle(format("%s %q,",depth,tostring(v))) - end - elseif k == "__p__" then -- parent - if false then - handle(format("%s __p__=nil,",depth)) - end - elseif t == "number" then - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]=0x%04X,",depth,k,v)) - else - handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g - end - elseif tk == "boolean" then - if hexify then - handle(format("%s [%s]=0x%04X,",depth,tostring(k),v)) - else - handle(format("%s [%s]=%s,",depth,tostring(k),v)) -- %.99g - end - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - if hexify then - handle(format("%s %s=0x%04X,",depth,k,v)) - else - handle(format("%s %s=%s,",depth,k,v)) -- %.99g - end - else - if hexify then - handle(format("%s [%q]=0x%04X,",depth,k,v)) - else - handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g - end - end - elseif t == "string" then - if reduce and tonumber(v) then - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v)) - else - handle(format("%s [%s]=%s,",depth,k,v)) - end - elseif tk == "boolean" then - handle(format("%s [%s]=%s,",depth,tostring(k),v)) - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - handle(format("%s %s=%s,",depth,k,v)) - else - handle(format("%s [%q]=%s,",depth,k,v)) - end - else - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]=%q,",depth,k,v)) - else - handle(format("%s [%s]=%q,",depth,k,v)) - end - elseif tk == "boolean" then - handle(format("%s [%s]=%q,",depth,tostring(k),v)) - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - handle(format("%s %s=%q,",depth,k,v)) - else - handle(format("%s [%q]=%q,",depth,k,v)) - end - end - elseif t == "table" then - if not next(v) then - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]={},",depth,k)) - else - handle(format("%s [%s]={},",depth,k)) - end - elseif tk == "boolean" then - handle(format("%s [%s]={},",depth,tostring(k))) - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - handle(format("%s %s={},",depth,k)) - else - handle(format("%s [%q]={},",depth,k)) - end - elseif inline then - local st = simple_table(v) - if st then - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]={ %s },",depth,k,concat(st,", "))) - else - handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) - end - elseif tk == "boolean" then -- or find(k,"^%d+$") then - handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", "))) - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - handle(format("%s %s={ %s },",depth,k,concat(st,", "))) - else - handle(format("%s [%q]={ %s },",depth,k,concat(st,", "))) - end - else - do_serialize(v,k,depth,level+1) - end - else - do_serialize(v,k,depth,level+1) - end - elseif t == "boolean" then - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,tostring(v))) - else - handle(format("%s [%s]=%s,",depth,k,tostring(v))) - end - elseif tk == "boolean" then -- or find(k,"^%d+$") then - handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v))) - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - handle(format("%s %s=%s,",depth,k,tostring(v))) - else - handle(format("%s [%q]=%s,",depth,k,tostring(v))) - end - elseif t == "function" then - if functions then - local f = getinfo(v).what == "C" and dump(dummy) or dump(v) - -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]=loadstring(%q),",depth,k,f)) - else - handle(format("%s [%s]=loadstring(%q),",depth,k,f)) - end - elseif tk == "boolean" then - handle(format("%s [%s]=loadstring(%q),",depth,tostring(k),f)) - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - handle(format("%s %s=loadstring(%q),",depth,k,f)) - else - handle(format("%s [%q]=loadstring(%q),",depth,k,f)) - end - end - else - if tk == "number" then -- or find(k,"^%d+$") then - if hexify then - handle(format("%s [0x%04X]=%q,",depth,k,tostring(v))) - else - handle(format("%s [%s]=%q,",depth,k,tostring(v))) - end - elseif tk == "boolean" then -- or find(k,"^%d+$") then - handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v))) - elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then - handle(format("%s %s=%q,",depth,k,tostring(v))) - else - handle(format("%s [%q]=%q,",depth,k,tostring(v))) - end - end - end - end - if level > 0 then - handle(format("%s},",depth)) end -end --- replacing handle by a direct t[#t+1] = ... (plus test) is not much --- faster (0.03 on 1.00 for zapfino.tma) +end -local function serialize(_handle,root,name,specification) -- handle wins - local tname = type(name) - if type(specification) == "table" then - noquotes = specification.noquotes - hexify = specification.hexify - handle = _handle or specification.handle or print - reduce = specification.reduce or false - functions = specification.functions - compact = specification.compact - inline = specification.inline and compact - if functions == nil then - functions = true - end - if compact == nil then - compact = true - end - if inline == nil then - inline = compact - end - else - noquotes = false - hexify = false - handle = _handle or print - reduce = false - compact = true - inline = true - functions = true - end - if tname == "string" then - if name == "return" then - handle("return {") - else - handle(name .. "={") - end - elseif tname == "number" then - if hexify then - handle(format("[0x%04X]={",name)) - else - handle("[" .. name .. "]={") - end - elseif tname == "boolean" then - if name then - handle("return {") - else - handle("{") - end - else - handle("t={") - end - if root then - -- The dummy access will initialize a table that has a delayed initialization - -- using a metatable. (maybe explicitly test for metatable) - if getmetatable(root) then -- todo: make this an option, maybe even per subtable - local dummy = root._w_h_a_t_e_v_e_r_ - root._w_h_a_t_e_v_e_r_ = nil - end - -- Let's forget about empty tables. - if next(root) then - do_serialize(root,name,"",0) - end - end - handle("}") -end +local patterns_escapes = { -- also defines in l-string + ["%"] = "%%", + ["."] = "%.", + ["+"] = "%+", ["-"] = "%-", ["*"] = "%*", + ["["] = "%[", ["]"] = "%]", + ["("] = "%)", [")"] = "%)", + -- ["{"] = "%{", ["}"] = "%}" + -- ["^"] = "%^", ["$"] = "%$", +} +local simple_escapes = { -- also defines in l-string + ["-"] = "%-", + ["."] = "%.", + ["?"] = ".", + ["*"] = ".*", +} -function table.serialize(root,name,specification) - local t, n = { }, 0 - local function flush(s) - n = n + 1 - t[n] = s - end - serialize(flush,root,name,specification) - return concat(t,"\n") +local p = Cs((S("-.+*%()[]") / patterns_escapes + anything)^0) +local s = Cs((S("-.+*%()[]") / simple_escapes + anything)^0) + +function string.escapedpattern(str,simple) + return match(simple and s or p,str) end -table.tohandle = serialize +-- utf extensies --- sometimes tables are real use (zapfino extra pro is some 85M) in which --- case a stepwise serialization is nice; actually, we could consider: --- --- for line in table.serializer(root,name,reduce,noquotes) do --- ...(line) --- end --- --- so this is on the todo list +lpeg.UP = lpeg.P -local maxtab = 2*1024 +if utfcharacters then -function table.tofile(filename,root,name,specification) - local f = io.open(filename,'w') - if f then - if maxtab > 1 then - local t, n = { }, 0 - local function flush(s) - n = n + 1 - t[n] = s - if n > maxtab then - f:write(concat(t,"\n"),"\n") -- hm, write(sometable) should be nice - t, n = { }, 0 -- we could recycle t if needed - end - end - serialize(flush,root,name,specification) - f:write(concat(t,"\n"),"\n") - else - local function flush(s) - f:write(s,"\n") + function lpeg.US(str) + local p + for uc in utfcharacters(str) do + if p then + p = p + P(uc) + else + p = P(uc) end - serialize(flush,root,name,specification) end - f:close() - io.flush() + return p end -end -local function flattened(t,f,depth) - if f == nil then - f = { } - depth = 0xFFFF - elseif tonumber(f) then - -- assume then only two arguments are given - depth = f - f = { } - elseif not depth then - depth = 0xFFFF - end - for k, v in next, t do - if type(k) ~= "number" then - if depth > 0 and type(v) == "table" then - flattened(v,f,depth-1) + +elseif utfgmatch then + + function lpeg.US(str) + local p + for uc in utfgmatch(str,".") do + if p then + p = p + P(uc) else - f[k] = v + p = P(uc) end end + return p end - local n = #f - for k=1,#t do - local v = t[k] - if depth > 0 and type(v) == "table" then - flattened(v,f,depth-1) - n = #f - else - n = n + 1 - f[n] = v - end - end - return f -end -table.flattened = flattened +else -local function unnest(t,f) -- only used in mk, for old times sake - if not f then -- and only relevant for token lists - f = { } - end - for i=1,#t do - local v = t[i] - if type(v) == "table" then - if type(v[1]) == "table" then - unnest(v,f) + function lpeg.US(str) + local p + local f = function(uc) + if p then + p = p + P(uc) else - f[#f+1] = v + p = P(uc) end - else - f[#f+1] = v end + match((utf8char/f)^0,str) + return p end - return f -end -function table.unnest(t) -- bad name - return unnest(t) end -local function are_equal(a,b,n,m) -- indexed - if a and b and #a == #b then - n = n or 1 - m = m or #a - for i=n,m do - local ai, bi = a[i], b[i] - if ai==bi then - -- same - elseif type(ai)=="table" and type(bi)=="table" then - if not are_equal(ai,bi) then - return false - end +local range = Cs(utf8byte) * (Cs(utf8byte) + Cc(false)) + +local utfchar = unicode and unicode.utf8 and unicode.utf8.char + +function lpeg.UR(str,more) + local first, last + if type(str) == "number" then + first = str + last = more or first + else + first, last = match(range,str) + if not last then + return P(str) + end + end + if first == last then + return P(str) + elseif utfchar and last - first < 8 then -- a somewhat arbitrary criterium + local p + for i=first,last do + if p then + p = p + P(utfchar(i)) else - return false + p = P(utfchar(i)) end end - return true + return p -- nil when invalid range else - return false - end -end - -local function identical(a,b) -- assumes same structure - for ka, va in next, a do - local vb = b[ka] - if va == vb then - -- same - elseif type(va) == "table" and type(vb) == "table" then - if not identical(va,vb) then - return false - end - else - return false + local f = function(b) + return b >= first and b <= last end + return utf8byte / f -- nil when invalid range end - return true end -table.identical = identical -table.are_equal = are_equal --- maybe also make a combined one -function table.compact(t) - if t then - for k,v in next, t do - if not next(v) then - t[k] = nil - end - end +function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") + if type(list) ~= "table" then + list = { list, ... } + end + -- sort(list) -- longest match first + local p = P(list[1]) + for l=2,#list do + p = p + P(list[l]) end + return p end -function table.contains(t, v) - if t then - for i=1, #t do - if t[i] == v then - return i - end +function lpeg.is_lpeg(p) + return p and lpegtype(p) == "pattern" +end + + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +if not modules then modules = { } end modules ['l-table'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string +local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove +local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match +local getmetatable, setmetatable = getmetatable, setmetatable + +-- Starting with version 5.2 Lua no longer provide ipairs, which makes +-- sense. As we already used the for loop and # in most places the +-- impact on ConTeXt was not that large; the remaining ipairs already +-- have been replaced. In a similar fashio we also hardly used pairs. +-- +-- Just in case, we provide the fallbacks as discussed in Programming +-- in Lua (http://www.lua.org/pil/7.3.html): + +if not ipairs then + + -- for k, v in ipairs(t) do ... end + -- for k=1,#t do local v = t[k] ... end + + local function iterate(a,i) + i = i + 1 + local v = a[i] + if v ~= nil then + return i, v --, nil end end - return false + + function ipairs(a) + return iterate, a, 0 + end + end -function table.count(t) - local n = 0 - for k, v in next, t do - n = n + 1 +if not pairs then + + -- for k, v in pairs(t) do ... end + -- for k, v in next, t do ... end + + function pairs(t) + return next, t -- , nil end - return n + end -function table.swapped(t,s) -- hash - local n = { } - if s then - for k, v in next, s do - n[k] = v +-- Also, unpack has been moved to the table table, and for compatiility +-- reasons we provide both now. + +if not table.unpack then + table.unpack = _G.unpack +elseif not unpack then + _G.unpack = table.unpack +end + +-- extra functions, some might go (when not used) + +function table.strip(tab) + local lst, l = { }, 0 + for i=1,#tab do + local s = gsub(tab[i],"^%s*(.-)%s*$","%1") + if s == "" then + -- skip this one + else + l = l + 1 + lst[l] = s end end - for k, v in next, t do - n[v] = k + return lst +end + +function table.keys(t) + local keys, k = { }, 0 + for key, _ in next, t do + k = k + 1 + keys[k] = key end - return n + return keys end -function table.reversed(t) - if t then - local tt, tn = { }, #t - if tn > 0 then - local ttn = 0 - for i=tn,1,-1 do - ttn = ttn + 1 - tt[ttn] = t[i] - end - end - return tt +local function compare(a,b) + local ta, tb = type(a), type(b) -- needed, else 11 < 2 + if ta == tb then + return a < b + else + return tostring(a) < tostring(b) end end -function table.sequenced(t,sep,simple) -- hash only - local s, n = { }, 0 - for k, v in sortedhash(t) do - if simple then - if v == true then - n = n + 1 - s[n] = k - elseif v and v~= "" then - n = n + 1 - s[n] = k .. "=" .. tostring(v) - end +local function sortedkeys(tab) + local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed + for key,_ in next, tab do + s = s + 1 + srt[s] = key + if category == 3 then + -- no further check else - n = n + 1 - s[n] = k .. "=" .. tostring(v) + local tkey = type(key) + if tkey == "string" then + category = (category == 2 and 3) or 1 + elseif tkey == "number" then + category = (category == 1 and 3) or 2 + else + category = 3 + end end end - return concat(s, sep or " | ") + if category == 0 or category == 3 then + sort(srt,compare) + else + sort(srt) + end + return srt end -function table.print(t,...) - if type(t) ~= "table" then - print(tostring(t)) - else - table.tohandle(print,t,...) +local function sortedhashkeys(tab) -- fast one + local srt, s = { }, 0 + for key,_ in next, tab do + if key then + s= s + 1 + srt[s] = key + end end + sort(srt) + return srt end --- -- -- obsolete but we keep them for a while and might comment them later -- -- -- +table.sortedkeys = sortedkeys +table.sortedhashkeys = sortedhashkeys --- roughly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack) +local function nothing() end -function table.sub(t,i,j) - return { unpack(t,i,j) } +local function sortedhash(t) + if t then + local n, s = 0, sortedkeys(t) -- the robust one + local function kv(s) + n = n + 1 + local k = s[n] + return k, t[k] + end + return kv, s + else + return nothing + end end --- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice) +table.sortedhash = sortedhash +table.sortedpairs = sortedhash -function table.is_empty(t) - return not t or not next(t) +function table.append(t, list) + local n = #t + for i=1,#list do + n = n + 1 + t[n] = list[i] + end + return t end -function table.has_one_entry(t) - return t and not next(t,next(t)) +function table.prepend(t, list) + local nl = #list + local nt = nl + #t + for i=#t,1,-1 do + t[nt] = t[i] + nt = nt - 1 + end + for i=1,#list do + t[i] = list[i] + end + return t end --- new - -function table.loweredkeys(t) -- maybe utf - local l = { } - for k, v in next, t do - l[lower(k)] = v +function table.merge(t, ...) -- first one is target + t = t or { } + local lst = { ... } + for i=1,#lst do + for k, v in next, lst[i] do + t[k] = v + end end - return l + return t end --- new, might move (maybe duplicate) - -function table.unique(old) - local hash = { } - local new = { } - local n = 0 - for i=1,#old do - local oi = old[i] - if not hash[oi] then - n = n + 1 - new[n] = oi - hash[oi] = true +function table.merged(...) + local tmp, lst = { }, { ... } + for i=1,#lst do + for k, v in next, lst[i] do + tmp[k] = v end end - return new + return tmp end --- function table.sorted(t,...) --- table.sort(t,...) --- return t -- still sorts in-place --- end +function table.imerge(t, ...) + local lst, nt = { ... }, #t + for i=1,#lst do + local nst = lst[i] + for j=1,#nst do + nt = nt + 1 + t[nt] = nst[j] + end + end + return t +end - -end -- of closure - -do -- create closure to overcome 200 locals limit - -if not modules then modules = { } end modules ['l-lpeg'] = { - version = 1.001, - comment = "companion to luat-lib.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - - --- a new lpeg fails on a #(1-P(":")) test and really needs a + P(-1) - -local lpeg = require("lpeg") - --- tracing (only used when we encounter a problem in integration of lpeg in luatex) - -local report = texio and texio.write_nl or print - - - - -local type = type -local byte, char, gmatch = string.byte, string.char, string.gmatch - --- Beware, we predefine a bunch of patterns here and one reason for doing so --- is that we get consistent behaviour in some of the visualizers. - -lpeg.patterns = lpeg.patterns or { } -- so that we can share -local patterns = lpeg.patterns - -local P, R, S, V, match = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match -local Ct, C, Cs, Cc = lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc -local lpegtype = lpeg.type - -local utfcharacters = string.utfcharacters -local utfgmatch = unicode and unicode.utf8.gmatch - -local anything = P(1) -local endofstring = P(-1) -local alwaysmatched = P(true) - -patterns.anything = anything -patterns.endofstring = endofstring -patterns.beginofstring = alwaysmatched -patterns.alwaysmatched = alwaysmatched - -local digit, sign = R('09'), S('+-') -local cr, lf, crlf = P("\r"), P("\n"), P("\r\n") -local newline = crlf + S("\r\n") -- cr + lf -local escaped = P("\\") * anything -local squote = P("'") -local dquote = P('"') -local space = P(" ") - -local utfbom_32_be = P('\000\000\254\255') -local utfbom_32_le = P('\255\254\000\000') -local utfbom_16_be = P('\255\254') -local utfbom_16_le = P('\254\255') -local utfbom_8 = P('\239\187\191') -local utfbom = utfbom_32_be + utfbom_32_le - + utfbom_16_be + utfbom_16_le - + utfbom_8 -local utftype = utfbom_32_be / "utf-32-be" + utfbom_32_le / "utf-32-le" - + utfbom_16_be / "utf-16-be" + utfbom_16_le / "utf-16-le" - + utfbom_8 / "utf-8" + alwaysmatched / "unknown" - -local utf8next = R("\128\191") - -patterns.utf8one = R("\000\127") -patterns.utf8two = R("\194\223") * utf8next -patterns.utf8three = R("\224\239") * utf8next * utf8next -patterns.utf8four = R("\240\244") * utf8next * utf8next * utf8next -patterns.utfbom = utfbom -patterns.utftype = utftype - -local utf8char = patterns.utf8one + patterns.utf8two + patterns.utf8three + patterns.utf8four -local validutf8char = utf8char^0 * endofstring * Cc(true) + Cc(false) - -patterns.utf8 = utf8char -patterns.utf8char = utf8char -patterns.validutf8 = validutf8char -patterns.validutf8char = validutf8char - -patterns.digit = digit -patterns.sign = sign -patterns.cardinal = sign^0 * digit^1 -patterns.integer = sign^0 * digit^1 -patterns.float = sign^0 * digit^0 * P('.') * digit^1 -patterns.cfloat = sign^0 * digit^0 * P(',') * digit^1 -patterns.number = patterns.float + patterns.integer -patterns.cnumber = patterns.cfloat + patterns.integer -patterns.oct = P("0") * R("07")^1 -patterns.octal = patterns.oct -patterns.HEX = P("0x") * R("09","AF")^1 -patterns.hex = P("0x") * R("09","af")^1 -patterns.hexadecimal = P("0x") * R("09","AF","af")^1 -patterns.lowercase = R("az") -patterns.uppercase = R("AZ") -patterns.letter = patterns.lowercase + patterns.uppercase -patterns.space = space -patterns.tab = P("\t") -patterns.spaceortab = patterns.space + patterns.tab -patterns.eol = S("\n\r") -patterns.spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto) -patterns.newline = newline -patterns.emptyline = newline^1 -patterns.nonspacer = 1 - patterns.spacer -patterns.whitespace = patterns.eol + patterns.spacer -patterns.nonwhitespace = 1 - patterns.whitespace -patterns.equal = P("=") -patterns.comma = P(",") -patterns.commaspacer = P(",") * patterns.spacer^0 -patterns.period = P(".") -patterns.colon = P(":") -patterns.semicolon = P(";") -patterns.underscore = P("_") -patterns.escaped = escaped -patterns.squote = squote -patterns.dquote = dquote -patterns.nosquote = (escaped + (1-squote))^0 -patterns.nodquote = (escaped + (1-dquote))^0 -patterns.unsingle = (squote/"") * patterns.nosquote * (squote/"") -patterns.undouble = (dquote/"") * patterns.nodquote * (dquote/"") -patterns.unquoted = patterns.undouble + patterns.unsingle -- more often undouble -patterns.unspacer = ((patterns.spacer^1)/"")^0 - -patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1 -patterns.beginline = #(1-newline) - --- print(string.unquoted("test")) --- print(string.unquoted([["t\"est"]])) --- print(string.unquoted([["t\"est"x]])) --- print(string.unquoted("\'test\'")) --- print(string.unquoted('"test"')) --- print(string.unquoted('"test"')) - -function lpeg.anywhere(pattern) --slightly adapted from website - return P { P(pattern) + 1 * V(1) } -- why so complex? -end - -function lpeg.splitter(pattern, action) - return (((1-P(pattern))^1)/action+1)^0 +function table.imerged(...) + local tmp, ntmp, lst = { }, 0, {...} + for i=1,#lst do + local nst = lst[i] + for j=1,#nst do + ntmp = ntmp + 1 + tmp[ntmp] = nst[j] + end + end + return tmp end -function lpeg.tsplitter(pattern, action) - return Ct((((1-P(pattern))^1)/action+1)^0) +local function fastcopy(old,metatabletoo) -- fast one + if old then + local new = { } + for k,v in next, old do + if type(v) == "table" then + new[k] = fastcopy(v,metatabletoo) -- was just table.copy + else + new[k] = v + end + end + if metatabletoo then + -- optional second arg + local mt = getmetatable(old) + if mt then + setmetatable(new,mt) + end + end + return new + else + return { } + end end --- probleem: separator can be lpeg and that does not hash too well, but --- it's quite okay as the key is then not garbage collected - -local splitters_s, splitters_m, splitters_t = { }, { }, { } +-- todo : copy without metatable -local function splitat(separator,single) - local splitter = (single and splitters_s[separator]) or splitters_m[separator] - if not splitter then - separator = P(separator) - local other = C((1 - separator)^0) - if single then - local any = anything - splitter = other * (separator * C(any^0) + "") -- ? - splitters_s[separator] = splitter +local function copy(t, tables) -- taken from lua wiki, slightly adapted + tables = tables or { } + local tcopy = {} + if not tables[t] then + tables[t] = tcopy + end + for i,v in next, t do -- brrr, what happens with sparse indexed + if type(i) == "table" then + if tables[i] then + i = tables[i] + else + i = copy(i, tables) + end + end + if type(v) ~= "table" then + tcopy[i] = v + elseif tables[v] then + tcopy[i] = tables[v] else - splitter = other * (separator * other)^0 - splitters_m[separator] = splitter + tcopy[i] = copy(v, tables) end end - return splitter -end - -local function tsplitat(separator) - local splitter = splitters_t[separator] - if not splitter then - splitter = Ct(splitat(separator)) - splitters_t[separator] = splitter + local mt = getmetatable(t) + if mt then + setmetatable(tcopy,mt) end - return splitter + return tcopy end -lpeg.splitat = splitat -lpeg.tsplitat = tsplitat +table.fastcopy = fastcopy +table.copy = copy -function string.splitup(str,separator) - if not separator then - separator = "," +function table.derive(parent) + local child = { } + if parent then + setmetatable(child,{ __index = parent }) end - return match(splitters_m[separator] or splitat(separator),str) + return child end - -local cache = { } - -function lpeg.split(separator,str) - local c = cache[separator] - if not c then - c = tsplitat(separator) - cache[separator] = c +function table.tohash(t,value) + local h = { } + if t then + if value == nil then value = true end + for _, v in next, t do -- no ipairs here + h[v] = value + end end - return match(c,str) + return h end -function string.split(str,separator) - local c = cache[separator] - if not c then - c = tsplitat(separator) - cache[separator] = c +function table.fromhash(t) + local hsh, h = { }, 0 + for k, v in next, t do -- no ipairs here + if v then + h = h + 1 + hsh[h] = k + end end - return match(c,str) + return hsh end -local spacing = patterns.spacer^0 * newline -- sort of strip -local empty = spacing * Cc("") -local nonempty = Cs((1-spacing)^1) * spacing^-1 -local content = (empty + nonempty)^1 - -patterns.textline = content - - -local linesplitter = tsplitat(newline) +local noquotes, hexify, handle, reduce, compact, inline, functions -patterns.linesplitter = linesplitter +local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key + 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if', + 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while', +} -function string.splitlines(str) - return match(linesplitter,str) -end - -local utflinesplitter = utfbom^-1 * tsplitat(newline) - -patterns.utflinesplitter = utflinesplitter - -function string.utfsplitlines(str) - return match(utflinesplitter,str or "") +local function simple_table(t) + if #t > 0 then + local n = 0 + for _,v in next, t do + n = n + 1 + end + if n == #t then + local tt, nt = { }, 0 + for i=1,#t do + local v = t[i] + local tv = type(v) + if tv == "number" then + nt = nt + 1 + if hexify then + tt[nt] = format("0x%04X",v) + else + tt[nt] = tostring(v) -- tostring not needed + end + elseif tv == "boolean" then + nt = nt + 1 + tt[nt] = tostring(v) + elseif tv == "string" then + nt = nt + 1 + tt[nt] = format("%q",v) + else + tt = nil + break + end + end + return tt + end + end + return nil end +-- Because this is a core function of mkiv I moved some function calls +-- inline. +-- +-- twice as fast in a test: +-- +-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) ) -local cache = { } +-- problem: there no good number_to_string converter with the best resolution -function lpeg.checkedsplit(separator,str) - local c = cache[separator] - if not c then - separator = P(separator) - local other = C((1 - separator)^1) - c = Ct(separator^0 * other * (separator^1 * other)^0) - cache[separator] = c +local function do_serialize(root,name,depth,level,indexed) + if level > 0 then + depth = depth .. " " + if indexed then + handle(format("%s{",depth)) + else + local tn = type(name) + if tn == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s[0x%04X]={",depth,name)) + else + handle(format("%s[%s]={",depth,name)) + end + elseif tn == "string" then + if noquotes and not reserved[name] and find(name,"^%a[%w%_]*$") then + handle(format("%s%s={",depth,name)) + else + handle(format("%s[%q]={",depth,name)) + end + elseif tn == "boolean" then + handle(format("%s[%s]={",depth,tostring(name))) + else + handle(format("%s{",depth)) + end + end end - return match(c,str) -end - -function string.checkedsplit(str,separator) - local c = cache[separator] - if not c then - separator = P(separator) - local other = C((1 - separator)^1) - c = Ct(separator^0 * other * (separator^1 * other)^0) - cache[separator] = c + -- we could check for k (index) being number (cardinal) + if root and next(root) then + local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone) + if compact then + -- NOT: for k=1,#root do (we need to quit at nil) + for k,v in ipairs(root) do -- can we use next? + if not first then first = k end + last = last + 1 + end + end + local sk = sortedkeys(root) + for i=1,#sk do + local k = sk[i] + local v = root[k] + -- circular + local t, tk = type(v), type(k) + if compact and first and tk == "number" and k >= first and k <= last then + if t == "number" then + if hexify then + handle(format("%s 0x%04X,",depth,v)) + else + handle(format("%s %s,",depth,v)) -- %.99g + end + elseif t == "string" then + if reduce and tonumber(v) then + handle(format("%s %s,",depth,v)) + else + handle(format("%s %q,",depth,v)) + end + elseif t == "table" then + if not next(v) then + handle(format("%s {},",depth)) + elseif inline then -- and #t > 0 + local st = simple_table(v) + if st then + handle(format("%s { %s },",depth,concat(st,", "))) + else + do_serialize(v,k,depth,level+1,true) + end + else + do_serialize(v,k,depth,level+1,true) + end + elseif t == "boolean" then + handle(format("%s %s,",depth,tostring(v))) + elseif t == "function" then + if functions then + handle(format('%s loadstring(%q),',depth,dump(v))) + else + handle(format('%s "function",',depth)) + end + else + handle(format("%s %q,",depth,tostring(v))) + end + elseif k == "__p__" then -- parent + if false then + handle(format("%s __p__=nil,",depth)) + end + elseif t == "number" then + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]=0x%04X,",depth,k,v)) + else + handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g + end + elseif tk == "boolean" then + if hexify then + handle(format("%s [%s]=0x%04X,",depth,tostring(k),v)) + else + handle(format("%s [%s]=%s,",depth,tostring(k),v)) -- %.99g + end + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + if hexify then + handle(format("%s %s=0x%04X,",depth,k,v)) + else + handle(format("%s %s=%s,",depth,k,v)) -- %.99g + end + else + if hexify then + handle(format("%s [%q]=0x%04X,",depth,k,v)) + else + handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g + end + end + elseif t == "string" then + if reduce and tonumber(v) then + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]=%s,",depth,k,v)) + else + handle(format("%s [%s]=%s,",depth,k,v)) + end + elseif tk == "boolean" then + handle(format("%s [%s]=%s,",depth,tostring(k),v)) + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + handle(format("%s %s=%s,",depth,k,v)) + else + handle(format("%s [%q]=%s,",depth,k,v)) + end + else + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]=%q,",depth,k,v)) + else + handle(format("%s [%s]=%q,",depth,k,v)) + end + elseif tk == "boolean" then + handle(format("%s [%s]=%q,",depth,tostring(k),v)) + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + handle(format("%s %s=%q,",depth,k,v)) + else + handle(format("%s [%q]=%q,",depth,k,v)) + end + end + elseif t == "table" then + if not next(v) then + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]={},",depth,k)) + else + handle(format("%s [%s]={},",depth,k)) + end + elseif tk == "boolean" then + handle(format("%s [%s]={},",depth,tostring(k))) + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + handle(format("%s %s={},",depth,k)) + else + handle(format("%s [%q]={},",depth,k)) + end + elseif inline then + local st = simple_table(v) + if st then + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]={ %s },",depth,k,concat(st,", "))) + else + handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) + end + elseif tk == "boolean" then -- or find(k,"^%d+$") then + handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", "))) + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + handle(format("%s %s={ %s },",depth,k,concat(st,", "))) + else + handle(format("%s [%q]={ %s },",depth,k,concat(st,", "))) + end + else + do_serialize(v,k,depth,level+1) + end + else + do_serialize(v,k,depth,level+1) + end + elseif t == "boolean" then + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]=%s,",depth,k,tostring(v))) + else + handle(format("%s [%s]=%s,",depth,k,tostring(v))) + end + elseif tk == "boolean" then -- or find(k,"^%d+$") then + handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v))) + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + handle(format("%s %s=%s,",depth,k,tostring(v))) + else + handle(format("%s [%q]=%s,",depth,k,tostring(v))) + end + elseif t == "function" then + if functions then + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]=loadstring(%q),",depth,k,dump(v))) + else + handle(format("%s [%s]=loadstring(%q),",depth,k,dump(v))) + end + elseif tk == "boolean" then + handle(format("%s [%s]=loadstring(%q),",depth,tostring(k),dump(v))) + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + handle(format("%s %s=loadstring(%q),",depth,k,dump(v))) + else + -- handle(format("%s [%q]=loadstring(%q),",depth,k,dump(v))) + handle(format("%s [%q]=loadstring(%q),",depth,k,debug.getinfo(v).what == "C" and "C code" or dump(v))) + end + end + else + if tk == "number" then -- or find(k,"^%d+$") then + if hexify then + handle(format("%s [0x%04X]=%q,",depth,k,tostring(v))) + else + handle(format("%s [%s]=%q,",depth,k,tostring(v))) + end + elseif tk == "boolean" then -- or find(k,"^%d+$") then + handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v))) + elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then + handle(format("%s %s=%q,",depth,k,tostring(v))) + else + handle(format("%s [%q]=%q,",depth,k,tostring(v))) + end + end + end + end + if level > 0 then + handle(format("%s},",depth)) end - return match(c,str) end +-- replacing handle by a direct t[#t+1] = ... (plus test) is not much +-- faster (0.03 on 1.00 for zapfino.tma) -local function f2(s) local c1, c2 = byte(s,1,2) return c1 * 64 + c2 - 12416 end -local function f3(s) local c1, c2, c3 = byte(s,1,3) return (c1 * 64 + c2) * 64 + c3 - 925824 end -local function f4(s) local c1, c2, c3, c4 = byte(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end - -local utf8byte = patterns.utf8one/byte + patterns.utf8two/f2 + patterns.utf8three/f3 + patterns.utf8four/f4 - -patterns.utf8byte = utf8byte - - - -local cache = { } - -function lpeg.stripper(str) - if type(str) == "string" then - local s = cache[str] - if not s then - s = Cs(((S(str)^1)/"" + 1)^0) - cache[str] = s +local function serialize(_handle,root,name,specification) -- handle wins + local tname = type(name) + if type(specification) == "table" then + noquotes = specification.noquotes + hexify = specification.hexify + handle = _handle or specification.handle or print + reduce = specification.reduce or false + functions = specification.functions + compact = specification.compact + inline = specification.inline and compact + if functions == nil then + functions = true + end + if compact == nil then + compact = true + end + if inline == nil then + inline = compact end - return s else - return Cs(((str^1)/"" + 1)^0) + noquotes = false + hexify = false + handle = _handle or print + reduce = false + compact = true + inline = true + functions = true end -end - -local cache = { } - -function lpeg.keeper(str) - if type(str) == "string" then - local s = cache[str] - if not s then - s = Cs((((1-S(str))^1)/"" + 1)^0) - cache[str] = s + if tname == "string" then + if name == "return" then + handle("return {") + else + handle(name .. "={") + end + elseif tname == "number" then + if hexify then + handle(format("[0x%04X]={",name)) + else + handle("[" .. name .. "]={") + end + elseif tname == "boolean" then + if name then + handle("return {") + else + handle("{") end - return s else - return Cs((((1-str)^1)/"" + 1)^0) + handle("t={") end -end - -function lpeg.frontstripper(str) -- or pattern (yet undocumented) - return (P(str) + P(true)) * Cs(P(1)^0) -end - -function lpeg.endstripper(str) -- or pattern (yet undocumented) - return Cs((1 - P(str) * P(-1))^0) -end - --- Just for fun I looked at the used bytecode and --- p = (p and p + pp) or pp gets one more (testset). - -function lpeg.replacer(one,two) - if type(one) == "table" then - local no = #one - if no > 0 then - local p - for i=1,no do - local o = one[i] - local pp = P(o[1]) / o[2] - if p then - p = p + pp - else - p = pp - end - end - return Cs((p + 1)^0) + if root then + -- The dummy access will initialize a table that has a delayed initialization + -- using a metatable. (maybe explicitly test for metatable) + if getmetatable(root) then -- todo: make this an option, maybe even per subtable + local dummy = root._w_h_a_t_e_v_e_r_ + root._w_h_a_t_e_v_e_r_ = nil + end + -- Let's forget about empty tables. + if next(root) then + do_serialize(root,name,"",0) end - else - two = two or "" - return Cs((P(one)/two + 1)^0) end + handle("}") end -local splitters_f, splitters_s = { }, { } - -function lpeg.firstofsplit(separator) -- always return value - local splitter = splitters_f[separator] - if not splitter then - separator = P(separator) - splitter = C((1 - separator)^0) - splitters_f[separator] = splitter - end - return splitter -end -function lpeg.secondofsplit(separator) -- nil if not split - local splitter = splitters_s[separator] - if not splitter then - separator = P(separator) - splitter = (1 - separator)^0 * separator * C(anything^0) - splitters_s[separator] = splitter +function table.serialize(root,name,specification) + local t, n = { }, 0 + local function flush(s) + n = n + 1 + t[n] = s end - return splitter -end - -function lpeg.balancer(left,right) - left, right = P(left), P(right) - return P { left * ((1 - left - right) + V(1))^0 * right } + serialize(flush,root,name,specification) + return concat(t,"\n") end +table.tohandle = serialize +-- sometimes tables are real use (zapfino extra pro is some 85M) in which +-- case a stepwise serialization is nice; actually, we could consider: +-- +-- for line in table.serializer(root,name,reduce,noquotes) do +-- ...(line) +-- end +-- +-- so this is on the todo list -local nany = utf8char/"" - -function lpeg.counter(pattern) - pattern = Cs((P(pattern)/" " + nany)^0) - return function(str) - return #match(pattern,str) - end -end - -if utfgmatch then +local maxtab = 2*1024 - function lpeg.count(str,what) -- replaces string.count - if type(what) == "string" then - local n = 0 - for _ in utfgmatch(str,what) do +function table.tofile(filename,root,name,specification) + local f = io.open(filename,'w') + if f then + if maxtab > 1 then + local t, n = { }, 0 + local function flush(s) n = n + 1 + t[n] = s + if n > maxtab then + f:write(concat(t,"\n"),"\n") -- hm, write(sometable) should be nice + t, n = { }, 0 -- we could recycle t if needed + end end - return n - else -- 4 times slower but still faster than / function - return #match(Cs((P(what)/" " + nany)^0),str) + serialize(flush,root,name,specification) + f:write(concat(t,"\n"),"\n") + else + local function flush(s) + f:write(s,"\n") + end + serialize(flush,root,name,specification) end + f:close() + io.flush() end +end -else - - local cache = { } - - function lpeg.count(str,what) -- replaces string.count - if type(what) == "string" then - local p = cache[what] - if not p then - p = Cs((P(what)/" " + nany)^0) - cache[p] = p +local function flattened(t,f,depth) + if f == nil then + f = { } + depth = 0xFFFF + elseif tonumber(f) then + -- assume then only two arguments are given + depth = f + f = { } + elseif not depth then + depth = 0xFFFF + end + for k, v in next, t do + if type(k) ~= "number" then + if depth > 0 and type(v) == "table" then + flattened(v,f,depth-1) + else + f[k] = v end - return #match(p,str) - else -- 4 times slower but still faster than / function - return #match(Cs((P(what)/" " + nany)^0),str) end end - -end - -local patterns_escapes = { -- also defines in l-string - ["%"] = "%%", - ["."] = "%.", - ["+"] = "%+", ["-"] = "%-", ["*"] = "%*", - ["["] = "%[", ["]"] = "%]", - ["("] = "%)", [")"] = "%)", - -- ["{"] = "%{", ["}"] = "%}" - -- ["^"] = "%^", ["$"] = "%$", -} - -local simple_escapes = { -- also defines in l-string - ["-"] = "%-", - ["."] = "%.", - ["?"] = ".", - ["*"] = ".*", -} - -local p = Cs((S("-.+*%()[]") / patterns_escapes + anything)^0) -local s = Cs((S("-.+*%()[]") / simple_escapes + anything)^0) - -function string.escapedpattern(str,simple) - return match(simple and s or p,str) + local n = #f + for k=1,#t do + local v = t[k] + if depth > 0 and type(v) == "table" then + flattened(v,f,depth-1) + n = #f + else + n = n + 1 + f[n] = v + end + end + return f end --- utf extensies - -lpeg.UP = lpeg.P - -if utfcharacters then +table.flattened = flattened - function lpeg.US(str) - local p - for uc in utfcharacters(str) do - if p then - p = p + P(uc) +local function unnest(t,f) -- only used in mk, for old times sake + if not f then -- and only relevant for token lists + f = { } + end + for i=1,#t do + local v = t[i] + if type(v) == "table" then + if type(v[1]) == "table" then + unnest(v,f) else - p = P(uc) + f[#f+1] = v end + else + f[#f+1] = v end - return p end + return f +end +function table.unnest(t) -- bad name + return unnest(t) +end -elseif utfgmatch then - - function lpeg.US(str) - local p - for uc in utfgmatch(str,".") do - if p then - p = p + P(uc) +local function are_equal(a,b,n,m) -- indexed + if a and b and #a == #b then + n = n or 1 + m = m or #a + for i=n,m do + local ai, bi = a[i], b[i] + if ai==bi then + -- same + elseif type(ai)=="table" and type(bi)=="table" then + if not are_equal(ai,bi) then + return false + end else - p = P(uc) + return false end end - return p + return true + else + return false end +end -else - - function lpeg.US(str) - local p - local f = function(uc) - if p then - p = p + P(uc) - else - p = P(uc) +local function identical(a,b) -- assumes same structure + for ka, va in next, a do + local vb = b[ka] + if va == vb then + -- same + elseif type(va) == "table" and type(vb) == "table" then + if not identical(va,vb) then + return false end + else + return false end - match((utf8char/f)^0,str) - return p end - + return true end -local range = Cs(utf8byte) * (Cs(utf8byte) + Cc(false)) +table.identical = identical +table.are_equal = are_equal -local utfchar = unicode and unicode.utf8 and unicode.utf8.char +-- maybe also make a combined one -function lpeg.UR(str,more) - local first, last - if type(str) == "number" then - first = str - last = more or first - else - first, last = match(range,str) - if not last then - return P(str) +function table.compact(t) + if t then + for k,v in next, t do + if not next(v) then + t[k] = nil + end end end - if first == last then - return P(str) - elseif utfchar and last - first < 8 then -- a somewhat arbitrary criterium - local p - for i=first,last do - if p then - p = p + P(utfchar(i)) - else - p = P(utfchar(i)) +end + +function table.contains(t, v) + if t then + for i=1, #t do + if t[i] == v then + return i end end - return p -- nil when invalid range - else - local f = function(b) - return b >= first and b <= last - end - return utf8byte / f -- nil when invalid range end + return false end - - -function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") - if type(list) ~= "table" then - list = { list, ... } - end - -- sort(list) -- longest match first - local p = P(list[1]) - for l=2,#list do - p = p + P(list[l]) +function table.count(t) + local n = 0 + for k, v in next, t do + n = n + 1 end - return p + return n end -function lpeg.is_lpeg(p) - return p and lpegtype(p) == "pattern" +function table.swapped(t,s) -- hash + local n = { } + if s then + for k, v in next, s do + n[k] = v + end + end + for k, v in next, t do + n[v] = k + end + return n end --- For the moment here, but it might move to utilities. Beware, we need to --- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we --- loop back from the end cq. prepend. - -local sort, fastcopy, sortedkeys = table.sort, table.fastcopy, table.sortedkeys -- dependency! - -function lpeg.append(list,pp,delayed,checked) - local p = pp - if #list > 0 then - local keys = fastcopy(list) - sort(keys) - for i=#keys,1,-1 do - local k = keys[i] - if p then - p = P(k) + p - else - p = P(k) +function table.reversed(t) + if t then + local tt, tn = { }, #t + if tn > 0 then + local ttn = 0 + for i=tn,1,-1 do + ttn = ttn + 1 + tt[ttn] = t[i] end end - elseif delayed then -- hm, it looks like the lpeg parser resolves anyway - local keys = sortedkeys(list) - if p then - for i=1,#keys,1 do - local k = keys[i] - local v = list[k] - p = P(k)/list + p + return tt + end +end + +function table.sequenced(t,sep,simple) -- hash only + local s, n = { }, 0 + for k, v in sortedhash(t) do + if simple then + if v == true then + n = n + 1 + s[n] = k + elseif v and v~= "" then + n = n + 1 + s[n] = k .. "=" .. tostring(v) end else - for i=1,#keys do - local k = keys[i] - local v = list[k] - if p then - p = P(k) + p - else - p = P(k) - end - end - if p then - p = p / list - end - end - elseif checked then - -- problem: substitution gives a capture - local keys = sortedkeys(list) - for i=1,#keys do - local k = keys[i] - local v = list[k] - if p then - if k == v then - p = P(k) + p - else - p = P(k)/v + p - end - else - if k == v then - p = P(k) - else - p = P(k)/v - end - end + n = n + 1 + s[n] = k .. "=" .. tostring(v) end + end + return concat(s, sep or " | ") +end + +function table.print(t,...) + if type(t) ~= "table" then + print(tostring(t)) else - local keys = sortedkeys(list) - for i=1,#keys do - local k = keys[i] - local v = list[k] - if p then - p = P(k)/v + p - else - p = P(k)/v - end - end + table.tohandle(print,t,...) end - return p end --- inspect(lpeg.append({ a = "1", aa = "1", aaa = "1" } ,nil,true)) --- inspect(lpeg.append({ ["degree celsius"] = "1", celsius = "1", degree = "1" } ,nil,true)) - --- function lpeg.exact_match(words,case_insensitive) --- local pattern = concat(words) --- if case_insensitive then --- local pattern = S(upper(characters)) + S(lower(characters)) --- local list = { } --- for i=1,#words do --- list[lower(words[i])] = true --- end --- return Cmt(pattern^1, function(_,i,s) --- return list[lower(s)] and i --- end) --- else --- local pattern = S(concat(words)) --- local list = { } --- for i=1,#words do --- list[words[i]] = true --- end --- return Cmt(pattern^1, function(_,i,s) --- return list[s] and i --- end) --- end --- end +-- -- -- obsolete but we keep them for a while and might comment them later -- -- -- --- experiment: +-- roughly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack) -local function make(t) - local p --- for k, v in next, t do - for k, v in table.sortedhash(t) do - if not p then - if next(v) then - p = P(k) * make(v) - else - p = P(k) - end - else - if next(v) then - p = p + P(k) * make(v) - else - p = p + P(k) - end - end - end - return p +function table.sub(t,i,j) + return { unpack(t,i,j) } end -function lpeg.utfchartabletopattern(list) - local tree = { } - for i=1,#list do - local t = tree - for c in gmatch(list[i],".") do - if not t[c] then - t[c] = { } - end - t = t[c] - end - end - return make(tree) +-- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice) + +function table.is_empty(t) + return not t or not next(t) end --- inspect ( lpeg.utfchartabletopattern { --- utfchar(0x00A0), -- nbsp --- utfchar(0x2000), -- enquad --- utfchar(0x2001), -- emquad --- utfchar(0x2002), -- enspace --- utfchar(0x2003), -- emspace --- utfchar(0x2004), -- threeperemspace --- utfchar(0x2005), -- fourperemspace --- utfchar(0x2006), -- sixperemspace --- utfchar(0x2007), -- figurespace --- utfchar(0x2008), -- punctuationspace --- utfchar(0x2009), -- breakablethinspace --- utfchar(0x200A), -- hairspace --- utfchar(0x200B), -- zerowidthspace --- utfchar(0x202F), -- narrownobreakspace --- utfchar(0x205F), -- math thinspace --- } ) +function table.has_one_entry(t) + return t and not next(t,next(t)) +end end -- of closure @@ -2056,11 +1831,6 @@ function io.readstring(f,n,m) return str end --- - -if not io.i_limiter then function io.i_limiter() end end -- dummy so we can test safely -if not io.o_limiter then function io.o_limiter() end end -- dummy so we can test safely - end -- of closure @@ -2291,7 +2061,7 @@ if not modules then modules = { } end modules ['l-os'] = { -- maybe build io.flush in os.execute local os = os -local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch +local find, format, gsub, upper = string.find, string.format, string.gsub, string.upper local concat = table.concat local random, ceil = math.random, math.ceil local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber @@ -2397,9 +2167,9 @@ os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" os.name = os.name or (os.type == "windows" and "mswin" ) or "linux" if os.type == "windows" then - os.libsuffix, os.binsuffix, os.binsuffixes = 'dll', 'exe', { 'exe', 'cmd', 'bat' } + os.libsuffix, os.binsuffix = 'dll', 'exe' else - os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' } + os.libsuffix, os.binsuffix = 'so', '' end function os.launch(str) @@ -2630,39 +2400,6 @@ function os.timezone(delta) end end -local memory = { } - -local function which(filename) - local fullname = memory[filename] - if fullname == nil then - local suffix = file.suffix(filename) - local suffixes = suffix == "" and os.binsuffixes or { suffix } - for directory in gmatch(os.getenv("PATH"),"[^" .. io.pathseparator .."]+") do - local df = file.join(directory,filename) - for i=1,#suffixes do - local dfs = file.addsuffix(df,suffixes[i]) - if io.exists(dfs) then - fullname = dfs - break - end - end - end - if not fullname then - fullname = false - end - memory[filename] = fullname - end - return fullname -end - -os.which = which -os.where = which - --- print(os.which("inkscape.exe")) --- print(os.which("inkscape")) --- print(os.which("gs.exe")) --- print(os.which("ps2pdf")) - end -- of closure @@ -2762,10 +2499,10 @@ end local trick_1 = char(1) local trick_2 = "^" .. trick_1 .. "/+" -function file.join(...) -- rather dirty +function file.join(...) local lst = { ... } local a, b = lst[1], lst[2] - if not a or a == "" then -- not a added + if a == "" then lst[1] = trick_1 elseif b and find(a,"^/+$") and find(b,"^/") then lst[1] = "" @@ -2786,15 +2523,6 @@ function file.join(...) -- rather dirty end --- We should be able to use: --- --- function file.is_writable(name) --- local a = attributes(name) or attributes(dirname(name,".")) --- return a and sub(a.permissions,2,2) == "w" --- end --- --- But after some testing Taco and I came up with: - function file.is_writable(name) if lfs.isdir(name) then name = name .. "/m_t_x_t_e_s_t.tmp" @@ -2804,17 +2532,12 @@ function file.is_writable(name) os.remove(name) return true end - elseif lfs.isfile(name) then - local f = io.open(name,"ab") - if f then - f:close() - return true - end - else - local f = io.open(name,"ab") + else + local existing = lfs.isfile(name) + f = io.open(name,"ab") if f then f:close() - os.remove(name) + if not existing then os.remove(name) end return true end end @@ -2871,7 +2594,7 @@ function file.collapsepath(str,anchor) if element == '.' then -- do nothing elseif element == '..' then - local n = i - 1 + local n = i -1 while n > 0 do local element = oldelements[n] if element ~= '..' and element ~= '.' then @@ -2967,42 +2690,10 @@ local path = C(((1-slash)^0 * slash)^0) local suffix = period * C(P(1-period)^0 * P(-1)) local base = C((1-suffix)^0) -drive = drive + Cc("") -path = path + Cc("") -base = base + Cc("") -suffix = suffix + Cc("") - -local pattern_a = drive * path * base * suffix -local pattern_b = path * base * suffix -local pattern_c = C(drive * path) * C(base * suffix) - -function file.splitname(str,splitdrive) - if splitdrive then - return lpegmatch(pattern_a,str) -- returns drive, path, base, suffix - else - return lpegmatch(pattern_b,str) -- returns path, base, suffix - end -end +local pattern = (drive + Cc("")) * (path + Cc("")) * (base + Cc("")) * (suffix + Cc("")) -function file.nametotable(str,splitdrive) -- returns table - local path, drive, subpath, name, base, suffix = lpegmatch(pattern_c,str) - if splitdrive then - return { - path = path, - drive = drive, - subpath = subpath, - name = name, - base = base, - suffix = suffix, - } - else - return { - path = path, - name = name, - base = base, - suffix = suffix, - } - end +function file.splitname(str) -- returns drive, path, base, suffix + return lpegmatch(pattern,str) end -- function test(t) for k, v in next, t do print(v, "=>", file.splitname(v)) end end @@ -3137,19 +2828,12 @@ local nothing = Cc("") local escaped = (plus / " ") + (percent * C(hexdigit * hexdigit) / tochar) -- we assume schemes with more than 1 character (in order to avoid problems with windows disks) --- we also assume that when we have a scheme, we also have an authority -local schemestr = Cs((escaped+(1-colon-slash-qmark-hash))^2) -local authoritystr = Cs((escaped+(1- slash-qmark-hash))^0) -local pathstr = Cs((escaped+(1- qmark-hash))^0) -local querystr = Cs((escaped+(1- hash))^0) -local fragmentstr = Cs((escaped+(1- endofstring))^0) - -local scheme = schemestr * colon + nothing -local authority = slash * slash * authoritystr + nothing -local path = slash * pathstr + nothing -local query = qmark * querystr + nothing -local fragment = hash * fragmentstr + nothing +local scheme = Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon * slash * slash + nothing +local authority = Cs((escaped+(1- slash-qmark-hash))^0) + nothing +local path = slash * Cs((escaped+(1- qmark-hash))^0) + nothing +local query = qmark * Cs((escaped+(1- hash))^0) + nothing +local fragment = hash * Cs((escaped+(1- endofstring))^0) + nothing local validurl = scheme * authority * path * query * fragment local parser = Ct(validurl) @@ -3170,14 +2854,11 @@ local function split(str) return (type(str) == "string" and lpegmatch(parser,str)) or str end -local isscheme = schemestr * colon * slash * slash -- this test also assumes authority - local function hasscheme(str) - local scheme = lpegmatch(isscheme,str) -- at least one character - return scheme ~= "" and scheme or false + local scheme = lpegmatch(scheme,str) -- at least one character + return scheme and scheme ~= "" end - -- todo: cache them local rootletter = R("az","AZ") @@ -3326,6 +3007,8 @@ local attributes = lfs.attributes local walkdir = lfs.dir local isdir = lfs.isdir local isfile = lfs.isfile +local mkdir = lfs.mkdir +local chdir = lfs.chdir local currentdir = lfs.currentdir -- handy @@ -3373,13 +3056,13 @@ local function collectpattern(path,patt,recurse,result) local ok, scanner result = result or { } if path == "/" then - ok, scanner, first = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe else - ok, scanner, first = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe end if ok and type(scanner) == "function" then if not find(path,"/$") then path = path .. '/' end - for name in scanner, first do + for name in scanner do local full = path .. name local attr = attributes(full) local mode = attr.mode @@ -3562,7 +3245,7 @@ if onwindows then pth = pth .. "/" .. s end if make_indeed and not isdir(pth) then - lfs.mkdir(pth) + mkdir(pth) end end return pth, (isdir(pth) == true) @@ -3594,7 +3277,7 @@ else pth = pth .. "/" .. s end if make_indeed and not first and not isdir(pth) then - lfs.mkdir(pth) + mkdir(pth) end end else @@ -3602,7 +3285,7 @@ else for s in gmatch(str,"[^/]+") do pth = pth .. "/" .. s if make_indeed and not isdir(pth) then - lfs.mkdir(pth) + mkdir(pth) end end end @@ -3630,10 +3313,10 @@ if onwindows then first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = currentdir() - if lfs.chdir(first) then + if chdir(first) then first = dir.current() end - lfs.chdir(d) + chdir(d) end end if not first then @@ -3698,6 +3381,10 @@ local type, tonumber = type, tonumber boolean = boolean or { } local boolean = boolean +-- function boolean.tonumber(b) +-- return b and 1 or 0 -- test and test and return or return +-- end + function boolean.tonumber(b) if b then return 1 else return 0 end -- test and return or return end @@ -3858,7 +3545,7 @@ local function utf16_to_utf8_be(t) if right then local now = 256*left + right if more > 0 then - now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 more = 0 r = r + 1 result[r] = utfchar(now) @@ -3886,7 +3573,7 @@ local function utf16_to_utf8_le(t) if right then local now = 256*right + left if more > 0 then - now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 more = 0 r = r + 1 result[r] = utfchar(now) @@ -3903,14 +3590,14 @@ local function utf16_to_utf8_le(t) return t end -local function utf32_to_utf8_be(t) +local function utf32_to_utf8_be(str) if type(t) == "string" then - t = utfsplitlines(t) + t = utfsplitlines(str) end local result = { } -- we reuse result for i=1,#t do local r, more = 0, -1 - for a,b in bytepairs(t[i]) do + for a,b in bytepairs(str) do if a and b then if more < 0 then more = 256*256*256*a + 256*256*b @@ -3925,17 +3612,17 @@ local function utf32_to_utf8_be(t) end t[i] = concat(result,"",1,r) end - return t + return result end -local function utf32_to_utf8_le(t) +local function utf32_to_utf8_le(str) if type(t) == "string" then - t = utfsplitlines(t) + t = utfsplitlines(str) end local result = { } -- we reuse result for i=1,#t do local r, more = 0, -1 - for a,b in bytepairs(t[i]) do + for a,b in bytepairs(str) do if a and b then if more < 0 then more = 256*b + a @@ -3950,7 +3637,7 @@ local function utf32_to_utf8_le(t) end t[i] = concat(result,"",1,r) end - return t + return result end unicode.utf32_to_utf8_be = utf32_to_utf8_be @@ -4019,66 +3706,14 @@ end local lpegmatch = lpeg.match -local patterns = lpeg.patterns -local utftype = patterns.utftype +local utftype = lpeg.patterns.utftype function unicode.filetype(data) return data and lpegmatch(utftype,data) or "unknown" end -local toentities = lpeg.Cs ( - ( - patterns.utf8one - + ( - patterns.utf8two - + patterns.utf8three - + patterns.utf8four - ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("&#%X;",b) end end - )^0 -) - -patterns.toentities = toentities - -function utf.toentities(str) - return lpegmatch(toentities,str) -end - - -local P, C, R, Cs = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs - -local one = P(1) -local two = C(1) * C(1) -local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1) - -local pattern = P("\254\255") * Cs( ( - four / function(a,b,c,d) - local ab = 0xFF * byte(a) + byte(b) - local cd = 0xFF * byte(c) + byte(d) - return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000) - end - + two / function(a,b) - return utfchar(byte(a)*256 + byte(b)) - end - + one - )^1 ) - + P("\255\254") * Cs( ( - four / function(b,a,d,c) - local ab = 0xFF * byte(a) + byte(b) - local cd = 0xFF * byte(c) + byte(d) - return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000) - end - + two / function(b,a) - return utfchar(byte(a)*256 + byte(b)) - end - + one - )^1 ) - -function string.toutf(s) - return lpegmatch(pattern,s) or s -- todo: utf32 -end - end -- of closure @@ -4115,8 +3750,8 @@ if not math.sind then end if not math.odd then - function math.odd (n) return n % 2 ~= 0 end - function math.even(n) return n % 2 == 0 end + function math.odd (n) return n % 2 == 0 end + function math.even(n) return n % 2 ~= 0 end end @@ -4136,10 +3771,9 @@ utilities = utilities or {} utilities.tables = utilities.tables or { } local tables = utilities.tables -local format, gmatch, rep = string.format, string.gmatch, string.rep +local format, gmatch = string.format, string.gmatch local concat, insert, remove = table.concat, table.insert, table.remove local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring -local type, next, rawset, tonumber = type, next, rawset, tonumber function tables.definetable(target) -- defines undefined tables local composed, t, n = nil, { }, 0 @@ -4155,31 +3789,14 @@ function tables.definetable(target) -- defines undefined tables return concat(t,"\n") end -function tables.accesstable(target,root) - local t = root or _G +function tables.accesstable(target) + local t = _G for name in gmatch(target,"([^%.]+)") do t = t[name] - if not t then - return - end end return t end -function tables.migratetable(target,v,root) - local t = root or _G - local names = string.split(target,".") - for i=1,#names-1 do - local name = names[i] - t[name] = t[name] or { } - t = t[name] - if not t then - return - end - end - t[names[#names]] = v -end - function tables.removevalue(t,value) -- todo: n if value then for i=1,#t do @@ -4223,19 +3840,13 @@ end -- experimental -local function toxml(t,d,result,step) +local function toxml(t,d,result) for k, v in table.sortedpairs(t) do if type(v) == "table" then - if type(k) == "number" then - result[#result+1] = format("%s",d,k) - toxml(v,d..step,result,step) - result[#result+1] = format("%s",d,k) - else - result[#result+1] = format("%s<%s>",d,k) - toxml(v,d..step,result,step) - result[#result+1] = format("%s",d,k) - end - elseif type(k) == "number" then + result[#result+1] = format("%s<%s>",d,k) + toxml(v,d.." ",result) + result[#result+1] = format("%s",d,k) + elseif tonumber(k) then result[#result+1] = format("%s%s",d,k,v,k) else result[#result+1] = format("%s<%s>%s",d,k,tostring(v),k) @@ -4243,56 +3854,17 @@ local function toxml(t,d,result,step) end end -function table.toxml(t,name,nobanner,indent,spaces) +function table.toxml(t,name,nobanner) local noroot = name == false local result = (nobanner or noroot) and { } or { "" } - local indent = rep(" ",indent or 0) - local spaces = rep(" ",spaces or 1) if noroot then - toxml( t, inndent, result, spaces) + toxml( t, "", result) else - toxml( { [name or "root"] = t }, indent, result, spaces) + toxml( { [name or "root"] = t }, "", result) end return concat(result,"\n") end --- also experimental - --- encapsulate(table,utilities.tables) --- encapsulate(table,utilities.tables,true) --- encapsulate(table,true) - -function tables.encapsulate(core,capsule,protect) - if type(capsule) ~= "table" then - protect = true - capsule = { } - end - for key, value in next, core do - if capsule[key] then - print(format("\ninvalid inheritance '%s' in '%s': %s",key,tostring(core))) - os.exit() - else - capsule[key] = value - end - end - if protect then - for key, value in next, core do - core[key] = nil - end - setmetatable(core, { - __index = capsule, - __newindex = function(t,key,value) - if capsule[key] then - print(format("\ninvalid overload '%s' in '%s'",key,tostring(core))) - os.exit() - else - rawset(t,key,value) - end - end - } ) - end -end - end -- of closure @@ -4314,8 +3886,8 @@ local storage = utilities.storage function storage.mark(t) if not t then - texio.write_nl("fatal error: storage cannot be marked") - return -- os.exit() + texio.write_nl("fatal error: storage '%s' cannot be marked",t) + os.exit() end local m = getmetatable(t) if not m then @@ -4344,8 +3916,8 @@ end function storage.checked(t) if not t then - texio.write_nl("fatal error: storage has not been allocated") - return -- os.exit() + texio.write_nl("fatal error: storage '%s' has not been allocated",t) + os.exit() end return t end @@ -4374,13 +3946,13 @@ end -- table namespace ? -local function f_empty () return "" end -- t,k -local function f_self (t,k) t[k] = k return k end -local function f_ignore() end -- t,k,v +local function f_empty () return "" end -- t,k +local function f_self (t,k) t[k] = k return k end +local function f_ignore() end -- t,k,v -local t_empty = { __index = f_empty } -local t_self = { __index = f_self } -local t_ignore = { __newindex = f_ignore } +local t_empty = { __index = empty } +local t_self = { __index = self } +local t_ignore = { __newindex = ignore } function table.setmetatableindex(t,f) local m = getmetatable(t) @@ -4401,7 +3973,6 @@ function table.setmetatableindex(t,f) setmetatable(t,{ __index = f }) end end - return t end function table.setmetatablenewindex(t,f) @@ -4419,7 +3990,6 @@ function table.setmetatablenewindex(t,f) setmetatable(t,{ __newindex = f }) end end - return t end function table.setmetatablecall(t,f) @@ -4429,7 +3999,6 @@ function table.setmetatablecall(t,f) else setmetatable(t,{ __call = f }) end - return t end function table.setmetatablekey(t,key,value) @@ -4439,7 +4008,6 @@ function table.setmetatablekey(t,key,value) setmetatable(t,m) end m[key] = value - return t end function table.getmetatablekey(t,key,value) @@ -4608,29 +4176,14 @@ utilities = utilities or {} utilities.lua = utilities.lua or { } utilities.report = logs and logs.reporter("system") or print -local function stupidcompile(luafile,lucfile) - local data = io.loaddata(luafile) - if data and data ~= "" then - data = string.dump(data) - if data and data ~= "" then - io.savedata(lucfile,data) - end - end -end - -function utilities.lua.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true +function utilities.lua.compile(luafile,lucfile,cleanup,strip) -- defaults: cleanup=false strip=true utilities.report("lua: compiling %s into %s",luafile,lucfile) os.remove(lucfile) local command = "-o " .. string.quoted(lucfile) .. " " .. string.quoted(luafile) if strip ~= false then command = "-s " .. command end - local done = os.spawn("texluac " .. command) == 0 -- or os.spawn("luac " .. command) == 0 - if not done and fallback then - utilities.report("lua: dumping %s into %s (unstripped)",luafile,lucfile) - stupidcompile(luafile,lucfile) -- maybe use the stripper we have elsewhere - cleanup = false -- better see how worse it is - end + local done = os.spawn("texluac " .. command) == 0 or os.spawn("luac " .. command) == 0 if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then utilities.report("lua: removing %s",luafile) os.remove(luafile) @@ -4657,9 +4210,9 @@ if not modules then modules = { } end modules ['util-prs'] = { license = "see context related readme files" } -local P, R, V, C, Ct, Cs, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg +local P, R, V, C, Ct, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Carg local lpegmatch = lpeg.match -local concat, format, gmatch, find = table.concat, string.format, string.gmatch, string.find +local concat, format, gmatch = table.concat, string.format, string.gmatch local tostring, type, next = tostring, type, next utilities = utilities or {} @@ -4687,12 +4240,8 @@ local rbrace = P("}") local nobrace = 1 - (lbrace+rbrace) local nested = P { lbrace * (nobrace + V(1))^0 * rbrace } local spaces = space^0 -local argument = Cs((lbrace/"") * ((nobrace + nested)^0) * (rbrace/"")) -local content = (1-P(-1))^0 -lpeg.patterns.nested = nested -- no capture -lpeg.patterns.argument = argument -- argument after e.g. = -lpeg.patterns.content = content -- rest after e.g = +lpeg.patterns.nested = nested local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0) @@ -4773,15 +4322,9 @@ parsers.patterns.settings_to_array = pattern -- we could use a weak table as cache -function parsers.settings_to_array(str,strict) +function parsers.settings_to_array(str) if not str or str == "" then return { } - elseif strict then - if find(str,"{") then - return lpegmatch(pattern,str) - else - return { str } - end else return lpegmatch(pattern,str) end @@ -5019,55 +4562,61 @@ local names = { } -- one local function hook() - local f = getinfo(2) -- "nS" + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end if f then - local n = "unknown" - if f.what == "C" then - n = f.name or '' - if not names[n] then - names[n] = format("%42s",n) - end + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end + +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' else -- source short_src linedefined what name namewhat nups func - n = f.name or f.namewhat or f.what - if not n or n == "" then - n = "?" - end - if not names[n] then - names[n] = format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source") - end + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) end - counters[n] = (counters[n] or 0) + 1 + else + return "unknown" end end -function debugger.showstats(printer,threshold) -- hm, something has changed, rubish now +function debugger.showstats(printer,threshold) printer = printer or texio.write or print threshold = threshold or 0 local total, grandtotal, functions = 0, 0, 0 - local dataset = { } - for name, count in next, counters do - dataset[#dataset+1] = { name, count } - end - table.sort(dataset,function(a,b) return a[2] == b[2] and b[1] > a[1] or a[2] > b[2] end) - for i=1,#dataset do - local d = dataset[i] - local name = d[1] - local count = d[2] - if count > threshold and not find(name,"for generator") then -- move up - printer(format("%8i %s\n", count, names[name])) - total = total + count + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in next, counters do + if count > threshold then + local name = getname(func) + if not find(name,"for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end end grandtotal = grandtotal + count functions = functions + 1 end - printer("\n") - printer(format("functions : % 10i\n", functions)) - printer(format("total : % 10i\n", total)) - printer(format("grand total: % 10i\n", grandtotal)) - printer(format("threshold : % 10i\n", threshold)) + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) end +-- two + + +-- rest + function debugger.savestats(filename,threshold) local f = io.open(filename,'w') if f then @@ -5089,7 +4638,6 @@ end local is_node = node and node.is_node -local is_lpeg = lpeg and lpeg.type function inspect(i) -- global function local ti = type(i) @@ -5097,30 +4645,11 @@ function inspect(i) -- global function table.print(i,"table") elseif is_node and is_node(i) then table.print(nodes.astable(i),tostring(i)) - elseif is_lpeg and is_lpeg(i) then - lpeg.print(i) else print(tostring(i)) end end --- from the lua book: - -function traceback() - local level = 1 - while true do - local info = debug.getinfo(level, "Sl") - if not info then - break - elseif info.what == "C" then - print(format("%3i : C function",level)) - else - print(format("%3i : [%s]:%d",level,info.short_src,info.currentline)) - end - level = level + 1 - end -end - end -- of closure @@ -5139,7 +4668,7 @@ if not modules then modules = { } end modules ['trac-inf'] = { -- get warnings about assignments. This is more efficient than using rawset -- and rawget. -local format, lower = string.format, string.lower +local format = string.format local clock = os.gettimeofday or os.clock -- should go in environment local write_nl = texio.write_nl @@ -5241,10 +4770,10 @@ function statistics.show(reporter) -- this code will move local register = statistics.register register("luatex banner", function() - return lower(status.banner) + return string.lower(status.banner) end) register("control sequences", function() - return format("%s of %s + %s", status.cs_count, status.hash_size,status.hash_extra) + return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra) end) register("callbacks", function() local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 @@ -5318,7 +4847,7 @@ end function commands.elapsedtime(name) stoptiming(name or "whatever") - context(elapsedtime(name or "whatever")) + tex.sprint(elapsedtime(name or "whatever")) end @@ -5402,10 +4931,6 @@ local function set(t,what,newvalue) if type(what) ~= "table" then return end - if not done then -- catch ... why not set? - done = { } - t.done = done - end for w, value in next, what do if value == "" then value = newvalue @@ -5642,8 +5167,6 @@ end if texconfig then - -- this happens too late in ini mode but that is no problem - local function set(k,v) v = tonumber(v) if v then @@ -5714,7 +5237,7 @@ local report, subreport, status, settarget, setformats, settranslations local direct, subdirect, writer, pushtarget, poptarget -if tex and (tex.jobname or tex.formatname) then +if tex and tex.jobname or tex.formatname then local valueiskey = { __index = function(t,k) t[k] = k return k end } -- will be helper @@ -5729,10 +5252,6 @@ if tex and (tex.jobname or tex.formatname) then write_nl(target,...) end - newline = function() - write_nl(target,"\n") - end - report = function(a,b,c,...) if c then write_nl(target,format("%-15s > %s\n",translations[a],format(formats[b],c,...))) @@ -5838,10 +5357,6 @@ else writer = write_nl - newline = function() - write_nl("\n") - end - report = function(a,b,c,...) if c then write_nl(format("%-15s | %s",a,format(b,c,...))) @@ -5901,7 +5416,6 @@ logs.settranslations = settranslations logs.direct = direct logs.subdirect = subdirect logs.writer = writer -logs.newline = newline -- installer @@ -6071,58 +5585,21 @@ local real, user, sub function logs.start_page_number() real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno --- real, user, sub = 0, 0, 0 end -local timing = false -local starttime = nil -local lasttime = nil - -trackers.register("pages.timing", function(v) -- only for myself (diagnostics) - starttime = os.clock() - timing = true -end) - -function logs.stop_page_number() -- the first page can includes the initialization so we omit this in average - if timing then - local elapsed, average - local stoptime = os.clock() - if not lasttime or real < 2 then - elapsed = stoptime - average = stoptime - starttime = stoptime - else - elapsed = stoptime - lasttime - average = (stoptime - starttime) / (real - 1) - end - lasttime = stoptime - if real > 0 then - if user > 0 then - if sub > 0 then - report_pages("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) - else - report_pages("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) - end +function logs.stop_page_number() + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) else - report_pages("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) + report_pages("flushing realpage %s, userpage %s",real,user) end else - report_pages("flushing page, time %0.04f / %0.04f",elapsed,average) + report_pages("flushing realpage %s",real) end else - if real > 0 then - if user > 0 then - if sub > 0 then - report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) - else - report_pages("flushing realpage %s, userpage %s",real,user) - end - else - report_pages("flushing realpage %s",real) - end - else - report_pages("flushing page") - end + report_pages("flushing page") end logs.flush() end @@ -6204,13 +5681,6 @@ local function reportbanner(t) end end -local function reportversion(t) - local banner = t.banner - if banner then - t.report(banner) - end -end - local function reporthelp(t,...) local helpinfo = t.helpinfo if type(helpinfo) == "string" then @@ -6237,7 +5707,6 @@ function logs.application(t) t.report = logs.reporter(t.name) t.help = function(...) reportbanner(t) ; reporthelp(t,...) ; reportinfo(t) end t.identify = function() reportbanner(t) end - t.version = function() reportversion(t) end return t end @@ -6303,11 +5772,6 @@ else end end --- do we still need io.flush then? - -io.stdout:setvbuf('no') -io.stderr:setvbuf('no') - end -- of closure @@ -6813,10 +6277,6 @@ if not modules then modules = { } end modules ['lxml-tab'] = { -- stripping spaces from e.g. cont-en.xml saves .2 sec runtime so it's not worth the -- trouble --- todo: when serializing optionally remap named entities to hex (if known in char-ent.lua) --- maybe when letter -> utf, else name .. then we need an option to the serializer .. a bit --- of work so we delay this till we cleanup - local trace_entities = false trackers.register("xml.entities", function(v) trace_entities = v end) local report_xml = logs and logs.reporter("xml","core") or function(...) print(format(...)) end @@ -6841,11 +6301,10 @@ xml = xml or { } local xml = xml -local utf = unicode.utf8 local concat, remove, insert = table.concat, table.remove, table.insert local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub -local utfchar, utffind, utfgsub = utf.char, utf.find, utf.gsub +local utfchar = unicode.utf8.char local lpegmatch = lpeg.match local P, S, R, C, V, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.C, lpeg.Cs @@ -6958,22 +6417,9 @@ element.

local nsremap, resolvens = xml.xmlns, xml.resolvens -local stack = { } -local top = { } -local dt = { } -local at = { } -local xmlns = { } -local errorstr = nil -local entities = { } -local strip = false -local cleanup = false -local utfize = false -local resolve_predefined = false -local unify_predefined = false - -local dcache = { } -local hcache = { } -local acache = { } +local stack, top, dt, at, xmlns, errorstr, entities = { }, { }, { }, { }, { }, nil, { } +local strip, cleanup, utfize, resolve, resolve_predefined, unify_predefined = false, false, false, false, false, false +local dcache, hcache, acache = { }, { }, { } local mt = { } @@ -7139,7 +6585,7 @@ local predefined_unified = { [42] = """, [47] = "'", [74] = "<", - [76] = ">", + [76] = "&gr;", } local predefined_simplified = { @@ -7150,58 +6596,6 @@ local predefined_simplified = { [76] = ">", gt = ">", } -local nofprivates = 0xF0000 -- shared but seldom used - -local privates_u = { -- unescaped - [ [[&]] ] = "&", - [ [["]] ] = """, - [ [[']] ] = "'", - [ [[<]] ] = "<", - [ [[>]] ] = ">", -} - -local privates_p = { -} - -local privates_n = { - -- keeps track of defined ones -} - -local function escaped(s) - if s == "" then - return "" - else -- if utffind(s,privates_u) then - return (utfgsub(s,".",privates_u)) - -- else - -- return s - end -end - -local function unescaped(s) - local p = privates_n[s] - if not p then - nofprivates = nofprivates + 1 - p = utfchar(nofprivates) - privates_n[s] = p - s = "&" .. s .. ";" -- todo: use char-ent to map to hex - privates_u[p] = s - privates_p[p] = s - end - return p -end - -local function unprivatized(s,resolve) - if s == "" then - return "" - else - return (utfgsub(s,".",privates_p)) - end -end - -xml.privatetoken = unescaped -xml.unprivatized = unprivatized -xml.privatecodes = privates_n - local function handle_hex_entity(str) local h = hcache[str] if not h then @@ -7243,7 +6637,7 @@ local function handle_dec_entity(str) if not n then report_xml("utfize, ignoring dec entity &#%s;",str) elseif trace_entities then - report_xml("utfize, converting dec entity &#%s; into %s",str,d) + report_xml("utfize, converting dec entity &#%s; into %s",str,h) end else if trace_entities then @@ -7263,45 +6657,35 @@ local function handle_any_entity(str) local a = acache[str] -- per instance ! todo if not a then a = resolve_predefined and predefined_simplified[str] + if a then + -- one of the predefined + elseif type(resolve) == "function" then + a = resolve(str) or entities[str] + else + a = entities[str] + end if a then if trace_entities then - report_xml("resolved entity &%s; -> %s (predefined)",str,a) + report_xml("resolved entity &%s; -> %s (internal)",str,a) end + a = lpegmatch(parsedentity,a) or a else - if type(resolve) == "function" then - a = resolve(str) or entities[str] - else - a = entities[str] + local unknown_any_entity = placeholders.unknown_any_entity + if unknown_any_entity then + a = unknown_any_entity(str) or "" end if a then - if type(a) == "function" then - if trace_entities then - report_xml("expanding entity &%s; (function)",str) - end - a = a(str) or "" - end - a = lpegmatch(parsedentity,a) or a -- for nested if trace_entities then - report_xml("resolved entity &%s; -> %s (internal)",str,a) + report_xml("resolved entity &%s; -> %s (external)",str,a) end else - local unknown_any_entity = placeholders.unknown_any_entity - if unknown_any_entity then - a = unknown_any_entity(str) or "" + if trace_entities then + report_xml("keeping entity &%s;",str) end - if a then - if trace_entities then - report_xml("resolved entity &%s; -> %s (external)",str,a) - end + if str == "" then + a = "&error;" else - if trace_entities then - report_xml("keeping entity &%s;",str) - end - if str == "" then - a = "&error;" - else - a = "&" .. str .. ";" - end + a = "&" .. str .. ";" end end end @@ -7316,25 +6700,18 @@ local function handle_any_entity(str) else local a = acache[str] if not a then + if trace_entities then + report_xml("found entity &%s;",str) + end a = resolve_predefined and predefined_simplified[str] if a then -- one of the predefined acache[str] = a - if trace_entities then - report_xml("entity &%s; becomes %s",str,tostring(a)) - end elseif str == "" then - if trace_entities then - report_xml("invalid entity &%s;",str) - end a = "&error;" acache[str] = a else - if trace_entities then - report_xml("entity &%s; is made private",str) - end - -- a = "&" .. str .. ";" - a = unescaped(str) + a = "&" .. str .. ";" acache[str] = a end end @@ -7384,7 +6761,7 @@ local value = (squote * Cs((entity + (1 - squote))^0) * squote) + (dq local endofattributes = slash * close + close -- recovery of flacky html local whatever = space * name * optionalspace * equal ------ wrongvalue = C(P(1-whatever-close)^1 + P(1-close)^1) / attribute_value_error +local wrongvalue = C(P(1-whatever-close)^1 + P(1-close)^1) / attribute_value_error ----- wrongvalue = C(P(1-whatever-endofattributes)^1 + P(1-endofattributes)^1) / attribute_value_error ----- wrongvalue = C(P(1-space-endofattributes)^1) / attribute_value_error local wrongvalue = Cs(P(entity + (1-space-endofattributes))^1) / attribute_value_error @@ -7419,8 +6796,6 @@ local function normalentity(k,v ) entities[k] = v end local function systementity(k,v,n) entities[k] = v end local function publicentity(k,v,n) entities[k] = v end --- todo: separate dtd parser - local begindoctype = open * P("!DOCTYPE") local enddoctype = close local beginset = P("[") @@ -7428,22 +6803,17 @@ local endset = P("]") local doctypename = C((1-somespace-close)^0) local elementdoctype = optionalspace * P(" & - cleanup = settings.text_cleanup - entities = settings.entities or { } - -- - if utfize == nil then - settings.utfize_entities = true - utfize = true - end - if resolve_predefined == nil then - settings.resolve_predefined_entities = true - resolve_predefined = true - end - -- - -- - stack, top, at, xmlns, errorstr = { }, { }, { }, { }, nil + unify_predefined = settings.unify_predefined_entities -- & -> & + cleanup = settings.text_cleanup + stack, top, at, xmlns, errorstr, entities = { }, { }, { }, { }, nil, settings.entities or { } acache, hcache, dcache = { }, { }, { } -- not stored reported_attribute_errors = { } if settings.parent_root then @@ -7536,7 +6893,7 @@ local function _xmlconvert_(data, settings) else errorhandler = errorhandler or xml.errorhandler if errorhandler then - xml.errorhandler(format("load error: %s",errorstr)) + xml.errorhandler("load",errorstr) end end else @@ -7550,7 +6907,7 @@ local function _xmlconvert_(data, settings) local v = rdt[k] if type(v) == "table" and not v.special then -- always table -) result.ri = k -- rootindex - v.__p__ = result -- new, experiment, else we cannot go back to settings, we need to test this ! +v.__p__ = result -- new, experiment, else we cannot go back to settings, we need to test this ! break end end @@ -7558,42 +6915,16 @@ local function _xmlconvert_(data, settings) if errorstr and errorstr ~= "" then result.error = true end - result.statistics = { - entities = { - decimals = dcache, - hexadecimals = hcache, - names = acache, - } - } - strip, utfize, resolve, resolve_predefined = nil, nil, nil, nil - unify_predefined, cleanup, entities = nil, nil, nil - stack, top, at, xmlns, errorstr = nil, nil, nil, nil, nil - acache, hcache, dcache = nil, nil, nil - reported_attribute_errors, mt, errorhandler = nil, nil, nil return result end --- Because we can have a crash (stack issues) with faulty xml, we wrap this one --- in a protector: - -function xmlconvert(data,settings) - local ok, result = pcall(function() return _xmlconvert_(data,settings) end) - if ok then - return result - else - return _xmlconvert_("") - end -end - xml.convert = xmlconvert -function xml.inheritedconvert(data,xmldata) -- xmldata is parent +function xml.inheritedconvert(data,xmldata) local settings = xmldata.settings - if settings then - settings.parent_root = xmldata -- to be tested - end + settings.parent_root = xmldata -- to be tested -- settings.no_root = true - local xc = xmlconvert(data,settings) -- hm, we might need to locate settings + local xc = xmlconvert(data,settings) -- xc.settings = nil -- xc.entities = nil -- xc.special = nil @@ -7622,7 +6953,7 @@ function xml.is_valid(root) return root and not root.error end -xml.errorhandler = report_xml +xml.errorhandler = report --[[ldx--

We cannot load an from a filehandle so we need to load @@ -7701,15 +7032,18 @@ alternative.

function xml.checkbom(root) -- can be made faster if root.ri then - local dt = root.dt + local dt, found = root.dt, false for k=1,#dt do local v = dt[k] if type(v) == "table" and v.special and v.tg == "@pi@" and find(v.dt[1],"xml.*version=") then - return + found = true + break end end - insert(dt, 1, { special=true, ns="", tg="@pi@", dt = { "xml version='1.0' standalone='yes'"} } ) - insert(dt, 2, "\n" ) + if not found then + insert(dt, 1, { special=true, ns="", tg="@pi@", dt = { "xml version='1.0' standalone='yes'"} } ) + insert(dt, 2, "\n" ) + end end end @@ -7720,14 +7054,14 @@ and then handle the lot.

-- new experimental reorganized serialize -local function verbose_element(e,handlers) -- options +local function verbose_element(e,handlers) local handle = handlers.handle local serialize = handlers.serialize local ens, etg, eat, edt, ern = e.ns, e.tg, e.at, e.dt, e.rn local ats = eat and next(eat) and { } if ats then for k,v in next, eat do - ats[#ats+1] = format('%s=%q',k,escaped(v)) + ats[#ats+1] = format('%s=%q',k,v) end end if ern and trace_entities and ern ~= ens then @@ -7743,7 +7077,7 @@ local function verbose_element(e,handlers) -- options for i=1,#edt do local e = edt[i] if type(e) == "string" then - handle(escaped(e)) + handle(e) else serialize(e,handlers) end @@ -7764,11 +7098,11 @@ local function verbose_element(e,handlers) -- options handle("<",etg,">") end for i=1,#edt do - local e = edt[i] - if type(e) == "string" then - handle(escaped(e)) -- option: hexify escaped entities + local ei = edt[i] + if type(ei) == "string" then + handle(ei) else - serialize(e,handlers) + serialize(ei,handlers) end end handle("") @@ -7803,7 +7137,7 @@ local function verbose_root(e,handlers) end local function verbose_text(e,handlers) - handlers.handle(escaped(e)) + handlers.handle(e) end local function verbose_document(e,handlers) @@ -7931,33 +7265,20 @@ local result local xmlfilehandler = newhandlers { name = "file", - initialize = function(name) - result = io.open(name,"wb") - return result - end, - finalize = function() - result:close() - return true - end, - handle = function(...) - result:write(...) - end, + initialize = function(name) result = io.open(name,"wb") return result end, + finalize = function() result:close() return true end, + handle = function(...) result:write(...) end, } -- no checking on writeability here but not faster either -- -- local xmlfilehandler = newhandlers { --- initialize = function(name) --- io.output(name,"wb") --- return true --- end, --- finalize = function() --- io.close() --- return true --- end, +-- initialize = function(name) io.output(name,"wb") return true end, +-- finalize = function() io.close() return true end, -- handle = io.write, -- } + function xml.save(root,name) serialize(root,xmlfilehandler,name) end @@ -7966,34 +7287,28 @@ local result local xmlstringhandler = newhandlers { name = "string", - initialize = function() - result = { } - return result - end, - finalize = function() - return concat(result) - end, - handle = function(...) - result[#result+1] = concat { ... } - end, + initialize = function() result = { } return result end, + finalize = function() return concat(result) end, + handle = function(...) result[#result+1] = concat { ... } end } local function xmltostring(root) -- 25% overhead due to collecting - if not root then - return "" - elseif type(root) == 'string' then - return root - else -- if next(root) then -- next is faster than type (and >0 test) - return serialize(root,xmlstringhandler) or "" + if root then + if type(root) == 'string' then + return root + else -- if next(root) then -- next is faster than type (and >0 test) + return serialize(root,xmlstringhandler) or "" + end end + return "" end -local function __tostring(root) -- inline +local function xmltext(root) -- inline return (root and xmltostring(root)) or "" end initialize_mt = function(root) -- redefinition - mt = { __tostring = __tostring, __index = root } + mt = { __tostring = xmltext, __index = root } end xml.defaulthandlers = handlers @@ -8113,7 +7428,7 @@ xml.tocdata(e,"error") --ldx]]-- function xml.tocdata(e,wrapper) - local whatever = type(e) == "table" and xmltostring(e.dt) or e or "" + local whatever = xmltostring(e.dt) if wrapper then whatever = format("<%s>%s",wrapper,whatever,wrapper) end @@ -8305,8 +7620,8 @@ apply_axis['child'] = function(list) c = c + 1 collected[c] = dk dk.ni = k -- refresh - en = en + 1 - dk.ei = en + en = en + 1 + dk.ei = en end end ll.en = en @@ -8334,7 +7649,6 @@ local function collect(list,collected,c) end return c end - apply_axis['descendant'] = function(list) local collected, c = { }, 0 for l=1,#list do @@ -8626,12 +7940,6 @@ local lp_or = P("|") / " or " local lp_and = P("&") / " and " local lp_builtin = P ( - P("text") / "(ll.dt[1] or '')" + -- fragile - P("content") / "ll.dt" + - -- P("name") / "(ll.ns~='' and ll.ns..':'..ll.tg)" + - P("name") / "((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)" + - P("tag") / "ll.tg" + - P("position") / "l" + -- is element in finalizer P("firstindex") / "1" + P("lastindex") / "(#ll.__p__.dt or 1)" + P("firstelement") / "1" + @@ -8639,11 +7947,15 @@ local lp_builtin = P ( P("first") / "1" + P("last") / "#list" + P("rootposition") / "order" + + P("position") / "l" + -- is element in finalizer P("order") / "order" + P("element") / "(ll.ei or 1)" + P("index") / "(ll.ni or 1)" + P("match") / "(ll.mi or 1)" + - -- P("namespace") / "ll.ns" + + P("text") / "(ll.dt[1] or '')" + + -- P("name") / "(ll.ns~='' and ll.ns..':'..ll.tg)" + + P("name") / "((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)" + + P("tag") / "ll.tg" + P("ns") / "ll.ns" ) * ((spaces * P("(") * spaces * P(")"))/"") @@ -8667,11 +7979,11 @@ local lp_function = C(R("az","AZ","__")^1) * P("(") / function(t) -- todo: bett end end -local lparent = P("(") -local rparent = P(")") +local lparent = lpeg.P("(") +local rparent = lpeg.P(")") local noparent = 1 - (lparent+rparent) -local nested = P{lparent * (noparent + V(1))^0 * rparent} -local value = P(lparent * C((noparent + nested)^0) * rparent) -- P{"("*C(((1-S("()"))+V(1))^0)*")"} +local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent} +local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"} local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')") local lp_number = S("+-") * R("09")^1 @@ -8823,10 +8135,7 @@ local special_1 = P("*") * Cc(register_auto_descendant) * Cc(register_all_nodes local special_2 = P("/") * Cc(register_auto_self) local special_3 = P("") * Cc(register_auto_self) -local no_nextcolon = P(-1) + #(1-P(":")) -- newer lpeg needs the P(-1) -local no_nextlparent = P(-1) + #(1-P("(")) -- newer lpeg needs the P(-1) - -local pathparser = Ct { "patterns", -- can be made a bit faster by moving some patterns outside +local pathparser = Ct { "patterns", -- can be made a bit faster by moving pattern outside patterns = spaces * V("protocol") * spaces * ( ( V("special") * spaces * P(-1) ) + @@ -8855,8 +8164,10 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p shortcuts = V("shortcuts_a") * (spaces * "/" * spaces * V("shortcuts_a"))^0, s_descendant_or_self = (P("***/") + P("/")) * Cc(register_descendant_or_self), --- *** is a bonus + -- s_descendant_or_self = P("/") * Cc(register_descendant_or_self), s_descendant = P("**") * Cc(register_descendant), - s_child = P("*") * no_nextcolon * Cc(register_child ), + s_child = P("*") * #(1-P(":")) * Cc(register_child ), +-- s_child = P("*") * #(P("/")+P(-1)) * Cc(register_child ), s_parent = P("..") * Cc(register_parent ), s_self = P("." ) * Cc(register_self ), s_root = P("^^") * Cc(register_root ), @@ -8883,13 +8194,13 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p expressions = expression / register_expression, letters = R("az")^1, - name = (1-S("/[]()|:*!"))^1, -- make inline + name = (1-lpeg.S("/[]()|:*!"))^1, negate = P("!") * Cc(false), nodefunction = V("negate") + P("not") * Cc(false) + Cc(true), nodetest = V("negate") + Cc(true), nodename = (V("negate") + Cc(true)) * spaces * ((V("wildnodename") * P(":") * V("wildnodename")) + (Cc(false) * V("wildnodename"))), - wildnodename = (C(V("name")) + P("*") * Cc(false)) * no_nextlparent, + wildnodename = (C(V("name")) + P("*") * Cc(false)) * #(1-P("(")), nodeset = spaces * Ct(V("nodename") * (spaces * P("|") * spaces * V("nodename"))^0) * spaces, finalizer = (Cb("protocol") * P("/")^-1 * C(V("name")) * arguments * P(-1)) / register_finalizer, @@ -9053,7 +8364,7 @@ local function profiled_apply(list,parsed,nofparsed,order) elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) elseif kind == "finalizer" then - collected = pi.finalizer(collected) -- no check on # here + collected = pi.finalizer(collected) p.matched = p.matched + 1 p.finalized = p.finalized + 1 return collected @@ -9186,9 +8497,9 @@ end expressions.child = function(e,pattern) return applylpath(e,pattern) -- todo: cache end -expressions.count = function(e,pattern) -- what if pattern == empty or nil +expressions.count = function(e,pattern) local collected = applylpath(e,pattern) -- todo: cache - return pattern and (collected and #collected) or 0 + return (collected and #collected) or 0 end -- external @@ -9197,7 +8508,7 @@ expressions.oneof = function(s,...) -- slow local t = {...} for i=1,#t do if s == t[i] then return true end end return false end expressions.error = function(str) - xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?"))) + xml.errorhandler("unknown function in lpath expression",tostring(str or "?")) return false end expressions.undefined = function(s) @@ -9223,23 +8534,6 @@ expressions.lower = lower expressions.number = tonumber expressions.boolean = toboolean -function expressions.contains(str,pattern) - local t = type(str) - if t == "string" then - if find(str,pattern) then - return true - end - elseif t == "table" then - for i=1,#str do - local d = str[i] - if type(d) == "string" and find(d,pattern) then - return true - end - end - end - return false -end - -- user interface local function traverse(root,pattern,handle) @@ -9562,12 +8856,10 @@ local xml = xml local xmlconvert, xmlcopy, xmlname = xml.convert, xml.copy, xml.name local xmlinheritedconvert = xml.inheritedconvert local xmlapplylpath = xml.applylpath -local xmlfilter = xml.filter local type, setmetatable, getmetatable = type, setmetatable, getmetatable -local insert, remove, fastcopy, concat = table.insert, table.remove, table.fastcopy, table.concat -local gmatch, gsub, format = string.gmatch, string.gsub, string.format -local utfbyte = utf.byte +local insert, remove, fastcopy = table.insert, table.remove, table.fastcopy +local gmatch, gsub = string.gmatch, string.gsub local function report(what,pattern,c,e) report_xml("%s element '%s' (root: '%s', position: %s, index: %s, pattern: %s)",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern) @@ -9712,7 +9004,7 @@ local function xmltoelement(whatever,root) end local element if type(whatever) == "string" then - element = xmlinheritedconvert(whatever,root) -- beware, not really a root + element = xmlinheritedconvert(whatever,root) else element = whatever -- we assume a table end @@ -9739,30 +9031,18 @@ local function copiedelement(element,newparent) end function xml.delete(root,pattern) - if not pattern or pattern == "" then - local p = root.__p__ - if p then - if trace_manipulations then - report('deleting',"--",c,root) - end - local d = p.dt - remove(d,root.ni) - redo_ni(d) -- can be made faster and inlined - end - else - local collected = xmlapplylpath(root,pattern) - if collected then - for c=1,#collected do - local e = collected[c] - local p = e.__p__ - if p then - if trace_manipulations then - report('deleting',pattern,c,e) - end - local d = p.dt - remove(d,e.ni) - redo_ni(d) -- can be made faster and inlined + local collected = xmlapplylpath(root,pattern) + if collected then + for c=1,#collected do + local e = collected[c] + local p = e.__p__ + if p then + if trace_manipulations then + report('deleting',pattern,c,e) end + local d = p.dt + remove(d,e.ni) + redo_ni(d) -- can be made faster and inlined end end end @@ -9825,39 +9105,32 @@ end local function inject_element(root,pattern,whatever,prepend) local element = root and xmltoelement(whatever,root) local collected = element and xmlapplylpath(root,pattern) - local function inject_e(e) - local r = e.__p__ - local d, k, rri = r.dt, e.ni, r.ri - local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt) - if edt then - local be, af - local cp = copiedelement(element,e) - if prepend then - be, af = cp, edt - else - be, af = edt, cp - end - local bn = #be - for i=1,#af do - bn = bn + 1 - be[bn] = af[i] - end - if rri then - r.dt[rri].dt = be - else - d[k].dt = be - end - redo_ni(d) - end - end - if not collected then - -- nothing - elseif collected.tg then - -- first or so - inject_e(collected) - else + if collected then for c=1,#collected do - inject_e(collected[c]) + local e = collected[c] + local r = e.__p__ + local d, k, rri = r.dt, e.ni, r.ri + local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt) + if edt then + local be, af + local cp = copiedelement(element,e) + if prepend then + be, af = cp, edt + else + be, af = edt, cp + end + local bn = #be + for i=1,#af do + bn = bn + 1 + be[bn] = af[i] + end + if rri then + r.dt[rri].dt = be + else + d[k].dt = be + end + redo_ni(d) + end end end end @@ -9865,23 +9138,16 @@ end local function insert_element(root,pattern,whatever,before) -- todo: element als functie local element = root and xmltoelement(whatever,root) local collected = element and xmlapplylpath(root,pattern) - local function insert_e(e) - local r = e.__p__ - local d, k = r.dt, e.ni - if not before then - k = k + 1 - end - insert(d,k,copiedelement(element,r)) - redo_ni(d) - end - if not collected then - -- nothing - elseif collected.tg then - -- first or so - insert_e(collected) - else + if collected then for c=1,#collected do - insert_e(collected[c]) + local e = collected[c] + local r = e.__p__ + local d, k = r.dt, e.ni + if not before then + k = k + 1 + end + insert(d,k,copiedelement(element,r)) + redo_ni(d) end end end @@ -10079,75 +9345,6 @@ function xml.remapname(root, pattern, newtg, newns, newrn) end end ---[[ldx-- -

Helper (for q2p).

---ldx]]-- - -function xml.cdatatotext(e) - local dt = e.dt - if #dt == 1 then - local first = dt[1] - if first.tg == "@cd@" then - e.dt = first.dt - end - else - -- maybe option - end -end - -xml.builtinentities = table.tohash { "amp", "quot", "apos", "lt", "gt" } -- used often so share - -local entities = characters and characters.entities or nil -local builtinentities = xml.builtinentities - -function xml.addentitiesdoctype(root,option) -- we could also have a 'resolve' i.e. inline hex - if not entities then - require("char-ent") - entities = characters.entities - end - if entities and root and root.tg == "@rt@" and root.statistics then - local list = { } - local hexify = option == "hexadecimal" - for k, v in table.sortedhash(root.statistics.entities.names) do - if not builtinentities[k] then - local e = entities[k] - if not e then - e = format("[%s]",k) - elseif hexify then - e = format("&#%05X;",utfbyte(k)) - end - list[#list+1] = format(" ",k,e) - end - end - local dt = root.dt - local n = dt[1].tg == "@pi@" and 2 or 1 - if #list > 0 then - insert(dt, n, { "\n" }) - insert(dt, n, { - tg = "@dt@", -- beware, doctype is unparsed - dt = { format("Something [\n%s\n] ",concat(list)) }, - ns = "", - special = true, - }) - insert(dt, n, { "\n\n" }) - else - -- insert(dt, n, { table.serialize(root.statistics) }) - end - end -end - --- local str = [==[ --- --- --- test   test { test --- --- --- ]==] --- --- local x = xml.convert(str) --- xml.addentitiesdoctype(x,"hexadecimal") --- print(x) - --[[ldx--

Here are a few synonyms.

--ldx]]-- @@ -10181,53 +9378,6 @@ xml.remap_tag = xml.remaptag obsolete.remap_tag xml.remap_name = xml.remapname obsolete.remap_name = xml.remapname xml.remap_namespace = xml.remapnamespace obsolete.remap_namespace = xml.remapnamespace --- new (probably ok) - -function xml.cdata(e) - if e then - local dt = e.dt - if dt and #dt == 1 then - local first = dt[1] - return first.tg == "@cd@" and first.dt[1] or "" - end - end - return "" -end - -function xml.finalizers.xml.cdata(collected) - if collected then - local e = collected[1] - if e then - local dt = e.dt - if dt and #dt == 1 then - local first = dt[1] - return first.tg == "@cd@" and first.dt[1] or "" - end - end - end - return "" -end - -function xml.insertcomment(e,str,n) -- also insertcdata - table.insert(e.dt,n or 1,{ - tg = "@cm@", - ns = "", - special = true, - at = { }, - dt = { str }, - }) -end - -function xml.setcdata(e,str) -- also setcomment - e.dt = { { - tg = "@cd@", - ns = "", - special = true, - at = { }, - dt = { str }, - } } -end - end -- of closure @@ -10241,17 +9391,15 @@ if not modules then modules = { } end modules ['lxml-xml'] = { license = "see context related readme files" } -local concat = table.concat -local find = string.find +local concat = string.concat local xml = xml -local finalizers = xml.finalizers.xml -local xmlfilter = xml.filter -- we could inline this one for speed -local xmltostring = xml.tostring -local xmlserialize = xml.serialize -local xmlcollected = xml.collected -local xmlnewhandlers = xml.newhandlers +local finalizers = xml.finalizers.xml +local xmlfilter = xml.filter -- we could inline this one for speed +local xmltostring = xml.tostring +local xmlserialize = xml.serialize +local xmlcollected = xml.collected local function first(collected) -- wrong ? return collected and collected[1] @@ -10265,21 +9413,6 @@ local function all(collected) return collected end --- local function reverse(collected) --- if collected then --- local nc = #collected --- if nc > 0 then --- local reversed, r = { }, 0 --- for c=nc,1,-1 do --- r = r + 1 --- reversed[r] = collected[c] --- end --- return reversed --- else --- return collected --- end --- end --- end local reverse = table.reversed @@ -10296,37 +9429,34 @@ local function att(id,name) end local function count(collected) - return collected and #collected or 0 + return (collected and #collected) or 0 end local function position(collected,n) - if not collected then - return 0 - end - local nc = #collected - if nc == 0 then - return 0 - end - n = tonumber(n) or 0 - if n < 0 then - return collected[nc + n + 1] - elseif n > 0 then - return collected[n] - else - return collected[1].mi or 0 + if collected then + n = tonumber(n) or 0 + if n < 0 then + return collected[#collected + n + 1] + elseif n > 0 then + return collected[n] + else + return collected[1].mi or 0 + end end end local function match(collected) - return collected and #collected > 0 and collected[1].mi or 0 -- match + return (collected and collected[1].mi) or 0 -- match end local function index(collected) - return collected and #collected > 0 and collected[1].ni or 0 -- 0 is new + if collected then + return collected[1].ni + end end local function attributes(collected,arguments) - if collected and #collected > 0 then + if collected then local at = collected[1].at if arguments then return at[arguments] @@ -10337,7 +9467,7 @@ local function attributes(collected,arguments) end local function chainattribute(collected,arguments) -- todo: optional levels - if collected and #collected > 0 then + if collected then local e = collected[1] while e do local at = e.at @@ -10355,169 +9485,108 @@ local function chainattribute(collected,arguments) -- todo: optional levels return "" end -local function raw(collected) -- hybrid (not much different from text so it might go) - if collected and #collected > 0 then +local function raw(collected) -- hybrid + if collected then local e = collected[1] or collected - return e and xmltostring(e) or "" -- only first as we cannot concat function + return (e and xmlserialize(e)) or "" -- only first as we cannot concat function else return "" end end --- - -local xmltexthandler = xmlnewhandlers { - name = "string", - initialize = function() - result = { } - return result - end, - finalize = function() - return concat(result) - end, - handle = function(...) - result[#result+1] = concat { ... } - end, - escape = false, -} - -local function xmltotext(root) - local dt = root.dt - if not dt then - return "" - end - local nt = #dt -- string or table - if nt == 0 then - return "" - elseif nt == 1 and type(dt[1]) == "string" then - return dt[1] -- no escaping of " ' < > & - else - return xmlserialize(root,xmltexthandler) or "" - end -end - --- - local function text(collected) -- hybrid - if collected then -- no # test here ! - local e = collected[1] or collected -- why fallback to element, how about cdata - return e and xmltotext(e) or "" + if collected then + local e = collected[1] or collected + return (e and xmltostring(e.dt)) or "" else return "" end end local function texts(collected) - if not collected then - return { } -- why no nil - end - local nc = #collected - if nc == 0 then - return { } -- why no nil - end - local t, n = { }, 0 - for c=1,nc do - local e = collected[c] - if e and e.dt then - n = n + 1 - t[n] = e.dt + if collected then + local t, n = { }, 0 + for c=1,#collected do + local e = collected[c] + if e and e.dt then + n = n + 1 + t[n] = e.dt + end end + return t end - return t end local function tag(collected,n) - if not collected then - return - end - local nc = #collected - if nc == 0 then - return - end - local c - if n == 0 or not n then - c = collected[1] - elseif n > 1 then - c = collected[n] - else - c = collected[nc-n+1] + if collected then + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[#collected-n+1] + end + return c and c.tg end - return c and c.tg end local function name(collected,n) - if not collected then - return - end - local nc = #collected - if nc == 0 then - return - end - local c - if n == 0 or not n then - c = collected[1] - elseif n > 1 then - c = collected[n] - else - c = collected[nc-n+1] - end - if not c then - -- sorry - elseif c.ns == "" then - return c.tg - else - return c.ns .. ":" .. c.tg + if collected then + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[#collected-n+1] + end + if c then + if c.ns == "" then + return c.tg + else + return c.ns .. ":" .. c.tg + end + end end end local function tags(collected,nonamespace) - if not collected then - return - end - local nc = #collected - if nc == 0 then - return - end - local t, n = { }, 0 - for c=1,nc do - local e = collected[c] - local ns, tg = e.ns, e.tg - n = n + 1 - if nonamespace or ns == "" then - t[n] = tg - else - t[n] = ns .. ":" .. tg + if collected then + local t, n = { }, 0 + for c=1,#collected do + local e = collected[c] + local ns, tg = e.ns, e.tg + n = n + 1 + if nonamespace or ns == "" then + t[n] = tg + else + t[n] = ns .. ":" .. tg + end end + return t end - return t end -local function empty(collected,spacesonly) - if not collected then - return true - end - local nc = #collected - if nc == 0 then - return true - end - for c=1,nc do - local e = collected[c] - if e then - local edt = e.dt - if edt then - local n = #edt - if n == 1 then - local edk = edt[1] - local typ = type(edk) - if typ == "table" then - return false - elseif edk ~= "" then - return false - elseif spacesonly and not find(edk,"%S") then +local function empty(collected) + if collected then + for c=1,#collected do + local e = collected[c] + if e then + local edt = e.dt + if edt then + local n = #edt + if n == 1 then + local edk = edt[1] + local typ = type(edk) + if typ == "table" then + return false + elseif edk ~= "" then -- maybe an extra tester for spacing only + return false + end + elseif n > 1 then return false end - elseif n > 1 then - return false end end end @@ -10572,14 +9641,14 @@ function xml.raw(id,pattern) end end -function xml.text(id,pattern) -- brrr either content or element (when cdata) +function xml.text(id,pattern) if pattern then -- return text(xmlfilter(id,pattern)) local collected = xmlfilter(id,pattern) - return collected and #collected > 0 and xmltotext(collected[1]) or "" + return (collected and xmltostring(collected[1].dt)) or "" elseif id then -- return text(id) - return xmltotext(id) or "" + return xmltostring(id.dt) or "" else return "" end @@ -10587,8 +9656,6 @@ end xml.content = text --- - function xml.position(id,pattern,n) -- element return position(xmlfilter(id,pattern),n) end @@ -10597,8 +9664,8 @@ function xml.match(id,pattern) -- number return match(xmlfilter(id,pattern)) end -function xml.empty(id,pattern,spacesonly) - return empty(xmlfilter(id,pattern),spacesonly) +function xml.empty(id,pattern) + return empty(xmlfilter(id,pattern)) end xml.all = xml.filter @@ -10652,7 +9719,7 @@ if not modules then modules = { } end modules ['data-ini'] = { license = "see context related readme files", } -local gsub, find, gmatch, char = string.gsub, string.find, string.gmatch, string.char +local gsub, find, gmatch = string.gsub, string.find, string.gmatch local concat = table.concat local next, type = next, type @@ -10714,7 +9781,7 @@ do local homedir = osgetenv(ostype == "windows" and 'USERPROFILE' or 'HOME') or '' if not homedir or homedir == "" then - homedir = char(127) -- we need a value, later we wil trigger on it + homedir = string.char(127) -- we need a value, later we wil trigger on it end homedir = file.collapsepath(homedir) @@ -10887,7 +9954,7 @@ if not modules then modules = { } end modules ['data-exp'] = { license = "see context related readme files", } -local format, find, gmatch, lower, char, sub = string.format, string.find, string.gmatch, string.lower, string.char, string.sub +local format, find, gmatch, lower = string.format, string.find, string.gmatch, string.lower local concat, sort = table.concat, table.sort local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local Ct, Cs, Cc, P, C, S = lpeg.Ct, lpeg.Cs, lpeg.Cc, lpeg.P, lpeg.C, lpeg.S @@ -10907,6 +9974,19 @@ local resolvers = resolvers -- all, when working on the main resolver code, I don't want to scroll -- past this every time. See data-obs.lua for the gsub variant. +-- {a,b,c,d} +-- a,b,c/{p,q,r},d +-- a,b,c/{p,q,r}/d/{x,y,z}// +-- a,b,c/{p,q/{x,y,z},r},d/{p,q,r} +-- a,b,c/{p,q/{x,y,z},r},d/{p,q,r} +-- a{b,c}{d,e}f +-- {a,b,c,d} +-- {a,b,c/{p,q,r},d} +-- {a,b,c/{p,q,r}/d/{x,y,z}//} +-- {a,b,c/{p,q/{x,y,z}},d/{p,q,r}} +-- {a,b,c/{p,q/{x,y,z},w}v,d/{p,q,r}} +-- {$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,.local,}/web2c} + local function f_first(a,b) local t, n = { }, 0 for s in gmatch(b,"[^,]+") do @@ -10963,9 +10043,12 @@ local function splitpathexpr(str, newlist, validate) -- I couldn't resist lpeggi str = lpegmatch(stripper_1,str) if validate then for s in gmatch(str,"[^,]+") do + local restoreslashes = false + if find(s, "//$") then restoreslashes = true end s = validate(s) if s then n = n + 1 ; t[n] = s + if restoreslashes and not find(s, "//$") then t[n] = t[n] .. '//' end end end else @@ -10998,56 +10081,41 @@ function resolvers.expandedpathfromlist(pathlist) return newlist end --- {a,b,c,d} --- a,b,c/{p,q,r},d --- a,b,c/{p,q,r}/d/{x,y,z}// --- a,b,c/{p,q/{x,y,z},r},d/{p,q,r} --- a,b,c/{p,q/{x,y,z},r},d/{p,q,r} --- a{b,c}{d,e}f --- {a,b,c,d} --- {a,b,c/{p,q,r},d} --- {a,b,c/{p,q,r}/d/{x,y,z}//} --- {a,b,c/{p,q/{x,y,z}},d/{p,q,r}} --- {a,b,c/{p,q/{x,y,z},w}v,d/{p,q,r}} --- {$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,.local,}/web2c} - local cleanup = lpeg.replacer { { "!" , "" }, { "\\" , "/" }, } -function resolvers.cleanpath(str) -- tricky, maybe only simple paths - local doslashes = (P("\\")/"/" + 1)^0 - local donegation = (P("!") /"" )^0 - local homedir = lpegmatch(Cs(donegation * doslashes),environment.homedir or "") - if homedir == "~" or homedir == "" or not lfs.isdir(homedir) then - if trace_expansions then - report_expansions("no home dir set, ignoring dependent paths") - end - function resolvers.cleanpath(str) - if not str or find(str,"~") then - return "" -- special case - else - return lpegmatch(cleanup,str) +local homedir + +function resolvers.cleanpath(str) + if not homedir then + homedir = lpegmatch(cleanup,environment.homedir or "") + if homedir == string.char(127) or homedir == "" or not lfs.isdir(homedir) then + if trace_expansions then + report_expansions("no home dir set, ignoring dependent paths") + end + function resolvers.cleanpath(str) + if find(str,"~") then + return "" -- special case + else + return str and lpegmatch(cleanup,str) + end + end + else + cleanup = lpeg.replacer { + { "!" , "" }, + { "\\" , "/" }, + { "~" , homedir }, + } + function resolvers.cleanpath(str) + return str and lpegmatch(cleanup,str) end - end - else - local dohome = ((P("~")+P("$HOME"))/homedir)^0 - local cleanup = Cs(donegation * dohome * doslashes) - function resolvers.cleanpath(str) - return str and lpegmatch(cleanup,str) or "" end end return resolvers.cleanpath(str) end --- print(resolvers.cleanpath("")) --- print(resolvers.cleanpath("!")) --- print(resolvers.cleanpath("~")) --- print(resolvers.cleanpath("~/test")) --- print(resolvers.cleanpath("!~/test")) --- print(resolvers.cleanpath("~/test~test")) - -- This one strips quotes and funny tokens. local expandhome = P("~") / "$HOME" -- environment.homedir @@ -11072,8 +10140,8 @@ end local cache = { } ------ splitter = lpeg.tsplitat(S(ostype == "windows" and ";" or ":;")) -- maybe add , -local splitter = lpeg.tsplitat(";") -- as we move towards urls, prefixes and use tables we no longer do : +---- splitter = Ct(lpeg.splitat(S(ostype == "windows" and ";" or ":;"))) -- maybe add , +local splitter = Ct(lpeg.splitat(";")) -- as we move towards urls, prefixes and use tables we no longer do : local backslashswapper = lpeg.replacer("\\","/") @@ -11133,22 +10201,13 @@ end --- a lot of this caching can be stripped away when we have ssd's everywhere --- --- we could cache all the (sub)paths here if needed +local weird = P(".")^1 + lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t")) local attributes, directory = lfs.attributes, lfs.dir -local weird = P(".")^1 + lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t")) -local timer = { } -local scanned = { } -local nofscans = 0 -local scancache = { } - local function scan(files,spec,path,n,m,r) - local full = (path == "" and spec) or (spec .. path .. '/') - local dirs = { } - local nofdirs = 0 + local full = (path == "" and spec) or (spec .. path .. '/') + local dirs, nofdirs = { }, 0 for name in directory(full) do if not lpegmatch(weird,name) then local mode = attributes(full..name,'mode') @@ -11186,122 +10245,25 @@ local function scan(files,spec,path,n,m,r) files, n, m, r = scan(files,spec,dirs[i],n,m,r) end end - scancache[sub(full,1,-2)] = files return files, n, m, r end -local fullcache = { } - -function resolvers.scanfiles(path,branch,usecache) - statistics.starttiming(timer) - local realpath = resolvers.resolve(path) -- no shortcut - if usecache then - local files = fullcache[realpath] - if files then - if trace_locating then - report_expansions("using caches scan of path '%s', branch '%s'",path,branch or path) - end - return files - end - end +function resolvers.scanfiles(path,branch) if trace_locating then - report_expansions("scanning path '%s', branch '%s'",path,branch or path) + report_expansions("scanning path '%s', branch '%s'",path, branch or path) end + local realpath = resolvers.resolve(path) -- no shortcut local files, n, m, r = scan({ },realpath .. '/',"",0,0,0) - files.__path__ = path -- can be selfautoparent:texmf-whatever - files.__files__ = n - files.__directories__ = m - files.__remappings__ = r + files.__path__ = path -- can be selfautoparent:texmf-whatever + files.__files__ = n + files.__directories__ = m + files.__remappings__ = r if trace_locating then report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r) end - if usecache then - scanned[#scanned+1] = realpath - fullcache[realpath] = files - end - nofscans = nofscans + 1 - statistics.stoptiming(timer) - return files -end - -local function simplescan(files,spec,path) -- first match only, no map and such - local full = (path == "" and spec) or (spec .. path .. '/') - local dirs = { } - local nofdirs = 0 - for name in directory(full) do - if not lpegmatch(weird,name) then - local mode = attributes(full..name,'mode') - if mode == 'file' then - if not files[name] then - -- only first match - files[name] = path - end - elseif mode == 'directory' then - nofdirs = nofdirs + 1 - if path ~= "" then - dirs[nofdirs] = path..'/'..name - else - dirs[nofdirs] = name - end - end - end - end - if nofdirs > 0 then - sort(dirs) - for i=1,nofdirs do - files = simplescan(files,spec,dirs[i]) - end - end - return files -end - -local simplecache = { } -local nofsharedscans = 0 - -function resolvers.simplescanfiles(path,branch,usecache) - statistics.starttiming(timer) - local realpath = resolvers.resolve(path) -- no shortcut - if usecache then - local files = simplecache[realpath] - if not files then - files = scancache[realpath] - if files then - nofsharedscans = nofsharedscans + 1 - end - end - if files then - if trace_locating then - report_expansions("using caches scan of path '%s', branch '%s'",path,branch or path) - end - return files - end - end - if trace_locating then - report_expansions("scanning path '%s', branch '%s'",path,branch or path) - end - local files = simplescan({ },realpath .. '/',"") - if trace_locating then - report_expansions("%s files found",table.count(files)) - end - if usecache then - scanned[#scanned+1] = realpath - simplecache[realpath] = files - end - nofscans = nofscans + 1 - statistics.stoptiming(timer) return files end -function resolvers.scandata() - table.sort(scanned) - return { - n = nofscans, - shared = nofsharedscans, - time = statistics.elapsedtime(timer), - paths = scanned, - } -end - end -- of closure @@ -11399,12 +10361,12 @@ local relations = allocate { -- todo: handlers also here mp = { names = { "mp" }, variable = 'MPINPUTS', - suffixes = { 'mp', 'mpvi', 'mpiv', 'mpii' }, + suffixes = { 'mp' }, }, tex = { names = { "tex" }, variable = 'TEXINPUTS', - suffixes = { 'tex', "mkvi", "mkiv", "mkii" }, + suffixes = { 'tex', "mkiv", "mkiv", "mkii" }, }, icc = { names = { "icc", "icc profile", "icc profiles" }, @@ -11541,7 +10503,7 @@ end resolvers.updaterelations() -- push this in the metatable -> newindex local function simplified(t,k) - return k and rawget(t,lower(gsub(k," ",""))) or nil + return rawget(t,lower(gsub(k," ",""))) end setmetatableindex(formats, simplified) @@ -11627,7 +10589,6 @@ luatools with a recache feature.

--ldx]]-- local format, lower, gsub, concat = string.format, string.lower, string.gsub, table.concat -local serialize, serializetofile = table.serialize, table.tofile local mkdirs, isdir = dir.mkdirs, lfs.isdir local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -11690,7 +10651,11 @@ local function identify() end elseif not writable and caches.force then local cacheparent = file.dirname(cachepath) - if file.is_writable(cacheparent) and true then -- we go on anyway (needed for mojca's kind of paths) + -- TH: added 'or true' for deeply buried non-existent caches. + -- file.is_writable() is not really important here, since this + -- branch is only checked for as-yet non-existent paths, and + -- it guards against mkdirs() failing, anyway. + if file.is_writable(cacheparent) or true then if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath), "no", { "yes", "no" }) == "yes" then mkdirs(cachepath) if isdir(cachepath) and file.is_writable(cachepath) then @@ -11781,7 +10746,7 @@ function caches.usedpaths() end function caches.configfiles() - return concat(resolvers.instance.specification,";") + return table.concat(resolvers.instance.specification,";") end function caches.hashed(tree) @@ -11905,9 +10870,9 @@ function caches.savedata(filepath,filename,data,raw) end data.cache_uuid = os.uuid() if caches.direct then - file.savedata(tmaname,serialize(data,true,saveoptions)) + file.savedata(tmaname,table.serialize(data,true,saveoptions)) else - serializetofile(tmaname,data,true,saveoptions) + table.tofile(tmaname,data,true,saveoptions) end utilities.lua.compile(tmaname,tmcname) end @@ -11974,7 +10939,7 @@ function caches.savecontent(cachename,dataname,content) content = content, uuid = os.uuid(), } - local ok = io.savedata(luaname,serialize(data,true)) + local ok = io.savedata(luaname,table.serialize(data,true)) if ok then if trace_locating then report_resolvers("category '%s', cachename '%s' saved in '%s'",dataname,cachename,luaname) @@ -12147,7 +11112,7 @@ if not modules then modules = { } end modules ['data-res'] = { -- instance but for practical purposes we now avoid this and use a -- instance variable. We always have one instance active (sort of global). --- todo: cache:/// home:/// selfautoparent:/// (sometime end 2012) +-- todo: cache:/// home:/// local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys @@ -12190,58 +11155,7 @@ resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARE resolvers.luacnfname = 'texmfcnf.lua' resolvers.luacnfstate = "unknown" --- The web2c tex binaries as well as kpse have built in paths for the configuration --- files and there can be a depressing truckload of them. This is actually the weak --- spot of a distribution. So we don't want: --- --- resolvers.luacnfspec = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}' --- --- but instead use: --- --- resolvers.luacnfspec = 'selfautoparent:{/texmf{-local,}{,/web2c}}' --- --- which does not make texlive happy as there is a texmf-local tree one level up --- (sigh), so we need this. (We can assume web2c as mkiv does not run on older --- texlives anyway. --- --- texlive: --- --- selfautodir: --- selfautoparent: --- selfautodir:share/texmf-local/web2c --- selfautodir:share/texmf/web2c --- selfautodir:texmf-local/web2c --- selfautodir:texmf/web2c --- selfautoparent:share/texmf-local/web2c --- selfautoparent:share/texmf/web2c --- selfautoparent:texmf-local/web2c --- selfautoparent:texmf/web2c --- --- minimals: --- --- home:texmf/web2c --- selfautoparent:texmf-local/web2c --- selfautoparent:texmf-context/web2c --- selfautoparent:texmf/web2c - -if this_is_texlive then - -- resolvers.luacnfspec = '{selfautodir:,selfautoparent:}{,{/share,}/texmf{-local,}/web2c}' - -- resolvers.luacnfspec = '{selfautodir:{/share,}/texmf-local/web2c,selfautoparent:{/share,}/texmf{-local,}/web2c}' - -- resolvers.luacnfspec = 'selfautodir:/texmf-local/web2c;selfautoparent:/texmf{-local,}/web2c' - resolvers.luacnfspec = 'selfautodir:;selfautoparent:;{selfautodir:,selfautoparent:}{/share,}/texmf{-local,}/web2c' -else - resolvers.luacnfspec = 'home:texmf/web2c;selfautoparent:texmf{-local,-context,}/web2c' -end - --- which (as we want users to use the web2c path) be can be simplified to this: --- --- if environment and environment.ownpath and string.find(environment.ownpath,"[\\/]texlive[\\/]") then --- resolvers.luacnfspec = 'selfautodir:/texmf-local/web2c,selfautoparent:/texmf-local/web2c,selfautoparent:/texmf/web2c' --- else --- resolvers.luacnfspec = 'selfautoparent:/texmf-local/web2c,selfautoparent:/texmf/web2c' --- end - - +resolvers.luacnfspec = '{selfautodir:,selfautoparent:};{selfautodir:,selfautoparent:}{/share,}/texmf{-local,};{selfautodir:,selfautoparent:}{/share,}/texmf{-local,}/web2c' local unset_variable = "unset" @@ -12263,7 +11177,7 @@ local instance = resolvers.instance or nil -- the current one (fast access) function resolvers.setenv(key,value,raw) if instance then -- this one will be consulted first when we stay inside - -- the current environment (prefixes are not resolved here) + -- the current environment instance.environment[key] = value -- we feed back into the environment, and as this is used -- by other applications (via os.execute) we need to make @@ -12343,7 +11257,6 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp remember = true, diskcache = true, renewcache = false, - renewtree = false, loaderror = false, savelists = true, pattern = nil, -- lists @@ -12435,7 +11348,7 @@ local function makepathexpression(str) end end -local function reportcriticalvariables(cnfspec) +local function reportcriticalvariables() if trace_locating then for i=1,#resolvers.criticalvars do local k = resolvers.criticalvars[i] @@ -12443,14 +11356,6 @@ local function reportcriticalvariables(cnfspec) report_resolving("variable '%s' set to '%s'",k,v) end report_resolving() - if cnfspec then - if type(cnfspec) == "table" then - report_resolving("using configuration specification '%s'",concat(cnfspec,",")) - else - report_resolving("using configuration specification '%s'",cnfspec) - end - end - report_resolving() end reportcriticalvariables = function() end end @@ -12465,7 +11370,7 @@ local function identify_configuration_files() else resolvers.luacnfstate = "environment" end - reportcriticalvariables(cnfspec) + reportcriticalvariables() local cnfpaths = expandedpathfromlist(resolvers.splitpath(cnfspec)) local luacnfname = resolvers.luacnfname for i=1,#cnfpaths do @@ -12501,19 +11406,6 @@ local function load_configuration_files() if blob then local setups = instance.setups local data = blob() - local parent = data and data.parent - if parent then - local filename = filejoin(pathname,parent) - local realname = resolvers.resolve(filename) -- no shortcut - local blob = loadfile(realname) - if blob then - local parentdata = blob() - if parentdata then - report_resolving("loading configuration file '%s'",filename) - data = table.merged(parentdata,data) - end - end - end data = data and data.content if data then if trace_locating then @@ -12603,6 +11495,11 @@ local function locate_file_databases() local runtime = stripped == path path = resolvers.cleanpath(path) local spec = resolvers.splitmethod(stripped) + -- TH Original did this the other way around (elseif and if tests + -- reversed) but then the else branch was never reached, as 'runtime' + -- would effectively be ignored. In turn, that meant that the wrong + -- locator method was used, such that tree: and file: were treated + -- identically (cached and no runtime search). if runtime and (spec.noscheme or spec.scheme == "file") then stripped = "tree:///" .. stripped elseif spec.scheme == "cache" or spec.scheme == "file" then @@ -12610,7 +11507,7 @@ local function locate_file_databases() end if trace_locating then if runtime then - report_resolving("locating list of '%s' (runtime) (%s)",path,stripped) + report_resolving("locating list of '%s' (runtime)",path) else report_resolving("locating list of '%s' (cached)",path) end @@ -12654,39 +11551,6 @@ local function save_file_databases() -- will become cachers end end -function resolvers.renew(hashname) - if hashname and hashname ~= "" then - local expanded = resolvers.expansion(hashname) or "" - if expanded ~= "" then - if trace_locating then - report_resolving("identifying tree '%s' from '%s'",expanded,hashname) - end - hashname = expanded - else - if trace_locating then - report_resolving("identifying tree '%s'",hashname) - end - end - local realpath = resolvers.resolve(hashname) - if lfs.isdir(realpath) then - if trace_locating then - report_resolving("using path '%s'",realpath) - end - methodhandler('generators',hashname) - -- could be shared - local content = instance.files[hashname] - caches.collapsecontent(content) - if trace_locating then - report_resolving("saving tree '%s'",hashname) - end - caches.savecontent(hashname,"files",content) - -- till here - else - report_resolving("invalid path '%s'",realpath) - end - end -end - local function load_databases() locate_file_databases() if instance.diskcache and not instance.renewcache then @@ -12974,7 +11838,6 @@ local function collect_files(names) if dname == "" or find(dname,"^%.") then dname = false else -dname = gsub(dname,"*","%.*") dname = "/" .. dname .. "$" end local hashes = instance.hashes @@ -13034,22 +11897,9 @@ dname = gsub(dname,"*","%.*") return noffiles > 0 and filelist or nil end -local fit = { } - -function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname) - local foundintrees = instance.foundintrees - if usedmethod == "direct" and filename == foundname and fit[foundname] then - -- just an extra lookup after a test on presence - else - local t = { - filename = filename, - format = format ~= "" and format or nil, - filetype = filetype ~= "" and filetype or nil, - usedmethod = usedmethod, - foundname = foundname, - } - fit[foundname] = t - foundintrees[#foundintrees+1] = t +function resolvers.registerintrees(name) + if not find(name,"^%.") then + instance.foundintrees[name] = (instance.foundintrees[name] or 0) + 1 -- maybe only one end end @@ -13069,423 +11919,297 @@ end local preparetreepattern = Cs((P(".")/"%%." + P("-")/"%%-" + P(1))^0 * Cc("$")) --- -- -- begin of main file search routing -- -- -- needs checking as previous has been patched - -local collect_instance_files +-- this one is split in smaller functions but it needs testing -local function find_analyze(filename,askedformat,allresults) - local filetype, wantedfiles, ext = '', { }, fileextname(filename) - -- too tricky as filename can be bla.1.2.3: - -- - -- if not suffixmap[ext] then - -- wantedfiles[#wantedfiles+1] = filename - -- end - wantedfiles[#wantedfiles+1] = filename - if askedformat == "" then - if ext == "" or not suffixmap[ext] then - local defaultsuffixes = resolvers.defaultsuffixes - for i=1,#defaultsuffixes do - local forcedname = filename .. '.' .. defaultsuffixes[i] - wantedfiles[#wantedfiles+1] = forcedname - filetype = resolvers.formatofsuffix(forcedname) - if trace_locating then - report_resolving("forcing filetype '%s'",filetype) - end - end - else - filetype = resolvers.formatofsuffix(filename) +local function collect_instance_files(filename,askedformat,allresults) -- todo : plugin (scanners, checkers etc) + local result = { } + local stamp = nil + askedformat = askedformat or "" + filename = collapsepath(filename) + -- speed up / beware: format problem + if instance.remember and not allresults then + stamp = filename .. "--" .. askedformat + if instance.found[stamp] then if trace_locating then - report_resolving("using suffix based filetype '%s'",filetype) - end - end - else - if ext == "" or not suffixmap[ext] then - local format_suffixes = suffixes[askedformat] - if format_suffixes then - for i=1,#format_suffixes do - wantedfiles[#wantedfiles+1] = filename .. "." .. format_suffixes[i] - end + report_resolving("remembered file '%s'",filename) end - end - filetype = askedformat - if trace_locating then - report_resolving("using given filetype '%s'",filetype) + resolvers.registerintrees(filename) -- for tracing used files + return instance.found[stamp] end end - return filetype, wantedfiles -end - -local function find_direct(filename,allresults) - if not dangerous[askedformat] and isreadable(filename) then - if trace_detail then - report_resolving("file '%s' found directly",filename) + if not dangerous[askedformat] then + if isreadable(filename) then + if trace_detail then + report_resolving("file '%s' found directly",filename) + end + if stamp then + instance.found[stamp] = { filename } + end + return { filename } end - return "direct", { filename } end -end - -local function find_wildcard(filename,allresults) if find(filename,'%*') then if trace_locating then report_resolving("checking wildcard '%s'", filename) end - local method, result = resolvers.findwildcardfiles(filename) - if result then - return "wildcard", result - end - end -end - -local function find_qualified(filename,allresults) -- this one will be split too - if not file.is_qualified_path(filename) then - return - end - if trace_locating then - report_resolving("checking qualified name '%s'", filename) - end - if isreadable(filename) then - if trace_detail then - report_resolving("qualified file '%s' found", filename) - end - return "qualified", { filename } - end - if trace_detail then - report_resolving("locating qualified file '%s'", filename) - end - local forcedname, suffix = "", fileextname(filename) - if suffix == "" then -- why - local format_suffixes = askedformat == "" and resolvers.defaultsuffixes or suffixes[askedformat] - if format_suffixes then - for i=1,#format_suffixes do - local s = format_suffixes[i] - forcedname = filename .. "." .. s - if isreadable(forcedname) then - if trace_locating then - report_resolving("no suffix, forcing format filetype '%s'", s) + result = resolvers.findwildcardfiles(filename) -- we can use th elocal + elseif file.is_qualified_path(filename) then + if isreadable(filename) then + if trace_locating then + report_resolving("qualified name '%s'", filename) + end + result = { filename } + else + local forcedname, ok, suffix = "", false, fileextname(filename) + if suffix == "" then -- why + local format_suffixes = askedformat == "" and resolvers.defaultsuffixes or suffixes[askedformat] + if format_suffixes then + for i=1,#format_suffixes do + local s = format_suffixes[i] + forcedname = filename .. "." .. s + if isreadable(forcedname) then + if trace_locating then + report_resolving("no suffix, forcing format filetype '%s'", s) + end + result, ok = { forcedname }, true + break + end end - return "qualified", { forcedname } end end - end - end - if suffix and suffix ~= "" then - -- try to find in tree (no suffix manipulation), here we search for the - -- matching last part of the name - local basename = filebasename(filename) - local pattern = lpegmatch(preparetreepattern,filename) - -- messy .. to be sorted out - local savedformat = askedformat - local format = savedformat or "" - if format == "" then - askedformat = resolvers.formatofsuffix(suffix) - end - if not format then - askedformat = "othertextfiles" -- kind of everything, maybe all - end - -- - if basename ~= filename then - local resolved = collect_instance_files(basename,askedformat,allresults) - if #resolved == 0 then - local lowered = lower(basename) - if filename ~= lowered then - resolved = collect_instance_files(lowered,askedformat,allresults) + if not ok and suffix ~= "" then + -- try to find in tree (no suffix manipulation), here we search for the + -- matching last part of the name + local basename = filebasename(filename) + local pattern = lpegmatch(preparetreepattern,filename) + -- messy .. to be sorted out + local savedformat = askedformat + local format = savedformat or "" + if format == "" then + askedformat = resolvers.formatofsuffix(suffix) + end + if not format then + askedformat = "othertextfiles" -- kind of everything, maybe texinput is better + end + -- + if basename ~= filename then + local resolved = collect_instance_files(basename,askedformat,allresults) + if #result == 0 then -- shouldn't this be resolved ? + local lowered = lower(basename) + if filename ~= lowered then + resolved = collect_instance_files(lowered,askedformat,allresults) + end + end + resolvers.format = savedformat + -- + for r=1,#resolved do + local rr = resolved[r] + if find(rr,pattern) then + result[#result+1], ok = rr, true + end + end end + -- a real wildcard: + -- + -- if not ok then + -- local filelist = collect_files({basename}) + -- for f=1,#filelist do + -- local ff = filelist[f][3] or "" + -- if find(ff,pattern) then + -- result[#result+1], ok = ff, true + -- end + -- end + -- end + end + if not ok and trace_locating then + report_resolving("qualified name '%s'", filename) end - resolvers.format = savedformat - -- - if #resolved > 0 then - local result = { } - for r=1,#resolved do - local rr = resolved[r] - if find(rr,pattern) then - result[#result+1] = rr + end + else + -- search spec + local filetype, done, wantedfiles, ext = '', false, { }, fileextname(filename) + -- -- tricky as filename can be bla.1.2.3 + -- if not suffixmap[ext] then --- probably needs to be done elsewhere too + -- wantedfiles[#wantedfiles+1] = filename + -- end + wantedfiles[#wantedfiles+1] = filename + if askedformat == "" then + if ext == "" or not suffixmap[ext] then + local defaultsuffixes = resolvers.defaultsuffixes + for i=1,#defaultsuffixes do + local forcedname = filename .. '.' .. defaultsuffixes[i] + wantedfiles[#wantedfiles+1] = forcedname + filetype = resolvers.formatofsuffix(forcedname) + if trace_locating then + report_resolving("forcing filetype '%s'",filetype) end end - if #result > 0 then - return "qualified", result + else + filetype = resolvers.formatofsuffix(filename) + if trace_locating then + report_resolving("using suffix based filetype '%s'",filetype) end end - end - -- a real wildcard: - -- - -- local filelist = collect_files({basename}) - -- result = { } - -- for f=1,#filelist do - -- local ff = filelist[f][3] or "" - -- if find(ff,pattern) then - -- result[#result+1], ok = ff, true - -- end - -- end - -- if #result > 0 then - -- return "qualified", result - -- end - end -end - -local function check_subpath(fname) - if isreadable(fname) then - if trace_detail then - report_resolving("found '%s' by deep scanning",fname) - end - return fname - end -end - -local function find_intree(filename,filetype,wantedfiles,allresults) - local typespec = resolvers.variableofformat(filetype) - local pathlist = resolvers.expandedpathlist(typespec) - local method = "intree" - if pathlist and #pathlist > 0 then - -- list search - local filelist = collect_files(wantedfiles) - local dirlist = { } - if filelist then - for i=1,#filelist do - dirlist[i] = filedirname(filelist[i][3]) .. "/" -- was [2] .. gamble + else + if ext == "" or not suffixmap[ext] then + local format_suffixes = suffixes[askedformat] + if format_suffixes then + for i=1,#format_suffixes do + wantedfiles[#wantedfiles+1] = filename .. "." .. format_suffixes[i] + end + end + end + filetype = askedformat + if trace_locating then + report_resolving("using given filetype '%s'",filetype) end end - if trace_detail then - report_resolving("checking filename '%s'",filename) - end - local result = { } - for k=1,#pathlist do - local path = pathlist[k] - local pathname = lpegmatch(inhibitstripper,path) - local doscan = path == pathname -- no ^!! - if not find (pathname,'//$') then - doscan = false -- we check directly on the path - end - local done = false - -- using file list - if filelist then -- database - -- compare list entries with permitted pattern -- /xx /xx// - local expression = makepathexpression(pathname) - if trace_detail then - report_resolving("using pattern '%s' for path '%s'",expression,pathname) + local typespec = resolvers.variableofformat(filetype) + local pathlist = resolvers.expandedpathlist(typespec) + if not pathlist or #pathlist == 0 then + -- no pathlist, access check only / todo == wildcard + if trace_detail then + report_resolving("checking filename '%s', filetype '%s', wanted files '%s'",filename, filetype or '?',concat(wantedfiles," | ")) + end + for k=1,#wantedfiles do + local fname = wantedfiles[k] + if fname and isreadable(fname) then + filename, done = fname, true + result[#result+1] = filejoin('.',fname) + break end - for k=1,#filelist do - local fl = filelist[k] - local f = fl[2] - local d = dirlist[k] - if find(d,expression) then - -- todo, test for readable - result[#result+1] = resolvers.resolve(fl[3]) -- no shortcut - done = true - if allresults then - if trace_detail then - report_resolving("match to '%s' in hash for file '%s' and path '%s', continue scanning",expression,f,d) - end - else - if trace_detail then - report_resolving("match to '%s' in hash for file '%s' and path '%s', quit scanning",expression,f,d) + end + -- this is actually 'other text files' or 'any' or 'whatever' + local filelist = collect_files(wantedfiles) + local fl = filelist and filelist[1] + if fl then + filename = fl[3] -- not local? + result[#result+1] = resolvers.resolve(filename) + done = true + end + else + -- list search + local filelist = collect_files(wantedfiles) + local dirlist = { } + if filelist then + for i=1,#filelist do + dirlist[i] = filedirname(filelist[i][3]) .. "/" -- was [2] .. gamble + end + end + if trace_detail then + report_resolving("checking filename '%s'",filename) + end + for k=1,#pathlist do + local path = pathlist[k] + local pathname = lpegmatch(inhibitstripper,path) + local doscan = path == pathname -- no ^!! + if not find (pathname, '//$') then doscan = false end + done = false + -- using file list + if filelist then + -- compare list entries with permitted pattern -- /xx /xx// + local expression = makepathexpression(pathname) + if trace_detail then + report_resolving("using pattern '%s' for path '%s'",expression,pathname) + end + for k=1,#filelist do + local fl = filelist[k] + local f = fl[2] + local d = dirlist[k] + if find(d,expression) then + -- todo, test for readable + result[#result+1] = resolvers.resolve(fl[3]) -- no shortcut + done = true + if allresults then + if trace_detail then + report_resolving("match to '%s' in hash for file '%s' and path '%s', continue scanning",expression,f,d) + end + else + if trace_detail then + report_resolving("match to '%s' in hash for file '%s' and path '%s', quit scanning",expression,f,d) + end + break end - break + elseif trace_detail then + report_resolving("no match to '%s' in hash for file '%s' and path '%s'",expression,f,d) end - elseif trace_detail then - report_resolving("no match to '%s' in hash for file '%s' and path '%s'",expression,f,d) end end - end - if done then - method = "database" - else - method = "filesystem" -- bonus, even when !! is specified - pathname = gsub(pathname,"/+$","") - pathname = resolvers.resolve(pathname) - local scheme = url.hasscheme(pathname) - if not scheme or scheme == "file" then - local pname = gsub(pathname,"%.%*$",'') - if not find(pname,"%*") then - if can_be_dir(pname) then - -- quick root scan first - for k=1,#wantedfiles do - local w = wantedfiles[k] - local fname = check_subpath(filejoin(pname,w)) - if fname then - result[#result+1] = fname - done = true - if not allresults then - break - end - end - end - if not done and doscan then - -- collect files in path (and cache the result) - local files = resolvers.simplescanfiles(pname,false,true) + if not done then + -- check if on disk / unchecked / does not work at all / also zips + -- TH perhaps it did not work because of missing resolvers.resolve() + -- and resolvers.scanfiles() calls ... + pathname = resolvers.resolve(pathname) + local scheme = url.hasscheme(pathname) + if not scheme or scheme == "file" then + local pname = gsub(pathname,"%.%*$",'') + if not find(pname,"%*") then + local ppname = gsub(pname,"/+$","") + if can_be_dir(ppname) then + local files = {} + if doscan then files = resolvers.scanfiles(ppname) end for k=1,#wantedfiles do local w = wantedfiles[k] - local subpath = files[w] - if not subpath or subpath == "" then - -- rootscan already done - elseif type(subpath) == "string" then - local fname = check_subpath(filejoin(pname,subpath,w)) - if fname then - result[#result+1] = fname - done = true - if not allresults then - break - end - end - else - for i=1,#subpath do - local sp = subpath[i] - if sp == "" then - -- roottest already done - else - local fname = check_subpath(filejoin(pname,sp,w)) - if fname then - result[#result+1] = fname - done = true - if not allresults then - break - end - end - end - end - if done and not allresults then - break + local subpath = '' + if files[w] then + subpath = type(files[w]) == "table" and files[w][1] or files[w] + end + local fname = filejoin(ppname,subpath,w) + if isreadable(fname) then + if trace_detail then + report_resolving("found '%s' by scanning",fname) end + result[#result+1] = fname + done = true + if not allresults then break end end end + else + -- no access needed for non existing path, speedup (esp in large tree with lots of fake) end end - else - -- no access needed for non existing path, speedup (esp in large tree with lots of fake) end end + if not done and doscan then + -- todo: slow path scanning ... although we now have tree:// supported in $TEXMF + end + if done and not allresults then break end end - -- todo recursive scanning - if done and not allresults then - break - end - end - if #result > 0 then - return method, result end end -end - -local function find_onpath(filename,filetype,wantedfiles,allresults) - if trace_detail then - report_resolving("checking filename '%s', filetype '%s', wanted files '%s'",filename, filetype or '?',concat(wantedfiles," | ")) - end - local result = { } - for k=1,#wantedfiles do - local fname = wantedfiles[k] - if fname and isreadable(fname) then - filename = fname - result[#result+1] = filejoin('.',fname) - if not allresults then - break - end - end + for k=1,#result do + local rk = collapsepath(result[k]) + result[k] = rk + resolvers.registerintrees(rk) -- for tracing used files end - if #result > 0 then - return "onpath", result + if stamp then + instance.found[stamp] = result end + return result end -local function find_otherwise(filename,filetype,wantedfiles,allresults) -- other text files | any | whatever - local filelist = collect_files(wantedfiles) - local fl = filelist and filelist[1] - if fl then - return "otherwise", { resolvers.resolve(fl[3]) } -- filename - end -end +-- -- -- begin of main file search routing -- -- -- + + + --- we could have a loop over the 6 functions but then we'd have to --- always analyze -collect_instance_files = function(filename,askedformat,allresults) -- uses nested - askedformat = askedformat or "" - filename = collapsepath(filename) - if allresults then - -- no need for caching, only used for tracing - local filetype, wantedfiles = find_analyze(filename,askedformat) - local results = { - { find_direct (filename,true) }, - { find_wildcard (filename,true) }, - { find_qualified(filename,true) }, - { find_intree (filename,filetype,wantedfiles,true) }, - { find_onpath (filename,filetype,wantedfiles,true) }, - { find_otherwise(filename,filetype,wantedfiles,true) }, - } - local result, status, done = { }, { }, { } - for k, r in next, results do - local method, list = r[1], r[2] - if method and list then - for i=1,#list do - local c = collapsepath(list[i]) - if not done[c] then - result[#result+1] = c - done[c] = true - end - status[#status+1] = format("%-10s: %s",method,c) - end - end - end - if trace_detail then - report_resolving("lookup status: %s",table.serialize(status,filename)) - end - return result, status - else - local method, result, stamp, filetype, wantedfiles - if instance.remember then - stamp = format("%s--%s", filename, askedformat) - result = stamp and instance.found[stamp] - if result then - if trace_locating then - report_resolving("remembered file '%s'",filename) - end - return result - end - end - method, result = find_direct(filename) - if not result then - method, result = find_wildcard(filename) - if not result then - method, result = find_qualified(filename) - if not result then - filetype, wantedfiles = find_analyze(filename,askedformat) - method, result = find_intree(filename,filetype,wantedfiles) - if not result then - method, result = find_onpath(filename,filetype,wantedfiles) - if not result then - method, result = find_otherwise(filename,filetype,wantedfiles) - end - end - end - end - end - if result and #result > 0 then - local foundname = collapsepath(result[1]) - resolvers.registerintrees(filename,askedformat,filetype,method,foundname) - result = { foundname } - else - result = { } -- maybe false - end - if stamp then - if trace_locating then - report_resolving("remembering file '%s'",filename) - end - instance.found[stamp] = result - end - return result - end -end --- -- -- end of main file search routing -- -- -- + + +-- -- -- end of main file search routing -- -- -- + local function findfiles(filename,filetype,allresults) - local result, status = collect_instance_files(filename,filetype or "",allresults) - if not result or #result == 0 then + local result = collect_instance_files(filename,filetype or "",allresults) + if #result == 0 then local lowered = lower(filename) if filename ~= lowered then - result, status = collect_instance_files(lowered,filetype or "",allresults) + return collect_instance_files(lowered,filetype or "",allresults) end end - return result or { }, status + return result end function resolvers.findfiles(filename,filetype) @@ -13646,10 +12370,6 @@ function resolvers.load(option) return files and next(files) and true end -function resolvers.loadtime() - return statistics.elapsedtime(instance) -end - local function report(str) if trace_locating then report_resolving(str) -- has already verbose @@ -13663,9 +12383,6 @@ function resolvers.dowithfilesandreport(command, files, ...) -- will move if trace_locating then report('') -- ? end - if type(files) == "string" then - files = { files } - end for f=1,#files do local file = files[f] local result = command(file,...) @@ -13823,8 +12540,6 @@ local cleanpath, findgivenfile, expansion = resolvers.cleanpath, resolvers.findg local getenv = resolvers.getenv -- we can probably also use resolvers.expansion local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match --- getenv = function(...) return resolvers.getenv(...) end -- needs checking (definitions changes later on) - prefixes.environment = function(str) return cleanpath(expansion(str)) end @@ -13863,7 +12578,7 @@ end prefixes.filename = function(str) local fullname = findgivenfile(str) or "" - return cleanpath(file.basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here + return cleanpath(file.basename((fullname ~= "" and fullname) or str)) end prefixes.pathname = function(str) @@ -13906,9 +12621,8 @@ function resolvers.allprefixes(separator) end local function _resolve_(method,target) - local action = prefixes[method] - if action then - return action(target) + if prefixes[method] then + return prefixes[method](target) else return method .. ":" .. target end @@ -13923,7 +12637,7 @@ end local function resolve(str) -- use schemes, this one is then for the commandline only local res = resolved[str] if not res then - res = gsub(str,"([a-z][a-z]+):([^ \"\';]*)",_resolve_) -- home:xx;selfautoparent:xx; etc + res = gsub(str,"([a-z][a-z]+):([^ \"\';]*)",_resolve_) resolved[str] = res abstract[res] = str end @@ -14083,7 +12797,7 @@ end function generators.file(specification) local path = specification.filename - local content = resolvers.scanfiles(path,false,true) -- scan once + local content = resolvers.scanfiles(path) resolvers.registerfilehash(path,content,true) end @@ -14438,18 +13152,6 @@ local archives = zip.archives zip.registeredfiles = zip.registeredfiles or { } local registeredfiles = zip.registeredfiles -local limited = false - -directives.register("system.inputmode", function(v) - if not limited then - local i_limiter = io.i_limiter(v) - if i_limiter then - zip.open = i_limiter.protect(zip.open) - limited = true - end - end -end) - local function validzip(str) -- todo: use url splitter if not find(str,"^zip://") then return "zip:///" .. str @@ -14717,11 +13419,11 @@ function resolvers.finders.tree(specification) end function resolvers.locators.tree(specification) - local name = specification.filename - local realname = resolvers.resolve(name) -- no shortcut - if realname and realname ~= '' and lfs.isdir(realname) then + -- TH: resolvers.resolve() call was missing here + local name = resolvers.resolve(specification.filename) + if name ~= '' and lfs.isdir(name) then if trace_locating then - report_trees("locator '%s' found",realname) + report_trees("locator '%s' found",name) end resolvers.appendhash('tree',name,false) -- don't cache elseif trace_locating then @@ -14735,8 +13437,6 @@ function resolvers.hashers.tree(specification) report_trees("analysing '%s'",name) end resolvers.methodhandler("hashers",name) - - resolvers.generators.file(specification) end resolvers.concatinators.tree = resolvers.concatinators.file @@ -14896,15 +13596,8 @@ local function loaded(libpaths,name,simple) end package.loaders[2] = function(name) -- was [#package.loaders+1] - if file.suffix(name) == "" then - name = file.addsuffix(name,"lua") -- maybe a list - if trace_locating then -- mode detail - report_libraries("! locating '%s' with forced suffix",name) - end - else - if trace_locating then -- mode detail - report_libraries("! locating '%s'",name) - end + if trace_locating then -- mode detail + report_libraries("! locating '%s'",name) end for i=1,#libformats do local format = libformats[i] @@ -15111,13 +13804,7 @@ function resolvers.load_tree(tree,resolve) -- Beware, we need to obey the relocatable autoparent so we -- set TEXMFCNF to its raw value. This is somewhat tricky when -- we run a mkii job from within. Therefore, in mtxrun, there - -- is a resolve applied when we're in mkii/kpse mode or when - -- --resolve is passed to mtxrun. Maybe we should also set the - -- local AUTOPARENT etc. although these are alwasy set new. - - if resolve then - resolvers.luacnfspec = resolvers.resolve(resolvers.luacnfspec) - end + -- is a resolve applied when we're in mkii/kpse mode. setenv('SELFAUTOPARENT', newroot) setenv('SELFAUTODIR', newtree) @@ -15125,12 +13812,11 @@ function resolvers.load_tree(tree,resolve) setenv('TEXROOT', newroot) setenv('TEXOS', texos) setenv('TEXMFOS', texmfos) - setenv('TEXMFCNF', resolvers.luacnfspec,true) -- already resolved - setenv('PATH', newpath .. io.pathseparator .. getenv('PATH')) + setenv('TEXMFCNF', resolvers.luacnfspec, not resolve) + setenv("PATH", newpath .. io.pathseparator .. getenv("PATH")) report_tds("changing from root '%s' to '%s'",oldroot,newroot) - report_tds("prepending '%s' to PATH",newpath) - report_tds("setting TEXMFCNF to '%s'",resolvers.luacnfspec) + report_tds("prepending '%s' to binary path",newpath) report_tds() end end @@ -15151,7 +13837,6 @@ if not modules then modules = { } end modules ['data-lst'] = { -- used in mtxrun, can be loaded later .. todo local find, concat, upper, format = string.find, table.concat, string.upper, string.format -local fastcopy, sortedpairs = table.fastcopy, table.sortedpairs resolvers.listers = resolvers.listers or { } @@ -15182,10 +13867,10 @@ function resolvers.listers.variables(pattern) end end end - local env = fastcopy(environment) - local var = fastcopy(variables) - local exp = fastcopy(expansions) - for key, value in sortedpairs(configured) do + local env = table.fastcopy(environment) + local var = table.fastcopy(variables) + local exp = table.fastcopy(expansions) + for key, value in table.sortedpairs(configured) do if key ~= "" and (pattern == "" or find(upper(key),pattern)) then report_lists(key) report_lists(" env: %s",tabstr(rawget(environment,key)) or "unset") @@ -15194,9 +13879,9 @@ function resolvers.listers.variables(pattern) report_lists(" res: %s",resolvers.resolve(expansions[key]) or "unset") end end - instance.environment = fastcopy(env) - instance.variables = fastcopy(var) - instance.expansions = fastcopy(exp) + instance.environment = table.fastcopy(env) + instance.variables = table.fastcopy(var) + instance.expansions = table.fastcopy(exp) end function resolvers.listers.configurations(report) @@ -15483,8 +14168,8 @@ own = { } -- not local, might change own.libs = { -- order can be made better 'l-string.lua', - 'l-table.lua', 'l-lpeg.lua', + 'l-table.lua', 'l-io.lua', 'l-number.lua', 'l-set.lua', @@ -15555,7 +14240,7 @@ end -- End of hack. -local format, gsub, gmatch, match, find = string.format, string.gsub, string.gmatch, string.match, string.find +local format, gsub, gmatch, match = string.format, string.gsub, string.gmatch, string.match local concat = table.concat own.name = (environment and environment.ownname) or arg[0] or 'mtxrun.lua' @@ -15677,7 +14362,7 @@ local helpinfo = [[ --resolve resolve prefixed arguments --ctxlua run internally (using preloaded libs) --internal run script using built in libraries (same as --ctxlua) ---locate locate given filename in database (default) or system (--first --all --detail) +--locate locate given filename --autotree use texmf tree cf. env 'texmfstart_tree' or 'texmfstarttree' --tree=pathtotree use given texmf tree (default file: 'setuptex.tmf') @@ -15725,7 +14410,7 @@ local helpinfo = [[ local application = logs.application { name = "mtxrun", - banner = "ConTeXt TDS Runner Tool 1.31", + banner = "ConTeXt TDS Runner Tool 1.30", helpinfo = helpinfo, } @@ -15770,12 +14455,12 @@ runners.registered = { xmltools = { 'xmltools.rb', true }, -- luatools = { 'luatools.lua', true }, mtxtools = { 'mtxtools.rb', true }, - pdftrimwhite = { 'pdftrimwhite.pl', false }, + pdftrimwhite = { 'pdftrimwhite.pl', false } } runners.launchers = { windows = { }, - unix = { }, + unix = { } } -- like runners.libpath("framework"): looks on script's subpath @@ -15802,7 +14487,7 @@ function runners.prepare() end local touchname = environment.argument("iftouched") if type(touchname) == "string" and touchname ~= "" then - local oldname, newname = string.splitup(touchname, ",") + local oldname, newname = string.split(touchname, ",") if oldname and newname and oldname ~= "" and newname ~= "" then if not file.needs_updating(oldname,newname) then if e_verbose then @@ -15836,11 +14521,11 @@ function runners.execute_script(fullname,internal,nosplit) if path ~= "" then result = fullname elseif name then - name = gsub(name,"^int[%a]*:",function() + name = name:gsub("^int[%a]*:",function() internal = true return "" end ) - name = gsub(name,"^script:","") + name = name:gsub("^script:","") if suffix == "" and runners.registered[name] and runners.registered[name][1] then name = runners.registered[name][1] suffix = file.extname(name) @@ -15870,15 +14555,13 @@ function runners.execute_script(fullname,internal,nosplit) environment.ownscript = result dofile(result) else + local quotedresult = result + if string.match(result,' ') and not string.match(result,"^\".*\"$") then quotedresult = '"' .. result .. '"' end local binary = runners.applications[file.extname(result)] - result = string.quoted(string.unquoted(result)) - -- if string.match(result,' ') and not string.match(result,"^\".*\"$") then - -- result = '"' .. result .. '"' - -- end if binary and binary ~= "" then - result = binary .. " " .. result + quotedresult = binary .. " " .. quotedresult end - local command = result .. " " .. environment.reconstructcommandline(environment.arguments_after,noquote) + local command = quotedresult .. " " .. environment.reconstructcommandline(environment.arguments_after,noquote) if e_verbose then report() report("executing: %s",command) @@ -15923,7 +14606,7 @@ function runners.execute_program(fullname) local before, after = environment.splitarguments(fullname) for k=1,#after do after[k] = resolvers.resolve(after[k]) end environment.initializearguments(after) - fullname = gsub(fullname,"^bin:","") + fullname = fullname:gsub("^bin:","") local command = fullname .. " " .. (environment.reconstructcommandline(after or "",noquote) or "") report() report("executing: %s",command) @@ -15984,24 +14667,10 @@ function runners.resolve_string(filename) end end --- differs from texmfstart where locate appends .com .exe .bat ... todo - -function runners.locate_file(filename) -- was given file but only searches in tree +function runners.locate_file(filename) + -- differs from texmfstart where locate appends .com .exe .bat ... todo if filename and filename ~= "" then - if environment.argument("first") then - runners.report_location(resolvers.findfile(filename)) - -- resolvers.dowithfilesandreport(resolvers.findfile,filename) - elseif environment.argument("all") then - local result, status = resolvers.findfiles(filename) - if status and environment.argument("detail") then - runners.report_location(status) - else - runners.report_location(result) - end - else - runners.report_location(resolvers.findgivenfile(filename)) - -- resolvers.dowithfilesandreport(resolvers.findgivenfile,filename) - end + runners.report_location(resolvers.findgivenfile(filename)) end end @@ -16010,12 +14679,12 @@ function runners.locate_platform() end function runners.report_location(result) - if type(result) == "table" then - for i=1,#result do - if i > 1 then - io.write("\n") - end - io.write(result[i]) + if e_verbose then + reportline() + if result and result ~= "" then + report(result) + else + report("not found") end else io.write(result) @@ -16073,8 +14742,8 @@ function resolvers.launch(str) end function runners.launch_file(filename) + instance.allresults = true trackers.enable("resolvers.locating") - local allresults = environment.arguments["all"] local pattern = environment.arguments["pattern"] if not pattern or pattern == "" then pattern = filename @@ -16082,15 +14751,15 @@ function runners.launch_file(filename) if not pattern or pattern == "" then report("provide name or --pattern=") else - local t = resolvers.findfiles(pattern,nil,allresults) + local t = resolvers.findfiles(pattern) if not t or #t == 0 then - t = resolvers.findfiles("*/" .. pattern,nil,allresults) + t = resolvers.findfiles("*/" .. pattern) end if not t or #t == 0 then - t = resolvers.findfiles("*/" .. pattern .. "*",nil,allresults) + t = resolvers.findfiles("*/" .. pattern .. "*") end if t and #t > 0 then - if allresults then + if environment.arguments["all"] then for _, v in pairs(t) do report("launching %s", v) resolvers.launch(v) @@ -16105,11 +14774,6 @@ function runners.launch_file(filename) end end -local mtxprefixes = { - { "^mtx%-", "mtx-" }, - { "^mtx%-t%-", "mtx-t-" }, -} - function runners.find_mtx_script(filename) local function found(name) local path = file.dirname(name) @@ -16135,27 +14799,24 @@ function runners.find_mtx_script(filename) return fullname end -- mtx- prefix checking - for i=1,#mtxprefixes do - local mtxprefix = mtxprefixes[i] - mtxprefix = find(filename,mtxprefix[1]) and "" or mtxprefix[2] - -- context namespace, mtx- - fullname = mtxprefix .. filename - fullname = found(fullname) or resolvers.findfile(fullname) - if fullname and fullname ~= "" then - return fullname - end - -- context namespace, mtx-s - fullname = mtxprefix .. basename .. "s" .. "." .. suffix - fullname = found(fullname) or resolvers.findfile(fullname) - if fullname and fullname ~= "" then - return fullname - end - -- context namespace, mtx- - fullname = mtxprefix .. gsub(basename,"s$","") .. "." .. suffix - fullname = found(fullname) or resolvers.findfile(fullname) - if fullname and fullname ~= "" then - return fullname - end + local mtxprefix = (filename:find("^mtx%-") and "") or "mtx-" + -- context namespace, mtx- + fullname = mtxprefix .. filename + fullname = found(fullname) or resolvers.findfile(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx-s + fullname = mtxprefix .. basename .. "s" .. "." .. suffix + fullname = found(fullname) or resolvers.findfile(fullname) + if fullname and fullname ~= "" then + return fullname + end + -- context namespace, mtx- + fullname = mtxprefix .. basename:gsub("s$","") .. "." .. suffix + fullname = found(fullname) or resolvers.findfile(fullname) + if fullname and fullname ~= "" then + return fullname end -- context namespace, just fullname = resolvers.findfile(filename) @@ -16302,11 +14963,9 @@ instance.lsrmode = environment.argument("lsr") or false local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))] -local e_argument = environment.argument - -if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then +if environment.argument("usekpse") or environment.argument("forcekpse") or is_mkii_stub then - resolvers.load_tree(e_argument('tree'),true) -- force resolve of TEXMFCNF + resolvers.load_tree(environment.argument('tree'),true) -- force resolve of TEXMFCNF os.setenv("engine","") os.setenv("progname","") @@ -16319,7 +14978,7 @@ if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then other = "other text files", } - local progname = e_argument("progname") or 'context' + local progname = environment.argument("progname") or 'context' local function kpse_initialized() texconfig.kpse_init = true @@ -16334,7 +14993,7 @@ if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then local findfile = resolvers.findfile local showpath = resolvers.showpath - if e_argument("forcekpse") then + if environment.argument("forcekpse") then function resolvers.findfile(name,kind) return (kpse_initialized():find_file(resolvers.cleanpath(name),(kind ~= "" and (remapper[kind] or kind)) or "tex") or "") or "" @@ -16343,7 +15002,7 @@ if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then return (kpse_initialized():show_path(name)) or "" end - elseif e_argument("usekpse") or is_mkii_stub then + elseif environment.argument("usekpse") or is_mkii_stub then resolvers.load() @@ -16382,12 +15041,12 @@ else end end - resolvers.load_tree(e_argument('tree'),e_argument("resolve")) + resolvers.load_tree(environment.argument('tree')) end -if e_argument("selfmerge") then +if environment.argument("selfmerge") then -- embed used libraries @@ -16397,27 +15056,27 @@ if e_argument("selfmerge") then utilities.merger.selfmerge(own.name,own.libs,{ found }) end -elseif e_argument("selfclean") then +elseif environment.argument("selfclean") then -- remove embedded libraries runners.loadbase() utilities.merger.selfclean(own.name) -elseif e_argument("selfupdate") then +elseif environment.argument("selfupdate") then runners.loadbase() trackers.enable("resolvers.locating") resolvers.updatescript(own.name,"mtxrun") -elseif e_argument("ctxlua") or e_argument("internal") then +elseif environment.argument("ctxlua") or environment.argument("internal") then -- run a script by loading it (using libs) runners.loadbase() ok = runners.execute_script(filename,true) -elseif e_argument("script") or e_argument("scripts") then +elseif environment.argument("script") or environment.argument("scripts") then -- run a script by loading it (using libs), pass args @@ -16428,110 +15087,109 @@ elseif e_argument("script") or e_argument("scripts") then ok = runners.execute_ctx_script(filename) end -elseif e_argument("execute") then +elseif environment.argument("execute") then -- execute script runners.loadbase() ok = runners.execute_script(filename) -elseif e_argument("direct") then +elseif environment.argument("direct") then -- equals bin: runners.loadbase() ok = runners.execute_program(filename) -elseif e_argument("edit") then +elseif environment.argument("edit") then -- edit file runners.loadbase() runners.edit_script(filename) -elseif e_argument("launch") then +elseif environment.argument("launch") then runners.loadbase() runners.launch_file(filename) -elseif e_argument("makestubs") then +elseif environment.argument("makestubs") then -- make stubs (depricated) runners.handle_stubs(true) -elseif e_argument("removestubs") then +elseif environment.argument("removestubs") then -- remove stub (depricated) runners.loadbase() runners.handle_stubs(false) -elseif e_argument("resolve") then +elseif environment.argument("resolve") then -- resolve string runners.loadbase() runners.resolve_string(filename) -elseif e_argument("locate") then +elseif environment.argument("locate") then - -- locate file (only database) + -- locate file runners.loadbase() runners.locate_file(filename) -elseif e_argument("platform") or e_argument("show-platform") then +elseif environment.argument("platform") or environment.argument("show-platform") then -- locate platform runners.loadbase() runners.locate_platform() -elseif e_argument("prefixes") then +elseif environment.argument("prefixes") then runners.loadbase() runners.prefixes() -elseif e_argument("timedrun") then +elseif environment.argument("timedrun") then -- locate platform runners.loadbase() runners.timedrun(filename) -elseif e_argument("variables") or e_argument("show-variables") or e_argument("expansions") or e_argument("show-expansions") then +elseif environment.argument("variables") or environment.argument("show-variables") or environment.argument("expansions") or environment.argument("show-expansions") then -- luatools: runners.execute_ctx_script("mtx-base","--expansions",filename) resolvers.load("nofiles") - resolvers.listers.variables(e_argument("pattern")) + resolvers.listers.variables(environment.argument("pattern")) -elseif e_argument("configurations") or e_argument("show-configurations") then +elseif environment.argument("configurations") or environment.argument("show-configurations") then -- luatools: runners.execute_ctx_script("mtx-base","--configurations",filename) resolvers.load("nofiles") resolvers.listers.configurations() -elseif e_argument("find-file") then +elseif environment.argument("find-file") then -- luatools: runners.execute_ctx_script("mtx-base","--find-file",filename) resolvers.load() - local e_all = e_argument("all") - local e_pattern = e_argument("pattern") - local e_format = e_argument("format") - local finder = e_all and resolvers.findfiles or resolvers.findfile + local e_pattern = environment.argument("pattern") + local e_format = environment.argument("format") if not e_pattern then runners.register_arguments(filename) environment.initializearguments(environment.arguments_after) - resolvers.dowithfilesandreport(finder,environment.files,e_format) + resolvers.dowithfilesandreport(resolvers.findfiles,environment.files,e_format) elseif type(e_pattern) == "string" then - resolvers.dowithfilesandreport(finder,{ e_pattern },e_format) + instance.allresults = true -- brrrr + resolvers.dowithfilesandreport(resolvers.findfiles,{ e_pattern }, e_format) end -elseif e_argument("find-path") then +elseif environment.argument("find-path") then -- luatools: runners.execute_ctx_script("mtx-base","--find-path",filename) @@ -16543,7 +15201,7 @@ elseif e_argument("find-path") then print(path) end -elseif e_argument("expand-braces") then +elseif environment.argument("expand-braces") then -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename) @@ -16552,7 +15210,7 @@ elseif e_argument("expand-braces") then environment.initializearguments(environment.arguments_after) resolvers.dowithfilesandreport(resolvers.expandbraces, environment.files) -elseif e_argument("expand-path") then +elseif environment.argument("expand-path") then -- luatools: runners.execute_ctx_script("mtx-base","--expand-path",filename) @@ -16561,7 +15219,7 @@ elseif e_argument("expand-path") then environment.initializearguments(environment.arguments_after) resolvers.dowithfilesandreport(resolvers.expandpath, environment.files) -elseif e_argument("expand-var") or e_argument("expand-variable") then +elseif environment.argument("expand-var") or environment.argument("expand-variable") then -- luatools: runners.execute_ctx_script("mtx-base","--expand-var",filename) @@ -16570,7 +15228,7 @@ elseif e_argument("expand-var") or e_argument("expand-variable") then environment.initializearguments(environment.arguments_after) resolvers.dowithfilesandreport(resolvers.expansion, environment.files) -elseif e_argument("show-path") or e_argument("path-value") then +elseif environment.argument("show-path") or environment.argument("path-value") then -- luatools: runners.execute_ctx_script("mtx-base","--show-path",filename) @@ -16579,7 +15237,7 @@ elseif e_argument("show-path") or e_argument("path-value") then environment.initializearguments(environment.arguments_after) resolvers.dowithfilesandreport(resolvers.showpath, environment.files) -elseif e_argument("var-value") or e_argument("show-value") then +elseif environment.argument("var-value") or environment.argument("show-value") then -- luatools: runners.execute_ctx_script("mtx-base","--show-value",filename) @@ -16588,36 +15246,28 @@ elseif e_argument("var-value") or e_argument("show-value") then environment.initializearguments(environment.arguments_after) resolvers.dowithfilesandreport(resolvers.variable,environment.files) -elseif e_argument("format-path") then +elseif environment.argument("format-path") then -- luatools: runners.execute_ctx_script("mtx-base","--format-path",filename) resolvers.load() report(caches.getwritablepath("format")) -elseif e_argument("pattern") then +elseif environment.argument("pattern") then -- luatools - runners.execute_ctx_script("mtx-base","--pattern='" .. e_argument("pattern") .. "'",filename) + runners.execute_ctx_script("mtx-base","--pattern='" .. environment.argument("pattern") .. "'",filename) -elseif e_argument("generate") then +elseif environment.argument("generate") then -- luatools - if filename and filename ~= "" then - resolvers.load("nofiles") - trackers.enable("resolvers.locating") - resolvers.renew(filename) - else - instance.renewcache = true - trackers.enable("resolvers.locating") - resolvers.load() - end - - e_verbose = true + instance.renewcache = true + trackers.enable("resolvers.locating") + resolvers.load() -elseif e_argument("make") or e_argument("ini") or e_argument("compile") then +elseif environment.argument("make") or environment.argument("ini") or environment.argument("compile") then -- luatools: runners.execute_ctx_script("mtx-base","--make",filename) @@ -16625,33 +15275,29 @@ elseif e_argument("make") or e_argument("ini") or e_argument("compile") then trackers.enable("resolvers.locating") environment.make_format(filename) -elseif e_argument("run") then +elseif environment.argument("run") then -- luatools runners.execute_ctx_script("mtx-base","--run",filename) -elseif e_argument("fmt") then +elseif environment.argument("fmt") then -- luatools runners.execute_ctx_script("mtx-base","--fmt",filename) -elseif e_argument("help") and filename=='base' then +elseif environment.argument("help") and filename=='base' then -- luatools runners.execute_ctx_script("mtx-base","--help") -elseif e_argument("version") then - - application.version() - -elseif e_argument("help") or filename=='help' or filename == "" then +elseif environment.argument("help") or filename=='help' or filename == "" then application.help() -elseif find(filename,"^bin:") then +elseif filename:find("^bin:") then runners.loadbase() ok = runners.execute_program(filename) diff --git a/Master/bin/i386-cygwin/odvicopy.exe b/Master/bin/i386-cygwin/odvicopy.exe index 691f3604200..49a25fa36e5 100755 Binary files a/Master/bin/i386-cygwin/odvicopy.exe and b/Master/bin/i386-cygwin/odvicopy.exe differ diff --git a/Master/bin/i386-cygwin/odvitype.exe b/Master/bin/i386-cygwin/odvitype.exe index 0c3194ee080..e6bc91c4a21 100755 Binary files a/Master/bin/i386-cygwin/odvitype.exe and b/Master/bin/i386-cygwin/odvitype.exe differ diff --git a/Master/bin/i386-cygwin/omfonts.exe b/Master/bin/i386-cygwin/omfonts.exe index 490209c62d5..3515158449b 100755 Binary files a/Master/bin/i386-cygwin/omfonts.exe and b/Master/bin/i386-cygwin/omfonts.exe differ diff --git a/Master/bin/i386-cygwin/otangle.exe b/Master/bin/i386-cygwin/otangle.exe index 9f4ee26a509..987564500d9 100755 Binary files a/Master/bin/i386-cygwin/otangle.exe and b/Master/bin/i386-cygwin/otangle.exe differ diff --git a/Master/bin/i386-cygwin/otfinfo.exe b/Master/bin/i386-cygwin/otfinfo.exe index d506140177d..ccf36d63e69 100755 Binary files a/Master/bin/i386-cygwin/otfinfo.exe and b/Master/bin/i386-cygwin/otfinfo.exe differ diff --git a/Master/bin/i386-cygwin/otftotfm.exe b/Master/bin/i386-cygwin/otftotfm.exe index a7a1369eb6e..81d1f6b9ee5 100755 Binary files a/Master/bin/i386-cygwin/otftotfm.exe and b/Master/bin/i386-cygwin/otftotfm.exe differ diff --git a/Master/bin/i386-cygwin/otp2ocp.exe b/Master/bin/i386-cygwin/otp2ocp.exe index c1117dfece6..f994252d1f0 100755 Binary files a/Master/bin/i386-cygwin/otp2ocp.exe and b/Master/bin/i386-cygwin/otp2ocp.exe differ diff --git a/Master/bin/i386-cygwin/outocp.exe b/Master/bin/i386-cygwin/outocp.exe index 6e64d60f614..dfc543206bf 100755 Binary files a/Master/bin/i386-cygwin/outocp.exe and b/Master/bin/i386-cygwin/outocp.exe differ diff --git a/Master/bin/i386-cygwin/patgen.exe b/Master/bin/i386-cygwin/patgen.exe index bcb2bb47fb5..1d5a5b471cb 100755 Binary files a/Master/bin/i386-cygwin/patgen.exe and b/Master/bin/i386-cygwin/patgen.exe differ diff --git a/Master/bin/i386-cygwin/pbibtex.exe b/Master/bin/i386-cygwin/pbibtex.exe index d485545d8a3..a8d9bb5641f 100755 Binary files a/Master/bin/i386-cygwin/pbibtex.exe and b/Master/bin/i386-cygwin/pbibtex.exe differ diff --git a/Master/bin/i386-cygwin/pdfclose.exe b/Master/bin/i386-cygwin/pdfclose.exe index b1525ac7f55..92a005b1f95 100755 Binary files a/Master/bin/i386-cygwin/pdfclose.exe and b/Master/bin/i386-cygwin/pdfclose.exe differ diff --git a/Master/bin/i386-cygwin/pdfopen.exe b/Master/bin/i386-cygwin/pdfopen.exe index 325d80ef0aa..67cba69fa03 100755 Binary files a/Master/bin/i386-cygwin/pdfopen.exe and b/Master/bin/i386-cygwin/pdfopen.exe differ diff --git a/Master/bin/i386-cygwin/pdftex.exe b/Master/bin/i386-cygwin/pdftex.exe index d9da786301c..b7bd48552f0 100755 Binary files a/Master/bin/i386-cygwin/pdftex.exe and b/Master/bin/i386-cygwin/pdftex.exe differ diff --git a/Master/bin/i386-cygwin/pdftosrc.exe b/Master/bin/i386-cygwin/pdftosrc.exe index eebe95a9570..d8ef9dfd2dc 100755 Binary files a/Master/bin/i386-cygwin/pdftosrc.exe and b/Master/bin/i386-cygwin/pdftosrc.exe differ diff --git a/Master/bin/i386-cygwin/pdvitype.exe b/Master/bin/i386-cygwin/pdvitype.exe index c773e73db9a..373fc8f577c 100755 Binary files a/Master/bin/i386-cygwin/pdvitype.exe and b/Master/bin/i386-cygwin/pdvitype.exe differ diff --git a/Master/bin/i386-cygwin/pfb2pfa.exe b/Master/bin/i386-cygwin/pfb2pfa.exe index 34025061e8d..1b373f6e956 100755 Binary files a/Master/bin/i386-cygwin/pfb2pfa.exe and b/Master/bin/i386-cygwin/pfb2pfa.exe differ diff --git a/Master/bin/i386-cygwin/pk2bm.exe b/Master/bin/i386-cygwin/pk2bm.exe index 7246fa53011..8941191e8dd 100755 Binary files a/Master/bin/i386-cygwin/pk2bm.exe and b/Master/bin/i386-cygwin/pk2bm.exe differ diff --git a/Master/bin/i386-cygwin/pktogf.exe b/Master/bin/i386-cygwin/pktogf.exe index 8d8bdb52b78..3c0e9a6d4d0 100755 Binary files a/Master/bin/i386-cygwin/pktogf.exe and b/Master/bin/i386-cygwin/pktogf.exe differ diff --git a/Master/bin/i386-cygwin/pktype.exe b/Master/bin/i386-cygwin/pktype.exe index 392cc6aea22..996553a7d34 100755 Binary files a/Master/bin/i386-cygwin/pktype.exe and b/Master/bin/i386-cygwin/pktype.exe differ diff --git a/Master/bin/i386-cygwin/pltotf.exe b/Master/bin/i386-cygwin/pltotf.exe index 7044773d0a6..1461c217028 100755 Binary files a/Master/bin/i386-cygwin/pltotf.exe and b/Master/bin/i386-cygwin/pltotf.exe differ diff --git a/Master/bin/i386-cygwin/pmx b/Master/bin/i386-cygwin/pmx new file mode 120000 index 00000000000..767c2118eb6 --- /dev/null +++ b/Master/bin/i386-cygwin/pmx @@ -0,0 +1 @@ +../../texmf-dist/scripts/pmx/pmx.lua \ No newline at end of file diff --git a/Master/bin/i386-cygwin/pmxab.exe b/Master/bin/i386-cygwin/pmxab.exe new file mode 100755 index 00000000000..cff371179ac Binary files /dev/null and b/Master/bin/i386-cygwin/pmxab.exe differ diff --git a/Master/bin/i386-cygwin/pooltype.exe b/Master/bin/i386-cygwin/pooltype.exe index 2c29b441c3d..5985c609839 100755 Binary files a/Master/bin/i386-cygwin/pooltype.exe and b/Master/bin/i386-cygwin/pooltype.exe differ diff --git a/Master/bin/i386-cygwin/ppltotf.exe b/Master/bin/i386-cygwin/ppltotf.exe index f5c381961a9..62ecb488bf9 100755 Binary files a/Master/bin/i386-cygwin/ppltotf.exe and b/Master/bin/i386-cygwin/ppltotf.exe differ diff --git a/Master/bin/i386-cygwin/prepmx.exe b/Master/bin/i386-cygwin/prepmx.exe new file mode 100755 index 00000000000..6cc35dbcb02 Binary files /dev/null and b/Master/bin/i386-cygwin/prepmx.exe differ diff --git a/Master/bin/i386-cygwin/ps2pk.exe b/Master/bin/i386-cygwin/ps2pk.exe index dc9a2b7a36a..bb8a7ed157f 100755 Binary files a/Master/bin/i386-cygwin/ps2pk.exe and b/Master/bin/i386-cygwin/ps2pk.exe differ diff --git a/Master/bin/i386-cygwin/psbook.exe b/Master/bin/i386-cygwin/psbook.exe index dfd6b09284c..1019a37d61d 100755 Binary files a/Master/bin/i386-cygwin/psbook.exe and b/Master/bin/i386-cygwin/psbook.exe differ diff --git a/Master/bin/i386-cygwin/psnup.exe b/Master/bin/i386-cygwin/psnup.exe index 058227e655b..3369a77578b 100755 Binary files a/Master/bin/i386-cygwin/psnup.exe and b/Master/bin/i386-cygwin/psnup.exe differ diff --git a/Master/bin/i386-cygwin/psresize.exe b/Master/bin/i386-cygwin/psresize.exe index 677d2af0012..9cab3defb8f 100755 Binary files a/Master/bin/i386-cygwin/psresize.exe and b/Master/bin/i386-cygwin/psresize.exe differ diff --git a/Master/bin/i386-cygwin/psselect.exe b/Master/bin/i386-cygwin/psselect.exe index 8fe8d0bc137..77aaedd43f8 100755 Binary files a/Master/bin/i386-cygwin/psselect.exe and b/Master/bin/i386-cygwin/psselect.exe differ diff --git a/Master/bin/i386-cygwin/pstops.exe b/Master/bin/i386-cygwin/pstops.exe index 73a0e2464ae..51bbbb2d8cd 100755 Binary files a/Master/bin/i386-cygwin/pstops.exe and b/Master/bin/i386-cygwin/pstops.exe differ diff --git a/Master/bin/i386-cygwin/ptex.exe b/Master/bin/i386-cygwin/ptex.exe index 045ed4ae073..8089bfcb2e7 100755 Binary files a/Master/bin/i386-cygwin/ptex.exe and b/Master/bin/i386-cygwin/ptex.exe differ diff --git a/Master/bin/i386-cygwin/ptftopl.exe b/Master/bin/i386-cygwin/ptftopl.exe index aacfeacb4cf..beee78e028d 100755 Binary files a/Master/bin/i386-cygwin/ptftopl.exe and b/Master/bin/i386-cygwin/ptftopl.exe differ diff --git a/Master/bin/i386-cygwin/scor2prt.exe b/Master/bin/i386-cygwin/scor2prt.exe new file mode 100755 index 00000000000..2fc0251fc04 Binary files /dev/null and b/Master/bin/i386-cygwin/scor2prt.exe differ diff --git a/Master/bin/i386-cygwin/sjisconv.exe b/Master/bin/i386-cygwin/sjisconv.exe index 9b56f3adc7a..788bf597832 100755 Binary files a/Master/bin/i386-cygwin/sjisconv.exe and b/Master/bin/i386-cygwin/sjisconv.exe differ diff --git a/Master/bin/i386-cygwin/sjislatex b/Master/bin/i386-cygwin/sjislatex index d794a7c7f5e..077eec710e0 100755 --- a/Master/bin/i386-cygwin/sjislatex +++ b/Master/bin/i386-cygwin/sjislatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/sjispdflatex b/Master/bin/i386-cygwin/sjispdflatex index 50daf343502..a1395cee780 100755 --- a/Master/bin/i386-cygwin/sjispdflatex +++ b/Master/bin/i386-cygwin/sjispdflatex @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1994-2008 Werner Lemberg +# Copyright (C) 1994-2012 Werner Lemberg # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/Master/bin/i386-cygwin/synctex.exe b/Master/bin/i386-cygwin/synctex.exe index 166d61928e7..80e8f474339 100755 Binary files a/Master/bin/i386-cygwin/synctex.exe and b/Master/bin/i386-cygwin/synctex.exe differ diff --git a/Master/bin/i386-cygwin/t1ascii.exe b/Master/bin/i386-cygwin/t1ascii.exe index 7b4971202d3..efd27638d40 100755 Binary files a/Master/bin/i386-cygwin/t1ascii.exe and b/Master/bin/i386-cygwin/t1ascii.exe differ diff --git a/Master/bin/i386-cygwin/t1asm.exe b/Master/bin/i386-cygwin/t1asm.exe index ae88e78b84e..eeb6e8b8bbc 100755 Binary files a/Master/bin/i386-cygwin/t1asm.exe and b/Master/bin/i386-cygwin/t1asm.exe differ diff --git a/Master/bin/i386-cygwin/t1binary.exe b/Master/bin/i386-cygwin/t1binary.exe index 0e7aa3cc89f..8e88df046fd 100755 Binary files a/Master/bin/i386-cygwin/t1binary.exe and b/Master/bin/i386-cygwin/t1binary.exe differ diff --git a/Master/bin/i386-cygwin/t1disasm.exe b/Master/bin/i386-cygwin/t1disasm.exe index 85b6096c0bb..bdff6606b74 100755 Binary files a/Master/bin/i386-cygwin/t1disasm.exe and b/Master/bin/i386-cygwin/t1disasm.exe differ diff --git a/Master/bin/i386-cygwin/t1dotlessj.exe b/Master/bin/i386-cygwin/t1dotlessj.exe index 0c6692bd569..9f114a08952 100755 Binary files a/Master/bin/i386-cygwin/t1dotlessj.exe and b/Master/bin/i386-cygwin/t1dotlessj.exe differ diff --git a/Master/bin/i386-cygwin/t1lint.exe b/Master/bin/i386-cygwin/t1lint.exe index 06428b4f797..98849165aef 100755 Binary files a/Master/bin/i386-cygwin/t1lint.exe and b/Master/bin/i386-cygwin/t1lint.exe differ diff --git a/Master/bin/i386-cygwin/t1mac.exe b/Master/bin/i386-cygwin/t1mac.exe index 48d3989c0c6..2c49f9b5ace 100755 Binary files a/Master/bin/i386-cygwin/t1mac.exe and b/Master/bin/i386-cygwin/t1mac.exe differ diff --git a/Master/bin/i386-cygwin/t1rawafm.exe b/Master/bin/i386-cygwin/t1rawafm.exe index 38f68349977..53058061087 100755 Binary files a/Master/bin/i386-cygwin/t1rawafm.exe and b/Master/bin/i386-cygwin/t1rawafm.exe differ diff --git a/Master/bin/i386-cygwin/t1reencode.exe b/Master/bin/i386-cygwin/t1reencode.exe index d0bb6ea5649..83aa62d07c6 100755 Binary files a/Master/bin/i386-cygwin/t1reencode.exe and b/Master/bin/i386-cygwin/t1reencode.exe differ diff --git a/Master/bin/i386-cygwin/t1testpage.exe b/Master/bin/i386-cygwin/t1testpage.exe index ee403c595f3..e0de8639282 100755 Binary files a/Master/bin/i386-cygwin/t1testpage.exe and b/Master/bin/i386-cygwin/t1testpage.exe differ diff --git a/Master/bin/i386-cygwin/t1unmac.exe b/Master/bin/i386-cygwin/t1unmac.exe index 148453ce8c0..d86f37e6d3e 100755 Binary files a/Master/bin/i386-cygwin/t1unmac.exe and b/Master/bin/i386-cygwin/t1unmac.exe differ diff --git a/Master/bin/i386-cygwin/t4ht.exe b/Master/bin/i386-cygwin/t4ht.exe index 7029c752aa3..c10b3671880 100755 Binary files a/Master/bin/i386-cygwin/t4ht.exe and b/Master/bin/i386-cygwin/t4ht.exe differ diff --git a/Master/bin/i386-cygwin/tangle.exe b/Master/bin/i386-cygwin/tangle.exe index 7077d9059aa..964bd520b3d 100755 Binary files a/Master/bin/i386-cygwin/tangle.exe and b/Master/bin/i386-cygwin/tangle.exe differ diff --git a/Master/bin/i386-cygwin/teckit_compile.exe b/Master/bin/i386-cygwin/teckit_compile.exe index 76587e8f55a..963ffbe595e 100755 Binary files a/Master/bin/i386-cygwin/teckit_compile.exe and b/Master/bin/i386-cygwin/teckit_compile.exe differ diff --git a/Master/bin/i386-cygwin/tex.exe b/Master/bin/i386-cygwin/tex.exe index ec340a9ac25..a97ed984ab7 100755 Binary files a/Master/bin/i386-cygwin/tex.exe and b/Master/bin/i386-cygwin/tex.exe differ diff --git a/Master/bin/i386-cygwin/tex4ht.exe b/Master/bin/i386-cygwin/tex4ht.exe index a835e0f1af7..16d8b0755da 100755 Binary files a/Master/bin/i386-cygwin/tex4ht.exe and b/Master/bin/i386-cygwin/tex4ht.exe differ diff --git a/Master/bin/i386-cygwin/texconfig-dialog b/Master/bin/i386-cygwin/texconfig-dialog index 8ccda930dd7..e1868d91574 100755 --- a/Master/bin/i386-cygwin/texconfig-dialog +++ b/Master/bin/i386-cygwin/texconfig-dialog @@ -21,8 +21,7 @@ export PATH test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"' # the version string -version=1184605103 # seconds since `00:00:00 1970-01-01 UTC' - # date '+%s' (with GNU date) +version='$Id: texconfig-dialog 23826 2011-09-05 17:59:15Z karl $' : ${PAGER=more} progname=texconfig-dialog @@ -82,24 +81,21 @@ logexec() ############################################################################### runDialog() { - termCtl clear if test -n "$DIALOG_PROG"; then + termCtl clear $DIALOG_PROG --title "TeX setup utility" ${1+"$@"} runDialogRc=$? + termCtl clear else - TERM=$DIALOG_TERM TERMINFO=$DIALOG_TERMINFO \ - tcdialog --title "TeX setup utility" ${1+"$@"} - runDialogRc=$? + abort "could not find dialog or whiptail program to run" fi - termCtl clear (exit $runDialogRc) return $runDialogRc } ############################################################################### # findDialog(void) -# Some systems have their own dialog. Use it then and do not use -# faked TERM and TERMINFO variables when calling that dialog. +# set DIALOG_PROG to the system dialog program, or the empty string. ############################################################################### findDialog() { @@ -111,11 +107,6 @@ findDialog() *) DIALOG_PROG=$binLoc; break;; esac done - case $DIALOG_PROG in - "") - : ${DIALOG_TERMINFO=$TEXMFMAIN/texconfig} - : ${DIALOG_TERM=generic} - esac } ############################################################################### diff --git a/Master/bin/i386-cygwin/tftopl.exe b/Master/bin/i386-cygwin/tftopl.exe index 4e3b6a5d781..007861b621c 100755 Binary files a/Master/bin/i386-cygwin/tftopl.exe and b/Master/bin/i386-cygwin/tftopl.exe differ diff --git a/Master/bin/i386-cygwin/tie.exe b/Master/bin/i386-cygwin/tie.exe index 9f113adc79f..ce51dd767fa 100755 Binary files a/Master/bin/i386-cygwin/tie.exe and b/Master/bin/i386-cygwin/tie.exe differ diff --git a/Master/bin/i386-cygwin/ttf2afm.exe b/Master/bin/i386-cygwin/ttf2afm.exe index 4f00b34db8a..1fbf181bbff 100755 Binary files a/Master/bin/i386-cygwin/ttf2afm.exe and b/Master/bin/i386-cygwin/ttf2afm.exe differ diff --git a/Master/bin/i386-cygwin/ttf2pk.exe b/Master/bin/i386-cygwin/ttf2pk.exe index 219bf80bb58..470189cb621 100755 Binary files a/Master/bin/i386-cygwin/ttf2pk.exe and b/Master/bin/i386-cygwin/ttf2pk.exe differ diff --git a/Master/bin/i386-cygwin/ttf2tfm.exe b/Master/bin/i386-cygwin/ttf2tfm.exe index d9376a9d76e..d0a6412556b 100755 Binary files a/Master/bin/i386-cygwin/ttf2tfm.exe and b/Master/bin/i386-cygwin/ttf2tfm.exe differ diff --git a/Master/bin/i386-cygwin/ttfdump.exe b/Master/bin/i386-cygwin/ttfdump.exe index 67f92596050..04ed5008506 100755 Binary files a/Master/bin/i386-cygwin/ttfdump.exe and b/Master/bin/i386-cygwin/ttfdump.exe differ diff --git a/Master/bin/i386-cygwin/ttftotype42.exe b/Master/bin/i386-cygwin/ttftotype42.exe index d51bb7978ef..8ef75173f93 100755 Binary files a/Master/bin/i386-cygwin/ttftotype42.exe and b/Master/bin/i386-cygwin/ttftotype42.exe differ diff --git a/Master/bin/i386-cygwin/upbibtex.exe b/Master/bin/i386-cygwin/upbibtex.exe index 90cb3969321..98e834e5214 100755 Binary files a/Master/bin/i386-cygwin/upbibtex.exe and b/Master/bin/i386-cygwin/upbibtex.exe differ diff --git a/Master/bin/i386-cygwin/updvitype.exe b/Master/bin/i386-cygwin/updvitype.exe index 88eca384f81..2dbe770dc3a 100755 Binary files a/Master/bin/i386-cygwin/updvitype.exe and b/Master/bin/i386-cygwin/updvitype.exe differ diff --git a/Master/bin/i386-cygwin/uppltotf.exe b/Master/bin/i386-cygwin/uppltotf.exe index cacfa54e5b0..9955835cdf9 100755 Binary files a/Master/bin/i386-cygwin/uppltotf.exe and b/Master/bin/i386-cygwin/uppltotf.exe differ diff --git a/Master/bin/i386-cygwin/uptex.exe b/Master/bin/i386-cygwin/uptex.exe index 97a3aeef572..e490ed3c616 100755 Binary files a/Master/bin/i386-cygwin/uptex.exe and b/Master/bin/i386-cygwin/uptex.exe differ diff --git a/Master/bin/i386-cygwin/uptftopl.exe b/Master/bin/i386-cygwin/uptftopl.exe index 1371e5d8020..2d53bb80122 100755 Binary files a/Master/bin/i386-cygwin/uptftopl.exe and b/Master/bin/i386-cygwin/uptftopl.exe differ diff --git a/Master/bin/i386-cygwin/vftovp.exe b/Master/bin/i386-cygwin/vftovp.exe index c8c7ba81f26..38826c0d9be 100755 Binary files a/Master/bin/i386-cygwin/vftovp.exe and b/Master/bin/i386-cygwin/vftovp.exe differ diff --git a/Master/bin/i386-cygwin/vlna.exe b/Master/bin/i386-cygwin/vlna.exe index 555d0b7440b..3e33f83807e 100755 Binary files a/Master/bin/i386-cygwin/vlna.exe and b/Master/bin/i386-cygwin/vlna.exe differ diff --git a/Master/bin/i386-cygwin/vptovf.exe b/Master/bin/i386-cygwin/vptovf.exe index 2ec0659ced4..f7f1ede9f41 100755 Binary files a/Master/bin/i386-cygwin/vptovf.exe and b/Master/bin/i386-cygwin/vptovf.exe differ diff --git a/Master/bin/i386-cygwin/weave.exe b/Master/bin/i386-cygwin/weave.exe index be1b52c82fb..051bcf51e09 100755 Binary files a/Master/bin/i386-cygwin/weave.exe and b/Master/bin/i386-cygwin/weave.exe differ diff --git a/Master/bin/i386-cygwin/xdvi-xaw.exe b/Master/bin/i386-cygwin/xdvi-xaw.exe index feec8023b37..31cc14b1cbd 100755 Binary files a/Master/bin/i386-cygwin/xdvi-xaw.exe and b/Master/bin/i386-cygwin/xdvi-xaw.exe differ diff --git a/Master/bin/i386-cygwin/xdvipdfmx.exe b/Master/bin/i386-cygwin/xdvipdfmx.exe index 27b9a374352..5125de7e4d4 100755 Binary files a/Master/bin/i386-cygwin/xdvipdfmx.exe and b/Master/bin/i386-cygwin/xdvipdfmx.exe differ diff --git a/Master/bin/i386-cygwin/xetex.exe b/Master/bin/i386-cygwin/xetex.exe index 19bf6088d32..bd42b664ef5 100755 Binary files a/Master/bin/i386-cygwin/xetex.exe and b/Master/bin/i386-cygwin/xetex.exe differ -- cgit v1.2.3