From 178de0871d690556af74f3768c11bc812b07f347 Mon Sep 17 00:00:00 2001 From: Taco Hoekwater Date: Fri, 27 Mar 2009 15:30:55 +0000 Subject: Import of luatex 0.37.0 (autoreconf has not been run yet!) git-svn-id: svn://tug.org/texlive/trunk@12529 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/ChangeLog | 5 + Build/source/texk/web2c/configure.ac | 2 +- Build/source/texk/web2c/luatexdir/ChangeLog | 5 + Build/source/texk/web2c/luatexdir/Makefile.in | 50 +- Build/source/texk/web2c/luatexdir/NEWS | 2922 +- Build/source/texk/web2c/luatexdir/am/luatex.am | 426 +- Build/source/texk/web2c/luatexdir/avl.c | 893 - Build/source/texk/web2c/luatexdir/avlstuff.c | 180 - Build/source/texk/web2c/luatexdir/avlstuff.h | 29 - Build/source/texk/web2c/luatexdir/commands.h | 550 + Build/source/texk/web2c/luatexdir/depend.mk | 3 - Build/source/texk/web2c/luatexdir/font/dofont.c | 275 +- Build/source/texk/web2c/luatexdir/font/luafont.c | 3445 +- .../source/texk/web2c/luatexdir/font/luatexfont.h | 67 + Build/source/texk/web2c/luatexdir/font/macnames.c | 33 +- Build/source/texk/web2c/luatexdir/font/mapfile.c | 302 +- Build/source/texk/web2c/luatexdir/font/pkin.c | 48 +- Build/source/texk/web2c/luatexdir/font/sfnt.c | 880 +- Build/source/texk/web2c/luatexdir/font/sfnt.h | 331 +- Build/source/texk/web2c/luatexdir/font/subfont.c | 226 +- Build/source/texk/web2c/luatexdir/font/texfont.c | 2373 +- Build/source/texk/web2c/luatexdir/font/texfont.h | 805 +- Build/source/texk/web2c/luatexdir/font/tfmofm.c | 1161 +- Build/source/texk/web2c/luatexdir/font/tounicode.c | 96 +- Build/source/texk/web2c/luatexdir/font/tt_glyf.c | 1123 +- Build/source/texk/web2c/luatexdir/font/tt_glyf.h | 97 +- Build/source/texk/web2c/luatexdir/font/tt_table.c | 787 +- Build/source/texk/web2c/luatexdir/font/tt_table.h | 310 +- Build/source/texk/web2c/luatexdir/font/vfovf.c | 2617 +- Build/source/texk/web2c/luatexdir/font/writecff.c | 5359 +-- Build/source/texk/web2c/luatexdir/font/writecff.h | 461 +- Build/source/texk/web2c/luatexdir/font/writeenc.c | 39 +- Build/source/texk/web2c/luatexdir/font/writefont.c | 662 +- Build/source/texk/web2c/luatexdir/font/writet3.c | 360 +- Build/source/texk/web2c/luatexdir/font/writettf.c | 1116 +- Build/source/texk/web2c/luatexdir/font/writettf.h | 212 +- .../source/texk/web2c/luatexdir/font/writetype0.c | 213 +- .../source/texk/web2c/luatexdir/font/writetype2.c | 642 +- .../source/texk/web2c/luatexdir/get_svnversion.sh | 13 + Build/source/texk/web2c/luatexdir/hyphen.h | 35 +- Build/source/texk/web2c/luatexdir/image/epdf.c | 42 +- Build/source/texk/web2c/luatexdir/image/epdf.h | 43 +- Build/source/texk/web2c/luatexdir/image/image.h | 81 +- .../source/texk/web2c/luatexdir/image/pdftoepdf.cc | 333 +- Build/source/texk/web2c/luatexdir/image/writeimg.c | 496 +- .../source/texk/web2c/luatexdir/image/writejbig2.c | 52 +- .../source/texk/web2c/luatexdir/image/writejbig2.h | 32 +- Build/source/texk/web2c/luatexdir/image/writejpg.c | 36 +- Build/source/texk/web2c/luatexdir/image/writepng.c | 129 +- Build/source/texk/web2c/luatexdir/lang/hyphen.c | 48 +- Build/source/texk/web2c/luatexdir/lang/texlang.c | 1498 +- .../source/texk/web2c/luatexdir/lua/lcallbacklib.c | 863 +- Build/source/texk/web2c/luatexdir/lua/lfontlib.c | 378 +- Build/source/texk/web2c/luatexdir/lua/limglib.c | 269 +- Build/source/texk/web2c/luatexdir/lua/lkpselib.c | 614 +- Build/source/texk/web2c/luatexdir/lua/llanglib.c | 401 +- Build/source/texk/web2c/luatexdir/lua/llualib.c | 486 +- Build/source/texk/web2c/luatexdir/lua/lmplib.c | 1273 - Build/source/texk/web2c/luatexdir/lua/lnodelib.c | 4679 +- Build/source/texk/web2c/luatexdir/lua/loslibext.c | 1168 +- Build/source/texk/web2c/luatexdir/lua/lpdflib.c | 42 +- Build/source/texk/web2c/luatexdir/lua/lstatslib.c | 383 +- Build/source/texk/web2c/luatexdir/lua/ltexiolib.c | 231 +- Build/source/texk/web2c/luatexdir/lua/ltexlib.c | 2138 +- Build/source/texk/web2c/luatexdir/lua/ltokenlib.c | 437 +- Build/source/texk/web2c/luatexdir/lua/luainit.c | 902 +- Build/source/texk/web2c/luatexdir/lua/luanode.c | 401 +- Build/source/texk/web2c/luatexdir/lua/luastuff.c | 616 +- Build/source/texk/web2c/luatexdir/lua/luatex.c | 534 +- Build/source/texk/web2c/luatexdir/lua/luatoken.c | 1072 +- Build/source/texk/web2c/luatexdir/lua/mp.w | 26202 ----------- Build/source/texk/web2c/luatexdir/lua/psout.w | 5686 --- Build/source/texk/web2c/luatexdir/lua/texluac.c | 324 +- Build/source/texk/web2c/luatexdir/lua51/Makefile | 13 +- Build/source/texk/web2c/luatexdir/lua51/lcoco.c | 10 + Build/source/texk/web2c/luatexdir/lua51/lcoco.h | 10 + Build/source/texk/web2c/luatexdir/lua51/liolib.c | 29 +- Build/source/texk/web2c/luatexdir/lua51/lobject.c | 8 +- Build/source/texk/web2c/luatexdir/lua51/lstrlib.c | 30 +- .../texk/web2c/luatexdir/luafilesystem/Makefile | 50 +- .../web2c/luatexdir/luafilesystem/Makefile.win | 25 + .../texk/web2c/luatexdir/luafilesystem/README | 38 + .../texk/web2c/luatexdir/luafilesystem/config | 44 +- .../texk/web2c/luatexdir/luafilesystem/config.win | 19 + .../luatexdir/luafilesystem/doc/us/examples.html | 8 +- .../luatexdir/luafilesystem/doc/us/index.html | 69 +- .../luatexdir/luafilesystem/doc/us/license.html | 10 +- .../luatexdir/luafilesystem/doc/us/manual.html | 69 +- .../texk/web2c/luatexdir/luafilesystem/src/lfs.c | 176 +- .../texk/web2c/luatexdir/luafilesystem/src/lfs.def | 5 + .../texk/web2c/luatexdir/luafilesystem/src/lfs.h | 5 +- .../web2c/luatexdir/luafilesystem/tests/test.lua | 193 +- .../texk/web2c/luatexdir/luafontforge/ChangeLog | 5 - .../texk/web2c/luatexdir/luafontforge/Makefile | 25 - .../texk/web2c/luatexdir/luafontforge/ff-config.in | 47 - .../web2c/luatexdir/luafontforge/fontforge/AUTHORS | 1 - .../web2c/luatexdir/luafontforge/fontforge/INSTALL | 182 - .../web2c/luatexdir/luafontforge/fontforge/LICENSE | 28 - .../luatexdir/luafontforge/fontforge/Makefile | 112 - .../luafontforge/fontforge/Unicode/Makefile | 15 - .../luafontforge/fontforge/Unicode/alphabet.c | 3348 -- .../luafontforge/fontforge/Unicode/char.c | 103 - .../luatexdir/luafontforge/fontforge/Unicode/cjk.c | 43041 ------------------- .../luafontforge/fontforge/Unicode/descrip.mms | 27 - .../luafontforge/fontforge/Unicode/gwwiconv.c | 1074 - .../luafontforge/fontforge/Unicode/memory.c | 90 - .../luafontforge/fontforge/Unicode/ustring.c | 885 - .../web2c/luatexdir/luafontforge/fontforge/VERSION | 1 - .../luatexdir/luafontforge/fontforge/descrip.mms | 9 - .../luafontforge/fontforge/fontforge/Makefile | 36 - .../luafontforge/fontforge/fontforge/autohint.c | 3528 -- .../luafontforge/fontforge/fontforge/charview.c | 9513 ---- .../fontforge/fontforge/configure-pfaedit.h | 292 - .../fontforge/fontforge/contextchain.c | 3032 -- .../luafontforge/fontforge/fontforge/descrip.mms | 197 - .../luafontforge/fontforge/fontforge/edgelist.h | 146 - .../luafontforge/fontforge/fontforge/edgelist2.h | 54 - .../luafontforge/fontforge/fontforge/encoding.c | 3093 -- .../luafontforge/fontforge/fontforge/featurefile.c | 5539 --- .../luafontforge/fontforge/fontforge/fontinfo.c | 10184 ----- .../luafontforge/fontforge/fontforge/fontview.c | 11163 ----- .../luafontforge/fontforge/fontforge/fvfonts.c | 1911 - .../luafontforge/fontforge/fontforge/groups.h | 49 - .../luafontforge/fontforge/fontforge/kernclass.c | 3059 -- .../luafontforge/fontforge/fontforge/lff.opt | 1 - .../luafontforge/fontforge/fontforge/lookups.c | 6916 --- .../luafontforge/fontforge/fontforge/macbinary.c | 3212 -- .../luafontforge/fontforge/fontforge/macenc.c | 3601 -- .../luafontforge/fontforge/fontforge/namelist.c | 19852 --------- .../luafontforge/fontforge/fontforge/ofl.h | 7 - .../luafontforge/fontforge/fontforge/parsepfa.c | 2762 -- .../luafontforge/fontforge/fontforge/parsettf.c | 5558 --- .../luafontforge/fontforge/fontforge/parsettfatt.c | 4635 -- .../luafontforge/fontforge/fontforge/parsettfvar.c | 778 - .../luafontforge/fontforge/fontforge/pfaedit.h | 111 - .../luafontforge/fontforge/fontforge/pfaeditui.h | 189 - .../luafontforge/fontforge/fontforge/plugins.h | 99 - .../luafontforge/fontforge/fontforge/prefs.c | 2282 - .../luafontforge/fontforge/fontforge/psfont.h | 191 - .../luafontforge/fontforge/fontforge/psread.c | 4671 -- .../luafontforge/fontforge/fontforge/pua.c | 1612 - .../luafontforge/fontforge/fontforge/scriptfuncs.h | 39 - .../luafontforge/fontforge/fontforge/scripting.h | 129 - .../luafontforge/fontforge/fontforge/sd.h | 170 - .../luafontforge/fontforge/fontforge/sfd1.h | 112 - .../luafontforge/fontforge/fontforge/splinefill.c | 1864 - .../luafontforge/fontforge/fontforge/splinefont.h | 2303 - .../fontforge/fontforge/splineorder2.c | 1484 - .../fontforge/fontforge/splineoverlap.c | 2527 -- .../fontforge/fontforge/splinerefigure.c | 101 - .../luafontforge/fontforge/fontforge/splinesave.c | 3616 -- .../fontforge/fontforge/splinestroke.c | 1987 - .../luafontforge/fontforge/fontforge/splineutil.c | 5776 --- .../luafontforge/fontforge/fontforge/splineutil2.c | 4069 -- .../luafontforge/fontforge/fontforge/stamp.c | 5 - .../luafontforge/fontforge/fontforge/stamper.c | 20 - .../luafontforge/fontforge/fontforge/start.c | 935 - .../luafontforge/fontforge/fontforge/stemdb.c | 2428 -- .../luafontforge/fontforge/fontforge/stemdb.h | 153 - .../luafontforge/fontforge/fontforge/tottf.c | 5768 --- .../luafontforge/fontforge/fontforge/tottfgpos.c | 3444 -- .../luafontforge/fontforge/fontforge/tottfvar.c | 814 - .../luafontforge/fontforge/fontforge/ttf.h | 831 - .../luafontforge/fontforge/fontforge/ttfspecial.c | 1067 - .../fontforge/fontforge/unicoderange.h | 47 - .../luafontforge/fontforge/fontforge/views.h | 1420 - .../luafontforge/fontforge/fontforge/xlib.opt | 13 - .../luatexdir/luafontforge/fontforge/inc/basics.h | 80 - .../luafontforge/fontforge/inc/chardata.h | 78 - .../luatexdir/luafontforge/fontforge/inc/charset.h | 71 - .../luatexdir/luafontforge/fontforge/inc/dynamic.h | 35 - .../luafontforge/fontforge/inc/fileutil.h | 43 - .../luatexdir/luafontforge/fontforge/inc/gdraw.h | 593 - .../luatexdir/luafontforge/fontforge/inc/gfile.h | 62 - .../luatexdir/luafontforge/fontforge/inc/ggadget.h | 484 - .../luatexdir/luafontforge/fontforge/inc/gicons.h | 52 - .../luatexdir/luafontforge/fontforge/inc/gio.h | 109 - .../luatexdir/luafontforge/fontforge/inc/gkeysym.h | 298 - .../luafontforge/fontforge/inc/gprogress.h | 77 - .../luafontforge/fontforge/inc/gresource.h | 58 - .../luatexdir/luafontforge/fontforge/inc/gwidget.h | 215 - .../luafontforge/fontforge/inc/gwwiconv.h | 55 - .../luatexdir/luafontforge/fontforge/inc/intl.h | 85 - .../luatexdir/luafontforge/fontforge/inc/ustring.h | 128 - .../luatexdir/luafontforge/fontforge/inc/utype.h | 115 - .../web2c/luatexdir/luafontforge/src/ffdummies.c | 5552 --- .../web2c/luatexdir/luafontforge/src/luafflib.c | 1789 - .../texk/web2c/luatexdir/luafontloader/ChangeLog | 5 + .../web2c/luatexdir/luafontloader/ff-config.in | 49 + .../luatexdir/luafontloader/fontforge/AUTHORS | 1 + .../luatexdir/luafontloader/fontforge/INSTALL | 182 + .../luatexdir/luafontloader/fontforge/LICENSE | 29 + .../luatexdir/luafontloader/fontforge/Makefile.in | 160 + .../luafontloader/fontforge/Unicode/ArabicForms.c | 260 + .../luafontloader/fontforge/Unicode/Makefile.in | 36 + .../luafontloader/fontforge/Unicode/alphabet.c | 3348 ++ .../luafontloader/fontforge/Unicode/backtrns.c | 7434 ++++ .../luafontloader/fontforge/Unicode/char.c | 96 + .../luafontloader/fontforge/Unicode/cjk.c | 43019 ++++++++++++++++++ .../luafontloader/fontforge/Unicode/combiners.h | 1014 + .../luafontloader/fontforge/Unicode/dump.c | 994 + .../luafontloader/fontforge/Unicode/gwwiconv.c | 1076 + .../luafontloader/fontforge/Unicode/memory.c | 90 + .../luafontloader/fontforge/Unicode/ucharmap.c | 675 + .../luafontloader/fontforge/Unicode/unialt.c | 8885 ++++ .../luafontloader/fontforge/Unicode/ustring.c | 890 + .../luafontloader/fontforge/Unicode/utype.c | 24588 +++++++++++ .../luatexdir/luafontloader/fontforge/VERSION | 1 + .../luafontloader/fontforge/configure-options | 1 + .../luatexdir/luafontloader/fontforge/configure.in | 704 + .../luafontloader/fontforge/fontforge/Makefile.in | 71 + .../luafontloader/fontforge/fontforge/PfEd.h | 218 + .../luafontloader/fontforge/fontforge/autohint.c | 2143 + .../luafontloader/fontforge/fontforge/baseviews.h | 541 + .../luafontloader/fontforge/fontforge/clipnoui.c | 68 + .../fontforge/fontforge/configure-pfaedit.h | 292 + .../luafontloader/fontforge/fontforge/cvundoes.c | 134 + .../luafontloader/fontforge/fontforge/dumppfa.c | 221 + .../luafontloader/fontforge/fontforge/edgelist.h | 149 + .../luafontloader/fontforge/fontforge/edgelist2.h | 49 + .../luafontloader/fontforge/fontforge/encoding.c | 1152 + .../luafontloader/fontforge/fontforge/encoding.h | 18 + .../fontforge/fontforge/featurefile.c | 4208 ++ .../fontforge/fontforge/fontforgevw.h | 34 + .../fontforge/fontforge/fontviewbase.c | 286 + .../luafontloader/fontforge/fontforge/fvcomposit.c | 160 + .../luafontloader/fontforge/fontforge/fvfonts.c | 572 + .../luafontloader/fontforge/fontforge/libffstamp.h | 3 + .../luafontloader/fontforge/fontforge/libstamp.pre | 103 + .../luafontloader/fontforge/fontforge/lookups.c | 4468 ++ .../luafontloader/fontforge/fontforge/lookups.h | 2 + .../luafontloader/fontforge/fontforge/macbinary.c | 1201 + .../luafontloader/fontforge/fontforge/macenc.c | 2244 + .../fontforge/fontforge/mathconstants.c | 99 + .../luafontloader/fontforge/fontforge/mm.c | 235 + .../luafontloader/fontforge/fontforge/mm.h | 32 + .../luafontloader/fontforge/fontforge/namelist.c | 19799 +++++++++ .../luafontloader/fontforge/fontforge/noprefs.c | 602 + .../luafontloader/fontforge/fontforge/nouiutil.c | 203 + .../luafontloader/fontforge/fontforge/parsepfa.c | 2740 ++ .../luafontloader/fontforge/fontforge/parsettf.c | 6489 +++ .../fontforge/fontforge/parsettfatt.c | 5594 +++ .../fontforge/fontforge/parsettfvar.c | 771 + .../luafontloader/fontforge/fontforge/pfaedit.h | 103 + .../luafontloader/fontforge/fontforge/plugins.h | 99 + .../luafontloader/fontforge/fontforge/psfont.h | 191 + .../luafontloader/fontforge/fontforge/psread.c | 4123 ++ .../luafontloader/fontforge/fontforge/pua.c | 1612 + .../luafontloader/fontforge/fontforge/python.c | 320 + .../luafontloader/fontforge/fontforge/scripting.h | 140 + .../luafontloader/fontforge/fontforge/sd.h | 163 + .../luafontloader/fontforge/fontforge/sfd1.c | 48 + .../luafontloader/fontforge/fontforge/sfd1.h | 112 + .../luafontloader/fontforge/fontforge/splinechar.c | 266 + .../luafontloader/fontforge/fontforge/splinefill.c | 535 + .../luafontloader/fontforge/fontforge/splinefont.c | 642 + .../luafontloader/fontforge/fontforge/splinefont.h | 3044 ++ .../fontforge/fontforge/splineorder2.c | 1508 + .../fontforge/fontforge/splineoverlap.c | 2396 ++ .../fontforge/fontforge/splinerefigure.c | 101 + .../luafontloader/fontforge/fontforge/splinesave.c | 3121 ++ .../fontforge/fontforge/splinesaveafm.c | 261 + .../fontforge/fontforge/splinestroke.c | 1875 + .../luafontloader/fontforge/fontforge/splineutil.c | 4624 ++ .../fontforge/fontforge/splineutil2.c | 2329 + .../luafontloader/fontforge/fontforge/start.c | 77 + .../luafontloader/fontforge/fontforge/stemdb.c | 40 + .../luafontloader/fontforge/fontforge/stemdb.h | 210 + .../luafontloader/fontforge/fontforge/tottf.c | 2048 + .../luafontloader/fontforge/fontforge/tottfaat.c | 134 + .../luafontloader/fontforge/fontforge/tottfgpos.c | 366 + .../luafontloader/fontforge/fontforge/ttf.h | 888 + .../luafontloader/fontforge/fontforge/ttfspecial.c | 903 + .../fontforge/fontforge/uiinterface.h | 511 + .../fontforge/fontforge/unicoderange.h | 38 + .../luafontloader/fontforge/fontforge/views.h | 1087 + .../luafontloader/fontforge/gdraw/Makefile.in | 0 .../luafontloader/fontforge/gutils/Makefile.in | 45 + .../luafontloader/fontforge/gutils/fsys.c | 487 + .../luafontloader/fontforge/gutils/gwwintl.c | 136 + .../luatexdir/luafontloader/fontforge/inc/basics.h | 78 + .../luafontloader/fontforge/inc/chardata.h | 78 + .../luafontloader/fontforge/inc/charset.h | 71 + .../luafontloader/fontforge/inc/config.h.in | 67 + .../luafontloader/fontforge/inc/dynamic.h | 62 + .../luafontloader/fontforge/inc/fileutil.h | 43 + .../luatexdir/luafontloader/fontforge/inc/gdraw.h | 532 + .../luatexdir/luafontloader/fontforge/inc/gfile.h | 62 + .../luafontloader/fontforge/inc/ggadget.h | 509 + .../luatexdir/luafontloader/fontforge/inc/gicons.h | 58 + .../luatexdir/luafontloader/fontforge/inc/gimage.h | 168 + .../luatexdir/luafontloader/fontforge/inc/gio.h | 109 + .../luafontloader/fontforge/inc/gkeysym.h | 298 + .../luafontloader/fontforge/inc/gprogress.h | 79 + .../luafontloader/fontforge/inc/gresource.h | 58 + .../luafontloader/fontforge/inc/gwidget.h | 222 + .../luafontloader/fontforge/inc/gwwiconv.h | 56 + .../luatexdir/luafontloader/fontforge/inc/intl.h | 107 + .../luafontloader/fontforge/inc/ustring.h | 129 + .../luatexdir/luafontloader/fontforge/inc/utype.h | 100 + .../luafontloader/fontforge/plugins/Makefile.in | 0 .../web2c/luatexdir/luafontloader/src/ffdummies.c | 256 + .../web2c/luatexdir/luafontloader/src/luafflib.c | 2379 + .../texk/web2c/luatexdir/luaprofiler/Makefile | 19 + .../texk/web2c/luatexdir/luaprofiler/clocks.c | 63 + .../texk/web2c/luatexdir/luaprofiler/clocks.h | 20 + .../web2c/luatexdir/luaprofiler/core_profiler.c | 180 + .../web2c/luatexdir/luaprofiler/core_profiler.h | 31 + .../web2c/luatexdir/luaprofiler/function_meter.c | 203 + .../web2c/luatexdir/luaprofiler/function_meter.h | 64 + .../web2c/luatexdir/luaprofiler/lua50_profiler.c | 230 + .../texk/web2c/luatexdir/luaprofiler/luaprofiler.h | 14 + .../texk/web2c/luatexdir/luaprofiler/stack.c | 33 + .../texk/web2c/luatexdir/luaprofiler/stack.h | 44 + .../source/texk/web2c/luatexdir/luasocket/LICENSE | 20 + Build/source/texk/web2c/luatexdir/luasocket/NEW | 14 + Build/source/texk/web2c/luatexdir/luasocket/README | 6 + Build/source/texk/web2c/luatexdir/luasocket/config | 60 + .../texk/web2c/luatexdir/luasocket/doc/dns.html | 132 + .../texk/web2c/luatexdir/luasocket/doc/ftp.html | 289 + .../texk/web2c/luatexdir/luasocket/doc/http.html | 333 + .../texk/web2c/luatexdir/luasocket/doc/index.html | 208 + .../luatexdir/luasocket/doc/installation.html | 163 + .../luatexdir/luasocket/doc/introduction.html | 333 + .../texk/web2c/luatexdir/luasocket/doc/ltn12.html | 430 + .../web2c/luatexdir/luasocket/doc/luasocket.png | Bin 0 -> 11732 bytes .../texk/web2c/luatexdir/luasocket/doc/mime.html | 476 + .../web2c/luatexdir/luasocket/doc/reference.css | 54 + .../web2c/luatexdir/luasocket/doc/reference.html | 239 + .../texk/web2c/luatexdir/luasocket/doc/smtp.html | 417 + .../texk/web2c/luatexdir/luasocket/doc/socket.html | 404 + .../texk/web2c/luatexdir/luasocket/doc/tcp.html | 533 + .../texk/web2c/luatexdir/luasocket/doc/udp.html | 416 + .../texk/web2c/luatexdir/luasocket/doc/url.html | 329 + .../texk/web2c/luatexdir/luasocket/etc/README | 89 + .../texk/web2c/luatexdir/luasocket/etc/b64.lua | 20 + .../web2c/luatexdir/luasocket/etc/check-links.lua | 112 + .../web2c/luatexdir/luasocket/etc/check-memory.lua | 17 + .../texk/web2c/luatexdir/luasocket/etc/dict.lua | 152 + .../web2c/luatexdir/luasocket/etc/dispatch.lua | 302 + .../texk/web2c/luatexdir/luasocket/etc/eol.lua | 14 + .../texk/web2c/luatexdir/luasocket/etc/forward.lua | 65 + .../texk/web2c/luatexdir/luasocket/etc/get.lua | 142 + .../texk/web2c/luatexdir/luasocket/etc/lp.lua | 324 + .../texk/web2c/luatexdir/luasocket/etc/qp.lua | 24 + .../texk/web2c/luatexdir/luasocket/etc/tftp.lua | 155 + .../texk/web2c/luatexdir/luasocket/luasocket.sln | 37 + .../source/texk/web2c/luatexdir/luasocket/makefile | 51 + .../texk/web2c/luatexdir/luasocket/mime.vcproj | 141 + .../texk/web2c/luatexdir/luasocket/samples/README | 50 + .../web2c/luatexdir/luasocket/samples/cddb.lua | 46 + .../luatexdir/luasocket/samples/daytimeclnt.lua | 23 + .../web2c/luatexdir/luasocket/samples/echoclnt.lua | 24 + .../web2c/luatexdir/luasocket/samples/echosrvr.lua | 29 + .../web2c/luatexdir/luasocket/samples/listener.lua | 26 + .../texk/web2c/luatexdir/luasocket/samples/lpr.lua | 51 + .../web2c/luatexdir/luasocket/samples/talker.lua | 21 + .../web2c/luatexdir/luasocket/samples/tinyirc.lua | 90 + .../texk/web2c/luatexdir/luasocket/socket.vcproj | 182 + .../texk/web2c/luatexdir/luasocket/src/Makefile | 63 + .../texk/web2c/luatexdir/luasocket/src/auxiliar.c | 149 + .../texk/web2c/luatexdir/luasocket/src/auxiliar.h | 48 + .../texk/web2c/luatexdir/luasocket/src/buffer.c | 268 + .../texk/web2c/luatexdir/luasocket/src/buffer.h | 47 + .../texk/web2c/luatexdir/luasocket/src/except.c | 99 + .../texk/web2c/luatexdir/luasocket/src/except.h | 35 + .../texk/web2c/luatexdir/luasocket/src/ftp.lua | 281 + .../texk/web2c/luatexdir/luasocket/src/ftp_lua.c | 470 + .../texk/web2c/luatexdir/luasocket/src/http.lua | 350 + .../texk/web2c/luatexdir/luasocket/src/http_lua.c | 623 + .../texk/web2c/luatexdir/luasocket/src/inet.c | 285 + .../texk/web2c/luatexdir/luasocket/src/inet.h | 42 + .../source/texk/web2c/luatexdir/luasocket/src/io.c | 32 + .../source/texk/web2c/luatexdir/luasocket/src/io.h | 67 + .../texk/web2c/luatexdir/luasocket/src/ltn12.lua | 292 + .../texk/web2c/luatexdir/luasocket/src/ltn12_lua.c | 422 + .../web2c/luatexdir/luasocket/src/lua_preload.c | 73 + .../texk/web2c/luatexdir/luasocket/src/luasocket.c | 118 + .../texk/web2c/luatexdir/luasocket/src/luasocket.h | 32 + .../texk/web2c/luatexdir/luasocket/src/mime.c | 711 + .../texk/web2c/luatexdir/luasocket/src/mime.h | 31 + .../texk/web2c/luatexdir/luasocket/src/mime.lua | 87 + .../texk/web2c/luatexdir/luasocket/src/mime_lua.c | 135 + .../texk/web2c/luatexdir/luasocket/src/options.c | 149 + .../texk/web2c/luatexdir/luasocket/src/options.h | 39 + .../texk/web2c/luatexdir/luasocket/src/select.c | 200 + .../texk/web2c/luatexdir/luasocket/src/select.h | 17 + .../texk/web2c/luatexdir/luasocket/src/smtp.lua | 251 + .../texk/web2c/luatexdir/luasocket/src/smtp_lua.c | 412 + .../texk/web2c/luatexdir/luasocket/src/socket.c | 5 + .../texk/web2c/luatexdir/luasocket/src/socket.h | 76 + .../texk/web2c/luatexdir/luasocket/src/socket.lua | 133 + .../web2c/luatexdir/luasocket/src/socket_lua.c | 217 + .../texk/web2c/luatexdir/luasocket/src/tcp.c | 339 + .../texk/web2c/luatexdir/luasocket/src/tcp.h | 36 + .../texk/web2c/luatexdir/luasocket/src/timeout.c | 207 + .../texk/web2c/luatexdir/luasocket/src/timeout.h | 30 + .../texk/web2c/luatexdir/luasocket/src/tp.lua | 123 + .../texk/web2c/luatexdir/luasocket/src/tp_lua.c | 194 + .../texk/web2c/luatexdir/luasocket/src/udp.c | 336 + .../texk/web2c/luatexdir/luasocket/src/udp.h | 33 + .../texk/web2c/luatexdir/luasocket/src/unix.c | 356 + .../texk/web2c/luatexdir/luasocket/src/unix.h | 28 + .../texk/web2c/luatexdir/luasocket/src/url.lua | 297 + .../texk/web2c/luatexdir/luasocket/src/url_lua.c | 540 + .../texk/web2c/luatexdir/luasocket/src/usocket.c | 377 + .../texk/web2c/luatexdir/luasocket/src/usocket.h | 40 + .../texk/web2c/luatexdir/luasocket/src/wsocket.c | 401 + .../texk/web2c/luatexdir/luasocket/src/wsocket.h | 21 + .../texk/web2c/luatexdir/luasocket/test/README | 12 + .../web2c/luatexdir/luasocket/test/testclnt.lua | 713 + .../web2c/luatexdir/luasocket/test/testsrvr.lua | 15 + .../web2c/luatexdir/luasocket/test/testsupport.lua | 37 + Build/source/texk/web2c/luatexdir/luatangle.ch | 9 +- Build/source/texk/web2c/luatexdir/luatex-api.h | 138 +- Build/source/texk/web2c/luatexdir/luatex.ch | 516 +- Build/source/texk/web2c/luatexdir/luatex.defines | 394 +- Build/source/texk/web2c/luatexdir/luatex.h | 139 +- Build/source/texk/web2c/luatexdir/luatex.mk | 25 +- Build/source/texk/web2c/luatexdir/luatex.web | 11561 ++--- Build/source/texk/web2c/luatexdir/luatexextra.in | 38 +- Build/source/texk/web2c/luatexdir/luatexlib.mk | 56 +- Build/source/texk/web2c/luatexdir/luazlib/lzlib.c | 25 +- Build/source/texk/web2c/luatexdir/macnames.c | 312 - Build/source/texk/web2c/luatexdir/makecpool.c | 93 + Build/source/texk/web2c/luatexdir/managed-sa.c | 458 +- Build/source/texk/web2c/luatexdir/managed-sa.h | 98 +- Build/source/texk/web2c/luatexdir/mathcodes.c | 586 +- Build/source/texk/web2c/luatexdir/mp/avl.c | 792 + Build/source/texk/web2c/luatexdir/mp/avl.h | 118 + Build/source/texk/web2c/luatexdir/mp/lmplib.c | 1238 + Build/source/texk/web2c/luatexdir/mp/memio.w | 405 + Build/source/texk/web2c/luatexdir/mp/mp.w | 26390 ++++++++++++ Build/source/texk/web2c/luatexdir/mp/psout.w | 5703 +++ Build/source/texk/web2c/luatexdir/mp/tfmin.w | 242 + Build/source/texk/web2c/luatexdir/nodes.h | 1156 +- Build/source/texk/web2c/luatexdir/pdf/pagetree.c | 268 + Build/source/texk/web2c/luatexdir/pdf/pdfpage.c | 565 + Build/source/texk/web2c/luatexdir/pdftosrc.1 | 219 - Build/source/texk/web2c/luatexdir/pdftosrc.cc | 178 - Build/source/texk/web2c/luatexdir/pdftosrc.rc | 35 - Build/source/texk/web2c/luatexdir/primitive.h | 82 + Build/source/texk/web2c/luatexdir/ptexlib.h | 359 +- Build/source/texk/web2c/luatexdir/ptexmac.h | 46 +- .../texk/web2c/luatexdir/slnunicode/slnunico.c | 5 +- Build/source/texk/web2c/luatexdir/svnversion.h | 3 - Build/source/texk/web2c/luatexdir/tex/filename.c | 339 + Build/source/texk/web2c/luatexdir/tex/linebreak.c | 62 +- Build/source/texk/web2c/luatexdir/tex/math.c | 2255 + Build/source/texk/web2c/luatexdir/tex/mlist.c | 3864 ++ .../texk/web2c/luatexdir/tex/postlinebreak.c | 50 +- Build/source/texk/web2c/luatexdir/tex/primitive.c | 668 + Build/source/texk/web2c/luatexdir/tex/texdeffont.c | 189 + Build/source/texk/web2c/luatexdir/tex/texnodes.c | 1271 +- Build/source/texk/web2c/luatexdir/tex/texpdf.c | 26 +- Build/source/texk/web2c/luatexdir/tex/textoken.c | 659 +- Build/source/texk/web2c/luatexdir/texmath.h | 316 + Build/source/texk/web2c/luatexdir/textcodes.c | 452 +- Build/source/texk/web2c/luatexdir/tokens.h | 96 +- Build/source/texk/web2c/luatexdir/ttf2afm.c | 1053 - Build/source/texk/web2c/luatexdir/ttf2afm.rc | 35 - Build/source/texk/web2c/luatexdir/utils.c | 1798 - Build/source/texk/web2c/luatexdir/utils/avl.c | 794 + Build/source/texk/web2c/luatexdir/utils/avl.h | 115 + Build/source/texk/web2c/luatexdir/utils/avlstuff.c | 190 + Build/source/texk/web2c/luatexdir/utils/avlstuff.h | 27 + Build/source/texk/web2c/luatexdir/utils/synctex.c | 1493 + Build/source/texk/web2c/luatexdir/utils/synctex.h | 113 + Build/source/texk/web2c/luatexdir/utils/utils.c | 1802 + Build/source/texk/web2c/luatexdir/utils/writezip.c | 99 + Build/source/texk/web2c/luatexdir/writezip.c | 98 - 471 files changed, 291124 insertions(+), 276092 deletions(-) delete mode 100644 Build/source/texk/web2c/luatexdir/avl.c delete mode 100644 Build/source/texk/web2c/luatexdir/avlstuff.c delete mode 100644 Build/source/texk/web2c/luatexdir/avlstuff.h create mode 100644 Build/source/texk/web2c/luatexdir/commands.h delete mode 100644 Build/source/texk/web2c/luatexdir/depend.mk create mode 100644 Build/source/texk/web2c/luatexdir/font/luatexfont.h create mode 100755 Build/source/texk/web2c/luatexdir/get_svnversion.sh delete mode 100644 Build/source/texk/web2c/luatexdir/lua/lmplib.c delete mode 100644 Build/source/texk/web2c/luatexdir/lua/mp.w delete mode 100644 Build/source/texk/web2c/luatexdir/lua/psout.w create mode 100644 Build/source/texk/web2c/luatexdir/luafilesystem/Makefile.win create mode 100644 Build/source/texk/web2c/luatexdir/luafilesystem/README create mode 100644 Build/source/texk/web2c/luatexdir/luafilesystem/config.win create mode 100644 Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.def delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/ChangeLog delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/Makefile delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/ff-config.in delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/AUTHORS delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/INSTALL delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/LICENSE delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Makefile delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/Makefile delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/alphabet.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/char.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/cjk.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/descrip.mms delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/gwwiconv.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/memory.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/Unicode/ustring.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/VERSION delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/descrip.mms delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/Makefile delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/autohint.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/charview.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/configure-pfaedit.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/contextchain.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/descrip.mms delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/edgelist.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/edgelist2.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/encoding.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/featurefile.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/fontinfo.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/fontview.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/fvfonts.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/groups.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/kernclass.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/lff.opt delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/lookups.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/macbinary.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/macenc.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/namelist.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/ofl.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/parsepfa.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/parsettf.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/parsettfatt.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/parsettfvar.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/pfaedit.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/pfaeditui.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/plugins.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/prefs.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/psfont.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/psread.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/pua.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/scriptfuncs.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/scripting.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/sd.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/sfd1.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splinefill.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splinefont.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splineorder2.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splineoverlap.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splinerefigure.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splinesave.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splinestroke.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splineutil.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/splineutil2.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/stamp.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/stamper.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/start.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/stemdb.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/stemdb.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/tottf.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/tottfgpos.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/tottfvar.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/ttf.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/ttfspecial.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/unicoderange.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/views.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/fontforge/xlib.opt delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/basics.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/chardata.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/charset.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/dynamic.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/fileutil.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gdraw.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gfile.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/ggadget.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gicons.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gio.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gkeysym.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gprogress.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gresource.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gwidget.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/gwwiconv.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/intl.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/ustring.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/fontforge/inc/utype.h delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/src/ffdummies.c delete mode 100644 Build/source/texk/web2c/luatexdir/luafontforge/src/luafflib.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/ChangeLog create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/ff-config.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/AUTHORS create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/INSTALL create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/LICENSE create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Makefile.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ArabicForms.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/Makefile.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/alphabet.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/backtrns.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/char.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/cjk.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/combiners.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/dump.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/memory.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ucharmap.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/unialt.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ustring.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/utype.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/VERSION create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/configure-options create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/configure.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/Makefile.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/PfEd.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/baseviews.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/clipnoui.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/configure-pfaedit.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/cvundoes.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/dumppfa.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/edgelist.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/edgelist2.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/featurefile.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/fontforgevw.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/fontviewbase.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/fvcomposit.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/fvfonts.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/libffstamp.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/libstamp.pre create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/lookups.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/lookups.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macenc.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mathconstants.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/namelist.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/noprefs.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsepfa.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfvar.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/pfaedit.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/plugins.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psfont.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/pua.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/python.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/scripting.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/sd.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/sfd1.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/sfd1.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinechar.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefill.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineorder2.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineoverlap.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinerefigure.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesave.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinestroke.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/start.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/stemdb.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/stemdb.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottf.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfgpos.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/ttf.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/ttfspecial.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/uiinterface.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/unicoderange.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/views.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gdraw/Makefile.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/Makefile.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/fsys.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/gutils/gwwintl.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/basics.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/chardata.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/charset.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/config.h.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/dynamic.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/fileutil.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gdraw.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gfile.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/ggadget.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gicons.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gimage.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gio.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gkeysym.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gprogress.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gresource.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gwidget.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/gwwiconv.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/intl.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/ustring.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/utype.h create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/fontforge/plugins/Makefile.in create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/src/ffdummies.c create mode 100644 Build/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/Makefile create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/clocks.c create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/clocks.h create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/core_profiler.c create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/core_profiler.h create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/function_meter.c create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/function_meter.h create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/lua50_profiler.c create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/luaprofiler.h create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/stack.c create mode 100644 Build/source/texk/web2c/luatexdir/luaprofiler/stack.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/LICENSE create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/NEW create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/README create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/config create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/dns.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/ftp.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/http.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/index.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/installation.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/introduction.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/ltn12.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/luasocket.png create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/mime.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/reference.css create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/reference.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/smtp.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/socket.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/tcp.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/udp.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/doc/url.html create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/README create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/b64.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/check-links.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/check-memory.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/dict.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/dispatch.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/eol.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/forward.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/get.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/lp.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/qp.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/etc/tftp.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/luasocket.sln create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/makefile create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/mime.vcproj create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/README create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/cddb.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/daytimeclnt.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/echoclnt.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/echosrvr.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/listener.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/lpr.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/talker.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/samples/tinyirc.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/socket.vcproj create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/Makefile create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/buffer.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/buffer.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/except.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/except.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/ftp.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/ftp_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/http.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/http_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/inet.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/inet.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/io.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/io.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/ltn12.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/ltn12_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/mime.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/mime.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/mime.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/mime_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/options.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/options.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/select.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/select.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/smtp.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/smtp_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/socket.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/socket.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/socket.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/socket_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/tcp.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/timeout.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/timeout.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/tp.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/tp_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/udp.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/udp.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/unix.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/unix.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/url.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/url_lua.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/usocket.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/usocket.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.c create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.h create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/test/README create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/test/testclnt.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/test/testsrvr.lua create mode 100644 Build/source/texk/web2c/luatexdir/luasocket/test/testsupport.lua delete mode 100644 Build/source/texk/web2c/luatexdir/macnames.c create mode 100644 Build/source/texk/web2c/luatexdir/makecpool.c create mode 100644 Build/source/texk/web2c/luatexdir/mp/avl.c create mode 100644 Build/source/texk/web2c/luatexdir/mp/avl.h create mode 100644 Build/source/texk/web2c/luatexdir/mp/lmplib.c create mode 100644 Build/source/texk/web2c/luatexdir/mp/memio.w create mode 100644 Build/source/texk/web2c/luatexdir/mp/mp.w create mode 100644 Build/source/texk/web2c/luatexdir/mp/psout.w create mode 100644 Build/source/texk/web2c/luatexdir/mp/tfmin.w create mode 100644 Build/source/texk/web2c/luatexdir/pdf/pagetree.c create mode 100644 Build/source/texk/web2c/luatexdir/pdf/pdfpage.c delete mode 100644 Build/source/texk/web2c/luatexdir/pdftosrc.1 delete mode 100644 Build/source/texk/web2c/luatexdir/pdftosrc.cc delete mode 100644 Build/source/texk/web2c/luatexdir/pdftosrc.rc create mode 100644 Build/source/texk/web2c/luatexdir/primitive.h delete mode 100644 Build/source/texk/web2c/luatexdir/svnversion.h create mode 100644 Build/source/texk/web2c/luatexdir/tex/filename.c create mode 100644 Build/source/texk/web2c/luatexdir/tex/math.c create mode 100644 Build/source/texk/web2c/luatexdir/tex/mlist.c create mode 100644 Build/source/texk/web2c/luatexdir/tex/primitive.c create mode 100644 Build/source/texk/web2c/luatexdir/tex/texdeffont.c create mode 100644 Build/source/texk/web2c/luatexdir/texmath.h delete mode 100644 Build/source/texk/web2c/luatexdir/ttf2afm.c delete mode 100644 Build/source/texk/web2c/luatexdir/ttf2afm.rc delete mode 100644 Build/source/texk/web2c/luatexdir/utils.c create mode 100644 Build/source/texk/web2c/luatexdir/utils/avl.c create mode 100644 Build/source/texk/web2c/luatexdir/utils/avl.h create mode 100644 Build/source/texk/web2c/luatexdir/utils/avlstuff.c create mode 100644 Build/source/texk/web2c/luatexdir/utils/avlstuff.h create mode 100644 Build/source/texk/web2c/luatexdir/utils/synctex.c create mode 100644 Build/source/texk/web2c/luatexdir/utils/synctex.h create mode 100644 Build/source/texk/web2c/luatexdir/utils/utils.c create mode 100644 Build/source/texk/web2c/luatexdir/utils/writezip.c delete mode 100644 Build/source/texk/web2c/luatexdir/writezip.c (limited to 'Build/source/texk') diff --git a/Build/source/texk/web2c/ChangeLog b/Build/source/texk/web2c/ChangeLog index 52f0df90d0d..23b1a80fa19 100644 --- a/Build/source/texk/web2c/ChangeLog +++ b/Build/source/texk/web2c/ChangeLog @@ -1,3 +1,8 @@ +2009-03-27 Taco Hoekwater + + * configure.ac: With the new luatex, what used to be + luatexdir/luafontforge/ is now luatexdir/luafontloader/. + 2009-03-08 Peter Breitenlohner * texmfmp-help.h [eTeX,TeX]: Document -synctex switch. diff --git a/Build/source/texk/web2c/configure.ac b/Build/source/texk/web2c/configure.ac index 96459d1387d..07da4331be8 100644 --- a/Build/source/texk/web2c/configure.ac +++ b/Build/source/texk/web2c/configure.ac @@ -221,7 +221,7 @@ AM_CONDITIONAL([WIN32], [test "x$kpse_cv_have_win32" != xno]) AM_CONDITIONAL([MINGW32], [test "x$kpse_cv_have_win32" = xmingw32]) AS_IF([test "x$enable_luatex" = xyes], -[AC_CONFIG_HEADERS([ff-config.h:luatexdir/luafontforge/ff-config.in]) +[AC_CONFIG_HEADERS([ff-config.h:luatexdir/luafontloader/ff-config.in]) AC_CHECK_HEADERS([langinfo_h]) AC_TYPE_LONG_DOUBLE AC_TYPE_LONG_LONG_INT diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog index 3b38d7fd37d..efaac4a9191 100644 --- a/Build/source/texk/web2c/luatexdir/ChangeLog +++ b/Build/source/texk/web2c/luatexdir/ChangeLog @@ -1,3 +1,8 @@ +2009-03-27 Taco Hoekwater + + * luatexdir: import of the current state of luatex, 0.37.0. + This affects many files in subdirectories. + 2009-03-05 Peter Breitenlohner * image/pdftoepdf.cc: Uninclude , included later diff --git a/Build/source/texk/web2c/luatexdir/Makefile.in b/Build/source/texk/web2c/luatexdir/Makefile.in index 43f433fd8b8..9d888766d18 100644 --- a/Build/source/texk/web2c/luatexdir/Makefile.in +++ b/Build/source/texk/web2c/luatexdir/Makefile.in @@ -1,4 +1,5 @@ # Makefile for luatex. +# Public domain. # $Id$ kpse_include ../make/common.mk @@ -8,7 +9,14 @@ kpse_include ../make/library.mk kpathsea_srcdir_parent = $(srcdir)/../.. kpathsea_dir_parent = ../.. -ALL_CXXFLAGS = @CXXFLAGS@ @DEFS@ $(XXCFLAGS) -I. -I$(srcdir) -I$(kpathsea_dir_parent) -I$(kpathsea_srcdir_parent) @LIBXPDFCPPFLAGS@ -I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. -I$(LIBOBSDCOMPATFSRCDIR) -I$(LIBOBSDCOMPATFSRCDIR)/.. -I$(LIBPNGSRCDIR) -I$(ZLIBSRCDIR) +ALL_CXXFLAGS = @CXXFLAGS@ @DEFS@ $(XXCFLAGS) \ + -I. -I$(srcdir) \ + -I$(kpathsea_dir_parent) -I$(kpathsea_srcdir_parent) \ + @LIBXPDFCPPFLAGS@ \ + -I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. \ + -I$(LIBOBSDCOMPATFSRCDIR) -I$(LIBOBSDCOMPATFSRCDIR)/.. \ + -I$(LIBPNGSRCDIR) -I$(ZLIBSRCDIR) \ + -DPDF_PARSER_ONLY -DDISABLE_OUTLINE -I../../../../src/libs/obsdcompat CXX = @CXX@ CTANGLE = ../ctangle @@ -32,18 +40,16 @@ LIBMD5DIR=../../../libs/md5 LIBMD5SRCDIR=$(srcdir)/$(LIBMD5DIR) LIBOBSDCOMPATDIR=../../../libs/obsdcompat -LIBOBSDCOMPATFSRCDIR=$(srcdir)/$(LIBOBSDCOMPATDIR) +LIBOBSDCOMPATSRCDIR=$(srcdir)/$(LIBOBSDCOMPATDIR) XCPPFLAGS=-I.. -I$(srcdir)/.. -I../.. -I$(srcdir)/../.. -I$(LIBMD5DIR) \ -I$(LIBMD5SRCDIR) @LIBPNGCPPFLAGS@ @ZLIBCPPFLAGS@ \ -I$(LIBXPDFDIR) -I$(LIBXPDFDIR)/.. -I$(LIBXPDFSRCDIR) -I$(LIBXPDFSRCDIR)/.. \ - -I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. -I$(LIBOBSDCOMPATFSRCDIR) \ - -I$(LIBOBSDCOMPATFSRCDIR)/.. -DpdfTeX + -I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. -I$(LIBOBSDCOMPATSRCDIR) \ + -I$(LIBOBSDCOMPATSRCDIR)/.. -DpdfTeX OBJS = \ -avl.o \ -avlstuff.o \ font/mapfile.o \ font/pkin.o \ font/subfont.o \ @@ -90,47 +96,51 @@ lua/luatoken.o \ lua/luanode.o \ lua/llanglib.o \ lua/limglib.o \ -lua/mp.o \ -lua/psout.o \ -lua/lmplib.o \ lang/hnjalloc.o \ lang/hyphen.o \ lang/texlang.o \ +pdf/pdfpage.o \ +pdf/pagetree.o \ tex/linebreak.o \ tex/postlinebreak.o \ tex/texnodes.o \ tex/textoken.o \ tex/texpdf.o \ +tex/math.o \ +tex/mlist.o \ +tex/primitive.o \ +tex/texdeffont.o \ +tex/filename.o \ managed-sa.o \ mathcodes.o \ textcodes.o \ -utils.o \ -writezip.o +utils/avl.o \ +utils/avlstuff.o \ +utils/utils.o \ +utils/writezip.o \ +utils/synctex.o -all: libpdf.a $(makecpool) +all: libpdf.a makecpool -libpdf.a: lua/mp.c lua/psout.c $(OBJS) +libpdf.a: $(OBJS) rm -f $@ $(AR) $(ARFLAGS) $@ $(OBJS) $(RANLIB) $@ -lua/mp.c: lua/mp.w - $(CTANGLE) $(srcdir)/lua/mp.w - lua/mp.c - -lua/psout.c: lua/psout.w - $(CTANGLE) $(srcdir)/lua/psout.w - lua/psout.c +makecpool: makecpool.o + $(link_command) makecpool.o kpse_include ../make/clean.mk clean:: - rm -f libpdf.a ttf2afm pdftosrc + rm -f libpdf.a depend: rm -f $(OBJS) $(srcdir)/depend.mk for a in $(OBJS); do \ env XXCFLAGS="-MM -MT \$$@" XCFLAGS="-MM -MT \$$@" $(MAKE) -k $$a; \ touch $$a; \ - grep -a -v "^$(CC)\|$(CXX)\|$(AR)\|make\|klibtool" $$a | \ + grep -a -v "^$(CC)\|$(CXX)\|$(AR)\|make" $$a | \ sed 's: [^ ]*/\.\./libs/[^ ]*::g' >> $(srcdir)/depend.mk; \ done; \ rm -f $(OBJS) diff --git a/Build/source/texk/web2c/luatexdir/NEWS b/Build/source/texk/web2c/luatexdir/NEWS index 626b5c95a0b..9f151037197 100644 --- a/Build/source/texk/web2c/luatexdir/NEWS +++ b/Build/source/texk/web2c/luatexdir/NEWS @@ -1,537 +1,2385 @@ ---------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-beta-20060811 was released on 2006-08-11 ---------------------------------------------------------------- -- renamed primitives: - \primitive -> \pdfprimitive - \ifprimitive -> \ifpdfprimitive - \ifabsdim -> \ifpdfabsdim - \ifabsnum -> \ifpdfabsnum -- new version of \primitive/\ifprimitive (but see above) -- new dimen: \pdfpxdimen -- support for jbig2 files -- new library: obsdcompat, which has improved string functions and allows the - use of __attribute__ -- update libpng to 1.2.12 -- added JFIF detection patch to writejpg.c (was bug 548) -- bugfix: truetype OS/2 v3 fonts (594) -- bugfix: file with only \immediate\pdfobj stream results in garbage (505) -- bugfix: invalid pdf created if font name contains space (509) - ---------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-beta-20060725 was released on 2006-07-25 ---------------------------------------------------------------- -- added patches by Christian Schenk forwarded by Hartmut -- added patch 421 (popen) from Taco -- added lots of (void) to writettf* and ttf2afm to silence the compiler -- removed some unused variables from tounicode.c -- add new code by Thanh (patch 580) -- added security patch for xpdf :-( -- added JFIF detection patch to writejpg.c (bug 548) - ---------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-beta-20060213 was released on 2006-02-13 ---------------------------------------------------------------- -- pdftex.web has been improved a bit -- new patch: - - 473 \ifabsnum and \ifabsdim -- the manual has been updated a bit and is again included - ---------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-beta-20060125 was released on 2006-01-25 ---------------------------------------------------------------- -- pdfTeX now includes pdfeTeX, i.e. there is no way to make a binary without - eTeX support. Also the sources of TeX, eTeX and pdfTeX have been merged into - one file pdftex.web -- most pdfTeX change files are gone; only one file (pdftex.ch) remains. -- improved patches: - - 393 Ensure newline before endstream - ---------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-beta-20060117 was released on 2006-01-17 ---------------------------------------------------------------- -- pdfTeX is now pdfeTeX, i.e. there is no way to make a binary without eTeX - support. Also the sources of TeX, eTeX and pdfTeX have been merged into one - file pdfetex.web -- strip trailing zeros in fractions of reals written -- removed patch 467 \ifindef -- improved logging of objstreams - ----------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-alpha-20060111 was released on 2006-01-11 ----------------------------------------------------------------- -- new patches: - - 466 \primitive and \ifprimitive - - 467 \ifinedef -- improved patches: - - 393 Ensure newline before endstream -- pdfTeX now sets /ModDate and /Trapped by default (the values can be - overridden with /pdfinfo) -- more fixes to remove warnings from -Wall - ----------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-alpha-20060106 was released on 2006-01-06 ----------------------------------------------------------------- -- many small fixes to remove warnings from -Wall -- removed some unused variables -- really fix bug 444 -- add some GCC extensions and use *nprintf instead of *printf where possible -- fixed a unicode bug in ttf2afm - ----------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-alpha-20051226 was released on 2005-12-26 ----------------------------------------------------------------- -- improved patches: - - 453 Object Streams for PDF-1.5 - - take PK resolution from "pk_dpi" parameter in texmf.cnf, if it has not - been set by the format file or by the user - - 432 Rules in a PDF qQ group -- some fixes for Thanhs patch -- some improvements from -Wall -- .indent.pro for indent - ----------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-alpha-20051221 was released on 2005-12-21 ----------------------------------------------------------------- -- has a large patch from Thanh -- pdflastlink has been fixed -- remove generated pdf in case of fatal error - ----------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-alpha-20051208 was released on 2005-12-08 ----------------------------------------------------------------- -- improved patches: - - 386 grow obj_tab and dest_names arrays dynamically - - 453 Object Streams for PDF-1.5 - - take PK resolution from "pk_dpi" parameter in texmf.cnf, if it has not - been set by the format file or by the user -- write out PDF statistics later to make them correct -- makefile target pdfetex-all.pdf for a huge file - ----------------------------------------------------------------- -pdfTeX 3.141592-1.40.0-alpha-20051205 was released on 2005-12-05 ----------------------------------------------------------------- -- has these patches: - - 386 grow obj_tab and dest_names arrays dynamically - - 416 new primitive pdflastlink - - 427 Character positioning patch - - 432 Rules in a PDF qQ group - - 434 Remove queued map item handling - - 438 \pdfsavepos in DVI mode - - 443 512 zeros in Type1 fonts not copied anymore - - 447 Don't write /Encoding for non-reencoded fonts - - 453 Object Streams for PDF-1.5 - - take PK resolution from "pk_dpi" parameter in texmf.cnf, if it has not - been set by the format file or by the user - -------------------------------------------------- -pdfTeX 3.141592-1.30.6 was released on 2006-02-16 -------------------------------------------------- -- bugfix: updated xpdf to 3.01pl2 - -------------------------------------------------- -pdfTeX 3.141592-1.30.5 was released on 2005-12-04 -------------------------------------------------- -- bugfix: \pdfximage prints the file name twice (bug 441) -- bugfix: buffer overflow with \pdfmatch (bug 444) -- bugfix: updated xpdf to 3.01pl1 - -------------------------------------------------- -pdfTeX 3.141592-1.30.4 was released on 2005-10-17 -------------------------------------------------- -- bugfix: whitespaces in filenames didn't work on Unix anymore (bug 377) -- bugfix: two \immediates cancel themselves (bug 437) -- bugfix: wrong file name in error messages of image inclusion (bug 435) - -------------------------------------------------- -pdfTeX 3.141592-1.30.3 was released on 2005-09-04 -------------------------------------------------- -- bugfix: \write18 - -------------------------------------------------- -pdfTeX 3.141592-1.30.2 was released on 2005-08-25 -------------------------------------------------- -- fixed some build problems and minor bugs introduced in 1.30.1 - -------------------------------------------------- -pdfTeX 3.141592-1.30.1 was released on 2005-08-21 -------------------------------------------------- -- the eTeX extensions can now be enabled with the cmdline switch -etex -- pdfTeX uses xpdf 3.01 - -------------------------------------------------- -pdfTeX 3.141592-1.30.0 was released on 2005-08-01 -------------------------------------------------- -- pdfxtex (introduced with 1.20a) is gone; all extensions are now in pdf(e)tex. -- Some primitives have been renamed; the old names will still work, but are - deprecated and some give a warning that they are obsolete: - \pdfoptionpdfminorversion -> \pdfminorversion - \pdfoptionalwaysusepdfpagebox -> \pdfforcepagebox - \pdfoptionpdfinclusionerrorlevel -> \pdfinclusionerrorlevel -- pdftex knows two new units: - - new Didot (1nd=0.375mm) - - new Cicero (1nc=12nd) -- New primitives: - - Inclusion of pngs has been greatly improved: It now does - - alpha channel and transparency (only if %!PDF >=1.4) - - 16-bit colour (only if %!PDF >=1.5); this must be enabled by setting - \pdfimagehicolor to 1. - - gamma correction; this must be enabled by setting \pdfimageapplygamma to - 1. The device gamma is taken from \pdfgamma. If no embedded value can be - found in the png image, then the value of \pdfimagegamma is used instead. - - fast direct embedding of png streams, if their structure allows this; the - automatic fall-back is to decompress and re-compress as before. - - pdfTeX now has an interface to the precise system time (if available) as an - aid in benchmarking TeX macro code. - - \pdfelapsedtime is a read-only integer that (initially) returns the - amount of time passed since the start of this run. This amount is given - in `scaled seconds': the value 65536 counts as one second. If more time - has passed than 32767 seconds, (2^31)-1 will be returned. - - \pdfresettimer updates the internal timer, such that subsequent calls to - \pdfelapsedtime will restart from 0. - - pdfTeX can now generate random numbers: - - \pdfuniformdeviate generates a uniformly distributed random - integer value between 0 (inclusive) and (exclusive). - - \pdfnormaldeviate expands to a random integer value with a mean of 0 and - a unit of 65536. - - \pdfrandomseed allows access to the current seed value. - - \pdfsetrandomseed sets the random seed to a specific value. - - \pdfnoligatures\f disables ligatures for the loaded font \f. - - Escaping strings: - - \pdfescapestring{} escapes the string so that it can be used as - PDF string. - - \pdfescapename{} escapes the string so that it can be used as PDF - name. - - \pdfescapehex{} converts the string to uppercase hexadecimal - representation. - - \pdfunescapehex{} reverses the effect of \pdfescapehex - - \pdfcreationdate expands to the date string that pdfTeX uses in the info - dict as default. - - \pdffilemoddate{} expands to the modification date of in the - same format as \pdfcreationdate (PDF date format). - - \pdffilesize{} expands to the size of as string. - - \pdfmdfivesum{} or \pdfmdfivesum file {} calculates the md5 - sum (of a string or a file) and converts it to uppercase hexadecimal format - (same as \pdfescapehex). - - \pdffiledump [offset ] [length ] - Expands to a hex dump of the file given in , starting at - given offset or 0 with given length. - - \pdfshellescape is a read-only integer that is 1 if \write18 is enabled, 0 - otherwise. - - \pdfxformname , which expands to the number in the - corresponding form XObject name. - - \leftmarginkern and \rightmarginkern tell the - margin kern at the left and right side of the horizontal list stored in box - . - - \pdfpkmode is a token register that sets the MF mode for pixel font - generation. The contents of this register is dumped into the format, so one - can (optionally) preset it e.g. in part of pdftexconfig.tex. - - \pdftracingfonts: An integer variable controlling the tracing of font - expansion. It is zero by default; then we get a log (with fontexpansion) - like this - ...\tenrm t - ...\tenrm (+20) e - Without font expansion, this default should be compatible with TeX's - original log output. - If \pdftracingfonts is set to 1 (or greater), we get a more verbose log: - ...\xivtt (cmtt10@14.0pt) t - ...\xivtt (cmtt10+20@14.0pt) e - See also bug 304. -- New experimental primitives: - - \pdfmatch [icase] [subcount }] {}{} - Implements pattern matching using the POSIX regex. - It returns the same values as \pdfstrcmp, but with the following semantics: - -1: error case (invalid pattern, ...) - 0: no match - 1: match found - Options: - * icase: case insensitive matching - * subcount: it sets the table size for found subpatterns. - A number "-1" resets the table size to the start default. - - \pdflastmatch - The result of \pdfmatch is stored in an array. The entry "0" contains the - match, the following entries submatches. The positions of the matches are - also available. They are encoded: - "->" - The position "-1" with an empty string indicates that this entry is not - set. - - \pdfstrcmp{}{} compares two strings and returns the strings "0" if - equals , "-1" if is less than , "1" if is greater than - -- The primitive \pdfmovechars has been removed (bug 294) -- Bugfixes: - - empty strings are not supressed anymore (bug 335) - - \unhboxing and character protusion didn't work well together (bug 292) - - --jobname didn't work if there was no filename at all (bug 302) - - Some problem with fonts on solaris (bug 315) - - Dangling font objects with non-replacable fonts (bug 311). - - \pdfxform didn't work with box>255 (bug 310) - - cmap: unicode ???? is mapped to multiple glyphs (bug 306). -- pdfTeX uses zlib 1.2.3 - ------------------------------------------------- -pdfTeX 3.141592-1.21a was released on 2005-02-04 ------------------------------------------------- -- ttf2afm 1.0: - - added support for refering to glyphs via unicode in encoding files (ie 'uniXXX') - - added some more info to the AFM output - - some minor bug fixes - - a short documentation available -- pdftex now understand forms 'uniXXXX' in encoding files (only makes sense - with TrueType fonts) -- added subset tag for TrueType fonts -- PDF strings are now printed as following: - (This is a string) -> (This is a string) - This is a string -> (This is a string) - -> -- check for double newline char to get rid of empty lines in PDF output -- Fixed a bug in the scanning of map lines introduced in the fix of bug #242 in - 1.20b. -- Fixed three problems in xpdf; xpdf is now 3.00pl3 -- \ifeof18 is a simple method to test if \write18 is enabled. -- a few extensions in pdfxtex: - - \pdflastximagecolordepth returns the last color depth - - \pdfximage supports a keyword "colorspace" following an object number - representing a ColorSpace object - - \pdfstrcmp compares two strings - - \pdfescapestring/\pdflastescapedstring provide a way to escape string - - \pdffirstlineheight/\pdflastlinedepth/\pdfeachlineheight/\pdfeachlinedepth - allow fixing line dimen - - patches from Taco - - px dimen unit - - tagcode patch - - quitvmode patch - ------------------------------------------------- -pdfTeX 3.141592-1.20b was released on 2004-12-22 ------------------------------------------------- -- Fixed some minor bugs, mostly with hz -- The info line "output format initialized to PDF/DVI" isn't shown anymore, as - this info wasn't reliable (bug 112). -- Now the PDF-related statistics (PDF objects...) in the .log file is only - shown in PDF output mode. It start with a line "PDF statistics:". -- \pdfimageresolution is not limited to 2400 [dpi] anymore, can now be between - 0 and 65535 [dpi]. -- pdfTeX uses xpdf 3.00pl2 -- pdfTeX uses libpng 1.2.8, which fixes some png-related bugs. - ------------------------------------------------- -pdfTeX 3.141592-1.20a was released on 2004-09-06 ------------------------------------------------- -- There is a new program pdfxtex, which contains experimental features which - might end up in pdftex in the future. -- Most distributions now use eTeX as the default engine, so when you call - pdftex you will get pdfeTeX. Most distributions now also use pdfTeX as the - default engine, so when you call latex you will get pdfeTeX running LaTeX.:-) -- We are setting up pdfTeX as a project at sarovar - (http://sarovar.org/projects/pdftex/). Please report bugs etc. through the - site. -- Support for the file pdftex.cfg is gone completely. All parameters that had - previously been set by it can be set through primitives; their values are - dumped to the format file. -- The searchpath for encoding and mapfiles has been changed. - See http://tug.org/pipermail/tex-live/2004-January/004734.html and - http://tug.org/pipermail/tex-live/2004-January/004791.html -- eTeX is now version 2.2, incorporating the last changes to TeX (3.141592). -- New options for \pdfmapfile: - General functionality: Map items (map files, new: also single map lines; see - \pdfmapline) are put in list of pending map items. During the next shipout, - pending map items are sequentially scanned for their map entries, and an - internal map entry database is updated, using the modes below. Then the list - of pending map items is cleared. Map entries of fonts already in use are left - untouched. New: All \pdfmapfile and \pdfmapline commands can also be given - after shipout of the first page. - - \pdfmapfile {foo.map} clears the list of pending map items and starts a new - list with the only pending file foo.map. When the map entry lines of - foo.map are scanned, duplicate map entries are ignored and a warning is - issued. This is the old behaviour. - - \pdfmapfile {+foo.map} puts foo.map in the list of pending map items. When - the map entry lines of foo.map are scanned, duplicate map entries are - ignored and a warning is issued. - - \pdfmapfile {=foo.map} puts foo.map in the list of pending map items. When - foo.map is scanned, matching map entries in database are replaced by new - entries from foo.map. - - \pdfmapfile {-foo.map} puts foo.map in the list of pending map items. When - foo.map is scanned, matching map entries are deleted from database. - - \pdfmapfile {} clears the list of pending map items. It does not affect map - entries already registered into the database. This is the old behaviour. -- New command \pdfmapline {line}. It's like \pdfmapfile but here you can set - single map lines like in the map files directly. The modifiers (+-=) have the - same effect as with \pdfmapfile. -- Simplified the handling of the 14 Type 1 "standard fonts" (Times, - Helvetica...): They are now more or less handled like any other Type 1 font. - See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000648.html -- hz: So far the font expansion feature required that the user must be able to - create expanded tfms (eg cmr10+10.tfm). Now font expansion can be used - without creating these tfms. - See http://www.ntg.nl/pipermail/ntg-pdftex/2004-May/000504.html -- hz: Changed \pdffontexpand primitive --> the expand factor is now fixed to - 1000 and the argument is ignored. This will lead to spurious texts of "1000" - in your output if you compile old documents. -- New command \pdftexbanner which returns a string with the full banner of the - current binary (e.g. "This is pdfTeX, Version 3.141592-1.20a (Web2C 7.5.3) - kpathsea version 3.5.3") -- The PTEX.FullBanner key is now inserted in the document info dict instead of - the catalog. Newer versions of Acrobat display it. -- Now includes support for encTeX. -- Extended \pdfannot to use reserveobjnum/useobjnum - See http://www.ntg.nl/pipermail/ntg-pdftex/2004-March/000424.html -- Bugfix: pdfTeX would read an .xpdfrc when including pdfs. - See http://tug.org/pipermail/pdftex/2004-March/004835.html -- Bugfix: The strings in /ID would sometimes be empty. -- Bugfix: Even when mapfiles or encodings or PostScript font files were - missing, pdfTeX still produced a (most often corrupt) pdf. Now it aborts with - an error in these cases. -- numerous small bugfixes. -- pdfTeX now uses the GNU libavl from Ben Pfaff for managing of fontmap - entries. -- pdfTeX uses zlib 1.2.1 -- pdfTeX uses xpdf 3.00 -- pdfTeX uses libpng 1.2.7 - ------------------------------------------------- -pdfTeX 3.141592-1.11b was released on 2003-10-06 ------------------------------------------------- -- Bugfix: The handling of /Rotate produced displaced images when /Rotate was 90 - or 270. - ------------------------------------------------- -pdfTeX 3.141592-1.11a was released on 2003-08-02 ------------------------------------------------- -- New command \pdftrailer analogue to \pdfcatalog whose argument ends up in the - trailer dictionary. -- The behaviour when an included pdf has a newer version than the one specified - with \pdfoptionpdfminorversion can be controlled by the new internal integer - \pdfoptionpdfinclusionerrorlevel: If it's 0, pdfTeX gives only a warning; if - it's 1, it raises an error. - This can also be set in pdftex.cfg with pdf_inclusion_errorlevel -- The syntax for outlines has been extended to allow attributes: - --> [count ] - See http://www.ntg.nl/pipermail/ntg-pdftex/2003-June/000165.html -- The syntax of \pdfobj has been extended: - \pdfobj (h, v, m) - --> reserveobjnum - | [useobjnum ] [] [stream []] - --> - | - When the optional keyword `reserveobjnum' and `useobjnum' is not given, the - behaviour is unchanged. - See also http://tug.org/mailman/htdig/pdftex/2003-March/003814.html -- Bugfix: /CreationDate didn't care for the timezone and could be fooled. - See http://www.ntg.nl/pipermail/ntg-pdftex/2003-July/000223.html -- Bugfix: The translation of 8-bit characters in included pdfs that had their - eighth bit set sometimes got wrong because of a missing typecast. - See http://www.ntg.nl/pipermail/ntg-pdftex/2003-July/000216.html -- Bugfix: pdfTeX -ini would crash with a minimal file because it didn't read - it's config and so didn't know anything about fonts. - See http://tug.org/pipermail/pdftex/2003-July/004262.html -- Bugfix: \pdfstartlink would produce spurious /NewWindow entries. Also the - syntax of and has been cleaned up. - See http://www.ntg.nl/pipermail/ntg-pdftex/2003-June/000167.html -- Bugfix: \pdffontattr was not used for T3 fonts. - See http://tug.org/pipermail/pdftex/2003-June/004127.html -- Bugfix: The cropbox of an included pdf would sometimes not be used. - See http://tug.org/pipermail/pdftex/2003-May/004037.html -- pdfTeX uses xpdf 2.02 - ------------------------------------------------- -pdfTeX 3.141592-1.10b was released on 2003-02-26 ------------------------------------------------- -- The numbers in transformation matrices are allways written with maximum - precision (see http://tug.org/pipermail/pdftex/2003-February/003596.html). -- Incorporated the new version of TeX: 3.141592 -- Bugfix: Numbers in pdfs would sometimes be just a wee bit of (changed - implementation of pdftoepdf.convertNumToPDF). -- Bugfix: When setting the /Producer, /Creator or /CreationDate keys with - /pdfinfo pdfTeX would also insert default values which caused duplicate keys - in the info dict (see - http://tug.org/pipermail/pdftex/2003-February/003524.html). -- The reading of mapfiles is much faster (see - http://tug.org/pipermail/pdftex/2002-July/002843.html). -- Bugfix: AR5 had problems with the CTM when displaying in "fit visible" mode - (see http://tug.org/pipermail/pdftex/2002-May/002688.html). -- Bugfix: str_in_str had wrong indices (see - http://tug.org/pipermail/pdftex/2002-March/002367.html). -- Bugfix: decimal_digits defaulted to 0, which caused problems with included - images when including pdfs (see - http://tug.org/pipermail/pdftex/2003-February/003518.html). - It now defaults to 4. -- Bugfix: the type of included images was decided based only on the extensions; - now pdfTeX looks for magic bytes at the start of files (see - http://tug.org/pipermail/pdftex/2003-February/003519.html) - ------------------------------------------------ -pdfTeX 3.14159-1.10a was released on 2003-01-16 ------------------------------------------------ -- pdfTeX is now able to produce pdf1.4 (which is also the default) and has - almost complete support for including pdf1.4 files: - - Additional attributes like MetaData are copied from included pdfs. - - Currently the Page Group attribute (see sections 7.3.6 and 7.5.5 of the pdf - 1.4 reference) of included pdfs is NOT copied (as we don't know how to - handle this when imposing pdfs). - This means including pdfs with transparency features will work as long as - the included pdf doesn't use Page Groups; if it does, the result might not - be what is expected (One application known to use Page Groups is Adobe - Illustrator v9++). The distributed pdfTeX binaries will give a warning - about any occurance of a Page Group in an included pdf and ignore the Page - Group (thus producing syntactically correct pdfs but probably not the - intended output). - Acrobat 5++ and newer versions of Jaws display files without Page Groups - correctly, so this might not really be a problem. - See pdftoepdf.cc for preprocessor flags which allow this behaviour to be - changed (copying the Page Group (most likely producing incorrect pdf) or - treating Page Groups as errors). -- The new primitive \pdfoptionpdfminorversion sets the pdf version of the - generated file and the latest allowed pdf version of included pdfs: - \pdfoptionpdfminorversion=3 - tells pdfTeX to set the pdf version to 1.3 and allows only included pdfs with - versions <= 1.3 . - The default for \pdfoptionpdfminorversion is 4 for pdf 1.4 - This must appear before any data is written to the generated pdf file, so - you should put it at the very start of your files. - This can also be set in pdftex.cfg with pdf_minorversion -- It is now possible to specify the pdf page box to use when including pdfs. - The syntax has been extended: - \pdfximage [] (h, v, m) - --> [] [] [] [] - --> mediabox|cropbox|bleedbox|trimbox|artbox - The default is cropbox (which defaults to mediabox), to be compatible with - previous versions of pdfTeX. - The page box specified at \pdfximage can be globally overridden with the - config parameter always_use_pdfpagebox and the command - \pdfoptionalwaysusepdfpagebox , where 0 is the default (use whatever - is specified with \pdfximage), 1 is media, 2 is crop, 3 is bleed, 4 is trim - and 5 is artbox. This can only be set once per object, i.e. the value used at - \pdfximage is remembered. - See the pdf reference for an explanation of the boxes. -- The support for the inclusion of jpeg images has been extended to allow the - inclusion of JPEG/Exif files which are produced by digital photo cameras - (thanks to Hartmut Henkel). -- The support for the inclusion of tif images has been removed as it was of - limited use (it worked only for gray-scale and rgb images) and produced wrong - results (all other images types where treated as rgb images). - Tif images can be converted on *nix on-the-fly to pngs with the help of - ImageMagick, epstopdf.sty or pdftex.def v0.4 or newer, and this rule: - \DeclareGraphicsRule{.tif}{png}{.png}{`convert #1 `basename #1 .tif`.png} -- The extensions for pdf encryption have been removed, since they make the - pdfTeX code overly complex. Those needing pdf encryption are encouraged to - produce a standalone program for encrypting pdfs. -- pdfTeX now writes a usage statistic about the pdfTeX specific memory to the - log. -- numerous bugfixes, most of them in the inclusion of pdfs. -- pdfTeX uses xpdf 2.01 -- pdfTeX uses libpng 1.2.5 - ---------------------------------------------------------------------- -pdfTeX 3.14159-1.00a-pretest-20011127-ojmw was released on 2002-01-29 ---------------------------------------------------------------------- - ----------------------------------------------------------------- -pdfTeX 3.14159-1.00a-pretest-20010806 was released on 2001-08-06 ----------------------------------------------------------------- - ----------------------------------------------------------------- -pdfTeX 3.14159-1.00a-pretest-20010804 was released on 2001-08-04 ----------------------------------------------------------------- - -$Id$ -// vim: tw=79:ts=2:expandtab:autoindent +============================================================== +Luatex beta-0.36.0 was released 20090323 +============================================================== + +* The included fontforge code is stripped considerably, and + the lua table to access the code is renamed to 'fontloader'. + The old name ('fontforge') will remain present for a while, + but will eventually go away. + +* New lua functions: tex.primitives(), tex.extraprimitives, + tex.enableprimitives(). This is a prelude to a big change + in the next beta: iniluatex will from now on start up with + only the TeX82 primitives and \directlua, everything else + has to be bootstrapped via tex.enableprimitives(). + See the manual for more details. + +* Support for multiple lua states has been removed, and at the + same time support for adding name ids to lua chunks has been + added. See the manual for more details. + +* More changes to the PDF backend to make it support non-latin + directions (form and image placement, vertical typesetting, + synctex). + +* The kpathsea library is updated. Highlights: cleaner build + process (thanks to Peter Breitenlohner), cleaner mingw32 + (cross)compilation support, and a new reentrant API. + +* Some possible endless loops within extended delimiters in + math mode are now trapped. + +* Movements inside VF font characters were considerably off + due to a wrong conversion routine. + +* Error handling for \outer has been reinstated, but can be + suppressed via the new primitive \suppressoutererror. + +* The new primitives: \suppresslongerror and \suppressifcsnameerror + that can be used to suppress errors for \par in non-long macros + and for non-expandable objects inside \ifcsname ... \endcsname, + respectively. + +* New lua function: node.vpack() via a patch from Khaled Hosny + that also improves error handling in node.hpack(). + +* Fix the typo that caused \charic (instead of \charit) + to be defined as a primitive. + +* Suppression of hyphenation via \hyphenchar\font=-1 now works + again. + +* The lua functions tex.print(), tex.sprint(), tex.write() now + accept an array of strings as well as vararg list of strings + to print. + +* A change to be build process: luatex.p is no longer split + int smaller pieces before running the C compiler. + +* Melissa O'Neill contributed a bugfix to the Type1 font + subsetting code. + +* A bunch of smaller bugfixes and cleanups (as usual). + +============================================================== +Luatex beta-0.35.0 was released 20090224 +============================================================== + +* The math handling portions of LuaTeX are converted to C code, + and extended to support Unicode math. There are a great many + related changes, see the new Math chapter in the manual for + details. + +* A nasty bug in the paragraph breaking routine was fixed. + (All lines except the first one were believed to be wider then + they really were. This affected which nodes were considered + as active breakpoints) + +* Various changes to the PDF backend to make it support non-latin + directions. + +* Fixed the behaviour of the page offsets. Placement of the output + on the physical page should now work correctly in all directions, + both in DVI and PDF. + There now are \pageleftoffset and \pagetopoffset primitives, + as well as + +* fontforge.apply_featurefile() was broken since 0.31.0 + +* The lua profiler library is added. + +* The included lua filesystem library is now 1.4.1. + +* Reading of pk files fixed. + +* An optional space afer a for \textdir c.s. + is ignored from now on. + +* \bodydir and \pagedir can now be (re)set even after the first + page has been output. + +* The new callback mlist_to_hlist can be used to intercept the + normal conversion of math lists to horizontal lists. + +* The programs ttf2afm and pdftosrc are removed from the luatex + distribution (these belong to pdftex). + +* fontforge.open() now uses much less memory when opening large + (CJK) fonts. + +* The included libpng is now 1.2.35. + +* Quite a lot of smaller bugfixes and cleanups (as usual). + + +============================================================== +Luatex beta-0.31.3 was released 20081229 +============================================================== + +This release has a bunch of updates from the development trunk +(#1657-1670,1677,1678,1680,1685,1687). + + * Closing of files opened by \externalocp. + + * Fix for a locale-related bug that make PDF generation fail + with a "Parsing CFF Dict failed" message when including + opentype fonts. + + * The included metapost is now version 1.102. + + * PDF rules in vertical modes in RL direction where output + in the wrong direction + + * Fix for a crash on Apple fonts that contain a 'bsln' table. + + * The handling of the second argument to fontforge.open() was + broken + + * The included libpng is now 1.2.34 + + * Handling of ttc files on Windows was broken + + +============================================================== +Luatex beta-0.31.2 was released 20081209 +============================================================== + +Besides fixing building issues, this release has + + * A small fix for a crash that could happen when using + external OCPs. + + * A fix in the format of fontforge.to_table output. + (In 0.31.1 .lookups was near-empty; the lookups + were accidentally output as part of the gpos table). + +============================================================== +Luatex beta-0.31.1 was released 20081209 +============================================================== + +fixed a bunch of compilation errors on various platforms, but +with no other visible changes. + + +============================================================== +Luatex beta-0.31.0 was released 20081205 +============================================================== + +This is just an intermediate release so that some testing can be +done on the updated fontforge embedding. + +* There are new fields being generated by fontforge.to_table(), + and one or two old ones have been removed. These fields are / + will be documented in the manual, but very briefly: + + - MATH table and associated information are now exported + (the main reason for the new fontforge code) + - Baseline data is now exported + (perhaps usable in lua code) + - Multiple Master / Glyph variation data is now exported + (but useless, for now) + - Mac Feature (AAT) information is now exported + (perhaps usable in lua code) + - If (lookup) names were saved via the PfED table, these + will the exported instead of the default, generated names. + (as requested by Yannis) + +* dfont is now treated as an archive format just like ttc + when it comes to fontforge.info(). NOTE: that does not mean you + can actually use them, because the backend doesn't know + yet how to embed dfont fonts in the PDF, that is on the + TODO list for the next big beta (0.40.0). + +* The executables are a lot larger than before. That is because + much more of fontforge is included than before. Likely this + will stay this way, because this makes upgrading the ff code + much easier, and it means that luatex/FF potentially + understands more font formats (after upgrading the backend, + of course) + + +============================================================== +Luatex beta-0.30.3 was released 20081128 +============================================================== + +This release fixes a really big bug, a few smaller ones, +and has updates of png and mplib: + +* All hyphenation patterns that were anchored at the start or + end of a word were ignored in luatex versions 0.25.X and 0.30.X + (and possibly even earlier). + +* Repeated use of \language=-1 could result in "There is not room + for another language". + +* The lua true coroutines patch (Coco) is now disabled on OpenBSD + running on non-intel platforms. + +* The lua socket library is patched so that it will now compile on + OpenSolaris. + +* Luatex now has libpng 1.2.33 and mplib 1.100 + +============================================================== +Luatex beta-0.30.2 was released 20081020 +============================================================== + +* The Lua coco change from 0.30.1 is reverted as it gave + trouble on MacOSX. Lua coco on non-intel OpenBSD platforms + is now explicitly turned off. + +* The lua file reading speedup in 0.30.1 broke reading of + files larger than 100MB. + +* Reading of font-related files was broken when there was a find + callback, but no read callback. + +* The texmf.cnf array size setup values were ignored whenever + --lua was given on the commandline (instead of only when + texconfig.kpse_init is set to false). + +* glyphs with negative widths resulted in incorrect horizontal + placement (overlapping) of the string in the output PDF. + +* Using \latelua could sometimes result in an invalid output PDF, + and the argument token list was expanded too early + +* There was a read buffer overrun in the mapfile parser + +* There are two new variables in the status table: + status.callbacks and status.indirect_callbacks (execution counts). + +============================================================== +Luatex beta-0.30.1 was released 20081009 +============================================================== + +* Invalid return values from the linebreak_filter callback + are now handled gracefully (was crashing) +* a preinstalled ctangle is no longer needed except when + cross-compiling +* In 0.30.0, the .notdef fix was incorrectly applied to + truetype / opentype fonts. +* A bunch of all memory leaks is fixed +* In lua, f:read('*a') now uses signicantly less memory +* The number of \catcodetables is now limited to 64KB + (for speed reasons) +* Luatex could crash if there were PDF images with and + without page /Group included on the same page +* Lua coco now always uses setjmp (for OpenBSD compatibility) +* The embedded mplib is updated to the latest svn version +* # marks (characters with catcode 6) are no longer doubled + inside \directlua +* Handling the nul character (U+0000) with catcode 13 + (active) was broken +* Luatex could crash on win32 with an access violation + because there was one predefined language too few + (the one matching \language=-1) + +============================================================== +Luatex beta-0.30.0 was released 20080930 +============================================================== + +New features: + +* Readable \tex internal params that are counts, attrs, or dimens are + now returned as numbers instead of strings, and skips as node objects. + Read-write access to tex's skip registers added: tex.skip[0] etc. +* new callback: 'linebreak_callback' to replace the internal paragraph + breaking code +* the tex table now supports more readable 'convert' values: + tex.fontname, tex.pdffontname, tex.pdffontobjnum, tex.pdffontsize, + tex.uniformdeviate, tex.number, tex.romannumeral, tex.pdfpageref, + tex.pdfxformname (each takes a number as argument) +* new readable parameter: tex.fontidentifier(number) returns the + \csname associated with that font id +* luatex now outputs \FONT instead of \^^@ in Overfull/Underfull + messages if the font's id text is zero (like for expanded fonts) (#77) + * luatex --version is split into --version and --credits +* There is now (again) an svn revision number in luatex --version (#91) +* Add support for more read-only internal access from lua: + tex.lastpenalty, tex.lastkern, tex.lastskip, tex.lastnodetype, + tex.inputlineno, tex.badness, tex.pdftexversion, tex.pdflastobj, + tex.pdflastxform, tex.pdflastximage, tex.pdflastximagepages, + tex.pdflastannot, tex.pdflastxpos, tex.pdflastypos, tex.pdfrandomseed, + tex.pdflastlink, tex.luatexversion, tex.Alephversion, + tex.Omegaversion, tex.Alephminorversion, tex.Omegaminorversion, + tex.eTeXminorversion, tex.eTeXversion, tex.currentgrouplevel, + tex.currentgrouptype, tex.currentiflevel, tex.currentiftype, + tex.currentifbranch, tex.pdflastximagecolordepth (#81) +* the old --src-specials are replaced by --synctex (#63) +* the \expanded primitive is backported from pdftex 1.50 (#43) +* luatex now comes with libpng 1.2.32 +* experimental: tex.definefont(string, number) associates a + csname string with a font id number + +Bugs fixed compared to 0.29.0: + +* dashes were exported wrongly by MPlib +* multi-item \discretionaries were broken in various ways (#78, mailinglist) +* read_font_info was sometimes called recursively from lua-loaded + virtual fonts +* do_vf was sometimes called on lua-loaded fonts that where + already known to be virtual +* trailing junk in tfm files is now ignored (needed for ecrm fonts) +* pdf_ignored_dimen was initialized too late, breaking \prevdepth + handling and causing output lines to overlap eachother (#72) +* pdf.immediateobj() had a printf-related bug +* the fontname terminal logging is fixed for strange font file names +* lua tex array assignments now listen to the globaldefs setting + (tex.count[0] etc) (#92,partial) +* \parshape was broken (#70) +* there is no longer a ".tex" extension forced on very input file (#74) +* eof() for mapfiles was true one byte too soon (#76) +* out of range \lefthyphenmin and \righthyphenmin settings now actually + disable hyphenation (#90) +* tex.unset_attribute() looked too far ahead when a to-be-unset + attribute id not only did not exist in the node, but was also + higher than the highest set attribute on the node. (#65) +* the parameters attr and page_name of read_image() were swapped + (this broke \pdfimage with attributes) +* tex filenames with spaces in them on the command line are now + allowed again (#30) +* sometimes pfb fonts were included multiple times without valid + reason (#29) +* some parts of the pdftex 1.40.9 PNG transparancy hack were still + present and caused transparant png handling to fail +* \localinterlinepenalty and \localbrokenpenalty were broken +* special case catcode tables are now handled better (#23) +* the handling of missing .notdef charstrings in old pfb fonts + is fixed (#27) + +============================================================== +Luatex beta-0.29.0 was released 20080718 +============================================================== + + +New features: + +* The embedded pdftex is now 1.40.9 (forthcoming) except for the + following: + - the png transparancy fix is skipped because it is in conflict + with a macro-based solution offered by context mkiv. + - LFS (PDF files > 2GiB) is not working yet. + - Synctex is still missing + +* libpng, xpdf, and zlib are updated to their pdftex 1.0.9 levels + +* MPlib is updated to 1.090 + +* The syntax of buildpage_filter is changed to avoid confusion + (and crashes). See the manual for the new calling convention. + +Bugs fixed compared to 0.28.0: + +* The previous bugfix for \languages skipping numbers was wrong. + +* Various compile-time warnings are suppressed + +* \pdfsetmatrix was broken + +* \pdfsave and \pdfrestore were broken + +* Valid user_defined whatsits nevertheless were generating errors. + + +============================================================== +Luatex beta-0.28.0 was released 20080630 +============================================================== + +There is one new feature: + +There is now experimental support for non-trivial discretionaries +following explicit hyphens. In analogy to \prehyphenchar and +\posthyphenchar, there are two new parameters \preexhyphenchar en +\postexhyphenchar. Both new parameters default to zero (nothing). +When set to a nonzero value, the parameter is added to either the +pre- or post- break text. Note that this is *in addition to* the +hyphen already in the input. Testing and comments are very welcome. + +Here is a short example (no idea what is says): + + \pdfoutput=1 + \hsize=2in + \postexhyphenchar=`- + Seria bom se eu + pudesse t\^e-lo mantido como amigo, mas por + mais bem-intencionado que eu fosse, n\~ao + foi possivel + \bye + + + +Bugs fixed compared to 0.27.0: + +* Words that started off with a character with a zero \lccode + were never hyphenated at all. + +* There was a bug in the new active characters code that prevented + the latex format from being built (with Invalid character error). + +* There is a temporary fix for the sometimes appearing "Font has a + bad FontBB" message from Acrobat. + +* \leaders did not actually stretch enough (the last bit of glue + that has to line up the line endings was never output to the PDF). + +* Bad paragraph-related callbacks could result in luatex crashing. + +* The pre_linebreak and post_linebreak filters were never called + when \output was active (this was a leftover of a superceded + optimization). + +* 'skipping' language codes when setting up \patterns c.s. did not + work (it used the next empty slot instead of the actual value of + \language). + +* Using multiple 'attr' keywords on box items could cause random + crashes. + +* Calling lang.hyphenate() with one argument (without specifying a + tail node) could crash. + +* The luatex pdf banner and version reporting is cleaned up a bit. + +* Conflicting patterns inside \patterns now give an error: + ! Conflicting pattern ignored. + (duplicate identical patterns are ignored without error). + +============================================================== +Luatex beta-0.27.0 was released 20080624 +============================================================== + +Bugs fixed compared to 0.25.3: + +* Unicode reencoding support for non-standard (i.e. older) + Type1 fonts is now somewhat less broken than it was (#25) + +* .vf fonts using specials crashed luatex + +* luatex would crash on --\par (#33) + +* An attempt is made to get a sane default value for StemV in + the created pdf (#32) + +* We can now guarantee that %PDF-1.* header is printed before + the first pdf.print() output + +* lang.hyphenate() was broken + +* insert_before(a,a,b) was broken (#37) + +* argv[0] is now cleaned up before being used as a default for + mem_name and prog_name (#28). + +* luatex would crash on loading extended fonts (fonts loaded + via lua callbacks) from a format file. + +* The fix for pdftex bug #799 is backported from pdftex 1.40.4. + +* slnunicode had a bug in the unicode.utf8.gmatch iterator. + +* Queries of nonexisting fontdimens could cause a crash. + +* luatex would crash on {\textdir TLT\pardir TLT x\break\par } + +* Fixed wrong placement of lines in mixed-direction paragraphs + that could happen in some situations. + +Other news: +* Luatex now includes luasocket (#35) + See http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/ + for usage. + There is a new commandline option: --nosocket to disable this, + and that is also implied by --safer. + + NOTE to the binary builders: there are some unfixed configure + problems when you need to add a specific library to get socket + support on your platform. You probably will have to edit the + generated Makefile by hand (search for 'socketlib'). + +* There is ongoing development to the 'img' and 'mplib' libraries. + See the reference manual for details. + +* The 'character commands' in virtual fonts now support image + inclusion. See the reference manual for details. + +* Lua error messages now include the call stack. + +* \directlua and \latelua have been extended to accept a 'name' + keyword. The argument is a token list that is used as the lua + name of this chunk in lua error messages and call stack prints. + (#42) + +* The lua chunk names can be interfaced via a new virtual + table called lua.instancename, the values in that function as + defaults in the absence of 'name' keywords. + +* The 2-plane limit on active character range is removed (#12). + +* Subsetted TTF fonts in the PDF now retain the cmap table. + +* There is a new Lua variable os.selfdir. This contains the + full absolute pathname of the directory that the executable + resides in (with symlinks resolved) + +* There is a new function os.uname() this returns a lua + table containing various platform information items. + +* The node library now uses text strings for direction specifiers + instead of numbers. See the reference manual for details. + +* The 'E' (edit) as error response functionality is now a noop. + +* Adding luatex 0.25.3 to texlive resulted in a few minor backports, + in particular: Support for mktexfmt is added, and luatangle now + identifies itself as such (instead of calling itself otangle). + +* We fixed a whole series of portability problems (but + we probably introduced new problems as well). + +* Most (all?) files now have a corrected Copyright header, + and link in $Id$ and $URL$ into the object file. + +* Some unnecessary files were removed from the distribution. + +============================================================== +Luatex beta-0.25.3 was released 20080418 +============================================================== + +Bugs fixed: +* Pdftex bug no. 936 (sarovar) regarding vertical + positioning of embedded PDF files if depth parameter is given. +* Luatex gave bogus lua return values for the tex.wd/hd/dp + values of void boxes +* A few bugfixes in mplib (square pens caused hangs, elliptical + pens caused confused output) +* Hyphenation of uppercase words (\uchyph) was broken +* Output image placements corrected for all 8 transform cases + also when artbox etc. is used +* There were missing maketexstring() calls in error messages +* Math display contents were sometimes prematurely freed during + the placement of the equation number +* Setting \language=-1 could cause crashes due to an array + index going out-of-bounds + +Other news: +* build.sh.ppc is added to the source distribution. This is a + script that crosscompiles osx ppc binaries from osx intel +* tex.box[] is now supported (but still experimental) +* a bunch of compiler warnings are removed +* The fontforge library now dump AAT feature tags as and + "" string +* The new function font.nextid() predicts the next assigned font id +* Some source code changes are backported from texlive + +============================================================== +Luatex beta-0.25.2 was released 20080410 +============================================================== + +* Updated to MPlib 0.40 +* Bugfixes and cleanup in the lua img table code +* Fix \pdflastximagepages bug from pdftex +* Fix for very large tex.print strings +* Update to Lpeg 0.8.1 +* &D Bugfix for Type1 fonts when out-of-range characters + are marked as 'used' + +============================================================== +Luatex beta-0.25.1 was released 20080321 +============================================================== + +* Updated to MPlib 0.30 (that is now becoming usable) +* The build requirement for a pre-installed ctangle is gone + (thanks to Martin) + +============================================================== +Luatex beta-0.25.0 was released 20080311 +============================================================== + +New: + +* mplib library: + This version features an embedded MP interpreter whose output + can be directly accessed from lua code (mplib), without calls + to an external "mpost" command. Of course it has bugs and + limitations (makempx does not work, for example) but keep in + mind that it is only an initial attempt. + See the manual for more details. +* img library: + ** img.immediatewrite() is added + ** images now accept a 'transform' key + ** widths etc. can now be given as width="100mm" + +Fixed: + +* \parshape handling was completely broken since 0.20.0+ +* when \pdfprotrudechars was in effect, an assertion failure + could happen when embedded \hboxes in the paragraph appeared + at the end of a line. +* import of otf fonts with contextual lookups has been debugged, + thanks to a patch by GW himself. +* compiling with gcc 4.2.3 is now supported +* if you want to build from source, you need a pre-installed ctangle. + + +============================================================== +Luatex beta-0.22.1 was released 20080227 +============================================================== + +* The macnames.c source file for building ttf2afm is restored. +* "make depend" in luatexdir now works again +* luatex sometimes crashed because it attempted to expand an + already expanded font +* luatex aborted when --progname was given but no format name. + It now sets the format name to the given progname in that case +* sometimes paragraphs with near-empty lines could cause a crash +* img.supportedtypes() had a bug causing it to crash +* img.supportedtypes() has been renamed to img.types for consistency +* img.boxes() added, returns strings representing bounding boxes +* img.node() added, returns a whatsit node cf. \pdfrefximage +* node.write() now accepts multiple arguments +* the program_name_set switch was not set automatically from C, + causing errors unless lua code called kpse.set_program_name() + explicitly +* kpse.set_program_name() can now be called more than once + in a single run. +* os.spawn{...} and os.exec{...} could cause crashes because of + a memory allocation error + +============================================================== +Luatex beta-0.22.0 was released 20080215 +============================================================== + +* We now have an official bug tracker: http://tracker.luatex.org +* A new lua library (img) is added that allows a direct + interface to the image handling of luatex. You can use this + to include images from lua code instead of via the more + traditional \pdfximage cs. See the manual. +* An optional equal sign after \{pre,post}hyphenchar is now + allowed. +* os.exec() has been extended, and os.spawn() added. These + functions have support for quoted strings, and they + also accept a table with preseparated command arguments. +* New string constants os.type and os.name are provided. +* node.last_node() is added. This pops and returns the last + node from luatex's 'current list' +* node.write() is added. This appends a node to the end of + luatex's 'current list' (experimental). +* The strict check on unicode compliance in pattern files + is dropped. Patterns files still have to be in proper UTF-8 + encoding, but the error for non-Unicode character values + (like 0 - 31 and 127 - 159) is dropped. +* \pdfadjustinterwordglue, \prependkern, \appendkern + and associated \XXXXcode arrays are gone. +* The rest of the pdftex font arrays are now merged into + the new luatex font data structure. This means that you + can now set up font expansion from lua code, and that a few + font-related limits are gone. +* The 'top_skip' field in 'insert' nodes is renamed to 'spec', + for improved consistency. +* kpse.show_path() added. This behaves just like + $ kpsewhich --show-path +* The unicode.utf8 functions now also accept values in the range + 1.114.112 - 1.114.367 that is used by LUATEX for raw byte output. + +What's been fixed: + +* Better node memory (de)allocation error tracking and messages +* Compilation on MacOSX 10.5 was broken +* There was a bug in node.insert_after +* Use of \{pre,post}hyphenchar was broken +* lfs.permissions was leaking memory +* Some warning and error messages are improved a bit +* A set of bugs in character protrusion, this seems to be working + ok now. +* Also, a set of bugs in font expansion. This now works in most + cases but is not quite bugfree yet (problematic files for testing + are welcomed). +* The functions in the kpse library would crash luatex if + kpse.set_program_name() was not yet called. gives an error now. +* Alignments with spanned columns could cause crashes +* A patch is added for problems with filename parsing on the + "first input line" (by Jonathan Kew) +* The hpack_filter and vpack_filter were only called for lists longer + than one node. +* Luatex is now more forgiving about font subsets being smaller + than their expected size (issues a warning instead of aborts now) +* A "double-free ignored" error for paragraphs with lines starting + with discarded items was fixed. + +============================================================== +Luatex beta-0.20.2 was released 20071217 +============================================================== + +* some portability fixes to the build scripts +* a fix for multi-\span in alignments causing unbreakable + loops +* manual improvements from Jonathan Sauer +* fix for undefined csnames in \directlua if + web2c's hash_extra is nonzero +* fix for LR text inside of a RL document +* fix for open_read_file callback not being called + unless find_read_file was also registered +* removed the ocp status message when \ocps are not + actually used +* "unicodeenc" in the fontforge to_table renamed to + "unicode" for improved consistency + +============================================================== +Luatex beta-0.20.1 was released 20071207 +============================================================== + +* texlua was broken on Solaris because the some C header + files were loaded in the wrong order. +* os.tmpdir() now accepts an argument, making it easier + to use. It now generates more unique filenames when + it is called repeatedly in one run. +* The --luaconly commandline switch is now documented + in the --help text. +* The new extended hyphenation exceptions were severely + broken. +* \pdfprotrudechars could cause luatex to abort with an + assertion failure. +* There was a bug in the \span code that could cause endless + loops. +* The simple forms of \leaders were messed up on windows + because a variable was not properly initialized. +* Non-grouped \textdir commands created invalid output. +* e-TeX's pseudo files were not closed properly in ini mode. +* The luatex.web now weaves properly again. +* I made some small improvements to the manual. + +============================================================== +Luatex beta-0.20.0 was released 20071205 +============================================================== + +News compared to the last beta (0.11.2) is as follows: + +* Completely overhauled hyphenation and ligkern application, + including the addition of a new "lang" table in lua to + interface to the language parameters, some extra functions + in the "node" table, and a few extra callbacks ("hyphenate", + "ligaturing", "kerning", "post_linebreak_filter"). + + There is a new chapter in the manual to document all the + changes to the hyphenation and line breaking algorithms, + it is simply too much to list here. + +* the interface of the pre_linebreak_filter,hpack_filter, + vpack_filter, and pre_output_filter has changed slightly. + +* boxes can now get explicit attributes different from the + currently active set, using a syntax like + + \hbox attr2=12 attr3=-1 to 12pt {Hi!} + +* lpeg is now at version 0.7 + +* a whole series of exotic bugs and compiler warnings are + fixed, mostly thanks to the watchful eye of Fabrice. + +* texio.print now accepts multiple strings as arguments. + +* the lua functions os.sleep(), os.times(), os.gettimeofday() + and os.tmpdir() have been added. + +* lua now comes with the coroutine (coco) patches from the + luajit project applied. + +* the banner line no longer claims to be TeX. + +* a bunch of bugs reported on the mailing list have been + fixed (I hope all of them). + +* (internal) we found lots of small ways to speed up lua + node processing. + +* (internal) the node (de)allocation functions have been + rewritten, so that absolutely all nodes now have a type, + even the ones with variable sizes. + + +============================================================== +Luatex snapshot-20071029 was released 20071029 +============================================================== + +* Completely overhauled hyphenation and ligkern application. + + There is a new chapter in the manual to document all the + changes to the hyphenation and line breaking algorithms, + it is simply too much to list here. + +* the interface of the pre_linebreak_filter,hpack_filter, + vpack_filter, and pre_output_filter has changed slightly. + +* lpeg is now at version 0.7 + +* a whole series of exotic bugs and compiler warnings are + fixed thanks to the watchful eye of Fabrice. + +* texio.print now accepts multiple strings as arguments. + +* The lua function os.sleep() is added + +============================================================== +Luatex beta-0.11.2 was released 20070918 +============================================================== + +* Pdf inclusion and subsetting of CID-based opentype fonts + now works as it should. + +============================================================== +Luatex beta-0.11.1 was released 20070918 +============================================================== + +A quick list of what is new and fixed since beta 0.10.2: + +New: +* pfb+afm fonts can now be used in 'wide' (encodingbytes=2) mode +* searching in PDFS using 'wide' fonts now works reasonably well + (based on the tounicode feature) +* related to that, tounicode information can now be passed + on inside the font metrics table +* font subsetting is now supported for CID-based OpenType fonts + (however, there is a known bug with KpozMinProVI-Regular.otf) +* fontforge's warning and error messages are now intercepted + and passed on to the lua code as a second return value of + the fontforge.open() function +* the new primitive \suppressfontnotfounderror can suppress + the TeX error for "Font not found" +* The lua function font.current can now be used to set TeX's + current font + +Fixes: +* set_attribute(-1) is now the same as unset_attribute() +* OpenType lookups with glyph classes would crash luatex +* luazlib would not compile on debian (fix from Norbert) +* CID-based fonts would crash luatex +* Bare CFF should be read in binary mode (fix from Akira) +* VF processing did not process packets containing zero bytes properly +* the truetype collection (.ttc) handling is fixed, so that all + of the fonts inside a collection can now be used reliably +* application segfaults and stack overflows are intercepted + so that luatex can quit a bit more gracefully +* an assertion failuer on systems with signed chars (linux-powerpc) + is fixed +* a crash on AMD64 linux was fixed +* the lua "pdf" table code was wrong +* \ifcsname did not work properly for UTF-8 characters +* Use of the math-related functions using make_fraction (like \atop) + caused a crash +* \handling of \if\noexpand was wrong +* applied a patch that cleans up XForm and page calculations +* "autoconf" support from zziplib is stripped + +============================================================== +Luatex beta-0.10.2 was released 20070814 +============================================================== + +Bugs fixed: + +* the primitive \span was completely broken +* \pdfexpandfont (font expansion) misbehaved if it was used more + than once +* virtual fonts: sometimes they used the wrong internal font id, + loading vf fonts via fonts.read_vf() was impossible, and sometimes + virtual fonts created segfaults +* while dumping formats, the last font parameter for each font was not + dumped at all +* zziplib was always compiled with pre-installed zlib headers, instead + of the ones in the build tree +* lua 5.1.2 has trouble quoting ^Z characters etc, the tentative patch + for lua 5.2 from Luiz fixes that, hopefully +* fontforge.font('font.pfb') now properly parses AFM boundingboxes +* non-existing files in the argument for fontforge.open() or + fontforge.info() could cause segfaults, now it generates an error + instead +* fontforge.open() did not return character widths for vertical fonts + as it should +* on Windows, fontforge believed that ttc files (TrueType Collections) + were actually directories. ttc processing is still not 100% correct, + but it is getting better +* the build system used explicit 'make' sometimes +* the auto-growing string pool was not used everywhere +* there were some typos in the documentation parts of the pascal web +* use of \parshape could easily exhaust all available memory + + +New features: + +* support for applying Adobe Feature files (.fea) and Adobe Font + Metrics (.afm) is added to the fontforge library +* fontforge.info() will now return an array of tables for the contents + for ttc files +* support for a 'texluac' personality was added, to replace the 'luac' + command from the official Lua distribution + +============================================================== +Luatex beta-0.10.1 was released 20070719 +============================================================== + +This was a hotfix because beta-0.10.0 was completely broken. + +============================================================== +Luatex beta-0.10.0 was released 20070718 +============================================================== + +The latest version of the manual is included in the package, and I +am not going to repeat all of that. There were some minor changes +compared to the previous snapshot, but mostly just bugfixes and +documentation improvements. + +============================================================== +Luatex snapshot-20070626 was released 20070626 +============================================================== + +* Integrated the lua library lzlib, this defines tables with + bindings for zlib (including eazy-to-use gzip support) +* Updated to slnunicode version 1.1 +* Some small cleanups in the sparse array handling +* Moved the raw byte support out of the valid unicode range +* Fixed a bug in the OFM font reader +* Removed the pdftex snap nodes (and associated primitives) + + +============================================================== +Luatex snapshot-20070622 was released 20070622 +============================================================== + +Not a lot of news, but it fixes a few important bugs in the lua +node processing. Also a few utility functions are added: + +* tex.round() + rounds and bounds checks a lua number to make sure it is + a valid tex integer. +* tex.scale() + multiplies a number (or the numeric values in a table) + with a fixed quantity, and calls tex.round() on the result. +* node.has_field() + Test if a node has a specified field name +* node.remove() + removes a node from a nodelist, while keeping the list intact +* node.insert_before() + inserts a new node into a nodelist, just before a specified + location node +* node.insert_before() + inserts a new node into a nodelist, just after a specified + location node +* node.hpack() + packages a nodelist into a hlist node + + +============================================================== +Luatex snapshot-20070619 was released 20070619 +============================================================== + +* The lua node processing interface is completely reworked. + It is now completely based on userdata, and uses a new lua table + called 'node' to hold the methods. More detailed information + is in the manual (of course). + +* There is a fifth node processing callback: + pre_output_filter + this is executed just before the packaging of \box 255. + +* The hpack_filter and pre_linebreak_filter callbacks now + receive an extra argument indicating the number of top-level + glyphs in the node list. + +* Virtual fonts can now contain a 'node' key in the glyph + commands: the value should be a hlist node (i.e.: a horizontal + box), and that will then be output for each character access + in that font. + +* A new set of registers is added, called \attribute. These are + values that will be automatically attached to nodes created in + their scope. More information in the manual. + +* Direct read/write access to TeX's box registers is addded to + the lua 'tex' table. + +* TeX's main memory now grows dynamically, and the (de)allocation + routines have been rewritten completely. + +* The 'kpse' table is extended with extra interface functions, to + allow texlua to be used as a scripting engine. + +* The \pdftexversion command now returns 200, not 140. + +* The displayed banner and --version screens are cleaned up. + +* The format file is now RLE compressed. Not as small as before, + but unpacking is much faster. + + +============================================================== +Luatex snapshot-20070426 was released 20070426 +============================================================== + +This past month I have been busy with nodes and lists of nodes, +so the big new feature in this release is that there are four +callbacks that operate on node lists: + + buildpage_filter + pre_linebreak_filter + hpack_filter + vpack_filter + +The preliminary documentation for these is in the manual, but the basic +idea is that you can filter a node list just before LuaTeX starts doing +something with it (like line breaking). This functionality is not stable +yet: the node presentation of the various node types is pretty much OK +now, but keep in mind the following: + + * math noads and math typesetting are not handled at all (yet) + * not all hpacks and vpacks are intercepted (yet) + * the nested node list handling will probably change + * A conversion tool for nodes to/from dictionaries is planned, + but not done yet + +The other changes in this snapshot are various bugfixes (for builds +on various platforms as well as font issues) and speedups (in the +execution of callbacks and the creation of lua font representations). + + +============================================================== +Luatex snapshot-20070322 was released 20070322 +============================================================== + +* I have changed the token_filter callback quite rigorously, + mostly because of speed issues. The raw speed of trivial + lua token handling is now only about 20 times slower than + the native handling. Not bad at all, considering it has to move + between interpreted and compiled code for each and every + token. If you do not run the token filter inside \output, + the effective run speed difference should not be much more + than a factor 1.5. + + Two big differences: you have to call token.get_next() + yourself, and the token table is now a three-item array + instead of a five-key hash. The minimal example changes to + + \directlua0{ + callback.register('token_filter', function () + return token.get_next() + end) + } + + more details are in the manual. + +* I've fixed a few bugs in the handling of Opentype TTF, and added + a new key in the font definition table: + + f.encodingbytes = (1|2) + + The default is 2 for opentype and truetype format, 1 otherwise. + Later on, it will become possible to have a type1 font in 2-byte + (CID) encoding or a truetype font in traditional encoding (1-byte), + but I have not covered all cases yet. + + + +============================================================== +Luatex snapshot-20070309 was released 20070309 +============================================================== + +* The OCP debug information is removed again. + +* There is a new callback that I am quite excited about myself: + 'token_filter'. + + +A bit of text from the reference manual: +-------------------- +This callback allows you to change the modify any lexical token that +enters the \type{main_control} function before \LUATEX\ executes the +associated command. + +Note: not all tokens can be intercepted yet, only those that are `seen' +by \LUATEX's main control function. Supplemental tokens like the bodies +of macro definitions and the right-hand side of register assignments +are not seen. For now, this is intentional. + +\startfunctioncall + function (table ) + return table + end +\stopfunctioncall + +Calling convention for this callback is bit more complicated then for +most other callbacks. Initially, lua function will be called with the +next token from \type{get_next()} as argument, represented as a small +lua table. The function should either return a lua table representing +a valid to-be-processed token, or something else like nil or an empty +table. + +If your lua function does not return a table representing a valid +token, it will be immediately called again with yet another token +from \type{get_next()} as argument, until it eventually does return +a useful token. + +But if the function does return a usable token, then that token will +be processed by \LUATEX. Afterwards, the function will be called +again, but now without an argument. This is repeated until it stops +returning tokens. Then processing reverts back to the other branch. + +The point behind that roundabout calling convention is that it +allows the lua function to buffer tokens for various uses. That in +turn makes it possible to do some really advanced things like +replacing OTPs. + +Now about that table. The table that the function will receive +contains four fields: + +\starttabulate[|l|i|p|] +\NC Key \NC type \NC Explanation \NC\FR +\NC cmd \NC string \NC A representation of \LUATEX's internal + command code\NC\NR +\NC chr \NC number \NC The command code modifier\NC\NR +\NC cs \NC string \NC If the token came from a csname, this + is that csname\NC\NR +\NC mod \NC character \NC A single character string representing +the current processing mode. One of {\bf v}ertical, {\bf h}orizontal, +display {\bf m}ath, {\bf n}o, internal {\bf V}ertical, + restricted {\bf H}orizontal, or inline {\bf M}ath mode.\NC\LR +\stoptabulate + +If you modify the table before returning it, then it is wise to return +either a (\type{cmd}, \type{chr}) pair, or a \type{cs} string. That is +because if both options are present, the pair has precedence and the +string is ignored. On the return table, {\bf mod} is ignored always. +-------------- + +I have no long example code yet and it is not as complete as one +would want it to be because it is not intercepting everything that +comes in, only the bits that are triggered by the main control +loop. + +I decided to do a fast snapshot release for two reasons: + +* It is one of the easier extensions to get started with if you want + to learn a bit about lua programming + +* I would welcome feedback on the token interface, because it will + be needed in other places as well, soon. I am still not sure + whether converting the command to/from strings is worth it, for + example. And maybe it would be less confusing if you could return + a list of tokens instead of being called repeatedly? + +Here is the trivial example to get you started: + + \directlua0{ + callback.register('token_filter', function (t) return t end) + } + + +============================================================== +Luatex snapshot-20070307 was released 20070307 +============================================================== + + +* Non-CID PostScript-based Opentype fonts are now combined over + the entire document, and properly subsetted. The code is + borrowed from xdvipdfmx with some minor adjustments + + Adding support for CID-keyed OpenType fonts would not be hard + but at the moment I lack example input (and incentive). + +* A small extension to the virtual fonts structure: you can use + + f.fonts[1] = { 'id' = 38} + + to do a backreference to a previously defined font. This saves quite + a few computations + +* There was a bug in the handling of \leaders in the output whereby + it's width was taken to be twice what it should be while writing + to the PDF, fixed now. + +* The font inclusion code is cleaned up a bit by Hartmut. + +* Some compilation problems were fixed. + +* There is (quite a bit of) debugging information printed out when + OTPs are in use, because I am tracking down a bug reported by Idris. + + The input of each and every OTP step is shown on the terminal in + a line line this: + + [57902][1568][58423][1568][58408][1568][58921] + + those are the decimal values of ocp i/o characters. If you don't + need them, don't worry about it. + +============================================================== +Luatex snapshot-20070302 was released 20070302 +============================================================== + +* The 'snapshot version' banner is now calculated dynamically + at build time. This aids in figuring out what binary people + are actually running, but it can possibly break the build on + systems that do not have a `date` command. + +* The do_vf() function that checks for virtual font existance + is now run immediately after the font definition instead of + being postponed until characters are output. + +* The 'define_font' callback interface has changed a little. + It is now: + retval = function (name,size,fontid) + + where fontid is the internal font number of the font that + is currently being defined, and retval can be either a table + (as before) or a different, previously defined fontid. This is + useful if a previous definition can be reused instead of + creating a whole new font structure. + +* The internal font data structure has been redone. Glyph index + inside a font is now handled by a sparse array, so that use + of e.g. 0xFB01 (fi-ligature) no longer creates a 64000+ entries + character array. + +* The internal cache-ing of font metric information is turned + off completely, because it was based on the assumption that + name + size were a unique identifier for a font. This can no + longer be guaranteed. + +* word boundary processing now works OK again, thanks to the + introduction of two virtual characters in the font table + definition. Besides the normal numeric entries in the + f.characters table, there can now also be two string keys: + "left_boundary" and "right_boundary". The ligatures and kerns + of the 'left_boundary' character are used for the pre-word + boundary processing, ligatures and kerns between characters + and 'right_boundary' are used for the post-word processing. + +* Lua font table references are no longer cached by the + executable ,in order to preserve memory. (the only downside + is that font.fonts[] access is now slower because of the need + to recreate the lua table). + +* There are other some small changes to the font table formats. + Please see the manual for details. + +* A 'real' font can now still have virtual characters if they + are loaded via lua. Just set the 'commands' section and/or + the 'fonts' array to your liking, and it should work out. + + If you have created no 'fonts' array at all, then the default + font (indentifier '1') is the current font, so that you + can create virtual duplicates of already existing characters. + + Note: this does not work the other way. There can not be + 'real' characters in a virtual font! + +* Truetype-based opentype fonts no longer require Acrobat 7 + t(hey are now written out as if they are normal truetype). + +* A lua init script can now set 'texconfig.formatname' and/or + 'texconfig.jobname'. If ther is no file or format specified + on the commandline, then, if, one of those keys is present, + that key will be used instead of simply quitting with an + error. + +* Placement of boxes and rules in right-to-left mode is debugged, + and now seems to work ok. + +* Virtual font loading is debugged. + +* Some memory leaks are resolved + +* HZ font expansion should work ok again, but is not tested. + +* a few of the warning during opentype loading have been removed + because the problems are rather harmless and turned out to be + triggered by almost every font. + + +============================================================== +Luatex snapshot-20070218 was released 20070218 +============================================================== + +* The pdftex stuff is now updated to 1.40.3 + (and on top of that, it still has those extra patches announced in + snapshot 20070202) + +* The virtual font parser is debugged and now appears rather stable. + +* There is one extra virtual command: + + "commands" = { + {"slot", 1, 97}, -- place character 97 'a' in local font 1. + } + + This is just a shortcut for {"font",1}, {"char", 97} + +* Some small memory leaks have been fixed. Luatex does not leak big + time, but I'd like to get back to valgrind reporting '0 out of 0', + instead of the current 800 bytes or so (that is a slow process). + +* You can read a truetype or opentype font from within lua code + using font.read_ttf() or font.read_otf(), respectively. + + This feature uses a fair bit of the fontforge code, making the + binary rather a bit larger than before. Just so you know. + + Apple (AAT, as well as encoding) support is still largely missing, + and bitmap-only and old Multiple-Master truetype fonts are not + supported at all (and never will be). + + The output format is (shadily) documented in the reference manual. + At the moment, it very closely resembles the internal font stucture + that is used by fontforge. + +* LuaTeX can now write wide OpenType fonts to the PDF file. + + There is no subsetting support yet, and a ToUnicode CMap is also + still missing, but nevertheless it is already somewhat useful. The + rule is very simple: if a font uses code points above 255, then it + is considered to be a `wide' font, and it will be written out as + a Type0 CID-keyed font to the PDF. + + Caveat: Getting suitable metrics into LuaTeX can be a bit of problem + right now, because font.read_otf() does not produce anything that + can be fed back into define_font without extra processing. Hans has + some experimental Lua code for ConTeXt (of course :-)) and that is + how I know it works. You can expect a nicer interface soon, + hopefully next week, in the form of a simplistic table conversion + routine. + +* I have started work on supporting Aleph's bidi typesetting in PDF + mode as well, simple text seems to be largely ok. More complicated + documents will no doubt still show some bugs, but fixing those will + be easy (once they are discovered). Exactly what happens with specials + is not yet investigated. + +* Omega's (16-bit) wide virtual fonts now work OK in PDF mode. This + means that many Aleph files can now be run in PDF mode directly. + (the documents that use UTF-8 input encoding) + + +============================================================== +Luatex snapshot-20070202 was released 20070202 +============================================================== + + +* The pdftex stuff is now updated to 1.40.2, and on top of that, it has + + - an extra patch from Han The Thanh that adds a primitive to control + the merging of fonts from external pdf images (\pdfreplacefonts), + and a bugfix for virtual font handling. + + - an extra patch by Hartmut Henkel that removes a number of malloc()s + and free()s from the calls to the compression library, thereby + making luatex run a bit faster. + +* luatex now happily accepts the following low-level syntax: + + \font\myfont = + + It feeds the to either kpathsea or a lua script for + further processing after stripping the braces. + + In itself, this is not all that useful, but the reason for this + syntax extension is that it paves the road for a macro package + to do something like this: + + \font\myfont = {font="Times New Roman", color="\darkred", + encoding="ec", features="liga", size=10bp} + + without having to resort to system-specific quoting mechanisms. + Macro (and other) expansion takes inside the braced argument. + + (I am considering adding this extension to \input as well). + +* It is now possible to define a font into the font.fonts[] + directly from lua, but becayse use is limited, I am only + mentioning it to be complete. + + Syntax: + id = font.define( font) + +* There is a (not very reliable yet) virtual font parser accessible + from lua. + + Syntax: +
vfdata = font.read_vf( name, size) + + The interpreter tries to give a reasonable representation of a + virtual font file (the .vf file). Besides a few simple top-level + items: + + designsize -- in scaled points + size -- also in sp + name -- the file name + checksum -- the vf checksum + header -- the header comment (if any) + + it also has a top-level array 'fonts' wherein each item is a mini- + array describing one of te mapped fonts. An example makes this + easy to understand + + "fonts" = { {"ptmr8a",655360}, {"psyr", 600000} } + + says that the first referenced font (index 1) in this virtual font + is ptrmr8a.tfm loaded at 10pt, and the second is psyr.tfm loaded + at a little over 9pt. These index numbers are used by the character + command definitions that follow. + + At top level, there is a 'characters' array, just as for a normal + font, except that each item has only two keys: + + "width" -- the tfm width (as stored in the .vf) + "commands" -- an array of virtual font commands for a character. + + each of the items in the 'commands' array is itself a tiny hash. + + Each of those mini-hashes represents a single character packet + command. Here is a 'commands' entry that contains every possible + one at least once: + + "commands" = { + {"push"}, -- remember where we are + {"right", 5000}, -- move right 0.08pt + {"font", 1}, -- select the fonts[1] entry + {"setchar", 97}, -- place character 97 'a' + {"pop"}, -- go all the way back + {"down", -200000}, -- move *up* about 3pt + {"special", "pdf: 1 0 0 rg"} -- switch to red color + {"rule", 500000, 20000} -- draw a bar + {'special',"pdf: 0 g"} -- back to black + } + + +* But the big news is that you can now define your own virtual fonts + on the fly, by adding a few statements to the table returned to + the 'define_font' callback. + + There are a few requirements: + + - The table has to have a top-level key 'type', and it's value + must be 'virtual'. + + The presence of this key with the specific value 'virtual' + will trigger handling of the rest of the special virtual font + fields in the table, but the mere existance of 'type' is + enough to prevent luatex from looking for a virtual font + on its own. + + Therefore, this also works 'in reverse': if you are absolutely + certain that a font is not a virtual font, assigning the value + 'base' or 'real' to 'type' will inhibit tex from looking for a + virtual font file, thereby saving you a disk search. + + - There must be a top-level 'fonts' array, as explained above. + Any fonts that are not yet known to luatex at that moment, + will be loaded automatically (Warning: do not ever use a font + in 'fonts' with the same name you will return in the table you + are defining right now!). + + - Each and every character in the fonts needs to have a 'commands' + key, as explained above. + + The main point behind these restrictions is that a font is + *either* a base font *or* a virtual font. It cannot be both + at the same time. + + +============================================================== +Luatex snapshot-20070126 was released 20070126 +============================================================== + + +* Underscores in pascal identifiers are now retained. + + This took quite a bit of work. The web2c conversion tools + needed only small adjustments, but most of the existing C + code depended on the removal of the underscores. I had to + go through changing many lines. 99% of all identifiers are + now written the same on the pascal side as on the C side. + This makes writing interface code quite a bit less confusing. + + Not everything is completely clean yet, because I did + not want to change the web2c-specific C files. I often + took the other approach and removed the underscores + from the web2c options (like 'parsefirstlinep') in the + change file instead. Ugly, but predictable. + + There is about a dozen or so of #defines left, that map + memoryword -> memory_word + strpool -> str_pool + etc. + +* The virtual font parsing and interpreting is now done in C. + (this is because it needs to be interfaced with the lua-based + font loader) + +* I am in the process of merging: the VF stuff; the TFM stuff; + the lua font loading; and the pdftex font backend into one + interface, so there were some smallish changes relating to + that as well. Nothing worth mentioning just yet except that + luatex now will read "ovf" files as well as "vf" files. + +* There are a few really small bugfixes for bug reports I received + on this list and by email. + +============================================================== +Luatex snapshot-20070119 was released 20070119 +============================================================== + +The largest new bit is the existence of a font.fonts array, that you +can use to query/adjust the internal defined tex fonts. See the manual +for more details. + +Two small new lua extensions are added as well: + + * os.setenv() -- to change the environment + * os.exec() -- a non-returning os.execute() + +And a bit of cleanup in the commandline processing. + + +============================================================== +Luatex snapshot-20070117 was released 20070117 +============================================================== + +* the pdftex core is updated to 1.40.1, and web2c to 7.5.6 + +* the pdftex-specific documentation is removed + +* lua lpeg library updated to 0.4 + ( http://www.inf.puc-rio.br/~roberto/lpeg.html ) + +* the C part of the lua md5 library is added to the binary + ( http://www.inf.puc-rio.br/~roberto/md5/md5-5/md5.html ) + +* --luaonly now puts the script itself at arg[0], and + preceding commandline items in the negative indices + (instead of starting the count at zero). + This new approach is compatible with the standalone lua + interpreter. + + +============================================================== +Luatex snapshot-20070107 was released 20070107 +============================================================== + +Hot on the heels of 20070105, a new snapshot. It turns out +that using the callback to define a font broke all ligatures. +This snapshot fixes that, and it has a few minor updates to +the manual. Next shapshot will be after the inclusion of +pdftex 1.40.1. + +============================================================== +Luatex snapshot-20070105 was released 20070105 +============================================================== + + * the calculations that converted lua strings into tex units + were horrendously wrong, this was discovered by Pawel. + + * io.lines() was still using the old, line ending sensitive, + code from the lua core distribution + + * The main font memory is allocated as needed^(1) instead of + statically pre-allocated. + + * ligatures and kerns are separated completely from each other, + so use of \noligatures no longer inhibits kerning as well + + * Metrics can be loaded using a callback: 'define_font'. + The value returned should be a lua table representing a tfm + file. + + * there is a new lua table: font. It has one function: + font.read_tfm() that returns a table reprentation of the tfm + contents, for use with the above mentioned callback + + * I dropped suppport for "Level 1" OFM files. I would like + to have a try at those extended font files, but I lack + examples (fonts nor documents). I am not even sure such + fonts have ever existed in the 'real world'. + + + +============================================================== +Luatex snapshot-20061208 was released 20061208 +============================================================== + +* There is a new switch: --safer. This disables a number of lua + functions that are more or less dangerous (a detailed list is + in the manual) + +* Two longstanding bugs have been fixed: \latelua works once + again (patch by Hartmut) and a bug that caused mysterious crashes + turned out to be a problem inside the paragraph builder + (reconstitution of ligatures) + +* Six new string iterators have been added to the string library: + string.characters (one 1-letter string) + string.bytes (one byte) + string.characterpairs (two 1-letter strings) + string.bytepairs (two bytes) + string.utfcharacters (a one-character utf-8 string) + string.utfvalues (a unicode code point number) + +* The top 256 values of the unicode range (starting at hex + value "10FF00) are now reserved for byte output. Characters + in that range will be written by luatex after substracting + that offset. The net result is that \char"10FFA9 is written + as byte value hex A9 = decimal 169 = copyright sign in latin1 + + This trick allows byte-oriented output to \pdfliterals and + \specials, but should be considered very experimental. + +* There is a new callback called 'process_input_buffer' that can + be used to mutate the line buffer just before LuaTeX actually + starts looking at it. + +* The statistics table now has readable items + statistics.inputid + statistics.lasterrorstring + that represent TeX's current input id and the last error string + +* The show_error_hook callback no longer receives any arguments +* There is a new switch: --safer. This disables a number of lua + functions that are more or less dangerous (a detailed list is + in the manual) + +* Two longstanding bugs have been fixed: \latelua works once + again (patch by Hartmut) and a bug that caused mysterious crashes + turned out to be a problem inside the paragraph builder + (reconstitution of ligatures) + +* Six new string iterators have been added to the string library: + string.characters (one 1-letter string) + string.bytes (one byte) + string.characterpairs (two 1-letter strings) + string.bytepairs (two bytes) + string.utfcharacters (a one-character utf-8 string) + string.utfvalues (a unicode code point number) + +* The top 256 values of the unicode range (starting at hex + value "10FF00) are now reserved for byte output. Characters + in that range will be written by luatex after substracting + that offset. The net result is that \char"10FFA9 is written + as byte value hex A9 = decimal 169 = copyright sign in latin1 + + This trick allows byte-oriented output to \pdfliterals and + \specials, but should be considered very experimental. + +* There is a new callback called 'process_input_buffer' that can + be used to mutate the line buffer just before LuaTeX actually + starts looking at it. + +* The statistics table now has readable items + statistics.inputid + statistics.lasterrorstring + that represent TeX's current input id and the last error string + +* The show_error_hook callback no longer receives any arguments + +* The statistics table now has readable items + statistics.luabytecodes + statistics.luastates + statistics.luabytecode_bytes + statistics.luastate_bytes + for memory statistics reporting + + +* The statistics table now has readable items + statistics.luabytecodes + statistics.luastates + statistics.luabytecode_bytes + statistics.luastate_bytes + for memory statistics reporting + + +============================================================== +Luatex snapshot-20061204 was released 20061204 +============================================================== + +* The LuaTeX interpreter can now be run as a standalone lua script + processor, by using a commandline like this: + + luatex --luaonly=luatools.lua + +* Luafilesystem (http://www.keplerproject.org/luafilesystem/ ) is + included. + +* There are a total of eight new file discovery callbacks: + find_vf_file + find_ocp_file + find_map_file + find_enc_file + find_sfd_file + find_pk_file + find_data_file + find_opentype_file + this enhances the orthogonality of the callback system, nothing + fundamental is changed. + +* There is a new callback called 'process_input_buffer' that can + be used to mutate the line buffer just before LuaTeX actually + starts looking at it. + +* The 'reader' and 'close' functions from 'open_read_file' now + receive the table they are defined in as a function argument, + that can be used as a per file localized data store. + +* Updated the Lua to the latest 5.1.1, with all known bug patches + from the website applied as well + +* Runtime autoloading of lua .so files is now off on all platforms. + +* The statistics table now has readable items + statistics.filename + statistics.linenumber + that represent TeX's current file name and line number + +* The support for user-defined type3 font .pgc files and the + associated 'read_miscfonts_file' callback has been removed. + (nobody used it anyway) + +* General cleanups to the source tree and build process. + +============================================================== +Luatex snapshot-20061023 was released 20061023 +============================================================== + +* there was a missing callback: find_font_file +* program_invocation_name was not set +* buf_size could not be more that 300k + + +============================================================== +Luatex snapshot-20061013 was released 20061013 +============================================================== + +Last friday I uploaded a new snapshot and today I finally +finished updating the manual to go with it. The changes all +relate to startup, file i/o, and callbacks. The main achievement +is: you can now run luatex without it *ever* initializing kpathsea. + +Because I am lazy, I have checked in the pdf of the manual +as well, so that I can say: Please look at + + https://foundry.supelec.fr/plugins/scmsvn/viewcvs.php/manual/ + /luatexref-t.pdf?root=luatex&rev=148&view=log + +for all the details. :-) + +============================================================== +Luatex snapshot-20061002 was released 20061002 +============================================================== + + +* Some infrastructure changes: + + libs/slnunicode-0.9.1/ renamed to libs/slnunicode/ + libs/zziplib added + libs/luazip added + + (zziplib is using a different version of autofoo. I know I have + messed up something in the build process, but the bit we need + compiles ok so I've postponed attempting to fix it) + +* The callback logic has changed quite a bit. + + - all callbacks are now only possible in lua state 0. + + - The callback 'input_line' has disappeared, and is replaced by + 'open_read_file'. One of the return values of that callback + is a table that defines a 'reader' function for line reading. + + See the manual for further information on this. + + - There are some new callbacks for the reading of various binary + files. The current ones are: + + "read_ocp_file", "read_vf_file", "read_data_file", "read_font_file", + "read_map_file". + + The rest of the file types will follow soon (fonts, enc files, and + images). + + - There are also some new callbacks that 'find' a file's pathname: + + "find_truetype_file", "find_type1_file", "find_image_file" + + here too, more will follow later. + + - the functions from io. that were copied to texio have been removed + again. The new callbacks do not pass file pointers around, so + they ere not longer needed + + - the 'open_write_file' is temporarily unavailable + +* startup.lua is now always loaded into lua state 0 + +* The luazip library from kepler is linked in, so there the table 'zip' + is accessible from all lua states. + +============================================================== +Luatex snapshot-20060922 was released 20060922 +============================================================== + +* The texio table has gained a new function: + + tex_file = texio.open(filename) + + returns a file handle of a type that luatex can use + internally (the return of io.open is unusable in callbacks + because it will be garbage-collected at a random time) + + +* In related news, there are two new callbacks you can define: + + callback.register('open_read_file', f) + callback.register('open_write_file', f) + + where your function should have the following conventions: + + function f (number id_number, string asked_name) + return boolean success, string actual_name, tex_file filep + end + + id_number: zero for the log or \input files or TeX's \read + number incremented by one (\read0 becomes 1). + asked_name: the user-supplied filename + + success: return false for error, true otherwise. + + The remaining two items are only looked at if you return true: + + actual_name: the true filename used (with extension!) + filep: a file object opened though texio.open() + + +* The tex.print function has an extra optional parameter: + + tex.print(ctt_id n, strings ...) + + This prints the strings using the catcode regime defined by + \catcodetable n (assuming n is valid, see below) + +* The new function tex.sprint has the same lua conventions as + tex.print, but behaces slightly different on the tex side: + + ** tex does not switch to the 'new_line' state (this implies + that leading spaces are not ignored) + ** no \endlinechars are inserted + ** trailing spaces are not removed from the argument + +* Catcode tables are a completely new feature, that allows + you to switch the current catcode regime in one simple + statement: + + \catcodetable + + Switches to the use of a different set of catcodes (table), + that is stored under the number . Such a table has to + be previously created using one of the two command below, or + the number 0 (which is pre-inititialized) + + This command obeys normal grouping rules. + + \initcatcodetable + + creates a new, global, independent catcode table with catcodes + matching the code that are predefined by initex (tex -ini). + + This allocation is global + + \savecatcodetable + + copies the current set of catcodes to a new, global, table + with id number . The definitions in this new table + are all treated as if they were made in the outermost level. + + This allocation is global + + At the end of each grouping level, items within all existing + catcodetables are restored, regardless of which one is the + currently active table. + + Catcode table numbers cannot be larger than 0xFFFFFFF (228-1) + +* There is a new lua table: lua. It contains three read-only + items: + + lua.id -- the id number of the instance + lua.version -- a luatex version identifier string + lua.startupfile -- the full filename (+path) of startup.lua + + and it also contains a read/write array: + + lua.bytecode[] -- lua executable bytecode + + This array can be used to save and restore lua functions + across lua states. The accepted values are for assignments + are functions and nil. Likewise, the retrieved value is + either a function or nil. + + The contents of the lua.bytecode array is stored inside the + format file, so it can also be used to preload lua code. + + +* The format files are quire a bit smaller than before + + +============================================================== +Luatex snapshot-20060915 was released 20060915 +============================================================== + +* There is a new TEX primitive: \formatname. It is similar + to \jobname (read-only). In initex, the expansion is empty, + otherwise the expansion is the same as the \jobname from + the initex run. + +* the lua "tex" table has been expanded with a few of the 'convert' + codes (read-only). The supported ones at this moment are: + + tex.eTeXVersion + tex.OmegaVersion + tex.AlephVersion + tex.pdftexrevision + tex.pdftexbanner + tex.pdfnormaldeviate + tex.jobname + tex.formatname + tex.eTeXrevision + tex.Omegarevision + tex.Alephrevision + + This list looks haphazard, but it really is not. These are + all the cases of the 'convert' internal command that do not + require an argument. + +* The metatables of the subtables like tex.dimen[] etc. are now + adjustable from lua (not that I recommend doing that;-)). + +* On the lua side, there is a new global value: "luaid" + It holds the internal id number of this \directlua instance. + +* There is a new lua table, "callback", that has the single function + "callback.register", used to register callbacks. This replaces + the previous concoction (see my message about snapshot 20060901). + Syntax is : + + callback.register(,function (f) ... end) + + where the is for the moment, either "input_line" + or "show_error_hook". + + This function internalizes the callback function in such a way + that you no longer have to worry about \luacallback (which has + been removed), nor does it matter if you redefine a function + accidentally. + + The internal testing for callback presence is also quite a bit + faster, thanks to this change. Callback assignments are global + and the "input_line" always takes effect starting on the next + input line to be read from an actual file. + + +* \detokenizedlua has been removed. It is functionally replaced by + the new function call tex.write(""). + + Each argument to each call of tex.write () counts as an input + line, but: + ** all catcodes on that line are either 'space' (for " ") or + 'character' for all others. + ** there is no \newlinechar appended. + +* The implementation of tex.print() has changed as well: + + ** the very last tex.print() line from a \directlua + will no longer have a trailing \newlinechar + (this is very convenient when \directlua is used + within an \edef) + ** tex.print() is quite a lot faster than before, and the total amount + of returnable text from a \directlua is now only limited by + available system RAM. However, each separate tex.print () + argument has to fit in TeX's input buffer. + +* The new primitive \luastartup can be set inside the format file + to specify the lua instance number in which a possible runtime + startup.lua script is executed (initex always uses 0) + +* There is a new primitive \scantextokens. Differences with + eTeX's \scantokens are: + + ** the last line (usually only) from \scantextokens + does not have a \newlinechar + + ** \scantextokens never raises an eof error. + + This means things like + + \edef\testone + {\scantextokens{\ifnum1=1 true}\else false\fi} + + are legal input (but potentially dangerous!). + +* If you say + local d = tex.dimen["unknowndimen"] + 'd' will now become "nil" instead of raising an error + + However, + tex.dimen["unknowndimen"] = d + is still (and probably will remain) illegal + +============================================================== +Luatex snapshot-20060908 was released 20060908 +============================================================== + +* BIG CHANGE: \directlua now runs \scantokens internally. + + There is no longer a need to call scantokens yourself, the + tex.print() output is now fed straight into a pseudo file. + This is quite a bit faster as well as easier to use, but + just in case you want it, the old behaviour is still present, + under the new name + + \detokenizedlua + + +* The texio library now has its own (partial) set of I/O commands, + so that the standard lua io library is back to the distributed + state (no more patched garbage collector) + + Note: This is really a very small change (it should not have any + impact on wellbehaved input files), but I attempt to be complete + in these notes, since there is no official documentation yet. + + +* There is a new standard library available: kpse + + The most important function in that library is find_file: + + string = kpse.find_file(string filename + [,string type] + [,boolean mustexist]) + + both "type" and "mustexist" are optional, so the function + has from one upto three arguments. + + "type" is like the '-format' argument of kpsewhich. You can + run 'kpsewich -h' for a list. The default type is "tex". + + "mustexist" is like '-must-exist', and the default is false. + If you specify "true" (or a nonzero integer), then the kpse + library will search the disk as well as the ls-R databases + + The new library also has three other functions that map + straight to kpsewhich commandline options: + + string = kpse.expand_path(string) + string = kpse.expand_var(string) + string = kpse.expand_braces(string) + +* There is a second callback possibility: + + texio.show_error_hook(string message, + string|number indicator, + number lineno) + + This command is run from inside the TeX error function, and the + idea is to allow you to do some extra reporting on top of what + TeX already does (none of the normal actions are removed). + + "message" is the formal error message tex has given to the + user (the line after the "! ") + "indicator" is either a filename (when it is a string) or a + location indicator (a number) that can means lots of different + things like a token list id or a \read number. + "lineno" is the current line number + + This is an investigative item only, comments are welcome but do + not take the syntax seriously. + + The final goal IMO is the total replacement of TeX's error + handling routines, but that needs lots of adjustments + in the web source because TeX deals with errors in a somewhat + haphazard fashion (it needs unification first). The current + hook is only for 'testing the water'. + +* It is now possible to use named items in the + + tex.count[] + tex.dimen[] + tex.toks[] + + subtables, so you can have + + tex.count.scratchcounter = 0 + local enormous = tex.dimen["maxdimen"] + + Luatex looks up the value for you on the fly. You have to use a + valid \countdef (or \dimendef, or \toksdef), anything else will + generate an error. + + In a normal TeX file, you don't do \dimen\maxdimen, but the + lua syntax seems to be a bit cleaner to me. The intention is + to evntually also allow \chardefs and macros that expand + into a number (todo) + + +* The tex table has also been extended with a large list of internal + parameters (partially read/write). It is possible to access + about every primitive that you can use after \the *and* is a + single token. So there is + + integer = tex.tracingcommands (\the\tracingcommands) + integer = tex.prevgraf (\the\prevgraf) + string = tex.output (\the\output) + + etc. for all of the internal parameters, but not the items + that need extra arguments (like \the\scriptfont ) + + The subset comprising simple integer and dimension registers + are writable as well as readable (stuff like \tracingcommands + and \parindent). + + The fact that both lists are still quite limited is a result of + the very different types of things that can occur after \the and + also on the LHS of an assignment. The remaining primitives will + be filled in when there is a real need or implementation becomes + simple, whichever comes first. + + + +============================================================== +Luatex snapshot-20060901 was released 20060901 +============================================================== + +All changes are related to lua this time, and most are quite unstable +/ experimental. But first the things that are stabel/fixed bugs: + +* A VF loading bug that turned up in some of Hans' fonts + has been fixed + +* A small series of bounds checking fixes to \ocplist has been + added to prevent the system from crashing due to array indexes + running out of bounds. + +* The Lua file searching paths are now fixed. The search path for lua + script files now contains the following items (tried in order) + 1. the local directory: + ./?.lua + (for document-specific files) + 2. the items from the expansion of kpathsea's $TEXMFSCRIPTS variable, + but only the parts containing 'lua' as a subpath: + $TEXMFSCRIPTS/?.lua + $TEXMFSCRIPTS/?/init.lua + (for format-specific files) + 3. the $SELFAUTOPARENT sibling directory named 'lib'. + $SELFAUTOPARENT/lib/lua/5.1/?.lua + $SELFAUTOPARENT/lib/lua/5.1/?/init.lua + (for files that are not related to tex) + + The search path for dynamic libraries has only + 1. the local directory: + ./?.so + (for document-specific files) + 2. and the $SELFAUTOPARENT sibling directory named 'lib'. + $SELFAUTOPARENT/lib/lua/5.1/?.so + + (of course the extension is .dll on windows, but .dlls do not + work at the moment so it will not do you much good) + +* There are two functions available within a new table called + texio: + texio.write (luastring) + texio.write_nl (luastring) + both write the luastring to the same location(s) TeX writes + its stuff. So if \batchmode is on, it writes only to the + log, inside a \write, it prints to the current write file, + etc. + + A read|write interface to TeX's "file selector" will + follow shortly. + +* At startup, luatex searches for a script named + startup.lua + in the path list I explained above. If such a file exists, it is + loaded. + + This happens right before the first input file needs to be opened + (that is after format loading, but before any \everyjob tokens). + + From within the script, you can check the value of + + tex.formatname + + that is the 'format identification' as used by TEX. When the variable + is equal to nil, luatex in in 'initex' mode, otherwise it will be + something like: " (format=plain 2006.9.1)" + + +Now for the experimental portion: callbacks. Here is what I have done +so far: + +* The main reason for wanting startup.lua is file (input) re-encoding. + For this purpose, it is now possible to set up a callback for + luatex to execute. + + If you attach a Lua function to + + texio.input_line + + then from the next input line onwards, luatex will run that + function whenever it needs a new input line from a text file. + + Your function will receive a file handle as argument, and + should return either a string or nil (with nil signalling that + the end of file has occurred). + + The trivial case is simply this: + + function reader (f) + return f:read() + end + texio.input_line = reader + + + Warning: The implementation is not totally finished yet. For the + moment the file handle ("f" in the example) is a normal lua file, + with a simple but important restriction: you cannot alter its value. + You cannot f:close() it, or assign it a different value. luatex + will eventually close the file itself. + + The restriction is a side-effect of a synchronisation problem with + the lua garbage collector. Because of this, it also was necessary + to turn off the automatic file closing code for normal lua io + files (In other words: you have to close yourself all the files + you opened yourself, and you should not close any files you did + not open yourself). + + In the near future, "f" will become a special 'texio' file object + and the needed functionality from the normal io library will be + reimplemented. Along with that change, there will also be a callback + to open (i.e. find) files, and a simple interface to the compiled-in + kpathsea to use within that callback. + + +============================================================== +Luatex snapshot-20060825 was released 20060825 +============================================================== + +The main change in this snapshot is that it uses far less memory. +luatex -ini on my linux machine went from 326Mb (last week) to +93Mb (now), and "texexec luatex" now ends at 184Mb instead of +over 1/2Gb. + +This is achieved by two big changes: + +* The \mathcode, \delcode, \catcode, \sfcode, \lccode and \uccode + tables are now sparse arrays that are implemented in C. They + are no longer part of the TeX "equivalence table" and because + each had 1.1 million entries with a few memory words each, this + makes a major difference. + + See mathcodes.c and textcodes.c if you are interested in the + gory details, but be warned: the code is still extremely + rough and ugly. In particular, the dump and undump routines + are far from optimal, resulting in somewhat larger format files + than before (approx 1.3Mb larger with unicode-letters loaded, + 10k without); and the assignments do not show up when using + the etex tracing routines \tracingassigns and \tracingrestores + (code simply not written yet) + +* Single-character commands are no longer "special" internally, + they are stored in the hash just like the multiletter csnames. + + +============================================================== +Luatex snapshot-20060818 was released 20060818 +============================================================== + +The snapshot is up to par with Aleph-RC4 (from texlive devel) +and the latest pdftex beta (even newer than 20060811). However, +there are some differences, to summarize: + +* There is no pool file (all strings are embedded) + +* -8bit and -translate-file are silently ignored + +* There is no mltex nor enctex (conflicts with aleph) + +* The tex functionality is always present and enabled + (but see below about TeXXeT), so the asterisk or + -etex switch for initex is not needed + +* "plus 1 filllllllll" does not generate any errors from TeX + +* TeXXeT (from eTeX) is not present, so the primives + \TeXXeTstate + \beginR + \beginL + \endR + \endL + are missing + +* The experimental pdftex regex match operations are removed, + because that feature does not make much sense when lua is + available so the primitives + \pdfmatch + \pdflastmatch + are missing + +* The input translations from Aleph are not implemented, the + 16 related primitives are all missing + \DefaultInputMode + \noDefaultInputMode + \noInputMode + \InputMode + \DefaultOutputMode + \noDefaultOutputMode + \noOutputMode + \OutputMode + \DefaultInputTranslation + \noDefaultInputTranslation + \noInputTranslation + \InputTranslation + \DefaultOutputTranslation + \noDefaultOutputTranslation + \noOutputTranslation + \OutputTranslation + All file IO assumes UTF-8, except that all the low-ascii + controls except TAB, CR en LF are written to the terminal + using ^^ notation (even these are binary in the log file). + +* Input characters can use the full range of Unicode, + but it probably only makes sense to use values above + the base plane for \mathcode and \catcode assignments, + since the fonts as well as the hyphenation patterns + are strictly 16-bit still. + +* The primitives + \pdfpagewidth and \pagewidth, + \pdfpageheight and \pageheight, + \fontcharwd and \charwd, + \fontcharht and \charht, + \fontchardp and \chardp, + \fontcharic and \charic, + are all aliases of eachother. + +* The new primitive + \clearmarks + clears a marks class completely. + +* The experimental pdftex primitives + \pdfprimitive + \ifpdfprimitive + \ifpdfabsnum + \ifpdfabsdim + and provided without the extra 'pdf' prefix, so they are + simply called + \primitive + \ifprimitive + \ifabsnum + \ifabsdim + instead. + +* I probably forgot to mention some things :-) \ No newline at end of file diff --git a/Build/source/texk/web2c/luatexdir/am/luatex.am b/Build/source/texk/web2c/luatexdir/am/luatex.am index 7bbb26b3aee..9e3a5c69f1b 100644 --- a/Build/source/texk/web2c/luatexdir/am/luatex.am +++ b/Build/source/texk/web2c/luatexdir/am/luatex.am @@ -13,10 +13,10 @@ luatex_tangle = WEBINPUTS=$(srcdir)/luatexdir $(buildenv) $(LUATANGLE) luatex_CPPFLAGS = $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES) $(XPDF_INCLUDES) luatex_CPPFLAGS += $(OBSDCOMPAT_INCLUDES) -I$(srcdir)/libmd5 -luatex_CPPFLAGS += -Iluatexdir -I$(srcdir)/luatexdir -I$(srcdir)/luatexdir/lua51 +luatex_CPPFLAGS += -Iluatexdir -I$(srcdir)/luatexdir -I$(srcdir)/luatexdir/lua51 -I$(srcdir)/luatexdir/mp luatex_CPPFLAGS += -Dextra_version_info=`date +-%Y%m%d%H` -luatex_ldadd = libluatex.a libff.a libluamisc.a libzzip.a liblua51.a +luatex_ldadd = libluatex.a libff.a libluamisc.a libzzip.a libluasocket.a liblua51.a luatex_ldadd += $(LIBPNG_LIBS) $(ZLIB_LIBS) $(XPDF_LIBS) luatex_ldadd += $(OBSDCOMPAT_LIBS) libmd5.a @@ -155,7 +155,7 @@ EXTRA_LIBRARIES += libzzip.a libzzip_a_DEPENDENCIES = liblua51.a libzzip_a_CPPFLAGS = \ - $(KPSE_ZLIB_INCLUDES) \ + $(ZLIB_INCLUDES) \ -I$(top_srcdir)/luatexdir/zziplib libzzip_a_SOURCES = \ @@ -227,14 +227,131 @@ EXTRA_DIST += \ luatexdir/zziplib/zzipback.sed \ luatexdir/zziplib/zzipwrap -## libluamisc (luafilesystem, luamd5, luapeg, luazip, luazlib, + +## luasocket +## +EXTRA_LIBRARIES += libluasocket.a + +libluasocket_a_DEPENDENCIES = $(ZLIB_DEPEND) libzzip.a + +libluasocket_a_CPPFLAGS = \ + -I$(top_srcdir)/luatexdir/luasocket -I$(srcdir)/luatexdir/lua51 + +libluasocket_a_SOURCES = \ + luatexdir/luasocket/src/auxiliar.c \ + luatexdir/luasocket/src/auxiliar.h \ + luatexdir/luasocket/src/buffer.c \ + luatexdir/luasocket/src/buffer.h \ + luatexdir/luasocket/src/except.c \ + luatexdir/luasocket/src/except.h \ + luatexdir/luasocket/src/inet.c \ + luatexdir/luasocket/src/inet.h \ + luatexdir/luasocket/src/io.c \ + luatexdir/luasocket/src/io.h \ + luatexdir/luasocket/src/lua_preload.c \ + luatexdir/luasocket/src/luasocket.c \ + luatexdir/luasocket/src/luasocket.h \ + luatexdir/luasocket/src/mime.c \ + luatexdir/luasocket/src/mime.h \ + luatexdir/luasocket/src/options.c \ + luatexdir/luasocket/src/options.h \ + luatexdir/luasocket/src/select.c \ + luatexdir/luasocket/src/select.h \ + luatexdir/luasocket/src/socket.c \ + luatexdir/luasocket/src/socket.h \ + luatexdir/luasocket/src/tcp.c \ + luatexdir/luasocket/src/tcp.h \ + luatexdir/luasocket/src/timeout.c \ + luatexdir/luasocket/src/timeout.h \ + luatexdir/luasocket/src/udp.c \ + luatexdir/luasocket/src/udp.h \ + luatexdir/luasocket/src/usocket.h + + +EXTRA_DIST += \ + luatexdir/luasocket/src/socket_lua.c \ + luatexdir/luasocket/src/ftp_lua.c \ + luatexdir/luasocket/src/http_lua.c \ + luatexdir/luasocket/src/smtp_lua.c \ + luatexdir/luasocket/src/tp_lua.c \ + luatexdir/luasocket/src/url_lua.c \ + luatexdir/luasocket/src/ltn12_lua.c \ + luatexdir/luasocket/src/mime_lua.c + +## Not used +## +EXTRA_DIST += \ + luatexdir/luasocket/src/Makefile \ + luatexdir/luasocket/src/unix.c \ + luatexdir/luasocket/src/unix.h \ + luatexdir/luasocket/src/usocket.c \ + luatexdir/luasocket/src/wsocket.c \ + luatexdir/luasocket/src/wsocket.h \ + luatexdir/luasocket/src/ftp.lua \ + luatexdir/luasocket/src/http.lua \ + luatexdir/luasocket/src/smtp.lua \ + luatexdir/luasocket/src/tp.lua \ + luatexdir/luasocket/src/url.lua \ + luatexdir/luasocket/src/ltn12.lua \ + luatexdir/luasocket/src/mime.lua \ + luatexdir/luasocket/LICENSE \ + luatexdir/luasocket/NEW \ + luatexdir/luasocket/README \ + luatexdir/luasocket/config \ + luatexdir/luasocket/luasocket.sln \ + luatexdir/luasocket/makefile \ + luatexdir/luasocket/mime.vcproj \ + luatexdir/luasocket/socket.vcproj \ + luatexdir/luasocket/doc/dns.html \ + luatexdir/luasocket/doc/ftp.html \ + luatexdir/luasocket/doc/http.html \ + luatexdir/luasocket/doc/index.html \ + luatexdir/luasocket/doc/installation.html \ + luatexdir/luasocket/doc/introduction.html \ + luatexdir/luasocket/doc/ltn12.html \ + luatexdir/luasocket/doc/luasocket.png \ + luatexdir/luasocket/doc/mime.html \ + luatexdir/luasocket/doc/reference.css \ + luatexdir/luasocket/doc/reference.html \ + luatexdir/luasocket/doc/smtp.html \ + luatexdir/luasocket/doc/socket.html \ + luatexdir/luasocket/doc/tcp.html \ + luatexdir/luasocket/doc/udp.html \ + luatexdir/luasocket/doc/url.html \ + luatexdir/luasocket/etc/README \ + luatexdir/luasocket/etc/b64.lua \ + luatexdir/luasocket/etc/check-links.lua \ + luatexdir/luasocket/etc/check-memory.lua \ + luatexdir/luasocket/etc/dict.lua \ + luatexdir/luasocket/etc/dispatch.lua \ + luatexdir/luasocket/etc/eol.lua \ + luatexdir/luasocket/etc/forward.lua \ + luatexdir/luasocket/etc/get.lua \ + luatexdir/luasocket/etc/lp.lua \ + luatexdir/luasocket/etc/qp.lua \ + luatexdir/luasocket/etc/tftp.lua \ + luatexdir/luasocket/samples/README \ + luatexdir/luasocket/samples/cddb.lua \ + luatexdir/luasocket/samples/daytimeclnt.lua \ + luatexdir/luasocket/samples/echoclnt.lua \ + luatexdir/luasocket/samples/echosrvr.lua \ + luatexdir/luasocket/samples/listener.lua \ + luatexdir/luasocket/samples/lpr.lua \ + luatexdir/luasocket/samples/talker.lua \ + luatexdir/luasocket/samples/tinyirc.lua \ + luatexdir/luasocket/test/README \ + luatexdir/luasocket/test/testclnt.lua \ + luatexdir/luasocket/test/testsrvr.lua \ + luatexdir/luasocket/test/testsupport.lua + +## libluamisc (luafilesystem, luamd5, luapeg, luazip, luazlib, luaprofiler, ## and slnunicode) EXTRA_LIBRARIES += libluamisc.a -libluamisc_a_DEPENDENCIES = $(KPSE_ZLIB_DEPEND) libzzip.a +libluamisc_a_DEPENDENCIES = libluasocket.a libluamisc_a_CPPFLAGS = \ - $(KPSE_ZLIB_INCLUDES) \ + $(ZLIB_INCLUDES) \ -I$(top_srcdir)/luatexdir/lua51 \ -I$(top_srcdir)/luatexdir/zziplib @@ -245,6 +362,16 @@ libluamisc_a_SOURCES = \ luatexdir/luamd5/md5.h \ luatexdir/luamd5/md5lib.c \ luatexdir/luapeg/lpeg.c \ + luatexdir/luaprofiler/clocks.h \ + luatexdir/luaprofiler/core_profiler.h \ + luatexdir/luaprofiler/function_meter.h \ + luatexdir/luaprofiler/luaprofiler.h \ + luatexdir/luaprofiler/stack.h \ + luatexdir/luaprofiler/clocks.c \ + luatexdir/luaprofiler/core_profiler.c \ + luatexdir/luaprofiler/function_meter.c \ + luatexdir/luaprofiler/lua50_profiler.c \ + luatexdir/luaprofiler/stack.c \ luatexdir/luazip/src/luazip.c \ luatexdir/luazip/src/luazip.h \ luatexdir/luazlib/lgzip.c \ @@ -258,14 +385,19 @@ EXTRA_libluamisc_a_SOURCES = luatexdir/slnunicode/slnudata.c ## EXTRA_DIST += \ luatexdir/luafilesystem/Makefile \ + luatexdir/luafilesystem/Makefile.win \ + luatexdir/luafilesystem/README \ luatexdir/luafilesystem/config \ + luatexdir/luafilesystem/config.win \ luatexdir/luafilesystem/doc \ + luatexdir/luafilesystem/src/lfs.def \ luatexdir/luafilesystem/tests \ luatexdir/luafilesystem/vc6 \ luatexdir/luamd5/makefile \ luatexdir/luamd5/md5.html \ luatexdir/luamd5/md5.lua \ luatexdir/luamd5/md5tests.lua \ + luatexdir/luaprofiler/Makefile \ luatexdir/luazip/Makefile \ luatexdir/luazip/README \ luatexdir/luazip/config \ @@ -292,110 +424,133 @@ libff_a_CPPFLAGS = \ -D_NO_PYTHON=1 -DX_DISPLAY_MISSING=1 -DNODYNAMIC=1 \ -D_NO_FREETYPE=1 -D_NO_LIBUNINAMESLIST=1 -UHAVE_LIBINTL_H \ -I$(top_srcdir)/luatexdir/lua51 \ - -I$(top_srcdir)/luatexdir/luafontforge/fontforge/inc \ - -I$(top_srcdir)/luatexdir/luafontforge/fontforge/fontforge + -I$(top_srcdir)/luatexdir/luafontloader/fontforge/inc \ + -I$(top_srcdir)/luatexdir/luafontloader/fontforge/fontforge libff_a_SOURCES = \ - luatexdir/luafontforge/fontforge/Unicode/alphabet.c \ - luatexdir/luafontforge/fontforge/Unicode/char.c \ - luatexdir/luafontforge/fontforge/Unicode/cjk.c \ - luatexdir/luafontforge/fontforge/Unicode/gwwiconv.c \ - luatexdir/luafontforge/fontforge/Unicode/memory.c \ - luatexdir/luafontforge/fontforge/Unicode/ustring.c \ - luatexdir/luafontforge/fontforge/fontforge/autohint.c \ - luatexdir/luafontforge/fontforge/fontforge/charview.c \ - luatexdir/luafontforge/fontforge/fontforge/configure-pfaedit.h \ - luatexdir/luafontforge/fontforge/fontforge/contextchain.c \ - luatexdir/luafontforge/fontforge/fontforge/edgelist.h \ - luatexdir/luafontforge/fontforge/fontforge/edgelist2.h \ - luatexdir/luafontforge/fontforge/fontforge/encoding.c \ - luatexdir/luafontforge/fontforge/fontforge/featurefile.c \ - luatexdir/luafontforge/fontforge/fontforge/fontinfo.c \ - luatexdir/luafontforge/fontforge/fontforge/fontview.c \ - luatexdir/luafontforge/fontforge/fontforge/fvfonts.c \ - luatexdir/luafontforge/fontforge/fontforge/groups.h \ - luatexdir/luafontforge/fontforge/fontforge/kernclass.c \ - luatexdir/luafontforge/fontforge/fontforge/lookups.c \ - luatexdir/luafontforge/fontforge/fontforge/macbinary.c \ - luatexdir/luafontforge/fontforge/fontforge/macenc.c \ - luatexdir/luafontforge/fontforge/fontforge/namelist.c \ - luatexdir/luafontforge/fontforge/fontforge/ofl.h \ - luatexdir/luafontforge/fontforge/fontforge/parsepfa.c \ - luatexdir/luafontforge/fontforge/fontforge/parsettf.c \ - luatexdir/luafontforge/fontforge/fontforge/parsettfatt.c \ - luatexdir/luafontforge/fontforge/fontforge/parsettfvar.c \ - luatexdir/luafontforge/fontforge/fontforge/pfaedit.h \ - luatexdir/luafontforge/fontforge/fontforge/pfaeditui.h \ - luatexdir/luafontforge/fontforge/fontforge/plugins.h \ - luatexdir/luafontforge/fontforge/fontforge/prefs.c \ - luatexdir/luafontforge/fontforge/fontforge/psfont.h \ - luatexdir/luafontforge/fontforge/fontforge/psread.c \ - luatexdir/luafontforge/fontforge/fontforge/pua.c \ - luatexdir/luafontforge/fontforge/fontforge/sd.h \ - luatexdir/luafontforge/fontforge/fontforge/splinefill.c \ - luatexdir/luafontforge/fontforge/fontforge/splinefont.h \ - luatexdir/luafontforge/fontforge/fontforge/splineorder2.c \ - luatexdir/luafontforge/fontforge/fontforge/splineoverlap.c \ - luatexdir/luafontforge/fontforge/fontforge/splinerefigure.c \ - luatexdir/luafontforge/fontforge/fontforge/splinesave.c \ - luatexdir/luafontforge/fontforge/fontforge/splinestroke.c \ - luatexdir/luafontforge/fontforge/fontforge/splineutil.c \ - luatexdir/luafontforge/fontforge/fontforge/splineutil2.c \ - luatexdir/luafontforge/fontforge/fontforge/stamp.c \ - luatexdir/luafontforge/fontforge/fontforge/start.c \ - luatexdir/luafontforge/fontforge/fontforge/stemdb.c \ - luatexdir/luafontforge/fontforge/fontforge/stemdb.h \ - luatexdir/luafontforge/fontforge/fontforge/tottf.c \ - luatexdir/luafontforge/fontforge/fontforge/tottfgpos.c \ - luatexdir/luafontforge/fontforge/fontforge/ttf.h \ - luatexdir/luafontforge/fontforge/fontforge/tottfvar.c \ - luatexdir/luafontforge/fontforge/fontforge/ttfspecial.c \ - luatexdir/luafontforge/fontforge/fontforge/unicoderange.h \ - luatexdir/luafontforge/fontforge/fontforge/views.h \ - luatexdir/luafontforge/fontforge/inc/basics.h \ - luatexdir/luafontforge/fontforge/inc/chardata.h \ - luatexdir/luafontforge/fontforge/inc/charset.h \ - luatexdir/luafontforge/fontforge/inc/dynamic.h \ - luatexdir/luafontforge/fontforge/inc/fileutil.h \ - luatexdir/luafontforge/fontforge/inc/gdraw.h \ - luatexdir/luafontforge/fontforge/inc/gfile.h \ - luatexdir/luafontforge/fontforge/inc/ggadget.h \ - luatexdir/luafontforge/fontforge/inc/gicons.h \ - luatexdir/luafontforge/fontforge/inc/gio.h \ - luatexdir/luafontforge/fontforge/inc/gkeysym.h \ - luatexdir/luafontforge/fontforge/inc/gprogress.h \ - luatexdir/luafontforge/fontforge/inc/gresource.h \ - luatexdir/luafontforge/fontforge/inc/gwidget.h \ - luatexdir/luafontforge/fontforge/inc/gwwiconv.h \ - luatexdir/luafontforge/fontforge/inc/intl.h \ - luatexdir/luafontforge/fontforge/inc/ustring.h \ - luatexdir/luafontforge/fontforge/inc/utype.h \ - luatexdir/luafontforge/src/ffdummies.c \ - luatexdir/luafontforge/src/luafflib.c + luatexdir/luafontloader/fontforge/Unicode/ArabicForms.c \ + luatexdir/luafontloader/fontforge/Unicode/alphabet.c \ + luatexdir/luafontloader/fontforge/Unicode/backtrns.c \ + luatexdir/luafontloader/fontforge/Unicode/char.c \ + luatexdir/luafontloader/fontforge/Unicode/cjk.c \ + luatexdir/luafontloader/fontforge/Unicode/combiners.h \ + luatexdir/luafontloader/fontforge/Unicode/dump.c \ + luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c \ + luatexdir/luafontloader/fontforge/Unicode/memory.c \ + luatexdir/luafontloader/fontforge/Unicode/ucharmap.c \ + luatexdir/luafontloader/fontforge/Unicode/unialt.c \ + luatexdir/luafontloader/fontforge/Unicode/ustring.c \ + luatexdir/luafontloader/fontforge/Unicode/utype.c \ + luatexdir/luafontloader/fontforge/fontforge/PfEd.h \ + luatexdir/luafontloader/fontforge/fontforge/autohint.c \ + luatexdir/luafontloader/fontforge/fontforge/baseviews.h \ + luatexdir/luafontloader/fontforge/fontforge/clipnoui.c \ + luatexdir/luafontloader/fontforge/fontforge/configure-pfaedit.h \ + luatexdir/luafontloader/fontforge/fontforge/cvundoes.c \ + luatexdir/luafontloader/fontforge/fontforge/dumppfa.c \ + luatexdir/luafontloader/fontforge/fontforge/edgelist.h \ + luatexdir/luafontloader/fontforge/fontforge/edgelist2.h \ + luatexdir/luafontloader/fontforge/fontforge/encoding.c \ + luatexdir/luafontloader/fontforge/fontforge/encoding.h \ + luatexdir/luafontloader/fontforge/fontforge/featurefile.c \ + luatexdir/luafontloader/fontforge/fontforge/fontforgevw.h \ + luatexdir/luafontloader/fontforge/fontforge/fontviewbase.c \ + luatexdir/luafontloader/fontforge/fontforge/fvcomposit.c \ + luatexdir/luafontloader/fontforge/fontforge/fvfonts.c \ + luatexdir/luafontloader/fontforge/fontforge/libffstamp.h \ + luatexdir/luafontloader/fontforge/fontforge/libstamp.pre \ + luatexdir/luafontloader/fontforge/fontforge/lookups.c \ + luatexdir/luafontloader/fontforge/fontforge/lookups.h \ + luatexdir/luafontloader/fontforge/fontforge/macbinary.c \ + luatexdir/luafontloader/fontforge/fontforge/macenc.c \ + luatexdir/luafontloader/fontforge/fontforge/mathconstants.c \ + luatexdir/luafontloader/fontforge/fontforge/mm.c \ + luatexdir/luafontloader/fontforge/fontforge/mm.h \ + luatexdir/luafontloader/fontforge/fontforge/namelist.c \ + luatexdir/luafontloader/fontforge/fontforge/noprefs.c \ + luatexdir/luafontloader/fontforge/fontforge/nouiutil.c \ + luatexdir/luafontloader/fontforge/fontforge/parsepfa.c \ + luatexdir/luafontloader/fontforge/fontforge/parsettf.c \ + luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c \ + luatexdir/luafontloader/fontforge/fontforge/parsettfvar.c \ + luatexdir/luafontloader/fontforge/fontforge/pfaedit.h \ + luatexdir/luafontloader/fontforge/fontforge/plugins.h \ + luatexdir/luafontloader/fontforge/fontforge/psfont.h \ + luatexdir/luafontloader/fontforge/fontforge/psread.c \ + luatexdir/luafontloader/fontforge/fontforge/pua.c \ + luatexdir/luafontloader/fontforge/fontforge/python.c \ + luatexdir/luafontloader/fontforge/fontforge/scripting.h \ + luatexdir/luafontloader/fontforge/fontforge/sd.h \ + luatexdir/luafontloader/fontforge/fontforge/sfd1.c \ + luatexdir/luafontloader/fontforge/fontforge/sfd1.h \ + luatexdir/luafontloader/fontforge/fontforge/splinechar.c \ + luatexdir/luafontloader/fontforge/fontforge/splinefill.c \ + luatexdir/luafontloader/fontforge/fontforge/splinefont.c \ + luatexdir/luafontloader/fontforge/fontforge/splinefont.h \ + luatexdir/luafontloader/fontforge/fontforge/splineorder2.c \ + luatexdir/luafontloader/fontforge/fontforge/splineoverlap.c \ + luatexdir/luafontloader/fontforge/fontforge/splinerefigure.c \ + luatexdir/luafontloader/fontforge/fontforge/splinesave.c \ + luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c \ + luatexdir/luafontloader/fontforge/fontforge/splinestroke.c \ + luatexdir/luafontloader/fontforge/fontforge/splineutil.c \ + luatexdir/luafontloader/fontforge/fontforge/splineutil2.c \ + luatexdir/luafontloader/fontforge/fontforge/start.c \ + luatexdir/luafontloader/fontforge/fontforge/stemdb.c \ + luatexdir/luafontloader/fontforge/fontforge/stemdb.h \ + luatexdir/luafontloader/fontforge/fontforge/tottf.c \ + luatexdir/luafontloader/fontforge/fontforge/tottfaat.c \ + luatexdir/luafontloader/fontforge/fontforge/tottfgpos.c \ + luatexdir/luafontloader/fontforge/fontforge/ttf.h \ + luatexdir/luafontloader/fontforge/fontforge/ttfspecial.c \ + luatexdir/luafontloader/fontforge/fontforge/uiinterface.h \ + luatexdir/luafontloader/fontforge/fontforge/unicoderange.h \ + luatexdir/luafontloader/fontforge/fontforge/views.h \ + luatexdir/luafontloader/fontforge/gutils/fsys.c \ + luatexdir/luafontloader/fontforge/gutils/gwwintl.c \ + luatexdir/luafontloader/fontforge/inc/basics.h \ + luatexdir/luafontloader/fontforge/inc/chardata.h \ + luatexdir/luafontloader/fontforge/inc/charset.h \ + luatexdir/luafontloader/fontforge/inc/dynamic.h \ + luatexdir/luafontloader/fontforge/inc/fileutil.h \ + luatexdir/luafontloader/fontforge/inc/gdraw.h \ + luatexdir/luafontloader/fontforge/inc/gfile.h \ + luatexdir/luafontloader/fontforge/inc/ggadget.h \ + luatexdir/luafontloader/fontforge/inc/gicons.h \ + luatexdir/luafontloader/fontforge/inc/gimage.h \ + luatexdir/luafontloader/fontforge/inc/gio.h \ + luatexdir/luafontloader/fontforge/inc/gkeysym.h \ + luatexdir/luafontloader/fontforge/inc/gprogress.h \ + luatexdir/luafontloader/fontforge/inc/gresource.h \ + luatexdir/luafontloader/fontforge/inc/gwidget.h \ + luatexdir/luafontloader/fontforge/inc/gwwiconv.h \ + luatexdir/luafontloader/fontforge/inc/intl.h \ + luatexdir/luafontloader/fontforge/inc/ustring.h \ + luatexdir/luafontloader/fontforge/inc/utype.h \ + luatexdir/luafontloader/src/ffdummies.c \ + luatexdir/luafontloader/src/luafflib.c EXTRA_DIST += \ - luatexdir/luafontforge/ChangeLog \ - luatexdir/luafontforge/fontforge/AUTHORS \ - luatexdir/luafontforge/fontforge/INSTALL \ - luatexdir/luafontforge/fontforge/LICENSE \ - luatexdir/luafontforge/fontforge/VERSION + luatexdir/luafontloader/ChangeLog \ + luatexdir/luafontloader/fontforge/AUTHORS \ + luatexdir/luafontloader/fontforge/INSTALL \ + luatexdir/luafontloader/fontforge/LICENSE \ + luatexdir/luafontloader/fontforge/VERSION \ + luatexdir/luafontloader/fontforge/libs \ + luatexdir/luafontloader/fontforge/po ## Not used ## EXTRA_DIST += \ - luatexdir/luafontforge/Makefile \ - luatexdir/luafontforge/fontforge/Makefile \ - luatexdir/luafontforge/fontforge/Unicode/Makefile \ - luatexdir/luafontforge/fontforge/Unicode/descrip.mms \ - luatexdir/luafontforge/fontforge/descrip.mms \ - luatexdir/luafontforge/fontforge/fontforge/Makefile \ - luatexdir/luafontforge/fontforge/fontforge/descrip.mms \ - luatexdir/luafontforge/fontforge/fontforge/lff.opt \ - luatexdir/luafontforge/fontforge/fontforge/scriptfuncs.h \ - luatexdir/luafontforge/fontforge/fontforge/scripting.h \ - luatexdir/luafontforge/fontforge/fontforge/sfd1.h \ - luatexdir/luafontforge/fontforge/fontforge/stamper.c \ - luatexdir/luafontforge/fontforge/fontforge/xlib.opt + luatexdir/luafontloader/fontforge/Makefile.in \ + luatexdir/luafontloader/fontforge/Unicode/Makefile.in \ + luatexdir/luafontloader/fontforge/configure-options \ + luatexdir/luafontloader/fontforge/configure.in \ + luatexdir/luafontloader/fontforge/fontforge/Makefile.in \ + luatexdir/luafontloader/fontforge/gdraw/Makefile.in \ + luatexdir/luafontloader/fontforge/gutils/Makefile.in \ + luatexdir/luafontloader/fontforge/inc/config.h.in \ + luatexdir/luafontloader/fontforge/plugins/Makefile.in ## libluatex ## @@ -409,11 +564,9 @@ libluatex_a_CPPFLAGS += -Iluatexdir -I$(srcdir)/luatexdir -I$(srcdir)/luatexdir/ libluatex_a_CPPFLAGS += -DpdfTeX libluatex_a_SOURCES = \ - luatexdir/avl.c \ - luatexdir/avl.h \ - luatexdir/avlstuff.c \ - luatexdir/avlstuff.h \ + luatexdir/commands.h \ luatexdir/font/dofont.c \ + luatexdir/font/luatexfont.h \ luatexdir/font/luafont.c \ luatexdir/font/mapfile.c \ luatexdir/font/pkin.c \ @@ -440,6 +593,7 @@ libluatex_a_SOURCES = \ luatexdir/font/writettf.h \ luatexdir/font/writetype0.c \ luatexdir/font/writetype2.c \ + luatexdir/get_svnversion.sh \ luatexdir/hyphen.h \ luatexdir/image/epdf.c \ luatexdir/image/epdf.h \ @@ -460,7 +614,6 @@ libluatex_a_SOURCES = \ luatexdir/lua/lkpselib.c \ luatexdir/lua/llanglib.c \ luatexdir/lua/llualib.c \ - luatexdir/lua/lmplib.c \ luatexdir/lua/lnodelib.c \ luatexdir/lua/loslibext.c \ luatexdir/lua/lpdflib.c \ @@ -476,21 +629,37 @@ libluatex_a_SOURCES = \ luatexdir/lua/texluac.c \ luatexdir/luatex-api.h \ luatexdir/luatex.h \ + luatexdir/makecpool.c \ luatexdir/managed-sa.c \ luatexdir/managed-sa.h \ luatexdir/mathcodes.c \ + luatexdir/mp/lmplib.c \ luatexdir/nodes.h \ + luatexdir/pdf/pagetree.c \ + luatexdir/pdf/pdfpage.c \ + luatexdir/primitive.h \ luatexdir/ptexmac.h \ - luatexdir/svnversion.h \ + luatexdir/tex/filename.c \ luatexdir/tex/linebreak.c \ + luatexdir/tex/math.c \ + luatexdir/tex/mlist.c \ luatexdir/tex/postlinebreak.c \ + luatexdir/tex/primitive.c \ + luatexdir/tex/texdeffont.c \ luatexdir/tex/texnodes.c \ luatexdir/tex/texpdf.c \ luatexdir/tex/textoken.c \ + luatexdir/texmath.h \ luatexdir/textcodes.c \ luatexdir/tokens.h \ - luatexdir/utils.c \ - luatexdir/writezip.c + luatexdir/utils/avl.c \ + luatexdir/utils/avl.h \ + luatexdir/utils/avlstuff.c \ + luatexdir/utils/avlstuff.h \ + luatexdir/utils/synctex.h \ + luatexdir/utils/synctex.c \ + luatexdir/utils/utils.c \ + luatexdir/utils/writezip.c nodist_libluatex_a_SOURCES = $(lua_mp_c_h) @@ -501,16 +670,21 @@ $(libluatex_a_SOURCES): $(lua_mp_c_h) endif LUATEX ## These files are mutually dependent -lua_mp_c_h = luatexdir/mp.c luatexdir/mplib.h luatexdir/mpmp.h -lua_mp_c_h += luatexdir/mppsout.h luatexdir/psout.c -lua_mp_web = luatexdir/lua/mp.w luatexdir/lua/psout.w +lua_mp_c_h = luatexdir/mp.c luatexdir/mplib.h luatexdir/mpmp.h +lua_mp_c_h += luatexdir/mppsout.h luatexdir/psout.c luatexdir/mplibps.h +lua_mp_c_h += luatexdir/memio.c luatexdir/tfmin.c +lua_mp_web = luatexdir/mp/avl.h luatexdir/mp/avl.c luatexdir/mp/mp.w luatexdir/mp/psout.w +lua_mp_web += luatexdir/mp/memio.w luatexdir/mp/tfmin.w +lua_mp_CPPFLAGS = -I$(srcdir)/luatexdir/mp $(lua_mp_c_h): mp-ctangle mp-ctangle: ctangle $(lua_mp_web) luatexd.h $(mkdir_p) luatexdir - CWEBINPUTS=$(srcdir)/luatexdir/lua $(ctangle) mp.w - CWEBINPUTS=$(srcdir)/luatexdir/lua $(ctangle) psout.w + CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) mp.w + CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) psout.w + CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) tfmin.w + CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) memio.w rm -f $(lua_mp_c_h) - mv mp.c mplib.h mpmp.h mppsout.h psout.c luatexdir + mv mp.c mplib.h mpmp.h mppsout.h psout.c mplibps.h memio.c tfmin.c luatexdir echo timestamp >$@ touch $(lua_mp_c_h) @@ -528,20 +702,9 @@ EXTRA_DIST += \ luatexdir/change-files.txt \ luatexdir/font/subfont.txt -## Not used (pdftosrc and ttf2afm) -## -EXTRA_DIST += \ - luatexdir/pdftosrc.1 \ - luatexdir/pdftosrc.cc \ - luatexdir/pdftosrc.rc \ - luatexdir/ttf2afm.c \ - luatexdir/ttf2afm.rc - -## included by luatexdir/ttf2afm.c -EXTRA_DIST += luatexdir/macnames.c ## Tests -## + dist_check_SCRIPTS += luatexdir/luatangle.test if LUATEX @@ -552,5 +715,8 @@ DISTCLEANFILES += cftest.p ## Eventually delete these files ## -EXTRA_DIST += luatexdir/Makefile.in luatexdir/luatex.mk luatexdir/luatexlib.mk - +EXTRA_DIST += \ + luatexdir/Makefile.in \ + luatexdir/depend.mk \ + luatexdir/luatex.mk \ + luatexdir/luatexlib.mk diff --git a/Build/source/texk/web2c/luatexdir/avl.c b/Build/source/texk/web2c/luatexdir/avl.c deleted file mode 100644 index a25239e8d93..00000000000 --- a/Build/source/texk/web2c/luatexdir/avl.c +++ /dev/null @@ -1,893 +0,0 @@ -/* Produced by texiweb from libavl.w. */ - -/* libavl - library for manipulation of binary trees. - Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - - The author may be contacted at on the Internet, or - write to Ben Pfaff, Stanford University, Computer Science Dept., 353 - Serra Mall, Stanford CA 94305, USA. -*/ - -#include -#include -#include -#include -#include "avl.h" - -/* Creates and returns a new table - with comparison function |compare| using parameter |param| - and memory allocator |allocator|. - Returns |NULL| if memory allocation failed. */ -struct avl_table * -avl_create (avl_comparison_func *compare, void *param, - struct libavl_allocator *allocator) -{ - struct avl_table *tree; - - assert (compare != NULL); - - if (allocator == NULL) - allocator = &avl_allocator_default; - - tree = allocator->libavl_malloc (allocator, sizeof *tree); - if (tree == NULL) - return NULL; - - tree->avl_root = NULL; - tree->avl_compare = compare; - tree->avl_param = param; - tree->avl_alloc = allocator; - tree->avl_count = 0; - tree->avl_generation = 0; - - return tree; -} - -/* Search |tree| for an item matching |item|, and return it if found. - Otherwise return |NULL|. */ -void * -avl_find (const struct avl_table *tree, const void *item) -{ - const struct avl_node *p; - - assert (tree != NULL && item != NULL); - for (p = tree->avl_root; p != NULL; ) - { - int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param); - - if (cmp < 0) - p = p->avl_link[0]; - else if (cmp > 0) - p = p->avl_link[1]; - else /* |cmp == 0| */ - return p->avl_data; - } - - return NULL; -} - -/* Inserts |item| into |tree| and returns a pointer to |item|'s address. - If a duplicate item is found in the tree, - returns a pointer to the duplicate without inserting |item|. - Returns |NULL| in case of memory allocation failure. */ -void ** -avl_probe (struct avl_table *tree, void *item) -{ - struct avl_node *y, *z; /* Top node to update balance factor, and parent. */ - struct avl_node *p, *q; /* Iterator, and parent. */ - struct avl_node *n; /* Newly inserted node. */ - struct avl_node *w; /* New root of rebalanced subtree. */ - int dir; /* Direction to descend. */ - - unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */ - int k = 0; /* Number of cached results. */ - - assert (tree != NULL && item != NULL); - - z = (struct avl_node *) &tree->avl_root; - y = tree->avl_root; - dir = 0; - for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir]) - { - int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param); - if (cmp == 0) - return &p->avl_data; - - if (p->avl_balance != 0) - z = q, y = p, k = 0; - da[k++] = dir = cmp > 0; - } - - n = q->avl_link[dir] = - tree->avl_alloc->libavl_malloc (tree->avl_alloc, sizeof *n); - if (n == NULL) - return NULL; - - tree->avl_count++; - n->avl_data = item; - n->avl_link[0] = n->avl_link[1] = NULL; - n->avl_balance = 0; - if (y == NULL) - return &n->avl_data; - - for (p = y, k = 0; p != n; p = p->avl_link[da[k]], k++) - if (da[k] == 0) - p->avl_balance--; - else - p->avl_balance++; - - if (y->avl_balance == -2) - { - struct avl_node *x = y->avl_link[0]; - if (x->avl_balance == -1) - { - w = x; - y->avl_link[0] = x->avl_link[1]; - x->avl_link[1] = y; - x->avl_balance = y->avl_balance = 0; - } - else - { - assert (x->avl_balance == +1); - w = x->avl_link[1]; - x->avl_link[1] = w->avl_link[0]; - w->avl_link[0] = x; - y->avl_link[0] = w->avl_link[1]; - w->avl_link[1] = y; - if (w->avl_balance == -1) - x->avl_balance = 0, y->avl_balance = +1; - else if (w->avl_balance == 0) - x->avl_balance = y->avl_balance = 0; - else /* |w->avl_balance == +1| */ - x->avl_balance = -1, y->avl_balance = 0; - w->avl_balance = 0; - } - } - else if (y->avl_balance == +2) - { - struct avl_node *x = y->avl_link[1]; - if (x->avl_balance == +1) - { - w = x; - y->avl_link[1] = x->avl_link[0]; - x->avl_link[0] = y; - x->avl_balance = y->avl_balance = 0; - } - else - { - assert (x->avl_balance == -1); - w = x->avl_link[0]; - x->avl_link[0] = w->avl_link[1]; - w->avl_link[1] = x; - y->avl_link[1] = w->avl_link[0]; - w->avl_link[0] = y; - if (w->avl_balance == +1) - x->avl_balance = 0, y->avl_balance = -1; - else if (w->avl_balance == 0) - x->avl_balance = y->avl_balance = 0; - else /* |w->avl_balance == -1| */ - x->avl_balance = +1, y->avl_balance = 0; - w->avl_balance = 0; - } - } - else - return &n->avl_data; - z->avl_link[y != z->avl_link[0]] = w; - - tree->avl_generation++; - return &n->avl_data; -} - -/* Inserts |item| into |table|. - Returns |NULL| if |item| was successfully inserted - or if a memory allocation error occurred. - Otherwise, returns the duplicate item. */ -void * -avl_insert (struct avl_table *table, void *item) -{ - void **p = avl_probe (table, item); - return p == NULL || *p == item ? NULL : *p; -} - -/* Inserts |item| into |table|, replacing any duplicate item. - Returns |NULL| if |item| was inserted without replacing a duplicate, - or if a memory allocation error occurred. - Otherwise, returns the item that was replaced. */ -void * -avl_replace (struct avl_table *table, void *item) -{ - void **p = avl_probe (table, item); - if (p == NULL || *p == item) - return NULL; - else - { - void *r = *p; - *p = item; - return r; - } -} - -/* Deletes from |tree| and returns an item matching |item|. - Returns a null pointer if no matching item found. */ -void * -avl_delete (struct avl_table *tree, const void *item) -{ - /* Stack of nodes. */ - struct avl_node *pa[AVL_MAX_HEIGHT]; /* Nodes. */ - unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */ - int k; /* Stack pointer. */ - - struct avl_node *p; /* Traverses tree to find node to delete. */ - int cmp; /* Result of comparison between |item| and |p|. */ - - assert (tree != NULL && item != NULL); - - k = 0; - p = (struct avl_node *) &tree->avl_root; - for (cmp = -1; cmp != 0; - cmp = tree->avl_compare (item, p->avl_data, tree->avl_param)) - { - int dir = cmp > 0; - - pa[k] = p; - da[k++] = dir; - - p = p->avl_link[dir]; - if (p == NULL) - return NULL; - } - item = p->avl_data; - - if (p->avl_link[1] == NULL) - pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0]; - else - { - struct avl_node *r = p->avl_link[1]; - if (r->avl_link[0] == NULL) - { - r->avl_link[0] = p->avl_link[0]; - r->avl_balance = p->avl_balance; - pa[k - 1]->avl_link[da[k - 1]] = r; - da[k] = 1; - pa[k++] = r; - } - else - { - struct avl_node *s; - int j = k++; - - for (;;) - { - da[k] = 0; - pa[k++] = r; - s = r->avl_link[0]; - if (s->avl_link[0] == NULL) - break; - - r = s; - } - - s->avl_link[0] = p->avl_link[0]; - r->avl_link[0] = s->avl_link[1]; - s->avl_link[1] = p->avl_link[1]; - s->avl_balance = p->avl_balance; - - pa[j - 1]->avl_link[da[j - 1]] = s; - da[j] = 1; - pa[j] = s; - } - } - - tree->avl_alloc->libavl_free (tree->avl_alloc, p); - - assert (k > 0); - while (--k > 0) - { - struct avl_node *y = pa[k]; - - if (da[k] == 0) - { - y->avl_balance++; - if (y->avl_balance == +1) - break; - else if (y->avl_balance == +2) - { - struct avl_node *x = y->avl_link[1]; - if (x->avl_balance == -1) - { - struct avl_node *w; - assert (x->avl_balance == -1); - w = x->avl_link[0]; - x->avl_link[0] = w->avl_link[1]; - w->avl_link[1] = x; - y->avl_link[1] = w->avl_link[0]; - w->avl_link[0] = y; - if (w->avl_balance == +1) - x->avl_balance = 0, y->avl_balance = -1; - else if (w->avl_balance == 0) - x->avl_balance = y->avl_balance = 0; - else /* |w->avl_balance == -1| */ - x->avl_balance = +1, y->avl_balance = 0; - w->avl_balance = 0; - pa[k - 1]->avl_link[da[k - 1]] = w; - } - else - { - y->avl_link[1] = x->avl_link[0]; - x->avl_link[0] = y; - pa[k - 1]->avl_link[da[k - 1]] = x; - if (x->avl_balance == 0) - { - x->avl_balance = -1; - y->avl_balance = +1; - break; - } - else - x->avl_balance = y->avl_balance = 0; - } - } - } - else - { - y->avl_balance--; - if (y->avl_balance == -1) - break; - else if (y->avl_balance == -2) - { - struct avl_node *x = y->avl_link[0]; - if (x->avl_balance == +1) - { - struct avl_node *w; - assert (x->avl_balance == +1); - w = x->avl_link[1]; - x->avl_link[1] = w->avl_link[0]; - w->avl_link[0] = x; - y->avl_link[0] = w->avl_link[1]; - w->avl_link[1] = y; - if (w->avl_balance == -1) - x->avl_balance = 0, y->avl_balance = +1; - else if (w->avl_balance == 0) - x->avl_balance = y->avl_balance = 0; - else /* |w->avl_balance == +1| */ - x->avl_balance = -1, y->avl_balance = 0; - w->avl_balance = 0; - pa[k - 1]->avl_link[da[k - 1]] = w; - } - else - { - y->avl_link[0] = x->avl_link[1]; - x->avl_link[1] = y; - pa[k - 1]->avl_link[da[k - 1]] = x; - if (x->avl_balance == 0) - { - x->avl_balance = +1; - y->avl_balance = -1; - break; - } - else - x->avl_balance = y->avl_balance = 0; - } - } - } - } - - tree->avl_count--; - tree->avl_generation++; - return (void *) item; -} - -/* Refreshes the stack of parent pointers in |trav| - and updates its generation number. */ -static void -trav_refresh (struct avl_traverser *trav) -{ - assert (trav != NULL); - - trav->avl_generation = trav->avl_table->avl_generation; - - if (trav->avl_node != NULL) - { - avl_comparison_func *cmp = trav->avl_table->avl_compare; - void *param = trav->avl_table->avl_param; - struct avl_node *node = trav->avl_node; - struct avl_node *i; - - trav->avl_height = 0; - for (i = trav->avl_table->avl_root; i != node; ) - { - assert (trav->avl_height < AVL_MAX_HEIGHT); - assert (i != NULL); - - trav->avl_stack[trav->avl_height++] = i; - i = i->avl_link[cmp (node->avl_data, i->avl_data, param) > 0]; - } - } -} - -/* Initializes |trav| for use with |tree| - and selects the null node. */ -void -avl_t_init (struct avl_traverser *trav, struct avl_table *tree) -{ - trav->avl_table = tree; - trav->avl_node = NULL; - trav->avl_height = 0; - trav->avl_generation = tree->avl_generation; -} - -/* Initializes |trav| for |tree| - and selects and returns a pointer to its least-valued item. - Returns |NULL| if |tree| contains no nodes. */ -void * -avl_t_first (struct avl_traverser *trav, struct avl_table *tree) -{ - struct avl_node *x; - - assert (tree != NULL && trav != NULL); - - trav->avl_table = tree; - trav->avl_height = 0; - trav->avl_generation = tree->avl_generation; - - x = tree->avl_root; - if (x != NULL) - while (x->avl_link[0] != NULL) - { - assert (trav->avl_height < AVL_MAX_HEIGHT); - trav->avl_stack[trav->avl_height++] = x; - x = x->avl_link[0]; - } - trav->avl_node = x; - - return x != NULL ? x->avl_data : NULL; -} - -/* Initializes |trav| for |tree| - and selects and returns a pointer to its greatest-valued item. - Returns |NULL| if |tree| contains no nodes. */ -void * -avl_t_last (struct avl_traverser *trav, struct avl_table *tree) -{ - struct avl_node *x; - - assert (tree != NULL && trav != NULL); - - trav->avl_table = tree; - trav->avl_height = 0; - trav->avl_generation = tree->avl_generation; - - x = tree->avl_root; - if (x != NULL) - while (x->avl_link[1] != NULL) - { - assert (trav->avl_height < AVL_MAX_HEIGHT); - trav->avl_stack[trav->avl_height++] = x; - x = x->avl_link[1]; - } - trav->avl_node = x; - - return x != NULL ? x->avl_data : NULL; -} - -/* Searches for |item| in |tree|. - If found, initializes |trav| to the item found and returns the item - as well. - If there is no matching item, initializes |trav| to the null item - and returns |NULL|. */ -void * -avl_t_find (struct avl_traverser *trav, struct avl_table *tree, void *item) -{ - struct avl_node *p, *q; - - assert (trav != NULL && tree != NULL && item != NULL); - trav->avl_table = tree; - trav->avl_height = 0; - trav->avl_generation = tree->avl_generation; - for (p = tree->avl_root; p != NULL; p = q) - { - int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param); - - if (cmp < 0) - q = p->avl_link[0]; - else if (cmp > 0) - q = p->avl_link[1]; - else /* |cmp == 0| */ - { - trav->avl_node = p; - return p->avl_data; - } - - assert (trav->avl_height < AVL_MAX_HEIGHT); - trav->avl_stack[trav->avl_height++] = p; - } - - trav->avl_height = 0; - trav->avl_node = NULL; - return NULL; -} - -/* Attempts to insert |item| into |tree|. - If |item| is inserted successfully, it is returned and |trav| is - initialized to its location. - If a duplicate is found, it is returned and |trav| is initialized to - its location. No replacement of the item occurs. - If a memory allocation failure occurs, |NULL| is returned and |trav| - is initialized to the null item. */ -void * -avl_t_insert (struct avl_traverser *trav, struct avl_table *tree, void *item) -{ - void **p; - - assert (trav != NULL && tree != NULL && item != NULL); - - p = avl_probe (tree, item); - if (p != NULL) - { - trav->avl_table = tree; - trav->avl_node = - ((struct avl_node *) - ((char *) p - offsetof (struct avl_node, avl_data))); - trav->avl_generation = tree->avl_generation - 1; - return *p; - } - else - { - avl_t_init (trav, tree); - return NULL; - } -} - -/* Initializes |trav| to have the same current node as |src|. */ -void * -avl_t_copy (struct avl_traverser *trav, const struct avl_traverser *src) -{ - assert (trav != NULL && src != NULL); - - if (trav != src) - { - trav->avl_table = src->avl_table; - trav->avl_node = src->avl_node; - trav->avl_generation = src->avl_generation; - if (trav->avl_generation == trav->avl_table->avl_generation) - { - trav->avl_height = src->avl_height; - memcpy (trav->avl_stack, (const void *) src->avl_stack, - sizeof *trav->avl_stack * trav->avl_height); - } - } - - return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL; -} - -/* Returns the next data item in inorder - within the tree being traversed with |trav|, - or if there are no more data items returns |NULL|. */ -void * -avl_t_next (struct avl_traverser *trav) -{ - struct avl_node *x; - - assert (trav != NULL); - - if (trav->avl_generation != trav->avl_table->avl_generation) - trav_refresh (trav); - - x = trav->avl_node; - if (x == NULL) - { - return avl_t_first (trav, trav->avl_table); - } - else if (x->avl_link[1] != NULL) - { - assert (trav->avl_height < AVL_MAX_HEIGHT); - trav->avl_stack[trav->avl_height++] = x; - x = x->avl_link[1]; - - while (x->avl_link[0] != NULL) - { - assert (trav->avl_height < AVL_MAX_HEIGHT); - trav->avl_stack[trav->avl_height++] = x; - x = x->avl_link[0]; - } - } - else - { - struct avl_node *y; - - do - { - if (trav->avl_height == 0) - { - trav->avl_node = NULL; - return NULL; - } - - y = x; - x = trav->avl_stack[--trav->avl_height]; - } - while (y == x->avl_link[1]); - } - trav->avl_node = x; - - return x->avl_data; -} - -/* Returns the previous data item in inorder - within the tree being traversed with |trav|, - or if there are no more data items returns |NULL|. */ -void * -avl_t_prev (struct avl_traverser *trav) -{ - struct avl_node *x; - - assert (trav != NULL); - - if (trav->avl_generation != trav->avl_table->avl_generation) - trav_refresh (trav); - - x = trav->avl_node; - if (x == NULL) - { - return avl_t_last (trav, trav->avl_table); - } - else if (x->avl_link[0] != NULL) - { - assert (trav->avl_height < AVL_MAX_HEIGHT); - trav->avl_stack[trav->avl_height++] = x; - x = x->avl_link[0]; - - while (x->avl_link[1] != NULL) - { - assert (trav->avl_height < AVL_MAX_HEIGHT); - trav->avl_stack[trav->avl_height++] = x; - x = x->avl_link[1]; - } - } - else - { - struct avl_node *y; - - do - { - if (trav->avl_height == 0) - { - trav->avl_node = NULL; - return NULL; - } - - y = x; - x = trav->avl_stack[--trav->avl_height]; - } - while (y == x->avl_link[0]); - } - trav->avl_node = x; - - return x->avl_data; -} - -/* Returns |trav|'s current item. */ -void * -avl_t_cur (struct avl_traverser *trav) -{ - assert (trav != NULL); - - return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL; -} - -/* Replaces the current item in |trav| by |new| and returns the item replaced. - |trav| must not have the null item selected. - The new item must not upset the ordering of the tree. */ -void * -avl_t_replace (struct avl_traverser *trav, void *new) -{ - void *old; - - assert (trav != NULL && trav->avl_node != NULL && new != NULL); - old = trav->avl_node->avl_data; - trav->avl_node->avl_data = new; - return old; -} - -/* Destroys |new| with |avl_destroy (new, destroy)|, - first setting right links of nodes in |stack| within |new| - to null pointers to avoid touching uninitialized data. */ -static void -copy_error_recovery (struct avl_node **stack, int height, - struct avl_table *new, avl_item_func *destroy) -{ - assert (stack != NULL && height >= 0 && new != NULL); - - for (; height > 2; height -= 2) - stack[height - 1]->avl_link[1] = NULL; - avl_destroy (new, destroy); -} - -/* Copies |org| to a newly created tree, which is returned. - If |copy != NULL|, each data item in |org| is first passed to |copy|, - and the return values are inserted into the tree, - with |NULL| return values taken as indications of failure. - On failure, destroys the partially created new tree, - applying |destroy|, if non-null, to each item in the new tree so far, - and returns |NULL|. - If |allocator != NULL|, it is used for allocation in the new tree. - Otherwise, the same allocator used for |org| is used. */ -struct avl_table * -avl_copy (const struct avl_table *org, avl_copy_func *copy, - avl_item_func *destroy, struct libavl_allocator *allocator) -{ - struct avl_node *stack[2 * (AVL_MAX_HEIGHT + 1)]; - int height = 0; - - struct avl_table *new; - const struct avl_node *x; - struct avl_node *y; - - assert (org != NULL); - new = avl_create (org->avl_compare, org->avl_param, - allocator != NULL ? allocator : org->avl_alloc); - if (new == NULL) - return NULL; - new->avl_count = org->avl_count; - if (new->avl_count == 0) - return new; - - x = (const struct avl_node *) &org->avl_root; - y = (struct avl_node *) &new->avl_root; - for (;;) - { - while (x->avl_link[0] != NULL) - { - assert (height < 2 * (AVL_MAX_HEIGHT + 1)); - - y->avl_link[0] = - new->avl_alloc->libavl_malloc (new->avl_alloc, - sizeof *y->avl_link[0]); - if (y->avl_link[0] == NULL) - { - if (y != (struct avl_node *) &new->avl_root) - { - y->avl_data = NULL; - y->avl_link[1] = NULL; - } - - copy_error_recovery (stack, height, new, destroy); - return NULL; - } - - stack[height++] = (struct avl_node *) x; - stack[height++] = y; - x = x->avl_link[0]; - y = y->avl_link[0]; - } - y->avl_link[0] = NULL; - - for (;;) - { - y->avl_balance = x->avl_balance; - if (copy == NULL) - y->avl_data = x->avl_data; - else - { - y->avl_data = copy (x->avl_data, org->avl_param); - if (y->avl_data == NULL) - { - y->avl_link[1] = NULL; - copy_error_recovery (stack, height, new, destroy); - return NULL; - } - } - - if (x->avl_link[1] != NULL) - { - y->avl_link[1] = - new->avl_alloc->libavl_malloc (new->avl_alloc, - sizeof *y->avl_link[1]); - if (y->avl_link[1] == NULL) - { - copy_error_recovery (stack, height, new, destroy); - return NULL; - } - - x = x->avl_link[1]; - y = y->avl_link[1]; - break; - } - else - y->avl_link[1] = NULL; - - if (height <= 2) - return new; - - y = stack[--height]; - x = stack[--height]; - } - } -} - -/* Frees storage allocated for |tree|. - If |destroy != NULL|, applies it to each data item in inorder. */ -void -avl_destroy (struct avl_table *tree, avl_item_func *destroy) -{ - struct avl_node *p, *q; - - assert (tree != NULL); - - for (p = tree->avl_root; p != NULL; p = q) - if (p->avl_link[0] == NULL) - { - q = p->avl_link[1]; - if (destroy != NULL && p->avl_data != NULL) - destroy (p->avl_data, tree->avl_param); - tree->avl_alloc->libavl_free (tree->avl_alloc, p); - } - else - { - q = p->avl_link[0]; - p->avl_link[0] = q->avl_link[1]; - q->avl_link[1] = p; - } - - tree->avl_alloc->libavl_free (tree->avl_alloc, tree); -} - -/* Allocates |size| bytes of space using |malloc()|. - Returns a null pointer if allocation fails. */ -void * -avl_malloc (struct libavl_allocator *allocator, size_t size) -{ - assert (allocator != NULL && size > 0); - return malloc (size); -} - -/* Frees |block|. */ -void -avl_free (struct libavl_allocator *allocator, void *block) -{ - assert (allocator != NULL && block != NULL); - free (block); -} - -/* Default memory allocator that uses |malloc()| and |free()|. */ -struct libavl_allocator avl_allocator_default = - { - avl_malloc, - avl_free - }; - -#undef NDEBUG -#include - -/* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */ -void -(avl_assert_insert) (struct avl_table *table, void *item) -{ - void **p = avl_probe (table, item); - assert (p != NULL && *p == item); -} - -/* Asserts that |avl_delete()| really removes |item| from |table|, - and returns the removed item. */ -void * -(avl_assert_delete) (struct avl_table *table, void *item) -{ - void *p = avl_delete (table, item); - assert (p != NULL); - return p; -} - diff --git a/Build/source/texk/web2c/luatexdir/avlstuff.c b/Build/source/texk/web2c/luatexdir/avlstuff.c deleted file mode 100644 index 74fcf6b8eda..00000000000 --- a/Build/source/texk/web2c/luatexdir/avlstuff.c +++ /dev/null @@ -1,180 +0,0 @@ -/* -Copyright (c) 2004-2005 Han The Thanh, - -This file is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This file is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with this file; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id$ - -*/ - -#include "ptexlib.h" -#include -#include -#include "avl.h" - -static struct avl_table *PdfObjTree[pdf_objtype_max + 1] = - { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - -/**********************************************************************/ -/* memory management functions for AVL */ - -void *avl_xmalloc(struct libavl_allocator *allocator, size_t size) -{ - assert(allocator != NULL && size > 0); - return xmalloc(size); -} - -void avl_xfree(struct libavl_allocator *allocator, void *block) -{ - assert(allocator != NULL && block != NULL); - xfree(block); -} - -struct libavl_allocator avl_xallocator = { - avl_xmalloc, - avl_xfree -}; - -/**********************************************************************/ -/* general AVL comparison functions */ - -int comp_int_entry(const void *pa, const void *pb, void *p) -{ - cmp_return(*(const int *) pa, *(const int *) pb); - return 0; -} - -int comp_string_entry(const void *pa, const void *pb, void *p) -{ - return strcmp((const char *) pa, (const char *) pb); -} - -/**********************************************************************/ -/* One AVL tree for each obj_type 0...pdfobjtypemax */ - - -typedef struct oentry_ { - integer int0; - integer objptr; -} oentry; - -/* AVL sort oentry into avl_table[] */ - -int compare_info(const void *pa, const void *pb, void *param) -{ - integer a, b; - int as, ae, bs, be, al, bl; - - a = ((const oentry *) pa)->int0; - b = ((const oentry *) pb)->int0; - if (a < 0 && b < 0) { /* string comparison */ - if (a <= 2097152 && b <= 2097152) { - a+=2097152; - b+=2097152; - as = str_start[-a]; - ae = str_start[-a + 1]; /* start of next string in pool */ - bs = str_start[-b]; - be = str_start[-b + 1]; - al = ae - as; - bl = be - bs; - if (al < bl) /* compare first by string length */ - return -1; - if (al > bl) - return 1; - for (; as < ae; as++, bs++) { - if (str_pool[as] < str_pool[bs]) - return -1; - if (str_pool[as] > str_pool[bs]) - return 1; - } - } else { - pdftex_fail("avlstuff.c: compare_items() for single characters: NI"); - } - } else { /* integer comparison */ - if (a < b) - return -1; - if (a > b) - return 1; - } - return 0; -} - -void avl_put_obj(integer objptr, integer t) -{ - static void **pp; - static oentry *oe; - - if (PdfObjTree[t] == NULL) { - PdfObjTree[t] = avl_create(compare_info, NULL, &avl_xallocator); - if (PdfObjTree[t] == NULL) - pdftex_fail("avlstuff.c: avl_create() PdfObjTree failed"); - } - oe = xtalloc(1, oentry); - oe->int0 = obj_tab[objptr].int0; - oe->objptr = objptr; /* allows to relocate objtab */ - pp = avl_probe(PdfObjTree[t], oe); - if (pp == NULL) - pdftex_fail("avlstuff.c: avl_probe() out of memory in insertion"); -} - - -/* replacement for linear search pascal function "find_obj()" */ - -integer avl_find_obj(integer t, integer i, integer byname) -{ - static oentry *p; - static oentry tmp; - - if (byname > 0) - tmp.int0 = -i; - else - tmp.int0 = i; - if (PdfObjTree[t] == NULL) - return 0; - p = (oentry *) avl_find(PdfObjTree[t], &tmp); - if (p == NULL) - return 0; - return p->objptr; -} - -/**********************************************************************/ - -struct avl_table *mf_tree = NULL; - -typedef struct { - char *tfm_name; - internalfontnumber fontnum; -} mf_entry; - -/**********************************************************************/ -/* cleaning up... */ - -static void destroy_oentry(void *pa, void *pb) -{ - oentry *p = (oentry *) pa; - xfree(p); -} - -void PdfObjTree_free() -{ - int i; - - for (i = 0; i <= pdf_objtype_max; i++) { - if (PdfObjTree[i] != NULL) - avl_destroy(PdfObjTree[i], destroy_oentry); - } -} - -/**********************************************************************/ diff --git a/Build/source/texk/web2c/luatexdir/avlstuff.h b/Build/source/texk/web2c/luatexdir/avlstuff.h deleted file mode 100644 index e5a4de894d2..00000000000 --- a/Build/source/texk/web2c/luatexdir/avlstuff.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright (c) 2004 Han The Thanh, - -This file is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This file is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with this file; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id$ - -formatted by indent -kr -*/ - -#include "avl.h" - -/* memory management functions for avl */ - -extern struct libavl_allocator avl_xallocator; - -/* end of file avlstuff.h */ diff --git a/Build/source/texk/web2c/luatexdir/commands.h b/Build/source/texk/web2c/luatexdir/commands.h new file mode 100644 index 00000000000..2ee3b8f28b4 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/commands.h @@ -0,0 +1,550 @@ +/* commands.h + + Copyright 2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: commands.h 2094 2009-03-23 14:13:54Z taco $ */ + + +typedef enum { + relax_cmd = 0, /* do nothing ( \.{\\relax} ) */ +#define escape_cmd relax_cmd /* escape delimiter (called \.\\ in {\sl The \TeX book\/}) */ + left_brace_cmd, /* beginning of a group ( \.\{ ) */ + right_brace_cmd, /* ending of a group ( \.\} ) */ + math_shift_cmd, /* mathematics shift character ( \.\$ ) */ + tab_mark_cmd, /* alignment delimiter ( \.\&, \.{\\span} ) */ + car_ret_cmd, /* end of line ( |carriage_return|, \.{\\cr}, \.{\\crcr} ) */ +#define out_param_cmd car_ret_cmd /* output a macro parameter */ + mac_param_cmd, /* macro parameter symbol ( \.\# ) */ + sup_mark_cmd, /* superscript ( \.{\char'136} ) */ + sub_mark_cmd, /* subscript ( \.{\char'137} ) */ + endv_cmd, /* end of \ list in alignment template */ +#define ignore_cmd endv_cmd /* characters to ignore ( \.{\^\^@@} ) */ + spacer_cmd, /* characters equivalent to blank space ( \.{\ } ) */ + letter_cmd, /* characters regarded as letters ( \.{A..Z}, \.{a..z} ) */ + other_char_cmd, /* none of the special character types */ + par_end_cmd, /* end of paragraph ( \.{\\par} ) */ +#define active_char_cmd par_end_cmd /* characters that invoke macros ( \.{\char`\~} ) */ +#define match_cmd par_end_cmd /* match a macro parameter */ + stop_cmd, /* end of job ( \.{\\end}, \.{\\dump} ) */ +#define comment_cmd stop_cmd /* characters that introduce comments ( \.\% ) */ +#define end_match_cmd stop_cmd /* end of parameters to macro */ + delim_num_cmd, /* specify delimiter numerically ( \.{\\delimiter} ) */ +#define invalid_char_cmd delim_num_cmd /* characters that shouldn't appear ( \.{\^\^?} ) */ +#define max_char_code_cmd delim_num_cmd /* largest catcode for individual characters */ + char_num_cmd, /* character specified numerically ( \.{\\char} ) */ + math_char_num_cmd, /* explicit math code ( \.{\\mathchar} ) */ + mark_cmd, /* mark definition ( \.{\\mark} ) */ + xray_cmd, /* peek inside of \TeX\ ( \.{\\show}, \.{\\showbox}, etc.~) */ + make_box_cmd, /* make a box ( \.{\\box}, \.{\\copy}, \.{\\hbox}, etc.~) */ + hmove_cmd, /* horizontal motion ( \.{\\moveleft}, \.{\\moveright} ) */ + vmove_cmd, /* vertical motion ( \.{\\raise}, \.{\\lower} ) */ + un_hbox_cmd, /* unglue a box ( \.{\\unhbox}, \.{\\unhcopy} ) */ + un_vbox_cmd, /* unglue a box ( \.{\\unvbox}, \.{\\unvcopy} or + \.{\\pagediscards}, \.{\\splitdiscards} ) */ + remove_item_cmd, /* nullify last item ( \.{\\unpenalty}, \.{\\unkern}, \.{\\unskip} ) */ + hskip_cmd, /* horizontal glue ( \.{\\hskip}, \.{\\hfil}, etc.~) */ + vskip_cmd, /* vertical glue ( \.{\\vskip}, \.{\\vfil}, etc.~) */ + mskip_cmd, /* math glue ( \.{\\mskip} ) */ + kern_cmd, /* fixed space ( \.{\\kern}) */ + mkern_cmd, /* math kern ( \.{\\mkern} ) */ + leader_ship_cmd, /* use a box ( \.{\\shipout}, \.{\\leaders}, etc.~) */ + halign_cmd, /* horizontal table alignment ( \.{\\halign} ) */ + valign_cmd, /* vertical table alignment ( \.{\\valign} ) */ + no_align_cmd, /* temporary escape from alignment ( \.{\\noalign} ) */ + vrule_cmd, /* vertical rule ( \.{\\vrule} ) */ + hrule_cmd, /* horizontal rule ( \.{\\hrule} ) */ + insert_cmd, /* vlist inserted in box ( \.{\\insert} ) */ + vadjust_cmd, /* vlist inserted in enclosing paragraph ( \.{\\vadjust} ) */ + ignore_spaces_cmd, /* gobble |spacer| tokens ( \.{\\ignorespaces} ) */ + after_assignment_cmd, /* save till assignment is done ( \.{\\afterassignment} ) */ + after_group_cmd, /* save till group is done ( \.{\\aftergroup} ) */ + break_penalty_cmd, /* additional badness ( \.{\\penalty} ) */ + start_par_cmd, /* begin paragraph ( \.{\\indent}, \.{\\noindent} ) */ + ital_corr_cmd, /* italic correction ( \.{\\/} ) */ + accent_cmd, /* attach accent in text ( \.{\\accent} ) */ + math_accent_cmd, /* attach accent in math ( \.{\\mathaccent} ) */ + discretionary_cmd, /* discretionary texts ( \.{\\-}, \.{\\discretionary} ) */ + eq_no_cmd, /* equation number ( \.{\\eqno}, \.{\\leqno} ) */ + left_right_cmd, /* variable delimiter ( \.{\\left}, \.{\\right} or \.{\\middle} ) */ + math_comp_cmd, /* component of formula ( \.{\\mathbin}, etc.~) */ + limit_switch_cmd, /* diddle limit conventions ( \.{\\displaylimits}, etc.~) */ + above_cmd, /* generalized fraction ( \.{\\above}, \.{\\atop}, etc.~) */ + math_style_cmd, /* style specification ( \.{\\displaystyle}, etc.~) */ + math_choice_cmd, /* choice specification ( \.{\\mathchoice} ) */ + non_script_cmd, /* conditional math glue ( \.{\\nonscript} ) */ + vcenter_cmd, /* vertically center a vbox ( \.{\\vcenter} ) */ + case_shift_cmd, /* force specific case ( \.{\\lowercase}, \.{\\uppercase}~) */ + message_cmd, /* send to user ( \.{\\message}, \.{\\errmessage} ) */ + extension_cmd, /* extensions to \TeX\ ( \.{\\write}, \.{\\special}, etc.~) */ + in_stream_cmd, /* files for reading ( \.{\\openin}, \.{\\closein} ) */ + begin_group_cmd, /* begin local grouping ( \.{\\begingroup} ) */ + end_group_cmd, /* end local grouping ( \.{\\endgroup} ) */ + omit_cmd, /* omit alignment template ( \.{\\omit} ) */ + ex_space_cmd, /* explicit space ( \.{\\\ } ) */ + no_boundary_cmd, /* suppress boundary ligatures ( \.{\\noboundary} ) */ + radical_cmd, /* square root and similar signs ( \.{\\radical} ) */ + end_cs_name_cmd, /* end control sequence ( \.{\\endcsname} ) */ + char_ghost_cmd, /* \.{\\ghostleft}, \.{\\ghostright} character for kerning */ + assign_local_box_cmd, /* box for guillemets \.{\\localleftbox} or \.{\\localrightbox} */ + char_given_cmd, /* character code defined by \.{\\chardef} */ +#define min_internal_cmd char_given_cmd /* the smallest code that can follow \.{\\the} */ + math_given_cmd, /* math code defined by \.{\\mathchardef} */ + omath_given_cmd, /* math code defined by \.{\\omathchardef} */ + xmath_given_cmd, /* math code defined by \.{\\LuaTeXmathchardef} */ + last_item_cmd, /* most recent item ( \.{\\lastpenalty}, \.{\\lastkern}, \.{\\lastskip} ) */ +#define max_non_prefixed_command_cmd last_item_cmd /* largest command code that can't be \.{\\global} */ + toks_register_cmd, /* token list register ( \.{\\toks} ) */ + assign_toks_cmd, /* special token list ( \.{\\output}, \.{\\everypar}, etc.~) */ + assign_int_cmd, /* user-defined integer ( \.{\\tolerance}, \.{\\day}, etc.~) */ + assign_attr_cmd, /* user-defined attributes */ + assign_dimen_cmd, /* user-defined length ( \.{\\hsize}, etc.~) */ + assign_glue_cmd, /* user-defined glue ( \.{\\baselineskip}, etc.~) */ + assign_mu_glue_cmd, /* user-defined muglue ( \.{\\thinmuskip}, etc.~) */ + assign_font_dimen_cmd, /* user-defined font dimension ( \.{\\fontdimen} ) */ + assign_font_int_cmd, /* user-defined font integer ( \.{\\hyphenchar}, \.{\\skewchar} ) */ + set_aux_cmd, /* specify state info ( \.{\\spacefactor}, \.{\\prevdepth} ) */ + set_prev_graf_cmd, /* specify state info ( \.{\\prevgraf} ) */ + set_page_dimen_cmd, /* specify state info ( \.{\\pagegoal}, etc.~) */ + set_page_int_cmd, /* specify state info ( \.{\\deadcycles}, \.{\\insertpenalties} ) */ + set_box_dimen_cmd, /* change dimension of box ( \.{\\wd}, \.{\\ht}, \.{\\dp} ) */ + set_tex_shape_cmd, /* specify fancy paragraph shape ( \.{\\parshape} ) */ + set_etex_shape_cmd, /* specify etex extended list ( \.{\\interlinepenalties}, etc.~) */ + def_char_code_cmd, /* define a character code ( \.{\\catcode}, etc.~) */ + def_del_code_cmd, /* define a delimiter code ( \.{\\delcode}) */ + extdef_math_code_cmd, /* define an extended character code ( \.{\\omathcode}, etc.~) */ + extdef_del_code_cmd, /* define an extended delimiter code ( \.{\\odelcode}, etc.~) */ + def_family_cmd, /* declare math fonts ( \.{\\textfont}, etc.~) */ + set_math_param_cmd, /* set math parameters ( \.{\\mathquad}, etc.~) */ + set_font_cmd, /* set current font ( font identifiers ) */ + def_font_cmd, /* define a font file ( \.{\\font} ) */ + register_cmd, /* internal register ( \.{\\count}, \.{\\dimen}, etc.~) */ + assign_box_dir_cmd, /* (\.{\\boxdir}) */ + assign_dir_cmd, /* (\.{\\pagedir}, \.{\\textdir}) */ +#define max_internal_cmd assign_dir_cmd /* the largest code that can follow \.{\\the} */ + advance_cmd, /* advance a register or parameter ( \.{\\advance} ) */ + multiply_cmd, /* multiply a register or parameter ( \.{\\multiply} ) */ + divide_cmd, /* divide a register or parameter ( \.{\\divide} ) */ + prefix_cmd, /* qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} ) */ + let_cmd, /* assign a command code ( \.{\\let}, \.{\\futurelet} ) */ + shorthand_def_cmd, /* code definition ( \.{\\chardef}, \.{\\countdef}, etc.~) */ + read_to_cs_cmd, /* read into a control sequence ( \.{\\read} ) */ + def_cmd, /* macro definition ( \.{\\def}, \.{\\gdef}, \.{\\xdef}, \.{\\edef} ) */ + set_box_cmd, /* set a box ( \.{\\setbox} ) */ + hyph_data_cmd, /* hyphenation data ( \.{\\hyphenation}, \.{\\patterns} ) */ + set_interaction_cmd, /* define level of interaction ( \.{\\batchmode}, etc.~) */ + letterspace_font_cmd, /* letterspace a font ( \.{\\letterspacefont} ) */ + pdf_copy_font_cmd, /* create a new font instance ( \.{\\pdfcopyfont} ) */ + set_ocp_cmd, /* Place a translation process in the stream */ + def_ocp_cmd, /* Define and load a translation process */ + set_ocp_list_cmd, /* Place a list of OCPs in the stream */ + def_ocp_list_cmd, /* Define a list of OCPs */ + clear_ocp_lists_cmd, /* Remove all active OCP lists */ + push_ocp_list_cmd, /* Add to the sequence of active OCP lists */ + pop_ocp_list_cmd, /* Remove from the sequence of active OCP lists */ + ocp_list_op_cmd, /* Operations for building a list of OCPs */ + ocp_trace_level_cmd, /* Tracing of active OCPs, either 0 or 1 */ +#define max_command_cmd ocp_trace_level_cmd /* the largest command code seen at |big_switch| */ + undefined_cs_cmd, /* initial state of most |eq_type| fields */ + expand_after_cmd, /* special expansion ( \.{\\expandafter} ) */ + no_expand_cmd, /* special nonexpansion ( \.{\\noexpand} ) */ + input_cmd, /* input a source file ( \.{\\input}, \.{\\endinput} or + \.{\\scantokens} or \.{\\scantextokens} ) */ + if_test_cmd, /* conditional text ( \.{\\if}, \.{\\ifcase}, etc.~) */ + fi_or_else_cmd, /* delimiters for conditionals ( \.{\\else}, etc.~) */ + cs_name_cmd, /* make a control sequence from tokens ( \.{\\csname} ) */ + convert_cmd, /* convert to text ( \.{\\number}, \.{\\string}, etc.~) */ + the_cmd, /* expand an internal quantity ( \.{\\the} or \.{\\unexpanded}, \.{\\detokenize} ) */ + top_bot_mark_cmd, /* inserted mark ( \.{\\topmark}, etc.~) */ + call_cmd, /* non-long, non-outer control sequence */ + long_call_cmd, /* long, non-outer control sequence */ + outer_call_cmd, /* non-long, outer control sequence */ + long_outer_call_cmd, /* long, outer control sequence */ + end_template_cmd, /* end of an alignment template */ + dont_expand_cmd, /* the following token was marked by \.{\\noexpand} */ + glue_ref_cmd, /* the equivalent points to a glue specification */ + shape_ref_cmd, /* the equivalent points to a parshape specification */ + box_ref_cmd, /* the equivalent points to a box node, or is |null| */ + data_cmd, /* the equivalent is simply a halfword number */ +#define last_cmd data_cmd +} tex_command_code; + + +typedef enum { + int_val_level = 0, /* integer values */ + attr_val_level, /* integer values */ + dimen_val_level, /* dimension values */ + glue_val_level, /* glue specifications */ + mu_val_level, /* math glue specifications */ + dir_val_level, /* directions */ + ident_val_level, /* font identifier */ + tok_val_level, /* token lists */ +} value_level_code; + +typedef enum { + above_code = 0, + over_code = 1, + atop_code = 2, + delimited_code = 3 +} fraction_codes; + + +typedef enum { + convert_number_code = 0, /* command code for \.{\\number} */ + convert_roman_numeral_code, /* command code for \.{\\romannumeral} */ + convert_string_code, /* command code for \.{\\string} */ + convert_meaning_code, /* command code for \.{\\meaning} */ + convert_font_name_code, /* command code for \.{\\fontname} */ + convert_etex_code, /* command code for \.{\\eTeXVersion} */ + convert_omega_code, /* command code for \.{\\OmegaVersion} */ + convert_aleph_code, /* command code for \.{\\AlephVersion} */ + convert_format_name_code, /* command code for \.{\\AlephVersion} */ + convert_pdftex_revision_code, /* command code for \.{\\pdftexrevision} */ +#define convert_pdftex_first_expand_code convert_pdftex_revision_code /* base for \pdfTeX's command codes */ + convert_pdftex_banner_code, /* command code for \.{\\pdftexbanner} */ + convert_pdf_font_name_code, /* command code for \.{\\pdffontname} */ + convert_pdf_font_objnum_code, /* command code for \.{\\pdffontobjnum} */ + convert_pdf_font_size_code, /* command code for \.{\\pdffontsize} */ + convert_pdf_page_ref_code, /* command code for \.{\\pdfpageref} */ + convert_pdf_xform_name_code, /* command code for \.{\\pdfxformname} */ + convert_left_margin_kern_code, /* command code for \.{\\leftmarginkern} */ + convert_right_margin_kern_code, /* command code for \.{\\rightmarginkern} */ + convert_pdf_creation_date_code, /* command code for \.{\\pdfcreationdate} */ + convert_uniform_deviate_code, /* command code for \.{\\uniformdeviate} */ + convert_normal_deviate_code, /* command code for \.{\\normaldeviate} */ + convert_pdf_insert_ht_code, /* command code for \.{\\pdfinsertht} */ + convert_pdf_ximage_bbox_code, /* command code for \.{\\pdfximagebbox} */ + convert_lua_code, /* command code for \.{\\directlua} */ + convert_lua_escape_string_code, /* command code for \.{\\luaescapestring} */ + convert_pdf_colorstack_init_code, /* command code for \.{\\pdfcolorstackinit} */ + convert_luatex_revision_code, /* command code for \.{\\luatexrevision} */ + convert_luatex_date_code, /* command code for \.{\\luatexdate} */ + convert_expanded_code, /* command code for \.{\\expanded} */ + convert_job_name_code, /* command code for \.{\\jobname} */ +#define convert_pdftex_convert_codes convert_job_name_code /* end of \pdfTeX's command codes */ + convert_Aleph_revision_code, /* command code for \.{\\Alephrevision} */ + convert_Omega_revision_code, /* command code for \.{\\Omegarevision} */ + convert_eTeX_revision_code, /* command code for \.{\\eTeXrevision} */ + convert_font_identifier_code, /* command code for \.{tex.fontidentifier} (virtual) */ +} convert_codes; + +typedef enum { + last_item_lastpenalty_code = 0, /* code for \.{\\lastpenalty} */ + last_item_lastattr_code, /* not used */ + last_item_lastkern_code, /* code for \.{\\lastkern} */ + last_item_lastskip_code, /* code for \.{\\lastskip} */ + last_item_last_node_type_code, /* code for \.{\\lastnodetype} */ + last_item_input_line_no_code, /* code for \.{\\inputlineno} */ + last_item_badness_code, /* code for \.{\\badness} */ + last_item_pdftex_version_code, /* code for \.{\\pdftexversion} */ +#define last_item_pdftex_first_rint_code last_item_pdftex_version_code /* base for \pdfTeX's command codes */ + last_item_pdf_last_obj_code, /* code for \.{\\pdflastobj} */ + last_item_pdf_last_xform_code, /* code for \.{\\pdflastxform} */ + last_item_pdf_last_ximage_code, /* code for \.{\\pdflastximage} */ + last_item_pdf_last_ximage_pages_code, /* code for \.{\\pdflastximagepages} */ + last_item_pdf_last_annot_code, /* code for \.{\\pdflastannot} */ + last_item_pdf_last_x_pos_code, /* code for \.{\\pdflastxpos} */ + last_item_pdf_last_y_pos_code, /* code for \.{\\pdflastypos} */ + last_item_pdf_retval_code, /* global multi-purpose return value */ + last_item_pdf_last_ximage_colordepth_code, /* code for \.{\\pdflastximagecolordepth} */ + last_item_random_seed_code, /* code for \.{\\pdfrandomseed} */ + last_item_pdf_last_link_code, /* code for \.{\\pdflastlink} */ + last_item_luatex_version_code, /* code for \.{\\luatexversion} */ +#define last_item_pdftex_last_item_codes last_item_luatex_version_code /* end of \pdfTeX's command codes */ + last_item_Aleph_version_code, /* code for \.{\\Alephversion} */ +#define last_item_Aleph_int last_item_Aleph_version_code + last_item_Omega_version_code, /* code for \.{\\Omegaversion} */ + last_item_Aleph_minor_version_code, /* code for \.{\\Alephminorversion} */ + last_item_Omega_minor_version_code, /* code for \.{\\Omegaminorversion} */ + last_item_eTeX_minor_version_code, /* code for \.{\\eTeXminorversion} */ + last_item_eTeX_version_code, /* code for \.{\\eTeXversion} */ +#define last_item_eTeX_int last_item_eTeX_version_code /* first of \eTeX\ codes for integers */ + last_item_current_group_level_code, /* code for \.{\\currentgrouplevel} */ + last_item_current_group_type_code, /* code for \.{\\currentgrouptype} */ + last_item_current_if_level_code, /* code for \.{\\currentiflevel} */ + last_item_current_if_type_code, /* code for \.{\\currentiftype} */ + last_item_current_if_branch_code, /* code for \.{\\currentifbranch} */ + last_item_glue_stretch_order_code, /* code for \.{\\gluestretchorder} */ + last_item_glue_shrink_order_code, /* code for \.{\\glueshrinkorder} */ + last_item_font_char_wd_code, /* code for \.{\\fontcharwd} */ +#define last_item_eTeX_dim last_item_font_char_wd_code /* first of \eTeX\ codes for dimensions */ + last_item_font_char_ht_code, /* code for \.{\\fontcharht} */ + last_item_font_char_dp_code, /* code for \.{\\fontchardp} */ + last_item_font_char_ic_code, /* code for \.{\\fontcharic} */ + last_item_par_shape_length_code, /* code for \.{\\parshapelength} */ + last_item_par_shape_indent_code, /* code for \.{\\parshapeindent} */ + last_item_par_shape_dimen_code, /* code for \.{\\parshapedimen} */ + last_item_glue_stretch_code, /* code for \.{\\gluestretch} */ + last_item_glue_shrink_code, /* code for \.{\\glueshrink} */ + last_item_mu_to_glue_code, /* code for \.{\\mutoglue} */ +#define last_item_eTeX_glue last_item_mu_to_glue_code /* first of \eTeX\ codes for glue */ + last_item_glue_to_mu_code, /* code for \.{\\gluetomu} */ +#define last_item_eTeX_mu last_item_glue_to_mu_code /* first of \eTeX\ codes for muglue */ + last_item_numexpr_code, /* code for \.{\\numexpr} */ +#define last_item_eTeX_expr last_item_numexpr_code /* first of \eTeX\ codes for expressions */ + last_item_attrexpr_code, /* not used */ + last_item_dimexpr_code, /* code for \.{\\dimexpr} */ + last_item_glueexpr_code, /* code for \.{\\glueexpr} */ + last_item_muexpr_code, /* code for \.{\\muexpr} */ +} last_item_codes; + +typedef enum { + param_par_shape_code = 0, /* specifies paragraph shape */ + param_output_routine_code, /* points to token list for \.{\\output} */ + param_every_par_code, /* points to token list for \.{\\everypar} */ + param_every_math_code, /* points to token list for \.{\\everymath} */ + param_every_display_code, /* points to token list for \.{\\everydisplay} */ + param_every_hbox_code, /* points to token list for \.{\\everyhbox} */ + param_every_vbox_code, /* points to token list for \.{\\everyvbox} */ + param_every_job_code, /* points to token list for \.{\\everyjob} */ + param_every_cr_code, /* points to token list for \.{\\everycr} */ + param_err_help_code, /* points to token list for \.{\\errhelp} */ + param_pdf_pages_attr_code, /* points to token list for \.{\\pdfpagesattr} */ + param_pdf_page_attr_code, /* points to token list for \.{\\pdfpageattr} */ + param_pdf_page_resources_code, /* points to token list for \.{\\pdfpageresources} */ + param_pdf_pk_mode_code, /* points to token list for \.{\\pdfpkmode} */ + param_every_eof_code, /* points to token list for \.{\\everyeof} */ + param_ocp_trace_level_code, + param_ocp_active_number_code, + param_ocp_active_min_ptr_code, + param_ocp_active_max_ptr_code, + param_ocp_active_code +} param_local_pars; + + +typedef enum { + param_pretolerance_code = 0, /* badness tolerance before hyphenation */ + param_tolerance_code, /* badness tolerance after hyphenation */ + param_line_penalty_code, /* added to the badness of every line */ + param_hyphen_penalty_code, /* penalty for break after discretionary hyphen */ + param_ex_hyphen_penalty_code, /* penalty for break after explicit hyphen */ + param_club_penalty_code, /* penalty for creating a club line */ + param_widow_penalty_code, /* penalty for creating a widow line */ + param_display_widow_penalty_code, /* ditto, just before a display */ + param_broken_penalty_code, /* penalty for breaking a page at a broken line */ + param_bin_op_penalty_code, /* penalty for breaking after a binary operation */ + param_rel_penalty_code, /* penalty for breaking after a relation */ + param_pre_display_penalty_code, /* penalty for breaking just before a displayed formula */ + param_post_display_penalty_code, /* penalty for breaking just after a displayed formula */ + param_inter_line_penalty_code, /* additional penalty between lines */ + param_double_hyphen_demerits_code, /* demerits for double hyphen break */ + param_final_hyphen_demerits_code, /* demerits for final hyphen break */ + param_adj_demerits_code, /* demerits for adjacent incompatible lines */ + param_mag_code, /* magnification ratio */ + param_delimiter_factor_code, /* ratio for variable-size delimiters */ + param_looseness_code, /* change in number of lines for a paragraph */ + param_time_code, /* current time of day */ + param_day_code, /* current day of the month */ + param_month_code, /* current month of the year */ + param_year_code, /* current year of our Lord */ + param_show_box_breadth_code, /* nodes per level in |show_box| */ + param_show_box_depth_code, /* maximum level in |show_box| */ + param_hbadness_code, /* hboxes exceeding this badness will be shown by |hpack| */ + param_vbadness_code, /* vboxes exceeding this badness will be shown by |vpack| */ + param_pausing_code, /* pause after each line is read from a file */ + param_tracing_online_code, /* show diagnostic output on terminal */ + param_tracing_macros_code, /* show macros as they are being expanded */ + param_tracing_stats_code, /* show memory usage if \TeX\ knows it */ + param_tracing_paragraphs_code, /* show line-break calculations */ + param_tracing_pages_code, /* show page-break calculations */ + param_tracing_output_code, /* show boxes when they are shipped out */ + param_tracing_lost_chars_code, /* show characters that aren't in the font */ + param_tracing_commands_code, /* show command codes at |big_switch| */ + param_tracing_restores_code, /* show equivalents when they are restored */ + param_uc_hyph_code, /* hyphenate words beginning with a capital letter */ + param_output_penalty_code, /* penalty found at current page break */ + param_max_dead_cycles_code, /* bound on consecutive dead cycles of output */ + param_hang_after_code, /* hanging indentation changes after this many lines */ + param_floating_penalty_code, /* penalty for insertions heldover after a split */ + param_global_defs_code, /* override \.{\\global} specifications */ + param_cur_fam_code, /* current family */ + param_escape_char_code, /* escape character for token output */ + param_default_hyphen_char_code, /* value of \.{\\hyphenchar} when a font is loaded */ + param_default_skew_char_code, /* value of \.{\\skewchar} when a font is loaded */ + param_end_line_char_code, /* character placed at the right end of the buffer */ + param_new_line_char_code, /* character that prints as |print_ln| */ + param_language_code, /* current hyphenation table */ + param_left_hyphen_min_code, /* minimum left hyphenation fragment size */ + param_right_hyphen_min_code, /* minimum right hyphenation fragment size */ + param_holding_inserts_code, /* do not remove insertion nodes from \.{\\box255} */ + param_error_context_lines_code, /* maximum intermediate line pairs shown */ + param_local_inter_line_penalty_code, /* local \.{\\interlinepenalty} */ + param_local_broken_penalty_code, /* local \.{\\brokenpenalty} */ + param_no_local_whatsits_code, /* counts local whatsits */ + param_no_local_dirs_code, + param_level_local_dir_code, + param_luastartup_id_code, + param_disable_lig_code, + param_disable_kern_code, + param_cat_code_table_code, + param_output_box_code, + param_cur_lang_code, /* current language id */ + param_ex_hyphen_char_code, + param_page_direction_code, /* the five direction params do not exist in web */ + param_body_direction_code, + param_par_direction_code, + param_text_direction_code, + param_math_direction_code, + param_pdf_output_code, /* switch on PDF output if positive */ + param_pdf_compress_level_code, /* compress level of streams */ + param_pdf_decimal_digits_code, /* digits after the decimal point of numbers */ + param_pdf_move_chars_code, /* move chars 0..31 to higher area if possible */ + param_pdf_image_resolution_code, /* default image resolution */ + param_pdf_pk_resolution_code, /* default resolution of PK font */ + param_pdf_unique_resname_code, /* generate unique names for resouces */ + param_pdf_option_always_use_pdfpagebox_code, /* if the PDF inclusion should always use a specific PDF page box */ + param_pdf_option_pdf_inclusion_errorlevel_code, /* if the PDF inclusion should treat pdfs newer than |pdf_minor_version| as an error */ + param_pdf_minor_version_code, /* fractional part of the PDF version produced */ + param_pdf_force_pagebox_code, /* if the PDF inclusion should always use a specific PDF page box */ + param_pdf_pagebox_code, /* default pagebox to use for PDF inclusion */ + param_pdf_inclusion_errorlevel_code, /* if the PDF inclusion should treat pdfs newer than |pdf_minor_version| as an error */ + param_pdf_gamma_code, + param_pdf_image_gamma_code, + param_pdf_image_hicolor_code, + param_pdf_image_apply_gamma_code, + param_pdf_adjust_spacing_code, /* level of spacing adjusting */ + param_pdf_protrude_chars_code, /* protrude chars at left/right edge of paragraphs */ + param_pdf_tracing_fonts_code, /* level of font detail in log */ + param_pdf_objcompresslevel_code, /* activate object streams */ + param_unused_one_code, /* deleted param (pdftex integer 21) */ + param_unused_two_code, /* deleted param (pdftex integer 22) */ + param_unused_three_code, /* deleted param (pdftex integer 23) */ + param_pdf_gen_tounicode_code, /* generate ToUnicode for fonts? */ + param_pdf_draftmode_code, /* switch on draftmode if positive */ + param_pdf_replace_font_code, /* generate ToUnicode for fonts? */ + param_pdf_inclusion_copy_font_code, /* generate ToUnicode for fonts? */ + param_tracing_assigns_code, /* show assignments */ + param_tracing_groups_code, /* show save/restore groups */ + param_tracing_ifs_code, /* show conditionals */ + param_tracing_scan_tokens_code, /* show pseudo file open and close */ + param_tracing_nesting_code, /* show incomplete groups and ifs within files */ + param_pre_display_direction_code, /* text direction preceding a display */ + param_last_line_fit_code, /* adjustment for last line of paragraph */ + param_saving_vdiscards_code, /* save items discarded from vlists */ + param_saving_hyph_codes_code, /* save hyphenation codes for languages */ + param_suppress_fontnotfound_error_code, /* suppress errors for missing fonts */ + param_suppress_long_error_code, /* suppress errors for \\par in non-long contexts */ + param_suppress_ifcsname_error_code, /* suppress errors for \\ifcsname junk contexts */ + param_suppress_outer_error_code, /* suppress errors for \\outer contexts */ + param_synctex_code, /* is synctex file generation enabled ? */ +} int_param_codes; + +#define param_int_pars param_synctex_code+1 /* total number of integer parameters */ + +typedef enum { + param_par_indent_code = 0, /* indentation of paragraphs */ + param_math_surround_code, /* space around math in text */ + param_line_skip_limit_code, /* threshold for |line_skip| instead of |baseline_skip| */ + param_hsize_code, /* line width in horizontal mode */ + param_vsize_code, /* page height in vertical mode */ + param_max_depth_code, /* maximum depth of boxes on main pages */ + param_split_max_depth_code, /* maximum depth of boxes on split pages */ + param_box_max_depth_code, /* maximum depth of explicit vboxes */ + param_hfuzz_code, /* tolerance for overfull hbox messages */ + param_vfuzz_code, /* tolerance for overfull vbox messages */ + param_delimiter_shortfall_code, /* maximum amount uncovered by variable delimiters */ + param_null_delimiter_space_code, /* blank space in null delimiters */ + param_script_space_code, /* extra space after subscript or superscript */ + param_pre_display_size_code, /* length of text preceding a display */ + param_display_width_code, /* length of line for displayed equation */ + param_display_indent_code, /* indentation of line for displayed equation */ + param_overfull_rule_code, /* width of rule that identifies overfull hboxes */ + param_hang_indent_code, /* amount of hanging indentation */ + param_h_offset_code, /* amount of horizontal offset when shipping pages out */ + param_v_offset_code, /* amount of vertical offset when shipping pages out */ + param_emergency_stretch_code, /* reduces badnesses on final pass of line-breaking */ + param_page_left_offset_code, + param_page_top_offset_code, + param_page_right_offset_code, + param_page_bottom_offset_code, + param_pdf_h_origin_code, /* horigin of the PDF output */ +#define param_pdftex_first_dimen_code param_pdf_horigin_code /* first number defined in this section */ + param_pdf_v_origin_code, /* vorigin of the PDF output */ + param_page_width_code, /* page width of the PDF output */ + param_page_height_code, /* page height of the PDF output */ + param_pdf_link_margin_code, /* link margin in the PDF output */ + param_pdf_dest_margin_code, /* dest margin in the PDF output */ + param_pdf_thread_margin_code, /* thread margin in the PDF output */ + param_pdf_first_line_height_code, + param_pdf_last_line_depth_code, + param_pdf_each_line_height_code, + param_pdf_each_line_depth_code, + param_pdf_ignored_dimen_code, + param_pdf_px_dimen_code +} dimen_param_codes; + +#define param_pdftex_last_dimen_code param_pdftex_px_dimen_code /* last number defined in this section */ +#define param_dimen_pars param_pdftex_last_dimen_code+1 /* total number of dimension parameters */ + +typedef enum { + param_line_skip_code = 0, /* interline glue if |baseline_skip| is infeasible */ + param_baseline_skip_code, /* desired glue between baselines */ + param_par_skip_code, /* extra glue just above a paragraph */ + param_above_display_skip_code, /* extra glue just above displayed math */ + param_below_display_skip_code, /* extra glue just below displayed math */ + param_above_display_short_skip_code, /* glue above displayed math following short lines */ + param_below_display_short_skip_code, /* glue below displayed math following short lines */ + param_left_skip_code, /* glue at left of justified lines */ + param_right_skip_code, /* glue at right of justified lines */ + param_top_skip_code, /* glue at top of main pages */ + param_split_top_skip_code, /* glue at top of split pages */ + param_tab_skip_code, /* glue between aligned entries */ + param_space_skip_code, /* glue between words (if not |zero_glue|) */ + param_xspace_skip_code, /* glue after sentences (if not |zero_glue|) */ + param_par_fill_skip_code, /* glue on last line of paragraph */ + param_thin_mu_skip_code, /* thin space in math formula */ + param_med_mu_skip_code, /* medium space in math formula */ + param_thick_mu_skip_code, /* thick space in math formula */ +} param_skip_codes; + +#define glue_pars thick_mu_skip_code+1 /* total number of glue parameters */ + +#define eq_type(a) zeqtb[a].hh.u.B0 +#define equiv(a) zeqtb[a].hh.v.RH + +#define int_par(A) zeqtb[static_int_base+(A)].cint +#define dimen_par(A) zeqtb[static_dimen_base+(A)].cint +#define loc_par(A) equiv(static_local_base+(A)) +#define glue_par(A) equiv(static_glue_base+(A)) + + +typedef enum { + bottom_level = 0, /* group code for the outside world */ + simple_group, /* group code for local structure only */ + hbox_group, /* code for `\.{\\hbox}\grp' */ + adjusted_hbox_group, /* code for `\.{\\hbox}\grp' in vertical mode */ + vbox_group, /* code for `\.{\\vbox}\grp' */ + vtop_group, /* code for `\.{\\vtop}\grp' */ + align_group, /* code for `\.{\\halign}\grp', `\.{\\valign}\grp' */ + no_align_group, /* code for `\.{\\noalign}\grp' */ + output_group, /* code for output routine */ + math_group, /* code for, e.g., `\.{\char'136}\grp' */ + disc_group, /* code for `\.{\\discretionary}\grp\grp\grp' */ + insert_group, /* code for `\.{\\insert}\grp', `\.{\\vadjust}\grp' */ + vcenter_group, /* code for `\.{\\vcenter}\grp' */ + math_choice_group, /* code for `\.{\\mathchoice}\grp\grp\grp\grp' */ + semi_simple_group, /* code for `\.{\\begingroup...\\endgroup}' */ + math_shift_group, /* code for `\.{\$...\$}' */ + math_left_group, /* code for `\.{\\left...\\right}' */ + local_box_group, /* code for `\.{\\localleftbox...\\localrightbox}' */ + max_group_code, + split_off_group, /* box code for the top part of a \.{\\vsplit} */ + split_keep_group, /* box code for the bottom part of a \.{\\vsplit} */ + preamble_group, /* box code for the preamble processing in an alignment */ + align_set_group, /* box code for the final item pass in an alignment */ + fin_row_group /* box code for a provisory line in an alignment */ +} tex_group_codes; diff --git a/Build/source/texk/web2c/luatexdir/depend.mk b/Build/source/texk/web2c/luatexdir/depend.mk deleted file mode 100644 index 4f456e24899..00000000000 --- a/Build/source/texk/web2c/luatexdir/depend.mk +++ /dev/null @@ -1,3 +0,0 @@ -lua/mp.o: lua/mp.c mplib.h mpmp.h mppsout.h -lua/psout.o: lua/psout.c avl.h mplib.h mpmp.h mppsout.h -lua/lmplib.o: lua/lmplib.c mplib.h mpmp.h mppsout.h diff --git a/Build/source/texk/web2c/luatexdir/font/dofont.c b/Build/source/texk/web2c/luatexdir/font/dofont.c index fbe44c29ba9..14d785b8a9f 100644 --- a/Build/source/texk/web2c/luatexdir/font/dofont.c +++ b/Build/source/texk/web2c/luatexdir/font/dofont.c @@ -1,183 +1,186 @@ -/* -Copyright (c) 1996-2006 Taco Hoekwater +/* dofont.c + + Copyright 2006-2008 Taco Hoekwater -This file is part of LuaTeX. + This file is part of LuaTeX. -LuaTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -LuaTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with LuaTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: dofont.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" #include "luatex-api.h" +static const char _svn_version[] = + "$Id: dofont.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/dofont.c $"; + #define TIMERS 0 #if TIMERS -#include +# include #endif /* a bit more interfacing is needed for proper error reporting */ -static char * -font_error_message (pointer u, char *nom, scaled s) { - char *str = xmalloc(256); - char *c = makecstring(zget_cs_text(u)); - char *extra = "metric data not found or bad"; - if (s>=0 ) { - snprintf(str,255,"Font \\%s=%s at %gpt not loadable: %s", c, nom, (double)s/65536, extra); - } else if (s!=-1000) { - snprintf(str,255,"Font \\%s=%s scaled %d not loadable: %s", c, nom, (int)(-s), extra); - } else { - snprintf(str,255,"Font \\%s=%s not loadable: %s", c, nom, extra); - } - return str; +static char *font_error_message(pointer u, char *nom, scaled s) +{ + char *str = xmalloc(256); + char *c = makecstring(zget_cs_text(u)); + char *extra = "metric data not found or bad"; + if (s >= 0) { + snprintf(str, 255, "Font \\%s=%s at %gpt not loadable: %s", c, nom, + (double) s / 65536, extra); + } else if (s != -1000) { + snprintf(str, 255, "Font \\%s=%s scaled %d not loadable: %s", c, nom, + (int) (-s), extra); + } else { + snprintf(str, 255, "Font \\%s=%s not loadable: %s", c, nom, extra); + } + return str; } static int -do_define_font (integer f, char *cnom, char *caire, scaled s, integer natural_dir) { +do_define_font(integer f, char *cnom, char *caire, scaled s, + integer natural_dir) +{ - boolean res; /* was the callback successful? */ - integer callback_id; - char *cnam; + boolean res; /* was the callback successful? */ + integer callback_id; + char *cnam; #if TIMERS struct timeval tva; struct timeval tvb; double tvdiff; #endif - int r; - res = 0; - - callback_id=callback_defined(define_font_callback); - if (callback_id>0) { - if (caire == NULL || strlen(caire)==0) { - cnam = xstrdup(cnom); - } else { - cnam = xmalloc(strlen(cnom)+strlen(caire)+2); - sprintf(cnam,"%s/%s",caire,cnom); - } + int r; + res = 0; + + callback_id = callback_defined(define_font_callback); + if (callback_id > 0) { + if (caire == NULL || strlen(caire) == 0) { + cnam = xstrdup(cnom); + } else { + cnam = xmalloc(strlen(cnom) + strlen(caire) + 2); + sprintf(cnam, "%s/%s", caire, cnom); + } #if TIMERS - gettimeofday(&tva,NULL); + gettimeofday(&tva, NULL); #endif - callback_id = run_and_save_callback(callback_id,"Sdd->",cnam,s,f); + callback_id = run_and_save_callback(callback_id, "Sdd->", cnam, s, f); #if TIMERS - gettimeofday(&tvb,NULL); - tvdiff = tvb.tv_sec*1000000.0; - tvdiff += (double)tvb.tv_usec; - tvdiff -= (tva.tv_sec*1000000.0); - tvdiff -= (double)tva.tv_usec; - tvdiff /= 1000000; - fprintf(stdout,"\ncallback('define_font',%s,%i): %f seconds\n", cnam,f,tvdiff); + gettimeofday(&tvb, NULL); + tvdiff = tvb.tv_sec * 1000000.0; + tvdiff += (double) tvb.tv_usec; + tvdiff -= (tva.tv_sec * 1000000.0); + tvdiff -= (double) tva.tv_usec; + tvdiff /= 1000000; + fprintf(stdout, "\ncallback('define_font',%s,%i): %f seconds\n", cnam, + f, tvdiff); #endif - free(cnam); - if (callback_id>0) { /* success */ - luaL_checkstack(Luas[0],1,"out of stack space"); - lua_rawgeti(Luas[0],LUA_REGISTRYINDEX, callback_id); - if (lua_istable(Luas[0],-1)) { + free(cnam); + if (callback_id > 0) { /* success */ + luaL_checkstack(Luas, 1, "out of stack space"); + lua_rawgeti(Luas, LUA_REGISTRYINDEX, callback_id); + if (lua_istable(Luas, -1)) { #if TIMERS - gettimeofday(&tva,NULL); + gettimeofday(&tva, NULL); #endif - res = font_from_lua(Luas[0],f); - destroy_saved_callback (callback_id); + res = font_from_lua(Luas, f); + destroy_saved_callback(callback_id); #if TIMERS - gettimeofday(&tvb,NULL); - tvdiff = tvb.tv_sec*1000000.0; - tvdiff += (double)tvb.tv_usec; - tvdiff -= (tva.tv_sec*1000000.0); - tvdiff -= (double)tva.tv_usec; - tvdiff /= 1000000; - fprintf(stdout,"font_from_lua(%s,%i): %f seconds\n", font_name(f),f,tvdiff); + gettimeofday(&tvb, NULL); + tvdiff = tvb.tv_sec * 1000000.0; + tvdiff += (double) tvb.tv_usec; + tvdiff -= (tva.tv_sec * 1000000.0); + tvdiff -= (double) tva.tv_usec; + tvdiff /= 1000000; + fprintf(stdout, "font_from_lua(%s,%i): %f seconds\n", + font_name(f), f, tvdiff); #endif - lua_pop(Luas[0],1); - } else if (lua_isnumber(Luas[0],-1)) { - r = lua_tonumber(Luas[0],-1); - destroy_saved_callback (callback_id); - delete_font(f); - lua_pop(Luas[0],1); - return r; - } else { - lua_pop(Luas[0],1); - delete_font(f); - return 0; - } + /* lua_pop(Luas, 1); *//* done by font_from_lua */ + } else if (lua_isnumber(Luas, -1)) { + r = lua_tonumber(Luas, -1); + destroy_saved_callback(callback_id); + delete_font(f); + lua_pop(Luas, 1); + return r; + } else { + lua_pop(Luas, 1); + delete_font(f); + return 0; + } + } + } else { + res = read_tfm_info(f, cnom, caire, s); + if (res) { + set_hyphen_char(f, get_default_hyphen_char()); + set_skew_char(f, get_default_skew_char()); + } } - } else { - res = read_tfm_info(f,cnom,caire,s); if (res) { - set_hyphen_char(f,get_default_hyphen_char()); - set_skew_char(f,get_default_skew_char()); + if (font_type(f) != virtual_font_type) { /* implies lua */ + do_vf(f); + set_font_natural_dir(f, natural_dir); + } + return f; + } else { + delete_font(f); + return 0; } - } - if (res) { - do_vf(f); - set_font_natural_dir(f,natural_dir); - return f; - } else { - delete_font(f); - return 0; - } } -int -read_font_info(pointer u, strnumber nom, strnumber aire, scaled s, - integer natural_dir) { - integer f; - char *cnom, *caire = NULL; - char *msg; - cnom = xstrdup(makecstring(nom)); - if (aire != 0) - caire = xstrdup(makecstring(aire)); - - f = new_font(); - if ((f = do_define_font(f, cnom,caire,s,natural_dir))) { - if (caire != NULL) free(caire); - free(cnom); - return f; - } else { - char *help[] = {"I wasn't able to read the size data for this font,", - "so I will ignore the font specification.", - "[Wizards can fix TFM files using TFtoPL/PLtoTF.]", - "You might try inserting a different font spec;", - "e.g., type `I\font='.", - NULL } ; - if(!get_suppress_fontnotfound_error()) { - msg = font_error_message(u, cnom, s); - tex_error(msg,help); - free(msg); - } - if (caire != NULL) free(caire); - free(cnom); - return 0; - } +int read_font_info(pointer u, strnumber nom, scaled s, integer natural_dir) +{ + integer f; + char *cnom; + char *msg; + cnom = xstrdup(makecstring(nom)); + + f = new_font(); + if ((f = do_define_font(f, cnom, NULL, s, natural_dir))) { + free(cnom); + return f; + } else { + char *help[] = { "I wasn't able to read the size data for this font,", + "so I will ignore the font specification.", + "[Wizards can fix TFM files using TFtoPL/PLtoTF.]", + "You might try inserting a different font spec;", + "e.g., type `I\font='.", + NULL + }; + if (!get_suppress_fontnotfound_error()) { + msg = font_error_message(u, cnom, s); + tex_error(msg, help); + free(msg); + } + free(cnom); + return 0; + } } /* TODO This function is a placeholder. There can easily appears holes in the |font_tables| array, and we could attempt to reuse those */ -int -find_font_id (char *nom, char *aire, scaled s) { - integer f; - f = new_font(); - if ((f = do_define_font(f, nom, aire,s,-1))) { - return f; - } else { - return 0; - } +int find_font_id(char *nom, char *aire, scaled s) +{ + integer f; + f = new_font(); + if ((f = do_define_font(f, nom, aire, s, -1))) { + return f; + } else { + return 0; + } } - diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.c b/Build/source/texk/web2c/luatexdir/font/luafont.c index 4a2eda1f41c..d9fd6273b06 100644 --- a/Build/source/texk/web2c/luatexdir/font/luafont.c +++ b/Build/source/texk/web2c/luatexdir/font/luafont.c @@ -1,316 +1,477 @@ +/* luafont.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "nodes.h" +static const char _svn_version[] = + "$Id: luafont.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/luafont.c $"; + #define noVERBOSE #define SAVE_REF 1 -char *font_type_strings[] = {"unknown","virtual","real", NULL}; -char *font_format_strings[] = {"unknown","type1","type3","truetype", "opentype", NULL}; -char *font_embedding_strings[] = {"unknown","no","subset", "full", NULL}; -char *ligature_type_strings[] = {"=:", "=:|", "|=:", "|=:|", "", "=:|>", "|=:>", "|=:|>", "", "", "", "|=:|>>", NULL }; +char *font_type_strings[] = { "unknown", "virtual", "real", NULL }; +char *font_format_strings[] = + { "unknown", "type1", "type3", "truetype", "opentype", NULL }; +char *font_embedding_strings[] = { "unknown", "no", "subset", "full", NULL }; +char *ligature_type_strings[] = + { "=:", "=:|", "|=:", "|=:|", "", "=:|>", "|=:>", "|=:|>", "", "", "", + "|=:|>>", NULL +}; + +const char *MATH_param_names[] = { + "nil", + "ScriptPercentScaleDown", + "ScriptScriptPercentScaleDown", + "DelimitedSubFormulaMinHeight", + "DisplayOperatorMinHeight", + "MathLeading", + "AxisHeight", + "AccentBaseHeight", + "FlattenedAccentBaseHeight", + "SubscriptShiftDown", + "SubscriptTopMax", + "SubscriptBaselineDropMin", + "SuperscriptShiftUp", + "SuperscriptShiftUpCramped", + "SuperscriptBottomMin", + "SuperscriptBaselineDropMax", + "SubSuperscriptGapMin", + "SuperscriptBottomMaxWithSubscript", + "SpaceAfterScript", + "UpperLimitGapMin", + "UpperLimitBaselineRiseMin", + "LowerLimitGapMin", + "LowerLimitBaselineDropMin", + "StackTopShiftUp", + "StackTopDisplayStyleShiftUp", + "StackBottomShiftDown", + "StackBottomDisplayStyleShiftDown", + "StackGapMin", + "StackDisplayStyleGapMin", + "StretchStackTopShiftUp", + "StretchStackBottomShiftDown", + "StretchStackGapAboveMin", + "StretchStackGapBelowMin", + "FractionNumeratorShiftUp", + "FractionNumeratorDisplayStyleShiftUp", + "FractionDenominatorShiftDown", + "FractionDenominatorDisplayStyleShiftDown", + "FractionNumeratorGapMin", + "FractionNumeratorDisplayStyleGapMin", + "FractionRuleThickness", + "FractionDenominatorGapMin", + "FractionDenominatorDisplayStyleGapMin", + "SkewedFractionHorizontalGap", + "SkewedFractionVerticalGap", + "OverbarVerticalGap", + "OverbarRuleThickness", + "OverbarExtraAscender", + "UnderbarVerticalGap", + "UnderbarRuleThickness", + "UnderbarExtraDescender", + "RadicalVerticalGap", + "RadicalDisplayStyleVerticalGap", + "RadicalRuleThickness", + "RadicalExtraAscender", + "RadicalKernBeforeDegree", + "RadicalKernAfterDegree", + "RadicalDegreeBottomRaisePercent", + "MinConnectorOverlap", + NULL, +}; + +static void dump_intfield(lua_State * L, char *n, int c) +{ + lua_pushstring(L, n); + lua_pushnumber(L, c); + lua_rawset(L, -3); +} -void -font_char_to_lua (lua_State *L, internalfontnumber f, charinfo *co) { - int i; - liginfo *l; - kerninfo *ki; - - lua_createtable(L,0,10); - - lua_pushstring(L,"width"); - lua_pushnumber(L,get_charinfo_width(co)); - lua_rawset(L,-3); - - lua_pushstring(L,"height"); - lua_pushnumber(L,get_charinfo_height(co)); - lua_rawset(L,-3); - - lua_pushstring(L,"depth"); - lua_pushnumber(L,get_charinfo_depth(co)); - lua_rawset(L,-3); - - lua_pushstring(L,"italic"); - lua_pushnumber(L,get_charinfo_italic(co)); - lua_rawset(L,-3); - - if (get_charinfo_ef(co)!=0) { - lua_pushstring(L,"expansion_factor"); - lua_pushnumber(L,get_charinfo_ef(co)); - lua_rawset(L,-3); - } - - if (get_charinfo_lp(co)!=0) { - lua_pushstring(L,"left_protruding"); - lua_pushnumber(L,get_charinfo_lp(co)); - lua_rawset(L,-3); - } - - if (get_charinfo_lp(co)!=0) { - lua_pushstring(L,"right_protruding"); - lua_pushnumber(L,get_charinfo_rp(co)); - lua_rawset(L,-3); - } - - - if (font_encodingbytes(f) == 2 ) { - lua_pushstring(L,"index"); - lua_pushnumber(L,get_charinfo_index(co)); - lua_rawset(L,-3); - } - - if (get_charinfo_name(co)!=NULL) { - lua_pushstring(L,"name"); - lua_pushstring(L,get_charinfo_name(co)); - lua_rawset(L,-3); - } - - if (get_charinfo_tounicode(co)!=NULL) { - lua_pushstring(L,"tounicode"); - lua_pushstring(L,get_charinfo_tounicode(co)); - lua_rawset(L,-3); - } - - if (get_charinfo_tag(co) == list_tag) { - lua_pushstring(L,"next"); - lua_pushnumber(L,get_charinfo_remainder(co)); - lua_rawset(L,-3); - } - - lua_pushstring(L,"used"); - lua_pushboolean(L,(get_charinfo_used(co) ? true : false)); - lua_rawset(L,-3); - - if (get_charinfo_tag(co) == ext_tag) { - lua_pushstring(L,"extensible"); - lua_createtable(L,0,4); - lua_pushnumber(L,get_charinfo_extensible(co,EXT_TOP)); - lua_setfield(L,-2,"top"); - lua_pushnumber(L,get_charinfo_extensible(co,EXT_BOT)); - lua_setfield(L,-2,"bot"); - lua_pushnumber(L,get_charinfo_extensible(co,EXT_MID)); - lua_setfield(L,-2,"mid"); - lua_pushnumber(L,get_charinfo_extensible(co,EXT_REP)); - lua_setfield(L,-2,"rep"); - lua_rawset(L,-3); - } - ki = get_charinfo_kerns(co); - if (ki != NULL) { - lua_pushstring(L,"kerns"); - lua_createtable(L,10,1); - for (i=0;!kern_end(ki[i]);i++) { - if (kern_char(ki[i]) == right_boundarychar) { - lua_pushstring(L,"right_boundary"); - } else { - lua_pushnumber(L,kern_char(ki[i])); - } - lua_pushnumber(L,kern_kern(ki[i])); - lua_rawset(L,-3); - } - lua_rawset(L,-3); - } - l = get_charinfo_ligatures(co); - if (l!=NULL) { - lua_pushstring(L,"ligatures"); - lua_createtable(L,10,1); - for (i=0;!lig_end(l[i]);i++) { - if (lig_char(l[i]) == right_boundarychar) { - lua_pushstring(L,"right_boundary"); - } else { - lua_pushnumber(L,lig_char(l[i])); - } - lua_createtable(L,0,2); - lua_pushstring(L,"type"); - lua_pushnumber(L,lig_type(l[i])); - lua_rawset(L,-3); - lua_pushstring(L,"char"); - lua_pushnumber(L,lig_replacement(l[i])); - lua_rawset(L,-3); - lua_rawset(L,-3); - } - lua_rawset(L,-3); - } + + +void font_char_to_lua(lua_State * L, internalfontnumber f, charinfo * co) +{ + int i; + liginfo *l; + kerninfo *ki; + + lua_createtable(L, 0, 10); + + lua_pushstring(L, "width"); + lua_pushnumber(L, get_charinfo_width(co)); + lua_rawset(L, -3); + + lua_pushstring(L, "height"); + lua_pushnumber(L, get_charinfo_height(co)); + lua_rawset(L, -3); + + lua_pushstring(L, "depth"); + lua_pushnumber(L, get_charinfo_depth(co)); + lua_rawset(L, -3); + + lua_pushstring(L, "italic"); + lua_pushnumber(L, get_charinfo_italic(co)); + lua_rawset(L, -3); + + lua_pushstring(L, "top_accent"); + lua_pushnumber(L, get_charinfo_top_accent(co)); + lua_rawset(L, -3); + + lua_pushstring(L, "bot_accent"); + lua_pushnumber(L, get_charinfo_bot_accent(co)); + lua_rawset(L, -3); + + + if (get_charinfo_ef(co) != 0) { + lua_pushstring(L, "expansion_factor"); + lua_pushnumber(L, get_charinfo_ef(co)); + lua_rawset(L, -3); + } + + if (get_charinfo_lp(co) != 0) { + lua_pushstring(L, "left_protruding"); + lua_pushnumber(L, get_charinfo_lp(co)); + lua_rawset(L, -3); + } + + if (get_charinfo_lp(co) != 0) { + lua_pushstring(L, "right_protruding"); + lua_pushnumber(L, get_charinfo_rp(co)); + lua_rawset(L, -3); + } + + + if (font_encodingbytes(f) == 2) { + lua_pushstring(L, "index"); + lua_pushnumber(L, get_charinfo_index(co)); + lua_rawset(L, -3); + } + + if (get_charinfo_name(co) != NULL) { + lua_pushstring(L, "name"); + lua_pushstring(L, get_charinfo_name(co)); + lua_rawset(L, -3); + } + + if (get_charinfo_tounicode(co) != NULL) { + lua_pushstring(L, "tounicode"); + lua_pushstring(L, get_charinfo_tounicode(co)); + lua_rawset(L, -3); + } + + if (get_charinfo_tag(co) == list_tag) { + lua_pushstring(L, "next"); + lua_pushnumber(L, get_charinfo_remainder(co)); + lua_rawset(L, -3); + } + + lua_pushstring(L, "used"); + lua_pushboolean(L, (get_charinfo_used(co) ? true : false)); + lua_rawset(L, -3); + + if (get_charinfo_tag(co) == ext_tag) { + extinfo *h; + h = get_charinfo_hor_variants(co); + if (h != NULL) { + int i = 1; + lua_newtable(L); + while (h != NULL) { + lua_createtable(L, 0, 5); + dump_intfield(L, "glyph", h->glyph); + dump_intfield(L, "extender", h->extender); + dump_intfield(L, "start", h->start_overlap); + dump_intfield(L, "end", h->end_overlap); + dump_intfield(L, "advance", h->advance); + lua_rawseti(L, -2, i); + i++; + h = h->next; + } + lua_setfield(L, -2, "horiz_variants"); + } + h = get_charinfo_vert_variants(co); + if (h != NULL) { + int i = 1; + lua_newtable(L); + while (h != NULL) { + lua_createtable(L, 0, 5); + dump_intfield(L, "glyph", h->glyph); + dump_intfield(L, "extender", h->extender); + dump_intfield(L, "start", h->start_overlap); + dump_intfield(L, "end", h->end_overlap); + dump_intfield(L, "advance", h->advance); + lua_rawseti(L, -2, i); + i++; + h = h->next; + } + lua_setfield(L, -2, "vert_variants"); + } + } + ki = get_charinfo_kerns(co); + if (ki != NULL) { + lua_pushstring(L, "kerns"); + lua_createtable(L, 10, 1); + for (i = 0; !kern_end(ki[i]); i++) { + if (kern_char(ki[i]) == right_boundarychar) { + lua_pushstring(L, "right_boundary"); + } else { + lua_pushnumber(L, kern_char(ki[i])); + } + lua_pushnumber(L, kern_kern(ki[i])); + lua_rawset(L, -3); + } + lua_rawset(L, -3); + } + l = get_charinfo_ligatures(co); + if (l != NULL) { + lua_pushstring(L, "ligatures"); + lua_createtable(L, 10, 1); + for (i = 0; !lig_end(l[i]); i++) { + if (lig_char(l[i]) == right_boundarychar) { + lua_pushstring(L, "right_boundary"); + } else { + lua_pushnumber(L, lig_char(l[i])); + } + lua_createtable(L, 0, 2); + lua_pushstring(L, "type"); + lua_pushnumber(L, lig_type(l[i])); + lua_rawset(L, -3); + lua_pushstring(L, "char"); + lua_pushnumber(L, lig_replacement(l[i])); + lua_rawset(L, -3); + lua_rawset(L, -3); + } + lua_rawset(L, -3); + } } -static void -write_lua_parameters (lua_State *L, int f) { - int k; - lua_newtable(L); - for (k=1;k<=font_params(f);k++) { - lua_pushnumber(L,font_param(f,k)); - switch (k) { - case slant_code: lua_setfield(L,-2,"slant"); break; - case space_code: lua_setfield(L,-2,"space"); break; - case space_stretch_code: lua_setfield(L,-2,"space_stretch"); break; - case space_shrink_code: lua_setfield(L,-2,"space_shrink"); break; - case x_height_code: lua_setfield(L,-2,"x_height"); break; - case quad_code: lua_setfield(L,-2,"quad"); break; - case extra_space_code: lua_setfield(L,-2,"extra_space"); break; - default: - lua_rawseti(L,-2,k); - } - } - lua_setfield(L,-2,"parameters"); +static void write_lua_parameters(lua_State * L, int f) +{ + int k; + lua_newtable(L); + for (k = 1; k <= font_params(f); k++) { + lua_pushnumber(L, font_param(f, k)); + switch (k) { + case slant_code: + lua_setfield(L, -2, "slant"); + break; + case space_code: + lua_setfield(L, -2, "space"); + break; + case space_stretch_code: + lua_setfield(L, -2, "space_stretch"); + break; + case space_shrink_code: + lua_setfield(L, -2, "space_shrink"); + break; + case x_height_code: + lua_setfield(L, -2, "x_height"); + break; + case quad_code: + lua_setfield(L, -2, "quad"); + break; + case extra_space_code: + lua_setfield(L, -2, "extra_space"); + break; + default: + lua_rawseti(L, -2, k); + } + } + lua_setfield(L, -2, "parameters"); } -int -font_to_lua (lua_State *L, int f) { - int k; - charinfo *co; - if (font_cache_id(f)) { - /* fetch the table from the registry if it was - saved there by font_from_lua() */ - lua_rawgeti(L,LUA_REGISTRYINDEX,font_cache_id(f)); - /* fontdimens can be changed from tex code */ - write_lua_parameters(L,f); +static void write_lua_math_parameters(lua_State * L, int f) +{ + int k; + lua_newtable(L); + for (k = 1; k < font_math_params(f); k++) { + lua_pushnumber(L, font_math_param(f, k)); + if (k <= MATH_param_max) { + lua_setfield(L, -2, MATH_param_names[k]); + } else { + lua_rawseti(L, -2, k); + } + } + lua_setfield(L, -2, "MathConstants"); +} + + + +int font_to_lua(lua_State * L, int f) +{ + int k; + charinfo *co; + if (font_cache_id(f)) { + /* fetch the table from the registry if it was + saved there by font_from_lua() */ + lua_rawgeti(L, LUA_REGISTRYINDEX, font_cache_id(f)); + /* fontdimens can be changed from tex code */ + write_lua_parameters(L, f); + return 1; + } + + lua_newtable(L); + lua_pushstring(L, font_name(f)); + lua_setfield(L, -2, "name"); + if (font_area(f) != NULL) { + lua_pushstring(L, font_area(f)); + lua_setfield(L, -2, "area"); + } + if (font_filename(f) != NULL) { + lua_pushstring(L, font_filename(f)); + lua_setfield(L, -2, "filename"); + } + if (font_fullname(f) != NULL) { + lua_pushstring(L, font_fullname(f)); + lua_setfield(L, -2, "fullname"); + } + if (font_encodingname(f) != NULL) { + lua_pushstring(L, font_encodingname(f)); + lua_setfield(L, -2, "encodingname"); + } + + lua_pushboolean(L, (font_used(f) ? true : false)); + lua_setfield(L, -2, "used"); + + + lua_pushstring(L, font_type_strings[font_type(f)]); + lua_setfield(L, -2, "type"); + lua_pushstring(L, font_format_strings[font_format(f)]); + lua_setfield(L, -2, "format"); + lua_pushstring(L, font_embedding_strings[font_embedding(f)]); + lua_setfield(L, -2, "embedding"); + + lua_pushnumber(L, font_size(f)); + lua_setfield(L, -2, "size"); + lua_pushnumber(L, font_dsize(f)); + lua_setfield(L, -2, "designsize"); + lua_pushnumber(L, font_checksum(f)); + lua_setfield(L, -2, "checksum"); + lua_pushnumber(L, font_slant(f)); + lua_setfield(L, -2, "slant"); + lua_pushnumber(L, font_extend(f)); + lua_setfield(L, -2, "extend"); + lua_pushnumber(L, font_natural_dir(f)); + lua_setfield(L, -2, "direction"); + lua_pushnumber(L, font_encodingbytes(f)); + lua_setfield(L, -2, "encodingbytes"); + lua_pushnumber(L, font_tounicode(f)); + lua_setfield(L, -2, "tounicode"); + + /* pdf parameters */ + /* skip the first four for now, that are very much interal */ + /* + if (pdf_font_size(f) != 0) { + lua_pushnumber(L,pdf_font_size(f)); + lua_setfield(L,-2,"pdf_size"); + } + if (pdf_font_num(f) != 0) { + lua_pushnumber(L,pdf_font_num(f)); + lua_setfield(L,-2,"pdf_num"); + } + if (pdf_font_blink(f) != 0) { + lua_pushnumber(L,pdf_font_blink(f)); + lua_setfield(L,-2,"pdf_blink"); + } + if (pdf_font_elink(f) != 0) { + lua_pushnumber(L,pdf_font_elink(f)); + lua_setfield(L,-2,"pdf_elink"); + } + */ + /* the next one is read only */ + if (pdf_font_expand_ratio(f) != 0) { + lua_pushnumber(L, pdf_font_expand_ratio(f)); + lua_setfield(L, -2, "expand_ratio"); + } + if (pdf_font_shrink(f) != 0) { + lua_pushnumber(L, pdf_font_shrink(f)); + lua_setfield(L, -2, "shrink"); + } + if (pdf_font_stretch(f) != 0) { + lua_pushnumber(L, pdf_font_stretch(f)); + lua_setfield(L, -2, "stretch"); + } + if (pdf_font_step(f) != 0) { + lua_pushnumber(L, pdf_font_step(f)); + lua_setfield(L, -2, "step"); + } + if (pdf_font_auto_expand(f) != 0) { + lua_pushboolean(L, pdf_font_auto_expand(f)); + lua_setfield(L, -2, "auto_expand"); + } + if (pdf_font_attr(f) != 0) { + lua_pushstring(L, makecstring(pdf_font_attr(f))); + lua_setfield(L, -2, "attributes"); + } + + /* params */ + write_lua_parameters(L, f); + write_lua_math_parameters(L, f); + + /* chars */ + lua_createtable(L, font_tables[f]->charinfo_size, 0); /* all characters */ + + if (has_left_boundary(f)) { + co = get_charinfo(f, left_boundarychar); + font_char_to_lua(L, f, co); + lua_setfield(L, -2, "left_boundary"); + } + if (has_right_boundary(f)) { + co = get_charinfo(f, right_boundarychar); + font_char_to_lua(L, f, co); + lua_setfield(L, -2, "right_boundary"); + } + + for (k = font_bc(f); k <= font_ec(f); k++) { + if (char_exists(f, k)) { + lua_pushnumber(L, k); + co = get_charinfo(f, k); + font_char_to_lua(L, f, co); + lua_rawset(L, -3); + } + } + lua_setfield(L, -2, "characters"); return 1; - } - - lua_newtable(L); - lua_pushstring(L,font_name(f)); - lua_setfield(L,-2,"name"); - if(font_area(f)!=NULL) { - lua_pushstring(L,font_area(f)); - lua_setfield(L,-2,"area"); - } - if(font_filename(f)!=NULL) { - lua_pushstring(L,font_filename(f)); - lua_setfield(L,-2,"filename"); - } - if(font_fullname(f)!=NULL) { - lua_pushstring(L,font_fullname(f)); - lua_setfield(L,-2,"fullname"); - } - if(font_encodingname(f)!=NULL) { - lua_pushstring(L,font_encodingname(f)); - lua_setfield(L,-2,"encodingname"); - } - - lua_pushboolean(L,(font_used(f) ? true : false)); - lua_setfield(L,-2,"used"); - - - lua_pushstring(L,font_type_strings[font_type(f)]); - lua_setfield(L,-2,"type"); - lua_pushstring(L,font_format_strings[font_format(f)]); - lua_setfield(L,-2,"format"); - lua_pushstring(L,font_embedding_strings[font_embedding(f)]); - lua_setfield(L,-2,"embedding"); - - lua_pushnumber(L,font_size(f)); - lua_setfield(L,-2,"size"); - lua_pushnumber(L,font_dsize(f)); - lua_setfield(L,-2,"designsize"); - lua_pushnumber(L,font_checksum(f)); - lua_setfield(L,-2,"checksum"); - lua_pushnumber(L,font_slant(f)); - lua_setfield(L,-2,"slant"); - lua_pushnumber(L,font_extend(f)); - lua_setfield(L,-2,"extend"); - lua_pushnumber(L,font_natural_dir(f)); - lua_setfield(L,-2,"direction"); - lua_pushnumber(L,font_encodingbytes(f)); - lua_setfield(L,-2,"encodingbytes"); - lua_pushnumber(L,font_tounicode(f)); - lua_setfield(L,-2,"tounicode"); - - /* pdf parameters */ - /* skip the first four for now, that are very much interal */ - /* - if (pdf_font_size(f) != 0) { - lua_pushnumber(L,pdf_font_size(f)); - lua_setfield(L,-2,"pdf_size"); - } - if (pdf_font_num(f) != 0) { - lua_pushnumber(L,pdf_font_num(f)); - lua_setfield(L,-2,"pdf_num"); - } - if (pdf_font_blink(f) != 0) { - lua_pushnumber(L,pdf_font_blink(f)); - lua_setfield(L,-2,"pdf_blink"); - } - if (pdf_font_elink(f) != 0) { - lua_pushnumber(L,pdf_font_elink(f)); - lua_setfield(L,-2,"pdf_elink"); - } - */ - /* the next one is read only */ - if (pdf_font_expand_ratio(f) != 0) { - lua_pushnumber(L,pdf_font_expand_ratio(f)); - lua_setfield(L,-2,"expand_ratio"); - } - if (pdf_font_shrink(f) != 0) { - lua_pushnumber(L,pdf_font_shrink(f)); - lua_setfield(L,-2,"shrink"); - } - if (pdf_font_stretch(f) != 0) { - lua_pushnumber(L,pdf_font_stretch(f)); - lua_setfield(L,-2,"stretch"); - } - if (pdf_font_step(f) != 0) { - lua_pushnumber(L,pdf_font_step(f)); - lua_setfield(L,-2,"step"); - } - if (pdf_font_auto_expand(f) != 0) { - lua_pushboolean(L,pdf_font_auto_expand(f)); - lua_setfield(L,-2,"auto_expand"); - } - if (pdf_font_attr(f) != 0) { - lua_pushstring(L,makecstring(pdf_font_attr(f))); - lua_setfield(L,-2,"attributes"); - } - - /* params */ - write_lua_parameters(L,f); - - /* chars */ - lua_createtable(L,font_tables[f]->charinfo_size,0); /* all characters */ - - if (has_left_boundary(f)) { - co = get_charinfo(f,left_boundarychar); - font_char_to_lua(L,f,co); - lua_setfield(L,-2,"left_boundary"); - } - if (has_right_boundary(f)) { - co = get_charinfo(f,right_boundarychar); - font_char_to_lua(L,f,co); - lua_setfield(L,-2,"right_boundary"); - } - - for (k=font_bc(f);k<=font_ec(f);k++) { - if (char_exists(f,k)) { - lua_pushnumber(L,k); - co = get_charinfo(f,k); - font_char_to_lua(L,f,co); - lua_rawset(L,-3); - } - } - lua_setfield(L,-2,"characters"); - return 1; } -static int -count_hash_items (lua_State *L, int name_index){ - int n = -1; - lua_rawgeti(L,LUA_REGISTRYINDEX,name_index); - lua_rawget(L,-2); - if (!lua_isnil(L,-1)) { - if (lua_istable(L,-1)) { - n = 0; - /* now find the number */ - lua_pushnil(L); /* first key */ - while (lua_next(L, -2) != 0) { - n++; - lua_pop(L,1); - } - } - } - lua_pop(L,1); - return n; +static int count_hash_items(lua_State * L, int name_index) +{ + int n = -1; + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); + lua_rawget(L, -2); + if (!lua_isnil(L, -1)) { + if (lua_istable(L, -1)) { + n = 0; + /* now find the number */ + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + n++; + lua_pop(L, 1); + } + } + } + lua_pop(L, 1); + return n; } #define streq(a,b) (strcmp(a,b)==0) @@ -321,130 +482,130 @@ count_hash_items (lua_State *L, int name_index){ append_packet((l&0xFF000000)>>24); \ append_packet((l&0x00FF0000)>>16); \ append_packet((l&0x0000FF00)>>8); \ - append_packet((l&0x000000FF)); } + append_packet((l&0x000000FF)); } /* */ #define lua_roundnumber(a,b) (int)floor((double)lua_tonumber(L,-1)+0.5) -static int -numeric_field (lua_State *L, char *name, int dflt) { - int i = dflt; - lua_pushstring(L,name); - lua_rawget(L,-2); - if (lua_isnumber(L,-1)) { - i = lua_roundnumber(L,-1); - } - lua_pop(L,1); - return i; +static int numeric_field(lua_State * L, char *name, int dflt) +{ + int i = dflt; + lua_pushstring(L, name); + lua_rawget(L, -2); + if (lua_isnumber(L, -1)) { + i = lua_roundnumber(L, -1); + } + lua_pop(L, 1); + return i; } -static int -n_numeric_field (lua_State *L, int name_index, int dflt) { - register int i = dflt; - lua_rawgeti(L,LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ - lua_rawget(L,-2); - if (lua_type(L,-1)==LUA_TNUMBER) { - i = lua_roundnumber(L,-1); - } - lua_pop(L,1); - return i; +static int n_numeric_field(lua_State * L, int name_index, int dflt) +{ + register int i = dflt; + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + lua_rawget(L, -2); + if (lua_type(L, -1) == LUA_TNUMBER) { + i = lua_roundnumber(L, -1); + } + lua_pop(L, 1); + return i; } -static int -enum_field (lua_State *L, char *name, int dflt, char **values) { - int k; - char *s; - int i = dflt; - lua_pushstring(L,name); - lua_rawget(L,-2); - if (lua_isnumber(L,-1)) { - i = lua_tonumber(L,-1); - } else if (lua_isstring(L,-1)) { - s = (char *)lua_tostring(L,-1); - k = 0; - while (values[k] != NULL) { - if (strcmp(values[k],s) == 0) { - i = k; - break; - } - k++; - } - } - lua_pop(L,1); - return i; +static int enum_field(lua_State * L, char *name, int dflt, char **values) +{ + int k; + char *s; + int i = dflt; + lua_pushstring(L, name); + lua_rawget(L, -2); + if (lua_isnumber(L, -1)) { + i = lua_tonumber(L, -1); + } else if (lua_isstring(L, -1)) { + s = (char *) lua_tostring(L, -1); + k = 0; + while (values[k] != NULL) { + if (strcmp(values[k], s) == 0) { + i = k; + break; + } + k++; + } + } + lua_pop(L, 1); + return i; } -static int -boolean_field (lua_State *L, char *name, int dflt) { - int i = dflt; - lua_pushstring(L,name); - lua_rawget(L,-2); - if (lua_isboolean(L,-1)) { - i = lua_toboolean(L,-1); - } - lua_pop(L,1); - return i; +static int boolean_field(lua_State * L, char *name, int dflt) +{ + int i = dflt; + lua_pushstring(L, name); + lua_rawget(L, -2); + if (lua_isboolean(L, -1)) { + i = lua_toboolean(L, -1); + } + lua_pop(L, 1); + return i; } -static int -n_boolean_field (lua_State *L, int name_index, int dflt) { - int i = dflt; - lua_rawgeti(L,LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ - lua_rawget(L,-2); - if (lua_isboolean(L,-1)) { - i = lua_toboolean(L,-1); - } - lua_pop(L,1); - return i; +static int n_boolean_field(lua_State * L, int name_index, int dflt) +{ + int i = dflt; + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + lua_rawget(L, -2); + if (lua_isboolean(L, -1)) { + i = lua_toboolean(L, -1); + } + lua_pop(L, 1); + return i; } -static char * -string_field (lua_State *L, char *name, char *dflt) { - char *i; - lua_pushstring(L,name); - lua_rawget(L,-2); - if (lua_isstring(L,-1)) { - i = xstrdup(lua_tostring(L,-1)); - } else if (dflt==NULL) { - i = NULL; - } else { - i = xstrdup(dflt); - } - lua_pop(L,1); - return i; +static char *string_field(lua_State * L, char *name, char *dflt) +{ + char *i; + lua_pushstring(L, name); + lua_rawget(L, -2); + if (lua_isstring(L, -1)) { + i = xstrdup(lua_tostring(L, -1)); + } else if (dflt == NULL) { + i = NULL; + } else { + i = xstrdup(dflt); + } + lua_pop(L, 1); + return i; } -static char * -n_string_field (lua_State *L, int name_index, char *dflt) { - char *i; - lua_rawgeti(L,LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ - lua_rawget(L,-2); - if (lua_isstring(L,-1)) { - i = xstrdup(lua_tostring(L,-1)); - } else if (dflt==NULL) { - i = NULL; - } else { - i = xstrdup(dflt); - } - lua_pop(L,1); - return i; +static char *n_string_field(lua_State * L, int name_index, char *dflt) +{ + char *i; + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + lua_rawget(L, -2); + if (lua_isstring(L, -1)) { + i = xstrdup(lua_tostring(L, -1)); + } else if (dflt == NULL) { + i = NULL; + } else { + i = xstrdup(dflt); + } + lua_pop(L, 1); + return i; } -#define init_luaS_index(a) do { \ - lua_pushliteral(L,#a); \ - luaS_##a##_ptr = (char *)lua_tostring(L,-1); \ - luaS_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \ +#define init_luaS_index(a) do { \ + lua_pushliteral(L,#a); \ + luaS_##a##_ptr = (char *)lua_tostring(L,-1); \ + luaS_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \ } while (0) -#define make_luaS_index(a) \ - static int luaS_##a##_index = 0; \ +#define make_luaS_index(a) \ + static int luaS_##a##_index = 0; \ static char * luaS_##a##_ptr = NULL -#define luaS_index(a) luaS_##a##_index +#define luaS_index(a) luaS_##a##_index #define luaS_ptr_eq(a,b) (a==luaS_##b##_ptr) @@ -452,13 +613,15 @@ make_luaS_index(width); make_luaS_index(height); make_luaS_index(depth); make_luaS_index(italic); +make_luaS_index(top_accent); +make_luaS_index(bot_accent); make_luaS_index(index); make_luaS_index(left_protruding); make_luaS_index(right_protruding); make_luaS_index(expansion_factor); -make_luaS_index(top); -make_luaS_index(bot); -make_luaS_index(rep); +make_luaS_index(top); +make_luaS_index(bot); +make_luaS_index(rep); make_luaS_index(mid); make_luaS_index(next); make_luaS_index(used); @@ -475,6 +638,7 @@ make_luaS_index(right); make_luaS_index(node); make_luaS_index(down); make_luaS_index(special); +make_luaS_index(image); make_luaS_index(slant); make_luaS_index(space); make_luaS_index(space_stretch); @@ -487,455 +651,634 @@ make_luaS_index(right_boundary); make_luaS_index(kerns); make_luaS_index(ligatures); make_luaS_index(fonts); - -void init_font_string_pointers (lua_State *L) { - init_luaS_index(width); - init_luaS_index(height); - init_luaS_index(depth); - init_luaS_index(italic); - init_luaS_index(index); - init_luaS_index(left_protruding); - init_luaS_index(right_protruding); - init_luaS_index(expansion_factor); - init_luaS_index(top); - init_luaS_index(bot); - init_luaS_index(rep); - init_luaS_index(mid); - init_luaS_index(next); - init_luaS_index(used); - init_luaS_index(name); - init_luaS_index(tounicode); - init_luaS_index(font); - init_luaS_index(char); - init_luaS_index(slot); - init_luaS_index(comment); - init_luaS_index(push); - init_luaS_index(pop); - init_luaS_index(rule); - init_luaS_index(right); - init_luaS_index(node); - init_luaS_index(down); - init_luaS_index(special); - - init_luaS_index(slant); - init_luaS_index(space); - init_luaS_index(space_stretch); - init_luaS_index(space_shrink); - init_luaS_index(x_height); - init_luaS_index(quad); - init_luaS_index(extra_space); - - init_luaS_index(left_boundary); - init_luaS_index(right_boundary); - init_luaS_index(kerns); - init_luaS_index(ligatures); - init_luaS_index(fonts); +make_luaS_index(extender); +make_luaS_index(start); +make_luaS_index(end); +make_luaS_index(advance); +make_luaS_index(glyph); + +void init_font_string_pointers(lua_State * L) +{ + init_luaS_index(width); + init_luaS_index(height); + init_luaS_index(depth); + init_luaS_index(italic); + init_luaS_index(top_accent); + init_luaS_index(bot_accent); + init_luaS_index(index); + init_luaS_index(left_protruding); + init_luaS_index(right_protruding); + init_luaS_index(expansion_factor); + init_luaS_index(top); + init_luaS_index(bot); + init_luaS_index(rep); + init_luaS_index(mid); + init_luaS_index(next); + init_luaS_index(used); + init_luaS_index(name); + init_luaS_index(tounicode); + init_luaS_index(font); + init_luaS_index(char); + init_luaS_index(slot); + init_luaS_index(comment); + init_luaS_index(push); + init_luaS_index(pop); + init_luaS_index(rule); + init_luaS_index(right); + init_luaS_index(node); + init_luaS_index(down); + init_luaS_index(special); + init_luaS_index(image); + + init_luaS_index(slant); + init_luaS_index(space); + init_luaS_index(space_stretch); + init_luaS_index(space_shrink); + init_luaS_index(x_height); + init_luaS_index(quad); + init_luaS_index(extra_space); + + init_luaS_index(left_boundary); + init_luaS_index(right_boundary); + init_luaS_index(kerns); + init_luaS_index(ligatures); + init_luaS_index(fonts); + + init_luaS_index(extender); + init_luaS_index(start); + init_luaS_index(end); + init_luaS_index(advance); + init_luaS_index(glyph); } -static int -count_char_packet_bytes (lua_State *L) { - register int i; - register int l = 0; - int ff = 0; - for (i=1;i<=lua_objlen(L,-1);i++) { - lua_rawgeti(L,-1,i); - if (lua_istable(L,-1)) { - lua_rawgeti(L,-1,1); - if (lua_isstring(L,-1)) { - char *s = (char *)lua_tostring(L,-1); - if (luaS_ptr_eq(s,font)) { l+= 5; ff =1; } - else if (luaS_ptr_eq(s,char)) { if (ff==0) { l+=5; } l += 5; ff = 1; } - else if (luaS_ptr_eq(s,slot)) { l += 10; ff = 1;} - else if (luaS_ptr_eq(s,comment)) { ; } - else if (luaS_ptr_eq(s,push) || - luaS_ptr_eq(s,pop)) { l++; } - else if (luaS_ptr_eq(s,rule)) { l+=9; } - else if (luaS_ptr_eq(s,right) || - luaS_ptr_eq(s,node) || - luaS_ptr_eq(s,down)) { l+=5; } - else if (luaS_ptr_eq(s,special)) { - size_t len; - lua_rawgeti(L,-2,2); - (void)lua_tolstring(L,-1,&len); - lua_pop(L,1); - if (len>0) { l = l + 5 + len; } +static int count_char_packet_bytes(lua_State * L) +{ + register int i; + register int l = 0; + int ff = 0; + for (i = 1; i <= (int) lua_objlen(L, -1); i++) { + lua_rawgeti(L, -1, i); + if (lua_istable(L, -1)) { + lua_rawgeti(L, -1, 1); + if (lua_isstring(L, -1)) { + char *s = (char *) lua_tostring(L, -1); + if (luaS_ptr_eq(s, font)) { + l += 5; + ff = 1; + } else if (luaS_ptr_eq(s, char)) { + if (ff == 0) { + l += 5; + } + l += 5; + ff = 1; + } else if (luaS_ptr_eq(s, slot)) { + l += 10; + ff = 1; + } else if (luaS_ptr_eq(s, comment)) {; + } else if (luaS_ptr_eq(s, push) || luaS_ptr_eq(s, pop)) { + l++; + } else if (luaS_ptr_eq(s, rule)) { + l += 9; + } else if (luaS_ptr_eq(s, right) || + luaS_ptr_eq(s, node) || luaS_ptr_eq(s, down)) { + l += 5; + } else if (luaS_ptr_eq(s, special)) { + size_t len; + lua_rawgeti(L, -2, 2); + (void) lua_tolstring(L, -1, &len); + lua_pop(L, 1); + if (len > 0) { + l = l + 5 + len; + } + } else if (luaS_ptr_eq(s, image)) { + l += 5; + } else { + fprintf(stdout, "unknown packet command %s!\n", s); + } + } else { + fprintf(stdout, "no packet command!\n"); + } + lua_pop(L, 1); /* command name */ } - else { fprintf(stdout,"unknown packet command %s!\n",s); } - } else { - fprintf(stdout,"no packet command!\n"); - } - lua_pop(L,1); /* command name */ - } - lua_pop(L,1); /* item */ - } - return l; + lua_pop(L, 1); /* item */ + } + return l; } -scaled -sp_to_dvi (halfword sp, halfword atsize) { - double result, mult; - mult = (double)(atsize>>16); - result = (sp << 4); - return floor (result/mult ); +scaled sp_to_dvi(halfword sp, halfword atsize) +{ + double result, mult; + mult = (double) (atsize / 65536.0); + result = (double) (sp * 16.0); + return floor(result / mult); } static void -read_char_packets (lua_State *L, integer *l_fonts, charinfo *co, int atsize) { - int i, n, m; - size_t l; - int cmd; - char *s; - real_eight_bits *cpackets; - int ff = 0; - int np = 0; - int max_f = 0; - int pc = count_char_packet_bytes (L); - if (pc<=0) - return; - assert(l_fonts != NULL); - assert(l_fonts[1] != 0); - while (l_fonts[(max_f+1)]!=0) - max_f++; - - cpackets = xmalloc(pc+1); - for (i=1;i<=lua_objlen(L,-1);i++) { - lua_rawgeti(L,-1,i); - if (lua_istable(L,-1)) { - /* fetch the command code */ - lua_rawgeti(L,-1,1); - if (lua_isstring(L,-1)) { - s = (char *)lua_tostring(L,-1); - cmd = 0; - if (luaS_ptr_eq(s,font)) { - cmd = packet_font_code; - } else if (luaS_ptr_eq(s,char)) { - cmd = packet_char_code; - if (ff==0) { - append_packet(packet_font_code); - ff = l_fonts[1]; - do_store_four(ff); - } - } else if (luaS_ptr_eq(s,slot)) { - cmd = packet_nop_code; - lua_rawgeti(L,-2,2); n = lua_tointeger(L,-1); - ff = (n>max_f ? l_fonts[1] : l_fonts[n]); - lua_rawgeti(L,-3,3); n = lua_tointeger(L,-1); - lua_pop(L,2); - append_packet(packet_font_code); - do_store_four(ff); - append_packet(packet_char_code); - do_store_four(n); - } - else if (luaS_ptr_eq(s,comment)) { cmd = packet_nop_code; } - else if (luaS_ptr_eq(s,node)) { cmd = packet_node_code; } - else if (luaS_ptr_eq(s,push)) { cmd = packet_push_code; } - else if (luaS_ptr_eq(s,pop)) { cmd = packet_pop_code; } - else if (luaS_ptr_eq(s,rule)) { cmd = packet_rule_code; } - else if (luaS_ptr_eq(s,right)) { cmd = packet_right_code; } - else if (luaS_ptr_eq(s,down)) { cmd = packet_down_code; } - else if (luaS_ptr_eq(s,special)) { cmd = packet_special_code; } - - switch(cmd) { - case packet_push_code: - case packet_pop_code: - append_packet(cmd); - break; - case packet_font_code: - append_packet(cmd); - lua_rawgeti(L,-2,2); - n = lua_tointeger(L,-1); - ff = (n>max_f ? l_fonts[1] : l_fonts[n]); - do_store_four(ff); - lua_pop(L,1); - break; - case packet_node_code: - append_packet(cmd); - lua_rawgeti(L,-2,2); - n = copy_node_list(nodelist_from_lua(L)); - do_store_four(n); - lua_pop(L,1); - break; - case packet_char_code: - append_packet(cmd); - lua_rawgeti(L,-2,2); - n = lua_tointeger(L,-1); - do_store_four(n); - lua_pop(L,1); - break; - case packet_right_code: - case packet_down_code: - append_packet(cmd); - lua_rawgeti(L,-2,2); - n = lua_tointeger(L,-1); - do_store_four(sp_to_dvi(n,atsize)); - lua_pop(L,1); - break; - case packet_rule_code: - append_packet(cmd); - lua_rawgeti(L,-2,2); - n = lua_tointeger(L,-1); - do_store_four(sp_to_dvi(n,atsize)); - lua_rawgeti(L,-3,3); - n = lua_tointeger(L,-1); - do_store_four(sp_to_dvi(n,atsize)); - lua_pop(L,2); - break; - case packet_special_code: - append_packet(cmd); - lua_rawgeti(L,-2,2); - s = (char *)lua_tolstring(L,-1,&l); - if (l>0) { - do_store_four(l); - m = (int)l; - while(m>0) { - n = *s++; - m--; - append_packet(n); +read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize) +{ + int i, n, m; + size_t l; + int cmd; + char *s; + real_eight_bits *cpackets; + int ff = 0; + int np = 0; + int max_f = 0; + int pc = count_char_packet_bytes(L); + if (pc <= 0) + return; + assert(l_fonts != NULL); + assert(l_fonts[1] != 0); + while (l_fonts[(max_f + 1)] != 0) + max_f++; + + cpackets = xmalloc(pc + 1); + for (i = 1; i <= (int) lua_objlen(L, -1); i++) { + lua_rawgeti(L, -1, i); + if (lua_istable(L, -1)) { + /* fetch the command code */ + lua_rawgeti(L, -1, 1); + if (lua_isstring(L, -1)) { + s = (char *) lua_tostring(L, -1); + cmd = 0; + if (luaS_ptr_eq(s, font)) { + cmd = packet_font_code; + } else if (luaS_ptr_eq(s, char)) { + cmd = packet_char_code; + if (ff == 0) { + append_packet(packet_font_code); + ff = l_fonts[1]; + do_store_four(ff); + } + } else if (luaS_ptr_eq(s, slot)) { + cmd = packet_nop_code; + lua_rawgeti(L, -2, 2); + n = lua_tointeger(L, -1); + ff = (n > max_f ? l_fonts[1] : l_fonts[n]); + lua_rawgeti(L, -3, 3); + n = lua_tointeger(L, -1); + lua_pop(L, 2); + append_packet(packet_font_code); + do_store_four(ff); + append_packet(packet_char_code); + do_store_four(n); + } else if (luaS_ptr_eq(s, comment)) { + cmd = packet_nop_code; + } else if (luaS_ptr_eq(s, node)) { + cmd = packet_node_code; + } else if (luaS_ptr_eq(s, push)) { + cmd = packet_push_code; + } else if (luaS_ptr_eq(s, pop)) { + cmd = packet_pop_code; + } else if (luaS_ptr_eq(s, rule)) { + cmd = packet_rule_code; + } else if (luaS_ptr_eq(s, right)) { + cmd = packet_right_code; + } else if (luaS_ptr_eq(s, down)) { + cmd = packet_down_code; + } else if (luaS_ptr_eq(s, special)) { + cmd = packet_special_code; + } else if (luaS_ptr_eq(s, image)) { + cmd = packet_image_code; + } + + switch (cmd) { + case packet_push_code: + case packet_pop_code: + append_packet(cmd); + break; + case packet_font_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = lua_tointeger(L, -1); + ff = (n > max_f ? l_fonts[1] : l_fonts[n]); + do_store_four(ff); + lua_pop(L, 1); + break; + case packet_node_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = copy_node_list(nodelist_from_lua(L)); + do_store_four(n); + lua_pop(L, 1); + break; + case packet_char_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = lua_tointeger(L, -1); + do_store_four(n); + lua_pop(L, 1); + break; + case packet_right_code: + case packet_down_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = lua_tointeger(L, -1); + do_store_four(sp_to_dvi(n, atsize)); + lua_pop(L, 1); + break; + case packet_rule_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = lua_tointeger(L, -1); + do_store_four(sp_to_dvi(n, atsize)); + lua_rawgeti(L, -3, 3); + n = lua_tointeger(L, -1); + do_store_four(sp_to_dvi(n, atsize)); + lua_pop(L, 2); + break; + case packet_special_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + s = (char *) lua_tolstring(L, -1, &l); + if (l > 0) { + do_store_four(l); + m = (int) l; + while (m > 0) { + n = *s++; + m--; + append_packet(n); + } + } + lua_pop(L, 1); + break; + case packet_image_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); /* img/imgtable? ... */ + if (lua_istable(L, -1)) { /* imgtable ... */ + lua_getglobal(L, "img"); /* imglib imgtable ... */ + lua_pushstring(L, "new"); /* `new' imglib imgtable ... */ + lua_gettable(L, -2); /* f imglib imgtable ... */ + lua_insert(L, -3); /* imglib imgtable f ... */ + lua_pop(L, 1); /* imgtable f ... */ + lua_call(L, 1, 1); + } /* img ... */ + luaL_checkudata(L, -1, TYPE_IMG); /* img ... --- just typecheck */ + n = luaL_ref(L, LUA_GLOBALSINDEX); /* ... */ + do_store_four(n); + break; + case packet_nop_code: + break; + default: + fprintf(stdout, + "Unknown char packet code %s (char %d in font %s)\n", + s, (int) c, font_name(f)); + } } - } - lua_pop(L,1); - break; - case packet_nop_code: - break; - default: - fprintf(stdout,"Unknown char packet code %s (char %d in font %s)\n",s,(int)c,font_name(f)); + lua_pop(L, 1); /* command code */ + } else { + fprintf(stdout, + "Found a `commands' item that is not a table (char %d in font %s)\n", + (int) c, font_name(f)); } - } - lua_pop(L,1); /* command code */ - } else { - fprintf(stdout,"Found a `commands' item that is not a table (char %d in font %s)\n",(int)c,font_name(f)); + lua_pop(L, 1); /* command table */ } - lua_pop(L,1); /* command table */ - } - append_packet(packet_end_code); - set_charinfo_packets(co,cpackets); - return; + append_packet(packet_end_code); + set_charinfo_packets(co, cpackets); + return; } -static void -read_lua_cidinfo (lua_State *L, int f) { - int i; - char *s; - lua_getfield(L,-1,"cidinfo"); - if (lua_istable(L,-1)) { - i = numeric_field(L,"version",0); - set_font_cidversion(f,i); - i = numeric_field(L,"supplement",0); - set_font_cidsupplement(f,i); - s = string_field(L,"registry","Adobe"); /* Adobe-Identity-0 */ - set_font_cidregistry(f,s); - s = string_field(L,"ordering","Identity"); - set_font_cidordering(f,s); - } - lua_pop(L,1); +static void read_lua_cidinfo(lua_State * L, int f) +{ + int i; + char *s; + lua_getfield(L, -1, "cidinfo"); + if (lua_istable(L, -1)) { + i = numeric_field(L, "version", 0); + set_font_cidversion(f, i); + i = numeric_field(L, "supplement", 0); + set_font_cidsupplement(f, i); + s = string_field(L, "registry", "Adobe"); /* Adobe-Identity-0 */ + set_font_cidregistry(f, s); + s = string_field(L, "ordering", "Identity"); + set_font_cidordering(f, s); + } + lua_pop(L, 1); } -static void -read_lua_parameters (lua_State *L, int f) { - int i, n; - char *s; - lua_getfield(L,-1,"parameters"); - if (lua_istable(L,-1)) { - /* the number of parameters is the max(IntegerKeys(L)),7) */ - n = 7; - lua_pushnil(L); /* first key */ - while (lua_next(L, -2) != 0) { - if (lua_isnumber(L,-2)) { - i = lua_tonumber(L,-2); - if (i > n) n = i; - } - lua_pop(L,1); /* pop value */ - } - if (n>7) set_font_params(f,n); - /* sometimes it is handy to have all integer keys */ - for (i=1;i<=7;i++) { - lua_rawgeti(L,-1,i); - if (lua_isnumber(L,-1)) { - n = lua_roundnumber(L,-1); - set_font_param(f,i, n); - } - lua_pop(L,1); - } - lua_pushnil(L); /* first key */ - while (lua_next(L, -2) != 0) { - if (lua_isnumber(L,-2)) { - i = lua_tointeger(L,-2); - if (i>=8) { - n = (lua_isnumber(L,-1) ? lua_roundnumber(L,-1) : 0); - set_font_param(f,i, n); +static void read_lua_parameters(lua_State * L, int f) +{ + int i, n; + char *s; + lua_getfield(L, -1, "parameters"); + if (lua_istable(L, -1)) { + /* the number of parameters is the max(IntegerKeys(L)),7) */ + n = 7; + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + if (lua_isnumber(L, -2)) { + i = lua_tonumber(L, -2); + if (i > n) + n = i; + } + lua_pop(L, 1); /* pop value */ } - } else if (lua_isstring(L,-2)) { - s = (char *)lua_tostring(L,-2); - n = (lua_isnumber(L,-1) ? lua_roundnumber(L,-1) : 0); - if (luaS_ptr_eq(s,slant)) { set_font_param(f,slant_code,n); } - else if (luaS_ptr_eq(s,space)) { set_font_param(f,space_code,n); } - else if (luaS_ptr_eq(s,space_stretch)) { set_font_param(f,space_stretch_code,n); } - else if (luaS_ptr_eq(s,space_shrink)) { set_font_param(f,space_shrink_code,n); } - else if (luaS_ptr_eq(s,x_height)) { set_font_param(f,x_height_code,n); } - else if (luaS_ptr_eq(s,quad)) { set_font_param(f,quad_code,n); } - else if (luaS_ptr_eq(s,extra_space)) { set_font_param(f,extra_space_code,n); } - } - lua_pop(L,1); - } - } - lua_pop(L,1); + if (n > 7) + set_font_params(f, n); + /* sometimes it is handy to have all integer keys */ + for (i = 1; i <= 7; i++) { + lua_rawgeti(L, -1, i); + if (lua_isnumber(L, -1)) { + n = lua_roundnumber(L, -1); + set_font_param(f, i, n); + } + lua_pop(L, 1); + } + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + if (lua_isnumber(L, -2)) { + i = lua_tointeger(L, -2); + if (i >= 8) { + n = (lua_isnumber(L, -1) ? lua_roundnumber(L, -1) : 0); + set_font_param(f, i, n); + } + } else if (lua_isstring(L, -2)) { + s = (char *) lua_tostring(L, -2); + n = (lua_isnumber(L, -1) ? lua_roundnumber(L, -1) : 0); + if (luaS_ptr_eq(s, slant)) { + set_font_param(f, slant_code, n); + } else if (luaS_ptr_eq(s, space)) { + set_font_param(f, space_code, n); + } else if (luaS_ptr_eq(s, space_stretch)) { + set_font_param(f, space_stretch_code, n); + } else if (luaS_ptr_eq(s, space_shrink)) { + set_font_param(f, space_shrink_code, n); + } else if (luaS_ptr_eq(s, x_height)) { + set_font_param(f, x_height_code, n); + } else if (luaS_ptr_eq(s, quad)) { + set_font_param(f, quad_code, n); + } else if (luaS_ptr_eq(s, extra_space)) { + set_font_param(f, extra_space_code, n); + } + } + lua_pop(L, 1); + } + } + lua_pop(L, 1); } - -void -font_char_from_lua (lua_State *L, internal_font_number f, integer i, integer *l_fonts) { - int k,r,t; - charinfo *co; - kerninfo *ckerns; - liginfo *cligs; - scaled j; - char *s; - int nl = 0; /* number of ligature table items */ - int nk = 0; /* number of kern table items */ - int ctr = 0; - int atsize = font_size(f); - if (lua_istable(L,-1)) { - co = get_charinfo(f,i); - set_charinfo_tag (co,0); - j = n_numeric_field(L,luaS_width_index,0); set_charinfo_width (co,j); - j = n_numeric_field(L,luaS_height_index,0); set_charinfo_height (co,j); - j = n_numeric_field(L,luaS_depth_index,0); set_charinfo_depth (co,j); - j = n_numeric_field(L,luaS_italic_index,0); set_charinfo_italic (co,j); - j = n_numeric_field(L,luaS_index_index,0); set_charinfo_index(co,j); - j = n_numeric_field(L,luaS_expansion_factor_index,0); set_charinfo_ef(co,j); - j = n_numeric_field(L,luaS_left_protruding_index,0); set_charinfo_lp(co,j); - j = n_numeric_field(L,luaS_right_protruding_index,0); set_charinfo_rp(co,j); - k = n_boolean_field(L,luaS_used_index,0); set_charinfo_used(co,k); - s = n_string_field (L,luaS_name_index,NULL); set_charinfo_name(co,s); - s = n_string_field (L,luaS_tounicode_index,NULL); set_charinfo_tounicode(co,s); - k = n_numeric_field(L,luaS_next_index,-1); - if (k>=0) { - set_charinfo_tag (co,list_tag); - set_charinfo_remainder (co,k); - } - lua_getfield(L,-1,"extensible"); - if (lua_istable(L,-1)){ - int top, bot,mid, rep; - top = n_numeric_field(L,luaS_top_index,0); - bot = n_numeric_field(L,luaS_bot_index,0); - mid = n_numeric_field(L,luaS_mid_index,0); - rep = n_numeric_field(L,luaS_rep_index,0); - if (top != 0 || bot != 0 || mid != 0 || rep != 0) { - set_charinfo_tag (co,ext_tag); - set_charinfo_extensible (co,top,bot,mid,rep); - } else { - pdftex_warn("lua-loaded font %s char [%d] has an invalid extensible field!",font_name(f),(int)i); - } - } - lua_pop(L,1); - - nk = count_hash_items(L,luaS_index(kerns)); - if (nk>0) { - ckerns = xcalloc((nk+1),sizeof(kerninfo)); - lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(kerns)); - lua_rawget(L,-2); - if (lua_istable(L,-1)) { /* there are kerns */ - ctr = 0; + +static void read_lua_math_parameters(lua_State * L, int f) +{ + int i = 0, n = 0; + lua_getfield(L, -1, "MathConstants"); + if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2) != 0) { - k = non_boundarychar; - if (lua_isnumber(L,-2)) { - k = lua_tonumber(L,-2); /* adjacent char */ - if (k<0) - k = non_boundarychar; - } else if (lua_isstring(L,-2)) { - s = (char *)lua_tostring(L,-2); - if (luaS_ptr_eq(s,right_boundary)) { - k = right_boundarychar; - if (!has_right_boundary(f)) - set_right_boundary(f,get_charinfo(f,right_boundarychar)); + if (lua_isnumber(L, -2)) { + i = lua_tonumber(L, -2); + } else if (lua_isstring(L, -2)) { + i = luaL_checkoption(L, -2, NULL, MATH_param_names); + } + n = lua_tonumber(L, -1); + if (i != 0) { + set_font_math_param(f, i, n); } - } - j = lua_roundnumber(L,-1); /* movement */ - if (k!=non_boundarychar) { - set_kern_item(ckerns[ctr],k,j); - ctr++; - } else { - pdftex_warn("lua-loaded font %s char [%d] has an invalid kern field!",font_name(f),(int)i); - } - lua_pop(L,1); + lua_pop(L, 1); /* pop value */ } - /* guard against empty tables */ - if (ctr>0) { - set_kern_item(ckerns[ctr],end_kern,0); - set_charinfo_kerns(co,ckerns); - } else { - pdftex_warn("lua-loaded font %s char [%d] has an invalid kerns field!",font_name(f),(int)i); + } + lua_pop(L, 1); +} + + +void +font_char_from_lua(lua_State * L, internal_font_number f, integer i, + integer * l_fonts) +{ + int k, r, t; + charinfo *co; + kerninfo *ckerns; + liginfo *cligs; + scaled j; + char *s; + int nl = 0; /* number of ligature table items */ + int nk = 0; /* number of kern table items */ + int ctr = 0; + int atsize = font_size(f); + if (lua_istable(L, -1)) { + co = get_charinfo(f, i); + set_charinfo_tag(co, 0); + j = n_numeric_field(L, luaS_width_index, 0); + set_charinfo_width(co, j); + j = n_numeric_field(L, luaS_height_index, 0); + set_charinfo_height(co, j); + j = n_numeric_field(L, luaS_depth_index, 0); + set_charinfo_depth(co, j); + j = n_numeric_field(L, luaS_italic_index, 0); + set_charinfo_italic(co, j); + j = n_numeric_field(L, luaS_top_accent_index, 0); + set_charinfo_top_accent(co, j); + j = n_numeric_field(L, luaS_bot_accent_index, 0); + set_charinfo_bot_accent(co, j); + j = n_numeric_field(L, luaS_index_index, 0); + set_charinfo_index(co, j); + j = n_numeric_field(L, luaS_expansion_factor_index, 0); + set_charinfo_ef(co, j); + j = n_numeric_field(L, luaS_left_protruding_index, 0); + set_charinfo_lp(co, j); + j = n_numeric_field(L, luaS_right_protruding_index, 0); + set_charinfo_rp(co, j); + k = n_boolean_field(L, luaS_used_index, 0); + set_charinfo_used(co, k); + s = n_string_field(L, luaS_name_index, NULL); + set_charinfo_name(co, s); + s = n_string_field(L, luaS_tounicode_index, NULL); + set_charinfo_tounicode(co, s); + k = n_numeric_field(L, luaS_next_index, -1); + if (k >= 0) { + set_charinfo_tag(co, list_tag); + set_charinfo_remainder(co, k); } - } - lua_pop(L,1); - } - - /* packet commands */ - lua_getfield(L,-1,"commands"); - if (lua_istable(L,-1)){ - lua_pushnil(L); /* first key */ - if (lua_next(L, -2) != 0) { - lua_pop(L,2); - read_char_packets(L,(integer *)l_fonts,co,atsize); - } - } - lua_pop(L,1); - - /* ligatures */ - nl = count_hash_items(L,luaS_index(ligatures)); - - if (nl>0) { - cligs = xcalloc((nl+1),sizeof(liginfo)); - lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(ligatures)); - lua_rawget(L,-2); - if (lua_istable(L,-1)){/* do ligs */ - ctr = 0; - lua_pushnil(L); - while (lua_next(L, -2) != 0) { - k = non_boundarychar; - if (lua_isnumber(L,-2)) { - k = lua_tonumber(L,-2); /* adjacent char */ - if (k<0) { - k = non_boundarychar; + lua_getfield(L, -1, "extensible"); + if (lua_istable(L, -1)) { + int top, bot, mid, rep; + top = n_numeric_field(L, luaS_top_index, 0); + bot = n_numeric_field(L, luaS_bot_index, 0); + mid = n_numeric_field(L, luaS_mid_index, 0); + rep = n_numeric_field(L, luaS_rep_index, 0); + if (top != 0 || bot != 0 || mid != 0 || rep != 0) { + set_charinfo_tag(co, ext_tag); + set_charinfo_extensible(co, top, bot, mid, rep); + } else { + pdftex_warn + ("lua-loaded font %s char [U+%X] has an invalid extensible field!", + font_name(f), (int) i); } - } else if (lua_isstring(L,-2)) { - s = (char *)lua_tostring(L,-2); - if (luaS_ptr_eq(s,right_boundary)) { - k = right_boundarychar; - if (!has_right_boundary(f)) - set_right_boundary(f,get_charinfo(f,right_boundarychar)); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "horiz_variants"); + if (lua_istable(L, -1)) { + int glyph, startconnect, endconnect, advance, extender; + extinfo *h; + set_charinfo_tag(co, ext_tag); + set_charinfo_hor_variants(co, NULL); + for (k = 1;; k++) { + lua_rawgeti(L, -1, k); + if (lua_istable(L, -1)) { + glyph = n_numeric_field(L, luaS_glyph_index, 0); + extender = n_numeric_field(L, luaS_extender_index, 0); + startconnect = n_numeric_field(L, luaS_start_index, 0); + endconnect = n_numeric_field(L, luaS_end_index, 0); + advance = n_numeric_field(L, luaS_advance_index, 0); + h = new_variant(glyph, startconnect, endconnect, advance, + extender); + add_charinfo_hor_variant(co, h); + lua_pop(L, 1); + } else { + lua_pop(L, 1); + break; + } } - } - r = -1; - if (lua_istable(L,-1)) { - r = n_numeric_field(L,luaS_char_index,-1); /* ligature */ - } - if (r != -1 && k != non_boundarychar) { - t = enum_field(L,"type",0,ligature_type_strings); - set_ligature_item(cligs[ctr],(t*2)+1,k,r); - ctr++; - } else { - pdftex_warn("lua-loaded font %s char [%d] has an invalid ligature field!",font_name(f),(int)i); - } - lua_pop(L,1); /* iterator value */ - } - /* guard against empty tables */ - if (ctr>0) { - set_ligature_item(cligs[ctr],0,end_ligature,0); - set_charinfo_ligatures(co,cligs); - } else { - pdftex_warn("lua-loaded font %s char [%d] has an invalid ligatures field!",font_name(f),(int)i); } - } - lua_pop(L,1); /* ligatures table */ + lua_pop(L, 1); + + + lua_getfield(L, -1, "vert_variants"); + if (lua_istable(L, -1)) { + int glyph, startconnect, endconnect, advance, extender; + extinfo *h; + set_charinfo_tag(co, ext_tag); + set_charinfo_vert_variants(co, NULL); + for (k = 1;; k++) { + lua_rawgeti(L, -1, k); + if (lua_istable(L, -1)) { + glyph = n_numeric_field(L, luaS_glyph_index, 0); + extender = n_numeric_field(L, luaS_extender_index, 0); + startconnect = n_numeric_field(L, luaS_start_index, 0); + endconnect = n_numeric_field(L, luaS_end_index, 0); + advance = n_numeric_field(L, luaS_advance_index, 0); + h = new_variant(glyph, startconnect, endconnect, advance, + extender); + add_charinfo_vert_variant(co, h); + lua_pop(L, 1); + } else { + lua_pop(L, 1); + break; + } + } + } + lua_pop(L, 1); + + nk = count_hash_items(L, luaS_index(kerns)); + if (nk > 0) { + ckerns = xcalloc((nk + 1), sizeof(kerninfo)); + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(kerns)); + lua_rawget(L, -2); + if (lua_istable(L, -1)) { /* there are kerns */ + ctr = 0; + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + k = non_boundarychar; + if (lua_isnumber(L, -2)) { + k = lua_tonumber(L, -2); /* adjacent char */ + if (k < 0) + k = non_boundarychar; + } else if (lua_isstring(L, -2)) { + s = (char *) lua_tostring(L, -2); + if (luaS_ptr_eq(s, right_boundary)) { + k = right_boundarychar; + if (!has_right_boundary(f)) + set_right_boundary(f, + get_charinfo(f, + right_boundarychar)); + } + } + j = lua_roundnumber(L, -1); /* movement */ + if (k != non_boundarychar) { + set_kern_item(ckerns[ctr], k, j); + ctr++; + } else { + pdftex_warn + ("lua-loaded font %s char [U+%X] has an invalid kern field!", + font_name(f), (int) i); + } + lua_pop(L, 1); + } + /* guard against empty tables */ + if (ctr > 0) { + set_kern_item(ckerns[ctr], end_kern, 0); + set_charinfo_kerns(co, ckerns); + } else { + pdftex_warn + ("lua-loaded font %s char [U+%X] has an invalid kerns field!", + font_name(f), (int) i); + } + } + lua_pop(L, 1); + } + + /* packet commands */ + lua_getfield(L, -1, "commands"); + if (lua_istable(L, -1)) { + lua_pushnil(L); /* first key */ + if (lua_next(L, -2) != 0) { + lua_pop(L, 2); + read_char_packets(L, (integer *) l_fonts, co, atsize); + } + } + lua_pop(L, 1); + + /* ligatures */ + nl = count_hash_items(L, luaS_index(ligatures)); + + if (nl > 0) { + cligs = xcalloc((nl + 1), sizeof(liginfo)); + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(ligatures)); + lua_rawget(L, -2); + if (lua_istable(L, -1)) { /* do ligs */ + ctr = 0; + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + k = non_boundarychar; + if (lua_isnumber(L, -2)) { + k = lua_tonumber(L, -2); /* adjacent char */ + if (k < 0) { + k = non_boundarychar; + } + } else if (lua_isstring(L, -2)) { + s = (char *) lua_tostring(L, -2); + if (luaS_ptr_eq(s, right_boundary)) { + k = right_boundarychar; + if (!has_right_boundary(f)) + set_right_boundary(f, + get_charinfo(f, + right_boundarychar)); + } + } + r = -1; + if (lua_istable(L, -1)) { + r = n_numeric_field(L, luaS_char_index, -1); /* ligature */ + } + if (r != -1 && k != non_boundarychar) { + t = enum_field(L, "type", 0, ligature_type_strings); + set_ligature_item(cligs[ctr], (t * 2) + 1, k, r); + ctr++; + } else { + pdftex_warn + ("lua-loaded font %s char [U+%X] has an invalid ligature field!", + font_name(f), (int) i); + } + lua_pop(L, 1); /* iterator value */ + } + /* guard against empty tables */ + if (ctr > 0) { + set_ligature_item(cligs[ctr], 0, end_ligature, 0); + set_charinfo_ligatures(co, cligs); + } else { + pdftex_warn + ("lua-loaded font %s char [U+%X] has an invalid ligatures field!", + font_name(f), (int) i); + } + } + lua_pop(L, 1); /* ligatures table */ + } } - } } @@ -943,203 +1286,247 @@ font_char_from_lua (lua_State *L, internal_font_number f, integer i, integer *l_ /* The caller has to fix the state of the lua stack when there is an error! */ -int -font_from_lua (lua_State *L, int f) { - int i,n,r,t; - int s_top; /* lua stack top */ - int bc; /* first char index */ - int ec; /* last char index */ - char *s; - integer *l_fonts = NULL; - /* the table is at stack index -1 */ - - if (luaS_width_index==0) - init_font_string_pointers(L); - - s = string_field(L,"area",""); set_font_area(f,s); - s = string_field(L,"filename",NULL); set_font_filename(f,s); - s = string_field(L,"encodingname",NULL); set_font_encodingname(f,s); - - s = string_field(L,"name",NULL); set_font_name(f,s); - s = string_field(L,"fullname",font_name(f)); set_font_fullname(f,s); - - if (s==NULL) { - pdftex_fail("lua-loaded font [%d] has no name!",f); - return false; - } - - i = numeric_field(L,"designsize",655360); set_font_dsize(f,i); - i = numeric_field(L,"size",font_dsize(f)); set_font_size(f,i); - i = numeric_field(L,"checksum",0); set_font_checksum(f,i); - i = numeric_field(L,"direction",0); set_font_natural_dir(f,i); - i = numeric_field(L,"encodingbytes",0); set_font_encodingbytes(f,i); - i = numeric_field(L,"tounicode",0); set_font_tounicode(f,i); - - i = numeric_field(L,"extend",0); - if (i<-2000) i = -2000; if (i>2000) i = 2000; if (i==1000) i = 0; - set_font_extend(f,i); - i = numeric_field(L,"slant",0); - if (i<-1000) i = -1000; if (i>1000) i = 1000; - set_font_slant(f,i); - - i = numeric_field(L,"hyphenchar",get_default_hyphen_char()); set_hyphen_char(f,i); - i = numeric_field(L,"skewchar",get_default_skew_char()); set_skew_char(f,i); - i = boolean_field(L,"used",0); set_font_used(f,i); - - s = string_field (L,"attributes",NULL); - if (s!=NULL && strlen(s)>0) { - i = maketexstring(s); - set_pdf_font_attr(f,i); - } - - i = enum_field(L,"type", unknown_font_type,font_type_strings); set_font_type(f,i); - i = enum_field(L,"format", unknown_format, font_format_strings); set_font_format(f,i); - i = enum_field(L,"embedding",unknown_embedding,font_embedding_strings); set_font_embedding(f,i); - if (font_encodingbytes(f)==0 && - (font_format(f)==opentype_format || font_format(f)==truetype_format)) { - set_font_encodingbytes(f,2); - } - - /* now fetch the base fonts, if needed */ - n = count_hash_items(L,luaS_index(fonts)); - if (n>0) { - l_fonts = xmalloc((n+2)*sizeof(integer)); - memset (l_fonts,0,(n+2)*sizeof(integer)); - lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(fonts)); - lua_rawget(L,-2); - for (i=1;i<=n;i++) { - lua_rawgeti(L,-1,i); - if (lua_istable(L,-1)) { - lua_getfield(L,-1,"id"); - if (lua_isnumber(L,-1)) { - l_fonts[i] = lua_tonumber(L,-1); - lua_pop(L,2); /* pop id and entry */ - continue; - } - lua_pop(L,1); /* pop id */ - }; - s = NULL; - if (lua_istable(L,-1)) { - lua_getfield(L,-1,"name"); - if (lua_isstring(L,-1)) { - s = (char *)lua_tostring(L,-1); - } - lua_pop(L,1); /* pop name */ - } - if (s!= NULL) { - lua_getfield(L,-1,"size"); - t = (lua_isnumber(L,-1) ? lua_roundnumber(L,-1) : -1000); - lua_pop(L,1); - - /* TODO: the stack is messed up, otherwise this - * explicit resizing would not be needed - */ - s_top = lua_gettop(L); - l_fonts[i] = find_font_id(s,"",t); - lua_settop(L,s_top); - } else { - pdftex_fail("Invalid local font in font %s!\n", font_name(f)); - } - lua_pop(L,1); /* pop list entry */ - } - lua_pop(L,1); /* pop list entry */ - } else { - if(font_type(f) == virtual_font_type) { - pdftex_fail("Invalid local fonts in font %s!\n", font_name(f)); - } else { - l_fonts = xmalloc(3*sizeof(integer)); - l_fonts[0] = 0; - l_fonts[1] = f; - l_fonts[2] = 0; - } - } - - /* parameters */ - read_lua_parameters(L,f); - read_lua_cidinfo(L,f); - - /* characters */ - lua_getfield(L,-1,"characters"); - if (lua_istable(L,-1)) { - /* find the array size values */ - ec = 0; bc = -1; - lua_pushnil(L); /* first key */ - while (lua_next(L, -2) != 0) { - if (lua_isnumber(L,-2)) { - i = lua_tointeger(L,-2); - if (i>=0) { - if (lua_istable(L,-1)) { - if (i>ec) ec = i; - if (bc<0) bc = i; - if (bc>=0 && i 2000) + i = 2000; + if (i == 1000) + i = 0; + set_font_extend(f, i); + i = numeric_field(L, "slant", 0); + if (i < -1000) + i = -1000; + if (i > 1000) + i = 1000; + set_font_slant(f, i); + + i = numeric_field(L, "hyphenchar", get_default_hyphen_char()); + set_hyphen_char(f, i); + i = numeric_field(L, "skewchar", get_default_skew_char()); + set_skew_char(f, i); + i = boolean_field(L, "used", 0); + set_font_used(f, i); + + s = string_field(L, "attributes", NULL); + if (s != NULL && strlen(s) > 0) { + i = maketexstring(s); + set_pdf_font_attr(f, i); + } + + i = enum_field(L, "type", unknown_font_type, font_type_strings); + set_font_type(f, i); + i = enum_field(L, "format", unknown_format, font_format_strings); + set_font_format(f, i); + i = enum_field(L, "embedding", unknown_embedding, font_embedding_strings); + set_font_embedding(f, i); + if (font_encodingbytes(f) == 0 && + (font_format(f) == opentype_format + || font_format(f) == truetype_format)) { + set_font_encodingbytes(f, 2); + } + + /* now fetch the base fonts, if needed */ + n = count_hash_items(L, luaS_index(fonts)); + if (n > 0) { + l_fonts = xmalloc((n + 2) * sizeof(integer)); + memset(l_fonts, 0, (n + 2) * sizeof(integer)); + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(fonts)); + lua_rawget(L, -2); + for (i = 1; i <= n; i++) { + lua_rawgeti(L, -1, i); + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "id"); + if (lua_isnumber(L, -1)) { + l_fonts[i] = lua_tonumber(L, -1); + lua_pop(L, 2); /* pop id and entry */ + continue; + } + lua_pop(L, 1); /* pop id */ + }; + s = NULL; + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "name"); + if (lua_isstring(L, -1)) { + s = (char *) lua_tostring(L, -1); + } + lua_pop(L, 1); /* pop name */ + } + if (s != NULL) { + lua_getfield(L, -1, "size"); + t = (lua_isnumber(L, -1) ? lua_roundnumber(L, -1) : -1000); + lua_pop(L, 1); + + /* TODO: the stack is messed up, otherwise this + * explicit resizing would not be needed + */ + s_top = lua_gettop(L); + if (strcmp(font_name(f), s) == 0) + l_fonts[i] = f; + else + l_fonts[i] = find_font_id(s, "", t); + lua_settop(L, s_top); + } else { + pdftex_fail("Invalid local font in font %s!\n", font_name(f)); + } + lua_pop(L, 1); /* pop list entry */ } - } - lua_pop(L, 1); - } - - if (bc != -1) { - /* fprintf(stdout,"defined a font at %d with %d-%d\n",f,bc,ec); */ - set_font_bc(f,bc); - set_font_ec(f,ec); - lua_pushnil(L); /* first key */ - while (lua_next(L, -2) != 0) { - if (lua_isnumber(L,-2)) { - i = lua_tonumber(L,-2); - if (i>=0) { - font_char_from_lua(L,f, i, l_fonts); - } - } else if (lua_isstring(L,-2)) { - s = (char *)lua_tostring(L,-2); - if (luaS_ptr_eq(s,left_boundary)) { - font_char_from_lua(L,f, left_boundarychar, l_fonts); - } else if (luaS_ptr_eq(s,right_boundary)) { - font_char_from_lua(L,f, right_boundarychar, l_fonts); - } + lua_pop(L, 1); /* pop list entry */ + } else { + if (font_type(f) == virtual_font_type) { + pdftex_fail("Invalid local fonts in font %s!\n", font_name(f)); + } else { + l_fonts = xmalloc(3 * sizeof(integer)); + l_fonts[0] = 0; + l_fonts[1] = f; + l_fonts[2] = 0; } - lua_pop(L, 1); - } - lua_pop(L, 1); - - /* handle font expansion last: the |copy_font| routine is called eventually, - and that needs to know |bc| and |ec|. */ - if (font_type(f)!=virtual_font_type) { - int fstep = numeric_field(L,"step",0); - if (fstep<0) fstep = 0; - if (fstep>100) fstep = 100; - if (fstep!=0) { - int fshrink = numeric_field(L,"shrink",0); - int fstretch = numeric_field(L,"stretch",0); - int fexpand = boolean_field(L,"auto_expand",0); - if (fshrink<0) fshrink = 0; - if (fshrink>500) fshrink = 500; - fshrink -= (fshrink % fstep); - if (fshrink<0) fshrink = 0; - if (fstretch<0) fstretch = 0; - if (fstretch>1000) fstretch = 1000; - fstretch -= (fstretch % fstep); - if (fstretch<0) fstretch = 0; - set_expand_params(f, fexpand, fstretch, fshrink, fstep, 0); - } - } - - } else { /* jikes, no characters */ - pdftex_warn("lua-loaded font [%d] (%s) has no characters!",f, font_name(f)); } + /* parameters */ + read_lua_parameters(L, f); + read_lua_math_parameters(L, f); + read_lua_cidinfo(L, f); + + /* characters */ + lua_getfield(L, -1, "characters"); + if (lua_istable(L, -1)) { + /* find the array size values */ + ec = 0; + bc = -1; + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + if (lua_isnumber(L, -2)) { + i = lua_tointeger(L, -2); + if (i >= 0) { + if (lua_istable(L, -1)) { + if (i > ec) + ec = i; + if (bc < 0) + bc = i; + if (bc >= 0 && i < bc) + bc = i; + } + } + } + lua_pop(L, 1); + } + + if (bc != -1) { + /* fprintf(stdout,"defined a font at %d with %d-%d\n",f,bc,ec); */ + set_font_bc(f, bc); + set_font_ec(f, ec); + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + if (lua_isnumber(L, -2)) { + i = lua_tonumber(L, -2); + if (i >= 0) { + font_char_from_lua(L, f, i, l_fonts); + } + } else if (lua_isstring(L, -2)) { + s = (char *) lua_tostring(L, -2); + if (luaS_ptr_eq(s, left_boundary)) { + font_char_from_lua(L, f, left_boundarychar, l_fonts); + } else if (luaS_ptr_eq(s, right_boundary)) { + font_char_from_lua(L, f, right_boundarychar, l_fonts); + } + } + lua_pop(L, 1); + } + lua_pop(L, 1); + + /* handle font expansion last: the |copy_font| routine is called eventually, + and that needs to know |bc| and |ec|. */ + if (font_type(f) != virtual_font_type) { + int fstep = numeric_field(L, "step", 0); + if (fstep < 0) + fstep = 0; + if (fstep > 100) + fstep = 100; + if (fstep != 0) { + int fshrink = numeric_field(L, "shrink", 0); + int fstretch = numeric_field(L, "stretch", 0); + int fexpand = boolean_field(L, "auto_expand", 0); + if (fshrink < 0) + fshrink = 0; + if (fshrink > 500) + fshrink = 500; + fshrink -= (fshrink % fstep); + if (fshrink < 0) + fshrink = 0; + if (fstretch < 0) + fstretch = 0; + if (fstretch > 1000) + fstretch = 1000; + fstretch -= (fstretch % fstep); + if (fstretch < 0) + fstretch = 0; + set_expand_params(f, fexpand, fstretch, fshrink, fstep, 0); + } + } + + } else { /* jikes, no characters */ + pdftex_warn("lua-loaded font [%d] (%s) has no characters!", f, + font_name(f)); + } + #if SAVE_REF - r = luaL_ref(Luas[0],LUA_REGISTRYINDEX); /* pops the table */ - set_font_cache_id(f,r); + r = luaL_ref(Luas, LUA_REGISTRYINDEX); /* pops the table */ + set_font_cache_id(f, r); #else - lua_pop(Luas[0],1); + lua_pop(Luas, 1); #endif - } else { /* jikes, no characters */ - pdftex_warn("lua-loaded font [%d] (%s) has no character table!",f, font_name(f)); - } + } else { /* jikes, no characters */ + pdftex_warn("lua-loaded font [%d] (%s) has no character table!", f, + font_name(f)); + } - if (l_fonts!=NULL) - free(l_fonts); - return true; + if (l_fonts != NULL) + free(l_fonts); + return true; } /* ==================================================================== @@ -1151,393 +1538,423 @@ font_from_lua (lua_State *L, int f) { #define assert_disc(a) \ assert(pre_break(a)!=null); /* expect head_node */ \ - assert(type(pre_break(a))==nesting_node); \ + assert(type(pre_break(a))==nesting_node); \ assert((vlink_pre_break(a)==null && tlink_pre_break(a)==null) || tail_of_list(vlink_pre_break(a))==tlink_pre_break(a)); \ assert(post_break(a)!=null); /* expect head_node */ \ - assert(type(post_break(a))==nesting_node); \ + assert(type(post_break(a))==nesting_node); \ assert((vlink_post_break(a)==null && tlink_post_break(a)==null) || tail_of_list(vlink_post_break(a))==tlink_post_break(a)); \ - assert(no_break(a)!=null); /* expect head_node */ \ - assert(type(no_break(a))==nesting_node); \ - assert((vlink_no_break(a)==null && tlink_no_break(a)==null) || tail_of_list(vlink_no_break(a))==tlink_no_break(a)); - -static void -nesting_append (halfword nest, halfword newn) { - halfword tail = tlink(nest); - assert(alink(nest)==null); - assert(vlink(newn)==null); - assert(alink(newn)==null); - if (tail==null) { - assert(vlink(nest)==null); - couple_nodes(nest,newn); - } else { - assert(vlink(tail)==null); - assert(tail_of_list(vlink(nest))==tail); - couple_nodes(tail,newn); - } - tlink(nest) = newn; + assert(no_break(a)!=null); /* expect head_node */ \ + assert(type(no_break(a))==nesting_node); \ + assert((vlink_no_break(a)==null && tlink_no_break(a)==null) || tail_of_list(vlink_no_break(a))==tlink_no_break(a)); + +static void nesting_append(halfword nest, halfword newn) +{ + halfword tail = tlink(nest); + assert(alink(nest) == null); + assert(vlink(newn) == null); + assert(alink(newn) == null); + if (tail == null) { + assert(vlink(nest) == null); + couple_nodes(nest, newn); + } else { + assert(vlink(tail) == null); + assert(tail_of_list(vlink(nest)) == tail); + couple_nodes(tail, newn); + } + tlink(nest) = newn; } -static void -nesting_prepend (halfword nest, halfword newn) { - halfword head = vlink(nest); - assert(alink(nest)==null); - assert(vlink(newn)==null); - assert(alink(newn)==null); - couple_nodes(nest,newn); - if (head==null) { - assert(tlink(nest)==null); - tlink(nest) = newn; - } else { - assert(alink(head)==nest); - assert(tail_of_list(head)==tlink(nest)); - couple_nodes(newn,head); - } +static void nesting_prepend(halfword nest, halfword newn) +{ + halfword head = vlink(nest); + assert(alink(nest) == null); + assert(vlink(newn) == null); + assert(alink(newn) == null); + couple_nodes(nest, newn); + if (head == null) { + assert(tlink(nest) == null); + tlink(nest) = newn; + } else { + assert(alink(head) == nest); + assert(tail_of_list(head) == tlink(nest)); + couple_nodes(newn, head); + } } -static int -test_ligature( liginfo *lig, halfword left, halfword right ) { - if (type(left)!=glyph_node) - return 0; - assert(type(right)==glyph_node); - if (font(left)!=font(right)) return 0; - if (is_ghost(left) || is_ghost(right)) return 0; - *lig = get_ligature(font(left),character(left),character(right)); - if (is_valid_ligature(*lig)) { - return 1; - } - return 0; +static int test_ligature(liginfo * lig, halfword left, halfword right) +{ + if (type(left) != glyph_node) + return 0; + assert(type(right) == glyph_node); + if (font(left) != font(right)) + return 0; + if (is_ghost(left) || is_ghost(right)) + return 0; + *lig = get_ligature(font(left), character(left), character(right)); + if (is_valid_ligature(*lig)) { + return 1; + } + return 0; } -static int -try_ligature(halfword *frst, halfword fwd) { - halfword cur = *frst; - liginfo lig; - if (test_ligature(&lig,cur,fwd)) { - int move_after = (lig_type(lig) & 0x0C)>>2; - int keep_right = ((lig_type(lig) & 0x01) != 0); - int keep_left = ((lig_type(lig) & 0x02) != 0); - halfword newgl = raw_glyph_node(); - font(newgl) = font(cur); - character(newgl) = lig_replacement(lig); - set_is_ligature(newgl); - - /* below might not be correct in contrived border case. - * but we use it only for debugging, so ... */ - if (character(cur)<0) { - set_is_leftboundary(newgl); - } - if (character(fwd)<0) { - set_is_rightboundary(newgl); - } - if (character(cur)<0) { - if (character(fwd)<0) { - build_attribute_list(newgl); - } else { - add_node_attr_ref(node_attr(fwd)); - node_attr(newgl) = node_attr(fwd); - } - } else { - add_node_attr_ref(node_attr(cur)); - node_attr(newgl) = node_attr(cur); - } - - /* TODO/FIXME if this ligature is consists of another ligature - * we should add it's lig_ptr to the new glyphs lig_ptr (and - * cleanup the no longer needed node) LOW PRIORITY */ - /* left side */ - if (keep_left) { - halfword new_first = copy_node(cur); - lig_ptr(newgl) = new_first; - couple_nodes(cur,newgl); - if (move_after) { - move_after--; - cur = newgl; - } - } else { - halfword prev = alink(cur); - uncouple_node(cur); - lig_ptr(newgl) = cur; - assert(prev!=null); - couple_nodes(prev,newgl); - cur = newgl; /* as cur has disappeared */ - } - /* right side */ - if (keep_right) { - halfword new_second = copy_node(fwd); - /* correct, because we _know_ lig_ptr points to _one_ node */ - couple_nodes(lig_ptr(newgl),new_second); - couple_nodes(newgl,fwd); - if (move_after) { - move_after--; - cur = fwd; - } - } else { - halfword next = vlink(fwd); - uncouple_node(fwd); - /* correct, because we _know_ lig_ptr points to _one_ node */ - couple_nodes(lig_ptr(newgl),fwd); - if (next!=null) {couple_nodes(newgl,next);} - } +static int try_ligature(halfword * frst, halfword fwd) +{ + halfword cur = *frst; + liginfo lig; + if (test_ligature(&lig, cur, fwd)) { + int move_after = (lig_type(lig) & 0x0C) >> 2; + int keep_right = ((lig_type(lig) & 0x01) != 0); + int keep_left = ((lig_type(lig) & 0x02) != 0); + halfword newgl = raw_glyph_node(); + font(newgl) = font(cur); + character(newgl) = lig_replacement(lig); + set_is_ligature(newgl); + + /* below might not be correct in contrived border case. + * but we use it only for debugging, so ... */ + if (character(cur) < 0) { + set_is_leftboundary(newgl); + } + if (character(fwd) < 0) { + set_is_rightboundary(newgl); + } + if (character(cur) < 0) { + if (character(fwd) < 0) { + build_attribute_list(newgl); + } else { + add_node_attr_ref(node_attr(fwd)); + node_attr(newgl) = node_attr(fwd); + } + } else { + add_node_attr_ref(node_attr(cur)); + node_attr(newgl) = node_attr(cur); + } - /* check and return */ - /* assert(move_after==0);*/ - *frst = cur; - return 1; - } - return 0; + /* TODO/FIXME if this ligature is consists of another ligature + * we should add it's lig_ptr to the new glyphs lig_ptr (and + * cleanup the no longer needed node) LOW PRIORITY */ + /* left side */ + if (keep_left) { + halfword new_first = copy_node(cur); + lig_ptr(newgl) = new_first; + couple_nodes(cur, newgl); + if (move_after) { + move_after--; + cur = newgl; + } + } else { + halfword prev = alink(cur); + uncouple_node(cur); + lig_ptr(newgl) = cur; + assert(prev != null); + couple_nodes(prev, newgl); + cur = newgl; /* as cur has disappeared */ + } + /* right side */ + if (keep_right) { + halfword new_second = copy_node(fwd); + /* correct, because we _know_ lig_ptr points to _one_ node */ + couple_nodes(lig_ptr(newgl), new_second); + couple_nodes(newgl, fwd); + if (move_after) { + move_after--; + cur = fwd; + } + } else { + halfword next = vlink(fwd); + uncouple_node(fwd); + /* correct, because we _know_ lig_ptr points to _one_ node */ + couple_nodes(lig_ptr(newgl), fwd); + if (next != null) { + couple_nodes(newgl, next); + } + } + + /* check and return */ + /* assert(move_after==0); */ + *frst = cur; + return 1; + } + return 0; } /* there shouldn't be any ligatures here - we only add them at the end of * xxx_break in a DISC-1 - DISC-2 situation and we stop processing DISC-1 * (we continue with DISC-1's post_ and no_break */ -static halfword -handle_lig_nest(halfword root, halfword cur) { - if (cur==null) return root; - while (vlink(cur)!=null) { - halfword fwd = vlink(cur); - if (type(cur)==glyph_node && type(fwd)==glyph_node && - font(cur)==font(fwd) && try_ligature(&cur,fwd)) continue; - cur = vlink(cur); - assert(vlink(alink(cur))==cur); - } - tlink(root) = cur; - return root; +static halfword handle_lig_nest(halfword root, halfword cur) +{ + if (cur == null) + return root; + while (vlink(cur) != null) { + halfword fwd = vlink(cur); + if (type(cur) == glyph_node && type(fwd) == glyph_node && + font(cur) == font(fwd) && try_ligature(&cur, fwd)) + continue; + cur = vlink(cur); + assert(vlink(alink(cur)) == cur); + } + tlink(root) = cur; + return root; } -static halfword -handle_lig_word(halfword cur) { - halfword right=null; - - if (type(cur)==whatsit_node && subtype(cur)==cancel_boundary_node) { - halfword prev= alink(cur); - halfword fwd = vlink(cur); -/* uncouple_node(cur); */ /* not needed, it is freed */ - flush_node(cur); - if (fwd==null) { - vlink(prev) = fwd; - return prev; - } - couple_nodes(prev,fwd); - if (type(fwd)!=glyph_node) return prev; - cur = fwd; - } else if (has_left_boundary(font(cur))) { - halfword prev= alink(cur); - halfword p = new_glyph(font(cur),left_boundarychar); - couple_nodes(prev,p); - couple_nodes(p,cur); - cur = p; - } - if (has_right_boundary(font(cur))) { - right = new_glyph(font(cur),right_boundarychar); - } - - while (1) { - /* A glyph followed by ... */ - if (type(cur)==glyph_node) { - halfword fwd = vlink(cur); - if (fwd==null) { /* last character of paragraph */ - if (right==null) break; - couple_nodes(cur,right); - right = null; - continue; - } - assert(alink(fwd)==cur); - if (type(fwd)==glyph_node) { /* GLYPH - GLYPH */ - if (font(cur)!=font(fwd)) break; - if (try_ligature(&cur,fwd)) continue; - } else if (type(fwd)==disc_node) { /* GLYPH - DISC */ - - /* if a{bx}{}{y} and a+b=>B convert to {Bx}{}{ay} */ - halfword pre = vlink_pre_break(fwd); - halfword nob = vlink_no_break(fwd); - halfword next, tail; - liginfo lig; - assert_disc(fwd); - /* Check on: a{b?}{?}{?} and a+b=>B : {B?}{?}{a?}*/ - /* Check on: a{?}{?}{b?} and a+b=>B : {a?}{?}{B?} */ - if ( (pre!=null && type(pre)==glyph_node && test_ligature(&lig,cur,pre)) - || (nob!=null && type(nob)==glyph_node && test_ligature(&lig,cur,nob))) { - /* move cur from before disc, to skipped part */ - halfword prev = alink(cur); - assert(vlink(prev)==cur); - uncouple_node(cur); - couple_nodes(prev,fwd); - nesting_prepend(no_break(fwd),cur); - /* now ligature the pre_break */ - nesting_prepend(pre_break(fwd),copy_node(cur)); - /* As we have removed cur, we need to start again ... */ - cur = prev; - } - /* Check on: a{?}{?}{}b and a+b=>B : {a?}{?b}{B}*/ - next = vlink(fwd); - if (nob==null && next != null && type(next)==glyph_node - && test_ligature(&lig,cur,next)) { - /* move cur from before disc to no_break part */ - halfword prev = alink(cur); - assert(alink(next)==fwd); - assert(vlink(prev)==cur); - uncouple_node(cur); - couple_nodes(prev,fwd); - couple_nodes(no_break(fwd),cur); /* we _know_ it's empty */ - /* now copy cur the pre_break */ - nesting_prepend(pre_break(fwd),copy_node(cur)); - /* move next from after disc to no_break part */ - tail = vlink(next); - uncouple_node(next); - try_couple_nodes(fwd,tail); - couple_nodes(cur,next); /* we _know_ this works */ - tlink(no_break(fwd)) = next; /* and make sure the list is correct */ - /* now copy next to the post_break */ - nesting_append(post_break(fwd),copy_node(next)); - /* As we have removed cur, we need to start again ... */ - cur = prev; - } - /* we are finished with the pre_break */ - handle_lig_nest(pre_break(fwd),vlink_pre_break(fwd)); - } else if (type(fwd)==whatsit_node && subtype(fwd)==cancel_boundary_node) { - halfword next = vlink(fwd); - try_couple_nodes(cur,next); - flush_node(fwd); - if (right!=null) { - flush_node(right); /* Shame, didn't need it */ - /* right = null; */ /* no need, we're going to leave the loop anyway */ +static halfword handle_lig_word(halfword cur) +{ + halfword right = null; + + if (type(cur) == whatsit_node && subtype(cur) == cancel_boundary_node) { + halfword prev = alink(cur); + halfword fwd = vlink(cur); + /* uncouple_node(cur); *//* not needed, it is freed */ + flush_node(cur); + if (fwd == null) { + vlink(prev) = fwd; + return prev; } - break; - } else { /* fwd is something unknown */ - if (right==null) break; - couple_nodes(cur,right); - couple_nodes(right,fwd); - right = null; - continue; - } - /* A discretionary followed by ... */ - } else if (type(cur)==disc_node) { - assert_disc(cur); - /* If {?}{x}{?} or {?}{?}{y} then ... */ - if (vlink_no_break(cur)!=null || vlink_post_break(cur)!=null) { - halfword fwd; - halfword lists[511]; /* max 8 levels */ - - int i, max_depth=0; - lists[max_depth++] = handle_lig_nest(post_break(cur),vlink_post_break(cur)); - lists[max_depth++] = handle_lig_nest(no_break(cur),vlink_no_break(cur)); - while (1) { - if ((fwd = vlink(cur))==null) return cur; - if ( type(fwd)==glyph_node) { - halfword next; - for (i=0; iB convert to {Bx}{}{ay} */ + halfword pre = vlink_pre_break(fwd); + halfword nob = vlink_no_break(fwd); + halfword next, tail; + liginfo lig; + assert_disc(fwd); + /* Check on: a{b?}{?}{?} and a+b=>B : {B?}{?}{a?} */ + /* Check on: a{?}{?}{b?} and a+b=>B : {a?}{?}{B?} */ + if ((pre != null && type(pre) == glyph_node + && test_ligature(&lig, cur, pre)) + || (nob != null && type(nob) == glyph_node + && test_ligature(&lig, cur, nob))) { + /* move cur from before disc, to skipped part */ + halfword prev = alink(cur); + assert(vlink(prev) == cur); + uncouple_node(cur); + couple_nodes(prev, fwd); + nesting_prepend(no_break(fwd), cur); + /* now ligature the pre_break */ + nesting_prepend(pre_break(fwd), copy_node(cur)); + /* As we have removed cur, we need to start again ... */ + cur = prev; + } + /* Check on: a{?}{?}{}b and a+b=>B : {a?}{?b}{B} */ + next = vlink(fwd); + if (nob == null && next != null && type(next) == glyph_node + && test_ligature(&lig, cur, next)) { + /* move cur from before disc to no_break part */ + halfword prev = alink(cur); + assert(alink(next) == fwd); + assert(vlink(prev) == cur); + uncouple_node(cur); + couple_nodes(prev, fwd); + couple_nodes(no_break(fwd), cur); /* we _know_ it's empty */ + /* now copy cur the pre_break */ + nesting_prepend(pre_break(fwd), copy_node(cur)); + /* move next from after disc to no_break part */ + tail = vlink(next); + uncouple_node(next); + try_couple_nodes(fwd, tail); + couple_nodes(cur, next); /* we _know_ this works */ + tlink(no_break(fwd)) = next; /* and make sure the list is correct */ + /* now copy next to the post_break */ + nesting_append(post_break(fwd), copy_node(next)); + /* As we have removed cur, we need to start again ... */ + cur = prev; + } + /* we are finished with the pre_break */ + handle_lig_nest(pre_break(fwd), vlink_pre_break(fwd)); + } else if (type(fwd) == whatsit_node + && subtype(fwd) == cancel_boundary_node) { + halfword next = vlink(fwd); + try_couple_nodes(cur, next); + flush_node(fwd); + if (right != null) { + flush_node(right); /* Shame, didn't need it */ + /* right = null; *//* no need, we're going to leave the loop anyway */ + } + break; + } else { /* fwd is something unknown */ + if (right == null) + break; + couple_nodes(cur, right); + couple_nodes(right, fwd); + right = null; + continue; } - next = vlink(fwd); - uncouple_node(fwd); - try_couple_nodes(cur,next); - flush_node(fwd); - } else if ( type(fwd)==disc_node) { - halfword next; - /* MAGIC WARNING - * A disc followed by a disc can have different kernings - * depending on which path is choosen, and it is impossible to - * store the possible kernings: fe {}{A}{W} {V}{}{A} - * So we _always_ add discs so only a simple path remains. */ - int m=max_depth; /* as max_depth changes in this loop */ - for (i=0; i0) { - tail = run_lua_ligkern_callback(head,tail,callback_id); - if (tail==null) tail = tail_of_list(head); - } else { - tail = handle_ligaturing(head,tail); - } - - callback_id = callback_defined(kerning_callback); - if (callback_id>0) { - tail = run_lua_ligkern_callback(head,tail,callback_id); - if (tail==null) tail = tail_of_list(head); - } else { - halfword nest = new_node(nesting_node,1); - halfword cur = vlink(head); - halfword aft = vlink(tail); - couple_nodes(nest,cur); - tlink(nest)=tail; - vlink(tail)=null; - do_handle_kerning(nest,null,null); - couple_nodes(head,vlink(nest)); - tail = tlink(nest); - try_couple_nodes(tail,aft); - flush_node(nest); - } - return tail; -} + callback_id = callback_defined(ligaturing_callback); + if (callback_id > 0) { + tail = run_lua_ligkern_callback(head, tail, callback_id); + if (tail == null) + tail = tail_of_list(head); + } else { + tail = handle_ligaturing(head, tail); + } + callback_id = callback_defined(kerning_callback); + if (callback_id > 0) { + tail = run_lua_ligkern_callback(head, tail, callback_id); + if (tail == null) + tail = tail_of_list(head); + } else { + halfword nest = new_node(nesting_node, 1); + halfword cur = vlink(head); + halfword aft = vlink(tail); + couple_nodes(nest, cur); + tlink(nest) = tail; + vlink(tail) = null; + do_handle_kerning(nest, null, null); + couple_nodes(head, vlink(nest)); + tail = tlink(nest); + try_couple_nodes(tail, aft); + flush_node(nest); + } + return tail; +} diff --git a/Build/source/texk/web2c/luatexdir/font/luatexfont.h b/Build/source/texk/web2c/luatexdir/font/luatexfont.h new file mode 100644 index 00000000000..ceee8bf69f3 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/luatexfont.h @@ -0,0 +1,67 @@ +/* luatexfont.h General font functions + + Copyright 2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: luatexfont.h 1783 2009-01-18 12:51:01Z oneiros $ */ + +#ifndef LUATEXFONT_H +# define LUATEXFONT_H 1 + +# include "ptexlib.h" +# include "sfnt.h" + +/* texfont.c */ +extern charinfo *copy_charinfo(charinfo * ci); + +/* tounicode.c */ +extern integer write_cid_tounicode(fo_entry * fo, internalfontnumber f); + +/* vfpacket.c */ +extern void replace_packet_fonts(internal_font_number f, integer * old_fontid, + integer * new_fontid, int count); +extern integer *packet_local_fonts(internal_font_number f, integer * num); + +/* writeccf.c */ +extern void writetype1w(fd_entry * fd); + +/* writetype0.c */ +extern void writetype0(fd_entry * fd); + +/* writetype2.c */ +extern void writetype2(fd_entry * fd); +extern unsigned long cidtogid_obj; +extern pdf_obj *pdf_new_stream(void); +extern void pdf_add_stream(pdf_obj * stream, unsigned char *buf, long len); +extern void pdf_release_obj(pdf_obj * stream); + +/* writet3.c */ +extern FILE *t3_file; + +extern unsigned char *t3_buffer; +extern integer t3_size; +extern integer t3_curbyte; + +# define t3_read_file() readbinfile(t3_file,&t3_buffer,&t3_size) +# define t3_close() xfclose(t3_file, cur_file_name) +# define t3_getchar() t3_buffer[t3_curbyte++] +# define t3_eof() (t3_curbyte>t3_size) + +# define t3_prefix(s) (!strncmp(t3_line_array, s, strlen(s))) +# define t3_putchar(c) pdfout(c) + +#endif diff --git a/Build/source/texk/web2c/luatexdir/font/macnames.c b/Build/source/texk/web2c/luatexdir/font/macnames.c index 941f087ef56..ae7720cc8dd 100644 --- a/Build/source/texk/web2c/luatexdir/font/macnames.c +++ b/Build/source/texk/web2c/luatexdir/font/macnames.c @@ -1,24 +1,25 @@ -/* -Copyright (c) 1996-2002 Han The Thanh, +/* macnames.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ -$Id: macnames.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ +static const char __svn_version[] = + "$Id: macnames.c 1223 2008-05-02 13:39:55Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/macnames.c $"; const char notdef[] = ".notdef"; diff --git a/Build/source/texk/web2c/luatexdir/font/mapfile.c b/Build/source/texk/web2c/luatexdir/font/mapfile.c index 1c444e5c1d4..c97cdf59782 100644 --- a/Build/source/texk/web2c/luatexdir/font/mapfile.c +++ b/Build/source/texk/web2c/luatexdir/font/mapfile.c @@ -1,25 +1,22 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, - -This file is part of pdfTeX. +/* mapfile.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: mapfile.c 1013 2008-02-14 00:09:02Z oneiros $ - -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include #include "ptexlib.h" @@ -28,6 +25,9 @@ $Id: mapfile.c 1013 2008-02-14 00:09:02Z oneiros $ #include #include "luatex-api.h" +static const char _svn_version[] = + "$Id: mapfile.c 1870 2009-02-19 10:03:13Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/mapfile.c $"; + #define FM_BUF_SIZE 1024 static FILE *fm_file; @@ -37,12 +37,12 @@ static integer fm_size = 0; static integer fm_curbyte = 0; #define fm_open() \ - open_input (&fm_file, kpse_fontmap_format, FOPEN_RBIN_MODE) + (fm_file = fopen((char *) nameoffile + 1, FOPEN_RBIN_MODE)) #define fm_read_file() \ readbinfile(fm_file,&fm_buffer,&fm_size) #define fm_close() xfclose(fm_file, cur_file_name) #define fm_getchar() fm_buffer[fm_curbyte++] -#define fm_eof() (fm_curbyte>=fm_size) +#define fm_eof() (fm_curbyte>fm_size) typedef enum { FM_DUPIGNORE, FM_REPLACE, FM_DELETE } updatemode; typedef enum { MAPFILE, MAPLINE } maptype; @@ -79,7 +79,7 @@ fm_entry *new_fm_entry(void) fm->tfm_name = NULL; fm->sfd_name = NULL; fm->ps_name = NULL; - fm->fd_flags = 4; + fm->fd_flags = FD_FLAGS_NOT_SET_IN_MAPLINE; fm->ff_name = NULL; fm->encname = NULL; fm->type = 0; @@ -102,23 +102,23 @@ void delete_fm_entry(fm_entry * fm) xfree(fm); } -static ff_entry *new_ff_entry (void) +static ff_entry *new_ff_entry(void) { ff_entry *ff; - ff = xtalloc (1, ff_entry); + ff = xtalloc(1, ff_entry); ff->ff_name = NULL; ff->ff_path = NULL; return ff; } -static void delete_ff_entry (ff_entry * ff) +static void delete_ff_entry(ff_entry * ff) { - xfree (ff->ff_name); - xfree (ff->ff_path); - xfree (ff); + xfree(ff->ff_name); + xfree(ff->ff_path); + xfree(ff); } -static fm_entry *dummy_fm_entry () +static fm_entry *dummy_fm_entry() { static const fm_entry const_fm_entry; return (fm_entry *) & const_fm_entry; @@ -133,10 +133,10 @@ struct avl_table *encname_tree = NULL; /* AVL sort fm_entry into tfm_tree by tfm_name */ -static int comp_fm_entry_tfm (const void *pa, const void *pb, void *p) +static int comp_fm_entry_tfm(const void *pa, const void *pb, void *p) { - return strcmp (((const fm_entry *) pa)->tfm_name, - ((const fm_entry *) pb)->tfm_name); + return strcmp(((const fm_entry *) pa)->tfm_name, + ((const fm_entry *) pb)->tfm_name); } /* AVL sort fm_entry into ps_tree by ps_name, slant, and extend */ @@ -155,13 +155,13 @@ static int comp_fm_entry_ps(const void *pa, const void *pb, void *p) /* AVL sort ff_entry into ff_tree by ff_name */ -static int comp_ff_entry (const void *pa, const void *pb, void *p) +static int comp_ff_entry(const void *pa, const void *pb, void *p) { - return strcmp (((const ff_entry *) pa)->ff_name, - ((const ff_entry *) pb)->ff_name); + return strcmp(((const ff_entry *) pa)->ff_name, + ((const ff_entry *) pb)->ff_name); } -static void create_avl_trees () +static void create_avl_trees() { assert(tfm_tree == NULL); tfm_tree = avl_create(comp_fm_entry_tfm, NULL, &avl_xallocator); @@ -354,9 +354,9 @@ int check_fm_entry(fm_entry * fm, boolean warn) } /**********************************************************************/ -/* returns true if s is one of the 14 std. font names; speed-trimmed. */ +/* returns the font number if s is one of the 14 std. font names, -1 otherwise; speed-trimmed. */ -boolean check_std_t1font(char *s) +int check_std_t1font(char *s) { static const char *std_t1font_names[] = { "Courier", /* 0:7 */ @@ -378,10 +378,12 @@ boolean check_std_t1font(char *s) { -1, -1, -1, -1, -1, -1, 8, 0, -1, 4, 10, 9, -1, -1, 5, 2, 12, 6, -1, 3, -1, 7 }; - const size_t n = strlen(s); + size_t n; int k = -1; + assert(s != NULL); + n = strlen(s); if (n > 21) - return false; + return -1; if (n == 12) { /* three names have length 12 */ switch (*s) { case 'C': @@ -394,15 +396,16 @@ boolean check_std_t1font(char *s) k = 13; /* ZapfDingbats */ break; default: - return false; + return -1; } } else k = index[n]; if (k > -1 && !strcmp(std_t1font_names[k], s)) - return true; - return false; + return k; + return -1; }; + /**********************************************************************/ static void fm_scan_line() @@ -415,11 +418,17 @@ static void fm_scan_line() switch (mitem->type) { case MAPFILE: p = fm_line; - do { - c = fm_getchar(); - append_char_to_buf(c, p, fm_line, FM_BUF_SIZE); + while (!fm_eof()) { + if (fm_curbyte == fm_size) { + fm_curbyte++; + c = 10; + } else { + c = fm_getchar(); + } + append_char_to_buf(c, p, fm_line, FM_BUF_SIZE); + if (c == 10) + break; } - while (c != 10 && !fm_eof()); *(--p) = '\0'; r = fm_line; break; @@ -532,9 +541,9 @@ static void fm_scan_line() } } done: - if (fm->ps_name != NULL && check_std_t1font(fm->ps_name)) + if (fm->ps_name != NULL && (check_std_t1font(fm->ps_name) >= 0)) set_std_t1font(fm); - if (is_fontfile(fm)) { + if (is_fontfile(fm) && strlen(fm_fontfile(fm)) > 3) { if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttf") == 0) set_truetype(fm); else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".otf") == 0) @@ -560,83 +569,95 @@ static void fm_scan_line() /**********************************************************************/ -void fm_read_info () +void fm_read_info() { int callback_id; int file_opened = 0; - char *ftemp = NULL; + char *ftemp = NULL; if (tfm_tree == NULL) - create_avl_trees (); + create_avl_trees(); if (mitem->line == NULL) /* nothing to do */ return; mitem->lineno = 1; switch (mitem->type) { case MAPFILE: - set_cur_file_name (mitem->line); - if (fm_buffer!=NULL) { - xfree(fm_buffer); - fm_buffer=NULL; - } - fm_curbyte=0; - fm_size=0; - callback_id=callback_defined(find_map_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->S",(char *)(nameoffile+1),&ftemp)) { - if(ftemp!=NULL&&strlen(ftemp)) { - free(nameoffile); - namelength = strlen(ftemp); - nameoffile = xmalloc(namelength+2); - strcpy((char *)(nameoffile+1),ftemp); - free(ftemp); - } - } - } - callback_id=callback_defined(read_map_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->bSd",(char *)(nameoffile+1), - &file_opened, &fm_buffer,&fm_size)) { - if(file_opened) { - if (fm_size>0) { - cur_file_name = (char *) nameoffile + 1; - if (tracefilenames) - tex_printf ("{%s", cur_file_name); - while (!fm_eof ()) { - fm_scan_line (); - mitem->lineno++; - } - if (tracefilenames) - tex_printf ("}"); - fm_file = NULL; - } - } else { - pdftex_warn ("cannot open font map file"); - } - } else { - pdftex_warn ("cannot open font map file"); - } - } else { - if (!fm_open ()) { - pdftex_warn ("cannot open font map file"); - } else { - fm_read_file(); - cur_file_name = (char *) nameoffile + 1; - tex_printf ("{%s", cur_file_name); - while (!fm_eof ()) { - fm_scan_line (); - mitem->lineno++; - } - fm_close (); - tex_printf ("}"); - fm_file = NULL; - } - } - break; + set_cur_file_name(mitem->line); + if (fm_buffer != NULL) { + xfree(fm_buffer); + fm_buffer = NULL; + } + fm_curbyte = 0; + fm_size = 0; + callback_id = callback_defined(find_map_file_callback); + if (callback_id > 0) { + if (run_callback + (callback_id, "S->S", (char *) (nameoffile + 1), &ftemp)) { + if (ftemp != NULL && strlen(ftemp)) { + free(nameoffile); + namelength = strlen(ftemp); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), ftemp); + free(ftemp); + } + } + } else { + ftemp = + kpse_find_file((char *) (nameoffile + 1), kpse_fontmap_format, + 0); + if (ftemp != NULL) { + free(nameoffile); + namelength = strlen(ftemp); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), ftemp); + free(ftemp); + } + } + callback_id = callback_defined(read_map_file_callback); + if (callback_id > 0) { + if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1), + &file_opened, &fm_buffer, &fm_size)) { + if (file_opened) { + if (fm_size > 0) { + cur_file_name = (char *) nameoffile + 1; + if (tracefilenames) + tex_printf("{%s", cur_file_name); + while (!fm_eof()) { + fm_scan_line(); + mitem->lineno++; + } + if (tracefilenames) + tex_printf("}"); + fm_file = NULL; + } + } else { + pdftex_warn("cannot open font map file"); + } + } else { + pdftex_warn("cannot open font map file"); + } + } else { + if (!fm_open()) { + pdftex_warn("cannot open font map file"); + } else { + fm_read_file(); + cur_file_name = (char *) nameoffile + 1; + tex_printf("{%s", cur_file_name); + while (!fm_eof()) { + fm_scan_line(); + mitem->lineno++; + } + fm_close(); + tex_printf("}"); + fm_file = NULL; + } + } + break; case MAPLINE: - cur_file_name = NULL; /* makes pdftex_warn() shorter */ - fm_scan_line (); - break; + cur_file_name = NULL; /* makes pdftex_warn() shorter */ + fm_scan_line(); + break; default: - assert (0); + assert(0); } mitem->line = NULL; /* done with this line */ cur_file_name = NULL; @@ -667,10 +688,10 @@ static fm_entry_ptr fmlookup(internalfontnumber f) boolean hasfmentry(internalfontnumber f) { - if (font_map(f) == NULL) - set_font_map(f, (fm_entry_ptr) fmlookup(f)); - assert(font_map(f) != NULL); - return font_map(f) != (fm_entry_ptr) dummy_fm_entry(); + if (font_map(f) == NULL) + set_font_map(f, (fm_entry_ptr) fmlookup(f)); + assert(font_map(f) != NULL); + return font_map(f) != (fm_entry_ptr) dummy_fm_entry(); } /* check whether a map entry is valid for font replacement */ @@ -859,7 +880,7 @@ void pdf_init_map_file(string map_name) mitem = xtalloc(1, mapitem); mitem->mode = FM_DUPIGNORE; mitem->type = MAPFILE; - mitem->line = xstrdup(map_name); + mitem->line = map_name; } @@ -881,7 +902,7 @@ ff_entry *check_ff_exist(char *ff_name, boolean is_tt) ff_entry tmp; void **aa; int callback_id; - char *filepath=NULL; + char *filepath = NULL; assert(ff_name != NULL); tmp.ff_name = ff_name; @@ -890,27 +911,26 @@ ff_entry *check_ff_exist(char *ff_name, boolean is_tt) ff = new_ff_entry(); ff->ff_name = xstrdup(ff_name); if (is_tt) { - callback_id=callback_defined(find_truetype_file_callback); - if (callback_id>0) { - run_callback(callback_id,"S->S",ff_name,&filepath); - if (filepath && strlen(filepath)==0) - filepath=NULL; - ff->ff_path = filepath; - } else { - ff->ff_path = kpse_find_file (ff_name, kpse_truetype_format, 0); - } - } - else { - callback_id=callback_defined(find_type1_file_callback); - if (callback_id>0) { - run_callback(callback_id,"S->S",ff_name,&filepath); - if (filepath && strlen(filepath)==0) - filepath=NULL; - ff->ff_path = filepath; - } else { - ff->ff_path = kpse_find_file (ff_name, kpse_type1_format, 0); - } - } + callback_id = callback_defined(find_truetype_file_callback); + if (callback_id > 0) { + run_callback(callback_id, "S->S", ff_name, &filepath); + if (filepath && strlen(filepath) == 0) + filepath = NULL; + ff->ff_path = filepath; + } else { + ff->ff_path = kpse_find_file(ff_name, kpse_truetype_format, 0); + } + } else { + callback_id = callback_defined(find_type1_file_callback); + if (callback_id > 0) { + run_callback(callback_id, "S->S", ff_name, &filepath); + if (filepath && strlen(filepath) == 0) + filepath = NULL; + ff->ff_path = filepath; + } else { + ff->ff_path = kpse_find_file(ff_name, kpse_type1_format, 0); + } + } aa = avl_probe(ff_tree, ff); assert(aa != NULL); } diff --git a/Build/source/texk/web2c/luatexdir/font/pkin.c b/Build/source/texk/web2c/luatexdir/font/pkin.c index 5067d6dbd66..99f64f29c11 100644 --- a/Build/source/texk/web2c/luatexdir/font/pkin.c +++ b/Build/source/texk/web2c/luatexdir/font/pkin.c @@ -1,24 +1,22 @@ -/* -Copyright (c) 1996-2002 Han The Thanh, - -This file is part of pdfTeX. +/* pkin.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: pkin.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ /* * NAME @@ -44,25 +42,21 @@ $Id: pkin.c 1013 2008-02-14 00:09:02Z oneiros $ */ #include "ptexlib.h" +#include "luatexfont.h" + +static const char _svn_version[] = + "$Id: pkin.c 1712 2009-01-02 10:54:55Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/pkin.c $"; /* * Now we have some routines to get stuff from the pk file. pkbyte returns * the next byte from the pk file. */ - -/* -static FILE *pkfile ; -*/ - -extern FILE *t3_file; -#define pkfile t3_file - static shalfword pkbyte(void) { register shalfword i; - - if ((i = xgetc(pkfile)) == EOF) + i = t3_getchar(); + if (t3_eof()) pdftex_fail("unexpected eof in pk file"); return (i); } diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.c b/Build/source/texk/web2c/luatexdir/font/sfnt.c index 95453a531a0..b705ef7240b 100644 --- a/Build/source/texk/web2c/luatexdir/font/sfnt.c +++ b/Build/source/texk/web2c/luatexdir/font/sfnt.c @@ -1,114 +1,110 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/sfnt.c,v 1.12 2004/09/11 14:50:29 hirata Exp $ +/* sfnt.c - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team + Copyright 2006-2008 Taco Hoekwater - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ /* Based on dvipdfmx-0.13.2c */ #if HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H_ */ +# include "config.h" +#endif /* HAVE_CONFIG_H_ */ #include #ifndef pdfTeX -#include "system.h" +# include "system.h" -#include "error.h" -#include "mem.h" -#include "mfileio.h" +# include "error.h" +# include "mem.h" +# include "mfileio.h" #else -extern void pdftex_fail (const char *fmt, ...); /* utils.c */ +# include "ptexlib.h" #endif #include "sfnt.h" +static const char _svn_version[] = + "$Id: sfnt.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/sfnt.c $"; + #ifdef XETEX -UNSIGNED_BYTE -ft_unsigned_byte(sfnt* f) +UNSIGNED_BYTE ft_unsigned_byte(sfnt * f) { - unsigned char byte; - unsigned long length = 1; - - if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, &byte, &length) != 0) - TT_ERROR("sfnt: Freetype failure..."); - f->loc += 1; - - return byte; + unsigned char byte; + unsigned long length = 1; + + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, &byte, &length) != 0) + TT_ERROR("sfnt: Freetype failure..."); + f->loc += 1; + + return byte; } -SIGNED_BYTE -ft_signed_byte(sfnt* f) +SIGNED_BYTE ft_signed_byte(sfnt * f) { - int b = ft_unsigned_byte(f); - if (b >= 0x80) - b -= 0x100; - return (SIGNED_BYTE)b; + int b = ft_unsigned_byte(f); + if (b >= 0x80) + b -= 0x100; + return (SIGNED_BYTE) b; } -UNSIGNED_PAIR -ft_unsigned_pair(sfnt* f) +UNSIGNED_PAIR ft_unsigned_pair(sfnt * f) { - unsigned char buf[2]; - unsigned long length = 2; - - if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) - TT_ERROR("sfnt: Freetype failure..."); - f->loc += 2; - - return (UNSIGNED_PAIR)((unsigned)buf[0] << 8) + buf[1]; + unsigned char buf[2]; + unsigned long length = 2; + + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) + TT_ERROR("sfnt: Freetype failure..."); + f->loc += 2; + + return (UNSIGNED_PAIR) ((unsigned) buf[0] << 8) + buf[1]; } -SIGNED_PAIR -ft_signed_pair(sfnt* f) +SIGNED_PAIR ft_signed_pair(sfnt * f) { - int p = ft_unsigned_pair(f); - if (p >= 0x8000U) - p -= 0x10000U; - - return (SIGNED_PAIR)p; + int p = ft_unsigned_pair(f); + if (p >= 0x8000U) + p -= 0x10000U; + + return (SIGNED_PAIR) p; } -UNSIGNED_QUAD -ft_unsigned_quad(sfnt* f) +UNSIGNED_QUAD ft_unsigned_quad(sfnt * f) { - unsigned char buf[4]; - unsigned long length = 4; + unsigned char buf[4]; + unsigned long length = 4; - if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) - TT_ERROR("sfnt: Freetype failure..."); - f->loc += 4; + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) + TT_ERROR("sfnt: Freetype failure..."); + f->loc += 4; - return ((unsigned long)buf[0] << 24) + ((unsigned long)buf[1] << 16) - + ((unsigned long)buf[2] << 8) + (unsigned long)buf[3]; + return ((unsigned long) buf[0] << 24) + ((unsigned long) buf[1] << 16) + + ((unsigned long) buf[2] << 8) + (unsigned long) buf[3]; } -unsigned long -ft_read(unsigned char* buf, unsigned long len, sfnt* f) +unsigned long ft_read(unsigned char *buf, unsigned long len, sfnt * f) { - unsigned long length = len; - if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) - TT_ERROR("sfnt: Freetype failure..."); - f->loc += len; + unsigned long length = len; + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) + TT_ERROR("sfnt: Freetype failure..."); + f->loc += len; - return length; + return length; } #endif @@ -122,398 +118,381 @@ ft_read(unsigned char* buf, unsigned long len, sfnt* f) * `ttcf': TrueType Collection */ #define SFNT_TRUETYPE 0x00010000UL -#define SFNT_MAC_TRUE 0x74727565UL +#define SFNT_MAC_TRUE 0x74727565UL #define SFNT_OPENTYPE 0x00010000UL #define SFNT_POSTSCRIPT 0x4f54544fUL #define SFNT_TTC 0x74746366UL #ifdef XETEX -sfnt * -sfnt_open (FT_Face face, int accept_types) +sfnt *sfnt_open(FT_Face face, int accept_types) { - sfnt *sfont; - ULONG type; - - if (!face || !FT_IS_SFNT(face)) - return NULL; - - sfont = NEW(1, sfnt); - sfont->ft_face = face; - sfont->loc = 0; - sfont->type = 0; - - type = sfnt_get_ulong(sfont); - - if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) { - sfont->type = SFNT_TYPE_TRUETYPE; - } else if (type == SFNT_OPENTYPE) { - sfont->type = SFNT_TYPE_OPENTYPE; - } else if (type == SFNT_POSTSCRIPT) { - sfont->type = SFNT_TYPE_POSTSCRIPT; - } else if (type == SFNT_TTC) { - sfont->type = SFNT_TYPE_TTC; - } - - if ((sfont->type & accept_types) == 0) { - RELEASE(sfont); - return NULL; - } - - sfont->loc = 0; - - sfont->directory = NULL; - - return sfont; + sfnt *sfont; + ULONG type; + + if (!face || !FT_IS_SFNT(face)) + return NULL; + + sfont = NEW(1, sfnt); + sfont->ft_face = face; + sfont->loc = 0; + sfont->type = 0; + + type = sfnt_get_ulong(sfont); + + if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) { + sfont->type = SFNT_TYPE_TRUETYPE; + } else if (type == SFNT_OPENTYPE) { + sfont->type = SFNT_TYPE_OPENTYPE; + } else if (type == SFNT_POSTSCRIPT) { + sfont->type = SFNT_TYPE_POSTSCRIPT; + } else if (type == SFNT_TTC) { + sfont->type = SFNT_TYPE_TTC; + } + + if ((sfont->type & accept_types) == 0) { + RELEASE(sfont); + return NULL; + } + + sfont->loc = 0; + + sfont->directory = NULL; + + return sfont; } -#else /* not XETEX */ -#ifdef pdfTeX -sfnt * -sfnt_open (unsigned char *buffer, integer buflen) +#else /* not XETEX */ +# ifdef pdfTeX +sfnt *sfnt_open(unsigned char *buffer, integer buflen) { - sfnt *sfont; - ULONG type; - - sfont = xmalloc(sizeof(sfnt)); - sfont->loc = 0; - sfont->buffer = buffer; - sfont->buflen = buflen; - - type = sfnt_get_ulong(sfont); - - if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) { - sfont->type = SFNT_TYPE_TRUETYPE; - } else if (type == SFNT_OPENTYPE) { - sfont->type = SFNT_TYPE_OPENTYPE; - } else if (type == SFNT_POSTSCRIPT) { - sfont->type = SFNT_TYPE_POSTSCRIPT; - } else if (type == SFNT_TTC) { - sfont->type = SFNT_TYPE_TTC; - } - - sfont->loc=0; - sfont->directory = NULL; - return sfont; + sfnt *sfont; + ULONG type; + + sfont = xmalloc(sizeof(sfnt)); + sfont->loc = 0; + sfont->buffer = buffer; + sfont->buflen = buflen; + + type = sfnt_get_ulong(sfont); + + if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) { + sfont->type = SFNT_TYPE_TRUETYPE; + } else if (type == SFNT_OPENTYPE) { + sfont->type = SFNT_TYPE_OPENTYPE; + } else if (type == SFNT_POSTSCRIPT) { + sfont->type = SFNT_TYPE_POSTSCRIPT; + } else if (type == SFNT_TTC) { + sfont->type = SFNT_TYPE_TTC; + } + + sfont->loc = 0; + sfont->directory = NULL; + return sfont; } -#else -sfnt * -sfnt_open (FILE *fp) +# else +sfnt *sfnt_open(FILE * fp) { - sfnt *sfont; - ULONG type; + sfnt *sfont; + ULONG type; - ASSERT(fp); + ASSERT(fp); - rewind(fp); + rewind(fp); - sfont = NEW(1, sfnt); + sfont = NEW(1, sfnt); - sfont->stream = fp; + sfont->stream = fp; - type = sfnt_get_ulong(sfont); + type = sfnt_get_ulong(sfont); - if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) { - sfont->type = SFNT_TYPE_TRUETYPE; - } else if (type == SFNT_OPENTYPE) { - sfont->type = SFNT_TYPE_OPENTYPE; - } else if (type == SFNT_POSTSCRIPT) { - sfont->type = SFNT_TYPE_POSTSCRIPT; - } else if (type == SFNT_TTC) { - sfont->type = SFNT_TYPE_TTC; - } + if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) { + sfont->type = SFNT_TYPE_TRUETYPE; + } else if (type == SFNT_OPENTYPE) { + sfont->type = SFNT_TYPE_OPENTYPE; + } else if (type == SFNT_POSTSCRIPT) { + sfont->type = SFNT_TYPE_POSTSCRIPT; + } else if (type == SFNT_TTC) { + sfont->type = SFNT_TYPE_TTC; + } - rewind(sfont->stream); + rewind(sfont->stream); - sfont->directory = NULL; + sfont->directory = NULL; - return sfont; + return sfont; } -#endif +# endif #endif -static void -release_directory (struct sfnt_table_directory *td) +static void release_directory(struct sfnt_table_directory *td) { - long i; - - if (td) { - if (td->tables) { - for (i = 0; i < td->num_tables; i++) { - if (td->tables[i].data) - RELEASE(td->tables[i].data); - } - RELEASE(td->tables); + long i; + + if (td) { + if (td->tables) { + for (i = 0; i < td->num_tables; i++) { + if (td->tables[i].data) + RELEASE(td->tables[i].data); + } + RELEASE(td->tables); + } + if (td->flags) + RELEASE(td->flags); + RELEASE(td); } - if (td->flags) - RELEASE(td->flags); - RELEASE(td); - } - return; + return; } -void -sfnt_close (sfnt *sfont) +void sfnt_close(sfnt * sfont) { - if (sfont) { - if (sfont->directory) - release_directory(sfont->directory); - RELEASE(sfont); - } + if (sfont) { + if (sfont->directory) + release_directory(sfont->directory); + RELEASE(sfont); + } - return; + return; } -int -put_big_endian (void *s, LONG q, int n) +int put_big_endian(void *s, LONG q, int n) { - int i; - char *p; + int i; + char *p; - p = (char *) s; - for (i = n - 1; i >= 0; i--) { - p[i] = (char) (q & 0xff); - q >>= 8; - } + p = (char *) s; + for (i = n - 1; i >= 0; i--) { + p[i] = (char) (q & 0xff); + q >>= 8; + } - return n; + return n; } /* Convert four-byte number to big endianess * in a machine independent way. */ -static void -convert_tag (char *tag, unsigned long u_tag) +static void convert_tag(char *tag, unsigned long u_tag) { - int i; + int i; - for (i = 3; i >= 0; i--) { - tag[i] = (char) (u_tag % 256); - u_tag /= 256; - } + for (i = 3; i >= 0; i--) { + tag[i] = (char) (u_tag % 256); + u_tag /= 256; + } - return; + return; } /* * Computes the max power of 2 <= n */ -static unsigned -max2floor (unsigned n) +static unsigned max2floor(unsigned n) { - int val = 1; + int val = 1; - while (n > 1) { - n /= 2; - val *= 2; - } + while (n > 1) { + n /= 2; + val *= 2; + } - return val; + return val; } /* * Computes the log2 of the max power of 2 <= n */ -static unsigned -log2floor (unsigned n) +static unsigned log2floor(unsigned n) { - unsigned val = 0; + unsigned val = 0; - while (n > 1) { - n /= 2; - val++; - } + while (n > 1) { + n /= 2; + val++; + } - return val; + return val; } -static ULONG -sfnt_calc_checksum(void *data, ULONG length) +static ULONG sfnt_calc_checksum(void *data, ULONG length) { - ULONG chksum = 0; - BYTE *p, *endptr; - int count = 0; - - p = (BYTE *) data; - endptr = p + length; - while (p < endptr) { - chksum += (p[0] << (8 * ( 3 - count))); - count = ((count + 1) & 3); - p++; - } - - return chksum; + ULONG chksum = 0; + BYTE *p, *endptr; + int count = 0; + + p = (BYTE *) data; + endptr = p + length; + while (p < endptr) { + chksum += (p[0] << (8 * (3 - count))); + count = ((count + 1) & 3); + p++; + } + + return chksum; } -static int -find_table_index (struct sfnt_table_directory *td, const char *tag) +static int find_table_index(struct sfnt_table_directory *td, const char *tag) { - int idx; + int idx; - if (!td) - return -1; + if (!td) + return -1; - for (idx = 0; idx < td->num_tables; idx++) { - if (!memcmp(td->tables[idx].tag, tag, 4)) - return idx; - } + for (idx = 0; idx < td->num_tables; idx++) { + if (!memcmp(td->tables[idx].tag, tag, 4)) + return idx; + } - return -1; + return -1; } -void -sfnt_set_table (sfnt *sfont, const char *tag, void *data, ULONG length) +void sfnt_set_table(sfnt * sfont, const char *tag, void *data, ULONG length) { - struct sfnt_table_directory *td; - int idx; + struct sfnt_table_directory *td; + int idx; - ASSERT(sfont); + ASSERT(sfont); - td = sfont->directory; - idx = find_table_index(td, tag); + td = sfont->directory; + idx = find_table_index(td, tag); - if (idx < 0) { - idx = td->num_tables; - td->num_tables++; - td->tables = RENEW(td->tables, td->num_tables, struct sfnt_table); - memcpy(td->tables[idx].tag, tag, 4); - } + if (idx < 0) { + idx = td->num_tables; + td->num_tables++; + td->tables = RENEW(td->tables, td->num_tables, struct sfnt_table); + memcpy(td->tables[idx].tag, tag, 4); + } - td->tables[idx].check_sum = sfnt_calc_checksum(data, length); - td->tables[idx].offset = 0L; - td->tables[idx].length = length; - td->tables[idx].data = data; + td->tables[idx].check_sum = sfnt_calc_checksum(data, length); + td->tables[idx].offset = 0L; + td->tables[idx].length = length; + td->tables[idx].data = data; - return; + return; } -ULONG -sfnt_find_table_len (sfnt *sfont, const char *tag) +ULONG sfnt_find_table_len(sfnt * sfont, const char *tag) { - ULONG length; - struct sfnt_table_directory *td; - int idx; - - ASSERT(sfont && tag); - - td = sfont->directory; - idx = find_table_index(td, tag); - if (idx < 0) - length = 0; - else { - length = td->tables[idx].length; - } + ULONG length; + struct sfnt_table_directory *td; + int idx; + + ASSERT(sfont && tag); + + td = sfont->directory; + idx = find_table_index(td, tag); + if (idx < 0) + length = 0; + else { + length = td->tables[idx].length; + } - return length; + return length; } -ULONG -sfnt_find_table_pos (sfnt *sfont, const char *tag) +ULONG sfnt_find_table_pos(sfnt * sfont, const char *tag) { - ULONG offset; - struct sfnt_table_directory *td; - int idx; - - ASSERT(sfont && tag); - - td = sfont->directory; - idx = find_table_index(td, tag); - if (idx < 0) - offset = 0; - else { - offset = td->tables[idx].offset; - } + ULONG offset; + struct sfnt_table_directory *td; + int idx; + + ASSERT(sfont && tag); + + td = sfont->directory; + idx = find_table_index(td, tag); + if (idx < 0) + offset = 0; + else { + offset = td->tables[idx].offset; + } - return offset; + return offset; } -ULONG -sfnt_locate_table (sfnt *sfont, const char *tag) +ULONG sfnt_locate_table(sfnt * sfont, const char *tag) { - ULONG offset; + ULONG offset; - ASSERT(sfont && tag); + ASSERT(sfont && tag); - offset = sfnt_find_table_pos(sfont, tag); - if (offset == 0) - TT_ERROR("sfnt: table not found..."); + offset = sfnt_find_table_pos(sfont, tag); + if (offset == 0) + TT_ERROR("sfnt: table not found..."); - sfnt_seek_set(sfont, offset); + sfnt_seek_set(sfont, offset); - return offset; + return offset; } -int -sfnt_read_table_directory (sfnt *sfont, ULONG offset) +int sfnt_read_table_directory(sfnt * sfont, ULONG offset) { - struct sfnt_table_directory *td; - unsigned long i, u_tag; + struct sfnt_table_directory *td; + unsigned long i, u_tag; - ASSERT(sfont); + ASSERT(sfont); - if (sfont->directory) - release_directory(sfont->directory); - sfont->directory = td = NEW (1, struct sfnt_table_directory); + if (sfont->directory) + release_directory(sfont->directory); + sfont->directory = td = NEW(1, struct sfnt_table_directory); #ifdef XETEX - ASSERT(sfont->ft_face); + ASSERT(sfont->ft_face); #elif defined(pdfTeX) - ASSERT(sfont->buffer); + ASSERT(sfont->buffer); #else - ASSERT(sfont->stream); + ASSERT(sfont->stream); #endif - sfnt_seek_set(sfont, offset); + sfnt_seek_set(sfont, offset); - td->version = sfnt_get_ulong(sfont); - td->num_tables = sfnt_get_ushort(sfont); - td->search_range = sfnt_get_ushort(sfont); - td->entry_selector = sfnt_get_ushort(sfont); - td->range_shift = sfnt_get_ushort(sfont); + td->version = sfnt_get_ulong(sfont); + td->num_tables = sfnt_get_ushort(sfont); + td->search_range = sfnt_get_ushort(sfont); + td->entry_selector = sfnt_get_ushort(sfont); + td->range_shift = sfnt_get_ushort(sfont); - td->flags = NEW(td->num_tables, char); - td->tables = NEW(td->num_tables, struct sfnt_table); + td->flags = NEW(td->num_tables, char); + td->tables = NEW(td->num_tables, struct sfnt_table); - for (i = 0; i < td->num_tables; i++) { - u_tag = sfnt_get_ulong(sfont); + for (i = 0; i < td->num_tables; i++) { + u_tag = sfnt_get_ulong(sfont); - convert_tag(td->tables[i].tag, u_tag); - td->tables[i].check_sum = sfnt_get_ulong(sfont); - td->tables[i].offset = sfnt_get_ulong(sfont); - td->tables[i].length = sfnt_get_ulong(sfont); - td->tables[i].data = NULL; + convert_tag(td->tables[i].tag, u_tag); + td->tables[i].check_sum = sfnt_get_ulong(sfont); + td->tables[i].offset = sfnt_get_ulong(sfont); + td->tables[i].length = sfnt_get_ulong(sfont); + td->tables[i].data = NULL; - td->flags[i] = 0; - } + td->flags[i] = 0; + } - td->num_kept_tables = 0; + td->num_kept_tables = 0; - return 0; + return 0; } -int -sfnt_require_table (sfnt *sfont, const char *tag, int must_exist) +int sfnt_require_table(sfnt * sfont, const char *tag, int must_exist) { - struct sfnt_table_directory *td; - int idx; - - ASSERT(sfont && sfont->directory); - - td = sfont->directory; - idx = find_table_index(td, tag); - if (idx < 0) { - if (must_exist) - return -1; - } else { - td->flags[idx] |= SFNT_TABLE_REQUIRED; - td->num_kept_tables++; - } - - return 0; + struct sfnt_table_directory *td; + int idx; + + ASSERT(sfont && sfont->directory); + + td = sfont->directory; + idx = find_table_index(td, tag); + if (idx < 0) { + if (must_exist) + return -1; + } else { + td->flags[idx] |= SFNT_TABLE_REQUIRED; + td->num_kept_tables++; + } + + return 0; } #ifndef pdfTeX -#include "pdfobj.h" +# include "pdfobj.h" #endif /* @@ -528,120 +507,115 @@ sfnt_require_table (sfnt *sfont, const char *tag, int must_exist) */ #ifdef pdfTeX -extern pdf_obj *pdf_new_stream(void); -extern void pdf_add_stream(pdf_obj *, unsigned char *, long); -extern void pdf_release_obj(pdf_obj *); -#undef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define STREAM_COMPRESS +# include "luatexfont.h" +# undef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +# define STREAM_COMPRESS #endif -static unsigned char wbuf[1024], padbytes[4] = {0, 0, 0, 0}; +static unsigned char wbuf[1024], padbytes[4] = { 0, 0, 0, 0 }; -pdf_obj * -sfnt_create_FontFile_stream (sfnt *sfont) +pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) { - pdf_obj *stream; + pdf_obj *stream; #ifndef pdfTeX - pdf_obj *stream_dict; + pdf_obj *stream_dict; #endif - struct sfnt_table_directory *td; - long offset, nb_read, length; - int i, sr; - char *p; - - ASSERT(sfont && sfont->directory); - - stream = pdf_new_stream(STREAM_COMPRESS); - - td = sfont->directory; - - /* Header */ - p = (char *) wbuf; - p += sfnt_put_ulong (p, td->version); - p += sfnt_put_ushort(p, td->num_kept_tables); - sr = max2floor(td->num_kept_tables) * 16; - p += sfnt_put_ushort(p, sr); - p += sfnt_put_ushort(p, log2floor(td->num_kept_tables)); - p += sfnt_put_ushort(p, td->num_kept_tables * 16 - sr); - - pdf_add_stream(stream, wbuf, 12); - - /* - * Compute start of actual tables (after headers). - */ - offset = 12 + 16 * td->num_kept_tables; - for (i = 0; i < td->num_tables; i++) { - /* This table must exist in FontFile */ - if (td->flags[i] & SFNT_TABLE_REQUIRED) { - if ((offset % 4) != 0) { - offset += 4 - (offset % 4); - } - - p = (char *) wbuf; - memcpy(p, td->tables[i].tag, 4); - p += 4; - p += sfnt_put_ulong(p, td->tables[i].check_sum); - p += sfnt_put_ulong(p, offset); - p += sfnt_put_ulong(p, td->tables[i].length); - pdf_add_stream(stream, wbuf, 16); - - offset += td->tables[i].length; + struct sfnt_table_directory *td; + long offset, nb_read, length; + int i, sr; + char *p; + + ASSERT(sfont && sfont->directory); + + stream = pdf_new_stream(STREAM_COMPRESS); + + td = sfont->directory; + + /* Header */ + p = (char *) wbuf; + p += sfnt_put_ulong(p, td->version); + p += sfnt_put_ushort(p, td->num_kept_tables); + sr = max2floor(td->num_kept_tables) * 16; + p += sfnt_put_ushort(p, sr); + p += sfnt_put_ushort(p, log2floor(td->num_kept_tables)); + p += sfnt_put_ushort(p, td->num_kept_tables * 16 - sr); + + pdf_add_stream(stream, wbuf, 12); + + /* + * Compute start of actual tables (after headers). + */ + offset = 12 + 16 * td->num_kept_tables; + for (i = 0; i < td->num_tables; i++) { + /* This table must exist in FontFile */ + if (td->flags[i] & SFNT_TABLE_REQUIRED) { + if ((offset % 4) != 0) { + offset += 4 - (offset % 4); + } + + p = (char *) wbuf; + memcpy(p, td->tables[i].tag, 4); + p += 4; + p += sfnt_put_ulong(p, td->tables[i].check_sum); + p += sfnt_put_ulong(p, offset); + p += sfnt_put_ulong(p, td->tables[i].length); + pdf_add_stream(stream, wbuf, 16); + + offset += td->tables[i].length; + } } - } - - offset = 12 + 16 * td->num_kept_tables; - for (i = 0; i < td->num_tables; i++) { - if (td->flags[i] & SFNT_TABLE_REQUIRED) { - if ((offset % 4) != 0) { - length = 4 - (offset % 4); - pdf_add_stream(stream, padbytes, length); - offset += length; - } - if (!td->tables[i].data) { + + offset = 12 + 16 * td->num_kept_tables; + for (i = 0; i < td->num_tables; i++) { + if (td->flags[i] & SFNT_TABLE_REQUIRED) { + if ((offset % 4) != 0) { + length = 4 - (offset % 4); + pdf_add_stream(stream, padbytes, length); + offset += length; + } + if (!td->tables[i].data) { #ifdef XETEX - if (!sfont->ft_face) + if (!sfont->ft_face) #elif defined(pdfTeX) - if (!sfont->buffer) + if (!sfont->buffer) #else - if (!sfont->stream) + if (!sfont->stream) #endif - { - pdf_release_obj(stream); - TT_ERROR("Font file not opened or already closed..."); - return NULL; - } - - length = td->tables[i].length; - sfnt_seek_set(sfont, td->tables[i].offset); - while (length > 0) { - nb_read = sfnt_read(wbuf, MIN(length, 1024), sfont); - if (nb_read < 0) { - pdf_release_obj(stream); - TT_ERROR("Reading file failed..."); - return NULL; - } else if (nb_read > 0) { - pdf_add_stream(stream, wbuf, nb_read); - } - length -= nb_read; - } - } else { - pdf_add_stream(stream, - (unsigned char *)td->tables[i].data, - td->tables[i].length); - RELEASE(td->tables[i].data); - td->tables[i].data = NULL; - } - /* Set offset for next table */ - offset += td->tables[i].length; + { + pdf_release_obj(stream); + TT_ERROR("Font file not opened or already closed..."); + return NULL; + } + + length = td->tables[i].length; + sfnt_seek_set(sfont, td->tables[i].offset); + while (length > 0) { + nb_read = sfnt_read(wbuf, MIN(length, 1024), sfont); + if (nb_read < 0) { + pdf_release_obj(stream); + TT_ERROR("Reading file failed..."); + return NULL; + } else if (nb_read > 0) { + pdf_add_stream(stream, wbuf, nb_read); + } + length -= nb_read; + } + } else { + pdf_add_stream(stream, + (unsigned char *) td->tables[i].data, + td->tables[i].length); + RELEASE(td->tables[i].data); + td->tables[i].data = NULL; + } + /* Set offset for next table */ + offset += td->tables[i].length; + } } - } #ifndef pdfTeX - stream_dict = pdf_stream_dict(stream); - pdf_add_dict(stream_dict, - pdf_new_name("Length1"), - pdf_new_number(offset)); + stream_dict = pdf_stream_dict(stream); + pdf_add_dict(stream_dict, pdf_new_name("Length1"), pdf_new_number(offset)); #endif - return stream; + return stream; } diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.h b/Build/source/texk/web2c/luatexdir/font/sfnt.h index 8db54dd9c39..87b373730be 100644 --- a/Build/source/texk/web2c/luatexdir/font/sfnt.h +++ b/Build/source/texk/web2c/luatexdir/font/sfnt.h @@ -1,197 +1,194 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/sfnt.h,v 1.9 2004/09/11 14:50:29 hirata Exp $ +/* sfnt.h - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team + Copyright 2006-2008 Taco Hoekwater - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: sfnt.h 1223 2008-05-02 13:39:55Z oneiros $ */ #ifndef _SFNT_H_ -#define _SFNT_H_ +# define _SFNT_H_ -#if HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H_ */ +# if HAVE_CONFIG_H +# include "config.h" +# endif /* HAVE_CONFIG_H_ */ -#ifndef pdfTeX -#include "mfileio.h" -#include "numbers.h" -#include "pdfobj.h" -#endif +# ifndef pdfTeX +# include "mfileio.h" +# include "numbers.h" +# include "pdfobj.h" +# endif -#ifdef XETEX -#include "ft2build.h" -#include FT_FREETYPE_H -#include FT_TRUETYPE_TABLES_H -#endif +# ifdef XETEX +# include "ft2build.h" +# include FT_FREETYPE_H +# include FT_TRUETYPE_TABLES_H +# endif /* Data Types as described in Apple's TTRefMan */ -typedef unsigned char BYTE; -typedef signed char ICHAR; +typedef unsigned char BYTE; +typedef signed char ICHAR; typedef unsigned short USHORT; -typedef signed short SHORT; -typedef unsigned long ULONG; -typedef signed long LONG; -typedef unsigned long Fixed; /* 16.16-bit signed fixed-point number */ -typedef short FWord; +typedef signed short SHORT; +typedef unsigned long ULONG; +typedef signed long LONG; +typedef unsigned long Fixed; /* 16.16-bit signed fixed-point number */ +typedef short FWord; typedef unsigned short uFWord; -typedef short F2Dot14; /* 16-bit signed fixed number with the low - 14 bits representing fraction. */ - -struct sfnt_table -{ - /* table header */ - char tag[4]; - ULONG check_sum; - ULONG offset; - ULONG length; - char *data; /* table data */ +typedef short F2Dot14; /* 16-bit signed fixed number with the low + 14 bits representing fraction. */ + +struct sfnt_table { + /* table header */ + char tag[4]; + ULONG check_sum; + ULONG offset; + ULONG length; + char *data; /* table data */ }; -#define SFNT_TABLE_REQUIRED (1 << 0) - -struct sfnt_table_directory -{ - ULONG version; /* Fixed for Win */ - USHORT num_tables; - USHORT search_range; - USHORT entry_selector; - USHORT range_shift; - USHORT num_kept_tables; /* number of kept tables */ - char *flags; /* keep or omit */ - struct sfnt_table *tables; +# define SFNT_TABLE_REQUIRED (1 << 0) + +struct sfnt_table_directory { + ULONG version; /* Fixed for Win */ + USHORT num_tables; + USHORT search_range; + USHORT entry_selector; + USHORT range_shift; + USHORT num_kept_tables; /* number of kept tables */ + char *flags; /* keep or omit */ + struct sfnt_table *tables; }; /* sfnt resource */ -#define SFNT_TYPE_TRUETYPE (1 << 0) -#define SFNT_TYPE_OPENTYPE (1 << 1) -#define SFNT_TYPE_POSTSCRIPT (1 << 2) -#define SFNT_TYPE_TTC (1 << 4) - -typedef struct -{ - int type; - struct sfnt_table_directory *directory; -#ifdef XETEX - FT_Face ft_face; - long loc; -#elif defined(pdfTeX) - BYTE *buffer; - long buflen; - long loc; -#else - FILE *stream; -#endif +# define SFNT_TYPE_TRUETYPE (1 << 0) +# define SFNT_TYPE_OPENTYPE (1 << 1) +# define SFNT_TYPE_POSTSCRIPT (1 << 2) +# define SFNT_TYPE_TTC (1 << 4) + +typedef struct { + int type; + struct sfnt_table_directory *directory; +# ifdef XETEX + FT_Face ft_face; + long loc; +# elif defined(pdfTeX) + BYTE *buffer; + long buflen; + long loc; +# else + FILE *stream; +# endif } sfnt; /* Convert sfnt "fixed" type to double */ -#define fixed(a) ((double)((a)%0x10000L)/(double)(0x10000L) + \ +# define fixed(a) ((double)((a)%0x10000L)/(double)(0x10000L) + \ (a)/0x10000L - (((a)/0x10000L > 0x7fffL) ? 0x10000L : 0)) -#ifdef XETEX -UNSIGNED_BYTE ft_unsigned_byte(sfnt* f); -SIGNED_BYTE ft_signed_byte(sfnt* f); -UNSIGNED_PAIR ft_unsigned_pair(sfnt* f); -SIGNED_PAIR ft_signed_pair(sfnt* f); -UNSIGNED_QUAD ft_unsigned_quad(sfnt* f); -unsigned long ft_read(unsigned char* buf, unsigned long len, sfnt* f); - -#define sfnt_get_byte(s) ((BYTE) ft_unsigned_byte(s)) -#define sfnt_get_char(s) ((ICHAR) ft_signed_byte (s)) -#define sfnt_get_ushort(s) ((USHORT) ft_unsigned_pair(s)) -#define sfnt_get_short(s) ((SHORT) ft_signed_pair (s)) -#define sfnt_get_ulong(s) ((ULONG) ft_unsigned_quad(s)) -#define sfnt_get_long(s) ((LONG) ft_signed_quad (s)) - -#define sfnt_seek_set(s,o) (s)->loc = (o) -#define sfnt_read(b,l,s) ft_read((b), (l), (s)) -#elif defined(pdfTeX) -BYTE get_unsigned_byte(sfnt* f); -ICHAR get_signed_byte(sfnt* f); -USHORT get_unsigned_pair(sfnt* f); -SHORT get_signed_pair(sfnt* f); -ULONG get_unsigned_quad(sfnt* f); -int do_sfnt_read (unsigned char *dest, int len, sfnt *f); - -#define sfnt_get_byte(s) ((BYTE) get_unsigned_byte(s)) -#define sfnt_get_char(s) ((ICHAR) get_signed_byte (s)) -#define sfnt_get_ushort(s) ((USHORT) get_unsigned_pair(s)) -#define sfnt_get_short(s) ((SHORT) get_signed_pair (s)) -#define sfnt_get_ulong(s) ((ULONG) get_unsigned_quad(s)) -#define sfnt_get_long(s) ((LONG) get_signed_quad (s)) - -#define sfnt_seek_set(s,o) (s)->loc = (o) -#define sfnt_read(b,l,s) do_sfnt_read((b), (l), (s)) -#else +# ifdef XETEX +UNSIGNED_BYTE ft_unsigned_byte(sfnt * f); +SIGNED_BYTE ft_signed_byte(sfnt * f); +UNSIGNED_PAIR ft_unsigned_pair(sfnt * f); +SIGNED_PAIR ft_signed_pair(sfnt * f); +UNSIGNED_QUAD ft_unsigned_quad(sfnt * f); +unsigned long ft_read(unsigned char *buf, unsigned long len, sfnt * f); + +# define sfnt_get_byte(s) ((BYTE) ft_unsigned_byte(s)) +# define sfnt_get_char(s) ((ICHAR) ft_signed_byte (s)) +# define sfnt_get_ushort(s) ((USHORT) ft_unsigned_pair(s)) +# define sfnt_get_short(s) ((SHORT) ft_signed_pair (s)) +# define sfnt_get_ulong(s) ((ULONG) ft_unsigned_quad(s)) +# define sfnt_get_long(s) ((LONG) ft_signed_quad (s)) + +# define sfnt_seek_set(s,o) (s)->loc = (o) +# define sfnt_read(b,l,s) ft_read((b), (l), (s)) +# elif defined(pdfTeX) +BYTE get_unsigned_byte(sfnt * f); +ICHAR get_signed_byte(sfnt * f); +USHORT get_unsigned_pair(sfnt * f); +SHORT get_signed_pair(sfnt * f); +ULONG get_unsigned_quad(sfnt * f); +int do_sfnt_read(unsigned char *dest, int len, sfnt * f); + +# define sfnt_get_byte(s) ((BYTE) get_unsigned_byte(s)) +# define sfnt_get_char(s) ((ICHAR) get_signed_byte (s)) +# define sfnt_get_ushort(s) ((USHORT) get_unsigned_pair(s)) +# define sfnt_get_short(s) ((SHORT) get_signed_pair (s)) +# define sfnt_get_ulong(s) ((ULONG) get_unsigned_quad(s)) +# define sfnt_get_long(s) ((LONG) get_signed_quad (s)) + +# define sfnt_seek_set(s,o) (s)->loc = (o) +# define sfnt_read(b,l,s) do_sfnt_read((b), (l), (s)) +# else /* get_***_*** from numbers.h */ -#define sfnt_get_byte(s) ((BYTE) get_unsigned_byte((s)->stream)) -#define sfnt_get_char(s) ((ICHAR) get_signed_byte ((s)->stream)) -#define sfnt_get_ushort(s) ((USHORT) get_unsigned_pair((s)->stream)) -#define sfnt_get_short(s) ((SHORT) get_signed_pair ((s)->stream)) -#define sfnt_get_ulong(s) ((ULONG) get_unsigned_quad((s)->stream)) -#define sfnt_get_long(s) ((LONG) get_signed_quad ((s)->stream)) - -#define sfnt_seek_set(s,o) seek_absolute((s)->stream, (o)) -#define sfnt_read(b,l,s) fread((b), 1, (l), (s)->stream) -#endif - -extern int put_big_endian (void *s, LONG q, int n); - -#define sfnt_put_ushort(s,v) put_big_endian((s), v, 2); -#define sfnt_put_short(s,v) put_big_endian((s), v, 2); -#define sfnt_put_ulong(s,v) put_big_endian((s), v, 4); -#define sfnt_put_long(s,v) put_big_endian((s), v, 4); - -#ifdef XETEX -extern sfnt *sfnt_open (FT_Face face, int accept_types); -#elif defined(pdfTeX) -extern sfnt *sfnt_open (unsigned char *buffer, integer buflen); -#else -extern sfnt *sfnt_open (FILE *fp); -#endif -extern void sfnt_close (sfnt *sfont); +# define sfnt_get_byte(s) ((BYTE) get_unsigned_byte((s)->stream)) +# define sfnt_get_char(s) ((ICHAR) get_signed_byte ((s)->stream)) +# define sfnt_get_ushort(s) ((USHORT) get_unsigned_pair((s)->stream)) +# define sfnt_get_short(s) ((SHORT) get_signed_pair ((s)->stream)) +# define sfnt_get_ulong(s) ((ULONG) get_unsigned_quad((s)->stream)) +# define sfnt_get_long(s) ((LONG) get_signed_quad ((s)->stream)) + +# define sfnt_seek_set(s,o) seek_absolute((s)->stream, (o)) +# define sfnt_read(b,l,s) fread((b), 1, (l), (s)->stream) +# endif + +extern int put_big_endian(void *s, LONG q, int n); + +# define sfnt_put_ushort(s,v) put_big_endian((s), v, 2); +# define sfnt_put_short(s,v) put_big_endian((s), v, 2); +# define sfnt_put_ulong(s,v) put_big_endian((s), v, 4); +# define sfnt_put_long(s,v) put_big_endian((s), v, 4); + +# ifdef XETEX +extern sfnt *sfnt_open(FT_Face face, int accept_types); +# elif defined(pdfTeX) +extern sfnt *sfnt_open(unsigned char *buffer, integer buflen); +# else +extern sfnt *sfnt_open(FILE * fp); +# endif +extern void sfnt_close(sfnt * sfont); /* table directory */ -extern int sfnt_read_table_directory (sfnt *sfont, ULONG offset); -extern ULONG sfnt_find_table_len (sfnt *sfont, const char *tag); -extern ULONG sfnt_find_table_pos (sfnt *sfont, const char *tag); -extern ULONG sfnt_locate_table (sfnt *sfont, const char *tag); - -extern void sfnt_set_table (sfnt *sfont, - const char *tag, void *data, ULONG length); -extern int sfnt_require_table (sfnt *sfont, const char *tag, int must_exist); - -#ifdef pdfTeX -typedef struct -{ - ULONG length; - BYTE *data; +extern int sfnt_read_table_directory(sfnt * sfont, ULONG offset); +extern ULONG sfnt_find_table_len(sfnt * sfont, const char *tag); +extern ULONG sfnt_find_table_pos(sfnt * sfont, const char *tag); +extern ULONG sfnt_locate_table(sfnt * sfont, const char *tag); + +extern void sfnt_set_table(sfnt * sfont, + const char *tag, void *data, ULONG length); +extern int sfnt_require_table(sfnt * sfont, const char *tag, int must_exist); + +# ifdef pdfTeX +typedef struct { + ULONG length; + BYTE *data; } pdf_obj; -#define ASSERT(a) assert(a) -#define RELEASE(a) free(a) -#define NEW(a,b) xmalloc((a)*sizeof(b)) -#define RENEW(a,b,c) xrealloc(a, ((b)*sizeof(c))) -#define TT_ERROR pdftex_fail -#define WARN printf +# define ASSERT(a) assert(a) +# define RELEASE(a) free(a) +# define NEW(a,b) xmalloc((a)*sizeof(b)) +# define RENEW(a,b,c) xrealloc(a, ((b)*sizeof(c))) +# define TT_ERROR pdftex_fail +# define WARN printf -#endif +# endif -extern pdf_obj *sfnt_create_FontFile_stream (sfnt *sfont); +extern pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont); -#endif /* _SFNT_H_ */ +#endif /* _SFNT_H_ */ diff --git a/Build/source/texk/web2c/luatexdir/font/subfont.c b/Build/source/texk/web2c/luatexdir/font/subfont.c index 836985c10fd..fecd5ed7857 100644 --- a/Build/source/texk/web2c/luatexdir/font/subfont.c +++ b/Build/source/texk/web2c/luatexdir/font/subfont.c @@ -1,26 +1,29 @@ -/* -Copyright (c) 2005-2006 Han The Thanh, +/* subfont.c + + Copyright 2005-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" #include +static const char _svn_version[] = + "$Id: subfont.c 1783 2009-01-18 12:51:01Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/subfont.c $"; + static struct avl_table *sfd_tree = NULL; static unsigned char *sfd_buffer = NULL; @@ -30,7 +33,7 @@ static integer sfd_curbyte = 0; #define SFD_BUF_SIZE SMALL_BUF_SIZE #define sfd_close() xfclose(sfd_file, cur_file_name) -#define sfd_open() open_input(&sfd_file, kpse_sfd_format, FOPEN_RBIN_MODE) +#define sfd_open() (sfd_file = fopen((char *) nameoffile + 1, FOPEN_RBIN_MODE)) #define sfd_read_file() readbinfile(sfd_file,&sfd_buffer,&sfd_size) #define sfd_getchar() sfd_buffer[sfd_curbyte++] @@ -40,11 +43,11 @@ static integer sfd_curbyte = 0; static FILE *sfd_file; static char sfd_line[SFD_BUF_SIZE]; -static subfont_entry *new_subfont_entry (void) +static subfont_entry *new_subfont_entry(void) { int i; subfont_entry *subfont; - subfont = xtalloc (1, subfont_entry); + subfont = xtalloc(1, subfont_entry); subfont->infix = NULL; for (i = 0; i < 256; ++i) subfont->charcodes[i] = -1; /* unassigned */ @@ -52,16 +55,16 @@ static subfont_entry *new_subfont_entry (void) return subfont; } -static sfd_entry *new_sfd_entry (void) +static sfd_entry *new_sfd_entry(void) { sfd_entry *sfd; - sfd = xtalloc (1, sfd_entry); + sfd = xtalloc(1, sfd_entry); sfd->name = NULL; sfd->subfont = NULL; return sfd; } -static void destroy_sfd_entry (void *pa, void *pb) +static void destroy_sfd_entry(void *pa, void *pb) { subfont_entry *p, *q; sfd_entry *sfd; @@ -69,132 +72,139 @@ static void destroy_sfd_entry (void *pa, void *pb) p = sfd->subfont; while (p != NULL) { q = p->next; - xfree (p->infix); - xfree (p); + xfree(p->infix); + xfree(p); p = q; } - xfree (sfd->name); + xfree(sfd->name); } -static int comp_sfd_entry (const void *pa, const void *pb, void *p) +static int comp_sfd_entry(const void *pa, const void *pb, void *p) { - return strcmp (((const sfd_entry *) pa)->name, - ((const sfd_entry *) pb)->name); + return strcmp(((const sfd_entry *) pa)->name, + ((const sfd_entry *) pb)->name); } -void sfd_free (void) +void sfd_free(void) { if (sfd_tree != NULL) - avl_destroy (sfd_tree, destroy_sfd_entry); + avl_destroy(sfd_tree, destroy_sfd_entry); } -static void sfd_getline (boolean expect_eof) +static void sfd_getline(boolean expect_eof) { char *p; int c; restart: - if (sfd_eof ()) { + if (sfd_eof()) { if (expect_eof) return; else - pdftex_fail ("unexpected end of file"); + pdftex_fail("unexpected end of file"); } p = sfd_line; do { - c = sfd_getchar (); - append_char_to_buf (c, p, sfd_line, SFD_BUF_SIZE); + c = sfd_getchar(); + append_char_to_buf(c, p, sfd_line, SFD_BUF_SIZE); } while (c != 10 && !sfd_eof()); - append_eol (p, sfd_line, SFD_BUF_SIZE); + append_eol(p, sfd_line, SFD_BUF_SIZE); if (p - sfd_line < 2 || *sfd_line == '#') goto restart; } -static sfd_entry *read_sfd (char *sfd_name) +static sfd_entry *read_sfd(char *sfd_name) { void **aa; sfd_entry *sfd, tmp_sfd; subfont_entry *sf; - char *ftemp = NULL; + char *ftemp = NULL; char buf[SMALL_BUF_SIZE], *p; long int i, j, k; int n; - int callback_id=0; - int file_opened=0; + int callback_id = 0; + int file_opened = 0; /* check whether this sfd has been read */ tmp_sfd.name = sfd_name; if (sfd_tree == NULL) { - sfd_tree = avl_create (comp_sfd_entry, NULL, &avl_xallocator); - assert (sfd_tree != NULL); + sfd_tree = avl_create(comp_sfd_entry, NULL, &avl_xallocator); + assert(sfd_tree != NULL); } - sfd = (sfd_entry *) avl_find (sfd_tree, &tmp_sfd); + sfd = (sfd_entry *) avl_find(sfd_tree, &tmp_sfd); if (sfd != NULL) return sfd; - set_cur_file_name (sfd_name); - if (sfd_buffer!=NULL) { - xfree(sfd_buffer); - sfd_buffer=NULL; + set_cur_file_name(sfd_name); + if (sfd_buffer != NULL) { + xfree(sfd_buffer); + sfd_buffer = NULL; } - sfd_curbyte=0; - sfd_size=0; + sfd_curbyte = 0; + sfd_size = 0; - callback_id=callback_defined(find_sfd_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->S",cur_file_name,&ftemp)) { - if(ftemp!=NULL&&strlen(ftemp)) { - if (cur_file_name) - free(cur_file_name); - cur_file_name = xstrdup(ftemp); - free(ftemp); - } - } - } - callback_id=callback_defined(read_sfd_file_callback); - if (callback_id>0) { - if(! (run_callback(callback_id,"S->bSd",cur_file_name, - &file_opened, &sfd_buffer,&sfd_size) && - file_opened && - sfd_size>0 ) ) { - pdftex_warn ("cannot open SFD file for reading"); - cur_file_name = NULL; - return NULL; - } - sfd_read_file(); - sfd_close(); + callback_id = callback_defined(find_sfd_file_callback); + if (callback_id > 0) { + if (run_callback(callback_id, "S->S", cur_file_name, &ftemp)) { + if (ftemp != NULL && strlen(ftemp)) { + if (cur_file_name) + free(cur_file_name); + cur_file_name = xstrdup(ftemp); + free(ftemp); + } + } + } else { + cur_file_name = kpse_find_file(cur_file_name, kpse_sfd_format, 0); + } + callback_id = callback_defined(read_sfd_file_callback); + if (callback_id > 0) { + if (!(run_callback(callback_id, "S->bSd", cur_file_name, + &file_opened, &sfd_buffer, &sfd_size) && + file_opened && sfd_size > 0)) { + pdftex_warn("cannot open SFD file for reading"); + cur_file_name = NULL; + return NULL; + } + } else { + if (!sfd_open()) { + pdftex_warn("cannot open SFD file for reading"); + cur_file_name = NULL; + return NULL; + } + sfd_read_file(); + sfd_close(); } - tex_printf ("{"); - tex_printf (cur_file_name); - sfd = new_sfd_entry (); - sfd->name = xstrdup (sfd_name); - while (!sfd_eof ()) { - sfd_getline (true); + tex_printf("{"); + tex_printf("%s", cur_file_name); + sfd = new_sfd_entry(); + sfd->name = xstrdup(sfd_name); + while (!sfd_eof()) { + sfd_getline(true); if (*sfd_line == 10) /* empty line indicating eof */ break; - sf = new_subfont_entry (); + sf = new_subfont_entry(); sf->next = sfd->subfont; sfd->subfont = sf; - sscanf (sfd_line, "%s %n", buf, &n); - sf->infix = xstrdup (buf); + sscanf(sfd_line, "%s %n", buf, &n); + sf->infix = xstrdup(buf); p = sfd_line + n; /* skip to the next word */ k = 0; read_ranges: for (;;) { if (*p == '\\') { /* continue on next line */ - sfd_getline (false); + sfd_getline(false); p = sfd_line; goto read_ranges; } else if (*p == 0) /* end of subfont */ break; - if (sscanf (p, " %li %n", &i, &n) == 0) - pdftex_fail ("invalid token:\n%s", p); + if (sscanf(p, " %li %n", &i, &n) == 0) + pdftex_fail("invalid token:\n%s", p); p += n; if (*p == ':') { /* offset */ k = i; p++; } else if (*p == '_') { /* range */ - if (sscanf (p + 1, " %li %n", &j, &n) == 0) - pdftex_fail ("invalid token:\n%s", p); + if (sscanf(p + 1, " %li %n", &j, &n) == 0) + pdftex_fail("invalid token:\n%s", p); if (i > j || k + (j - i) > 255) - pdftex_fail ("invalid range:\n%s", p); + pdftex_fail("invalid range:\n%s", p); while (i <= j) sf->charcodes[k++] = i++; p += n + 1; @@ -202,13 +212,13 @@ static sfd_entry *read_sfd (char *sfd_name) sf->charcodes[k++] = i; } } - tex_printf ("}"); - aa = avl_probe (sfd_tree, sfd); - assert (aa != NULL); + tex_printf("}"); + aa = avl_probe(sfd_tree, sfd); + assert(aa != NULL); return sfd; } -boolean handle_subfont_fm (fm_entry * fm, int mode) +boolean handle_subfont_fm(fm_entry * fm, int mode) { size_t l; char *p, *q, *r; @@ -216,28 +226,28 @@ boolean handle_subfont_fm (fm_entry * fm, int mode) subfont_entry *sf; fm_entry *fm2; char buf[SMALL_BUF_SIZE]; - assert (fm->tfm_name != NULL); + assert(fm->tfm_name != NULL); p = fm->tfm_name; - q = strchr (p, '@'); /* search for the first '@' */ + q = strchr(p, '@'); /* search for the first '@' */ if (q == NULL) return false; - r = strchr (q + 1, '@'); /* search for the second '@' */ + r = strchr(q + 1, '@'); /* search for the second '@' */ if (r == NULL) return false; if (q <= p || r <= q + 1 /* prefix or sfd name is empty */ - || r - p != strlen (p) - 1) /* or the second '@' is not the last char yet */ + || r - p != (int) strlen(p) - 1) /* or the second '@' is not the last char yet */ return false; l = r - (q + 1); /* length of sfd name */ - strncpy (buf, q + 1, l); + strncpy(buf, q + 1, l); buf[l] = 0; - check_buf(strlen(buf) + 4, SMALL_BUF_SIZE); - strcat (buf, ".sfd"); - sfd = read_sfd (buf); + check_buf(strlen(buf) + 4, SMALL_BUF_SIZE); + strcat(buf, ".sfd"); + sfd = read_sfd(buf); if (sfd == NULL) return false; /* at this point we know fm is a subfont */ - set_subfont (fm); - xfree (fm->ps_name); + set_subfont(fm); + xfree(fm->ps_name); fm->ps_name = NULL; /* set default values for PidEid */ if (fm->pid == -1) { @@ -246,19 +256,19 @@ boolean handle_subfont_fm (fm_entry * fm, int mode) } l = q - p; /* length of base tfm name (prefix) */ for (sf = sfd->subfont; sf != NULL; sf = sf->next) { - strncpy (buf, p, l); + strncpy(buf, p, l); buf[l] = 0; - strcat (buf, sf->infix); - fm2 = new_fm_entry (); - fm2->tfm_name = xstrdup (buf); - fm2->ff_name = xstrdup (fm->ff_name); + strcat(buf, sf->infix); + fm2 = new_fm_entry(); + fm2->tfm_name = xstrdup(buf); + fm2->ff_name = xstrdup(fm->ff_name); fm2->type = fm->type; fm2->pid = fm->pid; fm2->eid = fm->eid; fm2->subfont = sf; - if (avl_do_entry (fm2, mode) != 0) /* try to insert the entry */ - delete_fm_entry (fm2); /* delete it if failed */ + if (avl_do_entry(fm2, mode) != 0) /* try to insert the entry */ + delete_fm_entry(fm2); /* delete it if failed */ } - delete_fm_entry (fm); + delete_fm_entry(fm); return true; } diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.c b/Build/source/texk/web2c/luatexdir/font/texfont.c index 150c2cba769..1daf6a5b56b 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.c +++ b/Build/source/texk/web2c/luatexdir/font/texfont.c @@ -1,23 +1,21 @@ -/* - Copyright (c) 1996-2006 Taco Hoekwater - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - LuaTeX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with LuaTeX; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - $Id: texfont.c 1013 2008-02-14 00:09:02Z oneiros $ */ +/* texfont.c Main font API implementation for the pascal parts + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ /* Main font API implementation for the pascal parts */ @@ -36,6 +34,9 @@ #include "ptexlib.h" #include "luatex-api.h" +static const char _svn_version[] = + "$Id: texfont.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/texfont.c $"; + #define proper_char_index(c) (c<=font_ec(f) && c>=font_bc(f)) #define dxfree(a,b) { xfree(a); a = b ; } #define do_realloc(a,b,d) a = xrealloc(a,(b)*sizeof(d)) @@ -45,1050 +46,1460 @@ texfont **font_tables = NULL; static integer font_arr_max = 0; static integer font_id_maxval = 0; -static void grow_font_table (integer id) { - int j; - if (id>=font_arr_max) { - font_bytes += (font_arr_max-id+8)*sizeof(texfont *); - font_tables = xrealloc(font_tables,(id+8)*sizeof(texfont *)); - j = 8; - while (j--) { - font_tables[id+j] = NULL; +extern extinfo *get_charinfo_vert_variants(charinfo * ci); +extern extinfo *get_charinfo_hor_variants(charinfo * ci); +extern void set_charinfo_hor_variants(charinfo * ci, extinfo * ext); +extern void set_charinfo_vert_variants(charinfo * ci, extinfo * ext); + +extern extinfo *copy_variants(extinfo * o); + + +static void grow_font_table(integer id) +{ + int j; + if (id >= font_arr_max) { + font_bytes += (font_arr_max - id + 8) * sizeof(texfont *); + font_tables = xrealloc(font_tables, (id + 8) * sizeof(texfont *)); + j = 8; + while (j--) { + font_tables[id + j] = NULL; + } + font_arr_max = id + 8; } - font_arr_max = id+8; - } } -integer -new_font_id (void) { - int i; - for (i=0;i=font_arr_max) - grow_font_table (i); - if (i>font_id_maxval) + if (i >= font_arr_max) + grow_font_table(i); + if (i > font_id_maxval) + font_id_maxval = i; + return i; +} + +integer max_font_id(void) +{ + return font_id_maxval; +} + +void set_max_font_id(integer i) +{ font_id_maxval = i; - return i; -} - -integer -max_font_id (void) { - return font_id_maxval; -} - -void -set_max_font_id (integer i) { - font_id_maxval = i; -} - -integer -new_font (void) { - int k; - int id; - charinfo *ci; - id = new_font_id(); - font_bytes += sizeof(texfont); - /* most stuff is zero */ - font_tables[id] = xcalloc(1,sizeof(texfont)); - font_tables[id]->_font_name = NULL; - font_tables[id]->_font_area = NULL; - font_tables[id]->_font_filename = NULL; - font_tables[id]->_font_fullname = NULL; - font_tables[id]->_font_encodingname = NULL; - font_tables[id]->_font_cidregistry = NULL; - font_tables[id]->_font_cidordering = NULL; - font_tables[id]->_left_boundary = NULL; - font_tables[id]->_right_boundary = NULL; - font_tables[id]->_param_base = NULL; - - set_font_bc(id, 1); /* ec = 0 */ - set_hyphen_char(id,'-'); - set_skew_char(id,-1); - - /* allocate eight values including 0 */ - set_font_params(id,7); - for (k=0;k<=7;k++) { - set_font_param(id,k,0); - } - /* character info zero is reserved for notdef */ - font_tables[id]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ +} - ci = xcalloc(1,sizeof(charinfo)); - set_charinfo_name(ci,xstrdup(".notdef")); - font_tables[id]->charinfo = ci; - font_tables[id]->charinfo_cache = NULL; +integer new_font(void) +{ + int k; + int id; + charinfo *ci; + id = new_font_id(); + font_bytes += sizeof(texfont); + /* most stuff is zero */ + font_tables[id] = xcalloc(1, sizeof(texfont)); + font_tables[id]->_font_name = NULL; + font_tables[id]->_font_area = NULL; + font_tables[id]->_font_filename = NULL; + font_tables[id]->_font_fullname = NULL; + font_tables[id]->_font_encodingname = NULL; + font_tables[id]->_font_cidregistry = NULL; + font_tables[id]->_font_cidordering = NULL; + font_tables[id]->_left_boundary = NULL; + font_tables[id]->_right_boundary = NULL; + font_tables[id]->_param_base = NULL; + font_tables[id]->_math_param_base = NULL; + + set_font_bc(id, 1); /* ec = 0 */ + set_hyphen_char(id, '-'); + set_skew_char(id, -1); + + /* allocate eight values including 0 */ + set_font_params(id, 7); + for (k = 0; k <= 7; k++) { + set_font_param(id, k, 0); + } + /* character info zero is reserved for notdef */ + font_tables[id]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ + + ci = xcalloc(1, sizeof(charinfo)); + set_charinfo_name(ci, xstrdup(".notdef")); + font_tables[id]->charinfo = ci; + font_tables[id]->charinfo_cache = NULL; - return id; + return id; } #define Charinfo_count(a) font_tables[a]->charinfo_count #define Charinfo_size(a) font_tables[a]->charinfo_size #define Characters(a) font_tables[a]->characters -charinfo * -get_charinfo (internal_font_number f, integer c) { - sa_tree_item glyph; - charinfo *ci; - if (proper_char_index(c)) { - glyph = get_sa_item(Characters(f), c); - if (!glyph) { - /* this could be optimized using controlled growth */ - font_bytes += sizeof(charinfo); - glyph = ++font_tables[f]->charinfo_count; - do_realloc(font_tables[f]->charinfo, (glyph+1), charinfo); - memset (&(font_tables[f]->charinfo[glyph]),0,sizeof(charinfo)); - font_tables[f]->charinfo[glyph].ef = 1000; /* init */ - font_tables[f]->charinfo_size = glyph; - set_sa_item(font_tables[f]->characters, c, glyph, 1); /* 1= global */ - } - return &(font_tables[f]->charinfo[glyph]); - } else if (c == left_boundarychar) { - if (left_boundary(f)==NULL) { - ci = xcalloc(1,sizeof(charinfo)); - font_bytes += sizeof(charinfo); - set_left_boundary(f,ci); - } - return left_boundary(f); - } else if (c == right_boundarychar) { - if (right_boundary(f)==NULL) { - ci = xcalloc(1,sizeof(charinfo)); - font_bytes += sizeof(charinfo); - set_right_boundary(f,ci); - } - return right_boundary(f); - } - return &(font_tables[f]->charinfo[0]); +#define find_charinfo_id(f,c) get_sa_item(font_tables[f]->characters,c) + +charinfo *get_charinfo(internal_font_number f, integer c) +{ + sa_tree_item glyph; + charinfo *ci; + if (proper_char_index(c)) { + glyph = get_sa_item(Characters(f), c); + if (!glyph) { + /* this could be optimized using controlled growth */ + font_bytes += sizeof(charinfo); + glyph = ++font_tables[f]->charinfo_count; + do_realloc(font_tables[f]->charinfo, (glyph + 1), charinfo); + memset(&(font_tables[f]->charinfo[glyph]), 0, sizeof(charinfo)); + font_tables[f]->charinfo[glyph].ef = 1000; /* init */ + font_tables[f]->charinfo_size = glyph; + set_sa_item(font_tables[f]->characters, c, glyph, 1); /* 1= global */ + } + return &(font_tables[f]->charinfo[glyph]); + } else if (c == left_boundarychar) { + if (left_boundary(f) == NULL) { + ci = xcalloc(1, sizeof(charinfo)); + font_bytes += sizeof(charinfo); + set_left_boundary(f, ci); + } + return left_boundary(f); + } else if (c == right_boundarychar) { + if (right_boundary(f) == NULL) { + ci = xcalloc(1, sizeof(charinfo)); + font_bytes += sizeof(charinfo); + set_right_boundary(f, ci); + } + return right_boundary(f); + } + return &(font_tables[f]->charinfo[0]); +} + +void set_charinfo(internal_font_number f, integer c, charinfo * ci) +{ + sa_tree_item glyph; + if (proper_char_index(c)) { + glyph = get_sa_item(Characters(f), c); + if (glyph) { + font_tables[f]->charinfo[glyph] = *ci; + } else { + pdftex_fail("font: %s", "character insertion failed"); + } + } else if (c == left_boundarychar) { + set_left_boundary(f, ci); + } else if (c == right_boundarychar) { + set_right_boundary(f, ci); + } +} + + + +charinfo *copy_charinfo(charinfo * ci) +{ + int x; + kerninfo *kern; + liginfo *lig; + real_eight_bits *packet; + charinfo *co = NULL; + if (ci == NULL) + return NULL; + co = xmalloc(sizeof(charinfo)); + memcpy(co, ci, sizeof(charinfo)); + set_charinfo_used(co, false); + co->name = NULL; + co->tounicode = NULL; + co->packets = NULL; + co->ligatures = NULL; + co->kerns = NULL; + co->vert_variants = NULL; + co->hor_variants = NULL; + if (ci->name != NULL) { + co->name = xstrdup(ci->name); + } + if (ci->tounicode != NULL) { + co->tounicode = xstrdup(ci->tounicode); + } + /* kerns */ + if ((kern = get_charinfo_kerns(ci)) != NULL) { + x = 0; + while (!kern_end(kern[x])) { + x++; + } + x++; + co->kerns = xmalloc(x * sizeof(kerninfo)); + memcpy(co->kerns, ci->kerns, (x * sizeof(kerninfo))); + } + /* ligs */ + if ((lig = get_charinfo_ligatures(ci)) != NULL) { + x = 0; + while (!lig_end(lig[x])) { + x++; + } + x++; + co->ligatures = xmalloc(x * sizeof(liginfo)); + memcpy(co->ligatures, ci->ligatures, (x * sizeof(liginfo))); + } + /* packets */ + if ((packet = get_charinfo_packets(ci)) != NULL) { + x = vf_packet_bytes(ci); + co->packets = xmalloc(x); + memcpy(co->packets, ci->packets, x); + } + + /* horizontal and vertical extenders */ + if (get_charinfo_vert_variants(ci) != NULL) { + set_charinfo_vert_variants(co, + copy_variants(get_charinfo_vert_variants + (ci))); + } + if (get_charinfo_hor_variants(ci) != NULL) { + set_charinfo_hor_variants(co, + copy_variants(get_charinfo_hor_variants(ci))); + } + return co; +} + +charinfo *char_info(internal_font_number f, integer c) +{ + if (f > font_id_maxval) + return 0; + if (proper_char_index(c)) { + register int glyph = find_charinfo_id(f, c); + return &(font_tables[f]->charinfo[glyph]); + } else if (c == left_boundarychar && left_boundary(f) != NULL) { + return left_boundary(f); + } else if (c == right_boundarychar && right_boundary(f) != NULL) { + return right_boundary(f); + } + return &(font_tables[f]->charinfo[0]); +} + +charinfo_short char_info_short(internal_font_number f, integer c) +{ + charinfo_short s; + charinfo *i; + i = char_info(f, c); + s.ci_wd = i->width; + s.ci_dp = i->depth; + s.ci_ht = i->height; + return s; +} + +integer char_exists(internal_font_number f, integer c) +{ + if (f > font_id_maxval) + return 0; + if (proper_char_index(c)) { + return find_charinfo_id(f, c); + } else if ((c == left_boundarychar) && has_left_boundary(f)) { + return 1; + } else if ((c == right_boundarychar) && has_right_boundary(f)) { + return 1; + } + return 0; +} + +int lua_char_exists_callback(internal_font_number f, integer c) +{ + integer callback_id; + lua_State *L = Luas; + int ret = 0; + callback_id = callback_defined(char_exists_callback); + if (callback_id != 0) { + if (!get_callback(L, callback_id)) { + lua_pop(L, 2); + return 0; + } + lua_pushnumber(L, f); + lua_pushnumber(L, c); + if (lua_pcall(L, 2, 1, 0) != 0) { /* two args, 1 result */ + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 2); + error(); + } else { + ret = lua_toboolean(L, -1); + } + } + return ret; } -void -set_charinfo (internal_font_number f, integer c, charinfo *ci) { - sa_tree_item glyph; - if (proper_char_index(c)) { - glyph = get_sa_item(Characters(f), c); - if (glyph) { - font_tables[f]->charinfo[glyph] = *ci; + +extinfo *new_variant(int glyph, int startconnect, int endconnect, + int advance, int repeater) +{ + extinfo *ext; + ext = xmalloc(sizeof(extinfo)); + ext->next = NULL; + ext->glyph = glyph; + ext->start_overlap = startconnect; + ext->end_overlap = endconnect; + ext->advance = advance; + ext->extender = repeater; + return ext; +} + + +extinfo *copy_variant(extinfo * old) +{ + extinfo *ext; + ext = xmalloc(sizeof(extinfo)); + ext->next = NULL; + ext->glyph = old->glyph; + ext->start_overlap = old->start_overlap; + ext->end_overlap = old->end_overlap; + ext->advance = old->advance; + ext->extender = old->extender; + return ext; +} + +void dump_variant(extinfo * ext) +{ + dump_int(ext->glyph); + dump_int(ext->start_overlap); + dump_int(ext->end_overlap); + dump_int(ext->advance); + dump_int(ext->extender); + return; +} + + +extinfo *undump_variant(void) +{ + int x; + extinfo *ext; + undump_int(x); + if (x == 0) + return NULL; + ext = xmalloc(sizeof(extinfo)); + ext->next = NULL; + ext->glyph = x; + undump_int(x); + ext->start_overlap = x; + undump_int(x); + ext->end_overlap = x; + undump_int(x); + ext->advance = x; + undump_int(x); + ext->extender = x; + return ext; +} + +void add_charinfo_vert_variant(charinfo * ci, extinfo * ext) +{ + if (ci->vert_variants == NULL) { + ci->vert_variants = ext; } else { - pdftex_fail("font: %s","character insertion failed"); + extinfo *lst = ci->vert_variants; + while (lst->next != NULL) + lst = lst->next; + lst->next = ext; } - } else if (c == left_boundarychar) { - set_left_boundary(f,ci); - } else if (c == right_boundarychar) { - set_right_boundary(f,ci); - } + } +void add_charinfo_hor_variant(charinfo * ci, extinfo * ext) +{ + if (ci->hor_variants == NULL) { + ci->hor_variants = ext; + } else { + extinfo *lst = ci->hor_variants; + while (lst->next != NULL) + lst = lst->next; + lst->next = ext; + } +} -charinfo * -copy_charinfo (charinfo *ci) { - int x; - kerninfo *kern; - liginfo *lig; - real_eight_bits *packet; - charinfo *co = NULL; - if (ci==NULL) - return NULL; - co = xmalloc(sizeof(charinfo)); - memcpy(co,ci,sizeof(charinfo)); - set_charinfo_used(co,false); - co->name = NULL; - co->tounicode = NULL; - co->packets = NULL; - co->ligatures = NULL; - co->kerns = NULL; - co->extensible = NULL; - if (ci->name!=NULL) { - co->name = xstrdup(ci->name); - } - if (ci->tounicode!=NULL) { - co->tounicode = xstrdup(ci->tounicode); - } - /* kerns */ - if ((kern = get_charinfo_kerns(ci)) != NULL) { - x = 0; - while (!kern_end(kern[x])) { x++; } x++; - co->kerns = xmalloc (x*sizeof(kerninfo)); - memcpy(co->kerns,ci->kerns,(x*sizeof(kerninfo))); - } - /* ligs */ - if ((lig = get_charinfo_ligatures(ci)) != NULL) { - x = 0; - while (!lig_end(lig[x])) { x++; } x++; - co->ligatures = xmalloc (x*sizeof(liginfo)); - memcpy(co->ligatures,ci->ligatures,(x*sizeof(liginfo))); - } - /* packets */ - if ((packet = get_charinfo_packets(ci)) != NULL) { - x = vf_packet_bytes(ci); - co->packets = xmalloc (x); - memcpy(co->packets,ci->packets,x); - } - if (get_charinfo_tag(ci)==ext_tag) { - int top, bot, rep, mid; - top = get_charinfo_extensible(ci,EXT_TOP); - bot = get_charinfo_extensible(ci,EXT_BOT); - mid = get_charinfo_extensible(ci,EXT_MID); - rep = get_charinfo_extensible(ci,EXT_REP); - set_charinfo_extensible(co,top,bot,mid,rep); - } - return co; -} - -#if 0 -int -find_charinfo_id (internal_font_number f, integer c) { - register int g=0; - if (font_tables[f]->charinfo_cache==NULL) { - int i = (font_ec(f)+1)*sizeof(int); - font_tables[f]->charinfo_cache = xmalloc(i); - memset(font_tables[f]->charinfo_cache,0,i); - } else { - g = font_tables[f]->charinfo_cache[c]; - } - if (g==0) { - g = get_sa_item(font_tables[f]->characters, c); - font_tables[f]->charinfo_cache[c] = g; - } - return g; +extinfo *copy_variants(extinfo * o) +{ + extinfo *c, *t = NULL, *h = NULL; + while (o != NULL) { + c = copy_variant(o); + if (h == null) + h = c; + else + t->next = c; + t = c; + o = o->next; + } + + return h; } -#else -#define find_charinfo_id(f,c) get_sa_item(font_tables[f]->characters,c) -#endif - - -charinfo * -char_info (internal_font_number f, integer c) { - if (f>font_id_maxval) - return 0; - if (proper_char_index(c)) { - register int glyph = find_charinfo_id(f,c); - return &(font_tables[f]->charinfo[glyph]); - } else if (c == left_boundarychar && left_boundary(f)!=NULL) { - return left_boundary(f); - } else if (c == right_boundarychar && right_boundary(f)!=NULL) { - return right_boundary(f); - } - return &(font_tables[f]->charinfo[0]); -} - -charinfo_short -char_info_short (internal_font_number f, integer c) { - charinfo_short s; - charinfo *i; - i = char_info(f,c); - s.ci_wd = i->width; - s.ci_dp = i->depth; - s.ci_ht = i->height; - return s; -} - -integer -char_exists (internal_font_number f, integer c) { - if (f>font_id_maxval) - return 0; - if (proper_char_index(c)) { - return find_charinfo_id(f,c); - } else if ((c == left_boundarychar) && has_left_boundary(f)) { - return 1; - } else if ((c == right_boundarychar) && has_right_boundary(f)) { - return 1; - } - return 0; -} - -int -lua_char_exists_callback (internal_font_number f, integer c) { - integer callback_id ; - lua_State *L = Luas[0]; - int ret=0; - callback_id = callback_defined(char_exists_callback); - if (callback_id!=0) { - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1, callback_id); - if (!lua_isfunction(L,-1)) { - lua_pop(L,2); - return 0; - } - lua_pushnumber(L,f); - lua_pushnumber(L,c); - if (lua_pcall(L,2,1,0) != 0) { /* two args, 1 result */ - fprintf(stdout,"error: %s\n",lua_tostring(L,-1)); - lua_pop(L,2); - error(); - } else { - ret = lua_toboolean(L,-1); - } - } - return ret; -} - - -void set_charinfo_width (charinfo *ci, scaled val) { ci->width = val; } -void set_charinfo_height (charinfo *ci, scaled val) { ci->height = val; } -void set_charinfo_depth (charinfo *ci, scaled val) { ci->depth = val; } -void set_charinfo_italic (charinfo *ci, scaled val) { ci->italic = val; } -void set_charinfo_tag (charinfo *ci, scaled val) { ci->tag = val; } -void set_charinfo_remainder (charinfo *ci, scaled val) { ci->remainder = val; } -void set_charinfo_used (charinfo *ci, scaled val) { ci->used = val; } -void set_charinfo_index (charinfo *ci, scaled val) { ci->index = val; } -void set_charinfo_name (charinfo *ci, char *val) { dxfree(ci->name,val); } -void set_charinfo_tounicode (charinfo *ci, char *val) { dxfree(ci->tounicode,val); } -void set_charinfo_ligatures (charinfo *ci, liginfo *val) { dxfree(ci->ligatures,val); } -void set_charinfo_kerns (charinfo *ci, kerninfo *val) { dxfree(ci->kerns,val); } -void set_charinfo_packets (charinfo *ci, real_eight_bits *val){ dxfree(ci->packets,val); } -void set_charinfo_ef (charinfo *ci, scaled val) { ci->ef = val; } -void set_charinfo_lp (charinfo *ci, scaled val) { ci->lp = val; } -void set_charinfo_rp (charinfo *ci, scaled val) { ci->rp = val; } - - - -void set_charinfo_extensible (charinfo *ci, int top, int bot, int mid, int rep) { - if (top == 0 && bot == 0 && mid == 0 && rep == 0) { - if (ci->extensible != NULL) { - free(ci->extensible); - ci->extensible = NULL; - } - } else { - if (ci->extensible == NULL) { - ci->extensible = xmalloc(4*sizeof(integer)); - } - ci->extensible[EXT_TOP] = top; - ci->extensible[EXT_BOT] = bot; - ci->extensible[EXT_MID] = mid; - ci->extensible[EXT_REP] = rep; - } + + +void dump_charinfo_variants(extinfo * o) +{ + while (o != NULL) { + dump_variant(o); + o = o->next; + } + dump_int(0); + return; } - -scaled get_charinfo_width (charinfo *ci) { return ci->width; } -scaled get_charinfo_height (charinfo *ci) { return ci->height; } -scaled get_charinfo_depth (charinfo *ci) { return ci->depth; } -scaled get_charinfo_italic (charinfo *ci) { return ci->italic; } -char get_charinfo_tag (charinfo *ci) { return ci->tag; } -integer get_charinfo_remainder (charinfo *ci) { return ci->remainder; } -char get_charinfo_used (charinfo *ci) { return ci->used; } -integer get_charinfo_index (charinfo *ci) { return ci->index; } -char *get_charinfo_name (charinfo *ci) { return ci->name; } -char *get_charinfo_tounicode (charinfo *ci) { return ci->tounicode; } -liginfo *get_charinfo_ligatures (charinfo *ci) { return ci->ligatures; } -kerninfo *get_charinfo_kerns (charinfo *ci) { return ci->kerns; } -real_eight_bits *get_charinfo_packets (charinfo *ci) { return ci->packets; } -integer get_charinfo_ef (charinfo *ci) { return ci->ef; } -integer get_charinfo_rp (charinfo *ci) { return ci->rp; } -integer get_charinfo_lp (charinfo *ci) { return ci->lp; } -integer get_charinfo_extensible (charinfo *ci, int whch) { - int w = 0; - if (ci->extensible != NULL) - w = ci->extensible[whch]; - return w; +extinfo *undump_charinfo_variants(void) +{ + extinfo *c, *t, *h = NULL; + c = undump_variant(); + while (c != NULL) { + if (h == null) + h = c; + else + t->next = c; + t = c; + c = undump_variant(); + } + return h; } -integer ext_top (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - integer w = get_charinfo_extensible(ci,EXT_TOP); - /* fprintf(stdout,"top of char 0x%4x in font %s: %i\n",c,font_name(f),w);*/ - return w; -} -integer ext_bot (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - integer w = get_charinfo_extensible(ci,EXT_BOT); - /*fprintf(stdout,"bot of char 0x%4x in font %s: %i\n",c,font_name(f),w);*/ - return w; +void set_charinfo_width(charinfo * ci, scaled val) +{ + ci->width = val; } -integer ext_mid (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - integer w = get_charinfo_extensible(ci,EXT_MID); - /*fprintf(stdout,"mid of char 0x%4x in font %s: %i\n",c,font_name(f),w);*/ - return w; + +void set_charinfo_height(charinfo * ci, scaled val) +{ + ci->height = val; } -integer ext_rep (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - integer w = get_charinfo_extensible(ci,EXT_REP); - /*fprintf(stdout,"rep of char 0x%4x in font %s: %i\n",c,font_name(f),w);*/ - return w; + +void set_charinfo_depth(charinfo * ci, scaled val) +{ + ci->depth = val; } -scaled char_width (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - scaled w = get_charinfo_width(ci); - /*fprintf(stdout,"width of char 0x%x in font %s: %i\n",c,font_name(f),w);*/ - return w; -} - -scaled char_depth (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - scaled w = get_charinfo_depth(ci); - /*fprintf(stdout,"depth of char 0x%x in font %s: %i\n",c,font_name(f),w);*/ - return w; -} - -scaled char_height (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - scaled w = get_charinfo_height(ci); - /*fprintf(stdout,"height of char 0x%x in font %s: %i\n",c,font_name(f),w);*/ - return w; -} - -scaled char_italic (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_italic(ci); -} - -integer char_remainder (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_remainder(ci); -} - -char char_tag (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_tag(ci); -} - -char char_used (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_used(ci); -} - -char *char_name (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_name(ci); -} - -integer char_index (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_index(ci); -} - -liginfo * char_ligatures (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_ligatures(ci); -} - -kerninfo * char_kerns (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_kerns(ci); -} - -real_eight_bits * char_packets (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_packets(ci); -} - - -void -set_font_params(internal_font_number f, int b) { - int i; - i = font_params(f); - if (i!=b) { - font_bytes += (b-font_params(f))*sizeof(scaled); - do_realloc(param_base(f), (b+1), integer); - font_params(f) = b; - if (b>i) { - while (i_font_name = NULL; - font_tables[k]->_font_filename = NULL; - font_tables[k]->_font_fullname = NULL; - font_tables[k]->_font_encodingname = NULL; - font_tables[k]->_font_area = NULL; - font_tables[k]->_font_cidregistry = NULL; - font_tables[k]->_font_cidordering = NULL; - font_tables[k]->_left_boundary = NULL; - font_tables[k]->_right_boundary = NULL; - - set_font_name(k,xstrdup(font_name(f))); - if (font_filename(f)!= NULL) - set_font_filename(k,xstrdup(font_filename(f))); - if (font_fullname(f)!= NULL) - set_font_fullname(k,xstrdup(font_fullname(f))); - if (font_encodingname(f)!= NULL) - set_font_encodingname(k,xstrdup(font_encodingname(f))); - if (font_area(f)!= NULL) - set_font_area(k,xstrdup(font_area(f))); - if (font_cidregistry(f)!= NULL) - set_font_cidregistry(k,xstrdup(font_cidregistry(f))); - if (font_cidordering(f)!= NULL) - set_font_cidordering(k,xstrdup(font_cidordering(f))); - - i = sizeof(*param_base(f))*font_params(f); - font_bytes += i; - param_base(k) = xmalloc (i); - memcpy(param_base(k),param_base(f), i); - - i = sizeof(charinfo)*(Charinfo_size(f)+1); - font_bytes += i; - font_tables[k]->charinfo = xmalloc(i); - memset(font_tables[k]->charinfo,0,i); - for(i=0;i<=Charinfo_size(k);i++) { - ci = copy_charinfo(&font_tables[f]->charinfo[i]); - font_tables[k]->charinfo[i] = *ci; - } - - if (left_boundary(f)!= NULL ) { - ci = copy_charinfo(left_boundary(f)); - set_charinfo(k,left_boundarychar,ci); - } +void set_charinfo_italic(charinfo * ci, scaled val) +{ + ci->italic = val; +} - if (right_boundary(f)!= NULL ) { - ci = copy_charinfo(right_boundary(f)); - set_charinfo(k,right_boundarychar,ci); - } - return k; -} - -void delete_font (integer f) { - int i; - charinfo *co; - assert(f>0); - if (font_tables[f]!=NULL) { - set_font_name(f,NULL); - set_font_filename(f,NULL); - set_font_fullname(f,NULL); - set_font_encodingname(f,NULL); - set_font_area(f,NULL); - set_font_cidregistry(f,NULL); - set_font_cidordering(f,NULL); - set_left_boundary(f,NULL); - set_right_boundary(f,NULL); - - for(i=font_bc(f); i<=font_ec(f); i++) { - if (char_exists(f,i)) { - co = char_info(f,i); - set_charinfo_name(co,NULL); - set_charinfo_tounicode(co,NULL); - set_charinfo_packets(co,NULL); - set_charinfo_ligatures(co,NULL); - set_charinfo_kerns(co,NULL); - set_charinfo_extensible(co,0,0,0,0); - } - } - /* free .notdef */ - set_charinfo_name(font_tables[f]->charinfo+0,NULL); - free(font_tables[f]->charinfo); - destroy_sa_tree(font_tables[f]->characters); - - free(param_base(f)); - free(font_tables[f]); - font_tables[f] = NULL; +void set_charinfo_top_accent(charinfo * ci, scaled val) +{ + ci->top_accent = val; +} + +void set_charinfo_bot_accent(charinfo * ci, scaled val) +{ + ci->bot_accent = val; +} + +void set_charinfo_tag(charinfo * ci, scaled val) +{ + ci->tag = val; +} + +void set_charinfo_remainder(charinfo * ci, scaled val) +{ + ci->remainder = val; +} + +void set_charinfo_used(charinfo * ci, scaled val) +{ + ci->used = val; +} - if (font_id_maxval==f) { - font_id_maxval--; +void set_charinfo_index(charinfo * ci, scaled val) +{ + ci->index = val; +} +void set_charinfo_name(charinfo * ci, char *val) +{ + dxfree(ci->name, val); +} +void set_charinfo_tounicode(charinfo * ci, char *val) +{ + dxfree(ci->tounicode, val); +} + +void set_charinfo_ligatures(charinfo * ci, liginfo * val) +{ + dxfree(ci->ligatures, val); +} + +void set_charinfo_kerns(charinfo * ci, kerninfo * val) +{ + dxfree(ci->kerns, val); +} + +void set_charinfo_packets(charinfo * ci, real_eight_bits * val) +{ + dxfree(ci->packets, val); +} + +void set_charinfo_ef(charinfo * ci, scaled val) +{ + ci->ef = val; +} + +void set_charinfo_lp(charinfo * ci, scaled val) +{ + ci->lp = val; +} + +void set_charinfo_rp(charinfo * ci, scaled val) +{ + ci->rp = val; +} + +void set_charinfo_vert_variants(charinfo * ci, extinfo * ext) +{ + extinfo *c, *lst; + if (ci->vert_variants != NULL) { + lst = ci->vert_variants; + while (lst != NULL) { + c = lst->next; + free(lst); + lst = c; + } } - } + ci->vert_variants = ext; +} + +void set_charinfo_hor_variants(charinfo * ci, extinfo * ext) +{ + extinfo *c, *lst; + if (ci->hor_variants != NULL) { + lst = ci->hor_variants; + while (lst != NULL) { + c = lst->next; + free(lst); + lst = c; + } + } + ci->hor_variants = ext; + +} + +/* In TeX, extensibles were fairly simple things. + This function squeezes a TFM extensible into the vertical extender structures. + |advance==0| is a special case for TFM fonts, because finding the proper + advance width during tfm reading can be tricky +*/ + +/* a small complication arises if |rep| is the only non-zero: it needs to be + doubled as a non-repeatable to avoid mayhem */ + +void set_charinfo_extensible(charinfo * ci, int top, int bot, int mid, int rep) +{ + extinfo *ext; + set_charinfo_vert_variants(ci, NULL); /* clear old */ + if (bot == 0 && top == 0 && mid == 0 && rep != 0) { + ext = new_variant(rep, 0, 0, 0, EXT_NORMAL); + add_charinfo_vert_variant(ci, ext); + ext = new_variant(rep, 0, 0, 0, EXT_REPEAT); + add_charinfo_vert_variant(ci, ext); + return; + } + if (bot != 0) { + ext = new_variant(bot, 0, 0, 0, EXT_NORMAL); + add_charinfo_vert_variant(ci, ext); + } + if (rep != 0) { + ext = new_variant(rep, 0, 0, 0, EXT_REPEAT); + add_charinfo_vert_variant(ci, ext); + } + if (mid != 0) { + ext = new_variant(mid, 0, 0, 0, EXT_NORMAL); + add_charinfo_vert_variant(ci, ext); + if (rep != 0) { + ext = new_variant(rep, 0, 0, 0, EXT_REPEAT); + add_charinfo_vert_variant(ci, ext); + } + } + if (top != 0) { + ext = new_variant(top, 0, 0, 0, EXT_NORMAL); + add_charinfo_vert_variant(ci, ext); + } +} + +scaled get_charinfo_width(charinfo * ci) +{ + return ci->width; +} + +scaled get_charinfo_height(charinfo * ci) +{ + return ci->height; +} + +scaled get_charinfo_depth(charinfo * ci) +{ + return ci->depth; +} + +scaled get_charinfo_italic(charinfo * ci) +{ + return ci->italic; +} + +scaled get_charinfo_top_accent(charinfo * ci) +{ + return ci->top_accent; +} + +scaled get_charinfo_bot_accent(charinfo * ci) +{ + return ci->bot_accent; +} + +char get_charinfo_tag(charinfo * ci) +{ + return ci->tag; +} + +integer get_charinfo_remainder(charinfo * ci) +{ + return ci->remainder; } -void -create_null_font (void) { - int i = new_font(); - assert(i==0); - set_font_name(i,xstrdup("nullfont")); - set_font_area(i,xstrdup("")); - set_font_touched(i,1); +char get_charinfo_used(charinfo * ci) +{ + return ci->used; } -boolean -is_valid_font (integer id) { - int ret=0; - if (id>=0 && id<=font_id_maxval && font_tables[id]!=NULL) - ret=1; - return ret; +integer get_charinfo_index(charinfo * ci) +{ + return ci->index; +} + +char *get_charinfo_name(charinfo * ci) +{ + return ci->name; +} + +char *get_charinfo_tounicode(charinfo * ci) +{ + return ci->tounicode; +} + +liginfo *get_charinfo_ligatures(charinfo * ci) +{ + return ci->ligatures; +} + +kerninfo *get_charinfo_kerns(charinfo * ci) +{ + return ci->kerns; +} + +real_eight_bits *get_charinfo_packets(charinfo * ci) +{ + return ci->packets; +} + +integer get_charinfo_ef(charinfo * ci) +{ + return ci->ef; +} + +integer get_charinfo_rp(charinfo * ci) +{ + return ci->rp; +} + +integer get_charinfo_lp(charinfo * ci) +{ + return ci->lp; +} + +extinfo *get_charinfo_vert_variants(charinfo * ci) +{ + extinfo *w = NULL; + if (ci->vert_variants != NULL) + w = ci->vert_variants; + return w; +} + +extinfo *get_charinfo_hor_variants(charinfo * ci) +{ + extinfo *w = NULL; + if (ci->hor_variants != NULL) + w = ci->hor_variants; + return w; +} + + +scaled char_width(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + scaled w = get_charinfo_width(ci); + /*fprintf(stdout,"width of char 0x%x in font %s: %i\n",c,font_name(f),w); */ + return w; +} + +scaled char_depth(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + scaled w = get_charinfo_depth(ci); + /*fprintf(stdout,"depth of char 0x%x in font %s: %i\n",c,font_name(f),w); */ + return w; +} + +scaled char_height(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + scaled w = get_charinfo_height(ci); + /*fprintf(stdout,"height of char 0x%x in font %s: %i\n",c,font_name(f),w); */ + return w; +} + +scaled char_italic(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_italic(ci); +} + +scaled char_top_accent(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_top_accent(ci); +} + +scaled char_bot_accent(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_bot_accent(ci); +} + + +integer char_remainder(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_remainder(ci); +} + +char char_tag(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_tag(ci); +} + +char char_used(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_used(ci); +} + +char *char_name(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_name(ci); +} + +integer char_index(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_index(ci); +} + +liginfo *char_ligatures(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_ligatures(ci); +} + +kerninfo *char_kerns(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_kerns(ci); +} + +real_eight_bits *char_packets(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_packets(ci); +} + + +void set_font_params(internal_font_number f, int b) +{ + int i; + i = font_params(f); + if (i != b) { + font_bytes += (b - font_params(f) + 1) * sizeof(scaled); + do_realloc(param_base(f), (b + 2), integer); + font_params(f) = b; + if (b > i) { + while (i < b) { + i++; + set_font_param(f, i, 0); + } + } + } +} + +void set_font_math_params(internal_font_number f, int b) +{ + int i; + i = font_math_params(f); + if (i != b) { + font_bytes += (b - font_math_params(f) + 1) * sizeof(scaled); + do_realloc(math_param_base(f), (b + 2), integer); + font_math_params(f) = b; + if (b > i) { + while (i < b) { + i++; + set_font_math_param(f, i, undefined_math_parameter); + } + } + } +} + + + +integer copy_font(integer f) +{ + int i; + charinfo *ci; + integer k = new_font(); + memcpy(font_tables[k], font_tables[f], sizeof(texfont)); + + set_font_cache_id(k, 0); + set_font_used(k, 0); + set_font_touched(k, 0); + + font_tables[k]->_font_name = NULL; + font_tables[k]->_font_filename = NULL; + font_tables[k]->_font_fullname = NULL; + font_tables[k]->_font_encodingname = NULL; + font_tables[k]->_font_area = NULL; + font_tables[k]->_font_cidregistry = NULL; + font_tables[k]->_font_cidordering = NULL; + font_tables[k]->_left_boundary = NULL; + font_tables[k]->_right_boundary = NULL; + + set_font_name(k, xstrdup(font_name(f))); + if (font_filename(f) != NULL) + set_font_filename(k, xstrdup(font_filename(f))); + if (font_fullname(f) != NULL) + set_font_fullname(k, xstrdup(font_fullname(f))); + if (font_encodingname(f) != NULL) + set_font_encodingname(k, xstrdup(font_encodingname(f))); + if (font_area(f) != NULL) + set_font_area(k, xstrdup(font_area(f))); + if (font_cidregistry(f) != NULL) + set_font_cidregistry(k, xstrdup(font_cidregistry(f))); + if (font_cidordering(f) != NULL) + set_font_cidordering(k, xstrdup(font_cidordering(f))); + + i = sizeof(*param_base(f)) * font_params(f); + font_bytes += i; + param_base(k) = xmalloc(i); + memcpy(param_base(k), param_base(f), i); + + if (font_math_params(f) > 0) { + i = sizeof(*math_param_base(f)) * font_math_params(f); + font_bytes += i; + math_param_base(k) = xmalloc(i); + memcpy(math_param_base(k), math_param_base(f), i); + } + + i = sizeof(charinfo) * (Charinfo_size(f) + 1); + font_bytes += i; + font_tables[k]->charinfo = xmalloc(i); + memset(font_tables[k]->charinfo, 0, i); + for (i = 0; i <= Charinfo_size(k); i++) { + ci = copy_charinfo(&font_tables[f]->charinfo[i]); + font_tables[k]->charinfo[i] = *ci; + } + + if (left_boundary(f) != NULL) { + ci = copy_charinfo(left_boundary(f)); + set_charinfo(k, left_boundarychar, ci); + } + + if (right_boundary(f) != NULL) { + ci = copy_charinfo(right_boundary(f)); + set_charinfo(k, right_boundarychar, ci); + } + return k; +} + +void delete_font(integer f) +{ + int i; + charinfo *co; + assert(f > 0); + if (font_tables[f] != NULL) { + set_font_name(f, NULL); + set_font_filename(f, NULL); + set_font_fullname(f, NULL); + set_font_encodingname(f, NULL); + set_font_area(f, NULL); + set_font_cidregistry(f, NULL); + set_font_cidordering(f, NULL); + set_left_boundary(f, NULL); + set_right_boundary(f, NULL); + + for (i = font_bc(f); i <= font_ec(f); i++) { + if (char_exists(f, i)) { + co = char_info(f, i); + set_charinfo_name(co, NULL); + set_charinfo_tounicode(co, NULL); + set_charinfo_packets(co, NULL); + set_charinfo_ligatures(co, NULL); + set_charinfo_kerns(co, NULL); + set_charinfo_vert_variants(co, NULL); + set_charinfo_hor_variants(co, NULL); + } + } + /* free .notdef */ + set_charinfo_name(font_tables[f]->charinfo + 0, NULL); + free(font_tables[f]->charinfo); + destroy_sa_tree(font_tables[f]->characters); + + free(param_base(f)); + if (math_param_base(f) != NULL) + free(math_param_base(f)); + free(font_tables[f]); + font_tables[f] = NULL; + + if (font_id_maxval == f) { + font_id_maxval--; + } + } +} + +void create_null_font(void) +{ + int i = new_font(); + assert(i == 0); + set_font_name(i, xstrdup("nullfont")); + set_font_area(i, xstrdup("")); + set_font_touched(i, 1); +} + +boolean is_valid_font(integer id) +{ + int ret = 0; + if (id >= 0 && id <= font_id_maxval && font_tables[id] != NULL) + ret = 1; + return ret; } /* return 1 == identical */ -boolean -cmp_font_name (integer id, strnumber t) { - char *tid , *tt; - if (!is_valid_font(id)) - return 0; - tt = makecstring(t); - tid = font_name(id); - if (tt == NULL && tid == NULL) +boolean cmp_font_name(integer id, strnumber t) +{ + char *tid, *tt; + if (!is_valid_font(id)) + return 0; + tt = makecstring(t); + tid = font_name(id); + if (tt == NULL && tid == NULL) + return 1; + if (tt == NULL || tid == NULL || strcmp(tid, tt) != 0) + return 0; return 1; - if (tt == NULL || tid == NULL || strcmp(tid,tt)!=0) - return 0; - return 1; -} - -boolean -cmp_font_area (integer id, strnumber t) { - char *tt = NULL; - char *tid = font_area(id); - if (t == 0) { - if (tid == NULL || strlen(tid)==0) - return 1; - else - return 0; - } - tt = makecstring(t); - if ((tt == NULL || strlen(tt)==0) && (tid == NULL || strlen(tid)==0)) +} + +boolean cmp_font_area(integer id, strnumber t) +{ + char *tt = NULL; + char *tid = font_area(id); + if (t == 0) { + if (tid == NULL || strlen(tid) == 0) + return 1; + else + return 0; + } + tt = makecstring(t); + if ((tt == NULL || strlen(tt) == 0) && (tid == NULL || strlen(tid) == 0)) + return 1; + if (tt == NULL || strcmp(tid, tt) != 0) + return 0; return 1; - if (tt == NULL || strcmp(tid,tt)!=0) - return 0; - return 1; } -static boolean -same_font_name (integer id, integer t) { - int ret = 0; - if (font_name(t) == NULL || - font_name(id) == NULL || - strcmp(font_name(t),font_name(id))!=0) { - ; - } else { - ret =1 ; - } - return ret; -} - -boolean -font_shareable (internal_font_number f, internal_font_number k) { - int ret = 0; - if (font_cidregistry(f) == NULL) { - if ( hasfmentry ( k ) - && ( font_map ( k ) == font_map ( f ) ) - && ( same_font_name ( k , f ) - || - ( pdf_font_auto_expand (f) - && ( pdf_font_blink (f) != 0 ) /* 0 = nullfont */ - && same_font_name ( k , pdf_font_blink (f) ) ) ) ) { - ret = 1; - } - } else { - if ((font_filename(k) != NULL && font_filename(f) != NULL && - strcmp(font_filename(k),font_filename(f)) == 0) - || - ( pdf_font_auto_expand (f) - && ( pdf_font_blink (f) != 0 ) /* 0 = nullfont */ - && same_font_name ( k , pdf_font_blink (f) ) ) ) { - ret = 1; +static boolean same_font_name(integer id, integer t) +{ + int ret = 0; + if (font_name(t) == NULL || + font_name(id) == NULL || strcmp(font_name(t), font_name(id)) != 0) { + ; + } else { + ret = 1; } - } - return ret; -} - -integer -test_no_ligatures (internal_font_number f) { - integer c; - for (c=font_bc(f);c<=font_ec(f);c++) { - if (has_lig(f,c)) /* char_exists(f,c) */ - return 0; - } - return 1; -} - -integer -get_tag_code (internal_font_number f, integer c) { - small_number i; - if (char_exists(f,c)) { - i = char_tag(f,c); - if (i==lig_tag) return 1; - else if (i==list_tag) return 2; - else if (i==ext_tag) return 4; - else return 0; - } - return -1; -} - -integer -get_lp_code (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_lp(ci); -} - -integer -get_rp_code (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_rp(ci); -} - -integer -get_ef_code (internal_font_number f, integer c) { - charinfo *ci = char_info(f,c); - return get_charinfo_ef(ci); -} - -void -set_tag_code (internal_font_number f, integer c, integer i) { - integer fixedi; - charinfo * co; - if (char_exists(f,c)) { - /* abs(fix_int(i-7,0)) */ - fixedi = - (i<-7 ? -7 : (i>0 ? 0 : i )) ; - co = char_info(f,c); - if (fixedi >= 4) { - if (char_tag(f,c) == ext_tag) - set_charinfo_tag(co,(char_tag(f,c)- ext_tag)); - fixedi = fixedi - 4; - } - if (fixedi >= 2) { - if (char_tag(f,c) == list_tag) - set_charinfo_tag(co,(char_tag(f,c)- list_tag)); - fixedi = fixedi - 2; - }; - if (fixedi >= 1) { - if (has_lig(f,c)) - set_charinfo_ligatures(co,NULL); - if (has_kern(f,c)) - set_charinfo_kerns(co,NULL); + return ret; +} + +boolean font_shareable(internal_font_number f, internal_font_number k) +{ + int ret = 0; + /* For some lua-loaded (for instance AFM) fonts, it is normal to have + a zero cidregistry, and such fonts do not have a fontmap entry yet + at this point, so the test shoulh use the other branch */ + if (font_cidregistry(f) == NULL && font_cidregistry(k) == NULL && + font_encodingbytes(f) != 2 && font_encodingbytes(k) != 2) { + if (hasfmentry(k) + && (font_map(k) == font_map(f)) + && (same_font_name(k, f) + || (pdf_font_auto_expand(f) + && (pdf_font_blink(f) != 0) /* 0 = nullfont */ + &&same_font_name(k, pdf_font_blink(f))))) { + ret = 1; + } + } else { + if ((font_filename(k) != NULL && font_filename(f) != NULL && + strcmp(font_filename(k), font_filename(f)) == 0) + || (pdf_font_auto_expand(f) + && (pdf_font_blink(f) != 0) /* 0 = nullfont */ + &&same_font_name(k, pdf_font_blink(f)))) { + ret = 1; + } } - } + return ret; } +integer test_no_ligatures(internal_font_number f) +{ + integer c; + for (c = font_bc(f); c <= font_ec(f); c++) { + if (has_lig(f, c)) /* char_exists(f,c) */ + return 0; + } + return 1; +} -void -set_lp_code(internal_font_number f, integer c, integer i) { - charinfo * co; - if (char_exists(f,c)) { - co = char_info(f,c); - set_charinfo_lp(co,i); - } +integer get_tag_code(internal_font_number f, integer c) +{ + small_number i; + if (char_exists(f, c)) { + i = char_tag(f, c); + if (i == lig_tag) + return 1; + else if (i == list_tag) + return 2; + else if (i == ext_tag) + return 4; + else + return 0; + } + return -1; } -void -set_rp_code(internal_font_number f, integer c, integer i) { - charinfo * co; - if (char_exists(f,c)) { - co = char_info(f,c); - set_charinfo_rp(co,i); - } +integer get_lp_code(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_lp(ci); } -void -set_ef_code(internal_font_number f, integer c, integer i) { - charinfo * co; - if (char_exists(f,c)) { - co = char_info(f,c); - set_charinfo_ef(co,i); - } +integer get_rp_code(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_rp(ci); } -void -set_no_ligatures (internal_font_number f) { - integer c; - charinfo * co; - - if (font_tables[f]->ligatures_disabled) - return; - - co = char_info(f,left_boundarychar); - set_charinfo_ligatures(co,NULL); - co = char_info(f,right_boundarychar); /* this is weird */ - set_charinfo_ligatures(co,NULL); - for (c=0;ccharinfo_count;c++) { - co = font_tables[f]->charinfo+c; - set_charinfo_ligatures(co,NULL); - } - font_tables[f]->ligatures_disabled =1; +integer get_ef_code(internal_font_number f, integer c) +{ + charinfo *ci = char_info(f, c); + return get_charinfo_ef(ci); +} + +void set_tag_code(internal_font_number f, integer c, integer i) +{ + integer fixedi; + charinfo *co; + if (char_exists(f, c)) { + /* abs(fix_int(i-7,0)) */ + fixedi = -(i < -7 ? -7 : (i > 0 ? 0 : i)); + co = char_info(f, c); + if (fixedi >= 4) { + if (char_tag(f, c) == ext_tag) + set_charinfo_tag(co, (char_tag(f, c) - ext_tag)); + fixedi = fixedi - 4; + } + if (fixedi >= 2) { + if (char_tag(f, c) == list_tag) + set_charinfo_tag(co, (char_tag(f, c) - list_tag)); + fixedi = fixedi - 2; + }; + if (fixedi >= 1) { + if (has_lig(f, c)) + set_charinfo_ligatures(co, NULL); + if (has_kern(f, c)) + set_charinfo_kerns(co, NULL); + } + } } -liginfo -get_ligature (internal_font_number f, integer lc, integer rc) { - liginfo t, u; - charinfo * co; - t.lig = 0; - t.type = 0; - t.adj = 0; - if (lc == non_boundarychar || rc == non_boundarychar || (!has_lig(f,lc)) ) + +void set_lp_code(internal_font_number f, integer c, integer i) +{ + charinfo *co; + if (char_exists(f, c)) { + co = char_info(f, c); + set_charinfo_lp(co, i); + } +} + +void set_rp_code(internal_font_number f, integer c, integer i) +{ + charinfo *co; + if (char_exists(f, c)) { + co = char_info(f, c); + set_charinfo_rp(co, i); + } +} + +void set_ef_code(internal_font_number f, integer c, integer i) +{ + charinfo *co; + if (char_exists(f, c)) { + co = char_info(f, c); + set_charinfo_ef(co, i); + } +} + +void set_no_ligatures(internal_font_number f) +{ + integer c; + charinfo *co; + + if (font_tables[f]->ligatures_disabled) + return; + + co = char_info(f, left_boundarychar); + set_charinfo_ligatures(co, NULL); + co = char_info(f, right_boundarychar); /* this is weird */ + set_charinfo_ligatures(co, NULL); + for (c = 0; c < font_tables[f]->charinfo_count; c++) { + co = font_tables[f]->charinfo + c; + set_charinfo_ligatures(co, NULL); + } + font_tables[f]->ligatures_disabled = 1; +} + +liginfo get_ligature(internal_font_number f, integer lc, integer rc) +{ + liginfo t, u; + charinfo *co; + t.lig = 0; + t.type = 0; + t.adj = 0; + if (lc == non_boundarychar || rc == non_boundarychar || (!has_lig(f, lc))) + return t; + k = 0; + co = char_info(f, lc); + while (1) { + u = charinfo_ligature(co, k); + if (lig_end(u)) + break; + if (lig_char(u) == rc) { + if (lig_disabled(u)) { + return t; + } else { + return u; + } + } + k++; + } return t; - k = 0; - co = char_info(f,lc); - while (1) { - u = charinfo_ligature(co,k); - if (lig_end(u)) - break; - if (lig_char(u) == rc) { - if (lig_disabled(u)) { - return t; - } else { - return u; - } - } - k++; - } - return t; } -scaled -get_kern(internal_font_number f, integer lc, integer rc) +scaled raw_get_kern(internal_font_number f, integer lc, integer rc) { - integer k; - kerninfo u; - charinfo * co; - if (lc == non_boundarychar || rc == non_boundarychar || (!has_kern(f,lc)) ) + integer k; + kerninfo u; + charinfo *co; + if (lc == non_boundarychar || rc == non_boundarychar) + return 0; + k = 0; + co = char_info(f, lc); + while (1) { + u = charinfo_kern(co, k); + if (kern_end(u)) + break; + if (kern_char(u) == rc) { + if (kern_disabled(u)) + return 0; + else + return kern_kern(u); + } + k++; + } return 0; - k = 0; - co = char_info(f,lc); - while (1) { - u = charinfo_kern(co,k); - if (kern_end(u)) - break; - if (kern_char(u) == rc) { - if (kern_disabled(u)) - return 0; - else - return kern_kern(u); - } - k++; - } - return 0; +} + + +scaled get_kern(internal_font_number f, integer lc, integer rc) +{ + if (lc == non_boundarychar || rc == non_boundarychar || (!has_kern(f, lc))) + return 0; + return raw_get_kern(f, lc, rc); } /* dumping and undumping fonts */ -#define dump_string(a) \ - if (a!=NULL) { \ - x = strlen(a)+1; \ - dump_int(x); dump_things(*a, x); \ - } else { \ - x = 0; dump_int(x); \ +#define dump_string(a) \ + if (a!=NULL) { \ + x = strlen(a)+1; \ + dump_int(x); dump_things(*a, x); \ + } else { \ + x = 0; dump_int(x); \ } -void -dump_charinfo (int f , int c) { - charinfo *co; - int x; - liginfo *lig; - kerninfo *kern; - - dump_int(c); - co = char_info(f,c); - set_charinfo_used(co,0); - dump_int(get_charinfo_width(co)); - dump_int(get_charinfo_height(co)); - dump_int(get_charinfo_depth(co)); - dump_int(get_charinfo_italic(co)); - dump_int(get_charinfo_tag(co)); - dump_int(get_charinfo_ef(co)); - dump_int(get_charinfo_rp(co)); - dump_int(get_charinfo_lp(co)); - dump_int(get_charinfo_remainder(co)); - dump_int(get_charinfo_used(co)); - dump_int(get_charinfo_index(co)); - dump_string(get_charinfo_name(co)); - dump_string(get_charinfo_tounicode(co)); - - /* ligatures */ - x = 0; - if ((lig = get_charinfo_ligatures(co)) != NULL) { - while (!lig_end(lig[x])) { x++; } - x++; - dump_int(x); dump_things(*lig, x); - } else { +void dump_charinfo(int f, int c) +{ + charinfo *co; + int x; + liginfo *lig; + kerninfo *kern; + dump_int(c); + co = char_info(f, c); + set_charinfo_used(co, 0); + dump_int(get_charinfo_width(co)); + dump_int(get_charinfo_height(co)); + dump_int(get_charinfo_depth(co)); + dump_int(get_charinfo_italic(co)); + dump_int(get_charinfo_top_accent(co)); + dump_int(get_charinfo_bot_accent(co)); + dump_int(get_charinfo_tag(co)); + dump_int(get_charinfo_ef(co)); + dump_int(get_charinfo_rp(co)); + dump_int(get_charinfo_lp(co)); + dump_int(get_charinfo_remainder(co)); + dump_int(get_charinfo_used(co)); + dump_int(get_charinfo_index(co)); + dump_string(get_charinfo_name(co)); + dump_string(get_charinfo_tounicode(co)); + + /* ligatures */ + x = 0; + if ((lig = get_charinfo_ligatures(co)) != NULL) { + while (!lig_end(lig[x])) { + x++; + } + x++; + dump_int(x); + dump_things(*lig, x); + } else { + dump_int(x); + } + /* kerns */ + x = 0; + if ((kern = get_charinfo_kerns(co)) != NULL) { + while (!kern_end(kern[x])) { + x++; + } + x++; + dump_int(x); + dump_things(*kern, x); + } else { + dump_int(x); + } + /* packets */ + x = vf_packet_bytes(co); dump_int(x); - } - /* kerns */ - x = 0; - if ((kern = get_charinfo_kerns(co)) != NULL) { - while (!kern_end(kern[x])) { x++; } - x++; - dump_int(x); dump_things(*kern, x); - } else { - dump_int(x); - } - /* packets */ - x= vf_packet_bytes(co); - dump_int(x); - if (x>0) { - dump_things(*get_charinfo_packets(co), x); - } + if (x > 0) { + dump_things(*get_charinfo_packets(co), x); + } - if (get_charinfo_tag(co)==ext_tag) { - x = get_charinfo_extensible(co,EXT_TOP); dump_int(x); - x = get_charinfo_extensible(co,EXT_BOT); dump_int(x); - x = get_charinfo_extensible(co,EXT_MID); dump_int(x); - x = get_charinfo_extensible(co,EXT_REP); dump_int(x); - } + if (get_charinfo_tag(co) == ext_tag) { + dump_charinfo_variants(get_charinfo_vert_variants(co)); + dump_charinfo_variants(get_charinfo_hor_variants(co)); + } } -void -dump_font (int f) { - int i,x; - - set_font_used(f,0); - font_tables[f]->charinfo_cache = NULL; - dump_things(*(font_tables[f]), 1); - dump_string(font_name(f)); - dump_string(font_area(f)); - dump_string(font_filename(f)); - dump_string(font_fullname(f)); - dump_string(font_encodingname(f)); - dump_string(font_cidregistry(f)); - dump_string(font_cidordering(f)); - - dump_things(*param_base(f),(font_params(f)+1)); - - if (has_left_boundary(f)) { - dump_int(1); dump_charinfo(f,left_boundarychar); - } else { - dump_int(0); - } - if (has_right_boundary(f)) { - dump_int(1); dump_charinfo(f,right_boundarychar); - } else { - dump_int(0); - } +void dump_font(int f) +{ + int i, x; + + set_font_used(f, 0); + font_tables[f]->charinfo_cache = NULL; + dump_things(*(font_tables[f]), 1); + dump_string(font_name(f)); + dump_string(font_area(f)); + dump_string(font_filename(f)); + dump_string(font_fullname(f)); + dump_string(font_encodingname(f)); + dump_string(font_cidregistry(f)); + dump_string(font_cidordering(f)); + + dump_things(*param_base(f), (font_params(f) + 1)); + + if (font_math_params(f) > 0) { + dump_things(*math_param_base(f), (font_math_params(f))); + } + if (has_left_boundary(f)) { + dump_int(1); + dump_charinfo(f, left_boundarychar); + } else { + dump_int(0); + } + if (has_right_boundary(f)) { + dump_int(1); + dump_charinfo(f, right_boundarychar); + } else { + dump_int(0); + } - for(i=font_bc(f); i<=font_ec(f); i++) { - if (char_exists(f,i)) { - dump_charinfo(f,i); + for (i = font_bc(f); i <= font_ec(f); i++) { + if (char_exists(f, i)) { + dump_charinfo(f, i); + } } - } } -int -undump_charinfo (int f) { - charinfo *co; - int x,i; - char *s = NULL; - liginfo *lig = NULL; - kerninfo *kern = NULL; - real_eight_bits *packet = NULL; - int top = 0, bot = 0, mid = 0, rep = 0; - - undump_int(i); - co = get_charinfo(f,i); - undump_int(x); set_charinfo_width(co,x); - undump_int(x); set_charinfo_height(co,x); - undump_int(x); set_charinfo_depth(co,x); - undump_int(x); set_charinfo_italic(co,x); - undump_int(x); set_charinfo_tag(co,x); - undump_int(x); set_charinfo_ef(co,x); - undump_int(x); set_charinfo_rp(co,x); - undump_int(x); set_charinfo_lp(co,x); - undump_int(x); set_charinfo_remainder(co,x); - undump_int(x); set_charinfo_used(co,x); - undump_int(x); set_charinfo_index(co,x); - - /* name */ - undump_int (x); - if (x>0) { - font_bytes += x; - s = xmalloc(x); - undump_things(*s,x); - } - set_charinfo_name(co,s); - - /* tounicode */ - undump_int (x); - if (x>0) { - font_bytes += x; - s = xmalloc(x); - undump_things(*s,x); - } - set_charinfo_tounicode(co,s); - - /* ligatures */ - undump_int (x); - if (x>0) { - font_bytes += x*sizeof(liginfo); - lig = xmalloc(x*sizeof(liginfo)); - undump_things(*lig,x); - } - set_charinfo_ligatures(co,lig); - - /* kerns */ - undump_int (x); - if (x>0) { - font_bytes += x*sizeof(kerninfo); - kern = xmalloc(x*sizeof(kerninfo)); - undump_things(*kern,x); - } - set_charinfo_kerns(co,kern); - - /* packets */ - undump_int (x); - if (x>0) { - font_bytes += x; - packet = xmalloc(x); - undump_things(*packet,x); - } - set_charinfo_packets(co,packet); - - if (get_charinfo_tag(co)==ext_tag) { - undump_int(top); - undump_int(bot); - undump_int(mid); - undump_int(rep); - set_charinfo_extensible(co,top,bot,mid,rep); - } - return i; +int undump_charinfo(int f) +{ + charinfo *co; + int x, i; + char *s = NULL; + liginfo *lig = NULL; + kerninfo *kern = NULL; + real_eight_bits *packet = NULL; + + undump_int(i); + co = get_charinfo(f, i); + undump_int(x); + set_charinfo_width(co, x); + undump_int(x); + set_charinfo_height(co, x); + undump_int(x); + set_charinfo_depth(co, x); + undump_int(x); + set_charinfo_italic(co, x); + undump_int(x); + set_charinfo_top_accent(co, x); + undump_int(x); + set_charinfo_bot_accent(co, x); + undump_int(x); + set_charinfo_tag(co, x); + undump_int(x); + set_charinfo_ef(co, x); + undump_int(x); + set_charinfo_rp(co, x); + undump_int(x); + set_charinfo_lp(co, x); + undump_int(x); + set_charinfo_remainder(co, x); + undump_int(x); + set_charinfo_used(co, x); + undump_int(x); + set_charinfo_index(co, x); + + /* name */ + undump_int(x); + if (x > 0) { + font_bytes += x; + s = xmalloc(x); + undump_things(*s, x); + } + set_charinfo_name(co, s); + /* tounicode */ + undump_int(x); + if (x > 0) { + font_bytes += x; + s = xmalloc(x); + undump_things(*s, x); + } + set_charinfo_tounicode(co, s); + /* ligatures */ + undump_int(x); + if (x > 0) { + font_bytes += x * sizeof(liginfo); + lig = xmalloc(x * sizeof(liginfo)); + undump_things(*lig, x); + } + set_charinfo_ligatures(co, lig); + /* kerns */ + undump_int(x); + if (x > 0) { + font_bytes += x * sizeof(kerninfo); + kern = xmalloc(x * sizeof(kerninfo)); + undump_things(*kern, x); + } + set_charinfo_kerns(co, kern); + + /* packets */ + undump_int(x); + if (x > 0) { + font_bytes += x; + packet = xmalloc(x); + undump_things(*packet, x); + } + set_charinfo_packets(co, packet); + + if (get_charinfo_tag(co) == ext_tag) { + set_charinfo_vert_variants(co, undump_charinfo_variants()); + set_charinfo_hor_variants(co, undump_charinfo_variants()); + } + return i; } -#define undump_font_string(a) undump_int (x); \ - if (x>0) { \ - font_bytes += x; \ - s = xmalloc(x); undump_things(*s,x); \ +#define undump_font_string(a) undump_int (x); \ + if (x>0) { \ + font_bytes += x; \ + s = xmalloc(x); undump_things(*s,x); \ a(f,s); } -void -undump_font(int f) -{ - int x, i; - texfont *tt; - charinfo *ci; - char *s; - grow_font_table (f); - font_tables[f] = NULL; - font_bytes += sizeof(texfont); - tt = xmalloc(sizeof(texfont)); - undump_things(*tt,1); - font_tables[f] = tt; - - undump_font_string(set_font_name); - undump_font_string(set_font_area); - undump_font_string(set_font_filename); - undump_font_string(set_font_fullname); - undump_font_string(set_font_encodingname); - undump_font_string(set_font_cidregistry); - undump_font_string(set_font_cidordering); - - i = sizeof(*param_base(f))*(font_params(f)+1); - font_bytes += i; - param_base(f) = xmalloc (i); - undump_things(*param_base(f), (font_params(f)+1)); - - font_tables[f]->_left_boundary = NULL; - undump_int(x); - if (x) { i = undump_charinfo(f); } /* left boundary */ - - font_tables[f]->_right_boundary = NULL; - undump_int(x); - if (x) { i = undump_charinfo(f); } /* right boundary */ - - - font_tables[f]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ - ci = xcalloc(1,sizeof(charinfo)); - set_charinfo_name(ci,xstrdup(".notdef")); - font_tables[f]->charinfo = ci; - - i = font_bc(f); - while(i_font_name = NULL; + tt->_font_area = NULL; + tt->_font_filename = NULL; + tt->_font_fullname = NULL; + tt->_font_encodingname = NULL; + tt->_font_cidregistry = NULL; + tt->_font_cidordering = NULL; + font_tables[f] = tt; + + undump_font_string(set_font_name); + undump_font_string(set_font_area); + undump_font_string(set_font_filename); + undump_font_string(set_font_fullname); + undump_font_string(set_font_encodingname); + undump_font_string(set_font_cidregistry); + undump_font_string(set_font_cidordering); + + i = sizeof(*param_base(f)) * (font_params(f) + 1); + font_bytes += i; + param_base(f) = xmalloc(i); + undump_things(*param_base(f), (font_params(f) + 1)); + + if (font_math_params(f) > 0) { + i = sizeof(*math_param_base(f)) * (font_math_params(f) + 1); + font_bytes += i; + math_param_base(f) = xmalloc(i); + undump_things(*math_param_base(f), (font_math_params(f) + 1)); + } else { + math_param_base(f) = NULL; + } + font_tables[f]->_left_boundary = NULL; + undump_int(x); + if (x) { + i = undump_charinfo(f); + } + /* left boundary */ + font_tables[f]->_right_boundary = NULL; + undump_int(x); + if (x) { + i = undump_charinfo(f); + } + + /* right boundary */ + font_tables[f]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ + ci = xcalloc(1, sizeof(charinfo)); + set_charinfo_name(ci, xstrdup(".notdef")); + font_tables[f]->charinfo = ci; + + i = font_bc(f); + while (i < font_ec(f)) { + i = undump_charinfo(f); + } +} diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.h b/Build/source/texk/web2c/luatexdir/font/texfont.h index 21b79f1e876..f91d00dc2b1 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.h +++ b/Build/source/texk/web2c/luatexdir/font/texfont.h @@ -1,23 +1,23 @@ -/* - Copyright (c) 1996-2006 Taco Hoekwater - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - LuaTeX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with LuaTeX; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - $Id: texfont.h 1117 2008-03-21 15:26:12Z hhenkel $ */ +/* texfont.h Main font API implementation for the pascal parts + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: texfont.h 2057 2009-03-19 15:45:47Z taco $ */ /* Here we have the interface to LuaTeX's font system, as seen from the main pascal program. There is a companion list in luatex.defines to @@ -28,41 +28,53 @@ */ #ifndef TEXFONT_H -#define TEXFONT_H 1 +# define TEXFONT_H 1 -#include "luatexdir/managed-sa.h" +# include "luatexdir/managed-sa.h" -#define pointer halfword +# define pointer halfword typedef struct liginfo { - integer adj; - integer lig; - char type; + integer adj; + integer lig; + char type; } liginfo; typedef struct kerninfo { - integer adj; - scaled sc; + integer adj; + scaled sc; } kerninfo; +typedef struct extinfo { + struct extinfo *next; + int glyph; + int start_overlap; + int end_overlap; + int advance; + int extender; +} extinfo; + typedef struct charinfo { - char *name; /* postscript character name */ - liginfo *ligatures; /* ligature items */ - kerninfo *kerns; /* kern items */ - real_eight_bits *packets; /* virtual commands. */ - integer *extensible; /* extensible recipe (if any) */ - unsigned short index; /* CID index */ - integer remainder; /* spare value for odd items, could be union-ed with extensible */ - scaled width; /* width */ - scaled height; /* height */ - scaled depth; /* depth */ - scaled italic; /* italic correction */ - integer ef; /* font expansion factor */ - integer lp; /* left protruding factor */ - integer rp; /* right protruding factor */ - char tag ; /* list / ext taginfo */ - char used ; /* char is typeset ? */ - char *tounicode; /* unicode equivalent */ + char *name; /* postscript character name */ + liginfo *ligatures; /* ligature items */ + kerninfo *kerns; /* kern items */ + real_eight_bits *packets; /* virtual commands. */ + unsigned short index; /* CID index */ + integer remainder; /* spare value for odd items, could be union-ed with extensible */ + scaled width; /* width */ + scaled height; /* height */ + scaled depth; /* depth */ + scaled italic; /* italic correction */ + scaled top_accent; /* top accent alignment */ + scaled bot_accent; /* bot accent alignment */ + integer ef; /* font expansion factor */ + integer lp; /* left protruding factor */ + integer rp; /* right protruding factor */ + char tag; /* list / ext taginfo */ + char used; /* char is typeset ? */ + char *tounicode; /* unicode equivalent */ + extinfo *hor_variants; /* horizontal variants */ + extinfo *vert_variants; /* vertical variants */ } charinfo; @@ -71,94 +83,111 @@ typedef struct charinfo { at the same time. the structure |charinfo_short| is defined in web */ -#ifndef luaTeX +# ifndef luaTeX typedef struct charinfo_short { - scaled ci_wd; /* width */ - scaled ci_ht; /* height */ - scaled ci_dp; /* depth */ + scaled ci_wd; /* width */ + scaled ci_ht; /* height */ + scaled ci_dp; /* depth */ } charinfo_short; -#endif +# endif +# define EXT_NORMAL 0 +# define EXT_REPEAT 1 -extern charinfo_short char_info_short (internal_font_number f, integer c); +extern extinfo *get_charinfo_vert_variants(charinfo * ci); +extern extinfo *get_charinfo_hor_variants(charinfo * ci); +extern void set_charinfo_hor_variants(charinfo * ci, extinfo * ext); +extern void set_charinfo_vert_variants(charinfo * ci, extinfo * ext); +extern void add_charinfo_vert_variant(charinfo * ci, extinfo * ext); +extern void add_charinfo_hor_variant(charinfo * ci, extinfo * ext); + +extern extinfo *copy_variants(extinfo * o); + +extern extinfo *new_variant(int glyph, int startconnect, int endconnect, + int advance, int repeater); + +extern charinfo_short char_info_short(internal_font_number f, integer c); typedef struct texfont { - integer _font_size ; - integer _font_dsize ; - char * _font_name ; - char * _font_area ; - char * _font_filename ; - char * _font_fullname ; - char * _font_encodingname ; - char * _font_cidregistry ; - char * _font_cidordering ; - integer _font_cidversion ; - integer _font_cidsupplement ; - - integer _font_ec ; - integer _font_checksum ; /* internal information */ - char _font_used ; /* internal information */ - char _font_touched ; /* internal information */ - integer _font_cache_id ; /* internal information */ - char _font_encodingbytes ; /* 1 or 2 bytes */ - integer _font_slant ; /* a slant in ppt */ - integer _font_extend ; /* an extension in ppt, or 0 */ - char _font_tounicode ; /* 1 if info is present */ - fm_entry_ptr _font_map; - integer _font_type; - integer _font_format; - integer _font_embedding; - integer _font_bc ; - integer _hyphen_char ; - integer _skew_char ; - integer _font_natural_dir; - - charinfo *_left_boundary; - charinfo *_right_boundary; - - integer _font_params; - scaled *_param_base; - - sa_tree characters; - integer charinfo_count; - integer charinfo_size; - charinfo *charinfo; - int *charinfo_cache; - integer ligatures_disabled; - - integer _pdf_font_num; /* maps to a PDF resource ID */ - scaled _pdf_font_size; /* maps to a PDF font size */ - internal_font_number _pdf_font_blink; /* link to base font for expanded fonts */ - internal_font_number _pdf_font_elink; /* link to expanded fonts for base font */ - integer _pdf_font_expand_ratio; /* expansion ratio of a particular font */ - internal_font_number _pdf_font_shrink; /* font at limit of shrinking */ - internal_font_number _pdf_font_stretch; /* font at limit of stretching */ - integer _pdf_font_step; /* amount of one step of expansion */ - boolean _pdf_font_auto_expand; /* this font is auto-expanded? */ - str_number _pdf_font_attr; /* pointer to additional attributes */ + integer _font_size; + integer _font_dsize; + char *_font_name; + char *_font_area; + char *_font_filename; + char *_font_fullname; + char *_font_encodingname; + char *_font_cidregistry; + char *_font_cidordering; + integer _font_cidversion; + integer _font_cidsupplement; + + integer _font_ec; + unsigned _font_checksum; /* internal information */ + char _font_used; /* internal information */ + char _font_touched; /* internal information */ + integer _font_cache_id; /* internal information */ + char _font_encodingbytes; /* 1 or 2 bytes */ + integer _font_slant; /* a slant in ppt */ + integer _font_extend; /* an extension in ppt, or 0 */ + char _font_tounicode; /* 1 if info is present */ + fm_entry_ptr _font_map; + integer _font_type; + integer _font_format; + integer _font_embedding; + integer _font_bc; + integer _hyphen_char; + integer _skew_char; + integer _font_natural_dir; + + charinfo *_left_boundary; + charinfo *_right_boundary; + + integer _font_params; + scaled *_param_base; + + integer _font_math_params; + scaled *_math_param_base; + + sa_tree characters; + integer charinfo_count; + integer charinfo_size; + charinfo *charinfo; + int *charinfo_cache; + integer ligatures_disabled; + + integer _pdf_font_num; /* maps to a PDF resource ID */ + scaled _pdf_font_size; /* maps to a PDF font size */ + internal_font_number _pdf_font_blink; /* link to base font for expanded fonts */ + internal_font_number _pdf_font_elink; /* link to expanded fonts for base font */ + integer _pdf_font_expand_ratio; /* expansion ratio of a particular font */ + internal_font_number _pdf_font_shrink; /* font at limit of shrinking */ + internal_font_number _pdf_font_stretch; /* font at limit of stretching */ + integer _pdf_font_step; /* amount of one step of expansion */ + boolean _pdf_font_auto_expand; /* this font is auto-expanded? */ + str_number _pdf_font_attr; /* pointer to additional attributes */ } texfont; typedef enum { - unknown_font_type=0, /* new font (has not been used yet) */ - virtual_font_type, /* virtual font */ - real_font_type, /* real font */ + unknown_font_type = 0, /* new font (has not been used yet) */ + virtual_font_type, /* virtual font */ + real_font_type, /* real font */ } font_types; typedef enum { - unknown_format=0, - type1_format, - type3_format, - truetype_format, - opentype_format, + unknown_format = 0, + type1_format, + type3_format, + truetype_format, + opentype_format, } font_formats; typedef enum { - unknown_embedding=0, - no_embedding, - subset_embedding, - full_embedding, + unknown_embedding = 0, + no_embedding, + subset_embedding, + full_embedding, } font_embedding_option; extern char *font_type_strings[]; @@ -166,359 +195,391 @@ extern char *font_format_strings[]; extern char *font_embedding_strings[]; -#define font_checksum(a) font_tables[a]->_font_checksum -#define set_font_checksum(a,b) font_checksum(a) = b +# define font_checksum(a) font_tables[a]->_font_checksum +# define set_font_checksum(a,b) font_checksum(a) = b -#define font_check_0(a) ((font_tables[a]->_font_checksum&0xFF000000)>>24) -#define font_check_1(a) ((font_tables[a]->_font_checksum&0x00FF0000)>>16) -#define font_check_2(a) ((font_tables[a]->_font_checksum&0x0000FF00)>>8) -#define font_check_3(a) (font_tables[a]->_font_checksum&0x000000FF) +# define font_check_0(a) ((font_tables[a]->_font_checksum&0xFF000000)>>24) +# define font_check_1(a) ((font_tables[a]->_font_checksum&0x00FF0000)>>16) +# define font_check_2(a) ((font_tables[a]->_font_checksum&0x0000FF00)>>8) +# define font_check_3(a) (font_tables[a]->_font_checksum&0x000000FF) -#define font_size(a) font_tables[a]->_font_size -#define set_font_size(a,b) font_size(a) = b -#define font_dsize(a) font_tables[a]->_font_dsize -#define set_font_dsize(a,b) font_dsize(a) = b +# define font_size(a) font_tables[a]->_font_size +# define set_font_size(a,b) font_size(a) = b +# define font_dsize(a) font_tables[a]->_font_dsize +# define set_font_dsize(a,b) font_dsize(a) = b -#define font_name(a) font_tables[a]->_font_name -#define get_font_name(a) (unsigned char *)font_name(a) -#define set_font_name(f,b) font_name(f) = b -#define tex_font_name(a) maketexstring(font_name(a)) +# define font_name(a) font_tables[a]->_font_name +# define get_font_name(a) (unsigned char *)font_name(a) +# define set_font_name(f,b) font_name(f) = b +# define tex_font_name(a) maketexstring(font_name(a)) -boolean cmp_font_name (integer, strnumber); +boolean cmp_font_name(integer, strnumber); -#define font_area(a) font_tables[a]->_font_area -#define get_font_area(a) (unsigned char *)font_area(a) -#define set_font_area(f,b) font_area(f) = b -#define tex_font_area(a) maketexstring(font_area(a)) +# define font_area(a) font_tables[a]->_font_area +# define get_font_area(a) (unsigned char *)font_area(a) +# define set_font_area(f,b) font_area(f) = b +# define tex_font_area(a) maketexstring(font_area(a)) -boolean cmp_font_area (integer, strnumber); +boolean cmp_font_area(integer, strnumber); -#define font_reassign(a,b) { if (a!=NULL) free(a); a = b; } +# define font_reassign(a,b) { if (a!=NULL) free(a); a = b; } -#define font_filename(a) font_tables[a]->_font_filename -#define set_font_filename(f,b) font_reassign(font_filename(f),b) +# define font_filename(a) font_tables[a]->_font_filename +# define set_font_filename(f,b) font_reassign(font_filename(f),b) -#define font_fullname(a) font_tables[a]->_font_fullname -#define set_font_fullname(f,b) font_reassign(font_fullname(f),b) +# define font_fullname(a) font_tables[a]->_font_fullname +# define set_font_fullname(f,b) font_reassign(font_fullname(f),b) -#define font_encodingname(a) font_tables[a]->_font_encodingname -#define set_font_encodingname(f,b) font_reassign(font_encodingname(f),b) +# define font_encodingname(a) font_tables[a]->_font_encodingname +# define set_font_encodingname(f,b) font_reassign(font_encodingname(f),b) -boolean font_shareable(internal_font_number,internal_font_number); +boolean font_shareable(internal_font_number, internal_font_number); -#define cmp_font_filename(a,b) (!(font_filename(a)!=NULL || font_filename(b)!=NULL || \ +# define cmp_font_filename(a,b) (!(font_filename(a)!=NULL || font_filename(b)!=NULL || \ strcmp(font_filename(a),font_filename(b)))) -#define cmp_font_fullname(a,b) (!(font_fullname(a)!=NULL || font_fullname(b)!=NULL || \ +# define cmp_font_fullname(a,b) (!(font_fullname(a)!=NULL || font_fullname(b)!=NULL || \ strcmp(font_fullname(a),font_fullname(b)))) -#define cmp_font_encodingname(a,b) (!(font_encoding(a)!=NULL || font_encodingname(b)!=NULL || \ +# define cmp_font_encodingname(a,b) (!(font_encoding(a)!=NULL || font_encodingname(b)!=NULL || \ strcmp(font_encodingname(a),font_encodingname(b)))) -#define font_bc(a) font_tables[a]->_font_bc -#define set_font_bc(f,b) font_bc(f) = b +# define font_bc(a) font_tables[a]->_font_bc +# define set_font_bc(f,b) font_bc(f) = b -#define font_ec(a) font_tables[a]->_font_ec -#define set_font_ec(f,b) font_ec(f) = b +# define font_ec(a) font_tables[a]->_font_ec +# define set_font_ec(f,b) font_ec(f) = b -#define font_used(a) (font_tables[a]!=NULL && font_tables[a]->_font_used) -#define set_font_used(a,b) font_tables[a]->_font_used = b +# define font_used(a) (font_tables[a]!=NULL && font_tables[a]->_font_used) +# define set_font_used(a,b) font_tables[a]->_font_used = b -#define font_touched(a) font_tables[a]->_font_touched -#define set_font_touched(a,b) font_touched(a) = b - -#define font_type(a) font_tables[a]->_font_type -#define set_font_type(a,b) { /* fprintf(stdout,"set font type of %s to %i: %s\n",font_name(a),b,__FILE__); */ \ +# define font_touched(a) font_tables[a]->_font_touched +# define set_font_touched(a,b) font_touched(a) = b + +# define font_type(a) font_tables[a]->_font_type +# define set_font_type(a,b) { /* fprintf(stdout,"set font type of %s to %i: %s\n",font_name(a),b,__FILE__); */ \ font_type(a) = b; } -#define font_format(a) font_tables[a]->_font_format -#define font_format_name(a) font_format_strings[font_tables[a]->_font_format] -#define set_font_format(a,b) font_format(a) = b +# define font_format(a) font_tables[a]->_font_format +# define font_format_name(a) font_format_strings[font_tables[a]->_font_format] +# define set_font_format(a,b) font_format(a) = b -#define font_embedding(a) font_tables[a]->_font_embedding -#define set_font_embedding(a,b) font_embedding(a) = b +# define font_embedding(a) font_tables[a]->_font_embedding +# define set_font_embedding(a,b) font_embedding(a) = b -#define font_cidversion(a) font_tables[a]->_font_cidversion -#define set_font_cidversion(a,b) font_cidversion(a) = b +# define font_cidversion(a) font_tables[a]->_font_cidversion +# define set_font_cidversion(a,b) font_cidversion(a) = b -#define font_cidsupplement(a) font_tables[a]->_font_cidsupplement -#define set_font_cidsupplement(a,b) font_cidsupplement(a) = b +# define font_cidsupplement(a) font_tables[a]->_font_cidsupplement +# define set_font_cidsupplement(a,b) font_cidsupplement(a) = b -#define font_cidordering(a) font_tables[a]->_font_cidordering -#define set_font_cidordering(f,b) font_reassign(font_cidordering(f),b) +# define font_cidordering(a) font_tables[a]->_font_cidordering +# define set_font_cidordering(f,b) font_reassign(font_cidordering(f),b) -#define font_cidregistry(a) font_tables[a]->_font_cidregistry -#define set_font_cidregistry(f,b) font_reassign(font_cidregistry(f),b) +# define font_cidregistry(a) font_tables[a]->_font_cidregistry +# define set_font_cidregistry(f,b) font_reassign(font_cidregistry(f),b) -#define font_map(a) font_tables[a]->_font_map -#define set_font_map(a,b) font_map(a) = b +# define font_map(a) font_tables[a]->_font_map +# define set_font_map(a,b) font_map(a) = b -#define font_cache_id(a) font_tables[a]->_font_cache_id -#define set_font_cache_id(a,b) font_cache_id(a) = b +# define font_cache_id(a) font_tables[a]->_font_cache_id +# define set_font_cache_id(a,b) font_cache_id(a) = b -#define font_encodingbytes(a) font_tables[a]->_font_encodingbytes -#define set_font_encodingbytes(a,b) font_encodingbytes(a) = b +# define font_encodingbytes(a) font_tables[a]->_font_encodingbytes +# define set_font_encodingbytes(a,b) font_encodingbytes(a) = b -#define font_slant(a) font_tables[a]->_font_slant -#define set_font_slant(a,b) font_slant(a) = b +# define font_slant(a) font_tables[a]->_font_slant +# define set_font_slant(a,b) font_slant(a) = b -#define font_extend(a) font_tables[a]->_font_extend -#define set_font_extend(a,b) font_extend(a) = b +# define font_extend(a) font_tables[a]->_font_extend +# define set_font_extend(a,b) font_extend(a) = b -#define font_tounicode(a) font_tables[a]->_font_tounicode -#define set_font_tounicode(a,b) font_tounicode(a) = b +# define font_tounicode(a) font_tables[a]->_font_tounicode +# define set_font_tounicode(a,b) font_tounicode(a) = b -#define hyphen_char(a) font_tables[a]->_hyphen_char -#define set_hyphen_char(a,b) hyphen_char(a) = b +# define hyphen_char(a) font_tables[a]->_hyphen_char +# define set_hyphen_char(a,b) hyphen_char(a) = b -#define skew_char(a) font_tables[a]->_skew_char -#define set_skew_char(a,b) skew_char(a) = b +# define skew_char(a) font_tables[a]->_skew_char +# define set_skew_char(a,b) skew_char(a) = b -#define font_natural_dir(a) font_tables[a]->_font_natural_dir -#define set_font_natural_dir(a,b) font_natural_dir(a) = b +# define font_natural_dir(a) font_tables[a]->_font_natural_dir +# define set_font_natural_dir(a,b) font_natural_dir(a) = b -#define pdf_font_size(a) font_tables[a]->_pdf_font_size -#define set_pdf_font_size(a,b) pdf_font_size(a) = b +# define pdf_font_size(a) font_tables[a]->_pdf_font_size +# define set_pdf_font_size(a,b) pdf_font_size(a) = b -#define pdf_font_num(a) font_tables[a]->_pdf_font_num -#define set_pdf_font_num(a,b) pdf_font_num(a) = b +# define pdf_font_num(a) font_tables[a]->_pdf_font_num +# define set_pdf_font_num(a,b) pdf_font_num(a) = b -#define pdf_font_blink(a) font_tables[a]->_pdf_font_blink -#define set_pdf_font_blink(a,b) pdf_font_blink(a) = b +# define pdf_font_blink(a) font_tables[a]->_pdf_font_blink +# define set_pdf_font_blink(a,b) pdf_font_blink(a) = b -#define pdf_font_elink(a) font_tables[a]->_pdf_font_elink -#define set_pdf_font_elink(a,b) pdf_font_elink(a) = b +# define pdf_font_elink(a) font_tables[a]->_pdf_font_elink +# define set_pdf_font_elink(a,b) pdf_font_elink(a) = b -#define pdf_font_expand_ratio(a) font_tables[a]->_pdf_font_expand_ratio -#define set_pdf_font_expand_ratio(a,b) pdf_font_expand_ratio(a) = b +# define pdf_font_expand_ratio(a) font_tables[a]->_pdf_font_expand_ratio +# define set_pdf_font_expand_ratio(a,b) pdf_font_expand_ratio(a) = b -#define pdf_font_shrink(a) font_tables[a]->_pdf_font_shrink -#define set_pdf_font_shrink(a,b) pdf_font_shrink(a) = b +# define pdf_font_shrink(a) font_tables[a]->_pdf_font_shrink +# define set_pdf_font_shrink(a,b) pdf_font_shrink(a) = b -#define pdf_font_stretch(a) font_tables[a]->_pdf_font_stretch -#define set_pdf_font_stretch(a,b) pdf_font_stretch(a) = b +# define pdf_font_stretch(a) font_tables[a]->_pdf_font_stretch +# define set_pdf_font_stretch(a,b) pdf_font_stretch(a) = b -#define pdf_font_step(a) font_tables[a]->_pdf_font_step -#define set_pdf_font_step(a,b) pdf_font_step(a) = b +# define pdf_font_step(a) font_tables[a]->_pdf_font_step +# define set_pdf_font_step(a,b) pdf_font_step(a) = b -#define pdf_font_auto_expand(a) font_tables[a]->_pdf_font_auto_expand -#define set_pdf_font_auto_expand(a,b) pdf_font_auto_expand(a) = b +# define pdf_font_auto_expand(a) font_tables[a]->_pdf_font_auto_expand +# define set_pdf_font_auto_expand(a,b) pdf_font_auto_expand(a) = b -#define pdf_font_attr(a) font_tables[a]->_pdf_font_attr -#define set_pdf_font_attr(a,b) pdf_font_attr(a) = b +# define pdf_font_attr(a) font_tables[a]->_pdf_font_attr +# define set_pdf_font_attr(a,b) pdf_font_attr(a) = b -#define left_boundarychar -1 -#define right_boundarychar -2 -#define non_boundarychar -3 +# define left_boundarychar -1 +# define right_boundarychar -2 +# define non_boundarychar -3 -#define left_boundary(a) font_tables[a]->_left_boundary -#define has_left_boundary(a) (left_boundary(a)!=NULL) -#define set_left_boundary(a,b) font_reassign(left_boundary(a),b) +# define left_boundary(a) font_tables[a]->_left_boundary +# define has_left_boundary(a) (left_boundary(a)!=NULL) +# define set_left_boundary(a,b) font_reassign(left_boundary(a),b) -#define right_boundary(a) font_tables[a]->_right_boundary -#define has_right_boundary(a) (right_boundary(a)!=NULL) -#define set_right_boundary(a,b) font_reassign(right_boundary(a),b) +# define right_boundary(a) font_tables[a]->_right_boundary +# define has_right_boundary(a) (right_boundary(a)!=NULL) +# define set_right_boundary(a,b) font_reassign(right_boundary(a),b) -#define font_bchar(a) (right_boundary(a)!=NULL ? right_boundarychar : non_boundarychar) +# define font_bchar(a) (right_boundary(a)!=NULL ? right_boundarychar : non_boundarychar) /* font parameters */ -#define font_params(a) font_tables[a]->_font_params -#define param_base(a) font_tables[a]->_param_base -#define font_param(a,b) font_tables[a]->_param_base[b] +# define font_params(a) font_tables[a]->_font_params +# define param_base(a) font_tables[a]->_param_base +# define font_param(a,b) font_tables[a]->_param_base[b] extern void set_font_params(internal_font_number f, int b); -#define set_font_param(f,n,b) \ +# define set_font_param(f,n,b) \ { if (font_params(f)_font_math_params +# define math_param_base(a) font_tables[a]->_math_param_base +# define font_math_param(a,b) font_tables[a]->_math_param_base[b] + +extern void set_font_math_params(internal_font_number f, int b); + +# define set_font_math_param(f,n,b) \ + { if (font_math_params(f)kerns[c] +# define charinfo_kern(b,c) b->kerns[c] -#define kern_char(b) (b).adj -#define kern_kern(b) (b).sc -#define kern_end(b) ((b).adj == end_kern) -#define kern_disabled(b) ((b).adj > end_kern) +# define kern_char(b) (b).adj +# define kern_kern(b) (b).sc +# define kern_end(b) ((b).adj == end_kern) +# define kern_disabled(b) ((b).adj > end_kern) /* character ligatures */ -#define end_ligature 0x7FFFFF /* otherchar value meaning "stop" */ -#define ignored_ligature 0x800000 /* otherchar value meaning "disabled" */ - -#define charinfo_ligature(b,c) b->ligatures[c] - -#define is_valid_ligature(a) ((a).type!=0) -#define lig_type(a) ((a).type>>1) -#define lig_char(a) (a).adj -#define lig_replacement(a) (a).lig -#define lig_end(a) (lig_char(a) == end_ligature) -#define lig_disabled(a) (lig_char(a) > end_ligature) - -#define no_tag 0 /* vanilla character */ -#define lig_tag 1 /* character has a ligature/kerning program */ -#define list_tag 2 /* character has a successor in a charlist */ -#define ext_tag 3 /* character is extensible */ - -extern scaled char_height (internal_font_number f, integer c); -extern scaled char_width (internal_font_number f, integer c); -extern scaled char_depth (internal_font_number f, integer c); -extern scaled char_italic (internal_font_number f, integer c); - -extern liginfo * char_ligatures (internal_font_number f, integer c); -extern kerninfo * char_kerns (internal_font_number f, integer c); -extern real_eight_bits * char_packets (internal_font_number f, integer c); - -#define has_lig(f,b) (char_exists(f,b) &&( char_ligatures(f,b) != NULL)) -#define has_kern(f,b) (char_exists(f,b) && (char_kerns(f,b) != NULL)) -#define has_packet(f,b) (char_exists(f,b) && (char_packets(f,b) != NULL)) - -extern integer char_remainder (internal_font_number f, integer c); -extern char char_tag (internal_font_number f, integer c); -extern char char_used (internal_font_number f, integer c); -extern char * char_name (internal_font_number f, integer c); -extern integer char_index (internal_font_number f, integer c); - +# define end_ligature 0x7FFFFF /* otherchar value meaning "stop" */ +# define ignored_ligature 0x800000 /* otherchar value meaning "disabled" */ + +# define charinfo_ligature(b,c) b->ligatures[c] + +# define is_valid_ligature(a) ((a).type!=0) +# define lig_type(a) ((a).type>>1) +# define lig_char(a) (a).adj +# define lig_replacement(a) (a).lig +# define lig_end(a) (lig_char(a) == end_ligature) +# define lig_disabled(a) (lig_char(a) > end_ligature) + +# define no_tag 0 /* vanilla character */ +# define lig_tag 1 /* character has a ligature/kerning program */ +# define list_tag 2 /* character has a successor in a charlist */ +# define ext_tag 3 /* character is extensible */ + +extern scaled char_height(internal_font_number f, integer c); +extern scaled char_width(internal_font_number f, integer c); +extern scaled char_depth(internal_font_number f, integer c); +extern scaled char_italic(internal_font_number f, integer c); +extern scaled char_top_accent(internal_font_number f, integer c); +extern scaled char_bot_accent(internal_font_number f, integer c); + +extern liginfo *char_ligatures(internal_font_number f, integer c); +extern kerninfo *char_kerns(internal_font_number f, integer c); +extern real_eight_bits *char_packets(internal_font_number f, integer c); + +# define has_lig(f,b) (char_exists(f,b) &&( char_ligatures(f,b) != NULL)) +# define has_kern(f,b) (char_exists(f,b) && (char_kerns(f,b) != NULL)) +# define has_packet(f,b) (char_exists(f,b) && (char_packets(f,b) != NULL)) + +extern integer char_remainder(internal_font_number f, integer c); +extern char char_tag(internal_font_number f, integer c); +extern char char_used(internal_font_number f, integer c); +extern char *char_name(internal_font_number f, integer c); +extern integer char_index(internal_font_number f, integer c); + +scaled raw_get_kern(internalfontnumber f, integer lc, integer rc); scaled get_kern(internalfontnumber f, integer lc, integer rc); liginfo get_ligature(internalfontnumber f, integer lc, integer rc); -#define EXT_TOP 0 -#define EXT_BOT 1 -#define EXT_MID 2 -#define EXT_REP 3 +# define EXT_TOP 0 +# define EXT_BOT 1 +# define EXT_MID 2 +# define EXT_REP 3 extern texfont **font_tables; -integer new_font (void) ; -integer copy_font (integer id) ; -integer scale_font (integer id, integer atsize) ; -integer max_font_id (void); -void set_max_font_id (integer id); -integer new_font_id (void); -void create_null_font (void); +integer new_font(void); +integer copy_font(integer id); +integer scale_font(integer id, integer atsize); +integer max_font_id(void); +void set_max_font_id(integer id); +integer new_font_id(void); +void create_null_font(void); void delete_font(integer id); -boolean is_valid_font (integer id); +boolean is_valid_font(integer id); -void dump_font (int font_number); -void undump_font (int font_number); +void dump_font(int font_number); +void undump_font(int font_number); -integer test_no_ligatures (internal_font_number f) ; -void set_no_ligatures (internal_font_number f) ; +integer test_no_ligatures(internal_font_number f); +void set_no_ligatures(internal_font_number f); -extern integer get_tag_code (internal_font_number f, integer c); -extern integer get_lp_code (internal_font_number f, integer c); -extern integer get_rp_code (internal_font_number f, integer c); -extern integer get_ef_code (internal_font_number f, integer c); +extern integer get_tag_code(internal_font_number f, integer c); +extern integer get_lp_code(internal_font_number f, integer c); +extern integer get_rp_code(internal_font_number f, integer c); +extern integer get_ef_code(internal_font_number f, integer c); -extern void set_tag_code (internal_font_number f, integer c, integer i) ; -extern void set_lp_code(internal_font_number f, integer c, integer i) ; -extern void set_rp_code(internal_font_number f, integer c, integer i) ; -extern void set_ef_code(internal_font_number f, integer c, integer i) ; +extern void set_tag_code(internal_font_number f, integer c, integer i); +extern void set_lp_code(internal_font_number f, integer c, integer i); +extern void set_rp_code(internal_font_number f, integer c, integer i); +extern void set_ef_code(internal_font_number f, integer c, integer i); int read_tfm_info(internal_font_number f, char *nom, char *aire, scaled s); /* from dofont.c */ -extern int read_font_info (pointer u, strnumber nom, strnumber aire, scaled s, integer ndir); -extern int find_font_id (char *nom, char *aire, scaled s); +extern int read_font_info(pointer u, strnumber nom, scaled s, integer ndir); +extern int find_font_id(char *nom, char *aire, scaled s); /* for and from vfpacket.c */ -#define scan_special 3 /* look into special text */ /* this is a hack */ - -typedef enum { packet_char_code, - packet_font_code, - packet_pop_code, - packet_push_code, - packet_special_code, - packet_right_code, - packet_down_code, - packet_rule_code, - packet_node_code, - packet_nop_code, - packet_end_code } packet_command_codes; - -extern scaled sqxfw (scaled sq, integer fw); - -extern void do_vf_packet (internal_font_number vf_f, integer c); -extern int vf_packet_bytes (charinfo *co); +# define scan_special 3 /* look into special text */ /* this is a hack */ + +typedef enum { packet_char_code, + packet_font_code, + packet_pop_code, + packet_push_code, + packet_special_code, + packet_image_code, + packet_right_code, + packet_down_code, + packet_rule_code, + packet_node_code, + packet_nop_code, + packet_end_code +} packet_command_codes; + +extern scaled sqxfw(scaled sq, integer fw); + +extern void do_vf_packet(internal_font_number vf_f, integer c); +extern int vf_packet_bytes(charinfo * co); #endif diff --git a/Build/source/texk/web2c/luatexdir/font/tfmofm.c b/Build/source/texk/web2c/luatexdir/font/tfmofm.c index db82f94deba..36364ba6d44 100644 --- a/Build/source/texk/web2c/luatexdir/font/tfmofm.c +++ b/Build/source/texk/web2c/luatexdir/font/tfmofm.c @@ -1,34 +1,34 @@ -/* -Copyright (c) 1996-2006 Taco Hoekwater - -This file is part of LuaTeX. +/* tfmofm.c + + Copyright 2006-2008 Taco Hoekwater -LuaTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -LuaTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with LuaTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: tfmofm.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" - #include "luatex-api.h" +#include "luatexfont.h" + +static const char _svn_version[] = + "$Id: tfmofm.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tfmofm.c $"; /* Here are some macros that help process ligatures and kerns */ #define lig_kern_start(f,c) char_remainder(f,c) -#define stop_flag 128 /* value indicating `\.{STOP}' in a lig/kern program */ -#define kern_flag 128 /* op code for a kern step */ +#define stop_flag 128 /* value indicating `\.{STOP}' in a lig/kern program */ +#define kern_flag 128 /* op code for a kern step */ #define skip_byte(z) lig_kerns[z].b0 #define next_char(z) lig_kerns[z].b1 @@ -205,7 +205,7 @@ character does not exist in the font, since a character is valid if and only if it lies between |bc| and |ec| and has a nonzero |width_index|. */ - /* +/* @ \TeX\ checks the information of a \.{TFM} file for validity as the file is being read in, so that no further checks will be needed when typesetting is going on. The somewhat tedious subroutine that does this @@ -361,53 +361,54 @@ additional parameter information, which is explained later. */ -#define tfm_abort { font_tables[f]->_font_name = NULL; \ - font_tables[f]->_font_area = NULL; \ - xfree(tfm_buffer); xfree(kerns); \ - xfree(widths); xfree(heights); xfree(depths); \ - xfree(italics); xfree(extens); xfree(lig_kerns); \ - xfree(xligs); xfree(xkerns); \ - return 0; } +#define tfm_abort { font_tables[f]->_font_name = NULL; \ + font_tables[f]->_font_area = NULL; \ + xfree(tfm_buffer); xfree(kerns); \ + xfree(widths); xfree(heights); xfree(depths); \ + xfree(italics); xfree(extens); xfree(lig_kerns); \ + xfree(xligs); xfree(xkerns); \ + return 0; } -#define tfm_success { xfree(tfm_buffer); xfree(kerns); \ - xfree(widths); xfree(heights); xfree(depths); \ - xfree(italics); xfree(extens); xfree(lig_kerns); \ - xfree(xligs); xfree(xkerns); return 1; } +#define tfm_success { xfree(tfm_buffer); xfree(kerns); \ + xfree(widths); xfree(heights); xfree(depths); \ + xfree(italics); xfree(extens); xfree(lig_kerns); \ + xfree(xligs); xfree(xkerns); return 1; } int -open_tfm_file(char *nom, char *aire, unsigned char **tfm_buf, integer *tfm_siz) { - boolean res; /* was the callback successful? */ - boolean opened; /* was |tfm_file| successfully opened?*/ - integer callback_id; - FILE *tfm_file; - /* packfilename(nom,aire,getnullstr()); */ - if(nameoffile != NULL) - xfree(nameoffile); - nameoffile = malloc(strlen(nom)+2); - strcpy(stringcast(nameoffile+1),nom); - namelength = strlen(nom); - callback_id=callback_defined(read_font_file_callback); - if (callback_id>0) { - res = run_callback(callback_id,"S->bSd",stringcast(nameoffile+1), - &opened, tfm_buf, tfm_siz); - if (res && opened && (*tfm_siz>0)) { - return 1; - } +open_tfm_file(char *nom, char *aire, unsigned char **tfm_buf, integer * tfm_siz) +{ + boolean res; /* was the callback successful? */ + boolean opened; /* was |tfm_file| successfully opened? */ + integer callback_id; + FILE *tfm_file; + /* packfilename(nom,aire,getnullstr()); */ + if (nameoffile != NULL) + xfree(nameoffile); + nameoffile = malloc(strlen(nom) + 2); + strcpy(stringcast(nameoffile + 1), nom); + namelength = strlen(nom); + callback_id = callback_defined(read_font_file_callback); + if (callback_id > 0) { + res = run_callback(callback_id, "S->bSd", stringcast(nameoffile + 1), + &opened, tfm_buf, tfm_siz); + if (res && opened && (*tfm_siz > 0)) { + return 1; + } if (!opened) - return -1; - } else { - if (ofm_open_in(tfm_file)) { - res = read_tfm_file(tfm_file,tfm_buf,tfm_siz); - b_close(tfm_file); - if (res) { - return 1; - } + return -1; } else { - return -1; + if (ofm_open_in(tfm_file)) { + res = read_tfm_file(tfm_file, tfm_buf, tfm_siz); + b_close(tfm_file); + if (res) { + return 1; + } + } else { + return -1; + } } - } - return 0; + return 0; } @@ -441,47 +442,47 @@ open_tfm_file(char *nom, char *aire, unsigned char **tfm_buf, integer *tfm_siz) a=(a*256)+tfm_buffer[++tfm_byte]; } #define store_four_bytes(z) \ - { a=tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ + { a=tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ z = a; } #define store_char_info(z) \ { if (font_level!=-1) { \ - fget; read_sixteen_unsigned(a); \ - ci._width_index=a; \ - fget; read_sixteen_unsigned(b); \ - ci._height_index=b>>8; \ - ci._depth_index=b%256; \ - fget; read_sixteen_unsigned(c); \ - ci._italic_index=c>>8; \ - ci._tag=c%4; \ - fget; read_sixteen_unsigned(d); \ - ci._remainder=d; \ + fget; read_sixteen_unsigned(a); \ + ci._width_index=a; \ + fget; read_sixteen_unsigned(b); \ + ci._height_index=b>>8; \ + ci._depth_index=b%256; \ + fget; read_sixteen_unsigned(c); \ + ci._italic_index=c>>8; \ + ci._tag=c%4; \ + fget; read_sixteen_unsigned(d); \ + ci._remainder=d; \ } else { \ - a=tfm_buffer[++tfm_byte]; \ - ci._width_index=a; \ - b=tfm_buffer[++tfm_byte]; \ - ci._height_index=b>>4; \ - ci._depth_index=b%16; \ - c=tfm_buffer[++tfm_byte]; \ - ci._italic_index=c>>2; \ - ci._tag=c%4; \ - d=tfm_buffer[++tfm_byte]; \ - ci._remainder=d; \ + a=tfm_buffer[++tfm_byte]; \ + ci._width_index=a; \ + b=tfm_buffer[++tfm_byte]; \ + ci._height_index=b>>4; \ + ci._depth_index=b%16; \ + c=tfm_buffer[++tfm_byte]; \ + ci._italic_index=c>>2; \ + ci._tag=c%4; \ + d=tfm_buffer[++tfm_byte]; \ + ci._remainder=d; \ } } -#define read_four_quarters(q) \ +#define read_four_quarters(q) \ { if (font_level!=-1) { \ - fget; read_sixteen_unsigned(a); q.b0=a; \ - fget; read_sixteen_unsigned(b); q.b1=b; \ - fget; read_sixteen_unsigned(c); q.b2=c; \ - fget; read_sixteen_unsigned(d); q.b3=d; \ + fget; read_sixteen_unsigned(a); q.b0=a; \ + fget; read_sixteen_unsigned(b); q.b1=b; \ + fget; read_sixteen_unsigned(c); q.b2=c; \ + fget; read_sixteen_unsigned(d); q.b3=d; \ } else { \ - a=tfm_buffer[++tfm_byte]; q.b0=a; \ - b=tfm_buffer[++tfm_byte]; q.b1=b; \ - c=tfm_buffer[++tfm_byte]; q.b2=c; \ + a=tfm_buffer[++tfm_byte]; q.b0=a; \ + b=tfm_buffer[++tfm_byte]; q.b1=b; \ + c=tfm_buffer[++tfm_byte]; q.b2=c; \ d=tfm_buffer[++tfm_byte]; q.b3=d; \ } } @@ -507,499 +508,565 @@ open_tfm_file(char *nom, char *aire, unsigned char **tfm_buf, integer *tfm_siz) of \TeX\ between computers. */ -#define store_scaled(zz) \ +#define store_scaled(zz) \ { fget; a=fbyte; fget; b=fbyte; \ fget; c=fbyte; fget; d=fbyte; \ sw=(((((d*z)>>8)+(c*z))>>8)+(b*z)) / beta; \ - if (a==0) { zz=sw; } else if (a==255) { zz=sw-alpha; } else tfm_abort; \ + if (a==0) { zz=sw; } else if (a==255) { zz=sw-alpha; } else tfm_abort; \ } #define check_existence(z) \ { check_byte_range(z); \ - if (!char_exists(f,z)) tfm_abort; \ + if (!char_exists(f,z)) tfm_abort; \ } typedef struct tfmcharacterinfo { - integer _kern_index; - integer _lig_index; - integer _width_index; - integer _height_index; - integer _depth_index; - integer _italic_index; - integer _remainder; - unsigned char _tag ; + integer _kern_index; + integer _lig_index; + integer _width_index; + integer _height_index; + integer _depth_index; + integer _italic_index; + integer _remainder; + unsigned char _tag; } tfmcharacterinfo; -extern charinfo *copy_charinfo(charinfo *ci); - -int -read_tfm_info(internalfontnumber f, char *cnom, char *caire, scaled s) { - integer k; /* index into |font_info| */ - halfword lf,lh,bc,ec,nw,nh,nd,ni,nl,nk,ne,np,slh; /* sizes of subfiles */ - scaled *widths, *heights, *depths, *italics, *kerns; - halfword font_dir; - integer a,b,c,d; /* byte variables */ - integer i; /* counter */ - integer font_level,header_length; - integer nco,ncw,npc,nlw,neew; - tfmcharacterinfo ci; - charinfo *co; - four_quarters qw; - four_quarters *lig_kerns, *extens; - scaled sw; /* accumulators */ - integer bch_label; /* left boundary start location, or infinity */ - int bchar; /* :0..too_big_char; */ /* right boundary character, or |too_big_char| */ - integer first_two; - scaled z; /* the design size or the ``at'' size */ - integer alpha; - char beta; /* :1..16*/ - integer *xligs, *xkerns; /* aux. for ligkern processing */ - liginfo *cligs; - kerninfo *ckerns; - int fligs, fkerns; - char *tmpnam; - integer tfm_byte = 0; /* index into |tfm_buffer| */ - integer saved_tfm_byte = 0; /* saved index into |tfm_buffer| */ - unsigned char *tfm_buffer = NULL; /* byte buffer for tfm files */ - integer tfm_size = 0; /* total size of the tfm file */ - - widths=NULL; - heights=NULL; - depths = NULL; - italics = NULL; - kerns = NULL; - lig_kerns = NULL; - extens = NULL; - xkerns = NULL; - ckerns = NULL; - xligs = NULL; - cligs = NULL; - - font_dir = 0; - - memset(&ci,0,sizeof(tfmcharacterinfo)); - - if(open_tfm_file(cnom,caire,&tfm_buffer,&tfm_size)!=1) - tfm_abort; - - /* cnom can be an absolute filename, xbasename() fixes that. */ - - tmpnam=strdup(xbasename(cnom)); - if (strcmp(tmpnam+strlen(tmpnam)-4,".tfm")==0) { - *(tmpnam+strlen(tmpnam)-4) =0; - } - set_font_name(f,tmpnam); - set_font_area(f,xstrdup(caire)); /* perhaps it leaks, but it doesnt crash */ - - /* @; */ - nco=0; ncw=0; npc=0; - read_sixteen(first_two); - if (first_two!=0) { - font_level=-1; - lf=first_two; - fget; read_sixteen(lh); - fget; read_sixteen(bc); - fget; read_sixteen(ec); - if ((bc>ec+1)||(ec>255)) tfm_abort; - if (bc>255) { /* |bc=256| and |ec=255| */ - bc=1; ec=0; +int read_tfm_info(internalfontnumber f, char *cnom, char *caire, scaled s) +{ + integer k; /* index into |font_info| */ + halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np, slh; /* sizes of subfiles */ + scaled *widths, *heights, *depths, *italics, *kerns; + halfword font_dir; + integer a, b, c, d; /* byte variables */ + integer i; /* counter */ + integer font_level, header_length; + integer nco, ncw, npc, nlw, neew; + tfmcharacterinfo ci; + charinfo *co; + four_quarters qw; + four_quarters *lig_kerns, *extens; + scaled sw; /* accumulators */ + integer bch_label; /* left boundary start location, or infinity */ + int bchar; /* :0..too_big_char; *//* right boundary character, or |too_big_char| */ + integer first_two; + scaled z; /* the design size or the ``at'' size */ + integer alpha; + char beta; /* :1..16 */ + integer *xligs, *xkerns; /* aux. for ligkern processing */ + liginfo *cligs; + kerninfo *ckerns; + int fligs, fkerns; + char *tmpnam; + integer tfm_byte = 0; /* index into |tfm_buffer| */ + integer saved_tfm_byte = 0; /* saved index into |tfm_buffer| */ + unsigned char *tfm_buffer = NULL; /* byte buffer for tfm files */ + integer tfm_size = 0; /* total size of the tfm file */ + + widths = NULL; + heights = NULL; + depths = NULL; + italics = NULL; + kerns = NULL; + lig_kerns = NULL; + extens = NULL; + xkerns = NULL; + ckerns = NULL; + xligs = NULL; + cligs = NULL; + + font_dir = 0; + + memset(&ci, 0, sizeof(tfmcharacterinfo)); + + if (open_tfm_file(cnom, caire, &tfm_buffer, &tfm_size) != 1) + tfm_abort; + + /* cnom can be an absolute filename, xbasename() fixes that. */ + + tmpnam = strdup(xbasename(cnom)); + if (strcmp(tmpnam + strlen(tmpnam) - 4, ".tfm") == 0) { + *(tmpnam + strlen(tmpnam) - 4) = 0; + } + set_font_name(f, tmpnam); + set_font_area(f, NULL); + + /* @; */ + nco = 0; + ncw = 0; + npc = 0; + read_sixteen(first_two); + if (first_two != 0) { + font_level = -1; + lf = first_two; + fget; + read_sixteen(lh); + fget; + read_sixteen(bc); + fget; + read_sixteen(ec); + if ((bc > ec + 1) || (ec > 255)) + tfm_abort; + if (bc > 255) { /* |bc=256| and |ec=255| */ + bc = 1; + ec = 0; + }; + fget; + read_sixteen(nw); + fget; + read_sixteen(nh); + fget; + read_sixteen(nd); + fget; + read_sixteen(ni); + fget; + read_sixteen(nl); + fget; + read_sixteen(nk); + fget; + read_sixteen(ne); + fget; + read_sixteen(np); + header_length = 6; + ncw = (ec - bc + 1); + nlw = nl; + neew = ne; + } else { + fget; + read_sixteen(font_level); + if (font_level != 0) + tfm_abort; + read_thirtytwo(lf); + read_thirtytwo(lh); + read_thirtytwo(bc); + read_thirtytwo(ec); + if ((bc > ec + 1) || (ec > 65535)) + tfm_abort; + if (bc > 65535) { /* |bc=65536| and |ec=65535| */ + bc = 1; + ec = 0; + }; + read_thirtytwo(nw); + read_thirtytwo(nh); + read_thirtytwo(nd); + read_thirtytwo(ni); + read_thirtytwo(nl); + read_thirtytwo(nk); + read_thirtytwo(ne); + read_thirtytwo(np); + read_thirtytwo(font_dir); /* junk */ + nlw = 2 * nl; + neew = 2 * ne; + header_length = 14; + ncw = 2 * (ec - bc + 1); }; - fget; read_sixteen(nw); - fget; read_sixteen(nh); - fget; read_sixteen(nd); - fget; read_sixteen(ni); - fget; read_sixteen(nl); - fget; read_sixteen(nk); - fget; read_sixteen(ne); - fget; read_sixteen(np); - header_length=6; - ncw=(ec-bc+1); - nlw=nl; - neew=ne; - } else { - fget; read_sixteen(font_level); - if (font_level!=0) tfm_abort; - read_thirtytwo(lf); - read_thirtytwo(lh); - read_thirtytwo(bc); - read_thirtytwo(ec); - if ((bc>ec+1)||(ec>65535)) tfm_abort; - if (bc>65535) { /* |bc=65536| and |ec=65535| */ - bc=1; ec=0; + if (lf != + (header_length + lh + ncw + nw + nh + nd + ni + nlw + nk + neew + np)) + tfm_abort; + if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0)) + tfm_abort; + + /* + We check to see that the \.{TFM} file doesn't end prematurely; but + no error message is given for files having more than |lf| words. + */ + if (lf * 4 > tfm_size) + tfm_abort; + + /* @; */ + + set_font_natural_dir(f, font_dir); + set_font_bc(f, bc); + set_font_ec(f, ec); + + /* read the arrays first */ + widths = xmalloc(nw * sizeof(scaled)); + heights = xmalloc(nh * sizeof(scaled)); + depths = xmalloc(nd * sizeof(scaled)); + italics = xmalloc(ni * sizeof(scaled)); + extens = xmalloc(ne * sizeof(four_quarters)); + lig_kerns = xmalloc(nl * sizeof(four_quarters)); + kerns = xmalloc(nk * sizeof(scaled)); + + /* @; */ + + /* Only the first two words of the header are needed by \TeX82. */ + slh = lh; + if (lh < 2) + tfm_abort; + store_four_bytes(font_checksum(f)); + fget; + read_sixteen(z); /* this rejects a negative design size */ + fget; + z = z * 256 + fbyte; + fget; + z = (z * 16) + (fbyte >> 4); + if (z < unity) + tfm_abort; + while (lh > 2) { + fget; + fget; + fget; + fget; + lh--; /* ignore the rest of the header */ }; - read_thirtytwo(nw); - read_thirtytwo(nh); - read_thirtytwo(nd); - read_thirtytwo(ni); - read_thirtytwo(nl); - read_thirtytwo(nk); - read_thirtytwo(ne); - read_thirtytwo(np); - read_thirtytwo(font_dir); /* junk */ - nlw=2*nl; - neew=2*ne; - header_length=14; - ncw=2*(ec-bc+1); - }; - if (lf!=(header_length+lh+ncw+nw+nh+nd+ni+nlw+nk+neew+np)) tfm_abort; - - /* @; */ - - set_font_natural_dir(f,font_dir); - set_font_bc(f,bc); - set_font_ec(f,ec); - - /* read the arrays first */ - widths = xmalloc(nw*sizeof(scaled)); - heights = xmalloc(nh*sizeof(scaled)); - depths = xmalloc(nd*sizeof(scaled)); - italics = xmalloc(ni*sizeof(scaled)); - extens = xmalloc(ne*sizeof(four_quarters)); - lig_kerns = xmalloc(nl*sizeof(four_quarters)); - kerns = xmalloc(nk*sizeof(scaled)); - - /* @; */ - - /* Only the first two words of the header are needed by \TeX82. */ - slh = lh; - if (lh<2) - tfm_abort; - store_four_bytes(font_checksum(f)); - fget; read_sixteen(z); /* this rejects a negative design size */ - fget; z=z*256+fbyte; fget; z=(z*16)+(fbyte>>4); - if (z2) { - fget;fget;fget;fget; - lh--; /* ignore the rest of the header */ - }; - - /* read the arrays before the character info */ - - set_font_dsize(f,z); - if (s!=-1000) { - z = (s>=0 ? s : xn_over_d(z,-s,1000)); - } - set_font_size(f,z); - if (np>7) - set_font_params(f,np); + /* read the arrays before the character info */ - saved_tfm_byte = tfm_byte; - tfm_byte = (header_length+slh+ncw)*4 - 1; + set_font_dsize(f, z); + if (s != -1000) { + z = (s >= 0 ? s : xn_over_d(z, -s, 1000)); + } + set_font_size(f, z); - /* @; */ + if (np > 7) + set_font_params(f, np); - alpha=16; - while (z>=040000000) { - z=z>>1; alpha=alpha+alpha; - }; - beta=256/alpha; alpha=alpha*z; + saved_tfm_byte = tfm_byte; + tfm_byte = (header_length + slh + ncw) * 4 - 1; - /* @; */ + /* @; */ - for (k=0;k; */ - - bch_label=nl; /* infinity*/ - bchar=65536; - if (nl>0) { - for (k=0;k128) { - if (256*c+d>=nl) tfm_abort; - if (a==255 && k==0) bchar=b; - } else { - /* if (b!=bchar) check_existence(b); */ - if (c<128) { - /* check_existence(d); */ /* check ligature */ - } else if (256*(c-128)+d>=nk) { - tfm_abort; /* check kern */ - } - if ((a<128) && (k-0+a+1>=nl)) tfm_abort; - }; + alpha = 16; + while (z >= 040000000) { + z = z >> 1; + alpha = alpha + alpha; }; - if (a==255) bch_label=256*c+d; - }; + beta = 256 / alpha; + alpha = alpha * z; - /* the actual kerns */ - for (k=0;k; */ - /* @; */ - for (k=0;k; */ + + bch_label = nl; /* infinity */ + bchar = 65536; + if (nl > 0) { + for (k = 0; k < nl; k++) { + read_four_quarters(qw); + lig_kerns[k] = qw; + if (a > 128) { + if (256 * c + d >= nl) + tfm_abort; + if (a == 255 && k == 0) + bchar = b; + } else { + /* if (b!=bchar) check_existence(b); */ + if (c < 128) { + /* check_existence(d); *//* check ligature */ + } else if (256 * (c - 128) + d >= nk) { + tfm_abort; /* check kern */ + } + if ((a < 128) && (k - 0 + a + 1 >= nl)) + tfm_abort; + }; + }; + if (a == 255) + bch_label = 256 * c + d; + }; - /* @; */ + /* the actual kerns */ + for (k = 0; k < nk; k++) { + store_scaled(sw); + kerns[k] = sw; + } - if (np>7) { - set_font_params(f,np); - } - for (k=1;k<=np;k++) { - if (k==1) { /* the |slant| parameter is a pure number */ - fget; sw=fbyte; - if (sw>127) sw=sw-256; - fget; sw=sw*256+fbyte; - fget; sw=sw*256+fbyte; - fget; sw=(sw*16)+(fbyte>>4); - set_font_param(f,k,sw); - } else { - store_scaled(font_param(f,k)); + /* @; */ + for (k = 0; k < ne; k++) { + read_four_quarters(qw); + extens[k] = qw; } - } - /* - We check to see that the \.{TFM} file doesn't end prematurely; but - no error message is given for files having more than |lf| words. - */ - - if (tfm_byte stop_flag) - k = lig_kern_restart(k); - */ - while (1) { - if (skip_byte(k) <= stop_flag) { - if(op_byte(k) >= kern_flag) { /* kern */ - fkerns++; - } else { /* lig */ - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } + /* @; */ + + if (np > 7) { + set_font_params(f, np); } - } - if (fkerns >0 || fligs > 0) { - if (fligs>0) cligs = xcalloc((fligs+1),sizeof(liginfo)); - if (fkerns>0) ckerns = xcalloc((fkerns+1),sizeof(kerninfo)); + for (k = 1; k <= np; k++) { + if (k == 1) { /* the |slant| parameter is a pure number */ + fget; + sw = fbyte; + if (sw > 127) + sw = sw - 256; + fget; + sw = sw * 256 + fbyte; + fget; + sw = sw * 256 + fbyte; + fget; + sw = (sw * 16) + (fbyte >> 4); + set_font_param(f, k, sw); + } else { + store_scaled(font_param(f, k)); + } + } + + tfm_byte = saved_tfm_byte; + + /* fix up the left boundary character */ fligs = 0; fkerns = 0; - k = bch_label; - /* - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); - */ - while (1) { - if (skip_byte(k) <= stop_flag) { - if(op_byte(k) >= kern_flag) { /* kern */ - set_kern_item(ckerns[fkerns],next_char(k),kerns[256*(op_byte(k)-128)+rem_byte(k)]); - fkerns++; - } else { /* lig */ - set_ligature_item(cligs[fligs],(op_byte(k)*2+1),next_char(k),rem_byte(k)); - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } + if (bch_label != nl) { + k = bch_label; + /* + if (skip_byte(k) > stop_flag) + k = lig_kern_restart(k); + */ + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { /* kern */ + fkerns++; + } else { /* lig */ + fligs++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } } - if (fkerns>0 || fligs>0){ - co = get_charinfo(f,left_boundarychar); - if (fkerns>0) { - set_kern_item(ckerns[fkerns],end_kern,0); - fkerns++; - set_charinfo_kerns(co,ckerns); - } - if (fligs>0){ - set_ligature_item(cligs[fligs],0,end_ligature,0); - fligs++; - set_charinfo_ligatures(co,cligs); - } - set_charinfo_remainder(co,0); + if (fkerns > 0 || fligs > 0) { + if (fligs > 0) + cligs = xcalloc((fligs + 1), sizeof(liginfo)); + if (fkerns > 0) + ckerns = xcalloc((fkerns + 1), sizeof(kerninfo)); + fligs = 0; + fkerns = 0; + k = bch_label; + /* + if (skip_byte(k) > stop_flag) + k = lig_kern_restart(k); + */ + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { /* kern */ + set_kern_item(ckerns[fkerns], next_char(k), + kerns[256 * (op_byte(k) - 128) + + rem_byte(k)]); + fkerns++; + } else { /* lig */ + set_ligature_item(cligs[fligs], (op_byte(k) * 2 + 1), + next_char(k), rem_byte(k)); + fligs++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } + if (fkerns > 0 || fligs > 0) { + co = get_charinfo(f, left_boundarychar); + if (fkerns > 0) { + set_kern_item(ckerns[fkerns], end_kern, 0); + fkerns++; + set_charinfo_kerns(co, ckerns); + } + if (fligs > 0) { + set_ligature_item(cligs[fligs], 0, end_ligature, 0); + fligs++; + set_charinfo_ligatures(co, cligs); + } + set_charinfo_remainder(co, 0); + } } - } - /* @; */ - for (k=bc;k<=ec;k++) { - store_char_info(k); - if (ci._width_index==0) - continue; - if (ci._width_index>=nw||ci._height_index>=nh|| - ci._depth_index>=nd||ci._italic_index>=ni) tfm_abort; - d = ci._remainder; - switch (ci._tag) { - case lig_tag: if (d>=nl) tfm_abort; break; - case ext_tag: if (d>=ne) tfm_abort; break; - case list_tag: - /* We want to make sure that there is no cycle of characters linked together - by |list_tag| entries, since such a cycle would get \TeX\ into an endless - loop. If such a cycle exists, the routine here detects it when processing - the largest character code in the cycle. - */ - check_byte_range(d); - while (d stop_flag) - k = lig_kern_restart(k); - /* now k is the start index */ - while (1) { - if (skip_byte(k) <= stop_flag) { - if(op_byte(k) >= kern_flag) { /* kern */ - xkerns[i]++; - if (next_char(k) == bchar) - xkerns[i]++; - } else { /* lig */ - xligs[i]++; - if (next_char(k) == bchar) - xligs[i]++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } + /* @; */ + for (k = bc; k <= ec; k++) { + store_char_info(k); + if (ci._width_index == 0) + continue; + if (ci._width_index >= nw || ci._height_index >= nh || + ci._depth_index >= nd || ci._italic_index >= ni) + tfm_abort; + d = ci._remainder; + switch (ci._tag) { + case lig_tag: + if (d >= nl) + tfm_abort; + break; + case ext_tag: + if (d >= ne) + tfm_abort; + break; + case list_tag: + /* We want to make sure that there is no cycle of characters linked together + by |list_tag| entries, since such a cycle would get \TeX\ into an endless + loop. If such a cycle exists, the routine here detects it when processing + the largest character code in the cycle. + */ + check_byte_range(d); + while (d < k) { /* current_character == k */ + if (char_tag(f, d) != list_tag) + goto NOT_FOUND; /* not a cycle */ + d = char_remainder(f, d); /* next character on the list */ + }; + if (d == k) + tfm_abort; /* yes, there's a cycle */ + NOT_FOUND: + break; + } + /* put it in the actual font */ + co = get_charinfo(f, k); + set_charinfo_index(co, k); + set_charinfo_tag(co, ci._tag); + if (ci._tag == ext_tag) { + set_charinfo_extensible(co, extens[ci._remainder].b0, /* top */ + extens[ci._remainder].b2, /* bot */ + extens[ci._remainder].b1, /* mid */ + extens[ci._remainder].b3); /* rep */ + set_charinfo_remainder(co, 0); + } else { + set_charinfo_remainder(co, ci._remainder); + } + set_charinfo_width(co, widths[ci._width_index]); + set_charinfo_height(co, heights[ci._height_index]); + set_charinfo_depth(co, depths[ci._depth_index]); + set_charinfo_italic(co, italics[ci._italic_index]); + }; + + /* first pass: count ligs and kerns */ + + xligs = xcalloc((ec + 1), sizeof(integer)); + xkerns = xcalloc((ec + 1), sizeof(integer)); + + for (i = bc; i <= ec; i++) { + if (char_tag(f, i) == lig_tag) { + k = lig_kern_start(f, i); + if (skip_byte(k) > stop_flag) + k = lig_kern_restart(k); + /* now k is the start index */ + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { /* kern */ + xkerns[i]++; + if (next_char(k) == bchar) + xkerns[i]++; + } else { /* lig */ + xligs[i]++; + if (next_char(k) == bchar) + xligs[i]++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } + } } - } - - cligs = NULL; - ckerns = NULL; - for (i=bc;i<=ec;i++) { - fligs = 0; - fkerns = 0; - if (char_tag(f,i) == lig_tag) { - k = lig_kern_start(f,i); - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); - /* now k is the start index */ - if (xligs[i]>0) cligs = xcalloc((xligs[i]+1),sizeof(liginfo)); - if (xkerns[i]>0) ckerns = xcalloc((xkerns[i]+1),sizeof(kerninfo)); - while (1) { - if (skip_byte(k) <= stop_flag) { - if(op_byte(k) >= kern_flag) { /* kern */ - if (next_char(k) == bchar) { - set_kern_item(ckerns[fkerns],right_boundarychar,kerns[256*(op_byte(k)-128)+rem_byte(k)]); - fkerns++; - } - set_kern_item(ckerns[fkerns],next_char(k),kerns[256*(op_byte(k)-128)+rem_byte(k)]); - fkerns++; - } else { /* lig */ - if (next_char(k) == bchar) { - set_ligature_item(cligs[fligs],(op_byte(k)*2+1),right_boundarychar,rem_byte(k)); - fligs++; - } - set_ligature_item(cligs[fligs],(op_byte(k)*2+1),next_char(k),rem_byte(k)); - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - if (fkerns>0 || fligs>0){ - co = get_charinfo(f,i); - if (fkerns>0) { - set_kern_item(ckerns[fkerns],end_kern,0); - fkerns++; - set_charinfo_kerns(co,ckerns); - } - if (fligs>0){ - set_ligature_item(cligs[fligs],0,end_ligature,0); - fligs++; - set_charinfo_ligatures(co,cligs); - } - set_charinfo_remainder(co,0); - } + cligs = NULL; + ckerns = NULL; + + for (i = bc; i <= ec; i++) { + fligs = 0; + fkerns = 0; + if (char_tag(f, i) == lig_tag) { + k = lig_kern_start(f, i); + if (skip_byte(k) > stop_flag) + k = lig_kern_restart(k); + /* now k is the start index */ + if (xligs[i] > 0) + cligs = xcalloc((xligs[i] + 1), sizeof(liginfo)); + if (xkerns[i] > 0) + ckerns = xcalloc((xkerns[i] + 1), sizeof(kerninfo)); + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { /* kern */ + if (next_char(k) == bchar) { + set_kern_item(ckerns[fkerns], right_boundarychar, + kerns[256 * (op_byte(k) - 128) + + rem_byte(k)]); + fkerns++; + } + set_kern_item(ckerns[fkerns], next_char(k), + kerns[256 * (op_byte(k) - 128) + + rem_byte(k)]); + fkerns++; + } else { /* lig */ + if (next_char(k) == bchar) { + set_ligature_item(cligs[fligs], + (op_byte(k) * 2 + 1), + right_boundarychar, rem_byte(k)); + fligs++; + } + set_ligature_item(cligs[fligs], (op_byte(k) * 2 + 1), + next_char(k), rem_byte(k)); + fligs++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } + if (fkerns > 0 || fligs > 0) { + co = get_charinfo(f, i); + if (fkerns > 0) { + set_kern_item(ckerns[fkerns], end_kern, 0); + fkerns++; + set_charinfo_kerns(co, ckerns); + } + if (fligs > 0) { + set_ligature_item(cligs[fligs], 0, end_ligature, 0); + fligs++; + set_charinfo_ligatures(co, cligs); + } + set_charinfo_remainder(co, 0); + } + } } - } - /* @ */ + /* @ */ - /* Now to wrap it up, we have checked all the necessary things about the \.{TFM} - file, and all we need to do is put the finishing touches on the data for - the new font. - */ + /* Now to wrap it up, we have checked all the necessary things about the \.{TFM} + file, and all we need to do is put the finishing touches on the data for + the new font. + */ - if (bchar!= 65536) { - co = copy_charinfo(char_info(f,bchar)); - set_right_boundary(f,co); - } + if (bchar != 65536) { + co = copy_charinfo(char_info(f, bchar)); + set_right_boundary(f, co); + } - tfm_success; + tfm_success; } - diff --git a/Build/source/texk/web2c/luatexdir/font/tounicode.c b/Build/source/texk/web2c/luatexdir/font/tounicode.c index ff86a8512e2..29ee8c9bd0b 100644 --- a/Build/source/texk/web2c/luatexdir/font/tounicode.c +++ b/Build/source/texk/web2c/luatexdir/font/tounicode.c @@ -1,25 +1,27 @@ -/* -Copyright (c) 2006 Han The Thanh, +/* tounicode.c + Copyright 2006 Han The Thanh, + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" +static const char _svn_version[] = + "$Id: tounicode.c 2029 2009-03-14 19:10:25Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tounicode.c $"; + #define isXdigit(c) (isdigit(c) || ('A' <= (c) && (c) <= 'F')) #define UNI_UNDEF -1 #define UNI_STRING -2 /* string allocated by def_tounicode() */ @@ -289,17 +291,17 @@ static void set_glyph_unicode(char *s, glyph_unicode_entry * gp) } } -static void set_cid_glyph_unicode(long index, glyph_unicode_entry * gp, - internal_font_number f) { - char *s; - if (font_tounicode(f)) { - if ((s = get_charinfo_tounicode(char_info(f,index)))!=NULL) { +static void set_cid_glyph_unicode(long index, glyph_unicode_entry * gp, + internal_font_number f) +{ + char *s; + if (font_tounicode(f) && + (s = get_charinfo_tounicode(char_info(f, index))) != NULL) { gp->code = UNI_EXTRA_STRING; gp->unicode_seq = xstrdup(s); - } - } else { - gp->code = index; /* fallback */ - } + } else { + gp->code = index; /* fallback */ + } } @@ -314,7 +316,7 @@ integer write_tounicode(char **glyph_names, char *name) int bfchar_count, bfrange_count, subrange_count; assert(strlen(name) + strlen(builtin_suffix) < SMALL_BUF_SIZE); if (glyph_unicode_tree == NULL) { - pdftex_warn("no GlyphToUnicode entry has been inserted yet!"); + /*pdftex_warn("no GlyphToUnicode entry has been inserted yet!"); */ fixed_gen_tounicode = 0; return 0; } @@ -451,19 +453,21 @@ integer write_tounicode(char **glyph_names, char *name) return objnum; } -integer write_cid_tounicode(fo_entry * fo, internalfontnumber f) { +integer write_cid_tounicode(fo_entry * fo, internalfontnumber f) +{ int range_size[65537]; glyph_unicode_entry gtab[65537]; integer objnum; int i, j, k; int bfchar_count, bfrange_count, subrange_count; - char *buf; + char *buf; - assert(fo->fd->fontname); - buf = xmalloc(strlen(fo->fd->fontname)+8); - sprintf(buf,"%s-%s",(fo->fd->subset_tag!=NULL ? fo->fd->subset_tag : "UCS"), - fo->fd->fontname); + assert(fo->fd->fontname); + buf = xmalloc(strlen(fo->fd->fontname) + 8); + sprintf(buf, "%s-%s", + (fo->fd->subset_tag != NULL ? fo->fd->subset_tag : "UCS"), + fo->fd->fontname); objnum = pdf_new_objnum(); pdf_begin_dict(objnum, 0); @@ -486,25 +490,25 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber f) { "/CMapName /TeX-Identity-%s def\n" "/CMapType 2 def\n" "1 begincodespacerange\n" - "<0000> \n" + "<0000> \n" "endcodespacerange\n", buf, buf, buf, buf, buf); - xfree(buf); + xfree(buf); /* set up gtab */ for (i = 0; i < 65537; ++i) { gtab[i].code = UNI_UNDEF; } - for (k = 1; k <= max_font_id(); k++) { - if (k == f || -f == pdf_font_num(k)) { - for (i = font_bc(k); i <= font_ec(k); i++) { - if (char_exists(k,i) && char_used(k,i)) { - j = char_index(k,i); - if (gtab[j].code == UNI_UNDEF) { - set_cid_glyph_unicode(i, >ab[j], f); - } - } - } - } - } + for (k = 1; k <= max_font_id(); k++) { + if (k == f || -f == pdf_font_num(k)) { + for (i = font_bc(k); i <= font_ec(k); i++) { + if (char_exists(k, i) && char_used(k, i)) { + j = char_index(k, i); + if (gtab[j].code == UNI_UNDEF) { + set_cid_glyph_unicode(i, >ab[j], f); + } + } + } + } + } /* set range_size */ for (i = 0; i < 65536;) { @@ -522,7 +526,7 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber f) { /* at this point i is the last entry of the subrange */ i++; /* move i to the next entry */ range_size[j] = i - j; - } + } } /* calculate bfrange_count and bfchar_count */ diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c index bf21e58c49a..b024897f82d 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c +++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c @@ -1,24 +1,23 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/tt_glyf.c,v 1.2 2005/06/09 14:31:11 hirata Exp $ +/* tt_glyf.c - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team + Copyright 2006-2008 Taco Hoekwater - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ /* * Subsetting glyf, updating loca, hmtx, ... @@ -30,629 +29,623 @@ #include "sfnt.h" #include "tt_table.h" #include "tt_glyf.h" +#include "writettf.h" + +static const char _svn_version[] = + "$Id: tt_glyf.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tt_glyf.c $"; #define NUM_GLYPH_LIMIT 65534 #define TABLE_DATA_ALLOC_SIZE 40960 #define GLYPH_ARRAY_ALLOC_SIZE 256 -static USHORT -find_empty_slot (struct tt_glyphs *g) +static USHORT find_empty_slot(struct tt_glyphs *g) { - USHORT gid; + USHORT gid; - ASSERT(g); + ASSERT(g); - for (gid = 0; gid < NUM_GLYPH_LIMIT; gid++) { - if (!(g->used_slot[gid/8] & (1 << (7 - (gid % 8))))) - break; - } - if (gid == NUM_GLYPH_LIMIT) - TT_ERROR("No empty glyph slot available."); + for (gid = 0; gid < NUM_GLYPH_LIMIT; gid++) { + if (!(g->used_slot[gid / 8] & (1 << (7 - (gid % 8))))) + break; + } + if (gid == NUM_GLYPH_LIMIT) + TT_ERROR("No empty glyph slot available."); - return gid; + return gid; } -USHORT -tt_find_glyph (struct tt_glyphs *g, USHORT gid) +USHORT tt_find_glyph(struct tt_glyphs * g, USHORT gid) { - USHORT idx, new_gid = 0; + USHORT idx, new_gid = 0; - ASSERT(g); + ASSERT(g); - for (idx = 0; idx < g->num_glyphs; idx++) { - if (gid == g->gd[idx].ogid) { - new_gid = g->gd[idx].gid; - break; + for (idx = 0; idx < g->num_glyphs; idx++) { + if (gid == g->gd[idx].ogid) { + new_gid = g->gd[idx].gid; + break; + } } - } - return new_gid; + return new_gid; } -USHORT -tt_get_index (struct tt_glyphs *g, USHORT gid) +USHORT tt_get_index(struct tt_glyphs * g, USHORT gid) { - USHORT idx; + USHORT idx; - ASSERT(g); + ASSERT(g); - for (idx = 0; idx < g->num_glyphs; idx++) { - if (gid == g->gd[idx].gid) - break; - } - if (idx == g->num_glyphs) - idx = 0; + for (idx = 0; idx < g->num_glyphs; idx++) { + if (gid == g->gd[idx].gid) + break; + } + if (idx == g->num_glyphs) + idx = 0; - return idx; + return idx; } -USHORT -tt_add_glyph (struct tt_glyphs *g, USHORT gid, USHORT new_gid) +USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid) { - ASSERT(g); + ASSERT(g); - if (g->used_slot[new_gid/8] & (1 << (7 - (new_gid % 8)))) { - WARN("Slot %u already used.", new_gid); - } else { - if (g->num_glyphs+1 >= NUM_GLYPH_LIMIT) - TT_ERROR("Too many glyphs."); + if (g->used_slot[new_gid / 8] & (1 << (7 - (new_gid % 8)))) { + WARN("Slot %u already used.", new_gid); + } else { + if (g->num_glyphs + 1 >= NUM_GLYPH_LIMIT) + TT_ERROR("Too many glyphs."); + + if (g->num_glyphs >= g->max_glyphs) { + g->max_glyphs += GLYPH_ARRAY_ALLOC_SIZE; + g->gd = RENEW(g->gd, g->max_glyphs, struct tt_glyph_desc); + } + g->gd[g->num_glyphs].gid = new_gid; + g->gd[g->num_glyphs].ogid = gid; + g->gd[g->num_glyphs].length = 0; + g->gd[g->num_glyphs].data = NULL; + g->used_slot[new_gid / 8] |= (1 << (7 - (new_gid % 8))); + g->num_glyphs += 1; + } - if (g->num_glyphs >= g->max_glyphs) { - g->max_glyphs += GLYPH_ARRAY_ALLOC_SIZE; - g->gd = RENEW(g->gd, g->max_glyphs, struct tt_glyph_desc); + if (new_gid > g->last_gid) { + g->last_gid = new_gid; } - g->gd[g->num_glyphs].gid = new_gid; - g->gd[g->num_glyphs].ogid = gid; - g->gd[g->num_glyphs].length = 0; - g->gd[g->num_glyphs].data = NULL; - g->used_slot[new_gid/8] |= (1 << (7 - (new_gid % 8))); - g->num_glyphs += 1; - } - - if (new_gid > g->last_gid) { - g->last_gid = new_gid; - } - - return new_gid; + + return new_gid; } /* * Initialization */ -struct tt_glyphs * -tt_build_init (void) +struct tt_glyphs *tt_build_init(void) { - struct tt_glyphs *g; - - g = NEW(1, struct tt_glyphs); - - g->num_glyphs = 0; - g->max_glyphs = 0; - g->last_gid = 0; - g->emsize = 1; - g->default_advh = 0; - g->default_tsb = 0; - g->gd = NULL; - g->used_slot = NEW(8192, unsigned char); - memset(g->used_slot, 0, 8192); - tt_add_glyph(g, 0, 0); - - return g; + struct tt_glyphs *g; + + g = NEW(1, struct tt_glyphs); + + g->num_glyphs = 0; + g->max_glyphs = 0; + g->last_gid = 0; + g->emsize = 1; + g->default_advh = 0; + g->default_tsb = 0; + g->gd = NULL; + g->used_slot = NEW(8192, unsigned char); + memset(g->used_slot, 0, 8192); + tt_add_glyph(g, 0, 0); + + return g; } -void -tt_build_finish (struct tt_glyphs *g) +void tt_build_finish(struct tt_glyphs *g) { - if (g) { - if (g->gd) { - USHORT idx; - for (idx = 0; idx < g->num_glyphs; idx++) { - if (g->gd[idx].data) - RELEASE(g->gd[idx].data); - } - RELEASE(g->gd); + if (g) { + if (g->gd) { + USHORT idx; + for (idx = 0; idx < g->num_glyphs; idx++) { + if (g->gd[idx].data) + RELEASE(g->gd[idx].data); + } + RELEASE(g->gd); + } + if (g->used_slot) + RELEASE(g->used_slot); + RELEASE(g); } - if (g->used_slot) - RELEASE(g->used_slot); - RELEASE(g); - } } -static int -glyf_cmp (const void *v1, const void *v2) +static int glyf_cmp(const void *v1, const void *v2) { - int cmp = 0; - struct tt_glyph_desc *sv1, *sv2; - - sv1 = (struct tt_glyph_desc *) v1; - sv2 = (struct tt_glyph_desc *) v2; - - if (sv1->gid == sv2->gid) - cmp = 0; - else if (sv1->gid < sv2->gid) - cmp = -1; - else - cmp = 1; - - return cmp; + int cmp = 0; + struct tt_glyph_desc *sv1, *sv2; + + sv1 = (struct tt_glyph_desc *) v1; + sv2 = (struct tt_glyph_desc *) v2; + + if (sv1->gid == sv2->gid) + cmp = 0; + else if (sv1->gid < sv2->gid) + cmp = -1; + else + cmp = 1; + + return cmp; } -/* - * TrueType outline data. - */ -#define ARG_1_AND_2_ARE_WORDS (1 << 0) -#define ARGS_ARE_XY_VALUES (1 << 1) -#define ROUND_XY_TO_GRID (1 << 2) -#define WE_HAVE_A_SCALE (1 << 3) -#define RESERVED (1 << 4) -#define MORE_COMPONENT (1 << 5) -#define WE_HAVE_AN_X_AND_Y_SCALE (1 << 6) -#define WE_HAVE_A_TWO_BY_TWO (1 << 7) -#define WE_HAVE_INSTRUCTIONS (1 << 8) -#define USE_MY_METRICS (1 << 9) - -int -tt_build_tables (sfnt *sfont, struct tt_glyphs *g) +int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) { - char *hmtx_table_data = NULL, *loca_table_data = NULL; - char *glyf_table_data = NULL; - ULONG hmtx_table_size, loca_table_size, glyf_table_size; - /* some information available from other TrueType table */ - struct tt_head_table *head = NULL; - struct tt_hhea_table *hhea = NULL; - struct tt_maxp_table *maxp = NULL; - struct tt_longMetrics *hmtx, *vmtx = NULL; - struct tt_os2__table *os2; - /* temp */ - ULONG *location, offset; - long i; - USHORT *w_stat; /* Estimate most frequently appeared width */ - - ASSERT(g); - - if (sfont->type != SFNT_TYPE_TRUETYPE && - sfont->type != SFNT_TYPE_TTC) - TT_ERROR("Invalid font type"); - - if (g->num_glyphs > NUM_GLYPH_LIMIT) - TT_ERROR("Too many glyphs."); - - /* - * Read head, hhea, maxp, loca: - * - * unitsPerEm --> head - * numHMetrics --> hhea - * indexToLocFormat --> head - * numGlyphs --> maxp - */ - head = tt_read_head_table(sfont); - hhea = tt_read_hhea_table(sfont); - maxp = tt_read_maxp_table(sfont); - - if (hhea->metricDataFormat != 0) - TT_ERROR("Unknown metricDataFormat."); - - g->emsize = head->unitsPerEm; - - sfnt_locate_table(sfont, "hmtx"); - hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics); - - os2 = tt_read_os2__table(sfont); - if (os2) { - g->default_advh = os2->sTypoAscender - os2->sTypoDescender; - g->default_tsb = g->default_advh - os2->sTypoAscender; - } - - if (sfnt_find_table_pos(sfont, "vmtx") > 0) { - struct tt_vhea_table *vhea; - vhea = tt_read_vhea_table(sfont); - sfnt_locate_table(sfont, "vmtx"); - vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics); - RELEASE(vhea); - } else { - vmtx = NULL; - } - - sfnt_locate_table(sfont, "loca"); - location = NEW(maxp->numGlyphs + 1, ULONG); - if (head->indexToLocFormat == 0) { - for (i = 0; i <= maxp->numGlyphs; i++) - location[i] = 2*((ULONG) sfnt_get_ushort(sfont)); - } else if (head->indexToLocFormat == 1) { - for (i = 0; i <= maxp->numGlyphs; i++) - location[i] = sfnt_get_ulong(sfont); - } else { - TT_ERROR("Unknown IndexToLocFormat."); - } - - w_stat = NEW(g->emsize+2, USHORT); - memset(w_stat, 0, sizeof(USHORT)*(g->emsize+2)); - /* - * Read glyf table. - */ - offset = sfnt_locate_table(sfont, "glyf"); - /* - * The num_glyphs may grow when composite glyph is found. - * A component of glyph refered by a composite glyph is appended - * to used_glyphs if it is not already registered in used_glyphs. - * Glyph programs of composite glyphs are modified so that it - * correctly refer to new gid of their components. - */ - for (i = 0; i < NUM_GLYPH_LIMIT; i++) { - USHORT gid; /* old gid */ - ULONG loc, len; - BYTE *p, *endptr; - SHORT number_of_contours; - - if (i >= g->num_glyphs) /* finished */ - break; - - gid = g->gd[i].ogid; - if (gid >= maxp->numGlyphs) - TT_ERROR("Invalid glyph index (gid %u)", gid); - - loc = location[gid]; - len = location[gid+1] - loc; - g->gd[i].advw = hmtx[gid].advance; - g->gd[i].lsb = hmtx[gid].sideBearing; - if (vmtx) { - g->gd[i].advh = vmtx[gid].advance; - g->gd[i].tsb = vmtx[gid].sideBearing; - } else { - g->gd[i].advh = g->default_advh; - g->gd[i].tsb = g->default_tsb; - } - g->gd[i].length = len; - g->gd[i].data = NULL; - if (g->gd[i].advw <= g->emsize) { - w_stat[g->gd[i].advw] += 1; - } else { - w_stat[g->emsize+1] += 1; /* larger than em */ - } + char *hmtx_table_data = NULL, *loca_table_data = NULL; + char *glyf_table_data = NULL; + ULONG hmtx_table_size, loca_table_size, glyf_table_size; + /* some information available from other TrueType table */ + struct tt_head_table *head = NULL; + struct tt_hhea_table *hhea = NULL; + struct tt_maxp_table *maxp = NULL; + struct tt_longMetrics *hmtx, *vmtx = NULL; + struct tt_os2__table *os2; + /* temp */ + ULONG *location, offset; + long i; + USHORT *w_stat; /* Estimate most frequently appeared width */ + + ASSERT(g); + + if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC) + TT_ERROR("Invalid font type"); + + if (g->num_glyphs > NUM_GLYPH_LIMIT) + TT_ERROR("Too many glyphs."); - if (len == 0) { /* Does not contains any data. */ - continue; - } else if (len < 10) { - TT_ERROR("Invalid TrueType glyph data (gid %u).", gid); - } + /* + * Read head, hhea, maxp, loca: + * + * unitsPerEm --> head + * numHMetrics --> hhea + * indexToLocFormat --> head + * numGlyphs --> maxp + */ + head = tt_read_head_table(sfont); + hhea = tt_read_hhea_table(sfont); + maxp = tt_read_maxp_table(sfont); - g->gd[i].data = p = NEW(len, BYTE); - endptr = p + len; + if (hhea->metricDataFormat != 0) + TT_ERROR("Unknown metricDataFormat."); - sfnt_seek_set(sfont, offset+loc); - number_of_contours = sfnt_get_short(sfont); - p += sfnt_put_short(p, number_of_contours); + g->emsize = head->unitsPerEm; - /* BoundingBox: FWord x 4 */ - g->gd[i].llx = sfnt_get_short(sfont); - g->gd[i].lly = sfnt_get_short(sfont); - g->gd[i].urx = sfnt_get_short(sfont); - g->gd[i].ury = sfnt_get_short(sfont); - /* _FIXME_ */ -#if 1 - if (!vmtx) /* vertOriginY == sTypeAscender */ - g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury; -#endif - p += sfnt_put_short(p, g->gd[i].llx); - p += sfnt_put_short(p, g->gd[i].lly); - p += sfnt_put_short(p, g->gd[i].urx); - p += sfnt_put_short(p, g->gd[i].ury); + sfnt_locate_table(sfont, "hmtx"); + hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics); - /* Read evrything else. */ - sfnt_read(p, len - 10, sfont); - /* - * Fix GIDs of composite glyphs. - */ - if (number_of_contours < 0) { - USHORT flags, cgid, new_gid; /* flag, gid of a component */ - do { - if (p >= endptr) - TT_ERROR("Invalid TrueType glyph data (gid %u): %u bytes", gid, (unsigned int)len); - /* - * Flags and gid of component glyph are both USHORT. - */ - flags = ((*p) << 8)| *(p+1); - p += 2; - cgid = ((*p) << 8)| *(p+1); - if (cgid >= maxp->numGlyphs) { - TT_ERROR("Invalid gid (%u > %u) in composite glyph %u.", cgid, maxp->numGlyphs, gid); - } - new_gid = tt_find_glyph(g, cgid); - if (new_gid == 0) { - new_gid = tt_add_glyph(g, cgid, find_empty_slot(g)); - } - p += sfnt_put_ushort(p, new_gid); - /* - * Just skip remaining part. - */ - p += (flags & ARG_1_AND_2_ARE_WORDS) ? 4 : 2; - if (flags & WE_HAVE_A_SCALE) /* F2Dot14 */ - p += 2; - else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) /* F2Dot14 x 2 */ - p += 4; - else if (flags & WE_HAVE_A_TWO_BY_TWO) /* F2Dot14 x 4 */ - p += 8; - } while (flags & MORE_COMPONENT); - /* - * TrueType instructions comes here: - * length_of_instruction (ushort) - * instruction (byte * length_of_instruction) - */ - } - } - RELEASE(location); - RELEASE(hmtx); - if (vmtx) - RELEASE(vmtx); - - { - int max_count = -1; - - g->dw = g->gd[0].advw; - for (i = 0; i < g->emsize + 1; i++) { - if (w_stat[i] > max_count) { - max_count = w_stat[i]; - g->dw = i; - } + os2 = tt_read_os2__table(sfont); + if (os2) { + g->default_advh = os2->sTypoAscender - os2->sTypoDescender; + g->default_tsb = g->default_advh - os2->sTypoAscender; + + /* dvipdfmx does this elsewhere! */ + fd_cur->font_dim[STEMV_CODE].val = + (os2->usWeightClass / 65) * (os2->usWeightClass / 65) + 50; } - } - RELEASE(w_stat); - - qsort(g->gd, g->num_glyphs, sizeof(struct tt_glyph_desc), glyf_cmp); - { - USHORT prev, last_advw; - char *p, *q; - int padlen, num_hm_known; - - glyf_table_size = 0UL; - num_hm_known = 0; - last_advw = g->gd[g->num_glyphs - 1].advw; - for (i = g->num_glyphs - 1; i >= 0; i--) { - padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0; - glyf_table_size += g->gd[i].length + padlen; - if (!num_hm_known && last_advw != g->gd[i].advw) { - hhea->numberOfHMetrics = g->gd[i].gid + 2; - num_hm_known = 1; - } + + if (sfnt_find_table_pos(sfont, "vmtx") > 0) { + struct tt_vhea_table *vhea; + vhea = tt_read_vhea_table(sfont); + sfnt_locate_table(sfont, "vmtx"); + vmtx = + tt_read_longMetrics(sfont, maxp->numGlyphs, + vhea->numOfLongVerMetrics); + RELEASE(vhea); + } else { + vmtx = NULL; } - /* All advance widths are same. */ - if (!num_hm_known) { - hhea->numberOfHMetrics = 1; + + sfnt_locate_table(sfont, "loca"); + location = NEW(maxp->numGlyphs + 1, ULONG); + if (head->indexToLocFormat == 0) { + for (i = 0; i <= maxp->numGlyphs; i++) + location[i] = 2 * ((ULONG) sfnt_get_ushort(sfont)); + } else if (head->indexToLocFormat == 1) { + for (i = 0; i <= maxp->numGlyphs; i++) + location[i] = sfnt_get_ulong(sfont); + } else { + TT_ERROR("Unknown IndexToLocFormat."); } - hmtx_table_size = hhea->numberOfHMetrics * 2 + (g->last_gid + 1) * 2; + w_stat = NEW(g->emsize + 2, USHORT); + memset(w_stat, 0, sizeof(USHORT) * (g->emsize + 2)); /* - * Choosing short format does not always give good result - * when compressed. Sometimes increases size. + * Read glyf table. */ - if (glyf_table_size < 0x20000UL) { - head->indexToLocFormat = 0; - loca_table_size = (g->last_gid + 2)*2; - } else { - head->indexToLocFormat = 1; - loca_table_size = (g->last_gid + 2)*4; + offset = sfnt_locate_table(sfont, "glyf"); + /* + * The num_glyphs may grow when composite glyph is found. + * A component of glyph refered by a composite glyph is appended + * to used_glyphs if it is not already registered in used_glyphs. + * Glyph programs of composite glyphs are modified so that it + * correctly refer to new gid of their components. + */ + for (i = 0; i < NUM_GLYPH_LIMIT; i++) { + USHORT gid; /* old gid */ + ULONG loc, len; + BYTE *p, *endptr; + SHORT number_of_contours; + + if (i >= g->num_glyphs) /* finished */ + break; + + gid = g->gd[i].ogid; + if (gid >= maxp->numGlyphs) + TT_ERROR("Invalid glyph index (gid %u)", gid); + + loc = location[gid]; + len = location[gid + 1] - loc; + g->gd[i].advw = hmtx[gid].advance; + g->gd[i].lsb = hmtx[gid].sideBearing; + if (vmtx) { + g->gd[i].advh = vmtx[gid].advance; + g->gd[i].tsb = vmtx[gid].sideBearing; + } else { + g->gd[i].advh = g->default_advh; + g->gd[i].tsb = g->default_tsb; + } + g->gd[i].length = len; + g->gd[i].data = NULL; + if (g->gd[i].advw <= g->emsize) { + w_stat[g->gd[i].advw] += 1; + } else { + w_stat[g->emsize + 1] += 1; /* larger than em */ + } + + if (len == 0) { /* Does not contains any data. */ + continue; + } else if (len < 10) { + TT_ERROR("Invalid TrueType glyph data (gid %u).", gid); + } + + g->gd[i].data = p = NEW(len, BYTE); + endptr = p + len; + + sfnt_seek_set(sfont, offset + loc); + number_of_contours = sfnt_get_short(sfont); + p += sfnt_put_short(p, number_of_contours); + + /* BoundingBox: FWord x 4 */ + g->gd[i].llx = sfnt_get_short(sfont); + g->gd[i].lly = sfnt_get_short(sfont); + g->gd[i].urx = sfnt_get_short(sfont); + g->gd[i].ury = sfnt_get_short(sfont); + /* _FIXME_ */ +#if 1 + if (!vmtx) /* vertOriginY == sTypeAscender */ + g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury; +#endif + p += sfnt_put_short(p, g->gd[i].llx); + p += sfnt_put_short(p, g->gd[i].lly); + p += sfnt_put_short(p, g->gd[i].urx); + p += sfnt_put_short(p, g->gd[i].ury); + + /* Read evrything else. */ + sfnt_read(p, len - 10, sfont); + /* + * Fix GIDs of composite glyphs. + */ + if (number_of_contours < 0) { + USHORT flags, cgid, new_gid; /* flag, gid of a component */ + do { + if (p >= endptr) + TT_ERROR("Invalid TrueType glyph data (gid %u): %u bytes", + gid, (unsigned int) len); + /* + * Flags and gid of component glyph are both USHORT. + */ + flags = ((*p) << 8) | *(p + 1); + p += 2; + cgid = ((*p) << 8) | *(p + 1); + if (cgid >= maxp->numGlyphs) { + TT_ERROR("Invalid gid (%u > %u) in composite glyph %u.", + cgid, maxp->numGlyphs, gid); + } + new_gid = tt_find_glyph(g, cgid); + if (new_gid == 0) { + new_gid = tt_add_glyph(g, cgid, find_empty_slot(g)); + } + p += sfnt_put_ushort(p, new_gid); + /* + * Just skip remaining part. + */ + p += (flags & ARG_1_AND_2_ARE_WORDS) ? 4 : 2; + if (flags & WE_HAVE_A_SCALE) /* F2Dot14 */ + p += 2; + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) /* F2Dot14 x 2 */ + p += 4; + else if (flags & WE_HAVE_A_TWO_BY_TWO) /* F2Dot14 x 4 */ + p += 8; + } while (flags & MORE_COMPONENTS); + /* + * TrueType instructions comes here: + * length_of_instruction (ushort) + * instruction (byte * length_of_instruction) + */ + } } - - hmtx_table_data = p = NEW(hmtx_table_size, char); - loca_table_data = q = NEW(loca_table_size, char); - glyf_table_data = NEW(glyf_table_size, char); - - offset = 0UL; prev = 0; - for (i = 0; i < g->num_glyphs; i++) { - long gap, j; - gap = (long) g->gd[i].gid - prev - 1; - for (j = 1; j <= gap; j++) { - if (prev + j == hhea->numberOfHMetrics - 1) { - p += sfnt_put_ushort(p, last_advw); - } else if (prev + j < hhea->numberOfHMetrics) { - p += sfnt_put_ushort(p, 0); - } - p += sfnt_put_short (p, 0); - if (head->indexToLocFormat == 0) { - q += sfnt_put_ushort(q, (USHORT) (offset/2)); - } else { - q += sfnt_put_ulong(q, offset); - } - } - padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0; - if (g->gd[i].gid < hhea->numberOfHMetrics) { - p += sfnt_put_ushort(p, g->gd[i].advw); - } - p += sfnt_put_short (p, g->gd[i].lsb); - if (head->indexToLocFormat == 0) { - q += sfnt_put_ushort(q, (USHORT) (offset/2)); - } else { - q += sfnt_put_ulong(q, offset); - } - memset(glyf_table_data + offset, 0, g->gd[i].length + padlen); - memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length); - offset += g->gd[i].length + padlen; - prev = g->gd[i].gid; - /* free data here since it consume much memory */ - RELEASE(g->gd[i].data); - g->gd[i].length = 0; g->gd[i].data = NULL; + RELEASE(location); + RELEASE(hmtx); + if (vmtx) + RELEASE(vmtx); + + { + int max_count = -1; + + g->dw = g->gd[0].advw; + for (i = 0; i < g->emsize + 1; i++) { + if (w_stat[i] > max_count) { + max_count = w_stat[i]; + g->dw = i; + } + } } - if (head->indexToLocFormat == 0) { - q += sfnt_put_ushort(q, (USHORT) (offset/2)); - } else { - q += sfnt_put_ulong(q, offset); + RELEASE(w_stat); + + qsort(g->gd, g->num_glyphs, sizeof(struct tt_glyph_desc), glyf_cmp); + { + USHORT prev, last_advw; + char *p, *q; + int padlen, num_hm_known; + + glyf_table_size = 0UL; + num_hm_known = 0; + last_advw = g->gd[g->num_glyphs - 1].advw; + for (i = g->num_glyphs - 1; i >= 0; i--) { + padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0; + glyf_table_size += g->gd[i].length + padlen; + if (!num_hm_known && last_advw != g->gd[i].advw) { + hhea->numberOfHMetrics = g->gd[i].gid + 2; + num_hm_known = 1; + } + } + /* All advance widths are same. */ + if (!num_hm_known) { + hhea->numberOfHMetrics = 1; + } + hmtx_table_size = hhea->numberOfHMetrics * 2 + (g->last_gid + 1) * 2; + + /* + * Choosing short format does not always give good result + * when compressed. Sometimes increases size. + */ + if (glyf_table_size < 0x20000UL) { + head->indexToLocFormat = 0; + loca_table_size = (g->last_gid + 2) * 2; + } else { + head->indexToLocFormat = 1; + loca_table_size = (g->last_gid + 2) * 4; + } + + hmtx_table_data = p = NEW(hmtx_table_size, char); + loca_table_data = q = NEW(loca_table_size, char); + glyf_table_data = NEW(glyf_table_size, char); + + offset = 0UL; + prev = 0; + for (i = 0; i < g->num_glyphs; i++) { + long gap, j; + gap = (long) g->gd[i].gid - prev - 1; + for (j = 1; j <= gap; j++) { + if (prev + j == hhea->numberOfHMetrics - 1) { + p += sfnt_put_ushort(p, last_advw); + } else if (prev + j < hhea->numberOfHMetrics) { + p += sfnt_put_ushort(p, 0); + } + p += sfnt_put_short(p, 0); + if (head->indexToLocFormat == 0) { + q += sfnt_put_ushort(q, (USHORT) (offset / 2)); + } else { + q += sfnt_put_ulong(q, offset); + } + } + padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0; + if (g->gd[i].gid < hhea->numberOfHMetrics) { + p += sfnt_put_ushort(p, g->gd[i].advw); + } + p += sfnt_put_short(p, g->gd[i].lsb); + if (head->indexToLocFormat == 0) { + q += sfnt_put_ushort(q, (USHORT) (offset / 2)); + } else { + q += sfnt_put_ulong(q, offset); + } + memset(glyf_table_data + offset, 0, g->gd[i].length + padlen); + memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length); + offset += g->gd[i].length + padlen; + prev = g->gd[i].gid; + /* free data here since it consume much memory */ + RELEASE(g->gd[i].data); + g->gd[i].length = 0; + g->gd[i].data = NULL; + } + if (head->indexToLocFormat == 0) { + q += sfnt_put_ushort(q, (USHORT) (offset / 2)); + } else { + q += sfnt_put_ulong(q, offset); + } + + sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data, + hmtx_table_size); + sfnt_set_table(sfont, "loca", (char *) loca_table_data, + loca_table_size); + sfnt_set_table(sfont, "glyf", (char *) glyf_table_data, + glyf_table_size); } - sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data, hmtx_table_size); - sfnt_set_table(sfont, "loca", (char *) loca_table_data, loca_table_size); - sfnt_set_table(sfont, "glyf", (char *) glyf_table_data, glyf_table_size); - } - - head->checkSumAdjustment = 0; - maxp->numGlyphs = g->last_gid + 1; - - /* TODO */ - sfnt_set_table(sfont, "maxp", tt_pack_maxp_table(maxp), TT_MAXP_TABLE_SIZE); - sfnt_set_table(sfont, "hhea", tt_pack_hhea_table(hhea), TT_HHEA_TABLE_SIZE); - sfnt_set_table(sfont, "head", tt_pack_head_table(head), TT_HEAD_TABLE_SIZE); - RELEASE(maxp); - RELEASE(hhea); - RELEASE(head); - if (os2) - RELEASE(os2); + head->checkSumAdjustment = 0; + maxp->numGlyphs = g->last_gid + 1; + + /* TODO */ + sfnt_set_table(sfont, "maxp", tt_pack_maxp_table(maxp), TT_MAXP_TABLE_SIZE); + sfnt_set_table(sfont, "hhea", tt_pack_hhea_table(hhea), TT_HHEA_TABLE_SIZE); + sfnt_set_table(sfont, "head", tt_pack_head_table(head), TT_HEAD_TABLE_SIZE); + RELEASE(maxp); + RELEASE(hhea); + RELEASE(head); + if (os2) + RELEASE(os2); - return 0; + return 0; } -int -tt_get_metrics (sfnt *sfont, struct tt_glyphs *g) +int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) { - struct tt_head_table *head = NULL; - struct tt_hhea_table *hhea = NULL; - struct tt_maxp_table *maxp = NULL; - struct tt_longMetrics *hmtx, *vmtx = NULL; - struct tt_os2__table *os2; - /* temp */ - ULONG *location, offset; - long i; - USHORT *w_stat; - - ASSERT(g); - - if (sfont == NULL || + struct tt_head_table *head = NULL; + struct tt_hhea_table *hhea = NULL; + struct tt_maxp_table *maxp = NULL; + struct tt_longMetrics *hmtx, *vmtx = NULL; + struct tt_os2__table *os2; + /* temp */ + ULONG *location, offset; + long i; + USHORT *w_stat; + + ASSERT(g); + + if (sfont == NULL || #ifdef XETEX - sfont->ft_face == NULL + sfont->ft_face == NULL #elif defined(pdfTeX) - sfont->buffer == NULL + sfont->buffer == NULL #else - sfont->stream == NULL + sfont->stream == NULL #endif - ) - TT_ERROR("File not opened."); - - if (sfont->type != SFNT_TYPE_TRUETYPE && - sfont->type != SFNT_TYPE_TTC) - TT_ERROR("Invalid font type"); - - /* - * Read head, hhea, maxp, loca: - * - * unitsPerEm --> head - * numHMetrics --> hhea - * indexToLocFormat --> head - * numGlyphs --> maxp - */ - head = tt_read_head_table(sfont); - hhea = tt_read_hhea_table(sfont); - maxp = tt_read_maxp_table(sfont); - - if (hhea->metricDataFormat != 0) - TT_ERROR("Unknown metricDataFormat."); - - g->emsize = head->unitsPerEm; - - sfnt_locate_table(sfont, "hmtx"); - hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics); - - os2 = tt_read_os2__table(sfont); - g->default_advh = os2->sTypoAscender - os2->sTypoDescender; - g->default_tsb = g->default_advh - os2->sTypoAscender; - - if (sfnt_find_table_pos(sfont, "vmtx") > 0) { - struct tt_vhea_table *vhea; - vhea = tt_read_vhea_table(sfont); - sfnt_locate_table(sfont, "vmtx"); - vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics); - RELEASE(vhea); - } else { - vmtx = NULL; - } - - sfnt_locate_table(sfont, "loca"); - location = NEW(maxp->numGlyphs + 1, ULONG); - if (head->indexToLocFormat == 0) { - for (i = 0; i <= maxp->numGlyphs; i++) - location[i] = 2*((ULONG) sfnt_get_ushort(sfont)); - } else if (head->indexToLocFormat == 1) { - for (i = 0; i <= maxp->numGlyphs; i++) - location[i] = sfnt_get_ulong(sfont); - } else { - TT_ERROR("Unknown IndexToLocFormat."); - } - - w_stat = NEW(g->emsize+2, USHORT); - memset(w_stat, 0, sizeof(USHORT)*(g->emsize+2)); - /* - * Read glyf table. - */ - offset = sfnt_locate_table(sfont, "glyf"); - for (i = 0; i < g->num_glyphs; i++) { - USHORT gid; /* old gid */ - ULONG loc, len; - SHORT number_of_contours; - - gid = g->gd[i].ogid; - if (gid >= maxp->numGlyphs) - TT_ERROR("Invalid glyph index (gid %u)", gid); - - loc = location[gid]; - len = location[gid+1] - loc; - g->gd[i].advw = hmtx[gid].advance; - g->gd[i].lsb = hmtx[gid].sideBearing; - if (vmtx) { - g->gd[i].advh = vmtx[gid].advance; - g->gd[i].tsb = vmtx[gid].sideBearing; + ) + TT_ERROR("File not opened."); + + if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC) + TT_ERROR("Invalid font type"); + + /* + * Read head, hhea, maxp, loca: + * + * unitsPerEm --> head + * numHMetrics --> hhea + * indexToLocFormat --> head + * numGlyphs --> maxp + */ + head = tt_read_head_table(sfont); + hhea = tt_read_hhea_table(sfont); + maxp = tt_read_maxp_table(sfont); + + if (hhea->metricDataFormat != 0) + TT_ERROR("Unknown metricDataFormat."); + + g->emsize = head->unitsPerEm; + + sfnt_locate_table(sfont, "hmtx"); + hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics); + + os2 = tt_read_os2__table(sfont); + g->default_advh = os2->sTypoAscender - os2->sTypoDescender; + g->default_tsb = g->default_advh - os2->sTypoAscender; + + if (sfnt_find_table_pos(sfont, "vmtx") > 0) { + struct tt_vhea_table *vhea; + vhea = tt_read_vhea_table(sfont); + sfnt_locate_table(sfont, "vmtx"); + vmtx = + tt_read_longMetrics(sfont, maxp->numGlyphs, + vhea->numOfLongVerMetrics); + RELEASE(vhea); } else { - g->gd[i].advh = g->default_advh; - g->gd[i].tsb = g->default_tsb; + vmtx = NULL; } - g->gd[i].length = len; - g->gd[i].data = NULL; - if (g->gd[i].advw <= g->emsize) { - w_stat[g->gd[i].advw] += 1; + sfnt_locate_table(sfont, "loca"); + location = NEW(maxp->numGlyphs + 1, ULONG); + if (head->indexToLocFormat == 0) { + for (i = 0; i <= maxp->numGlyphs; i++) + location[i] = 2 * ((ULONG) sfnt_get_ushort(sfont)); + } else if (head->indexToLocFormat == 1) { + for (i = 0; i <= maxp->numGlyphs; i++) + location[i] = sfnt_get_ulong(sfont); } else { - w_stat[g->emsize+1] += 1; /* larger than em */ + TT_ERROR("Unknown IndexToLocFormat."); } - if (len == 0) { /* Does not contains any data. */ - continue; - } else if (len < 10) { - TT_ERROR("Invalid TrueType glyph data (gid %u).", gid); + w_stat = NEW(g->emsize + 2, USHORT); + memset(w_stat, 0, sizeof(USHORT) * (g->emsize + 2)); + /* + * Read glyf table. + */ + offset = sfnt_locate_table(sfont, "glyf"); + for (i = 0; i < g->num_glyphs; i++) { + USHORT gid; /* old gid */ + ULONG loc, len; + SHORT number_of_contours; + + gid = g->gd[i].ogid; + if (gid >= maxp->numGlyphs) + TT_ERROR("Invalid glyph index (gid %u)", gid); + + loc = location[gid]; + len = location[gid + 1] - loc; + g->gd[i].advw = hmtx[gid].advance; + g->gd[i].lsb = hmtx[gid].sideBearing; + if (vmtx) { + g->gd[i].advh = vmtx[gid].advance; + g->gd[i].tsb = vmtx[gid].sideBearing; + } else { + g->gd[i].advh = g->default_advh; + g->gd[i].tsb = g->default_tsb; + } + g->gd[i].length = len; + g->gd[i].data = NULL; + + if (g->gd[i].advw <= g->emsize) { + w_stat[g->gd[i].advw] += 1; + } else { + w_stat[g->emsize + 1] += 1; /* larger than em */ + } + + if (len == 0) { /* Does not contains any data. */ + continue; + } else if (len < 10) { + TT_ERROR("Invalid TrueType glyph data (gid %u).", gid); + } + + sfnt_seek_set(sfont, offset + loc); + number_of_contours = sfnt_get_short(sfont); + + /* BoundingBox: FWord x 4 */ + g->gd[i].llx = sfnt_get_short(sfont); + g->gd[i].lly = sfnt_get_short(sfont); + g->gd[i].urx = sfnt_get_short(sfont); + g->gd[i].ury = sfnt_get_short(sfont); + /* _FIXME_ */ +#if 1 + if (!vmtx) /* vertOriginY == sTypeAscender */ + g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury; +#endif } + RELEASE(location); + RELEASE(hmtx); + RELEASE(maxp); + RELEASE(hhea); + RELEASE(head); + RELEASE(os2); - sfnt_seek_set(sfont, offset+loc); - number_of_contours = sfnt_get_short(sfont); + if (vmtx) + RELEASE(vmtx); - /* BoundingBox: FWord x 4 */ - g->gd[i].llx = sfnt_get_short(sfont); - g->gd[i].lly = sfnt_get_short(sfont); - g->gd[i].urx = sfnt_get_short(sfont); - g->gd[i].ury = sfnt_get_short(sfont); - /* _FIXME_ */ -#if 1 - if (!vmtx) /* vertOriginY == sTypeAscender */ - g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury; -#endif - } - RELEASE(location); - RELEASE(hmtx); - RELEASE(maxp); - RELEASE(hhea); - RELEASE(head); - RELEASE(os2); - - if (vmtx) - RELEASE(vmtx); - - { - int max_count = -1; - - g->dw = g->gd[0].advw; - for (i = 0; i < g->emsize + 1; i++) { - if (w_stat[i] > max_count) { - max_count = w_stat[i]; - g->dw = i; - } + { + int max_count = -1; + + g->dw = g->gd[0].advw; + for (i = 0; i < g->emsize + 1; i++) { + if (w_stat[i] > max_count) { + max_count = w_stat[i]; + g->dw = i; + } + } } - } - RELEASE(w_stat); + RELEASE(w_stat); - return 0; + return 0; } diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.h b/Build/source/texk/web2c/luatexdir/font/tt_glyf.h index cf33af6733f..0ca8465c33d 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.h +++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.h @@ -1,60 +1,59 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/tt_glyf.h,v 1.1 2004/09/11 14:50:29 hirata Exp $ +/* tt_glyf.h - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team + Copyright 2006-2008 Taco Hoekwater - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: tt_glyf.h 1223 2008-05-02 13:39:55Z oneiros $ */ #ifndef _TT_GLYF_H_ -#define _TT_GLYF_H_ - -struct tt_glyph_desc -{ - USHORT gid; - USHORT ogid; /* GID in original font */ - USHORT advw, advh; - SHORT lsb, tsb; - SHORT llx, lly, urx, ury; - ULONG length; - BYTE *data; +# define _TT_GLYF_H_ + +struct tt_glyph_desc { + USHORT gid; + USHORT ogid; /* GID in original font */ + USHORT advw, advh; + SHORT lsb, tsb; + SHORT llx, lly, urx, ury; + ULONG length; + BYTE *data; }; -struct tt_glyphs -{ - USHORT num_glyphs; - USHORT max_glyphs; - USHORT last_gid; - USHORT emsize; - USHORT dw; /* optimal value for DW */ - USHORT default_advh; /* default value */ - SHORT default_tsb; /* default value */ - struct tt_glyph_desc *gd; - unsigned char *used_slot; +struct tt_glyphs { + USHORT num_glyphs; + USHORT max_glyphs; + USHORT last_gid; + USHORT emsize; + USHORT dw; /* optimal value for DW */ + USHORT default_advh; /* default value */ + SHORT default_tsb; /* default value */ + struct tt_glyph_desc *gd; + unsigned char *used_slot; }; -extern struct tt_glyphs *tt_build_init (void); -extern void tt_build_finish (struct tt_glyphs *g); +extern struct tt_glyphs *tt_build_init(void); +extern void tt_build_finish(struct tt_glyphs *g); -extern USHORT tt_add_glyph (struct tt_glyphs *g, USHORT gid, USHORT new_gid); -extern USHORT tt_get_index (struct tt_glyphs *g, USHORT gid); -extern USHORT tt_find_glyph (struct tt_glyphs *g, USHORT gid); +extern USHORT tt_add_glyph(struct tt_glyphs *g, USHORT gid, USHORT new_gid); +extern USHORT tt_get_index(struct tt_glyphs *g, USHORT gid); +extern USHORT tt_find_glyph(struct tt_glyphs *g, USHORT gid); -extern int tt_build_tables (sfnt *sfont, struct tt_glyphs *g); -extern int tt_get_metrics (sfnt *sfont, struct tt_glyphs *g); +extern int tt_build_tables(sfnt * sfont, struct tt_glyphs *g); +extern int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g); -#endif /* _TT_GLYF_H_ */ +#endif /* _TT_GLYF_H_ */ diff --git a/Build/source/texk/web2c/luatexdir/font/tt_table.c b/Build/source/texk/web2c/luatexdir/font/tt_table.c index 4f82552d9df..3df19723c2b 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_table.c +++ b/Build/source/texk/web2c/luatexdir/font/tt_table.c @@ -1,39 +1,41 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/tt_table.c,v 1.7 2004/09/11 14:50:29 hirata Exp $ +/* tt_table.c - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team + Copyright 2006-2008 Taco Hoekwater - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include #ifndef pdfTeX -#include "system.h" -#include "error.h" -#include "mem.h" -#include "mfileio.h" +# include "system.h" +# include "error.h" +# include "mem.h" +# include "mfileio.h" #else -extern void pdftex_fail (const char *fmt, ...); /* utils.c */ +# include "ptexlib.h" #endif #include "sfnt.h" #include "tt_table.h" +static const char _svn_version[] = + "$Id: tt_table.c 1588 2008-11-28 13:18:54Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tt_table.c $"; + /* tables contains information refered by other tables maxp->numGlyphs, etc --> loca, etc @@ -42,269 +44,264 @@ extern void pdftex_fail (const char *fmt, ...); /* utils.c */ head->glyphDataFormat --> glyf */ -char *tt_pack_head_table (struct tt_head_table *table) +char *tt_pack_head_table(struct tt_head_table *table) { - int i; - char *p, *data; - - if (table == NULL) - TT_ERROR("passed NULL pointer\n"); - - p = data = NEW(TT_HEAD_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_ulong(p, table->fontRevision); - p += sfnt_put_ulong(p, table->checkSumAdjustment); - p += sfnt_put_ulong(p, table->magicNumber); - p += sfnt_put_ushort(p, table->flags); - p += sfnt_put_ushort(p, table->unitsPerEm); - for (i=0; i<8; i++) { - *(p++) = (table->created)[i]; - } - for (i=0; i<8; i++) { - *(p++) = (table->modified)[i]; - } - p += sfnt_put_short(p, table->xMin); - p += sfnt_put_short(p, table->yMin); - p += sfnt_put_short(p, table->xMax); - p += sfnt_put_short(p, table->yMax); - p += sfnt_put_ushort(p, table->macStyle); - p += sfnt_put_ushort(p, table->lowestRecPPEM); - p += sfnt_put_short(p, table->fontDirectionHint); - p += sfnt_put_short(p, table->indexToLocFormat); - p += sfnt_put_short(p, table->glyphDataFormat); - - return data; + int i; + char *p, *data; + + if (table == NULL) + TT_ERROR("passed NULL pointer\n"); + + p = data = NEW(TT_HEAD_TABLE_SIZE, char); + p += sfnt_put_ulong(p, table->version); + p += sfnt_put_ulong(p, table->fontRevision); + p += sfnt_put_ulong(p, table->checkSumAdjustment); + p += sfnt_put_ulong(p, table->magicNumber); + p += sfnt_put_ushort(p, table->flags); + p += sfnt_put_ushort(p, table->unitsPerEm); + for (i = 0; i < 8; i++) { + *(p++) = (table->created)[i]; + } + for (i = 0; i < 8; i++) { + *(p++) = (table->modified)[i]; + } + p += sfnt_put_short(p, table->xMin); + p += sfnt_put_short(p, table->yMin); + p += sfnt_put_short(p, table->xMax); + p += sfnt_put_short(p, table->yMax); + p += sfnt_put_ushort(p, table->macStyle); + p += sfnt_put_ushort(p, table->lowestRecPPEM); + p += sfnt_put_short(p, table->fontDirectionHint); + p += sfnt_put_short(p, table->indexToLocFormat); + p += sfnt_put_short(p, table->glyphDataFormat); + + return data; } -struct tt_head_table *tt_read_head_table (sfnt *sfont) +struct tt_head_table *tt_read_head_table(sfnt * sfont) { - int i; - struct tt_head_table *table = NULL; - - table = NEW(1, struct tt_head_table); - - sfnt_locate_table(sfont, "head"); - - table->version = sfnt_get_ulong(sfont); - table->fontRevision = sfnt_get_ulong(sfont); - table->checkSumAdjustment = sfnt_get_ulong(sfont); - table->magicNumber = sfnt_get_ulong(sfont); - table->flags = sfnt_get_ushort(sfont); - table->unitsPerEm = sfnt_get_ushort(sfont); - for (i=0; i<8; i++) { - (table->created)[i] = sfnt_get_byte (sfont); - } - for (i=0; i<8; i++) { - (table->modified)[i] = sfnt_get_byte (sfont); - } - table->xMin = sfnt_get_short(sfont); - table->yMin = sfnt_get_short(sfont); - table->xMax = sfnt_get_short(sfont); - table->yMax = sfnt_get_short(sfont); - table->macStyle = sfnt_get_short(sfont); - table->lowestRecPPEM = sfnt_get_short(sfont); - table->fontDirectionHint = sfnt_get_short(sfont); - table->indexToLocFormat = sfnt_get_short(sfont); - table->glyphDataFormat = sfnt_get_short(sfont); - - return table; + int i; + struct tt_head_table *table = NULL; + + table = NEW(1, struct tt_head_table); + + sfnt_locate_table(sfont, "head"); + + table->version = sfnt_get_ulong(sfont); + table->fontRevision = sfnt_get_ulong(sfont); + table->checkSumAdjustment = sfnt_get_ulong(sfont); + table->magicNumber = sfnt_get_ulong(sfont); + table->flags = sfnt_get_ushort(sfont); + table->unitsPerEm = sfnt_get_ushort(sfont); + for (i = 0; i < 8; i++) { + (table->created)[i] = sfnt_get_byte(sfont); + } + for (i = 0; i < 8; i++) { + (table->modified)[i] = sfnt_get_byte(sfont); + } + table->xMin = sfnt_get_short(sfont); + table->yMin = sfnt_get_short(sfont); + table->xMax = sfnt_get_short(sfont); + table->yMax = sfnt_get_short(sfont); + table->macStyle = sfnt_get_short(sfont); + table->lowestRecPPEM = sfnt_get_short(sfont); + table->fontDirectionHint = sfnt_get_short(sfont); + table->indexToLocFormat = sfnt_get_short(sfont); + table->glyphDataFormat = sfnt_get_short(sfont); + + return table; } -char *tt_pack_maxp_table (struct tt_maxp_table *table) +char *tt_pack_maxp_table(struct tt_maxp_table *table) { - char *p, *data; - - p = data = NEW(TT_MAXP_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_ushort(p, table->numGlyphs); - p += sfnt_put_ushort(p, table->maxPoints); - p += sfnt_put_ushort(p, table->maxContours); - p += sfnt_put_ushort(p, table->maxComponentPoints); - p += sfnt_put_ushort(p, table->maxComponentContours); - p += sfnt_put_ushort(p, table->maxZones); - p += sfnt_put_ushort(p, table->maxTwilightPoints); - p += sfnt_put_ushort(p, table->maxStorage); - p += sfnt_put_ushort(p, table->maxFunctionDefs); - p += sfnt_put_ushort(p, table->maxInstructionDefs); - p += sfnt_put_ushort(p, table->maxStackElements); - p += sfnt_put_ushort(p, table->maxSizeOfInstructions); - p += sfnt_put_ushort(p, table->maxComponentElements); - p += sfnt_put_ushort(p, table->maxComponentDepth); - - return data; + char *p, *data; + + p = data = NEW(TT_MAXP_TABLE_SIZE, char); + p += sfnt_put_ulong(p, table->version); + p += sfnt_put_ushort(p, table->numGlyphs); + p += sfnt_put_ushort(p, table->maxPoints); + p += sfnt_put_ushort(p, table->maxContours); + p += sfnt_put_ushort(p, table->maxComponentPoints); + p += sfnt_put_ushort(p, table->maxComponentContours); + p += sfnt_put_ushort(p, table->maxZones); + p += sfnt_put_ushort(p, table->maxTwilightPoints); + p += sfnt_put_ushort(p, table->maxStorage); + p += sfnt_put_ushort(p, table->maxFunctionDefs); + p += sfnt_put_ushort(p, table->maxInstructionDefs); + p += sfnt_put_ushort(p, table->maxStackElements); + p += sfnt_put_ushort(p, table->maxSizeOfInstructions); + p += sfnt_put_ushort(p, table->maxComponentElements); + p += sfnt_put_ushort(p, table->maxComponentDepth); + + return data; } -struct tt_maxp_table *tt_read_maxp_table (sfnt *sfont) +struct tt_maxp_table *tt_read_maxp_table(sfnt * sfont) { - struct tt_maxp_table *table = NULL; - - table = NEW(1, struct tt_maxp_table); - - sfnt_locate_table(sfont, "maxp"); - table->version = sfnt_get_ulong(sfont); - table->numGlyphs = sfnt_get_ushort(sfont); - table->maxPoints = sfnt_get_ushort(sfont); - table->maxContours = sfnt_get_ushort(sfont); - table->maxComponentPoints = sfnt_get_ushort(sfont); - table->maxComponentContours = sfnt_get_ushort(sfont); - table->maxZones = sfnt_get_ushort(sfont); - table->maxTwilightPoints = sfnt_get_ushort(sfont); - table->maxStorage = sfnt_get_ushort(sfont); - table->maxFunctionDefs = sfnt_get_ushort(sfont); - table->maxInstructionDefs = sfnt_get_ushort(sfont); - table->maxStackElements = sfnt_get_ushort(sfont); - table->maxSizeOfInstructions = sfnt_get_ushort(sfont); - table->maxComponentElements = sfnt_get_ushort(sfont); - table->maxComponentDepth = sfnt_get_ushort(sfont); - - return table; + struct tt_maxp_table *table = NULL; + + table = NEW(1, struct tt_maxp_table); + + sfnt_locate_table(sfont, "maxp"); + table->version = sfnt_get_ulong(sfont); + table->numGlyphs = sfnt_get_ushort(sfont); + table->maxPoints = sfnt_get_ushort(sfont); + table->maxContours = sfnt_get_ushort(sfont); + table->maxComponentPoints = sfnt_get_ushort(sfont); + table->maxComponentContours = sfnt_get_ushort(sfont); + table->maxZones = sfnt_get_ushort(sfont); + table->maxTwilightPoints = sfnt_get_ushort(sfont); + table->maxStorage = sfnt_get_ushort(sfont); + table->maxFunctionDefs = sfnt_get_ushort(sfont); + table->maxInstructionDefs = sfnt_get_ushort(sfont); + table->maxStackElements = sfnt_get_ushort(sfont); + table->maxSizeOfInstructions = sfnt_get_ushort(sfont); + table->maxComponentElements = sfnt_get_ushort(sfont); + table->maxComponentDepth = sfnt_get_ushort(sfont); + + return table; } -char *tt_pack_hhea_table (struct tt_hhea_table *table) +char *tt_pack_hhea_table(struct tt_hhea_table *table) { - int i; - char *p, *data; - - p = data = NEW(TT_HHEA_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_short(p, table->Ascender); - p += sfnt_put_short(p, table->Descender); - p += sfnt_put_short(p, table->LineGap); - p += sfnt_put_ushort(p, table->advanceWidthMax); - p += sfnt_put_short(p, table->minLeftSideBearing); - p += sfnt_put_short(p, table->minRightSideBearing); - p += sfnt_put_short(p, table->xMaxExtent); - p += sfnt_put_short(p, table->caretSlopeRise); - p += sfnt_put_short(p, table->caretSlopeRun); - for (i = 0; i < 5; i++) { - p += sfnt_put_short(p, table->reserved[i]); - } - p += sfnt_put_short(p, table->metricDataFormat); - p += sfnt_put_ushort(p, table->numberOfHMetrics); - - return data; + int i; + char *p, *data; + + p = data = NEW(TT_HHEA_TABLE_SIZE, char); + p += sfnt_put_ulong(p, table->version); + p += sfnt_put_short(p, table->Ascender); + p += sfnt_put_short(p, table->Descender); + p += sfnt_put_short(p, table->LineGap); + p += sfnt_put_ushort(p, table->advanceWidthMax); + p += sfnt_put_short(p, table->minLeftSideBearing); + p += sfnt_put_short(p, table->minRightSideBearing); + p += sfnt_put_short(p, table->xMaxExtent); + p += sfnt_put_short(p, table->caretSlopeRise); + p += sfnt_put_short(p, table->caretSlopeRun); + for (i = 0; i < 5; i++) { + p += sfnt_put_short(p, table->reserved[i]); + } + p += sfnt_put_short(p, table->metricDataFormat); + p += sfnt_put_ushort(p, table->numberOfHMetrics); + + return data; } -struct tt_hhea_table * -tt_read_hhea_table (sfnt *sfont) +struct tt_hhea_table *tt_read_hhea_table(sfnt * sfont) { - int i; - struct tt_hhea_table *table = NULL; - - table = NEW(1, struct tt_hhea_table); - - sfnt_locate_table(sfont, "hhea"); - table->version = sfnt_get_ulong(sfont); - table->Ascender = sfnt_get_short (sfont); - table->Descender = sfnt_get_short(sfont); - table->LineGap = sfnt_get_short(sfont); - table->advanceWidthMax = sfnt_get_ushort(sfont); - table->minLeftSideBearing = sfnt_get_short(sfont); - table->minRightSideBearing = sfnt_get_short(sfont); - table->xMaxExtent = sfnt_get_short(sfont); - table->caretSlopeRise = sfnt_get_short(sfont); - table->caretSlopeRun = sfnt_get_short(sfont); - for(i = 0; i < 5; i++) { - table->reserved[i] = sfnt_get_short(sfont); - } - table->metricDataFormat = sfnt_get_short(sfont); - if (table->metricDataFormat != 0) - TT_ERROR("unknown metricDaraFormat"); - table->numberOfHMetrics = sfnt_get_ushort(sfont); - - return table; + int i; + struct tt_hhea_table *table = NULL; + + table = NEW(1, struct tt_hhea_table); + + sfnt_locate_table(sfont, "hhea"); + table->version = sfnt_get_ulong(sfont); + table->Ascender = sfnt_get_short(sfont); + table->Descender = sfnt_get_short(sfont); + table->LineGap = sfnt_get_short(sfont); + table->advanceWidthMax = sfnt_get_ushort(sfont); + table->minLeftSideBearing = sfnt_get_short(sfont); + table->minRightSideBearing = sfnt_get_short(sfont); + table->xMaxExtent = sfnt_get_short(sfont); + table->caretSlopeRise = sfnt_get_short(sfont); + table->caretSlopeRun = sfnt_get_short(sfont); + for (i = 0; i < 5; i++) { + table->reserved[i] = sfnt_get_short(sfont); + } + table->metricDataFormat = sfnt_get_short(sfont); + if (table->metricDataFormat != 0) + TT_ERROR("unknown metricDaraFormat"); + table->numberOfHMetrics = sfnt_get_ushort(sfont); + + return table; } /* vhea */ -char * -tt_pack_vhea_table (struct tt_vhea_table *table) +char *tt_pack_vhea_table(struct tt_vhea_table *table) { - int i; - char *p, *data; - - p = data = NEW(TT_VHEA_TABLE_SIZE, char); - p += sfnt_put_ulong(p, table->version); - p += sfnt_put_short(p, table->vertTypoAscender); - p += sfnt_put_short(p, table->vertTypoDescender); - p += sfnt_put_short(p, table->vertTypoLineGap); - p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */ - p += sfnt_put_short(p, table->minTopSideBearing); - p += sfnt_put_short(p, table->minBottomSideBearing); - p += sfnt_put_short(p, table->yMaxExtent); - p += sfnt_put_short(p, table->caretSlopeRise); - p += sfnt_put_short(p, table->caretSlopeRun); - p += sfnt_put_short(p, table->caretOffset); - for(i = 0; i < 5; i++) { - p += sfnt_put_short(p, table->reserved[i]); - } - p += sfnt_put_ushort(p, table->numOfLongVerMetrics); - - return data; -} + int i; + char *p, *data; + + p = data = NEW(TT_VHEA_TABLE_SIZE, char); + p += sfnt_put_ulong(p, table->version); + p += sfnt_put_short(p, table->vertTypoAscender); + p += sfnt_put_short(p, table->vertTypoDescender); + p += sfnt_put_short(p, table->vertTypoLineGap); + p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */ + p += sfnt_put_short(p, table->minTopSideBearing); + p += sfnt_put_short(p, table->minBottomSideBearing); + p += sfnt_put_short(p, table->yMaxExtent); + p += sfnt_put_short(p, table->caretSlopeRise); + p += sfnt_put_short(p, table->caretSlopeRun); + p += sfnt_put_short(p, table->caretOffset); + for (i = 0; i < 5; i++) { + p += sfnt_put_short(p, table->reserved[i]); + } + p += sfnt_put_ushort(p, table->numOfLongVerMetrics); -struct tt_vhea_table *tt_read_vhea_table (sfnt *sfont) -{ - int i; - struct tt_vhea_table *table = NULL; - - table = NEW(1, struct tt_vhea_table); - - sfnt_locate_table(sfont, "vhea"); - table->version = sfnt_get_ulong(sfont); - table->vertTypoAscender = sfnt_get_short (sfont); - table->vertTypoDescender = sfnt_get_short(sfont); - table->vertTypoLineGap = sfnt_get_short(sfont); - table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */ - table->minTopSideBearing = sfnt_get_short(sfont); - table->minBottomSideBearing = sfnt_get_short(sfont); - table->yMaxExtent = sfnt_get_short(sfont); - table->caretSlopeRise = sfnt_get_short(sfont); - table->caretSlopeRun = sfnt_get_short(sfont); - table->caretOffset = sfnt_get_short(sfont); - for(i=0;i<5;i++) { - (table->reserved)[i] = sfnt_get_short(sfont); - } - table->numOfLongVerMetrics = sfnt_get_ushort(sfont); - - return table; + return data; } - -struct tt_VORG_table * -tt_read_VORG_table (sfnt *sfont) +struct tt_vhea_table *tt_read_vhea_table(sfnt * sfont) { - struct tt_VORG_table *vorg; - ULONG offset; - USHORT i; - - offset = sfnt_find_table_pos(sfont, "VORG"); + int i; + struct tt_vhea_table *table = NULL; + + table = NEW(1, struct tt_vhea_table); + + sfnt_locate_table(sfont, "vhea"); + table->version = sfnt_get_ulong(sfont); + table->vertTypoAscender = sfnt_get_short(sfont); + table->vertTypoDescender = sfnt_get_short(sfont); + table->vertTypoLineGap = sfnt_get_short(sfont); + table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */ + table->minTopSideBearing = sfnt_get_short(sfont); + table->minBottomSideBearing = sfnt_get_short(sfont); + table->yMaxExtent = sfnt_get_short(sfont); + table->caretSlopeRise = sfnt_get_short(sfont); + table->caretSlopeRun = sfnt_get_short(sfont); + table->caretOffset = sfnt_get_short(sfont); + for (i = 0; i < 5; i++) { + (table->reserved)[i] = sfnt_get_short(sfont); + } + table->numOfLongVerMetrics = sfnt_get_ushort(sfont); - if (offset > 0) { - vorg = NEW(1, struct tt_VORG_table); + return table; +} - sfnt_locate_table(sfont, "VORG"); - if (sfnt_get_ushort(sfont) != 1 || - sfnt_get_ushort(sfont) != 0) - TT_ERROR("Unsupported VORG version."); - vorg->defaultVertOriginY = sfnt_get_short(sfont); - vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont); - vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics, - struct tt_vertOriginYMetrics); - /* - * The vertOriginYMetrics array must be sorted in increasing - * glyphIndex order. - */ - for (i = 0; - i < vorg->numVertOriginYMetrics; i++) { - vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont); - vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont); +struct tt_VORG_table *tt_read_VORG_table(sfnt * sfont) +{ + struct tt_VORG_table *vorg; + ULONG offset; + USHORT i; + + offset = sfnt_find_table_pos(sfont, "VORG"); + + if (offset > 0) { + vorg = NEW(1, struct tt_VORG_table); + + sfnt_locate_table(sfont, "VORG"); + if (sfnt_get_ushort(sfont) != 1 || sfnt_get_ushort(sfont) != 0) + TT_ERROR("Unsupported VORG version."); + + vorg->defaultVertOriginY = sfnt_get_short(sfont); + vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont); + vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics, + struct tt_vertOriginYMetrics); + /* + * The vertOriginYMetrics array must be sorted in increasing + * glyphIndex order. + */ + for (i = 0; i < vorg->numVertOriginYMetrics; i++) { + vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont); + vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont); + } + } else { + vorg = NULL; } - } else { - vorg = NULL; - } - return vorg; + return vorg; } /* @@ -313,171 +310,167 @@ tt_read_VORG_table (sfnt *sfont) * Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea. */ -struct tt_longMetrics * -tt_read_longMetrics (sfnt *sfont, USHORT numGlyphs, USHORT numLongMetrics) +struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs, + USHORT numLongMetrics) { - struct tt_longMetrics *m; - USHORT gid, last_adv = 0; - - m = NEW(numGlyphs, struct tt_longMetrics); - for (gid = 0; gid < numGlyphs; gid++) { - if (gid < numLongMetrics) - last_adv = sfnt_get_ushort(sfont); - m[gid].sideBearing = sfnt_get_short(sfont); - m[gid].advance = last_adv; - } - - return m; + struct tt_longMetrics *m; + USHORT gid, last_adv = 0; + + m = NEW(numGlyphs, struct tt_longMetrics); + for (gid = 0; gid < numGlyphs; gid++) { + if (gid < numLongMetrics) + last_adv = sfnt_get_ushort(sfont); + m[gid].sideBearing = sfnt_get_short(sfont); + m[gid].advance = last_adv; + } + + return m; } /* OS/2 table */ /* this table may not exist */ -struct tt_os2__table * -tt_read_os2__table (sfnt *sfont) +struct tt_os2__table *tt_read_os2__table(sfnt * sfont) { - struct tt_os2__table *table = NULL; - int i; + struct tt_os2__table *table = NULL; + int i; + + if (sfnt_find_table_pos(sfont, "OS/2") == 0) + return NULL; + + sfnt_locate_table(sfont, "OS/2"); + + table = NEW(1, struct tt_os2__table); + + table->version = sfnt_get_ushort(sfont); + table->xAvgCharWidth = sfnt_get_short(sfont); + table->usWeightClass = sfnt_get_ushort(sfont); + table->usWidthClass = sfnt_get_ushort(sfont); + table->fsType = sfnt_get_short(sfont); + table->ySubscriptXSize = sfnt_get_short(sfont); + table->ySubscriptYSize = sfnt_get_short(sfont); + table->ySubscriptXOffset = sfnt_get_short(sfont); + table->ySubscriptYOffset = sfnt_get_short(sfont); + table->ySuperscriptXSize = sfnt_get_short(sfont); + table->ySuperscriptYSize = sfnt_get_short(sfont); + table->ySuperscriptXOffset = sfnt_get_short(sfont); + table->ySuperscriptYOffset = sfnt_get_short(sfont); + table->yStrikeoutSize = sfnt_get_short(sfont); + table->yStrikeoutPosition = sfnt_get_short(sfont); + table->sFamilyClass = sfnt_get_short(sfont); + for (i = 0; i < 10; i++) { + table->panose[i] = sfnt_get_byte(sfont); + } + table->ulUnicodeRange1 = sfnt_get_ulong(sfont); + table->ulUnicodeRange2 = sfnt_get_ulong(sfont); + table->ulUnicodeRange3 = sfnt_get_ulong(sfont); + table->ulUnicodeRange4 = sfnt_get_ulong(sfont); + for (i = 0; i < 4; i++) { + table->achVendID[i] = sfnt_get_char(sfont); + } + table->fsSelection = sfnt_get_ushort(sfont); + table->usFirstCharIndex = sfnt_get_ushort(sfont); + table->usLastCharIndex = sfnt_get_ushort(sfont); + table->sTypoAscender = sfnt_get_short(sfont); + table->sTypoDescender = sfnt_get_short(sfont); + table->sTypoLineGap = sfnt_get_short(sfont); + table->usWinAscent = sfnt_get_ushort(sfont); + table->usWinDescent = sfnt_get_ushort(sfont); + table->ulCodePageRange1 = sfnt_get_ulong(sfont); + table->ulCodePageRange2 = sfnt_get_ulong(sfont); + if (table->version == 0x0002) { + table->sxHeight = sfnt_get_short(sfont); + table->sCapHeight = sfnt_get_short(sfont); + table->usDefaultChar = sfnt_get_ushort(sfont); + table->usBreakChar = sfnt_get_ushort(sfont); + table->usMaxContext = sfnt_get_ushort(sfont); + } - if (sfnt_find_table_pos(sfont, "OS/2") == 0) - return NULL; - - sfnt_locate_table(sfont, "OS/2"); - - table = NEW(1, struct tt_os2__table); - - table->version = sfnt_get_ushort(sfont); - table->xAvgCharWidth = sfnt_get_short(sfont); - table->usWeightClass = sfnt_get_ushort(sfont); - table->usWidthClass = sfnt_get_ushort(sfont); - table->fsType = sfnt_get_short(sfont); - table->ySubscriptXSize = sfnt_get_short(sfont); - table->ySubscriptYSize = sfnt_get_short(sfont); - table->ySubscriptXOffset = sfnt_get_short(sfont); - table->ySubscriptYOffset = sfnt_get_short(sfont); - table->ySuperscriptXSize = sfnt_get_short(sfont); - table->ySuperscriptYSize = sfnt_get_short(sfont); - table->ySuperscriptXOffset = sfnt_get_short(sfont); - table->ySuperscriptYOffset = sfnt_get_short(sfont); - table->yStrikeoutSize = sfnt_get_short(sfont); - table->yStrikeoutPosition = sfnt_get_short(sfont); - table->sFamilyClass = sfnt_get_short(sfont); - for (i = 0; i < 10; i++) { - table->panose[i] = sfnt_get_byte(sfont); - } - table->ulUnicodeRange1 = sfnt_get_ulong(sfont); - table->ulUnicodeRange2 = sfnt_get_ulong(sfont); - table->ulUnicodeRange3 = sfnt_get_ulong(sfont); - table->ulUnicodeRange4 = sfnt_get_ulong(sfont); - for (i = 0; i < 4; i++) { - table->achVendID[i] = sfnt_get_char(sfont); - } - table->fsSelection = sfnt_get_ushort(sfont); - table->usFirstCharIndex = sfnt_get_ushort(sfont); - table->usLastCharIndex = sfnt_get_ushort(sfont); - table->sTypoAscender = sfnt_get_short(sfont); - table->sTypoDescender = sfnt_get_short(sfont); - table->sTypoLineGap = sfnt_get_short(sfont); - table->usWinAscent = sfnt_get_ushort(sfont); - table->usWinDescent = sfnt_get_ushort(sfont); - table->ulCodePageRange1 = sfnt_get_ulong(sfont); - table->ulCodePageRange2 = sfnt_get_ulong(sfont); - if (table->version == 0x0002) { - table->sxHeight = sfnt_get_short(sfont); - table->sCapHeight = sfnt_get_short(sfont); - table->usDefaultChar = sfnt_get_ushort(sfont); - table->usBreakChar = sfnt_get_ushort(sfont); - table->usMaxContext = sfnt_get_ushort(sfont); - } - - return table; + return table; } USHORT -tt_get_name (sfnt *sfont, char *dest, USHORT destlen, - USHORT plat_id, USHORT enco_id, - USHORT lang_id, USHORT name_id) +tt_get_name(sfnt * sfont, char *dest, USHORT destlen, + USHORT plat_id, USHORT enco_id, USHORT lang_id, USHORT name_id) { - USHORT length = 0; - USHORT num_names, string_offset; - ULONG name_offset; - int i; - - name_offset = sfnt_locate_table (sfont, "name"); - - if (sfnt_get_ushort(sfont)) - TT_ERROR ("Expecting zero"); - - num_names = sfnt_get_ushort(sfont); - string_offset = sfnt_get_ushort(sfont); - for (i=0;i destlen - 1) { - fprintf(stderr, "\n** Notice: Name string too long. Truncating **\n"); - length = destlen - 1; - } - sfnt_seek_set (sfont, name_offset+string_offset+offset); - sfnt_read((unsigned char*)dest, length, sfont); - dest[length] = '\0'; - break; + USHORT length = 0; + USHORT num_names, string_offset; + ULONG name_offset; + int i; + + name_offset = sfnt_locate_table(sfont, "name"); + + if (sfnt_get_ushort(sfont)) + TT_ERROR("Expecting zero"); + + num_names = sfnt_get_ushort(sfont); + string_offset = sfnt_get_ushort(sfont); + for (i = 0; i < num_names; i++) { + USHORT p_id, e_id, n_id, l_id; + USHORT offset; + + p_id = sfnt_get_ushort(sfont); + e_id = sfnt_get_ushort(sfont); + l_id = sfnt_get_ushort(sfont); + n_id = sfnt_get_ushort(sfont); + length = sfnt_get_ushort(sfont); + offset = sfnt_get_ushort(sfont); + /* language ID value 0xffffu for `accept any language ID' */ + if ((p_id == plat_id) && (e_id == enco_id) && + (lang_id == 0xffffu || l_id == lang_id) && (n_id == name_id)) { + if (length > destlen - 1) { + fprintf(stderr, + "\n** Notice: Name string too long. Truncating **\n"); + length = destlen - 1; + } + sfnt_seek_set(sfont, name_offset + string_offset + offset); + sfnt_read((unsigned char *) dest, length, sfont); + dest[length] = '\0'; + break; + } + } + if (i == num_names) { + length = 0; } - } - if (i == num_names) { - length = 0; - } - return length; + return length; } -USHORT -tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen) +USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen) { - USHORT namelen = 0; + USHORT namelen = 0; #ifdef XETEX - const char* name = FT_Get_Postscript_Name(sfont->ft_face); + const char *name = FT_Get_Postscript_Name(sfont->ft_face); namelen = strlen(name); if (namelen > destlen - 1) { - strncpy(dest, name, destlen - 1); - dest[destlen] = 0; - } - else - strcpy(dest, name); + strncpy(dest, name, destlen - 1); + dest[destlen] = 0; + } else + strcpy(dest, name); #else - /* First try Mac-Roman PS name and then Win-Unicode PS name */ - if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 || - (namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 || - (namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0) - return namelen; + /* First try Mac-Roman PS name and then Win-Unicode PS name */ + if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 || + (namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 || + (namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0) + return namelen; - fprintf(stderr, "\n** Warning: No valid PostScript name available **\n"); - /* - Wrokaround for some bad TTfonts: - Language ID value 0xffffu for `accept any language ID' - */ - if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) { + fprintf(stderr, "\n** Warning: No valid PostScript name available **\n"); /* - Finally falling back to Mac Roman name field. - Warning: Some bad Japanese TTfonts using SJIS encoded string in the - Mac Roman name field. - */ - namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1); - } - + Wrokaround for some bad TTfonts: + Language ID value 0xffffu for `accept any language ID' + */ + if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) { + /* + Finally falling back to Mac Roman name field. + Warning: Some bad Japanese TTfonts using SJIS encoded string in the + Mac Roman name field. + */ + namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1); + } #endif - return namelen; + return namelen; } diff --git a/Build/source/texk/web2c/luatexdir/font/tt_table.h b/Build/source/texk/web2c/luatexdir/font/tt_table.h index ffb2c5b8f45..5dcd17d5b66 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_table.h +++ b/Build/source/texk/web2c/luatexdir/font/tt_table.h @@ -1,193 +1,189 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/tt_table.h,v 1.6 2004/09/11 14:50:29 hirata Exp $ +/* tt_table.h - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team + Copyright 2006-2008 Taco Hoekwater - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: tt_table.h 1223 2008-05-02 13:39:55Z oneiros $ */ #ifndef _TT_TABLE_H_ -#define _TT_TABLE_H_ - -#include "sfnt.h" - -#define TT_HEAD_TABLE_SIZE 54UL -#define TT_MAXP_TABLE_SIZE 32UL -#define TT_HHEA_TABLE_SIZE 36UL -#define TT_VHEA_TABLE_SIZE 36UL - -struct tt_head_table -{ - Fixed version; - Fixed fontRevision; - ULONG checkSumAdjustment; - ULONG magicNumber; - USHORT flags; - USHORT unitsPerEm; - BYTE created[8]; - BYTE modified[8]; - FWord xMin, yMin, xMax, yMax; - USHORT macStyle; - USHORT lowestRecPPEM; - SHORT fontDirectionHint; - SHORT indexToLocFormat; - SHORT glyphDataFormat; +# define _TT_TABLE_H_ + +# include "sfnt.h" + +# define TT_HEAD_TABLE_SIZE 54UL +# define TT_MAXP_TABLE_SIZE 32UL +# define TT_HHEA_TABLE_SIZE 36UL +# define TT_VHEA_TABLE_SIZE 36UL + +struct tt_head_table { + Fixed version; + Fixed fontRevision; + ULONG checkSumAdjustment; + ULONG magicNumber; + USHORT flags; + USHORT unitsPerEm; + BYTE created[8]; + BYTE modified[8]; + FWord xMin, yMin, xMax, yMax; + USHORT macStyle; + USHORT lowestRecPPEM; + SHORT fontDirectionHint; + SHORT indexToLocFormat; + SHORT glyphDataFormat; }; -struct tt_hhea_table -{ - Fixed version; - FWord Ascender; - FWord Descender; - FWord LineGap; - uFWord advanceWidthMax; - FWord minLeftSideBearing; - FWord minRightSideBearing; - FWord xMaxExtent; - SHORT caretSlopeRise; - SHORT caretSlopeRun; - SHORT reserved[5]; /* set to 0 */ - SHORT metricDataFormat; - USHORT numberOfHMetrics; +struct tt_hhea_table { + Fixed version; + FWord Ascender; + FWord Descender; + FWord LineGap; + uFWord advanceWidthMax; + FWord minLeftSideBearing; + FWord minRightSideBearing; + FWord xMaxExtent; + SHORT caretSlopeRise; + SHORT caretSlopeRun; + SHORT reserved[5]; /* set to 0 */ + SHORT metricDataFormat; + USHORT numberOfHMetrics; }; -struct tt_vhea_table -{ - Fixed version; - SHORT vertTypoAscender; /* v.1.1 name */ - SHORT vertTypoDescender; /* v.1.1 name */ - SHORT vertTypoLineGap; /* v.1.1 name */ - SHORT advanceHeightMax; - SHORT minTopSideBearing; - SHORT minBottomSideBearing; - SHORT yMaxExtent; - SHORT caretSlopeRise; - SHORT caretSlopeRun; - SHORT caretOffset; - SHORT reserved[5]; /* set to 0 */ - USHORT numOfLongVerMetrics; +struct tt_vhea_table { + Fixed version; + SHORT vertTypoAscender; /* v.1.1 name */ + SHORT vertTypoDescender; /* v.1.1 name */ + SHORT vertTypoLineGap; /* v.1.1 name */ + SHORT advanceHeightMax; + SHORT minTopSideBearing; + SHORT minBottomSideBearing; + SHORT yMaxExtent; + SHORT caretSlopeRise; + SHORT caretSlopeRun; + SHORT caretOffset; + SHORT reserved[5]; /* set to 0 */ + USHORT numOfLongVerMetrics; }; -struct tt_maxp_table -{ - Fixed version; - USHORT numGlyphs; - USHORT maxPoints; - USHORT maxContours; - USHORT maxComponentPoints; - USHORT maxComponentContours; - USHORT maxZones; - USHORT maxTwilightPoints; - USHORT maxStorage; - USHORT maxFunctionDefs; - USHORT maxInstructionDefs; - USHORT maxStackElements; - USHORT maxSizeOfInstructions; - USHORT maxComponentElements; - USHORT maxComponentDepth; +struct tt_maxp_table { + Fixed version; + USHORT numGlyphs; + USHORT maxPoints; + USHORT maxContours; + USHORT maxComponentPoints; + USHORT maxComponentContours; + USHORT maxZones; + USHORT maxTwilightPoints; + USHORT maxStorage; + USHORT maxFunctionDefs; + USHORT maxInstructionDefs; + USHORT maxStackElements; + USHORT maxSizeOfInstructions; + USHORT maxComponentElements; + USHORT maxComponentDepth; }; -struct tt_os2__table -{ - USHORT version; /* 0x0001 or 0x0002 */ - SHORT xAvgCharWidth; - USHORT usWeightClass; - USHORT usWidthClass; - SHORT fsType; /* if (faType & 0x08) editable_embedding */ - SHORT ySubscriptXSize; - SHORT ySubscriptYSize; - SHORT ySubscriptXOffset; - SHORT ySubscriptYOffset; - SHORT ySuperscriptXSize; - SHORT ySuperscriptYSize; - SHORT ySuperscriptXOffset; - SHORT ySuperscriptYOffset; - SHORT yStrikeoutSize; - SHORT yStrikeoutPosition; - SHORT sFamilyClass; - BYTE panose[10]; - ULONG ulUnicodeRange1; - ULONG ulUnicodeRange2; - ULONG ulUnicodeRange3; - ULONG ulUnicodeRange4; - ICHAR achVendID[4]; - USHORT fsSelection; - USHORT usFirstCharIndex; - USHORT usLastCharIndex; - SHORT sTypoAscender; /* TTF spec. from MS is wrong */ - SHORT sTypoDescender; /* TTF spec. from MS is wrong */ - SHORT sTypoLineGap; /* TTF spec. from MS is wrong */ - USHORT usWinAscent; - USHORT usWinDescent; - ULONG ulCodePageRange1; - ULONG ulCodePageRange2; - /* version 0x0002 */ - SHORT sxHeight; - SHORT sCapHeight; - USHORT usDefaultChar; - USHORT usBreakChar; - USHORT usMaxContext; +struct tt_os2__table { + USHORT version; /* 0x0001 or 0x0002 */ + SHORT xAvgCharWidth; + USHORT usWeightClass; + USHORT usWidthClass; + SHORT fsType; /* if (faType & 0x08) editable_embedding */ + SHORT ySubscriptXSize; + SHORT ySubscriptYSize; + SHORT ySubscriptXOffset; + SHORT ySubscriptYOffset; + SHORT ySuperscriptXSize; + SHORT ySuperscriptYSize; + SHORT ySuperscriptXOffset; + SHORT ySuperscriptYOffset; + SHORT yStrikeoutSize; + SHORT yStrikeoutPosition; + SHORT sFamilyClass; + BYTE panose[10]; + ULONG ulUnicodeRange1; + ULONG ulUnicodeRange2; + ULONG ulUnicodeRange3; + ULONG ulUnicodeRange4; + ICHAR achVendID[4]; + USHORT fsSelection; + USHORT usFirstCharIndex; + USHORT usLastCharIndex; + SHORT sTypoAscender; /* TTF spec. from MS is wrong */ + SHORT sTypoDescender; /* TTF spec. from MS is wrong */ + SHORT sTypoLineGap; /* TTF spec. from MS is wrong */ + USHORT usWinAscent; + USHORT usWinDescent; + ULONG ulCodePageRange1; + ULONG ulCodePageRange2; + /* version 0x0002 */ + SHORT sxHeight; + SHORT sCapHeight; + USHORT usDefaultChar; + USHORT usBreakChar; + USHORT usMaxContext; }; struct tt_vertOriginYMetrics { - USHORT glyphIndex; - SHORT vertOriginY; + USHORT glyphIndex; + SHORT vertOriginY; }; struct tt_VORG_table { - SHORT defaultVertOriginY; - USHORT numVertOriginYMetrics; - struct tt_vertOriginYMetrics *vertOriginYMetrics; + SHORT defaultVertOriginY; + USHORT numVertOriginYMetrics; + struct tt_vertOriginYMetrics *vertOriginYMetrics; }; /* hmtx and vmtx */ -struct tt_longMetrics -{ - USHORT advance; - SHORT sideBearing; +struct tt_longMetrics { + USHORT advance; + SHORT sideBearing; }; /* head, hhea, maxp */ -extern char *tt_pack_head_table (struct tt_head_table *table); -extern struct tt_head_table *tt_read_head_table (sfnt *sfont); -extern char *tt_pack_hhea_table (struct tt_hhea_table *table); -extern struct tt_hhea_table *tt_read_hhea_table (sfnt *sfont); -extern char *tt_pack_maxp_table (struct tt_maxp_table *table); -extern struct tt_maxp_table *tt_read_maxp_table (sfnt *sfont); +extern char *tt_pack_head_table(struct tt_head_table *table); +extern struct tt_head_table *tt_read_head_table(sfnt * sfont); +extern char *tt_pack_hhea_table(struct tt_hhea_table *table); +extern struct tt_hhea_table *tt_read_hhea_table(sfnt * sfont); +extern char *tt_pack_maxp_table(struct tt_maxp_table *table); +extern struct tt_maxp_table *tt_read_maxp_table(sfnt * sfont); /* vhea */ -extern char *tt_pack_vhea_table (struct tt_vhea_table *table); -extern struct tt_vhea_table *tt_read_vhea_table (sfnt *sfont); +extern char *tt_pack_vhea_table(struct tt_vhea_table *table); +extern struct tt_vhea_table *tt_read_vhea_table(sfnt * sfont); /* VORG */ -extern struct tt_VORG_table *tt_read_VORG_table (sfnt *sfont); +extern struct tt_VORG_table *tt_read_VORG_table(sfnt * sfont); /* hmtx and vmtx */ -extern struct tt_longMetrics *tt_read_longMetrics (sfnt *sfont, - USHORT numGlyphs, USHORT numLongMetrics); +extern struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, + USHORT numGlyphs, + USHORT numLongMetrics); /* OS/2 table */ -extern struct tt_os2__table *tt_read_os2__table (sfnt *sfont); +extern struct tt_os2__table *tt_read_os2__table(sfnt * sfont); /* name table */ -extern USHORT tt_get_name (sfnt *sfont, char *dest, USHORT destlen, - USHORT plat_id, USHORT enco_id, - USHORT lang_id, USHORT name_id); -extern USHORT tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen); +extern USHORT tt_get_name(sfnt * sfont, char *dest, USHORT destlen, + USHORT plat_id, USHORT enco_id, + USHORT lang_id, USHORT name_id); +extern USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen); -#endif /* _TT_TABLE_H_ */ +#endif /* _TT_TABLE_H_ */ diff --git a/Build/source/texk/web2c/luatexdir/font/vfovf.c b/Build/source/texk/web2c/luatexdir/font/vfovf.c index 61a0b76aaa4..fefcd16b756 100644 --- a/Build/source/texk/web2c/luatexdir/font/vfovf.c +++ b/Build/source/texk/web2c/luatexdir/font/vfovf.c @@ -1,113 +1,114 @@ -/* -Copyright (c) 1996-2006 Taco Hoekwater - -This file is part of LuaTeX. +/* vfovf.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -LuaTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -LuaTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with LuaTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: vfovf.c 1169 2008-04-15 14:57:56Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" - #include "luatex-api.h" +#include "luatexfont.h" + +static const char _svn_version[] = + "$Id: vfovf.c 2057 2009-03-19 15:45:47Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/vfovf.c $"; /* this is a hack! */ #define font_max 5000 -#define set_char_0 0 /* typeset character 0 and move right */ -#define set1 128 /* typeset a character and move right */ -#define set2 129 /* typeset a character and move right */ -#define set3 130 /* typeset a character and move right */ -#define set4 131 /* typeset a character and move right */ -#define set_rule 132 /* typeset a rule and move right */ -#define put1 133 /* typeset a character without moving */ -#define put2 134 /* typeset a character without moving */ -#define put3 135 /* typeset a character without moving */ -#define put4 136 /* typeset a character without moving */ -#define put_rule 137 /* typeset a rule */ -#define nop 138 /* no operation */ -#define bop 139 /* beginning of page */ -#define eop 140 /* ending of page */ -#define push 141 /* save the current positions */ -#define pop 142 /* restore previous positions */ -#define right1 143 /* move right */ -#define right2 144 /* move right */ -#define right3 145 /* move right */ -#define right4 146 /* move right, 4 bytes */ -#define w0 147 /* move right by |w| */ -#define w1 148 /* move right and set |w| */ -#define w2 149 /* move right and set |w| */ -#define w3 150 /* move right and set |w| */ -#define w4 151 /* move right and set |w| */ -#define x0 152 /* move right by |x| */ -#define x1 153 /* move right and set |x| */ -#define x2 154 /* move right and set |x| */ -#define x3 155 /* move right and set |x| */ -#define x4 156 /* move right and set |x| */ -#define down1 157 /* move down */ -#define down2 158 /* move down */ -#define down3 159 /* move down */ -#define down4 160 /* move down, 4 bytes */ -#define y0 161 /* move down by |y| */ -#define y1 162 /* move down and set |y| */ -#define y2 163 /* move down and set |y| */ -#define y3 164 /* move down and set |y| */ -#define y4 165 /* move down and set |y| */ -#define z0 166 /* move down by |z| */ -#define z1 167 /* move down and set |z| */ -#define z2 168 /* move down and set |z| */ -#define z3 169 /* move down and set |z| */ -#define z4 170 /* move down and set |z| */ -#define fnt_num_0 171 /* set current font to 0 */ -#define fnt1 235 /* set current font */ -#define fnt2 236 /* set current font */ -#define fnt3 237 /* set current font */ -#define fnt4 238 /* set current font */ -#define xxx1 239 /* extension to DVI primitives */ -#define xxx2 240 /* extension to DVI primitives */ -#define xxx3 241 /* extension to DVI primitives */ -#define xxx4 242 /* potentially long extension to DVI primitives */ -#define fnt_def1 243 /* define the meaning of a font number */ -#define pre 247 /* preamble */ -#define post 248 /* postamble beginning */ -#define post_post 249 /* postamble ending */ -#define yyy1 250 /* PDF literal text */ -#define yyy2 251 /* PDF literal text */ -#define yyy3 252 /* PDF literal text */ -#define yyy4 253 /* PDF literal text */ +#define set_char_0 0 /* typeset character 0 and move right */ +#define set1 128 /* typeset a character and move right */ +#define set2 129 /* typeset a character and move right */ +#define set3 130 /* typeset a character and move right */ +#define set4 131 /* typeset a character and move right */ +#define set_rule 132 /* typeset a rule and move right */ +#define put1 133 /* typeset a character without moving */ +#define put2 134 /* typeset a character without moving */ +#define put3 135 /* typeset a character without moving */ +#define put4 136 /* typeset a character without moving */ +#define put_rule 137 /* typeset a rule */ +#define nop 138 /* no operation */ +#define bop 139 /* beginning of page */ +#define eop 140 /* ending of page */ +#define push 141 /* save the current positions */ +#define pop 142 /* restore previous positions */ +#define right1 143 /* move right */ +#define right2 144 /* move right */ +#define right3 145 /* move right */ +#define right4 146 /* move right, 4 bytes */ +#define w0 147 /* move right by |w| */ +#define w1 148 /* move right and set |w| */ +#define w2 149 /* move right and set |w| */ +#define w3 150 /* move right and set |w| */ +#define w4 151 /* move right and set |w| */ +#define x0 152 /* move right by |x| */ +#define x1 153 /* move right and set |x| */ +#define x2 154 /* move right and set |x| */ +#define x3 155 /* move right and set |x| */ +#define x4 156 /* move right and set |x| */ +#define down1 157 /* move down */ +#define down2 158 /* move down */ +#define down3 159 /* move down */ +#define down4 160 /* move down, 4 bytes */ +#define y0 161 /* move down by |y| */ +#define y1 162 /* move down and set |y| */ +#define y2 163 /* move down and set |y| */ +#define y3 164 /* move down and set |y| */ +#define y4 165 /* move down and set |y| */ +#define z0 166 /* move down by |z| */ +#define z1 167 /* move down and set |z| */ +#define z2 168 /* move down and set |z| */ +#define z3 169 /* move down and set |z| */ +#define z4 170 /* move down and set |z| */ +#define fnt_num_0 171 /* set current font to 0 */ +#define fnt1 235 /* set current font */ +#define fnt2 236 /* set current font */ +#define fnt3 237 /* set current font */ +#define fnt4 238 /* set current font */ +#define xxx1 239 /* extension to DVI primitives */ +#define xxx2 240 /* extension to DVI primitives */ +#define xxx3 241 /* extension to DVI primitives */ +#define xxx4 242 /* potentially long extension to DVI primitives */ +#define fnt_def1 243 /* define the meaning of a font number */ +#define pre 247 /* preamble */ +#define post 248 /* postamble beginning */ +#define post_post 249 /* postamble ending */ +#define yyy1 250 /* PDF literal text */ +#define yyy2 251 /* PDF literal text */ +#define yyy3 252 /* PDF literal text */ +#define yyy4 253 /* PDF literal text */ #define null_font 0 -#define long_char 242 /* \.{VF} command for general character packet */ -#define vf_id 202 /* identifies \.{VF} files */ +#define long_char 242 /* \.{VF} command for general character packet */ +#define vf_id 202 /* identifies \.{VF} files */ /* go out \.{VF} processing with an error message */ -#define bad_vf(a) { xfree(vf_buffer); print_nlp(); \ - print_string("Error in processing VF font ("); \ - print_string(font_name(f)); \ - print_string(".vf): "); \ - print_string(a); \ - print_string(", virtual font will be ignored"); \ - print_ln(); return; } - -#define lua_bad_vf(a) { xfree(vf_buffer); \ - lua_settop(L,s_top); \ - lua_pushnil(L); \ - lua_pushstring(L,a); \ - return 2; } +#define bad_vf(a) { xfree(vf_buffer); print_nlp(); \ + print_string("Error in processing VF font ("); \ + print_string(font_name(f)); \ + print_string(".vf): "); \ + print_string(a); \ + print_string(", virtual font will be ignored"); \ + print_ln(); return; } + +#define lua_bad_vf(a) { xfree(vf_buffer); \ + lua_settop(L,s_top); \ + lua_pushnil(L); \ + lua_pushstring(L,a); \ + return 2; } #define tmp_b0 tmp_w.qqqq.b0 #define tmp_b1 tmp_w.qqqq.b1 @@ -115,9 +116,9 @@ $Id: vfovf.c 1169 2008-04-15 14:57:56Z oneiros $ #define tmp_b3 tmp_w.qqqq.b3 #define tmp_int tmp_w.cint -#define vf_stack_size 100 /* \.{DVI} files shouldn't |push| beyond this depth */ +#define vf_stack_size 100 /* \.{DVI} files shouldn't |push| beyond this depth */ -typedef unsigned char vf_stack_index ; /* an index into the stack */ +typedef unsigned char vf_stack_index; /* an index into the stack */ typedef struct vf_stack_record { scaled stack_w, stack_x, stack_y, stack_z; @@ -127,179 +128,201 @@ boolean auto_expand_vf(internal_font_number f); /* forward */ /* get a byte from\.{VF} file */ -#define vf_byte(a) { real_eight_bits vf_tmp_b; \ - if (vf_cur>=vf_size) { \ - pdftex_fail("unexpected eof on virtual font"); \ - } \ +#define vf_byte(a) { real_eight_bits vf_tmp_b; \ + if (vf_cur>=vf_size) { \ + pdftex_fail("unexpected eof on virtual font"); \ + } \ vf_tmp_b = vf_buffer[vf_cur++] ; a = vf_tmp_b; } -#define vf_replace_z() { \ - vf_alpha=16; \ - while (vf_z>=040000000) { \ - vf_z= vf_z / 2; \ - vf_alpha += vf_alpha; \ - } \ - vf_beta=256 / vf_alpha; \ +#define vf_replace_z() { \ + vf_alpha=16; \ + while (vf_z>=040000000) { \ + vf_z= vf_z / 2; \ + vf_alpha += vf_alpha; \ + } \ + vf_beta=256 / vf_alpha; \ vf_alpha=vf_alpha*vf_z; } /* read |k| bytes as an integer from \.{VF} file */ -#define vf_read(k,l) { integer itmp = 0, dtmp = k, jtmp = 0; \ - while (dtmp > 0) { \ - vf_byte(jtmp); \ - if ((dtmp==k) && jtmp>127) \ - jtmp = jtmp - 256; \ - itmp = itmp*256 + jtmp; \ - decr(dtmp); \ - } \ +#define vf_read(k,l) { integer itmp = 0, dtmp = k, jtmp = 0; \ + while (dtmp > 0) { \ + vf_byte(jtmp); \ + if ((dtmp==(integer)k) && jtmp>127) \ + jtmp = jtmp - 256; \ + itmp = itmp*256 + jtmp; \ + decr(dtmp); \ + } \ l = itmp; } -#define vf_read_u(k,l) { unsigned int dtmp=k, itmp = 0, jtmp = 0; \ - while (dtmp-- > 0) { \ - vf_byte(jtmp); \ - itmp = itmp*256 + jtmp; \ - } \ +#define vf_read_u(k,l) { unsigned int dtmp=k, itmp = 0, jtmp = 0; \ + while (dtmp-- > 0) { \ + vf_byte(jtmp); \ + itmp = itmp*256 + jtmp; \ + } \ l = itmp; } -void -pdf_check_vf_cur_val (void) { - internal_font_number f; - f = cur_val; - if (font_type(f) == virtual_font_type) - pdf_error(maketexstring("font"), maketexstring("command cannot be used with virtual font")); +void pdf_check_vf_cur_val(void) +{ + internal_font_number f; + f = cur_val; + if (font_type(f) == virtual_font_type) + pdf_error(maketexstring("font"), + maketexstring("command cannot be used with virtual font")); } static void -vf_local_font_warning(internal_font_number f, internal_font_number k, char *s, integer a, integer b) { - print_nlp(); - print_string(s); - print_string(" in local font "); - print_string(font_name(k)); - print_string(" ("); - print_int(b); - print_string(" != "); - print_int(a); - print_string(") in virtual font "); - print_string(font_name(f)); - print_string(".vf ignored."); +vf_local_font_warning(internal_font_number f, internal_font_number k, char *s, + integer a, integer b) +{ + print_nlp(); + print_string(s); + print_string(" in local font "); + print_string(font_name(k)); + print_string(" ("); + print_int(b); + print_string(" != "); + print_int(a); + print_string(") in virtual font "); + print_string(font_name(f)); + print_string(".vf ignored."); } /* process a local font in \.{VF} file */ -internal_font_number -vf_def_font(internal_font_number f,unsigned char *vf_buffer, integer *vf_cr) { +internal_font_number +vf_def_font(internal_font_number f, unsigned char *vf_buffer, integer * vf_cr) +{ internal_font_number k; str_number s; - scaled ds,fs; + scaled ds, fs; four_quarters cs; - memory_word tmp_w; /* accumulator */ + memory_word tmp_w; /* accumulator */ integer junk; unsigned long checksum; - cs.b0 = vf_buffer[(*vf_cr)]; - cs.b1 = vf_buffer[(*vf_cr)+1]; - cs.b2 = vf_buffer[(*vf_cr)+2]; - cs.b3 = vf_buffer[(*vf_cr)+3]; (*vf_cr)+=4; - checksum = cs.b0*256*256*256 + cs.b1*256*256 + cs.b2*256 + cs.b3; - k = vf_buffer[(*vf_cr)] ; (*vf_cr)++; - if (k>127) k-=256; - k = k*256+ vf_buffer[(*vf_cr)] ; (*vf_cr)++; - k = k*256+ vf_buffer[(*vf_cr)] ; (*vf_cr)++; - k = k*256+ vf_buffer[(*vf_cr)] ; (*vf_cr)++; + cs.b0 = vf_buffer[(*vf_cr)]; + cs.b1 = vf_buffer[(*vf_cr) + 1]; + cs.b2 = vf_buffer[(*vf_cr) + 2]; + cs.b3 = vf_buffer[(*vf_cr) + 3]; + (*vf_cr) += 4; + checksum = + cs.b0 * 256 * 256 * 256 + cs.b1 * 256 * 256 + cs.b2 * 256 + cs.b3; + k = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + if (k > 127) + k -= 256; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; fs = sqxfw(k, font_size(f)); - k = vf_buffer[(*vf_cr)] ; (*vf_cr)++; - if (k>127) k-=256; - k = k*256+ vf_buffer[(*vf_cr)] ; (*vf_cr)++; - k = k*256+ vf_buffer[(*vf_cr)] ; (*vf_cr)++; - k = k*256+ vf_buffer[(*vf_cr)] ; (*vf_cr)++; + k = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + if (k > 127) + k -= 256; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; ds = k / 16; - tmp_b0 = vf_buffer[(*vf_cr)] ; (*vf_cr)++; - tmp_b1 = vf_buffer[(*vf_cr)] ; (*vf_cr)++; + tmp_b0 = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + tmp_b1 = vf_buffer[(*vf_cr)]; + (*vf_cr)++; while (tmp_b0 > 0) { - tmp_b0--; - (*vf_cr)++; /* skip the font path */ + tmp_b0--; + (*vf_cr)++; /* skip the font path */ } string_room(tmp_b1); while (tmp_b1 > 0) { - tmp_b1--; - junk = vf_buffer[(*vf_cr)] ; (*vf_cr)++; - append_pool_char(junk); + tmp_b1--; + junk = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + append_pool_char(junk); } s = make_string(); k = tfm_lookup(s, fs); - if (k == null_font) - k = read_font_info(get_nullcs(), s, get_nullstr(), fs, -1); + if (k == null_font) + k = read_font_info(get_nullcs(), s, fs, -1); if (k != null_font) { - if (checksum!=0 && font_checksum(k)!=0 && checksum!= font_checksum(k)) - vf_local_font_warning(f, k, "checksum mismatch",checksum,font_checksum(k)); - if (ds != font_dsize(k)) - vf_local_font_warning(f, k, "design size mismatch",ds,font_dsize(k)); + if (checksum != 0 && font_checksum(k) != 0 + && checksum != font_checksum(k)) + vf_local_font_warning(f, k, "checksum mismatch", checksum, + font_checksum(k)); + if (ds != font_dsize(k)) + vf_local_font_warning(f, k, "design size mismatch", ds, + font_dsize(k)); } if (pdf_font_expand_ratio(f) != 0) - set_expand_params(k, pdf_font_auto_expand(f), - pdf_font_expand_ratio(pdf_font_stretch(f)), - -pdf_font_expand_ratio(pdf_font_shrink(f)), - pdf_font_step(f), pdf_font_expand_ratio(f)); + set_expand_params(k, pdf_font_auto_expand(f), + pdf_font_expand_ratio(pdf_font_stretch(f)), + -pdf_font_expand_ratio(pdf_font_shrink(f)), + pdf_font_step(f), pdf_font_expand_ratio(f)); return k; } -int -open_vf_file (char *fn, unsigned char **vbuffer, integer *vsize) { - boolean res; /* was the callback successful? */ - integer callback_id; - boolean file_read; /* was |vf_file| successfully read? */ - FILE *vf_file; - char *fnam = NULL; +int open_vf_file(char *fn, unsigned char **vbuffer, integer * vsize) +{ + boolean res; /* was the callback successful? */ + integer callback_id; + boolean file_read; /* was |vf_file| successfully read? */ + FILE *vf_file; + char *fnam = NULL; - namelength = strlen(fn); - nameoffile = xmalloc(namelength+2); - strcpy((char *)(nameoffile+1),fn); + namelength = strlen(fn); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), fn); - callback_id=callback_defined(find_vf_file_callback); - if (callback_id>0) { - res = run_callback(callback_id,"S->S",fn, &fnam); - if (res && (fnam!=NULL) && (strlen(fnam)>0)) { - /* @; */ - free(nameoffile); - namelength = strlen(fnam); - nameoffile = xmalloc(namelength+2); - strcpy((char *)(nameoffile+1),fnam); - } else { - return 0; - } - } - callback_id=callback_defined(read_vf_file_callback); - if (callback_id>0) { - file_read = false; - res = run_callback(callback_id,"S->bSd",stringcast(nameoffile+1), - &file_read, vbuffer,vsize); - if (res && file_read && (*vsize>0)) { - return 1; + callback_id = callback_defined(find_vf_file_callback); + if (callback_id > 0) { + res = run_callback(callback_id, "S->S", fn, &fnam); + if (res && (fnam != NULL) && (strlen(fnam) > 0)) { + /* @; */ + free(nameoffile); + namelength = strlen(fnam); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), fnam); + } else { + return 0; + } } - if (!file_read) - return 0; /* -1 */ - } else { - if (ovf_b_open_in(vf_file) || vf_b_open_in(vf_file)) { - res = read_vf_file(vf_file,vbuffer,vsize); - b_close(vf_file); - if (res) { - return 1; - } + callback_id = callback_defined(read_vf_file_callback); + if (callback_id > 0) { + file_read = false; + res = run_callback(callback_id, "S->bSd", stringcast(nameoffile + 1), + &file_read, vbuffer, vsize); + if (res && file_read && (*vsize > 0)) { + return 1; + } + if (!file_read) + return 0; /* -1 */ } else { - return 0; /* -1 */ + if (ovf_b_open_in(vf_file) || vf_b_open_in(vf_file)) { + res = read_vf_file(vf_file, vbuffer, vsize); + b_close(vf_file); + if (res) { + return 1; + } + } else { + return 0; /* -1 */ + } } - } - return 0; + return 0; } @@ -311,1039 +334,1281 @@ open_vf_file (char *fn, unsigned char **vbuffer, integer *vsize) { process font definitions in virtual font we call |vf_def_font|. */ -#define append_packet(k) vpackets[vf_np++] = k +#define append_packet(k) vpackets[vf_np++] = k /* life is easier if all internal font commands are fnt4 and all character commands are set4 or put4 */ -#define append_fnt_set(k) { \ - assert(k>0) ; \ - append_packet(packet_font_code); \ - append_four(k); } +#define append_fnt_set(k) { \ + assert(k>0) ; \ + append_packet(packet_font_code); \ + append_four(k); } -#define append_four(k) { \ - append_packet((k&0xFF000000)>>24); \ - append_packet((k&0x00FF0000)>>16); \ - append_packet((k&0x0000FF00)>>8); \ - append_packet((k&0x000000FF)); } +#define append_four(k) { \ + append_packet((k&0xFF000000)>>24); \ + append_packet((k&0x00FF0000)>>16); \ + append_packet((k&0x0000FF00)>>8); \ + append_packet((k&0x000000FF)); } /* some of these things happen twice, adding a define is simplest */ -#define test_checksum() { vf_byte(tmp_b0); vf_byte(tmp_b1); \ - vf_byte(tmp_b2); vf_byte(tmp_b3); \ +#define test_checksum() { vf_byte(tmp_b0); vf_byte(tmp_b1); \ + vf_byte(tmp_b2); vf_byte(tmp_b3); \ if (((tmp_b0 != 0) || (tmp_b1 != 0) || (tmp_b2 != 0) || (tmp_b3 != 0)) && \ - ((font_check_0(f) != 0) || (font_check_1(f) != 0) || \ - (font_check_2(f) != 0) || (font_check_3(f) != 0)) && \ - ((tmp_b0 != font_check_0(f)) || (tmp_b1 != font_check_1(f)) || \ - (tmp_b2 != font_check_2(f)) || (tmp_b3 != font_check_3(f)))) { \ - print_nlp(); \ - print_string("checksum mismatch in font "); \ - print_string(font_name(f)); \ + ((font_check_0(f) != 0) || (font_check_1(f) != 0) || \ + (font_check_2(f) != 0) || (font_check_3(f) != 0)) && \ + ((tmp_b0 != font_check_0(f)) || (tmp_b1 != font_check_1(f)) || \ + (tmp_b2 != font_check_2(f)) || (tmp_b3 != font_check_3(f)))) { \ + print_nlp(); \ + print_string("checksum mismatch in font "); \ + print_string(font_name(f)); \ print_string(".vf ignored "); } } -#define test_dsize() { int read_tmp; vf_read(4,read_tmp); \ - if ((read_tmp / 16) != font_dsize(f)) { \ - print_nlp(); \ - print_string("design size mismatch in font "); \ - print_string(font_name(f)); \ - print_string(".vf ignored"); \ +#define test_dsize() { int read_tmp; vf_read(4,read_tmp); \ + if ((read_tmp / 16) != font_dsize(f)) { \ + print_nlp(); \ + print_string("design size mismatch in font "); \ + print_string(font_name(f)); \ + print_string(".vf ignored"); \ } } -int count_packet_bytes (real_eight_bits *vf_buf, int cur_bute, int count) { - int k = 0; - int ff = 0; - int acc = 0; - unsigned int cmd = 0; - unsigned int d = 0; - while (k= set_char_0) && (cmd < set1)) { - if (ff==0) { ff = 1; acc+=5; } - acc+=5; - } else if ((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) { - ff = 1; - acc+=5; - } else { - switch (cmd) { - case fnt1: acc+=5; k+=1; ff=1 ; break; - case fnt2: acc+=5; k+=2; ff=1 ; break; - case fnt3: acc+=5; k+=3; ff=1 ; break; - case fnt4: acc+=5; k+=4; ff=1 ; break; - case set_rule: acc+=9; k+=8; break; - case put_rule: acc+=11; k+=8; break; - case set1: acc+=5; k+=1; if (ff==0) { ff = 1; acc+=5; } break; - case set2: acc+=5; k+=2; if (ff==0) { ff = 1; acc+=5; } break; - case set3: acc+=5; k+=3; if (ff==0) { ff = 1; acc+=5; } break; - case set4: acc+=5; k+=4; if (ff==0) { ff = 1; acc+=5; } break; - case put1: acc+=7; k+=1; if (ff==0) { ff = 1; acc+=5; } break; - case put2: acc+=7; k+=2; if (ff==0) { ff = 1; acc+=5; } break; - case put3: acc+=7; k+=3; if (ff==0) { ff = 1; acc+=5; } break; - case put4: acc+=7; k+=4; if (ff==0) { ff = 1; acc+=5; } break; - case right1: acc+=5; k+=1; break; - case right2: acc+=5; k+=2; break; - case right3: acc+=5; k+=3; break; - case right4: acc+=5; k+=4; break; - case w1: acc+=5; k+=1; break; - case w2: acc+=5; k+=2; break; - case w3: acc+=5; k+=3; break; - case w4: acc+=5; k+=4; break; - case x1: acc+=5; k+=1; break; - case x2: acc+=5; k+=2; break; - case x3: acc+=5; k+=3; break; - case x4: acc+=5; k+=4; break; - case down1: acc+=5; k+=1; break; - case down2: acc+=5; k+=2; break; - case down3: acc+=5; k+=3; break; - case down4: acc+=5; k+=4; break; - case y1: acc+=5; k+=1; break; - case y2: acc+=5; k+=2; break; - case y3: acc+=5; k+=3; break; - case y4: acc+=5; k+=4; break; - case z1: acc+=5; k+=1; break; - case z2: acc+=5; k+=2; break; - case z3: acc+=5; k+=3; break; - case z4: acc+=5; k+=4; break; - case xxx1: - d = vf_buf[cur_bute+k]; k++; - k += d; acc += 5 + d; - break; - case xxx2: - d = vf_buf[cur_bute+k]; k++; - d = d*256 + vf_buf[cur_bute+k]; k++; - k += d; acc += 5 + d; - break; - case xxx3: - d = vf_buf[cur_bute+k]; k++; - d = d*256 + vf_buf[cur_bute+k]; k++; - d = d*256 + vf_buf[cur_bute+k]; k++; - k += d; acc += 5 + d; - break; - case xxx4: - d = vf_buf[cur_bute+k]; k++; - d = d*256 + vf_buf[cur_bute+k]; k++; - d = d*256 + vf_buf[cur_bute+k]; k++; - d = d*256 + vf_buf[cur_bute+k]; k++; - k += d; acc += 5 + d; - break; - case w0: acc+=5; break; - case x0: acc+=5; break; - case y0: acc+=5; break; - case z0: acc+=5; break; - case nop: break; - case push: acc+=1; break; - case pop: acc+=1; break; - } - } - } - return (acc+1); +int count_packet_bytes(real_eight_bits * vf_buf, int cur_bute, int count) +{ + int k = 0; + int ff = 0; + int acc = 0; + unsigned int cmd = 0; + unsigned int d = 0; + while (k < count) { + cmd = vf_buf[cur_bute + k]; + k++; + if (cmd < set1) { + if (ff == 0) { + ff = 1; + acc += 5; + } + acc += 5; + } else if ((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) { + ff = 1; + acc += 5; + } else { + switch (cmd) { + case fnt1: + acc += 5; + k += 1; + ff = 1; + break; + case fnt2: + acc += 5; + k += 2; + ff = 1; + break; + case fnt3: + acc += 5; + k += 3; + ff = 1; + break; + case fnt4: + acc += 5; + k += 4; + ff = 1; + break; + case set_rule: + acc += 9; + k += 8; + break; + case put_rule: + acc += 11; + k += 8; + break; + case set1: + acc += 5; + k += 1; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case set2: + acc += 5; + k += 2; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case set3: + acc += 5; + k += 3; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case set4: + acc += 5; + k += 4; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put1: + acc += 7; + k += 1; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put2: + acc += 7; + k += 2; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put3: + acc += 7; + k += 3; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put4: + acc += 7; + k += 4; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case right1: + acc += 5; + k += 1; + break; + case right2: + acc += 5; + k += 2; + break; + case right3: + acc += 5; + k += 3; + break; + case right4: + acc += 5; + k += 4; + break; + case w1: + acc += 5; + k += 1; + break; + case w2: + acc += 5; + k += 2; + break; + case w3: + acc += 5; + k += 3; + break; + case w4: + acc += 5; + k += 4; + break; + case x1: + acc += 5; + k += 1; + break; + case x2: + acc += 5; + k += 2; + break; + case x3: + acc += 5; + k += 3; + break; + case x4: + acc += 5; + k += 4; + break; + case down1: + acc += 5; + k += 1; + break; + case down2: + acc += 5; + k += 2; + break; + case down3: + acc += 5; + k += 3; + break; + case down4: + acc += 5; + k += 4; + break; + case y1: + acc += 5; + k += 1; + break; + case y2: + acc += 5; + k += 2; + break; + case y3: + acc += 5; + k += 3; + break; + case y4: + acc += 5; + k += 4; + break; + case z1: + acc += 5; + k += 1; + break; + case z2: + acc += 5; + k += 2; + break; + case z3: + acc += 5; + k += 3; + break; + case z4: + acc += 5; + k += 4; + break; + case xxx1: + d = vf_buf[cur_bute + k]; + k++; + k += d; + acc += 5 + d; + break; + case xxx2: + d = vf_buf[cur_bute + k]; + k++; + d = d * 256 + vf_buf[cur_bute + k]; + k++; + k += d; + acc += 5 + d; + break; + case xxx3: + d = vf_buf[cur_bute + k]; + k++; + d = d * 256 + vf_buf[cur_bute + k]; + k++; + d = d * 256 + vf_buf[cur_bute + k]; + k++; + k += d; + acc += 5 + d; + break; + case xxx4: + d = vf_buf[cur_bute + k]; + k++; + d = d * 256 + vf_buf[cur_bute + k]; + k++; + d = d * 256 + vf_buf[cur_bute + k]; + k++; + d = d * 256 + vf_buf[cur_bute + k]; + k++; + k += d; + acc += 5 + d; + break; + case w0: + acc += 5; + break; + case x0: + acc += 5; + break; + case y0: + acc += 5; + break; + case z0: + acc += 5; + break; + case nop: + break; + case push: + acc += 1; + break; + case pop: + acc += 1; + break; + } + } + } + return (acc + 1); } -void -do_vf(internal_font_number f) { - integer k, n, i; - unsigned cmd; - scaled x,y,w,z,h,v; - integer cc, cmd_length, packet_length; - charinfo *co; - scaled tfm_width; - integer save_cur_byte; - vf_stack_index stack_level; - integer vf_z; /* multiplier */ - integer vf_alpha; /* correction for negative values */ - char vf_beta; /* divisor */ - integer vf_np; - real_eight_bits *vpackets; - memory_word tmp_w; /* accumulator */ - vf_stack_record vf_stack[256]; - integer junk; - unsigned char *vf_buffer; - integer vf_size; - integer vf_cur; - integer *vf_local_fnts = NULL; /* external font ids */ - integer *vf_real_fnts = NULL; /* internal font ids */ - unsigned vf_nf = 0; /* local font counter */ - - if (font_type(f)!= unknown_font_type) - return; - set_font_type(f,real_font_type); - if (auto_expand_vf(f)) - return; /* auto-expanded virtual font */ - stack_level = 0; - /* @; */ - vf_cur=0; vf_buffer=NULL; vf_size=0; - if (!open_vf_file(font_name(f), &vf_buffer, &vf_size)) - return; - /* @;@/ */ - set_font_type(f,virtual_font_type); - vf_byte(k); - if (k != pre) - bad_vf("PRE command expected"); - vf_byte(k); - if (k != vf_id) - bad_vf("wrong id byte"); - vf_byte(cmd_length); - for (k = 1;k<= cmd_length;k++) - vf_byte(junk); - test_checksum(); - test_dsize(); - /* update_terminal;*/ - vf_z = font_size(f); - vf_replace_z(); - /* @;@/ */ - /* scan forward to find the number of internal fonts */ - vf_nf = 0; - save_cur_byte = vf_cur; - vf_byte(cmd); - while ((cmd >= fnt_def1) && (cmd <= (fnt_def1 + 3))) { - vf_read((cmd - fnt_def1 + 1),junk); - vf_read(4,junk); - vf_read(4,junk); - vf_read(4,junk); +void do_vf(internal_font_number f) +{ + integer k, i; + unsigned cmd, n; + scaled x, y, w, z, h, v; + integer cc, cmd_length, packet_length; + charinfo *co; + scaled tfm_width; + integer save_cur_byte; + vf_stack_index stack_level; + integer vf_z; /* multiplier */ + integer vf_alpha; /* correction for negative values */ + char vf_beta; /* divisor */ + integer vf_np; + real_eight_bits *vpackets; + memory_word tmp_w; /* accumulator */ + vf_stack_record vf_stack[256]; + integer junk; + unsigned char *vf_buffer; + integer vf_size; + integer vf_cur; + integer *vf_local_fnts = NULL; /* external font ids */ + integer *vf_real_fnts = NULL; /* internal font ids */ + unsigned vf_nf = 0; /* local font counter */ + + if (font_type(f) != unknown_font_type) + return; + set_font_type(f, real_font_type); + if (auto_expand_vf(f)) + return; /* auto-expanded virtual font */ + stack_level = 0; + /* @; */ + vf_cur = 0; + vf_buffer = NULL; + vf_size = 0; + if (!open_vf_file(font_name(f), &vf_buffer, &vf_size)) + return; + /* @;@/ */ + set_font_type(f, virtual_font_type); vf_byte(k); - vf_byte(junk); - k += junk; - while (k-- > 0) { vf_byte(junk); } - incr(vf_nf); - vf_byte(cmd); - } - vf_cur = save_cur_byte; - vf_byte(cmd); - /* malloc and fill the local font arrays */ - if (vf_nf>0) { - i = vf_nf*sizeof(integer); - vf_local_fnts= xmalloc(i); - memset(vf_local_fnts,0,i); - vf_real_fnts= xmalloc(i); - memset(vf_real_fnts,0,i); + if (k != pre) + bad_vf("PRE command expected"); + vf_byte(k); + if (k != vf_id) + bad_vf("wrong id byte"); + vf_byte(cmd_length); + for (k = 1; k <= cmd_length; k++) + vf_byte(junk); + test_checksum(); + test_dsize(); + /* update_terminal; */ + vf_z = font_size(f); + vf_replace_z(); + /* @;@/ */ + /* scan forward to find the number of internal fonts */ vf_nf = 0; + save_cur_byte = vf_cur; + vf_byte(cmd); while ((cmd >= fnt_def1) && (cmd <= (fnt_def1 + 3))) { - vf_read_u((cmd - fnt_def1 + 1),vf_local_fnts[vf_nf]); - vf_real_fnts[vf_nf] = vf_def_font(f, vf_buffer, &vf_cur); - incr(vf_nf); - vf_byte(cmd); + vf_read((cmd - fnt_def1 + 1), junk); + vf_read(4, junk); + vf_read(4, junk); + vf_read(4, junk); + vf_byte(k); + vf_byte(junk); + k += junk; + while (k-- > 0) { + vf_byte(junk); + } + incr(vf_nf); + vf_byte(cmd); + } + vf_cur = save_cur_byte; + vf_byte(cmd); + /* malloc and fill the local font arrays */ + if (vf_nf > 0) { + i = vf_nf * sizeof(integer); + vf_local_fnts = xmalloc(i); + memset(vf_local_fnts, 0, i); + vf_real_fnts = xmalloc(i); + memset(vf_real_fnts, 0, i); + vf_nf = 0; + while ((cmd >= fnt_def1) && (cmd <= (fnt_def1 + 3))) { + vf_read_u((cmd - fnt_def1 + 1), vf_local_fnts[vf_nf]); + vf_real_fnts[vf_nf] = vf_def_font(f, vf_buffer, &vf_cur); + incr(vf_nf); + vf_byte(cmd); + } } - } - while (cmd <= long_char) { - /* @;@/ */ - vf_np = 0; - if (cmd == long_char) { - vf_read_u(4,packet_length); - vf_read_u(4,cc); - if (!char_exists(f,cc)) { - bad_vf("invalid character code"); - } - vf_read(4,k); - tfm_width = sqxfw(k, font_size(f)); - } else { - packet_length = cmd; - vf_byte(cc); - if (!char_exists(f,cc)) { - bad_vf("invalid character code"); - } - vf_read(3,k); - tfm_width = sqxfw(k, font_size(f)); + while (cmd <= long_char) { + /* @;@/ */ + vf_np = 0; + if (cmd == long_char) { + vf_read_u(4, packet_length); + vf_read_u(4, cc); + if (!char_exists(f, cc)) { + bad_vf("invalid character code"); + } + vf_read(4, k); + tfm_width = sqxfw(k, font_size(f)); + } else { + packet_length = cmd; + vf_byte(cc); + if (!char_exists(f, cc)) { + bad_vf("invalid character code"); + } + vf_read(3, k); + tfm_width = sqxfw(k, font_size(f)); + } + if (packet_length < 0) + bad_vf("negative packet length"); + if (tfm_width != char_width(f, cc)) { + /* precisely 'one off' errors are rampant */ + if (abs(tfm_width - char_width(f, cc)) > 1) { + print_nlp(); + print_string("character width mismatch in font "); + print_string(font_name(f)); + print_string(".vf ignored"); + } + } + k = count_packet_bytes(vf_buffer, vf_cur, packet_length); + vpackets = xmalloc(k + 1); /* need one extra extra for packet_end */ + co = get_charinfo(f, cc); + k = 0; + w = 0; + x = 0; + y = 0; + z = 0; + while (packet_length > 0) { + vf_byte(cmd); + decr(packet_length); + + if (cmd < set1) { + if (k == 0) { + k = vf_real_fnts[0]; + append_fnt_set(k); + } + append_packet(packet_char_code); + append_four(cmd); + cmd_length = 0; + cmd = nop; + + } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || + ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { + if (cmd >= fnt1) { + vf_read_u((cmd - fnt1 + 1), k); + packet_length -= (cmd - fnt1 + 1); + } else { + k = cmd - fnt_num_0; + } + + /* change from local to external font id */ + n = 0; + while ((n < vf_nf) && (vf_local_fnts[n] != k)) + n++; + if (n == vf_nf) + bad_vf("undefined local font"); + + k = vf_real_fnts[n]; + append_fnt_set(k); + cmd_length = 0; + cmd = nop; + } else { + switch (cmd) { + case set_rule: + vf_read(4, h); + vf_read(4, v); + append_packet(packet_rule_code); + append_four(h); + append_four(v); + packet_length -= 8; + break; + case put_rule: + vf_read(4, h); + vf_read(4, v); + append_packet(packet_push_code); + append_packet(packet_rule_code); + append_four(h); + append_four(v); + append_packet(packet_pop_code); + packet_length -= 8; + break; + case set1: + case set2: + case set3: + case set4: + if (k == 0) { + k = vf_real_fnts[0]; + append_fnt_set(k); + } + vf_read_u((cmd - set1 + 1), i); + append_packet(packet_char_code); + append_four(i); + packet_length -= (cmd - set1 + 1); + break; + case put1: + case put2: + case put3: + case put4: + if (k == 0) { + k = vf_real_fnts[0]; + append_fnt_set(k); + } + vf_read_u((cmd - put1 + 1), i); + append_packet(packet_push_code); + append_packet(packet_char_code); + append_four(i); + append_packet(packet_pop_code); + packet_length -= (cmd - put1 + 1); + break; + case right1: + case right2: + case right3: + case right4: + vf_read((cmd - right1 + 1), i); + append_packet(packet_right_code); + append_four(i); + packet_length -= (cmd - right1 + 1); + break; + case w1: + case w2: + case w3: + case w4: + vf_read((cmd - w1 + 1), w); + append_packet(packet_right_code); + append_four(w); + packet_length -= (cmd - w1 + 1); + break; + case x1: + case x2: + case x3: + case x4: + vf_read((cmd - x1 + 1), x); + append_packet(packet_right_code); + append_four(x); + packet_length -= (cmd - x1 + 1); + break; + case down1: + case down2: + case down3: + case down4: + vf_read((cmd - down1 + 1), i); + append_packet(packet_down_code); + append_four(i); + packet_length -= (cmd - down1 + 1); + break; + case y1: + case y2: + case y3: + case y4: + vf_read((cmd - y1 + 1), y); + append_packet(packet_down_code); + append_four(y); + packet_length -= (cmd - y1 + 1); + break; + case z1: + case z2: + case z3: + case z4: + vf_read((cmd - z1 + 1), z); + append_packet(packet_down_code); + append_four(z); + packet_length -= (cmd - z1 + 1); + break; + case xxx1: + case xxx2: + case xxx3: + case xxx4: + vf_read_u((cmd - xxx1 + 1), cmd_length); + packet_length -= (cmd - xxx1 + 1); + if (cmd_length <= 0) + bad_vf("special of negative length"); + packet_length -= cmd_length; + + append_packet(packet_special_code); + append_four(cmd_length); + while (cmd_length > 0) { + cmd_length--; + vf_byte(i); + append_packet(i); + } + break; + case w0: + append_packet(packet_right_code); + append_four(w); + break; + case x0: + append_packet(packet_right_code); + append_four(x); + break; + case y0: + append_packet(packet_down_code); + append_four(y); + break; + case z0: + append_packet(packet_down_code); + append_four(z); + break; + case nop: + break; + case push: + if (stack_level == vf_stack_size) { + overflow_string("virtual font stack size", + vf_stack_size); + } else { + vf_stack[stack_level].stack_w = w; + vf_stack[stack_level].stack_x = x; + vf_stack[stack_level].stack_y = y; + vf_stack[stack_level].stack_z = z; + incr(stack_level); + append_packet(packet_push_code); + } + break; + case pop: + if (stack_level == 0) { + bad_vf("more POPs than PUSHs in character"); + } else { + decr(stack_level); + w = vf_stack[stack_level].stack_w; + x = vf_stack[stack_level].stack_x; + y = vf_stack[stack_level].stack_y; + z = vf_stack[stack_level].stack_z; + append_packet(packet_pop_code); + } + break; + default: + bad_vf("improver DVI command"); + } + } + } + /* signal end of packet */ + append_packet(packet_end_code); + + if (stack_level != 0) + bad_vf("more PUSHs than POPs in character packet"); + if (packet_length != 0) + bad_vf("invalid packet length or DVI command in packet"); + /* @; */ + set_charinfo_packets(co, vpackets); + vf_byte(cmd); } - if (packet_length < 0) - bad_vf("negative packet length"); - if (tfm_width != char_width(f,cc)) { - /* precisely 'one off' errors are rampant */ - if (abs(tfm_width - char_width(f,cc))>1) { - print_nlp(); - print_string("character width mismatch in font "); - print_string(font_name(f)); - print_string(".vf ignored"); - } - } - k = count_packet_bytes(vf_buffer,vf_cur,packet_length); - vpackets = xmalloc(k+1); - co = get_charinfo(f,cc); - k = 0; - w = 0; x = 0; y = 0; z = 0; - while (packet_length > 0) { - vf_byte(cmd); - decr(packet_length); - - if ((cmd >= set_char_0) && (cmd < set1)) { - if (k == 0) { - k = vf_real_fnts[0]; - append_fnt_set(k); - } - append_packet(packet_char_code); - append_four(cmd); - cmd_length = 0; - cmd = nop; - - } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || - ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { - if (cmd >= fnt1) { - vf_read_u((cmd - fnt1 + 1),k); - packet_length -= (cmd - fnt1 + 1); - } else { - k = cmd - fnt_num_0; - } - - /* change from local to external font id */ - n = 0; - while ((n < vf_nf) && (vf_local_fnts[n] != k)) - n++; - if (n==vf_nf) - bad_vf("undefined local font"); - - k = vf_real_fnts[n]; - append_fnt_set(k); - cmd_length = 0; - cmd = nop; - } else { - switch (cmd) { - case set_rule: - vf_read(4,h); vf_read(4,v); - append_packet(packet_rule_code); - append_four(h); - append_four(v); - packet_length -= 8; - break; - case put_rule: - vf_read(4,h); vf_read(4,v); - append_packet(packet_push_code); - append_packet(packet_rule_code); - append_four(h); - append_four(v); - append_packet(packet_pop_code); - packet_length -= 8; - break; - case set1: - case set2: - case set3: - case set4: - if (k == 0) { - k = vf_real_fnts[0]; - append_fnt_set(k); - } - vf_read_u((cmd - set1 + 1),i); - append_packet(packet_char_code); - append_four(i); - packet_length -= (cmd - set1 + 1); - break; - case put1: - case put2: - case put3: - case put4: - if (k == 0) { - k = vf_real_fnts[0]; - append_fnt_set(k); - } - vf_read_u((cmd - put1 + 1),i); - append_packet(packet_push_code); - append_packet(packet_char_code); - append_four(i); - append_packet(packet_pop_code); - packet_length -= (cmd - put1 + 1); - break; - case right1: - case right2: - case right3: - case right4: - vf_read((cmd - right1 + 1),i); - append_packet(packet_right_code); - append_four(i); - packet_length -= (cmd - right1 + 1); - break; - case w1: - case w2: - case w3: - case w4: - vf_read((cmd - w1 + 1),w); - append_packet(packet_right_code); - append_four(w); - packet_length -= (cmd - w1 + 1); - break; - case x1: - case x2: - case x3: - case x4: - vf_read((cmd - x1 + 1),x); - append_packet(packet_right_code); - append_four(x); - packet_length -= (cmd - x1 + 1); - break; - case down1: - case down2: - case down3: - case down4: - vf_read((cmd - down1 + 1),i); - append_packet(packet_down_code); - append_four(i); - packet_length -= (cmd - down1 + 1); - break; - case y1: - case y2: - case y3: - case y4: - vf_read((cmd - y1 + 1),y); - append_packet(packet_down_code); - append_four(y); - packet_length -= (cmd - y1 + 1); - break; - case z1: - case z2: - case z3: - case z4: - vf_read((cmd - z1 + 1),z); - append_packet(packet_down_code); - append_four(z); - packet_length -= (cmd - z1 + 1); - break; - case xxx1: - case xxx2: - case xxx3: - case xxx4: - vf_read_u((cmd - xxx1 + 1),cmd_length); - packet_length -= (cmd - xxx1 + 1); - if (cmd_length <= 0) - bad_vf("special of negative length"); - packet_length -= cmd_length; - - append_packet(packet_special_code); - append_four(cmd_length); - while (cmd_length > 0) { - cmd_length--; - vf_byte(i); - append_packet(i); - } - append_packet(0); - break; - case w0: - append_packet(packet_right_code); - append_four(w); - break; - case x0: - append_packet(packet_right_code); - append_four(x); - break; - case y0: - append_packet(packet_down_code); - append_four(y); - break; - case z0: - append_packet(packet_down_code); - append_four(z); - break; - case nop: - break; - case push: - if (stack_level == vf_stack_size) { - overflow_string("virtual font stack size", vf_stack_size); - } else { - vf_stack[stack_level].stack_w = w; - vf_stack[stack_level].stack_x = x; - vf_stack[stack_level].stack_y = y; - vf_stack[stack_level].stack_z = z; - incr(stack_level); - append_packet(packet_push_code); - } - break; - case pop: - if (stack_level == 0) { - bad_vf("more POPs than PUSHs in character"); - } else { - decr(stack_level); - w = vf_stack[stack_level].stack_w; - x = vf_stack[stack_level].stack_x; - y = vf_stack[stack_level].stack_y; - z = vf_stack[stack_level].stack_z; - append_packet(packet_pop_code); - } - break; - default: - bad_vf("improver DVI command"); - } - } - } - /* signal end of packet */ - append_packet(packet_end_code); - - if (stack_level != 0) - bad_vf("more PUSHs than POPs in character packet"); - if (packet_length != 0) - bad_vf("invalid packet length or DVI command in packet"); - /* @; */ - set_charinfo_packets(co,vpackets); - vf_byte(cmd); - } - if (cmd != post) - bad_vf("POST command expected"); + if (cmd != post) + bad_vf("POST command expected"); - xfree(vf_buffer); + xfree(vf_buffer); } -#define make_command0(N,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_rawseti(L,-2, K); \ +#define make_command0(N,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_rawseti(L,-2, K); \ K++; } -#define make_command1(N,V,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushnumber(L, V); \ - lua_rawseti(L,-2, 2); \ - lua_rawseti(L,-2, K); \ +#define make_command1(N,V,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushnumber(L, V); \ + lua_rawseti(L,-2, 2); \ + lua_rawseti(L,-2, K); \ K++; } -#define make_command2(N,V,W,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushnumber(L, V); \ - lua_rawseti(L,-2, 2); \ - lua_pushnumber(L, W); \ - lua_rawseti(L,-2, 3); \ - lua_rawseti(L,-2, K); \ +#define make_command2(N,V,W,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushnumber(L, V); \ + lua_rawseti(L,-2, 2); \ + lua_pushnumber(L, W); \ + lua_rawseti(L,-2, 3); \ + lua_rawseti(L,-2, K); \ K++; } -#define make_commands(N,S,V,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushlstring(L, S, V); \ - lua_rawseti(L,-2, 2); \ - lua_rawseti(L,-2, K); \ +#define make_commands(N,S,V,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushlstring(L, S, V); \ + lua_rawseti(L,-2, 2); \ + lua_rawseti(L,-2, K); \ K++; } -int -make_vf_table(lua_State *L, char *cnom, scaled atsize) { - integer cmd, k, i; - integer cc, cmd_length, packet_length; - scaled tfm_width; - vf_stack_index stack_level; - integer vf_z; /* multiplier */ - integer vf_alpha; /* correction for negative values */ - char vf_beta; /* divisor */ - char *s; - scaled h,v; - scaled w, x, y, z; - integer s_top; /* lua stack */ - integer vf_nf ; /* local font counter */ - scaled ds,fs; - four_quarters cs; - memory_word tmp_w; /* accumulator */ - vf_stack_record vf_stack[256]; - unsigned char *vf_buffer; - integer vf_size; - integer vf_cur; - - - stack_level = 0; - /* @; */ - vf_cur=0; vf_buffer=NULL; vf_size=0; - if (!open_vf_file(cnom, &vf_buffer, &vf_size)) { - lua_pushnil(L); - return 1; - } +int make_vf_table(lua_State * L, char *cnom, scaled atsize) +{ + integer cmd, k, i; + integer cc, cmd_length, packet_length; + scaled tfm_width; + vf_stack_index stack_level; + integer vf_z; /* multiplier */ + integer vf_alpha; /* correction for negative values */ + char vf_beta; /* divisor */ + char *s; + scaled h, v; + scaled w, x, y, z; + integer s_top; /* lua stack */ + integer vf_nf; /* local font counter */ + scaled ds, fs; + four_quarters cs; + memory_word tmp_w; /* accumulator */ + vf_stack_record vf_stack[256]; + unsigned char *vf_buffer; + integer vf_size; + integer vf_cur; + + + stack_level = 0; + /* @; */ + vf_cur = 0; + vf_buffer = NULL; + vf_size = 0; + if (!open_vf_file(cnom, &vf_buffer, &vf_size)) { + lua_pushnil(L); + return 1; + } + + /* start by creating a table */ + s_top = lua_gettop(L); + lua_newtable(L); + + /* @;@/ */ + vf_byte(k); + if (k != pre) + lua_bad_vf("PRE command expected"); + vf_byte(k); + if (k != vf_id) + lua_bad_vf("wrong id byte"); + vf_byte(cmd_length); + + s = xmalloc(cmd_length); + for (k = 1; k <= cmd_length; k++) + vf_byte(s[(k - 1)]); - /* start by creating a table */ - s_top = lua_gettop(L); - lua_newtable(L); - - /* @;@/ */ - vf_byte(k); - if (k != pre) - lua_bad_vf("PRE command expected"); - vf_byte(k); - if (k != vf_id) - lua_bad_vf("wrong id byte"); - vf_byte(cmd_length); - - s = xmalloc(cmd_length); - for (k = 1;k<= cmd_length;k++) - vf_byte(s[(k-1)]); - - lua_pushlstring(L,s,cmd_length); - free(s); - lua_setfield(L,-2,"header"); - - vf_byte(cs.b0); vf_byte(cs.b1); vf_byte(cs.b2); vf_byte(cs.b3); - lua_pushnumber(L, (unsigned long)(cs.b0<<24)+(cs.b1<<16)+(cs.b2<<8)+cs.b3 ); - lua_setfield(L,-2,"checksum"); - - vf_read(4,k); - ds = k /16; - lua_pushinteger(L,ds); - lua_setfield(L,-2,"designsize"); - - - lua_pushstring(L,cnom); - lua_setfield(L,-2,"name"); - - lua_pushinteger(L,atsize); - lua_setfield(L,-2,"size"); - - - /* update_terminal;*/ - vf_z = atsize; - vf_replace_z(); - /* @;@/ */ - vf_byte(cmd); - lua_newtable(L); - - i = 1; - while ((cmd >= fnt_def1) && (cmd <= fnt_def1 + 3)) { - - lua_newtable(L); - vf_read_u((cmd - fnt_def1 + 1),vf_nf); - vf_nf++; - /* checksum */ - vf_byte(cs.b0); vf_byte(cs.b1); vf_byte(cs.b2); vf_byte(cs.b3); - - vf_read(4,k); - fs = sqxfw(k, atsize); - lua_pushstring(L,"size"); - lua_pushnumber(L,fs); - lua_rawset(L,-3); - - vf_read(4,k); - ds = k / 16; /* dsize, not used */ - - vf_byte(tmp_b0); - vf_byte(tmp_b1); - while (tmp_b0 > 0) { tmp_b0--; vf_byte(k); } /* skip the font path */ - - s = xmalloc(tmp_b1+1); k = 0; - while (tmp_b1-- > 0) - vf_byte(s[k++]); - s[k]=0; - lua_pushstring(L,"name"); - lua_pushstring(L,xstrdup(s)); + lua_pushlstring(L, s, cmd_length); free(s); - lua_rawset(L,-3); - - lua_rawseti(L,-2,vf_nf); - i++; - vf_byte(cmd); - } + lua_setfield(L, -2, "header"); + + vf_byte(cs.b0); + vf_byte(cs.b1); + vf_byte(cs.b2); + vf_byte(cs.b3); + lua_pushnumber(L, + (unsigned long) (cs.b0 << 24) + (cs.b1 << 16) + + (cs.b2 << 8) + cs.b3); + lua_setfield(L, -2, "checksum"); + + vf_read(4, k); + ds = k / 16; + lua_pushinteger(L, ds); + lua_setfield(L, -2, "designsize"); - if (i>1) { - lua_setfield(L,-2,"fonts"); - } else { - lua_pop(L,1); - } - lua_newtable(L); /* 'characters' */ - while (cmd <= long_char) { - /* @;@/ */ - if (cmd == long_char) { - vf_read_u(4,packet_length); - vf_read_u(4,cc); - vf_read(4,tfm_width); - } else { - packet_length = cmd; - vf_byte(cc); - vf_read(3,tfm_width); - } - if (packet_length < 0) - lua_bad_vf("negative packet length"); - - lua_newtable(L); /* for this character */ - - lua_pushnumber(L,tfm_width); - lua_setfield(L,-2,"width"); - - lua_newtable(L); /* for 'commands' */ - - k = 1; vf_nf = 0; - w = 0; x = 0; y = 0; z = 0; - while (packet_length > 0) { - vf_byte(cmd); - decr(packet_length); - - if ((cmd >= set_char_0) && (cmd < set1)) { - if (vf_nf == 0) { - vf_nf = 1; - make_command1("font",vf_nf,k); - } - make_command1("char",cmd,k); - - } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || - ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { - if (cmd >= fnt1) { - vf_read_u((cmd - fnt1 + 1),vf_nf); vf_nf++; - packet_length -= (cmd - fnt1 + 1); - } else { - vf_nf = cmd - fnt_num_0 + 1; - } - make_command1("font",vf_nf,k); - } else { - switch (cmd) { - case set_rule: - vf_read(4,h); vf_read(4,v); - make_command2("rule",sqxfw(h,atsize),sqxfw(v,atsize),k); - packet_length -= 8; - break; - case put_rule: - vf_read(4,h); vf_read(4,v); - make_command0("push",k); - make_command2("rule",sqxfw(h,atsize),sqxfw(v,atsize),k); - make_command0("pop",k); - packet_length -= 8; - break; - case set1: - case set2: - case set3: - case set4: - if (vf_nf == 0) { - vf_nf = 1; - make_command1("font",vf_nf,k); - } - vf_read_u((cmd - set1 + 1),i); - make_command1("char",i,k); - packet_length -= (cmd - set1 + 1); - break; - case put1: - case put2: - case put3: - case put4: - if (vf_nf == 0) { - vf_nf = 1; - make_command1("font",vf_nf,k); - } - vf_read_u((cmd - put1 + 1),i); - make_command0("push",k); - make_command1("char",i,k); - make_command0("pop",k); - packet_length -= (cmd - put1 + 1); - break; - case right1: - case right2: - case right3: - case right4: - vf_read((cmd - right1 + 1),i); - make_command1("right",sqxfw(i,atsize),k); - packet_length -= (cmd - right1 + 1); - break; - case w1: - case w2: - case w3: - case w4: - vf_read((cmd - w1 + 1),w); - make_command1("right",sqxfw(w,atsize),k); - packet_length -= (cmd - w1 + 1); - break; - case x1: - case x2: - case x3: - case x4: - vf_read((cmd - x1 + 1),x); - make_command1("right",sqxfw(x,atsize),k); - packet_length -= (cmd - x1 + 1); - break; - case down1: - case down2: - case down3: - case down4: - vf_read((cmd - down1 + 1),i); - make_command1("down",sqxfw(i,atsize),k); - packet_length -= (cmd - down1 + 1); - break; - case y1: - case y2: - case y3: - case y4: - vf_read((cmd - y1 + 1),y); - make_command1("down",sqxfw(y,atsize),k); - packet_length -= (cmd - y1 + 1); - break; - case z1: - case z2: - case z3: - case z4: - vf_read((cmd - z1 + 1),z); - make_command1("down",sqxfw(z,atsize),k); - packet_length -= (cmd - z1 + 1); - break; - case xxx1: - case xxx2: - case xxx3: - case xxx4: - vf_read_u((cmd - xxx1 + 1),cmd_length); - packet_length -= (cmd - xxx1 + 1); - if (cmd_length <= 0) - lua_bad_vf("special of negative length"); - packet_length -= cmd_length; - - s = xmalloc(cmd_length+1); i = 0; - while (cmd_length > 0) { - cmd_length--; - vf_byte(s[i]); - i++; - } - s[i]=0; - make_commands("special",strdup(s),i,k); - free(s); - break; - case w0: - make_command1("right",sqxfw(w,atsize),k); - break; - case x0: - make_command1("right",sqxfw(x,atsize),k); - break; - case y0: - make_command1("down",sqxfw(y,atsize),k); - break; - case z0: - make_command1("down",sqxfw(z,atsize),k); - break; - case nop: - break; - case push: - if (stack_level == vf_stack_size) { - overflow_string("virtual font stack size", vf_stack_size); - } else { - vf_stack[stack_level].stack_w = w; - vf_stack[stack_level].stack_x = x; - vf_stack[stack_level].stack_y = y; - vf_stack[stack_level].stack_z = z; - incr(stack_level); - make_command0("push",k); - } - break; - case pop: - if (stack_level == 0) { - lua_bad_vf("more POPs than PUSHs in character"); - } else { - decr(stack_level); - w = vf_stack[stack_level].stack_w; - x = vf_stack[stack_level].stack_x; - y = vf_stack[stack_level].stack_y; - z = vf_stack[stack_level].stack_z; - make_command0("pop",k); - } - break; - default: - lua_bad_vf("improver DVI command"); - } - } - } - /* signal end of packet */ - lua_setfield(L,-2,"commands"); + lua_pushstring(L, cnom); + lua_setfield(L, -2, "name"); - if (stack_level != 0) - lua_bad_vf("more PUSHs than POPs in character packet"); - if (packet_length != 0) - lua_bad_vf("invalid packet length or DVI command in packet"); + lua_pushinteger(L, atsize); + lua_setfield(L, -2, "size"); - lua_rawseti(L,-2,cc); + /* update_terminal; */ + vf_z = atsize; + vf_replace_z(); + /* @;@/ */ vf_byte(cmd); - } - lua_setfield(L,-2,"characters"); + lua_newtable(L); + + i = 1; + while ((cmd >= fnt_def1) && (cmd <= fnt_def1 + 3)) { + + lua_newtable(L); + vf_read_u((cmd - fnt_def1 + 1), vf_nf); + vf_nf++; + /* checksum */ + vf_byte(cs.b0); + vf_byte(cs.b1); + vf_byte(cs.b2); + vf_byte(cs.b3); + + vf_read(4, k); + fs = sqxfw(k, atsize); + lua_pushstring(L, "size"); + lua_pushnumber(L, fs); + lua_rawset(L, -3); + + vf_read(4, k); + ds = k / 16; /* dsize, not used */ + + vf_byte(tmp_b0); + vf_byte(tmp_b1); + while (tmp_b0 > 0) { + tmp_b0--; + vf_byte(k); + } /* skip the font path */ + + s = xmalloc(tmp_b1 + 1); + k = 0; + while (tmp_b1-- > 0) + vf_byte(s[k++]); + s[k] = 0; + lua_pushstring(L, "name"); + lua_pushstring(L, xstrdup(s)); + free(s); + lua_rawset(L, -3); + + lua_rawseti(L, -2, vf_nf); + i++; + vf_byte(cmd); + } - if (cmd != post) - lua_bad_vf("POST command expected"); - xfree(vf_buffer); - return 1; -} + if (i > 1) { + lua_setfield(L, -2, "fonts"); + } else { + lua_pop(L, 1); + } + lua_newtable(L); /* 'characters' */ + while (cmd <= long_char) { + /* @;@/ */ + if (cmd == long_char) { + vf_read_u(4, packet_length); + vf_read_u(4, cc); + vf_read(4, tfm_width); + } else { + packet_length = cmd; + vf_byte(cc); + vf_read(3, tfm_width); + } + if (packet_length < 0) + lua_bad_vf("negative packet length"); + + lua_newtable(L); /* for this character */ + + lua_pushnumber(L, tfm_width); + lua_setfield(L, -2, "width"); + + lua_newtable(L); /* for 'commands' */ + + k = 1; + vf_nf = 0; + w = 0; + x = 0; + y = 0; + z = 0; + while (packet_length > 0) { + vf_byte(cmd); + decr(packet_length); + + if ((cmd >= set_char_0) && (cmd < set1)) { + if (vf_nf == 0) { + vf_nf = 1; + make_command1("font", vf_nf, k); + } + make_command1("char", cmd, k); + + } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || + ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { + if (cmd >= fnt1) { + vf_read_u((cmd - fnt1 + 1), vf_nf); + vf_nf++; + packet_length -= (cmd - fnt1 + 1); + } else { + vf_nf = cmd - fnt_num_0 + 1; + } + make_command1("font", vf_nf, k); + } else { + switch (cmd) { + case set_rule: + vf_read(4, h); + vf_read(4, v); + make_command2("rule", sqxfw(h, atsize), sqxfw(v, atsize), + k); + packet_length -= 8; + break; + case put_rule: + vf_read(4, h); + vf_read(4, v); + make_command0("push", k); + make_command2("rule", sqxfw(h, atsize), sqxfw(v, atsize), + k); + make_command0("pop", k); + packet_length -= 8; + break; + case set1: + case set2: + case set3: + case set4: + if (vf_nf == 0) { + vf_nf = 1; + make_command1("font", vf_nf, k); + } + vf_read_u((cmd - set1 + 1), i); + make_command1("char", i, k); + packet_length -= (cmd - set1 + 1); + break; + case put1: + case put2: + case put3: + case put4: + if (vf_nf == 0) { + vf_nf = 1; + make_command1("font", vf_nf, k); + } + vf_read_u((cmd - put1 + 1), i); + make_command0("push", k); + make_command1("char", i, k); + make_command0("pop", k); + packet_length -= (cmd - put1 + 1); + break; + case right1: + case right2: + case right3: + case right4: + vf_read((cmd - right1 + 1), i); + make_command1("right", sqxfw(i, atsize), k); + packet_length -= (cmd - right1 + 1); + break; + case w1: + case w2: + case w3: + case w4: + vf_read((cmd - w1 + 1), w); + make_command1("right", sqxfw(w, atsize), k); + packet_length -= (cmd - w1 + 1); + break; + case x1: + case x2: + case x3: + case x4: + vf_read((cmd - x1 + 1), x); + make_command1("right", sqxfw(x, atsize), k); + packet_length -= (cmd - x1 + 1); + break; + case down1: + case down2: + case down3: + case down4: + vf_read((cmd - down1 + 1), i); + make_command1("down", sqxfw(i, atsize), k); + packet_length -= (cmd - down1 + 1); + break; + case y1: + case y2: + case y3: + case y4: + vf_read((cmd - y1 + 1), y); + make_command1("down", sqxfw(y, atsize), k); + packet_length -= (cmd - y1 + 1); + break; + case z1: + case z2: + case z3: + case z4: + vf_read((cmd - z1 + 1), z); + make_command1("down", sqxfw(z, atsize), k); + packet_length -= (cmd - z1 + 1); + break; + case xxx1: + case xxx2: + case xxx3: + case xxx4: + vf_read_u((cmd - xxx1 + 1), cmd_length); + packet_length -= (cmd - xxx1 + 1); + if (cmd_length <= 0) + lua_bad_vf("special of negative length"); + packet_length -= cmd_length; + + s = xmalloc(cmd_length + 1); + i = 0; + while (cmd_length > 0) { + cmd_length--; + vf_byte(s[i]); + i++; + } + s[i] = 0; + make_commands("special", strdup(s), i, k); + free(s); + break; + case w0: + make_command1("right", sqxfw(w, atsize), k); + break; + case x0: + make_command1("right", sqxfw(x, atsize), k); + break; + case y0: + make_command1("down", sqxfw(y, atsize), k); + break; + case z0: + make_command1("down", sqxfw(z, atsize), k); + break; + case nop: + break; + case push: + if (stack_level == vf_stack_size) { + overflow_string("virtual font stack size", + vf_stack_size); + } else { + vf_stack[stack_level].stack_w = w; + vf_stack[stack_level].stack_x = x; + vf_stack[stack_level].stack_y = y; + vf_stack[stack_level].stack_z = z; + incr(stack_level); + make_command0("push", k); + } + break; + case pop: + if (stack_level == 0) { + lua_bad_vf("more POPs than PUSHs in character"); + } else { + decr(stack_level); + w = vf_stack[stack_level].stack_w; + x = vf_stack[stack_level].stack_x; + y = vf_stack[stack_level].stack_y; + z = vf_stack[stack_level].stack_z; + make_command0("pop", k); + } + break; + default: + lua_bad_vf("improver DVI command"); + } + } + } + /* signal end of packet */ + lua_setfield(L, -2, "commands"); + + if (stack_level != 0) + lua_bad_vf("more PUSHs than POPs in character packet"); + if (packet_length != 0) + lua_bad_vf("invalid packet length or DVI command in packet"); + + lua_rawseti(L, -2, cc); + + vf_byte(cmd); + } + lua_setfield(L, -2, "characters"); -extern void replace_packet_fonts(internal_font_number f, integer *old_fontid, integer *new_fontid, int count) ; -extern integer *packet_local_fonts(internal_font_number f, integer *num); -extern internal_font_number auto_expand_font (internal_font_number f, integer e) ; + if (cmd != post) + lua_bad_vf("POST command expected"); + xfree(vf_buffer); + return 1; +} /* This function is called from |do_vf|, and fixes up the virtual data inside an auto-expanded virtual font */ -boolean -auto_expand_vf(internal_font_number f) { - - internal_font_number bf; - integer e, k; - integer *vf_old_fonts, *vf_new_fonts; - integer num = 0; - - if ((! pdf_font_auto_expand(f)) || (pdf_font_blink(f) == null_font)) - return false ; /* not an auto-expanded font */ - bf = pdf_font_blink(f); - - if (font_type(bf) != virtual_font_type) - return false; /* not a virtual font */ - - e = pdf_font_expand_ratio(f); - - vf_old_fonts = packet_local_fonts(bf,&num); - if (num>0) { - vf_new_fonts = xmalloc(num*sizeof(integer)); - for (k=0;k 0) { + vf_new_fonts = xmalloc(num * sizeof(integer)); + for (k = 0; k < num; k++) { + vf_new_fonts[k] = auto_expand_font(vf_old_fonts[k], e); + copy_expand_params(vf_new_fonts[k], vf_old_fonts[k], e); + } + replace_packet_fonts(f, vf_old_fonts, vf_new_fonts, num); + xfree(vf_new_fonts); + xfree(vf_old_fonts); } - replace_packet_fonts(f,vf_old_fonts,vf_new_fonts,num); - xfree(vf_new_fonts); - xfree(vf_old_fonts); - } - set_font_type(f,virtual_font_type); - return true; + set_font_type(f, virtual_font_type); + return true; } /* this function is not always safe, because it needs makecstring() */ -str_number -expand_font_name (internal_font_number f, integer e) { - int old_setting; - old_setting=selector; - selector=new_string; - print_string(font_name(f)); - if (e > 0) { - print_char('+'); - } - print_int(e); - selector=old_setting; - return make_string(); +str_number expand_font_name(internal_font_number f, integer e) +{ + int old_setting; + old_setting = selector; + selector = new_string; + print_string(font_name(f)); + if (e > 0) { + print_char('+'); + } + print_int(e); + selector = old_setting; + return make_string(); } -internal_font_number -auto_expand_font (internal_font_number f, integer e) { - internal_font_number k; - kerninfo *krn; - charinfo *co, *ci; - char *fn; - integer i; - scaled w; - k = copy_font(f); - i = strlen(font_name(f))+12; - fn = xmalloc(i); - snprintf(fn,i,"%s%s%d",font_name(f),(e>0 ? "+" : ""), (int)e); - set_font_name(k,fn); - for (i = font_bc(k);i<=font_ec(k);i++) { - if (char_exists(k,i)) { - co = get_charinfo(k,i); - w = round_xn_over_d(char_width(f,i), 1000 + e, 1000); - set_charinfo_width (co, w); - w = round_xn_over_d(char_italic(f,i), 1000 + e, 1000); - set_charinfo_italic(co, w); - krn = get_charinfo_kerns(co); - if (krn != NULL) { - while (!kern_end((*krn))) { - kern_kern(*krn) = round_xn_over_d(kern_kern(*krn), 1000 + e, 1000); - krn++; - } - } +internal_font_number auto_expand_font(internal_font_number f, integer e) +{ + internal_font_number k; + kerninfo *krn; + charinfo *co; + char *fn; + integer i; + scaled w; + k = copy_font(f); + i = strlen(font_name(f)) + 12; + fn = xmalloc(i); + snprintf(fn, i, "%s%s%d", font_name(f), (e > 0 ? "+" : ""), (int) e); + set_font_name(k, fn); + for (i = font_bc(k); i <= font_ec(k); i++) { + if (char_exists(k, i)) { + co = get_charinfo(k, i); + w = round_xn_over_d(char_width(f, i), 1000 + e, 1000); + set_charinfo_width(co, w); + w = round_xn_over_d(char_italic(f, i), 1000 + e, 1000); + set_charinfo_italic(co, w); + krn = get_charinfo_kerns(co); + if (krn != NULL) { + while (!kern_end((*krn))) { + kern_kern(*krn) = + round_xn_over_d(kern_kern(*krn), 1000 + e, 1000); + krn++; + } + } + } } - } - return k; + return k; } -void -vf_expand_local_fonts(internal_font_number f) { - internal_font_number lf; - integer k, num; - integer *vf_old_fonts; - pdfassert(font_type(f) == virtual_font_type); - num = 0; - vf_old_fonts = packet_local_fonts(f,&num); - if (num>0) { - for (k = 0;k 0) { + for (k = 0; k < num; k++) { + lf = vf_old_fonts[k]; + set_expand_params(lf, pdf_font_auto_expand(f), + pdf_font_expand_ratio(pdf_font_stretch(f)), + -pdf_font_expand_ratio(pdf_font_shrink(f)), + pdf_font_step(f), pdf_font_expand_ratio(f)); + if (font_type(lf) == virtual_font_type) + vf_expand_local_fonts(lf); + } + xfree(vf_old_fonts); } - xfree(vf_old_fonts); - } } -internal_font_number -letter_space_font (halfword u, internal_font_number f, integer e) { - internal_font_number k; - scaled w, r; +internal_font_number +letter_space_font(halfword u, internal_font_number f, integer e) +{ + internal_font_number k; + scaled w, r; - char *new_font_name; - integer vf_z; - integer vf_alpha; - integer vf_beta; - memory_word tmp_w; /* accumulator */ + char *new_font_name; + integer vf_z; + integer vf_alpha; + integer vf_beta; + memory_word tmp_w; /* accumulator */ - /* read a new font and expand the character widths */ - k = read_font_info(u, tex_font_name(f), get_nullstr(), font_size(f), font_natural_dir(f)); - set_no_ligatures(k); /* disable ligatures for letter-spaced fonts */ + /* read a new font and expand the character widths */ + k = read_font_info(u, tex_font_name(f), font_size(f), font_natural_dir(f)); + set_no_ligatures(k); /* disable ligatures for letter-spaced fonts */ /* for (i = 0;i <= font_widths(k);i++) { set_font_width(k,i,font_width(f,i)+round_xn_over_d(quad(k), e, 1000)); } */ - /* append eg '+100ls' to font name */ - new_font_name = xmalloc(strlen(font_name(k)) + 8); /* |abs(e) <= 1000| */ - if (e > 0) { - sprintf(new_font_name,"%s+%ils",font_name(k),(int)e); - } else { - /* minus from %i */ - sprintf(new_font_name,"%s%ils",font_name(k),(int)e); - } - set_font_name(k, new_font_name); - - /* create the corresponding virtual font */ - set_font_type(k,virtual_font_type); - - vf_z = font_size(f); - vf_replace_z(); - w = round_xn_over_d(quad(f), e, 2000); - if (w > 0) { - tmp_b0 = 0; - } else { - tmp_b0 = 255; - w = vf_alpha + w; - } - r = w*vf_beta; - tmp_b1 = r / vf_z; - r = r % vf_z; - if (r == 0) { - tmp_b2 = 0; - } else { - r = r * 256; - tmp_b2 = r / vf_z; + /* append eg '+100ls' to font name */ + new_font_name = xmalloc(strlen(font_name(k)) + 8); /* |abs(e) <= 1000| */ + if (e > 0) { + sprintf(new_font_name, "%s+%ils", font_name(k), (int) e); + } else { + /* minus from %i */ + sprintf(new_font_name, "%s%ils", font_name(k), (int) e); + } + set_font_name(k, new_font_name); + + /* create the corresponding virtual font */ + set_font_type(k, virtual_font_type); + + vf_z = font_size(f); + vf_replace_z(); + w = round_xn_over_d(quad(f), e, 2000); + if (w > 0) { + tmp_b0 = 0; + } else { + tmp_b0 = 255; + w = vf_alpha + w; + } + r = w * vf_beta; + tmp_b1 = r / vf_z; r = r % vf_z; - } - if (r == 0) { - tmp_b3 = 0; - } else { - r = r * 256; - tmp_b3 = r / vf_z; - } - /* - vf_packet_base[k] = new_vf_packet(k); - - for (c=font_bc(k);c<=font_ec(k);c++) { - string_room(17); - append_fnt_set(f); - append_packet(right1 + 3); - append_packet(tmp_b0); - append_packet(tmp_b1); - append_packet(tmp_b2); - append_packet(tmp_b3); - - append_packet(set1); - append_packet(c); - - append_packet(right1 + 3); - append_packet(tmp_b0); - append_packet(tmp_b1); - append_packet(tmp_b2); - append_packet(tmp_b3); - s = make_string(); - store_packet(k, c, s); - flush_str(s); - } -*/ - return k; + if (r == 0) { + tmp_b2 = 0; + } else { + r = r * 256; + tmp_b2 = r / vf_z; + r = r % vf_z; + } + if (r == 0) { + tmp_b3 = 0; + } else { + r = r * 256; + tmp_b3 = r / vf_z; + } + /* + vf_packet_base[k] = new_vf_packet(k); + + for (c=font_bc(k);c<=font_ec(k);c++) { + string_room(17); + append_fnt_set(f); + append_packet(right1 + 3); + append_packet(tmp_b0); + append_packet(tmp_b1); + append_packet(tmp_b2); + append_packet(tmp_b3); + + append_packet(set1); + append_packet(c); + + append_packet(right1 + 3); + append_packet(tmp_b0); + append_packet(tmp_b1); + append_packet(tmp_b2); + append_packet(tmp_b3); + s = make_string(); + store_packet(k, c, s); + flush_str(s); + } + */ + return k; } +/* the fontname has [+-]\d+ls at the end */ + +boolean is_letterspaced_font(internal_font_number f) +{ + char *i, *j; + if (font_type(f) != virtual_font_type) + return false; + j = font_name(f); + i = j + strlen(j); + if ((*(i - 1) != 'l') || (*i != 's')) + return false; + i = i - 2; + while (i >= j) { + if ((*i < '0') || (*i > '9')) + break; + i--; + } + if (i < j) + return false; + if ((*i != '+') && (*i != '-')) + return false; + return true; +} +/* TODO */ + +internal_font_number copy_font_info(internal_font_number f) +{ + return copy_font(f); +} diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.c b/Build/source/texk/web2c/luatexdir/font/writecff.c index 69c35c6950e..274c4ad1567 100644 --- a/Build/source/texk/web2c/luatexdir/font/writecff.c +++ b/Build/source/texk/web2c/luatexdir/font/writecff.c @@ -1,29 +1,29 @@ -/* -Copyright (c) 2007 Taco Hoekwater, taco@luatex.org - -This file is part of luaTeX. +/* writecff.c + + Copyright 2006-2008 Taco Hoekwater -luaTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -luaTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with luaTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writecff.c 1021 2008-02-14 10:24:34Z taco $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" #include "writecff.h" +static const char _svn_version[] = + "$Id: writecff.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writecff.c $"; + #define get_offset(s,n) get_unsigned(s, (n)) #define get_card8(a) a->stream[a->offset++] #define get_card16(a) get_unsigned(a,2) @@ -37,12 +37,12 @@ $Id: writecff.c 1021 2008-02-14 10:24:34Z taco $ static char work_buffer[WORK_BUFFER_SIZE]; -static unsigned long get_unsigned (cff_font *cff, int n) +static unsigned long get_unsigned(cff_font * cff, int n) { - unsigned long v = 0; - while (n-- > 0) - v = v*256 + get_card8(cff); - return v; + unsigned long v = 0; + while (n-- > 0) + v = v * 256 + get_card8(cff); + return v; } #define CFF_ERROR pdftex_fail @@ -50,421 +50,454 @@ static unsigned long get_unsigned (cff_font *cff, int n) const char *const cff_stdstr[CFF_STDSTR_MAX] = { - ".notdef", "space", "exclam", "quotedbl", "numbersign", - "dollar", "percent", "ampersand", "quoteright", "parenleft", - "parenright", "asterisk", "plus", "comma", "hyphen", - "period", "slash", "zero", "one", "two", - "three", "four", "five", "six", "seven", - "eight", "nine", "colon", "semicolon", "less", - "equal", "greater", "question", "at", "A", - "B", "C", "D", "E", "F", - "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", - "Q", "R", "S", "T", "U", - "V", "W", "X", "Y", "Z", - "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", - "quoteleft", "a", "b", "c", "d", - "e", "f", "g", "h", "i", - "j", "k", "l", "m", "n", - "o", "p", "q", "r", "s", - "t", "u", "v", "w", "x", - "y", "z", "braceleft", "bar", "braceright", - "asciitilde", "exclamdown", "cent", "sterling", "fraction", - "yen", "florin", "section", "currency", "quotesingle", - "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", - "fl", "endash", "dagger", "daggerdbl", "periodcentered", - "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", - "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", - "acute", "circumflex", "tilde", "macron", "breve", - "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", - "ogonek", "caron", "emdash", "AE", "ordfeminine", - "Lslash", "Oslash", "OE", "ordmasculine", "ae", - "dotlessi", "lslash", "oslash", "oe", "germandbls", - "onesuperior", "logicalnot", "mu", "trademark", "Eth", - "onehalf", "plusminus", "Thorn", "onequarter", "divide", - "brokenbar", "degree", "thorn", "threequarters", "twosuperior", - "registered", "minus", "eth", "multiply", "threesuperior", - "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", - "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", - "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", - "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", - "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", - "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", - "aacute", "acircumflex", "adieresis", "agrave", "aring", - "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", - "egrave", "iacute", "icircumflex", "idieresis", "igrave", - "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", - "otilde", "scaron", "uacute", "ucircumflex", "udieresis", - "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", - "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", - "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle", - "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", - "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", - "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", - "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", - "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", - "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", - "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", - "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", - "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", - "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", - "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", - "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", - "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", - "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", - "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", - "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", - "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", - "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", - "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", - "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", - "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", - "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", - "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", - "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", - "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", - "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", - "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", - "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", - "001.000", "001.001", "001.002", "001.003", - "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" + ".notdef", "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quoteright", "parenleft", + "parenright", "asterisk", "plus", "comma", "hyphen", + "period", "slash", "zero", "one", "two", + "three", "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", "less", + "equal", "greater", "question", "at", "A", + "B", "C", "D", "E", "F", + "G", "H", "I", "J", "K", + "L", "M", "N", "O", "P", + "Q", "R", "S", "T", "U", + "V", "W", "X", "Y", "Z", + "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", + "quoteleft", "a", "b", "c", "d", + "e", "f", "g", "h", "i", + "j", "k", "l", "m", "n", + "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", + "y", "z", "braceleft", "bar", "braceright", + "asciitilde", "exclamdown", "cent", "sterling", "fraction", + "yen", "florin", "section", "currency", "quotesingle", + "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", + "fl", "endash", "dagger", "daggerdbl", "periodcentered", + "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", + "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", + "acute", "circumflex", "tilde", "macron", "breve", + "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", + "ogonek", "caron", "emdash", "AE", "ordfeminine", + "Lslash", "Oslash", "OE", "ordmasculine", "ae", + "dotlessi", "lslash", "oslash", "oe", "germandbls", + "onesuperior", "logicalnot", "mu", "trademark", "Eth", + "onehalf", "plusminus", "Thorn", "onequarter", "divide", + "brokenbar", "degree", "thorn", "threequarters", "twosuperior", + "registered", "minus", "eth", "multiply", "threesuperior", + "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", + "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", + "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", + "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", + "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", + "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", + "aacute", "acircumflex", "adieresis", "agrave", "aring", + "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", + "egrave", "iacute", "icircumflex", "idieresis", "igrave", + "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", + "otilde", "scaron", "uacute", "ucircumflex", "udieresis", + "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", + "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", + "Acutesmall", + "parenleftsuperior", "parenrightsuperior", "twodotenleader", + "onedotenleader", "zerooldstyle", + "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", + "commasuperior", + "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", + "bsuperior", + "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", + "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", + "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", + "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", + "Asmall", + "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", + "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", + "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", + "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", + "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", + "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", + "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", + "Dieresissmall", + "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", + "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", + "questiondownsmall", + "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", + "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", + "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", + "oneinferior", + "twoinferior", "threeinferior", "fourinferior", "fiveinferior", + "sixinferior", + "seveninferior", "eightinferior", "nineinferior", "centinferior", + "dollarinferior", + "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", + "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", + "Igravesmall", + "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", + "Ntildesmall", + "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", + "Odieresissmall", + "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", + "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", + "001.000", "001.001", "001.002", "001.003", + "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" }; /* Only read header part but not body */ -cff_index * -cff_get_index_header (cff_font *cff) +cff_index *cff_get_index_header(cff_font * cff) { - cff_index *idx; - card16 i, count; + cff_index *idx; + card16 i, count; - idx = xcalloc(1, sizeof(cff_index)); + idx = xcalloc(1, sizeof(cff_index)); - idx->count = count = get_card16(cff); - if (count > 0) { - idx->offsize = get_card8(cff); - if (idx->offsize < 1 || idx->offsize > 4) - CFF_ERROR("invalid offsize data"); + idx->count = count = get_card16(cff); + if (count > 0) { + idx->offsize = get_card8(cff); + if (idx->offsize < 1 || idx->offsize > 4) + CFF_ERROR("invalid offsize data"); - idx->offset = xcalloc(count+1, sizeof(l_offset)); - for (i=0;ioffset)[i] = get_offset(cff, idx->offsize); - } + idx->offset = xcalloc(count + 1, sizeof(l_offset)); + for (i = 0; i < count + 1; i++) { + (idx->offset)[i] = get_offset(cff, idx->offsize); + } - if (idx->offset[0] != 1) - CFF_ERROR("cff_get_index(): invalid index data"); + if (idx->offset[0] != 1) + CFF_ERROR("cff_get_index(): invalid index data"); - idx->data = NULL; - } else { - idx->offsize = 0; - idx->offset = NULL; - idx->data = NULL; - } + idx->data = NULL; + } else { + idx->offsize = 0; + idx->offset = NULL; + idx->data = NULL; + } - return idx; + return idx; } -cff_index * -cff_get_index (cff_font *cff) +cff_index *cff_get_index(cff_font * cff) { - cff_index *idx; - card16 i, count; - long length; + cff_index *idx; + card16 i, count; + long length; - idx = xcalloc(1,sizeof(cff_index)); + idx = xcalloc(1, sizeof(cff_index)); - idx->count = count = get_card16(cff); - if (count > 0) { - idx->offsize = get_card8(cff); - if (idx->offsize < 1 || idx->offsize > 4) - CFF_ERROR("invalid offsize data"); + idx->count = count = get_card16(cff); + if (count > 0) { + idx->offsize = get_card8(cff); + if (idx->offsize < 1 || idx->offsize > 4) + CFF_ERROR("invalid offsize data"); - idx->offset = xcalloc((count + 1),sizeof(l_offset)); - for (i = 0 ; i < count + 1; i++) { - idx->offset[i] = get_offset(cff, idx->offsize); - } + idx->offset = xcalloc((count + 1), sizeof(l_offset)); + for (i = 0; i < count + 1; i++) { + idx->offset[i] = get_offset(cff, idx->offsize); + } - if (idx->offset[0] != 1) - CFF_ERROR("Invalid CFF Index offset data"); + if (idx->offset[0] != 1) + CFF_ERROR("Invalid CFF Index offset data"); - length = idx->offset[count] - idx->offset[0]; + length = idx->offset[count] - idx->offset[0]; - idx->data = xcalloc(length,sizeof(card8)); - memcpy(idx->data,&cff->stream[cff->offset],length); - cff->offset += length; + idx->data = xcalloc(length, sizeof(card8)); + memcpy(idx->data, &cff->stream[cff->offset], length); + cff->offset += length; - } else { - idx->offsize = 0; - idx->offset = NULL; - idx->data = NULL; - } - return idx; + } else { + idx->offsize = 0; + idx->offset = NULL; + idx->data = NULL; + } + return idx; } -long -cff_pack_index (cff_index *idx, card8 *dest, long destlen) +long cff_pack_index(cff_index * idx, card8 * dest, long destlen) { - long len = 0; - unsigned long datalen; - card16 i; + long len = 0; + unsigned long datalen; + card16 i; - if (idx->count < 1) { - if (destlen < 2) - CFF_ERROR("Not enough space available..."); - memset(dest, 0, 2); - return 2; - } + if (idx->count < 1) { + if (destlen < 2) + CFF_ERROR("Not enough space available..."); + memset(dest, 0, 2); + return 2; + } - len = cff_index_size(idx); - datalen = idx->offset[idx->count] - 1; + len = cff_index_size(idx); + datalen = idx->offset[idx->count] - 1; - if (destlen < len) - CFF_ERROR("Not enough space available..."); + if (destlen < len) + CFF_ERROR("Not enough space available..."); - *(dest++) = (idx->count >> 8) & 0xff; - *(dest++) = idx->count & 0xff; + *(dest++) = (idx->count >> 8) & 0xff; + *(dest++) = idx->count & 0xff; - if (datalen < 0xffUL) { - idx->offsize = 1; - *(dest++) = 1; - for (i = 0; i <= idx->count; i++) { - *(dest++) = (card8) (idx->offset[i] & 0xff); - } - } else if (datalen < 0xffffUL) { - idx->offsize = 2; - *(dest++) = 2; - for (i = 0; i <= idx->count; i++) { - *(dest++) = (card8) ((idx->offset[i] >> 8) & 0xff); - *(dest++) = (card8) ( idx->offset[i] & 0xff); - } - } else if (datalen < 0xffffffUL) { - idx->offsize = 3; - *(dest++) = 3; - for (i = 0; i <= idx->count; i++) { - *(dest++) = (card8)((idx->offset[i] >> 16) & 0xff); - *(dest++) = (card8)((idx->offset[i] >> 8) & 0xff); - *(dest++) = (card8)(idx->offset[i] & 0xff); - } - } else { - idx->offsize = 4; - *(dest++) = 4; - for (i = 0; i <= idx->count; i++) { - *(dest++) = (card8)((idx->offset[i] >> 24) & 0xff); - *(dest++) = (card8)((idx->offset[i] >> 16) & 0xff); - *(dest++) = (card8)((idx->offset[i] >> 8) & 0xff); - *(dest++) = (card8)(idx->offset[i] & 0xff); + if (datalen < 0xffUL) { + idx->offsize = 1; + *(dest++) = 1; + for (i = 0; i <= idx->count; i++) { + *(dest++) = (card8) (idx->offset[i] & 0xff); + } + } else if (datalen < 0xffffUL) { + idx->offsize = 2; + *(dest++) = 2; + for (i = 0; i <= idx->count; i++) { + *(dest++) = (card8) ((idx->offset[i] >> 8) & 0xff); + *(dest++) = (card8) (idx->offset[i] & 0xff); + } + } else if (datalen < 0xffffffUL) { + idx->offsize = 3; + *(dest++) = 3; + for (i = 0; i <= idx->count; i++) { + *(dest++) = (card8) ((idx->offset[i] >> 16) & 0xff); + *(dest++) = (card8) ((idx->offset[i] >> 8) & 0xff); + *(dest++) = (card8) (idx->offset[i] & 0xff); + } + } else { + idx->offsize = 4; + *(dest++) = 4; + for (i = 0; i <= idx->count; i++) { + *(dest++) = (card8) ((idx->offset[i] >> 24) & 0xff); + *(dest++) = (card8) ((idx->offset[i] >> 16) & 0xff); + *(dest++) = (card8) ((idx->offset[i] >> 8) & 0xff); + *(dest++) = (card8) (idx->offset[i] & 0xff); + } } - } - memmove(dest, idx->data, idx->offset[idx->count] - 1); + memmove(dest, idx->data, idx->offset[idx->count] - 1); - return len; + return len; } -long -cff_index_size (cff_index *idx) +long cff_index_size(cff_index * idx) { - if (idx->count > 0) { - l_offset datalen; - - datalen = idx->offset[idx->count] - 1; - if (datalen < 0xffUL) { - idx->offsize = 1; - } else if (datalen < 0xffffUL) { - idx->offsize = 2; - } else if (datalen < 0xffffffUL) { - idx->offsize = 3; + if (idx->count > 0) { + l_offset datalen; + + datalen = idx->offset[idx->count] - 1; + if (datalen < 0xffUL) { + idx->offsize = 1; + } else if (datalen < 0xffffUL) { + idx->offsize = 2; + } else if (datalen < 0xffffffUL) { + idx->offsize = 3; + } else { + idx->offsize = 4; + } + return (3 + (idx->offsize) * (idx->count + 1) + datalen); } else { - idx->offsize = 4; + return 2; } - return (3 + (idx->offsize)*(idx->count + 1) + datalen); - } else { - return 2; - } } -cff_index *cff_new_index (card16 count) +cff_index *cff_new_index(card16 count) { - cff_index *idx; + cff_index *idx; - idx = xcalloc(1, sizeof(cff_index)); - idx->count = count; - idx->offsize = 0; + idx = xcalloc(1, sizeof(cff_index)); + idx->count = count; + idx->offsize = 0; - if (count > 0) { - idx->offset = xcalloc(count + 1, sizeof(l_offset)); - (idx->offset)[0] = 1; - } else { - idx->offset = NULL; - } - idx->data = NULL; + if (count > 0) { + idx->offset = xcalloc(count + 1, sizeof(l_offset)); + (idx->offset)[0] = 1; + } else { + idx->offset = NULL; + } + idx->data = NULL; - return idx; + return idx; } -void cff_release_index (cff_index *idx) +void cff_release_index(cff_index * idx) { - if (idx) { - xfree(idx->data); - xfree(idx->offset); - xfree(idx); - } + if (idx) { + xfree(idx->data); + xfree(idx->offset); + xfree(idx); + } } -void cff_release_dict (cff_dict *dict) +void cff_release_dict(cff_dict * dict) { - if (dict) { - if (dict->entries) { - int i; - for (i=0;icount;i++) { - xfree((dict->entries)[i].values); - } - xfree(dict->entries); - } - xfree(dict); - } + if (dict) { + if (dict->entries) { + int i; + for (i = 0; i < dict->count; i++) { + xfree((dict->entries)[i].values); + } + xfree(dict->entries); + } + xfree(dict); + } } -void cff_release_encoding (cff_encoding *encoding) +void cff_release_encoding(cff_encoding * encoding) { - if (encoding) { - switch (encoding->format & (~0x80)) { - case 0: xfree(encoding->data.codes); break; - case 1: xfree(encoding->data.range1); break; - default: CFF_ERROR("Unknown Encoding format."); + if (encoding) { + switch (encoding->format & (~0x80)) { + case 0: + xfree(encoding->data.codes); + break; + case 1: + xfree(encoding->data.range1); + break; + default: + CFF_ERROR("Unknown Encoding format."); + } + if (encoding->format & 0x80) + xfree(encoding->supp); + xfree(encoding); } - if (encoding->format & 0x80) - xfree(encoding->supp); - xfree(encoding); - } } -void -cff_release_charsets (cff_charsets *charset) +void cff_release_charsets(cff_charsets * charset) { - if (charset) { - switch (charset->format) { - case 0: xfree(charset->data.glyphs); break; - case 1: xfree(charset->data.range1); break; - case 2: xfree(charset->data.range2); break; - default: break; + if (charset) { + switch (charset->format) { + case 0: + xfree(charset->data.glyphs); + break; + case 1: + xfree(charset->data.range1); + break; + case 2: + xfree(charset->data.range2); + break; + default: + break; + } + xfree(charset); } - xfree(charset); - } } -void cff_release_fdselect (cff_fdselect *fdselect) +void cff_release_fdselect(cff_fdselect * fdselect) { - if (fdselect) { - if (fdselect->format == 0) { xfree(fdselect->data.fds); } - else if (fdselect->format == 3) { xfree(fdselect->data.ranges); } - xfree(fdselect); - } + if (fdselect) { + if (fdselect->format == 0) { + xfree(fdselect->data.fds); + } else if (fdselect->format == 3) { + xfree(fdselect->data.ranges); + } + xfree(fdselect); + } } -void -cff_close (cff_font *cff) +void cff_close(cff_font * cff) { - card16 i; - - if (cff) { - if (cff->fontname) xfree(cff->fontname); - if (cff->name) cff_release_index(cff->name); - if (cff->topdict) cff_release_dict(cff->topdict); - if (cff->string) cff_release_index(cff->string); - if (cff->gsubr) cff_release_index(cff->gsubr); - if (cff->encoding) cff_release_encoding(cff->encoding); - if (cff->charsets) cff_release_charsets(cff->charsets); - if (cff->fdselect) cff_release_fdselect(cff->fdselect); - if (cff->cstrings) cff_release_index(cff->cstrings); - if (cff->fdarray) { - for (i=0;inum_fds;i++) { - if (cff->fdarray[i]) cff_release_dict(cff->fdarray[i]); - } - xfree(cff->fdarray); - } - if (cff->private) { - for (i=0;inum_fds;i++) { - if (cff->private[i]) cff_release_dict(cff->private[i]); - } - xfree(cff->private); - } - if (cff->subrs) { - for (i=0;inum_fds;i++) { - if (cff->subrs[i]) cff_release_index(cff->subrs[i]); - } - xfree(cff->subrs); - } - if (cff->_string) - cff_release_index(cff->_string); - xfree(cff); - } + card16 i; + + if (cff) { + if (cff->fontname) + xfree(cff->fontname); + if (cff->name) + cff_release_index(cff->name); + if (cff->topdict) + cff_release_dict(cff->topdict); + if (cff->string) + cff_release_index(cff->string); + if (cff->gsubr) + cff_release_index(cff->gsubr); + if (cff->encoding) + cff_release_encoding(cff->encoding); + if (cff->charsets) + cff_release_charsets(cff->charsets); + if (cff->fdselect) + cff_release_fdselect(cff->fdselect); + if (cff->cstrings) + cff_release_index(cff->cstrings); + if (cff->fdarray) { + for (i = 0; i < cff->num_fds; i++) { + if (cff->fdarray[i]) + cff_release_dict(cff->fdarray[i]); + } + xfree(cff->fdarray); + } + if (cff->private) { + for (i = 0; i < cff->num_fds; i++) { + if (cff->private[i]) + cff_release_dict(cff->private[i]); + } + xfree(cff->private); + } + if (cff->subrs) { + for (i = 0; i < cff->num_fds; i++) { + if (cff->subrs[i]) + cff_release_index(cff->subrs[i]); + } + xfree(cff->subrs); + } + if (cff->_string) + cff_release_index(cff->_string); + xfree(cff); + } - return; + return; } -char * -cff_get_name (cff_font *cff) +char *cff_get_name(cff_font * cff) { - char *fontname; - l_offset len; - cff_index *idx; + char *fontname; + l_offset len; + cff_index *idx; - idx = cff->name; - len = idx->offset[cff->index + 1] - idx->offset[cff->index]; - fontname = xmalloc((len + 1)*sizeof(char)); - memcpy(fontname, idx->data + idx->offset[cff->index] - 1, len); - fontname[len] = '\0'; + idx = cff->name; + len = idx->offset[cff->index + 1] - idx->offset[cff->index]; + fontname = xmalloc((len + 1) * sizeof(char)); + memcpy(fontname, idx->data + idx->offset[cff->index] - 1, len); + fontname[len] = '\0'; - return fontname; + return fontname; } -long -cff_set_name (cff_font *cff, char *name) +long cff_set_name(cff_font * cff, char *name) { - cff_index *idx; + cff_index *idx; - if (strlen(name) > 127) - CFF_ERROR("FontName string length too large..."); + if (strlen(name) > 127) + CFF_ERROR("FontName string length too large..."); - if (cff->name) - cff_release_index(cff->name); + if (cff->name) + cff_release_index(cff->name); - cff->name = idx = xcalloc(1, sizeof(cff_index)); - idx->count = 1; - idx->offsize = 1; - idx->offset = xmalloc(2*sizeof(l_offset)); - (idx->offset)[0] = 1; - (idx->offset)[1] = strlen(name) + 1; - idx->data = xcalloc(strlen(name), sizeof(card8)); - memmove(idx->data, name, strlen(name)); /* no trailing '\0' */ + cff->name = idx = xcalloc(1, sizeof(cff_index)); + idx->count = 1; + idx->offsize = 1; + idx->offset = xmalloc(2 * sizeof(l_offset)); + (idx->offset)[0] = 1; + (idx->offset)[1] = strlen(name) + 1; + idx->data = xcalloc(strlen(name), sizeof(card8)); + memmove(idx->data, name, strlen(name)); /* no trailing '\0' */ - return 5 + strlen(name); + return 5 + strlen(name); } -long -cff_put_header (cff_font *cff, card8 *dest, long destlen) +long cff_put_header(cff_font * cff, card8 * dest, long destlen) { - if (destlen < 4) - CFF_ERROR("Not enough space available..."); - - *(dest++) = cff->header_major; - *(dest++) = cff->header_minor; - *(dest++) = 4; /* Additional data in between header and - * Name INDEX ignored. - */ - /* We will set all offset (0) to four-byte integer. */ - *(dest++) = 4; - cff->header_offsize = 4; - - return 4; + if (destlen < 4) + CFF_ERROR("Not enough space available..."); + + *(dest++) = cff->header_major; + *(dest++) = cff->header_minor; + *(dest++) = 4; /* Additional data in between header and + * Name INDEX ignored. + */ + /* We will set all offset (0) to four-byte integer. */ + *(dest++) = 4; + cff->header_offsize = 4; + + return 4; } #define CFF_PARSE_OK 0 @@ -475,15 +508,15 @@ cff_put_header (cff_font *cff, card8 *dest, long destlen) #define DICT_ENTRY_MAX 16 -cff_dict *cff_new_dict (void) +cff_dict *cff_new_dict(void) { - cff_dict *dict; + cff_dict *dict; - dict = xcalloc(1, sizeof(cff_dict)); - dict->max = DICT_ENTRY_MAX; - dict->count = 0; - dict->entries = xcalloc(dict->max, sizeof(cff_dict_entry)); - return dict; + dict = xcalloc(1, sizeof(cff_dict)); + dict->max = DICT_ENTRY_MAX; + dict->count = 0; + dict->entries = xcalloc(dict->max, sizeof(cff_dict_entry)); + return dict; } /* @@ -500,7 +533,7 @@ cff_dict *cff_new_dict (void) */ #define CFF_DICT_STACK_LIMIT 64 -static int stack_top = 0; +static int stack_top = 0; static double arg_stack[CFF_DICT_STACK_LIMIT]; /* @@ -513,231 +546,239 @@ static double arg_stack[CFF_DICT_STACK_LIMIT]; #define CFF_LAST_DICT_OP (CFF_LAST_DICT_OP1 + CFF_LAST_DICT_OP2) static struct { - const char *opname; - int argtype; + const char *opname; + int argtype; } dict_operator[CFF_LAST_DICT_OP] = { - {"version", CFF_TYPE_SID}, - {"Notice", CFF_TYPE_SID}, - {"FullName", CFF_TYPE_SID}, - {"FamilyName", CFF_TYPE_SID}, - {"Weight", CFF_TYPE_SID}, - {"FontBBox", CFF_TYPE_ARRAY}, - {"BlueValues", CFF_TYPE_DELTA}, - {"OtherBlues", CFF_TYPE_DELTA}, - {"FamilyBlues", CFF_TYPE_DELTA}, - {"FamilyOtherBlues", CFF_TYPE_DELTA}, - {"StdHW", CFF_TYPE_NUMBER}, - {"StdVW", CFF_TYPE_NUMBER}, - {NULL, -1}, /* first byte of two-byte operator */ - /* Top */ - {"UniqueID", CFF_TYPE_NUMBER}, - {"XUID", CFF_TYPE_ARRAY}, - {"charset", CFF_TYPE_OFFSET}, - {"Encoding", CFF_TYPE_OFFSET}, - {"CharStrings", CFF_TYPE_OFFSET}, - {"Private", CFF_TYPE_SZOFF}, /* two numbers (size and offset) */ - /* Private */ - {"Subrs", CFF_TYPE_OFFSET}, - {"defaultWidthX", CFF_TYPE_NUMBER}, - {"nominalWidthX", CFF_TYPE_NUMBER}, - /* Operator 2 */ - {"Copyright", CFF_TYPE_SID}, - {"IsFixedPitch", CFF_TYPE_BOOLEAN}, - {"ItalicAngle", CFF_TYPE_NUMBER}, - {"UnderlinePosition", CFF_TYPE_NUMBER}, - {"UnderlineThickness", CFF_TYPE_NUMBER}, - {"PaintType", CFF_TYPE_NUMBER}, - {"CharstringType", CFF_TYPE_NUMBER}, - {"FontMatrix", CFF_TYPE_ARRAY}, - {"StrokeWidth", CFF_TYPE_NUMBER}, - {"BlueScale", CFF_TYPE_NUMBER}, - {"BlueShift", CFF_TYPE_NUMBER}, - {"BlueFuzz", CFF_TYPE_NUMBER}, - {"StemSnapH", CFF_TYPE_DELTA}, - {"StemSnapV", CFF_TYPE_DELTA}, - {"ForceBold", CFF_TYPE_BOOLEAN}, - {NULL, -1}, - {NULL, -1}, - {"LanguageGroup", CFF_TYPE_NUMBER}, - {"ExpansionFactor", CFF_TYPE_NUMBER}, - {"InitialRandomSeed", CFF_TYPE_NUMBER}, - {"SyntheticBase", CFF_TYPE_NUMBER}, - {"PostScript", CFF_TYPE_SID}, - {"BaseFontName", CFF_TYPE_SID}, - {"BaseFontBlend", CFF_TYPE_DELTA}, /* MMaster ? */ - {NULL, -1}, - {NULL, -1}, - {NULL, -1}, - {NULL, -1}, - {NULL, -1}, - {NULL, -1}, - /* CID-Keyed font */ - {"ROS", CFF_TYPE_ROS}, /* SID SID number */ - {"CIDFontVersion", CFF_TYPE_NUMBER}, - {"CIDFontRevision", CFF_TYPE_NUMBER}, - {"CIDFontType", CFF_TYPE_NUMBER}, - {"CIDCount", CFF_TYPE_NUMBER}, - {"UIDBase", CFF_TYPE_NUMBER}, - {"FDArray", CFF_TYPE_OFFSET}, - {"FDSelect", CFF_TYPE_OFFSET}, - {"FontName", CFF_TYPE_SID}, -}; + { + "version", CFF_TYPE_SID}, { + "Notice", CFF_TYPE_SID}, { + "FullName", CFF_TYPE_SID}, { + "FamilyName", CFF_TYPE_SID}, { + "Weight", CFF_TYPE_SID}, { + "FontBBox", CFF_TYPE_ARRAY}, { + "BlueValues", CFF_TYPE_DELTA}, { + "OtherBlues", CFF_TYPE_DELTA}, { + "FamilyBlues", CFF_TYPE_DELTA}, { + "FamilyOtherBlues", CFF_TYPE_DELTA}, { + "StdHW", CFF_TYPE_NUMBER}, { + "StdVW", CFF_TYPE_NUMBER}, { + NULL, -1}, /* first byte of two-byte operator */ + /* Top */ + { + "UniqueID", CFF_TYPE_NUMBER}, { + "XUID", CFF_TYPE_ARRAY}, { + "charset", CFF_TYPE_OFFSET}, { + "Encoding", CFF_TYPE_OFFSET}, { + "CharStrings", CFF_TYPE_OFFSET}, { + "Private", CFF_TYPE_SZOFF}, /* two numbers (size and offset) */ + /* Private */ + { + "Subrs", CFF_TYPE_OFFSET}, { + "defaultWidthX", CFF_TYPE_NUMBER}, { + "nominalWidthX", CFF_TYPE_NUMBER}, + /* Operator 2 */ + { + "Copyright", CFF_TYPE_SID}, { + "IsFixedPitch", CFF_TYPE_BOOLEAN}, { + "ItalicAngle", CFF_TYPE_NUMBER}, { + "UnderlinePosition", CFF_TYPE_NUMBER}, { + "UnderlineThickness", CFF_TYPE_NUMBER}, { + "PaintType", CFF_TYPE_NUMBER}, { + "CharstringType", CFF_TYPE_NUMBER}, { + "FontMatrix", CFF_TYPE_ARRAY}, { + "StrokeWidth", CFF_TYPE_NUMBER}, { + "BlueScale", CFF_TYPE_NUMBER}, { + "BlueShift", CFF_TYPE_NUMBER}, { + "BlueFuzz", CFF_TYPE_NUMBER}, { + "StemSnapH", CFF_TYPE_DELTA}, { + "StemSnapV", CFF_TYPE_DELTA}, { + "ForceBold", CFF_TYPE_BOOLEAN}, { + NULL, -1}, { + NULL, -1}, { + "LanguageGroup", CFF_TYPE_NUMBER}, { + "ExpansionFactor", CFF_TYPE_NUMBER}, { + "InitialRandomSeed", CFF_TYPE_NUMBER}, { + "SyntheticBase", CFF_TYPE_NUMBER}, { + "PostScript", CFF_TYPE_SID}, { + "BaseFontName", CFF_TYPE_SID}, { + "BaseFontBlend", CFF_TYPE_DELTA}, /* MMaster ? */ + { + NULL, -1}, { + NULL, -1}, { + NULL, -1}, { + NULL, -1}, { + NULL, -1}, { + NULL, -1}, + /* CID-Keyed font */ + { + "ROS", CFF_TYPE_ROS}, /* SID SID number */ + { + "CIDFontVersion", CFF_TYPE_NUMBER}, { + "CIDFontRevision", CFF_TYPE_NUMBER}, { + "CIDFontType", CFF_TYPE_NUMBER}, { + "CIDCount", CFF_TYPE_NUMBER}, { + "UIDBase", CFF_TYPE_NUMBER}, { + "FDArray", CFF_TYPE_OFFSET}, { + "FDSelect", CFF_TYPE_OFFSET}, { +"FontName", CFF_TYPE_SID},}; /* Parse DICT data */ -static double get_integer (card8 **data, card8 *endptr, int *status) +static double get_integer(card8 ** data, card8 * endptr, int *status) { - long result = 0; - card8 b0, b1, b2; - - b0 = *(*data)++; - if (b0 == 28 && *data < endptr - 2) { /* shortint */ - b1 = *(*data)++; - b2 = *(*data)++; - result = b1*256+b2; - if (result > 0x7fffL) - result -= 0x10000L; - } else if (b0 == 29 && *data < endptr - 4) { /* longint */ - int i; - result = *(*data)++; - if (result > 0x7f) - result -= 0x100; - for (i=0;i<3;i++) { - result = result*256+(**data); - *data += 1; - } - } else if (b0 >= 32 && b0 <= 246) { /* int (1) */ - result = b0 - 139; - } else if (b0 >= 247 && b0 <= 250) { /* int (2) */ - b1 = *(*data)++; - result = (b0-247)*256+b1+108; - } else if (b0 >= 251 && b0 <= 254) { - b1 = *(*data)++; - result = -(b0-251)*256-b1-108; - } else { - *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; - } + long result = 0; + card8 b0, b1, b2; + + b0 = *(*data)++; + if (b0 == 28 && *data < endptr - 2) { /* shortint */ + b1 = *(*data)++; + b2 = *(*data)++; + result = b1 * 256 + b2; + if (result > 0x7fffL) + result -= 0x10000L; + } else if (b0 == 29 && *data < endptr - 4) { /* longint */ + int i; + result = *(*data)++; + if (result > 0x7f) + result -= 0x100; + for (i = 0; i < 3; i++) { + result = result * 256 + (**data); + *data += 1; + } + } else if (b0 >= 32 && b0 <= 246) { /* int (1) */ + result = b0 - 139; + } else if (b0 >= 247 && b0 <= 250) { /* int (2) */ + b1 = *(*data)++; + result = (b0 - 247) * 256 + b1 + 108; + } else if (b0 >= 251 && b0 <= 254) { + b1 = *(*data)++; + result = -(b0 - 251) * 256 - b1 - 108; + } else { + *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; + } - return (double) result; + return (double) result; } /* Simply uses strtod */ -static double get_real(card8 **data, card8 *endptr, int *status) +static double get_real(card8 ** data, card8 * endptr, int *status) { - double result = 0.0; - int nibble = 0, pos = 0; - int len = 0, fail = 0; - - if (**data != 30 || *data >= endptr -1) { - *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; - return 0.0; - } - - *data += 1; /* skip first byte (30) */ - - pos = 0; - while ((! fail) && len < WORK_BUFFER_SIZE - 2 && *data < endptr) { - /* get nibble */ - if (pos % 2) { - nibble = **data & 0x0f; - *data += 1; + double result = 0.0; + int nibble = 0, pos = 0; + int len = 0, fail = 0; + + if (**data != 30 || *data >= endptr - 1) { + *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; + return 0.0; + } + + *data += 1; /* skip first byte (30) */ + + pos = 0; + while ((!fail) && len < WORK_BUFFER_SIZE - 2 && *data < endptr) { + /* get nibble */ + if (pos % 2) { + nibble = **data & 0x0f; + *data += 1; + } else { + nibble = (**data >> 4) & 0x0f; + } + if (nibble >= 0x00 && nibble <= 0x09) { + work_buffer[len++] = nibble + '0'; + } else if (nibble == 0x0a) { /* . */ + work_buffer[len++] = '.'; + } else if (nibble == 0x0b || nibble == 0x0c) { /* E, E- */ + work_buffer[len++] = 'e'; + if (nibble == 0x0c) + work_buffer[len++] = '-'; + } else if (nibble == 0x0e) { /* `-' */ + work_buffer[len++] = '-'; + } else if (nibble == 0x0d) { /* skip */ + /* do nothing */ + } else if (nibble == 0x0f) { /* end */ + work_buffer[len++] = '\0'; + if (((pos % 2) == 0) && (**data != 0xff)) { + fail = 1; + } + break; + } else { /* invalid */ + fail = 1; + } + pos++; + } + + /* returned values */ + if (fail || nibble != 0x0f) { + *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; } else { - nibble = (**data >> 4) & 0x0f; - } - if (nibble >= 0x00 && nibble <= 0x09) { - work_buffer[len++] = nibble + '0'; - } else if (nibble == 0x0a) { /* . */ - work_buffer[len++] = '.'; - } else if (nibble == 0x0b || nibble == 0x0c) { /* E, E- */ - work_buffer[len++] = 'e'; - if (nibble == 0x0c) - work_buffer[len++] = '-'; - } else if (nibble == 0x0e) { /* `-' */ - work_buffer[len++] = '-'; - } else if (nibble == 0x0d) { /* skip */ - /* do nothing */ - } else if (nibble == 0x0f) { /* end */ - work_buffer[len++] = '\0'; - if (((pos % 2) == 0) && (**data != 0xff)) { - fail = 1; - } - break; - } else { /* invalid */ - fail = 1; - } - pos++; - } - - /* returned values */ - if (fail || nibble != 0x0f) { - *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; - } else { - char *s; - result = strtod(work_buffer, &s); - if (*s != 0 || errno == ERANGE) { - *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; + char *s; + result = strtod(work_buffer, &s); + if (*s != 0 || errno == ERANGE) { + *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; + } } - } - return result; + return result; } /* operators */ -static void add_dict (cff_dict *dict, - card8 **data, card8 *endptr, int *status) +static void add_dict(cff_dict * dict, + card8 ** data, card8 * endptr, int *status) { - int id, argtype; + int id, argtype; + + id = **data; + if (id == 0x0c) { + *data += 1; + if (*data >= endptr || + (id = **data + CFF_LAST_DICT_OP1) >= CFF_LAST_DICT_OP) { + *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; + return; + } + } else if (id >= CFF_LAST_DICT_OP1) { + *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; + return; + } + + argtype = dict_operator[id].argtype; + if (dict_operator[id].opname == NULL || argtype < 0) { + *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; + return; + } else if (stack_top < 1) { + *status = CFF_CFF_ERROR_STACK_UNDERFLOW; + return; + } + + if (dict->count >= dict->max) { + dict->max += DICT_ENTRY_MAX; + /* not zeroed! */ + dict->entries = + xrealloc(dict->entries, dict->max * sizeof(cff_dict_entry)); + } + + (dict->entries)[dict->count].id = id; + (dict->entries)[dict->count].key = (char *) dict_operator[id].opname; + if (argtype == CFF_TYPE_NUMBER || + argtype == CFF_TYPE_BOOLEAN || + argtype == CFF_TYPE_SID || argtype == CFF_TYPE_OFFSET) { + stack_top--; + (dict->entries)[dict->count].count = 1; + (dict->entries)[dict->count].values = xcalloc(1, sizeof(double)); + (dict->entries)[dict->count].values[0] = arg_stack[stack_top]; + } else { + (dict->entries)[dict->count].count = stack_top; + (dict->entries)[dict->count].values = + xcalloc(stack_top, sizeof(double)); + while (stack_top > 0) { + stack_top--; + (dict->entries)[dict->count].values[stack_top] = + arg_stack[stack_top]; + } + } - id = **data; - if (id == 0x0c) { + dict->count += 1; *data += 1; - if (*data >= endptr || - (id = **data + CFF_LAST_DICT_OP1) >= CFF_LAST_DICT_OP) { - *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; - return; - } - } else if (id >= CFF_LAST_DICT_OP1) { - *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; - return; - } - argtype = dict_operator[id].argtype; - if (dict_operator[id].opname == NULL || argtype < 0) { - *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; return; - } else if (stack_top < 1) { - *status = CFF_CFF_ERROR_STACK_UNDERFLOW; - return; - } - - if (dict->count >= dict->max) { - dict->max += DICT_ENTRY_MAX; - /* not zeroed! */ - dict->entries = xrealloc(dict->entries, dict->max*sizeof(cff_dict_entry)); - } - - (dict->entries)[dict->count].id = id; - (dict->entries)[dict->count].key = (char *) dict_operator[id].opname; - if (argtype == CFF_TYPE_NUMBER || - argtype == CFF_TYPE_BOOLEAN || - argtype == CFF_TYPE_SID || - argtype == CFF_TYPE_OFFSET) { - stack_top--; - (dict->entries)[dict->count].count = 1; - (dict->entries)[dict->count].values = xcalloc(1, sizeof(double)); - (dict->entries)[dict->count].values[0] = arg_stack[stack_top]; - } else { - (dict->entries)[dict->count].count = stack_top; - (dict->entries)[dict->count].values = xcalloc(stack_top, sizeof(double)); - while (stack_top > 0) { - stack_top--; - (dict->entries)[dict->count].values[stack_top] = arg_stack[stack_top]; - } - } - - dict->count += 1; - *data += 1; - - return; } /* @@ -745,370 +786,370 @@ static void add_dict (cff_dict *dict, * Private: two numbers, size and offset * ROS : three numbers, SID, SID, and a number */ -cff_dict *cff_dict_unpack (card8 *data, card8 *endptr) +cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) { - cff_dict *dict; - int status = CFF_PARSE_OK; - - stack_top = 0; - - dict = cff_new_dict(); - while (data < endptr && status == CFF_PARSE_OK) { - if (*data < 22) { /* operator */ - add_dict(dict, &data, endptr, &status); - } else if (*data == 30) { /* real - First byte of a sequence (variable) */ - if (stack_top < CFF_DICT_STACK_LIMIT) { - arg_stack[stack_top] = get_real(&data, endptr, &status); - stack_top++; - } else { - status = CFF_CFF_ERROR_STACK_OVERFLOW; - } - } else if (*data == 255 || (*data >= 22 && *data <= 27)) { /* reserved */ - data++; - } else { /* everything else are integer */ - if (stack_top < CFF_DICT_STACK_LIMIT) { - arg_stack[stack_top] = get_integer(&data, endptr, &status); - stack_top++; - } else { - status = CFF_CFF_ERROR_STACK_OVERFLOW; - } - } - } + cff_dict *dict; + int status = CFF_PARSE_OK; - if (status != CFF_PARSE_OK) { - pdftex_fail("Parsing CFF DICT failed. (error=%d)", status); - } else if (stack_top != 0) { - WARN("Garbage in CFF DICT data."); stack_top = 0; - } - return dict; + dict = cff_new_dict(); + while (data < endptr && status == CFF_PARSE_OK) { + if (*data < 22) { /* operator */ + add_dict(dict, &data, endptr, &status); + } else if (*data == 30) { /* real - First byte of a sequence (variable) */ + if (stack_top < CFF_DICT_STACK_LIMIT) { + arg_stack[stack_top] = get_real(&data, endptr, &status); + stack_top++; + } else { + status = CFF_CFF_ERROR_STACK_OVERFLOW; + } + } else if (*data == 255 || (*data >= 22 && *data <= 27)) { /* reserved */ + data++; + } else { /* everything else are integer */ + if (stack_top < CFF_DICT_STACK_LIMIT) { + arg_stack[stack_top] = get_integer(&data, endptr, &status); + stack_top++; + } else { + status = CFF_CFF_ERROR_STACK_OVERFLOW; + } + } + } + + if (status != CFF_PARSE_OK) { + pdftex_fail("Parsing CFF DICT failed. (error=%d)", status); + } else if (stack_top != 0) { + WARN("Garbage in CFF DICT data."); + stack_top = 0; + } + + return dict; } -int cff_dict_known (cff_dict *dict, const char *key) +int cff_dict_known(cff_dict * dict, const char *key) { - int i; + int i; - for (i = 0; i < dict->count; i++) { - if (key && strcmp(key, (dict->entries)[i].key) == 0 - && (dict->entries)[i].count > 0) - return 1; - } + for (i = 0; i < dict->count; i++) { + if (key && strcmp(key, (dict->entries)[i].key) == 0 + && (dict->entries)[i].count > 0) + return 1; + } - return 0; + return 0; } -double cff_dict_get (cff_dict *dict, const char *key, int idx) +double cff_dict_get(cff_dict * dict, const char *key, int idx) { - double value = 0.0; - int i; + double value = 0.0; + int i; - assert(key && dict); + assert(key && dict); - for (i = 0; i < dict->count; i++) { - if (strcmp(key, (dict->entries)[i].key) == 0) { - if ((dict->entries)[i].count > idx) - value = (dict->entries)[i].values[idx]; - else - pdftex_fail("Invalid index number."); - break; + for (i = 0; i < dict->count; i++) { + if (strcmp(key, (dict->entries)[i].key) == 0) { + if ((dict->entries)[i].count > idx) + value = (dict->entries)[i].values[idx]; + else + pdftex_fail("Invalid index number."); + break; + } } - } - if (i == dict->count) - pdftex_fail("DICT entry \"%s\" not found.", key); + if (i == dict->count) + pdftex_fail("DICT entry \"%s\" not found.", key); - return value; + return value; } -card8 cff_fdselect_lookup (cff_font *cff, card16 gid) +card8 cff_fdselect_lookup(cff_font * cff, card16 gid) { - card8 fd = 0xff; - cff_fdselect *fdsel; - - if (cff->fdselect == NULL) - CFF_ERROR("in cff_fdselect_lookup(): FDSelect not available"); - - fdsel = cff->fdselect; - - if (gid >= cff->num_glyphs) - CFF_ERROR("in cff_fdselect_lookup(): Invalid glyph index"); - - switch (fdsel->format) { - case 0: - fd = fdsel->data.fds[gid]; - break; - case 3: - { - if (gid == 0) { - fd = (fdsel->data).ranges[0].fd; - } else { - card16 i; - for (i=1;i<(fdsel->num_entries);i++) { - if (gid < (fdsel->data).ranges[i].first) - break; - } - fd = (fdsel->data).ranges[i-1].fd; - } - } - break; - default: - CFF_ERROR("in cff_fdselect_lookup(): Invalid FDSelect format"); - break; - } - - if (fd >= cff->num_fds) - CFF_ERROR("in cff_fdselect_lookup(): Invalid Font DICT index"); - - return fd; + card8 fd = 0xff; + cff_fdselect *fdsel; + + if (cff->fdselect == NULL) + CFF_ERROR("in cff_fdselect_lookup(): FDSelect not available"); + + fdsel = cff->fdselect; + + if (gid >= cff->num_glyphs) + CFF_ERROR("in cff_fdselect_lookup(): Invalid glyph index"); + + switch (fdsel->format) { + case 0: + fd = fdsel->data.fds[gid]; + break; + case 3: + { + if (gid == 0) { + fd = (fdsel->data).ranges[0].fd; + } else { + card16 i; + for (i = 1; i < (fdsel->num_entries); i++) { + if (gid < (fdsel->data).ranges[i].first) + break; + } + fd = (fdsel->data).ranges[i - 1].fd; + } + } + break; + default: + CFF_ERROR("in cff_fdselect_lookup(): Invalid FDSelect format"); + break; + } + + if (fd >= cff->num_fds) + CFF_ERROR("in cff_fdselect_lookup(): Invalid Font DICT index"); + + return fd; } -long cff_read_subrs (cff_font *cff) +long cff_read_subrs(cff_font * cff) { - long len = 0; - long offset; - int i; - - - if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdselect == NULL) { - cff_read_fdselect(cff); - } - - if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdarray == NULL) { - cff_read_fdarray(cff); - } + long len = 0; + long offset; + int i; - if (cff->private == NULL) - cff_read_private(cff); - if (cff->gsubr == NULL) { - cff->offset = cff->gsubr_offset; - cff->gsubr = cff_get_index(cff); - } - - cff->subrs = xcalloc(cff->num_fds, sizeof(cff_index *)); - if (cff->flag & FONTTYPE_CIDFONT) { - for (i=0;inum_fds;i++) { - if (cff->private[i] == NULL || - !cff_dict_known(cff->private[i], "Subrs")) { - (cff->subrs)[i] = NULL; - } else { - offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); - offset += (long) cff_dict_get(cff->private[i], "Subrs", 0); - cff->offset = offset; - (cff->subrs)[i] = cff_get_index(cff); - len += cff_index_size((cff->subrs)[i]); - } - } - } else { - if (cff->private[0] == NULL || - !cff_dict_known(cff->private[0], "Subrs")) { - (cff->subrs)[0] = NULL; - } else { - offset = (long) cff_dict_get(cff->topdict, "Private", 1); - offset += (long) cff_dict_get(cff->private[0], "Subrs", 0); - cff->offset = offset; - (cff->subrs)[0] = cff_get_index(cff); - len += cff_index_size((cff->subrs)[0]); + if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdselect == NULL) { + cff_read_fdselect(cff); } - } - - return len; -} - - -long cff_read_fdarray (cff_font *cff) -{ - long len = 0; - cff_index *idx; - long offset, size; - card16 i; - if (cff->topdict == NULL) - CFF_ERROR("in cff_read_fdarray(): Top DICT not found"); + if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdarray == NULL) { + cff_read_fdarray(cff); + } - if (!(cff->flag & FONTTYPE_CIDFONT)) - return 0; + if (cff->private == NULL) + cff_read_private(cff); - /* must exist */ - offset = (long) cff_dict_get(cff->topdict, "FDArray", 0); - cff->offset = offset; - idx = cff_get_index(cff); - cff->num_fds = (card8)idx->count; - cff->fdarray = xcalloc(idx->count, sizeof(cff_dict *)); - for (i=0;icount;i++) { - card8 *data = idx->data + (idx->offset)[i] - 1; - size = (idx->offset)[i+1] - (idx->offset)[i]; - if (size > 0) { - (cff->fdarray)[i] = cff_dict_unpack(data, data+size); - } else { - (cff->fdarray)[i] = NULL; + if (cff->gsubr == NULL) { + cff->offset = cff->gsubr_offset; + cff->gsubr = cff_get_index(cff); } - } - len = cff_index_size(idx); - cff_release_index(idx); - return len; + cff->subrs = xcalloc(cff->num_fds, sizeof(cff_index *)); + if (cff->flag & FONTTYPE_CIDFONT) { + for (i = 0; i < cff->num_fds; i++) { + if (cff->private[i] == NULL || + !cff_dict_known(cff->private[i], "Subrs")) { + (cff->subrs)[i] = NULL; + } else { + offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); + offset += (long) cff_dict_get(cff->private[i], "Subrs", 0); + cff->offset = offset; + (cff->subrs)[i] = cff_get_index(cff); + len += cff_index_size((cff->subrs)[i]); + } + } + } else { + if (cff->private[0] == NULL || + !cff_dict_known(cff->private[0], "Subrs")) { + (cff->subrs)[0] = NULL; + } else { + offset = (long) cff_dict_get(cff->topdict, "Private", 1); + offset += (long) cff_dict_get(cff->private[0], "Subrs", 0); + cff->offset = offset; + (cff->subrs)[0] = cff_get_index(cff); + len += cff_index_size((cff->subrs)[0]); + } + } + + return len; } -long cff_read_private (cff_font *cff) +long cff_read_fdarray(cff_font * cff) { - long len = 0; - card8 *data; - long offset, size; + long len = 0; + cff_index *idx; + long offset, size; + card16 i; + + if (cff->topdict == NULL) + CFF_ERROR("in cff_read_fdarray(): Top DICT not found"); + + if (!(cff->flag & FONTTYPE_CIDFONT)) + return 0; + + /* must exist */ + offset = (long) cff_dict_get(cff->topdict, "FDArray", 0); + cff->offset = offset; + idx = cff_get_index(cff); + cff->num_fds = (card8) idx->count; + cff->fdarray = xcalloc(idx->count, sizeof(cff_dict *)); + for (i = 0; i < idx->count; i++) { + card8 *data = idx->data + (idx->offset)[i] - 1; + size = (idx->offset)[i + 1] - (idx->offset)[i]; + if (size > 0) { + (cff->fdarray)[i] = cff_dict_unpack(data, data + size); + } else { + (cff->fdarray)[i] = NULL; + } + } + len = cff_index_size(idx); + cff_release_index(idx); + + return len; +} - if (cff->flag & FONTTYPE_CIDFONT) { - int i; - if (cff->fdarray == NULL) - cff_read_fdarray(cff); - - cff->private = xcalloc(cff->num_fds, sizeof(cff_dict *)); - for (i=0;inum_fds;i++) { - if (cff->fdarray[i] != NULL && - cff_dict_known(cff->fdarray[i], "Private") && - (size = (long) cff_dict_get(cff->fdarray[i], "Private", 0)) - > 0) { - offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); - cff->offset = offset; - data = xcalloc(size, sizeof(card8)); - memcpy(data,&cff->stream[cff->offset],size); - cff->offset = size; - (cff->private)[i] = cff_dict_unpack(data, data+size); - xfree(data); - len += size; - } else { - (cff->private)[i] = NULL; - } - } - } else { - cff->num_fds = 1; - cff->private = xcalloc(1, sizeof(cff_dict *)); - if (cff_dict_known(cff->topdict, "Private") && - (size = (long) cff_dict_get(cff->topdict, "Private", 0)) > 0) { - offset = (long) cff_dict_get(cff->topdict, "Private", 1); - cff->offset = offset; - data = xcalloc(size, sizeof(card8)); - memcpy(data,&cff->stream[cff->offset],size); - cff->offset = size; - cff->private[0] = cff_dict_unpack(data, data+size); - xfree(data); - len += size; +long cff_read_private(cff_font * cff) +{ + long len = 0; + card8 *data; + long offset, size; + + if (cff->flag & FONTTYPE_CIDFONT) { + int i; + + if (cff->fdarray == NULL) + cff_read_fdarray(cff); + + cff->private = xcalloc(cff->num_fds, sizeof(cff_dict *)); + for (i = 0; i < cff->num_fds; i++) { + if (cff->fdarray[i] != NULL && + cff_dict_known(cff->fdarray[i], "Private") && + (size = (long) cff_dict_get(cff->fdarray[i], "Private", 0)) + > 0) { + offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); + cff->offset = offset; + data = xcalloc(size, sizeof(card8)); + memcpy(data, &cff->stream[cff->offset], size); + cff->offset = size; + (cff->private)[i] = cff_dict_unpack(data, data + size); + xfree(data); + len += size; + } else { + (cff->private)[i] = NULL; + } + } } else { - (cff->private)[0] = NULL; - len = 0; - } - } - - return len; + cff->num_fds = 1; + cff->private = xcalloc(1, sizeof(cff_dict *)); + if (cff_dict_known(cff->topdict, "Private") && + (size = (long) cff_dict_get(cff->topdict, "Private", 0)) > 0) { + offset = (long) cff_dict_get(cff->topdict, "Private", 1); + cff->offset = offset; + data = xcalloc(size, sizeof(card8)); + memcpy(data, &cff->stream[cff->offset], size); + cff->offset = size; + cff->private[0] = cff_dict_unpack(data, data + size); + xfree(data); + len += size; + } else { + (cff->private)[0] = NULL; + len = 0; + } + } + + return len; } -cff_font *read_cff (unsigned char *buf,long buflength, int n) +cff_font *read_cff(unsigned char *buf, long buflength, int n) { - cff_font *cff; - cff_index *idx; - long offset ; + cff_font *cff; + cff_index *idx; + long offset; - cff = xcalloc(1,sizeof(cff_font)); + cff = xcalloc(1, sizeof(cff_font)); - cff->stream = buf; - cff->stream_size = buflength; - cff->index = n; + cff->stream = buf; + cff->stream_size = buflength; + cff->index = n; - cff->header_major = get_card8(cff); - cff->header_minor = get_card8(cff); - cff->header_hdr_size = get_card8(cff); - cff->header_offsize = get_card8(cff); - if (cff->header_offsize < 1 || cff->header_offsize > 4) { - WARN("invalid offsize data"); - cff_close(cff); - return NULL; - } - if (cff->header_major > 1) { - pdftex_warn("CFF major version %u not supported.",cff->header_major); - cff_close(cff); - return NULL; - } - cff->offset = cff->header_hdr_size; - - /* Name INDEX */ - idx = cff_get_index(cff); - if (n > idx->count - 1) { - pdftex_warn("Invalid CFF fontset index number."); - cff_close(cff); - return NULL; - } + cff->header_major = get_card8(cff); + cff->header_minor = get_card8(cff); + cff->header_hdr_size = get_card8(cff); + cff->header_offsize = get_card8(cff); + if (cff->header_offsize < 1 || cff->header_offsize > 4) { + WARN("invalid offsize data"); + cff_close(cff); + return NULL; + } + if (cff->header_major > 1) { + pdftex_warn("CFF major version %u not supported.", cff->header_major); + cff_close(cff); + return NULL; + } + cff->offset = cff->header_hdr_size; - cff->name = idx; + /* Name INDEX */ + idx = cff_get_index(cff); + if (n > idx->count - 1) { + pdftex_warn("Invalid CFF fontset index number."); + cff_close(cff); + return NULL; + } - cff->fontname = cff_get_name(cff); + cff->name = idx; - /* Top DICT INDEX */ - idx = cff_get_index(cff); - if (n > idx->count - 1) { - WARN("CFF Top DICT not exist..."); - cff_close(cff); - return NULL; - } - cff->topdict = cff_dict_unpack(idx->data + idx->offset[n] - 1, - idx->data + idx->offset[n + 1] - 1); - if (!cff->topdict) { - WARN("Parsing CFF Top DICT data failed..."); - cff_close(cff); - return NULL; - } - cff_release_index(idx); + cff->fontname = cff_get_name(cff); - if (cff_dict_known(cff->topdict, "CharstringType") && - cff_dict_get(cff->topdict, "CharstringType", 0) != 2) { - WARN("Only Type 2 Charstrings supported..."); - cff_close(cff); - return NULL; - } + /* Top DICT INDEX */ + idx = cff_get_index(cff); + if (n > idx->count - 1) { + WARN("CFF Top DICT not exist..."); + cff_close(cff); + return NULL; + } + cff->topdict = cff_dict_unpack(idx->data + idx->offset[n] - 1, + idx->data + idx->offset[n + 1] - 1); + if (!cff->topdict) { + WARN("Parsing CFF Top DICT data failed..."); + cff_close(cff); + return NULL; + } + cff_release_index(idx); - if (cff_dict_known(cff->topdict, "SyntheticBase")) { - WARN("CFF Synthetic font not supported."); - cff_close(cff); - return NULL; - } + if (cff_dict_known(cff->topdict, "CharstringType") && + cff_dict_get(cff->topdict, "CharstringType", 0) != 2) { + WARN("Only Type 2 Charstrings supported..."); + cff_close(cff); + return NULL; + } - /* String INDEX */ - cff->string = cff_get_index(cff); + if (cff_dict_known(cff->topdict, "SyntheticBase")) { + WARN("CFF Synthetic font not supported."); + cff_close(cff); + return NULL; + } - /* offset to GSubr */ - cff->gsubr_offset = cff->offset; + /* String INDEX */ + cff->string = cff_get_index(cff); - /* Number of glyphs */ - offset = (long) cff_dict_get(cff->topdict, "CharStrings", 0); - cff->offset = offset; - cff->num_glyphs = get_card16(cff); + /* offset to GSubr */ + cff->gsubr_offset = cff->offset; - /* Check for font type */ - if (cff_dict_known(cff->topdict, "ROS")) { - cff->flag |= FONTTYPE_CIDFONT; - } else { - cff->flag |= FONTTYPE_FONT; - } + /* Number of glyphs */ + offset = (long) cff_dict_get(cff->topdict, "CharStrings", 0); + cff->offset = offset; + cff->num_glyphs = get_card16(cff); - /* Check for encoding */ - if (cff_dict_known(cff->topdict, "Encoding")) { - offset = (long) cff_dict_get(cff->topdict, "Encoding", 0); - if (offset == 0) { /* predefined */ - cff->flag |= ENCODING_STANDARD; - } else if (offset == 1) { - cff->flag |= ENCODING_EXPERT; + /* Check for font type */ + if (cff_dict_known(cff->topdict, "ROS")) { + cff->flag |= FONTTYPE_CIDFONT; + } else { + cff->flag |= FONTTYPE_FONT; } - } else { - cff->flag |= ENCODING_STANDARD; - } - cff->offset = cff->gsubr_offset; /* seek back to GSubr */ + /* Check for encoding */ + if (cff_dict_known(cff->topdict, "Encoding")) { + offset = (long) cff_dict_get(cff->topdict, "Encoding", 0); + if (offset == 0) { /* predefined */ + cff->flag |= ENCODING_STANDARD; + } else if (offset == 1) { + cff->flag |= ENCODING_EXPERT; + } + } else { + cff->flag |= ENCODING_STANDARD; + } + + cff->offset = cff->gsubr_offset; /* seek back to GSubr */ - return cff; + return cff; } /* write a cff for opentype */ @@ -1116,610 +1157,610 @@ cff_font *read_cff (unsigned char *buf,long buflength, int n) /* Pack DICT data */ -static long pack_integer (card8 *dest, long destlen, long value) +static long pack_integer(card8 * dest, long destlen, long value) { - long len = 0; - - if (value >= -107 && value <= 107) { - if (destlen < 1) - CFF_ERROR("Buffer overflow."); - dest[0] = (value + 139) & 0xff; - len = 1; - } else if (value >= 108 && value <= 1131) { - if (destlen < 2) - CFF_ERROR("Buffer overflow."); - value = 0xf700u + value - 108; - dest[0] = (value >> 8) & 0xff; - dest[1] = value & 0xff; - len = 2; - } else if (value >= -1131 && value <= -108) { - if (destlen < 2) - CFF_ERROR("Buffer overflow."); - value = 0xfb00u - value - 108; - dest[0] = (value >> 8) & 0xff; - dest[1] = value & 0xff; - len = 2; - } else if (value >= -32768 && value <= 32767) { /* shortint */ - if (destlen < 3) - CFF_ERROR("Buffer overflow."); - dest[0] = 28; - dest[1] = (value >> 8) & 0xff; - dest[2] = value & 0xff; - len = 3; - } else { /* longint */ - if (destlen < 5) - CFF_ERROR("Buffer overflow."); - dest[0] = 29; - dest[1] = (value >> 24) & 0xff; - dest[2] = (value >> 16) & 0xff; - dest[3] = (value >> 8) & 0xff; - dest[4] = value & 0xff; - len = 5; - } - return len; + long len = 0; + + if (value >= -107 && value <= 107) { + if (destlen < 1) + CFF_ERROR("Buffer overflow."); + dest[0] = (value + 139) & 0xff; + len = 1; + } else if (value >= 108 && value <= 1131) { + if (destlen < 2) + CFF_ERROR("Buffer overflow."); + value = 0xf700u + value - 108; + dest[0] = (value >> 8) & 0xff; + dest[1] = value & 0xff; + len = 2; + } else if (value >= -1131 && value <= -108) { + if (destlen < 2) + CFF_ERROR("Buffer overflow."); + value = 0xfb00u - value - 108; + dest[0] = (value >> 8) & 0xff; + dest[1] = value & 0xff; + len = 2; + } else if (value >= -32768 && value <= 32767) { /* shortint */ + if (destlen < 3) + CFF_ERROR("Buffer overflow."); + dest[0] = 28; + dest[1] = (value >> 8) & 0xff; + dest[2] = value & 0xff; + len = 3; + } else { /* longint */ + if (destlen < 5) + CFF_ERROR("Buffer overflow."); + dest[0] = 29; + dest[1] = (value >> 24) & 0xff; + dest[2] = (value >> 16) & 0xff; + dest[3] = (value >> 8) & 0xff; + dest[4] = value & 0xff; + len = 5; + } + return len; } -static long pack_real (card8 *dest, long destlen, double value) +static long pack_real(card8 * dest, long destlen, double value) { - long e; - int i = 0, pos = 2; + long e; + int i = 0, pos = 2; #define CFF_REAL_MAX_LEN 17 - if (destlen < 2) - CFF_ERROR("Buffer overflow."); - - dest[0] = 30; - - if (value == 0.0) { - dest[1] = 0x0f; - return 2; - } - - if (value < 0.0) { - dest[1] = 0xe0; - value *= -1.0; - pos++; - } - - e = 0; - if (value >= 10.0) { - while (value >= 10.0) { - value /= 10.0; - e++; - } - } else if (value < 1.0) { - while (value < 1.0) { - value *= 10.0; - e--; - } - } - - sprintf(work_buffer, "%1.14g", value); - for (i=0;i= '0' && work_buffer[i] <= '9') { - ch = work_buffer[i] - '0'; - } else { - CFF_ERROR("Invalid character."); - } - - if (destlen < pos/2 + 1) - CFF_ERROR("Buffer overflow."); - - if (pos % 2) { - dest[pos/2] += ch; - } else { - dest[pos/2] = (ch << 4); + if (destlen < 2) + CFF_ERROR("Buffer overflow."); + + dest[0] = 30; + + if (value == 0.0) { + dest[1] = 0x0f; + return 2; + } + + if (value < 0.0) { + dest[1] = 0xe0; + value *= -1.0; + pos++; + } + + e = 0; + if (value >= 10.0) { + while (value >= 10.0) { + value /= 10.0; + e++; + } + } else if (value < 1.0) { + while (value < 1.0) { + value *= 10.0; + e--; + } + } + + sprintf(work_buffer, "%1.14g", value); + for (i = 0; i < CFF_REAL_MAX_LEN; i++) { + unsigned char ch = 0; + if (work_buffer[i] == '\0') { + break; + } else if (work_buffer[i] == '.') { + ch = 0x0a; + } else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') { + ch = work_buffer[i] - '0'; + } else { + CFF_ERROR("Invalid character."); + } + + if (destlen < pos / 2 + 1) + CFF_ERROR("Buffer overflow."); + + if (pos % 2) { + dest[pos / 2] += ch; + } else { + dest[pos / 2] = (ch << 4); + } + pos++; + } + + if (e > 0) { + if (pos % 2) { + dest[pos / 2] += 0x0b; + } else { + if (destlen < pos / 2 + 1) + CFF_ERROR("Buffer overflow."); + dest[pos / 2] = 0xb0; + } + pos++; + } else if (e < 0) { + if (pos % 2) { + dest[pos / 2] += 0x0c; + } else { + if (destlen < pos / 2 + 1) + CFF_ERROR("Buffer overflow."); + dest[pos / 2] = 0xc0; + } + e *= -1; + pos++; + } + + if (e != 0) { + sprintf(work_buffer, "%ld", e); + for (i = 0; i < CFF_REAL_MAX_LEN; i++) { + unsigned char ch = 0; + if (work_buffer[i] == '\0') { + break; + } else if (work_buffer[i] == '.') { + ch = 0x0a; + } else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') { + ch = work_buffer[i] - '0'; + } else { + CFF_ERROR("Invalid character."); + } + + if (destlen < pos / 2 + 1) + CFF_ERROR("Buffer overflow."); + + if (pos % 2) { + dest[pos / 2] += ch; + } else { + dest[pos / 2] = (ch << 4); + } + pos++; + } } - pos++; - } - if (e > 0) { - if (pos % 2) { - dest[pos/2] += 0x0b; - } else { - if (destlen < pos/2 + 1) - CFF_ERROR("Buffer overflow."); - dest[pos/2] = 0xb0; - } - pos++; - } else if (e < 0) { if (pos % 2) { - dest[pos/2] += 0x0c; + dest[pos / 2] += 0x0f; + pos++; } else { - if (destlen < pos/2 + 1) - CFF_ERROR("Buffer overflow."); - dest[pos/2] = 0xc0; - } - e *= -1; - pos++; - } - - if (e != 0) { - sprintf(work_buffer, "%ld", e); - for (i=0;i= '0' && work_buffer[i] <= '9') { - ch = work_buffer[i] - '0'; - } else { - CFF_ERROR("Invalid character."); - } - - if (destlen < pos/2 + 1) - CFF_ERROR("Buffer overflow."); - - if (pos % 2) { - dest[pos/2] += ch; - } else { - dest[pos/2] = (ch << 4); - } - pos++; + if (destlen < pos / 2 + 1) + CFF_ERROR("Buffer overflow."); + dest[pos / 2] = 0xff; + pos += 2; } - } - - if (pos % 2) { - dest[pos/2] += 0x0f; - pos++; - } else { - if (destlen < pos/2 + 1) - CFF_ERROR("Buffer overflow."); - dest[pos/2] = 0xff; - pos += 2; - } - return pos/2; + return pos / 2; } -static long cff_dict_put_number (double value, - card8 *dest, long destlen, - int type) +static long cff_dict_put_number(double value, + card8 * dest, long destlen, int type) { - long len = 0; - double nearint; - - nearint = floor(value+0.5); - /* set offset to longint */ - if (type == CFF_TYPE_OFFSET) { - long lvalue; - - lvalue = (long) value; - if (destlen < 5) - CFF_ERROR("Buffer overflow."); - dest[0] = 29; - dest[1] = (lvalue >> 24) & 0xff; - dest[2] = (lvalue >> 16) & 0xff; - dest[3] = (lvalue >> 8) & 0xff; - dest[4] = lvalue & 0xff; - len = 5; - } else if (value > CFF_INT_MAX || value < CFF_INT_MIN || - (fabs(value - nearint) > 1.0e-5)) { /* real */ - len = pack_real(dest, destlen, value); - } else { /* integer */ - len = pack_integer(dest, destlen, (long) nearint); - } - - return len; + long len = 0; + double nearint; + + nearint = floor(value + 0.5); + /* set offset to longint */ + if (type == CFF_TYPE_OFFSET) { + long lvalue; + + lvalue = (long) value; + if (destlen < 5) + CFF_ERROR("Buffer overflow."); + dest[0] = 29; + dest[1] = (lvalue >> 24) & 0xff; + dest[2] = (lvalue >> 16) & 0xff; + dest[3] = (lvalue >> 8) & 0xff; + dest[4] = lvalue & 0xff; + len = 5; + } else if (value > CFF_INT_MAX || value < CFF_INT_MIN || (fabs(value - nearint) > 1.0e-5)) { /* real */ + len = pack_real(dest, destlen, value); + } else { /* integer */ + len = pack_integer(dest, destlen, (long) nearint); + } + + return len; } -static long -put_dict_entry (cff_dict_entry *de, - card8 *dest, long destlen) +static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen) { - long len = 0; - int i, type, id; - - if (de->count > 0) { - id = de->id; - if (dict_operator[id].argtype == CFF_TYPE_OFFSET || - dict_operator[id].argtype == CFF_TYPE_SZOFF) { - type = CFF_TYPE_OFFSET; - } else { - type = CFF_TYPE_NUMBER; - } - for (i = 0; i < de->count; i++) { - len += cff_dict_put_number(de->values[i], - dest+len, - destlen-len, type); - } - if (id >= 0 && id < CFF_LAST_DICT_OP1) { - if (len + 1 > destlen) - CFF_ERROR("Buffer overflow."); - dest[len++] = id; - } else if (id >= 0 && id < CFF_LAST_DICT_OP) { - if (len + 2 > destlen) - CFF_ERROR("in cff_dict_pack(): Buffer overflow"); - dest[len++] = 12; - dest[len++] = id - CFF_LAST_DICT_OP1; - } else { - CFF_ERROR("Invalid CFF DICT operator ID."); - } - } - - return len; + long len = 0; + int i, type, id; + + if (de->count > 0) { + id = de->id; + if (dict_operator[id].argtype == CFF_TYPE_OFFSET || + dict_operator[id].argtype == CFF_TYPE_SZOFF) { + type = CFF_TYPE_OFFSET; + } else { + type = CFF_TYPE_NUMBER; + } + for (i = 0; i < de->count; i++) { + len += cff_dict_put_number(de->values[i], + dest + len, destlen - len, type); + } + if (id >= 0 && id < CFF_LAST_DICT_OP1) { + if (len + 1 > destlen) + CFF_ERROR("Buffer overflow."); + dest[len++] = id; + } else if (id >= 0 && id < CFF_LAST_DICT_OP) { + if (len + 2 > destlen) + CFF_ERROR("in cff_dict_pack(): Buffer overflow"); + dest[len++] = 12; + dest[len++] = id - CFF_LAST_DICT_OP1; + } else { + CFF_ERROR("Invalid CFF DICT operator ID."); + } + } + + return len; } -long cff_dict_pack (cff_dict *dict, card8 *dest, long destlen) +long cff_dict_pack(cff_dict * dict, card8 * dest, long destlen) { - long len = 0; - int i; + long len = 0; + int i; - for (i = 0; i < dict->count; i++) { - if (!strcmp(dict->entries[i].key, "ROS")) { - len += put_dict_entry(&dict->entries[i], dest, destlen); - break; + for (i = 0; i < dict->count; i++) { + if (!strcmp(dict->entries[i].key, "ROS")) { + len += put_dict_entry(&dict->entries[i], dest, destlen); + break; + } } - } - for (i = 0; i < dict->count; i++) { - if (strcmp(dict->entries[i].key, "ROS")) { - len += put_dict_entry(&dict->entries[i], dest+len, destlen-len); + for (i = 0; i < dict->count; i++) { + if (strcmp(dict->entries[i].key, "ROS")) { + len += put_dict_entry(&dict->entries[i], dest + len, destlen - len); + } } - } - return len; + return len; } -void cff_dict_add (cff_dict *dict, const char *key, int count) +void cff_dict_add(cff_dict * dict, const char *key, int count) { - int id, i; + int id, i; - for (id=0;idcount;i++) { - if ((dict->entries)[i].id == id) { - if ((dict->entries)[i].count != count) - CFF_ERROR("Inconsistent DICT argument number."); - return; + for (i = 0; i < dict->count; i++) { + if ((dict->entries)[i].id == id) { + if ((dict->entries)[i].count != count) + CFF_ERROR("Inconsistent DICT argument number."); + return; + } } - } - if (dict->count + 1 >= dict->max) { - dict->max += 8; - dict->entries = xrealloc(dict->entries, (dict->max)*sizeof(cff_dict_entry)); - } + if (dict->count + 1 >= dict->max) { + dict->max += 8; + dict->entries = + xrealloc(dict->entries, (dict->max) * sizeof(cff_dict_entry)); + } - (dict->entries)[dict->count].id = id; - (dict->entries)[dict->count].key = (char *) dict_operator[id].opname; - (dict->entries)[dict->count].count = count; - if (count > 0) { - (dict->entries)[dict->count].values = xcalloc(count, sizeof(double)); - memset((dict->entries)[dict->count].values, - 0, sizeof(double)*count); - } else { - (dict->entries)[dict->count].values = NULL; - } - dict->count += 1; + (dict->entries)[dict->count].id = id; + (dict->entries)[dict->count].key = (char *) dict_operator[id].opname; + (dict->entries)[dict->count].count = count; + if (count > 0) { + (dict->entries)[dict->count].values = xcalloc(count, sizeof(double)); + memset((dict->entries)[dict->count].values, 0, sizeof(double) * count); + } else { + (dict->entries)[dict->count].values = NULL; + } + dict->count += 1; - return; + return; } -void cff_dict_remove (cff_dict *dict, const char *key) +void cff_dict_remove(cff_dict * dict, const char *key) { - int i; - for (i = 0; i < dict->count; i++) { - if (key && strcmp(key, (dict->entries)[i].key) == 0) { - (dict->entries)[i].count = 0; - if ((dict->entries)[i].values) - xfree((dict->entries)[i].values); - (dict->entries)[i].values = NULL; + int i; + for (i = 0; i < dict->count; i++) { + if (key && strcmp(key, (dict->entries)[i].key) == 0) { + (dict->entries)[i].count = 0; + if ((dict->entries)[i].values) + xfree((dict->entries)[i].values); + (dict->entries)[i].values = NULL; + } } - } } -void cff_dict_set (cff_dict *dict, const char *key, int idx, double value) +void cff_dict_set(cff_dict * dict, const char *key, int idx, double value) { - int i; + int i; - assert(dict && key); + assert(dict && key); - for (i = 0 ; i < dict->count; i++) { - if (strcmp(key, (dict->entries)[i].key) == 0) { - if ((dict->entries)[i].count > idx) - (dict->entries)[i].values[idx] = value; - else - CFF_ERROR("Invalid index number."); - break; + for (i = 0; i < dict->count; i++) { + if (strcmp(key, (dict->entries)[i].key) == 0) { + if ((dict->entries)[i].count > idx) + (dict->entries)[i].values[idx] = value; + else + CFF_ERROR("Invalid index number."); + break; + } } - } - if (i == dict->count) - pdftex_fail("DICT entry \"%s\" not found.", key); + if (i == dict->count) + pdftex_fail("DICT entry \"%s\" not found.", key); } /* Strings */ -char *cff_get_string (cff_font *cff, s_SID id) +char *cff_get_string(cff_font * cff, s_SID id) { - char *result = NULL; - long len; - - if (id < CFF_STDSTR_MAX) { - len = strlen(cff_stdstr[id]); - result = xcalloc(len+1, sizeof(char)); - memcpy(result, cff_stdstr[id], len); - result[len] = '\0'; - } else if (cff && cff->string) { - cff_index *strings = cff->string; - id -= CFF_STDSTR_MAX; - if (id < strings->count) { - len = (strings->offset)[id+1] - (strings->offset)[id]; - result = xcalloc(len + 1, sizeof(char)); - memmove(result, strings->data + (strings->offset)[id] - 1, len); - result[len] = '\0'; - } - } - - return result; + char *result = NULL; + long len; + + if (id < CFF_STDSTR_MAX) { + len = strlen(cff_stdstr[id]); + result = xcalloc(len + 1, sizeof(char)); + memcpy(result, cff_stdstr[id], len); + result[len] = '\0'; + } else if (cff && cff->string) { + cff_index *strings = cff->string; + id -= CFF_STDSTR_MAX; + if (id < strings->count) { + len = (strings->offset)[id + 1] - (strings->offset)[id]; + result = xcalloc(len + 1, sizeof(char)); + memmove(result, strings->data + (strings->offset)[id] - 1, len); + result[len] = '\0'; + } + } + + return result; } -long cff_get_sid (cff_font *cff, char *str) +long cff_get_sid(cff_font * cff, char *str) { - card16 i; + card16 i; - if (!cff || !str) - return -1; + if (!cff || !str) + return -1; - /* I search String INDEX first. */ - if (cff && cff->string) { - cff_index *idx = cff->string; - for (i = 0; i < idx->count; i++) { - if (strlen(str) == (idx->offset)[i+1] - (idx->offset)[i] && - !memcmp(str, (idx->data)+(idx->offset)[i]-1, strlen(str))) - return (i + CFF_STDSTR_MAX); + /* I search String INDEX first. */ + if (cff && cff->string) { + cff_index *idx = cff->string; + for (i = 0; i < idx->count; i++) { + if (strlen(str) == (idx->offset)[i + 1] - (idx->offset)[i] && + !memcmp(str, (idx->data) + (idx->offset)[i] - 1, strlen(str))) + return (i + CFF_STDSTR_MAX); + } } - } - for (i = 0; i < CFF_STDSTR_MAX; i++) { - if (!strcmp(str, cff_stdstr[i])) - return i; - } + for (i = 0; i < CFF_STDSTR_MAX; i++) { + if (!strcmp(str, cff_stdstr[i])) + return i; + } - return -1; + return -1; } -void cff_update_string (cff_font *cff) +void cff_update_string(cff_font * cff) { - if (cff == NULL) - CFF_ERROR("CFF font not opened."); - - if (cff->string) - cff_release_index(cff->string); - cff->string = cff->_string; - cff->_string = NULL; + if (cff == NULL) + CFF_ERROR("CFF font not opened."); + + if (cff->string) + cff_release_index(cff->string); + cff->string = cff->_string; + cff->_string = NULL; } -s_SID cff_add_string (cff_font *cff, char *str) +s_SID cff_add_string(cff_font * cff, char *str) { - card16 idx; - cff_index *strings; - l_offset offset, size; - - if (cff == NULL) - CFF_ERROR("CFF font not opened."); - - if (cff->_string == NULL) - cff->_string = cff_new_index(0); - strings = cff->_string; - - for (idx = 0; idx < strings->count; idx++) { - size = strings->offset[idx+1] - strings->offset[idx]; - offset = strings->offset[idx]; - if (size == strlen(str) && - !memcmp(strings->data+offset-1, str, strlen(str))) - return (idx + CFF_STDSTR_MAX); - } - - for (idx = 0; idx < CFF_STDSTR_MAX; idx++) { - if (cff_stdstr[idx] && - !strcmp(cff_stdstr[idx], str)) - return idx; - } - offset = (strings->count > 0) ? strings->offset[strings->count] : 1; - strings->offset = xrealloc(strings->offset, (strings->count+2)*sizeof(l_offset)); - if (strings->count == 0) - strings->offset[0] = 1; - idx = strings->count; - strings->count += 1; - strings->offset[strings->count] = offset + strlen(str); - strings->data = xrealloc(strings->data, (offset+strlen(str)-1)*sizeof(card8)); - memcpy(strings->data+offset-1, str, strlen(str)); - - return (idx + CFF_STDSTR_MAX); + card16 idx; + cff_index *strings; + l_offset offset, size; + + if (cff == NULL) + CFF_ERROR("CFF font not opened."); + + if (cff->_string == NULL) + cff->_string = cff_new_index(0); + strings = cff->_string; + + for (idx = 0; idx < strings->count; idx++) { + size = strings->offset[idx + 1] - strings->offset[idx]; + offset = strings->offset[idx]; + if (size == strlen(str) && + !memcmp(strings->data + offset - 1, str, strlen(str))) + return (idx + CFF_STDSTR_MAX); + } + + for (idx = 0; idx < CFF_STDSTR_MAX; idx++) { + if (cff_stdstr[idx] && !strcmp(cff_stdstr[idx], str)) + return idx; + } + offset = (strings->count > 0) ? strings->offset[strings->count] : 1; + strings->offset = + xrealloc(strings->offset, (strings->count + 2) * sizeof(l_offset)); + if (strings->count == 0) + strings->offset[0] = 1; + idx = strings->count; + strings->count += 1; + strings->offset[strings->count] = offset + strlen(str); + strings->data = + xrealloc(strings->data, (offset + strlen(str) - 1) * sizeof(card8)); + memcpy(strings->data + offset - 1, str, strlen(str)); + + return (idx + CFF_STDSTR_MAX); } -void cff_dict_update (cff_dict *dict, cff_font *cff) +void cff_dict_update(cff_dict * dict, cff_font * cff) { - int i; - - for (i = 0;i < dict->count; i++) { - if ((dict->entries)[i].count > 0) { - char *str; - int id; - - id = (dict->entries)[i].id; - - if (dict_operator[id].argtype == CFF_TYPE_SID) { - str = cff_get_string(cff, (dict->entries)[i].values[0]); - (dict->entries)[i].values[0] = cff_add_string(cff, str); - xfree(str); - } else if (dict_operator[id].argtype == CFF_TYPE_ROS) { - str = cff_get_string(cff, (dict->entries)[i].values[0]); - (dict->entries)[i].values[0] = cff_add_string(cff, str); - xfree(str); - str = cff_get_string(cff, (dict->entries)[i].values[1]); - (dict->entries)[i].values[1] = cff_add_string(cff, str); - xfree(str); - } - + int i; + + for (i = 0; i < dict->count; i++) { + if ((dict->entries)[i].count > 0) { + char *str; + int id; + + id = (dict->entries)[i].id; + + if (dict_operator[id].argtype == CFF_TYPE_SID) { + str = cff_get_string(cff, (dict->entries)[i].values[0]); + (dict->entries)[i].values[0] = cff_add_string(cff, str); + xfree(str); + } else if (dict_operator[id].argtype == CFF_TYPE_ROS) { + str = cff_get_string(cff, (dict->entries)[i].values[0]); + (dict->entries)[i].values[0] = cff_add_string(cff, str); + xfree(str); + str = cff_get_string(cff, (dict->entries)[i].values[1]); + (dict->entries)[i].values[1] = cff_add_string(cff, str); + xfree(str); + } + + } } - } } /* charsets */ -long cff_read_charsets (cff_font *cff) +long cff_read_charsets(cff_font * cff) { - cff_charsets *charset; - long offset, length; - card16 count, i; + cff_charsets *charset; + long offset, length; + card16 count, i; - if (cff->topdict == NULL) - CFF_ERROR("Top DICT not available"); + if (cff->topdict == NULL) + CFF_ERROR("Top DICT not available"); - if (!cff_dict_known(cff->topdict, "charset")) { - cff->flag |= CHARSETS_ISOADOBE; - cff->charsets = NULL; - return 0; - } + if (!cff_dict_known(cff->topdict, "charset")) { + cff->flag |= CHARSETS_ISOADOBE; + cff->charsets = NULL; + return 0; + } - offset = (long) cff_dict_get(cff->topdict, "charset", 0); + offset = (long) cff_dict_get(cff->topdict, "charset", 0); - if (offset == 0) { /* predefined */ - cff->flag |= CHARSETS_ISOADOBE; - cff->charsets = NULL; - return 0; - } else if (offset == 1) { - cff->flag |= CHARSETS_EXPERT; - cff->charsets = NULL; - return 0; - } else if (offset == 2) { - cff->flag |= CHARSETS_EXPSUB; - cff->charsets = NULL; - return 0; - } + if (offset == 0) { /* predefined */ + cff->flag |= CHARSETS_ISOADOBE; + cff->charsets = NULL; + return 0; + } else if (offset == 1) { + cff->flag |= CHARSETS_EXPERT; + cff->charsets = NULL; + return 0; + } else if (offset == 2) { + cff->flag |= CHARSETS_EXPSUB; + cff->charsets = NULL; + return 0; + } - cff->offset = offset; - cff->charsets = charset = xcalloc(1, sizeof(cff_charsets)); - charset->format = get_card8(cff); - charset->num_entries = 0; - - count = cff->num_glyphs - 1; - length = 1; - - /* Not sure. Not well documented. */ - switch (charset->format) { - case 0: - charset->num_entries = cff->num_glyphs - 1; /* no .notdef */ - charset->data.glyphs = xcalloc(charset->num_entries, sizeof(s_SID)); - length += (charset->num_entries) * 2; - for (i=0;i<(charset->num_entries);i++) { - charset->data.glyphs[i] = get_card16(cff); - } - count = 0; - break; - case 1: - { - cff_range1 *ranges = NULL; - while (count > 0 && charset->num_entries < cff->num_glyphs) { - ranges = xrealloc(ranges, (charset->num_entries + 1)*sizeof(cff_range1)); - ranges[charset->num_entries].first = get_card16(cff); - ranges[charset->num_entries].n_left = get_card8(cff); - count -= ranges[charset->num_entries].n_left + 1; /* no-overrap */ - charset->num_entries += 1; - charset->data.range1 = ranges; - } - length += (charset->num_entries) * 3; - } - break; - case 2: - { - cff_range2 *ranges = NULL; - while (count > 0 && charset->num_entries < cff->num_glyphs) { - ranges = xrealloc(ranges, (charset->num_entries + 1)*sizeof(cff_range2)); - ranges[charset->num_entries].first = get_card16(cff); - ranges[charset->num_entries].n_left = get_card16(cff); - count -= ranges[charset->num_entries].n_left + 1; /* non-overrapping */ - charset->num_entries += 1; - } - charset->data.range2 = ranges; - length += (charset->num_entries) * 4; - } - break; - default: - xfree(charset); - CFF_ERROR("Unknown Charset format"); - break; - } + cff->offset = offset; + cff->charsets = charset = xcalloc(1, sizeof(cff_charsets)); + charset->format = get_card8(cff); + charset->num_entries = 0; - if (count > 0) - CFF_ERROR("Charset data possibly broken"); + count = cff->num_glyphs - 1; + length = 1; - return length; + /* Not sure. Not well documented. */ + switch (charset->format) { + case 0: + charset->num_entries = cff->num_glyphs - 1; /* no .notdef */ + charset->data.glyphs = xcalloc(charset->num_entries, sizeof(s_SID)); + length += (charset->num_entries) * 2; + for (i = 0; i < (charset->num_entries); i++) { + charset->data.glyphs[i] = get_card16(cff); + } + count = 0; + break; + case 1: + { + cff_range1 *ranges = NULL; + while (count > 0 && charset->num_entries < cff->num_glyphs) { + ranges = + xrealloc(ranges, + (charset->num_entries + 1) * sizeof(cff_range1)); + ranges[charset->num_entries].first = get_card16(cff); + ranges[charset->num_entries].n_left = get_card8(cff); + count -= ranges[charset->num_entries].n_left + 1; /* no-overrap */ + charset->num_entries += 1; + charset->data.range1 = ranges; + } + length += (charset->num_entries) * 3; + } + break; + case 2: + { + cff_range2 *ranges = NULL; + while (count > 0 && charset->num_entries < cff->num_glyphs) { + ranges = + xrealloc(ranges, + (charset->num_entries + 1) * sizeof(cff_range2)); + ranges[charset->num_entries].first = get_card16(cff); + ranges[charset->num_entries].n_left = get_card16(cff); + count -= ranges[charset->num_entries].n_left + 1; /* non-overrapping */ + charset->num_entries += 1; + } + charset->data.range2 = ranges; + length += (charset->num_entries) * 4; + } + break; + default: + xfree(charset); + CFF_ERROR("Unknown Charset format"); + break; + } + + if (count > 0) + CFF_ERROR("Charset data possibly broken"); + + return length; } -long cff_pack_charsets (cff_font *cff, card8 *dest, long destlen) +long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) { - long len = 0; - card16 i; - cff_charsets *charset; - - if (cff->flag & HAVE_STANDARD_CHARSETS || cff->charsets == NULL) - return 0; + long len = 0; + card16 i; + cff_charsets *charset; - if (destlen < 1) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + if (cff->flag & HAVE_STANDARD_CHARSETS || cff->charsets == NULL) + return 0; - charset = cff->charsets; + if (destlen < 1) + CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); - dest[len++] = charset->format; - switch (charset->format) { - case 0: - if (destlen < len + (charset->num_entries)*2) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); - for (i=0;i<(charset->num_entries);i++) { - s_SID sid = (charset->data).glyphs[i]; /* or CID */ - dest[len++] = (sid >> 8) & 0xff; - dest[len++] = sid & 0xff; - } - break; - case 1: - { - if (destlen < len + (charset->num_entries)*3) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); - for (i=0;i<(charset->num_entries);i++) { - dest[len++] = ((charset->data).range1[i].first >> 8) & 0xff; - dest[len++] = (charset->data).range1[i].first & 0xff; - dest[len++] = (charset->data).range1[i].n_left; - } - } - break; - case 2: - { - if (destlen < len + (charset->num_entries)*4) - CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); - for (i=0;i<(charset->num_entries);i++) { - dest[len++] = ((charset->data).range2[i].first >> 8) & 0xff; - dest[len++] = (charset->data).range2[i].first & 0xff; - dest[len++] = ((charset->data).range2[i].n_left >> 8) & 0xff; - dest[len++] = (charset->data).range2[i].n_left & 0xff; - } - } - break; - default: - CFF_ERROR("Unknown Charset format"); - break; - } + charset = cff->charsets; - return len; + dest[len++] = charset->format; + switch (charset->format) { + case 0: + if (destlen < len + (charset->num_entries) * 2) + CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + for (i = 0; i < (charset->num_entries); i++) { + s_SID sid = (charset->data).glyphs[i]; /* or CID */ + dest[len++] = (sid >> 8) & 0xff; + dest[len++] = sid & 0xff; + } + break; + case 1: + { + if (destlen < len + (charset->num_entries) * 3) + CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + for (i = 0; i < (charset->num_entries); i++) { + dest[len++] = ((charset->data).range1[i].first >> 8) & 0xff; + dest[len++] = (charset->data).range1[i].first & 0xff; + dest[len++] = (charset->data).range1[i].n_left; + } + } + break; + case 2: + { + if (destlen < len + (charset->num_entries) * 4) + CFF_ERROR("in cff_pack_charsets(): Buffer overflow"); + for (i = 0; i < (charset->num_entries); i++) { + dest[len++] = ((charset->data).range2[i].first >> 8) & 0xff; + dest[len++] = (charset->data).range2[i].first & 0xff; + dest[len++] = ((charset->data).range2[i].n_left >> 8) & 0xff; + dest[len++] = (charset->data).range2[i].n_left & 0xff; + } + } + break; + default: + CFF_ERROR("Unknown Charset format"); + break; + } + + return len; } @@ -1771,14 +1812,14 @@ static int status = CS_PARSE_CFF_ERROR; /* hintmask and cntrmask need number of stem zones */ static int num_stems = 0; -static int phase = 0; +static int phase = 0; /* subroutine nesting */ -static int cs2_nest = 0; +static int cs2_nest = 0; /* advance width */ -static int have_width = 0; -static double width = 0.0; +static int have_width = 0; +static double width = 0.0; /* * Standard Encoding Accented Characters: @@ -1787,11 +1828,11 @@ static double width = 0.0; */ #if 0 /* adx ady bchar achar endchar */ -static double seac[4] = {0.0, 0.0, 0.0, 0.0}; +static double seac[4] = { 0.0, 0.0, 0.0, 0.0 }; #endif /* Operand stack and Transient array */ -static int cs2_stack_top = 0; +static int cs2_stack_top = 0; static double cs2_arg_stack[CS_ARG_STACK_MAX]; static double trn_array[CS_TRANS_ARRAY_MAX]; @@ -1864,7 +1905,7 @@ static double trn_array[CS_TRANS_ARRAY_MAX]; /* RESERVED 19 */ #define cs_put 20 #define cs_get 21 -#define cs_ifelse 22 +#define cs_ifelse 22 #define cs_random 23 #define cs_mul 24 /* RESERVED 25 */ @@ -1884,60 +1925,59 @@ static double trn_array[CS_TRANS_ARRAY_MAX]; /* * clear_stack() put all operands sotred in operand stack to dest. */ -static void -clear_stack (card8 **dest, card8 *limit) +static void clear_stack(card8 ** dest, card8 * limit) { - int i; - - for (i = 0; i < cs2_stack_top; i++) { - double value; - long ivalue; - value = cs2_arg_stack[i]; - /* Nearest integer value */ - ivalue = (long) floor(value+0.5); - if (value >= 0x8000L || value <= (-0x8000L - 1)) { - /* - * This number cannot be represented as a single operand. - * We must use `a b mul ...' or `a c div' to represent large values. - */ - CFF_ERROR("Argument value too large. (This is bug)"); - } else if (fabs(value - ivalue) > 3.0e-5) { - /* 16.16-bit signed fixed value */ - DST_NEED(limit, *dest + 5); - *(*dest)++ = 255; - ivalue = (long) floor(value); /* mantissa */ - *(*dest)++ = (ivalue >> 8) & 0xff; - *(*dest)++ = ivalue & 0xff; - ivalue = (long)((value - ivalue) * 0x10000l); /* fraction */ - *(*dest)++ = (ivalue >> 8) & 0xff; - *(*dest)++ = ivalue & 0xff; - /* Everything else are integers. */ - } else if (ivalue >= -107 && ivalue <= 107) { - DST_NEED(limit, *dest + 1); - *(*dest)++ = ivalue + 139; - } else if (ivalue >= 108 && ivalue <= 1131) { - DST_NEED(limit, *dest + 2); - ivalue = 0xf700u + ivalue - 108; - *(*dest)++ = (ivalue >> 8) & 0xff; - *(*dest)++ = ivalue & 0xff; - } else if (ivalue >= -1131 && ivalue <= -108) { - DST_NEED(limit, *dest + 2); - ivalue = 0xfb00u - ivalue - 108; - *(*dest)++ = (ivalue >> 8) & 0xff; - *(*dest)++ = ivalue & 0xff; - } else if (ivalue >= -32768 && ivalue <= 32767) { /* shortint */ - DST_NEED(limit, *dest + 3); - *(*dest)++ = 28; - *(*dest)++ = (ivalue >> 8) & 0xff; - *(*dest)++ = (ivalue) & 0xff; - } else { /* Shouldn't come here */ - CFF_ERROR("Unexpected error."); - } - } + int i; - cs2_stack_top = 0; /* clear stack */ + for (i = 0; i < cs2_stack_top; i++) { + double value; + long ivalue; + value = cs2_arg_stack[i]; + /* Nearest integer value */ + ivalue = (long) floor(value + 0.5); + if (value >= 0x8000L || value <= (-0x8000L - 1)) { + /* + * This number cannot be represented as a single operand. + * We must use `a b mul ...' or `a c div' to represent large values. + */ + CFF_ERROR("Argument value too large. (This is bug)"); + } else if (fabs(value - ivalue) > 3.0e-5) { + /* 16.16-bit signed fixed value */ + DST_NEED(limit, *dest + 5); + *(*dest)++ = 255; + ivalue = (long) floor(value); /* mantissa */ + *(*dest)++ = (ivalue >> 8) & 0xff; + *(*dest)++ = ivalue & 0xff; + ivalue = (long) ((value - ivalue) * 0x10000l); /* fraction */ + *(*dest)++ = (ivalue >> 8) & 0xff; + *(*dest)++ = ivalue & 0xff; + /* Everything else are integers. */ + } else if (ivalue >= -107 && ivalue <= 107) { + DST_NEED(limit, *dest + 1); + *(*dest)++ = ivalue + 139; + } else if (ivalue >= 108 && ivalue <= 1131) { + DST_NEED(limit, *dest + 2); + ivalue = 0xf700u + ivalue - 108; + *(*dest)++ = (ivalue >> 8) & 0xff; + *(*dest)++ = ivalue & 0xff; + } else if (ivalue >= -1131 && ivalue <= -108) { + DST_NEED(limit, *dest + 2); + ivalue = 0xfb00u - ivalue - 108; + *(*dest)++ = (ivalue >> 8) & 0xff; + *(*dest)++ = ivalue & 0xff; + } else if (ivalue >= -32768 && ivalue <= 32767) { /* shortint */ + DST_NEED(limit, *dest + 3); + *(*dest)++ = 28; + *(*dest)++ = (ivalue >> 8) & 0xff; + *(*dest)++ = (ivalue) & 0xff; + } else { /* Shouldn't come here */ + CFF_ERROR("Unexpected error."); + } + } + + cs2_stack_top = 0; /* clear stack */ - return; + return; } /* @@ -1951,122 +1991,122 @@ clear_stack (card8 **dest, card8 *limit) */ static void -do_operator1 (card8 **dest, card8 *limit, card8 **data, card8 *endptr) +do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) { - card8 op = **data; - - *data += 1; - - switch (op) { - case cs_hstemhm: - case cs_vstemhm: - /* charstring may have hintmask if above operator have seen */ - case cs_hstem: - case cs_vstem: - if (phase == 0 && (cs2_stack_top % 2)) { - have_width = 1; - width = cs2_arg_stack[0]; - } - num_stems += cs2_stack_top/2; - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - phase = 1; - break; - case cs_hintmask: - case cs_cntrmask: - if (phase < 2) { - if (phase == 0 && (cs2_stack_top % 2)) { - have_width = 1; - width = cs2_arg_stack[0]; - } - num_stems += cs2_stack_top/2; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - if (num_stems > 0) { - int masklen = (num_stems + 7) / 8; - DST_NEED(limit, *dest + masklen); - SRC_NEED(endptr, *data + masklen); - memmove(*dest, *data, masklen); - *data += masklen; - *dest += masklen; - } - phase = 2; - break; - case cs_rmoveto: - if (phase == 0 && (cs2_stack_top % 2)) { - have_width = 1; - width = cs2_arg_stack[0]; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - phase = 2; - break; - case cs_hmoveto: - case cs_vmoveto: - if (phase == 0 && (cs2_stack_top % 2) == 0) { - have_width = 1; - width = cs2_arg_stack[0]; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - phase = 2; - break; - case cs_endchar: - if (cs2_stack_top == 1) { - have_width = 1; - width = cs2_arg_stack[0]; - clear_stack(dest, limit); - } else if (cs2_stack_top == 4 || cs2_stack_top == 5) { - WARN("\"seac\" character deprecated in Type 2 charstring."); - status = CS_PARSE_CFF_ERROR; - return; - } else if (cs2_stack_top > 0) { - WARN("Operand stack not empty."); - } - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - status = CS_CHAR_END; - break; - /* above oprators are candidate for first stack-clearing operator */ - case cs_rlineto: - case cs_hlineto: - case cs_vlineto: - case cs_rrcurveto: - case cs_rcurveline: - case cs_rlinecurve: - case cs_vvcurveto: - case cs_hhcurveto: - case cs_vhcurveto: - case cs_hvcurveto: - if (phase < 2) { - WARN("Broken Type 2 charstring."); - status = CS_PARSE_CFF_ERROR; - return; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - break; - /* all operotors above are stack-clearing operator */ - /* no output */ - case cs_return: - case cs_callgsubr: - case cs_callsubr: - CFF_ERROR("Unexpected call(g)subr/return"); - break; - default: - /* no-op ? */ - WARN("%s: Unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR, op); - status = CS_PARSE_CFF_ERROR; - break; - } + card8 op = **data; + + *data += 1; + + switch (op) { + case cs_hstemhm: + case cs_vstemhm: + /* charstring may have hintmask if above operator have seen */ + case cs_hstem: + case cs_vstem: + if (phase == 0 && (cs2_stack_top % 2)) { + have_width = 1; + width = cs2_arg_stack[0]; + } + num_stems += cs2_stack_top / 2; + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + phase = 1; + break; + case cs_hintmask: + case cs_cntrmask: + if (phase < 2) { + if (phase == 0 && (cs2_stack_top % 2)) { + have_width = 1; + width = cs2_arg_stack[0]; + } + num_stems += cs2_stack_top / 2; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + if (num_stems > 0) { + int masklen = (num_stems + 7) / 8; + DST_NEED(limit, *dest + masklen); + SRC_NEED(endptr, *data + masklen); + memmove(*dest, *data, masklen); + *data += masklen; + *dest += masklen; + } + phase = 2; + break; + case cs_rmoveto: + if (phase == 0 && (cs2_stack_top % 2)) { + have_width = 1; + width = cs2_arg_stack[0]; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + phase = 2; + break; + case cs_hmoveto: + case cs_vmoveto: + if (phase == 0 && (cs2_stack_top % 2) == 0) { + have_width = 1; + width = cs2_arg_stack[0]; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + phase = 2; + break; + case cs_endchar: + if (cs2_stack_top == 1) { + have_width = 1; + width = cs2_arg_stack[0]; + clear_stack(dest, limit); + } else if (cs2_stack_top == 4 || cs2_stack_top == 5) { + WARN("\"seac\" character deprecated in Type 2 charstring."); + status = CS_PARSE_CFF_ERROR; + return; + } else if (cs2_stack_top > 0) { + WARN("Operand stack not empty."); + } + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + status = CS_CHAR_END; + break; + /* above oprators are candidate for first stack-clearing operator */ + case cs_rlineto: + case cs_hlineto: + case cs_vlineto: + case cs_rrcurveto: + case cs_rcurveline: + case cs_rlinecurve: + case cs_vvcurveto: + case cs_hhcurveto: + case cs_vhcurveto: + case cs_hvcurveto: + if (phase < 2) { + WARN("Broken Type 2 charstring."); + status = CS_PARSE_CFF_ERROR; + return; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + break; + /* all operotors above are stack-clearing operator */ + /* no output */ + case cs_return: + case cs_callgsubr: + case cs_callsubr: + CFF_ERROR("Unexpected call(g)subr/return"); + break; + default: + /* no-op ? */ + WARN("%s: Unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR, op); + status = CS_PARSE_CFF_ERROR; + break; + } - return; + return; } /* @@ -2077,272 +2117,276 @@ do_operator1 (card8 **dest, card8 *limit, card8 **data, card8 *endptr) * random: How random ? */ static void -do_operator2 (card8 **dest, card8 *limit, card8 **data, card8 *endptr) +do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) { - card8 op; + card8 op; - *data += 1; + *data += 1; - SRC_NEED(endptr, *data + 1); + SRC_NEED(endptr, *data + 1); - op = **data; - *data += 1; + op = **data; + *data += 1; - switch(op) { - case cs_dotsection: /* deprecated */ - WARN("Operator \"dotsection\" deprecated in Type 2 charstring."); - status = CS_PARSE_CFF_ERROR; - return; - break; - case cs_hflex: - case cs_flex: - case cs_hflex1: - case cs_flex1: - if (phase < 2) { - WARN("%s: Broken Type 2 charstring.", CS_TYPE2_DEBUG_STR); - status = CS_PARSE_CFF_ERROR; - return; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 2); - *(*dest)++ = cs_escape; - *(*dest)++ = op; - break; - /* all operator above are stack-clearing */ - /* no output */ - case cs_and: - NEED(cs2_stack_top, 2); - cs2_stack_top--; - if (cs2_arg_stack[cs2_stack_top] && cs2_arg_stack[cs2_stack_top-1]) { - cs2_arg_stack[cs2_stack_top-1] = 1.0; - } else { - cs2_arg_stack[cs2_stack_top-1] = 0.0; - } - break; - case cs_or: - NEED(cs2_stack_top, 2); - cs2_stack_top--; - if (cs2_arg_stack[cs2_stack_top] || cs2_arg_stack[cs2_stack_top-1]) { - cs2_arg_stack[cs2_stack_top-1] = 1.0; - } else { - cs2_arg_stack[cs2_stack_top-1] = 0.0; - } - break; - case cs_not: - NEED(cs2_stack_top, 1); - if (cs2_arg_stack[cs2_stack_top-1]) { - cs2_arg_stack[cs2_stack_top-1] = 0.0; - } else { - cs2_arg_stack[cs2_stack_top-1] = 1.0; - } - break; - case cs_abs: - NEED(cs2_stack_top, 1); - cs2_arg_stack[cs2_stack_top-1] = fabs(cs2_arg_stack[cs2_stack_top-1]); - break; - case cs_add: - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top-2] += cs2_arg_stack[cs2_stack_top-1]; - cs2_stack_top--; - break; - case cs_sub: - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top-2] -= cs2_arg_stack[cs2_stack_top-1]; - cs2_stack_top--; - break; - case cs_div: /* doesn't check overflow */ - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top-2] /= cs2_arg_stack[cs2_stack_top-1]; - cs2_stack_top--; - break; - case cs_neg: - NEED(cs2_stack_top, 1); - cs2_arg_stack[cs2_stack_top-1] *= -1.0; - break; - case cs_eq: - NEED(cs2_stack_top, 2); - cs2_stack_top--; - if (cs2_arg_stack[cs2_stack_top] == cs2_arg_stack[cs2_stack_top-1]) { - cs2_arg_stack[cs2_stack_top-1] = 1.0; - } else { - cs2_arg_stack[cs2_stack_top-1] = 0.0; - } - break; - case cs_drop: - NEED(cs2_stack_top, 1); - cs2_stack_top--; - break; - case cs_put: - NEED(cs2_stack_top, 2); - { - int idx = (int)cs2_arg_stack[--cs2_stack_top]; - NEED(CS_TRANS_ARRAY_MAX, idx); - trn_array[idx] = cs2_arg_stack[--cs2_stack_top]; - } - break; - case cs_get: - NEED(cs2_stack_top, 1); - { - int idx = (int)cs2_arg_stack[cs2_stack_top-1]; - NEED(CS_TRANS_ARRAY_MAX, idx); - cs2_arg_stack[cs2_stack_top-1] = trn_array[idx]; - } - break; - case cs_ifelse: - NEED(cs2_stack_top, 4); - cs2_stack_top -= 3; - if (cs2_arg_stack[cs2_stack_top+1] > cs2_arg_stack[cs2_stack_top+2]) { - cs2_arg_stack[cs2_stack_top-1] = cs2_arg_stack[cs2_stack_top]; - } - break; - case cs_mul: - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top-2] = cs2_arg_stack[cs2_stack_top-2] * cs2_arg_stack[cs2_stack_top-1]; - cs2_stack_top--; - break; - case cs_sqrt: - NEED(cs2_stack_top, 1); - cs2_arg_stack[cs2_stack_top-1] = sqrt(cs2_arg_stack[cs2_stack_top-1]); - break; - case cs_dup: - NEED(cs2_stack_top, 1); - NEED(CS_ARG_STACK_MAX, cs2_stack_top+1); - cs2_arg_stack[cs2_stack_top] = cs2_arg_stack[cs2_stack_top-1]; - cs2_stack_top++; - break; - case cs_exch: - NEED(cs2_stack_top, 2); - { - double save = cs2_arg_stack[cs2_stack_top-2]; - cs2_arg_stack[cs2_stack_top-2] = cs2_arg_stack[cs2_stack_top-1]; - cs2_arg_stack[cs2_stack_top-1] = save; + switch (op) { + case cs_dotsection: /* deprecated */ + WARN("Operator \"dotsection\" deprecated in Type 2 charstring."); + status = CS_PARSE_CFF_ERROR; + return; + break; + case cs_hflex: + case cs_flex: + case cs_hflex1: + case cs_flex1: + if (phase < 2) { + WARN("%s: Broken Type 2 charstring.", CS_TYPE2_DEBUG_STR); + status = CS_PARSE_CFF_ERROR; + return; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 2); + *(*dest)++ = cs_escape; + *(*dest)++ = op; + break; + /* all operator above are stack-clearing */ + /* no output */ + case cs_and: + NEED(cs2_stack_top, 2); + cs2_stack_top--; + if (cs2_arg_stack[cs2_stack_top] && cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; + } else { + cs2_arg_stack[cs2_stack_top - 1] = 0.0; + } + break; + case cs_or: + NEED(cs2_stack_top, 2); + cs2_stack_top--; + if (cs2_arg_stack[cs2_stack_top] || cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; + } else { + cs2_arg_stack[cs2_stack_top - 1] = 0.0; + } + break; + case cs_not: + NEED(cs2_stack_top, 1); + if (cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 0.0; + } else { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; + } + break; + case cs_abs: + NEED(cs2_stack_top, 1); + cs2_arg_stack[cs2_stack_top - 1] = + fabs(cs2_arg_stack[cs2_stack_top - 1]); + break; + case cs_add: + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] += cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_sub: + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] -= cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_div: /* doesn't check overflow */ + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] /= cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_neg: + NEED(cs2_stack_top, 1); + cs2_arg_stack[cs2_stack_top - 1] *= -1.0; + break; + case cs_eq: + NEED(cs2_stack_top, 2); + cs2_stack_top--; + if (cs2_arg_stack[cs2_stack_top] == cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; + } else { + cs2_arg_stack[cs2_stack_top - 1] = 0.0; + } + break; + case cs_drop: + NEED(cs2_stack_top, 1); + cs2_stack_top--; + break; + case cs_put: + NEED(cs2_stack_top, 2); + { + int idx = (int) cs2_arg_stack[--cs2_stack_top]; + NEED(CS_TRANS_ARRAY_MAX, idx); + trn_array[idx] = cs2_arg_stack[--cs2_stack_top]; + } + break; + case cs_get: + NEED(cs2_stack_top, 1); + { + int idx = (int) cs2_arg_stack[cs2_stack_top - 1]; + NEED(CS_TRANS_ARRAY_MAX, idx); + cs2_arg_stack[cs2_stack_top - 1] = trn_array[idx]; + } + break; + case cs_ifelse: + NEED(cs2_stack_top, 4); + cs2_stack_top -= 3; + if (cs2_arg_stack[cs2_stack_top + 1] > cs2_arg_stack[cs2_stack_top + 2]) { + cs2_arg_stack[cs2_stack_top - 1] = cs2_arg_stack[cs2_stack_top]; + } + break; + case cs_mul: + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] = + cs2_arg_stack[cs2_stack_top - 2] * cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_sqrt: + NEED(cs2_stack_top, 1); + cs2_arg_stack[cs2_stack_top - 1] = + sqrt(cs2_arg_stack[cs2_stack_top - 1]); + break; + case cs_dup: + NEED(cs2_stack_top, 1); + NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); + cs2_arg_stack[cs2_stack_top] = cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top++; + break; + case cs_exch: + NEED(cs2_stack_top, 2); + { + double save = cs2_arg_stack[cs2_stack_top - 2]; + cs2_arg_stack[cs2_stack_top - 2] = cs2_arg_stack[cs2_stack_top - 1]; + cs2_arg_stack[cs2_stack_top - 1] = save; + } + break; + case cs_index: + NEED(cs2_stack_top, 2); /* need two arguments at least */ + { + int idx = (int) cs2_arg_stack[cs2_stack_top - 1]; + if (idx < 0) { + cs2_arg_stack[cs2_stack_top - 1] = + cs2_arg_stack[cs2_stack_top - 2]; + } else { + NEED(cs2_stack_top, idx + 2); + cs2_arg_stack[cs2_stack_top - 1] = + cs2_arg_stack[cs2_stack_top - idx - 2]; + } + } + break; + case cs_roll: + NEED(cs2_stack_top, 2); + { + int N, J; + J = (int) cs2_arg_stack[--cs2_stack_top]; + N = (int) cs2_arg_stack[--cs2_stack_top]; + NEED(cs2_stack_top, N); + if (J > 0) { + J = J % N; + while (J-- > 0) { + double save = cs2_arg_stack[cs2_stack_top - 1]; + int i = cs2_stack_top - 1; + while (i > cs2_stack_top - N) { + cs2_arg_stack[i] = cs2_arg_stack[i - 1]; + i--; + } + cs2_arg_stack[i] = save; + } + } else { + J = (-J) % N; + while (J-- > 0) { + double save = cs2_arg_stack[cs2_stack_top - N]; + int i = cs2_stack_top - N; + while (i < cs2_stack_top - 1) { + cs2_arg_stack[i] = cs2_arg_stack[i + 1]; + i++; + } + cs2_arg_stack[i] = save; + } + } + } + break; + case cs_random: + WARN("%s: Charstring operator \"random\" found.", CS_TYPE2_DEBUG_STR); + NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); + cs2_arg_stack[cs2_stack_top++] = 1.0; + break; + default: + /* no-op ? */ + WARN("%s: Unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR, + op); + status = CS_PARSE_CFF_ERROR; + break; } - break; - case cs_index: - NEED(cs2_stack_top, 2); /* need two arguments at least */ - { - int idx = (int)cs2_arg_stack[cs2_stack_top-1]; - if (idx < 0) { - cs2_arg_stack[cs2_stack_top-1] = cs2_arg_stack[cs2_stack_top-2]; - } else { - NEED(cs2_stack_top, idx+2); - cs2_arg_stack[cs2_stack_top-1] = cs2_arg_stack[cs2_stack_top-idx-2]; - } - } - break; - case cs_roll: - NEED(cs2_stack_top, 2); - { - int N, J; - J = (int)cs2_arg_stack[--cs2_stack_top]; - N = (int)cs2_arg_stack[--cs2_stack_top]; - NEED(cs2_stack_top, N); - if (J > 0) { - J = J % N; - while (J-- > 0) { - double save = cs2_arg_stack[cs2_stack_top-1]; - int i = cs2_stack_top - 1; - while (i > cs2_stack_top-N) { - cs2_arg_stack[i] = cs2_arg_stack[i-1]; - i--; - } - cs2_arg_stack[i] = save; - } - } else { - J = (-J) % N; - while (J-- > 0) { - double save = cs2_arg_stack[cs2_stack_top-N]; - int i = cs2_stack_top - N; - while (i < cs2_stack_top-1) { - cs2_arg_stack[i] = cs2_arg_stack[i+1]; - i++; - } - cs2_arg_stack[i] = save; - } - } - } - break; - case cs_random: - WARN("%s: Charstring operator \"random\" found.", CS_TYPE2_DEBUG_STR); - NEED(CS_ARG_STACK_MAX, cs2_stack_top+1); - cs2_arg_stack[cs2_stack_top++] = 1.0; - break; - default: - /* no-op ? */ - WARN("%s: Unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR, op); - status = CS_PARSE_CFF_ERROR; - break; - } - return; + return; } /* * integer: * exactly the same as the DICT encoding (except 29) */ -static void -cs2_get_integer (card8 **data, card8 *endptr) +static void cs2_get_integer(card8 ** data, card8 * endptr) { - long result = 0; - card8 b0 = **data, b1, b2; - - *data += 1; - - if (b0 == 28) { /* shortint */ - SRC_NEED(endptr, *data + 2); - b1 = **data; - b2 = *(*data+1); - result = b1*256+b2; - if (result > 0x7fff) - result -= 0x10000L; - *data += 2; - } else if (b0 >= 32 && b0 <= 246) { /* int (1) */ - result = b0 - 139; - } else if (b0 >= 247 && b0 <= 250) { /* int (2) */ - SRC_NEED(endptr, *data + 1); - b1 = **data; - result = (b0-247)*256+b1+108; - *data += 1; - } else if (b0 >= 251 && b0 <= 254) { - SRC_NEED(endptr, *data + 1); - b1 = **data; - result = -(b0-251)*256-b1-108; + long result = 0; + card8 b0 = **data, b1, b2; + *data += 1; - } else { - status = CS_PARSE_CFF_ERROR; - return; - } - NEED(CS_ARG_STACK_MAX, cs2_stack_top+1); - cs2_arg_stack[cs2_stack_top++] = (double) result; + if (b0 == 28) { /* shortint */ + SRC_NEED(endptr, *data + 2); + b1 = **data; + b2 = *(*data + 1); + result = b1 * 256 + b2; + if (result > 0x7fff) + result -= 0x10000L; + *data += 2; + } else if (b0 >= 32 && b0 <= 246) { /* int (1) */ + result = b0 - 139; + } else if (b0 >= 247 && b0 <= 250) { /* int (2) */ + SRC_NEED(endptr, *data + 1); + b1 = **data; + result = (b0 - 247) * 256 + b1 + 108; + *data += 1; + } else if (b0 >= 251 && b0 <= 254) { + SRC_NEED(endptr, *data + 1); + b1 = **data; + result = -(b0 - 251) * 256 - b1 - 108; + *data += 1; + } else { + status = CS_PARSE_CFF_ERROR; + return; + } + + NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); + cs2_arg_stack[cs2_stack_top++] = (double) result; - return; + return; } /* * Signed 16.16-bits fixed number for Type 2 charstring encoding */ -static void -get_fixed (card8 **data, card8 *endptr) +static void get_fixed(card8 ** data, card8 * endptr) { - long ivalue; - double rvalue; + long ivalue; + double rvalue; - *data += 1; + *data += 1; - SRC_NEED(endptr, *data + 4); + SRC_NEED(endptr, *data + 4); - ivalue = *(*data) * 0x100 + *(*data+1); - rvalue = (ivalue > 0x7fffL) ? (ivalue - 0x10000L) : ivalue; - ivalue = *(*data+2) * 0x100 + *(*data+3); - rvalue += ((double) ivalue) / 0x10000L; + ivalue = *(*data) * 0x100 + *(*data + 1); + rvalue = (ivalue > 0x7fffL) ? (ivalue - 0x10000L) : ivalue; + ivalue = *(*data + 2) * 0x100 + *(*data + 3); + rvalue += ((double) ivalue) / 0x10000L; - NEED(CS_ARG_STACK_MAX, cs2_stack_top+1); - cs2_arg_stack[cs2_stack_top++] = rvalue; - *data += 4; + NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); + cs2_arg_stack[cs2_stack_top++] = rvalue; + *data += 4; - return; + return; } /* @@ -2354,32 +2398,33 @@ get_fixed (card8 **data, card8 *endptr) * subr_idx: CFF INDEX data that contains subroutines. * id: biased subroutine number. */ -static void -get_subr (card8 **subr, long *len, cff_index *subr_idx, long id) +static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id) { - card16 count; + card16 count; - if (subr_idx == NULL) - CFF_ERROR("%s: Subroutine called but no subroutine found.", CS_TYPE2_DEBUG_STR); + if (subr_idx == NULL) + CFF_ERROR("%s: Subroutine called but no subroutine found.", + CS_TYPE2_DEBUG_STR); - count = subr_idx->count; + count = subr_idx->count; - /* Adding bias number */ - if (count < 1240) { - id += 107; - } else if (count < 33900) { - id += 1131; - } else { - id += 32768; - } + /* Adding bias number */ + if (count < 1240) { + id += 107; + } else if (count < 33900) { + id += 1131; + } else { + id += 32768; + } - if (id > count) - CFF_ERROR("%s: Invalid Subr index: %ld (max=%u)", CS_TYPE2_DEBUG_STR, id, count); + if (id > count) + CFF_ERROR("%s: Invalid Subr index: %ld (max=%u)", CS_TYPE2_DEBUG_STR, + id, count); - *len = (subr_idx->offset)[id + 1] - (subr_idx->offset)[id]; - *subr = subr_idx->data + (subr_idx->offset)[id] - 1; + *len = (subr_idx->offset)[id + 1] - (subr_idx->offset)[id]; + *subr = subr_idx->data + (subr_idx->offset)[id] - 1; - return; + return; } /* @@ -2390,112 +2435,115 @@ get_subr (card8 **subr, long *len, cff_index *subr_idx, long id) */ static void -do_charstring (card8 **dest, card8 *limit, - card8 **data, card8 *endptr, - cff_index *gsubr_idx, cff_index *subr_idx) +do_charstring(card8 ** dest, card8 * limit, + card8 ** data, card8 * endptr, + cff_index * gsubr_idx, cff_index * subr_idx) { - card8 b0 = 0, *subr; - long len; - - if (cs2_nest > CS_SUBR_NEST_MAX) - CFF_ERROR("%s: Subroutine nested too deeply.", CS_TYPE2_DEBUG_STR); - - cs2_nest++; - - while (*data < endptr && status == CS_PARSE_OK) { - b0 = **data; - if (b0 == 255) { /* 16-bit.16-bit fixed signed number */ - get_fixed(data, endptr); - } else if (b0 == cs_return) { - status = CS_SUBR_RETURN; - } else if (b0 == cs_callgsubr) { - if (cs2_stack_top < 1) { - status = CS_STACK_CFF_ERROR; - } else { - cs2_stack_top--; - get_subr(&subr, &len, gsubr_idx, (long) cs2_arg_stack[cs2_stack_top]); - if (*dest + len > limit) - CFF_ERROR("%s: Possible buffer overflow.", CS_TYPE2_DEBUG_STR); - do_charstring(dest, limit, &subr, subr + len, - gsubr_idx, subr_idx); - *data += 1; - } - } else if (b0 == cs_callsubr) { - if (cs2_stack_top < 1) { - status = CS_STACK_CFF_ERROR; - } else { - cs2_stack_top--; - get_subr(&subr, &len, subr_idx, (long) cs2_arg_stack[cs2_stack_top]); - if (limit < *dest + len) - CFF_ERROR("%s: Possible buffer overflow.", CS_TYPE2_DEBUG_STR); - do_charstring(dest, limit, &subr, subr + len, - gsubr_idx, subr_idx); - *data += 1; - } - } else if (b0 == cs_escape) { - do_operator2(dest, limit, data, endptr); - } else if (b0 < 32 && b0 != 28) { /* 19, 20 need mask */ - do_operator1(dest, limit, data, endptr); - } else if ((b0 <= 22 && b0 >= 27) || b0 == 31) { /* reserved */ - status = CS_PARSE_CFF_ERROR; /* not an error ? */ - } else { /* integer */ - cs2_get_integer(data, endptr); - } - } - - if (status == CS_SUBR_RETURN) { - status = CS_PARSE_OK; - } else if (status == CS_CHAR_END && *data < endptr) { - WARN("%s: Garbage after endchar.", CS_TYPE2_DEBUG_STR); - } else if (status < CS_PARSE_OK) { /* error */ - CFF_ERROR("%s: Parsing charstring failed: (status=%d, stack=%d)", - CS_TYPE2_DEBUG_STR, status, cs2_stack_top); - } - - cs2_nest--; + card8 b0 = 0, *subr; + long len; + + if (cs2_nest > CS_SUBR_NEST_MAX) + CFF_ERROR("%s: Subroutine nested too deeply.", CS_TYPE2_DEBUG_STR); + + cs2_nest++; + + while (*data < endptr && status == CS_PARSE_OK) { + b0 = **data; + if (b0 == 255) { /* 16-bit.16-bit fixed signed number */ + get_fixed(data, endptr); + } else if (b0 == cs_return) { + status = CS_SUBR_RETURN; + } else if (b0 == cs_callgsubr) { + if (cs2_stack_top < 1) { + status = CS_STACK_CFF_ERROR; + } else { + cs2_stack_top--; + get_subr(&subr, &len, gsubr_idx, + (long) cs2_arg_stack[cs2_stack_top]); + if (*dest + len > limit) + CFF_ERROR("%s: Possible buffer overflow.", + CS_TYPE2_DEBUG_STR); + do_charstring(dest, limit, &subr, subr + len, gsubr_idx, + subr_idx); + *data += 1; + } + } else if (b0 == cs_callsubr) { + if (cs2_stack_top < 1) { + status = CS_STACK_CFF_ERROR; + } else { + cs2_stack_top--; + get_subr(&subr, &len, subr_idx, + (long) cs2_arg_stack[cs2_stack_top]); + if (limit < *dest + len) + CFF_ERROR("%s: Possible buffer overflow.", + CS_TYPE2_DEBUG_STR); + do_charstring(dest, limit, &subr, subr + len, gsubr_idx, + subr_idx); + *data += 1; + } + } else if (b0 == cs_escape) { + do_operator2(dest, limit, data, endptr); + } else if (b0 < 32 && b0 != 28) { /* 19, 20 need mask */ + do_operator1(dest, limit, data, endptr); + } else if ((b0 <= 22 && b0 >= 27) || b0 == 31) { /* reserved */ + status = CS_PARSE_CFF_ERROR; /* not an error ? */ + } else { /* integer */ + cs2_get_integer(data, endptr); + } + } + + if (status == CS_SUBR_RETURN) { + status = CS_PARSE_OK; + } else if (status == CS_CHAR_END && *data < endptr) { + WARN("%s: Garbage after endchar.", CS_TYPE2_DEBUG_STR); + } else if (status < CS_PARSE_OK) { /* error */ + CFF_ERROR("%s: Parsing charstring failed: (status=%d, stack=%d)", + CS_TYPE2_DEBUG_STR, status, cs2_stack_top); + } + + cs2_nest--; - return; + return; } -static void -cs_parse_init (void) +static void cs_parse_init(void) { - status = CS_PARSE_OK; - cs2_nest = 0; - phase = 0; - num_stems = 0; - cs2_stack_top = 0; + status = CS_PARSE_OK; + cs2_nest = 0; + phase = 0; + num_stems = 0; + cs2_stack_top = 0; } /* * Not just copying... */ long -cs_copy_charstring (card8 *dst, long dstlen, - card8 *src, long srclen, - cff_index *gsubr, cff_index *subr, - double default_width, double nominal_width, cs_ginfo *ginfo) +cs_copy_charstring(card8 * dst, long dstlen, + card8 * src, long srclen, + cff_index * gsubr, cff_index * subr, + double default_width, double nominal_width, cs_ginfo * ginfo) { - card8 *save = dst; + card8 *save = dst; - cs_parse_init(); + cs_parse_init(); - width = 0.0; - have_width = 0; + width = 0.0; + have_width = 0; - /* expand call(g)subrs */ - do_charstring(&dst, dst + dstlen, &src, src + srclen, gsubr, subr); + /* expand call(g)subrs */ + do_charstring(&dst, dst + dstlen, &src, src + srclen, gsubr, subr); - if (ginfo) { - ginfo->flags = 0; /* not used */ - if (have_width) { - ginfo->wx = nominal_width + width; - } else { - ginfo->wx = default_width; + if (ginfo) { + ginfo->flags = 0; /* not used */ + if (have_width) { + ginfo->wx = nominal_width + width; + } else { + ginfo->wx = default_width; + } } - } - return (long)(dst - save); + return (long) (dst - save); } /* encodings */ @@ -2505,243 +2553,244 @@ cs_copy_charstring (card8 *dst, long dstlen, * * Encoding and Charset arrays always begin with GID = 1. */ -long cff_read_encoding (cff_font *cff) +long cff_read_encoding(cff_font * cff) { - cff_encoding *encoding; - long offset, length; - card8 i; + cff_encoding *encoding; + long offset, length; + card8 i; - if (cff->topdict == NULL) { - CFF_ERROR("Top DICT data not found"); - } + if (cff->topdict == NULL) { + CFF_ERROR("Top DICT data not found"); + } - if (!cff_dict_known(cff->topdict, "Encoding")) { - cff->flag |= ENCODING_STANDARD; - cff->encoding = NULL; - return 0; - } + if (!cff_dict_known(cff->topdict, "Encoding")) { + cff->flag |= ENCODING_STANDARD; + cff->encoding = NULL; + return 0; + } - offset = (long) cff_dict_get(cff->topdict, "Encoding", 0); - if (offset == 0) { /* predefined */ - cff->flag |= ENCODING_STANDARD; - cff->encoding = NULL; - return 0; - } else if (offset == 1) { - cff->flag |= ENCODING_EXPERT; - cff->encoding = NULL; - return 0; - } + offset = (long) cff_dict_get(cff->topdict, "Encoding", 0); + if (offset == 0) { /* predefined */ + cff->flag |= ENCODING_STANDARD; + cff->encoding = NULL; + return 0; + } else if (offset == 1) { + cff->flag |= ENCODING_EXPERT; + cff->encoding = NULL; + return 0; + } - cff->offset= offset; - cff->encoding = encoding = xcalloc(1, sizeof(cff_encoding)); - encoding->format = get_card8(cff); - length = 1; - - switch (encoding->format & (~0x80)) { - case 0: - encoding->num_entries = get_card8(cff); - (encoding->data).codes = xcalloc(encoding->num_entries, sizeof(card8)); - for (i=0;i<(encoding->num_entries);i++) { - (encoding->data).codes[i] = get_card8(cff); - } - length += encoding->num_entries + 1; - break; - case 1: - { - cff_range1 *ranges; - encoding->num_entries = get_card8(cff); - encoding->data.range1 = ranges - = xcalloc(encoding->num_entries, sizeof(cff_range1)); - for (i=0;i<(encoding->num_entries);i++) { - ranges[i].first = get_card8(cff); - ranges[i].n_left = get_card8(cff); - } - length += (encoding->num_entries) * 2 + 1; - } - break; - default: - xfree(encoding); - CFF_ERROR("Unknown Encoding format"); - break; - } + cff->offset = offset; + cff->encoding = encoding = xcalloc(1, sizeof(cff_encoding)); + encoding->format = get_card8(cff); + length = 1; - /* Supplementary data */ - if ((encoding->format) & 0x80) { - cff_map *map; - encoding->num_supps = get_card8(cff); - encoding->supp = map = xcalloc(encoding->num_supps, sizeof(cff_map)); - for (i=0;i<(encoding->num_supps);i++) { - map[i].code = get_card8(cff); - map[i].glyph = get_card16(cff); /* SID */ - } - length += (encoding->num_supps) * 3 + 1; - } else { - encoding->num_supps = 0; - encoding->supp = NULL; - } + switch (encoding->format & (~0x80)) { + case 0: + encoding->num_entries = get_card8(cff); + (encoding->data).codes = xcalloc(encoding->num_entries, sizeof(card8)); + for (i = 0; i < (encoding->num_entries); i++) { + (encoding->data).codes[i] = get_card8(cff); + } + length += encoding->num_entries + 1; + break; + case 1: + { + cff_range1 *ranges; + encoding->num_entries = get_card8(cff); + encoding->data.range1 = ranges + = xcalloc(encoding->num_entries, sizeof(cff_range1)); + for (i = 0; i < (encoding->num_entries); i++) { + ranges[i].first = get_card8(cff); + ranges[i].n_left = get_card8(cff); + } + length += (encoding->num_entries) * 2 + 1; + } + break; + default: + xfree(encoding); + CFF_ERROR("Unknown Encoding format"); + break; + } + + /* Supplementary data */ + if ((encoding->format) & 0x80) { + cff_map *map; + encoding->num_supps = get_card8(cff); + encoding->supp = map = xcalloc(encoding->num_supps, sizeof(cff_map)); + for (i = 0; i < (encoding->num_supps); i++) { + map[i].code = get_card8(cff); + map[i].glyph = get_card16(cff); /* SID */ + } + length += (encoding->num_supps) * 3 + 1; + } else { + encoding->num_supps = 0; + encoding->supp = NULL; + } - return length; + return length; } -long cff_pack_encoding (cff_font *cff, card8 *dest, long destlen) +long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) { - long len = 0; - cff_encoding *encoding; - card16 i; + long len = 0; + cff_encoding *encoding; + card16 i; - if (cff->flag & HAVE_STANDARD_ENCODING || cff->encoding == NULL) - return 0; + if (cff->flag & HAVE_STANDARD_ENCODING || cff->encoding == NULL) + return 0; - if (destlen < 2) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); - - encoding = cff->encoding; - - dest[len++] = encoding->format; - dest[len++] = encoding->num_entries; - switch (encoding->format & (~0x80)) { - case 0: - if (destlen < len + encoding->num_entries) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); - for (i=0;i<(encoding->num_entries);i++) { - dest[len++] = (encoding->data).codes[i]; - } - break; - case 1: - { - if (destlen < len + (encoding->num_entries)*2) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); - for (i=0;i<(encoding->num_entries);i++) { - dest[len++] = (encoding->data).range1[i].first & 0xff; - dest[len++] = (encoding->data).range1[i].n_left; - } - } - break; - default: - CFF_ERROR("Unknown Encoding format"); - break; - } + if (destlen < 2) + CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); - if ((encoding->format) & 0x80) { - if (destlen < len + (encoding->num_supps)*3 + 1) - CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); - dest[len++] = encoding->num_supps; - for (i=0;i<(encoding->num_supps);i++) { - dest[len++] = (encoding->supp)[i].code; - dest[len++] = ((encoding->supp)[i].glyph >> 8) & 0xff; - dest[len++] = (encoding->supp)[i].glyph & 0xff; - } - } + encoding = cff->encoding; - return len; + dest[len++] = encoding->format; + dest[len++] = encoding->num_entries; + switch (encoding->format & (~0x80)) { + case 0: + if (destlen < len + encoding->num_entries) + CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); + for (i = 0; i < (encoding->num_entries); i++) { + dest[len++] = (encoding->data).codes[i]; + } + break; + case 1: + { + if (destlen < len + (encoding->num_entries) * 2) + CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); + for (i = 0; i < (encoding->num_entries); i++) { + dest[len++] = (encoding->data).range1[i].first & 0xff; + dest[len++] = (encoding->data).range1[i].n_left; + } + } + break; + default: + CFF_ERROR("Unknown Encoding format"); + break; + } + + if ((encoding->format) & 0x80) { + if (destlen < len + (encoding->num_supps) * 3 + 1) + CFF_ERROR("in cff_pack_encoding(): Buffer overflow"); + dest[len++] = encoding->num_supps; + for (i = 0; i < (encoding->num_supps); i++) { + dest[len++] = (encoding->supp)[i].code; + dest[len++] = ((encoding->supp)[i].glyph >> 8) & 0xff; + dest[len++] = (encoding->supp)[i].glyph & 0xff; + } + } + + return len; } /* CID-Keyed font specific */ -long cff_read_fdselect (cff_font *cff) +long cff_read_fdselect(cff_font * cff) { - cff_fdselect *fdsel; - long offset, length; - card16 i; - - if (cff->topdict == NULL) - CFF_ERROR("Top DICT not available"); - - if (!(cff->flag & FONTTYPE_CIDFONT)) - return 0; - - offset = (long) cff_dict_get(cff->topdict, "FDSelect", 0); - cff->offset = offset; - cff->fdselect = fdsel = xcalloc(1, sizeof(cff_fdselect)); - fdsel->format = get_card8(cff); - - length = 1; - - switch (fdsel->format) { - case 0: - fdsel->num_entries = cff->num_glyphs; - (fdsel->data).fds = xcalloc(fdsel->num_entries, sizeof(card8)); - for (i=0;i<(fdsel->num_entries);i++) { - (fdsel->data).fds[i] = get_card8(cff); - } - length += fdsel->num_entries; - break; - case 3: - { - cff_range3 *ranges; - fdsel->num_entries = get_card16(cff); - fdsel->data.ranges = ranges = xcalloc(fdsel->num_entries, sizeof(cff_range3)); - for (i=0;i<(fdsel->num_entries);i++) { - ranges[i].first = get_card16(cff); - ranges[i].fd = get_card8(cff); - } - if (ranges[0].first != 0) - CFF_ERROR("Range not starting with 0."); - if (cff->num_glyphs != get_card16(cff)) - CFF_ERROR("Sentinel value mismatched with number of glyphs."); - length += (fdsel->num_entries) * 3 + 4; - } - break; - default: - xfree(fdsel); - CFF_ERROR("Unknown FDSelect format."); - break; - } - - return length; + cff_fdselect *fdsel; + long offset, length; + card16 i; + + if (cff->topdict == NULL) + CFF_ERROR("Top DICT not available"); + + if (!(cff->flag & FONTTYPE_CIDFONT)) + return 0; + + offset = (long) cff_dict_get(cff->topdict, "FDSelect", 0); + cff->offset = offset; + cff->fdselect = fdsel = xcalloc(1, sizeof(cff_fdselect)); + fdsel->format = get_card8(cff); + + length = 1; + + switch (fdsel->format) { + case 0: + fdsel->num_entries = cff->num_glyphs; + (fdsel->data).fds = xcalloc(fdsel->num_entries, sizeof(card8)); + for (i = 0; i < (fdsel->num_entries); i++) { + (fdsel->data).fds[i] = get_card8(cff); + } + length += fdsel->num_entries; + break; + case 3: + { + cff_range3 *ranges; + fdsel->num_entries = get_card16(cff); + fdsel->data.ranges = ranges = + xcalloc(fdsel->num_entries, sizeof(cff_range3)); + for (i = 0; i < (fdsel->num_entries); i++) { + ranges[i].first = get_card16(cff); + ranges[i].fd = get_card8(cff); + } + if (ranges[0].first != 0) + CFF_ERROR("Range not starting with 0."); + if (cff->num_glyphs != get_card16(cff)) + CFF_ERROR("Sentinel value mismatched with number of glyphs."); + length += (fdsel->num_entries) * 3 + 4; + } + break; + default: + xfree(fdsel); + CFF_ERROR("Unknown FDSelect format."); + break; + } + + return length; } -long cff_pack_fdselect (cff_font *cff, card8 *dest, long destlen) +long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) { - cff_fdselect *fdsel; - long len = 0; - card16 i; - - if (cff->fdselect == NULL) - return 0; + cff_fdselect *fdsel; + long len = 0; + card16 i; - if (destlen < 1) - CFF_ERROR("in cff_pack_fdselect(): Buffur overflow"); - - fdsel = cff->fdselect; - - dest[len++] = fdsel->format; - switch (fdsel->format) { - case 0: - if (fdsel->num_entries != cff->num_glyphs) - CFF_ERROR("in cff_pack_fdselect(): Invalid data"); - if (destlen < len + fdsel->num_entries) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); - for (i=0;inum_entries;i++) { - dest[len++] = (fdsel->data).fds[i]; - } - break; - case 3: - { - if (destlen < len + 2) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); - len += 2; - for (i=0;i<(fdsel->num_entries);i++) { - if (destlen < len + 3) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); - dest[len++] = ((fdsel->data).ranges[i].first >> 8) & 0xff; - dest[len++] = (fdsel->data).ranges[i].first & 0xff; - dest[len++] = (fdsel->data).ranges[i].fd; - } - if (destlen < len + 2) - CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); - dest[len++] = (cff->num_glyphs >> 8) & 0xff; - dest[len++] = cff->num_glyphs & 0xff; - dest[1] = ((len/3 - 1) >> 8) & 0xff; - dest[2] = (len/3 - 1) & 0xff; - } - break; - default: - CFF_ERROR("Unknown FDSelect format."); - break; - } + if (cff->fdselect == NULL) + return 0; - return len; + if (destlen < 1) + CFF_ERROR("in cff_pack_fdselect(): Buffur overflow"); + + fdsel = cff->fdselect; + + dest[len++] = fdsel->format; + switch (fdsel->format) { + case 0: + if (fdsel->num_entries != cff->num_glyphs) + CFF_ERROR("in cff_pack_fdselect(): Invalid data"); + if (destlen < len + fdsel->num_entries) + CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + for (i = 0; i < fdsel->num_entries; i++) { + dest[len++] = (fdsel->data).fds[i]; + } + break; + case 3: + { + if (destlen < len + 2) + CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + len += 2; + for (i = 0; i < (fdsel->num_entries); i++) { + if (destlen < len + 3) + CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + dest[len++] = ((fdsel->data).ranges[i].first >> 8) & 0xff; + dest[len++] = (fdsel->data).ranges[i].first & 0xff; + dest[len++] = (fdsel->data).ranges[i].fd; + } + if (destlen < len + 2) + CFF_ERROR("in cff_pack_fdselect(): Buffer overflow"); + dest[len++] = (cff->num_glyphs >> 8) & 0xff; + dest[len++] = cff->num_glyphs & 0xff; + dest[1] = ((len / 3 - 1) >> 8) & 0xff; + dest[2] = (len / 3 - 1) & 0xff; + } + break; + default: + CFF_ERROR("Unknown FDSelect format."); + break; + } + + return len; } @@ -2749,335 +2798,334 @@ long cff_pack_fdselect (cff_font *cff, card8 *dest, long destlen) /* * Create an instance of embeddable font. */ -static void -write_fontfile (cff_font *cffont, char *fullname) +static void write_fontfile(cff_font * cffont, char *fullname) { - cff_index *topdict, *fdarray, *private; - unsigned char *dest; - long destlen = 0, i, size; - long offset, topdict_offset, fdarray_offset; - - /* DICT sizes (offset set to long int) */ - topdict = cff_new_index(1); - fdarray = cff_new_index(cffont->num_fds); - private = cff_new_index(cffont->num_fds); - - cff_dict_remove(cffont->topdict, "UniqueID"); - cff_dict_remove(cffont->topdict, "XUID"); - cff_dict_remove(cffont->topdict, "Private"); /* some bad font may have */ - cff_dict_remove(cffont->topdict, "Encoding"); /* some bad font may have */ - - topdict->offset[1] = cff_dict_pack(cffont->topdict, - (card8 *) work_buffer, - WORK_BUFFER_SIZE) + 1; - for (i = 0;i < cffont->num_fds; i++) { - size = 0; - if (cffont->private && cffont->private[i]) { - size = cff_dict_pack(cffont->private[i], - (card8 *) work_buffer, WORK_BUFFER_SIZE); - if (size < 1) { /* Private had contained only Subr */ - cff_dict_remove(cffont->fdarray[i], "Private"); - } - } - (private->offset)[i+1] = (private->offset)[i] + size; - (fdarray->offset)[i+1] = (fdarray->offset)[i] + - cff_dict_pack(cffont->fdarray[i], - (card8 *) work_buffer, WORK_BUFFER_SIZE); - } - - destlen = 4; /* header size */ - destlen += cff_set_name(cffont, fullname); - destlen += cff_index_size(topdict); - destlen += cff_index_size(cffont->string); - destlen += cff_index_size(cffont->gsubr); - destlen += (cffont->charsets->num_entries) * 2 + 1; /* charset format 0 */ - destlen += (cffont->fdselect->num_entries) * 3 + 5; /* fdselect format 3 */ - destlen += cff_index_size(cffont->cstrings); - destlen += cff_index_size(fdarray); - destlen += private->offset[private->count] - 1; /* Private is not INDEX */ - - dest = xcalloc(destlen, sizeof(card8)); - - offset = 0; - /* Header */ - offset += cff_put_header(cffont, dest + offset, destlen - offset); - /* Name */ - offset += cff_pack_index(cffont->name, dest + offset, destlen - offset); - /* Top DICT */ - topdict_offset = offset; - offset += cff_index_size(topdict); - /* Strings */ - offset += cff_pack_index(cffont->string, dest + offset, destlen - offset); - /* Global Subrs */ - offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset); - - /* charset */ - cff_dict_set(cffont->topdict, "charset", 0, offset); - offset += cff_pack_charsets(cffont, dest + offset, destlen - offset); - - /* FDSelect */ - cff_dict_set(cffont->topdict, "FDSelect", 0, offset); - offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset); - - /* CharStrings */ - cff_dict_set(cffont->topdict, "CharStrings", 0, offset); - offset += cff_pack_index(cffont->cstrings, - dest + offset, cff_index_size(cffont->cstrings)); - cff_release_index(cffont->cstrings); - cffont->cstrings = NULL; /* Charstrings cosumes huge memory */ - - /* FDArray and Private */ - cff_dict_set(cffont->topdict, "FDArray", 0, offset); - fdarray_offset = offset; - offset += cff_index_size(fdarray); - - fdarray->data = xcalloc(fdarray->offset[fdarray->count] - 1, sizeof(card8)); - for (i = 0; i < cffont->num_fds; i++) { - size = private->offset[i+1] - private->offset[i]; - if (cffont->private[i] && size > 0) { - cff_dict_pack(cffont->private[i], dest + offset, size); - cff_dict_set(cffont->fdarray[i], "Private", 0, size); - cff_dict_set(cffont->fdarray[i], "Private", 1, offset); - } - cff_dict_pack(cffont->fdarray[i], - fdarray->data + (fdarray->offset)[i] - 1, - fdarray->offset[fdarray->count] - 1); - offset += size; - } - - cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray)); - cff_release_index(fdarray); - cff_release_index(private); - - /* Finally Top DICT */ - topdict->data = xcalloc(topdict->offset[topdict->count] - 1, sizeof(card8)); - cff_dict_pack(cffont->topdict, - topdict->data, topdict->offset[topdict->count] - 1); - cff_pack_index(topdict, dest + topdict_offset, cff_index_size(topdict)); - cff_release_index(topdict); - - for (i = 0; i < offset; i++) - fb_putchar (dest[i]); - - /*fprintf(stdout," (%i/%i)",offset,cffont->stream_size);*/ - xfree(dest); - return ; + cff_index *topdict, *fdarray, *private; + unsigned char *dest; + long destlen = 0, i, size; + long offset, topdict_offset, fdarray_offset; + + /* DICT sizes (offset set to long int) */ + topdict = cff_new_index(1); + fdarray = cff_new_index(cffont->num_fds); + private = cff_new_index(cffont->num_fds); + + cff_dict_remove(cffont->topdict, "UniqueID"); + cff_dict_remove(cffont->topdict, "XUID"); + cff_dict_remove(cffont->topdict, "Private"); /* some bad font may have */ + cff_dict_remove(cffont->topdict, "Encoding"); /* some bad font may have */ + + topdict->offset[1] = cff_dict_pack(cffont->topdict, + (card8 *) work_buffer, + WORK_BUFFER_SIZE) + 1; + for (i = 0; i < cffont->num_fds; i++) { + size = 0; + if (cffont->private && cffont->private[i]) { + size = cff_dict_pack(cffont->private[i], + (card8 *) work_buffer, WORK_BUFFER_SIZE); + if (size < 1) { /* Private had contained only Subr */ + cff_dict_remove(cffont->fdarray[i], "Private"); + } + } + (private->offset)[i + 1] = (private->offset)[i] + size; + (fdarray->offset)[i + 1] = (fdarray->offset)[i] + + cff_dict_pack(cffont->fdarray[i], + (card8 *) work_buffer, WORK_BUFFER_SIZE); + } + + destlen = 4; /* header size */ + destlen += cff_set_name(cffont, fullname); + destlen += cff_index_size(topdict); + destlen += cff_index_size(cffont->string); + destlen += cff_index_size(cffont->gsubr); + destlen += (cffont->charsets->num_entries) * 2 + 1; /* charset format 0 */ + destlen += (cffont->fdselect->num_entries) * 3 + 5; /* fdselect format 3 */ + destlen += cff_index_size(cffont->cstrings); + destlen += cff_index_size(fdarray); + destlen += private->offset[private->count] - 1; /* Private is not INDEX */ + + dest = xcalloc(destlen, sizeof(card8)); + + offset = 0; + /* Header */ + offset += cff_put_header(cffont, dest + offset, destlen - offset); + /* Name */ + offset += cff_pack_index(cffont->name, dest + offset, destlen - offset); + /* Top DICT */ + topdict_offset = offset; + offset += cff_index_size(topdict); + /* Strings */ + offset += cff_pack_index(cffont->string, dest + offset, destlen - offset); + /* Global Subrs */ + offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset); + + /* charset */ + cff_dict_set(cffont->topdict, "charset", 0, offset); + offset += cff_pack_charsets(cffont, dest + offset, destlen - offset); + + /* FDSelect */ + cff_dict_set(cffont->topdict, "FDSelect", 0, offset); + offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset); + + /* CharStrings */ + cff_dict_set(cffont->topdict, "CharStrings", 0, offset); + offset += cff_pack_index(cffont->cstrings, + dest + offset, cff_index_size(cffont->cstrings)); + cff_release_index(cffont->cstrings); + cffont->cstrings = NULL; /* Charstrings cosumes huge memory */ + + /* FDArray and Private */ + cff_dict_set(cffont->topdict, "FDArray", 0, offset); + fdarray_offset = offset; + offset += cff_index_size(fdarray); + + fdarray->data = xcalloc(fdarray->offset[fdarray->count] - 1, sizeof(card8)); + for (i = 0; i < cffont->num_fds; i++) { + size = private->offset[i + 1] - private->offset[i]; + if (cffont->private[i] && size > 0) { + cff_dict_pack(cffont->private[i], dest + offset, size); + cff_dict_set(cffont->fdarray[i], "Private", 0, size); + cff_dict_set(cffont->fdarray[i], "Private", 1, offset); + } + cff_dict_pack(cffont->fdarray[i], + fdarray->data + (fdarray->offset)[i] - 1, + fdarray->offset[fdarray->count] - 1); + offset += size; + } + + cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray)); + cff_release_index(fdarray); + cff_release_index(private); + + /* Finally Top DICT */ + topdict->data = xcalloc(topdict->offset[topdict->count] - 1, sizeof(card8)); + cff_dict_pack(cffont->topdict, + topdict->data, topdict->offset[topdict->count] - 1); + cff_pack_index(topdict, dest + topdict_offset, cff_index_size(topdict)); + cff_release_index(topdict); + + for (i = 0; i < offset; i++) + fb_putchar(dest[i]); + + /*fprintf(stdout," (%i/%i)",offset,cffont->stream_size); */ + xfree(dest); + return; } -/* if the CFF data was converted from an old type1 font, then the .notdef - glyph may not be at id 0, so in that case |uglytype1fix| is nonzero */ - -void write_cff(cff_font *cffont, fd_entry *fd, int uglytype1fix) { - cff_index *charstrings, *cs_idx; +/* this block is used a few times */ + +#define DO_COPY_CHARSTRING() \ + if ((avl_find(fd->gl_tree,glyph) != NULL)) { \ + size = cs_idx->offset[code+1] - cs_idx->offset[code]; \ + if (size > CS_STR_LEN_MAX) { \ + pdftex_fail("Charstring too long: gid=%u, %ld bytes", code, size); \ + } \ + if (charstring_len + CS_STR_LEN_MAX >= max_len) { \ + max_len = charstring_len + 2 * CS_STR_LEN_MAX; \ + charstrings->data = xrealloc(charstrings->data, max_len*sizeof(card8)); \ + } \ + (charstrings->offset)[gid] = charstring_len + 1; \ + cffont->offset= offset + (cs_idx->offset)[code] - 1; \ + memcpy(data,&cffont->stream[cffont->offset],size); \ + charstring_len += cs_copy_charstring(charstrings->data + charstring_len, \ + max_len - charstring_len, \ + data, size, \ + cffont->gsubr, (cffont->subrs)[0], \ + default_width, nominal_width, NULL); \ + gid++; \ + } + +void write_cff(cff_font * cffont, fd_entry * fd) +{ + cff_index *charstrings, *cs_idx; - long charstring_len, max_len; - long size, offset = 0; + long charstring_len, max_len; + long size, offset = 0; - card8 *data; - card16 num_glyphs, cs_count, code, gid, last_cid; + card8 *data; + card16 num_glyphs, cs_count, code, gid, last_cid; - double nominal_width, default_width; + double nominal_width, default_width; - char *fullname; + char *fullname; - glw_entry *glyph, *found; - struct avl_traverser t; + glw_entry *glyph, *found; + struct avl_traverser t; + fullname = xcalloc(8 + strlen(fd->fontname), 1); + sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname); + /* finish parsing the CFF */ + cff_read_private(cffont); + cff_read_subrs(cffont); - - fullname = xcalloc(8+strlen(fd->fontname),1); - sprintf(fullname,"%s+%s",fd->subset_tag,fd->fontname); + /* + * Widths + */ + if (cffont->private[0] && + cff_dict_known(cffont->private[0], "defaultWidthX")) { + default_width = + (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0); + } else { + default_width = CFF_DEFAULTWIDTHX_DEFAULT; + } + if (cffont->private[0] && + cff_dict_known(cffont->private[0], "nominalWidthX")) { + nominal_width = + (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0); + } else { + nominal_width = CFF_NOMINALWIDTHX_DEFAULT; + } - /* finish parsing the CFF */ - cff_read_private(cffont); - cff_read_subrs (cffont); + num_glyphs = 0; + last_cid = 0; + glyph = xtalloc(1, glw_entry); - /* - * Widths - */ - if (cffont->private[0] && - cff_dict_known(cffont->private[0], "defaultWidthX")) { - default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0); - } else { - default_width = CFF_DEFAULTWIDTHX_DEFAULT; - } - if (cffont->private[0] && - cff_dict_known(cffont->private[0], "nominalWidthX")) { - nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0); - } else { - nominal_width = CFF_NOMINALWIDTHX_DEFAULT; - } + /* insert notdef */ + glyph->id = 0; + if (avl_find(fd->gl_tree, glyph) == NULL) { + avl_insert(fd->gl_tree, glyph); + glyph = xtalloc(1, glw_entry); + } - num_glyphs = 0; - last_cid = 0; - glyph = xtalloc(1,glw_entry); + avl_t_init(&t, fd->gl_tree); + for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); + found != NULL; found = (glw_entry *) avl_t_next(&t)) { + if (found->id > last_cid) + last_cid = found->id; + num_glyphs++; + } - /* insert notdef */ - glyph->id = uglytype1fix; - if (avl_find(fd->gl_tree, glyph)==NULL) { - /*fprintf(stderr,"seeding .notdef at %i\n",uglytype1fix);*/ - avl_insert(fd->gl_tree, glyph); - glyph = xtalloc(1,glw_entry); - } + { + cff_fdselect *fdselect; + fdselect = xcalloc(1, sizeof(cff_fdselect)); + fdselect->format = 3; + fdselect->num_entries = 1; + fdselect->data.ranges = xcalloc(1, sizeof(cff_range3)); + fdselect->data.ranges[0].first = 0; + fdselect->data.ranges[0].fd = 0; + cffont->fdselect = fdselect; + } - avl_t_init(&t, fd->gl_tree); - for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); - found != NULL; - found = (glw_entry *) avl_t_next(&t)) { - if (found->id > last_cid) - last_cid = found->id; - num_glyphs++; - } + { + cff_charsets *charset; + + charset = xcalloc(1, sizeof(cff_charsets)); + charset->format = 0; + charset->num_entries = num_glyphs - 1; + charset->data.glyphs = xcalloc(num_glyphs, sizeof(s_SID)); + + gid = 0; + + avl_t_init(&t, fd->gl_tree); + for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); + found != NULL; found = (glw_entry *) avl_t_next(&t)) { + if (found->id != 0) { + charset->data.glyphs[gid] = found->id; + gid++; + } + } + cffont->charsets = charset; + } + + cff_dict_add(cffont->topdict, "CIDCount", 1); + cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1); + + cffont->fdarray = xcalloc(1, sizeof(cff_dict *)); + cffont->fdarray[0] = cff_new_dict(); + cff_dict_add(cffont->fdarray[0], "FontName", 1); + cff_dict_set(cffont->fdarray[0], "FontName", 0, (double) cff_add_string(cffont, fullname)); /* FIXME: Skip XXXXXX+ */ + cff_dict_add(cffont->fdarray[0], "Private", 2); + cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); + cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); + /* FDArray - index offset, not known yet */ + cff_dict_add(cffont->topdict, "FDArray", 1); + cff_dict_set(cffont->topdict, "FDArray", 0, 0.0); + /* FDSelect - offset, not known yet */ + cff_dict_add(cffont->topdict, "FDSelect", 1); + cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0); + + cff_dict_remove(cffont->topdict, "UniqueID"); + cff_dict_remove(cffont->topdict, "XUID"); + cff_dict_remove(cffont->topdict, "Private"); + cff_dict_remove(cffont->topdict, "Encoding"); + + cffont->offset = cff_dict_get(cffont->topdict, "CharStrings", 0); + cs_idx = cff_get_index_header(cffont); + + offset = cffont->offset; + cs_count = cs_idx->count; + if (cs_count < 2) { + CFF_ERROR("No valid charstring data found."); + } + + /* build the new charstrings entry */ + charstrings = cff_new_index(cs_count + 1); + max_len = 2 * CS_STR_LEN_MAX; + charstrings->data = xcalloc(max_len, sizeof(card8)); + charstring_len = 0; - { - cff_fdselect *fdselect; + gid = 0; + data = xcalloc(CS_STR_LEN_MAX, sizeof(card8)); - fdselect = xcalloc(1, sizeof(cff_fdselect)); - fdselect->format = 3; - fdselect->num_entries = 1; - fdselect->data.ranges = xcalloc(1, sizeof(cff_range3)); - fdselect->data.ranges[0].first = 0; - fdselect->data.ranges[0].fd = 0; - cffont->fdselect = fdselect; - } + { + int i; + for (i = 0; i < cs_count; i++) { + code = i; + glyph->id = code; + DO_COPY_CHARSTRING(); + } + } - { - cff_charsets *charset; + /* this happens if the internal metrics do not agree with the actual disk font */ + if (gid < num_glyphs) { + WARN("embedded subset is smaller than expected: %d instead of %d glyphs.", gid, num_glyphs); + num_glyphs = gid; + } - charset = xcalloc(1, sizeof(cff_charsets)); - charset->format = 0; - charset->num_entries = num_glyphs-1; - charset->data.glyphs = xcalloc(num_glyphs, sizeof(s_SID)); + xfree(data); + cff_release_index(cs_idx); - gid = 0; + (charstrings->offset)[num_glyphs] = charstring_len + 1; + charstrings->count = num_glyphs; + cffont->num_glyphs = num_glyphs; + cffont->cstrings = charstrings; - avl_t_init(&t, fd->gl_tree); - for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); - found != NULL; - found = (glw_entry *) avl_t_next(&t)) { - if(found->id!=0) { - charset->data.glyphs[gid] = found->id; - gid++; - } - } - cffont->charsets = charset; - } + /* + * We don't use subroutines at all. + */ + if (cffont->gsubr) + cff_release_index(cffont->gsubr); + cffont->gsubr = cff_new_index(0); - cff_dict_add(cffont->topdict, "CIDCount", 1); - cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1); - - cffont->fdarray = xcalloc(1, sizeof(cff_dict *)); - cffont->fdarray[0] = cff_new_dict(); - cff_dict_add(cffont->fdarray[0], "FontName", 1); - cff_dict_set(cffont->fdarray[0], "FontName", 0, - (double) cff_add_string(cffont, fullname)); /* FIXME: Skip XXXXXX+ */ - cff_dict_add(cffont->fdarray[0], "Private", 2); - cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); - cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); - /* FDArray - index offset, not known yet */ - cff_dict_add(cffont->topdict, "FDArray", 1); - cff_dict_set(cffont->topdict, "FDArray", 0, 0.0); - /* FDSelect - offset, not known yet */ - cff_dict_add(cffont->topdict, "FDSelect", 1); - cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0); - - cff_dict_remove(cffont->topdict, "UniqueID"); - cff_dict_remove(cffont->topdict, "XUID"); - cff_dict_remove(cffont->topdict, "Private"); - cff_dict_remove(cffont->topdict, "Encoding"); - - cffont->offset = cff_dict_get(cffont->topdict, "CharStrings", 0); - cs_idx = cff_get_index_header(cffont); - - offset = cffont->offset; - cs_count = cs_idx->count; - if (cs_count < 2) { - CFF_ERROR("No valid charstring data found."); - } + if (cffont->subrs && cffont->subrs[0]) + cff_release_index(cffont->subrs[0]); + cffont->subrs[0] = NULL; - /* build the new charstrings entry */ - charstrings = cff_new_index(cs_count+1); - max_len = 2 * CS_STR_LEN_MAX; - charstrings->data = xcalloc(max_len, sizeof(card8)); - charstring_len = 0; - - gid = 0; - data = xcalloc(CS_STR_LEN_MAX, sizeof(card8)); - - for (code=0; code < cs_count; code++) { - glyph->id = code; - if ((avl_find(fd->gl_tree,glyph) != NULL)) { - size = cs_idx->offset[code+1] - cs_idx->offset[code]; - - if (size > CS_STR_LEN_MAX) { - pdftex_fail("Charstring too long: gid=%u, %ld bytes", code, size); - } - if (charstring_len + CS_STR_LEN_MAX >= max_len) { - max_len = charstring_len + 2 * CS_STR_LEN_MAX; - charstrings->data = xrealloc(charstrings->data, max_len*sizeof(card8)); - } - (charstrings->offset)[gid] = charstring_len + 1; - cffont->offset= offset + (cs_idx->offset)[code] - 1; - memcpy(data,&cffont->stream[cffont->offset],size); - charstring_len += cs_copy_charstring(charstrings->data + charstring_len, - max_len - charstring_len, - data, size, - cffont->gsubr, (cffont->subrs)[0], - default_width, nominal_width, NULL); - gid++; + if (cffont->private && (cffont->private)[0]) { + cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */ } - } - - /* this happens if the internal metrics do not agree with the actual disk font */ - if (gid < num_glyphs) { - WARN("embedded subset is smaller than expected: %d instead of %d glyphs.", gid, num_glyphs); - num_glyphs = gid; - } - - xfree(data); - cff_release_index(cs_idx); - - (charstrings->offset)[num_glyphs] = charstring_len + 1; - charstrings->count = num_glyphs; - cffont->num_glyphs = num_glyphs; - cffont->cstrings = charstrings; - - /* - * We don't use subroutines at all. - */ - if (cffont->gsubr) - cff_release_index(cffont->gsubr); - cffont->gsubr = cff_new_index(0); - - if (cffont->subrs && cffont->subrs[0]) - cff_release_index(cffont->subrs[0]); - cffont->subrs[0] = NULL; - - if (cffont->private && (cffont->private)[0]) { - cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */ - } - cff_add_string(cffont, (char *)"Adobe"); - cff_add_string(cffont, (char *)"Identity"); + cff_add_string(cffont, (char *) "Adobe"); + cff_add_string(cffont, (char *) "Identity"); - cff_dict_update(cffont->topdict, cffont); - cff_dict_update(cffont->private[0], cffont); - cff_update_string(cffont); + cff_dict_update(cffont->topdict, cffont); + cff_dict_update(cffont->private[0], cffont); + cff_update_string(cffont); - /* CFF code need to be rewrote... */ - cff_dict_add(cffont->topdict, "ROS", 3); - cff_dict_set(cffont->topdict, "ROS", 0, - (double) cff_get_sid(cffont, (char *)"Adobe")); - cff_dict_set(cffont->topdict, "ROS", 1, - (double) cff_get_sid(cffont, (char *)"Identity")); - cff_dict_set(cffont->topdict, "ROS", 2, 0.0); + /* CFF code need to be rewrote... */ + cff_dict_add(cffont->topdict, "ROS", 3); + cff_dict_set(cffont->topdict, "ROS", 0, + (double) cff_get_sid(cffont, (char *) "Adobe")); + cff_dict_set(cffont->topdict, "ROS", 1, + (double) cff_get_sid(cffont, (char *) "Identity")); + cff_dict_set(cffont->topdict, "ROS", 2, 0.0); - write_fontfile(cffont,fullname); - xfree(fullname); - cff_close (cffont); + write_fontfile(cffont, fullname); + xfree(fullname); + cff_close(cffont); } @@ -3086,236 +3134,245 @@ void write_cff(cff_font *cffont, fd_entry *fd, int uglytype1fix) { /* Input : SID or CID (16-bit unsigned int) * Output: glyph index */ -card16 -cff_charsets_lookup (cff_font *cff, card16 cid) +card16 cff_charsets_lookup(cff_font * cff, card16 cid) { - card16 gid = 0; - cff_charsets *charset; - card16 i; - - if (cff->flag & (CHARSETS_ISOADOBE|CHARSETS_EXPERT|CHARSETS_EXPSUB)) { - ERROR("Predefined CFF charsets not supported yet"); - } else if (cff->charsets == NULL) { - ERROR("Charsets data not available"); - } + card16 gid = 0; + cff_charsets *charset; + card16 i; - if (cid == 0) { - return 0; /* GID 0 (.notdef) */ - } + if (cff->flag & (CHARSETS_ISOADOBE | CHARSETS_EXPERT | CHARSETS_EXPSUB)) { + ERROR("Predefined CFF charsets not supported yet"); + } else if (cff->charsets == NULL) { + ERROR("Charsets data not available"); + } - charset = cff->charsets; - - gid = 0; - switch (charset->format) { - case 0: - for (i = 0; i num_entries; i++) { - if (cid == charset->data.glyphs[i]) { - gid = i + 1; - return gid; - } - } - break; - case 1: - for (i = 0; i < charset->num_entries; i++) { - if (cid >= charset->data.range1[i].first && - cid <= charset->data.range1[i].first + charset->data.range1[i].n_left) { - gid += cid - charset->data.range1[i].first + 1; - return gid; - } - gid += charset->data.range1[i].n_left + 1; - } - break; - case 2: - for (i = 0; i < charset->num_entries; i++) { - if (cid >= charset->data.range2[i].first && - cid <= charset->data.range2[i].first + charset->data.range2[i].n_left) { - gid += cid - charset->data.range2[i].first + 1; - return gid; - } - gid += charset->data.range2[i].n_left + 1; - } - break; - default: - ERROR("Unknown Charset format"); - } + if (cid == 0) { + return 0; /* GID 0 (.notdef) */ + } + + charset = cff->charsets; - return 0; /* not found */ + gid = 0; + switch (charset->format) { + case 0: + for (i = 0; i < charset->num_entries; i++) { + if (cid == charset->data.glyphs[i]) { + gid = i + 1; + return gid; + } + } + break; + case 1: + for (i = 0; i < charset->num_entries; i++) { + if (cid >= charset->data.range1[i].first && + cid <= + charset->data.range1[i].first + + charset->data.range1[i].n_left) { + gid += cid - charset->data.range1[i].first + 1; + return gid; + } + gid += charset->data.range1[i].n_left + 1; + } + break; + case 2: + for (i = 0; i < charset->num_entries; i++) { + if (cid >= charset->data.range2[i].first && + cid <= + charset->data.range2[i].first + + charset->data.range2[i].n_left) { + gid += cid - charset->data.range2[i].first + 1; + return gid; + } + gid += charset->data.range2[i].n_left + 1; + } + break; + default: + ERROR("Unknown Charset format"); + } + + return 0; /* not found */ } #define is_cidfont(a) ((a)->flag & FONTTYPE_CIDFONT) #define CID_MAX 65535 -void write_cid_cff(cff_font *cffont, fd_entry *fd, int uglytype1fix) { - cff_index *charstrings, *cs_idx; +void write_cid_cff(cff_font * cffont, fd_entry * fd) +{ + cff_index *charstrings, *cs_idx; - long charstring_len, max_len; - long size, offset = 0; + long charstring_len, max_len; + long size, offset = 0; - card8 *data; - card16 num_glyphs, cs_count, gid, last_cid; + card8 *data; + card16 num_glyphs, cs_count, gid, last_cid; - int fdsel, prev_fd, cid_count, cid; - char *fullname; + int fdsel, prev_fd, cid_count, cid; + char *fullname; - glw_entry *glyph; + glw_entry *glyph; - unsigned char *CIDToGIDMap = NULL; + unsigned char *CIDToGIDMap = NULL; - cff_fdselect *fdselect = NULL; - cff_charsets *charset = NULL; + cff_fdselect *fdselect = NULL; + cff_charsets *charset = NULL; - if (!is_cidfont(cffont)) { - perror("Not a CIDfont."); - return; - } + if (!is_cidfont(cffont)) { + perror("Not a CIDfont."); + return; + } - fullname = xcalloc(8+strlen(fd->fontname),1); - sprintf(fullname,"%s+%s",fd->subset_tag,fd->fontname); + fullname = xcalloc(8 + strlen(fd->fontname), 1); + sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname); - /* finish parsing the CFF */ + /* finish parsing the CFF */ - if (cff_dict_known(cffont->topdict, "CIDCount")) { - cid_count = (card16) cff_dict_get(cffont->topdict, "CIDCount", 0); - } else { - cid_count = CFF_CIDCOUNT_DEFAULT; - } - cff_read_charsets(cffont); - CIDToGIDMap = xmalloc((2*cid_count) * sizeof(unsigned char)); - memset(CIDToGIDMap, 0, 2*cid_count); + if (cff_dict_known(cffont->topdict, "CIDCount")) { + cid_count = (card16) cff_dict_get(cffont->topdict, "CIDCount", 0); + } else { + cid_count = CFF_CIDCOUNT_DEFAULT; + } + cff_read_charsets(cffont); + CIDToGIDMap = xmalloc((2 * cid_count) * sizeof(unsigned char)); + memset(CIDToGIDMap, 0, 2 * cid_count); - glyph = xtalloc(1,glw_entry); - /* insert notdef */ - glyph->id = uglytype1fix; - if (avl_find(fd->gl_tree, glyph)==NULL) { - avl_insert(fd->gl_tree, glyph); - glyph = xtalloc(1,glw_entry); - } + glyph = xtalloc(1, glw_entry); + /* insert notdef */ + glyph->id = 0; + if (avl_find(fd->gl_tree, glyph) == NULL) { + avl_insert(fd->gl_tree, glyph); + glyph = xtalloc(1, glw_entry); + } - cid = 0; last_cid = 0; num_glyphs = 0; - for (cid = 0; cid <= CID_MAX; cid++) { - glyph->id = cid; - if (avl_find(fd->gl_tree,glyph) != NULL) { - gid = cff_charsets_lookup(cffont, cid); - CIDToGIDMap[2*cid] = (gid >> 8) & 0xff; - CIDToGIDMap[2*cid+1] = gid & 0xff; - last_cid = cid; - num_glyphs++; + cid = 0; + last_cid = 0; + num_glyphs = 0; + for (cid = 0; cid <= CID_MAX; cid++) { + glyph->id = cid; + if (avl_find(fd->gl_tree, glyph) != NULL) { + gid = cff_charsets_lookup(cffont, cid); + CIDToGIDMap[2 * cid] = (gid >> 8) & 0xff; + CIDToGIDMap[2 * cid + 1] = gid & 0xff; + last_cid = cid; + num_glyphs++; + } } - } - cff_read_fdselect(cffont); - cff_read_fdarray(cffont); - cff_read_private(cffont); - - cff_read_subrs (cffont); + cff_read_fdselect(cffont); + cff_read_fdarray(cffont); + cff_read_private(cffont); + cff_read_subrs(cffont); - cffont->offset = cff_dict_get(cffont->topdict, "CharStrings", 0); - cs_idx = cff_get_index_header(cffont); - offset = cffont->offset; - cs_count = cs_idx->count; - if (cs_count < 2) { - CFF_ERROR("No valid charstring data found."); - } + cffont->offset = cff_dict_get(cffont->topdict, "CharStrings", 0); + cs_idx = cff_get_index_header(cffont); - charset = xcalloc(1, sizeof(cff_charsets)); - charset->format = 0; - charset->num_entries = 0; - charset->data.glyphs = xcalloc(num_glyphs, sizeof(s_SID)); - - fdselect = xcalloc(1, sizeof(cff_fdselect)); - fdselect->format = 3; - fdselect->num_entries = 0; - fdselect->data.ranges = xcalloc(num_glyphs, sizeof(cff_range3)); - - charstrings = cff_new_index(cs_count+1); - max_len = 2 * CS_STR_LEN_MAX; - charstrings->data = xcalloc(max_len, sizeof(card8)); - charstring_len = 0; - - prev_fd = -1; gid = 0; - data = xcalloc(CS_STR_LEN_MAX, sizeof(card8)); - for (cid=0; cid <= last_cid; cid++) { - unsigned short gid_org; - - glyph->id = cid; - if (avl_find(fd->gl_tree,glyph) == NULL) - continue; - - gid_org = (CIDToGIDMap[2*cid] << 8)|(CIDToGIDMap[2*cid+1]); - size = cs_idx->offset[gid_org+1] - cs_idx->offset[gid_org]; - if (size > CS_STR_LEN_MAX) { - pdftex_fail("Charstring too long: gid=%u, %ld bytes", cid, size); - } - if (charstring_len + CS_STR_LEN_MAX >= max_len) { - max_len = charstring_len + 2 * CS_STR_LEN_MAX; - charstrings->data = xrealloc(charstrings->data, max_len*sizeof(card8)); - } - (charstrings->offset)[gid] = charstring_len + 1; - cffont->offset= offset + (cs_idx->offset)[gid_org] - 1; - memcpy(data,&cffont->stream[cffont->offset],size); - fdsel = cff_fdselect_lookup(cffont, gid_org); - charstring_len += cs_copy_charstring(charstrings->data + charstring_len, - max_len - charstring_len, - data, size, - cffont->gsubr, (cffont->subrs)[fdsel], - 0, 0, NULL); - - if (cid>0 && gid_org > 0) { - charset->data.glyphs[charset->num_entries] = cid; - charset->num_entries += 1; - } - if (fdsel != prev_fd) { - fdselect->data.ranges[fdselect->num_entries].first = gid; - fdselect->data.ranges[fdselect->num_entries].fd = fdsel; - fdselect->num_entries += 1; - prev_fd = fdsel; - } - gid++; - } - - if (gid != num_glyphs) - CFF_ERROR("Unexpected error: %i != %i", gid, num_glyphs); - xfree(data); - cff_release_index(cs_idx); - - xfree(CIDToGIDMap); - - (charstrings->offset)[num_glyphs] = charstring_len + 1; - charstrings->count = num_glyphs; - cffont->num_glyphs = num_glyphs; - cffont->cstrings = charstrings; - - cff_release_charsets(cffont->charsets); - cffont->charsets = charset; - cff_release_fdselect(cffont->fdselect); - cffont->fdselect = fdselect; - - /* - * We don't use subroutines at all. - */ - if (cffont->gsubr) - cff_release_index(cffont->gsubr); - cffont->gsubr = cff_new_index(0); - - for (fdsel = 0; fdsel < cffont->num_fds; fdsel++) { - if (cffont->subrs && cffont->subrs[fdsel]) { - cff_release_index(cffont->subrs[fdsel]); - cffont->subrs[fdsel] = NULL; - } - if (cffont->private && (cffont->private)[fdsel]) { - cff_dict_remove((cffont->private)[fdsel], "Subrs"); /* no Subrs */ + offset = cffont->offset; + cs_count = cs_idx->count; + if (cs_count < 2) { + CFF_ERROR("No valid charstring data found."); } - } - write_fontfile(cffont,fullname); - xfree(fullname); - cff_close (cffont); + charset = xcalloc(1, sizeof(cff_charsets)); + charset->format = 0; + charset->num_entries = 0; + charset->data.glyphs = xcalloc(num_glyphs, sizeof(s_SID)); + + fdselect = xcalloc(1, sizeof(cff_fdselect)); + fdselect->format = 3; + fdselect->num_entries = 0; + fdselect->data.ranges = xcalloc(num_glyphs, sizeof(cff_range3)); + + charstrings = cff_new_index(cs_count + 1); + max_len = 2 * CS_STR_LEN_MAX; + charstrings->data = xcalloc(max_len, sizeof(card8)); + charstring_len = 0; + + prev_fd = -1; + gid = 0; + data = xcalloc(CS_STR_LEN_MAX, sizeof(card8)); + for (cid = 0; cid <= last_cid; cid++) { + unsigned short gid_org; + + glyph->id = cid; + if (avl_find(fd->gl_tree, glyph) == NULL) + continue; + + gid_org = (CIDToGIDMap[2 * cid] << 8) | (CIDToGIDMap[2 * cid + 1]); + size = cs_idx->offset[gid_org + 1] - cs_idx->offset[gid_org]; + if (size > CS_STR_LEN_MAX) { + pdftex_fail("Charstring too long: gid=%u, %ld bytes", cid, size); + } + if (charstring_len + CS_STR_LEN_MAX >= max_len) { + max_len = charstring_len + 2 * CS_STR_LEN_MAX; + charstrings->data = + xrealloc(charstrings->data, max_len * sizeof(card8)); + } + (charstrings->offset)[gid] = charstring_len + 1; + cffont->offset = offset + (cs_idx->offset)[gid_org] - 1; + memcpy(data, &cffont->stream[cffont->offset], size); + fdsel = cff_fdselect_lookup(cffont, gid_org); + charstring_len += cs_copy_charstring(charstrings->data + charstring_len, + max_len - charstring_len, + data, size, + cffont->gsubr, + (cffont->subrs)[fdsel], 0, 0, + NULL); + + if (cid > 0 && gid_org > 0) { + charset->data.glyphs[charset->num_entries] = cid; + charset->num_entries += 1; + } + if (fdsel != prev_fd) { + fdselect->data.ranges[fdselect->num_entries].first = gid; + fdselect->data.ranges[fdselect->num_entries].fd = fdsel; + fdselect->num_entries += 1; + prev_fd = fdsel; + } + gid++; + } + + if (gid != num_glyphs) + CFF_ERROR("Unexpected error: %i != %i", gid, num_glyphs); + xfree(data); + cff_release_index(cs_idx); + + xfree(CIDToGIDMap); + + (charstrings->offset)[num_glyphs] = charstring_len + 1; + charstrings->count = num_glyphs; + cffont->num_glyphs = num_glyphs; + cffont->cstrings = charstrings; + + cff_release_charsets(cffont->charsets); + cffont->charsets = charset; + cff_release_fdselect(cffont->fdselect); + cffont->fdselect = fdselect; + + /* + * We don't use subroutines at all. + */ + if (cffont->gsubr) + cff_release_index(cffont->gsubr); + cffont->gsubr = cff_new_index(0); + + for (fdsel = 0; fdsel < cffont->num_fds; fdsel++) { + if (cffont->subrs && cffont->subrs[fdsel]) { + cff_release_index(cffont->subrs[fdsel]); + cffont->subrs[fdsel] = NULL; + } + if (cffont->private && (cffont->private)[fdsel]) { + cff_dict_remove((cffont->private)[fdsel], "Subrs"); /* no Subrs */ + } + } + + write_fontfile(cffont, fullname); + xfree(fullname); + cff_close(cffont); } @@ -3324,58 +3381,56 @@ void write_cid_cff(cff_font *cffont, fd_entry *fd, int uglytype1fix) { * I have defined a utility function in luafflib.c that does exactly that. * If it works out ok, I will clean up this code. */ +extern int ff_createcff(char *, unsigned char **, integer *); /* libs/luafontforge/src/luafflib.c */ -extern int ff_createcff (char *, unsigned char **, integer *); - -void writetype1w (fd_entry *fd) { - cff_font *cff; - int i; - FILE *fp; - ff_entry *ff; - unsigned char *tfm_buffer = NULL; - integer tfm_size = 0; - int notdefpos = 0; - - ff = check_ff_exist(fd->fm->ff_name, 0); - - fp = fopen (ff->ff_path, "rb"); - cur_file_name = ff->ff_path; - - if (!fp) { - fprintf(stderr,"Type1: Could not open Type1 font: %s", cur_file_name); - uexit(1); - } - fclose(fp); +void writetype1w(fd_entry * fd) +{ + cff_font *cff; + int i; + FILE *fp; + ff_entry *ff; + unsigned char *tfm_buffer = NULL; + integer tfm_size = 0; - if (tracefilenames) { - if (is_subsetted(fd->fm)) - tex_printf ("<%s", cur_file_name); - else - tex_printf ("<<%s", cur_file_name); - } + ff = check_ff_exist(fd->fm->ff_name, 0); - notdefpos = ff_createcff(ff->ff_path,&tfm_buffer,&tfm_size); + fp = fopen(ff->ff_path, "rb"); + cur_file_name = ff->ff_path; - if (tfm_size>0) { - cff = read_cff(tfm_buffer,tfm_size,0); - if (cff != NULL) { - write_cff(cff,fd,notdefpos); - } else { - for (i = 0; i < tfm_size ; i++) - fb_putchar (tfm_buffer[i]); + if (!fp) { + fprintf(stderr, "Type1: Could not open Type1 font: %s", cur_file_name); + uexit(1); + } + fclose(fp); + + if (tracefilenames) { + if (is_subsetted(fd->fm)) + tex_printf("<%s", cur_file_name); + else + tex_printf("<<%s", cur_file_name); } - fd->ff_found = 1; - } else { - fprintf(stderr,"Type1: Could not understand Type1 font: %s", cur_file_name); - uexit(1); - } - if (tracefilenames) { - if (is_subsetted (fd->fm)) - tex_printf (">"); - else - tex_printf (">>"); - } - cur_file_name = NULL; -} + (void) ff_createcff(ff->ff_path, &tfm_buffer, &tfm_size); + if (tfm_size > 0) { + cff = read_cff(tfm_buffer, tfm_size, 0); + if (cff != NULL) { + write_cff(cff, fd); + } else { + for (i = 0; i < tfm_size; i++) + fb_putchar(tfm_buffer[i]); + } + fd->ff_found = 1; + } else { + fprintf(stderr, "Type1: Could not understand Type1 font: %s", + cur_file_name); + uexit(1); + } + if (tracefilenames) { + if (is_subsetted(fd->fm)) + tex_printf(">"); + else + tex_printf(">>"); + } + cur_file_name = NULL; +} diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.h b/Build/source/texk/web2c/luatexdir/font/writecff.h index 8cb93024f7a..2d92a8723ae 100644 --- a/Build/source/texk/web2c/luatexdir/font/writecff.h +++ b/Build/source/texk/web2c/luatexdir/font/writecff.h @@ -1,349 +1,344 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/cff_limits.h,v 1.3 2002/10/30 02:27:05 chofchof Exp $ +/* writecff.h - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team + Copyright 2006-2008 Taco Hoekwater - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: writecff.h 1518 2008-09-30 08:18:10Z taco $ */ #ifndef _CFF_LIMITS_H_ -#define _CFF_LIMITS_H_ +# define _CFF_LIMITS_H_ -#include +# include -#define CFF_INT_MAX 0x7fffffff -#define CFF_INT_MIN (-0x7fffffff - 1) +# define CFF_INT_MAX 0x7fffffff +# define CFF_INT_MIN (-0x7fffffff - 1) -#if (LONG_MAX < CFF_INT_MAX || LONG_MIN > CFF_INT_MIN) -#error "CFF support won't work on this system." -#endif +# if (LONG_MAX < CFF_INT_MAX || LONG_MIN > CFF_INT_MIN) +# error "CFF support won't work on this system." +# endif -#define CFF_SID_MAX 64999 -#define CFF_STDSTR_MAX 391 +# define CFF_SID_MAX 64999 +# define CFF_STDSTR_MAX 391 /* Type 2 Charstring */ -#define CS_NUM_SUBR_MAX 65536 -#define CS_STR_LEN_MAX 65536 -#define CS_STEM_ZONE_MAX 96 -#define CS_ARG_STACK_MAX 48 -#define CS_TRANS_ARRAY_MAX 32 -#define CS_SUBR_NEST_MAX 10 +# define CS_NUM_SUBR_MAX 65536 +# define CS_STR_LEN_MAX 65536 +# define CS_STEM_ZONE_MAX 96 +# define CS_ARG_STACK_MAX 48 +# define CS_TRANS_ARRAY_MAX 32 +# define CS_SUBR_NEST_MAX 10 -#endif /* _CFF_LIMITS_H_ */ +#endif /* _CFF_LIMITS_H_ */ #ifndef _CFF_TYPES_H_ -#define _CFF_TYPES_H_ +# define _CFF_TYPES_H_ /* CFF Data Types */ -#define CFF_TYPE_UNKNOWN 0 -#define CFF_TYPE_INTEGER (1 << 0) -#define CFF_TYPE_REAL (1 << 1) -#define CFF_TYPE_NUMBER (CFF_TYPE_INTEGER|CFF_TYPE_REAL) -#define CFF_TYPE_BOOLEAN (1 << 2) -#define CFF_TYPE_SID (1 << 3) -#define CFF_TYPE_ARRAY (1 << 4) -#define CFF_TYPE_DELTA (1 << 5) +# define CFF_TYPE_UNKNOWN 0 +# define CFF_TYPE_INTEGER (1 << 0) +# define CFF_TYPE_REAL (1 << 1) +# define CFF_TYPE_NUMBER (CFF_TYPE_INTEGER|CFF_TYPE_REAL) +# define CFF_TYPE_BOOLEAN (1 << 2) +# define CFF_TYPE_SID (1 << 3) +# define CFF_TYPE_ARRAY (1 << 4) +# define CFF_TYPE_DELTA (1 << 5) /* SID SID number */ -#define CFF_TYPE_ROS (1 << 6) +# define CFF_TYPE_ROS (1 << 6) /* offset(0) */ -#define CFF_TYPE_OFFSET (1 << 7) +# define CFF_TYPE_OFFSET (1 << 7) /* size offset(0) */ -#define CFF_TYPE_SZOFF (1 << 8) +# define CFF_TYPE_SZOFF (1 << 8) -typedef unsigned char card8; /* 1-byte unsigned number */ -typedef unsigned short card16; /* 2-byte unsigned number */ -typedef unsigned char c_offsize; /* 1-byte unsigned number specifies the size - of an Offset field or fields, range 1-4 */ -typedef unsigned long l_offset; /* 1, 2, 3, or 4-byte offset */ -typedef unsigned short s_SID; /* 2-byte string identifier */ +typedef unsigned char card8; /* 1-byte unsigned number */ +typedef unsigned short card16; /* 2-byte unsigned number */ +typedef unsigned char c_offsize; /* 1-byte unsigned number specifies the size + of an Offset field or fields, range 1-4 */ +typedef unsigned long l_offset; /* 1, 2, 3, or 4-byte offset */ +typedef unsigned short s_SID; /* 2-byte string identifier */ -typedef unsigned long l_size; +typedef unsigned long l_size; typedef struct { - card16 count; /* number of objects stored in INDEX */ - c_offsize offsize; /* Offset array element size, 1-4 */ - l_offset *offset; /* Offset array, count + 1 offsets */ - card8 *data; /* Object data */ + card16 count; /* number of objects stored in INDEX */ + c_offsize offsize; /* Offset array element size, 1-4 */ + l_offset *offset; /* Offset array, count + 1 offsets */ + card8 *data; /* Object data */ } cff_index; /* Dictionary */ typedef struct { - int id; /* encoded data value (as card8 or card16) */ - char *key; /* opname */ - int count; /* number of values */ - double *values; /* values */ + int id; /* encoded data value (as card8 or card16) */ + char *key; /* opname */ + int count; /* number of values */ + double *values; /* values */ } cff_dict_entry; typedef struct { - int max; - int count; - cff_dict_entry *entries; + int max; + int count; + cff_dict_entry *entries; } cff_dict; /* Encoding, Charset and FDSelect */ -typedef struct -{ - s_SID first; /* SID or CID, or card8 for Encoding */ - card8 n_left; /* no. of remaining gids/codes in this range */ +typedef struct { + s_SID first; /* SID or CID, or card8 for Encoding */ + card8 n_left; /* no. of remaining gids/codes in this range */ } cff_range1; -typedef struct -{ - s_SID first; /* SID or CID (card16) */ - card16 n_left; /* card16-version of range1 */ +typedef struct { + s_SID first; /* SID or CID (card16) */ + card16 n_left; /* card16-version of range1 */ } cff_range2; -typedef struct -{ - card8 code; - s_SID glyph; +typedef struct { + card8 code; + s_SID glyph; } cff_map; -typedef struct -{ - card8 format; /* if (format & 0x80) then have supplement */ - card8 num_entries; /* number of entries */ - union { - card8 *codes; /* format 0 */ - cff_range1 *range1; /* format 1 */ - } data; - card8 num_supps; /* number of supplementary data */ - cff_map *supp; /* supplement */ +typedef struct { + card8 format; /* if (format & 0x80) then have supplement */ + card8 num_entries; /* number of entries */ + union { + card8 *codes; /* format 0 */ + cff_range1 *range1; /* format 1 */ + } data; + card8 num_supps; /* number of supplementary data */ + cff_map *supp; /* supplement */ } cff_encoding; -typedef struct -{ - card8 format; - card16 num_entries; - union { - s_SID *glyphs; /* format 0 */ - cff_range1 *range1; /* format 1 */ - cff_range2 *range2; /* format 2 */ - } data; +typedef struct { + card8 format; + card16 num_entries; + union { + s_SID *glyphs; /* format 0 */ + cff_range1 *range1; /* format 1 */ + cff_range2 *range2; /* format 2 */ + } data; } cff_charsets; /* CID-Keyed font specific */ -typedef struct -{ - card16 first; - card8 fd; +typedef struct { + card16 first; + card8 fd; } cff_range3; -typedef struct -{ - card8 format; - card16 num_entries; /* number of glyphs/ranges */ - union { - card8 *fds; /* format 0 */ - cff_range3 *ranges; /* format 3 */ - } data; - /* card16 sentinel; */ /* format 3 only, must be equals to num_glyphs */ +typedef struct { + card8 format; + card16 num_entries; /* number of glyphs/ranges */ + union { + card8 *fds; /* format 0 */ + cff_range3 *ranges; /* format 3 */ + } data; + /* card16 sentinel; *//* format 3 only, must be equals to num_glyphs */ } cff_fdselect; -#endif /* _CFF_TYPES_H_ */ +#endif /* _CFF_TYPES_H_ */ #ifndef _CFF_STDSTR_H_ -#define _CFF_STDSTR_H_ +# define _CFF_STDSTR_H_ -#define CFF_STDSTR_MAX 391 +# define CFF_STDSTR_MAX 391 extern const char *const cff_stdstr[]; -#endif /* _CFF_STDSTR_H_ */ +#endif /* _CFF_STDSTR_H_ */ #ifndef _CFF_H_ -#define _CFF_H_ +# define _CFF_H_ /*#include "mfileio.h"*/ /* Flag */ -#define FONTTYPE_CIDFONT (1 << 0) -#define FONTTYPE_FONT (1 << 1) -#define FONTTYPE_MMASTER (1 << 2) +# define FONTTYPE_CIDFONT (1 << 0) +# define FONTTYPE_FONT (1 << 1) +# define FONTTYPE_MMASTER (1 << 2) -#define ENCODING_STANDARD (1 << 3) -#define ENCODING_EXPERT (1 << 4) +# define ENCODING_STANDARD (1 << 3) +# define ENCODING_EXPERT (1 << 4) -#define CHARSETS_ISOADOBE (1 << 5) -#define CHARSETS_EXPERT (1 << 6) -#define CHARSETS_EXPSUB (1 << 7) +# define CHARSETS_ISOADOBE (1 << 5) +# define CHARSETS_EXPERT (1 << 6) +# define CHARSETS_EXPSUB (1 << 7) -#define HAVE_STANDARD_ENCODING (ENCODING_STANDARD|ENCODING_EXPERT) -#define HAVE_STANDARD_CHARSETS \ +# define HAVE_STANDARD_ENCODING (ENCODING_STANDARD|ENCODING_EXPERT) +# define HAVE_STANDARD_CHARSETS \ (CHARSETS_ISOADOBE|CHARSETS_EXPERT|CHARSETS_EXPSUB) -#define CFF_STRING_NOTDEF 65535 - -typedef struct -{ - char *fontname; /* FontName */ - - /* - CFF structure - */ - - card8 header_major; /* major version */ - card8 header_minor; /* minor version */ - card8 header_hdr_size; /* Header size (bytes) */ - c_offsize header_offsize; /* Absolute offset (0) size */ - - cff_index *name; /* Name INDEX */ - cff_dict *topdict; /* Top DICT (single) */ - cff_index *string; /* String INDEX */ - cff_index *gsubr; /* Global Subr INDEX */ - cff_encoding *encoding; /* Encodings */ - cff_charsets *charsets; /* Charsets */ - cff_fdselect *fdselect; /* FDSelect, CIDFont only */ - cff_index *cstrings; /* CharStrings */ - cff_dict **fdarray; /* CIDFont only */ - cff_dict **private; /* per-Font DICT */ - cff_index **subrs; /* Local Subr INDEX, per-Private DICT */ - - /* -- extra data -- */ - l_offset gsubr_offset; - card16 num_glyphs; /* number of glyphs (CharString INDEX count) */ - card8 num_fds; /* number of Font DICT */ - - /* Updated String INDEX. - * Please fix this. We should separate input and output. - */ - cff_index *_string; - - unsigned char *stream; - l_offset offset; - l_offset stream_size; - - int index; /* CFF fontset index */ - int flag; /* Flag: see above */ +# define CFF_STRING_NOTDEF 65535 + +typedef struct { + char *fontname; /* FontName */ + + /* - CFF structure - */ + + card8 header_major; /* major version */ + card8 header_minor; /* minor version */ + card8 header_hdr_size; /* Header size (bytes) */ + c_offsize header_offsize; /* Absolute offset (0) size */ + + cff_index *name; /* Name INDEX */ + cff_dict *topdict; /* Top DICT (single) */ + cff_index *string; /* String INDEX */ + cff_index *gsubr; /* Global Subr INDEX */ + cff_encoding *encoding; /* Encodings */ + cff_charsets *charsets; /* Charsets */ + cff_fdselect *fdselect; /* FDSelect, CIDFont only */ + cff_index *cstrings; /* CharStrings */ + cff_dict **fdarray; /* CIDFont only */ + cff_dict **private; /* per-Font DICT */ + cff_index **subrs; /* Local Subr INDEX, per-Private DICT */ + + /* -- extra data -- */ + l_offset gsubr_offset; + card16 num_glyphs; /* number of glyphs (CharString INDEX count) */ + card8 num_fds; /* number of Font DICT */ + + /* Updated String INDEX. + * Please fix this. We should separate input and output. + */ + cff_index *_string; + + unsigned char *stream; + l_offset offset; + l_offset stream_size; + + int index; /* CFF fontset index */ + int flag; /* Flag: see above */ } cff_font; extern cff_font *cff_open(unsigned char *stream, long stream_size, int n); -extern void cff_close (cff_font *cff); +extern void cff_close(cff_font * cff); -#define cff_seek_set(c, p) seek_absolute (((c)->stream), ((c)->offset) + (p)); +# define cff_seek_set(c, p) seek_absolute (((c)->stream), ((c)->offset) + (p)); /* CFF Header */ -extern long cff_put_header (cff_font *cff, card8 *dest, long destlen); +extern long cff_put_header(cff_font * cff, card8 * dest, long destlen); /* CFF INDEX */ -extern cff_index *cff_get_index (cff_font *cff); -extern cff_index *cff_get_index_header (cff_font *cff); -extern void cff_release_index (cff_index *idx); -extern cff_index *cff_new_index (card16 count); -extern long cff_index_size (cff_index *idx); -extern long cff_pack_index (cff_index *idx, card8 *dest, long destlen); +extern cff_index *cff_get_index(cff_font * cff); +extern cff_index *cff_get_index_header(cff_font * cff); +extern void cff_release_index(cff_index * idx); +extern cff_index *cff_new_index(card16 count); +extern long cff_index_size(cff_index * idx); +extern long cff_pack_index(cff_index * idx, card8 * dest, long destlen); /* Name INDEX */ -extern char *cff_get_name (cff_font *cff); -extern long cff_set_name (cff_font *cff, char *name); +extern char *cff_get_name(cff_font * cff); +extern long cff_set_name(cff_font * cff, char *name); /* Global and Local Subrs INDEX */ -extern long cff_read_subrs (cff_font *cff); +extern long cff_read_subrs(cff_font * cff); /* Encoding */ -extern long cff_read_encoding (cff_font *cff); -extern long cff_pack_encoding (cff_font *cff, card8 *dest, long destlen); -extern card16 cff_encoding_lookup (cff_font *cff, card8 code); -extern void cff_release_encoding (cff_encoding *encoding); +extern long cff_read_encoding(cff_font * cff); +extern long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen); +extern card16 cff_encoding_lookup(cff_font * cff, card8 code); +extern void cff_release_encoding(cff_encoding * encoding); /* Charsets */ -extern long cff_read_charsets (cff_font *cff); -extern long cff_pack_charsets (cff_font *cff, card8 *dest, long destlen); +extern long cff_read_charsets(cff_font * cff); +extern long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen); /* Returns GID of PS name "glyph" */ -extern card16 cff_glyph_lookup (cff_font *cff, const char *glyph); +extern card16 cff_glyph_lookup(cff_font * cff, const char *glyph); /* Returns GID of glyph with SID/CID "cid" */ -extern card16 cff_charsets_lookup (cff_font *cff, card16 cid); -extern void cff_release_charsets (cff_charsets *charset); +extern card16 cff_charsets_lookup(cff_font * cff, card16 cid); +extern void cff_release_charsets(cff_charsets * charset); /* Returns SID or CID */ -extern card16 cff_charsets_lookup_inverse (cff_font *cff, card16 gid); +extern card16 cff_charsets_lookup_inverse(cff_font * cff, card16 gid); /* FDSelect */ -extern long cff_read_fdselect (cff_font *cff); -extern long cff_pack_fdselect (cff_font *cff, card8 *dest, long destlen); -extern card8 cff_fdselect_lookup (cff_font *cff, card16 gid); -extern void cff_release_fdselect (cff_fdselect *fdselect); +extern long cff_read_fdselect(cff_font * cff); +extern long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen); +extern card8 cff_fdselect_lookup(cff_font * cff, card16 gid); +extern void cff_release_fdselect(cff_fdselect * fdselect); /* Font DICT(s) */ -extern long cff_read_fdarray (cff_font *cff); +extern long cff_read_fdarray(cff_font * cff); /* Private DICT(s) */ -extern long cff_read_private (cff_font *cff); +extern long cff_read_private(cff_font * cff); /* String */ -extern int cff_match_string (cff_font *cff, const char *str, s_SID sid); -extern char *cff_get_string (cff_font *cff, s_SID id); -extern long cff_get_sid (cff_font *cff, char *str); -extern s_SID cff_add_string (cff_font *cff, char *str); -extern void cff_update_string (cff_font *cff); +extern int cff_match_string(cff_font * cff, const char *str, s_SID sid); +extern char *cff_get_string(cff_font * cff, s_SID id); +extern long cff_get_sid(cff_font * cff, char *str); +extern s_SID cff_add_string(cff_font * cff, char *str); +extern void cff_update_string(cff_font * cff); -#define cff_is_stdstr(s) (cff_get_sid(NULL, (s)) >= 0) +# define cff_is_stdstr(s) (cff_get_sid(NULL, (s)) >= 0) -#endif /* _CFF_H_ */ +#endif /* _CFF_H_ */ #ifndef _CFF_DICT_H_ -#define _CFF_DICT_H_ +# define _CFF_DICT_H_ -#define CFF_CIDCOUNT_DEFAULT 8720 -#define CFF_NOMINALWIDTHX_DEFAULT 0.0 -#define CFF_DEFAULTWIDTHX_DEFAULT 0.0 +# define CFF_CIDCOUNT_DEFAULT 8720 +# define CFF_NOMINALWIDTHX_DEFAULT 0.0 +# define CFF_DEFAULTWIDTHX_DEFAULT 0.0 -extern cff_dict *cff_new_dict (void); -extern void cff_release_dict (cff_dict *dict); +extern cff_dict *cff_new_dict(void); +extern void cff_release_dict(cff_dict * dict); -extern void cff_dict_set (cff_dict *dict, const char *key, int idx, double value); -extern double cff_dict_get (cff_dict *dict, const char *key, int idx); -extern void cff_dict_add (cff_dict *dict, const char *key, int count); -extern void cff_dict_remove (cff_dict *dict, const char *key); -extern int cff_dict_known (cff_dict *dict, const char *key); +extern void cff_dict_set(cff_dict * dict, const char *key, int idx, + double value); +extern double cff_dict_get(cff_dict * dict, const char *key, int idx); +extern void cff_dict_add(cff_dict * dict, const char *key, int count); +extern void cff_dict_remove(cff_dict * dict, const char *key); +extern int cff_dict_known(cff_dict * dict, const char *key); /* decode/encode DICT */ -extern cff_dict *cff_dict_unpack (card8 *data, card8 *endptr); -extern long cff_dict_pack (cff_dict *dict, card8 *dest, long destlen); +extern cff_dict *cff_dict_unpack(card8 * data, card8 * endptr); +extern long cff_dict_pack(cff_dict * dict, card8 * dest, long destlen); -extern void cff_dict_update (cff_dict *dict, cff_font *cff); +extern void cff_dict_update(cff_dict * dict, cff_font * cff); -#endif /* _CFF_DICT_H_ */ +#endif /* _CFF_DICT_H_ */ #ifndef _CS_TYPE2_H_ -#define _CS_TYPE2_H_ +# define _CS_TYPE2_H_ typedef struct { - int flags; /* unused in Type 2 charstring */ - double wx, wy; - struct { - double llx, lly, urx, ury; - } bbox; - struct { - double asb, adx, ady; - card8 bchar, achar; - } seac; /* unused in Type 2 charstring */ + int flags; /* unused in Type 2 charstring */ + double wx, wy; + struct { + double llx, lly, urx, ury; + } bbox; + struct { + double asb, adx, ady; + card8 bchar, achar; + } seac; /* unused in Type 2 charstring */ } cs_ginfo; -extern long cs_copy_charstring (card8 *dest, long destlen, - card8 *src, long srclen, - cff_index *gsubr, cff_index *subr, - double default_width, double nominal_width, cs_ginfo *ginfo); -#endif /* _CS_TYPE2_H_ */ +extern long cs_copy_charstring(card8 * dest, long destlen, + card8 * src, long srclen, + cff_index * gsubr, cff_index * subr, + double default_width, double nominal_width, + cs_ginfo * ginfo); +#endif /* _CS_TYPE2_H_ */ #define cff_is_cidfont(a) (a->flag & FONTTYPE_CIDFONT) #define cff_understandable(a) (a->header_major==1) -extern cff_font *read_cff(unsigned char *buf,long buflength, int subf); +extern cff_font *read_cff(unsigned char *buf, long buflength, int subf); -extern void write_cff(cff_font *cff, fd_entry *fd, int hack); -extern void write_cid_cff(cff_font *cffont, fd_entry *fd, int uglytype1fix) ; +extern void write_cff(cff_font * cff, fd_entry * fd); +extern void write_cid_cff(cff_font * cffont, fd_entry * fd); diff --git a/Build/source/texk/web2c/luatexdir/font/writeenc.c b/Build/source/texk/web2c/luatexdir/font/writeenc.c index feaf1407d1e..648992ba6cd 100644 --- a/Build/source/texk/web2c/luatexdir/font/writeenc.c +++ b/Build/source/texk/web2c/luatexdir/font/writeenc.c @@ -1,27 +1,28 @@ -/* -Copyright (c) 1996-2005 Han The Thanh, +/* writeenc.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: writeenc.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" +static const char _svn_version[] = + "$Id: writeenc.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writeenc.c $"; + /**********************************************************************/ /* All encoding entries go into AVL tree for fast search by name. */ @@ -93,7 +94,7 @@ void epdf_write_enc(char **glyph_names, integer fe_objnum) assert(fe_objnum != 0); pdf_begin_dict(fe_objnum, 1); pdf_puts("/Type /Encoding\n"); - pdf_printf("/Differences ["); + pdf_puts("/Differences ["); for (i = 0, i_old = -2; i < 256; i++) if (glyph_names[i] != notdef) { if (i == i_old + 1) /* no gap */ @@ -119,7 +120,7 @@ void write_enc(char **glyph_names, struct avl_table *tx_tree, integer fe_objnum) assert(fe_objnum != 0); pdf_begin_dict(fe_objnum, 1); pdf_puts("/Type /Encoding\n"); - pdf_printf("/Differences ["); + pdf_puts("/Differences ["); avl_t_init(&t, tx_tree); for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL; p = (int *) avl_t_next(&t)) { diff --git a/Build/source/texk/web2c/luatexdir/font/writefont.c b/Build/source/texk/web2c/luatexdir/font/writefont.c index 679929e32e4..5c6b2d905a0 100644 --- a/Build/source/texk/web2c/luatexdir/font/writefont.c +++ b/Build/source/texk/web2c/luatexdir/font/writefont.c @@ -1,42 +1,32 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, - -This file is part of pdfTeX. +/* writefont.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2009 Taco Hoekwater -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writefont.c 1139 2008-04-09 14:44:20Z taco $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" +#include "luatexfont.h" -extern void writetype0 (fd_entry * fd) ; -extern void writetype2 (fd_entry * fd) ; -extern unsigned long cidtogid_obj; - -#ifdef DO_TYPE1C -extern void writet1c(fd_entry * fd); /* in writecff.c */ -#endif - -extern void writet1w (fd_entry * fd); /* in writecff.c */ -extern void writetype1w (fd_entry * fd); -extern integer write_cid_tounicode(fo_entry * fo, internalfontnumber f); /* in tounicode.c */ - +static const char _svn_version[] = + "$Id: writefont.c 2097 2009-03-23 22:45:03Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writefont.c $"; void write_cid_fontdictionary(fo_entry * fo, internalfontnumber f); -void create_cid_fontdictionary(fm_entry * fm, integer font_objnum, internalfontnumber f); +void create_cid_fontdictionary(fm_entry * fm, integer font_objnum, + internalfontnumber f); /**********************************************************************/ @@ -97,7 +87,7 @@ fd_entry *new_fd_entry(void) fd->fn_objnum = 0; fd->all_glyphs = false; fd->write_ttf_glyph_names = false; - for (i = 0; i < INT_KEYS_NUM; i++) { + for (i = 0; i < FONT_KEYS_NUM; i++) { fd->font_dim[i].val = 0; fd->font_dim[i].set = false; } @@ -121,21 +111,21 @@ static void preset_fontmetrics(fd_entry * fd, internalfontnumber f) int i; fd->font_dim[ITALIC_ANGLE_CODE].val = divide_scaled(-atan(get_slant(f) / 65536.0) * (180 / M_PI), - pdf_font_size(f), 3); + pdf_font_size(f), 3); fd->font_dim[ASCENT_CODE].val = - divide_scaled(char_height(f, 'h'), pdf_font_size(f), 3); + divide_scaled(char_height(f, 'h'), pdf_font_size(f), 3); fd->font_dim[CAPHEIGHT_CODE].val = - divide_scaled(char_height(f, 'H'), pdf_font_size(f), 3); + divide_scaled(char_height(f, 'H'), pdf_font_size(f), 3); i = -divide_scaled(char_depth(f, 'y'), pdf_font_size(f), 3); fd->font_dim[DESCENT_CODE].val = i < 0 ? i : 0; fd->font_dim[STEMV_CODE].val = - divide_scaled(char_width(f, '.') / 3, pdf_font_size(f), 3); + divide_scaled(char_width(f, '.') / 3, pdf_font_size(f), 3); fd->font_dim[XHEIGHT_CODE].val = - divide_scaled(get_x_height(f), pdf_font_size(f), 3); + divide_scaled(get_x_height(f), pdf_font_size(f), 3); fd->font_dim[FONTBBOX1_CODE].val = 0; fd->font_dim[FONTBBOX2_CODE].val = fd->font_dim[DESCENT_CODE].val; fd->font_dim[FONTBBOX3_CODE].val = - divide_scaled(get_quad(f), pdf_font_size(f), 3); + divide_scaled(get_quad(f), pdf_font_size(f), 3); fd->font_dim[FONTBBOX4_CODE].val = fd->font_dim[CAPHEIGHT_CODE].val > fd->font_dim[ASCENT_CODE].val ? fd->font_dim[CAPHEIGHT_CODE].val : fd->font_dim[ASCENT_CODE].val; @@ -143,16 +133,48 @@ static void preset_fontmetrics(fd_entry * fd, internalfontnumber f) fd->font_dim[i].set = true; } +static void fix_fontmetrics(fd_entry * fd) +{ + int i; + intparm *p = (intparm *) fd->font_dim; + assert(p[FONTBBOX1_CODE].set && p[FONTBBOX2_CODE].set + && p[FONTBBOX3_CODE].set && p[FONTBBOX4_CODE].set); + /* make sure there is a rectangle */ + if (p[FONTBBOX3_CODE].val < p[FONTBBOX1_CODE].val) { + i = p[FONTBBOX3_CODE].val; + p[FONTBBOX3_CODE].val = p[FONTBBOX1_CODE].val; + p[FONTBBOX1_CODE].val = i; + } else if (p[FONTBBOX3_CODE].val == p[FONTBBOX1_CODE].val) + p[FONTBBOX3_CODE].val = p[FONTBBOX1_CODE].val + 1; + if (p[FONTBBOX4_CODE].val < p[FONTBBOX2_CODE].val) { + i = p[FONTBBOX4_CODE].val; + p[FONTBBOX4_CODE].val = p[FONTBBOX2_CODE].val; + p[FONTBBOX2_CODE].val = i; + } else if (p[FONTBBOX4_CODE].val == p[FONTBBOX2_CODE].val) + p[FONTBBOX4_CODE].val = p[FONTBBOX2_CODE].val + 1; + if (!p[ASCENT_CODE].set) { + p[ASCENT_CODE].val = p[FONTBBOX4_CODE].val; + p[ASCENT_CODE].set = true; + } + if (!p[DESCENT_CODE].set) { + p[DESCENT_CODE].val = p[FONTBBOX2_CODE].val; + p[DESCENT_CODE].set = true; + } + if (!p[CAPHEIGHT_CODE].set) { + p[CAPHEIGHT_CODE].val = p[FONTBBOX4_CODE].val; + p[CAPHEIGHT_CODE].set = true; + } +} + static void write_fontmetrics(fd_entry * fd) { int i; - if (fd->font_dim[FONTBBOX1_CODE].set && fd->font_dim[FONTBBOX2_CODE].set - && fd->font_dim[FONTBBOX3_CODE].set && fd->font_dim[FONTBBOX4_CODE].set) - pdf_printf("/%s [%i %i %i %i]\n", font_key[FONTBBOX1_CODE].pdfname, - (int) fd->font_dim[FONTBBOX1_CODE].val, - (int) fd->font_dim[FONTBBOX2_CODE].val, - (int) fd->font_dim[FONTBBOX3_CODE].val, - (int) fd->font_dim[FONTBBOX4_CODE].val); + fix_fontmetrics(fd); + pdf_printf("/%s [%i %i %i %i]\n", font_key[FONTBBOX1_CODE].pdfname, + (int) fd->font_dim[FONTBBOX1_CODE].val, + (int) fd->font_dim[FONTBBOX2_CODE].val, + (int) fd->font_dim[FONTBBOX3_CODE].val, + (int) fd->font_dim[FONTBBOX4_CODE].val); for (i = 0; i < GEN_KEY_NUM; i++) if (fd->font_dim[i].set) pdf_printf("/%s %i\n", font_key[i].pdfname, fd->font_dim[i].val); @@ -299,7 +321,7 @@ void get_char_range(fo_entry * fo, internalfontnumber f) { int i; assert(fo != NULL); - for (i = font_bc(f); i <= font_ec(f); i++) /* search for first_char and last_char */ + for (i = font_bc(f); i <= font_ec(f); i++) /* search for first_char and last_char */ if (pdf_char_marked(f, i)) break; fo->first_char = i; @@ -308,15 +330,31 @@ void get_char_range(fo_entry * fo, internalfontnumber f) break; fo->last_char = i; if ((fo->first_char > fo->last_char) - || !pdf_char_marked(f, fo->first_char)) { /* no character used from this font */ + || !pdf_char_marked(f, fo->first_char)) { /* no character used from this font */ fo->last_char = 0; fo->first_char = fo->last_char + 1; } } +static int font_has_subset(internalfontnumber f) +{ + int i, s; + for (i = font_bc(f); i <= font_ec(f); i++) /* search for first_char and last_char */ + if (pdf_char_marked(f, i)) + break; + s = i; + for (i = font_ec(f); i >= font_bc(f); i--) + if (pdf_char_marked(f, i)) + break; + if (s > i) + return 0; + else + return 1; +} + static void write_charwidth_array(fo_entry * fo, internalfontnumber f) { - int i, j, *ip, *fip, width; + int i, j, *ip, *fip; struct avl_traverser t; assert(fo->tx_tree != NULL); assert(fo->cw_objnum == 0); @@ -335,10 +373,7 @@ static void write_charwidth_array(fo_entry * fo, internalfontnumber f) j++; } j = i; - width = divide_scaled(char_width(f, i), pdf_font_size(f), 4); - pdf_printf("%i", (int) width / 10); /* see adv_char_width() in pdftex.web */ - if ((width = width % 10) != 0) - pdf_printf(".%i", width); + pdf_print_charwidth(f, i); } pdf_puts("]\n"); pdf_end_obj(); @@ -374,72 +409,89 @@ void register_fo_entry(fo_entry * fo) assert(fo != NULL); assert(fo->fm != NULL); assert(fo->fm->tfm_name != NULL); - assert (lookup_fo_entry(fo->fm->tfm_name) == NULL) ; - aa = avl_probe(fo_tree, fo); - assert(aa != NULL); + assert(lookup_fo_entry(fo->fm->tfm_name) == NULL); + aa = avl_probe(fo_tree, fo); + assert(aa != NULL); } /**********************************************************************/ static void write_fontfile(fd_entry * fd) { - assert(is_included(fd->fm)); - if (is_cidkeyed(fd->fm)) { - if (is_opentype(fd->fm)) - writetype0(fd); - else if (is_truetype(fd->fm)) - writetype2(fd); - else if (is_type1(fd->fm)) - writetype1w(fd); - else - assert(0); - } else { - if (is_type1(fd->fm)) -#ifdef DO_TYPE1C - writet1c(fd); -#else - writet1(fd); -#endif - else if (is_truetype(fd->fm)) - writettf(fd); - else if (is_opentype(fd->fm)) - writeotf(fd); - else - assert(0); - } - if (!fd->ff_found) - return; - assert(fd->ff_objnum == 0); - fd->ff_objnum = pdf_new_objnum(); - pdf_begin_dict(fd->ff_objnum, 0); /* font file stream */ - if (is_cidkeyed(fd->fm)) { - /* No subtype is used for TrueType-based OpenType fonts */ - if (is_opentype(fd->fm) || is_type1(fd->fm)) - pdf_puts("/Subtype /CIDFontType0C\n"); - /* else - pdf_puts("/Subtype /OpenType\n");*/ - } else { - if (is_type1(fd->fm)) - pdf_printf("/Length1 %i\n/Length2 %i\n/Length3 %i\n", - (int) t1_length1, (int) t1_length2, (int) t1_length3); - else if (is_truetype(fd->fm)) - pdf_printf("/Length1 %i\n", (int) ttf_length); - else if (is_opentype(fd->fm)) - pdf_puts("/Subtype /Type1C\n"); - else - assert(0); + assert(is_included(fd->fm)); + if (is_cidkeyed(fd->fm)) { + if (is_opentype(fd->fm)) + writetype0(fd); + else if (is_truetype(fd->fm)) + writetype2(fd); + else if (is_type1(fd->fm)) + writetype1w(fd); + else + assert(0); + } else { + if (is_type1(fd->fm)) + writet1(fd); + else if (is_truetype(fd->fm)) + writettf(fd); + else if (is_opentype(fd->fm)) + writeotf(fd); + else + assert(0); } - pdf_begin_stream(); - fb_flush(); - pdf_end_stream(); + if (!fd->ff_found) + return; + assert(fd->ff_objnum == 0); + fd->ff_objnum = pdf_new_objnum(); + pdf_begin_dict(fd->ff_objnum, 0); /* font file stream */ + if (is_cidkeyed(fd->fm)) { + /* No subtype is used for TrueType-based OpenType fonts */ + if (is_opentype(fd->fm) || is_type1(fd->fm)) + pdf_puts("/Subtype /CIDFontType0C\n"); + /* else + pdf_puts("/Subtype /OpenType\n"); */ + } else { + if (is_type1(fd->fm)) + pdf_printf("/Length1 %i\n/Length2 %i\n/Length3 %i\n", + (int) t1_length1, (int) t1_length2, (int) t1_length3); + else if (is_truetype(fd->fm)) + pdf_printf("/Length1 %i\n", (int) ttf_length); + else if (is_opentype(fd->fm)) + pdf_puts("/Subtype /Type1C\n"); + else + assert(0); + } + pdf_begin_stream(); + fb_flush(); + pdf_end_stream(); } /**********************************************************************/ static void write_fontdescriptor(fd_entry * fd) { + static const int std_flags[] = { + /* indices for << start with 0, but bits start with 1, so the numbers + * for << are 1 lower than the bits in table 5.20 */ + /* *INDENT-OFF* */ + 1 + 2 + (1 << 5), /* Courier */ + 1 + 2 + (1 << 5) + (1 << 18),/* Courier-Bold */ + 1 + 2 + (1 << 5) + (1 << 6), /* Courier-Oblique */ + 1 + 2 + (1 << 5) + (1 << 6) + (1 << 18),/* Courier-BoldOblique */ + (1 << 5), /* Helvetica */ + (1 << 5) + (1 << 18),/* Helvetica-Bold */ + (1 << 5) + (1 << 6), /* Helvetica-Oblique */ + (1 << 5) + (1 << 6) + (1 << 18),/* Helvetica-BoldOblique */ + 4, /* Symbol */ + 2 + (1 << 5), /* Times-Roman */ + 2 + (1 << 5) + (1 << 18),/* Times-Bold */ + 2 + (1 << 5) + (1 << 6), /* Times-Italic */ + 2 + (1 << 5) + (1 << 6) + (1 << 18),/* Times-BoldItalic */ + 4 /* ZapfDingbats */ + /* *INDENT-ON* */ + }; char *glyph; struct avl_traverser t; + int fd_flags; assert(fd != NULL && fd->fm != NULL); if (is_fontfile(fd->fm)) @@ -451,13 +503,24 @@ static void write_fontdescriptor(fd_entry * fd) pdf_begin_dict(fd->fd_objnum, 1); pdf_puts("/Type /FontDescriptor\n"); write_fontname(fd, "FontName"); - if (!fd->ff_found && fd->fm->fd_flags == 4) - pdf_puts("/Flags 34\n"); /* assumes a roman sans serif font */ - else - pdf_printf("/Flags %i\n", (int) fd->fm->fd_flags); + if (fd->fm->fd_flags != FD_FLAGS_NOT_SET_IN_MAPLINE) + fd_flags = (int) fd->fm->fd_flags; + else if (fd->ff_found) + fd_flags = FD_FLAGS_DEFAULT_EMBED; + else { + fd_flags = is_std_t1font(fd->fm) + ? std_flags[check_std_t1font(fd->fm->ps_name)] + : FD_FLAGS_DEFAULT_NON_EMBED; + pdftex_warn + ("No flags specified for non-embedded font `%s' (%s) (I'm using %i): " + "fix your map entry.", + fd->fm->ps_name != NULL ? fd->fm->ps_name : "No name given", + fd->fm->tfm_name, fd_flags); + } + pdf_printf("/Flags %i\n", fd_flags); write_fontmetrics(fd); if (is_cidkeyed(fd->fm)) { - if (is_type1(fd->fm)) + if (is_type1(fd->fm)) pdf_printf("/FontFile3 %i 0 R\n", (int) fd->ff_objnum); else if (is_truetype(fd->fm)) pdf_printf("/FontFile2 %i 0 R\n", (int) fd->ff_objnum); @@ -466,36 +529,36 @@ static void write_fontdescriptor(fd_entry * fd) else assert(0); } else { - if (fd->ff_found) { - if (is_subsetted(fd->fm) && is_type1(fd->fm)) { - /* /CharSet is optional; names may appear in any order */ - assert(fd->gl_tree != NULL); - avl_t_init(&t, fd->gl_tree); - pdf_puts("/CharSet ("); - for (glyph = (char *) avl_t_first(&t, fd->gl_tree); glyph != NULL; - glyph = (char *) avl_t_next(&t)) - pdf_printf("/%s", glyph); - pdf_puts(")\n"); + if (fd->ff_found) { + if (is_subsetted(fd->fm) && is_type1(fd->fm)) { + /* /CharSet is optional; names may appear in any order */ + assert(fd->gl_tree != NULL); + avl_t_init(&t, fd->gl_tree); + pdf_puts("/CharSet ("); + for (glyph = (char *) avl_t_first(&t, fd->gl_tree); + glyph != NULL; glyph = (char *) avl_t_next(&t)) + pdf_printf("/%s", glyph); + pdf_puts(")\n"); + } + if (is_type1(fd->fm)) + pdf_printf("/FontFile %i 0 R\n", (int) fd->ff_objnum); + else if (is_truetype(fd->fm)) + pdf_printf("/FontFile2 %i 0 R\n", (int) fd->ff_objnum); + else if (is_opentype(fd->fm)) + pdf_printf("/FontFile3 %i 0 R\n", (int) fd->ff_objnum); + else + assert(0); } - if (is_type1(fd->fm)) - pdf_printf("/FontFile %i 0 R\n", (int) fd->ff_objnum); - else if (is_truetype(fd->fm)) - pdf_printf("/FontFile2 %i 0 R\n", (int) fd->ff_objnum); - else if (is_opentype(fd->fm)) - pdf_printf("/FontFile3 %i 0 R\n", (int) fd->ff_objnum); - else - assert(0); - } } /* TODO: Optional keys for CID fonts. - + The most interesting ones are - /Style << /Panose <12-byte string>>> + /Style << /Panose <12-byte string>>> and - /CIDSET + /CIDSET the latter can be used in subsets, to give the included CIDs as a bitmap on the whole list. - */ + */ pdf_end_dict(); } @@ -535,11 +598,7 @@ void write_fontdictionary(fo_entry * fo) pdf_puts("/Type /Font\n"); pdf_puts("/Subtype /"); if (is_type1(fo->fm)) -#ifdef DO_TYPE1C - pdf_printf("%s\n", "Type1C"); -#else pdf_printf("%s\n", "Type1"); -#endif else if (is_truetype(fo->fm)) pdf_printf("%s\n", "TrueType"); else if (is_opentype(fo->fm)) @@ -551,14 +610,14 @@ void write_fontdictionary(fo_entry * fo) pdf_printf("/FontDescriptor %i 0 R\n", (int) fo->fd->fd_objnum); assert(fo->cw_objnum != 0); pdf_printf("/FirstChar %i\n/LastChar %i\n/Widths %i 0 R\n", - (int) fo->first_char, (int) fo->last_char, - (int) fo->cw_objnum); - if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL && fo->fe->fe_objnum != 0) + (int) fo->first_char, (int) fo->last_char, (int) fo->cw_objnum); + if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL + && fo->fe->fe_objnum != 0) pdf_printf("/Encoding %i 0 R\n", (int) fo->fe->fe_objnum); if (fo->tounicode_objnum != 0) pdf_printf("/ToUnicode %i 0 R\n", (int) fo->tounicode_objnum); if (pdf_font_attr(fo->tex_font) != get_nullstr()) { - pdf_print(pdf_font_attr(fo->tex_font)); + pdf_print(pdf_font_attr(fo->tex_font)); pdf_puts("\n"); } pdf_end_dict(); @@ -596,7 +655,8 @@ void create_fontdictionary(fm_entry * fm, integer font_objnum, { fo_entry *fo = new_fo_entry(); get_char_range(fo, f); /* set fo->first_char and fo->last_char from f */ - if (fo->last_char>255) fo->last_char=255; /* added 9-4-2008, mantis #25 */ + if (fo->last_char > 255) + fo->last_char = 255; /* added 9-4-2008, mantis #25 */ assert(fo->last_char >= fo->first_char); fo->fm = fm; fo->fo_objnum = font_objnum; @@ -605,7 +665,7 @@ void create_fontdictionary(fm_entry * fm, integer font_objnum, fo->fe = get_fe_entry(fo->fm->encname); /* returns NULL if .enc file couldn't be opened */ if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) { if (fo->fe->fe_objnum == 0) - fo->fe->fe_objnum = pdf_new_objnum(); /* then it will be written out */ + fo->fe->fe_objnum = pdf_new_objnum(); /* then it will be written out */ /* mark encoding pairs used by TeX to optimize encoding vector */ fo->fe->tx_tree = mark_chars(fo, fo->fe->tx_tree, f); } @@ -613,37 +673,37 @@ void create_fontdictionary(fm_entry * fm, integer font_objnum, fo->tx_tree = mark_chars(fo, fo->tx_tree, f); /* for write_charwidth_array() */ write_charwidth_array(fo, f); if (!is_builtin(fo->fm)) { - if (is_type1(fo->fm)) { - if ((fo->fd = lookup_fontdescriptor(fo)) == NULL) { - create_fontdescriptor(fo, f); - register_fd_entry(fo->fd); - } - } else - create_fontdescriptor(fo, f); - if (fo->fe != NULL) { - mark_reenc_glyphs(fo, f); - if (!is_type1(fo->fm)) { - /* mark reencoded characters as chars on TeX level */ - assert(fo->fd->tx_tree == NULL); - fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); - if (is_truetype(fo->fm)) - fo->fd->write_ttf_glyph_names = true; - } - } else - /* mark non-reencoded characters as chars on TeX level */ - fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); - if (!is_type1(fo->fm)) - write_fontdescriptor(fo->fd); + if (is_type1(fo->fm)) { + if ((fo->fd = lookup_fontdescriptor(fo)) == NULL) { + create_fontdescriptor(fo, f); + register_fd_entry(fo->fd); + } + } else + create_fontdescriptor(fo, f); + if (fo->fe != NULL) { + mark_reenc_glyphs(fo, f); + if (!is_type1(fo->fm)) { + /* mark reencoded characters as chars on TeX level */ + assert(fo->fd->tx_tree == NULL); + fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); + if (is_truetype(fo->fm)) + fo->fd->write_ttf_glyph_names = true; + } + } else + /* mark non-reencoded characters as chars on TeX level */ + fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); + if (!is_type1(fo->fm)) + write_fontdescriptor(fo->fd); } else { - /* builtin fonts still need the /Widths array and /FontDescriptor - * (to avoid error 'font FOO contains bad /BBox') - */ - create_fontdescriptor(fo, f); - write_fontdescriptor(fo->fd); - if (!is_std_t1font(fo->fm)) - pdftex_warn("font `%s' is not a standard font; " - "I suppose it is available to your PDF viewer then", - fo->fm->ps_name); + /* builtin fonts still need the /Widths array and /FontDescriptor + * (to avoid error 'font FOO contains bad /BBox') + */ + create_fontdescriptor(fo, f); + write_fontdescriptor(fo->fd); + if (!is_std_t1font(fo->fm)) + pdftex_warn("font `%s' is not a standard font; " + "I suppose it is available to your PDF viewer then", + fo->fm->ps_name); } if (is_type1(fo->fm)) register_fo_entry(fo); @@ -658,47 +718,57 @@ void do_pdf_font(integer font_objnum, internalfontnumber f) { fm_entry *fm; /* This is not 100% true: CID is actually needed whenever (and - * only) there are more than 256 separate glyphs used. But for - * now, just assume the user knows what he is doing; - */ - if (font_encodingbytes(f)==2) { - /* Create a virtual font map entry, as this is needed by the - * rest of the font inclusion mechanism. - */ - fm = new_fm_entry(); - fm->tfm_name = font_name(f); /* or whatever, not a real tfm */ - fm->ff_name = font_filename(f); /* the actual file */ - fm->encname = font_encodingname(f); /* for the CIDSystemInfo */ - fm->ps_name = font_fullname(f); /* the true name */ - fm->slant = font_slant(f); /* slant factor */ - fm->extend = font_extend(f); /* extension factor */ - fm->fd_flags = 4; /* can perhaps be done better */ - fm->in_use = true; - - switch (font_format(f)) { - case opentype_format: set_opentype(fm); break; - case truetype_format: set_truetype(fm); break; - case type1_format: set_type1(fm); break; - default: - pdftex_fail("writefont.c: The file format (%s) for font `%s' is incompatible with wide characters\n", - font_format_name(f),font_name(f)); - } - /* This makes "unknown" default to subsetted inclusion */ - if (font_embedding(f)!=no_embedding) { - set_included(fm); - if (font_embedding(f)!=full_embedding) { - set_subsetted(fm); - } - } - set_cidkeyed(fm); - create_cid_fontdictionary(fm, font_objnum, f); - + * only) there are more than 256 separate glyphs used. But for + * now, just assume the user knows what he is doing; + */ + if (!font_has_subset(f)) + return; + + if (font_encodingbytes(f) == 2) { + /* Create a virtual font map entry, as this is needed by the + * rest of the font inclusion mechanism. + */ + fm = new_fm_entry(); + fm->tfm_name = font_name(f); /* or whatever, not a real tfm */ + fm->ff_name = font_filename(f); /* the actual file */ + fm->encname = font_encodingname(f); /* for the CIDSystemInfo */ + fm->ps_name = font_fullname(f); /* the true name */ + fm->slant = font_slant(f); /* slant factor */ + fm->extend = font_extend(f); /* extension factor */ + fm->fd_flags = 4; /* can perhaps be done better */ + fm->in_use = true; + + switch (font_format(f)) { + case opentype_format: + set_opentype(fm); + break; + case truetype_format: + set_truetype(fm); + break; + case type1_format: + set_type1(fm); + break; + default: + pdftex_fail + ("writefont.c: The file format (%s) for font `%s' is incompatible with wide characters\n", + font_format_name(f), font_name(f)); + } + /* This makes "unknown" default to subsetted inclusion */ + if (font_embedding(f) != no_embedding) { + set_included(fm); + if (font_embedding(f) != full_embedding) { + set_subsetted(fm); + } + } + set_cidkeyed(fm); + create_cid_fontdictionary(fm, font_objnum, f); + } else { - fm = hasfmentry(f) ? (fm_entry *) font_map(f) : NULL; - if (fm == NULL || (fm->ps_name == NULL && fm->ff_name == NULL)) - writet3(font_objnum, f); - else - create_fontdictionary(fm, font_objnum, f); + fm = hasfmentry(f) ? (fm_entry *) font_map(f) : NULL; + if (fm == NULL || (fm->ps_name == NULL && fm->ff_name == NULL)) + writet3(font_objnum, f); + else + create_fontdictionary(fm, font_objnum, f); } } @@ -717,11 +787,11 @@ void do_pdf_font(integer font_objnum, internalfontnumber f) int comp_glw_entry(const void *pa, const void *pb, void *p) { - unsigned short i, j; - i = (*(glw_entry *)pa).id; - j = (*(glw_entry *)pb).id; - cmp_return(i,j); - return 0; + unsigned short i, j; + i = (*(glw_entry *) pa).id; + j = (*(glw_entry *) pb).id; + cmp_return(i, j); + return 0; } void create_cid_fontdescriptor(fo_entry * fo, internalfontnumber f) @@ -744,26 +814,29 @@ void create_cid_fontdescriptor(fo_entry * fo, internalfontnumber f) indexes, and those are limited to 16-bit values. */ -static void mark_cid_subset_glyphs(fo_entry *fo, internal_font_number f) -{ - int i, k; - glw_entry *j; - void *aa; - for (k = 1; k <= max_font_id(); k++) { - if ( k == f || -f == pdf_font_num(k)) { - for (i = font_bc(k); i <= font_ec(k); i++) { - if (char_exists(k,i) && char_used(k,i)) { - j = xtalloc(1,glw_entry); - j->id = char_index(k,i); - j->wd = divide_scaled_n(char_width(k, i), pdf_font_size(k), 10000.0); - if ((glw_entry *)avl_find(fo->fd->gl_tree,j) == NULL) { - aa = avl_probe(fo->fd->gl_tree, j); - assert(aa != NULL); - } - } - } +static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) +{ + int i, k, l; + glw_entry *j; + void *aa; + for (k = 1; k <= max_font_id(); k++) { + if (k == f || -f == pdf_font_num(k)) { + l = pdf_font_size(k); + for (i = font_bc(k); i <= font_ec(k); i++) { + if (char_exists(k, i) && char_used(k, i)) { + j = xtalloc(1, glw_entry); + j->id = char_index(k, i); + j->wd = divide_scaled_n(char_width(k, i), l, 10000.0); + if ((glw_entry *) avl_find(fo->fd->gl_tree, j) == NULL) { + aa = avl_probe(fo->fd->gl_tree, j); + assert(aa != NULL); + } else { + xfree(j); + } + } + } + } } - } } /* @@ -782,38 +855,47 @@ static void mark_cid_subset_glyphs(fo_entry *fo, internal_font_number f) static void write_cid_charwidth_array(fo_entry * fo) { - int i, j; - glw_entry *glyph; - struct avl_traverser t; - - assert(fo->cw_objnum == 0); - fo->cw_objnum = pdf_new_objnum(); - pdf_begin_obj(fo->cw_objnum, 1); - avl_t_init(&t, fo->fd->gl_tree); - glyph = (glw_entry *) avl_t_first(&t, fo->fd->gl_tree); - assert(glyph != NULL); - i = glyph->id; - pdf_printf("[ %i [", i); - for (; glyph != NULL; glyph = (glw_entry *) avl_t_next(&t)) { - j = glyph->wd; - if (glyph->id>(i+1)) { - pdf_printf("] %i [", glyph->id); - j = glyph->wd; - } - if (glyph->id==(i+1)) - pdf_puts(" "); - pdf_printf("%i", (j/10)); - if ((j % 10) != 0) - pdf_printf(".%i", (j % 10)); + int i, j; + glw_entry *glyph; + struct avl_traverser t; + + assert(fo->cw_objnum == 0); + fo->cw_objnum = pdf_new_objnum(); + pdf_begin_obj(fo->cw_objnum, 1); + avl_t_init(&t, fo->fd->gl_tree); + glyph = (glw_entry *) avl_t_first(&t, fo->fd->gl_tree); + assert(glyph != NULL); i = glyph->id; - } - pdf_puts("]]\n"); - pdf_end_obj(); + pdf_printf("[ %i [", i); + for (; glyph != NULL; glyph = (glw_entry *) avl_t_next(&t)) { + j = glyph->wd; + if (glyph->id > (unsigned) (i + 1)) { + pdf_printf("] %i [", glyph->id); + j = glyph->wd; + } + if (glyph->id == (unsigned) (i + 1)) + pdf_puts(" "); + + if (j < 0) { + pdf_puts("-"); + j = -j; + } + + /* pdf_print_charwidth(f, i); */ + + pdf_printf("%i", (j / 10)); + if ((j % 10) != 0) + pdf_printf(".%i", (j % 10)); + + i = glyph->id; + } + pdf_puts("]]\n"); + pdf_end_obj(); } void create_cid_fontdictionary(fm_entry * fm, integer font_objnum, - internalfontnumber f) + internalfontnumber f) { fo_entry *fo = new_fo_entry(); get_char_range(fo, f); /* set fo->first_char and fo->last_char from f */ @@ -821,66 +903,68 @@ void create_cid_fontdictionary(fm_entry * fm, integer font_objnum, fo->fm = fm; fo->fo_objnum = font_objnum; fo->tex_font = f; - create_cid_fontdescriptor (fo, f); - mark_cid_subset_glyphs (fo,f); + create_cid_fontdescriptor(fo, f); + mark_cid_subset_glyphs(fo, f); if (is_subsetted(fo->fm)) { - /* - this is a bit sneaky. |make_subset_tag()| actually expects the glyph tree - to contain strings instead of |glw_entry| items. However, all calculations - are done using explicit typecasts, so it works out ok. - */ - make_subset_tag(fo->fd); + /* + this is a bit sneaky. |make_subset_tag()| actually expects the glyph tree + to contain strings instead of |glw_entry| items. However, all calculations + are done using explicit typecasts, so it works out ok. + */ + make_subset_tag(fo->fd); } write_cid_charwidth_array(fo); write_fontdescriptor(fo->fd); - - write_cid_fontdictionary(fo,f); + + write_cid_fontdictionary(fo, f); + xfree(fo); } void write_cid_fontdictionary(fo_entry * fo, internalfontnumber f) { int i; - fo->tounicode_objnum = write_cid_tounicode(fo,f); + fo->tounicode_objnum = write_cid_tounicode(fo, f); pdf_begin_dict(fo->fo_objnum, 1); pdf_puts("/Type /Font\n"); pdf_puts("/Subtype /Type0\n"); pdf_puts("/Encoding /Identity-H\n"); write_fontname(fo->fd, "BaseFont"); - i = pdf_new_objnum(); + i = pdf_new_objnum(); pdf_printf("/DescendantFonts [%i 0 R]\n", i); /* todo: the ToUnicode CMap */ - if (fo->tounicode_objnum != 0) - pdf_printf("/ToUnicode %i 0 R\n", (int) fo->tounicode_objnum); - + if (fo->tounicode_objnum != 0) + pdf_printf("/ToUnicode %i 0 R\n", (int) fo->tounicode_objnum); + pdf_end_dict(); pdf_begin_dict(i, 1); pdf_puts("/Type /Font\n"); if (is_opentype(fo->fm) || is_type1(fo->fm)) { - pdf_puts("/Subtype /CIDFontType0\n"); + pdf_puts("/Subtype /CIDFontType0\n"); } else { - pdf_puts("/Subtype /CIDFontType2\n"); - pdf_printf("/CIDToGIDMap /Identity\n"); + pdf_puts("/Subtype /CIDFontType2\n"); + pdf_printf("/CIDToGIDMap /Identity\n"); } write_fontname(fo->fd, "BaseFont"); pdf_printf("/FontDescriptor %i 0 R\n", (int) fo->fd->fd_objnum); - pdf_printf("/W %i 0 R\n",(int) fo->cw_objnum); + pdf_printf("/W %i 0 R\n", (int) fo->cw_objnum); pdf_printf("/CIDSystemInfo <<\n"); - pdf_printf("/Registry (%s)\n", (font_cidregistry(f)? font_cidregistry(f): "Adobe")); - pdf_printf("/Ordering (%s)\n",(font_cidordering(f)? font_cidordering(f) : "Identity")) ; - pdf_printf("/Supplement %u\n",(unsigned int)font_cidsupplement(f)); + pdf_printf("/Registry (%s)\n", + (font_cidregistry(f) ? font_cidregistry(f) : "Adobe")); + pdf_printf("/Ordering (%s)\n", + (font_cidordering(f) ? font_cidordering(f) : "Identity")); + pdf_printf("/Supplement %u\n", (unsigned int) font_cidsupplement(f)); pdf_printf(">>\n"); /* I doubt there is anything useful that could be written here */ /* - if (pdf_font_attr(fo->tex_font) != get_nullstr()) { - pdf_print(pdf_font_attr(fo->tex_font)); - pdf_puts("\n"); - } - */ + if (pdf_font_attr(fo->tex_font) != get_nullstr()) { + pdf_print(pdf_font_attr(fo->tex_font)); + pdf_puts("\n"); + } + */ pdf_end_dict(); } - diff --git a/Build/source/texk/web2c/luatexdir/font/writet3.c b/Build/source/texk/web2c/luatexdir/font/writet3.c index 42827d1b124..4e349860d22 100644 --- a/Build/source/texk/web2c/luatexdir/font/writet3.c +++ b/Build/source/texk/web2c/luatexdir/font/writet3.c @@ -1,34 +1,36 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, +/* writet3.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: writet3.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" #include #include #include +#include "luatexfont.h" + +static const char _svn_version[] = + "$Id: writet3.c 1712 2009-01-02 10:54:55Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writet3.c $"; #define T3_BUF_SIZE 1024 typedef char t3_line_entry; -define_array (t3_line); +define_array(t3_line); FILE *t3_file; static boolean t3_image_used; @@ -40,30 +42,18 @@ static float t3_font_scale; static integer t3_b0, t3_b1, t3_b2, t3_b3; static boolean is_pk_font; -static unsigned char *t3_buffer = NULL; -static integer t3_size = 0; -static integer t3_curbyte = 0; - - -#define t3_open() \ - open_input(&t3_file, kpse_miscfonts_format, FOPEN_RBIN_MODE) -#define t3_read_file() readbinfile(t3_file,&t3_buffer,&t3_size) -#define t3_close() xfclose(t3_file, cur_file_name) -#define t3_getchar() t3_buffer[t3_curbyte++] -#define t3_eof() (t3_curbyte>t3_size) - -#define t3_prefix(s) (!strncmp(t3_line_array, s, strlen(s))) -#define t3_putchar(c) pdfout(c) - - +/* not static because used by pkin.c */ +unsigned char *t3_buffer = NULL; +integer t3_size = 0; +integer t3_curbyte = 0; #define t3_check_eof() \ if (t3_eof()) \ pdftex_fail("unexpected end of file"); -static void update_bbox (integer llx, integer lly, integer urx, integer ury, - boolean is_first_glyph) +static void update_bbox(integer llx, integer lly, integer urx, integer ury, + boolean is_first_glyph) { if (is_first_glyph) { t3_b0 = llx; @@ -82,111 +72,111 @@ static void update_bbox (integer llx, integer lly, integer urx, integer ury, } } -static integer get_pk_font_scale (internalfontnumber f) +static integer get_pk_font_scale(internalfontnumber f) { return - divide_scaled (pk_scale_factor, - divide_scaled (pdf_font_size(f), one_hundred_bp, + divide_scaled(pk_scale_factor, + divide_scaled(pdf_font_size(f), one_hundred_bp, fixed_decimal_digits + 2), 0); } -static integer pk_char_width (internalfontnumber f, scaled w) +static integer pk_char_width(internalfontnumber f, scaled w) { return - divide_scaled (divide_scaled (w, pdf_font_size(f), 7), - get_pk_font_scale (f), 0); + divide_scaled(divide_scaled(w, pdf_font_size(f), 7), + get_pk_font_scale(f), 0); } -scaled get_pk_char_width (internalfontnumber f, scaled w) +scaled get_pk_char_width(internalfontnumber f, scaled w) { - return (get_pk_font_scale (f) / 100000.0) * - (pk_char_width (f, w) / 100.0) * pdf_font_size(f); + return (get_pk_font_scale(f) / 100000.0) * + (pk_char_width(f, w) / 100.0) * pdf_font_size(f); } -static boolean writepk (internalfontnumber f) +static boolean writepk(internalfontnumber f) { kpse_glyph_file_type font_ret; integer llx, lly, urx, ury; integer cw, rw, i, j; halfword *row; char *name; - char *ftemp = NULL; + char *ftemp = NULL; chardesc cd; boolean is_null_glyph, check_preamble; integer dpi; - int callback_id=0; - int file_opened=0; - int mallocsize=0; - if (t3_buffer!=NULL) { - xfree(t3_buffer); - t3_buffer=NULL; + int callback_id = 0; + int file_opened = 0; + int mallocsize = 0; + if (t3_buffer != NULL) { + xfree(t3_buffer); + t3_buffer = NULL; } - t3_curbyte=0; - t3_size=0; + t3_curbyte = 0; + t3_size = 0; - callback_id=callback_defined(find_pk_file_callback); + callback_id = callback_defined(find_pk_file_callback); - if (callback_id>0) { - dpi = round (fixed_pk_resolution * - (((float) pdf_font_size(f)) / font_dsize(f))); - /* .dpi/.pk */ - cur_file_name = font_name(f); - mallocsize = strlen(cur_file_name)+24+9; - name = xmalloc(mallocsize); - snprintf(name,mallocsize,"%ddpi/%s.%dpk",(int)fixed_pk_resolution,cur_file_name,(int)dpi); - if(run_callback(callback_id,"S->S",name,&ftemp)) { - if(ftemp!=NULL&&strlen(ftemp)) { - free(name); - name = xstrdup(ftemp); - free(ftemp); - } - } - } else { - dpi = - kpse_magstep_fix (round - (fixed_pk_resolution * - (((float) pdf_font_size(f)) / font_dsize(f))), - fixed_pk_resolution, NULL); - cur_file_name = font_name(f); - name = kpse_find_pk (cur_file_name, (unsigned) dpi, &font_ret); - if (name == NULL || - !FILESTRCASEEQ (cur_file_name, font_ret.name) || - !kpse_bitmap_tolerance ((float) font_ret.dpi, (float) dpi)) { - pdftex_warn ("Font %s at %i not found", cur_file_name, (int) dpi); - cur_file_name = NULL; - return false; - } - } - callback_id=callback_defined(read_pk_file_callback); - if (callback_id>0) { - if(! ( run_callback(callback_id,"S->bSd",name, &file_opened, &t3_buffer,&t3_size) && - file_opened && - t3_size>0 ) ) { - pdftex_warn ("Font %s at %i not found", cur_file_name, (int)dpi); - cur_file_name = NULL; - return false; - } + if (callback_id > 0) { + dpi = round(fixed_pk_resolution * + (((float) pdf_font_size(f)) / font_dsize(f))); + /* .dpi/.pk */ + cur_file_name = font_name(f); + mallocsize = strlen(cur_file_name) + 24 + 9; + name = xmalloc(mallocsize); + snprintf(name, mallocsize, "%ddpi/%s.%dpk", (int) fixed_pk_resolution, + cur_file_name, (int) dpi); + if (run_callback(callback_id, "S->S", name, &ftemp)) { + if (ftemp != NULL && strlen(ftemp)) { + free(name); + name = xstrdup(ftemp); + free(ftemp); + } + } + } else { + dpi = + kpse_magstep_fix(round + (fixed_pk_resolution * + (((float) pdf_font_size(f)) / font_dsize(f))), + fixed_pk_resolution, NULL); + cur_file_name = font_name(f); + name = kpse_find_pk(cur_file_name, (unsigned) dpi, &font_ret); + if (name == NULL || + !FILESTRCASEEQ(cur_file_name, font_ret.name) || + !kpse_bitmap_tolerance((float) font_ret.dpi, (float) dpi)) { + pdftex_fail("Font %s at %i not found", cur_file_name, (int) dpi); + } + } + callback_id = callback_defined(read_pk_file_callback); + if (callback_id > 0) { + if (! + (run_callback + (callback_id, "S->bSd", name, &file_opened, &t3_buffer, &t3_size) + && file_opened && t3_size > 0)) { + pdftex_warn("Font %s at %i not found", cur_file_name, (int) dpi); + cur_file_name = NULL; + return false; + } } else { - t3_file = xfopen (name, FOPEN_RBIN_MODE); - t3_read_file(); - t3_close(); + t3_file = xfopen(name, FOPEN_RBIN_MODE); + recorder_record_input(name); + t3_read_file(); + t3_close(); } t3_image_used = true; is_pk_font = true; - if (tracefilenames) - tex_printf (" <%s", (char *) name); + if (tracefilenames) + tex_printf(" <%s", (char *) name); cd.rastersize = 256; - cd.raster = xtalloc (cd.rastersize, halfword); + cd.raster = xtalloc(cd.rastersize, halfword); check_preamble = true; - while (readchar (check_preamble, &cd) != 0) { + while (readchar(check_preamble, &cd) != 0) { check_preamble = false; - if (!pdf_char_marked (f, cd.charcode)) + if (!pdf_char_marked(f, cd.charcode)) continue; t3_char_widths[cd.charcode] = - pk_char_width (f, get_charwidth (f, cd.charcode)); + pk_char_width(f, get_charwidth(f, cd.charcode)); if (cd.cwidth < 1 || cd.cheight < 1) { - cd.xescape = cd.cwidth = - round (t3_char_widths[cd.charcode] / 100.0); + cd.xescape = cd.cwidth = round(t3_char_widths[cd.charcode] / 100.0); cd.cheight = 1; cd.xoff = 0; cd.yoff = 0; @@ -197,44 +187,44 @@ static boolean writepk (internalfontnumber f) lly = cd.yoff - cd.cheight + 1; urx = cd.cwidth + llx + 1; ury = cd.cheight + lly; - update_bbox (llx, lly, urx, ury, t3_glyph_num == 0); + update_bbox(llx, lly, urx, ury, t3_glyph_num == 0); t3_glyph_num++; - pdf_new_dict (0, 0, 0); + pdf_new_dict(0, 0, 0); t3_char_procs[cd.charcode] = obj_ptr; - pdf_begin_stream (); - pdf_print_real (t3_char_widths[cd.charcode], 2); - pdf_printf (" 0 %i %i %i %i d1\n", - (int) llx, (int) lly, (int) urx, (int) ury); + pdf_begin_stream(); + pdf_print_real(t3_char_widths[cd.charcode], 2); + pdf_printf(" 0 %i %i %i %i d1\n", + (int) llx, (int) lly, (int) urx, (int) ury); if (is_null_glyph) goto end_stream; - pdf_printf ("q\n%i 0 0 %i %i %i cm\nBI\n", (int) cd.cwidth, - (int) cd.cheight, (int) llx, (int) lly); - pdf_printf ("/W %i\n/H %i\n", (int) cd.cwidth, (int) cd.cheight); - pdf_puts ("/IM true\n/BPC 1\n/D [1 0]\nID "); + pdf_printf("q\n%i 0 0 %i %i %i cm\nBI\n", (int) cd.cwidth, + (int) cd.cheight, (int) llx, (int) lly); + pdf_printf("/W %i\n/H %i\n", (int) cd.cwidth, (int) cd.cheight); + pdf_puts("/IM true\n/BPC 1\n/D [1 0]\nID "); cw = (cd.cwidth + 7) / 8; rw = (cd.cwidth + 15) / 16; row = cd.raster; for (i = 0; i < cd.cheight; i++) { for (j = 0; j < rw - 1; j++) { - pdfout (*row / 256); - pdfout (*row % 256); + pdfout(*row / 256); + pdfout(*row % 256); row++; } - pdfout (*row / 256); + pdfout(*row / 256); if (2 * rw == cw) - pdfout (*row % 256); + pdfout(*row % 256); row++; } - pdf_puts ("\nEI\nQ\n"); + pdf_puts("\nEI\nQ\n"); end_stream: - pdf_end_stream (); + pdf_end_stream(); } - xfree (cd.raster); + xfree(cd.raster); cur_file_name = NULL; return true; } -void writet3 (int objnum, internalfontnumber f) +void writet3(int objnum, internalfontnumber f) { int i; @@ -250,99 +240,99 @@ void writet3 (int objnum, internalfontnumber f) t3_char_procs[i] = 0; t3_char_widths[i] = 0; } - pack_file_name (tex_font_name(f), get_nullstr (), maketexlstring (".pgc",4)); - cur_file_name = makecstring (make_name_string ()); + pack_file_name(tex_font_name(f), get_nullstr(), maketexlstring(".pgc", 4)); + cur_file_name = makecstring(make_name_string()); is_pk_font = false; - if (t3_buffer!=NULL) { - xfree(t3_buffer); - t3_buffer=NULL; + if (t3_buffer != NULL) { + xfree(t3_buffer); + t3_buffer = NULL; + } + t3_curbyte = 0; + t3_size = 0; + if (!writepk(f)) { + cur_file_name = NULL; + return; } - t3_curbyte=0; - t3_size=0; - if (!writepk (f)) { - cur_file_name = NULL; - return; - } for (i = font_bc(f); i <= font_ec(f); i++) - if (pdf_char_marked (f, i)) + if (pdf_char_marked(f, i)) break; first_char = i; for (i = font_ec(f); i > first_char; i--) - if (pdf_char_marked (f, i)) + if (pdf_char_marked(f, i)) break; last_char = i; - pdf_begin_dict (objnum, 1); /* Type 3 font dictionary */ - pdf_puts ("/Type /Font\n/Subtype /Type3\n"); - pdf_printf ("/Name /F%i\n", (int) f); - if (pdf_font_attr(f) != get_nullstr ()) { - pdf_print (pdf_font_attr(f)); - pdf_puts ("\n"); + pdf_begin_dict(objnum, 1); /* Type 3 font dictionary */ + pdf_puts("/Type /Font\n/Subtype /Type3\n"); + pdf_printf("/Name /F%i\n", (int) f); + if (pdf_font_attr(f) != get_nullstr()) { + pdf_print(pdf_font_attr(f)); + pdf_puts("\n"); } if (is_pk_font) { - pk_font_scale = get_pk_font_scale (f); - pdf_puts ("/FontMatrix ["); - pdf_print_real (pk_font_scale, 5); - pdf_puts (" 0 0 "); - pdf_print_real (pk_font_scale, 5); - pdf_puts (" 0 0]\n"); + pk_font_scale = get_pk_font_scale(f); + pdf_puts("/FontMatrix ["); + pdf_print_real(pk_font_scale, 5); + pdf_puts(" 0 0 "); + pdf_print_real(pk_font_scale, 5); + pdf_puts(" 0 0]\n"); } else - pdf_printf ("/FontMatrix [%g 0 0 %g 0 0]\n", - (double) t3_font_scale, (double) t3_font_scale); - pdf_printf ("/%s [ %i %i %i %i ]\n", - font_key[FONTBBOX1_CODE].pdfname, - (int) t3_b0, (int) t3_b1, (int) t3_b2, (int) t3_b3); - pdf_printf ("/Resources << /ProcSet [ /PDF %s] >>\n", - t3_image_used ? "/ImageB " : ""); - pdf_printf ("/FirstChar %i\n/LastChar %i\n", first_char, last_char); - wptr = pdf_new_objnum (); - eptr = pdf_new_objnum (); - cptr = pdf_new_objnum (); - pdf_printf ("/Widths %i 0 R\n/Encoding %i 0 R\n/CharProcs %i 0 R\n", - (int)wptr, (int)eptr, (int)cptr); - pdf_end_dict (); - pdf_begin_obj (wptr, 1); /* chars width array */ - pdf_puts ("["); + pdf_printf("/FontMatrix [%g 0 0 %g 0 0]\n", + (double) t3_font_scale, (double) t3_font_scale); + pdf_printf("/%s [ %i %i %i %i ]\n", + font_key[FONTBBOX1_CODE].pdfname, + (int) t3_b0, (int) t3_b1, (int) t3_b2, (int) t3_b3); + pdf_printf("/Resources << /ProcSet [ /PDF %s] >>\n", + t3_image_used ? "/ImageB " : ""); + pdf_printf("/FirstChar %i\n/LastChar %i\n", first_char, last_char); + wptr = pdf_new_objnum(); + eptr = pdf_new_objnum(); + cptr = pdf_new_objnum(); + pdf_printf("/Widths %i 0 R\n/Encoding %i 0 R\n/CharProcs %i 0 R\n", + (int) wptr, (int) eptr, (int) cptr); + pdf_end_dict(); + pdf_begin_obj(wptr, 1); /* chars width array */ + pdf_puts("["); if (is_pk_font) for (i = first_char; i <= last_char; i++) { - pdf_print_real (t3_char_widths[i], 2); - pdf_puts (" "); + pdf_print_real(t3_char_widths[i], 2); + pdf_puts(" "); } else for (i = first_char; i <= last_char; i++) - pdf_printf ("%i ", (int) t3_char_widths[i]); - pdf_puts ("]\n"); - pdf_end_obj (); - pdf_begin_dict (eptr, 1); /* encoding dictionary */ - pdf_printf ("/Type /Encoding\n/Differences [%i", first_char); + pdf_printf("%i ", (int) t3_char_widths[i]); + pdf_puts("]\n"); + pdf_end_obj(); + pdf_begin_dict(eptr, 1); /* encoding dictionary */ + pdf_printf("/Type /Encoding\n/Differences [%i", first_char); if (t3_char_procs[first_char] == 0) { - pdf_printf ("/%s", notdef); + pdf_printf("/%s", notdef); is_notdef = true; } else { - pdf_printf ("/a%i", first_char); + pdf_printf("/a%i", first_char); is_notdef = false; } for (i = first_char + 1; i <= last_char; i++) { if (t3_char_procs[i] == 0) { if (!is_notdef) { - pdf_printf (" %i/%s", i, notdef); + pdf_printf(" %i/%s", i, notdef); is_notdef = true; } } else { if (is_notdef) { - pdf_printf (" %i", i); + pdf_printf(" %i", i); is_notdef = false; } - pdf_printf ("/a%i", i); + pdf_printf("/a%i", i); } } - pdf_puts ("]\n"); - pdf_end_dict (); - pdf_begin_dict (cptr, 1); /* CharProcs dictionary */ + pdf_puts("]\n"); + pdf_end_dict(); + pdf_begin_dict(cptr, 1); /* CharProcs dictionary */ for (i = first_char; i <= last_char; i++) if (t3_char_procs[i] != 0) - pdf_printf ("/a%i %i 0 R\n", (int) i, (int) t3_char_procs[i]); - pdf_end_dict (); - if (tracefilenames) - tex_printf (">"); + pdf_printf("/a%i %i 0 R\n", (int) i, (int) t3_char_procs[i]); + pdf_end_dict(); + if (tracefilenames) + tex_printf(">"); cur_file_name = NULL; } diff --git a/Build/source/texk/web2c/luatexdir/font/writettf.c b/Build/source/texk/web2c/luatexdir/font/writettf.c index 2a92706a0de..fafd7c6eab4 100644 --- a/Build/source/texk/web2c/luatexdir/font/writettf.c +++ b/Build/source/texk/web2c/luatexdir/font/writettf.c @@ -1,29 +1,30 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, - -This file is part of pdfTeX. +/* writettf.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writettf.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" #include "writettf.h" #include +static const char _svn_version[] = + "$Id: writettf.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writettf.c $"; + #define DEFAULT_NTABS 14 #define NEW_CMAP_SIZE 2 @@ -31,7 +32,7 @@ $Id: writettf.c 1013 2008-02-14 00:09:02Z oneiros $ #define ttf_offset fb_offset #define ttf_seek_outbuf fb_seek - /* #define INFILE ttf_file*/ + /* #define INFILE ttf_file */ unsigned char *ttf_buffer = NULL; integer ttf_size = 0; @@ -40,7 +41,7 @@ integer ttf_curbyte = 0; typedef struct { char *name; /* name of glyph */ long code; /* charcode in case of subfonts */ - short newindex; /* new index of glyph in output file */ + long newindex; /* new index of glyph in output file */ } ttfenc_entry; @@ -59,7 +60,7 @@ typedef struct { char *ttf_name; TTF_USHORT pid; TTF_USHORT eid; - short *table; + long *table; } ttf_cmap_entry; static TTF_USHORT ntabs; @@ -89,7 +90,7 @@ static TTF_ULONG checkSumAdjustment_offset; FILE *ttf_file; static ttfenc_entry ttfenc_tab[256]; -fd_entry *fd_cur; /* pointer to the current font descriptor */ +fd_entry *fd_cur; /* pointer to the current font descriptor */ static struct avl_table *ttf_cmap_tree = NULL; @@ -97,8 +98,8 @@ integer ttf_length; #include "macnames.c" -extern char *fb_array; -extern char charsetstr[]; +extern char *fb_array; /* from luatexdir/utils.c */ +extern char charsetstr[]; /* from mpdir/psout.w */ static const char *newtabnames[] = { "OS/2", @@ -117,44 +118,44 @@ static const char *newtabnames[] = { "prep" }; -ttf_cmap_entry *new_ttf_cmap_entry (void) +ttf_cmap_entry *new_ttf_cmap_entry(void) { ttf_cmap_entry *e; - e = xtalloc (1, ttf_cmap_entry); + e = xtalloc(1, ttf_cmap_entry); e->ttf_name = NULL; e->table = NULL; return e; } -static void destroy_ttf_cmap_entry (void *pa, void *pb) +static void destroy_ttf_cmap_entry(void *pa, void *pb) { ttf_cmap_entry *p; p = (ttf_cmap_entry *) pa; - xfree (p->ttf_name); - xfree (p->table); - xfree (p); + xfree(p->ttf_name); + xfree(p->table); + xfree(p); } -void ttf_free (void) +void ttf_free(void) { if (ttf_cmap_tree != NULL) - avl_destroy (ttf_cmap_tree, destroy_ttf_cmap_entry); + avl_destroy(ttf_cmap_tree, destroy_ttf_cmap_entry); } -static int comp_ttf_cmap_entry (const void *pa, const void *pb, void *p) +static int comp_ttf_cmap_entry(const void *pa, const void *pb, void *p) { const ttf_cmap_entry *p1 = (const ttf_cmap_entry *) pa, *p2 = (const ttf_cmap_entry *) pb; int i; - assert (p1->ttf_name != NULL && p2->ttf_name != NULL); - if ((i = strcmp (p1->ttf_name, p2->ttf_name)) != 0) + assert(p1->ttf_name != NULL && p2->ttf_name != NULL); + if ((i = strcmp(p1->ttf_name, p2->ttf_name)) != 0) return i; - cmp_return (p1->pid, p2->pid); - cmp_return (p1->eid, p2->eid); + cmp_return(p1->pid, p2->pid); + cmp_return(p1->eid, p2->eid); return 0; } -static unsigned char ttf_addchksm (unsigned char b) +static unsigned char ttf_addchksm(unsigned char b) { tmp_ulong = (tmp_ulong << 8) + b; tab_length++; @@ -165,14 +166,14 @@ static unsigned char ttf_addchksm (unsigned char b) return b; } -static TTF_ULONG ttf_getchksm (void) +static TTF_ULONG ttf_getchksm(void) { while (tab_length % 4 != 0) - ttf_putchar (ttf_addchksm (0)); /* ttf_addchksm updates tab_length */ + ttf_putchar(ttf_addchksm(0)); /* ttf_addchksm updates tab_length */ return checksum; } -long ttf_putnum (int s, long n) +long ttf_putnum(int s, long n) { long i = n; char buf[TTF_LONG_SIZE + 1], *p = buf; @@ -182,25 +183,25 @@ long ttf_putnum (int s, long n) } p--; while (p >= buf) - ttf_putchar (ttf_addchksm (*p--)); + ttf_putchar(ttf_addchksm(*p--)); return n; } -long ttf_getnum (int s) +long ttf_getnum(int s) { long i = 0; int c; while (s > 0) { - if (ttf_eof()) - pdftex_fail ("unexpected EOF"); - c = ttf_getchar (); - i = (i << 8) + c; - s--; + if (ttf_eof()) + pdftex_fail("unexpected EOF"); + c = ttf_getchar(); + i = (i << 8) + c; + s--; } return i; } -static long ttf_funit (long n) +static long ttf_funit(long n) { if (n < 0) return -((-n / upem) * 1000 + ((-n % upem) * 1000) / upem); @@ -208,38 +209,38 @@ static long ttf_funit (long n) return (n / upem) * 1000 + ((n % upem) * 1000) / upem; } -static void ttf_ncopy (int n) +static void ttf_ncopy(int n) { while (n-- > 0) - copy_byte (); + copy_byte(); } -dirtab_entry *ttf_name_lookup (const char *s, boolean required) +dirtab_entry *ttf_name_lookup(const char *s, boolean required) { dirtab_entry *tab; for (tab = dir_tab; tab - dir_tab < ntabs; tab++) - if (strncmp (tab->tag, s, 4) == 0) + if (strncmp(tab->tag, s, 4) == 0) break; if (tab - dir_tab == ntabs) { if (required) - pdftex_fail ("can't find table `%s'", s); + pdftex_fail("can't find table `%s'", s); else tab = NULL; } return tab; } -dirtab_entry *ttf_seek_tab (const char *name, TTF_LONG offset) +dirtab_entry *ttf_seek_tab(const char *name, TTF_LONG offset) { - dirtab_entry *tab = ttf_name_lookup (name, true); - /*xfseek (INFILE, tab->offset + offset, SEEK_SET, cur_file_name);*/ - ttf_curbyte = tab->offset + offset; + dirtab_entry *tab = ttf_name_lookup(name, true); + /*xfseek (INFILE, tab->offset + offset, SEEK_SET, cur_file_name); */ + ttf_curbyte = tab->offset + offset; return tab; } -static void ttf_seek_off (TTF_LONG offset) +static void ttf_seek_off(TTF_LONG offset) { - ttf_curbyte = offset; + ttf_curbyte = offset; //xfseek (INFILE, offset, SEEK_SET, cur_file_name); } @@ -294,7 +295,9 @@ static void ttf_copy_encoding(void) e = ttfenc_tab + *q; e->code = charcodes[*q]; if (e->code == -1) - pdftex_warn("character %i is not mapped to any charcode", *q); + pdftex_warn + ("character %i in subfont %s is not mapped to any charcode", + *q, fd_cur->fm->tfm_name); else { assert(e->code < 0x10000); sprintf(buf, "/c%4.4X", (int) e->code); @@ -333,27 +336,27 @@ static char *strip_spaces_and_delims(char *s, int l) return buf; } -static void ttf_read_name (void) +static void ttf_read_name(void) { int i, j; - dirtab_entry *tab = ttf_seek_tab ("name", TTF_USHORT_SIZE); - char *p; - name_record_num = get_ushort (); - name_tab = xtalloc (name_record_num, name_record); + dirtab_entry *tab = ttf_seek_tab("name", TTF_USHORT_SIZE); + char *p, buf[SMALL_BUF_SIZE]; + name_record_num = get_ushort(); + name_tab = xtalloc(name_record_num, name_record); name_buf_size = tab->length - (3 * TTF_USHORT_SIZE + name_record_num * 6 * TTF_USHORT_SIZE); - name_buf = xtalloc (name_buf_size, char); - ttf_skip (TTF_USHORT_SIZE); + name_buf = xtalloc(name_buf_size, char); + ttf_skip(TTF_USHORT_SIZE); for (i = 0; i < name_record_num; i++) { - name_tab[i].platform_id = get_ushort (); - name_tab[i].encoding_id = get_ushort (); - name_tab[i].language_id = get_ushort (); - name_tab[i].name_id = get_ushort (); - name_tab[i].length = get_ushort (); - name_tab[i].offset = get_ushort (); + name_tab[i].platform_id = get_ushort(); + name_tab[i].encoding_id = get_ushort(); + name_tab[i].language_id = get_ushort(); + name_tab[i].name_id = get_ushort(); + name_tab[i].length = get_ushort(); + name_tab[i].offset = get_ushort(); } for (p = name_buf; p - name_buf < name_buf_size; p++) - *p = get_char (); + *p = get_char(); /* look for PS font name */ for (i = 0; i < name_record_num; i++) { if (name_tab[i].platform_id == 1 && @@ -369,12 +372,15 @@ static void ttf_read_name (void) if (!fd_cur->font_dim[FONTNAME_CODE].set) { for (i = 0; i < name_record_num; i++) { if (name_tab[i].platform_id == 3 && - (name_tab[i].encoding_id == 0 || - name_tab[i].encoding_id == 1) && name_tab[i].name_id == 6) { - for (j = 0, p = fd_cur->fontname; j < name_tab[i].length; - j += 2) + (name_tab[i].encoding_id == 0 || name_tab[i].encoding_id == 1) + && name_tab[i].name_id == 6) { + xfree(fd_cur->fontname); + assert(name_tab[i].length < sizeof(buf)); + for (j = 0, p = buf; j < name_tab[i].length; j += 2) *p++ = name_buf[name_tab[i].offset + j + 1]; *p = 0; + fd_cur->fontname = + xstrdup(strip_spaces_and_delims(buf, strlen(buf))); fd_cur->font_dim[FONTNAME_CODE].set = true; break; } @@ -382,28 +388,28 @@ static void ttf_read_name (void) } } -static void ttf_read_mapx (void) +static void ttf_read_mapx(void) { glyph_entry *glyph; - ttf_seek_tab ("maxp", TTF_FIXED_SIZE); - glyph_tab = xtalloc (1 + (glyphs_count = get_ushort ()), glyph_entry); + ttf_seek_tab("maxp", TTF_FIXED_SIZE); + glyph_tab = xtalloc(1 + (glyphs_count = get_ushort()), glyph_entry); for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count; glyph++) { glyph->newindex = -1; glyph->newoffset = 0; glyph->name_index = 0; glyph->name = (char *) notdef; } - glyph_index = xtalloc (glyphs_count, long); + glyph_index = xtalloc(glyphs_count, long); glyph_index[0] = 0; /* index of ".notdef" glyph */ glyph_index[1] = 1; /* index of ".null" glyph */ } -void ttf_read_head (void) +void ttf_read_head(void) { - ttf_seek_tab ("head", - 2 * TTF_FIXED_SIZE + 2 * TTF_ULONG_SIZE + TTF_USHORT_SIZE); - upem = get_ushort (); - ttf_skip (16); + ttf_seek_tab("head", + 2 * TTF_FIXED_SIZE + 2 * TTF_ULONG_SIZE + TTF_USHORT_SIZE); + upem = get_ushort(); + ttf_skip(16); fd_cur->font_dim[FONTBBOX1_CODE].val = ttf_funit(get_fword()); fd_cur->font_dim[FONTBBOX2_CODE].val = ttf_funit(get_fword()); fd_cur->font_dim[FONTBBOX3_CODE].val = ttf_funit(get_fword()); @@ -412,27 +418,27 @@ void ttf_read_head (void) fd_cur->font_dim[FONTBBOX2_CODE].set = true; fd_cur->font_dim[FONTBBOX3_CODE].set = true; fd_cur->font_dim[FONTBBOX4_CODE].set = true; - ttf_skip (2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE); - loca_format = get_short (); + ttf_skip(2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE); + loca_format = get_short(); } -void ttf_read_hhea (void) +void ttf_read_hhea(void) { - ttf_seek_tab ("hhea", TTF_FIXED_SIZE); + ttf_seek_tab("hhea", TTF_FIXED_SIZE); fd_cur->font_dim[ASCENT_CODE].val = ttf_funit(get_fword()); fd_cur->font_dim[DESCENT_CODE].val = ttf_funit(get_fword()); fd_cur->font_dim[ASCENT_CODE].set = true; fd_cur->font_dim[DESCENT_CODE].set = true; - ttf_skip (TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3 * TTF_FWORD_SIZE + - 8 * TTF_SHORT_SIZE); - nhmtxs = get_ushort (); + ttf_skip(TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3 * TTF_FWORD_SIZE + + 8 * TTF_SHORT_SIZE); + nhmtxs = get_ushort(); } -void ttf_read_pclt (void) +void ttf_read_pclt(void) { - if (ttf_name_lookup ("PCLT", false) == NULL) + if (ttf_name_lookup("PCLT", false) == NULL) return; - ttf_seek_tab ("PCLT", TTF_FIXED_SIZE + TTF_ULONG_SIZE + TTF_USHORT_SIZE); + ttf_seek_tab("PCLT", TTF_FIXED_SIZE + TTF_ULONG_SIZE + TTF_USHORT_SIZE); fd_cur->font_dim[XHEIGHT_CODE].val = ttf_funit(get_ushort()); ttf_skip(2 * TTF_USHORT_SIZE); fd_cur->font_dim[CAPHEIGHT_CODE].val = ttf_funit(get_ushort()); @@ -440,25 +446,25 @@ void ttf_read_pclt (void) fd_cur->font_dim[CAPHEIGHT_CODE].set = true; } -static void ttf_read_hmtx (void) +static void ttf_read_hmtx(void) { glyph_entry *glyph; TTF_UFWORD last_advWidth; - ttf_seek_tab ("hmtx", 0); + ttf_seek_tab("hmtx", 0); for (glyph = glyph_tab; glyph - glyph_tab < nhmtxs; glyph++) { - glyph->advWidth = get_ufword (); - glyph->lsb = get_ufword (); + glyph->advWidth = get_ufword(); + glyph->lsb = get_ufword(); } if (nhmtxs < glyphs_count) { last_advWidth = glyph[-1].advWidth; for (; glyph - glyph_tab < glyphs_count; glyph++) { glyph->advWidth = last_advWidth; - glyph->lsb = get_ufword (); + glyph->lsb = get_ufword(); } } } -void ttf_read_post (void) +void ttf_read_post(void) { int k, nnames; long length; @@ -467,9 +473,9 @@ void ttf_read_post (void) TTF_FIXED italic_angle; char *p; glyph_entry *glyph; - const dirtab_entry *tab = ttf_seek_tab ("post", 0); - post_format = get_fixed (); - italic_angle = get_fixed (); + const dirtab_entry *tab = ttf_seek_tab("post", 0); + post_format = get_fixed(); + italic_angle = get_fixed(); int_part = italic_angle >> 16; if (int_part > 0x7FFF) { /* a negative number */ int_part = 0x10000 - int_part; @@ -481,7 +487,7 @@ void ttf_read_post (void) fd_cur->font_dim[ITALIC_ANGLE_CODE].set = true; if (glyph_tab == NULL) return; /* being called from writeotf() */ - ttf_skip (2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); + ttf_skip(2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); switch (post_format) { case 0x10000: for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) { @@ -490,15 +496,15 @@ void ttf_read_post (void) } break; case 0x20000: - nnames = get_ushort (); /* some fonts have this value different from nglyphs */ + nnames = get_ushort(); /* some fonts have this value different from nglyphs */ for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) - glyph->name_index = get_ushort (); - /*length = tab->length - (xftell (INFILE, cur_file_name) - tab->offset);*/ + glyph->name_index = get_ushort(); + /*length = tab->length - (xftell (INFILE, cur_file_name) - tab->offset); */ length = tab->length - (ttf_curbyte - tab->offset); - glyph_name_buf = xtalloc (length, char); + glyph_name_buf = xtalloc(length, char); for (p = glyph_name_buf; p - glyph_name_buf < length;) { - for (k = get_byte (); k > 0; k--) - *p++ = get_char (); + for (k = get_byte(); k > 0; k--) + *p++ = get_char(); *p++ = 0; } for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) { @@ -508,7 +514,7 @@ void ttf_read_post (void) p = glyph_name_buf; k = glyph->name_index - NMACGLYPHS; for (; k > 0; k--) - p = strend (p) + 1; + p = strend(p) + 1; glyph->name = p; } } @@ -519,41 +525,41 @@ void ttf_read_post (void) } break; default: - pdftex_fail ("unsupported format (%.8X) of `post' table", - (unsigned int) post_format); + pdftex_fail("unsupported format (%.8X) of `post' table", + (unsigned int) post_format); } } -static void ttf_read_loca (void) +static void ttf_read_loca(void) { glyph_entry *glyph; - ttf_seek_tab ("loca", 0); + ttf_seek_tab("loca", 0); if (loca_format != 0) for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count + 1; glyph++) - glyph->offset = get_ulong (); + glyph->offset = get_ulong(); else for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count + 1; glyph++) - glyph->offset = get_ushort () << 1; + glyph->offset = get_ushort() << 1; } -void ttf_read_tabdir (void) +void ttf_read_tabdir(void) { int i; dirtab_entry *tab; - ttf_skip (TTF_FIXED_SIZE); /* ignore the sfnt number */ - dir_tab = xtalloc (ntabs = get_ushort (), dirtab_entry); - ttf_skip (3 * TTF_USHORT_SIZE); + ttf_skip(TTF_FIXED_SIZE); /* ignore the sfnt number */ + dir_tab = xtalloc(ntabs = get_ushort(), dirtab_entry); + ttf_skip(3 * TTF_USHORT_SIZE); for (tab = dir_tab; tab - dir_tab < ntabs; tab++) { for (i = 0; i < 4; i++) - tab->tag[i] = get_char (); - tab->checksum = get_ulong (); - tab->offset = get_ulong (); - tab->length = get_ulong (); + tab->tag[i] = get_char(); + tab->checksum = get_ulong(); + tab->offset = get_ulong(); + tab->length = get_ulong(); } } -static ttf_cmap_entry *ttf_read_cmap (char *ttf_name, int pid, int eid, - boolean warn) +static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, + boolean warn) { seg_entry *seg_tab, *s; TTF_USHORT *glyphId, format, segCount; @@ -568,71 +574,71 @@ static ttf_cmap_entry *ttf_read_cmap (char *ttf_name, int pid, int eid, tmp_e.pid = pid; tmp_e.eid = eid; if (ttf_cmap_tree == NULL) { - ttf_cmap_tree = avl_create (comp_ttf_cmap_entry, NULL, &avl_xallocator); - assert (ttf_cmap_tree != NULL); + ttf_cmap_tree = avl_create(comp_ttf_cmap_entry, NULL, &avl_xallocator); + assert(ttf_cmap_tree != NULL); } - p = (ttf_cmap_entry *) avl_find (ttf_cmap_tree, &tmp_e); + p = (ttf_cmap_entry *) avl_find(ttf_cmap_tree, &tmp_e); if (p != NULL) return p; /* not found, have to read it */ - ttf_seek_tab ("cmap", TTF_USHORT_SIZE); /* skip the table vesrion number (=0) */ - ncmapsubtabs = get_ushort (); - /* cmap_offset = xftell (INFILE, cur_file_name) - 2 * TTF_USHORT_SIZE;*/ - cmap_offset = ttf_curbyte - 2 * TTF_USHORT_SIZE; - cmap_tab = xtalloc (ncmapsubtabs, cmap_entry); + ttf_seek_tab("cmap", TTF_USHORT_SIZE); /* skip the table vesrion number (=0) */ + ncmapsubtabs = get_ushort(); + /* cmap_offset = xftell (INFILE, cur_file_name) - 2 * TTF_USHORT_SIZE; */ + cmap_offset = ttf_curbyte - 2 * TTF_USHORT_SIZE; + cmap_tab = xtalloc(ncmapsubtabs, cmap_entry); for (i = 0; i < ncmapsubtabs; ++i) { - tmp_pid = get_ushort (); - tmp_eid = get_ushort (); - tmp_offset = get_ulong (); + tmp_pid = get_ushort(); + tmp_eid = get_ushort(); + tmp_offset = get_ulong(); if (tmp_pid == pid && tmp_eid == eid) { - ttf_seek_off (cmap_offset + tmp_offset); - format = get_ushort (); + ttf_seek_off(cmap_offset + tmp_offset); + format = get_ushort(); if (format == 4) goto read_cmap_format_4; else { if (warn) - pdftex_warn ("cmap format %i unsupported", format); + pdftex_warn("cmap format %i unsupported", format); return NULL; } } } if (warn) - pdftex_warn ("cannot find cmap subtable for (pid,eid) = (%i, %i)", - pid, eid); + pdftex_warn("cannot find cmap subtable for (pid,eid) = (%i, %i)", + pid, eid); return NULL; read_cmap_format_4: /* initialize the new entry */ - p = new_ttf_cmap_entry (); - p->ttf_name = xstrdup (ttf_name); + p = new_ttf_cmap_entry(); + p->ttf_name = xstrdup(ttf_name); p->pid = pid; p->eid = eid; - p->table = xtalloc (0x10000, short); + p->table = xtalloc(0x10000, long); for (i = 0; i < 0x10000; ++i) p->table[i] = -1; /* unassigned yet */ /* read the subtable */ - length = get_ushort (); /* length of subtable */ - (void) get_ushort (); /* skip the version number */ - segCount = get_ushort () / 2; - (void) get_ushort (); /* skip searchRange */ - (void) get_ushort (); /* skip entrySelector */ - (void) get_ushort (); /* skip rangeShift */ - seg_tab = xtalloc (segCount, seg_entry); + length = get_ushort(); /* length of subtable */ + (void) get_ushort(); /* skip the version number */ + segCount = get_ushort() / 2; + (void) get_ushort(); /* skip searchRange */ + (void) get_ushort(); /* skip entrySelector */ + (void) get_ushort(); /* skip rangeShift */ + seg_tab = xtalloc(segCount, seg_entry); for (s = seg_tab; s - seg_tab < segCount; s++) - s->endCode = get_ushort (); - (void) get_ushort (); /* skip reversedPad */ + s->endCode = get_ushort(); + (void) get_ushort(); /* skip reversedPad */ for (s = seg_tab; s - seg_tab < segCount; s++) - s->startCode = get_ushort (); + s->startCode = get_ushort(); for (s = seg_tab; s - seg_tab < segCount; s++) - s->idDelta = get_ushort (); + s->idDelta = get_ushort(); for (s = seg_tab; s - seg_tab < segCount; s++) - s->idRangeOffset = get_ushort (); + s->idRangeOffset = get_ushort(); length -= 8 * TTF_USHORT_SIZE + 4 * segCount * TTF_USHORT_SIZE; n = length / TTF_USHORT_SIZE; /* number of glyphID's */ - glyphId = xtalloc (n, TTF_USHORT); + glyphId = xtalloc(n, TTF_USHORT); for (i = 0; i < n; i++) - glyphId[i] = get_ushort (); + glyphId[i] = get_ushort(); for (s = seg_tab; s - seg_tab < segCount; s++) { for (i = s->startCode; i <= s->endCode; i++) { if (i == 0xFFFF) @@ -643,144 +649,144 @@ static ttf_cmap_entry *ttf_read_cmap (char *ttf_name, int pid, int eid, else { k = (i - s->startCode) + s->idRangeOffset / 2 + (s - seg_tab) - segCount; - assert (k >= 0 && k < n); + assert(k >= 0 && k < n); index = glyphId[k]; if (index != 0) index = (index + s->idDelta) & 0xFFFF; } if (index >= glyphs_count) - pdftex_fail ("cmap: glyph index %li out of range [0..%i)", - index, glyphs_count); + pdftex_fail("cmap: glyph index %li out of range [0..%i)", + index, glyphs_count); if (p->table[i] != -1) pdftex_warn ("cmap: multiple glyphs are mapped to unicode %.4lX, " - "only %i will be used (glyph %li being ignored)", i, + "only %li will be used (glyph %li being ignored)", i, p->table[i], index); else p->table[i] = index; } } } - xfree (seg_tab); - xfree (glyphId); - aa = avl_probe (ttf_cmap_tree, p); - assert (aa != NULL); + xfree(seg_tab); + xfree(glyphId); + aa = avl_probe(ttf_cmap_tree, p); + assert(aa != NULL); return p; } -static void ttf_read_font (void) +static void ttf_read_font(void) { - ttf_read_tabdir (); - if (ttf_name_lookup ("PCLT", false) == NULL) + ttf_read_tabdir(); + if (ttf_name_lookup("PCLT", false) == NULL) new_ntabs--; - if (ttf_name_lookup ("fpgm", false) == NULL) + if (ttf_name_lookup("fpgm", false) == NULL) new_ntabs--; - if (ttf_name_lookup ("cvt ", false) == NULL) + if (ttf_name_lookup("cvt ", false) == NULL) new_ntabs--; - if (ttf_name_lookup ("prep", false) == NULL) + if (ttf_name_lookup("prep", false) == NULL) new_ntabs--; - ttf_read_mapx (); - ttf_read_head (); - ttf_read_hhea (); - ttf_read_pclt (); - ttf_read_hmtx (); - ttf_read_post (); - ttf_read_loca (); - ttf_read_name (); + ttf_read_mapx(); + ttf_read_head(); + ttf_read_hhea(); + ttf_read_pclt(); + ttf_read_hmtx(); + ttf_read_post(); + ttf_read_loca(); + ttf_read_name(); } -static void ttf_reset_chksm (dirtab_entry * tab) +static void ttf_reset_chksm(dirtab_entry * tab) { checksum = 0; tab_length = 0; tmp_ulong = 0; - tab->offset = ttf_offset (); + tab->offset = ttf_offset(); if (tab->offset % 4 != 0) - pdftex_warn ("offset of `%4.4s' is not a multiple of 4", tab->tag); + pdftex_warn("offset of `%4.4s' is not a multiple of 4", tab->tag); } -static void ttf_set_chksm (dirtab_entry * tab) +static void ttf_set_chksm(dirtab_entry * tab) { - tab->length = ttf_offset () - tab->offset; - tab->checksum = ttf_getchksm (); + tab->length = ttf_offset() - tab->offset; + tab->checksum = ttf_getchksm(); } -static void ttf_copytab (const char *name) +static void ttf_copytab(const char *name) { long i; - dirtab_entry *tab = ttf_seek_tab (name, 0); - ttf_reset_chksm (tab); + dirtab_entry *tab = ttf_seek_tab(name, 0); + ttf_reset_chksm(tab); for (i = tab->length; i > 0; i--) - copy_char (); - ttf_set_chksm (tab); + copy_char(); + ttf_set_chksm(tab); } #define BYTE_ENCODING_LENGTH \ ((256)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE) -static void ttf_byte_encoding (void) +static void ttf_byte_encoding(void) { ttfenc_entry *e; - (void) put_ushort (0); /* format number (0: byte encoding table) */ - (void) put_ushort (BYTE_ENCODING_LENGTH); /* length of table */ - (void) put_ushort (0); /* version number */ + (void) put_ushort(0); /* format number (0: byte encoding table) */ + (void) put_ushort(BYTE_ENCODING_LENGTH); /* length of table */ + (void) put_ushort(0); /* version number */ for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) if (e->newindex < 256) { - put_byte (e->newindex); + put_byte(e->newindex); } else { if (e->name != notdef) pdftex_warn ("glyph `%s' has been mapped to `%s' in `ttf_byte_encoding' cmap table", e->name, notdef); - put_byte (0); /* notdef */ + put_byte(0); /* notdef */ } } #define TRIMMED_TABLE_MAP_LENGTH (TTF_USHORT_SIZE*(5 + (256))) -static void ttf_trimmed_table_map (void) +static void ttf_trimmed_table_map(void) { ttfenc_entry *e; - (void) put_ushort (6); /* format number (6): trimmed table mapping */ - (void) put_ushort (TRIMMED_TABLE_MAP_LENGTH); - (void) put_ushort (0); /* version number (0) */ - (void) put_ushort (0); /* first character code */ - (void) put_ushort (256); /* number of character code in table */ + (void) put_ushort(6); /* format number (6): trimmed table mapping */ + (void) put_ushort(TRIMMED_TABLE_MAP_LENGTH); + (void) put_ushort(0); /* version number (0) */ + (void) put_ushort(0); /* first character code */ + (void) put_ushort(256); /* number of character code in table */ for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) - (void) put_ushort (e->newindex); + (void) put_ushort(e->newindex); } #define SEG_MAP_DELTA_LENGTH ((16 + (256))*TTF_USHORT_SIZE) -static void ttf_seg_map_delta (void) +static void ttf_seg_map_delta(void) { ttfenc_entry *e; - (void) put_ushort (4); /* format number (4: segment mapping to delta values) */ - (void) put_ushort (SEG_MAP_DELTA_LENGTH); - (void) put_ushort (0); /* version number */ - (void) put_ushort (4); /* 2*segCount */ - (void) put_ushort (4); /* searchRange */ - (void) put_ushort (1); /* entrySelector */ - (void) put_ushort (0); /* rangeShift */ - (void) put_ushort (0xF0FF); /* endCount[0] */ - (void) put_ushort (0xFFFF); /* endCount[1] */ - (void) put_ushort (0); /* reversedPad */ - (void) put_ushort (0xF000); /* startCount[0] */ - (void) put_ushort (0xFFFF); /* startCount[1] */ - (void) put_ushort (0); /* idDelta[0] */ - (void) put_ushort (1); /* idDelta[1] */ - (void) put_ushort (2 * TTF_USHORT_SIZE); /* idRangeOffset[0] */ - (void) put_ushort (0); /* idRangeOffset[1] */ + (void) put_ushort(4); /* format number (4: segment mapping to delta values) */ + (void) put_ushort(SEG_MAP_DELTA_LENGTH); + (void) put_ushort(0); /* version number */ + (void) put_ushort(4); /* 2*segCount */ + (void) put_ushort(4); /* searchRange */ + (void) put_ushort(1); /* entrySelector */ + (void) put_ushort(0); /* rangeShift */ + (void) put_ushort(0xF0FF); /* endCount[0] */ + (void) put_ushort(0xFFFF); /* endCount[1] */ + (void) put_ushort(0); /* reversedPad */ + (void) put_ushort(0xF000); /* startCount[0] */ + (void) put_ushort(0xFFFF); /* startCount[1] */ + (void) put_ushort(0); /* idDelta[0] */ + (void) put_ushort(1); /* idDelta[1] */ + (void) put_ushort(2 * TTF_USHORT_SIZE); /* idRangeOffset[0] */ + (void) put_ushort(0); /* idRangeOffset[1] */ for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) - (void) put_ushort (e->newindex); + (void) put_ushort(e->newindex); } #define CMAP_ENTRY_LENGTH (2*TTF_USHORT_SIZE + TTF_ULONG_SIZE) -static void ttf_select_cmap (void) +static void ttf_select_cmap(void) { - assert (sizeof (new_cmap_tab) <= NEW_CMAP_SIZE * sizeof (cmap_entry)); + assert(sizeof(new_cmap_tab) <= NEW_CMAP_SIZE * sizeof(cmap_entry)); new_cmap_tab[0].platform_id = 1; /* Macintosh */ new_cmap_tab[0].encoding_id = 0; /* Symbol; ignore code page */ new_cmap_tab[0].format = new_glyphs_count < 256 ? 0 /* byte encoding */ @@ -790,15 +796,15 @@ static void ttf_select_cmap (void) new_cmap_tab[1].format = 4; /* segment mapping to delta */ } -static void ttf_write_cmap (void) +static void ttf_write_cmap(void) { cmap_entry *ce; long offset; - dirtab_entry *tab = ttf_name_lookup ("cmap", true); - ttf_select_cmap (); - ttf_reset_chksm (tab); - (void) put_ushort (0); /* table version number (0) */ - (void) put_ushort (NEW_CMAP_SIZE); /* number of encoding tables */ + dirtab_entry *tab = ttf_name_lookup("cmap", true); + ttf_select_cmap(); + ttf_reset_chksm(tab); + (void) put_ushort(0); /* table version number (0) */ + (void) put_ushort(NEW_CMAP_SIZE); /* number of encoding tables */ offset = 2 * TTF_USHORT_SIZE + NEW_CMAP_SIZE * CMAP_ENTRY_LENGTH; for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) { ce->offset = offset; @@ -813,33 +819,34 @@ static void ttf_write_cmap (void) offset += TRIMMED_TABLE_MAP_LENGTH; break; default: - pdftex_fail ("invalid format (it should not have happened)"); + pdftex_fail("invalid format (it should not have happened)"); } - (void) put_ushort (ce->platform_id); - (void) put_ushort (ce->encoding_id); - put_ulong (ce->offset); + (void) put_ushort(ce->platform_id); + (void) put_ushort(ce->encoding_id); + put_ulong(ce->offset); } for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) { switch (ce->format) { case 0: - ttf_byte_encoding (); + ttf_byte_encoding(); break; case 4: - ttf_seg_map_delta (); + ttf_seg_map_delta(); break; case 6: - ttf_trimmed_table_map (); + ttf_trimmed_table_map(); break; } } - ttf_set_chksm (tab); + ttf_set_chksm(tab); } -static int prepend_subset_tags (int index, char *p) +static int prepend_subset_tags(int index, char *p) { - const boolean is_unicode = (name_tab[index].platform_id == 3); + boolean is_unicode; int i; - assert (index > 0 && index < name_record_num && fd_cur->subset_tag != NULL); + assert(index >= 0 && index < name_record_num && fd_cur->subset_tag != NULL); + is_unicode = (name_tab[index].platform_id == 3); if (is_unicode) { for (i = 0; i < 6; ++i) { *p++ = 0; @@ -849,7 +856,7 @@ static int prepend_subset_tags (int index, char *p) *p++ = '+'; return 14; } else { - strncpy (p, fd_cur->subset_tag, 6); + strncpy(p, fd_cur->subset_tag, 6); p += 6; *p++ = '+'; return 7; @@ -857,19 +864,19 @@ static int prepend_subset_tags (int index, char *p) } -static void ttf_write_name (void) +static void ttf_write_name(void) { int i, l; char *p; int new_name_buf_size; char *new_name_buf; name_record *n; - dirtab_entry *tab = ttf_name_lookup ("name", true); - if (is_subsetted (fd_cur->fm)) { + dirtab_entry *tab = ttf_name_lookup("name", true); + if (is_subsetted(fd_cur->fm)) { l = 0; for (i = 0; i < name_record_num; i++) l += name_tab[i].length + 14; /* maximum lengh of new stogare area */ - new_name_buf = xtalloc (l, char); + new_name_buf = xtalloc(l, char); /* additional space for subset tags */ p = new_name_buf; for (i = 0; i < name_record_num; i++) { @@ -880,11 +887,11 @@ static void ttf_write_name (void) ((n->platform_id == 1 && n->encoding_id == 0) || (n->platform_id == 3 && n->encoding_id == 0) || (n->platform_id == 3 && n->encoding_id == 1))) { - l = prepend_subset_tags (i, p); + l = prepend_subset_tags(i, p); p += l; } else l = 0; - memcpy (p, name_buf + n->offset, n->length); + memcpy(p, name_buf + n->offset, n->length); p += n->length; n->new_length = n->length + l; } @@ -893,51 +900,51 @@ static void ttf_write_name (void) new_name_buf = name_buf; new_name_buf_size = name_buf_size; } - ttf_reset_chksm (tab); - (void) put_ushort (0); /* Format selector */ - (void) put_ushort (name_record_num); - (void) put_ushort (3 * TTF_USHORT_SIZE + - name_record_num * 6 * TTF_USHORT_SIZE); + ttf_reset_chksm(tab); + (void) put_ushort(0); /* Format selector */ + (void) put_ushort(name_record_num); + (void) put_ushort(3 * TTF_USHORT_SIZE + + name_record_num * 6 * TTF_USHORT_SIZE); for (i = 0; i < name_record_num; i++) { - (void) put_ushort (name_tab[i].platform_id); - (void) put_ushort (name_tab[i].encoding_id); - (void) put_ushort (name_tab[i].language_id); - (void) put_ushort (name_tab[i].name_id); - (void) put_ushort (name_tab[i].new_length); - (void) put_ushort (name_tab[i].new_offset); + (void) put_ushort(name_tab[i].platform_id); + (void) put_ushort(name_tab[i].encoding_id); + (void) put_ushort(name_tab[i].language_id); + (void) put_ushort(name_tab[i].name_id); + (void) put_ushort(name_tab[i].new_length); + (void) put_ushort(name_tab[i].new_offset); } for (p = new_name_buf; p - new_name_buf < new_name_buf_size; p++) - put_char (*p); - ttf_set_chksm (tab); + put_char(*p); + ttf_set_chksm(tab); if (new_name_buf != name_buf) - xfree (new_name_buf); + xfree(new_name_buf); } -static void ttf_write_dirtab (void) +static void ttf_write_dirtab(void) { dirtab_entry *tab; TTF_ULONG i, k; char *p; - const integer save_offset = ttf_offset (); - ttf_seek_outbuf (TABDIR_OFF); - if (is_subsetted (fd_cur->fm)) { + const integer save_offset = ttf_offset(); + ttf_seek_outbuf(TABDIR_OFF); + if (is_subsetted(fd_cur->fm)) { for (i = 0; i < DEFAULT_NTABS; i++) { - tab = ttf_name_lookup (newtabnames[i], false); + tab = ttf_name_lookup(newtabnames[i], false); if (tab == NULL) continue; for (k = 0; k < 4; k++) - put_char (tab->tag[k]); - put_ulong (tab->checksum); - put_ulong (tab->offset); - put_ulong (tab->length); + put_char(tab->tag[k]); + put_ulong(tab->checksum); + put_ulong(tab->offset); + put_ulong(tab->length); } } else { for (tab = dir_tab; tab - dir_tab < ntabs; tab++) { for (k = 0; k < 4; k++) - put_char (tab->tag[k]); - put_ulong (tab->checksum); - put_ulong (tab->offset); - put_ulong (tab->length); + put_char(tab->tag[k]); + put_ulong(tab->checksum); + put_ulong(tab->offset); + put_ulong(tab->length); } } /* adjust checkSumAdjustment */ @@ -952,34 +959,34 @@ static void ttf_write_dirtab (void) } } if (i % 4 != 0) { - pdftex_warn ("font length is not a multiple of 4 (%li)", i); + pdftex_warn("font length is not a multiple of 4 (%li)", i); checksum <<= 8 * (4 - i % 4); } k = 0xB1B0AFBA - checksum; - ttf_seek_outbuf (checkSumAdjustment_offset); - put_ulong (k); - ttf_seek_outbuf (save_offset); + ttf_seek_outbuf(checkSumAdjustment_offset); + put_ulong(k); + ttf_seek_outbuf(save_offset); } -static void ttf_write_glyf (void) +static void ttf_write_glyf(void) { long *id, k; TTF_USHORT idx; TTF_USHORT flags; - dirtab_entry *tab = ttf_name_lookup ("glyf", true); + dirtab_entry *tab = ttf_name_lookup("glyf", true); const long glyf_offset = tab->offset; - const long new_glyf_offset = ttf_offset (); - ttf_reset_chksm (tab); + const long new_glyf_offset = ttf_offset(); + ttf_reset_chksm(tab); for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) { - glyph_tab[*id].newoffset = ttf_offset () - new_glyf_offset; + glyph_tab[*id].newoffset = ttf_offset() - new_glyf_offset; if (glyph_tab[*id].offset != glyph_tab[*id + 1].offset) { - ttf_seek_off (glyf_offset + glyph_tab[*id].offset); - k = copy_short (); - ttf_ncopy (4 * TTF_FWORD_SIZE); + ttf_seek_off(glyf_offset + glyph_tab[*id].offset); + k = copy_short(); + ttf_ncopy(4 * TTF_FWORD_SIZE); if (k < 0) { do { - flags = copy_ushort (); - idx = get_ushort (); + flags = copy_ushort(); + idx = get_ushort(); if (glyph_tab[idx].newindex < 0) { glyph_tab[idx].newindex = new_glyphs_count; glyph_index[new_glyphs_count++] = idx; @@ -988,27 +995,27 @@ static void ttf_write_glyf (void) which appears in the condition of the `for' loop */ } - (void) put_ushort (glyph_tab[idx].newindex); + (void) put_ushort(glyph_tab[idx].newindex); if (flags & ARG_1_AND_2_ARE_WORDS) - ttf_ncopy (2 * TTF_SHORT_SIZE); + ttf_ncopy(2 * TTF_SHORT_SIZE); else - ttf_ncopy (TTF_USHORT_SIZE); + ttf_ncopy(TTF_USHORT_SIZE); if (flags & WE_HAVE_A_SCALE) - ttf_ncopy (TTF_F2DOT14_SIZE); + ttf_ncopy(TTF_F2DOT14_SIZE); else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) - ttf_ncopy (2 * TTF_F2DOT14_SIZE); + ttf_ncopy(2 * TTF_F2DOT14_SIZE); else if (flags & WE_HAVE_A_TWO_BY_TWO) - ttf_ncopy (4 * TTF_F2DOT14_SIZE); + ttf_ncopy(4 * TTF_F2DOT14_SIZE); } while (flags & MORE_COMPONENTS); if (flags & WE_HAVE_INSTRUCTIONS) - ttf_ncopy (copy_ushort ()); + ttf_ncopy(copy_ushort()); } else - ttf_ncopy (glyph_tab[*id + 1].offset - glyph_tab[*id].offset - - TTF_USHORT_SIZE - 4 * TTF_FWORD_SIZE); + ttf_ncopy(glyph_tab[*id + 1].offset - glyph_tab[*id].offset - + TTF_USHORT_SIZE - 4 * TTF_FWORD_SIZE); } } - last_glyf_offset = ttf_offset () - new_glyf_offset; - ttf_set_chksm (tab); + last_glyf_offset = ttf_offset() - new_glyf_offset; + ttf_set_chksm(tab); } static void ttf_reindex_glyphs(void) @@ -1016,7 +1023,7 @@ static void ttf_reindex_glyphs(void) ttfenc_entry *e; glyph_entry *glyph; int index; - short *t; + long *t; ttf_cmap_entry *cmap = NULL; boolean cmap_not_found = false; @@ -1089,7 +1096,7 @@ static void ttf_reindex_glyphs(void) if (t[index] != -1) { if (t[index] >= glyphs_count) { pdftex_warn - ("`%s' is mapped to index %i which is out of valid range [0..%i)", + ("`%s' is mapped to index %li which is out of valid range [0..%i)", e->name, t[index], glyphs_count); continue; } @@ -1112,7 +1119,7 @@ static void ttf_reindex_glyphs(void) append_new_glyph: assert(glyph > glyph_tab && glyph - glyph_tab < glyphs_count); if (glyph->newindex < 0) { - glyph_index[new_glyphs_count] = (short) (glyph - glyph_tab); + glyph_index[new_glyphs_count] = (short) (glyph - glyph_tab); glyph->newindex = new_glyphs_count; new_glyphs_count++; } @@ -1120,53 +1127,53 @@ static void ttf_reindex_glyphs(void) } } -static void ttf_write_head () +static void ttf_write_head() { dirtab_entry *tab; - tab = ttf_seek_tab ("head", 0); - ttf_reset_chksm (tab); - ttf_ncopy (2 * TTF_FIXED_SIZE); - checkSumAdjustment_offset = ttf_offset (); - put_ulong (0); - ttf_skip (TTF_ULONG_SIZE); /* skip checkSumAdjustment */ - ttf_ncopy (TTF_ULONG_SIZE + 2 * TTF_USHORT_SIZE + 16 + - 4 * TTF_FWORD_SIZE + 2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE); + tab = ttf_seek_tab("head", 0); + ttf_reset_chksm(tab); + ttf_ncopy(2 * TTF_FIXED_SIZE); + checkSumAdjustment_offset = ttf_offset(); + put_ulong(0); + ttf_skip(TTF_ULONG_SIZE); /* skip checkSumAdjustment */ + ttf_ncopy(TTF_ULONG_SIZE + 2 * TTF_USHORT_SIZE + 16 + + 4 * TTF_FWORD_SIZE + 2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE); if (is_subsetted(fd_cur->fm)) { - (void) put_short (loca_format); - (void) put_short (0); + (void) put_short(loca_format); + (void) put_short(0); } else - ttf_ncopy (2 * TTF_SHORT_SIZE); - ttf_set_chksm (tab); + ttf_ncopy(2 * TTF_SHORT_SIZE); + ttf_set_chksm(tab); } -static void ttf_write_hhea (void) +static void ttf_write_hhea(void) { dirtab_entry *tab; - tab = ttf_seek_tab ("hhea", 0); - ttf_reset_chksm (tab); - ttf_ncopy (TTF_FIXED_SIZE + 3 * TTF_FWORD_SIZE + TTF_UFWORD_SIZE + - 3 * TTF_FWORD_SIZE + 8 * TTF_SHORT_SIZE); - (void) put_ushort (new_glyphs_count); - ttf_set_chksm (tab); + tab = ttf_seek_tab("hhea", 0); + ttf_reset_chksm(tab); + ttf_ncopy(TTF_FIXED_SIZE + 3 * TTF_FWORD_SIZE + TTF_UFWORD_SIZE + + 3 * TTF_FWORD_SIZE + 8 * TTF_SHORT_SIZE); + (void) put_ushort(new_glyphs_count); + ttf_set_chksm(tab); } -static void ttf_write_htmx (void) +static void ttf_write_htmx(void) { long *id; - dirtab_entry *tab = ttf_seek_tab ("hmtx", 0); - ttf_reset_chksm (tab); + dirtab_entry *tab = ttf_seek_tab("hmtx", 0); + ttf_reset_chksm(tab); for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) { - put_ufword (glyph_tab[*id].advWidth); - put_ufword (glyph_tab[*id].lsb); + put_ufword(glyph_tab[*id].advWidth); + put_ufword(glyph_tab[*id].lsb); } - ttf_set_chksm (tab); + ttf_set_chksm(tab); } -static void ttf_write_loca (void) +static void ttf_write_loca(void) { long *id; - dirtab_entry *tab = ttf_seek_tab ("loca", 0); - ttf_reset_chksm (tab); + dirtab_entry *tab = ttf_seek_tab("loca", 0); + ttf_reset_chksm(tab); loca_format = 0; if (last_glyf_offset >= 0x00020000 || (last_glyf_offset & 1)) loca_format = 1; @@ -1178,152 +1185,152 @@ static void ttf_write_loca (void) } if (loca_format != 0) { for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) - put_ulong (glyph_tab[*id].newoffset); - put_ulong (last_glyf_offset); + put_ulong(glyph_tab[*id].newoffset); + put_ulong(last_glyf_offset); } else { for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) - (void) put_ushort (glyph_tab[*id].newoffset / 2); - (void) put_ushort (last_glyf_offset / 2); + (void) put_ushort(glyph_tab[*id].newoffset / 2); + (void) put_ushort(last_glyf_offset / 2); } - ttf_set_chksm (tab); + ttf_set_chksm(tab); } -static void ttf_write_mapx (void) +static void ttf_write_mapx(void) { - dirtab_entry *tab = ttf_seek_tab ("maxp", TTF_FIXED_SIZE + TTF_USHORT_SIZE); - ttf_reset_chksm (tab); - put_fixed (0x00010000); - (void) put_ushort (new_glyphs_count); - ttf_ncopy (13 * TTF_USHORT_SIZE); - ttf_set_chksm (tab); + dirtab_entry *tab = ttf_seek_tab("maxp", TTF_FIXED_SIZE + TTF_USHORT_SIZE); + ttf_reset_chksm(tab); + put_fixed(0x00010000); + (void) put_ushort(new_glyphs_count); + ttf_ncopy(13 * TTF_USHORT_SIZE); + ttf_set_chksm(tab); } -static void ttf_write_OS2 (void) +static void ttf_write_OS2(void) { - dirtab_entry *tab = ttf_seek_tab ("OS/2", 0); + dirtab_entry *tab = ttf_seek_tab("OS/2", 0); TTF_USHORT version; - ttf_reset_chksm (tab); - version = get_ushort (); + ttf_reset_chksm(tab); + version = get_ushort(); if (version > 3) - pdftex_fail ("unknown version of OS/2 table (%.4X)", version); - (void) put_ushort (0x0001); /* fix version to 1 */ - ttf_ncopy (2 * TTF_USHORT_SIZE + 13 * TTF_SHORT_SIZE + 10 * TTF_BYTE_SIZE); - ttf_skip (4 * TTF_ULONG_SIZE); /* ulUnicodeRange 1--4 */ - put_ulong (0x00000003); /* Basic Latin + Latin-1 Supplement (0x0000--0x00FF) */ - put_ulong (0x10000000); /* Private Use (0xE000--0xF8FF) */ - put_ulong (0x00000000); - put_ulong (0x00000000); - ttf_ncopy (4 * TTF_CHAR_SIZE + TTF_USHORT_SIZE); /* achVendID + fsSelection */ - ttf_skip (2 * TTF_USHORT_SIZE); - (void) put_ushort (0x0000); /* usFirstCharIndex */ - (void) put_ushort (0xF0FF); /* usLastCharIndex */ - ttf_ncopy (5 * TTF_USHORT_SIZE); + pdftex_fail("unknown version of OS/2 table (%.4X)", version); + (void) put_ushort(0x0001); /* fix version to 1 */ + ttf_ncopy(2 * TTF_USHORT_SIZE + 13 * TTF_SHORT_SIZE + 10 * TTF_BYTE_SIZE); + ttf_skip(4 * TTF_ULONG_SIZE); /* ulUnicodeRange 1--4 */ + put_ulong(0x00000003); /* Basic Latin + Latin-1 Supplement (0x0000--0x00FF) */ + put_ulong(0x10000000); /* Private Use (0xE000--0xF8FF) */ + put_ulong(0x00000000); + put_ulong(0x00000000); + ttf_ncopy(4 * TTF_CHAR_SIZE + TTF_USHORT_SIZE); /* achVendID + fsSelection */ + ttf_skip(2 * TTF_USHORT_SIZE); + (void) put_ushort(0x0000); /* usFirstCharIndex */ + (void) put_ushort(0xF0FF); /* usLastCharIndex */ + ttf_ncopy(5 * TTF_USHORT_SIZE); /* for version 0 the OS/2 table ends here, the rest is for version 1 */ - put_ulong (0x80000000); /* Symbol Character Set---don't use any code page */ - put_ulong (0x00000000); - ttf_set_chksm (tab); + put_ulong(0x80000000); /* Symbol Character Set---don't use any code page */ + put_ulong(0x00000000); + ttf_set_chksm(tab); } -static boolean unsafe_name (char *s) +static boolean unsafe_name(char *s) { const char **p; for (p = ambiguous_names; *p != NULL; p++) - if (strcmp (s, *p) == 0) + if (strcmp(s, *p) == 0) return true; return false; } -static void ttf_write_post (void) +static void ttf_write_post(void) { - dirtab_entry *tab = ttf_seek_tab ("post", TTF_FIXED_SIZE); + dirtab_entry *tab = ttf_seek_tab("post", TTF_FIXED_SIZE); glyph_entry *glyph; char *s; long *id; int l; - ttf_reset_chksm (tab); + ttf_reset_chksm(tab); if (!fd_cur->write_ttf_glyph_names || post_format == 0x00030000) { - put_fixed (0x00030000); - ttf_ncopy (TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); + put_fixed(0x00030000); + ttf_ncopy(TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); } else { - put_fixed (0x00020000); - ttf_ncopy (TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); - (void) put_ushort (new_glyphs_count); + put_fixed(0x00020000); + ttf_ncopy(TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); + (void) put_ushort(new_glyphs_count); k = 0; for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) { glyph = glyph_tab + *id; - if (glyph->name_index >= NMACGLYPHS || unsafe_name (glyph->name)) + if (glyph->name_index >= NMACGLYPHS || unsafe_name(glyph->name)) glyph->name_index = NMACGLYPHS + k++; - (void) put_ushort (glyph->name_index); + (void) put_ushort(glyph->name_index); } for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) { glyph = glyph_tab + *id; if (glyph->name_index >= NMACGLYPHS) { s = glyph->name; - l = strlen (s); - put_byte (l); + l = strlen(s); + put_byte(l); while (l-- > 0) - put_char (*s++); + put_char(*s++); } } } - ttf_set_chksm (tab); + ttf_set_chksm(tab); } -static void ttf_init_font (int n) +static void ttf_init_font(int n) { int i, k; for (i = 1, k = 0; i <= n; i <<= 1, k++); - put_fixed (0x00010000); /* font version */ - (void) put_ushort (n); /* number of tables */ - (void) put_ushort (i << 3); /* search range */ - (void) put_ushort (k - 1); /* entry selector */ - (void) put_ushort ((n << 4) - (i << 3)); /* range shift */ - ttf_seek_outbuf (TABDIR_OFF + n * 4 * TTF_ULONG_SIZE); + put_fixed(0x00010000); /* font version */ + (void) put_ushort(n); /* number of tables */ + (void) put_ushort(i << 3); /* search range */ + (void) put_ushort(k - 1); /* entry selector */ + (void) put_ushort((n << 4) - (i << 3)); /* range shift */ + ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE); } -static void ttf_subset_font (void) +static void ttf_subset_font(void) { - ttf_init_font (new_ntabs); - if (ttf_name_lookup ("PCLT", false) != NULL) - ttf_copytab ("PCLT"); - if (ttf_name_lookup ("fpgm", false) != NULL) - ttf_copytab ("fpgm"); - if (ttf_name_lookup ("cvt ", false) != NULL) - ttf_copytab ("cvt "); - if (ttf_name_lookup ("prep", false) != NULL) - ttf_copytab ("prep"); - ttf_reindex_glyphs (); - ttf_write_glyf (); - ttf_write_loca (); - ttf_write_OS2 (); - ttf_write_head (); - ttf_write_hhea (); - ttf_write_htmx (); - ttf_write_mapx (); - ttf_write_name (); - ttf_write_post (); - ttf_write_cmap (); - ttf_write_dirtab (); + ttf_init_font(new_ntabs); + if (ttf_name_lookup("PCLT", false) != NULL) + ttf_copytab("PCLT"); + if (ttf_name_lookup("fpgm", false) != NULL) + ttf_copytab("fpgm"); + if (ttf_name_lookup("cvt ", false) != NULL) + ttf_copytab("cvt "); + if (ttf_name_lookup("prep", false) != NULL) + ttf_copytab("prep"); + ttf_reindex_glyphs(); + ttf_write_glyf(); + ttf_write_loca(); + ttf_write_OS2(); + ttf_write_head(); + ttf_write_hhea(); + ttf_write_htmx(); + ttf_write_mapx(); + ttf_write_name(); + ttf_write_post(); + ttf_write_cmap(); + ttf_write_dirtab(); } -static void ttf_copy_font (void) +static void ttf_copy_font(void) { dirtab_entry *tab; - ttf_init_font (ntabs); + ttf_init_font(ntabs); for (tab = dir_tab; tab - dir_tab < ntabs; tab++) { - if (strncmp (tab->tag, "head", 4) == 0) - ttf_write_head (); + if (strncmp(tab->tag, "head", 4) == 0) + ttf_write_head(); else - ttf_copytab (tab->tag); + ttf_copytab(tab->tag); } - ttf_write_dirtab (); + ttf_write_dirtab(); } void writettf(fd_entry * fd) { - int callback_id; - int file_opened = 0; - char *ftemp = NULL; + int callback_id; + int file_opened = 0; + char *ftemp = NULL; fd_cur = fd; /* fd_cur is global inside writettf.c */ assert(fd_cur->fm != NULL); assert(is_truetype(fd_cur->fm)); @@ -1333,47 +1340,46 @@ void writettf(fd_entry * fd) if (is_subsetted(fd_cur->fm) && (fd_cur->fe == NULL) && !is_subfont(fd_cur->fm)) { - pdftex_warn ("Subset TrueType must be a reencoded or a subfont"); - cur_file_name = NULL; - return; + pdftex_fail("Subset TrueType must be a reencoded or a subfont"); + } + ttf_curbyte = 0; + ttf_size = 0; + callback_id = callback_defined(find_truetype_file_callback); + if (callback_id > 0) { + if (run_callback + (callback_id, "S->S", (char *) (nameoffile + 1), &ftemp)) { + if (ftemp != NULL && strlen(ftemp)) { + free(nameoffile); + namelength = strlen(ftemp); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), ftemp); + free(ftemp); + } + } + } + + callback_id = callback_defined(read_truetype_file_callback); + if (callback_id > 0) { + if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1), + &file_opened, &ttf_buffer, &ttf_size) && + file_opened && ttf_size > 0) { + } else { + pdftex_fail("cannot open TrueType font file for reading"); + } + } else { + if (!ttf_open()) { + pdftex_fail("cannot open TrueType font file for reading"); + } + ttf_read_file(); + ttf_close(); } - ttf_curbyte=0; - ttf_size=0; - callback_id=callback_defined(find_truetype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->S",(char *)(nameoffile+1),&ftemp)) { - if(ftemp!=NULL&&strlen(ftemp)) { - free(nameoffile); - namelength = strlen(ftemp); - nameoffile = xmalloc(namelength+2); - strcpy((char *)(nameoffile+1),ftemp); - free(ftemp); - } - } - } - - callback_id=callback_defined(read_truetype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->bSd",(char *)(nameoffile+1), - &file_opened, &ttf_buffer,&ttf_size) && - file_opened && ttf_size>0) { - } else { - pdftex_fail ("cannot open TrueType font file for reading"); - } - } else { - if (!ttf_open ()) { - pdftex_fail ("cannot open TrueType font file for reading"); - } - ttf_read_file(); - ttf_close(); - } cur_file_name = (char *) nameoffile + 1; - if (tracefilenames) { - if (is_subsetted(fd_cur->fm)) - tex_printf ("<%s", cur_file_name); - else - tex_printf ("<<%s", cur_file_name); - } + if (tracefilenames) { + if (is_subsetted(fd_cur->fm)) + tex_printf("<%s", cur_file_name); + else + tex_printf("<<%s", cur_file_name); + } fd_cur->ff_found = true; new_glyphs_count = 2; new_ntabs = DEFAULT_NTABS; @@ -1383,107 +1389,111 @@ void writettf(fd_entry * fd) glyph_name_buf = NULL; name_tab = NULL; name_buf = NULL; - ttf_read_font (); - - pdf_save_offset = pdfoffset (); - pdf_flush (); - - if (is_subsetted(fd_cur->fm)) { - ttf_copy_encoding (); - ttf_subset_font (); - } else - ttf_copy_font (); - ttf_length = ttf_offset (); - - xfree (dir_tab); - xfree (glyph_tab); - xfree (glyph_index); - xfree (glyph_name_buf); - xfree (name_tab); - xfree (name_buf); - if (tracefilenames) { - if (is_subsetted (fd_cur->fm)) - tex_printf (">"); - else - tex_printf (">>"); - } + ttf_read_font(); + + pdf_save_offset = pdfoffset(); + pdf_flush(); + + if (is_subsetted(fd_cur->fm)) { + ttf_copy_encoding(); + ttf_subset_font(); + } else + ttf_copy_font(); + ttf_length = ttf_offset(); + + xfree(dir_tab); + xfree(glyph_tab); + xfree(glyph_index); + xfree(glyph_name_buf); + xfree(name_tab); + xfree(name_buf); + if (tracefilenames) { + if (is_subsetted(fd_cur->fm)) + tex_printf(">"); + else + tex_printf(">>"); + } + xfree(ttf_buffer); cur_file_name = NULL; } void do_writeotf(fd_entry * fd) { - long i; - dirtab_entry *tab; - dir_tab = NULL; - glyph_tab = NULL; - if (tracefilenames) - tex_printf ("<<%s", cur_file_name); - ttf_read_tabdir (); - /* read font parameters */ - if (ttf_name_lookup ("head", false) != NULL) - ttf_read_head (); - if (ttf_name_lookup ("hhea", false) != NULL) - ttf_read_hhea (); - if (ttf_name_lookup ("PCLT", false) != NULL) - ttf_read_pclt (); - if (ttf_name_lookup ("post", false) != NULL) - ttf_read_post (); - /* copy font file */ - tab = ttf_seek_tab ("CFF ", 0); - for (i = tab->length; i > 0; i--) - copy_char (); - xfree (dir_tab); - /* ttf_close ();*/ - if (tracefilenames) - tex_printf (">>"); + long i; + dirtab_entry *tab; + dir_tab = NULL; + glyph_tab = NULL; + if (tracefilenames) + tex_printf("<<%s", cur_file_name); + ttf_read_tabdir(); + /* read font parameters */ + if (ttf_name_lookup("head", false) != NULL) + ttf_read_head(); + if (ttf_name_lookup("hhea", false) != NULL) + ttf_read_hhea(); + if (ttf_name_lookup("PCLT", false) != NULL) + ttf_read_pclt(); + if (ttf_name_lookup("post", false) != NULL) + ttf_read_post(); + /* copy font file */ + tab = ttf_seek_tab("CFF ", 0); + for (i = tab->length; i > 0; i--) + copy_char(); + xfree(dir_tab); + /* ttf_close (); */ + if (tracefilenames) + tex_printf(">>"); } -void writeotf (fd_entry * fd) { - int callback_id; - int file_opened = 0; - char *ftemp = NULL; - - - fd_cur = fd; /* fd_cur is global inside writettf.c */ - assert(fd_cur->fm != NULL); - assert(is_opentype(fd_cur->fm)); - assert(is_included(fd_cur->fm)); - - set_cur_file_name(fd_cur->fm->ff_name); - ttf_curbyte=0; - ttf_size=0; - callback_id=callback_defined(find_opentype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->S",(char *)(nameoffile+1),&ftemp)) { - if(ftemp!=NULL&&strlen(ftemp)) { - free(nameoffile); - namelength = strlen(ftemp); - nameoffile = xmalloc(namelength+2); - strcpy((char *)(nameoffile+1),ftemp); - free(ftemp); - } +void writeotf(fd_entry * fd) +{ + int callback_id; + int file_opened = 0; + char *ftemp = NULL; + + + fd_cur = fd; /* fd_cur is global inside writettf.c */ + assert(fd_cur->fm != NULL); + assert(is_opentype(fd_cur->fm)); + assert(is_included(fd_cur->fm)); + + set_cur_file_name(fd_cur->fm->ff_name); + ttf_curbyte = 0; + ttf_size = 0; + callback_id = callback_defined(find_opentype_file_callback); + if (callback_id > 0) { + if (run_callback + (callback_id, "S->S", (char *) (nameoffile + 1), &ftemp)) { + if (ftemp != NULL && strlen(ftemp)) { + free(nameoffile); + namelength = strlen(ftemp); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), ftemp); + free(ftemp); + } + } } - } - callback_id=callback_defined(read_opentype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->bSd",(char *)(nameoffile+1), - &file_opened, &ttf_buffer,&ttf_size) && - file_opened && ttf_size>0) { + callback_id = callback_defined(read_opentype_file_callback); + if (callback_id > 0) { + if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1), + &file_opened, &ttf_buffer, &ttf_size) && + file_opened && ttf_size > 0) { + } else { + pdftex_fail("cannot open OpenType font file for reading"); + } } else { - pdftex_fail ("cannot open OpenType font file for reading"); - } - } else { - if (!otf_open ()) { - pdftex_fail ("cannot open OpenType font file for reading"); + if (!otf_open()) { + pdftex_fail("cannot open OpenType font file for reading"); + } + ttf_read_file(); + ttf_close(); } - ttf_read_file(); - ttf_close(); - } - - cur_file_name = (char *) nameoffile + 1; - fd_cur->ff_found = true; - do_writeotf(fd); - cur_file_name = NULL; + + cur_file_name = (char *) nameoffile + 1; + fd_cur->ff_found = true; + do_writeotf(fd); + xfree(ttf_buffer); + cur_file_name = NULL; } /* diff --git a/Build/source/texk/web2c/luatexdir/font/writettf.h b/Build/source/texk/web2c/luatexdir/font/writettf.h index ecfaa2c37e3..42a57a72c8f 100644 --- a/Build/source/texk/web2c/luatexdir/font/writettf.h +++ b/Build/source/texk/web2c/luatexdir/font/writettf.h @@ -1,25 +1,27 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, +/* writettf.h + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ -$Id: writettf.h 1013 2008-02-14 00:09:02Z oneiros $ -*/ +/* $Id: writettf.h 1592 2008-11-28 13:23:51Z oneiros $ */ +#ifndef WRITETTF_H +# define WRITETTF_H 1 typedef signed char TTF_CHAR; typedef unsigned char TTF_BYTE; typedef signed short TTF_SHORT; @@ -32,79 +34,82 @@ typedef signed short TTF_FWORD; typedef unsigned short TTF_UFWORD; typedef unsigned short TTF_F2DOT14; -#define TTF_CHAR_SIZE 1 -#define TTF_BYTE_SIZE 1 -#define TTF_SHORT_SIZE 2 -#define TTF_USHORT_SIZE 2 -#define TTF_LONG_SIZE 4 -#define TTF_ULONG_SIZE 4 -#define TTF_FIXED_SIZE 4 -#define TTF_FWORD_SIZE 2 -#define TTF_UFWORD_SIZE 2 -#define TTF_F2DOT14_SIZE 2 - -#define ARG_1_AND_2_ARE_WORDS (1<<0) -#define ARGS_ARE_XY_VALUES (1<<1) -#define ROUND_XY_TO_GRID (1<<2) -#define WE_HAVE_A_SCALE (1<<3) -#define RESERVED (1<<4) -#define MORE_COMPONENTS (1<<5) -#define WE_HAVE_AN_X_AND_Y_SCALE (1<<6) -#define WE_HAVE_A_TWO_BY_TWO (1<<7) -#define WE_HAVE_INSTRUCTIONS (1<<8) -#define USE_MY_METRICS (1<<9) - -#define get_type(t) ((t)ttf_getnum(t##_SIZE)) -#define ttf_skip(n) ttf_getnum(n) - -#define get_byte() get_type(TTF_BYTE) -#define get_char() get_type(TTF_CHAR) -#define get_ushort() get_type(TTF_USHORT) -#define get_short() get_type(TTF_SHORT) -#define get_ulong() get_type(TTF_ULONG) -#define get_long() get_type(TTF_LONG) -#define get_fixed() get_type(TTF_FIXED) -#define get_funit() get_type(TTF_FUNIT) -#define get_fword() get_type(TTF_FWORD) -#define get_ufword() get_type(TTF_UFWORD) -#define get_f2dot14() get_type(TTF_F2DOT14) - -#define put_num(t,n) ((t)ttf_putnum(t##_SIZE, n)) - -#define put_char(n) (void)put_num(TTF_CHAR, n) -#define put_byte(n) (void)put_num(TTF_BYTE, n) -#define put_short(n) put_num(TTF_SHORT, n) -#define put_ushort(n) put_num(TTF_USHORT, n) -#define put_long(n) put_num(TTF_LONG, n) -#define put_ulong(n) (void)put_num(TTF_ULONG, n) -#define put_fixed(n) (void)put_num(TTF_FIXED, n) -#define put_funit(n) put_num(TTF_FUNIT, n) -#define put_fword(n) put_num(TTF_FWORD, n) -#define put_ufword(n) (void)put_num(TTF_UFWORD, n) -#define put_f2dot14(n) put_num(TTF_F2DOT14, n) - -#define copy_byte() put_byte(get_byte()) -#define copy_char() put_char(get_char()) -#define copy_ushort() put_ushort(get_ushort()) -#define copy_short() put_short(get_short()) -#define copy_ulong() put_ulong(get_ulong()) -#define copy_long() put_long(get_long()) -#define copy_fixed() put_fixed(get_fixed()) -#define copy_funit() put_funit(get_funit()) -#define copy_fword() put_fword(get_fword()) -#define copy_ufword() put_ufword(get_ufword()) -#define copy_f2dot14() put_f2dot14(get_f2dot14()) - -#define is_unicode_mapping(e) \ +# define TTF_CHAR_SIZE 1 +# define TTF_BYTE_SIZE 1 +# define TTF_SHORT_SIZE 2 +# define TTF_USHORT_SIZE 2 +# define TTF_LONG_SIZE 4 +# define TTF_ULONG_SIZE 4 +# define TTF_FIXED_SIZE 4 +# define TTF_FWORD_SIZE 2 +# define TTF_UFWORD_SIZE 2 +# define TTF_F2DOT14_SIZE 2 + +/* + * TrueType outline data. + */ +# define ARG_1_AND_2_ARE_WORDS (1<<0) +# define ARGS_ARE_XY_VALUES (1<<1) +# define ROUND_XY_TO_GRID (1<<2) +# define WE_HAVE_A_SCALE (1<<3) +# define RESERVED (1<<4) +# define MORE_COMPONENTS (1<<5) +# define WE_HAVE_AN_X_AND_Y_SCALE (1<<6) +# define WE_HAVE_A_TWO_BY_TWO (1<<7) +# define WE_HAVE_INSTRUCTIONS (1<<8) +# define USE_MY_METRICS (1<<9) + +# define get_type(t) ((t)ttf_getnum(t##_SIZE)) +# define ttf_skip(n) ttf_getnum(n) + +# define get_byte() get_type(TTF_BYTE) +# define get_char() get_type(TTF_CHAR) +# define get_ushort() get_type(TTF_USHORT) +# define get_short() get_type(TTF_SHORT) +# define get_ulong() get_type(TTF_ULONG) +# define get_long() get_type(TTF_LONG) +# define get_fixed() get_type(TTF_FIXED) +# define get_funit() get_type(TTF_FUNIT) +# define get_fword() get_type(TTF_FWORD) +# define get_ufword() get_type(TTF_UFWORD) +# define get_f2dot14() get_type(TTF_F2DOT14) + +# define put_num(t,n) ((t)ttf_putnum(t##_SIZE, n)) + +# define put_char(n) (void)put_num(TTF_CHAR, n) +# define put_byte(n) (void)put_num(TTF_BYTE, n) +# define put_short(n) put_num(TTF_SHORT, n) +# define put_ushort(n) put_num(TTF_USHORT, n) +# define put_long(n) put_num(TTF_LONG, n) +# define put_ulong(n) (void)put_num(TTF_ULONG, n) +# define put_fixed(n) (void)put_num(TTF_FIXED, n) +# define put_funit(n) put_num(TTF_FUNIT, n) +# define put_fword(n) put_num(TTF_FWORD, n) +# define put_ufword(n) (void)put_num(TTF_UFWORD, n) +# define put_f2dot14(n) put_num(TTF_F2DOT14, n) + +# define copy_byte() put_byte(get_byte()) +# define copy_char() put_char(get_char()) +# define copy_ushort() put_ushort(get_ushort()) +# define copy_short() put_short(get_short()) +# define copy_ulong() put_ulong(get_ulong()) +# define copy_long() put_long(get_long()) +# define copy_fixed() put_fixed(get_fixed()) +# define copy_funit() put_funit(get_funit()) +# define copy_fword() put_fword(get_fword()) +# define copy_ufword() put_ufword(get_ufword()) +# define copy_f2dot14() put_f2dot14(get_f2dot14()) + +# define is_unicode_mapping(e) \ (e->platform_id == 0 || (e->platform_id == 3 || e->encoding_id == 1)) -#define NMACGLYPHS 258 -#define TABDIR_OFF 12 -#define ENC_BUF_SIZE 1024 +# define NMACGLYPHS 258 +# define TABDIR_OFF 12 +# define ENC_BUF_SIZE 1024 -#define GLYPH_PREFIX_INDEX "index" -#define GLYPH_PREFIX_UNICODE "uni" +# define GLYPH_PREFIX_INDEX "index" +# define GLYPH_PREFIX_UNICODE "uni" typedef struct { char tag[4]; @@ -145,28 +150,27 @@ extern integer ttf_size; extern integer ttf_curbyte; extern glyph_entry *glyph_tab; extern dirtab_entry *dir_tab; -extern dirtab_entry *ttf_name_lookup (const char *s, boolean required); -extern dirtab_entry *ttf_seek_tab (const char *name, TTF_LONG offset); +extern dirtab_entry *ttf_name_lookup(const char *s, boolean required); +extern dirtab_entry *ttf_seek_tab(const char *name, TTF_LONG offset); -extern void ttf_read_tabdir (void); -extern void ttf_read_head (void); -extern void ttf_read_hhea (void); -extern void ttf_read_pclt (void); -extern void ttf_read_post (void); +extern void ttf_read_tabdir(void); +extern void ttf_read_head(void); +extern void ttf_read_hhea(void); +extern void ttf_read_pclt(void); +extern void ttf_read_post(void); extern FILE *ttf_file; -#define ttf_open() \ - open_input(&ttf_file, kpse_truetype_format, FOPEN_RBIN_MODE) -#define otf_open() \ - open_input(&ttf_file, kpse_opentype_format, FOPEN_RBIN_MODE) -#define ttf_read_file() \ +# define ttf_open() \ + (ttf_file = fopen((char *) nameoffile + 1, FOPEN_RBIN_MODE)) +# define otf_open() \ + (ttf_file = fopen((char *) nameoffile + 1, FOPEN_RBIN_MODE)) +# define ttf_read_file() \ readbinfile(ttf_file,&ttf_buffer,&ttf_size) -#define ttf_close() xfclose(ttf_file,cur_file_name) -#define ttf_getchar() ttf_buffer[ttf_curbyte++] -#define ttf_eof() (ttf_curbyte>ttf_size) - -extern long ttf_putnum (int s, long n); -extern long ttf_getnum (int s); - +# define ttf_close() xfclose(ttf_file,cur_file_name) +# define ttf_getchar() ttf_buffer[ttf_curbyte++] +# define ttf_eof() (ttf_curbyte>ttf_size) +extern long ttf_putnum(int s, long n); +extern long ttf_getnum(int s); +#endif diff --git a/Build/source/texk/web2c/luatexdir/font/writetype0.c b/Build/source/texk/web2c/luatexdir/font/writetype0.c index 0f9eecaac7c..846314bedab 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype0.c +++ b/Build/source/texk/web2c/luatexdir/font/writetype0.c @@ -1,124 +1,125 @@ -/* -Copyright (c) 2007 Taco Hoekwater, taco@luatex.org +/* writetype0.c + + Copyright 2006-2008 Taco Hoekwater -This file is part of luaTeX. + This file is part of LuaTeX. -luaTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -luaTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with luaTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: writetype0.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" - #include "writettf.h" - #include "writecff.h" -void writetype0 (fd_entry * fd) { - int callback_id; - int file_opened = 0; - char *ftemp = NULL; - long i; - dirtab_entry *tab; - cff_font *cff; - - dir_tab = NULL; - glyph_tab = NULL; - - fd_cur = fd; /* fd_cur is global inside writettf.c */ - assert(fd_cur->fm != NULL); - assert(is_opentype(fd_cur->fm)); - assert(is_included(fd_cur->fm)); - - set_cur_file_name(fd_cur->fm->ff_name); - ttf_curbyte=0; - ttf_size=0; - callback_id=callback_defined(find_opentype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->S",(char *)(nameoffile+1),&ftemp)) { - if(ftemp!=NULL&&strlen(ftemp)) { - free(nameoffile); - namelength = strlen(ftemp); - nameoffile = xmalloc(namelength+2); - strcpy((char *)(nameoffile+1),ftemp); - free(ftemp); - } +static const char _svn_version[] = + "$Id: writetype0.c 1783 2009-01-18 12:51:01Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writetype0.c $"; + +void writetype0(fd_entry * fd) +{ + int callback_id; + int file_opened = 0; + char *ftemp = NULL; + long i; + dirtab_entry *tab; + cff_font *cff; + + dir_tab = NULL; + glyph_tab = NULL; + + fd_cur = fd; /* fd_cur is global inside writettf.c */ + assert(fd_cur->fm != NULL); + assert(is_opentype(fd_cur->fm)); + assert(is_included(fd_cur->fm)); + + set_cur_file_name(fd_cur->fm->ff_name); + ttf_curbyte = 0; + ttf_size = 0; + callback_id = callback_defined(find_opentype_file_callback); + if (callback_id > 0) { + if (run_callback + (callback_id, "S->S", (char *) (nameoffile + 1), &ftemp)) { + if (ftemp != NULL && strlen(ftemp)) { + free(nameoffile); + namelength = strlen(ftemp); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), ftemp); + free(ftemp); + } + } } - } - callback_id=callback_defined(read_opentype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->bSd",(char *)(nameoffile+1), - &file_opened, &ttf_buffer,&ttf_size) && - file_opened && ttf_size>0) { + callback_id = callback_defined(read_opentype_file_callback); + if (callback_id > 0) { + if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1), + &file_opened, &ttf_buffer, &ttf_size) && + file_opened && ttf_size > 0) { + } else { + pdftex_fail("cannot open OpenType font file for reading"); + } } else { - pdftex_fail ("cannot open OpenType font file for reading"); - } - } else { - if (!otf_open ()) { - pdftex_fail ("cannot open OpenType font file for reading"); + if (!otf_open()) { + pdftex_fail("cannot open OpenType font file for reading"); + } + ttf_read_file(); + ttf_close(); } - ttf_read_file(); - ttf_close(); - } - - cur_file_name = (char *) nameoffile + 1; - fd_cur->ff_found = true; - if (tracefilenames) { - if (is_subsetted(fd_cur->fm)) - tex_printf ("<%s", cur_file_name); - else - tex_printf ("<<%s", cur_file_name); - } - ttf_read_tabdir (); - /* read font parameters */ - if (ttf_name_lookup ("head", false) != NULL) - ttf_read_head (); - if (ttf_name_lookup ("hhea", false) != NULL) - ttf_read_hhea (); - if (ttf_name_lookup ("PCLT", false) != NULL) - ttf_read_pclt (); - if (ttf_name_lookup ("post", false) != NULL) - ttf_read_post (); + cur_file_name = (char *) nameoffile + 1; + fd_cur->ff_found = true; - /* copy font file */ - tab = ttf_seek_tab ("CFF ", 0); + if (tracefilenames) { + if (is_subsetted(fd_cur->fm)) + tex_printf("<%s", cur_file_name); + else + tex_printf("<<%s", cur_file_name); + } + ttf_read_tabdir(); + /* read font parameters */ + if (ttf_name_lookup("head", false) != NULL) + ttf_read_head(); + if (ttf_name_lookup("hhea", false) != NULL) + ttf_read_hhea(); + if (ttf_name_lookup("PCLT", false) != NULL) + ttf_read_pclt(); + if (ttf_name_lookup("post", false) != NULL) + ttf_read_post(); - /* TODO the next 0 is a subfont index */ - cff = read_cff(ttf_buffer+ttf_curbyte,tab->length,0); - if (cff != NULL) { - if (cff_is_cidfont(cff)) { - write_cid_cff(cff,fd_cur,0); - /* - for (i = tab->length; i > 0; i--) - fb_putchar (ttf_getnum(1)); - */ + /* copy font file */ + tab = ttf_seek_tab("CFF ", 0); + + /* TODO the next 0 is a subfont index */ + cff = read_cff(ttf_buffer + ttf_curbyte, tab->length, 0); + if (cff != NULL) { + if (cff_is_cidfont(cff)) { + write_cid_cff(cff, fd_cur); + /* + for (i = tab->length; i > 0; i--) + fb_putchar (ttf_getnum(1)); + */ + } else { + write_cff(cff, fd_cur); + } } else { - write_cff(cff,fd_cur,0); + /* not understood, just do a copy */ + for (i = tab->length; i > 0; i--) + fb_putchar(ttf_getnum(1)); + } + xfree(dir_tab); + xfree(ttf_buffer); + if (tracefilenames) { + if (is_subsetted(fd_cur->fm)) + tex_printf(">"); + else + tex_printf(">>"); } - } else { - /* not understood, just do a copy */ - for (i = tab->length; i > 0; i--) - fb_putchar (ttf_getnum(1)); - } - xfree (dir_tab); - if (tracefilenames) { - if (is_subsetted (fd_cur->fm)) - tex_printf (">"); - else - tex_printf (">>"); - } - cur_file_name = NULL; + cur_file_name = NULL; } diff --git a/Build/source/texk/web2c/luatexdir/font/writetype2.c b/Build/source/texk/web2c/luatexdir/font/writetype2.c index 649c350b707..ba98772b931 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype2.c +++ b/Build/source/texk/web2c/luatexdir/font/writetype2.c @@ -1,25 +1,21 @@ +/* writetype0.c + + Copyright 2006-2008 Taco Hoekwater -/* -Copyright (c) 2007 Taco Hoekwater, taco@luatex.org - -This file is part of luaTeX. - -luaTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -luaTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with luaTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writetype2.c 1013 2008-02-14 00:09:02Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" #include "writettf.h" @@ -28,170 +24,185 @@ $Id: writetype2.c 1013 2008-02-14 00:09:02Z oneiros $ #include "sfnt.h" #include "tt_glyf.h" +static const char _svn_version[] = + "$Id: writetype2.c 1783 2009-01-18 12:51:01Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writetype2.c $"; + /* forward*/ -void make_tt_subset (fd_entry * fd,unsigned char *buffer, integer buflen) ; +void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen); unsigned long cidtogid_obj = 0; /* low-level helpers */ -#define test_loc(l) \ - if ((f->loc+l)>f->buflen) { \ - fprintf (stderr,"File ended prematurely\n"); \ - uexit(1); \ +#define test_loc(l) \ + if ((f->loc+l)>f->buflen) { \ + fprintf (stderr,"File ended prematurely\n"); \ + uexit(1); \ } -BYTE get_unsigned_byte(sfnt* f) { - test_loc(1); - return (BYTE)f->buffer[(f->loc++)]; +BYTE get_unsigned_byte(sfnt * f) +{ + test_loc(1); + return (BYTE) f->buffer[(f->loc++)]; }; -ICHAR get_signed_byte(sfnt* f) { - test_loc(1); - return (ICHAR)f->buffer[(f->loc++)]; +ICHAR get_signed_byte(sfnt * f) +{ + test_loc(1); + return (ICHAR) f->buffer[(f->loc++)]; }; -USHORT get_unsigned_pair(sfnt* f){ - USHORT l; - test_loc(2); - l = f->buffer[(f->loc++)]; - l = l*0x100 + f->buffer[(f->loc++)]; - return l; +USHORT get_unsigned_pair(sfnt * f) +{ + USHORT l; + test_loc(2); + l = f->buffer[(f->loc++)]; + l = l * 0x100 + f->buffer[(f->loc++)]; + return l; }; -SHORT get_signed_pair(sfnt* f){ - long l; - test_loc(2); - l = f->buffer[(f->loc++)]; - if (l>0x80) l -= 0x100; - l = l*0x100 + f->buffer[(f->loc++)]; - return l; +SHORT get_signed_pair(sfnt * f) +{ + long l; + test_loc(2); + l = f->buffer[(f->loc++)]; + if (l > 0x80) + l -= 0x100; + l = l * 0x100 + f->buffer[(f->loc++)]; + return l; }; -ULONG get_unsigned_quad(sfnt* f){ - ULONG l; - test_loc(4); - l = f->buffer[(f->loc++)]; - l = l*0x100 + f->buffer[(f->loc++)]; - l = l*0x100 + f->buffer[(f->loc++)]; - l = l*0x100 + f->buffer[(f->loc++)]; - return l; +ULONG get_unsigned_quad(sfnt * f) +{ + ULONG l; + test_loc(4); + l = f->buffer[(f->loc++)]; + l = l * 0x100 + f->buffer[(f->loc++)]; + l = l * 0x100 + f->buffer[(f->loc++)]; + l = l * 0x100 + f->buffer[(f->loc++)]; + return l; }; -int do_sfnt_read (unsigned char *dest, int len, sfnt *f) { - int i; - test_loc(len); - for (i=0;ibuffer[f->loc+i]; - } - f->loc += len; - return len; +int do_sfnt_read(unsigned char *dest, int len, sfnt * f) +{ + int i; + test_loc(len); + for (i = 0; i < len; i++) { + *(dest + i) = f->buffer[f->loc + i]; + } + f->loc += len; + return len; }; -pdf_obj *pdf_new_stream(void) { - pdf_obj *stream = xmalloc(sizeof(pdf_obj)) ; - stream->length =0; - stream->data=NULL; - return stream; +pdf_obj *pdf_new_stream(void) +{ + pdf_obj *stream = xmalloc(sizeof(pdf_obj)); + stream->length = 0; + stream->data = NULL; + return stream; }; -void pdf_add_stream(pdf_obj *stream, unsigned char *buf, long len) { - int i; - assert (stream!=NULL); - if (stream->data==NULL) { - stream->data = xmalloc(len); - } else { - stream->data = xrealloc(stream->data,len+stream->length); - } - for (i=0;idata+stream->length+i)=*(buf+i); - } - stream->length+=len; +void pdf_add_stream(pdf_obj * stream, unsigned char *buf, long len) +{ + int i; + assert(stream != NULL); + if (stream->data == NULL) { + stream->data = xmalloc(len); + } else { + stream->data = xrealloc(stream->data, len + stream->length); + } + for (i = 0; i < len; i++) { + *(stream->data + stream->length + i) = *(buf + i); + } + stream->length += len; }; -void pdf_release_obj(pdf_obj *stream) { - if (stream!=NULL) { - if (stream->data!=NULL) { - xfree(stream->data); +void pdf_release_obj(pdf_obj * stream) +{ + if (stream != NULL) { + if (stream->data != NULL) { + xfree(stream->data); + } + xfree(stream); } - xfree(stream); - } }; -void -writetype2 (fd_entry * fd) { - int callback_id; - int file_opened = 0; - char *ftemp = NULL; - - glyph_tab = NULL; - - fd_cur = fd; /* fd_cur is global inside writettf.c */ - assert(fd_cur->fm != NULL); - assert(is_truetype(fd_cur->fm)); - - if (!is_subsetted(fd_cur->fm)) { - writettf(fd); - return; - } - - assert(is_included(fd_cur->fm)); - - set_cur_file_name(fd_cur->fm->ff_name); - ttf_curbyte=0; - ttf_size=0; - callback_id=callback_defined(find_opentype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->S",(char *)(nameoffile+1),&ftemp)) { - if(ftemp!=NULL&&strlen(ftemp)) { - free(nameoffile); - namelength = strlen(ftemp); - nameoffile = xmalloc(namelength+2); - strcpy((char *)(nameoffile+1),ftemp); - free(ftemp); - } +void writetype2(fd_entry * fd) +{ + int callback_id; + int file_opened = 0; + char *ftemp = NULL; + + glyph_tab = NULL; + + fd_cur = fd; /* fd_cur is global inside writettf.c */ + assert(fd_cur->fm != NULL); + assert(is_truetype(fd_cur->fm)); + + if (!is_subsetted(fd_cur->fm)) { + writettf(fd); + return; } - } - callback_id=callback_defined(read_opentype_file_callback); - if (callback_id>0) { - if(run_callback(callback_id,"S->bSd",(char *)(nameoffile+1), - &file_opened, &ttf_buffer,&ttf_size) && - file_opened && ttf_size>0) { + + assert(is_included(fd_cur->fm)); + + set_cur_file_name(fd_cur->fm->ff_name); + ttf_curbyte = 0; + ttf_size = 0; + callback_id = callback_defined(find_opentype_file_callback); + if (callback_id > 0) { + if (run_callback + (callback_id, "S->S", (char *) (nameoffile + 1), &ftemp)) { + if (ftemp != NULL && strlen(ftemp)) { + free(nameoffile); + namelength = strlen(ftemp); + nameoffile = xmalloc(namelength + 2); + strcpy((char *) (nameoffile + 1), ftemp); + free(ftemp); + } + } + } + callback_id = callback_defined(read_opentype_file_callback); + if (callback_id > 0) { + if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1), + &file_opened, &ttf_buffer, &ttf_size) && + file_opened && ttf_size > 0) { + } else { + pdftex_fail("cannot open OpenType font file for reading"); + } } else { - pdftex_fail ("cannot open OpenType font file for reading"); + if (!otf_open()) { + pdftex_fail("cannot open OpenType font file for reading"); + } + ttf_read_file(); + ttf_close(); } - } else { - if (!otf_open ()) { - pdftex_fail ("cannot open OpenType font file for reading"); + + cur_file_name = (char *) nameoffile + 1; + fd_cur->ff_found = true; + + if (tracefilenames) { + if (is_subsetted(fd_cur->fm)) + tex_printf("<%s", cur_file_name); + else + tex_printf("<<%s", cur_file_name); } - ttf_read_file(); - ttf_close(); - } - - cur_file_name = (char *) nameoffile + 1; - fd_cur->ff_found = true; - - if (tracefilenames) { - if (is_subsetted(fd_cur->fm)) - tex_printf ("<%s", cur_file_name); - else - tex_printf ("<<%s", cur_file_name); - } - /* here is the real work */ + /* here is the real work */ - make_tt_subset(fd,ttf_buffer,ttf_size); + make_tt_subset(fd, ttf_buffer, ttf_size); - /*xfree (dir_tab);*/ - if (tracefilenames) { - if (is_subsetted (fd_cur->fm)) - tex_printf (">"); - else - tex_printf (">>"); - } - cur_file_name = NULL; + /*xfree (dir_tab); */ + xfree(ttf_buffer); + if (tracefilenames) { + if (is_subsetted(fd_cur->fm)) + tex_printf(">"); + else + tex_printf(">>"); + } + cur_file_name = NULL; } /* @@ -216,207 +227,216 @@ writetype2 (fd_entry * fd) { * The 'name' table added. See comments in ttf.c. */ -static struct -{ - const char *name; - int must_exist; +static struct { + const char *name; + int must_exist; } required_table[] = { - {"OS/2", 0}, {"head", 1}, {"hhea", 1}, {"loca", 1}, {"maxp", 1}, - {"name", 1}, {"glyf", 1}, {"hmtx", 1}, {"fpgm", 0}, {"cvt ", 0}, - {"prep", 0}, {NULL, 0} + { + "OS/2", 0}, { + "cmap", 0}, { + "head", 1}, { + "hhea", 1}, { + "loca", 1}, { + "maxp", 1}, { + "name", 1}, { + "glyf", 1}, { + "hmtx", 1}, { + "fpgm", 0}, { + "cvt ", 0}, { + "prep", 0}, { + NULL, 0} }; -unsigned long ttc_read_offset (sfnt *sfont, int ttc_idx) +unsigned long ttc_read_offset(sfnt * sfont, int ttc_idx) { - long version; - unsigned long offset = 0; - unsigned long num_dirs = 0; + long version; + unsigned long offset = 0; + unsigned long num_dirs = 0; - sfnt_seek_set (sfont, 4); /* skip version tag */ + sfnt_seek_set(sfont, 4); /* skip version tag */ - version = sfnt_get_ulong(sfont); - num_dirs = sfnt_get_ulong(sfont); - if (ttc_idx < 0 || ttc_idx > num_dirs - 1) { - fprintf(stderr,"Invalid TTC index number\n"); - uexit(1); - } + version = sfnt_get_ulong(sfont); + num_dirs = sfnt_get_ulong(sfont); + if (ttc_idx < 0 || ttc_idx > (int) (num_dirs - 1)) { + fprintf(stderr, "Invalid TTC index number\n"); + uexit(1); + } - sfnt_seek_set (sfont, 12 + ttc_idx * 4); - offset = sfnt_get_ulong (sfont); + sfnt_seek_set(sfont, 12 + ttc_idx * 4); + offset = sfnt_get_ulong(sfont); - return offset; + return offset; } -extern int ff_get_ttc_index(char *ffname, char*psname); - -void make_tt_subset (fd_entry * fd,unsigned char *buffer, integer buflen) { - - long i, cid; - unsigned int last_cid; - glw_entry *glyph, *found; - struct avl_traverser t; - unsigned char *cidtogidmap ; - unsigned short num_glyphs, gid; - struct tt_glyphs *glyphs; - char *used_chars; - sfnt *sfont; - pdf_obj *fontfile; - int verbose = 0, error = 0; - - cidtogidmap = NULL; - - sfont = sfnt_open(buffer, buflen); - - if (sfont->type == SFNT_TYPE_TTC) { - i = ff_get_ttc_index(fd->fm->ff_name,fd->fm->ps_name); - error = sfnt_read_table_directory(sfont, ttc_read_offset(sfont, i)); - } else { - error = sfnt_read_table_directory(sfont, 0); - } +extern int ff_get_ttc_index(char *ffname, char *psname); /* libs/luafontforge/src/luafflib.c */ - if (error < 0) { - fprintf(stderr,"Could not parse the ttf directory.\n"); - uexit(1); - } +void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen) +{ + + long i, cid; + unsigned int last_cid; + glw_entry *found; + struct avl_traverser t; + unsigned char *cidtogidmap; + unsigned short num_glyphs, gid; + struct tt_glyphs *glyphs; + char *used_chars; + sfnt *sfont; + pdf_obj *fontfile; + int verbose = 0, error = 0; + + cidtogidmap = NULL; + + sfont = sfnt_open(buffer, buflen); + + if (sfont->type == SFNT_TYPE_TTC) { + i = ff_get_ttc_index(fd->fm->ff_name, fd->fm->ps_name); + error = sfnt_read_table_directory(sfont, ttc_read_offset(sfont, i)); + } else { + error = sfnt_read_table_directory(sfont, 0); + } - glyphs = tt_build_init(); + if (error < 0) { + fprintf(stderr, "Could not parse the ttf directory.\n"); + uexit(1); + } - last_cid = 0; - num_glyphs = 1; /* .notdef */ + glyphs = tt_build_init(); - glyph = xtalloc(1,glw_entry); + last_cid = 0; + + avl_t_init(&t, fd->gl_tree); + for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); + found != NULL; found = (glw_entry *) avl_t_next(&t)) { + if (found->id > last_cid) + last_cid = found->id; + } - avl_t_init(&t, fd->gl_tree); - for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); - found != NULL; - found = (glw_entry *) avl_t_next(&t)) { - if (found->id > last_cid) - last_cid = found->id; - } - #ifndef NO_GHOSTSCRIPT_BUG - cidtogidmap = NULL; + cidtogidmap = NULL; #else - cidtogidmap = xmalloc(((last_cid + 1) * 2) * sizeof(unsigned char)); - memset(cidtogidmap, 0, (last_cid + 1) * 2); + cidtogidmap = xmalloc(((last_cid + 1) * 2) * sizeof(unsigned char)); + memset(cidtogidmap, 0, (last_cid + 1) * 2); #endif - /* fill used_chars */ - used_chars = xmalloc((last_cid + 1) * sizeof(char)); - memset(used_chars, 0, (last_cid + 1)); - avl_t_init(&t, fd->gl_tree); - for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); - found != NULL; - found = (glw_entry *) avl_t_next(&t)) { - used_chars[found->id] = 1; - } + /* fill used_chars */ + used_chars = xmalloc((last_cid + 1) * sizeof(char)); + memset(used_chars, 0, (last_cid + 1)); + avl_t_init(&t, fd->gl_tree); + for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); + found != NULL; found = (glw_entry *) avl_t_next(&t)) { + used_chars[found->id] = 1; + } - /* - * Map CIDs to GIDs. - */ + /* + * Map CIDs to GIDs. + */ - num_glyphs = 1; /* .notdef */ - for (cid = 1; cid <= last_cid; cid++) { - if (used_chars[cid]==0) - continue; - gid = cid; + num_glyphs = 1; /* .notdef */ + for (cid = 1; cid <= (long) last_cid; cid++) { + if (used_chars[cid] == 0) + continue; + gid = cid; #ifndef NO_GHOSTSCRIPT_BUG - gid = tt_add_glyph(glyphs, gid, cid); + gid = tt_add_glyph(glyphs, gid, cid); #else - gid = tt_add_glyph(glyphs, gid, num_glyphs); - cidtogidmap[2*cid ] = gid >> 8; - cidtogidmap[2*cid+1] = gid & 0xff; -#endif /* !NO_GHOSTSCRIPT_BUG */ - - num_glyphs++; - } + gid = tt_add_glyph(glyphs, gid, num_glyphs); + cidtogidmap[2 * cid] = gid >> 8; + cidtogidmap[2 * cid + 1] = gid & 0xff; +#endif /* !NO_GHOSTSCRIPT_BUG */ - if (num_glyphs==1) { - fprintf(stderr,"No glyphs in subset?.\n"); - uexit(1); - } + num_glyphs++; + } - if (tt_build_tables(sfont, glyphs) < 0) { - fprintf(stderr,"Could not parse the ttf buffer.\n"); - uexit(1); - } - - if (verbose > 1) { - fprintf(stdout,"[%u glyphs (Max CID: %u)]", glyphs->num_glyphs, last_cid); - } + if (num_glyphs == 1) { + fprintf(stderr, "No glyphs in subset?.\n"); + uexit(1); + } - tt_build_finish(glyphs); + if (tt_build_tables(sfont, glyphs) < 0) { + fprintf(stderr, "Could not parse the ttf buffer.\n"); + uexit(1); + } - /* Create font file */ + if (verbose > 1) { + fprintf(stdout, "[%u glyphs (Max CID: %u)]", glyphs->num_glyphs, + last_cid); + } - for (i = 0; required_table[i].name; i++) { - if (sfnt_require_table(sfont, - required_table[i].name, - required_table[i].must_exist) < 0) { - fprintf(stderr,"Some required TrueType table does not exist."); - uexit(1); + tt_build_finish(glyphs); + + /* Create font file */ + + for (i = 0; required_table[i].name; i++) { + if (sfnt_require_table(sfont, + required_table[i].name, + required_table[i].must_exist) < 0) { + fprintf(stderr, "Some required TrueType table does not exist."); + uexit(1); + } } - } - fontfile = sfnt_create_FontFile_stream(sfont); + fontfile = sfnt_create_FontFile_stream(sfont); - if (verbose > 1) { - fprintf(stdout,"[%ld bytes]", fontfile->length); - } + if (verbose > 1) { + fprintf(stdout, "[%ld bytes]", fontfile->length); + } - /* squeeze in the cidgidmap */ - if (cidtogidmap!=NULL) { - cidtogid_obj = pdf_new_objnum(); - pdf_begin_dict(cidtogid_obj, 0); - pdf_printf("/Length %i\n",((last_cid + 1) * 2)); - pdf_end_dict(); - pdf_printf("stream\n"); - pdfroom ((last_cid + 1) * 2); - for (i = 0; i<((last_cid + 1) * 2); i++ ) { - pdf_buf[pdf_ptr++] = cidtogidmap[i]; + /* squeeze in the cidgidmap */ + if (cidtogidmap != NULL) { + cidtogid_obj = pdf_new_objnum(); + pdf_begin_dict(cidtogid_obj, 0); + pdf_printf("/Length %i\n", ((last_cid + 1) * 2)); + pdf_end_dict(); + pdf_printf("stream\n"); + pdfroom((last_cid + 1) * 2); + for (i = 0; i < ((int) (last_cid + 1) * 2); i++) { + pdf_buf[pdf_ptr++] = cidtogidmap[i]; + } + pdf_printf("\nendstream\n"); } - pdf_printf("\nendstream\n"); - } - /* the tff subset */ - for (i = 0; ilength; i++ ) - fb_putchar (fontfile->data[i]); - - - /* other stuff that needs fixing: */ - - /* - * DW, W, DW2, and W2 - */ - /* - if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { - pdf_add_dict(font->fontdict, - pdf_new_name("DW"), pdf_new_number(1000.0)); - } else { - add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); - if (v_used_chars) - add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); - } - */ - - /* - * CIDSet - */ - /* - { - pdf_obj *cidset; - - cidset = pdf_new_stream(STREAM_COMPRESS); - pdf_add_stream(cidset, used_chars, last_cid/8 + 1); - pdf_add_dict(font->descriptor, - pdf_new_name("CIDSet"), - pdf_ref_obj(cidset)); - pdf_release_obj(cidset); - } - */ + /* the tff subset */ + for (i = 0; i < (int) (fontfile->length); i++) + fb_putchar(fontfile->data[i]); - return; + pdf_release_obj(fontfile); + + /* other stuff that needs fixing: */ + + /* + * DW, W, DW2, and W2 + */ + /* + if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + } else { + add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); + if (v_used_chars) + add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); + } + */ + + /* + * CIDSet + */ + /* + { + pdf_obj *cidset; + + cidset = pdf_new_stream(STREAM_COMPRESS); + pdf_add_stream(cidset, used_chars, last_cid/8 + 1); + pdf_add_dict(font->descriptor, + pdf_new_name("CIDSet"), + pdf_ref_obj(cidset)); + pdf_release_obj(cidset); + } + */ + xfree(used_chars); + sfnt_close(sfont); + return; } diff --git a/Build/source/texk/web2c/luatexdir/get_svnversion.sh b/Build/source/texk/web2c/luatexdir/get_svnversion.sh new file mode 100755 index 00000000000..1c544342799 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/get_svnversion.sh @@ -0,0 +1,13 @@ +#!/bin/sh +srcdir=$1 +if [ -e "`which svnversion`" ] && [ -e "`which sed`" ]; then + REV=`svnversion $srcdir | sed 's/^\([0-9]\+\).*/\1/'` + case $REV in *[^0-9]*) + echo unknown + exit 0 + ;; + esac + echo $REV +else + echo unknown +fi \ No newline at end of file diff --git a/Build/source/texk/web2c/luatexdir/hyphen.h b/Build/source/texk/web2c/luatexdir/hyphen.h index f665c7605b9..fa54e8db245 100644 --- a/Build/source/texk/web2c/luatexdir/hyphen.h +++ b/Build/source/texk/web2c/luatexdir/hyphen.h @@ -34,27 +34,28 @@ * */ #ifndef __HYPHEN_H__ -#define __HYPHEN_H__ +# define __HYPHEN_H__ -#ifdef __cplusplus +# ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +# endif /* __cplusplus */ -typedef struct _HyphenDict HyphenDict; + typedef struct _HyphenDict HyphenDict; -#include "ptexlib.h" -#include "nodes.h" +# include "ptexlib.h" +# include "nodes.h" -HyphenDict* hnj_hyphen_new(); -void hnj_hyphen_load(HyphenDict*dict, const unsigned char *fn); -void hnj_hyphen_free (HyphenDict *dict); -void hnj_hyphen_clear (HyphenDict *dict); -void hnj_hyphen_hyphenate (HyphenDict *dict, halfword first, halfword last, int size, halfword left, halfword right, lang_variables*lan); -unsigned char* hnj_serialize(HyphenDict*); -void hnj_free_serialize(unsigned char*); + HyphenDict *hnj_hyphen_new(); + void hnj_hyphen_load(HyphenDict * dict, const unsigned char *fn); + void hnj_hyphen_free(HyphenDict * dict); + void hnj_hyphen_clear(HyphenDict * dict); + void hnj_hyphen_hyphenate(HyphenDict * dict, halfword first, halfword last, + int size, halfword left, halfword right, + lang_variables * lan); + unsigned char *hnj_serialize(HyphenDict *); + void hnj_free_serialize(unsigned char *); -#ifdef __cplusplus +# ifdef __cplusplus } -#endif /* __cplusplus */ - -#endif /* __HYPHEN_H__ */ +# endif /* __cplusplus */ +#endif /* __HYPHEN_H__ */ diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.c b/Build/source/texk/web2c/luatexdir/image/epdf.c index 071181f17bd..05ba93fdcf2 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.c +++ b/Build/source/texk/web2c/luatexdir/image/epdf.c @@ -1,32 +1,32 @@ -/* -Copyright (c) 1996-2002 Han The Thanh, +/* epdf.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: epdf.c 1012 2008-02-14 00:00:57Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "ptexlib.h" - #include #include #include +static const char _svn_version[] = + "$Id: epdf.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/epdf.c $"; + extern void epdf_check_mem(void); extern void register_fd_entry(fd_entry *); @@ -37,7 +37,7 @@ int is_subsetable(fm_entry * fm) return is_subsetted(fm); } -fd_entry *epdf_create_fontdescriptor(fm_entry * fm) +fd_entry *epdf_create_fontdescriptor(fm_entry * fm, int stemV) { fd_entry *fd; if ((fd = lookup_fd_entry(fm->ff_name, fm->slant, fm->extend)) == NULL) { @@ -48,7 +48,9 @@ fd_entry *epdf_create_fontdescriptor(fm_entry * fm) fd->fd_objnum = pdf_new_objnum(); assert(fm->ps_name != NULL); fd->fontname = xstrdup(fm->ps_name); /* just fallback */ - /* preset_fontmetrics (fo->fd, f); */ + // stemV must be copied + fd->font_dim[STEMV_CODE].val = stemV; + fd->font_dim[STEMV_CODE].set = true; fd->gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); assert(fd->gl_tree != NULL); } diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h index 93a9e1c45eb..d079c4c98c4 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.h +++ b/Build/source/texk/web2c/luatexdir/image/epdf.h @@ -1,24 +1,24 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, +/* epdf.h + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ -$Id: epdf.h 1125 2008-03-25 19:36:52Z hhenkel $ -*/ +/* $Id: epdf.h 2073 2009-03-21 10:06:50Z hhenkel $ */ extern "C" { @@ -45,12 +45,13 @@ extern "C" { #include #include "openbsd-compat.h" #include "image.h" -#include "../avlstuff.h" +#include "../utils/avlstuff.h" /* #-define pdfbufsize pdfbufmax */ extern integer epdf_page_box; extern void *epdf_xref; + extern integer epdf_lastGroupObjectNum; extern integer pdf_box_spec_media; extern integer pdf_box_spec_crop; @@ -58,14 +59,15 @@ extern "C" { extern integer pdf_box_spec_trim; extern integer pdf_box_spec_art; - extern integer pdf_stream_length; - extern integer pdf_ptr; + extern longinteger pdf_stream_length; + extern longinteger pdf_ptr; extern integer pool_ptr; typedef unsigned char eight_bits; extern eight_bits *pdf_buf; extern integer pdf_buf_size; extern integer pdf_os_mode; extern eight_bits pdf_last_byte; + extern integer fixed_inclusion_copy_font; extern char notdef[]; @@ -94,6 +96,7 @@ extern "C" { __attribute__ ((format(printf, 1, 2))) extern void tex_printf(const char *, ...); extern void write_epdf(image_dict *); + extern void write_additional_epdf_objects(void); extern void zpdf_begin_dict(integer, bool); extern void zpdf_begin_obj(integer, bool); extern void zpdf_create_obj(integer, integer); @@ -102,7 +105,7 @@ extern "C" { /* epdf.c */ extern void epdf_mark_glyphs(struct fd_entry *, char *); - extern struct fd_entry *epdf_create_fontdescriptor(struct fm_entry *); + extern struct fd_entry *epdf_create_fontdescriptor(struct fm_entry *, int); extern int get_fd_objnum(struct fd_entry *); extern int get_fn_objnum(struct fd_entry *); diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h index 33f09274433..7d9bb8b0e00 100644 --- a/Build/source/texk/web2c/luatexdir/image/image.h +++ b/Build/source/texk/web2c/luatexdir/image/image.h @@ -1,23 +1,24 @@ -/* -Copyright (c) 1996-2002 Han The Thanh, +/* image.h + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: image.h 1125 2008-03-25 19:36:52Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id: image.h 1407 2008-07-15 10:49:28Z taco $ */ #ifndef IMAGE_H # define IMAGE_H @@ -34,6 +35,7 @@ $Id: image.h 1125 2008-03-25 19:36:52Z hhenkel $ extern integer zround(double); /* from zround.c */ # define bp2int(p) zround(p * (one_hundred_bp / 100.0)) +# define int2bp(i) (i * 100.0 / one_hundred_bp) # define TYPE_IMG "image" # define TYPE_IMG_DICT "image-dict" @@ -42,6 +44,10 @@ extern integer zround(double); /* from zround.c */ /**********************************************************************/ +typedef struct { + char *stream; +} pdf_stream_struct; + typedef struct { png_structp png_ptr; png_infop info_ptr; @@ -52,21 +58,21 @@ typedef struct { JPG_UINT32 length; /* length of file/data */ } jpg_img_struct; -#if 0 +# if 0 typedef struct { /* currently unused */ } jb2_img_struct; -#endif +# endif typedef enum { DICT_NEW, /* fresh dictionary */ DICT_FILESCANNED, /* image file scanned */ DICT_REFERED, /* pdf_refximage_node in node list --> read-only dict */ DICT_OUTIMG, /* /Im* appears in pagestream */ - DICT_SCHEDULED, /* image dict scheduled for writing */ + DICT_SCHEDULED, /* image dict scheduled for writing (PONR) */ DICT_WRITTEN /* image dict written to file */ } dict_state; -typedef enum { IMAGE_TYPE_NONE, IMAGE_TYPE_PDF, IMAGE_TYPE_PNG, IMAGE_TYPE_JPG, - IMAGE_TYPE_JBIG2, IMAGE_TYPE_SENTINEL +typedef enum { IMG_TYPE_NONE, IMG_TYPE_PDF, IMG_TYPE_PNG, IMG_TYPE_JPG, + IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_SENTINEL } imgtype_e; typedef enum { IMG_KEEPOPEN, IMG_CLOSEINBETWEEN } img_readtype_e; @@ -87,7 +93,9 @@ typedef struct { integer y_orig; integer x_res; /* pixel resolution as in JPG/PNG/JBIG2 file */ integer y_res; + integer rotation; /* rotation (multiples of 90 deg.) for PDF files */ integer colorspace; /* number of /ColorSpace object */ + integer group_ref; /* if it's <=0, the page has no group */ integer total_pages; integer page_num; /* requested page (by number) */ char *pagename; /* requested page (by name) */ @@ -99,8 +107,11 @@ typedef struct { int color_space; /* used color space. See JPG_ constants */ int color_depth; /* color depth */ pdfboxspec_e page_box_spec; /* PDF page box spec.: media/crop/bleed/trim/art */ + integer bbox[4]; dict_state state; + integer flags; union { + pdf_stream_struct *pdfstream; png_img_struct *png; jpg_img_struct *jpg; /* jb2_img_struct *jb2; */ @@ -115,7 +126,9 @@ typedef struct { # define img_yorig(N) ((N)->y_orig) # define img_xres(N) ((N)->x_res) # define img_yres(N) ((N)->y_res) +# define img_rotation(N) ((N)->rotation) # define img_colorspace(N) ((N)->colorspace) +# define img_group_ref(N) ((N)->group_ref) # define img_totalpages(N) ((N)->total_pages) # define img_pagenum(N) ((N)->page_num) # define img_pagename(N) ((N)->pagename) @@ -127,8 +140,12 @@ typedef struct { # define img_color(N) ((N)->color_space) # define img_colordepth(N) ((N)->color_depth) # define img_pagebox(N) ((N)->page_box_spec) +# define img_bbox(N) ((N)->bbox) # define img_state(N) ((N)->state) +# define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream) +# define img_pdfstream_stream(N) ((N)->img_struct.pdfstream->stream) + # define img_png_ptr(N) ((N)->img_struct.png) # define img_png_png_ptr(N) ((N)->img_struct.png->png_ptr) # define img_png_info_ptr(N) ((N)->img_struct.png->info_ptr) @@ -138,6 +155,12 @@ typedef struct { # define img_jb2_ptr(N) ((N)->img_struct.jb2) +# define F_FLAG_BBOX (1 << 0) + +# define img_set_bbox(N) (img_flags(N) |= F_FLAG_BBOX) +# define img_unset_bbox(N) (img_flags(N) &= ~F_FLAG_BBOX) +# define img_is_bbox(N) ((img_flags(N) & F_FLAG_BBOX) != 0) + /**********************************************************************/ typedef struct { @@ -147,6 +170,7 @@ typedef struct { integer transform; integer flags; image_dict *dict; + int array_idx; /* index within img_array */ int dict_ref; /* luaL_ref() reference */ } image; @@ -156,18 +180,17 @@ typedef struct { # define img_transform(N) ((N)->transform) # define img_flags(N) ((N)->flags) # define img_dict(N) ((N)->dict) +# define img_arrayidx(N) ((N)->array_idx) # define img_dictref(N) ((N)->dict_ref) -# define F_FLAG_SCALED 0x01 -# define F_FLAG_REFERED 0x02 +# define img_is_refered(N) (img_arrayidx(N) != -1) + +# define F_FLAG_SCALED (1 << 0) # define img_flags(N) ((N)->flags) # define img_set_scaled(N) (img_flags(N) |= F_FLAG_SCALED) -# define img_set_refered(N) (img_flags(N) |= F_FLAG_REFERED) # define img_unset_scaled(N) (img_flags(N) &= ~F_FLAG_SCALED) -# define img_unset_refered(N) (img_flags(N) &= ~F_FLAG_REFERED) # define img_is_scaled(N) ((img_flags(N) & F_FLAG_SCALED) != 0) -# define img_is_refered(N) ((img_flags(N) & F_FLAG_REFERED) != 0) # define set_wd_running(N) (img_width(N) = null_flag) # define set_ht_running(N) (img_height(N) = null_flag) @@ -180,6 +203,9 @@ typedef struct { /* writeimg.c */ +void new_img_pdfstream_struct(image_dict *); +void check_pdfstream_dict(image_dict *); +void write_pdfstream(image_dict *); image *new_image(); image_dict *new_image_dict(); void init_image(image *); @@ -206,6 +232,9 @@ void write_jpg(image_dict *); void write_jbig2(image_dict *); void write_epdf(image_dict *); +extern void write_additional_epdf_objects(void); +extern void write_additional_png_objects(void); + /* pdftoepdf.cc */ void unrefPdfDocument(char *); diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc index 81b74369bb9..663e37d073b 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc @@ -1,24 +1,22 @@ -/* -Copyright 1996-2006 Han The Thanh, +/* pdftoepdf.cc + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: pdftoepdf.cc 1129 2008-03-27 19:43:44Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include #include @@ -46,24 +44,14 @@ $Id: pdftoepdf.cc 1129 2008-03-27 19:43:44Z hhenkel $ #include "epdf.h" +static const char _svn_version[] = + "$Id: pdftoepdf.cc 1539 2008-10-06 09:52:07Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/pdftoepdf.cc $"; + #define one_hundred_bp 6578176 /* 7227 * 65536 / 72 */ // This file is mostly C and not very much C++; it's just used to interface // the functions of xpdf, which happens to be written in C++. -// Used flags below: -// PDFTEX_COPY_PAGEGROUP -// If pdfTeX should copy a page group (a new feature in PDF 1.4 for -// transparency) of an included file. The current support for this is -// most likely broken. pdfTeX will at least give a warning if this flag -// is not set. Surprisingly Acrobat and Jaws display files without a -// page group correctly, so it might be safe to not set the flag. -// See also PDFTEX_COPY_PAGEGROUP_NOFAIL. -// PDFTEX_COPY_PAGEGROUP_NOFAIL -// If set to false, pdfTeX will treat a page group in an included file -// as an error and abort gracefully. This is only evaluated if -// PDFTEX_COPY_PAGEGROUP is set. - // The prefix "PTEX" for the PDF keys is special to pdfTeX; // this has been registered with Adobe by Hans Hagen. @@ -75,6 +63,7 @@ $Id: pdftoepdf.cc 1129 2008-03-27 19:43:44Z hhenkel $ // and &obj to get a pointer to the object. // It is no longer necessary to call Object::free explicitely. +/* *INDENT-OFF* */ class PdfObject { public: PdfObject() { // nothing @@ -94,6 +83,7 @@ class PdfObject { public: Object iObject; }; +/* *INDENT-ON* */ // When copying the Resources of the selected page, all objects are copied // recusively top-down. Indirect objects however are not fetched during @@ -123,6 +113,8 @@ static XRef *xref = NULL; static InObj *inObjList = NULL; static UsedEncoding *encodingList; static GBool isInit = gFalse; +static bool groupIsIndirect; +static PdfObject lastGroup; //********************************************************************** // Maintain AVL tree of open embedded PDF files @@ -290,13 +282,28 @@ static void copyName(char *s) pdf_puts("/"); for (; *s != 0; s++) { if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' || - *s == '.' || *s == '-') + *s == '.' || *s == '-' || *s == '+') pdfout(*s); else pdf_printf("#%.2X", *s & 0xFF); } } +static int getNewObjectNumber(Ref ref) +{ + InObj *p; + if (inObjList == 0) { + pdftex_fail("No objects copied yet"); + } else { + for (p = inObjList; p != 0; p = p->next) { + if (p->ref.num == ref.num && p->ref.gen == ref.gen) { + return p->num; + } + } + pdftex_fail("Object not yet copied: %i %i", ref.num, ref.gen); + } +} + static void copyObject(Object *); static void copyDictEntry(Object * obj, int i) @@ -347,9 +354,10 @@ static void copyStream(Stream * str) { int c; str->reset(); - while ((c = str->getChar()) != EOF) + while ((c = str->getChar()) != EOF) { pdfout(c); - pdf_last_byte = pdf_buf[pdf_ptr - 1]; + pdf_last_byte = c; + } } static void copyProcSet(Object * obj) @@ -376,7 +384,7 @@ static void copyProcSet(Object * obj) static void copyFont(char *tag, Object * fontRef) { PdfObject fontdict, subtype, basefont, fontdescRef, fontdesc, charset, - fontfile, ffsubtype; + fontfile, ffsubtype, stemV; GfxFont *gfont; fd_entry *fd; fm_entry *fontmap; @@ -392,7 +400,7 @@ static void copyFont(char *tag, Object * fontRef) } // Only handle included Type1 (and Type1C) fonts; anything else will be copied. // Type1C fonts are replaced by Type1 fonts, if REPLACE_TYPE1C is true. - if (fixed_replace_font && fontRef->fetch(xref, &fontdict)->isDict() + if (!fixed_inclusion_copy_font && fontRef->fetch(xref, &fontdict)->isDict() && fontdict->dictLookup("Subtype", &subtype)->isName() && !strcmp(subtype->getName(), "Type1") && fontdict->dictLookup("BaseFont", &basefont)->isName() @@ -405,7 +413,9 @@ static void copyFont(char *tag, Object * fontRef) &ffsubtype)->isName() && !strcmp(ffsubtype->getName(), "Type1C"))) && (fontmap = lookup_fontmap(basefont->getName())) != NULL) { - fd = epdf_create_fontdescriptor(fontmap); + // copy the value of /StemV + fontdesc->dictLookup("StemV", &stemV); + fd = epdf_create_fontdescriptor(fontmap, stemV->getInt()); if (fontdesc->dictLookup("CharSet", &charset) && charset->isString() && is_subsetable(fontmap)) epdf_mark_glyphs(fd, charset->getString()->getCString()); @@ -579,16 +589,16 @@ static void copyObject(Object * obj) copyDict(&obj1); pdf_puts(">>\n"); pdf_puts("stream\n"); - copyStream(obj->getStream()->getBaseStream()); + copyStream(obj->getStream()->getUndecodedStream()); if (pdf_last_byte != '\n') pdf_puts("\n"); pdf_puts("endstream"); // can't simply write pdf_end_stream() } else if (obj->isRef()) { ref = obj->getRef(); if (ref.num == 0) { - pdftex_warn - ("PDF inclusion: reference to invalid object was replaced by "); - pdf_puts("null"); + pdftex_fail + ("PDF inclusion: reference to invalid object" + " (is the included pdf broken?)"); } else pdf_printf("%d 0 R", addOther(ref)); } else { @@ -633,8 +643,9 @@ static void writeEncodings() for (r = encodingList; r != NULL; r = r->next) { for (i = 0; i < 256; i++) { if (r->font->isCIDFont()) { - pdftex_warn - ("PDF inclusion: CID font included, encoding maybe wrong"); + pdftex_fail + ("PDF inclusion: CID fonts are not supported" + " (try to disable font replacement to fix this)"); } if ((s = ((Gfx8BitFont *) r->font)->getCharName(i)) != NULL) glyphNames[i] = s; @@ -684,10 +695,9 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted, Page *page; int rotate; PDFRectangle *pagebox; - float pdf_version_found, pdf_version_wanted, pdf_width, pdf_height, - pdf_xorig, pdf_yorig; + float pdf_version_found, pdf_version_wanted, xsize, ysize, xorig, yorig; assert(idict != NULL); - assert(img_type(idict) == IMAGE_TYPE_PDF); + assert(img_type(idict) == IMG_TYPE_PDF); // initialize if (isInit == gFalse) { globalParams = new GlobalParams(); @@ -733,49 +743,75 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted, pdftex_fail("PDF inclusion: required page <%i> does not exist", (int) img_pagenum(idict)); } + pdf_doc->xref = pdf_doc->doc->getXRef(); // get the required page page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict)); // get the pagebox (media, crop...) to use. pagebox = get_pagebox(page, img_pagebox(idict)); if (pagebox->x2 > pagebox->x1) { - pdf_xorig = pagebox->x1; - pdf_width = pagebox->x2 - pagebox->x1; + xorig = pagebox->x1; + xsize = pagebox->x2 - pagebox->x1; } else { - pdf_xorig = pagebox->x2; - pdf_width = pagebox->x1 - pagebox->x2; + xorig = pagebox->x2; + xsize = pagebox->x1 - pagebox->x2; } if (pagebox->y2 > pagebox->y1) { - pdf_yorig = pagebox->y1; - pdf_height = pagebox->y2 - pagebox->y1; + yorig = pagebox->y1; + ysize = pagebox->y2 - pagebox->y1; } else { - pdf_yorig = pagebox->y2; - pdf_height = pagebox->y1 - pagebox->y2; + yorig = pagebox->y2; + ysize = pagebox->y1 - pagebox->y2; } - + // The following 4 parameters are raw. Do _not_ modify by /Rotate! + img_xsize(idict) = bp2int(xsize); + img_ysize(idict) = bp2int(ysize); + img_xorig(idict) = bp2int(xorig); + img_yorig(idict) = bp2int(yorig); + + // Handle /Rotate parameter. Only multiples of 90 deg. are allowed + // (PDF Ref. v1.3, p. 78). rotate = page->getRotate(); - // handle page rotation and adjust dimens as needed - if (rotate != 0) { - // handle only the simple case: multiple of 90s. - // these are the only values allowed according to the - // reference (v1.3, p. 78). - // 180 needs no special treatment here - register float f; - switch (rotate % 360) { - case 90: - case 270: - f = pdf_height; - pdf_height = pdf_width; - pdf_width = f; - break; - default:; + switch (((rotate % 360) + 360) % 360) { // handles also neg. angles + case 0: + img_rotation(idict) = 0; + break; + case 90: + img_rotation(idict) = 3; // PDF counts clockwise! + break; + case 180: + img_rotation(idict) = 2; + break; + case 270: + img_rotation(idict) = 1; + break; + default: + pdftex_warn + ("PDF inclusion: " + "/Rotate parameter in PDF file not multiple of 90 degrees."); + } + if (page->getGroup() != NULL) { + initDictFromDict(lastGroup, page->getGroup()); + if (lastGroup->dictGetLength() > 0) { + groupIsIndirect = lastGroup->isRef(); + if (groupIsIndirect) { + // FIXME: Here we already copy the object. It would be + // better to do this only after write_epdf, otherwise we + // may copy ununsed /Group objects + copyObject(&lastGroup); + epdf_lastGroupObjectNum = + getNewObjectNumber(lastGroup->getRef()); + } else { + // make the group an indirect object; copying is done later + // by write_additional_epdf_objects after write_epdf + epdf_lastGroupObjectNum = pdf_new_objnum(); + } + pdf_puts("\n"); } + } else { + epdf_lastGroupObjectNum = 0; } - pdf_doc->xref = pdf_doc->doc->getXRef(); - img_xsize(idict) = bp2int(pdf_width); - img_ysize(idict) = bp2int(pdf_height); - img_xorig(idict) = bp2int(pdf_xorig); - img_yorig(idict) = bp2int(pdf_yorig); + } // Writes the current epf_doc. @@ -786,22 +822,19 @@ static void write_epdf1(image_dict * idict) { Page *page; PdfObject contents, obj1, obj2; - PdfObject group, metadata, pieceinfo, separationInfo; + PdfObject metadata, pieceinfo, separationInfo; Object info; char *key; char s[256]; int i, l; - int rotate; - double scale[6] = { 0, 0, 0, 0, 0, 0 }; - bool writematrix = false; PdfDocument *pdf_doc = (PdfDocument *) findPdfDocument(img_filepath(idict)); assert(pdf_doc != NULL); xref = pdf_doc->xref; inObjList = pdf_doc->inObjList; encodingList = NULL; page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict)); - rotate = page->getRotate(); PDFRectangle *pagebox; + float bbox[4]; // write the Page header pdf_puts("/Type /XObject\n/Subtype /Form\n"); if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) @@ -819,73 +852,35 @@ static void write_epdf1(image_dict * idict) pdf_printf("/%s.InfoDict ", pdfkeyprefix); pdf_printf("%d 0 R\n", addOther(info.getRef())); } - // get the pagebox (media, crop...) to use. - pagebox = get_pagebox(page, img_pagebox(idict)); - - // handle page rotation - if (rotate != 0) { - // this handles only the simple case: multiple of 90s but these - // are the only values allowed according to the reference - // (v1.3, p. 78). - // the image is rotated around its center. - // the /Rotate key is clockwise while the matrix is - // counterclockwise :-% - tex_printf(", page is rotated %d degrees", rotate); - switch (rotate % 360) { - case 90: - scale[1] = -1; - scale[2] = 1; - scale[4] = pagebox->x1 - pagebox->y1; - scale[5] = pagebox->y1 + pagebox->x2; - writematrix = true; - break; - case 180: - scale[0] = scale[3] = -1; - scale[4] = pagebox->x1 + pagebox->x2; - scale[5] = pagebox->y1 + pagebox->y2; - writematrix = true; - break; // width and height are exchanged - case 270: - scale[1] = 1; - scale[2] = -1; - scale[4] = pagebox->x1 + pagebox->y2; - scale[5] = pagebox->y1 - pagebox->x1; - writematrix = true; - break; - default:; - } - if (writematrix) { // The matrix is only written if the image is rotated. - sprintf(s, "/Matrix [%.8f %.8f %.8f %.8f %.8f %.8f]\n", - scale[0], scale[1], scale[2], scale[3], scale[4], scale[5]); - pdf_printf(stripzeros(s)); - } + if (img_is_bbox(idict)) { + bbox[0] = int2bp(img_bbox(idict)[0]); + bbox[1] = int2bp(img_bbox(idict)[1]); + bbox[2] = int2bp(img_bbox(idict)[2]); + bbox[3] = int2bp(img_bbox(idict)[3]); + } else { + // get the pagebox (media, crop...) to use. + pagebox = get_pagebox(page, img_pagebox(idict)); + bbox[0] = pagebox->x1; + bbox[1] = pagebox->y1; + bbox[2] = pagebox->x2; + bbox[3] = pagebox->y2; } - - sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", - pagebox->x1, pagebox->y1, pagebox->x2, pagebox->y2); - pdf_printf(stripzeros(s)); + sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", bbox[0], bbox[1], bbox[2], + bbox[3]); + pdf_puts(stripzeros(s)); + // The /Matrix calculation is replaced by transforms in out_img(). // write the page Group if it's there - if (page->getGroup() != NULL) { -#if PDFTEX_COPY_PAGEGROUP -# if PDFTEX_COPY_PAGEGROUP_NOFAIL - // FIXME: This will most likely produce incorrect PDFs :-( - initDictFromDict(group, page->getGroup()); - if (group->dictGetLength() > 0) { + if (epdf_lastGroupObjectNum > 0) { + if (page->getGroup() != NULL) { + initDictFromDict(lastGroup, page->getGroup()); + if (lastGroup->dictGetLength() > 0) { pdf_puts("/Group "); - copyObject(&group); + groupIsIndirect = lastGroup->isRef(); + pdf_printf("%d 0 R", epdf_lastGroupObjectNum); pdf_puts("\n"); } -# else - // FIXME: currently we don't know how to handle Page Groups so we abort gracefully :-( - pdftex_fail - ("PDF inclusion: Page Group detected which luatex can't handle. Sorry."); -# endif -#else - // FIXME: currently we don't know how to handle Page Groups so we at least give a warning :-( - pdftex_warn - ("PDF inclusion: Page Group detected which luatex can't handle. Ignoring it."); -#endif + } } // write the page Metadata if it's there if (page->getMetadata() != NULL) { @@ -903,6 +898,11 @@ static void write_epdf1(image_dict * idict) pdf_puts("\n"); } } + // copy LastModified (needed when PieceInfo is there) + if (page->getLastModified() != NULL) { + pdf_printf("/LastModified (%s)\n", + page->getLastModified()->getCString()); + } // write the page SeparationInfo if it's there if (page->getSeparationInfo() != NULL) { initDictFromDict(separationInfo, page->getSeparationInfo()); @@ -915,13 +915,10 @@ static void write_epdf1(image_dict * idict) // write the Resources dictionary if (page->getResourceDict() == NULL) { // Resources can be missing (files without them have been spotted - // in the wild). This violates the PDF Ref., which claims they are - // required, but all RIPs accept them. - // We "replace" them with empty /Resources, although in form xobjects - // /Resources are not required. + // in the wild); in which case the /Resouces of the /Page will be used. + // "This practice is not recommended". pdftex_warn - ("PDF inclusion: no /Resources detected. Replacing with empty /Resources."); - pdf_puts("/Resources <<>>\n"); + ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)"); } else { initDictFromDict(obj1, page->getResourceDict()); page->getResourceDict()->incRef(); @@ -944,9 +941,36 @@ static void write_epdf1(image_dict * idict) // write the page contents page->getContents(&contents); if (contents->isStream()) { - initDictFromDict(obj1, contents->streamGetDict()); - contents->streamGetDict()->incRef(); - copyDict(&obj1); + // Variant A: get stream and recompress under control + // of \pdfcompresslevel + // + // pdfbeginstream(); + // copyStream(contents->getStream()); + // pdfendstream(); + + // Variant B: copy stream without recompressing + // + contents->streamGetDict()->lookup("F", &obj1); + if (!obj1->isNull()) { + pdftex_fail("PDF inclusion: Unsupported external stream"); + } + contents->streamGetDict()->lookup("Length", &obj1); + assert(!obj1->isNull()); + pdf_puts("/Length "); + copyObject(&obj1); + pdf_puts("\n"); + contents->streamGetDict()->lookup("Filter", &obj1); + if (!obj1->isNull()) { + pdf_puts("/Filter "); + copyObject(&obj1); + pdf_puts("\n"); + contents->streamGetDict()->lookup("DecodeParms", &obj1); + if (!obj1->isNull()) { + pdf_puts("/DecodeParms "); + copyObject(&obj1); + pdf_puts("\n"); + } + } pdf_puts(">>\nstream\n"); copyStream(contents->getStream()->getBaseStream()); pdf_end_stream(); @@ -1013,3 +1037,14 @@ void epdf_check_mem() delete globalParams; isInit = gFalse; } + +// Called after the xobject generated by write_epdf has been finished; used to +// write out objects that have been made indirect +void write_additional_epdf_objects(void) +{ + if ((epdf_lastGroupObjectNum > 0) && !groupIsIndirect) { + zpdf_begin_obj(epdf_lastGroupObjectNum, 2); + copyObject(&lastGroup); + pdf_end_obj(); + } +} diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.c b/Build/source/texk/web2c/luatexdir/image/writeimg.c index 79c3445945d..b105f507b42 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.c +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.c @@ -1,24 +1,22 @@ -/* -Copyright (c) 1996-2002, 2005 Han The Thanh, +/* writeimg.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. -pdfTeX is free software; -you can redistribute it and / or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writeimg.c 1152 2008-04-13 22:29:59Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include #include "ptexlib.h" @@ -30,8 +28,13 @@ $Id: writeimg.c 1152 2008-04-13 22:29:59Z hhenkel $ #include <../lua51/lua.h> #include <../lua51/lauxlib.h> +static const char _svn_version[] = + "$Id: writeimg.c 2019 2009-03-14 00:15:58Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writeimg.c $"; + extern void pdf_print_real(integer m, integer d); +extern pdfstructure *pstruct; + #define obj_aux(A) obj_tab[(A)].int4 /**********************************************************************/ @@ -104,9 +107,9 @@ extern void pdf_print_real(integer m, integer d); standard extension. Functions "check_type_by_header" and "check_type_by_extension": - img_type(img) is set to IMAGE_TYPE_NONE by new_image_dict(). + img_type(img) is set to IMG_TYPE_NONE by new_image_dict(). Both functions try to detect a type and set img_type(img). - Thus a value other than IMAGE_TYPE_NONE indicates that a + Thus a value other than IMG_TYPE_NONE indicates that a type has been found. */ @@ -116,6 +119,8 @@ extern void pdf_print_real(integer m, integer d); #define HEADER_PDF "%PDF-1." #define MAX_HEADER (sizeof(HEADER_PNG)-1) +integer epdf_lastGroupObjectNum; + static void check_type_by_header(image_dict * idict) { int i; @@ -123,7 +128,7 @@ static void check_type_by_header(image_dict * idict) char header[MAX_HEADER]; assert(idict != NULL); - if (img_type(idict) != IMAGE_TYPE_NONE) /* nothing to do */ + if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ return; /* read the header */ file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); @@ -135,13 +140,13 @@ static void check_type_by_header(image_dict * idict) xfclose(file, img_filepath(idict)); /* tests */ if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0) - img_type(idict) = IMAGE_TYPE_JPG; + img_type(idict) = IMG_TYPE_JPG; else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0) - img_type(idict) = IMAGE_TYPE_PNG; + img_type(idict) = IMG_TYPE_PNG; else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0) - img_type(idict) = IMAGE_TYPE_JBIG2; + img_type(idict) = IMG_TYPE_JBIG2; else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0) - img_type(idict) = IMAGE_TYPE_PDF; + img_type(idict) = IMG_TYPE_PDF; } static void check_type_by_extension(image_dict * idict) @@ -149,21 +154,31 @@ static void check_type_by_extension(image_dict * idict) char *image_suffix; assert(idict != NULL); - if (img_type(idict) != IMAGE_TYPE_NONE) /* nothing to do */ + if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ return; /* tests */ if ((image_suffix = strrchr(img_filename(idict), '.')) == 0) - img_type(idict) = IMAGE_TYPE_NONE; + img_type(idict) = IMG_TYPE_NONE; else if (strcasecmp(image_suffix, ".png") == 0) - img_type(idict) = IMAGE_TYPE_PNG; + img_type(idict) = IMG_TYPE_PNG; else if (strcasecmp(image_suffix, ".jpg") == 0 || strcasecmp(image_suffix, ".jpeg") == 0) - img_type(idict) = IMAGE_TYPE_JPG; + img_type(idict) = IMG_TYPE_JPG; else if (strcasecmp(image_suffix, ".jbig2") == 0 || strcasecmp(image_suffix, ".jb2") == 0) - img_type(idict) = IMAGE_TYPE_JBIG2; + img_type(idict) = IMG_TYPE_JBIG2; else if (strcasecmp(image_suffix, ".pdf") == 0) - img_type(idict) = IMAGE_TYPE_PDF; + img_type(idict) = IMG_TYPE_PDF; +} + +/**********************************************************************/ + +void new_img_pdfstream_struct(image_dict * p) +{ + assert(p != NULL); + assert(img_pdfstream_ptr(p) == NULL); + img_pdfstream_ptr(p) = xtalloc(1, pdf_stream_struct); + img_pdfstream_stream(p) = NULL; } /**********************************************************************/ @@ -176,9 +191,9 @@ void init_image(image * p) set_dp_running(p); img_transform(p) = 0; img_flags(p) = 0; - img_unset_refered(p); /* wd/ht/dp may be modified */ img_unset_scaled(p); img_dict(p) = NULL; + img_arrayidx(p) = -1; /* -1 = unused, used count from 0 */ img_dictref(p) = LUA_NOREF; } @@ -200,7 +215,9 @@ void init_image_dict(image_dict * p) img_yorig(p) = 0; img_xres(p) = 0; img_yres(p) = 0; + img_rotation(p) = 0; img_colorspace(p) = 0; + img_group_ref(p) = 0; img_totalpages(p) = 0; img_pagenum(p) = 1; img_pagename(p) = NULL; @@ -208,10 +225,15 @@ void init_image_dict(image_dict * p) img_filepath(p) = NULL; img_attr(p) = NULL; img_file(p) = NULL; - img_type(p) = IMAGE_TYPE_NONE; + img_type(p) = IMG_TYPE_NONE; img_color(p) = 0; img_colordepth(p) = 0; img_pagebox(p) = PDF_BOX_SPEC_MEDIA; + img_bbox(p)[0] = 0; + img_bbox(p)[1] = 0; + img_bbox(p)[2] = 0; + img_bbox(p)[3] = 0; + img_unset_bbox(p); img_state(p) = DICT_NEW; img_png_ptr(p) = NULL; /* union */ } @@ -240,21 +262,31 @@ void free_dict_strings(image_dict * p) } void free_image_dict(image_dict * p) -{ /* called from limglib.c */ +{ + if (ini_version) + return; /* The image may be \dump{}ed to a format */ + /* called from limglib.c */ assert(img_state(p) < DICT_REFERED); switch (img_type(p)) { - case IMAGE_TYPE_PDF: + case IMG_TYPE_PDF: unrefPdfDocument(img_filepath(p)); break; - case IMAGE_TYPE_PNG: /* assuming IMG_CLOSEINBETWEEN */ + case IMG_TYPE_PNG: /* assuming IMG_CLOSEINBETWEEN */ assert(img_png_ptr(p) == NULL); break; - case IMAGE_TYPE_JPG: /* assuming IMG_CLOSEINBETWEEN */ + case IMG_TYPE_JPG: /* assuming IMG_CLOSEINBETWEEN */ assert(img_jpg_ptr(p) == NULL); break; - case IMAGE_TYPE_JBIG2: /* todo: writejbig2.c cleanup */ + case IMG_TYPE_JBIG2: /* todo: writejbig2.c cleanup */ break; - case IMAGE_TYPE_NONE: + case IMG_TYPE_PDFSTREAM: + if (img_pdfstream_ptr(p) != NULL) { + if (img_pdfstream_stream(p) != NULL) + xfree(img_pdfstream_stream(p)); + xfree(img_pdfstream_ptr(p)); + } + break; + case IMG_TYPE_NONE: break; default: assert(0); @@ -293,21 +325,23 @@ void read_img(image_dict * idict, integer pdf_minor_version, } if (img_filepath(idict) == NULL) pdftex_fail("cannot find image file"); + recorder_record_input(img_filename(idict)); /* type checks */ check_type_by_header(idict); check_type_by_extension(idict); /* read image */ switch (img_type(idict)) { - case IMAGE_TYPE_PDF: + case IMG_TYPE_PDF: read_pdf_info(idict, pdf_minor_version, pdf_inclusion_errorlevel); + img_group_ref(idict) = epdf_lastGroupObjectNum; break; - case IMAGE_TYPE_PNG: + case IMG_TYPE_PNG: read_png_info(idict, IMG_CLOSEINBETWEEN); break; - case IMAGE_TYPE_JPG: + case IMG_TYPE_JPG: read_jpg_info(idict, IMG_CLOSEINBETWEEN); break; - case IMAGE_TYPE_JBIG2: + case IMG_TYPE_JBIG2: if (pdf_minor_version < 4) { pdftex_fail ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", @@ -316,42 +350,56 @@ void read_img(image_dict * idict, integer pdf_minor_version, read_jbig2_info(idict); break; default: - pdftex_fail("internal error: unknown image type"); + pdftex_fail("internal error: unknown image type (2)"); } cur_file_name = NULL; if (img_state(idict) < DICT_FILESCANNED) img_state(idict) = DICT_FILESCANNED; } +// Within scale_img() only image width and height matter; +// the offsets and positioning are not interesting here. +// But one needs rotation info to swap width and height. +// img_rotation() comes from the optional /Rotate key in the PDF file. + void scale_img(image * img) { - integer x, y, xr, yr; /* size and resolution of image */ - scaled w, h; /* indeed size corresponds to image resolution */ + integer x, y, xr, yr, tmp; /* size and resolution of image */ + scaled w = 0, h = 0; /* indeed size corresponds to image resolution */ integer default_res; image_dict *idict; assert(img != NULL); idict = img_dict(img); assert(idict != NULL); - x = img_xsize(idict); /* dimensions, resolutions from image file */ - y = img_ysize(idict); + if ((img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) { + x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */ + y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; + img_xorig(idict) = img_bbox(idict)[0]; + img_yorig(idict) = img_bbox(idict)[1]; + } else { + x = img_xsize(idict); /* dimensions, resolutions from image file */ + y = img_ysize(idict); + } xr = img_xres(idict); yr = img_yres(idict); - if ((img_transform(img) & 1) == 1) { - int tmp = x; + if (x <= 0 || y <= 0 || xr < 0 || yr < 0) + pdftex_fail("ext1: invalid image dimensions"); + if (xr > 65535 || yr > 65535) { + xr = 0; + yr = 0; + pdftex_warn("ext1: too large image resolution ignored"); + } + if (((img_transform(img) - img_rotation(idict)) & 1) == 1) { + tmp = x; x = y; y = tmp; tmp = xr; xr = yr; yr = tmp; } - if (xr > 65535 || yr > 65535) { - xr = 0; - yr = 0; - pdftex_warn("ext1: too large image resolution ignored"); - } - if (x <= 0 || y <= 0 || xr < 0 || yr < 0) - pdftex_fail("ext1: invalid image dimensions"); - if (img_type(idict) == IMAGE_TYPE_PDF) { + if (img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) { w = x; h = y; } else { @@ -410,41 +458,50 @@ void scale_img(image * img) img_set_scaled(img); } -void out_img(image * img, scaled hpos, scaled vpos) +void out_img(image * img, pdfstructure * p, scaledpos * pos) { float a[6]; /* transformation matrix */ float xoff, yoff, tmp; int r; /* number of digits after the decimal point */ - image_dict *idict; + int k; scaled wd, ht, dp; + scaledpos tmppos; + pdffloat cm[6]; + image_dict *idict; + integer groupref; /* added from web for 1.40.8 */ assert(img != 0); idict = img_dict(img); assert(idict != 0); wd = img_width(img); ht = img_height(img); dp = img_depth(img); - if ((img_transform(img) & 1) == 1) { /* 90 deg. or 270 deg. rotated */ - if (ht == -dp) - pdftex_fail("image transform: division by zero (height == -depth)"); - if (wd == 0) - pdftex_fail("image transform: division by zero (width == 0)"); - } + a[0] = a[3] = 1.0e6; a[1] = a[2] = 0; - if (img_type(idict) == IMAGE_TYPE_PDF) { - a[0] = 1.0e6 / img_xsize(idict); - a[3] = 1.0e6 / img_ysize(idict); + if (img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) { + a[0] /= img_xsize(idict); + a[3] /= img_ysize(idict); + xoff = (float) img_xorig(idict) / img_xsize(idict); + yoff = (float) img_yorig(idict) / img_ysize(idict); r = 6; } else { - a[3] = a[0] = 1.0e6 / one_hundred_bp; + /* added from web for 1.40.8 */ + if (img_type(idict) == IMG_TYPE_PNG) { + groupref = img_group_ref(idict); + if ((groupref > 0) && (pdf_page_group_val < 1)) + pdf_page_group_val = groupref; + } + /* /added from web */ + a[0] /= one_hundred_bp; + a[3] = a[0]; + xoff = yoff = 0; r = 4; } - xoff = (float) img_xorig(idict) / img_xsize(idict); - yoff = (float) img_yorig(idict) / img_ysize(idict); - if ((img_transform(img) & 7) > 3) { /* mirrored */ + if ((img_transform(img) & 7) > 3) { // mirror cases a[0] *= -1; xoff *= -1; } - switch (img_transform(img) & 3) { + switch ((img_transform(img) + img_rotation(idict)) & 3) { case 0: /* no transform */ break; case 1: /* rot. 90 deg. (counterclockwise) */ @@ -477,41 +534,42 @@ void out_img(image * img, scaled hpos, scaled vpos) a[1] *= ht + dp; a[2] *= wd; a[3] *= ht + dp; - a[4] = hpos - xoff; - a[5] = vpos - yoff; - switch (img_transform(img) & 7) { + a[4] = pos->h - xoff; + a[5] = pos->v - yoff; + k = img_transform(img) + img_rotation(idict); + if ((img_transform(img) & 7) > 3) + k++; + switch (k & 3) { case 0: /* no transform */ - case 7: /* mirrored, then rot. 270 deg. */ break; case 1: /* rot. 90 deg. (counterclockwise) */ - case 4: /* mirrored, unrotated */ a[4] += wd; break; case 2: /* rot. 180 deg. */ - case 5: /* mirrored, then rot. 90 deg. */ a[4] += wd; a[5] += ht + dp; break; case 3: /* rot. 270 deg. */ - case 6: /* mirrored, then rot. 180 deg. */ a[5] += ht + dp; break; default:; } - pdf_end_text(); + /* the following is a kludge, TODO: use pdfpage.c functions */ + setpdffloat(cm[0], round(a[0]), r); + setpdffloat(cm[1], round(a[1]), r); + setpdffloat(cm[2], round(a[2]), r); + setpdffloat(cm[3], round(a[3]), r); + tmppos.h = round(a[4]); + tmppos.v = round(a[5]); + (void) calc_pdfpos(p, &tmppos); + cm[4] = p->cm[4]; + cm[5] = p->cm[5]; + pdf_goto_pagemode(); + if (pdf_page_group_val < 1) + pdf_page_group_val = img_group_ref(idict); /* added from web for 1.40.8 */ pdf_printf("q\n"); - pdf_print_real((integer) a[0], r); - pdfout(' '); - pdf_print_real((integer) a[1], r); - pdfout(' '); - pdf_print_real((integer) a[2], r); - pdfout(' '); - pdf_print_real((integer) a[3], r); - pdfout(' '); - pdf_print_bp((integer) a[4]); - pdfout(' '); - pdf_print_bp((integer) a[5]); - pdf_printf(" cm\n/Im"); + pdf_print_cm(cm); + pdf_printf("/Im"); pdf_print_int(img_index(idict)); pdf_print_resname_prefix(); pdf_printf(" Do\nQ\n"); @@ -526,23 +584,34 @@ void write_img(image_dict * idict) if (tracefilenames) tex_printf(" <%s", img_filepath(idict)); switch (img_type(idict)) { - case IMAGE_TYPE_PNG: + case IMG_TYPE_PNG: write_png(idict); break; - case IMAGE_TYPE_JPG: + case IMG_TYPE_JPG: write_jpg(idict); break; - case IMAGE_TYPE_JBIG2: + case IMG_TYPE_JBIG2: write_jbig2(idict); break; - case IMAGE_TYPE_PDF: + case IMG_TYPE_PDF: write_epdf(idict); + epdf_lastGroupObjectNum = img_group_ref(idict); + break; + case IMG_TYPE_PDFSTREAM: + write_pdfstream(idict); break; default: - pdftex_fail("internal error: unknown image type"); + pdftex_fail("internal error: unknown image type (1)"); } if (tracefilenames) tex_printf(">"); + if (img_type(idict) == IMG_TYPE_PDF) { + write_additional_epdf_objects(); + } else { + if (img_type(idict) == IMG_TYPE_PNG) { + write_additional_png_objects(); + } + } } if (img_state(idict) < DICT_WRITTEN) img_state(idict) = DICT_WRITTEN; @@ -550,9 +619,41 @@ void write_img(image_dict * idict) /**********************************************************************/ +void check_pdfstream_dict(image_dict * idict) +{ + if (!img_is_bbox(idict)) + pdftex_fail("image.stream: no bbox given"); + if (img_state(idict) < DICT_FILESCANNED) + img_state(idict) = DICT_FILESCANNED; +} + +void write_pdfstream(image_dict * idict) +{ + char s[256]; + assert(img_pdfstream_ptr(idict) != NULL); + assert(img_is_bbox(idict)); + pdf_puts("/Type /XObject\n/Subtype /Form\n"); + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) + pdf_printf("%s\n", img_attr(idict)); + pdf_puts("/FormType 1\n"); + sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", int2bp(img_bbox(idict)[0]), + int2bp(img_bbox(idict)[1]), int2bp(img_bbox(idict)[2]), + int2bp(img_bbox(idict)[3])); + pdf_printf(stripzeros(s)); + pdf_begin_stream(); + if (img_pdfstream_stream(idict) != NULL) + pdf_puts(img_pdfstream_stream(idict)); + pdf_end_stream(); +} + +/**********************************************************************/ + typedef image *img_entry; /* define img_ptr, img_array, & img_limit */ -define_array(img); /* array of pointers to image structures */ +/* avoid use of size_t */ +img_entry *img_ptr, *img_array = NULL; +integer img_limit; + integer img_to_array(image * img) { @@ -562,20 +663,168 @@ integer img_to_array(image * img) return img_ptr++ - img_array; /* now img is read-only */ } + + +/**********************************************************************/ + +/* To allow the use of \pdfrefximage inside saved boxes in -ini mode, + * the information in the array has to be (un)dumped with the format. + * The next two routines take care of that. + * + * Most of the work involved in setting up the images is simply + * executed again. This solves the many possible errors resulting from + * the split in two separate runs. + + * There was only one problem remaining: The pdfversion and + * pdfinclusionerrorlevel can have changed inbetween the call to + * readimage() and dump time. That is why they are passed as arguments + * to undumpimagemeta once more. + */ + +/* some of the dumped values are really type int, not integer, + * but since the macro falls back to generic_dump anyway, that + * does not matter. + */ + +#define dumpinteger generic_dump +#define undumpinteger generic_undump + +/* (un)dumping a string means dumping the allocation size, followed + * by the bytes. The trailing \0 is dumped as well, because that + * makes the code simpler. + */ + +#define dumpcharptr(a) \ + do { \ + integer x; \ + if (a!=NULL) { \ + x = strlen(a)+1; \ + dumpinteger(x); dump_things(*a, x); \ + } else { \ + x = 0; dumpinteger(x); \ + } \ + } while (0) + +#define undumpcharptr(s) \ + do { \ + integer x; \ + char *a; \ + undumpinteger (x); \ + if (x>0) { \ + a = malloc(x); \ + undump_things(*a,x); \ + s = a ; \ + } else { s = NULL; } \ + } while (0) + + + +void dumpimagemeta(void) +{ + int cur_image, i; + image *img; + image_dict *idict; + + dumpinteger(img_limit); + cur_image = (img_ptr - img_array); + dumpinteger(cur_image); + + for (i = 0; i < cur_image; i++) { + img = img_array[i]; + assert(img != NULL); + idict = img_dict(img); + dumpcharptr(img_filename(idict)); + dumpinteger(img_type(idict)); + dumpinteger(img_color(idict)); + dumpinteger(img_width(img)); + dumpinteger(img_height(img)); + dumpinteger(img_xres(idict)); + dumpinteger(img_yres(idict)); + dumpinteger(img_totalpages(idict)); + dumpinteger(img_colorspace(idict)); + dumpinteger(img_group_ref(idict)); + + /* the image_struct is not dumped at all, except for a few + variables that are needed to restore the contents */ + + if (img_type(idict) == IMG_TYPE_PDF) { + dumpinteger(img_pagebox(idict)); + dumpinteger(img_pagenum(idict)); + } else if (img_type(idict) == IMG_TYPE_JBIG2) { + dumpinteger(img_pagenum(idict)); + } + + } +} + +void undumpimagemeta(integer pdfversion, integer pdfinclusionerrorlevel) +{ + int cur_image, i; + image *img; + image_dict *idict; + + undumpinteger(img_limit); + + img_array = xtalloc(img_limit, img_entry); + undumpinteger(cur_image); + img_ptr = img_array + cur_image; + + for (i = 0; i < cur_image; i++) { + img = new_image(); + assert(img_arrayidx(img) == -1); + img_arrayidx(img) = img_to_array(img); + idict = img_dict(img) = new_image_dict(); + assert(idict != NULL); + undumpcharptr(img_filename(idict)); + undumpinteger(img_type(idict)); + undumpinteger(img_color(idict)); + undumpinteger(img_width(img)); + undumpinteger(img_height(img)); + undumpinteger(img_xres(idict)); + undumpinteger(img_yres(idict)); + undumpinteger(img_totalpages(idict)); + undumpinteger(img_colorspace(idict)); + undumpinteger(img_group_ref(idict)); + + switch (img_type(idict)) { + case IMG_TYPE_PDF: + undumpinteger(img_pagebox(idict)); + undumpinteger(img_pagenum(idict)); + break; + case IMG_TYPE_PNG: + break; + case IMG_TYPE_JPG: + break; + case IMG_TYPE_JBIG2: + if (pdfversion < 4) { + pdftex_fail + ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", + (int) pdfversion); + } + undumpinteger(img_pagenum(idict)); + break; + default: + pdftex_fail("unknown type of image"); + } + read_img(idict, pdfversion, pdfinclusionerrorlevel); + } +} + + + + /**********************************************************************/ /* stuff to be accessible from TeX */ integer read_image(integer objnum, integer index, strnumber filename, - integer page_num, - strnumber attr, - strnumber page_name, + integer page_num, strnumber page_name, strnumber attr, integer colorspace, integer page_box, integer pdf_minor_version, integer pdf_inclusion_errorlevel) { - integer ref; - image *a = new_image(); image_dict *idict; - ref = img_to_array(a); + image *a = new_image(); + assert(img_arrayidx(a) == -1); + img_arrayidx(a) = img_to_array(a); idict = img_dict(a) = new_image_dict(); assert(idict != NULL); img_objnum(idict) = objnum; @@ -594,8 +843,7 @@ integer read_image(integer objnum, integer index, strnumber filename, img_pagebox(idict) = page_box; read_img(idict, pdf_minor_version, pdf_inclusion_errorlevel); img_unset_scaled(a); - img_set_refered(a); - return ref; + return img_arrayidx(a); } void set_image_dimensions(integer ref, integer wd, integer ht, integer dp) @@ -613,8 +861,11 @@ void scale_image(integer ref) void out_image(integer ref, scaled hpos, scaled vpos) { + scaledpos pos; + pos.h = hpos; + pos.v = vpos; image *a = img_array[ref]; - out_img(a, hpos, vpos); + out_img(a, pstruct, &pos); } void write_image(integer ref) @@ -632,6 +883,24 @@ integer image_colordepth(integer ref) return img_colordepth(img_dict(img_array[ref])); } +integer image_group_ref(integer ref) +{ + return img_group_ref(img_dict(img_array[ref])); +} + + +/* The following five functions are for \pdfximagebbox */ + +integer epdf_xsize(integer ref) +{ + return img_xsize(img_dict(img_array[ref])); +} + +integer epdf_ysize(integer ref) +{ + return img_ysize(img_dict(img_array[ref])); +} + integer epdf_orig_x(integer ref) { return img_xorig(img_dict(img_array[ref])); @@ -642,6 +911,17 @@ integer epdf_orig_y(integer ref) return img_yorig(img_dict(img_array[ref])); } +boolean is_pdf_image(integer ref) +{ + return img_type(img_dict(img_array[ref])) == IMG_TYPE_PDF; +} + +boolean is_png_image(integer ref) +{ + return img_type(img_dict(img_array[ref])) == IMG_TYPE_PNG; +} + + integer image_objnum(integer ref) { return img_objnum(img_dict(img_array[ref])); diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.c b/Build/source/texk/web2c/luatexdir/image/writejbig2.c index 2d7d4560548..c2f01d1bfca 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.c +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.c @@ -1,21 +1,24 @@ -/*********************************************************************** -Copyright (c) 2002-2006 Han The Thanh, +/* writejbig2.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. -This file is part of pdfTeX. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -pdfTeX is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ -You should have received a copy of the GNU General Public License along -with pdfTeX; if not, write to the Free Software Foundation, Inc., 59 -Temple Place, Suite 330, Boston, MA 02111-1307 USA +/*********************************************************************** This is experimental JBIG2 image support to pdfTeX. JBIG2 image decoding is part of Adobe PDF-1.4, and requires Acroread 5.0 or later. @@ -75,10 +78,13 @@ object exists, reference it. Else create fresh one. 09 Dec. 2002: JBIG2 seg. page numbers > 0 are now set to 1, see PDF Ref. -$Id: writejbig2.c 1127 2008-03-25 21:32:54Z hhenkel $ ***********************************************************************/ #include "writejbig2.h" + +static const char _svn_version[] = + "$Id: writejbig2.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writejbig2.c $"; + #undef DEBUG /**********************************************************************/ @@ -292,7 +298,7 @@ void readfilehdr(FILEINFO * fip) fip->sequentialaccess = (fip->filehdrflags & 0x01) ? true : false; if (fip->sequentialaccess) { /* Annex D.1 vs. Annex D.2 */ xfseek(fip->file, 0, SEEK_END, fip->filepath); - fip->filesize = xftell(fip->file, fip->filepath); + fip->filesize = (long) xftello(fip->file, fip->filepath); xfseek(fip->file, 9, SEEK_SET, fip->filepath); } /* Annex D.4.3 Number of pages */ @@ -363,7 +369,7 @@ boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->segpage = ygetc(fip->file); /* 7.2.7 Segment data length */ sip->segdatalen = read4bytes(fip->file); - sip->hdrend = xftell(fip->file, fip->filepath); + sip->hdrend = (long) xftello(fip->file, fip->filepath); /* ---- at end of segment header ---- */ return true; } @@ -583,7 +589,7 @@ void rd_jbig2_info(FILEINFO * fip) sip->dataend = sip->datastart + sip->segdatalen; if (!fip->sequentialaccess && (sip->pageinfoflag || sip->endofstripeflag)) - xfseek(fip->file, sip->datastart, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath); seekdist = sip->segdatalen; /* 7.4.8 Page information segment syntax */ if (sip->pageinfoflag) { @@ -603,11 +609,11 @@ void rd_jbig2_info(FILEINFO * fip) } if (!fip->sequentialaccess && (sip->pageinfoflag || sip->endofstripeflag)) - xfseek(fip->file, sip->hdrend, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->hdrend, SEEK_SET, fip->filepath); if (!fip->sequentialaccess) streampos += sip->segdatalen; if (fip->sequentialaccess) - xfseek(fip->file, seekdist, SEEK_CUR, fip->filepath); + xfseeko(fip->file, seekdist, SEEK_CUR, fip->filepath); if (sip->endofpageflag && currentpage && (pip->stripinginfo >> 15)) pip->height = pip->stripedheight; } @@ -655,10 +661,10 @@ void wr_jbig2(FILEINFO * fip, unsigned long page) for (slip = pip->segments.first; slip != NULL; slip = slip->next) { /* loop over page segments */ sip = slip->d; if (sip->isrefered || page > 0) { - xfseek(fip->file, sip->hdrstart, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->hdrstart, SEEK_SET, fip->filepath); /* mark refered-to page 0 segments, change segpages > 1 to 1 */ writeseghdr(fip, sip); - xfseek(fip->file, sip->datastart, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath); for (i = sip->datastart; i < sip->dataend; i++) pdfout(ygetc(fip->file)); } @@ -675,7 +681,7 @@ void read_jbig2_info(image_dict * idict) PAGEINFO *pip; void **aa; assert(idict != NULL); - img_type(idict) = IMAGE_TYPE_JBIG2; + img_type(idict) = IMG_TYPE_JBIG2; if (img_pagenum(idict) < 1) pdftex_fail ("read_jbig2_info(): page %d not in JBIG2 image file; page must be > 0", diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.h b/Build/source/texk/web2c/luatexdir/image/writejbig2.h index c1bec32d859..5bc91920889 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.h +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.h @@ -1,26 +1,28 @@ -/*********************************************************************** -Copyright (c) 2002-2006 Han The Thanh, +/* writejbig2.h + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License along -with pdfTeX; if not, write to the Free Software Foundation, Inc., 59 -Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ +/*********************************************************************** This is experimental JBIG2 image support to pdfTeX. JBIG2 image decoding is part of Adobe PDF-1.4, and requires Acroread 5.0 or later. -$Id: writejbig2.h 1012 2008-02-14 00:00:57Z oneiros $ +$Id: writejbig2.h 1224 2008-05-02 15:26:27Z oneiros $ ***********************************************************************/ #include diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.c b/Build/source/texk/web2c/luatexdir/image/writejpg.c index 422c29470fb..8e439c76ca5 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.c +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.c @@ -1,28 +1,30 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, +/* writejpg.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writejpg.c 1100 2008-03-09 13:40:48Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include #include "ptexlib.h" #include "image.h" +static const char _svn_version[] = + "$Id: writejpg.c 1224 2008-05-02 15:26:27Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writejpg.c $"; + #define JPG_GRAY 1 /* Gray color space, use /DeviceGray */ #define JPG_RGB 3 /* RGB color space, use /DeviceRGB */ #define JPG_CMYK 4 /* CMYK color space, use /DeviceCMYK */ @@ -117,7 +119,7 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype) int i, units = 0; unsigned char jpg_id[] = "JFIF"; assert(idict != NULL); - assert(img_type(idict) == IMAGE_TYPE_JPG); + assert(img_type(idict) == IMG_TYPE_JPG); img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.c b/Build/source/texk/web2c/luatexdir/image/writepng.c index d431b3b7ed1..1981d002218 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.c +++ b/Build/source/texk/web2c/luatexdir/image/writepng.c @@ -1,29 +1,32 @@ -/* -Copyright (c) 1996-2004 Han The Thanh, - -This file is part of pdfTeX. +/* writepng.c + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writepng.c 1101 2008-03-09 16:12:15Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include #include "ptexlib.h" #include "image.h" +static const char _svn_version[] = + "$Id: writepng.c 2029 2009-03-14 19:10:25Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writepng.c $"; + +static int transparent_page_group = -1; + void close_and_cleanup_png(image_dict * idict) { assert(idict != NULL); @@ -44,7 +47,7 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) png_structp png_p; png_infop info_p; assert(idict != NULL); - assert(img_type(idict) == IMAGE_TYPE_PNG); + assert(img_type(idict) == IMG_TYPE_PNG); img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; @@ -120,7 +123,7 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) #define write_gray_pixel_8(r) \ if (j % 2 == 0) pdf_buf[pdf_ptr++] = *r++; \ - else smask[smask_ptr++] = *r++ + else smask[smask_ptr++] = *r++ #define write_rgb_pixel_16(r) \ @@ -139,27 +142,27 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) r = row; \ k = info_p->rowbytes; \ while(k > 0) { \ - l = (k > pdf_buf_size)? pdf_buf_size : k; \ - pdfroom(l); \ - for (j = 0; j < l; j++) { \ - outmac; \ - } \ - k -= l; \ - } \ + l = (k > pdf_buf_size)? pdf_buf_size : k; \ + pdfroom(l); \ + for (j = 0; j < l; j++) { \ + outmac; \ + } \ + k -= l; \ + } \ } #define write_interlaced(outmac) \ for (i = 0; (unsigned) i < (int)info_p->height; i++) { \ row = rows[i]; \ - k = info_p->rowbytes; \ - while(k > 0) { \ - l = (k > pdf_buf_size)? pdf_buf_size : k;\ - pdfroom(l); \ - for (j = 0; j < l; j++) { \ - outmac; \ - } \ - k -= l; \ - } \ + k = info_p->rowbytes; \ + while(k > 0) { \ + l = (k > pdf_buf_size)? pdf_buf_size : k;\ + pdfroom(l); \ + for (j = 0; j < l; j++) { \ + outmac; \ + } \ + k -= l; \ + } \ xfree(rows[i]); \ } @@ -389,7 +392,7 @@ void write_png_rgb_alpha(image_dict * idict) bitdepth = (int) info_p->bit_depth; pdf_begin_dict(smask_objnum, 0); pdf_puts("/Type /XObject\n/Subtype /Image\n"); - if (img_attr(idict) != NULL) + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) pdf_printf("%s\n", img_attr(idict)); pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n", (int) info_p->width, @@ -460,14 +463,15 @@ void copy_png(image_dict * idict) pdftex_fail("writepng: fseek in PNG file failed"); } } while (endflag == false); - pdf_printf("/Length %d\n", streamlength); - pdf_printf("/Filter /FlateDecode\n"); - pdf_printf("/DecodeParms << "); - pdf_printf("/Colors %d ", info_p->color_type == 2 ? 3 : 1); - pdf_printf("/Columns %d ", (int) info_p->width); - pdf_printf("/BitsPerComponent %i ", (int) info_p->bit_depth); - pdf_printf("/Predictor %d ", 10); /* actual predictor defined on line basis */ - pdf_printf(">>\n>>\nstream\n"); + pdf_printf("/Length %d\n" + "/Filter/FlateDecode\n" + "/DecodeParms<<" + "/Colors %d" + "/Columns %d" + "/BitsPerComponent %i" + "/Predictor 10>>\n>>\nstream\n", streamlength, + info_p->color_type == 2 ? 3 : 1, + (int) info_p->width, info_p->bit_depth); /* 2nd pass to copy data */ endflag = false; if (fseek(fp, 8, SEEK_SET) != 0) @@ -516,6 +520,8 @@ void reopen_png(image_dict * idict) pdftex_fail("writepng: image dimensions have changed"); } +static boolean last_png_needs_page_group; + void write_png(image_dict * idict) { double gamma, checked_gamma; @@ -524,6 +530,7 @@ void write_png(image_dict * idict) png_structp png_p; png_infop info_p; assert(idict != NULL); + last_png_needs_page_group = false; if (img_file(idict) == NULL) reopen_png(idict); assert(img_png_ptr(idict) != NULL); @@ -616,18 +623,20 @@ void write_png(image_dict * idict) write_png_gray(idict); break; case PNG_COLOR_TYPE_GRAY_ALPHA: - if (fixed_pdf_minor_version >= 4) + if (fixed_pdf_minor_version >= 4) { write_png_gray_alpha(idict); - else + last_png_needs_page_group = true; + } else write_png_gray(idict); break; case PNG_COLOR_TYPE_RGB: write_png_rgb(idict); break; case PNG_COLOR_TYPE_RGB_ALPHA: - if (fixed_pdf_minor_version >= 4) + if (fixed_pdf_minor_version >= 4) { write_png_rgb_alpha(idict); - else + last_png_needs_page_group = true; + } else write_png_rgb(idict); break; default: @@ -638,3 +647,27 @@ void write_png(image_dict * idict) pdf_flush(); close_and_cleanup_png(idict); } + + + +static boolean transparent_page_group_was_written = false; + +/* Called after the xobject generated by write_png has been finished; used to + * write out additional objects */ +void write_additional_png_objects(void) +{ + return; /* this interferes with current macro-based usage and cannot be configured */ + if (last_png_needs_page_group) { + if (!transparent_page_group_was_written && transparent_page_group > 1) { + /* create new group object */ + transparent_page_group_was_written = true; + pdf_begin_obj(transparent_page_group, 2); + if (get_pdf_compress_level() == 0) { + pdf_puts("%PTEX Group needed for transparent pngs\n"); + } + pdf_puts + ("<>\n"); + pdf_end_obj(); + } + } +} diff --git a/Build/source/texk/web2c/luatexdir/lang/hyphen.c b/Build/source/texk/web2c/luatexdir/lang/hyphen.c index 049210d3d71..56d745809ae 100644 --- a/Build/source/texk/web2c/luatexdir/lang/hyphen.c +++ b/Build/source/texk/web2c/luatexdir/lang/hyphen.c @@ -53,6 +53,9 @@ #include "hnjalloc.h" #include "hyphen.h" +static const char _svn_version[] = + "$Id: hyphen.c 1696 2008-12-28 21:02:34Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $"; + /* SHOULD BE MOVED TO SEPARATE LIBRARY */ static unsigned char * hnj_strdup( const unsigned char *s @@ -283,7 +286,15 @@ static void hyppat_insert( i = hnj_string_hash (key) % HASH_SIZE; for (e = hashtab->entries[i]; e; e=e->next) { if (strcmp((char*)e->key,(char*)key)==0) { - if (e->u.hyppat) hnj_free(e->u.hyppat); + if (e->u.hyppat) { + if (hyppat && strcmp((char*)e->u.hyppat,(char*)hyppat)!=0) { + int s = maketexstring("Conflicting pattern ignored"); + do_print_err(s); + error(); + flush_str(s); + } + hnj_free(e->u.hyppat); + } e->u.hyppat = hyppat; hnj_free(key); return; @@ -418,7 +429,7 @@ static const unsigned char* next_pattern( size_t* length, const unsigned char **buf ) { - const unsigned char *rover = *buf, *here; + const unsigned char *here, *rover = *buf; while (*rover && isspace(*rover)) rover++; here = rover; while (*rover) { @@ -598,10 +609,10 @@ void hnj_hyphen_load( const unsigned char* format; const unsigned char* begin = f; + unsigned char *pat; + char *org; while((format = next_pattern(&l,&f))!=NULL) { int i,j,e; - unsigned char *pat; - char *org; /* printf("%s\n",format); char* repl = strnchr(format, '/',l); @@ -630,10 +641,11 @@ void hnj_hyphen_load( if (is_utf8_follow(format[i])) e++; } /* l-e => number of _characters_ not _bytes_*/ + /* l-j => number of pattern bytes */ /* l-e-j => number of pattern characters*/ pat = (unsigned char*) malloc(1+l-j); org = ( char*) malloc(2+l-e-j); - /* remove hyphenation encoders (digits) from pat*/ + /* remove hyphenation encoders (digits) from pat*/ org[0] = '0'; for (i=0,j=0,e=0; (unsigned)ipatterns,word+i,j))!=NULL) { char* newpat_pat; if ((newpat_pat = hyppat_lookup(dict->merged,word,l))==NULL) { + char *neworg; unsigned char *newword=(unsigned char*)malloc(l+1); int e=0; - char *neworg; strncpy((char*)newword, (char*)word,l); newword[l]=0; for (i=0; i=0x80) { - int i=1, m; + int m; + int i=1; while (is_utf8_follow(word[j-i])) i++; ch = word[j-i] & mask[i]; m = j-i; @@ -757,14 +770,14 @@ void hnj_hyphen_hyphenate( halfword right, lang_variables *lan ) { + int char_num; + halfword here; + int state = 0; /* +2 for dots at each end, +1 for points /outside/ characters*/ int ext_word_len = length+2; int hyphen_len = ext_word_len+1; /*char *hyphens = hnj_malloc((hyphen_len*2)+1); */ /* LATER */ char *hyphens = hnj_malloc(hyphen_len+1); - int char_num; - int state = 0; - halfword here; /* Add a '.' to beginning and end to facilitate matching*/ set_vlink(begin_point,first); @@ -780,18 +793,21 @@ void hnj_hyphen_hyphenate( hyphens[hyphen_len] = 0; /* now, run the finite state machine */ - for (char_num=0, here=begin_point; here!=end_point; here=get_vlink(here)) { - - int ch = get_lc_code(get_character(here)); + for (char_num=0, here=begin_point; here!=get_vlink(end_point); here=get_vlink(here)) { + int ch; + if (here == begin_point || here == end_point) + ch='.'; + else + ch = get_lc_code(get_character(here)); while (state!=-1) { /* printf("%*s%s%c",char_num-strlen(get_state_str(state)),"",get_state_str(state),(char)ch);*/ HyphenState *hstate = &dict->states[state]; int k; for (k = 0; k < hstate->num_trans; k++) { if (hstate->trans[k].uni_ch == ch) { - char *match; - state = hstate->trans[k].new_state; + char *match; + state = hstate->trans[k].new_state; /* printf(" state %d\n",state);*/ match = dict->states[state].match; if (match) { diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.c b/Build/source/texk/web2c/luatexdir/lang/texlang.c index 1f847f5c643..c37350f146f 100644 --- a/Build/source/texk/web2c/luatexdir/lang/texlang.c +++ b/Build/source/texk/web2c/luatexdir/lang/texlang.c @@ -1,24 +1,21 @@ -/* -Copyright (c) 2007 Taco Hoekwater +/* texlang.c + + Copyright 2006-2008 Taco Hoekwater -This file is part of luatex. + This file is part of LuaTeX. -luatex is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -luatex is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with luatex; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -This is texlang.c -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include @@ -26,464 +23,648 @@ This is texlang.c #include #include "nodes.h" +#include "font/texfont.h" #include "hyphen.h" +static const char _svn_version[] = + "$Id: texlang.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $"; + /* functions from the fontforge unicode library */ -extern unsigned int *utf82u_strcpy(unsigned int *ubuf,const char *utf8buf); +#if 0 +extern unsigned int *utf82u_strcpy(unsigned int *ubuf, const char *utf8buf); extern unsigned int u_strlen(unsigned int *ubuf); -extern char *utf8_idpb(char *w,unsigned int i); +extern char *utf8_idpb(char *w, unsigned int i); +#else + +typedef unsigned int unichar_t; +typedef unsigned char uint8; +typedef unsigned int uint32; + +static unichar_t *utf82u_strcpy(unichar_t * ubuf, const char *utf8buf) +{ + int len = strlen(utf8buf) + 1; + unichar_t *upt = ubuf, *uend = ubuf + len - 1; + const uint8 *pt = (const uint8 *) utf8buf, *end = pt + strlen(utf8buf); + int w, w2; + + while (pt < end && *pt != '\0' && upt < uend) { + if (*pt <= 127) + *upt = *pt++; + else if (*pt <= 0xdf) { + *upt = ((*pt & 0x1f) << 6) | (pt[1] & 0x3f); + pt += 2; + } else if (*pt <= 0xef) { + *upt = ((*pt & 0xf) << 12) | ((pt[1] & 0x3f) << 6) | (pt[2] & 0x3f); + pt += 3; + } else { + w = (((*pt & 0x7) << 2) | ((pt[1] & 0x30) >> 4)) - 1; + w = (w << 6) | ((pt[1] & 0xf) << 2) | ((pt[2] & 0x30) >> 4); + w2 = ((pt[2] & 0xf) << 6) | (pt[3] & 0x3f); + *upt = w * 0x400 + w2 + 0x10000; + pt += 4; + } + ++upt; + } + *upt = '\0'; + return (ubuf); +} + +static char *utf8_idpb(char *utf8_text, uint32 ch) +{ + /* Increment and deposit character */ + if (ch >= 17 * 65536) + return (utf8_text); + + if (ch <= 127) + *utf8_text++ = ch; + else if (ch <= 0x7ff) { + *utf8_text++ = 0xc0 | (ch >> 6); + *utf8_text++ = 0x80 | (ch & 0x3f); + } else if (ch <= 0xffff) { + *utf8_text++ = 0xe0 | (ch >> 12); + *utf8_text++ = 0x80 | ((ch >> 6) & 0x3f); + *utf8_text++ = 0x80 | (ch & 0x3f); + } else { + uint32 val = ch - 0x10000; + int u = ((val & 0xf0000) >> 16) + 1, z = (val & 0x0f000) >> 12, y = + (val & 0x00fc0) >> 6, x = val & 0x0003f; + *utf8_text++ = 0xf0 | (u >> 2); + *utf8_text++ = 0x80 | ((u & 3) << 4) | z; + *utf8_text++ = 0x80 | y; + *utf8_text++ = 0x80 | x; + } + return (utf8_text); +} + +static int u_strlen(register unichar_t * str) +{ + register int len = 0; + while (*str++ != '\0') + ++len; + return (len); +} + +#endif #define noVERBOSE -#define MAX_TEX_LANGUAGES 32767 +#define MAX_TEX_LANGUAGES 32768 -static struct tex_language *tex_languages[MAX_TEX_LANGUAGES] = {NULL}; +static struct tex_language *tex_languages[MAX_TEX_LANGUAGES] = { NULL }; static int next_lang_id = 0; -struct tex_language * -new_language (void) { - struct tex_language* lang; - if (next_lang_idid = next_lang_id++; - lang->exceptions = 0; - lang->patterns = NULL; - lang->pre_hyphen_char = '-'; - lang->post_hyphen_char = 0; - return lang; - } else { - return NULL; - } +struct tex_language *new_language(int n) +{ + struct tex_language *lang; + unsigned l; + if (n >= 0) { + l = (unsigned) n; + if (l != (MAX_TEX_LANGUAGES - 1)) + if (next_lang_id <= n) + next_lang_id = n + 1; + } else { + while (tex_languages[next_lang_id] != NULL) + next_lang_id++; + l = next_lang_id++; + } + if (l < (MAX_TEX_LANGUAGES - 1) && tex_languages[l] == NULL) { + lang = xmalloc(sizeof(struct tex_language)); + tex_languages[l] = lang; + lang->id = l; + lang->exceptions = 0; + lang->patterns = NULL; + lang->pre_hyphen_char = '-'; + lang->post_hyphen_char = 0; + lang->pre_exhyphen_char = 0; + lang->post_exhyphen_char = 0; + return lang; + } else { + return NULL; + } } -struct tex_language * -get_language (int n) { - if (n>=0 && n= 0 && n < MAX_TEX_LANGUAGES) { + if (tex_languages[n] != NULL) { + return tex_languages[n]; + } else { + return new_language(n); + } } else { - return new_language(); + return NULL; } - } else { - return NULL; - } } -void -set_pre_hyphen_char (integer n, integer v) { - struct tex_language *l = get_language((int)n); - if (l!=NULL) - l->pre_hyphen_char = (int)v; +void set_pre_hyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->pre_hyphen_char = (int) v; } -void -set_post_hyphen_char (integer n, integer v) { - struct tex_language *l = get_language((int)n); - if (l!=NULL) - l->post_hyphen_char = (int)v; +void set_post_hyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->post_hyphen_char = (int) v; } -integer -get_pre_hyphen_char (integer n) { - struct tex_language *l = get_language((int)n); - if (l==NULL) return -1; - return (integer)l->pre_hyphen_char; + +void set_pre_exhyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->pre_exhyphen_char = (int) v; } -integer -get_post_hyphen_char (integer n) { - struct tex_language *l = get_language((int)n); - if (l==NULL) return -1; - return (integer)l->post_hyphen_char; +void set_post_exhyphen_char(integer n, integer v) +{ + struct tex_language *l = get_language((int) n); + if (l != NULL) + l->post_exhyphen_char = (int) v; } -void -load_patterns (struct tex_language *lang, unsigned char *buffer) { - if (lang==NULL) - return; - if (lang->patterns==NULL) { - lang->patterns = hnj_hyphen_new(); - } - hnj_hyphen_load (lang->patterns,buffer); + + +integer get_pre_hyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->pre_hyphen_char; } -void -clear_patterns (struct tex_language *lang) { - if (lang==NULL) - return; - if (lang->patterns!=NULL) { - hnj_hyphen_clear(lang->patterns); - } +integer get_post_hyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->post_hyphen_char; } -void -load_tex_patterns(int curlang, halfword head) { - char *s = tokenlist_to_cstring (head,1, NULL); - load_patterns(get_language(curlang),(unsigned char *)s); + +integer get_pre_exhyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->pre_exhyphen_char; +} + +integer get_post_exhyphen_char(integer n) +{ + struct tex_language *l = get_language((int) n); + if (l == NULL) + return -1; + return (integer) l->post_exhyphen_char; +} + +void load_patterns(struct tex_language *lang, unsigned char *buffer) +{ + if (lang == NULL) + return; + if (lang->patterns == NULL) { + lang->patterns = hnj_hyphen_new(); + } + hnj_hyphen_load(lang->patterns, buffer); +} + +void clear_patterns(struct tex_language *lang) +{ + if (lang == NULL) + return; + if (lang->patterns != NULL) { + hnj_hyphen_clear(lang->patterns); + } +} + +void load_tex_patterns(int curlang, halfword head) +{ + char *s = tokenlist_to_cstring(head, 1, NULL); + load_patterns(get_language(curlang), (unsigned char *) s); } #define STORE_CHAR(x) { word[w] = x ; if (wexceptions==0) { - lua_newtable(L); - lang->exceptions = luaL_ref(L,LUA_REGISTRYINDEX); - } - lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions); - s = (char *)buffer; - while (*s) { - while (isspace(*s)) s++; - if (*s) { - value = s; - s = clean_hyphenation(s, &cleaned); - if (cleaned!=NULL) { - if ((s-value)>0) { - lua_pushstring(L,cleaned); - lua_pushlstring(L,value,(s-value)); - lua_rawset(L,-3); - } - free(cleaned); - } else { + word[w] = 0; + *cleaned = xstrdup((char *) word); + return s; +} + +void load_hyphenation(struct tex_language *lang, unsigned char *buffer) +{ + char *s, *value, *cleaned; + lua_State *L = Luas; + if (lang == NULL) + return; + if (lang->exceptions == 0) { + lua_newtable(L); + lang->exceptions = luaL_ref(L, LUA_REGISTRYINDEX); + } + lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions); + s = (char *) buffer; + while (*s) { + while (isspace(*s)) + s++; + if (*s) { + value = s; + s = clean_hyphenation(s, &cleaned); + if (cleaned != NULL) { + if ((s - value) > 0) { + lua_pushstring(L, cleaned); + lua_pushlstring(L, value, (s - value)); + lua_rawset(L, -3); + } + free(cleaned); + } else { #ifdef VERBOSE - fprintf(stderr,"skipping invalid hyphenation exception: %s\n",value); + fprintf(stderr, "skipping invalid hyphenation exception: %s\n", + value); #endif - } + } + } } - } } -void -clear_hyphenation (struct tex_language *lang) { - if (lang==NULL) - return; - if (lang->exceptions!=0) { - luaL_unref(Luas[0],LUA_REGISTRYINDEX,lang->exceptions); - lang->exceptions = 0; - } +void clear_hyphenation(struct tex_language *lang) +{ + if (lang == NULL) + return; + if (lang->exceptions != 0) { + luaL_unref(Luas, LUA_REGISTRYINDEX, lang->exceptions); + lang->exceptions = 0; + } } -void -load_tex_hyphenation(int curlang, halfword head) { - char *s = tokenlist_to_cstring (head,1, NULL); - load_hyphenation(get_language(curlang),(unsigned char *)s); +void load_tex_hyphenation(int curlang, halfword head) +{ + char *s = tokenlist_to_cstring(head, 1, NULL); + load_hyphenation(get_language(curlang), (unsigned char *) s); } /* TODO: clean this up. The delete_attribute_ref() statements are not very nice, but needed. Also, in the post-break, it would be nicer to get the attribute list from vlink(n). No rush, as it is currently not used much. */ -halfword insert_discretionary ( halfword t, halfword pre, halfword post, halfword replace) { - halfword g, n; - n = new_node(disc_node,syllable_disc); - try_couple_nodes(n,vlink(t)); - couple_nodes(t,n); - for (g=pre;g!=null;g=vlink(g)) { - font(g)=font(replace); - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; +halfword insert_discretionary(halfword t, halfword pre, halfword post, + halfword replace) +{ + halfword g, n; + int f; + n = new_node(disc_node, syllable_disc); + try_couple_nodes(n, vlink(t)); + couple_nodes(t, n); + if (replace != null) + f = font(replace); + else + f = get_cur_font(); /* for compound words following explicit hyphens */ + for (g = pre; g != null; g = vlink(g)) { + font(g) = f; + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(g)); + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } } - } - for (g=post;g!=null;g =vlink(g)) { - font(g)=font(replace); - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; + for (g = post; g != null; g = vlink(g)) { + font(g) = f; + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(g)); + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } } - } - for (g=replace;g!=null;g =vlink(g)) { - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(g)); - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; + for (g = replace; g != null; g = vlink(g)) { + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(g)); + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } } - } - if (node_attr(t)!=null) { - delete_attribute_ref(node_attr(vlink(t))); - node_attr(vlink(t)) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; - } - t = vlink(t); - set_disc_field(pre_break(t),pre); - set_disc_field(post_break(t),post); - set_disc_field(no_break(t),replace); - return t; -} - -halfword -insert_syllable_discretionary ( halfword t, lang_variables *lan) { - halfword g, n; - n = new_node(disc_node,syllable_disc); - couple_nodes(n,vlink(t)); - couple_nodes(t,n); - delete_attribute_ref(node_attr(n)); - if (node_attr(t)!=null) { - node_attr(n) = node_attr(t); - attr_list_ref(node_attr(t))++ ; - } else { - node_attr(n) = null; - } - if (lan->pre_hyphen_char >0) { - g = raw_glyph_node(); - set_to_character(g); - character(g)=lan->pre_hyphen_char; - font(g)=font(t); - lang_data(g)=lang_data(t); - if (node_attr(t)!=null) { - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) ++; - } - set_disc_field(pre_break(n),g); - } + if (node_attr(t) != null) { + delete_attribute_ref(node_attr(vlink(t))); + node_attr(vlink(t)) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } + t = vlink(t); + set_disc_field(pre_break(t), pre); + set_disc_field(post_break(t), post); + set_disc_field(no_break(t), replace); + return t; +} - if (lan->post_hyphen_char >0) { - t = vlink(n); - g = raw_glyph_node(); - set_to_character(g); - character(g)=lan->post_hyphen_char; - font(g)=font(t); - lang_data(g)=lang_data(t); - if (node_attr(t)!=null) { - node_attr(g) = node_attr(t); - attr_list_ref(node_attr(t)) += 1; - } - set_disc_field(post_break(n),g); - } - return n; +halfword insert_syllable_discretionary(halfword t, lang_variables * lan) +{ + halfword g, n; + n = new_node(disc_node, syllable_disc); + couple_nodes(n, vlink(t)); + couple_nodes(t, n); + delete_attribute_ref(node_attr(n)); + if (node_attr(t) != null) { + node_attr(n) = node_attr(t); + attr_list_ref(node_attr(t))++; + } else { + node_attr(n) = null; + } + if (lan->pre_hyphen_char > 0) { + g = raw_glyph_node(); + set_to_character(g); + character(g) = lan->pre_hyphen_char; + font(g) = font(t); + lang_data(g) = lang_data(t); + if (node_attr(t) != null) { + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t))++; + } + set_disc_field(pre_break(n), g); + } + + if (lan->post_hyphen_char > 0) { + t = vlink(n); + g = raw_glyph_node(); + set_to_character(g); + character(g) = lan->post_hyphen_char; + font(g) = font(t); + lang_data(g) = lang_data(t); + if (node_attr(t) != null) { + node_attr(g) = node_attr(t); + attr_list_ref(node_attr(t)) += 1; + } + set_disc_field(post_break(n), g); + } + return n; } -halfword insert_word_discretionary ( halfword t, lang_variables *lan) { - halfword pre = null, pos = null; - if (lan->pre_hyphen_char >0) pre = insert_character ( null, lan->pre_hyphen_char); - if (lan->post_hyphen_char>0) pos = insert_character ( null, lan->post_hyphen_char); - return insert_discretionary ( t, pre, pos, null); +halfword insert_word_discretionary(halfword t, lang_variables * lan) +{ + halfword pre = null, pos = null; + if (lan->pre_exhyphen_char > 0) + pre = insert_character(null, lan->pre_exhyphen_char); + if (lan->post_exhyphen_char > 0) + pos = insert_character(null, lan->post_exhyphen_char); + return insert_discretionary(t, pre, pos, null); } -halfword insert_complex_discretionary ( halfword t, lang_variables *lan, - halfword pre, halfword pos, halfword replace) { - return insert_discretionary ( t, pre, pos, replace); +halfword compound_word_break(halfword t, int clang) +{ + int disc; + lang_variables langdata; + langdata.pre_exhyphen_char = get_pre_exhyphen_char(clang); + langdata.post_exhyphen_char = get_post_exhyphen_char(clang); + disc = insert_word_discretionary(t, &langdata); + return disc; } -halfword insert_character ( halfword t, int c) { - halfword p; - p=new_node(glyph_node,0); - set_to_character(p); - character(p)=c; - if (t!=null) { - couple_nodes(t,p); - } - return p; +halfword insert_complex_discretionary(halfword t, lang_variables * lan, + halfword pre, halfword pos, + halfword replace) +{ + (void) lan; + return insert_discretionary(t, pre, pos, replace); } -void -set_disc_field (halfword f, halfword t) { - if (t!=null) { - couple_nodes(f,t); - tlink(f) = tail_of_list(t); - } +halfword insert_character(halfword t, int c) +{ + halfword p; + p = new_node(glyph_node, 0); + set_to_character(p); + character(p) = c; + if (t != null) { + couple_nodes(t, p); + } + return p; +} + + +void set_disc_field(halfword f, halfword t) +{ + if (t != null) { + couple_nodes(f, t); + tlink(f) = tail_of_list(t); + } else { + vlink(f) = null; + tlink(f) = null; + } } -char *hyphenation_exception(int exceptions, char *w) { - char *ret = NULL; - lua_State *L = Luas[0]; - lua_checkstack(L,2); - lua_rawgeti(L,LUA_REGISTRYINDEX,exceptions); - if (lua_istable(L,-1)) { /* ?? */ - lua_pushstring(L,w); /* word table */ - lua_rawget(L,-2); - if (lua_isstring(L,-1)) { - ret = xstrdup((char *)lua_tostring(L,-1)); +char *hyphenation_exception(int exceptions, char *w) +{ + char *ret = NULL; + lua_State *L = Luas; + lua_checkstack(L, 2); + lua_rawgeti(L, LUA_REGISTRYINDEX, exceptions); + if (lua_istable(L, -1)) { /* ?? */ + lua_pushstring(L, w); /* word table */ + lua_rawget(L, -2); + if (lua_isstring(L, -1)) { + ret = xstrdup((char *) lua_tostring(L, -1)); + } + lua_pop(L, 2); + } else { + lua_pop(L, 1); } - lua_pop(L,2); - } else { - lua_pop(L,1); - } - return ret; -} - - -char *exception_strings(struct tex_language *lang) { - char *value; - size_t size = 0, current =0; - size_t l =0; - char *ret = NULL; - lua_State *L = Luas[0]; - if (lang->exceptions==0) - return NULL; - lua_checkstack(L,2); - lua_rawgeti(L,LUA_REGISTRYINDEX,lang->exceptions); - if (lua_istable(L,-1)) { - /* iterate and join */ - lua_pushnil(L); /* first key */ - while (lua_next(L,-2) != 0) { - value = (char *)lua_tolstring(L, -1, &l); - if (current + 2 + l > size ) { - ret = xrealloc(ret, (1.2*size)+current+l+1024); - size = (1.2*size)+current+l+1024; - } - *(ret+current) = ' '; - strcpy(ret+current+1,value); - current += l+1; - lua_pop(L, 1); + return ret; +} + + +char *exception_strings(struct tex_language *lang) +{ + char *value; + size_t size = 0, current = 0; + size_t l = 0; + char *ret = NULL; + lua_State *L = Luas; + if (lang->exceptions == 0) + return NULL; + lua_checkstack(L, 2); + lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions); + if (lua_istable(L, -1)) { + /* iterate and join */ + lua_pushnil(L); /* first key */ + while (lua_next(L, -2) != 0) { + value = (char *) lua_tolstring(L, -1, &l); + if (current + 2 + l > size) { + ret = xrealloc(ret, (1.2 * size) + current + l + 1024); + size = (1.2 * size) + current + l + 1024; + } + *(ret + current) = ' '; + strcpy(ret + current + 1, value); + current += l + 1; + lua_pop(L, 1); + } } - } - return ret; + return ret; } /* the sequence from |wordstart| to |r| can contain only normal characters */ /* it could be faster to modify a halfword pointer and return an integer */ -halfword find_exception_part(unsigned int *j, int *uword, int len) { - halfword g = null, gg = null; - register int i = *j; - i++; /* this puts uword[i] on the '{' */ - while (i0) { - halfword q = t; - replace = vlink(q); - while(repl>0 && q!=null) { - q=vlink(q); - if (type(q)==glyph_node) { - repl--; - } - } - try_couple_nodes(t,vlink(q)); - vlink(q)=null; - } - t = insert_discretionary(t,gg,hh,replace); - } else { - t = vlink(t); +int count_exception_part(unsigned int *j, int *uword, int len) +{ + int ret = 0; + register int i = *j; + i++; /* this puts uword[i] on the '{' */ + while (i < len && uword[i + 1] != '}') { + ret++; + i++; + } + *j = ++i; + return ret; +} + + +static char *PAT_ERROR[] = { + "Exception discretionaries should contain three pairs of braced items.", + "No intervening spaces are allowed.", + NULL +}; + +void do_exception(halfword wordstart, halfword r, char *replacement) +{ + unsigned i; + halfword t; + unsigned len; + int clang; + lang_variables langdata; + int uword[MAX_WORD_LEN + 1] = { 0 }; + (void) utf82u_strcpy((unsigned int *) uword, replacement); + len = u_strlen((unsigned int *) uword); + i = 0; + t = wordstart; + clang = char_lang(wordstart); + langdata.pre_hyphen_char = get_pre_hyphen_char(clang); + langdata.post_hyphen_char = get_post_hyphen_char(clang); + + for (i = 0; i < len; i++) { + if (uword[i + 1] == '-') { /* a hyphen follows */ + while (vlink(t) != r + && (type(t) != glyph_node || !is_simple_character(t))) + t = vlink(t); + if (vlink(t) == r) + break; + insert_syllable_discretionary(t, &langdata); + t = vlink(t); /* skip the new disc */ + } else if (uword[i + 1] == '=') { + /* do nothing ? */ + t = vlink(t); + } else if (uword[i + 1] == '{') { + halfword gg, hh, replace = null; + int repl; + gg = find_exception_part(&i, uword, len); + if (i == len || uword[i + 1] != '{') { + tex_error("broken pattern 1", PAT_ERROR); + } + hh = find_exception_part(&i, uword, len); + if (i == len || uword[i + 1] != '{') { + tex_error("broken pattern 2", PAT_ERROR); + } + repl = count_exception_part(&i, uword, len); + if (i == len) { + tex_error("broken pattern 3", PAT_ERROR); + } + /*i++; *//* jump over the last right brace */ + if (vlink(t) == r) + break; + if (repl > 0) { + halfword q = t; + replace = vlink(q); + while (repl > 0 && q != null) { + q = vlink(q); + if (type(q) == glyph_node) { + repl--; + } + } + try_couple_nodes(t, vlink(q)); + vlink(q) = null; + } + t = insert_discretionary(t, gg, hh, replace); + t = vlink(t); /* skip the new disc */ + } else { + t = vlink(t); + } } - } } /* This is a documentation section from the pascal web file. It is not @@ -554,276 +735,299 @@ using an algorithm due to Frank~M. Liang. /* * This is incompatible with TEX because the first word of a paragraph * can be hyphenated, but most european users seem to agree that - * prohibiting hyphenation there was not a the best idea ever. + * prohibiting hyphenation there was not the best idea ever. */ -halfword find_next_wordstart(halfword r) { - register int l; - register int start_ok = 1; - int mathlevel = 1; - while (r!=null) { - switch (type(r)) { - case glue_node: - start_ok = 1; - break; - case math_node: - while (mathlevel>0 ){ - r = vlink(r); - if (r==null) - return r; - if (type(r)==math_node) { - if (subtype(r)==before) { - mathlevel++; - } else { - mathlevel--; - } - } - } - break; - case glyph_node: - if (start_ok && - is_simple_character(r) && - (l = get_lc_code(character(r)))>0 && - (char_uchyph(r) || l == character(r))) - return r; - /* fall through */ - default: - start_ok = 0; - break; - } - r = vlink(r); - } - return r; -} - -int valid_wordend( halfword s) { - register halfword r = s; - register int clang = char_lang(s); - if (r==null) - return 1; - while ((r!=null) && - ((type(r)==glyph_node && is_simple_character(r) && clang == char_lang(r)) || - (type(r)==kern_node && subtype(r)==normal))) { - r = vlink(r); - } - if (r==null || - (type(r)==glyph_node && is_simple_character(r) && clang != char_lang(r)) || - type(r)==glue_node || - type(r)==whatsit_node || - type(r)==ins_node || - type(r)==adjust_node || - type(r)==penalty_node || - (type(r)==kern_node && subtype(r)==explicit)) - return 1; - return 0; -} - -void -hnj_hyphenation (halfword head, halfword tail) { - int lchar, i; - struct tex_language* lang; - lang_variables langdata; - char utf8word[(4*MAX_WORD_LEN)+1] = {0}; - int wordlen = 0; - char *hy = utf8word; - char *replacement = NULL; - halfword s, r = head, wordstart = null, save_tail = null, left = null, right = null; - - /* this first movement assures two things: - * a) that we won't waste lots of time on something that has been - * handled already (in that case, none of the glyphs match |simple_character|). - * b) that the first word can be hyphenated. if the movement was - * not explicit, then the indentation at the start of a paragraph - * list would make find_next_wordstart() look too far ahead. - */ - - while (r!=null && (type(r)!=glyph_node || !is_simple_character(r))) - r =vlink(r); - /* this will make |r| a glyph node with subtype_character */ - r = find_next_wordstart(r); - if (r==null) - return; - - assert (tail!=null); - save_tail = vlink(tail); - s = new_penalty(0); - couple_nodes(tail, s); - - while (r!=null) { /* could be while(1), but let's be paranoid */ - int clang, lhmin, rhmin; - wordstart = r; - assert (is_simple_character(wordstart)); - clang = char_lang(wordstart); - lhmin = char_lhmin(wordstart); - rhmin = char_rhmin(wordstart); - langdata.pre_hyphen_char = get_pre_hyphen_char(clang); - langdata.post_hyphen_char = get_post_hyphen_char(clang); - while (r!=null && - type(r)==glyph_node && - is_simple_character(r) && - clang == char_lang(r) && - (lchar = get_lc_code(character(r)))>0) { - wordlen++; - hy = utf8_idpb(hy,character(r)); - /* this should not be needed any more */ - /*if (vlink(r)!=null) alink(vlink(r))=r;*/ - r = vlink(r); - } - if (valid_wordend(r) && wordlen>=lhmin+rhmin && (lang=tex_languages[clang])!=NULL) { - *hy=0; - if (lang->exceptions!=0 && - (replacement = hyphenation_exception(lang->exceptions,utf8word))!=NULL) { +halfword find_next_wordstart(halfword r) +{ + register int l; + register int start_ok = 1; + int mathlevel = 1; + while (r != null) { + switch (type(r)) { + case glue_node: + start_ok = 1; + break; + case math_node: + while (mathlevel > 0) { + r = vlink(r); + if (r == null) + return r; + if (type(r) == math_node) { + if (subtype(r) == before) { + mathlevel++; + } else { + mathlevel--; + } + } + } + break; + case glyph_node: + if (start_ok && + is_simple_character(r) && + (l = get_lc_code(character(r))) > 0 && + (char_uchyph(r) || l == character(r))) + return r; + break; + default: + start_ok = 0; + break; + } + r = vlink(r); + } + return r; +} + +int valid_wordend(halfword s) +{ + register halfword r = s; + register int clang = char_lang(s); + if (r == null) + return 1; + while ((r != null) && ((type(r) == glyph_node && is_simple_character(r) + && clang == char_lang(r)) || (type(r) == kern_node + && subtype(r) == + normal))) { + r = vlink(r); + } + if (r == null || (type(r) == glyph_node && is_simple_character(r) + && clang != char_lang(r)) || type(r) == glue_node + || type(r) == whatsit_node || type(r) == ins_node + || type(r) == adjust_node || type(r) == penalty_node + || (type(r) == kern_node && subtype(r) == explicit)) + return 1; + return 0; +} + +void hnj_hyphenation(halfword head, halfword tail) +{ + int lchar, i; + struct tex_language *lang; + lang_variables langdata; + char utf8word[(4 * MAX_WORD_LEN) + 1] = { 0 }; + int wordlen = 0; + char *hy = utf8word; + char *replacement = NULL; + halfword s, r = head, wordstart = null, save_tail = null, left = + null, right = null; + + /* this first movement assures two things: + * a) that we won't waste lots of time on something that has been + * handled already (in that case, none of the glyphs match |simple_character|). + * b) that the first word can be hyphenated. if the movement was + * not explicit, then the indentation at the start of a paragraph + * list would make find_next_wordstart() look too far ahead. + */ + + while (r != null && (type(r) != glyph_node || !is_simple_character(r))) { + r = vlink(r); + } + /* this will make |r| a glyph node with subtype_character */ + r = find_next_wordstart(r); + if (r == null) + return; + + assert(tail != null); + save_tail = vlink(tail); + s = new_penalty(0); + couple_nodes(tail, s); + + while (r != null) { /* could be while(1), but let's be paranoid */ + int clang, lhmin, rhmin; + halfword hyf_font; + halfword end_word = r; + wordstart = r; + assert(is_simple_character(wordstart)); + hyf_font = font(wordstart); + if (hyphen_char(hyf_font)<0) /* for backward compat */ + hyf_font = 0; + clang = char_lang(wordstart); + lhmin = char_lhmin(wordstart); + rhmin = char_rhmin(wordstart); + langdata.pre_hyphen_char = get_pre_hyphen_char(clang); + langdata.post_hyphen_char = get_post_hyphen_char(clang); + while (r != null && + type(r) == glyph_node && + is_simple_character(r) && + clang == char_lang(r) && + (lchar = get_lc_code(character(r))) > 0) { + wordlen++; + hy = utf8_idpb(hy, character(r)); + /* this should not be needed any more */ + /*if (vlink(r)!=null) alink(vlink(r))=r; */ + end_word = r; + r = vlink(r); + } + if (valid_wordend(r) && wordlen >= lhmin + rhmin + && (hyf_font != 0) && (lang = tex_languages[clang]) != NULL) { + *hy = 0; + if (lang->exceptions != 0 && + (replacement = + hyphenation_exception(lang->exceptions, utf8word)) != NULL) { #ifdef VERBOSE - fprintf(stderr,"replacing %s (c=%d) by %s\n",utf8word,clang,replacement); -#endif - do_exception(wordstart,r,replacement); - free(replacement); - } else if (lang->patterns!=NULL) { - - left = wordstart; - for (i=lhmin;i>1;i--) { - left = vlink(left); - while (!is_simple_character(left)) - left = vlink(left); - } - right = r; - for (i=rhmin;i>0;i--) { - right = alink(right); - while (!is_simple_character(right)) - right = alink(right); - } - + fprintf(stderr, "replacing %s (c=%d) by %s\n", utf8word, clang, + replacement); +#endif + do_exception(wordstart, r, replacement); + free(replacement); + } else if (lang->patterns != NULL) { + + left = wordstart; + for (i = lhmin; i > 1; i--) { + left = vlink(left); + while (!is_simple_character(left)) + left = vlink(left); + } + right = r; + for (i = rhmin; i > 0; i--) { + right = alink(right); + while (!is_simple_character(right)) + right = alink(right); + } + #ifdef VERBOSE - fprintf(stderr,"hyphenate %s (c=%d,l=%d,r=%d) from %c to %c\n",utf8word, - clang,lhmin,rhmin, - character(left), character(right)); -#endif - (void)hnj_hyphen_hyphenate(lang->patterns,wordstart,r,wordlen,left,right, &langdata); - } - } - wordlen = 0; - hy = utf8word; - if (r==null) - break; - r = find_next_wordstart(r); - } - flush_node(vlink(tail)); - vlink(tail) = save_tail; -} - - -void -new_hyphenation (halfword head, halfword tail) { - register int callback_id = 0; - if (head==null || vlink(head)==null) - return; - fix_node_list (head); /* TODO: use couple_nodes() in append_tail()!*/ - callback_id = callback_defined(hyphenate_callback); - if (callback_id>0) { - lua_State *L = Luas[0]; - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1, callback_id); - if (!lua_isfunction(L,-1)) { - lua_pop(L,2); - return; - } - nodelist_to_lua(L,head); - nodelist_to_lua(L,tail); - if (lua_pcall(L,2,0,0) != 0) { - fprintf(stdout,"error: %s\n",lua_tostring(L,-1)); - lua_pop(L,2); - lua_error(L); - return; - } - lua_pop(L,1); - } else { - hnj_hyphenation(head,tail); - } + fprintf(stderr, "hyphenate %s (c=%d,l=%d,r=%d) from %c to %c\n", + utf8word, clang, lhmin, rhmin, character(left), + character(right)); +#endif + (void) hnj_hyphen_hyphenate(lang->patterns, wordstart, end_word, + wordlen, left, right, &langdata); + } + } + wordlen = 0; + hy = utf8word; + if (r == null) + break; + r = find_next_wordstart(r); + } + flush_node(vlink(tail)); + vlink(tail) = save_tail; +} + + +void new_hyphenation(halfword head, halfword tail) +{ + register int callback_id = 0; + if (head == null || vlink(head) == null) + return; + fix_node_list(head); /* TODO: use couple_nodes() in append_tail()! */ + callback_id = callback_defined(hyphenate_callback); + if (callback_id > 0) { + lua_State *L = Luas; + if (!get_callback(L, callback_id)) { + lua_pop(L, 2); + return; + } + nodelist_to_lua(L, head); + nodelist_to_lua(L, tail); + if (lua_pcall(L, 2, 0, 0) != 0) { + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 2); + lua_error(L); + return; + } + lua_pop(L, 1); + } else { + hnj_hyphenation(head, tail); + } } /* dumping and undumping fonts */ -#define dump_string(a) \ - if (a!=NULL) { \ - x = strlen(a)+1; \ - dump_int(x); dump_things(*a, x); \ - } else { \ - x = 0; dump_int(x); \ +#define dump_string(a) \ + if (a!=NULL) { \ + x = strlen(a)+1; \ + dump_int(x); dump_things(*a, x); \ + } else { \ + x = 0; dump_int(x); \ } -void dump_one_language (int i) { - char *s = NULL; - unsigned x = 0; - struct tex_language *lang; - lang = tex_languages[i]; - dump_int(lang->id); - dump_int(lang->pre_hyphen_char); - dump_int(lang->post_hyphen_char); - if (lang->patterns!=NULL) { - s = (char *)hnj_serialize(lang->patterns); - } - dump_string(s); - if (s!=NULL) { - free(s); - s = NULL; - } - if (lang->exceptions!=0) - s = exception_strings(lang); - dump_string(s); - if (s!=NULL) { - free(s); - } - free (lang); +void dump_one_language(int i) +{ + char *s = NULL; + unsigned x = 0; + struct tex_language *lang; + lang = tex_languages[i]; + dump_int(lang->id); + dump_int(lang->pre_hyphen_char); + dump_int(lang->post_hyphen_char); + dump_int(lang->pre_exhyphen_char); + dump_int(lang->post_exhyphen_char); + if (lang->patterns != NULL) { + s = (char *) hnj_serialize(lang->patterns); + } + dump_string(s); + if (s != NULL) { + free(s); + s = NULL; + } + if (lang->exceptions != 0) + s = exception_strings(lang); + dump_string(s); + if (s != NULL) { + free(s); + } + free(lang); } -void dump_language_data (void) { - int i; - dump_int(next_lang_id); - for (i=0;iid = x; - undump_int(x); lang->pre_hyphen_char = x; - undump_int(x); lang->post_hyphen_char = x; - /* patterns */ - undump_int (x); - if (x>0) { - s = xmalloc(x); - undump_things(*s,x); - load_patterns(lang,(unsigned char *)s); - free(s); - } - /* exceptions */ - undump_int (x); - if (x>0) { - s = xmalloc(x); - undump_things(*s,x); - load_hyphenation(lang,(unsigned char *)s); - free(s); - } -} - -void undump_language_data (void) { - unsigned i, x, numlangs; - undump_int(numlangs); - for (i=0;iid = x; + undump_int(x); + lang->pre_hyphen_char = x; undump_int(x); - if (x==1) { - undump_one_language(i); + lang->post_hyphen_char = x; + undump_int(x); + lang->pre_exhyphen_char = x; + undump_int(x); + lang->post_exhyphen_char = x; + /* patterns */ + undump_int(x); + if (x > 0) { + s = xmalloc(x); + undump_things(*s, x); + load_patterns(lang, (unsigned char *) s); + free(s); + } + /* exceptions */ + undump_int(x); + if (x > 0) { + s = xmalloc(x); + undump_things(*s, x); + load_hyphenation(lang, (unsigned char *) s); + free(s); } - } } +void undump_language_data(void) +{ + unsigned i, x, numlangs; + undump_int(numlangs); + next_lang_id = numlangs; + for (i = 0; i < numlangs; i++) { + undump_int(x); + if (x == 1) { + undump_one_language(i); + } + } +} diff --git a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c index 09e94fda2e9..c85a1912e49 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c @@ -1,149 +1,175 @@ -/* $Id: lcallbacklib.c 1013 2008-02-14 00:09:02Z oneiros $ */ +/* lcallbacklib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include -extern int do_run_callback (int special, char *values, va_list vl); +static const char _svn_version[] = + "$Id: lcallbacklib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lcallbacklib.c $"; -int callback_set[total_callbacks] = {0}; +extern int do_run_callback(int special, char *values, va_list vl); +extern int lua_traceback(lua_State * L); + +int callback_count = 0; +int saved_callback_count = 0; + +int callback_set[total_callbacks] = { 0 }; static const char *const callbacknames[] = { - "", /* empty on purpose */ - "find_write_file", - "find_output_file", - "find_image_file", - "find_format_file", - "find_read_file", "open_read_file", - "find_ocp_file", "read_ocp_file", - "find_vf_file", "read_vf_file", - "find_data_file", "read_data_file", - "find_font_file", "read_font_file", - "find_map_file", "read_map_file", - "find_enc_file", "read_enc_file", - "find_type1_file", "read_type1_file", - "find_truetype_file", "read_truetype_file", - "find_opentype_file", "read_opentype_file", - "find_sfd_file", "read_sfd_file", - "find_pk_file", "read_pk_file", - "show_error_hook", - "process_input_buffer", - "start_page_number", "stop_page_number", - "start_run", "stop_run", - "define_font", - "token_filter", - "pre_output_filter", - "buildpage_filter", - "hpack_filter", "vpack_filter", - "char_exists", - "hyphenate", - "ligaturing", - "kerning", - "pre_linebreak_filter", - "linebreak_filter", - "post_linebreak_filter", - NULL }; + "", /* empty on purpose */ + "find_write_file", + "find_output_file", + "find_image_file", + "find_format_file", + "find_read_file", "open_read_file", + "find_ocp_file", "read_ocp_file", + "find_vf_file", "read_vf_file", + "find_data_file", "read_data_file", + "find_font_file", "read_font_file", + "find_map_file", "read_map_file", + "find_enc_file", "read_enc_file", + "find_type1_file", "read_type1_file", + "find_truetype_file", "read_truetype_file", + "find_opentype_file", "read_opentype_file", + "find_sfd_file", "read_sfd_file", + "find_pk_file", "read_pk_file", + "show_error_hook", + "process_input_buffer", + "start_page_number", "stop_page_number", + "start_run", "stop_run", + "define_font", + "token_filter", + "pre_output_filter", + "buildpage_filter", + "hpack_filter", "vpack_filter", + "char_exists", + "hyphenate", + "ligaturing", + "kerning", + "pre_linebreak_filter", + "linebreak_filter", + "post_linebreak_filter", + "mlist_to_hlist", + NULL +}; int callback_callbacks_id = 0; -void -get_lua_boolean (char *table, char *name, boolean *target) { - int stacktop; - stacktop = lua_gettop(Luas[0]); - luaL_checkstack(Luas[0],2,"out of stack space"); - lua_getglobal(Luas[0],table); - if (lua_istable(Luas[0],-1)) { - lua_getfield(Luas[0],-1,name); - if (lua_isboolean(Luas[0],-1)) { - *target = (lua_toboolean(Luas[0],-1)); - } else if (lua_isnumber(Luas[0],-1)) { - *target = (lua_tonumber(Luas[0],-1)==0 ? 0 : 1); +void get_lua_boolean(char *table, char *name, boolean * target) +{ + int stacktop; + stacktop = lua_gettop(Luas); + luaL_checkstack(Luas, 2, "out of stack space"); + lua_getglobal(Luas, table); + if (lua_istable(Luas, -1)) { + lua_getfield(Luas, -1, name); + if (lua_isboolean(Luas, -1)) { + *target = (lua_toboolean(Luas, -1)); + } else if (lua_isnumber(Luas, -1)) { + *target = (lua_tonumber(Luas, -1) == 0 ? 0 : 1); + } } - } - lua_settop(Luas[0],stacktop); - return; + lua_settop(Luas, stacktop); + return; } -void -get_saved_lua_boolean (int r, char *name, boolean *target) { - int stacktop; - stacktop = lua_gettop(Luas[0]); - luaL_checkstack(Luas[0],2,"out of stack space"); - lua_rawgeti(Luas[0],LUA_REGISTRYINDEX,r); - if (lua_istable(Luas[0],-1)) { - lua_getfield(Luas[0],-1,name); - if (lua_isboolean(Luas[0],-1)) { - *target = lua_toboolean(Luas[0],-1); - } else if (lua_isnumber(Luas[0],-1)) { - *target = (lua_tonumber(Luas[0],-1)==0 ? 0 : 1); - } - } - lua_settop(Luas[0],stacktop); - return; +void get_saved_lua_boolean(int r, char *name, boolean * target) +{ + int stacktop; + stacktop = lua_gettop(Luas); + luaL_checkstack(Luas, 2, "out of stack space"); + lua_rawgeti(Luas, LUA_REGISTRYINDEX, r); + if (lua_istable(Luas, -1)) { + lua_getfield(Luas, -1, name); + if (lua_isboolean(Luas, -1)) { + *target = lua_toboolean(Luas, -1); + } else if (lua_isnumber(Luas, -1)) { + *target = (lua_tonumber(Luas, -1) == 0 ? 0 : 1); + } + } + lua_settop(Luas, stacktop); + return; } -void -get_lua_number (char *table, char *name, integer *target) { - int stacktop; - stacktop = lua_gettop(Luas[0]); - luaL_checkstack(Luas[0],2,"out of stack space"); - lua_getglobal(Luas[0],table); - if (lua_istable(Luas[0],-1)) { - lua_getfield(Luas[0],-1,name); - if (lua_isnumber(Luas[0],-1)) { - *target = lua_tonumber(Luas[0],-1); +void get_lua_number(char *table, char *name, integer * target) +{ + int stacktop; + stacktop = lua_gettop(Luas); + luaL_checkstack(Luas, 2, "out of stack space"); + lua_getglobal(Luas, table); + if (lua_istable(Luas, -1)) { + lua_getfield(Luas, -1, name); + if (lua_isnumber(Luas, -1)) { + *target = lua_tonumber(Luas, -1); + } } - } - lua_settop(Luas[0],stacktop); - return; + lua_settop(Luas, stacktop); + return; } -void -get_saved_lua_number (int r, char *name, integer *target) { - int stacktop; - stacktop = lua_gettop(Luas[0]); - luaL_checkstack(Luas[0],2,"out of stack space"); - lua_rawgeti(Luas[0],LUA_REGISTRYINDEX,r); - if (lua_istable(Luas[0],-1)) { - lua_getfield(Luas[0],-1,name); - if (lua_isnumber(Luas[0],-1)) { - *target = lua_tonumber(Luas[0],-1); - } - } - lua_settop(Luas[0],stacktop); - return; +void get_saved_lua_number(int r, char *name, integer * target) +{ + int stacktop; + stacktop = lua_gettop(Luas); + luaL_checkstack(Luas, 2, "out of stack space"); + lua_rawgeti(Luas, LUA_REGISTRYINDEX, r); + if (lua_istable(Luas, -1)) { + lua_getfield(Luas, -1, name); + if (lua_isnumber(Luas, -1)) { + *target = lua_tonumber(Luas, -1); + } + } + lua_settop(Luas, stacktop); + return; } -void -get_lua_string (char *table, char *name, char **target) { - int stacktop; - stacktop = lua_gettop(Luas[0]); - luaL_checkstack(Luas[0],2,"out of stack space"); - lua_getglobal(Luas[0],table); - if (lua_istable(Luas[0],-1)) { - lua_getfield(Luas[0],-1,name); - if (lua_isstring(Luas[0],-1)) { - *target = (char *)lua_tostring(Luas[0],-1); +void get_lua_string(char *table, char *name, char **target) +{ + int stacktop; + stacktop = lua_gettop(Luas); + luaL_checkstack(Luas, 2, "out of stack space"); + lua_getglobal(Luas, table); + if (lua_istable(Luas, -1)) { + lua_getfield(Luas, -1, name); + if (lua_isstring(Luas, -1)) { + *target = (char *) lua_tostring(Luas, -1); + } } - } - lua_settop(Luas[0],stacktop); - return; + lua_settop(Luas, stacktop); + return; } -void -get_saved_lua_string (int r, char *name, char **target) { - int stacktop; - stacktop = lua_gettop(Luas[0]); - luaL_checkstack(Luas[0],2,"out of stack space"); - lua_rawgeti(Luas[0],LUA_REGISTRYINDEX,r); - if (lua_istable(Luas[0],-1)) { - lua_getfield(Luas[0],-1,name); - if (lua_isstring(Luas[0],-1)) { - *target = (char *)lua_tostring(Luas[0],-1); - } - } - lua_settop(Luas[0],stacktop); - return; +void get_saved_lua_string(int r, char *name, char **target) +{ + int stacktop; + stacktop = lua_gettop(Luas); + luaL_checkstack(Luas, 2, "out of stack space"); + lua_rawgeti(Luas, LUA_REGISTRYINDEX, r); + if (lua_istable(Luas, -1)) { + lua_getfield(Luas, -1, name); + if (lua_isstring(Luas, -1)) { + *target = (char *) lua_tostring(Luas, -1); + } + } + lua_settop(Luas, stacktop); + return; } @@ -154,311 +180,340 @@ get_saved_lua_string (int r, char *name, char **target) { #define CALLBACK_STRING 'S' #define CALLBACK_CHARNUM 'c' -int -run_saved_callback (int r, char *name, char *values, ...) { - va_list args; - int ret = 0; - lua_State *L = Luas[0]; - int stacktop = lua_gettop(L); - va_start(args,values); - luaL_checkstack(L,2,"out of stack space"); - lua_rawgeti(L,LUA_REGISTRYINDEX,r); - lua_pushstring(L,name); - lua_rawget(L,-2); - if (lua_isfunction(L,-1)) { - ret = do_run_callback(2,values,args); - } - va_end(args); - lua_settop(L,stacktop); - return ret; + +int run_saved_callback(int r, char *name, char *values, ...) +{ + va_list args; + int ret = 0; + lua_State *L = Luas; + int stacktop = lua_gettop(L); + va_start(args, values); + luaL_checkstack(L, 2, "out of stack space"); + lua_rawgeti(L, LUA_REGISTRYINDEX, r); + lua_pushstring(L, name); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + saved_callback_count++; + callback_count++; + ret = do_run_callback(2, values, args); + } + va_end(args); + lua_settop(L, stacktop); + return ret; } -int -run_and_save_callback (int i, char *values, ...) { - va_list args; - int ret = 0; - lua_State *L = Luas[0]; - int stacktop = lua_gettop(L); - va_start(args,values); - luaL_checkstack(L,2,"out of stack space"); - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1,i); - if (lua_isfunction(L,-1)) { - ret = do_run_callback(1,values,args); - } - va_end(args); - if (ret>0) { - ret = luaL_ref(L,LUA_REGISTRYINDEX); - } - lua_settop(L,stacktop); - return ret; +boolean get_callback(lua_State * L, int i) +{ + luaL_checkstack(L, 2, "out of stack space"); + lua_rawgeti(L, LUA_REGISTRYINDEX, callback_callbacks_id); + lua_rawgeti(L, -1, i); + if (lua_isfunction(L, -1)) { + callback_count++; + return true; + } else { + return false; + } +} + +int run_and_save_callback(int i, char *values, ...) +{ + va_list args; + int ret = 0; + lua_State *L = Luas; + int stacktop = lua_gettop(L); + va_start(args, values); + if (get_callback(L, i)) { + ret = do_run_callback(1, values, args); + } + va_end(args); + if (ret > 0) { + ret = luaL_ref(L, LUA_REGISTRYINDEX); + } + lua_settop(L, stacktop); + return ret; } -int -run_callback (int i, char *values, ...) { - va_list args; - int ret = 0; - lua_State *L = Luas[0]; - int stacktop = lua_gettop(L); - va_start(args,values); - luaL_checkstack(L,2,"out of stack space"); - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1, i); - if (lua_isfunction(L,-1)) { - ret = do_run_callback(0,values,args); - } - va_end(args); - lua_settop(L,stacktop); - return ret; +int run_callback(int i, char *values, ...) +{ + va_list args; + int ret = 0; + lua_State *L = Luas; + int stacktop = lua_gettop(L); + va_start(args, values); + if (get_callback(L, i)) { + ret = do_run_callback(0, values, args); + } + va_end(args); + lua_settop(L, stacktop); + return ret; } -int -do_run_callback (int special, char *values, va_list vl) { - int ret, len; - int narg,nres; - char *s; - char cs; - int *bufloc; - char *ss = NULL; - int retval = 0; - lua_State *L = Luas[0]; - if (special==2) { /* copy the enclosing table */ - luaL_checkstack(L,1,"out of stack space"); - lua_pushvalue(L,-2); - } - for (narg = 0; *values; narg++) { - luaL_checkstack(L,1,"out of stack space"); - switch (*values++) { - case CALLBACK_CHARNUM: /* an ascii char! */ - cs = (char)va_arg(vl, int); - lua_pushlstring(L,&cs, 1); - break; - case CALLBACK_STRING: /* C string */ - s = va_arg(vl, char *); - lua_pushstring(L, s); - break; - case CALLBACK_INTEGER: /* int */ - lua_pushnumber(L, va_arg(vl, int)); - break; - case CALLBACK_STRNUMBER: /* TeX string */ - s = makeclstring(va_arg(vl, int),&len); - lua_pushlstring(L, s,len); - break; - case CALLBACK_BOOLEAN: /* boolean */ - lua_pushboolean(L, va_arg(vl, int)); - break; - case CALLBACK_LINE: /* a buffer section, with implied start */ - lua_pushlstring(L, (char *)(buffer+first), va_arg(vl, int)); - break; - case '-': - narg--; - break; - case '>': - goto ENDARGS; - default : - ; +int do_run_callback(int special, char *values, va_list vl) +{ + int ret; + size_t len; + int narg, nres; + const char *s; + char cs; + int *bufloc; + char *ss = NULL; + int retval = 0; + lua_State *L = Luas; + if (special == 2) { /* copy the enclosing table */ + luaL_checkstack(L, 1, "out of stack space"); + lua_pushvalue(L, -2); } - } - ENDARGS: - nres = strlen(values); - if (special==1) { - nres++; - } - if (special==2) { - narg++; - } - if(lua_pcall(L,narg,nres,0) != 0) { - /* Can't be more precise here, could be called before - * TeX initialization is complete - */ - fprintf(stderr,"This went wrong: %s\n",lua_tostring(L,-1)); - error(); - return 0; - }; - if (nres==0) { - return 1; - } - nres = -nres; - while (*values) { - int b; - switch (*values++) { - case CALLBACK_BOOLEAN: - if (!lua_isboolean(L,nres)) { - fprintf(stderr,"Expected a boolean, not: %s\n", lua_typename(L,lua_type(L,nres))); - goto EXIT; - } - b = lua_toboolean(L,nres); - *va_arg(vl, boolean *) = (boolean)b; - break; - case CALLBACK_INTEGER: - if (!lua_isnumber(L,nres)) { - fprintf(stderr,"Expected a number, not: %s\n", lua_typename(L,lua_type(L,nres))); - goto EXIT; - } - b = lua_tonumber(L,nres); - *va_arg(vl, int *) = b; - break; - case CALLBACK_LINE: /* TeX line */ - if (!lua_isstring(L,nres)) { - if (!lua_isnil(L,nres)) - fprintf(stderr,"Expected a string for (l), not: %s\n", - lua_typename(L,lua_type(L,nres))); - goto EXIT; - } - s = (char *)lua_tolstring(L,nres, (size_t *)&len); - if (s!=NULL) { /* |len| can be zero */ - bufloc = va_arg(vl, int *); - ret = *bufloc; - check_buffer_overflow (ret+len); - while (len--) { - buffer[(*bufloc)++] = *s++; - } - while ((*bufloc)-1>ret && buffer[(*bufloc)-1] == ' ') - (*bufloc)--; - } else { - bufloc = 0; - } - break; - case CALLBACK_STRNUMBER: /* TeX string */ - if (!lua_isstring(L,nres)) { - if (!lua_isnil(L,nres)) { - fprintf(stderr,"Expected a string for (s), not: %s\n", - lua_typename(L,lua_type(L,nres))); - goto EXIT; - } - } - s = (char *)lua_tolstring(L,nres,(size_t *)&len); - if (s==NULL) /* |len| can be zero */ - *va_arg(vl, int *) = 0; - else { - *va_arg(vl, int *) = maketexlstring(s,len); - } - break; - case CALLBACK_STRING: /* C string aka buffer */ - if (!lua_isstring(L,nres)) { - if (!lua_isnil(L,nres)) { - fprintf(stderr,"Expected a string for (S), not: %s\n", - lua_typename(L,lua_type(L,nres))); - goto EXIT; - } - } - s = (char *)lua_tolstring(L,nres,(size_t *)&len); - - if (s==NULL) /* |len| can be zero */ - *va_arg(vl, int *) = 0; - else { - ss = xmalloc(len+1); - (void)memcpy(ss,s,(len+1)); - *va_arg(vl, char **) = ss; - } - break; - default: - fprintf(stdout,"invalid return value type"); - goto EXIT; + ss = index(values, '>'); + assert(ss); + luaL_checkstack(L, (ss - values + 1), "out of stack space"); + ss = NULL; + for (narg = 0; *values; narg++) { + switch (*values++) { + case CALLBACK_CHARNUM: /* an ascii char! */ + cs = (char) va_arg(vl, int); + lua_pushlstring(L, &cs, 1); + break; + case CALLBACK_STRING: /* C string */ + s = va_arg(vl, char *); + lua_pushstring(L, s); + break; + case CALLBACK_INTEGER: /* int */ + lua_pushnumber(L, va_arg(vl, int)); + break; + case CALLBACK_STRNUMBER: /* TeX string */ + s = makeclstring(va_arg(vl, int), &len); + lua_pushlstring(L, s, len); + break; + case CALLBACK_BOOLEAN: /* boolean */ + lua_pushboolean(L, va_arg(vl, int)); + break; + case CALLBACK_LINE: /* a buffer section, with implied start */ + lua_pushlstring(L, (char *) (buffer + first), va_arg(vl, int)); + break; + case '-': + narg--; + break; + case '>': + goto ENDARGS; + default: + ; + } + } + ENDARGS: + nres = strlen(values); + if (special == 1) { + nres++; + } + if (special == 2) { + narg++; + } + { + int i; + lua_active++; + i = lua_pcall(L, narg, nres, 0); + lua_active--; + /* lua_remove(L, base); *//* remove traceback function */ + if (i != 0) { + /* Can't be more precise here, could be called before + * TeX initialization is complete + */ + if (!log_opened) { + fprintf(stderr, "This went wrong: %s\n", lua_tostring(L, -1)); + error(); + } else { + lua_gc(L, LUA_GCCOLLECT, 0); + luatex_error(L, (i == LUA_ERRRUN ? 0 : 1)); + } + return 0; + } + } + if (nres == 0) { + return 1; + } + nres = -nres; + while (*values) { + int b; + switch (*values++) { + case CALLBACK_BOOLEAN: + if (!lua_isboolean(L, nres)) { + fprintf(stderr, "Expected a boolean, not: %s\n", + lua_typename(L, lua_type(L, nres))); + goto EXIT; + } + b = lua_toboolean(L, nres); + *va_arg(vl, boolean *) = (boolean) b; + break; + case CALLBACK_INTEGER: + if (!lua_isnumber(L, nres)) { + fprintf(stderr, "Expected a number, not: %s\n", + lua_typename(L, lua_type(L, nres))); + goto EXIT; + } + b = lua_tonumber(L, nres); + *va_arg(vl, int *) = b; + break; + case CALLBACK_LINE: /* TeX line */ + if (!lua_isstring(L, nres)) { + if (!lua_isnil(L, nres)) + fprintf(stderr, "Expected a string for (l), not: %s\n", + lua_typename(L, lua_type(L, nres))); + goto EXIT; + } + s = lua_tolstring(L, nres, &len); + if (s != NULL) { /* |len| can be zero */ + bufloc = va_arg(vl, int *); + if (len != 0) { + ret = *bufloc; + check_buffer_overflow(ret + len); + strncpy((char *) (buffer + ret), s, len); + *bufloc += len; + /* while (len--) { buffer[(*bufloc)++] = *s++; } */ + while ((*bufloc) - 1 > ret && buffer[(*bufloc) - 1] == ' ') + (*bufloc)--; + } + } else { + bufloc = 0; + } + break; + case CALLBACK_STRNUMBER: /* TeX string */ + if (!lua_isstring(L, nres)) { + if (!lua_isnil(L, nres)) { + fprintf(stderr, "Expected a string for (s), not: %s\n", + lua_typename(L, lua_type(L, nres))); + goto EXIT; + } + } + s = lua_tolstring(L, nres, &len); + if (s == NULL) /* |len| can be zero */ + *va_arg(vl, int *) = 0; + else { + *va_arg(vl, int *) = maketexlstring(s, len); + } + break; + case CALLBACK_STRING: /* C string aka buffer */ + if (!lua_isstring(L, nres)) { + if (!lua_isnil(L, nres)) { + fprintf(stderr, "Expected a string for (S), not: %s\n", + lua_typename(L, lua_type(L, nres))); + goto EXIT; + } + } + s = lua_tolstring(L, nres, &len); + + if (s == NULL) /* |len| can be zero */ + *va_arg(vl, int *) = 0; + else { + ss = xmalloc(len + 1); + (void) memcpy(ss, s, (len + 1)); + *va_arg(vl, char **) = ss; + } + break; + default: + fprintf(stdout, "invalid return value type"); + goto EXIT; + } + nres++; } - nres++; - } - retval = 1; - EXIT: - return retval; + retval = 1; + EXIT: + return retval; } -void -destroy_saved_callback (int i) { - luaL_unref(Luas[0],LUA_REGISTRYINDEX,i); +void destroy_saved_callback(int i) +{ + luaL_unref(Luas, LUA_REGISTRYINDEX, i); } -static int callback_register (lua_State *L) { - int cb; - char *s; - if (!lua_isstring(L,1) || - ((!lua_isfunction(L,2)) && !lua_isnil(L,2))) { - lua_pushnil(L); - lua_pushstring(L,"Invalid arguments to callback.register."); - return 2; - } - s = (char *)lua_tostring(L,1); - for(cb=0;cb + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "nodes.h" +static const char _svn_version[] = + "$Id: lfontlib.c 1226 2008-05-02 16:11:02Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lfontlib.c $"; + /* this function is in vfovf.c for the moment */ -extern int make_vf_table(lua_State *L, char *name, scaled s); - -static int -font_read_tfm (lua_State *L) { - internalfontnumber f; - scaled s; - int k; - char *cnom; - if(lua_isstring(L, 1)) { - cnom = (char *)lua_tostring(L, 1); - if(lua_isnumber(L, 2)) { - s = (integer)lua_tonumber(L,2); - if (strlen(cnom)) { - f = new_font(); - if (read_tfm_info(f, cnom, "", s)) { - k = font_to_lua(L,f); - delete_font(f); - return k; - } else { - delete_font(f); - lua_pushstring(L, "font loading failed"); - lua_error(L); - } - } else { - lua_pushstring(L, "expected tfm name as first argument"); - lua_error(L); - } +extern int make_vf_table(lua_State * L, char *name, scaled s); + +static int font_read_tfm(lua_State * L) +{ + internalfontnumber f; + scaled s; + int k; + char *cnom; + if (lua_isstring(L, 1)) { + cnom = (char *) lua_tostring(L, 1); + if (lua_isnumber(L, 2)) { + s = (integer) lua_tonumber(L, 2); + if (strlen(cnom)) { + f = new_font(); + if (read_tfm_info(f, cnom, "", s)) { + k = font_to_lua(L, f); + delete_font(f); + return k; + } else { + delete_font(f); + lua_pushstring(L, "font loading failed"); + lua_error(L); + } + } else { + lua_pushstring(L, "expected tfm name as first argument"); + lua_error(L); + } + } else { + lua_pushstring(L, "expected an integer size as second argument"); + lua_error(L); + } } else { - lua_pushstring(L, "expected an integer size as second argument"); - lua_error(L); + lua_pushstring(L, "expected tfm name as first argument"); + lua_error(L); } - } else { - lua_pushstring(L, "expected tfm name as first argument"); - lua_error(L); - } - return 2; /* not reached */ + return 2; /* not reached */ } -static int -font_read_vf (lua_State *L) { - scaled s; - char *cnom; - if(lua_isstring(L, 1)) { - cnom = (char *)lua_tostring(L, 1); - if (strlen(cnom)) { - if(lua_isnumber(L, 2)) { - s = lua_tonumber(L,2); - return make_vf_table(L,cnom,s); - } else { - lua_pushstring(L, "expected an integer size as second argument"); - lua_error(L); - return 2; - } - } - } - lua_pushstring(L, "expected vf name as first argument"); - lua_error(L); - return 2; /* not reached */ +static int font_read_vf(lua_State * L) +{ + scaled s; + char *cnom; + if (lua_isstring(L, 1)) { + cnom = (char *) lua_tostring(L, 1); + if (strlen(cnom)) { + if (lua_isnumber(L, 2)) { + s = lua_tonumber(L, 2); + return make_vf_table(L, cnom, s); + } else { + lua_pushstring(L, + "expected an integer size as second argument"); + lua_error(L); + return 2; + } + } + } + lua_pushstring(L, "expected vf name as first argument"); + lua_error(L); + return 2; /* not reached */ } -static int -tex_current_font (lua_State *L) { - int i; - i = (int)luaL_optinteger(L,1,0); - if (i>0) { - if (is_valid_font(i)) { - zset_cur_font(i); - return 0; - } else { - lua_pushstring(L, "expected a valid font id"); - lua_error(L); - return 2; /* not reached */ - } - } else { - lua_pushnumber(L,get_cur_font()); - return 1; - } +static int tex_current_font(lua_State * L) +{ + int i; + i = (int) luaL_optinteger(L, 1, 0); + if (i > 0) { + if (is_valid_font(i)) { + zset_cur_font(i); + return 0; + } else { + lua_pushstring(L, "expected a valid font id"); + lua_error(L); + return 2; /* not reached */ + } + } else { + lua_pushnumber(L, get_cur_font()); + return 1; + } } -static int -tex_max_font (lua_State *L) { - lua_pushnumber(L,max_font_id()); - return 1; +static int tex_max_font(lua_State * L) +{ + lua_pushnumber(L, max_font_id()); + return 1; } -static int -tex_each_font_next (lua_State *L) { - int i,m; /* id */ - m = lua_tonumber(L,1); - i = lua_tonumber(L,2); - i++; - while(i<=m && !is_valid_font(i)) - i++; - if (i>m) { - lua_pushnil(L); - return 1; - } else { - lua_pushnumber(L, i); - font_to_lua (L, i); - return 2; - } +static int tex_each_font_next(lua_State * L) +{ + int i, m; /* id */ + m = lua_tonumber(L, 1); + i = lua_tonumber(L, 2); + i++; + while (i <= m && !is_valid_font(i)) + i++; + if (i > m) { + lua_pushnil(L); + return 1; + } else { + lua_pushnumber(L, i); + font_to_lua(L, i); + return 2; + } } -static int -tex_each_font (lua_State *L) { - lua_pushcclosure(L, tex_each_font_next, 0); - lua_pushnumber(L, max_font_id()); - lua_pushnumber(L, 0); - return 3; +static int tex_each_font(lua_State * L) +{ + lua_pushcclosure(L, tex_each_font_next, 0); + lua_pushnumber(L, max_font_id()); + lua_pushnumber(L, 0); + return 3; } -static int -frozenfont (lua_State *L) { - int i; - i = (int)luaL_checkinteger(L,1); - if (i) { - if (is_valid_font(i)) { - if (font_touched(i) || font_used(i)) { - lua_pushboolean(L,1); - } else { - lua_pushboolean(L,0); - } +static int frozenfont(lua_State * L) +{ + int i; + i = (int) luaL_checkinteger(L, 1); + if (i) { + if (is_valid_font(i)) { + if (font_touched(i) || font_used(i)) { + lua_pushboolean(L, 1); + } else { + lua_pushboolean(L, 0); + } + } else { + lua_pushnil(L); + } + return 1; } else { - lua_pushnil(L); + lua_pushstring(L, "expected an integer argument"); + lua_error(L); } - return 1; - } else { - lua_pushstring(L, "expected an integer argument"); - lua_error(L); - } - return 0; /* not reached */ + return 0; /* not reached */ } -static int -setfont (lua_State *L) { - int i; - i = (int)luaL_checkinteger(L,-2); - if (i) { - luaL_checktype(L,-1,LUA_TTABLE); - if (is_valid_font(i)) { - if (! (font_touched(i) || font_used(i))) { - font_from_lua (L,i) ; - } else { - lua_pushstring(L, "that font has been accessed already, changing it is forbidden"); - lua_error(L); - } - } else { - lua_pushstring(L, "that integer id is not a valid font"); - lua_error(L); +static int setfont(lua_State * L) +{ + int i; + i = (int) luaL_checkinteger(L, -2); + if (i) { + luaL_checktype(L, -1, LUA_TTABLE); + if (is_valid_font(i)) { + if (!(font_touched(i) || font_used(i))) { + font_from_lua(L, i); + } else { + lua_pushstring(L, + "that font has been accessed already, changing it is forbidden"); + lua_error(L); + } + } else { + lua_pushstring(L, "that integer id is not a valid font"); + lua_error(L); + } } - } - return 0; + return 0; } -static int -deffont (lua_State *L) { - int i; - luaL_checktype(L,-1,LUA_TTABLE); +static int deffont(lua_State * L) +{ + int i; + luaL_checktype(L, -1, LUA_TTABLE); - i = new_font(); - if(font_from_lua (L,i)) { - lua_pushnumber(L,i); - return 1; - } else { - lua_pop(L,1); /* pop the broken table */ - delete_font(i); - lua_pushstring(L, "font creation failed"); - lua_error(L); - } - return 0; /* not reached */ + i = new_font(); + if (font_from_lua(L, i)) { + lua_pushnumber(L, i); + return 1; + } else { + lua_pop(L, 1); /* pop the broken table */ + delete_font(i); + lua_pushstring(L, "font creation failed"); + lua_error(L); + } + return 0; /* not reached */ } /* this returns the expected (!) next fontid. */ -static int -nextfontid (lua_State *L) { - int i = new_font(); - lua_pushnumber(L,i); - delete_font(i); - return 1; +static int nextfontid(lua_State * L) +{ + int i = new_font(); + lua_pushnumber(L, i); + delete_font(i); + return 1; } -static int -getfont (lua_State *L) { - int i; - i = (int)luaL_checkinteger(L,-1); - if (i && is_valid_font(i) && font_to_lua (L, i)) +static int getfont(lua_State * L) +{ + int i; + i = (int) luaL_checkinteger(L, -1); + if (i && is_valid_font(i) && font_to_lua(L, i)) + return 1; + lua_pushnil(L); return 1; - lua_pushnil(L); - return 1; } -static const struct luaL_reg fontlib [] = { - {"read_tfm", font_read_tfm}, - {"read_vf", font_read_vf}, - {"current", tex_current_font}, - {"max", tex_max_font}, - {"each", tex_each_font}, - {"getfont", getfont}, - {"setfont", setfont}, - {"define", deffont}, - {"nextid", nextfontid}, - {"frozen", frozenfont}, - {NULL, NULL} /* sentinel */ +static const struct luaL_reg fontlib[] = { + {"read_tfm", font_read_tfm}, + {"read_vf", font_read_vf}, + {"current", tex_current_font}, + {"max", tex_max_font}, + {"each", tex_each_font}, + {"getfont", getfont}, + {"setfont", setfont}, + {"define", deffont}, + {"nextid", nextfontid}, + {"frozen", frozenfont}, + {NULL, NULL} /* sentinel */ }; -int luaopen_font (lua_State *L) +int luaopen_font(lua_State * L) { - luaL_register(L, "font", fontlib); - make_table(L,"fonts","getfont","setfont"); - return 1; + luaL_register(L, "font", fontlib); + make_table(L, "fonts", "getfont", "setfont"); + return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/limglib.c b/Build/source/texk/web2c/luatexdir/lua/limglib.c index 8f3f70ec718..44b3a04712d 100644 --- a/Build/source/texk/web2c/luatexdir/lua/limglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/limglib.c @@ -1,4 +1,21 @@ -/* $Id: limglib.c 1098 2008-03-09 10:28:19Z hhenkel $ */ +/* limglib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include #include @@ -9,16 +26,18 @@ #include "../image/image.h" #include "../luatex-api.h" +static const char _svn_version[] = + "$Id: limglib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/limglib.c $"; + /**********************************************************************/ #ifdef DEBUG -static void stackDump(lua_State * L, char *s) +void stackDump(lua_State * L, char *s) { - int i; - int top = lua_gettop(L); + int i, t, top = lua_gettop(L); printf("\n=== stackDump <%s>: ", s); - for (i = 1; i <= top; i++) { /* repeat for each level */ - int t = lua_type(L, i); + for (i = top; i >= 1; i--) { /* repeat for each level */ + t = lua_type(L, i); printf("%d: ", i); switch (t) { case LUA_TSTRING: /* strings */ @@ -42,10 +61,10 @@ static void stackDump(lua_State * L, char *s) /**********************************************************************/ -typedef enum { P__ZERO, P_ATTR, P_COLORDEPTH, P_COLORSPACE, P_DEPTH, P_FILENAME, - P_FILEPATH, P_HEIGHT, P_IMAGETYPE, P_INDEX, P_OBJNUM, P_PAGE, P_PAGEBOX, - P_TOTALPAGES, P_TRANSFORM, P_WIDTH, P_XRES, P_XSIZE, P_YRES, P_YSIZE, - P__SENTINEL +typedef enum { P__ZERO, P_ATTR, P_BBOX, P_COLORDEPTH, P_COLORSPACE, P_DEPTH, + P_FILENAME, P_FILEPATH, P_HEIGHT, P_IMAGETYPE, P_INDEX, P_OBJNUM, + P_PAGE, P_PAGEBOX, P_TOTALPAGES, P_ROTATION, P_STREAM, P_TRANSFORM, + P_WIDTH, P_XRES, P_XSIZE, P_YRES, P_YSIZE, P__SENTINEL } parm_idx; typedef struct { @@ -53,9 +72,10 @@ typedef struct { parm_idx idx; /* index within img_parms array */ } parm_struct; -parm_struct img_parms[] = { +const parm_struct img_parms[] = { {NULL, P__ZERO}, /* dummy; lua indices run from 1 */ {"attr", P_ATTR}, + {"bbox", P_BBOX}, {"colordepth", P_COLORDEPTH}, {"colorspace", P_COLORSPACE}, {"depth", P_DEPTH}, @@ -68,6 +88,8 @@ parm_struct img_parms[] = { {"page", P_PAGE}, {"pagebox", P_PAGEBOX}, {"pages", P_TOTALPAGES}, + {"rotation", P_ROTATION}, + {"stream", P_STREAM}, {"transform", P_TRANSFORM}, {"width", P_WIDTH}, {"xres", P_XRES}, @@ -77,8 +99,9 @@ parm_struct img_parms[] = { {NULL, P__SENTINEL} }; -#define imgtype_max 4 -const char *imgtype_s[] = { "none", "pdf", "png", "jpg", "jbig2", NULL }; +#define imgtype_max 5 +const char *imgtype_s[] = + { "none", "pdf", "png", "jpg", "jbig2", "stream", NULL }; #define pagebox_max 5 const char *pdfboxspec_s[] = @@ -94,7 +117,7 @@ static void image_to_lua(lua_State * L, image * a) lua_pushvalue(L, -1); /* k k u ... */ lua_gettable(L, LUA_ENVIRONINDEX); /* i? k u ... */ if (!lua_isnumber(L, -1)) /* !i k u ... */ - luaL_error(L, "image_to_lua not a valid image key: %s", + luaL_error(L, "image_to_lua(): %s is not a valid image key", lua_tostring(L, -2)); i = lua_tointeger(L, -1); /* i k u ... */ lua_pop(L, 2); /* u ... */ @@ -148,11 +171,17 @@ static void image_to_lua(lua_State * L, image * a) case P_TOTALPAGES: lua_pushinteger(L, img_totalpages(d)); break; - case P_XSIZE: - lua_pushinteger(L, img_xsize(d)); + case P_XSIZE: /* Modify by /Rotate only for output */ + if ((img_rotation(d) & 1) == 0) + lua_pushinteger(L, img_xsize(d)); + else + lua_pushinteger(L, img_ysize(d)); break; - case P_YSIZE: - lua_pushinteger(L, img_ysize(d)); + case P_YSIZE: /* Modify by /Rotate only for output */ + if ((img_rotation(d) & 1) == 0) + lua_pushinteger(L, img_ysize(d)); + else + lua_pushinteger(L, img_xsize(d)); break; case P_XRES: lua_pushinteger(L, img_xres(d)); @@ -160,6 +189,9 @@ static void image_to_lua(lua_State * L, image * a) case P_YRES: lua_pushinteger(L, img_yres(d)); break; + case P_ROTATION: + lua_pushinteger(L, img_rotation(d)); + break; case P_COLORSPACE: if (img_colorspace(d) == 0) lua_pushnil(L); @@ -175,7 +207,7 @@ static void image_to_lua(lua_State * L, image * a) case P_IMAGETYPE: j = img_type(d); if (j >= 0 && j <= imgtype_max) { - if (j == IMAGE_TYPE_NONE) + if (j == IMG_TYPE_NONE) lua_pushnil(L); else lua_pushstring(L, imgtype_s[j]); @@ -192,6 +224,27 @@ static void image_to_lua(lua_State * L, image * a) } else assert(0); break; + case P_BBOX: + if (!img_is_bbox(d)) { + img_bbox(d)[0] = img_xorig(d); + img_bbox(d)[1] = img_yorig(d); + img_bbox(d)[2] = img_xorig(d) + img_xsize(d); + img_bbox(d)[3] = img_yorig(d) + img_ysize(d); + } + lua_newtable(L); + lua_pushinteger(L, 1); + lua_pushinteger(L, img_bbox(d)[0]); + lua_settable(L, -3); + lua_pushinteger(L, 2); + lua_pushinteger(L, img_bbox(d)[1]); + lua_settable(L, -3); + lua_pushinteger(L, 3); + lua_pushinteger(L, img_bbox(d)[2]); + lua_settable(L, -3); + lua_pushinteger(L, 4); + lua_pushinteger(L, img_bbox(d)[3]); + lua_settable(L, -3); + break; case P_OBJNUM: if (img_objnum(d) == 0) lua_pushnil(L); @@ -204,6 +257,14 @@ static void image_to_lua(lua_State * L, image * a) else lua_pushinteger(L, img_index(d)); break; + case P_STREAM: + if (img_type(d) != IMG_TYPE_PDFSTREAM || img_pdfstream_ptr(d) == NULL + || img_pdfstream_stream(d) == NULL + || strlen(img_pdfstream_stream(d)) == 0) + lua_pushnil(L); + else + lua_pushstring(L, img_pdfstream_stream(d)); + break; default: assert(0); } /* v u ... */ @@ -217,7 +278,7 @@ static void lua_to_image(lua_State * L, image * a) lua_pushvalue(L, -2); /* k v k t ... */ lua_gettable(L, LUA_ENVIRONINDEX); /* i? v k t ... */ if (!lua_isnumber(L, -1)) /* !i v k t ... */ - luaL_error(L, "lua_to_image not a valid image key: %s", + luaL_error(L, "lua_to_image(): %s is not a valid image key", lua_tostring(L, -3)); i = lua_tointeger(L, -1); /* i v k t ... */ lua_pop(L, 1); /* v k t ... */ @@ -277,6 +338,8 @@ static void lua_to_image(lua_State * L, image * a) case P_FILENAME: if (img_state(d) >= DICT_FILESCANNED) luaL_error(L, "image.filename is now read-only"); + if (img_type(d) == IMG_TYPE_PDFSTREAM) + luaL_error(L, "image.filename can't be used with image.stream"); if (lua_isstring(L, -1)) { if (img_filename(d) != NULL) xfree(img_filename(d)); @@ -331,12 +394,49 @@ static void lua_to_image(lua_State * L, image * a) else luaL_error(L, "image.pagebox needs string or nil value"); break; + case P_BBOX: + if (img_state(d) >= DICT_FILESCANNED) + luaL_error(L, "image.bbox is now read-only"); + if (!lua_istable(L, -1)) + luaL_error(L, "image.bbox needs table value"); + if (lua_objlen(L, -1) != 4) + luaL_error(L, "image.bbox table must have exactly 4 elements"); + for (i = 1; i <= 4; i++) { /* v k t ... */ + lua_pushinteger(L, i); /* idx v k t ... */ + lua_gettable(L, -2); /* int v k t ... */ + if (lua_type(L, -1) == LUA_TNUMBER) + img_bbox(d)[i - 1] = lua_tointeger(L, -1); + else if (lua_type(L, -1) == LUA_TSTRING) + img_bbox(d)[i - 1] = + dimen_to_number(L, (char *) lua_tostring(L, -1)); + else + luaL_error(L, + "image.bbox table needs integer value or dimension string elements"); + lua_pop(L, 1); /* v k t ... */ + } + img_set_bbox(d); + img_unset_scaled(a); + break; + case P_STREAM: + if (img_filename(d) != NULL) + luaL_error(L, "image.stream can't be used with image.filename"); + if (img_state(d) >= DICT_FILESCANNED) + luaL_error(L, "image.stream is now read-only"); + if (img_pdfstream_ptr(d) == NULL) + new_img_pdfstream_struct(d); + if (img_pdfstream_stream(d) != NULL) + xfree(img_pdfstream_stream(d)); + img_pdfstream_stream(d) = xstrdup(lua_tostring(L, -1)); + img_type(d) = IMG_TYPE_PDFSTREAM; + img_unset_scaled(a); + break; case P_FILEPATH: case P_TOTALPAGES: case P_XSIZE: case P_YSIZE: case P_XRES: case P_YRES: + case P_ROTATION: case P_IMAGETYPE: case P_OBJNUM: case P_INDEX: @@ -389,24 +489,24 @@ void copy_image(lua_State * L, lua_Number scale) /**********************************************************************/ -static int l_new_image(lua_State * L) +int l_new_image(lua_State * L) { image *a, **aa; image_dict **add; if (lua_gettop(L) > 1) luaL_error(L, "img.new() needs maximum 1 argument"); - if (lua_gettop(L) == 1 && !lua_istable(L, 1)) + if (lua_gettop(L) == 1 && !lua_istable(L, -1)) luaL_error(L, "img.new() needs table as optional argument"); /* (t) */ aa = (image **) lua_newuserdata(L, sizeof(image *)); /* i (t) */ luaL_getmetatable(L, TYPE_IMG); /* m i (t) */ lua_setmetatable(L, -2); /* i (t) */ a = *aa = new_image(); - add = (image_dict **) lua_newuserdata(L, sizeof(image_dict *)); /* ad i (t) */ + add = (image_dict **) lua_newuserdata(L, sizeof(image_dict *)); /* ad i (t) */ luaL_getmetatable(L, TYPE_IMG_DICT); /* m ad i (t) */ lua_setmetatable(L, -2); /* ad i (t) */ img_dict(a) = *add = new_image_dict(); img_dictref(a) = luaL_ref(L, LUA_GLOBALSINDEX); /* i (t) */ - if (lua_gettop(L) != 1) { /* i t, else just i */ + if (lua_gettop(L) == 2) { /* i t, else just i */ lua_insert(L, -2); /* t i */ lua_pushnil(L); /* n t i (1st key for iterator) */ while (lua_next(L, -2) != 0) { /* v k t i */ @@ -423,40 +523,62 @@ static int l_copy_image(lua_State * L) if (lua_gettop(L) != 1) luaL_error(L, "img.copy() needs exactly 1 argument"); if (lua_istable(L, 1)) - l_new_image(L); /* image --- if everything worked well */ + (void) l_new_image(L); /* image --- if everything worked well */ else - copy_image(L, 1.0); /* image */ + (void) copy_image(L, 1.0); /* image */ return 1; /* image */ } +static void read_scale_img(lua_State * L, image * a) +{ + image_dict *ad; + assert(a != NULL); + ad = img_dict(a); + assert(ad != NULL); + if (img_state(ad) == DICT_NEW) { + if (img_type(ad) == IMG_TYPE_PDFSTREAM) + check_pdfstream_dict(ad); + else { + /* check_pdfminorversion() should not be here, as it belongs + * to the output functions, and it is too early here to start + * already the PDF file only for image file scanning; but + * it's needed as several fixed_* parameters are used early, + * e. g. by read_png_info(). */ + check_pdfminorversion(); + read_img(ad, get_pdf_minor_version(), + get_pdf_inclusion_errorlevel()); + img_unset_scaled(a); + } + } + fix_image_size(L, a); +} + static int l_scan_image(lua_State * L) { image *a, **aa; - image_dict *ad; if (lua_gettop(L) != 1) luaL_error(L, "img.scan() needs exactly 1 argument"); if (lua_istable(L, 1)) - l_new_image(L); /* image --- if everything worked well */ + (void) l_new_image(L); /* image --- if everything worked well */ aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */ a = *aa; - ad = img_dict(a); - if (img_state(ad) == DICT_NEW) { - read_img(ad, get_pdf_minor_version(), get_pdf_inclusion_errorlevel()); - img_unset_scaled(a); - } - fix_image_size(L, a); + check_pdfoutput(maketexstring("img.scan()"), true); + flush_str(last_tex_string); + read_scale_img(L, a); return 1; /* image */ } -/* these should go into some header file... */ -#define obj_type_ximage 8 +/* DANGER! these should go into some header file... */ +#define obj_type_ximage 7 #define obj_aux(a) obj_tab[a].int4 /* auxiliary pointer */ #define obj_data_ptr obj_aux /* pointer to |pdf_mem| */ static halfword img_to_node(image * a, integer ref) { - image_dict *ad = img_dict(a); + image_dict *ad; halfword n; + assert(a != NULL); + ad = img_dict(a); assert(ad != NULL); assert(img_objnum(ad) != 0); n = new_node(whatsit_node, pdf_refximage_node); @@ -467,44 +589,47 @@ static halfword img_to_node(image * a, integer ref) return n; } -typedef enum { WR_WRITE, WR_IMMEDIATEWRITE, WR_NODE } wrtype_e; +typedef enum { WR_WRITE, WR_IMMEDIATEWRITE, WR_NODE, WR_VF_IMG } wrtype_e; const char *wrtype_s[] = - { "img.write()", "img.immediatewrite()", "img.node()" }; + { "img.write()", "img.immediatewrite()", "img.node()", "write vf image" }; extern void lua_nodelib_push_fast(lua_State * L, halfword n); +static void setup_image(lua_State * L, image * a, wrtype_e writetype) +{ + image_dict *ad; + assert(a != NULL); + ad = img_dict(a); + check_pdfoutput(maketexstring(wrtype_s[writetype]), true); + flush_str(last_tex_string); + read_scale_img(L, a); + if (img_arrayidx(a) == -1) + img_arrayidx(a) = img_to_array(a); /* now a is read-only */ + if (img_objnum(ad) == 0) { /* latest needed just before out_img() */ + pdf_ximage_count++; + pdf_create_obj(obj_type_ximage, pdf_ximage_count); + img_objnum(ad) = obj_ptr; + img_index(ad) = pdf_ximage_count; + obj_data_ptr(obj_ptr) = img_arrayidx(a); + } +} + static void write_image_or_node(lua_State * L, wrtype_e writetype) { image *a, **aa; image_dict *ad; halfword n; - integer ref; if (lua_gettop(L) != 1) luaL_error(L, "%s needs exactly 1 argument", wrtype_s[writetype]); if (lua_istable(L, 1)) - l_new_image(L); /* image --- if everything worked well */ + (void) l_new_image(L); /* image --- if everything worked well */ aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */ a = *aa; ad = img_dict(a); - assert(ad != NULL); - if (img_state(ad) == DICT_NEW) { - read_img(ad, get_pdf_minor_version(), get_pdf_inclusion_errorlevel()); - img_unset_scaled(a); - } - fix_image_size(L, a); - check_pdfoutput(maketexstring(wrtype_s[writetype]), true); - flush_str(last_tex_string); - ref = img_to_array(a); - if (img_objnum(ad) == 0) { /* not strictly needed here, could be delayed until out_image() */ - pdf_ximage_count++; - pdf_create_obj(obj_type_ximage, pdf_ximage_count); - img_objnum(ad) = obj_ptr; - img_index(ad) = pdf_ximage_count; - obj_data_ptr(obj_ptr) = ref; - } + setup_image(L, a, writetype); switch (writetype) { case WR_WRITE: - n = img_to_node(a, ref); + n = img_to_node(a, img_arrayidx(a)); new_tail_append(n); break; /* image */ case WR_IMMEDIATEWRITE: @@ -514,7 +639,7 @@ static void write_image_or_node(lua_State * L, wrtype_e writetype) break; /* image */ case WR_NODE: /* image */ lua_pop(L, 1); /* - */ - n = img_to_node(a, ref); + n = img_to_node(a, img_arrayidx(a)); lua_nodelib_push_fast(L, n); break; /* node */ default: @@ -522,7 +647,6 @@ static void write_image_or_node(lua_State * L, wrtype_e writetype) } if (img_state(ad) < DICT_REFERED) img_state(ad) = DICT_REFERED; - img_set_refered(a); /* now image may not be freed by gc */ } static int l_write_image(lua_State * L) @@ -545,7 +669,7 @@ static int l_image_node(lua_State * L) static int l_image_keys(lua_State * L) { - parm_struct *p = img_parms + 1; + const parm_struct *p = img_parms + 1; if (lua_gettop(L) != 0) luaL_error(L, "img.keys() goes without argument"); lua_newtable(L); /* t */ @@ -600,6 +724,21 @@ static const struct luaL_Reg imglib[] = { {NULL, NULL} /* sentinel */ }; +/**********************************************************************/ + +void vf_out_image(unsigned i) +{ + image *a, **aa; + lua_State *L = Luas; /* ... */ + lua_rawgeti(L, LUA_GLOBALSINDEX, i); /* image ... */ + aa = (image **) luaL_checkudata(L, -1, TYPE_IMG); + a = *aa; + setup_image(L, a, WR_VF_IMG); /* image ... */ + assert(img_is_refered(a)); + output_image(img_arrayidx(a)); + lua_pop(L, 1); /* ... */ +} + /**********************************************************************/ /* Metamethods for image */ @@ -635,8 +774,10 @@ static int m_img_mul(lua_State * L) static int m_img_print(lua_State * L) { - image **aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); - image_dict *d = img_dict(*aa); + image **aa; + image_dict *d; + aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); + d = img_dict(*aa); if (img_pagename(d) != NULL && strlen(img_pagename(d)) != 0) lua_pushfstring(L, "", img_filename(d), img_pagename(d)); @@ -692,7 +833,7 @@ static const struct luaL_Reg img_dict_m[] = { /**********************************************************************/ -void preset_environment(lua_State * L, parm_struct * p) +void preset_environment(lua_State * L, const parm_struct * p) { int i; lua_newtable(L); /* t */ diff --git a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c index 5ec4dfed869..23bd37e2f5f 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c @@ -1,4 +1,21 @@ -/* $Id: lkpselib.c 1061 2008-02-20 09:51:04Z taco $ */ +/* lkpselib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include @@ -7,202 +24,298 @@ #include #include +static const char _svn_version[] = + "$Id: lkpselib.c 2093 2009-03-23 11:44:13Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lkpselib.c $"; + static const int filetypes[] = { - kpse_gf_format, - kpse_pk_format, - kpse_any_glyph_format, - kpse_tfm_format, - kpse_afm_format, - kpse_base_format, - kpse_bib_format, - kpse_bst_format, - kpse_cnf_format, - kpse_db_format, - kpse_fmt_format, - kpse_fontmap_format, - kpse_mem_format, - kpse_mf_format, - kpse_mfpool_format, - kpse_mft_format, - kpse_mp_format, - kpse_mppool_format, - kpse_mpsupport_format, - kpse_ocp_format, - kpse_ofm_format, - kpse_opl_format, - kpse_otp_format, - kpse_ovf_format, - kpse_ovp_format, - kpse_pict_format, - kpse_tex_format, - kpse_texdoc_format, - kpse_texpool_format, - kpse_texsource_format, - kpse_tex_ps_header_format, - kpse_troff_font_format, - kpse_type1_format, - kpse_vf_format, - kpse_dvips_config_format, - kpse_ist_format, - kpse_truetype_format, - kpse_type42_format, - kpse_web2c_format, - kpse_program_text_format, - kpse_program_binary_format, - kpse_miscfonts_format, - kpse_web_format, - kpse_cweb_format, - kpse_enc_format, - kpse_cmap_format, - kpse_sfd_format, - kpse_opentype_format, - kpse_pdftex_config_format, - kpse_lig_format, - kpse_texmfscripts_format }; + kpse_gf_format, + kpse_pk_format, + kpse_any_glyph_format, + kpse_tfm_format, + kpse_afm_format, + kpse_base_format, + kpse_bib_format, + kpse_bst_format, + kpse_cnf_format, + kpse_db_format, + kpse_fmt_format, + kpse_fontmap_format, + kpse_mem_format, + kpse_mf_format, + kpse_mfpool_format, + kpse_mft_format, + kpse_mp_format, + kpse_mppool_format, + kpse_mpsupport_format, + kpse_ocp_format, + kpse_ofm_format, + kpse_opl_format, + kpse_otp_format, + kpse_ovf_format, + kpse_ovp_format, + kpse_pict_format, + kpse_tex_format, + kpse_texdoc_format, + kpse_texpool_format, + kpse_texsource_format, + kpse_tex_ps_header_format, + kpse_troff_font_format, + kpse_type1_format, + kpse_vf_format, + kpse_dvips_config_format, + kpse_ist_format, + kpse_truetype_format, + kpse_type42_format, + kpse_web2c_format, + kpse_program_text_format, + kpse_program_binary_format, + kpse_miscfonts_format, + kpse_web_format, + kpse_cweb_format, + kpse_enc_format, + kpse_cmap_format, + kpse_sfd_format, + kpse_opentype_format, + kpse_pdftex_config_format, + kpse_lig_format, + kpse_texmfscripts_format, + kpse_lua_format +}; static const char *const filetypenames[] = { - "gf", - "pk", - "bitmap font", - "tfm", - "afm", - "base", - "bib", - "bst", - "cnf", - "ls-R", - "fmt", - "map", - "mem", - "mf", - "mfpool", - "mft", - "mp", - "mppool", - "MetaPost support", - "ocp", - "ofm", - "opl", - "otp", - "ovf", - "ovp", - "graphic/figure", - "tex", - "TeX system documentation", - "texpool", - "TeX system sources", - "PostScript header", - "Troff fonts", - "type1 fonts", - "vf", - "dvips config", - "ist", - "truetype fonts", - "type42 fonts", - "web2c files", - "other text files", - "other binary files", - "misc fonts", - "web", - "cweb", - "enc files", - "cmap files", - "subfont definition files", - "opentype fonts", - "pdftex config", - "lig files", - "texmfscripts", - NULL }; + "gf", + "pk", + "bitmap font", + "tfm", + "afm", + "base", + "bib", + "bst", + "cnf", + "ls-R", + "fmt", + "map", + "mem", + "mf", + "mfpool", + "mft", + "mp", + "mppool", + "MetaPost support", + "ocp", + "ofm", + "opl", + "otp", + "ovf", + "ovp", + "graphic/figure", + "tex", + "TeX system documentation", + "texpool", + "TeX system sources", + "PostScript header", + "Troff fonts", + "type1 fonts", + "vf", + "dvips config", + "ist", + "truetype fonts", + "type42 fonts", + "web2c files", + "other text files", + "other binary files", + "misc fonts", + "web", + "cweb", + "enc files", + "cmap files", + "subfont definition files", + "opentype fonts", + "pdftex config", + "lig files", + "texmfscripts", + "lua", + NULL +}; + + +#define KPATHSEA_METATABLE "luatex_kpathsea" /* set to 1 by the |program_name| function */ -int program_name_set = 0; +int program_name_set = 0; -#define TEST_PROGRAM_NAME_SET do { \ - if (! program_name_set) { \ +#define TEST_PROGRAM_NAME_SET do { \ + if (! program_name_set) { \ lua_pushstring(L, "Please call kpse.set_program_name() before using the library"); \ - return lua_error(L); \ - } \ + return lua_error(L); \ + } \ } while (0) -static int find_file (lua_State *L) { - int i; - char *st; - int ftype = kpse_tex_format; - int mexist = 0; - TEST_PROGRAM_NAME_SET; - if (!lua_isstring(L,1)) { - lua_pushstring(L, "not a file name"); - lua_error(L); - } - st = (char *)lua_tostring(L,1); - i = lua_gettop(L); - while (i>1) { - if (lua_isboolean (L,i)) { - mexist = lua_toboolean (L,i); - } else if (lua_isnumber (L,i)) { - mexist = lua_tonumber (L,i) ; - } else if (lua_isstring(L,i)) { - int op = luaL_checkoption(L, i, NULL, filetypenames); - ftype = filetypes[op]; +static int find_file(lua_State * L) +{ + int i; + char *st; + int ftype = kpse_tex_format; + int mexist = 0; + TEST_PROGRAM_NAME_SET; + if (!lua_isstring(L, 1)) { + lua_pushstring(L, "not a file name"); + lua_error(L); + } + st = (char *) lua_tostring(L, 1); + i = lua_gettop(L); + while (i > 1) { + if (lua_isboolean(L, i)) { + mexist = lua_toboolean(L, i); + } else if (lua_isnumber(L, i)) { + mexist = lua_tonumber(L, i); + } else if (lua_isstring(L, i)) { + int op = luaL_checkoption(L, i, NULL, filetypenames); + ftype = filetypes[op]; + } + i--; + } + if (ftype == kpse_pk_format || + ftype == kpse_gf_format || ftype == kpse_any_glyph_format) { + /* ret.format, ret.name, ret.dpi */ + kpse_glyph_file_type ret; + lua_pushstring(L, kpse_find_glyph(st, mexist, ftype, &ret)); + } else { + if (mexist > 0) + mexist = 1; + if (mexist < 0) + mexist = 0; + lua_pushstring(L, kpse_find_file(st, ftype, mexist)); + } + return 1; +} + + +static int lua_kpathsea_find_file(lua_State * L) +{ + int i; + int ftype = kpse_tex_format; + int mexist = 0; + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + char *st = (char *) luaL_checkstring(L, 2); + i = lua_gettop(L); + while (i > 2) { + if (lua_isboolean(L, i)) { + mexist = lua_toboolean(L, i); + } else if (lua_isnumber(L, i)) { + mexist = lua_tonumber(L, i); + } else if (lua_isstring(L, i)) { + int op = luaL_checkoption(L, i, NULL, filetypenames); + ftype = filetypes[op]; + } + i--; } - i--; - } - if (ftype==kpse_pk_format || - ftype==kpse_gf_format || - ftype==kpse_any_glyph_format) { - /* ret.format, ret.name, ret.dpi */ - kpse_glyph_file_type ret; - lua_pushstring(L, kpse_find_glyph (st,mexist, ftype, &ret)); - } else { - if (mexist>0) - mexist = 1; - if (mexist<0) - mexist = 0; - lua_pushstring(L, kpse_find_file (st,ftype,mexist)); - } - return 1; + if (ftype == kpse_pk_format || + ftype == kpse_gf_format || ftype == kpse_any_glyph_format) { + /* ret.format, ret.name, ret.dpi */ + kpse_glyph_file_type ret; + lua_pushstring(L, kpathsea_find_glyph(*kp, st, mexist, ftype, &ret)); + } else { + if (mexist > 0) + mexist = 1; + if (mexist < 0) + mexist = 0; + lua_pushstring(L, kpathsea_find_file(*kp, st, ftype, mexist)); + } + return 1; + +} + +static int show_path(lua_State * L) +{ + int op = luaL_checkoption(L, -1, "tex", filetypenames); + int user_format = filetypes[op]; + TEST_PROGRAM_NAME_SET; + if (!kpse_format_info[user_format].type) /* needed if arg was numeric */ + kpse_init_format(user_format); + lua_pushstring(L, kpse_format_info[user_format].path); + return 1; +} + +static int lua_kpathsea_show_path(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + int op = luaL_checkoption(L, -1, "tex", filetypenames); + int user_format = filetypes[op]; + if (!(*kp)->format_info[user_format].type) /* needed if arg was numeric */ + kpathsea_init_format(*kp, user_format); + lua_pushstring(L, (*kp)->format_info[user_format].path); + return 1; +} + +static int expand_path(lua_State * L) +{ + const char *st = luaL_checkstring(L, 1); + TEST_PROGRAM_NAME_SET; + lua_pushstring(L, kpse_path_expand(st)); + return 1; +} + +static int lua_kpathsea_expand_path(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + const char *st = luaL_checkstring(L, 2); + lua_pushstring(L, kpathsea_path_expand(*kp, st)); + return 1; +} + +static int expand_braces(lua_State * L) +{ + const char *st = luaL_checkstring(L, 1); + TEST_PROGRAM_NAME_SET; + lua_pushstring(L, kpse_brace_expand(st)); + return 1; } -static int show_path (lua_State *L) { - int op = luaL_checkoption(L, -1, "tex", filetypenames); - int user_format = filetypes[op]; - TEST_PROGRAM_NAME_SET; - if (!kpse_format_info[user_format].type) /* needed if arg was numeric */ - kpse_init_format (user_format); - lua_pushstring (L, kpse_format_info[user_format].path); - return 1; +static int lua_kpathsea_expand_braces(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + const char *st = luaL_checkstring(L, 2); + lua_pushstring(L, kpathsea_brace_expand(*kp, st)); + return 1; } -static int expand_path (lua_State *L) { - const char *st = luaL_checkstring(L,1); - TEST_PROGRAM_NAME_SET; - lua_pushstring(L, kpse_path_expand(st)); - return 1; +static int expand_var(lua_State * L) +{ + const char *st = luaL_checkstring(L, 1); + TEST_PROGRAM_NAME_SET; + lua_pushstring(L, kpse_var_expand(st)); + return 1; } -static int expand_braces (lua_State *L) { - const char *st = luaL_checkstring(L,1); - TEST_PROGRAM_NAME_SET; - lua_pushstring(L, kpse_brace_expand(st)); - return 1; +static int lua_kpathsea_expand_var(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + const char *st = luaL_checkstring(L, 2); + lua_pushstring(L, kpathsea_var_expand(*kp, st)); + return 1; } -static int expand_var (lua_State *L) { - const char *st = luaL_checkstring(L,1); - TEST_PROGRAM_NAME_SET; - lua_pushstring(L, kpse_var_expand(st)); - return 1; + +static int var_value(lua_State * L) +{ + const char *st = luaL_checkstring(L, 1); + TEST_PROGRAM_NAME_SET; + lua_pushstring(L, kpse_var_value(st)); + return 1; } -static int var_value (lua_State *L) { - const char *st = luaL_checkstring(L,1); - TEST_PROGRAM_NAME_SET; - lua_pushstring(L, kpse_var_value(st)); - return 1; +static int lua_kpathsea_var_value(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + const char *st = luaL_checkstring(L, 2); + lua_pushstring(L, kpathsea_var_value(*kp, st)); + return 1; } + /* Engine support is a bit of a problem, because we do not want * to interfere with the normal format discovery of |luatex|. * Current approach: run |os.setenv()| if you have to. @@ -210,63 +323,122 @@ static int var_value (lua_State *L) { extern int luainit; -static int set_program_name (lua_State *L) { - const char *exe_name = luaL_checkstring(L,1); - const char *prog_name = luaL_optstring(L,2,exe_name); - if (! program_name_set) { - kpse_set_program_name(exe_name, prog_name); - program_name_set = 1; - } else { - kpse_reset_program_name(prog_name); - } - /* fix up the texconfig entry */ - lua_checkstack(L,3); - lua_getglobal(L,"texconfig"); - if (lua_istable(L,-1)) { - lua_pushstring(L,"kpse_init"); - lua_pushboolean(L,0); - lua_rawset(L,-3); - } - lua_pop(L,1); - return 0; +static int set_program_name(lua_State * L) +{ + const char *exe_name = luaL_checkstring(L, 1); + const char *prog_name = luaL_optstring(L, 2, exe_name); + if (!program_name_set) { + kpse_set_program_name(exe_name, prog_name); + program_name_set = 1; + } else { + kpse_reset_program_name(prog_name); + } + /* fix up the texconfig entry */ + lua_checkstack(L, 3); + lua_getglobal(L, "texconfig"); + if (lua_istable(L, -1)) { + lua_pushstring(L, "kpse_init"); + lua_pushboolean(L, 0); + lua_rawset(L, -3); + } + lua_pop(L, 1); + return 0; +} + +static int init_prog(lua_State * L) +{ + const char *prefix = luaL_checkstring(L, 1); + unsigned dpi = luaL_checkinteger(L, 2); + const char *mode = luaL_checkstring(L, 3); + const char *fallback = luaL_optstring(L, 4, NULL); + TEST_PROGRAM_NAME_SET; + kpse_init_prog(prefix, dpi, mode, fallback); + return 0; } -static int init_prog (lua_State *L) { - const char *prefix = luaL_checkstring(L,1); - unsigned dpi = luaL_checkinteger(L,2); - const char *mode = luaL_checkstring(L,3); - const char *fallback = luaL_optstring(L,4,NULL); - TEST_PROGRAM_NAME_SET; - kpse_init_prog(prefix,dpi,mode,fallback); - return 0; +static int lua_kpathsea_init_prog(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + const char *prefix = luaL_checkstring(L, 2); + unsigned dpi = luaL_checkinteger(L, 3); + const char *mode = luaL_checkstring(L, 4); + const char *fallback = luaL_optstring(L, 5, NULL); + kpathsea_init_prog(*kp,prefix, dpi, mode, fallback); + return 0; } -static int readable_file (lua_State *L) { - const char *name = luaL_checkstring(L,1); - TEST_PROGRAM_NAME_SET; - lua_pushstring(L,(char *)kpse_readable_file (name)); - return 1; +static int readable_file(lua_State * L) +{ + const char *name = luaL_checkstring(L, 1); + TEST_PROGRAM_NAME_SET; + lua_pushstring(L, (char *) kpse_readable_file(name)); + return 1; } +static int lua_kpathsea_readable_file(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + const char *name = luaL_checkstring(L, 2); + lua_pushstring(L, (char *) kpathsea_readable_file(*kp,name)); + return 1; +} -static const struct luaL_reg kpselib [] = { - {"set_program_name", set_program_name}, - {"init_prog", init_prog}, - {"readable_file", readable_file}, - {"find_file", find_file}, - {"expand_path", expand_path}, - {"expand_var", expand_var}, - {"expand_braces",expand_braces}, - {"var_value",var_value}, - {"show_path",show_path}, - {NULL, NULL} /* sentinel */ -}; +static int lua_kpathsea_finish(lua_State * L) +{ + kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea_finish(*kp); + return 0; +} -int -luaopen_kpse (lua_State *L) +static int lua_kpathsea_new(lua_State * L) { - luaL_register(L,"kpse",kpselib); - return 1; + kpathsea kpse = NULL; + kpathsea *kp = NULL; + char *argv = (char *)luaL_checkstring(L,1); + char *liar = (char *)luaL_optstring(L,2,argv); + kpse = kpathsea_new(); + kpathsea_set_program_name(kpse, argv, liar); + kp = (kpathsea *)lua_newuserdata(L, sizeof(kpathsea *)); + *kp = kpse; + luaL_getmetatable(L, KPATHSEA_METATABLE); + lua_setmetatable(L, -2); + return 1; } +static const struct luaL_reg kpselib_m[] = { + {"__gc", lua_kpathsea_finish }, + {"init_prog", lua_kpathsea_init_prog }, + {"readable_file", lua_kpathsea_readable_file }, + {"find_file", lua_kpathsea_find_file }, + {"expand_path", lua_kpathsea_expand_path }, + {"expand_var", lua_kpathsea_expand_var }, + {"expand_braces", lua_kpathsea_expand_braces }, + {"var_value", lua_kpathsea_var_value }, + {"show_path", lua_kpathsea_show_path }, + {NULL, NULL} /* sentinel */ +}; + +static const struct luaL_reg kpselib_l[] = { + {"new", lua_kpathsea_new }, + {"set_program_name", set_program_name }, + {"init_prog", init_prog }, + {"readable_file", readable_file }, + {"find_file", find_file }, + {"expand_path", expand_path }, + {"expand_var", expand_var }, + {"expand_braces", expand_braces }, + {"var_value", var_value }, + {"show_path", show_path }, + {NULL, NULL} /* sentinel */ +}; + +int luaopen_kpse(lua_State * L) +{ + luaL_newmetatable(L, KPATHSEA_METATABLE); + lua_pushvalue(L, -1); + lua_setfield(L, -2,"__index"); + luaL_register(L, NULL, kpselib_m); + luaL_register(L, "kpse", kpselib_l); + return 1; +} diff --git a/Build/source/texk/web2c/luatexdir/lua/llanglib.c b/Build/source/texk/web2c/luatexdir/lua/llanglib.c index a5227afa1a0..6aa634525b5 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llanglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llanglib.c @@ -1,222 +1,275 @@ -/* -Copyright (c) 2007 Taco Hoekwater +/* llanglib.c + + Copyright 2006-2008 Taco Hoekwater -This file is part of luatex. + This file is part of LuaTeX. -luatex is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -luatex is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with luatex; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -This is llanglib.c -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "nodes.h" +static const char _svn_version[] = + "$Id: llanglib.c 1594 2008-11-28 13:32:48Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/llanglib.c $"; + #define LANG_METATABLE "luatex.lang" #define check_islang(L,b) (struct tex_language **)luaL_checkudata(L,b,LANG_METATABLE) -extern halfword *check_isnode (lua_State *L, int ud) ; +extern halfword *check_isnode(lua_State * L, int ud); -static int -lang_new (lua_State *L) { - struct tex_language **lang; - if (lua_gettop(L)==0) { - lang = lua_newuserdata(L, sizeof(struct tex_language *)); - *lang = new_language(); - if (!*lang) { - lua_pushstring(L,"lang.new(): no room for a new language"); - return lua_error(L); +static int lang_new(lua_State * L) +{ + struct tex_language **lang; + if (lua_gettop(L) == 0) { + lang = lua_newuserdata(L, sizeof(struct tex_language *)); + *lang = new_language(-1); + if (!*lang) { + lua_pushstring(L, "lang.new(): no room for a new language"); + return lua_error(L); + } + } else { + lang = lua_newuserdata(L, sizeof(struct tex_language *)); + *lang = get_language(lua_tonumber(L, 1)); + if (!*lang) { + lua_pushfstring(L, "lang.new(%d): undefined language", + lua_tonumber(L, 1)); + return lua_error(L); + } } - } else { - lang = lua_newuserdata(L, sizeof(struct tex_language *)); - *lang = get_language(lua_tonumber(L,1)); - } - luaL_getmetatable(L,LANG_METATABLE); - lua_setmetatable(L,-2); - return 1; + luaL_getmetatable(L, LANG_METATABLE); + lua_setmetatable(L, -2); + return 1; } -static int -lang_id (lua_State *L) { - struct tex_language **lang_ptr; - lang_ptr = check_islang(L,1); - lua_pushnumber(L,(*lang_ptr)->id); - return 1; +static int lang_id(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + lua_pushnumber(L, (*lang_ptr)->id); + return 1; } -static int -lang_patterns (lua_State *L) { - struct tex_language **lang_ptr; - lang_ptr = check_islang(L,1); - if (lua_gettop(L)!=1) { - if (!lua_isstring(L,2)) { - lua_pushstring(L,"lang.patterns(): argument should be a string"); - return lua_error(L); - } - load_patterns(*lang_ptr, (unsigned char *)lua_tostring(L,2)); - return 0; - } else { - if ((*lang_ptr)->patterns!=NULL) { - lua_pushstring(L,(char *)hnj_serialize((*lang_ptr)->patterns)); - } else { - lua_pushnil(L); - } - return 1; - } +static int lang_patterns(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_gettop(L) != 1) { + if (!lua_isstring(L, 2)) { + lua_pushstring(L, "lang.patterns(): argument should be a string"); + return lua_error(L); + } + load_patterns(*lang_ptr, (unsigned char *) lua_tostring(L, 2)); + return 0; + } else { + if ((*lang_ptr)->patterns != NULL) { + lua_pushstring(L, (char *) hnj_serialize((*lang_ptr)->patterns)); + } else { + lua_pushnil(L); + } + return 1; + } } -static int -lang_clear_patterns (lua_State *L) { - struct tex_language **lang_ptr; - lang_ptr = check_islang(L,1); - clear_patterns(*lang_ptr); - return 0; +static int lang_clear_patterns(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + clear_patterns(*lang_ptr); + return 0; } -static int -lang_hyphenation (lua_State *L) { - struct tex_language **lang_ptr; - lang_ptr = check_islang(L,1); - if (lua_gettop(L)!=1) { - if(!lua_isstring(L,2)) { - lua_pushstring(L,"lang.hyphenation(): argument should be a string"); - return lua_error(L); - } - load_hyphenation(*lang_ptr,(unsigned char *)lua_tostring(L,2)); - return 0; - } else { - if ((*lang_ptr)->exceptions!=0) { - lua_pushstring(L,exception_strings(*lang_ptr)); - } else { - lua_pushnil(L); - } - return 1; - } +static int lang_hyphenation(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_gettop(L) != 1) { + if (!lua_isstring(L, 2)) { + lua_pushstring(L, + "lang.hyphenation(): argument should be a string"); + return lua_error(L); + } + load_hyphenation(*lang_ptr, (unsigned char *) lua_tostring(L, 2)); + return 0; + } else { + if ((*lang_ptr)->exceptions != 0) { + lua_pushstring(L, exception_strings(*lang_ptr)); + } else { + lua_pushnil(L); + } + return 1; + } } -static int -lang_pre_hyphen_char (lua_State *L) { - struct tex_language **lang_ptr; - lang_ptr = check_islang(L,1); - if (lua_gettop(L)!=1) { - if(!lua_isnumber(L,2)) { - lua_pushstring(L,"lang.prehyphenchar(): argument should be a character number"); - return lua_error(L); - } - (*lang_ptr)->pre_hyphen_char = lua_tonumber(L,2); - return 0; - } else { - lua_pushnumber(L,(*lang_ptr)->pre_hyphen_char); - return 1; - } +static int lang_pre_hyphen_char(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_gettop(L) != 1) { + if (!lua_isnumber(L, 2)) { + lua_pushstring(L, + "lang.prehyphenchar(): argument should be a character number"); + return lua_error(L); + } + (*lang_ptr)->pre_hyphen_char = lua_tonumber(L, 2); + return 0; + } else { + lua_pushnumber(L, (*lang_ptr)->pre_hyphen_char); + return 1; + } } -static int -lang_post_hyphen_char (lua_State *L) { - struct tex_language **lang_ptr; - lang_ptr = check_islang(L,1); - if (lua_gettop(L)!=1) { - if(!lua_isnumber(L,2)) { - lua_pushstring(L,"lang.posthyphenchar(): argument should be a character number"); - return lua_error(L); - } - (*lang_ptr)->post_hyphen_char = lua_tonumber(L,2); - return 0; - } else { - lua_pushnumber(L,(*lang_ptr)->post_hyphen_char); - return 1; - } +static int lang_post_hyphen_char(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_gettop(L) != 1) { + if (!lua_isnumber(L, 2)) { + lua_pushstring(L, + "lang.posthyphenchar(): argument should be a character number"); + return lua_error(L); + } + (*lang_ptr)->post_hyphen_char = lua_tonumber(L, 2); + return 0; + } else { + lua_pushnumber(L, (*lang_ptr)->post_hyphen_char); + return 1; + } } -static int -lang_clear_hyphenation (lua_State *L) { - struct tex_language **lang_ptr; - lang_ptr = check_islang(L,1); - clear_hyphenation(*lang_ptr); - return 0; + +static int lang_pre_exhyphen_char(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_gettop(L) != 1) { + if (!lua_isnumber(L, 2)) { + lua_pushstring(L, + "lang.preexhyphenchar(): argument should be a character number"); + return lua_error(L); + } + (*lang_ptr)->pre_exhyphen_char = lua_tonumber(L, 2); + return 0; + } else { + lua_pushnumber(L, (*lang_ptr)->pre_exhyphen_char); + return 1; + } } +static int lang_post_exhyphen_char(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + if (lua_gettop(L) != 1) { + if (!lua_isnumber(L, 2)) { + lua_pushstring(L, + "lang.postexhyphenchar(): argument should be a character number"); + return lua_error(L); + } + (*lang_ptr)->post_exhyphen_char = lua_tonumber(L, 2); + return 0; + } else { + lua_pushnumber(L, (*lang_ptr)->post_exhyphen_char); + return 1; + } +} + + +static int lang_clear_hyphenation(lua_State * L) +{ + struct tex_language **lang_ptr; + lang_ptr = check_islang(L, 1); + clear_hyphenation(*lang_ptr); + return 0; +} -static int -do_lang_clean (lua_State *L) { - char *cleaned; - if (!lua_isstring(L,1)) { - lua_pushstring(L,"lang.clean(): argument should be a string"); - return lua_error(L); - } - (void)clean_hyphenation((char *)lua_tostring(L,1),&cleaned); - lua_pushstring(L,cleaned); - return 1; + +static int do_lang_clean(lua_State * L) +{ + char *cleaned; + if (!lua_isstring(L, 1)) { + lua_pushstring(L, "lang.clean(): argument should be a string"); + return lua_error(L); + } + (void) clean_hyphenation((char *) lua_tostring(L, 1), &cleaned); + lua_pushstring(L, cleaned); + return 1; } -static int -do_lang_hyphenate (lua_State *L) { - halfword *h,*t; - h = check_isnode(L,1); - if (lua_isuserdata(L,2)) { - t = check_isnode(L,2); - lua_pop(L,1); - } else { - t = h; - while (vlink(*t)!=null) - *t = vlink(*t); - } - hnj_hyphenation(*h,*t); - lua_pushboolean(L,1); - return 1; +static int do_lang_hyphenate(lua_State * L) +{ + halfword *h, *t; + h = check_isnode(L, 1); + if (lua_isuserdata(L, 2)) { + t = check_isnode(L, 2); + lua_pop(L, 1); + } else { + t = h; + while (vlink(*t) != null) + *t = vlink(*t); + } + hnj_hyphenation(*h, *t); + lua_pushboolean(L, 1); + return 1; } -static const struct luaL_reg langlib_d [] = { - {"clear_patterns", lang_clear_patterns}, - {"clear_hyphenation", lang_clear_hyphenation}, - {"patterns", lang_patterns}, - {"hyphenation", lang_hyphenation}, - {"prehyphenchar", lang_pre_hyphen_char}, - {"posthyphenchar", lang_post_hyphen_char}, - {"id", lang_id}, - {NULL, NULL} /* sentinel */ +static const struct luaL_reg langlib_d[] = { + /* *INDENT-OFF* */ + {"clear_patterns", lang_clear_patterns}, + {"clear_hyphenation", lang_clear_hyphenation}, + {"patterns", lang_patterns}, + {"hyphenation", lang_hyphenation}, + {"prehyphenchar", lang_pre_hyphen_char}, + {"posthyphenchar", lang_post_hyphen_char}, + {"preexhyphenchar", lang_pre_exhyphen_char}, + {"postexhyphenchar", lang_post_exhyphen_char}, + {"id", lang_id}, + /* *INDENT-ON* */ + {NULL, NULL} /* sentinel */ }; static const struct luaL_reg langlib[] = { - {"clear_patterns", lang_clear_patterns}, - {"clear_hyphenation", lang_clear_hyphenation}, - {"patterns", lang_patterns}, - {"hyphenation", lang_hyphenation}, - {"prehyphenchar", lang_pre_hyphen_char}, - {"posthyphenchar", lang_post_hyphen_char}, - {"id", lang_id}, - {"clean", do_lang_clean}, - {"hyphenate", do_lang_hyphenate}, - {"new", lang_new}, - {NULL, NULL} /* sentinel */ + /* *INDENT-OFF* */ + {"clear_patterns", lang_clear_patterns}, + {"clear_hyphenation", lang_clear_hyphenation}, + {"patterns", lang_patterns}, + {"hyphenation", lang_hyphenation}, + {"prehyphenchar", lang_pre_hyphen_char}, + {"posthyphenchar", lang_post_hyphen_char}, + {"preexhyphenchar", lang_pre_exhyphen_char}, + {"postexhyphenchar", lang_post_exhyphen_char}, + {"id", lang_id}, + {"clean", do_lang_clean}, + {"hyphenate", do_lang_hyphenate}, + {"new", lang_new}, + /* *INDENT-ON* */ + {NULL, NULL} /* sentinel */ }; -int -luaopen_lang (lua_State *L) { - luaL_newmetatable(L,LANG_METATABLE); - lua_pushvalue(L, -1); /* push metatable */ - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_register(L, NULL, langlib_d); /* dict methods */ - luaL_register(L, "lang", langlib); - return 1; +int luaopen_lang(lua_State * L) +{ + luaL_newmetatable(L, LANG_METATABLE); + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, langlib_d); /* dict methods */ + luaL_register(L, "lang", langlib); + return 1; } - diff --git a/Build/source/texk/web2c/luatexdir/lua/llualib.c b/Build/source/texk/web2c/luatexdir/lua/llualib.c index 90b1687f3b1..7efff052754 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llualib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llualib.c @@ -1,17 +1,36 @@ +/* llualib.c + + Copyright 2006-2008 Taco Hoekwater -/* $Id: llualib.c 1169 2008-04-15 14:57:56Z oneiros $ */ + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include +static const char _svn_version[] = + "$Id: llualib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/llualib.c $"; + #define LOAD_BUF_SIZE 256 #define UINT_MAX32 0xFFFFFFFF typedef struct { - unsigned char* buf; - int size; - int done; - int alloc; + unsigned char *buf; + int size; + int done; + int alloc; } bytecode; static bytecode *lua_bytecode_registers = NULL; @@ -19,211 +38,298 @@ static bytecode *lua_bytecode_registers = NULL; int luabytecode_max = -1; unsigned int luabytecode_bytes = 0; -void dump_luac_registers (void) { - int k,n; - bytecode b; - dump_int(luabytecode_max); - if (lua_bytecode_registers != NULL) { - n = 0; - for (k=0;k<=luabytecode_max;k++) { - if (lua_bytecode_registers[k].size != 0) - n++; - } - dump_int(n); - for (k=0;k<=luabytecode_max;k++) { - b = lua_bytecode_registers[k]; - if (b.size != 0) { - dump_int(k); - dump_int(b.size); - do_zdump ((char *)b.buf,1,(b.size), DUMP_FILE); - } - } - } +char *luanames[65536] = {NULL}; + +extern char *luanames[]; + +char * +get_lua_name (int i) +{ + if (i<0 || i>65535) + return NULL; + return luanames[i]; +} + +void dump_luac_registers(void) +{ + integer x; + int k, n; + bytecode b; + dump_int(luabytecode_max); + if (lua_bytecode_registers != NULL) { + n = 0; + for (k = 0; k <= luabytecode_max; k++) { + if (lua_bytecode_registers[k].size != 0) + n++; + } + dump_int(n); + for (k = 0; k <= luabytecode_max; k++) { + b = lua_bytecode_registers[k]; + if (b.size != 0) { + dump_int(k); + dump_int(b.size); + do_zdump((char *) b.buf, 1, (b.size), DUMP_FILE); + } + } + } + for (k = 0; k < 65536; k++) { + char *a = luanames[k]; + if (a!=NULL) { + x = strlen(a)+1; + dump_int(x); + dump_things(*a, x); + } else { + x = 0; + dump_int(x); + } + } } -void undump_luac_registers (void) { - int k,n; - unsigned int i; - bytecode b; - undump_int(luabytecode_max); - if (luabytecode_max>=0) { - i = (luabytecode_max+1); - if ((int)(UINT_MAX32/sizeof(bytecode)+1)<=i) { - lua_fatal_error(maketexstring("Corrupt format file")); - } - lua_bytecode_registers = xmalloc(i*sizeof(bytecode)); - luabytecode_bytes = i*sizeof(bytecode); - for (i=0;i<=(unsigned)luabytecode_max;i++) { - lua_bytecode_registers[i].done = 0; - lua_bytecode_registers[i].size = 0; - lua_bytecode_registers[i].buf = NULL; - } - undump_int(n); - for (i=0;i<(unsigned)n;i++) { - undump_int(k); - undump_int(b.size); - b.buf=xmalloc(b.size); - luabytecode_bytes += b.size; - memset(b.buf, 0, b.size); - do_zundump ((char *)b.buf,1, b.size, DUMP_FILE); - lua_bytecode_registers[k].size = b.size; - lua_bytecode_registers[k].alloc = b.size; - lua_bytecode_registers[k].buf = b.buf; - } - } +void undump_luac_registers(void) +{ + integer x; + int k, n; + unsigned int i; + bytecode b; + undump_int(luabytecode_max); + if (luabytecode_max >= 0) { + i = (luabytecode_max + 1); + if ((int) (UINT_MAX32 / sizeof(bytecode) + 1) <= i) { + lua_fatal_error(maketexstring("Corrupt format file")); + } + lua_bytecode_registers = xmalloc(i * sizeof(bytecode)); + luabytecode_bytes = i * sizeof(bytecode); + for (i = 0; i <= (unsigned) luabytecode_max; i++) { + lua_bytecode_registers[i].done = 0; + lua_bytecode_registers[i].size = 0; + lua_bytecode_registers[i].buf = NULL; + } + undump_int(n); + for (i = 0; i < (unsigned) n; i++) { + undump_int(k); + undump_int(b.size); + b.buf = xmalloc(b.size); + luabytecode_bytes += b.size; + memset(b.buf, 0, b.size); + do_zundump((char *) b.buf, 1, b.size, DUMP_FILE); + lua_bytecode_registers[k].size = b.size; + lua_bytecode_registers[k].alloc = b.size; + lua_bytecode_registers[k].buf = b.buf; + } + } + for (k = 0; k < 65536; k++) { + undump_int(x); + if (x > 0) { + char *s = xmalloc(x); + undump_things(*s, x); + luanames[k] = s; + } + } } -static void -bytecode_register_shadow_set (lua_State* L, int k){ - /* the stack holds the value to be set */ - lua_pushstring(L,"bytecode_shadow"); /* lua.bytecode_shadow */ - lua_rawget(L,LUA_REGISTRYINDEX); - if (lua_istable(L, -1)) { - lua_pushvalue(L,-2); - lua_rawseti(L,-2,k); - } - lua_pop(L,1); /* pop table or nil */ - lua_pop(L,1); /* pop value */ +static void bytecode_register_shadow_set(lua_State * L, int k) +{ + /* the stack holds the value to be set */ + lua_pushstring(L, "bytecode_shadow"); /* lua.bytecode_shadow */ + lua_rawget(L, LUA_REGISTRYINDEX); + if (lua_istable(L, -1)) { + lua_pushvalue(L, -2); + lua_rawseti(L, -2, k); + } + lua_pop(L, 1); /* pop table or nil */ + lua_pop(L, 1); /* pop value */ } -static int -bytecode_register_shadow_get (lua_State* L, int k){ - /* the stack holds the value to be set */ - int ret = 0; - lua_pushstring(L,"bytecode_shadow"); - lua_rawget(L,LUA_REGISTRYINDEX); - if (lua_istable(L, -1)) { - lua_rawgeti(L,-1,k); - if (!lua_isnil(L,-1)) - ret = 1; - lua_insert(L,-3); /* store the value or nil, deeper down */ - lua_pop(L,1); /* pop the value or nil at top */ - } - lua_pop(L,1); /* pop table or nil */ - return ret; +static int bytecode_register_shadow_get(lua_State * L, int k) +{ + /* the stack holds the value to be set */ + int ret = 0; + lua_pushstring(L, "bytecode_shadow"); + lua_rawget(L, LUA_REGISTRYINDEX); + if (lua_istable(L, -1)) { + lua_rawgeti(L, -1, k); + if (!lua_isnil(L, -1)) + ret = 1; + lua_insert(L, -3); /* store the value or nil, deeper down */ + lua_pop(L, 1); /* pop the value or nil at top */ + } + lua_pop(L, 1); /* pop table or nil */ + return ret; } -int writer(lua_State* L, const void* b, size_t size, void* B) { - bytecode* buf = (bytecode*)B; - if ((int)(buf->size + size) > buf->alloc) { - buf->buf = xrealloc(buf->buf,buf->alloc+size+LOAD_BUF_SIZE); - buf->alloc = buf->alloc+size+LOAD_BUF_SIZE; - } - memcpy(buf->buf+buf->size, b, size); - buf->size += size; - luabytecode_bytes += size; - return 0; +int writer(lua_State * L, const void *b, size_t size, void *B) +{ + bytecode *buf = (bytecode *) B; + (void)L; /* for -Wunused */ + if ((int) (buf->size + size) > buf->alloc) { + buf->buf = xrealloc(buf->buf, buf->alloc + size + LOAD_BUF_SIZE); + buf->alloc = buf->alloc + size + LOAD_BUF_SIZE; + } + memcpy(buf->buf + buf->size, b, size); + buf->size += size; + luabytecode_bytes += size; + return 0; } -const char* reader(lua_State* L, void* ud, size_t* size) { - bytecode* buf = (bytecode*)ud; - if (buf->done == buf->size) { - *size = 0; - buf->done = 0; - return NULL; - } - *size = buf->size; - buf->done = buf->size; - return (const char*)buf->buf; +const char *reader(lua_State * L, void *ud, size_t * size) +{ + bytecode *buf = (bytecode *) ud; + (void)L; /* for -Wunused */ + if (buf->done == buf->size) { + *size = 0; + buf->done = 0; + return NULL; + } + *size = buf->size; + buf->done = buf->size; + return (const char *) buf->buf; } -int get_bytecode (lua_State *L) { - int k; - k = (int)luaL_checkinteger(L,-1); - if (k<0) { - lua_pushnil(L); - } else if (!bytecode_register_shadow_get(L,k)) { - if (k<=luabytecode_max && lua_bytecode_registers[k].buf != NULL) { - if(lua_load(L,reader,(void *)(lua_bytecode_registers+k),"bytecode")) { - lua_error(L); - lua_pushnil(L); - } else { - lua_pushvalue(L,-1); - bytecode_register_shadow_set(L,k); - } - } else { - lua_pushnil(L); +int get_bytecode(lua_State * L) +{ + int k; + k = (int) luaL_checkinteger(L, -1); + if (k < 0) { + lua_pushnil(L); + } else if (!bytecode_register_shadow_get(L, k)) { + if (k <= luabytecode_max && lua_bytecode_registers[k].buf != NULL) { + if (lua_load + (L, reader, (void *) (lua_bytecode_registers + k), + "bytecode")) { + lua_error(L); + lua_pushnil(L); + } else { + lua_pushvalue(L, -1); + bytecode_register_shadow_set(L, k); + } + } else { + lua_pushnil(L); + } } - } - return 1; + return 1; } -int set_bytecode (lua_State *L) { - int k, ltype; - unsigned int i; - k = (int)luaL_checkinteger(L,-2); - i = k+1; - if ((int)(UINT_MAX32/sizeof(bytecode)+1)luabytecode_max) { - i = sizeof(bytecode)*(k+1); - lua_bytecode_registers = xrealloc(lua_bytecode_registers,i); - if (luabytecode_max==-1) { - luabytecode_bytes += sizeof(bytecode)*(k+1); - } else { - luabytecode_bytes += sizeof(bytecode)*(k+1-luabytecode_max); - } - for (i=(luabytecode_max+1);i<=(unsigned)k;i++) { - lua_bytecode_registers[i].buf=NULL; - lua_bytecode_registers[i].size=0; - lua_bytecode_registers[i].done=0; - } - luabytecode_max = k; - } - if (lua_bytecode_registers[k].buf != NULL) { - xfree(lua_bytecode_registers[k].buf); - luabytecode_bytes -= lua_bytecode_registers[k].size; - lua_bytecode_registers[k].buf = NULL; - lua_bytecode_registers[k].size=0; - lua_bytecode_registers[k].done=0; - lua_pushnil(L); - bytecode_register_shadow_set(L,k); - } - if (ltype == LUA_TFUNCTION) { - lua_bytecode_registers[k].buf=xmalloc(LOAD_BUF_SIZE); - lua_bytecode_registers[k].alloc = LOAD_BUF_SIZE; - memset(lua_bytecode_registers[k].buf, 0, LOAD_BUF_SIZE); - lua_dump(L,writer,(void *)(lua_bytecode_registers+k)); - } - lua_pop(L,1); - return 0; +int set_bytecode(lua_State * L) +{ + int k, ltype; + unsigned int i; + k = (int) luaL_checkinteger(L, -2); + i = k + 1; + if ((int) (UINT_MAX32 / sizeof(bytecode) + 1) < i) { + lua_pushstring(L, "value too large"); + lua_error(L); + } + if (k < 0) { + lua_pushstring(L, "negative values not allowed"); + lua_error(L); + } + ltype = lua_type(L, -1); + if (ltype != LUA_TFUNCTION && ltype != LUA_TNIL) { + lua_pushstring(L, "unsupported type"); + lua_error(L); + } + if (k > luabytecode_max) { + i = sizeof(bytecode) * (k + 1); + lua_bytecode_registers = xrealloc(lua_bytecode_registers, i); + if (luabytecode_max == -1) { + luabytecode_bytes += sizeof(bytecode) * (k + 1); + } else { + luabytecode_bytes += sizeof(bytecode) * (k + 1 - luabytecode_max); + } + for (i = (luabytecode_max + 1); i <= (unsigned) k; i++) { + lua_bytecode_registers[i].buf = NULL; + lua_bytecode_registers[i].size = 0; + lua_bytecode_registers[i].done = 0; + } + luabytecode_max = k; + } + if (lua_bytecode_registers[k].buf != NULL) { + xfree(lua_bytecode_registers[k].buf); + luabytecode_bytes -= lua_bytecode_registers[k].size; + lua_bytecode_registers[k].buf = NULL; + lua_bytecode_registers[k].size = 0; + lua_bytecode_registers[k].done = 0; + lua_pushnil(L); + bytecode_register_shadow_set(L, k); + } + if (ltype == LUA_TFUNCTION) { + lua_bytecode_registers[k].buf = xmalloc(LOAD_BUF_SIZE); + lua_bytecode_registers[k].alloc = LOAD_BUF_SIZE; + memset(lua_bytecode_registers[k].buf, 0, LOAD_BUF_SIZE); + lua_dump(L, writer, (void *) (lua_bytecode_registers + k)); + } + lua_pop(L, 1); + return 0; } -static const struct luaL_reg lualib [] = { - {"getbytecode", get_bytecode}, - {"setbytecode", set_bytecode}, - {NULL, NULL} /* sentinel */ -}; -int luaopen_lua (lua_State *L, int n, char *fname) +int set_luaname(lua_State * L) { - luaL_register(L, "lua", lualib); - make_table(L,"bytecode","getbytecode","setbytecode"); - lua_newtable(L); - lua_setfield(L, LUA_REGISTRYINDEX, "bytecode_shadow"); - lua_pushinteger(L, n); - lua_setfield(L, -2, "id"); - lua_pushstring(L, "0.1"); - lua_setfield(L, -2, "version"); - if (fname == NULL) { - lua_pushnil(L); - } else { - lua_pushstring(L, fname); - } - lua_setfield(L, -2, "startupfile"); - return 1; + int k; + char *s; + if (lua_gettop(L)==3) { + k = (int) luaL_checkinteger(L, 2); + if (k>65535 || k<0) { + /* error */ + } else { + if (luanames[k] != NULL) { + free(luanames[k]); + luanames[k] = NULL; + } + if (lua_isstring(L, 3)) { + s = (char *) lua_tostring(L,3); + if (s!=NULL) + luanames[k] = xstrdup(s); + } + } + } + return 0; } +int get_luaname(lua_State * L) +{ + int k; + k = (int) luaL_checkinteger(L, 2); + if (k>65535 || k<0) { + /* error */ + lua_pushnil(L); + } else { + if (luanames[k]!=NULL) + lua_pushstring(L, luanames[k]); + else + lua_pushnil(L); + } + return 1; +} + + + +static const struct luaL_reg lualib[] = { + /* *INDENT-OFF* */ + {"getluaname", get_luaname}, + {"setluaname", set_luaname}, + {"getbytecode", get_bytecode}, + {"setbytecode", set_bytecode}, + /* *INDENT-ON* */ + {NULL, NULL} /* sentinel */ +}; + +int luaopen_lua(lua_State * L, char *fname) +{ + luaL_register(L, "lua", lualib); + make_table(L, "bytecode", "getbytecode", "setbytecode"); + make_table(L, "name", "getluaname", "setluaname"); + lua_newtable(L); + lua_setfield(L, LUA_REGISTRYINDEX, "bytecode_shadow"); + lua_pushstring(L, LUA_VERSION); + lua_setfield(L, -2, "version"); + if (fname == NULL) { + lua_pushnil(L); + } else { + lua_pushstring(L, fname); + } + lua_setfield(L, -2, "startupfile"); + return 1; +} diff --git a/Build/source/texk/web2c/luatexdir/lua/lmplib.c b/Build/source/texk/web2c/luatexdir/lua/lmplib.c deleted file mode 100644 index b435618e97b..00000000000 --- a/Build/source/texk/web2c/luatexdir/lua/lmplib.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* $Id$ */ - -#include -#include -#include - -#ifndef pdfTeX -#include -#include -#include -#else -#include <../lua51/lua.h> -#include <../lua51/lauxlib.h> -#include <../lua51/lualib.h> -#endif - -#include "mplib.h" -#include "mpmp.h" -#include "mppsout.h" /* for mp_edge_object */ - -#define MPLIB_METATABLE "MPlib" -#define MPLIB_FIG_METATABLE "MPlib.fig" -#define MPLIB_GR_METATABLE "MPlib.gr" - -#define mplib_init_S(a) do { \ - lua_pushliteral(L,#a); \ - mplib_##a##_ptr = (char *)lua_tostring(L,-1); \ - mplib_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \ - } while (0) - -#define mplib_push_S(a) do { \ - lua_rawgeti(L,LUA_REGISTRYINDEX,mplib_##a##_index); \ - } while (0) - -#define mplib_is_S(a,i) (mplib_##a##_ptr==(char *)lua_tostring(L,i)) - -#define mplib_make_S(a) \ - static int mplib_##a##_index = 0; \ - static char *mplib_##a##_ptr = NULL - -static int mplib_type_Ses[mp_special_code+1] = {0}; /* [0] is not used */ - -mplib_make_S(fill); -mplib_make_S(outline); -mplib_make_S(text); -mplib_make_S(special); -mplib_make_S(start_bounds); -mplib_make_S(stop_bounds); -mplib_make_S(start_clip); -mplib_make_S(stop_clip); - -mplib_make_S(left_type); -mplib_make_S(right_type); -mplib_make_S(x_coord); -mplib_make_S(y_coord); -mplib_make_S(left_x); -mplib_make_S(left_y); -mplib_make_S(right_x); -mplib_make_S(right_y); - -mplib_make_S(color); -mplib_make_S(dash); -mplib_make_S(depth); -mplib_make_S(dsize); -mplib_make_S(font); -mplib_make_S(height); -mplib_make_S(htap); -mplib_make_S(linecap); -mplib_make_S(linejoin); -mplib_make_S(miterlimit); -mplib_make_S(path); -mplib_make_S(pen); -mplib_make_S(postscript); -mplib_make_S(prescript); -mplib_make_S(transform); -mplib_make_S(type); -mplib_make_S(width); - -void mplib_init_Ses(lua_State *L) { - mplib_init_S(fill); - mplib_init_S(outline); - mplib_init_S(text); - mplib_init_S(start_bounds); - mplib_init_S(stop_bounds); - mplib_init_S(start_clip); - mplib_init_S(stop_clip); - mplib_init_S(special); - - mplib_type_Ses[mp_fill_code] = mplib_fill_index; - mplib_type_Ses[mp_stroked_code] = mplib_outline_index; - mplib_type_Ses[mp_text_code] = mplib_text_index; - mplib_type_Ses[mp_start_bounds_code] = mplib_start_bounds_index; - mplib_type_Ses[mp_stop_bounds_code] = mplib_stop_bounds_index; - mplib_type_Ses[mp_start_clip_code] = mplib_start_clip_index; - mplib_type_Ses[mp_stop_clip_code] = mplib_stop_clip_index; - mplib_type_Ses[mp_special_code] = mplib_special_index; - - mplib_init_S(left_type); - mplib_init_S(right_type); - mplib_init_S(x_coord); - mplib_init_S(y_coord); - mplib_init_S(left_x); - mplib_init_S(left_y); - mplib_init_S(right_x); - mplib_init_S(right_y); - - mplib_init_S(color); - mplib_init_S(dash); - mplib_init_S(depth); - mplib_init_S(dsize); - mplib_init_S(font); - mplib_init_S(height); - mplib_init_S(htap); - mplib_init_S(linecap); - mplib_init_S(linejoin); - mplib_init_S(miterlimit); - mplib_init_S(path); - mplib_init_S(pen); - mplib_init_S(postscript); - mplib_init_S(prescript); - mplib_init_S(transform); - mplib_init_S(type); - mplib_init_S(width); -} - - - - -#define xfree(A) if ((A)!=NULL) { free((A)); A = NULL; } - -#define is_mp(L,b) (MP *)luaL_checkudata(L,b,MPLIB_METATABLE) -#define is_fig(L,b) (struct mp_edge_object **)luaL_checkudata(L,b,MPLIB_FIG_METATABLE) -#define is_gr_object(L,b) (struct mp_graphic_object **)luaL_checkudata(L,b,MPLIB_GR_METATABLE) - -/* Enumeration string arrays */ - -static const char *interaction_options[] = - { "unknown","batch","nonstop","scroll","errorstop", NULL}; - -static const char *mplib_filetype_names[] = - {"term", "error", "mp", "log", "ps", "mem", "tfm", "map", "pfb", "enc", NULL}; - -/* only "endpoint" and "explicit" actually happen in paths, - as well as "open" in elliptical pens */ - -static const char *knot_type_enum[] = - { "endpoint", "explicit", "given", "curl", "open", "end_cycle" }; - -/* object fields */ - -static const char *fill_fields[] = - { "type", "path", "htap", "pen", "color", "linejoin", "miterlimit", - "prescript", "postscript", NULL }; - -static const char *stroked_fields[] = - { "type", "path", "pen", "color", "linejoin", "miterlimit", "linecap", "dash", - "prescript", "postscript", NULL }; - -static const char *text_fields[] = - { "type", "text", "dsize", "font", "color", "width", "height", "depth", "transform", - "prescript", "postscript", NULL }; - -static const char *special_fields[] = - { "type", "prescript", NULL }; - -static const char *start_bounds_fields[] = - { "type", "path", NULL }; - -static const char *start_clip_fields[] = - { "type", "path", NULL }; - -static const char *stop_bounds_fields[] = - { "type", NULL }; - -static const char *stop_clip_fields[] = - { "type", NULL }; - -static const char *no_fields[] = - { NULL }; - -typedef enum { - P_ERROR_LINE, P_HALF_LINE, P_MAX_LINE, P_MAIN_MEMORY, - P_HASH_SIZE, P_HASH_PRIME, P_PARAM_SIZE, P_IN_OPEN, P_RANDOM_SEED, - P_INTERACTION, P_INI_VERSION, P_TROFF_MODE, P_PRINT_NAMES, P_MEM_NAME, - P_JOB_NAME, P_FIND_FILE, P__SENTINEL -} mplib_parm_idx; - -typedef struct { - const char *name; /* parameter name */ - mplib_parm_idx idx; /* parameter index */ -} mplib_parm_struct; - -static mplib_parm_struct mplib_parms[] = { - {"error_line", P_ERROR_LINE }, - {"half_error_line", P_HALF_LINE }, - {"max_print_line", P_MAX_LINE }, - {"main_memory", P_MAIN_MEMORY }, - {"hash_size", P_HASH_SIZE }, - {"hash_prime", P_HASH_PRIME }, - {"param_size", P_PARAM_SIZE }, - {"max_in_open", P_IN_OPEN }, - {"random_seed", P_RANDOM_SEED }, - {"interaction", P_INTERACTION }, - {"ini_version", P_INI_VERSION }, - {"troff_mode", P_TROFF_MODE }, - {"print_found_names", P_PRINT_NAMES }, - {"mem_name", P_MEM_NAME }, - {"job_name", P_JOB_NAME }, - {"find_file", P_FIND_FILE }, - {NULL, P__SENTINEL } -}; - -typedef struct _FILE_ITEM { - FILE *f; -} _FILE_ITEM ; - -typedef struct _FILE_ITEM File; - -#define make_stream_buf(A) char *A; size_t A##_size; size_t A##_used - -#define free_stream_buf(A) xfree(mplib_data->A); mplib_data->A##_size = 0; mplib_data->A##_used = 0 - -typedef struct _MPLIB_INSTANCE_DATA { - void *term_file_ptr; - void *err_file_ptr; - void *log_file_ptr; - void *ps_file_ptr; - make_stream_buf(term_out); - make_stream_buf(error_out); - make_stream_buf(log_out); - make_stream_buf(ps_out); - char *input_data; - char *input_data_ptr; - size_t input_data_len; - struct mp_edge_object *edges ; - lua_State *LL; -} _MPLIB_INSTANCE_DATA; - -typedef struct _MPLIB_INSTANCE_DATA mplib_instance; - -static mplib_instance *mplib_get_data (MP mp) { - return (mplib_instance *)mp->userdata; -} - -static mplib_instance *mplib_make_data (void) { - mplib_instance *mplib_data = malloc(sizeof(mplib_instance)); - memset(mplib_data,0,sizeof(mplib_instance)); - return mplib_data ; -} - - -/* Start by defining all the callback routines for the library - * except |run_make_mpx| and |run_editor|. - */ - - -char *mplib_find_file (MP mp, const char *fname, const char *fmode, int ftype) { - mplib_instance *mplib_data = mplib_get_data(mp); - lua_State *L = mplib_data->LL; - lua_checkstack(L,4); - lua_getfield(L,LUA_REGISTRYINDEX,"mplib_file_finder"); - if (lua_isfunction(L,-1)) { - char *s = NULL, *x = NULL; - lua_pushstring(L, fname); - lua_pushstring(L, fmode); - if (ftype >= mp_filetype_text) { - lua_pushnumber(L, ftype-mp_filetype_text); - } else { - lua_pushstring(L, mplib_filetype_names[ftype]); - } - if(lua_pcall(L,3,1,0) != 0) { - fprintf(stdout,"Error in mp.find_file: %s\n", (char *)lua_tostring(L,-1)); - return NULL; - } - x = (char *)lua_tostring(L,-1); - if (x!=NULL) - s = strdup(x); - lua_pop(L,1); /* pop the string */ - return s; - } else { - lua_pop(L,1); - } - if (fmode[0] != 'r' || (! access (fname,R_OK)) || ftype) { - return strdup(fname); - } - return NULL; -} - -static int -mplib_find_file_function (lua_State *L) { - if (! (lua_isfunction(L,-1)|| lua_isnil(L,-1) )) { - return 1; /* error */ - } - lua_pushstring(L, "mplib_file_finder"); - lua_pushvalue(L,-2); - lua_rawset(L,LUA_REGISTRYINDEX); - return 0; -} - -void *mplib_open_file(MP mp, const char *fname, const char *fmode, int ftype) { - File *ff = malloc(sizeof (File)); - if (ff) { - mplib_instance *mplib_data = mplib_get_data(mp); - ff->f = NULL; - if (ftype==mp_filetype_terminal) { - if (fmode[0] == 'r') { - ff->f = stdin; - } else { - xfree(mplib_data->term_file_ptr); - ff->f = malloc(1); - mplib_data->term_file_ptr = ff->f; - } - } else if (ftype==mp_filetype_error) { - xfree(mplib_data->err_file_ptr); - ff->f = malloc(1); - mplib_data->err_file_ptr = ff->f; - } else if (ftype == mp_filetype_log) { - xfree(mplib_data->log_file_ptr); - ff->f = malloc(1); - mplib_data->log_file_ptr = ff->f; - } else if (ftype == mp_filetype_postscript) { - xfree(mplib_data->ps_file_ptr); - ff->f = malloc(1); - mplib_data->ps_file_ptr = ff->f; - } else { - char realmode[3]; - char *f = mplib_find_file(mp, fname,fmode,ftype); - if (f==NULL) - return NULL; - realmode[0] = *fmode; - realmode[1] = 'b'; - realmode[2] = 0; - ff->f = fopen(f, realmode); - if ((fmode[0] == 'r') && (ff->f == NULL)) { - free(ff); - return NULL; - } - } - return ff; - } - return NULL; -} - -static int -mplib_get_char (void *f, mplib_instance *mplib_data) { - int c; - if (f==stdin && mplib_data->input_data != NULL) { - if (mplib_data->input_data_len==0) { - if (mplib_data->input_data_ptr!=NULL) - mplib_data->input_data_ptr = NULL; - else - mplib_data->input_data = NULL; - c = EOF; - } else { - mplib_data->input_data_len--; - c = *(mplib_data->input_data_ptr)++; - } - } else { - c = fgetc(f); - } - return c; -} - -static void -mplib_unget_char (void *f, mplib_instance *mplib_data, int c) { - if (f==stdin && mplib_data->input_data_ptr != NULL) { - mplib_data->input_data_len++; - mplib_data->input_data_ptr--; - } else { - ungetc(c,f); - } -} - - -char *mplib_read_ascii_file (MP mp, void *ff, size_t *size) { - char *s = NULL; - if (ff!=NULL) { - int c; - size_t len = 0, lim = 128; - mplib_instance *mplib_data = mplib_get_data(mp); - FILE *f = ((File *)ff)->f; - if (f==NULL) - return NULL; - *size = 0; - c = mplib_get_char(f,mplib_data); - if (c==EOF) - return NULL; - s = malloc(lim); - if (s==NULL) return NULL; - while (c!=EOF && c!='\n' && c!='\r') { - if (len==lim) { - s =realloc(s, (lim+(lim>>2))); - if (s==NULL) return NULL; - lim+=(lim>>2); - } - s[len++] = c; - c = mplib_get_char(f,mplib_data); - } - if (c=='\r') { - c = mplib_get_char(f,mplib_data); - if (c!=EOF && c!='\n') - mplib_unget_char(f,mplib_data,c); - } - s[len] = 0; - *size = len; - } - return s; -} - -#define APPEND_STRING(a,b) do { \ - if ((mplib_data->a##_used+strlen(b))>=mplib_data->a##_size) { \ - mplib_data->a##_size += 256+(mplib_data->a##_size)/5+strlen(b); \ - mplib_data->a = realloc(mplib_data->a,mplib_data->a##_size); \ - } \ - (void)strcpy(mplib_data->a+mplib_data->a##_used,b); \ - mplib_data->a##_used += strlen(b); \ - } while (0) - -void mplib_write_ascii_file (MP mp, void *ff, const char *s) { - if (ff!=NULL) { - void *f = ((File *)ff)->f; - mplib_instance *mplib_data = mplib_get_data(mp); - if (f!=NULL) { - if (f==mplib_data->term_file_ptr) { - APPEND_STRING(term_out,s); - } else if (f==mplib_data->err_file_ptr) { - APPEND_STRING(error_out,s); - } else if (f==mplib_data->log_file_ptr) { - APPEND_STRING(log_out,s); - } else if (f==mplib_data->ps_file_ptr) { - APPEND_STRING(ps_out,s); - } else { - fprintf((FILE *)f,"%s",s); - } - } - } -} - -void mplib_read_binary_file (MP mp, void *ff, void **data, size_t *size) { - (void)mp; - if (ff!=NULL) { - size_t len = 0; - FILE *f = ((File *)ff)->f; - if (f!=NULL) - len = fread(*data,1,*size,f); - *size = len; - } -} - -void mplib_write_binary_file (MP mp, void *ff, void *s, size_t size) { - (void)mp; - if (ff!=NULL) { - FILE *f = ((File *)ff)->f; - if (f!=NULL) - fwrite(s,size,1,f); - } -} - - -void mplib_close_file (MP mp, void *ff) { - if (ff!=NULL) { - mplib_instance *mplib_data = mplib_get_data(mp); - void *f = ((File *)ff)->f; - if (f != NULL && f != mplib_data->term_file_ptr && f != mplib_data->err_file_ptr - && f != mplib_data->log_file_ptr && f != mplib_data->ps_file_ptr) { - fclose(f); - } - free(ff); - } -} - -int mplib_eof_file (MP mp, void *ff) { - if (ff!=NULL) { - mplib_instance *mplib_data = mplib_get_data(mp); - FILE *f = ((File *)ff)->f; - if (f==NULL) - return 1; - if (f==stdin && mplib_data->input_data != NULL) { - return (mplib_data->input_data_len==0); - } - return feof(f); - } - return 1; -} - -void mplib_flush_file (MP mp, void *ff) { - (void)mp; - (void)ff; - return ; -} - -#define APPEND_TO_EDGES(a) do { \ - if (mplib_data->edges==NULL) { \ - mplib_data->edges = hh; \ - } else { \ - struct mp_edge_object *p = mplib_data->edges; \ - while (p->_next!=NULL) { p = p->_next; } \ - p->_next = hh; \ - } \ -} while (0) - -void mplib_shipout_backend (MP mp, int h) { - struct mp_edge_object *hh = mp_gr_export(mp, h); - if (hh) { - mplib_instance *mplib_data = mplib_get_data(mp); - APPEND_TO_EDGES(hh); - } -} - - -static void -mplib_setup_file_ops(struct MP_options * options) { - options->find_file = mplib_find_file; - options->open_file = mplib_open_file; - options->close_file = mplib_close_file; - options->eof_file = mplib_eof_file; - options->flush_file = mplib_flush_file; - options->write_ascii_file = mplib_write_ascii_file; - options->read_ascii_file = mplib_read_ascii_file; - options->write_binary_file = mplib_write_binary_file; - options->read_binary_file = mplib_read_binary_file; - options->shipout_backend = mplib_shipout_backend; -} - -static int -mplib_new (lua_State *L) { - MP *mp_ptr; - mp_ptr = lua_newuserdata(L, sizeof(MP *)); - if (mp_ptr) { - int i; - mplib_instance *mplib_data; - struct MP_options * options; /* instance options */ - options = mp_options(); - mplib_setup_file_ops(options); - mplib_data = mplib_make_data(); - mplib_data->LL = L; - options->userdata = (void *)mplib_data; - options->noninteractive = 1; /* required ! */ - options->print_found_names = 0; - if (lua_type(L,1)==LUA_TTABLE) { - for (i=0;mplib_parms[i].name!=NULL;i++) { - lua_getfield(L,1,mplib_parms[i].name); - if (lua_isnil(L,-1)) { - lua_pop(L,1); - continue; /* skip unset */ - } - switch(mplib_parms[i].idx) { - case P_ERROR_LINE: - options->error_line = lua_tointeger(L,-1); - break; - case P_HALF_LINE: - options->half_error_line = lua_tointeger(L,-1); - break; - case P_MAX_LINE: - options->max_print_line = lua_tointeger(L,-1); - break; - case P_MAIN_MEMORY: - options->main_memory = lua_tointeger(L,-1); - break; - case P_HASH_SIZE: - options->hash_size = lua_tointeger(L,-1); - break; - case P_HASH_PRIME: - options->hash_prime = lua_tointeger(L,-1); - break; - case P_PARAM_SIZE: - options->param_size = lua_tointeger(L,-1); - break; - case P_IN_OPEN: - options->max_in_open = lua_tointeger(L,-1); - break; - case P_RANDOM_SEED: - options->random_seed = lua_tointeger(L,-1); - break; - case P_INTERACTION: - options->interaction = luaL_checkoption(L,-1,"errorstopmode", interaction_options); - break; - case P_INI_VERSION: - options->ini_version = lua_toboolean(L,-1); - break; - case P_TROFF_MODE: - options->troff_mode = lua_toboolean(L,-1); - break; - case P_PRINT_NAMES: - options->print_found_names = lua_toboolean(L,-1); - break; - /* - case P_COMMAND_LINE: - options->command_line = strdup((char *)lua_tostring(L,-1)); - break; - */ - case P_MEM_NAME: - options->mem_name = strdup((char *)lua_tostring(L,-1)); - break; - case P_JOB_NAME: - options->job_name = strdup((char *)lua_tostring(L,-1)); - break; - case P_FIND_FILE: - if(mplib_find_file_function(L)) { /* error here */ - fprintf(stdout,"Invalid arguments to mp.new({find_file=...})\n"); - } - break; - default: - break; - } - lua_pop(L,1); - } - } - *mp_ptr = mp_new(options); - xfree(options->command_line); - xfree(options->mem_name); - xfree(options->job_name); - free(options); - if (*mp_ptr) { - luaL_getmetatable(L,MPLIB_METATABLE); - lua_setmetatable(L,-2); - return 1; - } - } - lua_pushnil(L); - return 1; -} - -static int -mplib_collect (lua_State *L) { - MP *mp_ptr = is_mp(L,1); - xfree(*mp_ptr); - return 0; -} - -static int -mplib_tostring (lua_State *L) { - MP *mp_ptr = is_mp(L,1); - if (*mp_ptr!=NULL) { - lua_pushfstring(L,"",*mp_ptr); - return 1; - } - return 0; -} - -static int -mplib_wrapresults(lua_State *L, mplib_instance *mplib_data, int h) { - lua_checkstack(L,5); - lua_newtable(L); - if (mplib_data->term_out != NULL) { - lua_pushstring(L,mplib_data->term_out); - lua_setfield(L,-2,"term"); - free_stream_buf(term_out); - } - if (mplib_data->error_out != NULL) { - lua_pushstring(L,mplib_data->error_out); - lua_setfield(L,-2,"error"); - free_stream_buf(error_out); - } - if (mplib_data->log_out != NULL ) { - lua_pushstring(L,mplib_data->log_out); - lua_setfield(L,-2,"log"); - free_stream_buf(log_out); - } - if (mplib_data->edges != NULL ) { - struct mp_edge_object **v; - struct mp_edge_object *p = mplib_data->edges; - int i = 1; - lua_newtable(L); - while (p!=NULL) { - v = lua_newuserdata (L, sizeof(struct mp_edge_object *)); - *v = p; - luaL_getmetatable(L,MPLIB_FIG_METATABLE); - lua_setmetatable(L,-2); - lua_rawseti(L,-2,i); i++; - p = p->_next; - } - lua_setfield(L,-2,"fig"); - mplib_data->edges = NULL; - } - lua_pushnumber(L,h); - lua_setfield(L,-2,"status"); - return 1; -} - -static int -mplib_execute (lua_State *L) { - MP *mp_ptr = is_mp(L,1); - if (*mp_ptr!=NULL && lua_isstring(L,2)) { - int h; - mplib_instance *mplib_data = mplib_get_data(*mp_ptr); - mplib_data->input_data = (char *)lua_tolstring(L,2, &(mplib_data->input_data_len)); - mplib_data->input_data_ptr = mplib_data->input_data; - if ((*mp_ptr)->run_state==0) { - h = mp_initialize(*mp_ptr); - } - h = mp_execute(*mp_ptr); - if (mplib_data->input_data_len!=0) { - mplib_data->input_data = NULL; - mplib_data->input_data_ptr = NULL; - mplib_data->input_data_len=0; - } - return mplib_wrapresults(L, mplib_data, h); - } else { - lua_pushnil(L); - } - return 1; -} - -static int -mplib_finish (lua_State *L) { - MP *mp_ptr = is_mp(L,1); - if (*mp_ptr!=NULL) { - mplib_instance *mplib_data = mplib_get_data(*mp_ptr); - int h = mp_finish(*mp_ptr); - return mplib_wrapresults(L, mplib_data, h); - } else { - lua_pushnil(L); - } - return 1; -} - -static int -mplib_statistics (lua_State *L) { - MP *mp_ptr = is_mp(L,1); - if (*mp_ptr!=NULL) { - lua_newtable(L); - lua_pushnumber(L, mp_memory_usage (*mp_ptr)); - lua_setfield(L,-2,"main_memory"); - lua_pushnumber(L, mp_hash_usage (*mp_ptr)); - lua_setfield(L,-2,"hash_size"); - lua_pushnumber(L, mp_param_usage (*mp_ptr)); - lua_setfield(L,-2,"param_size"); - lua_pushnumber(L, mp_open_usage (*mp_ptr)); - lua_setfield(L,-2,"max_in_open"); - } else { - lua_pushnil(L); - } - return 1; -} - - -/* figure methods */ - -static int -mplib_fig_collect (lua_State *L) { - struct mp_edge_object **hh = is_fig(L,1); - if (*hh!=NULL) { - mp_gr_toss_objects (*hh); - *hh=NULL; - } - return 0; -} - -static int -mplib_fig_body (lua_State *L) { - int i = 1; - struct mp_graphic_object **v; - struct mp_graphic_object *p; - struct mp_edge_object **hh = is_fig(L,1); - lua_newtable(L); - p = (*hh)->body; - while (p!=NULL) { - v = lua_newuserdata (L, sizeof(struct mp_graphic_object *)); - *v = p; - luaL_getmetatable(L,MPLIB_GR_METATABLE); - lua_setmetatable(L,-2); - lua_rawseti(L,-2,i); i++; - p = p->_link_field; - } - (*hh)->body = NULL; /* prevent double free */ - return 1; -} - -static int -mplib_fig_copy_body (lua_State *L) { - int i = 1; - struct mp_graphic_object **v; - struct mp_graphic_object *p; - struct mp_edge_object **hh = is_fig(L,1); - lua_newtable(L); - p = (*hh)->body; - while (p!=NULL) { - v = lua_newuserdata (L, sizeof(struct mp_graphic_object *)); - *v = mp_gr_copy_object((*hh)->_parent,p); - luaL_getmetatable(L,MPLIB_GR_METATABLE); - lua_setmetatable(L,-2); - lua_rawseti(L,-2,i); i++; - p = p->_link_field; - } - return 1; -} - - -static int -mplib_fig_tostring (lua_State *L) { - struct mp_edge_object **hh = is_fig(L,1); - lua_pushfstring(L,"
",*hh); - return 1; -} - - - -static int -mp_wrapped_shipout (struct mp_edge_object *hh, int prologues, int procset) { - MP mp = hh->_parent; - if (setjmp(mp->jump_buf)) { - return 0; - } - mp_gr_ship_out(hh,prologues,procset); - return 1; -} - -static int -mplib_fig_postscript (lua_State *L) { - struct mp_edge_object **hh = is_fig(L,1); - int prologues = luaL_optnumber(L,2,-1); - int procset = luaL_optnumber(L,3,-1); - mplib_instance *mplib_data = mplib_get_data((*hh)->_parent); - if (mplib_data->ps_out == NULL) { - if (mp_wrapped_shipout(*hh,prologues, procset)) { - if (mplib_data->ps_out!=NULL ) { - lua_pushstring(L, mplib_data->ps_out); - free_stream_buf(ps_out); - } else { - lua_pushnil(L); - } - return 1; - } else { - lua_pushnil(L); - lua_pushstring(L,mplib_data->log_out); - xfree(mplib_data->ps_out); - return 2; - } - } - lua_pushnil(L); - return 1; -} - -static int -mplib_fig_filename (lua_State *L) { - struct mp_edge_object **hh = is_fig(L,1); - if (*hh!= NULL) { - char *s = (*hh)->_filename; - lua_pushstring(L,s); - } else { - lua_pushnil(L); - } - return 1; -} - - -static int -mplib_fig_bb (lua_State *L) { - struct mp_edge_object **hh = is_fig(L,1); - lua_newtable(L); - lua_pushnumber(L, (double)(*hh)->_minx/65536.0); - lua_rawseti(L,-2,1); - lua_pushnumber(L, (double)(*hh)->_miny/65536.0); - lua_rawseti(L,-2,2); - lua_pushnumber(L, (double)(*hh)->_maxx/65536.0); - lua_rawseti(L,-2,3); - lua_pushnumber(L, (double)(*hh)->_maxy/65536.0); - lua_rawseti(L,-2,4); - return 1; -} - -/* object methods */ - -static int -mplib_gr_collect (lua_State *L) { - struct mp_graphic_object **hh = is_gr_object(L,1); - if (*hh!=NULL) { - mp_gr_toss_object(*hh); - *hh=NULL; - } - return 0; -} - -static int -mplib_gr_tostring (lua_State *L) { - struct mp_graphic_object **hh = is_gr_object(L,1); - lua_pushfstring(L,"",*hh); - return 1; -} - - -static int -mplib_gr_fields (lua_State *L) { - const char **fields; - int i ; - struct mp_graphic_object **hh = is_gr_object(L,1); - if (*hh) { - switch ((*hh)->_type_field) { - case mp_fill_code: fields = fill_fields; break; - case mp_stroked_code: fields = stroked_fields; break; - case mp_text_code: fields = text_fields; break; - case mp_special_code: fields = special_fields; break; - case mp_start_clip_code: fields = start_clip_fields; break; - case mp_start_bounds_code: fields = start_bounds_fields; break; - case mp_stop_clip_code: fields = stop_clip_fields; break; - case mp_stop_bounds_code: fields = stop_bounds_fields; break; - default: fields = no_fields; - } - lua_newtable(L); - for (i=0;fields[i]!=NULL;i++) { - lua_pushstring(L,fields[i]); - lua_rawseti(L,-2,(i+1)); - } - } else { - lua_pushnil(L); - } - return 1; -} - - -#define mplib_push_number(L,x) lua_pushnumber(L,(lua_Number)(x)/65536.0) - -#define MPLIB_PATH 0 -#define MPLIB_PEN 1 - -static void -mplib_push_path (lua_State *L, struct mp_knot *h, int is_pen) { - struct mp_knot *p; /* for scanning the path */ - int i=1; - p=h; - if (p!=NULL) { - lua_newtable(L); - do { - lua_createtable(L,0,6); - if (!is_pen) { - if (p->left_type_field != mp_explicit) { - mplib_push_S(left_type); - lua_pushstring(L,knot_type_enum[p->left_type_field]); - lua_rawset(L,-3); - } - if (p->right_type_field != mp_explicit) { - mplib_push_S(right_type); - lua_pushstring(L,knot_type_enum[p->right_type_field]); - lua_rawset(L,-3); - } - } - mplib_push_S(x_coord); - mplib_push_number(L,p->x_coord_field); - lua_rawset(L,-3); - mplib_push_S(y_coord); - mplib_push_number(L,p->y_coord_field); - lua_rawset(L,-3); - mplib_push_S(left_x); - mplib_push_number(L,p->left_x_field); - lua_rawset(L,-3); - mplib_push_S(left_y); - mplib_push_number(L,p->left_y_field); - lua_rawset(L,-3); - mplib_push_S(right_x); - mplib_push_number(L,p->right_x_field); - lua_rawset(L,-3); - mplib_push_S(right_y); - mplib_push_number(L,p->right_y_field); - lua_rawset(L,-3); - lua_rawseti(L,-2,i); i++; - if ( p->right_type_field==mp_endpoint ) { - return; - } - p=p->next_field; - } while (p!=h) ; - } else { - lua_pushnil(L); - } -} - -/* this assumes that the top of the stack is a table - or nil already in the case - */ -static void -mplib_push_pentype (lua_State *L, struct mp_knot *h) { - struct mp_knot *p; /* for scanning the path */ - p=h; - if (p==NULL) { - /* do nothing */ - } else if (p==p->next_field) { - mplib_push_S(type); - lua_pushstring(L,"elliptical"); - lua_rawset(L,-3); - } else { - } -} - -#define set_color_objects(pq) \ - object_color_model = pq->color_model_field; \ - object_color_a = pq->color_field._a_val; \ - object_color_b = pq->color_field._b_val; \ - object_color_c = pq->color_field._c_val; \ - object_color_d = pq->color_field._d_val; - - -static void -mplib_push_color (lua_State *L, struct mp_graphic_object *p ) { - int object_color_model; - int object_color_a, object_color_b, object_color_c, object_color_d ; - if (p!=NULL) { - if (p->_type_field == mp_fill_code) { - mp_fill_object *h = (mp_fill_object *)p; - set_color_objects(h); - } else if (p->_type_field == mp_stroked_code) { - mp_stroked_object *h = (mp_stroked_object *)p; - set_color_objects(h); - } else { - mp_text_object *h = (mp_text_object *)p; - set_color_objects(h); - } - lua_newtable(L); - if (object_color_model >= mp_grey_model) { - mplib_push_number(L,object_color_a); - lua_rawseti(L,-2,1); - if (object_color_model >= mp_rgb_model) { - mplib_push_number(L,object_color_b); - lua_rawseti(L,-2,2); - mplib_push_number(L,object_color_c); - lua_rawseti(L,-2,3); - if (object_color_model == mp_cmyk_model) { - mplib_push_number(L,object_color_d); - lua_rawseti(L,-2,4); - } - } - } - } else { - lua_pushnil(L); - } -} - -/* the dash scale is not exported, the field has no external value */ -static void -mplib_push_dash (lua_State *L, struct mp_stroked_object *h ) { - mp_dash_object *d; - double ds; - if (h!=NULL && h->dash_p_field != NULL) { - d = h->dash_p_field; - lua_newtable(L); - mplib_push_number(L,d->offset_field); - lua_setfield(L,-2,"offset"); - if (d->array_field!=NULL ) { - int i = 0; - lua_newtable(L); - while (*(d->array_field+i) != -1) { - ds = *(d->array_field+1) / 65536.0; - lua_pushnumber(L, ds); - i++; - lua_rawseti(L,-2,i); - } - lua_setfield(L,-2,"dashes"); - } - } else { - lua_pushnil(L); - } -} - -static void -mplib_push_transform (lua_State *L, struct mp_text_object *h ) { - int i = 1; - if (h!=NULL) { - lua_createtable(L,6,0); - mplib_push_number(L,h->tx_field); - lua_rawseti(L,-2,i); i++; - mplib_push_number(L,h->ty_field); - lua_rawseti(L,-2,i); i++; - mplib_push_number(L,h->txx_field); - lua_rawseti(L,-2,i); i++; - mplib_push_number(L,h->tyx_field); - lua_rawseti(L,-2,i); i++; - mplib_push_number(L,h->txy_field); - lua_rawseti(L,-2,i); i++; - mplib_push_number(L,h->tyy_field); - lua_rawseti(L,-2,i); i++; - } else { - lua_pushnil(L); - } -} - -#define FIELD(A) (mplib_is_S(A,2)) - -static void -mplib_fill_field (lua_State *L, struct mp_fill_object *h) { - if (FIELD(path)) { - mplib_push_path(L, h->path_p_field, MPLIB_PATH); - } else if (FIELD(htap)) { - mplib_push_path(L, h->htap_p_field, MPLIB_PATH); - } else if (FIELD(pen)) { - mplib_push_path(L, h->pen_p_field, MPLIB_PEN); - mplib_push_pentype(L, h->pen_p_field); - } else if (FIELD(color)) { - mplib_push_color(L,(mp_graphic_object *)h); - } else if (FIELD(linejoin)) { - lua_pushnumber(L,h->ljoin_field); - } else if (FIELD(miterlimit)) { - mplib_push_number(L,h->miterlim_field); - } else if (FIELD(prescript)) { - lua_pushstring(L,h->pre_script_field); - } else if (FIELD(postscript)) { - lua_pushstring(L,h->post_script_field); - } else { - lua_pushnil(L); - } -} - -static void -mplib_stroked_field (lua_State *L, struct mp_stroked_object *h) { - if (FIELD(path)) { - mplib_push_path(L, h->path_p_field, MPLIB_PATH); - } else if (FIELD(pen)) { - mplib_push_path(L, h->pen_p_field, MPLIB_PEN); - mplib_push_pentype(L, h->pen_p_field); - } else if (FIELD(color)) { - mplib_push_color(L, (mp_graphic_object *)h); - } else if (FIELD(dash)) { - mplib_push_dash(L,h); - } else if (FIELD(linecap)) { - lua_pushnumber(L,h->lcap_field); - } else if (FIELD(linejoin)) { - lua_pushnumber(L,h->ljoin_field); - } else if (FIELD(miterlimit)) { - mplib_push_number(L,h->miterlim_field); - } else if (FIELD(prescript)) { - lua_pushstring(L,h->pre_script_field); - } else if (FIELD(postscript)) { - lua_pushstring(L,h->post_script_field); - } else { - lua_pushnil(L); - } -} - -static void -mplib_text_field (lua_State *L, struct mp_text_object *h) { - if (FIELD(text)) { - lua_pushstring(L,h->text_p_field); - } else if (FIELD(dsize)) { - mplib_push_number(L,(h->font_dsize_field/16)); - } else if (FIELD(font)) { - lua_pushstring(L,h->font_name_field); - } else if (FIELD(color)) { - mplib_push_color(L,(mp_graphic_object *)h); - } else if (FIELD(width)) { - mplib_push_number(L,h->width_field); - } else if (FIELD(height)) { - mplib_push_number(L,h->height_field); - } else if (FIELD(depth)) { - mplib_push_number(L,h->depth_field); - } else if (FIELD(transform)) { - mplib_push_transform(L,h); - } else if (FIELD(prescript)) { - lua_pushstring(L,h->pre_script_field); - } else if (FIELD(postscript)) { - lua_pushstring(L,h->post_script_field); - } else { - lua_pushnil(L); - } -} - -static void -mplib_special_field (lua_State *L, struct mp_special_object *h) { - if (FIELD(prescript)) { - lua_pushstring(L,h->pre_script_field); - } else { - lua_pushnil(L); - } -} - -static void -mplib_start_bounds_field (lua_State *L, struct mp_bounds_object *h) { - if (FIELD(path)) { - mplib_push_path(L,h->path_p_field, MPLIB_PATH); - } else { - lua_pushnil(L); - } -} - -static void -mplib_start_clip_field (lua_State *L, struct mp_clip_object *h) { - if (FIELD(path)) { - mplib_push_path(L,h->path_p_field, MPLIB_PATH); - } else { - lua_pushnil(L); - } -} - -static int -mplib_gr_index (lua_State *L) { - struct mp_graphic_object **hh = is_gr_object(L,1); - if (*hh) { - struct mp_graphic_object *h = *hh; - - if (mplib_is_S(type,2)) { - lua_rawgeti(L,LUA_REGISTRYINDEX,mplib_type_Ses[h->_type_field]); - } else { - switch (h->_type_field) { - case mp_fill_code: mplib_fill_field(L,(mp_fill_object *)h); break; - case mp_stroked_code: mplib_stroked_field(L,(mp_stroked_object *)h); break; - case mp_text_code: mplib_text_field(L,(mp_text_object *)h); break; - case mp_special_code: mplib_special_field(L,(mp_special_object *)h); break; - case mp_start_clip_code: mplib_start_clip_field(L,(mp_clip_object *)h); break; - case mp_start_bounds_code: mplib_start_bounds_field(L,(mp_bounds_object *)h); break; - /* case mp_stop_clip_code: */ - /* case mp_stop_bounds_code: */ - default: lua_pushnil(L); - } - } - } else { - lua_pushnil(L); - } - return 1; -} - - -static const struct luaL_reg mplib_meta[] = { - {"__gc", mplib_collect}, - {"__tostring", mplib_tostring}, - {NULL, NULL} /* sentinel */ -}; - -static const struct luaL_reg mplib_fig_meta[] = { - {"__gc", mplib_fig_collect }, - {"__tostring", mplib_fig_tostring }, - {"objects", mplib_fig_body }, - {"copy_objects", mplib_fig_copy_body }, - {"filename", mplib_fig_filename }, - {"postscript", mplib_fig_postscript }, - {"boundingbox", mplib_fig_bb }, - {NULL, NULL} /* sentinel */ -}; - -static const struct luaL_reg mplib_gr_meta[] = { - {"__gc", mplib_gr_collect }, - {"__tostring", mplib_gr_tostring }, - {"__index", mplib_gr_index }, - {NULL, NULL} /* sentinel */ -}; - - -static const struct luaL_reg mplib_d [] = { - {"execute", mplib_execute }, - {"finish", mplib_finish }, - {"statistics", mplib_statistics }, - {NULL, NULL} /* sentinel */ -}; - - -static const struct luaL_reg mplib_m[] = { - {"new", mplib_new }, - {"fields", mplib_gr_fields }, - {NULL, NULL} /* sentinel */ -}; - - -int -luaopen_mp (lua_State *L) { - mplib_init_Ses(L); - - luaL_newmetatable(L,MPLIB_GR_METATABLE); - lua_pushvalue(L, -1); /* push metatable */ - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_register(L, NULL, mplib_gr_meta); /* object meta methods */ - lua_pop(L,1); - - luaL_newmetatable(L,MPLIB_FIG_METATABLE); - lua_pushvalue(L, -1); /* push metatable */ - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_register(L, NULL, mplib_fig_meta); /* figure meta methods */ - lua_pop(L,1); - - luaL_newmetatable(L,MPLIB_METATABLE); - lua_pushvalue(L, -1); /* push metatable */ - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_register(L, NULL, mplib_meta); /* meta methods */ - luaL_register(L, NULL, mplib_d); /* dict methods */ - luaL_register(L, "mplib", mplib_m); /* module functions */ - return 1; -} - diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index de269d5d9c8..0bbbc021987 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -1,10 +1,32 @@ -/* $Id: lnodelib.c 1056 2008-02-19 15:42:17Z taco $ */ +/* lnodelib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "nodes.h" +#include "commands.h" + +static const char _svn_version[] = + "$Id: lnodelib.c 2027 2009-03-14 18:47:32Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lnodelib.c $"; + #define init_luaS_index(a) do { \ lua_pushliteral(L,#a); \ luaS_##a##_ptr = (char *)lua_tostring(L,-1); \ @@ -15,7 +37,7 @@ static int luaS_##a##_index = 0; \ static char * luaS_##a##_ptr = NULL -#define luaS_index(a) luaS_##a##_index +#define luaS_index(a) luaS_##a##_index #define luaS_ptr_eq(a,b) (a==luaS_##b##_ptr) @@ -23,75 +45,81 @@ make_luaS_index(luatex_node); -halfword *check_isnode (lua_State *L, int ud) { - register halfword *p = lua_touserdata(L, ud); - if (p != NULL) { - if (lua_getmetatable(L, ud)) { - lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(luatex_node)); - lua_gettable(L, LUA_REGISTRYINDEX); - if (lua_rawequal(L, -1, -2)) { - lua_pop(L, 2); - return p; - } +halfword *check_isnode(lua_State * L, int ud) +{ + register halfword *p = lua_touserdata(L, ud); + if (p != NULL) { + if (lua_getmetatable(L, ud)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(luatex_node)); + lua_gettable(L, LUA_REGISTRYINDEX); + if (lua_rawequal(L, -1, -2)) { + lua_pop(L, 2); + return p; + } + } } - } - luaL_typerror(L, ud, NODE_METATABLE); - return NULL; + luaL_typerror(L, ud, NODE_METATABLE); + return NULL; } /* This routine finds the numerical value of a string (or number) at lua stack index |n|. If it is not a valid node type, returns -1 */ -static -int do_get_node_type_id (lua_State *L, int n, node_info *data) { - register int j; - if (lua_type(L,n)==LUA_TSTRING) { - char *s = (char *)lua_tostring(L,n); - for (j=0;data[j].id!=-1;j++) { - if (strcmp(s,data[j].name)==0) - return j; - } - } else if (lua_type(L,n)==LUA_TNUMBER) { - register int i = lua_tointeger(L,n); - if (data[i].id==i) - return i; - for (j=0;data[j].id!=-1;j++) { - if (data[j].id==i) - return j; +static +int do_get_node_type_id(lua_State * L, int n, node_info * data) +{ + register int j; + if (lua_type(L, n) == LUA_TSTRING) { + char *s = (char *) lua_tostring(L, n); + for (j = 0; data[j].id != -1; j++) { + if (strcmp(s, data[j].name) == 0) + return j; + } + } else if (lua_type(L, n) == LUA_TNUMBER) { + register int i = lua_tointeger(L, n); + for (j = 0; data[j].id != -1; j++) { + if (data[j].id == i) + return j; + } } - } - return -1; + return -1; } #define get_node_type_id(L,n) do_get_node_type_id(L,n,node_data) #define get_node_subtype_id(L,n) do_get_node_type_id(L,n,whatsit_node_data) -static -int get_valid_node_type_id (lua_State *L, int n) { - int i = get_node_type_id(L,n); - if (i==-1) { - if (lua_type(L,n)==LUA_TSTRING) { - lua_pushfstring(L, "Invalid node type id: %s",(char *)lua_tostring(L,n)); - } else { - lua_pushfstring(L, "Invalid node type id: %d",(int)lua_tonumber(L,n)); +static +int get_valid_node_type_id(lua_State * L, int n) +{ + int i = get_node_type_id(L, n); + if (i == -1) { + if (lua_type(L, n) == LUA_TSTRING) { + lua_pushfstring(L, "Invalid node type id: %s", + (char *) lua_tostring(L, n)); + } else { + lua_pushfstring(L, "Invalid node type id: %d", + (int) lua_tonumber(L, n)); + } + return lua_error(L); } - return lua_error(L); - } - return i; + return i; } -static -int get_valid_node_subtype_id (lua_State *L, int n) { - int i = get_node_subtype_id(L,n); - if (i==-1) { - if (lua_type(L,n)==LUA_TSTRING) { - lua_pushfstring(L, "Invalid whatsit node id: %s",(char *)lua_tostring(L,n)); - } else { - lua_pushfstring(L, "Invalid whatsit node id: %d",(int)lua_tonumber(L,n)); +static +int get_valid_node_subtype_id(lua_State * L, int n) +{ + int i = get_node_subtype_id(L, n); + if (i == -1) { + if (lua_type(L, n) == LUA_TSTRING) { + lua_pushfstring(L, "Invalid whatsit node id: %s", + (char *) lua_tostring(L, n)); + } else { + lua_pushfstring(L, "Invalid whatsit node id: %d", + (int) lua_tonumber(L, n)); + } + return lua_error(L); } - return lua_error(L); - } - return i; + return i; } @@ -103,362 +131,454 @@ int get_valid_node_subtype_id (lua_State *L, int n) { range. This test could be improved. */ -void -lua_nodelib_push(lua_State *L) { - halfword n; - halfword *a; - n = -1; - if (lua_isnumber(L,-1)) { - n = lua_tointeger(L,-1); - } - lua_pop(L,1); - if ((n==null) || (n<0) || (n>var_mem_max)) { - lua_pushnil(L); - } else { - a = lua_newuserdata(L, sizeof(halfword)); - *a = n; - lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(luatex_node)); - lua_gettable(L, LUA_REGISTRYINDEX); - lua_setmetatable(L,-2); - } - return; +void lua_nodelib_push(lua_State * L) +{ + halfword n; + halfword *a; + n = -1; + if (lua_isnumber(L, -1)) { + n = lua_tointeger(L, -1); + } + lua_pop(L, 1); + if ((n == null) || (n < 0) || (n > var_mem_max)) { + lua_pushnil(L); + } else { + a = lua_newuserdata(L, sizeof(halfword)); + *a = n; + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(luatex_node)); + lua_gettable(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); + } + return; } -void -lua_nodelib_push_fast(lua_State *L, halfword n) { - halfword *a; - a = lua_newuserdata(L, sizeof(halfword)); - *a = n; - lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(luatex_node)); - lua_gettable(L, LUA_REGISTRYINDEX); - lua_setmetatable(L,-2); - return; +void lua_nodelib_push_fast(lua_State * L, halfword n) +{ + halfword *a; + a = lua_newuserdata(L, sizeof(halfword)); + *a = n; + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(luatex_node)); + lua_gettable(L, LUA_REGISTRYINDEX); + lua_setmetatable(L, -2); + return; } /* converts type strings to type ids */ -static int -lua_nodelib_id (lua_State *L) { - integer i = get_node_type_id(L,1); - if (i>=0) { - lua_pushnumber(L,i); - } else { - lua_pushnil(L); - } - return 1; +static int lua_nodelib_id(lua_State * L) +{ + integer i = get_node_type_id(L, 1); + if (i >= 0) { + lua_pushnumber(L, i); + } else { + lua_pushnil(L); + } + return 1; } -static int -lua_nodelib_subtype (lua_State *L) { - integer i = get_node_subtype_id(L,1); - if (i>=0) { - lua_pushnumber(L,i); - } else { - lua_pushnil(L); - } - return 1; +static int lua_nodelib_subtype(lua_State * L) +{ + integer i = get_node_subtype_id(L, 1); + if (i >= 0) { + lua_pushnumber(L, i); + } else { + lua_pushnil(L); + } + return 1; } /* converts id numbers to type names */ -static int -lua_nodelib_type (lua_State *L) { - integer i = get_node_type_id(L,1); - if (i>=0) { - lua_pushstring(L,node_data[i].name); - } else { - lua_pushnil(L); - } - return 1; +static int lua_nodelib_type(lua_State * L) +{ + integer i = get_node_type_id(L, 1); + if (i >= 0) { + lua_pushstring(L, node_data[i].name); + } else { + lua_pushnil(L); + } + return 1; } /* allocate a new node */ -static int -lua_nodelib_new(lua_State *L) { - int i,j; - halfword n = null; - i = get_valid_node_type_id(L,1); - - if (i==whatsit_node) { - j = -1; - if (lua_gettop(L)>1) { j = get_valid_node_subtype_id(L,2); } - if (j<0) { - lua_pushstring(L, "Creating a whatsit requires the subtype number as a second argument"); - lua_error(L); - } - } else { - j = 0; - if (lua_gettop(L)>1) { j = lua_tointeger(L,2); } - } - n = new_node(i,j); - lua_nodelib_push_fast(L,n); - return 1; +static int lua_nodelib_new(lua_State * L) +{ + int i, j; + halfword n = null; + i = get_valid_node_type_id(L, 1); + + if (i == whatsit_node) { + j = -1; + if (lua_gettop(L) > 1) { + j = get_valid_node_subtype_id(L, 2); + } + if (j < 0) { + lua_pushstring(L, + "Creating a whatsit requires the subtype number as a second argument"); + lua_error(L); + } + } else { + j = 0; + if (lua_gettop(L) > 1) { + j = lua_tointeger(L, 2); + } + } + n = new_node(i, j); + lua_nodelib_push_fast(L, n); + return 1; } /* Free a node. This function returns the 'next' node, because that may be helpful */ -static int -lua_nodelib_free(lua_State *L) { - halfword *n; - halfword p; - if (lua_gettop(L)<1) { - lua_pushnil(L); +static int lua_nodelib_free(lua_State * L) +{ + halfword *n; + halfword p; + if (lua_gettop(L) < 1) { + lua_pushnil(L); + return 1; + } else if (lua_isnil(L, 1)) { + return 1; /* the nil itself */ + } + n = check_isnode(L, 1); + p = vlink(*n); + flush_node(*n); + lua_pushnumber(L, p); + lua_nodelib_push(L); return 1; - } else if(lua_isnil(L,1)) { - return 1; /* the nil itself */ - } - n = check_isnode(L,1); - p = vlink(*n); - flush_node(*n); - lua_pushnumber(L,p); - lua_nodelib_push(L); - return 1; } /* Free a node list */ -static int -lua_nodelib_flush_list(lua_State *L) { - halfword *n_ptr; - if ((lua_gettop(L)<1) || lua_isnil(L,1)) +static int lua_nodelib_flush_list(lua_State * L) +{ + halfword *n_ptr; + if ((lua_gettop(L) < 1) || lua_isnil(L, 1)) + return 0; + n_ptr = check_isnode(L, 1); + flush_node_list(*n_ptr); return 0; - n_ptr = check_isnode(L,1); - flush_node_list(*n_ptr); - return 0; } /* find prev, and fix backlinks */ -#define set_t_to_prev(head,current) \ - t = head; \ - while (vlink(t)!=current && t != null) { \ - if (vlink(t)!=null) \ - alink(vlink(t)) = t; \ - t = vlink(t); \ +#define set_t_to_prev(head,current) \ + t = head; \ + while (vlink(t)!=current && t != null) { \ + if (vlink(t)!=null) \ + alink(vlink(t)) = t; \ + t = vlink(t); \ } /* remove a node from a list */ -static int -lua_nodelib_remove (lua_State *L) { - halfword head, current, t; - if (lua_gettop(L)<2) { - lua_pushstring(L,"Not enough arguments for node.remove()"); - lua_error(L); - } - head = *(check_isnode(L,1)); - if (lua_isnil(L,2)) { - return 2; /* the arguments, as they are */ - } - current = *(check_isnode(L,2)); - - if (head == current) { - if (alink(head)!=null && vlink(current)!=null) { - alink(vlink(current)) = alink(head); - } - head = vlink(current); - current = head; - } else { /* head != current */ - t = alink(current); - if (t==null || vlink(t)!=current) { - set_t_to_prev(head,current); - if (t==null) { /* error! */ - lua_pushstring(L,"Attempt to node.remove() a non-existing node"); - lua_error(L); - } - } - /* t is now the previous node */ - vlink(t) = vlink(current); - if (vlink(current)!=null) { - alink(vlink(current)) = t; - } - current = vlink(current); - } - lua_pushnumber(L,head); - lua_nodelib_push(L); - lua_pushnumber(L,current); - lua_nodelib_push(L); - return 2; +static int lua_nodelib_remove(lua_State * L) +{ + halfword head, current, t; + if (lua_gettop(L) < 2) { + lua_pushstring(L, "Not enough arguments for node.remove()"); + lua_error(L); + } + head = *(check_isnode(L, 1)); + if (lua_isnil(L, 2)) { + return 2; /* the arguments, as they are */ + } + current = *(check_isnode(L, 2)); + + if (head == current) { + if (alink(head) != null && vlink(current) != null) { + alink(vlink(current)) = alink(head); + } + head = vlink(current); + current = head; + } else { /* head != current */ + t = alink(current); + if (t == null || vlink(t) != current) { + set_t_to_prev(head, current); + if (t == null) { /* error! */ + lua_pushstring(L, + "Attempt to node.remove() a non-existing node"); + lua_error(L); + } + } + /* t is now the previous node */ + vlink(t) = vlink(current); + if (vlink(current) != null) { + alink(vlink(current)) = t; + } + current = vlink(current); + } + lua_pushnumber(L, head); + lua_nodelib_push(L); + lua_pushnumber(L, current); + lua_nodelib_push(L); + return 2; } /* Insert a node in a list */ -static int -lua_nodelib_insert_before (lua_State *L) { - halfword head, current, n, t; - if (lua_gettop(L)<3) { - lua_pushstring(L,"Not enough arguments for node.insert_before()"); - lua_error(L); - } - if (lua_isnil(L,3)) { - lua_pop(L,1); - return 2; - } else { - n = *(check_isnode(L,3)); - } - if (lua_isnil(L,1)) { /* no head */ - vlink(n) = null; - alink(n) = null; - lua_nodelib_push_fast(L,n); - lua_pushvalue(L,-1); - return 2; - } else { - head = *(check_isnode(L,1)); - } - if (lua_isnil(L,2)) { - current = tail_of_list(head); - } else { - current = *(check_isnode(L,2)); - } - t = alink(current); - if (t==null || vlink(t)!=current) { - set_t_to_prev(head,current); - if (t==null) { /* error! */ - lua_pushstring(L,"Attempt to node.insert_before() a non-existing node"); - lua_error(L); +static int lua_nodelib_insert_before(lua_State * L) +{ + halfword head, current, n, t; + if (lua_gettop(L) < 3) { + lua_pushstring(L, "Not enough arguments for node.insert_before()"); + lua_error(L); } - } - couple_nodes(t,n); - couple_nodes(n,current); - if (head==current) { - lua_nodelib_push_fast(L,n); - } else { - lua_nodelib_push_fast(L,head); - } - lua_nodelib_push_fast(L,n); - return 2; + if (lua_isnil(L, 3)) { + lua_pop(L, 1); + return 2; + } else { + n = *(check_isnode(L, 3)); + } + if (lua_isnil(L, 1)) { /* no head */ + vlink(n) = null; + alink(n) = null; + lua_nodelib_push_fast(L, n); + lua_pushvalue(L, -1); + return 2; + } else { + head = *(check_isnode(L, 1)); + } + if (lua_isnil(L, 2)) { + current = tail_of_list(head); + } else { + current = *(check_isnode(L, 2)); + } + if (head != current) { + t = alink(current); + if (t == null || vlink(t) != current) { + set_t_to_prev(head, current); + if (t == null) { /* error! */ + lua_pushstring(L, + "Attempt to node.insert_before() a non-existing node"); + lua_error(L); + } + } + couple_nodes(t, n); + } + couple_nodes(n, current); + if (head == current) { + lua_nodelib_push_fast(L, n); + } else { + lua_nodelib_push_fast(L, head); + } + lua_nodelib_push_fast(L, n); + return 2; } -static int -lua_nodelib_insert_after (lua_State *L) { - halfword head, current, n; - if (lua_gettop(L)<3) { - lua_pushstring(L,"Not enough arguments for node.insert_after()"); - lua_error(L); - } - if (lua_isnil(L,3)) { - lua_pop(L,1); - return 2; - } else { - n = *(check_isnode(L,3)); - } - if (lua_isnil(L,1)) { /* no head */ - vlink(n) = null; - alink(n) = null; - lua_nodelib_push_fast(L,n); - lua_pushvalue(L,-1); - return 2; - } else { - head = *(check_isnode(L,1)); - } - if (lua_isnil(L,2)) { - current = head; - while (vlink(current)!=null) - current = vlink(current); - } else { - current = *(check_isnode(L,2)); - } - try_couple_nodes(n,vlink(current)); - couple_nodes(current, n); +static int lua_nodelib_insert_after(lua_State * L) +{ + halfword head, current, n; + if (lua_gettop(L) < 3) { + lua_pushstring(L, "Not enough arguments for node.insert_after()"); + lua_error(L); + } + if (lua_isnil(L, 3)) { + lua_pop(L, 1); + return 2; + } else { + n = *(check_isnode(L, 3)); + } + if (lua_isnil(L, 1)) { /* no head */ + vlink(n) = null; + alink(n) = null; + lua_nodelib_push_fast(L, n); + lua_pushvalue(L, -1); + return 2; + } else { + head = *(check_isnode(L, 1)); + } + if (lua_isnil(L, 2)) { + current = head; + while (vlink(current) != null) + current = vlink(current); + } else { + current = *(check_isnode(L, 2)); + } + try_couple_nodes(n, vlink(current)); + couple_nodes(current, n); - lua_pop(L,2); - lua_nodelib_push_fast(L,n); - return 2; + lua_pop(L, 2); + lua_nodelib_push_fast(L, n); + return 2; } /* Copy a node list */ -static int -lua_nodelib_copy_list (lua_State *L) { - halfword *n; - halfword m; - if (lua_isnil(L,1)) - return 1; /* the nil itself */ - n = check_isnode(L,1); - m = copy_node_list(*n); - lua_nodelib_push_fast(L,m); - return 1; +static int lua_nodelib_copy_list(lua_State * L) +{ + halfword *n; + halfword m; + if (lua_isnil(L, 1)) + return 1; /* the nil itself */ + n = check_isnode(L, 1); + m = copy_node_list(*n); + lua_nodelib_push_fast(L, m); + return 1; } /* (Deep) copy a node */ -static int -lua_nodelib_copy(lua_State *L) { - halfword *n; - halfword m; - if (lua_isnil(L,1)) - return 1; /* the nil itself */ - n = check_isnode(L,1); - m = copy_node(*n); - lua_nodelib_push_fast(L,m); - return 1; +static int lua_nodelib_copy(lua_State * L) +{ + halfword *n; + halfword m; + if (lua_isnil(L, 1)) + return 1; /* the nil itself */ + n = check_isnode(L, 1); + m = copy_node(*n); + lua_nodelib_push_fast(L, m); + return 1; } /* output (write) a node to tex's processor */ -static int -lua_nodelib_append(lua_State *L) { - halfword *n; - halfword m; - int i, j; - j = lua_gettop(L); - for (i=1;i<=j;i++) { - n = check_isnode(L,i); - m = copy_node_list(*n); - new_tail_append(m); - while (vlink(m)!= null) { - m = vlink(m); - new_tail_append(m); - } - } - return 0; +static int lua_nodelib_append(lua_State * L) +{ + halfword *n; + halfword m; + int i, j; + j = lua_gettop(L); + for (i = 1; i <= j; i++) { + n = check_isnode(L, i); + m = copy_node_list(*n); + new_tail_append(m); + while (vlink(m) != null) { + m = vlink(m); + new_tail_append(m); + } + } + return 0; } -static int -lua_nodelib_last_node(lua_State *L) { - halfword m; - m = pop_tail(); - lua_pushnumber(L,m); - lua_nodelib_push(L); - return 1; +static int lua_nodelib_last_node(lua_State * L) +{ + halfword m; + m = pop_tail(); + lua_pushnumber(L, m); + lua_nodelib_push(L); + return 1; } /* build a hbox */ -static int -lua_nodelib_hpack(lua_State *L) { - halfword n, p; - char *s; - integer w = 0; - int m = 1; - n = *(check_isnode(L,1)); - if (lua_gettop(L)>1) { - w = lua_tointeger(L,2); - if (lua_gettop(L)>2 && lua_type(L,3)==LUA_TSTRING) { - s = (char *)lua_tostring(L,3); - if (strcmp(s,"additional")==0) { - m = 1; - } else { - m = lua_tonumber(L,3); - } +static int lua_nodelib_hpack(lua_State * L) +{ + halfword n, p; + char *s; + integer w = 0; + int m = 1; + n = *(check_isnode(L, 1)); + if (lua_gettop(L) > 1) { + w = lua_tointeger(L, 2); + if (lua_gettop(L) > 2) { + if (lua_type(L, 3) == LUA_TSTRING) { + s = (char *) lua_tostring(L, 3); + if (strcmp(s, "additional") == 0) + m = 1; + else if (strcmp(s, "exactly") == 0) + m = 0; + else { + lua_pushstring(L, + "3rd argument should be either additional or exactly"); + lua_error(L); + } + } + + else if (lua_type(L, 3) == LUA_TNUMBER) { + m = lua_tonumber(L, 3); + } else { + lua_pushstring(L, "incorrect 3rd argument"); + } + } } - } - p = hpack(n,w,m); - lua_nodelib_push_fast(L,p); - return 1; + p = hpack(n, w, m); + lua_nodelib_push_fast(L, p); + return 1; +} + + +/* build a vbox */ +static int lua_nodelib_vpack(lua_State * L) +{ + halfword n, p; + char *s; + integer w = 0; + int m = 1; + n = *(check_isnode(L, 1)); + if (lua_gettop(L) > 1) { + w = lua_tointeger(L, 2); + if (lua_gettop(L) > 2) { + if (lua_type(L, 3) == LUA_TSTRING) { + s = (char *) lua_tostring(L, 3); + if (strcmp(s, "additional") == 0) + m = 1; + else if (strcmp(s, "exactly") == 0) + m = 0; + else { + lua_pushstring(L, + "3rd argument should be either additional or exactly"); + lua_error(L); + } + } + + else if (lua_type(L, 3) == LUA_TNUMBER) { + m = lua_tonumber(L, 3); + } else { + lua_pushstring(L, "incorrect 3rd argument"); + } + } + } + p = vpackage(n, w, m, max_dimen); + lua_nodelib_push_fast(L, p); + return 1; +} + + +/* create a hlist from a formula */ + +static int lua_nodelib_mlist_to_hlist(lua_State * L) +{ + halfword n; + int w; + boolean m; + n = *(check_isnode(L, 1)); + w = luaL_checkoption(L, 2, "text", math_style_names); + luaL_checkany(L, 3); + m = lua_toboolean(L, 3); + cur_mlist = n; + cur_style = w; + mlist_penalties = m; + mlist_to_hlist(); + lua_nodelib_push_fast(L, vlink(temp_head)); + return 1; } +static int lua_nodelib_mfont(lua_State * L) +{ + int f, s; + f = luaL_checkinteger(L, 1); + if (lua_gettop(L) == 2) + s = lua_tointeger(L, 2); /* this should be a multiple of 256 ! */ + else + s = 0; + lua_pushnumber(L, fam_fnt(f, s)); + return 1; +} + + + /* This function is similar to |get_node_type_id|, for field identifiers. It has to do some more work, because not all identifiers are valid for all types of nodes. @@ -486,338 +606,363 @@ make_luaS_index(xoffset); make_luaS_index(yoffset); -void initialize_luaS_indexes(lua_State *L) { - init_luaS_index(id); - init_luaS_index(next); - init_luaS_index(char); - init_luaS_index(font); - init_luaS_index(attr); - init_luaS_index(prev); - init_luaS_index(lang); - init_luaS_index(subtype); - init_luaS_index(left); - init_luaS_index(right); - init_luaS_index(uchyph); - init_luaS_index(components); - init_luaS_index(xoffset); - init_luaS_index(yoffset); +void initialize_luaS_indexes(lua_State * L) +{ + init_luaS_index(id); + init_luaS_index(next); + init_luaS_index(char); + init_luaS_index(font); + init_luaS_index(attr); + init_luaS_index(prev); + init_luaS_index(lang); + init_luaS_index(subtype); + init_luaS_index(left); + init_luaS_index(right); + init_luaS_index(uchyph); + init_luaS_index(components); + init_luaS_index(xoffset); + init_luaS_index(yoffset); } -static int -get_node_field_id (lua_State *L, int n, int node ) { - register int t = type(node); - register char *s = (char *)lua_tostring(L,n); - if (luaS_ptr_eq(s,next)) { return 0; } - else if (luaS_ptr_eq(s,id)) { return 1; } - else if (luaS_ptr_eq(s,attr) && - nodetype_has_attributes(t)) { return 3 ; } - else if (t==glyph_node) { - if (luaS_ptr_eq(s,subtype)) { return 2; } - else if (luaS_ptr_eq(s,font)) { return 5; } - else if (luaS_ptr_eq(s,char)) { return 4; } - else if (luaS_ptr_eq(s,prev)) { return -1; } - else if (luaS_ptr_eq(s,lang)) { return 6; } - else if (luaS_ptr_eq(s,left)) { return 7; } - else if (luaS_ptr_eq(s,right)) { return 8; } - else if (luaS_ptr_eq(s,uchyph)) { return 9; } - else if (luaS_ptr_eq(s,components)) { return 10; } - else if (luaS_ptr_eq(s,xoffset)) { return 11; } - else if (luaS_ptr_eq(s,yoffset)) { return 12; } - } - else if (luaS_ptr_eq(s,prev)) { return -1; } - else if (luaS_ptr_eq(s,subtype)) { return 2; } - else { - int j; - char **fields = node_data[t].fields; - if (t==whatsit_node) - fields = whatsit_node_data[subtype(node)].fields; - for (j=0;fields[j]!=NULL;j++) { - if (strcmp(s,fields[j])==0) { - return j+3; - } - } - } - return -2; +static int get_node_field_id(lua_State * L, int n, int node) +{ + register int t = type(node); + register char *s = (char *) lua_tostring(L, n); + if (luaS_ptr_eq(s, next)) { + return 0; + } else if (luaS_ptr_eq(s, id)) { + return 1; + } else if (luaS_ptr_eq(s, attr) && nodetype_has_attributes(t)) { + return 3; + } else if (t == glyph_node) { + if (luaS_ptr_eq(s, subtype)) { + return 2; + } else if (luaS_ptr_eq(s, font)) { + return 5; + } else if (luaS_ptr_eq(s, char)) { + return 4; + } else if (luaS_ptr_eq(s, prev)) { + return -1; + } else if (luaS_ptr_eq(s, lang)) { + return 6; + } else if (luaS_ptr_eq(s, left)) { + return 7; + } else if (luaS_ptr_eq(s, right)) { + return 8; + } else if (luaS_ptr_eq(s, uchyph)) { + return 9; + } else if (luaS_ptr_eq(s, components)) { + return 10; + } else if (luaS_ptr_eq(s, xoffset)) { + return 11; + } else if (luaS_ptr_eq(s, yoffset)) { + return 12; + } + } else if (luaS_ptr_eq(s, prev)) { + return -1; + } else if (luaS_ptr_eq(s, subtype)) { + return 2; + } else { + int j; + char **fields = node_data[t].fields; + if (t == whatsit_node) + fields = whatsit_node_data[subtype(node)].fields; + for (j = 0; fields[j] != NULL; j++) { + if (strcmp(s, fields[j]) == 0) { + return j + 3; + } + } + } + return -2; } -static int -get_valid_node_field_id (lua_State *L, int n, int node ) { - int i = get_node_field_id(L,n,node); - if (i==-2) { - char *s = (char *)lua_tostring(L,n); - lua_pushfstring(L, "Invalid field id %s for node type %s (%d)" , s, node_data[type(node)].name,subtype(node)); - lua_error(L); - } - return i; +static int get_valid_node_field_id(lua_State * L, int n, int node) +{ + int i = get_node_field_id(L, n, node); + if (i == -2) { + char *s = (char *) lua_tostring(L, n); + lua_pushfstring(L, "Invalid field id %s for node type %s (%d)", s, + node_data[type(node)].name, subtype(node)); + lua_error(L); + } + return i; } -static int -lua_nodelib_has_field (lua_State *L) { - int i= -2; - if (!lua_isnil(L,1)) { - i = get_node_field_id(L,2,*(check_isnode(L,1))); - } - lua_pushboolean(L,(i!=-2)); - return 1; +static int lua_nodelib_has_field(lua_State * L) +{ + int i = -2; + if (!lua_isnil(L, 1)) { + i = get_node_field_id(L, 2, *(check_isnode(L, 1))); + } + lua_pushboolean(L, (i != -2)); + return 1; } /* fetch the list of valid node types */ -static int -do_lua_nodelib_types (lua_State *L, node_info *data) { - int i; - lua_newtable(L); - for (i=0;data[i].id!=-1;i++) { - lua_pushstring(L,data[i].name); - lua_rawseti(L,-2,data[i].id); - } - return 1; +static int do_lua_nodelib_types(lua_State * L, node_info * data) +{ + int i; + lua_newtable(L); + for (i = 0; data[i].id != -1; i++) { + lua_pushstring(L, data[i].name); + lua_rawseti(L, -2, data[i].id); + } + return 1; } -static int -lua_nodelib_types (lua_State *L) { - return do_lua_nodelib_types (L, node_data); +static int lua_nodelib_types(lua_State * L) +{ + return do_lua_nodelib_types(L, node_data); } -static int -lua_nodelib_whatsits (lua_State *L) { - return do_lua_nodelib_types (L, whatsit_node_data); +static int lua_nodelib_whatsits(lua_State * L) +{ + return do_lua_nodelib_types(L, whatsit_node_data); } /* fetch the list of valid fields */ -static int -lua_nodelib_fields (lua_State *L) { - int i = -1; - char ** fields; - int t = get_valid_node_type_id(L,1); - if (t==whatsit_node ) { - t = get_valid_node_subtype_id(L,2); - fields = whatsit_node_data[t].fields; - } else { - fields = node_data[t].fields; - } - lua_checkstack(L,2); - lua_newtable(L); - lua_pushstring(L,"next"); - lua_rawseti(L,-2,0); - lua_pushstring(L,"id"); - lua_rawseti(L,-2,1); - lua_pushstring(L,"subtype"); - lua_rawseti(L,-2,2); - if (fields!=NULL) { - lua_pushstring(L,"prev"); - lua_rawseti(L,-2,-1); - for (i=0;fields[i]!=NULL;i++) { - lua_pushstring(L,fields[i]); - lua_rawseti(L,-2,(i+3)); +static int lua_nodelib_fields(lua_State * L) +{ + int i = -1; + char **fields; + int t = get_valid_node_type_id(L, 1); + if (t == whatsit_node) { + t = get_valid_node_subtype_id(L, 2); + fields = whatsit_node_data[t].fields; + } else { + fields = node_data[t].fields; } - } - return 1; + lua_checkstack(L, 2); + lua_newtable(L); + lua_pushstring(L, "next"); + lua_rawseti(L, -2, 0); + lua_pushstring(L, "id"); + lua_rawseti(L, -2, 1); + lua_pushstring(L, "subtype"); + lua_rawseti(L, -2, 2); + if (fields != NULL) { + lua_pushstring(L, "prev"); + lua_rawseti(L, -2, -1); + for (i = 0; fields[i] != NULL; i++) { + lua_pushstring(L, fields[i]); + lua_rawseti(L, -2, (i + 3)); + } + } + return 1; } /* find the end of a list */ -static int -lua_nodelib_tail (lua_State *L) { - halfword *n; - halfword t; - if (lua_isnil(L,1)) - return 1; /* the nil itself */ - n = check_isnode(L,1); - t=*n; - if (t==null) - return 1; /* the old userdata */ - alink(t) = null; - while (vlink(t)!=null) { - alink(vlink(t)) = t; - t = vlink(t); - } - lua_nodelib_push_fast(L,t); - return 1; +static int lua_nodelib_tail(lua_State * L) +{ + halfword *n; + halfword t; + if (lua_isnil(L, 1)) + return 1; /* the nil itself */ + n = check_isnode(L, 1); + t = *n; + if (t == null) + return 1; /* the old userdata */ + alink(t) = null; + while (vlink(t) != null) { + alink(vlink(t)) = t; + t = vlink(t); + } + lua_nodelib_push_fast(L, t); + return 1; } /* a few utility functions for attribute stuff */ -static int -lua_nodelib_has_attribute (lua_State *L) { - halfword *n; - int i, val ; - if (lua_isnil(L,1)) - return 1; /* the nil itself */ - n = check_isnode(L,1); - i = lua_tointeger(L,2); - val = luaL_optinteger(L,3,-1); - if((val = has_attribute(*n,i,val))>=0) { - lua_pushnumber(L,val); - } else { +static int lua_nodelib_has_attribute(lua_State * L) +{ + halfword *n; + int i, val; + n = check_isnode(L, 1); + if (n != NULL) { + i = lua_tointeger(L, 2); + val = luaL_optinteger(L, 3, -1); + if ((val = has_attribute(*n, i, val)) >= 0) { + lua_pushnumber(L, val); + return 1; + } + } lua_pushnil(L); - } - return 1; + return 1; } -static int -lua_nodelib_set_attribute (lua_State *L) { - halfword *n; - int i, val; - if (lua_gettop(L)==3) { - i = lua_tointeger(L,2); - val = lua_tointeger(L,3); - n = check_isnode(L,1); - if (val<0) { - (void)unset_attribute(*n,i,val); +static int lua_nodelib_set_attribute(lua_State * L) +{ + halfword *n; + int i, val; + if (lua_gettop(L) == 3) { + i = lua_tointeger(L, 2); + val = lua_tointeger(L, 3); + n = check_isnode(L, 1); + if (val < 0) { + (void) unset_attribute(*n, i, val); + } else { + set_attribute(*n, i, val); + } } else { - set_attribute(*n,i,val); + lua_pushstring(L, "incorrect number of arguments"); + lua_error(L); } - } else { - lua_pushstring(L,"incorrect number of arguments"); - lua_error(L); - } - return 0; + return 0; } -static int -lua_nodelib_unset_attribute (lua_State *L) { - halfword *n; - int i, val, ret; - if (lua_gettop(L)<=3) { - i = luaL_checknumber(L,2); - val = luaL_optnumber(L,3,-1); - n = check_isnode(L,1); - ret = unset_attribute(*n,i,val); - if(ret>=0) { - lua_pushnumber(L,ret); +static int lua_nodelib_unset_attribute(lua_State * L) +{ + halfword *n; + int i, val, ret; + if (lua_gettop(L) <= 3) { + i = luaL_checknumber(L, 2); + val = luaL_optnumber(L, 3, -1); + n = check_isnode(L, 1); + ret = unset_attribute(*n, i, val); + if (ret >= 0) { + lua_pushnumber(L, ret); + } else { + lua_pushnil(L); + } + return 1; } else { - lua_pushnil(L); + lua_pushstring(L, "incorrect number of arguments"); + return lua_error(L); } - return 1; - } else { - lua_pushstring(L,"incorrect number of arguments"); - return lua_error(L); - } } /* iteration */ -static int nodelib_aux_nil (lua_State *L) { - lua_pushnil(L); - return 1; +static int nodelib_aux_nil(lua_State * L) +{ + lua_pushnil(L); + return 1; } -static int -nodelib_aux_next_filtered (lua_State *L) { - register halfword t; /* traverser */ - register int i = lua_tointeger(L,lua_upvalueindex(1)); - if (lua_isnil(L,2)) { /* first call */ - t = *check_isnode(L,1); - } else { - t = *check_isnode(L,2); - t = vlink(t); - } - while (t!=null && type(t)!=i) { t = vlink(t); } - if (t==null) { - lua_pushnil(L); - } else { - lua_nodelib_push_fast(L,t); - } - return 1; +static int nodelib_aux_next_filtered(lua_State * L) +{ + register halfword t; /* traverser */ + register int i = lua_tointeger(L, lua_upvalueindex(1)); + if (lua_isnil(L, 2)) { /* first call */ + t = *check_isnode(L, 1); + } else { + t = *check_isnode(L, 2); + t = vlink(t); + } + while (t != null && type(t) != i) { + t = vlink(t); + } + if (t == null) { + lua_pushnil(L); + } else { + lua_nodelib_push_fast(L, t); + } + return 1; } -static int -lua_nodelib_traverse_filtered (lua_State *L) { - halfword n; - if (lua_isnil(L,2)) { - lua_pushcclosure(L, nodelib_aux_nil, 0); - return 1; - } - n = *(check_isnode(L,2)); - lua_pop(L,1); /* the node, integer remains */ - lua_pushcclosure(L, nodelib_aux_next_filtered, 1); - lua_nodelib_push_fast(L,n); - lua_pushnil(L); - return 3; -} - -static int -nodelib_aux_next (lua_State *L) { - register halfword t; /* traverser */ - if (lua_isnil(L,2)) { /* first call */ - t = *check_isnode(L,1); - } else { - t = *check_isnode(L,2); - t = vlink(t); - } - if (t==null) { +static int lua_nodelib_traverse_filtered(lua_State * L) +{ + halfword n; + if (lua_isnil(L, 2)) { + lua_pushcclosure(L, nodelib_aux_nil, 0); + return 1; + } + n = *(check_isnode(L, 2)); + lua_pop(L, 1); /* the node, integer remains */ + lua_pushcclosure(L, nodelib_aux_next_filtered, 1); + lua_nodelib_push_fast(L, n); lua_pushnil(L); - } else { - lua_nodelib_push_fast(L,t); - } - return 1; + return 3; } -static int -lua_nodelib_traverse (lua_State *L) { - halfword n; - if (lua_isnil(L,1)) { - lua_pushcclosure(L, nodelib_aux_nil, 0); +static int nodelib_aux_next(lua_State * L) +{ + register halfword t; /* traverser */ + if (lua_isnil(L, 2)) { /* first call */ + t = *check_isnode(L, 1); + } else { + t = *check_isnode(L, 2); + t = vlink(t); + } + if (t == null) { + lua_pushnil(L); + } else { + lua_nodelib_push_fast(L, t); + } return 1; - } - n = *(check_isnode(L,1)); - lua_pushcclosure(L, nodelib_aux_next, 0); - lua_nodelib_push_fast(L,n); - lua_pushnil(L); - return 3; -; +} + +static int lua_nodelib_traverse(lua_State * L) +{ + halfword n; + if (lua_isnil(L, 1)) { + lua_pushcclosure(L, nodelib_aux_nil, 0); + return 1; + } + n = *(check_isnode(L, 1)); + lua_pushcclosure(L, nodelib_aux_next, 0); + lua_nodelib_push_fast(L, n); + lua_pushnil(L); + return 3; + ; } static int -do_lua_nodelib_count (lua_State *L, halfword match, int i, halfword first) { - int count = 0; - int t = first; - while (t!=match) { - if (i<0 || type(t)==i) { count++; } - t = vlink(t); - } - lua_pushnumber(L,count); - return 1; +do_lua_nodelib_count(lua_State * L, halfword match, int i, halfword first) +{ + int count = 0; + int t = first; + while (t != match) { + if (i < 0 || type(t) == i) { + count++; + } + t = vlink(t); + } + lua_pushnumber(L, count); + return 1; } -static int lua_nodelib_length (lua_State *L) { - halfword n; - halfword m = null; - if (lua_isnil(L,1)) { - lua_pushnumber(L,0); - return 1; - } - n = *(check_isnode(L,1)); - if (lua_gettop(L)==2) { - m = *(check_isnode(L,2)); - } - return do_lua_nodelib_count(L,m,-1,n); +static int lua_nodelib_length(lua_State * L) +{ + halfword n; + halfword m = null; + if (lua_isnil(L, 1)) { + lua_pushnumber(L, 0); + return 1; + } + n = *(check_isnode(L, 1)); + if (lua_gettop(L) == 2) { + m = *(check_isnode(L, 2)); + } + return do_lua_nodelib_count(L, m, -1, n); } -static int lua_nodelib_count (lua_State *L) { - halfword n; - halfword m = null; - int i = -1; - i = lua_tointeger(L,1); - if (lua_isnil(L,2)) { - lua_pushnumber(L,0); - return 1; - } - n = *(check_isnode(L,2)); - if (lua_gettop(L)==3) - m = *(check_isnode(L,3)); - return do_lua_nodelib_count(L,m,i,n); +static int lua_nodelib_count(lua_State * L) +{ + halfword n; + halfword m = null; + int i = -1; + i = lua_tointeger(L, 1); + if (lua_isnil(L, 2)) { + lua_pushnumber(L, 0); + return 1; + } + n = *(check_isnode(L, 2)); + if (lua_gettop(L) == 3) + m = *(check_isnode(L, 3)); + return do_lua_nodelib_count(L, m, i, n); } /* fetching a field from a node */ @@ -828,1140 +973,2332 @@ static int lua_nodelib_count (lua_State *L) { #define nodelib_pushaction(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); } #define nodelib_pushstring(L,n) { lua_pushstring(L,makecstring(n)); } -static void -lua_nodelib_getfield_whatsit (lua_State *L, int n, int field) { - if (field==2) { - lua_pushnumber(L,subtype(n)); - } else { - switch (subtype(n)) { - case open_node: - switch (field) { - case 4: lua_pushnumber(L,write_stream(n)); break; - case 5: nodelib_pushstring(L,open_name(n)); break; - case 6: nodelib_pushstring(L,open_area(n)); break; - case 7: nodelib_pushstring(L,open_ext(n)); break; - default: lua_pushnil(L); - } - break; - case write_node: - switch (field) { - case 4: lua_pushnumber(L,write_stream(n)); break; - case 5: tokenlist_to_lua(L,write_tokens(n)); break; - default: lua_pushnil(L); - } - break; - case close_node: - switch (field) { - case 4: lua_pushnumber(L,write_stream(n)); break; - default: lua_pushnil(L); - } - break; - case special_node: - switch (field) { - case 4: tokenlist_to_luastring(L,write_tokens(n)); break; - default: lua_pushnil(L); - } - break; - case local_par_node: - switch (field) { - case 4: lua_pushnumber(L,local_pen_inter(n)); break; - case 5: lua_pushnumber(L,local_pen_broken(n)); break; - case 6: lua_pushnumber(L,local_par_dir(n)); break; - case 7: nodelib_pushlist(L,local_box_left(n)); break; - case 8: lua_pushnumber(L,local_box_left_width(n)); break; - case 9: nodelib_pushlist(L,local_box_right(n)); break; - case 10: lua_pushnumber(L,local_box_right_width(n)); break; - default: lua_pushnil(L); - } - break; - case dir_node: - switch (field) { - case 4: lua_pushnumber(L,dir_dir(n)); break; - case 5: lua_pushnumber(L,dir_level(n)); break; - case 6: lua_pushnumber(L,dir_dvi_ptr(n)); break; - case 7: lua_pushnumber(L,dir_dvi_h(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_literal_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_literal_mode(n)); break; - case 5: tokenlist_to_luastring(L,pdf_literal_data(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_refobj_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_obj_objnum(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_refxform_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_width(n)); break; - case 5: lua_pushnumber(L,pdf_height(n)); break; - case 6: lua_pushnumber(L,pdf_depth(n)); break; - case 7: lua_pushnumber(L,pdf_xform_objnum(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_refximage_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_width(n)); break; - case 5: lua_pushnumber(L,pdf_height(n)); break; - case 6: lua_pushnumber(L,pdf_depth(n)); break; - case 7: lua_pushnumber(L,pdf_ximage_objnum(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_annot_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_width(n)); break; - case 5: lua_pushnumber(L,pdf_height(n)); break; - case 6: lua_pushnumber(L,pdf_depth(n)); break; - case 7: lua_pushnumber(L,pdf_annot_objnum(n)); break; - case 8: tokenlist_to_luastring(L,pdf_annot_data(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_start_link_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_width(n)); break; - case 5: lua_pushnumber(L,pdf_height(n)); break; - case 6: lua_pushnumber(L,pdf_depth(n)); break; - case 7: lua_pushnumber(L,pdf_link_objnum(n)); break; - case 8: tokenlist_to_luastring(L,pdf_link_attr(n)); break; - case 9: nodelib_pushaction(L,pdf_link_action(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_dest_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_width(n)); break; - case 5: lua_pushnumber(L,pdf_height(n)); break; - case 6: lua_pushnumber(L,pdf_depth(n)); break; - case 7: lua_pushnumber(L,pdf_dest_named_id(n)); break; - case 8: if (pdf_dest_named_id(n) == 1) - tokenlist_to_luastring(L,pdf_dest_id(n)); - else - lua_pushnumber(L,pdf_dest_id(n)); break; - case 9: lua_pushnumber(L,pdf_dest_type(n)); break; - case 10: lua_pushnumber(L,pdf_dest_xyz_zoom(n)); break; - case 11: lua_pushnumber(L,pdf_dest_objnum(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_thread_node: - case pdf_start_thread_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_width(n)); break; - case 5: lua_pushnumber(L,pdf_height(n)); break; - case 6: lua_pushnumber(L,pdf_depth(n)); break; - case 7: lua_pushnumber(L,pdf_thread_named_id(n)); break; - case 8: if (pdf_thread_named_id(n) == 1) - tokenlist_to_luastring(L,pdf_thread_id(n)); - else - lua_pushnumber(L,pdf_thread_id(n)); break; - case 9: tokenlist_to_luastring(L,pdf_thread_attr(n)); break; - default: lua_pushnil(L); - } - break; - case late_lua_node: - switch (field) { - case 4: lua_pushnumber(L,late_lua_reg(n)); break; - case 5: tokenlist_to_luastring(L,late_lua_data(n)); break; - default: lua_pushnil(L); - } - break; - case close_lua_node: - switch (field) { - case 4: lua_pushnumber(L,late_lua_reg(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_colorstack_node: - switch (field) { - case 4: lua_pushnumber(L,pdf_colorstack_stack(n)); break; - case 5: lua_pushnumber(L,pdf_colorstack_cmd(n)); break; - case 6: tokenlist_to_luastring(L,pdf_colorstack_data(n)); break; - default: lua_pushnil(L); - } - break; - case pdf_setmatrix_node: - switch (field) { - case 4: tokenlist_to_luastring(L,pdf_setmatrix_data(n)); break; - default: lua_pushnil(L); - } - break; - case user_defined_node: - switch (field) { - case 4: lua_pushnumber(L,user_node_id(n)); break; - case 5: lua_pushnumber(L,user_node_type(n)); break; - case 6: - switch (user_node_type(n)) { - case 'a': nodelib_pushlist(L,user_node_value(n)); break; - case 'd': lua_pushnumber(L,user_node_value(n)); break; - case 'n': nodelib_pushlist(L,user_node_value(n)); break; - case 's': nodelib_pushstring(L,user_node_value(n)); break; - case 't': tokenlist_to_lua(L,user_node_value(n)); break; - default: lua_pushnumber(L,user_node_value(n)); break; - } break; - default: lua_pushnil(L); - } - break; - default: - lua_pushnil(L); - break; - } - } +static void nodelib_pushdir(lua_State * L, int n, boolean dirnode) +{ + int f = 0; + char dirstring[5] = { 0 }; + if (dirnode) { + dirstring[f++] = (n < 0 ? '-' : '+'); + } + if (n < 0) + n += 64; + dirstring[f++] = dir_names[(int) dir_primary[n]]; + dirstring[f++] = dir_names[(int) dir_secondary[n]]; + dirstring[f++] = dir_names[(int) dir_tertiary[n]]; + lua_pushstring(L, dirstring); +} + +static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) +{ + if (field == 2) { + lua_pushnumber(L, subtype(n)); + } else { + switch (subtype(n)) { + case open_node: + switch (field) { + case 4: + lua_pushnumber(L, write_stream(n)); + break; + case 5: + nodelib_pushstring(L, open_name(n)); + break; + case 6: + nodelib_pushstring(L, open_area(n)); + break; + case 7: + nodelib_pushstring(L, open_ext(n)); + break; + default: + lua_pushnil(L); + } + break; + case write_node: + switch (field) { + case 4: + lua_pushnumber(L, write_stream(n)); + break; + case 5: + tokenlist_to_lua(L, write_tokens(n)); + break; + default: + lua_pushnil(L); + } + break; + case close_node: + switch (field) { + case 4: + lua_pushnumber(L, write_stream(n)); + break; + default: + lua_pushnil(L); + } + break; + case special_node: + switch (field) { + case 4: + tokenlist_to_luastring(L, write_tokens(n)); + break; + default: + lua_pushnil(L); + } + break; + case local_par_node: + switch (field) { + case 4: + lua_pushnumber(L, local_pen_inter(n)); + break; + case 5: + lua_pushnumber(L, local_pen_broken(n)); + break; + case 6: + nodelib_pushdir(L, local_par_dir(n), false); + break; + case 7: + nodelib_pushlist(L, local_box_left(n)); + break; + case 8: + lua_pushnumber(L, local_box_left_width(n)); + break; + case 9: + nodelib_pushlist(L, local_box_right(n)); + break; + case 10: + lua_pushnumber(L, local_box_right_width(n)); + break; + default: + lua_pushnil(L); + } + break; + case dir_node: + switch (field) { + case 4: + nodelib_pushdir(L, dir_dir(n), true); + break; + case 5: + lua_pushnumber(L, dir_level(n)); + break; + case 6: + lua_pushnumber(L, dir_dvi_ptr(n)); + break; + case 7: + lua_pushnumber(L, dir_dvi_h(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_literal_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_literal_mode(n)); + break; + case 5: + tokenlist_to_luastring(L, pdf_literal_data(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_refobj_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_obj_objnum(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_refxform_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_width(n)); + break; + case 5: + lua_pushnumber(L, pdf_height(n)); + break; + case 6: + lua_pushnumber(L, pdf_depth(n)); + break; + case 7: + lua_pushnumber(L, pdf_xform_objnum(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_refximage_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_width(n)); + break; + case 5: + lua_pushnumber(L, pdf_height(n)); + break; + case 6: + lua_pushnumber(L, pdf_depth(n)); + break; + case 7: + lua_pushnumber(L, pdf_ximage_objnum(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_annot_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_width(n)); + break; + case 5: + lua_pushnumber(L, pdf_height(n)); + break; + case 6: + lua_pushnumber(L, pdf_depth(n)); + break; + case 7: + lua_pushnumber(L, pdf_annot_objnum(n)); + break; + case 8: + tokenlist_to_luastring(L, pdf_annot_data(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_start_link_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_width(n)); + break; + case 5: + lua_pushnumber(L, pdf_height(n)); + break; + case 6: + lua_pushnumber(L, pdf_depth(n)); + break; + case 7: + lua_pushnumber(L, pdf_link_objnum(n)); + break; + case 8: + tokenlist_to_luastring(L, pdf_link_attr(n)); + break; + case 9: + nodelib_pushaction(L, pdf_link_action(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_dest_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_width(n)); + break; + case 5: + lua_pushnumber(L, pdf_height(n)); + break; + case 6: + lua_pushnumber(L, pdf_depth(n)); + break; + case 7: + lua_pushnumber(L, pdf_dest_named_id(n)); + break; + case 8: + if (pdf_dest_named_id(n) == 1) + tokenlist_to_luastring(L, pdf_dest_id(n)); + else + lua_pushnumber(L, pdf_dest_id(n)); + break; + case 9: + lua_pushnumber(L, pdf_dest_type(n)); + break; + case 10: + lua_pushnumber(L, pdf_dest_xyz_zoom(n)); + break; + case 11: + lua_pushnumber(L, pdf_dest_objnum(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_thread_node: + case pdf_start_thread_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_width(n)); + break; + case 5: + lua_pushnumber(L, pdf_height(n)); + break; + case 6: + lua_pushnumber(L, pdf_depth(n)); + break; + case 7: + lua_pushnumber(L, pdf_thread_named_id(n)); + break; + case 8: + if (pdf_thread_named_id(n) == 1) + tokenlist_to_luastring(L, pdf_thread_id(n)); + else + lua_pushnumber(L, pdf_thread_id(n)); + break; + case 9: + tokenlist_to_luastring(L, pdf_thread_attr(n)); + break; + default: + lua_pushnil(L); + } + break; + case late_lua_node: + switch (field) { + case 4: + lua_pushnumber(L, late_lua_reg(n)); + break; + case 5: + tokenlist_to_luastring(L, late_lua_data(n)); + break; + case 6: + tokenlist_to_luastring(L, late_lua_name(n)); + break; + default: + lua_pushnil(L); + } + break; + case close_lua_node: + switch (field) { + case 4: + lua_pushnumber(L, late_lua_reg(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_colorstack_node: + switch (field) { + case 4: + lua_pushnumber(L, pdf_colorstack_stack(n)); + break; + case 5: + lua_pushnumber(L, pdf_colorstack_cmd(n)); + break; + case 6: + tokenlist_to_luastring(L, pdf_colorstack_data(n)); + break; + default: + lua_pushnil(L); + } + break; + case pdf_setmatrix_node: + switch (field) { + case 4: + tokenlist_to_luastring(L, pdf_setmatrix_data(n)); + break; + default: + lua_pushnil(L); + } + break; + case user_defined_node: + switch (field) { + case 4: + lua_pushnumber(L, user_node_id(n)); + break; + case 5: + lua_pushnumber(L, user_node_type(n)); + break; + case 6: + switch (user_node_type(n)) { + case 'a': + nodelib_pushlist(L, user_node_value(n)); + break; + case 'd': + lua_pushnumber(L, user_node_value(n)); + break; + case 'n': + nodelib_pushlist(L, user_node_value(n)); + break; + case 's': + nodelib_pushstring(L, user_node_value(n)); + break; + case 't': + tokenlist_to_lua(L, user_node_value(n)); + break; + default: + lua_pushnumber(L, user_node_value(n)); + break; + } + break; + default: + lua_pushnil(L); + } + break; + default: + lua_pushnil(L); + break; + } + } } -static int -lua_nodelib_getfield (lua_State *L) { - halfword *n_ptr, n; - int field; - if (lua_isnil(L,1)) - return 1; /* a nil */ - n_ptr = check_isnode(L,1); - n = *n_ptr; - field = get_valid_node_field_id(L,2, n); - - if (field<-1) - return 0; - if (field==0) { - lua_pushnumber(L,vlink(n)); - lua_nodelib_push(L); - } else if (field==1) { - lua_pushnumber(L,type(n)); - } else if (field==-1) { - lua_pushnumber(L,alink(n)); - lua_nodelib_push(L); - } else if (field==3 && nodetype_has_attributes(type(n))) { - nodelib_pushattr(L,node_attr(n)); - } else { +static int lua_nodelib_getfield(lua_State * L) +{ + register halfword n; + register int field; + n = *((halfword *) lua_touserdata(L, 1)); + field = get_valid_node_field_id(L, 2, n); + if (field == 0) { + lua_pushnumber(L, vlink(n)); + lua_nodelib_push(L); + return 1; + } + if (field == 1) { + lua_pushnumber(L, type(n)); + return 1; + } + if (field == -1) { + lua_pushnumber(L, alink(n)); + lua_nodelib_push(L); + return 1; + } + if (field == 3 && nodetype_has_attributes(type(n))) { + nodelib_pushattr(L, node_attr(n)); + return 1; + } + if (field < -1) + return 0; switch (type(n)) { case hlist_node: case vlist_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: lua_pushnumber(L,width(n)); break; - case 5: lua_pushnumber(L,depth(n)); break; - case 6: lua_pushnumber(L,height(n)); break; - case 7: lua_pushnumber(L,box_dir(n)); break; - case 8: lua_pushnumber(L,shift_amount(n)); break; - case 9: lua_pushnumber(L,glue_order(n)); break; - case 10: lua_pushnumber(L,glue_sign(n)); break; - case 11: lua_pushnumber(L,(double)glue_set(n)); break; - case 12: nodelib_pushlist(L,list_ptr(n)); break; - default: lua_pushnil(L); - } - break; + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, width(n)); + break; + case 5: + lua_pushnumber(L, depth(n)); + break; + case 6: + lua_pushnumber(L, height(n)); + break; + case 7: + nodelib_pushdir(L, box_dir(n), false); + break; + case 8: + lua_pushnumber(L, shift_amount(n)); + break; + case 9: + lua_pushnumber(L, glue_order(n)); + break; + case 10: + lua_pushnumber(L, glue_sign(n)); + break; + case 11: + lua_pushnumber(L, (double) glue_set(n)); + break; + case 12: + nodelib_pushlist(L, list_ptr(n)); + break; + default: + lua_pushnil(L); + } + break; case unset_node: - switch (field) { - case 2: lua_pushnumber(L,0); break; - case 4: lua_pushnumber(L,width(n)); break; - case 5: lua_pushnumber(L,depth(n)); break; - case 6: lua_pushnumber(L,height(n)); break; - case 7: lua_pushnumber(L,box_dir(n)); break; - case 8: lua_pushnumber(L,glue_shrink(n)); break; - case 9: lua_pushnumber(L,glue_order(n)); break; - case 10: lua_pushnumber(L,glue_sign(n)); break; - case 11: lua_pushnumber(L,glue_stretch(n)); break; - case 12: lua_pushnumber(L,span_count(n)); break; - case 13: nodelib_pushlist(L,list_ptr(n)); break; - default: lua_pushnil(L); - } - break; + switch (field) { + case 2: + lua_pushnumber(L, 0); + break; + case 4: + lua_pushnumber(L, width(n)); + break; + case 5: + lua_pushnumber(L, depth(n)); + break; + case 6: + lua_pushnumber(L, height(n)); + break; + case 7: + nodelib_pushdir(L, box_dir(n), false); + break; + case 8: + lua_pushnumber(L, glue_shrink(n)); + break; + case 9: + lua_pushnumber(L, glue_order(n)); + break; + case 10: + lua_pushnumber(L, glue_sign(n)); + break; + case 11: + lua_pushnumber(L, glue_stretch(n)); + break; + case 12: + lua_pushnumber(L, span_count(n)); + break; + case 13: + nodelib_pushlist(L, list_ptr(n)); + break; + default: + lua_pushnil(L); + } + break; case rule_node: - switch (field) { - case 2: lua_pushnumber(L,0); break; - case 4: lua_pushnumber(L,width(n)); break; - case 5: lua_pushnumber(L,depth(n)); break; - case 6: lua_pushnumber(L,height(n)); break; - case 7: lua_pushnumber(L,rule_dir(n)); break; - default: lua_pushnil(L); - } - break; + switch (field) { + case 2: + lua_pushnumber(L, 0); + break; + case 4: + lua_pushnumber(L, width(n)); + break; + case 5: + lua_pushnumber(L, depth(n)); + break; + case 6: + lua_pushnumber(L, height(n)); + break; + case 7: + nodelib_pushdir(L, rule_dir(n), false); + break; + default: + lua_pushnil(L); + } + break; case ins_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: lua_pushnumber(L,float_cost(n)); break; - case 5: lua_pushnumber(L,depth(n)); break; - case 6: lua_pushnumber(L,height(n)); break; - case 7: nodelib_pushspec(L,split_top_ptr(n)); break; - case 8: nodelib_pushlist(L,ins_ptr(n)); break; - default: lua_pushnil(L); - } - break; - case mark_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: lua_pushnumber(L,mark_class(n)); break; - case 5: tokenlist_to_lua(L,mark_ptr(n)); break; - default: lua_pushnil(L); - } - break; - case adjust_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: nodelib_pushlist(L,adjust_ptr(n)); break; - default: lua_pushnil(L); - } - break; - case disc_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: nodelib_pushlist(L,vlink(pre_break(n))); break; - case 5: nodelib_pushlist(L,vlink(post_break(n))); break; - case 6: nodelib_pushlist(L,vlink(no_break(n))); break; - default: lua_pushnil(L); - } - break; - case math_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: lua_pushnumber(L,surround(n)); break; - default: lua_pushnil(L); - } - break; - case glue_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: nodelib_pushspec(L,glue_ptr(n)); break; - case 5: nodelib_pushlist(L,leader_ptr(n)); break; - default: lua_pushnil(L); - } - break; - case glue_spec_node: - switch (field) { - case 2: lua_pushnumber(L,0); break; - case 3: lua_pushnumber(L,width(n)); break; - case 4: lua_pushnumber(L,stretch(n)); break; - case 5: lua_pushnumber(L,shrink(n)); break; - case 6: lua_pushnumber(L,stretch_order(n)); break; - case 7: lua_pushnumber(L,shrink_order(n)); break; - case 8: lua_pushnumber(L,glue_ref_count(n)); break; - default: lua_pushnil(L); - } - break; - case kern_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: lua_pushnumber(L,width(n)); break; - default: lua_pushnil(L); - } - break; - case penalty_node: - switch (field) { - case 2: lua_pushnumber(L,0); break; - case 4: lua_pushnumber(L,penalty(n)); break; - default: lua_pushnil(L); - } - break; - case glyph_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 4: lua_pushnumber(L,character(n)); break; - case 5: lua_pushnumber(L,font(n)); break; - case 6: lua_pushnumber(L,char_lang(n)); break; - case 7: lua_pushnumber(L,char_lhmin(n)); break; - case 8: lua_pushnumber(L,char_rhmin(n)); break; - case 9: lua_pushnumber(L,char_uchyph(n)); break; - case 10: nodelib_pushlist(L,lig_ptr(n)); break; - case 11: lua_pushnumber(L,x_displace(n)); break; - case 12: lua_pushnumber(L,y_displace(n)); break; - default: lua_pushnil(L); - } - break; + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, float_cost(n)); + break; + case 5: + lua_pushnumber(L, depth(n)); + break; + case 6: + lua_pushnumber(L, height(n)); + break; + case 7: + nodelib_pushspec(L, split_top_ptr(n)); + break; + case 8: + nodelib_pushlist(L, ins_ptr(n)); + break; + default: + lua_pushnil(L); + } + break; + case mark_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, mark_class(n)); + break; + case 5: + tokenlist_to_lua(L, mark_ptr(n)); + break; + default: + lua_pushnil(L); + } + break; + case adjust_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, adjust_ptr(n)); + break; + default: + lua_pushnil(L); + } + break; + case disc_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, vlink(pre_break(n))); + break; + case 5: + nodelib_pushlist(L, vlink(post_break(n))); + break; + case 6: + nodelib_pushlist(L, vlink(no_break(n))); + break; + default: + lua_pushnil(L); + } + break; + case math_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, surround(n)); + break; + default: + lua_pushnil(L); + } + break; + case glue_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushspec(L, glue_ptr(n)); + break; + case 5: + nodelib_pushlist(L, leader_ptr(n)); + break; + default: + lua_pushnil(L); + } + break; + case glue_spec_node: + switch (field) { + case 2: + lua_pushnumber(L, 0); + break; + case 3: + lua_pushnumber(L, width(n)); + break; + case 4: + lua_pushnumber(L, stretch(n)); + break; + case 5: + lua_pushnumber(L, shrink(n)); + break; + case 6: + lua_pushnumber(L, stretch_order(n)); + break; + case 7: + lua_pushnumber(L, shrink_order(n)); + break; + case 8: + lua_pushnumber(L, glue_ref_count(n)); + break; + default: + lua_pushnil(L); + } + break; + case kern_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, width(n)); + break; + default: + lua_pushnil(L); + } + break; + case penalty_node: + switch (field) { + case 2: + lua_pushnumber(L, 0); + break; + case 4: + lua_pushnumber(L, penalty(n)); + break; + default: + lua_pushnil(L); + } + break; + case glyph_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, character(n)); + break; + case 5: + lua_pushnumber(L, font(n)); + break; + case 6: + lua_pushnumber(L, char_lang(n)); + break; + case 7: + lua_pushnumber(L, char_lhmin(n)); + break; + case 8: + lua_pushnumber(L, char_rhmin(n)); + break; + case 9: + lua_pushnumber(L, char_uchyph(n)); + break; + case 10: + nodelib_pushlist(L, lig_ptr(n)); + break; + case 11: + lua_pushnumber(L, x_displace(n)); + break; + case 12: + lua_pushnumber(L, y_displace(n)); + break; + default: + lua_pushnil(L); + } + break; + case style_node: + switch (field) { + case 2: + lua_pushnumber(L, 0); + break; + case 4: + lua_pushstring(L, math_style_names[subtype(n)]); + break; + default: + lua_pushnil(L); + } + break; + case choice_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, display_mlist(n)); + break; + case 5: + nodelib_pushlist(L, text_mlist(n)); + break; + case 6: + nodelib_pushlist(L, script_mlist(n)); + break; + case 7: + nodelib_pushlist(L, script_script_mlist(n)); + break; + default: + lua_pushnil(L); + } + break; + case ord_noad: + case op_noad: + case bin_noad: + case rel_noad: + case open_noad: + case close_noad: + case punct_noad: + case inner_noad: + case under_noad: + case over_noad: + case vcenter_noad: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, nucleus(n)); + break; + case 5: + nodelib_pushlist(L, subscr(n)); + break; + case 6: + nodelib_pushlist(L, supscr(n)); + break; + default: + lua_pushnil(L); + } + break; + case radical_noad: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, nucleus(n)); + break; + case 5: + nodelib_pushlist(L, subscr(n)); + break; + case 6: + nodelib_pushlist(L, supscr(n)); + break; + case 7: + nodelib_pushlist(L, left_delimiter(n)); + break; + case 8: + nodelib_pushlist(L, degree(n)); + break; + default: + lua_pushnil(L); + } + break; + case fraction_noad: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, thickness(n)); + break; + case 5: + nodelib_pushlist(L, numerator(n)); + break; + case 6: + nodelib_pushlist(L, denominator(n)); + break; + case 7: + nodelib_pushlist(L, left_delimiter(n)); + break; + case 8: + nodelib_pushlist(L, right_delimiter(n)); + break; + default: + lua_pushnil(L); + } + break; + case accent_noad: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, nucleus(n)); + break; + case 5: + nodelib_pushlist(L, subscr(n)); + break; + case 6: + nodelib_pushlist(L, supscr(n)); + break; + case 7: + nodelib_pushlist(L, accent_chr(n)); + break; + case 8: + nodelib_pushlist(L, bot_accent_chr(n)); + break; + default: + lua_pushnil(L); + } + break; + case fence_noad: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, delimiter(n)); + break; + default: + lua_pushnil(L); + } + break; + case math_char_node: + case math_text_char_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, math_fam(n)); + break; + case 5: + lua_pushnumber(L, math_character(n)); + break; + default: + lua_pushnil(L); + } + break; + case sub_box_node: + case sub_mlist_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + nodelib_pushlist(L, math_list(n)); + break; + default: + lua_pushnil(L); + } + break; + case delim_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 4: + lua_pushnumber(L, small_fam(n)); + break; + case 5: + lua_pushnumber(L, small_char(n)); + break; + case 6: + lua_pushnumber(L, large_fam(n)); + break; + case 7: + lua_pushnumber(L, large_char(n)); + break; + default: + lua_pushnil(L); + } + break; case inserting_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 3: nodelib_pushlist(L,last_ins_ptr(n)); break; - case 4: nodelib_pushlist(L,best_ins_ptr(n)); break; - default: lua_pushnil(L); - } - break; + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 3: + nodelib_pushlist(L, last_ins_ptr(n)); + break; + case 4: + nodelib_pushlist(L, best_ins_ptr(n)); + break; + default: + lua_pushnil(L); + } + break; case split_up_node: - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 3: nodelib_pushlist(L,last_ins_ptr(n)); break; - case 4: nodelib_pushlist(L,best_ins_ptr(n)); break; - case 5: nodelib_pushlist(L,broken_ptr(n)); break; - case 6: nodelib_pushlist(L,broken_ins(n)); break; - default: lua_pushnil(L); - } - break; - case margin_kern_node : - switch (field) { - case 2: lua_pushnumber(L,subtype(n)); break; - case 3: lua_pushnumber(L,width(n)); break; - case 4: nodelib_pushlist(L,margin_char(n)); break; - default: lua_pushnil(L); - } - break; + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 3: + nodelib_pushlist(L, last_ins_ptr(n)); + break; + case 4: + nodelib_pushlist(L, best_ins_ptr(n)); + break; + case 5: + nodelib_pushlist(L, broken_ptr(n)); + break; + case 6: + nodelib_pushlist(L, broken_ins(n)); + break; + default: + lua_pushnil(L); + } + break; + case margin_kern_node: + switch (field) { + case 2: + lua_pushnumber(L, subtype(n)); + break; + case 3: + lua_pushnumber(L, width(n)); + break; + case 4: + nodelib_pushlist(L, margin_char(n)); + break; + default: + lua_pushnil(L); + } + break; case action_node: - switch (field) { - case 2: lua_pushnil(L); /* dummy subtype */ break; - case 3: lua_pushnumber(L,pdf_action_type(n)); break; - case 4: lua_pushnumber(L,pdf_action_named_id(n)); break; - case 5: if (pdf_action_named_id(n)==1) { - tokenlist_to_luastring(L,pdf_action_id(n)); - } else { - lua_pushnumber(L,pdf_action_id(n)); - } break; - case 6: tokenlist_to_luastring(L,pdf_action_file(n)); break; - case 7: lua_pushnumber(L,pdf_action_new_window(n)); break; - case 8: tokenlist_to_luastring(L,pdf_action_tokens(n));break; - case 9: lua_pushnumber(L,pdf_action_refcount(n)); break; - default: lua_pushnil(L); - } - break; - case attribute_list_node : - switch (field) { - case 2: lua_pushnumber(L,0); break; - default: lua_pushnil(L); - } - break; - case attribute_node : - switch (field) { - case 2: lua_pushnumber(L,0); break; - case 3: lua_pushnumber(L,attribute_id(n)); break; - case 4: lua_pushnumber(L,attribute_value(n)); break; - default: lua_pushnil(L); - } - break; + switch (field) { + case 2: + lua_pushnil(L); /* dummy subtype */ + break; + case 3: + lua_pushnumber(L, pdf_action_type(n)); + break; + case 4: + lua_pushnumber(L, pdf_action_named_id(n)); + break; + case 5: + if (pdf_action_named_id(n) == 1) { + tokenlist_to_luastring(L, pdf_action_id(n)); + } else { + lua_pushnumber(L, pdf_action_id(n)); + } + break; + case 6: + tokenlist_to_luastring(L, pdf_action_file(n)); + break; + case 7: + lua_pushnumber(L, pdf_action_new_window(n)); + break; + case 8: + tokenlist_to_luastring(L, pdf_action_tokens(n)); + break; + case 9: + lua_pushnumber(L, pdf_action_refcount(n)); + break; + default: + lua_pushnil(L); + } + break; + case attribute_list_node: + switch (field) { + case 2: + lua_pushnumber(L, 0); + break; + default: + lua_pushnil(L); + } + break; + case attribute_node: + switch (field) { + case 2: + lua_pushnumber(L, 0); + break; + case 3: + lua_pushnumber(L, attribute_id(n)); + break; + case 4: + lua_pushnumber(L, attribute_value(n)); + break; + default: + lua_pushnil(L); + } + break; case whatsit_node: - lua_nodelib_getfield_whatsit(L,n,field); - break; - default: - lua_pushnil(L); - break; + lua_nodelib_getfield_whatsit(L, n, field); + break; + default: + lua_pushnil(L); + break; } - } - return 1; + return 1; } -static int nodelib_getlist(lua_State *L, int n) { - halfword *m; - if (lua_isuserdata(L,n)) { - m = check_isnode(L,n); - return *m; - } else { - return null ; - } + + +static int nodelib_getlist(lua_State * L, int n) +{ + halfword *m; + if (lua_isuserdata(L, n)) { + m = check_isnode(L, n); + return *m; + } else { + return null; + } } +static int nodelib_getdir(lua_State * L, int n) +{ + char *s = NULL; + int d = 32; /* invalid number */ + int a = -1, b = -1, c = -1; + if (lua_type(L, n) == LUA_TSTRING) { + s = (char *) lua_tostring(L, n); + if (strlen(s) == 3) { + d = 0; + } + if (strlen(s) == 4) { + if (*s == '-') + d = -64; + else if (*s == '+') + d = 0; + s++; + } + if (strlen(s) == 3) { + switch (*s) { + /* *INDENT-OFF* */ + case 'T': a=0; break; + case 'L': a=1; break; + case 'B': a=2; break; + case 'R': a=3; break; + /* *INDENT-ON* */ + } + switch (*(s + 1)) { + /* *INDENT-OFF* */ + case 'T': b=0; break; + case 'L': b=1; break; + case 'B': b=2; break; + case 'R': b=3; break; + /* *INDENT-ON* */ + } + switch (*(s + 2)) { + /* *INDENT-OFF* */ + case 'T': c=0; break; + case 'L': c=1; break; + case 'B': c=2; break; + case 'R': c=3; break; + /* *INDENT-ON* */ + } + } + if (a != -1 && b != -1 && c != -1 && !dir_parallel(a, b)) { + d += (a * 8 + dir_rearrange[b] * 4 + c); + } + } else if (lua_isnumber(L, n)) { + d = lua_tonumber(L, n); + } + if ((d > 31) || (d < -64) || (d < 0 && (d + 64) > 31)) { + d = 0; + lua_pushfstring(L, "Bad direction specifier %s", + (char *) lua_tostring(L, n)); + lua_error(L); + } + return d; +} + + #define nodelib_getspec nodelib_getlist #define nodelib_getaction nodelib_getlist -static str_number -nodelib_getstring(lua_State *L, int a) { - size_t k; - char *s=(char *)lua_tolstring(L,a, &k); - return maketexlstring(s,k); +static str_number nodelib_getstring(lua_State * L, int a) +{ + size_t k; + char *s = (char *) lua_tolstring(L, a, &k); + return maketexlstring(s, k); } #define nodelib_gettoks(L,a) tokenlist_from_lua(L) -static void nodelib_setattr (lua_State *L, int stackindex, halfword n) { - halfword p; - p = nodelib_getlist(L,stackindex); - if (node_attr(n) != p) { - if (node_attr(n)!=null) - delete_attribute_ref(node_attr(n)); - node_attr(n) = p; - attr_list_ref(p)++; - } +static void nodelib_setattr(lua_State * L, int stackindex, halfword n) +{ + halfword p; + p = nodelib_getlist(L, stackindex); + if (node_attr(n) != p) { + if (node_attr(n) != null) + delete_attribute_ref(node_attr(n)); + node_attr(n) = p; + attr_list_ref(p)++; + } } -static int nodelib_cantset (lua_State *L, int field, int n) { - lua_pushfstring(L,"You cannot set field %d in a node of type %s", - field, node_data[type(n)].name); - lua_error(L); - return 0; +static int nodelib_cantset(lua_State * L, int field, int n) +{ + lua_pushfstring(L, "You cannot set field %d in a node of type %s", + field, node_data[type(n)].name); + lua_error(L); + return 0; } -static int -lua_nodelib_setfield_whatsit(lua_State *L, int n, int field) { - switch (subtype(n)) { - case open_node: - switch (field) { - case 4: write_stream(n) = lua_tointeger(L,3); break; - case 5: open_name(n) = nodelib_getstring(L,3); break; - case 6: open_area(n) = nodelib_getstring(L,3); break; - case 7: open_ext(n) = nodelib_getstring(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case write_node: - switch (field) { - case 4: write_stream(n) = lua_tointeger(L,3); break; - case 5: write_tokens(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case close_node: - switch (field) { - case 4: write_stream(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case special_node: - switch (field) { - case 4: write_tokens(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case local_par_node: - switch (field) { - case 4: local_pen_inter(n) = lua_tointeger(L,3); break; - case 5: local_pen_broken(n) = lua_tointeger(L,3); break; - case 6: local_par_dir(n) = lua_tointeger(L,3); break; - case 7: local_box_left(n) = nodelib_getlist(L,3); break; - case 8: local_box_left_width(n) = lua_tointeger(L,3); break; - case 9: local_box_right(n) = nodelib_getlist(L,3); break; - case 10: local_box_right_width(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case dir_node: - switch (field) { - case 4: dir_dir(n) = lua_tointeger(L,3); break; - case 5: dir_level(n) = lua_tointeger(L,3); break; - case 6: dir_dvi_ptr(n) = lua_tointeger(L,3); break; - case 7: dir_dvi_h(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_literal_node: - switch (field) { - case 4: pdf_literal_mode(n) = lua_tointeger(L,3); break; - case 5: pdf_literal_data(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_refobj_node: - switch (field) { - case 4: pdf_obj_objnum(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_refxform_node: - switch (field) { - case 4: pdf_width(n) = lua_tointeger(L,3); break; - case 5: pdf_height(n) = lua_tointeger(L,3); break; - case 6: pdf_depth(n) = lua_tointeger(L,3); break; - case 7: pdf_xform_objnum(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_refximage_node: - switch (field) { - case 4: pdf_width(n) = lua_tointeger(L,3); break; - case 5: pdf_height(n) = lua_tointeger(L,3); break; - case 6: pdf_depth(n) = lua_tointeger(L,3); break; - case 7: pdf_ximage_objnum(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_annot_node: - switch (field) { - case 4: pdf_width(n) = lua_tointeger(L,3); break; - case 5: pdf_height(n) = lua_tointeger(L,3); break; - case 6: pdf_depth(n) = lua_tointeger(L,3); break; - case 7: pdf_annot_objnum(n) = lua_tointeger(L,3); break; - case 8: pdf_annot_data(n) = nodelib_getstring(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_start_link_node: - switch (field) { - case 4: pdf_width(n) = lua_tointeger(L,3); break; - case 5: pdf_height(n) = lua_tointeger(L,3); break; - case 6: pdf_depth(n) = lua_tointeger(L,3); break; - case 7: pdf_link_objnum(n) = lua_tointeger(L,3); break; - case 8: pdf_link_attr(n) = nodelib_getstring(L,3); break; - case 9: pdf_link_action(n) = nodelib_getaction(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_end_link_node: - switch (field) { - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_dest_node: - switch (field) { - case 4: pdf_width(n) = lua_tointeger(L,3); break; - case 5: pdf_height(n) = lua_tointeger(L,3); break; - case 6: pdf_depth(n) = lua_tointeger(L,3); break; - case 7: pdf_dest_named_id(n) = lua_tointeger(L,3); break; - case 8: if (pdf_dest_named_id(n)==1) - pdf_dest_id(n) = nodelib_gettoks(L,3); - else - pdf_dest_id(n) = lua_tointeger(L,3); break; - case 9: pdf_dest_type(n) = lua_tointeger(L,3); break; - case 10: pdf_dest_xyz_zoom(n) = lua_tointeger(L,3); break; - case 11: pdf_dest_objnum(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_thread_node: - case pdf_start_thread_node: - switch (field) { - case 4: pdf_width(n) = lua_tointeger(L,3); break; - case 5: pdf_height(n) = lua_tointeger(L,3); break; - case 6: pdf_depth(n) = lua_tointeger(L,3); break; - case 7: pdf_thread_named_id(n) = lua_tointeger(L,3); break; - case 8: if (pdf_thread_named_id(n)==1) - pdf_thread_id(n) = nodelib_gettoks(L,3); - else - pdf_thread_id(n) = lua_tointeger(L,3); break; - case 9: pdf_thread_attr(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_end_thread_node: - case pdf_save_pos_node: - return nodelib_cantset(L,field,n); - break; - case late_lua_node: - switch (field) { - case 4: late_lua_reg(n) = lua_tointeger(L,3); break; - case 5: late_lua_data(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case close_lua_node: - switch (field) { - case 4: late_lua_reg(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_colorstack_node: - switch (field) { - case 4: pdf_colorstack_stack(n) = lua_tointeger(L,3); break; - case 5: pdf_colorstack_cmd(n) = lua_tointeger(L,3); break; - case 6: pdf_colorstack_data(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_setmatrix_node: - switch (field) { - case 4: pdf_setmatrix_data(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case pdf_save_node: - case pdf_restore_node: - case cancel_boundary_node: - return nodelib_cantset(L,field,n); - break; - case user_defined_node: - switch (field) { - case 4: user_node_id(n) = lua_tointeger(L,3); break; - case 5: user_node_type(n) = lua_tointeger(L,3); break; - case 6: - switch(user_node_type(n)) { - case 'a': user_node_value(n) = nodelib_getlist(L,3); break; - case 'd': user_node_value(n) = lua_tointeger(L,3); break; - case 'n': user_node_value(n) = nodelib_getlist(L,3); break; - case 's': user_node_value(n) = nodelib_getstring(L,3); break; - case 't': user_node_value(n) = nodelib_gettoks(L,3); break; - default: user_node_value(n) = lua_tointeger(L,3); break; - } break; - default: return nodelib_cantset(L,field,n); - } - break; - default: - /* do nothing */ - break; - } - return 0; +static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) +{ + switch (subtype(n)) { + case open_node: + switch (field) { + case 4: + write_stream(n) = lua_tointeger(L, 3); + break; + case 5: + open_name(n) = nodelib_getstring(L, 3); + break; + case 6: + open_area(n) = nodelib_getstring(L, 3); + break; + case 7: + open_ext(n) = nodelib_getstring(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case write_node: + switch (field) { + case 4: + write_stream(n) = lua_tointeger(L, 3); + break; + case 5: + write_tokens(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case close_node: + switch (field) { + case 4: + write_stream(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case special_node: + switch (field) { + case 4: + write_tokens(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case local_par_node: + switch (field) { + case 4: + local_pen_inter(n) = lua_tointeger(L, 3); + break; + case 5: + local_pen_broken(n) = lua_tointeger(L, 3); + break; + case 6: + local_par_dir(n) = nodelib_getdir(L, 3); + break; + case 7: + local_box_left(n) = nodelib_getlist(L, 3); + break; + case 8: + local_box_left_width(n) = lua_tointeger(L, 3); + break; + case 9: + local_box_right(n) = nodelib_getlist(L, 3); + break; + case 10: + local_box_right_width(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case dir_node: + switch (field) { + case 4: + dir_dir(n) = nodelib_getdir(L, 3); + break; + case 5: + dir_level(n) = lua_tointeger(L, 3); + break; + case 6: + dir_dvi_ptr(n) = lua_tointeger(L, 3); + break; + case 7: + dir_dvi_h(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_literal_node: + switch (field) { + case 4: + pdf_literal_mode(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_literal_data(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_refobj_node: + switch (field) { + case 4: + pdf_obj_objnum(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_refxform_node: + switch (field) { + case 4: + pdf_width(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_height(n) = lua_tointeger(L, 3); + break; + case 6: + pdf_depth(n) = lua_tointeger(L, 3); + break; + case 7: + pdf_xform_objnum(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_refximage_node: + switch (field) { + case 4: + pdf_width(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_height(n) = lua_tointeger(L, 3); + break; + case 6: + pdf_depth(n) = lua_tointeger(L, 3); + break; + case 7: + pdf_ximage_objnum(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_annot_node: + switch (field) { + case 4: + pdf_width(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_height(n) = lua_tointeger(L, 3); + break; + case 6: + pdf_depth(n) = lua_tointeger(L, 3); + break; + case 7: + pdf_annot_objnum(n) = lua_tointeger(L, 3); + break; + case 8: + pdf_annot_data(n) = nodelib_getstring(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_start_link_node: + switch (field) { + case 4: + pdf_width(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_height(n) = lua_tointeger(L, 3); + break; + case 6: + pdf_depth(n) = lua_tointeger(L, 3); + break; + case 7: + pdf_link_objnum(n) = lua_tointeger(L, 3); + break; + case 8: + pdf_link_attr(n) = nodelib_getstring(L, 3); + break; + case 9: + pdf_link_action(n) = nodelib_getaction(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_end_link_node: + switch (field) { + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_dest_node: + switch (field) { + case 4: + pdf_width(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_height(n) = lua_tointeger(L, 3); + break; + case 6: + pdf_depth(n) = lua_tointeger(L, 3); + break; + case 7: + pdf_dest_named_id(n) = lua_tointeger(L, 3); + break; + case 8: + if (pdf_dest_named_id(n) == 1) + pdf_dest_id(n) = nodelib_gettoks(L, 3); + else + pdf_dest_id(n) = lua_tointeger(L, 3); + break; + case 9: + pdf_dest_type(n) = lua_tointeger(L, 3); + break; + case 10: + pdf_dest_xyz_zoom(n) = lua_tointeger(L, 3); + break; + case 11: + pdf_dest_objnum(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_thread_node: + case pdf_start_thread_node: + switch (field) { + case 4: + pdf_width(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_height(n) = lua_tointeger(L, 3); + break; + case 6: + pdf_depth(n) = lua_tointeger(L, 3); + break; + case 7: + pdf_thread_named_id(n) = lua_tointeger(L, 3); + break; + case 8: + if (pdf_thread_named_id(n) == 1) + pdf_thread_id(n) = nodelib_gettoks(L, 3); + else + pdf_thread_id(n) = lua_tointeger(L, 3); + break; + case 9: + pdf_thread_attr(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_end_thread_node: + case pdf_save_pos_node: + return nodelib_cantset(L, field, n); + break; + case late_lua_node: + switch (field) { + case 4: + late_lua_reg(n) = lua_tointeger(L, 3); + break; + case 5: + late_lua_data(n) = nodelib_gettoks(L, 3); + break; + case 6: + late_lua_name(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case close_lua_node: + switch (field) { + case 4: + late_lua_reg(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_colorstack_node: + switch (field) { + case 4: + pdf_colorstack_stack(n) = lua_tointeger(L, 3); + break; + case 5: + pdf_colorstack_cmd(n) = lua_tointeger(L, 3); + break; + case 6: + pdf_colorstack_data(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_setmatrix_node: + switch (field) { + case 4: + pdf_setmatrix_data(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case pdf_save_node: + case pdf_restore_node: + case cancel_boundary_node: + return nodelib_cantset(L, field, n); + break; + case user_defined_node: + switch (field) { + case 4: + user_node_id(n) = lua_tointeger(L, 3); + break; + case 5: + user_node_type(n) = lua_tointeger(L, 3); + break; + case 6: + switch (user_node_type(n)) { + case 'a': + user_node_value(n) = nodelib_getlist(L, 3); + break; + case 'd': + user_node_value(n) = lua_tointeger(L, 3); + break; + case 'n': + user_node_value(n) = nodelib_getlist(L, 3); + break; + case 's': + user_node_value(n) = nodelib_getstring(L, 3); + break; + case 't': + user_node_value(n) = nodelib_gettoks(L, 3); + break; + default: + user_node_value(n) = lua_tointeger(L, 3); + break; + } + break; + default: + return nodelib_cantset(L, field, n); + } + break; + default: + /* do nothing */ + break; + } + return 0; } -static int -lua_nodelib_setfield (lua_State *L) { - register halfword n; - register int field; - n = *check_isnode(L,1); - field = get_valid_node_field_id(L,2,n); - if (field<-1) - return 0; - if (field==0) { - vlink(n) = nodelib_getlist(L,3); - } else if (field==-1) { - alink(n) = nodelib_getlist(L,3); - } else if (field==3 && nodetype_has_attributes(type(n))) { - nodelib_setattr(L,3,n); - } else if (type(n)==glyph_node) { - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: character(n) = lua_tointeger(L,3); break; - case 5: font(n) = lua_tointeger(L,3); break; - case 6: set_char_lang(n,lua_tointeger(L,3)); break; - case 7: set_char_lhmin(n,lua_tointeger(L,3)); break; - case 8: set_char_rhmin(n,lua_tointeger(L,3)); break; - case 9: set_char_uchyph(n,lua_tointeger(L,3)); break; - case 10: lig_ptr(n) = nodelib_getlist(L,3); break; - case 11: x_displace(n) = lua_tointeger(L,3); break; - case 12: y_displace(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - } else { - switch (type(n)) { - case hlist_node: - case vlist_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: width(n) = lua_tointeger(L,3); break; - case 5: depth(n) = lua_tointeger(L,3); break; - case 6: height(n) = lua_tointeger(L,3); break; - case 7: box_dir(n) = lua_tointeger(L,3); break; - case 8: shift_amount(n) = lua_tointeger(L,3); break; - case 9: glue_order(n) = lua_tointeger(L,3); break; - case 10: glue_sign(n) = lua_tointeger(L,3); break; - case 11: glue_set(n) = (double)lua_tonumber(L,3); break; - case 12: list_ptr(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case unset_node: - switch (field) { - case 2: /* dummy subtype */ break; - case 4: width(n) = lua_tointeger(L,3); break; - case 5: depth(n) = lua_tointeger(L,3); break; - case 6: height(n) = lua_tointeger(L,3); break; - case 7: box_dir(n) = lua_tointeger(L,3); break; - case 8: glue_shrink(n) = lua_tointeger(L,3); break; - case 9: glue_order(n) = lua_tointeger(L,3); break; - case 10: glue_sign(n) = lua_tointeger(L,3); break; - case 11: glue_stretch(n) = lua_tointeger(L,3); break; - case 12: span_count(n) = lua_tointeger(L,3); break; - case 13: list_ptr(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case rule_node: - switch (field) { - case 2: /* dummy subtype */ break; - case 4: width(n) = lua_tointeger(L,3); break; - case 5: depth(n) = lua_tointeger(L,3); break; - case 6: height(n) = lua_tointeger(L,3); break; - case 7: rule_dir(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case ins_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: float_cost(n) = lua_tointeger(L,3); break; - case 5: depth(n) = lua_tointeger(L,3); break; - case 6: height(n) = lua_tointeger(L,3); break; - case 7: split_top_ptr(n) = nodelib_getspec(L,3); break; - case 8: ins_ptr(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case mark_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: mark_class(n) = lua_tointeger(L,3); break; - case 5: mark_ptr(n) = nodelib_gettoks(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case adjust_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: adjust_ptr(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case disc_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: set_disc_field(pre_break(n),nodelib_getlist(L,3)); break; - case 5: set_disc_field(post_break(n),nodelib_getlist(L,3)); break; - case 6: set_disc_field(no_break(n),nodelib_getlist(L,3)); break; - default: return nodelib_cantset(L,field,n); - } - break; - case math_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: surround(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case glue_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: glue_ptr(n) = nodelib_getspec(L,3); break; - case 5: leader_ptr(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case glue_spec_node: - switch (field) { - case 2: /* dummy subtype */ break; - case 3: width(n) = lua_tointeger(L,3); break; - case 4: stretch(n) = lua_tointeger(L,3); break; - case 5: shrink(n) = lua_tointeger(L,3); break; - case 6: stretch_order(n) = lua_tointeger(L,3); break; - case 7: shrink_order(n) = lua_tointeger(L,3); break; - case 8: glue_ref_count(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case kern_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 4: width(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case penalty_node: - switch (field) { - case 2: /* dummy subtype */ break; - case 4: penalty(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case action_node: - switch (field) { - case 2: /* dummy subtype */ break; - case 3: pdf_action_type(n) = lua_tointeger(L,3); break; - case 4: pdf_action_named_id(n) = lua_tointeger(L,3); break; - case 5: if (pdf_action_named_id(n)==1) { - pdf_action_id(n) = nodelib_gettoks(L,3); - } else { - pdf_action_id(n) = lua_tointeger(L,3); - } break; - case 6: pdf_action_file(n) = nodelib_gettoks(L,3); break; - case 7: pdf_action_new_window(n) = lua_tointeger(L,3); break; - case 8: pdf_action_tokens(n) = nodelib_gettoks(L,3); break; - case 9: pdf_action_refcount(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case margin_kern_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 3: width(n) = lua_tointeger(L,3); break; - case 4: margin_char(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case inserting_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 3: last_ins_ptr(n) = nodelib_getlist(L,3); break; - case 4: best_ins_ptr(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case split_up_node: - switch (field) { - case 2: subtype(n) = lua_tointeger(L,3); break; - case 3: last_ins_ptr(n) = nodelib_getlist(L,3); break; - case 4: best_ins_ptr(n) = nodelib_getlist(L,3); break; - case 5: broken_ptr(n) = nodelib_getlist(L,3); break; - case 6: broken_ins(n) = nodelib_getlist(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case attribute_list_node: - switch (field) { - case 2: /* dummy subtype */ break; - default: return nodelib_cantset(L,field,n); - } - break; - case attribute_node: - switch (field) { - case 2: /* dummy subtype */ break; - case 3: attribute_id(n) = lua_tointeger(L,3); break; - case 4: attribute_value(n) = lua_tointeger(L,3); break; - default: return nodelib_cantset(L,field,n); - } - break; - case whatsit_node: - lua_nodelib_setfield_whatsit(L,n,field); - break; - default: - /* do nothing */ - break; +static int lua_nodelib_setfield(lua_State * L) +{ + register halfword n; + register int field; + n = *((halfword *) lua_touserdata(L, 1)); + field = get_valid_node_field_id(L, 2, n); + if (field < -1) + return 0; + if (field == 0) { + vlink(n) = nodelib_getlist(L, 3); + } else if (field == -1) { + alink(n) = nodelib_getlist(L, 3); + } else if (field == 3 && nodetype_has_attributes(type(n))) { + nodelib_setattr(L, 3, n); + } else if (type(n) == glyph_node) { + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + character(n) = lua_tointeger(L, 3); + break; + case 5: + font(n) = lua_tointeger(L, 3); + break; + case 6: + set_char_lang(n, lua_tointeger(L, 3)); + break; + case 7: + set_char_lhmin(n, lua_tointeger(L, 3)); + break; + case 8: + set_char_rhmin(n, lua_tointeger(L, 3)); + break; + case 9: + set_char_uchyph(n, lua_tointeger(L, 3)); + break; + case 10: + lig_ptr(n) = nodelib_getlist(L, 3); + break; + case 11: + x_displace(n) = lua_tointeger(L, 3); + break; + case 12: + y_displace(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + } else { + switch (type(n)) { + case hlist_node: + case vlist_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + width(n) = lua_tointeger(L, 3); + break; + case 5: + depth(n) = lua_tointeger(L, 3); + break; + case 6: + height(n) = lua_tointeger(L, 3); + break; + case 7: + box_dir(n) = nodelib_getdir(L, 3); + break; + case 8: + shift_amount(n) = lua_tointeger(L, 3); + break; + case 9: + glue_order(n) = lua_tointeger(L, 3); + break; + case 10: + glue_sign(n) = lua_tointeger(L, 3); + break; + case 11: + glue_set(n) = (double) lua_tonumber(L, 3); + break; + case 12: + list_ptr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case unset_node: + switch (field) { + case 2: /* dummy subtype */ + break; + case 4: + width(n) = lua_tointeger(L, 3); + break; + case 5: + depth(n) = lua_tointeger(L, 3); + break; + case 6: + height(n) = lua_tointeger(L, 3); + break; + case 7: + box_dir(n) = lua_tointeger(L, 3); + break; + case 8: + glue_shrink(n) = lua_tointeger(L, 3); + break; + case 9: + glue_order(n) = lua_tointeger(L, 3); + break; + case 10: + glue_sign(n) = lua_tointeger(L, 3); + break; + case 11: + glue_stretch(n) = lua_tointeger(L, 3); + break; + case 12: + span_count(n) = lua_tointeger(L, 3); + break; + case 13: + list_ptr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case rule_node: + switch (field) { + case 2: /* dummy subtype */ + break; + case 4: + width(n) = lua_tointeger(L, 3); + break; + case 5: + depth(n) = lua_tointeger(L, 3); + break; + case 6: + height(n) = lua_tointeger(L, 3); + break; + case 7: + rule_dir(n) = nodelib_getdir(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case ins_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + float_cost(n) = lua_tointeger(L, 3); + break; + case 5: + depth(n) = lua_tointeger(L, 3); + break; + case 6: + height(n) = lua_tointeger(L, 3); + break; + case 7: + split_top_ptr(n) = nodelib_getspec(L, 3); + break; + case 8: + ins_ptr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case mark_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + mark_class(n) = lua_tointeger(L, 3); + break; + case 5: + mark_ptr(n) = nodelib_gettoks(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case adjust_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + adjust_ptr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case disc_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + set_disc_field(pre_break(n), nodelib_getlist(L, 3)); + break; + case 5: + set_disc_field(post_break(n), nodelib_getlist(L, 3)); + break; + case 6: + set_disc_field(no_break(n), nodelib_getlist(L, 3)); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case math_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + surround(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case glue_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + glue_ptr(n) = nodelib_getspec(L, 3); + break; + case 5: + leader_ptr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case glue_spec_node: + switch (field) { + case 2: /* dummy subtype */ + break; + case 3: + width(n) = lua_tointeger(L, 3); + break; + case 4: + stretch(n) = lua_tointeger(L, 3); + break; + case 5: + shrink(n) = lua_tointeger(L, 3); + break; + case 6: + stretch_order(n) = lua_tointeger(L, 3); + break; + case 7: + shrink_order(n) = lua_tointeger(L, 3); + break; + case 8: + glue_ref_count(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case kern_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + width(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case penalty_node: + switch (field) { + case 2: /* dummy subtype */ + break; + case 4: + penalty(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case action_node: + switch (field) { + case 2: /* dummy subtype */ + break; + case 3: + pdf_action_type(n) = lua_tointeger(L, 3); + break; + case 4: + pdf_action_named_id(n) = lua_tointeger(L, 3); + break; + case 5: + if (pdf_action_named_id(n) == 1) { + pdf_action_id(n) = nodelib_gettoks(L, 3); + } else { + pdf_action_id(n) = lua_tointeger(L, 3); + } + break; + case 6: + pdf_action_file(n) = nodelib_gettoks(L, 3); + break; + case 7: + pdf_action_new_window(n) = lua_tointeger(L, 3); + break; + case 8: + pdf_action_tokens(n) = nodelib_gettoks(L, 3); + break; + case 9: + pdf_action_refcount(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case style_node: + switch (field) { + case 2: /* dummy subtype */ + break; + case 4: + subtype(n) = luaL_checkoption(L, 3, "text", math_style_names); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case choice_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + display_mlist(n) = nodelib_getlist(L, 3); + break; + case 5: + text_mlist(n) = nodelib_getlist(L, 3); + break; + case 6: + script_mlist(n) = nodelib_getlist(L, 3); + break; + case 7: + script_script_mlist(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case ord_noad: + case op_noad: + case bin_noad: + case rel_noad: + case open_noad: + case close_noad: + case punct_noad: + case inner_noad: + case under_noad: + case over_noad: + case vcenter_noad: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + nucleus(n) = nodelib_getlist(L, 3); + break; + case 5: + subscr(n) = nodelib_getlist(L, 3); + break; + case 6: + supscr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case radical_noad: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + nucleus(n) = nodelib_getlist(L, 3); + break; + case 5: + subscr(n) = nodelib_getlist(L, 3); + break; + case 6: + supscr(n) = nodelib_getlist(L, 3); + break; + case 7: + left_delimiter(n) = nodelib_getlist(L, 3); + break; + case 8: + degree(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case fraction_noad: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + thickness(n) = lua_tointeger(L, 3); + break; + case 5: + numerator(n) = nodelib_getlist(L, 3); + break; + case 6: + denominator(n) = nodelib_getlist(L, 3); + break; + case 7: + left_delimiter(n) = nodelib_getlist(L, 3); + break; + case 8: + right_delimiter(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case accent_noad: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + nucleus(n) = nodelib_getlist(L, 3); + break; + case 5: + subscr(n) = nodelib_getlist(L, 3); + break; + case 6: + supscr(n) = nodelib_getlist(L, 3); + break; + case 7: + accent_chr(n) = nodelib_getlist(L, 3); + break; + case 8: + bot_accent_chr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case fence_noad: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + delimiter(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case math_char_node: + case math_text_char_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + math_fam(n) = lua_tointeger(L, 3); + break; + case 5: + math_character(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case sub_box_node: + case sub_mlist_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + math_list(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case delim_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 4: + small_fam(n) = lua_tointeger(L, 3); + break; + case 5: + small_char(n) = lua_tointeger(L, 3); + break; + case 6: + large_fam(n) = lua_tointeger(L, 3); + break; + case 7: + large_char(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case margin_kern_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 3: + width(n) = lua_tointeger(L, 3); + break; + case 4: + margin_char(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case inserting_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 3: + last_ins_ptr(n) = nodelib_getlist(L, 3); + break; + case 4: + best_ins_ptr(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case split_up_node: + switch (field) { + case 2: + subtype(n) = lua_tointeger(L, 3); + break; + case 3: + last_ins_ptr(n) = nodelib_getlist(L, 3); + break; + case 4: + best_ins_ptr(n) = nodelib_getlist(L, 3); + break; + case 5: + broken_ptr(n) = nodelib_getlist(L, 3); + break; + case 6: + broken_ins(n) = nodelib_getlist(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case attribute_list_node: + switch (field) { + case 2: /* dummy subtype */ + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case attribute_node: + switch (field) { + case 2: /* dummy subtype */ + break; + case 3: + attribute_id(n) = lua_tointeger(L, 3); + break; + case 4: + attribute_value(n) = lua_tointeger(L, 3); + break; + default: + return nodelib_cantset(L, field, n); + } + break; + case whatsit_node: + lua_nodelib_setfield_whatsit(L, n, field); + break; + default: + /* do nothing */ + break; + } } - } - return 0; + return 0; } -static int -lua_nodelib_print (lua_State *L) { - char *msg; - char a[7] = {' ',' ',' ', 'n', 'i', 'l', 0}; - char v[7] = {' ',' ',' ', 'n', 'i', 'l', 0}; - halfword *n; - n = check_isnode(L,1); - msg = xmalloc(256); - if (alink(*n)!=null) - snprintf(a,7,"%6d",(int)alink(*n)); - if (vlink(*n)!=null) - snprintf(v,7,"%6d",(int)vlink(*n)); - snprintf(msg,255," %s : %s %d>", a, (int)*n, v, node_data[type(*n)].name, subtype(*n)); - lua_pushstring(L,msg); - free(msg); - return 1; +static int lua_nodelib_print(lua_State * L) +{ + char *msg; + char a[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 }; + char v[7] = { ' ', ' ', ' ', 'n', 'i', 'l', 0 }; + halfword *n; + n = check_isnode(L, 1); + msg = xmalloc(256); + if (alink(*n) != null) + snprintf(a, 7, "%6d", (int) alink(*n)); + if (vlink(*n) != null) + snprintf(v, 7, "%6d", (int) vlink(*n)); + snprintf(msg, 255, " %s : %s %d>", a, (int) *n, v, + node_data[type(*n)].name, subtype(*n)); + lua_pushstring(L, msg); + free(msg); + return 1; } -static int -lua_nodelib_equal (lua_State *L) { - halfword n, m; - n = *(check_isnode(L,1)); - m = *(check_isnode(L,2)); - lua_pushboolean(L,(n==m)); - return 1; -} - -static int -font_tex_ligaturing (lua_State *L) { - /* on the stack are two nodes and a direction */ - halfword tmp_head; - halfword *h; - halfword t =null; - if (lua_gettop(L)<1) { - lua_pushnil(L); - lua_pushboolean(L,0); - return 2; - } - h = check_isnode(L,1); - if (lua_gettop(L)>1) { - t = *(check_isnode(L,2)); - } - tmp_head = new_node(nesting_node,1); - couple_nodes(tmp_head,*h); - tlink(tmp_head)=t; - t = handle_ligaturing(tmp_head,t); - lua_pushnumber(L,vlink(tmp_head)); - flush_node(tmp_head); - lua_nodelib_push(L); - lua_pushnumber(L,t); - lua_nodelib_push(L); - lua_pushboolean(L,1); - return 3; -} - -static int -font_tex_kerning (lua_State *L) { - /* on the stack are two nodes and a direction */ - - halfword tmp_head; - halfword *h; - halfword t =null; - if (lua_gettop(L)<1) { - lua_pushnil(L); - lua_pushboolean(L,0); - return 2; - } - h = check_isnode(L,1); - if (lua_gettop(L)>1) { - t = *(check_isnode(L,2)); - } - tmp_head = new_node(nesting_node,1); - couple_nodes(tmp_head,*h); - tlink(tmp_head)=t; - t = handle_kerning(tmp_head,t); - lua_pushnumber(L,vlink(tmp_head)); - flush_node(tmp_head); - lua_nodelib_push(L); - lua_pushnumber(L,t); - lua_nodelib_push(L); - lua_pushboolean(L,1); - return 3; +static int lua_nodelib_equal(lua_State * L) +{ + register halfword n, m; + n = *((halfword *) lua_touserdata(L, 1)); + m = *((halfword *) lua_touserdata(L, 2)); + lua_pushboolean(L, (n == m)); + return 1; } -static int -lua_nodelib_protect_glyphs (lua_State *L) { - int t = 0; - halfword head = *(check_isnode(L,1)); - while (head!=null) { - if (type(head)==glyph_node) { - register int s = subtype(head); - if (s<256) { - t = 1; - subtype(head) = ((s&0xFE) << 8); - } - } - head = vlink(head); - } - lua_pushboolean(L,t); - lua_pushvalue(L,1); - return 2; +static int font_tex_ligaturing(lua_State * L) +{ + /* on the stack are two nodes and a direction */ + halfword tmp_head; + halfword *h; + halfword t = null; + if (lua_gettop(L) < 1) { + lua_pushnil(L); + lua_pushboolean(L, 0); + return 2; + } + h = check_isnode(L, 1); + if (lua_gettop(L) > 1) { + t = *(check_isnode(L, 2)); + } + tmp_head = new_node(nesting_node, 1); + couple_nodes(tmp_head, *h); + tlink(tmp_head) = t; + t = handle_ligaturing(tmp_head, t); + lua_pushnumber(L, vlink(tmp_head)); + flush_node(tmp_head); + lua_nodelib_push(L); + lua_pushnumber(L, t); + lua_nodelib_push(L); + lua_pushboolean(L, 1); + return 3; } -static int -lua_nodelib_unprotect_glyphs (lua_State *L) { - int t = 0; - halfword head = *(check_isnode(L,1)); - while (head!=null) { - if (type(head)==glyph_node) { - register int s = subtype(head); - if (s>=256) { - t = 1; - subtype(head) = (s >> 8); - } - } - head = vlink(head); - } - lua_pushboolean(L,t); - lua_pushvalue(L,1); - return 2; +static int font_tex_kerning(lua_State * L) +{ + /* on the stack are two nodes and a direction */ + + halfword tmp_head; + halfword *h; + halfword t = null; + if (lua_gettop(L) < 1) { + lua_pushnil(L); + lua_pushboolean(L, 0); + return 2; + } + h = check_isnode(L, 1); + if (lua_gettop(L) > 1) { + t = *(check_isnode(L, 2)); + } + tmp_head = new_node(nesting_node, 1); + couple_nodes(tmp_head, *h); + tlink(tmp_head) = t; + t = handle_kerning(tmp_head, t); + lua_pushnumber(L, vlink(tmp_head)); + flush_node(tmp_head); + lua_nodelib_push(L); + lua_pushnumber(L, t); + lua_nodelib_push(L); + lua_pushboolean(L, 1); + return 3; } +static int lua_nodelib_protect_glyphs(lua_State * L) +{ + int t = 0; + halfword head = *(check_isnode(L, 1)); + while (head != null) { + if (type(head) == glyph_node) { + register int s = subtype(head); + if (s <= 256) { + t = 1; + subtype(head) = (s == 1 ? 256 : 256 + s); + } + } + head = vlink(head); + } + lua_pushboolean(L, t); + lua_pushvalue(L, 1); + return 2; +} -static int -lua_nodelib_first_character (lua_State *L) { - /* on the stack are two nodes and a direction */ - halfword h, savetail = null, t = null; - if (lua_gettop(L)<1) { - lua_pushnil(L); - lua_pushboolean(L,0); +static int lua_nodelib_unprotect_glyphs(lua_State * L) +{ + int t = 0; + halfword head = *(check_isnode(L, 1)); + while (head != null) { + if (type(head) == glyph_node) { + register int s = subtype(head); + if (s > 256) { + t = 1; + subtype(head) = s - 256; + } + } + head = vlink(head); + } + lua_pushboolean(L, t); + lua_pushvalue(L, 1); + return 2; +} + + +static int lua_nodelib_first_character(lua_State * L) +{ + /* on the stack are two nodes and a direction */ + halfword h, savetail = null, t = null; + if (lua_gettop(L) < 1) { + lua_pushnil(L); + lua_pushboolean(L, 0); + return 2; + } + h = *(check_isnode(L, 1)); + if (lua_gettop(L) > 1) { + t = *(check_isnode(L, 2)); + savetail = vlink(t); + vlink(t) = null; + } + while (h != null && !is_simple_character(h)) { + h = vlink(h); + } + if (savetail != null) { + vlink(t) = savetail; + } + lua_pushnumber(L, h); + lua_nodelib_push(L); + lua_pushboolean(L, (h == null ? 0 : 1)); return 2; - } - h = *(check_isnode(L,1)); - if (lua_gettop(L)>1) { - t = *(check_isnode(L,2)); - savetail = vlink(t); - vlink(t) = null; - } - while (h!=null && !is_simple_character(h)) { - h = vlink(h); - } - if (savetail!=null) { vlink(t) = savetail; } - lua_pushnumber(L,h); - lua_nodelib_push(L); - lua_pushboolean(L,(h==null? 0 : 1)); - return 2; } /* this is too simplistic, but it helps Hans to get going */ -halfword -do_ligature_n (halfword prev, halfword stop, halfword lig) { - vlink(lig) = vlink(stop); - vlink(stop) = null; - lig_ptr(lig) = vlink(prev); - vlink(prev) = lig; - return lig; +halfword do_ligature_n(halfword prev, halfword stop, halfword lig) +{ + vlink(lig) = vlink(stop); + vlink(stop) = null; + lig_ptr(lig) = vlink(prev); + vlink(prev) = lig; + return lig; } /* node.do_ligature_n(node prev, node last, node lig) */ -static int -lua_nodelib_do_ligature_n (lua_State *L) { - halfword n, m, o, p, tmp_head; - n = *(check_isnode(L,1)); - m = *(check_isnode(L,2)); - o = *(check_isnode(L,3)); - if (alink(n)==null || vlink(alink(n))!=n) { - tmp_head = new_node(temp_node,0); - couple_nodes(tmp_head,n); - p = do_ligature_n(tmp_head,m,o); - flush_node(tmp_head); - } else { - p = do_ligature_n(alink(n),m,o); - } - lua_pushnumber(L,p); - lua_nodelib_push(L); - return 1; +static int lua_nodelib_do_ligature_n(lua_State * L) +{ + halfword n, m, o, p, tmp_head; + n = *(check_isnode(L, 1)); + m = *(check_isnode(L, 2)); + o = *(check_isnode(L, 3)); + if (alink(n) == null || vlink(alink(n)) != n) { + tmp_head = new_node(temp_node, 0); + couple_nodes(tmp_head, n); + p = do_ligature_n(tmp_head, m, o); + flush_node(tmp_head); + } else { + p = do_ligature_n(alink(n), m, o); + } + lua_pushnumber(L, p); + lua_nodelib_push(L); + return 1; } -extern halfword list_node_mem_usage (void) ; +extern halfword list_node_mem_usage(void); -static int -lua_nodelib_usedlist (lua_State *L) { - lua_pushnumber(L,list_node_mem_usage()); - lua_nodelib_push(L); - return 1; -} - - -static const struct luaL_reg nodelib_f [] = { - {"id", lua_nodelib_id}, - {"subtype", lua_nodelib_subtype}, - {"type", lua_nodelib_type}, - {"new", lua_nodelib_new}, - {"length", lua_nodelib_length}, - {"count", lua_nodelib_count}, - {"traverse", lua_nodelib_traverse}, - {"traverse_id", lua_nodelib_traverse_filtered}, - {"slide", lua_nodelib_tail}, - {"types", lua_nodelib_types}, - {"whatsits", lua_nodelib_whatsits}, - {"fields", lua_nodelib_fields}, - {"has_field", lua_nodelib_has_field}, - {"free", lua_nodelib_free}, - {"flush_list", lua_nodelib_flush_list}, - {"remove", lua_nodelib_remove}, - {"insert_before", lua_nodelib_insert_before}, - {"insert_after", lua_nodelib_insert_after}, - {"write", lua_nodelib_append}, - {"last_node", lua_nodelib_last_node}, - {"copy", lua_nodelib_copy}, - {"copy_list", lua_nodelib_copy_list}, - {"hpack", lua_nodelib_hpack}, - {"has_attribute", lua_nodelib_has_attribute}, - {"set_attribute", lua_nodelib_set_attribute}, - {"unset_attribute", lua_nodelib_unset_attribute}, - {"do_ligature_n", lua_nodelib_do_ligature_n}, - {"ligaturing", font_tex_ligaturing}, - {"kerning", font_tex_kerning}, - {"first_character", lua_nodelib_first_character}, - {"usedlist", lua_nodelib_usedlist}, - {"protect_glyphs", lua_nodelib_protect_glyphs}, - {"unprotect_glyphs", lua_nodelib_unprotect_glyphs}, - {NULL, NULL} /* sentinel */ +static int lua_nodelib_usedlist(lua_State * L) +{ + lua_pushnumber(L, list_node_mem_usage()); + lua_nodelib_push(L); + return 1; +} + + +static const struct luaL_reg nodelib_f[] = { + {"id", lua_nodelib_id}, + {"subtype", lua_nodelib_subtype}, + {"type", lua_nodelib_type}, + {"new", lua_nodelib_new}, + {"length", lua_nodelib_length}, + {"count", lua_nodelib_count}, + {"traverse", lua_nodelib_traverse}, + {"traverse_id", lua_nodelib_traverse_filtered}, + {"slide", lua_nodelib_tail}, + {"types", lua_nodelib_types}, + {"whatsits", lua_nodelib_whatsits}, + {"fields", lua_nodelib_fields}, + {"has_field", lua_nodelib_has_field}, + {"free", lua_nodelib_free}, + {"flush_list", lua_nodelib_flush_list}, + {"remove", lua_nodelib_remove}, + {"insert_before", lua_nodelib_insert_before}, + {"insert_after", lua_nodelib_insert_after}, + {"write", lua_nodelib_append}, + {"last_node", lua_nodelib_last_node}, + {"copy", lua_nodelib_copy}, + {"copy_list", lua_nodelib_copy_list}, + {"hpack", lua_nodelib_hpack}, + {"vpack", lua_nodelib_vpack}, + {"mlist_to_hlist", lua_nodelib_mlist_to_hlist}, + {"family_font", lua_nodelib_mfont}, + {"has_attribute", lua_nodelib_has_attribute}, + {"set_attribute", lua_nodelib_set_attribute}, + {"unset_attribute", lua_nodelib_unset_attribute}, + {"do_ligature_n", lua_nodelib_do_ligature_n}, + {"ligaturing", font_tex_ligaturing}, + {"kerning", font_tex_kerning}, + {"first_character", lua_nodelib_first_character}, + {"usedlist", lua_nodelib_usedlist}, + {"protect_glyphs", lua_nodelib_protect_glyphs}, + {"unprotect_glyphs", lua_nodelib_unprotect_glyphs}, + {NULL, NULL} /* sentinel */ }; -static const struct luaL_reg nodelib_m [] = { - {"__index", lua_nodelib_getfield}, - {"__newindex", lua_nodelib_setfield}, - {"__tostring", lua_nodelib_print}, - {"__eq", lua_nodelib_equal}, - {NULL, NULL} /* sentinel */ +static const struct luaL_reg nodelib_m[] = { + {"__index", lua_nodelib_getfield}, + {"__newindex", lua_nodelib_setfield}, + {"__tostring", lua_nodelib_print}, + {"__eq", lua_nodelib_equal}, + {NULL, NULL} /* sentinel */ }; -int -luaopen_node (lua_State *L) +int luaopen_node(lua_State * L) { - luaL_newmetatable(L,NODE_METATABLE); - luaL_register(L, NULL, nodelib_m); - luaL_register(L, "node", nodelib_f); - init_luaS_index(luatex_node); - initialize_luaS_indexes(L); - return 1; + luaL_newmetatable(L, NODE_METATABLE); + luaL_register(L, NULL, nodelib_m); + luaL_register(L, "node", nodelib_f); + init_luaS_index(luatex_node); + initialize_luaS_indexes(L); + return 1; } -void -nodelist_to_lua (lua_State *L, int n) { - lua_pushnumber(L,n); - lua_nodelib_push(L); +void nodelist_to_lua(lua_State * L, int n) +{ + lua_pushnumber(L, n); + lua_nodelib_push(L); } -int -nodelist_from_lua (lua_State *L) { - halfword *n; - if (lua_isnil(L,-1)) - return null; - n = check_isnode(L,-1); - return *n; +int nodelist_from_lua(lua_State * L) +{ + halfword *n; + if (lua_isnil(L, -1)) + return null; + n = check_isnode(L, -1); + return *n; } - diff --git a/Build/source/texk/web2c/luatexdir/lua/loslibext.c b/Build/source/texk/web2c/luatexdir/lua/loslibext.c index e79e3a52a98..5f5da8dd6f5 100644 --- a/Build/source/texk/web2c/luatexdir/lua/loslibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/loslibext.c @@ -1,4 +1,21 @@ -/* $Id: loslibext.c 1066 2008-02-23 10:52:51Z taco $ */ +/* loslibext.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include @@ -7,6 +24,15 @@ #include #include +static const char _svn_version[] = + "$Id: loslibext.c 1594 2008-11-28 13:32:48Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/loslibext.c $"; + +#if defined(_WIN32) || defined(WIN32) || defined(__NT__) +#define MKDIR(a,b) mkdir(a) +#else +#define MKDIR(a,b) mkdir(a,b) +#endif + /* An attempt to figure out the basic platform, does not care about niceties like version numbers yet, and ignores platforms where luatex is unlikely to @@ -14,47 +40,48 @@ (amiga|mac|os2|vms) */ #if defined(_WIN32) || defined(WIN32) || defined(__NT__) -#define OS_PLATTYPE "windows" -#define OS_PLATNAME "windows" -#elif defined(__GO32__) || defined(__DJGPP__) || defined(__DOS__) -#define OS_PLATTYPE "msdos" -#define OS_PLATNAME "msdos" -#else /* assume everything else is unix-y */ -#define OS_PLATTYPE "unix" +# define OS_PLATTYPE "windows" +# define OS_PLATNAME "windows" +#elif defined(__GO32__) || defined(__DJGPP__) || defined(__DOS__) +# define OS_PLATTYPE "msdos" +# define OS_PLATNAME "msdos" +#else /* assume everything else is unix-y */ +# include +# define OS_PLATTYPE "unix" /* this is just a first guess */ -#if defined(__BSD__) - #define OS_PLATNAME "bsd" -#elif defined(__SYSV__) - #define OS_PLATNAME "sysv" -#else - #define OS_PLATNAME "generic" -#endif +# if defined(__BSD__) +# define OS_PLATNAME "bsd" +# elif defined(__SYSV__) +# define OS_PLATNAME "sysv" +# else +# define OS_PLATNAME "generic" +# endif /* attempt to be more precise */ -#if defined(__LINUX__) || defined (__linux) - #undef OS_PLATNAME - #define OS_PLATNAME "linux" -#elif defined(__FREEBSD__) || defined(__FreeBSD) - #undef OS_PLATNAME - #define OS_PLATNAME "freebsd" -#elif defined(__OPENBSD__) || defined(__OpenBSD) - #undef OS_PLATNAME - #define OS_PLATNAME "openbsd" -#elif defined(__SOLARIS__) - #undef OS_PLATNAME - #define OS_PLATNAME "solaris" -#elif defined(__SUNOS__) || defined(__SUN__) || defined(sun) - #undef OS_PLATNAME - #define OS_PLATNAME "sunos" -#elif defined(HPUX) || defined(__hpux) - #undef OS_PLATNAME - #define OS_PLATNAME "hpux" -#elif defined(__sgi) - #undef OS_PLATNAME - #define OS_PLATNAME "irix" -#elif defined(__MACH__) && defined(__APPLE__) - #undef OS_PLATNAME - #define OS_PLATNAME "macosx" -#endif +# if defined(__LINUX__) || defined (__linux) +# undef OS_PLATNAME +# define OS_PLATNAME "linux" +# elif defined(__FREEBSD__) || defined(__FreeBSD__) || defined(__FreeBSD) +# undef OS_PLATNAME +# define OS_PLATNAME "freebsd" +# elif defined(__OPENBSD__) || defined(__OpenBSD) +# undef OS_PLATNAME +# define OS_PLATNAME "openbsd" +# elif defined(__SOLARIS__) +# undef OS_PLATNAME +# define OS_PLATNAME "solaris" +# elif defined(__SUNOS__) || defined(__SUN__) || defined(sun) +# undef OS_PLATNAME +# define OS_PLATNAME "sunos" +# elif defined(HPUX) || defined(__hpux) +# undef OS_PLATNAME +# define OS_PLATNAME "hpux" +# elif defined(__sgi) +# undef OS_PLATNAME +# define OS_PLATNAME "irix" +# elif defined(__MACH__) && defined(__APPLE__) +# undef OS_PLATNAME +# define OS_PLATNAME "macosx" +# endif #endif @@ -67,77 +94,76 @@ */ #if (! defined(WIN32)) && (! defined(__SUNOS__)) -#include /* gettimeofday() */ -#include /* times() */ -#include -#endif +# include /* gettimeofday() */ +# include /* times() */ +# include +#endif /* set this to one for spawn instead of exec on windows */ #define DONT_REALLY_EXIT 1 #ifdef WIN32 -#include -#define spawn_command(a,b,c) _spawnvpe(_P_WAIT,(const char *)a,(const char* const*)b,(const char* const*)c) -#if DONT_REALLY_EXIT -#define exec_command(a,b,c) exit(spawn_command((a),(b),(c))) +# include +# define spawn_command(a,b,c) _spawnvpe(_P_WAIT,(const char *)a,(const char* const*)b,(const char* const*)c) +# if DONT_REALLY_EXIT +# define exec_command(a,b,c) exit(spawn_command((a),(b),(c))) +# else +# define exec_command(a,b,c) _execvpe((const char *)a,(const char* const*)b,(const char* const*)c) +# endif #else -#define exec_command(a,b,c) _execvpe((const char *)a,(const char* const*)b,(const char* const*)c) -#endif -#else -#include -#define DEFAULT_PATH "/bin:/usr/bin:." +# include +# define DEFAULT_PATH "/bin:/usr/bin:." -static int -exec_command(const char *file, char *const *argv, char *const *envp) +static int exec_command(const char *file, char *const *argv, char *const *envp) { - char path[PATH_MAX]; - const char *searchpath, *esp; - size_t prefixlen, filelen, totallen; - - if (strchr(file, '/')) /* Specific path */ - return execve(file, argv, envp); - - filelen = strlen(file); - - searchpath = getenv("PATH"); - if (!searchpath) - searchpath = DEFAULT_PATH; - - errno = ENOENT; /* Default errno, if execve() doesn't change it */ - - do { - esp = strchr(searchpath, ':'); - if (esp) - prefixlen = esp - searchpath; - else - prefixlen = strlen(searchpath); - - if (prefixlen == 0 || searchpath[prefixlen - 1] == '/') { - totallen = prefixlen + filelen; - if (totallen >= PATH_MAX) - continue; - memcpy(path, searchpath, prefixlen); - memcpy(path + prefixlen, file, filelen); - } else { - totallen = prefixlen + filelen + 1; - if (totallen >= PATH_MAX) - continue; - memcpy(path, searchpath, prefixlen); - path[prefixlen] = '/'; - memcpy(path + prefixlen + 1, file, filelen); - } - path[totallen] = '\0'; - - execve(path, argv, envp); - if (errno == E2BIG || errno == ENOEXEC || - errno == ENOMEM || errno == ETXTBSY) - break; /* Report this as an error, no more search */ - - searchpath = esp + 1; - } while (esp); - - return -1; + char path[PATH_MAX]; + const char *searchpath, *esp; + size_t prefixlen, filelen, totallen; + + if (strchr(file, '/')) /* Specific path */ + return execve(file, argv, envp); + + filelen = strlen(file); + + searchpath = getenv("PATH"); + if (!searchpath) + searchpath = DEFAULT_PATH; + + errno = ENOENT; /* Default errno, if execve() doesn't change it */ + + do { + esp = strchr(searchpath, ':'); + if (esp) + prefixlen = esp - searchpath; + else + prefixlen = strlen(searchpath); + + if (prefixlen == 0 || searchpath[prefixlen - 1] == '/') { + totallen = prefixlen + filelen; + if (totallen >= PATH_MAX) + continue; + memcpy(path, searchpath, prefixlen); + memcpy(path + prefixlen, file, filelen); + } else { + totallen = prefixlen + filelen + 1; + if (totallen >= PATH_MAX) + continue; + memcpy(path, searchpath, prefixlen); + path[prefixlen] = '/'; + memcpy(path + prefixlen + 1, file, filelen); + } + path[totallen] = '\0'; + + execve(path, argv, envp); + if (errno == E2BIG || errno == ENOEXEC || + errno == ENOMEM || errno == ETXTBSY) + break; /* Report this as an error, no more search */ + + searchpath = esp + 1; + } while (esp); + + return -1; } /* @@ -159,61 +185,66 @@ exec_command(const char *file, char *const *argv, char *const *envp) range in the 8-bit section. */ -#define INVALID_RET_E2BIG 143 -#define INVALID_RET_ENOENT 144 -#define INVALID_RET_ENOEXEC 145 -#define INVALID_RET_ENOMEM 146 -#define INVALID_RET_ETXTBSY 147 -#define INVALID_RET_UNKNOWN 148 -#define INVALID_RET_INTR 149 +# define INVALID_RET_E2BIG 143 +# define INVALID_RET_ENOENT 144 +# define INVALID_RET_ENOEXEC 145 +# define INVALID_RET_ENOMEM 146 +# define INVALID_RET_ETXTBSY 147 +# define INVALID_RET_UNKNOWN 148 +# define INVALID_RET_INTR 149 -static int -spawn_command(const char *file, char *const *argv, char *const *envp) +static int spawn_command(const char *file, char *const *argv, char *const *envp) { - pid_t pid, wait_pid; - int status; - pid = fork(); - if (pid<0) { - return -1; /* fork failed */ - } - if (pid>0) { /* parent */ - status = 0; - wait_pid = waitpid (pid, &status,0); - if (wait_pid == pid) { - if (WIFEXITED(status)) - return WEXITSTATUS(status); - else - return INVALID_RET_INTR; - } else { - return -1; /* some waitpid error */ + pid_t pid, wait_pid; + int status; + pid = fork(); + if (pid < 0) { + return -1; /* fork failed */ } - } else { - int f; - /* somewhat random upper limit. ignore errors on purpose */ - for (f = 0; f<256; f++) - (void)fsync(f); - - if (exec_command(file, argv, envp)) { - /* let's hope no-one uses these values */ - switch (errno) { - case E2BIG: exit(INVALID_RET_E2BIG); - case ETXTBSY: exit(INVALID_RET_ETXTBSY); - case ENOENT: exit(INVALID_RET_ENOENT); - case ENOEXEC: exit(INVALID_RET_ENOEXEC); - case ENOMEM: exit(INVALID_RET_ENOMEM); - default: exit(INVALID_RET_UNKNOWN); - } - return -1; + if (pid > 0) { /* parent */ + status = 0; + wait_pid = waitpid(pid, &status, 0); + if (wait_pid == pid) { + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else + return INVALID_RET_INTR; + } else { + return -1; /* some waitpid error */ + } + } else { + int f; + /* somewhat random upper limit. ignore errors on purpose */ + for (f = 0; f < 256; f++) + (void) fsync(f); + + if (exec_command(file, argv, envp)) { + /* let's hope no-one uses these values */ + switch (errno) { + case E2BIG: + exit(INVALID_RET_E2BIG); + case ETXTBSY: + exit(INVALID_RET_ETXTBSY); + case ENOENT: + exit(INVALID_RET_ENOENT); + case ENOEXEC: + exit(INVALID_RET_ENOEXEC); + case ENOMEM: + exit(INVALID_RET_ENOMEM); + default: + exit(INVALID_RET_UNKNOWN); + } + return -1; + } } - } + return 0; } #endif extern char **environ; -static char ** -do_split_command(char *maincmd) +static char **do_split_command(char *maincmd) { char *piece, *start_piece; char *cmd; @@ -223,299 +254,489 @@ do_split_command(char *maincmd) int in_string = 0; int quoted = 0; if (strlen(maincmd) == 0) - return NULL; + return NULL; /* allocate the array of options first. it will probably be be a little bit too big, but better too much than to little */ - j=2; - for (i = 0; i < strlen(maincmd); i++) { if (maincmd[i]==' ') j++; } + j = 2; + for (i = 0; i < strlen(maincmd); i++) { + if (maincmd[i] == ' ') + j++; + } cmdline = malloc(sizeof(char *) * j); - for (i = 0; i < j; i++) { cmdline[i] = NULL; } + for (i = 0; i < j; i++) { + cmdline[i] = NULL; + } cmd = maincmd; i = 0; - while (cmd[i] == ' ') i++; /* skip leading spaces */ - start_piece = malloc(strlen(cmd)+1); /* a buffer */ + while (cmd[i] == ' ') + i++; /* skip leading spaces */ + start_piece = malloc(strlen(cmd) + 1); /* a buffer */ piece = start_piece; for (; i <= strlen(maincmd); i++) { - if (cmd[i]=='\\' && - (cmd[i+1] == '\\' || cmd[i+1] == '\'' || cmd[i+1] == '"')) { - quoted =1; - continue; - } - if (in_string && cmd[i] == in_string && !quoted) { - in_string = 0; - continue; - } - if ((cmd[i] == '"' || cmd[i] == '\'')&& !quoted) { - in_string = cmd[i]; - continue; - } - if ((in_string==0 && cmd[i] == ' ') || cmd[i]==0) { - *piece = 0; - cmdline[ret++] = xstrdup(start_piece); - piece = start_piece; - while (i < strlen(maincmd) && cmd[(i + 1)] == ' ') - i++; - continue; - } - *piece++ = cmd[i]; - quoted=0; + if (cmd[i] == '\\' && + (cmd[i + 1] == '\\' || cmd[i + 1] == '\'' || cmd[i + 1] == '"')) { + quoted = 1; + continue; + } + if (in_string && cmd[i] == in_string && !quoted) { + in_string = 0; + continue; + } + if ((cmd[i] == '"' || cmd[i] == '\'') && !quoted) { + in_string = cmd[i]; + continue; + } + if ((in_string == 0 && cmd[i] == ' ') || cmd[i] == 0) { + *piece = 0; + cmdline[ret++] = xstrdup(start_piece); + piece = start_piece; + while (i < strlen(maincmd) && cmd[(i + 1)] == ' ') + i++; + continue; + } + *piece++ = cmd[i]; + quoted = 0; } xfree(start_piece); return cmdline; } -static char ** -do_flatten_command(lua_State *L, char **runcmd) { - unsigned int i, j ; - char *s; - char **cmdline = NULL; - *runcmd = NULL; - - for (j = 1;;j++) { - lua_rawgeti(L,-1,j); - if (lua_isnil(L,-1)) { - lua_pop(L,1); - break; - } - lua_pop(L,1); - } - if (j == 1) - return NULL; - cmdline = malloc(sizeof(char *) * (j+1)); - for (i = 1; i <= j; i++) { - cmdline[i] = NULL; - lua_rawgeti(L,-1,i); - if (lua_isnil(L,-1) || (s=(char *)lua_tostring(L,-1))==NULL) { - lua_pop(L,1); - if (i==1) { - xfree(cmdline) ; - return NULL; - } else { - break; - } - } else { - lua_pop(L,1); - cmdline[(i-1)] = xstrdup(s); - } - } - cmdline[i] = NULL; - - lua_rawgeti(L,-1,0); - if (lua_isnil(L,-1) || (s=(char *)lua_tostring(L,-1))==NULL) { - *runcmd = cmdline[0]; - } else { - *runcmd = xstrdup(s); - } - lua_pop(L,1); - - return cmdline; +static char **do_flatten_command(lua_State * L, char **runcmd) +{ + unsigned int i, j; + char *s; + char **cmdline = NULL; + *runcmd = NULL; + + for (j = 1;; j++) { + lua_rawgeti(L, -1, j); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + break; + } + lua_pop(L, 1); + } + if (j == 1) + return NULL; + cmdline = malloc(sizeof(char *) * (j + 1)); + for (i = 1; i <= j; i++) { + cmdline[i] = NULL; + lua_rawgeti(L, -1, i); + if (lua_isnil(L, -1) || (s = (char *) lua_tostring(L, -1)) == NULL) { + lua_pop(L, 1); + if (i == 1) { + xfree(cmdline); + return NULL; + } else { + break; + } + } else { + lua_pop(L, 1); + cmdline[(i - 1)] = xstrdup(s); + } + } + cmdline[i] = NULL; + + lua_rawgeti(L, -1, 0); + if (lua_isnil(L, -1) || (s = (char *) lua_tostring(L, -1)) == NULL) { + *runcmd = cmdline[0]; + } else { + *runcmd = xstrdup(s); + } + lua_pop(L, 1); + + return cmdline; } -static int os_exec (lua_State *L) { - char * maincmd, * runcmd; - char ** cmdline = NULL; +static int os_exec(lua_State * L) +{ + char *maincmd, *runcmd; + char **cmdline = NULL; - if (lua_gettop(L)!=1) { - lua_pushnil(L); - lua_pushliteral(L,"invalid arguments passed"); - return 2; - } - if (lua_type(L,1)==LUA_TSTRING) { - maincmd = (char *)lua_tostring(L, 1); - cmdline = do_split_command(maincmd); - runcmd = cmdline[0]; - } else if (lua_type(L,1)==LUA_TTABLE) { - cmdline = do_flatten_command(L, & runcmd); - } - if (cmdline!=NULL) { + if (lua_gettop(L) != 1) { + lua_pushnil(L); + lua_pushliteral(L, "invalid arguments passed"); + return 2; + } + if (lua_type(L, 1) == LUA_TSTRING) { + maincmd = (char *) lua_tostring(L, 1); + cmdline = do_split_command(maincmd); + runcmd = cmdline[0]; + } else if (lua_type(L, 1) == LUA_TTABLE) { + cmdline = do_flatten_command(L, &runcmd); + } + if (cmdline != NULL) { #if defined(WIN32) && DONT_REALLY_EXIT - exec_command(runcmd, cmdline, environ); + exec_command(runcmd, cmdline, environ); #else - if (exec_command(runcmd, cmdline, environ)==-1) { - lua_pushnil(L); - lua_pushfstring(L,"%s: %s",runcmd, strerror(errno)); - lua_pushnumber(L, errno); - return 3; - } + if (exec_command(runcmd, cmdline, environ) == -1) { + lua_pushnil(L); + lua_pushfstring(L, "%s: %s", runcmd, strerror(errno)); + lua_pushnumber(L, errno); + return 3; + } #endif - } - lua_pushnil(L); - lua_pushliteral(L,"invalid command line passed"); - return 2; + } + lua_pushnil(L); + lua_pushliteral(L, "invalid command line passed"); + return 2; } -#define do_error_return(A,B) do { \ - lua_pushnil(L); \ - lua_pushfstring(L,"%s: %s",runcmd,(A)); \ - lua_pushnumber(L, B); \ - return 3; \ +#define do_error_return(A,B) do { \ + lua_pushnil(L); \ + lua_pushfstring(L,"%s: %s",runcmd,(A)); \ + lua_pushnumber(L, B); \ + return 3; \ } while (0) -static int os_spawn (lua_State *L) { - char * maincmd, * runcmd; - char ** cmdline = NULL; - int i; +static int os_spawn(lua_State * L) +{ + char *maincmd, *runcmd; + char **cmdline = NULL; + int i; - if (lua_gettop(L)!=1) { - lua_pushnil(L); - lua_pushliteral(L,"invalid arguments passed"); - return 2; - } - if (lua_type(L,1)==LUA_TSTRING) { - maincmd = (char *)lua_tostring(L, 1); - cmdline = do_split_command(maincmd); - runcmd = cmdline[0]; - } else if (lua_type(L,1)==LUA_TTABLE) { - cmdline = do_flatten_command(L, &runcmd); - } - if (cmdline!=NULL) { - i = spawn_command(runcmd, cmdline, environ); - if (i==0) { - lua_pushnumber(L, i); - return 1; - } else if (i==-1) { - /* this branch covers WIN32 as well as fork() and waitpid() errors */ - do_error_return(strerror(errno),errno); + if (lua_gettop(L) != 1) { + lua_pushnil(L); + lua_pushliteral(L, "invalid arguments passed"); + return 2; + } + if (lua_type(L, 1) == LUA_TSTRING) { + maincmd = (char *) lua_tostring(L, 1); + cmdline = do_split_command(maincmd); + runcmd = cmdline[0]; + } else if (lua_type(L, 1) == LUA_TTABLE) { + cmdline = do_flatten_command(L, &runcmd); + } + if (cmdline != NULL) { + i = spawn_command(runcmd, cmdline, environ); + if (i == 0) { + lua_pushnumber(L, i); + return 1; + } else if (i == -1) { + /* this branch covers WIN32 as well as fork() and waitpid() errors */ + do_error_return(strerror(errno), errno); #ifndef WIN32 - } else if (i==INVALID_RET_E2BIG) { do_error_return(strerror(E2BIG),i); - } else if (i==INVALID_RET_ENOENT) { do_error_return(strerror(ENOENT),i); - } else if (i==INVALID_RET_ENOEXEC) { do_error_return(strerror(ENOEXEC),i); - } else if (i==INVALID_RET_ENOMEM) { do_error_return(strerror(ENOMEM),i); - } else if (i==INVALID_RET_ETXTBSY) { do_error_return(strerror(ETXTBSY),i); - } else if (i==INVALID_RET_UNKNOWN) { do_error_return("execution failed",i); - } else if (i==INVALID_RET_INTR) { do_error_return("execution interrupted",i); + } else if (i == INVALID_RET_E2BIG) { + do_error_return(strerror(E2BIG), i); + } else if (i == INVALID_RET_ENOENT) { + do_error_return(strerror(ENOENT), i); + } else if (i == INVALID_RET_ENOEXEC) { + do_error_return(strerror(ENOEXEC), i); + } else if (i == INVALID_RET_ENOMEM) { + do_error_return(strerror(ENOMEM), i); + } else if (i == INVALID_RET_ETXTBSY) { + do_error_return(strerror(ETXTBSY), i); + } else if (i == INVALID_RET_UNKNOWN) { + do_error_return("execution failed", i); + } else if (i == INVALID_RET_INTR) { + do_error_return("execution interrupted", i); #endif - } else { - lua_pushnumber(L, i); - return 1; + } else { + lua_pushnumber(L, i); + return 1; + } } - } - lua_pushnil(L); - lua_pushliteral(L,"invalid command line passed"); - return 2; + lua_pushnil(L); + lua_pushliteral(L, "invalid command line passed"); + return 2; } /* Hans wants to set env values */ -static int os_setenv (lua_State *L) { - char *value, *key, *val; - key = (char *)luaL_optstring(L, 1, NULL); - val = (char *)luaL_optstring(L, 2, NULL); - if (key) { - if (val) { - value = xmalloc(strlen(key)+strlen(val)+2); - sprintf(value,"%s=%s",key,val); - if (putenv(value)) { - return luaL_error(L, "unable to change environment"); - } - } else { +static int os_setenv(lua_State * L) +{ + char *value, *key, *val; + key = (char *) luaL_optstring(L, 1, NULL); + val = (char *) luaL_optstring(L, 2, NULL); + if (key) { + if (val) { + value = xmalloc(strlen(key) + strlen(val) + 2); + sprintf(value, "%s=%s", key, val); + if (putenv(value)) { + return luaL_error(L, "unable to change environment"); + } + } else { #if defined(WIN32) || defined(__sun__) || defined(__sun) || defined(_AIX) - value = xmalloc(strlen(key)+2); - sprintf(value,"%s=",key); - if (putenv(value)) { - return luaL_error(L, "unable to change environment"); - } + value = xmalloc(strlen(key) + 2); + sprintf(value, "%s=", key); + if (putenv(value)) { + return luaL_error(L, "unable to change environment"); + } #else - (void)unsetenv(key); -#endif - } - } - lua_pushboolean (L, 1); - return 1; + (void) unsetenv(key); +#endif + } + } + lua_pushboolean(L, 1); + return 1; } -void find_env (lua_State *L){ - char *envitem, *envitem_orig; - char *envkey; - char **envpointer; - envpointer = environ; - lua_getglobal(L,"os"); - if (envpointer!=NULL && lua_istable(L,-1)) { - luaL_checkstack(L,2,"out of stack space"); - lua_pushstring(L,"env"); - lua_newtable(L); - while (*envpointer) { - /* TODO: perhaps a memory leak here */ - luaL_checkstack(L,2,"out of stack space"); - envitem = xstrdup(*envpointer); - envitem_orig = envitem; - envkey=envitem; - while (*envitem != '=') { - envitem++; - } - *envitem=0; - envitem++; - lua_pushstring(L,envkey); - lua_pushstring(L,envitem); - lua_rawset(L,-3); - envpointer++; - free(envitem_orig); +void find_env(lua_State * L) +{ + char *envitem, *envitem_orig; + char *envkey; + char **envpointer; + envpointer = environ; + lua_getglobal(L, "os"); + if (envpointer != NULL && lua_istable(L, -1)) { + luaL_checkstack(L, 2, "out of stack space"); + lua_pushstring(L, "env"); + lua_newtable(L); + while (*envpointer) { + /* TODO: perhaps a memory leak here */ + luaL_checkstack(L, 2, "out of stack space"); + envitem = xstrdup(*envpointer); + envitem_orig = envitem; + envkey = envitem; + while (*envitem != '=') { + envitem++; + } + *envitem = 0; + envitem++; + lua_pushstring(L, envkey); + lua_pushstring(L, envitem); + lua_rawset(L, -3); + envpointer++; + free(envitem_orig); + } + lua_rawset(L, -3); } - lua_rawset(L,-3); - } - lua_pop(L,1); + lua_pop(L, 1); } -static int ex_sleep(lua_State *L) +static int ex_sleep(lua_State * L) { - lua_Number interval = luaL_checknumber(L, 1); - lua_Number units = luaL_optnumber(L, 2, 1); + lua_Number interval = luaL_checknumber(L, 1); + lua_Number units = luaL_optnumber(L, 2, 1); #ifdef WIN32 - Sleep(1e3 * interval / units); -#else /* assumes posix or bsd */ - usleep(1e6 * interval / units); + Sleep(1e3 * interval / units); +#else /* assumes posix or bsd */ + usleep(1e6 * interval / units); #endif - return 0; + return 0; } -#if (! defined (WIN32)) && (! defined (__SUNOS__)) -static int os_times (lua_State *L) { - struct tms r; - (void)times(&r); - lua_newtable(L); - lua_pushnumber(L, ((lua_Number)(r.tms_utime))/(lua_Number)sysconf(_SC_CLK_TCK)); - lua_setfield(L,-2,"utime"); - lua_pushnumber(L, ((lua_Number)(r.tms_stime))/(lua_Number)sysconf(_SC_CLK_TCK)); - lua_setfield(L,-2,"stime"); - lua_pushnumber(L, ((lua_Number)(r.tms_cutime))/(lua_Number)sysconf(_SC_CLK_TCK)); - lua_setfield(L,-2,"cutime"); - lua_pushnumber(L, ((lua_Number)(r.tms_cstime))/(lua_Number)sysconf(_SC_CLK_TCK)); - lua_setfield(L,-2,"cstime"); - return 1; + + +#ifdef WIN32 +# define _UTSNAME_LENGTH 65 + +/* Structure describing the system and machine. */ +struct utsname { + char sysname[_UTSNAME_LENGTH]; + char nodename[_UTSNAME_LENGTH]; + char release[_UTSNAME_LENGTH]; + char version[_UTSNAME_LENGTH]; + char machine[_UTSNAME_LENGTH]; +}; + +/* + * Get name and information about current kernel. + */ +static int uname(struct utsname *uts) +{ + enum { WinNT, Win95, Win98, WinUnknown }; + OSVERSIONINFO osver; + SYSTEM_INFO sysinfo; + DWORD sLength; + DWORD os = WinUnknown; + + memset(uts, 0, sizeof(*uts)); + + osver.dwOSVersionInfoSize = sizeof(osver); + GetVersionEx(&osver); + GetSystemInfo(&sysinfo); + + switch (osver.dwPlatformId) { + case VER_PLATFORM_WIN32_NT: /* NT, Windows 2000 or Windows XP */ + if (osver.dwMajorVersion == 4) + strcpy(uts->sysname, "Windows NT4x"); /* NT4x */ + else if (osver.dwMajorVersion <= 3) + strcpy(uts->sysname, "Windows NT3x"); /* NT3x */ + else if (osver.dwMajorVersion == 5) { + if (osver.dwMinorVersion == 0) + strcpy(uts->sysname, "Windows 2000"); /* 2k */ + else if (osver.dwMinorVersion == 1) + strcpy(uts->sysname, "Windows XP"); /* XP */ + else if (osver.dwMinorVersion == 2) + strcpy(uts->sysname, "Windows Server 2003"); /* Server 2003 */ + } else if (osver.dwMajorVersion == 6) { + /* + if( osver.wProductType == VER_NT_WORKSTATION ) + */ + strcpy(uts->sysname, "Windows Vista"); /* Vista */ + /* + else + strcpy (uts->sysname, "Windows Server 2008"); + */ + } + os = WinNT; + break; + + case VER_PLATFORM_WIN32_WINDOWS: /* Win95, Win98 or WinME */ + if ((osver.dwMajorVersion > 4) || + ((osver.dwMajorVersion == 4) && (osver.dwMinorVersion > 0))) { + if (osver.dwMinorVersion >= 90) + strcpy(uts->sysname, "Windows ME"); /* ME */ + else + strcpy(uts->sysname, "Windows 98"); /* 98 */ + os = Win98; + } else { + strcpy(uts->sysname, "Windows 95"); /* 95 */ + os = Win95; + } + break; + + case VER_PLATFORM_WIN32s: /* Windows 3.x */ + strcpy(uts->sysname, "Windows"); + break; + + default: /* anything else */ + strcpy(uts->sysname, "Windows"); + break; + } + + sprintf(uts->version, "%ld.%02ld", + osver.dwMajorVersion, osver.dwMinorVersion); + + if (osver.szCSDVersion[0] != '\0' && + (strlen(osver.szCSDVersion) + strlen(uts->version) + 1) < + sizeof(uts->version)) { + strcat(uts->version, " "); + strcat(uts->version, osver.szCSDVersion); + } + + sprintf(uts->release, "build %ld", osver.dwBuildNumber & 0xFFFF); + + switch (sysinfo.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_PPC: + strcpy(uts->machine, "ppc"); + break; + case PROCESSOR_ARCHITECTURE_ALPHA: + strcpy(uts->machine, "alpha"); + break; + case PROCESSOR_ARCHITECTURE_MIPS: + strcpy(uts->machine, "mips"); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + /* + * dwProcessorType is only valid in Win95 and Win98 and WinME + * wProcessorLevel is only valid in WinNT + */ + switch (os) { + case Win95: + case Win98: + switch (sysinfo.dwProcessorType) { + case PROCESSOR_INTEL_386: + case PROCESSOR_INTEL_486: + case PROCESSOR_INTEL_PENTIUM: + sprintf(uts->machine, "i%ld", sysinfo.dwProcessorType); + break; + default: + strcpy(uts->machine, "i386"); + break; + } + break; + case WinNT: + sprintf(uts->machine, "i%d86", sysinfo.wProcessorLevel); + break; + default: + strcpy(uts->machine, "unknown"); + break; + } + break; + default: + strcpy(uts->machine, "unknown"); + break; + } + + sLength = sizeof(uts->nodename) - 1; + GetComputerName(uts->nodename, &sLength); + return 0; } #endif -#if ! defined (__SUNOS__) -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) - #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else - #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +static int ex_uname(lua_State * L) +{ + struct utsname uts; + if (uname(&uts) >= 0) { + lua_newtable(L); + lua_pushstring(L, uts.sysname); + lua_setfield(L, -2, "sysname"); + lua_pushstring(L, uts.machine); + lua_setfield(L, -2, "machine"); + lua_pushstring(L, uts.release); + lua_setfield(L, -2, "release"); + lua_pushstring(L, uts.version); + lua_setfield(L, -2, "version"); + lua_pushstring(L, uts.nodename); + lua_setfield(L, -2, "nodename"); + } else { + lua_pushnil(L); + } + return 1; +} + + +#if (! defined (WIN32)) && (! defined (__SUNOS__)) +static int os_times(lua_State * L) +{ + struct tms r; + (void) times(&r); + lua_newtable(L); + lua_pushnumber(L, + ((lua_Number) (r.tms_utime)) / + (lua_Number) sysconf(_SC_CLK_TCK)); + lua_setfield(L, -2, "utime"); + lua_pushnumber(L, + ((lua_Number) (r.tms_stime)) / + (lua_Number) sysconf(_SC_CLK_TCK)); + lua_setfield(L, -2, "stime"); + lua_pushnumber(L, + ((lua_Number) (r.tms_cutime)) / + (lua_Number) sysconf(_SC_CLK_TCK)); + lua_setfield(L, -2, "cutime"); + lua_pushnumber(L, + ((lua_Number) (r.tms_cstime)) / + (lua_Number) sysconf(_SC_CLK_TCK)); + lua_setfield(L, -2, "cstime"); + return 1; +} #endif -static int os_gettimeofday (lua_State *L) { - double v; -#ifndef WIN32 - struct timeval tv; - gettimeofday(&tv, NULL); - v = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; -#else - FILETIME ft; - unsigned __int64 tmpres = 0; +#if ! defined (__SUNOS__) - GetSystemTimeAsFileTime(&ft); +# if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) +# define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +# else +# define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +# endif - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - tmpres /= 10; - tmpres -= DELTA_EPOCH_IN_MICROSECS; /*converting file time to unix epoch*/ - v = (double)tmpres / 1000000.0; -#endif - lua_pushnumber(L, v); - return 1; +static int os_gettimeofday(lua_State * L) +{ + double v; +# ifndef WIN32 + struct timeval tv; + gettimeofday(&tv, NULL); + v = (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; +# else + FILETIME ft; + unsigned __int64 tmpres = 0; + + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + tmpres /= 10; + tmpres -= DELTA_EPOCH_IN_MICROSECS; /*converting file time to unix epoch */ + v = (double) tmpres / 1000000.0; +# endif + lua_pushnumber(L, v); + return 1; } #endif @@ -525,103 +746,110 @@ static int dirs_made = 0; #define MAXTRIES 36*36*36 -char * -do_mkdtemp (char *tmpl) +char *do_mkdtemp(char *tmpl) { - int count ; - int value ; - char *xes = &tmpl[strlen (tmpl) - 6]; - /* this is not really all that random, but it will do */ - if (dirs_made==0) { - srand(time(NULL)); - } - value = rand(); - for (count = 0; count < MAXTRIES; value += 8413, ++count) { - int v = value; - xes[0] = repl[v % 36]; v /= 36; - xes[1] = repl[v % 36]; v /= 36; - xes[2] = repl[v % 36]; v /= 36; - xes[3] = repl[v % 36]; v /= 36; - xes[4] = repl[v % 36]; v /= 36; - xes[5] = repl[v % 36]; - if (mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR) >= 0) { - dirs_made++; - return tmpl; - } else if (errno != EEXIST) { - return NULL; - } + int count; + int value; + char *xes = &tmpl[strlen(tmpl) - 6]; + /* this is not really all that random, but it will do */ + if (dirs_made == 0) { + srand(time(NULL)); + } + value = rand(); + for (count = 0; count < MAXTRIES; value += 8413, ++count) { + int v = value; + xes[0] = repl[v % 36]; + v /= 36; + xes[1] = repl[v % 36]; + v /= 36; + xes[2] = repl[v % 36]; + v /= 36; + xes[3] = repl[v % 36]; + v /= 36; + xes[4] = repl[v % 36]; + v /= 36; + xes[5] = repl[v % 36]; + if (MKDIR(tmpl, S_IRUSR | S_IWUSR | S_IXUSR) >= 0) { + dirs_made++; + return tmpl; + } else if (errno != EEXIST) { + return NULL; + } } - return NULL; + return NULL; } -static int os_tmpdir (lua_State *L) { - char *s, *tempdir; - char *tmp = (char *)luaL_optstring(L, 1, "luatex.XXXXXX"); - if (tmp==NULL || - strlen(tmp)<6 || - (strcmp(tmp+strlen(tmp)-6,"XXXXXX") != 0)) { - lua_pushnil(L); - lua_pushstring(L, "Invalid argument to os.tmpdir()"); - return 2; - } else { - tempdir = xstrdup(tmp); - } +static int os_tmpdir(lua_State * L) +{ + char *s, *tempdir; + char *tmp = (char *) luaL_optstring(L, 1, "luatex.XXXXXX"); + if (tmp == NULL || + strlen(tmp) < 6 || (strcmp(tmp + strlen(tmp) - 6, "XXXXXX") != 0)) { + lua_pushnil(L); + lua_pushstring(L, "Invalid argument to os.tmpdir()"); + return 2; + } else { + tempdir = xstrdup(tmp); + } #ifdef HAVE_MKDTEMP - s = mkdtemp(tempdir); + s = mkdtemp(tempdir); #else - s = do_mkdtemp(tempdir); + s = do_mkdtemp(tempdir); #endif - if (s==NULL) { - int en = errno; /* calls to Lua API may change this value */ - lua_pushnil(L); - lua_pushfstring(L, "%s", strerror(en)); - return 2; - } else { - lua_pushstring(L,s); - return 1; - } + if (s == NULL) { + int en = errno; /* calls to Lua API may change this value */ + lua_pushnil(L); + lua_pushfstring(L, "%s", strerror(en)); + return 2; + } else { + lua_pushstring(L, s); + return 1; + } } -void -open_oslibext (lua_State *L, int safer_option) { - - find_env(L); +void open_oslibext(lua_State * L, int safer_option) +{ - lua_getglobal(L,"os"); - lua_pushcfunction(L, ex_sleep); - lua_setfield(L,-2,"sleep"); - lua_getglobal(L,"os"); - lua_pushliteral(L, OS_PLATTYPE); - lua_setfield(L,-2,"type"); - lua_getglobal(L,"os"); - lua_pushliteral(L, OS_PLATNAME); - lua_setfield(L,-2,"name"); + find_env(L); + + lua_getglobal(L, "os"); + lua_pushcfunction(L, ex_sleep); + lua_setfield(L, -2, "sleep"); + lua_getglobal(L, "os"); + lua_pushliteral(L, OS_PLATTYPE); + lua_setfield(L, -2, "type"); + lua_getglobal(L, "os"); + lua_pushliteral(L, OS_PLATNAME); + lua_setfield(L, -2, "name"); + lua_getglobal(L, "os"); + lua_pushcfunction(L, ex_uname); + lua_setfield(L, -2, "uname"); #if (! defined (WIN32)) && (! defined (__SUNOS__)) - lua_getglobal(L,"os"); - lua_pushcfunction(L, os_times); - lua_setfield(L,-2,"times"); + lua_getglobal(L, "os"); + lua_pushcfunction(L, os_times); + lua_setfield(L, -2, "times"); #endif #if ! defined (__SUNOS__) - lua_getglobal(L,"os"); - lua_pushcfunction(L, os_gettimeofday); - lua_setfield(L,-2,"gettimeofday"); + lua_getglobal(L, "os"); + lua_pushcfunction(L, os_gettimeofday); + lua_setfield(L, -2, "gettimeofday"); #endif - if (!safer_option) { - lua_getglobal(L,"os"); - lua_pushcfunction(L, os_setenv); - lua_setfield(L,-2,"setenv"); - lua_getglobal(L,"os"); - lua_pushcfunction(L, os_exec); - lua_setfield(L,-2,"exec"); - lua_getglobal(L,"os"); - lua_pushcfunction(L, os_spawn); - lua_setfield(L,-2,"spawn"); - lua_getglobal(L,"os"); - lua_pushcfunction(L, os_tmpdir); - lua_setfield(L,-2,"tmpdir"); - - } + if (!safer_option) { + lua_getglobal(L, "os"); + lua_pushcfunction(L, os_setenv); + lua_setfield(L, -2, "setenv"); + lua_getglobal(L, "os"); + lua_pushcfunction(L, os_exec); + lua_setfield(L, -2, "exec"); + lua_getglobal(L, "os"); + lua_pushcfunction(L, os_spawn); + lua_setfield(L, -2, "spawn"); + lua_getglobal(L, "os"); + lua_pushcfunction(L, os_tmpdir); + lua_setfield(L, -2, "tmpdir"); + + } } diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c index 393409b0729..6c1558e47a6 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c @@ -1,8 +1,27 @@ -/* $Id: lpdflib.c 1154 2008-04-13 22:36:03Z oneiros $ */ +/* lpdflib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include +static const char _svn_version[] = + "$Id: lpdflib.c 2072 2009-03-21 08:50:20Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lpdflib.c $"; static int findcurv(lua_State * L) { @@ -20,7 +39,6 @@ static int findcurh(lua_State * L) return 1; } - typedef enum { set_origin, direct_page, direct_always } pdf_lit_mode; int luapdfprint(lua_State * L) @@ -57,13 +75,15 @@ int luapdfprint(lua_State * L) lua_error(L); } } + check_pdfminorversion(); switch (literal_mode) { case (set_origin): - pdf_end_text(); - pdf_set_origin(cur_h, cur_v); + pdf_goto_pagemode(); + pos = synch_p_with_c(cur); + pdf_set_pos(pos.h, pos.v); break; case (direct_page): - pdf_end_text(); + pdf_goto_pagemode(); break; case (direct_always): pdf_end_string_nl(); @@ -80,15 +100,25 @@ int luapdfprint(lua_State * L) return 0; } +/* DANGER! this should go into some header file */ #define obj_type_others 0 static int l_immediateobj(lua_State * L) { + unsigned i; + size_t len; + const char *st; if (!lua_isstring(L, -1)) luaL_error(L, "pdf.immediateobj needs string value"); pdf_create_obj(obj_type_others, 0); pdf_begin_obj(obj_ptr, 1); - pdf_printf("%s\n", lua_tostring(L, -1)); + st = lua_tolstring(L, -1, &len); + for (i = 0; i < len; i++) { + if (i % 16 == 0) + pdfroom(16); + pdf_buf[pdf_ptr++] = st[i]; + } + pdf_puts("\n"); pdf_end_obj(); lua_pop(L, 1); lua_pushinteger(L, obj_ptr); diff --git a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c index 025e851e775..586ded0db4f 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c @@ -1,211 +1,248 @@ -/* $Id: lstatslib.c 1013 2008-02-14 00:09:02Z oneiros $ */ +/* lstatslib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include + +static const char _svn_version[] = + "$Id: lstatslib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lstatslib.c $"; + typedef struct statistic { - const char *name; - char type; - void *value; -} statistic ; + const char *name; + char type; + void *value; +} statistic; extern char *ptexbanner; -/* extern string getcurrentfilenamestring; */ +extern void lua_nodelib_push_fast(lua_State * L, halfword n); -typedef char * (*charfunc)(void); -typedef integer (*intfunc)(void); +typedef char *(*charfunc) (void); +typedef integer(*intfunc) (void); -char *getbanner (void) { - return ptexbanner; +char *getbanner(void) +{ + return ptexbanner; } /* hack, I really should implement the makecstring */ -char *getfilename (void) { - integer t; - t = get_current_name(); - if (t>(1<<21)) - return makecstring(t); - else - return xstrdup (""); +char *getfilename(void) +{ + integer t; + t = get_current_name(); + if (t > (1 << 21)) + return makecstring(t); + else + return xstrdup(""); } -char *getlasterror (void) { - return makecstring(last_error); +char *getlasterror(void) +{ + return makecstring(last_error); } extern int luabytecode_max; extern int luabytecode_bytes; -extern int luastate_max; +static int luastate_max = 1; /* fixed value */ extern int luastate_bytes; +extern int callback_count; +extern int saved_callback_count; static struct statistic stats[] = { - { "pdf_gone", 'g', &pdf_gone }, - { "pdf_ptr", 'g', &pdf_ptr }, - { "dvi_gone", 'g', &dvi_offset }, - { "dvi_ptr", 'g', &dvi_ptr }, - { "total_pages", 'g', &total_pages }, - { "output_file_name", 's', &output_file_name }, - { "log_name", 's', &texmf_log_name }, /* weird */ - { "banner", 'S', &getbanner }, - { "pdftex_banner", 's', &pdftex_banner }, - /* - * mem stat - */ - { "var_used", 'g', &var_used }, - { "dyn_used", 'g', &dyn_used }, - /* - * traditional tex stats - */ - { "str_ptr", 'g', &str_ptr }, - { "init_str_ptr", 'g', &init_str_ptr }, - { "max_strings", 'g', &max_strings }, - { "pool_ptr", 'g', &pool_ptr }, - { "init_pool_ptr", 'g', &init_pool_ptr }, - { "pool_size", 'g', &pool_size }, - { "var_mem_max", 'g', &var_mem_max }, - { "node_mem_usage", 'S', &sprint_node_mem_usage }, - { "fix_mem_max", 'g', &fix_mem_max }, - { "fix_mem_min", 'g', &fix_mem_min }, - { "fix_mem_end", 'g', &fix_mem_end }, - { "cs_count", 'g', &cs_count }, - { "hash_size", 'G', &get_hash_size }, - { "hash_extra", 'g', &hash_extra }, - { "font_ptr", 'G', &max_font_id }, - { "max_in_stack", 'g', &max_in_stack }, - { "max_nest_stack", 'g', &max_nest_stack }, - { "max_param_stack", 'g', &max_param_stack }, - { "max_buf_stack", 'g', &max_buf_stack }, - { "max_save_stack", 'g', &max_save_stack }, - { "stack_size", 'g', &stack_size }, - { "nest_size", 'g', &nest_size }, - { "param_size", 'g', ¶m_size }, - { "buf_size", 'g', &buf_size }, - { "save_size", 'g', &save_size }, - /* pdf stats */ - { "obj_ptr", 'g', &obj_ptr }, - { "obj_tab_size", 'g', &obj_tab_size }, - { "pdf_os_cntr", 'g', &pdf_os_cntr }, - { "pdf_os_objidx", 'g', &pdf_os_objidx }, - { "pdf_dest_names_ptr", 'g', &pdf_dest_names_ptr }, - { "dest_names_size", 'g', &dest_names_size }, - { "pdf_mem_ptr", 'g', &pdf_mem_ptr }, - { "pdf_mem_size", 'g', &pdf_mem_size }, - - { "largest_used_mark", 'g', &biggest_used_mark }, - - { "filename", 'S', &getfilename }, - { "inputid", 'G', &get_current_name }, - { "linenumber", 'g', &line }, - { "lasterrorstring", 'S', &getlasterror }, - - { "luabytecodes", 'g', &luabytecode_max }, - { "luabytecode_bytes", 'g', &luabytecode_bytes }, - { "luastates", 'g', &luastate_max }, - { "luastate_bytes", 'g', &luastate_bytes }, - - { "output_active", 'b', &output_active }, - - { NULL, 0 , 0 } }; - - -static int stats_name_to_id (char *name) { - int i; - for (i=0; stats[i].name!=NULL; i++) { - if (strcmp(stats[i].name, name) == 0) - return i; - } - return 0; + {"pdf_gone", 'g', &pdf_gone}, + {"pdf_ptr", 'g', &pdf_ptr}, + {"dvi_gone", 'g', &dvi_offset}, + {"dvi_ptr", 'g', &dvi_ptr}, + {"total_pages", 'g', &total_pages}, + {"output_file_name", 's', &output_file_name}, + {"log_name", 's', &texmf_log_name}, /* weird */ + {"banner", 'S', &getbanner}, + {"pdftex_banner", 's', &pdftex_banner}, + /* + * mem stat + */ + {"var_used", 'g', &var_used}, + {"dyn_used", 'g', &dyn_used}, + /* + * traditional tex stats + */ + {"str_ptr", 'g', &str_ptr}, + {"init_str_ptr", 'g', &init_str_ptr}, + {"max_strings", 'g', &max_strings}, + {"pool_ptr", 'g', &pool_ptr}, + {"init_pool_ptr", 'g', &init_pool_ptr}, + {"pool_size", 'g', &pool_size}, + {"var_mem_max", 'g', &var_mem_max}, + {"node_mem_usage", 'S', &sprint_node_mem_usage}, + {"fix_mem_max", 'g', &fix_mem_max}, + {"fix_mem_min", 'g', &fix_mem_min}, + {"fix_mem_end", 'g', &fix_mem_end}, + {"cs_count", 'g', &cs_count}, + {"hash_size", 'G', &get_hash_size}, + {"hash_extra", 'g', &hash_extra}, + {"font_ptr", 'G', &max_font_id}, + {"max_in_stack", 'g', &max_in_stack}, + {"max_nest_stack", 'g', &max_nest_stack}, + {"max_param_stack", 'g', &max_param_stack}, + {"max_buf_stack", 'g', &max_buf_stack}, + {"max_save_stack", 'g', &max_save_stack}, + {"stack_size", 'g', &stack_size}, + {"nest_size", 'g', &nest_size}, + {"param_size", 'g', ¶m_size}, + {"buf_size", 'g', &buf_size}, + {"save_size", 'g', &save_size}, + /* pdf stats */ + {"obj_ptr", 'g', &obj_ptr}, + {"obj_tab_size", 'g', &obj_tab_size}, + {"pdf_os_cntr", 'g', &pdf_os_cntr}, + {"pdf_os_objidx", 'g', &pdf_os_objidx}, + {"pdf_dest_names_ptr", 'g', &pdf_dest_names_ptr}, + {"dest_names_size", 'g', &dest_names_size}, + {"pdf_mem_ptr", 'g', &pdf_mem_ptr}, + {"pdf_mem_size", 'g', &pdf_mem_size}, + + {"largest_used_mark", 'g', &biggest_used_mark}, + + {"filename", 'S', &getfilename}, + {"inputid", 'G', &get_current_name}, + {"linenumber", 'g', &line}, + {"lasterrorstring", 'S', &getlasterror}, + + {"luabytecodes", 'g', &luabytecode_max}, + {"luabytecode_bytes", 'g', &luabytecode_bytes}, + {"luastates", 'g', &luastate_max}, + {"luastate_bytes", 'g', &luastate_bytes}, + {"callbacks", 'g', &callback_count}, + {"indirect_callbacks", 'g', &saved_callback_count}, + + {"output_active", 'b', &output_active}, + {"best_page_break", 'n', &best_page_break}, + {NULL, 0, 0} +}; + + +static int stats_name_to_id(char *name) +{ + int i; + for (i = 0; stats[i].name != NULL; i++) { + if (strcmp(stats[i].name, name) == 0) + return i; + } + return 0; } -static int do_getstat (lua_State *L,int i) { - int t; - char *st; - charfunc f; - intfunc g; - int str; - t = stats[i].type; - switch(t) { - case 'S': - f = stats[i].value; - st = f(); - lua_pushstring(L,st); - break; - case 's': - str = *(integer *)(stats[i].value); - if (str) { - lua_pushstring(L,makecstring(str)); - } else { - lua_pushnil(L); - } - break; - case 'G': - g = stats[i].value; - lua_pushnumber(L,g()); - break; - case 'g': - lua_pushnumber(L,*(integer *)(stats[i].value)); - break; - case 'B': - g = stats[i].value; - lua_pushboolean(L,g()); - break; - case 'b': - lua_pushboolean(L,*(integer *)(stats[i].value)); - break; - default: - lua_pushnil(L); - } - return 1; +static int do_getstat(lua_State * L, int i) +{ + int t; + char *st; + charfunc f; + intfunc g; + int str; + t = stats[i].type; + switch (t) { + case 'S': + f = stats[i].value; + st = f(); + lua_pushstring(L, st); + break; + case 's': + str = *(integer *) (stats[i].value); + if (str) { + lua_pushstring(L, makecstring(str)); + } else { + lua_pushnil(L); + } + break; + case 'G': + g = stats[i].value; + lua_pushnumber(L, g()); + break; + case 'g': + lua_pushnumber(L, *(integer *) (stats[i].value)); + break; + case 'B': + g = stats[i].value; + lua_pushboolean(L, g()); + break; + case 'n': + lua_nodelib_push_fast(L, *(halfword *) (stats[i].value)); + break; + case 'b': + lua_pushboolean(L, *(integer *) (stats[i].value)); + break; + default: + lua_pushnil(L); + } + return 1; } -static int getstats (lua_State *L) { - char *st; - int i; - if (lua_isstring(L,-1)) { - st = (char *)lua_tostring(L,-1); - i = stats_name_to_id(st); - if (i>0) { - return do_getstat(L,i); - } - } - return 0; +static int getstats(lua_State * L) +{ + char *st; + int i; + if (lua_isstring(L, -1)) { + st = (char *) lua_tostring(L, -1); + i = stats_name_to_id(st); + if (i > 0) { + return do_getstat(L, i); + } + } + return 0; } -static int setstats (lua_State *L) { - return 0; +static int setstats(lua_State * L) +{ + return 0; } -static int statslist (lua_State *L) { - int i; - luaL_checkstack(L,1,"out of stack space"); - lua_newtable(L); - for (i=0; stats[i].name!=NULL; i++) { - luaL_checkstack(L,2,"out of stack space"); - lua_pushstring(L,stats[i].name); - do_getstat(L,i); - lua_rawset(L,-3); - } - return 1; +static int statslist(lua_State * L) +{ + int i; + luaL_checkstack(L, 1, "out of stack space"); + lua_newtable(L); + for (i = 0; stats[i].name != NULL; i++) { + luaL_checkstack(L, 2, "out of stack space"); + lua_pushstring(L, stats[i].name); + do_getstat(L, i); + lua_rawset(L, -3); + } + return 1; } -static const struct luaL_reg statslib [] = { - {"list",statslist}, - {NULL, NULL} /* sentinel */ +static const struct luaL_reg statslib[] = { + {"list", statslist}, + {NULL, NULL} /* sentinel */ }; -int luaopen_stats (lua_State *L) +int luaopen_stats(lua_State * L) { - luaL_register(L, "status", statslib); - luaL_newmetatable(L,"stats_meta"); - lua_pushstring(L, "__index"); - lua_pushcfunction(L, getstats); - lua_settable(L, -3); - lua_pushstring(L, "__newindex"); - lua_pushcfunction(L, setstats); - lua_settable(L, -3); - lua_setmetatable(L,-2); /* meta to itself */ - return 1; + luaL_register(L, "status", statslib); + luaL_newmetatable(L, "stats_meta"); + lua_pushstring(L, "__index"); + lua_pushcfunction(L, getstats); + lua_settable(L, -3); + lua_pushstring(L, "__newindex"); + lua_pushcfunction(L, setstats); + lua_settable(L, -3); + lua_setmetatable(L, -2); /* meta to itself */ + return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c index a61409b2943..c07d3cac696 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c @@ -1,117 +1,160 @@ -/* $Id: ltexiolib.c 1013 2008-02-14 00:09:02Z oneiros $ */ +/* ltexiolib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include +static const char _svn_version[] = + "$Id: ltexiolib.c 2027 2009-03-14 18:47:32Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/ltexiolib.c $"; + typedef void (*texio_printer) (strnumber s); static char *loggable_info = NULL; -static int -do_texio_print (lua_State *L, texio_printer printfunction) { - strnumber texs,u; - char *s; - char save_selector; - int n,i; - size_t k; - u = 0; - n = lua_gettop(L); - if (n==0 || !lua_isstring(L, -1)) { - lua_pushstring(L, "no string to print"); - lua_error(L); - } - save_selector = selector; - i = 1; - if (n>1) { - s=(char *)lua_tostring(L, 1); - if (strcmp(s,"log") == 0) { i++; selector = log_only; } - else if (strcmp(s,"term") == 0) { i++; selector = term_only; } - else if (strcmp(s,"term and log") == 0) { i++; selector = term_and_log; } - } - if (selector!=log_only && selector!=term_only && selector != term_and_log) { - normalize_selector(); /* sets selector */ - } - /* just in case there is a string in progress */ - if (str_start[str_ptr-0x200000] 1) { + if (get_selector_value(L, i, &selector)) + i++; + } + if (selector != log_only && selector != term_only + && selector != term_and_log) { + normalize_selector(); /* sets selector */ + } + /* just in case there is a string in progress */ + if (str_start[str_ptr - 0x200000] < pool_ptr) + u = make_string(); + for (; i <= n; i++) { + if (lua_isstring(L, i)) { + s = (char *) lua_tolstring(L, i, &k); + texs = maketexlstring(s, k); + printfunction(texs); + flush_str(texs); + } else { + lua_pushstring(L, "argument is not a string"); + lua_error(L); + } + } + selector = save_selector; + if (u != 0) + str_ptr--; + return 0; } -static void -do_texio_ini_print (lua_State *L, char *extra) { - char *s; - int i,n,l; - n = lua_gettop(L); - i = 1; - l = 3; - if (n>1) { - s=(char *)lua_tostring(L, 1); - if (strcmp(s,"log") == 0) { i++; l = 1; } - else if (strcmp(s,"term") == 0) { i++; l = 2; } - else if (strcmp(s,"term and log") == 0) { i++; l = 3; } - } - for (;i<=n;i++) { - if(lua_isstring(L, i)) { - s = (char *)lua_tostring(L, i); - if (l==2||l==3) - fprintf(stdout,"%s%s", extra, s); - if (l==1||l==3) { - if (loggable_info==NULL) { - loggable_info = strdup(s); - } else { - char *v = concat3 (loggable_info,extra,s); - free(loggable_info); - loggable_info = v; - } - } - } - } +static void do_texio_ini_print(lua_State * L, char *extra) +{ + char *s; + int i = 1; + char l = term_and_log; + int n = lua_gettop(L); + if (n > 1) { + if (get_selector_value(L, i, &l)) + i++; + } + for (; i <= n; i++) { + if (lua_isstring(L, i)) { + s = (char *) lua_tostring(L, i); + if (l == term_and_log || l == term_only) + fprintf(stdout, "%s%s", extra, s); + if (l == log_only || l == term_and_log) { + if (loggable_info == NULL) { + loggable_info = strdup(s); + } else { + char *v = concat3(loggable_info, extra, s); + free(loggable_info); + loggable_info = v; + } + } + } + } } -static int -texio_print (lua_State *L) { - if (ready_already!=314159 || pool_ptr==0 || job_name==0) { - do_texio_ini_print(L,""); - return 0; - } - return do_texio_print(L,zprint); +static int texio_print(lua_State * L) +{ + if (ready_already != 314159 || pool_ptr == 0 || job_name == 0) { + do_texio_ini_print(L, ""); + return 0; + } + return do_texio_print(L, zprint); } -static int -texio_printnl (lua_State *L) { - if (ready_already!=314159 || pool_ptr==0 || job_name==0) { - do_texio_ini_print(L,"\n"); - return 0; - } - return do_texio_print(L,zprint_nl); +static int texio_printnl(lua_State * L) +{ + if (ready_already != 314159 || pool_ptr == 0 || job_name == 0) { + do_texio_ini_print(L, "\n"); + return 0; + } + return do_texio_print(L, zprint_nl); } /* at the point this function is called, the selector is log_only */ -void flush_loggable_info (void) { - if (loggable_info!=NULL) { - fprintf(log_file,"%s\n",loggable_info); - free(loggable_info); - loggable_info=NULL; - } +void flush_loggable_info(void) +{ + if (loggable_info != NULL) { + fprintf(log_file, "%s\n", loggable_info); + free(loggable_info); + loggable_info = NULL; + } } -static const struct luaL_reg texiolib [] = { - {"write", texio_print}, - {"write_nl", texio_printnl}, - {NULL, NULL} /* sentinel */ +static const struct luaL_reg texiolib[] = { + {"write", texio_print}, + {"write_nl", texio_printnl}, + {NULL, NULL} /* sentinel */ }; -int -luaopen_texio (lua_State *L) { - luaL_register(L,"texio",texiolib); - return 1; +int luaopen_texio(lua_State * L) +{ + luaL_register(L, "texio", texiolib); + return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c index 937c802727a..a847d89f12e 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -1,191 +1,226 @@ -/* $Id: ltexlib.c 1168 2008-04-15 13:43:34Z taco $ */ +/* ltexlib.c + + Copyright 2006-2009 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "nodes.h" +#include "commands.h" +#include "tokens.h" + +static const char _svn_version[] = + "$Id: ltexlib.c 2079 2009-03-22 10:15:03Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/ltexlib.c $"; + +extern halfword *check_isnode(lua_State * L, int ud); +extern void lua_nodelib_push_fast(lua_State * L, halfword n); typedef struct { - char *text; - unsigned int tsize; - void *next; - unsigned char partial; - int cattable; + char *text; + unsigned int tsize; + void *next; + boolean partial; + integer cattable; } rope; typedef struct { - rope *head; - rope *tail; - char complete; /* currently still writing ? */ + rope *head; + rope *tail; + char complete; /* currently still writing ? */ } spindle; #define PARTIAL_LINE 1 #define FULL_LINE 0 -#define NO_CAT_TABLE -2 -#define DEFAULT_CAT_TABLE -1 - #define write_spindle spindles[spindle_index] #define read_spindle spindles[(spindle_index-1)] -static int spindle_size = 0; -static spindle *spindles = NULL; -static int spindle_index = 0; - - -static int -do_luacprint (lua_State * L, int partial, int deftable) { - int i, n; - size_t tsize; - char *st, *sttemp; - rope *rn; - int cattable = deftable; - int startstrings = 1; - n = lua_gettop(L); - if (cattable != NO_CAT_TABLE) { - if (lua_type(L,1)==LUA_TNUMBER && n>1) { - cattable = lua_tonumber(L, 1); - startstrings = 2; - } - } - for (i = startstrings; i <= n; i++) { - if (!lua_isstring(L, i)) { - lua_pushstring(L, "no string to print"); - lua_error(L); - } - sttemp = (char *)lua_tolstring(L, i,&tsize); - st = xmalloc((tsize+1)); - memcpy(st,sttemp,(tsize+1)); +static int spindle_size = 0; +static spindle *spindles = NULL; +static int spindle_index = 0; + +static void +luac_store (lua_State *L, int i, int partial, integer cattable) +{ + char *st, *sttemp; + size_t tsize; + rope *rn = NULL; + sttemp = (char *) lua_tolstring(L, i, &tsize); + st = xmalloc((tsize + 1)); + memcpy(st, sttemp, (tsize + 1)); if (st) { - /* fprintf(stderr,"W[%d]:=%s\n",spindle_index,st);*/ - luacstrings++; - rn = (rope *)xmalloc(sizeof(rope)); /* valgrind says we leak here */ - rn->text = st; - rn->tsize = tsize; - rn->partial = partial; - rn->cattable = cattable; - rn->next = NULL; - if (write_spindle.head == NULL) { - assert(write_spindle.tail == NULL); - write_spindle.head = rn; - } else { - write_spindle.tail->next = rn; - } - write_spindle.tail = rn; - write_spindle.complete = 0; + luacstrings++; + rn = (rope *) xmalloc(sizeof(rope)); + rn->text = st; + rn->tsize = tsize; + rn->partial = partial; + rn->cattable = cattable; + rn->next = NULL; + if (write_spindle.head == NULL) { + assert(write_spindle.tail == NULL); + write_spindle.head = rn; + } else { + write_spindle.tail->next = rn; + } + write_spindle.tail = rn; + write_spindle.complete = 0; } - } - return 0; } -int luacwrite(lua_State * L) { - return do_luacprint(L,FULL_LINE,NO_CAT_TABLE); -} -int luacprint(lua_State * L) { - return do_luacprint(L,FULL_LINE,DEFAULT_CAT_TABLE); +static int +do_luacprint(lua_State * L, int partial, int deftable) +{ + int i, n; + integer cattable = (integer) deftable; + int startstrings = 1; + n = lua_gettop(L); + if (cattable != NO_CAT_TABLE) { + if (lua_type(L, 1) == LUA_TNUMBER && n > 1) { + cattable = lua_tonumber(L, 1); + startstrings = 2; + } + } + if (lua_type(L, startstrings) == LUA_TTABLE) { + for (i = 1; ; i++) { + lua_rawgeti(L,startstrings, i); + if (lua_isstring(L, -1)) { + luac_store(L, -1, partial, cattable); + lua_pop(L,1); + } else { + break; + } + } + } else { + for (i = startstrings; i <= n; i++) { + if (!lua_isstring(L, i)) { + lua_pushstring(L, "no string to print"); + lua_error(L); + } + luac_store(L,i, partial, cattable); + } + } + return 0; } -int luacsprint(lua_State * L) { - return do_luacprint(L,PARTIAL_LINE,DEFAULT_CAT_TABLE); +int luacwrite(lua_State * L) +{ + return do_luacprint(L, FULL_LINE, NO_CAT_TABLE); } -int -luacstring_detokenized (void) { - return (read_spindle.tail->cattable == NO_CAT_TABLE); +int luacprint(lua_State * L) +{ + return do_luacprint(L, FULL_LINE, DEFAULT_CAT_TABLE); } -int -luacstring_defaultcattable (void) { - return (read_spindle.tail->cattable == DEFAULT_CAT_TABLE); +int luacsprint(lua_State * L) +{ + return do_luacprint(L, PARTIAL_LINE, DEFAULT_CAT_TABLE); } -integer -luacstring_cattable (void) { - return (integer)read_spindle.tail->cattable; +integer luacstring_cattable(void) +{ + return (integer) read_spindle.tail->cattable; } -int -luacstring_simple (void) { - return (read_spindle.tail->partial == PARTIAL_LINE); +int luacstring_partial(void) +{ + return read_spindle.tail->partial; } -int -luacstring_penultimate (void) { - return (read_spindle.tail->next == NULL); +int luacstring_final_line(void) +{ + return (read_spindle.tail->next == NULL); } -int -luacstring_input (void) { - char *st; - int ret; - rope *t = read_spindle.head; - if (!read_spindle.complete) { - read_spindle.complete =1; - read_spindle.tail = NULL; - } - if (t == NULL) { - if(read_spindle.tail != NULL) - free(read_spindle.tail); - read_spindle.tail = NULL; - return 0; - } - if (t->text != NULL) { - st = t->text; - /* put that thing in the buffer */ - last = first; - ret = last; - check_buffer_overflow (last + t->tsize); - /* make sure it fits in the pool as well (for show_token_list c.s) */ - check_pool_overflow(pool_ptr + t->tsize); - while (t->tsize-->0) - buffer[last++] = *st++; - if (!t->partial) { - while (last-1>ret && buffer[last-1] == ' ') - last--; - } - free (t->text); - t->text = NULL; - } - if (read_spindle.tail != NULL) { /* not a one-liner */ - free(read_spindle.tail); - } - read_spindle.tail = t; - read_spindle.head = t->next; - return 1; +int luacstring_input(void) +{ + char *st; + int ret; + rope *t = read_spindle.head; + if (!read_spindle.complete) { + read_spindle.complete = 1; + read_spindle.tail = NULL; + } + if (t == NULL) { + if (read_spindle.tail != NULL) + free(read_spindle.tail); + read_spindle.tail = NULL; + return 0; + } + if (t->text != NULL) { + st = t->text; + /* put that thing in the buffer */ + last = first; + ret = last; + check_buffer_overflow(last + t->tsize); + /* make sure it fits in the pool as well (for show_token_list c.s) */ + check_pool_overflow(pool_ptr + t->tsize); + while (t->tsize-- > 0) + buffer[last++] = *st++; + if (!t->partial) { + while (last - 1 > ret && buffer[last - 1] == ' ') + last--; + } + free(t->text); + t->text = NULL; + } + if (read_spindle.tail != NULL) { /* not a one-liner */ + free(read_spindle.tail); + } + read_spindle.tail = t; + read_spindle.head = t->next; + return 1; } /* open for reading, and make a new one for writing */ -void -luacstring_start (int n) { - spindle_index++; - if(spindle_size == spindle_index) { /* add a new one */ - spindles = xrealloc(spindles,sizeof(spindle)*(spindle_size+1)); - spindles[spindle_index].head = NULL; - spindles[spindle_index].tail = NULL; - spindles[spindle_index].complete = 0; - spindle_size++; - } +void luacstring_start(int n) +{ + (void) n; /* for -W */ + spindle_index++; + if (spindle_size == spindle_index) { /* add a new one */ + spindles = xrealloc(spindles, sizeof(spindle) * (spindle_size + 1)); + spindles[spindle_index].head = NULL; + spindles[spindle_index].tail = NULL; + spindles[spindle_index].complete = 0; + spindle_size++; + } } /* close for reading */ -void -luacstring_close (int n) { - rope *next, *t; - next = read_spindle.head; - while (next != NULL) { - if (next->text != NULL) - free(next->text); - t = next; - next = next->next; - free(t); - } - read_spindle.head = NULL; - if(read_spindle.tail != NULL) - free(read_spindle.tail); - read_spindle.tail = NULL; - read_spindle.complete = 0; - spindle_index--; +void luacstring_close(int n) +{ + rope *next, *t; + (void) n; /* for -W */ + next = read_spindle.head; + while (next != NULL) { + if (next->text != NULL) + free(next->text); + t = next; + next = next->next; + free(t); + } + read_spindle.head = NULL; + if (read_spindle.tail != NULL) + free(read_spindle.tail); + read_spindle.tail = NULL; + read_spindle.complete = 0; + spindle_index--; } /* local (static) versions */ @@ -196,653 +231,1210 @@ luacstring_close (int n) { #define check_index_range(j) \ if (j > 65535) { \ - lua_pushstring(L, "incorrect index value"); \ - lua_error(L); } - - -int dimen_to_number (lua_State *L,char *s){ - double v; - char *d; - int j; - v = strtod(s,&d); - if (strcmp (d,"in") == 0) { j = (int)(((v*7227)/100) *65536); } - else if (strcmp (d,"pc") == 0) { j = (int)((v*12) *65536); } - else if (strcmp (d,"cm") == 0) { j = (int)(((v*7227)/254) *65536); } - else if (strcmp (d,"mm") == 0) { j = (int)(((v*7227)/2540) *65536); } - else if (strcmp (d,"bp") == 0) { j = (int)(((v*7227)/7200) *65536); } - else if (strcmp (d,"dd") == 0) { j = (int)(((v*1238)/1157) *65536); } - else if (strcmp (d,"cc") == 0) { j = (int)(((v*14856)/1157) *65536); } - else if (strcmp (d,"nd") == 0) { j = (int)(((v*21681)/20320)*65536); } - else if (strcmp (d,"nc") == 0) { j = (int)(((v*65043)/5080) *65536); } - else if (strcmp (d,"pt") == 0) { j = (int)(v *65536); } - else if (strcmp (d,"sp") == 0) { j = (int)(v); } - else { - lua_pushstring(L, "unknown dimension specifier"); - lua_error(L); - j = 0; - } - return j; -} - -int setdimen (lua_State *L) { - int i,j; - size_t k; - int cur_cs; - int texstr; - char *s; - i = lua_gettop(L); - j = 0; - /* find the value*/ - if (!lua_isnumber(L,i)) - if (lua_isstring(L,i)) { - j = dimen_to_number(L,(char *)lua_tostring(L,i)); + lua_pushstring(L, "incorrect index value"); \ + lua_error(L); } + + +int dimen_to_number(lua_State * L, char *s) +{ + double v; + char *d; + int j; + v = strtod(s, &d); + if (strcmp(d, "in") == 0) { + j = (int) (((v * 7227) / 100) * 65536); + } else if (strcmp(d, "pc") == 0) { + j = (int) ((v * 12) * 65536); + } else if (strcmp(d, "cm") == 0) { + j = (int) (((v * 7227) / 254) * 65536); + } else if (strcmp(d, "mm") == 0) { + j = (int) (((v * 7227) / 2540) * 65536); + } else if (strcmp(d, "bp") == 0) { + j = (int) (((v * 7227) / 7200) * 65536); + } else if (strcmp(d, "dd") == 0) { + j = (int) (((v * 1238) / 1157) * 65536); + } else if (strcmp(d, "cc") == 0) { + j = (int) (((v * 14856) / 1157) * 65536); + } else if (strcmp(d, "nd") == 0) { + j = (int) (((v * 21681) / 20320) * 65536); + } else if (strcmp(d, "nc") == 0) { + j = (int) (((v * 65043) / 5080) * 65536); + } else if (strcmp(d, "pt") == 0) { + j = (int) (v * 65536); + } else if (strcmp(d, "sp") == 0) { + j = (int) (v); } else { - lua_pushstring(L, "unsupported value type"); - lua_error(L); - } - else - j = (int)lua_tonumber(L,i); - /* find the index*/ - if (lua_type(L,i-1)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i-1, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - k = zget_equiv(cur_cs)-get_scaled_base(); - } else { - k = (int)luaL_checkinteger(L,i-1); - } - check_index_range(k); - if(set_tex_dimen_register(k,j)) { - lua_pushstring(L, "incorrect value"); - lua_error(L); - } - return 0; -} - -int getdimen (lua_State *L) { - int i,j; - size_t k; - int cur_cs; - int texstr; - char *s; - i = lua_gettop(L); - if (lua_type(L,i)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs)-get_scaled_base(); - } else { - k = (int)luaL_checkinteger(L,i); - } - check_index_range(k); - j = get_tex_dimen_register(k); - lua_pushnumber(L, j); - return 1; -} - -int setcount (lua_State *L) { - int i,j; - size_t k; - int cur_cs; - int texstr; - char *s; - i = lua_gettop(L); - j = (int)luaL_checkinteger(L,i); - if (lua_type(L,i-1)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i-1,&k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - k = zget_equiv(cur_cs)-get_count_base(); - } else { - k = (int)luaL_checkinteger(L,i-1); - } - check_index_range(k); - if (set_tex_count_register(k,j)) { - lua_pushstring(L, "incorrect value"); - lua_error(L); - } - return 0; -} - -int getcount (lua_State *L) { - int i, j; - size_t k; - int cur_cs; - int texstr; - char *s; - i = lua_gettop(L); - if (lua_type(L,i)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs)-get_count_base(); - } else { - k = (int)luaL_checkinteger(L,i); - } - check_index_range(k); - j = get_tex_count_register(k); - lua_pushnumber(L, j); - return 1; -} - - -int setattribute (lua_State *L) { - int i,j; - size_t k; - int cur_cs; - int texstr; - char *s; - i = lua_gettop(L); - j = (int)luaL_checkinteger(L,i); - if (lua_type(L,i-1)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i-1, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - k = zget_equiv(cur_cs)-get_attribute_base(); - } else { - k = (int)luaL_checkinteger(L,i-1); - } - check_index_range(k); - if (set_tex_attribute_register(k,j)) { - lua_pushstring(L, "incorrect value"); - lua_error(L); - } - return 0; -} - -int getattribute (lua_State *L) { - int i, j; - size_t k; - int cur_cs; - int texstr; - char *s; - i = lua_gettop(L); - if (lua_type(L,i)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs)-get_attribute_base(); - } else { - k = (int)luaL_checkinteger(L,i); - } - check_index_range(k); - j = get_tex_attribute_register(k); - lua_pushnumber(L, j); - return 1; -} - -int settoks (lua_State *L) { - int i,j; - size_t k,len; - int cur_cs; - int texstr; - char *s, *st; - i = lua_gettop(L); - if (!lua_isstring(L,i)) { - lua_pushstring(L, "unsupported value type"); - lua_error(L); - } - st = (char *)lua_tolstring(L,i,&len); - - if (lua_type(L,i-1)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i-1, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - k = zget_equiv(cur_cs)-get_toks_base(); - } else { - k = (int)luaL_checkinteger(L,i-1); - } - check_index_range(k); - j = maketexlstring(st,len); - - if(zset_tex_toks_register(k,j)) { - flush_str(j); - lua_pushstring(L, "incorrect value"); - lua_error(L); - } - return 0; -} - -int gettoks (lua_State *L) { - int i; - size_t k; - strnumber t; - int cur_cs; - int texstr; - char *s; - i = lua_gettop(L); - if (lua_type(L,i)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - flush_str(texstr); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs)-get_toks_base(); - } else { - k = (int)luaL_checkinteger(L,i); - } - - check_index_range(k); - t = get_tex_toks_register(k); - lua_pushstring(L, makecstring(t)); - flush_str(t); - return 1; -} - -/* UGLY hack */ - -#define char_given 70 -#define math_given 71 -#define omath_given 72 - -static int get_box_id (lua_State *L, int i) { - const char *s; - integer cur_cs, cur_cmd; - str_number texstr; - size_t k = 0; - int j = -1; - if (lua_type(L,i)==LUA_TSTRING) { - s = (char *)lua_tolstring(L,i, &k); - texstr = maketexlstring(s,k); - cur_cs = string_lookup(texstr); - cur_cmd = zget_eq_type(cur_cs); - flush_str(texstr); - if (cur_cmd==char_given || - cur_cmd==math_given || - cur_cmd==omath_given) { - j = zget_equiv(cur_cs); - } - } else { - j = (int)lua_tonumber(L,(i)); - } - return j; -} - -int getbox (lua_State *L) { - int k, t; - k = get_box_id(L,-1); - check_index_range(k); - t = get_tex_box_register(k); - nodelist_to_lua(L,t); - return 1; -} - -int setbox (lua_State *L) { - int i,j,k; - k = get_box_id(L,-2); - check_index_range(k); - i = get_tex_box_register(k); - if (lua_isboolean(L,-1)) { - j = lua_toboolean(L,-1); - if (j==0) - j = null; - else - return 0; - } else { - j = nodelist_from_lua(L); - } - if(set_tex_box_register(k,j)) { - lua_pushstring(L, "incorrect value"); - lua_error(L); - } - return 0; -} - -static int getboxdim (lua_State *L, int whichdim) { - int i, j; - i = lua_gettop(L); - j = get_box_id(L,i); - lua_settop(L,(i-2)); /* table at -1 */ - if (j<0 || j > 65535) { - lua_pushstring(L, "incorrect index"); - lua_error(L); - } - switch (whichdim) { - case width_offset: - lua_pushnumber(L, get_tex_box_width(j)); - break; - case height_offset: - lua_pushnumber(L, get_tex_box_height(j)); - break; - case depth_offset: - lua_pushnumber(L, get_tex_box_depth(j)); - } - return 1; -} - -int getboxwd (lua_State *L) { - return getboxdim (L, width_offset); -} - -int getboxht (lua_State *L) { - return getboxdim (L, height_offset); -} - -int getboxdp (lua_State *L) { - return getboxdim (L, depth_offset); -} - -static int setboxdim (lua_State *L, int whichdim) { - int i,j,k,err; - i = lua_gettop(L); - if (!lua_isnumber(L,i)) { - j = dimen_to_number(L,(char *)lua_tostring(L,i)); - } else { - j = (int)lua_tonumber(L,i); - } - k = get_box_id(L,(i-1)); - lua_settop(L,(i-3)); /* table at -2 */ - if (k<0 || k > 65535) { - lua_pushstring(L, "incorrect index"); - lua_error(L); - } - err = 0; - switch (whichdim) { - case width_offset: - err = set_tex_box_width(k,j); - break; - case height_offset: - err = set_tex_box_height(k,j); - break; - case depth_offset: - err = set_tex_box_depth(k,j); - } - if (err) { - lua_pushstring(L, "not a box"); - lua_error(L); - } - return 0; -} - -int setboxwd (lua_State *L) { - return setboxdim(L,width_offset); -} - -int setboxht (lua_State *L) { - return setboxdim(L,height_offset); -} - -int setboxdp (lua_State *L) { - return setboxdim(L,depth_offset); -} - -int settex (lua_State *L) { - char *st; - int i,j,texstr; - size_t k; - int cur_cs, cur_cmd; - j = 0; - i = lua_gettop(L); - if (lua_isstring(L,(i-1))) { - st = (char *)lua_tolstring(L,(i-1), &k); - texstr = maketexlstring(st,k); - if (zis_primitive(texstr)) { - cur_cs = string_lookup(texstr); - flush_str(texstr); - cur_cmd = zget_eq_type(cur_cs); - if (is_int_assign(cur_cmd)) { - if (lua_isnumber(L,i)) { - assign_internal_int(zget_equiv(cur_cs),lua_tonumber(L,i)); - } else { - lua_pushstring(L, "unsupported value type"); - lua_error(L); - } - } else if (is_dim_assign(cur_cmd)) { - if (!lua_isnumber(L,i)) - if (lua_isstring(L,i)) { - j = dimen_to_number(L,(char *)lua_tostring(L,i)); - } else { - lua_pushstring(L, "unsupported value type"); - lua_error(L); - } - else - j = (int)lua_tonumber(L,i); - assign_internal_dim(zget_equiv(cur_cs),j); - } else { - lua_pushstring(L, "unsupported tex internal assignment"); - lua_error(L); - } + lua_pushstring(L, "unknown dimension specifier"); + lua_error(L); + j = 0; + } + return j; +} + +int setdimen(lua_State * L) +{ + int i, j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + j = 0; + /* find the value */ + if (!lua_isnumber(L, i)) + if (lua_isstring(L, i)) { + j = dimen_to_number(L, (char *) lua_tostring(L, i)); + } else { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } else + j = (int) lua_tonumber(L, i); + /* find the index */ + if (lua_type(L, i - 1) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i - 1, &k); + cur_cs = string_lookup(s, k); + k = zget_equiv(cur_cs) - get_scaled_base(); + } else { + k = (int) luaL_checkinteger(L, i - 1); + } + check_index_range(k); + if (set_tex_dimen_register(k, j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int getdimen(lua_State * L) +{ + int i, j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + if (lua_type(L, i) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i, &k); + cur_cs = string_lookup(s, k); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs) - get_scaled_base(); + } else { + k = (int) luaL_checkinteger(L, i); + } + check_index_range(k); + j = get_tex_dimen_register(k); + lua_pushnumber(L, j); + return 1; +} + + +int setskip(lua_State * L) +{ + int i; + halfword *j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + j = check_isnode(L, i); /* the value */ + + if (lua_type(L, i - 1) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i - 1, &k); + cur_cs = string_lookup(s, k); + k = zget_equiv(cur_cs) - get_scaled_base(); + } else { + k = (int) luaL_checkinteger(L, i - 1); + } + check_index_range(k); /* the index */ + if (set_tex_skip_register(k, *j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int getskip(lua_State * L) +{ + int i; + halfword j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + if (lua_type(L, i) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i, &k); + cur_cs = string_lookup(s, k); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs) - get_scaled_base(); + } else { + k = (int) luaL_checkinteger(L, i); + } + check_index_range(k); + j = get_tex_skip_register(k); + lua_nodelib_push_fast(L, j); + return 1; +} + + + +int setcount(lua_State * L) +{ + int i, j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + j = (int) luaL_checkinteger(L, i); + if (lua_type(L, i - 1) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i - 1, &k); + cur_cs = string_lookup(s, k); + k = zget_equiv(cur_cs) - get_count_base(); + } else { + k = (int) luaL_checkinteger(L, i - 1); + } + check_index_range(k); + if (set_tex_count_register(k, j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int getcount(lua_State * L) +{ + int i, j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + if (lua_type(L, i) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i, &k); + cur_cs = string_lookup(s, k); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs) - get_count_base(); + } else { + k = (int) luaL_checkinteger(L, i); + } + check_index_range(k); + j = get_tex_count_register(k); + lua_pushnumber(L, j); + return 1; +} + + +int setattribute(lua_State * L) +{ + int i, j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + j = (int) luaL_checkinteger(L, i); + if (lua_type(L, i - 1) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i - 1, &k); + cur_cs = string_lookup(s, k); + k = zget_equiv(cur_cs) - get_attribute_base(); + } else { + k = (int) luaL_checkinteger(L, i - 1); + } + check_index_range(k); + if (set_tex_attribute_register(k, j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int getattribute(lua_State * L) +{ + int i, j; + size_t k; + int cur_cs; + char *s; + i = lua_gettop(L); + if (lua_type(L, i) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i, &k); + cur_cs = string_lookup(s, k); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs) - get_attribute_base(); + } else { + k = (int) luaL_checkinteger(L, i); + } + check_index_range(k); + j = get_tex_attribute_register(k); + lua_pushnumber(L, j); + return 1; +} + +int settoks(lua_State * L) +{ + int i, j; + size_t k, len; + int cur_cs; + char *s, *st; + i = lua_gettop(L); + if (!lua_isstring(L, i)) { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } + st = (char *) lua_tolstring(L, i, &len); + + if (lua_type(L, i - 1) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i - 1, &k); + cur_cs = string_lookup(s, k); + k = zget_equiv(cur_cs) - get_toks_base(); + } else { + k = (int) luaL_checkinteger(L, i - 1); + } + check_index_range(k); + j = maketexlstring(st, len); + + if (zset_tex_toks_register(k, j)) { + flush_str(j); + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +int gettoks(lua_State * L) +{ + int i; + size_t k; + strnumber t; + int cur_cs; + char *s; + i = lua_gettop(L); + if (lua_type(L, i) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i, &k); + cur_cs = string_lookup(s, k); + if (is_undefined_cs(cur_cs)) { + lua_pushnil(L); + return 1; + } + k = zget_equiv(cur_cs) - get_toks_base(); } else { - lua_rawset(L,(i-2)); - } - } else { - lua_rawset(L,(i-2)); - } - return 0; -} - -char * -get_something_internal (int cur_cmd, int cur_code) { - int texstr; - char *str; - int save_cur_val,save_cur_val_level; - save_cur_val = cur_val; - save_cur_val_level = cur_val_level; - zscan_something_simple(cur_cmd,cur_code); - texstr = the_scanned_result(); - cur_val = save_cur_val; - cur_val_level = save_cur_val_level; - str = makecstring(texstr); - flush_str(texstr); - return str; -} - -char * -get_convert (int cur_code) { - int texstr; - char *str = NULL; - texstr = the_convert_string(cur_code); - if (texstr) { + k = (int) luaL_checkinteger(L, i); + } + + check_index_range(k); + t = get_tex_toks_register(k); + lua_pushstring(L, makecstring(t)); + flush_str(t); + return 1; +} + +static int get_box_id(lua_State * L, int i) +{ + char *s; + integer cur_cs, cur_cmd; + size_t k = 0; + int j = -1; + if (lua_type(L, i) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i, &k); + cur_cs = string_lookup(s, k); + cur_cmd = zget_eq_type(cur_cs); + if (cur_cmd == char_given_cmd || + cur_cmd == math_given_cmd || cur_cmd == omath_given_cmd) { + j = zget_equiv(cur_cs); + } + } else { + j = (int) lua_tonumber(L, (i)); + } + return j; +} + +int getbox(lua_State * L) +{ + int k, t; + k = get_box_id(L, -1); + check_index_range(k); + t = get_tex_box_register(k); + nodelist_to_lua(L, t); + return 1; +} + +int setbox(lua_State * L) +{ + int i, j, k; + k = get_box_id(L, -2); + check_index_range(k); + i = get_tex_box_register(k); + if (lua_isboolean(L, -1)) { + j = lua_toboolean(L, -1); + if (j == 0) + j = null; + else + return 0; + } else { + j = nodelist_from_lua(L); + } + if (set_tex_box_register(k, j)) { + lua_pushstring(L, "incorrect value"); + lua_error(L); + } + return 0; +} + +static int getboxdim(lua_State * L, int whichdim) +{ + int i, j; + i = lua_gettop(L); + j = get_box_id(L, i); + lua_settop(L, (i - 2)); /* table at -1 */ + if (j < 0 || j > 65535) { + lua_pushstring(L, "incorrect index"); + lua_error(L); + } + switch (whichdim) { + case width_offset: + lua_pushnumber(L, get_tex_box_width(j)); + break; + case height_offset: + lua_pushnumber(L, get_tex_box_height(j)); + break; + case depth_offset: + lua_pushnumber(L, get_tex_box_depth(j)); + } + return 1; +} + +int getboxwd(lua_State * L) +{ + return getboxdim(L, width_offset); +} + +int getboxht(lua_State * L) +{ + return getboxdim(L, height_offset); +} + +int getboxdp(lua_State * L) +{ + return getboxdim(L, depth_offset); +} + +static int setboxdim(lua_State * L, int whichdim) +{ + int i, j, k, err; + i = lua_gettop(L); + if (!lua_isnumber(L, i)) { + j = dimen_to_number(L, (char *) lua_tostring(L, i)); + } else { + j = (int) lua_tonumber(L, i); + } + k = get_box_id(L, (i - 1)); + lua_settop(L, (i - 3)); /* table at -2 */ + if (k < 0 || k > 65535) { + lua_pushstring(L, "incorrect index"); + lua_error(L); + } + err = 0; + switch (whichdim) { + case width_offset: + err = set_tex_box_width(k, j); + break; + case height_offset: + err = set_tex_box_height(k, j); + break; + case depth_offset: + err = set_tex_box_depth(k, j); + } + if (err) { + lua_pushstring(L, "not a box"); + lua_error(L); + } + return 0; +} + +int setboxwd(lua_State * L) +{ + return setboxdim(L, width_offset); +} + +int setboxht(lua_State * L) +{ + return setboxdim(L, height_offset); +} + +int setboxdp(lua_State * L) +{ + return setboxdim(L, depth_offset); +} + +int settex(lua_State * L) +{ + char *st; + int i, j, texstr; + size_t k; + int cur_cs, cur_cmd; + j = 0; + i = lua_gettop(L); + if (lua_isstring(L, (i - 1))) { + st = (char *) lua_tolstring(L, (i - 1), &k); + texstr = maketexlstring(st, k); + if (is_primitive(texstr)) { + cur_cs = string_lookup(st, k); + flush_str(texstr); + cur_cmd = zget_eq_type(cur_cs); + if (is_int_assign(cur_cmd)) { + if (lua_isnumber(L, i)) { + assign_internal_value(0, zget_equiv(cur_cs), + lua_tonumber(L, i)); + } else { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } + } else if (is_dim_assign(cur_cmd)) { + if (!lua_isnumber(L, i)) + if (lua_isstring(L, i)) { + j = dimen_to_number(L, (char *) lua_tostring(L, i)); + } else { + lua_pushstring(L, "unsupported value type"); + lua_error(L); + } else + j = (int) lua_tonumber(L, i); + assign_internal_value(0, zget_equiv(cur_cs), j); + } else { + lua_pushstring(L, "unsupported tex internal assignment"); + lua_error(L); + } + } else { + lua_rawset(L, (i - 2)); + } + } else { + lua_rawset(L, (i - 2)); + } + return 0; +} + +char *get_something_internal(int cur_cmd, int cur_code) +{ + int texstr; + char *str; + int save_cur_val, save_cur_val_level; + save_cur_val = cur_val; + save_cur_val_level = cur_val_level; + zscan_something_simple(cur_cmd, cur_code); + texstr = the_scanned_result(); + cur_val = save_cur_val; + cur_val_level = save_cur_val_level; str = makecstring(texstr); flush_str(texstr); - } - return str; -} - - -int -gettex (lua_State *L) { - char *st; - int i,texstr; - size_t k; - char *str; - int cur_cs, cur_cmd, cur_code; - i = lua_gettop(L); - if (lua_isstring(L,i)) { - st = (char *)lua_tolstring(L,i, &k); - texstr = maketexlstring(st,k); - cur_cs = zprim_lookup(texstr); - flush_str(texstr); - if (cur_cs) { - cur_cmd = zget_prim_eq_type(cur_cs); - cur_code = zget_prim_equiv(cur_cs); - if (is_convert(cur_cmd)) - str = get_convert(cur_code); - else - str = get_something_internal(cur_cmd,cur_code); - if (str) - lua_pushstring(L,str); - else - lua_pushnil(L); - return 1; + return str; +} + +int do_convert(lua_State * L, int cur_code) +{ + int texstr; + integer i = -1; + char *str = NULL; + switch (cur_code) { + case convert_pdf_creation_date_code: /* ? */ + case convert_pdf_insert_ht_code: /* arg */ + case convert_pdf_ximage_bbox_code: /* arg 2 ints */ + case convert_lua_code: /* arg complex */ + case convert_lua_escape_string_code: /* arg token list */ + case convert_pdf_colorstack_init_code: /* arg complex */ + case convert_left_margin_kern_code: /* arg box */ + case convert_right_margin_kern_code: /* arg box */ + break; + case convert_string_code: /* arg token */ + case convert_meaning_code: /* arg token */ + break; + + /* the next fall through, and come from 'official' indices! */ + case convert_font_name_code: /* arg fontid */ + case convert_font_identifier_code: /* arg fontid */ + case convert_pdf_font_name_code: /* arg fontid */ + case convert_pdf_font_objnum_code: /* arg fontid */ + case convert_pdf_font_size_code: /* arg fontid */ + case convert_uniform_deviate_code: /* arg int */ + case convert_number_code: /* arg int */ + case convert_roman_numeral_code: /* arg int */ + case convert_pdf_page_ref_code: /* arg int */ + case convert_pdf_xform_name_code: /* arg int */ + if (lua_gettop(L) < 1) { + /* error */ + } + i = lua_tonumber(L, 1); /* these fall through! */ + default: + texstr = the_convert_string(cur_code, i); + if (texstr) { + str = makecstring(texstr); + flush_str(texstr); + } + } + if (str) + lua_pushstring(L, str); + else + lua_pushnil(L); + return 1; +} + + +int do_scan_internal(lua_State * L, int cur_cmd, int cur_code) +{ + int texstr; + char *str = NULL; + int save_cur_val, save_cur_val_level; + save_cur_val = cur_val; + save_cur_val_level = cur_val_level; + zscan_something_simple(cur_cmd, cur_code); + + if (cur_val_level == int_val_level || + cur_val_level == dimen_val_level || cur_val_level == attr_val_level) { + lua_pushnumber(L, cur_val); + } else if (cur_val_level == glue_val_level) { + lua_nodelib_push_fast(L, cur_val); + } else { /* dir_val_level, mu_val_level, tok_val_level */ + texstr = the_scanned_result(); + str = makecstring(texstr); + if (str) + lua_pushstring(L, str); + else + lua_pushnil(L); + flush_str(texstr); + } + cur_val = save_cur_val; + cur_val_level = save_cur_val_level; + return 1; +} + +int do_lastitem(lua_State * L, int cur_code) +{ + int retval = 1; + switch (cur_code) { + /* the next two do not actually exist */ + case last_item_lastattr_code: + case last_item_attrexpr_code: + lua_pushnil(L); + break; + /* the expressions do something complicated with arguments, yuck */ + case last_item_numexpr_code: + case last_item_dimexpr_code: + case last_item_glueexpr_code: + case last_item_muexpr_code: + lua_pushnil(L); + break; + /* these read a glue or muglue, todo */ + case last_item_mu_to_glue_code: + case last_item_glue_to_mu_code: + case last_item_glue_stretch_order_code: + case last_item_glue_shrink_order_code: + case last_item_glue_stretch_code: + case last_item_glue_shrink_code: + lua_pushnil(L); + break; + /* these read a fontid and a char, todo */ + case last_item_font_char_wd_code: + case last_item_font_char_ht_code: + case last_item_font_char_dp_code: + case last_item_font_char_ic_code: + lua_pushnil(L); + break; + /* these read an integer, todo */ + case last_item_par_shape_length_code: + case last_item_par_shape_indent_code: + case last_item_par_shape_dimen_code: + lua_pushnil(L); + break; + case last_item_lastpenalty_code: + case last_item_lastkern_code: + case last_item_lastskip_code: + case last_item_last_node_type_code: + case last_item_input_line_no_code: + case last_item_badness_code: + case last_item_pdftex_version_code: + case last_item_pdf_last_obj_code: + case last_item_pdf_last_xform_code: + case last_item_pdf_last_ximage_code: + case last_item_pdf_last_ximage_pages_code: + case last_item_pdf_last_annot_code: + case last_item_pdf_last_x_pos_code: + case last_item_pdf_last_y_pos_code: + case last_item_pdf_retval_code: + case last_item_pdf_last_ximage_colordepth_code: + case last_item_random_seed_code: + case last_item_pdf_last_link_code: + case last_item_luatex_version_code: + case last_item_Aleph_version_code: + case last_item_Omega_version_code: + case last_item_Aleph_minor_version_code: + case last_item_Omega_minor_version_code: + case last_item_eTeX_minor_version_code: + case last_item_eTeX_version_code: + case last_item_current_group_level_code: + case last_item_current_group_type_code: + case last_item_current_if_level_code: + case last_item_current_if_type_code: + case last_item_current_if_branch_code: + retval = do_scan_internal(L, last_item_cmd, cur_code); + break; + default: + lua_pushnil(L); + break; + } + return retval; +} + + +static int getfontname(lua_State * L) +{ + return do_convert(L, convert_font_name_code); +} + +static int getfontidentifier(lua_State * L) +{ + return do_convert(L, convert_font_identifier_code); +} + +static int getpdffontname(lua_State * L) +{ + return do_convert(L, convert_pdf_font_name_code); +} + +static int getpdffontobjnum(lua_State * L) +{ + return do_convert(L, convert_pdf_font_objnum_code); +} + +static int getpdffontsize(lua_State * L) +{ + return do_convert(L, convert_pdf_font_size_code); +} + +static int getuniformdeviate(lua_State * L) +{ + return do_convert(L, convert_uniform_deviate_code); +} + +static int getnumber(lua_State * L) +{ + return do_convert(L, convert_number_code); +} + +static int getromannumeral(lua_State * L) +{ + return do_convert(L, convert_roman_numeral_code); +} + +static int getpdfpageref(lua_State * L) +{ + return do_convert(L, convert_pdf_page_ref_code); +} + +static int getpdfxformname(lua_State * L) +{ + return do_convert(L, convert_pdf_xform_name_code); +} + + +int get_parshape(lua_State * L) +{ + int n; + halfword par_shape_ptr = get_par_shape_ptr(); + if (par_shape_ptr != 0) { + int m = 1; + n = vinfo(par_shape_ptr + 1); + lua_createtable(L, n, 0); + while (m <= n) { + lua_createtable(L, 2, 0); + lua_pushnumber(L, vlink((par_shape_ptr) + (2 * (m - 1)) + 2)); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, vlink((par_shape_ptr) + (2 * (m - 1)) + 3)); + lua_rawseti(L, -2, 2); + lua_rawseti(L, -2, m); + m++; + } } else { - lua_rawget(L,(i-1)); - return 1; - } - } else { - lua_rawget(L,(i-1)); + lua_pushnil(L); + } return 1; - } - return 0; /* not reached */ -} - - -int -getlist (lua_State *L) { - char *str; - if (lua_isstring(L,2)) { - str = (char *)lua_tostring(L,2); - if (strcmp(str,"page_ins_head")==0) { - lua_pushnumber(L,page_ins_head); lua_nodelib_push(L); - } else if (strcmp(str,"contrib_head")==0) { - lua_pushnumber(L,contrib_head); lua_nodelib_push(L); - } else if (strcmp(str,"page_head")==0) { - lua_pushnumber(L,page_head); lua_nodelib_push(L); - } else if (strcmp(str,"temp_head")==0) { - lua_pushnumber(L,temp_head); lua_nodelib_push(L); - } else if (strcmp(str,"hold_head")==0) { - lua_pushnumber(L,hold_head); lua_nodelib_push(L); - } else if (strcmp(str,"adjust_head")==0) { - lua_pushnumber(L,adjust_head); lua_nodelib_push(L); - } else if (strcmp(str,"pre_adjust_head")==0) { - lua_pushnumber(L,pre_adjust_head); lua_nodelib_push(L); - } else if (strcmp(str,"align_head")==0) { - lua_pushnumber(L,align_head); lua_nodelib_push(L); +} + + +int gettex(lua_State * L) +{ + int cur_cs = -1; + int retval = 1; /* default is to return nil */ + + if (lua_isstring(L, 2)) { /* 1 == 'tex' */ + int texstr; + size_t k; + char *st = (char *) lua_tolstring(L, 2, &k); + texstr = maketexlstring(st, k); + cur_cs = prim_lookup(texstr); /* not found == relax == 0 */ + flush_str(texstr); + } + if (cur_cs > 0) { + int cur_cmd, cur_code; + cur_cmd = get_prim_eq_type(cur_cs); + cur_code = get_prim_equiv(cur_cs); + switch (cur_cmd) { + case last_item_cmd: + retval = do_lastitem(L, cur_code); + break; + case convert_cmd: + retval = do_convert(L, cur_code); + break; + case assign_toks_cmd: + case assign_int_cmd: + case assign_attr_cmd: + case assign_dir_cmd: + case assign_dimen_cmd: + case assign_glue_cmd: + case assign_mu_glue_cmd: + case set_aux_cmd: + case set_prev_graf_cmd: + case set_page_int_cmd: + case set_page_dimen_cmd: + case char_given_cmd: + case math_given_cmd: + case omath_given_cmd: + retval = do_scan_internal(L, cur_cmd, cur_code); + break; + case set_tex_shape_cmd: + retval = get_parshape(L); + break; + default: + lua_pushnil(L); + break; + } } else { - lua_pushnil(L); + lua_rawget(L, 1); /* fetch other index from table */ } - } else { - lua_pushnil(L); - } - return 1; + return retval; } -int -setlist (lua_State *L) { - assert(L); - return 0; + +int getlist(lua_State * L) +{ + char *str; + if (lua_isstring(L, 2)) { + str = (char *) lua_tostring(L, 2); + if (strcmp(str, "page_ins_head") == 0) { + if (vlink(page_ins_head) == page_ins_head) + lua_pushnumber(L, null); + else + lua_pushnumber(L, vlink(page_ins_head)); + lua_nodelib_push(L); + } else if (strcmp(str, "contrib_head") == 0) { + lua_pushnumber(L, vlink(contrib_head)); + lua_nodelib_push(L); + } else if (strcmp(str, "page_head") == 0) { + lua_pushnumber(L, vlink(page_head)); + lua_nodelib_push(L); + } else if (strcmp(str, "temp_head") == 0) { + lua_pushnumber(L, vlink(temp_head)); + lua_nodelib_push(L); + } else if (strcmp(str, "hold_head") == 0) { + lua_pushnumber(L, vlink(hold_head)); + lua_nodelib_push(L); + } else if (strcmp(str, "adjust_head") == 0) { + lua_pushnumber(L, vlink(adjust_head)); + lua_nodelib_push(L); + } else if (strcmp(str, "best_page_break") == 0) { + lua_pushnumber(L, best_page_break); + lua_nodelib_push(L); + } else if (strcmp(str, "least_page_cost") == 0) { + lua_pushnumber(L, least_page_cost); + } else if (strcmp(str, "best_size") == 0) { + lua_pushnumber(L, best_size); + } else if (strcmp(str, "pre_adjust_head") == 0) { + lua_pushnumber(L, vlink(pre_adjust_head)); + lua_nodelib_push(L); + } else if (strcmp(str, "align_head") == 0) { + lua_pushnumber(L, vlink(align_head)); + lua_nodelib_push(L); + } else { + lua_pushnil(L); + } + } else { + lua_pushnil(L); + } + return 1; +} + +int setlist(lua_State * L) +{ + halfword *n_ptr; + char *str; + halfword n = 0; + if (lua_isstring(L, 2)) { + str = (char *) lua_tostring(L, 2); + if (strcmp(str, "best_size") == 0) { + best_size = lua_tointeger(L, 3); + } else if (strcmp(str, "least_page_cost") == 0) { + least_page_cost = lua_tointeger(L, 3); + } else { + if (!lua_isnil(L, 3)) { + n_ptr = check_isnode(L, 3); + n = *n_ptr; + } + if (strcmp(str, "page_ins_head") == 0) { + if (n == 0) { + vlink(page_ins_head) = page_ins_head; + } else { + halfword m; + vlink(page_ins_head) = n; + m = tail_of_list(n); + vlink(m) = page_ins_head; + } + } else if (strcmp(str, "contrib_head") == 0) { + vlink(contrib_head) = n; + if (n == 0) { + if (nest_ptr == 0) + cur_list.tail_field = contrib_head; /* vertical mode */ + else + nest[0].tail_field = contrib_head; /* other modes */ + } + } else if (strcmp(str, "best_page_break") == 0) { + best_page_break = n; + } else if (strcmp(str, "page_head") == 0) { + vlink(page_head) = n; + page_tail = (n == 0 ? page_head : tail_of_list(n)); + } else if (strcmp(str, "temp_head") == 0) { + vlink(temp_head) = n; + } else if (strcmp(str, "hold_head") == 0) { + vlink(hold_head) = n; + } else if (strcmp(str, "adjust_head") == 0) { + vlink(adjust_head) = n; + adjust_tail = (n == 0 ? adjust_head : tail_of_list(n)); + } else if (strcmp(str, "pre_adjust_head") == 0) { + vlink(pre_adjust_head) = n; + pre_adjust_tail = (n == 0 ? pre_adjust_head : tail_of_list(n)); + } else if (strcmp(str, "align_head") == 0) { + vlink(align_head) = n; + } + } + } + return 0; } #define infinity 2147483647 -static int -do_integer_error(double m) { - char *help[] = {"I can only go up to 2147483647='17777777777=""7FFFFFFF,", - "so I'm using that number instead of yours.", - NULL } ; - tex_error("Number too big",help); - return (m>0.0 ? infinity : -infinity); +static int do_integer_error(double m) +{ + char *help[] = { "I can only go up to 2147483647='17777777777=" "7FFFFFFF,", + "so I'm using that number instead of yours.", + NULL + }; + tex_error("Number too big", help); + return (m > 0.0 ? infinity : -infinity); } -static int -tex_roundnumber (lua_State *L) { - double m = lua_tonumber(L, 1)+0.5; - if (abs(m)>(double)infinity) - lua_pushnumber(L,do_integer_error(m)); - else - lua_pushnumber(L,floor(m)); - return 1; +static int tex_roundnumber(lua_State * L) +{ + double m = lua_tonumber(L, 1) + 0.5; + if (abs(m) > (double) infinity) + lua_pushnumber(L, do_integer_error(m)); + else + lua_pushnumber(L, floor(m)); + return 1; } -static int -tex_scaletable (lua_State *L) { - double delta = luaL_checknumber(L, 2); - if (lua_istable(L,1)) { - lua_newtable(L); /* the new table is at index 3 */ - lua_pushnil(L); - while (lua_next(L,1)!= 0 ) { /* numeric value */ - lua_pushvalue(L,-2); - lua_insert(L,-2); - if (lua_isnumber(L,-1)) { - double m = lua_tonumber(L,-1)*delta + 0.5; - lua_pop(L,1); - if (abs(m)>(double)infinity) - lua_pushnumber(L,do_integer_error(m)); - else - lua_pushnumber(L,floor(m)); - } - lua_rawset(L,3); - } - } else if (lua_isnumber(L,1)) { - double m = lua_tonumber(L,1)*delta + 0.5; - if (abs(m)>(double)infinity) - lua_pushnumber(L,do_integer_error(m)); - else - lua_pushnumber(L,floor(m)); - } else { - lua_pushnil(L); - } - return 1; -} - -static const struct luaL_reg texlib [] = { - {"write", luacwrite}, - {"print", luacprint}, - {"sprint", luacsprint}, - {"setdimen", setdimen}, - {"getdimen", getdimen}, - {"setattribute", setattribute}, - {"getattribute", getattribute}, - {"setcount", setcount}, - {"getcount", getcount}, - {"settoks", settoks}, - {"gettoks", gettoks}, - {"setbox", setbox}, - {"getbox", getbox}, - {"setlist", setlist}, - {"getlist", getlist}, - {"setboxwd", setboxwd}, - {"getboxwd", getboxwd}, - {"setboxht", setboxht}, - {"getboxht", getboxht}, - {"setboxdp", setboxdp}, - {"getboxdp", getboxdp}, - {"round", tex_roundnumber}, - {"scale", tex_scaletable}, - {NULL, NULL} /* sentinel */ -}; +static int tex_scaletable(lua_State * L) +{ + double delta = luaL_checknumber(L, 2); + if (lua_istable(L, 1)) { + lua_newtable(L); /* the new table is at index 3 */ + lua_pushnil(L); + while (lua_next(L, 1) != 0) { /* numeric value */ + lua_pushvalue(L, -2); + lua_insert(L, -2); + if (lua_isnumber(L, -1)) { + double m = lua_tonumber(L, -1) * delta + 0.5; + lua_pop(L, 1); + if (abs(m) > (double) infinity) + lua_pushnumber(L, do_integer_error(m)); + else + lua_pushnumber(L, floor(m)); + } + lua_rawset(L, 3); + } + } else if (lua_isnumber(L, 1)) { + double m = lua_tonumber(L, 1) * delta + 0.5; + if (abs(m) > (double) infinity) + lua_pushnumber(L, do_integer_error(m)); + else + lua_pushnumber(L, floor(m)); + } else { + lua_pushnil(L); + } + return 1; +} + +#define hash_text(A) hash[(A)].rh + +static int tex_definefont(lua_State * L) +{ + char *csname; + int f, u; + str_number t; + size_t l; + int i = 1; + int a = 0; + if (!no_new_control_sequence) { + char *help[] = + { "You can't create a new font inside a \\csname\\endcsname pair", + NULL + }; + tex_error("Definition active", help); + } + if ((lua_gettop(L) == 3) && lua_isboolean(L, 1)) { + a = lua_toboolean(L, 1); + i = 2; + } + csname = (char *) luaL_checklstring(L, i, &l); + f = luaL_checkinteger(L, (i + 1)); + t = maketexlstring(csname, l); + no_new_control_sequence = 0; + u = string_lookup(csname, l); + no_new_control_sequence = 1; + if (a) + geq_define(u, set_font_cmd, f); + else + eq_define(u, set_font_cmd, f); + zeqtb[get_font_id_base() + f] = zeqtb[u]; + hash_text(get_font_id_base() + f) = t; + return 0; +} + +static int tex_hashpairs(lua_State * L) +{ + int cmd, chr; + str_number s = 0; + int cs = 1; + int eqtb_size = get_eqtb_size(); + lua_newtable(L); + while (cs < eqtb_size) { + s = hash_text(cs); + if (s > 0) { + lua_pushstring(L, makecstring(s)); + cmd = zget_eq_type(cs); + chr = zget_equiv(cs); + make_token_table(L, cmd, chr, cs); + lua_rawset(L, -3); + } + cs++; + } + return 1; +} + +static int tex_primitives(lua_State * L) +{ + int cmd, chr; + str_number s = 0; + int cs = 0; + lua_newtable(L); + while (cs < prim_size) { + s = get_prim_text(cs); + if (s > 0) { + lua_pushstring(L, makecstring(s)); + cmd = get_prim_eq_type(cs); + chr = get_prim_equiv(cs); + make_token_table(L, cmd, chr, 0); + lua_rawset(L, -3); + } + cs++; + } + return 1; +} -int luaopen_tex (lua_State *L) -{ - luaL_register(L, "tex", texlib); - make_table(L,"attribute","getattribute","setattribute"); - make_table(L,"dimen","getdimen","setdimen"); - make_table(L,"count","getcount","setcount"); - make_table(L,"toks","gettoks","settoks"); - make_table(L,"box","getbox","setbox"); - make_table(L,"lists","getlist","setlist"); - make_table(L,"wd","getboxwd","setboxwd"); - make_table(L,"ht","getboxht","setboxht"); - make_table(L,"dp","getboxdp","setboxdp"); - /* make the meta entries */ - /* fetch it back */ - luaL_newmetatable(L,"tex_meta"); - lua_pushstring(L, "__index"); - lua_pushcfunction(L, gettex); - lua_settable(L, -3); - lua_pushstring(L, "__newindex"); - lua_pushcfunction(L, settex); - lua_settable(L, -3); - lua_setmetatable(L,-2); /* meta to itself */ - /* initialize the I/O stack: */ - spindles = xmalloc(sizeof(spindle)); - spindle_index = 0; - spindles[0].head = NULL; - spindles[0].tail = NULL; - spindle_size = 1; - return 1; +static int tex_extraprimitives(lua_State * L) +{ + int n, i; + int mask = 0; + str_number s = 0; + int cs = 0; + n = lua_gettop(L); + if (n == 0) { + mask = etex_command + aleph_command + omega_command + + pdftex_command + luatex_command; + } else { + for (i = 1; i <= n; i++) { + if (lua_isstring(L, i)) { + char *s = (char *) lua_tostring(L, i); + if (strcmp(s, "etex") == 0) { + mask |= etex_command; + } else if (strcmp(s, "tex") == 0) { + mask |= tex_command; + } else if (strcmp(s, "core") == 0) { + mask |= core_command; + } else if (strcmp(s, "pdftex") == 0) { + mask |= pdftex_command; + } else if (strcmp(s, "aleph") == 0) { + mask |= aleph_command; + } else if (strcmp(s, "omega") == 0) { + mask |= omega_command; + } else if (strcmp(s, "luatex") == 0) { + mask |= luatex_command; + } + } + } + } + lua_newtable(L); + i = 1; + while (cs < prim_size) { + s = get_prim_text(cs); + if (s > 0) { + if (get_prim_origin(cs) & mask) { + lua_pushstring(L, makecstring(s)); + lua_rawseti(L, -2, i++); + } + } + cs++; + } + return 1; +} + +static int tex_enableprimitives(lua_State * L) +{ + int n = lua_gettop(L); + if (n != 2) { + lua_pushstring(L, "wrong number of arguments"); + lua_error(L); + } else { + size_t l; + int i; + char *pre = (char *) luaL_checklstring(L, 1, &l); + if (lua_istable(L,2)) { + int nncs = no_new_control_sequence; + no_new_control_sequence = true; + i = 1; + while (1) { + lua_rawgeti(L,2,i); + if (lua_isstring(L,3)) { + char *prim = (char *) lua_tostring(L,3); + str_number s = maketexstring(prim); + halfword prim_val = prim_lookup(s); + if (prim_val != undefined_primitive) { + char *newprim; + size_t newl; + halfword cur_cmd = get_prim_eq_type(prim_val); + halfword cur_chr = get_prim_equiv(prim_val); + if (strncmp(pre,prim,l)!=0) { /* not a prefix */ + newl = strlen(prim)+l; + newprim = (char *) xmalloc (newl+1); + strcpy(newprim,pre); + strcat(newprim+l,prim); + } else { + newl = strlen(prim); + newprim = (char *) xmalloc (newl+1); + strcpy(newprim,prim); + } + if (string_lookup(newprim, newl) == static_undefined_control_sequence ) { + primitive_def(newprim, newl, cur_cmd, cur_chr); + } + free (newprim); + } + flush_str(s); + } else { + lua_pop(L,1); + break; + } + lua_pop(L,1); + i++; + } + lua_pop(L,1); /* the table */ + no_new_control_sequence = nncs; + } else { + lua_pushstring(L, "Expected an array of names as second argument"); + lua_error(L); + } + } + return 0; } + + +static const struct luaL_reg texlib[] = { + {"write", luacwrite}, + {"print", luacprint}, + {"sprint", luacsprint}, + {"setdimen", setdimen}, + {"getdimen", getdimen}, + {"setskip", setskip}, + {"getskip", getskip}, + {"setattribute", setattribute}, + {"getattribute", getattribute}, + {"setcount", setcount}, + {"getcount", getcount}, + {"settoks", settoks}, + {"gettoks", gettoks}, + {"setbox", setbox}, + {"getbox", getbox}, + {"setlist", setlist}, + {"getlist", getlist}, + {"setboxwd", setboxwd}, + {"getboxwd", getboxwd}, + {"setboxht", setboxht}, + {"getboxht", getboxht}, + {"setboxdp", setboxdp}, + {"getboxdp", getboxdp}, + {"round", tex_roundnumber}, + {"scale", tex_scaletable}, + {"fontname", getfontname}, + {"fontidentifier", getfontidentifier}, + {"pdffontname", getpdffontname}, + {"pdffontobjnum", getpdffontobjnum}, + {"pdffontsize", getpdffontsize}, + {"uniformdeviate", getuniformdeviate}, + {"number", getnumber}, + {"romannumeral", getromannumeral}, + {"pdfpageref", getpdfpageref}, + {"pdfxformname", getpdfxformname}, + {"definefont", tex_definefont}, + {"hashtokens", tex_hashpairs}, + {"primitives", tex_primitives}, + {"extraprimitives", tex_extraprimitives}, + {"enableprimitives", tex_enableprimitives}, + {NULL, NULL} /* sentinel */ +}; + +int luaopen_tex(lua_State * L) +{ + luaL_register(L, "tex", texlib); + make_table(L, "attribute", "getattribute", "setattribute"); + make_table(L, "skip", "getskip", "setskip"); + make_table(L, "dimen", "getdimen", "setdimen"); + make_table(L, "count", "getcount", "setcount"); + make_table(L, "toks", "gettoks", "settoks"); + make_table(L, "box", "getbox", "setbox"); + make_table(L, "lists", "getlist", "setlist"); + make_table(L, "wd", "getboxwd", "setboxwd"); + make_table(L, "ht", "getboxht", "setboxht"); + make_table(L, "dp", "getboxdp", "setboxdp"); + /* make the meta entries */ + /* fetch it back */ + luaL_newmetatable(L, "tex_meta"); + lua_pushstring(L, "__index"); + lua_pushcfunction(L, gettex); + lua_settable(L, -3); + lua_pushstring(L, "__newindex"); + lua_pushcfunction(L, settex); + lua_settable(L, -3); + lua_setmetatable(L, -2); /* meta to itself */ + /* initialize the I/O stack: */ + spindles = xmalloc(sizeof(spindle)); + spindle_index = 0; + spindles[0].head = NULL; + spindles[0].tail = NULL; + spindle_size = 1; + /* a somewhat odd place for this assert, maybe */ + assert(command_names[data_cmd].command_offset == data_cmd); + assert(param_int_pars == (get_count_base() - get_int_base())); + return 1; +} diff --git a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c index 582779623cf..b81c61f4023 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c @@ -1,263 +1,284 @@ -/* $Id: ltokenlib.c 1013 2008-02-14 00:09:02Z oneiros $ */ +/* ltokenlib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include +#include "tokens.h" +static const char _svn_version[] = + "$Id: ltokenlib.c 2015 2009-03-13 19:06:34Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/ltokenlib.c $"; -extern int get_command_id (char *); +extern int get_command_id(char *); static int max_command = 0; -static int hash_base = 0; -static int active_base = 0; static int null_cs = 0; #define protected_token 0x1C00001 #define is_valid_token(L,i) (lua_istable(L,i) && lua_objlen(L,i)==3) -#define get_token_cmd(L,i) lua_rawgeti(L,i,1) -#define get_token_chr(L,i) lua_rawgeti(L,i,2) -#define get_token_cs(L,i) lua_rawgeti(L,i,3) - -static int -test_expandable (lua_State *L) { - integer cmd = -1; - if (is_valid_token(L,-1)) { - get_token_cmd(L,-1); - if (lua_isnumber(L,-1)) { - cmd = lua_tointeger(L,-1); - } else if (lua_isstring(L,-1)) { - cmd = get_command_id((char *)lua_tostring(L,-1)); - } - if (cmd>max_command) { - lua_pushboolean(L,1); +#define get_token_cmd(L,i) lua_rawgeti(L,i,1) +#define get_token_chr(L,i) lua_rawgeti(L,i,2) +#define get_token_cs(L,i) lua_rawgeti(L,i,3) +#define is_active_string(s) (strlen((char *)s)>3 && *s==0xEF && *(s+1)==0xBF && *(s+2)==0xBF) + + +static int test_expandable(lua_State * L) +{ + integer cmd = -1; + if (is_valid_token(L, -1)) { + get_token_cmd(L, -1); + if (lua_isnumber(L, -1)) { + cmd = lua_tointeger(L, -1); + } else if (lua_isstring(L, -1)) { + cmd = get_command_id((char *) lua_tostring(L, -1)); + } + if (cmd > max_command) { + lua_pushboolean(L, 1); + } else { + lua_pushboolean(L, 0); + } } else { - lua_pushboolean(L,0); + lua_pushnil(L); } - } else { - lua_pushnil(L); - } - return 1; + return 1; } -static int -test_protected (lua_State *L) { - integer chr = -1; - if (is_valid_token(L,-1)) { - get_token_chr(L,-1); - if (lua_isnumber(L,-1)) { - chr = lua_tointeger(L,-1); - } else if (lua_isstring(L,-1)) { - chr = get_command_id((char *)lua_tostring(L,-1)); - } - if (fixmem[fixmem[chr].hhrh].hhlh==protected_token) { - lua_pushboolean(L,1); +static int test_protected(lua_State * L) +{ + integer chr = -1; + if (is_valid_token(L, -1)) { + get_token_chr(L, -1); + if (lua_isnumber(L, -1)) { + chr = lua_tointeger(L, -1); + } else if (lua_isstring(L, -1)) { + chr = get_command_id((char *) lua_tostring(L, -1)); + } + if (fixmem[fixmem[chr].hhrh].hhlh == protected_token) { + lua_pushboolean(L, 1); + } else { + lua_pushboolean(L, 0); + } } else { - lua_pushboolean(L,0); + lua_pushnil(L); } - } else { - lua_pushnil(L); - } - return 1; + return 1; } -static int -test_activechar (lua_State *L) { - integer cmd = -1; - if (is_valid_token(L,-1)) { - get_token_chr(L,-1); - if (lua_isnumber(L,-1)) { - cmd = lua_tointeger(L,-1); - } - if (cmd>0 && cmd==protected_token) { - lua_pushboolean(L,1); - } else { - lua_pushboolean(L,0); +static int test_activechar(lua_State * L) +{ + if (is_valid_token(L, -1)) { + str_number n; + integer cs = 0; + get_token_cs(L, -1); + if (lua_isnumber(L, -1)) { + cs = lua_tointeger(L, -1); + } + lua_pop(L, 1); + if (cs != 0 && (n = zget_cs_text(cs)) && n > 0) { + unsigned char *s = (unsigned char *) makecstring(n); + if (is_active_string(s)) { + free(s); + lua_pushboolean(L, 1); + return 1; + } + free(s); + } } - } else { - lua_pushnil(L); - } - return 1; + lua_pushboolean(L, 0); + return 1; } -static int -run_get_command_name (lua_State *L) { - int cs; - if (is_valid_token(L,-1)) { - get_token_cmd(L,-1); - if (lua_isnumber(L,-1)) { - cs = lua_tointeger(L,-1); - lua_pushstring(L,command_names[cs].cmd_name); +static int run_get_command_name(lua_State * L) +{ + int cs; + if (is_valid_token(L, -1)) { + get_token_cmd(L, -1); + if (lua_isnumber(L, -1)) { + cs = lua_tointeger(L, -1); + lua_pushstring(L, command_names[cs].cmd_name); + } else { + lua_pushstring(L, ""); + } } else { - lua_pushstring(L,""); + lua_pushnil(L); } - } else { - lua_pushnil(L); - } - return 1; + return 1; } -static int -run_get_csname_name (lua_State *L) { - int cs,cmd,n; - char *s; - - if (is_valid_token(L,-1)) { - get_token_cmd(L,-1); - if (lua_isnumber(L,-1)) { - cmd = lua_tointeger(L,-1); - } - lua_pop(L,1); - cs = 0; - get_token_cs(L,-1); - if (lua_isnumber(L,-1)) { - cs = lua_tointeger(L,-1); - } - lua_pop(L,1); - - if (cs != 0 && (n = zget_cs_text(cs)) && n>=0) { - s = makecstring(n); - lua_pushstring(L,s); - } else { - lua_pushstring(L,""); - } - } else { - lua_pushnil(L); - } - return 1; + +static int run_get_csname_name(lua_State * L) +{ + int cs, cmd, n; + + if (is_valid_token(L, -1)) { + get_token_cmd(L, -1); + if (lua_isnumber(L, -1)) { + cmd = lua_tointeger(L, -1); + } + lua_pop(L, 1); + cs = 0; + get_token_cs(L, -1); + if (lua_isnumber(L, -1)) { + cs = lua_tointeger(L, -1); + } + lua_pop(L, 1); + + if (cs != 0 && (n = zget_cs_text(cs)) && n >= 0) { + unsigned char *s = (unsigned char *) makecstring(n); + if (is_active_string(s)) + lua_pushstring(L, (char *) (s + 3)); + else + lua_pushstring(L, (char *) s); + } else { + lua_pushstring(L, ""); + } + } else { + lua_pushnil(L); + } + return 1; } -static int -run_get_command_id (lua_State *L) { - int cs = -1; - if (lua_isstring(L,-1)) { - cs = get_command_id((char *)lua_tostring(L,-1)); - } - lua_pushnumber(L,cs); - return 1; +static int run_get_command_id(lua_State * L) +{ + int cs = -1; + if (lua_isstring(L, -1)) { + cs = get_command_id((char *) lua_tostring(L, -1)); + } + lua_pushnumber(L, cs); + return 1; } -static int -run_get_csname_id (lua_State *L) { - int texstr; - char *s; - size_t k,cs = 0; - if (lua_isstring(L,-1)) { - s = (char *)lua_tolstring(L,-1, &k); - texstr = maketexlstring(s,k); - cs = string_lookup(texstr); - flush_str(texstr); - } - lua_pushnumber(L,cs); - return 1; +static int run_get_csname_id(lua_State * L) +{ + char *s; + size_t k, cs = 0; + if (lua_isstring(L, -1)) { + s = (char *) lua_tolstring(L, -1, &k); + cs = string_lookup(s, k); + } + lua_pushnumber(L, cs); + return 1; } -void -make_token_table (lua_State *L, int cmd, int chr, int cs) { - lua_createtable(L,3,0); - lua_pushnumber(L,cmd); - lua_rawseti(L,-2,1); - lua_pushnumber(L,chr); - lua_rawseti(L,-2,2); - lua_pushnumber(L,cs); - lua_rawseti(L,-2,3); +void make_token_table(lua_State * L, int cmd, int chr, int cs) +{ + lua_createtable(L, 3, 0); + lua_pushnumber(L, cmd); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, chr); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, cs); + lua_rawseti(L, -2, 3); } -static int -run_get_next (lua_State *L) { - int save_nncs; - save_nncs = no_new_control_sequence; - no_new_control_sequence = 0; - get_next(); - no_new_control_sequence = save_nncs; - make_token_table(L,cur_cmd,cur_chr,cur_cs); - return 1; +static int run_get_next(lua_State * L) +{ + int save_nncs; + save_nncs = no_new_control_sequence; + no_new_control_sequence = 0; + get_next(); + no_new_control_sequence = save_nncs; + make_token_table(L, cur_cmd, cur_chr, cur_cs); + return 1; } -static int -run_expand (lua_State *L) { - expand(); - return 0; +static int run_expand(lua_State * L) +{ + expand(); + return 0; } -static int -run_lookup (lua_State *L) { - char *s; - size_t l; - str_number t; - integer cs,cmd,chr; - int save_nncs; - if (lua_isstring(L,-1)) { - s = (char *)lua_tolstring(L,-1,&l); - if (l>0) { - save_nncs = no_new_control_sequence; - no_new_control_sequence = true; - cs = id_lookup((last+1),l); /* cleans up the lookup buffer */ - t = maketexlstring(s,l); - cs = string_lookup(t); - flush_str(t); - cmd = zget_eq_type(cs); - chr = zget_equiv(cs); - make_token_table(L,cmd,chr,cs); - no_new_control_sequence = save_nncs; - return 1; +static int run_lookup(lua_State * L) +{ + char *s; + size_t l; + integer cs, cmd, chr; + int save_nncs; + if (lua_isstring(L, -1)) { + s = (char *) lua_tolstring(L, -1, &l); + if (l > 0) { + save_nncs = no_new_control_sequence; + no_new_control_sequence = true; + cs = id_lookup((last + 1), l); /* cleans up the lookup buffer */ + cs = string_lookup(s, l); + cmd = zget_eq_type(cs); + chr = zget_equiv(cs); + make_token_table(L, cmd, chr, cs); + no_new_control_sequence = save_nncs; + return 1; + } } - } - lua_newtable(L); - return 1; + lua_newtable(L); + return 1; } -static int -run_build (lua_State *L) { - integer cmd,chr,cs; - if (lua_isnumber(L,1)) { - cs =0; - chr = lua_tointeger(L,1); - cmd = luaL_optinteger(L,2,zget_char_cat_code(chr)); - if (cmd==0 || cmd == 9 || cmd == 14 || cmd == 15) { - fprintf(stdout, "\n\nluatex error: not a good token.\nCatcode %i can not be returned, so I replaced it by 12 (other)",(int)cmd); - error(); - cmd=12; - } - if (cmd == 13) { - cs=chr+active_base; - cmd=zget_eq_type(cs); - chr=zget_equiv(cs); +static int run_build(lua_State * L) +{ + integer cmd, chr, cs; + if (lua_isnumber(L, 1)) { + cs = 0; + chr = lua_tointeger(L, 1); + cmd = luaL_optinteger(L, 2, get_char_cat_code(chr)); + if (cmd == 0 || cmd == 9 || cmd == 14 || cmd == 15) { + fprintf(stdout, + "\n\nluatex error: not a good token.\nCatcode %i can not be returned, so I replaced it by 12 (other)", + (int) cmd); + error(); + cmd = 12; + } + if (cmd == 13) { + cs = active_to_cs(chr, false); + cmd = zget_eq_type(cs); + chr = zget_equiv(cs); + } + make_token_table(L, cmd, chr, cs); + return 1; + } else { + return run_lookup(L); } - make_token_table(L,cmd,chr,cs); - return 1; - } else { - return run_lookup(L); - } } -static const struct luaL_reg tokenlib [] = { - {"get_next", run_get_next}, - {"expand", run_expand}, - {"lookup", run_lookup}, - {"create", run_build}, - {"is_expandable",test_expandable}, - {"is_activechar",test_activechar}, - {"is_protected", test_protected}, - {"csname_id", run_get_csname_id}, - {"csname_name", run_get_csname_name}, - {"command_name", run_get_command_name}, - {"command_id", run_get_command_id}, - {NULL, NULL} /* sentinel */ +static const struct luaL_reg tokenlib[] = { + {"get_next", run_get_next}, + {"expand", run_expand}, + {"lookup", run_lookup}, + {"create", run_build}, + {"is_expandable", test_expandable}, + {"is_activechar", test_activechar}, + {"is_protected", test_protected}, + {"csname_id", run_get_csname_id}, + {"csname_name", run_get_csname_name}, + {"command_name", run_get_command_name}, + {"command_id", run_get_command_id}, + {NULL, NULL} /* sentinel */ }; -int luaopen_token (lua_State *L) +int luaopen_token(lua_State * L) { - luaL_register(L, "token", tokenlib); - max_command = get_max_command(); - hash_base = get_hash_base(); - active_base = get_active_base(); - null_cs = get_nullcs(); - return 1; + luaL_register(L, "token", tokenlib); + max_command = get_max_command(); + null_cs = get_nullcs(); + return 1; } - diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.c b/Build/source/texk/web2c/luatexdir/lua/luainit.c index 3aa5dfc35b5..f89607530ac 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luainit.c +++ b/Build/source/texk/web2c/luatexdir/lua/luainit.c @@ -1,3 +1,22 @@ +/* luainit.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + #include #include "luatex-api.h" @@ -5,21 +24,37 @@ #include -#ifndef program_invocation_name -/* char *program_invocation_name = NULL; */ -#endif - -extern void parse_src_specials_option (char *n) ; +static const char _svn_version[] = + "$Id: luainit.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luainit.c $"; + +/* TH: TODO + * + * This file is getting a bit messy, but it is not simple to fix unilaterally. + * + * Better to wait until Karl has some time (after texlive 2008) so we can + * synchronize with kpathsea. One problem, for instance, is that I would + * like to resolve the full executable path. kpse_set_program_name() does + * that, indirectly (by setting SELFAUTOLOC in the environment), but it + * does much more, making it hard to use for our purpose. + * + * In fact, it sets three C variables: + * program_invocation_name program_invocation_short_name kpse->program_name + * and four environment variables: + * SELFAUTOLOC SELFAUTODIR SELFAUTOPARENT progname + * + */ + +extern string normalize_quotes(const_string name, const_string mesg); const_string LUATEX_IHELP[] = { "Usage: luatex --lua=FILE [OPTION]... [TEXNAME[.tex]] [COMMANDS]", " or: luatex --lua=FILE [OPTION]... \\FIRST-LINE", " or: luatex --lua=FILE [OPTION]... &FMT ARGS", - " Run luaTeX on TEXNAME, usually creating TEXNAME.pdf.", + " Run LuaTeX on TEXNAME, usually creating TEXNAME.pdf.", " Any remaining COMMANDS are processed as luatex input, after TEXNAME is read.", "", " Alternatively, if the first non-option argument begins with a backslash,", - " interpret all non-option arguments as a line of luatex input.", + " luatex interprets all non-option arguments as an input line.", "", " Alternatively, if the first non-option argument begins with a &, the", " next word is taken as the FMT to read, overriding all else. Any", @@ -28,7 +63,8 @@ const_string LUATEX_IHELP[] = { " If no arguments or options are specified, prompt for input.", "", " --lua=FILE the lua initialization file", - " --safer disable some easily exploitable lua commands", + " --nosocket disable the luasocket (network) library", + " --safer disable easily exploitable lua commands", " --fmt=FORMAT load the format file FORMAT", " --ini be initex, for dumping formats", " --help display this help and exit", @@ -41,23 +77,50 @@ const_string LUATEX_IHELP[] = { NULL }; +char *ex_selfdir(char *argv0) +{ +#if defined(WIN32) + char short_path[PATH_MAX], path[PATH_MAX], *fp; + + /* SearchPath() always gives back an absolute directory */ + if (SearchPath(NULL, argv0, ".exe", PATH_MAX, short_path, &fp) == 0) + FATAL1("Can't determine where the executable %s is.\n", argv0); + if (!win32_get_long_filename(short_path, path, sizeof(path))) { + FATAL1("This path points to an invalid file : %s\n", short_path); + } + /* slashify the dirname */ + for (fp = path; fp && *fp; fp++) + if (IS_DIR_SEP(*fp)) + *fp = DIR_SEP; + /* sdir will be the directory of the executable, ie: c:/TeX/bin */ + return xdirname(path); +#else + return kpse_selfdir(argv0); +#endif +} + static void prepare_cmdline(lua_State * L, char **argv, int argc, int zero_offset) { int i; + char *s; luaL_checkstack(L, argc + 3, "too many arguments to script"); lua_createtable(L, 0, 0); for (i = 0; i < argc; i++) { - lua_pushstring(L, argv[i]); - lua_rawseti(L, -2, (i-zero_offset)); + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, (i - zero_offset)); } lua_setglobal(L, "arg"); + lua_getglobal(L, "os"); + s = ex_selfdir(argv[0]); + lua_pushstring(L, s); + xfree(s); + lua_setfield(L, -2, "selfdir"); return; } extern string dump_name; extern const_string c_job_name; -extern boolean srcspecialsoption; extern char *last_source_name; extern int last_lineno; @@ -66,7 +129,7 @@ string input_name = NULL; static string user_progname = NULL; extern char *ptexbanner; -extern int program_name_set; /* in lkpselib.c */ +extern int program_name_set; /* in lkpselib.c */ /* for topenin() */ extern char **argv; @@ -77,6 +140,7 @@ int lua_only = 0; int lua_offset = 0; int safer_option = 0; +int nosocket_option = 0; /* Reading the options. */ @@ -87,444 +151,448 @@ int safer_option = 0; /* SunOS cc can't initialize automatic structs, so make this static. */ static struct option long_options[] - = { { "fmt", 1, 0, 0}, - { "lua", 1, 0, 0}, - { "luaonly", 0, 0, 0}, - { "safer", 0, &safer_option, 1}, - { "help", 0, 0, 0 }, - { "ini", 0, &ini_version, 1 }, - { "interaction", 1, 0, 0 }, - { "halt-on-error", 0, &haltonerrorp, 1 }, - { "kpathsea-debug", 1, 0, 0 }, - { "progname", 1, 0, 0 }, - { "version", 0, 0, 0 }, - { "recorder", 0, &recorder_enabled, 1 }, - { "etex", 0, 0, 0 }, - { "output-comment", 1, 0, 0 }, - { "output-directory", 1, 0, 0 }, - { "draftmode", 0, 0, 0 }, - { "output-format", 1, 0, 0 }, - { "shell-escape", 0, &shellenabledp, 1 }, - { "no-shell-escape", 0, &shellenabledp, -1 }, - { "enable-write18", 0, &shellenabledp, 1 }, - { "disable-write18", 0, &shellenabledp, -1 }, - { "shell-restricted", 0, 0, 0 }, - { "debug-format", 0, &debug_format_file, 1 }, - { "src-specials", 2, 0, 0 }, - { "file-line-error-style", 0, &filelineerrorstylep, 1 }, - { "no-file-line-error-style", 0, &filelineerrorstylep, -1 }, += { {"fmt", 1, 0, 0}, +{"lua", 1, 0, 0}, +{"luaonly", 0, 0, 0}, +{"safer", 0, &safer_option, 1}, +{"nosocket", 0, &nosocket_option, 1}, +{"help", 0, 0, 0}, +{"ini", 0, &ini_version, 1}, +{"interaction", 1, 0, 0}, +{"halt-on-error", 0, &haltonerrorp, 1}, +{"kpathsea-debug", 1, 0, 0}, +{"progname", 1, 0, 0}, +{"version", 0, 0, 0}, +{"credits", 0, 0, 0}, +{"recorder", 0, &recorder_enabled, 1}, +{"etex", 0, 0, 0}, +{"output-comment", 1, 0, 0}, +{"output-directory", 1, 0, 0}, +{"draftmode", 0, 0, 0}, +{"output-format", 1, 0, 0}, +{"shell-escape", 0, &shellenabledp, 1}, +{"no-shell-escape", 0, &shellenabledp, -1}, +{"debug-format", 0, &debug_format_file, 1}, +{"file-line-error-style", 0, &filelineerrorstylep, 1}, +{"no-file-line-error-style", 0, &filelineerrorstylep, -1}, /* Shorter option names for the above. */ - { "file-line-error", 0, &filelineerrorstylep, 1 }, - { "no-file-line-error", 0, &filelineerrorstylep, -1 }, - { "jobname", 1, 0, 0 }, - { "parse-first-line", 0, &parsefirstlinep, 1 }, - { "no-parse-first-line", 0, &parsefirstlinep, -1 }, - { "translate-file", 1, 0, 0 }, - { "default-translate-file", 1, 0, 0 }, - { "8bit", 0, 0, 0 }, - { "mktex", 1, 0, 0 }, - { "no-mktex", 1, 0, 0 }, +{"file-line-error", 0, &filelineerrorstylep, 1}, +{"no-file-line-error", 0, &filelineerrorstylep, -1}, +{"jobname", 1, 0, 0}, +{"parse-first-line", 0, &parsefirstlinep, 1}, +{"no-parse-first-line", 0, &parsefirstlinep, -1}, +{"translate-file", 1, 0, 0}, +{"default-translate-file", 1, 0, 0}, +{"8bit", 0, 0, 0}, +{"mktex", 1, 0, 0}, +{"no-mktex", 1, 0, 0}, +/* Synchronization: just like "interaction" above */ +{"synctex", 1, 0, 0}, {0, 0, 0, 0} }; -static void -parse_options(int argc, char **argv) +static void parse_options(int argc, char **argv) { - int g; /* `getopt' return code. */ - int option_index; - char *firstfile = NULL; - opterr = 0; /* dont whine */ - for (;;) { - g = getopt_long_only(argc, argv, "+", long_options, &option_index); - - if (g == -1) /* End of arguments, exit the loop. */ - break; - if (g == '?') /* Unknown option. */ - continue; - - assert(g == 0); /* We have no short option names. */ - - if (ARGUMENT_IS("luaonly")) { - lua_only = 1; - lua_offset = optind; - luainit = 1 ; - } else if (ARGUMENT_IS("lua")) { - startup_filename = optarg; - lua_offset = (optind-1); - luainit = 1 ; - - } else if (ARGUMENT_IS ("kpathsea-debug")) { - kpathsea_debug |= atoi (optarg); - - } else if (ARGUMENT_IS("progname")) { - user_progname = optarg; - - } else if (ARGUMENT_IS ("jobname")) { - c_job_name = optarg; - - } else if (ARGUMENT_IS("fmt")) { - dump_name = optarg; - - } else if (ARGUMENT_IS ("output-directory")) { - output_directory = optarg; - - } else if (ARGUMENT_IS ("output-comment")) { - unsigned len = strlen (optarg); - if (len < 256) { - output_comment = optarg; - } else { - WARNING2 ("Comment truncated to 255 characters from %d. (%s)", - len, optarg); - output_comment = (string)xmalloc (256); - strncpy (output_comment, optarg, 255); - output_comment[255] = 0; - } - - } else if (ARGUMENT_IS ("src-specials")) { - last_source_name = xstrdup(""); - /* Option `--src" without any value means `auto' mode. */ - if (optarg == NULL) { - insertsrcspecialeverypar = true; - insertsrcspecialauto = true; - srcspecialsoption = true; - srcspecialsp = true; - } else { - parse_src_specials_option(optarg); - } - - } else if (ARGUMENT_IS ("output-format")) { - pdf_output_option = 1; - if (strcmp(optarg, "dvi") == 0) { - pdf_output_value = 0; - } else if (strcmp(optarg, "pdf") == 0) { - pdf_output_value = 2; - } else { - WARNING1 ("Ignoring unknown value `%s' for --output-format", optarg); - pdf_output_option = 0; - } - - } else if (ARGUMENT_IS ("draftmode")) { - pdf_draftmode_option = 1; - pdf_draftmode_value = 1; - - } else if (ARGUMENT_IS ("mktex")) { - kpse_maketex_option (optarg, true); - - } else if (ARGUMENT_IS ("no-mktex")) { - kpse_maketex_option (optarg, false); - - } else if (ARGUMENT_IS ("interaction")) { - /* These numbers match @d's in *.ch */ - if (STREQ (optarg, "batchmode")) { - interactionoption = 0; - } else if (STREQ (optarg, "nonstopmode")) { - interactionoption = 1; - } else if (STREQ (optarg, "scrollmode")) { - interactionoption = 2; - } else if (STREQ (optarg, "errorstopmode")) { - interactionoption = 3; - } else { - WARNING1 ("Ignoring unknown argument `%s' to --interaction", optarg); - } - - } else if (ARGUMENT_IS("help")) { - usagehelp(LUATEX_IHELP, BUG_ADDRESS); - - } else if (ARGUMENT_IS("version")) { - char *versions; - initversionstring(&versions); - print_version_banner(); - - puts( -"\n\nLuaTeX merges and builds upon (parts of) the code from these projects:\n\n" -"tex by Donald Knuth\n" -"etex by Peter Breitenlohner, Phil Taylor and friends\n" -"omega by John Plaice and Yannis Haralambous\n" -"aleph by Giuseppe Bilotta\n" -"pdftex by Han The Thanh and friends\n" -"kpathsea by Karl Berry, Olaf Weber and others\n" -"lua by Roberto Ierusalimschy, Waldemar Celes,\n" -" Luiz Henrique de Figueiredo\n" -"metapost by John Hobby, Taco Hoekwater and friends.\n" -"xpdf by Derek Noonberg (partial)\n" -"fontforge by George Williams (partial)\n\n" -"Some extensions to lua and additional lua libraries are used, as well as\n" -"libraries for graphic inclusion. More details can be found in the source.\n" -"Code development was sponsored by a grant from Colorado State University\n" -"via the 'oriental tex' project, the TeX User Groups, and donations.\n\n" -"The LuaTeX team is Hans Hagen, Hartmut Henkel, Taco Hoekwater.\n\n" -"There is NO warranty. Redistribution of this software is covered by\n" -"the terms of the GNU General Public License, version 2. For more\n" -"information about these matters, see the file named COPYING and\n" -"the LuaTeX source.\n\n" -"Copyright 2008 Taco Hoekwater, the LuaTeX Team.\n"); - - puts(versions); - uexit(0); - } - } - /* attempt to find dump_name */ - if (argv[optind] && argv[optind][0] == '&') { - dump_name = strdup(argv[optind] + 1); - } else if (argv[optind] && argv[optind][0] != '\\') { - if (argv[optind][0] == '*') { - input_name = strdup(argv[optind] + 1); - } else { - firstfile = strdup(argv[optind]); - if (lua_only) { - startup_filename = firstfile; - } else { - if ((strstr(firstfile,".lua") == firstfile+strlen(firstfile)-4) || - (strstr(firstfile,".luc") == firstfile+strlen(firstfile)-4) || - (strstr(firstfile,".LUA") == firstfile+strlen(firstfile)-4) || - (strstr(firstfile,".LUC") == firstfile+strlen(firstfile)-4) || - (strstr(argv[0],"luatexlua") != NULL) || - (strstr(argv[0],"texlua") != NULL)) { - startup_filename = firstfile; - lua_only = 1; - lua_offset = optind; - luainit = 1 ; - } else { - input_name = firstfile; - } - } - } - } else { - if ((strstr(argv[0],"luatexlua") != NULL)|| - (strstr(argv[0],"texlua") != NULL)) { - lua_only = 1; - luainit = 1 ; - } - } + int g; /* `getopt' return code. */ + int option_index; + char *firstfile = NULL; + opterr = 0; /* dont whine */ + for (;;) { + g = getopt_long_only(argc, argv, "+", long_options, &option_index); + + if (g == -1) /* End of arguments, exit the loop. */ + break; + if (g == '?') /* Unknown option. */ + continue; + + assert(g == 0); /* We have no short option names. */ + + if (ARGUMENT_IS("luaonly")) { + lua_only = 1; + lua_offset = optind; + luainit = 1; + } else if (ARGUMENT_IS("lua")) { + startup_filename = optarg; + lua_offset = (optind - 1); + luainit = 1; + + } else if (ARGUMENT_IS("kpathsea-debug")) { + kpathsea_debug |= atoi(optarg); + + } else if (ARGUMENT_IS("progname")) { + user_progname = optarg; + + } else if (ARGUMENT_IS("jobname")) { + c_job_name = optarg; + + } else if (ARGUMENT_IS("fmt")) { + dump_name = optarg; + + } else if (ARGUMENT_IS("output-directory")) { + output_directory = optarg; + + } else if (ARGUMENT_IS("output-comment")) { + unsigned len = strlen(optarg); + if (len < 256) { + output_comment = optarg; + } else { + WARNING2("Comment truncated to 255 characters from %d. (%s)", + len, optarg); + output_comment = (string) xmalloc(256); + strncpy(output_comment, optarg, 255); + output_comment[255] = 0; + } + + } else if (ARGUMENT_IS("output-format")) { + pdf_output_option = 1; + if (strcmp(optarg, "dvi") == 0) { + pdf_output_value = 0; + } else if (strcmp(optarg, "pdf") == 0) { + pdf_output_value = 2; + } else { + WARNING1("Ignoring unknown value `%s' for --output-format", + optarg); + pdf_output_option = 0; + } + + } else if (ARGUMENT_IS("draftmode")) { + pdf_draftmode_option = 1; + pdf_draftmode_value = 1; + + } else if (ARGUMENT_IS("mktex")) { + kpse_maketex_option(optarg, true); + + } else if (ARGUMENT_IS("no-mktex")) { + kpse_maketex_option(optarg, false); + + } else if (ARGUMENT_IS("interaction")) { + /* These numbers match @d's in *.ch */ + if (STREQ(optarg, "batchmode")) { + interactionoption = 0; + } else if (STREQ(optarg, "nonstopmode")) { + interactionoption = 1; + } else if (STREQ(optarg, "scrollmode")) { + interactionoption = 2; + } else if (STREQ(optarg, "errorstopmode")) { + interactionoption = 3; + } else { + WARNING1("Ignoring unknown argument `%s' to --interaction", + optarg); + } + + } else if (ARGUMENT_IS("synctex")) { + /* Synchronize TeXnology: catching the command line option as a long */ + synctexoption = (int) strtol(optarg, NULL, 0); + + } else if (ARGUMENT_IS("help")) { + usagehelp(LUATEX_IHELP, BUG_ADDRESS); + + } else if (ARGUMENT_IS("version")) { + print_version_banner(); + /* *INDENT-OFF* */ + puts("\n\nExecute 'luatex --credits' for credits and version details.\n\n" + "There is NO warranty. Redistribution of this software is covered by\n" + "the terms of the GNU General Public License, version 2. For more\n" + "information about these matters, see the file named COPYING and\n" + "the LuaTeX source.\n\n" + "Copyright 2009 Taco Hoekwater, the LuaTeX Team.\n"); + /* *INDENT-ON* */ + uexit(0); + } else if (ARGUMENT_IS("credits")) { + char *versions; + initversionstring(&versions); + print_version_banner(); + /* *INDENT-OFF* */ + puts("\n\nThe LuaTeX team is Hans Hagen, Hartmut Henkel, Taco Hoekwater.\n" + "LuaTeX merges and builds upon (parts of) the code from these projects:\n\n" + "tex by Donald Knuth\n" + "etex by Peter Breitenlohner, Phil Taylor and friends\n" + "omega by John Plaice and Yannis Haralambous\n" + "aleph by Giuseppe Bilotta\n" + "pdftex by Han The Thanh and friends\n" + "kpathsea by Karl Berry, Olaf Weber and others\n" + "lua by Roberto Ierusalimschy, Waldemar Celes,\n" + " Luiz Henrique de Figueiredo\n" + "metapost by John Hobby, Taco Hoekwater and friends.\n" + "xpdf by Derek Noonberg (partial)\n" + "fontforge by George Williams (partial)\n\n" + "Some extensions to lua and additional lua libraries are used, as well as\n" + "libraries for graphic inclusion. More details can be found in the source.\n" + "Code development was sponsored by a grant from Colorado State University\n" + "via the 'oriental tex' project, the TeX User Groups, and donations.\n"); + /* *INDENT-ON* */ + puts(versions); + uexit(0); + } + } + /* attempt to find dump_name */ + if (argv[optind] && argv[optind][0] == '&') { + dump_name = strdup(argv[optind] + 1); + } else if (argv[optind] && argv[optind][0] != '\\') { + if (argv[optind][0] == '*') { + input_name = strdup(argv[optind] + 1); + } else { + firstfile = strdup(argv[optind]); + if (lua_only) { + startup_filename = firstfile; + } else { + if ((strstr(firstfile, ".lua") == + firstfile + strlen(firstfile) - 4) + || (strstr(firstfile, ".luc") == + firstfile + strlen(firstfile) - 4) + || (strstr(firstfile, ".LUA") == + firstfile + strlen(firstfile) - 4) + || (strstr(firstfile, ".LUC") == + firstfile + strlen(firstfile) - 4) + || (strstr(argv[0], "luatexlua") != NULL) + || (strstr(argv[0], "texlua") != NULL)) { + startup_filename = firstfile; + lua_only = 1; + lua_offset = optind; + luainit = 1; + } else { + input_name = firstfile; + } + } + } + } else { + if ((strstr(argv[0], "luatexlua") != NULL) || + (strstr(argv[0], "texlua") != NULL)) { + lua_only = 1; + luainit = 1; + } + } + if (safer_option) /* --safer implies --nosocket */ + nosocket_option = 1; + + /* Finalize the input filename. */ + if (input_name != NULL) { + argv[optind] = normalize_quotes(input_name, "argument"); + } } /* test for readability */ #define is_readable(a) (stat(a,&finfo)==0) && S_ISREG(finfo.st_mode) && \ (f=fopen(a,"r")) != NULL && !fclose(f) -char * -find_filename(char *name, char *envkey) +char *find_filename(char *name, char *envkey) { struct stat finfo; char *dirname = NULL; char *filename = NULL; FILE *f; if (is_readable(name)) { - return name; + return name; } else { - dirname = getenv(envkey); - if ((dirname != NULL) && strlen(dirname)) { - dirname = strdup(getenv(envkey)); - if (*(dirname + strlen(dirname) - 1) == '/') { - *(dirname + strlen(dirname) - 1) = 0; - } - filename = xmalloc(strlen(dirname) + strlen(name) + 2); - filename = concat3(dirname, "/", name); - if (is_readable(filename)) { - xfree(dirname); - return filename; - } - xfree(filename); - } + dirname = getenv(envkey); + if ((dirname != NULL) && strlen(dirname)) { + dirname = strdup(getenv(envkey)); + if (*(dirname + strlen(dirname) - 1) == '/') { + *(dirname + strlen(dirname) - 1) = 0; + } + filename = xmalloc(strlen(dirname) + strlen(name) + 2); + filename = concat3(dirname, "/", name); + if (is_readable(filename)) { + xfree(dirname); + return filename; + } + xfree(filename); + } } return NULL; } -void -init_kpse (void) { - - if (!user_progname) { - user_progname = dump_name; - } else if (!dump_name) { - dump_name = user_progname; - } - if (!user_progname) { - if (ini_version) { - user_progname = input_name; - } else { - if(!startup_filename) { - if (!dump_name) { - dump_name = strdup(argv[0]); - user_progname = dump_name; - } - } - } - } - if (!user_progname) { - fprintf(stdout, - "kpathsea mode needs a --progname or --fmt switch\n"); - exit(1); - } - - kpse_set_program_enabled (kpse_fmt_format, MAKE_TEX_FMT_BY_DEFAULT, - kpse_src_compile); - - kpse_set_program_name(argv[0], user_progname); - program_name_set=1; - - /* Needs program_name set. */ - init_shell_escape (); -} - -void -fix_dumpname (void) { - int dist; - if (dump_name) { - /* adjust array for Pascal and provide extension, if needed */ - dist = strlen(dump_name) - strlen(DUMP_EXT); - if (strstr(dump_name, DUMP_EXT) == dump_name + dist) - DUMP_VAR = concat(" ", dump_name); - else - DUMP_VAR = concat3(" ", dump_name, DUMP_EXT); - DUMP_LENGTH_VAR = strlen(DUMP_VAR + 1); - } else { - /* For dump_name to be NULL is a bug. */ - if (!ini_version) - abort(); - } +char *cleaned_invocation_name(char *arg) +{ + char *ret, *dot; + const char *start = xbasename(arg); + ret = xstrdup(start); + dot = index(ret, '.'); + if (dot != NULL) { + *dot = 0; /* chop */ + } + return ret; } -void -lua_initialize(int ac, char **av) +void init_kpse(void) { - char *given_file = NULL; - int kpse_init; - int tex_table_id; - int pdf_table_id; - int token_table_id; - int node_table_id; - /* Save to pass along to topenin. */ - argc = ac; - argv = av; - - ptexbanner = BANNER; - program_invocation_name = argv[0]; - - /* be 'luac' */ - if (argc>1 && - (STREQ(argv[0],"texluac") || - STREQ(argv[1],"--luaconly") || - STREQ(argv[1],"--luac"))) { - exit(luac_main(ac,av)); - } - - /* Must be initialized before options are parsed. */ - interactionoption = 4; - dump_name = NULL; - /* parse commandline */ - parse_options(ac, av); - - /* make sure that the locale is 'sane' (for lua) */ - putenv("LC_CTYPE=C"); - putenv("LC_COLLATE=C"); - putenv("LC_NUMERIC=C"); - - /* this is sometimes needed */ - putenv("engine=luatex"); - - luainterpreter(0); - - prepare_cmdline(Luas[0], argv, argc, lua_offset); /* collect arguments */ - - if (startup_filename != NULL) { - given_file = xstrdup(startup_filename); - startup_filename = find_filename(startup_filename, "LUATEXDIR"); - } - /* now run the file */ - if (startup_filename != NULL) { - /* hide the 'tex' and 'pdf' table */ - tex_table_id = hide_lua_table(Luas[0], "tex"); - token_table_id = hide_lua_table(Luas[0], "token"); - node_table_id = hide_lua_table(Luas[0], "node"); - pdf_table_id = hide_lua_table(Luas[0], "pdf"); - - if (luaL_loadfile(Luas[0], startup_filename)) { - fprintf(stdout, "%s\n",lua_tostring(Luas[0], -1)); - exit(1); + if (!user_progname) { + user_progname = dump_name; + } else if (!dump_name) { + dump_name = user_progname; } - if (lua_pcall(Luas[0], 0, 0, 0)) { - fprintf(stdout, "%s\n",lua_tostring(Luas[0], -1)); - exit(1); + if (!user_progname) { + if (ini_version) { + user_progname = input_name; + } else { + if (!startup_filename) { + if (!dump_name) { + dump_name = cleaned_invocation_name(argv[0]); + user_progname = dump_name; + } + } + } } - /* no filename? quit now! */ - if (!input_name) { - get_lua_string("texconfig", "jobname", &input_name); + if (!user_progname) { + fprintf(stdout, "kpathsea mode needs a --progname or --fmt switch\n"); + exit(1); } - if (!dump_name) { - get_lua_string("texconfig", "formatname", &dump_name); + + kpse_set_program_enabled(kpse_fmt_format, MAKE_TEX_FMT_BY_DEFAULT, + kpse_src_compile); + + kpse_set_program_name(argv[0], user_progname); + program_name_set = 1; +} + +void fix_dumpname(void) +{ + int dist; + if (dump_name) { + /* adjust array for Pascal and provide extension, if needed */ + dist = strlen(dump_name) - strlen(DUMP_EXT); + if (strstr(dump_name, DUMP_EXT) == dump_name + dist) + DUMP_VAR = concat(" ", dump_name); + else + DUMP_VAR = concat3(" ", dump_name, DUMP_EXT); + DUMP_LENGTH_VAR = strlen(DUMP_VAR + 1); + } else { + /* For dump_name to be NULL is a bug. */ + if (!ini_version) + abort(); } - if ((lua_only) || ((!input_name) && (!dump_name))) { - exit(0); +} + +void lua_initialize(int ac, char **av) +{ + + char *given_file = NULL; + int kpse_init; + int tex_table_id; + int pdf_table_id; + int token_table_id; + int node_table_id; + /* Save to pass along to topenin. */ + argc = ac; + argv = av; + + ptexbanner = BANNER; + + program_invocation_name = cleaned_invocation_name(argv[0]); + + /* be 'luac' */ + if (argc > 1 && + (STREQ(program_invocation_name, "texluac") || + STREQ(argv[1], "--luaconly") || STREQ(argv[1], "--luac"))) { + exit(luac_main(ac, av)); } - /* unhide the 'tex' and 'pdf' table */ - unhide_lua_table(Luas[0], "tex", tex_table_id); - unhide_lua_table(Luas[0], "pdf", pdf_table_id); - unhide_lua_table(Luas[0], "token", token_table_id); - unhide_lua_table(Luas[0], "node", node_table_id); - - /* kpse_init */ - kpse_init = -1; - get_lua_boolean("texconfig", "kpse_init", &kpse_init); - - if (kpse_init != 0) { - init_kpse(); + + /* Must be initialized before options are parsed. */ + interactionoption = 4; + dump_name = NULL; + +#warning SyncTeX: -synctex command line option available + /* 0 means "disable Synchronize TeXnology". + * synctexoption is a *.web variable. + * We initialize it to a weird value to catch the -synctex command line flag + * At runtime, if synctexoption is not INT_MAX, then it contains the command line option provided, + * otherwise no such option was given by the user. */ +#define SYNCTEX_NO_OPTION INT_MAX + synctexoption = SYNCTEX_NO_OPTION; + + /* parse commandline */ + parse_options(ac, av); + + /* make sure that the locale is 'sane' (for lua) */ + putenv("LC_CTYPE=C"); + putenv("LC_COLLATE=C"); + putenv("LC_NUMERIC=C"); + + /* this is sometimes needed */ + putenv("engine=luatex"); + + luainterpreter(); + + prepare_cmdline(Luas, argv, argc, lua_offset); /* collect arguments */ + + if (startup_filename != NULL) { + given_file = xstrdup(startup_filename); + startup_filename = find_filename(startup_filename, "LUATEXDIR"); } - /* prohibit_file_trace (boolean) */ - tracefilenames = 1; - get_lua_boolean("texconfig", "trace_file_names", &tracefilenames); - - /* src_special_xx */ - insertsrcspecialauto = insertsrcspecialeverypar = - insertsrcspecialeveryparend = insertsrcspecialeverycr = - insertsrcspecialeverymath = insertsrcspecialeveryhbox = - insertsrcspecialeveryvbox = insertsrcspecialeverydisplay = - false; - get_lua_boolean("texconfig", "src_special_auto", - &insertsrcspecialauto); - get_lua_boolean("texconfig", "src_special_everypar", - &insertsrcspecialeverypar); - get_lua_boolean("texconfig", "src_special_everyparend", - &insertsrcspecialeveryparend); - get_lua_boolean("texconfig", "src_special_everycr", - &insertsrcspecialeverycr); - get_lua_boolean("texconfig", "src_special_everymath", - &insertsrcspecialeverymath); - get_lua_boolean("texconfig", "src_special_everyhbox", - &insertsrcspecialeveryhbox); - get_lua_boolean("texconfig", "src_special_everyvbox", - &insertsrcspecialeveryvbox); - get_lua_boolean("texconfig", "src_special_everydisplay", - &insertsrcspecialeverydisplay); - - srcspecialsp = insertsrcspecialauto | insertsrcspecialeverypar | - insertsrcspecialeveryparend | insertsrcspecialeverycr | - insertsrcspecialeverymath | insertsrcspecialeveryhbox | - insertsrcspecialeveryvbox | insertsrcspecialeverydisplay; - - /* file_line_error */ - filelineerrorstylep = false; - get_lua_boolean("texconfig", "file_line_error", - &filelineerrorstylep); - - /* halt_on_error */ - haltonerrorp = false; - get_lua_boolean("texconfig", "halt_on_error", &haltonerrorp); - - fix_dumpname(); - } else { - if (luainit) { - if (given_file) { - fprintf(stdout, "%s file %s not found\n", (lua_only ? "Script" : "Configuration"), given_file); - } else { - fprintf(stdout, "No %s file given\n", (lua_only ? "script" : "configuration")); - } - exit(1); + /* now run the file */ + if (startup_filename != NULL) { + /* hide the 'tex' and 'pdf' table */ + tex_table_id = hide_lua_table(Luas, "tex"); + token_table_id = hide_lua_table(Luas, "token"); + node_table_id = hide_lua_table(Luas, "node"); + pdf_table_id = hide_lua_table(Luas, "pdf"); + + if (luaL_loadfile(Luas, startup_filename)) { + fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); + exit(1); + } + if (lua_pcall(Luas, 0, 0, 0)) { + fprintf(stdout, "%s\n", lua_tostring(Luas, -1)); + exit(1); + } + /* no filename? quit now! */ + if (!input_name) { + get_lua_string("texconfig", "jobname", &input_name); + } + if (!dump_name) { + get_lua_string("texconfig", "formatname", &dump_name); + } + if ((lua_only) || ((!input_name) && (!dump_name))) { + if (given_file) + free(given_file); + /* this is not strictly needed but it pleases valgrind */ + lua_close(Luas); + exit(0); + } + /* unhide the 'tex' and 'pdf' table */ + unhide_lua_table(Luas, "tex", tex_table_id); + unhide_lua_table(Luas, "pdf", pdf_table_id); + unhide_lua_table(Luas, "token", token_table_id); + unhide_lua_table(Luas, "node", node_table_id); + + /* kpse_init */ + kpse_init = -1; + get_lua_boolean("texconfig", "kpse_init", &kpse_init); + + if (kpse_init != 0) { + luainit = 0; /* re-enable loading of texmf.cnf values, see luatex.ch */ + init_kpse(); + } + /* prohibit_file_trace (boolean) */ + tracefilenames = 1; + get_lua_boolean("texconfig", "trace_file_names", &tracefilenames); + + /* file_line_error */ + filelineerrorstylep = false; + get_lua_boolean("texconfig", "file_line_error", &filelineerrorstylep); + + /* halt_on_error */ + haltonerrorp = false; + get_lua_boolean("texconfig", "halt_on_error", &haltonerrorp); + + fix_dumpname(); } else { - /* init */ - init_kpse(); - fix_dumpname(); + if (luainit) { + if (given_file) { + fprintf(stdout, "%s file %s not found\n", + (lua_only ? "Script" : "Configuration"), given_file); + free(given_file); + } else { + fprintf(stdout, "No %s file given\n", + (lua_only ? "script" : "configuration")); + } + exit(1); + } else { + /* init */ + init_kpse(); + fix_dumpname(); + } } - } } diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.c b/Build/source/texk/web2c/luatexdir/lua/luanode.c index 17c8e7be8e2..0be6547446f 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luanode.c +++ b/Build/source/texk/web2c/luatexdir/lua/luanode.c @@ -1,181 +1,247 @@ -/* $Id: luanode.c 1013 2008-02-14 00:09:02Z oneiros $ */ +/* luanode.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "nodes.h" -#undef link /* defined by cpascal.h */ +static const char _svn_version[] = + "$Id: luanode.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luanode.c $"; + +#undef link /* defined by cpascal.h */ #define info(a) fixmem[(a)].hhlh #define link(a) fixmem[(a)].hhrh - static char *group_code_names[] = { - "", - "simple", - "hbox", - "adjusted_hbox", - "vbox", - "vtop", - "align", - "no_align", - "output", - "math", - "disc", - "insert", - "vcenter", - "math_choice", - "semi_simple", - "math_shift", - "math_left", - "local_box" , - "split_off", - "split_keep", - "preamble", - "align_set", - "fin_row"}; - -char *pack_type_name[] = { "exactly", "additional"}; + "", + "simple", + "hbox", + "adjusted_hbox", + "vbox", + "vtop", + "align", + "no_align", + "output", + "math", + "disc", + "insert", + "vcenter", + "math_choice", + "semi_simple", + "math_shift", + "math_left", + "local_box", + "split_off", + "split_keep", + "preamble", + "align_set", + "fin_row" +}; +char *pack_type_name[] = { "exactly", "additional" }; -void -lua_node_filter_s (int filterid, char *extrainfo, halfword head_node, halfword *tail_node) { - halfword ret; - int a; - lua_State *L = Luas[0]; - int callback_id = callback_defined(filterid); - if (head_node==null || vlink(head_node)==null || callback_id==0) - return; - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1, callback_id); - if (!lua_isfunction(L,-1)) { - lua_pop(L,2); - return; - } - nodelist_to_lua(L,vlink(head_node)); /* arg 1 */ - lua_pushstring(L,extrainfo); /* arg 2 */ - if (lua_pcall(L,2,1,0) != 0) { /* no arg, 1 result */ - fprintf(stdout,"error: %s\n",lua_tostring(L,-1)); - lua_pop(L,2); - error(); + +void lua_node_filter_s(int filterid, char *extrainfo) +{ + lua_State *L = Luas; + int s_top = lua_gettop(L); + if (!get_callback(L, callback_defined(filterid))) { + lua_settop(L, s_top); + return; + } + lua_pushstring(L, extrainfo); /* arg 1 */ + if (lua_pcall(L, 1, 0, 0) != 0) { + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_settop(L, s_top); + error(); + return; + } + lua_settop(L, s_top); return; - } - if (lua_isboolean(L,-1)) { - if (lua_toboolean(L,-1)!=1) { - flush_node_list(vlink(head_node)); - vlink(head_node) = null; - } - } else { - a = nodelist_from_lua(L); - vlink(head_node)= a; - } - lua_pop(L,2); /* result and callback container table */ - if (fix_node_lists) - fix_node_list(head_node); - ret = vlink(head_node); - if (ret!=null) { - while (vlink(ret)!=null) - ret=vlink(ret); - *tail_node=ret; - } else { - *tail_node=head_node; - } - return ; } void -lua_node_filter (int filterid, int extrainfo, halfword head_node, halfword *tail_node) { - lua_node_filter_s(filterid, group_code_names[extrainfo], head_node, tail_node); - return ; +lua_node_filter(int filterid, int xextrainfo, halfword head_node, + halfword * tail_node) +{ + halfword ret; + int a; + lua_State *L = Luas; + char *extrainfo = group_code_names[xextrainfo]; + int callback_id = callback_defined(filterid); + if (head_node == null || vlink(head_node) == null || callback_id == 0) + return; + if (!get_callback(L, callback_id)) { + lua_pop(L, 2); + return; + } + nodelist_to_lua(L, vlink(head_node)); /* arg 1 */ + lua_pushstring(L, extrainfo); /* arg 2 */ + if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */ + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 2); + error(); + return; + } + if (lua_isboolean(L, -1)) { + if (lua_toboolean(L, -1) != 1) { + flush_node_list(vlink(head_node)); + vlink(head_node) = null; + } + } else { + a = nodelist_from_lua(L); + vlink(head_node) = a; + } + lua_pop(L, 2); /* result and callback container table */ + if (fix_node_lists) + fix_node_list(head_node); + ret = vlink(head_node); + if (ret != null) { + while (vlink(ret) != null) + ret = vlink(ret); + *tail_node = ret; + } else { + *tail_node = head_node; + } + return; +} + + +int +lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head) +{ + int a; + register halfword *p; + int ret = 0; /* failure */ + lua_State *L = Luas; + int callback_id = callback_defined(linebreak_filter_callback); + if (head_node == null || vlink(head_node) == null || callback_id == 0) + return ret; + if (!get_callback(L, callback_id)) { + lua_pop(L, 2); + return ret; + } + nodelist_to_lua(L, vlink(head_node)); /* arg 1 */ + lua_pushboolean(L, is_broken); /* arg 2 */ + if (lua_pcall(L, 2, 1, 0) != 0) { /* no arg, 1 result */ + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 2); + error(); + return ret; + } + + p = lua_touserdata(L, -1); + if (p != NULL) { + a = nodelist_from_lua(L); + vlink(*new_head) = a; + ret = 1; + } + lua_pop(L, 2); /* result and callback container table */ + return ret; } halfword -lua_hpack_filter (halfword head_node, scaled size, int pack_type, int extrainfo) { - halfword ret; - lua_State *L = Luas[0]; - int callback_id = callback_defined(hpack_filter_callback); - if (head_node==null || callback_id == 0) - return head_node; - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1, callback_id); - if (!lua_isfunction(L,-1)) { - lua_pop(L,2); - return head_node; - } - - nodelist_to_lua(L,head_node); - lua_pushstring(L,group_code_names[extrainfo]); - lua_pushnumber(L,size); - lua_pushstring(L,pack_type_name[pack_type]); - if (lua_pcall(L,4,1,0) != 0) { /* no arg, 1 result */ - fprintf(stdout,"error: %s\n",lua_tostring(L,-1)); - lua_pop(L,2); - error(); - return head_node; - } - ret = head_node; - if (lua_isboolean(L,-1)) { - if (lua_toboolean(L,-1)!=1) { - flush_node_list(head_node); - ret = null; - } - } else { - ret = nodelist_from_lua(L); - } - lua_pop(L,2); /* result and callback container table */ - /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);*/ - if (fix_node_lists) - fix_node_list(ret); - return ret; +lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo) +{ + halfword ret; + lua_State *L = Luas; + int callback_id = callback_defined(hpack_filter_callback); + if (head_node == null || callback_id == 0) + return head_node; + if (!get_callback(L, callback_id)) { + lua_pop(L, 2); + return head_node; + } + nodelist_to_lua(L, head_node); + lua_pushstring(L, group_code_names[extrainfo]); + lua_pushnumber(L, size); + lua_pushstring(L, pack_type_name[pack_type]); + if (lua_pcall(L, 4, 1, 0) != 0) { /* no arg, 1 result */ + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 2); + error(); + return head_node; + } + ret = head_node; + if (lua_isboolean(L, -1)) { + if (lua_toboolean(L, -1) != 1) { + flush_node_list(head_node); + ret = null; + } + } else { + ret = nodelist_from_lua(L); + } + lua_pop(L, 2); /* result and callback container table */ + /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); */ + if (fix_node_lists) + fix_node_list(ret); + return ret; } halfword -lua_vpack_filter (halfword head_node, scaled size, int pack_type, scaled maxd, int extrainfo) { - halfword ret; - integer callback_id ; - lua_State *L = Luas[0]; - if (head_node==null) - return head_node; - if (strcmp("output",group_code_names[extrainfo])==0) { - callback_id = callback_defined(pre_output_filter_callback); - } else { - callback_id = callback_defined(vpack_filter_callback); - } - if (callback_id==0) { - return head_node; - } - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - lua_rawgeti(L,-1, callback_id); - if (!lua_isfunction(L,-1)) { - lua_pop(L,2); - return head_node; - } - nodelist_to_lua(L,head_node); - lua_pushstring(L,group_code_names[extrainfo]); - lua_pushnumber(L,size); - lua_pushstring(L,pack_type_name[pack_type]); - lua_pushnumber(L,maxd); - if (lua_pcall(L,5,1,0) != 0) { /* no arg, 1 result */ - fprintf(stdout,"error: %s\n",lua_tostring(L,-1)); - lua_pop(L,2); - error(); - return head_node; - } - ret = head_node; - if (lua_isboolean(L,-1)) { - if (lua_toboolean(L,-1)!=1) { - flush_node_list(head_node); - ret = null; - } - } else { - ret = nodelist_from_lua(L); - } - lua_pop(L,2); /* result and callback container table */ - /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);*/ - if (fix_node_lists) - fix_node_list(ret); - return ret; +lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd, + int extrainfo) +{ + halfword ret; + integer callback_id; + lua_State *L = Luas; + if (head_node == null) + return head_node; + if (strcmp("output", group_code_names[extrainfo]) == 0) { + callback_id = callback_defined(pre_output_filter_callback); + } else { + callback_id = callback_defined(vpack_filter_callback); + } + if (callback_id == 0) { + return head_node; + } + if (!get_callback(L, callback_id)) { + lua_pop(L, 2); + return head_node; + } + nodelist_to_lua(L, head_node); + lua_pushstring(L, group_code_names[extrainfo]); + lua_pushnumber(L, size); + lua_pushstring(L, pack_type_name[pack_type]); + lua_pushnumber(L, maxd); + if (lua_pcall(L, 5, 1, 0) != 0) { /* no arg, 1 result */ + fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 2); + error(); + return head_node; + } + ret = head_node; + if (lua_isboolean(L, -1)) { + if (lua_toboolean(L, -1) != 1) { + flush_node_list(head_node); + ret = null; + } + } else { + ret = nodelist_from_lua(L); + } + lua_pop(L, 2); /* result and callback container table */ + /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); */ + if (fix_node_lists) + fix_node_list(ret); + return ret; } @@ -184,17 +250,16 @@ lua_vpack_filter (halfword head_node, scaled size, int pack_type, scaled maxd, i * eTeX manual for the expected return values. */ -int -visible_last_node_type (int n) { - int i = type(n); - if ((i!=math_node) && (i<=unset_node)) - return i+1; - if (i==glyph_node) - return -1; - if (i==whatsit_node && subtype(n)==local_par_node) - return -1; - if (i==255) - return -1 ; /* this is not right, probably dir nodes! */ - return last_known_node +1 ; +int visible_last_node_type(int n) +{ + int i = type(n); + if ((i != math_node) && (i <= unset_node)) + return i + 1; + if (i == glyph_node) + return -1; + if (i == whatsit_node && subtype(n) == local_par_node) + return -1; + if (i == 255) + return -1; /* this is not right, probably dir nodes! */ + return last_known_node + 1; } - diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.c b/Build/source/texk/web2c/luatexdir/lua/luastuff.c index f48bfdb0171..49298ea2fc5 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luastuff.c +++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.c @@ -1,41 +1,64 @@ -/* $Id: luastuff.c 1079 2008-03-05 15:34:41Z taco $ */ +/* luastuff.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include -lua_State *Luas[65536]; +static const char _svn_version[] = + "$Id: luastuff.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luastuff.c $"; + +lua_State *Luas = NULL; extern char *startup_filename; extern int safer_option; +extern int nosocket_option; -int luastate_max = 0; int luastate_bytes = 0; -void -make_table (lua_State *L, char *tab, char *getfunc, char *setfunc) { - /* make the table */ /* [{}] */ - lua_pushstring(L,tab); /* [{},"dimen"] */ - lua_newtable(L); /* [{},"dimen",{}] */ - lua_settable(L, -3); /* [{}] */ - /* fetch it back */ - lua_pushstring(L,tab); /* [{},"dimen"] */ - lua_gettable(L, -2); /* [{},{}] */ - /* make the meta entries */ - luaL_newmetatable(L,tab); /* [{},{},{}] */ - lua_pushstring(L, "__index"); /* [{},{},{},"__index"] */ - lua_pushstring(L, getfunc); /* [{},{},{},"__index","getdimen"] */ - lua_gettable(L, -5); /* [{},{},{},"__index",] */ - lua_settable(L, -3); /* [{},{},{}] */ - lua_pushstring(L, "__newindex");/* [{},{},{},"__newindex"] */ - lua_pushstring(L, setfunc); /* [{},{},{},"__newindex","setdimen"] */ - lua_gettable(L, -5); /* [{},{},{},"__newindex",] */ - lua_settable(L, -3); /* [{},{},{}] */ - lua_setmetatable(L,-2); /* [{},{}] : assign the metatable */ - lua_pop(L,1); /* [{}] : clean the stack */ +int lua_active = 0; + +void make_table(lua_State * L, char *tab, char *getfunc, char *setfunc) +{ + /* make the table *//* [{}] */ + lua_pushstring(L, tab); /* [{},"dimen"] */ + lua_newtable(L); /* [{},"dimen",{}] */ + lua_settable(L, -3); /* [{}] */ + /* fetch it back */ + lua_pushstring(L, tab); /* [{},"dimen"] */ + lua_gettable(L, -2); /* [{},{}] */ + /* make the meta entries */ + luaL_newmetatable(L, tab); /* [{},{},{}] */ + lua_pushstring(L, "__index"); /* [{},{},{},"__index"] */ + lua_pushstring(L, getfunc); /* [{},{},{},"__index","getdimen"] */ + lua_gettable(L, -5); /* [{},{},{},"__index",] */ + lua_settable(L, -3); /* [{},{},{}] */ + lua_pushstring(L, "__newindex"); /* [{},{},{},"__newindex"] */ + lua_pushstring(L, setfunc); /* [{},{},{},"__newindex","setdimen"] */ + lua_gettable(L, -5); /* [{},{},{},"__newindex",] */ + lua_settable(L, -3); /* [{},{},{}] */ + lua_setmetatable(L, -2); /* [{},{}] : assign the metatable */ + lua_pop(L, 1); /* [{}] : clean the stack */ } -static -const char *getS(lua_State * L, void *ud, size_t * size) { +static +const char *getS(lua_State * L, void *ud, size_t * size) +{ LoadS *ls = (LoadS *) ud; (void) L; if (ls->size == 0) @@ -45,266 +68,345 @@ const char *getS(lua_State * L, void *ud, size_t * size) { return ls->s; } -void *my_luaalloc (void *ud, void *ptr, size_t osize, size_t nsize) { - void *ret = NULL; - if (nsize == 0) - free(ptr); - else - ret = realloc(ptr, nsize); - luastate_bytes += (nsize-osize); - return ret; +void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize) +{ + void *ret = NULL; + (void)ud; /* for -Wunused */ + if (nsize == 0) + free(ptr); + else + ret = realloc(ptr, nsize); + luastate_bytes += (nsize - osize); + return ret; } -static int my_luapanic (lua_State *L) { - (void)L; /* to avoid warnings */ - fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", - lua_tostring(L, -1)); - return 0; +static int my_luapanic(lua_State * L) +{ + (void) L; /* to avoid warnings */ + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; } -void -luainterpreter (int n) { - lua_State *L; - L = lua_newstate(my_luaalloc, NULL); - if (L==NULL) { - fprintf(stderr,"Can't create a new Lua state (%d).",n); - return; - } - lua_atpanic(L, &my_luapanic); - - luastate_max++; - luaL_openlibs(L); - - open_oslibext(L,safer_option); - - lua_getglobal(L,"package"); - lua_pushstring(L,""); - lua_setfield(L,-2,"cpath"); - lua_pop(L,1); /* pop the table */ - - /*luaopen_unicode(L);*/ - lua_pushcfunction(L, luaopen_unicode); - lua_pushstring(L, "unicode"); - lua_call(L, 1, 0); - - /*luaopen_zip(L);*/ - lua_pushcfunction(L, luaopen_zip); - lua_pushstring(L, "zip"); - lua_call(L, 1, 0); - - /*luaopen_lpeg(L);*/ - lua_pushcfunction(L, luaopen_lpeg); - lua_pushstring(L, "lpeg"); - lua_call(L, 1, 0); - - /*luaopen_md5(L);*/ - lua_pushcfunction(L, luaopen_md5); - lua_pushstring(L, "md5"); - lua_call(L, 1, 0); - - /*luaopen_lfs(L);*/ - lua_pushcfunction(L, luaopen_lfs); - lua_pushstring(L, "lfs"); - lua_call(L, 1, 0); - - /* zlib. slightly odd calling convention */ - luaopen_zlib(L); - lua_setglobal(L,"zlib"); - luaopen_gzip(L); - /* fontforge */ - luaopen_ff(L); - - luaopen_pdf(L); - luaopen_tex(L); - luaopen_token(L); - luaopen_node(L); - luaopen_texio(L); - luaopen_kpse(L); - if (n==0) { +void luainterpreter(void) +{ + lua_State *L; + L = lua_newstate(my_luaalloc, NULL); + if (L == NULL) { + fprintf(stderr, "Can't create the Lua state.\n"); + return; + } + lua_atpanic(L, &my_luapanic); + + luaL_openlibs(L); + + open_oslibext(L, safer_option); + + lua_getglobal(L, "package"); + lua_pushstring(L, ""); + lua_setfield(L, -2, "cpath"); + lua_pop(L, 1); /* pop the table */ + + /*luaopen_unicode(L); */ + lua_pushcfunction(L, luaopen_unicode); + lua_pushstring(L, "unicode"); + lua_call(L, 1, 0); + + /*luaopen_zip(L); */ + lua_pushcfunction(L, luaopen_zip); + lua_pushstring(L, "zip"); + lua_call(L, 1, 0); + + /* luasockets */ + /* socket and mime are a bit tricky to open because + * they use a load-time dependency that has to be + * worked around for luatex, where the C module is + * loaded way before the lua module. + */ + if (!nosocket_option) { + lua_getglobal(L, "package"); + lua_getfield(L, -1, "loaded"); + if (!lua_istable(L, -1)) { + lua_newtable(L); + lua_setfield(L, -2, "loaded"); + lua_getfield(L, -1, "loaded"); + } + luaopen_socket_core(L); + lua_setfield(L, -2, "socket.core"); + lua_pushnil(L); + lua_setfield(L, -2, "socket"); /* package.loaded.socket = nil */ + + luaopen_mime_core(L); + lua_setfield(L, -2, "mime.core"); + lua_pushnil(L); + lua_setfield(L, -2, "mime"); /* package.loaded.mime = nil */ + lua_pop(L, 2); /* pop the tables */ + + luatex_socketlua_open(L); /* preload the pure lua modules */ + } + + /*luaopen_lpeg(L); */ + lua_pushcfunction(L, luaopen_lpeg); + lua_pushstring(L, "lpeg"); + lua_call(L, 1, 0); + + /*luaopen_md5(L); */ + lua_pushcfunction(L, luaopen_md5); + lua_pushstring(L, "md5"); + lua_call(L, 1, 0); + + /*luaopen_lfs(L); */ + lua_pushcfunction(L, luaopen_lfs); + lua_pushstring(L, "lfs"); + lua_call(L, 1, 0); + + /* zlib. slightly odd calling convention */ + luaopen_zlib(L); + lua_setglobal(L, "zlib"); + luaopen_gzip(L); + /* fontforge */ + luaopen_ff(L); + /* profiler, from kepler */ + luaopen_profiler(L); + + luaopen_pdf(L); + luaopen_tex(L); + luaopen_token(L); + luaopen_node(L); + luaopen_texio(L); + luaopen_kpse(L); + luaopen_callback(L); lua_createtable(L, 0, 0); lua_setglobal(L, "texconfig"); - } - luaopen_lua(L,n,startup_filename); - luaopen_stats(L); - luaopen_font(L); - luaopen_lang(L); - - /* luaopen_img(L); */ - lua_pushcfunction(L, luaopen_img); - lua_pushstring(L, "img"); - lua_call(L, 1, 0); - - luaopen_mp(L); - - if (safer_option) { - /* disable some stuff if --safer */ - (void)hide_lua_value(L, "os","execute"); - (void)hide_lua_value(L, "os","rename"); - (void)hide_lua_value(L, "os","remove"); - (void)hide_lua_value(L, "io","popen"); - /* make io.open only read files */ - luaL_checkstack(L,2,"out of stack space"); - lua_getglobal(L,"io"); - lua_getfield(L,-1,"open_ro"); - lua_setfield(L,-2,"open"); - (void)hide_lua_value(L, "io","tmpfile"); - (void)hide_lua_value(L, "io","output"); - (void)hide_lua_value(L, "lfs","chdir"); - (void)hide_lua_value(L, "lfs","lock"); - (void)hide_lua_value(L, "lfs","touch"); - (void)hide_lua_value(L, "lfs","rmdir"); - (void)hide_lua_value(L, "lfs","mkdir"); - } - Luas[n] = L; + + luaopen_lua(L, startup_filename); + luaopen_stats(L); + luaopen_font(L); + luaopen_lang(L); + + /* luaopen_img(L); */ + lua_pushcfunction(L, luaopen_img); + lua_pushstring(L, "img"); + lua_call(L, 1, 0); + + luaopen_mplib(L); + + if (safer_option) { + /* disable some stuff if --safer */ + (void) hide_lua_value(L, "os", "execute"); + (void) hide_lua_value(L, "os", "rename"); + (void) hide_lua_value(L, "os", "remove"); + (void) hide_lua_value(L, "io", "popen"); + /* make io.open only read files */ + luaL_checkstack(L, 2, "out of stack space"); + lua_getglobal(L, "io"); + lua_getfield(L, -1, "open_ro"); + lua_setfield(L, -2, "open"); + (void) hide_lua_value(L, "io", "tmpfile"); + (void) hide_lua_value(L, "io", "output"); + (void) hide_lua_value(L, "lfs", "chdir"); + (void) hide_lua_value(L, "lfs", "lock"); + (void) hide_lua_value(L, "lfs", "touch"); + (void) hide_lua_value(L, "lfs", "rmdir"); + (void) hide_lua_value(L, "lfs", "mkdir"); + } + Luas = L; +} + +int hide_lua_table(lua_State * L, char *name) +{ + int r = 0; + lua_getglobal(L, name); + if (lua_istable(L, -1)) { + r = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushnil(L); + lua_setglobal(L, name); + } + return r; } -int hide_lua_table(lua_State *L, char *name) { - int r=0; - lua_getglobal(L,name); - if(lua_istable(L,-1)) { - r = luaL_ref(L,LUA_REGISTRYINDEX); - lua_pushnil(L); - lua_setglobal(L,name); - } - return r; +void unhide_lua_table(lua_State * L, char *name, int r) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, r); + lua_setglobal(L, name); + luaL_unref(L, LUA_REGISTRYINDEX, r); } -void unhide_lua_table(lua_State *L, char *name, int r) { - lua_rawgeti(L,LUA_REGISTRYINDEX,r); - lua_setglobal(L,name); - luaL_unref(L,LUA_REGISTRYINDEX,r); +int hide_lua_value(lua_State * L, char *name, char *item) +{ + int r = 0; + lua_getglobal(L, name); + if (lua_istable(L, -1)) { + lua_getfield(L, -1, item); + r = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pushnil(L); + lua_setfield(L, -2, item); + } + return r; } -int hide_lua_value(lua_State *L, char *name, char *item) { - int r=0; - lua_getglobal(L,name); - if(lua_istable(L,-1)) { - lua_getfield(L,-1,item); - r = luaL_ref(L,LUA_REGISTRYINDEX); - lua_pushnil(L); - lua_setfield(L,-2,item); - } - return r; +void unhide_lua_value(lua_State * L, char *name, char *item, int r) +{ + lua_getglobal(L, name); + if (lua_istable(L, -1)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, r); + lua_setfield(L, -2, item); + luaL_unref(L, LUA_REGISTRYINDEX, r); + } } -void unhide_lua_value(lua_State *L, char *name, char *item, int r) { - lua_getglobal(L,name); - if(lua_istable(L,-1)) { - lua_rawgeti(L,LUA_REGISTRYINDEX,r); - lua_setfield(L,-2,item); - luaL_unref(L,LUA_REGISTRYINDEX,r); - } + +int lua_traceback(lua_State * L) +{ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; } +void luacall(int p, int nameptr) +{ + LoadS ls; + int i, l; + char *lua_id; + char *s = NULL; -void -luacall(int n, int s) { - LoadS ls; - int i ; - char lua_id[12]; - if (Luas[n] == NULL) { - luainterpreter(n); - } - luatex_load_init(s,&ls); - if (ls.size>0) { - snprintf((char *)lua_id,12,"luas[%d]",n); - i = lua_load(Luas[n], getS, &ls, lua_id); - if (i != 0) { - Luas[n] = luatex_error(Luas[n],(i == LUA_ERRSYNTAX ? 0 : 1)); - } else { - i = lua_pcall(Luas[n], 0, 0, 0); - if (i != 0) { - Luas[n] = luatex_error(Luas[n],(i == LUA_ERRRUN ? 0 : 1)); - } - } - } + if (Luas == NULL) { + luainterpreter(); + } + l = 0; + lua_active++; + s = tokenlist_to_cstring(p, 1, &l); + ls.s = s; + ls.size = l; + + if (ls.size > 0) { + if (nameptr > 0) { + lua_id = tokenlist_to_cstring(nameptr, 1, &l); + } else if (nameptr<0) { + char *tmp = get_lua_name((nameptr+65536)); + if (tmp!=NULL) + lua_id = xstrdup(tmp); + else + lua_id = xstrdup("\\latelua "); + } else { + lua_id = xmalloc(20); + snprintf((char *) lua_id, 20, "\\latelua ") ; + } + + i = lua_load(Luas, getS, &ls, lua_id); + if (i != 0) { + Luas = luatex_error(Luas, (i == LUA_ERRSYNTAX ? 0 : 1)); + } else { + int base = lua_gettop(Luas); /* function index */ + lua_checkstack(Luas, 1); + lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ + lua_insert(Luas, base); /* put it under chunk */ + i = lua_pcall(Luas, 0, 0, base); + lua_remove(Luas, base); /* remove traceback function */ + if (i != 0) { + lua_gc(Luas, LUA_GCCOLLECT, 0); + Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1)); + } + } + xfree(lua_id); + } + lua_active--; } -void -luatokencall(int n, int p) { - LoadS ls; - int i, l; - char *s=NULL; - char lua_id[12]; - if (Luas[n] == NULL) { - luainterpreter(n); - } - l = 0; - s = tokenlist_to_cstring(p,1,&l); - ls.s = s; - ls.size = l; - if (ls.size>0) { - snprintf((char *)lua_id,12,"luas[%d]",n); - i = lua_load(Luas[n], getS, &ls, lua_id); - xfree(s); - if (i != 0) { - Luas[n] = luatex_error(Luas[n],(i == LUA_ERRSYNTAX ? 0 : 1)); - } else { - i = lua_pcall(Luas[n], 0, 0, 0); - if (i != 0) { - Luas[n] = luatex_error(Luas[n],(i == LUA_ERRRUN ? 0 : 1)); - } - } - } +void luatokencall(int p, int nameptr) +{ + LoadS ls; + int i, l; + char *s = NULL; + char *lua_id; + assert (Luas); + l = 0; + lua_active++; + s = tokenlist_to_cstring(p, 1, &l); + ls.s = s; + ls.size = l; + if (ls.size > 0) { + if (nameptr > 0) { + lua_id = tokenlist_to_cstring(nameptr, 1, &l); + } else if (nameptr<0) { + char *tmp = get_lua_name((nameptr+65536)); + if (tmp!=NULL) + lua_id = xstrdup(tmp); + else + lua_id = xstrdup("\\directlua "); + } else { + lua_id = xstrdup("\\directlua "); + } + i = lua_load(Luas, getS, &ls, lua_id); + xfree(s); + if (i != 0) { + Luas = luatex_error(Luas, (i == LUA_ERRSYNTAX ? 0 : 1)); + } else { + int base = lua_gettop(Luas); /* function index */ + lua_checkstack(Luas, 1); + lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ + lua_insert(Luas, base); /* put it under chunk */ + i = lua_pcall(Luas, 0, 0, base); + lua_remove(Luas, base); /* remove traceback function */ + if (i != 0) { + lua_gc(Luas, LUA_GCCOLLECT, 0); + Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1)); + } + } + xfree(lua_id); + } + lua_active--; } -void -closelua(int n) { - if (n!=0 && Luas[n] != NULL) { - lua_close(Luas[n]); - luastate_max--; - Luas[n] = NULL; - } +void luatex_load_init(int s, LoadS * ls) +{ + ls->s = (const char *) &(str_pool[str_start[s]]); + ls->size = str_start[s + 1] - str_start[s]; } -void -luatex_load_init (int s, LoadS *ls) { - ls->s = (const char *)&(str_pool[str_start[s]]); - ls->size = str_start[s + 1] - str_start[s]; -} +lua_State *luatex_error(lua_State * L, int is_fatal) +{ -lua_State * -luatex_error (lua_State * L, int is_fatal) { - - size_t len; - char *err; - strnumber s; - const char *luaerr = lua_tolstring(L, -1,&len); - err = (char *)xmalloc(len+1); - len = snprintf(err,(len+1),"%s",luaerr); - if (is_fatal>0) { - /* Normally a memory error from lua. - The pool may overflow during the maketexlstring(), but we - are crashing anyway so we may as well abort on the pool size */ - s = maketexlstring(err, len); - lua_fatal_error(s); - /* never reached */ - xfree (err); - lua_close(L); - luastate_max--; - return (lua_State *)NULL; - } else { - /* Here, the pool could be full already, but we can possibly escape from that - * condition, since the lua chunk that caused the error is the current string. - */ - s = str_ptr-0x200000; - /* fprintf(stderr,"poolinfo: %d: %d,%d out of %d\n",s,pool_ptr,str_start[(s-1)],pool_size);*/ - pool_ptr = str_start[(s-1)]; - str_start[s] = pool_ptr; - if (pool_ptr+len>=pool_size) { - lua_norm_error(' '); + strnumber s; + const char *luaerr; + size_t len = 0; + char *err = NULL; + if (lua_isstring(L, -1)) { + luaerr = lua_tolstring(L, -1, &len); + err = (char *) xmalloc(len + 1); + len = snprintf(err, (len + 1), "%s", luaerr); + } + if (is_fatal > 0) { + /* Normally a memory error from lua. + The pool may overflow during the maketexlstring(), but we + are crashing anyway so we may as well abort on the pool size */ + s = maketexlstring(err, len); + lua_fatal_error(s); + /* never reached */ + xfree(err); + lua_close(L); + return (lua_State *) NULL; } else { - s = maketexlstring(err,len); - lua_norm_error(s); - flush_str(s); + s = maketexlstring(err, len); + lua_norm_error(s); + flush_str(s); + xfree(err); + return L; } - xfree (err); - return L; - } } - diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex.c b/Build/source/texk/web2c/luatexdir/lua/luatex.c index 5172ca24292..24b928fba45 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatex.c @@ -1,32 +1,53 @@ -/* $Id: luatex.c 1013 2008-02-14 00:09:02Z oneiros $ */ +/* luatex.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include +static const char _svn_version[] = + "$Id: luatex.c 2028 2009-03-14 18:50:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luatex.c $"; + /* do this aleph stuff here, for now */ -void -b_test_in(void) +extern int program_name_set; /* in lkpselib.c */ + +void b_test_in(void) { - string fname = kpse_find_file ((char *)(nameoffile + 1), - kpse_program_binary_format, true); - - if (fname) { - libcfree(nameoffile); - nameoffile = xmalloc(2+strlen(fname)); - namelength = strlen(fname); - strcpy((char *)nameoffile+1, fname); - } - else { - libcfree(nameoffile); - nameoffile = xmalloc(2); - namelength = 0; - nameoffile[0] = 0; - nameoffile[1] = 0; + if (program_name_set) { + string fname = kpse_find_file((char *) (nameoffile + 1), + kpse_program_binary_format, true); + if (fname) { + libcfree(nameoffile); + nameoffile = xmalloc(2 + strlen(fname)); + namelength = strlen(fname); + strcpy((char *) nameoffile + 1, fname); + } else { + libcfree(nameoffile); + nameoffile = xmalloc(2); + namelength = 0; + nameoffile[0] = 0; + nameoffile[1] = 0; + } } } - + int **ocp_tables; static int ocp_entries = 0; @@ -35,41 +56,39 @@ void allocate_ocp_table P2C(int, ocp_number, int, ocp_size) { int i; - if (ocp_entries==0) { - ocp_tables = (int **) xmalloc(256*sizeof(int**)); - ocp_entries=256; - } else if ((ocp_number==256)&&(ocp_entries==256)) { - ocp_tables = xrealloc(ocp_tables, 65536); - ocp_entries=65536; + if (ocp_entries == 0) { + ocp_tables = (int **) xmalloc(256 * sizeof(int **)); + ocp_entries = 256; + } else if ((ocp_number == 256) && (ocp_entries == 256)) { + ocp_tables = xrealloc(ocp_tables, 65536); + ocp_entries = 65536; } - ocp_tables[ocp_number] = - (int *) xmalloc((1+ocp_size)*sizeof(int)); + ocp_tables[ocp_number] = (int *) xmalloc((1 + ocp_size) * sizeof(int)); ocp_tables[ocp_number][0] = ocp_size; - for (i=1; i<=ocp_size; i++) { - ocp_tables[ocp_number][i] = 0; + for (i = 1; i <= ocp_size; i++) { + ocp_tables[ocp_number][i] = 0; } } void dump_ocp_table P1C(int, ocp_number) { - dump_things(ocp_tables[ocp_number][0], ocp_tables[ocp_number][0]+1); + dump_things(ocp_tables[ocp_number][0], ocp_tables[ocp_number][0] + 1); } void undump_ocp_table P1C(int, ocp_number) { int sizeword; - if (ocp_entries==0) { - ocp_tables = (int **) xmalloc(256*sizeof(int**)); - ocp_entries=256; - } else if ((ocp_number==256)&&(ocp_entries==256)) { - ocp_tables = xrealloc(ocp_tables, 65536); - ocp_entries=65536; + if (ocp_entries == 0) { + ocp_tables = (int **) xmalloc(256 * sizeof(int **)); + ocp_entries = 256; + } else if ((ocp_number == 256) && (ocp_entries == 256)) { + ocp_tables = xrealloc(ocp_tables, 65536); + ocp_entries = 65536; } - undump_things(sizeword,1); - ocp_tables[ocp_number] = - (int *) xmalloc((1+sizeword)*sizeof(int)); + undump_things(sizeword, 1); + ocp_tables[ocp_number] = (int *) xmalloc((1 + sizeword) * sizeof(int)); ocp_tables[ocp_number][0] = sizeword; undump_things(ocp_tables[ocp_number][1], sizeword); } @@ -78,141 +97,146 @@ undump_ocp_table P1C(int, ocp_number) void run_external_ocp P1C(string, external_ocp_name) { - char *in_file_name; - char *out_file_name; - FILE *in_file; - FILE *out_file; - char command_line[400]; - int i; - unsigned c; - int c_in; + char *in_file_name; + char *out_file_name; + FILE *in_file; + FILE *out_file; + int in_file_fd; + int out_file_fd; + char command_line[400]; + int i; + unsigned c; + int c_in; #ifdef WIN32 - char *tempenv; - -#define null_string(s) ((s == NULL) || (*s == '\0')) - - tempenv = getenv("TMPDIR"); - if (null_string(tempenv)) - tempenv = getenv("TEMP"); - if (null_string(tempenv)) - tempenv = getenv("TMP"); - if (null_string(tempenv)) - tempenv = "c:/tmp"; /* "/tmp" is not good if we are on a CD-ROM */ - in_file_name = concat(tempenv, "/__aleph__in__XXXXXX"); - mktemp(in_file_name); + char *tempenv; + +# define null_string(s) ((s == NULL) || (*s == '\0')) + + tempenv = getenv("TMPDIR"); + if (null_string(tempenv)) + tempenv = getenv("TEMP"); + if (null_string(tempenv)) + tempenv = getenv("TMP"); + if (null_string(tempenv)) + tempenv = "c:/tmp"; /* "/tmp" is not good if we are on a CD-ROM */ + in_file_name = concat(tempenv, "/__aleph__in__XXXXXX"); + mktemp(in_file_name); + in_file = fopen(in_file_name, FOPEN_WBIN_MODE); #else - in_file_name = strdup("/tmp/__aleph__in__XXXXXX"); - mkstemp(in_file_name); -#endif /* WIN32 */ - - in_file = fopen(in_file_name, FOPEN_WBIN_MODE); - - for (i=1; i<=otp_input_end; i++) { - c = otp_input_buf[i]; - if (c>0xffff) { - fprintf(stderr, "Aleph does not currently support 31-bit chars\n"); - exit(1); - } - if (c>0x4000000) { - fputc(0xfc | ((c>>30) & 0x1), in_file); - fputc(0x80 | ((c>>24) & 0x3f), in_file); - fputc(0x80 | ((c>>18) & 0x3f), in_file); - fputc(0x80 | ((c>>12) & 0x3f), in_file); - fputc(0x80 | ((c>>6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c>0x200000) { - fputc(0xf8 | ((c>>24) & 0x3), in_file); - fputc(0x80 | ((c>>18) & 0x3f), in_file); - fputc(0x80 | ((c>>12) & 0x3f), in_file); - fputc(0x80 | ((c>>6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c>0x10000) { - fputc(0xf0 | ((c>>18) & 0x7), in_file); - fputc(0x80 | ((c>>12) & 0x3f), in_file); - fputc(0x80 | ((c>>6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c>0x800) { - fputc(0xe0 | ((c>>12) & 0xf), in_file); - fputc(0x80 | ((c>>6) & 0x3f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else if (c>0x80) { - fputc(0xc0 | ((c>>6) & 0x1f), in_file); - fputc(0x80 | (c & 0x3f), in_file); - } else { - fputc(c & 0x7f, in_file); - } - } - fclose(in_file); - + in_file_name = strdup("/tmp/__aleph__in__XXXXXX"); + in_file_fd = mkstemp(in_file_name); + in_file = fdopen(in_file_fd, FOPEN_WBIN_MODE); +#endif /* WIN32 */ + + + for (i = 1; i <= otp_input_end; i++) { + c = otp_input_buf[i]; + if (c > 0xffff) { + fprintf(stderr, "Aleph does not currently support 31-bit chars\n"); + exit(1); + } + if (c > 0x4000000) { + fputc(0xfc | ((c >> 30) & 0x1), in_file); + fputc(0x80 | ((c >> 24) & 0x3f), in_file); + fputc(0x80 | ((c >> 18) & 0x3f), in_file); + fputc(0x80 | ((c >> 12) & 0x3f), in_file); + fputc(0x80 | ((c >> 6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c > 0x200000) { + fputc(0xf8 | ((c >> 24) & 0x3), in_file); + fputc(0x80 | ((c >> 18) & 0x3f), in_file); + fputc(0x80 | ((c >> 12) & 0x3f), in_file); + fputc(0x80 | ((c >> 6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c > 0x10000) { + fputc(0xf0 | ((c >> 18) & 0x7), in_file); + fputc(0x80 | ((c >> 12) & 0x3f), in_file); + fputc(0x80 | ((c >> 6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c > 0x800) { + fputc(0xe0 | ((c >> 12) & 0xf), in_file); + fputc(0x80 | ((c >> 6) & 0x3f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else if (c > 0x80) { + fputc(0xc0 | ((c >> 6) & 0x1f), in_file); + fputc(0x80 | (c & 0x3f), in_file); + } else { + fputc(c & 0x7f, in_file); + } + } + fclose(in_file); + #define advance_cin if ((c_in = fgetc(out_file)) == -1) { \ fprintf(stderr, "File contains bad char\n"); \ goto end_of_while; \ } - + #ifdef WIN32 - out_file_name = concat(tempenv, "/__aleph__out__XXXXXX"); - mktemp(out_file_name); + out_file_name = concat(tempenv, "/__aleph__out__XXXXXX"); + mktemp(out_file_name); + out_file = fopen(out_file_name, FOPEN_RBIN_MODE); #else - out_file_name = strdup("/tmp/__aleph__out__XXXXXX"); - mkstemp(out_file_name); + out_file_name = strdup("/tmp/__aleph__out__XXXXXX"); + out_file_fd = mkstemp(out_file_name); + out_file = fdopen(out_file_fd, FOPEN_RBIN_MODE); #endif - sprintf(command_line, "%s <%s >%s\n", - external_ocp_name+1, in_file_name, out_file_name); - system(command_line); - out_file = fopen(out_file_name, FOPEN_RBIN_MODE); - otp_output_end = 0; - otp_output_buf[otp_output_end] = 0; - while ((c_in = fgetc(out_file)) != -1) { - if (c_in>=0xfc) { - c = (c_in & 0x1) << 30; - {advance_cin} - c |= (c_in & 0x3f) << 24; - {advance_cin} - c |= (c_in & 0x3f) << 18; - {advance_cin} - c |= (c_in & 0x3f) << 12; - {advance_cin} - c |= (c_in & 0x3f) << 6; - {advance_cin} - c |= c_in & 0x3f; - } else if (c_in>=0xf8) { - c = (c_in & 0x3) << 24; - {advance_cin} - c |= (c_in & 0x3f) << 18; - {advance_cin} - c |= (c_in & 0x3f) << 12; - {advance_cin} - c |= (c_in & 0x3f) << 6; - {advance_cin} - c |= c_in & 0x3f; - } else if (c_in>=0xf0) { - c = (c_in & 0x7) << 18; - {advance_cin} - c |= (c_in & 0x3f) << 12; - {advance_cin} - c |= (c_in & 0x3f) << 6; - {advance_cin} - c |= c_in & 0x3f; - } else if (c_in>=0xe0) { - c = (c_in & 0xf) << 12; - {advance_cin} - c |= (c_in & 0x3f) << 6; - {advance_cin} - c |= c_in & 0x3f; - } else if (c_in>=0x80) { - c = (c_in & 0x1f) << 6; - {advance_cin} - c |= c_in & 0x3f; - } else { - c = c_in & 0x7f; - } - otp_output_buf[++otp_output_end] = c; - } - -end_of_while: - remove(in_file_name); - remove(out_file_name); + sprintf(command_line, "%s <%s >%s\n", + external_ocp_name + 1, in_file_name, out_file_name); + system(command_line); + otp_output_end = 0; + otp_output_buf[otp_output_end] = 0; + while ((c_in = fgetc(out_file)) != -1) { + if (c_in >= 0xfc) { + c = (c_in & 0x1) << 30; + advance_cin; + c |= (c_in & 0x3f) << 24; + advance_cin; + c |= (c_in & 0x3f) << 18; + advance_cin; + c |= (c_in & 0x3f) << 12; + advance_cin; + c |= (c_in & 0x3f) << 6; + advance_cin; + c |= c_in & 0x3f; + } else if (c_in >= 0xf8) { + c = (c_in & 0x3) << 24; + advance_cin; + c |= (c_in & 0x3f) << 18; + advance_cin; + c |= (c_in & 0x3f) << 12; + advance_cin; + c |= (c_in & 0x3f) << 6; + advance_cin; + c |= c_in & 0x3f; + } else if (c_in >= 0xf0) { + c = (c_in & 0x7) << 18; + advance_cin; + c |= (c_in & 0x3f) << 12; + advance_cin; + c |= (c_in & 0x3f) << 6; + advance_cin; + c |= c_in & 0x3f; + } else if (c_in >= 0xe0) { + c = (c_in & 0xf) << 12; + advance_cin; + c |= (c_in & 0x3f) << 6; + advance_cin; + c |= c_in & 0x3f; + } else if (c_in >= 0x80) { + c = (c_in & 0x1f) << 6; + advance_cin; + c |= c_in & 0x3f; + } else { + c = c_in & 0x7f; + } + otp_output_buf[++otp_output_end] = c; + } + fclose(out_file); + + end_of_while: + remove(in_file_name); + remove(out_file_name); } /* Read and write dump files through zlib */ @@ -224,120 +248,116 @@ end_of_while: static gzFile gz_fmtfile = NULL; -void -do_zdump (char *p, int item_size, int nitems, FILE *out_file) +void do_zdump(char *p, int item_size, int nitems, FILE * out_file) { - int err; - if (nitems==0) - return; - if (gzwrite (gz_fmtfile,(void *)p, item_size*nitems) != item_size*nitems) - { - fprintf (stderr, "! Could not write %d %d-byte item(s): %s.\n", - nitems, item_size, gzerror(gz_fmtfile,&err)); - uexit (1); + int err; + if (nitems == 0) + return; + if (gzwrite(gz_fmtfile, (void *) p, item_size * nitems) != + item_size * nitems) { + fprintf(stderr, "! Could not write %d %d-byte item(s): %s.\n", nitems, + item_size, gzerror(gz_fmtfile, &err)); + uexit(1); } } -void -do_zundump (char *p, int item_size, int nitems, FILE *in_file) +void do_zundump(char *p, int item_size, int nitems, FILE * in_file) { - int err; - if (nitems==0) - return; - if (gzread (gz_fmtfile,(void *)p, item_size*nitems) <= 0) - { - fprintf (stderr, "Could not undump %d %d-byte item(s): %s.\n", - nitems, item_size, gzerror(gz_fmtfile,&err)); - uexit (1); - } + int err; + if (nitems == 0) + return; + if (gzread(gz_fmtfile, (void *) p, item_size * nitems) <= 0) { + fprintf(stderr, "Could not undump %d %d-byte item(s): %s.\n", + nitems, item_size, gzerror(gz_fmtfile, &err)); + uexit(1); + } } #define COMPRESSION "R3" -boolean -zopen_w_input (FILE **f, int format, const_string fopen_mode) { - int callbackid; - int res; - char *fnam; - callbackid = callback_defined(find_format_file_callback); - if (callbackid>0) { - res = run_callback(callbackid,"S->S",(nameoffile+1),&fnam); - if (res && fnam && strlen(fnam)>0) { - xfree (nameoffile); - nameoffile = xmalloc (strlen(fnam)+2); - memcpy((nameoffile+1),fnam,strlen(fnam)); - *(nameoffile+strlen(fnam)+1)=0; - *f = xfopen(fnam,fopen_mode); - if (*f == NULL) { - return 0; - } - } else { - return 0; - } - } else { - res = open_input(f,format,fopen_mode); - } - if (res) { - gz_fmtfile = gzdopen(fileno(*f),"rb" COMPRESSION); - } - return res; +boolean zopen_w_input(FILE ** f, int format, const_string fopen_mode) +{ + int callbackid; + int res; + char *fnam; + callbackid = callback_defined(find_format_file_callback); + if (callbackid > 0) { + res = run_callback(callbackid, "S->S", (nameoffile + 1), &fnam); + if (res && fnam && strlen(fnam) > 0) { + xfree(nameoffile); + nameoffile = xmalloc(strlen(fnam) + 2); + memcpy((nameoffile + 1), fnam, strlen(fnam)); + *(nameoffile + strlen(fnam) + 1) = 0; + *f = xfopen(fnam, fopen_mode); + if (*f == NULL) { + return 0; + } + } else { + return 0; + } + } else { + res = open_input(f, format, fopen_mode); + } + if (res) { + gz_fmtfile = gzdopen(fileno(*f), "rb" COMPRESSION); + } + return res; } -boolean -zopen_w_output (FILE **f, const_string fopen_mode) { - int res = 1; - if (luainit) { - *f = fopen((nameoffile+1),fopen_mode); - if (*f == NULL) { - return 0; +boolean zopen_w_output(FILE ** f, const_string fopen_mode) +{ + int res = 1; + if (luainit) { + *f = fopen((const_string) (nameoffile + 1), fopen_mode); + if (*f == NULL) { + return 0; + } + } else { + res = open_output(f, fopen_mode); + } + if (res) { + gz_fmtfile = gzdopen(fileno(*f), "wb" COMPRESSION); } - } else { - res = open_output(f,fopen_mode); - } - if (res) { - gz_fmtfile = gzdopen(fileno(*f),"wb" COMPRESSION); - } - return res; + return res; } -void -zwclose (FILE *f) { - gzclose(gz_fmtfile); +void zwclose(FILE * f) +{ + gzclose(gz_fmtfile); } /* create the dvi or pdf file */ -int -open_outfile(FILE **f, char *name, char *mode) { - FILE *res; - res = fopen(name,mode); - if (res != NULL) { - *f = res; - return 1; - } - return 0; +int open_outfile(FILE ** f, char *name, char *mode) +{ + FILE *res; + res = fopen(name, mode); + if (res != NULL) { + *f = res; + return 1; + } + return 0; } /* the caller sets tfm_buffer=NULL and tfm_size=0 */ -int -readbinfile (FILE *f, unsigned char **tfm_buffer, integer *tfm_size) { - void *buf; - int size; - if (fseek(f, 0, SEEK_END)==0) { - size = ftell(f); - if (size>0) { - buf = xmalloc(size); - if(fseek(f, 0, SEEK_SET)==0) { - if(fread((void *)buf,size,1,f)==1) { - *tfm_buffer=(unsigned char *)buf; - *tfm_size=(integer)size; - return 1; - } - } - } - } /* seek failed, or zero-sized file */ - return 0; +int readbinfile(FILE * f, unsigned char **tfm_buffer, integer * tfm_size) +{ + void *buf; + int size; + if (fseek(f, 0, SEEK_END) == 0) { + size = ftell(f); + if (size > 0) { + buf = xmalloc(size); + if (fseek(f, 0, SEEK_SET) == 0) { + if (fread((void *) buf, size, 1, f) == 1) { + *tfm_buffer = (unsigned char *) buf; + *tfm_size = (integer) size; + return 1; + } + } + } + } /* seek failed, or zero-sized file */ + return 0; } - diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.c b/Build/source/texk/web2c/luatexdir/lua/luatoken.c index 5f823104d56..4182d94e6fe 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatoken.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.c @@ -1,548 +1,600 @@ -/* $Id: luatoken.c 1168 2008-04-15 13:43:34Z taco $ */ +/* luatoken.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "tokens.h" +#include "commands.h" -command_item command_names[] = - { { "relax", 0, NULL }, - { "left_brace", 0 , NULL }, - { "right_brace", 0 , NULL }, - { "math_shift", 0 , NULL }, - { "tab_mark", 0 , NULL }, - { "car_ret", 0 , NULL }, - { "mac_param", 0 , NULL }, - { "sup_mark", 0 , NULL }, - { "sub_mark", 0 , NULL }, - { "endv", 0 , NULL }, - { "spacer", 0 , NULL }, - { "letter", 0 , NULL }, - { "other_char", 0 , NULL }, - { "par_end", 0 , NULL }, - { "stop", 0 , NULL }, - { "delim_num", 0 , NULL }, - { "char_num", 0 , NULL }, - { "math_char_num", 0 , NULL }, - { "mark", 0 , NULL }, - { "xray", 0 , NULL }, - { "make_box", 0 , NULL }, - { "hmove", 0 , NULL }, - { "vmove", 0 , NULL }, - { "un_hbox", 0 , NULL }, - { "un_vbox", 0 , NULL }, - { "remove_item", 0 , NULL }, - { "hskip", 0 , NULL }, - { "vskip", 0 , NULL }, - { "mskip", 0 , NULL }, - { "kern", 0 , NULL }, - { "mkern", 0 , NULL }, - { "leader_ship", 0 , NULL }, - { "halign", 0 , NULL }, - { "valign", 0 , NULL }, - { "no_align", 0 , NULL }, - { "vrule", 0 , NULL }, - { "hrule", 0 , NULL }, - { "insert", 0 , NULL }, - { "vadjust", 0 , NULL }, - { "ignore_spaces", 0 , NULL }, - { "after_assignment", 0 , NULL }, - { "after_group", 0 , NULL }, - { "break_penalty", 0 , NULL }, - { "start_par", 0 , NULL }, - { "ital_corr", 0 , NULL }, - { "accent", 0 , NULL }, - { "math_accent", 0 , NULL }, - { "discretionary", 0 , NULL }, - { "eq_no", 0 , NULL }, - { "left_right", 0 , NULL }, - { "math_comp", 0 , NULL }, - { "limit_switch", 0 , NULL }, - { "above", 0 , NULL }, - { "math_style", 0 , NULL }, - { "math_choice", 0 , NULL }, - { "non_script", 0 , NULL }, - { "vcenter", 0 , NULL }, - { "case_shift", 0 , NULL }, - { "message", 0 , NULL }, - { "extension", 0 , NULL }, - { "in_stream", 0 , NULL }, - { "begin_group", 0 , NULL }, - { "end_group", 0 , NULL }, - { "omit", 0 , NULL }, - { "ex_space", 0 , NULL }, - { "no_boundary", 0 , NULL }, - { "radical", 0 , NULL }, - { "end_cs_name", 0 , NULL }, - { "char_ghost", 0 , NULL }, - { "assign_local_box", 0 , NULL }, - { "char_given", 0 , NULL }, - { "math_given", 0 , NULL }, - { "omath_given", 0 , NULL }, - { "last_item", 0 , NULL }, - { "toks_register", 0 , NULL }, - { "assign_toks", 0, NULL }, - { "assign_int", 0, NULL }, - { "assign_dimen", 0 , NULL }, - { "assign_glue", 0 ,NULL }, - { "assign_mu_glue", 0 , NULL }, - { "assign_font_dimen", 0 , NULL }, - { "assign_font_int", 0 , NULL }, - { "set_aux", 0 , NULL }, - { "set_prev_graf", 0 , NULL }, - { "set_page_dimen", 0 , NULL }, - { "set_page_int", 0 , NULL }, - { "set_box_dimen", 0 , NULL }, - { "set_shape", 0, NULL }, - { "def_code", 0 , NULL }, - { "extdef_code", 0 , NULL }, - { "def_family", 0 , NULL }, - { "set_font", 0 , NULL }, - { "def_font", 0 , NULL }, - { "register", 0 , NULL }, - { "assign_box_dir", 0 , NULL }, - { "assign_dir", 0 , NULL }, - { "advance", 0 , NULL }, - { "multiply", 0 , NULL }, - { "divide", 0 , NULL }, - { "prefix", 0 , NULL }, - { "let", 0 , NULL }, /* 100 */ - { "shorthand_def", 0 , NULL }, - { "read_to_cs", 0 , NULL }, - { "def", 0 , NULL }, - { "set_box", 0 , NULL }, - { "hyph_data", 0 , NULL }, - { "set_interaction", 0 , NULL }, - { "letterspace_font", 0 , NULL }, - { "set_ocp", 0 , NULL }, - { "def_ocp", 0 , NULL }, - { "set_ocp_list", 0 , NULL }, /* 110 */ - { "def_ocp_list", 0 , NULL }, - { "clear_ocp_lists", 0 , NULL }, - { "push_ocp_list", 0 , NULL }, - { "pop_ocp_list", 0 , NULL }, - { "ocp_list_op", 0 , NULL }, - { "ocp_trace_level", 0 , NULL}, - { "undefined_cs", 0 , NULL }, - { "expand_after", 0 , NULL }, - { "no_expand", 0 , NULL }, - { "input", 0 , NULL }, /* 120 */ - { "if_test", 0 , NULL }, - { "fi_or_else", 0 , NULL }, - { "cs_name", 0 , NULL }, - { "convert", 0 , NULL }, - { "the", 0 , NULL }, - { "top_bot_mark", 0 , NULL }, - { "call", 0 , NULL }, - { "long_call", 0 , NULL }, - { "outer_call", 0 , NULL }, - { "long_outer_call", 0 , NULL }, /* 130 */ - { "end_template", 0 , NULL }, - { "dont_expand", 0, NULL }, - { "glue_ref", 0 , NULL }, - { "shape_ref", 0 , NULL }, - { "box_ref", 0 , NULL }, - { "data", 0 , NULL }, - { NULL, 0, NULL } }; - - -int get_command_id (char *s) { - int i; - int cmd = -1; - for (i=0;command_names[i].cmd_name != NULL;i++) { - if (strcmp(s,command_names[i].cmd_name) == 0) - break; - } - if (command_names[i].cmd_name!=NULL) { - cmd = i; - } - return cmd; +static const char _svn_version[] = + "$Id: luatoken.c 2079 2009-03-22 10:15:03Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luatoken.c $"; + +command_item command_names[] = { + {"relax", relax_cmd, NULL}, + {"left_brace", left_brace_cmd, NULL}, + {"right_brace", right_brace_cmd, NULL}, + {"math_shift", math_shift_cmd, NULL}, + {"tab_mark", tab_mark_cmd, NULL}, + {"car_ret", car_ret_cmd, NULL}, + {"mac_param", mac_param_cmd, NULL}, + {"sup_mark", sup_mark_cmd, NULL}, + {"sub_mark", sub_mark_cmd, NULL}, + {"endv", endv_cmd, NULL}, + {"spacer", spacer_cmd, NULL}, + {"letter", letter_cmd, NULL}, + {"other_char", other_char_cmd, NULL}, + {"par_end", par_end_cmd, NULL}, + {"stop", stop_cmd, NULL}, + {"delim_num", delim_num_cmd, NULL}, + {"char_num", char_num_cmd, NULL}, + {"math_char_num", math_char_num_cmd, NULL}, + {"mark", mark_cmd, NULL}, + {"xray", xray_cmd, NULL}, + {"make_box", make_box_cmd, NULL}, + {"hmove", hmove_cmd, NULL}, + {"vmove", vmove_cmd, NULL}, + {"un_hbox", un_hbox_cmd, NULL}, + {"un_vbox", un_vbox_cmd, NULL}, + {"remove_item", remove_item_cmd, NULL}, + {"hskip", hskip_cmd, NULL}, + {"vskip", vskip_cmd, NULL}, + {"mskip", mskip_cmd, NULL}, + {"kern", kern_cmd, NULL}, + {"mkern", mkern_cmd, NULL}, + {"leader_ship", leader_ship_cmd, NULL}, + {"halign", halign_cmd, NULL}, + {"valign", valign_cmd, NULL}, + {"no_align", no_align_cmd, NULL}, + {"vrule", vrule_cmd, NULL}, + {"hrule", hrule_cmd, NULL}, + {"insert", insert_cmd, NULL}, + {"vadjust", vadjust_cmd, NULL}, + {"ignore_spaces", ignore_spaces_cmd, NULL}, + {"after_assignment", after_assignment_cmd, NULL}, + {"after_group", after_group_cmd, NULL}, + {"break_penalty", break_penalty_cmd, NULL}, + {"start_par", start_par_cmd, NULL}, + {"ital_corr", ital_corr_cmd, NULL}, + {"accent", accent_cmd, NULL}, + {"math_accent", math_accent_cmd, NULL}, + {"discretionary", discretionary_cmd, NULL}, + {"eq_no", eq_no_cmd, NULL}, + {"left_right", left_right_cmd, NULL}, + {"math_comp", math_comp_cmd, NULL}, + {"limit_switch", limit_switch_cmd, NULL}, + {"above", above_cmd, NULL}, + {"math_style", math_style_cmd, NULL}, + {"math_choice", math_choice_cmd, NULL}, + {"non_script", non_script_cmd, NULL}, + {"vcenter", vcenter_cmd, NULL}, + {"case_shift", case_shift_cmd, NULL}, + {"message", message_cmd, NULL}, + {"extension", extension_cmd, NULL}, + {"in_stream", in_stream_cmd, NULL}, + {"begin_group", begin_group_cmd, NULL}, + {"end_group", end_group_cmd, NULL}, + {"omit", omit_cmd, NULL}, + {"ex_space", ex_space_cmd, NULL}, + {"no_boundary", no_boundary_cmd, NULL}, + {"radical", radical_cmd, NULL}, + {"end_cs_name", end_cs_name_cmd, NULL}, + {"char_ghost", char_ghost_cmd, NULL}, + {"assign_local_box", assign_local_box_cmd, NULL}, + {"char_given", char_given_cmd, NULL}, + {"math_given", math_given_cmd, NULL}, + {"omath_given", omath_given_cmd, NULL}, + {"xmath_given", xmath_given_cmd, NULL}, + {"last_item", last_item_cmd, NULL}, + {"toks_register", toks_register_cmd, NULL}, + {"assign_toks", assign_toks_cmd, NULL}, + {"assign_int", assign_int_cmd, NULL}, + {"assign_attr", assign_attr_cmd, NULL}, + {"assign_dimen", assign_dimen_cmd, NULL}, + {"assign_glue", assign_glue_cmd, NULL}, + {"assign_mu_glue", assign_mu_glue_cmd, NULL}, + {"assign_font_dimen", assign_font_dimen_cmd, NULL}, + {"assign_font_int", assign_font_int_cmd, NULL}, + {"set_aux", set_aux_cmd, NULL}, + {"set_prev_graf", set_prev_graf_cmd, NULL}, + {"set_page_dimen", set_page_dimen_cmd, NULL}, + {"set_page_int", set_page_int_cmd, NULL}, + {"set_box_dimen", set_box_dimen_cmd, NULL}, + {"set_tex_shape", set_tex_shape_cmd, NULL}, + {"set_etex_shape", set_etex_shape_cmd, NULL}, + {"def_char_code", def_char_code_cmd, NULL}, + {"def_del_code", def_del_code_cmd, NULL}, + {"extdef_math_code", extdef_math_code_cmd, NULL}, + {"extdef_del_code", extdef_del_code_cmd, NULL}, + {"def_family", def_family_cmd, NULL}, + {"set_math_param", set_math_param_cmd, NULL}, + {"set_font", set_font_cmd, NULL}, + {"def_font", def_font_cmd, NULL}, + {"register", register_cmd, NULL}, + {"assign_box_dir", assign_box_dir_cmd, NULL}, + {"assign_dir", assign_dir_cmd, NULL}, + {"advance", advance_cmd, NULL}, + {"multiply", multiply_cmd, NULL}, + {"divide", divide_cmd, NULL}, + {"prefix", prefix_cmd, NULL}, + {"let", let_cmd, NULL}, + {"shorthand_def", shorthand_def_cmd, NULL}, + {"read_to_cs", read_to_cs_cmd, NULL}, + {"def", def_cmd, NULL}, + {"set_box", set_box_cmd, NULL}, + {"hyph_data", hyph_data_cmd, NULL}, + {"set_interaction", set_interaction_cmd, NULL}, + {"letterspace_font", letterspace_font_cmd, NULL}, + {"pdf_copy_font", pdf_copy_font_cmd, NULL}, + {"set_ocp", set_ocp_cmd, NULL}, + {"def_ocp", def_ocp_cmd, NULL}, + {"set_ocp_list", set_ocp_list_cmd, NULL}, + {"def_ocp_list", def_ocp_list_cmd, NULL}, + {"clear_ocp_lists", clear_ocp_lists_cmd, NULL}, + {"push_ocp_list", push_ocp_list_cmd, NULL}, + {"pop_ocp_list", pop_ocp_list_cmd, NULL}, + {"ocp_list_op", ocp_list_op_cmd, NULL}, + {"ocp_trace_level", ocp_trace_level_cmd, NULL}, + {"undefined_cs", undefined_cs_cmd, NULL}, + {"expand_after", expand_after_cmd, NULL}, + {"no_expand", no_expand_cmd, NULL}, + {"input", input_cmd, NULL}, + {"if_test", if_test_cmd, NULL}, + {"fi_or_else", fi_or_else_cmd, NULL}, + {"cs_name", cs_name_cmd, NULL}, + {"convert", convert_cmd, NULL}, + {"the", the_cmd, NULL}, + {"top_bot_mark", top_bot_mark_cmd, NULL}, + {"call", call_cmd, NULL}, + {"long_call", long_call_cmd, NULL}, + {"outer_call", outer_call_cmd, NULL}, + {"long_outer_call", long_outer_call_cmd, NULL}, + {"end_template", end_template_cmd, NULL}, + {"dont_expand", dont_expand_cmd, NULL}, + {"glue_ref", glue_ref_cmd, NULL}, + {"shape_ref", shape_ref_cmd, NULL}, + {"box_ref", box_ref_cmd, NULL}, + {"data", data_cmd, NULL}, + {NULL, 0, NULL} +}; + + +int get_command_id(char *s) +{ + int i; + int cmd = -1; + for (i = 0; command_names[i].cmd_name != NULL; i++) { + if (strcmp(s, command_names[i].cmd_name) == 0) + break; + } + if (command_names[i].cmd_name != NULL) { + cmd = i; + } + return cmd; } -static int -get_cur_cmd (lua_State *L) { - int r = 0, len; - cur_cs = 0; - len = lua_objlen(L,-1); - if (len==3 || len==2) { - r = 1; - lua_rawgeti(L,-1,1); - cur_cmd = lua_tointeger(L,-1); - lua_rawgeti(L,-2,2); - cur_chr = lua_tointeger(L,-1); - if (len==3) { - lua_rawgeti(L,-3,3); - cur_cs = lua_tointeger(L,-1); - } - lua_pop(L,len); - if (cur_cs==0) - cur_tok=(cur_cmd*string_offset)+cur_chr; - else - cur_tok=cs_token_flag+cur_cs; - } - return r; +static int get_cur_cmd(lua_State * L) +{ + int r = 0; + int len = lua_objlen(L, -1); + cur_cs = 0; + if (len == 3 || len == 2) { + r = 1; + lua_rawgeti(L, -1, 1); + cur_cmd = lua_tointeger(L, -1); + lua_rawgeti(L, -2, 2); + cur_chr = lua_tointeger(L, -1); + if (len == 3) { + lua_rawgeti(L, -3, 3); + cur_cs = lua_tointeger(L, -1); + } + lua_pop(L, len); + if (cur_cs == 0) + cur_tok = (cur_cmd * string_offset) + cur_chr; + else + cur_tok = cs_token_flag + cur_cs; + } + return r; } -static int -token_from_lua (lua_State *L) { - int cmd,chr; - int cs = 0; - int len = lua_objlen(L,-1); - if (len==3 || len==2) { - lua_rawgeti(L,-1,1); - cmd = lua_tointeger(L,-1); - lua_rawgeti(L,-2,2); - chr = lua_tointeger(L,-1); - if (len==3) { - lua_rawgeti(L,-3,3); - cs = lua_tointeger(L,-1); - } - lua_pop(L,len); - if (cs==0) { - return (cmd*string_offset)+chr; - } else { - return cs_token_flag+cs; +static int token_from_lua(lua_State * L) +{ + int cmd, chr; + int cs = 0; + int len = lua_objlen(L, -1); + if (len == 3 || len == 2) { + lua_rawgeti(L, -1, 1); + cmd = lua_tointeger(L, -1); + lua_rawgeti(L, -2, 2); + chr = lua_tointeger(L, -1); + if (len == 3) { + lua_rawgeti(L, -3, 3); + cs = lua_tointeger(L, -1); + } + lua_pop(L, len); + if (cs == 0) { + return (cmd * string_offset) + chr; + } else { + return cs_token_flag + cs; + } } - } - return -1; + return -1; } -static int -get_cur_cs (lua_State *L) { - char *s; - unsigned j; - size_t l; - integer cs; - int save_nncs; - int ret; - ret = 0; - cur_cs = 0; - lua_getfield(L,-1,"name"); - if (lua_isstring(L,-1)) { - s = (char *)lua_tolstring(L,-1,&l); - if (l>0) { - if ((int)(last+l)>buf_size) - check_buffer_overflow(last+l); - for (j=0;j 0) { + if ((int) (last + l) > buf_size) + check_buffer_overflow(last + l); + for (j = 0; j < l; j++) { + buffer[last + 1 + j] = *s++; + } + save_nncs = no_new_control_sequence; + no_new_control_sequence = false; + cs = id_lookup((last + 1), l); + cur_tok = cs_token_flag + cs; + cur_cmd = zget_eq_type(cs); + cur_chr = zget_equiv(cs); + no_new_control_sequence = save_nncs; + ret = 1; + } } - } - lua_pop(L,1); - return ret; + lua_pop(L, 1); + return ret; } -#define append_i_byte(a) { \ - if ((i+2)>alloci) { \ - ret = xrealloc(ret,alloci+64); \ - alloci = alloci + 64; } \ - ret[i++] = a; } - -#define Print_char(a) append_i_byte(a) - -#define Print_uchar(s) { \ - if (s<=0x7F) { \ - Print_char(s); \ - } else if (s<=0x7FF) { \ - Print_char(0xC0 + (s / 0x40)); \ - Print_char(0x80 + (s % 0x40)); \ - } else if (s<=0xFFFF) { \ - Print_char(0xE0 + (s / 0x1000)); \ - Print_char(0x80 + ((s % 0x1000) / 0x40)); \ - Print_char(0x80 + ((s % 0x1000) % 0x40)); \ - } else if (s>=0x10FF00) { \ - Print_char(s-0x10FF00); \ - } else { \ - Print_char(0xF0 + (s / 0x40000)); \ - Print_char(0x80 + ((s % 0x40000) / 0x1000)); \ - Print_char(0x80 + (((s % 0x40000) % 0x1000) / 0x40)); \ - Print_char(0x80 + (((s % 0x40000) % 0x1000) % 0x40)); \ - } } - - -#define Print_esc(b) { if (e>0 && e=0xF0))|| \ - ((length(a)==3)&&(str_pool[str_start_macro(a)]>=0xE0))|| \ +#define make_room(a) \ + if ((i+a+1)>alloci) { \ + ret = xrealloc(ret,alloci+64); \ + alloci = alloci + 64; \ + } + + +#define append_i_byte(a) ret[i++] = a + +#define Print_char(a) make_room(1); append_i_byte(a) + +#define Print_uchar(s) { \ + make_room(4); \ + if (s<=0x7F) { \ + append_i_byte(s); \ + } else if (s<=0x7FF) { \ + append_i_byte(0xC0 + (s / 0x40)); \ + append_i_byte(0x80 + (s % 0x40)); \ + } else if (s<=0xFFFF) { \ + append_i_byte(0xE0 + (s / 0x1000)); \ + append_i_byte(0x80 + ((s % 0x1000) / 0x40)); \ + append_i_byte(0x80 + ((s % 0x1000) % 0x40)); \ + } else if (s>=0x110000) { \ + append_i_byte(s-0x11000); \ + } else { \ + append_i_byte(0xF0 + (s / 0x40000)); \ + append_i_byte(0x80 + ((s % 0x40000) / 0x1000)); \ + append_i_byte(0x80 + (((s % 0x40000) % 0x1000) / 0x40)); \ + append_i_byte(0x80 + (((s % 0x40000) % 0x1000) % 0x40)); \ + } } + + +#define Print_esc(b) { \ + char *v = b; \ + if (e>0 && e=0xF0))|| \ + ((length(a)==3)&&(str_pool[str_start_macro(a)]>=0xE0))|| \ ((length(a)==2)&&(str_pool[str_start_macro(a)]>=0xC0)) -#define is_cat_letter(a) \ +#define is_active_cs(a) (length(a)>3 && \ + (str_pool[str_start_macro(a)] == 0xEF) && \ + (str_pool[str_start_macro(a)+1] == 0xBF) && \ + (str_pool[str_start_macro(a)+2] == 0xBF)) + +#define is_cat_letter(a) \ (get_char_cat_code(pool_to_unichar(str_start_macro(a))) == 11) -static int active_base = 0; -static int hash_base = 0; -static int eqtb_size = 0; static int null_cs = 0; -static int undefined_control_sequence; - -char * -tokenlist_to_cstring ( int p , int inhibit_par, int *siz) { - integer m, c ; - integer q; - char *s; - int e; - char *ret=NULL; - int match_chr = '#'; - int n = '0'; - int alloci = 0; - int i = 0; - if (p==null || link(p)==null) { - if (siz!=NULL) - *siz = 0; - return NULL; - } - p = link(p); /* skip refcount */ - if (active_base==0) { - active_base = get_active_base(); - hash_base = get_hash_base(); - null_cs = get_nullcs(); - eqtb_size = get_eqtb_size(); - undefined_control_sequence = get_undefined_control_sequence(); - } - e = get_escape_char(); - while ( p != null ) { - if (p < fix_mem_min || p > fix_mem_end ) { - Print_esc ("CLOBBERED.") ; - break; - } - if (info(p)>=cs_token_flag) { - if ( ! (inhibit_par && info(p)==par_token) ) { - q = info(p) - cs_token_flag; - if (q=undefined_control_sequence)&&((q<=eqtb_size)||(q>eqtb_size+hash_extra))) { - Print_esc("IMPOSSIBLE."); - } else if ((zget_cs_text(q)<0)||(zget_cs_text(q)>=str_ptr)) { - Print_esc("NONEXISTENT."); - } else { - Print_uchar (e); - s = makecstring(zget_cs_text(q)); - while (*s) { Print_char(*s); s++; } - if ((! single_letter(zget_cs_text(q))) || is_cat_letter(zget_cs_text(q))) { - Print_char(' '); - } - } - } - } else { - m=info(p) / string_offset; - c=info(p) % string_offset; - if ( info(p) < 0 ) { - Print_esc ( "BAD.") ; - } else { - switch ( m ) { - case 6 : /* falls through */ - Print_uchar ( c ) ; - case 1 : - case 2 : - case 3 : - case 4 : - case 7 : - case 8 : - case 10 : - case 11 : - case 12 : - Print_uchar ( c ) ; - break ; - case 5 : - Print_uchar ( match_chr ) ; - if ( c <= 9 ) { - Print_char ( c + '0') ; - } else { - Print_char ( '!' ) ; - return NULL; - } - break ; - case 13 : - match_chr = c ; - Print_uchar ( c ) ; - incr ( n ) ; - Print_char ( n ) ; - if ( n > '9' ) - return NULL; - break ; - case 14 : - if ( c == 0 ) { - Print_char ('-'); - Print_char ('>') ; - } - break ; - default: - Print_esc ( "BAD.") ; - break ; - } - } - } - p = link(p); - } - ret[i]=0; - if (siz!=NULL) - *siz = i; - return ret; +static int eqtb_size = 0; + +/* 2,720,652 */ +char *tokenlist_to_cstring(int pp, int inhibit_par, int *siz) +{ + register integer p, c, m; + integer q; + integer infop; + char *s; + int e; + char *ret; + int match_chr = '#'; + int n = '0'; + int alloci = 1024; + int i = 0; + p = pp; + if (p == null || link(p) == null) { + if (siz != NULL) + *siz = 0; + return NULL; + } + ret = xmalloc(alloci); + p = link(p); /* skip refcount */ + if (null_cs == 0) { + null_cs = get_nullcs(); + eqtb_size = get_eqtb_size(); + } + e = get_escape_char(); + while (p != null) { + if (p < fix_mem_min || p > fix_mem_end) { + Print_esc("CLOBBERED."); + break; + } + infop = info(p); + if (infop >= cs_token_flag) { + if (!(inhibit_par && infop == par_token)) { + q = infop - cs_token_flag; + if (q < hash_base) { + if (q == null_cs) { + /* Print_esc("csname"); Print_esc("endcsname"); */ + } + } else if ((q >= static_undefined_control_sequence) + && ((q <= eqtb_size) + || (q > eqtb_size + hash_extra))) { + Print_esc("IMPOSSIBLE."); + } else if ((zget_cs_text(q) < 0) + || (zget_cs_text(q) >= str_ptr)) { + Print_esc("NONEXISTENT."); + } else { + str_number txt = zget_cs_text(q); + s = makecstring(txt); + if (is_active_cs(txt)) { + s = s + 3; + while (*s) { + Print_char(*s); + s++; + } + } else { + Print_uchar(e); + while (*s) { + Print_char(*s); + s++; + } + if ((!single_letter(zget_cs_text(q))) + || is_cat_letter(zget_cs_text(q))) { + Print_char(' '); + } + } + } + } + } else { + if (infop < 0) { + Print_esc("BAD."); + } else { + m = infop >> string_offset_bits; + c = infop & (string_offset - 1); + switch (m) { + case 10: + case 11: + case 12: + case 1: + case 2: + case 3: + case 4: + case 7: + case 8: + Print_uchar(c); + break; + case 6: + /* Print_uchar(c); */ + Print_uchar(c); + break; + case 5: + Print_uchar(match_chr); + if (c <= 9) { + Print_char(c + '0'); + } else { + Print_char('!'); + xfree(ret); + return NULL; + } + break; + case 13: + match_chr = c; + Print_uchar(c); + n++; + Print_char(n); + if (n > '9') { + xfree(ret); + return NULL; + } + break; + case 14: + if (c == 0) { + Print_char('-'); + Print_char('>'); + } + break; + default: + Print_esc("BAD."); + break; + } + } + } + p = link(p); + } + ret[i] = 0; + if (siz != NULL) + *siz = i; + return ret; } -void -tokenlist_to_lua(lua_State *L, int p) { - int cmd,chr,cs; - int v; - int i = 1; - v = p; - while (v!=null && v < fix_mem_end) { i++; v = link(v); } - i = 1; - lua_createtable(L,i,0); - while (p!=null&& p < fix_mem_end) { - if (info(p)>=cs_token_flag) { - cs=info(p)-cs_token_flag; - cmd = zget_eq_type(cs); - chr = zget_equiv(cs); - make_token_table(L,cmd,chr,cs); - } else { - cmd=info(p) / string_offset; - chr=info(p) % string_offset; - make_token_table(L,cmd,chr,0); +void tokenlist_to_lua(lua_State * L, int p) +{ + int cmd, chr, cs; + int v; + int i = 1; + v = p; + while (v != null && v < fix_mem_end) { + i++; + v = link(v); + } + i = 1; + lua_createtable(L, i, 0); + while (p != null && p < fix_mem_end) { + if (info(p) >= cs_token_flag) { + cs = info(p) - cs_token_flag; + cmd = zget_eq_type(cs); + chr = zget_equiv(cs); + make_token_table(L, cmd, chr, cs); + } else { + cmd = info(p) / string_offset; + chr = info(p) % string_offset; + make_token_table(L, cmd, chr, 0); + } + lua_rawseti(L, -2, i++); + p = link(p); } - lua_rawseti(L,-2,i++); - p = link(p); - } } -void -tokenlist_to_luastring(lua_State *L, int p) { - int l; - char *s; - s = tokenlist_to_cstring(p,1,&l); - lua_pushlstring(L,s,l); +void tokenlist_to_luastring(lua_State * L, int p) +{ + int l; + char *s; + s = tokenlist_to_cstring(p, 1, &l); + lua_pushlstring(L, s, l); } -int -tokenlist_from_lua(lua_State *L) { - char *s; - int tok; - size_t i,j; - halfword p,q,r; - r = get_avail(); - info(r)=0; /* ref count */ - link(r)=null; - p = r; - if (lua_istable(L,-1)) { - j = lua_objlen(L,-1); - if (j>0) { - for (i=1;i<=j;i++) { - lua_rawgeti(L,-1,i); - tok = token_from_lua(L); - if (tok>=0) { - store_new_token(tok); - } - lua_pop(L,1); - }; - } - return r; - } else if (lua_isstring(L,-1)) { - s = (char *)lua_tolstring(L,-1,&j); - for (i=0;i 0) { + for (i = 1; i <= j; i++) { + lua_rawgeti(L, -1, i); + tok = token_from_lua(L); + if (tok >= 0) { + store_new_token(tok); + } + lua_pop(L, 1); + }; + } + return r; + } else if (lua_isstring(L, -1)) { + s = (char *) lua_tolstring(L, -1, &j); + for (i = 0; i < j; i++) { + if (s[i] == 32) { + tok = (10 * string_offset) + s[i]; + } else { + tok = (12 * string_offset) + s[i]; + } + store_new_token(tok); + } + return r; + } else { + free_avail(r); + return null; } - return r; - } else { - free_avail(r); - return null; - } } -void -do_get_token_lua (integer callback_id) { - lua_State *L = Luas[0]; - - lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id); - while (1) { - lua_rawgeti(L,-1, callback_id); - if (!lua_isfunction(L,-1)) { - lua_pop(L,2); /* the not-a-function callback and the container */ - get_next(); - return; - } - if (lua_pcall(L,0,1,0) != 0) { /* no arg, 1 result */ - fprintf(stdout,"error: %s\n",lua_tostring(L,-1)); - lua_pop(L,2); - error(); - return; - } - if (lua_istable(L,-1)) { - lua_rawgeti(L,-1,1); - if (lua_istable(L,-1)) { - integer p,q,r; - int i,j; - lua_pop(L,1); - /* build a token list */ - r = get_avail(); - p = r; - j = lua_objlen(L,-1); - if (j>0) { - for (i=1;i<=j;i++) { - lua_rawgeti(L,-1,i); - if (get_cur_cmd(L) || get_cur_cs(L)) { - store_new_token(cur_tok); - } - lua_pop(L,1); - } - } - if (p!=r) { - p = link(r); - free_avail(r); - begin_token_list(p, inserted); - cur_input.nofilter_field=true; - get_next(); - lua_pop(L,1); - break; - } else { - fprintf(stdout,"error: illegal or empty token list returned\n"); - lua_pop(L,2); - error(); - return; - } - } else { - lua_pop(L,1); - if (get_cur_cmd(L) || get_cur_cs(L)) { - lua_pop(L,1); - break; - } else { - lua_pop(L,2); - continue; - } - } - } else { - lua_pop(L,1); - continue; +void do_get_token_lua(integer callback_id) +{ + lua_State *L = Luas; + while (1) { + if (!get_callback(L, callback_id)) { + get_next(); + lua_pop(L, 2); /* the not-a-function callback and the container */ + break; + } + if (lua_pcall(L, 0, 1, 0) != 0) { /* no arg, 1 result */ + tex_error((char *) lua_tostring(L, -1), NULL); + lua_pop(L, 2); /* container and result */ + break; + } + if (lua_istable(L, -1)) { + lua_rawgeti(L, -1, 1); + if (lua_istable(L, -1)) { /* container, result, result[1] */ + integer p, q, r; + int i, j; + lua_pop(L, 1); /* container, result */ + /* build a token list */ + r = get_avail(); + p = r; + j = lua_objlen(L, -1); + if (j > 0) { + for (i = 1; i <= j; i++) { + lua_rawgeti(L, -1, i); + if (get_cur_cmd(L) || get_cur_cs(L)) { + store_new_token(cur_tok); + } + lua_pop(L, 1); + } + } + if (p != r) { + p = link(r); + free_avail(r); + begin_token_list(p, inserted); + cur_input.nofilter_field = true; + get_next(); + } else { + tex_error("error: illegal or empty token list returned", + NULL); + } + lua_pop(L, 2); + break; + } else { /* container, result, whatever */ + lua_pop(L, 1); /* container, result */ + if (get_cur_cmd(L) || get_cur_cs(L)) { + lua_pop(L, 2); + break; + } else { + lua_pop(L, 2); + continue; + } + } + } else { + lua_pop(L, 2); /* container, result */ + } } - } - lua_pop(L,1); /* callback container */ - return; + return; } - diff --git a/Build/source/texk/web2c/luatexdir/lua/mp.w b/Build/source/texk/web2c/luatexdir/lua/mp.w deleted file mode 100644 index 4894a54e9aa..00000000000 --- a/Build/source/texk/web2c/luatexdir/lua/mp.w +++ /dev/null @@ -1,26202 +0,0 @@ -% $Id: mp.web,v 1.8 2005/08/24 10:54:02 taco Exp $ -% MetaPost, by John Hobby. Public domain. - -% Much of this program was copied with permission from MF.web Version 1.9 -% It interprets a language very similar to D.E. Knuth's METAFONT, but with -% changes designed to make it more suitable for PostScript output. - -% TeX is a trademark of the American Mathematical Society. -% METAFONT is a trademark of Addison-Wesley Publishing Company. -% PostScript is a trademark of Adobe Systems Incorporated. - -% Here is TeX material that gets inserted after \input webmac -\def\hang{\hangindent 3em\noindent\ignorespaces} -\def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces} -\def\ps{PostScript} -\def\psqrt#1{\sqrt{\mathstrut#1}} -\def\k{_{k+1}} -\def\pct!{{\char`\%}} % percent sign in ordinary text -\font\tenlogo=logo10 % font used for the METAFONT logo -\font\logos=logosl10 -\def\MF{{\tenlogo META}\-{\tenlogo FONT}} -\def\MP{{\tenlogo META}\-{\tenlogo POST}} -\def\[#1]{\ignorespaces} % left over from pascal web -\def\<#1>{$\langle#1\rangle$} -\def\section{\mathhexbox278} -\let\swap=\leftrightarrow -\def\round{\mathop{\rm round}\nolimits} -\mathchardef\vb="026A % synonym for `\|' - -\def\(#1){} % this is used to make section names sort themselves better -\def\9#1{} % this is used for sort keys in the index via @@:sort key}{entry@@> -\def\title{MetaPost} -\pdfoutput=1 -\pageno=3 - -@* \[1] Introduction. - -This is \MP, a graphics-language processor based on D. E. Knuth's \MF. - -The main purpose of the following program is to explain the algorithms of \MP\ -as clearly as possible. However, the program has been written so that it -can be tuned to run efficiently in a wide variety of operating environments -by making comparatively few changes. Such flexibility is possible because -the documentation that follows is written in the \.{WEB} language, which is -at a higher level than C. - -A large piece of software like \MP\ has inherent complexity that cannot -be reduced below a certain level of difficulty, although each individual -part is fairly simple by itself. The \.{WEB} language is intended to make -the algorithms as readable as possible, by reflecting the way the -individual program pieces fit together and by providing the -cross-references that connect different parts. Detailed comments about -what is going on, and about why things were done in certain ways, have -been liberally sprinkled throughout the program. These comments explain -features of the implementation, but they rarely attempt to explain the -\MP\ language itself, since the reader is supposed to be familiar with -{\sl The {\logos METAFONT\/}book} as well as the manual -@.WEB@> -@:METAFONTbook}{\sl The {\logos METAFONT\/}book@> -{\sl A User's Manual for MetaPost}, Computing Science Technical Report 162, -AT\AM T Bell Laboratories. - -@ The present implementation is a preliminary version, but the possibilities -for new features are limited by the desire to remain as nearly compatible -with \MF\ as possible. - -On the other hand, the \.{WEB} description can be extended without changing -the core of the program, and it has been designed so that such -extensions are not extremely difficult to make. -The |banner| string defined here should be changed whenever \MP\ -undergoes any modifications, so that it will be clear which version of -\MP\ might be the guilty party when a problem arises. -@^extensions to \MP@> -@^system dependencies@> - -@d banner "This is MetaPost, Version 1.003" /* printed when \MP\ starts */ -@d metapost_version "1.003" -@d mplib_version "0.40" -@d version_string " (Cweb version 0.40)" - -@d true 1 -@d false 0 - -@ The external library header for \MP\ is |mplib.h|. It contains a -few typedefs and the header defintions for the externally used -fuctions. - -The most important of the typedefs is the definition of the structure -|MP_options|, that acts as a small, configurable front-end to the fairly -large |MP_instance| structure. - -@(mplib.h@>= -typedef struct MP_instance * MP; -@ -typedef struct MP_options { - @
+ + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+ +
+ + + + +

DNS

+ +

+Name resolution functions return all information obtained from the +resolver in a table of the form: +

+ +
+resolved = {
+  name = canonic-name,
+  alias = alias-list,
+  ip = ip-address-list
+} +
+ +

+Note that the alias list can be empty. +

+ + + +

+socket.dns.gethostname() +

+ +

+Returns the standard host name for the machine as a string. +

+ + + +

+socket.dns.tohostname(address) +

+ +

+Converts from IP address to host name. +

+ +

+Address can be an IP address or host name. +

+ +

+The function returns a string with the canonic host name of the given +address, followed by a table with all information returned by +the resolver. In case of error, the function returns nil +followed by an error message. +

+ + + +

+socket.dns.toip(address) +

+ +

+Converts from host name to IP address. +

+ +

+Address can be an IP address or host name. +

+ +

+Returns a string with the first IP address found for address, +followed by a table with all information returned by the resolver. +In case of error, the function returns nil followed by an error +message. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/ftp.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/ftp.html new file mode 100644 index 00000000000..9884f31339d --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/ftp.html @@ -0,0 +1,289 @@ + + + + + + +LuaSocket: FTP support + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

FTP

+ +

+FTP (File Transfer Protocol) is a protocol used to transfer files +between hosts. The ftp namespace offers thorough support +to FTP, under a simple interface. The implementation conforms to +RFC 959. +

+ +

+High level functions are provided supporting the most common operations. +These high level functions are implemented on top of a lower level +interface. Using the low-level interface, users can easily create their +own functions to access any operation supported by the FTP +protocol. For that, check the implementation. +

+ +

+To really benefit from this module, a good understanding of + +LTN012, Filters sources and sinks is necessary. +

+ +

+To obtain the ftp namespace, run: +

+ +
+-- loads the FTP module and any libraries it requires
+local ftp = require("socket.ftp")
+
+ +

+URLs MUST conform to +RFC +1738, that is, an URL is a string in the form: +

+ +
+ +[ftp://][<user>[:<password>]@]<host>[:<port>][/<path>][type=a|i] +
+ +

+The following constants in the namespace can be set to control the default behavior of +the FTP module: +

+ +
    +
  • PASSWORD: default anonymous password. +
  • PORT: default port used for the control connection; +
  • TIMEOUT: sets the timeout for all I/O operations; +
  • USER: default anonymous user; +
+ + + + +

+ftp.get(url)
+ftp.get{
+  host = string,
+  sink = LTN12 sink,
+  argument or path = string,
+  [user = string,]
+  [password = string]
+  [command = string,]
+  [port = number,]
+  [type = string,]
+  [step = LTN12 pump step,]
+  [create = function]
+} +

+ +

+The get function has two forms. The simple form has fixed +functionality: it downloads the contents of a URL and returns it as a +string. The generic form allows a lot more control, as explained +below. +

+ +

+If the argument of the get function is a table, the function +expects at least the fields host, sink, and one of +argument or path (argument takes +precedence). Host is the server to connect to. Sink is +the simple +LTN12 +sink that will receive the downloaded data. Argument or +path give the target path to the resource in the server. The +optional arguments are the following: +

+
    +
  • user, password: User name and password used for +authentication. Defaults to "ftp:anonymous@anonymous.org"; +
  • command: The FTP command used to obtain data. Defaults to +"retr", but see example below; +
  • port: The port to used for the control connection. Defaults to 21; +
  • type: The transfer mode. Can take values "i" or +"a". Defaults to whatever is the server default; +
  • step: +LTN12 +pump step function used to pass data from the +server to the sink. Defaults to the LTN12 pump.step function; +
  • create: An optional function to be used instead of +socket.tcp when the communications socket is created. +
+ +

+If successful, the simple version returns the URL contents as a +string, and the generic function returns 1. In case of error, both +functions return nil and an error message describing the +error. +

+ +
+-- load the ftp support
+local ftp = require("socket.ftp")
+
+-- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br",
+-- and get file "lua.tar.gz" from directory "pub/lua" as binary.
+f, e = ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz;type=i")
+
+ +
+-- load needed modules
+local ftp = require("socket.ftp")
+local ltn12 = require("ltn12")
+local url = require("socket.url")
+
+-- a function that returns a directory listing
+function nlst(u)
+    local t = {}
+    local p = url.parse(u)
+    p.command = "nlst"
+    p.sink = ltn12.sink.table(t)
+    local r, e = ftp.get(p)
+    return r and table.concat(t), e
+end
+
+ + + +

+ftp.put(url, content)
+ftp.put{
+  host = string,
+  source = LTN12 sink,
+  argument or path = string,
+  [user = string,]
+  [password = string]
+  [command = string,]
+  [port = number,]
+  [type = string,]
+  [step = LTN12 pump step,]
+  [create = function]
+} +

+ +

+The put function has two forms. The simple form has fixed +functionality: it uploads a string of content into a URL. The generic form +allows a lot more control, as explained below. +

+ +

+If the argument of the put function is a table, the function +expects at least the fields host, source, and one of +argument or path (argument takes +precedence). Host is the server to connect to. Source is +the simple +LTN12 +source that will provide the contents to be uploaded. +Argument or +path give the target path to the resource in the server. The +optional arguments are the following: +

+
    +
  • user, password: User name and password used for +authentication. Defaults to "ftp:anonymous@anonymous.org"; +
  • command: The FTP command used to send data. Defaults to +"stor", but see example below; +
  • port: The port to used for the control connection. Defaults to 21; +
  • type: The transfer mode. Can take values "i" or +"a". Defaults to whatever is the server default; +
  • step: +LTN12 +pump step function used to pass data from the +server to the sink. Defaults to the LTN12 pump.step function; +
  • create: An optional function to be used instead of +socket.tcp when the communications socket is created. +
+ +

+Both functions return 1 if successful, or nil and an error +message describing the reason for failure. +

+ +
+-- load the ftp support
+local ftp = require("socket.ftp")
+
+-- Log as user "fulano" on server "ftp.example.com",
+-- using password "silva", and store a file "README" with contents 
+-- "wrong password, of course"
+f, e = ftp.put("ftp://fulano:silva@ftp.example.com/README", 
+    "wrong password, of course")
+
+ +
+-- load the ftp support
+local ftp = require("socket.ftp")
+local ltn12 = require("ltn12")
+
+-- Log as user "fulano" on server "ftp.example.com",
+-- using password "silva", and append to the remote file "LOG", sending the
+-- contents of the local file "LOCAL-LOG"
+f, e = ftp.put{
+  host = "ftp.example.com", 
+  user = "fulano",
+  password = "silva",
+  command = "appe",
+  argument = "LOG",
+  source = ltn12.source.file(io.open("LOCAL-LOG", "r"))
+}
+
+ + + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/http.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/http.html new file mode 100644 index 00000000000..0acac13feec --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/http.html @@ -0,0 +1,333 @@ + + + + + + +LuaSocket: HTTP support + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +introduction · +introduction · +reference +

+
+
+
+ + + +

HTTP

+ +

+HTTP (Hyper Text Transfer Protocol) is the protocol used to exchange +information between web-browsers and servers. The http +namespace offers full support for the client side of the HTTP +protocol (i.e., +the facilities that would be used by a web-browser implementation). The +implementation conforms to the HTTP/1.1 standard, +RFC +2616. +

+ +

+The module exports functions that provide HTTP functionality in different +levels of abstraction. From the simple +string oriented requests, through generic +LTN12 based, down to even lower-level if you bother to look through the source code. +

+ +

+To obtain the http namespace, run: +

+ +
+-- loads the HTTP module and any libraries it requires
+local http = require("socket.http")
+
+ +

+URLs must conform to +RFC +1738, +that is, an URL is a string in the form: +

+ +
+
+[http://][<user>[:<password>]@]<host>[:<port>][/<path>] 
+
+
+ +

+MIME headers are represented as a Lua table in the form: +

+ +
+ + +
+headers = {
+  field-1-name = field-1-value,
+  field-2-name = field-2-value,
+  field-3-name = field-3-value,
+  ...
+  field-n-name = field-n-value
+} +
+
+ +

+Field names are case insensitive (as specified by the standard) and all +functions work with lowercase field names. +Field values are left unmodified. +

+ +

+Note: MIME headers are independent of order. Therefore, there is no problem +in representing them in a Lua table. +

+ +

+The following constants can be set to control the default behavior of +the HTTP module: +

+ +
    +
  • PORT: default port used for connections; +
  • PROXY: default proxy used for connections; +
  • TIMEOUT: sets the timeout for all I/O operations; +
  • USERAGENT: default user agent reported to server. +
+ + + +

+http.request(url [, body])
+http.request{
+  url = string,
+  [sink = LTN12 sink,]
+  [method = string,]
+  [headers = header-table,]
+  [source = LTN12 source],
+  [step = LTN12 pump step,]
+  [proxy = string,]
+  [redirect = boolean,]
+  [create = function]
+} +

+ +

+The request function has two forms. The simple form downloads +a URL using the GET or POST method and is based +on strings. The generic form performs any HTTP method and is +LTN12 based. +

+ +

+If the first argument of the request function is a string, it +should be an url. In that case, if a body +is provided as a string, the function will perform a POST method +in the url. Otherwise, it performs a GET in the +url +

+ +

+If the first argument is instead a table, the most important fields are +the url and the simple +LTN12 +sink that will receive the downloaded content. +Any part of the url can be overridden by including +the appropriate field in the request table. +If authentication information is provided, the function +uses the Basic Authentication Scheme (see note) +to retrieve the document. If sink is nil, the +function discards the downloaded data. The optional parameters are the +following: +

+
    +
  • method: The HTTP request method. Defaults to "GET"; +
  • headers: Any additional HTTP headers to send with the request; +
  • source: simple +LTN12 +source to provide the request body. If there +is a body, you need to provide an appropriate "content-length" +request header field, or the function will attempt to send the body as +"chunked" (something few servers support). Defaults to the empty source; +
  • step: +LTN12 +pump step function used to move data. +Defaults to the LTN12 pump.step function. +
  • proxy: The URL of a proxy server to use. Defaults to no proxy; +
  • redirect: Set to false to prevent the +function from automatically following 301 or 302 server redirect messages; +
  • create: An optional function to be used instead of +socket.tcp when the communications socket is created. +
+ +

+In case of failure, the function returns nil followed by an +error message. If successful, the simple form returns the response +body as a string, followed by the response status code, the response +headers and the response status line. The generic function returns the same +information, except the first return value is just the number 1 (the body +goes to the sink). +

+ +

+Even when the server fails to provide the contents of the requested URL (URL not found, for example), +it usually returns a message body (a web page informing the +URL was not found or some other useless page). To make sure the +operation was successful, check the returned status code. For +a list of the possible values and their meanings, refer to RFC +2616. +

+ +

+Here are a few examples with the simple interface: +

+ +
+-- load the http module
+local io = require("io")
+local http = require("socket.http")
+local ltn12 = require("ltn12")
+
+-- connect to server "www.cs.princeton.edu" and retrieves this manual
+-- file from "~diego/professional/luasocket/http.html" and print it to stdout
+http.request{ 
+    url = "http://www.cs.princeton.edu/~diego/professional/luasocket/http.html", 
+    sink = ltn12.sink.file(io.stdout)
+}
+
+-- connect to server "www.example.com" and tries to retrieve
+-- "/private/index.html". Fails because authentication is needed.
+b, c, h = http.request("http://www.example.com/private/index.html")
+-- b returns some useless page telling about the denied access, 
+-- h returns authentication information
+-- and c returns with value 401 (Authentication Required)
+
+-- tries to connect to server "wrong.host" to retrieve "/"
+-- and fails because the host does not exist.
+r, e = http.request("http://wrong.host/")
+-- r is nil, and e returns with value "host not found"
+
+ +

+And here is an example using the generic interface: +

+ +
+-- load the http module
+http = require("socket.http")
+
+-- Requests information about a document, without downloading it.
+-- Useful, for example, if you want to display a download gauge and need
+-- to know the size of the document in advance
+r, c, h = http.request {
+  method = "HEAD",
+  url = "http://www.tecgraf.puc-rio.br/~diego"
+}
+-- r is 1, c is 200, and h would return the following headers:
+-- h = {
+--   date = "Tue, 18 Sep 2001 20:42:21 GMT",
+--   server = "Apache/1.3.12 (Unix)  (Red Hat/Linux)",
+--   ["last-modified"] = "Wed, 05 Sep 2001 06:11:20 GMT",
+--   ["content-length"] = 15652,
+--   ["connection"] = "close",
+--   ["content-Type"] = "text/html"
+-- }
+
+ +

+Note: When sending a POST request, simple interface adds a +"Content-type: application/x-www-form-urlencoded" +header to the request. This is the type used by +HTML forms. If you need another type, use the generic +interface. +

+ +

+Note: Some URLs are protected by their +servers from anonymous download. For those URLs, the server must receive +some sort of authentication along with the request or it will deny +download and return status "401 Authentication Required". +

+ +

+The HTTP/1.1 standard defines two authentication methods: the Basic +Authentication Scheme and the Digest Authentication Scheme, both +explained in detail in +RFC 2068. +

+ +

The Basic Authentication Scheme sends +<user> and +<password> unencrypted to the server and is therefore +considered unsafe. Unfortunately, by the time of this implementation, +the wide majority of servers and browsers support the Basic Scheme only. +Therefore, this is the method used by the toolkit whenever +authentication is required. +

+ +
+-- load required modules
+http = require("socket.http")
+mime = require("mime")
+
+-- Connect to server "www.example.com" and tries to retrieve
+-- "/private/index.html", using the provided name and password to
+-- authenticate the request
+b, c, h = http.request("http://fulano:silva@www.example.com/private/index.html")
+
+-- Alternatively, one could fill the appropriate header and authenticate
+-- the request directly.
+r, c = http.request {
+  url = "http://www.example.com/private/index.html",
+  headers = { authentication = "Basic " .. (mime.b64("fulano:silva")) }
+}
+
+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/index.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/index.html new file mode 100644 index 00000000000..57a790714ac --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/index.html @@ -0,0 +1,208 @@ + + + + + + +LuaSocket: Network support for the Lua language + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

What is LuaSocket?

+ +

+LuaSocket is a Lua extension library +that is composed by two parts: a C core that provides support for the TCP +and UDP transport layers, and a set of Lua modules that add support for +functionality commonly needed by applications that deal with the Internet. +

+ +

+The core support has been implemented so that it is both efficient and +simple to use. It is available to any Lua application once it has been +properly initialized by the interpreter in use. The code has been tested +and runs well on several Windows and Unix platforms.

+ +

+Among the support modules, the most commonly used implement the +SMTP +(sending e-mails), +HTTP +(WWW access) and +FTP +(uploading and downloading files) client +protocols. These provide a very natural and generic interface to the +functionality defined by each protocol. +In addition, you will find that the +MIME (common encodings), +URL +(anything you could possible want to do with one) and +LTN12 +(filters, sinks, sources and pumps) modules can be very handy. +

+ +

+The library is available under the same + +terms and conditions as the Lua language, the MIT license. The idea is +that if you can use Lua in a project, you should also be able to use +LuaSocket. +

+ +

+Copyright © 2004-2007 Diego Nehab. All rights reserved.
+Author: Diego Nehab +

+ + + +

Download

+ +

+LuaSocket version 2.0.2 is now available for download! It is +compatible with Lua 5.1, and has +been tested on Windows XP, Linux, and Mac OS X. Chances +are it works well on most UNIX distributions and Windows flavors. +

+ +

+The library can be downloaded in source code from the +LuaSocket +project page at LuaForge. +Besides the full C and Lua source code for the library, the distribution +contains several examples, this user's manual and basic test procedures. +

+ +

+Danilo Tuler is maintaining Win32 binaries for LuaSocket, which are also +available from LuaForge. These are compatible with the +LuaBinaries, +also available from LuaForge. +

+ +

Take a look at the installation section of the +manual to find out how to properly install the library. +

+ + + +

Special thanks

+ +

+Throughout LuaSocket's history, many people gave suggestions that helped +improve it. For that, I thank the Lua community. +Special thanks go to +David Burgess, who has helped push the library to a new level of quality and +from whom I have learned a lot of stuff that doesn't show up in RFCs. +Special thanks also to Carlos Cassino, who played a big part in the +extensible design seen in the C core of LuaSocket 2.0. Mike Pall +has been helping a lot too! Thanks to you all! +

+ + + +

What's New

+ +

+2.0.2 is just a bug-fix/update release. +

+ +
    +
  • Improved: http.request() now supports deprecated +HTTP/0.9 servers (Florian Berger); +
  • Fixed: could return "timedout" instead of "timeout" (Leo Leo); +
  • Fixed: crash when reading '*a' on closed socket (Paul Ducklin); +
  • Fixed: return values are consistent when reading from closed sockets; +
  • Fixed: case sensitivity in headers of multipart +messages in smtp.message() (Graham Henstridge); +
  • Fixed a couple instances of error() being called instead of +base.error(). These would cause an error when an error was +reported :) (Ketmar Dark); +
  • Fixed: test script now uses pairs() iterator instead +of the old Lua syntax (Robert Dodier). +
+ +

+2.0.1 is just a bug-fix/update release. +

+ +
    +
  • Updated: now using compat-5.1r5; +
  • Improved: http.request is more robust to +malformed URLs (Adrian Sietsma); +
  • Improved: the simple http.request interface sends a +"Content-type: application/x-www-form-urlencoded" +header (William Trenker); +
  • Improved: http.request is robust to evil +servers that send inappropriate 100-continue messages +(David Burgess); +
  • Fixed: http.request was using the old host header during +redirects (Florian Berger); +
  • Fixed: sample unix.c had fallen through the +cracks during development (Matthew Percival); +
  • Fixed: error code was not being propagated correctly in +ftp.lua (David Burgess). +
+ + + +

Old Versions

+ +

+All previous versions of the LuaSocket library can be downloaded +here. Although these versions are no longer supported, they are +still available for those that have compatibility issues. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/installation.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/installation.html new file mode 100644 index 00000000000..0288f4af31a --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/installation.html @@ -0,0 +1,163 @@ + + + + + + +LuaSocket: Installation + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

Installation

+ +

LuaSocket 2.0.2 uses the new package system for Lua 5.1. +All Lua library developers are encouraged to update their libraries so that +all libraries can coexist peacefully and users can benefit from the +standardization and flexibility of the standard. +

+ +

+Those stuck with Lua 5.0 will need the +compat-5.1 +module. It is maintained by +The Kepler +Project's team, and implements the Lua 5.1 package proposal +on top of Lua 5.0.

+ +

Here we will only describe the standard distribution. +If the standard doesn't meet your needs, we refer you to the +Lua discussion list, where any question about the package +scheme will likely already have been answered.

+ +

Directory structure

+ +

On Unix systems, the standard distribution uses two base +directories, one for system dependent files, and another for system +independent files. Let's call these directories <CDIR> +and <LDIR>, respectively. +For instance, in my laptop, I use '/usr/local/lib/lua/5.0' for +<CDIR> and '/usr/local/share/lua/5.0' for +<LDIR>. On Windows, sometimes only one directory is used, say +'c:\program files\lua\5.0'. Here is the standard LuaSocket +distribution directory structure:

+ +
+<LDIR>/compat-5.1.lua
+<LDIR>/ltn12.lua
+<LDIR>/socket.lua
+<CDIR>/socket/core.dll
+<LDIR>/socket/http.lua
+<LDIR>/socket/tp.lua
+<LDIR>/socket/ftp.lua
+<LDIR>/socket/smtp.lua
+<LDIR>/socket/url.lua
+<LDIR>/mime.lua
+<CDIR>/mime/core.dll
+
+ +

Naturally, on Unix systems, core.dll +would be replaced by core.so. +

+ +

In order for the interpreter to find all LuaSocket components, three +environment variables need to be set. The first environment variable tells +the interpreter to load the compat-5.1.lua module at startup:

+ +
+LUA_INIT=@<LDIR>/compat-5.1.lua
+
+ +

+This is only need for Lua 5.0! Lua 5.1 comes with +the package system built in, of course. +

+ +

+The other two environment variables instruct the compatibility module to +look for dynamic libraries and extension modules in the appropriate +directories and with the appropriate filename extensions. +

+ +
+LUA_PATH=<LDIR>/?.lua;?.lua
+LUA_CPATH=<CDIR>/?.dll;?.dll
+
+ +

Again, naturally, on Unix systems the shared library extension would be +.so instead of .dll.

+ +

Using LuaSocket

+ +

With the above setup, and an interpreter with shared library support, +it should be easy to use LuaSocket. Just fire the interpreter and use the +require function to gain access to whatever module you need:

+ +
+Lua 5.1.2  Copyright (C) 1994-2007 Lua.org, PUC-Rio
+> socket = require("socket")
+> print(socket._VERSION)
+--> LuaSocket 2.0.2
+
+ +

Each module loads their dependencies automatically, so you only need to +load the modules you directly depend upon:

+ +
+Lua 5.1.2  Copyright (C) 1994-2007 Lua.org, PUC-Rio
+> http = require("socket.http")
+> print(http.request("http://www.cs.princeton.edu/~diego/professional/luasocket"))
+--> homepage gets dumped to terminal
+
+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/introduction.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/introduction.html new file mode 100644 index 00000000000..eff63676750 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/introduction.html @@ -0,0 +1,333 @@ + + + + + + +LuaSocket: Introduction to the core + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

Introduction

+ +

+LuaSocket is a Lua extension library +that is composed by two parts: a C core that provides support for the TCP +and UDP transport layers, and a set of Lua modules that add support for +the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and +downloading files) protocols and other functionality commonly needed by +applications that deal with the Internet. This introduction is about the C +core. +

+ +

+Communication in LuaSocket is performed via I/O objects. These can +represent different network domains. Currently, support is provided for TCP +and UDP, but nothing prevents other developers from implementing SSL, Local +Domain, Pipes, File Descriptors etc. I/O objects provide a standard +interface to I/O across different domains and operating systems. +

+ +

+The API design had two goals in mind. First, users +experienced with the C API to sockets should feel comfortable using LuaSocket. +Second, the simplicity and the feel of the Lua language should be +preserved. To achieve these goals, the LuaSocket API keeps the function names and semantics the C API whenever possible, but their usage in Lua has been greatly simplified. +

+ + +

+One of the simplifications is the receive pattern capability. +Applications can read data from stream domains (such as TCP) +line by line, block by block, or until the connection is closed. +All I/O reads are buffered and the performance differences between +different receive patterns are negligible. +

+ +

+Another advantage is the flexible timeout control +mechanism. As in C, all I/O operations are blocking by default. For +example, the send, +receive and +accept methods +of the TCP domain will block the caller application until +the operation is completed (if ever!). However, with a call to the +settimeout +method, an application can specify upper limits on +the time it can be blocked by LuaSocket (the "total" timeout), on +the time LuaSocket can internally be blocked by any OS call (the +"block" timeout) or a combination of the two. Each LuaSocket +call might perform several OS calls, so that the two timeout values are +not equivalent. +

+ +

+Finally, the host name resolution is transparent, meaning that most +functions and methods accept both IP addresses and host names. In case a +host name is given, the library queries the system's resolver and +tries the main IP address returned. Note that direct use of IP addresses +is more efficient, of course. The +toip +and tohostname +functions from the DNS module are provided to convert between host names and IP addresses. +

+ +

+Together, these changes make network programming in LuaSocket much simpler +than it is in C, as the following sections will show. +

+ + + +

TCP

+ +

+TCP (Transfer Control Protocol) is reliable stream protocol. In other +words, applications communicating through TCP can send and receive data as +an error free stream of bytes. Data is split in one end and +reassembled transparently on the other end. There are no boundaries in +the data transfers. The library allows users to read data from the +sockets in several different granularities: patterns are available for +lines, arbitrary sized blocks or "read up to connection closed", all with +good performance. +

+ +

+The library distinguishes three types of TCP sockets: master, +client and server sockets. +

+ +

+Master sockets are newly created TCP sockets returned by the function +socket.tcp. A master socket is +transformed into a server socket +after it is associated with a local address by a call to the +bind method followed by a call to the +listen. Conversely, a master socket +can be changed into a client socket with the method +connect, +which associates it with a remote address. +

+ +

+On server sockets, applications can use the +accept method +to wait for a client connection. Once a connection is established, a +client socket object is returned representing this connection. The +other methods available for server socket objects are +getsockname, +setoption, +settimeout, and +close. +

+ +

+Client sockets are used to exchange data between two applications over +the Internet. Applications can call the methods +send and +receive +to send and receive data. The other methods +available for client socket objects are +getsockname, +getpeername, +setoption, +settimeout, +shutdown, and +close. +

+ +

+Example: +

+
+

+A simple echo server, using LuaSocket. The program binds to an ephemeral +port (one that is chosen by the operating system) on the local host and +awaits client connections on that port. When a connection is established, +the program reads a line from the remote end and sends it back, closing +the connection immediately. You can test it using the telnet +program. +

+ +
+-- load namespace
+local socket = require("socket")
+-- create a TCP socket and bind it to the local host, at any port
+local server = assert(socket.bind("*", 0))
+-- find out which port the OS chose for us
+local ip, port = server:getsockname()
+-- print a message informing what's up
+print("Please telnet to localhost on port " .. port)
+print("After connecting, you have 10s to enter a line to be echoed")
+-- loop forever waiting for clients
+while 1 do
+  -- wait for a connection from any client
+  local client = server:accept()
+  -- make sure we don't block waiting for this client's line
+  client:settimeout(10)
+  -- receive the line
+  local line, err = client:receive()
+  -- if there was no error, send it back to the client
+  if not err then client:send(line .. "\n") end
+  -- done with client, close the object
+  client:close()
+end
+
+
+ + + +

UDP

+ +

+UDP (User Datagram Protocol) is a non-reliable datagram protocol. In +other words, applications communicating through UDP send and receive +data as independent blocks, which are not guaranteed to reach the other +end. Even when they do reach the other end, they are not guaranteed to be +error free. Data transfers are atomic, one datagram at a time. Reading +only part of a datagram discards the rest, so that the following read +operation will act on the next datagram. The advantages are in +simplicity (no connection setup) and performance (no error checking or +error correction). +

+ +

+Note that although no guarantees are made, these days +networks are so good that, under normal circumstances, few errors +happen in practice. +

+ +

+An UDP socket object is created by the +socket.udp function. UDP +sockets do not need to be connected before use. The method +sendto +can be used immediately after creation to +send a datagram to IP address and port. Host names are not allowed +because performing name resolution for each packet would be forbiddingly +slow. Methods +receive and +receivefrom +can be used to retrieve datagrams, the latter returning the IP and port of +the sender as extra return values (thus being slightly less +efficient). +

+ +

+When communication is performed repeatedly with a single peer, an +application should call the +setpeername method to specify a +permanent partner. Methods +sendto and +receivefrom +can no longer be used, but the method +send can be used to send data +directly to the peer, and the method +receive +will only return datagrams originating +from that peer. There is about 30% performance gain due to this practice. +

+ +

+To associate an UDP socket with a local address, an application calls the +setsockname +method before sending any datagrams. Otherwise, the socket is +automatically bound to an ephemeral address before the first data +transmission and once bound the local address cannot be changed. +The other methods available for UDP sockets are +getpeername, +getsockname, +settimeout, +setoption and +close. +

+ +

+Example: +

+
+

+A simple daytime client, using LuaSocket. The program connects to a remote +server and tries to retrieve the daytime, printing the answer it got or an +error message. +

+ +
+-- change here to the host an port you want to contact
+local host, port = "localhost", 13
+-- load namespace
+local socket = require("socket")
+-- convert host name to ip address
+local ip = assert(socket.dns.toip(host))
+-- create a new UDP object
+local udp = assert(socket.udp())
+-- contact daytime host
+assert(udp:sendto("anything", ip, port))
+-- retrieve the answer and print results
+io.write(assert(udp:receive()))
+
+
+ + + +

Support modules

+ +

Although not covered in the introduction, LuaSocket offers +much more than TCP and UDP functionality. As the library +evolved, support for HTTP, FTP, +and SMTP were built on top of these. These modules +and many others are covered by the reference manual. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/ltn12.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/ltn12.html new file mode 100644 index 00000000000..001395030af --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/ltn12.html @@ -0,0 +1,430 @@ + + + + + + +LuaSocket: LTN12 module + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

LTN12

+ +

The ltn12 namespace implements the ideas described in + +LTN012, Filters sources and sinks. This manual simply describes the +functions. Please refer to the LTN for a deeper explanation of the +functionality provided by this module. +

+ +

+To obtain the ltn12 namespace, run: +

+ +
+-- loads the LTN21 module
+local ltn12 = require("ltn12")
+
+ + + +

Filters

+ + + +

+ltn12.filter.chain(filter1, filter2 +[, ... filterN]) +

+ +

+Returns a filter that passes all data it receives through each of a +series of given filters. +

+ +

+Filter1 to filterN are simple +filters. +

+ +

+The function returns the chained filter. +

+ +

+The nesting of filters can be arbitrary. For instance, the useless filter +below doesn't do anything but return the data that was passed to it, +unaltered. +

+ +
+-- load required modules
+local ltn12 = require("ltn12")
+local mime = require("mime")
+
+-- create a silly identity filter
+id = ltn12.filter.chain(
+  mime.encode("quoted-printable"),
+  mime.encode("base64"),
+  mime.decode("base64"),
+  mime.decode("quoted-printable")
+)
+
+ + + +

+ltn12.filter.cycle(low [, ctx, extra]) +

+ +

+Returns a high-level filter that cycles though a low-level filter by +passing it each chunk and updating a context between calls. +

+ +

+Low is the low-level filter to be cycled, +ctx is the initial context and extra is any extra +argument the low-level filter might take. +

+ +

+The function returns the high-level filter. +

+ +
+-- load the ltn12 module
+local ltn12 = require("ltn12")
+
+-- the base64 mime filter factory
+encodet['base64'] = function()
+    return ltn12.filter.cycle(b64, "")
+end
+
+ + + +

Pumps

+ + + +

+ltn12.pump.all(source, sink) +

+ +

+Pumps all data from a source to a sink. +

+ +

+If successful, the function returns a value that evaluates to +true. In case +of error, the function returns a false value, followed by an error message. +

+ + + +

+ltn12.pump.step(source, sink) +

+ +

+Pumps one chunk of data from a source to a sink. +

+ +

+If successful, the function returns a value that evaluates to +true. In case +of error, the function returns a false value, followed by an error message. +

+ + + +

Sinks

+ + + +

+ltn12.sink.chain(filter, sink) +

+ +

+Creates and returns a new sink that passes data through a filter before sending it to a given sink. +

+ + + +

+ltn12.sink.error(message) +

+ +

+Creates and returns a sink that aborts transmission with the error +message. +

+ + + +

+ltn12.sink.file(handle, message) +

+ +

+Creates a sink that sends data to a file. +

+ +

+Handle is a file handle. If handle is nil, +message should give the reason for failure. +

+ +

+The function returns a sink that sends all data to the given handle +and closes the file when done, or a sink that aborts the transmission with +the error message +

+ +

+In the following example, notice how the prototype is designed to +fit nicely with the io.open function. +

+ +
+-- load the ltn12 module
+local ltn12 = require("ltn12")
+
+-- copy a file
+ltn12.pump.all(
+  ltn12.source.file(io.open("original.png")),
+  ltn12.sink.file(io.open("copy.png"))
+)
+
+ + + +

+ltn12.sink.null() +

+ +

+Returns a sink that ignores all data it receives. +

+ + + +

+ltn12.sink.simplify(sink) +

+ +

+Creates and returns a simple sink given a fancy sink. +

+ + + +

+ltn12.sink.table([table]) +

+ +

+Creates a sink that stores all chunks in a table. The chunks can later be +efficiently concatenated into a single string. +

+ +

+Table is used to hold the chunks. If +nil, the function creates its own table. +

+ +

+The function returns the sink and the table used to store the chunks. +

+ +
+-- load needed modules
+local http = require("socket.http")
+local ltn12 = require("ltn12")
+
+-- a simplified http.get function
+function http.get(u)
+  local t = {}
+  local respt = request{
+    url = u,
+    sink = ltn12.sink.table(t)
+  }
+  return table.concat(t), respt.headers, respt.code
+end
+
+ + + +

Sources

+ + + +

+ltn12.source.cat(source1 [, source2, ..., +sourceN]) +

+ +

+Creates a new source that produces the concatenation of the data produced +by a number of sources. +

+ +

+Source1 to sourceN are the original +sources. +

+ +

+The function returns the new source. +

+ + + +

+ltn12.source.chain(source, filter) +

+ +

+Creates a new source that passes data through a filter +before returning it. +

+ +

+The function returns the new source. +

+ + + +

+ltn12.source.empty() +

+ +

+Creates and returns an empty source. +

+ + + +

+ltn12.source.error(message) +

+ +

+Creates and returns a source that aborts transmission with the error +message. +

+ + + +

+ltn12.source.file(handle, message) +

+ +

+Creates a source that produces the contents of a file. +

+ +

+Handle is a file handle. If handle is nil, +message should give the reason for failure. +

+ +

+The function returns a source that reads chunks of data from +given handle and returns it to the user, +closing the file when done, or a source that aborts the transmission with +the error message +

+ +

+In the following example, notice how the prototype is designed to +fit nicely with the io.open function. +

+ +
+-- load the ltn12 module
+local ltn12 = require("ltn12")
+
+-- copy a file
+ltn12.pump.all(
+  ltn12.source.file(io.open("original.png")),
+  ltn12.sink.file(io.open("copy.png"))
+)
+
+ + + +

+ltn12.source.simplify(source) +

+ +

+Creates and returns a simple source given a fancy source. +

+ + + +

+ltn12.source.string(string) +

+ +

+Creates and returns a source that produces the contents of a +string, chunk by chunk. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/luasocket.png b/Build/source/texk/web2c/luatexdir/luasocket/doc/luasocket.png new file mode 100644 index 00000000000..d24a95495b5 Binary files /dev/null and b/Build/source/texk/web2c/luatexdir/luasocket/doc/luasocket.png differ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/mime.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/mime.html new file mode 100644 index 00000000000..d7faf52cbcb --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/mime.html @@ -0,0 +1,476 @@ + + + + + + +LuaSocket: MIME module + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

MIME

+ +

+The mime namespace offers filters that apply and remove common +content transfer encodings, such as Base64 and Quoted-Printable. +It also provides functions to break text into lines and change +the end-of-line convention. +MIME is described mainly in +RFC 2045, +2046, +2047, +2048, and +2049. +

+ +

+All functionality provided by the MIME module +follows the ideas presented in + +LTN012, Filters sources and sinks. +

+ +

+To obtain the mime namespace, run: +

+ +
+-- loads the MIME module and everything it requires
+local mime = require("mime")
+
+ + + + +

High-level filters

+ + + +

+mime.normalize([marker]) +

+ +

+Converts most common end-of-line markers to a specific given marker. +

+ +

+Marker is the new marker. It defaults to CRLF, the canonic +end-of-line marker defined by the MIME standard. +

+ +

+The function returns a filter that performs the conversion. +

+ +

+Note: There is no perfect solution to this problem. Different end-of-line +markers are an evil that will probably plague developers forever. +This function, however, will work perfectly for text created with any of +the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF), +or the DOS (CRLF) conventions. Even if the data has mixed end-of-line +markers, the function will still work well, although it doesn't +guarantee that the number of empty lines will be correct. +

+ + + +

+mime.decode("base64")
+mime.decode("quoted-printable") +

+ +

+Returns a filter that decodes data from a given transfer content +encoding. +

+ + + +

+mime.encode("base64")
+mime.encode("quoted-printable" [, mode]) +

+ +

+Returns a filter that encodes data according to a given transfer content +encoding. +

+ +

+In the Quoted-Printable case, the user can specify whether the data is +textual or binary, by passing the mode strings "text" or +"binary". Mode defaults to "text". +

+ +

+Although both transfer content encodings specify a limit for the line +length, the encoding filters do not break text into lines (for +added flexibility). +Below is a filter that converts binary data to the Base64 transfer content +encoding and breaks it into lines of the correct size. +

+ +
+base64 = ltn12.filter.chain(
+  mime.encode("base64"),
+  mime.wrap("base64")
+)
+
+ +

+Note: Text data has to be converted to canonic form +before being encoded. +

+ +
+base64 = ltn12.filter.chain(
+  mime.normalize(),
+  mime.encode("base64"),
+  mime.wrap("base64")
+)
+
+ + + +

+mime.stuff()
+

+ +

+Creates and returns a filter that performs stuffing of SMTP messages. +

+ +

+Note: The smtp.send function +uses this filter automatically. You don't need to chain it with your +source, or apply it to your message body. +

+ + + +

+mime.wrap("text" [, length])
+mime.wrap("base64")
+mime.wrap("quoted-printable") +

+ +

+Returns a filter that breaks data into lines. +

+ +

+The "text" line-wrap filter simply breaks text into lines by +inserting CRLF end-of-line markers at appropriate positions. +Length defaults 76. +The "base64" line-wrap filter works just like the default +"text" line-wrap filter with default length. +The function can also wrap "quoted-printable" lines, taking care +not to break lines in the middle of an escaped character. In that case, the +line length is fixed at 76. +

+ +

+For example, to create an encoding filter for the Quoted-Printable transfer content encoding of text data, do the following: +

+ +
+qp = ltn12.filter.chain(
+  mime.normalize(),
+  mime.encode("quoted-printable"),
+  mime.wrap("quoted-printable")
+)
+
+ +

+Note: To break into lines with a different end-of-line convention, apply +a normalization filter after the line break filter. +

+ + + +

Low-level filters

+ + + +

+A, B = mime.b64(C [, D]) +

+ +

+Low-level filter to perform Base64 encoding. +

+ +

+A is the encoded version of the largest prefix of +C..D +that can be encoded unambiguously. B has the remaining bytes of +C..D, before encoding. +If D is nil, A is padded with +the encoding of the remaining bytes of C. +

+ +

+Note: The simplest use of this function is to encode a string into it's +Base64 transfer content encoding. Notice the extra parenthesis around the +call to mime.b64, to discard the second return value. +

+ +
+print((mime.b64("diego:password")))
+--> ZGllZ286cGFzc3dvcmQ=
+
+ + +

+A, n = mime.dot(m [, B]) +

+ +

+Low-level filter to perform SMTP stuffing and enable transmission of +messages containing the sequence "CRLF.CRLF". +

+ +

+A is the stuffed version of B. 'n' gives the +number of characters from the sequence CRLF seen in the end of B. +'m' should tell the same, but for the previous chunk. +

+ +

Note: The message body is defined to begin with +an implicit CRLF. Therefore, to stuff a message correctly, the +first m should have the value 2. +

+ +
+print((string.gsub(mime.dot(2, ".\r\nStuffing the message.\r\n.\r\n."), "\r\n", "\\n")))
+--> ..\nStuffing the message.\n..\n..
+
+ +

+Note: The smtp.send function +uses this filter automatically. You don't need to +apply it again. +

+ + + +

+A, B = mime.eol(C [, D, marker]) +

+ +

+Low-level filter to perform end-of-line marker translation. +For each chunk, the function needs to know if the last character of the +previous chunk could be part of an end-of-line marker or not. This is the +context the function receives besides the chunk. An updated version of +the context is returned after each new chunk. +

+ +

+A is the translated version of D. C is the +ASCII value of the last character of the previous chunk, if it was a +candidate for line break, or 0 otherwise. +B is the same as C, but for the current +chunk. Marker gives the new end-of-line marker and defaults to CRLF. +

+ +
+-- translates the end-of-line marker to UNIX
+unix = mime.eol(0, dos, "\n") 
+
+ + + +

+A, B = mime.qp(C [, D, marker]) +

+ +

+Low-level filter to perform Quoted-Printable encoding. +

+ +

+A is the encoded version of the largest prefix of +C..D +that can be encoded unambiguously. B has the remaining bytes of +C..D, before encoding. +If D is nil, A is padded with +the encoding of the remaining bytes of C. +Throughout encoding, occurrences of CRLF are replaced by the +marker, which itself defaults to CRLF. +

+ +

+Note: The simplest use of this function is to encode a string into it's +Quoted-Printable transfer content encoding. +Notice the extra parenthesis around the call to mime.qp, to discard the second return value. +

+ +
+print((mime.qp("maçã")))
+--> ma=E7=E3=
+
+ + + +

+A, m = mime.qpwrp(n [, B, length]) +

+ +

+Low-level filter to break Quoted-Printable text into lines. +

+ +

+A is a copy of B, broken into lines of at most +length bytes (defaults to 76). +'n' should tell how many bytes are left for the first +line of B and 'm' returns the number of bytes +left in the last line of A. +

+ +

+Note: Besides breaking text into lines, this function makes sure the line +breaks don't fall in the middle of an escaped character combination. Also, +this function only breaks lines that are bigger than length bytes. +

+ + + +

+A, B = mime.unb64(C [, D]) +

+ +

+Low-level filter to perform Base64 decoding. +

+ +

+A is the decoded version of the largest prefix of +C..D +that can be decoded unambiguously. B has the remaining bytes of +C..D, before decoding. +If D is nil, A is the empty string +and B returns whatever couldn't be decoded. +

+ +

+Note: The simplest use of this function is to decode a string from it's +Base64 transfer content encoding. +Notice the extra parenthesis around the call to mime.unqp, to discard the second return value. +

+ +
+print((mime.unb64("ZGllZ286cGFzc3dvcmQ=")))
+--> diego:password
+
+ + + +

+A, B = mime.unqp(C [, D]) +

+ +

+Low-level filter to remove the Quoted-Printable transfer content encoding +from data. +

+ +

+A is the decoded version of the largest prefix of +C..D +that can be decoded unambiguously. B has the remaining bytes of +C..D, before decoding. +If D is nil, A is augmented with +the encoding of the remaining bytes of C. +

+ +

+Note: The simplest use of this function is to decode a string from it's +Quoted-Printable transfer content encoding. +Notice the extra parenthesis around the call to mime.unqp, to discard the second return value. +

+ +
+print((mime.qp("ma=E7=E3=")))
+--> maçã
+
+ + + +

+A, m = mime.wrp(n [, B, length]) +

+ +

+Low-level filter to break text into lines with CRLF marker. +Text is assumed to be in the normalize form. +

+ +

+A is a copy of B, broken into lines of at most +length bytes (defaults to 76). +'n' should tell how many bytes are left for the first +line of B and 'm' returns the number of bytes +left in the last line of A. +

+ +

+Note: This function only breaks lines that are bigger than +length bytes. The resulting line length does not include the CRLF +marker. +

+ + + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/reference.css b/Build/source/texk/web2c/luatexdir/luasocket/doc/reference.css new file mode 100644 index 00000000000..b1dd25d70bb --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/reference.css @@ -0,0 +1,54 @@ +body { + margin-left: 1em; + margin-right: 1em; + font-family: "Verdana", sans-serif; +} + +tt { + font-family: "Andale Mono", monospace; +} + +h1, h2, h3, h4 { margin-left: 0em; } + + +h3 { padding-top: 1em; } + +p { margin-left: 1em; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; + margin-left: 0em; +} + +a[href] { color: #00007f; } + +blockquote { margin-left: 3em; } + +pre.example { + background: #ccc; + padding: 1em; + margin-left: 1em; + font-family: "Andale Mono", monospace; + font-size: small; +} + +hr { + margin-left: 0em; + background: #00007f; + border: 0px; + height: 1px; +} + +ul { list-style-type: disc; } + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } +table.index ul { padding-top: 0em; margin-top: 0em; } + +h1:first-letter, +h2:first-letter, +h2:first-letter, +h3:first-letter { color: #00007f; } + +div.header, div.footer { margin-left: 0em; } diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/reference.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/reference.html new file mode 100644 index 00000000000..b329f57f58b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/reference.html @@ -0,0 +1,239 @@ + + + + + + +LuaSocket: Index to reference manual + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

Reference

+ +
+DNS (in socket) +
+toip, +tohostname, +gethostname. +
+
+ + + +
+FTP +
+get, +put. +
+
+ + + +
+HTTP +
+request. +
+
+ + + +
+LTN12 +
+filter: +chain, +cycle. +
+
+pump: +all, +step. +
+
+sink: +chain, +error, +file, +null, +simplify, +table. +
+
+source: +cat, +chain, +empty, +error, +file, +simplify, +string. +
+
+ + + +
+MIME +
+high-level: +normalize, +decode, +encode, +stuff, +wrap. +
+
+low-level: +b64, +dot, +eol, +qp, +wrp, +qpwrp. +unb64, +unqp, +
+
+ + + +
+SMTP +
+message, +send. +
+
+ + + +
+Socket +
+_DEBUG, +dns, +gettime, +newtry, +protect, +select, +sink, +skip, +sleep, +source, +tcp, +try, +udp, +_VERSION. +
+
+ + + +
+TCP (in socket) +
+accept, +bind, +close, +connect, +getpeername, +getsockname, +getstats, +receive, +send, +setoption, +setstats, +settimeout, +shutdown. +
+
+ + + +
+UDP (in socket) +
+close, +getpeername, +getsockname, +receive, +receivefrom, +send, +sendto, +setpeername, +setsockname, +setoption, +settimeout. +
+
+ + + +
+URL +
+absolute, +build, +build_path, +escape, +parse, +parse_path, +unescape. +
+
+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/smtp.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/smtp.html new file mode 100644 index 00000000000..27dd4736b4b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/smtp.html @@ -0,0 +1,417 @@ + + + + + + +LuaSocket: SMTP support + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

SMTP

+ +

The smtp namespace provides functionality to send e-mail +messages. The high-level API consists of two functions: one to +define an e-mail message, and another to actually send the message. +Although almost all users will find that these functions provide more than +enough functionality, the underlying implementation allows for even more +control (if you bother to read the code). +

+ +

The implementation conforms to the Simple Mail Transfer Protocol, +RFC 2821. +Another RFC of interest is RFC 2822, +which governs the Internet Message Format. +Multipart messages (those that contain attachments) are part +of the MIME standard, but described mainly +in RFC +2046 + +

In the description below, good understanding of LTN012, Filters +sources and sinks and the MIME module is +assumed. In fact, the SMTP module was the main reason for their +creation.

+ +

+To obtain the smtp namespace, run: +

+ +
+-- loads the SMTP module and everything it requires
+local smtp = require("socket.smtp")
+
+ +

+MIME headers are represented as a Lua table in the form: +

+ +
+ + +
+headers = {
+  field-1-name = field-1-value,
+  field-2-name = field-2-value,
+  field-3-name = field-3-value,
+  ...
+  field-n-name = field-n-value
+} +
+
+ +

+Field names are case insensitive (as specified by the standard) and all +functions work with lowercase field names. +Field values are left unmodified. +

+ +

+Note: MIME headers are independent of order. Therefore, there is no problem +in representing them in a Lua table. +

+ +

+The following constants can be set to control the default behavior of +the SMTP module: +

+ +
    +
  • DOMAIN: domain used to greet the server; +
  • PORT: default port used for the connection; +
  • SERVER: default server used for the connection; +
  • TIMEOUT: default timeout for all I/O operations; +
  • ZONE: default time zone. +
+ + + +

+smtp.send{
+  from = string,
+  rcpt = string or string-table,
+  source = LTN12 source,
+  [user = string,]
+  [password = string,]
+  [server = string,]
+  [port = number,]
+  [domain = string,]
+  [step = LTN12 pump step,]
+  [create = function]
+} +

+ +

+Sends a message to a recipient list. Since sending messages is not as +simple as downloading an URL from a FTP or HTTP server, this function +doesn't have a simple interface. However, see the +message source factory for +a very powerful way to define the message contents. +

+ + +

+The sender is given by the e-mail address in the from field. +Rcpt is a Lua table with one entry for each recipient e-mail +address, or a string +in case there is just one recipient. +The contents of the message are given by a simple +LTN12 +source. Several arguments are optional: +

+
    +
  • user, password: User and password for +authentication. The function will attempt LOGIN and PLAIN authentication +methods if supported by the server (both are unsafe); +
  • server: Server to connect to. Defaults to "localhost"; +
  • port: Port to connect to. Defaults to 25; +
  • domain: Domain name used to greet the server; Defaults to the +local machine host name; +
  • step: +LTN12 +pump step function used to pass data from the +source to the server. Defaults to the LTN12 pump.step function; +
  • create: An optional function to be used instead of +socket.tcp when the communications socket is created. +
+ +

+If successful, the function returns 1. Otherwise, the function returns +nil followed by an error message. +

+ +

+Note: SMTP servers can be very picky with the format of e-mail +addresses. To be safe, use only addresses of the form +"<fulano@example.com>" in the from and +rcpt arguments to the send function. In headers, e-mail +addresses can take whatever form you like.

+ +

+Big note: There is a good deal of misconception with the use of the +destination address field headers, i.e., the 'To', 'Cc', +and, more importantly, the 'Bcc' headers. Do not add a +'Bcc' header to your messages because it will probably do the +exact opposite of what you expect. +

+ +

+Only recipients specified in the rcpt list will receive a copy of the +message. Each recipient of an SMTP mail message receives a copy of the +message body along with the headers, and nothing more. The headers +are part of the message and should be produced by the +LTN12 +source function. The rcpt list is not +part of the message and will not be sent to anyone. +

+ +

+RFC 2822 +has two important and short sections, "3.6.3. Destination address +fields" and "5. Security considerations", explaining the proper +use of these headers. Here is a summary of what it says: +

+ +
    +
  • To: contains the address(es) of the primary recipient(s) +of the message; +
  • Cc: (where the "Cc" means "Carbon Copy" in the sense of +making a copy on a typewriter using carbon paper) contains the +addresses of others who are to receive the message, though the +content of the message may not be directed at them; +
  • Bcc: (where the "Bcc" means "Blind Carbon +Copy") contains addresses of recipients of the message whose addresses are not to be revealed to other recipients of the message. +
+ +

+The LuaSocket send function does not care or interpret the +headers you send, but it gives you full control over what is sent and +to whom it is sent: +

+
    +
  • If someone is to receive the message, the e-mail address has +to be in the recipient list. This is the only parameter that controls who +gets a copy of the message; +
  • If there are multiple recipients, none of them will automatically +know that someone else got that message. That is, the default behavior is +similar to the Bcc field of popular e-mail clients; +
  • It is up to you to add the To header with the list of primary +recipients so that other recipients can see it; +
  • It is also up to you to add the Cc header with the +list of additional recipients so that everyone else sees it; +
  • Adding a header Bcc is nonsense, unless it is +empty. Otherwise, everyone receiving the message will see it and that is +exactly what you don't want to happen! +
+ +

+I hope this clarifies the issue. Otherwise, please refer to +RFC 2821 +and +RFC 2822. +

+ +
+-- load the smtp support
+local smtp = require("socket.smtp")
+
+-- Connects to server "localhost" and sends a message to users
+-- "fulano@example.com",  "beltrano@example.com", 
+-- and "sicrano@example.com".
+-- Note that "fulano" is the primary recipient, "beltrano" receives a
+-- carbon copy and neither of them knows that "sicrano" received a blind
+-- carbon copy of the message.
+from = "<luasocket@example.com>"
+
+rcpt = {
+  "<fulano@example.com>",
+  "<beltrano@example.com>",
+  "<sicrano@example.com>"
+}
+
+mesgt = {
+  headers = {
+    to = "Fulano da Silva <fulano@example.com>",
+    cc = '"Beltrano F. Nunes" <beltrano@example.com>',
+    subject = "My first message"
+  },
+  body = "I hope this works. If it does, I can send you another 1000 copies."
+}
+
+r, e = smtp.send{
+  from = from,
+  rcpt = rcpt, 
+  source = smtp.message(mesgt)
+}
+
+ + + +

+smtp.message(mesgt) +

+ +

+Returns a simple +LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep). +

+ +

+The only parameter of the function is a table describing the message. +Mesgt has the following form (notice the recursive structure): +

+ +
+ + +
+mesgt = {
+  headers = header-table,
+  body = LTN12 source or string or +multipart-mesgt
+}

+multipart-mesgt = {
+  [preamble = string,]
+  [1] = mesgt,
+  [2] = mesgt,
+  ...
+  [n] = mesgt,
+  [epilogue = string,]
+}
+
+
+ +

+For a simple message, all that is needed is a set of headers +and the body. The message body can be given as a string +or as a simple +LTN12 +source. For multipart messages, the body is a table that +recursively defines each part as an independent message, plus an optional +preamble and epilogue. +

+ +

+The function returns a simple +LTN12 +source that produces the +message contents as defined by mesgt, chunk by chunk. +Hopefully, the following +example will make things clear. When in doubt, refer to the appropriate RFC +as listed in the introduction.

+ +
+-- load the smtp support and its friends
+local smtp = require("socket.smtp")
+local mime = require("mime")
+local ltn12 = require("ltn12")
+
+-- creates a source to send a message with two parts. The first part is 
+-- plain text, the second part is a PNG image, encoded as base64.
+source = smtp.message{
+  headers = {
+     -- Remember that headers are *ignored* by smtp.send. 
+     from = "Sicrano de Oliveira <sicrano@example.com>",
+     to = "Fulano da Silva <fulano@example.com>",
+     subject = "Here is a message with attachments"
+  },
+  body = {
+    preamble = "If your client doesn't understand attachments, \r\n" ..
+               "it will still display the preamble and the epilogue.\r\n" ..
+               "Preamble will probably appear even in a MIME enabled client.",
+    -- first part: no headers means plain text, us-ascii.
+    -- The mime.eol low-level filter normalizes end-of-line markers.
+    [1] = { 
+      body = mime.eol(0, [[
+        Lines in a message body should always end with CRLF. 
+        The smtp module will *NOT* perform translation. However, the 
+        send function *DOES* perform SMTP stuffing, whereas the message
+        function does *NOT*.
+      ]])
+    },
+    -- second part: headers describe content to be a png image, 
+    -- sent under the base64 transfer content encoding.
+    -- notice that nothing happens until the message is actually sent. 
+    -- small chunks are loaded into memory right before transmission and 
+    -- translation happens on the fly.
+    [2] = { 
+      headers = {
+        ["content-type"] = 'image/png; name="image.png"',
+        ["content-disposition"] = 'attachment; filename="image.png"',
+        ["content-description"] = 'a beautiful image',
+        ["content-transfer-encoding"] = "BASE64"
+      },
+      body = ltn12.source.chain(
+        ltn12.source.file(io.open("image.png", "rb")),
+        ltn12.filter.chain(
+          mime.encode("base64"),
+          mime.wrap()
+        )
+      )
+    },
+    epilogue = "This might also show up, but after the attachments"
+  }
+}
+
+-- finally send it
+r, e = smtp.send{
+    from = "<sicrano@example.com>",
+    rcpt = "<fulano@example.com>",
+    source = source,
+}
+
+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/socket.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/socket.html new file mode 100644 index 00000000000..ba4b7303e32 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/socket.html @@ -0,0 +1,404 @@ + + + + + + +LuaSocket: The socket namespace + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

The socket namespace

+ +

+The socket namespace contains the core functionality of LuaSocket. +

+ +

+To obtain the socket namespace, run: +

+ +
+-- loads the socket module 
+local socket = require("socket")
+
+ + + +

+socket.bind(address, port [, backlog]) +

+ +

+This function is a shortcut that creates and returns a TCP server object +bound to a local address and port, ready to +accept client connections. Optionally, +user can also specify the backlog argument to the +listen method (defaults to 32). +

+ +

+Note: The server object returned will have the option "reuseaddr" +set to true. +

+ + + +

+socket.connect(address, port [, locaddr, locport]) +

+ +

+This function is a shortcut that creates and returns a TCP client object +connected to a remote host at a given port. Optionally, +the user can also specify the local address and port to bind +(locaddr and locport). +

+ + + +

+socket._DEBUG +

+ +

+This constant is set to true if the library was compiled +with debug support. +

+ + + +

+socket.newtry(finalizer) +

+ +

+Creates and returns a clean +try +function that allows for cleanup before the exception +is raised. +

+ +

+Finalizer is a function that will be called before +try throws the exception. It will be called +in protected mode. +

+ +

+The function returns your customized try function. +

+ +

+Note: This idea saved a lot of work with the +implementation of protocols in LuaSocket: +

+ +
+foo = socket.protect(function()
+    -- connect somewhere
+    local c = socket.try(socket.connect("somewhere", 42))
+    -- create a try function that closes 'c' on error
+    local try = socket.newtry(function() c:close() end)
+    -- do everything reassured c will be closed 
+    try(c:send("hello there?\r\n"))
+    local answer = try(c:receive())
+    ...
+    try(c:send("good bye\r\n"))
+    c:close()
+end)
+
+ + + + +

+socket.protect(func) +

+ +

+Converts a function that throws exceptions into a safe function. This +function only catches exceptions thrown by the try +and newtry functions. It does not catch normal +Lua errors. +

+ +

+Func is a function that calls +try (or assert, or error) +to throw exceptions. +

+ +

+Returns an equivalent function that instead of throwing exceptions, +returns nil followed by an error message. +

+ +

+Note: Beware that if your function performs some illegal operation that +raises an error, the protected function will catch the error and return it +as a string. This is because the try function +uses errors as the mechanism to throw exceptions. +

+ + + +

+socket.select(recvt, sendt [, timeout]) +

+ +

+Waits for a number of sockets to change status. +

+ +

+Recvt is an array with the sockets to test for characters +available for reading. Sockets in the sendt array are watched to +see if it is OK to immediately write on them. Timeout is the +maximum amount of time (in seconds) to wait for a change in status. A +nil, negative or omitted timeout value allows the +function to block indefinitely. Recvt and sendt can also +be empty tables or nil. Non-socket values (or values with +non-numeric indices) in the arrays will be silently ignored. +

+ +

The function returns a list with the sockets ready for +reading, a list with the sockets ready for writing and an error message. +The error message is "timeout" if a timeout condition was met and +nil otherwise. The returned tables are +doubly keyed both by integers and also by the sockets +themselves, to simplify the test if a specific socket has +changed status. +

+ +

+Important note: a known bug in WinSock causes select to fail +on non-blocking TCP sockets. The function may return a socket as +writable even though the socket is not ready for sending. +

+ +

+Another important note: calling select with a server socket in the receive parameter before a call to accept does not guarantee +accept will return immediately. +Use the settimeout +method or accept might block forever. +

+ +

+Yet another note: If you close a socket and pass +it to select, it will be ignored. +

+ + + +

+socket.sink(mode, socket) +

+ +

+Creates an +LTN12 +sink from a stream socket object. +

+ +

+Mode defines the behavior of the sink. The following +options are available: +

+
    +
  • "http-chunked": sends data through socket after applying the +chunked transfer coding, closing the socket when done; +
  • "close-when-done": sends all received data through the +socket, closing the socket when done; +
  • "keep-open": sends all received data through the +socket, leaving it open when done. +
+

+Socket is the stream socket object used to send the data. +

+ +

+The function returns a sink with the appropriate behavior. +

+ + + +

+socket.skip(d [, ret1, ret2 ... retN]) +

+ +

+Drops a number of arguments and returns the remaining. +

+ +

+D is the number of arguments to drop. Ret1 to +retN are the arguments. +

+ +

+The function returns retd+1 to retN. +

+ +

+Note: This function is useful to avoid creation of dummy variables: +

+ +
+-- get the status code and separator from SMTP server reply 
+local code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
+
+ + + +

+socket.sleep(time) +

+ +

+Freezes the program execution during a given amount of time. +

+ +

+Time is the number of seconds to sleep for. +

+ + + +

+socket.source(mode, socket [, length]) +

+ +

+Creates an +LTN12 +source from a stream socket object. +

+ +

+Mode defines the behavior of the source. The following +options are available: +

+
    +
  • "http-chunked": receives data from socket and removes the +chunked transfer coding before returning the data; +
  • "by-length": receives a fixed number of bytes from the +socket. This mode requires the extra argument length; +
  • "until-closed": receives data from a socket until the other +side closes the connection. +
+

+Socket is the stream socket object used to receive the data. +

+ +

+The function returns a source with the appropriate behavior. +

+ + + +

+socket.gettime() +

+ +

+Returns the time in seconds, relative to the origin of the +universe. You should subtract the values returned by this function +to get meaningful values. +

+ +
+t = socket.gettime()
+-- do stuff
+print(socket.gettime() - t .. " seconds elapsed")
+
+ + + +

+socket.try(ret1 [, ret2 ... retN]) +

+ +

+Throws an exception in case of error. The exception can only be caught +by the protect function. It does not explode +into an error message. +

+ +

+Ret1 to retN can be arbitrary +arguments, but are usually the return values of a function call +nested with try. +

+ +

+The function returns ret1 to retN if +ret1 is not nil. Otherwise, it calls error passing ret2. +

+ +
+-- connects or throws an exception with the appropriate error message
+c = socket.try(socket.connect("localhost", 80))
+
+ + + +

+socket._VERSION +

+ +

+This constant has a string describing the current LuaSocket version. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/tcp.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/tcp.html new file mode 100644 index 00000000000..a16a09ed538 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/tcp.html @@ -0,0 +1,533 @@ + + + + + + +LuaSocket: TCP/IP support + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

TCP

+ + + +

+socket.tcp() +

+ +

+Creates and returns a TCP master object. A master object can +be transformed into a server object with the method +listen (after a call to bind) or into a client object with +the method connect. The only other +method supported by a master object is the +close method.

+ +

+In case of success, a new master object is returned. In case of error, +nil is returned, followed by an error message. +

+ + + +

+server:accept() +

+ +

+Waits for a remote connection on the server +object and returns a client object representing that connection. +

+ +

+If a connection is successfully initiated, a client object is returned. +If a timeout condition is met, the method returns nil +followed by the error string 'timeout'. Other errors are +reported by nil followed by a message describing the error. +

+ +

+Note: calling socket.select +with a server object in +the recvt parameter before a call to accept does +not guarantee accept will return immediately. Use the settimeout method or accept +might block until another client shows up. +

+ + + +

+master:bind(address, port) +

+ +

+Binds a master object to address and port on the +local host. + +

+Address can be an IP address or a host name. +Port must be an integer number in the range [0..64K). +If address +is '*', the system binds to all local interfaces +using the INADDR_ANY constant. If port is 0, the system automatically +chooses an ephemeral port. +

+ +

+In case of success, the method returns 1. In case of error, the +method returns nil followed by an error message. +

+ +

+Note: The function socket.bind +is available and is a shortcut for the creation of server sockets. +

+ + + +

+master:close()
+client:close()
+server:close() +

+ +

+Closes a TCP object. The internal socket used by the object is closed +and the local address to which the object was +bound is made available to other applications. No further operations +(except for further calls to the close method) are allowed on +a closed socket. +

+ +

+Note: It is important to close all used sockets once they are not +needed, since, in many systems, each socket uses a file descriptor, +which are limited system resources. Garbage-collected objects are +automatically closed before destruction, though. +

+ + + +

+master:connect(address, port) +

+ +

+Attempts to connect a master object to a remote host, transforming it into a +client object. +Client objects support methods +send, +receive, +getsockname, +getpeername, +settimeout, +and close. +

+ +

+Address can be an IP address or a host name. +Port must be an integer number in the range [1..64K). +

+ +

+In case of error, the method returns nil followed by a string +describing the error. In case of success, the method returns 1. +

+ +

+Note: The function socket.connect +is available and is a shortcut for the creation of client sockets. +

+ +

+Note: Starting with LuaSocket 2.0, +the settimeout +method affects the behavior of connect, causing it to return +with an error in case of a timeout. If that happens, you can still call socket.select with the socket in the +sendt table. The socket will be writable when the connection is +established. +

+ + + +

+client:getpeername() +

+ +

+Returns information about the remote side of a connected client object. +

+ +

+Returns a string with the IP address of the peer, followed by the +port number that peer is using for the connection. +In case of error, the method returns nil. +

+ +

+Note: It makes no sense to call this method on server objects. +

+ + + +

+master:getsockname()
+client:getsockname()
+server:getsockname() +

+ +

+Returns the local address information associated to the object. +

+ +

+The method returns a string with local IP address and a number with +the port. In case of error, the method returns nil. +

+ + + +

+master:getstats()
+client:getstats()
+server:getstats()
+

+ +

+Returns accounting information on the socket, useful for throttling +of bandwidth. +

+ +

+The method returns the number of bytes received, the number of bytes sent, +and the age of the socket object in seconds. +

+ + + +

+master:listen(backlog) +

+ +

+Specifies the socket is willing to receive connections, transforming the +object into a server object. Server objects support the +accept, +getsockname, +setoption, +settimeout, +and close methods. +

+ +

+The parameter backlog specifies the number of client +connections that can +be queued waiting for service. If the queue is full and another client +attempts connection, the connection is refused. +

+ +

+In case of success, the method returns 1. In case of error, the +method returns nil followed by an error message. +

+ + + +

+client:receive([pattern [, prefix]]) +

+ +

+Reads data from a client object, according to the specified read +pattern. Patterns follow the Lua file I/O format, and the difference in performance between all patterns is negligible. +

+ +

+Pattern can be any of the following: +

+ +
    +
  • '*a': reads from the socket until the connection is +closed. No end-of-line translation is performed; +
  • '*l': reads a line of text from the socket. The line is +terminated by a LF character (ASCII 10), optionally preceded by a +CR character (ASCII 13). The CR and LF characters are not included in +the returned line. In fact, all CR characters are +ignored by the pattern. This is the default pattern; +
  • number: causes the method to read a specified number +of bytes from the socket. +
+ +

+Prefix is an optional string to be concatenated to the beginning +of any received data before return. +

+ +

+If successful, the method returns the received pattern. In case of error, +the method returns nil followed by an error message which +can be the string 'closed' in case the connection was +closed before the transmission was completed or the string +'timeout' in case there was a timeout during the operation. +Also, after the error message, the function returns the partial result of +the transmission. +

+ +

+Important note: This function was changed severely. It used +to support multiple patterns (but I have never seen this feature used) and +now it doesn't anymore. Partial results used to be returned in the same +way as successful results. This last feature violated the idea that all +functions should return nil on error. Thus it was changed +too. +

+ + + +

+client:send(data [, i [, j]]) +

+ +

+Sends data through client object. +

+ +

+Data is the string to be sent. The optional arguments +i and j work exactly like the standard +string.sub Lua function to allow the selection of a +substring to be sent. +

+ +

+If successful, the method returns the index of the last byte +within [i, j] that has been sent. Notice that, if +i is 1 or absent, this is effectively the total +number of bytes sent. In case of error, the method returns +nil, followed by an error message, followed +by the index of the last byte within [i, j] that +has been sent. You might want to try again from the byte +following that. The error message can be 'closed' +in case the connection was closed before the transmission +was completed or the string 'timeout' in case +there was a timeout during the operation. +

+ +

+Note: Output is not buffered. For small strings, +it is always better to concatenate them in Lua +(with the '..' operator) and send the result in one call +instead of calling the method several times. +

+ + + +

+client:setoption(option [, value])
+server:setoption(option [, value]) +

+ +

+Sets options for the TCP object. Options are only needed by low-level or +time-critical applications. You should only modify an option if you +are sure you need it. +

+ +

+Option is a string with the option name, and value +depends on the option being set: + +

    + +
  • 'keepalive': Setting this option to true enables +the periodic transmission of messages on a connected socket. Should the +connected party fail to respond to these messages, the connection is +considered broken and processes using the socket are notified; + +
  • 'linger': Controls the action taken when unsent data are +queued on a socket and a close is performed. The value is a table with a +boolean entry 'on' and a numeric entry for the time interval +'timeout' in seconds. If the 'on' field is set to +true, the system will block the process on the close attempt until +it is able to transmit the data or until 'timeout' has passed. If +'on' is false and a close is issued, the system will +process the close in a manner that allows the process to continue as +quickly as possible. I do not advise you to set this to anything other than +zero; + +
  • 'reuseaddr': Setting this option indicates that the rules +used in validating addresses supplied in a call to +bind should allow reuse of local addresses; + +
  • 'tcp-nodelay': Setting this option to true +disables the Nagle's algorithm for the connection. + +
+ +

+The method returns 1 in case of success, or nil otherwise. +

+ +

+Note: The descriptions above come from the man pages. +

+ + + +

+master:setstats(received, sent, age)
+client:setstats(received, sent, age)
+server:setstats(received, sent, age)
+

+ +

+Resets accounting information on the socket, useful for throttling +of bandwidth. +

+ +

+Received is a number with the new number of bytes received. +Sent is a number with the new number of bytes sent. +Age is the new age in seconds. +

+ +

+The method returns 1 in case of success and nil otherwise. +

+ + + +

+master:settimeout(value [, mode])
+client:settimeout(value [, mode])
+server:settimeout(value [, mode]) +

+ +

+Changes the timeout values for the object. By default, +all I/O operations are blocking. That is, any call to the methods +send, +receive, and +accept +will block indefinitely, until the operation completes. The +settimeout method defines a limit on the amount of time the +I/O methods can block. When a timeout is set and the specified amount of +time has elapsed, the affected methods give up and fail with an error code. +

+ +

+The amount of time to wait is specified as the +value parameter, in seconds. There are two timeout modes and +both can be used together for fine tuning: +

+ +
    +
  • 'b': block timeout. Specifies the upper limit on +the amount of time LuaSocket can be blocked by the operating system +while waiting for completion of any single I/O operation. This is the +default mode;
  • + +
  • 't': total timeout. Specifies the upper limit on +the amount of time LuaSocket can block a Lua script before returning from +a call.
  • +
+ +

+The nil timeout value allows operations to block +indefinitely. Negative timeout values have the same effect. +

+ +

+Note: although timeout values have millisecond precision in LuaSocket, +large blocks can cause I/O functions not to respect timeout values due +to the time the library takes to transfer blocks to and from the OS +and to and from the Lua interpreter. Also, function that accept host names +and perform automatic name resolution might be blocked by the resolver for +longer than the specified timeout value. +

+ +

+Note: The old timeout method is deprecated. The name has been +changed for sake of uniformity, since all other method names already +contained verbs making their imperative nature obvious. +

+ + + +

+client:shutdown(mode)
+

+ +

+Shuts down part of a full-duplex connection. +

+ +

+Mode tells which way of the connection should be shut down and can +take the value: +

    +
  • "both": disallow further sends and receives on the object. +This is the default mode; +
  • "send": disallow further sends on the object; +
  • "receive": disallow further receives on the object. +
+ +

+This function returns 1. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/udp.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/udp.html new file mode 100644 index 00000000000..688649decb9 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/udp.html @@ -0,0 +1,416 @@ + + + + + + +LuaSocket: UDP support + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + + +

UDP

+ + + +

+socket.udp() +

+ +

+Creates and returns an unconnected UDP object. Unconnected objects support the +sendto, +receive, +receivefrom, +getsockname, +setoption, +settimeout, +setpeername, +setsockname, and +close. +The setpeername +is used to connect the object. +

+ +

+In case of success, a new unconnected UDP object +returned. In case of error, nil is returned, followed by +an error message. +

+ + + +

+connected:close()
+unconnected:close() +

+ +

+Closes a UDP object. The internal socket +used by the object is closed and the local address to which the +object was bound is made available to other applications. No +further operations (except for further calls to the close +method) are allowed on a closed socket. +

+ +

+Note: It is important to close all used sockets +once they are not needed, since, in many systems, each socket uses +a file descriptor, which are limited system resources. +Garbage-collected objects are automatically closed before +destruction, though. +

+ + + +

+connected:getpeername() +

+ +

+Retrieves information about the peer +associated with a connected UDP object. +

+ +

+Returns the IP address and port number of the peer. +

+ +

+Note: It makes no sense to call this method on unconnected objects. +

+ + + +

+connected:getsockname()
+unconnected:getsockname() +

+ +

+Returns the local address information associated to the object. +

+ +

+The method returns a string with local IP +address and a number with the port. In case of error, the method +returns nil. +

+ +

+Note: UDP sockets are not bound to any address +until the setsockname or the +sendto method is called for the +first time (in which case it is bound to an ephemeral port and the +wild-card address). +

+ + + +

+connected:receive([size])
+unconnected:receive([size]) +

+ +

+Receives a datagram from the UDP object. If +the UDP object is connected, only datagrams coming from the peer +are accepted. Otherwise, the returned datagram can come from any +host. +

+ +

+The optional size parameter +specifies the maximum size of the datagram to be retrieved. If +there are more than size bytes available in the datagram, +the excess bytes are discarded. If there are less then +size bytes available in the current datagram, the +available bytes are returned. If size is omitted, the +maximum datagram size is used (which is currently limited by the +implementation to 8192 bytes). +

+ +

+In case of success, the method returns the +received datagram. In case of timeout, the method returns +nil followed by the string 'timeout'. +

+ + + +

+unconnected:receivefrom([size]) +

+ +

+Works exactly as the receive +method, except it returns the IP +address and port as extra return values (and is therefore slightly less +efficient). +

+ + + +

+connected:send(datagram) +

+ +

+Sends a datagram to the UDP peer of a connected object. +

+ +

+Datagram is a string with the datagram contents. +The maximum datagram size for UDP is 64K minus IP layer overhead. +However datagrams larger than the link layer packet size will be +fragmented, which may deteriorate performance and/or reliability. +

+ +

+If successful, the method returns 1. In case of +error, the method returns nil followed by an error message. +

+ +

+Note: In UDP, the send method never blocks +and the only way it can fail is if the underlying transport layer +refuses to send a message to the specified address (i.e. no +interface accepts the address). +

+ + + +

+unconnected:sendto(datagram, ip, port) +

+ +

+Sends a datagram to the specified IP address and port number. +

+ +

+Datagram is a string with the +datagram contents. +The maximum datagram size for UDP is 64K minus IP layer overhead. +However datagrams larger than the link layer packet size will be +fragmented, which may deteriorate performance and/or reliability. +Ip is the IP address of the recipient. +Host names are not allowed for performance reasons. + +Port is the port number at the recipient. +

+ +

+If successful, the method returns 1. In case of +error, the method returns nil followed by an error message. +

+ +

+Note: In UDP, the send method never blocks +and the only way it can fail is if the underlying transport layer +refuses to send a message to the specified address (i.e. no +interface accepts the address). +

+ + + +

+connected:setpeername('*')
+unconnected:setpeername(address, port) +

+ +

+Changes the peer of a UDP object. This +method turns an unconnected UDP object into a connected UDP +object or vice versa. +

+ +

+For connected objects, outgoing datagrams +will be sent to the specified peer, and datagrams received from +other peers will be discarded by the OS. Connected UDP objects must +use the send and +receive methods instead of +sendto and +receivefrom. +

+ +

+Address can be an IP address or a +host name. Port is the port number. If address is +'*' and the object is connected, the peer association is +removed and the object becomes an unconnected object again. In that +case, the port argument is ignored. +

+ +

+In case of error the method returns +nil followed by an error message. In case of success, the +method returns 1. +

+ +

+Note: Since the address of the peer does not have +to be passed to and from the OS, the use of connected UDP objects +is recommended when the same peer is used for several transmissions +and can result in up to 30% performance gains. +

+ + + +

+unconnected:setsockname(address, port) +

+ +

+Binds the UDP object to a local address. +

+ +

+Address can be an IP address or a +host name. If address is '*' the system binds to +all local interfaces using the constant INADDR_ANY. If +port is 0, the system chooses an ephemeral port. +

+ +

+If successful, the method returns 1. In case of +error, the method returns nil followed by an error +message. +

+ +

+Note: This method can only be called before any +datagram is sent through the UDP object, and only once. Otherwise, +the system automatically binds the object to all local interfaces +and chooses an ephemeral port as soon as the first datagram is +sent. After the local address is set, either automatically by the +system or explicitly by setsockname, it cannot be +changed. +

+ + + +

+connected:setoption(option [, value])
+unconnected:setoption(option [, value]) +

+ +

+Sets options for the UDP object. Options are +only needed by low-level or time-critical applications. You should +only modify an option if you are sure you need it.

+

Option is a string with the option +name, and value depends on the option being set: +

+ +
    +
  • 'dontroute': Setting this option to true +indicates that outgoing messages should bypass the standard routing +facilities;
  • +
  • 'broadcast': Setting this option to true +requests permission to send broadcast datagrams on the +socket.
  • +
+ +

+The method returns 1 in case of success, or +nil followed by an error message otherwise. +

+ +

+Note: The descriptions above come from the man +pages. +

+ + + +

+connected:settimeout(value)
+unconnected:settimeout(value) +

+ +

+Changes the timeout values for the object. By default, the +receive and +receivefrom +operations are blocking. That is, any call to the methods will block +indefinitely, until data arrives. The settimeout function defines +a limit on the amount of time the functions can block. When a timeout is +set and the specified amount of time has elapsed, the affected methods +give up and fail with an error code. +

+ +

+The amount of time to wait is specified as +the value parameter, in seconds. The nil timeout +value allows operations to block indefinitely. Negative +timeout values have the same effect. +

+ +

+Note: In UDP, the send +and sendto methods never block (the +datagram is just passed to the OS and the call returns +immediately). Therefore, the settimeout method has no +effect on them. +

+ +

+Note: The old timeout method is +deprecated. The name has been changed for sake of uniformity, since +all other method names already contained verbs making their +imperative nature obvious. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/doc/url.html b/Build/source/texk/web2c/luatexdir/luasocket/doc/url.html new file mode 100644 index 00000000000..e87126fa316 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/doc/url.html @@ -0,0 +1,329 @@ + + + + + + +LuaSocket: URL support + + + + + + + +
+
+
+ + + +
+LuaSocket +
Network support for the Lua language +
+

+home · +download · +installation · +introduction · +reference +

+
+
+
+ + + +

URL

+ +

+The url namespace provides functions to parse, protect, +and build URLs, as well as functions to compose absolute URLs +from base and relative URLs, according to +RFC +2396. +

+ +

+To obtain the url namespace, run: +

+ +
+-- loads the URL module 
+local url = require("socket.url")
+
+ +

+An URL is defined by the following grammar: +

+ +
+ +<url> ::= [<scheme>:][//<authority>][/<path>][;<params>][?<query>][#<fragment>]
+<authority> ::= [<userinfo>@]<host>[:<port>]
+<userinfo> ::= <user>[:<password>]
+<path> ::= {<segment>/}<segment>
+
+
+ + + +

+url.absolute(base, relative) +

+ +

+Builds an absolute URL from a base URL and a relative URL. +

+ +

+Base is a string with the base URL or +a parsed URL table. Relative is a +string with the relative URL. +

+ +

+The function returns a string with the absolute URL. +

+ +

+Note: The rules that +govern the composition are fairly complex, and are described in detail in +RFC 2396. +The example bellow should give an idea of what the rules are. +

+ +
+http://a/b/c/d;p?q
+
++
+
+g:h      =  g:h
+g        =  http://a/b/c/g
+./g      =  http://a/b/c/g
+g/       =  http://a/b/c/g/
+/g       =  http://a/g
+//g      =  http://g
+?y       =  http://a/b/c/?y
+g?y      =  http://a/b/c/g?y
+#s       =  http://a/b/c/d;p?q#s
+g#s      =  http://a/b/c/g#s
+g?y#s    =  http://a/b/c/g?y#s
+;x       =  http://a/b/c/;x
+g;x      =  http://a/b/c/g;x
+g;x?y#s  =  http://a/b/c/g;x?y#s
+.        =  http://a/b/c/
+./       =  http://a/b/c/
+..       =  http://a/b/
+../      =  http://a/b/
+../g     =  http://a/b/g
+../..    =  http://a/
+../../   =  http://a/
+../../g  =  http://a/g
+
+ + + +

+url.build(parsed_url) +

+ +

+Rebuilds an URL from its parts. +

+ +

+Parsed_url is a table with same components returned by +parse. +Lower level components, if specified, +take precedence over high level components of the URL grammar. +

+ +

+The function returns a string with the built URL. +

+ + + +

+url.build_path(segments, unsafe) +

+ +

+Builds a <path> component from a list of +<segment> parts. +Before composition, any reserved characters found in a segment are escaped into +their protected form, so that the resulting path is a valid URL path +component. +

+ +

+Segments is a list of strings with the <segment> +parts. If unsafe is anything but nil, reserved +characters are left untouched. +

+ +

+The function returns a string with the +built <path> component. +

+ + + +

+url.escape(content) +

+ +

+Applies the URL escaping content coding to a string +Each byte is encoded as a percent character followed +by the two byte hexadecimal representation of its integer +value. +

+ +

+Content is the string to be encoded. +

+ +

+The function returns the encoded string. +

+ +
+-- load url module
+url = require("socket.url")
+
+code = url.escape("/#?;")
+-- code = "%2f%23%3f%3b"
+
+ + + +

+url.parse(url, default) +

+ +

+Parses an URL given as a string into a Lua table with its components. +

+ +

+Url is the URL to be parsed. If the default table is +present, it is used to store the parsed fields. Only fields present in the +URL are overwritten. Therefore, this table can be used to pass default +values for each field. +

+ +

+The function returns a table with all the URL components: +

+ +
+parsed_url = {
+  url = string,
+  scheme = string,
+  authority = string,
+  path = string,
+  params = string,
+  query = string,
+  fragment = string,
+  userinfo = string,
+  host = string,
+  port = string,
+  user = string,
+  password = string
+} +
+ +
+-- load url module
+url = require("socket.url")
+
+parsed_url = url.parse("http://www.example.com/cgilua/index.lua?a=2#there")
+-- parsed_url = {
+--   scheme = "http",
+--   authority = "www.example.com",
+--   path = "/cgilua/index.lua"
+--   query = "a=2",
+--   fragment = "there",
+--   host = "www.puc-rio.br",
+-- }
+
+parsed_url = url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i")
+-- parsed_url = {
+--   scheme = "ftp",
+--   authority = "root:passwd@unsafe.org",
+--   path = "/pub/virus.exe",
+--   params = "type=i",
+--   userinfo = "root:passwd",
+--   host = "unsafe.org",
+--   user = "root",
+--   password = "passwd",
+-- }
+
+ + + +

+url.parse_path(path) +

+ +

+Breaks a <path> URL component into all its +<segment> parts. +

+ +

+Path is a string with the path to be parsed. +

+ +

+Since some characters are reserved in URLs, they must be escaped +whenever present in a <path> component. Therefore, before +returning a list with all the parsed segments, the function removes +escaping from all of them. +

+ + + +

+url.unescape(content) +

+ +

+Removes the URL escaping content coding from a string. +

+ +

+Content is the string to be decoded. +

+ +

+The function returns the decoded string. +

+ + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/README b/Build/source/texk/web2c/luatexdir/luasocket/etc/README new file mode 100644 index 00000000000..cfd3e372fad --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/README @@ -0,0 +1,89 @@ +This directory contains code that is more useful than the +samples. This code *is* supported. + + tftp.lua -- Trivial FTP client + +This module implements file retrieval by the TFTP protocol. +Its main use was to test the UDP code, but since someone +found it usefull, I turned it into a module that is almost +official (no uploads, yet). + + dict.lua -- Dict client + +The dict.lua module started with a cool simple client +for the DICT protocol, written by Luiz Henrique Figueiredo. +This new version has been converted into a library, similar +to the HTTP and FTP libraries, that can be used from within +any luasocket application. Take a look on the source code +and you will be able to figure out how to use it. + + lp.lua -- LPD client library + +The lp.lua module implements the client part of the Line +Printer Daemon protocol, used to print files on Unix +machines. It is courtesy of David Burgess! See the source +code and the lpr.lua in the examples directory. + + b64.lua + qp.lua + eol.lua + +These are tiny programs that perform Base64, +Quoted-Printable and end-of-line marker conversions. + + get.lua -- file retriever + +This little program is a client that uses the FTP and +HTTP code to implement a command line file graber. Just +run + + lua get.lua [] + +to download a remote file (either ftp:// or http://) to +the specified local file. The program also prints the +download throughput, elapsed time, bytes already downloaded +etc during download. + + check-memory.lua -- checks memory consumption + +This is just to see how much memory each module uses. + + dispatch.lua -- coroutine based dispatcher + +This is a first try at a coroutine based non-blocking +dispatcher for LuaSocket. Take a look at 'check-links.lua' +and at 'forward.lua' to see how to use it. + + check-links.lua -- HTML link checker program + +This little program scans a HTML file and checks for broken +links. It is similar to check-links.pl by Jamie Zawinski, +but uses all facilities of the LuaSocket library and the Lua +language. It has not been thoroughly tested, but it should +work. Just run + + lua check-links.lua [-n] {} > output + +and open the result to see a list of broken links. Make sure +you check the '-n' switch. It runs in non-blocking mode, +using coroutines, and is MUCH faster! + + forward.lua -- coroutine based forward server + +This is a forward server that can accept several connections +and transfers simultaneously using non-blocking I/O and the +coroutine-based dispatcher. You can run, for example + + lua forward.lua 8080:proxy.com:3128 + +to redirect all local conections to port 8080 to the host +'proxy.com' at port 3128. + + unix.c and unix.h + +This is an implementation of Unix local domain sockets and +demonstrates how to extend LuaSocket with a new type of +transport. It has been tested on Linux and on Mac OS X. + +Good luck, +Diego. diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/b64.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/b64.lua new file mode 100644 index 00000000000..f75c4232db6 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/b64.lua @@ -0,0 +1,20 @@ +----------------------------------------------------------------------------- +-- Little program to convert to and from Base64 +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: b64.lua,v 1.8 2004/06/16 04:28:21 diego Exp $ +----------------------------------------------------------------------------- +local ltn12 = require("ltn12") +local mime = require("mime") +local source = ltn12.source.file(io.stdin) +local sink = ltn12.sink.file(io.stdout) +local convert +if arg and arg[1] == '-d' then + convert = mime.decode("base64") +else + local base64 = mime.encode("base64") + local wrap = mime.wrap() + convert = ltn12.filter.chain(base64, wrap) +end +sink = ltn12.sink.chain(convert, sink) +ltn12.pump.all(source, sink) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/check-links.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/check-links.lua new file mode 100644 index 00000000000..a989f8c271e --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/check-links.lua @@ -0,0 +1,112 @@ +----------------------------------------------------------------------------- +-- Little program that checks links in HTML files, using coroutines and +-- non-blocking I/O via the dispatcher module. +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $$ +----------------------------------------------------------------------------- +local url = require("socket.url") +local dispatch = require("dispatch") +local http = require("socket.http") +dispatch.TIMEOUT = 10 + +-- make sure the user knows how to invoke us +arg = arg or {} +if table.getn(arg) < 1 then + print("Usage:\n luasocket check-links.lua [-n] {}") + exit() +end + +-- '-n' means we are running in non-blocking mode +if arg[1] == "-n" then + -- if non-blocking I/O was requested, use real dispatcher interface + table.remove(arg, 1) + handler = dispatch.newhandler("coroutine") +else + -- if using blocking I/O, use fake dispatcher interface + handler = dispatch.newhandler("sequential") +end + +local nthreads = 0 + +-- get the status of a URL using the dispatcher +function getstatus(link) + local parsed = url.parse(link, {scheme = "file"}) + if parsed.scheme == "http" then + nthreads = nthreads + 1 + handler:start(function() + local r, c, h, s = http.request{ + method = "HEAD", + url = link, + create = handler.tcp + } + if r and c == 200 then io.write('\t', link, '\n') + else io.write('\t', link, ': ', tostring(c), '\n') end + nthreads = nthreads - 1 + end) + end +end + +function readfile(path) + path = url.unescape(path) + local file, error = io.open(path, "r") + if file then + local body = file:read("*a") + file:close() + return body + else return nil, error end +end + +function load(u) + local parsed = url.parse(u, { scheme = "file" }) + local body, headers, code, error + local base = u + if parsed.scheme == "http" then + body, code, headers = http.request(u) + if code == 200 then + -- if there was a redirect, update base to reflect it + base = headers.location or base + end + if not body then + error = code + end + elseif parsed.scheme == "file" then + body, error = readfile(parsed.path) + else error = string.format("unhandled scheme '%s'", parsed.scheme) end + return base, body, error +end + +function getlinks(body, base) + -- get rid of comments + body = string.gsub(body, "%<%!%-%-.-%-%-%>", "") + local links = {} + -- extract links + body = string.gsub(body, '[Hh][Rr][Ee][Ff]%s*=%s*"([^"]*)"', function(href) + table.insert(links, url.absolute(base, href)) + end) + body = string.gsub(body, "[Hh][Rr][Ee][Ff]%s*=%s*'([^']*)'", function(href) + table.insert(links, url.absolute(base, href)) + end) + string.gsub(body, "[Hh][Rr][Ee][Ff]%s*=%s*(.-)>", function(href) + table.insert(links, url.absolute(base, href)) + end) + return links +end + +function checklinks(address) + local base, body, error = load(address) + if not body then print(error) return end + print("Checking ", base) + local links = getlinks(body, base) + for _, link in ipairs(links) do + getstatus(link) + end +end + +for _, address in ipairs(arg) do + checklinks(url.absolute("file:", address)) +end + +while nthreads > 0 do + handler:step() +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/check-memory.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/check-memory.lua new file mode 100644 index 00000000000..7bd984d8ee8 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/check-memory.lua @@ -0,0 +1,17 @@ +function load(s) + collectgarbage() + local a = gcinfo() + _G[s] = require(s) + collectgarbage() + local b = gcinfo() + print(s .. ":\t " .. (b-a) .. "k") +end + +load("socket.url") +load("ltn12") +load("socket") +load("mime") +load("socket.tp") +load("socket.smtp") +load("socket.http") +load("socket.ftp") diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/dict.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/dict.lua new file mode 100644 index 00000000000..c082c24c0db --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/dict.lua @@ -0,0 +1,152 @@ +----------------------------------------------------------------------------- +-- Little program to download DICT word definitions +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: dict.lua,v 1.22 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Load required modules +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local table = require("table") +local socket = require("socket") +local url = require("socket.url") +local tp = require("socket.tp") +module("socket.dict") + +----------------------------------------------------------------------------- +-- Globals +----------------------------------------------------------------------------- +HOST = "dict.org" +PORT = 2628 +TIMEOUT = 10 + +----------------------------------------------------------------------------- +-- Low-level dict API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function open(host, port) + local tp = socket.try(tp.connect(host or HOST, port or PORT, TIMEOUT)) + return base.setmetatable({tp = tp}, metat) +end + +function metat.__index:greet() + return socket.try(self.tp:check(220)) +end + +function metat.__index:check(ok) + local code, status = socket.try(self.tp:check(ok)) + return code, + base.tonumber(socket.skip(2, string.find(status, "^%d%d%d (%d*)"))) +end + +function metat.__index:getdef() + local line = socket.try(self.tp:receive()) + local def = {} + while line ~= "." do + table.insert(def, line) + line = socket.try(self.tp:receive()) + end + return table.concat(def, "\n") +end + +function metat.__index:define(database, word) + database = database or "!" + socket.try(self.tp:command("DEFINE", database .. " " .. word)) + local code, count = self:check(150) + local defs = {} + for i = 1, count do + self:check(151) + table.insert(defs, self:getdef()) + end + self:check(250) + return defs +end + +function metat.__index:match(database, strat, word) + database = database or "!" + strat = strat or "." + socket.try(self.tp:command("MATCH", database .." ".. strat .." ".. word)) + self:check(152) + local mat = {} + local line = socket.try(self.tp:receive()) + while line ~= '.' do + database, word = socket.skip(2, string.find(line, "(%S+) (.*)")) + if not mat[database] then mat[database] = {} end + table.insert(mat[database], word) + line = socket.try(self.tp:receive()) + end + self:check(250) + return mat +end + +function metat.__index:quit() + self.tp:command("QUIT") + return self:check(221) +end + +function metat.__index:close() + return self.tp:close() +end + +----------------------------------------------------------------------------- +-- High-level dict API +----------------------------------------------------------------------------- +local default = { + scheme = "dict", + host = "dict.org" +} + +local function there(f) + if f == "" then return nil + else return f end +end + +local function parse(u) + local t = socket.try(url.parse(u, default)) + socket.try(t.scheme == "dict", "invalid scheme '" .. t.scheme .. "'") + socket.try(t.path, "invalid path in url") + local cmd, arg = socket.skip(2, string.find(t.path, "^/(.)(.*)$")) + socket.try(cmd == "d" or cmd == "m", " should be 'm' or 'd'") + socket.try(arg and arg ~= "", "need at least in URL") + t.command, t.argument = cmd, arg + arg = string.gsub(arg, "^:([^:]+)", function(f) t.word = f end) + socket.try(t.word, "need at least in URL") + arg = string.gsub(arg, "^:([^:]*)", function(f) t.database = there(f) end) + if cmd == "m" then + arg = string.gsub(arg, "^:([^:]*)", function(f) t.strat = there(f) end) + end + string.gsub(arg, ":([^:]*)$", function(f) t.n = base.tonumber(f) end) + return t +end + +local function tget(gett) + local con = open(gett.host, gett.port) + con:greet() + if gett.command == "d" then + local def = con:define(gett.database, gett.word) + con:quit() + con:close() + if gett.n then return def[gett.n] + else return def end + elseif gett.command == "m" then + local mat = con:match(gett.database, gett.strat, gett.word) + con:quit() + con:close() + return mat + else return nil, "invalid command" end +end + +local function sget(u) + local gett = parse(u) + return tget(gett) +end + +get = socket.protect(function(gett) + if base.type(gett) == "string" then return sget(gett) + else return tget(gett) end +end) + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/dispatch.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/dispatch.lua new file mode 100644 index 00000000000..3ef1e72b690 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/dispatch.lua @@ -0,0 +1,302 @@ +----------------------------------------------------------------------------- +-- A hacked dispatcher module +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $$ +----------------------------------------------------------------------------- +local base = _G +local table = require("table") +local socket = require("socket") +local coroutine = require("coroutine") +module("dispatch") + +-- if too much time goes by without any activity in one of our sockets, we +-- just kill it +TIMEOUT = 60 + +----------------------------------------------------------------------------- +-- We implement 3 types of dispatchers: +-- sequential +-- coroutine +-- threaded +-- The user can choose whatever one is needed +----------------------------------------------------------------------------- +local handlert = {} + +-- default handler is coroutine +function newhandler(mode) + mode = mode or "coroutine" + return handlert[mode]() +end + +local function seqstart(self, func) + return func() +end + +-- sequential handler simply calls the functions and doesn't wrap I/O +function handlert.sequential() + return { + tcp = socket.tcp, + start = seqstart + } +end + +----------------------------------------------------------------------------- +-- Mega hack. Don't try to do this at home. +----------------------------------------------------------------------------- +-- we can't yield across calls to protect, so we rewrite it with coxpcall +-- make sure you don't require any module that uses socket.protect before +-- loading our hack +function socket.protect(f) + return function(...) + local co = coroutine.create(f) + while true do + local results = {coroutine.resume(co, base.unpack(arg))} + local status = table.remove(results, 1) + if not status then + if type(results[1]) == 'table' then + return nil, results[1][1] + else base.error(results[1]) end + end + if coroutine.status(co) == "suspended" then + arg = {coroutine.yield(base.unpack(results))} + else + return base.unpack(results) + end + end + end +end + +----------------------------------------------------------------------------- +-- Simple set data structure. O(1) everything. +----------------------------------------------------------------------------- +local function newset() + local reverse = {} + local set = {} + return base.setmetatable(set, {__index = { + insert = function(set, value) + if not reverse[value] then + table.insert(set, value) + reverse[value] = table.getn(set) + end + end, + remove = function(set, value) + local index = reverse[value] + if index then + reverse[value] = nil + local top = table.remove(set) + if top ~= value then + reverse[top] = index + set[index] = top + end + end + end + }}) +end + +----------------------------------------------------------------------------- +-- socket.tcp() wrapper for the coroutine dispatcher +----------------------------------------------------------------------------- +local function cowrap(dispatcher, tcp, error) + if not tcp then return nil, error end + -- put it in non-blocking mode right away + tcp:settimeout(0) + -- metatable for wrap produces new methods on demand for those that we + -- don't override explicitly. + local metat = { __index = function(table, key) + table[key] = function(...) + arg[1] = tcp + return tcp[key](base.unpack(arg)) + end + return table[key] + end} + -- does our user want to do his own non-blocking I/O? + local zero = false + -- create a wrap object that will behave just like a real socket object + local wrap = { } + -- we ignore settimeout to preserve our 0 timeout, but record whether + -- the user wants to do his own non-blocking I/O + function wrap:settimeout(value, mode) + if value == 0 then zero = true + else zero = false end + return 1 + end + -- send in non-blocking mode and yield on timeout + function wrap:send(data, first, last) + first = (first or 1) - 1 + local result, error + while true do + -- return control to dispatcher and tell it we want to send + -- if upon return the dispatcher tells us we timed out, + -- return an error to whoever called us + if coroutine.yield(dispatcher.sending, tcp) == "timeout" then + return nil, "timeout" + end + -- try sending + result, error, first = tcp:send(data, first+1, last) + -- if we are done, or there was an unexpected error, + -- break away from loop + if error ~= "timeout" then return result, error, first end + end + end + -- receive in non-blocking mode and yield on timeout + -- or simply return partial read, if user requested timeout = 0 + function wrap:receive(pattern, partial) + local error = "timeout" + local value + while true do + -- return control to dispatcher and tell it we want to receive + -- if upon return the dispatcher tells us we timed out, + -- return an error to whoever called us + if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then + return nil, "timeout" + end + -- try receiving + value, error, partial = tcp:receive(pattern, partial) + -- if we are done, or there was an unexpected error, + -- break away from loop. also, if the user requested + -- zero timeout, return all we got + if (error ~= "timeout") or zero then + return value, error, partial + end + end + end + -- connect in non-blocking mode and yield on timeout + function wrap:connect(host, port) + local result, error = tcp:connect(host, port) + if error == "timeout" then + -- return control to dispatcher. we will be writable when + -- connection succeeds. + -- if upon return the dispatcher tells us we have a + -- timeout, just abort + if coroutine.yield(dispatcher.sending, tcp) == "timeout" then + return nil, "timeout" + end + -- when we come back, check if connection was successful + result, error = tcp:connect(host, port) + if result or error == "already connected" then return 1 + else return nil, "non-blocking connect failed" end + else return result, error end + end + -- accept in non-blocking mode and yield on timeout + function wrap:accept() + while 1 do + -- return control to dispatcher. we will be readable when a + -- connection arrives. + -- if upon return the dispatcher tells us we have a + -- timeout, just abort + if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then + return nil, "timeout" + end + local client, error = tcp:accept() + if error ~= "timeout" then + return cowrap(dispatcher, client, error) + end + end + end + -- remove cortn from context + function wrap:close() + dispatcher.stamp[tcp] = nil + dispatcher.sending.set:remove(tcp) + dispatcher.sending.cortn[tcp] = nil + dispatcher.receiving.set:remove(tcp) + dispatcher.receiving.cortn[tcp] = nil + return tcp:close() + end + return base.setmetatable(wrap, metat) +end + + +----------------------------------------------------------------------------- +-- Our coroutine dispatcher +----------------------------------------------------------------------------- +local cometat = { __index = {} } + +function schedule(cortn, status, operation, tcp) + if status then + if cortn and operation then + operation.set:insert(tcp) + operation.cortn[tcp] = cortn + operation.stamp[tcp] = socket.gettime() + end + else base.error(operation) end +end + +function kick(operation, tcp) + operation.cortn[tcp] = nil + operation.set:remove(tcp) +end + +function wakeup(operation, tcp) + local cortn = operation.cortn[tcp] + -- if cortn is still valid, wake it up + if cortn then + kick(operation, tcp) + return cortn, coroutine.resume(cortn) + -- othrewise, just get scheduler not to do anything + else + return nil, true + end +end + +function abort(operation, tcp) + local cortn = operation.cortn[tcp] + if cortn then + kick(operation, tcp) + coroutine.resume(cortn, "timeout") + end +end + +-- step through all active cortns +function cometat.__index:step() + -- check which sockets are interesting and act on them + local readable, writable = socket.select(self.receiving.set, + self.sending.set, 1) + -- for all readable connections, resume their cortns and reschedule + -- when they yield back to us + for _, tcp in base.ipairs(readable) do + schedule(wakeup(self.receiving, tcp)) + end + -- for all writable connections, do the same + for _, tcp in base.ipairs(writable) do + schedule(wakeup(self.sending, tcp)) + end + -- politely ask replacement I/O functions in idle cortns to + -- return reporting a timeout + local now = socket.gettime() + for tcp, stamp in base.pairs(self.stamp) do + if tcp.class == "tcp{client}" and now - stamp > TIMEOUT then + abort(self.sending, tcp) + abort(self.receiving, tcp) + end + end +end + +function cometat.__index:start(func) + local cortn = coroutine.create(func) + schedule(cortn, coroutine.resume(cortn)) +end + +function handlert.coroutine() + local stamp = {} + local dispatcher = { + stamp = stamp, + sending = { + name = "sending", + set = newset(), + cortn = {}, + stamp = stamp + }, + receiving = { + name = "receiving", + set = newset(), + cortn = {}, + stamp = stamp + }, + } + function dispatcher.tcp() + return cowrap(dispatcher, socket.tcp()) + end + return base.setmetatable(dispatcher, cometat) +end + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/eol.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/eol.lua new file mode 100644 index 00000000000..b90be79d8f9 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/eol.lua @@ -0,0 +1,14 @@ +----------------------------------------------------------------------------- +-- Little program to adjust end of line markers. +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: eol.lua,v 1.8 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- +local mime = require("mime") +local ltn12 = require("ltn12") +local marker = '\n' +if arg and arg[1] == '-d' then marker = '\r\n' end +local filter = mime.normalize(marker) +local source = ltn12.source.chain(ltn12.source.file(io.stdin), filter) +local sink = ltn12.sink.file(io.stdout) +ltn12.pump.all(source, sink) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/forward.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/forward.lua new file mode 100644 index 00000000000..9073ac4d0fa --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/forward.lua @@ -0,0 +1,65 @@ +-- load our favourite library +local dispatch = require("dispatch") +local handler = dispatch.newhandler() + +-- make sure the user knows how to invoke us +if table.getn(arg) < 1 then + print("Usage") + print(" lua forward.lua ...") + os.exit(1) +end + +-- function to move data from one socket to the other +local function move(foo, bar) + local live + while 1 do + local data, error, partial = foo:receive(2048) + live = data or error == "timeout" + data = data or partial + local result, error = bar:send(data) + if not live or not result then + foo:close() + bar:close() + break + end + end +end + +-- for each tunnel, start a new server +for i, v in ipairs(arg) do + -- capture forwarding parameters + local _, _, iport, ohost, oport = string.find(v, "([^:]+):([^:]+):([^:]+)") + assert(iport, "invalid arguments") + -- create our server socket + local server = assert(handler.tcp()) + assert(server:setoption("reuseaddr", true)) + assert(server:bind("*", iport)) + assert(server:listen(32)) + -- handler for the server object loops accepting new connections + handler:start(function() + while 1 do + local client = assert(server:accept()) + assert(client:settimeout(0)) + -- for each new connection, start a new client handler + handler:start(function() + -- handler tries to connect to peer + local peer = assert(handler.tcp()) + assert(peer:settimeout(0)) + assert(peer:connect(ohost, oport)) + -- if sucessful, starts a new handler to send data from + -- client to peer + handler:start(function() + move(client, peer) + end) + -- afte starting new handler, enter in loop sending data from + -- peer to client + move(peer, client) + end) + end + end) +end + +-- simply loop stepping the server +while 1 do + handler:step() +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/get.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/get.lua new file mode 100644 index 00000000000..3df6a451262 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/get.lua @@ -0,0 +1,142 @@ +----------------------------------------------------------------------------- +-- Little program to download files from URLs +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: get.lua,v 1.25 2007/03/12 04:08:40 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +local http = require("socket.http") +local ftp = require("socket.ftp") +local url = require("socket.url") +local ltn12 = require("ltn12") + +-- formats a number of seconds into human readable form +function nicetime(s) + local l = "s" + if s > 60 then + s = s / 60 + l = "m" + if s > 60 then + s = s / 60 + l = "h" + if s > 24 then + s = s / 24 + l = "d" -- hmmm + end + end + end + if l == "s" then return string.format("%5.0f%s", s, l) + else return string.format("%5.2f%s", s, l) end +end + +-- formats a number of bytes into human readable form +function nicesize(b) + local l = "B" + if b > 1024 then + b = b / 1024 + l = "KB" + if b > 1024 then + b = b / 1024 + l = "MB" + if b > 1024 then + b = b / 1024 + l = "GB" -- hmmm + end + end + end + return string.format("%7.2f%2s", b, l) +end + +-- returns a string with the current state of the download +local remaining_s = "%s received, %s/s throughput, %2.0f%% done, %s remaining" +local elapsed_s = "%s received, %s/s throughput, %s elapsed " +function gauge(got, delta, size) + local rate = got / delta + if size and size >= 1 then + return string.format(remaining_s, nicesize(got), nicesize(rate), + 100*got/size, nicetime((size-got)/rate)) + else + return string.format(elapsed_s, nicesize(got), + nicesize(rate), nicetime(delta)) + end +end + +-- creates a new instance of a receive_cb that saves to disk +-- kind of copied from luasocket's manual callback examples +function stats(size) + local start = socket.gettime() + local last = start + local got = 0 + return function(chunk) + -- elapsed time since start + local current = socket.gettime() + if chunk then + -- total bytes received + got = got + string.len(chunk) + -- not enough time for estimate + if current - last > 1 then + io.stderr:write("\r", gauge(got, current - start, size)) + io.stderr:flush() + last = current + end + else + -- close up + io.stderr:write("\r", gauge(got, current - start), "\n") + end + return chunk + end +end + +-- determines the size of a http file +function gethttpsize(u) + local r, c, h = http.request {method = "HEAD", url = u} + if c == 200 then + return tonumber(h["content-length"]) + end +end + +-- downloads a file using the http protocol +function getbyhttp(u, file) + local save = ltn12.sink.file(file or io.stdout) + -- only print feedback if output is not stdout + if file then save = ltn12.sink.chain(stats(gethttpsize(u)), save) end + local r, c, h, s = http.request {url = u, sink = save } + if c ~= 200 then io.stderr:write(s or c, "\n") end +end + +-- downloads a file using the ftp protocol +function getbyftp(u, file) + local save = ltn12.sink.file(file or io.stdout) + -- only print feedback if output is not stdout + -- and we don't know how big the file is + if file then save = ltn12.sink.chain(stats(), save) end + local gett = url.parse(u) + gett.sink = save + gett.type = "i" + local ret, err = ftp.get(gett) + if err then print(err) end +end + +-- determines the scheme +function getscheme(u) + -- this is an heuristic to solve a common invalid url poblem + if not string.find(u, "//") then u = "//" .. u end + local parsed = url.parse(u, {scheme = "http"}) + return parsed.scheme +end + +-- gets a file either by http or ftp, saving as +function get(u, name) + local fout = name and io.open(name, "wb") + local scheme = getscheme(u) + if scheme == "ftp" then getbyftp(u, fout) + elseif scheme == "http" then getbyhttp(u, fout) + else print("unknown scheme" .. scheme) end +end + +-- main program +arg = arg or {} +if table.getn(arg) < 1 then + io.write("Usage:\n lua get.lua []\n") + os.exit(1) +else get(arg[1], arg[2]) end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/lp.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/lp.lua new file mode 100644 index 00000000000..32699209c6b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/lp.lua @@ -0,0 +1,324 @@ +----------------------------------------------------------------------------- +-- LPD support for the Lua language +-- LuaSocket toolkit. +-- Author: David Burgess +-- Modified by Diego Nehab, but David is in charge +-- RCS ID: $Id: lp.lua,v 1.14 2005/11/21 07:04:44 diego Exp $ +----------------------------------------------------------------------------- +--[[ + if you have any questions: RFC 1179 +]] +-- make sure LuaSocket is loaded +local io = require("io") +local base = _G +local os = require("os") +local math = require("math") +local string = require("string") +local socket = require("socket") +local ltn12 = require("ltn12") +module("socket.lp") + +-- default port +PORT = 515 +SERVER = os.getenv("SERVER_NAME") or os.getenv("COMPUTERNAME") or "localhost" +PRINTER = os.getenv("PRINTER") or "printer" + +local function connect(localhost, option) + local host = option.host or SERVER + local port = option.port or PORT + local skt + local try = socket.newtry(function() if skt then skt:close() end end) + if option.localbind then + -- bind to a local port (if we can) + local localport = 721 + local done, err + repeat + skt = socket.try(socket.tcp()) + try(skt:settimeout(30)) + done, err = skt:bind(localhost, localport) + if not done then + localport = localport + 1 + skt:close() + skt = nil + else break end + until localport > 731 + socket.try(skt, err) + else skt = socket.try(socket.tcp()) end + try(skt:connect(host, port)) + return { skt = skt, try = try } +end + +--[[ +RFC 1179 +5.3 03 - Send queue state (short) + + +----+-------+----+------+----+ + | 03 | Queue | SP | List | LF | + +----+-------+----+------+----+ + Command code - 3 + Operand 1 - Printer queue name + Other operands - User names or job numbers + + If the user names or job numbers or both are supplied then only those + jobs for those users or with those numbers will be sent. + + The response is an ASCII stream which describes the printer queue. + The stream continues until the connection closes. Ends of lines are + indicated with ASCII LF control characters. The lines may also + contain ASCII HT control characters. + +5.4 04 - Send queue state (long) + + +----+-------+----+------+----+ + | 04 | Queue | SP | List | LF | + +----+-------+----+------+----+ + Command code - 4 + Operand 1 - Printer queue name + Other operands - User names or job numbers + + If the user names or job numbers or both are supplied then only those + jobs for those users or with those numbers will be sent. + + The response is an ASCII stream which describes the printer queue. + The stream continues until the connection closes. Ends of lines are + indicated with ASCII LF control characters. The lines may also + contain ASCII HT control characters. +]] + +-- gets server acknowledement +local function recv_ack(con) + local ack = con.skt:receive(1) + con.try(string.char(0) == ack, "failed to receive server acknowledgement") +end + +-- sends client acknowledement +local function send_ack(con) + local sent = con.skt:send(string.char(0)) + con.try(sent == 1, "failed to send acknowledgement") +end + +-- sends queue request +-- 5.2 02 - Receive a printer job +-- +-- +----+-------+----+ +-- | 02 | Queue | LF | +-- +----+-------+----+ +-- Command code - 2 +-- Operand - Printer queue name +-- +-- Receiving a job is controlled by a second level of commands. The +-- daemon is given commands by sending them over the same connection. +-- The commands are described in the next section (6). +-- +-- After this command is sent, the client must read an acknowledgement +-- octet from the daemon. A positive acknowledgement is an octet of +-- zero bits. A negative acknowledgement is an octet of any other +-- pattern. +local function send_queue(con, queue) + queue = queue or PRINTER + local str = string.format("\2%s\10", queue) + local sent = con.skt:send(str) + con.try(sent == string.len(str), "failed to send print request") + recv_ack(con) +end + +-- sends control file +-- 6.2 02 - Receive control file +-- +-- +----+-------+----+------+----+ +-- | 02 | Count | SP | Name | LF | +-- +----+-------+----+------+----+ +-- Command code - 2 +-- Operand 1 - Number of bytes in control file +-- Operand 2 - Name of control file +-- +-- The control file must be an ASCII stream with the ends of lines +-- indicated by ASCII LF. The total number of bytes in the stream is +-- sent as the first operand. The name of the control file is sent as +-- the second. It should start with ASCII "cfA", followed by a three +-- digit job number, followed by the host name which has constructed the +-- control file. Acknowledgement processing must occur as usual after +-- the command is sent. +-- +-- The next "Operand 1" octets over the same TCP connection are the +-- intended contents of the control file. Once all of the contents have +-- been delivered, an octet of zero bits is sent as an indication that +-- the file being sent is complete. A second level of acknowledgement +-- processing must occur at this point. + +-- sends data file +-- 6.3 03 - Receive data file +-- +-- +----+-------+----+------+----+ +-- | 03 | Count | SP | Name | LF | +-- +----+-------+----+------+----+ +-- Command code - 3 +-- Operand 1 - Number of bytes in data file +-- Operand 2 - Name of data file +-- +-- The data file may contain any 8 bit values at all. The total number +-- of bytes in the stream may be sent as the first operand, otherwise +-- the field should be cleared to 0. The name of the data file should +-- start with ASCII "dfA". This should be followed by a three digit job +-- number. The job number should be followed by the host name which has +-- constructed the data file. Interpretation of the contents of the +-- data file is determined by the contents of the corresponding control +-- file. If a data file length has been specified, the next "Operand 1" +-- octets over the same TCP connection are the intended contents of the +-- data file. In this case, once all of the contents have been +-- delivered, an octet of zero bits is sent as an indication that the +-- file being sent is complete. A second level of acknowledgement +-- processing must occur at this point. + + +local function send_hdr(con, control) + local sent = con.skt:send(control) + con.try(sent and sent >= 1 , "failed to send header file") + recv_ack(con) +end + +local function send_control(con, control) + local sent = con.skt:send(control) + con.try(sent and sent >= 1, "failed to send control file") + send_ack(con) +end + +local function send_data(con,fh,size) + local buf + while size > 0 do + buf,message = fh:read(8192) + if buf then + st = con.try(con.skt:send(buf)) + size = size - st + else + con.try(size == 0, "file size mismatch") + end + end + recv_ack(con) -- note the double acknowledgement + send_ack(con) + recv_ack(con) + return size +end + + +--[[ +local control_dflt = { + "H"..string.sub(socket.hostname,1,31).."\10", -- host + "C"..string.sub(socket.hostname,1,31).."\10", -- class + "J"..string.sub(filename,1,99).."\10", -- jobname + "L"..string.sub(user,1,31).."\10", -- print banner page + "I"..tonumber(indent).."\10", -- indent column count ('f' only) + "M"..string.sub(mail,1,128).."\10", -- mail when printed user@host + "N"..string.sub(filename,1,131).."\10", -- name of source file + "P"..string.sub(user,1,31).."\10", -- user name + "T"..string.sub(title,1,79).."\10", -- title for banner ('p' only) + "W"..tonumber(width or 132).."\10", -- width of print f,l,p only + + "f"..file.."\10", -- formatted print (remove control chars) + "l"..file.."\10", -- print + "o"..file.."\10", -- postscript + "p"..file.."\10", -- pr format - requires T, L + "r"..file.."\10", -- fortran format + "U"..file.."\10", -- Unlink (data file only) +} +]] + +-- generate a varying job number +local seq = 0 +local function newjob(connection) + seq = seq + 1 + return math.floor(socket.gettime() * 1000 + seq)%1000 +end + + +local format_codes = { + binary = 'l', + text = 'f', + ps = 'o', + pr = 'p', + fortran = 'r', + l = 'l', + r = 'r', + o = 'o', + p = 'p', + f = 'f' +} + +-- lp.send{option} +-- requires option.file + +send = socket.protect(function(option) + socket.try(option and base.type(option) == "table", "invalid options") + local file = option.file + socket.try(file, "invalid file name") + local fh = socket.try(io.open(file,"rb")) + local datafile_size = fh:seek("end") -- get total size + fh:seek("set") -- go back to start of file + local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME") + or "localhost" + local con = connect(localhost, option) +-- format the control file + local jobno = newjob() + local localip = socket.dns.toip(localhost) + localhost = string.sub(localhost,1,31) + local user = string.sub(option.user or os.getenv("LPRUSER") or + os.getenv("USERNAME") or os.getenv("USER") or "anonymous", 1,31) + local lpfile = string.format("dfA%3.3d%-s", jobno, localhost); + local fmt = format_codes[option.format] or 'l' + local class = string.sub(option.class or localip or localhost,1,31) + local _,_,ctlfn = string.find(file,".*[%/%\\](.*)") + ctlfn = string.sub(ctlfn or file,1,131) + local cfile = + string.format("H%-s\nC%-s\nJ%-s\nP%-s\n%.1s%-s\nU%-s\nN%-s\n", + localhost, + class, + option.job or "LuaSocket", + user, + fmt, lpfile, + lpfile, + ctlfn); -- mandatory part of ctl file + if (option.banner) then cfile = cfile .. 'L'..user..'\10' end + if (option.indent) then cfile = cfile .. 'I'..base.tonumber(option.indent)..'\10' end + if (option.mail) then cfile = cfile .. 'M'..string.sub((option.mail),1,128)..'\10' end + if (fmt == 'p' and option.title) then cfile = cfile .. 'T'..string.sub((option.title),1,79)..'\10' end + if ((fmt == 'p' or fmt == 'l' or fmt == 'f') and option.width) then + cfile = cfile .. 'W'..base.tonumber(option,width)..'\10' + end + + con.skt:settimeout(option.timeout or 65) +-- send the queue header + send_queue(con, option.queue) +-- send the control file header + local cfilecmd = string.format("\2%d cfA%3.3d%-s\n",string.len(cfile), jobno, localhost); + send_hdr(con,cfilecmd) + +-- send the control file + send_control(con,cfile) + +-- send the data file header + local dfilecmd = string.format("\3%d dfA%3.3d%-s\n",datafile_size, jobno, localhost); + send_hdr(con,dfilecmd) + +-- send the data file + send_data(con,fh,datafile_size) + fh:close() + con.skt:close(); + return jobno, datafile_size +end) + +-- +-- lp.query({host=,queue=printer|'*', format='l'|'s', list=}) +-- +query = socket.protect(function(p) + p = p or {} + local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME") + or "localhost" + local con = connect(localhost,p) + local fmt + if string.sub(p.format or 's',1,1) == 's' then fmt = 3 else fmt = 4 end + con.try(con.skt:send(string.format("%c%s %s\n", fmt, p.queue or "*", + p.list or ""))) + local data = con.try(con.skt:receive("*a")) + con.skt:close() + return data +end) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/qp.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/qp.lua new file mode 100644 index 00000000000..a4c0cad5933 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/qp.lua @@ -0,0 +1,24 @@ +----------------------------------------------------------------------------- +-- Little program to convert to and from Quoted-Printable +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: qp.lua,v 1.5 2004/06/17 21:46:22 diego Exp $ +----------------------------------------------------------------------------- +local ltn12 = require("ltn12") +local mime = require("mime") +local convert +arg = arg or {} +local mode = arg and arg[1] or "-et" +if mode == "-et" then + local normalize = mime.normalize() + local qp = mime.encode("quoted-printable") + local wrap = mime.wrap("quoted-printable") + convert = ltn12.filter.chain(normalize, qp, wrap) +elseif mode == "-eb" then + local qp = mime.encode("quoted-printable", "binary") + local wrap = mime.wrap("quoted-printable") + convert = ltn12.filter.chain(qp, wrap) +else convert = mime.decode("quoted-printable") end +local source = ltn12.source.chain(ltn12.source.file(io.stdin), convert) +local sink = ltn12.sink.file(io.stdout) +ltn12.pump.all(source, sink) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/etc/tftp.lua b/Build/source/texk/web2c/luatexdir/luasocket/etc/tftp.lua new file mode 100644 index 00000000000..94eaf3424d8 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/etc/tftp.lua @@ -0,0 +1,155 @@ +----------------------------------------------------------------------------- +-- TFTP support for the Lua language +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: tftp.lua,v 1.16 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Load required files +----------------------------------------------------------------------------- +local base = _G +local table = require("table") +local math = require("math") +local string = require("string") +local socket = require("socket") +local ltn12 = require("ltn12") +local url = require("socket.url") +module("socket.tftp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +local char = string.char +local byte = string.byte + +PORT = 69 +local OP_RRQ = 1 +local OP_WRQ = 2 +local OP_DATA = 3 +local OP_ACK = 4 +local OP_ERROR = 5 +local OP_INV = {"RRQ", "WRQ", "DATA", "ACK", "ERROR"} + +----------------------------------------------------------------------------- +-- Packet creation functions +----------------------------------------------------------------------------- +local function RRQ(source, mode) + return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) +end + +local function WRQ(source, mode) + return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) +end + +local function ACK(block) + local low, high + low = math.mod(block, 256) + high = (block - low)/256 + return char(0, OP_ACK, high, low) +end + +local function get_OP(dgram) + local op = byte(dgram, 1)*256 + byte(dgram, 2) + return op +end + +----------------------------------------------------------------------------- +-- Packet analysis functions +----------------------------------------------------------------------------- +local function split_DATA(dgram) + local block = byte(dgram, 3)*256 + byte(dgram, 4) + local data = string.sub(dgram, 5) + return block, data +end + +local function get_ERROR(dgram) + local code = byte(dgram, 3)*256 + byte(dgram, 4) + local msg + _,_, msg = string.find(dgram, "(.*)\000", 5) + return string.format("error code %d: %s", code, msg) +end + +----------------------------------------------------------------------------- +-- The real work +----------------------------------------------------------------------------- +local function tget(gett) + local retries, dgram, sent, datahost, dataport, code + local last = 0 + socket.try(gett.host, "missing host") + local con = socket.try(socket.udp()) + local try = socket.newtry(function() con:close() end) + -- convert from name to ip if needed + gett.host = try(socket.dns.toip(gett.host)) + con:settimeout(1) + -- first packet gives data host/port to be used for data transfers + local path = string.gsub(gett.path or "", "^/", "") + path = url.unescape(path) + retries = 0 + repeat + sent = try(con:sendto(RRQ(path, "octet"), gett.host, gett.port)) + dgram, datahost, dataport = con:receivefrom() + retries = retries + 1 + until dgram or datahost ~= "timeout" or retries > 5 + try(dgram, datahost) + -- associate socket with data host/port + try(con:setpeername(datahost, dataport)) + -- default sink + local sink = gett.sink or ltn12.sink.null() + -- process all data packets + while 1 do + -- decode packet + code = get_OP(dgram) + try(code ~= OP_ERROR, get_ERROR(dgram)) + try(code == OP_DATA, "unhandled opcode " .. code) + -- get data packet parts + local block, data = split_DATA(dgram) + -- if not repeated, write + if block == last+1 then + try(sink(data)) + last = block + end + -- last packet brings less than 512 bytes of data + if string.len(data) < 512 then + try(con:send(ACK(block))) + try(con:close()) + try(sink(nil)) + return 1 + end + -- get the next packet + retries = 0 + repeat + sent = try(con:send(ACK(last))) + dgram, err = con:receive() + retries = retries + 1 + until dgram or err ~= "timeout" or retries > 5 + try(dgram, err) + end +end + +local default = { + port = PORT, + path ="/", + scheme = "tftp" +} + +local function parse(u) + local t = socket.try(url.parse(u, default)) + socket.try(t.scheme == "tftp", "invalid scheme '" .. t.scheme .. "'") + socket.try(t.host, "invalid host") + return t +end + +local function sget(u) + local gett = parse(u) + local t = {} + gett.sink = ltn12.sink.table(t) + tget(gett) + return table.concat(t) +end + +get = socket.protect(function(gett) + if base.type(gett) == "string" then return sget(gett) + else return tget(gett) end +end) + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/luasocket.sln b/Build/source/texk/web2c/luatexdir/luasocket/luasocket.sln new file mode 100644 index 00000000000..a674c33caab --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/luasocket.sln @@ -0,0 +1,37 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socket", "socket.vcproj", "{66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mime", "mime.vcproj", "{128E8BD0-174A-48F0-8771-92B1E8D18713}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libluasocket", "libluasocket.vcproj", "{599EAD40-60EE-4043-9C14-AE090A8A092D}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug.ActiveCfg = Debug|Win32 + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug.Build.0 = Debug|Win32 + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release.ActiveCfg = Release|Win32 + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release.Build.0 = Release|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug.ActiveCfg = Debug|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug.Build.0 = Debug|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release.ActiveCfg = Release|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release.Build.0 = Release|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Debug.ActiveCfg = Debug|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Debug.Build.0 = Debug|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Release.ActiveCfg = Release|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/Build/source/texk/web2c/luatexdir/luasocket/makefile b/Build/source/texk/web2c/luatexdir/luasocket/makefile new file mode 100644 index 00000000000..6d700392a0a --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/makefile @@ -0,0 +1,51 @@ +#------ +# Load configuration +# +include config + +#------ +# Hopefully no need to change anything below this line +# +INSTALL_SOCKET_SHARE=$(INSTALL_TOP_SHARE)/socket +INSTALL_SOCKET_LIB=$(INSTALL_TOP_LIB)/socket +INSTALL_MIME_SHARE=$(INSTALL_TOP_SHARE)/mime +INSTALL_MIME_LIB=$(INSTALL_TOP_LIB)/mime + +all clean: + cd src; $(MAKE) $@ + +#------ +# Files to install +# +TO_SOCKET_SHARE:= \ + http.lua \ + url.lua \ + tp.lua \ + ftp.lua \ + smtp.lua + +TO_TOP_SHARE:= \ + ltn12.lua \ + socket.lua \ + mime.lua + +TO_MIME_SHARE:= + +#------ +# Install LuaSocket according to recommendation +# +install: all + cd src; mkdir -p $(INSTALL_TOP_SHARE) + cd src; $(INSTALL_DATA) $(TO_TOP_SHARE) $(INSTALL_TOP_SHARE) + cd src; mkdir -p $(INSTALL_SOCKET_SHARE) + cd src; $(INSTALL_DATA) $(TO_SOCKET_SHARE) $(INSTALL_SOCKET_SHARE) + cd src; mkdir -p $(INSTALL_SOCKET_LIB) + cd src; $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(EXT) + #cd src; mkdir -p $(INSTALL_MIME_SHARE) + #cd src; $(INSTALL_DATA) $(TO_MIME_SHARE) $(INSTALL_MIME_SHARE) + cd src; mkdir -p $(INSTALL_MIME_LIB) + cd src; $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(EXT) + +#------ +# End of makefile +# diff --git a/Build/source/texk/web2c/luatexdir/luasocket/mime.vcproj b/Build/source/texk/web2c/luatexdir/luasocket/mime.vcproj new file mode 100644 index 00000000000..8ad790040ba --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/mime.vcproj @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/README b/Build/source/texk/web2c/luatexdir/luasocket/samples/README new file mode 100644 index 00000000000..e63a6f52147 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/README @@ -0,0 +1,50 @@ +This directory contains some sample programs using +LuaSocket. This code is not supported. + + listener.lua -- socket to stdout + talker.lua -- stdin to socket + +listener.lua and talker.lua are about the simplest +applications you can write using LuaSocket. Run + + 'lua listener.lua' and 'lua talker.lua' + +on different terminals. Whatever you type on talk.lua will +be printed by listen.lua. + + lpr.lua -- lpr client + +This is a cool program written by David Burgess to print +files using the Line Printer Daemon protocol, widely used in +Unix machines. It uses the lp.lua implementation, in the +etc directory. Just run 'lua lpr.lua +queue=' and the file will print! + + cddb.lua -- CDDB client + +This is the first try on a simple CDDB client. Not really +useful, but one day it might become a module. + + daytimeclnt.lua -- day time client + +Just run the program to retrieve the hour and date in +readable form from any server running an UDP daytime daemon. + + echoclnt.lua -- UDP echo client + echosrvr.lua -- UDP echo server + +These are a UDP echo client/server pair. They work with +other client and servers as well. + + tinyirc.lua -- irc like broadcast server + +This is a simple server that waits simultaneously on two +server sockets for telnet connections. Everything it +receives from the telnet clients is broadcasted to every +other connected client. It tests the select function and +shows how to create a simple server whith LuaSocket. Just +run tinyirc.lua and then open as many telnet connections +as you want to ports 8080 and 8081. + +Good luck, +Diego. diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/cddb.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/cddb.lua new file mode 100644 index 00000000000..883730c3a4c --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/cddb.lua @@ -0,0 +1,46 @@ +local socket = require("socket") +local http = require("socket.http") + +if not arg or not arg[1] or not arg[2] then + print("luasocket cddb.lua []") + os.exit(1) +end + +local server = arg[3] or "http://freedb.freedb.org/~cddb/cddb.cgi" + +function parse(body) + local lines = string.gfind(body, "(.-)\r\n") + local status = lines() + local code, message = socket.skip(2, string.find(status, "(%d%d%d) (.*)")) + if tonumber(code) ~= 210 then + return nil, code, message + end + local data = {} + for l in lines do + local c = string.sub(l, 1, 1) + if c ~= '#' and c ~= '.' then + local key, value = socket.skip(2, string.find(l, "(.-)=(.*)")) + value = string.gsub(value, "\\n", "\n") + value = string.gsub(value, "\\\\", "\\") + value = string.gsub(value, "\\t", "\t") + data[key] = value + end + end + return data, code, message +end + +local host = socket.dns.gethostname() +local query = "%s?cmd=cddb+read+%s+%s&hello=LuaSocket+%s+LuaSocket+2.0&proto=6" +local url = string.format(query, server, arg[1], arg[2], host) +local body, headers, code = http.get(url) + +if code == 200 then + local data, code, error = parse(body) + if not data then + print(error or code) + else + for i,v in pairs(data) do + io.write(i, ': ', v, '\n') + end + end +else print(error) end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/daytimeclnt.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/daytimeclnt.lua new file mode 100644 index 00000000000..90ab39e9713 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/daytimeclnt.lua @@ -0,0 +1,23 @@ +----------------------------------------------------------------------------- +-- UDP sample: daytime protocol client +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: daytimeclnt.lua,v 1.11 2004/06/21 06:07:57 diego Exp $ +----------------------------------------------------------------------------- +local socket = require"socket" +host = host or "127.0.0.1" +port = port or 13 +if arg then + host = arg[1] or host + port = arg[2] or port +end +host = socket.dns.toip(host) +udp = socket.udp() +print("Using host '" ..host.. "' and port " ..port.. "...") +udp:setpeername(host, port) +udp:settimeout(3) +sent, err = udp:send("anything") +if err then print(err) os.exit() end +dgram, err = udp:receive() +if not dgram then print(err) os.exit() end +io.write(dgram) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/echoclnt.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/echoclnt.lua new file mode 100644 index 00000000000..038be4c239d --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/echoclnt.lua @@ -0,0 +1,24 @@ +----------------------------------------------------------------------------- +-- UDP sample: echo protocol client +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: echoclnt.lua,v 1.10 2005/01/02 22:44:00 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "localhost" +port = port or 7 +if arg then + host = arg[1] or host + port = arg[2] or port +end +host = socket.dns.toip(host) +udp = assert(socket.udp()) +assert(udp:setpeername(host, port)) +print("Using remote host '" ..host.. "' and port " .. port .. "...") +while 1 do + line = io.read() + if not line or line == "" then os.exit() end + assert(udp:send(line)) + dgram = assert(udp:receive()) + print(dgram) +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/echosrvr.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/echosrvr.lua new file mode 100644 index 00000000000..2697ca46d69 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/echosrvr.lua @@ -0,0 +1,29 @@ +----------------------------------------------------------------------------- +-- UDP sample: echo protocol server +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: echosrvr.lua,v 1.12 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "127.0.0.1" +port = port or 7 +if arg then + host = arg[1] or host + port = arg[2] or port +end +print("Binding to host '" ..host.. "' and port " ..port.. "...") +udp = assert(socket.udp()) +assert(udp:setsockname(host, port)) +assert(udp:settimeout(5)) +ip, port = udp:getsockname() +assert(ip, port) +print("Waiting packets on " .. ip .. ":" .. port .. "...") +while 1 do + dgram, ip, port = udp:receivefrom() + if dgram then + print("Echoing '" .. dgram .. "' to " .. ip .. ":" .. port) + udp:sendto(dgram, ip, port) + else + print(ip) + end +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/listener.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/listener.lua new file mode 100644 index 00000000000..9260fbb0f35 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/listener.lua @@ -0,0 +1,26 @@ +----------------------------------------------------------------------------- +-- TCP sample: Little program to dump lines received at a given port +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: listener.lua,v 1.11 2005/01/02 22:44:00 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "*" +port = port or 8080 +if arg then + host = arg[1] or host + port = arg[2] or port +end +print("Binding to host '" ..host.. "' and port " ..port.. "...") +s = assert(socket.bind(host, port)) +i, p = s:getsockname() +assert(i, p) +print("Waiting connection from talker on " .. i .. ":" .. p .. "...") +c = assert(s:accept()) +print("Connected. Here is the stuff:") +l, e = c:receive() +while not e do + print(l) + l, e = c:receive() +end +print(e) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/lpr.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/lpr.lua new file mode 100644 index 00000000000..2b059b15871 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/lpr.lua @@ -0,0 +1,51 @@ +local lp = require("socket.lp") + +local function usage() + print('\nUsage: lua lpr.lua [filename] [keyword=val...]\n') + print('Valid keywords are :') + print( + ' host=remote host or IP address (default "localhost")\n' .. + ' queue=remote queue or printer name (default "printer")\n' .. + ' port=remote port number (default 515)\n' .. + ' user=sending user name\n' .. + ' format=["binary" | "text" | "ps" | "pr" | "fortran"] (default "binary")\n' .. + ' banner=true|false\n' .. + ' indent=number of columns to indent\n' .. + ' mail=email of address to notify when print is complete\n' .. + ' title=title to use for "pr" format\n' .. + ' width=width for "text" or "pr" formats\n' .. + ' class=\n' .. + ' job=\n' .. + ' name=\n' .. + ' localbind=true|false\n' + ) + return nil +end + +if not arg or not arg[1] then + return usage() +end + +do + local opt = {} + local pat = "[%s%c%p]*([%w]*)=([\"]?[%w%s_!@#$%%^&*()<>:;]+[\"]\?\.?)" + for i = 2, table.getn(arg), 1 do + string.gsub(arg[i], pat, function(name, value) opt[name] = value end) + end + if not arg[2] then + return usage() + end + if arg[1] ~= "query" then + opt.file = arg[1] + r,e=lp.send(opt) + io.stdout:write(tostring(r or e),'\n') + else + r,e=lp.query(opt) + io.stdout:write(tostring(r or e), '\n') + end +end + +-- trivial tests +--lua lp.lua lp.lua queue=default host=localhost +--lua lp.lua lp.lua queue=default host=localhost format=binary localbind=1 +--lua lp.lua query queue=default host=localhost diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/talker.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/talker.lua new file mode 100644 index 00000000000..607ff31989b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/talker.lua @@ -0,0 +1,21 @@ +----------------------------------------------------------------------------- +-- TCP sample: Little program to send text lines to a given host/port +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: talker.lua,v 1.9 2005/01/02 22:44:00 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "localhost" +port = port or 8080 +if arg then + host = arg[1] or host + port = arg[2] or port +end +print("Attempting connection to host '" ..host.. "' and port " ..port.. "...") +c = assert(socket.connect(host, port)) +print("Connected! Please type stuff (empty line to stop):") +l = io.read() +while l and l ~= "" and not e do + assert(c:send(l .. "\n")) + l = io.read() +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/samples/tinyirc.lua b/Build/source/texk/web2c/luatexdir/luasocket/samples/tinyirc.lua new file mode 100644 index 00000000000..f474302e0a2 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/samples/tinyirc.lua @@ -0,0 +1,90 @@ +----------------------------------------------------------------------------- +-- Select sample: simple text line server +-- LuaSocket sample files. +-- Author: Diego Nehab +-- RCS ID: $Id: tinyirc.lua,v 1.14 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "*" +port1 = port1 or 8080 +port2 = port2 or 8181 +if arg then + host = arg[1] or host + port1 = arg[2] or port1 + port2 = arg[3] or port2 +end + +server1 = assert(socket.bind(host, port1)) +server2 = assert(socket.bind(host, port2)) +server1:settimeout(1) -- make sure we don't block in accept +server2:settimeout(1) + +io.write("Servers bound\n") + +-- simple set implementation +-- the select function doesn't care about what is passed to it as long as +-- it behaves like a table +-- creates a new set data structure +function newset() + local reverse = {} + local set = {} + return setmetatable(set, {__index = { + insert = function(set, value) + if not reverse[value] then + table.insert(set, value) + reverse[value] = table.getn(set) + end + end, + remove = function(set, value) + local index = reverse[value] + if index then + reverse[value] = nil + local top = table.remove(set) + if top ~= value then + reverse[top] = index + set[index] = top + end + end + end + }}) +end + +set = newset() + +io.write("Inserting servers in set\n") +set:insert(server1) +set:insert(server2) + +while 1 do + local readable, _, error = socket.select(set, nil) + for _, input in ipairs(readable) do + -- is it a server socket? + if input == server1 or input == server2 then + io.write("Waiting for clients\n") + local new = input:accept() + if new then + new:settimeout(1) + io.write("Inserting client in set\n") + set:insert(new) + end + -- it is a client socket + else + local line, error = input:receive() + if error then + input:close() + io.write("Removing client from set\n") + set:remove(input) + else + io.write("Broadcasting line '", line, "'\n") + writable, error = socket.skip(1, socket.select(nil, set, 1)) + if not error then + for __, output in ipairs(writable) do + if output ~= input then + output:send(line .. "\n") + end + end + else io.write("No client ready to receive!!!\n") end + end + end + end +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/socket.vcproj b/Build/source/texk/web2c/luatexdir/luasocket/socket.vcproj new file mode 100644 index 00000000000..b7c4a083297 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/socket.vcproj @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/Makefile b/Build/source/texk/web2c/luatexdir/luasocket/src/Makefile new file mode 100644 index 00000000000..f42d62047c5 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/Makefile @@ -0,0 +1,63 @@ + +SOCKET_SO=socket.a + +INSTALL_TOP_SHARE=/usr/local/share/lua/5.1 +INSTALL_TOP_LIB=/usr/local/lib/lua/5.1 + +LUAINC = -I../../lua51 + +DEF = -DLUASOCKET_DEBUG +CFLAGS = $(LUAINC) $(DEF) $(XCFLAGS) +AR=ar +ARFLAGS=rc + +SOCKET_OBJS:= \ + luasocket.o \ + timeout.o \ + buffer.o \ + io.o \ + auxiliar.o \ + options.o \ + inet.o \ + tcp.o \ + udp.o \ + except.o \ + select.o \ + socket.o \ + mime.o \ + lua_preload.o + +all: $(SOCKET_SO) + +$(SOCKET_SO): $(SOCKET_OBJS) + $(AR) $(ARFLAGS) $@ $(SOCKET_OBJS) + +#------ +# List of dependencies +# +auxiliar.o: auxiliar.c auxiliar.h +buffer.o: buffer.c buffer.h io.h timeout.h +except.o: except.c except.h +inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h +io.o: io.c io.h timeout.h +luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \ + buffer.h io.h inet.h socket.h usocket.h tcp.h udp.h select.h +mime.o: mime.c mime.h +options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \ + usocket.h inet.h +select.o: select.c socket.h io.h timeout.h usocket.h select.h +tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ + options.h tcp.h buffer.h +timeout.o: timeout.c auxiliar.h timeout.h +udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ + options.h udp.h +unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h options.h \ + unix.h buffer.h +usocket.o: usocket.c socket.h io.h timeout.h usocket.h + +clean: + rm -f $(SOCKET_SO) $(SOCKET_OBJS) + +#------ +# End of makefile configuration +# diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.c b/Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.c new file mode 100644 index 00000000000..9514970119f --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.c @@ -0,0 +1,149 @@ +/*=========================================================================*\ +* Auxiliar routines for class hierarchy manipulation +* LuaSocket toolkit +* +* RCS ID: $Id: auxiliar.c,v 1.14 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include +#include + +#include "auxiliar.h" + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes the module +\*-------------------------------------------------------------------------*/ +int auxiliar_open(lua_State *L) { + (void) L; + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Creates a new class with given methods +* Methods whose names start with __ are passed directly to the metatable. +\*-------------------------------------------------------------------------*/ +void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func) { + luaL_newmetatable(L, classname); /* mt */ + /* create __index table to place methods */ + lua_pushstring(L, "__index"); /* mt,"__index" */ + lua_newtable(L); /* mt,"__index",it */ + /* put class name into class metatable */ + lua_pushstring(L, "class"); /* mt,"__index",it,"class" */ + lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */ + lua_rawset(L, -3); /* mt,"__index",it */ + /* pass all methods that start with _ to the metatable, and all others + * to the index table */ + for (; func->name; func++) { /* mt,"__index",it */ + lua_pushstring(L, func->name); + lua_pushcfunction(L, func->func); + lua_rawset(L, func->name[0] == '_' ? -5: -3); + } + lua_rawset(L, -3); /* mt */ + lua_pop(L, 1); +} + +/*-------------------------------------------------------------------------*\ +* Prints the value of a class in a nice way +\*-------------------------------------------------------------------------*/ +int auxiliar_tostring(lua_State *L) { + char buf[32]; + if (!lua_getmetatable(L, 1)) goto error; + lua_pushstring(L, "__index"); + lua_gettable(L, -2); + if (!lua_istable(L, -1)) goto error; + lua_pushstring(L, "class"); + lua_gettable(L, -2); + if (!lua_isstring(L, -1)) goto error; + sprintf(buf, "%p", lua_touserdata(L, 1)); + lua_pushfstring(L, "%s: %s", lua_tostring(L, -1), buf); + return 1; +error: + lua_pushstring(L, "invalid object passed to 'auxiliar.c:__tostring'"); + lua_error(L); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Insert class into group +\*-------------------------------------------------------------------------*/ +void auxiliar_add2group(lua_State *L, const char *classname, const char *groupname) { + luaL_getmetatable(L, classname); + lua_pushstring(L, groupname); + lua_pushboolean(L, 1); + lua_rawset(L, -3); + lua_pop(L, 1); +} + +/*-------------------------------------------------------------------------*\ +* Make sure argument is a boolean +\*-------------------------------------------------------------------------*/ +int auxiliar_checkboolean(lua_State *L, int objidx) { + if (!lua_isboolean(L, objidx)) + luaL_typerror(L, objidx, lua_typename(L, LUA_TBOOLEAN)); + return lua_toboolean(L, objidx); +} + +/*-------------------------------------------------------------------------*\ +* Return userdata pointer if object belongs to a given class, abort with +* error otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) { + void *data = auxiliar_getclassudata(L, classname, objidx); + if (!data) { + char msg[45]; + sprintf(msg, "%.35s expected", classname); + luaL_argerror(L, objidx, msg); + } + return data; +} + +/*-------------------------------------------------------------------------*\ +* Return userdata pointer if object belongs to a given group, abort with +* error otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx) { + void *data = auxiliar_getgroupudata(L, groupname, objidx); + if (!data) { + char msg[45]; + sprintf(msg, "%.35s expected", groupname); + luaL_argerror(L, objidx, msg); + } + return data; +} + +/*-------------------------------------------------------------------------*\ +* Set object class +\*-------------------------------------------------------------------------*/ +void auxiliar_setclass(lua_State *L, const char *classname, int objidx) { + luaL_getmetatable(L, classname); + if (objidx < 0) objidx--; + lua_setmetatable(L, objidx); +} + +/*-------------------------------------------------------------------------*\ +* Get a userdata pointer if object belongs to a given group. Return NULL +* otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) { + if (!lua_getmetatable(L, objidx)) + return NULL; + lua_pushstring(L, groupname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); + return NULL; + } else { + lua_pop(L, 2); + return lua_touserdata(L, objidx); + } +} + +/*-------------------------------------------------------------------------*\ +* Get a userdata pointer if object belongs to a given class. Return NULL +* otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) { + return luaL_checkudata(L, objidx, classname); +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.h b/Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.h new file mode 100644 index 00000000000..18b849554ff --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/auxiliar.h @@ -0,0 +1,48 @@ +#ifndef AUXILIAR_H +#define AUXILIAR_H +/*=========================================================================*\ +* Auxiliar routines for class hierarchy manipulation +* LuaSocket toolkit (but completely independent of other LuaSocket modules) +* +* A LuaSocket class is a name associated with Lua metatables. A LuaSocket +* group is a name associated with a class. A class can belong to any number +* of groups. This module provides the functionality to: +* +* - create new classes +* - add classes to groups +* - set the class of objects +* - check if an object belongs to a given class or group +* - get the userdata associated to objects +* - print objects in a pretty way +* +* LuaSocket class names follow the convention {}. Modules +* can define any number of classes and groups. The module tcp.c, for +* example, defines the classes tcp{master}, tcp{client} and tcp{server} and +* the groups tcp{client,server} and tcp{any}. Module functions can then +* perform type-checking on their arguments by either class or group. +* +* LuaSocket metatables define the __index metamethod as being a table. This +* table has one field for each method supported by the class, and a field +* "class" with the class name. +* +* The mapping from class name to the corresponding metatable and the +* reverse mapping are done using lauxlib. +* +* RCS ID: $Id: auxiliar.h,v 1.9 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +#include "lua.h" +#include "lauxlib.h" + +int auxiliar_open(lua_State *L); +void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func); +void auxiliar_add2group(lua_State *L, const char *classname, const char *group); +void auxiliar_setclass(lua_State *L, const char *classname, int objidx); +void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx); +void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx); +void *auxiliar_getclassudata(lua_State *L, const char *groupname, int objidx); +void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx); +int auxiliar_checkboolean(lua_State *L, int objidx); +int auxiliar_tostring(lua_State *L); + +#endif /* AUXILIAR_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/buffer.c b/Build/source/texk/web2c/luatexdir/luasocket/src/buffer.c new file mode 100644 index 00000000000..73f4ffa85e6 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/buffer.c @@ -0,0 +1,268 @@ +/*=========================================================================*\ +* Input/Output interface for Lua programs +* LuaSocket toolkit +* +* RCS ID: $Id: buffer.c,v 1.28 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include "lua.h" +#include "lauxlib.h" + +#include "buffer.h" + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b); +static int recvline(p_buffer buf, luaL_Buffer *b); +static int recvall(p_buffer buf, luaL_Buffer *b); +static int buffer_get(p_buffer buf, const char **data, size_t *count); +static void buffer_skip(p_buffer buf, size_t count); +static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent); + +/* min and max macros */ +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? x : y) +#endif +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? x : y) +#endif + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int buffer_open(lua_State *L) { + (void) L; + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Initializes C structure +\*-------------------------------------------------------------------------*/ +void buffer_init(p_buffer buf, p_io io, p_timeout tm) { + buf->first = buf->last = 0; + buf->io = io; + buf->tm = tm; + buf->received = buf->sent = 0; + buf->birthday = timeout_gettime(); +} + +/*-------------------------------------------------------------------------*\ +* object:getstats() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_getstats(lua_State *L, p_buffer buf) { + lua_pushnumber(L, buf->received); + lua_pushnumber(L, buf->sent); + lua_pushnumber(L, timeout_gettime() - buf->birthday); + return 3; +} + +/*-------------------------------------------------------------------------*\ +* object:setstats() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_setstats(lua_State *L, p_buffer buf) { + buf->received = (long) luaL_optnumber(L, 2, buf->received); + buf->sent = (long) luaL_optnumber(L, 3, buf->sent); + if (lua_isnumber(L, 4)) buf->birthday = timeout_gettime() - lua_tonumber(L, 4); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* object:send() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_send(lua_State *L, p_buffer buf) { + int top = lua_gettop(L); + int err = IO_DONE; + size_t size = 0, sent = 0; + const char *data = luaL_checklstring(L, 2, &size); + long start = (long) luaL_optnumber(L, 3, 1); + long end = (long) luaL_optnumber(L, 4, -1); + p_timeout tm = timeout_markstart(buf->tm); + if (start < 0) start = (long) (size+start+1); + if (end < 0) end = (long) (size+end+1); + if (start < 1) start = (long) 1; + if (end > (long) size) end = (long) size; + if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent); + /* check if there was an error */ + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, buf->io->error(buf->io->ctx, err)); + lua_pushnumber(L, sent+start-1); + } else { + lua_pushnumber(L, sent+start-1); + lua_pushnil(L); + lua_pushnil(L); + } +#ifdef LUASOCKET_DEBUG + /* push time elapsed during operation as the last return value */ + lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); +#endif + return lua_gettop(L) - top; +} + +/*-------------------------------------------------------------------------*\ +* object:receive() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_receive(lua_State *L, p_buffer buf) { + int err = IO_DONE, top = lua_gettop(L); + luaL_Buffer b; + size_t size; + const char *part = luaL_optlstring(L, 3, "", &size); + p_timeout tm = timeout_markstart(buf->tm); + /* initialize buffer with optional extra prefix + * (useful for concatenating previous partial results) */ + luaL_buffinit(L, &b); + luaL_addlstring(&b, part, size); + /* receive new patterns */ + if (!lua_isnumber(L, 2)) { + const char *p= luaL_optstring(L, 2, "*l"); + if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b); + else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b); + else luaL_argcheck(L, 0, 2, "invalid receive pattern"); + /* get a fixed number of bytes (minus what was already partially + * received) */ + } else err = recvraw(buf, (size_t) lua_tonumber(L, 2)-size, &b); + /* check if there was an error */ + if (err != IO_DONE) { + /* we can't push anyting in the stack before pushing the + * contents of the buffer. this is the reason for the complication */ + luaL_pushresult(&b); + lua_pushstring(L, buf->io->error(buf->io->ctx, err)); + lua_pushvalue(L, -2); + lua_pushnil(L); + lua_replace(L, -4); + } else { + luaL_pushresult(&b); + lua_pushnil(L); + lua_pushnil(L); + } +#ifdef LUASOCKET_DEBUG + /* push time elapsed during operation as the last return value */ + lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); +#endif + return lua_gettop(L) - top; +} + +/*-------------------------------------------------------------------------*\ +* Determines if there is any data in the read buffer +\*-------------------------------------------------------------------------*/ +int buffer_isempty(p_buffer buf) { + return buf->first >= buf->last; +} + +/*=========================================================================*\ +* Internal functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Sends a block of data (unbuffered) +\*-------------------------------------------------------------------------*/ +#define STEPSIZE 8192 +static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) { + p_io io = buf->io; + p_timeout tm = buf->tm; + size_t total = 0; + int err = IO_DONE; + while (total < count && err == IO_DONE) { + size_t done; + size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE; + err = io->send(io->ctx, data+total, step, &done, tm); + total += done; + } + *sent = total; + buf->sent += total; + return err; +} + +/*-------------------------------------------------------------------------*\ +* Reads a fixed number of bytes (buffered) +\*-------------------------------------------------------------------------*/ +static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) { + int err = IO_DONE; + size_t total = 0; + while (err == IO_DONE) { + size_t count; const char *data; + err = buffer_get(buf, &data, &count); + count = MIN(count, wanted - total); + luaL_addlstring(b, data, count); + buffer_skip(buf, count); + total += count; + if (total >= wanted) break; + } + return err; +} + +/*-------------------------------------------------------------------------*\ +* Reads everything until the connection is closed (buffered) +\*-------------------------------------------------------------------------*/ +static int recvall(p_buffer buf, luaL_Buffer *b) { + int err = IO_DONE; + size_t total = 0; + while (err == IO_DONE) { + const char *data; size_t count; + err = buffer_get(buf, &data, &count); + total += count; + luaL_addlstring(b, data, count); + buffer_skip(buf, count); + } + if (err == IO_CLOSED) { + if (total > 0) return IO_DONE; + else return IO_CLOSED; + } else return err; +} + +/*-------------------------------------------------------------------------*\ +* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF +* are not returned by the function and are discarded from the buffer +\*-------------------------------------------------------------------------*/ +static int recvline(p_buffer buf, luaL_Buffer *b) { + int err = IO_DONE; + while (err == IO_DONE) { + size_t count, pos; const char *data; + err = buffer_get(buf, &data, &count); + pos = 0; + while (pos < count && data[pos] != '\n') { + /* we ignore all \r's */ + if (data[pos] != '\r') luaL_putchar(b, data[pos]); + pos++; + } + if (pos < count) { /* found '\n' */ + buffer_skip(buf, pos+1); /* skip '\n' too */ + break; /* we are done */ + } else /* reached the end of the buffer */ + buffer_skip(buf, pos); + } + return err; +} + +/*-------------------------------------------------------------------------*\ +* Skips a given number of bytes from read buffer. No data is read from the +* transport layer +\*-------------------------------------------------------------------------*/ +static void buffer_skip(p_buffer buf, size_t count) { + buf->received += count; + buf->first += count; + if (buffer_isempty(buf)) + buf->first = buf->last = 0; +} + +/*-------------------------------------------------------------------------*\ +* Return any data available in buffer, or get more data from transport layer +* if buffer is empty +\*-------------------------------------------------------------------------*/ +static int buffer_get(p_buffer buf, const char **data, size_t *count) { + int err = IO_DONE; + p_io io = buf->io; + p_timeout tm = buf->tm; + if (buffer_isempty(buf)) { + size_t got; + err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm); + buf->first = 0; + buf->last = got; + } + *count = buf->last - buf->first; + *data = buf->data + buf->first; + return err; +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/buffer.h b/Build/source/texk/web2c/luatexdir/luasocket/src/buffer.h new file mode 100644 index 00000000000..baf93caa031 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/buffer.h @@ -0,0 +1,47 @@ +#ifndef BUF_H +#define BUF_H +/*=========================================================================*\ +* Input/Output interface for Lua programs +* LuaSocket toolkit +* +* Line patterns require buffering. Reading one character at a time involves +* too many system calls and is very slow. This module implements the +* LuaSocket interface for input/output on connected objects, as seen by +* Lua programs. +* +* Input is buffered. Output is *not* buffered because there was no simple +* way of making sure the buffered output data would ever be sent. +* +* The module is built on top of the I/O abstraction defined in io.h and the +* timeout management is done with the timeout.h interface. +* +* RCS ID: $Id: buffer.h,v 1.12 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "io.h" +#include "timeout.h" + +/* buffer size in bytes */ +#define BUF_SIZE 8192 + +/* buffer control structure */ +typedef struct t_buffer_ { + double birthday; /* throttle support info: creation time, */ + size_t sent, received; /* bytes sent, and bytes received */ + p_io io; /* IO driver used for this buffer */ + p_timeout tm; /* timeout management for this buffer */ + size_t first, last; /* index of first and last bytes of stored data */ + char data[BUF_SIZE]; /* storage space for buffer data */ +} t_buffer; +typedef t_buffer *p_buffer; + +int buffer_open(lua_State *L); +void buffer_init(p_buffer buf, p_io io, p_timeout tm); +int buffer_meth_send(lua_State *L, p_buffer buf); +int buffer_meth_receive(lua_State *L, p_buffer buf); +int buffer_meth_getstats(lua_State *L, p_buffer buf); +int buffer_meth_setstats(lua_State *L, p_buffer buf); +int buffer_isempty(p_buffer buf); + +#endif /* BUF_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/except.c b/Build/source/texk/web2c/luatexdir/luasocket/src/except.c new file mode 100644 index 00000000000..5faa5be0039 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/except.c @@ -0,0 +1,99 @@ +/*=========================================================================*\ +* Simple exception support +* LuaSocket toolkit +* +* RCS ID: $Id: except.c,v 1.8 2005/09/29 06:11:41 diego Exp $ +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" + +#include "except.h" + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static int global_protect(lua_State *L); +static int global_newtry(lua_State *L); +static int protected_(lua_State *L); +static int finalize(lua_State *L); +static int do_nothing(lua_State *L); + +/* except functions */ +static luaL_reg func[] = { + {"newtry", global_newtry}, + {"protect", global_protect}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Try factory +\*-------------------------------------------------------------------------*/ +static void wrap(lua_State *L) { + lua_newtable(L); + lua_pushnumber(L, 1); + lua_pushvalue(L, -3); + lua_settable(L, -3); + lua_insert(L, -2); + lua_pop(L, 1); +} + +static int finalize(lua_State *L) { + if (!lua_toboolean(L, 1)) { + lua_pushvalue(L, lua_upvalueindex(1)); + lua_pcall(L, 0, 0, 0); + lua_settop(L, 2); + wrap(L); + lua_error(L); + return 0; + } else return lua_gettop(L); +} + +static int do_nothing(lua_State *L) { + (void) L; + return 0; +} + +static int global_newtry(lua_State *L) { + lua_settop(L, 1); + if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); + lua_pushcclosure(L, finalize, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Protect factory +\*-------------------------------------------------------------------------*/ +static int unwrap(lua_State *L) { + if (lua_istable(L, -1)) { + lua_pushnumber(L, 1); + lua_gettable(L, -2); + lua_pushnil(L); + lua_insert(L, -2); + return 1; + } else return 0; +} + +static int protected_(lua_State *L) { + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) { + if (unwrap(L)) return 2; + else lua_error(L); + return 0; + } else return lua_gettop(L); +} + +static int global_protect(lua_State *L) { + lua_pushcclosure(L, protected_, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Init module +\*-------------------------------------------------------------------------*/ +int except_open(lua_State *L) { + luaL_openlib(L, NULL, func, 0); + return 0; +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/except.h b/Build/source/texk/web2c/luatexdir/luasocket/src/except.h new file mode 100644 index 00000000000..81efb29be53 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/except.h @@ -0,0 +1,35 @@ +#ifndef EXCEPT_H +#define EXCEPT_H +/*=========================================================================*\ +* Exception control +* LuaSocket toolkit (but completely independent from other modules) +* +* This provides support for simple exceptions in Lua. During the +* development of the HTTP/FTP/SMTP support, it became aparent that +* error checking was taking a substantial amount of the coding. These +* function greatly simplify the task of checking errors. +* +* The main idea is that functions should return nil as its first return +* value when it finds an error, and return an error message (or value) +* following nil. In case of success, as long as the first value is not nil, +* the other values don't matter. +* +* The idea is to nest function calls with the "try" function. This function +* checks the first value, and calls "error" on the second if the first is +* nil. Otherwise, it returns all values it received. +* +* The protect function returns a new function that behaves exactly like the +* function it receives, but the new function doesn't throw exceptions: it +* returns nil followed by the error message instead. +* +* With these two function, it's easy to write functions that throw +* exceptions on error, but that don't interrupt the user script. +* +* RCS ID: $Id: except.h,v 1.2 2005/09/29 06:11:41 diego Exp $ +\*=========================================================================*/ + +#include "lua.h" + +int except_open(lua_State *L); + +#endif diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/ftp.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/ftp.lua new file mode 100644 index 00000000000..598f65dcaf0 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/ftp.lua @@ -0,0 +1,281 @@ +----------------------------------------------------------------------------- +-- FTP support for the Lua language +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: ftp.lua,v 1.45 2007/07/11 19:25:47 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local table = require("table") +local string = require("string") +local math = require("math") +local socket = require("socket") +local url = require("socket.url") +local tp = require("socket.tp") +local ltn12 = require("ltn12") +module("socket.ftp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- timeout in seconds before the program gives up on a connection +TIMEOUT = 60 +-- default port for ftp service +PORT = 21 +-- this is the default anonymous password. used when no password is +-- provided in url. should be changed to your e-mail. +USER = "ftp" +PASSWORD = "anonymous@anonymous.org" + +----------------------------------------------------------------------------- +-- Low level FTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function open(server, port, create) + local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create)) + local f = base.setmetatable({ tp = tp }, metat) + -- make sure everything gets closed in an exception + f.try = socket.newtry(function() f:close() end) + return f +end + +function metat.__index:portconnect() + self.try(self.server:settimeout(TIMEOUT)) + self.data = self.try(self.server:accept()) + self.try(self.data:settimeout(TIMEOUT)) +end + +function metat.__index:pasvconnect() + self.data = self.try(socket.tcp()) + self.try(self.data:settimeout(TIMEOUT)) + self.try(self.data:connect(self.pasvt.ip, self.pasvt.port)) +end + +function metat.__index:login(user, password) + self.try(self.tp:command("user", user or USER)) + local code, reply = self.try(self.tp:check{"2..", 331}) + if code == 331 then + self.try(self.tp:command("pass", password or PASSWORD)) + self.try(self.tp:check("2..")) + end + return 1 +end + +function metat.__index:pasv() + self.try(self.tp:command("pasv")) + local code, reply = self.try(self.tp:check("2..")) + local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern)) + self.try(a and b and c and d and p1 and p2, reply) + self.pasvt = { + ip = string.format("%d.%d.%d.%d", a, b, c, d), + port = p1*256 + p2 + } + if self.server then + self.server:close() + self.server = nil + end + return self.pasvt.ip, self.pasvt.port +end + +function metat.__index:port(ip, port) + self.pasvt = nil + if not ip then + ip, port = self.try(self.tp:getcontrol():getsockname()) + self.server = self.try(socket.bind(ip, 0)) + ip, port = self.try(self.server:getsockname()) + self.try(self.server:settimeout(TIMEOUT)) + end + local pl = math.mod(port, 256) + local ph = (port - pl)/256 + local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",") + self.try(self.tp:command("port", arg)) + self.try(self.tp:check("2..")) + return 1 +end + +function metat.__index:send(sendt) + self.try(self.pasvt or self.server, "need port or pasv first") + -- if there is a pasvt table, we already sent a PASV command + -- we just get the data connection into self.data + if self.pasvt then self:pasvconnect() end + -- get the transfer argument and command + local argument = sendt.argument or + url.unescape(string.gsub(sendt.path or "", "^[/\\]", "")) + if argument == "" then argument = nil end + local command = sendt.command or "stor" + -- send the transfer command and check the reply + self.try(self.tp:command(command, argument)) + local code, reply = self.try(self.tp:check{"2..", "1.."}) + -- if there is not a a pasvt table, then there is a server + -- and we already sent a PORT command + if not self.pasvt then self:portconnect() end + -- get the sink, source and step for the transfer + local step = sendt.step or ltn12.pump.step + local readt = {self.tp.c} + local checkstep = function(src, snk) + -- check status in control connection while downloading + local readyt = socket.select(readt, nil, 0) + if readyt[tp] then code = self.try(self.tp:check("2..")) end + return step(src, snk) + end + local sink = socket.sink("close-when-done", self.data) + -- transfer all data and check error + self.try(ltn12.pump.all(sendt.source, sink, checkstep)) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + -- done with data connection + self.data:close() + -- find out how many bytes were sent + local sent = socket.skip(1, self.data:getstats()) + self.data = nil + return sent +end + +function metat.__index:receive(recvt) + self.try(self.pasvt or self.server, "need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument = recvt.argument or + url.unescape(string.gsub(recvt.path or "", "^[/\\]", "")) + if argument == "" then argument = nil end + local command = recvt.command or "retr" + self.try(self.tp:command(command, argument)) + local code = self.try(self.tp:check{"1..", "2.."}) + if not self.pasvt then self:portconnect() end + local source = socket.source("until-closed", self.data) + local step = recvt.step or ltn12.pump.step + self.try(ltn12.pump.all(source, recvt.sink, step)) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + self.data:close() + self.data = nil + return 1 +end + +function metat.__index:cwd(dir) + self.try(self.tp:command("cwd", dir)) + self.try(self.tp:check(250)) + return 1 +end + +function metat.__index:type(type) + self.try(self.tp:command("type", type)) + self.try(self.tp:check(200)) + return 1 +end + +function metat.__index:greet() + local code = self.try(self.tp:check{"1..", "2.."}) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + return 1 +end + +function metat.__index:quit() + self.try(self.tp:command("quit")) + self.try(self.tp:check("2..")) + return 1 +end + +function metat.__index:close() + if self.data then self.data:close() end + if self.server then self.server:close() end + return self.tp:close() +end + +----------------------------------------------------------------------------- +-- High level FTP API +----------------------------------------------------------------------------- +local function override(t) + if t.url then + local u = url.parse(t.url) + for i,v in base.pairs(t) do + u[i] = v + end + return u + else return t end +end + +local function tput(putt) + putt = override(putt) + socket.try(putt.host, "missing hostname") + local f = open(putt.host, putt.port, putt.create) + f:greet() + f:login(putt.user, putt.password) + if putt.type then f:type(putt.type) end + f:pasv() + local sent = f:send(putt) + f:quit() + f:close() + return sent +end + +local default = { + path = "/", + scheme = "ftp" +} + +local function parse(u) + local t = socket.try(url.parse(u, default)) + socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'") + socket.try(t.host, "missing hostname") + local pat = "^type=(.)$" + if t.params then + t.type = socket.skip(2, string.find(t.params, pat)) + socket.try(t.type == "a" or t.type == "i", + "invalid type '" .. t.type .. "'") + end + return t +end + +local function sput(u, body) + local putt = parse(u) + putt.source = ltn12.source.string(body) + return tput(putt) +end + +put = socket.protect(function(putt, body) + if base.type(putt) == "string" then return sput(putt, body) + else return tput(putt) end +end) + +local function tget(gett) + gett = override(gett) + socket.try(gett.host, "missing hostname") + local f = open(gett.host, gett.port, gett.create) + f:greet() + f:login(gett.user, gett.password) + if gett.type then f:type(gett.type) end + f:pasv() + f:receive(gett) + f:quit() + return f:close() +end + +local function sget(u) + local gett = parse(u) + local t = {} + gett.sink = ltn12.sink.table(t) + tget(gett) + return table.concat(t) +end + +command = socket.protect(function(cmdt) + cmdt = override(cmdt) + socket.try(cmdt.host, "missing hostname") + socket.try(cmdt.command, "missing command") + local f = open(cmdt.host, cmdt.port, cmdt.create) + f:greet() + f:login(cmdt.user, cmdt.password) + f.try(f.tp:command(cmdt.command, cmdt.argument)) + if cmdt.check then f.try(f.tp:check(cmdt.check)) end + f:quit() + return f:close() +end) + +get = socket.protect(function(gett) + if base.type(gett) == "string" then return sget(gett) + else return tget(gett) end +end) + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/ftp_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/ftp_lua.c new file mode 100644 index 00000000000..b359db30b5c --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/ftp_lua.c @@ -0,0 +1,470 @@ +/* + * This file is auto-generated by "./lua2c ftp.lua ftp_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_ftp_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 70, 84, 80, 32,115,117,112,112,111,114,116, 32,102,111,114, 32,116,104,101, + 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 10, 45, 45, 32, 76,117, 97, + 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65, +117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, + 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,102,116,112, 46,108, +117, 97, 44,118, 32, 49, 46, 52, 53, 32, 50, 48, 48, 55, 47, 48, 55, 47, 49, 49, + 32, 49, 57, 58, 50, 53, 58, 52, 55, 32,100,105,101,103,111, 32, 69,120,112, 32, + 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, + 32,105,109,112,111,114,116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108, +111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, + 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, + 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, + 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108, +111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, + 34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, + 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10,108,111, 99, 97,108, + 32,116,112, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101, +116, 46,116,112, 34, 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, + 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,109,111, +100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,102,116,112, 34, 41, 10, 10, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, +116,105,109,101,111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 32, 98, +101,102,111,114,101, 32,116,104,101, 32,112,114,111,103,114, 97,109, 32,103,105, +118,101,115, 32,117,112, 32,111,110, 32, 97, 32, 99,111,110,110,101, 99,116,105, +111,110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100, +101,102, 97,117,108,116, 32,112,111,114,116, 32,102,111,114, 32,102,116,112, 32, +115,101,114,118,105, 99,101, 10, 80, 79, 82, 84, 32, 61, 32, 50, 49, 10, 45, 45, + 32,116,104,105,115, 32,105,115, 32,116,104,101, 32,100,101,102, 97,117,108,116, + 32, 97,110,111,110,121,109,111,117,115, 32,112, 97,115,115,119,111,114,100, 46, + 32,117,115,101,100, 32,119,104,101,110, 32,110,111, 32,112, 97,115,115,119,111, +114,100, 32,105,115, 10, 45, 45, 32,112,114,111,118,105,100,101,100, 32,105,110, + 32,117,114,108, 46, 32,115,104,111,117,108,100, 32, 98,101, 32, 99,104, 97,110, +103,101,100, 32,116,111, 32,121,111,117,114, 32,101, 45,109, 97,105,108, 46, 10, + 85, 83, 69, 82, 32, 61, 32, 34,102,116,112, 34, 10, 80, 65, 83, 83, 87, 79, 82, + 68, 32, 61, 32, 34, 97,110,111,110,121,109,111,117,115, 64, 97,110,111,110,121, +109,111,117,115, 46,111,114,103, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101,118,101, +108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, + 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10, +102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118,101,114, + 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46,116,114, +121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101,114, 44, + 32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 44, 32, 84, 73, 77, 69, 79, + 85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,102, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123, 32,116,112, 32, 61, 32,116,112, 32,125, 44, 32,109,101, +116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114, +101, 32,101,118,101,114,121,116,104,105,110,103, 32,103,101,116,115, 32, 99,108, +111,115,101,100, 32,105,110, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, + 10, 32, 32, 32, 32,102, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46, +110,101,119,116,114,121, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,102, 58, + 99,108,111,115,101, 40, 41, 32,101,110,100, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,102, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112,111,114,116, 99,111, +110,110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,115,101,114,118,101,114, 58,115,101,116,116,105,109,101, +111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101, +108,102, 46,100, 97,116, 97, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,115,101,114,118,101,114, 58, 97, 99, 99,101,112,116, 40, 41, 41, + 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,100, + 97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79, + 85, 84, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 99,111,110, +110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97,116, 97, + 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111, 99,107,101,116, 46,116, + 99,112, 40, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,100, 97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40, + 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,100, 97,116, 97, 58, 99,111,110,110,101, 99,116, + 40,115,101,108,102, 46,112, 97,115,118,116, 46,105,112, 44, 32,115,101,108,102, + 46,112, 97,115,118,116, 46,112,111,114,116, 41, 41, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111, +114,100, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,117,115,101,114, 34, 44, + 32,117,115,101,114, 32,111,114, 32, 85, 83, 69, 82, 41, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, 32, +115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, + 99,107,123, 34, 50, 46, 46, 34, 44, 32, 51, 51, 49,125, 41, 10, 32, 32, 32, 32, +105,102, 32, 99,111,100,101, 32, 61, 61, 32, 51, 51, 49, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,112, 97,115,115, 34, 44, + 32,112, 97,115,115,119,111,114,100, 32,111,114, 32, 80, 65, 83, 83, 87, 79, 82, + 68, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, + 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 40, 41, 10, 32, + 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,111,109,109, 97,110,100, 40, 34,112, 97,115,118, 34, 41, 41, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104, +101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,112, 97,116,116,101,114,110, 32, 61, 32, 34, 40, 37,100, 43, 41, 37, 68, + 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, + 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 34, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 44, 32,112, 49, 44, + 32,112, 50, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, + 32,115,116,114,105,110,103, 46,102,105,110,100, 40,114,101,112,108,121, 44, 32, +112, 97,116,116,101,114,110, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40, 97, 32, 97,110,100, 32, 98, 32, 97,110,100, 32, 99, 32, 97,110,100, + 32,100, 32, 97,110,100, 32,112, 49, 32, 97,110,100, 32,112, 50, 44, 32,114,101, +112,108,121, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, + 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 32, 61, 32,115,116,114, +105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37,100, 46, 37,100, 46, 37,100, + 46, 37,100, 34, 44, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 41, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,112,111,114,116, 32, 61, 32,112, 49, 42, 50, 53, 54, + 32, 43, 32,112, 50, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32,115, +101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32,115,101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115, +101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,115,101,114, +118,101,114, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,112, 97,115,118,116, 46, +105,112, 44, 32,115,101,108,102, 46,112, 97,115,118,116, 46,112,111,114,116, 10, +101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, + 95, 95,105,110,100,101,120, 58,112,111,114,116, 40,105,112, 44, 32,112,111,114, +116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, 61, 32, +110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,105,112, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32, + 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,103, +101,116, 99,111,110,116,114,111,108, 40, 41, 58,103,101,116,115,111, 99,107,110, + 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46, +115,101,114,118,101,114, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111, + 99,107,101,116, 46, 98,105,110,100, 40,105,112, 44, 32, 48, 41, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32, 61, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101,114, 58,103,101, +116,115,111, 99,107,110, 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101, +114, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, + 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,112,108, 32, 61, 32,109, 97,116,104, 46,109,111,100, 40,112,111,114,116, 44, + 32, 50, 53, 54, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,104, 32, 61, + 32, 40,112,111,114,116, 32, 45, 32,112,108, 41, 47, 50, 53, 54, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 97,114,103, 32, 61, 32,115,116,114,105,110,103, 46, +103,115,117, 98, 40,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, + 37,115, 44, 37,100, 44, 37,100, 34, 44, 32,105,112, 44, 32,112,104, 44, 32,112, +108, 41, 44, 32, 34, 37, 46, 34, 44, 32, 34, 44, 34, 41, 10, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, + 97,110,100, 40, 34,112,111,114,116, 34, 44, 32, 97,114,103, 41, 41, 10, 32, 32, + 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99, +104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,115, +101,110,100,116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,112, 97,115,118,116, 32,111,114, 32,115,101,108,102, 46,115,101, +114,118,101,114, 44, 32, 34,110,101,101,100, 32,112,111,114,116, 32,111,114, 32, +112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10, 32, 32, 32, 32, 45, 45, 32, +105,102, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,112, 97,115,118,116, 32, +116, 97, 98,108,101, 44, 32,119,101, 32, 97,108,114,101, 97,100,121, 32,115,101, +110,116, 32, 97, 32, 80, 65, 83, 86, 32, 99,111,109,109, 97,110,100, 10, 32, 32, + 32, 32, 45, 45, 32,119,101, 32,106,117,115,116, 32,103,101,116, 32,116,104,101, + 32,100, 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 32,105,110,116, +111, 32,115,101,108,102, 46,100, 97,116, 97, 10, 32, 32, 32, 32,105,102, 32,115, +101,108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58, +112, 97,115,118, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, + 32, 32, 45, 45, 32,103,101,116, 32,116,104,101, 32,116,114, 97,110,115,102,101, +114, 32, 97,114,103,117,109,101,110,116, 32, 97,110,100, 32, 99,111,109,109, 97, +110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117,109,101,110, +116, 32, 61, 32,115,101,110,100,116, 46, 97,114,103,117,109,101,110,116, 32,111, +114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101,115, 99, 97, +112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,115,101,110,100,116, + 46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47, 92, 92, 93, + 34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114,103,117,109, +101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114,103,117,109, +101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,115,101,110,100,116, 46, + 99,111,109,109, 97,110,100, 32,111,114, 32, 34,115,116,111,114, 34, 10, 32, 32, + 32, 32, 45, 45, 32,115,101,110,100, 32,116,104,101, 32,116,114, 97,110,115,102, +101,114, 32, 99,111,109,109, 97,110,100, 32, 97,110,100, 32, 99,104,101, 99,107, + 32,116,104,101, 32,114,101,112,108,121, 10, 32, 32, 32, 32,115,101,108,102, 46, +116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, + 99,111,109,109, 97,110,100, 44, 32, 97,114,103,117,109,101,110,116, 41, 41, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108, +121, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58, 99,104,101, 99,107,123, 34, 50, 46, 46, 34, 44, 32, 34, 49, 46, 46, 34,125, + 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, + 32,110,111,116, 32, 97, 32, 97, 32,112, 97,115,118,116, 32,116, 97, 98,108,101, + 44, 32,116,104,101,110, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,115,101, +114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32, 97,110,100, 32,119,101, 32, 97, +108,114,101, 97,100,121, 32,115,101,110,116, 32, 97, 32, 80, 79, 82, 84, 32, 99, +111,109,109, 97,110,100, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101, +108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112, +111,114,116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, + 32, 45, 45, 32,103,101,116, 32,116,104,101, 32,115,105,110,107, 44, 32,115,111, +117,114, 99,101, 32, 97,110,100, 32,115,116,101,112, 32,102,111,114, 32,116,104, +101, 32,116,114, 97,110,115,102,101,114, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,115,116,101,112, 32, 61, 32,115,101,110,100,116, 46,115,116,101,112, 32,111, +114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,114,101, 97,100,116, 32, 61, 32,123,115,101,108, +102, 46,116,112, 46, 99,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104, +101, 99,107,115,116,101,112, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115, +114, 99, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, + 99,104,101, 99,107, 32,115,116, 97,116,117,115, 32,105,110, 32, 99,111,110,116, +114,111,108, 32, 99,111,110,110,101, 99,116,105,111,110, 32,119,104,105,108,101, + 32,100,111,119,110,108,111, 97,100,105,110,103, 10, 32, 32, 32, 32, 32, 32, 32, + 32,108,111, 99, 97,108, 32,114,101, 97,100,121,116, 32, 61, 32,115,111, 99,107, +101,116, 46,115,101,108,101, 99,116, 40,114,101, 97,100,116, 44, 32,110,105,108, + 44, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,114,101, 97,100, +121,116, 91,116,112, 93, 32,116,104,101,110, 32, 99,111,100,101, 32, 61, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99, +107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115,116,101,112, 40,115,114, 99, 44, 32,115, +110,107, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,115,105,110,107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, + 40, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, 34, 44, 32, +115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32, 45, 45, 32,116,114, + 97,110,115,102,101,114, 32, 97,108,108, 32,100, 97,116, 97, 32, 97,110,100, 32, + 99,104,101, 99,107, 32,101,114,114,111,114, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40, +115,101,110,100,116, 46,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32, + 99,104,101, 99,107,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,105,102, 32,115, +116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, + 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32, +101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,100,111,110,101, 32,119,105,116,104, + 32,100, 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 10, 32, 32, 32, + 32,115,101,108,102, 46,100, 97,116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, + 32, 32, 32, 45, 45, 32,102,105,110,100, 32,111,117,116, 32,104,111,119, 32,109, + 97,110,121, 32, 98,121,116,101,115, 32,119,101,114,101, 32,115,101,110,116, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110,116, 32, 61, 32,115,111, 99, +107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108,102, 46,100, 97,116, + 97, 58,103,101,116,115,116, 97,116,115, 40, 41, 41, 10, 32, 32, 32, 32,115,101, +108,102, 46,100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,101,110,116, 10,101,110,100, 10, 10,102,117,110, 99,116, +105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, + 99,101,105,118,101, 40,114,101, 99,118,116, 41, 10, 32, 32, 32, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,112, 97,115,118,116, 32,111,114, 32, +115,101,108,102, 46,115,101,114,118,101,114, 44, 32, 34,110,101,101,100, 32,112, +111,114,116, 32,111,114, 32,112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10, + 32, 32, 32, 32,105,102, 32,115,101,108,102, 46,112, 97,115,118,116, 32,116,104, +101,110, 32,115,101,108,102, 58,112, 97,115,118, 99,111,110,110,101, 99,116, 40, + 41, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117, +109,101,110,116, 32, 61, 32,114,101, 99,118,116, 46, 97,114,103,117,109,101,110, +116, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101, +115, 99, 97,112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101, + 99,118,116, 46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47, + 92, 92, 93, 34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114, +103,117,109,101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114, +103,117,109,101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,114,101, 99, +118,116, 46, 99,111,109,109, 97,110,100, 32,111,114, 32, 34,114,101,116,114, 34, + 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116, +112, 58, 99,111,109,109, 97,110,100, 40, 99,111,109,109, 97,110,100, 44, 32, 97, +114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, + 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, + 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, 32, 34, 50, 46, + 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101,108,102, + 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112,111,114, +116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,115,111,117,114, 99,101, 32, 61, 32,115,111, 99,107,101,116, + 46,115,111,117,114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101, +100, 34, 44, 32,115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,115,116,101,112, 32, 61, 32,114,101, 99,118,116, 46,115,116, +101,112, 32,111,114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101, +112, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, + 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32,114,101, + 99,118,116, 46,115,105,110,107, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, + 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, + 44, 32, 34, 49, 46, 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, + 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97, +116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46, +100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,119,100, 40,100,105,114, 41, + 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116, +112, 58, 99,111,109,109, 97,110,100, 40, 34, 99,119,100, 34, 44, 32,100,105,114, + 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, + 46,116,112, 58, 99,104,101, 99,107, 40, 50, 53, 48, 41, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,116,121,112, +101, 40,116,121,112,101, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,116,121, +112,101, 34, 44, 32,116,121,112,101, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 50, + 48, 48, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110, +100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, + 32, 34, 50, 46, 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105, +110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, 46, 34, 41, + 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,113, +117,105,116, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,105,102, 32,115,101, +108,102, 46,100, 97,116, 97, 32,116,104,101,110, 32,115,101,108,102, 46,100, 97, +116, 97, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,105, +102, 32,115,101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 32,115, +101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115,101, 40, 41, 32,101, +110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, +112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, + 32,108,101,118,101,108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102, +117,110, 99,116,105,111,110, 32,111,118,101,114,114,105,100,101, 40,116, 41, 10, + 32, 32, 32, 32,105,102, 32,116, 46,117,114,108, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,117,114,108, 46, +112, 97,114,115,101, 40,116, 46,117,114,108, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105, +114,115, 40,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,117, 91,105, 93, 32, 61, 32,118, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, 10, 32, + 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, 32,101,110,100, + 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, + 32,116,112,117,116, 40,112,117,116,116, 41, 10, 32, 32, 32, 32,112,117,116,116, + 32, 61, 32,111,118,101,114,114,105,100,101, 40,112,117,116,116, 41, 10, 32, 32, + 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,112,117,116,116, 46,104,111, +115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109, +101, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112, +101,110, 40,112,117,116,116, 46,104,111,115,116, 44, 32,112,117,116,116, 46,112, +111,114,116, 44, 32,112,117,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, + 32, 32,102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111, +103,105,110, 40,112,117,116,116, 46,117,115,101,114, 44, 32,112,117,116,116, 46, +112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,112,117,116, +116, 46,116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,112, +117,116,116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58, +112, 97,115,118, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110, +116, 32, 61, 32,102, 58,115,101,110,100, 40,112,117,116,116, 41, 10, 32, 32, 32, + 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,102, 58, 99,108,111,115, +101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,110,116, 10, +101,110,100, 10, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32, 61, + 32,123, 10, 9,112, 97,116,104, 32, 61, 32, 34, 47, 34, 44, 10, 9,115, 99,104, +101,109,101, 32, 61, 32, 34,102,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108, + 32,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117, 41, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,115,111, 99,107,101,116, 46, +116,114,121, 40,117,114,108, 46,112, 97,114,115,101, 40,117, 44, 32,100,101,102, + 97,117,108,116, 41, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114, +121, 40,116, 46,115, 99,104,101,109,101, 32, 61, 61, 32, 34,102,116,112, 34, 44, + 32, 34,119,114,111,110,103, 32,115, 99,104,101,109,101, 32, 39, 34, 32, 46, 46, + 32,116, 46,115, 99,104,101,109,101, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, + 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,116, 46,104,111,115,116, 44, + 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116, 32, 61, 32, 34, 94,116, +121,112,101, 61, 40, 46, 41, 36, 34, 10, 32, 32, 32, 32,105,102, 32,116, 46,112, + 97,114, 97,109,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,116, + 46,116,121,112,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, + 50, 44, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,116, 46,112, 97,114, + 97,109,115, 44, 32,112, 97,116, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115, +111, 99,107,101,116, 46,116,114,121, 40,116, 46,116,121,112,101, 32, 61, 61, 32, + 34, 97, 34, 32,111,114, 32,116, 46,116,121,112,101, 32, 61, 61, 32, 34,105, 34, + 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34,105,110,118, 97,108, +105,100, 32,116,121,112,101, 32, 39, 34, 32, 46, 46, 32,116, 46,116,121,112,101, + 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10,108,111, 99, 97,108, + 32,102,117,110, 99,116,105,111,110, 32,115,112,117,116, 40,117, 44, 32, 98,111, +100,121, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,117,116,116, 32, 61, + 32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,112,117,116,116, 46,115, +111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99,101, + 46,115,116,114,105,110,103, 40, 98,111,100,121, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 10,101,110,100, 10, + 10,112,117,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99, +116, 40,102,117,110, 99,116,105,111,110, 40,112,117,116,116, 44, 32, 98,111,100, +121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40, +112,117,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,115,112,117,116, 40,112,117,116,116, 44, + 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117, +114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 32,101,110,100, 10,101,110, +100, 41, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,116, +103,101,116, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,103,101,116,116, 32, 61, + 32,111,118,101,114,114,105,100,101, 40,103,101,116,116, 41, 10, 32, 32, 32, 32, +115,111, 99,107,101,116, 46,116,114,121, 40,103,101,116,116, 46,104,111,115,116, + 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34, + 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112,101,110, + 40,103,101,116,116, 46,104,111,115,116, 44, 32,103,101,116,116, 46,112,111,114, +116, 44, 32,103,101,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, +102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111,103,105, +110, 40,103,101,116,116, 46,117,115,101,114, 44, 32,103,101,116,116, 46,112, 97, +115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,103,101,116,116, 46, +116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,103,101,116, +116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,112, 97, +115,118, 40, 41, 10, 32, 32, 32, 32,102, 58,114,101, 99,101,105,118,101, 40,103, +101,116,116, 41, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101, 40, 41, 10,101, +110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115, +103,101,116, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,103,101,116, +116, 32, 61, 32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,103,101,116,116, 46,115, +105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, 98, +108,101, 40,116, 41, 10, 32, 32, 32, 32,116,103,101,116, 40,103,101,116,116, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, 46, 99,111, +110, 99, 97,116, 40,116, 41, 10,101,110,100, 10, 10, 99,111,109,109, 97,110,100, + 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99,116, 40,102,117, +110, 99,116,105,111,110, 40, 99,109,100,116, 41, 10, 32, 32, 32, 32, 99,109,100, +116, 32, 61, 32,111,118,101,114,114,105,100,101, 40, 99,109,100,116, 41, 10, 32, + 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, 99,109,100,116, 46,104, +111,115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97, +109,101, 34, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, + 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 34,109,105,115,115,105, +110,103, 32, 99,111,109,109, 97,110,100, 34, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,102, 32, 61, 32,111,112,101,110, 40, 99,109,100,116, 46,104,111,115, +116, 44, 32, 99,109,100,116, 46,112,111,114,116, 44, 32, 99,109,100,116, 46, 99, +114,101, 97,116,101, 41, 10, 32, 32, 32, 32,102, 58,103,114,101,101,116, 40, 41, + 10, 32, 32, 32, 32,102, 58,108,111,103,105,110, 40, 99,109,100,116, 46,117,115, +101,114, 44, 32, 99,109,100,116, 46,112, 97,115,115,119,111,114,100, 41, 10, 32, + 32, 32, 32,102, 46,116,114,121, 40,102, 46,116,112, 58, 99,111,109,109, 97,110, +100, 40, 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 99,109,100,116, + 46, 97,114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 99, +109,100,116, 46, 99,104,101, 99,107, 32,116,104,101,110, 32,102, 46,116,114,121, + 40,102, 46,116,112, 58, 99,104,101, 99,107, 40, 99,109,100,116, 46, 99,104,101, + 99,107, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101, + 40, 41, 10,101,110,100, 41, 10, 10,103,101,116, 32, 61, 32,115,111, 99,107,101, +116, 46,112,114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,103, +101,116,116, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112, +101, 40,103,101,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32,115,103,101,116, 40,103,101,116, +116, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, +103,101,116, 40,103,101,116,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, 10, + + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/http.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/http.lua new file mode 100644 index 00000000000..ad8db1ee065 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/http.lua @@ -0,0 +1,350 @@ +----------------------------------------------------------------------------- +-- HTTP/1.1 client support for the Lua language. +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: http.lua,v 1.71 2007/10/13 23:55:20 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +------------------------------------------------------------------------------- +local socket = require("socket") +local url = require("socket.url") +local ltn12 = require("ltn12") +local mime = require("mime") +local string = require("string") +local base = _G +local table = require("table") +module("socket.http") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- connection timeout in seconds +TIMEOUT = 60 +-- default port for document retrieval +PORT = 80 +-- user agent field sent in request +USERAGENT = socket._VERSION + +----------------------------------------------------------------------------- +-- Reads MIME headers from a connection, unfolding where needed +----------------------------------------------------------------------------- +local function receiveheaders(sock, headers) + local line, name, value, err + headers = headers or {} + -- get first line + line, err = sock:receive() + if err then return nil, err end + -- headers go until a blank line is found + while line ~= "" do + -- get field-name and value + name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)")) + if not (name and value) then return nil, "malformed reponse headers" end + name = string.lower(name) + -- get next line (value might be folded) + line, err = sock:receive() + if err then return nil, err end + -- unfold any folded values + while string.find(line, "^%s") do + value = value .. line + line = sock:receive() + if err then return nil, err end + end + -- save pair in table + if headers[name] then headers[name] = headers[name] .. ", " .. value + else headers[name] = value end + end + return headers +end + +----------------------------------------------------------------------------- +-- Extra sources and sinks +----------------------------------------------------------------------------- +socket.sourcet["http-chunked"] = function(sock, headers) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + -- get chunk size, skip extention + local line, err = sock:receive() + if err then return nil, err end + local size = base.tonumber(string.gsub(line, ";.*", ""), 16) + if not size then return nil, "invalid chunk size" end + -- was it the last chunk? + if size > 0 then + -- if not, get chunk and skip terminating CRLF + local chunk, err, part = sock:receive(size) + if chunk then sock:receive() end + return chunk, err + else + -- if it was, read trailers into headers table + headers, err = receiveheaders(sock, headers) + if not headers then return nil, err end + end + end + }) +end + +socket.sinkt["http-chunked"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if not chunk then return sock:send("0\r\n\r\n") end + local size = string.format("%X\r\n", string.len(chunk)) + return sock:send(size .. chunk .. "\r\n") + end + }) +end + +----------------------------------------------------------------------------- +-- Low level HTTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function open(host, port, create) + -- create socket with user connect function, or with default + local c = socket.try((create or socket.tcp)()) + local h = base.setmetatable({ c = c }, metat) + -- create finalized try + h.try = socket.newtry(function() h:close() end) + -- set timeout before connecting + h.try(c:settimeout(TIMEOUT)) + h.try(c:connect(host, port or PORT)) + -- here everything worked + return h +end + +function metat.__index:sendrequestline(method, uri) + local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri) + return self.try(self.c:send(reqline)) +end + +function metat.__index:sendheaders(headers) + local h = "\r\n" + for i, v in base.pairs(headers) do + h = i .. ": " .. v .. "\r\n" .. h + end + self.try(self.c:send(h)) + return 1 +end + +function metat.__index:sendbody(headers, source, step) + source = source or ltn12.source.empty() + step = step or ltn12.pump.step + -- if we don't know the size in advance, send chunked and hope for the best + local mode = "http-chunked" + if headers["content-length"] then mode = "keep-open" end + return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step)) +end + +function metat.__index:receivestatusline() + local status = self.try(self.c:receive(5)) + -- identify HTTP/0.9 responses, which do not contain a status line + -- this is just a heuristic, but is what the RFC recommends + if status ~= "HTTP/" then return nil, status end + -- otherwise proceed reading a status line + status = self.try(self.c:receive("*l", status)) + local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) + return self.try(base.tonumber(code), status) +end + +function metat.__index:receiveheaders() + return self.try(receiveheaders(self.c)) +end + +function metat.__index:receivebody(headers, sink, step) + sink = sink or ltn12.sink.null() + step = step or ltn12.pump.step + local length = base.tonumber(headers["content-length"]) + local t = headers["transfer-encoding"] -- shortcut + local mode = "default" -- connection close + if t and t ~= "identity" then mode = "http-chunked" + elseif base.tonumber(headers["content-length"]) then mode = "by-length" end + return self.try(ltn12.pump.all(socket.source(mode, self.c, length), + sink, step)) +end + +function metat.__index:receive09body(status, sink, step) + local source = ltn12.source.rewind(socket.source("until-closed", self.c)) + source(status) + return self.try(ltn12.pump.all(source, sink, step)) +end + +function metat.__index:close() + return self.c:close() +end + +----------------------------------------------------------------------------- +-- High level HTTP API +----------------------------------------------------------------------------- +local function adjusturi(reqt) + local u = reqt + -- if there is a proxy, we need the full url. otherwise, just a part. + if not reqt.proxy and not PROXY then + u = { + path = socket.try(reqt.path, "invalid path 'nil'"), + params = reqt.params, + query = reqt.query, + fragment = reqt.fragment + } + end + return url.build(u) +end + +local function adjustproxy(reqt) + local proxy = reqt.proxy or PROXY + if proxy then + proxy = url.parse(proxy) + return proxy.host, proxy.port or 3128 + else + return reqt.host, reqt.port + end +end + +local function adjustheaders(reqt) + -- default headers + local lower = { + ["user-agent"] = USERAGENT, + ["host"] = reqt.host, + ["connection"] = "close, TE", + ["te"] = "trailers" + } + -- if we have authentication information, pass it along + if reqt.user and reqt.password then + lower["authorization"] = + "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password)) + end + -- override with user headers + for i,v in base.pairs(reqt.headers or lower) do + lower[string.lower(i)] = v + end + return lower +end + +-- default url parts +local default = { + host = "", + port = PORT, + path ="/", + scheme = "http" +} + +local function adjustrequest(reqt) + -- parse url if provided + local nreqt = reqt.url and url.parse(reqt.url, default) or {} + -- explicit components override url + for i,v in base.pairs(reqt) do nreqt[i] = v end + if nreqt.port == "" then nreqt.port = 80 end + socket.try(nreqt.host and nreqt.host ~= "", + "invalid host '" .. base.tostring(nreqt.host) .. "'") + -- compute uri if user hasn't overriden + nreqt.uri = reqt.uri or adjusturi(nreqt) + -- ajust host and port if there is a proxy + nreqt.host, nreqt.port = adjustproxy(nreqt) + -- adjust headers in request + nreqt.headers = adjustheaders(nreqt) + return nreqt +end + +local function shouldredirect(reqt, code, headers) + return headers.location and + string.gsub(headers.location, "%s", "") ~= "" and + (reqt.redirect ~= false) and + (code == 301 or code == 302) and + (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD") + and (not reqt.nredirects or reqt.nredirects < 5) +end + +local function shouldreceivebody(reqt, code) + if reqt.method == "HEAD" then return nil end + if code == 204 or code == 304 then return nil end + if code >= 100 and code < 200 then return nil end + return 1 +end + +-- forward declarations +local trequest, tredirect + +function tredirect(reqt, location) + local result, code, headers, status = trequest { + -- the RFC says the redirect URL has to be absolute, but some + -- servers do not respect that + url = url.absolute(reqt.url, location), + source = reqt.source, + sink = reqt.sink, + headers = reqt.headers, + proxy = reqt.proxy, + nredirects = (reqt.nredirects or 0) + 1, + create = reqt.create + } + -- pass location header back as a hint we redirected + headers = headers or {} + headers.location = headers.location or location + return result, code, headers, status +end + +function trequest(reqt) + -- we loop until we get what we want, or + -- until we are sure there is no way to get it + local nreqt = adjustrequest(reqt) + local h = open(nreqt.host, nreqt.port, nreqt.create) + -- send request line and headers + h:sendrequestline(nreqt.method, nreqt.uri) + h:sendheaders(nreqt.headers) + -- if there is a body, send it + if nreqt.source then + h:sendbody(nreqt.headers, nreqt.source, nreqt.step) + end + local code, status = h:receivestatusline() + -- if it is an HTTP/0.9 server, simply get the body and we are done + if not code then + h:receive09body(status, nreqt.sink, nreqt.step) + return 1, 200 + end + local headers + -- ignore any 100-continue messages + while code == 100 do + headers = h:receiveheaders() + code, status = h:receivestatusline() + end + headers = h:receiveheaders() + -- at this point we should have a honest reply from the server + -- we can't redirect if we already used the source, so we report the error + if shouldredirect(nreqt, code, headers) and not nreqt.source then + h:close() + return tredirect(reqt, headers.location) + end + -- here we are finally done + if shouldreceivebody(nreqt, code) then + h:receivebody(headers, nreqt.sink, nreqt.step) + end + h:close() + return 1, code, headers, status +end + +local function srequest(u, b) + local t = {} + local reqt = { + url = u, + sink = ltn12.sink.table(t) + } + if b then + reqt.source = ltn12.source.string(b) + reqt.headers = { + ["content-length"] = string.len(b), + ["content-type"] = "application/x-www-form-urlencoded" + } + reqt.method = "POST" + end + local code, headers, status = socket.skip(1, trequest(reqt)) + return table.concat(t), code, headers, status +end + +request = socket.protect(function(reqt, body) + if base.type(reqt) == "string" then return srequest(reqt, body) + else return trequest(reqt) end +end) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/http_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/http_lua.c new file mode 100644 index 00000000000..fa287503798 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/http_lua.c @@ -0,0 +1,623 @@ +/* + * This file is auto-generated by "./lua2c http.lua http_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_http_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 72, 84, 84, 80, 47, 49, 46, 49, 32, 99,108,105,101,110,116, 32,115,117,112, +112,111,114,116, 32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110, +103,117, 97,103,101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32, +116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, + 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, + 68, 58, 32, 36, 73,100, 58, 32,104,116,116,112, 46,108,117, 97, 44,118, 32, 49, + 46, 55, 49, 32, 50, 48, 48, 55, 47, 49, 48, 47, 49, 51, 32, 50, 51, 58, 53, 53, + 58, 50, 48, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, + 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114, +116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, + 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115, +111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32, +114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, + 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117, +105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109, +105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, + 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113, +117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, + 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98, +108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, + 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,104,116,116, +112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97, +110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10, 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32,116,105,109,101, +111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 10, 84, 73, 77, 69, 79, + 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,112, +111,114,116, 32,102,111,114, 32,100,111, 99,117,109,101,110,116, 32,114,101,116, +114,105,101,118, 97,108, 10, 80, 79, 82, 84, 32, 61, 32, 56, 48, 10, 45, 45, 32, +117,115,101,114, 32, 97,103,101,110,116, 32,102,105,101,108,100, 32,115,101,110, +116, 32,105,110, 32,114,101,113,117,101,115,116, 10, 85, 83, 69, 82, 65, 71, 69, + 78, 84, 32, 61, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, 78, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32, 82,101, 97,100,115, 32, 77, 73, 77, 69, 32,104,101, 97,100,101,114, +115, 32,102,114,111,109, 32, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 44, + 32,117,110,102,111,108,100,105,110,103, 32,119,104,101,114,101, 32,110,101,101, +100,101,100, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,114,101, 99, +101,105,118,101,104,101, 97,100,101,114,115, 40,115,111, 99,107, 44, 32,104,101, + 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110, +101, 44, 32,110, 97,109,101, 44, 32,118, 97,108,117,101, 44, 32,101,114,114, 10, + 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101, 97,100,101,114, +115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,102, +105,114,115,116, 32,108,105,110,101, 10, 32, 32, 32, 32,108,105,110,101, 44, 32, +101,114,114, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, + 10, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, + 32, 45, 45, 32,104,101, 97,100,101,114,115, 32,103,111, 32,117,110,116,105,108, + 32, 97, 32, 98,108, 97,110,107, 32,108,105,110,101, 32,105,115, 32,102,111,117, +110,100, 10, 32, 32, 32, 32,119,104,105,108,101, 32,108,105,110,101, 32,126, 61, + 32, 34, 34, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,103,101, +116, 32,102,105,101,108,100, 45,110, 97,109,101, 32, 97,110,100, 32,118, 97,108, +117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 44, 32,118, 97,108, +117,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32, +115,116,114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, + 40, 46, 45, 41, 58, 37,115, 42, 40, 46, 42, 41, 34, 41, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,110,111,116, 32, 40,110, 97,109,101, 32, 97,110,100, + 32,118, 97,108,117,101, 41, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, +110,105,108, 44, 32, 34,109, 97,108,102,111,114,109,101,100, 32,114,101,112,111, +110,115,101, 32,104,101, 97,100,101,114,115, 34, 32,101,110,100, 10, 32, 32, 32, + 32, 32, 32, 32, 32,110, 97,109,101, 32, 61, 32,115,116,114,105,110,103, 46,108, +111,119,101,114, 40,110, 97,109,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, + 45, 32,103,101,116, 32,110,101,120,116, 32,108,105,110,101, 32, 40,118, 97,108, +117,101, 32,109,105,103,104,116, 32, 98,101, 32,102,111,108,100,101,100, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 32, 61, + 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 45, 45, 32,117,110,102,111,108,100, 32, 97,110,121, 32,102,111, +108,100,101,100, 32,118, 97,108,117,101,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, +119,104,105,108,101, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,108,105, +110,101, 44, 32, 34, 94, 37,115, 34, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,118, 97,108,117,101, 32, 61, 32,118, 97,108,117,101, 32, + 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +108,105,110,101, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, +114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 45, 45, 32,115, 97,118,101, 32,112, 97,105,114, 32,105, +110, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,104, +101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32,116,104,101,110, 32,104,101, + 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,104,101, 97,100,101,114, +115, 91,110, 97,109,101, 93, 32, 46, 46, 32, 34, 44, 32, 34, 32, 46, 46, 32,118, + 97,108,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,104,101, + 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,118, 97,108,117,101, 32, +101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,104,101, 97,100,101,114,115, 10,101,110,100, 10, 10, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,120,116, +114, 97, 32,115,111,117,114, 99,101,115, 32, 97,110,100, 32,115,105,110,107,115, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,115, +111, 99,107,101,116, 46,115,111,117,114, 99,101,116, 91, 34,104,116,116,112, 45, + 99,104,117,110,107,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, + 40,115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, + 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116, +105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105, +114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99, +116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, + 45, 32,103,101,116, 32, 99,104,117,110,107, 32,115,105,122,101, 44, 32,115,107, +105,112, 32,101,120,116,101,110,116,105,111,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110,101, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, +115,105,122,101, 32, 61, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,108,105,110,101, 44, 32, 34, + 59, 46, 42, 34, 44, 32, 34, 34, 41, 44, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,105,122,101, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118, + 97,108,105,100, 32, 99,104,117,110,107, 32,115,105,122,101, 34, 32,101,110,100, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,119, 97,115, 32, +105,116, 32,116,104,101, 32,108, 97,115,116, 32, 99,104,117,110,107, 63, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,105,122,101, 32, 62, + 32, 48, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 45, 45, 32,105,102, 32,110,111,116, 44, 32,103,101,116, 32, 99, +104,117,110,107, 32, 97,110,100, 32,115,107,105,112, 32,116,101,114,109,105,110, + 97,116,105,110,103, 32, 67, 82, 76, 70, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32, +101,114,114, 44, 32,112, 97,114,116, 32, 61, 32,115,111, 99,107, 58,114,101, 99, +101,105,118,101, 40,115,105,122,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, + 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 32,101,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32, 99,104,117,110,107, 44, 32,101,114,114, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,105,102, 32,105,116, 32,119, 97,115, 44, + 32,114,101, 97,100, 32,116,114, 97,105,108,101,114,115, 32,105,110,116,111, 32, +104,101, 97,100,101,114,115, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 44, 32,101, +114,114, 32, 61, 32,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, +115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,104,101, + 97,100,101,114,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105, +108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,125, 41, 10,101,110,100, 10, 10,115,111, 99,107,101,116, 46,115,105, +110,107,116, 91, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 93, 32, + 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97, +116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102, +100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114, +110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, + 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99, +116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100, +105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, + 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101, +114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, +111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,115,101,110,100, 40, 34, 48, 92,114, 92,110, 92,114, 92, +110, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,115,116,114,105,110,103, 46, +102,111,114,109, 97,116, 40, 34, 37, 88, 92,114, 92,110, 34, 44, 32,115,116,114, +105,110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58, +115,101,110,100, 40,115,105,122,101, 32, 46, 46, 32, 32, 99,104,117,110,107, 32, + 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32, +108,101,118,101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109, +101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123, +125, 32,125, 10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,104, +111,115,116, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, + 32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,115,111, 99,107,101,116, 32, +119,105,116,104, 32,117,115,101,114, 32, 99,111,110,110,101, 99,116, 32,102,117, +110, 99,116,105,111,110, 44, 32,111,114, 32,119,105,116,104, 32,100,101,102, 97, +117,108,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, 32, 61, 32,115,111, + 99,107,101,116, 46,116,114,121, 40, 40, 99,114,101, 97,116,101, 32,111,114, 32, +115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,104, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, + 97,116, 97, 98,108,101, 40,123, 32, 99, 32, 61, 32, 99, 32,125, 44, 32,109,101, +116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,102, +105,110, 97,108,105,122,101,100, 32,116,114,121, 10, 32, 32, 32, 32,104, 46,116, +114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114,121, 40,102, +117,110, 99,116,105,111,110, 40, 41, 32,104, 58, 99,108,111,115,101, 40, 41, 32, +101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,116, 32,116,105,109,101, +111,117,116, 32, 98,101,102,111,114,101, 32, 99,111,110,110,101, 99,116,105,110, +103, 10, 32, 32, 32, 32,104, 46,116,114,121, 40, 99, 58,115,101,116,116,105,109, +101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,104, + 46,116,114,121, 40, 99, 58, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, + 32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 41, 41, 10, 32, 32, 32, 32, + 45, 45, 32,104,101,114,101, 32,101,118,101,114,121,116,104,105,110,103, 32,119, +111,114,107,101,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104, 10,101, +110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, + 95,105,110,100,101,120, 58,115,101,110,100,114,101,113,117,101,115,116,108,105, +110,101, 40,109,101,116,104,111,100, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,114,101,113,108,105,110,101, 32, 61, 32,115,116,114,105, +110,103, 46,102,111,114,109, 97,116, 40, 34, 37,115, 32, 37,115, 32, 72, 84, 84, + 80, 47, 49, 46, 49, 92,114, 92,110, 34, 44, 32,109,101,116,104,111,100, 32,111, +114, 32, 34, 71, 69, 84, 34, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, + 58,115,101,110,100, 40,114,101,113,108,105,110,101, 41, 41, 10,101,110,100, 10, + 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110, +100,101,120, 58,115,101,110,100,104,101, 97,100,101,114,115, 40,104,101, 97,100, +101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, + 92,114, 92,110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105, +110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115, + 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46, + 46, 32, 34, 58, 32, 34, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110, + 34, 32, 46, 46, 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, 58,115,101,110,100, 40, +104, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,115,101,110,100, 98,111,100,121, 40,104,101, 97,100,101,114, +115, 44, 32,115,111,117,114, 99,101, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, + 32,115,111,117,114, 99,101, 32, 61, 32,115,111,117,114, 99,101, 32,111,114, 32, +108,116,110, 49, 50, 46,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, + 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111,114, 32, +108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, 32, 32, + 45, 45, 32,105,102, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 32, +116,104,101, 32,115,105,122,101, 32,105,110, 32, 97,100,118, 97,110, 99,101, 44, + 32,115,101,110,100, 32, 99,104,117,110,107,101,100, 32, 97,110,100, 32,104,111, +112,101, 32,102,111,114, 32,116,104,101, 32, 98,101,115,116, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,109,111,100,101, 32, 61, 32, 34,104,116,116,112, 45, 99, +104,117,110,107,101,100, 34, 10, 32, 32, 32, 32,105,102, 32,104,101, 97,100,101, +114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, + 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, 34,107,101,101,112, 45,111, +112,101,110, 34, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, + 97,108,108, 40,115,111,117,114, 99,101, 44, 32,115,111, 99,107,101,116, 46,115, +105,110,107, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 41, 44, 32,115, +116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118, +101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 53, 41, 41, + 10, 32, 32, 32, 32, 45, 45, 32,105,100,101,110,116,105,102,121, 32, 72, 84, 84, + 80, 47, 48, 46, 57, 32,114,101,115,112,111,110,115,101,115, 44, 32,119,104,105, + 99,104, 32,100,111, 32,110,111,116, 32, 99,111,110,116, 97,105,110, 32, 97, 32, +115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, 45, 45, 32,116, +104,105,115, 32,105,115, 32,106,117,115,116, 32, 97, 32,104,101,117,114,105,115, +116,105, 99, 44, 32, 98,117,116, 32,105,115, 32,119,104, 97,116, 32,116,104,101, + 32, 82, 70, 67, 32,114,101, 99,111,109,109,101,110,100,115, 10, 32, 32, 32, 32, +105,102, 32,115,116, 97,116,117,115, 32,126, 61, 32, 34, 72, 84, 84, 80, 47, 34, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,116, + 97,116,117,115, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,111,116,104,101, +114,119,105,115,101, 32,112,114,111, 99,101,101,100, 32,114,101, 97,100,105,110, +103, 32, 97, 32,115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, +115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 34, 42,108, 34, 44, 32,115, +116, 97,116,117,115, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111, +100,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32, +115,116,114,105,110,103, 46,102,105,110,100, 40,115,116, 97,116,117,115, 44, 32, + 34, 72, 84, 84, 80, 47, 37,100, 42, 37, 46, 37,100, 42, 32, 40, 37,100, 37,100, + 37,100, 41, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101, +108,102, 46,116,114,121, 40, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40, 99,111,100,101, 41, 44, 32,115,116, 97,116,117,115, 41, 10,101,110,100, 10, + 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110, +100,101,120, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, + 40,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40,115,101,108,102, + 46, 99, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, + 98,111,100,121, 40,104,101, 97,100,101,114,115, 44, 32,115,105,110,107, 44, 32, +115,116,101,112, 41, 10, 32, 32, 32, 32,115,105,110,107, 32, 61, 32,115,105,110, +107, 32,111,114, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,110,117,108,108, + 40, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111, +114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,108,101,110,103,116,104, 32, 61, 32, 98, 97,115, +101, 46,116,111,110,117,109, 98,101,114, 40,104,101, 97,100,101,114,115, 91, 34, + 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,104,101, 97,100,101,114,115, 91, + 34,116,114, 97,110,115,102,101,114, 45,101,110, 99,111,100,105,110,103, 34, 93, + 32, 45, 45, 32,115,104,111,114,116, 99,117,116, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,109,111,100,101, 32, 61, 32, 34,100,101,102, 97,117,108,116, 34, 32, + 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32, 99,108,111,115,101, 10, + 32, 32, 32, 32,105,102, 32,116, 32, 97,110,100, 32,116, 32,126, 61, 32, 34,105, +100,101,110,116,105,116,121, 34, 32,116,104,101,110, 32,109,111,100,101, 32, 61, + 32, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 10, 32, 32, 32, 32, +101,108,115,101,105,102, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40,104,101, 97,100,101,114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101, +110,103,116,104, 34, 93, 41, 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, + 34, 98,121, 45,108,101,110,103,116,104, 34, 32,101,110,100, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, + 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111, 99,107,101,116, 46,115,111, +117,114, 99,101, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 44, 32,108, +101,110,103,116,104, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,105,110,107, + 44, 32,115,116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99, +101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117,115, 44, 32,115, +105,110,107, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, + 99,101, 46,114,101,119,105,110,100, 40,115,111, 99,107,101,116, 46,115,111,117, +114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101,100, 34, 44, 32, +115,101,108,102, 46, 99, 41, 41, 10, 32, 32, 32, 32,115,111,117,114, 99,101, 40, +115,116, 97,116,117,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, +101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97, +108,108, 40,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32,115,116,101, +112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58, 99,108, +111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118, +101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,117,110, 99, +116,105,111,110, 32, 97,100,106,117,115,116,117,114,105, 40,114,101,113,116, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,114,101,113,116, 10, + 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, 32, 97, + 32,112,114,111,120,121, 44, 32,119,101, 32,110,101,101,100, 32,116,104,101, 32, +102,117,108,108, 32,117,114,108, 46, 32,111,116,104,101,114,119,105,115,101, 44, + 32,106,117,115,116, 32, 97, 32,112, 97,114,116, 46, 10, 32, 32, 32, 32,105,102, + 32,110,111,116, 32,114,101,113,116, 46,112,114,111,120,121, 32, 97,110,100, 32, +110,111,116, 32, 80, 82, 79, 88, 89, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32,117, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +112, 97,116,104, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40,114,101, +113,116, 46,112, 97,116,104, 44, 32, 34,105,110,118, 97,108,105,100, 32,112, 97, +116,104, 32, 39,110,105,108, 39, 34, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,112, 97,114, 97,109,115, 32, 61, 32,114,101,113,116, 46,112, 97,114, + 97,109,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,113,117,101,114, +121, 32, 61, 32,114,101,113,116, 46,113,117,101,114,121, 44, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,102,114, 97,103,109,101,110,116, 32, 61, 32,114,101, +113,116, 46,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, +125, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32,117,114,108, 46, 98,117,105,108,100, 40,117, 41, 10,101,110,100, 10, 10,108, +111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116, +112,114,111,120,121, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,112,114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121, + 32,111,114, 32, 80, 82, 79, 88, 89, 10, 32, 32, 32, 32,105,102, 32,112,114,111, +120,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,112,114,111,120, +121, 32, 61, 32,117,114,108, 46,112, 97,114,115,101, 40,112,114,111,120,121, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112,114,111,120, +121, 46,104,111,115,116, 44, 32,112,114,111,120,121, 46,112,111,114,116, 32,111, +114, 32, 51, 49, 50, 56, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,113,116, 46,104,111,115,116, + 44, 32,114,101,113,116, 46,112,111,114,116, 10, 32, 32, 32, 32,101,110,100, 10, +101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, + 97,100,106,117,115,116,104,101, 97,100,101,114,115, 40,114,101,113,116, 41, 10, + 32, 32, 32, 32, 45, 45, 32,100,101,102, 97,117,108,116, 32,104,101, 97,100,101, +114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111,119,101,114, 32, 61, + 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,117,115,101,114, 45, 97,103, +101,110,116, 34, 93, 32, 61, 32, 85, 83, 69, 82, 65, 71, 69, 78, 84, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 91, 34,104,111,115,116, 34, 93, 32, 61, 32,114,101, +113,116, 46,104,111,115,116, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99, +111,110,110,101, 99,116,105,111,110, 34, 93, 32, 61, 32, 34, 99,108,111,115,101, + 44, 32, 84, 69, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,116,101, 34, + 93, 32, 61, 32, 34,116,114, 97,105,108,101,114,115, 34, 10, 32, 32, 32, 32,125, + 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,119,101, 32,104, 97,118,101, 32, 97, +117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32,105,110,102,111,114,109, + 97,116,105,111,110, 44, 32,112, 97,115,115, 32,105,116, 32, 97,108,111,110,103, + 10, 32, 32, 32, 32,105,102, 32,114,101,113,116, 46,117,115,101,114, 32, 97,110, +100, 32,114,101,113,116, 46,112, 97,115,115,119,111,114,100, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91, 34, 97,117,116,104, +111,114,105,122, 97,116,105,111,110, 34, 93, 32, 61, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 34, 66, 97,115,105, 99, 32, 34, 32, 46, 46, 32, 32, + 40,109,105,109,101, 46, 98, 54, 52, 40,114,101,113,116, 46,117,115,101,114, 32, + 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,114,101,113,116, 46,112, 97,115,115,119, +111,114,100, 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, + 32,111,118,101,114,114,105,100,101, 32,119,105,116,104, 32,117,115,101,114, 32, +104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32, +105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 46,104, +101, 97,100,101,114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, + 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, + 46,108,111,119,101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10, +101,110,100, 10, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,117,114,108, 32, +112, 97,114,116,115, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32, + 61, 32,123, 10, 32, 32, 32, 32,104,111,115,116, 32, 61, 32, 34, 34, 44, 10, 32, + 32, 32, 32,112,111,114,116, 32, 61, 32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32, +112, 97,116,104, 32, 61, 34, 47, 34, 44, 10, 32, 32, 32, 32,115, 99,104,101,109, +101, 32, 61, 32, 34,104,116,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108, 32, +102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116,114,101,113,117,101, +115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,114,115, +101, 32,117,114,108, 32,105,102, 32,112,114,111,118,105,100,101,100, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,110,114,101,113,116, 32, 61, 32,114,101,113,116, + 46,117,114,108, 32, 97,110,100, 32,117,114,108, 46,112, 97,114,115,101, 40,114, +101,113,116, 46,117,114,108, 44, 32,100,101,102, 97,117,108,116, 41, 32,111,114, + 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,101,120,112,108,105, 99,105,116, 32, + 99,111,109,112,111,110,101,110,116,115, 32,111,118,101,114,114,105,100,101, 32, +117,114,108, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, + 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 41, 32,100,111, 32,110, +114,101,113,116, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32, +105,102, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 61, 32, 34, 34, 32, +116,104,101,110, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 32, 56, 48, + 32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, +110,114,101,113,116, 46,104,111,115,116, 32, 97,110,100, 32,110,114,101,113,116, + 46,104,111,115,116, 32,126, 61, 32, 34, 34, 44, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 34,105,110,118, 97,108,105,100, 32,104,111,115,116, 32, 39, 34, 32, 46, + 46, 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110,114,101,113, +116, 46,104,111,115,116, 41, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32, + 45, 45, 32, 99,111,109,112,117,116,101, 32,117,114,105, 32,105,102, 32,117,115, +101,114, 32,104, 97,115,110, 39,116, 32,111,118,101,114,114,105,100,101,110, 10, + 32, 32, 32, 32,110,114,101,113,116, 46,117,114,105, 32, 61, 32,114,101,113,116, + 46,117,114,105, 32,111,114, 32, 97,100,106,117,115,116,117,114,105, 40,110,114, +101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,106,117,115,116, 32,104,111, +115,116, 32, 97,110,100, 32,112,111,114,116, 32,105,102, 32,116,104,101,114,101, + 32,105,115, 32, 97, 32,112,114,111,120,121, 10, 32, 32, 32, 32,110,114,101,113, +116, 46,104,111,115,116, 44, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, + 32, 97,100,106,117,115,116,112,114,111,120,121, 40,110,114,101,113,116, 41, 10, + 32, 32, 32, 32, 45, 45, 32, 97,100,106,117,115,116, 32,104,101, 97,100,101,114, +115, 32,105,110, 32,114,101,113,117,101,115,116, 10, 32, 32, 32, 32,110,114,101, +113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116,104, +101, 97,100,101,114,115, 40,110,114,101,113,116, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,110,114,101,113,116, 10,101,110,100, 10, 10,108,111, 99, 97, +108, 32,102,117,110, 99,116,105,111,110, 32,115,104,111,117,108,100,114,101,100, +105,114,101, 99,116, 40,114,101,113,116, 44, 32, 99,111,100,101, 44, 32,104,101, + 97,100,101,114,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104,101, + 97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 97,110,100, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116,114,105,110,103, 46,103,115,117, + 98, 40,104,101, 97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 44, 32, + 34, 37,115, 34, 44, 32, 34, 34, 41, 32,126, 61, 32, 34, 34, 32, 97,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,114,101,113,116, 46,114,101,100, +105,114,101, 99,116, 32,126, 61, 32,102, 97,108,115,101, 41, 32, 97,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 99,111,100,101, 32, 61, 61, 32, + 51, 48, 49, 32,111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 50, 41, 32, + 97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,110,111,116, 32, +114,101,113,116, 46,109,101,116,104,111,100, 32,111,114, 32,114,101,113,116, 46, +109,101,116,104,111,100, 32, 61, 61, 32, 34, 71, 69, 84, 34, 32,111,114, 32,114, +101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 97,110,100, 32, 40,110,111, +116, 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114, + 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32, 60, 32, 53, + 41, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111, +110, 32,115,104,111,117,108,100,114,101, 99,101,105,118,101, 98,111,100,121, 40, +114,101,113,116, 44, 32, 99,111,100,101, 41, 10, 32, 32, 32, 32,105,102, 32,114, +101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, + 10, 32, 32, 32, 32,105,102, 32, 99,111,100,101, 32, 61, 61, 32, 50, 48, 52, 32, +111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 52, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,105, +102, 32, 99,111,100,101, 32, 62, 61, 32, 49, 48, 48, 32, 97,110,100, 32, 99,111, +100,101, 32, 60, 32, 50, 48, 48, 32,116,104,101,110, 32,114,101,116,117,114,110, + 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, + 49, 10,101,110,100, 10, 10, 45, 45, 32,102,111,114,119, 97,114,100, 32,100,101, + 99,108, 97,114, 97,116,105,111,110,115, 10,108,111, 99, 97,108, 32,116,114,101, +113,117,101,115,116, 44, 32,116,114,101,100,105,114,101, 99,116, 10, 10,102,117, +110, 99,116,105,111,110, 32,116,114,101,100,105,114,101, 99,116, 40,114,101,113, +116, 44, 32,108,111, 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114,101,115,117,108,116, 44, 32, 99,111,100,101, 44, 32,104,101, 97, +100,101,114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,116,114,101,113,117, +101,115,116, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,116,104,101, + 32, 82, 70, 67, 32,115, 97,121,115, 32,116,104,101, 32,114,101,100,105,114,101, + 99,116, 32, 85, 82, 76, 32,104, 97,115, 32,116,111, 32, 98,101, 32, 97, 98,115, +111,108,117,116,101, 44, 32, 98,117,116, 32,115,111,109,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 45, 45, 32,115,101,114,118,101,114,115, 32,100,111, 32,110,111, +116, 32,114,101,115,112,101, 99,116, 32,116,104, 97,116, 10, 32, 32, 32, 32, 32, + 32, 32, 32,117,114,108, 32, 61, 32,117,114,108, 46, 97, 98,115,111,108,117,116, +101, 40,114,101,113,116, 46,117,114,108, 44, 32,108,111, 99, 97,116,105,111,110, + 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,111,117,114, 99,101, 32, 61, 32, +114,101,113,116, 46,115,111,117,114, 99,101, 44, 10, 32, 32, 32, 32, 32, 32, 32, + 32,115,105,110,107, 32, 61, 32,114,101,113,116, 46,115,105,110,107, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,114,101,113, +116, 46,104,101, 97,100,101,114,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, +114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121, 44, 32, 10, + 32, 32, 32, 32, 32, 32, 32, 32,110,114,101,100,105,114,101, 99,116,115, 32, 61, + 32, 40,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114, + 32, 48, 41, 32, 43, 32, 49, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,114,101, + 97,116,101, 32, 61, 32,114,101,113,116, 46, 99,114,101, 97,116,101, 10, 32, 32, + 32, 32,125, 32, 32, 32, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,115,115, 32,108, +111, 99, 97,116,105,111,110, 32,104,101, 97,100,101,114, 32, 98, 97, 99,107, 32, + 97,115, 32, 97, 32,104,105,110,116, 32,119,101, 32,114,101,100,105,114,101, 99, +116,101,100, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101, + 97,100,101,114,115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32,104,101, 97,100, +101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 61, 32,104,101, 97,100,101, +114,115, 46,108,111, 99, 97,116,105,111,110, 32,111,114, 32,108,111, 99, 97,116, +105,111,110, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,115,117,108, +116, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, + 97,116,117,115, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,116, +114,101,113,117,101,115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, + 32,119,101, 32,108,111,111,112, 32,117,110,116,105,108, 32,119,101, 32,103,101, +116, 32,119,104, 97,116, 32,119,101, 32,119, 97,110,116, 44, 32,111,114, 10, 32, + 32, 32, 32, 45, 45, 32,117,110,116,105,108, 32,119,101, 32, 97,114,101, 32,115, +117,114,101, 32,116,104,101,114,101, 32,105,115, 32,110,111, 32,119, 97,121, 32, +116,111, 32,103,101,116, 32,105,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, +110,114,101,113,116, 32, 61, 32, 97,100,106,117,115,116,114,101,113,117,101,115, +116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, + 61, 32,111,112,101,110, 40,110,114,101,113,116, 46,104,111,115,116, 44, 32,110, +114,101,113,116, 46,112,111,114,116, 44, 32,110,114,101,113,116, 46, 99,114,101, + 97,116,101, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,114,101,113, +117,101,115,116, 32,108,105,110,101, 32, 97,110,100, 32,104,101, 97,100,101,114, +115, 10, 32, 32, 32, 32,104, 58,115,101,110,100,114,101,113,117,101,115,116,108, +105,110,101, 40,110,114,101,113,116, 46,109,101,116,104,111,100, 44, 32,110,114, +101,113,116, 46,117,114,105, 41, 10, 32, 32, 32, 32,104, 58,115,101,110,100,104, +101, 97,100,101,114,115, 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, + 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, + 32, 97, 32, 98,111,100,121, 44, 32,115,101,110,100, 32,105,116, 10, 32, 32, 32, + 32,105,102, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58,115,101,110,100, 98,111,100,121, + 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, 44, 32,110,114,101,113, +116, 46,115,111,117,114, 99,101, 44, 32,110,114,101,113,116, 46,115,116,101,112, + 41, 32, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, 32,104, 58,114,101, + 99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, + 32, 32, 45, 45, 32,105,102, 32,105,116, 32,105,115, 32, 97,110, 32, 72, 84, 84, + 80, 47, 48, 46, 57, 32,115,101,114,118,101,114, 44, 32,115,105,109,112,108,121, + 32,103,101,116, 32,116,104,101, 32, 98,111,100,121, 32, 97,110,100, 32,119,101, + 32, 97,114,101, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,110,111,116, + 32, 99,111,100,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, + 58,114,101, 99,101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117, +115, 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116, + 46,115,116,101,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 44, 32, 50, 48, 48, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32, 45, + 45, 32,105,103,110,111,114,101, 32, 97,110,121, 32, 49, 48, 48, 45, 99,111,110, +116,105,110,117,101, 32,109,101,115,115, 97,103,101,115, 10, 32, 32, 32, 32,119, +104,105,108,101, 32, 99,111,100,101, 32, 61, 61, 32, 49, 48, 48, 32,100,111, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104, + 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, + 32,104, 58,114,101, 99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101, + 40, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104,101, 97,100,101, +114,115, 32, 61, 32,104, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114, +115, 40, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,116, 32,116,104,105,115, 32,112, +111,105,110,116, 32,119,101, 32,115,104,111,117,108,100, 32,104, 97,118,101, 32, + 97, 32,104,111,110,101,115,116, 32,114,101,112,108,121, 32,102,114,111,109, 32, +116,104,101, 32,115,101,114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32,119,101, + 32, 99, 97,110, 39,116, 32,114,101,100,105,114,101, 99,116, 32,105,102, 32,119, +101, 32, 97,108,114,101, 97,100,121, 32,117,115,101,100, 32,116,104,101, 32,115, +111,117,114, 99,101, 44, 32,115,111, 32,119,101, 32,114,101,112,111,114,116, 32, +116,104,101, 32,101,114,114,111,114, 32, 10, 32, 32, 32, 32,105,102, 32,115,104, +111,117,108,100,114,101,100,105,114,101, 99,116, 40,110,114,101,113,116, 44, 32, + 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 41, 32, 97,110,100, 32,110, +111,116, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58, 99,108,111,115,101, 40, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,116,114,101,100,105,114, +101, 99,116, 40,114,101,113,116, 44, 32,104,101, 97,100,101,114,115, 46,108,111, + 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 45, 45, 32,104,101,114,101, 32,119,101, 32, 97,114,101, 32,102,105,110, 97,108, +108,121, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,115,104,111,117,108, +100,114,101, 99,101,105,118,101, 98,111,100,121, 40,110,114,101,113,116, 44, 32, + 99,111,100,101, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, + 58,114,101, 99,101,105,118,101, 98,111,100,121, 40,104,101, 97,100,101,114,115, + 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116, 46, +115,116,101,112, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104, 58, + 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, + 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, 97, +116,117,115, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116, +105,111,110, 32,115,114,101,113,117,101,115,116, 40,117, 44, 32, 98, 41, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,114,101,113,116, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, + 32, 32, 32,117,114,108, 32, 61, 32,117, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, +115,105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, + 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32, + 98, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46, +115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99, +101, 46,115,116,114,105,110,103, 40, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32,123, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,108, +101,110,103,116,104, 34, 93, 32, 61, 32,115,116,114,105,110,103, 46,108,101,110, + 40, 98, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99, +111,110,116,101,110,116, 45,116,121,112,101, 34, 93, 32, 61, 32, 34, 97,112,112, +108,105, 99, 97,116,105,111,110, 47,120, 45,119,119,119, 45,102,111,114,109, 45, +117,114,108,101,110, 99,111,100,101,100, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, +125, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46,109,101,116,104,111, +100, 32, 61, 32, 34, 80, 79, 83, 84, 34, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,104,101, 97,100,101, +114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,115,111, 99,107,101,116, 46, +115,107,105,112, 40, 49, 44, 32,116,114,101,113,117,101,115,116, 40,114,101,113, +116, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, + 46, 99,111,110, 99, 97,116, 40,116, 41, 44, 32, 99,111,100,101, 44, 32,104,101, + 97,100,101,114,115, 44, 32,115,116, 97,116,117,115, 10,101,110,100, 10, 10,114, +101,113,117,101,115,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116, +101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,114,101,113,116, 44, 32, 98, +111,100,121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112, +101, 40,114,101,113,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32,115,114,101,113,117,101,115,116, + 40,114,101,113,116, 44, 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115, +101, 32,114,101,116,117,114,110, 32,116,114,101,113,117,101,115,116, 40,114,101, +113,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c new file mode 100644 index 00000000000..3d30698cadc --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c @@ -0,0 +1,285 @@ +/*=========================================================================*\ +* Internet domain functions +* LuaSocket toolkit +* +* RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include +#include + +#include "lua.h" +#include "lauxlib.h" + +#include "inet.h" + +#if defined(__SUNOS__) || defined (__SUN__) +#define INET_ATON 1 +#endif + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static int inet_global_toip(lua_State *L); +static int inet_global_tohostname(lua_State *L); +static void inet_pushresolved(lua_State *L, struct hostent *hp); +static int inet_global_gethostname(lua_State *L); + +/* DNS functions */ +static luaL_reg func[] = { + { "toip", inet_global_toip }, + { "tohostname", inet_global_tohostname }, + { "gethostname", inet_global_gethostname}, + { NULL, NULL} +}; + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int inet_open(lua_State *L) +{ + lua_pushstring(L, "dns"); + lua_newtable(L); + luaL_openlib(L, NULL, func, 0); + lua_settable(L, -3); + return 0; +} + +/*=========================================================================*\ +* Global Lua functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Returns all information provided by the resolver given a host name +* or ip address +\*-------------------------------------------------------------------------*/ +static int inet_gethost(const char *address, struct hostent **hp) { + struct in_addr addr; + if (inet_aton(address, &addr)) + return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp); + else + return socket_gethostbyname(address, hp); +} + +/*-------------------------------------------------------------------------*\ +* Returns all information provided by the resolver given a host name +* or ip address +\*-------------------------------------------------------------------------*/ +static int inet_global_tohostname(lua_State *L) { + const char *address = luaL_checkstring(L, 1); + struct hostent *hp = NULL; + int err = inet_gethost(address, &hp); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_hoststrerror(err)); + return 2; + } + lua_pushstring(L, hp->h_name); + inet_pushresolved(L, hp); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Returns all information provided by the resolver given a host name +* or ip address +\*-------------------------------------------------------------------------*/ +static int inet_global_toip(lua_State *L) +{ + const char *address = luaL_checkstring(L, 1); + struct hostent *hp = NULL; + int err = inet_gethost(address, &hp); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_hoststrerror(err)); + return 2; + } + lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr))); + inet_pushresolved(L, hp); + return 2; +} + + +/*-------------------------------------------------------------------------*\ +* Gets the host name +\*-------------------------------------------------------------------------*/ +static int inet_global_gethostname(lua_State *L) +{ + char name[257]; + name[256] = '\0'; + if (gethostname(name, 256) < 0) { + lua_pushnil(L); + lua_pushstring(L, "gethostname failed"); + return 2; + } else { + lua_pushstring(L, name); + return 1; + } +} + + + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Retrieves socket peer name +\*-------------------------------------------------------------------------*/ +int inet_meth_getpeername(lua_State *L, p_socket ps) +{ + struct sockaddr_in peer; + socklen_t peer_len = sizeof(peer); + if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getpeername failed"); + } else { + lua_pushstring(L, inet_ntoa(peer.sin_addr)); + lua_pushnumber(L, ntohs(peer.sin_port)); + } + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Retrieves socket local name +\*-------------------------------------------------------------------------*/ +int inet_meth_getsockname(lua_State *L, p_socket ps) +{ + struct sockaddr_in local; + socklen_t local_len = sizeof(local); + if (getsockname(*ps, (SA *) &local, &local_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockname failed"); + } else { + lua_pushstring(L, inet_ntoa(local.sin_addr)); + lua_pushnumber(L, ntohs(local.sin_port)); + } + return 2; +} + +/*=========================================================================*\ +* Internal functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Passes all resolver information to Lua as a table +\*-------------------------------------------------------------------------*/ +static void inet_pushresolved(lua_State *L, struct hostent *hp) +{ + char **alias; + struct in_addr **addr; + int i, resolved; + lua_newtable(L); resolved = lua_gettop(L); + lua_pushstring(L, "name"); + lua_pushstring(L, hp->h_name); + lua_settable(L, resolved); + lua_pushstring(L, "ip"); + lua_pushstring(L, "alias"); + i = 1; + alias = hp->h_aliases; + lua_newtable(L); + if (alias) { + while (*alias) { + lua_pushnumber(L, i); + lua_pushstring(L, *alias); + lua_settable(L, -3); + i++; alias++; + } + } + lua_settable(L, resolved); + i = 1; + lua_newtable(L); + addr = (struct in_addr **) hp->h_addr_list; + if (addr) { + while (*addr) { + lua_pushnumber(L, i); + lua_pushstring(L, inet_ntoa(**addr)); + lua_settable(L, -3); + i++; addr++; + } + } + lua_settable(L, resolved); +} + +/*-------------------------------------------------------------------------*\ +* Tries to create a new inet socket +\*-------------------------------------------------------------------------*/ +const char *inet_trycreate(p_socket ps, int type) { + return socket_strerror(socket_create(ps, AF_INET, type, 0)); +} + +/*-------------------------------------------------------------------------*\ +* Tries to connect to remote address (address, port) +\*-------------------------------------------------------------------------*/ +const char *inet_tryconnect(p_socket ps, const char *address, + unsigned short port, p_timeout tm) +{ + struct sockaddr_in remote; + int err; + memset(&remote, 0, sizeof(remote)); + remote.sin_family = AF_INET; + remote.sin_port = htons(port); + if (strcmp(address, "*")) { + if (!inet_aton(address, &remote.sin_addr)) { + struct hostent *hp = NULL; + struct in_addr **addr; + err = socket_gethostbyname(address, &hp); + if (err != IO_DONE) return socket_hoststrerror(err); + addr = (struct in_addr **) hp->h_addr_list; + memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); + } + } else remote.sin_family = AF_UNSPEC; + err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm); + return socket_strerror(err); +} + +/*-------------------------------------------------------------------------*\ +* Tries to bind socket to (address, port) +\*-------------------------------------------------------------------------*/ +const char *inet_trybind(p_socket ps, const char *address, unsigned short port) +{ + struct sockaddr_in local; + int err; + memset(&local, 0, sizeof(local)); + /* address is either wildcard or a valid ip address */ + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(port); + local.sin_family = AF_INET; + if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) { + struct hostent *hp = NULL; + struct in_addr **addr; + err = socket_gethostbyname(address, &hp); + if (err != IO_DONE) return socket_hoststrerror(err); + addr = (struct in_addr **) hp->h_addr_list; + memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); + } + err = socket_bind(ps, (SA *) &local, sizeof(local)); + if (err != IO_DONE) socket_destroy(ps); + return socket_strerror(err); +} + +/*-------------------------------------------------------------------------*\ +* Some systems do not provide this so that we provide our own. It's not +* marvelously fast, but it works just fine. +\*-------------------------------------------------------------------------*/ +#ifdef INET_ATON +int inet_aton(const char *cp, struct in_addr *inp) +{ + unsigned int a = 0, b = 0, c = 0, d = 0; + int n = 0, r; + unsigned long int addr = 0; + r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n); + if (r == 0 || n == 0) return 0; + cp += n; + if (*cp) return 0; + if (a > 255 || b > 255 || c > 255 || d > 255) return 0; + if (inp) { + addr += a; addr <<= 8; + addr += b; addr <<= 8; + addr += c; addr <<= 8; + addr += d; + inp->s_addr = htonl(addr); + } + return 1; +} +#endif + + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.h b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.h new file mode 100644 index 00000000000..7662266110a --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.h @@ -0,0 +1,42 @@ +#ifndef INET_H +#define INET_H +/*=========================================================================*\ +* Internet domain functions +* LuaSocket toolkit +* +* This module implements the creation and connection of internet domain +* sockets, on top of the socket.h interface, and the interface of with the +* resolver. +* +* The function inet_aton is provided for the platforms where it is not +* available. The module also implements the interface of the internet +* getpeername and getsockname functions as seen by Lua programs. +* +* The Lua functions toip and tohostname are also implemented here. +* +* RCS ID: $Id: inet.h,v 1.16 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" +#include "socket.h" +#include "timeout.h" + +#ifdef _WIN32 +#define INET_ATON +#endif + +int inet_open(lua_State *L); + +const char *inet_trycreate(p_socket ps, int type); +const char *inet_tryconnect(p_socket ps, const char *address, + unsigned short port, p_timeout tm); +const char *inet_trybind(p_socket ps, const char *address, + unsigned short port); + +int inet_meth_getpeername(lua_State *L, p_socket ps); +int inet_meth_getsockname(lua_State *L, p_socket ps); + +#ifdef INET_ATON +int inet_aton(const char *cp, struct in_addr *inp); +#endif + +#endif /* INET_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/io.c b/Build/source/texk/web2c/luatexdir/luasocket/src/io.c new file mode 100644 index 00000000000..06dc50ecacc --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/io.c @@ -0,0 +1,32 @@ +/*=========================================================================*\ +* Input/Output abstraction +* LuaSocket toolkit +* +* RCS ID: $Id: io.c,v 1.6 2005/09/29 06:11:41 diego Exp $ +\*=========================================================================*/ +#include "io.h" + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes C structure +\*-------------------------------------------------------------------------*/ +void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) { + io->send = send; + io->recv = recv; + io->error = error; + io->ctx = ctx; +} + +/*-------------------------------------------------------------------------*\ +* I/O error strings +\*-------------------------------------------------------------------------*/ +const char *io_strerror(int err) { + switch (err) { + case IO_DONE: return NULL; + case IO_CLOSED: return "closed"; + case IO_TIMEOUT: return "timeout"; + default: return "unknown error"; + } +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/io.h b/Build/source/texk/web2c/luatexdir/luasocket/src/io.h new file mode 100644 index 00000000000..cce3aaf556b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/io.h @@ -0,0 +1,67 @@ +#ifndef IO_H +#define IO_H +/*=========================================================================*\ +* Input/Output abstraction +* LuaSocket toolkit +* +* This module defines the interface that LuaSocket expects from the +* transport layer for streamed input/output. The idea is that if any +* transport implements this interface, then the buffer.c functions +* automatically work on it. +* +* The module socket.h implements this interface, and thus the module tcp.h +* is very simple. +* +* RCS ID: $Id: io.h,v 1.11 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include +#include "lua.h" + +#include "timeout.h" + +/* IO error codes */ +enum { + IO_DONE = 0, /* operation completed successfully */ + IO_TIMEOUT = -1, /* operation timed out */ + IO_CLOSED = -2, /* the connection has been closed */ + IO_UNKNOWN = -3 +}; + +/* interface to error message function */ +typedef const char *(*p_error) ( + void *ctx, /* context needed by send */ + int err /* error code */ +); + +/* interface to send function */ +typedef int (*p_send) ( + void *ctx, /* context needed by send */ + const char *data, /* pointer to buffer with data to send */ + size_t count, /* number of bytes to send from buffer */ + size_t *sent, /* number of bytes sent uppon return */ + p_timeout tm /* timeout control */ +); + +/* interface to recv function */ +typedef int (*p_recv) ( + void *ctx, /* context needed by recv */ + char *data, /* pointer to buffer where data will be writen */ + size_t count, /* number of bytes to receive into buffer */ + size_t *got, /* number of bytes received uppon return */ + p_timeout tm /* timeout control */ +); + +/* IO driver definition */ +typedef struct t_io_ { + void *ctx; /* context needed by send/recv */ + p_send send; /* send function pointer */ + p_recv recv; /* receive function pointer */ + p_error error; /* strerror function */ +} t_io; +typedef t_io *p_io; + +void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx); +const char *io_strerror(int err); + +#endif /* IO_H */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/ltn12.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/ltn12.lua new file mode 100644 index 00000000000..b42689a34ab --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/ltn12.lua @@ -0,0 +1,292 @@ +----------------------------------------------------------------------------- +-- LTN12 - Filters, sources, sinks and pumps. +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module +----------------------------------------------------------------------------- +local string = require("string") +local table = require("table") +local base = _G +module("ltn12") + +filter = {} +source = {} +sink = {} +pump = {} + +-- 2048 seems to be better in windows... +BLOCKSIZE = 2048 +_VERSION = "LTN12 1.0.1" + +----------------------------------------------------------------------------- +-- Filter stuff +----------------------------------------------------------------------------- +-- returns a high level filter that cycles a low-level filter +function filter.cycle(low, ctx, extra) + base.assert(low) + return function(chunk) + local ret + ret, ctx = low(ctx, chunk, extra) + return ret + end +end + +-- chains a bunch of filters together +-- (thanks to Wim Couwenberg) +function filter.chain(...) + local n = table.getn(arg) + local top, index = 1, 1 + local retry = "" + return function(chunk) + retry = chunk and retry + while true do + if index == top then + chunk = arg[index](chunk) + if chunk == "" or top == n then return chunk + elseif chunk then index = index + 1 + else + top = top+1 + index = top + end + else + chunk = arg[index](chunk or "") + if chunk == "" then + index = index - 1 + chunk = retry + elseif chunk then + if index == n then return chunk + else index = index + 1 end + else base.error("filter returned inappropriate nil") end + end + end + end +end + +----------------------------------------------------------------------------- +-- Source stuff +----------------------------------------------------------------------------- +-- create an empty source +local function empty() + return nil +end + +function source.empty() + return empty +end + +-- returns a source that just outputs an error +function source.error(err) + return function() + return nil, err + end +end + +-- creates a file source +function source.file(handle, io_err) + if handle then + return function() + local chunk = handle:read(BLOCKSIZE) + if not chunk then handle:close() end + return chunk + end + else return source.error(io_err or "unable to open file") end +end + +-- turns a fancy source into a simple source +function source.simplify(src) + base.assert(src) + return function() + local chunk, err_or_new = src() + src = err_or_new or src + if not chunk then return nil, err_or_new + else return chunk end + end +end + +-- creates string source +function source.string(s) + if s then + local i = 1 + return function() + local chunk = string.sub(s, i, i+BLOCKSIZE-1) + i = i + BLOCKSIZE + if chunk ~= "" then return chunk + else return nil end + end + else return source.empty() end +end + +-- creates rewindable source +function source.rewind(src) + base.assert(src) + local t = {} + return function(chunk) + if not chunk then + chunk = table.remove(t) + if not chunk then return src() + else return chunk end + else + table.insert(t, chunk) + end + end +end + +function source.chain(src, f) + base.assert(src and f) + local last_in, last_out = "", "" + local state = "feeding" + local err + return function() + if not last_out then + base.error('source is empty!', 2) + end + while true do + if state == "feeding" then + last_in, err = src() + if err then return nil, err end + last_out = f(last_in) + if not last_out then + if last_in then + base.error('filter returned inappropriate nil') + else + return nil + end + elseif last_out ~= "" then + state = "eating" + if last_in then last_in = "" end + return last_out + end + else + last_out = f(last_in) + if last_out == "" then + if last_in == "" then + state = "feeding" + else + base.error('filter returned ""') + end + elseif not last_out then + if last_in then + base.error('filter returned inappropriate nil') + else + return nil + end + else + return last_out + end + end + end + end +end + +-- creates a source that produces contents of several sources, one after the +-- other, as if they were concatenated +-- (thanks to Wim Couwenberg) +function source.cat(...) + local src = table.remove(arg, 1) + return function() + while src do + local chunk, err = src() + if chunk then return chunk end + if err then return nil, err end + src = table.remove(arg, 1) + end + end +end + +----------------------------------------------------------------------------- +-- Sink stuff +----------------------------------------------------------------------------- +-- creates a sink that stores into a table +function sink.table(t) + t = t or {} + local f = function(chunk, err) + if chunk then table.insert(t, chunk) end + return 1 + end + return f, t +end + +-- turns a fancy sink into a simple sink +function sink.simplify(snk) + base.assert(snk) + return function(chunk, err) + local ret, err_or_new = snk(chunk, err) + if not ret then return nil, err_or_new end + snk = err_or_new or snk + return 1 + end +end + +-- creates a file sink +function sink.file(handle, io_err) + if handle then + return function(chunk, err) + if not chunk then + handle:close() + return 1 + else return handle:write(chunk) end + end + else return sink.error(io_err or "unable to open file") end +end + +-- creates a sink that discards data +local function null() + return 1 +end + +function sink.null() + return null +end + +-- creates a sink that just returns an error +function sink.error(err) + return function() + return nil, err + end +end + +-- chains a sink with a filter +function sink.chain(f, snk) + base.assert(f and snk) + return function(chunk, err) + if chunk ~= "" then + local filtered = f(chunk) + local done = chunk and "" + while true do + local ret, snkerr = snk(filtered, err) + if not ret then return nil, snkerr end + if filtered == done then return 1 end + filtered = f(done) + end + else return 1 end + end +end + +----------------------------------------------------------------------------- +-- Pump stuff +----------------------------------------------------------------------------- +-- pumps one chunk from the source to the sink +function pump.step(src, snk) + local chunk, src_err = src() + local ret, snk_err = snk(chunk, src_err) + if chunk and ret then return 1 + else return nil, src_err or snk_err end +end + +-- pumps all data from a source to a sink, using a step function +function pump.all(src, snk, step) + base.assert(src and snk) + step = step or pump.step + while true do + local ret, err = step(src, snk) + if not ret then + if err then return nil, err + else return 1 end + end + end +end + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/ltn12_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/ltn12_lua.c new file mode 100644 index 00000000000..308bc31f0df --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/ltn12_lua.c @@ -0,0 +1,422 @@ +/* + * This file is auto-generated by "./lua2c ltn12.lua ltn12_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_ltn12_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 76, 84, 78, 49, 50, 32, 45, 32, 70,105,108,116,101,114,115, 44, 32,115,111, +117,114, 99,101,115, 44, 32,115,105,110,107,115, 32, 97,110,100, 32,112,117,109, +112,115, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111, +108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101, +103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, + 36, 73,100, 58, 32,108,116,110, 49, 50, 46,108,117, 97, 44,118, 32, 49, 46, 51, + 49, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51, 32, 48, 52, 58, 52, 53, 58, 52, + 50, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114, +101, 32,109,111,100,117,108,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10, +108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114, +101, 40, 34,116, 97, 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115, +101, 32, 61, 32, 95, 71, 10,109,111,100,117,108,101, 40, 34,108,116,110, 49, 50, + 34, 41, 10, 10,102,105,108,116,101,114, 32, 61, 32,123,125, 10,115,111,117,114, + 99,101, 32, 61, 32,123,125, 10,115,105,110,107, 32, 61, 32,123,125, 10,112,117, +109,112, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 50, 48, 52, 56, 32,115,101,101, +109,115, 32,116,111, 32, 98,101, 32, 98,101,116,116,101,114, 32,105,110, 32,119, +105,110,100,111,119,115, 46, 46, 46, 10, 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, + 61, 32, 50, 48, 52, 56, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32, 61, 32, 34, 76, + 84, 78, 49, 50, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 70,105,108,116,101,114, + 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,105, +103,104, 32,108,101,118,101,108, 32,102,105,108,116,101,114, 32,116,104, 97,116, + 32, 99,121, 99,108,101,115, 32, 97, 32,108,111,119, 45,108,101,118,101,108, 32, +102,105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,102,105,108,116, +101,114, 46, 99,121, 99,108,101, 40,108,111,119, 44, 32, 99,116,120, 44, 32,101, +120,116,114, 97, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114, +116, 40,108,111,119, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117, +110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32,114,101,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116, 44, 32, 99,116,120, 32, 61, 32,108,111,119, 40, 99,116,120, 44, 32, + 99,104,117,110,107, 44, 32,101,120,116,114, 97, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,114,101,116, 10, 32, 32, 32, 32,101,110,100, + 10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105,110,115, 32, 97, 32, 98,117, +110, 99,104, 32,111,102, 32,102,105,108,116,101,114,115, 32,116,111,103,101,116, +104,101,114, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32,116,111, 32, 87,105, +109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102,117,110, 99,116,105, +111,110, 32,102,105,108,116,101,114, 46, 99,104, 97,105,110, 40, 46, 46, 46, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,110, 32, 61, 32,116, 97, 98,108,101, + 46,103,101,116,110, 40, 97,114,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,116,111,112, 44, 32,105,110,100,101,120, 32, 61, 32, 49, 44, 32, 49, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32,114,101,116,114,121, 32, 61, 32, 34, 34, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, + 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,114,121, + 32, 61, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116,114,121, 10, 32, + 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,105,110,100,101, +120, 32, 61, 61, 32,116,111,112, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114, +103, 91,105,110,100,101,120, 93, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, + 32, 61, 61, 32, 34, 34, 32,111,114, 32,116,111,112, 32, 61, 61, 32,110, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32, + 99,104,117,110,107, 32,116,104,101,110, 32,105,110,100,101,120, 32, 61, 32,105, +110,100,101,120, 32, 43, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116,111,112, 32, 61, 32,116,111,112, 43, + 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,110,100,101,120, 32, 61, 32,116,111,112, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114,103, 91,105, +110,100,101,120, 93, 40, 99,104,117,110,107, 32,111,114, 32, 34, 34, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104, +117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,110,100,101,120, + 32, 61, 32,105,110,100,101,120, 32, 45, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, + 32,114,101,116,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,108,115,101,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,105,102, 32,105,110,100,101,120, 32, 61, 61, 32,110, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,105,110, +100,101,120, 32, 61, 32,105,110,100,101,120, 32, 43, 32, 49, 32,101,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 34,102,105,108,116,101,114, 32, +114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97, +116,101, 32,110,105,108, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,111,117,114, 99, +101, 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32, 97,110, 32,101, +109,112,116,121, 32,115,111,117,114, 99,101, 10,108,111, 99, 97,108, 32,102,117, +110, 99,116,105,111,110, 32,101,109,112,116,121, 40, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,110,105,108, 10,101,110,100, 10, 10,102,117,110, 99,116, +105,111,110, 32,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,101,109,112,116,121, 10,101,110,100, 10, + 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,115,111,117,114, 99,101, + 32,116,104, 97,116, 32,106,117,115,116, 32,111,117,116,112,117,116,115, 32, 97, +110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,111,117, +114, 99,101, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, + 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, + 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,111,117,114, 99,101, 10,102, +117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,102,105,108,101, 40, +104, 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32, +105,102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, +104,117,110,107, 32, 61, 32,104, 97,110,100,108,101, 58,114,101, 97,100, 40, 66, + 76, 79, 67, 75, 83, 73, 90, 69, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32, +104, 97,110,100,108,101, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104, +117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46,101, +114,114,111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98, +108,101, 32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110, +100, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114,110,115, 32, 97, 32,102, 97, +110, 99,121, 32,115,111,117,114, 99,101, 32,105,110,116,111, 32, 97, 32,115,105, +109,112,108,101, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, + 32,115,111,117,114, 99,101, 46,115,105,109,112,108,105,102,121, 40,115,114, 99, + 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, + 99, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, +111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, +104,117,110,107, 44, 32,101,114,114, 95,111,114, 95,110,101,119, 32, 61, 32,115, +114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,114, 99, 32, 61, 32,101, +114,114, 95,111,114, 95,110,101,119, 32,111,114, 32,115,114, 99, 10, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 95,111, +114, 95,110,101,119, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, 32, 32, +101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, +115,116,114,105,110,103, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105, +111,110, 32,115,111,117,114, 99,101, 46,115,116,114,105,110,103, 40,115, 41, 10, + 32, 32, 32, 32,105,102, 32,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32,105, 32, 61, 32, 49, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104, +117,110,107, 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115, 44, 32, +105, 44, 32,105, 43, 66, 76, 79, 67, 75, 83, 73, 90, 69, 45, 49, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, 32, 61, 32,105, 32, 43, 32, 66, 76, + 79, 67, 75, 83, 73, 90, 69, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, + 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46, +101,109,112,116,121, 40, 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, + 99,114,101, 97,116,101,115, 32,114,101,119,105,110,100, 97, 98,108,101, 32,115, +111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,111,117,114, 99, +101, 46,114,101,119,105,110,100, 40,115,114, 99, 41, 10, 32, 32, 32, 32, 98, 97, +115,101, 46, 97,115,115,101,114,116, 40,115,114, 99, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117, +110,107, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40,116, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, + 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,114, + 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99, +104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,115,114, 99, 44, 32,102, 41, + 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, 99, + 32, 97,110,100, 32,102, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108, 97, +115,116, 95,105,110, 44, 32,108, 97,115,116, 95,111,117,116, 32, 61, 32, 34, 34, + 44, 32, 34, 34, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,116, 97,116,101, + 32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,101,114,114, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117, +110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, + 40, 39,115,111,117,114, 99,101, 32,105,115, 32,101,109,112,116,121, 33, 39, 44, + 32, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116, 97,116,101, 32, 61, + 61, 32, 34,102,101,101,100,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,105,110, + 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97, +115,116, 95,111,117,116, 32, 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, +111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115, +101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101,114, 32,114,101,116,117, +114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97,116,101, 32,110, +105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, + 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,108, 97,115,116, 95,111,117,116, + 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116, 97,116,101, 32, 61, 32, + 34,101, 97,116,105,110,103, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32, +116,104,101,110, 32,108, 97,115,116, 95,105,110, 32, 61, 32, 34, 34, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,111,117,116, 32, + 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,111,117,116, + 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95, +105,110, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116, + 97,116,101, 32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108, +116,101,114, 32,114,101,116,117,114,110,101,100, 32, 34, 34, 39, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108, +115,101,105,102, 32,110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101, +114, 32,114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114, +105, 97,116,101, 32,110,105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97, +116,101,115, 32, 97, 32,115,111,117,114, 99,101, 32,116,104, 97,116, 32,112,114, +111,100,117, 99,101,115, 32, 99,111,110,116,101,110,116,115, 32,111,102, 32,115, +101,118,101,114, 97,108, 32,115,111,117,114, 99,101,115, 44, 32,111,110,101, 32, + 97,102,116,101,114, 32,116,104,101, 10, 45, 45, 32,111,116,104,101,114, 44, 32, + 97,115, 32,105,102, 32,116,104,101,121, 32,119,101,114,101, 32, 99,111,110, 99, + 97,116,101,110, 97,116,101,100, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32, +116,111, 32, 87,105,109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102, +117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46, 99, 97,116, 40, 46, + 46, 46, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,114, 99, 32, 61, 32, +116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97,114,103, 44, 32, 49, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, + 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,115,114, 99, + 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97, +108, 32, 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110, +107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101, +114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +115,114, 99, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97, +114,103, 44, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,105,110,107, 32,115,116, +117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110,107, 32, +116,104, 97,116, 32,115,116,111,114,101,115, 32,105,110,116,111, 32, 97, 32,116, + 97, 98,108,101, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,116, + 97, 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,116, 32, 61, 32,116, 32,111,114, + 32,123,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, + 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99,104,117, +110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,102, 44, 32,116, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114, +110,115, 32, 97, 32,102, 97,110, 99,121, 32,115,105,110,107, 32,105,110,116,111, + 32, 97, 32,115,105,109,112,108,101, 32,115,105,110,107, 10,102,117,110, 99,116, +105,111,110, 32,115,105,110,107, 46,115,105,109,112,108,105,102,121, 40,115,110, +107, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115, +110,107, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116, +105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 95,111, +114, 95,110,101,119, 32, 61, 32,115,110,107, 40, 99,104,117,110,107, 44, 32,101, +114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, +101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 95,111,114, 95,110,101,119, 32,101,110,100, 10, 32, 32, 32, 32, 32, + 32, 32, 32,115,110,107, 32, 61, 32,101,114,114, 95,111,114, 95,110,101,119, 32, +111,114, 32,115,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, + 99,114,101, 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,105,110,107, 10, +102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,102,105,108,101, 40,104, + 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32,105, +102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104, +117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104, 97,110,100, +108,101, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, +104, 97,110,100,108,101, 58,119,114,105,116,101, 40, 99,104,117,110,107, 41, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +101,108,115,101, 32,114,101,116,117,114,110, 32,115,105,110,107, 46,101,114,114, +111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98,108,101, + 32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110,100, 10, +101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105, +110,107, 32,116,104, 97,116, 32,100,105,115, 99, 97,114,100,115, 32,100, 97,116, + 97, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,117,108, +108, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,110,117,108,108, + 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,117,108,108, 10,101, +110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110, +107, 32,116,104, 97,116, 32,106,117,115,116, 32,114,101,116,117,114,110,115, 32, + 97,110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,105, +110,107, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 10, + 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105, +110,115, 32, 97, 32,115,105,110,107, 32,119,105,116,104, 32, 97, 32,102,105,108, +116,101,114, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46, 99,104, + 97,105,110, 40,102, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 98, 97,115,101, + 46, 97,115,115,101,114,116, 40,102, 32, 97,110,100, 32,115,110,107, 41, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99, +104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105, +102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,102,105,108, +116,101,114,101,100, 32, 61, 32,102, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 32, + 61, 32, 99,104,117,110,107, 32, 97,110,100, 32, 34, 34, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114,101,116, 44, 32,115,110,107,101,114,114, 32, 61, 32,115,110,107, + 40,102,105,108,116,101,114,101,100, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, +101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +115,110,107,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,102,105,108,116,101,114,101,100, 32, 61, + 61, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 49, + 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,102,105,108,116,101,114,101,100, 32, 61, 32,102, 40,100,111,110,101, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101,110, +100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80,117,109,112, + 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32,112,117,109,112,115, 32,111,110,101, 32, 99,104, +117,110,107, 32,102,114,111,109, 32,116,104,101, 32,115,111,117,114, 99,101, 32, +116,111, 32,116,104,101, 32,115,105,110,107, 10,102,117,110, 99,116,105,111,110, + 32,112,117,109,112, 46,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,115,114, + 99, 95,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,114,101,116, 44, 32,115,110,107, 95,101,114,114, 32, 61, 32,115, +110,107, 40, 99,104,117,110,107, 44, 32,115,114, 99, 95,101,114,114, 41, 10, 32, + 32, 32, 32,105,102, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32,101,108, +115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,114, 99, 95,101, +114,114, 32,111,114, 32,115,110,107, 95,101,114,114, 32,101,110,100, 10,101,110, +100, 10, 10, 45, 45, 32,112,117,109,112,115, 32, 97,108,108, 32,100, 97,116, 97, + 32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 32,116,111, 32, 97, 32, +115,105,110,107, 44, 32,117,115,105,110,103, 32, 97, 32,115,116,101,112, 32,102, +117,110, 99,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,112,117,109, +112, 46, 97,108,108, 40,115,114, 99, 44, 32,115,110,107, 44, 32,115,116,101,112, + 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, + 99, 32, 97,110,100, 32,115,110,107, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, + 61, 32,115,116,101,112, 32,111,114, 32,112,117,109,112, 46,115,116,101,112, 10, + 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, + 32, 61, 32,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,116, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, +114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, +101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c b/Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c new file mode 100644 index 00000000000..8e27995a414 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c @@ -0,0 +1,73 @@ + +#include +#include "lua.h" +#include "lauxlib.h" + +#include "socket_lua.c" +#include "ftp_lua.c" +#include "http_lua.c" +#include "smtp_lua.c" +#include "tp_lua.c" +#include "url_lua.c" +#include "ltn12_lua.c" +#include "mime_lua.c" + + +void luatex_socketlua_open (lua_State *L) { + lua_getglobal(L, "package"); + lua_getfield(L, -1, "loaded"); + if (!lua_istable(L,-1)) { + lua_newtable(L); + lua_setfield(L, -2, "loaded"); + lua_getfield(L, -1, "loaded"); + } + if(!luatex_socket_lua_open(L)) { + lua_setfield(L, -2, "socket"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_ltn12_lua_open(L)) { + lua_setfield(L, -2, "ltn12"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_mime_lua_open(L)) { + lua_setfield(L, -2, "mime"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_url_lua_open(L)) { + lua_setfield(L, -2, "socket.url"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_tp_lua_open(L)) { + lua_setfield(L, -2, "socket.tp"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_smtp_lua_open(L)) { + lua_setfield(L, -2, "socket.smtp"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_http_lua_open(L)) { + lua_setfield(L, -2, "socket.http"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_ftp_lua_open(L)) { + lua_setfield(L, -2, "socket.ftp"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + lua_pop(L,2); +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.c b/Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.c new file mode 100644 index 00000000000..11ffee94c46 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.c @@ -0,0 +1,118 @@ +/*=========================================================================*\ +* LuaSocket toolkit +* Networking support for the Lua language +* Diego Nehab +* 26/11/1999 +* +* This library is part of an effort to progressively increase the network +* connectivity of the Lua language. The Lua interface to networking +* functions follows the Sockets API closely, trying to simplify all tasks +* involved in setting up both client and server connections. The provided +* IO routines, however, follow the Lua style, being very similar to the +* standard Lua read and write functions. +* +* RCS ID: $Id: luasocket.c,v 1.53 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +/*=========================================================================*\ +* Standard include files +\*=========================================================================*/ +#include "lua.h" +#include "lauxlib.h" + +#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) +#include "compat-5.1.h" +#endif + +/*=========================================================================*\ +* LuaSocket includes +\*=========================================================================*/ +#include "luasocket.h" +#include "auxiliar.h" +#include "except.h" +#include "timeout.h" +#include "buffer.h" +#include "inet.h" +#include "tcp.h" +#include "udp.h" +#include "select.h" + +/*-------------------------------------------------------------------------*\ +* Internal function prototypes +\*-------------------------------------------------------------------------*/ +static int global_skip(lua_State *L); +static int global_unload(lua_State *L); +static int base_open(lua_State *L); + +/*-------------------------------------------------------------------------*\ +* Modules and functions +\*-------------------------------------------------------------------------*/ +static const luaL_reg mod[] = { + {"auxiliar", auxiliar_open}, + {"except", except_open}, + {"timeout", timeout_open}, + {"buffer", buffer_open}, + {"inet", inet_open}, + {"tcp", tcp_open}, + {"udp", udp_open}, + {"select", select_open}, + {NULL, NULL} +}; + +static luaL_reg func[] = { + {"skip", global_skip}, + {"__unload", global_unload}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Skip a few arguments +\*-------------------------------------------------------------------------*/ +static int global_skip(lua_State *L) { + int amount = luaL_checkint(L, 1); + int ret = lua_gettop(L) - amount - 1; + return ret >= 0 ? ret : 0; +} + +/*-------------------------------------------------------------------------*\ +* Unloads the library +\*-------------------------------------------------------------------------*/ +static int global_unload(lua_State *L) { + (void) L; + socket_close(); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Setup basic stuff. +\*-------------------------------------------------------------------------*/ +static int base_open(lua_State *L) { + if (socket_open()) { + /* export functions (and leave namespace table on top of stack) */ + luaL_openlib(L, "socket", func, 0); +#ifdef LUASOCKET_DEBUG + lua_pushstring(L, "_DEBUG"); + lua_pushboolean(L, 1); + lua_rawset(L, -3); +#endif + /* make version string available to scripts */ + lua_pushstring(L, "_VERSION"); + lua_pushstring(L, LUASOCKET_VERSION); + lua_rawset(L, -3); + return 1; + } else { + lua_pushstring(L, "unable to initialize library"); + lua_error(L); + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Initializes all library modules. +\*-------------------------------------------------------------------------*/ +LUASOCKET_API int luaopen_socket_core(lua_State *L) { + int i; + base_open(L); + for (i = 0; mod[i].name; i++) mod[i].func(L); + return 1; +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.h b/Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.h new file mode 100644 index 00000000000..67270abb937 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/luasocket.h @@ -0,0 +1,32 @@ +#ifndef LUASOCKET_H +#define LUASOCKET_H +/*=========================================================================*\ +* LuaSocket toolkit +* Networking support for the Lua language +* Diego Nehab +* 9/11/1999 +* +* RCS ID: $Id: luasocket.h,v 1.25 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +/*-------------------------------------------------------------------------*\ +* Current socket library version +\*-------------------------------------------------------------------------*/ +#define LUASOCKET_VERSION "LuaSocket 2.0.2" +#define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" +#define LUASOCKET_AUTHORS "Diego Nehab" + +/*-------------------------------------------------------------------------*\ +* This macro prefixes all exported API functions +\*-------------------------------------------------------------------------*/ +#ifndef LUASOCKET_API +#define LUASOCKET_API extern +#endif + +/*-------------------------------------------------------------------------*\ +* Initializes the library. +\*-------------------------------------------------------------------------*/ +LUASOCKET_API int luaopen_socket_core(lua_State *L); + +#endif /* LUASOCKET_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/mime.c b/Build/source/texk/web2c/luatexdir/luasocket/src/mime.c new file mode 100644 index 00000000000..700fa05e930 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/mime.c @@ -0,0 +1,711 @@ +/*=========================================================================*\ +* MIME support functions +* LuaSocket toolkit +* +* RCS ID: $Id: mime.c,v 1.28 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" + +#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) +#include "compat-5.1.h" +#endif + +#include "mime.h" + +/*=========================================================================*\ +* Don't want to trust escape character constants +\*=========================================================================*/ +typedef unsigned char UC; +static const char CRLF[] = "\r\n"; +static const char EQCRLF[] = "=\r\n"; + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static int mime_global_wrp(lua_State *L); +static int mime_global_b64(lua_State *L); +static int mime_global_unb64(lua_State *L); +static int mime_global_qp(lua_State *L); +static int mime_global_unqp(lua_State *L); +static int mime_global_qpwrp(lua_State *L); +static int mime_global_eol(lua_State *L); +static int mime_global_dot(lua_State *L); + +static size_t dot(int c, size_t state, luaL_Buffer *buffer); +static void b64setup(UC *b64unbase); +static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); +static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); +static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer); + +static void qpsetup(UC *qpclass, UC *qpunbase); +static void qpquote(UC c, luaL_Buffer *buffer); +static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); +static size_t qpencode(UC c, UC *input, size_t size, + const char *marker, luaL_Buffer *buffer); +static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); + +/* code support functions */ +static luaL_reg func[] = { + { "dot", mime_global_dot }, + { "b64", mime_global_b64 }, + { "eol", mime_global_eol }, + { "qp", mime_global_qp }, + { "qpwrp", mime_global_qpwrp }, + { "unb64", mime_global_unb64 }, + { "unqp", mime_global_unqp }, + { "wrp", mime_global_wrp }, + { NULL, NULL } +}; + +/*-------------------------------------------------------------------------*\ +* Quoted-printable globals +\*-------------------------------------------------------------------------*/ +static UC qpclass[256]; +static UC qpbase[] = "0123456789ABCDEF"; +static UC qpunbase[256]; +enum {QP_PLAIN, QP_QUOTED, QP_CR, QP_IF_LAST}; + +/*-------------------------------------------------------------------------*\ +* Base64 globals +\*-------------------------------------------------------------------------*/ +static const UC b64base[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static UC b64unbase[256]; + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +MIME_API int luaopen_mime_core(lua_State *L) +{ + luaL_openlib(L, "mime", func, 0); + /* make version string available to scripts */ + lua_pushstring(L, "_VERSION"); + lua_pushstring(L, MIME_VERSION); + lua_rawset(L, -3); + /* initialize lookup tables */ + qpsetup(qpclass, qpunbase); + b64setup(b64unbase); + return 1; +} + +/*=========================================================================*\ +* Global Lua functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Incrementaly breaks a string into lines. The string can have CRLF breaks. +* A, n = wrp(l, B, length) +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. +\*-------------------------------------------------------------------------*/ +static int mime_global_wrp(lua_State *L) +{ + size_t size = 0; + int left = (int) luaL_checknumber(L, 1); + const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *last = input + size; + int length = (int) luaL_optnumber(L, 3, 76); + luaL_Buffer buffer; + /* end of input black-hole */ + if (!input) { + /* if last line has not been terminated, add a line break */ + if (left < length) lua_pushstring(L, CRLF); + /* otherwise, we are done */ + else lua_pushnil(L); + lua_pushnumber(L, length); + return 2; + } + luaL_buffinit(L, &buffer); + while (input < last) { + switch (*input) { + case '\r': + break; + case '\n': + luaL_addstring(&buffer, CRLF); + left = length; + break; + default: + if (left <= 0) { + left = length; + luaL_addstring(&buffer, CRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; + } + input++; + } + luaL_pushresult(&buffer); + lua_pushnumber(L, left); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Fill base64 decode map. +\*-------------------------------------------------------------------------*/ +static void b64setup(UC *b64unbase) +{ + int i; + for (i = 0; i <= 255; i++) b64unbase[i] = (UC) 255; + for (i = 0; i < 64; i++) b64unbase[b64base[i]] = (UC) i; + b64unbase['='] = 0; +} + +/*-------------------------------------------------------------------------*\ +* Acumulates bytes in input buffer until 3 bytes are available. +* Translate the 3 bytes into Base64 form and append to buffer. +* Returns new number of bytes in buffer. +\*-------------------------------------------------------------------------*/ +static size_t b64encode(UC c, UC *input, size_t size, + luaL_Buffer *buffer) +{ + input[size++] = c; + if (size == 3) { + UC code[4]; + unsigned long value = 0; + value += input[0]; value <<= 8; + value += input[1]; value <<= 8; + value += input[2]; + code[3] = b64base[value & 0x3f]; value >>= 6; + code[2] = b64base[value & 0x3f]; value >>= 6; + code[1] = b64base[value & 0x3f]; value >>= 6; + code[0] = b64base[value]; + luaL_addlstring(buffer, (char *) code, 4); + size = 0; + } + return size; +} + +/*-------------------------------------------------------------------------*\ +* Encodes the Base64 last 1 or 2 bytes and adds padding '=' +* Result, if any, is appended to buffer. +* Returns 0. +\*-------------------------------------------------------------------------*/ +static size_t b64pad(const UC *input, size_t size, + luaL_Buffer *buffer) +{ + unsigned long value = 0; + UC code[4] = {'=', '=', '=', '='}; + switch (size) { + case 1: + value = input[0] << 4; + code[1] = b64base[value & 0x3f]; value >>= 6; + code[0] = b64base[value]; + luaL_addlstring(buffer, (char *) code, 4); + break; + case 2: + value = input[0]; value <<= 8; + value |= input[1]; value <<= 2; + code[2] = b64base[value & 0x3f]; value >>= 6; + code[1] = b64base[value & 0x3f]; value >>= 6; + code[0] = b64base[value]; + luaL_addlstring(buffer, (char *) code, 4); + break; + default: + break; + } + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Acumulates bytes in input buffer until 4 bytes are available. +* Translate the 4 bytes from Base64 form and append to buffer. +* Returns new number of bytes in buffer. +\*-------------------------------------------------------------------------*/ +static size_t b64decode(UC c, UC *input, size_t size, + luaL_Buffer *buffer) +{ + /* ignore invalid characters */ + if (b64unbase[c] > 64) return size; + input[size++] = c; + /* decode atom */ + if (size == 4) { + UC decoded[3]; + int valid, value = 0; + value = b64unbase[input[0]]; value <<= 6; + value |= b64unbase[input[1]]; value <<= 6; + value |= b64unbase[input[2]]; value <<= 6; + value |= b64unbase[input[3]]; + decoded[2] = (UC) (value & 0xff); value >>= 8; + decoded[1] = (UC) (value & 0xff); value >>= 8; + decoded[0] = (UC) value; + /* take care of paddding */ + valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3; + luaL_addlstring(buffer, (char *) decoded, valid); + return 0; + /* need more data */ + } else return size; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally applies the Base64 transfer content encoding to a string +* A, B = b64(C, D) +* A is the encoded version of the largest prefix of C .. D that is +* divisible by 3. B has the remaining bytes of C .. D, *without* encoding. +* The easiest thing would be to concatenate the two strings and +* encode the result, but we can't afford that or Lua would dupplicate +* every chunk we received. +\*-------------------------------------------------------------------------*/ +static int mime_global_b64(lua_State *L) +{ + UC atom[3]; + size_t isize = 0, asize = 0; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of the input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = b64encode(*input++, atom, asize, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second part is nil, we are done */ + if (!input) { + asize = b64pad(atom, asize, &buffer); + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise process the second part */ + last = input + isize; + while (input < last) + asize = b64encode(*input++, atom, asize, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally removes the Base64 transfer content encoding from a string +* A, B = b64(C, D) +* A is the encoded version of the largest prefix of C .. D that is +* divisible by 4. B has the remaining bytes of C .. D, *without* encoding. +\*-------------------------------------------------------------------------*/ +static int mime_global_unb64(lua_State *L) +{ + UC atom[4]; + size_t isize = 0, asize = 0; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of the input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = b64decode(*input++, atom, asize, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second is nil, we are done */ + if (!input) { + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise, process the rest of the input */ + last = input + isize; + while (input < last) + asize = b64decode(*input++, atom, asize, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Quoted-printable encoding scheme +* all (except CRLF in text) can be =XX +* CLRL in not text must be =XX=XX +* 33 through 60 inclusive can be plain +* 62 through 126 inclusive can be plain +* 9 and 32 can be plain, unless in the end of a line, where must be =XX +* encoded lines must be no longer than 76 not counting CRLF +* soft line-break are =CRLF +* To encode one byte, we need to see the next two. +* Worst case is when we see a space, and wonder if a CRLF is comming +\*-------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------*\ +* Split quoted-printable characters into classes +* Precompute reverse map for encoding +\*-------------------------------------------------------------------------*/ +static void qpsetup(UC *qpclass, UC *qpunbase) +{ + int i; + for (i = 0; i < 256; i++) qpclass[i] = QP_QUOTED; + for (i = 33; i <= 60; i++) qpclass[i] = QP_PLAIN; + for (i = 62; i <= 126; i++) qpclass[i] = QP_PLAIN; + qpclass['\t'] = QP_IF_LAST; + qpclass[' '] = QP_IF_LAST; + qpclass['\r'] = QP_CR; + for (i = 0; i < 256; i++) qpunbase[i] = 255; + qpunbase['0'] = 0; qpunbase['1'] = 1; qpunbase['2'] = 2; + qpunbase['3'] = 3; qpunbase['4'] = 4; qpunbase['5'] = 5; + qpunbase['6'] = 6; qpunbase['7'] = 7; qpunbase['8'] = 8; + qpunbase['9'] = 9; qpunbase['A'] = 10; qpunbase['a'] = 10; + qpunbase['B'] = 11; qpunbase['b'] = 11; qpunbase['C'] = 12; + qpunbase['c'] = 12; qpunbase['D'] = 13; qpunbase['d'] = 13; + qpunbase['E'] = 14; qpunbase['e'] = 14; qpunbase['F'] = 15; + qpunbase['f'] = 15; +} + +/*-------------------------------------------------------------------------*\ +* Output one character in form =XX +\*-------------------------------------------------------------------------*/ +static void qpquote(UC c, luaL_Buffer *buffer) +{ + luaL_putchar(buffer, '='); + luaL_putchar(buffer, qpbase[c >> 4]); + luaL_putchar(buffer, qpbase[c & 0x0F]); +} + +/*-------------------------------------------------------------------------*\ +* Accumulate characters until we are sure about how to deal with them. +* Once we are sure, output to the buffer, in the correct form. +\*-------------------------------------------------------------------------*/ +static size_t qpencode(UC c, UC *input, size_t size, + const char *marker, luaL_Buffer *buffer) +{ + input[size++] = c; + /* deal with all characters we can have */ + while (size > 0) { + switch (qpclass[input[0]]) { + /* might be the CR of a CRLF sequence */ + case QP_CR: + if (size < 2) return size; + if (input[1] == '\n') { + luaL_addstring(buffer, marker); + return 0; + } else qpquote(input[0], buffer); + break; + /* might be a space and that has to be quoted if last in line */ + case QP_IF_LAST: + if (size < 3) return size; + /* if it is the last, quote it and we are done */ + if (input[1] == '\r' && input[2] == '\n') { + qpquote(input[0], buffer); + luaL_addstring(buffer, marker); + return 0; + } else luaL_putchar(buffer, input[0]); + break; + /* might have to be quoted always */ + case QP_QUOTED: + qpquote(input[0], buffer); + break; + /* might never have to be quoted */ + default: + luaL_putchar(buffer, input[0]); + break; + } + input[0] = input[1]; input[1] = input[2]; + size--; + } + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Deal with the final characters +\*-------------------------------------------------------------------------*/ +static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) +{ + size_t i; + for (i = 0; i < size; i++) { + if (qpclass[input[i]] == QP_PLAIN) luaL_putchar(buffer, input[i]); + else qpquote(input[i], buffer); + } + if (size > 0) luaL_addstring(buffer, EQCRLF); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally converts a string to quoted-printable +* A, B = qp(C, D, marker) +* Marker is the text to be used to replace CRLF sequences found in A. +* A is the encoded version of the largest prefix of C .. D that +* can be encoded without doubts. +* B has the remaining bytes of C .. D, *without* encoding. +\*-------------------------------------------------------------------------*/ +static int mime_global_qp(lua_State *L) +{ + + size_t asize = 0, isize = 0; + UC atom[3]; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + const char *marker = luaL_optstring(L, 3, CRLF); + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = qpencode(*input++, atom, asize, marker, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second part is nil, we are done */ + if (!input) { + asize = qppad(atom, asize, &buffer); + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise process rest of input */ + last = input + isize; + while (input < last) + asize = qpencode(*input++, atom, asize, marker, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Accumulate characters until we are sure about how to deal with them. +* Once we are sure, output the to the buffer, in the correct form. +\*-------------------------------------------------------------------------*/ +static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { + int d; + input[size++] = c; + /* deal with all characters we can deal */ + switch (input[0]) { + /* if we have an escape character */ + case '=': + if (size < 3) return size; + /* eliminate soft line break */ + if (input[1] == '\r' && input[2] == '\n') return 0; + /* decode quoted representation */ + c = qpunbase[input[1]]; d = qpunbase[input[2]]; + /* if it is an invalid, do not decode */ + if (c > 15 || d > 15) luaL_addlstring(buffer, (char *)input, 3); + else luaL_putchar(buffer, (c << 4) + d); + return 0; + case '\r': + if (size < 2) return size; + if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2); + return 0; + default: + if (input[0] == '\t' || (input[0] > 31 && input[0] < 127)) + luaL_putchar(buffer, input[0]); + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Incrementally decodes a string in quoted-printable +* A, B = qp(C, D) +* A is the decoded version of the largest prefix of C .. D that +* can be decoded without doubts. +* B has the remaining bytes of C .. D, *without* decoding. +\*-------------------------------------------------------------------------*/ +static int mime_global_unqp(lua_State *L) +{ + size_t asize = 0, isize = 0; + UC atom[3]; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = qpdecode(*input++, atom, asize, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second part is nil, we are done */ + if (!input) { + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise process rest of input */ + last = input + isize; + while (input < last) + asize = qpdecode(*input++, atom, asize, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally breaks a quoted-printed string into lines +* A, n = qpwrp(l, B, length) +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. +* There are two complications: lines can't be broken in the middle +* of an encoded =XX, and there might be line breaks already +\*-------------------------------------------------------------------------*/ +static int mime_global_qpwrp(lua_State *L) +{ + size_t size = 0; + int left = (int) luaL_checknumber(L, 1); + const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *last = input + size; + int length = (int) luaL_optnumber(L, 3, 76); + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + if (left < length) lua_pushstring(L, EQCRLF); + else lua_pushnil(L); + lua_pushnumber(L, length); + return 2; + } + /* process all input */ + luaL_buffinit(L, &buffer); + while (input < last) { + switch (*input) { + case '\r': + break; + case '\n': + left = length; + luaL_addstring(&buffer, CRLF); + break; + case '=': + if (left <= 3) { + left = length; + luaL_addstring(&buffer, EQCRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; + default: + if (left <= 1) { + left = length; + luaL_addstring(&buffer, EQCRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; + } + input++; + } + luaL_pushresult(&buffer); + lua_pushnumber(L, left); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Here is what we do: \n, and \r are considered candidates for line +* break. We issue *one* new line marker if any of them is seen alone, or +* followed by a different one. That is, \n\n and \r\r will issue two +* end of line markers each, but \r\n, \n\r etc will only issue *one* +* marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as +* probably other more obscure conventions. +* +* c is the current character being processed +* last is the previous character +\*-------------------------------------------------------------------------*/ +#define eolcandidate(c) (c == '\r' || c == '\n') +static int eolprocess(int c, int last, const char *marker, + luaL_Buffer *buffer) +{ + if (eolcandidate(c)) { + if (eolcandidate(last)) { + if (c == last) luaL_addstring(buffer, marker); + return 0; + } else { + luaL_addstring(buffer, marker); + return c; + } + } else { + luaL_putchar(buffer, c); + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Converts a string to uniform EOL convention. +* A, n = eol(o, B, marker) +* A is the converted version of the largest prefix of B that can be +* converted unambiguously. 'o' is the context returned by the previous +* call. 'n' is the new context. +\*-------------------------------------------------------------------------*/ +static int mime_global_eol(lua_State *L) +{ + int ctx = luaL_checkint(L, 1); + size_t isize = 0; + const char *input = luaL_optlstring(L, 2, NULL, &isize); + const char *last = input + isize; + const char *marker = luaL_optstring(L, 3, CRLF); + luaL_Buffer buffer; + luaL_buffinit(L, &buffer); + /* end of input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnumber(L, 0); + return 2; + } + /* process all input */ + while (input < last) + ctx = eolprocess(*input++, ctx, marker, &buffer); + luaL_pushresult(&buffer); + lua_pushnumber(L, ctx); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Takes one byte and stuff it if needed. +\*-------------------------------------------------------------------------*/ +static size_t dot(int c, size_t state, luaL_Buffer *buffer) +{ + luaL_putchar(buffer, c); + switch (c) { + case '\r': + return 1; + case '\n': + return (state == 1)? 2: 0; + case '.': + if (state == 2) + luaL_putchar(buffer, '.'); + default: + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Incrementally applies smtp stuffing to a string +* A, n = dot(l, D) +\*-------------------------------------------------------------------------*/ +static int mime_global_dot(lua_State *L) +{ + size_t isize = 0, state = (size_t) luaL_checknumber(L, 1); + const char *input = luaL_optlstring(L, 2, NULL, &isize); + const char *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnumber(L, 2); + return 2; + } + /* process all input */ + luaL_buffinit(L, &buffer); + while (input < last) + state = dot(*input++, state, &buffer); + luaL_pushresult(&buffer); + lua_pushnumber(L, state); + return 2; +} + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/mime.h b/Build/source/texk/web2c/luatexdir/luasocket/src/mime.h new file mode 100644 index 00000000000..85ee2a39856 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/mime.h @@ -0,0 +1,31 @@ +#ifndef MIME_H +#define MIME_H +/*=========================================================================*\ +* Core MIME support +* LuaSocket toolkit +* +* This module provides functions to implement transfer content encodings +* and formatting conforming to RFC 2045. It is used by mime.lua, which +* provide a higher level interface to this functionality. +* +* RCS ID: $Id: mime.h,v 1.15 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +/*-------------------------------------------------------------------------*\ +* Current MIME library version +\*-------------------------------------------------------------------------*/ +#define MIME_VERSION "MIME 1.0.2" +#define MIME_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" +#define MIME_AUTHORS "Diego Nehab" + +/*-------------------------------------------------------------------------*\ +* This macro prefixes all exported API functions +\*-------------------------------------------------------------------------*/ +#ifndef MIME_API +#define MIME_API extern +#endif + +MIME_API int luaopen_mime_core(lua_State *L); + +#endif /* MIME_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/mime.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/mime.lua new file mode 100644 index 00000000000..169eda29a94 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/mime.lua @@ -0,0 +1,87 @@ +----------------------------------------------------------------------------- +-- MIME support for the Lua language. +-- Author: Diego Nehab +-- Conforming to RFCs 2045-2049 +-- RCS ID: $Id: mime.lua,v 1.29 2007/06/11 23:44:54 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local ltn12 = require("ltn12") +local mime = require("mime.core") +local io = require("io") +local string = require("string") +module("mime") + +-- encode, decode and wrap algorithm tables +encodet = {} +decodet = {} +wrapt = {} + +-- creates a function that chooses a filter by name from a given table +local function choose(table) + return function(name, opt1, opt2) + if base.type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = table[name or "nil"] + if not f then + base.error("unknown key (" .. base.tostring(name) .. ")", 3) + else return f(opt1, opt2) end + end +end + +-- define the encoding filters +encodet['base64'] = function() + return ltn12.filter.cycle(b64, "") +end + +encodet['quoted-printable'] = function(mode) + return ltn12.filter.cycle(qp, "", + (mode == "binary") and "=0D=0A" or "\r\n") +end + +-- define the decoding filters +decodet['base64'] = function() + return ltn12.filter.cycle(unb64, "") +end + +decodet['quoted-printable'] = function() + return ltn12.filter.cycle(unqp, "") +end + +local function format(chunk) + if chunk then + if chunk == "" then return "''" + else return string.len(chunk) end + else return "nil" end +end + +-- define the line-wrap filters +wrapt['text'] = function(length) + length = length or 76 + return ltn12.filter.cycle(wrp, length, length) +end +wrapt['base64'] = wrapt['text'] +wrapt['default'] = wrapt['text'] + +wrapt['quoted-printable'] = function() + return ltn12.filter.cycle(qpwrp, 76, 76) +end + +-- function that choose the encoding, decoding or wrap algorithm +encode = choose(encodet) +decode = choose(decodet) +wrap = choose(wrapt) + +-- define the end-of-line normalization filter +function normalize(marker) + return ltn12.filter.cycle(eol, 0, marker) +end + +-- high level stuffing filter +function stuff() + return ltn12.filter.cycle(dot, 2) +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/mime_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/mime_lua.c new file mode 100644 index 00000000000..e131536a8b4 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/mime_lua.c @@ -0,0 +1,135 @@ +/* + * This file is auto-generated by "./lua2c mime.lua mime_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_mime_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 77, 73, 77, 69, 32,115,117,112,112,111,114,116, 32,102,111,114, 32,116,104, +101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 46, 10, 45, 45, 32, 65, +117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, + 45, 32, 67,111,110,102,111,114,109,105,110,103, 32,116,111, 32, 82, 70, 67,115, + 32, 50, 48, 52, 53, 45, 50, 48, 52, 57, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, + 58, 32, 36, 73,100, 58, 32,109,105,109,101, 46,108,117, 97, 44,118, 32, 49, 46, + 50, 57, 32, 50, 48, 48, 55, 47, 48, 54, 47, 49, 49, 32, 50, 51, 58, 52, 52, 58, + 53, 52, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97, +114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, + 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97, +115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108, +111, 99, 97,108, 32,109,105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, + 34,109,105,109,101, 46, 99,111,114,101, 34, 41, 10,108,111, 99, 97,108, 32,105, +111, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,105,111, 34, 41, 10,108,111, + 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,115,116,114,105,110,103, 34, 41, 10,109,111,100,117,108,101, 40, 34,109, +105,109,101, 34, 41, 10, 10, 45, 45, 32,101,110, 99,111,100,101, 44, 32,100,101, + 99,111,100,101, 32, 97,110,100, 32,119,114, 97,112, 32, 97,108,103,111,114,105, +116,104,109, 32,116, 97, 98,108,101,115, 10,101,110, 99,111,100,101,116, 32, 61, + 32,123,125, 10,100,101, 99,111,100,101,116, 32, 61, 32,123,125, 10,119,114, 97, +112,116, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, + 97, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99,104,111,111, +115,101,115, 32, 97, 32,102,105,108,116,101,114, 32, 98,121, 32,110, 97,109,101, + 32,102,114,111,109, 32, 97, 32,103,105,118,101,110, 32,116, 97, 98,108,101, 10, +108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115, +101, 40,116, 97, 98,108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +102,117,110, 99,116,105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, + 32,111,112,116, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97, +115,101, 46,116,121,112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116, +114,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, + 61, 32, 34,100,101,102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111, +112,116, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91, +110, 97,109,101, 32,111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,102, 32,116,104,101,110, 32, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, + 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 32, 46, 46, 32, + 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, 32, + 46, 46, 32, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111, +112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, + 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110, 99,111, +100,105,110,103, 32,102,105,108,116,101,114,115, 10,101,110, 99,111,100,101,116, + 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111, +110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,116,110, 49, 50, + 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, 98, 54, 52, 44, 32, 34, + 34, 41, 10,101,110,100, 10, 10,101,110, 99,111,100,101,116, 91, 39,113,117,111, +116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40,109,111,100,101, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99, +108,101, 40,113,112, 44, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, +109,111,100,101, 32, 61, 61, 32, 34, 98,105,110, 97,114,121, 34, 41, 32, 97,110, +100, 32, 34, 61, 48, 68, 61, 48, 65, 34, 32,111,114, 32, 34, 92,114, 92,110, 34, + 41, 10,101,110,100, 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, + 32,100,101, 99,111,100,105,110,103, 32,102,105,108,116,101,114,115, 10,100,101, + 99,111,100,101,116, 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40,117, +110, 98, 54, 52, 44, 32, 34, 34, 41, 10,101,110,100, 10, 10,100,101, 99,111,100, +101,116, 91, 39,113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, + 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, + 99,121, 99,108,101, 40,117,110,113,112, 44, 32, 34, 34, 41, 10,101,110,100, 10, + 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,102,111,114,109, + 97,116, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32,105,102, 32, 99,104,117, +110,107, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99, +104,117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32, 34, 39, 39, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,108,101,110, 40, 99, +104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32, 34,110,105,108, 34, 32,101,110,100, 10,101,110,100, 10, + 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,108,105,110,101, 45, +119,114, 97,112, 32,102,105,108,116,101,114,115, 10,119,114, 97,112,116, 91, 39, +116,101,120,116, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,108,101, +110,103,116,104, 41, 10, 32, 32, 32, 32,108,101,110,103,116,104, 32, 61, 32,108, +101,110,103,116,104, 32,111,114, 32, 55, 54, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108, +101, 40,119,114,112, 44, 32,108,101,110,103,116,104, 44, 32,108,101,110,103,116, +104, 41, 10,101,110,100, 10,119,114, 97,112,116, 91, 39, 98, 97,115,101, 54, 52, + 39, 93, 32, 61, 32,119,114, 97,112,116, 91, 39,116,101,120,116, 39, 93, 10,119, +114, 97,112,116, 91, 39,100,101,102, 97,117,108,116, 39, 93, 32, 61, 32,119,114, + 97,112,116, 91, 39,116,101,120,116, 39, 93, 10, 10,119,114, 97,112,116, 91, 39, +113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108, +101, 40,113,112,119,114,112, 44, 32, 55, 54, 44, 32, 55, 54, 41, 10,101,110,100, + 10, 10, 45, 45, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99, +104,111,111,115,101, 32,116,104,101, 32,101,110, 99,111,100,105,110,103, 44, 32, +100,101, 99,111,100,105,110,103, 32,111,114, 32,119,114, 97,112, 32, 97,108,103, +111,114,105,116,104,109, 10,101,110, 99,111,100,101, 32, 61, 32, 99,104,111,111, +115,101, 40,101,110, 99,111,100,101,116, 41, 10,100,101, 99,111,100,101, 32, 61, + 32, 99,104,111,111,115,101, 40,100,101, 99,111,100,101,116, 41, 10,119,114, 97, +112, 32, 61, 32, 99,104,111,111,115,101, 40,119,114, 97,112,116, 41, 10, 10, 45, + 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110,100, 45,111,102, 45, +108,105,110,101, 32,110,111,114,109, 97,108,105,122, 97,116,105,111,110, 32,102, +105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,110,111,114,109, 97, +108,105,122,101, 40,109, 97,114,107,101,114, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99, +108,101, 40,101,111,108, 44, 32, 48, 44, 32,109, 97,114,107,101,114, 41, 10,101, +110,100, 10, 10, 45, 45, 32,104,105,103,104, 32,108,101,118,101,108, 32,115,116, +117,102,102,105,110,103, 32,102,105,108,116,101,114, 10,102,117,110, 99,116,105, +111,110, 32,115,116,117,102,102, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, + 40,100,111,116, 44, 32, 50, 41, 10,101,110,100, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/options.c b/Build/source/texk/web2c/luatexdir/luasocket/src/options.c new file mode 100644 index 00000000000..5da3c518c28 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/options.c @@ -0,0 +1,149 @@ +/*=========================================================================*\ +* Common option interface +* LuaSocket toolkit +* +* RCS ID: $Id: options.c,v 1.6 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include + +#include "lauxlib.h" + +#include "auxiliar.h" +#include "options.h" +#include "inet.h" + + +/*=========================================================================*\ +* Internal functions prototypes +\*=========================================================================*/ +static int opt_setmembership(lua_State *L, p_socket ps, int level, int name); +static int opt_setboolean(lua_State *L, p_socket ps, int level, int name); +static int opt_set(lua_State *L, p_socket ps, int level, int name, + void *val, int len); + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Calls appropriate option handler +\*-------------------------------------------------------------------------*/ +int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps) +{ + const char *name = luaL_checkstring(L, 2); /* obj, name, ... */ + while (opt->name && strcmp(name, opt->name)) + opt++; + if (!opt->func) { + char msg[45]; + sprintf(msg, "unsupported option `%.35s'", name); + luaL_argerror(L, 2, msg); + } + return opt->func(L, ps); +} + +/* enables reuse of local address */ +int opt_reuseaddr(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); +} + +/* disables the Naggle algorithm */ +int opt_tcp_nodelay(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); +} + +int opt_keepalive(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); +} + +int opt_dontroute(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); +} + +int opt_broadcast(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); +} + +int opt_ip_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); +} + +int opt_linger(lua_State *L, p_socket ps) +{ + struct linger li; /* obj, name, table */ + if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); + lua_pushstring(L, "on"); + lua_gettable(L, 3); + if (!lua_isboolean(L, -1)) + luaL_argerror(L, 3, "boolean 'on' field expected"); + li.l_onoff = (u_short) lua_toboolean(L, -1); + lua_pushstring(L, "timeout"); + lua_gettable(L, 3); + if (!lua_isnumber(L, -1)) + luaL_argerror(L, 3, "number 'timeout' field expected"); + li.l_linger = (u_short) lua_tonumber(L, -1); + return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); +} + +int opt_ip_multicast_ttl(lua_State *L, p_socket ps) +{ + int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ + return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &val, sizeof(val)); +} + +int opt_ip_add_membership(lua_State *L, p_socket ps) +{ + return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); +} + +int opt_ip_drop_membersip(lua_State *L, p_socket ps) +{ + return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); +} + +/*=========================================================================*\ +* Auxiliar functions +\*=========================================================================*/ +static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) +{ + struct ip_mreq val; /* obj, name, table */ + if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); + lua_pushstring(L, "multiaddr"); + lua_gettable(L, 3); + if (!lua_isstring(L, -1)) + luaL_argerror(L, 3, "string 'multiaddr' field expected"); + if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr)) + luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); + lua_pushstring(L, "interface"); + lua_gettable(L, 3); + if (!lua_isstring(L, -1)) + luaL_argerror(L, 3, "string 'interface' field expected"); + val.imr_interface.s_addr = htonl(INADDR_ANY); + if (strcmp(lua_tostring(L, -1), "*") && + !inet_aton(lua_tostring(L, -1), &val.imr_interface)) + luaL_argerror(L, 3, "invalid 'interface' ip address"); + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} + +static +int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len) +{ + if (setsockopt(*ps, level, name, (char *) val, len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "setsockopt failed"); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) +{ + int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/options.h b/Build/source/texk/web2c/luatexdir/luasocket/src/options.h new file mode 100644 index 00000000000..4981cf2a0ef --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/options.h @@ -0,0 +1,39 @@ +#ifndef OPTIONS_H +#define OPTIONS_H +/*=========================================================================*\ +* Common option interface +* LuaSocket toolkit +* +* This module provides a common interface to socket options, used mainly by +* modules UDP and TCP. +* +* RCS ID: $Id: options.h,v 1.4 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +#include "lua.h" +#include "socket.h" + +/* option registry */ +typedef struct t_opt { + const char *name; + int (*func)(lua_State *L, p_socket ps); +} t_opt; +typedef t_opt *p_opt; + +/* supported options */ +int opt_dontroute(lua_State *L, p_socket ps); +int opt_broadcast(lua_State *L, p_socket ps); +int opt_reuseaddr(lua_State *L, p_socket ps); +int opt_tcp_nodelay(lua_State *L, p_socket ps); +int opt_keepalive(lua_State *L, p_socket ps); +int opt_linger(lua_State *L, p_socket ps); +int opt_reuseaddr(lua_State *L, p_socket ps); +int opt_ip_multicast_ttl(lua_State *L, p_socket ps); +int opt_ip_multicast_loop(lua_State *L, p_socket ps); +int opt_ip_add_membership(lua_State *L, p_socket ps); +int opt_ip_drop_membersip(lua_State *L, p_socket ps); + +/* invokes the appropriate option handler */ +int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); + +#endif diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/select.c b/Build/source/texk/web2c/luatexdir/luasocket/src/select.c new file mode 100644 index 00000000000..d70f662713a --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/select.c @@ -0,0 +1,200 @@ +/*=========================================================================*\ +* Select implementation +* LuaSocket toolkit +* +* RCS ID: $Id: select.c,v 1.22 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" + +#include "socket.h" +#include "timeout.h" +#include "select.h" + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static t_socket getfd(lua_State *L); +static int dirty(lua_State *L); +static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, + int itab, fd_set *set); +static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set); +static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, + int itab, int tab, int start); +static void make_assoc(lua_State *L, int tab); +static int global_select(lua_State *L); + +/* functions in library namespace */ +static luaL_reg func[] = { + {"select", global_select}, + {NULL, NULL} +}; + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int select_open(lua_State *L) { + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*=========================================================================*\ +* Global Lua functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Waits for a set of sockets until a condition is met or timeout. +\*-------------------------------------------------------------------------*/ +static int global_select(lua_State *L) { + int rtab, wtab, itab, ret, ndirty; + t_socket max_fd; + fd_set rset, wset; + t_timeout tm; + double t = luaL_optnumber(L, 3, -1); + FD_ZERO(&rset); FD_ZERO(&wset); + lua_settop(L, 3); + lua_newtable(L); itab = lua_gettop(L); + lua_newtable(L); rtab = lua_gettop(L); + lua_newtable(L); wtab = lua_gettop(L); + max_fd = collect_fd(L, 1, SOCKET_INVALID, itab, &rset); + ndirty = check_dirty(L, 1, rtab, &rset); + t = ndirty > 0? 0.0: t; + timeout_init(&tm, t, -1); + timeout_markstart(&tm); + max_fd = collect_fd(L, 2, max_fd, itab, &wset); + ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm); + if (ret > 0 || ndirty > 0) { + return_fd(L, &rset, max_fd+1, itab, rtab, ndirty); + return_fd(L, &wset, max_fd+1, itab, wtab, 0); + make_assoc(L, rtab); + make_assoc(L, wtab); + return 2; + } else if (ret == 0) { + lua_pushstring(L, "timeout"); + return 3; + } else { + lua_pushstring(L, "error"); + return 3; + } +} + +/*=========================================================================*\ +* Internal functions +\*=========================================================================*/ +static t_socket getfd(lua_State *L) { + t_socket fd = SOCKET_INVALID; + lua_pushstring(L, "getfd"); + lua_gettable(L, -2); + if (!lua_isnil(L, -1)) { + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + if (lua_isnumber(L, -1)) + fd = (t_socket) lua_tonumber(L, -1); + } + lua_pop(L, 1); + return fd; +} + +static int dirty(lua_State *L) { + int is = 0; + lua_pushstring(L, "dirty"); + lua_gettable(L, -2); + if (!lua_isnil(L, -1)) { + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + is = lua_toboolean(L, -1); + } + lua_pop(L, 1); + return is; +} + +static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, + int itab, fd_set *set) { + int i = 1; + if (lua_isnil(L, tab)) + return max_fd; + while (1) { + t_socket fd; + lua_pushnumber(L, i); + lua_gettable(L, tab); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + break; + } + fd = getfd(L); + if (fd != SOCKET_INVALID) { + FD_SET(fd, set); + if (max_fd == SOCKET_INVALID || max_fd < fd) + max_fd = fd; + lua_pushnumber(L, fd); + lua_pushvalue(L, -2); + lua_settable(L, itab); + } + lua_pop(L, 1); + i = i + 1; + } + return max_fd; +} + +static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { + int ndirty = 0, i = 1; + if (lua_isnil(L, tab)) + return 0; + while (1) { + t_socket fd; + lua_pushnumber(L, i); + lua_gettable(L, tab); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + break; + } + fd = getfd(L); + if (fd != SOCKET_INVALID && dirty(L)) { + lua_pushnumber(L, ++ndirty); + lua_pushvalue(L, -2); + lua_settable(L, dtab); + FD_CLR(fd, set); + } + lua_pop(L, 1); + i = i + 1; + } + return ndirty; +} + +static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, + int itab, int tab, int start) { + t_socket fd; + for (fd = 0; fd < max_fd; fd++) { + if (FD_ISSET(fd, set)) { + lua_pushnumber(L, ++start); + lua_pushnumber(L, fd); + lua_gettable(L, itab); + lua_settable(L, tab); + } + } +} + +static void make_assoc(lua_State *L, int tab) { + int i = 1, atab; + lua_newtable(L); atab = lua_gettop(L); + while (1) { + lua_pushnumber(L, i); + lua_gettable(L, tab); + if (!lua_isnil(L, -1)) { + lua_pushnumber(L, i); + lua_pushvalue(L, -2); + lua_settable(L, atab); + lua_pushnumber(L, i); + lua_settable(L, atab); + } else { + lua_pop(L, 1); + break; + } + i = i+1; + } +} + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/select.h b/Build/source/texk/web2c/luatexdir/luasocket/src/select.h new file mode 100644 index 00000000000..aa3db4adf3b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/select.h @@ -0,0 +1,17 @@ +#ifndef SELECT_H +#define SELECT_H +/*=========================================================================*\ +* Select implementation +* LuaSocket toolkit +* +* Each object that can be passed to the select function has to export +* method getfd() which returns the descriptor to be passed to the +* underlying select function. Another method, dirty(), should return +* true if there is data ready for reading (required for buffered input). +* +* RCS ID: $Id: select.h,v 1.7 2004/06/16 01:02:07 diego Exp $ +\*=========================================================================*/ + +int select_open(lua_State *L); + +#endif /* SELECT_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/smtp.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/smtp.lua new file mode 100644 index 00000000000..8f3cfcff6e4 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/smtp.lua @@ -0,0 +1,251 @@ +----------------------------------------------------------------------------- +-- SMTP client support for the Lua language. +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: smtp.lua,v 1.46 2007/03/12 04:08:40 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local coroutine = require("coroutine") +local string = require("string") +local math = require("math") +local os = require("os") +local socket = require("socket") +local tp = require("socket.tp") +local ltn12 = require("ltn12") +local mime = require("mime") +module("socket.smtp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- timeout for connection +TIMEOUT = 60 +-- default server used to send e-mails +SERVER = "localhost" +-- default port +PORT = 25 +-- domain used in HELO command and default sendmail +-- If we are under a CGI, try to get from environment +DOMAIN = os.getenv("SERVER_NAME") or "localhost" +-- default time zone (means we don't know) +ZONE = "-0000" + +--------------------------------------------------------------------------- +-- Low level SMTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function metat.__index:greet(domain) + self.try(self.tp:check("2..")) + self.try(self.tp:command("EHLO", domain or DOMAIN)) + return socket.skip(1, self.try(self.tp:check("2.."))) +end + +function metat.__index:mail(from) + self.try(self.tp:command("MAIL", "FROM:" .. from)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:rcpt(to) + self.try(self.tp:command("RCPT", "TO:" .. to)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:data(src, step) + self.try(self.tp:command("DATA")) + self.try(self.tp:check("3..")) + self.try(self.tp:source(src, step)) + self.try(self.tp:send("\r\n.\r\n")) + return self.try(self.tp:check("2..")) +end + +function metat.__index:quit() + self.try(self.tp:command("QUIT")) + return self.try(self.tp:check("2..")) +end + +function metat.__index:close() + return self.tp:close() +end + +function metat.__index:login(user, password) + self.try(self.tp:command("AUTH", "LOGIN")) + self.try(self.tp:check("3..")) + self.try(self.tp:command(mime.b64(user))) + self.try(self.tp:check("3..")) + self.try(self.tp:command(mime.b64(password))) + return self.try(self.tp:check("2..")) +end + +function metat.__index:plain(user, password) + local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password) + self.try(self.tp:command("AUTH", auth)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:auth(user, password, ext) + if not user or not password then return 1 end + if string.find(ext, "AUTH[^\n]+LOGIN") then + return self:login(user, password) + elseif string.find(ext, "AUTH[^\n]+PLAIN") then + return self:plain(user, password) + else + self.try(nil, "authentication not supported") + end +end + +-- send message or throw an exception +function metat.__index:send(mailt) + self:mail(mailt.from) + if base.type(mailt.rcpt) == "table" then + for i,v in base.ipairs(mailt.rcpt) do + self:rcpt(v) + end + else + self:rcpt(mailt.rcpt) + end + self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) +end + +function open(server, port, create) + local tp = socket.try(tp.connect(server or SERVER, port or PORT, + TIMEOUT, create)) + local s = base.setmetatable({tp = tp}, metat) + -- make sure tp is closed if we get an exception + s.try = socket.newtry(function() + s:close() + end) + return s +end + +-- convert headers to lowercase +local function lower_headers(headers) + local lower = {} + for i,v in base.pairs(headers or lower) do + lower[string.lower(i)] = v + end + return lower +end + +--------------------------------------------------------------------------- +-- Multipart message source +----------------------------------------------------------------------------- +-- returns a hopefully unique mime boundary +local seqno = 0 +local function newboundary() + seqno = seqno + 1 + return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'), + math.random(0, 99999), seqno) +end + +-- send_message forward declaration +local send_message + +-- yield the headers all at once, it's faster +local function send_headers(headers) + local h = "\r\n" + for i,v in base.pairs(headers) do + h = i .. ': ' .. v .. "\r\n" .. h + end + coroutine.yield(h) +end + +-- yield multipart message body from a multipart message table +local function send_multipart(mesgt) + -- make sure we have our boundary and send headers + local bd = newboundary() + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or 'multipart/mixed' + headers['content-type'] = headers['content-type'] .. + '; boundary="' .. bd .. '"' + send_headers(headers) + -- send preamble + if mesgt.body.preamble then + coroutine.yield(mesgt.body.preamble) + coroutine.yield("\r\n") + end + -- send each part separated by a boundary + for i, m in base.ipairs(mesgt.body) do + coroutine.yield("\r\n--" .. bd .. "\r\n") + send_message(m) + end + -- send last boundary + coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n") + -- send epilogue + if mesgt.body.epilogue then + coroutine.yield(mesgt.body.epilogue) + coroutine.yield("\r\n") + end +end + +-- yield message body from a source +local function send_source(mesgt) + -- make sure we have a content-type + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or + 'text/plain; charset="iso-8859-1"' + send_headers(headers) + -- send body from source + while true do + local chunk, err = mesgt.body() + if err then coroutine.yield(nil, err) + elseif chunk then coroutine.yield(chunk) + else break end + end +end + +-- yield message body from a string +local function send_string(mesgt) + -- make sure we have a content-type + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or + 'text/plain; charset="iso-8859-1"' + send_headers(headers) + -- send body from string + coroutine.yield(mesgt.body) +end + +-- message source +function send_message(mesgt) + if base.type(mesgt.body) == "table" then send_multipart(mesgt) + elseif base.type(mesgt.body) == "function" then send_source(mesgt) + else send_string(mesgt) end +end + +-- set defaul headers +local function adjust_headers(mesgt) + local lower = lower_headers(mesgt.headers) + lower["date"] = lower["date"] or + os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE) + lower["x-mailer"] = lower["x-mailer"] or socket._VERSION + -- this can't be overriden + lower["mime-version"] = "1.0" + return lower +end + +function message(mesgt) + mesgt.headers = adjust_headers(mesgt) + -- create and return message source + local co = coroutine.create(function() send_message(mesgt) end) + return function() + local ret, a, b = coroutine.resume(co) + if ret then return a, b + else return nil, a end + end +end + +--------------------------------------------------------------------------- +-- High level SMTP API +----------------------------------------------------------------------------- +send = socket.protect(function(mailt) + local s = open(mailt.server, mailt.port, mailt.create) + local ext = s:greet(mailt.domain) + s:auth(mailt.user, mailt.password, ext) + s:send(mailt) + s:quit() + return s:close() +end) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/smtp_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/smtp_lua.c new file mode 100644 index 00000000000..8743ff557eb --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/smtp_lua.c @@ -0,0 +1,412 @@ +/* + * This file is auto-generated by "./lua2c smtp.lua smtp_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_smtp_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 83, 77, 84, 80, 32, 99,108,105,101,110,116, 32,115,117,112,112,111,114,116, + 32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103, +101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108, +107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103, +111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, + 73,100, 58, 32,115,109,116,112, 46,108,117, 97, 44,118, 32, 49, 46, 52, 54, 32, + 50, 48, 48, 55, 47, 48, 51, 47, 49, 50, 32, 48, 52, 58, 48, 56, 58, 52, 48, 32, +100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32, +109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101, +112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, + 61, 32, 95, 71, 10,108,111, 99, 97,108, 32, 99,111,114,111,117,116,105,110,101, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34, 99,111,114,111,117,116,105,110, +101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114, +101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, + 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109, + 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,111,115, 32, 61, 32,114,101,113, +117,105,114,101, 40, 34,111,115, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99, +107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101, +116, 34, 41, 10,108,111, 99, 97,108, 32,116,112, 32, 61, 32,114,101,113,117,105, +114,101, 40, 34,115,111, 99,107,101,116, 46,116,112, 34, 41, 10,108,111, 99, 97, +108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108, +116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109,105,109,101, 32, 61, 32, +114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, 41, 10,109,111,100,117, +108,101, 40, 34,115,111, 99,107,101,116, 46,115,109,116,112, 34, 41, 10, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, + 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,116, +105,109,101,111,117,116, 32,102,111,114, 32, 99,111,110,110,101, 99,116,105,111, +110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101, +102, 97,117,108,116, 32,115,101,114,118,101,114, 32,117,115,101,100, 32,116,111, + 32,115,101,110,100, 32,101, 45,109, 97,105,108,115, 10, 83, 69, 82, 86, 69, 82, + 32, 61, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100,101, +102, 97,117,108,116, 32,112,111,114,116, 10, 80, 79, 82, 84, 32, 61, 32, 50, 53, + 10, 45, 45, 32,100,111,109, 97,105,110, 32,117,115,101,100, 32,105,110, 32, 72, + 69, 76, 79, 32, 99,111,109,109, 97,110,100, 32, 97,110,100, 32,100,101,102, 97, +117,108,116, 32,115,101,110,100,109, 97,105,108, 10, 45, 45, 32, 73,102, 32,119, +101, 32, 97,114,101, 32,117,110,100,101,114, 32, 97, 32, 67, 71, 73, 44, 32,116, +114,121, 32,116,111, 32,103,101,116, 32,102,114,111,109, 32,101,110,118,105,114, +111,110,109,101,110,116, 10, 68, 79, 77, 65, 73, 78, 32, 61, 32,111,115, 46,103, +101,116,101,110,118, 40, 34, 83, 69, 82, 86, 69, 82, 95, 78, 65, 77, 69, 34, 41, + 32,111,114, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100, +101,102, 97,117,108,116, 32,116,105,109,101, 32,122,111,110,101, 32, 40,109,101, + 97,110,115, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 41, 10, 90, + 79, 78, 69, 32, 61, 32, 34, 45, 48, 48, 48, 48, 34, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101, +118,101,108, 32, 83, 77, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, + 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32, +125, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,103,114,101,101,116, 40,100,111,109, 97,105,110, 41, 10, + 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, + 97,110,100, 40, 34, 69, 72, 76, 79, 34, 44, 32,100,111,109, 97,105,110, 32,111, +114, 32, 68, 79, 77, 65, 73, 78, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, + 34, 50, 46, 46, 34, 41, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,109, 97,105, +108, 40,102,114,111,109, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 77, 65, + 73, 76, 34, 44, 32, 34, 70, 82, 79, 77, 58, 34, 32, 46, 46, 32,102,114,111,109, + 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, + 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114, 99,112,116, 40,116,111, + 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 82, 67, 80, 84, 34, 44, 32, 34, + 84, 79, 58, 34, 32, 46, 46, 32,116,111, 41, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58,100, 97,116, 97, 40,115,114, 99, 44, 32,115,116,101,112, 41, 10, 32, + 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,111,109,109, 97,110,100, 40, 34, 68, 65, 84, 65, 34, 41, 41, 10, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104, +101, 99,107, 40, 34, 51, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,111,117,114, 99,101, 40, +115,114, 99, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,101,110,100, 40, 34, 92, +114, 92,110, 46, 92,114, 92,110, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 81, + 85, 73, 84, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101, +108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, + 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111, +115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, + 46,116,112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10,102,117,110, + 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, +108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, + 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 34, + 76, 79, 71, 73, 78, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, 46, + 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98, 54, + 52, 40,117,115,101,114, 41, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, + 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98, + 54, 52, 40,112, 97,115,115,119,111,114,100, 41, 41, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,112,108, 97,105,110, 40,117,115,101,114, 44, 32,112, 97,115, +115,119,111,114,100, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,117,116, +104, 32, 61, 32, 34, 80, 76, 65, 73, 78, 32, 34, 32, 46, 46, 32,109,105,109,101, + 46, 98, 54, 52, 40, 34, 92, 48, 34, 32, 46, 46, 32,117,115,101,114, 32, 46, 46, + 32, 34, 92, 48, 34, 32, 46, 46, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, + 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 97,117,116,104, + 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, + 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 97,117,116,104, 40,117,115, +101,114, 44, 32,112, 97,115,115,119,111,114,100, 44, 32,101,120,116, 41, 10, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114, 32,111,114, 32,110,111, +116, 32,112, 97,115,115,119,111,114,100, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105, +110,103, 46,102,105,110,100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94, + 92,110, 93, 43, 76, 79, 71, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 58,108,111,103, +105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, + 32, 32, 32,101,108,115,101,105,102, 32,115,116,114,105,110,103, 46,102,105,110, +100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94, 92,110, 93, 43, 80, 76, + 65, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,101,108,102, 58,112,108, 97,105,110, 40,117,115,101, +114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,101,108,115, +101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,110, +105,108, 44, 32, 34, 97,117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32, +110,111,116, 32,115,117,112,112,111,114,116,101,100, 34, 41, 10, 32, 32, 32, 32, +101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,110,100, 32,109,101,115, +115, 97,103,101, 32,111,114, 32,116,104,114,111,119, 32, 97,110, 32,101,120, 99, +101,112,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97, +116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,109, 97,105,108,116, + 41, 10, 32, 32, 32, 32,115,101,108,102, 58,109, 97,105,108, 40,109, 97,105,108, +116, 46,102,114,111,109, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46, +116,121,112,101, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32, 61, 61, 32, + 34,116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,105,112, 97, +105,114,115, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32,100,111, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99,112,116, + 40,118, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99, +112,116, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,115,101,108,102, 58,100, 97,116, 97, 40,108,116,110, + 49, 50, 46,115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,109, 97,105,108, +116, 46,115,111,117,114, 99,101, 44, 32,109,105,109,101, 46,115,116,117,102,102, + 40, 41, 41, 44, 32,109, 97,105,108,116, 46,115,116,101,112, 41, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118, +101,114, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46, +116,114,121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101, +114, 32,111,114, 32, 83, 69, 82, 86, 69, 82, 44, 32,112,111,114,116, 32,111,114, + 32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 84, 73, 77, 69, 79, + 85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,115, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123,116,112, 32, 61, 32,116,112,125, 44, 32,109,101,116, 97, +116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32, +116,112, 32,105,115, 32, 99,108,111,115,101,100, 32,105,102, 32,119,101, 32,103, +101,116, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, 10, 32, 32, 32, 32, +115, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114, +121, 40,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,115, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,115, 10,101,110,100, 10, 10, 45, 45, + 32, 99,111,110,118,101,114,116, 32,104,101, 97,100,101,114,115, 32,116,111, 32, +108,111,119,101,114, 99, 97,115,101, 10,108,111, 99, 97,108, 32,102,117,110, 99, +116,105,111,110, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,104, +101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111, +119,101,114, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, + 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101, +114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, 32, 32, 32, 32, + 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, 46,108,111,119, +101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10,101,110,100, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, + 77,117,108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,115,111, +117,114, 99,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,111,112,101, +102,117,108,108,121, 32,117,110,105,113,117,101, 32,109,105,109,101, 32, 98,111, +117,110,100, 97,114,121, 10,108,111, 99, 97,108, 32,115,101,113,110,111, 32, 61, + 32, 48, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,101, +119, 98,111,117,110,100, 97,114,121, 40, 41, 10, 32, 32, 32, 32,115,101,113,110, +111, 32, 61, 32,115,101,113,110,111, 32, 43, 32, 49, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 39, + 37,115, 37, 48, 53,100, 61, 61, 37, 48, 53,117, 39, 44, 32,111,115, 46,100, 97, +116,101, 40, 39, 37,100, 37,109, 37, 89, 37, 72, 37, 77, 37, 83, 39, 41, 44, 10, + 32, 32, 32, 32, 32, 32, 32, 32,109, 97,116,104, 46,114, 97,110,100,111,109, 40, + 48, 44, 32, 57, 57, 57, 57, 57, 41, 44, 32,115,101,113,110,111, 41, 10,101,110, +100, 10, 10, 45, 45, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 32,102, +111,114,119, 97,114,100, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 10,108, +111, 99, 97,108, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 10, 10, 45, + 45, 32,121,105,101,108,100, 32,116,104,101, 32,104,101, 97,100,101,114,115, 32, + 97,108,108, 32, 97,116, 32,111,110, 99,101, 44, 32,105,116, 39,115, 32,102, 97, +115,116,101,114, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, +115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114,115, + 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, 92,114, 92, +110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97, +115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115, 41, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46, 46, 32, 39, 58, + 32, 39, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 32, 46, 46, + 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,114,111,117, +116,105,110,101, 46,121,105,101,108,100, 40,104, 41, 10,101,110,100, 10, 10, 45, + 45, 32,121,105,101,108,100, 32,109,117,108,116,105,112, 97,114,116, 32,109,101, +115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97, 32,109,117, +108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,116, 97, 98,108, +101, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110, +100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103,116, 41, 10, 32, + 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104, + 97,118,101, 32,111,117,114, 32, 98,111,117,110,100, 97,114,121, 32, 97,110,100, + 32,115,101,110,100, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 98,100, 32, 61, 32,110,101,119, 98,111,117,110,100, 97,114,121, + 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, + 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115, +103,116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32, + 32, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116, +121,112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110, +116,101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 32, 39,109,117,108,116, +105,112, 97,114,116, 47,109,105,120,101,100, 39, 10, 32, 32, 32, 32,104,101, 97, +100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, + 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45, +116,121,112,101, 39, 93, 32, 46, 46, 10, 32, 32, 32, 32, 32, 32, 32, 32, 39, 59, + 32, 98,111,117,110,100, 97,114,121, 61, 34, 39, 32, 46, 46, 32, 32, 98,100, 32, + 46, 46, 32, 39, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97,100, +101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, 32, +115,101,110,100, 32,112,114,101, 97,109, 98,108,101, 10, 32, 32, 32, 32,105,102, + 32,109,101,115,103,116, 46, 98,111,100,121, 46,112,114,101, 97,109, 98,108,101, + 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116, +105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111,100,121, + 46,112,114,101, 97,109, 98,108,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, +111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, + 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,115,101, +110,100, 32,101, 97, 99,104, 32,112, 97,114,116, 32,115,101,112, 97,114, 97,116, +101,100, 32, 98,121, 32, 97, 32, 98,111,117,110,100, 97,114,121, 10, 32, 32, 32, + 32,102,111,114, 32,105, 44, 32,109, 32,105,110, 32, 98, 97,115,101, 46,105,112, + 97,105,114,115, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32,100,111, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105, +101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, 98,100, 32, 46, + 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101, +110,100, 95,109,101,115,115, 97,103,101, 40,109, 41, 10, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,108, 97,115,116, 32, 98, +111,117,110,100, 97,114,121, 10, 32, 32, 32, 32, 99,111,114,111,117,116,105,110, +101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, + 98,100, 32, 46, 46, 32, 34, 45, 45, 92,114, 92,110, 92,114, 92,110, 34, 41, 10, + 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,101,112,105,108,111,103,117,101, + 10, 32, 32, 32, 32,105,102, 32,109,101,115,103,116, 46, 98,111,100,121, 46,101, +112,105,108,111,103,117,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115, +103,116, 46, 98,111,100,121, 46,101,112,105,108,111,103,117,101, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108, +100, 40, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10,101,110, +100, 10, 10, 45, 45, 32,121,105,101,108,100, 32,109,101,115,115, 97,103,101, 32, + 98,111,100,121, 32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 10,108, +111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110,100, 95,115, +111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, +109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104, 97,118,101, 32, 97, 32, + 99,111,110,116,101,110,116, 45,116,121,112,101, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,104,101, 97,100,101,114,115, 32, 61, 32,108,111,119,101,114, 95,104, +101, 97,100,101,114,115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114,115, + 32,111,114, 32,123,125, 41, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 91, + 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, 32, 61, 32,104,101, + 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, + 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 39,116,101,120,116, 47,112, +108, 97,105,110, 59, 32, 99,104, 97,114,115,101,116, 61, 34,105,115,111, 45, 56, + 56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97, +100,101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, + 32,115,101,110,100, 32, 98,111,100,121, 32,102,114,111,109, 32,115,111,117,114, + 99,101, 10, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, + 44, 32,101,114,114, 32, 61, 32,109,101,115,103,116, 46, 98,111,100,121, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, + 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,110,105,108, + 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105, +102, 32, 99,104,117,110,107, 32,116,104,101,110, 32, 99,111,114,111,117,116,105, +110,101, 46,121,105,101,108,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 32, 98,114,101, 97,107, 32,101,110,100, 10, 32, + 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,121,105,101,108,100, + 32,109,101,115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97, + 32,115,116,114,105,110,103, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105, +111,110, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116, + 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119, +101, 32,104, 97,118,101, 32, 97, 32, 99,111,110,116,101,110,116, 45,116,121,112, +101, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 32, + 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115,103, +116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32, 32, + 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121, +112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116, +101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 39,116,101,120,116, 47,112,108, 97,105,110, 59, 32, 99,104, 97,114,115, +101,116, 61, 34,105,115,111, 45, 56, 56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32, + 32,115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114, +115, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32, 98,111,100,121, 32, +102,114,111,109, 32,115,116,114,105,110,103, 10, 32, 32, 32, 32, 99,111,114,111, +117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111, +100,121, 41, 10,101,110,100, 10, 10, 45, 45, 32,109,101,115,115, 97,103,101, 32, +115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,101,110,100, + 95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, +105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,109,101,115,103,116, 46, 98, +111,100,121, 41, 32, 61, 61, 32, 34,116, 97, 98,108,101, 34, 32,116,104,101,110, + 32,115,101,110,100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103, +116, 41, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32, 98, 97,115,101, 46,116, +121,112,101, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32, 61, 61, 32, 34, +102,117,110, 99,116,105,111,110, 34, 32,116,104,101,110, 32,115,101,110,100, 95, +115,111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,101,108, +115,101, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116, + 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,116, 32,100,101, +102, 97,117,108, 32,104,101, 97,100,101,114,115, 10,108,111, 99, 97,108, 32,102, +117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116, 95,104,101, 97,100,101, +114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, +108,111,119,101,114, 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114, +115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, + 32,108,111,119,101,114, 91, 34,100, 97,116,101, 34, 93, 32, 61, 32,108,111,119, +101,114, 91, 34,100, 97,116,101, 34, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, + 32, 32,111,115, 46,100, 97,116,101, 40, 34, 33, 37, 97, 44, 32, 37,100, 32, 37, + 98, 32, 37, 89, 32, 37, 72, 58, 37, 77, 58, 37, 83, 32, 34, 41, 32, 46, 46, 32, + 40,109,101,115,103,116, 46,122,111,110,101, 32,111,114, 32, 90, 79, 78, 69, 41, + 10, 32, 32, 32, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, + 34, 93, 32, 61, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, + 34, 93, 32,111,114, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, + 78, 10, 32, 32, 32, 32, 45, 45, 32,116,104,105,115, 32, 99, 97,110, 39,116, 32, + 98,101, 32,111,118,101,114,114,105,100,101,110, 10, 32, 32, 32, 32,108,111,119, +101,114, 91, 34,109,105,109,101, 45,118,101,114,115,105,111,110, 34, 93, 32, 61, + 32, 34, 49, 46, 48, 34, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111, +119,101,114, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,109,101,115, +103,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116, 95, +104,101, 97,100,101,114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, + 45, 32, 99,114,101, 97,116,101, 32, 97,110,100, 32,114,101,116,117,114,110, 32, +109,101,115,115, 97,103,101, 32,115,111,117,114, 99,101, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32, 99,111, 32, 61, 32, 99,111,114,111,117,116,105,110,101, 46, + 99,114,101, 97,116,101, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,115,101, +110,100, 95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 32,101,110, +100, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, +111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114, +101,116, 44, 32, 97, 44, 32, 98, 32, 61, 32, 99,111,114,111,117,116,105,110,101, + 46,114,101,115,117,109,101, 40, 99,111, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32,114,101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 97, + 44, 32, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32, 97, 32,101,110,100, 10, 32, 32, 32, 32,101, +110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118,101,108, 32, 83, 77, + 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10,115,101,110,100, 32, 61, 32,115,111, 99,107,101,116, 46,112, +114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,109, 97,105,108, +116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, 32, 61, 32,111,112,101, +110, 40,109, 97,105,108,116, 46,115,101,114,118,101,114, 44, 32,109, 97,105,108, +116, 46,112,111,114,116, 44, 32,109, 97,105,108,116, 46, 99,114,101, 97,116,101, + 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,101,120,116, 32, 61, 32,115, 58, +103,114,101,101,116, 40,109, 97,105,108,116, 46,100,111,109, 97,105,110, 41, 10, + 32, 32, 32, 32,115, 58, 97,117,116,104, 40,109, 97,105,108,116, 46,117,115,101, +114, 44, 32,109, 97,105,108,116, 46,112, 97,115,115,119,111,114,100, 44, 32,101, +120,116, 41, 10, 32, 32, 32, 32,115, 58,115,101,110,100, 40,109, 97,105,108,116, + 41, 10, 32, 32, 32, 32,115, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 41, + 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/socket.c b/Build/source/texk/web2c/luatexdir/luasocket/src/socket.c new file mode 100644 index 00000000000..84165c70e5e --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/socket.c @@ -0,0 +1,5 @@ +#ifdef _WIN32 +#include "wsocket.c" +#else +#include "usocket.c" +#endif diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/socket.h b/Build/source/texk/web2c/luatexdir/luasocket/src/socket.h new file mode 100644 index 00000000000..656c7f5d5ce --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/socket.h @@ -0,0 +1,76 @@ +#ifndef SOCKET_H +#define SOCKET_H +/*=========================================================================*\ +* Socket compatibilization module +* LuaSocket toolkit +* +* BSD Sockets and WinSock are similar, but there are a few irritating +* differences. Also, not all *nix platforms behave the same. This module +* (and the associated usocket.h and wsocket.h) factor these differences and +* creates a interface compatible with the io.h module. +* +* RCS ID: $Id: socket.h,v 1.20 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include "io.h" + +/*=========================================================================*\ +* Platform specific compatibilization +\*=========================================================================*/ +#ifdef _WIN32 +#include "wsocket.h" +#else +#include "usocket.h" +#endif + +/*=========================================================================*\ +* The connect and accept functions accept a timeout and their +* implementations are somewhat complicated. We chose to move +* the timeout control into this module for these functions in +* order to simplify the modules that use them. +\*=========================================================================*/ +#include "timeout.h" + +/* we are lazy... */ +typedef struct sockaddr SA; + +/*=========================================================================*\ +* Functions bellow implement a comfortable platform independent +* interface to sockets +\*=========================================================================*/ +int socket_open(void); +int socket_close(void); +void socket_destroy(p_socket ps); +void socket_shutdown(p_socket ps, int how); +int socket_sendto(p_socket ps, const char *data, size_t count, + size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm); +int socket_recvfrom(p_socket ps, char *data, size_t count, + size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm); + +void socket_setnonblocking(p_socket ps); +void socket_setblocking(p_socket ps); + +int socket_waitfd(p_socket ps, int sw, p_timeout tm); +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, + p_timeout tm); + +int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm); +int socket_create(p_socket ps, int domain, int type, int protocol); +int socket_bind(p_socket ps, SA *addr, socklen_t addr_len); +int socket_listen(p_socket ps, int backlog); +int socket_accept(p_socket ps, p_socket pa, SA *addr, + socklen_t *addr_len, p_timeout tm); + +const char *socket_hoststrerror(int err); +const char *socket_strerror(int err); + +/* these are perfect to use with the io abstraction module + and the buffered input module */ +int socket_send(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm); +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm); +const char *socket_ioerror(p_socket ps, int err); + +int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp); +int socket_gethostbyname(const char *addr, struct hostent **hp); + +#endif /* SOCKET_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/socket.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/socket.lua new file mode 100644 index 00000000000..211adcd1d98 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/socket.lua @@ -0,0 +1,133 @@ +----------------------------------------------------------------------------- +-- LuaSocket helper module +-- Author: Diego Nehab +-- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local math = require("math") +local socket = require("socket.core") +module("socket") + +----------------------------------------------------------------------------- +-- Exported auxiliar functions +----------------------------------------------------------------------------- +function connect(address, port, laddress, lport) + local sock, err = socket.tcp() + if not sock then return nil, err end + if laddress then + local res, err = sock:bind(laddress, lport, -1) + if not res then return nil, err end + end + local res, err = sock:connect(address, port) + if not res then return nil, err end + return sock +end + +function bind(host, port, backlog) + local sock, err = socket.tcp() + if not sock then return nil, err end + sock:setoption("reuseaddr", true) + local res, err = sock:bind(host, port) + if not res then return nil, err end + res, err = sock:listen(backlog) + if not res then return nil, err end + return sock +end + +try = newtry() + +function choose(table) + return function(name, opt1, opt2) + if base.type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = table[name or "nil"] + if not f then base.error("unknown key (".. base.tostring(name) ..")", 3) + else return f(opt1, opt2) end + end +end + +----------------------------------------------------------------------------- +-- Socket sources and sinks, conforming to LTN12 +----------------------------------------------------------------------------- +-- create namespaces inside LuaSocket namespace +sourcet = {} +sinkt = {} + +BLOCKSIZE = 2048 + +sinkt["close-when-done"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if not chunk then + sock:close() + return 1 + else return sock:send(chunk) end + end + }) +end + +sinkt["keep-open"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if chunk then return sock:send(chunk) + else return 1 end + end + }) +end + +sinkt["default"] = sinkt["keep-open"] + +sink = choose(sinkt) + +sourcet["by-length"] = function(sock, length) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if length <= 0 then return nil end + local size = math.min(socket.BLOCKSIZE, length) + local chunk, err = sock:receive(size) + if err then return nil, err end + length = length - string.len(chunk) + return chunk + end + }) +end + +sourcet["until-closed"] = function(sock) + local done + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if done then return nil end + local chunk, err, partial = sock:receive(socket.BLOCKSIZE) + if not err then return chunk + elseif err == "closed" then + sock:close() + done = 1 + return partial + else return nil, err end + end + }) +end + + +sourcet["default"] = sourcet["until-closed"] + +source = choose(sourcet) + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/socket_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/socket_lua.c new file mode 100644 index 00000000000..4f3709e0d0e --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/socket_lua.c @@ -0,0 +1,217 @@ +/* + * This file is auto-generated by "./lua2c socket.lua socket_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_socket_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 76,117, 97, 83,111, 99,107,101,116, 32,104,101,108,112,101,114, 32,109,111, +100,117,108,101, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103, +111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, + 73,100, 58, 32,115,111, 99,107,101,116, 46,108,117, 97, 44,118, 32, 49, 46, 50, + 50, 32, 50, 48, 48, 53, 47, 49, 49, 47, 50, 50, 32, 48, 56, 58, 51, 51, 58, 50, + 57, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114, +101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32, +100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115, +101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10, +108,111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101, +116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46, + 99,111,114,101, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101, +116, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32, 69,120,112,111,114,116,101,100, 32, 97,117,120,105,108, +105, 97,114, 32,102,117,110, 99,116,105,111,110,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, + 32, 99,111,110,110,101, 99,116, 40, 97,100,100,114,101,115,115, 44, 32,112,111, +114,116, 44, 32,108, 97,100,100,114,101,115,115, 44, 32,108,112,111,114,116, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,111, 99,107, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107,101,116, 46,116, 99,112, 40, 41, 10, 32, 32, 32, 32, +105,102, 32,110,111,116, 32,115,111, 99,107, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, + 32,105,102, 32,108, 97,100,100,114,101,115,115, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,108, 97,100,100,114,101,115, +115, 44, 32,108,112,111,114,116, 44, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101, +116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, + 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, + 32,101,114,114, 32, 61, 32,115,111, 99,107, 58, 99,111,110,110,101, 99,116, 40, + 97,100,100,114,101,115,115, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105, +102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,111, 99,107, 10,101,110,100, 10, 10,102,117,110, 99, +116,105,111,110, 32, 98,105,110,100, 40,104,111,115,116, 44, 32,112,111,114,116, + 44, 32, 98, 97, 99,107,108,111,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,115,111, 99,107, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107,101,116, 46, +116, 99,112, 40, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,111, 99, +107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, +114,114, 32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107, 58,115,101,116,111, +112,116,105,111,110, 40, 34,114,101,117,115,101, 97,100,100,114, 34, 44, 32,116, +114,117,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32, +101,114,114, 32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,104,111,115,116, + 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, +101,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114,101,115, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58,108,105,115,116,101,110, 40, 98, 97, 99,107,108, +111,103, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32, +101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 10, +101,110,100, 10, 10,116,114,121, 32, 61, 32,110,101,119,116,114,121, 40, 41, 10, + 10,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115,101, 40,116, 97, 98, +108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116, +105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121, +112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116,114,105,110,103, 34, + 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97, +109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, 61, 32, 34,100,101, +102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111,112,116, 49, 10, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,108, +111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91,110, 97,109,101, 32, +111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, + 32,110,111,116, 32,102, 32,116,104,101,110, 32, 98, 97,115,101, 46,101,114,114, +111,114, 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 46, 46, + 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, + 32, 46, 46, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111, +112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32, 83,111, 99,107,101,116, 32,115,111,117,114, 99,101,115, 32, 97,110, +100, 32,115,105,110,107,115, 44, 32, 99,111,110,102,111,114,109,105,110,103, 32, +116,111, 32, 76, 84, 78, 49, 50, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32,110, 97,109, +101,115,112, 97, 99,101,115, 32,105,110,115,105,100,101, 32, 76,117, 97, 83,111, + 99,107,101,116, 32,110, 97,109,101,115,112, 97, 99,101, 10,115,111,117,114, 99, +101,116, 32, 61, 32,123,125, 10,115,105,110,107,116, 32, 61, 32,123,125, 10, 10, + 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, 61, 32, 50, 48, 52, 56, 10, 10,115,105, +110,107,116, 91, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, + 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109, +101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103, +101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101, +116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110, +100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102, +117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99, +107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, + 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32, +102,117,110, 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, + 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, +102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 58, 99,108, +111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58, +115,101,110,100, 40, 99,104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, +115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112,101,110, 34, 93, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, + 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116, +105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105, +114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99, +116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101,114, +114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104, +117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,111, 99,107, + 58,115,101,110,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101, +110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, + 41, 10,101,110,100, 10, 10,115,105,110,107,116, 91, 34,100,101,102, 97,117,108, +116, 34, 93, 32, 61, 32,115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112, +101,110, 34, 93, 10, 10,115,105,110,107, 32, 61, 32, 99,104,111,111,115,101, 40, +115,105,110,107,116, 41, 10, 10,115,111,117,114, 99,101,116, 91, 34, 98,121, 45, +108,101,110,103,116,104, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, +115,111, 99,107, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, 97, 98, +108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115, +111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, 32, 32, + 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116,105,111, +110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105,114,116, +121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99,116,105, +111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +108,101,110,103,116,104, 32, 60, 61, 32, 48, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,109, 97,116, +104, 46,109,105,110, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, + 90, 69, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40,115,105,122,101, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, +114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,101, +110,103,116,104, 32, 61, 32,108,101,110,103,116,104, 32, 45, 32,115,116,114,105, +110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110, +100, 10, 10,115,111,117,114, 99,101,116, 91, 34,117,110,116,105,108, 45, 99,108, +111,115,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, + 99,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101, +116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101, +116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116, +117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, + 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, + 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32, +123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102, +117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, 44, 32, +112, 97,114,116,105, 97,108, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105, +118,101, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, +101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110, +107, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, + 32,101,114,114, 32, 61, 61, 32, 34, 99,108,111,115,101,100, 34, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, + 99,107, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,100,111,110,101, 32, 61, 32, 49, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, + 97,114,116,105, 97,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +125, 41, 10,101,110,100, 10, 10, 10,115,111,117,114, 99,101,116, 91, 34,100,101, +102, 97,117,108,116, 34, 93, 32, 61, 32,115,111,117,114, 99,101,116, 91, 34,117, +110,116,105,108, 45, 99,108,111,115,101,100, 34, 93, 10, 10,115,111,117,114, 99, +101, 32, 61, 32, 99,104,111,111,115,101, 40,115,111,117,114, 99,101,116, 41, 10, + 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c b/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c new file mode 100644 index 00000000000..6b8a79b4bc5 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c @@ -0,0 +1,339 @@ +/*=========================================================================*\ +* TCP object +* LuaSocket toolkit +* +* RCS ID: $Id: tcp.c,v 1.41 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "socket.h" +#include "inet.h" +#include "options.h" +#include "tcp.h" + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_connect(lua_State *L); +static int meth_listen(lua_State *L); +static int meth_bind(lua_State *L); +static int meth_send(lua_State *L); +static int meth_getstats(lua_State *L); +static int meth_setstats(lua_State *L); +static int meth_getsockname(lua_State *L); +static int meth_getpeername(lua_State *L); +static int meth_shutdown(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_accept(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); + +/* tcp object methods */ +static luaL_reg tcp[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"accept", meth_accept}, + {"bind", meth_bind}, + {"close", meth_close}, + {"connect", meth_connect}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getpeername", meth_getpeername}, + {"getsockname", meth_getsockname}, + {"getstats", meth_getstats}, + {"setstats", meth_setstats}, + {"listen", meth_listen}, + {"receive", meth_receive}, + {"send", meth_send}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_connect}, + {"setsockname", meth_bind}, + {"settimeout", meth_settimeout}, + {"shutdown", meth_shutdown}, + {NULL, NULL} +}; + +/* socket option handlers */ +static t_opt opt[] = { + {"keepalive", opt_keepalive}, + {"reuseaddr", opt_reuseaddr}, + {"tcp-nodelay", opt_tcp_nodelay}, + {"linger", opt_linger}, + {NULL, NULL} +}; + +/* functions in library namespace */ +static luaL_reg func[] = { + {"tcp", global_create}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int tcp_open(lua_State *L) +{ + /* create classes */ + auxiliar_newclass(L, "tcp{master}", tcp); + auxiliar_newclass(L, "tcp{client}", tcp); + auxiliar_newclass(L, "tcp{server}", tcp); + /* create class groups */ + auxiliar_add2group(L, "tcp{master}", "tcp{any}"); + auxiliar_add2group(L, "tcp{client}", "tcp{any}"); + auxiliar_add2group(L, "tcp{server}", "tcp{any}"); + /* define library functions */ + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Just call buffered IO methods +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_send(L, &tcp->buf); +} + +static int meth_receive(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_receive(L, &tcp->buf); +} + +static int meth_getstats(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_getstats(L, &tcp->buf); +} + +static int meth_setstats(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_setstats(L, &tcp->buf); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return opt_meth_setoption(L, opt, &tcp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + lua_pushnumber(L, (int) tcp->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + tcp->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + lua_pushboolean(L, !buffer_isempty(&tcp->buf)); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Waits for and returns a client object attempting connection to the +* server object +\*-------------------------------------------------------------------------*/ +static int meth_accept(lua_State *L) +{ + p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1); + p_timeout tm = timeout_markstart(&server->tm); + t_socket sock; + int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); + /* if successful, push client socket */ + if (err == IO_DONE) { + p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); + auxiliar_setclass(L, "tcp{client}", -1); + /* initialize structure fields */ + socket_setnonblocking(&sock); + clnt->sock = sock; + io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &clnt->sock); + timeout_init(&clnt->tm, -1, -1); + buffer_init(&clnt->buf, &clnt->io, &clnt->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ +* Binds an object to an address +\*-------------------------------------------------------------------------*/ +static int meth_bind(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); + const char *address = luaL_checkstring(L, 2); + unsigned short port = (unsigned short) luaL_checknumber(L, 3); + const char *err = inet_trybind(&tcp->sock, address, port); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master tcp object into a client object. +\*-------------------------------------------------------------------------*/ +static int meth_connect(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + const char *address = luaL_checkstring(L, 2); + unsigned short port = (unsigned short) luaL_checknumber(L, 3); + p_timeout tm = timeout_markstart(&tcp->tm); + const char *err = inet_tryconnect(&tcp->sock, address, port, tm); + /* have to set the class even if it failed due to non-blocking connects */ + auxiliar_setclass(L, "tcp{client}", 1); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* turn master object into a client object */ + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + socket_destroy(&tcp->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Puts the sockt in listen mode +\*-------------------------------------------------------------------------*/ +static int meth_listen(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); + int backlog = (int) luaL_optnumber(L, 2, 32); + int err = socket_listen(&tcp->sock, backlog); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } + /* turn master object into a server object */ + auxiliar_setclass(L, "tcp{server}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Shuts the connection down partially +\*-------------------------------------------------------------------------*/ +static int meth_shutdown(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + const char *how = luaL_optstring(L, 2, "both"); + switch (how[0]) { + case 'b': + if (strcmp(how, "both")) goto error; + socket_shutdown(&tcp->sock, 2); + break; + case 's': + if (strcmp(how, "send")) goto error; + socket_shutdown(&tcp->sock, 1); + break; + case 'r': + if (strcmp(how, "receive")) goto error; + socket_shutdown(&tcp->sock, 0); + break; + } + lua_pushnumber(L, 1); + return 1; +error: + luaL_argerror(L, 2, "invalid shutdown method"); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Just call inet methods +\*-------------------------------------------------------------------------*/ +static int meth_getpeername(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return inet_meth_getpeername(L, &tcp->sock); +} + +static int meth_getsockname(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return inet_meth_getsockname(L, &tcp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return timeout_meth_settimeout(L, &tcp->tm); +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master tcp object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) +{ + t_socket sock; + const char *err = inet_trycreate(&sock, SOCK_STREAM); + /* try to allocate a system socket */ + if (!err) { + /* allocate tcp object */ + p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); + /* set its type as master object */ + auxiliar_setclass(L, "tcp{master}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + tcp->sock = sock; + io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &tcp->sock); + timeout_init(&tcp->tm, -1, -1); + buffer_init(&tcp->buf, &tcp->io, &tcp->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.h b/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.h new file mode 100644 index 00000000000..511357f371a --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.h @@ -0,0 +1,36 @@ +#ifndef TCP_H +#define TCP_H +/*=========================================================================*\ +* TCP object +* LuaSocket toolkit +* +* The tcp.h module is basicly a glue that puts together modules buffer.h, +* timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET, +* SOCK_STREAM) support. +* +* Three classes are defined: master, client and server. The master class is +* a newly created tcp object, that has not been bound or connected. Server +* objects are tcp objects bound to some local address. Client objects are +* tcp objects either connected to some address or returned by the accept +* method of a server object. +* +* RCS ID: $Id: tcp.h,v 1.7 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "buffer.h" +#include "timeout.h" +#include "socket.h" + +typedef struct t_tcp_ { + t_socket sock; + t_io io; + t_buffer buf; + t_timeout tm; +} t_tcp; + +typedef t_tcp *p_tcp; + +int tcp_open(lua_State *L); + +#endif /* TCP_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/timeout.c b/Build/source/texk/web2c/luatexdir/luasocket/src/timeout.c new file mode 100644 index 00000000000..c1df1021811 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/timeout.c @@ -0,0 +1,207 @@ +/*=========================================================================*\ +* Timeout management functions +* LuaSocket toolkit +* +* RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "timeout.h" + +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +/* min and max macros */ +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? x : y) +#endif +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? x : y) +#endif + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int timeout_lua_gettime(lua_State *L); +static int timeout_lua_sleep(lua_State *L); + +static luaL_reg func[] = { + { "gettime", timeout_lua_gettime }, + { "sleep", timeout_lua_sleep }, + { NULL, NULL } +}; + +/*=========================================================================*\ +* Exported functions. +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initialize structure +\*-------------------------------------------------------------------------*/ +void timeout_init(p_timeout tm, double block, double total) { + tm->block = block; + tm->total = total; +} + +/*-------------------------------------------------------------------------*\ +* Determines how much time we have left for the next system call, +* if the previous call was successful +* Input +* tm: timeout control structure +* Returns +* the number of ms left or -1 if there is no time limit +\*-------------------------------------------------------------------------*/ +double timeout_get(p_timeout tm) { + if (tm->block < 0.0 && tm->total < 0.0) { + return -1; + } else if (tm->block < 0.0) { + double t = tm->total - timeout_gettime() + tm->start; + return MAX(t, 0.0); + } else if (tm->total < 0.0) { + return tm->block; + } else { + double t = tm->total - timeout_gettime() + tm->start; + return MIN(tm->block, MAX(t, 0.0)); + } +} + +/*-------------------------------------------------------------------------*\ +* Returns time since start of operation +* Input +* tm: timeout control structure +* Returns +* start field of structure +\*-------------------------------------------------------------------------*/ +double timeout_getstart(p_timeout tm) { + return tm->start; +} + +/*-------------------------------------------------------------------------*\ +* Determines how much time we have left for the next system call, +* if the previous call was a failure +* Input +* tm: timeout control structure +* Returns +* the number of ms left or -1 if there is no time limit +\*-------------------------------------------------------------------------*/ +double timeout_getretry(p_timeout tm) { + if (tm->block < 0.0 && tm->total < 0.0) { + return -1; + } else if (tm->block < 0.0) { + double t = tm->total - timeout_gettime() + tm->start; + return MAX(t, 0.0); + } else if (tm->total < 0.0) { + double t = tm->block - timeout_gettime() + tm->start; + return MAX(t, 0.0); + } else { + double t = tm->total - timeout_gettime() + tm->start; + return MIN(tm->block, MAX(t, 0.0)); + } +} + +/*-------------------------------------------------------------------------*\ +* Marks the operation start time in structure +* Input +* tm: timeout control structure +\*-------------------------------------------------------------------------*/ +p_timeout timeout_markstart(p_timeout tm) { + tm->start = timeout_gettime(); + return tm; +} + +/*-------------------------------------------------------------------------*\ +* Gets time in s, relative to January 1, 1970 (UTC) +* Returns +* time in s. +\*-------------------------------------------------------------------------*/ +#ifdef _WIN32 +double timeout_gettime(void) { + FILETIME ft; + double t; + GetSystemTimeAsFileTime(&ft); + /* Windows file time (time since January 1, 1601 (UTC)) */ + t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7); + /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */ + return (t - 11644473600.0); +} +#else +double timeout_gettime(void) { + struct timeval v; + gettimeofday(&v, (struct timezone *) NULL); + /* Unix Epoch time (time since January 1, 1970 (UTC)) */ + return v.tv_sec + v.tv_usec/1.0e6; +} +#endif + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int timeout_open(lua_State *L) { + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Sets timeout values for IO operations +* Lua Input: base, time [, mode] +* time: time out value in seconds +* mode: "b" for block timeout, "t" for total timeout. (default: b) +\*-------------------------------------------------------------------------*/ +int timeout_meth_settimeout(lua_State *L, p_timeout tm) { + double t = luaL_optnumber(L, 2, -1); + const char *mode = luaL_optstring(L, 3, "b"); + switch (*mode) { + case 'b': + tm->block = t; + break; + case 'r': case 't': + tm->total = t; + break; + default: + luaL_argcheck(L, 0, 3, "invalid timeout mode"); + break; + } + lua_pushnumber(L, 1); + return 1; +} + +/*=========================================================================*\ +* Test support functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Returns the time the system has been up, in secconds. +\*-------------------------------------------------------------------------*/ +static int timeout_lua_gettime(lua_State *L) +{ + lua_pushnumber(L, timeout_gettime()); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Sleep for n seconds. +\*-------------------------------------------------------------------------*/ +int timeout_lua_sleep(lua_State *L) +{ + double n = luaL_checknumber(L, 1); +#ifdef _WIN32 + Sleep((int)(n*1000)); +#else + struct timespec t, r; + t.tv_sec = (int) n; + n -= t.tv_sec; + t.tv_nsec = (int) (n * 1000000000); + if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999; + while (nanosleep(&t, &r) != 0) { + t.tv_sec = r.tv_sec; + t.tv_nsec = r.tv_nsec; + } +#endif + return 0; +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/timeout.h b/Build/source/texk/web2c/luatexdir/luasocket/src/timeout.h new file mode 100644 index 00000000000..d2d8964100f --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/timeout.h @@ -0,0 +1,30 @@ +#ifndef TIMEOUT_H +#define TIMEOUT_H +/*=========================================================================*\ +* Timeout management functions +* LuaSocket toolkit +* +* RCS ID: $Id: timeout.h,v 1.14 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +/* timeout control structure */ +typedef struct t_timeout_ { + double block; /* maximum time for blocking calls */ + double total; /* total number of miliseconds for operation */ + double start; /* time of start of operation */ +} t_timeout; +typedef t_timeout *p_timeout; + +int timeout_open(lua_State *L); +void timeout_init(p_timeout tm, double block, double total); +double timeout_get(p_timeout tm); +double timeout_getretry(p_timeout tm); +p_timeout timeout_markstart(p_timeout tm); +double timeout_getstart(p_timeout tm); +double timeout_gettime(void); +int timeout_meth_settimeout(lua_State *L, p_timeout tm); + +#define timeout_iszero(tm) ((tm)->block == 0.0) + +#endif /* TIMEOUT_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/tp.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/tp.lua new file mode 100644 index 00000000000..0683869499f --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/tp.lua @@ -0,0 +1,123 @@ +----------------------------------------------------------------------------- +-- Unified SMTP/FTP subsystem +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: tp.lua,v 1.22 2006/03/14 09:04:15 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local socket = require("socket") +local ltn12 = require("ltn12") +module("socket.tp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +TIMEOUT = 60 + +----------------------------------------------------------------------------- +-- Implementation +----------------------------------------------------------------------------- +-- gets server reply (works for SMTP and FTP) +local function get_reply(c) + local code, current, sep + local line, err = c:receive() + local reply = line + if err then return nil, err end + code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) + if not code then return nil, "invalid server reply" end + if sep == "-" then -- reply is multiline + repeat + line, err = c:receive() + if err then return nil, err end + current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) + reply = reply .. "\n" .. line + -- reply ends with same code + until code == current and sep == " " + end + return code, reply +end + +-- metatable for sock object +local metat = { __index = {} } + +function metat.__index:check(ok) + local code, reply = get_reply(self.c) + if not code then return nil, reply end + if base.type(ok) ~= "function" then + if base.type(ok) == "table" then + for i, v in base.ipairs(ok) do + if string.find(code, v) then + return base.tonumber(code), reply + end + end + return nil, reply + else + if string.find(code, ok) then return base.tonumber(code), reply + else return nil, reply end + end + else return ok(base.tonumber(code), reply) end +end + +function metat.__index:command(cmd, arg) + if arg then + return self.c:send(cmd .. " " .. arg.. "\r\n") + else + return self.c:send(cmd .. "\r\n") + end +end + +function metat.__index:sink(snk, pat) + local chunk, err = c:receive(pat) + return snk(chunk, err) +end + +function metat.__index:send(data) + return self.c:send(data) +end + +function metat.__index:receive(pat) + return self.c:receive(pat) +end + +function metat.__index:getfd() + return self.c:getfd() +end + +function metat.__index:dirty() + return self.c:dirty() +end + +function metat.__index:getcontrol() + return self.c +end + +function metat.__index:source(source, step) + local sink = socket.sink("keep-open", self.c) + local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step) + return ret, err +end + +-- closes the underlying c +function metat.__index:close() + self.c:close() + return 1 +end + +-- connect with server and return c object +function connect(host, port, timeout, create) + local c, e = (create or socket.tcp)() + if not c then return nil, e end + c:settimeout(timeout or TIMEOUT) + local r, e = c:connect(host, port) + if not r then + c:close() + return nil, e + end + return base.setmetatable({c = c}, metat) +end + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/tp_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/tp_lua.c new file mode 100644 index 00000000000..897579d53ef --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/tp_lua.c @@ -0,0 +1,194 @@ +/* + * This file is auto-generated by "./lua2c tp.lua tp_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_tp_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 85,110,105,102,105,101,100, 32, 83, 77, 84, 80, 47, 70, 84, 80, 32,115,117, + 98,115,121,115,116,101,109, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, + 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, + 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, + 73, 68, 58, 32, 36, 73,100, 58, 32,116,112, 46,108,117, 97, 44,118, 32, 49, 46, + 50, 50, 32, 50, 48, 48, 54, 47, 48, 51, 47, 49, 52, 32, 48, 57, 58, 48, 52, 58, + 49, 53, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97, +114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, + 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97, +115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, + 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117, +105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32, +108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, + 49, 50, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46, +116,112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, + 97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 73,109, +112,108,101,109,101,110,116, 97,116,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,103,101,116,115, 32,115, +101,114,118,101,114, 32,114,101,112,108,121, 32, 40,119,111,114,107,115, 32,102, +111,114, 32, 83, 77, 84, 80, 32, 97,110,100, 32, 70, 84, 80, 41, 10,108,111, 99, + 97,108, 32,102,117,110, 99,116,105,111,110, 32,103,101,116, 95,114,101,112,108, +121, 40, 99, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, + 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, + 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101, +112,108,121, 32, 61, 32,108,105,110,101, 10, 32, 32, 32, 32,105,102, 32,101,114, +114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, +114,114, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,101,112, + 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116, +114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37, +100, 37,100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32,105,102, + 32,110,111,116, 32, 99,111,100,101, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, 32,115,101,114,118, +101,114, 32,114,101,112,108,121, 34, 32,101,110,100, 10, 32, 32, 32, 32,105,102, + 32,115,101,112, 32, 61, 61, 32, 34, 45, 34, 32,116,104,101,110, 32, 45, 45, 32, +114,101,112,108,121, 32,105,115, 32,109,117,108,116,105,108,105,110,101, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,112,101, 97,116, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58, +114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, + 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 32, 61, + 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,114,105, +110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37,100, 37, +100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,112,108,121, 32, 61, 32,114,101,112,108,121, 32, 46, 46, + 32, 34, 92,110, 34, 32, 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 45, 45, 32,114,101,112,108,121, 32,101,110,100,115, 32,119,105,116,104, + 32,115, 97,109,101, 32, 99,111,100,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,117, +110,116,105,108, 32, 99,111,100,101, 32, 61, 61, 32, 99,117,114,114,101,110,116, + 32, 97,110,100, 32,115,101,112, 32, 61, 61, 32, 34, 32, 34, 10, 32, 32, 32, 32, +101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,111,100,101, 44, + 32,114,101,112,108,121, 10,101,110,100, 10, 10, 45, 45, 32,109,101,116, 97,116, + 97, 98,108,101, 32,102,111,114, 32,115,111, 99,107, 32,111, 98,106,101, 99,116, + 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105, +110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116,105,111, +110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,104,101, 99, +107, 40,111,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, + 44, 32,114,101,112,108,121, 32, 61, 32,103,101,116, 95,114,101,112,108,121, 40, +115,101,108,102, 46, 99, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, +111,100,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, + 32,114,101,112,108,121, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32, 98, 97, +115,101, 46,116,121,112,101, 40,111,107, 41, 32,126, 61, 32, 34,102,117,110, 99, +116,105,111,110, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105, +102, 32, 98, 97,115,101, 46,116,121,112,101, 40,111,107, 41, 32, 61, 61, 32, 34, +116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105,110, 32, 98, 97,115,101, + 46,105,112, 97,105,114,115, 40,111,107, 41, 32,100,111, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, + 46,102,105,110,100, 40, 99,111,100,101, 44, 32,118, 41, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40, 99,111,100,101, 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101,112,108,121, 10, + 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, + 99,111,100,101, 44, 32,111,107, 41, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101, + 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101, +112,108,121, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,111,107, 40, 98, + 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101, 41, 44, 32, +114,101,112,108,121, 41, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99, +116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99, +111,109,109, 97,110,100, 40, 99,109,100, 44, 32, 97,114,103, 41, 10, 32, 32, 32, + 32,105,102, 32, 97,114,103, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40, + 99,109,100, 32, 46, 46, 32, 34, 32, 34, 32, 46, 46, 32, 97,114,103, 46, 46, 32, + 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115, +101,110,100, 40, 99,109,100, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, + 32, 32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, + 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,105,110,107, 40, +115,110,107, 44, 32,112, 97,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, + 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, 99,101,105, +118,101, 40,112, 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, +110,107, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58,115,101,110,100, 40,100, 97,116, 97, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40,100, 97,116, + 97, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, + 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, 40,112, + 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, + 99, 58,114,101, 99,101,105,118,101, 40,112, 97,116, 41, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58,103,101,116,102,100, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,115,101,108,102, 46, 99, 58,103,101,116,102,100, 40, 41, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,100,105,114,116,121, 40, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,115,101,108,102, 46, 99, 58,100,105,114,116,121, 40, 41, 10,101, +110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, + 95,105,110,100,101,120, 58,103,101,116, 99,111,110,116,114,111,108, 40, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 10,101,110, +100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,115,111,117,114, 99,101, 40,115,111,117,114, 99,101, 44, + 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,110, +107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, 40, 34,107,101,101, +112, 45,111,112,101,110, 34, 44, 32,115,101,108,102, 46, 99, 41, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 32, 61, 32,108,116, +110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, + 32,115,105,110,107, 44, 32,115,116,101,112, 32,111,114, 32,108,116,110, 49, 50, + 46,112,117,109,112, 46,115,116,101,112, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,114,101,116, 44, 32,101,114,114, 10,101,110,100, 10, 10, 45, 45, 32, + 99,108,111,115,101,115, 32,116,104,101, 32,117,110,100,101,114,108,121,105,110, +103, 32, 99, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, + 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115, +101,108,102, 46, 99, 58, 99,108,111,115,101, 40, 41, 10, 9,114,101,116,117,114, +110, 32, 49, 10,101,110,100, 10, 10, 45, 45, 32, 99,111,110,110,101, 99,116, 32, +119,105,116,104, 32,115,101,114,118,101,114, 32, 97,110,100, 32,114,101,116,117, +114,110, 32, 99, 32,111, 98,106,101, 99,116, 10,102,117,110, 99,116,105,111,110, + 32, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, 32,112,111,114,116, 44, + 32,116,105,109,101,111,117,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32, 99, 44, 32,101, 32, 61, 32, 40, 99,114,101, 97, +116,101, 32,111,114, 32,115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 10, + 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, 32,116,104,101,110, 32,114,101, +116,117,114,110, 32,110,105,108, 44, 32,101, 32,101,110,100, 10, 32, 32, 32, 32, + 99, 58,115,101,116,116,105,109,101,111,117,116, 40,116,105,109,101,111,117,116, + 32,111,114, 32, 84, 73, 77, 69, 79, 85, 84, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114, 44, 32,101, 32, 61, 32, 99, 58, 99,111,110,110,101, 99,116, 40, +104,111,115,116, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110, +111,116, 32,114, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, 58, + 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32,110,105,108, 44, 32,101, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, + 97,116, 97, 98,108,101, 40,123, 99, 32, 61, 32, 99,125, 44, 32,109,101,116, 97, +116, 41, 10,101,110,100, 10, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/udp.c b/Build/source/texk/web2c/luatexdir/luasocket/src/udp.c new file mode 100644 index 00000000000..fc25aa027dc --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/udp.c @@ -0,0 +1,336 @@ +/*=========================================================================*\ +* UDP object +* LuaSocket toolkit +* +* RCS ID: $Id: udp.c,v 1.29 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "socket.h" +#include "inet.h" +#include "options.h" +#include "udp.h" + +/* min and max macros */ +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? x : y) +#endif +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? x : y) +#endif + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_send(lua_State *L); +static int meth_sendto(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_receivefrom(lua_State *L); +static int meth_getsockname(lua_State *L); +static int meth_getpeername(lua_State *L); +static int meth_setsockname(lua_State *L); +static int meth_setpeername(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); + +/* udp object methods */ +static luaL_reg udp[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"close", meth_close}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getpeername", meth_getpeername}, + {"getsockname", meth_getsockname}, + {"receive", meth_receive}, + {"receivefrom", meth_receivefrom}, + {"send", meth_send}, + {"sendto", meth_sendto}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_setpeername}, + {"setsockname", meth_setsockname}, + {"settimeout", meth_settimeout}, + {NULL, NULL} +}; + +/* socket options */ +static t_opt opt[] = { + {"dontroute", opt_dontroute}, + {"broadcast", opt_broadcast}, + {"reuseaddr", opt_reuseaddr}, + {"ip-multicast-ttl", opt_ip_multicast_ttl}, + {"ip-multicast-loop", opt_ip_multicast_loop}, + {"ip-add-membership", opt_ip_add_membership}, + {"ip-drop-membership", opt_ip_drop_membersip}, + {NULL, NULL} +}; + +/* functions in library namespace */ +static luaL_reg func[] = { + {"udp", global_create}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int udp_open(lua_State *L) +{ + /* create classes */ + auxiliar_newclass(L, "udp{connected}", udp); + auxiliar_newclass(L, "udp{unconnected}", udp); + /* create class groups */ + auxiliar_add2group(L, "udp{connected}", "udp{any}"); + auxiliar_add2group(L, "udp{unconnected}", "udp{any}"); + auxiliar_add2group(L, "udp{connected}", "select{able}"); + auxiliar_add2group(L, "udp{unconnected}", "select{able}"); + /* define library functions */ + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +const char *udp_strerror(int err) { + /* a 'closed' error on an unconnected means the target address was not + * accepted by the transport layer */ + if (err == IO_CLOSED) return "refused"; + else return socket_strerror(err); +} + +/*-------------------------------------------------------------------------*\ +* Send data through connected udp socket +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); + p_timeout tm = &udp->tm; + size_t count, sent = 0; + int err; + const char *data = luaL_checklstring(L, 2, &count); + timeout_markstart(tm); + err = socket_send(&udp->sock, data, count, &sent, tm); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } + lua_pushnumber(L, sent); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Send data through unconnected udp socket +\*-------------------------------------------------------------------------*/ +static int meth_sendto(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); + size_t count, sent = 0; + const char *data = luaL_checklstring(L, 2, &count); + const char *ip = luaL_checkstring(L, 3); + unsigned short port = (unsigned short) luaL_checknumber(L, 4); + p_timeout tm = &udp->tm; + struct sockaddr_in addr; + int err; + memset(&addr, 0, sizeof(addr)); + if (!inet_aton(ip, &addr.sin_addr)) + luaL_argerror(L, 3, "invalid ip address"); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + timeout_markstart(tm); + err = socket_sendto(&udp->sock, data, count, &sent, + (SA *) &addr, sizeof(addr), tm); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } + lua_pushnumber(L, sent); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Receives data from a UDP socket +\*-------------------------------------------------------------------------*/ +static int meth_receive(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + char buffer[UDP_DATAGRAMSIZE]; + size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); + int err; + p_timeout tm = &udp->tm; + count = MIN(count, sizeof(buffer)); + timeout_markstart(tm); + err = socket_recv(&udp->sock, buffer, count, &got, tm); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } + lua_pushlstring(L, buffer, got); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Receives data and sender from a UDP socket +\*-------------------------------------------------------------------------*/ +static int meth_receivefrom(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + char buffer[UDP_DATAGRAMSIZE]; + size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); + int err; + p_timeout tm = &udp->tm; + timeout_markstart(tm); + count = MIN(count, sizeof(buffer)); + err = socket_recvfrom(&udp->sock, buffer, count, &got, + (SA *) &addr, &addr_len, tm); + if (err == IO_DONE) { + lua_pushlstring(L, buffer, got); + lua_pushstring(L, inet_ntoa(addr.sin_addr)); + lua_pushnumber(L, ntohs(addr.sin_port)); + return 3; + } else { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + lua_pushnumber(L, (int) udp->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + udp->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + (void) udp; + lua_pushboolean(L, 0); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Just call inet methods +\*-------------------------------------------------------------------------*/ +static int meth_getpeername(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); + return inet_meth_getpeername(L, &udp->sock); +} + +static int meth_getsockname(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return inet_meth_getsockname(L, &udp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return opt_meth_setoption(L, opt, &udp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return timeout_meth_settimeout(L, &udp->tm); +} + +/*-------------------------------------------------------------------------*\ +* Turns a master udp object into a client object. +\*-------------------------------------------------------------------------*/ +static int meth_setpeername(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + p_timeout tm = &udp->tm; + const char *address = luaL_checkstring(L, 2); + int connecting = strcmp(address, "*"); + unsigned short port = connecting ? + (unsigned short) luaL_checknumber(L, 3) : + (unsigned short) luaL_optnumber(L, 3, 0); + const char *err = inet_tryconnect(&udp->sock, address, port, tm); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* change class to connected or unconnected depending on address */ + if (connecting) auxiliar_setclass(L, "udp{connected}", 1); + else auxiliar_setclass(L, "udp{unconnected}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + socket_destroy(&udp->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master object into a server object +\*-------------------------------------------------------------------------*/ +static int meth_setsockname(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); + const char *address = luaL_checkstring(L, 2); + unsigned short port = (unsigned short) luaL_checknumber(L, 3); + const char *err = inet_trybind(&udp->sock, address, port); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master udp object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) { + t_socket sock; + const char *err = inet_trycreate(&sock, SOCK_DGRAM); + /* try to allocate a system socket */ + if (!err) { + /* allocate tcp object */ + p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); + auxiliar_setclass(L, "udp{unconnected}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + udp->sock = sock; + timeout_init(&udp->tm, -1, -1); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/udp.h b/Build/source/texk/web2c/luatexdir/luasocket/src/udp.h new file mode 100644 index 00000000000..28017121714 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/udp.h @@ -0,0 +1,33 @@ +#ifndef UDP_H +#define UDP_H +/*=========================================================================*\ +* UDP object +* LuaSocket toolkit +* +* The udp.h module provides LuaSocket with support for UDP protocol +* (AF_INET, SOCK_DGRAM). +* +* Two classes are defined: connected and unconnected. UDP objects are +* originally unconnected. They can be "connected" to a given address +* with a call to the setpeername function. The same function can be used to +* break the connection. +* +* RCS ID: $Id: udp.h,v 1.10 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "timeout.h" +#include "socket.h" + +/* can't be larger than wsocket.c MAXCHUNK!!! */ +#define UDP_DATAGRAMSIZE 8192 + +typedef struct t_udp_ { + t_socket sock; + t_timeout tm; +} t_udp; +typedef t_udp *p_udp; + +int udp_open(lua_State *L); + +#endif /* UDP_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/unix.c b/Build/source/texk/web2c/luatexdir/luasocket/src/unix.c new file mode 100644 index 00000000000..158d319a5f2 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/unix.c @@ -0,0 +1,356 @@ +/*=========================================================================*\ +* Unix domain socket +* LuaSocket toolkit +* +* RCS ID: $Id: unix.c,v 1.13 2006/03/13 07:16:39 diego Exp $ +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "socket.h" +#include "options.h" +#include "unix.h" +#include + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_connect(lua_State *L); +static int meth_listen(lua_State *L); +static int meth_bind(lua_State *L); +static int meth_send(lua_State *L); +static int meth_shutdown(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_accept(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); +static int meth_getstats(lua_State *L); +static int meth_setstats(lua_State *L); + +static const char *unix_tryconnect(p_unix un, const char *path); +static const char *unix_trybind(p_unix un, const char *path); + +/* unix object methods */ +static luaL_reg un[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"accept", meth_accept}, + {"bind", meth_bind}, + {"close", meth_close}, + {"connect", meth_connect}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getstats", meth_getstats}, + {"setstats", meth_setstats}, + {"listen", meth_listen}, + {"receive", meth_receive}, + {"send", meth_send}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_connect}, + {"setsockname", meth_bind}, + {"settimeout", meth_settimeout}, + {"shutdown", meth_shutdown}, + {NULL, NULL} +}; + +/* socket option handlers */ +static t_opt opt[] = { + {"keepalive", opt_keepalive}, + {"reuseaddr", opt_reuseaddr}, + {"linger", opt_linger}, + {NULL, NULL} +}; + +/* our socket creation function */ +static luaL_reg func[] = { + {"unix", global_create}, + {NULL, NULL} +}; + + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int luaopen_socket_unix(lua_State *L) { + /* create classes */ + auxiliar_newclass(L, "unix{master}", un); + auxiliar_newclass(L, "unix{client}", un); + auxiliar_newclass(L, "unix{server}", un); + /* create class groups */ + auxiliar_add2group(L, "unix{master}", "unix{any}"); + auxiliar_add2group(L, "unix{client}", "unix{any}"); + auxiliar_add2group(L, "unix{server}", "unix{any}"); + /* make sure the function ends up in the package table */ + luaL_openlib(L, "socket", func, 0); + /* return the function instead of the 'socket' table */ + lua_pushstring(L, "unix"); + lua_gettable(L, -2); + return 1; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Just call buffered IO methods +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_send(L, &un->buf); +} + +static int meth_receive(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_receive(L, &un->buf); +} + +static int meth_getstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_getstats(L, &un->buf); +} + +static int meth_setstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_setstats(L, &un->buf); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + return opt_meth_setoption(L, opt, &un->sock); +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + lua_pushnumber(L, (int) un->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + un->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + lua_pushboolean(L, !buffer_isempty(&un->buf)); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Waits for and returns a client object attempting connection to the +* server object +\*-------------------------------------------------------------------------*/ +static int meth_accept(lua_State *L) { + p_unix server = (p_unix) auxiliar_checkclass(L, "unix{server}", 1); + p_timeout tm = timeout_markstart(&server->tm); + t_socket sock; + int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); + /* if successful, push client socket */ + if (err == IO_DONE) { + p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + auxiliar_setclass(L, "unix{client}", -1); + /* initialize structure fields */ + socket_setnonblocking(&sock); + clnt->sock = sock; + io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv, + (p_error) socket_ioerror, &clnt->sock); + timeout_init(&clnt->tm, -1, -1); + buffer_init(&clnt->buf, &clnt->io, &clnt->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ +* Binds an object to an address +\*-------------------------------------------------------------------------*/ +static const char *unix_trybind(p_unix un, const char *path) { + struct sockaddr_un local; + size_t len = strlen(path); + int err; + if (len >= sizeof(local.sun_path)) return "path too long"; + memset(&local, 0, sizeof(local)); + strcpy(local.sun_path, path); + local.sun_family = AF_UNIX; +#ifdef UNIX_HAS_SUN_LEN + local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) + + len + 1; + err = socket_bind(&un->sock, (SA *) &local, local.sun_len); + +#else + err = socket_bind(&un->sock, (SA *) &local, + sizeof(local.sun_family) + len); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_bind(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unix_trybind(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master unix object into a client object. +\*-------------------------------------------------------------------------*/ +static const char *unix_tryconnect(p_unix un, const char *path) +{ + struct sockaddr_un remote; + int err; + size_t len = strlen(path); + if (len >= sizeof(remote.sun_path)) return "path too long"; + memset(&remote, 0, sizeof(remote)); + strcpy(remote.sun_path, path); + remote.sun_family = AF_UNIX; + timeout_markstart(&un->tm); +#ifdef UNIX_HAS_SUN_LEN + remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + + len + 1; + err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); +#else + err = socket_connect(&un->sock, (SA *) &remote, + sizeof(remote.sun_family) + len, &un->tm); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_connect(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unix_tryconnect(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* turn master object into a client object */ + auxiliar_setclass(L, "unix{client}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + socket_destroy(&un->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Puts the sockt in listen mode +\*-------------------------------------------------------------------------*/ +static int meth_listen(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); + int backlog = (int) luaL_optnumber(L, 2, 32); + int err = socket_listen(&un->sock, backlog); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } + /* turn master object into a server object */ + auxiliar_setclass(L, "unix{server}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Shuts the connection down partially +\*-------------------------------------------------------------------------*/ +static int meth_shutdown(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + const char *how = luaL_optstring(L, 2, "both"); + switch (how[0]) { + case 'b': + if (strcmp(how, "both")) goto error; + socket_shutdown(&un->sock, 2); + break; + case 's': + if (strcmp(how, "send")) goto error; + socket_shutdown(&un->sock, 1); + break; + case 'r': + if (strcmp(how, "receive")) goto error; + socket_shutdown(&un->sock, 0); + break; + } + lua_pushnumber(L, 1); + return 1; +error: + luaL_argerror(L, 2, "invalid shutdown method"); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + return timeout_meth_settimeout(L, &un->tm); +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master unix object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) { + t_socket sock; + int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0); + /* try to allocate a system socket */ + if (err == IO_DONE) { + /* allocate unix object */ + p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + /* set its type as master object */ + auxiliar_setclass(L, "unix{master}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + un->sock = sock; + io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &un->sock); + timeout_init(&un->tm, -1, -1); + buffer_init(&un->buf, &un->io, &un->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/unix.h b/Build/source/texk/web2c/luatexdir/luasocket/src/unix.h new file mode 100644 index 00000000000..32b7380fffa --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/unix.h @@ -0,0 +1,28 @@ +#ifndef UNIX_H +#define UNIX_H +/*=========================================================================*\ +* Unix domain object +* LuaSocket toolkit +* +* This module is just an example of how to extend LuaSocket with a new +* domain. +* +* RCS ID: $Id: unix.h,v 1.9 2006/03/13 07:16:39 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "buffer.h" +#include "timeout.h" +#include "socket.h" + +typedef struct t_unix_ { + t_socket sock; + t_io io; + t_buffer buf; + t_timeout tm; +} t_unix; +typedef t_unix *p_unix; + +int luaopen_socket_unix(lua_State *L); + +#endif /* UNIX_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/url.lua b/Build/source/texk/web2c/luatexdir/luasocket/src/url.lua new file mode 100644 index 00000000000..0e31d8af20d --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/url.lua @@ -0,0 +1,297 @@ +----------------------------------------------------------------------------- +-- URI parsing, composition and relative URL resolution +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: url.lua,v 1.38 2006/04/03 04:45:42 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module +----------------------------------------------------------------------------- +local string = require("string") +local base = _G +local table = require("table") +module("socket.url") + +----------------------------------------------------------------------------- +-- Module version +----------------------------------------------------------------------------- +_VERSION = "URL 1.0.1" + +----------------------------------------------------------------------------- +-- Encodes a string into its escaped hexadecimal representation +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +function escape(s) + return string.gsub(s, "([^A-Za-z0-9_])", function(c) + return string.format("%%%02x", string.byte(c)) + end) +end + +----------------------------------------------------------------------------- +-- Protects a path segment, to prevent it from interfering with the +-- url parsing. +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +local function make_set(t) + local s = {} + for i,v in base.ipairs(t) do + s[t[i]] = 1 + end + return s +end + +-- these are allowed withing a path segment, along with alphanum +-- other characters must be escaped +local segment_set = make_set { + "-", "_", ".", "!", "~", "*", "'", "(", + ")", ":", "@", "&", "=", "+", "$", ",", +} + +local function protect_segment(s) + return string.gsub(s, "([^A-Za-z0-9_])", function (c) + if segment_set[c] then return c + else return string.format("%%%02x", string.byte(c)) end + end) +end + +----------------------------------------------------------------------------- +-- Encodes a string into its escaped hexadecimal representation +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +function unescape(s) + return string.gsub(s, "%%(%x%x)", function(hex) + return string.char(base.tonumber(hex, 16)) + end) +end + +----------------------------------------------------------------------------- +-- Builds a path from a base path and a relative path +-- Input +-- base_path +-- relative_path +-- Returns +-- corresponding absolute path +----------------------------------------------------------------------------- +local function absolute_path(base_path, relative_path) + if string.sub(relative_path, 1, 1) == "/" then return relative_path end + local path = string.gsub(base_path, "[^/]*$", "") + path = path .. relative_path + path = string.gsub(path, "([^/]*%./)", function (s) + if s ~= "./" then return s else return "" end + end) + path = string.gsub(path, "/%.$", "/") + local reduced + while reduced ~= path do + reduced = path + path = string.gsub(reduced, "([^/]*/%.%./)", function (s) + if s ~= "../../" then return "" else return s end + end) + end + path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) + if s ~= "../.." then return "" else return s end + end) + return path +end + +----------------------------------------------------------------------------- +-- Parses a url and returns a table with all its parts according to RFC 2396 +-- The following grammar describes the names given to the URL parts +-- ::= :///;?# +-- ::= @: +-- ::= [:] +-- :: = {/} +-- Input +-- url: uniform resource locator of request +-- default: table with default values for each field +-- Returns +-- table with the following fields, where RFC naming conventions have +-- been preserved: +-- scheme, authority, userinfo, user, password, host, port, +-- path, params, query, fragment +-- Obs: +-- the leading '/' in {/} is considered part of +----------------------------------------------------------------------------- +function parse(url, default) + -- initialize default parameters + local parsed = {} + for i,v in base.pairs(default or parsed) do parsed[i] = v end + -- empty url is parsed to nil + if not url or url == "" then return nil, "invalid url" end + -- remove whitespace + -- url = string.gsub(url, "%s", "") + -- get fragment + url = string.gsub(url, "#(.*)$", function(f) + parsed.fragment = f + return "" + end) + -- get scheme + url = string.gsub(url, "^([%w][%w%+%-%.]*)%:", + function(s) parsed.scheme = s; return "" end) + -- get authority + url = string.gsub(url, "^//([^/]*)", function(n) + parsed.authority = n + return "" + end) + -- get query stringing + url = string.gsub(url, "%?(.*)", function(q) + parsed.query = q + return "" + end) + -- get params + url = string.gsub(url, "%;(.*)", function(p) + parsed.params = p + return "" + end) + -- path is whatever was left + if url ~= "" then parsed.path = url end + local authority = parsed.authority + if not authority then return parsed end + authority = string.gsub(authority,"^([^@]*)@", + function(u) parsed.userinfo = u; return "" end) + authority = string.gsub(authority, ":([^:]*)$", + function(p) parsed.port = p; return "" end) + if authority ~= "" then parsed.host = authority end + local userinfo = parsed.userinfo + if not userinfo then return parsed end + userinfo = string.gsub(userinfo, ":([^:]*)$", + function(p) parsed.password = p; return "" end) + parsed.user = userinfo + return parsed +end + +----------------------------------------------------------------------------- +-- Rebuilds a parsed URL from its components. +-- Components are protected if any reserved or unallowed characters are found +-- Input +-- parsed: parsed URL, as returned by parse +-- Returns +-- a stringing with the corresponding URL +----------------------------------------------------------------------------- +function build(parsed) + local ppath = parse_path(parsed.path or "") + local url = build_path(ppath) + if parsed.params then url = url .. ";" .. parsed.params end + if parsed.query then url = url .. "?" .. parsed.query end + local authority = parsed.authority + if parsed.host then + authority = parsed.host + if parsed.port then authority = authority .. ":" .. parsed.port end + local userinfo = parsed.userinfo + if parsed.user then + userinfo = parsed.user + if parsed.password then + userinfo = userinfo .. ":" .. parsed.password + end + end + if userinfo then authority = userinfo .. "@" .. authority end + end + if authority then url = "//" .. authority .. url end + if parsed.scheme then url = parsed.scheme .. ":" .. url end + if parsed.fragment then url = url .. "#" .. parsed.fragment end + -- url = string.gsub(url, "%s", "") + return url +end + +----------------------------------------------------------------------------- +-- Builds a absolute URL from a base and a relative URL according to RFC 2396 +-- Input +-- base_url +-- relative_url +-- Returns +-- corresponding absolute url +----------------------------------------------------------------------------- +function absolute(base_url, relative_url) + if base.type(base_url) == "table" then + base_parsed = base_url + base_url = build(base_parsed) + else + base_parsed = parse(base_url) + end + local relative_parsed = parse(relative_url) + if not base_parsed then return relative_url + elseif not relative_parsed then return base_url + elseif relative_parsed.scheme then return relative_url + else + relative_parsed.scheme = base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority = base_parsed.authority + if not relative_parsed.path then + relative_parsed.path = base_parsed.path + if not relative_parsed.params then + relative_parsed.params = base_parsed.params + if not relative_parsed.query then + relative_parsed.query = base_parsed.query + end + end + else + relative_parsed.path = absolute_path(base_parsed.path or "", + relative_parsed.path) + end + end + return build(relative_parsed) + end +end + +----------------------------------------------------------------------------- +-- Breaks a path into its segments, unescaping the segments +-- Input +-- path +-- Returns +-- segment: a table with one entry per segment +----------------------------------------------------------------------------- +function parse_path(path) + local parsed = {} + path = path or "" + --path = string.gsub(path, "%s", "") + string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) + for i = 1, table.getn(parsed) do + parsed[i] = unescape(parsed[i]) + end + if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end + if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end + return parsed +end + +----------------------------------------------------------------------------- +-- Builds a path component from its segments, escaping protected characters. +-- Input +-- parsed: path segments +-- unsafe: if true, segments are not protected before path is built +-- Returns +-- path: corresponding path stringing +----------------------------------------------------------------------------- +function build_path(parsed, unsafe) + local path = "" + local n = table.getn(parsed) + if unsafe then + for i = 1, n-1 do + path = path .. parsed[i] + path = path .. "/" + end + if n > 0 then + path = path .. parsed[n] + if parsed.is_directory then path = path .. "/" end + end + else + for i = 1, n-1 do + path = path .. protect_segment(parsed[i]) + path = path .. "/" + end + if n > 0 then + path = path .. protect_segment(parsed[n]) + if parsed.is_directory then path = path .. "/" end + end + end + if parsed.is_absolute then path = "/" .. path end + return path +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/url_lua.c b/Build/source/texk/web2c/luatexdir/luasocket/src/url_lua.c new file mode 100644 index 00000000000..7b4a6e799c0 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/url_lua.c @@ -0,0 +1,540 @@ +/* + * This file is auto-generated by "./lua2c url.lua url_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_url_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 85, 82, 73, 32,112, 97,114,115,105,110,103, 44, 32, 99,111,109,112,111,115, +105,116,105,111,110, 32, 97,110,100, 32,114,101,108, 97,116,105,118,101, 32, 85, + 82, 76, 32,114,101,115,111,108,117,116,105,111,110, 10, 45, 45, 32, 76,117, 97, + 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65, +117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, + 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,117,114,108, 46,108, +117, 97, 44,118, 32, 49, 46, 51, 56, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51, + 32, 48, 52, 58, 52, 53, 58, 52, 50, 32,100,105,101,103,111, 32, 69,120,112, 32, + 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, + 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115, +116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, + 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101, +113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, 41, 10,109,111,100,117,108, +101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 77,111, +100,117,108,101, 32,118,101,114,115,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32, + 61, 32, 34, 85, 82, 76, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,110, 99,111, +100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116,111, 32,105,116, +115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, 99,105,109, 97, +108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, 10, 45, 45, 32, + 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105,110, 97,114,121, + 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, 99,111,100,101, +100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32,101,115, + 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, + 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114,121, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99, +116,105,111,110, 32,101,115, 99, 97,112,101, 40,115, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, + 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, 34, 44, 32, +102,117,110, 99,116,105,111,110, 40, 99, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, + 40, 34, 37, 37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121, +116,101, 40, 99, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 80,114,111,116,101, 99,116,115, 32, 97, 32,112, 97,116,104, 32,115,101, +103,109,101,110,116, 44, 32,116,111, 32,112,114,101,118,101,110,116, 32,105,116, + 32,102,114,111,109, 32,105,110,116,101,114,102,101,114,105,110,103, 32,119,105, +116,104, 32,116,104,101, 10, 45, 45, 32,117,114,108, 32,112, 97,114,115,105,110, +103, 46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, + 98,105,110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32, +101,110, 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, + 45, 32, 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110, +116, 97,116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, + 97,114,121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,109, 97,107, +101, 95,115,101,116, 40,116, 41, 10, 9,108,111, 99, 97,108, 32,115, 32, 61, 32, +123,125, 10, 9,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46, +105,112, 97,105,114,115, 40,116, 41, 32,100,111, 10, 9, 9,115, 91,116, 91,105, + 93, 93, 32, 61, 32, 49, 10, 9,101,110,100, 10, 9,114,101,116,117,114,110, 32, +115, 10,101,110,100, 10, 10, 45, 45, 32,116,104,101,115,101, 32, 97,114,101, 32, + 97,108,108,111,119,101,100, 32,119,105,116,104,105,110,103, 32, 97, 32,112, 97, +116,104, 32,115,101,103,109,101,110,116, 44, 32, 97,108,111,110,103, 32,119,105, +116,104, 32, 97,108,112,104, 97,110,117,109, 10, 45, 45, 32,111,116,104,101,114, + 32, 99,104, 97,114, 97, 99,116,101,114,115, 32,109,117,115,116, 32, 98,101, 32, +101,115, 99, 97,112,101,100, 10,108,111, 99, 97,108, 32,115,101,103,109,101,110, +116, 95,115,101,116, 32, 61, 32,109, 97,107,101, 95,115,101,116, 32,123, 10, 32, + 32, 32, 32, 34, 45, 34, 44, 32, 34, 95, 34, 44, 32, 34, 46, 34, 44, 32, 34, 33, + 34, 44, 32, 34,126, 34, 44, 32, 34, 42, 34, 44, 32, 34, 39, 34, 44, 32, 34, 40, + 34, 44, 10, 9, 34, 41, 34, 44, 32, 34, 58, 34, 44, 32, 34, 64, 34, 44, 32, 34, + 38, 34, 44, 32, 34, 61, 34, 44, 32, 34, 43, 34, 44, 32, 34, 36, 34, 44, 32, 34, + 44, 34, 44, 10,125, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111, +110, 32,112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,115, 41, + 10, 9,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, + 40,115, 44, 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, + 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40, 99, 41, 10, 9, 9,105,102, + 32,115,101,103,109,101,110,116, 95,115,101,116, 91, 99, 93, 32,116,104,101,110, + 32,114,101,116,117,114,110, 32, 99, 10, 9, 9,101,108,115,101, 32,114,101,116, +117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37, + 37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121,116,101, 40, + 99, 41, 41, 32,101,110,100, 10, 9,101,110,100, 41, 10,101,110,100, 10, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, + 69,110, 99,111,100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116, +111, 32,105,116,115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, + 99,105,109, 97,108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, + 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105, +110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, + 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, + 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97, +116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114, +121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, +102,117,110, 99,116,105,111,110, 32,117,110,101,115, 99, 97,112,101, 40,115, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103, +115,117, 98, 40,115, 44, 32, 34, 37, 37, 40, 37,120, 37,120, 41, 34, 44, 32,102, +117,110, 99,116,105,111,110, 40,104,101,120, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46, 99,104, 97,114, 40, + 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40,104,101,120, 44, 32, 49, + 54, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66, +117,105,108,100,115, 32, 97, 32,112, 97,116,104, 32,102,114,111,109, 32, 97, 32, + 98, 97,115,101, 32,112, 97,116,104, 32, 97,110,100, 32, 97, 32,114,101,108, 97, +116,105,118,101, 32,112, 97,116,104, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, + 45, 32, 32, 32, 98, 97,115,101, 95,112, 97,116,104, 10, 45, 45, 32, 32, 32,114, +101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117, +114,110,115, 10, 45, 45, 32, 32, 32, 99,111,114,114,101,115,112,111,110,100,105, +110,103, 32, 97, 98,115,111,108,117,116,101, 32,112, 97,116,104, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, + 32,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108,117,116,101, 95,112, + 97,116,104, 40, 98, 97,115,101, 95,112, 97,116,104, 44, 32,114,101,108, 97,116, +105,118,101, 95,112, 97,116,104, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114, +105,110,103, 46,115,117, 98, 40,114,101,108, 97,116,105,118,101, 95,112, 97,116, +104, 44, 32, 49, 44, 32, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, + 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,112, 97,116, +104, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116,104, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 98, 97,115,101, 95, +112, 97,116,104, 44, 32, 34, 91, 94, 47, 93, 42, 36, 34, 44, 32, 34, 34, 41, 10, + 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,114, +101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 32, 32, 32, 32,112, 97,116, +104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, + 44, 32, 34, 40, 91, 94, 47, 93, 42, 37, 46, 47, 41, 34, 44, 32,102,117,110, 99, +116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +115, 32,126, 61, 32, 34, 46, 47, 34, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,115, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 34, 34, 32,101, +110,100, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,116,104, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44, + 32, 34, 47, 37, 46, 36, 34, 44, 32, 34, 47, 34, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,114,101,100,117, 99,101,100, 10, 32, 32, 32, 32,119,104,105,108, +101, 32,114,101,100,117, 99,101,100, 32,126, 61, 32,112, 97,116,104, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,100,117, 99,101,100, 32, 61, 32,112, + 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,115, +116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117, 99,101,100, 44, 32, + 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 47, 41, 34, 44, 32,102,117,110, + 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 47, 34, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, +101,110,100, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,112, 97,116, +104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117, + 99,101,100, 44, 32, 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 41, 36, 34, + 44, 32,102,117,110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 34, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,116,104, 10,101,110,100, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32, 80, 97,114,115,101,115, 32, 97, 32,117,114,108, 32, 97,110,100, 32, +114,101,116,117,114,110,115, 32, 97, 32,116, 97, 98,108,101, 32,119,105,116,104, + 32, 97,108,108, 32,105,116,115, 32,112, 97,114,116,115, 32, 97, 99, 99,111,114, +100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, 51, 57, 54, 10, 45, 45, 32, + 84,104,101, 32,102,111,108,108,111,119,105,110,103, 32,103,114, 97,109,109, 97, +114, 32,100,101,115, 99,114,105, 98,101,115, 32,116,104,101, 32,110, 97,109,101, +115, 32,103,105,118,101,110, 32,116,111, 32,116,104,101, 32, 85, 82, 76, 32,112, + 97,114,116,115, 10, 45, 45, 32, 60,117,114,108, 62, 32, 58, 58, 61, 32, 60,115, + 99,104,101,109,101, 62, 58, 47, 47, 60, 97,117,116,104,111,114,105,116,121, 62, + 47, 60,112, 97,116,104, 62, 59, 60,112, 97,114, 97,109,115, 62, 63, 60,113,117, +101,114,121, 62, 35, 60,102,114, 97,103,109,101,110,116, 62, 10, 45, 45, 32, 60, + 97,117,116,104,111,114,105,116,121, 62, 32, 58, 58, 61, 32, 60,117,115,101,114, +105,110,102,111, 62, 64, 60,104,111,115,116, 62, 58, 60,112,111,114,116, 62, 10, + 45, 45, 32, 60,117,115,101,114,105,110,102,111, 62, 32, 58, 58, 61, 32, 60,117, +115,101,114, 62, 91, 58, 60,112, 97,115,115,119,111,114,100, 62, 93, 10, 45, 45, + 32, 60,112, 97,116,104, 62, 32, 58, 58, 32, 61, 32,123, 60,115,101,103,109,101, +110,116, 62, 47,125, 60,115,101,103,109,101,110,116, 62, 10, 45, 45, 32, 73,110, +112,117,116, 10, 45, 45, 32, 32, 32,117,114,108, 58, 32,117,110,105,102,111,114, +109, 32,114,101,115,111,117,114, 99,101, 32,108,111, 99, 97,116,111,114, 32,111, +102, 32,114,101,113,117,101,115,116, 10, 45, 45, 32, 32, 32,100,101,102, 97,117, +108,116, 58, 32,116, 97, 98,108,101, 32,119,105,116,104, 32,100,101,102, 97,117, +108,116, 32,118, 97,108,117,101,115, 32,102,111,114, 32,101, 97, 99,104, 32,102, +105,101,108,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, + 32,116, 97, 98,108,101, 32,119,105,116,104, 32,116,104,101, 32,102,111,108,108, +111,119,105,110,103, 32,102,105,101,108,100,115, 44, 32,119,104,101,114,101, 32, + 82, 70, 67, 32,110, 97,109,105,110,103, 32, 99,111,110,118,101,110,116,105,111, +110,115, 32,104, 97,118,101, 10, 45, 45, 32, 32, 32, 98,101,101,110, 32,112,114, +101,115,101,114,118,101,100, 58, 10, 45, 45, 32, 32, 32, 32, 32,115, 99,104,101, +109,101, 44, 32, 97,117,116,104,111,114,105,116,121, 44, 32,117,115,101,114,105, +110,102,111, 44, 32,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 44, + 32,104,111,115,116, 44, 32,112,111,114,116, 44, 10, 45, 45, 32, 32, 32, 32, 32, +112, 97,116,104, 44, 32,112, 97,114, 97,109,115, 44, 32,113,117,101,114,121, 44, + 32,102,114, 97,103,109,101,110,116, 10, 45, 45, 32, 79, 98,115, 58, 10, 45, 45, + 32, 32, 32,116,104,101, 32,108,101, 97,100,105,110,103, 32, 39, 47, 39, 32,105, +110, 32,123, 47, 60,112, 97,116,104, 62,125, 32,105,115, 32, 99,111,110,115,105, +100,101,114,101,100, 32,112, 97,114,116, 32,111,102, 32, 60,112, 97,116,104, 62, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102, +117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117,114,108, 44, 32,100, +101,102, 97,117,108,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,110,105,116,105, + 97,108,105,122,101, 32,100,101,102, 97,117,108,116, 32,112, 97,114, 97,109,101, +116,101,114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,114,115,101, +100, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105, +110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,100,101,102, 97,117,108,116, + 32,111,114, 32,112, 97,114,115,101,100, 41, 32,100,111, 32,112, 97,114,115,101, +100, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32, +101,109,112,116,121, 32,117,114,108, 32,105,115, 32,112, 97,114,115,101,100, 32, +116,111, 32,110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,114, +108, 32,111,114, 32,117,114,108, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, + 32,117,114,108, 34, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,114,101,109, +111,118,101, 32,119,104,105,116,101,115,112, 97, 99,101, 10, 32, 32, 32, 32, 45, + 45, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, +117,114,108, 44, 32, 34, 37,115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32, 45, + 45, 32,103,101,116, 32,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32,117, +114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, + 44, 32, 34, 35, 40, 46, 42, 41, 36, 34, 44, 32,102,117,110, 99,116,105,111,110, + 40,102, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,100, 46,102, +114, 97,103,109,101,110,116, 32, 61, 32,102, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, + 32, 32, 32, 45, 45, 32,103,101,116, 32,115, 99,104,101,109,101, 10, 32, 32, 32, + 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117, +114,108, 44, 32, 34, 94, 40, 91, 37,119, 93, 91, 37,119, 37, 43, 37, 45, 37, 46, + 93, 42, 41, 37, 58, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,117,110, 99, +116,105,111,110, 40,115, 41, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109, +101, 32, 61, 32,115, 59, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,110,100, + 41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32, 97,117,116,104,111,114,105, +116,121, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46, +103,115,117, 98, 40,117,114,108, 44, 32, 34, 94, 47, 47, 40, 91, 94, 47, 93, 42, + 41, 34, 44, 32,102,117,110, 99,116,105,111,110, 40,110, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, + 32, 61, 32,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, + 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,103, +101,116, 32,113,117,101,114,121, 32,115,116,114,105,110,103,105,110,103, 10, 32, + 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, + 40,117,114,108, 44, 32, 34, 37, 63, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99, +116,105,111,110, 40,113, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115, +101,100, 46,113,117,101,114,121, 32, 61, 32,113, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, + 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,112, 97,114, 97,109,115, 10, 32, 32, + 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, +117,114,108, 44, 32, 34, 37, 59, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99,116, +105,111,110, 40,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101, +100, 46,112, 97,114, 97,109,115, 32, 61, 32,112, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, + 32, 32, 32, 32, 45, 45, 32,112, 97,116,104, 32,105,115, 32,119,104, 97,116,101, +118,101,114, 32,119, 97,115, 32,108,101,102,116, 10, 32, 32, 32, 32,105,102, 32, +117,114,108, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112, 97,114,115,101, +100, 46,112, 97,116,104, 32, 61, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, + 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, +105,102, 32,110,111,116, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 32,101,110,100, 10, + 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,115,116,114,105, +110,103, 46,103,115,117, 98, 40, 97,117,116,104,111,114,105,116,121, 44, 34, 94, + 40, 91, 94, 64, 93, 42, 41, 64, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102, +117,110, 99,116,105,111,110, 40,117, 41, 32,112, 97,114,115,101,100, 46,117,115, +101,114,105,110,102,111, 32, 61, 32,117, 59, 32,114,101,116,117,114,110, 32, 34, + 34, 32,101,110,100, 41, 10, 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 97,117,116,104,111, +114,105,116,121, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, + 97,114,115,101,100, 46,112,111,114,116, 32, 61, 32,112, 59, 32,114,101,116,117, +114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,105,102, 32, 97,117, +116,104,111,114,105,116,121, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112, + 97,114,115,101,100, 46,104,111,115,116, 32, 61, 32, 97,117,116,104,111,114,105, +116,121, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,115,101, +114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114,105, +110,102,111, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114,105, +110,102,111, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,112, 97,114,115, +101,100, 32,101,110,100, 10, 32, 32, 32, 32,117,115,101,114,105,110,102,111, 32, + 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,115,101,114,105,110, +102,111, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, 32, 32, + 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, 97,114, +115,101,100, 46,112, 97,115,115,119,111,114,100, 32, 61, 32,112, 59, 32,114,101, +116,117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,114, +115,101,100, 46,117,115,101,114, 32, 61, 32,117,115,101,114,105,110,102,111, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 10,101,110, +100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 10, 45, 45, 32, 82,101, 98,117,105,108,100,115, 32, 97, 32,112, 97,114,115,101, +100, 32, 85, 82, 76, 32,102,114,111,109, 32,105,116,115, 32, 99,111,109,112,111, +110,101,110,116,115, 46, 10, 45, 45, 32, 67,111,109,112,111,110,101,110,116,115, + 32, 97,114,101, 32,112,114,111,116,101, 99,116,101,100, 32,105,102, 32, 97,110, +121, 32,114,101,115,101,114,118,101,100, 32,111,114, 32,117,110, 97,108,108,111, +119,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, 32, 97,114,101, 32,102, +111,117,110,100, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112, + 97,114,115,101,100, 58, 32,112, 97,114,115,101,100, 32, 85, 82, 76, 44, 32, 97, +115, 32,114,101,116,117,114,110,101,100, 32, 98,121, 32,112, 97,114,115,101, 10, + 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32, 97, 32,115,116, +114,105,110,103,105,110,103, 32,119,105,116,104, 32,116,104,101, 32, 99,111,114, +114,101,115,112,111,110,100,105,110,103, 32, 85, 82, 76, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111, +110, 32, 98,117,105,108,100, 40,112, 97,114,115,101,100, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,112,112, 97,116,104, 32, 61, 32,112, 97,114,115,101, 95, +112, 97,116,104, 40,112, 97,114,115,101,100, 46,112, 97,116,104, 32,111,114, 32, + 34, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32, + 98,117,105,108,100, 95,112, 97,116,104, 40,112,112, 97,116,104, 41, 10, 32, 32, + 32, 32,105,102, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116, +104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32, 34, 59, 34, + 32, 46, 46, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,101,110, +100, 10, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,113,117,101,114, +121, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32, + 34, 63, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,113,117,101,114,121, 32, +101,110,100, 10, 9,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, + 32, 61, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10, + 9,105,102, 32,112, 97,114,115,101,100, 46,104,111,115,116, 32,116,104,101,110, + 10, 9, 9, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, 97,114,115,101, +100, 46,104,111,115,116, 10, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112, +111,114,116, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61, + 32, 97,117,116,104,111,114,105,116,121, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, + 32,112, 97,114,115,101,100, 46,112,111,114,116, 32,101,110,100, 10, 9, 9,108, +111, 99, 97,108, 32,117,115,101,114,105,110,102,111, 32, 61, 32,112, 97,114,115, +101,100, 46,117,115,101,114,105,110,102,111, 10, 9, 9,105,102, 32,112, 97,114, +115,101,100, 46,117,115,101,114, 32,116,104,101,110, 10, 9, 9, 9,117,115,101, +114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114, 10, + 9, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114, +100, 32,116,104,101,110, 10, 9, 9, 9, 9,117,115,101,114,105,110,102,111, 32, + 61, 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, + 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114,100, 10, 9, 9, 9, +101,110,100, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,117,115,101,114,105, +110,102,111, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61, + 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 64, 34, 32, 46, 46, 32, + 97,117,116,104,111,114,105,116,121, 32,101,110,100, 10, 9,101,110,100, 10, 32, + 32, 32, 32,105,102, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101,110, + 32,117,114,108, 32, 61, 32, 34, 47, 47, 34, 32, 46, 46, 32, 97,117,116,104,111, +114,105,116,121, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32, 32, +105,102, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101, +110, 32,117,114,108, 32, 61, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109, +101, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10, + 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109,101, +110,116, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, + 32, 34, 35, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109, +101,110,116, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,117,114,108, 32, 61, + 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 37, +115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, +114,108, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32, 97, 98, +115,111,108,117,116,101, 32, 85, 82, 76, 32,102,114,111,109, 32, 97, 32, 98, 97, +115,101, 32, 97,110,100, 32, 97, 32,114,101,108, 97,116,105,118,101, 32, 85, 82, + 76, 32, 97, 99, 99,111,114,100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, + 51, 57, 54, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32, 98, 97, +115,101, 95,117,114,108, 10, 45, 45, 32, 32, 32,114,101,108, 97,116,105,118,101, + 95,117,114,108, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, + 32, 99,111,114,114,101,115,112,111,110,100,105,110,103, 32, 97, 98,115,111,108, +117,116,101, 32,117,114,108, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108, +117,116,101, 40, 98, 97,115,101, 95,117,114,108, 44, 32,114,101,108, 97,116,105, +118,101, 95,117,114,108, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46, +116,121,112,101, 40, 98, 97,115,101, 95,117,114,108, 41, 32, 61, 61, 32, 34,116, + 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, + 97,115,101, 95,112, 97,114,115,101,100, 32, 61, 32, 98, 97,115,101, 95,117,114, +108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 95,117,114,108, 32, 61, + 32, 98,117,105,108,100, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 41, 10, + 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115, +101, 95,112, 97,114,115,101,100, 32, 61, 32,112, 97,114,115,101, 40, 98, 97,115, +101, 95,117,114,108, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, + 32, 61, 32,112, 97,114,115,101, 40,114,101,108, 97,116,105,118,101, 95,117,114, +108, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 98, 97,115,101, 95,112, + 97,114,115,101,100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,114,101, +108, 97,116,105,118,101, 95,117,114,108, 10, 32, 32, 32, 32,101,108,115,101,105, +102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101, +100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 95,117, +114,108, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32,114,101,108, 97,116,105, +118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,117,114, +108, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114, +101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109, +101, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101, +109,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101, +108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116,104,111,114, +105,116,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116, +104,111,114,105,116,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, + 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, + 97,114,115,101,100, 46,112, 97,116,104, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, + 95,112, 97,114,115,101,100, 46,112, 97,116,104, 32, 61, 32, 98, 97,115,101, 95, +112, 97,114,115,101,100, 46,112, 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116, +105,118,101, 95,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,112, + 97,114, 97,109,115, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46, +112, 97,114, 97,109,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105, +118,101, 95,112, 97,114,115,101,100, 46,113,117,101,114,121, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, + 46,113,117,101,114,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, + 46,113,117,101,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,108,115,101, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114, +115,101,100, 46,112, 97,116,104, 32, 61, 32, 97, 98,115,111,108,117,116,101, 95, +112, 97,116,104, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,112, 97,116, +104, 32,111,114, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97, +114,115,101,100, 46,112, 97,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98,117,105,108,100, 40, +114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 41, 10, 32, 32, 32, + 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,114,101, 97,107,115, 32, 97, 32, +112, 97,116,104, 32,105,110,116,111, 32,105,116,115, 32,115,101,103,109,101,110, +116,115, 44, 32,117,110,101,115, 99, 97,112,105,110,103, 32,116,104,101, 32,115, +101,103,109,101,110,116,115, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, + 32, 32,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, + 32, 32, 32,115,101,103,109,101,110,116, 58, 32, 97, 32,116, 97, 98,108,101, 32, +119,105,116,104, 32,111,110,101, 32,101,110,116,114,121, 32,112,101,114, 32,115, +101,103,109,101,110,116, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 95, +112, 97,116,104, 40,112, 97,116,104, 41, 10, 9,108,111, 99, 97,108, 32,112, 97, +114,115,101,100, 32, 61, 32,123,125, 10, 9,112, 97,116,104, 32, 61, 32,112, 97, +116,104, 32,111,114, 32, 34, 34, 10, 9, 45, 45,112, 97,116,104, 32, 61, 32,115, +116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44, 32, 34, 37,115, + 34, 44, 32, 34, 34, 41, 10, 9,115,116,114,105,110,103, 46,103,115,117, 98, 40, +112, 97,116,104, 44, 32, 34, 40, 91, 94, 47, 93, 43, 41, 34, 44, 32,102,117,110, + 99,116,105,111,110, 32, 40,115, 41, 32,116, 97, 98,108,101, 46,105,110,115,101, +114,116, 40,112, 97,114,115,101,100, 44, 32,115, 41, 32,101,110,100, 41, 10, 9, +102,111,114, 32,105, 32, 61, 32, 49, 44, 32,116, 97, 98,108,101, 46,103,101,116, +110, 40,112, 97,114,115,101,100, 41, 32,100,111, 10, 9, 9,112, 97,114,115,101, +100, 91,105, 93, 32, 61, 32,117,110,101,115, 99, 97,112,101, 40,112, 97,114,115, +101,100, 91,105, 93, 41, 10, 9,101,110,100, 10, 9,105,102, 32,115,116,114,105, +110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 49, 44, 32, 49, 41, 32, 61, + 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, 97,114,115,101,100, 46,105,115, + 95, 97, 98,115,111,108,117,116,101, 32, 61, 32, 49, 32,101,110,100, 10, 9,105, +102, 32,115,116,114,105,110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 45, + 49, 44, 32, 45, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, + 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114,121, 32, 61, + 32, 49, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32,112, 97,114,115,101, +100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32,112, 97,116, +104, 32, 99,111,109,112,111,110,101,110,116, 32,102,114,111,109, 32,105,116,115, + 32,115,101,103,109,101,110,116,115, 44, 32,101,115, 99, 97,112,105,110,103, 32, +112,114,111,116,101, 99,116,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, + 46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112, 97,114,115, +101,100, 58, 32,112, 97,116,104, 32,115,101,103,109,101,110,116,115, 10, 45, 45, + 32, 32, 32,117,110,115, 97,102,101, 58, 32,105,102, 32,116,114,117,101, 44, 32, +115,101,103,109,101,110,116,115, 32, 97,114,101, 32,110,111,116, 32,112,114,111, +116,101, 99,116,101,100, 32, 98,101,102,111,114,101, 32,112, 97,116,104, 32,105, +115, 32, 98,117,105,108,116, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, + 45, 32, 32, 32,112, 97,116,104, 58, 32, 99,111,114,114,101,115,112,111,110,100, +105,110,103, 32,112, 97,116,104, 32,115,116,114,105,110,103,105,110,103, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, + 99,116,105,111,110, 32, 98,117,105,108,100, 95,112, 97,116,104, 40,112, 97,114, +115,101,100, 44, 32,117,110,115, 97,102,101, 41, 10, 9,108,111, 99, 97,108, 32, +112, 97,116,104, 32, 61, 32, 34, 34, 10, 9,108,111, 99, 97,108, 32,110, 32, 61, + 32,116, 97, 98,108,101, 46,103,101,116,110, 40,112, 97,114,115,101,100, 41, 10, + 9,105,102, 32,117,110,115, 97,102,101, 32,116,104,101,110, 10, 9, 9,102,111, +114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100,111, 10, 9, 9, 9,112, + 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,112, 97,114,115,101,100, + 91,105, 93, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, + 46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,110, 32, 62, + 32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97, +116,104, 32, 46, 46, 32,112, 97,114,115,101,100, 91,110, 93, 10, 9, 9, 9,105, +102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114, +121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, + 46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,108,115, +101, 10, 9, 9,102,111,114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100, +111, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32, +112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,112, 97,114,115, +101,100, 91,105, 93, 41, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116, +104, 32, 46, 46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32, +110, 32, 62, 32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61, + 32,112, 97,116,104, 32, 46, 46, 32,112,114,111,116,101, 99,116, 95,115,101,103, +109,101,110,116, 40,112, 97,114,115,101,100, 91,110, 93, 41, 10, 9, 9, 9,105, +102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114, +121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, + 46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,110,100, + 10, 9,105,102, 32,112, 97,114,115,101,100, 46,105,115, 95, 97, 98,115,111,108, +117,116,101, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32, 34, 47, 34, 32, + 46, 46, 32,112, 97,116,104, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32, +112, 97,116,104, 10,101,110,100, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/usocket.c b/Build/source/texk/web2c/luatexdir/luasocket/src/usocket.c new file mode 100644 index 00000000000..40d7596227c --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/usocket.c @@ -0,0 +1,377 @@ +/*=========================================================================*\ +* Socket compatibilization module for Unix +* LuaSocket toolkit +* +* The code is now interrupt-safe. +* The penalty of calling select to avoid busy-wait is only paid when +* the I/O call fail in the first place. +* +* RCS ID: $Id: usocket.c,v 1.38 2007/10/13 23:55:20 diego Exp $ +\*=========================================================================*/ +#include +#include + +#include "socket.h" + +#if defined(__sun__) +#define HSTRERROR(A) "unknown host error" +#else +#define HSTRERROR(A) hstrerror(A) +#endif + + +/*-------------------------------------------------------------------------*\ +* Wait for readable/writable/connected socket with timeout +\*-------------------------------------------------------------------------*/ +#ifdef SOCKET_POLL +#include + +#define WAITFD_R POLLIN +#define WAITFD_W POLLOUT +#define WAITFD_C (POLLIN|POLLOUT) +int socket_waitfd(p_socket ps, int sw, p_timeout tm) { + int ret; + struct pollfd pfd; + pfd.fd = *ps; + pfd.events = sw; + pfd.revents = 0; + if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ + do { + int t = (int)(timeout_getretry(tm)*1e3); + ret = poll(&pfd, 1, t >= 0? t: -1); + } while (ret == -1 && errno == EINTR); + if (ret == -1) return errno; + if (ret == 0) return IO_TIMEOUT; + if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED; + return IO_DONE; +} +#else + +#define WAITFD_R 1 +#define WAITFD_W 2 +#define WAITFD_C (WAITFD_R|WAITFD_W) + +int socket_waitfd(p_socket ps, int sw, p_timeout tm) { + int ret; + fd_set rfds, wfds, *rp, *wp; + struct timeval tv, *tp; + double t; + if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ + do { + /* must set bits within loop, because select may have modifed them */ + rp = wp = NULL; + if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; } + if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } + t = timeout_getretry(tm); + tp = NULL; + if (t >= 0.0) { + tv.tv_sec = (int)t; + tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6); + tp = &tv; + } + ret = select(*ps+1, rp, wp, NULL, tp); + } while (ret == -1 && errno == EINTR); + if (ret == -1) return errno; + if (ret == 0) return IO_TIMEOUT; + if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED; + return IO_DONE; +} +#endif + + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int socket_open(void) { + /* instals a handler to ignore sigpipe or it will crash us */ + signal(SIGPIPE, SIG_IGN); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Close module +\*-------------------------------------------------------------------------*/ +int socket_close(void) { + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Close and inutilize socket +\*-------------------------------------------------------------------------*/ +void socket_destroy(p_socket ps) { + if (*ps != SOCKET_INVALID) { + socket_setblocking(ps); + close(*ps); + *ps = SOCKET_INVALID; + } +} + +/*-------------------------------------------------------------------------*\ +* Select with timeout control +\*-------------------------------------------------------------------------*/ +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, + p_timeout tm) { + int ret; + do { + struct timeval tv; + double t = timeout_getretry(tm); + tv.tv_sec = (int) t; + tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); + /* timeout = 0 means no wait */ + ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL); + } while (ret < 0 && errno == EINTR); + return ret; +} + +/*-------------------------------------------------------------------------*\ +* Creates and sets up a socket +\*-------------------------------------------------------------------------*/ +int socket_create(p_socket ps, int domain, int type, int protocol) { + *ps = socket(domain, type, protocol); + if (*ps != SOCKET_INVALID) return IO_DONE; + else return errno; +} + +/*-------------------------------------------------------------------------*\ +* Binds or returns error message +\*-------------------------------------------------------------------------*/ +int socket_bind(p_socket ps, SA *addr, socklen_t len) { + int err = IO_DONE; + socket_setblocking(ps); + if (bind(*ps, addr, len) < 0) err = errno; + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +int socket_listen(p_socket ps, int backlog) { + int err = IO_DONE; + socket_setblocking(ps); + if (listen(*ps, backlog)) err = errno; + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +void socket_shutdown(p_socket ps, int how) { + socket_setblocking(ps); + shutdown(*ps, how); + socket_setnonblocking(ps); +} + +/*-------------------------------------------------------------------------*\ +* Connects or returns error message +\*-------------------------------------------------------------------------*/ +int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { + int err; + /* avoid calling on closed sockets */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* call connect until done or failed without being interrupted */ + do if (connect(*ps, addr, len) == 0) return IO_DONE; + while ((err = errno) == EINTR); + /* if connection failed immediately, return error code */ + if (err != EINPROGRESS && err != EAGAIN) return err; + /* zero timeout case optimization */ + if (timeout_iszero(tm)) return IO_TIMEOUT; + /* wait until we have the result of the connection attempt or timeout */ + err = socket_waitfd(ps, WAITFD_C, tm); + if (err == IO_CLOSED) { + if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; + else return errno; + } else return err; +} + +/*-------------------------------------------------------------------------*\ +* Accept with timeout +\*-------------------------------------------------------------------------*/ +int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { + SA daddr; + socklen_t dlen = sizeof(daddr); + if (*ps == SOCKET_INVALID) return IO_CLOSED; + if (!addr) addr = &daddr; + if (!len) len = &dlen; + for ( ;; ) { + int err; + if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; + err = errno; + if (err == EINTR) continue; + if (err != EAGAIN && err != ECONNABORTED) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Send with timeout +\*-------------------------------------------------------------------------*/ +int socket_send(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm) +{ + int err; + *sent = 0; + /* avoid making system calls on closed sockets */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* loop until we send something or we give up on error */ + for ( ;; ) { + long put = (long) send(*ps, data, count, 0); + /* if we sent anything, we are done */ + if (put > 0) { + *sent = put; + return IO_DONE; + } + err = errno; + /* send can't really return 0, but EPIPE means the connection was + closed */ + if (put == 0 || err == EPIPE) return IO_CLOSED; + /* we call was interrupted, just try again */ + if (err == EINTR) continue; + /* if failed fatal reason, report error */ + if (err != EAGAIN) return err; + /* wait until we can send something or we timeout */ + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Sendto with timeout +\*-------------------------------------------------------------------------*/ +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, + SA *addr, socklen_t len, p_timeout tm) +{ + int err; + *sent = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + long put = (long) sendto(*ps, data, count, 0, addr, len); + if (put > 0) { + *sent = put; + return IO_DONE; + } + err = errno; + if (put == 0 || err == EPIPE) return IO_CLOSED; + if (err == EINTR) continue; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Receive with timeout +\*-------------------------------------------------------------------------*/ +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + long taken = (long) recv(*ps, data, count, 0); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + err = errno; + if (taken == 0) return IO_CLOSED; + if (err == EINTR) continue; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Recvfrom with timeout +\*-------------------------------------------------------------------------*/ +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, + SA *addr, socklen_t *len, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + long taken = (long) recvfrom(*ps, data, count, 0, addr, len); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + err = errno; + if (taken == 0) return IO_CLOSED; + if (err == EINTR) continue; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Put socket into blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setblocking(p_socket ps) { + int flags = fcntl(*ps, F_GETFL, 0); + flags &= (~(O_NONBLOCK)); + fcntl(*ps, F_SETFL, flags); +} + +/*-------------------------------------------------------------------------*\ +* Put socket into non-blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setnonblocking(p_socket ps) { + int flags = fcntl(*ps, F_GETFL, 0); + flags |= O_NONBLOCK; + fcntl(*ps, F_SETFL, flags); +} + +/*-------------------------------------------------------------------------*\ +* DNS helpers +\*-------------------------------------------------------------------------*/ +int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { + *hp = gethostbyaddr(addr, len, AF_INET); + if (*hp) return IO_DONE; + else if (h_errno) return h_errno; + else if (errno) return errno; + else return IO_UNKNOWN; +} + +int socket_gethostbyname(const char *addr, struct hostent **hp) { + *hp = gethostbyname(addr); + if (*hp) return IO_DONE; + else if (h_errno) return h_errno; + else if (errno) return errno; + else return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Error translation functions +* Make sure important error messages are standard +\*-------------------------------------------------------------------------*/ +const char *socket_hoststrerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case HOST_NOT_FOUND: return "host not found"; + default: return HSTRERROR(err); + } +} + +const char *socket_strerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case EADDRINUSE: return "address already in use"; + case EISCONN: return "already connected"; + case EACCES: return "permission denied"; + case ECONNREFUSED: return "connection refused"; + case ECONNABORTED: return "closed"; + case ECONNRESET: return "closed"; + case ETIMEDOUT: return "timeout"; + default: return strerror(errno); + } +} + +const char *socket_ioerror(p_socket ps, int err) { + (void) ps; + return socket_strerror(err); +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/usocket.h b/Build/source/texk/web2c/luatexdir/luasocket/src/usocket.h new file mode 100644 index 00000000000..f2a89aa0d21 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/usocket.h @@ -0,0 +1,40 @@ +#ifndef USOCKET_H +#define USOCKET_H +/*=========================================================================*\ +* Socket compatibilization module for Unix +* LuaSocket toolkit +* +* RCS ID: $Id: usocket.h,v 1.7 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +/*=========================================================================*\ +* BSD include files +\*=========================================================================*/ +/* error codes */ +#include +/* close function */ +#include +/* fnctnl function and associated constants */ +#include +/* struct sockaddr */ +#include +/* socket function */ +#include +/* struct timeval */ +#include +/* gethostbyname and gethostbyaddr functions */ +#include +/* sigpipe handling */ +#include +/* IP stuff*/ +#include +#include +/* TCP options (nagle algorithm disable) */ +#include + +typedef int t_socket; +typedef t_socket *p_socket; + +#define SOCKET_INVALID (-1) + +#endif /* USOCKET_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.c b/Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.c new file mode 100644 index 00000000000..6022565188a --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.c @@ -0,0 +1,401 @@ +/*=========================================================================*\ +* Socket compatibilization module for Win32 +* LuaSocket toolkit +* +* The penalty of calling select to avoid busy-wait is only paid when +* the I/O call fail in the first place. +* +* RCS ID: $Id: wsocket.c,v 1.36 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include + +#include "socket.h" + +/* WinSock doesn't have a strerror... */ +static const char *wstrerror(int err); + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int socket_open(void) { + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(2, 0); + int err = WSAStartup(wVersionRequested, &wsaData ); + if (err != 0) return 0; + if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) && + (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) { + WSACleanup(); + return 0; + } + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Close module +\*-------------------------------------------------------------------------*/ +int socket_close(void) { + WSACleanup(); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Wait for readable/writable/connected socket with timeout +\*-------------------------------------------------------------------------*/ +#define WAITFD_R 1 +#define WAITFD_W 2 +#define WAITFD_E 4 +#define WAITFD_C (WAITFD_E|WAITFD_W) + +int socket_waitfd(p_socket ps, int sw, p_timeout tm) { + int ret; + fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; + struct timeval tv, *tp = NULL; + double t; + if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ + if (sw & WAITFD_R) { + FD_ZERO(&rfds); + FD_SET(*ps, &rfds); + rp = &rfds; + } + if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } + if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; } + if ((t = timeout_get(tm)) >= 0.0) { + tv.tv_sec = (int) t; + tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6); + tp = &tv; + } + ret = select(0, rp, wp, ep, tp); + if (ret == -1) return WSAGetLastError(); + if (ret == 0) return IO_TIMEOUT; + if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED; + return IO_DONE; +} + +/*-------------------------------------------------------------------------*\ +* Select with int timeout in ms +\*-------------------------------------------------------------------------*/ +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, + p_timeout tm) { + struct timeval tv; + double t = timeout_get(tm); + tv.tv_sec = (int) t; + tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); + if (n <= 0) { + Sleep((DWORD) (1000*t)); + return 0; + } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL); +} + +/*-------------------------------------------------------------------------*\ +* Close and inutilize socket +\*-------------------------------------------------------------------------*/ +void socket_destroy(p_socket ps) { + if (*ps != SOCKET_INVALID) { + socket_setblocking(ps); /* close can take a long time on WIN32 */ + closesocket(*ps); + *ps = SOCKET_INVALID; + } +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +void socket_shutdown(p_socket ps, int how) { + socket_setblocking(ps); + shutdown(*ps, how); + socket_setnonblocking(ps); +} + +/*-------------------------------------------------------------------------*\ +* Creates and sets up a socket +\*-------------------------------------------------------------------------*/ +int socket_create(p_socket ps, int domain, int type, int protocol) { + *ps = socket(domain, type, protocol); + if (*ps != SOCKET_INVALID) return IO_DONE; + else return WSAGetLastError(); +} + +/*-------------------------------------------------------------------------*\ +* Connects or returns error message +\*-------------------------------------------------------------------------*/ +int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { + int err; + /* don't call on closed socket */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* ask system to connect */ + if (connect(*ps, addr, len) == 0) return IO_DONE; + /* make sure the system is trying to connect */ + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err; + /* zero timeout case optimization */ + if (timeout_iszero(tm)) return IO_TIMEOUT; + /* we wait until something happens */ + err = socket_waitfd(ps, WAITFD_C, tm); + if (err == IO_CLOSED) { + int len = sizeof(err); + /* give windows time to set the error (yes, disgusting) */ + Sleep(10); + /* find out why we failed */ + getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); + /* we KNOW there was an error. if 'why' is 0, we will return + * "unknown error", but it's not really our fault */ + return err > 0? err: IO_UNKNOWN; + } else return err; + +} + +/*-------------------------------------------------------------------------*\ +* Binds or returns error message +\*-------------------------------------------------------------------------*/ +int socket_bind(p_socket ps, SA *addr, socklen_t len) { + int err = IO_DONE; + socket_setblocking(ps); + if (bind(*ps, addr, len) < 0) err = WSAGetLastError(); + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +int socket_listen(p_socket ps, int backlog) { + int err = IO_DONE; + socket_setblocking(ps); + if (listen(*ps, backlog) < 0) err = WSAGetLastError(); + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* Accept with timeout +\*-------------------------------------------------------------------------*/ +int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, + p_timeout tm) { + SA daddr; + socklen_t dlen = sizeof(daddr); + if (*ps == SOCKET_INVALID) return IO_CLOSED; + if (!addr) addr = &daddr; + if (!len) len = &dlen; + for ( ;; ) { + int err; + /* try to get client socket */ + if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; + /* find out why we failed */ + err = WSAGetLastError(); + /* if we failed because there was no connectoin, keep trying */ + if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err; + /* call select to avoid busy wait */ + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Send with timeout +* On windows, if you try to send 10MB, the OS will buffer EVERYTHING +* this can take an awful lot of time and we will end up blocked. +* Therefore, whoever calls this function should not pass a huge buffer. +\*-------------------------------------------------------------------------*/ +int socket_send(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm) +{ + int err; + *sent = 0; + /* avoid making system calls on closed sockets */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* loop until we send something or we give up on error */ + for ( ;; ) { + /* try to send something */ + int put = send(*ps, data, (int) count, 0); + /* if we sent something, we are done */ + if (put > 0) { + *sent = put; + return IO_DONE; + } + /* deal with failure */ + err = WSAGetLastError(); + /* we can only proceed if there was no serious error */ + if (err != WSAEWOULDBLOCK) return err; + /* avoid busy wait */ + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Sendto with timeout +\*-------------------------------------------------------------------------*/ +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, + SA *addr, socklen_t len, p_timeout tm) +{ + int err; + *sent = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + int put = sendto(*ps, data, (int) count, 0, addr, len); + if (put > 0) { + *sent = put; + return IO_DONE; + } + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) return err; + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Receive with timeout +\*-------------------------------------------------------------------------*/ +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + int taken = recv(*ps, data, (int) count, 0); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + if (taken == 0) return IO_CLOSED; + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Recvfrom with timeout +\*-------------------------------------------------------------------------*/ +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, + SA *addr, socklen_t *len, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + int taken = recvfrom(*ps, data, (int) count, 0, addr, len); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + if (taken == 0) return IO_CLOSED; + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Put socket into blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setblocking(p_socket ps) { + u_long argp = 0; + ioctlsocket(*ps, FIONBIO, &argp); +} + +/*-------------------------------------------------------------------------*\ +* Put socket into non-blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setnonblocking(p_socket ps) { + u_long argp = 1; + ioctlsocket(*ps, FIONBIO, &argp); +} + +/*-------------------------------------------------------------------------*\ +* DNS helpers +\*-------------------------------------------------------------------------*/ +int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { + *hp = gethostbyaddr(addr, len, AF_INET); + if (*hp) return IO_DONE; + else return WSAGetLastError(); +} + +int socket_gethostbyname(const char *addr, struct hostent **hp) { + *hp = gethostbyname(addr); + if (*hp) return IO_DONE; + else return WSAGetLastError(); +} + +/*-------------------------------------------------------------------------*\ +* Error translation functions +\*-------------------------------------------------------------------------*/ +const char *socket_hoststrerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case WSAHOST_NOT_FOUND: return "host not found"; + default: return wstrerror(err); + } +} + +const char *socket_strerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case WSAEADDRINUSE: return "address already in use"; + case WSAECONNREFUSED: return "connection refused"; + case WSAEISCONN: return "already connected"; + case WSAEACCES: return "permission denied"; + case WSAECONNABORTED: return "closed"; + case WSAECONNRESET: return "closed"; + case WSAETIMEDOUT: return "timeout"; + default: return wstrerror(err); + } +} + +const char *socket_ioerror(p_socket ps, int err) { + (void) ps; + return socket_strerror(err); +} + +static const char *wstrerror(int err) { + switch (err) { + case WSAEINTR: return "Interrupted function call"; + case WSAEACCES: return "Permission denied"; + case WSAEFAULT: return "Bad address"; + case WSAEINVAL: return "Invalid argument"; + case WSAEMFILE: return "Too many open files"; + case WSAEWOULDBLOCK: return "Resource temporarily unavailable"; + case WSAEINPROGRESS: return "Operation now in progress"; + case WSAEALREADY: return "Operation already in progress"; + case WSAENOTSOCK: return "Socket operation on nonsocket"; + case WSAEDESTADDRREQ: return "Destination address required"; + case WSAEMSGSIZE: return "Message too long"; + case WSAEPROTOTYPE: return "Protocol wrong type for socket"; + case WSAENOPROTOOPT: return "Bad protocol option"; + case WSAEPROTONOSUPPORT: return "Protocol not supported"; + case WSAESOCKTNOSUPPORT: return "Socket type not supported"; + case WSAEOPNOTSUPP: return "Operation not supported"; + case WSAEPFNOSUPPORT: return "Protocol family not supported"; + case WSAEAFNOSUPPORT: + return "Address family not supported by protocol family"; + case WSAEADDRINUSE: return "Address already in use"; + case WSAEADDRNOTAVAIL: return "Cannot assign requested address"; + case WSAENETDOWN: return "Network is down"; + case WSAENETUNREACH: return "Network is unreachable"; + case WSAENETRESET: return "Network dropped connection on reset"; + case WSAECONNABORTED: return "Software caused connection abort"; + case WSAECONNRESET: return "Connection reset by peer"; + case WSAENOBUFS: return "No buffer space available"; + case WSAEISCONN: return "Socket is already connected"; + case WSAENOTCONN: return "Socket is not connected"; + case WSAESHUTDOWN: return "Cannot send after socket shutdown"; + case WSAETIMEDOUT: return "Connection timed out"; + case WSAECONNREFUSED: return "Connection refused"; + case WSAEHOSTDOWN: return "Host is down"; + case WSAEHOSTUNREACH: return "No route to host"; + case WSAEPROCLIM: return "Too many processes"; + case WSASYSNOTREADY: return "Network subsystem is unavailable"; + case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range"; + case WSANOTINITIALISED: + return "Successful WSAStartup not yet performed"; + case WSAEDISCON: return "Graceful shutdown in progress"; + case WSAHOST_NOT_FOUND: return "Host not found"; + case WSATRY_AGAIN: return "Nonauthoritative host not found"; + case WSANO_RECOVERY: return "Nonrecoverable name lookup error"; + case WSANO_DATA: return "Valid name, no data record of requested type"; + default: return "Unknown error"; + } +} diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.h b/Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.h new file mode 100644 index 00000000000..b536683685c --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/wsocket.h @@ -0,0 +1,21 @@ +#ifndef WSOCKET_H +#define WSOCKET_H +/*=========================================================================*\ +* Socket compatibilization module for Win32 +* LuaSocket toolkit +* +* RCS ID: $Id: wsocket.h,v 1.4 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +/*=========================================================================*\ +* WinSock include files +\*=========================================================================*/ +#include + +typedef int socklen_t; +typedef SOCKET t_socket; +typedef t_socket *p_socket; + +#define SOCKET_INVALID (INVALID_SOCKET) + +#endif /* WSOCKET_H */ diff --git a/Build/source/texk/web2c/luatexdir/luasocket/test/README b/Build/source/texk/web2c/luatexdir/luasocket/test/README new file mode 100644 index 00000000000..180fa277ca7 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/test/README @@ -0,0 +1,12 @@ +This provides the automated test scripts used to make sure the library +is working properly. + +The files provided are: + + testsrvr.lua -- test server + testclnt.lua -- test client + +To run these tests, just run lua on the server and then on the client. + +Good luck, +Diego. diff --git a/Build/source/texk/web2c/luatexdir/luasocket/test/testclnt.lua b/Build/source/texk/web2c/luatexdir/luasocket/test/testclnt.lua new file mode 100644 index 00000000000..a7ca1ba6768 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/test/testclnt.lua @@ -0,0 +1,713 @@ +local socket = require"socket" + +host = host or "localhost" +port = port or "8383" + +function pass(...) + local s = string.format(unpack(arg)) + io.stderr:write(s, "\n") +end + +function fail(...) + local s = string.format(unpack(arg)) + io.stderr:write("ERROR: ", s, "!\n") +socket.sleep(3) + os.exit() +end + +function warn(...) + local s = string.format(unpack(arg)) + io.stderr:write("WARNING: ", s, "\n") +end + +function remote(...) + local s = string.format(unpack(arg)) + s = string.gsub(s, "\n", ";") + s = string.gsub(s, "%s+", " ") + s = string.gsub(s, "^%s*", "") + control:send(s .. "\n") + control:receive() +end + +function test(test) + io.stderr:write("----------------------------------------------\n", + "testing: ", test, "\n", + "----------------------------------------------\n") +end + +function check_timeout(tm, sl, elapsed, err, opp, mode, alldone) + if tm < sl then + if opp == "send" then + if not err then warn("must be buffered") + elseif err == "timeout" then pass("proper timeout") + else fail("unexpected error '%s'", err) end + else + if err ~= "timeout" then fail("should have timed out") + else pass("proper timeout") end + end + else + if mode == "total" then + if elapsed > tm then + if err ~= "timeout" then fail("should have timed out") + else pass("proper timeout") end + elseif elapsed < tm then + if err then fail(err) + else pass("ok") end + else + if alldone then + if err then fail("unexpected error '%s'", err) + else pass("ok") end + else + if err ~= "timeout" then fail(err) + else pass("proper timeoutk") end + end + end + else + if err then fail(err) + else pass("ok") end + end + end +end + +if not socket._DEBUG then + fail("Please define LUASOCKET_DEBUG and recompile LuaSocket") +end + +io.stderr:write("----------------------------------------------\n", +"LuaSocket Test Procedures\n", +"----------------------------------------------\n") + +start = socket.gettime() + +function reconnect() + io.stderr:write("attempting data connection... ") + if data then data:close() end + remote [[ + if data then data:close() data = nil end + data = server:accept() + data:setoption("tcp-nodelay", true) + ]] + data, err = socket.connect(host, port) + if not data then fail(err) + else pass("connected!") end + data:setoption("tcp-nodelay", true) +end + +pass("attempting control connection...") +control, err = socket.connect(host, port) +if err then fail(err) +else pass("connected!") end +control:setoption("tcp-nodelay", true) + +------------------------------------------------------------------------ +function test_methods(sock, methods) + for _, v in pairs(methods) do + if type(sock[v]) ~= "function" then + fail(sock.class .. " method '" .. v .. "' not registered") + end + end + pass(sock.class .. " methods are ok") +end + +------------------------------------------------------------------------ +function test_mixed(len) + reconnect() + local inter = math.ceil(len/4) + local p1 = "unix " .. string.rep("x", inter) .. "line\n" + local p2 = "dos " .. string.rep("y", inter) .. "line\r\n" + local p3 = "raw " .. string.rep("z", inter) .. "bytes" + local p4 = "end" .. string.rep("w", inter) .. "bytes" + local bp1, bp2, bp3, bp4 +remote (string.format("str = data:receive(%d)", + string.len(p1)+string.len(p2)+string.len(p3)+string.len(p4))) + sent, err = data:send(p1..p2..p3..p4) + if err then fail(err) end +remote "data:send(str); data:close()" + bp1, err = data:receive() + if err then fail(err) end + bp2, err = data:receive() + if err then fail(err) end + bp3, err = data:receive(string.len(p3)) + if err then fail(err) end + bp4, err = data:receive("*a") + if err then fail(err) end + if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 and bp4 == p4 then + pass("patterns match") + else fail("patterns don't match") end +end + +------------------------------------------------------------------------ +function test_asciiline(len) + reconnect() + local str, str10, back, err + str = string.rep("x", math.mod(len, 10)) + str10 = string.rep("aZb.c#dAe?", math.floor(len/10)) + str = str .. str10 +remote "str = data:receive()" + sent, err = data:send(str.."\n") + if err then fail(err) end +remote "data:send(str ..'\\n')" + back, err = data:receive() + if err then fail(err) end + if back == str then pass("lines match") + else fail("lines don't match") end +end + +------------------------------------------------------------------------ +function test_rawline(len) + reconnect() + local str, str10, back, err + str = string.rep(string.char(47), math.mod(len, 10)) + str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100), + math.floor(len/10)) + str = str .. str10 +remote "str = data:receive()" + sent, err = data:send(str.."\n") + if err then fail(err) end +remote "data:send(str..'\\n')" + back, err = data:receive() + if err then fail(err) end + if back == str then pass("lines match") + else fail("lines don't match") end +end + +------------------------------------------------------------------------ +function test_raw(len) + reconnect() + local half = math.floor(len/2) + local s1, s2, back, err + s1 = string.rep("x", half) + s2 = string.rep("y", len-half) +remote (string.format("str = data:receive(%d)", len)) + sent, err = data:send(s1) + if err then fail(err) end + sent, err = data:send(s2) + if err then fail(err) end +remote "data:send(str)" + back, err = data:receive(len) + if err then fail(err) end + if back == s1..s2 then pass("blocks match") + else fail("blocks don't match") end +end + +------------------------------------------------------------------------ +function test_totaltimeoutreceive(len, tm, sl) + reconnect() + local str, err, partial + pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = string.rep('a', %d) + data:send(str) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + data:send(str) + ]], 2*tm, len, sl, sl)) + data:settimeout(tm, "total") +local t = socket.gettime() + str, err, partial, elapsed = data:receive(2*len) + check_timeout(tm, sl, elapsed, err, "receive", "total", + string.len(str or partial) == 2*len) +end + +------------------------------------------------------------------------ +function test_totaltimeoutsend(len, tm, sl) + reconnect() + local str, err, total + pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = data:receive(%d) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + str = data:receive(%d) + ]], 2*tm, len, sl, sl, len)) + data:settimeout(tm, "total") + str = string.rep("a", 2*len) + total, err, partial, elapsed = data:send(str) + check_timeout(tm, sl, elapsed, err, "send", "total", + total == 2*len) +end + +------------------------------------------------------------------------ +function test_blockingtimeoutreceive(len, tm, sl) + reconnect() + local str, err, partial + pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = string.rep('a', %d) + data:send(str) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + data:send(str) + ]], 2*tm, len, sl, sl)) + data:settimeout(tm) + str, err, partial, elapsed = data:receive(2*len) + check_timeout(tm, sl, elapsed, err, "receive", "blocking", + string.len(str or partial) == 2*len) +end + +------------------------------------------------------------------------ +function test_blockingtimeoutsend(len, tm, sl) + reconnect() + local str, err, total + pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = data:receive(%d) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + str = data:receive(%d) + ]], 2*tm, len, sl, sl, len)) + data:settimeout(tm) + str = string.rep("a", 2*len) + total, err, partial, elapsed = data:send(str) + check_timeout(tm, sl, elapsed, err, "send", "blocking", + total == 2*len) +end + +------------------------------------------------------------------------ +function empty_connect() + reconnect() + if data then data:close() data = nil end + remote [[ + if data then data:close() data = nil end + data = server:accept() + ]] + data, err = socket.connect("", port) + if not data then + pass("ok") + data = socket.connect(host, port) + else + pass("gethostbyname returns localhost on empty string...") + end +end + +------------------------------------------------------------------------ +function isclosed(c) + return c:getfd() == -1 or c:getfd() == (2^32-1) +end + +function active_close() + reconnect() + if isclosed(data) then fail("should not be closed") end + data:close() + if not isclosed(data) then fail("should be closed") end + data = nil + local udp = socket.udp() + if isclosed(udp) then fail("should not be closed") end + udp:close() + if not isclosed(udp) then fail("should be closed") end + pass("ok") +end + +------------------------------------------------------------------------ +function test_closed() + local back, partial, err + local str = 'little string' + reconnect() + pass("trying read detection") + remote (string.format ([[ + data:send('%s') + data:close() + data = nil + ]], str)) + -- try to get a line + back, err, partial = data:receive() + if not err then fail("should have gotten 'closed'.") + elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.") + elseif str ~= partial then fail("didn't receive partial result.") + else pass("graceful 'closed' received") end + reconnect() + pass("trying write detection") + remote [[ + data:close() + data = nil + ]] + total, err, partial = data:send(string.rep("ugauga", 100000)) + if not err then + pass("failed: output buffer is at least %d bytes long!", total) + elseif err ~= "closed" then + fail("got '"..err.."' instead of 'closed'.") + else + pass("graceful 'closed' received after %d bytes were sent", partial) + end +end + +------------------------------------------------------------------------ +function test_selectbugs() + local r, s, e = socket.select(nil, nil, 0.1) + assert(type(r) == "table" and type(s) == "table" and + (e == "timeout" or e == "error")) + pass("both nil: ok") + local udp = socket.udp() + udp:close() + r, s, e = socket.select({ udp }, { udp }, 0.1) + assert(type(r) == "table" and type(s) == "table" and + (e == "timeout" or e == "error")) + pass("closed sockets: ok") + e = pcall(socket.select, "wrong", 1, 0.1) + assert(e == false) + e = pcall(socket.select, {}, 1, 0.1) + assert(e == false) + pass("invalid input: ok") +end + +------------------------------------------------------------------------ +function accept_timeout() + io.stderr:write("accept with timeout (if it hangs, it failed): ") + local s, e = socket.bind("*", 0, 0) + assert(s, e) + local t = socket.gettime() + s:settimeout(1) + local c, e = s:accept() + assert(not c, "should not accept") + assert(e == "timeout", string.format("wrong error message (%s)", e)) + t = socket.gettime() - t + assert(t < 2, string.format("took to long to give up (%gs)", t)) + s:close() + pass("good") +end + +------------------------------------------------------------------------ +function connect_timeout() + io.stderr:write("connect with timeout (if it hangs, it failed!): ") + local t = socket.gettime() + local c, e = socket.tcp() + assert(c, e) + c:settimeout(0.1) + local t = socket.gettime() + local r, e = c:connect("10.0.0.1", 81) +print(r, e) + assert(not r, "should not connect") + assert(socket.gettime() - t < 2, "took too long to give up.") + c:close() + print("ok") +end + +------------------------------------------------------------------------ +function accept_errors() + io.stderr:write("not listening: ") + local d, e = socket.bind("*", 0) + assert(d, e); + local c, e = socket.tcp(); + assert(c, e); + d:setfd(c:getfd()) + d:settimeout(2) + local r, e = d:accept() + assert(not r and e) + print("ok: ", e) + io.stderr:write("not supported: ") + local c, e = socket.udp() + assert(c, e); + d:setfd(c:getfd()) + local r, e = d:accept() + assert(not r and e) + print("ok: ", e) +end + +------------------------------------------------------------------------ +function connect_errors() + io.stderr:write("connection refused: ") + local c, e = socket.connect("localhost", 1); + assert(not c and e) + print("ok: ", e) + io.stderr:write("host not found: ") + local c, e = socket.connect("host.is.invalid", 1); + assert(not c and e, e) + print("ok: ", e) +end + +------------------------------------------------------------------------ +function rebind_test() + local c = socket.bind("localhost", 0) + local i, p = c:getsockname() + local s, e = socket.tcp() + assert(s, e) + s:setoption("reuseaddr", false) + r, e = s:bind("localhost", p) + assert(not r, "managed to rebind!") + assert(e) + print("ok: ", e) +end + +------------------------------------------------------------------------ +function getstats_test() + reconnect() + local t = 0 + for i = 1, 25 do + local c = math.random(1, 100) + remote (string.format ([[ + str = data:receive(%d) + data:send(str) + ]], c)) + data:send(string.rep("a", c)) + data:receive(c) + t = t + c + local r, s, a = data:getstats() + assert(r == t, "received count failed" .. tostring(r) + .. "/" .. tostring(t)) + assert(s == t, "sent count failed" .. tostring(s) + .. "/" .. tostring(t)) + end + print("ok") +end + + +------------------------------------------------------------------------ +function test_nonblocking(size) + reconnect() +print("Testing " .. 2*size .. " bytes") +remote(string.format([[ + data:send(string.rep("a", %d)) + socket.sleep(0.5) + data:send(string.rep("b", %d) .. "\n") +]], size, size)) + local err = "timeout" + local part = "" + local str + data:settimeout(0) + while 1 do + str, err, part = data:receive("*l", part) + if err ~= "timeout" then break end + end + assert(str == (string.rep("a", size) .. string.rep("b", size))) + reconnect() +remote(string.format([[ + str = data:receive(%d) + socket.sleep(0.5) + str = data:receive(2*%d, str) + data:send(str) +]], size, size)) + data:settimeout(0) + local start = 0 + while 1 do + ret, err, start = data:send(str, start+1) + if err ~= "timeout" then break end + end + data:send("\n") + data:settimeout(-1) + local back = data:receive(2*size) + assert(back == str, "'" .. back .. "' vs '" .. str .. "'") + print("ok") +end + +------------------------------------------------------------------------ +function test_readafterclose() + local back, partial, err + local str = 'little string' + reconnect() + pass("trying repeated '*a' pattern") + remote (string.format ([[ + data:send('%s') + data:close() + data = nil + ]], str)) + back, err, partial = data:receive("*a") + assert(back == str, "unexpected data read") + back, err, partial = data:receive("*a") + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before '*a'") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive("*a") + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before '*l'") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive() + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before raw 1") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive(1) + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before raw 0") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive(0) + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") +end + +test("method registration") +test_methods(socket.tcp(), { + "accept", + "bind", + "close", + "connect", + "dirty", + "getfd", + "getpeername", + "getsockname", + "getstats", + "setstats", + "listen", + "receive", + "send", + "setfd", + "setoption", + "setpeername", + "setsockname", + "settimeout", + "shutdown", +}) + +test_methods(socket.udp(), { + "close", + "getpeername", + "dirty", + "getfd", + "getpeername", + "getsockname", + "receive", + "receivefrom", + "send", + "sendto", + "setfd", + "setoption", + "setpeername", + "setsockname", + "settimeout" +}) + +test("testing read after close") +test_readafterclose() + +test("select function") +test_selectbugs() + +test("connect function") +connect_timeout() +empty_connect() +connect_errors() + +test("rebinding: ") +rebind_test() + +test("active close: ") +active_close() + +test("closed connection detection: ") +test_closed() + +test("accept function: ") +accept_timeout() +accept_errors() + +test("getstats test") +getstats_test() + +test("character line") +test_asciiline(1) +test_asciiline(17) +test_asciiline(200) +test_asciiline(4091) +test_asciiline(80199) +test_asciiline(8000000) +test_asciiline(80199) +test_asciiline(4091) +test_asciiline(200) +test_asciiline(17) +test_asciiline(1) + +test("mixed patterns") +test_mixed(1) +test_mixed(17) +test_mixed(200) +test_mixed(4091) +test_mixed(801990) +test_mixed(4091) +test_mixed(200) +test_mixed(17) +test_mixed(1) + +test("binary line") +test_rawline(1) +test_rawline(17) +test_rawline(200) +test_rawline(4091) +test_rawline(80199) +test_rawline(8000000) +test_rawline(80199) +test_rawline(4091) +test_rawline(200) +test_rawline(17) +test_rawline(1) + +test("raw transfer") +test_raw(1) +test_raw(17) +test_raw(200) +test_raw(4091) +test_raw(80199) +test_raw(8000000) +test_raw(80199) +test_raw(4091) +test_raw(200) +test_raw(17) +test_raw(1) + +test("non-blocking transfer") +test_nonblocking(1) +test_nonblocking(17) +test_nonblocking(200) +test_nonblocking(4091) +test_nonblocking(80199) +test_nonblocking(800000) +test_nonblocking(80199) +test_nonblocking(4091) +test_nonblocking(200) +test_nonblocking(17) +test_nonblocking(1) + +test("total timeout on send") +test_totaltimeoutsend(800091, 1, 3) +test_totaltimeoutsend(800091, 2, 3) +test_totaltimeoutsend(800091, 5, 2) +test_totaltimeoutsend(800091, 3, 1) + +test("total timeout on receive") +test_totaltimeoutreceive(800091, 1, 3) +test_totaltimeoutreceive(800091, 2, 3) +test_totaltimeoutreceive(800091, 3, 2) +test_totaltimeoutreceive(800091, 3, 1) + +test("blocking timeout on send") +test_blockingtimeoutsend(800091, 1, 3) +test_blockingtimeoutsend(800091, 2, 3) +test_blockingtimeoutsend(800091, 3, 2) +test_blockingtimeoutsend(800091, 3, 1) + +test("blocking timeout on receive") +test_blockingtimeoutreceive(800091, 1, 3) +test_blockingtimeoutreceive(800091, 2, 3) +test_blockingtimeoutreceive(800091, 3, 2) +test_blockingtimeoutreceive(800091, 3, 1) + +test(string.format("done in %.2fs", socket.gettime() - start)) diff --git a/Build/source/texk/web2c/luatexdir/luasocket/test/testsrvr.lua b/Build/source/texk/web2c/luatexdir/luasocket/test/testsrvr.lua new file mode 100644 index 00000000000..f1972c2273c --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/test/testsrvr.lua @@ -0,0 +1,15 @@ +socket = require("socket"); +host = host or "localhost"; +port = port or "8383"; +server = assert(socket.bind(host, port)); +ack = "\n"; +while 1 do + print("server: waiting for client connection..."); + control = assert(server:accept()); + while 1 do + command = assert(control:receive()); + assert(control:send(ack)); + print(command); + (loadstring(command))(); + end +end diff --git a/Build/source/texk/web2c/luatexdir/luasocket/test/testsupport.lua b/Build/source/texk/web2c/luatexdir/luasocket/test/testsupport.lua new file mode 100644 index 00000000000..acad8f5bce6 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luasocket/test/testsupport.lua @@ -0,0 +1,37 @@ +function readfile(name) + local f = io.open(name, "rb") + if not f then return nil end + local s = f:read("*a") + f:close() + return s +end + +function similar(s1, s2) + return string.lower(string.gsub(s1 or "", "%s", "")) == + string.lower(string.gsub(s2 or "", "%s", "")) +end + +function fail(msg) + msg = msg or "failed" + error(msg, 2) +end + +function compare(input, output) + local original = readfile(input) + local recovered = readfile(output) + if original ~= recovered then fail("comparison failed") + else print("ok") end +end + +local G = _G +local set = rawset +local warn = print + +local setglobal = function(table, key, value) + warn("changed " .. key) + set(table, key, value) +end + +setmetatable(G, { + __newindex = setglobal +}) diff --git a/Build/source/texk/web2c/luatexdir/luatangle.ch b/Build/source/texk/web2c/luatexdir/luatangle.ch index f6de622eeb2..936e4d62ab4 100644 --- a/Build/source/texk/web2c/luatexdir/luatangle.ch +++ b/Build/source/texk/web2c/luatexdir/luatangle.ch @@ -1,12 +1,13 @@ -% otangle.ch: web2c changes to file tangle.ch +% luatangle.ch: web2c changes to file tangle.ch +% $Id$ % -% This file is part of the Omega project, which -% is based in the web2c distribution of TeX. +% This file is part of LuaTeX. % % Copyright (c) 1994--1998 John Plaice and Yannis Haralambous +% Copyright 2006-2008 Taco Hoekwater % applies only to the changes to the original tangle.ch. % -% otangle.ch for C compilation with web2c. +% luatangle.ch for C compilation with web2c. % % 10/9/82 (HT) Original version % 11/29 (HT) New version, with conversion to lowercase handled properly diff --git a/Build/source/texk/web2c/luatexdir/luatex-api.h b/Build/source/texk/web2c/luatexdir/luatex-api.h index 3585e01dea7..8cb7363e216 100644 --- a/Build/source/texk/web2c/luatexdir/luatex-api.h +++ b/Build/source/texk/web2c/luatexdir/luatex-api.h @@ -1,4 +1,23 @@ -/* $Id */ +/* luatex-api.h + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id$ */ #include #include @@ -13,92 +32,97 @@ typedef struct LoadS { size_t size; } LoadS; -extern lua_State *Luas[]; +extern lua_State *Luas; + +extern void make_table(lua_State * L, char *tab, char *getfunc, char *setfunc); -extern void make_table (lua_State *L, char *tab, char *getfunc, char*setfunc); +extern int luac_main(int argc, char *argv[]); -extern int luac_main (int argc, char* argv[]); +extern int luaopen_tex(lua_State * L); -extern int luaopen_tex (lua_State *L); +extern int luaopen_pdf(lua_State * L); -extern int luaopen_pdf (lua_State *L); +#define LUA_TEXFILEHANDLE "TEXFILE*" -#define LUA_TEXFILEHANDLE "TEXFILE*" +extern int luaopen_texio(lua_State * L); -extern int luaopen_texio (lua_State *L); +extern int luaopen_lang(lua_State * L); -extern int luaopen_lang (lua_State *L); +extern void luatex_load_init(int s, LoadS * ls); -extern void luatex_load_init (int s, LoadS *ls); +extern lua_State *luatex_error(lua_State * L, int fatal); -extern lua_State *luatex_error (lua_State *L, int fatal); +extern int luaopen_unicode(lua_State * L); +extern int luaopen_zip(lua_State * L); +extern int luaopen_lfs(lua_State * L); +extern int luaopen_lpeg(lua_State * L); +extern int luaopen_md5(lua_State * L); +extern int luaopen_zlib(lua_State * L); +extern int luaopen_gzip(lua_State * L); +extern int luaopen_ff(lua_State * L); +extern int luaopen_profiler(lua_State * L); -extern int luaopen_unicode (lua_State *L); -extern int luaopen_zip (lua_State *L); -extern int luaopen_lfs (lua_State *L); -extern int luaopen_lpeg (lua_State *L); -extern int luaopen_md5 (lua_State *L); -extern int luaopen_zlib (lua_State *L); -extern int luaopen_gzip (lua_State *L); -extern int luaopen_ff (lua_State *L); +extern int luaopen_socket_core(lua_State * L); +extern int luaopen_mime_core(lua_State * L); +extern void luatex_socketlua_open(lua_State * L); -extern int luaopen_img (lua_State *L); -extern int luaopen_mp (lua_State *L); +extern int luaopen_img(lua_State * L); +extern int l_new_image(lua_State * L); +extern int luaopen_mplib(lua_State * L); -extern void open_oslibext (lua_State *L, int safer_option); +extern void open_oslibext(lua_State * L, int safer_option); -extern void initfilecallbackids (int max); -extern void setinputfilecallbackid (int n, int i) ; -extern void setreadfilecallbackid (int n, int i) ; -extern int getinputfilecallbackid (int n); -extern int getreadfilecallbackid (int n); +extern void initfilecallbackids(int max); +extern void setinputfilecallbackid(int n, int i); +extern void setreadfilecallbackid(int n, int i); +extern int getinputfilecallbackid(int n); +extern int getreadfilecallbackid(int n); -extern void lua_initialize (int ac, char **av); +extern void lua_initialize(int ac, char **av); -extern int luaopen_kpse (lua_State *L); +extern int luaopen_kpse(lua_State * L); -extern int luaopen_callback (lua_State *L); +extern int luaopen_callback(lua_State * L); -extern int luaopen_lua (lua_State *L, int n, char *fname); +extern int luaopen_lua(lua_State * L, char *fname); -extern int luaopen_stats (lua_State *L); +extern int luaopen_stats(lua_State * L); -extern int luaopen_font (lua_State *L); -extern int font_to_lua (lua_State *L, int f) ; -extern int font_from_lua (lua_State *L, int f) ; /* return is boolean */ +extern int luaopen_font(lua_State * L); +extern int font_to_lua(lua_State * L, int f); +extern int font_from_lua(lua_State * L, int f); /* return is boolean */ -extern int luaopen_token (lua_State *L); -extern char *tokenlist_to_cstring (int p , int inhibit_par, int *siz); -extern void tokenlist_to_lua(lua_State *L, int p); -extern void tokenlist_to_luastring(lua_State *L, int p) ; -extern int tokenlist_from_lua(lua_State *L); +extern int luaopen_token(lua_State * L); +extern char *tokenlist_to_cstring(int p, int inhibit_par, int *siz); +extern void tokenlist_to_lua(lua_State * L, int p); +extern void tokenlist_to_luastring(lua_State * L, int p); +extern int tokenlist_from_lua(lua_State * L); -extern void lua_nodelib_push (lua_State *L) ; -extern int luaopen_node (lua_State *L); -extern void nodelist_to_lua (lua_State *L, int n) ; -extern int nodelist_from_lua (lua_State *L); +extern void lua_nodelib_push(lua_State * L); +extern int luaopen_node(lua_State * L); +extern void nodelist_to_lua(lua_State * L, int n); +extern int nodelist_from_lua(lua_State * L); -extern int dimen_to_number (lua_State *L, char *s); +extern int dimen_to_number(lua_State * L, char *s); -extern void dump_luac_registers (void); +extern void dump_luac_registers(void); -extern void undump_luac_registers (void); +extern void undump_luac_registers(void); -extern void unhide_lua_table(lua_State *lua, char *name, int r); -extern int hide_lua_table (lua_State *lua, char *name); +extern void unhide_lua_table(lua_State * lua, char *name, int r); +extern int hide_lua_table(lua_State * lua, char *name); -extern void unhide_lua_value(lua_State *lua, char *name, char *item, int r); -extern int hide_lua_value (lua_State *lua, char *name, char *item); +extern void unhide_lua_value(lua_State * lua, char *name, char *item, int r); +extern int hide_lua_value(lua_State * lua, char *name, char *item); typedef struct command_item_ { - char *cmd_name; - int command_offset; - char **commands; + char *cmd_name; + int command_offset; + char **commands; } command_item; - + extern command_item command_names[]; extern int callback_callbacks_id; -void luainterpreter (int n) ; - +extern void luainterpreter(void); diff --git a/Build/source/texk/web2c/luatexdir/luatex.ch b/Build/source/texk/web2c/luatexdir/luatex.ch index 0ae368beb80..5361f6550ca 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.ch +++ b/Build/source/texk/web2c/luatexdir/luatex.ch @@ -1,3 +1,24 @@ +% luatex.ch +% +% Copyright 2006-2008 Taco Hoekwater +% +% This file is part of LuaTeX. +% +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. +% +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. +% +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see . +% +% $Id$ +% @x \def\?##1]{\hbox to 1in{\hfil##1.\ }} } @@ -8,11 +29,11 @@ @z @x -@d banner==luaTeX_banner +@d banner==LuaTeX_banner @y -@d luaTeXk_banner=='This is luaTeXk, Version ',luatex_version_string +@d luaTeXk_banner=='This is LuaTeXk, Version ',luatex_version_string @# -@d banner==luaTeX_banner +@d banner==LuaTeX_banner @d banner_k==luaTeXk_banner @z @@ -20,6 +41,7 @@ Actually the heading shown here is not quite normal: The |program| line does not mention any |output| file, because \ph\ would ask the \TeX\ user to specify a file name if |output| were specified here. +@:PASCAL H}{\ph@> @^system dependencies@> @y @z @@ -129,7 +151,7 @@ versions of the program. {Larger values than 65536 cause the arrays consume much more memory.} @= -@!hash_offset=514; {smallest index in hash array, i.e., |hash_base| } +@!hash_offset=0; {smallest index in hash array, i.e., |hash_base| } {Use |hash_offset=0| for compilers which cannot decrement pointers.} @!engine_name='luatex'; {the name of this engine} @# @@ -184,20 +206,6 @@ versions of the program. @!sup_expand_depth = 1000000; @z -@x -@d font_base=0 {smallest internal font number; must not be less - than |min_quarterword|} -@d hash_size=2100 {maximum number of control sequences; it should be at most - about |(fix_mem_max-fix_mem_min)/10|} -@d hash_prime=1777 {a prime number equal to about 85\pct! of |hash_size|} -@y -@d font_base=0 {smallest internal font number; must not be less - than |min_quarterword|} -@d hash_size=65536 {maximum number of control sequences; it should be at most - about |(mem_max-mem_min)/10|} -@d hash_prime=55711 {a prime number equal to about 85\pct! of |hash_size|} -@z - @x @d incr(#) == #:=#+1 {increase a variable by unity} @d decr(#) == #:=#-1 {decrease a variable by unity} @@ -279,6 +287,7 @@ end; @x @ Files can be closed with the \ph\ routine `|close(f)|', which +@:PASCAL H}{\ph@> @^system dependencies@> should be used when all input or output with respect to |f| has been completed. This makes |f| available to be opened again, if desired; and if |f| was used for @@ -391,21 +400,12 @@ tini@/ @!filelineerrorstylep:cinttype; {format messages as file:line:error} @!haltonerrorp:cinttype; {stop at first error} @!quoted_filename:boolean; {current filename is quoted} -{Variables for source specials} -@!srcspecialsp : boolean;{Whether |src_specials| are enabled at all} -@!insertsrcspecialauto : boolean; -@!insertsrcspecialeverypar : boolean; -@!insertsrcspecialeveryparend : boolean; -@!insertsrcspecialeverycr : boolean; -@!insertsrcspecialeverymath : boolean; -@!insertsrcspecialeveryhbox : boolean; -@!insertsrcspecialeveryvbox : boolean; -@!insertsrcspecialeverydisplay : boolean; @z @x @ Here is how to open the terminal files in \ph. The `\.{/I}' switch suppresses the first |get|. +@:PASCAL H}{\ph@> @^system dependencies@> @d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input} @@ -420,6 +420,7 @@ any command line arguments the user has provided. It's defined in C. @x these operations can be specified in \ph: +@:PASCAL H}{\ph@> @^system dependencies@> @d update_terminal == break(term_out) {empty the terminal output buffer} @@ -573,47 +574,6 @@ if (haltonerrorp) then begin end; @z -@x -line ready to be edited. But such an extension requires some system -wizardry, so the present implementation simply types out the name of the -file that should be -edited and the relevant line number. -@^system dependencies@> - -There is a secret `\.D' option available when the debugging routines haven't -been commented~out. -@^debugging@> -@y -line ready to be edited. -We do this by calling the external procedure |calledit| with a pointer to -the filename, its length, and the line number. -However, here we just set up the variables that will be used as arguments, -since we don't want to do the switch-to-editor until after TeX has closed -its files. -@^system dependencies@> - -There is a secret `\.D' option available when the debugging routines haven't -been commented~out. -@^debugging@> -@d edit_file==input_stack[base_ptr] -@z - -@x -"E": if base_ptr>0 then - begin print_nl("You want to edit file "); -@.You want to edit file x@> - slow_print(input_stack[base_ptr].name_field); - print(" at line "); print_int(line); - interaction:=scroll_mode; jump_out; -@y -"E": if base_ptr>0 then - begin edit_name_start:=str_start_macro(edit_file.name_field); - edit_name_length:=str_start_macro(edit_file.name_field+1) - - str_start_macro(edit_file.name_field); - edit_line:=line; - jump_out; -@z - @x |remainder|, holds the remainder after a division. @@ -686,18 +646,6 @@ So they have been simplified here in the obvious way. @=#include "texmfmem.h";@> @z -@x - if abs(vmem(p+glue_offset).int)<@'4000000 then print("?.?") - else if abs(g)>float_constant(20000) then -@y - { The Unix |pc| folks removed this restriction with a remark that - invalid bit patterns were vanishingly improbable, so we follow - their example without really understanding it. - |if abs(vmem(p+glue_offset).int)<@'4000000 then print('?.?')| - |else| } - if fabs(g)>float_constant(20000) then -@z - @x begin if m>0 then case m div (max_command+1) of @@ -751,10 +699,8 @@ end; @z @x -local_par:=null; local_par_bool:=false; @; @y -local_par:=null; local_par_bool:=false; @/{The following piece of code is a copy of module 991:} page_contents:=empty; page_tail:=page_head; {|link(page_head):=null;|}@/ last_glue:=max_halfword; last_penalty:=0; last_kern:=0; @@ -771,20 +717,10 @@ page_depth:=0; page_max_depth:=0; @z @x -@d frozen_null_font=frozen_control_sequence+12 - {permanent `\.{\\nullfont}'} -@y -@d frozen_special=frozen_control_sequence+12 - {permanent `\.{\\special}'} -@d frozen_null_font=frozen_control_sequence+13 - {permanent `\.{\\nullfont}'} -@z - -@x -for k:=active_base to undefined_control_sequence-1 do +for k:=null_cs to undefined_control_sequence-1 do eqtb[k]:=eqtb[undefined_control_sequence]; @y -for k:=active_base to eqtb_top do +for k:=null_cs to eqtb_top do eqtb[k]:=eqtb[undefined_control_sequence]; @z @@ -823,7 +759,7 @@ else if (neqtb_size)and(n<=eqtb_top)) then @z @x -@!eqtb:array[active_base..eqtb_size] of memory_word; +@!eqtb:array[null_cs..eqtb_size] of memory_word; @y @!zeqtb:^memory_word; @z @@ -855,32 +791,6 @@ hash_used:=frozen_control_sequence; {nothing is used} hash_high:=0; @z -@x -@ @= -begin if text(p)>0 then - begin repeat if hash_is_full then overflow("hash size",hash_size); -@:TeX capacity exceeded hash size}{\quad hash size@> - decr(hash_used); - until text(hash_used)=0; {search for an empty location in |hash|} - next(p):=hash_used; p:=hash_used; - end; -@y -@ @= -begin if text(p)>0 then - begin if hash_high - decr(hash_used); - until text(hash_used)=0; {search for an empty location in |hash|} - next(p):=hash_used; p:=hash_used; - end; - end; -@z - @x else if p>=undefined_control_sequence then print_esc("IMPOSSIBLE.") @y @@ -1025,203 +935,6 @@ otherwise the file area is null. If the remaining file name contains In C, the default paths are specified separately. @z -@x -begin area_delimiter:=0; ext_delimiter:=0; -@y -begin area_delimiter:=0; ext_delimiter:=0; quoted_filename:=false; -@z - -@x -begin if c=" " then more_name:=false -@y -begin if (c=" ") and stop_at_space and (not quoted_filename) then - more_name:=false -else if c="""" then begin - quoted_filename:=not quoted_filename; - more_name:=true; - end -@z - -@x - if (c=">")or(c=":") then -@y - if ISDIRSEP(c) then -@z - -@x - else if (c=".")and(ext_delimiter=0) then ext_delimiter:=cur_length; -@y - else if c="." then ext_delimiter:=cur_length; -@z - -@x -@ The third. -@^system dependencies@> - -@p procedure end_name; -@y -@ The third. -@^system dependencies@> -If a string is already in the string pool, the function -|slow_make_string| does not create a new string but returns this string -number, thus saving string space. Because of this new property of the -returned string number it is not possible to apply |flush_string| to -these strings. - -@p procedure end_name; -var temp_str: str_number; {result of file name cache lookups} -@!j,@!s,@!t: pool_pointer; {running indices} -@!must_quote:boolean; {whether we need to quote a string} -@z - -@x -@:TeX capacity exceeded number of strings}{\quad number of strings@> -@y -@:TeX capacity exceeded number of strings}{\quad number of strings@> -str_room(6); {Room for quotes, if needed.} -{add quotes if needed} -if area_delimiter<>0 then begin - {maybe quote |cur_area|} - must_quote:=false; - s:=str_start_macro(str_ptr); - t:=str_start_macro(str_ptr)+area_delimiter; - j:=s; - while (not must_quote) and (j0 then ext_delimiter:=ext_delimiter+2; - area_delimiter:=area_delimiter+2; - pool_ptr:=pool_ptr+2; - end; - end; -{maybe quote |cur_name|} -s:=str_start_macro(str_ptr)+area_delimiter; -if ext_delimiter=0 then t:=pool_ptr else t:=str_start_macro(str_ptr)+ext_delimiter-1; -must_quote:=false; -j:=s; -while (not must_quote) and (j0 then ext_delimiter:=ext_delimiter+2; - pool_ptr:=pool_ptr+2; - end; -if ext_delimiter<>0 then begin - {maybe quote |cur_ext|} - s:=str_start_macro(str_ptr)+ext_delimiter-1; - t:=pool_ptr; - must_quote:=false; - j:=s; - while (not must_quote) and (j0 then - begin cur_area:=temp_str; - decr(str_ptr); {no |flush_string|, |pool_ptr| will be wrong!} - for j:=str_start_macro(str_ptr+1) to pool_ptr-1 do - begin str_pool[j-area_delimiter]:=str_pool[j]; - end; - pool_ptr:=pool_ptr-area_delimiter; {update |pool_ptr|} - end; - end; -if ext_delimiter=0 then - begin cur_ext:=""; cur_name:=slow_make_string; -@z - -@x -else begin cur_name:=str_ptr; - str_start_macro(str_ptr+1):=str_start_macro(str_ptr)+ext_delimiter-area_delimiter-1; - incr(str_ptr); cur_ext:=make_string; -@y -else begin cur_name:=str_ptr; - str_start_macro(str_ptr+1):=str_start_macro(str_ptr)+ext_delimiter-area_delimiter-1; - incr(str_ptr); cur_ext:=make_string; - decr(str_ptr); {undo extension string to look at name part} - temp_str:=search_string(cur_name); - if temp_str>0 then - begin cur_name:=temp_str; - decr(str_ptr); {no |flush_string|, |pool_ptr| will be wrong!} - for j:=str_start_macro(str_ptr+1) to pool_ptr-1 do - begin str_pool[j-ext_delimiter+area_delimiter+1]:=str_pool[j]; - end; - pool_ptr:=pool_ptr-ext_delimiter+area_delimiter+1; {update |pool_ptr|} - end; - cur_ext:=slow_make_string; {remake extension string} -@z - -@x -begin slow_print(a); slow_print(n); slow_print(e); -@y -var must_quote: boolean; {whether to quote the filename} -@!j:pool_pointer; {index into |str_pool|} -begin -must_quote:=false; -if a<>0 then begin - j:=str_start_macro(a); - while (not must_quote) and (j0 then begin - j:=str_start_macro(n); - while (not must_quote) and (j0 then begin - j:=str_start_macro(e); - while (not must_quote) and (j0)and(|str_pool|[|str_start|[|a|]]=""""))or - ((|n|<>0)and(|str_pool|[|str_start|[|n|]]=""""))or - ((|e|<>0)and(|str_pool|[|str_start|[|e|]]=""""));} -if must_quote then print_char(""""); -if a<>0 then - for j:=str_start_macro(a) to str_start_macro(a+1)-1 do - if so(str_pool[j])<>"""" then - print(so(str_pool[j])); -if n<>0 then - for j:=str_start_macro(n) to str_start_macro(n+1)-1 do - if so(str_pool[j])<>"""" then - print(so(str_pool[j])); -if e<>0 then - for j:=str_start_macro(e) to str_start_macro(e+1)-1 do - if so(str_pool[j])<>"""" then - print(so(str_pool[j])); -if must_quote then print_char(""""); -@z - @x @d append_to_name(#)==begin c:=#; incr(k); if k<=file_name_size then nameoffile[k]:=xchr[c]; @@ -1318,78 +1031,6 @@ nameoffile[namelength+1]:=0; @.I can't find the format...@> @z -@x -@p function make_name_string:str_number; -var k:1..file_name_size; {index into |nameoffile|} -begin if (pool_ptr+namelength>pool_size)or(str_ptr=max_strings)or - (cur_length>0) then - make_name_string:="?" -else begin for k:=1 to namelength do append_char(nameoffile[k]); - make_name_string:=make_string; - end; -@y -@p function make_name_string:str_number; -var k:1..file_name_size; {index into |nameoffile|} -save_area_delimiter, save_ext_delimiter: pool_pointer; -save_name_in_progress, save_stop_at_space: boolean; -begin if (pool_ptr+namelength>pool_size)or(str_ptr=max_strings)or - (cur_length>0) then - make_name_string:="?" -else begin for k:=1 to namelength do append_char(nameoffile[k]); - make_name_string:=make_string; - {At this point we also set |cur_name|, |cur_ext|, and |cur_area| to - match the contents of |nameoffile|.} - save_area_delimiter:=area_delimiter; - save_ext_delimiter:=ext_delimiter; - save_name_in_progress:=name_in_progress; - save_stop_at_space:=stop_at_space; - name_in_progress:=true; - begin_name; - stop_at_space:=false; - k:=1; - while (k<=namelength)and(more_name(nameoffile[k])) do - incr(k); - stop_at_space:=save_stop_at_space; - end_name; - name_in_progress:=save_name_in_progress; - area_delimiter:=save_area_delimiter; - ext_delimiter:=save_ext_delimiter; - end; -@z - -@x - if not more_name(cur_chr) then goto done; -@y - {If |cur_chr| is a space and we're not scanning a token list, check - whether we're at the end of the buffer. Otherwise we end up adding - spurious spaces to file names in some cases.} - if (cur_chr=" ") and (state<>token_list) and (loc>limit) then goto done; - if not more_name(cur_chr) then goto done; -@z - -@x -var k:0..buf_size; {index into |buffer|} -@y -var k:0..buf_size; {index into |buffer|} -@!saved_cur_name:str_number; {to catch empty terminal input} -@z - -@x -if e=".tex" then show_context; -@y -if (e=".tex") or (e="") then show_context; -@z - -@x -clear_terminal; prompt_input(": "); @; -if cur_ext="" then cur_ext:=e; -@y -saved_cur_name:=cur_name; -clear_terminal; prompt_input(": "); @; -if cur_ext="" then cur_ext:=e; -if length(cur_name)=0 then cur_name:=saved_cur_name; -@z - @x @d ensure_dvi_open==if output_file_name=0 then @y @@ -1409,14 +1050,14 @@ if job_name=0 then job_name:="texput"; @y if job_name=0 then job_name:=getjobname("texput"); @.texput@> -pack_job_name(".fls"); +pack_job_name('.fls'); recorder_change_filename(stringcast(nameoffile+1)); @z @x begin wlog(banner); @y -begin if srcspecialsp or filelineerrorstylep or parsefirstlinep +begin if filelineerrorstylep or parsefirstlinep then wlog(banner_k) else @@ -1447,10 +1088,6 @@ if shellenabledp then begin end; wlog('\write18 enabled.') end; -if srcspecialsp then begin - wlog_cr; - wlog(' Source specials enabled.') - end; if filelineerrorstylep then begin wlog_cr; wlog(' file:line:error style messages enabled.') @@ -1463,9 +1100,9 @@ end @z @x - prompt_file_name("input file name",".tex"); + prompt_file_name('input file name','.tex'); @y - prompt_file_name("input file name",""); + prompt_file_name('input file name',''); @z @x @@ -1613,9 +1250,6 @@ endifn ('IPC') continue: adjust_space_factor;@/ @y @= -if ((head=tail) and (mode>0)) then begin - if (insertsrcspecialauto) then append_src_special; -end; continue: adjust_space_factor;@/ @z @@ -1635,7 +1269,6 @@ if indented then begin p:=new_null_box; box_dir(p):=par_direction; width(p):=par_indent;@+ tail_append(p); - if (insertsrcspecialeverypar) then insert_src_special;@+ @z @x @@ -1656,20 +1289,6 @@ end else begin end; @z -@x -if every_math<>null then begin_token_list(every_math,every_math_text); -@y -if (insertsrcspecialeverymath) then insert_src_special; -if every_math<>null then begin_token_list(every_math,every_math_text); -@z - -@x - if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text); -@y - if (insertsrcspecialeveryvbox) then insert_src_special; - if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text); -@z - @x if (cur_cs=0)or(cur_cs>frozen_control_sequence) then @y @@ -1677,11 +1296,6 @@ if (cur_cs=0)or(cur_cs>eqtb_top)or ((cur_cs>frozen_control_sequence)and(cur_cs<=eqtb_size)) then @z -@x -@!flushable_string:str_number; {string not yet referenced} -@y -@z - @x interaction:=cur_chr; @y @@ -1774,7 +1388,7 @@ if x<>@$ then goto bad_fmt; {check that strings are the same} @y @+Init libcfree(str_pool); libcfree(str_start); -libcfree(yhash); libcfree(zeqtb); libcfree(fixmem); libcfree(varmem); +libcfree(yhash); libcfree(zeqtb); libcfree(fixmem); libcfree(varmemcast(varmem)); @+Tini undump_int(x); format_debug('format magic number')(x); @@ -2065,8 +1679,8 @@ print(" (format="); print(job_name); print_char(" "); @d setup_bound_var(#)==bound_default:=#; setup_bound_var_end @d setup_bound_var_end(#)==bound_name:=#; setup_bound_var_end_end @d setup_bound_var_end_end(#)==if luainit>0 then begin - get_lua_number('texconfig',bound_name,addressof(#)); - if #=0 then #:=bound_default; + get_lua_number('texconfig',bound_name,addressof(#)); + if #=0 then #:=bound_default; end else setupboundvariable(addressof(#), bound_name, bound_default); @@ -2201,7 +1815,7 @@ end {|main_body|}; @x wterm(banner); @y - if srcspecialsp or filelineerrorstylep or parsefirstlinep then + if filelineerrorstylep or parsefirstlinep then wterm(banner_k) else wterm(banner); @@ -2222,9 +1836,6 @@ end {|main_body|}; end; wterm_ln('\write18 enabled.'); end; - if srcspecialsp then begin - wterm_ln(' Source specials enabled.') - end; if filelineerrorstylep then begin wterm_ln(' file:line:error style messages enabled.') end; @@ -2300,13 +1911,6 @@ tini@/ abort {do something to cause a core dump} @z -@x -primitive("special",extension,special_node);@/ -@y -primitive("special",extension,special_node);@/ -text(frozen_special):="special"; eqtb[frozen_special]:=eqtb[cur_val];@/ -@z - @x else if cur_val>15 then cur_val:=16; @y @@ -2350,7 +1954,7 @@ if j=18 then str_room(1); append_char(0); {Append a null byte to the expansion.} clobbered:=false; for d:=0 to cur_length-1 do {Convert to external character set.} - begin + begin str_pool[str_start_macro(str_ptr)+d]:=xchr[str_pool[str_start_macro(str_ptr)+d]]; if (str_pool[str_start_macro(str_ptr)+d]=null_code) and (d= - -procedure insert_src_special; -var toklist, p, q,r : pointer; -begin - if (source_filename_stack[in_open] > 0 and isnewsource (source_filename_stack[in_open] -, line)) then begin - toklist := get_avail; - p := toklist; - info(p) := cs_token_flag+frozen_special; - r := get_avail; link(p):=r; p := link(p); - info(p) := left_brace_token+"{"; - q := str_toks (makesrcspecial (source_filename_stack[in_open], line)); - link(p) := link(temp_token_head); - p := q; - r := get_avail; link(p):=r; p := link(p); - info(p) := right_brace_token+"}"; - ins_list (toklist); - remembersourceinfo (source_filename_stack[in_open], line); - end; -end; - -procedure append_src_special; -var q : pointer; -begin - if (source_filename_stack[in_open] > 0 and isnewsource (source_filename_stack[in_open] -, line)) then begin - new_whatsit (special_node); - write_stream(tail) := 0; - q:=get_avail; def_ref := q; - token_ref_count(def_ref) := null; - q := str_toks (makesrcspecial (source_filename_stack[in_open], line)); - link(def_ref) := link(temp_head); - write_tokens(tail) := def_ref; - remembersourceinfo (source_filename_stack[in_open], line); - end; -end; - @ This function used to be in pdftex, but is useful in tex too. @p function get_nullstr: str_number; diff --git a/Build/source/texk/web2c/luatexdir/luatex.defines b/Build/source/texk/web2c/luatexdir/luatex.defines index 7a1ac4e79d8..b4e5baeba34 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.defines +++ b/Build/source/texk/web2c/luatexdir/luatex.defines @@ -1,26 +1,28 @@ -{ -Copyright (c) 1996-2006, 2008 Han The Thanh, Taco Hoekwater +{ luatex.defines + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of luaTeX. + This file is part of LuaTeX. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . } -$Id$ -} +{ $Id$ } -{ luatex.defines: additions for luaTeX } +{ luatex.defines: additions for LuaTeX } + +@define function simple_advance_width(); @define function new_node(); @define function new_glyph_node; @@ -61,7 +63,6 @@ $Id$ @define function make_lang_data(); @define procedure ext_do_line_break(); @define procedure initialize_active; -@define var active_node_size; @define var prev_char_p; @define function cur_break(); @define function break_node(); @@ -75,10 +76,16 @@ $Id$ @define procedure dump_language_data; @define procedure undump_language_data; @define function insert_discretionary(); +@define function compound_word_break(); @define procedure set_pre_hyphen_char(); @define procedure set_post_hyphen_char(); +@define procedure set_pre_exhyphen_char(); +@define procedure set_post_exhyphen_char(); @define function get_pre_hyphen_char(); @define function get_post_hyphen_char(); +@define function get_pre_exhyphen_char(); +@define function get_post_exhyphen_char(); + { macros from luatex.h } @define function pdf_char_marked(); @@ -91,15 +98,13 @@ $Id$ @define procedure luacall(); @define procedure luatokencall(); @define procedure closelua(); +@define function get_lua_name(); + +{ for virtual file input } -@define function luacstring_input; -@define function luacstring_penultimate; -@define function luacstring_detokenized; -@define function luacstring_cattable; -@define function luacstring_defaultcattable; -@define function luacstring_simple; @define procedure luacstring_close(); @define procedure luacstring_start(); +@define var DEFAULT_CAT_TABLE; { for callbacks } @@ -146,11 +151,13 @@ $Id$ @define var define_font_callback; @define var token_filter_callback; @define var pre_linebreak_filter_callback; +@define var linebreak_filter_callback; @define var post_linebreak_filter_callback; @define var buildpage_filter_callback; @define var hyphenate_callback; @define function lua_hyphenate_callback(); +@define function lua_linebreak_callback(); @define procedure get_saved_lua_boolean(); @define procedure get_saved_lua_number(); @@ -167,16 +174,39 @@ $Id$ { bits for extended char code access } +@define const tex_mathcode ; +@define const aleph_mathcode ; +@define const xetex_mathcode ; +@define const xetexnum_mathcode; + +@define type mathcodeval; +@define @field origin_value; +@define @field class_value; +@define @field family_value; +@define @field character_value; + +@define type delcodeval; +@define @field small_family_value; +@define @field small_character_value; +@define @field large_family_value; +@define @field large_character_value; + @define function get_math_code(); +@define function get_math_code_num(); @define procedure set_math_code(); -@define function get_del_code_a(); -@define function get_del_code_b(); +@define function get_del_code(); @define procedure set_del_code(); +@define procedure show_mathcode_value(); + +@define function scan_mathchar(); +@define function scan_delimiter_as_mathchar(); +@define function mathchar_from_integer(); @define procedure unsave_math_codes (); @define procedure initialize_math_codes; @define procedure dump_math_codes; @define procedure undump_math_codes; +@define procedure free_math_codes; @define function get_lc_code(); @define procedure set_lc_code(); @@ -197,6 +227,7 @@ $Id$ @define procedure unsave_cat_codes (); @define procedure unsave_text_codes (); @define procedure initializetextcodes; +@define procedure free_text_codes; @define procedure dumptextcodes; @define procedure undumptextcodes; @@ -209,6 +240,8 @@ $Id$ @define procedure flush_loggable_info; @define var extra_version_info; +@define var SVN_REV; +@define procedure do_write_wterm(); { bits and pieces from aleph } @@ -227,6 +260,8 @@ $Id$ @define procedure undump_ocp_table (); @define procedure run_external_ocp (); +@define function copy_font_info(); + { 'texfont' library definitions } @define procedure dump_font (); @@ -404,6 +439,13 @@ $Id$ @define procedure writefontstuff; +{functions from filename.c } +@define procedure pack_job_name(); +@define procedure prompt_file_name(); +@define procedure scan_file_name; +@define function make_name_string; +@define procedure print_file_name(); + { functions from utils.c } @define procedure escapehex(); @define procedure escapename(); @@ -445,6 +487,9 @@ $Id$ @define function getlly; @define function geturx; @define function getury; +@define function pdf_do_page_divert(); +@define procedure pdf_do_page_undivert(); +@define function output_pages_tree; {functions from texpdf.c } @@ -457,6 +502,9 @@ $Id$ {functions from textoken.c } @define function get_next; +@define function scan_keyword(); +@define procedure scan_direction; +@define function active_to_cs(); { functions from vfpacket.c } @define function new_vf_packet(); @@ -471,10 +519,13 @@ $Id$ @define function check_image_b(); @define function check_image_c(); @define function check_image_i(); +@define function epdf_xsize(); +@define function epdf_ysize(); @define function epdf_orig_x(); @define function epdf_orig_y(); @define function image_pages(); @define function image_colordepth(); +@define function image_groupref(); @define function image_index(); @define function image_width(); @define function image_height(); @@ -482,6 +533,7 @@ $Id$ @define function image_objnum(); @define function image_imgnum(); @define function is_pdf_image(); +@define function is_png_image(); @define function read_image(); @define function new_image_entry; @define procedure update_image_procset(); @@ -491,8 +543,20 @@ $Id$ @define procedure set_image_index(); @define procedure out_image(); +@define procedure dumpimagemeta; +@define procedure undumpimagemeta(); + { functions from limglib.c } -@define procedure lua_setximage(); + +{ functions from pdfpage.c } +@define procedure pdf_place_rule(); +@define procedure pdf_place_glyph(); +@define procedure pdf_place_form(); +@define procedure pdf_goto_pagemode; +@define procedure pdf_page_init; +@define procedure pdf_set_pos(); +@define procedure pdf_end_string_nl; +@define procedure pdf_print_charwidth(); { functions from writet3.c } @define function get_pk_char_width(); @@ -507,6 +571,9 @@ $Id$ { functions from tounicode.c } @define procedure def_tounicode(); +{ functions from luatex.web } +@define function auto_expand_vf(); + { end of luatex.defines } {texmf.defines} @@ -556,3 +623,276 @@ $Id$ @define procedure write_ln (); @define procedure recorder_change_filename (); + +{ functions from the synctex controller in synctex.c } + +@define procedure synctex_init_command; +@define procedure synctex_start_input; +@define procedure synctex_terminate(); +@define procedure synctex_sheet(); +@define procedure synctex_teehs; +@define procedure synctex_vlist(); +@define procedure synctex_tsilv(); +@define procedure synctex_void_vlist(); +@define procedure synctex_hlist(); +@define procedure synctex_tsilh(); +@define procedure synctex_void_hlist(); +@define procedure synctex_math(); +@define procedure synctex_kern(); +@define procedure synctex_char(); +@define procedure synctex_node(); +@define procedure synctex_current; +@define procedure synctex_horizontal_rule_or_glue(); + +{math stuff} + +@define procedure initialize_math; +@define procedure show_math_node(); +@define procedure print_math_comp(); +@define procedure print_limit_switch(); +@define procedure print_style(); + +@define procedure scan_extdef_math_code(); +@define procedure scan_extdef_del_code(); + +@define function fam_fnt(); +@define procedure def_fam_fnt(); +@define procedure dump_math_data; +@define procedure undump_math_data; +@define procedure unsave_math_data(); + +@define const fence_noad; +@define const ord_noad; +@define const op_noad; +@define const bin_noad; +@define const rel_noad; +@define const open_noad; +@define const close_noad; +@define const punct_noad; +@define const inner_noad; +@define const limits; +@define const no_limits; +@define const under_noad; +@define const over_noad; +@define const accent_noad; +@define const vcenter_noad; + +@define const left_noad_side ; +@define const middle_noad_side ; +@define const right_noad_side ; + +@define procedure print_size(); +@define procedure finish_display_alignment(); +@define function new_sub_box(); +@define function math_vcenter_group(); +@define procedure close_math_group(); +@define procedure set_math_char(); +@define function new_style(); +@define const display_style; +@define const text_style; +@define const script_style; +@define const script_script_style; +@define const cramped_display_style; +@define const cramped_text_style; +@define const cramped_script_style; +@define const cramped_script_script_style; + +@define procedure def_math_param(); +@define procedure print_math_param(); +@define function get_math_param(); +@define procedure math_char_in_text(); + + +@define const math_param_quad; +@define const math_param_axis; +@define const math_param_operator_size; +@define const math_param_overbar_kern; +@define const math_param_overbar_rule; +@define const math_param_overbar_vgap; +@define const math_param_underbar_kern; +@define const math_param_underbar_rule; +@define const math_param_underbar_vgap; +@define const math_param_radical_kern; +@define const math_param_radical_rule; +@define const math_param_radical_vgap; +@define const math_param_radical_degree_before; +@define const math_param_radical_degree_after; +@define const math_param_radical_degree_raise; +@define const math_param_stack_vgap; +@define const math_param_stack_num_up; +@define const math_param_stack_denom_down; +@define const math_param_fraction_rule; +@define const math_param_fraction_num_vgap; +@define const math_param_fraction_num_up; +@define const math_param_fraction_denom_vgap; +@define const math_param_fraction_denom_down; +@define const math_param_fraction_del_size; +@define const math_param_limit_above_vgap; +@define const math_param_limit_above_bgap; +@define const math_param_limit_above_kern; +@define const math_param_limit_below_vgap; +@define const math_param_limit_below_bgap; +@define const math_param_limit_below_kern; +@define const math_param_under_delimiter_vgap; +@define const math_param_under_delimiter_bgap; +@define const math_param_over_delimiter_vgap; +@define const math_param_over_delimiter_bgap; +@define const math_param_sub_shift_drop; +@define const math_param_sup_shift_drop; +@define const math_param_sub_shift_down; +@define const math_param_sub_sup_shift_down; +@define const math_param_sub_top_max; +@define const math_param_sup_shift_up; +@define const math_param_sup_bottom_min; +@define const math_param_sup_sub_bottom_max; +@define const math_param_subsup_vgap; +@define const math_param_space_after_script; +@define const math_param_connector_overlap_min; +@define const math_param_first_mu_glue; +@define const math_param_ord_ord_spacing; +@define const math_param_ord_op_spacing; +@define const math_param_ord_bin_spacing; +@define const math_param_ord_rel_spacing; +@define const math_param_ord_open_spacing; +@define const math_param_ord_close_spacing; +@define const math_param_ord_punct_spacing; +@define const math_param_ord_inner_spacing; +@define const math_param_op_ord_spacing; +@define const math_param_op_op_spacing; +@define const math_param_op_bin_spacing; +@define const math_param_op_rel_spacing; +@define const math_param_op_open_spacing; +@define const math_param_op_close_spacing; +@define const math_param_op_punct_spacing; +@define const math_param_op_inner_spacing; +@define const math_param_bin_ord_spacing; +@define const math_param_bin_op_spacing; +@define const math_param_bin_bin_spacing; +@define const math_param_bin_rel_spacing; +@define const math_param_bin_open_spacing; +@define const math_param_bin_close_spacing; +@define const math_param_bin_punct_spacing; +@define const math_param_bin_inner_spacing; +@define const math_param_rel_ord_spacing; +@define const math_param_rel_op_spacing; +@define const math_param_rel_bin_spacing; +@define const math_param_rel_rel_spacing; +@define const math_param_rel_open_spacing; +@define const math_param_rel_close_spacing; +@define const math_param_rel_punct_spacing; +@define const math_param_rel_inner_spacing; +@define const math_param_open_ord_spacing; +@define const math_param_open_op_spacing; +@define const math_param_open_bin_spacing; +@define const math_param_open_rel_spacing; +@define const math_param_open_open_spacing; +@define const math_param_open_close_spacing; +@define const math_param_open_punct_spacing; +@define const math_param_open_inner_spacing; +@define const math_param_close_ord_spacing; +@define const math_param_close_op_spacing; +@define const math_param_close_bin_spacing; +@define const math_param_close_rel_spacing; +@define const math_param_close_open_spacing; +@define const math_param_close_close_spacing; +@define const math_param_close_punct_spacing; +@define const math_param_close_inner_spacing; +@define const math_param_punct_ord_spacing; +@define const math_param_punct_op_spacing; +@define const math_param_punct_bin_spacing; +@define const math_param_punct_rel_spacing; +@define const math_param_punct_open_spacing; +@define const math_param_punct_close_spacing; +@define const math_param_punct_punct_spacing; +@define const math_param_punct_inner_spacing; +@define const math_param_inner_ord_spacing; +@define const math_param_inner_op_spacing; +@define const math_param_inner_bin_spacing; +@define const math_param_inner_rel_spacing; +@define const math_param_inner_open_spacing; +@define const math_param_inner_close_spacing; +@define const math_param_inner_punct_spacing; +@define const math_param_inner_inner_spacing; + + +@define const hlist_node; +@define const vlist_node; +@define const rule_node; +@define const ins_node; +@define const mark_node; +@define const adjust_node; +@define const disc_node; +@define const whatsit_node; +@define const math_node; +@define const glue_node; +@define const kern_node; +@define const penalty_node; +@define const unset_node; +@define const margin_kern_node; +@define const glyph_node; +@define const align_record_node; +@define const inserting_node; +@define const split_up_node; +@define const expr_node; +@define const span_node; +@define const action_node; +@define const glue_spec_node; +@define const temp_node; +@define const align_stack_node; +@define const movement_node; +@define const if_node; +@define const shape_node; + +@define const write_node_size; +@define const open_node_size; + +@define procedure print_short_node_contents(); +@define procedure show_node_list(); + +@define const zero_glue ; +@define const sfi_glue ; +@define const fil_glue ; +@define const fill_glue ; +@define const ss_glue ; +@define const fil_neg_glue ; +@define const page_ins_head ; +@define const contrib_head ; +@define const page_head ; +@define const temp_head ; +@define const hold_head ; +@define const adjust_head ; +@define const pre_adjust_head ; +@define const align_head ; +@define const end_span ; + + +@define const tex_command; +@define const etex_command; +@define const aleph_command; +@define const pdftex_command; +@define const luatex_command; + +@define procedure primitive_tex(); +@define procedure primitive_etex(); +@define procedure primitive_aleph(); +@define procedure primitive_omega(); +@define procedure primitive_pdftex(); +@define procedure primitive_luatex(); +@define procedure primitive_core(); +@define procedure print_cmd_chr(); + +@define procedure init_primitives; +@define procedure ini_init_primitives; +@define procedure dump_primitives; +@define procedure undump_primitives; +@define function compute_pool_hash(); + +@define const undefined_primitive; +@define const hash_prime; + +@define function get_prim_eq_type(); +@define function get_prim_equiv(); +@define function prim_lookup(); +@define function id_lookup(); + +@define procedure tex_def_font(); diff --git a/Build/source/texk/web2c/luatexdir/luatex.h b/Build/source/texk/web2c/luatexdir/luatex.h index aef2f355396..2ee976b478e 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.h +++ b/Build/source/texk/web2c/luatexdir/luatex.h @@ -1,69 +1,29 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, +/* luatex.h + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ -$Id $ -*/ - -/* some code array functions */ - -extern void set_math_code (integer n, halfword v, quarterword grouplevel); -extern halfword get_math_code (integer n); - -extern void set_del_code (integer n, halfword v, halfword w, quarterword grouplevel); -extern halfword get_del_code_a (integer n); -extern halfword get_del_code_b (integer n); - -extern void unsavemathcodes (quarterword grouplevel); -extern void initializemathcodes (); -extern void dumpmathcodes (); -extern void undumpmathcodes (); - -extern void set_lc_code (integer n, halfword v, quarterword grouplevel); -extern halfword get_lc_code (integer n); -extern void set_uc_code (integer n, halfword v, quarterword grouplevel); -extern halfword get_uc_code (integer n); -extern void set_sf_code (integer n, halfword v, quarterword grouplevel); -extern halfword get_sf_code (integer n); -extern void set_cat_code (integer h, integer n, halfword v, quarterword grouplevel); -extern halfword get_cat_code (integer h, integer n); - -extern void unsavetextcodes (quarterword grouplevel); -extern void unsavecatcodes (integer h,quarterword grouplevel); -extern void copy_cat_codes (int from, int to); -extern void initex_cat_codes (int h); -extern void clearcatcodestack (integer h); -extern boolean validcatcodetable (int h); - -extern void initializetextcodes (); -extern void dumptextcodes (); -extern void undumptextcodes (); - -typedef enum { - escape, left_brace, right_brace, math_shift, - tab_mark, car_ret, mac_param, sup_mark, - sub_mark, ignore, spacer, letter, - other_char, active_char, comment, invalid_char } cat_codes; +/* $Id$ */ extern void do_vf(internal_font_number tmp_f); -extern int readbinfile(FILE *f, unsigned char **b, integer *s); +extern int readbinfile(FILE * f, unsigned char **b, integer * s); #define read_tfm_file readbinfile #define read_vf_file readbinfile @@ -99,7 +59,7 @@ extern void b_test_in(); #define vf_b_open_in(f) \ open_input (&(f), kpse_vf_format, FOPEN_RBIN_MODE) -extern int open_outfile(FILE **f, char *name, char *mode); +extern int open_outfile(FILE ** f, char *name, char *mode); #define do_a_open_out(f) open_outfile(&(f),(char *)(nameoffile+1),FOPEN_W_MODE) #define do_b_open_out(f) open_outfile(&(f),(char *)(nameoffile+1),FOPEN_WBIN_MODE) @@ -111,63 +71,10 @@ extern int open_outfile(FILE **f, char *name, char *mode); extern volatile memory_word *varmem; extern halfword var_mem_min; extern halfword var_mem_max; -extern halfword get_node (integer s); -extern void free_node (halfword p, integer s) ; -extern void init_node_mem (integer r, integer s) ; -extern void dump_node_mem (void) ; -extern void undump_node_mem (void); - - -typedef enum { - find_write_file_callback = 1, - find_output_file_callback, - find_image_file_callback, - find_format_file_callback, - find_read_file_callback, open_read_file_callback, - find_ocp_file_callback, read_ocp_file_callback, - find_vf_file_callback, read_vf_file_callback, - find_data_file_callback, read_data_file_callback, - find_font_file_callback, read_font_file_callback, - find_map_file_callback, read_map_file_callback, - find_enc_file_callback, read_enc_file_callback, - find_type1_file_callback, read_type1_file_callback, - find_truetype_file_callback, read_truetype_file_callback, - find_opentype_file_callback, read_opentype_file_callback, - find_sfd_file_callback, read_sfd_file_callback, - find_pk_file_callback, read_pk_file_callback, - show_error_hook_callback, - process_input_buffer_callback, - start_page_number_callback, stop_page_number_callback, - start_run_callback, stop_run_callback, - define_font_callback, - token_filter_callback, - pre_output_filter_callback, - buildpage_filter_callback, - hpack_filter_callback, vpack_filter_callback, - char_exists_callback, - hyphenate_callback, - ligaturing_callback, - kerning_callback, - pre_linebreak_filter_callback, - linebreak_filter_callback, - post_linebreak_filter_callback, - total_callbacks } callback_callback_types; - -extern int callback_set[]; - -#define callback_defined(a) callback_set[a] - -extern int run_callback (int i, char *values, ...); -extern int run_saved_callback (int i, char *name, char *values, ...); -extern int run_and_save_callback (int i, char *values, ...); -extern void destroy_saved_callback (int i); - -extern void get_saved_lua_boolean (int i, char *name, boolean *target); -extern void get_saved_lua_number (int i, char *name, integer *target); -extern void get_saved_lua_string (int i, char *name, char **target); - -extern void get_lua_boolean (char *table, char *name, boolean *target); -extern void get_lua_number (char *table, char *name, integer *target); -extern void get_lua_string (char *table, char *name, char **target); +extern halfword get_node(integer s); +extern void free_node(halfword p, integer s); +extern void init_node_mem(integer s); +extern void dump_node_mem(void); +extern void undump_node_mem(void); #include diff --git a/Build/source/texk/web2c/luatexdir/luatex.mk b/Build/source/texk/web2c/luatexdir/luatex.mk index fdc7df211bd..6a0a5d6386d 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.mk +++ b/Build/source/texk/web2c/luatexdir/luatex.mk @@ -1,6 +1,7 @@ # Makefile fragment for pdfeTeX and web2c. --infovore@xs4all.nl. Public domain. # This fragment contains the parts of the makefile that are most likely to -# differ between releases of pdfeTeX. +# differ between releases of luatex +# $Id$ # We build luatex luatex = @LTEX@ luatex @@ -19,11 +20,12 @@ LIBXPDFSRCDIR=$(srcdir)/$(LIBXPDFDIR) LIBOBSDCOMPATDIR=../../libs/obsdcompat LIBOBSDCOMPATFSRCDIR=$(srcdir)/$(LIBOBSDCOMPATDIR) -XCPPFLAGS=-I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. -I$(LIBOBSDCOMPATFSRCDIR) -I$(LIBOBSDCOMPATFSRCDIR)/.. -I$(ZLIBSRCDIR) -I$(LIBPNGSRCDIR) -I$(LIBXPDFSRCDIR) -Dextra_version_info=`date +-%Y%m%d%H` +SVN_REV := $(shell $(srcdir)/$(luatexdir)/get_svnversion.sh $(srcdir)) + +XCPPFLAGS=-I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. -I$(LIBOBSDCOMPATFSRCDIR) -I$(LIBOBSDCOMPATFSRCDIR)/.. -I$(ZLIBSRCDIR) -I$(LIBPNGSRCDIR) -I$(LIBXPDFSRCDIR) -Dextra_version_info=`date +-%Y%m%d%H` -DSVN_REV=\"$(SVN_REV)\" Makefile: $(srcdir)/$(luatexdir)/luatex.mk -# luatex_bin = luatex ttf2afm pdftosrc luatex_bin = luatex linux_build_dir = $(HOME)/luatex/build/linux/texk/web2c @@ -36,24 +38,25 @@ $(luatexdir)/luatex.version: $(srcdir)/$(luatexdir)/luatex.web >$(luatexdir)/luatex.version # The C sources. -luatex_c = luatexini.c luatex0.c luatex1.c luatex2.c luatex3.c -luatex_o = luatexini.o luatex0.o luatex1.o luatex2.o luatex3.o luatexextra.o loadpool.o +luatex_c = luatexini.c luatex0.c +luatex_o = luatexini.o luatex0.o luatexextra.o luatex-pool.o $(luatex_o-with_synctex) # Making luatex luatex: luatexd.h $(luatex_o) $(luatexextra_o) $(luatexlibsdep) - @CXXHACKLINK@ $(luatex_o) $(luatexextra_o) $(luatexlibs) $(socketlibs) @CXXHACKLDLIBS@ @CXXLDEXTRA@ + @CXXHACKLINK@ $(luatex_o) $(luatexextra_o) $(luatexlibs) $(socketlibs) @SOCKETHACK@ @CXXHACKLDLIBS@ @CXXLDEXTRA@ # C file dependencies. $(luatex_c) luatexcoerce.h luatexd.h: luatex.p $(web2c_texmf) $(srcdir)/$(luatexdir)/luatex.defines $(srcdir)/$(luatexdir)/luatex.h $(web2c) luatex -luatexextra.c: $(luatexdir)/luatexextra.h lib/texmfmp.c +# $(luatexd.h-with_synctex) +luatexextra.c: luatexd.h $(luatexdir)/luatexextra.h lib/texmfmp.c test -d $(luatexdir) || mkdir $(luatexdir) sed s/TEX-OR-MF-OR-MP/luatex/ $(srcdir)/lib/texmfmp.c >$@ $(luatexdir)/luatexextra.h: $(luatexdir)/luatexextra.in $(luatexdir)/luatex.version test -d $(luatexdir) || mkdir $(luatexdir) sed -e s/LUATEX-VERSION/`cat $(luatexdir)/luatex.version`/ \ $(srcdir)/$(luatexdir)/luatexextra.in >$@ -loadpool.c: luatex.pool $(makecpool) +luatex-pool.c: luatex.pool $(makecpool) luatex.pool luatexdir/ptexlib.h >$@ || rm -f $@ # luatangle we need a private version of tangle @@ -83,8 +86,8 @@ luatex.p luatex.pool: luatangle $(srcdir)/$(luatexdir)/luatex.web $(srcdir)/$(lu # for developing only #luatex-org.web: $(TIE) $(luatex_ch_srcs_org) # $(TIE) -m $@ $(luatex_ch_srcs_org) -#luatex-all.web: $(TIE) $(srcdir)/$(luatexdir)/luatex.web luatex.ch -# $(TIE) -m $@ $(srcdir)/$(luatexdir)/luatex.web luatex.ch +luatex-all.web: $(TIE) $(srcdir)/$(luatexdir)/luatex.web $(srcdir)/$(luatexdir)/luatex.ch + $(TIE) -m $@ $(srcdir)/$(luatexdir)/luatex.web $(srcdir)/$(luatexdir)/luatex.ch #luatex-all.tex: luatex-all.web # $(WEAVE) luatex-all.web # echo -e '1s/ webmac/ pdfwebmac/\nw\nq' | ed $@ >/dev/null 2>&1 @@ -123,8 +126,6 @@ install-luatex: install-luatex-exec install-programs: @LTEX@ install-luatex-exec install-luatex-exec: $(luatex) $(bindir) for p in luatex; do $(INSTALL_LIBTOOL_PROG) $$p $(bindir); done - cd $(DESTDIR)$(bindir) && rm -f texlua && $(LN) luatex texlua - cd $(DESTDIR)$(bindir) && rm -f texluac && $(LN) luatex texluac # # luatex binaries archive diff --git a/Build/source/texk/web2c/luatexdir/luatex.web b/Build/source/texk/web2c/luatexdir/luatex.web index 5bd87dd7b96..df2a5372c85 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.web +++ b/Build/source/texk/web2c/luatexdir/luatex.web @@ -1,19 +1,24 @@ -% Copyright (c) 2007 Hartmut Henkel, Taco Hoekwater - -% This file is part of luaTeX. - -% luaTeX is free software; you can redistribute it and/or modify it under the -% terms of the GNU General Public License as published by the Free Software -% Foundation; either version 2 of the License, or (at your option) any later -% version. - -% luaTeX is distributed in the hope that it will be useful, but WITHOUT ANY -% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -% A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -% You should have received a copy of the GNU General Public License -% along with luaTeX; if not, write to the Free Software Foundation, Inc., -% 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +% luatex.web +% +% Copyright 2006-2009 Taco Hoekwater +% Copyright 2006-2009 Hartmut Henkel +% +% This file is part of LuaTeX. +% +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. +% +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. +% +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see . +% +% $Id$ % pdfTeX is copyright (C) 1996-2006 Han The Thanh, . % e-TeX is copyright (C) 1994,98 by Peter Breitenlohner. @@ -62,9 +67,10 @@ % Version 3.1415 preserved nonexplicit kerns, tidied up (February 1993). % Version 3.14159 allowed fontmemsize to change; bulletproofing (March 1995). % Version 3.141592 fixed \xleaders, glueset, weird alignments (December 2002). +% Version 3.1415926 was a general cleanup with minor fixes (February 2008). -% Although considerable effort has been expended to make the luaTeX program +% Although considerable effort has been expended to make the LuaTeX program % correct and reliable, no warranty is implied; the authors disclaim any % obligation or liability for damages, including but not limited to % special, indirect, or consequential damages arising out of or in @@ -177,6 +183,7 @@ complete version of \TeX\ was designed and coded by the author in late {\mc SAIL} language, for which an excellent debugging system was available. Preliminary plans to convert the {\mc SAIL} code into a form somewhat like the present ``web'' were developed by Luis Trabb~Pardo and +@^Trabb Pardo, Luis Isidoro@> the author at the beginning of 1979, and a complete implementation was created by Ignacio~A. Zabala in 1979 and 1980. The \TeX82 program, which @^Zabala Salelles, Ignacio Andr\'es@> @@ -242,15 +249,16 @@ known as `\eTeX'. @d pdftex_revision=="0" { \.{\\pdftexrevision} } @d pdftex_version_string=='-2.00.0' {current \pdfTeX\ version} @# -@d luatex_version==25 { \.{\\luatexversion} } -@d luatex_revision=="4" { \.{\\luatexrevision} } -@d luatex_version_string=='snapshot-0.25.4' {current \LuaTeX\ version} +@d luatex_version==37 { \.{\\luatexversion} } +@d luatex_revision=="0" { \.{\\luatexrevision} } +@d luatex_version_string=='snapshot-0.37.0' {current \LuaTeX\ version} @d luatex_date_info==-extra_version_info { the compile date is negated } +@d luatex_svnversion==SVN_REV { as proposed by Peter M\"unster } @# -@d luaTeX_banner=='This is LuaTeX, Version ',luatex_version_string,extra_version_info +@d LuaTeX_banner=='This is LuaTeX, Version ',luatex_version_string,extra_version_info {printed when \LuaTeX\ starts} @# -@d banner==luaTeX_banner +@d banner==LuaTeX_banner @# @d TEX==ETEX {change program name into |ETEX|} @@ -307,6 +315,7 @@ portions of the program heading. Actually the heading shown here is not quite normal: The |program| line does not mention any |output| file, because \ph\ would ask the \TeX\ user to specify a file name if |output| were specified here. +@:PASCAL H}{\ph@> @^system dependencies@> @d mtype==t@&y@&p@&e {this is a \.{WEB} coding trick:} @@ -327,6 +336,44 @@ procedure initialize; {this procedure gets things started properly} @t\4@>@@/ @t\4@>@@/ +@ Here is a workaround for the unfortunate limitation of WEB2C that +doesn't know how to deal with symbolic case labels. + +@d hlist_node_case==0 +@d vlist_node_case==1 +@d rule_node_case==2 +@d ins_node_case==3 +@d mark_node_case==4 +@d adjust_node_case==5 +@d disc_node_case==7 +@d whatsit_node_case==8 +@d math_node_case==9 +@d glue_node_case==10 +@d kern_node_case==11 +@d penalty_node_case==12 +@d unset_node_case==13 +@d margin_kern_node_case==36 + +@= +pdfassert(hlist_node_case=hlist_node); +pdfassert(vlist_node_case=vlist_node); +pdfassert(rule_node_case=rule_node); +pdfassert(ins_node_case=ins_node); +pdfassert(mark_node_case=mark_node); +pdfassert(adjust_node_case=adjust_node); +pdfassert(disc_node_case=disc_node); +pdfassert(whatsit_node_case=whatsit_node); +pdfassert(math_node_case=math_node); +pdfassert(glue_node_case=glue_node); +pdfassert(kern_node_case=kern_node); +pdfassert(penalty_node_case=penalty_node); +pdfassert(unset_node_case=unset_node); +pdfassert(margin_kern_node_case=margin_kern_node); + + + + + @ The overall \TeX\ program begins with the heading just shown, after which comes a bunch of procedure declarations and function declarations. Finally we will get to the main program, which begins with the @@ -399,8 +446,9 @@ directives shown below specify full checking and inclusion of the \PASCAL\ debugger when \TeX\ is being debugged, but they cause range checking and other redundant code to be eliminated when the production system is being generated. Arithmetic overflow will be detected in all cases. +@:PASCAL H}{\ph@> @^system dependencies@> -@^Overflow in arithmetic@> +@^overflow in arithmetic@> @= @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @@ -434,6 +482,7 @@ if the compiler wants one. (Of course, if no default mechanism is available, the |case| statements of \TeX\ will have to be laboriously extended by listing all remaining cases. People who are stuck with such \PASCAL s have, in fact, done this, successfully but not happily!) +@:PASCAL H}{\ph@> @d othercases == others: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @@ -492,9 +541,8 @@ emphasize this distinction. @d font_base=0 {smallest internal font number; must not be less than |min_quarterword|} -@d hash_size=2100 {maximum number of control sequences; it should be at most +@d hash_size=65536 {maximum number of control sequences; it should be at most about |(fix_mem_max-fix_mem_min)/10|} -@d hash_prime=1777 {a prime number equal to about 85\pct! of |hash_size|} @d ocp_base=0 {smallest internal ocp number; must not be less than |min_quarterword|} @d ocp_biggest=32767 {the real biggest ocp} @@ -515,17 +563,14 @@ emphasize this distinction. @d too_big_char=1114112 {2097152} {|biggest_char+1|} @d special_char=1114113 {2097153} {|biggest_char+2|} @d number_chars=1114112 {2097152} {|biggest_char+1|} -@d number_active_chars=65536+65536 {to reduce the memory req. only two planes } @d string_offset=2097152 @d font_biggest=5535 {the real biggest font} @d number_fonts=font_biggest-font_base+1 -@d number_math_fonts=768 -@d math_font_biggest=767 @d biggest_lang=32767 @d too_big_lang=32768 @d text_size=0 {size code for the largest size in a family} -@d script_size=256 {size code for the medium size in a family} -@d script_script_size=512 {size code for the smallest size in a family} +@d script_size=1 {size code for the medium size in a family} +@d script_script_size=2 {size code for the smallest size in a family} @ In case somebody has inadvertently made bad settings of the ``constants,'' @@ -1022,13 +1067,13 @@ begin if (test)and(fnam<>0)and(length(fnam)>0) then begin @; lua_a_open_out := do_a_open_out(f); - name_file_pointer := f; + name_file_pointer := f; end else lua_a_open_out := false; end else begin - if openoutnameok(stringcast(nameoffile+1)) then begin + if openoutnameok(stringcast(nameoffile+1)) then begin lua_a_open_out := a_open_out(f); name_file_pointer := f; end @@ -1050,13 +1095,13 @@ begin if (test)and(fnam<>0)and(length(fnam)>0) then begin @; lua_b_open_out := do_b_open_out(f); - name_file_pointer := f; + name_file_pointer := f; end else lua_b_open_out := false; end else begin - if openoutnameok(stringcast(nameoffile+1)) then begin + if openoutnameok(stringcast(nameoffile+1)) then begin lua_b_open_out := b_open_out(f); name_file_pointer := f; end @@ -1076,6 +1121,7 @@ namelength := length(fnam); flush_string @ Files can be closed with the \ph\ routine `|close(f)|', which +@:PASCAL H}{\ph@> @^system dependencies@> should be used when all input or output with respect to |f| has been completed. This makes |f| available to be opened again, if desired; and if |f| was used for @@ -1210,9 +1256,9 @@ end; function lua_input_ln(var f:alpha_file;n:quarterword;@!bypass_eoln:boolean):boolean; var lua_result:boolean; - last_ptr:integer; + last_ptr:integer; callback_id:integer; - bypass_p:boolean; + bypass_p:boolean; begin if n=0 then callback_id:=input_file_callback_id[index] @@ -1220,12 +1266,12 @@ else callback_id:=read_file_callback_id[n]; if callback_id>0 then begin last:=first; - last_ptr := first; + last_ptr := first; lua_result := run_saved_callback(callback_id,'reader','->l', addressof(last_ptr)); - if (lua_result=true)and(last_ptr<>0) then begin - last := last_ptr; - if last>max_buf_stack then max_buf_stack:=last; - lua_input_ln := true; + if (lua_result=true)and(last_ptr<>0) then begin + last := last_ptr; + if last>max_buf_stack then max_buf_stack:=last; + lua_input_ln := true; @; end else @@ -1234,7 +1280,7 @@ if callback_id>0 then begin else begin bypass_p := bypass_eoln; {this is for -Wextra} lua_result := input_ln(f,bypass_p); - if lua_result=true then begin + if lua_result=true then begin lua_input_ln := true; @; end @@ -1251,8 +1297,8 @@ if last>=first then begin last_ptr := first; lua_result := run_callback(callback_id, 'l->l', (last-first), addressof(last_ptr)); if (lua_result=true)and(last_ptr<>0) then begin - last := last_ptr; - if last>max_buf_stack then max_buf_stack:=last; + last := last_ptr; + if last>max_buf_stack then max_buf_stack:=last; end; end; end @@ -1271,6 +1317,7 @@ is considered an output file the file variable is |term_out|. @ Here is how to open the terminal files in \ph. The `\.{/I}' switch suppresses the first |get|. +@:PASCAL H}{\ph@> @^system dependencies@> @d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input} @@ -1288,6 +1335,7 @@ issue an unexpected error message). The third, |wake_up_terminal|, is supposed to revive the terminal if the user has disabled it by some instruction to the operating system. The following macros show how these operations can be specified in \ph: +@:PASCAL H}{\ph@> @^system dependencies@> @d update_terminal == break(term_out) {empty the terminal output buffer} @@ -1416,6 +1464,7 @@ into some integer greater than~|biggest_char|. Some \PASCAL\ compilers won't pack integers into a single byte unless the integers lie in the range |-128..127|. To accommodate such systems we access the string pool only via macros that can easily be redefined. +@^system dependencies@> @d si(#) == # {convert from |ASCII_code| to |packed_ASCII_code|} @d so(#) == # {convert from |packed_ASCII_code| to |ASCII_code|} @@ -1466,12 +1515,12 @@ end @p procedure string_room(t:integer); begin - str_room(t); + str_room(t); end; @# procedure append_pool_char(c:ASCII_code); begin - append_char(c); + append_char(c); end; @@ -1514,37 +1563,37 @@ begin if b<@"80 then a := b else if b>=@"F0 then begin - a := (b-@"F0) * 64; - b := buffer[k+1]; - test_sequence_byte(b); - a := (a + (b-128)) * 64; - b := buffer[k+2]; - test_sequence_byte(b); - a := (a + (b-128)) * 64; - b := buffer[k+3]; - test_sequence_byte(b); - a := a + (b-128); + a := (b-@"F0) * 64; + b := buffer[k+1]; + test_sequence_byte(b); + a := (a + (b-128)) * 64; + b := buffer[k+2]; + test_sequence_byte(b); + a := (a + (b-128)) * 64; + b := buffer[k+3]; + test_sequence_byte(b); + a := a + (b-128); end else if b>=@"E0 then begin - a := (b-@"E0) * 64; - b := buffer[k+1]; - test_sequence_byte(b); - a := (a + (b-128)) * 64; - b := buffer[k+2]; - test_sequence_byte(b); - a := a + (b-128); + a := (b-@"E0) * 64; + b := buffer[k+1]; + test_sequence_byte(b); + a := (a + (b-128)) * 64; + b := buffer[k+2]; + test_sequence_byte(b); + a := a + (b-128); end else if b>=@"C0 then begin - a := (b-@"C0) * 64; - b := buffer[k+1]; - test_sequence_byte(b); - a := a + (b-128); + a := (b-@"C0) * 64; + b := buffer[k+1]; + test_sequence_byte(b); + a := a + (b-128); end else begin { NI: this is an encoding error } - print_err("Buffer contains an invalid utf-8 sequence"); + print_err("Buffer contains an invalid utf-8 sequence"); @.Text line contains...@> - help2("A funny symbol somehow ended up in the input buffer.")@/ - ("Just continue, I'll change it to 0xFFFD.");@/ + help2("A funny symbol somehow ended up in the input buffer.")@/ + ("Just continue, I'll change it to 0xFFFD.");@/ deletions_allowed:=false; error; deletions_allowed:=true; a:=@"FFFD; end; @@ -1601,7 +1650,7 @@ if ss then goto not_found; end else @@ -1675,8 +1724,8 @@ extended character set recommended in {\sl The \TeX book\/} would, for example, be `|k in [0,@'10..@'12,@'14,@'15,@'33,@'177..@'377]|'. If character |k| cannot be printed, and |k<@'200|, then character |k+@'100| or |k-@'100| must be printable; moreover, ASCII codes |[@'41..@'46, -@'60..@'71, @'141..@'146, @'160..@'171]| must be printable. -Thus, at least 80 printable characters are needed. +@'60..@'71, @'136, @'141..@'146, @'160..@'171]| must be printable. +Thus, at least 81 printable characters are needed. @:TeXbook}{\sl The \TeX book@> @^character set dependencies@> @^system dependencies@> @@ -1878,32 +1927,32 @@ begin if b<=@"7F then a := b else if b>=@"F0 then begin - a := (b-@"F0) * 64; - b := str_pool[t+1]; - a := (a + (b-128)) * 64; - b := str_pool[t+2]; - a := (a + (b-128)) * 64; - b := str_pool[t+3]; - a := a + (b-128); + a := (b-@"F0) * 64; + b := str_pool[t+1]; + a := (a + (b-128)) * 64; + b := str_pool[t+2]; + a := (a + (b-128)) * 64; + b := str_pool[t+3]; + a := a + (b-128); end else if b>=@"E0 then begin - a := (b-@"E0) * 64; - b := str_pool[t+1]; - a := (a + (b-128)) * 64; - b := str_pool[t+2]; - a := a + (b-128); + a := (b-@"E0) * 64; + b := str_pool[t+1]; + a := (a + (b-128)) * 64; + b := str_pool[t+2]; + a := a + (b-128); end else if b>=@"C0 then begin - a := (b-@"C0) * 64; - b := str_pool[t+1]; - a := a + (b-128); + a := (b-@"C0) * 64; + b := str_pool[t+1]; + a := a + (b-128); end else begin { NI: this is an encoding error } - wlog_ln('! Pool contains an invalid utf-8 sequence'); - wterm_ln('! Pool contains an invalid utf-8 sequence'); + wlog_ln('! Pool contains an invalid utf-8 sequence'); + wterm_ln('! Pool contains an invalid utf-8 sequence'); @.Text line contains...@> - help2("A funny symbol somehow ended up in the string pool.")@/ - ("Just continue, I'll change it to 0xFFFD.");@/ + help2("A funny symbol somehow ended up in the string pool.")@/ + ("Just continue, I'll change it to 0xFFFD.");@/ deletions_allowed:=false; error; deletions_allowed:=true; a:=@"FFFD; end; @@ -1941,7 +1990,7 @@ else if s=@"110000 then - print_char(s-@"110000) + print_char(s-@"110000) else begin print_char(@"F0 + (s div @"40000)); print_char(@"80 + ((s mod @"40000) div @"1000)); @@ -1955,8 +2004,8 @@ j:=str_start_macro(s); while j= -procedure print_int(@!n:integer); {prints an integer in decimal form} +procedure print_int(@!n:longinteger); {prints an integer in decimal form} var k:0..23; {index to current digit; we assume that $|n|<10^{23}$} -@!m:integer; {used to negate |n| in possibly dangerous cases} +@!m:longinteger; {used to negate |n| in possibly dangerous cases} begin k:=0; if n<0 then begin print_char("-"); @@ -2302,6 +2351,11 @@ begin help1(a); end; @# +procedure dohelp0; +begin + help0; +end; +@# procedure do_print_err (s:str_number); begin print_err(s); @@ -2529,15 +2583,19 @@ end; @= procedure lua_norm_error(@!s:str_number); {lua found a problem} +var saved_new_line_char: integer; begin +saved_new_line_char:=new_line_char; +new_line_char:=10; print_err("LuaTeX error "); print(s); help2("The lua interpreter ran into a problem, so the")@/ ("remainder of this lua chunk will be ignored."); error; +new_line_char:=saved_new_line_char; end; procedure lua_fatal_error(@!s:str_number); {lua found a problem} -begin normalize_selector; +begin new_line_char:=10; normalize_selector; print_err("LuaTeX fatal error "); print(s); succumb; end; @@ -2599,10 +2657,10 @@ a way to make |interrupt| nonzero using the \PASCAL\ debugger. @= @!interrupt:integer; {should \TeX\ pause for instructions?} @!OK_to_interrupt:boolean; {should interrupts be observed?} -@!detokenized_line:boolean; {indicates this is a 'detokenized' input line } -@!line_catcode_table:integer; {the used catcode table for input lines} -@!local_catcode_table:boolean; {the used catcode table for input lines} @!static_int_base:integer; {C version of |int_base|} +@!static_glue_base:integer; {C version of |glue_base|} +@!static_dimen_base:integer; {C version of |dimen_base|} +@!static_local_base:integer; {C version of |local_base|} @ @p procedure check_interrupt; begin @@ -2611,8 +2669,7 @@ end; @ @= -interrupt:=0; OK_to_interrupt:=true; detokenized_line:=false; -line_catcode_table:=0; local_catcode_table:=false; +interrupt:=0; OK_to_interrupt:=true; @ When an interrupt has been detected, the program goes into its highest interaction level and lets the user have nearly the full flexibility of @@ -2726,7 +2783,7 @@ meters); two such quantities can be added without overflow on a 32-bit computer. The present implementation of \TeX\ does not check for overflow when -@^Overflow in arithmetic@> +@^overflow in arithmetic@> dimensions are added or subtracted. This could be done by inserting a few dozen tests of the form `\ignorespaces|if x>=@'10000000000 then @t\\{report\_overflow}@>|', but the chance of overflow is so remote that @@ -3521,8 +3578,6 @@ end; of |mem| is a nonempty, doubly-linked circular list of empty nodes, pointed to by the roving pointer |rover|. -@d temp_node==46 -@d temp_node_size==2 @d vmem(#) == varmem[#] @d vlink(#) == vmem(#).hh.rh {the |link| field of a memory word} @d vinfo(#) == vmem(#).hh.lh {the |info| field of a memory word} @@ -3625,8 +3680,6 @@ glue should stretch or shrink or remain rigid; and |glue_order(p)| specifies the order of infinity to which glue setting applies (|normal|, |sfi|, |fil|, |fill|, or |filll|). The |subtype| field is not used. -@d hlist_node=0 {|type| of hlist nodes} -@d box_node_size=8 {number of words to allocate for a box node} @d width_offset=2 {position of |width| field in a box node} @d depth_offset=3 {position of |depth| field in a box node} @d height_offset=4 {position of |height| field in a box node} @@ -3642,9 +3695,7 @@ specifies the order of infinity to which glue setting applies (|normal|, @d normal=0 {the most common case when several cases are named} @d stretching = 1 {glue setting applies to the stretch components} @d shrinking = 2 {glue setting applies to the shrink components} -@d glue_offset = 7 {position of |glue_set| in a box node} -@d glue_set(#) == vmem(#+glue_offset).gr - {a word of type |glue_ratio| for glue setting} +@d glue_set(#) == vmem(#+7).gr {a word of type |glue_ratio| for glue setting} @ The |new_null_box| function returns a pointer to an |hlist_node| in which all subfields have the values corresponding to `\.{\\hbox\{\}}'. @@ -3661,8 +3712,6 @@ end; @ A |vlist_node| is like an |hlist_node| in all respects except that it contains a vertical list. -@d vlist_node=1 {|type| of vlist nodes} - @ A |rule_node| stands for a solid black rectangle; it has |width|, |depth|, and |height| fields just as in an |hlist_node|. However, if any of these dimensions is $-2^{30}$, the actual value will be determined @@ -3670,8 +3719,6 @@ by running the rule up to the boundary of the innermost enclosing box. This is called a ``running dimension.'' The |width| is never running in an hlist; the |height| and |depth| are never running in a~vlist. -@d rule_node=2 {|type| of rule nodes} -@d rule_node_size=6 {number of words to allocate for a rule node} @d null_flag==-@'10000000000 {$-2^{30}$, signifies a missing item} @d is_running(#) == (#=null_flag) {tests for a running dimension} @d rule_dir(#)==vlink(#+5) @@ -3700,8 +3747,6 @@ will be used if this insertion floats to a subsequent page after a split insertion of the same class. There is one more field, the |ins_ptr|, which points to the beginning of the vlist for the insertion. -@d ins_node=3 {|type| of insertion nodes} -@d ins_node_size=6 {number of words to allocate for an insertion} @d float_cost(#)==vmem(#+2).int {the |floating_penalty| to be used} @d ins_ptr(#)==vinfo(#+5) {the vertical list to be inserted} @d split_top_ptr(#)==vlink(#+5) {the |split_top_skip| to be used} @@ -3710,8 +3755,6 @@ split insertion of the same class. There is one more field, the of a token list that contains the user's \.{\\mark} text. In addition there is a |mark_class| field that contains the mark class. -@d mark_node=4 {|type| of a mark node} -@d mark_node_size=3 {number of words to allocate for a mark node} @d mark_ptr(#)==vlink(#+2) {head of the token list for a mark} @d mark_class(#)==vinfo(#+2) {the mark class} @@ -3721,8 +3764,6 @@ vertical list; i.e., it is used to implement \TeX's `\.{\\vadjust}' operation. The |adjust_ptr| field points to the vlist containing this material. -@d adjust_node=5 {|type| of an adjust node} -@d adjust_node_size=3 @d adjust_pre == subtype {pre-adjustment?} @d adjust_ptr(#)==vlink(#+2) {vertical list to be moved out of horizontal list} @#{|append_list| is used to append a list to |tail|} @@ -3750,8 +3791,6 @@ and their base (through |make_accent|), and math nucleus items (in the conversion from |mlist| to |hlist|). -@d glyph_node_size=5 -@d glyph_node=33 {|type| of a glyph node} @d is_char_node(#) == ((#<>null)and(type(#)=glyph_node)) @d font(#)==vlink(#+2) {the font code in a |glyph_node|} @d character(#)==vinfo(#+2) {the character code in a |glyph_node|} @@ -3854,8 +3893,6 @@ decides to make the break, and the discretionary node will disappear at that time; thus, the output routine sees only discretionaries that were not chosen. -@d disc_node=7 {|type| of a discretionary node} -@d disc_node_size=10 @d automatic_disc=2 @d syllable_disc=3 @d disc_type==subtype {the kind of discretionary} @@ -3889,15 +3926,11 @@ The present implementation of \TeX\ treats the features associated with illustrate how such routines might be coded. We shall defer further discussion of extensions until the end of this program. -@d whatsit_node=8 {|type| of special extension nodes} - @ A |math_node|, which occurs only in horizontal lists, appears before and after mathematical formulas. The |subtype| field is |before| before the formula and |after| after it. There is a |surround| field, which represents the amount of surrounding space inserted by \.{\\mathsurround}. -@d math_node=9 {|type| of a math node} -@d math_node_size=3 @d surround(#)==vlink(#+2) @d before=0 {|subtype| for math node that introduces a formula} @d after=1 {|subtype| for math node that winds up a formula} @@ -3944,8 +3977,6 @@ instead of scaled \.{pt}); and |cond_math_glue| denotes the `\.{\\nonscript}' feature that cancels the glue node immediately following if it appears in a subscript. -@d glue_node=10 {|type| of node that points to a glue specification} -@d glue_node_size=3 @d cond_math_glue=98 {special |subtype| to suppress glue in the next node} @d mu_glue=99 {|subtype| for math glue} @d a_leaders=100 {|subtype| for aligned leaders} @@ -3968,8 +3999,6 @@ fields called |stretch_order| and |shrink_order|; these contain the orders of infinity (|normal|, |sfi|, |fil|, |fill|, or |filll|) corresponding to the stretch and shrink values. -@d glue_spec_size=4 {number of words to allocate for a glue specification} -@d glue_spec_node=43 @d glue_ref_count(#) == vlink(#+3) {reference count of a glue specification} @d stretch(#) == vlink(#+1) {the stretchability of this glob of glue} @d shrink(#) == vinfo(#+1) {the shrinkability of this glob of glue} @@ -4018,7 +4047,7 @@ glue_ptr(p):=q; incr(glue_ref_count(q)); new_glue:=p; end; -@ Still another subroutine is needed: this one is sort of a combination +@ Still another subroutine is needed: This one is sort of a combination of |new_param_glue| and |new_glue|. It creates a glue node for one of the current glue parameters, but it makes a fresh copy of the glue specification, since that specification will probably be subject to change, @@ -4043,14 +4072,10 @@ kerns inserted from font information or math mode calculations) or |explicit| (for kerns inserted from non-math accents) or |mu_glue| (for kerns inserted from \.{\\mkern} specifications in math formulas). -@d kern_node=11 {|type| of a kern node} -@d kern_node_size=3 @d explicit=1 {|subtype| of kern nodes from \.{\\kern} and \.{\\/}} @d acc_kern=2 {|subtype| of kern nodes from accents} @# {memory structure for marginal kerns} -@d margin_kern_node = 32 -@d margin_kern_node_size = 4 @d margin_char(#) == vlink(#+3) @# {|subtype| of marginal kerns} @@ -4084,8 +4109,6 @@ treated as infinity, and no break will be allowed for such high values. Similarly, any penalty |<=-10000| is treated as negative infinity, and a break will be forced. -@d penalty_node=12 {|type| of a penalty node} -@d penalty_node_size=3 {has to be the same as |glue_node_size|} @d inf_penalty=inf_bad {``infinite'' penalty value} @d eject_penalty=-inf_penalty {``negatively infinite'' penalty value} @d penalty(#) == vlink(#+2) {the added cost of breaking a list here} @@ -4113,8 +4136,7 @@ The |subtype| field is called |span_count|; an unset box typically contains the data for |qo(span_count)+1| columns. Unset nodes will be changed to box nodes when alignment is completed. -@d unset_node=13 {|type| for an unset node} -@d glue_stretch(#)==vmem(#+glue_offset).sc {total stretch in an unset node} +@d glue_stretch(#)==vmem(#+7).sc {total stretch in an unset node} @d glue_shrink==shift_amount {total shrink in an unset node} @d span_count==subtype {indicates the number of spanned columns} @@ -4133,32 +4155,23 @@ the \.{WEB} macro definitions above, so that format changes will leave \TeX's other algorithms intact. @^system dependencies@> -@* \[11] Memory layout. -Some areas of |mem| are dedicated to fixed usage, since static allocation is -more efficient than dynamic allocation when we can get away with it. For -example, |zero_glue| used for glue that is `\.{0pt plus 0pt minus 0pt}'. The -following macro definitions accomplish the static allocation by giving -symbolic names to the fixed positions. - -@d zero_glue==0 {specification for \.{0pt plus 0pt minus 0pt}} -@d sfi_glue==zero_glue+glue_spec_size {\.{0pt plus 1fi minus 0pt}} -@d fil_glue==sfi_glue+glue_spec_size {\.{0pt plus 1fil minus 0pt}} -@d fill_glue==fil_glue+glue_spec_size {\.{0pt plus 1fill minus 0pt}} -@d ss_glue==fill_glue+glue_spec_size {\.{0pt plus 1fil minus 1fil}} -@d fil_neg_glue==ss_glue+glue_spec_size {\.{0pt plus -1fil minus 0pt}} -@d page_ins_head==fil_neg_glue+glue_spec_size {list of insertion data for current page} -@d contrib_head==page_ins_head+temp_node_size {list of items not yet on current page} -@d page_head==contrib_head+temp_node_size {list for current page} -@d temp_head==page_head+temp_node_size {head of a temporary list of some kind} -@d hold_head==temp_head+temp_node_size {head of a temporary list of another kind} -@d adjust_head==hold_head+temp_node_size {head of adjustment list returned by |hpack|} -@d pre_adjust_head==adjust_head+temp_node_size {head of pre-adjustment list returned by |hpack|} -@d active==pre_adjust_head+temp_node_size {head of active list in |line_break|} -@d align_head==active+active_node_size {head of preamble list for alignments} -@d end_span==align_head+temp_node_size {tail of spanned-width lists} -@d begin_point==end_span+span_node_size {left-side dot for words in hyphenation} -@d end_point==begin_point+glyph_node_size {right-side dot for words in hyphenation} -@d var_mem_stat_max==(end_point+glyph_node_size-1) {largest statically allocated word in the variable-size |mem|} +@* \[11] Memory layout. + +Some areas of |mem| are dedicated to fixed usage, since static +allocation is more efficient than dynamic allocation when we can get +away with it. For example, |zero_glue| used for glue that is `\.{0pt +plus 0pt minus 0pt}'. A few C macro definitions accomplish the static +allocation of node memory locations by giving symbolic names to fixed +positions. The list of imported constant identifiers is: |zero_glue|, +|sfi_glue|, |fil_glue|, |fill_glue|, |ss_glue|, |fil_neg_glue| (all +glue specs), |page_ins_head| (list of insertion data for current +page), |contrib_head| (list of insertion data for current page), +|page_head| (list for current page), |temp_head| and |hold_head| +(temporary lists), |adjust_head| (head of adjustment list returned by +|hpack|), |pre_adjust_head| (head of pre-adjustment list returned by +|hpack|), |align_head| (head of alignment preamble), and +|end_span| (tail of spanned-width lists). + @= garbage:pointer; {head of a junk list, write only} @@ -4176,52 +4189,7 @@ initializing itself the slow~way. @ @= procedure init_link_heads;forward; -init_node_mem(var_mem_stat_max,500); -glue_ref_count(zero_glue):=null+1; width(zero_glue):=0; -type(zero_glue):=glue_spec_node; vlink(zero_glue):=null; -stretch(zero_glue):=0; stretch_order(zero_glue):=normal;@/ -shrink(zero_glue):=0; shrink_order(zero_glue):=normal;@/ -glue_ref_count(sfi_glue):=null+1; width(sfi_glue):=0; -type(sfi_glue):=glue_spec_node; vlink(sfi_glue):=null; -stretch(sfi_glue):=0; stretch_order(sfi_glue):=sfi;@/ -shrink(sfi_glue):=0; shrink_order(sfi_glue):=normal;@/ -glue_ref_count(fil_glue):=null+1; width(fil_glue):=0; -type(fil_glue):=glue_spec_node; vlink(fil_glue):=null; -stretch(fil_glue):=unity; stretch_order(fil_glue):=fil;@/ -shrink(fil_glue):=0; shrink_order(fil_glue):=normal;@/ -glue_ref_count(fill_glue):=null+1; width(fill_glue):=0; -type(fill_glue):=glue_spec_node; vlink(fill_glue):=null; -stretch(fill_glue):=unity; stretch_order(fill_glue):=fill;@/ -shrink(fill_glue):=0; shrink_order(fill_glue):=normal;@/ -glue_ref_count(ss_glue):=null+1; width(ss_glue):=0; -type(ss_glue):=glue_spec_node; vlink(ss_glue):=null; -stretch(ss_glue):=unity; stretch_order(ss_glue):=fil;@/ -shrink(ss_glue):=unity; shrink_order(ss_glue):=fil;@/ -glue_ref_count(fil_neg_glue):=null+1; width(fil_neg_glue):=0; -type(fil_neg_glue):=glue_spec_node; vlink(fil_neg_glue):=null; -stretch(fil_neg_glue):=-unity; stretch_order(fil_neg_glue):=fil;@/ -shrink(fil_neg_glue):=0; shrink_order(fil_neg_glue):=normal;@/ -{initialize node list heads} -vinfo(page_ins_head):=0; vlink(page_ins_head):=null; alink(page_ins_head):=null; -vinfo(contrib_head):=0; vlink(contrib_head):=null; alink(contrib_head):=null; -vinfo(page_head):=0; vlink(page_head):=null; alink(page_head):=null; -vinfo(temp_head):=0; vlink(temp_head):=null; alink(temp_head):=null; -vinfo(hold_head):=0; vlink(hold_head):=null; alink(hold_head):=null; -vinfo(adjust_head):=0; vlink(adjust_head):=null; alink(adjust_head):=null; -vinfo(pre_adjust_head):=0; vlink(pre_adjust_head):=null; alink(pre_adjust_head):=null; -vinfo(active):=0; vlink(active):=null; alink(active):=null; -vinfo(align_head):=0; vlink(align_head):=null; alink(align_head):=null; -vinfo(end_span):=0; vlink(end_span):=null; alink(end_span):=null; -type(begin_point):=glyph_node; subtype(begin_point):=0; vlink(begin_point):=null; -vinfo(begin_point+1):=null; alink(begin_point):=null; -font(begin_point):=0; character(begin_point):='.'; -vinfo(begin_point+3):=0; vlink(begin_point+3):=0; -vinfo(begin_point+4):=0; vlink(begin_point+4):=0; -type(end_point):=glyph_node; subtype(end_point):=0; vlink(end_point):=null; -vinfo(end_point+1):=null; alink(end_point):=null; -font(end_point):=0; character(end_point):='.'; -vinfo(end_point+3):=0; vlink(end_point+3):=0; -vinfo(end_point+4):=0; vlink(end_point+4):=0; +init_node_mem(500); avail:=null; fix_mem_end:=0; init_list_heads; @; @@ -4268,11 +4236,21 @@ sort of ``complicated'' are indicated only by printing `\.{[]}'. @p procedure print_font_identifier(f: internal_font_number); +var fonttext:str_number; begin if pdf_font_blink(f) = null_font then - print_esc(font_id_text(f)) + fonttext := font_id_text(f) else - print_esc(font_id_text(pdf_font_blink(f))); + fonttext := font_id_text(pdf_font_blink(f)); + if fonttext>0 then + print_esc(fonttext) + else begin + print_esc("FONT"); + if pdf_font_blink(f) = null_font then + print_int(f) + else + print_int(pdf_font_blink(f)); + end; if pdf_tracing_fonts > 0 then begin print(" ("); print_font_name(f); @@ -4314,17 +4292,7 @@ begin while p<>null do end; @ @= -case type(p) of -hlist_node,vlist_node,ins_node,whatsit_node,mark_node,adjust_node, - unset_node: print("[]"); -rule_node: print_char("|"); -glue_node: if glue_ptr(p)<>zero_glue then print_char(" "); -math_node: print_char("$"); -disc_node: begin short_display(vlink(pre_break(p))); - short_display(vlink(post_break(p)));@/ - end; -othercases do_nothing -endcases +print_short_node_contents(p) @ The |show_node_list| routine requires some auxiliary subroutines: one to print a font-and-character combination, one to print a token list without @@ -4393,8 +4361,7 @@ end; @ We also need to declare some procedures that appear later in this documentation. -@p @@; -@ +@p @ @ Since boxes can be inside of boxes, |show_node_list| is inherently recursive, @^recursion@> @@ -4402,12 +4369,6 @@ up to a given maximum number of levels. The history of nesting is indicated by the current string, which will be printed at the beginning of each line; the length of this string, namely |cur_length|, is the depth of nesting. -Recursive calls on |show_node_list| therefore use the following pattern: - -@d node_list_display(#)== - begin append_char("."); show_node_list(#); flush_char; - end {|str_room| need not be checked; see |show_box| below} - @ A global variable called |depth_threshold| is used to record the maximum depth of nesting for which |show_node_list| will show information. If we have |depth_threshold=0|, for example, only the top level information will @@ -4419,224 +4380,6 @@ be given and no sublists will be traversed. Another global variable, called @!depth_threshold : integer; {maximum nesting depth in box displays} @!breadth_max : integer; {maximum number of items shown at the same list level} -@ Now we are ready for |show_node_list| itself. This procedure has been -written to be ``extra robust'' in the sense that it should not crash or get -into a loop even if the data structures have been messed up by bugs in -the rest of the program. You can safely call its parent routine -|show_box(p)| for arbitrary values of |p| when you are debugging \TeX. -However, in the presence of bad data, the procedure may -@^dirty \PASCAL@>@^debugging@> -fetch a |memory_word| whose variant is different from the way it was stored; -for example, it might try to read |mem[p].hh| when |mem[p]| -contains a scaled integer, if |p| is a pointer that has been -clobbered or chosen at random. - -@p procedure show_node_list(@!p:integer); {prints a node list symbolically} -label exit; -var n:integer; {the number of items already printed at this level} -@!g:real; {a glue ratio, as a floating point number} -begin if cur_length>depth_threshold then - begin if p>null then print(" []"); - {indicate that there's been some truncation} - return; - end; -n:=0; -while p<>null do - begin print_ln; print_current_string; {display the nesting history} - if tracing_online<-2 then print_int(p); - incr(n); if n>breadth_max then {time to stop} - begin print("etc."); return; -@.etc@> - end; - @; - p:=vlink(p); - end; -exit: -end; - -@ @= -if is_char_node(p) then begin - print_font_and_char(p); - if is_ligature(p) then @; - end -else case type(p) of - hlist_node,vlist_node,unset_node: @; - rule_node: @; - ins_node: @; - whatsit_node: @; - glue_node: @; - margin_kern_node: begin - print_esc("kern"); - print_scaled(width(p)); - if subtype(p) = left_side then - print(" (left margin)") - else - print(" (right margin)"); - end; - kern_node: @; - math_node: @; - penalty_node: @; - disc_node: @; - mark_node: @; - adjust_node: @; - @t\4@>@@; - othercases print("Unknown node type!") - endcases - -@ @= -begin if type(p)=hlist_node then print_esc("h") -else if type(p)=vlist_node then print_esc("v") -else print_esc("unset"); -print("box("); print_scaled(height(p)); print_char("+"); -print_scaled(depth(p)); print(")x"); print_scaled(width(p)); -if type(p)=unset_node then - @ -else begin @; - if shift_amount(p)<>0 then - begin print(", shifted "); print_scaled(shift_amount(p)); - end; - print(", direction "); print_dir(box_dir(p)); - end; -{|pdfassert(list_ptr(p)<>0);|} -node_list_display(list_ptr(p)); {recursive call} -end - -@ @= -begin if span_count(p)<>min_quarterword then - begin print(" ("); print_int(qo(span_count(p))+1); - print(" columns)"); - end; -if glue_stretch(p)<>0 then - begin print(", stretch "); print_glue(glue_stretch(p),glue_order(p),0); - end; -if glue_shrink(p)<>0 then - begin print(", shrink "); print_glue(glue_shrink(p),glue_sign(p),0); - end; -end - -@ The code will have to change in this place if |glue_ratio| is -a structured type instead of an ordinary |real|. Note that this routine -should avoid arithmetic errors even if the |glue_set| field holds an -arbitrary random value. The following code assumes that a properly -formed nonzero |real| number has absolute value $2^{20}$ or more when -it is regarded as an integer; this precaution was adequate to prevent -floating point underflow on the author's computer. -@^system dependencies@> -@^dirty \PASCAL@> - -@= -g:=float(glue_set(p)); -if (g<>float_constant(0))and(glue_sign(p)<>normal) then - begin print(", glue set "); - if glue_sign(p)=shrinking then print("- "); - if abs(vmem(p+glue_offset).int)<@'4000000 then print("?.?") - else if abs(g)>float_constant(20000) then - begin if g>float_constant(0) then print_char(">") - else print("< -"); - print_glue(20000*unity,glue_order(p),0); - end - else print_glue(round(unity*g),glue_order(p),0); -@^real multiplication@> - end - -@ @= -begin print_esc("rule("); print_rule_dimen(height(p)); print_char("+"); -print_rule_dimen(depth(p)); print(")x"); print_rule_dimen(width(p)); -end - -@ @= -begin print_esc("insert"); print_int(qo(subtype(p))); -print(", natural size "); print_scaled(height(p)); -print("; split("); print_spec(split_top_ptr(p),0); -print_char(","); print_scaled(depth(p)); -print("); float cost "); print_int(float_cost(p)); -node_list_display(ins_ptr(p)); {recursive call} -end - -@ @= -if subtype(p)>=a_leaders then @ -else begin print_esc("glue"); - if subtype(p)<>normal then - begin print_char("("); - if subtype(p)cond_math_glue then - begin print_char(" "); - if subtype(p)= -begin print_esc(""); -if subtype(p)=c_leaders then print_char("c") -else if subtype(p)=x_leaders then print_char("x"); -print("leaders "); print_spec(glue_ptr(p),0); -node_list_display(leader_ptr(p)); {recursive call} -end - -@ An ``explicit'' kern value is indicated implicitly by an explicit space. - -@= -if subtype(p)<>mu_glue then - begin print_esc("kern"); - if subtype(p)<>normal then print_char(" "); - print_scaled(width(p)); - if subtype(p)=acc_kern then print(" (for accent)"); -@.for accent@> - end -else begin print_esc("mkern"); print_scaled(width(p)); print("mu"); - end - -@ @= -begin print_esc("math"); -if subtype(p)=before then print("on") -else print("off"); -if width(p)<>0 then - begin print(", surrounded "); print_scaled(width(p)); - end; -end - -@ @= -begin print(" (ligature "); -if is_leftboundary(p) then print_char("|"); -font_in_short_display:=font(p); short_display(lig_ptr(p)); -if is_rightboundary(p) then print_char("|"); -print_char(")"); -end - -@ @= -begin print_esc("penalty "); print_int(penalty(p)); -end - -@ The |post_break| list of a discretionary node is indicated by a prefixed -`\.{\char'174}' instead of the `\..' before the |pre_break| list. - -@= -begin print_esc("discretionary"); -if vlink(no_break(p))<>null then - begin print(" replacing "); node_list_display(vlink(no_break(p))); - end; -node_list_display(vlink(pre_break(p))); {recursive call} -append_char("|"); show_node_list(vlink(post_break(p))); flush_char; {recursive call} -end - -@ @= -begin print_esc("mark"); -if mark_class(p)<>0 then - begin print_char("s"); print_int(mark_class(p)); - end; -print_mark(mark_ptr(p)); -end - -@ @= -begin print_esc("vadjust"); if adjust_pre(p) <> 0 then print(" pre "); -node_list_display(adjust_ptr(p)); {recursive call} -end @ The recursive machinery is started by calling |show_box|. @^recursion@> @@ -4830,7 +4573,8 @@ expanded by `\.{\\the}'. @d char_given=min_internal {character code defined by \.{\\chardef}} @d math_given=char_given+1 {math code defined by \.{\\mathchardef}} @d omath_given=math_given+1 {math code defined by \.{\\omathchardef}} -@d last_item=omath_given+1 {most recent item ( \.{\\lastpenalty}, +@d xmath_given=omath_given+1 {math code defined by \.{\\Umathchardef}} +@d last_item=xmath_given+1 {most recent item ( \.{\\lastpenalty}, \.{\\lastkern}, \.{\\lastskip} )} @d max_non_prefixed_command=last_item {largest command code that can't be \.{\\global}} @@ -4874,22 +4618,30 @@ break down otherwise. \.{\\insertpenalties} )} @d set_box_dimen=set_page_int+1 {change dimension of box ( \.{\\wd}, \.{\\ht}, \.{\\dp} )} -@d set_shape=set_box_dimen+1 +@d set_tex_shape=set_box_dimen+1 {specify fancy paragraph shape ( \.{\\parshape} )} -@d def_code=set_shape+1 +@d set_etex_shape=set_tex_shape+1 + {specify etex specials ( \.{\\interlinepenalties}, etc.~)} +@d def_char_code=set_etex_shape+1 {define a character code ( \.{\\catcode}, etc.~)} -@d extdef_code=def_code+1 +@d def_del_code=def_char_code+1 + {define a delimiter code ( \.{\\delcode})} +@d extdef_math_code=def_del_code+1 {define an extended character code ( \.{\\omathcode}, etc.~)} -@d def_family=extdef_code+1 +@d extdef_del_code=extdef_math_code+1 + {define an extended delimiter code ( \.{\\odelcode}, etc.~)} +@d def_family=extdef_del_code+1 {declare math fonts ( \.{\\textfont}, etc.~)} -@d set_font=def_family+1 +@d set_math_param=def_family+1 + {declare math parameters ( \.{\\Umathquad}, etc.~)} +@d set_font=set_math_param+1 {set current font ( font identifiers )} @d def_font=set_font+1 {define a font file ( \.{\\font} )} @d register=def_font+1 {internal register ( \.{\\count}, \.{\\dimen}, etc.~)} @d assign_box_dir=register+1 {(\.{\\boxdir})} -@d assign_dir=register+2 {(\.{\\pagedir}, \.{\\textdir})} +@d assign_dir=register+2 {(\.{\\pagedir}, \.{\\bodydir}, \.{\\pardir}, \.{\\textdir}), \.{\\mathdir}} @d max_internal=assign_dir {the largest code that can follow \.{\\the}} @d advance=max_internal+1 @@ -4916,7 +4668,9 @@ break down otherwise. {define level of interaction ( \.{\\batchmode}, etc.~)} @d letterspace_font=set_interaction+1 {letterspace a font ( \.{\\letterspacefont} )} -@d set_ocp=letterspace_font+1 +@d pdf_copy_font=letterspace_font+1 + {create a new font instance ( \.{\\pdfcopyfont} )} +@d set_ocp=pdf_copy_font+1 {Place a translation process in the stream} @d def_ocp=set_ocp+1 {Define and load a translation process} @@ -5076,7 +4830,7 @@ user's output routine. A seventh quantity, |eTeX_aux|, is used by the extended features \eTeX. In math mode it is known as |delim_ptr| and points to the most -recent |left_noad| or |middle_noad| of a |math_left_group|. +recent |fence_noad| of a |math_left_group|. In horizontal mode, the |prev_graf| field is used for initial language data. @@ -5087,7 +4841,7 @@ level is kept in the global quantities |mode|, |head|, |tail|, |prev_graf|, |aux|, and |mode_line|, which live in a \PASCAL\ record that is ready to be pushed onto |nest| if necessary. -@d ignore_depth==-65536000 {|prev_depth| value that is ignored} +@d ignore_depth==-65536000 {magic dimension value to mean `ignore me'} @= @!list_state_record=record@!mode_field:-mmode..mmode;@+ @@ -5097,8 +4851,6 @@ be pushed onto |nest| if necessary. @!aux_field: memory_word; @!dirs_field: halfword; @!math_field: integer; - @!local_par_field: pointer; - @!local_par_bool_field: boolean; end; @ @d mode==cur_list.mode_field {current mode} @@ -5115,10 +4867,6 @@ be pushed onto |nest| if necessary. @d dir_save==cur_list.dirs_field {dir stack when a paragraph is interrupted} @d dir_math_save==cur_list.math_field {should begin/end dir nodes be placed around mathematics?} -@d local_par==cur_list.local_par_field - {pointer to whatsit for local stuff} -@d local_par_bool==cur_list.local_par_bool_field - {has local stuff been changed in this group?} @= @!nest:array[0..nest_size] of list_state_record; @@ -5179,7 +4927,6 @@ eTeX_aux:=null; prev_depth:=ignore_depth; mode_line:=0; prev_graf:=0; shown_mode:=0; dir_save:=null; dir_math_save:=false; -local_par:=null; local_par_bool:=false; @; @ @p @; @@ -5199,7 +4946,6 @@ begin if nest_ptr>max_nest_stack then nest[nest_ptr]:=cur_list; {stack the record} incr(nest_ptr); head:=new_node(temp_node,0); tail:=head; prev_graf:=0; mode_line:=line; dir_save:=null; dir_math_save:=false; -local_par:=make_local_par_node; local_par_bool:=false; eTeX_aux:=null; end; @@ -5210,10 +4956,6 @@ is a node that should be returned to free memory. @p procedure pop_nest; {leave a semantic level, re-enter the old} begin -if local_par<>null then begin - if local_par_bool then begin end {|tail_append(local_par)|} - else flush_node(local_par); - end; flush_node(head); decr(nest_ptr); cur_list:=nest[nest_ptr]; end; @@ -5252,7 +4994,7 @@ end; @ @= case abs(m) div (max_command+1) of 0: begin print_nl("prevdepth "); - if a.sc<=ignore_depth then print("ignored") + if a.sc<=pdf_ignored_dimen then print("ignored") else print_scaled(a.sc); if nest[p].pg_field<>0 then begin print(", prevgraf "); @@ -5283,11 +5025,11 @@ or what their current values are, for all quantities that are subject to the nesting structure provided by \TeX's grouping mechanism. There are six parts to |eqtb|: -\yskip\hangg 1) |eqtb[active_base..(hash_base-1)]| holds the current -equivalents of single-character control sequences. +\yskip\hangg 1) |eqtb[null_cs]| holds the current equivalent of the +zero-length control sequence. \yskip\hangg 2) |eqtb[hash_base..(glue_base-1)]| holds the current -equivalents of multiletter control sequences. +equivalents of single- and multiletter control sequences. \yskip\hangg 3) |eqtb[glue_base..(local_base-1)]| holds the current equivalents of glue parameters like the current baselineskip. @@ -5343,8 +5085,9 @@ things. paragraphs is to define these names, and to set up the initial values of the equivalents. -In the first region we have |number_active_chars| equivalents for ``active -characters'' that act as control sequences. +In the first region we have a single entry for the `null csname' of +length zero. In luatex, the active characters and and single-letter +control sequence names are part of the next region. Then comes region~2, which corresponds to the hash table that we will define later. The maximum address in this region is used for a dummy @@ -5352,8 +5095,7 @@ control sequence that is perpetually undefined. There also are several locations for control sequences that are perpetually defined (since they are used in error recovery). -@d active_base=1 {beginning of region 1, for active character equivalents} -@d null_cs=active_base+number_active_chars {equivalent of \.{\\csname\\endcsname}} +@d null_cs=1 {equivalent of \.{\\csname\\endcsname}} @d hash_base=null_cs+1 {beginning of region 2, for the hash table} @d frozen_control_sequence=hash_base+hash_size {for error recovery} @d frozen_protection=frozen_control_sequence {inaccessible but definable} @@ -5369,7 +5111,9 @@ locations for control sequences that are perpetually defined {permanent `\.{\\notexpanded:}'} @d frozen_primitive=frozen_control_sequence+11 {permanent `\.{\\pdfprimitive}'} -@d frozen_null_font=frozen_control_sequence+12 +@d frozen_special=frozen_control_sequence+12 + {permanent `\.{\\special}'} +@d frozen_null_font=frozen_control_sequence+13 {permanent `\.{\\nullfont}'} @d font_id_base=frozen_null_font-font_base {begins table of |number_fonts| permanent font identifiers} @@ -5388,9 +5132,17 @@ locations for control sequences that are perpetually defined eq_type(undefined_control_sequence):=undefined_cs; equiv(undefined_control_sequence):=null; eq_level(undefined_control_sequence):=level_zero; -for k:=active_base to undefined_control_sequence-1 do +for k:=null_cs to undefined_control_sequence-1 do eqtb[k]:=eqtb[undefined_control_sequence]; +@ Create a C version of |undefined_control_sequence|. + +@= +@!static_undefined_control_sequence:integer; + +@ @= +static_undefined_control_sequence:=undefined_control_sequence; + @ Here is a routine that displays the current meaning of an |eqtb| entry in region 1 or~2. (Similar routines for the other regions will appear below.) @@ -5455,6 +5207,10 @@ parameters have larger numbers than the others. @=glue_par(n) +@ @= +static_local_base:=local_base; +static_glue_base:=glue_base; + @ Sometimes we need to convert \TeX's internal code numbers into symbolic form. The |print_skip_param| routine gives the symbolic name of a glue parameter. @@ -5489,54 +5245,43 @@ by using the routine called |primitive|, defined below. Let us enter them now, so that we don't have to list all those parameter names anywhere else. @= -primitive("lineskip",assign_glue,glue_base+line_skip_code);@/ +primitive_tex("lineskip",assign_glue,glue_base+line_skip_code,glue_base);@/ @!@:line_skip_}{\.{\\lineskip} primitive@> -primitive("baselineskip",assign_glue,glue_base+baseline_skip_code);@/ +primitive_tex("baselineskip",assign_glue,glue_base+baseline_skip_code,glue_base);@/ @!@:baseline_skip_}{\.{\\baselineskip} primitive@> -primitive("parskip",assign_glue,glue_base+par_skip_code);@/ +primitive_tex("parskip",assign_glue,glue_base+par_skip_code,glue_base);@/ @!@:par_skip_}{\.{\\parskip} primitive@> -primitive("abovedisplayskip",assign_glue,glue_base+above_display_skip_code);@/ +primitive_tex("abovedisplayskip",assign_glue,glue_base+above_display_skip_code,glue_base);@/ @!@:above_display_skip_}{\.{\\abovedisplayskip} primitive@> -primitive("belowdisplayskip",assign_glue,glue_base+below_display_skip_code);@/ +primitive_tex("belowdisplayskip",assign_glue,glue_base+below_display_skip_code,glue_base);@/ @!@:below_display_skip_}{\.{\\belowdisplayskip} primitive@> -primitive("abovedisplayshortskip", - assign_glue,glue_base+above_display_short_skip_code);@/ +primitive_tex("abovedisplayshortskip",assign_glue,glue_base+above_display_short_skip_code,glue_base);@/ @!@:above_display_short_skip_}{\.{\\abovedisplayshortskip} primitive@> -primitive("belowdisplayshortskip", - assign_glue,glue_base+below_display_short_skip_code);@/ +primitive_tex("belowdisplayshortskip",assign_glue,glue_base+below_display_short_skip_code,glue_base);@/ @!@:below_display_short_skip_}{\.{\\belowdisplayshortskip} primitive@> -primitive("leftskip",assign_glue,glue_base+left_skip_code);@/ +primitive_tex("leftskip",assign_glue,glue_base+left_skip_code,glue_base);@/ @!@:left_skip_}{\.{\\leftskip} primitive@> -primitive("rightskip",assign_glue,glue_base+right_skip_code);@/ +primitive_tex("rightskip",assign_glue,glue_base+right_skip_code,glue_base);@/ @!@:right_skip_}{\.{\\rightskip} primitive@> -primitive("topskip",assign_glue,glue_base+top_skip_code);@/ +primitive_tex("topskip",assign_glue,glue_base+top_skip_code,glue_base);@/ @!@:top_skip_}{\.{\\topskip} primitive@> -primitive("splittopskip",assign_glue,glue_base+split_top_skip_code);@/ +primitive_tex("splittopskip",assign_glue,glue_base+split_top_skip_code,glue_base);@/ @!@:split_top_skip_}{\.{\\splittopskip} primitive@> -primitive("tabskip",assign_glue,glue_base+tab_skip_code);@/ +primitive_tex("tabskip",assign_glue,glue_base+tab_skip_code,glue_base);@/ @!@:tab_skip_}{\.{\\tabskip} primitive@> -primitive("spaceskip",assign_glue,glue_base+space_skip_code);@/ +primitive_tex("spaceskip",assign_glue,glue_base+space_skip_code,glue_base);@/ @!@:space_skip_}{\.{\\spaceskip} primitive@> -primitive("xspaceskip",assign_glue,glue_base+xspace_skip_code);@/ +primitive_tex("xspaceskip",assign_glue,glue_base+xspace_skip_code,glue_base);@/ @!@:xspace_skip_}{\.{\\xspaceskip} primitive@> -primitive("parfillskip",assign_glue,glue_base+par_fill_skip_code);@/ +primitive_tex("parfillskip",assign_glue,glue_base+par_fill_skip_code,glue_base);@/ @!@:par_fill_skip_}{\.{\\parfillskip} primitive@> -primitive("thinmuskip",assign_mu_glue,glue_base+thin_mu_skip_code);@/ +primitive_tex("thinmuskip",assign_mu_glue,glue_base+thin_mu_skip_code,glue_base+thin_mu_skip_code);@/ @!@:thin_mu_skip_}{\.{\\thinmuskip} primitive@> -primitive("medmuskip",assign_mu_glue,glue_base+med_mu_skip_code);@/ +primitive_tex("medmuskip",assign_mu_glue,glue_base+med_mu_skip_code,glue_base+thin_mu_skip_code);@/ @!@:med_mu_skip_}{\.{\\medmuskip} primitive@> -primitive("thickmuskip",assign_mu_glue,glue_base+thick_mu_skip_code);@/ +primitive_tex("thickmuskip",assign_mu_glue,glue_base+thick_mu_skip_code,glue_base+thin_mu_skip_code);@/ @!@:thick_mu_skip_}{\.{\\thickmuskip} primitive@> -@ @= -assign_glue,assign_mu_glue: if chr_code= @@ -5608,10 +5353,8 @@ registers. @d local_right_box_base=local_left_box_base+1 @d box_base=local_right_box_base+1 {table of |number_regs| box registers} @d cur_font_loc=box_base+number_regs {internal font number outside math mode} -@d math_font_base=cur_font_loc+1 - {table of |number_math_fonts| math font numbers} -@d cat_code_base=math_font_base+number_math_fonts - {table of |number_chars| command codes (the ``catcodes'')} +@d math_param_base=cur_font_loc+1 {current math parameter data index } +@d cat_code_base=math_param_base+1 {current category code data index } @d lc_code_base=cat_code_base+1 {table of |number_chars| lowercase mappings} @d uc_code_base=lc_code_base+1 {table of |number_chars| uppercase mappings} @d sf_code_base=uc_code_base+1 {table of |number_chars| spacefactor mappings} @@ -5637,56 +5380,35 @@ registers. @d local_right_box==equiv(local_right_box_base) @d box(#)==equiv(box_base+#) @d cur_font==equiv(cur_font_loc) -@d fam_fnt(#)==equiv(math_font_base+#) @= -primitive("output",assign_toks,output_routine_loc); +primitive_tex("output",assign_toks,output_routine_loc,local_base); @!@:output_}{\.{\\output} primitive@> -primitive("everypar",assign_toks,every_par_loc); +primitive_tex("everypar",assign_toks,every_par_loc,local_base); @!@:every_par_}{\.{\\everypar} primitive@> -primitive("everymath",assign_toks,every_math_loc); +primitive_tex("everymath",assign_toks,every_math_loc,local_base); @!@:every_math_}{\.{\\everymath} primitive@> -primitive("everydisplay",assign_toks,every_display_loc); +primitive_tex("everydisplay",assign_toks,every_display_loc,local_base); @!@:every_display_}{\.{\\everydisplay} primitive@> -primitive("everyhbox",assign_toks,every_hbox_loc); +primitive_tex("everyhbox",assign_toks,every_hbox_loc,local_base); @!@:every_hbox_}{\.{\\everyhbox} primitive@> -primitive("everyvbox",assign_toks,every_vbox_loc); +primitive_tex("everyvbox",assign_toks,every_vbox_loc,local_base); @!@:every_vbox_}{\.{\\everyvbox} primitive@> -primitive("everyjob",assign_toks,every_job_loc); +primitive_tex("everyjob",assign_toks,every_job_loc,local_base); @!@:every_job_}{\.{\\everyjob} primitive@> -primitive("everycr",assign_toks,every_cr_loc); +primitive_tex("everycr",assign_toks,every_cr_loc,local_base); @!@:every_cr_}{\.{\\everycr} primitive@> -primitive("errhelp",assign_toks,err_help_loc); +primitive_tex("errhelp",assign_toks,err_help_loc,local_base); @!@:err_help_}{\.{\\errhelp} primitive@> -primitive("pdfpagesattr",assign_toks,pdf_pages_attr_loc); +primitive_pdftex("pdfpagesattr",assign_toks,pdf_pages_attr_loc,local_base); @!@:pdf_pages_attr_}{\.{\\pdfpagesattr} primitive@> -primitive("pdfpageattr",assign_toks,pdf_page_attr_loc); +primitive_pdftex("pdfpageattr",assign_toks,pdf_page_attr_loc,local_base); @!@:pdf_page_attr_}{\.{\\pdfpageattr} primitive@> -primitive("pdfpageresources",assign_toks,pdf_page_resources_loc); +primitive_pdftex("pdfpageresources",assign_toks,pdf_page_resources_loc,local_base); @!@:pdf_page_resources_}{\.{\\pdfpageresources} primitive@> -primitive("pdfpkmode",assign_toks,pdf_pk_mode_loc); +primitive_pdftex("pdfpkmode",assign_toks,pdf_pk_mode_loc,local_base); @!@:pdf_pk_mode_}{\.{\\pdfpkmode} primitive@> -@ @= -assign_toks: if chr_code>=toks_base then - begin print_esc("toks"); print_int(chr_code-toks_base); - end -else case chr_code of - output_routine_loc: print_esc("output"); - every_par_loc: print_esc("everypar"); - every_math_loc: print_esc("everymath"); - every_display_loc: print_esc("everydisplay"); - every_hbox_loc: print_esc("everyhbox"); - every_vbox_loc: print_esc("everyvbox"); - every_job_loc: print_esc("everyjob"); - every_cr_loc: print_esc("everycr"); - @/@@/ - pdf_pages_attr_loc: print_esc("pdfpagesattr"); - pdf_page_attr_loc: print_esc("pdfpageattr"); - pdf_page_resources_loc: print_esc("pdfpageresources"); - pdf_pk_mode_loc: print_esc("pdfpkmode"); - othercases print_esc("errhelp") - endcases; @ We initialize most things to null or undefined values. An undefined font is represented by the internal code |font_base|. @@ -5701,7 +5423,7 @@ possible. @d null_font==font_base @d null_ocp==ocp_base @d null_ocp_list==ocp_list_base -@d var_code==@"7000000 {math code meaning ``use the current family''} +@d var_code==7 {math code meaning ``use the current family''} @= par_shape_ptr:=null; eq_type(par_shape_loc):=shape_ref; @@ -5714,19 +5436,21 @@ box(0):=null; eq_type(box_base):=box_ref; eq_level(box_base):=level_one; for k:=box_base+1 to box_base+biggest_reg do eqtb[k]:=eqtb[box_base]; cur_font:=null_font; eq_type(cur_font_loc):=data; eq_level(cur_font_loc):=level_one;@/ -for k:=math_font_base to math_font_base+47 do eqtb[k]:=eqtb[cur_font_loc]; equiv(cat_code_base):=0; eq_type(cat_code_base):=data; eq_level(cat_code_base):=level_one;@/ +eqtb[math_param_base]:=eqtb[cat_code_base]; eqtb[lc_code_base] :=eqtb[cat_code_base]; eqtb[uc_code_base] :=eqtb[cat_code_base]; eqtb[sf_code_base] :=eqtb[cat_code_base]; eqtb[math_code_base]:=eqtb[cat_code_base];@/ cat_code_table:=0; +initialize_math_codes; +initialize_text_codes; initex_cat_codes(0); -for k:="0" to "9" do set_math_code(k,(hi(k+var_code)),level_one);@/ +for k:="0" to "9" do set_math_code(k,tex_mathcode,var_code,0,k,level_one);@/ for k:="A" to "Z" do begin - set_math_code(k,(hi(k+var_code+@"10000)),level_one); - set_math_code(k+32,(hi(k+32+var_code+@"10000)),level_one);@/ + set_math_code(k,tex_mathcode,var_code,1,k,level_one); + set_math_code((k+32),tex_mathcode,var_code,1,(k+32),level_one);@/ set_lc_code(k,k+32,level_one); set_lc_code(k+32,k+32,level_one);@/ set_uc_code(k,k,level_one); set_uc_code(k+32,k,level_one);@/ set_sf_code(k,999,level_one); @@ -5734,19 +5458,19 @@ for k:="A" to "Z" do begin @ @= static_int_base:=int_base; -initialize_math_codes; -initialize_text_codes; @ @= if (n=par_shape_loc) or ((n>=etex_pen_base) and (npar_shape_loc then begin print_int(penalty(equiv(n))); print_char(" "); print_int(penalty(equiv(n)+1)); if penalty(equiv(n))>1 then print_esc("ETC."); end - else print_int(vinfo(par_shape_ptr)); + else print_int(vinfo(par_shape_ptr+1)); end else if n -else @ +else if n=cur_font_loc then @ @ @= -begin if n=cur_font_loc then print("current font") -else if n15) or - (((#) mod @"10000)>255) - -@= -if n@/ othercases begin print("[unknown integer parameter!]"); end @@ -6162,189 +5863,183 @@ end; @ The integer parameter names must be entered into the hash table. @= -primitive("pretolerance",assign_int,int_base+pretolerance_code);@/ +primitive_tex("pretolerance",assign_int,int_base+pretolerance_code,int_base);@/ @!@:pretolerance_}{\.{\\pretolerance} primitive@> -primitive("tolerance",assign_int,int_base+tolerance_code);@/ +primitive_tex("tolerance",assign_int,int_base+tolerance_code,int_base);@/ @!@:tolerance_}{\.{\\tolerance} primitive@> -primitive("linepenalty",assign_int,int_base+line_penalty_code);@/ +primitive_tex("linepenalty",assign_int,int_base+line_penalty_code,int_base);@/ @!@:line_penalty_}{\.{\\linepenalty} primitive@> -primitive("hyphenpenalty",assign_int,int_base+hyphen_penalty_code);@/ +primitive_tex("hyphenpenalty",assign_int,int_base+hyphen_penalty_code,int_base);@/ @!@:hyphen_penalty_}{\.{\\hyphenpenalty} primitive@> -primitive("exhyphenpenalty",assign_int,int_base+ex_hyphen_penalty_code);@/ +primitive_tex("exhyphenpenalty",assign_int,int_base+ex_hyphen_penalty_code,int_base);@/ @!@:ex_hyphen_penalty_}{\.{\\exhyphenpenalty} primitive@> -primitive("clubpenalty",assign_int,int_base+club_penalty_code);@/ +primitive_tex("clubpenalty",assign_int,int_base+club_penalty_code,int_base);@/ @!@:club_penalty_}{\.{\\clubpenalty} primitive@> -primitive("widowpenalty",assign_int,int_base+widow_penalty_code);@/ +primitive_tex("widowpenalty",assign_int,int_base+widow_penalty_code,int_base);@/ @!@:widow_penalty_}{\.{\\widowpenalty} primitive@> -primitive("displaywidowpenalty", - assign_int,int_base+display_widow_penalty_code);@/ +primitive_tex("displaywidowpenalty", assign_int,int_base+display_widow_penalty_code,int_base);@/ @!@:display_widow_penalty_}{\.{\\displaywidowpenalty} primitive@> -primitive("brokenpenalty",assign_int,int_base+broken_penalty_code);@/ +primitive_tex("brokenpenalty",assign_int,int_base+broken_penalty_code,int_base);@/ @!@:broken_penalty_}{\.{\\brokenpenalty} primitive@> -primitive("binoppenalty",assign_int,int_base+bin_op_penalty_code);@/ +primitive_tex("binoppenalty",assign_int,int_base+bin_op_penalty_code,int_base);@/ @!@:bin_op_penalty_}{\.{\\binoppenalty} primitive@> -primitive("relpenalty",assign_int,int_base+rel_penalty_code);@/ +primitive_tex("relpenalty",assign_int,int_base+rel_penalty_code,int_base);@/ @!@:rel_penalty_}{\.{\\relpenalty} primitive@> -primitive("predisplaypenalty",assign_int,int_base+pre_display_penalty_code);@/ +primitive_tex("predisplaypenalty",assign_int,int_base+pre_display_penalty_code,int_base);@/ @!@:pre_display_penalty_}{\.{\\predisplaypenalty} primitive@> -primitive("postdisplaypenalty",assign_int,int_base+post_display_penalty_code);@/ +primitive_tex("postdisplaypenalty",assign_int,int_base+post_display_penalty_code,int_base);@/ @!@:post_display_penalty_}{\.{\\postdisplaypenalty} primitive@> -primitive("interlinepenalty",assign_int,int_base+inter_line_penalty_code);@/ +primitive_tex("interlinepenalty",assign_int,int_base+inter_line_penalty_code,int_base);@/ @!@:inter_line_penalty_}{\.{\\interlinepenalty} primitive@> -primitive("doublehyphendemerits", - assign_int,int_base+double_hyphen_demerits_code);@/ +primitive_tex("doublehyphendemerits", assign_int,int_base+double_hyphen_demerits_code,int_base);@/ @!@:double_hyphen_demerits_}{\.{\\doublehyphendemerits} primitive@> -primitive("finalhyphendemerits", - assign_int,int_base+final_hyphen_demerits_code);@/ +primitive_tex("finalhyphendemerits", assign_int,int_base+final_hyphen_demerits_code,int_base);@/ @!@:final_hyphen_demerits_}{\.{\\finalhyphendemerits} primitive@> -primitive("adjdemerits",assign_int,int_base+adj_demerits_code);@/ +primitive_tex("adjdemerits",assign_int,int_base+adj_demerits_code,int_base);@/ @!@:adj_demerits_}{\.{\\adjdemerits} primitive@> -primitive("mag",assign_int,int_base+mag_code);@/ +primitive_tex("mag",assign_int,int_base+mag_code,int_base);@/ @!@:mag_}{\.{\\mag} primitive@> -primitive("delimiterfactor",assign_int,int_base+delimiter_factor_code);@/ +primitive_tex("delimiterfactor",assign_int,int_base+delimiter_factor_code,int_base);@/ @!@:delimiter_factor_}{\.{\\delimiterfactor} primitive@> -primitive("looseness",assign_int,int_base+looseness_code);@/ +primitive_tex("looseness",assign_int,int_base+looseness_code,int_base);@/ @!@:looseness_}{\.{\\looseness} primitive@> -primitive("time",assign_int,int_base+time_code);@/ +primitive_tex("time",assign_int,int_base+time_code,int_base);@/ @!@:time_}{\.{\\time} primitive@> -primitive("day",assign_int,int_base+day_code);@/ +primitive_tex("day",assign_int,int_base+day_code,int_base);@/ @!@:day_}{\.{\\day} primitive@> -primitive("month",assign_int,int_base+month_code);@/ +primitive_tex("month",assign_int,int_base+month_code,int_base);@/ @!@:month_}{\.{\\month} primitive@> -primitive("year",assign_int,int_base+year_code);@/ +primitive_tex("year",assign_int,int_base+year_code,int_base);@/ @!@:year_}{\.{\\year} primitive@> -primitive("showboxbreadth",assign_int,int_base+show_box_breadth_code);@/ +primitive_tex("showboxbreadth",assign_int,int_base+show_box_breadth_code,int_base);@/ @!@:show_box_breadth_}{\.{\\showboxbreadth} primitive@> -primitive("showboxdepth",assign_int,int_base+show_box_depth_code);@/ +primitive_tex("showboxdepth",assign_int,int_base+show_box_depth_code,int_base);@/ @!@:show_box_depth_}{\.{\\showboxdepth} primitive@> -primitive("hbadness",assign_int,int_base+hbadness_code);@/ +primitive_tex("hbadness",assign_int,int_base+hbadness_code,int_base);@/ @!@:hbadness_}{\.{\\hbadness} primitive@> -primitive("vbadness",assign_int,int_base+vbadness_code);@/ +primitive_tex("vbadness",assign_int,int_base+vbadness_code,int_base);@/ @!@:vbadness_}{\.{\\vbadness} primitive@> -primitive("pausing",assign_int,int_base+pausing_code);@/ +primitive_tex("pausing",assign_int,int_base+pausing_code,int_base);@/ @!@:pausing_}{\.{\\pausing} primitive@> -primitive("tracingonline",assign_int,int_base+tracing_online_code);@/ +primitive_tex("tracingonline",assign_int,int_base+tracing_online_code,int_base);@/ @!@:tracing_online_}{\.{\\tracingonline} primitive@> -primitive("tracingmacros",assign_int,int_base+tracing_macros_code);@/ +primitive_tex("tracingmacros",assign_int,int_base+tracing_macros_code,int_base);@/ @!@:tracing_macros_}{\.{\\tracingmacros} primitive@> -primitive("tracingstats",assign_int,int_base+tracing_stats_code);@/ +primitive_tex("tracingstats",assign_int,int_base+tracing_stats_code,int_base);@/ @!@:tracing_stats_}{\.{\\tracingstats} primitive@> -primitive("tracingparagraphs",assign_int,int_base+tracing_paragraphs_code);@/ +primitive_tex("tracingparagraphs",assign_int,int_base+tracing_paragraphs_code,int_base);@/ @!@:tracing_paragraphs_}{\.{\\tracingparagraphs} primitive@> -primitive("tracingpages",assign_int,int_base+tracing_pages_code);@/ +primitive_tex("tracingpages",assign_int,int_base+tracing_pages_code,int_base);@/ @!@:tracing_pages_}{\.{\\tracingpages} primitive@> -primitive("tracingoutput",assign_int,int_base+tracing_output_code);@/ +primitive_tex("tracingoutput",assign_int,int_base+tracing_output_code,int_base);@/ @!@:tracing_output_}{\.{\\tracingoutput} primitive@> -primitive("tracinglostchars",assign_int,int_base+tracing_lost_chars_code);@/ +primitive_tex("tracinglostchars",assign_int,int_base+tracing_lost_chars_code,int_base);@/ @!@:tracing_lost_chars_}{\.{\\tracinglostchars} primitive@> -primitive("tracingcommands",assign_int,int_base+tracing_commands_code);@/ +primitive_tex("tracingcommands",assign_int,int_base+tracing_commands_code,int_base);@/ @!@:tracing_commands_}{\.{\\tracingcommands} primitive@> -primitive("tracingrestores",assign_int,int_base+tracing_restores_code);@/ +primitive_tex("tracingrestores",assign_int,int_base+tracing_restores_code,int_base);@/ @!@:tracing_restores_}{\.{\\tracingrestores} primitive@> -primitive("uchyph",assign_int,int_base+uc_hyph_code);@/ +primitive_tex("uchyph",assign_int,int_base+uc_hyph_code,int_base);@/ @!@:uc_hyph_}{\.{\\uchyph} primitive@> -primitive("outputpenalty",assign_int,int_base+output_penalty_code);@/ +primitive_tex("outputpenalty",assign_int,int_base+output_penalty_code,int_base);@/ @!@:output_penalty_}{\.{\\outputpenalty} primitive@> -primitive("maxdeadcycles",assign_int,int_base+max_dead_cycles_code);@/ +primitive_tex("maxdeadcycles",assign_int,int_base+max_dead_cycles_code,int_base);@/ @!@:max_dead_cycles_}{\.{\\maxdeadcycles} primitive@> -primitive("hangafter",assign_int,int_base+hang_after_code);@/ +primitive_tex("hangafter",assign_int,int_base+hang_after_code,int_base);@/ @!@:hang_after_}{\.{\\hangafter} primitive@> -primitive("floatingpenalty",assign_int,int_base+floating_penalty_code);@/ +primitive_tex("floatingpenalty",assign_int,int_base+floating_penalty_code,int_base);@/ @!@:floating_penalty_}{\.{\\floatingpenalty} primitive@> -primitive("globaldefs",assign_int,int_base+global_defs_code);@/ +primitive_tex("globaldefs",assign_int,int_base+global_defs_code,int_base);@/ @!@:global_defs_}{\.{\\globaldefs} primitive@> -primitive("fam",assign_int,int_base+cur_fam_code);@/ +primitive_tex("fam",assign_int,int_base+cur_fam_code,int_base);@/ @!@:fam_}{\.{\\fam} primitive@> -primitive("escapechar",assign_int,int_base+escape_char_code);@/ +primitive_tex("escapechar",assign_int,int_base+escape_char_code,int_base);@/ @!@:escape_char_}{\.{\\escapechar} primitive@> -primitive("defaulthyphenchar",assign_int,int_base+default_hyphen_char_code);@/ +primitive_tex("defaulthyphenchar",assign_int,int_base+default_hyphen_char_code,int_base);@/ @!@:default_hyphen_char_}{\.{\\defaulthyphenchar} primitive@> -primitive("defaultskewchar",assign_int,int_base+default_skew_char_code);@/ +primitive_tex("defaultskewchar",assign_int,int_base+default_skew_char_code,int_base);@/ @!@:default_skew_char_}{\.{\\defaultskewchar} primitive@> -primitive("endlinechar",assign_int,int_base+end_line_char_code);@/ +primitive_tex("endlinechar",assign_int,int_base+end_line_char_code,int_base);@/ @!@:end_line_char_}{\.{\\endlinechar} primitive@> -primitive("newlinechar",assign_int,int_base+new_line_char_code);@/ +primitive_tex("newlinechar",assign_int,int_base+new_line_char_code,int_base);@/ @!@:new_line_char_}{\.{\\newlinechar} primitive@> -primitive("language",assign_int,int_base+language_code);@/ +primitive_tex("language",assign_int,int_base+language_code,int_base);@/ @!@:language_}{\.{\\language} primitive@> -primitive("setlanguage",assign_int,int_base+cur_lang_code);@/ +primitive_tex("setlanguage",assign_int,int_base+cur_lang_code,int_base);@/ @!@:cur_lang_}{\.{\\setlanguage} primitive@> -primitive("exhyphenchar",assign_int,int_base+ex_hyphen_char_code);@/ +primitive_tex("exhyphenchar",assign_int,int_base+ex_hyphen_char_code,int_base);@/ @!@:ex_hyphen_char_}{\.{\\exhyphenchar} primitive@> -primitive("lefthyphenmin",assign_int,int_base+left_hyphen_min_code);@/ +primitive_tex("lefthyphenmin",assign_int,int_base+left_hyphen_min_code,int_base);@/ @!@:left_hyphen_min_}{\.{\\lefthyphenmin} primitive@> -primitive("righthyphenmin",assign_int,int_base+right_hyphen_min_code);@/ +primitive_tex("righthyphenmin",assign_int,int_base+right_hyphen_min_code,int_base);@/ @!@:right_hyphen_min_}{\.{\\righthyphenmin} primitive@> -primitive("holdinginserts",assign_int,int_base+holding_inserts_code);@/ +primitive_tex("holdinginserts",assign_int,int_base+holding_inserts_code,int_base);@/ @!@:holding_inserts_}{\.{\\holdinginserts} primitive@> -primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/ +primitive_tex("errorcontextlines",assign_int,int_base+error_context_lines_code,int_base);@/ @!@:error_context_lines_}{\.{\\errorcontextlines} primitive@> -primitive("luastartup",assign_int,int_base+luastartup_id_code);@/ +primitive_luatex("luastartup",assign_int,int_base+luastartup_id_code,int_base);@/ @!@:luastartup_id_}{\.{\\luastartup} primitive@> -primitive("nokerns",assign_int,int_base+disable_kern_code);@/ +primitive_luatex("nokerns",assign_int,int_base+disable_kern_code,int_base);@/ @!@:disable_kern_}{\.{\\noligkerns} primitive@> -primitive("noligs",assign_int,int_base+disable_lig_code);@/ +primitive_luatex("noligs",assign_int,int_base+disable_lig_code,int_base);@/ @!@:disable_lig_}{\.{\\noligs} primitive@> -primitive("catcodetable",assign_int,int_base+cat_code_table_code);@/ +primitive_luatex("catcodetable",assign_int,int_base+cat_code_table_code,int_base);@/ @!@:cat_code_table_}{\.{\\catcodetable} primitive@> -primitive("pdfoutput",assign_int,int_base+pdf_output_code);@/ +primitive_luatex("outputbox",assign_int,int_base+output_box_code,int_base);@/ +@!@:output_box_}{\.{\\outputbox} primitive@> +primitive_pdftex("pdfoutput",assign_int,int_base+pdf_output_code,int_base);@/ @!@:pdf_output_}{\.{\\pdfoutput} primitive@> -primitive("pdfcompresslevel",assign_int,int_base+pdf_compress_level_code);@/ +primitive_pdftex("pdfcompresslevel",assign_int,int_base+pdf_compress_level_code,int_base);@/ @!@:pdf_compress_level_}{\.{\\pdfcompresslevel} primitive@> -primitive("pdfobjcompresslevel",assign_int,int_base+pdf_objcompresslevel_code);@/ +primitive_pdftex("pdfobjcompresslevel",assign_int,int_base+pdf_objcompresslevel_code,int_base);@/ @!@:pdf_objcompresslevel_}{\.{\\pdfobjcompresslevel} primitive@> -primitive("pdfdecimaldigits",assign_int,int_base+pdf_decimal_digits_code);@/ +primitive_pdftex("pdfdecimaldigits",assign_int,int_base+pdf_decimal_digits_code,int_base);@/ @!@:pdf_decimal_digits_}{\.{\\pdfdecimaldigits} primitive@> -primitive("pdfmovechars",assign_int,int_base+pdf_move_chars_code);@/ +primitive_pdftex("pdfmovechars",assign_int,int_base+pdf_move_chars_code,int_base);@/ @!@:pdf_move_chars_}{\.{\\pdfmovechars} primitive@> -primitive("pdfimageresolution",assign_int,int_base+pdf_image_resolution_code);@/ +primitive_pdftex("pdfimageresolution",assign_int,int_base+pdf_image_resolution_code,int_base);@/ @!@:pdf_image_resolution_}{\.{\\pdfimageresolution} primitive@> -primitive("pdfpkresolution",assign_int,int_base+pdf_pk_resolution_code);@/ +primitive_pdftex("pdfpkresolution",assign_int,int_base+pdf_pk_resolution_code,int_base);@/ @!@:pdf_pk_resolution_}{\.{\\pdfpkresolution} primitive@> -primitive("pdfuniqueresname",assign_int,int_base+pdf_unique_resname_code);@/ +primitive_pdftex("pdfuniqueresname",assign_int,int_base+pdf_unique_resname_code,int_base);@/ @!@:pdf_unique_resname_}{\.{\\pdfuniqueresname} primitive@> -primitive("pdfoptionpdfminorversion",assign_int,int_base+pdf_minor_version_code);@/ +primitive_pdftex("pdfoptionpdfminorversion",assign_int,int_base+pdf_minor_version_code,int_base);@/ @!@:pdf_minor_version_}{\.{\\pdfoptionpdfminorversion} primitive@> -primitive("pdfoptionalwaysusepdfpagebox",assign_int,int_base+pdf_option_always_use_pdfpagebox_code);@/ +primitive_pdftex("pdfoptionalwaysusepdfpagebox",assign_int,int_base+pdf_option_always_use_pdfpagebox_code,int_base);@/ @!@:pdf_option_always_use_pdfpagebox_}{\.{\\pdfoptionalwaysusepdfpagebox} primitive@> -primitive("pdfoptionpdfinclusionerrorlevel",assign_int,int_base+pdf_option_pdf_inclusion_errorlevel_code);@/ +primitive_pdftex("pdfoptionpdfinclusionerrorlevel",assign_int,int_base+pdf_option_pdf_inclusion_errorlevel_code,int_base);@/ @!@:pdf_option_pdf_inclusion_errorlevel_}{\.{\\pdfoptionpdfinclusionerrorlevel} primitive@> -primitive("pdfminorversion",assign_int,int_base+pdf_minor_version_code);@/ +primitive_pdftex("pdfminorversion",assign_int,int_base+pdf_minor_version_code,int_base);@/ @!@:pdf_minor_version_}{\.{\\pdfminorversion} primitive@> -primitive("pdfforcepagebox",assign_int,int_base+pdf_force_pagebox_code);@/ +primitive_pdftex("pdfforcepagebox",assign_int,int_base+pdf_force_pagebox_code,int_base);@/ @!@:pdf_force_pagebox_}{\.{\\pdfforcepagebox} primitive@> -primitive("pdfpagebox",assign_int,int_base+pdf_pagebox_code);@/ +primitive_pdftex("pdfpagebox",assign_int,int_base+pdf_pagebox_code,int_base);@/ @!@:pdf_pagebox_}{\.{\\pdfpagebox} primitive@> -primitive("pdfinclusionerrorlevel",assign_int,int_base+pdf_inclusion_errorlevel_code);@/ +primitive_pdftex("pdfinclusionerrorlevel",assign_int,int_base+pdf_inclusion_errorlevel_code,int_base);@/ @!@:pdf_inclusion_errorlevel_}{\.{\\pdfinclusionerrorlevel} primitive@> -primitive("pdfgamma",assign_int,int_base+pdf_gamma_code);@/ +primitive_pdftex("pdfgamma",assign_int,int_base+pdf_gamma_code,int_base);@/ @!@:pdf_gamma_}{\.{\\pdfgamma} primitive@> -primitive("pdfimagegamma",assign_int,int_base+pdf_image_gamma_code);@/ +primitive_pdftex("pdfimagegamma",assign_int,int_base+pdf_image_gamma_code,int_base);@/ @!@:pdf_image_gamma_}{\.{\\pdfimagegamma} primitive@> -primitive("pdfimagehicolor",assign_int,int_base+pdf_image_hicolor_code);@/ +primitive_pdftex("pdfimagehicolor",assign_int,int_base+pdf_image_hicolor_code,int_base);@/ @!@:pdf_image_hicolor_}{\.{\\pdfimagehicolor} primitive@> -primitive("pdfimageapplygamma",assign_int,int_base+pdf_image_apply_gamma_code);@/ +primitive_pdftex("pdfimageapplygamma",assign_int,int_base+pdf_image_apply_gamma_code,int_base);@/ @!@:pdf_image_apply_gamma_}{\.{\\pdfimageapplygamma} primitive@> -primitive("pdfadjustspacing",assign_int,int_base+pdf_adjust_spacing_code);@/ +primitive_pdftex("pdfadjustspacing",assign_int,int_base+pdf_adjust_spacing_code,int_base);@/ @!@:pdf_adjust_spacing_}{\.{\\pdfadjustspacing} primitive@> -primitive("pdfprotrudechars",assign_int,int_base+pdf_protrude_chars_code);@/ +primitive_pdftex("pdfprotrudechars",assign_int,int_base+pdf_protrude_chars_code,int_base);@/ @!@:pdf_protrude_chars_}{\.{\\pdfprotrudechars} primitive@> -primitive("pdftracingfonts",assign_int,int_base+pdf_tracing_fonts_code);@/ +primitive_pdftex("pdftracingfonts",assign_int,int_base+pdf_tracing_fonts_code,int_base);@/ @!@:pdf_tracing_fonts_}{\.{\\pdftracingfonts} primitive@> -primitive("pdfgentounicode",assign_int,int_base+pdf_gen_tounicode_code);@/ +primitive_pdftex("pdfgentounicode",assign_int,int_base+pdf_gen_tounicode_code,int_base);@/ @!@:pdf_gen_tounicode_}{\.{\\pdfgentounicode} primitive@> -primitive("pdfdraftmode",assign_int,int_base+pdf_draftmode_code);@/ +primitive_pdftex("pdfdraftmode",assign_int,int_base+pdf_draftmode_code,int_base);@/ @!@:pdf_draftmode_}{\.{\\pdfdraftmode} primitive@> -primitive("pdfreplacefont",assign_int,int_base+pdf_replace_font_code);@/ +primitive_pdftex("pdfinclusioncopyfonts",assign_int,int_base+pdf_inclusion_copy_font_code,int_base);@/ +@!@:pdf_inclusion_copy_font_}{\.{\\pdfinclusioncopyfonts} primitive@> +primitive_pdftex("pdfreplacefont",assign_int,int_base+pdf_replace_font_code,int_base);@/ @!@:pdf_replace_font_}{\.{\\pdfreplacefont} primitive@> -@ @= -assign_int: if chr_code= -primitive("parindent",assign_dimen,dimen_base+par_indent_code);@/ +primitive_tex("parindent",assign_dimen,dimen_base+par_indent_code,dimen_base);@/ @!@:par_indent_}{\.{\\parindent} primitive@> -primitive("mathsurround",assign_dimen,dimen_base+math_surround_code);@/ +primitive_tex("mathsurround",assign_dimen,dimen_base+math_surround_code,dimen_base);@/ @!@:math_surround_}{\.{\\mathsurround} primitive@> -primitive("lineskiplimit",assign_dimen,dimen_base+line_skip_limit_code);@/ +primitive_tex("lineskiplimit",assign_dimen,dimen_base+line_skip_limit_code,dimen_base);@/ @!@:line_skip_limit_}{\.{\\lineskiplimit} primitive@> -primitive("hsize",assign_dimen,dimen_base+hsize_code);@/ +primitive_tex("hsize",assign_dimen,dimen_base+hsize_code,dimen_base);@/ @!@:hsize_}{\.{\\hsize} primitive@> -primitive("vsize",assign_dimen,dimen_base+vsize_code);@/ +primitive_tex("vsize",assign_dimen,dimen_base+vsize_code,dimen_base);@/ @!@:vsize_}{\.{\\vsize} primitive@> -primitive("maxdepth",assign_dimen,dimen_base+max_depth_code);@/ +primitive_tex("maxdepth",assign_dimen,dimen_base+max_depth_code,dimen_base);@/ @!@:max_depth_}{\.{\\maxdepth} primitive@> -primitive("splitmaxdepth",assign_dimen,dimen_base+split_max_depth_code);@/ +primitive_tex("splitmaxdepth",assign_dimen,dimen_base+split_max_depth_code,dimen_base);@/ @!@:split_max_depth_}{\.{\\splitmaxdepth} primitive@> -primitive("boxmaxdepth",assign_dimen,dimen_base+box_max_depth_code);@/ +primitive_tex("boxmaxdepth",assign_dimen,dimen_base+box_max_depth_code,dimen_base);@/ @!@:box_max_depth_}{\.{\\boxmaxdepth} primitive@> -primitive("hfuzz",assign_dimen,dimen_base+hfuzz_code);@/ +primitive_tex("hfuzz",assign_dimen,dimen_base+hfuzz_code,dimen_base);@/ @!@:hfuzz_}{\.{\\hfuzz} primitive@> -primitive("vfuzz",assign_dimen,dimen_base+vfuzz_code);@/ +primitive_tex("vfuzz",assign_dimen,dimen_base+vfuzz_code,dimen_base);@/ @!@:vfuzz_}{\.{\\vfuzz} primitive@> -primitive("delimitershortfall", - assign_dimen,dimen_base+delimiter_shortfall_code);@/ +primitive_tex("delimitershortfall", assign_dimen,dimen_base+delimiter_shortfall_code,dimen_base);@/ @!@:delimiter_shortfall_}{\.{\\delimitershortfall} primitive@> -primitive("nulldelimiterspace", - assign_dimen,dimen_base+null_delimiter_space_code);@/ +primitive_tex("nulldelimiterspace", assign_dimen,dimen_base+null_delimiter_space_code,dimen_base);@/ @!@:null_delimiter_space_}{\.{\\nulldelimiterspace} primitive@> -primitive("scriptspace",assign_dimen,dimen_base+script_space_code);@/ +primitive_tex("scriptspace",assign_dimen,dimen_base+script_space_code,dimen_base);@/ @!@:script_space_}{\.{\\scriptspace} primitive@> -primitive("predisplaysize",assign_dimen,dimen_base+pre_display_size_code);@/ +primitive_tex("predisplaysize",assign_dimen,dimen_base+pre_display_size_code,dimen_base);@/ @!@:pre_display_size_}{\.{\\predisplaysize} primitive@> -primitive("displaywidth",assign_dimen,dimen_base+display_width_code);@/ +primitive_tex("displaywidth",assign_dimen,dimen_base+display_width_code,dimen_base);@/ @!@:display_width_}{\.{\\displaywidth} primitive@> -primitive("displayindent",assign_dimen,dimen_base+display_indent_code);@/ +primitive_tex("displayindent",assign_dimen,dimen_base+display_indent_code,dimen_base);@/ @!@:display_indent_}{\.{\\displayindent} primitive@> -primitive("overfullrule",assign_dimen,dimen_base+overfull_rule_code);@/ +primitive_tex("overfullrule",assign_dimen,dimen_base+overfull_rule_code,dimen_base);@/ @!@:overfull_rule_}{\.{\\overfullrule} primitive@> -primitive("hangindent",assign_dimen,dimen_base+hang_indent_code);@/ +primitive_tex("hangindent",assign_dimen,dimen_base+hang_indent_code,dimen_base);@/ @!@:hang_indent_}{\.{\\hangindent} primitive@> -primitive("hoffset",assign_dimen,dimen_base+h_offset_code);@/ +primitive_tex("hoffset",assign_dimen,dimen_base+h_offset_code,dimen_base);@/ @!@:h_offset_}{\.{\\hoffset} primitive@> -primitive("voffset",assign_dimen,dimen_base+v_offset_code);@/ +primitive_tex("voffset",assign_dimen,dimen_base+v_offset_code,dimen_base);@/ @!@:v_offset_}{\.{\\voffset} primitive@> -primitive("emergencystretch",assign_dimen,dimen_base+emergency_stretch_code);@/ +primitive_tex("emergencystretch",assign_dimen,dimen_base+emergency_stretch_code,dimen_base);@/ @!@:emergency_stretch_}{\.{\\emergencystretch} primitive@> -primitive("pdfhorigin",assign_dimen,dimen_base+pdf_h_origin_code);@/ +primitive_pdftex("pdfhorigin",assign_dimen,dimen_base+pdf_h_origin_code,dimen_base);@/ @!@:pdf_h_origin_}{\.{\\pdfhorigin} primitive@> -primitive("pdfvorigin",assign_dimen,dimen_base+pdf_v_origin_code);@/ +primitive_pdftex("pdfvorigin",assign_dimen,dimen_base+pdf_v_origin_code,dimen_base);@/ @!@:pdf_v_origin_}{\.{\\pdfvorigin} primitive@> @# -primitive("pagewidth",assign_dimen,dimen_base+page_width_code);@/ -primitive("pdfpagewidth",assign_dimen,dimen_base+page_width_code);@/ +primitive_omega("pagewidth",assign_dimen,dimen_base+page_width_code,dimen_base);@/ +primitive_pdftex("pdfpagewidth",assign_dimen,dimen_base+page_width_code,dimen_base);@/ @!@:page_width_}{\.{\\pdfpagewidth} primitive@> -primitive("pageheight",assign_dimen,dimen_base+page_height_code);@/ -primitive("pdfpageheight",assign_dimen,dimen_base+page_height_code);@/ +primitive_omega("pageheight",assign_dimen,dimen_base+page_height_code,dimen_base);@/ +primitive_pdftex("pdfpageheight",assign_dimen,dimen_base+page_height_code,dimen_base);@/ @!@:page_height_}{\.{\\pdfpageheight} primitive@> @# -primitive("pdflinkmargin",assign_dimen,dimen_base+pdf_link_margin_code);@/ +primitive_pdftex("pdflinkmargin",assign_dimen,dimen_base+pdf_link_margin_code,dimen_base);@/ @!@:pdf_link_margin_}{\.{\\pdflinkmargin} primitive@> -primitive("pdfdestmargin",assign_dimen,dimen_base+pdf_dest_margin_code);@/ +primitive_pdftex("pdfdestmargin",assign_dimen,dimen_base+pdf_dest_margin_code,dimen_base);@/ @!@:pdf_dest_margin_}{\.{\\pdfdestmargin} primitive@> -primitive("pdfthreadmargin",assign_dimen,dimen_base+pdf_thread_margin_code);@/ +primitive_pdftex("pdfthreadmargin",assign_dimen,dimen_base+pdf_thread_margin_code,dimen_base);@/ @!@:pdf_thread_margin_}{\.{\\pdfthreadmargin} primitive@> -primitive("pdffirstlineheight",assign_dimen,dimen_base+pdf_first_line_height_code);@/ +primitive_pdftex("pdffirstlineheight",assign_dimen,dimen_base+pdf_first_line_height_code,dimen_base);@/ @!@:pdf_first_line_height_}{\.{\\pdffirstlineheight} primitive@> -primitive("pdflastlinedepth",assign_dimen,dimen_base+pdf_last_line_depth_code);@/ +primitive_pdftex("pdflastlinedepth",assign_dimen,dimen_base+pdf_last_line_depth_code,dimen_base);@/ @!@:pdf_last_line_depth_}{\.{\\pdflastlinedepth} primitive@> -primitive("pdfeachlineheight",assign_dimen,dimen_base+pdf_each_line_height_code);@/ +primitive_pdftex("pdfeachlineheight",assign_dimen,dimen_base+pdf_each_line_height_code,dimen_base);@/ @!@:pdf_each_line_height_}{\.{\\pdfeachlineheight} primitive@> -primitive("pdfeachlinedepth",assign_dimen,dimen_base+pdf_each_line_depth_code);@/ +primitive_pdftex("pdfeachlinedepth",assign_dimen,dimen_base+pdf_each_line_depth_code,dimen_base);@/ @!@:pdf_each_line_depth_}{\.{\\pdfeachlinedepth} primitive@> -primitive("pdfpxdimen",assign_dimen,dimen_base+pdf_px_dimen_code);@/ +primitive_pdftex("pdfignoreddimen",assign_dimen,dimen_base+pdf_ignored_dimen_code,dimen_base);@/ +@!@:pdf_ignored_dimen_}{\.{\\pdfignoreddimen} primitive@> +primitive_pdftex("pdfpxdimen",assign_dimen,dimen_base+pdf_px_dimen_code,dimen_base);@/ @!@:pdf_px_dimen_}{\.{\\pdfpxdimen} primitive@> -@ @= -assign_dimen: if chr_code= for k:=dimen_base to eqtb_size do eqtb[k].sc:=0; +page_left_offset := one_inch; +page_top_offset := one_inch; +page_right_offset := one_inch; +page_bottom_offset := one_inch; + +@ @= +pdf_ignored_dimen := ignore_depth; +pdf_each_line_height := pdf_ignored_dimen; +pdf_each_line_depth := pdf_ignored_dimen; +pdf_first_line_height := pdf_ignored_dimen; +pdf_last_line_depth := pdf_ignored_dimen; + @ @= begin if n@@;@/ +@p @!stat procedure show_eqtb(@!n:pointer); -begin if n else if n else if n @@ -6655,8 +6362,8 @@ but \TeX\ needs to store the |eq_level| information in another array called |xeq_level|. @= -@!eqtb:array[active_base..eqtb_size] of memory_word; -@!xeq_level:array[int_base..eqtb_size] of quarterword; +@!eqtb:array[null_cs..eqtb_size] of memory_word; +@!xeq_level:array[null_cs..eqtb_size] of quarterword; @ @= for k:=int_base to eqtb_size do xeq_level[k]:=level_one; @@ -6701,50 +6408,10 @@ A global boolean variable called |no_new_control_sequence| is set to @!no_new_control_sequence:boolean; {are new identifiers legal?} @!cs_count:integer; {total number of known identifiers} -@ Primitive support needs a few extra variables and definitions - -@d prim_size=2100 {maximum number of primitives } -@d prim_prime=1777 {about 85\pct! of |primitive_size|} -@d prim_base=1 -@d prim_next(#) == prim[#].lh {link for coalesced lists} -@d prim_text(#) == prim[#].rh {string number for control sequence name} -@d prim_is_full == (prim_used=prim_base) {test if all positions are occupied} -@d prim_eq_level_field(#)==#.hh.b1 -@d prim_eq_type_field(#)==#.hh.b0 -@d prim_equiv_field(#)==#.hh.rh -@d prim_eq_level(#)==prim_eq_level_field(prim_eqtb[#]) {level of definition} -@d prim_eq_type(#)==prim_eq_type_field(prim_eqtb[#]) {command code for equivalent} -@d prim_equiv(#)==prim_equiv_field(prim_eqtb[#]) {equivalent value} -@d undefined_primitive=0 - -@= -@!prim: array [0..prim_size] of two_halves; {the primitives table} -@!prim_used:pointer; {allocation pointer for |prim|} -@!prim_eqtb:array[0..prim_size] of memory_word; - @ The extra set of functions make sure we can query the primitive meanings of thing s from C code @p -function get_char_cat_code(c:integer):quarterword; -begin - if local_catcode_table then - get_char_cat_code:=get_cat_code(line_catcode_table,c) - else - get_char_cat_code:=get_cat_code(cat_code_table,c) -end; -function get_prim_eq_level(p:integer):quarterword; -begin - get_prim_eq_level := prim_eq_level(p); -end; -function get_prim_eq_type(p:integer):quarterword; -begin - get_prim_eq_type := prim_eq_type(p); -end; -function get_prim_equiv(p:integer):halfword; -begin - get_prim_equiv := prim_equiv(p); -end; function get_eq_type(p:integer):quarterword; begin get_eq_type := eq_type(p); @@ -6762,9 +6429,7 @@ begin get_equiv := equiv(p); end; function get_cs_text(cs:integer):str_number; -begin if cs=str_ptr) then get_cs_text := "" else get_cs_text := text(cs); end; @@ -6776,6 +6441,14 @@ function get_count_base:halfword; begin get_count_base := count_base; end; +function get_skip_base:halfword; +begin + get_skip_base := skip_base; +end; +function get_mu_skip_base:halfword; +begin + get_mu_skip_base := mu_skip_base; +end; function get_attribute_base:halfword; begin get_attribute_base := attribute_base; @@ -6788,10 +6461,18 @@ function get_int_base:halfword; begin get_int_base := int_base; end; +function get_dimen_base:halfword; +begin + get_dimen_base := dimen_base; +end; function get_toks_base:halfword; begin get_toks_base := toks_base; end; +function get_del_code_base:halfword; +begin + get_del_code_base := del_code_base; +end; function get_every_eof:halfword; begin get_every_eof := every_eof; @@ -6815,17 +6496,12 @@ end; @ @= no_new_control_sequence:=true; {new identifiers are usually forbidden} -prim_next(0):=0; prim_text(0):=0; -for k:=1 to prim_size do prim[k]:=prim[0]; -prim_eq_level(0) := level_zero; -prim_eq_type(0) := undefined_cs; -prim_equiv(0) := null; -for k:=1 to prim_size do prim_eqtb[k]:=prim_eqtb[0]; +init_primitives; next(hash_base):=0; text(hash_base):=0; for k:=hash_base+1 to undefined_control_sequence-1 do hash[k]:=hash[hash_base]; @ @= -prim_used:=prim_size; {nothing is used} +ini_init_primitives; hash_used:=frozen_control_sequence; {nothing is used} cs_count:=0; eq_type(frozen_dont_expand):=dont_expand; @@ -6837,166 +6513,6 @@ equiv(frozen_primitive):=1; eq_level(frozen_primitive):=level_one; text(frozen_primitive):="primitive"; -@ Here is the subroutine that searches the hash table for an identifier -that matches a given string of length |l>1| appearing in |buffer[j.. -(j+l-1)]|. If the identifier is found, the corresponding hash table address -is returned. Otherwise, if the global variable |no_new_control_sequence| -is |true|, the dummy address |undefined_control_sequence| is returned. -Otherwise the identifier is inserted into the hash table and its location -is returned. - -@p function id_lookup(@!j,@!l:integer):pointer; {search the hash table} -label found; {go here if you found it} -var h:integer; {hash code} -@!d:integer; {number of characters in incomplete current string} -@!p:pointer; {index in |hash| array} -@!k:pointer; {index in |buffer| array} -begin @; -p:=h+hash_base; {we start searching here; note that |0<=h0 then if length(text(p))=l then - if str_eq_buf(text(p),j) then goto found; - if next(p)=0 then - begin if no_new_control_sequence then - p:=undefined_control_sequence - else @; - goto found; - end; - p:=next(p); - end; -found: id_lookup:=p; -end; - -@ @= -begin if text(p)>0 then - begin repeat if hash_is_full then overflow("hash size",hash_size); -@:TeX capacity exceeded hash size}{\quad hash size@> - decr(hash_used); - until text(hash_used)=0; {search for an empty location in |hash|} - next(p):=hash_used; p:=hash_used; - end; -str_room(l); d:=cur_length; -while pool_ptr>str_start_macro(str_ptr) do - begin decr(pool_ptr); str_pool[pool_ptr+l]:=str_pool[pool_ptr]; - end; {move current string up to make room for another} -for k:=j to j+l-1 do append_char(buffer[k]); -text(p):=make_string; pool_ptr:=pool_ptr+d; -@!stat incr(cs_count);@+tats@;@/ -end - -@ The value of |hash_prime| should be roughly 85\pct! of |hash_size|, and it -should be a prime number. The theory of hashing tells us to expect fewer -than two table probes, on the average, when the search is successful. -[See J.~S. Vitter, {\sl Journal of the ACM\/ \bf30} (1983), 231--258.] -@^Vitter, Jeffrey Scott@> - -@= -h:=buffer[j]; -for k:=j+1 to j+l-1 do - begin h:=h+h+buffer[k]; - while h>=hash_prime do h:=h-hash_prime; - end - -@ Here is the subroutine that searches the primitive table for an identifier - -@p function prim_lookup(@!s:str_number):pointer; {search the primitives table} -label found; {go here if you found it} -var h:integer; {hash code} -@!p:pointer; {index in |hash| array} -@!k:pointer; {index in string pool} -@!the_hash_prime:halfword; -@!j,@!l:integer; -begin -the_hash_prime:= prim_prime; -if slevel_one) then - p := undefined_primitive; -end -else begin - j:=str_start_macro(s); - if s = str_ptr then l := cur_length else l := length(s); - @; - p:=h+prim_base; {we start searching here; note that |0<=h0 then if length(prim_text(p))=l then - if str_eq_str(prim_text(p),s) then goto found; - if prim_next(p)=0 then - begin if no_new_control_sequence then - p:=undefined_primitive - else @; - goto found; - end; - p:=prim_next(p); - end; - end; -found: prim_lookup:=p; -end; - -function string_lookup(@!s:str_number):pointer; {search the primitives table} -label found; {go here if you found it} -var h:integer; {hash code} -@!p:pointer; {index in |hash| array} -@!k:pointer; {index in string pool} -@!the_hash_prime: halfword; -@!j,@!l:integer; -begin -the_hash_prime := hash_prime; -if slevel_one) then - p := undefined_cs; -end -else begin - j:=str_start_macro(s); - if s = str_ptr then l := cur_length else l := length(s); - @; - p:=h+hash_base; {we start searching here; note that |0<=h0 then if length(text(p))=l then - if str_eq_str(text(p),s) then goto found; - if next(p)=0 then - begin - p:=undefined_cs ; - goto found; - end; - p:=next(p); - end; - end; -found: string_lookup:=p; -end; - -function is_primitive(csname:str_number):boolean; - var n,m:integer; -begin - m := prim_lookup(csname); - n := string_lookup(csname); - is_primitive :=((n<>undefined_cs) and - (m<>undefined_primitive) and - (eq_type(n)=get_prim_eq_type(m)) and - (equiv(n)=get_prim_equiv(m))); -end; - -@ @= -begin if prim_text(p)>0 then - begin repeat if prim_is_full then overflow("primitive size",prim_size); -@:TeX capacity exceeded primitive size}{\quad primitive size@> - decr(prim_used); - until prim_text(prim_used)=0; {search for an empty location in |prim|} - prim_next(p):=prim_used; p:=prim_used; - end; -prim_text(p):=s; -end - -@ The value of |prim_prime| should be roughly 85\pct! of -|prim_size|, and it should be a prime number. - -@= -h:=str_pool[j]; -for k:=j+1 to j+l-1 do - begin h:=h+h+str_pool[k]; - while h>=the_hash_prime do h:=h-the_hash_prime; - end - @ The procedure |print_cs| prints the name of a control sequence, given a pointer to its address in |eqtb|. A space is printed after the name @@ -7010,28 +6526,38 @@ they may be unprintable. ((length(#)=3)and(str_pool[str_start_macro(#)]>=@"E0))or ((length(#)=2)and(str_pool[str_start_macro(#)]>=@"C0)) +@d is_active_csname(#)==((length(text(#))>3)and + (str_pool[str_start_macro(text(#))]=@"EF)and + (str_pool[str_start_macro(text(#))+1]=@"BF)and + (str_pool[str_start_macro(text(#))+2]=@"BF)) + +@d active_csname_value(#)==pool_to_unichar(str_start_macro(text(#))+3) + @= procedure print_cs(@!p:integer); {prints a purported control sequence} -begin if p - else print(p-active_base) else if p>=undefined_control_sequence then print_esc("IMPOSSIBLE.") else if (text(p)<0)or(text(p)>=str_ptr) then print_esc("NONEXISTENT.") @.NONEXISTENT@> -else begin - print_esc(text(p)); - if single_letter(text(p)) then begin - if get_cat_code(cat_code_table,pool_to_unichar(str_start_macro(text(p))))=letter then - print_char(" ") +else begin + if is_active_csname(p) then + print(active_csname_value(p)) + else begin + print_esc(text(p)); + if single_letter(text(p)) then begin + if get_cat_code(cat_code_table,pool_to_unichar(str_start_macro(text(p))))=letter then + print_char(" ") + else + do_nothing; + end else - do_nothing; + print_char(" "); end - else - print_char(" "); end; end; @@ -7040,158 +6566,154 @@ prints a space after the control sequence. @= procedure sprint_cs(@!p:pointer); {prints a control sequence} -begin if p127 then confusion("prim"); { should be ASCII } - append_char(ss); - s:=make_string; +begin if p=null_cs then begin + print_esc("csname"); print_esc("endcsname"); end -else - s:=ss; -k:=str_start_macro(s); l:=str_start_macro(s+1)-k; - {we will move |s| into the (possibly non-empty) |buffer|} -if first+l>buf_size+1 then - check_buffer_overflow(first+l); -@:TeX capacity exceeded buffer size}{\quad buffer size@> -for j:=0 to l-1 do buffer[first+j]:=so(str_pool[k+j]); -cur_val:=id_lookup(first,l); {|no_new_control_sequence| is |false|} -flush_string; text(cur_val):=s; {we don't want to have the string twice} -prim_val:=prim_lookup(s); -eq_level(cur_val):=level_one; eq_type(cur_val):=c; equiv(cur_val):=o; -prim_eq_level(prim_val) := level_one; -prim_eq_type(prim_val) := c; -prim_equiv(prim_val) := o; +else begin + if is_active_csname(p) then + print(active_csname_value(p)) + else + print_esc(text(p)); + end; end; -tini + @ Many of \TeX's primitives need no |equiv|, since they are identifiable by their |eq_type| alone. These primitives are loaded into the hash table as follows: @= -primitive(" ",ex_space,0);@/ +primitive_tex(" ",ex_space,0,0);@/ @!@:Single-character primitives /}{\quad\.{\\\ }@> -primitive("/",ital_corr,0);@/ +primitive_tex("/",ital_corr,0,0);@/ @!@:Single-character primitives /}{\quad\.{\\/}@> -primitive("accent",accent,0);@/ +primitive_tex("accent",accent,0,0);@/ @!@:accent_}{\.{\\accent} primitive@> -primitive("advance",advance,0);@/ +primitive_tex("advance",advance,0,0);@/ @!@:advance_}{\.{\\advance} primitive@> -primitive("afterassignment",after_assignment,0);@/ +primitive_tex("afterassignment",after_assignment,0,0);@/ @!@:after_assignment_}{\.{\\afterassignment} primitive@> -primitive("aftergroup",after_group,0);@/ +primitive_tex("aftergroup",after_group,0,0);@/ @!@:after_group_}{\.{\\aftergroup} primitive@> -primitive("begingroup",begin_group,0);@/ +primitive_tex("begingroup",begin_group,0,0);@/ @!@:begin_group_}{\.{\\begingroup} primitive@> -primitive("char",char_num,0);@/ +primitive_tex("char",char_num,0,0);@/ @!@:char_}{\.{\\char} primitive@> -primitive("csname",cs_name,0);@/ +primitive_tex("csname",cs_name,0,0);@/ @!@:cs_name_}{\.{\\csname} primitive@> -primitive("delimiter",delim_num,0);@/ +primitive_tex("delimiter",delim_num,0,0);@/ @!@:delimiter_}{\.{\\delimiter} primitive@> -primitive("odelimiter",delim_num,1);@/ +primitive_omega("odelimiter",delim_num,1,0);@/ @!@:odelimiter_}{\.{\\odelimiter} primitive@> -primitive("divide",divide,0);@/ +primitive_luatex("Udelimiter",delim_num,2,0);@/ +@!@:odelimiter_}{\.{\\Udelimiter} primitive@> +primitive_tex("divide",divide,0,0);@/ @!@:divide_}{\.{\\divide} primitive@> -primitive("endcsname",end_cs_name,0);@/ +primitive_tex("endcsname",end_cs_name,0,0);@/ @!@:end_cs_name_}{\.{\\endcsname} primitive@> -primitive("endgroup",end_group,0); +primitive_tex("endgroup",end_group,0,0); @!@:end_group_}{\.{\\endgroup} primitive@> text(frozen_end_group):="endgroup"; eqtb[frozen_end_group]:=eqtb[cur_val];@/ -primitive("expandafter",expand_after,0);@/ +primitive_tex("expandafter",expand_after,0,0);@/ @!@:expand_after_}{\.{\\expandafter} primitive@> -primitive("font",def_font,0);@/ +primitive_tex("font",def_font,0,0);@/ @!@:font_}{\.{\\font} primitive@> -primitive("letterspacefont",letterspace_font,0);@/ +primitive_pdftex("letterspacefont",letterspace_font,0,0);@/ @!@:letterspace_font_}{\.{\\letterspacefont} primitive@> -primitive("fontdimen",assign_font_dimen,0);@/ +primitive_pdftex("pdfcopyfont",pdf_copy_font,0,0);@/ +@!@:pdf_copy_font_}{\.{\\pdfcopyfont} primitive@> +primitive_tex("fontdimen",assign_font_dimen,0,0);@/ @!@:font_dimen_}{\.{\\fontdimen} primitive@> -primitive("halign",halign,0);@/ +primitive_tex("halign",halign,0,0);@/ @!@:halign_}{\.{\\halign} primitive@> -primitive("hrule",hrule,0);@/ +primitive_tex("hrule",hrule,0,0);@/ @!@:hrule_}{\.{\\hrule} primitive@> -primitive("ignorespaces",ignore_spaces,0);@/ +primitive_tex("ignorespaces",ignore_spaces,0,0);@/ @!@:ignore_spaces_}{\.{\\ignorespaces} primitive@> -primitive("insert",insert,0);@/ +primitive_tex("insert",insert,0,0);@/ @!@:insert_}{\.{\\insert} primitive@> -primitive("leftghost",char_ghost,0);@/ +primitive_omega("leftghost",char_ghost,0,0);@/ @!@:leftghost_}{\.{\\leftghost} primitive@> -primitive("mark",mark,0);@/ +primitive_tex("mark",mark,0,0);@/ @!@:mark_}{\.{\\mark} primitive@> -primitive("mathaccent",math_accent,0);@/ +primitive_tex("mathaccent",math_accent,0,0);@/ @!@:math_accent_}{\.{\\mathaccent} primitive@> -primitive("mathchar",math_char_num,0);@/ -@!@:math_char_}{\.{\\mathchar} primitive@> -primitive("omathaccent",math_accent,1);@/ +primitive_omega("omathaccent",math_accent,1,0);@/ @!@:math_accent_}{\.{\\omathaccent} primitive@> -primitive("omathchar",math_char_num,1);@/ +primitive_luatex("Umathaccent",math_accent,2,0);@/ +@!@:math_accent_}{\.{\\Umathaccent} primitive@> +primitive_luatex("Umathbotaccent",math_accent,3,0);@/ +@!@:math_accent_}{\.{\\Umathbotaccent} primitive@> +primitive_luatex("Umathaccents",math_accent,4,0);@/ +@!@:math_accent_}{\.{\\Umathaccents} primitive@> +primitive_tex("mathchar",math_char_num,0,0);@/ +@!@:math_char_}{\.{\\mathchar} primitive@> +primitive_omega("omathchar",math_char_num,1,0);@/ @!@:math_char_}{\.{\\omathchar} primitive@> -primitive("mathchoice",math_choice,0);@/ +primitive_luatex("Umathchar",math_char_num,2,0);@/ +@!@:math_char_}{\.{\\Umathchar} primitive@> +primitive_luatex("Umathcharnum",math_char_num,3,0);@/ +@!@:math_char_}{\.{\\Umathcharnum} primitive@> +primitive_tex("mathchoice",math_choice,0,0);@/ @!@:math_choice_}{\.{\\mathchoice} primitive@> -primitive("multiply",multiply,0);@/ +primitive_tex("multiply",multiply,0,0);@/ @!@:multiply_}{\.{\\multiply} primitive@> -primitive("noalign",no_align,0);@/ +primitive_tex("noalign",no_align,0,0);@/ @!@:no_align_}{\.{\\noalign} primitive@> -primitive("noboundary",no_boundary,0);@/ +primitive_tex("noboundary",no_boundary,0,0);@/ @!@:no_boundary_}{\.{\\noboundary} primitive@> -primitive("noexpand",no_expand,0);@/ +primitive_tex("noexpand",no_expand,0,0);@/ @!@:no_expand_}{\.{\\noexpand} primitive@> -primitive("primitive",no_expand,1);@/ +primitive_luatex("primitive",no_expand,1,0);@/ @!@:primitive_}{\.{\\primitive} primitive@> -primitive("pdfprimitive",no_expand,1);@/ +primitive_pdftex("pdfprimitive",no_expand,1,0);@/ @!@:pdfprimitive_}{\.{\\pdfprimitive} primitive@> -primitive("nonscript",non_script,0);@/ +primitive_tex("nonscript",non_script,0,0);@/ @!@:non_script_}{\.{\\nonscript} primitive@> -primitive("omit",omit,0);@/ +primitive_tex("omit",omit,0,0);@/ @!@:omit_}{\.{\\omit} primitive@> -primitive("parshape",set_shape,par_shape_loc);@/ +primitive_tex("parshape",set_tex_shape,par_shape_loc,par_shape_loc);@/ @!@:par_shape_}{\.{\\parshape} primitive@> -primitive("penalty",break_penalty,0);@/ +primitive_tex("penalty",break_penalty,0,0);@/ @!@:penalty_}{\.{\\penalty} primitive@> -primitive("prevgraf",set_prev_graf,0);@/ +primitive_tex("prevgraf",set_prev_graf,0,0);@/ @!@:prev_graf_}{\.{\\prevgraf} primitive@> -primitive("radical",radical,0);@/ +primitive_tex("radical",radical,0,0);@/ @!@:radical_}{\.{\\radical} primitive@> -primitive("oradical",radical,1);@/ +primitive_omega("oradical",radical,1,0);@/ @!@:radical_}{\.{\\oradical} primitive@> -primitive("read",read_to_cs,0);@/ +primitive_luatex("Uradical",radical,2,0);@/ +@!@:radical_}{\.{\\Uradical} primitive@> +primitive_luatex("Uroot",radical,3,0);@/ +@!@:radical_}{\.{\\Uroot} primitive@> +primitive_luatex("Uunderdelimiter",radical,4,0);@/ +@!@:radical_}{\.{\\Uunderdelimiter} primitive@> +primitive_luatex("Uoverdelimiter",radical,5,0);@/ +@!@:radical_}{\.{\\Uoverdelimiter} primitive@> +primitive_luatex("Udelimiterunder",radical,6,0);@/ +@!@:radical_}{\.{\\Udelimiterunder} primitive@> +primitive_luatex("Udelimiterover",radical,7,0);@/ +@!@:radical_}{\.{\\Udelimiterover} primitive@> +primitive_tex("read",read_to_cs,0,0);@/ @!@:read_}{\.{\\read} primitive@> -primitive("relax",relax,too_big_char); +primitive_tex("relax",relax,too_big_char,too_big_char); @!@:relax_}{\.{\\relax} primitive@> text(frozen_relax):="relax"; eqtb[frozen_relax]:=eqtb[cur_val];@/ -primitive("rightghost",char_ghost,1);@/ +primitive_omega("rightghost",char_ghost,1,0);@/ @!@:rightghost_}{\.{\\rightghost} primitive@> -primitive("setbox",set_box,0);@/ +primitive_tex("setbox",set_box,0,0);@/ @!@:set_box_}{\.{\\setbox} primitive@> -primitive("the",the,0);@/ +primitive_tex("the",the,0,0);@/ @!@:the_}{\.{\\the} primitive@> -primitive("toks",toks_register,0);@/ +primitive_tex("toks",toks_register,0,0);@/ @!@:toks_}{\.{\\toks} primitive@> -primitive("vadjust",vadjust,0);@/ +primitive_tex("vadjust",vadjust,0,0);@/ @!@:vadjust_}{\.{\\vadjust} primitive@> -primitive("valign",valign,0);@/ +primitive_tex("valign",valign,0,0);@/ @!@:valign_}{\.{\\valign} primitive@> -primitive("vcenter",vcenter,0);@/ +primitive_tex("vcenter",vcenter,0,0);@/ @!@:vcenter_}{\.{\\vcenter} primitive@> -primitive("vrule",vrule,0);@/ +primitive_tex("vrule",vrule,0,0);@/ @!@:vrule_}{\.{\\vrule} primitive@> @ Each primitive has a corresponding inverse, so that it is possible to @@ -7200,65 +6722,6 @@ Every call of |primitive| in this program is therefore accompanied by some straightforward code that forms part of the |print_cmd_chr| routine below. -@= -accent: print_esc("accent"); -advance: print_esc("advance"); -after_assignment: print_esc("afterassignment"); -after_group: print_esc("aftergroup"); -assign_font_dimen: print_esc("fontdimen"); -begin_group: print_esc("begingroup"); -break_penalty: print_esc("penalty"); -char_num: print_esc("char"); -char_ghost: if cur_chr=0 then print_esc("leftghost") - else print_esc("rightghost"); -cs_name: print_esc("csname"); -def_font: print_esc("font"); -letterspace_font: print_esc("letterspacefont"); -delim_num: if chr_code=0 then print_esc("delimiter") else print_esc("odelimiter") ; -divide: print_esc("divide"); -end_cs_name: print_esc("endcsname"); -end_group: print_esc("endgroup"); -ex_space: print_esc(" "); -expand_after: if chr_code=0 then print_esc("expandafter") - @; -halign: print_esc("halign"); -hrule: print_esc("hrule"); -ignore_spaces: if chr_code=0 then print_esc("ignorespaces") else print_esc("primitive"); -insert: print_esc("insert"); -ital_corr: print_esc("/"); -mark: begin - if chr_code=0 then print_esc("mark") - else if chr_code=1 then print_esc("clearmarks") - else print_esc("marks"); - end; -math_accent: if chr_code=0 then print_esc("mathaccent") else print_esc("omathaccent"); -math_char_num: if chr_code=0 then print_esc("mathchar") else print_esc("omathchar"); -math_choice: print_esc("mathchoice"); -multiply: print_esc("multiply"); -no_align: print_esc("noalign"); -no_boundary:print_esc("noboundary"); -no_expand: if chr_code=0 then print_esc("noexpand") - else print_esc("primitive"); -non_script: print_esc("nonscript"); -omit: print_esc("omit"); -radical: if chr_code=0 then print_esc("radical") else print_esc("oradical"); -read_to_cs: if chr_code=0 then print_esc("read") - @; -relax: print_esc("relax"); -set_box: print_esc("setbox"); -set_prev_graf: print_esc("prevgraf"); -set_shape: case chr_code of - par_shape_loc: print_esc("parshape"); - @@;@/ - end; {there are no other cases} -the: if chr_code=0 then print_esc("the") - @; -toks_register: print_esc("toks"); -vadjust: print_esc("vadjust"); -valign: print_esc("valign"); -vcenter: print_esc("vcenter"); -vrule: print_esc("vrule"); - @ We will deal with the other primitives later, at some point in the program where their |eq_type| and |equiv| values are more meaningful. For example, the primitives for math mode will be loaded when we consider the routines @@ -7312,7 +6775,7 @@ source line number at which the current level of grouping was entered. @d save_level(#)==save_stack[#].hh.b1 {saved level for regions 5 and 6, or group code} @d save_index(#)==save_stack[#].hh.rh - {|eqtb| location or |save_stack| location} + {|eqtb| location or token or |save_stack| location} @d restore_old_value=0 {|save_type| when a value should be restored later} @d restore_zero=1 {|save_type| when an undefined entry should be restored} @d insert_token=2 {|save_type| when a token is being saved for later use} @@ -7340,7 +6803,7 @@ one that starts with \.{\\begingroup} should end with \.{\\endgroup}. @d align_group=6 {code for `\.{\\halign}\grp', `\.{\\valign}\grp'} @d no_align_group=7 {code for `\.{\\noalign}\grp'} @d output_group=8 {code for output routine} -@d math_group=9 {code for, e.g, `\.{\char'136}\grp'} +@d math_group=9 {code for, e.g., `\.{\char'136}\grp'} @d disc_group=10 {code for `\.{\\discretionary}\grp\grp\grp'} @d insert_group=11 {code for `\.{\\insert}\grp', `\.{\\vadjust}\grp'} @d vcenter_group=12 {code for `\.{\\vcenter}\grp'} @@ -7544,6 +7007,7 @@ begin a:=false; l:=level_one; {just in case} unsave_math_codes(cur_level); unsave_cat_codes (cat_code_table,cur_level); unsave_text_codes(cur_level); +unsave_math_data(cur_level); if cur_level>level_one then begin decr(cur_level); @; @@ -7774,7 +7238,7 @@ if (pfix_mem_end) then end; if info(p)>=cs_token_flag then begin if not ((inhibit_par_tokens) and (info(p)=par_token)) then - print_cs(info(p)-cs_token_flag); + print_cs(info(p)-cs_token_flag); end else begin m:=info(p) div string_offset; c:=info(p) mod string_offset; if info(p)<0 then print_esc("BAD.") @@ -7790,7 +7254,7 @@ parameters by seeing one in a |match| command before it runs into any case m of left_brace,right_brace,math_shift,tab_mark,sup_mark,sub_mark,spacer, letter,other_char: print(c); -mac_param: begin print(c); print(c); +mac_param: begin if not in_lua_escape then print(c); print(c); end; out_param: begin print(match_chr); if c<=9 then print_char(c+"0") @@ -7877,39 +7341,6 @@ low-level languages that do not support recursion. @!cur_cs: pointer; {control sequence found here, zero if none found} @!cur_tok: halfword; {packed representative of |cur_cmd| and |cur_chr|} -@ The |print_cmd_chr| routine prints a symbolic interpretation of a -command code and its modifier. This is used in certain `\.{You can\'t}' -error messages, and in the implementation of diagnostic routines like -\.{\\show}. - -The body of |print_cmd_chr| is a rather tedious listing of print -commands, and most of it is essentially an inverse to the |primitive| -routine that enters a \TeX\ primitive into |eqtb|. Therefore much of -this procedure appears elsewhere in the program, -together with the corresponding |primitive| calls. - -@d chr_cmd(#)==begin print(#); print(chr_code); - end - -@= -procedure print_cmd_chr(@!cmd:quarterword;@!chr_code:halfword); -var n:integer; {temp variable} -begin case cmd of -left_brace: chr_cmd("begin-group character "); -right_brace: chr_cmd("end-group character "); -math_shift: chr_cmd("math shift character "); -mac_param: chr_cmd("macro parameter character "); -sup_mark: chr_cmd("superscript character "); -sub_mark: chr_cmd("subscript character "); -endv: print("end of alignment template"); -spacer: chr_cmd("blank space "); -letter: chr_cmd("the letter "); -other_char: chr_cmd("the character "); -@t\4@>@@/ -othercases print("[unknown command code!]") -endcases; -end; - @ Here is a procedure that displays the current command. @p procedure show_cur_cmd_chr; @@ -7968,6 +7399,9 @@ convention~(1), so it is declared in the following way: @!start_field,@!loc_field, @!limit_field, @!name_field, @!ocp_lstack_field: halfword; {used for omega translation processes} @!ocp_no_field: halfword; {used for omega translation processes} + @!synctex_tag_field: integer; {stack the tag of the current file} + @!cattable_field: integer; {category table used by the current line (see textoken.c)} + @!partial_field: boolean; {is the current line partial? (see textoken.c)} @!nofilter_field: boolean; {used by token filtering} end; @@ -7988,8 +7422,11 @@ in our discussion of basic input-output routines. The other components of @d limit==cur_input.limit_field {end of current line in |buffer|} @d nofilter==cur_input.nofilter_field {is token filtering explicitly disallowed?} @d name==cur_input.name_field {name of the current file} +@d synctex_tag==cur_input.synctex_tag_field {{\sl Sync\TeX} tag of the current file} @d current_ocp_lstack==cur_input.ocp_lstack_field {name of the current ocp} @d current_ocp_no==cur_input.ocp_no_field {name of the current ocp} +@d line_catcode_table==cur_input.cattable_field +@d line_partial==cur_input.partial_field @ Let's look more closely now at the control variables (|state|,~|index|,~|start|,~|loc|,~|limit|,~|name|), @@ -8615,6 +8052,8 @@ eof_seen[index]:=false; grp_stack[index]:=cur_boundary; if_stack[index]:=cond_ptr; line_stack[index]:=line; start:=first; state:=mid_line; name:=0; {|terminal_input| is now |true|} +line_catcode_table:=DEFAULT_CAT_TABLE; line_partial:=false; +@; end; @ Conversely, the variables must be downdated when such a level of input @@ -8651,6 +8090,7 @@ scanner_status:=normal; warning_index:=null; first:=1; state:=new_line; start:=1; index:=0; line:=0; name:=0; current_ocp_lstack:=0; current_ocp_no:=0; nofilter:=false; force_eof:=false; luacstrings :=0; +line_catcode_table:=DEFAULT_CAT_TABLE; line_partial:=false; align_state:=1000000;@/ if not init_terminal then goto final_end; limit:=last; first:=last+1; {|init_terminal| has set |loc| and |last|} @@ -8689,13 +8129,10 @@ when detecting a blank line. @!par_token:halfword; {token representing `\.{\\par}'} @ @= -primitive("par",par_end,too_big_char); {cf. |scan_file_name|} +primitive_tex("par",par_end,too_big_char,too_big_char); {cf.\ |scan_file_name|} @!@:par_}{\.{\\par} primitive@> par_loc:=cur_val; par_token:=cs_token_flag+par_loc; -@ @= -par_end:print_esc("par"); - @ The function |get_next| is now defined in |textoken.c|. Parts of this routine are executed more often than any other instructions of \TeX. @^mastication@>@^inner loop@> @@ -8755,9 +8192,7 @@ or the evaluation of the conditional. |get_next| has already been called. \yskip\noindent -In fact, these three procedures account for {\sl all\/} uses of |get_next|, -except for two places in the ``inner loop'' when |cur_tok| need not be set, -and except when the arguments to \.{\\ifx} are being scanned. +In fact, these three procedures account for almost every use of |get_next|. @ No new control sequences will be defined except during a call of |get_token|, or when \.{\\csname} compresses a token list, because @@ -9029,16 +8464,11 @@ end which will be declared later; the processing of \.{\\endinput} is trivial. @= -primitive("input",input,0);@/ +primitive_tex("input",input,0,0);@/ @!@:input_}{\.{\\input} primitive@> -primitive("endinput",input,1);@/ +primitive_tex("endinput",input,1,0);@/ @!@:end_input_}{\.{\\endinput} primitive@> -@ @= -input: if chr_code=0 then print_esc("input") - @/@@/ - else print_esc("endinput"); - @ @= if cur_chr=1 then force_eof:=true @/@@/ @@ -9157,42 +8587,31 @@ for i:=0 to biggest_mark do begin end; @ @= -primitive("topmark",top_bot_mark,top_mark_code); +primitive_tex("topmark",top_bot_mark,top_mark_code,0); @!@:top_mark_}{\.{\\topmark} primitive@> -primitive("firstmark",top_bot_mark,first_mark_code); +primitive_tex("firstmark",top_bot_mark,first_mark_code,0); @!@:first_mark_}{\.{\\firstmark} primitive@> -primitive("botmark",top_bot_mark,bot_mark_code); +primitive_tex("botmark",top_bot_mark,bot_mark_code,0); @!@:bot_mark_}{\.{\\botmark} primitive@> -primitive("splitfirstmark",top_bot_mark,split_first_mark_code); +primitive_tex("splitfirstmark",top_bot_mark,split_first_mark_code,0); @!@:split_first_mark_}{\.{\\splitfirstmark} primitive@> -primitive("splitbotmark",top_bot_mark,split_bot_mark_code); +primitive_tex("splitbotmark",top_bot_mark,split_bot_mark_code,0); @!@:split_bot_mark_}{\.{\\splitbotmark} primitive@> -primitive("clearmarks",mark,clear_marks_code);@/ +primitive_luatex("clearmarks",mark,clear_marks_code,0);@/ @!@:clearmarks_}{\.{\\clearmarks} primitive@> -primitive("marks",mark,marks_code); +primitive_etex("marks",mark,marks_code,0); @!@:marks_}{\.{\\marks} primitive@> -primitive("topmarks",top_bot_mark,top_mark_code+marks_code); +primitive_etex("topmarks",top_bot_mark,top_mark_code+marks_code,0); @!@:top_marks_}{\.{\\topmarks} primitive@> -primitive("firstmarks",top_bot_mark,first_mark_code+marks_code); +primitive_etex("firstmarks",top_bot_mark,first_mark_code+marks_code,0); @!@:first_marks_}{\.{\\firstmarks} primitive@> -primitive("botmarks",top_bot_mark,bot_mark_code+marks_code); +primitive_etex("botmarks",top_bot_mark,bot_mark_code+marks_code,0); @!@:bot_marks_}{\.{\\botmarks} primitive@> -primitive("splitfirstmarks",top_bot_mark,split_first_mark_code+marks_code); +primitive_etex("splitfirstmarks",top_bot_mark,split_first_mark_code+marks_code,0); @!@:split_first_marks_}{\.{\\splitfirstmarks} primitive@> -primitive("splitbotmarks",top_bot_mark,split_bot_mark_code+marks_code); +primitive_etex("splitbotmarks",top_bot_mark,split_bot_mark_code+marks_code,0); @!@:split_bot_marks_}{\.{\\splitbotmarks} primitive@> -@ @= -top_bot_mark: begin case (chr_code mod marks_code) of - first_mark_code: print_esc("firstmark"); - bot_mark_code: print_esc("botmark"); - split_first_mark_code: print_esc("splitfirstmark"); - split_bot_mark_code: print_esc("splitbotmark"); - othercases print_esc("topmark") - endcases; - if chr_code>=marks_code then print_char("s"); - end; - @ The following code is activated when |cur_cmd=top_bot_mark| and when |cur_chr| is a code like |top_mark_code|. @@ -9334,8 +8753,9 @@ if cur_tok=info(r) then @; -if cur_tok=par_token then if long_state<>long_call then - @; +if cur_tok=par_token then if long_state<>long_call then + if not suppress_long_error then + @; if cur_tok @@ -9379,6 +8799,7 @@ help6("I've run across a `}' that doesn't seem to match anything.")@/ ("argument that might be the root of the problem. But if")@/ ("your `}' was spurious, just type `2' and it will go away."); incr(align_state); long_state:=call; cur_tok:=par_token; ins_error; +goto continue; end {a white lie; the \.{\\par} won't always trigger a runaway} @ If |long_state=outer_call|, a runaway argument has already been reported. @@ -9447,7 +8868,8 @@ begin unbalance:=1; @^inner loop@> loop@+ begin fast_store_new_token(cur_tok); get_token; if cur_tok=par_token then if long_state<>long_call then - @; + if not suppress_long_error then + @; if cur_tokspacer -@ In case you are getting bored, here is a slightly less trivial routine: -Given a string of lowercase letters, like `\.{pt}' or `\.{plus}' or -`\.{width}', the |scan_keyword| routine checks to see whether the next -tokens of input match this string. The match must be exact, except that -uppercase letters will match their lowercase counterparts; uppercase -equivalents are determined by subtracting |"a"-"A"|, rather than using the -|uc_code| table, since \TeX\ uses this routine only for its own limited -set of keywords. - -If a match is found, the characters are effectively removed from the input -and |true| is returned. Otherwise |false| is returned, and the input -is left essentially unchanged (except for the fact that some macros -may have been expanded, etc.). -@^inner loop@> - -@p function scan_keyword(@!s:str_number):boolean; {look for a given string} -label exit; -var p:pointer; {tail of the backup list} -@!q:pointer; {new node being added to the token list via |store_new_token|} -@!k:pool_pointer; {index into |str_pool|} -begin -if s; - if (cur_cs=0)and((cur_chr=s)or(cur_chr=s-"a"+"A")) then - scan_keyword:=true - else - begin back_input; - scan_keyword:=false; return; - end; - end -else begin - p:=backup_head; link(p):=null; - k:=str_start_macro(s); - while k - if (cur_cs=0)and@| - ((cur_chr=so(str_pool[k]))or(cur_chr=so(str_pool[k])-"a"+"A")) then - begin store_new_token(cur_tok); incr(k); - end - else if (cur_cmd<>spacer)or(p<>backup_head) then - begin - if p<>backup_head then begin - q:=get_avail; info(q):=cur_tok; link(q):=null; - link(p) := q; - back_list(link(backup_head)); - end - else - back_input; - scan_keyword:=false; return; - end; - end; - flush_list(link(backup_head)); scan_keyword:=true; -end; -exit:end; - @ Here is a procedure that sounds an alarm when mu and non-mu units are being switched. @@ -9673,22 +9039,15 @@ as their command code; they are distinguished by the |chr_code|, which is either |int_val|, |attr_val|, |dimen_val|, |glue_val|, or |mu_val|. @= -primitive("count",register,int_val); +primitive_tex("count",register,int_val,0); @!@:count_}{\.{\\count} primitive@> -primitive("attribute",register,attr_val); +primitive_luatex("attribute",register,attr_val,0); @!@:count_}{\.{\\attribute} primitive@> -primitive("dimen",register,dimen_val); +primitive_tex("dimen",register,dimen_val,0); @!@:dimen_}{\.{\\dimen} primitive@> -primitive("skip",register,glue_val); +primitive_tex("skip",register,glue_val,0); @!@:skip_}{\.{\\skip} primitive@> -primitive("muskip",register,mu_val); - -@ @= -register: if chr_code=int_val then print_esc("count") - else if chr_code=attr_val then print_esc("attribute") - else if chr_code=dimen_val then print_esc("dimen") - else if chr_code=glue_val then print_esc("skip") - else print_esc("muskip"); +primitive_tex("muskip",register,mu_val,0); @ OK, we're ready for |scan_something_internal| itself. A second parameter, |negative|, is set |true| if the value that is found should be negated. @@ -9708,10 +9067,16 @@ var m:halfword; {|chr_code| part of the operand token} @!p:0..nest_size; {index into |nest|} begin m:=cur_chr; case cur_cmd of -def_code: @; -extdef_code: @; -toks_register,assign_toks,def_family,set_font,def_font,letterspace_font: @; +def_char_code: @; +def_del_code: @; +extdef_math_code: @; +extdef_del_code: @; +toks_register,assign_toks,set_font,def_font,letterspace_font,pdf_copy_font: + @; +def_family: + @; +set_math_param: + @; assign_int: scanned_result(eqtb[m].int)(int_val); assign_attr: scanned_result(eqtb[m].int)(int_val); assign_box_dir: begin @@ -9729,9 +9094,10 @@ set_aux: @; set_prev_graf: @; set_page_int:@; set_page_dimen: @; -set_shape: @; +set_tex_shape: @; +set_etex_shape: @; set_box_dimen: @; -char_given,math_given,omath_given: scanned_result(cur_chr)(int_val); +char_given,math_given,omath_given,xmath_given: scanned_result(cur_chr)(int_val); assign_font_dimen: @; assign_font_int: @; register: @; @@ -9746,9 +9112,13 @@ procedure scan_something_simple(@!cmd:halfword;@!subitem:halfword); {fetch an internal parameter} label exit; var m:halfword; {|chr_code| part of the operand token} +@!q:halfword; {general purpose index} @!p:0..nest_size; {index into |nest|} @!level:small_number; { allowed level} -begin m:=subitem; level:=tok_val; +@!negative:boolean; +@!save_cur_chr:integer; +begin m:=subitem; level:=tok_val; +negative:=false; {never actually used, added for etexs |last_item| cases} case cmd of assign_toks: scanned_result(equiv(m))(tok_val); assign_int: scanned_result(eqtb[m].int)(int_val); @@ -9761,8 +9131,16 @@ set_aux: @; set_prev_graf: @; set_page_int:@; set_page_dimen: @; -set_shape: @; -char_given,math_given,omath_given: scanned_result(m)(int_val); {TH: TODO, doesnt work} +set_tex_shape: @; +set_etex_shape: @; +last_item: begin + save_cur_chr:=cur_chr; + cur_chr:=subitem; + @; + cur_chr:=save_cur_chr; + end; +char_given,math_given,omath_given,xmath_given: + scanned_result(m)(int_val); {TH: TODO, doesnt work} othercases @ endcases;@/ exit:end; @@ -9770,18 +9148,7 @@ exit:end; @ @= begin scan_char_num; if m=math_code_base then begin - cur_val1:=get_math_code(cur_val); - if ((cur_val1 div @"1000000)>8) or - (((cur_val1 mod @"1000000) div @"10000)>15) or - ((cur_val1 mod @"10000)>255) then - begin print_err("Extended mathchar used as mathchar"); -@.Bad mathchar@> - help2("A mathchar number must be between 0 and ""7FFF.")@/ - ("I changed this one to zero."); int_error(cur_val1); cur_val1:=0; - end; - cur_val1:=((cur_val1 div @"1000000)*@"1000) + - (((cur_val1 mod @"1000000) div @"10000)*@"100) + - (cur_val1 mod @"10000); + cur_val1:=get_math_code_num(cur_val); scanned_result(cur_val1)(int_val); end else if m=lc_code_base then begin @@ -9806,7 +9173,10 @@ end @ @= begin scan_char_num; -if m=math_code_base then scanned_result(get_math_code(cur_val))(int_val) +if m=math_code_base then begin + cur_val1:=get_math_code_num(cur_val); + scanned_result(cur_val1)(int_val); + end { TH: next two lines should not be possible } else if m= +begin scan_char_num; cur_val1:=fam_fnt(cur_val,m); + scanned_result(cur_val1)(int_val); + end + +@ @= +begin cur_val1:=cur_chr; get_token; + if cur_cmd<>math_style then + begin print_err("Missing math style, treated as \\displaystyle"); +@.Missing number...@> + help1("A style should have been here; I inserted `\\displaystyle'."); + cur_val:=display_style; + back_error; + end + else + cur_val:=cur_chr; + if cur_val1= -primitive("spacefactor",set_aux,hmode); +primitive_tex("spacefactor",set_aux,hmode,0); @!@:space_factor_}{\.{\\spacefactor} primitive@> -primitive("prevdepth",set_aux,vmode);@/ +primitive_tex("prevdepth",set_aux,vmode,0);@/ @!@:prev_depth_}{\.{\\prevdepth} primitive@> -primitive("deadcycles",set_page_int,0); +primitive_tex("deadcycles",set_page_int,0,0); @!@:dead_cycles_}{\.{\\deadcycles} primitive@> -primitive("insertpenalties",set_page_int,1); +primitive_tex("insertpenalties",set_page_int,1,0); @!@:insert_penalties_}{\.{\\insertpenalties} primitive@> -primitive("wd",set_box_dimen,width_offset); +primitive_tex("wd",set_box_dimen,width_offset,0); @!@:wd_}{\.{\\wd} primitive@> -primitive("ht",set_box_dimen,height_offset); +primitive_tex("ht",set_box_dimen,height_offset,0); @!@:ht_}{\.{\\ht} primitive@> -primitive("dp",set_box_dimen,depth_offset); +primitive_tex("dp",set_box_dimen,depth_offset,0); @!@:dp_}{\.{\\dp} primitive@> -primitive("lastpenalty",last_item,int_val); +primitive_tex("lastpenalty",last_item,int_val,0); @!@:last_penalty_}{\.{\\lastpenalty} primitive@> -primitive("lastkern",last_item,dimen_val); +primitive_tex("lastkern",last_item,dimen_val,0); @!@:last_kern_}{\.{\\lastkern} primitive@> -primitive("lastskip",last_item,glue_val); +primitive_tex("lastskip",last_item,glue_val,0); @!@:last_skip_}{\.{\\lastskip} primitive@> -primitive("inputlineno",last_item,input_line_no_code); +primitive_tex("inputlineno",last_item,input_line_no_code,0); @!@:input_line_no_}{\.{\\inputlineno} primitive@> -primitive("badness",last_item,badness_code); +primitive_tex("badness",last_item,badness_code,0); @!@:badness_}{\.{\\badness} primitive@> -primitive("pdftexversion",last_item,pdftex_version_code);@/ +primitive_pdftex("pdftexversion",last_item,pdftex_version_code,0);@/ @!@:pdftex_version_}{\.{\\pdftexversion} primitive@> -primitive("luatexversion",last_item,luatex_version_code);@/ +primitive_luatex("luatexversion",last_item,luatex_version_code,0);@/ @!@:luatex_version_}{\.{\\luatexversion} primitive@> -primitive("pdflastobj",last_item,pdf_last_obj_code);@/ +primitive_pdftex("pdflastobj",last_item,pdf_last_obj_code,0);@/ @!@:pdf_last_obj_}{\.{\\pdflastobj} primitive@> -primitive("pdflastxform",last_item,pdf_last_xform_code);@/ +primitive_pdftex("pdflastxform",last_item,pdf_last_xform_code,0);@/ @!@:pdf_last_xform_}{\.{\\pdflastxform} primitive@> -primitive("pdflastximage",last_item,pdf_last_ximage_code);@/ +primitive_pdftex("pdflastximage",last_item,pdf_last_ximage_code,0);@/ @!@:pdf_last_ximage_}{\.{\\pdflastximage} primitive@> -primitive("pdflastximagepages",last_item,pdf_last_ximage_pages_code);@/ +primitive_pdftex("pdflastximagepages",last_item,pdf_last_ximage_pages_code,0);@/ @!@:pdf_last_ximage_pages_}{\.{\\pdflastximagepages} primitive@> -primitive("pdflastannot",last_item,pdf_last_annot_code);@/ +primitive_pdftex("pdflastannot",last_item,pdf_last_annot_code,0);@/ @!@:pdf_last_annot_}{\.{\\pdflastannot} primitive@> -primitive("pdflastxpos",last_item,pdf_last_x_pos_code);@/ +primitive_pdftex("pdflastxpos",last_item,pdf_last_x_pos_code,0);@/ @!@:pdf_last_x_pos_}{\.{\\pdflastxpos} primitive@> -primitive("pdflastypos",last_item,pdf_last_y_pos_code);@/ +primitive_pdftex("pdflastypos",last_item,pdf_last_y_pos_code,0);@/ @!@:pdf_last_y_pos_}{\.{\\pdflastypos} primitive@> -primitive("pdfretval",last_item,pdf_retval_code);@/ +primitive_pdftex("pdfretval",last_item,pdf_retval_code,0);@/ @!@:pdf_retval_}{\.{\\pdfretval} primitive@> -primitive("pdflastximagecolordepth",last_item,pdf_last_ximage_colordepth_code);@/ +primitive_pdftex("pdflastximagecolordepth",last_item,pdf_last_ximage_colordepth_code,0);@/ @!@:pdf_last_ximage_colordepth_}{\.{\\pdflastximagecolordepth} primitive@> -primitive("pdfrandomseed",last_item,random_seed_code); +primitive_pdftex("pdfrandomseed",last_item,random_seed_code,0); @!@:random_seed_}{\.{\\pdfrandomseed} primitive@> -primitive("pdflastlink",last_item,pdf_last_link_code);@/ +primitive_pdftex("pdflastlink",last_item,pdf_last_link_code,0);@/ @!@:pdf_last_link_}{\.{\\pdflastlink} primitive@> -@ @= -set_aux: if chr_code=vmode then print_esc("prevdepth") -@+else print_esc("spacefactor"); -set_page_int: if chr_code=0 then print_esc("deadcycles") -@/@@/ -@+else print_esc("insertpenalties"); -set_box_dimen: if chr_code=width_offset then print_esc("wd") -else if chr_code=height_offset then print_esc("ht") -else print_esc("dp"); -last_item: case chr_code of - int_val: print_esc("lastpenalty"); - dimen_val: print_esc("lastkern"); - glue_val: print_esc("lastskip"); - input_line_no_code: print_esc("inputlineno"); - @/@@/ - pdftex_version_code: print_esc("pdftexversion"); - luatex_version_code: print_esc("luatexversion"); - pdf_last_obj_code: print_esc("pdflastobj"); - pdf_last_xform_code: print_esc("pdflastxform"); - pdf_last_ximage_code: print_esc("pdflastximage"); - pdf_last_ximage_pages_code: print_esc("pdflastximagepages"); - pdf_last_annot_code: print_esc("pdflastannot"); - pdf_last_x_pos_code: print_esc("pdflastxpos"); - pdf_last_y_pos_code: print_esc("pdflastypos"); - pdf_retval_code: print_esc("pdfretval"); - pdf_last_ximage_colordepth_code: print_esc("pdflastximagecolordepth"); - random_seed_code: print_esc("pdfrandomseed"); - pdf_last_link_code: print_esc("pdflastlink"); - othercases print_esc("badness") - endcases; - @ @= if abs(mode)<>m then begin print_err("Improper "); print_cmd_chr(set_aux,m); @@ -9968,11 +9343,8 @@ if abs(mode)<>m then if level<>tok_val then scanned_result(0)(dimen_val) else scanned_result(0)(int_val); end -else if m=vmode then - begin cur_val:=prev_depth; cur_val_level:=dimen_val; - end -else begin cur_val:=space_factor; cur_val_level:=int_val; - end +else if m=vmode then scanned_result(prev_depth)(dimen_val) +else scanned_result(space_factor)(int_val) @ @= begin if m=0 then cur_val:=dead_cycles @@ -10007,9 +9379,8 @@ else begin nest[nest_ptr]:=cur_list; p:=nest_ptr; end @ @= -begin if m>par_shape_loc then @ -else if par_shape_ptr=null then cur_val:=0 -else cur_val:=vinfo(par_shape_ptr); +begin if par_shape_ptr=null then cur_val:=0 +else cur_val:=vinfo(par_shape_ptr+1); cur_val_level:=int_val; end @@ -10186,6 +9557,9 @@ applications of |scan_int| that have already been made inside of @d dir_prev_end(#)==((#) mod 4) @d dir_prev(#)==(((#)+1) mod 4)=dir_prev_end +@d dir_horizontal(#)==(((#)=dir_L) or ((#)=dir_R)) +@d dir_vertical(#)==(((#)=dir_T) or ((#)=dir_B)) + {box directions} @d dir_TL_=0 @d dir_TR_=1 @@ -10214,43 +9588,11 @@ applications of |scan_int| that have already been made inside of @d dir__BB=14 @d dir__BR=15 -@d is_mirrored(#)==dir_opposite(dir_primary[#])(dir_tertiary[#]) -@d is_rotated(#)==dir_parallel(dir_secondary[#])(dir_tertiary[#]) +@d is_mirrored(#)==(dir_opposite(dir_primary[#])(dir_tertiary[#])) +@d is_rotated(#)==(dir_parallel(dir_secondary[#])(dir_tertiary[#])) @d font_direction(#)==(# mod 16) @d box_direction(#)==(# div 4) -@d scan_single_dir(#)==begin -if scan_keyword("T") then #:=dir_T -else if scan_keyword("L") then #:=dir_L -else if scan_keyword("B") then #:=dir_B -else if scan_keyword("R") then #:=dir_R -else begin - print_err("Bad direction"); cur_val:=0; - goto exit; - end -end - -@= -procedure scan_direction; -var d1,d2,d3: integer; -begin -get_x_token; -if cur_cmd=assign_dir then begin - cur_val:=eqtb[cur_chr].int; - goto exit; - end -else back_input; -scan_single_dir(d1); -scan_single_dir(d2); -if dir_parallel(d1)(d2) then begin - print_err("Bad direction"); cur_val:=0; - goto exit; - end; -scan_single_dir(d3); -cur_val:=d1*8+dir_rearrange[d2]*4+d3; -exit: -end; - @ It is nice to have routines that say what they do, so the original |scan_eight_bit_int| is superceded by |scan_register_num| and |scan_mark_num|. It may become split up even further in the future. @@ -10351,12 +9693,6 @@ if (cur_val<0)or(cur_val>@'777777777) then help2("A numeric delimiter code must be between 0 and 2^{27}-1.")@/ ("I changed this one to zero."); int_error(cur_val); cur_val:=0; end; -cur_val1 := (((cur_val mod @"1000) div @"100) * @"10000) + - (cur_val mod @"100); -cur_val := cur_val div @"1000; -cur_val := ((cur_val div @"1000) * @"1000000) + - (((cur_val mod @"1000) div @"100) * @"10000) + - (cur_val mod @"100); end; procedure scan_fifty_one_bit_int; @@ -10430,7 +9766,7 @@ comes into action before any of the basic scanning routines has assigned them a value. @= -cur_val:=0; cur_val_level:=int_val; radix:=0; cur_order:=0; +cur_val:=0; cur_val_level:=int_val; radix:=0; cur_order:=normal; @ The |scan_int| routine is used also to scan the integer part of a fraction; for example, the `\.3' in `\.{3.14159}' will be found by @@ -10473,10 +9809,10 @@ if cur_tok; @; if mu then @; -if scan_keyword("true") then @; +if scan_keyword('true') then @; @.true@> -if scan_keyword("pt") then goto attach_fraction; {the easy case} +if scan_keyword('pt') then goto attach_fraction; {the easy case} @.pt@> @; @@ -10689,10 +10025,10 @@ L}' will lead to two error messages (one for each additional keyword Not so for luatex, it just parses the construct in reverse. @= -if scan_keyword("filll") then begin cur_order:=filll; goto attach_fraction; end -else if scan_keyword("fill") then begin cur_order:=fill; goto attach_fraction; end -else if scan_keyword("fil") then begin cur_order:=fil; goto attach_fraction; end -else if scan_keyword("fi") then begin cur_order:=sfi; goto attach_fraction; end +if scan_keyword('filll') then begin cur_order:=filll; goto attach_fraction; end +else if scan_keyword('fill') then begin cur_order:=fill; goto attach_fraction; end +else if scan_keyword('fil') then begin cur_order:=fil; goto attach_fraction; end +else if scan_keyword('fi') then begin cur_order:=sfi; goto attach_fraction; end @ @= save_cur_val:=cur_val; @@ -10706,11 +10042,11 @@ else begin if mu then v:=cur_val; goto found; end; if mu then goto not_found; -if scan_keyword("em") then v:=(@) +if scan_keyword('em') then v:=(@) @.em@> -else if scan_keyword("ex") then v:=(@) +else if scan_keyword('ex') then v:=(@) @.ex@> -else if scan_keyword("px") then v:=pdf_px_dimen +else if scan_keyword('px') then v:=pdf_px_dimen @.px@> else goto not_found; @; @@ -10719,7 +10055,7 @@ goto attach_sign; not_found: @ @= -if scan_keyword("mu") then goto attach_fraction +if scan_keyword('mu') then goto attach_fraction @.mu@> else begin print_err("Illegal unit of measure ("); print("mu inserted)"); @.Illegal unit of measure@> @@ -10749,36 +10085,37 @@ in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980). The Didot point has been newly standardized in 1978; it's now exactly $\rm 1\,nd=0.375\,mm$. Conversion uses the equation $0.375=21681/20320/72.27\cdot25.4$. -The new Cicero follows the new Didot point; $\rm 1\,nc=12\,nd$. These -would lead to the ratios $21681/20320$ and $65043/5080$, respectively. +The new Cicero follows the new Didot point; $\rm 1\,nc=12\,nd$. +These would lead to the ratios $21681/20320$ and $65043/5080$, +respectively. The closest approximations supported by the algorithm would be $11183/10481$ and $1370/107$. In order to maintain the -relation $\rm 1\,nc=12\,nd$, we pick the ratio $685/642$ for $\rm nd$, -however. +relation $\rm 1\,nc=12\,nd$, we pick the ratio $685/642$ for +$\rm nd$, however. @d set_conversion_end(#)== denom:=#; end @d set_conversion(#)==@+begin num:=#; set_conversion_end @= -if scan_keyword("in") then set_conversion(7227)(100) +if scan_keyword('in') then set_conversion(7227)(100) @.in@> -else if scan_keyword("pc") then set_conversion(12)(1) +else if scan_keyword('pc') then set_conversion(12)(1) @.pc@> -else if scan_keyword("cm") then set_conversion(7227)(254) +else if scan_keyword('cm') then set_conversion(7227)(254) @.cm@> -else if scan_keyword("mm") then set_conversion(7227)(2540) +else if scan_keyword('mm') then set_conversion(7227)(2540) @.mm@> -else if scan_keyword("bp") then set_conversion(7227)(7200) +else if scan_keyword('bp') then set_conversion(7227)(7200) @.bp@> -else if scan_keyword("dd") then set_conversion(1238)(1157) +else if scan_keyword('dd') then set_conversion(1238)(1157) @.dd@> -else if scan_keyword("cc") then set_conversion(14856)(1157) +else if scan_keyword('cc') then set_conversion(14856)(1157) @.cc@> -else if scan_keyword("nd") then set_conversion(685)(642) +else if scan_keyword('nd') then set_conversion(685)(642) @.nd@> -else if scan_keyword("nc") then set_conversion(1370)(107) +else if scan_keyword('nc') then set_conversion(1370)(107) @.nc@> -else if scan_keyword("sp") then goto done +else if scan_keyword('sp') then goto done @.sp@> else @; cur_val:=xn_over_d(cur_val,num,denom); @@ -10845,12 +10182,12 @@ exit:end; @ @= q:=new_spec(zero_glue); width(q):=cur_val; -if scan_keyword("plus") then +if scan_keyword('plus') then @.plus@> begin scan_dimen(mu,true,false); stretch(q):=cur_val; stretch_order(q):=cur_order; end; -if scan_keyword("minus") then +if scan_keyword('minus') then @.minus@> begin scan_dimen(mu,true,false); shrink(q):=cur_val; shrink_order(q):=cur_order; @@ -10878,15 +10215,15 @@ else begin height(q):=default_rule; depth(q):=0; rule_dir(q):=text_direction; end; -reswitch: if scan_keyword("width") then +reswitch: if scan_keyword('width') then @.width@> begin scan_normal_dimen; width(q):=cur_val; goto reswitch; end; -if scan_keyword("height") then +if scan_keyword('height') then @.height@> begin scan_normal_dimen; height(q):=cur_val; goto reswitch; end; -if scan_keyword("depth") then +if scan_keyword('depth') then @.depth@> begin scan_normal_dimen; depth(q):=cur_val; goto reswitch; end; @@ -11078,104 +10415,74 @@ such that |job_name_code| remains last. @d pdf_colorstack_init_code = pdftex_first_expand_code + 16 {command code for \.{\\pdfcolorstackinit}} @d luatex_revision_code = pdftex_first_expand_code + 17 {command code for \.{\\luatexrevision}} @d luatex_date_code = pdftex_first_expand_code + 18 {command code for \.{\\luatexdate}} -@d pdftex_convert_codes = pdftex_first_expand_code + 19 {end of \pdfTeX's command codes} +@d expanded_code = pdftex_first_expand_code + 19 {command code for \.{\\luatexdate}} +@d pdftex_convert_codes = pdftex_first_expand_code + 20 {end of \pdfTeX's command codes} @d job_name_code=pdftex_convert_codes {command code for \.{\\jobname}} @= -primitive("number",convert,number_code);@/ +primitive_tex("number",convert,number_code,0);@/ @!@:number_}{\.{\\number} primitive@> -primitive("romannumeral",convert,roman_numeral_code);@/ +primitive_tex("romannumeral",convert,roman_numeral_code,0);@/ @!@:roman_numeral_}{\.{\\romannumeral} primitive@> -primitive("string",convert,string_code);@/ +primitive_tex("string",convert,string_code,0);@/ @!@:string_}{\.{\\string} primitive@> -primitive("meaning",convert,meaning_code);@/ +primitive_tex("meaning",convert,meaning_code,0);@/ @!@:meaning_}{\.{\\meaning} primitive@> -primitive("eTeXVersion",convert,etex_code);@/ +primitive_etex("eTeXVersion",convert,etex_code,0);@/ @!@:omega_version_}{\.{\\OmegaVersion} primitive@> -primitive("OmegaVersion",convert,omega_code);@/ +primitive_omega("OmegaVersion",convert,omega_code,0);@/ @!@:omega_version_}{\.{\\OmegaVersion} primitive@> -primitive("AlephVersion",convert,aleph_code);@/ +primitive_aleph("AlephVersion",convert,aleph_code,0);@/ @!@:aleph_version_}{\.{\\AlephVersion} primitive@> -primitive("fontname",convert,font_name_code);@/ +primitive_tex("fontname",convert,font_name_code,0);@/ @!@:font_name_}{\.{\\fontname} primitive@> -primitive("pdftexrevision",convert,pdftex_revision_code);@/ +primitive_pdftex("pdftexrevision",convert,pdftex_revision_code,0);@/ @!@:pdftex_revision_}{\.{\\pdftexrevision} primitive@> -primitive("luatexrevision",convert,luatex_revision_code);@/ +primitive_luatex("luatexrevision",convert,luatex_revision_code,0);@/ @!@:luatex_revision_}{\.{\\luatexrevision} primitive@> -primitive("luatexdatestamp",convert,luatex_date_code);@/ +primitive_luatex("luatexdatestamp",convert,luatex_date_code,0);@/ @!@:luatex_date_}{\.{\\luatexdatestamp} primitive@> -primitive("pdftexbanner",convert,pdftex_banner_code);@/ +primitive_pdftex("pdftexbanner",convert,pdftex_banner_code,0);@/ @!@:pdftex_banner_}{\.{\\pdftexbanner} primitive@> -primitive("pdffontname",convert,pdf_font_name_code);@/ +primitive_pdftex("pdffontname",convert,pdf_font_name_code,0);@/ @!@:pdf_font_name_}{\.{\\pdffontname} primitive@> -primitive("pdffontobjnum",convert,pdf_font_objnum_code);@/ +primitive_pdftex("pdffontobjnum",convert,pdf_font_objnum_code,0);@/ @!@:pdf_font_objnum_}{\.{\\pdffontobjnum} primitive@> -primitive("pdffontsize",convert,pdf_font_size_code);@/ +primitive_pdftex("pdffontsize",convert,pdf_font_size_code,0);@/ @!@:pdf_font_size_}{\.{\\pdffontsize} primitive@> -primitive("pdfpageref",convert,pdf_page_ref_code);@/ +primitive_pdftex("pdfpageref",convert,pdf_page_ref_code,0);@/ @!@:pdf_page_ref_}{\.{\\pdfpageref} primitive@> -primitive("leftmarginkern",convert,left_margin_kern_code);@/ +primitive_pdftex("leftmarginkern",convert,left_margin_kern_code,0);@/ @!@:left_margin_kern_}{\.{\\leftmarginkern} primitive@> -primitive("rightmarginkern",convert,right_margin_kern_code);@/ +primitive_pdftex("rightmarginkern",convert,right_margin_kern_code,0);@/ @!@:right_margin_kern_}{\.{\\rightmarginkern} primitive@> -primitive("pdfxformname",convert,pdf_xform_name_code);@/ +primitive_pdftex("pdfxformname",convert,pdf_xform_name_code,0);@/ @!@:pdf_xform_name_}{\.{\\pdfxformname} primitive@> -primitive("pdfcreationdate",convert,pdf_creation_date_code);@/ +primitive_pdftex("pdfcreationdate",convert,pdf_creation_date_code,0);@/ @!@:pdf_creation_date_}{\.{\\pdfcreationdate} primitive@> -primitive("pdfuniformdeviate",convert,uniform_deviate_code);@/ +primitive_pdftex("pdfuniformdeviate",convert,uniform_deviate_code,0);@/ @!@:uniform_deviate_}{\.{\\pdfuniformdeviate} primitive@> -primitive("pdfcolorstackinit",convert,pdf_colorstack_init_code);@/ +primitive_pdftex("pdfcolorstackinit",convert,pdf_colorstack_init_code,0);@/ @!@:pdf_colorstack_init_}{\.{\\pdfcolorstackinit} primitive@> -primitive("pdfnormaldeviate",convert,normal_deviate_code);@/ +primitive_pdftex("pdfnormaldeviate",convert,normal_deviate_code,0);@/ @!@:normal_deviate_}{\.{\\pdfnormaldeviate} primitive@> -primitive("directlua",convert,lua_code);@/ +primitive_core("directlua",convert,lua_code,0);@/ @!@:lua_}{\.{\\directlua} primitive@> -primitive("luaescapestring",convert,lua_escape_string_code);@/ +primitive_luatex("luaescapestring",convert,lua_escape_string_code,0);@/ @!@:lua_}{\.{\\luaescapestring} primitive@> +primitive_pdftex("expanded",convert,expanded_code,0);@/ +@!@:expanded_}{\.{\\expanded} primitive@> @# -primitive("jobname",convert,job_name_code);@/ +primitive_tex("jobname",convert,job_name_code,0);@/ @!@:job_name_}{\.{\\jobname} primitive@> -primitive("formatname",convert,format_name_code);@/ +primitive_luatex("formatname",convert,format_name_code,0);@/ @!@:format_name_}{\.{\\formatname} primitive@> -primitive("pdfinsertht",convert,pdf_insert_ht_code);@/ +primitive_pdftex("pdfinsertht",convert,pdf_insert_ht_code,0);@/ @!@:pdf_insert_ht_}{\.{\\pdfinsertht} primitive@> -primitive("pdfximagebbox",convert,pdf_ximage_bbox_code);@/ +primitive_pdftex("pdfximagebbox",convert,pdf_ximage_bbox_code,0);@/ @!@:pdf_ximage_bbox_}{\.{\\pdfximagebbox} primitive@> -@ @= -convert: case chr_code of - number_code: print_esc("number"); - roman_numeral_code: print_esc("romannumeral"); - string_code: print_esc("string"); - meaning_code: print_esc("meaning"); - etex_code: print_esc("eTeXVersion"); - omega_code: print_esc("OmegaVersion"); - aleph_code: print_esc("AlephVersion"); - font_name_code: print_esc("fontname"); - pdftex_revision_code: print_esc("pdftexrevision"); - luatex_revision_code: print_esc("luatexrevision"); - luatex_date_code: print_esc("luatexdatestamp"); - pdftex_banner_code: print_esc("pdftexbanner"); - pdf_font_name_code: print_esc("pdffontname"); - pdf_font_objnum_code: print_esc("pdffontobjnum"); - pdf_font_size_code: print_esc("pdffontsize"); - pdf_page_ref_code: print_esc("pdfpageref"); - left_margin_kern_code: print_esc("leftmarginkern"); - right_margin_kern_code: print_esc("rightmarginkern"); - pdf_xform_name_code: print_esc("pdfxformname"); - pdf_creation_date_code: print_esc("pdfcreationdate"); - pdf_colorstack_init_code: print_esc("pdfcolorstackinit"); - uniform_deviate_code: print_esc("pdfuniformdeviate"); - normal_deviate_code: print_esc("pdfnormaldeviate"); - pdf_insert_ht_code: print_esc("pdfinsertht"); - pdf_ximage_bbox_code: print_esc("pdfximagebbox"); - lua_code: print_esc("directlua"); - lua_escape_string_code: print_esc("luaescapestring"); - @/@@/ - othercases print_esc("jobname") - endcases; - @ The procedure |conv_toks| uses |str_toks| to insert the token list for |convert| functions into the scanner; `\.{\\outer}' control sequences are allowed to follow `\.{\\string}' and `\.{\\meaning}'. @@ -11200,6 +10507,7 @@ p, q: pointer; @!j: integer; {second temp integer} @!b:pool_pointer; {base of temporary string} @!s: str_number; {first temp string} +@!sn: integer; {lua chunk name} @!u: str_number; {third temp string} @!junk: pointer; begin @@ -11213,6 +10521,12 @@ selector:=old_setting; junk:=str_toks(b); ins_list(link(temp_token_head)); exit: end; +@ @= +in_lua_escape:boolean; + +@ @= +in_lua_escape:=false; + @ @= case c of number_code,roman_numeral_code: scan_int; @@ -11262,11 +10576,11 @@ pdf_creation_date_code: job_name_code: if job_name=0 then open_log_file; pdf_colorstack_init_code: begin - bool := scan_keyword("page"); - if scan_keyword("direct") then + bool := scan_keyword('page'); + if scan_keyword('direct') then cur_val := direct_always else - if scan_keyword("page") then + if scan_keyword('page') then cur_val := direct_page else cur_val := set_origin; @@ -11297,54 +10611,77 @@ uniform_deviate_code: scan_int; normal_deviate_code: do_nothing; lua_escape_string_code: begin - u:=0; + u:=0; { check if a string is already being built} if str_start_macro(str_ptr)0 then begin decr(str_ptr); u:=0; end; + if u<>0 then begin decr(str_ptr); u:=0; end; + return; + end; +expanded_code: + begin + save_scanner_status := scanner_status; + save_warning_index := warning_index; + save_def_ref := def_ref; + save_cur_string; + scan_pdf_ext_toks; + warning_index := save_warning_index; + scanner_status := save_scanner_status; + ins_list(link(def_ref)); + def_ref := save_def_ref; + restore_cur_string; return; end; lua_code: begin - u:=0; - { check if a string is already being built} + u:=0; + { Have to check if a string is already being built, because lua code + may call library functions that may call C functions that + themselves use the string pool, like e.g. |maketexstring| } if str_start_macro(str_ptr); scan_pdf_ext_toks; s := def_ref; warning_index := save_warning_index; def_ref := save_def_ref; scanner_status := save_scanner_status; luacstrings:=0; - luatokencall(i,s); + luatokencall(s,sn); delete_token_ref(s); - if u<>0 then begin + if u<>0 then begin if str_ptr=u+1 then decr(str_ptr) else begin {copy old string to the top location} i:=0; - str_room(length(u)); + str_room(length(u)); while i0 then - lua_string_start; + if luacstrings>0 then + lua_string_start; return; end; pdf_insert_ht_code: scan_register_num; @@ -11360,6 +10697,26 @@ pdf_ximage_bbox_code: begin @ end {there are no other cases} +@ @= +begin + @; + back_input; { have to push it back, whatever it is } + if cur_cmd<>left_brace then begin + scan_register_num; + if get_lua_name(cur_val) then + sn:=(cur_val-65536) + else begin + i:=tracing_online; + tracing_online:=1; + begin_diagnostic; + print_nl("Warning: support for multiple lua states has been dropped."); + print_nl(" Please stop using a number after \directlua and \latelua."); + end_diagnostic(true); + tracing_online:=i; + end; + end; +end + @ @= case c of number_code: print_int(cur_val); @@ -11437,12 +10794,15 @@ pdf_insert_ht_code: begin print("pt"); end; pdf_ximage_bbox_code: begin - case j of - 1: print_scaled(epdf_orig_x(i)); - 2: print_scaled(epdf_orig_y(i)); - 3: print_scaled(epdf_orig_x(i) + image_width(i)); - 4: print_scaled(epdf_orig_y(i) + image_height(i)); - endcases; + if is_pdf_image(i) then begin + case j of + 1: print_scaled(epdf_orig_x(i)); + 2: print_scaled(epdf_orig_y(i)); + 3: print_scaled(epdf_orig_x(i) + epdf_xsize(i)); + 4: print_scaled(epdf_orig_y(i) + epdf_ysize(i)); + endcases; + end else + print_scaled(0); print("pt"); end; format_name_code: print(format_name); @@ -11456,24 +10816,49 @@ begin is_convert:=(c=convert); end; -function the_convert_string (c:halfword):str_number; +function the_convert_string (c:halfword;i:integer):str_number; var old_setting:0..max_selector; {saved |selector| setting} - is_known:boolean; + is_known:boolean; begin old_setting:=selector; selector:=new_string; is_known:=true; case c of - etex_code: print(eTeX_version_string); - omega_code: print(Omega_version_string); - aleph_code: print(Aleph_version_string); - pdftex_revision_code: print(pdftex_revision); - luatex_revision_code: print(luatex_revision); - luatex_date_code: print_int(luatex_date_info); - pdftex_banner_code: print(pdftex_banner); - normal_deviate_code: print_int(norm_rand); - format_name_code: print(format_name); - job_name_code: print(job_name); + number_code: print_int(i); + roman_numeral_code: print_roman_int(i); + etex_code: print(eTeX_version_string); + omega_code: print(Omega_version_string); + aleph_code: print(Aleph_version_string); + pdftex_revision_code: print(pdftex_revision); + luatex_revision_code: print(luatex_revision); + luatex_date_code: print_int(luatex_date_info); + pdftex_banner_code: print(pdftex_banner); + normal_deviate_code: print_int(norm_rand); + uniform_deviate_code: print_int(unif_rand(i)); + format_name_code: print(format_name); + job_name_code: print(job_name); + font_name_code: begin + append_string(font_name(i)); + if font_size(i)<>font_dsize(i) then + begin print(" at "); print_scaled(font_size(i)); + print("pt"); + end; + end; + font_identifier_code: print_font_identifier(i); + pdf_page_ref_code: print_int(get_obj(obj_type_page, i, false)); + pdf_xform_name_code: print_int(obj_info(i)); + pdf_font_name_code, pdf_font_objnum_code: begin + set_ff(i); + if c = pdf_font_name_code then + print_int(obj_info(pdf_font_num(ff))) + else + print_int(pdf_font_num(ff)); + end; + pdf_font_size_code: begin + print_scaled(font_size(i)); + print("pt"); + end; + @/@@/ othercases is_known:=false end; @@ -11747,70 +11132,45 @@ We consider now the way \TeX\ handles various kinds of \.{\\if} commands. @d if_primitive_code=21 { `\.{\\ifprimitive}' } @= -primitive("if",if_test,if_char_code); +primitive_tex("if",if_test,if_char_code,0); @!@:if_char_}{\.{\\if} primitive@> -primitive("ifcat",if_test,if_cat_code); +primitive_tex("ifcat",if_test,if_cat_code,0); @!@:if_cat_code_}{\.{\\ifcat} primitive@> -primitive("ifnum",if_test,if_int_code); +primitive_tex("ifnum",if_test,if_int_code,0); @!@:if_int_}{\.{\\ifnum} primitive@> -primitive("ifdim",if_test,if_dim_code); +primitive_tex("ifdim",if_test,if_dim_code,0); @!@:if_dim_}{\.{\\ifdim} primitive@> -primitive("ifodd",if_test,if_odd_code); +primitive_tex("ifodd",if_test,if_odd_code,0); @!@:if_odd_}{\.{\\ifodd} primitive@> -primitive("ifvmode",if_test,if_vmode_code); +primitive_tex("ifvmode",if_test,if_vmode_code,0); @!@:if_vmode_}{\.{\\ifvmode} primitive@> -primitive("ifhmode",if_test,if_hmode_code); +primitive_tex("ifhmode",if_test,if_hmode_code,0); @!@:if_hmode_}{\.{\\ifhmode} primitive@> -primitive("ifmmode",if_test,if_mmode_code); +primitive_tex("ifmmode",if_test,if_mmode_code,0); @!@:if_mmode_}{\.{\\ifmmode} primitive@> -primitive("ifinner",if_test,if_inner_code); +primitive_tex("ifinner",if_test,if_inner_code,0); @!@:if_inner_}{\.{\\ifinner} primitive@> -primitive("ifvoid",if_test,if_void_code); +primitive_tex("ifvoid",if_test,if_void_code,0); @!@:if_void_}{\.{\\ifvoid} primitive@> -primitive("ifhbox",if_test,if_hbox_code); +primitive_tex("ifhbox",if_test,if_hbox_code,0); @!@:if_hbox_}{\.{\\ifhbox} primitive@> -primitive("ifvbox",if_test,if_vbox_code); +primitive_tex("ifvbox",if_test,if_vbox_code,0); @!@:if_vbox_}{\.{\\ifvbox} primitive@> -primitive("ifx",if_test,ifx_code); +primitive_tex("ifx",if_test,ifx_code,0); @!@:ifx_}{\.{\\ifx} primitive@> -primitive("ifeof",if_test,if_eof_code); +primitive_tex("ifeof",if_test,if_eof_code,0); @!@:if_eof_}{\.{\\ifeof} primitive@> -primitive("iftrue",if_test,if_true_code); +primitive_tex("iftrue",if_test,if_true_code,0); @!@:if_true_}{\.{\\iftrue} primitive@> -primitive("iffalse",if_test,if_false_code); +primitive_tex("iffalse",if_test,if_false_code,0); @!@:if_false_}{\.{\\iffalse} primitive@> -primitive("ifcase",if_test,if_case_code); +primitive_tex("ifcase",if_test,if_case_code,0); @!@:if_case_}{\.{\\ifcase} primitive@> -primitive("ifprimitive",if_test,if_primitive_code); +primitive_luatex("ifprimitive",if_test,if_primitive_code,0); @!@:if_primitive_}{\.{\\ifprimitive} primitive@> -primitive("ifpdfprimitive",if_test,if_primitive_code); +primitive_pdftex("ifpdfprimitive",if_test,if_primitive_code,0); @!@:if_primitive_}{\.{\\ifpdfprimitive} primitive@> -@ @= -if_test: begin if chr_code>=unless_code then print_esc("unless"); -case chr_code mod unless_code of - if_cat_code:print_esc("ifcat"); - if_int_code:print_esc("ifnum"); - if_dim_code:print_esc("ifdim"); - if_odd_code:print_esc("ifodd"); - if_vmode_code:print_esc("ifvmode"); - if_hmode_code:print_esc("ifhmode"); - if_mmode_code:print_esc("ifmmode"); - if_inner_code:print_esc("ifinner"); - if_void_code:print_esc("ifvoid"); - if_hbox_code:print_esc("ifhbox"); - if_vbox_code:print_esc("ifvbox"); - ifx_code:print_esc("ifx"); - if_eof_code:print_esc("ifeof"); - if_true_code:print_esc("iftrue"); - if_false_code:print_esc("iffalse"); - if_case_code:print_esc("ifcase"); - if_primitive_code:print_esc("ifprimitive"); - @/@@/ - othercases print_esc("if") - endcases; -end; - @ Conditions can be inside conditions, and this nesting has a stack that is independent of the |save_stack|. @@ -11827,8 +11187,6 @@ Otherwise |cond_ptr| points to a two-word node; the |type|, |subtype|, and |cond_ptr| at the next level, and the second word contains the corresponding |if_line|. -@d if_node==49 -@d if_node_size=2 {number of words in stack entry for conditionals} @d if_limit_subtype(#)==subtype(#+1) @d if_limit_type(#)==type(#+1) @d if_line_field(#)==vlink(#+1) @@ -11847,19 +11205,14 @@ corresponding |if_line|. cond_ptr:=null; if_limit:=normal; cur_if:=0; if_line:=0; @ @= -primitive("fi",fi_or_else,fi_code); +primitive_tex("fi",fi_or_else,fi_code,0); @!@:fi_}{\.{\\fi} primitive@> text(frozen_fi):="fi"; eqtb[frozen_fi]:=eqtb[cur_val]; -primitive("or",fi_or_else,or_code); +primitive_tex("or",fi_or_else,or_code,0); @!@:or_}{\.{\\or} primitive@> -primitive("else",fi_or_else,else_code); +primitive_tex("else",fi_or_else,else_code,0); @!@:else_}{\.{\\else} primitive@> -@ @= -fi_or_else: if chr_code=fi_code then print_esc("fi") - else if chr_code=or_code then print_esc("or") - else print_esc("else"); - @ When we skip conditional text, we keep track of the line number where skipping began, for use in error messages. @@ -12057,17 +11410,13 @@ else b:=(type(p)=vlist_node); end @ An active character will be treated as category 13 following -\.{\\if\\noexpand} or following \.{\\ifcat\\noexpand}. We use the fact that -active characters have the smallest tokens, among all control sequences. - -The |(biggest_char-number_active_chars)| part is needed because only the -bottom two planes are present as active characters in |eqtb|. +\.{\\if\\noexpand} or following \.{\\ifcat\\noexpand}. @d get_x_token_or_active_char==@t@>@; begin get_x_token; - if cur_cmd=relax then if cur_chr=no_expand_flag then + if cur_cmd=relax then if cur_chr=no_expand_flag then if is_active_csname(cur_cs) then begin cur_cmd:=active_char; - cur_chr:=cur_tok-cs_token_flag-active_base+(biggest_char-number_active_chars); + cur_chr:=active_csname_value(cur_tok-cs_token_flag); end; end @@ -12199,31 +11548,7 @@ System-dependent changes to allow such things should probably be made with reluctance, and only when an entire file name that includes spaces is ``quoted'' somehow. -@ In order to isolate the system-dependent aspects of file names, the -@^system dependencies@> -system-independent parts of \TeX\ are expressed in terms -of three system-dependent -procedures called |begin_name|, |more_name|, and |end_name|. In -essence, if the user-specified characters of the file name are $c_1\ldots c_n$, -the system-independent driver program does the operations -$$|begin_name|;\,|more_name|(c_1);\,\ldots\,;|more_name|(c_n); -\,|end_name|.$$ -These three procedures communicate with each other via global variables. -Afterwards the file name will appear in the string pool as three strings -called |cur_name|\penalty10000\hskip-.05em, -|cur_area|, and |cur_ext|; the latter two are null (i.e., -|""|), unless they were explicitly specified by the user. - -Actually the situation is slightly more complicated, because \TeX\ needs -to know when the file name ends. The |more_name| routine is a function -(with side effects) that returns |true| on the calls |more_name|$(c_1)$, -\dots, |more_name|$(c_{n-1})$. The final call |more_name|$(c_n)$ -returns |false|; or, it returns |true| and the token following $c_n$ is -something like `\.{\\hbox}' (i.e., not a character). In other words, -|more_name| is supposed to return |true| unless it is sure that the -file name has been completely scanned; and |end_name| is supposed to be able -to finish the assembly of |cur_name|, |cur_area|, and |cur_ext| regardless of -whether $|more_name|(c_n)$ returned |true| or |false|. +@ Here are the global values that file names will be scanned into. @= @!cur_name:str_number; {name of file just scanned} @@ -12261,60 +11586,6 @@ from place to place. @d OMEGA_ocp_area=="OmegaOCPs:" @.OmegaOCPs@> -@ Here now is the first of the system-dependent routines for file name scanning. -@^system dependencies@> - -@p procedure begin_name; -begin area_delimiter:=0; ext_delimiter:=0; -end; - -@ And here's the second. The string pool might change as the file name is -being scanned, since a new \.{\\csname} might be entered; therefore we keep -|area_delimiter| and |ext_delimiter| relative to the beginning of the current -string, instead of assigning an absolute address like |pool_ptr| to them. -@^system dependencies@> - -@p function more_name(@!c:ASCII_code):boolean; -begin if c=" " then more_name:=false -else begin str_room(1); append_char(c); {contribute |c| to the current string} - if (c=">")or(c=":") then - begin area_delimiter:=cur_length; ext_delimiter:=0; - end - else if (c=".")and(ext_delimiter=0) then ext_delimiter:=cur_length; - more_name:=true; - end; -end; - -@ The third. -@^system dependencies@> - -@p procedure end_name; -begin if str_ptr+3>(max_strings+string_offset) then - overflow("number of strings",max_strings-init_str_ptr); -@:TeX capacity exceeded number of strings}{\quad number of strings@> -if area_delimiter=0 then cur_area:="" -else begin cur_area:=str_ptr; - str_start_macro(str_ptr+1):=str_start_macro(str_ptr)+area_delimiter; incr(str_ptr); - end; -if ext_delimiter=0 then - begin cur_ext:=""; cur_name:=make_string; - end -else begin cur_name:=str_ptr; - str_start_macro(str_ptr+1):=str_start_macro(str_ptr)+ext_delimiter-area_delimiter-1; - incr(str_ptr); cur_ext:=make_string; - end; -end; - -@ Conversely, here is a routine that takes three strings and prints a file -name that might have produced them. (The routine is system dependent, because -some operating systems put the file area last instead of first.) -@^system dependencies@> - -@= -procedure print_file_name(@!n,@!a,@!e:integer); -begin slow_print(a); slow_print(n); slow_print(e); -end; - @ Another system-dependent routine is needed to convert three internal \TeX\ strings into the |nameoffile| value that is used to open files. The present code @@ -12346,7 +11617,7 @@ and extensions related to format files. @d format_default_length=20 {length of the |TEX_format_default| string} @d format_area_length=11 {length of its area part} @d format_ext_length=4 {length of its `\.{.fmt}' part} -@d format_extension=".fmt" {the extension, as a \.{WEB} constant} +@d format_extension=='.fmt' {the extension, as a \.{WEB} constant} @= @!TEX_format_default:packed array[1..format_default_length] of char; @@ -12437,33 +11708,6 @@ we dare not use `|str_room|'. @d b_make_name_string(#)==make_name_string @d w_make_name_string(#)==make_name_string -@p function make_name_string:str_number; -var k:1..file_name_size; {index into |nameoffile|} -begin if (pool_ptr+namelength>pool_size)or(str_ptr=max_strings)or - (cur_length>0) then - make_name_string:="?" -else begin for k:=1 to namelength do append_char(nameoffile[k]); - make_name_string:=make_string; - end; -end; - -@ Now let's consider the ``driver'' -routines by which \TeX\ deals with file names -in a system-independent manner. First comes a procedure that looks for a -file name in the input by calling |get_x_token| for the information. - -@p procedure scan_file_name; -label done; -begin name_in_progress:=true; begin_name; -@; -loop@+begin if (cur_cmd>other_char)or(cur_chr>biggest_char) then {not a character} - begin back_input; goto done; - end; - if not more_name(cur_chr) then goto done; - get_x_token; - end; -done: end_name; name_in_progress:=false; -end; @ The global variable |name_in_progress| is used to prevent recursive use of |scan_file_name|, since the |begin_name| and other procedures @@ -12486,67 +11730,20 @@ and `\.{.fmt}' in the names of \TeX's output files. We have |job_name=0| if and only if the `\.{log}' file has not been opened, except of course for a short time just after |job_name| has become nonzero. -@= -job_name:=0; name_in_progress:=false; log_opened:=false; - -@ Here is a routine that manufactures the output file names, assuming that -|job_name<>0|. It ignores and changes the current settings of |cur_area| -and |cur_ext|. - @d pack_cur_name==pack_file_name(cur_name,cur_area,cur_ext) -@p procedure pack_job_name(@!s:str_number); {|s = ".log"|, |".dvi"|, or - |format_extension|} -begin cur_area:=""; cur_ext:=s; -cur_name:=job_name; pack_cur_name; -end; - -@ If some trouble arises when \TeX\ tries to open a file, the following -routine calls upon the user to supply another file name. Parameter~|s| -is used in the error message to identify the type of file; parameter~|e| -is the default extension if none is given. Upon exit from the routine, -variables |cur_name|, |cur_area|, |cur_ext|, and |nameoffile| are -ready for another attempt at file opening. - -@p procedure prompt_file_name(@!s,@!e:str_number); -label done; -var k:0..buf_size; {index into |buffer|} -begin if interaction=scroll_mode then wake_up_terminal; -if s="input file name" then print_err("I can't find file `") -@.I can't find file x@> -else print_err("I can't write on file `"); -@.I can't write on file x@> -print_file_name(cur_name,cur_area,cur_ext); print("'."); -if e=".tex" then show_context; -print_nl("Please type another "); print(s); -@.Please type...@> -if interaction -clear_terminal; prompt_input(": "); @; -if cur_ext="" then cur_ext:=e; -pack_cur_name; -end; - -@ @= -begin begin_name; k:=first; -while (buffer[k]=" ")and(k= +job_name:=0; name_in_progress:=false; log_opened:=false; @ Here's an example of how these conventions are used. Whenever it is time to ship out a box of stuff, we shall use the macro |ensure_dvi_open|. @d ensure_dvi_open==if output_file_name=0 then begin if job_name=0 then open_log_file; - pack_job_name(".dvi"); + pack_job_name('.dvi'); while not lua_b_open_out(dvi_file) do - prompt_file_name("file name for output",".dvi"); - dvi_file:=name_file_pointer ; + prompt_file_name('file name for output','.dvi'); + dvi_file:=name_file_pointer ; output_file_name:=b_make_name_string(dvi_file); end @@ -12568,7 +11765,7 @@ var old_setting:0..max_selector; {previous |selector| setting} begin old_setting:=selector; if job_name=0 then job_name:="texput"; @.texput@> -pack_job_name(".log"); +pack_job_name('.log'); while not lua_a_open_out(addressof(log_file),0) do @; log_file := name_file_pointer; log_name:=a_make_name_string(log_file); @@ -12582,10 +11779,8 @@ if not callback_defined(start_run_callback) then begin if buffer[l]=end_line_char then decr(l); { TODO: multichar endlinechar} for k:=1 to l do print(buffer[k]); print_ln; {now the transcript file contains the first line of input} - end -else begin - flush_loggable_info; -end; + end; +flush_loggable_info; {should be done always} selector:=old_setting+2; {|log_only| or |term_and_log|} end; @@ -12605,7 +11800,7 @@ this file. @= begin selector:=term_only; -prompt_file_name("transcript file name",".log"); +prompt_file_name('transcript file name','.log'); end @ @= @@ -12625,12 +11820,12 @@ when an `\.{\\input}' command is being processed. label done; var temp_str:str_number; begin scan_file_name; {set |cur_name| to desired file name} -if cur_ext="" then cur_ext:=".tex"; +{|if cur_ext="" then cur_ext:=".tex";|} pack_cur_name; loop@+ begin begin_file_reading; {set up |cur_file| and new level of input} if lua_a_open_in(cur_file,0) then goto done; end_file_reading; {remove the level that didn't work} - prompt_file_name("input file name",".tex"); + prompt_file_name('input file name','.tex'); end; done: cur_file := name_file_pointer; @@ -12651,6 +11846,7 @@ state:=new_line; if name=str_ptr-1 then {we can conserve string pool space now} begin flush_string; name:=cur_name; end; +@; @; end; @@ -12696,7 +11892,7 @@ create_null_font; font_bytes:=0; @ @= -primitive("nullfont",set_font,null_font); +primitive_tex("nullfont",set_font,null_font,0); @!@:null_font_}{\.{\\nullfont} primitive@> text(frozen_null_font):="nullfont"; eqtb[frozen_null_font]:=eqtb[cur_val]; @@ -12712,13 +11908,13 @@ procedure scan_font_ident; var f:internal_font_number; @!m:halfword; begin @; -if (cur_cmd=def_font) or (cur_cmd=letterspace_font) then f:=cur_font +if (cur_cmd=def_font) or (cur_cmd=letterspace_font) or (cur_cmd=pdf_copy_font) then f:=cur_font else if cur_cmd=set_font then begin f:=cur_chr; set_font_touched(f,1); end else if cur_cmd=def_family then begin - m:=cur_chr; scan_math_family_int; f:=equiv(m+cur_val); + m:=cur_chr; scan_math_family_int; f:=fam_fnt(cur_val,m); set_font_touched(f,1); end else begin print_err("Missing font identifier"); @@ -12799,14 +11995,22 @@ prints a warning message unless the user has suppressed it. @p procedure char_warning(@!f:internal_font_number;@!c:integer); var old_setting: integer; {saved value of |tracing_online|} + k:0..22; {index to current digit; we assume that $0\L n<16^{22}$} begin if tracing_lost_chars>0 then begin old_setting:=tracing_online; if tracing_lost_chars>1 then tracing_online:=1; begin begin_diagnostic; print_nl("Missing character: There is no "); @.Missing character@> - print(c); print(" ("); - print_int(c); print(") in font "); + print(c); print(" (U+"); + k:=0; + if c<16 then print_char('0'); + if c<256 then print_char('0'); + if c<4096 then print_char('0'); + repeat dig[k]:=c mod 16; c:=c div 16; incr(k); + until c=0; + print_the_digs(k); + print(") in font "); print_font_name(f); print_char("!"); end_diagnostic(false); end; @@ -12877,7 +12081,7 @@ procedure add_ocp_stack(min_index:integer; min_value:scaled); var p:ocp_lstack_index; llstack_no:scaled; counter:integer; - m:scaled; + m:scaled; begin m:=min_value; { TH: whatever this is ..} p:=ocp_list_lstack(holding[min_index]); @@ -13014,7 +12218,7 @@ ocp_info(null_ocp)(offset_ocp_info+4) := 36; {|OTP_STOP|} @ @= -primitive("nullocp", set_ocp, null_ocp); +primitive_omega("nullocp", set_ocp, null_ocp,0); text(frozen_null_ocp) := "nullocp"; eqtb[frozen_null_ocp] := eqtb[cur_val]; geq_define(ocp_active_number_base, data, 0); @@ -13317,7 +12521,7 @@ ocp_lstackmem_ptr:=1; @ $\Omega$ always knows at least one ocp list, namely the null ocp list. @ @= -primitive("nullocplist", set_ocp_list, null_ocp_list); +primitive_omega("nullocplist", set_ocp_list, null_ocp_list,0); text(frozen_null_ocp_list) := "nullocplist"; eqtb[frozen_null_ocp_list] := eqtb[cur_val]; @@ -14274,15 +13478,13 @@ dvi_out(font_check_2(f)); dvi_out(font_check_3(f));@/ dvi_four(font_size(f)); dvi_four(font_dsize(f));@/ -dvi_out(strlen(font_area(f))); +dvi_out(0); { |font_area(f)| is unused } dvi_out(strlen(font_name(f))); @; end; @ @= fa := get_font_name(f); k := 0; -while fa[k]<>0 do begin dvi_out(fa[k]); incr(k); end; -fa := get_font_area(f); k := 0; while fa[k]<>0 do begin dvi_out(fa[k]); incr(k); end @ Versions of \TeX\ intended for small computers might well choose to omit @@ -14343,8 +13545,6 @@ byte number of the \.{DVI} command in question (including the appropriate on the stack; and the |vinfo| field encodes the options for possible change in the \.{DVI} command. -@d movement_node=48 -@d movement_node_size=3 {number of words per entry in the down and right stacks} @d location(#)==vmem(#+1).int {\.{DVI} byte number for a movement command} @= @@ -14359,16 +13559,13 @@ of motion, and |o| is either |down1| or |right1|. We use the fact that the command codes have convenient arithmetic properties: |y1-down1=w1-right1| and |z1-down1=x1-right1|. -@d dvi_set(#)==oval:=#; ocmd:=set1; out_cmd -@d dvi_put(#)==oval:=#; ocmd:=put1; out_cmd -@d dvi_set_rule_end(#)==dvi_four(#) -@d dvi_set_rule(#)==dvi_out(set_rule); dvi_four(#); dvi_set_rule_end -@d dvi_put_rule_end(#)==dvi_four(#) -@d dvi_put_rule(#)==dvi_out(put_rule); dvi_four(#); dvi_put_rule_end -@d dvi_right(#)==dvi_out(right4); dvi_four(#); -@d dvi_left(#)==dvi_out(right4); dvi_four(-#); -@d dvi_down(#)==dvi_out(down4); dvi_four(#); -@d dvi_up(#)==dvi_out(down4); dvi_four(-#); +@d dvi_set_end(#)==dvi.h := dvi.h + (#); end +@d dvi_set(#)==begin synch_dvi_with_pos; oval:=#; ocmd:=set1; out_cmd; dvi_set_end +@d dvi_put(#)==begin synch_dvi_with_pos; oval:=#; ocmd:=put1; out_cmd; end +@d dvi_set_rule_end(#)==dvi_four(#); dvi.h := dvi.h + (#); end +@d dvi_set_rule(#)==begin synch_dvi_with_pos; dvi_out(set_rule); dvi_four(#); dvi_set_rule_end +@d dvi_put_rule_end(#)==dvi_four(#); end +@d dvi_put_rule(#)==begin synch_dvi_with_pos; dvi_out(put_rule); dvi_four(#); dvi_put_rule_end @p procedure movement(@!w:scaled;@!o:eight_bits); label exit,found,not_found,2,1; @@ -14376,48 +13573,16 @@ var mstate:small_number; {have we seen a |y| or |z|?} @!p,@!q:pointer; {current and top nodes on the stack} @!k:integer; {index into |dvi_buf|, modulo |dvi_buf_size|} begin -case box_direction(dvi_direction) of - dir_TL_: begin - end; - dir_TR_: begin - if o=right1 then negate(w); - end; - dir_LT_: begin - if o=right1 then o:=down1 - else o:=right1; - end; - dir_LB_: begin - if o=right1 then begin - o:=down1; negate(w); - end - else o:=right1; - end; - dir_BL_: begin - if o=down1 then negate(w); - end; - dir_BR_: begin - negate(w); - end; - dir_RT_: begin - if o=right1 then o:=down1 - else begin o:=right1; negate(w); - end; - end; - dir_RB_: begin - if o=right1 then o:=down1 else o:=right1; - negate(w); - end; - end; if false then begin -q:=new_node(movement_node,0); {new node for the top of the stack} -width(q):=w; location(q):=dvi_offset+dvi_ptr; -if o=down1 then - begin vlink(q):=down_ptr; down_ptr:=q; - end -else begin vlink(q):=right_ptr; right_ptr:=q; - end; -@; + q:=new_node(movement_node,0); {new node for the top of the stack} + width(q):=w; location(q):=dvi_offset+dvi_ptr; + if o=down1 then + begin vlink(q):=down_ptr; down_ptr:=q; + end + else begin vlink(q):=right_ptr; right_ptr:=q; + end; + @; end; @; found: @dvi_h then - begin movement(cur_h-dvi_h,right1); dvi_h:=cur_h; +@d synch_h==if pos.h <> dvi.h then begin + movement(pos.h - dvi.h, right1); + dvi.h := pos.h; end -@d synch_v==if cur_v<>dvi_v then - begin movement(cur_v-dvi_v,down1); dvi_v:=cur_v; + +@d synch_v==if pos.v <> dvi.v then begin + movement(dvi.v - pos.v, down1); + dvi.v := pos.v; end -@= -@!dvi_h,@!dvi_v:scaled; {a \.{DVI} reader program thinks we are here} -@!cur_h,@!cur_v:scaled; {\TeX\ thinks we are here} +@d synch_dvi_with_pos==begin + synch_h; synch_v; + end + +@d synch_pos_with_cur==case box_direction(dvi_direction) of + dir_TL_: begin pos.h := box_pos.h + cur.h; pos.v := box_pos.v - cur.v; end; + dir_TR_: begin pos.h := box_pos.h - cur.h; pos.v := box_pos.v - cur.v; end; + dir_BL_: begin pos.h := box_pos.h + cur.h; pos.v := box_pos.v + cur.v; end; + dir_BR_: begin pos.h := box_pos.h - cur.h; pos.v := box_pos.v + cur.v; end; + dir_LT_: begin pos.h := box_pos.h + cur.v; pos.v := box_pos.v - cur.h; end; + dir_RT_: begin pos.h := box_pos.h - cur.v; pos.v := box_pos.v - cur.h; end; + dir_LB_: begin pos.h := box_pos.h + cur.v; pos.v := box_pos.v + cur.h; end; + dir_RB_: begin pos.h := box_pos.h - cur.v; pos.v := box_pos.v + cur.h; end; + end + +@d synch_dvi_with_cur==begin + synch_pos_with_cur; + synch_dvi_with_pos; +end + +@d set_to_zero(#)==begin #.h := 0; #.v := 0; end + +@ @p function synch_p_with_c(cur: scaledpos): scaledpos; +var pos: scaledpos; +begin + synch_pos_with_cur; + synch_p_with_c := pos; +end; + +@ @= +@!scaledpos = record + h, v: scaled; + end; + +@ @= +@!cur: scaledpos; {\TeX\ position relative to origin of the surrounding box, in box coordinate system} +@!box_pos: scaledpos; {position of box origin in page coordinates} +@!pos: scaledpos; {global position on page, in $\rm sp$, from lower left page corner} +@!dvi: scaledpos; {a \.{DVI} position in page coordinates, in sync with DVI file} @!dvi_f:internal_font_number; {the current font} @!cur_s:integer; {current depth of output box nesting, initially $-1$} @ @= if page_width > 0 then - cur_page_width := page_width + cur_page_size.h := page_width else - cur_page_width := width(p) + 2*(h_offset + one_inch); + case box_direction(dvi_direction) of + dir_TL_, dir_BL_: cur_page_size.h := width(p) + 2 * page_left_offset; + dir_TR_, dir_BR_: cur_page_size.h := width(p) + 2 * page_right_offset; + dir_LT_, dir_LB_: cur_page_size.h := height(p) + depth(p) + 2 * page_left_offset; + dir_RT_, dir_RB_: cur_page_size.h := height(p) + depth(p) + 2 * page_right_offset; + end; if page_height > 0 then - cur_page_height := page_height -else - cur_page_height := height(p) + depth(p) + 2*(v_offset + one_inch); -if page_bottom_offset <> 0 then - cur_bottom_offset := page_bottom_offset + cur_page_size.v := page_height else - cur_bottom_offset := 2*one_inch; -if page_right_offset <> 0 then - cur_right_offset := page_right_offset -else - cur_right_offset := 2*one_inch - + case box_direction(dvi_direction) of + dir_TL_, dir_TR_: cur_page_size.v := height(p) + depth(p) + 2 * page_top_offset; + dir_BL_, dir_BR_: cur_page_size.v := height(p) + depth(p) + 2 * page_bottom_offset; + dir_LT_, dir_RT_: cur_page_size.v := width(p) + 2 * page_top_offset; + dir_LB_, dir_RB_: cur_page_size.v := width(p) + 2 * page_bottom_offset; + end @ @= -dvi_h:=0; dvi_v:=0; cur_h:=0; cur_v:=0; dvi_f:=null_font; +set_to_zero(dvi); set_to_zero(cur); dvi_f:=null_font; @; ensure_dvi_open; if total_pages=0 then @@ -14649,6 +13854,10 @@ if total_pages=0 then @^preamble of \.{DVI} file@> dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp} prepare_mag; dvi_four(mag); {magnification factor is frozen} + if mag<>1000 then + one_true_inch:=xn_over_d(one_hundred_inch,10,mag) + else + one_true_inch:=one_inch; old_setting:=selector; selector:=new_string; print(" LuaTeX output "); print_int(year); print_char("."); print_two(month); print_char("."); print_two(day); @@ -14661,20 +13870,20 @@ if total_pages=0 then @ When |hlist_out| is called, its duty is to output the box represented by the |hlist_node| pointed to by |temp_ptr|. The reference point of that -box has coordinates |(cur_h,cur_v)|. +box has coordinates |(cur.h,cur.v)|. Similarly, when |vlist_out| is called, its duty is to output the box represented by the |vlist_node| pointed to by |temp_ptr|. The reference point of that -box has coordinates |(cur_h,cur_v)|. +box has coordinates |(cur.h,cur.v)|. @^recursion@> @p procedure@?vlist_out; forward; {|hlist_out| and |vlist_out| are mutually recursive} -@ The recursive procedures |hlist_out| and |vlist_out| each have local variables -|save_h| and |save_v| to hold the values of |dvi_h| and |dvi_v| just before -entering a new level of recursion. In effect, the values of |save_h| and -|save_v| on \TeX's run-time stack correspond to the values of |h| and |v| +@ The recursive procedures |hlist_out| and |vlist_out| each have a local variable +|save_dvi| to hold the value of |dvi| just before +entering a new level of recursion. In effect, the value of |save_dvi| +on \TeX's run-time stack corresponds to the values of |h| and |v| that a \.{DVI}-reading program will push onto its coordinate stack. @d move_past=13 {go to this label when advancing past glue or a rule} @@ -14687,18 +13896,19 @@ label move_past, fin_rule, next_p; var base_line: scaled; {the baseline coordinate for this box} c_wd,c_ht,c_dp: scaled; {the real width, height and depth of the character} +w: scaled; { temporary value for directional width calculation } +dir_nest: integer; { for tracking nested direction nodes } edge_v: scaled; edge_h: scaled; effective_horizontal: scaled; basepoint_horizontal: scaled; basepoint_vertical: scaled; -saving_h: scaled; -saving_v: scaled; save_direction: integer; dir_ptr,dir_tmp:pointer; -dvi_dir_h,dvi_dir_ptr,dvi_temp_ptr:integer; @!left_edge: scaled; {the left coordinate for this box} -@!save_h,@!save_v: scaled; {what |dvi_h| and |dvi_v| should pop to} +@!save_h: scaled; {what |cur.h| should pop to} +@!save_dvi: scaledpos; {what |dvi| should pop to} +@!save_box_pos: scaledpos; {what |box_pos| should pop to} @!this_box: pointer; {pointer to containing box} @!g_order: glue_ord; {applicable order of infinity for glue} @!g_sign: normal..shrinking; {selects type of glue} @@ -14711,22 +13921,24 @@ dvi_dir_h,dvi_dir_ptr,dvi_temp_ptr:integer; @!edge:scaled; {right edge of sub-box or leader space} @!glue_temp:real; {glue value before rounding} @!cur_glue:real; {glue seen so far} +@!save_cur_glue:real; { saved version, for direction switch } @!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio} +@!save_cur_g:scaled; { saved version, for direction switch } begin cur_g:=0; cur_glue:=float_constant(0); this_box:=temp_ptr; g_order:=glue_order(this_box); g_sign:=glue_sign(this_box); p:=list_ptr(this_box); +set_to_zero(cur); box_pos:=pos; save_direction:=dvi_direction; dvi_direction:=box_dir(this_box); @; -saving_h:=dvi_h; saving_v:=dvi_v; incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; -save_loc:=dvi_offset+dvi_ptr; base_line:=cur_v; left_edge:=cur_h; +save_loc:=dvi_offset+dvi_ptr; base_line:=cur.v; left_edge:=cur.h; +@; while p<>null do @; -cur_h:=saving_h; cur_v:=saving_v; -synch_h; synch_v; + maintaining the condition |cur.v=base_line|@>; +@; prune_movements(save_loc); if cur_s>0 then dvi_pop(save_loc); decr(cur_s); @@ -14758,128 +13970,130 @@ reaching a non-|char_node|. The program uses the fact that |set_char_0=0|. @= if is_char_node(p) then - begin synch_h; synch_v; - repeat f:=font(p); c:=character(p); + begin + repeat + if x_displace(p)<>0 then cur.h := cur.h + x_displace(p); + if y_displace(p)<>0 then cur.v := cur.v - y_displace(p); + synch_pos_with_cur; f:=font(p); c:=character(p); ci := char_info_short(f,c); if f<>dvi_f then @; - if is_rotated(dvi_direction) then begin - c_ht:=charinfo_width(ci) div 2; - c_wd:=charinfo_height(ci)+charinfo_depth(ci); - c_dp:=0; - end - else begin - c_ht:=charinfo_height(ci); - c_dp:=charinfo_depth(ci); - c_wd:=charinfo_width(ci); - end; - cur_h:=cur_h+c_wd; + c_ht:=charinfo_height(ci); + c_dp:=charinfo_depth(ci); + c_wd:=charinfo_width(ci); if (font_natural_dir(f)<>-1) then begin case font_direction(dvi_direction) of dir__LT,dir__LB: begin - dvi_set(c); + dvi_set(c)(c_wd); end; dir__RT,dir__RB: begin dvi_put(c); - dvi_left(c_wd); end; - dir__TL,dir__TR: begin + dir__TL,dir__TR,dir__BL,dir__BR: begin + c_wd := c_ht + c_dp; dvi_put(c); - dvi_down(c_wd); end; - dir__BL,dir__BR: begin + dir__LL: begin + pos_right(c_wd); dvi_put(c); - dvi_up(c_wd); end; - dir__LL,dir__LR: begin + dir__RR: begin + pos_left(c_wd); dvi_put(c); - dvi_right(c_wd); end; - dir__RL,dir__RR: begin + dir__LR: begin + dvi_set(c)(c_wd); + end; + dir__RL: begin dvi_put(c); - dvi_left(c_wd); end; - dir__TT,dir__TB: begin + dir__TT: begin + c_wd := c_ht + c_dp; + pos_down(c_wd); dvi_put(c); - dvi_down(c_wd); end; - dir__BT,dir__BB: begin + dir__TB: begin + c_wd := c_ht + c_dp; dvi_put(c); - dvi_up(c_wd); end; - end; + dir__BT: begin + c_wd := c_ht + c_dp; + dvi_put(c); + end; + dir__BB: begin + c_wd := c_ht + c_dp; + pos_up(c_wd); + dvi_put(c); + end; + endcases; end else begin case font_direction(dvi_direction) of dir__LT: begin - dvi_set(c); + dvi_set(c)(c_wd); end; dir__LB: begin - dvi_down(c_ht); - dvi_set(c); - dvi_up(c_ht); + pos_down(c_ht); + dvi_set(c)(c_wd); end; dir__RT: begin - dvi_left(c_wd); + pos_left(c_wd); dvi_put(c); end; dir__RB: begin - dvi_left(c_wd); - dvi_down(c_ht); + pos_down(c_ht); + pos_left(c_wd); dvi_put(c); - dvi_up(c_ht); end; dir__TL: begin - dvi_down(c_wd); - dvi_left(c_ht); + pos_down(c_ht); + pos_left(c_wd); dvi_put(c); - dvi_right(c_ht); + c_wd := c_ht + c_dp; end; dir__TR: begin - dvi_down(c_wd); - dvi_left(c_dp); + pos_down(c_ht); dvi_put(c); - dvi_right(c_dp); + c_wd := c_ht + c_dp; end; dir__BL: begin - dvi_left(c_ht); + pos_left(c_wd); + pos_up(c_dp); dvi_put(c); - dvi_right(c_ht); - dvi_up(c_wd); + c_wd := c_ht + c_dp; end; dir__BR: begin - dvi_left(c_dp); + pos_up(c_dp); dvi_put(c); - dvi_right(c_dp); - dvi_up(c_wd); + c_wd := c_ht + c_dp; end; dir__LL,dir__LR: begin - dvi_down(c_ht); - dvi_put(c); - dvi_up(c_ht); - dvi_right(c_wd); + pos_down((c_ht - c_dp) div 2); + dvi_set(c)(c_wd); end; dir__RL,dir__RR: begin - dvi_left(c_wd); - dvi_down(c_ht); + pos_left(c_wd); + pos_down((c_ht - c_dp) div 2); dvi_put(c); - dvi_up(c_ht); end; dir__TT,dir__TB: begin - dvi_down(c_wd); - dvi_left(c_ht); + pos_down(c_ht); + pos_left(c_wd div 2); dvi_put(c); - dvi_right(c_ht); + c_wd:=c_ht + c_dp; end; dir__BT,dir__BB: begin - dvi_left(c_ht); + pos_up(c_dp); + pos_left(c_wd div 2); dvi_put(c); - dvi_right(c_ht); - dvi_up(c_wd); + c_wd := c_ht + c_dp; end; - end; + endcases; end; + if x_displace(p)<>0 then cur.h := cur.h - x_displace(p); + if y_displace(p)<>0 then cur.v := cur.v + y_displace(p); + cur.h:=cur.h+c_wd; p:=vlink(p); until not is_char_node(p); - dvi_h:=cur_h; + @; end else @ @@ -14894,8 +14108,8 @@ end @ @= begin case type(p) of -hlist_node,vlist_node:@; -rule_node: begin +hlist_node_case,vlist_node_case:@; +rule_node_case: begin if not (dir_orthogonal(dir_primary[rule_dir(p)])(dir_primary[dvi_direction])) then begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); @@ -14907,21 +14121,31 @@ rule_node: begin end; goto fin_rule; end; -whatsit_node: @; -glue_node: @; -disc_node: if vlink(no_break(p))<>null then begin +whatsit_node_case: @; +glue_node_case: @; +disc_node_case: if vlink(no_break(p))<>null then begin vlink(tlink(no_break(p))):=vlink(p); q:=vlink(no_break(p)); vlink(no_break(p)):=null; vlink(p):=q; end; -margin_kern_node,kern_node:cur_h:=cur_h+width(p); -math_node:cur_h:=cur_h+surround(p); +margin_kern_node_case:cur.h:=cur.h+width(p); +kern_node_case: begin + @; + cur.h:=cur.h+width(p); +end; +math_node_case: begin + @; + cur.h:=cur.h+surround(p); +end; othercases do_nothing endcases;@/ goto next_p; fin_rule: @; -move_past: cur_h:=cur_h+rule_wd; +move_past: begin + cur.h:=cur.h+rule_wd; + @; +end; next_p:p:=vlink(p); end @@ -14938,7 +14162,7 @@ if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) end else begin effective_horizontal:=height(p)+depth(p); - if not (is_mirrored(box_dir(p))) then + if not is_mirrored(box_dir(p)) then if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(p) else @@ -14953,20 +14177,25 @@ else begin else basepoint_vertical:= (width(p) div 2); end; -if not (is_mirrored(dvi_direction)) then +if not is_mirrored(dvi_direction) then basepoint_vertical := basepoint_vertical + shift_amount(p) {shift the box `down'} else basepoint_vertical := basepoint_vertical - shift_amount(p); {shift the box `up'} -if list_ptr(p)=null then cur_h:=cur_h + effective_horizontal +if list_ptr(p)=null then begin + @; + cur.h:=cur.h + effective_horizontal; + end else begin - temp_ptr:=p; edge:=cur_h; cur_h:=cur_h + basepoint_horizontal; - edge_v:=cur_v; cur_v:=base_line + basepoint_vertical; - synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; + temp_ptr:=p; edge:=cur.h; cur.h:=cur.h + basepoint_horizontal; + edge_v:=cur.v; cur.v:=base_line + basepoint_vertical; + synch_dvi_with_cur; save_dvi:=dvi; + save_box_pos:=box_pos; if type(p)=vlist_node then vlist_out@+else hlist_out; - dvi_h:=save_h; dvi_v:=save_v; - cur_h:=edge+effective_horizontal; cur_v:=base_line; + dvi:=save_dvi; + box_pos:=save_box_pos; + cur.h:=edge+effective_horizontal; cur.v:=base_line; end end @@ -14975,46 +14204,42 @@ if is_running(rule_ht) then rule_ht:=height(this_box); if is_running(rule_dp) then rule_dp:=depth(this_box); rule_ht:=rule_ht+rule_dp; {this is the rule thickness} if (rule_ht>0)and(rule_wd>0) then {we don't output empty rules} - begin synch_h; cur_v:=base_line+rule_dp; synch_v; - case font_direction(dvi_direction) of - dir__LT: begin + begin cur.v:=base_line+rule_dp; synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: begin dvi_set_rule(rule_ht)(rule_wd); end; - dir__LB: begin - dvi_down(rule_ht); + dir_BL_: begin + pos_down(rule_ht); dvi_set_rule(rule_ht)(rule_wd); - dvi_up(rule_ht); end; - dir__RT: begin - dvi_left(rule_wd); + dir_TR_: begin + pos_left(rule_wd); dvi_put_rule(rule_ht)(rule_wd); end; - dir__RB: begin - dvi_left(rule_wd); - dvi_down(rule_ht); + dir_BR_: begin + pos_left(rule_wd); + pos_down(rule_ht); dvi_put_rule(rule_ht)(rule_wd); - dvi_up(rule_ht); end; - dir__TL: begin - dvi_down(rule_wd); - dvi_left(rule_ht); + dir_LT_: begin + pos_down(rule_wd); + pos_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); end; - dir__TR: begin - dvi_down(rule_wd); + dir_RT_: begin + pos_down(rule_wd); dvi_put_rule(rule_wd)(rule_ht); end; - dir__BL: begin - dvi_left(rule_ht); + dir_LB_: begin + pos_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); - dvi_up(rule_wd); end; - dir__BR: begin + dir_RB_: begin dvi_put_rule(rule_wd)(rule_ht); - dvi_up(rule_wd); end; end; - cur_v:=base_line; dvi_h:=dvi_h+rule_wd; + cur.v:=base_line; end @ @d billion==float_constant(1000000000) @@ -15061,50 +14286,50 @@ else leader_wd:=height(leader_box)+depth(leader_box); if (leader_wd>0)and(rule_wd>0) then begin rule_wd:=rule_wd+10; {compensate for floating-point rounding} - edge:=cur_h+rule_wd; lx:=0; - @; - while cur_h+leader_wd<=edge do - @; - cur_h:=edge-10; goto next_p; + while cur.h+leader_wd<=edge do + @; + cur.h:=edge-10; goto next_p; end; end @ The calculations related to leaders require a bit of care. First, in the -case of |a_leaders| (aligned leaders), we want to move |cur_h| to +case of |a_leaders| (aligned leaders), we want to move |cur.h| to |left_edge| plus the smallest multiple of |leader_wd| for which the result -is not less than the current value of |cur_h|; i.e., |cur_h| should become +is not less than the current value of |cur.h|; i.e., |cur.h| should become $|left_edge|+|leader_wd|\times\lceil -(|cur_h|-|left_edge|)/|leader_wd|\rceil$. The program here should work in +(|cur.h|-|left_edge|)/|leader_wd|\rceil$. The program here should work in all cases even though some implementations of \PASCAL\ give nonstandard -results for the |div| operation when |cur_h| is less than |left_edge|. +results for the |div| operation when |cur.h| is less than |left_edge|. -In the case of |c_leaders| (centered leaders), we want to increase |cur_h| +In the case of |c_leaders| (centered leaders), we want to increase |cur.h| by half of the excess space not occupied by the leaders; and in the -case of |x_leaders| (expanded leaders) we increase |cur_h| +case of |x_leaders| (expanded leaders) we increase |cur.h| by $1/(q+1)$ of this excess space, where $q$ is the number of times the leader box will be replicated. Slight inaccuracies in the division might accumulate; half of this rounding error is placed at each end of the leaders. -@= +@= if subtype(p)=a_leaders then - begin save_h:=cur_h; - cur_h:=left_edge+leader_wd*((cur_h-left_edge)@!div leader_wd); - if cur_h= +@= begin if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction])) then begin @@ -15115,7 +14340,7 @@ if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_directi basepoint_horizontal:=0; end else begin - if not (is_mirrored(box_dir(leader_box))) then + if not is_mirrored(box_dir(leader_box)) then if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(leader_box) else @@ -15130,21 +14355,23 @@ else begin else basepoint_vertical:= (width(leader_box) div 2); end; -if not (is_mirrored(dvi_direction)) then +if not is_mirrored(dvi_direction) then basepoint_vertical := basepoint_vertical + shift_amount(leader_box) {shift the box `down'} else basepoint_vertical := basepoint_vertical - shift_amount(leader_box); {shift the box `up'} temp_ptr:=leader_box; -edge_h:=cur_h; cur_h:=cur_h + basepoint_horizontal; -edge_v:=cur_v; cur_v:=base_line + basepoint_vertical; -synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; +edge_h:=cur.h; cur.h:=cur.h + basepoint_horizontal; +edge_v:=cur.v; cur.v:=base_line + basepoint_vertical; +synch_dvi_with_cur; save_dvi:=dvi; +save_box_pos:=box_pos; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then vlist_out@+else hlist_out; doing_leaders:=outer_doing_leaders; -dvi_h:=save_h; dvi_v:=save_v; -cur_h:=edge_h+leader_wd+lx; cur_v:=base_line; +box_pos:=save_box_pos; +dvi:=save_dvi; +cur.h:=edge_h+leader_wd+lx; cur.v:=base_line; end @ The |vlist_out| routine is similar to |hlist_out|, but a bit simpler. @@ -15153,7 +14380,9 @@ end label move_past, fin_rule, next_p; var left_edge: scaled; {the left coordinate for this box} @!top_edge: scaled; {the top coordinate for this box} -@!save_h,@!save_v: scaled; {what |dvi_h| and |dvi_v| should pop to} +@!save_v: scaled; {what |cur.v| should pop to} +@!save_dvi: scaledpos; {what |dvi| should pop to} +@!save_box_pos: scaledpos; {what |box_pos| should pop to} @!this_box: pointer; {pointer to containing box} @!g_order: glue_ord; {applicable order of infinity for glue} @!g_sign: normal..shrinking; {selects type of glue} @@ -15172,24 +14401,23 @@ var left_edge: scaled; {the left coordinate for this box} @!basepoint_horizontal: scaled; @!basepoint_vertical: scaled; @!edge_v: scaled; -@!saving_v: scaled; -@!saving_h: scaled; begin cur_g:=0; cur_glue:=float_constant(0); this_box:=temp_ptr; g_order:=glue_order(this_box); g_sign:=glue_sign(this_box); p:=list_ptr(this_box); {pdfassert(p<>0);} -saving_v:=dvi_v; saving_h:=dvi_h; +set_to_zero(cur); box_pos:=pos; save_direction:=dvi_direction; dvi_direction:=box_dir(this_box); incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; -save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; cur_v:=cur_v-height(this_box); -top_edge:=cur_v; +save_loc:=dvi_offset+dvi_ptr; left_edge:=cur.h; +@; +cur.v:=cur.v-height(this_box); +top_edge:=cur.v; while p<>null do @; -cur_v:=saving_v; cur_h:=saving_h; -synch_v; synch_h; + maintaining the condition |cur.h=left_edge|@>; +@; prune_movements(save_loc); if cur_s>0 then dvi_pop(save_loc); decr(cur_s); @@ -15205,8 +14433,8 @@ end @ @= begin case type(p) of -hlist_node,vlist_node:@; -rule_node: begin +hlist_node_case,vlist_node_case:@; +rule_node_case: begin if not (dir_orthogonal(dir_primary[rule_dir(p)])(dir_primary[dvi_direction])) then begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); @@ -15218,14 +14446,14 @@ rule_node: begin end; goto fin_rule; end; -whatsit_node: @; -glue_node: @; -kern_node:cur_v:=cur_v+width(p); +whatsit_node_case: @; +glue_node_case: @; +kern_node_case:cur.v:=cur.v+width(p); othercases do_nothing endcases;@/ goto next_p; fin_rule: @; -move_past: cur_v:=cur_v+rule_ht; +move_past: cur.v:=cur.v+rule_ht; end @ The |synch_v| here allows the \.{DVI} output to use one-byte commands @@ -15237,7 +14465,7 @@ begin if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) then begin effective_vertical:=height(p)+depth(p); - if (type(p)=hlist_node) and (is_mirrored(box_dir(p))) then + if (type(p)=hlist_node) and is_mirrored(box_dir(p)) then basepoint_vertical:=depth(p) else basepoint_vertical:=height(p); @@ -15248,7 +14476,7 @@ if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) end else begin effective_vertical:=width(p); - if not (is_mirrored(box_dir(p))) then + if not is_mirrored(box_dir(p)) then if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(p) else @@ -15266,61 +14494,60 @@ else begin basepoint_horizontal := basepoint_horizontal + shift_amount(p); {shift the box `right'} if list_ptr(p)=null then begin - cur_v:=cur_v+effective_vertical; + cur.v:=cur.v+effective_vertical; + @; end else begin - synch_h; synch_v; edge_v:=cur_v; - cur_h:=left_edge + basepoint_horizontal; - cur_v:=cur_v + basepoint_vertical; - synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; + edge_v:=cur.v; + cur.h:=left_edge + basepoint_horizontal; + cur.v:=cur.v + basepoint_vertical; + synch_dvi_with_cur; save_dvi:=dvi; + save_box_pos:=box_pos; temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; - dvi_h:=save_h; dvi_v:=save_v; - cur_h:=left_edge; cur_v:=edge_v + effective_vertical; + dvi:=save_dvi; + box_pos:=save_box_pos; + cur.h:=left_edge; cur.v:=edge_v + effective_vertical; end end @ @= if is_running(rule_wd) then rule_wd:=width(this_box); rule_ht:=rule_ht+rule_dp; {this is the rule thickness} -cur_v:=cur_v+rule_ht; +cur.v:=cur.v+rule_ht; if (rule_ht>0)and(rule_wd>0) then {we don't output empty rules} - begin synch_h; synch_v; - case font_direction(dvi_direction) of - dir__LT: begin + begin synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: begin dvi_put_rule(rule_ht)(rule_wd); end; - dir__LB: begin - dvi_down(rule_ht); + dir_BL_: begin + pos_down(rule_ht); dvi_put_rule(rule_ht)(rule_wd); - dvi_up(rule_ht); end; - dir__RT: begin - dvi_left(rule_wd); + dir_TR_: begin + pos_left(rule_wd); dvi_set_rule(rule_ht)(rule_wd); end; - dir__RB: begin - dvi_down(rule_ht); - dvi_left(rule_wd); + dir_BR_: begin + pos_down(rule_ht); + pos_left(rule_wd); dvi_set_rule(rule_ht)(rule_wd); - dvi_up(rule_ht); end; - dir__TL: begin - dvi_down(rule_wd); - dvi_left(rule_ht); + dir_LT_: begin + pos_down(rule_wd); + pos_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); - dvi_up(rule_wd); end; - dir__TR: begin - dvi_down(rule_wd); + dir_RT_: begin + pos_down(rule_wd); dvi_put_rule(rule_wd)(rule_ht); - dvi_up(rule_wd); end; - dir__BL: begin - dvi_left(rule_ht); + dir_LB_: begin + pos_left(rule_ht); dvi_set_rule(rule_wd)(rule_ht); end; - dir__BR: begin + dir_RB_: begin dvi_put_rule(rule_wd)(rule_ht); end; end; @@ -15363,39 +14590,39 @@ else leader_ht:=width(leader_box); if (leader_ht>0)and(rule_ht>0) then begin rule_ht:=rule_ht+10; {compensate for floating-point rounding} - edge:=cur_v+rule_ht; lx:=0; - @; - while cur_v+leader_ht<=edge do - @; - cur_v:=edge-10; goto next_p; + while cur.v+leader_ht<=edge do + @; + cur.v:=edge-10; goto next_p; end; end -@ @= +@ @= if subtype(p)=a_leaders then - begin save_v:=cur_v; - cur_v:=top_edge+leader_ht*((cur_v-top_edge)@!div leader_ht); - if cur_v= +@= begin if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction])) then begin effective_vertical:=height(leader_box)+depth(leader_box); - if (type(leader_box)=hlist_node) and (is_mirrored(box_dir(leader_box))) then + if (type(leader_box)=hlist_node) and is_mirrored(box_dir(leader_box)) then basepoint_vertical:=depth(leader_box) else basepoint_vertical:=height(leader_box); @@ -15406,7 +14633,7 @@ if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_directi end else begin effective_vertical:=width(leader_box); - if not (is_mirrored(box_dir(leader_box))) then + if not is_mirrored(box_dir(leader_box)) then if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(leader_box) else @@ -15424,15 +14651,17 @@ else begin basepoint_horizontal := basepoint_horizontal + shift_amount(leader_box); {shift the box `right'} temp_ptr:=leader_box; -cur_h:=left_edge + basepoint_horizontal; -edge_v:=cur_v ; -cur_v:=cur_v + basepoint_vertical; -synch_h; synch_v; save_h:=dvi_h; save_v:=dvi_v; +cur.h:=left_edge + basepoint_horizontal; +edge_v:=cur.v ; +cur.v:=cur.v + basepoint_vertical; +synch_dvi_with_cur; save_dvi:=dvi; +save_box_pos:=box_pos; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then vlist_out@+else hlist_out; doing_leaders:=outer_doing_leaders; -dvi_h:=save_h; dvi_v:=save_v; -cur_h:=left_edge; cur_v:=edge_v+leader_ht+lx; +box_pos:=save_box_pos; +dvi:=save_dvi; +cur.h:=left_edge; cur.v:=edge_v+leader_ht+lx; end @ The |hlist_out| and |vlist_out| procedures are now complete, so we are @@ -15447,9 +14676,10 @@ var page_loc:integer; {location of the current |bop|} pre_callback_id:integer; post_callback_id:integer; ret:boolean; -begin -pre_callback_id:=callback_defined(start_page_number_callback); -post_callback_id:=callback_defined(stop_page_number_callback); +begin +@; +pre_callback_id:=callback_defined(start_page_number_callback); +post_callback_id:=callback_defined(stop_page_number_callback); if (tracing_output>0)and(pre_callback_id=0) then begin print_nl(""); print_ln; print("Completed box being shipped out"); @@ -15480,6 +14710,7 @@ update_terminal; {progress report} @; if post_callback_id>0 then ret:=run_callback(post_callback_id,'->'); +@; end; @ @= @@ -15506,63 +14737,42 @@ page_loc:=dvi_offset+dvi_ptr; dvi_out(bop); for k:=0 to 9 do dvi_four(count(k)); dvi_four(last_bop); last_bop:=page_loc; +{Think in upright page/paper coordinates): First preset |pos.h| and |pos.v| to the DVI origin.} +pos.h := one_true_inch; +pos.v := cur_page_size.v - one_true_inch; +box_pos := pos; dvi := pos; +{Then calculate |cur.h| and |cur.v| within the upright coordinate system +for the DVI origin depending on the |page_direction|.} dvi_direction:=page_direction; case box_direction(dvi_direction) of dir_TL_,dir_LT_: begin + cur.h := page_left_offset; + cur.v := page_top_offset; end; dir_TR_,dir_RT_: begin - dvi_right(cur_page_width-cur_right_offset); - dvi_h:=-cur_right_offset; - end; -dir_RB_,dir_BR_: begin - dvi_right(cur_page_width-cur_right_offset); - dvi_down(cur_page_height-cur_bottom_offset); - dvi_h:=-cur_right_offset; - dvi_v:=-cur_bottom_offset; + cur.h := cur_page_size.h - page_right_offset; + cur.v := page_top_offset; end; dir_BL_,dir_LB_: begin - dvi_down(cur_page_height-cur_bottom_offset); - dvi_v:=-cur_bottom_offset; - end; -end; -cur_h:=h_offset; -cur_v:=height(p)+v_offset; -case box_direction(dvi_direction) of -dir_TL_: begin - dvi_down(cur_v); - dvi_right(cur_h); - end; -dir_TR_: begin - dvi_down(cur_v); - dvi_right(-cur_h); - end; -dir_LT_: begin - dvi_right(cur_v); - dvi_down(cur_h); - end; -dir_LB_: begin - dvi_right(cur_v); - dvi_down(-cur_h); - end; -dir_BL_: begin - dvi_down(-cur_v); - dvi_right(cur_h); + cur.h := page_left_offset; + cur.v := cur_page_size.v - page_bottom_offset; end; -dir_BR_: begin - dvi_down(-cur_v); - dvi_right(-cur_h); - end; -dir_RT_: begin - dvi_right(-cur_v); - dvi_down(cur_h); - end; -dir_RB_: begin - dvi_right(-cur_v); - dvi_down(-cur_h); - end; -end; -dvi_h:=cur_h; -dvi_v:=cur_v; +dir_RB_,dir_BR_: begin + cur.h := cur_page_size.h - page_right_offset; + cur.v := cur_page_size.v - page_bottom_offset; + end; +end; +cur.h := cur.h - one_true_inch; {correct for DVI origin} +cur.v := cur.v - one_true_inch; +{The movement is actually done within the upright page coordinate system.} +dvi_direction := dir_TL_; {only temporarily for this adjustment} +synch_pos_with_cur; box_pos := pos; {keep track on page} +{Then switch to page box coordinate system; do |height(p)| movement.} +dvi_direction := page_direction; +cur.h := 0; +cur.v := height(p); +synch_pos_with_cur; +{Now we are at the point on the page where the origin of the page box should go.} temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; dvi_out(eop); incr(total_pages); cur_s:=-1; @@ -15595,7 +14805,8 @@ if width(p)+h_offset>max_h then max_h:=width(p)+h_offset @ At the end of the program, we must finish things off by writing the post\-amble. If |total_pages=0|, the \.{DVI} file was never opened. -If |total_pages>=65536|, the \.{DVI} file will lie. +If |total_pages>=65536|, the \.{DVI} file will lie. And if +|max_push>=65536|, the user deserves whatever chaos might ensue. An integer variable |k| will be declared for use by this routine. @@ -15684,6 +14895,11 @@ begin get_nullfont := null_font; end; +function get_par_shape_ptr: halfword; +begin + get_par_shape_ptr := par_shape_ptr; +end; + function get_escape_char: integer; begin get_escape_char := escape_char; @@ -15719,6 +14935,7 @@ begin get_tex_dimen := dimen_par(code); end; + function get_x_height(f: internal_font_number): scaled; begin get_x_height := x_height(f); @@ -15760,7 +14977,7 @@ end; function new_dummy_font: internal_font_number; begin - new_dummy_font := read_font_info(null_cs, "dummy", "", -1000, -1); + new_dummy_font := read_font_info(null_cs, "dummy", -1000, -1); end; function get_hash_size: integer; @@ -15778,11 +14995,12 @@ begin get_hash_base:= hash_base; end; -function get_active_base: integer; +function get_font_id_base: integer; begin - get_active_base:= active_base; + get_font_id_base:= font_id_base; end; + function get_cur_font: internal_font_number; begin get_cur_font:= cur_font; @@ -15936,7 +15154,7 @@ end @!pdf_file: byte_file; {the PDF output file} @!pdf_buf: ^real_eight_bits; {pointer to the PDF output buffer or PDF object stream buffer} @!pdf_buf_size: integer; {end of PDF output buffer or PDF object stream buffer} -@!pdf_ptr: integer; {pointer to the first unused byte in the PDF buffer or object stream buffer} +@!pdf_ptr: longinteger; {pointer to the first unused byte in the PDF buffer or object stream buffer} @!pdf_op_buf: ^real_eight_bits; {the PDF output buffer} @!pdf_os_buf: ^real_eight_bits; {the PDF object stream buffer} @!pdf_os_buf_size: integer; {current size of the PDF object stream buffer, grows dynamically} @@ -15949,23 +15167,23 @@ end @!pdf_os_mode: boolean; {true if producing object stream} @!pdf_os_enable: boolean; {true if object streams are globally enabled} @!pdf_os_cur_objnum: integer; {number of current object stream object} -@!pdf_gone: integer; {number of bytes that were flushed to output} -@!pdf_save_offset: integer; {to save |pdf_offset|} +@!pdf_gone: longinteger; {number of bytes that were flushed to output} +@!pdf_save_offset: longinteger; {to save |pdf_offset|} @!zip_write_state: integer; {which state of compression we are in} @!fixed_pdf_minor_version: integer; {fixed minor part of the PDF version} +@!fixed_pdf_minor_version_set: boolean; {flag if the PDF version has been set} @!fixed_pdf_objcompresslevel: integer; {fixed level for activating PDF object streams} -@!pdf_minor_version_written: boolean; {flag if the PDF version has been written} @!fixed_pdfoutput: integer; {fixed output format} @!fixed_pdfoutput_set: boolean; {|fixed_pdfoutput| has been set?} @!fixed_gamma: integer; @!fixed_image_gamma: integer; @!fixed_image_hicolor: boolean; @!fixed_image_apply_gamma: integer; +@!fixed_pdf_draftmode: integer; {fixed \\pdfdraftmode} +@!pdf_page_group_val: integer; @!epochseconds: integer; @!microseconds: integer; -@!fixed_pdf_draftmode: integer; {fixed \\pdfdraftmode} -@!fixed_pdf_draftmode_set: boolean; {|fixed_pdf_draftmode| has been set?} - +@!page_divert_val: integer; @ @= pdf_gone := 0; @@ -15980,9 +15198,10 @@ pdf_os_buf_size := inf_pdf_os_buf_size; pdf_buf := pdf_op_buf; pdf_seek_write_length := false; zip_write_state := no_zip; -pdf_minor_version_written := false; +fixed_pdf_minor_version_set := false; fixed_pdfoutput_set := false; -fixed_pdf_draftmode_set := false; +pdf_page_group_val := -1; +page_divert_val := 0; @ @p function fix_int(val, min, max: integer): integer; @@ -15996,80 +15215,122 @@ begin end; @ This ensures that |pdfminorversion| is set only before any bytes have -been written to the generated PDF file. Here also the PDF file is opened -by |ensure_pdf_open| and the PDF header is written. +been written to the generated \.{PDF} file. Here also all variables for +\.{PDF} output are initialized, the \.{PDF} file is opened by |ensure_pdf_open|, +and the \.{PDF} header is written. @p procedure check_pdfminorversion; begin - if not pdf_minor_version_written then begin - pdf_minor_version_written := true; - if (pdf_minor_version < 0) or (pdf_minor_version > 9) then begin - print_err("pdfTeX error (illegal pdfminorversion)"); - print_ln; - help2 ("The pdfminorversion must be between 0 and 9.")@/ - ("I changed this to 4."); - int_error (pdf_minor_version); - pdf_minor_version := 4; - end; - fixed_pdf_minor_version := pdf_minor_version; - fixed_gamma := fix_int(pdf_gamma, 0, 1000000); - fixed_image_gamma := fix_int(pdf_image_gamma, 0, 1000000); - fixed_image_hicolor := fix_int(pdf_image_hicolor, 0, 1); - fixed_image_apply_gamma := fix_int(pdf_image_apply_gamma, 0, 1); - fixed_pdf_objcompresslevel := fix_int(pdf_objcompresslevel, 0, 3); - fixed_pdf_draftmode := fix_int(pdf_draftmode, 0, 1); - fixed_replace_font := fix_int(pdf_replace_font, 0, 1); - if (fixed_pdf_minor_version >= 5) and (fixed_pdf_objcompresslevel > 0) then - pdf_os_enable := true - else begin - if fixed_pdf_objcompresslevel > 0 then begin - pdf_warning("Object streams", "\pdfobjcompresslevel > 0 requires \pdfminorversion > 4. Object streams disabled now.", true, true); - fixed_pdf_objcompresslevel := 0; - end; - pdf_os_enable := false; - end; - ensure_pdf_open; - fix_pdfoutput; - pdf_print("%PDF-1."); - pdf_print_int_ln(fixed_pdf_minor_version); - pdf_print("%"); - pdf_out(208); {'P' + 128} - pdf_out(212); {'T' + 128} - pdf_out(197); {'E' + 128} - pdf_out(216); {'X' + 128} - pdf_print_nl; + fix_pdfoutput; + pdfassert(fixed_pdfoutput > 0); + if not fixed_pdf_minor_version_set then begin + fixed_pdf_minor_version_set := true; + @; + @; end else begin - if fixed_pdf_minor_version <> pdf_minor_version then - pdf_error("setup", - "\pdfminorversion cannot be changed after data is written to the PDF file"); + @; + end; + if fixed_pdf_draftmode <> 0 then begin + pdf_compress_level := 0; {re-fix it, might have been changed inbetween} + fixed_pdf_objcompresslevel := 0; end; end; -@ Checks that we have a name for the generated PDF file and that it's open. - -@p procedure ensure_pdf_open; -begin - if output_file_name <> 0 then - return; - if job_name = 0 then - open_log_file; - pack_job_name(".pdf"); - if fixed_pdf_draftmode = 0 then - while not lua_b_open_out(pdf_file) do - prompt_file_name("file name for output",".pdf"); - pdf_file:=name_file_pointer; - output_file_name := b_make_name_string(pdf_file); +@ @= +prepare_mag; +if (pdf_minor_version < 0) or (pdf_minor_version > 9) then begin + print_err("LuaTeX error (illegal pdfminorversion)"); + print_ln; + help2 ("The pdfminorversion must be between 0 and 9.")@/ + ("I changed this to 4."); + int_error (pdf_minor_version); + pdf_minor_version := 4; +end; +fixed_pdf_minor_version := pdf_minor_version; +fixed_decimal_digits := fix_int(pdf_decimal_digits, 0, 4); +fixed_gamma := fix_int(pdf_gamma, 0, 1000000); +fixed_image_gamma := fix_int(pdf_image_gamma, 0, 1000000); +fixed_image_hicolor := fix_int(pdf_image_hicolor, 0, 1); +fixed_image_apply_gamma := fix_int(pdf_image_apply_gamma, 0, 1); +fixed_pdf_objcompresslevel := fix_int(pdf_objcompresslevel, 0, 3); +fixed_pdf_draftmode := fix_int(pdf_draftmode, 0, 1); +fixed_inclusion_copy_font:= fix_int(pdf_inclusion_copy_font, 0, 1); +fixed_replace_font := fix_int(pdf_replace_font, 0, 1); +fixed_pk_resolution := fix_int(pdf_pk_resolution, 72, 8000); +if (fixed_pdf_minor_version >= 5) and (fixed_pdf_objcompresslevel > 0) then + pdf_os_enable := true +else begin + if fixed_pdf_objcompresslevel > 0 then begin + pdf_warning("Object streams", + "\pdfobjcompresslevel > 0 requires \pdfminorversion > 4. Object streams disabled now.", true, true); + fixed_pdf_objcompresslevel := 0; + end; + pdf_os_enable := false; end; - -@ The PDF buffer is flushed by calling |pdf_flush|, which checks the -variable |zip_write_state| and will compress the buffer before flushing if -neccesary. We call |pdf_begin_stream| to begin a stream and |pdf_end_stream| +if pdf_pk_resolution = 0 then {if not set from format file or by user} + pdf_pk_resolution := pk_dpi; {take it from \.{texmf.cnf}} +pk_scale_factor := + divide_scaled(72, fixed_pk_resolution, 5 + fixed_decimal_digits); +if not callback_defined(read_pk_file_callback) then begin + if pdf_pk_mode <> null then begin + kpseinitprog('PDFTEX', fixed_pk_resolution, + makecstring(tokens_to_string(pdf_pk_mode)), nil); + flush_string; + end else + kpseinitprog('PDFTEX', fixed_pk_resolution, nil, nil); + if not kpsevarvalue('MKTEXPK') then + kpsesetprogramenabled (kpsepkformat, 1, kpsesrccmdline); + end; +set_job_id(year, month, day, time); +if (pdf_unique_resname > 0) and (pdf_resname_prefix = 0) then + pdf_resname_prefix := get_resname_prefix + +@ @= +if fixed_pdf_minor_version <> pdf_minor_version then + pdf_error("setup", + "\pdfminorversion cannot be changed after data is written to the PDF file"); +if fixed_pdf_draftmode <> pdf_draftmode then + pdf_error("setup", + "\pdfdraftmode cannot be changed after data is written to the PDF file"); + +@ @= +ensure_pdf_open; +pdf_print("%PDF-1."); +pdf_print_int_ln(fixed_pdf_minor_version); +pdf_print("%"); +pdf_out(208); {'P' + 128} +pdf_out(212); {'T' + 128} +pdf_out(197); {'E' + 128} +pdf_out(216); {'X' + 128} +pdf_print_nl; + +@ Checks that we have a name for the generated PDF file and that it's open. + +@p procedure ensure_pdf_open; +begin + if output_file_name <> 0 then + return; + if job_name = 0 then + open_log_file; + pack_job_name('.pdf'); + if fixed_pdf_draftmode = 0 then + while not lua_b_open_out(pdf_file) do + prompt_file_name('file name for output','.pdf'); + pdf_file:=name_file_pointer; + output_file_name := b_make_name_string(pdf_file); +end; + +@ The PDF buffer is flushed by calling |pdf_flush|, which checks the +variable |zip_write_state| and will compress the buffer before flushing if +neccesary. We call |pdf_begin_stream| to begin a stream and |pdf_end_stream| to finish it. The stream contents will be compressed if compression is turn on. @p procedure pdf_flush; {flush out the |pdf_buf|} +var saved_pdf_gone : longinteger; begin if not pdf_os_mode then begin + saved_pdf_gone := pdf_gone; case zip_write_state of no_zip: if pdf_ptr > 0 then begin if fixed_pdf_draftmode = 0 then write_pdf(0, pdf_ptr - 1); @@ -16084,6 +15345,8 @@ begin end; end; pdf_ptr := 0; + if saved_pdf_gone > pdf_gone then + pdf_error("file size", "File size exceeds architectural limits (pdf_gone wraps around)"); end; end; @@ -16093,6 +15356,7 @@ begin pdf_seek_write_length := true; {fill in length at |pdf_end_stream| call} pdf_stream_length_offset := pdf_offset - 11; pdf_stream_length := 0; + pdf_last_byte := 0; if pdf_compress_level > 0 then begin pdf_print_ln("/Filter /FlateDecode"); pdf_print_ln(">>"); @@ -16150,7 +15414,7 @@ end procedure pdf_error(t, p: str_number); begin normalize_selector; - print_err("pdfTeX error"); + print_err("LuaTeX error"); if t <> 0 then begin print(" ("); print(t); @@ -16166,7 +15430,7 @@ begin wake_up_terminal; if prepend_nl then print_ln; - print("pdfTeX warning"); + print("LuaTeX warning"); if t <> 0 then begin print(" ("); print(t); @@ -16175,7 +15439,7 @@ begin print(": "); print(p); if append_nl then print_ln; - if history=spotless then history:=warning_issued; + if history=spotless then history:=warning_issued; end; procedure pdf_os_get_os_buf(s: integer); {check that |s| bytes more @@ -16247,12 +15511,10 @@ accurary. @= @!one_hundred_inch: scaled; {scaled value corresponds to 100in} @!one_inch: scaled; {scaled value corresponds to 1in (rounded!)} +@!one_true_inch: scaled; {scaled value corresponds to 1truein (rounded!)} @!one_hundred_bp: scaled; {scaled value corresponds to 100bp} @!one_bp: scaled; {scaled value corresponds to 1bp (rounded!)} @!ten_pow: array[0..9] of integer; {$10^0..10^9$} -@!scaled_out: integer; {amount of |scaled| that was taken out in -|divide_scaled|} -@!init_pdf_output: boolean; @ @= one_hundred_inch := 7227 * 65536; {exact, 473628672} @@ -16262,8 +15524,6 @@ one_bp := (one_hundred_bp + 50) div 100; {rounded to 65782} ten_pow[0] := 1; for i := 1 to 9 do ten_pow[i] := 10*ten_pow[i - 1]; -init_pdf_output := false; - @ The function |divide_scaled| divides |s| by |m| using |dd| decimal digits of precision. It is defined in C because it is a good candidate @@ -16290,51 +15550,7 @@ else round_xn_over_d := -u; end; -@ Next subroutines are needed for controling spacing in PDF page description. -For a given character |c| from a font |f|, -the procedure |adv_char_width| advances |pdf_h| -by {\it about\/} the amount |w|, which is the character width. -But we cannot simply add |w| to |pdf_h|. -Instead we have to bring the required shift into the same raster, -on which also the \.{/Widths} array values, -as they appear in the PDF file, are based. -The |scaled_out| value is the |w| value moved into this raster. -The \.{/Widths} values are used by the PDF reader independently -to update its positions. -So one has to be sure, that calculations are properly synchronized. -Currently the \.{/Widths} array values are output -with one digit after the decimal point, -therefore the raster on which |adv_char_width| is operating -is $1/10000$ of the |pdf_font_size|. - -For PK fonts things are more complicated, -as we have to deal with scaling bitmaps as well. - -@p -procedure adv_char_width(f: internal_font_number; c: integer); {update |pdf_h| -by character width |w| from font |f|} -var w, s_out: scaled; - s: integer; -begin - w := char_width(f,c); - if hasfmentry(f) then begin - if pdf_cur_Tm_a = 1000 then begin - call_func(divide_scaled_n(w, pdf_font_size(f), 10000.0)); - pdf_delta_h := pdf_delta_h + scaled_out; - end - else begin - s := divide_scaled_n(round_xn_over_d(w, 1000, pdf_cur_Tm_a), - pdf_font_size(f), 10000.0); - s_out := round_xn_over_d(round_xn_over_d(pdf_font_size(f), abs(s), 10000), - pdf_cur_Tm_a, 1000); - if s < 0 then - s_out := -s_out; - pdf_delta_h := pdf_delta_h + s_out; - end; - end else - pdf_delta_h := pdf_delta_h + get_pk_char_width(f, w); -end; - +@ @p procedure pdf_print_bp(s: scaled); {print scaled as |bp|} begin pdf_print_real(divide_scaled(s, one_hundred_bp, fixed_decimal_digits + 2), @@ -16351,135 +15567,23 @@ end; @* \[32c] PDF page description. -@d pdf_h_offset == (h_offset + pdf_h_origin) -@d pdf_v_offset == (v_offset + pdf_v_origin) -@d pdf_x(#) == ((#) - pdf_h_offset + one_inch) {convert $x$-coordinate from \.{DVI} to PDF} -@d pdf_y(#) == (cur_page_height - (#) - pdf_v_offset + one_inch) {convert $y$-coordinate from \.{DVI} to PDF} - @= -@!pdf_f: internal_font_number; {the current font in PDF output page} -@!pdf_h: scaled; {current horizontal coordinate in PDF output page} -@!pdf_v: scaled; {current vertical coordinate in PDF output page} -@!pdf_tj_start_h: scaled; {horizontal coordinate in PDF output page just before \.{TJ} array start} -@!cur_delta_h: scaled; {horizontal |cur_h| offset from |pdf_tj_start_h|} -@!pdf_delta_h: scaled; {horizontal offset from |pdf_tj_start_h|} -@!pdf_origin_h: scaled; {current horizontal origin in PDF output page} -@!pdf_origin_v: scaled; {current vertical origin in PDF output page} -@!pdf_doing_string: boolean; {we are writing string to PDF file?} -@!pdf_doing_text: boolean; {we are writing text section to PDF file?} -@!min_bp_val: scaled; -@!min_font_val: scaled; {(TJ array system)} @!fixed_pk_resolution: integer; @!fixed_decimal_digits: integer; @!fixed_gen_tounicode: integer; +@!fixed_inclusion_copy_font: integer; @!fixed_replace_font: integer; @!pk_scale_factor: integer; @!pdf_output_option: integer; @!pdf_output_value: integer; @!pdf_draftmode_option: integer; @!pdf_draftmode_value: integer; -@!pdf_cur_Tm_a: integer; {value |a| of the current text matrix, i.e., - the current horizontal scaling factor} -@!pdf_cur_Tm_c: integer; {value |c| of the current text matrix, i.e., slant (skew, obliqueness)} -@!pdf_last_f: internal_font_number; {last font in PDF output page} -@!pdf_last_fs: internal_font_number; {last font size in PDF output page} - -@ Following procedures implement low-level subroutines to convert \TeX{} -internal structures to PDF page description. - -@p procedure pdf_set_origin(h, v: scaled); {set the origin to |h|, |v|} -begin - if (abs(h - pdf_origin_h) >= min_bp_val) or - (abs(v - pdf_origin_v) >= min_bp_val) then begin - pdf_print("1 0 0 1 "); - pdf_print_bp(h - pdf_origin_h); - pdf_origin_h := pdf_origin_h + scaled_out; - pdf_out(" "); - pdf_print_bp(pdf_origin_v - v); - pdf_origin_v := pdf_origin_v - scaled_out; - pdf_print_ln(" cm"); - end; - pdf_h := pdf_origin_h; - pdf_tj_start_h := pdf_h; - pdf_v := pdf_origin_v; -end; - -procedure pdf_set_origin_temp(h, v: scaled); {set the origin to |h|, |v| inside group} -begin - if (abs(h - pdf_origin_h) >= min_bp_val) or - (abs(v - pdf_origin_v) >= min_bp_val) then begin - pdf_print("1 0 0 1 "); - pdf_print_bp(h - pdf_origin_h); - pdf_out(" "); - pdf_print_bp(pdf_origin_v - v); - pdf_print_ln(" cm"); - end; -end; - -procedure pdf_end_string; {end the current string} -begin - if pdf_doing_string then begin - pdf_print(")]TJ"); - pdf_doing_string := false; - end; -end; - -procedure pdf_end_string_nl; {end the current string, with new-line} -begin - if pdf_doing_string then begin - pdf_print_ln(")]TJ"); - pdf_doing_string := false; - end; -end; - -procedure pdf_set_textmatrix(v, v_out: scaled; f: internal_font_number); -{set the next starting point to |cur_h|, |cur_v|} -var pdf_new_Tm_a, pdf_new_Tm_c: integer; {values |a| and |c| of the new text matrix} -begin - pdf_out(" "); - if f = pdf_f then begin - pdf_new_Tm_a := pdf_cur_Tm_a; - pdf_new_Tm_c := pdf_cur_Tm_c; - end else begin - if pdf_font_auto_expand(f) then - pdf_new_Tm_a := 1000 + pdf_font_expand_ratio(f) - else - pdf_new_Tm_a := 1000; - pdf_new_Tm_c := 0 * font_slant(f); {don't activate it yet, needs fixing writefont.c etc.} - end; - if (pdf_new_Tm_a <> 1000) or (pdf_cur_Tm_a <> 1000) - or (pdf_new_Tm_c <> 0) or (pdf_cur_Tm_c <> 0) - then begin - pdf_print_real(pdf_new_Tm_a, 3); - pdf_print(" 0 "); - pdf_print_real(pdf_new_Tm_c, 3); - pdf_print(" 1 "); - pdf_print_bp(cur_h - pdf_origin_h); - pdf_h := pdf_origin_h + scaled_out; - pdf_out(" "); - pdf_print_bp(pdf_origin_v - cur_v); - pdf_v := pdf_origin_v - scaled_out; - pdf_print(" Tm"); - pdf_cur_Tm_a := pdf_new_Tm_a; - pdf_cur_Tm_c := pdf_new_Tm_c; - pdfassert(pdf_cur_Tm_a > 0); - end else begin - pdf_print_bp(cur_h - pdf_tj_start_h); {works only for unexpanded fonts} - pdf_h := pdf_tj_start_h + scaled_out; - pdf_out(" "); - pdf_print_real(v, fixed_decimal_digits); {use |v| and |v_out| to avoid duplicate calculation} - pdf_v := pdf_v - v_out; - pdf_print(" Td"); - end; - pdf_tj_start_h := pdf_h; - pdf_delta_h := 0; -end; +@ @p procedure pdf_use_font(f: internal_font_number; fontnum: integer); {mark |f| as a used font; set |font_used(f)|, |pdf_font_size(f)| and |pdf_font_num(f)|} begin - call_func(divide_scaled(font_size(f), one_hundred_bp, 6)); - set_pdf_font_size(f,scaled_out); + set_pdf_font_size(f,font_size(f)); set_font_used(f,true); pdfassert((fontnum > 0) or ((fontnum < 0) and (pdf_font_num(-fontnum) > 0))); set_pdf_font_num(f,fontnum); @@ -16509,7 +15613,7 @@ begin {if |f| is auto expanded then ensure the base font is initialized} if pdf_font_auto_expand(f) and (pdf_font_blink(f) <> null_font) then begin b := pdf_font_blink(f); - {TODO: reinstate this check. disabled because wide fonts font have fmentries} + {TODO: reinstate this check. disabled because wide fonts font have fmentries} if false and (not hasfmentry(b)) then pdf_error("font expansion", "auto expansion is only possible with scalable fonts"); if not font_used(b) then @@ -16548,7 +15652,7 @@ begin pdf_init_font(cur_val); end; -procedure pdf_set_font(f: internal_font_number); +function pdf_set_font(f: internal_font_number): internal_font_number; {set the actual font on PDF page} label found, found1; var p: pointer; @@ -16569,134 +15673,10 @@ begin end; pdf_append_list(f)(pdf_font_list); {|f| not found in |pdf_font_list|, append it now} found: - if (k = pdf_last_f) and (font_size(f) = pdf_last_fs) then - return; - pdf_print("/F"); - pdf_print_int(k); - pdf_print_resname_prefix; - pdf_out(" "); - pdf_print_real(divide_scaled(font_size(f), one_hundred_bp, 6), 4); - pdf_print(" Tf"); - pdf_last_f := k; - pdf_last_fs := font_size(f); -end; - -procedure pdf_begin_text; {begin a text section} -begin - pdf_set_origin(0, cur_page_height); - pdf_print_ln("BT"); - pdf_doing_text := true; - pdf_f := null_font; - pdf_last_f := null_font; - pdf_last_fs := 0; - pdf_doing_string := false; - pdf_cur_Tm_a := 1000; - pdf_cur_Tm_c := 0; + pdf_set_font := k; end; @ @p -procedure pdf_begin_string(f: internal_font_number); {begin to draw a string} -var s_out, v, v_out: scaled; - s: integer; -begin s_out:=0; - if not pdf_doing_text then - pdf_begin_text; - if f <> pdf_f then begin - pdf_end_string; - pdf_set_font(f); - end; - if pdf_cur_Tm_a = 1000 then begin - s := divide_scaled_n(cur_h - (pdf_tj_start_h + pdf_delta_h), pdf_font_size(f), 1000.0); - s_out := scaled_out; - end - else begin - s := divide_scaled_n(round_xn_over_d(cur_h - (pdf_tj_start_h + pdf_delta_h), 1000, - pdf_cur_Tm_a), pdf_font_size(f), 1000.0); - if abs(s) < @'100000 then begin - s_out := round_xn_over_d(round_xn_over_d(pdf_font_size(f), abs(s), 1000), - pdf_cur_Tm_a, 1000); - if s < 0 then - s_out := -s_out; - end; - {no need to calculate |s_out| when |abs(s) >= @'100000|, since the text - matrix will be reset below} - end; - if abs(cur_v - pdf_v) >= min_bp_val then begin - v := divide_scaled(pdf_v - cur_v, one_hundred_bp, - fixed_decimal_digits + 2); - v_out := scaled_out; - end - else begin - v := 0; - v_out := 0; - end; - if (f <> pdf_f) or (v <> 0) or (abs(s) >= @'100000) then begin - pdf_end_string; - pdf_set_textmatrix(v, v_out, f); - pdf_f := f; - s := 0; - end; - if not pdf_doing_string then begin - pdf_print(" ["); - if s = 0 then - pdf_out("("); - end; - if s <> 0 then begin - if pdf_doing_string then - pdf_out(")"); - pdf_print_int(-s); - pdf_out("("); - pdf_delta_h := pdf_delta_h + s_out; - end; - pdf_doing_string := true; -end; - -procedure pdf_end_text; {end a text section} -begin - if pdf_doing_text then begin - pdf_end_string_nl; - pdf_print_ln("ET"); - pdf_doing_text := false; - end; -end; - -procedure pdf_set_rule(x, y, w, h: scaled); {draw a rule} -begin - pdf_end_text; - pdf_print_ln("q"); - if h <= one_bp then begin - pdf_set_origin_temp(x, y - (h + 1)/2); - pdf_print("[]0 d 0 J "); - pdf_print_bp(h); pdf_print(" w 0 0 m "); - pdf_print_bp(w); pdf_print_ln(" 0 l S"); - end - else if w <= one_bp then begin - pdf_set_origin_temp(x + (w + 1)/2, cur_v); - pdf_print("[]0 d 0 J "); - pdf_print_bp(w); pdf_print(" w 0 0 m 0 "); - pdf_print_bp(h); pdf_print_ln(" l S"); - end - else begin - pdf_set_origin_temp(x, y); - pdf_print("0 0 "); - pdf_print_bp(w); pdf_out(" "); - pdf_print_bp(h); pdf_print_ln(" re f"); - end; - pdf_print_ln("Q"); -end; - -procedure pdf_rectangle(left, top, right, bottom: scaled); {output a -rectangle specification to PDF file} -begin - prepare_mag; - pdf_print("/Rect ["); - pdf_print_mag_bp(pdf_x(left)); pdf_out(" "); - pdf_print_mag_bp(pdf_y(bottom)); pdf_out(" "); - pdf_print_mag_bp(pdf_x(right)); pdf_out(" "); - pdf_print_mag_bp(pdf_y(top)); - pdf_print_ln("]"); -end; - procedure literal(s: str_number; literal_mode: integer; warn: boolean); var j: pool_pointer; {current character code position} begin @@ -16723,49 +15703,54 @@ begin end; case literal_mode of set_origin: begin - pdf_end_text; - pdf_set_origin(cur_h, cur_v); + pdf_goto_pagemode; + synch_pos_with_cur; + pdf_set_pos(pos.h, pos.v); end; direct_page: - pdf_end_text; + pdf_goto_pagemode; direct_always: pdf_end_string_nl; othercases confusion("literal1") endcases; - if s>string_offset then + if s>string_offset then while j= @!obj_entry = record@;@/ - int0, int1, int2, int3, int4: integer; + int0, int1: integer; + int2: longinteger; + int3, int4: integer; end; @ The first field contains information representing identifier of this object. @@ -16776,10 +15761,9 @@ The second field of |obj_entry| contains link to the next object in |obj_tab| if this object is linked in a list. The third field holds the byte offset of the object in the output PDF file, -or its byte offset within an object stream. -Objects that have been not written yet have this field set to zero. However -sometimes we have to use this field to store some info before the object is -written out. +or its byte offset within an object stream. As long as the object is not +written, this field is used for flags about the write status of the object; +then it has a negative value. The fourth field holds the object number of the object stream, into which the object is included. @@ -16790,39 +15774,41 @@ well. @d obj_info(#) == obj_tab[#].int0 {information representing identifier of this object} @d obj_link(#) == obj_tab[#].int1 {link to the next entry in linked list} -@d obj_offset(#) == obj_tab[#].int2 {byte offset for this object in PDF output file, or object stream number for this object} +@d obj_offset(#) == obj_tab[#].int2 {negative (flags), or byte offset for this object in PDF output file, or object stream number for this object} @d obj_os_idx(#) == obj_tab[#].int3 {index of this object in object stream} @d obj_aux(#) == obj_tab[#].int4 {auxiliary pointer} -@d is_obj_written(#) == (obj_offset(#) <> 0) + +@d set_obj_fresh(#) == obj_offset(#) := -2 +@d set_obj_scheduled(#) == if intcast(obj_offset(#)) = -2 then obj_offset(#) := -1 +@d is_obj_scheduled(#) == (intcast(obj_offset(#)) > -2) +@d is_obj_written(#) == (intcast(obj_offset(#)) > -1) @# {types of objects} @d obj_type_others == 0 {objects which are not linked in any list} @d obj_type_page == 1 {index of linked list of Page objects} -@d obj_type_pages == 2 {index of linked list of Pages objects} -@d obj_type_font == 3 {index of linked list of Fonts objects} -@d obj_type_outline == 4 {index of linked list of outline objects} -@d obj_type_dest == 5 {index of linked list of destination objects} -@d obj_type_obj == 6 {index of linked list of raw objects} -@d obj_type_xform == 7 {index of linked list of XObject forms} -@d obj_type_ximage == 8 {index of linked list of XObject image} -@d obj_type_thread == 9 {index of linked list of num article threads} +@d obj_type_font == 2 {index of linked list of Fonts objects} +@d obj_type_outline == 3 {index of linked list of outline objects} +@d obj_type_dest == 4 {index of linked list of destination objects} +@d obj_type_obj == 5 {index of linked list of raw objects} +@d obj_type_xform == 6 {index of linked list of XObject forms} +@d obj_type_ximage == 7 {index of linked list of XObject image} +@d obj_type_thread == 8 {index of linked list of num article threads} @d head_tab_max == obj_type_thread {max index of |head_tab|} @# {max number of kids for balanced trees} -@d pages_tree_kids_max == 6 {max number of kids of Pages tree node} @d name_tree_kids_max == 6 {max number of kids of node of name tree for name destinations} @# {when a whatsit node representing annotation is created, words |1..3| are width, height and depth of this annotation; after shipping out words |1..4| are rectangle specification of annotation. For whatsit node representing -destination |pdf_left| and |pdf_top| are used for some types of destinations} +destination |pdf_ann_left| and |pdf_ann_top| are used for some types of destinations} @# {coordinates of destinations/threads/annotations (in whatsit node)} -@d pdf_left(#) == vmem(# + 2).sc -@d pdf_top(#) == vmem(# + 3).sc -@d pdf_right(#) == vmem(# + 4).sc -@d pdf_bottom(#) == vmem(# + 5).sc +@d pdf_ann_left(#) == vmem(# + 2).sc +@d pdf_ann_top(#) == vmem(# + 3).sc +@d pdf_ann_right(#) == vmem(# + 4).sc +@d pdf_ann_bottom(#) == vmem(# + 5).sc @# {dimension of destinations/threads/annotations (in whatsit node)} @d pdf_width(#) == vmem(# + 2).sc @@ -16840,7 +15826,6 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations} @d scan_special == 3 {look into special text} @# {data structure for \.{\\pdfcolorstack}} -@d pdf_colorstack_node_size == 4 @d pdf_colorstack_stack(#) == vlink(#+2) {stack number} @d pdf_colorstack_cmd(#) == vinfo(#+2) {command: set, push, pop, current} @d pdf_colorstack_data(#) == vlink(#+3) {data} @@ -16853,22 +15838,17 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations} @d colorstack_current == 3 @# {data structure for \.{\\pdfsetmatrix}} -@d pdf_setmatrix_node_size == 3 @d pdf_setmatrix_data(#) == vlink(#+2) {data} -@# {data structure for \.{\\pdsave}} -@d pdf_save_node_size == 3 +@# {data structure for \.{\\pdfsave}} @# {data structure for \.{\\pdfrestore}} -@d pdf_restore_node_size == 3 - @# {data structure for \.{\\latelua}} -@d late_lua_data(#) == vlink(#+2) {data} -@d late_lua_reg(#) == vinfo(#+2) {register id} +@d late_lua_data == write_tokens {data} +@d late_lua_name(#) == vlink(#+3) {name} @# {data structure for \.{\\pdfobj} and \.{\\pdfrefobj}} -@d pdf_refobj_node_size == 3 {size of whatsit node representing the raw object} @d pdf_obj_objnum(#) == vinfo(# + 2) {number of the raw object} @d obj_data_ptr == obj_aux {pointer to |pdf_mem|} @d pdfmem_obj_size == 4 {size of memory in |pdf_mem| which |obj_data_ptr| holds} @@ -16881,11 +15861,10 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations} read from an external file?} @# {data structure for \.{\\pdfxform} and \.{\\pdfrefxform}} -@d pdf_refxform_node_size == 6 {size of whatsit node for xform; words 1..3 are - form dimensions} -@d pdf_xform_objnum(#) == vinfo(# + 4) {object number} @d pdfmem_xform_size == 6 {size of memory in |pdf_mem| which |obj_data_ptr| holds} + +@d pdf_xform_objnum(#) == vinfo(# + 4) {object number} @d obj_xform_width(#) == pdf_mem[obj_data_ptr(#) + 0] @d obj_xform_height(#) == pdf_mem[obj_data_ptr(#) + 1] @d obj_xform_depth(#) == pdf_mem[obj_data_ptr(#) + 2] @@ -16897,14 +15876,11 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations} Resources} @# {data structure for \.{\\pdfximage} and \.{\\pdfrefximage}} -@d pdf_refximage_node_size == 6 {size of whatsit node for ximage; words 2..4 - are image dimensions} -@d pdf_ximage_ref(#) == vinfo(# + 5) {image reference number} +@d pdf_ximage_idx(#) == vinfo(# + 5) {image index in array} @# {data structure of annotations; words 1..4 represent the coordinates of the annotation} @d obj_annot_ptr == obj_aux {pointer to corresponding whatsit node} -@d pdf_annot_node_size == 8 {size of whatsit node representing annotation} @d pdf_annot_data(#) == vinfo(# + 6) {raw data of general annotations} @d pdf_link_attr(#) == vinfo(# + 6) {attributes of link annotations} @d pdf_link_action(#) == vlink(# + 6) {pointer to action structure} @@ -16918,8 +15894,6 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations} @d pdf_action_user == 3 {user-defined action} @# {data structure of actions} -@d pdf_action_size == 4 {size of action structure in |mem|} -@d action_node == 45 @d pdf_action_type(#) == type(#+1) {action type} @d pdf_action_named_id(#) == subtype(#+1) {identifier is type of name} @d pdf_action_id(#) == vlink(#+1) {destination/thread name identifier} @@ -16932,9 +15906,8 @@ destination |pdf_left| and |pdf_top| are used for some types of destinations} before all outline entries are defined, so memory allocated for outline entries can't not be deallocated and will stay in memory. For this reason we will store data of outline entries in |pdf_mem| instead of |mem|} - @d pdfmem_outline_size == 8 {size of memory in |pdf_mem| which -|obj_outline_ptr| points to} + |obj_outline_ptr| points to} @d obj_outline_count == obj_info{count of all opened children} @d obj_outline_ptr == obj_aux {pointer to |pdf_mem|} @d obj_outline_title(#) == pdf_mem[obj_outline_ptr(#)] @@ -16959,9 +15932,6 @@ action} @# {data structure of destinations} @d obj_dest_ptr == obj_aux {pointer to |pdf_dest_node|} -@d pdf_dest_node_size == 8 {size of whatsit node for destination; -words |1..4| hold dest dimensions, word |6| identifier type, subtype -and identifier of destination, word |6| the corresponding object number} @d pdf_dest_type(#) == type(# + 6) {type of destination} @d pdf_dest_named_id(#) == subtype(# + 6) {is named identifier?} @d pdf_dest_id(#) == vlink(# + 6) {destination identifier} @@ -16971,7 +15941,6 @@ object} @# {data structure of threads; words 1..4 represent the coordinates of the corners} -@d pdf_thread_node_size == 8 @d pdf_thread_named_id(#) == subtype(# + 6) {is a named identifier} @d pdf_thread_id(#) == vlink(# + 6) {thread identifier} @d pdf_thread_attr(#) == vinfo(# + 7) {attributes of thread} @@ -17010,8 +15979,8 @@ so we can use this field for both} @!pdf_last_pages: integer; {pointer to most recently generated pages object} @!pdf_last_page: integer; {pointer to most recently generated page object} @!pdf_last_stream: integer; {pointer to most recently generated stream} -@!pdf_stream_length: integer; {length of most recently generated stream} -@!pdf_stream_length_offset: integer; {file offset of the last stream length} +@!pdf_stream_length: longinteger; {length of most recently generated stream} +@!pdf_stream_length_offset: longinteger; {file offset of the last stream length} @!pdf_seek_write_length: boolean; {flag whether to seek back and write \.{/Length}} @!pdf_last_byte: integer; {byte most recently written to PDF file; for \.{endstream} in new line} @!pdf_append_list_arg: integer; {for use with |pdf_append_list|} @@ -17085,7 +16054,7 @@ begin incr(sys_obj_ptr); obj_ptr := sys_obj_ptr; obj_info(obj_ptr) := i; - obj_offset(obj_ptr) := 0; + set_obj_fresh(obj_ptr); obj_aux(obj_ptr) := 0; avl_put_obj(obj_ptr, t); if t = obj_type_page then begin @@ -17321,7 +16290,7 @@ end; @ Subroutines to print out various PDF objects -@p procedure pdf_print_fw_int(n, w: integer); {print out an integer with +@p procedure pdf_print_fw_int(n: longinteger; w: integer); {print out an integer with fixed width; used for outputting cross-reference table} var k: integer; {$0\le k\le23$} begin @@ -17335,10 +16304,10 @@ begin end; end; -procedure pdf_out_bytes(n, w: integer); {print out an integer as +procedure pdf_out_bytes(n: longinteger; w: integer); {print out an integer as a number of bytes; used for outputting \.{/XRef} cross-reference stream} var k: integer; -byte: array[0..3] of integer; {digits in a number being output} +byte: array[0..7] of integer; {digits in a number being output} begin k := 0; repeat byte[k] := n mod 256; n := n div 256; incr(k); @@ -17419,15 +16388,101 @@ The |has_packet()| C macro checks for this condition. @ The following code typesets a character to PDF output. -@p procedure output_one_char(ffi:internal_font_number;c:integer); +@p +procedure output_one_char(ffi:internal_font_number;c:integer); +var c_wd,c_ht,c_dp: scaled; {the real width, height and depth of the character} +ci: charinfo_short; +save, save_box_pos: scaledpos; +save_direction: integer; begin - if has_packet(ffi,c) then - do_vf_packet(ffi, c) - else begin - pdf_begin_string(ffi); - pdf_print_char(ffi, c); - adv_char_width(ffi, c); - end; + ci := char_info_short(ffi,c); + c_ht:=charinfo_height(ci); + c_dp:=charinfo_depth(ci); + c_wd:=charinfo_width(ci); + synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: begin + case font_direction(dvi_direction) of + dir__LL, dir__LR: pos_down((c_ht - c_dp) div 2); + dir__LT: ; + dir__LB: pos_down(c_ht); + endcases; + end; + dir_TR_: begin + pos_left(c_wd); + case font_direction(dvi_direction) of + dir__RL, dir__RR: pos_down((c_ht - c_dp) div 2); + dir__RT: ; + dir__RB: pos_down(c_ht); + endcases; + end; + dir_BL_: begin + case font_direction(dvi_direction) of + dir__LL, dir__LR: pos_down((c_ht - c_dp) div 2); + dir__LT: pos_up(c_dp); + dir__LB: pos_down(c_ht); + endcases; + end; + dir_BR_: begin + pos_left(c_wd); + case font_direction(dvi_direction) of + dir__RL, dir__RR: pos_down((c_ht - c_dp) div 2); + dir__RT: pos_up(c_dp); + dir__RB: pos_down(c_ht); + endcases; + end; + dir_LT_: begin + pos_down(c_ht); + case font_direction(dvi_direction) of + dir__TL: pos_left(c_wd); + dir__TR: ; + dir__TB, dir__TT: pos_left(c_wd div 2); + endcases; + end; + dir_RT_: begin + pos_down(c_ht); + case font_direction(dvi_direction) of + dir__TL: pos_left(c_wd); + dir__TR: ; + dir__TB, dir__TT: pos_left(c_wd div 2); + endcases; + end; + dir_LB_: begin + pos_up(c_dp); + case font_direction(dvi_direction) of + dir__BL: pos_left(c_wd); + dir__BR: ; + dir__BB, dir__BT: pos_left(c_wd div 2); + endcases; + end; + dir_RB_: begin + pos_up(c_dp); + case font_direction(dvi_direction) of + dir__BL: pos_left(c_wd); + dir__BR: ; + dir__BB, dir__BT: pos_left(c_wd div 2); + endcases; + end; + endcases; + if has_packet(ffi,c) then begin + save := cur; + save_box_pos := box_pos; + box_pos := pos; + save_direction := dvi_direction; + dvi_direction := dir_TL_; {local virtual font coordinate system} + set_to_zero(cur); + do_vf_packet(ffi, c); + dvi_direction := save_direction; + box_pos := save_box_pos; + cur := save; + end else + pdf_place_glyph(ffi, c); + case box_direction(dvi_direction) of + dir_TL_, dir_TR_, dir_BL_, dir_BR_: + cur.h := cur.h + c_wd; + dir_LT_, dir_RT_, dir_LB_, dir_RB_: + cur.h := cur.h + c_ht + c_dp; + endcases; end; @ @= @@ -17438,24 +16493,19 @@ procedure scan_pdf_ext_toks; forward; @ Here come some subroutines to deal with expanded fonts for HZ-algorithm. -@d set_char_and_font(#) == -if is_char_node(#) then begin - c := character(#); - f := font(#); -end +@d non_existent_path == "///..." @p function get_default_hyphen_char:integer; begin - get_default_hyphen_char:=default_hyphen_char; + get_default_hyphen_char:=default_hyphen_char; end; @# function get_default_skew_char:integer; begin - get_default_skew_char:=default_skew_char; + get_default_skew_char:=default_skew_char; end; @# - procedure copy_expand_params(k, f: internal_font_number; e: integer); {set expansion-related parameters for an expanded font |k|, based on the base font |f| and the expansion amount |e|} @@ -17473,7 +16523,9 @@ var k: internal_font_number; begin if fs <> 0 then begin for k := 1 to max_font_id do - if cmp_font_name(k, s) and (font_size(k) = fs) then begin + if (tex_font_area(k) <> non_existent_path) and + cmp_font_name(k, s) and + (font_size(k) = fs) then begin flush_str(s); tfm_lookup := k; return; @@ -17481,8 +16533,9 @@ begin end else begin for k := 1 to max_font_id do - if cmp_font_name(k, s) then begin - flush_string; {|font_name|} + if (tex_font_area(k) <> non_existent_path) and + cmp_font_name(k, s) then begin + flush_string; {|font_name|} flush_str(s); tfm_lookup := k; return; @@ -17504,10 +16557,10 @@ begin if k = null_font then begin if pdf_font_auto_expand(f) then begin k := auto_expand_font(f, e); - font_id_text(k) := font_id_text(f); + font_id_text(k) := font_id_text(f); end else - k := read_font_info(null_cs, s, "", font_size(f), font_natural_dir(f)); + k := read_font_info(null_cs, s, font_size(f), font_natural_dir(f)); end; copy_expand_params(k, f, e); load_expand_font := k; @@ -17579,21 +16632,21 @@ begin end; procedure set_expand_params(f: internal_font_number; auto_expand: boolean; - font_stretch, font_shrink, font_step, expand_ratio: integer); + stretch_limit, shrink_limit, font_step, expand_ratio: integer); {expand a font with given parameters} begin set_pdf_font_step(f, font_step); set_pdf_font_auto_expand(f, auto_expand); - if font_stretch > 0 then - set_pdf_font_stretch(f,get_expand_font(f, font_stretch)); - if font_shrink > 0 then - set_pdf_font_shrink(f, get_expand_font(f, -font_shrink)); + if stretch_limit > 0 then + set_pdf_font_stretch(f,get_expand_font(f, stretch_limit)); + if shrink_limit > 0 then + set_pdf_font_shrink(f, get_expand_font(f, -shrink_limit)); if expand_ratio <> 0 then set_pdf_font_expand_ratio(f,expand_ratio); end; procedure read_expand_font; {read font expansion spec and load expanded font} -var font_shrink, font_stretch, font_step: integer; +var shrink_limit, stretch_limit, font_step: integer; f: internal_font_number; auto_expand: boolean; begin @@ -17603,26 +16656,26 @@ begin if f = null_font then pdf_error("font expansion", "invalid font identifier"); if pdf_font_blink(f) <> null_font then - pdf_error("font expansion", "\pdffontexpand cannot be used this way (the base font has been expanded or letter-spaced)"); + pdf_error("font expansion", "\pdffontexpand cannot be used this way (the base font has been expanded)"); scan_optional_equals; scan_int; - font_stretch := fix_int(cur_val, 0, 1000); + stretch_limit := fix_int(cur_val, 0, 1000); scan_int; - font_shrink := fix_int(cur_val, 0, 500); + shrink_limit := fix_int(cur_val, 0, 500); scan_int; font_step := fix_int(cur_val, 0, 100); if font_step = 0 then pdf_error("font expansion", "invalid step"); - font_stretch := font_stretch - font_stretch mod font_step; - if font_stretch < 0 then - font_stretch := 0; - font_shrink := font_shrink - font_shrink mod font_step; - if font_shrink < 0 then - font_shrink := 0; - if (font_stretch = 0) and (font_shrink = 0) then + stretch_limit := stretch_limit - stretch_limit mod font_step; + if stretch_limit < 0 then + stretch_limit := 0; + shrink_limit := shrink_limit - shrink_limit mod font_step; + if shrink_limit < 0 then + shrink_limit := 0; + if (stretch_limit = 0) and (shrink_limit = 0) then pdf_error("font expansion", "invalid limit(s)"); auto_expand := false; - if scan_keyword("autoexpand") then begin + if scan_keyword('autoexpand') then begin auto_expand := true; @; end; @@ -17633,42 +16686,41 @@ begin if (pdf_font_step(f) <> 0) then {this font has been expanded, ensure the expansion parameters are identical} begin - if (pdf_font_step(f) <> font_step) or - ((pdf_font_stretch(f) = null_font) and (font_stretch <> 0)) or + if pdf_font_step(f) <> font_step then + pdf_error("font expansion", "font has been expanded with different expansion step"); + + if ((pdf_font_stretch(f) = null_font) and (stretch_limit <> 0)) or ((pdf_font_stretch(f) <> null_font) and - (pdf_font_expand_ratio(pdf_font_stretch(f)) <> font_stretch)) or - ((pdf_font_shrink(f) = null_font) and (font_shrink <> 0)) or + (pdf_font_expand_ratio(pdf_font_stretch(f)) <> stretch_limit)) then + pdf_error("font expansion", "font has been expanded with different stretch limit"); + + if ((pdf_font_shrink(f) = null_font) and (shrink_limit <> 0)) or ((pdf_font_shrink(f) <> null_font) and - (pdf_font_expand_ratio(pdf_font_shrink(f)) <> -font_shrink)) or - (pdf_font_auto_expand(f) <> auto_expand) - then - pdf_error("font expansion", "font has been expanded with different parameters"); + (-pdf_font_expand_ratio(pdf_font_shrink(f)) <> shrink_limit)) then + pdf_error("font expansion", "font has been expanded with different shrink limit"); + + if pdf_font_auto_expand(f) <> auto_expand then + pdf_error("font expansion", "font has been expanded with different auto expansion value"); end else begin if font_used(f) then pdf_warning("font expansion", "font should be expanded before its first use", true, true); - set_expand_params(f, auto_expand, font_stretch, font_shrink, font_step, 0); + set_expand_params(f, auto_expand, stretch_limit, shrink_limit, font_step, 0); if font_type(f) = virtual_font_type then vf_expand_local_fonts(f); end; end; -procedure new_letterspaced_font(a: small_number); +procedure new_letterspaced_font(a: small_number); {letter-space a font by creating a virtual font} var u:pointer; {user's font identifier} @!t:str_number; {name for the frozen font identifier} -@!old_setting:0..max_selector; {holds |selector| setting} @!f, k:internal_font_number; begin get_r_token; u:=cur_cs; - if u>=hash_base then t:=text(u) - else if u=null_cs then t:="FONT" - else begin old_setting:=selector; selector:=new_string; - print("FONT"); print(u-active_base); selector:=old_setting; - @.FONTx@> - str_room(1); t:=make_string; - end; + if u>=hash_base then t:=text(u) else t:="FONT"; +@.FONTx@> define(u,set_font,null_font); scan_optional_equals; scan_font_ident; k := cur_val; scan_int; @@ -17676,6 +16728,22 @@ begin equiv(u):=f; eqtb[font_id_base+f]:=eqtb[u]; font_id_text(f):=t; end; +procedure make_font_copy(a: small_number); +{make a font copy for further use with font expansion} +var u:pointer; {user's font identifier} +@!t:str_number; {name for the frozen font identifier} +@!f, k:internal_font_number; +begin + get_r_token; u:=cur_cs; + if u>=hash_base then t:=text(u) else t:="FONT"; +@.FONTx@> + define(u,set_font,null_font); scan_optional_equals; scan_font_ident; + k := cur_val; + f := copy_font_info(k); + equiv(u):=f; eqtb[font_id_base+f]:=eqtb[u]; font_id_text(f):=t; +end; + + @ We need to hold information about used characters in each font for partial downloading. @@ -17790,7 +16858,8 @@ begin selector:=old_setting; str_room(7); str_pool[pool_ptr] := 0; { make C string for pdfsetmatrix } - pdfsetmatrix(str_start_macro(str_ptr), cur_h, cur_page_height - cur_v); + synch_pos_with_cur; + pdfsetmatrix(str_start_macro(str_ptr), pos); str_room(7); append_char(" "); append_char("0"); @@ -17806,13 +16875,15 @@ end; procedure pdf_out_save; begin - checkpdfsave(cur_h, cur_v); + synch_pos_with_cur; + checkpdfsave(pos); literal("q", set_origin, false); end; procedure pdf_out_restore; begin - checkpdfrestore(cur_h, cur_v); + synch_pos_with_cur; + checkpdfrestore(pos); literal("Q", set_origin, false); end; @@ -17829,15 +16900,12 @@ begin end; procedure do_late_lua(p: pointer); -var old_setting:0..max_selector; {holds print |selector|} - s: str_number; begin - old_setting:=selector; selector:=new_string; - show_token_list(link(late_lua_data(p)),null,pool_size-pool_ptr); - selector:=old_setting; - s := make_string; - latelua(late_lua_reg(p), s); - flush_str(s); + if not doing_leaders then begin + expand_late_lua(p); + latelua(def_ref, late_lua_name(p)); + flush_list(def_ref); + end; end; procedure pdf_print_toks(p: pointer); {print tokens list |p|} @@ -17870,8 +16938,6 @@ end; procedure pdf_hlist_out; {output an |hlist_node| box} label move_past, fin_rule, next_p; var base_line: scaled; {the baseline coordinate for this box} -c_wd,c_ht,c_dp: scaled; - {the real width, height and depth of the character} w: scaled; { temporary value for directional width calculation } dir_nest: integer; { for tracking nested direction nodes } edge_v: scaled; @@ -17879,12 +16945,11 @@ edge_h: scaled; effective_horizontal: scaled; basepoint_horizontal: scaled; basepoint_vertical: scaled; -saving_h: scaled; -saving_v: scaled; save_direction: integer; dvi_ptr,dir_ptr,dir_tmp:pointer; @!left_edge: scaled; {the left coordinate for this box} -@!save_h: scaled; {what |cur_h| should pop to} +@!save_h: scaled; {what |cur.h| should pop to} +@!save_box_pos: scaledpos; {what |box_pos| should pop to} @!this_box: pointer; {pointer to containing box} @!g_order: glue_ord; {applicable order of infinity for glue} @!g_sign: normal..shrinking; {selects type of glue} @@ -17894,6 +16959,7 @@ dvi_ptr,dir_ptr,dir_tmp:pointer; @!lx:scaled; {extra space between leader boxes} @!outer_doing_leaders:boolean; {were we doing leaders?} @!edge:scaled; {right edge of sub-box or leader space} +@!border:scaled; {right edge of sub-box or leader space} @!prev_p:pointer; {one step behind |p|} @!glue_temp:real; {glue value before rounding} @!cur_glue:real; {glue seen so far} @@ -17904,20 +16970,21 @@ dvi_ptr,dir_ptr,dir_tmp:pointer; begin cur_g:=0; cur_glue:=float_constant(0); this_box:=temp_ptr; g_order:=glue_order(this_box); g_sign:=glue_sign(this_box); p:=list_ptr(this_box); +set_to_zero(cur); box_pos:=pos; save_direction:=dvi_direction; dvi_direction:=box_dir(this_box); dvi_ptr:=0; lx:=0; @; -saving_h:=cur_h; saving_v:=cur_v; incr(cur_s); -base_line:=cur_v; -left_edge:=cur_h; +base_line:=cur.v; +left_edge:=cur.h; prev_p:=this_box+list_offset; @; +@; while p<>null do @; -cur_h:=saving_h; cur_v:=saving_v; + maintaining the condition |cur.v=base_line|@>; +@; decr(cur_s); dvi_direction:=save_direction; @; @@ -17932,184 +16999,39 @@ end @ -@d pdf_dvicmd_set(#)==output_one_char(f,#) -@d pdf_dvicmd_put(#)==output_one_char(f,#); cur_h:=cur_h-c_wd -@d pdf_dvicmd_right(#)==cur_h := cur_h + # -@d pdf_dvicmd_left(#)== cur_h := cur_h - # -@d pdf_dvicmd_down(#)== cur_v := cur_v - # -@d pdf_dvicmd_up(#)== cur_v := cur_v + # -@d pdf_dvicmd_h(#)==case box_direction(dvi_direction) of - dir_TL_: begin cur_h := cur_h + #; end; - dir_TR_: begin cur_h := cur_h - #; end; - dir_LT_: begin do_nothing; {if o=right1 then o:=down1 else o:=right1;} end; - dir_LB_: begin do_nothing; {if o=right1 then begin o:=down1; negate(w); end else o:=right1;} end; - dir_BL_: begin do_nothing; {if o=down1 then negate(w); } end; - dir_BR_: begin do_nothing; { negate(w);} end; - dir_RT_: begin do_nothing; {if o=right1 then o:=down1 else begin o:=right1; negate(w); end;} end; - dir_RB_: begin do_nothing; {if o=right1 then o:=down1 else o:=right1; negate(w);} end; - end - +@d pos_right(#) == pos.h := pos.h + (#) +@d pos_left(#) == pos.h := pos.h - (#) +@d pos_up(#) == pos.v := pos.v + (#) +@d pos_down(#) == pos.v := pos.v - (#) @= begin -if is_char_node(p) then - begin - repeat f:=font(p); c:=character(p); - ci := char_info_short (f,c); - {|writeln('hlist_out: a char node ', c:1 , ' in font ',f:1);|} - if is_valid_char(c) then begin - if is_rotated(dvi_direction) then begin - c_ht:=charinfo_width(ci) div 2; - c_dp:=0; - c_wd:=charinfo_height(ci)+charinfo_depth(ci); - end - else begin - c_ht:=charinfo_height(ci); - c_dp:=charinfo_depth(ci); - c_wd:=charinfo_width(ci); - end; - if (font_natural_dir(f)<>-1) then - case font_direction(dvi_direction) of - dir__LT,dir__LB: begin - if x_displace(p)<>0 then pdf_dvicmd_right(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_up(-y_displace(p)); - pdf_dvicmd_set(c); - if x_displace(p)<>0 then pdf_dvicmd_left(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_down(-y_displace(p)); - end; - dir__RT,dir__RB: begin - if x_displace(p)<>0 then pdf_dvicmd_left(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_up(-y_displace(p)); - pdf_dvicmd_left(c_wd); - pdf_dvicmd_put(c); - if x_displace(p)<>0 then pdf_dvicmd_right(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_down(-y_displace(p)); - end; - dir__TL,dir__TR: begin - pdf_dvicmd_put(c); - pdf_dvicmd_down(c_wd); - end; - dir__BL,dir__BR: begin - pdf_dvicmd_put(c); - pdf_dvicmd_up(c_wd); - end; - dir__LL,dir__LR: begin - pdf_dvicmd_put(c); - pdf_dvicmd_right(c_wd); - end; - dir__RL,dir__RR: begin - pdf_dvicmd_put(c); - pdf_dvicmd_left(c_wd); - end; - dir__TT,dir__TB: begin - pdf_dvicmd_put(c); - pdf_dvicmd_down(c_wd); - end; - dir__BT,dir__BB: begin - pdf_dvicmd_put(c); - pdf_dvicmd_up(c_wd); - end; - end - else - case font_direction(dvi_direction) of - dir__LT: begin - if x_displace(p)<>0 then pdf_dvicmd_right(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_up(-y_displace(p)); - pdf_dvicmd_set(c); - if x_displace(p)<>0 then pdf_dvicmd_left(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_down(-y_displace(p)); - end; - dir__LB: begin - pdf_dvicmd_down(c_ht); - pdf_dvicmd_set(c); - pdf_dvicmd_up(c_ht); - end; - dir__RT: begin - if x_displace(p)<>0 then pdf_dvicmd_left(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_up(-y_displace(p)); - pdf_dvicmd_left(c_wd); - pdf_dvicmd_put(c); - if x_displace(p)<>0 then pdf_dvicmd_right(x_displace(p)); - if y_displace(p)<>0 then pdf_dvicmd_down(-y_displace(p)); - end; - dir__RB: begin - pdf_dvicmd_left(c_wd); - pdf_dvicmd_down(c_ht); - pdf_dvicmd_put(c); - pdf_dvicmd_up(c_ht); - end; - dir__TL: begin - pdf_dvicmd_down(c_wd); - pdf_dvicmd_left(c_ht); - pdf_dvicmd_put(c); - pdf_dvicmd_right(c_ht); - end; - dir__TR: begin - pdf_dvicmd_down(c_wd); - pdf_dvicmd_left(c_dp); - pdf_dvicmd_put(c); - pdf_dvicmd_right(c_dp); - end; - dir__BL: begin - pdf_dvicmd_left(c_ht); - pdf_dvicmd_put(c); - pdf_dvicmd_right(c_ht); - pdf_dvicmd_up(c_wd); - end; - dir__BR: begin - pdf_dvicmd_left(c_dp); - pdf_dvicmd_put(c); - pdf_dvicmd_right(c_dp); - pdf_dvicmd_up(c_wd); - end; - dir__LL,dir__LR: begin - pdf_dvicmd_down(c_ht); - pdf_dvicmd_put(c); - pdf_dvicmd_up(c_ht); - pdf_dvicmd_right(c_wd); - end; - dir__RL,dir__RR: begin - pdf_dvicmd_left(c_wd); - pdf_dvicmd_down(c_ht); - pdf_dvicmd_put(c); - pdf_dvicmd_up(c_ht); - end; - dir__TT,dir__TB: begin - pdf_dvicmd_down(c_wd); - pdf_dvicmd_left(c_ht); - pdf_dvicmd_put(c); - pdf_dvicmd_right(c_ht); - end; - dir__BT,dir__BB: begin - pdf_dvicmd_left(c_ht); - pdf_dvicmd_put(c); - pdf_dvicmd_right(c_ht); - pdf_dvicmd_up(c_wd); - end; - end; - cur_h:=cur_h+c_wd; - end - else - char_warning(f, c); - prev_p:=p; - p:=vlink(p); +if is_char_node(p) then begin + repeat + if x_displace(p)<>0 then cur.h := cur.h + x_displace(p); + if y_displace(p)<>0 then cur.v := cur.v - y_displace(p); + output_one_char(font(p), character(p)); + if x_displace(p)<>0 then cur.h := cur.h - x_displace(p); + if y_displace(p)<>0 then cur.v := cur.v + y_displace(p); + p:=vlink(p); until not is_char_node(p); - end + @; +end else @; end @ @= begin case type(p) of -hlist_node,vlist_node:@<(\pdfTeX) Output a box in an hlist@>; -disc_node: if vlink(no_break(p))<>null then begin +hlist_node_case,vlist_node_case:@<(\pdfTeX) Output a box in an hlist@>; +disc_node_case: if vlink(no_break(p))<>null then begin q:=tail_of_list (vlink(no_break(p))); {TODO, this should be a tlink} vlink(q):=vlink(p); q:=vlink(no_break(p)); vlink(no_break(p)):=null; vlink(p):=q; end; -rule_node: begin +rule_node_case: begin if not (dir_orthogonal(dir_primary[rule_dir(p)])(dir_primary[dvi_direction])) then begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); @@ -18121,15 +17043,25 @@ rule_node: begin end; goto fin_rule; end; -whatsit_node: @; -glue_node: @<(\pdfTeX) Move right or output leaders@>; -margin_kern_node,kern_node: pdf_dvicmd_h(width(p)); -math_node: pdf_dvicmd_h(surround(p)); +whatsit_node_case: @; +glue_node_case: @<(\pdfTeX) Move right or output leaders@>; +margin_kern_node_case: cur.h := cur.h + width(p); +kern_node_case: begin + @; + cur.h := cur.h + width(p); + end; +math_node_case: begin + @; + cur.h := cur.h + surround(p); + end; othercases do_nothing endcases;@/ goto next_p; fin_rule: @<(\pdfTeX) Output a rule in an hlist@>; -move_past: pdf_dvicmd_h(rule_wd); +move_past: begin + cur.h := cur.h + rule_wd; + @; + end; next_p:prev_p:=p; p:=vlink(p); end @@ -18146,7 +17078,7 @@ if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) end else begin effective_horizontal:=height(p)+depth(p); - if not (is_mirrored(box_dir(p))) then + if not is_mirrored(box_dir(p)) then if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(p) else @@ -18161,74 +17093,45 @@ else begin else basepoint_vertical:= (width(p) div 2); end; -if not (is_mirrored(dvi_direction)) then +if not is_mirrored(dvi_direction) then basepoint_vertical := basepoint_vertical + shift_amount(p) {shift the box `down'} else basepoint_vertical := basepoint_vertical - shift_amount(p); {shift the box `up'} -if list_ptr(p)=null then begin pdf_dvicmd_h(effective_horizontal); end +if list_ptr(p)=null then begin + @; + cur.h := cur.h + effective_horizontal; + end else begin temp_ptr:=p; - edge:=cur_h; pdf_dvicmd_h(basepoint_horizontal); - edge_v:=cur_v; cur_v:=base_line + basepoint_vertical; + edge:=cur.h; cur.h := cur.h + basepoint_horizontal; + edge_v:=cur.v; cur.v:=base_line + basepoint_vertical; + synch_pos_with_cur; + save_box_pos:=box_pos; if type(p)=vlist_node then pdf_vlist_out@+else pdf_hlist_out; - cur_h:=edge; pdf_dvicmd_h(effective_horizontal); - cur_v:=base_line; + box_pos:=save_box_pos; + cur.h:=edge; cur.h := cur.h + effective_horizontal; + cur.v:=base_line; end end @ @<(\pdfTeX) Output a rule in an hlist@>= if is_running(rule_ht) then rule_ht:=height(this_box); if is_running(rule_dp) then rule_dp:=depth(this_box); -rule_ht:=rule_ht+rule_dp; {this is the rule thickness} -if (rule_ht>0)and(rule_wd>0) then {we don't output empty rules} - begin cur_v:=base_line+rule_dp; - case font_direction(dvi_direction) of - dir__LT: begin - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - end; - dir__LB: begin - pdf_dvicmd_down(rule_ht); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_up(rule_ht); - end; - dir__RT: begin - pdf_dvicmd_left(rule_wd); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_right(rule_wd); - end; - dir__RB: begin - pdf_dvicmd_left(rule_wd); - pdf_dvicmd_down(rule_ht); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_left(rule_wd); - pdf_dvicmd_up(rule_ht); - end; - dir__TL: begin - pdf_dvicmd_down(rule_wd); - pdf_dvicmd_left(rule_ht); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - end; - dir__TR: begin - pdf_dvicmd_down(rule_wd); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_left(rule_ht); - end; - dir__BL: begin - pdf_dvicmd_left(rule_ht); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_up(rule_wd); - end; - dir__BR: begin - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_left(rule_ht); - pdf_dvicmd_up(rule_wd); - end; - end; - {|cur_h:=cur_h+rule_wd;|}{|dir__RT| is corrected elsewhere} - cur_v:=base_line; - end +if ((rule_ht+rule_dp)>0)and(rule_wd>0) then begin {we don't output empty rules} + synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: pdf_place_rule(pos.h, pos.v - rule_dp, rule_wd, rule_ht + rule_dp); + dir_BL_: pdf_place_rule(pos.h, pos.v - rule_ht, rule_wd, rule_ht + rule_dp); + dir_TR_: pdf_place_rule(pos.h - rule_wd, pos.v - rule_dp, rule_wd, rule_ht + rule_dp); + dir_BR_: pdf_place_rule(pos.h - rule_wd, pos.v - rule_ht, rule_wd, rule_ht + rule_dp); + dir_LT_: pdf_place_rule(pos.h - rule_ht, pos.v - rule_wd, rule_ht + rule_dp, rule_wd); + dir_RT_: pdf_place_rule(pos.h - rule_dp, pos.v - rule_wd, rule_ht + rule_dp, rule_wd); + dir_LB_: pdf_place_rule(pos.h - rule_ht, pos.v, rule_ht + rule_dp, rule_wd); + dir_RB_: pdf_place_rule(pos.h - rule_dp, pos.v, rule_ht + rule_dp, rule_wd); + end; +end @ @<(\pdfTeX) Move right or output leaders@>= begin g:=glue_ptr(p); rule_wd:=width(g)-cur_g; @@ -18266,29 +17169,34 @@ else leader_wd:=height(leader_box)+depth(leader_box); if (leader_wd>0)and(rule_wd>0) then begin - edge:=cur_h+rule_wd; {TODO this double |case| is a hack, and not quite the proper solution, but it produces the correct output for |xleaders| in TRT mode, which is important for KASHIDAH fills.} case box_direction(dvi_direction) of dir_TR_,dir_RT_: begin - edge:=cur_h; - cur_h:=cur_h-rule_wd; + border:=cur.h+leader_wd; + cur.h:=cur.h-rule_wd+leader_wd; + edge:=cur.h-leader_wd; + end; + othercases begin { |dir_TL_,dir_LT_| } + edge:=cur.h+rule_wd; + border:=edge; end; end; - @; - while cur_h+leader_wd<=edge do - @<(\pdfTeX) Output a leader box at |cur_h|, - then advance |cur_h| by |leader_wd+lx|@>; + while cur.h+leader_wd<=border do + @<(\pdfTeX) Output a leader box at |cur.h|, + then advance |cur.h| by |leader_wd+lx|@>; case box_direction(dvi_direction) of - dir_TR_,dir_RT_: cur_h:=cur_h-rule_wd; + dir_TR_,dir_RT_: cur.h:=edge; + dir_TL_,dir_LT_: cur.h:=edge; end; goto next_p; end; end -@ @<(\pdfTeX) Output a leader box at |cur_h|, ...@>= +@ @<(\pdfTeX) Output a leader box at |cur.h|, ...@>= begin if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction])) then begin @@ -18300,7 +17208,7 @@ if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_directi basepoint_horizontal:=0; end else begin - if not (is_mirrored(box_dir(leader_box))) then + if not is_mirrored(box_dir(leader_box)) then if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(leader_box) else @@ -18315,19 +17223,22 @@ else begin else basepoint_vertical:= (width(leader_box) div 2); end; -if not (is_mirrored(dvi_direction)) then +if not is_mirrored(dvi_direction) then basepoint_vertical := basepoint_vertical + shift_amount(leader_box) {shift the box `down'} else basepoint_vertical := basepoint_vertical - shift_amount(leader_box); {shift the box `up'} temp_ptr:=leader_box; -edge_h:=cur_h; cur_h:=cur_h + basepoint_horizontal; -edge_v:=cur_v; cur_v:=base_line + basepoint_vertical; +edge_h:=cur.h; cur.h:=cur.h + basepoint_horizontal; +edge_v:=cur.v; cur.v:=base_line + basepoint_vertical; +synch_pos_with_cur; +save_box_pos:=box_pos; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then pdf_vlist_out@+else pdf_hlist_out; doing_leaders:=outer_doing_leaders; -cur_h:=edge_h+leader_wd+lx; cur_v:=base_line; +box_pos:=save_box_pos; +cur.h:=edge_h+leader_wd+lx; cur.v:=base_line; end @ The |pdf_vlist_out| routine is similar to |pdf_hlist_out|, but a bit simpler. @@ -18335,7 +17246,8 @@ end label move_past, fin_rule, next_p; var left_edge: scaled; {the left coordinate for this box} @!top_edge: scaled; {the top coordinate for this box} -@!save_v: scaled; {what |cur_v| should pop to} +@!save_v: scaled; {what |cur.v| should pop to} +@!save_box_pos: scaledpos; {what |box_pos| should pop to} @!this_box: pointer; {pointer to containing box} @!g_order: glue_ord; {applicable order of infinity for glue} @!g_sign: normal..shrinking; {selects type of glue} @@ -18353,23 +17265,23 @@ var left_edge: scaled; {the left coordinate for this box} @!basepoint_horizontal: scaled; @!basepoint_vertical: scaled; @!edge_v: scaled; -@!saving_v: scaled; -@!saving_h: scaled; begin cur_g:=0; cur_glue:=float_constant(0); this_box:=temp_ptr; g_order:=glue_order(this_box); g_sign:=glue_sign(this_box); p:=list_ptr(this_box); {pdfassert(p<>0);} -saving_v:=cur_v; saving_h:=cur_h; -{|writeln(''); writeln('vlist_out: left edge: ', cur_h:1 , '');|} +set_to_zero(cur); box_pos:=pos; +{|writeln(''); writeln('vlist_out: left edge: ', cur.h:1 , '');|} save_direction:=dvi_direction; dvi_direction:=box_dir(this_box); incr(cur_s); -left_edge:=cur_h; cur_v:=cur_v-height(this_box); top_edge:=cur_v; +left_edge:=cur.h; +@; +cur.v:=cur.v-height(this_box); top_edge:=cur.v; @; while p<>null do @; -cur_v:=saving_v; cur_h:=saving_h; + maintaining the condition |cur.h=left_edge|@>; +@; decr(cur_s); dvi_direction:=save_direction; end; @@ -18388,8 +17300,8 @@ end @ @= begin case type(p) of -hlist_node,vlist_node:@<(\pdfTeX) Output a box in a vlist@>; -rule_node: begin +hlist_node_case,vlist_node_case:@<(\pdfTeX) Output a box in a vlist@>; +rule_node_case: begin if not (dir_orthogonal(dir_primary[rule_dir(p)])(dir_primary[dvi_direction])) then begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); @@ -18401,14 +17313,14 @@ rule_node: begin end; goto fin_rule; end; -whatsit_node: @; -glue_node: @<(\pdfTeX) Move down or output leaders@>; -kern_node:cur_v:=cur_v+width(p); +whatsit_node_case: @; +glue_node_case: @<(\pdfTeX) Move down or output leaders@>; +kern_node_case:cur.v := cur.v + width(p); othercases do_nothing endcases;@/ goto next_p; fin_rule: @<(\pdfTeX) Output a rule in a vlist, |goto next_p|@>; -move_past: cur_v:=cur_v+rule_ht; +move_past: cur.v := cur.v + rule_ht; end @ TODO: the direct test to switch between |width(p)| and |-width(p)| @@ -18422,7 +17334,7 @@ begin if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) then begin effective_vertical:=height(p)+depth(p); - if (type(p)=hlist_node) and (is_mirrored(box_dir(p))) then + if (type(p)=hlist_node) and is_mirrored(box_dir(p)) then basepoint_vertical:=depth(p) else basepoint_vertical:=height(p); @@ -18437,7 +17349,7 @@ if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) end else begin effective_vertical:=width(p); - if not (is_mirrored(box_dir(p))) then + if not is_mirrored(box_dir(p)) then if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then basepoint_horizontal:=height(p) else @@ -18454,68 +17366,39 @@ else begin end; basepoint_horizontal := basepoint_horizontal + shift_amount(p); if list_ptr(p)=null then begin - cur_v:=cur_v+effective_vertical; + cur.v:=cur.v+effective_vertical; + @; end else begin - edge_v:=cur_v; - cur_h:=left_edge + basepoint_horizontal; - cur_v:=cur_v + basepoint_vertical; + edge_v:=cur.v; + cur.h:=left_edge + basepoint_horizontal; + cur.v:=cur.v + basepoint_vertical; + synch_pos_with_cur; + save_box_pos:=box_pos; temp_ptr:=p; if type(p)=vlist_node then pdf_vlist_out@+else pdf_hlist_out; - cur_h:=left_edge; cur_v:=edge_v + effective_vertical; + box_pos:=save_box_pos; + cur.h:=left_edge; cur.v:=edge_v + effective_vertical; end end @ @<(\pdfTeX) Output a rule in a vlist...@>= if is_running(rule_wd) then rule_wd:=width(this_box); rule_ht:=rule_ht+rule_dp; {this is the rule thickness} -cur_v:=cur_v+rule_ht; -if (rule_ht>0)and(rule_wd>0) then {we don't output empty rules} - begin - case font_direction(dvi_direction) of - dir__LT: begin - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - {|pdf_dvicmd_left(rule_wd);|} - end; - dir__LB: begin - pdf_dvicmd_down(rule_ht); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_left(rule_wd); - pdf_dvicmd_up(rule_ht); - end; - dir__RT: begin - pdf_dvicmd_left(rule_wd); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_left(rule_wd); - end; - dir__RB: begin - pdf_dvicmd_down(rule_ht); - pdf_dvicmd_left(rule_wd); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_up(rule_ht); - end; - dir__TL: begin - pdf_dvicmd_down(rule_wd); - pdf_dvicmd_left(rule_ht); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_up(rule_wd); - end; - dir__TR: begin - pdf_dvicmd_down(rule_wd); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_left(rule_wd); - pdf_dvicmd_up(rule_wd); - end; - dir__BL: begin - pdf_dvicmd_left(rule_ht); - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - end; - dir__BR: begin - pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht); - pdf_dvicmd_left(rule_wd); - end; - end; +if (rule_ht>0)and(rule_wd>0) then begin {we don't output empty rules} + synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: pdf_place_rule(pos.h, pos.v - rule_ht, rule_wd, rule_ht); + dir_BL_: pdf_place_rule(pos.h, pos.v, rule_wd, rule_ht); + dir_TR_: pdf_place_rule(pos.h - rule_wd, pos.v - rule_ht, rule_wd, rule_ht); + dir_BR_: pdf_place_rule(pos.h - rule_wd, pos.v, rule_wd, rule_ht); + dir_LT_: pdf_place_rule(pos.h, pos.v - rule_wd, rule_ht, rule_wd); + dir_RT_: pdf_place_rule(pos.h - rule_ht, pos.v - rule_wd, rule_ht, rule_wd); + dir_LB_: pdf_place_rule(pos.h, pos.v, rule_ht, rule_wd); + dir_RB_: pdf_place_rule(pos.h - rule_ht, pos.v, rule_ht, rule_wd); end; + cur.v := cur.v + rule_ht; +end; goto next_p @ @<(\pdfTeX) Move down or output leaders@>= @@ -18551,29 +17434,32 @@ if type(leader_box)=rule_node then leader_ht:=height(leader_box)+depth(leader_box); if (leader_ht>0)and(rule_ht>0) then begin rule_ht:=rule_ht+10; {compensate for floating-point rounding} - edge:=cur_v+rule_ht; lx:=0; - @; - while cur_v+leader_ht<=edge do - @<(\pdfTeX) Output a leader box at |cur_v|, - then advance |cur_v| by |leader_ht+lx|@>; - cur_v:=edge-10; goto next_p; + while cur.v+leader_ht<=edge do + @<(\pdfTeX) Output a leader box at |cur.v|, + then advance |cur.v| by |leader_ht+lx|@>; + cur.v:=edge-10; goto next_p; end; end -@ @<(\pdfTeX) Output a leader box at |cur_v|, ...@>= -begin cur_h:=left_edge+shift_amount(leader_box); -cur_v:=cur_v+height(leader_box); save_v:=cur_v; +@ @<(\pdfTeX) Output a leader box at |cur.v|, ...@>= +begin cur.h:=left_edge+shift_amount(leader_box); +cur.v:=cur.v+height(leader_box); save_v:=cur.v; +synch_pos_with_cur; +save_box_pos:=box_pos; temp_ptr:=leader_box; outer_doing_leaders:=doing_leaders; doing_leaders:=true; if type(leader_box)=vlist_node then pdf_vlist_out@+else pdf_hlist_out; doing_leaders:=outer_doing_leaders; -cur_h:=left_edge; -cur_v:=save_v-height(leader_box)+leader_ht+lx; +box_pos:=save_box_pos; +cur.h:=left_edge; +cur.v:=save_v-height(leader_box)+leader_ht+lx; end -@ |fix_pdfoutput| freezes |pdfoutput| when something has been written to -the output. +@ |fix_pdfoutput| freezes |fixed_pdfoutput| as soon as anything has been written +to the output file, be it \.{PDF} or \.{DVI}. @p procedure fix_pdfoutput; begin @@ -18584,25 +17470,6 @@ begin else if fixed_pdfoutput <> pdf_output then pdf_error("setup", "\pdfoutput can only be changed before anything is written to the output"); - if fixed_pdfoutput_set then fix_pdf_draftmode; -end; - -@ |fix_pdf_draftmode| freezes |pdfdraftmode| when something has been written to -the output and also switches somes things off when draftmode is on. -@p procedure fix_pdf_draftmode; -begin - if not fixed_pdf_draftmode_set then begin - fixed_pdf_draftmode := pdf_draftmode; - fixed_pdf_draftmode_set := true; - end - else if fixed_pdf_draftmode <> pdf_draftmode then - pdf_error("setup", - "\pdfdraftmode can only be changed before anything is written to the output"); - if fixed_pdf_draftmode_set and fixed_pdf_draftmode > 0 then begin - fixed_pdf_draftmode_set := true; - pdf_compress_level := 0; - fixed_pdf_objcompresslevel := 0; - end; end; @ |pdf_ship_out| is used instead of |ship_out| to shipout a box to PDF @@ -18618,23 +17485,23 @@ save_ximage_list: pointer; {to save |pdf_ximage_list|} save_xform_list: pointer; {to save |pdf_xform_list|} save_image_procset: integer; {to save |pdf_image_procset|} save_text_procset: integer; {to save |pdf_text_procset|} -save_cur_page_height: scaled; {to save |cur_page_height| during flushing pending forms} +save_cur_page_size: scaledpos; {to save |cur_page_size| during flushing pending forms} +form_margin: scaled; pdf_last_resources: integer; {pointer to most recently generated Resources object} pre_callback_id:integer; post_callback_id:integer; ret:boolean; -begin -pre_callback_id:=callback_defined(start_page_number_callback); -post_callback_id:=callback_defined(stop_page_number_callback); +begin +@; +form_margin := one_bp; +pre_callback_id:=callback_defined(start_page_number_callback); +post_callback_id:=callback_defined(stop_page_number_callback); if (tracing_output>0)and(pre_callback_id=0) then begin print_nl(""); print_ln; print("Completed box being shipped out"); @.Completed box...@> end; -if not init_pdf_output then begin - @; - init_pdf_output := true; -end; +check_pdfminorversion; is_shipping_page := shipping_page; if shipping_page then begin if pre_callback_id>0 then @@ -18651,8 +17518,8 @@ if shipping_page then begin end; update_terminal; end; -if (tracing_output>0)and(post_callback_id=0) then - begin if shipping_page then print_char("]"); +if (tracing_output>0)and(post_callback_id=0)and shipping_page then + begin print_char("]"); begin_diagnostic; show_box(p); end_diagnostic(true); end; @<(\pdfTeX) Ship box |p| out@>; @@ -18663,6 +17530,7 @@ update_terminal; {progress report} @; if post_callback_id>0 then ret:=run_callback(post_callback_id,'->'); +@; end; @ @<(\pdfTeX) Ship box |p| out@>= @@ -18677,9 +17545,12 @@ cur_s:=-1; done: @ @= -fix_pdfoutput; -temp_ptr:=p; prepare_mag; +if mag<>1000 then + one_true_inch:=xn_over_d(one_hundred_inch,10,mag) +else + one_true_inch:=one_inch; +temp_ptr:=p; pdf_last_resources := pdf_new_objnum; @; dvi_direction:=page_direction; @@ -18691,7 +17562,7 @@ if not shipping_page then begin end else begin pdf_last_page := get_obj(obj_type_page, total_pages + 1, 0); - obj_aux(pdf_last_page) := 1; {mark that this page has beed created} + obj_aux(pdf_last_page) := 1; {mark that this page has been created} pdf_new_dict(obj_type_others, 0, 0); pdf_last_stream := obj_ptr; @; @@ -18715,39 +17586,92 @@ last_thread := null @ @= if is_shipping_page then begin - if page_width > 0 then - cur_page_width := page_width - else - cur_page_width := width(p) + 2 * pdf_h_offset; - if page_height > 0 then - cur_page_height := page_height - else - cur_page_height := height(p) + depth(p) + 2 * pdf_v_offset; - if page_bottom_offset <> 0 then - cur_bottom_offset := page_bottom_offset - else - cur_bottom_offset := one_inch; - if page_right_offset <> 0 then - cur_right_offset := page_right_offset - else - cur_right_offset := one_inch; - cur_h := pdf_h_offset; - cur_v := height(p) + pdf_v_offset; + @; + {Think in upright page/paper coordinates): First preset |pos.h| and |pos.v| to the DVI origin.} + pos.h := pdf_h_origin; + pos.v := cur_page_size.v - pdf_v_origin; + box_pos := pos; + {Then calculate |cur.h| and |cur.v| within the upright coordinate system + for the DVI origin depending on the |page_direction|.} + dvi_direction:=page_direction; case box_direction(dvi_direction) of - dir_TL_,dir_LT_: begin end; - dir_TR_,dir_RT_: begin cur_h:=cur_page_width-cur_right_offset; end; - dir_RB_,dir_BR_: begin cur_h:=cur_page_width-cur_right_offset; cur_v:=-cur_bottom_offset; end; - dir_BL_,dir_LB_: begin cur_v:=-cur_bottom_offset; end; + dir_TL_,dir_LT_: begin + cur.h := page_left_offset; + cur.v := page_top_offset; + end; + dir_TR_,dir_RT_: begin + cur.h := cur_page_size.h - page_right_offset; + cur.v := page_top_offset; + end; + dir_BL_,dir_LB_: begin + cur.h := page_left_offset; + cur.v := cur_page_size.v - page_bottom_offset; + end; + dir_RB_,dir_BR_: begin + cur.h := cur_page_size.h - page_right_offset; + cur.v := cur_page_size.v - page_bottom_offset; + end; end; + cur.h := cur.h - one_true_inch; {correct for DVI origin} + cur.v := cur.v - one_true_inch; + {The movement is actually done within the upright page coordinate system.} + dvi_direction := dir_TL_; {only temporarily for this adjustment} + synch_pos_with_cur; box_pos := pos; {keep track on page} + {Then switch to page box coordinate system; do |height(p)| movement.} + dvi_direction := page_direction; + cur.h := 0; + cur.v := height(p); + synch_pos_with_cur; + {Now we are at the point on the page where the origin of the page box should go.} end else begin - cur_page_width := width(p); - cur_page_height := height(p) + depth(p); - cur_h := 0; - cur_v := height(p); + dvi_direction:=box_dir(p); + case box_direction(dvi_direction) of + dir_TL_,dir_TR_,dir_BL_,dir_BR_: begin + cur_page_size.h := width(p); + cur_page_size.v := height(p) + depth(p); + end; + dir_LT_,dir_RT_,dir_LB_,dir_RB_: begin + cur_page_size.h := height(p) + depth(p); + cur_page_size.v := width(p); + end; + end; + case box_direction(dvi_direction) of + dir_TL_: begin + pos.h := 0; + pos.v := depth(p); + end; + dir_TR_: begin + pos.h := width(p); + pos.v := depth(p); + end; + dir_BL_: begin + pos.h := 0; + pos.v := height(p); + end; + dir_BR_: begin + pos.h := width(p); + pos.v := height(p); + end; + dir_LT_: begin + pos.h := height(p); + pos.v := width(p); + end; + dir_RT_: begin + pos.h := depth(p); + pos.v := width(p); + end; + dir_LB_: begin + pos.h := height(p); + pos.v := 0; + end; + dir_RB_: begin + pos.h := depth(p); + pos.v := 0; + end; + end; end; -pdf_origin_h := 0; -pdf_origin_v := cur_page_height; +pdf_page_init; @ Here we write out the header for Form. @@ -18759,9 +17683,10 @@ if obj_xform_attr(pdf_cur_form) <> null then begin delete_toks(obj_xform_attr(pdf_cur_form)); end; pdf_print("/BBox ["); -pdf_print("0 0 "); -pdf_print_bp(cur_page_width); pdf_out(" "); -pdf_print_bp(cur_page_height); pdf_print_ln("]"); +pdf_print_bp(-form_margin); pdf_print(" "); +pdf_print_bp(-form_margin); pdf_print(" "); +pdf_print_bp(cur_page_size.h + form_margin); pdf_out(" "); +pdf_print_bp(cur_page_size.v + form_margin); pdf_print_ln("]"); pdf_print_ln("/FormType 1"); pdf_print_ln("/Matrix [1 0 0 1 0 0]"); pdf_indirect_ln("Resources", pdf_last_resources) @@ -18801,7 +17726,7 @@ if shipping_page then begin end @ @= -pdf_end_text; +pdf_goto_pagemode; pdfshipoutend(shipping_page); pdf_end_stream @@ -18906,26 +17831,26 @@ pdf_print_ln(" ]") @ @= pdf_begin_dict(pdf_last_page, 1); +pdf_last_pages := pdf_do_page_divert(pdf_last_page, page_divert_val); pdf_print_ln("/Type /Page"); pdf_indirect_ln("Contents", pdf_last_stream); pdf_indirect_ln("Resources", pdf_last_resources); pdf_print("/MediaBox [0 0 "); -pdf_print_mag_bp(cur_page_width); pdf_out(" "); -pdf_print_mag_bp(cur_page_height); +pdf_print_mag_bp(cur_page_size.h); pdf_out(" "); +pdf_print_mag_bp(cur_page_size.v); pdf_print_ln("]"); if pdf_page_attr <> null then pdf_print_toks_ln(pdf_page_attr); -@; +pdf_indirect_ln("Parent", pdf_last_pages); +if pdf_page_group_val > 0 then begin + pdf_print("/Group "); + pdf_print_int(pdf_page_group_val); + pdf_print_ln(" 0 R"); + pdf_page_group_val := -1; +end; @; pdf_end_dict -@ @= -if total_pages mod pages_tree_kids_max = 1 then begin - pdf_create_obj(obj_type_pages, pages_tree_kids_max); - pdf_last_pages := obj_ptr; -end; -pdf_indirect_ln("Parent", pdf_last_pages) - @ @= if (pdf_annot_list <> null) or (pdf_link_list <> null) then begin pdf_print("/Annots [ "); @@ -18964,7 +17889,7 @@ var s: str_number; file_opened:boolean; k:integer; res:boolean; - fnam: str_number; + fnam: str_number; callback_id:integer; begin s := tokens_to_string(obj_obj_data(n)); @@ -18982,14 +17907,14 @@ begin if obj_obj_is_file(n) > 0 then begin data_size:=0; data_cur:=0; data_buffer:=0; pack_file_name(s,"",""); - callback_id:=callback_defined(find_data_file_callback); - if callback_id>0 then begin - res := run_callback(callback_id,'S->s',stringcast(nameoffile+1),addressof(fnam)); - if (res)and(fnam<>0)and(length(fnam)>0) then begin - @; - end; + callback_id:=callback_defined(find_data_file_callback); + if callback_id>0 then begin + res := run_callback(callback_id,'S->s',stringcast(nameoffile+1),addressof(fnam)); + if (res)and(fnam<>0)and(length(fnam)>0) then begin + @; + end; end; - callback_id:=callback_defined(read_data_file_callback); + callback_id:=callback_defined(read_data_file_callback); if callback_id>0 then begin file_opened := false; res := run_callback(callback_id,'S->bSd',stringcast(nameoffile+1), @@ -19010,7 +17935,7 @@ begin pdf_out(data_buffer[data_cur]); incr(data_cur); end; - if data_buffer<>0 then libcfree(data_buffer); + if data_buffer<>0 then libcfree(data_buffer); print(">>"); end else if obj_obj_is_stream(n) > 0 then @@ -19037,7 +17962,7 @@ end @ When flushing pending forms we need to save and restore resource lists (|pdf_font_list|, |pdf_obj_list|, |pdf_xform_list| and |pdf_ximage_list|), which are also used by page shipping. -Saving and restoring |cur_page_height| is needed for proper +Saving and restoring |cur_page_size| is needed for proper writing out pending PDF marks. @= @@ -19048,9 +17973,9 @@ if pdf_xform_list <> null then begin pdf_cur_form := info(k); @; @; - save_cur_page_height := cur_page_height; + save_cur_page_size := cur_page_size; pdf_ship_out(obj_xform_box(pdf_cur_form), false); - cur_page_height := save_cur_page_height; + cur_page_size := save_cur_page_size; @; end; k := link(k); @@ -19091,8 +18016,6 @@ if pdf_ximage_list <> null then begin end @ @= -pdf_origin_h := 0; -pdf_origin_v := cur_page_height; @; @; @; @@ -19106,7 +18029,7 @@ if pdf_annot_list <> null then begin pdf_begin_dict(info(k), 1); pdf_print_ln("/Type /Annot"); pdf_print_toks_ln(pdf_annot_data(i)); - pdf_rectangle(pdf_left(i), pdf_top(i), pdf_right(i), pdf_bottom(i)); + pdf_rectangle(i); pdf_end_dict; k := link(k); end; @@ -19119,14 +18042,13 @@ while k <> null do begin i := obj_annot_ptr(info(k)); pdf_begin_dict(info(k), 1); pdf_print_ln("/Type /Annot"); + if pdf_action_type(pdf_link_action(i)) <> pdf_action_user then + pdf_print_ln("/Subtype /Link"); if pdf_link_attr(i) <> null then pdf_print_toks_ln(pdf_link_attr(i)); - pdf_rectangle(pdf_left(i), pdf_top(i), pdf_right(i), pdf_bottom(i)); - if pdf_action_type(pdf_link_action(i)) <> pdf_action_user - then begin - pdf_print_ln("/Subtype /Link"); + pdf_rectangle(i); + if pdf_action_type(pdf_link_action(i)) <> pdf_action_user then pdf_print("/A "); - end; write_action(pdf_link_action(i)); pdf_end_dict; k := link(k); @@ -19164,8 +18086,8 @@ if pdf_dest_list <> null then begin case pdf_dest_type(i) of pdf_dest_xyz: begin pdf_print("/XYZ "); - pdf_print_mag_bp(pdf_x(pdf_left(i))); pdf_out(" "); - pdf_print_mag_bp(pdf_y(pdf_top(i))); pdf_out(" "); + pdf_print_mag_bp(pdf_ann_left(i)); pdf_out(" "); + pdf_print_mag_bp(pdf_ann_top(i)); pdf_out(" "); if pdf_dest_xyz_zoom(i) = null then pdf_print("null") else begin @@ -19178,21 +18100,21 @@ if pdf_dest_list <> null then begin pdf_print("/Fit"); pdf_dest_fith: begin pdf_print("/FitH "); - pdf_print_mag_bp(pdf_y(pdf_top(i))); + pdf_print_mag_bp(pdf_ann_top(i)); end; pdf_dest_fitv: begin pdf_print("/FitV "); - pdf_print_mag_bp(pdf_x(pdf_left(i))); + pdf_print_mag_bp(pdf_ann_left(i)); end; pdf_dest_fitb: pdf_print("/FitB"); pdf_dest_fitbh: begin pdf_print("/FitBH "); - pdf_print_mag_bp(pdf_y(pdf_top(i))); + pdf_print_mag_bp(pdf_ann_top(i)); end; pdf_dest_fitbv: begin pdf_print("/FitBV "); - pdf_print_mag_bp(pdf_x(pdf_left(i))); + pdf_print_mag_bp(pdf_ann_left(i)); end; pdf_dest_fitr: begin pdf_print("/FitR "); @@ -19213,13 +18135,21 @@ end @ @= procedure pdf_print_rect_spec(r: pointer); {prints a rect spec} begin - pdf_print_mag_bp(pdf_x(pdf_left(r))); + pdf_print_mag_bp(pdf_ann_left(r)); pdf_out(" "); - pdf_print_mag_bp(pdf_y(pdf_bottom(r))); + pdf_print_mag_bp(pdf_ann_bottom(r)); pdf_out(" "); - pdf_print_mag_bp(pdf_x(pdf_right(r))); + pdf_print_mag_bp(pdf_ann_right(r)); pdf_out(" "); - pdf_print_mag_bp(pdf_y(pdf_top(r))); + pdf_print_mag_bp(pdf_ann_top(r)); +end; + +procedure pdf_rectangle(r:pointer); {output a rectangle specification to PDF file} +begin + prepare_mag; + pdf_print("/Rect ["); + pdf_print_rect_spec(r); + pdf_print_ln("]"); end; @ @= @@ -19333,31 +18263,6 @@ begin dvi_ship_out(p); end; -@ @= -check_pdfminorversion; -prepare_mag; -fixed_decimal_digits := fix_int(pdf_decimal_digits, 0, 4); -min_bp_val := - divide_scaled(one_hundred_bp, ten_pow[fixed_decimal_digits + 2], 0); -if pdf_pk_resolution = 0 then {if not set from format file or by user} - pdf_pk_resolution := pk_dpi; {take it from \.{texmf.cnf}} -fixed_pk_resolution := fix_int(pdf_pk_resolution, 72, 8000); -pk_scale_factor := - divide_scaled(72, fixed_pk_resolution, 5 + fixed_decimal_digits); -if not callback_defined(read_pk_file_callback) then begin - if pdf_pk_mode <> null then begin - kpseinitprog('PDFTEX', fixed_pk_resolution, - makecstring(tokens_to_string(pdf_pk_mode)), nil); - flush_string; - end else - kpseinitprog('PDFTEX', fixed_pk_resolution, nil, nil); - if not kpsevarvalue('MKTEXPK') then - kpsesetprogramenabled (kpsepkformat, 1, kpsesrccmdline); - end; -set_job_id(year, month, day, time); -if (pdf_unique_resname > 0) and (pdf_resname_prefix = 0) then - pdf_resname_prefix := get_resname_prefix - @ Finishing the PDF output file. The following procedures sort the table of destination names @@ -19413,53 +18318,48 @@ are already written completely to PDF output file. @= if total_pages=0 then begin - if callback_id=0 then - print_nl("No pages of output.") + if callback_id=0 then + print_nl("No pages of output.") else - res:=run_callback(callback_id,'->'); - @.No pages of output@> + res:=run_callback(callback_id,'->'); + @.No pages of output@> if pdf_gone > 0 then garbage_warning; end else begin if fixed_pdf_draftmode = 0 then begin - pdf_flush; {to make sure that the output file name has been already - created} - if total_pages mod pages_tree_kids_max <> 0 then - obj_info(pdf_last_pages) := total_pages mod pages_tree_kids_max; - {last pages object may have less than |pages_tree_kids_max| children} - flush_jbig2_page0_objects; {flush page 0 objects from JBIG2 images, if any} - @; - @; - @; - @; - @; - @; - @; - @; - @; - pdf_print_info; {last candidate for object stream} - if pdf_os_enable then begin - pdf_os_switch(true); - pdf_os_write_objstream; - pdf_flush; - pdf_os_switch(false); - @; + pdf_flush; {to make sure that the output file name has been already created} + flush_jbig2_page0_objects; {flush page 0 objects from JBIG2 images, if any} + @; + @; + @; + pdf_last_pages := output_pages_tree; + @; + @; + @; + @; + pdf_print_info; {last candidate for object stream} + if pdf_os_enable then begin + pdf_os_switch(true); + pdf_os_write_objstream; + pdf_flush; + pdf_os_switch(false); + @; + pdf_flush; + end else begin + @; + end; + @; pdf_flush; - end else begin - @; - end; - @; - pdf_flush; - if callback_id=0 then begin - print_nl("Output written on "); print_file_name(0, output_file_name, 0); - @.Output written on x@> - print(" ("); print_int(total_pages); print(" page"); - if total_pages<>1 then print_char("s"); - print(", "); print_int(pdf_offset); print(" bytes)."); - end - else - res:=run_callback(callback_id,'->'); + if callback_id=0 then begin + print_nl("Output written on "); print_file_name(0, output_file_name, 0); + @.Output written on x@> + print(" ("); print_int(total_pages); print(" page"); + if total_pages<>1 then print_char("s"); + print(", "); print_int(pdf_offset); print(" bytes)."); + end + else + res:=run_callback(callback_id,'->'); end; libpdffinish; if fixed_pdf_draftmode = 0 then b_close(pdf_file) @@ -19511,27 +18411,6 @@ while obj_aux(k) = 0 do begin end; head_tab[obj_type_page] := k -@ @= -k := head_tab[obj_type_page]; -l := 0; -repeat - i := obj_link(k); - obj_link(k) := l; - l := k; - k := i; -until k = 0; -head_tab[obj_type_page] := l; -k := head_tab[obj_type_pages]; -pages_tail := k; -l := 0; -repeat - i := obj_link(k); - obj_link(k) := l; - l := k; - k := i; -until k = 0; -head_tab[obj_type_pages] := l - @ @= for k := 1 to max_font_id do if font_used(k) and (pdf_font_num(k) < 0) then begin @@ -19550,7 +18429,9 @@ for k := 1 to max_font_id do print_font_identifier(i); print(" and "); print_font_identifier(k); - print(" has conflicting attributes"); print_ln; print_ln; + print(" have conflicting attributes; I will ignore the attributes assigned to "); + print_font_identifier(i); + print_ln; print_ln; end; end; fixed_gen_tounicode := pdf_gen_tounicode; @@ -19563,77 +18444,12 @@ while k <> 0 do begin end; write_fontstuff -@ We will generate in each single step the parents of all Pages/Page objects in -the previous level. These new generated Pages object will create a new level of -Pages tree. We will repeat this until search only one Pages object. This one -will be the Root object. - -@= -a := sys_obj_ptr + 1; {all Pages objects whose children are not Page objects - should have index greater than |a|} -l := head_tab[obj_type_pages]; {|l| is the index of current Pages object - which is being output} -k := head_tab[obj_type_page]; {|k| is the index of current child of |l|} -b := 0; -repeat - i := 0; {counter of Pages object in current level} - c := 0; {first Pages object in previous level} - if obj_link(l) = 0 then - is_root := true {only Pages object; total pages is - not greater than |pages_tree_kids_max|} - else - is_root := false; - repeat - if not is_root then begin - if i mod pages_tree_kids_max = 0 then begin {create a new Pages object - for next level} - pdf_last_pages := pdf_new_objnum; - if c = 0 then - c := pdf_last_pages; - obj_link(pages_tail) := pdf_last_pages; - pages_tail := pdf_last_pages; - obj_link(pdf_last_pages) := 0; - obj_info(pdf_last_pages) := obj_info(l); - end - else - obj_info(pdf_last_pages) := obj_info(pdf_last_pages) + - obj_info(l); - end; - @; - incr(i); - l := obj_link(l); - until (l = c); - b := c; - if l = 0 then - goto done; -until false; -done: - -@ @= -pdf_begin_dict(l, 1); -pdf_print_ln("/Type /Pages"); -pdf_int_entry_ln("Count", obj_info(l)); -if not is_root then - pdf_indirect_ln("Parent", pdf_last_pages); -pdf_print("/Kids ["); -j := 0; -repeat - pdf_print_int(k); - pdf_print(" 0 R "); - k := obj_link(k); - incr(j); -until ((l < a) and (j = obj_info(l))) or - (k = 0) or ((k = b) and (b <> 0)) or - (j = pages_tree_kids_max); -remove_last_space; -pdf_print_ln("]"); -if k = 0 then begin - k := head_tab[obj_type_pages]; - head_tab[obj_type_pages] := 0; +@ @p +procedure print_pdf_pages_attr; +begin + if pdf_pages_attr <> null then + pdf_print_toks_ln(pdf_pages_attr); end; -if is_root and (pdf_pages_attr <> null) then - pdf_print_toks_ln(pdf_pages_attr); -pdf_end_dict; @ The name tree is very similiar to Pages tree so its construction should be certain from Pages tree construction. For intermediate node |obj_info| will be @@ -19826,7 +18642,7 @@ begin end; @ @= -pdf_print("/Producer (luaTeX-"); +pdf_print("/Producer (LuaTeX-"); pdf_print_int(luatex_version div 100); pdf_out("."); pdf_print_int(luatex_version mod 100); @@ -19843,21 +18659,25 @@ print_mod_date; @ @= @!pdftex_banner: str_number; {the complete banner} -@ @= +@ @= l := 0; +set_obj_fresh(l); {null object at begin of list of free objects} for k := 1 to sys_obj_ptr do - if obj_offset(k) = 0 then begin + if not is_obj_written(k) then begin obj_link(l) := k; l := k; end; -obj_link(l) := 0; +obj_link(l) := 0 + +@ @= +@; pdf_save_offset := pdf_offset; pdf_print_ln("xref"); pdf_print("0 "); pdf_print_int_ln(obj_ptr + 1); pdf_print_fw_int(obj_link(0), 10); pdf_print_ln(" 65535 f "); for k := 1 to obj_ptr do begin - if obj_offset(k) = 0 then begin + if not is_obj_written(k) then begin pdf_print_fw_int(obj_link(k), 10); pdf_print_ln(" 00000 f "); end @@ -19869,21 +18689,15 @@ end @ @= pdf_new_dict(obj_type_others, 0, 0); -if obj_offset(sys_obj_ptr) > 16777215 then +if ((obj_offset(sys_obj_ptr)/256) > 16777215) then + xref_offset_width := 5 +else if obj_offset(sys_obj_ptr) > 16777215 then xref_offset_width := 4 else if obj_offset(sys_obj_ptr) > 65535 then xref_offset_width := 3 -else if obj_offset(sys_obj_ptr) > 255 then - xref_offset_width := 2 else - xref_offset_width := 1; -l := 0; -for k := 1 to sys_obj_ptr do - if obj_offset(k) = 0 then begin - obj_link(l) := k; - l := k; - end; -obj_link(l) := 0; + xref_offset_width := 2; +@; pdf_print_ln("/Type /XRef"); pdf_print("/Index [0 "); pdf_print_int(obj_ptr); @@ -19902,7 +18716,7 @@ print_ID(output_file_name); pdf_print_nl; pdf_begin_stream; for k := 0 to sys_obj_ptr do begin - if obj_offset(k) = 0 then begin {a free object} + if not is_obj_written(k) then begin {a free object} pdf_out(0); pdf_out_bytes(obj_link(k), xref_offset_width); pdf_out(255); @@ -20004,26 +18818,26 @@ attr_list:=attr_list_cache; if three_codes then begin s:=saved(0); continue: - if scan_keyword("attr") then begin + if scan_keyword('attr') then begin scan_register_num; i:=cur_val; scan_optional_equals; scan_int; v:=cur_val; - if (attr_list<>null) and (attr_list=attr_list_cache) then begin + if (attr_list<>null) and (attr_list=attr_list_cache) then begin attr_list:=copy_attribute_list(attr_list_cache); - add_node_attr_ref(attr_list); {will be used once} + add_node_attr_ref(attr_list); {will be used once} end; attr_list:=do_set_attribute(attr_list,i,v); goto continue; end; - if scan_keyword("dir") then begin + if scan_keyword('dir') then begin scan_direction; spec_direction:=cur_val; goto continue; end; end; if attr_list=attr_list_cache then begin add_node_attr_ref(attr_list); end; -if scan_keyword("to") then spec_code:=exactly +if scan_keyword('to') then spec_code:=exactly @.to@> -else if scan_keyword("spread") then spec_code:=additional +else if scan_keyword('spread') then spec_code:=additional @.spread@> else begin spec_code:=additional; cur_val:=0; goto found; @@ -20089,19 +18903,6 @@ location |adjust_tail|. @!last_leftmost_char: pointer; @!last_rightmost_char: pointer; -@ @d cal_margin_kern_var(#) == -begin - character(cp) := character(#); - font(cp) := font(#); - do_subst_font(cp, 1000); - if font(cp) <> font(#) then - margin_kern_stretch := margin_kern_stretch + left_pw(#) - left_pw(cp); - font(cp) := font(#); - do_subst_font(cp, -1000); - if font(cp) <> font(#) then - margin_kern_shrink := margin_kern_shrink + left_pw(cp) - left_pw(#); -end - @ @= next_char_p:pointer; {pointer to the next char of an implicit kern} prev_char_p:pointer; {pointer to the previous char of an implicit kern} @@ -20122,9 +18923,6 @@ font expansion is being used. We define some constants used when calling @d substituted = 3 {|subtype| of kern nodes that should be substituted} -@d left_pw(#) == char_pw(#, left_side) -@d right_pw(#) == char_pw(#, right_side) - @p function char_stretch(p:halfword): scaled; var k: internal_font_number; dw: scaled; @@ -20234,7 +19032,7 @@ begin else begin {|short_display_n(p, 5);|} pdf_error("font expansion", "invalid node type"); - return; + return; end; f := font(r); ef := get_ef_code(f, character(r)); @@ -20365,7 +19163,7 @@ exit: if (m = cal_expand_ratio) and (font_expand_ratio <> 0) then begin font_expand_ratio := fix_int(font_expand_ratio, -1000, 1000); q := list_ptr(r); - list_ptr(r):=null; flush_node(r); + list_ptr(r):=null; flush_node(r); r:=hpack(q, w, subst_ex_font); end; while dir_ptr<>null do pop_dir_node; @@ -20374,7 +19172,6 @@ end; function filtered_hpack(@!p:pointer;@!qt:pointer;@!w:scaled;@!m:small_number;@!grp:integer):pointer; var q:pointer; - d:integer; { a direction } begin new_hyphenation(p,qt); call_func(new_ligkern(p,qt)); {don't care about the tail in this case} @@ -20398,14 +19195,14 @@ begin while is_char_node(p) do the hbox that will contain~it, then move to the next node@>; if p<>null then begin case type(p) of - hlist_node,vlist_node,rule_node,unset_node: + hlist_node_case,vlist_node_case,rule_node_case,unset_node_case: @; - ins_node,mark_node,adjust_node: begin if adjust_tail<>null then + ins_node_case,mark_node_case,adjust_node_case: begin if adjust_tail<>null then @; end; - whatsit_node:@; - glue_node:@; - margin_kern_node: begin + whatsit_node_case:@; + glue_node_case:@; + margin_kern_node_case: begin if m = cal_expand_ratio then begin f := font(margin_char(p)); do_subst_font(margin_char(p), 1000); @@ -20425,7 +19222,7 @@ if p<>null then end; x := x + width(p); end; - kern_node: begin + kern_node_case: begin if subtype(p) = normal then begin if m = cal_expand_ratio then begin font_stretch := font_stretch + kern_stretch(p); @@ -20446,8 +19243,8 @@ if p<>null then end; x := x + width(p); end; - math_node: x:=x+surround(p); - disc_node: + math_node_case: x:=x+surround(p); + disc_node_case: begin if m = subst_ex_font then do_subst_font(p, font_expand_ratio); if vlink(no_break(p))<>null then begin @@ -20476,7 +19273,7 @@ if (type(p)=hlist_node) or (type(p)=vlist_node) then begin if (width(p) div 2)-s>h then h:=(width(p) div 2)-s; if (width(p) div 2)+s>d then d:=(width(p) div 2)+s; end - else if (type(p)=hlist_node) and (is_mirrored(hpack_dir)) then begin + else if (type(p)=hlist_node) and is_mirrored(hpack_dir) then begin x:=x+width(p); s:=shift_amount(p); if depth(p)-s>h then h:=depth(p)-s; @@ -20778,12 +19575,12 @@ end; begin if is_char_node(p) then confusion("vpack") @:this can't happen vpack}{\quad vpack@> else case type(p) of - hlist_node,vlist_node,rule_node,unset_node: + hlist_node_case,vlist_node_case,rule_node_case,unset_node_case: @; - whatsit_node:@; - glue_node: @; - kern_node: begin x:=x+d+width(p); d:=0; + whatsit_node_case:@; + glue_node_case: @; + kern_node_case: begin x:=x+d+width(p); d:=0; end; othercases do_nothing endcases; @@ -20798,7 +19595,7 @@ if (type(p)=hlist_node) or (type(p)=vlist_node) then begin s:=shift_amount(p); if depth(p)+height(p)+s>w then w:=depth(p)+height(p)+s; end - else if (type(p)=hlist_node) and (is_mirrored(box_dir(p))) then begin + else if (type(p)=hlist_node) and is_mirrored(box_dir(p)) then begin x:=x+d+depth(p); d:=height(p); s:=shift_amount(p); if width(p)+s>w then w:=width(p)+s; @@ -20924,10 +19721,10 @@ baselineskip calculation is handled by the |append_to_vlist| routine. @p procedure append_to_vlist(@!b:pointer); var d:scaled; {deficiency of space between baselines} -@!p:pointer; {a new glue specification} -begin if prev_depth>ignore_depth then +@!p:pointer; {a new glue node} +begin if prev_depth>pdf_ignored_dimen then begin - if (type(b)=hlist_node) and (is_mirrored(box_dir(b))) then + if (type(b)=hlist_node) and is_mirrored(box_dir(b)) then d:=width(baseline_skip)-prev_depth-depth(b) else d:=width(baseline_skip)-prev_depth-height(b); @@ -20938,1895 +19735,160 @@ begin if prev_depth>ignore_depth then vlink(tail):=p; tail:=p; end; vlink(tail):=b; tail:=b; -if (type(b)=hlist_node) and (is_mirrored(box_dir(b))) then +if (type(b)=hlist_node) and is_mirrored(box_dir(b)) then prev_depth:=height(b) else prev_depth:=depth(b); end; @* \[34] Data structures for math mode. -When \TeX\ reads a formula that is enclosed between \.\$'s, it constructs an -{\sl mlist}, which is essentially a tree structure representing that -formula. An mlist is a linear sequence of items, but we can regard it as -a tree structure because mlists can appear within mlists. For example, many -of the entries can be subscripted or superscripted, and such ``scripts'' -are mlists in their own right. - -An entire formula is parsed into such a tree before any of the actual -typesetting is done, because the current style of type is usually not -known until the formula has been fully scanned. For example, when the -formula `\.{\$a+b \\over c+d\$}' is being read, there is no way to tell -that `\.{a+b}' will be in script size until `\.{\\over}' has appeared. - -During the scanning process, each element of the mlist being built is -classified as a relation, a binary operator, an open parenthesis, etc., -or as a construct like `\.{\\sqrt}' that must be built up. This classification -appears in the mlist data structure. - -After a formula has been fully scanned, the mlist is converted to an hlist -so that it can be incorporated into the surrounding text. This conversion is -controlled by a recursive procedure that decides all of the appropriate -styles by a ``top-down'' process starting at the outermost level and working -in towards the subformulas. The formula is ultimately pasted together using -combinations of horizontal and vertical boxes, with glue and penalty nodes -inserted as necessary. - -An mlist is represented internally as a linked list consisting chiefly -of ``noads'' (pronounced ``no-adds''), to distinguish them from the somewhat -similar ``nodes'' in hlists and vlists. Certain kinds of ordinary nodes are -allowed to appear in mlists together with the noads; \TeX\ tells the difference -by means of the |type| field, since a noad's |type| is always greater than -that of a node. An mlist does not contain character nodes, hlist nodes, vlist -nodes, math nodes or unset nodes; in particular, each mlist item appears in the -variable-size part of |mem|, so the |type| field is always present. - -@ Each noad is five or more words long. The first word contains the -|type| and |subtype| and |link| fields that are already so familiar to -us; the second contains the attribute list pointer, and the third, -fourth an fifth words are called the noad's |nucleus|, |subscr|, and -|supscr| fields. (This use of a combined attribute list is temporary. -Eventually, each of fields need their own list) - -Consider, for example, the simple formula `\.{\$x\^2\$}', which would be -parsed into an mlist containing a single element called an |ord_noad|. -The |nucleus| of this noad is a representation of `\.x', the |subscr| is -empty, and the |supscr| is a representation of `\.2'. - -The |nucleus|, |subscr|, and |supscr| fields are further broken into -subfields. If |p| points to a noad, and if |q| is one of its principal -fields (e.g., |q=subscr(p)|), there are several possibilities for the -subfields, depending on the |math_type| of |q|. - -\yskip\hang|math_type(q)=math_char| means that |fam(q)| refers to one of -the sixteen font families, and |character(q)| is the number of a character -within a font of that family, as in a character node. - -\yskip\hang|math_type(q)=math_text_char| is similar, but the character is -unsubscripted and unsuperscripted and it is followed immediately by another -character from the same font. (This |math_type| setting appears only -briefly during the processing; it is used to suppress unwanted italic -corrections.) - -\yskip\hang|math_type(q)=empty| indicates a field with no value (the -corresponding attribute of noad |p| is not present). - -\yskip\hang|math_type(q)=sub_box| means that |vinfo(q)| points to a box -node (either an |hlist_node| or a |vlist_node|) that should be used as the -value of the field. The |shift_amount| in the subsidiary box node is the -amount by which that box will be shifted downward. - -\yskip\hang|math_type(q)=sub_mlist| means that |vinfo(q)| points to -an mlist; the mlist must be converted to an hlist in order to obtain -the value of this field. - -\yskip\noindent In the latter case, we might have |vinfo(q)=null|. This -is not the same as |math_type(q)=empty|; for example, `\.{\$P\_\{\}\$}' -and `\.{\$P\$}' produce different results (the former will not have the -``italic correction'' added to the width of |P|, but the ``script skip'' -will be added). - -The definitions of subfields given here are a little wasteful of space, -since a quarterword is being used for the |math_type| although only three -bits would be needed. However, there are hardly ever many noads present at -once, since they are soon converted to nodes that take up even more space, -so we can afford to represent them in whatever way simplifies the -programming. - -I tried exchanging |mcharacter()| and |math_type()| so that a character -could use the full Unicode range, but for some reason that does not work -properly. TH - -@d noad_size=5 {number of words in a normal noad} -@d nucleus(#)==#+2 {the |nucleus| field of a noad} -@d supscr(#)==#+3 {the |supscr| field of a noad} -@d subscr(#)==#+4 {the |subscr| field of a noad} -@d math_type==vlink {a |quarterword| in |mem|} -@d fam(#)==type(#) {a |quarterword| in |mem|} -@d mcharacter(#)==subtype(#) -@d math_char=1 {|math_type| when the attribute is simple} -@d sub_box=2 {|math_type| when the attribute is a box} -@d sub_mlist=3 {|math_type| when the attribute is a formula} -@d math_text_char=4 {|math_type| when italic correction is dubious} - -@ Each portion of a formula is classified as Ord, Op, Bin, Rel, Ope, -Clo, Pun, or Inn, for purposes of spacing and line breaking. An -|ord_noad|, |op_noad|, |bin_noad|, |rel_noad|, |open_noad|, |close_noad|, -|punct_noad|, or |inner_noad| is used to represent portions of the various -types. For example, an `\.=' sign in a formula leads to the creation of a -|rel_noad| whose |nucleus| field is a representation of an equals sign -(usually |fam=0|, |character=@'75|). A formula preceded by \.{\\mathrel} -also results in a |rel_noad|. When a |rel_noad| is followed by an -|op_noad|, say, and possibly separated by one or more ordinary nodes (not -noads), \TeX\ will insert a penalty node (with the current |rel_penalty|) -just after the formula that corresponds to the |rel_noad|, unless there -already was a penalty immediately following; and a ``thick space'' will be -inserted just before the formula that corresponds to the |op_noad|. - -A noad of type |ord_noad|, |op_noad|, \dots, |inner_noad| usually -has a |subtype=normal|. The only exception is that an |op_noad| might -have |subtype=limits| or |no_limits|, if the normal positioning of -limits has been overridden for this operator. - -@d ord_noad=unset_node+3 {|type| of a noad classified Ord} -@d op_noad=ord_noad+1 {|type| of a noad classified Op} -@d bin_noad=ord_noad+2 {|type| of a noad classified Bin} -@d rel_noad=ord_noad+3 {|type| of a noad classified Rel} -@d open_noad=ord_noad+4 {|type| of a noad classified Ope} -@d close_noad=ord_noad+5 {|type| of a noad classified Clo} -@d punct_noad=ord_noad+6 {|type| of a noad classified Pun} -@d inner_noad=ord_noad+7 {|type| of a noad classified Inn} -@d limits=1 {|subtype| of |op_noad| whose scripts are to be above, below} -@d no_limits=2 {|subtype| of |op_noad| whose scripts are to be normal} - -@ A |radical_noad| is five words long; the fifth word is the |left_delimiter| -field, which usually represents a square root sign. - -A |fraction_noad| is six words long; it has a |right_delimiter| field -as well as a |left_delimiter|. - -Delimiter fields are of type |four_quarters|, and they have four subfields -called |small_fam|, |small_char|, |large_fam|, |large_char|. These subfields -represent variable-size delimiters by giving the ``small'' and ``large'' -starting characters, as explained in Chapter~17 of {\sl The \TeX book}. -@:TeXbook}{\sl The \TeX book@> -A |fraction_noad| is actually quite different from all other noads. Not -only does it have six words, it has |thickness|, |denominator|, and -|numerator| fields instead of |nucleus|, |subscr|, and |supscr|. The -|thickness| is a scaled value that tells how thick to make a fraction -rule; however, the special value |default_code| is used to stand for the -|default_rule_thickness| of the current size. The |numerator| and -|denominator| point to mlists that define a fraction; we always have -$$\hbox{|math_type(numerator)=math_type(denominator)=sub_mlist|}.$$ The -|left_delimiter| and |right_delimiter| fields specify delimiters that will -be placed at the left and right of the fraction. In this way, a -|fraction_noad| is able to represent all of \TeX's operators \.{\\over}, -\.{\\atop}, \.{\\above}, \.{\\overwithdelims}, \.{\\atopwithdelims}, and - \.{\\abovewithdelims}. - -@d left_delimiter(#)==#+5 {first delimiter field of a noad} -@d right_delimiter(#)==#+6 {second delimiter field of a fraction noad} -@d radical_noad=inner_noad+1 {|type| of a noad for square roots} -@d radical_noad_size=6 {number of |mem| words in a radical noad} -@d fraction_noad=radical_noad+1 {|type| of a noad for generalized fractions} -@d fraction_noad_size=7 {number of |mem| words in a fraction noad} -@d small_fam(#)==vmem(#).qqqq.b0 {|fam| for ``small'' delimiter} -@d small_char(#)==vmem(#).qqqq.b1 {|character| for ``small'' delimiter} -@d large_fam(#)==vmem(#).qqqq.b2 {|fam| for ``large'' delimiter} -@d large_char(#)==vmem(#).qqqq.b3 {|character| for ``large'' delimiter} -@d thickness(#)==vmem(#+2).sc {|thickness| field in a fraction noad} -@d default_code==@'10000000000 {denotes |default_rule_thickness|} -@d numerator==supscr {|numerator| field in a fraction noad} -@d denominator==subscr {|denominator| field in a fraction noad} - -@ The global variable |empty_field| is set up for initialization of empty -fields in new noads. Similarly, |null_delimiter| is for the initialization -of delimiter fields. +Is done in C. -@= -@!empty_field:two_halves; -@!null_delimiter:four_quarters; +@* \[35] Subroutines for math mode. -@ @= -empty_field.rh:=empty; empty_field.lh:=null;@/ -null_delimiter.b0:=0; null_delimiter.b1:=min_quarterword;@/ -null_delimiter.b2:=0; null_delimiter.b3:=min_quarterword; +Is one in C. -@ The |new_noad| function creates an |ord_noad| that is completely null. +@* \[36] Typesetting math formulas. -@p function new_noad:pointer; -var p:pointer; -begin p:=new_node(ord_noad,normal); -vmem(nucleus(p)).hh:=empty_field; -vmem(subscr(p)).hh:=empty_field; -vmem(supscr(p)).hh:=empty_field; -new_noad:=p; -end; - -@ A few more kinds of noads will complete the set: An |under_noad| has its -nucleus underlined; an |over_noad| has it overlined. An |accent_noad| places -an accent over its nucleus; the accent character appears as -|fam(accent_chr(p))| and |mcharacter(accent_chr(p))|. A |vcenter_noad| -centers its nucleus vertically with respect to the axis of the formula; -in such noads we always have |math_type(nucleus(p))=sub_box|. - -And finally, we have |left_noad| and |right_noad| types, to implement -\TeX's \.{\\left} and \.{\\right} as well as \eTeX's \.{\\middle}. -The |nucleus| of such noads is -replaced by a |delimiter| field; thus, for example, `\.{\\left(}' produces -a |left_noad| such that |delimiter(p)| holds the family and character -codes for all left parentheses. A |left_noad| never appears in an mlist -except as the first element, and a |right_noad| never appears in an mlist -except as the last element; furthermore, we either have both a |left_noad| -and a |right_noad|, or neither one is present. The |subscr| and |supscr| -fields are always |empty| in a |left_noad| and a |right_noad|. - -@d under_noad=fraction_noad+1 {|type| of a noad for underlining} -@d over_noad=under_noad+1 {|type| of a noad for overlining} -@d accent_noad=over_noad+1 {|type| of a noad for accented subformulas} -@d accent_noad_size=6 {number of |mem| words in an accent noad} -@d accent_chr(#)==#+5 {the |accent_chr| field of an accent noad} -@d vcenter_noad=accent_noad+1 {|type| of a noad for \.{\\vcenter}} -@d left_noad=vcenter_noad+1 {|type| of a noad for \.{\\left}} -@d right_noad=left_noad+1 {|type| of a noad for \.{\\right}} -@d delimiter==nucleus {|delimiter| field in left and right noads} -@d middle_noad==1 {|subtype| of right noad representing \.{\\middle}} -@d scripts_allowed(#)==(type(#)>=ord_noad)and(type(#) +Is done in C. -@d style_node=unset_node+1 {|type| of a style node} -@d style_node_size=4 {number of words in a style node} -@d display_style=0 {|subtype| for \.{\\displaystyle}} -@d text_style=2 {|subtype| for \.{\\textstyle}} -@d script_style=4 {|subtype| for \.{\\scriptstyle}} -@d script_script_style=6 {|subtype| for \.{\\scriptscriptstyle}} -@d cramped=1 {add this to an uncramped style if you want to cramp it} +@* \[37] Alignment. +It's sort of a miracle whenever \.{\\halign} and \.{\\valign} work, because +they cut across so many of the control structures of \TeX. -@p function new_style(@!s:small_number):pointer; {create a style node} -var p:pointer; {the new node} -begin p:=new_node(style_node,s); -new_style:=p; -end; +Therefore the +present page is probably not the best place for a beginner to start reading +this program; it is better to master everything else first. -@ Finally, the \.{\\mathchoice} primitive creates a |choice_node|, which -has special subfields |display_mlist|, |text_mlist|, |script_mlist|, -and |script_script_mlist| pointing to the mlists for each style. +Let us focus our thoughts on an example of what the input might be, in order +to get some idea about how the alignment miracle happens. The example doesn't +do anything useful, but it is sufficiently general to indicate all of the +special cases that must be dealt with; please do not be disturbed by its +apparent complexity and meaninglessness. +$$\vbox{\halign{\.{#}\hfil\cr +{}\\tabskip 2pt plus 3pt\cr +{}\\halign to 300pt\{u1\#v1\&\cr +\hskip 50pt\\tabskip 1pt plus 1fil u2\#v2\&\cr +\hskip 50pt u3\#v3\\cr\cr +\hskip 25pt a1\&\\omit a2\&\\vrule\\cr\cr +\hskip 25pt \\noalign\{\\vskip 3pt\}\cr +\hskip 25pt b1\\span b2\\cr\cr +\hskip 25pt \\omit\&c2\\span\\omit\\cr\}\cr}}$$ +Here's what happens: -@d choice_node=unset_node+2 {|type| of a choice node} -@d display_mlist(#)==vinfo(#+2) {mlist to be used in display style} -@d text_mlist(#)==vlink(#+2) {mlist to be used in text style} -@d script_mlist(#)==vinfo(#+3) {mlist to be used in script style} -@d script_script_mlist(#)==vlink(#+3) {mlist to be used in scriptscript style} +\yskip +(0) When `\.{\\halign to 300pt\{}' is scanned, the |scan_spec| routine +places the 300pt dimension onto the |save_stack|, and an |align_group| +code is placed above it. This will make it possible to complete the alignment +when the matching `\.\}' is found. -@p function new_choice:pointer; {create a choice node} -var p:pointer; {the new node} -begin p:=new_node(choice_node,0); {the |subtype| is not used} -new_choice:=p; -end; - -@ Let's consider now the previously unwritten part of |show_node_list| -that displays the things that can only be present in mlists; this -program illustrates how to access the data structures just defined. - -In the context of the following program, |p| points to a node or noad that -should be displayed, and the current string contains the ``recursion history'' -that leads to this point. The recursion history consists of a dot for each -outer level in which |p| is subsidiary to some node, or in which |p| is -subsidiary to the |nucleus| field of some noad; the dot is replaced by -`\.\_' or `\.\^' or `\./' or `\.\\' if |p| is descended from the |subscr| -or |supscr| or |denominator| or |numerator| fields of noads. For example, -the current string would be `\.{.\^.\_/}' if |p| points to the |ord_noad| for -|x| in the (ridiculous) formula -`\.{\$\\sqrt\{a\^\{\\mathinner\{b\_\{c\\over x+y\}\}\}\}\$}'. - -@= -style_node:print_style(subtype(p)); -choice_node:@; -ord_noad,op_noad,bin_noad,rel_noad,open_noad,close_noad,punct_noad,inner_noad, - radical_noad,over_noad,under_noad,vcenter_noad,accent_noad, - left_noad,right_noad:@; -fraction_noad:@; - -@ Here are some simple routines used in the display of noads. - -@= -procedure print_fam_and_char(@!p:pointer); {prints family and character} -begin print_esc("fam"); print_int(fam(p)); print_char(" "); -print(qo(mcharacter(p))); -end; -@# -procedure print_delimiter(@!p:pointer); {prints a delimiter as 24-bit hex value} -{TH: FIX to do: print 48-bit integer where needed!} -var a:integer; {accumulator} -begin a:=small_fam(p)*256+qo(small_char(p)); -a:=a*@"1000+large_fam(p)*256+qo(large_char(p)); -if a<0 then print_int(a) {this should never happen} -else print_hex(a); -end; - -@ The next subroutine will descend to another level of recursion when a -subsidiary mlist needs to be displayed. The parameter |c| indicates what -character is to become part of the recursion history. An empty mlist is -distinguished from a field with |math_type(p)=empty|, because these are -not equivalent (as explained above). -@^recursion@> +(1) The preamble is scanned next. Macros in the preamble are not expanded, +@^preamble@> +except as part of a tabskip specification. For example, if \.{u2} had been +a macro in the preamble above, it would have been expanded, since \TeX\ +must look for `\.{minus...}' as part of the tabskip glue. A ``preamble list'' +is constructed based on the user's preamble; in our case it contains the +following seven items: +$$\vbox{\halign{\.{#}\hfil\qquad&(#)\hfil\cr +{}\\glue 2pt plus 3pt&the tabskip preceding column 1\cr +{}\\alignrecord, width $-\infty$&preamble info for column 1\cr +{}\\glue 2pt plus 3pt&the tabskip between columns 1 and 2\cr +{}\\alignrecord, width $-\infty$&preamble info for column 2\cr +{}\\glue 1pt plus 1fil&the tabskip between columns 2 and 3\cr +{}\\alignrecord, width $-\infty$&preamble info for column 3\cr +{}\\glue 1pt plus 1fil&the tabskip following column 3\cr}}$$ +These ``alignrecord'' entries have the same size as an |unset_node|, +since they will later be converted into such nodes. These alignrecord +nodes have no |depth| field; this is split into |u_part| and |v_part|, +and they point to token lists for the templates of the alignment. For +example, the |u_part| field in the first alignrecord points to the +token list `\.{u1}', i.e., the template preceding the `\.\#' for +column~1. Furthermore, They have a |span_ptr| instead of a |node_attr| +field, and these |span_ptr| fields are initially set to the value +|end_span|, for reasons explained below. -@= -procedure@?show_info; forward;@t\2@>@?{|show_node_list(vinfo(temp_ptr))|} -procedure print_subsidiary_data(@!p:pointer;@!c:ASCII_code); - {display a noad field} -begin if cur_length>=depth_threshold then - begin if math_type(p)<>empty then print(" []"); - end -else begin append_char(c); {include |c| in the recursion history} - temp_ptr:=p; {prepare for |show_info| if recursion is needed} - case math_type(p) of - math_char: begin print_ln; print_current_string; print_fam_and_char(p); - end; - sub_box: show_info; {recursive call} - sub_mlist: if vinfo(p)=null then - begin print_ln; print_current_string; print("{}"); - end - else show_info; {recursive call} - othercases do_nothing {|empty|} - endcases;@/ - flush_char; {remove |c| from the recursion history} - end; -end; +(2) \TeX\ now looks at what follows the \.{\\cr} that ended the preamble. +It is not `\.{\\noalign}' or `\.{\\omit}', so this input is put back to +be read again, and the template `\.{u1}' is fed to the scanner. Just +before reading `\.{u1}', \TeX\ goes into restricted horizontal mode. +Just after reading `\.{u1}', \TeX\ will see `\.{a1}', and then (when the +{\.\&} is sensed) \TeX\ will see `\.{v1}'. Then \TeX\ scans an |endv| +token, indicating the end of a column. At this point an |unset_node| is +created, containing the contents of the current hlist (i.e., `\.{u1a1v1}'). +The natural width of this unset node replaces the |width| field of the +alignrecord for column~1; in general, the alignrecords will record the +maximum natural width that has occurred so far in a given column. -@ The inelegant introduction of |show_info| in the code above seems better -than the alternative of using \PASCAL's strange |forward| declaration for a -procedure with parameters. The \PASCAL\ convention about dropping parameters -from a post-|forward| procedure is, frankly, so intolerable to the author -of \TeX\ that he would rather stoop to communication via a global temporary -variable. (A similar stoopidity occurred with respect to |hlist_out| and -|vlist_out| above, and it will occur with respect to |mlist_to_hlist| below.) -@^Knuth, Donald Ervin@> -@:PASCAL}{\PASCAL@> +(3) Since `\.{\\omit}' follows the `\.\&', the templates for column~2 +are now bypassed. Again \TeX\ goes into restricted horizontal mode and +makes an |unset_node| from the resulting hlist; but this time the +hlist contains simply `\.{a2}'. The natural width of the new unset box +is remembered in the |width| field of the alignrecord for column~2. -@p procedure show_info; {the reader will kindly forgive this} -begin show_node_list(vinfo(temp_ptr)); -end; +(4) A third |unset_node| is created for column 3, using essentially the +mechanism that worked for column~1; this unset box contains `\.{u3\\vrule +v3}'. The vertical rule in this case has running dimensions that will later +extend to the height and depth of the whole first row, since each |unset_node| +in a row will eventually inherit the height and depth of its enclosing box. -@ @= -procedure print_style(@!c:integer); -begin case c div 2 of -0: print_esc("displaystyle"); {|display_style=0|} -1: print_esc("textstyle"); {|text_style=2|} -2: print_esc("scriptstyle"); {|script_style=4|} -3: print_esc("scriptscriptstyle"); {|script_script_style=6|} -othercases print("Unknown style!") -endcases; -end; +(5) The first row has now ended; it is made into a single unset box +comprising the following seven items: +$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr +{}\\glue 2pt plus 3pt\cr +{}\\unsetbox for 1 column: u1a1v1\cr +{}\\glue 2pt plus 3pt\cr +{}\\unsetbox for 1 column: a2\cr +{}\\glue 1pt plus 1fil\cr +{}\\unsetbox for 1 column: u3\\vrule v3\cr +{}\\glue 1pt plus 1fil\cr}}$$ +The width of this unset row is unimportant, but it has the correct height +and depth, so the correct baselineskip glue will be computed as the row +is inserted into a vertical list. -@ @= -begin print_esc("mathchoice"); -append_char("D"); show_node_list(display_mlist(p)); flush_char; -append_char("T"); show_node_list(text_mlist(p)); flush_char; -append_char("S"); show_node_list(script_mlist(p)); flush_char; -append_char("s"); show_node_list(script_script_mlist(p)); flush_char; -end +(6) Since `\.{\\noalign}' follows the current \.{\\cr}, \TeX\ appends +additional material (in this case \.{\\vskip 3pt}) to the vertical list. +While processing this material, \TeX\ will be in internal vertical +mode, and |no_align_group| will be on |save_stack|. -@ @= -begin case type(p) of -ord_noad: print_esc("mathord"); -op_noad: print_esc("mathop"); -bin_noad: print_esc("mathbin"); -rel_noad: print_esc("mathrel"); -open_noad: print_esc("mathopen"); -close_noad: print_esc("mathclose"); -punct_noad: print_esc("mathpunct"); -inner_noad: print_esc("mathinner"); -over_noad: print_esc("overline"); -under_noad: print_esc("underline"); -vcenter_noad: print_esc("vcenter"); -radical_noad: begin - {TH: TODO print oradical where needed and fix otherwise} - print_esc("radical"); print_delimiter(left_delimiter(p)); - end; -accent_noad: begin print_esc("accent"); print_fam_and_char(accent_chr(p)); - end; -left_noad: begin print_esc("left"); print_delimiter(nucleus(p)); - end; -right_noad: begin if subtype(p)=normal then print_esc("right") - else print_esc("middle"); - print_delimiter(nucleus(p)); - end; -end; -if type(p)normal then - if subtype(p)=limits then print_esc("limits") - else print_esc("nolimits"); - print_subsidiary_data(nucleus(p),"."); - end; -print_subsidiary_data(supscr(p),"^"); -print_subsidiary_data(subscr(p),"_"); -end - -@ @= -begin print_esc("fraction, thickness "); -if thickness(p)=default_code then print("= default") -else print_scaled(thickness(p)); -if (small_fam(left_delimiter(p))<>0)or@+ - (small_char(left_delimiter(p))<>min_quarterword)or@| - (large_fam(left_delimiter(p))<>0)or@| - (large_char(left_delimiter(p))<>min_quarterword) then - begin print(", left-delimiter "); print_delimiter(left_delimiter(p)); - end; -if (small_fam(right_delimiter(p))<>0)or@| - (small_char(right_delimiter(p))<>min_quarterword)or@| - (large_fam(right_delimiter(p))<>0)or@| - (large_char(right_delimiter(p))<>min_quarterword) then - begin print(", right-delimiter "); print_delimiter(right_delimiter(p)); - end; -print_subsidiary_data(numerator(p),"\"); -print_subsidiary_data(denominator(p),"/"); -end +(7) The next row produces an unset box that looks like this: +$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr +{}\\glue 2pt plus 3pt\cr +{}\\unsetbox for 2 columns: u1b1v1u2b2v2\cr +{}\\glue 1pt plus 1fil\cr +{}\\unsetbox for 1 column: {\rm(empty)}\cr +{}\\glue 1pt plus 1fil\cr}}$$ +The natural width of the unset box that spans columns 1~and~2 is stored +in a ``span node,'' which we will explain later; the |span_ptr| field of the +alignrecord for column~1 now points to the new span node, and the |span_ptr| +of the span node points to |end_span|. -@* \[35] Subroutines for math mode. -In order to convert mlists to hlists, i.e., noads to nodes, we need several -subroutines that are conveniently dealt with now. +(8) The final row produces the unset box +$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr +{}\\glue 2pt plus 3pt\cr +{}\\unsetbox for 1 column: {\rm(empty)}\cr +{}\\glue 2pt plus 3pt\cr +{}\\unsetbox for 2 columns: u2c2v2\cr +{}\\glue 1pt plus 1fil\cr}}$$ +A new span node is attached to the alignrecord for column 2. -Let us first introduce the macros that make it easy to get at the parameters and -other font information. A size code, which is a multiple of 16, is added to a -family number to get an index into the table of internal font numbers -for each combination of family and size. (Be alert: Size codes get -larger as the type gets smaller.) +(9) The last step is to compute the true column widths and to change all the +unset boxes to hboxes, appending the whole works to the vertical list that +encloses the \.{\\halign}. The rules for deciding on the final widths of +each unset column box will be explained below. -@= -procedure print_size(@!s:integer); -begin if s=0 then print_esc("textfont") -else if s=script_size then print_esc("scriptfont") -else print_esc("scriptscriptfont"); -end; - -@ Before an mlist is converted to an hlist, \TeX\ makes sure that -the fonts in family~2 have enough parameters to be math-symbol -fonts, and that the fonts in family~3 have enough parameters to be -math-extension fonts. The math-symbol parameters are referred to by using the -following macros, which take a size code as their parameter; for example, -|num1(cur_size)| gives the value of the |num1| parameter for the current size. -@^parameters for symbols@> -@^font parameters@> - -@d mathsy_end(#)== -@d mathsy(#)==font_param(fam_fnt(2+cur_size),#) mathsy_end -@d math_x_height==mathsy(5) {height of `\.x'} -@d math_quad==mathsy(6) {\.{18mu}} -@d num1==mathsy(8) {numerator shift-up in display styles} -@d num2==mathsy(9) {numerator shift-up in non-display, non-\.{\\atop}} -@d num3==mathsy(10) {numerator shift-up in non-display \.{\\atop}} -@d denom1==mathsy(11) {denominator shift-down in display styles} -@d denom2==mathsy(12) {denominator shift-down in non-display styles} -@d sup1==mathsy(13) {superscript shift-up in uncramped display style} -@d sup2==mathsy(14) {superscript shift-up in uncramped non-display} -@d sup3==mathsy(15) {superscript shift-up in cramped styles} -@d sub1==mathsy(16) {subscript shift-down if superscript is absent} -@d sub2==mathsy(17) {subscript shift-down if superscript is present} -@d sup_drop==mathsy(18) {superscript baseline below top of large box} -@d sub_drop==mathsy(19) {subscript baseline below bottom of large box} -@d delim1==mathsy(20) {size of \.{\\atopwithdelims} delimiters - in display styles} -@d delim2==mathsy(21) {size of \.{\\atopwithdelims} delimiters in non-displays} -@d axis_height==mathsy(22) {height of fraction lines above the baseline} -@d total_mathsy_params=22 - -@ The math-extension parameters have similar macros, but the size code is -omitted (since it is always |cur_size| when we refer to such parameters). -@^parameters for symbols@> -@^font parameters@> - -@d mathex(#)==font_param(fam_fnt(3+cur_size),#) -@d default_rule_thickness==mathex(8) {thickness of \.{\\over} bars} -@d big_op_spacing1==mathex(9) {minimum clearance above a displayed op} -@d big_op_spacing2==mathex(10) {minimum clearance below a displayed op} -@d big_op_spacing3==mathex(11) {minimum baselineskip above displayed op} -@d big_op_spacing4==mathex(12) {minimum baselineskip below displayed op} -@d big_op_spacing5==mathex(13) {padding above and below displayed limits} -@d total_mathex_params=13 - -@ We also need to compute the change in style between mlists and their -subsidiaries. The following macros define the subsidiary style for -an overlined nucleus (|cramped_style|), for a subscript or a superscript -(|sub_style| or |sup_style|), or for a numerator or denominator (|num_style| -or |denom_style|). - -@d cramped_style(#)==2*(# div 2)+cramped {cramp the style} -@d sub_style(#)==2*(# div 4)+script_style+cramped {smaller and cramped} -@d sup_style(#)==2*(# div 4)+script_style+(# mod 2) {smaller} -@d num_style(#)==#+2-2*(# div 6) {smaller unless already script-script} -@d denom_style(#)==2*(# div 2)+cramped+2-2*(# div 6) {smaller, cramped} - -@ When the style changes, the following piece of program computes associated -information: - -@= -begin if cur_style@ -function var_delimiter(@!d:pointer;@!s:integer;@!v:scaled):pointer; -label found,continue; -var b:pointer; {the box that will be constructed} -@!f,@!g: internal_font_number; {best-so-far and tentative font codes} -@!c,@!x,@!y: integer; {best-so-far and tentative character codes} -@!cc: integer; { a temporary character code for extensibles } -@!m,@!n: integer; {the number of extensible pieces} -@!u: scaled; {height-plus-depth of a tentative character} -@!w: scaled; {largest height-plus-depth so far} -@!z: integer; {runs through font family members} -@!large_attempt: boolean; {are we trying the ``large'' variant?} -begin f:=null_font; c:=0; w:=0; large_attempt:=false; -z:=small_fam(d); x:=small_char(d); -loop@+ begin @; - if large_attempt then goto found; {there were none large enough} - large_attempt:=true; z:=large_fam(d); x:=large_char(d); - end; -found: if f<>null_font then - @ -else begin b:=new_null_box; - width(b):=null_delimiter_space; {use this width if no delimiter was found} - end; -z:=cur_size; cur_size:=s; -shift_amount(b):=half(height(b)-depth(b)) - axis_height(cur_size); -cur_size:=z; -var_delimiter:=b; -end; - -@ The search process is complicated slightly by the facts that some of the -characters might not be present in some of the fonts, and they might not -be probed in increasing order of height. - -@= -if (z<>0)or(x<>min_quarterword) then - begin z:=z+s+script_size; - repeat z:=z-script_size; g:=fam_fnt(z); - if g<>null_font then - @; - until z= -begin y:=x; -if (y>=font_bc(g))and(y<=font_ec(g)) then - begin continue: - if char_exists(g,y) then - begin if char_tag(g,y)=ext_tag then - begin f:=g; c:=y; goto found; - end; - u:=char_height(g,y)+char_depth(g,y); - if u>w then - begin f:=g; c:=y; w:=u; - if u>=v then goto found; - end; - if char_tag(g,y)=list_tag then - begin y:=char_remainder(g,y); goto continue; - end; - end; - end; -end - -@ Here is a subroutine that creates a new box, whose list contains a -single character, and whose width includes the italic correction for -that character. The height or depth of the box will be negative, if -the height or depth of the character is negative; thus, this routine -may deliver a slightly different result than |hpack| would produce. - -@= -function char_box(@!f:internal_font_number;@!c:quarterword):pointer; -var @!b,@!p:pointer; {the new box and its character node} -begin -b:=new_null_box; ci:=char_info_short(f,c); -width(b):=charinfo_width(ci)+char_italic(f,c); -height(b):=charinfo_height(ci); depth(b):=charinfo_depth(ci); -p:=new_char(f,c); list_ptr(b):=p; char_box:=b; -end; - -@ When the following code is executed, |char_tag(q)| will be equal to -|ext_tag| if and only if a built-up symbol is supposed to be returned. - -@= -if char_tag(f,c)=ext_tag then - @ -else b:=char_box(f,c) - -@ When we build an extensible character, it's handy to have the -following subroutine, which puts a given character on top -of the characters already in box |b|: - -@= -procedure stack_into_box(@!b:pointer;@!f:internal_font_number; - @!c:quarterword); -var p:pointer; {new node placed into |b|} -begin p:=char_box(f,c); vlink(p):=list_ptr(b); list_ptr(b):=p; -height(b):=height(p); -end; - -@ Another handy subroutine computes the height plus depth of -a given character: - -@= -function height_plus_depth(@!f:internal_font_number;@!c:quarterword):scaled; -begin -height_plus_depth:=char_height(f,c)+char_depth(f,c); -end; - -@ @= -begin b:=new_null_box; -type(b):=vlist_node; -@; -cc:=ext_bot(f,c); -if cc<>min_quarterword then stack_into_box(b,f,cc); -cc:=ext_rep(f,c); -for m:=1 to n do stack_into_box(b,f,cc); -cc:=ext_mid(f,c); -if cc<>min_quarterword then - begin stack_into_box(b,f,cc); cc:=ext_rep(f,c); - for m:=1 to n do stack_into_box(b,f,cc); - end; -cc:=ext_top(f,c); -if cc<>min_quarterword then stack_into_box(b,f,cc); -depth(b):=w-height(b); -end - -@ The width of an extensible character is the width of the repeatable -module. If this module does not have positive height plus depth, -we don't use any copies of it, otherwise we use as few as possible -(in groups of two if there is a middle part). - -@= -cc:=ext_rep(f,c); u:=height_plus_depth(f,cc); -w:=0; width(b):=char_width(f,cc)+char_italic(f,cc);@/ -cc:=ext_bot(f,c);@+if cc<>min_quarterword then w:=w+height_plus_depth(f,cc); -cc:=ext_mid(f,c);@+if cc<>min_quarterword then w:=w+height_plus_depth(f,cc); -cc:=ext_top(f,c);@+if cc<>min_quarterword then w:=w+height_plus_depth(f,cc); -n:=0; -if u>0 then while wmin_quarterword then w:=w+u; - end - -@ The next subroutine is much simpler; it is used for numerators and -denominators of fractions as well as for displayed operators and -their limits above and below. It takes a given box~|b| and -changes it so that the new box is centered in a box of width~|w|. -The centering is done by putting \.{\\hss} glue at the left and right -of the list inside |b|, then packaging the new box; thus, the -actual box might not really be centered, if it already contains -infinite glue. - -The given box might contain a single character whose italic correction -has been added to the width of the box; in this case a compensating -kern is inserted. - -@p function rebox(@!b:pointer;@!w:scaled):pointer; -var p,q:pointer; {temporary registers for list manipulation} -@!f:internal_font_number; {font in a one-character box} -@!v:scaled; {width of a character without italic correction} -begin if (width(b)<>w)and(list_ptr(b)<>null) then - begin if type(b)=vlist_node then b:=hpack(b,natural); - p:=list_ptr(b); - if (is_char_node(p))and(vlink(p)=null) then - begin f:=font(p); v:=char_width(f,character(p)); - if v<>width(b) then begin - q:=new_kern(width(b)-v); vlink(p):=q; - end; - end; - list_ptr(b):=null; flush_node(b); - b:=new_glue(ss_glue); vlink(b):=p; - while vlink(p)<>null do p:=vlink(p); - q:=new_glue(ss_glue); vlink(p):=q; - rebox:=hpack(b,w,exactly); - end -else begin width(b):=w; rebox:=b; - end; -end; - -@ Here is a subroutine that creates a new glue specification from another -one that is expressed in `\.{mu}', given the value of the math unit. - -@d mu_mult(#)==nx_plus_y(n,#,xn_over_d(#,f,@'200000)) - -@p function math_glue(@!g:pointer;@!m:scaled):pointer; -var p:pointer; {the new glue specification} -@!n:integer; {integer part of |m|} -@!f:scaled; {fraction part of |m|} -begin n:=x_over_n(m,@'200000); f:=remainder;@/ -if f<0 then - begin decr(n); f:=f+@'200000; - end; -p:=new_node(glue_spec_node,0); -width(p):=mu_mult(width(g)); {convert \.{mu} to \.{pt}} -stretch_order(p):=stretch_order(g); -if stretch_order(p)=normal then stretch(p):=mu_mult(stretch(g)) -else stretch(p):=stretch(g); -shrink_order(p):=shrink_order(g); -if shrink_order(p)=normal then shrink(p):=mu_mult(shrink(g)) -else shrink(p):=shrink(g); -math_glue:=p; -end; - -@ The |math_kern| subroutine removes |mu_glue| from a kern node, given -the value of the math unit. - -@p procedure math_kern(@!p:pointer;@!m:scaled); -var @!n:integer; {integer part of |m|} -@!f:scaled; {fraction part of |m|} -begin if subtype(p)=mu_glue then - begin n:=x_over_n(m,@'200000); f:=remainder;@/ - if f<0 then - begin decr(n); f:=f+@'200000; - end; - width(p):=mu_mult(width(p)); subtype(p):=explicit; - end; -end; - -@ Sometimes it is necessary to destroy an mlist. The following -subroutine empties the current list, assuming that |abs(mode)=mmode|. - -@p procedure flush_math; -begin flush_node_list(vlink(head)); flush_node_list(incompleat_noad); -vlink(head):=null; tail:=head; incompleat_noad:=null; -end; - -@* \[36] Typesetting math formulas. -\TeX's most important routine for dealing with formulas is called -|mlist_to_hlist|. After a formula has been scanned and represented as an -mlist, this routine converts it to an hlist that can be placed into a box -or incorporated into the text of a paragraph. There are three implicit -parameters, passed in global variables: |cur_mlist| points to the first -node or noad in the given mlist (and it might be |null|); |cur_style| is a -style code; and |mlist_penalties| is |true| if penalty nodes for potential -line breaks are to be inserted into the resulting hlist. After -|mlist_to_hlist| has acted, |vlink(temp_head)| points to the translated hlist. - -Since mlists can be inside mlists, the procedure is recursive. And since this -is not part of \TeX's inner loop, the program has been written in a manner -that stresses compactness over efficiency. -@^recursion@> - -@= -@!cur_mlist:pointer; {beginning of mlist to be translated} -@!cur_style:integer; {style code at current place in the list} -@!cur_size:integer; {size code corresponding to |cur_style|} -@!cur_mu:scaled; {the math unit width corresponding to |cur_size|} -@!mlist_penalties:boolean; {should |mlist_to_hlist| insert penalties?} - -@ The recursion in |mlist_to_hlist| is due primarily to a subroutine -called |clean_box| that puts a given noad field into a box using a given -math style; |mlist_to_hlist| can call |clean_box|, which can call -|mlist_to_hlist|. -@^recursion@> - -The box returned by |clean_box| is ``clean'' in the -sense that its |shift_amount| is zero. - -@p procedure@?mlist_to_hlist; forward;@t\2@>@/ -function clean_box(@!p:pointer;@!s:integer):pointer; -label found; -var q:pointer; {beginning of a list to be boxed} -@!save_style:integer; {|cur_style| to be restored} -@!x:pointer; {box to be returned} -@!r:pointer; {temporary pointer} -begin -case math_type(p) of -math_char: begin cur_mlist:=new_noad; vmem(nucleus(cur_mlist)):=vmem(p); - end; -sub_box: begin q:=vinfo(p); goto found; - end; -sub_mlist: cur_mlist:=vinfo(p); -othercases begin q:=new_null_box; goto found; - end -endcases;@/ -save_style:=cur_style; cur_style:=s; mlist_penalties:=false;@/ -mlist_to_hlist; q:=vlink(temp_head); {recursive call} -cur_style:=save_style; {restore the style} -@; -found: if is_char_node(q)or(q=null) then x:=hpack(q,natural) - else if (vlink(q)=null)and(type(q)<=vlist_node)and(shift_amount(q)=0) then - x:=q {it's already clean} - else x:=hpack(q,natural); -@; -clean_box:=x; -end; - -@ Here we save memory space in a common case. - -@= -q:=list_ptr(x); -if is_char_node(q) then - begin r:=vlink(q); - if r<>null then if vlink(r)=null then if not is_char_node(r) then - if type(r)=kern_node then {unneeded italic correction} - begin flush_node(r); vlink(q):=null; - end; - end - -@ It is convenient to have a procedure that converts a |math_char| -field to an ``unpacked'' form. The |fetch| routine sets |cur_f| and |cur_c| -to the font code and character code of a given noad field. -It also takes care of issuing error messages for -nonexistent characters; in such cases, |char_exists(cur_f,cur_c)| will be |false| -after |fetch| has acted, and the field will also have been reset to |empty|. - -@p procedure fetch(@!a:pointer); {unpack the |math_char| field |a|} -begin cur_c:=mcharacter(a); cur_f:=fam_fnt(fam(a)+cur_size); -if cur_f=null_font then - @ -else begin - if not(char_exists(cur_f,cur_c)) then - begin char_warning(cur_f,qo(cur_c)); - math_type(a):=empty; - end; - end; -end; - -@ @= -begin print_err(""); print_size(cur_size); print_char(" "); -print_int(fam(a)); print(" is undefined (character "); -print(qo(cur_c)); print_char(")"); -help4("Somewhere in the math formula just ended, you used the")@/ -("stated character from an undefined font family. For example,")@/ -("plain TeX doesn't allow \it or \sl in subscripts. Proceed,")@/ -("and I'll try to forget that I needed that character."); -error; math_type(a):=empty; -end - -@ The outputs of |fetch| are placed in global variables. - -@= -@!cur_f:internal_font_number; {the |font| field of a |math_char|} -@!cur_c:quarterword; {the |character| field of a |math_char|} - -@ We need to do a lot of different things, so |mlist_to_hlist| makes two -passes over the given mlist. - -The first pass does most of the processing: It removes ``mu'' spacing from -glue, it recursively evaluates all subsidiary mlists so that only the -top-level mlist remains to be handled, it puts fractions and square roots -and such things into boxes, it attaches subscripts and superscripts, and -it computes the overall height and depth of the top-level mlist so that -the size of delimiters for a |left_noad| and a |right_noad| will be known. -The hlist resulting from each noad is recorded in that noad's |new_hlist| -field, an integer field that replaces the |nucleus| or |thickness|. -@^recursion@> - -The second pass eliminates all noads and inserts the correct glue and -penalties between nodes. - -@d new_hlist(#)==vmem(nucleus(#)).int {the translation of an mlist} - -@ Here is the overall plan of |mlist_to_hlist|, and the list of its -local variables. - -@d done_with_noad=80 {go here when a noad has been fully translated} -@d done_with_node=81 {go here when a node has been fully converted} -@d check_dimensions=82 {go here to update |max_h| and |max_d|} -@d delete_q=83 {go here to delete |q| and move to the next node} - -@p@t\4@>@ -procedure mlist_to_hlist; -label reswitch, check_dimensions, done_with_noad, done_with_node, delete_q, - done; -var mlist:pointer; {beginning of the given list} -@!penalties:boolean; {should penalty nodes be inserted?} -@!style:integer; {the given style} -@!save_style:integer; {holds |cur_style| during recursion} -@!q:pointer; {runs through the mlist} -@!r:pointer; {the most recent noad preceding |q|} -@!r_type:integer; {the |type| of noad |r|, or |op_noad| if |r=null|} -@!t:integer; {the effective |type| of noad |q| during the second pass} -@!p,@!x,@!y,@!z: pointer; {temporary registers for list construction} -@!pen:integer; {a penalty to be inserted} -@!s:integer; {the size of a noad to be deleted} -@!max_hl,@!max_d:scaled; {maximum height and depth of the list translated so far} -@!delta:scaled; {offset between subscript and superscript} -begin mlist:=cur_mlist; penalties:=mlist_penalties; -style:=cur_style; {tuck global parameters away as local variables} -q:=mlist; r:=null; r_type:=op_noad; max_hl:=0; max_d:=0; x:=null; p:=null; -@; -while q<>null do @; -@; -@; -end; - -@ We use the fact that no character nodes appear in an mlist, hence -the field |type(q)| is always present. - -@= -begin @; -check_dimensions: z:=hpack(new_hlist(q),natural); -if height(z)>max_hl then max_hl:=height(z); -if depth(z)>max_d then max_d:=depth(z); -list_ptr(z):=null; flush_node(z); -done_with_noad: r:=q; r_type:=type(r); -if r_type=right_noad then - begin r_type:=left_noad; cur_style:=style; @; - end; -done_with_node: q:=vlink(q); -end - -@ One of the things we must do on the first pass is change a |bin_noad| to -an |ord_noad| if the |bin_noad| is not in the context of a binary operator. -The values of |r| and |r_type| make this fairly easy. - -@= -reswitch: delta:=0; -case type(q) of -bin_noad: case r_type of - bin_noad,op_noad,rel_noad,open_noad,punct_noad,left_noad: - begin type(q):=ord_noad; goto reswitch; - end; - othercases do_nothing - endcases; -rel_noad,close_noad,punct_noad,right_noad: begin@t@>@;@/ - @; - if type(q)=right_noad then goto done_with_noad; - end; -@t\4@>@@; -@t\4@>@@; -othercases confusion("mlist1") -@:this can't happen mlist1}{\quad mlist1@> -endcases;@/ -@ - -@ @= -if r_type=bin_noad then type(r):=ord_noad - -@ @= -style_node: begin cur_style:=subtype(q); - @; - goto done_with_node; - end; -choice_node: @; -ins_node,mark_node,adjust_node, - whatsit_node,penalty_node,disc_node: goto done_with_node; -rule_node: begin if height(q)>max_hl then max_hl:=height(q); - if depth(q)>max_d then max_d:=depth(q); goto done_with_node; - end; -glue_node: begin @; - goto done_with_node; - end; -kern_node: begin math_kern(q,cur_mu); goto done_with_node; - end; - -@ @d choose_mlist(#)==begin p:=#(q); #(q):=null;@+end - -@= -begin case cur_style div 2 of -0: choose_mlist(display_mlist); {|display_style=0|} -1: choose_mlist(text_mlist); {|text_style=2|} -2: choose_mlist(script_mlist); {|script_style=4|} -3: choose_mlist(script_script_mlist); {|script_script_style=6|} -end; {there are no other cases} -flush_node_list(display_mlist(q)); -flush_node_list(text_mlist(q)); -flush_node_list(script_mlist(q)); -flush_node_list(script_script_mlist(q));@/ -type(q):=style_node; subtype(q):=cur_style; width(q):=0; depth(q):=0; -if p<>null then - begin z:=vlink(q); vlink(q):=p; - while vlink(p)<>null do p:=vlink(p); - vlink(p):=z; - end; -goto done_with_node; -end - -@ Conditional math glue (`\.{\\nonscript}') results in a |glue_node| -pointing to |zero_glue|, with |subtype(q)=cond_math_glue|; in such a case -the node following will be eliminated if it is a glue or kern node and if the -current size is different from |text_size|. Unconditional math glue -(`\.{\\muskip}') is converted to normal glue by multiplying the dimensions -by |cur_mu|. -@!@:non_script_}{\.{\\nonscript} primitive@> - -@= -if subtype(q)=mu_glue then - begin x:=glue_ptr(q); - y:=math_glue(x,cur_mu); delete_glue_ref(x); glue_ptr(q):=y; - subtype(q):=normal; - end -else if (cur_size<>text_size)and(subtype(q)=cond_math_glue) then - begin p:=vlink(q); - if p<>null then if (type(p)=glue_node)or(type(p)=kern_node) then - begin vlink(q):=vlink(p); vlink(p):=null; flush_node_list(p); - end; - end - -@ @= -left_noad: goto done_with_noad; -fraction_noad: begin make_fraction(q); goto check_dimensions; - end; -op_noad: begin delta:=make_op(q); - if subtype(q)=limits then goto check_dimensions; - end; -ord_noad: make_ord(q); -open_noad,inner_noad: do_nothing; -radical_noad: make_radical(q); -over_noad: make_over(q); -under_noad: make_under(q); -accent_noad: make_math_accent(q); -vcenter_noad: make_vcenter(q); - -@ Most of the actual construction work of |mlist_to_hlist| is done -by procedures with names -like |make_fraction|, |make_radical|, etc. To illustrate -the general setup of such procedures, let's begin with a couple of -simple ones. - -@= -procedure make_over(@!q:pointer); -var p:pointer; -begin p:=overbar(clean_box(nucleus(q),cramped_style(cur_style)),@| - 3*default_rule_thickness,default_rule_thickness); -vinfo(nucleus(q)):=p; -math_type(nucleus(q)):=sub_box; -end; - -@ @= -procedure make_under(@!q:pointer); -var p,@!x,@!y,@!r: pointer; {temporary registers for box construction} -@!delta:scaled; {overall height plus depth} -begin x:=clean_box(nucleus(q),cur_style); -p:=new_kern(3*default_rule_thickness); vlink(x):=p; -r:=fraction_rule(default_rule_thickness); vlink(p):=r; -pack_direction:=math_direction; y:=vpack(x,natural); -delta:=height(y)+depth(y)+default_rule_thickness; -height(y):=height(x); depth(y):=delta-height(y); -vinfo(nucleus(q)):=y; math_type(nucleus(q)):=sub_box; -end; - -@ @= -procedure make_vcenter(@!q:pointer); -var v:pointer; {the box that should be centered vertically} -@!delta:scaled; {its height plus depth} -begin v:=vinfo(nucleus(q)); -if type(v)<>vlist_node then confusion("vcenter"); -@:this can't happen vcenter}{\quad vcenter@> -delta:=height(v)+depth(v); -height(v):=axis_height(cur_size)+half(delta); -depth(v):=delta-height(v); -end; - -@ According to the rules in the \.{DVI} file specifications, we ensure alignment -@^square roots@> -between a square root sign and the rule above its nucleus by assuming that the -baseline of the square-root symbol is the same as the bottom of the rule. The -height of the square-root symbol will be the thickness of the rule, and the -depth of the square-root symbol should exceed or equal the height-plus-depth -of the nucleus plus a certain minimum clearance~|clr|. The symbol will be -placed so that the actual clearance is |clr| plus half the excess. - -@= -procedure make_radical(@!q:pointer); -var x,@!y,@!p:pointer; {temporary registers for box construction} -@!delta,@!clr:scaled; {dimensions involved in the calculation} -begin x:=clean_box(nucleus(q),cramped_style(cur_style)); -if cur_style0 then clr:=clr+half(delta); {increase the actual clearance} -shift_amount(y):=-(height(x)+clr); -p:=overbar(x,clr,height(y)); vlink(y):=p; -p:=hpack(y,natural); vinfo(nucleus(q)):=p; -math_type(nucleus(q)):=sub_box; -end; - -@ Slants are not considered when placing accents in math mode. The accenter is -centered over the accentee, and the accent width is treated as zero with -respect to the size of the final box. - -@= -procedure make_math_accent(@!q:pointer); -label done; -var p,@!x,@!y:pointer; {temporary registers for box construction} -@!c:quarterword; {accent character} -@!f:internal_font_number; {its font} -@!s:scaled; {amount to skew the accent to the right} -@!h:scaled; {height of character being accented} -@!delta:scaled; {space to remove between accent and accentee} -@!w:scaled; {width of the accentee, not including sub/superscripts} -begin fetch(accent_chr(q)); -if char_exists(cur_f,cur_c) then - begin c:=cur_c; f:=cur_f;@/ - @; - x:=clean_box(nucleus(q),cramped_style(cur_style)); w:=width(x); h:=height(x); - @; - if hempty)or(math_type(subscr(q))<>empty) then - if math_type(nucleus(q))=math_char then - @; - y:=char_box(f,c); - shift_amount(y):=s+half(w-width(y)); - width(y):=0; p:=new_kern(-delta); vlink(p):=x; vlink(y):=p; - pack_direction:=math_direction; - y:=vpack(y,natural); width(y):=width(x); - if height(y); - vinfo(nucleus(q)):=y; - math_type(nucleus(q)):=sub_box; - end; -end; - -@ @= -begin p:=new_kern(h-height(y)); vlink(p):=list_ptr(y); list_ptr(y):=p; -height(y):=h; -end - -@ @= -loop@+ begin if char_tag(f,c)<>list_tag then goto done; - y:=char_remainder(f,c); - if not char_exists(f,y) then goto done; - if char_width(f,y)>w then goto done; - c:=y; - end; -done: - -@ @= -s:=0; -if math_type(nucleus(q))=math_char then - begin fetch(nucleus(q)); - s := get_kern(cur_f,cur_c,skew_char(cur_f)); - end - -@ @= -begin flush_node_list(x); x:=new_noad; -vmem(nucleus(x)):=vmem(nucleus(q)); -vmem(supscr(x)):=vmem(supscr(q)); -vmem(subscr(x)):=vmem(subscr(q));@/ -vmem(supscr(q)).hh:=empty_field; -vmem(subscr(q)).hh:=empty_field;@/ -math_type(nucleus(q)):=sub_mlist; vinfo(nucleus(q)):=x; -x:=clean_box(nucleus(q),cur_style); delta:=delta+height(x)-h; h:=height(x); -end - -@ The |make_fraction| procedure is a bit different because it sets -|new_hlist(q)| directly rather than making a sub-box. - -@= -procedure make_fraction(@!q:pointer); -var p,@!v,@!x,@!y,@!z:pointer; {temporary registers for box construction} -@!delta,@!delta1,@!delta2,@!shift_up,@!shift_down,@!clr:scaled; - {dimensions for box calculations} -begin if thickness(q)=default_code then thickness(q):=default_rule_thickness; -@; -if thickness(q)=0 then @ -else @; -@; -@; -end; - -@ @= -x:=clean_box(numerator(q),num_style(cur_style)); -z:=clean_box(denominator(q),denom_style(cur_style)); -vinfo(numerator(q)):=null; -vinfo(denominator(q)):=null; -if width(x)0 then shift_up:=num2(cur_size) - else shift_up:=num3(cur_size); - end - -@ The numerator and denominator must be separated by a certain minimum -clearance, called |clr| in the following program. The difference between -|clr| and the actual clearance is |2delta|. - -@= -begin if cur_style0 then - begin shift_up:=shift_up+delta; - shift_down:=shift_down+delta; - end; -end - -@ In the case of a fraction line, the minimum clearance depends on the actual -thickness of the line. - -@= -begin if cur_style0 then shift_up:=shift_up+delta1; -if delta2>0 then shift_down:=shift_down+delta2; -end - -@ @= -v:=new_null_box; type(v):=vlist_node; -height(v):=shift_up+height(x); depth(v):=depth(z)+shift_down; -width(v):=width(x); {this also equals |width(z)|} -if thickness(q)=0 then - begin p:=new_kern((shift_up-depth(x))-(height(z)-shift_down)); - vlink(p):=z; - end -else begin y:=fraction_rule(thickness(q));@/ - p:=new_kern((axis_height(cur_size)-delta)-@|(height(z)-shift_down));@/ - vlink(y):=p; vlink(p):=z;@/ - p:=new_kern((shift_up-depth(x))-(axis_height(cur_size)+delta)); - vlink(p):=y; - end; -vlink(x):=p; list_ptr(v):=x - -@ @= -if cur_style= -function make_op(@!q:pointer):scaled; -var delta:scaled; {offset between subscript and superscript} -@!p,@!v,@!x,@!y,@!z:pointer; {temporary registers for box construction} -@!c:quarterword; {register for character examination} -@!shift_up,@!shift_down:scaled; {dimensions for box calculation} -begin if (subtype(q)=normal)and(cur_styleempty)and(subtype(q)<>limits) then - width(x):=width(x)-delta; {remove italic correction} - shift_amount(x):=half(height(x)-depth(x)) - axis_height(cur_size); - {center vertically} - math_type(nucleus(q)):=sub_box; vinfo(nucleus(q)):=x; - end -else delta:=0; -if subtype(q)=limits then - @; -make_op:=delta; -end; - -@ The following program builds a vlist box |v| for displayed limits. The -width of the box is not affected by the fact that the limits may be skewed. - -@= -begin x:=clean_box(supscr(q),sup_style(cur_style)); -y:=clean_box(nucleus(q),cur_style); -z:=clean_box(subscr(q),sub_style(cur_style)); -v:=new_null_box; type(v):=vlist_node; width(v):=width(y); -if width(x)>width(v) then width(v):=width(x); -if width(z)>width(v) then width(v):=width(z); -x:=rebox(x,width(v)); y:=rebox(y,width(v)); z:=rebox(z,width(v));@/ -shift_amount(x):=half(delta); shift_amount(z):=-shift_amount(x); -height(v):=height(y); depth(v):=depth(y); -@; -new_hlist(q):=v; -end - -@ We use |shift_up| and |shift_down| in the following program for the -amount of glue between the displayed operator |y| and its limits |x| and -|z|. The vlist inside box |v| will consist of |x| followed by |y| followed -by |z|, with kern nodes for the spaces between and around them. - -@= -if math_type(supscr(q))=empty then - begin list_ptr(x):=null; flush_node(x); list_ptr(v):=y; - end -else begin shift_up:=big_op_spacing3-depth(x); - if shift_up= -procedure make_ord(@!q:pointer); -label restart,exit; -var a:integer; { the left-side character for lig/kern testing } -@!p,@!r:pointer; {temporary registers for list manipulation} -k:scaled; { a kern } -lig:liginfo; { a ligature } -begin restart:@t@>@;@/ -if math_type(subscr(q))=empty then if math_type(supscr(q))=empty then - if math_type(nucleus(q))=math_char then - begin p:=vlink(q); - if p<>null then if (type(p)>=ord_noad)and(type(p)<=punct_noad) then - if math_type(nucleus(p))=math_char then - if fam(nucleus(p))=fam(nucleus(q)) then - begin math_type(nucleus(q)):=math_text_char; - fetch(nucleus(q)); a:=cur_c; - if (has_kern(cur_f,a))or(has_lig(cur_f,a)) then - begin cur_c:=mcharacter(nucleus(p)); - @; - end; - end; - end; -exit:end; - -@ Note that a ligature between an |ord_noad| and another kind of noad -is replaced by an |ord_noad|, when the two noads collapse into one. -But we could make a parenthesis (say) change shape when it follows -certain letters. Presumably a font designer will define such -ligatures only when this convention makes sense. - -\chardef\?='174 % vertical line to indicate character retention - -@= -begin -if disable_lig=0 and has_lig(cur_f,a) then begin - lig:=get_ligature(cur_f,a,cur_c); - if is_valid_ligature(lig) then begin - check_interrupt; {allow a way out of infinite ligature loop} - case lig_type(lig) of - qi(1),qi(5): mcharacter(nucleus(q)):=lig_replacement(lig); {\.{=:\?}, \.{=:\?>}} - qi(2),qi(6): mcharacter(nucleus(p)):=lig_replacement(lig); {\.{\?=:}, \.{\?=:>}} - qi(3),qi(7),qi(11):begin r:=new_noad; {\.{\?=:\?}, \.{\?=:\?>}, \.{\?=:\?>>}} - mcharacter(nucleus(r)):=lig_replacement(lig); - fam(nucleus(r)):=fam(nucleus(q));@/ - vlink(q):=r; vlink(r):=p; - if lig_type(lig)qi(3) then return; - math_type(nucleus(q)):=math_char; goto restart; - end; - end; -if disable_kern=0 and has_kern(cur_f,a) then begin - k:=get_kern(cur_f,a,cur_c); - if k<>0 then begin - p:=new_kern(k); vlink(p):=vlink(q); vlink(q):=p; return; - end; - end; -end - -@ When we get to the following part of the program, we have ``fallen through'' -from cases that did not lead to |check_dimensions| or |done_with_noad| or -|done_with_node|. Thus, |q|~points to a noad whose nucleus may need to be -converted to an hlist, and whose subscripts and superscripts need to be -appended if they are present. - -If |nucleus(q)| is not a |math_char|, the variable |delta| is the amount -by which a superscript should be moved right with respect to a subscript -when both are present. -@^subscripts@> -@^superscripts@> - -@= -case math_type(nucleus(q)) of -math_char, math_text_char: - @; -empty: p:=null; -sub_box: p:=vinfo(nucleus(q)); -sub_mlist: begin cur_mlist:=vinfo(nucleus(q)); save_style:=cur_style; - mlist_penalties:=false; mlist_to_hlist; {recursive call} -@^recursion@> - cur_style:=save_style; @; - p:=hpack(vlink(temp_head),natural); - end; -othercases confusion("mlist2") -@:this can't happen mlist2}{\quad mlist2@> -endcases;@/ -new_hlist(q):=p; -if (math_type(subscr(q))=empty)and(math_type(supscr(q))=empty) then - goto check_dimensions; -make_scripts(q,delta) - -@ @= -begin fetch(nucleus(q)); -if char_exists(cur_f,cur_c) then - begin delta:=char_italic(cur_f,cur_c); p:=new_glyph(cur_f,cur_c); - if (math_type(nucleus(q))=math_text_char)and(space(cur_f)<>0) then - delta:=0; {no italic correction in mid-word of text font} - if (math_type(subscr(q))=empty)and(delta<>0) then - begin x:=new_kern(delta); vlink(p):=x; delta:=0; - end; - end -else p:=null; -end - -@ The purpose of |make_scripts(q,delta)| is to attach the subscript and/or -superscript of noad |q| to the list that starts at |new_hlist(q)|, -given that subscript and superscript aren't both empty. The superscript -will appear to the right of the subscript by a given distance |delta|. - -We set |shift_down| and |shift_up| to the minimum amounts to shift the -baseline of subscripts and superscripts based on the given nucleus. - -@= -procedure make_scripts(@!q:pointer;@!delta:scaled); -var p,@!x,@!y,@!z:pointer; {temporary registers for box construction} -@!shift_up,@!shift_down,@!clr:scaled; {dimensions in the calculation} -@!t:integer; {subsidiary size code} -begin p:=new_hlist(q); -if is_char_node(p) then - begin shift_up:=0; shift_down:=0; - end -else begin z:=hpack(p,natural); - t:=cur_size; - if cur_style -else begin @; - if math_type(subscr(q))=empty then shift_amount(x):=-shift_up - else @; - end; -if new_hlist(q)=null then new_hlist(q):=x -else begin p:=new_hlist(q); - while vlink(p)<>null do p:=vlink(p); - vlink(p):=x; - end; -end; - -@ When there is a subscript without a superscript, the top of the subscript -should not exceed the baseline plus four-fifths of the x-height. - -@= -begin x:=clean_box(subscr(q),sub_style(cur_style)); -width(x):=width(x)+script_space; -if shift_down= -begin x:=clean_box(supscr(q),sup_style(cur_style)); -width(x):=width(x)+script_space; -if odd(cur_style) then clr:=sup3(cur_size) -else if cur_style= -begin y:=clean_box(subscr(q),sub_style(cur_style)); -width(y):=width(y)+script_space; -if shift_down0 then - begin shift_down:=shift_down+clr; - clr:=(abs(math_x_height(cur_size)*4) div 5)-(shift_up-depth(x)); - if clr>0 then - begin shift_up:=shift_up+clr; - shift_down:=shift_down-clr; - end; - end; -shift_amount(x):=delta; {superscript is |delta| to the right of the subscript} -p:=new_kern((shift_up-depth(x))-(height(y)-shift_down)); vlink(x):=p; vlink(p):=y; -pack_direction:=math_direction; -x:=vpack(x,natural); shift_amount(x):=shift_down; -end - -@ We have now tied up all the loose ends of the first pass of |mlist_to_hlist|. -The second pass simply goes through and hooks everything together with the -proper glue and penalties. It also handles the |left_noad| and |right_noad| that -might be present, since |max_hl| and |max_d| are now known. Variable |p| points -to a node at the current end of the final hlist. - -@= -p:=temp_head; vlink(p):=null; q:=mlist; r_type:=0; cur_style:=style; -@; -while q<>null do - begin @; - @; - @; - if type(q)=right_noad then t:=open_noad; - r_type:=t; - delete_q: r:=q; q:=vlink(q); - flush_node(r); {|r| had better be a noad-like thing } - done: end - -@ Just before doing the big |case| switch in the second pass, the program -sets up default values so that most of the branches are short. - -@= -t:=ord_noad; s:=noad_size; pen:=inf_penalty; -case type(q) of -op_noad,open_noad,close_noad,punct_noad,inner_noad: t:=type(q); -bin_noad: begin t:=bin_noad; pen:=bin_op_penalty; - end; -rel_noad: begin t:=rel_noad; pen:=rel_penalty; - end; -ord_noad,vcenter_noad,over_noad,under_noad: do_nothing; -radical_noad: s:=radical_noad_size; -accent_noad: s:=accent_noad_size; -fraction_noad: begin t:=inner_noad; s:=fraction_noad_size; - end; -left_noad,right_noad: t:=make_left_right(q,style,max_d,max_hl); -style_node: @; -whatsit_node,penalty_node,rule_node,disc_node,adjust_node,ins_node,mark_node, - glue_node,kern_node:@t@>@;@/ - begin vlink(p):=q; p:=q; q:=vlink(q); vlink(p):=null; goto done; - end; -othercases confusion("mlist3") -@:this can't happen mlist3}{\quad mlist3@> -endcases - -@ The |make_left_right| function constructs a left or right delimiter of -the required size and returns the value |open_noad| or |close_noad|. The -|right_noad| and |left_noad| will both be based on the original |style|, -so they will have consistent sizes. - -We use the fact that |right_noad-left_noad=close_noad-open_noad|. - -@= -function make_left_right(@!q:pointer;@!style:integer; - @!max_d,@!max_hv:scaled):small_number; -var delta,@!delta1,@!delta2:scaled; {dimensions used in the calculation} -tmp:pointer; -begin cur_style:=style; @; -delta2:=max_d+axis_height(cur_size); -delta1:=max_hv+max_d-delta2; -if delta2>delta1 then delta1:=delta2; {|delta1| is max distance from axis} -delta:=(delta1 div 500)*delimiter_factor; -delta2:=delta1+delta1-delimiter_shortfall; -if delta= -begin cur_style:=subtype(q); s:=style_node_size; -@; -goto delete_q; -end - -@ The inter-element spacing in math formulas depends on a $8\times8$ table that -\TeX\ preloads as a 64-digit string. The elements of this string have the -following significance: -$$\vbox{\halign{#\hfil\cr -\.0 means no space;\cr -\.1 means a conditional thin space (\.{\\nonscript\\mskip\\thinmuskip});\cr -\.2 means a thin space (\.{\\mskip\\thinmuskip});\cr -\.3 means a conditional medium space - (\.{\\nonscript\\mskip\\medmuskip});\cr -\.4 means a conditional thick space - (\.{\\nonscript\\mskip\\thickmuskip});\cr -\.* means an impossible case.\cr}}$$ -This is all pretty cryptic, but {\sl The \TeX book\/} explains what is -supposed to happen, and the string makes it happen. -@:TeXbook}{\sl The \TeX book@> - -A global variable |magic_offset| is computed so that if |a| and |b| are -in the range |ord_noad..inner_noad|, then |str_pool[a*8+b+magic_offset]| -is the digit for spacing between noad types |a| and |b|. - -If \PASCAL\ had provided a good way to preload constant arrays, this part of -the program would not have been so strange. -@:PASCAL}{\PASCAL@> - -@d math_spacing=@;@/ -@t\hskip-35pt@> -"0234000122*4000133**3**344*0400400*000000234000111*1111112341011" -@t$ \hskip-35pt$@> - -@= -@!magic_offset:integer; {used to find inter-element spacing} - -@ @= -magic_offset:=str_start_macro(math_spacing)-9*ord_noad - -@ @= -if r_type>0 then {not the first noad} - begin case so(str_pool[r_type*8+t+magic_offset]) of - "0": x:=0; - "1": if cur_style - endcases; - if x<>0 then - begin y:=math_glue(glue_par(x),cur_mu); - z:=new_glue(y); glue_ref_count(y):=null; vlink(p):=z; p:=z;@/ - subtype(z):=x+1; {store a symbolic subtype} - end; - end - -@ We insert a penalty node after the hlist entries of noad |q| if |pen| -is not an ``infinite'' penalty, and if the node immediately following |q| -is not a penalty node or a |rel_noad| or absent entirely. - -@= -if new_hlist(q)<>null then - begin vlink(p):=new_hlist(q); - repeat p:=vlink(p); - until vlink(p)=null; - end; -if penalties then if vlink(q)<>null then if penpenalty_node then if r_type<>rel_noad then - begin z:=new_penalty(pen); vlink(p):=z; p:=z; - end; - end - -@* \[37] Alignment. -It's sort of a miracle whenever \.{\\halign} and \.{\\valign} work, because -they cut across so many of the control structures of \TeX. - -Therefore the -present page is probably not the best place for a beginner to start reading -this program; it is better to master everything else first. - -Let us focus our thoughts on an example of what the input might be, in order -to get some idea about how the alignment miracle happens. The example doesn't -do anything useful, but it is sufficiently general to indicate all of the -special cases that must be dealt with; please do not be disturbed by its -apparent complexity and meaninglessness. -$$\vbox{\halign{\.{#}\hfil\cr -{}\\tabskip 2pt plus 3pt\cr -{}\\halign to 300pt\{u1\#v1\&\cr -\hskip 50pt\\tabskip 1pt plus 1fil u2\#v2\&\cr -\hskip 50pt u3\#v3\\cr\cr -\hskip 25pt a1\&\\omit a2\&\\vrule\\cr\cr -\hskip 25pt \\noalign\{\\vskip 3pt\}\cr -\hskip 25pt b1\\span b2\\cr\cr -\hskip 25pt \\omit\&c2\\span\\omit\\cr\}\cr}}$$ -Here's what happens: - -\yskip -(0) When `\.{\\halign to 300pt\{}' is scanned, the |scan_spec| routine -places the 300pt dimension onto the |save_stack|, and an |align_group| -code is placed above it. This will make it possible to complete the alignment -when the matching `\.\}' is found. - -(1) The preamble is scanned next. Macros in the preamble are not expanded, -@^preamble@> -except as part of a tabskip specification. For example, if \.{u2} had been -a macro in the preamble above, it would have been expanded, since \TeX\ -must look for `\.{minus...}' as part of the tabskip glue. A ``preamble list'' -is constructed based on the user's preamble; in our case it contains the -following seven items: -$$\vbox{\halign{\.{#}\hfil\qquad&(#)\hfil\cr -{}\\glue 2pt plus 3pt&the tabskip preceding column 1\cr -{}\\alignrecord, width $-\infty$&preamble info for column 1\cr -{}\\glue 2pt plus 3pt&the tabskip between columns 1 and 2\cr -{}\\alignrecord, width $-\infty$&preamble info for column 2\cr -{}\\glue 1pt plus 1fil&the tabskip between columns 2 and 3\cr -{}\\alignrecord, width $-\infty$&preamble info for column 3\cr -{}\\glue 1pt plus 1fil&the tabskip following column 3\cr}}$$ -These ``alignrecord'' entries have the same size as an |unset_node|, -since they will later be converted into such nodes. These alignrecord -nodes have no |depth| field; this is split into |u_part| and |v_part|, -and they point to token lists for the templates of the alignment. For -example, the |u_part| field in the first alignrecord points to the -token list `\.{u1}', i.e., the template preceding the `\.\#' for -column~1. Furthermore, They have a |span_ptr| instead of a |node_attr| -field, and these |span_ptr| fields are initially set to the value -|end_span|, for reasons explained below. - -(2) \TeX\ now looks at what follows the \.{\\cr} that ended the preamble. -It is not `\.{\\noalign}' or `\.{\\omit}', so this input is put back to -be read again, and the template `\.{u1}' is fed to the scanner. Just -before reading `\.{u1}', \TeX\ goes into restricted horizontal mode. -Just after reading `\.{u1}', \TeX\ will see `\.{a1}', and then (when the -{\.\&} is sensed) \TeX\ will see `\.{v1}'. Then \TeX\ scans an |endv| -token, indicating the end of a column. At this point an |unset_node| is -created, containing the contents of the current hlist (i.e., `\.{u1a1v1}'). -The natural width of this unset node replaces the |width| field of the -alignrecord for column~1; in general, the alignrecords will record the -maximum natural width that has occurred so far in a given column. - -(3) Since `\.{\\omit}' follows the `\.\&', the templates for column~2 -are now bypassed. Again \TeX\ goes into restricted horizontal mode and -makes an |unset_node| from the resulting hlist; but this time the -hlist contains simply `\.{a2}'. The natural width of the new unset box -is remembered in the |width| field of the alignrecord for column~2. - -(4) A third |unset_node| is created for column 3, using essentially the -mechanism that worked for column~1; this unset box contains `\.{u3\\vrule -v3}'. The vertical rule in this case has running dimensions that will later -extend to the height and depth of the whole first row, since each |unset_node| -in a row will eventually inherit the height and depth of its enclosing box. - -(5) The first row has now ended; it is made into a single unset box -comprising the following seven items: -$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr -{}\\glue 2pt plus 3pt\cr -{}\\unsetbox for 1 column: u1a1v1\cr -{}\\glue 2pt plus 3pt\cr -{}\\unsetbox for 1 column: a2\cr -{}\\glue 1pt plus 1fil\cr -{}\\unsetbox for 1 column: u3\\vrule v3\cr -{}\\glue 1pt plus 1fil\cr}}$$ -The width of this unset row is unimportant, but it has the correct height -and depth, so the correct baselineskip glue will be computed as the row -is inserted into a vertical list. - -(6) Since `\.{\\noalign}' follows the current \.{\\cr}, \TeX\ appends -additional material (in this case \.{\\vskip 3pt}) to the vertical list. -While processing this material, \TeX\ will be in internal vertical -mode, and |no_align_group| will be on |save_stack|. - -(7) The next row produces an unset box that looks like this: -$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr -{}\\glue 2pt plus 3pt\cr -{}\\unsetbox for 2 columns: u1b1v1u2b2v2\cr -{}\\glue 1pt plus 1fil\cr -{}\\unsetbox for 1 column: {\rm(empty)}\cr -{}\\glue 1pt plus 1fil\cr}}$$ -The natural width of the unset box that spans columns 1~and~2 is stored -in a ``span node,'' which we will explain later; the |span_ptr| field of the -alignrecord for column~1 now points to the new span node, and the |span_ptr| -of the span node points to |end_span|. - -(8) The final row produces the unset box -$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr -{}\\glue 2pt plus 3pt\cr -{}\\unsetbox for 1 column: {\rm(empty)}\cr -{}\\glue 2pt plus 3pt\cr -{}\\unsetbox for 2 columns: u2c2v2\cr -{}\\glue 1pt plus 1fil\cr}}$$ -A new span node is attached to the alignrecord for column 2. - -(9) The last step is to compute the true column widths and to change all the -unset boxes to hboxes, appending the whole works to the vertical list that -encloses the \.{\\halign}. The rules for deciding on the final widths of -each unset column box will be explained below. - -\yskip\noindent -Note that as \.{\\halign} is being processed, we fearlessly give up control -to the rest of \TeX. At critical junctures, an alignment routine is -called upon to step in and do some little action, but most of the time -these routines just lurk in the background. It's something like -post-hypnotic suggestion. +\yskip\noindent +Note that as \.{\\halign} is being processed, we fearlessly give up control +to the rest of \TeX. At critical junctures, an alignment routine is +called upon to step in and do some little action, but most of the time +these routines just lurk in the background. It's something like +post-hypnotic suggestion. @ We have mentioned that alignrecords contain no |height| or |depth| fields. Their |glue_sign| and |glue_order| are pre-empted as well, since it is necessary to store information about what to do when a template ends. This information is called the |extra_info| field. -@d align_record_node=34 @d u_part(#)==vlink(#+depth_offset) {pointer to \ token list} @d v_part(#)==vinfo(#+depth_offset) {pointer to \ token list} @d span_ptr(#)==vinfo(#+1) {column spanning list} @@ -22851,7 +19913,6 @@ when they have to be pushed down, they are stored in 6-word nodes, and |align_ptr| points to the topmost such node. @d preamble==vlink(align_head) {the current preamble list} -@d align_stack_node=47 @= @!cur_align:pointer; {current position in preamble list} @@ -23000,12 +20061,12 @@ as its command code. @d end_template_token==cs_token_flag+frozen_end_template @= -primitive("span",tab_mark,span_code);@/ +primitive_tex("span",tab_mark,span_code,span_code);@/ @!@:span_}{\.{\\span} primitive@> -primitive("cr",car_ret,cr_code); +primitive_tex("cr",car_ret,cr_code,cr_code); @!@:cr_}{\.{\\cr} primitive@> text(frozen_cr):="cr"; eqtb[frozen_cr]:=eqtb[cur_val];@/ -primitive("crcr",car_ret,cr_cr_code); +primitive_tex("crcr",car_ret,cr_cr_code,cr_code); @!@:cr_cr_}{\.{\\crcr} primitive@> text(frozen_end_template):="endtemplate"; text(frozen_endv):="endtemplate"; eq_type(frozen_endv):=endv; equiv(frozen_endv):=null_list; @@ -23013,12 +20074,6 @@ eq_level(frozen_endv):=level_one;@/ eqtb[frozen_end_template]:=eqtb[frozen_endv]; eq_type(frozen_end_template):=end_template; -@ @= -tab_mark: if chr_code=span_code then print_esc("span") - else chr_cmd("alignment tab character "); -car_ret: if chr_code=cr_code then print_esc("cr") - else print_esc("crcr"); - @ The preamble is copied directly, except that \.{\\tabskip} causes a change to the tabskip glue, thereby possibly expanding macros that immediately follow it. An appearance of \.{\\span} also causes such an expansion. @@ -23140,7 +20195,7 @@ entered, so that the columns will generate a list for subsequent packaging. procedure init_span(@!p:pointer); begin push_nest; if mode=-hmode then space_factor:=1000 -else begin prev_depth:=ignore_depth; normal_paragraph; +else begin prev_depth:=pdf_ignored_dimen; normal_paragraph; end; cur_span:=p; end; @@ -23295,8 +20350,6 @@ that column. The code has to make sure that there is room for The |new_span_node| function is defined in |texnodes.c|. -@d span_node==41 -@d span_node_size==3 {number of |mem| words for a span node} @d span_span(#)==vlink(#+1) {that is normally |alink| } @= @@ -23380,7 +20433,7 @@ widths. Let $w_{ij}$ be the maximum of the natural widths of all entries that span columns $i$ through $j$, inclusive. The alignrecord for column~$i$ contains $w_{ii}$ in its |width| field, and there is also a linked list of the nonzero $w_{ij}$ for increasing $j$, accessible via the |info| field; -these span nodes contain the value $j-i-1+|min_quarterword|$ in their +these span nodes contain the value $j-i+|min_quarterword|$ in their |link| fields. The values of $w_{ii}$ were initialized to |null_flag|, which we regard as $-\infty$. @@ -23596,7 +20649,7 @@ program will be deferred until we're more familiar with such operations.) @= aux_save:=aux; p:=vlink(head); q:=tail; pop_nest; -if mode=mmode then @ +if mode=mmode then finish_display_alignment(p,q,aux_save) else begin aux:=aux_save; vlink(tail):=p; if p<>null then tail:=q; if mode=vmode then begin check_filter('alignment'); build_page; end; @@ -23623,7 +20676,7 @@ line-breaking problem can be regarded as a special case of the problem of computing the shortest path in an acyclic network. The cited paper includes numerous examples and describes the history of line breaking as it has been practiced by printers through the ages. The present implementation adds two -new ideas to the algorithm of 1980: memory space requirements are considerably +new ideas to the algorithm of 1980: Memory space requirements are considerably reduced by using smaller records for inactive nodes than for active ones, and arithmetic overflow is avoided by using ``delta distances'' instead of keeping track of the total distance from the beginning of the paragraph to the @@ -23670,7 +20723,7 @@ line_break_context := bottom_level; @ In it's complete form, |line_break| is a rather lengthy procedure---sort of a small world unto itself---we must build it up -little by little. Below you see only te general outline. +little by little. Below you see only the general outline. The main task performed here is to move the list from |head| to |temp_head| and go into the enclosing semantic level. We also append @@ -23689,6 +20742,7 @@ Most other processing is delegated to external functions. @p procedure line_break(@!d:boolean); var final_par_glue:pointer; start_of_par:pointer; +callback_id:integer; begin pack_begin_line:=mode_line; {this is for over/underfull box messages} vlink(temp_head):=vlink(head); new_hyphenation(temp_head, tail); @@ -23710,28 +20764,52 @@ else begin end; final_par_glue:=new_param_glue(par_fill_skip_code); couple_nodes(tail,final_par_glue); -if not output_active then - lua_node_filter(pre_linebreak_filter_callback, - line_break_context,temp_head,addressof(tail)); +lua_node_filter(pre_linebreak_filter_callback, + line_break_context,temp_head,addressof(tail)); last_line_fill:=vlink(tail); pop_nest; start_of_par:=tail; -ext_do_line_break(d,pretolerance,tracing_paragraphs,tolerance,emergency_stretch, - looseness,hyphen_penalty,ex_hyphen_penalty, - pdf_adjust_spacing, par_shape_ptr, adj_demerits, - pdf_protrude_chars, line_penalty, last_line_fit, - double_hyphen_demerits, final_hyphen_demerits, - hang_indent, hsize, hang_after, left_skip, right_skip, - pdf_each_line_height,pdf_each_line_depth, - pdf_first_line_height, pdf_last_line_depth, - inter_line_penalties_ptr, inter_line_penalty, - club_penalty, club_penalties_ptr, - display_widow_penalties_ptr,widow_penalties_ptr, - display_widow_penalty, widow_penalty, - broken_penalty, final_par_glue); -if not output_active then - lua_node_filter(post_linebreak_filter_callback, - line_break_context,start_of_par,addressof(tail)); +callback_id:=callback_defined(linebreak_filter_callback); +if callback_id<>0 then begin + callback_id := lua_linebreak_callback(d, temp_head, addressof(tail)); + if callback_id>0 then begin + just_box := tail; + if just_box<>null then + while vlink(just_box)<>null do + just_box := vlink(just_box); + if (just_box=null)or(type(just_box) <> hlist_node) then begin + help3("A linebreaking routine should return a non-empty list of nodes") + ("and the last one of those has to be a \\hbox.") + ("Sorry, I cannot recover from this."); + print_err("Invalid linebreak_filter"); + succumb; + end + end + else begin + if tracing_paragraphs>0 then begin + begin_diagnostic; + print_nl("Lua linebreak_filter failed, reverting to default on line "); print_int(line); + end_diagnostic(true); + end; + end; +end; +if callback_id=0 then begin + ext_do_line_break(d,pretolerance,tracing_paragraphs,tolerance,emergency_stretch, + looseness,hyphen_penalty,ex_hyphen_penalty, + pdf_adjust_spacing, par_shape_ptr, adj_demerits, + pdf_protrude_chars, line_penalty, last_line_fit, + double_hyphen_demerits, final_hyphen_demerits, + hang_indent, hsize, hang_after, left_skip, right_skip, + pdf_each_line_height,pdf_each_line_depth, + pdf_first_line_height, pdf_last_line_depth, + inter_line_penalties_ptr, inter_line_penalty, + club_penalty, club_penalties_ptr, + display_widow_penalties_ptr,widow_penalties_ptr, + display_widow_penalty, widow_penalty, + broken_penalty, final_par_glue, pdf_ignored_dimen); +end; +lua_node_filter(post_linebreak_filter_callback, + line_break_context,start_of_par,addressof(tail)); pack_begin_line:=0; end; @# @@ -23742,13 +20820,7 @@ end; The choice between |check_head_filter| and |check_contrib_filter| is not quite clear to me yet, but it seems that the latter is the better choice. -@d check_head_filter(#)==if (not output_active) and (vlink(head)<>null) then -lua_node_filter_s(buildpage_filter_callback,#,head,addressof(tail)) - -@d check_contrib_filter(#)==if (not output_active) and (vlink(contrib_head)<>null) then -lua_node_filter_s(buildpage_filter_callback,#,contrib_head,addressof(garbage)) - -@d check_filter==check_head_filter +@d check_filter(#)==if not output_active then lua_node_filter_s(buildpage_filter_callback,#) @* \[39] Breaking paragraphs into lines, continued. @@ -23795,6 +20867,21 @@ begin scan_optional_equals; scan_int; set_post_hyphen_char(language,cur_val); end; +@ `\.{\\preexhyphenchar}', sets the |pre_break| character, and +`\.{\\postexhyphenchar}' the |post_break| character. Their +defaults are both zero (nul). + +@p procedure new_pre_exhyphen_char; +begin scan_optional_equals; scan_int; + set_pre_exhyphen_char(language,cur_val); +end; +@# +procedure new_post_exhyphen_char; +begin scan_optional_equals; scan_int; + set_post_exhyphen_char(language,cur_val); +end; + + @* \[43] Initializing the hyphenation tables. None of the trie-related stuff is applicable any more in luatex. @@ -23823,12 +20910,12 @@ var prev_p:pointer; {lags one step behind |p|} begin prev_p:=temp_head; vlink(temp_head):=p; r:=null; while p<>null do case type(p) of - hlist_node,vlist_node,rule_node:@; - whatsit_node,mark_node,ins_node: begin + whatsit_node_case,mark_node_case,ins_node_case: begin prev_p:=p; p:=vlink(prev_p); end; - glue_node,kern_node,penalty_node: begin + glue_node_case,kern_node_case,penalty_node_case: begin q:=p; p:=vlink(q); vlink(q):=null; vlink(prev_p):=p; if s then @@ -23928,19 +21015,19 @@ not_found: if prev_dp>d then @ @= case type(p) of -hlist_node,vlist_node,rule_node: begin@t@>@;@/ +hlist_node_case,vlist_node_case,rule_node_case: begin@t@>@;@/ cur_height:=cur_height+prev_dp+height(p); prev_dp:=depth(p); goto not_found; end; -whatsit_node:@; -glue_node: if precedes_break(prev_p) then pi:=0 +whatsit_node_case:@; +glue_node_case: if precedes_break(prev_p) then pi:=0 else goto update_heights; -kern_node: begin if vlink(p)=null then t:=penalty_node +kern_node_case: begin if vlink(p)=null then t:=penalty_node else t:=type(vlink(p)); if t=glue_node then pi:=0@+else goto update_heights; end; -penalty_node: pi:=penalty(p); -mark_node,ins_node: goto not_found; +penalty_node_case: pi:=penalty(p); +mark_node_case,ins_node_case: goto not_found; othercases confusion("vertbreak") @:this can't happen vertbreak}{\quad vertbreak@> endcases @@ -24132,8 +21219,8 @@ node $r_j$ is followed by |r@t$_{j+1}$@>=vlink(r@t$_j$@>)|; and if there are each node in this list refers to an insertion number; for example, `\.{\\insert 250}' would correspond to a node whose |subtype| is |qi(250)| (the same as the |subtype| field of the relevant |ins_node|). These |subtype| -fields are in increasing order, and |subtype(page_ins_head)= -qi(255)|, so |page_ins_head| serves as a convenient sentinel +fields are in increasing order, and |subtype(page_ins_head)=65535, so +|page_ins_head| serves as a convenient sentinel at the end of the list. A record is present for each insertion number that appears in the current page. @@ -24160,8 +21247,6 @@ The data structure definitions here use the fact that the |@!height| field appears in the fourth word of a box node. @^data structure assumptions@> -@d inserting_node=37 {an insertion class that has not yet overflowed} -@d split_up_node=38 {an overflowed insertion class} @d broken_ptr(#)==vlink(#+2) {an insertion for this class will break here if anywhere} @d broken_ins(#)==vinfo(#+2) {this insertion might break at |broken_ptr|} @@ -24169,7 +21254,7 @@ appears in the fourth word of a box node. @d best_ins_ptr(#)==vinfo(#+3) {the optimum most recent insertion} @= -subtype(page_ins_head):=qi(255); +subtype(page_ins_head):=65535; type(page_ins_head):=split_up_node; vlink(page_ins_head):=page_ins_head; @ An array |page_so_far| records the heights and depths of everything @@ -24207,35 +21292,23 @@ all split and floating insertions. @!insert_penalties:integer; {sum of the penalties for held-over insertions} @ @= -primitive("pagegoal",set_page_dimen,0); +primitive_tex("pagegoal",set_page_dimen,0,0); @!@:page_goal_}{\.{\\pagegoal} primitive@> -primitive("pagetotal",set_page_dimen,1); +primitive_tex("pagetotal",set_page_dimen,1,0); @!@:page_total_}{\.{\\pagetotal} primitive@> -primitive("pagestretch",set_page_dimen,2); +primitive_tex("pagestretch",set_page_dimen,2,0); @!@:page_stretch_}{\.{\\pagestretch} primitive@> -primitive("pagefilstretch",set_page_dimen,3); +primitive_tex("pagefilstretch",set_page_dimen,3,0); @!@:page_fil_stretch_}{\.{\\pagefilstretch} primitive@> -primitive("pagefillstretch",set_page_dimen,4); +primitive_tex("pagefillstretch",set_page_dimen,4,0); @!@:page_fill_stretch_}{\.{\\pagefillstretch} primitive@> -primitive("pagefilllstretch",set_page_dimen,5); +primitive_tex("pagefilllstretch",set_page_dimen,5,0); @!@:page_filll_stretch_}{\.{\\pagefilllstretch} primitive@> -primitive("pageshrink",set_page_dimen,6); +primitive_tex("pageshrink",set_page_dimen,6,0); @!@:page_shrink_}{\.{\\pageshrink} primitive@> -primitive("pagedepth",set_page_dimen,7); +primitive_tex("pagedepth",set_page_dimen,7,0); @!@:page_depth_}{\.{\\pagedepth} primitive@> -@ @= -set_page_dimen: case chr_code of -0: print_esc("pagegoal"); -1: print_esc("pagetotal"); -2: print_esc("pagestretch"); -3: print_esc("pagefilstretch"); -4: print_esc("pagefillstretch"); -5: print_esc("pagefilllstretch"); -6: print_esc("pageshrink"); -othercases print_esc("pagedepth") -endcases; - @ @d print_plus_end(#)==print(#);@+end @d print_plus(#)==if page_so_far[#]<>0 then begin print(" plus "); print_scaled(page_so_far[#]); print_plus_end @@ -24266,7 +21339,9 @@ if page_head<>page_tail then while r<>page_ins_head do begin print_ln; print_esc("insert"); t:=qo(subtype(r)); print_int(t); print(" adds "); - t:=x_over_n(height(r),1000)*count(t); print_scaled(t); + if count(t)=1000 then t:=height(r) + else t:=x_over_n(height(r),1000)*count(t); + print_scaled(t); if type(r)=split_up_node then begin q:=page_head; t:=0; repeat q:=vlink(q); @@ -24344,7 +21419,7 @@ last_glue:=max_halfword; last_penalty:=0; last_kern:=0; last_node_type:=-1; page_depth:=0; page_max_depth:=0 -@ At certain times box 255 is supposed to be void (i.e., |null|), +@ At certain times box \outputbox is supposed to be void (i.e., |null|), or an insertion box is supposed to be ready to accept a vertical list. If not, an error message is printed, and the following subroutine flushes the unwanted contents, reporting them to the user. @@ -24461,23 +21536,23 @@ we know its successor. @= case type(p) of -hlist_node,vlist_node,rule_node: if page_contents else @; -whatsit_node: @; -glue_node: if page_contents; +penalty_node_case: if page_contents; othercases confusion("page") @:this can't happen page}{\quad page@> endcases @@ -24486,7 +21561,7 @@ endcases begin if page_contents=empty then freeze_page_specs(box_there) else page_contents:=box_there; q:=new_skip_param(top_skip_code); {now |temp_ptr=glue_ptr(q)|} -if (type(p)=hlist_node) and (is_mirrored(body_direction)) then begin +if (type(p)=hlist_node) and is_mirrored(body_direction) then begin if width(temp_ptr)>depth(p) then width(temp_ptr):=width(temp_ptr)-depth(p) else width(temp_ptr):=0; end @@ -24499,7 +21574,7 @@ end @ @= begin -if (type(p)=hlist_node) and (is_mirrored(body_direction)) then begin +if (type(p)=hlist_node) and is_mirrored(body_direction) then begin page_total:=page_total+page_depth+depth(p); page_depth:=height(p); end @@ -24688,7 +21763,7 @@ end @ When the page builder has looked at as much material as could appear before the next page break, it makes its decision. The break that gave minimum -badness will be used to put a completed ``page'' into box 255, with insertions +badness will be used to put a completed ``page'' into box \.{\\outputbox}, with insertions appended to their other boxes. We also set the values of |top_mark|, |first_mark|, and |bot_mark|. The @@ -24720,7 +21795,7 @@ for i:=0 to biggest_used_mark do begin delete_first_mark(i); end; end; -@; for i:=0 to biggest_used_mark do begin @@ -24747,9 +21822,9 @@ pointer |p| runs through the vlist, with |prev_p| trailing behind; pointer |q| is the tail of a list of insertions that are being held over for a subsequent page. -@= +@= if c=best_page_break then best_page_break:=null; {|c| not yet linked in} -@; +@; insert_penalties:=0; {this will count the number of insertions held over} save_split_top_skip:=split_top_skip; if holding_inserts<=0 then @@ -24767,17 +21842,17 @@ while p<>best_page_break do prev_p:=p; p:=vlink(prev_p); end; split_top_skip:=save_split_top_skip; -@; @ -@ @= -if box(255)<>null then - begin print_err(""); print_esc("box"); print("255 is not void"); -@:box255}{\.{\\box255 is not void}@> - help2("You shouldn't use \box255 except in \output routines.")@/ +@ @= +if box(output_box)<>null then + begin print_err(""); print_esc("box"); print_int(output_box); print(" is not void"); +@:box\\outputbox}{\.{\\box\\outputbox is not void}@> + help2("You shouldn't use \box\outputbox except in \output routines.")@/ ("Proceed, and I'll discard its present contents."); - box_error(255); + box_error(output_box); end @ @= @@ -24812,7 +21887,7 @@ if p<>null then save_vbadness:=vbadness; vbadness:=inf_bad; save_vfuzz:=vfuzz; vfuzz:=max_dimen; {inhibit error messages} pack_direction:=body_direction; -box(255):=filtered_vpackage(vlink(page_head),best_size,exactly,page_max_depth,output_group); +box(output_box):=filtered_vpackage(vlink(page_head),best_size,exactly,page_max_depth,output_group); vbadness:=save_vbadness; vfuzz:=save_vfuzz; if last_glue<>max_halfword then delete_glue_ref(last_glue); @; {this sets |last_glue:=max_halfword|} @@ -24912,7 +21987,7 @@ begin if vlink(page_head)<>null then vlink(page_head):=null; page_tail:=page_head; end; flush_node_list(page_disc); page_disc:=null; -ship_out(box(255)); box(255):=null; +ship_out(box(output_box)); box(output_box):=null; end @ @= @@ -24920,14 +21995,14 @@ begin print_err("Output loop---"); print_int(dead_cycles); @.Output loop...@> print(" consecutive dead cycles"); help3("I've concluded that your \output is awry; it never does a")@/ -("\shipout, so I'm shipping \box255 out myself. Next time")@/ +("\shipout, so I'm shipping \box\outputbox out myself. Next time")@/ ("increase \maxdeadcycles if you want me to be more patient!"); error; end @ @= begin output_active:=true; incr(dead_cycles); -push_nest; mode:=-vmode; prev_depth:=ignore_depth; mode_line:=-line; +push_nest; mode:=-vmode; prev_depth:=pdf_ignored_dimen; mode_line:=-line; begin_token_list(output_routine,output_text); new_save_level(output_group); normal_paragraph; scan_left_brace; @@ -24943,7 +22018,7 @@ begin if (loc<>null) or @; end_token_list; {conserve stack space in case more outputs are triggered} end_graf; unsave; output_active:=false; insert_penalties:=0;@/ -@; +@; if tail<>head then {current list goes after heldover insertions} begin vlink(page_tail):=vlink(head); page_tail:=tail; @@ -24955,7 +22030,7 @@ if vlink(page_head)<>null then {and both go before heldover contributions} vlink(page_head):=null; page_tail:=page_head; end; flush_node_list(page_disc); page_disc:=null; -pop_nest; build_page; +pop_nest; check_filter('after_output'); build_page; end @ @= @@ -24967,15 +22042,15 @@ repeat get_token; until loc=null; end {loops forever if reading from a file, since |null=min_halfword<=0|} -@ @= -if box(255)<>null then +@ @= +if box(output_box)<>null then begin print_err("Output routine didn't use all of "); - print_esc("box"); print_int(255); + print_esc("box"); print_int(output_box); @.Output routine didn't use...@> - help3("Your \output commands should empty \box255,")@/ - ("e.g., by saying `\shipout\box255'.")@/ + help3("Your \output commands should empty \box\outputbox,")@/ + ("e.g., by saying `\shipout\box\outputbox'.")@/ ("Proceed; I'll discard its present contents."); - box_error(255); + box_error(output_box); end @* \[46] The chief executive. @@ -25033,6 +22108,7 @@ label big_switch,reswitch,continue,exit; var@!t,k:integer; {general-purpose temporary variables} p:pointer; {for whatsit nodes and testing whether an auto kern should be inserted} chr_stack:integer; { to temporarily save an |cur_chr| to be appended } +mval:mathcodeval; { to build up an argument to |set_math_char| } begin t:=0; {for -Wall} chr_stack:=-1; if every_job<>null then begin_token_list(every_job,every_job_text); @@ -25059,7 +22135,7 @@ hmode+no_boundary: begin @; hmode+char_ghost: begin t:=cur_chr; get_x_token; if (cur_cmd=letter)or(cur_cmd=other_char)or(cur_cmd=char_given)or (cur_cmd=char_num) then begin - p:=new_glyph(cur_font,cur_chr); + p:=new_glyph(cur_font,cur_chr); if t=0 then begin set_is_leftghost(p); end else begin set_is_rightghost(p); end; tail_append(p); @@ -25124,13 +22200,15 @@ if (cur_cmd=letter)or(cur_cmd=other_char)or scan_char_num; cur_chr:=cur_val; end; if (chr_stack=ex_hyphen_char)and(cur_chr<>ex_hyphen_char)and(mode>0) then begin - tail_append(new_disc); subtype(tail):=automatic_disc; + tail:=compound_word_break(tail,cur_lang); + subtype(tail):=automatic_disc; end; goto continue; end else begin if (chr_stack=ex_hyphen_char) and (mode>0) then begin - tail_append(new_disc); subtype(tail):=automatic_disc; + tail:=compound_word_break(tail,cur_lang); + subtype(tail):=automatic_disc; end; chr_stack:=-1; goto reswitch; @@ -25235,6 +22313,7 @@ any_mode(ignore_spaces): begin end; end; vmode+stop: if its_all_over then return; {this is the only way out} +@t\4@>@; @t\4@>@@+@,any_mode(mac_param): report_illegal_case; @: insert_dollar_sign; @@ -25248,8 +22327,7 @@ mode by mistake. \TeX\ will insert a dollar sign and rescan the current token. @d non_math(#)==vmode+#,hmode+# @= -non_math(sup_mark), non_math(sub_mark), non_math(math_char_num), -non_math(math_given), non_math(omath_given), +non_math(sup_mark), non_math(sub_mark), non_math(math_comp), non_math(delim_num), non_math(left_right), non_math(above), non_math(radical), non_math(math_style), non_math(math_choice), non_math(vcenter), @@ -25258,6 +22336,36 @@ non_math(mskip), non_math(math_accent), mmode+endv, mmode+par_end, mmode+stop, mmode+vskip, mmode+un_vbox, mmode+valign, mmode+hrule +@ @= +vmode+math_char_num, vmode+math_given, vmode+omath_given, vmode+xmath_given: begin + back_input; new_graf(true); + end; +hmode+math_char_num: begin + if cur_chr=0 then + mval := scan_mathchar(tex_mathcode) + else if cur_chr=1 then + mval := scan_mathchar(aleph_mathcode) + else if cur_chr=2 then + mval := scan_mathchar(xetex_mathcode) + else + mval := scan_mathchar(xetexnum_mathcode); + math_char_in_text(mval); + end; +hmode+math_given: begin + mval := mathchar_from_integer(cur_chr,tex_mathcode); + math_char_in_text(mval); + end; +hmode+omath_given: begin + mval := mathchar_from_integer(cur_chr,aleph_mathcode); + math_char_in_text(mval); + end; +hmode+xmath_given: begin + mval := mathchar_from_integer(cur_chr,xetex_mathcode); + math_char_in_text(mval); + end + + + @ @= procedure insert_dollar_sign; begin back_input; cur_tok:=math_shift_token+"$"; @@ -25317,14 +22425,11 @@ end; endgame, since both of them have `|stop|' as their command code. @= -primitive("end",stop,0);@/ +primitive_tex("end",stop,0,0);@/ @!@:end_}{\.{\\end} primitive@> -primitive("dump",stop,1);@/ +primitive_tex("dump",stop,1,0);@/ @!@:dump_}{\.{\\dump} primitive@> -@ @= -stop:if chr_code=1 then print_esc("dump")@+else print_esc("end"); - @ We don't want to leave |main_control| immediately when a |stop| command is sensed, because it may be necessary to invoke an \.{\\output} routine several times before things really grind to a halt. (The output routine @@ -25345,7 +22450,7 @@ begin if privileged then width(tail):=hsize; tail_append(new_glue(fill_glue)); tail_append(new_penalty(-@'10000000000));@/ - build_page; {append \.{\\hbox to \\hsize\{\}\\vfill\\penalty-'10000000000}} + check_filter('end'); build_page; {append \.{\\hbox to \\hsize\{\}\\vfill\\penalty-'10000000000}} end; its_all_over:=false; exit:end; @@ -25364,11 +22469,11 @@ is short, since the |scan_rule_spec| routine already does most of what is required; thus, there is no need for a special action procedure. Note that baselineskip calculations are disabled after a rule in vertical -mode, by setting |prev_depth:=ignore_depth|. +mode, by setting |prev_depth:=pdf_ignored_dimen|. @= vmode+hrule,hmode+vrule,mmode+vrule: begin tail_append(scan_rule_spec); - if abs(mode)=vmode then prev_depth:=ignore_depth + if abs(mode)=vmode then prev_depth:=pdf_ignored_dimen else if abs(mode)=hmode then space_factor:=1000; end; @@ -25393,52 +22498,33 @@ The difference is in the value of |cur_chr|. @d mskip_code=5 {identifies \.{\\mskip}} @= -primitive("hskip",hskip,skip_code);@/ +primitive_tex("hskip",hskip,skip_code,0);@/ @!@:hskip_}{\.{\\hskip} primitive@> -primitive("hfil",hskip,fil_code); +primitive_tex("hfil",hskip,fil_code,0); @!@:hfil_}{\.{\\hfil} primitive@> -primitive("hfill",hskip,fill_code);@/ +primitive_tex("hfill",hskip,fill_code,0);@/ @!@:hfill_}{\.{\\hfill} primitive@> -primitive("hss",hskip,ss_code); +primitive_tex("hss",hskip,ss_code,0); @!@:hss_}{\.{\\hss} primitive@> -primitive("hfilneg",hskip,fil_neg_code);@/ +primitive_tex("hfilneg",hskip,fil_neg_code,0);@/ @!@:hfil_neg_}{\.{\\hfilneg} primitive@> -primitive("vskip",vskip,skip_code);@/ +primitive_tex("vskip",vskip,skip_code,0);@/ @!@:vskip_}{\.{\\vskip} primitive@> -primitive("vfil",vskip,fil_code); +primitive_tex("vfil",vskip,fil_code,0); @!@:vfil_}{\.{\\vfil} primitive@> -primitive("vfill",vskip,fill_code);@/ +primitive_tex("vfill",vskip,fill_code,0);@/ @!@:vfill_}{\.{\\vfill} primitive@> -primitive("vss",vskip,ss_code); +primitive_tex("vss",vskip,ss_code,0); @!@:vss_}{\.{\\vss} primitive@> -primitive("vfilneg",vskip,fil_neg_code);@/ +primitive_tex("vfilneg",vskip,fil_neg_code,0);@/ @!@:vfil_neg_}{\.{\\vfilneg} primitive@> -primitive("mskip",mskip,mskip_code);@/ +primitive_tex("mskip",mskip,mskip_code,0);@/ @!@:mskip_}{\.{\\mskip} primitive@> -primitive("kern",kern,explicit); +primitive_tex("kern",kern,explicit,0); @!@:kern_}{\.{\\kern} primitive@> -primitive("mkern",mkern,mu_glue);@/ +primitive_tex("mkern",mkern,mu_glue,0);@/ @!@:mkern_}{\.{\\mkern} primitive@> -@ @= -hskip: case chr_code of - skip_code:print_esc("hskip"); - fil_code:print_esc("hfil"); - fill_code:print_esc("hfill"); - ss_code:print_esc("hss"); - othercases print_esc("hfilneg") - endcases; -vskip: case chr_code of - skip_code:print_esc("vskip"); - fil_code:print_esc("vfil"); - fill_code:print_esc("vfill"); - ss_code:print_esc("vss"); - othercases print_esc("vfilneg") - endcases; -mskip: print_esc("mskip"); -kern: print_esc("kern"); -mkern: print_esc("mkern"); - @ All the work relating to glue creation has been relegated to the following subroutine. It does not call |build_page|, because it is used in at least one place where that would be a mistake. @@ -25592,7 +22678,8 @@ procedure handle_right_brace; var p,@!q:pointer; {for short-term use} @!d:scaled; {holds |split_max_depth| in |insert_group|} @!f:integer; {holds |floating_penalty| in |insert_group|} -begin case cur_group of +begin p:=null; +case cur_group of simple_group: begin temp_no_whatsits:=no_local_whatsits; temp_no_dirs:=no_local_dirs; @@ -25696,57 +22783,40 @@ where the latter two are used denote \.{\\vbox} and \.{\\hbox}, respectively. @d vtop_code=4 {|chr_code| for `\.{\\vtop}'} @= -primitive("moveleft",hmove,1); +primitive_tex("moveleft",hmove,1,0); @!@:move_left_}{\.{\\moveleft} primitive@> -primitive("moveright",hmove,0);@/ +primitive_tex("moveright",hmove,0,0);@/ @!@:move_right_}{\.{\\moveright} primitive@> -primitive("raise",vmove,1); +primitive_tex("raise",vmove,1,0); @!@:raise_}{\.{\\raise} primitive@> -primitive("lower",vmove,0); +primitive_tex("lower",vmove,0,0); @!@:lower_}{\.{\\lower} primitive@> @# -primitive("box",make_box,box_code); +primitive_tex("box",make_box,box_code,0); @!@:box_}{\.{\\box} primitive@> -primitive("copy",make_box,copy_code); +primitive_tex("copy",make_box,copy_code,0); @!@:copy_}{\.{\\copy} primitive@> -primitive("lastbox",make_box,last_box_code); +primitive_tex("lastbox",make_box,last_box_code,0); @!@:last_box_}{\.{\\lastbox} primitive@> -primitive("vsplit",make_box,vsplit_code); +primitive_tex("vsplit",make_box,vsplit_code,0); @!@:vsplit_}{\.{\\vsplit} primitive@> -primitive("vtop",make_box,vtop_code);@/ +primitive_tex("vtop",make_box,vtop_code,0);@/ @!@:vtop_}{\.{\\vtop} primitive@> -primitive("vbox",make_box,vtop_code+vmode); +primitive_tex("vbox",make_box,vtop_code+vmode,0); @!@:vbox_}{\.{\\vbox} primitive@> -primitive("hbox",make_box,vtop_code+hmode);@/ +primitive_tex("hbox",make_box,vtop_code+hmode,0);@/ @!@:hbox_}{\.{\\hbox} primitive@> -primitive("shipout",leader_ship,a_leaders-1); {|ship_out_flag=leader_flag-1|} +primitive_tex("shipout",leader_ship,a_leaders-1,0); {|ship_out_flag=leader_flag-1|} @!@:ship_out_}{\.{\\shipout} primitive@> -primitive("leaders",leader_ship,a_leaders); +primitive_tex("leaders",leader_ship,a_leaders,0); @!@:leaders_}{\.{\\leaders} primitive@> -primitive("cleaders",leader_ship,c_leaders); +primitive_tex("cleaders",leader_ship,c_leaders,0); @!@:c_leaders_}{\.{\\cleaders} primitive@> -primitive("xleaders",leader_ship,x_leaders); +primitive_tex("xleaders",leader_ship,x_leaders,0); @!@:x_leaders_}{\.{\\xleaders} primitive@>; -primitive("boxdir",assign_box_dir,0); +primitive_aleph("boxdir",assign_box_dir,0,0); @!@:box_dir}{\.{\\boxdir} primitive@> -@ @= -hmove: if chr_code=1 then print_esc("moveleft")@+else print_esc("moveright"); -vmove: if chr_code=1 then print_esc("raise")@+else print_esc("lower"); -make_box: case chr_code of - box_code: print_esc("box"); - copy_code: print_esc("copy"); - last_box_code: print_esc("lastbox"); - vsplit_code: print_esc("vsplit"); - vtop_code: print_esc("vtop"); - vtop_code+vmode: print_esc("vbox"); - othercases print_esc("hbox") - endcases; -leader_ship: if chr_code=a_leaders then print_esc("leaders") - else if chr_code=c_leaders then print_esc("cleaders") - else if chr_code=x_leaders then print_esc("xleaders") - else print_esc("shipout"); - @ Constructions that require a box are started by calling |scan_box| with a specified context code. The |scan_box| routine verifies that a |make_box| command comes next and then it calls |begin_box|. @@ -25777,7 +22847,6 @@ case can occur only with leaders. @= procedure box_end(@!box_context:integer); -var p:pointer; {|ord_noad| for new box in math mode} begin if box_context else if box_context @@ -25810,10 +22879,7 @@ begin if cur_box<>null then if mode>0 then begin check_filter('box'); build_page; end; end else begin if abs(mode)=hmode then space_factor:=1000 - else begin p:=new_noad; - math_type(nucleus(p)):=sub_box; - vinfo(nucleus(p)):=cur_box; cur_box:=p; - end; + else cur_box:=new_sub_box(cur_box); vlink(tail):=cur_box; tail:=cur_box; end; end; @@ -25827,8 +22893,7 @@ else geq_define(box_base+box_context-global_box_flag,box_ref,cur_box) @ @= begin @; if ((cur_cmd=hskip)and(abs(mode)<>vmode))or@| - ((cur_cmd=vskip)and(abs(mode)=vmode))or@| - ((cur_cmd=mskip)and(abs(mode)=mmode)) then + ((cur_cmd=vskip)and(abs(mode)=vmode)) then begin append_glue; subtype(tail):=box_context-(leader_flag-a_leaders); leader_ptr(tail):=cur_box; end @@ -25902,7 +22967,7 @@ done:end @= begin scan_register_num; n:=cur_val; -if not scan_keyword("to") then +if not scan_keyword('to') then @.to@> begin print_err("Missing `to' inserted"); @.Missing `to' inserted@> @@ -25934,7 +22999,7 @@ else begin if k=vmode then scan_spec(vbox_group,true) end; push_nest; mode:=-k; if k=vmode then - begin prev_depth:=ignore_depth; + begin prev_depth:=pdf_ignored_dimen; if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text); end else begin space_factor:=1000; @@ -26015,16 +23080,13 @@ or when the paragraph is explicitly started by `\.{\\quitvmode}', `\.{\\indent}' or `\.{\\noindent}'. @= -primitive("indent",start_par,1); +primitive_tex("indent",start_par,1,0); @!@:indent_}{\.{\\indent} primitive@> -primitive("noindent",start_par,0); +primitive_tex("noindent",start_par,0,0); @!@:no_indent_}{\.{\\noindent} primitive@> -primitive("quitvmode",start_par,2); +primitive_pdftex("quitvmode",start_par,2,0); @!@:quit_vmode_}{\.{\\quitvmode} primitive@> -@ @= -start_par: if chr_code=0 then print_esc("noindent")@+ else if chr_code=1 then print_esc("indent")@+ else print_esc("quitvmode"); - @ @= vmode+start_par: new_graf(cur_chr>0); vmode+letter,vmode+other_char,vmode+char_num,vmode+char_given, @@ -26041,8 +23103,6 @@ var p,q,dir_graf_tmp:pointer; begin prev_graf:=0; if (mode=vmode)or(head<>tail) then begin tail_append(new_param_glue(par_skip_code)); - if nest_ptr=0 then - check_filter('begin_of_par'); end; push_nest; mode:=hmode; space_factor:=1000; @; @@ -26067,7 +23127,7 @@ while vlink(q)<>null do q:=vlink(q); tail:=q; if every_par<>null then begin_token_list(every_par,every_par_text); if nest_ptr=1 then begin - build_page; {put |par_skip| glue on current page} + check_filter('new_graf'); build_page; {put |par_skip| glue on current page} end; end; @@ -26076,13 +23136,11 @@ hmode+start_par,mmode+start_par: if cur_chr<>2 then indent_in_hmode; @ @= procedure indent_in_hmode; -var p,@!q:pointer; +var p:pointer; begin if cur_chr>0 then {\.{\\indent}} begin p:=new_null_box; width(p):=par_indent; if abs(mode)=hmode then space_factor:=1000 - else begin q:=new_noad; math_type(nucleus(q)):=sub_box; - vinfo(nucleus(q)):=p; p:=q; - end; + else p:=new_sub_box(p); tail_append(p); end; end; @@ -26098,7 +23156,7 @@ vmode+par_end: begin normal_paragraph; hmode+par_end: begin if align_state<0 then off_save; {this tries to recover from an alignment that didn't end properly} if (mode>0) and (nest[(nest_ptr-1)].mode_field=vmode) then - line_break_context:=bottom_level; + line_break_context:=bottom_level; end_graf; {this takes us to the enclosing mode, if |mode>0|} if mode=vmode then begin check_filter('hmode_par'); build_page; end; end; @@ -26150,23 +23208,23 @@ vmode+vadjust, @ @= procedure begin_insert_or_adjust; -begin if cur_cmd=vadjust then cur_val:=255 +begin if cur_cmd=vadjust then cur_val:=output_box else begin scan_register_num; - if cur_val=255 then - begin print_err("You can't "); print_esc("insert"); print_int(255); -@.You can't \\insert255@> - help1("I'm changing to \insert0; box 255 is special."); + if cur_val=output_box then + begin print_err("You can't "); print_esc("insert"); print_int(output_box); +@.You can't \\insert\outputbox@> + help1("I'm changing to \insert0; box \outputbox is special."); error; cur_val:=0; end; end; saved(0) := cur_val; -if (cur_cmd = vadjust) and scan_keyword("pre") then +if (cur_cmd = vadjust) and scan_keyword('pre') then saved(1) := 1 else saved(1) := 0; save_ptr := save_ptr + 2; new_save_level(insert_group); scan_left_brace; normal_paragraph; -push_nest; mode:=-vmode; prev_depth:=ignore_depth; +push_nest; mode:=-vmode; prev_depth:=pdf_ignored_dimen; end; @ @= @@ -26174,9 +23232,9 @@ insert_group: begin line_break_context:=insert_group; end_graf; q:=split_top_skip; add_glue_ref(q); d:=split_max_depth; f:=floating_penalty; unsave; save_ptr := save_ptr - 2; - {now |saved(0)| is the insertion number, or 255 for |vadjust|} + {now |saved(0)| is the insertion number, or |output_box| for |vadjust|} p:=vpack(vlink(head),natural); pop_nest; - if saved(0)<>255 then + if saved(0)<>output_box then begin tail_append(new_node(ins_node,saved(0))); height(tail):=height(p)+depth(p); ins_ptr(tail):=list_ptr(p); split_top_ptr(tail):=q; depth(tail):=d; float_cost(tail):=f; @@ -26275,31 +23333,21 @@ begin if (cur_chr<>glue_node)or(last_glue<>max_halfword) then end @ @= -primitive("unpenalty",remove_item,penalty_node);@/ +primitive_tex("unpenalty",remove_item,penalty_node,0);@/ @!@:un_penalty_}{\.{\\unpenalty} primitive@> -primitive("unkern",remove_item,kern_node);@/ +primitive_tex("unkern",remove_item,kern_node,0);@/ @!@:un_kern_}{\.{\\unkern} primitive@> -primitive("unskip",remove_item,glue_node);@/ +primitive_tex("unskip",remove_item,glue_node,0);@/ @!@:un_skip_}{\.{\\unskip} primitive@> -primitive("unhbox",un_hbox,box_code);@/ +primitive_tex("unhbox",un_hbox,box_code,0);@/ @!@:un_hbox_}{\.{\\unhbox} primitive@> -primitive("unhcopy",un_hbox,copy_code);@/ +primitive_tex("unhcopy",un_hbox,copy_code,0);@/ @!@:un_hcopy_}{\.{\\unhcopy} primitive@> -primitive("unvbox",un_vbox,box_code);@/ +primitive_tex("unvbox",un_vbox,box_code,0);@/ @!@:un_vbox_}{\.{\\unvbox} primitive@> -primitive("unvcopy",un_vbox,copy_code);@/ +primitive_tex("unvcopy",un_vbox,copy_code,0);@/ @!@:un_vcopy_}{\.{\\unvcopy} primitive@> -@ @= -remove_item: if chr_code=glue_node then print_esc("unskip") - else if chr_code=kern_node then print_esc("unkern") - else print_esc("unpenalty"); -un_hbox: if chr_code=copy_code then print_esc("unhcopy") - else print_esc("unhbox"); -un_vbox: if chr_code=copy_code then print_esc("unvcopy") - @@/ - else print_esc("unvbox"); - @ The |un_hbox| and |un_vbox| commands unwrap one of the |number_regs| current boxes. @= @@ -26373,21 +23421,15 @@ generated by primitive commands. @d explicit_disc=1 @= -primitive("-",discretionary,explicit_disc); +primitive_tex("-",discretionary,explicit_disc,0); @!@:Single-character primitives -}{\quad\.{\\-}@> -primitive("discretionary",discretionary,discretionary_disc); +primitive_tex("discretionary",discretionary,discretionary_disc,0); @!@:discretionary_}{\.{\\discretionary} primitive@> -primitive("localleftbox",assign_local_box,0); +primitive_omega("localleftbox",assign_local_box,0,0); @!@:assign_local_box}{\.{\\localleftbox} primitive@> -primitive("localrightbox",assign_local_box,1); +primitive_omega("localrightbox",assign_local_box,1,0); @!@:assign_local_box}{\.{\\localrightbox} primitive@> -@ @= -discretionary: if chr_code=explicit_disc then - print_esc("-")@+else print_esc("discretionary"); -assign_local_box: if chr_code=0 then print_esc("localleftbox") - else print_esc("localrightbox"); - @ @= hmode+discretionary,mmode+discretionary: append_discretionary; any_mode(assign_local_box): append_local_box(cur_chr); @@ -26409,9 +23451,9 @@ subtype(tail):=cur_chr; if cur_chr=explicit_disc then begin c:=get_pre_hyphen_char(cur_lang); if c<>0 then begin - vlink(pre_break(tail)):=new_char(cur_font,c); + vlink(pre_break(tail)):=new_char(cur_font,c); alink(vlink(pre_break(tail))):=pre_break(tail); - tlink(pre_break(tail)):=vlink(pre_break(tail)); + tlink(pre_break(tail)):=vlink(pre_break(tail)); end; c:=get_post_hyphen_char(cur_lang); if c<>0 then begin @@ -26516,7 +23558,7 @@ while p<>null do end_diagnostic(true); flush_node_list(p); vlink(q):=null; goto done; end; - q:=p; p:=vlink(q); incr(n); + alink(p):=q; q:=p; p:=vlink(q); incr(n); end; done: @@ -26662,9 +23704,10 @@ Let's take a look at what happens when they are used correctly. @= vmode+halign,hmode+valign:init_align; -mmode+halign: if privileged then +mmode+halign: if privileged then begin if cur_group=math_shift_group then init_align else off_save; + end; vmode+endv,hmode+endv: do_endv; @ An |align_group| code is supposed to remain on the |save_stack| @@ -26703,514 +23746,148 @@ align_group: begin back_input; cur_tok:=cs_token_flag+frozen_cr; no_align_group: begin line_break_context:=no_align_group; end_graf; unsave; align_peek; end; -@ Finally, \.{\\endcsname} is not supposed to get through to |main_control|. - -@= -any_mode(end_cs_name): cs_error; - -@ @= -procedure cs_error; -begin print_err("Extra "); print_esc("endcsname"); -@.Extra \\endcsname@> -help1("I'm ignoring this, since I wasn't doing a \csname."); -error; -end; - -@* \[48] Building math lists. -The routines that \TeX\ uses to create mlists are similar to those we have -just seen for the generation of hlists and vlists. But it is necessary to -make ``noads'' as well as nodes, so the reader should review the -discussion of math mode data structures before trying to make sense out of -the following program. - -Here is a little routine that needs to be done whenever a subformula -is about to be processed. The parameter is a code like |math_group|. - -@= -procedure push_math(@!c:group_code); -begin -if math_direction<>text_direction then dir_math_save:=true; -push_nest; mode:=-mmode; incompleat_noad:=null; -@; -end; - -@ We get into math mode from horizontal mode when a `\.\$' (i.e., a -|math_shift| character) is scanned. We must check to see whether this -`\.\$' is immediately followed by another, in case display math mode is -called for. +@ Finally, \.{\\endcsname} is not supposed to get through to |main_control|. @= -hmode+math_shift:init_math; +any_mode(end_cs_name): cs_error; @ @= -procedure init_math; -label found,not_found,done; -var w:scaled; {new or partial |pre_display_size|} -@!l:scaled; {new |display_width|} -@!s:scaled; {new |display_indent|} -@!p:pointer; {current node when calculating |pre_display_size|} -@!q:pointer; {glue specification when calculating |pre_display_size|} -@!f:internal_font_number; {font in current |char_node|} -@!n:integer; {scope of paragraph shape specification} -@!v:scaled; {|w| plus possible glue amount} -@!d:scaled; {increment to |v|} -begin get_token; {|get_x_token| would fail on \.{\\ifmmode}\thinspace!} -if (cur_cmd=math_shift)and(mode>0) then @ -else begin back_input; @; - end; +procedure cs_error; +begin print_err("Extra "); print_esc("endcsname"); +@.Extra \\endcsname@> +help1("I'm ignoring this, since I wasn't doing a \csname."); +error; end; -@ @= -begin push_math(math_shift_group); eq_word_define(int_base+cur_fam_code,-1); -if every_math<>null then begin_token_list(every_math,every_math_text); -end +@* \[48] Building math lists. -@ We get into ordinary math mode from display math mode when `\.{\\eqno}' or -`\.{\\leqno}' appears. In such cases |cur_chr| will be 0 or~1, respectively; -the value of |cur_chr| is placed onto |save_stack| for safe keeping. +@ Almost all of this section is now in C, see |math.c|. Let here are just +the definitions of the primitives and the infrastructure hooks into |main_control|, +|print_cmd_chr| and |handle_right_brace|. @= -mmode+eq_no: if privileged then +hmode+math_shift:init_math; +mmode+eq_no: if privileged then begin if cur_group=math_shift_group then start_eq_no else off_save; + end; @ @= -primitive("eqno",eq_no,0); +primitive_tex("eqno",eq_no,0,0); @!@:eq_no_}{\.{\\eqno} primitive@> -primitive("leqno",eq_no,1); +primitive_tex("leqno",eq_no,1,0); @!@:leq_no_}{\.{\\leqno} primitive@> -@ When \TeX\ is in display math mode, |cur_group=math_shift_group|, -so it is not necessary for the |start_eq_no| procedure to test for -this condition. - -@= -procedure start_eq_no; -begin saved(0):=cur_chr; incr(save_ptr); -@; -end; - -@ @= -eq_no:if chr_code=1 then print_esc("leqno")@+else print_esc("eqno"); - @ @=non_math(eq_no), -@ When we enter display math mode, we need to call |line_break| to -process the partial paragraph that has just been interrupted by the -display. Then we can set the proper values of |display_width| and -|display_indent| and |pre_display_size|. - -@= -begin if head=tail then {`\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}'} - begin pop_nest; w:=-max_dimen; - end -else begin - line_break(true);@/ - @; - end; -{now we are in vertical mode, working on the list that will contain the display} -@; -push_math(math_shift_group); mode:=mmode; -eq_word_define(int_base+cur_fam_code,-1);@/ -eq_word_define(dimen_base+pre_display_size_code,w); -eq_word_define(dimen_base+display_width_code,l); -eq_word_define(dimen_base+display_indent_code,s); -if every_display<>null then begin_token_list(every_display,every_display_text); -if nest_ptr=1 then begin check_contrib_filter('before_display'); build_page; end; -end - -@ @= -v:=shift_amount(just_box)+2*quad(cur_font); w:=-max_dimen; -p:=list_ptr(just_box); -while p<>null do - begin @; - if v= -if is_char_node(p) then - begin f:=font(p); d:=glyph_width(p); - goto found; - end; -case type(p) of -hlist_node,vlist_node,rule_node: begin d:=width(p); goto found; - end; -margin_kern_node: d:=width(p); -kern_node: d:=width(p); -math_node: d:=surround(p); -glue_node:@; -whatsit_node: @; -othercases d:=0 -endcases - -@ We need to be careful that |w|, |v|, and |d| do not depend on any |glue_set| -values, since such values are subject to system-dependent rounding. -System-dependent numbers are not allowed to infiltrate parameters like -|pre_display_size|, since \TeX82 is supposed to make the same decisions on all -machines. - -@= -begin q:=glue_ptr(p); d:=width(q); -if glue_sign(just_box)=stretching then - begin if (glue_order(just_box)=stretch_order(q))and@| - (stretch(q)<>0) then - v:=max_dimen; - end -else if glue_sign(just_box)=shrinking then - begin if (glue_order(just_box)=shrink_order(q))and@| - (shrink(q)<>0) then - v:=max_dimen; - end; -if subtype(p)>=a_leaders then goto found; -end - -@ A displayed equation is considered to be three lines long, so we -calculate the length and offset of line number |prev_graf+2|. - -@= -if par_shape_ptr=null then - if (hang_indent<>0)and@| - (((hang_after>=0)and(prev_graf+2>hang_after))or@| - (prev_graf+1<-hang_after)) then - begin l:=hsize-abs(hang_indent); - if hang_indent>0 then s:=hang_indent@+else s:=0; - end - else begin l:=hsize; s:=0; - end -else begin n:=vinfo(par_shape_ptr); - if prev_graf+2>=n then p:=par_shape_ptr+2*n - else p:=par_shape_ptr+2*(prev_graf+2); - s:=vmem(p-1).sc; l:=vmem(p).sc; - end - -@ Subformulas of math formulas cause a new level of math mode to be entered, -on the semantic nest as well as the save stack. These subformulas arise in -several ways: (1)~A left brace by itself indicates the beginning of a -subformula that will be put into a box, thereby freezing its glue and -preventing line breaks. (2)~A subscript or superscript is treated as a -subformula if it is not a single character; the same applies to -the nucleus of things like \.{\\underline}. (3)~The \.{\\left} primitive -initiates a subformula that will be terminated by a matching \.{\\right}. -The group codes placed on |save_stack| in these three cases are -|math_group|, |math_group|, and |math_left_group|, respectively. - -Here is the code that handles case (1); the other cases are not quite as -trivial, so we shall consider them later. - -@= -mmode+left_brace: begin tail_append(new_noad); - back_input; scan_math(nucleus(tail)); - end; - -@ Recall that the |nucleus|, |subscr|, and |supscr| fields in a noad are -broken down into subfields called |math_type| and either |info| or -|(fam,character)|. The job of |scan_math| is to figure out what to place -in one of these principal fields; it looks at the subformula that -comes next in the input, and places an encoding of that subformula -into a given word of |mem|. - -@d fam_in_range==((cur_fam>=0)and(cur_fam<256)) - -@= -@t\4@>@@t@>@;@/ - -procedure scan_math(@!p:pointer); -label restart,reswitch,exit; -var c:integer; {math character code} -begin restart:@; -reswitch:case cur_cmd of -letter,other_char,char_given: begin c:=get_math_code(cur_chr); - if c=@"8000000 then - begin @; - goto restart; - end; - end; -char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given; - goto reswitch; - end; -math_char_num: begin - if cur_chr=0 then scan_fifteen_bit_int - else scan_big_fifteen_bit_int; - c:=cur_val; - end; -math_given: begin - c := ((cur_chr div @"1000) * @"1000000) + - (((cur_chr mod @"1000) div @"100) * @"10000) + - (cur_chr mod @"100); - end; -omath_given: begin c:=cur_chr; - end; -delim_num: begin - if cur_chr=0 then scan_twenty_seven_bit_int - else scan_fifty_one_bit_int; - c:=cur_val; - end; -othercases @ -endcases;@/ -math_type(p):=math_char; mcharacter(p):=qi(c mod @"10000); -if (c>=var_code)and fam_in_range then fam(p):=cur_fam -else fam(p):=(c div @"10000) mod @"100; -exit:end; - -@ An active character that is an |outer_call| is allowed here. - -@= -begin cur_cs:=(cur_chr mod number_active_chars)+active_base; -cur_cmd:=eq_type(cur_cs); cur_chr:=equiv(cur_cs); -x_token; back_input; -end - -@ The pointer |p| is placed on |save_stack| while a complex subformula -is being scanned. - -@= -begin back_input; scan_left_brace;@/ -saved(0):=p; incr(save_ptr); push_math(math_group); return; -end - -@ The simplest math formula is, of course, `\.{\${ }\$}', when no noads are -generated. The next simplest cases involve a single character, e.g., -`\.{\$x\$}'. Even though such cases may not seem to be very interesting, -the reader can perhaps understand how happy the author was when `\.{\$x\$}' -was first properly typeset by \TeX. The code in this section was used. -@^Knuth, Donald Ervin@> - -@= +@ @= +mmode+left_brace: math_left_brace; mmode+letter,mmode+other_char,mmode+char_given: set_math_char(get_math_code(cur_chr)); mmode+char_num: begin scan_char_num; cur_chr:=cur_val; set_math_char(get_math_code(cur_chr)); end; mmode+math_char_num: begin - if cur_chr=0 then scan_fifteen_bit_int - else scan_big_fifteen_bit_int; - set_math_char(cur_val); + if cur_chr=0 then + mval := scan_mathchar(tex_mathcode) + else if cur_chr=1 then + mval := scan_mathchar(aleph_mathcode) + else if cur_chr=2 then + mval := scan_mathchar(xetex_mathcode) + else + mval := scan_mathchar(xetexnum_mathcode); + set_math_char(mval); end; mmode+math_given: begin - set_math_char(((cur_chr div @"1000) * @"1000000) + - (((cur_chr mod @"1000) div @"100) * @"10000) + - (cur_chr mod @"100)); + mval := mathchar_from_integer(cur_chr,tex_mathcode); + set_math_char(mval); end; -mmode+omath_given: set_math_char(cur_chr); -mmode+delim_num: begin - if cur_chr=0 then scan_twenty_seven_bit_int - else scan_fifty_one_bit_int; - set_math_char(cur_val); +mmode+omath_given: begin + mval := mathchar_from_integer(cur_chr,aleph_mathcode); + set_math_char(mval); end; - -@ The |set_math_char| procedure creates a new noad appropriate to a given -math code, and appends it to the current mlist. However, if the math code -is sufficiently large, the |cur_chr| is treated as an active character and -nothing is appended. - -@= -procedure set_math_char(@!c:integer); -var p:pointer; {the new noad} -begin if c>=@"8000000 then - @ -else begin p:=new_noad; math_type(nucleus(p)):=math_char; - mcharacter(nucleus(p)):=qi(c mod @"10000); - fam(nucleus(p)):=(c div @"10000) mod @"100; - if c>=var_code then - begin if fam_in_range then fam(nucleus(p)):=cur_fam; - type(p):=ord_noad; - end - else - type(p):=ord_noad+(c div @"1000000); - vlink(tail):=p; tail:=p; +mmode+xmath_given: begin + mval := mathchar_from_integer(cur_chr,xetex_mathcode); + set_math_char(mval); + end; +mmode+delim_num: begin + if cur_chr=0 then + mval := scan_delimiter_as_mathchar(tex_mathcode) + else if cur_chr=1 then + mval := scan_delimiter_as_mathchar(aleph_mathcode) + else + mval := scan_delimiter_as_mathchar(xetex_mathcode); + set_math_char(mval); end; -end; @ Primitive math operators like \.{\\mathop} and \.{\\underline} are given the command code |math_comp|, supplemented by the noad type that they generate. @= -primitive("mathord",math_comp,ord_noad); +primitive_tex("mathord",math_comp,ord_noad,0); @!@:math_ord_}{\.{\\mathord} primitive@> -primitive("mathop",math_comp,op_noad); +primitive_tex("mathop",math_comp,op_noad,0); @!@:math_op_}{\.{\\mathop} primitive@> -primitive("mathbin",math_comp,bin_noad); +primitive_tex("mathbin",math_comp,bin_noad,0); @!@:math_bin_}{\.{\\mathbin} primitive@> -primitive("mathrel",math_comp,rel_noad); +primitive_tex("mathrel",math_comp,rel_noad,0); @!@:math_rel_}{\.{\\mathrel} primitive@> -primitive("mathopen",math_comp,open_noad); +primitive_tex("mathopen",math_comp,open_noad,0); @!@:math_open_}{\.{\\mathopen} primitive@> -primitive("mathclose",math_comp,close_noad); +primitive_tex("mathclose",math_comp,close_noad,0); @!@:math_close_}{\.{\\mathclose} primitive@> -primitive("mathpunct",math_comp,punct_noad); +primitive_tex("mathpunct",math_comp,punct_noad,0); @!@:math_punct_}{\.{\\mathpunct} primitive@> -primitive("mathinner",math_comp,inner_noad); +primitive_tex("mathinner",math_comp,inner_noad,0); @!@:math_inner_}{\.{\\mathinner} primitive@> -primitive("underline",math_comp,under_noad); +primitive_tex("underline",math_comp,under_noad,0); @!@:underline_}{\.{\\underline} primitive@> -primitive("overline",math_comp,over_noad);@/ +primitive_tex("overline",math_comp,over_noad,0);@/ @!@:overline_}{\.{\\overline} primitive@> -primitive("displaylimits",limit_switch,normal); +primitive_tex("displaylimits",limit_switch,normal,0); @!@:display_limits_}{\.{\\displaylimits} primitive@> -primitive("limits",limit_switch,limits); +primitive_tex("limits",limit_switch,limits,0); @!@:limits_}{\.{\\limits} primitive@> -primitive("nolimits",limit_switch,no_limits); +primitive_tex("nolimits",limit_switch,no_limits,0); @!@:no_limits_}{\.{\\nolimits} primitive@> -@ @= -math_comp: case chr_code of - ord_noad: print_esc("mathord"); - op_noad: print_esc("mathop"); - bin_noad: print_esc("mathbin"); - rel_noad: print_esc("mathrel"); - open_noad: print_esc("mathopen"); - close_noad: print_esc("mathclose"); - punct_noad: print_esc("mathpunct"); - inner_noad: print_esc("mathinner"); - under_noad: print_esc("underline"); - othercases print_esc("overline") - endcases; -limit_switch: if chr_code=limits then print_esc("limits") - else if chr_code=no_limits then print_esc("nolimits") - else print_esc("displaylimits"); - @ @= -mmode+math_comp: begin tail_append(new_noad); - type(tail):=cur_chr; scan_math(nucleus(tail)); - end; +mmode+math_comp: math_math_comp; mmode+limit_switch: math_limit_switch; - -@ @= -procedure math_limit_switch; -label exit; -begin if head<>tail then if type(tail)=op_noad then - begin subtype(tail):=cur_chr; return; - end; -print_err("Limit controls must follow a math operator"); -@.Limit controls must follow...@> -help1("I'm ignoring this misplaced \limits or \nolimits command."); error; -exit:end; - -@ Delimiter fields of noads are filled in by the |scan_delimiter| routine. -The first parameter of this procedure is the |mem| address where the -delimiter is to be placed; the second tells if this delimiter follows -\.{\\radical} or not. - -@= -procedure scan_delimiter(@!p:pointer;@!r:integer); -begin if r=1 then scan_twenty_seven_bit_int -else if r=2 then scan_fifty_one_bit_int -else begin @; - case cur_cmd of - letter,other_char: begin - cur_val:=get_del_code_a(cur_chr); cur_val1:=get_del_code_b(cur_chr); - end; - delim_num: if cur_chr=0 then scan_twenty_seven_bit_int - else scan_fifty_one_bit_int; - othercases begin cur_val:=-1; cur_val1:=-1; end; - endcases; - end; -if cur_val<0 then begin @; - cur_val1:=0; - end; -small_fam(p):=(cur_val div @"10000) mod @"100; -small_char(p):=qi(cur_val mod @"10000); -large_fam(p):=(cur_val1 div @"10000) mod @"100; -large_char(p):=qi(cur_val1 mod @"10000); -end; - -@ @= -begin print_err("Missing delimiter (. inserted)"); -@.Missing delimiter...@> -help6("I was expecting to see something like `(' or `\{' or")@/ - ("`\}' here. If you typed, e.g., `{' instead of `\{', you")@/ - ("should probably delete the `{' by typing `1' now, so that")@/ - ("braces don't get unbalanced. Otherwise just proceed.")@/ - ("Acceptable delimiters are characters whose \delcode is")@/ - ("nonnegative, or you can use `\delimiter '."); -back_error; cur_val:=0; -end - -@ @= -mmode+radical:math_radical; - -@ @= -procedure math_radical; -begin tail_append(new_node(radical_noad,normal)); -vmem(nucleus(tail)).hh:=empty_field; -vmem(subscr(tail)).hh:=empty_field; -vmem(supscr(tail)).hh:=empty_field; -scan_delimiter(left_delimiter(tail),cur_chr+1); -scan_math(nucleus(tail)); -end; - -@ @= +mmode+radical: math_radical; mmode+accent,mmode+math_accent:math_ac; - -@ @= -procedure math_ac; -begin if cur_cmd=accent then - @; -tail_append(new_node(accent_noad,normal)); -vmem(nucleus(tail)).hh:=empty_field; -vmem(subscr(tail)).hh:=empty_field; -vmem(supscr(tail)).hh:=empty_field; -math_type(accent_chr(tail)):=math_char; -if cur_chr=0 then scan_fifteen_bit_int -else scan_big_fifteen_bit_int; -mcharacter(accent_chr(tail)):=qi(cur_val mod @"1000); -if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam -else fam(accent_chr(tail)):=(cur_val div @"10000) mod @"100; -scan_math(nucleus(tail)); -end; - -@ @= -begin print_err("Please use "); print_esc("mathaccent"); -print(" for accents in math mode"); -@.Please use \\mathaccent...@> -help2("I'm changing \accent to \mathaccent here; wish me luck.")@/ - ("(Accents are not the same in formulas as they are in text.)"); -error; -end - -@ @= mmode+vcenter: begin scan_spec(vcenter_group,false); normal_paragraph; - push_nest; mode:=-vmode; prev_depth:=ignore_depth; + push_nest; mode:=-vmode; prev_depth:=pdf_ignored_dimen; if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text); end; @ @= vcenter_group: begin line_break_context:=vcenter_group; end_graf; unsave; save_ptr:=save_ptr-2; p:=vpack(vlink(head),saved(1),saved(0)); pop_nest; - tail_append(new_noad); type(tail):=vcenter_noad; - math_type(nucleus(tail)):=sub_box; vinfo(nucleus(tail)):=p; + p:=math_vcenter_group(p); + tail_append(p); end; @ The routine that inserts a |style_node| holds no surprises. @= -primitive("displaystyle",math_style,display_style); +primitive_tex("displaystyle",math_style,display_style,0); @!@:display_style_}{\.{\\displaystyle} primitive@> -primitive("textstyle",math_style,text_style); +primitive_tex("textstyle",math_style,text_style,0); @!@:text_style_}{\.{\\textstyle} primitive@> -primitive("scriptstyle",math_style,script_style); +primitive_tex("scriptstyle",math_style,script_style,0); @!@:script_style_}{\.{\\scriptstyle} primitive@> -primitive("scriptscriptstyle",math_style,script_script_style); +primitive_tex("scriptscriptstyle",math_style,script_script_style,0); @!@:script_script_style_}{\.{\\scriptscriptstyle} primitive@> - -@ @= -math_style: print_style(chr_code); +primitive_luatex("crampeddisplaystyle",math_style,cramped_display_style,0); +@!@:cramped_display_style_}{\.{\\crampeddisplaystyle} primitive@> +primitive_luatex("crampedtextstyle",math_style,cramped_text_style,0); +@!@:cramped_text_style_}{\.{\\crampedtextstyle} primitive@> +primitive_luatex("crampedscriptstyle",math_style,cramped_script_style,0); +@!@:cramped_script_style_}{\.{\\crampedscriptstyle} primitive@> +primitive_luatex("crampedscriptscriptstyle",math_style,cramped_script_script_style,0); +@!@:cramped_script_script_style_}{\.{\\crampedscriptscriptstyle} primitive@> @ @= mmode+math_style: tail_append(new_style(cur_chr)); @@ -27219,531 +23896,58 @@ mmode+non_script: begin tail_append(new_glue(zero_glue)); end; mmode+math_choice: append_choices; -@ The routine that scans the four mlists of a \.{\\mathchoice} is very -much like the routine that builds discretionary nodes. - -@= -procedure append_choices; -begin tail_append(new_choice); incr(save_ptr); saved(-1):=0; -push_math(math_choice_group); scan_left_brace; -end; - @ @= math_choice_group: build_choices; -@ @= -procedure build_choices; -label exit; -var p:pointer; {the current mlist} -begin @; p:=fin_mlist(null); -case saved(-1) of -0:display_mlist(tail):=p; -1:text_mlist(tail):=p; -2:script_mlist(tail):=p; -3:begin script_script_mlist(tail):=p; decr(save_ptr); return; - end; -end; {there are no other cases} -incr(saved(-1)); push_math(math_choice_group); scan_left_brace; -exit:end; - -@ Subscripts and superscripts are attached to the previous nucleus by the -@^superscripts@>@^subscripts@> -action procedure called |sub_sup|. We use the facts that |sub_mark=sup_mark+1| -and |subscr(p)=supscr(p)+1|. - -@= +@ @= mmode+sub_mark,mmode+sup_mark: sub_sup; -@ @= -procedure sub_sup; -var t:small_number; {type of previous sub/superscript} -@!p:pointer; {field to be filled by |scan_math|} -begin t:=empty; p:=null; -if tail<>head then if scripts_allowed(tail) then - begin p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|} - t:=math_type(p); - end; -if (p=null)or(t<>empty) then @; -scan_math(p); -end; - -@ @= -begin tail_append(new_noad); -p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|} -if t<>empty then - begin if cur_cmd=sup_mark then - begin print_err("Double superscript"); -@.Double superscript@> - help1("I treat `x^1^2' essentially like `x^1{}^2'."); - end - else begin print_err("Double subscript"); -@.Double subscript@> - help1("I treat `x_1_2' essentially like `x_1{}_2'."); - end; - error; - end; -end - -@ An operation like `\.{\\over}' causes the current mlist to go into a -state of suspended animation: |incompleat_noad| points to a |fraction_noad| -that contains the mlist-so-far as its numerator, while the denominator -is yet to come. Finally when the mlist is finished, the denominator will -go into the incompleat fraction noad, and that noad will become the -whole formula, unless it is surrounded by `\.{\\left}' and `\.{\\right}' -delimiters. - +@ @d above_code=0 { `\.{\\above}' } @d over_code=1 { `\.{\\over}' } @d atop_code=2 { `\.{\\atop}' } @d delimited_code=3 { `\.{\\abovewithdelims}', etc.} @= -primitive("above",above,above_code);@/ +primitive_tex("above",above,above_code,0);@/ @!@:above_}{\.{\\above} primitive@> -primitive("over",above,over_code);@/ +primitive_tex("over",above,over_code,0);@/ @!@:over_}{\.{\\over} primitive@> -primitive("atop",above,atop_code);@/ +primitive_tex("atop",above,atop_code,0);@/ @!@:atop_}{\.{\\atop} primitive@> -primitive("abovewithdelims",above,delimited_code+above_code);@/ +primitive_tex("abovewithdelims",above,delimited_code+above_code,0);@/ @!@:above_with_delims_}{\.{\\abovewithdelims} primitive@> -primitive("overwithdelims",above,delimited_code+over_code);@/ +primitive_tex("overwithdelims",above,delimited_code+over_code,0);@/ @!@:over_with_delims_}{\.{\\overwithdelims} primitive@> -primitive("atopwithdelims",above,delimited_code+atop_code); +primitive_tex("atopwithdelims",above,delimited_code+atop_code,0); @!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@> -@ @= -above: case chr_code of - over_code:print_esc("over"); - atop_code:print_esc("atop"); - delimited_code+above_code:print_esc("abovewithdelims"); - delimited_code+over_code:print_esc("overwithdelims"); - delimited_code+atop_code:print_esc("atopwithdelims"); - othercases print_esc("above") - endcases; - @ @= mmode+above: math_fraction; -@ @= -procedure math_fraction; -var c:small_number; {the type of generalized fraction we are scanning} -begin c:=cur_chr; -if incompleat_noad<>null then - @ -else begin incompleat_noad:=new_node(fraction_noad,normal); - math_type(numerator(incompleat_noad)):=sub_mlist; - vinfo(numerator(incompleat_noad)):=vlink(head); - vmem(denominator(incompleat_noad)).hh:=empty_field; - vmem(left_delimiter(incompleat_noad)).qqqq:=null_delimiter; - vmem(right_delimiter(incompleat_noad)).qqqq:=null_delimiter;@/ - vlink(head):=null; tail:=head; - @; - end; -end; - -@ @= -if c>=delimited_code then - begin scan_delimiter(left_delimiter(incompleat_noad),false); - scan_delimiter(right_delimiter(incompleat_noad),false); - end; -case c mod delimited_code of -above_code: begin scan_normal_dimen; - thickness(incompleat_noad):=cur_val; - end; -over_code: thickness(incompleat_noad):=default_code; -atop_code: thickness(incompleat_noad):=0; -end {there are no other cases} - -@ @= -begin if c>=delimited_code then - begin scan_delimiter(garbage,false); scan_delimiter(garbage,false); - end; -if c mod delimited_code=above_code then scan_normal_dimen; -print_err("Ambiguous; you need another { and }"); -@.Ambiguous...@> -help3("I'm ignoring this fraction specification, since I don't")@/ - ("know whether a construction like `x \over y \over z'")@/ - ("means `{x \over y} \over z' or `x \over {y \over z}'."); -error; -end - -@ At the end of a math formula or subformula, the |fin_mlist| routine is -called upon to return a pointer to the newly completed mlist, and to -pop the nest back to the enclosing semantic level. The parameter to -|fin_mlist|, if not null, points to a |right_noad| that ends the -current mlist; this |right_noad| has not yet been appended. - -@= -function fin_mlist(@!p:pointer):pointer; -var q:pointer; {the mlist to return} -begin if incompleat_noad<>null then @ -else begin vlink(tail):=p; q:=vlink(head); - end; -pop_nest; fin_mlist:=q; -end; - -@ @= -begin math_type(denominator(incompleat_noad)):=sub_mlist; -vinfo(denominator(incompleat_noad)):=vlink(head); -if p=null then q:=incompleat_noad -else begin q:=vinfo(numerator(incompleat_noad)); - if (type(q)<>left_noad)or(delim_ptr=null) then confusion("right"); -@:this can't happen right}{\quad right@> - vinfo(numerator(incompleat_noad)):=vlink(delim_ptr); - vlink(delim_ptr):=incompleat_noad; vlink(incompleat_noad):=p; - end; -end - -@ Now at last we're ready to see what happens when a right brace occurs -in a math formula. Two special cases are simplified here: Braces are effectively -removed when they surround a single Ord without sub/superscripts, or when they -surround an accent that is the nucleus of an Ord atom. - -@= -math_group: begin @; decr(save_ptr);@/ - math_type(saved(0)):=sub_mlist; p:=fin_mlist(null); vinfo(saved(0)):=p; - if p<>null then if vlink(p)=null then - if type(p)=ord_noad then - begin if math_type(subscr(p))=empty then - if math_type(supscr(p))=empty then - begin vmem(saved(0)).hh:=vmem(nucleus(p)).hh; - flush_node(p); - end; - end - else if type(p)=accent_noad then if saved(0)=nucleus(tail) then - if type(tail)=ord_noad then @; - end; - -@ @= -begin q:=head; while vlink(q)<>tail do q:=vlink(q); -vlink(q):=p; flush_node(tail); tail:=p; -end +@ @= +math_group: close_math_group(p); -@ We have dealt with all constructions of math mode except `\.{\\left}' and -`\.{\\right}', so the picture is completed by the following sections of -the program. +@ @= -primitive("left",left_right,left_noad); +primitive_tex("left",left_right,left_noad_side,0); @!@:left_}{\.{\\left} primitive@> -primitive("right",left_right,right_noad); +primitive_tex("right",left_right,right_noad_side,0); @!@:right_}{\.{\\right} primitive@> +primitive_tex("middle",left_right,middle_noad_side,0); +@!@:middle_}{\.{\\middle} primitive@> text(frozen_right):="right"; eqtb[frozen_right]:=eqtb[cur_val]; -@ @= -left_right: if chr_code=left_noad then print_esc("left") -@/@@/ -else print_esc("right"); - @ @= mmode+left_right: math_left_right; -@ @= -procedure math_left_right; -var t:small_number; {|left_noad| or |right_noad|} -@!p:pointer; {new noad} -@!q:pointer; {resulting mlist} -begin t:=cur_chr; -if (t<>left_noad)and(cur_group<>math_left_group) then - @ -else begin p:=new_noad; type(p):=t; - scan_delimiter(delimiter(p),false); - if t=middle_noad then - begin type(p):=right_noad; subtype(p):=middle_noad; - end; - if t=left_noad then q:=p - else begin q:=fin_mlist(p); - @; {end of |math_left_group|} - end; - if t<>right_noad then - begin push_math(math_left_group); vlink(head):=q; tail:=p; - delim_ptr:=p; - end - else begin - tail_append(new_noad); type(tail):=inner_noad; - math_type(nucleus(tail)):=sub_mlist; - vinfo(nucleus(tail)):=q; - end; - end; -end; - -@ @= -begin if cur_group=math_shift_group then - begin scan_delimiter(garbage,false); - print_err("Extra "); - if t=middle_noad then - begin print_esc("middle"); -@.Extra \\middle.@> - help1("I'm ignoring a \middle that had no matching \left."); - end - else begin print_esc("right"); -@.Extra \\right.@> - help1("I'm ignoring a \right that had no matching \left."); - end; - error; - end -else off_save; -end - @ Here is the only way out of math mode. @= mmode+math_shift: if cur_group=math_shift_group then after_math else off_save; -@ @= -procedure after_math; -var l:boolean; {`\.{\\leqno}' instead of `\.{\\eqno}'} -@!danger:boolean; {not enough symbol fonts are present} -@!m:integer; {|mmode| or |-mmode|} -@!p:pointer; {the formula} -@!a:pointer; {box containing equation number} -@@; -begin danger:=false; -@; -m:=mode; l:=false; p:=fin_mlist(null); {this pops the nest} -if mode=-m then {end of equation number} - begin @; - cur_mlist:=p; cur_style:=text_style; mlist_penalties:=false; - mlist_to_hlist; a:=hpack(vlink(temp_head),natural); - @; - decr(save_ptr); {now |cur_group=math_shift_group|} - if saved(0)=1 then l:=true; - danger:=false; - @; - m:=mode; p:=fin_mlist(null); - end -else a:=null; -if m<0 then @ -else begin if a=null then @; - @; - end; -end; - -@ @= -if (font_params(fam_fnt(2+text_size)) - help3("Sorry, but I can't typeset math unless \textfont 2")@/ - ("and \scriptfont 2 and \scriptscriptfont 2 have all")@/ - ("the \fontdimen values needed in math symbol fonts."); - error; flush_math; danger:=true; - end -else if (font_params(fam_fnt(3+text_size)) = -begin tail_append(new_math(math_surround,before)); -if dir_math_save then - @; -cur_mlist:=p; cur_style:=text_style; mlist_penalties:=(mode>0); mlist_to_hlist; -vlink(tail):=vlink(temp_head); -while vlink(tail)<>null do tail:=vlink(tail); -if dir_math_save then - @; -dir_math_save:=false; -tail_append(new_math(math_surround,after)); -space_factor:=1000; -@; -end - -@ \TeX\ gets to the following part of the program when the first `\.\$' ending -a display has been scanned. - -@= -begin get_x_token; -if cur_cmd<>math_shift then - begin print_err("Display math should end with $$"); -@.Display math...with \$\$@> - help2("The `$' that I just saw supposedly matches a previous `$$'.")@/ - ("So I shall assume that you typed `$$' both times."); - back_error; - end; -end - -@ We have saved the worst for last: The fussiest part of math mode processing -occurs when a displayed formula is being centered and placed with an optional -equation number. - -@= -@!b:pointer; {box containing the equation} -@!w:scaled; {width of the equation} -@!z:scaled; {width of the line} -@!e:scaled; {width of equation number} -@!q:scaled; {width of equation number plus space to separate from equation} -@!d:scaled; {displacement of equation in the line} -@!s:scaled; {move the line right this much} -@!g1,@!g2:small_number; {glue parameter codes for before and after} -@!r:pointer; {kern node used to position the display} -@!t:pointer; {tail of adjustment list} -@!pre_t:pointer; {tail of pre-adjustment list} - -@ At this time |p| points to the mlist for the formula; |a| is either -|null| or it points to a box containing the equation number; and we are in -vertical mode (or internal vertical mode). - -@= -cur_mlist:=p; cur_style:=display_style; mlist_penalties:=false; -mlist_to_hlist; p:=vlink(temp_head);@/ -adjust_tail:=adjust_head; pre_adjust_tail:=pre_adjust_head; -b:=hpack(p,natural); p:=list_ptr(b); -t:=adjust_tail; adjust_tail:=null;@/ -pre_t:=pre_adjust_tail; pre_adjust_tail:=null;@/ -w:=width(b); z:=display_width; s:=display_indent; -if (a=null)or danger then - begin e:=0; q:=0; - end -else begin e:=width(a); q:=e+math_quad(text_size); - end; -if w+q>z then - @; -@; -@; -@; -@; -resume_after_display - -@ @= -procedure resume_after_display; -begin if cur_group<>math_shift_group then confusion("display"); -@:this can't happen display}{\quad display@> -@; -prev_graf:=prev_graf+3; -push_nest; mode:=hmode; space_factor:=1000; -@; -@; -if nest_ptr=1 then begin check_filter('after_display'); build_page; end; -end; - -@ The user can force the equation number to go on a separate line -by causing its width to be zero. - -@= -begin if (e<>0)and((w-total_shrink[normal]+q<=z)or@| - (total_shrink[sfi]<>0)or(total_shrink[fil]<>0)or - (total_shrink[fill]<>0)or(total_shrink[filll]<>0)) then - begin list_ptr(b):=null; flush_node(b); - b:=hpack(p,z-q,exactly); - end -else begin e:=0; - if w>z then - begin - list_ptr(b):=null; flush_node(b); - b:=hpack(p,z,exactly); - end; - end; -w:=width(b); -end - -@ We try first to center the display without regard to the existence of -the equation number. If that would make it too close (where ``too close'' -means that the space between display and equation number is less than the -width of the equation number), we either center it in the remaining space -or move it as far from the equation number as possible. The latter alternative -is taken only if the display begins with glue, since we assume that the -user put glue there to control the spacing precisely. - -@= -d:=half(z-w); -if (e>0)and(d<2*e) then {too close} - begin d:=half(z-w-e); - if p<>null then if not is_char_node(p) then if type(p)=glue_node then d:=0; - end - -@ If the equation number is set on a line by itself, either before or -after the formula, we append an infinite penalty so that no page break will -separate the display from its number; and we use the same size and -displacement for all three potential lines of the display, even though -`\.{\\parshape}' may specify them differently. - -@= -tail_append(new_penalty(pre_display_penalty));@/ -if (d+s<=pre_display_size)or l then {not enough clearance} - begin g1:=above_display_skip_code; g2:=below_display_skip_code; - end -else begin g1:=above_display_short_skip_code; - g2:=below_display_short_skip_code; - end; -if l and(e=0) then {it follows that |type(a)=hlist_node|} - begin shift_amount(a):=s; append_to_vlist(a); - tail_append(new_penalty(inf_penalty)); - end -else tail_append(new_param_glue(g1)) - -@ @= -if e<>0 then - begin r:=new_kern(z-w-e-d); - if l then - begin vlink(a):=r; vlink(r):=b; b:=a; d:=0; - end - else begin vlink(b):=r; vlink(r):=a; - end; - b:=hpack(b,natural); - end; -shift_amount(b):=s+d; append_to_vlist(b) - -@ @= -if (a<>null)and(e=0)and not l then - begin tail_append(new_penalty(inf_penalty)); - shift_amount(a):=s+z-width(a); - append_to_vlist(a); - g2:=0; - end; -if t<>adjust_head then {migrating material comes after equation number} - begin vlink(tail):=vlink(adjust_head); tail:=t; - end; -if pre_t<>pre_adjust_head then - begin vlink(tail):=vlink(pre_adjust_head); tail:=pre_t; - end; -tail_append(new_penalty(post_display_penalty)); -if g2>0 then tail_append(new_param_glue(g2)) - -@ When \.{\\halign} appears in a display, the alignment routines operate -essentially as they do in vertical mode. Then the following program is -activated, with |p| and |q| pointing to the beginning and end of the -resulting list, and with |aux_save| holding the |prev_depth| value. - -@= -begin do_assignments; -if cur_cmd<>math_shift then @ -else @; -pop_nest; -tail_append(new_penalty(pre_display_penalty)); -tail_append(new_param_glue(above_display_skip_code)); -vlink(tail):=p; -if p<>null then tail:=q; -tail_append(new_penalty(post_display_penalty)); -tail_append(new_param_glue(below_display_skip_code)); -prev_depth:=aux_save.sc; resume_after_display; -end - -@ @= -begin print_err("Missing $$ inserted"); -@.Missing {\$\$} inserted@> -help2("Displays can use special alignments (like \eqalignno)")@/ - ("only if nothing but the alignment itself is between $$'s."); -back_error; -end @* \[49] Mode-independent processing. The long |main_control| procedure has now been fully specified, except for @@ -27761,31 +23965,21 @@ by adding the corresponding codes. (\PASCAL's |set| operations could also have been used.) @= -primitive("long",prefix,1); +primitive_tex("long",prefix,1,0); @!@:long_}{\.{\\long} primitive@> -primitive("outer",prefix,2); +primitive_tex("outer",prefix,2,0); @!@:outer_}{\.{\\outer} primitive@> -primitive("global",prefix,4); +primitive_tex("global",prefix,4,0); @!@:global_}{\.{\\global} primitive@> -primitive("def",def,0); +primitive_tex("def",def,0,0); @!@:def_}{\.{\\def} primitive@> -primitive("gdef",def,1); +primitive_tex("gdef",def,1,0); @!@:gdef_}{\.{\\gdef} primitive@> -primitive("edef",def,2); +primitive_tex("edef",def,2,0); @!@:edef_}{\.{\\edef} primitive@> -primitive("xdef",def,3); +primitive_tex("xdef",def,3,0); @!@:xdef_}{\.{\\xdef} primitive@> -@ @= -prefix: if chr_code=1 then print_esc("long") - else if chr_code=2 then print_esc("outer") - @/@@/ - else print_esc("global"); -def: if chr_code=0 then print_esc("def") - else if chr_code=1 then print_esc("gdef") - else if chr_code=2 then print_esc("edef") - else print_esc("xdef"); - @ Every prefix, and every command code that might or might not be prefixed, calls the action procedure |prefixed_command|. This routine accumulates a sequence of prefixes until coming to a non-prefix, then it carries out @@ -27807,13 +24001,18 @@ any_mode(set_prev_graf), any_mode(set_page_dimen), any_mode(set_page_int), any_mode(set_box_dimen), -any_mode(set_shape), -any_mode(def_code), -any_mode(extdef_code), +any_mode(set_tex_shape), +any_mode(set_etex_shape), +any_mode(def_char_code), +any_mode(def_del_code), +any_mode(extdef_math_code), +any_mode(extdef_del_code), any_mode(def_family), +any_mode(set_math_param), any_mode(set_font), any_mode(def_font), any_mode(letterspace_font), +any_mode(pdf_copy_font), any_mode(register), any_mode(advance), any_mode(multiply), @@ -27849,6 +24048,7 @@ var a:small_number; {accumulated prefix codes so far} @!p,@!q:pointer; {for temporary short-term use} @!n:integer; {ditto} @!e:boolean; {should a definition be expanded? or was \.{\\let} not done?} +@!mval:mathcodeval; {for handling of \.{\\mathchardef}s} begin a:=0; while cur_cmd=prefix do begin if not odd(a div cur_chr) then a:=a+cur_chr; @@ -27871,7 +24071,7 @@ exit:end; begin print_err("You can't use a prefix with `"); @.You can't use a prefix with x@> print_cmd_chr(cur_cmd,cur_chr); print_char("'"); -help1("I'll pretend you didn't say \long or \outer or \global."); +help1("I'll pretend you didn't say \long or \outer or \global or \protected."); back_error; return; end @@ -27895,10 +24095,6 @@ since the following routines test for the \.{\\global} prefix as follows. @d global==(a>=4) @d define(#)==if global then geq_define(#)@+else eq_define(#) @d word_define(#)==if global then geq_word_define(#)@+else eq_word_define(#) -@d define_math_code(#)==if global - then set_math_code(#,level_one)@+else set_math_code(#,cur_level) -@d define_del_code(#)==if global - then set_del_code(#,level_one)@+else set_del_code(#,cur_level) @d define_lc_code(#)==if global then set_lc_code(#,level_one)@+else set_lc_code(#,cur_level) @d define_uc_code(#)==if global @@ -27907,6 +24103,11 @@ since the following routines test for the \.{\\global} prefix as follows. then set_sf_code(#,level_one)@+else set_sf_code(#,cur_level) @d define_cat_code(#)==if global then set_cat_code(cat_code_table,#,level_one)@+else set_cat_code(cat_code_table,#,cur_level) +@d define_fam_fnt(#)==if global + then def_fam_fnt(#,level_one)@+else def_fam_fnt(#,cur_level) +@d define_math_param(#)==if global + then def_math_param(#,level_one)@+else def_math_param(#,cur_level) + @= if global_defs<>0 then @@ -27952,17 +24153,76 @@ function is_dim_assign(cmd:halfword):boolean; begin is_dim_assign := (cmd=assign_dimen); end; -procedure assign_internal_int(cmd:halfword;value:integer); -var a:small_number; -begin - a:=0; - word_define(cmd,value); -end; -procedure assign_internal_dim(cmd:halfword;value:integer); -var a:small_number; + +@ @= +procedure assign_internal_value(a:small_number;p:halfword;cur_val:integer); +var n:halfword; begin - a:=0; - word_define(cmd,value); +if (p>=int_base)and(pcat_code_table then + word_define(p,cur_val); + end + else begin + print_err("Invalid \catcode table"); + help2("You can only switch to a \catcode table that is initialized") + ("using \savecatcodetable or \initcatcodetable, or to table 0"); + error; + end; + end + else if (p=(int_base+output_box_code)and((cur_val>65535)or(cur_val<0))) then begin + print_err("Invalid \outputbox"); + help1("The value for \outputbox has to be between 0 and 65535."); + error; + end + else if ((p=new_line_char)and((cur_val>127)or(cur_val<0))) then begin + print_err("Invalid \newlinechar"); + help1("The value for \newlinechar has to be between 0 and 127."); + error; + end + else if p=end_line_char then begin + if (cur_val<0)or(cur_val>biggest_char) then + word_define(p,-1) + else + word_define(p,13); + end + else + word_define(p,cur_val); +{If we are defining subparagraph penalty levels while we are +in hmode, then we put out a whatsit immediately, otherwise +we leave it alone. This mechanism might not be sufficiently +powerful, and some other algorithm, searching down the stack, +might be necessary. Good first step.} + if (abs(mode)=hmode) and + ((p=(int_base+local_inter_line_penalty_code)) or + (p=(int_base+local_broken_penalty_code))) then begin + @; + eq_word_define(int_base+no_local_whatsits_code,no_local_whatsits+1); + end; + if p=int_base+language_code then word_define(int_base+cur_lang_code,cur_val); + end +else if (p>=dimen_base)and(p=0) then a:=a+4; @ Both \.{\\let} and \.{\\futurelet} share the command code |let|. @= -primitive("let",let,normal);@/ +primitive_tex("let",let,normal,0);@/ @!@:let_}{\.{\\let} primitive@> -primitive("futurelet",let,normal+1);@/ +primitive_tex("futurelet",let,normal+1,0);@/ @!@:future_let_}{\.{\\futurelet} primitive@> -@ @= -let: if chr_code<>normal then print_esc("futurelet")@+else print_esc("let"); - @ @= let: begin n:=cur_chr; get_r_token; p:=cur_cs; @@ -28026,52 +24283,36 @@ corresponding |chr| is the |eqtb| location of the internal register in question. @d char_def_code=0 {|shorthand_def| for \.{\\chardef}} @d math_char_def_code=1 {|shorthand_def| for \.{\\mathchardef}} @d omath_char_def_code=2 {|shorthand_def| for \.{\\omathchardef}} -@d count_def_code=3 {|shorthand_def| for \.{\\countdef}} -@d attribute_def_code=4 {|shorthand_def| for \.{\\attributedef}} -@d dimen_def_code=5 {|shorthand_def| for \.{\\dimendef}} -@d skip_def_code=6 {|shorthand_def| for \.{\\skipdef}} -@d mu_skip_def_code=7 {|shorthand_def| for \.{\\muskipdef}} -@d toks_def_code=8 {|shorthand_def| for \.{\\toksdef}} +@d xmath_char_def_code=3 {|shorthand_def| for \.{\\Umathchardef}} +@d count_def_code=4 {|shorthand_def| for \.{\\countdef}} +@d attribute_def_code=5 {|shorthand_def| for \.{\\attributedef}} +@d dimen_def_code=6 {|shorthand_def| for \.{\\dimendef}} +@d skip_def_code=7 {|shorthand_def| for \.{\\skipdef}} +@d mu_skip_def_code=8 {|shorthand_def| for \.{\\muskipdef}} +@d toks_def_code=9 {|shorthand_def| for \.{\\toksdef}} @= -primitive("chardef",shorthand_def,char_def_code);@/ +primitive_tex("chardef",shorthand_def,char_def_code,0);@/ @!@:char_def_}{\.{\\chardef} primitive@> -primitive("mathchardef",shorthand_def,math_char_def_code);@/ +primitive_tex("mathchardef",shorthand_def,math_char_def_code,0);@/ @!@:math_char_def_}{\.{\\mathchardef} primitive@> -primitive("omathchardef",shorthand_def,omath_char_def_code);@/ +primitive_omega("omathchardef",shorthand_def,omath_char_def_code,0);@/ @!@:math_char_def_}{\.{\\omathchardef} primitive@> -primitive("countdef",shorthand_def,count_def_code);@/ +primitive_luatex("Umathchardef",shorthand_def,xmath_char_def_code,0);@/ +@!@:math_char_def_}{\.{\\Umathchardef} primitive@> +primitive_tex("countdef",shorthand_def,count_def_code,0);@/ @!@:count_def_}{\.{\\countdef} primitive@> -primitive("attributedef",shorthand_def,attribute_def_code);@/ +primitive_luatex("attributedef",shorthand_def,attribute_def_code,0);@/ @!@:attribute_def_}{\.{\\attributedef} primitive@> -primitive("dimendef",shorthand_def,dimen_def_code);@/ +primitive_tex("dimendef",shorthand_def,dimen_def_code,0);@/ @!@:dimen_def_}{\.{\\dimendef} primitive@> -primitive("skipdef",shorthand_def,skip_def_code);@/ +primitive_tex("skipdef",shorthand_def,skip_def_code,0);@/ @!@:skip_def_}{\.{\\skipdef} primitive@> -primitive("muskipdef",shorthand_def,mu_skip_def_code);@/ +primitive_tex("muskipdef",shorthand_def,mu_skip_def_code,0);@/ @!@:mu_skip_def_}{\.{\\muskipdef} primitive@> -primitive("toksdef",shorthand_def,toks_def_code);@/ +primitive_tex("toksdef",shorthand_def,toks_def_code,0);@/ @!@:toks_def_}{\.{\\toksdef} primitive@> -@ @= -shorthand_def: case chr_code of - char_def_code: print_esc("chardef"); - math_char_def_code: print_esc("mathchardef"); - omath_char_def_code: print_esc("omathchardef"); - count_def_code: print_esc("countdef"); - attribute_def_code: print_esc("attributedef"); - dimen_def_code: print_esc("dimendef"); - skip_def_code: print_esc("skipdef"); - mu_skip_def_code: print_esc("muskipdef"); - othercases print_esc("toksdef") - endcases; -char_given: begin print_esc("char"); print_hex(chr_code); - end; -math_given: begin print_esc("mathchar"); print_hex(chr_code); - end; -omath_given: begin print_esc("omathchar"); print_hex(chr_code); - end; - @ We temporarily define |p| to be |relax|, so that an occurrence of |p| while scanning the definition will simply stop the scanning instead of producing an ``undefined control sequence'' error or expanding the @@ -28083,12 +24324,21 @@ shorthand_def: begin n:=cur_chr; get_r_token; p:=cur_cs; case n of char_def_code: begin scan_char_num; define(p,char_given,cur_val); end; - math_char_def_code: begin scan_real_fifteen_bit_int; + math_char_def_code: begin + mval:=scan_mathchar(tex_mathcode); + cur_val:=(mval.class_value*16+mval.family_value)*256+mval.character_value; define(p,math_given,cur_val); end; - omath_char_def_code: begin scan_big_fifteen_bit_int; + omath_char_def_code: begin + mval:=scan_mathchar(aleph_mathcode); + cur_val:=(mval.class_value*256+mval.family_value)*65536+mval.character_value; define(p,omath_given,cur_val); end; + xmath_char_def_code: begin + mval:=scan_mathchar(xetex_mathcode); + cur_val:=(mval.class_value+(8*mval.family_value))*(65536*32)+mval.character_value; + define(p,xmath_given,cur_val); + end; othercases begin scan_register_num; case n of count_def_code: define(p,assign_int,count_base+cur_val); @@ -28104,7 +24354,8 @@ shorthand_def: begin n:=cur_chr; get_r_token; p:=cur_cs; @ @= read_to_cs: begin j:=cur_chr; scan_int; n:=cur_val; - if not scan_keyword("to") then + if not scan_keyword('to') then +@.to@> begin print_err("Missing `to' inserted"); @.Missing `to'...@> help2("You should have said `\read to \cs'.")@/ @@ -28160,45 +24411,8 @@ end @= assign_int: begin p:=cur_chr; scan_optional_equals; scan_int; - if p=(int_base+cat_code_table_code) then begin - if valid_catcode_table(cur_val) then begin - if cur_val<>cat_code_table then - word_define(p,cur_val); - end - else begin - print_err("Invalid \catcode table"); - help2("You can only switch to a \catcode table that is initialized") - ("using \savecatcodetable or \initcatcodetable, or to table 0"); - error; - end; - end - else if (p=new_line_char)and(cur_val>127) then begin - print_err("Invalid \newlinechar"); - help1("The value for \newlinechar has to be between 0 and 127."); - error; - end - else if p=end_line_char then begin - if (cur_val<0)or(cur_val>biggest_char) then - word_define(p,-1) - else - word_define(p,13); - end - else - word_define(p,cur_val); -{If we are defining subparagraph penalty levels while we are -in hmode, then we put out a whatsit immediately, otherwise -we leave it alone. This mechanism might not be sufficiently -powerful, and some other algorithm, searching down the stack, -might be necessary. Good first step.} - if (abs(mode)=hmode) and - ((p=(int_base+local_inter_line_penalty_code)) or - (p=(int_base+local_broken_penalty_code))) then begin - @; - eq_word_define(int_base+no_local_whatsits_code,no_local_whatsits+1); - local_par_bool:=true; - end; - if p=int_base+language_code then word_define(int_base+cur_lang_code,cur_val); - end; + assign_internal_value(a,p,cur_val); + end; assign_attr: begin p:=cur_chr; scan_optional_equals; scan_int; if (p-attribute_base)>max_used_attr then max_used_attr:=(p-attribute_base); attr_list_cache:=cache_disabled; @@ -28207,7 +24421,7 @@ assign_dir: begin @ end; assign_dimen: begin p:=cur_chr; scan_optional_equals; - scan_normal_dimen; word_define(p,cur_val); + scan_normal_dimen; assign_internal_value(a,p,cur_val); end; assign_glue,assign_mu_glue: begin p:=cur_chr; n:=cur_cmd; scan_optional_equals; if n=assign_mu_glue then scan_glue(mu_val)@+else scan_glue(glue_val); @@ -28231,39 +24445,146 @@ end; and the font families are declared by |def_family|. @= -primitive("catcode",def_code,cat_code_base); +primitive_tex("catcode",def_char_code,cat_code_base,cat_code_base); @!@:cat_code_}{\.{\\catcode} primitive@> -primitive("mathcode",def_code,math_code_base); +primitive_tex("mathcode",def_char_code,math_code_base,cat_code_base); @!@:math_code_}{\.{\\mathcode} primitive@> -primitive("lccode",def_code,lc_code_base); +primitive_tex("lccode",def_char_code,lc_code_base,cat_code_base); @!@:lc_code_}{\.{\\lccode} primitive@> -primitive("uccode",def_code,uc_code_base); +primitive_tex("uccode",def_char_code,uc_code_base,cat_code_base); @!@:uc_code_}{\.{\\uccode} primitive@> -primitive("sfcode",def_code,sf_code_base); +primitive_tex("sfcode",def_char_code,sf_code_base,cat_code_base); @!@:sf_code_}{\.{\\sfcode} primitive@> -primitive("delcode",def_code,del_code_base); +primitive_tex("delcode",def_del_code,del_code_base,del_code_base); @!@:del_code_}{\.{\\delcode} primitive@> -primitive("textfont",def_family,math_font_base); +primitive_tex("textfont",def_family,text_size,0); @!@:text_font_}{\.{\\textfont} primitive@> -primitive("scriptfont",def_family,math_font_base+script_size); +primitive_tex("scriptfont",def_family,script_size,0); @!@:script_font_}{\.{\\scriptfont} primitive@> -primitive("scriptscriptfont",def_family,math_font_base+script_script_size); +primitive_tex("scriptscriptfont",def_family,script_script_size,0); @!@:script_script_font_}{\.{\\scriptscriptfont} primitive@> -primitive("omathcode",extdef_code,math_code_base); +primitive_luatex("Umathquad", set_math_param, math_param_quad,0); +primitive_luatex("Umathaxis", set_math_param, math_param_axis,0); +primitive_luatex("Umathoperatorsize", set_math_param, math_param_operator_size,0); +primitive_luatex("Umathoverbarkern", set_math_param, math_param_overbar_kern,0); +primitive_luatex("Umathoverbarrule", set_math_param, math_param_overbar_rule,0); +primitive_luatex("Umathoverbarvgap", set_math_param, math_param_overbar_vgap,0); +primitive_luatex("Umathunderbarkern", set_math_param, math_param_underbar_kern,0); +primitive_luatex("Umathunderbarrule", set_math_param, math_param_underbar_rule,0); +primitive_luatex("Umathunderbarvgap", set_math_param, math_param_underbar_vgap,0); +primitive_luatex("Umathradicalkern", set_math_param, math_param_radical_kern,0); +primitive_luatex("Umathradicalrule", set_math_param, math_param_radical_rule,0); +primitive_luatex("Umathradicalvgap", set_math_param, math_param_radical_vgap,0); +primitive_luatex("Umathradicaldegreebefore",set_math_param, math_param_radical_degree_before,0); +primitive_luatex("Umathradicaldegreeafter", set_math_param, math_param_radical_degree_after,0); +primitive_luatex("Umathradicaldegreeraise", set_math_param, math_param_radical_degree_raise,0); +primitive_luatex("Umathstackvgap", set_math_param, math_param_stack_vgap,0); +primitive_luatex("Umathstacknumup", set_math_param, math_param_stack_num_up,0); +primitive_luatex("Umathstackdenomdown", set_math_param, math_param_stack_denom_down,0); +primitive_luatex("Umathfractionrule", set_math_param, math_param_fraction_rule,0); +primitive_luatex("Umathfractionnumvgap", set_math_param, math_param_fraction_num_vgap,0); +primitive_luatex("Umathfractionnumup", set_math_param, math_param_fraction_num_up,0); +primitive_luatex("Umathfractiondenomvgap",set_math_param, math_param_fraction_denom_vgap,0); +primitive_luatex("Umathfractiondenomdown",set_math_param, math_param_fraction_denom_down,0); +primitive_luatex("Umathfractiondelsize", set_math_param, math_param_fraction_del_size,0); +primitive_luatex("Umathlimitabovevgap", set_math_param, math_param_limit_above_vgap,0); +primitive_luatex("Umathlimitabovebgap", set_math_param, math_param_limit_above_bgap,0); +primitive_luatex("Umathlimitabovekern", set_math_param, math_param_limit_above_kern,0); +primitive_luatex("Umathlimitdownvgap", set_math_param, math_param_limit_below_vgap,0); +primitive_luatex("Umathlimitdownbgap", set_math_param, math_param_limit_below_bgap,0); +primitive_luatex("Umathlimitdownkern", set_math_param, math_param_limit_below_kern,0); +primitive_luatex("Umathunderdelimitervgap", set_math_param, math_param_under_delimiter_vgap,0); +primitive_luatex("Umathunderdelimiterbgap", set_math_param, math_param_under_delimiter_bgap,0); +primitive_luatex("Umathoverdelimitervgap",set_math_param, math_param_over_delimiter_vgap,0); +primitive_luatex("Umathoverdelimiterbgap",set_math_param, math_param_over_delimiter_bgap,0); +primitive_luatex("Umathsubshiftdrop", set_math_param, math_param_sub_shift_drop,0); +primitive_luatex("Umathsupshiftdrop", set_math_param, math_param_sup_shift_drop,0); +primitive_luatex("Umathsubshiftdown", set_math_param, math_param_sub_shift_down,0); +primitive_luatex("Umathsubsupshiftdown", set_math_param, math_param_sub_sup_shift_down,0); +primitive_luatex("Umathsubtopmax", set_math_param, math_param_sub_top_max,0); +primitive_luatex("Umathsupshiftup", set_math_param, math_param_sup_shift_up,0); +primitive_luatex("Umathsupbottommin", set_math_param, math_param_sup_bottom_min,0); +primitive_luatex("Umathsupsubbottommax", set_math_param, math_param_sup_sub_bottom_max,0); +primitive_luatex("Umathsubsupvgap", set_math_param, math_param_subsup_vgap,0); +primitive_luatex("Umathspaceafterscript", set_math_param, math_param_space_after_script,0); +primitive_luatex("Umathconnectoroverlapmin", set_math_param, math_param_connector_overlap_min,0); +primitive_luatex("Umathordordspacing", set_math_param, math_param_ord_ord_spacing,0); +primitive_luatex("Umathordopspacing", set_math_param, math_param_ord_op_spacing,0); +primitive_luatex("Umathordbinspacing", set_math_param, math_param_ord_bin_spacing,0); +primitive_luatex("Umathordrelspacing", set_math_param, math_param_ord_rel_spacing,0); +primitive_luatex("Umathordopenspacing", set_math_param, math_param_ord_open_spacing,0); +primitive_luatex("Umathordclosespacing", set_math_param, math_param_ord_close_spacing,0); +primitive_luatex("Umathordpunctspacing", set_math_param, math_param_ord_punct_spacing,0); +primitive_luatex("Umathordinnerspacing", set_math_param, math_param_ord_inner_spacing,0); +primitive_luatex("Umathopordspacing", set_math_param, math_param_op_ord_spacing,0); +primitive_luatex("Umathopopspacing", set_math_param, math_param_op_op_spacing,0); +primitive_luatex("Umathopbinspacing", set_math_param, math_param_op_bin_spacing,0); +primitive_luatex("Umathoprelspacing", set_math_param, math_param_op_rel_spacing,0); +primitive_luatex("Umathopopenspacing", set_math_param, math_param_op_open_spacing,0); +primitive_luatex("Umathopclosespacing", set_math_param, math_param_op_close_spacing,0); +primitive_luatex("Umathoppunctspacing", set_math_param, math_param_op_punct_spacing,0); +primitive_luatex("Umathopinnerspacing", set_math_param, math_param_op_inner_spacing,0); +primitive_luatex("Umathbinordspacing", set_math_param, math_param_bin_ord_spacing,0); +primitive_luatex("Umathbinopspacing", set_math_param, math_param_bin_op_spacing,0); +primitive_luatex("Umathbinbinspacing", set_math_param, math_param_bin_bin_spacing,0); +primitive_luatex("Umathbinrelspacing", set_math_param, math_param_bin_rel_spacing,0); +primitive_luatex("Umathbinopenspacing", set_math_param, math_param_bin_open_spacing,0); +primitive_luatex("Umathbinclosespacing", set_math_param, math_param_bin_close_spacing,0); +primitive_luatex("Umathbinpunctspacing", set_math_param, math_param_bin_punct_spacing,0); +primitive_luatex("Umathbininnerspacing", set_math_param, math_param_bin_inner_spacing,0); +primitive_luatex("Umathrelordspacing", set_math_param, math_param_rel_ord_spacing,0); +primitive_luatex("Umathrelopspacing", set_math_param, math_param_rel_op_spacing,0); +primitive_luatex("Umathrelbinspacing", set_math_param, math_param_rel_bin_spacing,0); +primitive_luatex("Umathrelrelspacing", set_math_param, math_param_rel_rel_spacing,0); +primitive_luatex("Umathrelopenspacing", set_math_param, math_param_rel_open_spacing,0); +primitive_luatex("Umathrelclosespacing", set_math_param, math_param_rel_close_spacing,0); +primitive_luatex("Umathrelpunctspacing", set_math_param, math_param_rel_punct_spacing,0); +primitive_luatex("Umathrelinnerspacing", set_math_param, math_param_rel_inner_spacing,0); +primitive_luatex("Umathopenordspacing", set_math_param, math_param_open_ord_spacing,0); +primitive_luatex("Umathopenopspacing", set_math_param, math_param_open_op_spacing,0); +primitive_luatex("Umathopenbinspacing", set_math_param, math_param_open_bin_spacing,0); +primitive_luatex("Umathopenrelspacing", set_math_param, math_param_open_rel_spacing,0); +primitive_luatex("Umathopenopenspacing", set_math_param, math_param_open_open_spacing,0); +primitive_luatex("Umathopenclosespacing", set_math_param, math_param_open_close_spacing,0); +primitive_luatex("Umathopenpunctspacing", set_math_param, math_param_open_punct_spacing,0); +primitive_luatex("Umathopeninnerspacing", set_math_param, math_param_open_inner_spacing,0); +primitive_luatex("Umathcloseordspacing", set_math_param, math_param_close_ord_spacing,0); +primitive_luatex("Umathcloseopspacing", set_math_param, math_param_close_op_spacing,0); +primitive_luatex("Umathclosebinspacing", set_math_param, math_param_close_bin_spacing,0); +primitive_luatex("Umathcloserelspacing", set_math_param, math_param_close_rel_spacing,0); +primitive_luatex("Umathcloseopenspacing", set_math_param, math_param_close_open_spacing,0); +primitive_luatex("Umathcloseclosespacing",set_math_param, math_param_close_close_spacing,0); +primitive_luatex("Umathclosepunctspacing",set_math_param, math_param_close_punct_spacing,0); +primitive_luatex("Umathcloseinnerspacing",set_math_param, math_param_close_inner_spacing,0); +primitive_luatex("Umathpunctordspacing", set_math_param, math_param_punct_ord_spacing,0); +primitive_luatex("Umathpunctopspacing", set_math_param, math_param_punct_op_spacing,0); +primitive_luatex("Umathpunctbinspacing", set_math_param, math_param_punct_bin_spacing,0); +primitive_luatex("Umathpunctrelspacing", set_math_param, math_param_punct_rel_spacing,0); +primitive_luatex("Umathpunctopenspacing", set_math_param, math_param_punct_open_spacing,0); +primitive_luatex("Umathpunctclosespacing",set_math_param, math_param_punct_close_spacing,0); +primitive_luatex("Umathpunctpunctspacing",set_math_param, math_param_punct_punct_spacing,0); +primitive_luatex("Umathpunctinnerspacing",set_math_param, math_param_punct_inner_spacing,0); +primitive_luatex("Umathinnerordspacing", set_math_param, math_param_inner_ord_spacing,0); +primitive_luatex("Umathinneropspacing", set_math_param, math_param_inner_op_spacing,0); +primitive_luatex("Umathinnerbinspacing", set_math_param, math_param_inner_bin_spacing,0); +primitive_luatex("Umathinnerrelspacing", set_math_param, math_param_inner_rel_spacing,0); +primitive_luatex("Umathinneropenspacing", set_math_param, math_param_inner_open_spacing,0); +primitive_luatex("Umathinnerclosespacing",set_math_param, math_param_inner_close_spacing,0); +primitive_luatex("Umathinnerpunctspacing",set_math_param, math_param_inner_punct_spacing,0); +primitive_luatex("Umathinnerinnerspacing",set_math_param, math_param_inner_inner_spacing,0); +primitive_omega("omathcode",extdef_math_code,math_code_base,math_code_base); @!@:math_code_}{\.{\\omathcode} primitive@> -primitive("odelcode",extdef_code,del_code_base); +primitive_omega("odelcode",extdef_del_code,del_code_base,del_code_base); @!@:del_code_}{\.{\\odelcode} primitive@> +primitive_luatex("Umathcode",extdef_math_code,math_code_base+1,math_code_base); +@!@:math_code_}{\.{\\Umathcode} primitive@> +primitive_luatex("Udelcode",extdef_del_code,del_code_base+1,del_code_base); +@!@:del_code_}{\.{\\Udelcode} primitive@> +primitive_luatex("Umathcodenum",extdef_math_code,math_code_base+2,math_code_base); +@!@:math_code_}{\.{\\Umathcodenum} primitive@> +primitive_luatex("Udelcodenum",extdef_del_code,del_code_base+2,del_code_base); +@!@:del_code_}{\.{\\Udelcodenum} primitive@> -@ @= -def_code: if chr_code=cat_code_base then print_esc("catcode") - else if chr_code=math_code_base then print_esc("mathcode") - else if chr_code=lc_code_base then print_esc("lccode") - else if chr_code=uc_code_base then print_esc("uccode") - else if chr_code=sf_code_base then print_esc("sfcode") - else print_esc("delcode"); -extdef_code: if chr_code=math_code_base then print_esc("omathcode") - else print_esc("odelcode"); -def_family: print_size(chr_code-math_font_base); @ The different types of code values have different legal ranges; the following program is careful to check each case properly. @@ -28280,18 +24601,12 @@ following program is careful to check each case properly. @= -def_code: begin @; +def_char_code,def_del_code: begin + @; p:=cur_chr; if cur_chr=math_code_base then begin - scan_char_num; p:= cur_val; - scan_optional_equals; - scan_int; - check_def_code(math_code_base); - if cur_val=@"8000 then cur_val:=@"8000000 - else cur_val:=((cur_val div @"1000) * @"1000000) + - (((cur_val mod @"1000) div @"100) * @"10000) + - (cur_val mod @"100); - define_math_code(p,cur_val); + if global then cur_val1:=level_one else cur_val1:=cur_level; + scan_extdef_math_code(cur_val1,tex_mathcode); end else if cur_chr=lc_code_base then begin scan_char_num; p:= cur_val; @@ -28322,56 +24637,63 @@ def_code: begin @; define_cat_code(p,cur_val); end else if cur_chr=del_code_base then begin - scan_char_num; p:= cur_val; - scan_optional_equals; - scan_int; - check_def_code(del_code_base); - cur_val1:=cur_val div @"1000; - cur_val1:=(cur_val1 div @"100)*@"10000 + (cur_val1 mod @"100); - cur_val:=cur_val mod @"1000; - cur_val:=(cur_val div @"100)*@"10000 + (cur_val mod @"100); - define_del_code(p,cur_val1,cur_val); - end; - end; -extdef_code: begin - if cur_chr=del_code_base then begin - p:=cur_chr; scan_char_num; p:=p+cur_val; scan_optional_equals; - scan_int; cur_val1:=cur_val; scan_int; {backwards} - if (cur_val1>@"FFFFFF) or (cur_val>@"FFFFFF) then - begin print_err("Invalid code ("); print_int(cur_val1); print(" "); - print_int(cur_val); - print("), should be at most ""FFFFFF ""FFFFFF"); - help1("I'm going to use 0 instead of that illegal code value.");@/ - error; cur_val1:=0; cur_val:=0; - end; - define_del_code(p,cur_val1,cur_val); - end - else begin - p:=cur_chr; scan_char_num; p:=cur_val; scan_optional_equals; - scan_int; - if (cur_val>@"8000000) then - begin print_err("Invalid code ("); print_int(cur_val); -@.Invalid code@> - print("), should be at most "); print_int(@"8000000); - help1("I'm going to use 0 instead of that illegal code value.");@/ - error; cur_val:=0; - end; - define_math_code(p,cur_val); - end; + if global then cur_val1:=level_one else cur_val1:=cur_level; + scan_extdef_del_code(cur_val1,tex_mathcode); + end; + end; +extdef_math_code, extdef_del_code: begin + if global then cur_val1:=level_one else cur_val1:=cur_level; + if cur_chr=math_code_base then + scan_extdef_math_code(cur_val1,aleph_mathcode) + else if cur_chr=math_code_base+1 then + scan_extdef_math_code(cur_val1,xetex_mathcode) + else if cur_chr=math_code_base+2 then + scan_extdef_math_code(cur_val1,xetexnum_mathcode) + else if cur_chr=del_code_base then + scan_extdef_del_code(cur_val1,aleph_mathcode) + else if cur_chr=del_code_base+1 then + scan_extdef_del_code(cur_val1,xetex_mathcode) + else if cur_chr=del_code_base+2 then + scan_extdef_del_code(cur_val1,xetexnum_mathcode); end; + @ @= if cur_chr=cat_code_base then n:=max_char_code else if cur_chr=lc_code_base then n:=biggest_char else if cur_chr=uc_code_base then n:=biggest_char -else if cur_chr=math_code_base then n:=@'100000 else if cur_chr=sf_code_base then n:=@'77777 -else if cur_chr=del_code_base then n:=@'77777777 else n:=biggest_char @ @= -def_family: begin p:=cur_chr; scan_math_family_int; p:=p+cur_val; - scan_optional_equals; scan_font_ident; define(p,data,cur_val); +def_family: begin p:=cur_chr; scan_math_family_int; cur_val1:=cur_val; + scan_optional_equals; scan_font_ident; + define_fam_fnt(cur_val1,p,cur_val); + end; +set_math_param: begin p:=cur_chr; get_token; + if cur_cmd<>math_style then begin + print_err("Missing math style, treated as \displaystyle"); +@.Missing number...@> + help1("A style should have been here; I inserted `\displaystyle'."); + cur_val1:=display_style; + back_error; + end + else + cur_val1:=cur_chr; + scan_optional_equals; + if p; if q=register then scan_optional_equals -else if scan_keyword("by") then do_nothing; {optional `\.{by}'} +else if scan_keyword('by') then do_nothing; {optional `\.{by}'} +@.by@> arith_error:=false; if q @@ -28399,6 +24722,7 @@ if arith_error then @.Arithmetic overflow@> help2("I can't carry out that multiplication or division,")@/ ("since the result is out of range."); + if p>=glue_val then delete_glue_ref(cur_val); error; return; end; if pmax_used_attr then max_used_attr:=(l-attribute_base); attr_list_cache:=cache_disabled; end; - word_define(l,cur_val); + if (p=int_val) or (p=dimen_val) then + assign_internal_value(a,l,cur_val) + else + word_define(l,cur_val); end else begin trap_zero_glue; define(l,glue_ref,cur_val); end; exit: end; -@ Here we use the fact that the consecutive codes |int_val...mu_val| and +@ Here we use the fact that the consecutive codes |int_val..mu_val| and |assign_int..assign_mu_glue| correspond to each other nicely. @= @@ -28584,20 +24911,10 @@ end; @ Paragraph shapes are set up in an obvious way. It needs one word more than in \TeX, though. -@d shape_node=54 { storage for shape pointers } - @= -set_shape: begin q:=cur_chr; scan_optional_equals; scan_int; n:=cur_val; +set_tex_shape: begin q:=cur_chr; scan_optional_equals; scan_int; n:=cur_val; if n<=0 then p:=null - else if q>par_shape_loc then - begin n:=(cur_val div 2)+1; p:=new_node(shape_node,2*n+1+1); vinfo(p+1):=n; - n:=cur_val; vmem(p+2).int:=n; {number of penalties} - for j:=p+3 to p+n+2 do - begin scan_int; vmem(j).int:=cur_val; {penalty values} - end; - if not odd(n) then vmem(p+n+3).int:=0; {unused} - end - else begin p:=new_node(shape_node,2*(n+1)+1); vinfo(p+1):=n; + else begin p:=new_node(shape_node,2*(n+1)+1); vinfo(p+1):=n; for j:=1 to n do begin scan_normal_dimen; vmem(p+2*j).sc:=cur_val; {indentation} @@ -28607,26 +24924,33 @@ set_shape: begin q:=cur_chr; scan_optional_equals; scan_int; n:=cur_val; end; define(q,shape_ref,p); end; +set_etex_shape: begin q:=cur_chr; scan_optional_equals; scan_int; n:=cur_val; + if n<=0 then p:=null + else begin n:=(cur_val div 2)+1; p:=new_node(shape_node,2*n+1+1); vinfo(p+1):=n; + n:=cur_val; vmem(p+2).int:=n; {number of penalties} + for j:=p+3 to p+n+2 do + begin scan_int; vmem(j).int:=cur_val; {penalty values} + end; + if not odd(n) then vmem(p+n+3).int:=0; {unused} + end; + define(q,shape_ref,p); + end; @ New language information data is loaded by the |hyph_data| command. @= -primitive("hyphenation",hyph_data,0); +primitive_tex("hyphenation",hyph_data,0,0); @!@:hyphenation_}{\.{\\hyphenation} primitive@> -primitive("patterns",hyph_data,1); +primitive_tex("patterns",hyph_data,1,0); @!@:patterns_}{\.{\\patterns} primitive@> -primitive("prehyphenchar",hyph_data,2); +primitive_luatex("prehyphenchar",hyph_data,2,0); @!@:prehyphenchar_}{\.{\\prehyphenchar} primitive@> -primitive("posthyphenchar",hyph_data,3); +primitive_luatex("posthyphenchar",hyph_data,3,0); @!@:posthyphenchar_}{\.{\\posthyphenchar} primitive@> - -@ @= -hyph_data: case cur_chr of - 0: print_esc("hyphenation"); - 1: print_esc("patterns"); - 2: print_esc("prehyphenchar"); - 3: print_esc("posthyphenchar"); - endcases; +primitive_luatex("preexhyphenchar",hyph_data,4,0); +@!@:preexhyphenchar_}{\.{\\preexhyphenchar} primitive@> +primitive_luatex("postexhyphenchar",hyph_data,5,0); +@!@:postexhyphenchar_}{\.{\\postexhyphenchar} primitive@> @ @= hyph_data: begin @@ -28635,6 +24959,8 @@ hyph_data: begin 1: new_patterns; 2: new_pre_hyphen_char; 3: new_post_hyphen_char; + 4: new_pre_exhyphen_char; + 5: new_post_exhyphen_char; endcases; goto done; end; @@ -28664,158 +24990,38 @@ assign_font_int: begin end; @ @= -primitive("hyphenchar",assign_font_int,0); +primitive_tex("hyphenchar",assign_font_int,0,0); @!@:hyphen_char_}{\.{\\hyphenchar} primitive@> -primitive("skewchar",assign_font_int,1); +primitive_tex("skewchar",assign_font_int,1,0); @!@:skew_char_}{\.{\\skewchar} primitive@> -primitive("lpcode",assign_font_int,lp_code_base); +primitive_pdftex("lpcode",assign_font_int,lp_code_base,0); @!@:lp_code_}{\.{\\lpcode} primitive@> -primitive("rpcode",assign_font_int,rp_code_base); +primitive_pdftex("rpcode",assign_font_int,rp_code_base,0); @!@:rp_code_}{\.{\\rpcode} primitive@> -primitive("efcode",assign_font_int,ef_code_base); +primitive_pdftex("efcode",assign_font_int,ef_code_base,0); @!@:ef_code_}{\.{\\efcode} primitive@> -primitive("tagcode",assign_font_int,tag_code); +primitive_pdftex("tagcode",assign_font_int,tag_code,0); @!@:tag_code_}{\.{\\tagcode} primitive@> -primitive("pdfnoligatures",assign_font_int,no_lig_code); +primitive_pdftex("pdfnoligatures",assign_font_int,no_lig_code,0); @!@:no_lig_code_}{\.{\\pdfnoligatures} primitive@> -@ @= -assign_font_int: case chr_code of -0: print_esc("hyphenchar"); -1: print_esc("skewchar"); -lp_code_base: print_esc("lpcode"); -rp_code_base: print_esc("rpcode"); -ef_code_base: print_esc("efcode"); -tag_code: print_esc("tagcode"); -no_lig_code: print_esc("pdfnoligatures"); -endcases; - @ Here is where the information for a new font gets loaded. @= -def_font: def_new_font(a); +def_font: tex_def_font(a); {in C} letterspace_font: new_letterspaced_font(a); - -@ @= -procedure def_new_font(@!a:small_number); -var u:pointer; {user's font identifier} -@!s:scaled; {stated ``at'' size, or negative of scaled magnification} -@!f:internal_font_number; {runs through existing fonts} -@!t:str_number; {name for the frozen font identifier} -@!old_setting:0..max_selector; {holds |selector| setting} -@!offset:integer; -@!natural_dir:integer;{the natural direction of the font} -@!flushable_string:str_number; {string not yet referenced} -@!junk:pointer; -begin if job_name=0 then open_log_file; - {avoid confusing \.{texput} with the font name} -@.texput@> -get_r_token; u:=cur_cs; -if u>=hash_base then t:=text(u) -else if u=null_cs then t:="FONT" -else begin old_setting:=selector; selector:=new_string; - print("FONT"); print(u-active_base); selector:=old_setting; -@.FONTx@> - str_room(1); t:=make_string; - end; -define(u,set_font,null_font); scan_optional_equals; -@; -if cur_cmd<>left_brace then begin - back_input; - scan_file_name; - end -else begin - back_input; - junk:=scan_toks(false,true); - old_setting:=selector; selector:=new_string; - token_show(def_ref); selector:=old_setting; - flush_list(def_ref); - str_room(1); - cur_name:=make_string; - cur_ext:=""; - cur_area:=""; - end; -@; -name_in_progress:=true; -if scan_keyword("offset") then begin - scan_int; - offset:=cur_val; - if (cur_val<0) then begin - print_err("Illegal offset has been changed to 0"); - help1("The offset must be bigger than 0."); int_error(cur_val); - offset:=0; - end - end -else offset:=0; -if scan_keyword("naturaldir") then begin - scan_direction; - natural_dir:=cur_val; - end -else natural_dir:=-1; -name_in_progress:=false; -if cur_area = "" then - f:=read_font_info(u,cur_name,"",s,natural_dir) -else - f:=read_font_info(u,cur_name,cur_area,s,natural_dir); -equiv(u):=f; eqtb[font_id_base+f]:=eqtb[u]; font_id_text(f):=t; -end; - -@ @= -name_in_progress:=true; {this keeps |cur_name| from being changed} -if scan_keyword("at") then @ -@.at@> -else if scan_keyword("scaled") then -@.scaled@> - begin scan_int; s:=-cur_val; - if (cur_val<=0)or(cur_val>32768) then - begin print_err("Illegal magnification has been changed to 1000");@/ -@.Illegal magnification...@> - help1("The magnification ratio must be between 1 and 32768."); - int_error(cur_val); s:=-1000; - end; - end -else s:=-1000; -name_in_progress:=false - -@ @= -begin scan_normal_dimen; s:=cur_val; -if (s<=0)or(s>=@'1000000000) then - begin print_err("Improper `at' size ("); - print_scaled(s); print("pt), replaced by 10pt"); -@.Improper `at' size...@> - help2("I can only handle fonts at positive sizes that are")@/ - ("less than 2048pt, so I've changed what you said to 10pt."); - error; s:=10*unity; - end; -end - - -@ @= -set_font:begin print("select font "); print_font_name(chr_code); - if font_size(chr_code)<>font_dsize(chr_code) then - begin print(" at "); print_scaled(font_size(chr_code)); - print("pt"); - end; - end; +pdf_copy_font: make_font_copy(a); @ @= -primitive("batchmode",set_interaction,batch_mode); +primitive_tex("batchmode",set_interaction,batch_mode,0); @!@:batch_mode_}{\.{\\batchmode} primitive@> -primitive("nonstopmode",set_interaction,nonstop_mode); +primitive_tex("nonstopmode",set_interaction,nonstop_mode,0); @!@:nonstop_mode_}{\.{\\nonstopmode} primitive@> -primitive("scrollmode",set_interaction,scroll_mode); +primitive_tex("scrollmode",set_interaction,scroll_mode,0); @!@:scroll_mode_}{\.{\\scrollmode} primitive@> -primitive("errorstopmode",set_interaction,error_stop_mode); +primitive_tex("errorstopmode",set_interaction,error_stop_mode,0); @!@:error_stop_mode_}{\.{\\errorstopmode} primitive@> -@ @= -set_interaction: case chr_code of - batch_mode: print_esc("batchmode"); - nonstop_mode: print_esc("nonstopmode"); - scroll_mode: print_esc("scrollmode"); - othercases print_esc("errorstopmode") - endcases; - @ @= set_interaction: new_interaction; @@ -28865,15 +25071,11 @@ any_mode(after_group):begin get_token; save_for_after(cur_tok); @ Files for \.{\\read} are opened and closed by the |in_stream| command. @= -primitive("openin",in_stream,1); +primitive_tex("openin",in_stream,1,0); @!@:open_in_}{\.{\\openin} primitive@> -primitive("closein",in_stream,0); +primitive_tex("closein",in_stream,0,0); @!@:close_in_}{\.{\\closein} primitive@> -@ @= -in_stream: if chr_code=0 then print_esc("closein") - else print_esc("openin"); - @ @= any_mode(in_stream): open_or_close_in; @@ -28903,15 +25105,11 @@ current mode. any_mode(message):issue_message; @ @= -primitive("message",message,0); +primitive_tex("message",message,0,0); @!@:message_}{\.{\\message} primitive@> -primitive("errmessage",message,1); +primitive_tex("errmessage",message,1,0); @!@:err_message_}{\.{\\errmessage} primitive@> -@ @= -message: if chr_code=0 then print_esc("message") - else print_esc("errmessage"); - @ @= procedure issue_message; var old_setting:0..max_selector; {holds |selector| setting} @@ -28971,15 +25169,11 @@ building a token list and then changing the cases of the letters in it. any_mode(case_shift):shift_case; @ @= -primitive("lowercase",case_shift,lc_code_base); +primitive_tex("lowercase",case_shift,lc_code_base,lc_code_base); @!@:lowercase_}{\.{\\lowercase} primitive@> -primitive("uppercase",case_shift,uc_code_base); +primitive_tex("uppercase",case_shift,uc_code_base,lc_code_base); @!@:uppercase_}{\.{\\uppercase} primitive@> -@ @= -case_shift:if chr_code=lc_code_base then print_esc("lowercase") - else print_esc("uppercase"); - @ @= procedure shift_case; var b:pointer; {|lc_code_base| or |uc_code_base|} @@ -28996,22 +25190,26 @@ back_list(link(def_ref)); free_avail(def_ref); {omit reference count} end; @ When the case of a |chr_code| changes, we don't change the |cmd|. -We also change active characters, using the fact that -|cs_token_flag+active_base| is a multiple of~|string_offset|. -@^data structure assumptions@> +We also change active characters. @= t:=info(p); -if t0 then info(p):=t-c+i; - end - else - begin if get_lc_code(c)<>0 then info(p):=t-c+get_lc_code(c); end; + if b=uc_code_base then + i:=get_uc_code(c) + else + i:=get_lc_code(c); + if i<>0 then info(p):=t-c+i; end +else if is_active_csname(t-cs_token_flag) then begin + c:=active_csname_value(t-cs_token_flag); + if b=uc_code_base then + i:=get_uc_code(c) + else + i:= get_lc_code(c); + if i<>0 then info(p):=active_to_cs(i,true)+cs_token_flag; +end @ We come finally to the last pieces missing from |main_control|, namely the `\.{\\show}' commands that are useful when debugging. @@ -29025,24 +25223,15 @@ any_mode(xray): show_whatever; @d show_lists=3 { \.{\\showlists} } @= -primitive("show",xray,show_code); +primitive_tex("show",xray,show_code,0); @!@:show_}{\.{\\show} primitive@> -primitive("showbox",xray,show_box_code); +primitive_tex("showbox",xray,show_box_code,0); @!@:show_box_}{\.{\\showbox} primitive@> -primitive("showthe",xray,show_the_code); +primitive_tex("showthe",xray,show_the_code,0); @!@:show_the_}{\.{\\showthe} primitive@> -primitive("showlists",xray,show_lists); +primitive_tex("showlists",xray,show_lists,0); @!@:show_lists_}{\.{\\showlists} primitive@> -@ @= -xray: case chr_code of - show_box_code:print_esc("showbox"); - show_the_code:print_esc("showthe"); - show_lists:print_esc("showlists"); - @@;@/ - othercases print_esc("show") - endcases; - @ @= procedure show_whatever; label common_ending; @@ -29090,18 +25279,6 @@ if cur_cs<>0 then print_meaning; goto common_ending; end -@ @= -undefined_cs: print("undefined"); -call,long_call,outer_call,long_outer_call: begin n:=cmd-call; - if info(link(chr_code))=protected_token then n:=n+4; - if odd(n div 4) then print_esc("protected"); - if odd(n) then print_esc("long"); - if odd(n div 2) then print_esc("outer"); - if n>0 then print_char(" "); - print("macro"); - end; -end_template: print_esc("outer endtemplate"); - @ @= begin scan_register_num; begin_diagnostic; print_nl("> \box"); print_int(cur_val); print_char("="); @@ -29137,7 +25314,7 @@ so that the inverse relation between them is clear. The global variable |format_ident| is a string that is printed right after the |banner| line when \TeX\ is ready to start. For \.{INITEX} this string says simply `\.{(INITEX)}'; for other versions of \TeX\ it says, -for example, `\.{(preloaded format=plain 82.11.19)}', showing the year, +for example, `\.{(preloaded format=plain 1982.11.19)}', showing the year, month, and day that the format file was created. We have |format_ident=0| before \TeX's tables are loaded. @@ -29171,6 +25348,7 @@ begin @; @; @; @; +@; @; @; @; @@ -29204,8 +25382,10 @@ begin @; @; @; @; +@; @; @; +prev_depth := pdf_ignored_dimen; load_fmt_file:=true; return; {it worked!} bad_fmt: wake_up_terminal; wterm_ln('(Fatal format file error; I''m stymied)'); @@ -29371,7 +25551,7 @@ format file represents $n+m$ consecutive entries of |eqtb|, with |m| extra copies of $x_n$, namely $(x_1,\ldots,x_n,x_n,\ldots,x_n)$. @= -k:=active_base; +k:=null_cs; repeat j:=k; while jeqtb_size @ @= -k:=active_base; +k:=null_cs; repeat undump_int(x); if (x<1)or(k+x>eqtb_size+1) then goto bad_fmt; for j:=k to k+x-1 do undump_wd(eqtb[j]); @@ -29430,8 +25610,7 @@ two words, |p| and |hash[p]|. The hash table is, of course, densely packed for |p>=hash_used|, so the remaining entries are output in a~block. @= -for p:=0 to prim_size do dump_hh(prim[p]); -for p:=0 to prim_size do dump_wd(prim_eqtb[p]); +dump_primitives; dump_int(hash_used); cs_count:=frozen_control_sequence-1-hash_used; for p:=hash_base to hash_used do if text(p)<>0 then begin dump_int(p); dump_hh(hash[p]); incr(cs_count); @@ -29441,8 +25620,7 @@ dump_int(cs_count);@/ print_ln; print_int(cs_count); print(" multiletter control sequences") @ @= -for p:=0 to prim_size do undump_hh(prim[p]); -for p:=0 to prim_size do undump_wd(prim_eqtb[p]); +undump_primitives; undump(hash_base)(frozen_control_sequence)(hash_used); p:=hash_base-1; repeat undump(p+1)(hash_used)(p); undump_hh(hash[p]); until p=hash_used; @@ -29454,13 +25632,15 @@ dump_int(max_font_id); for k:=0 to max_font_id do @; print_ln; print_int(max_font_id); print(" preloaded font"); -if max_font_id<>1 then print_char("s") +if max_font_id<>1 then print_char("s"); +dump_math_data @ @= undump_int(x); set_max_font_id(x); for k:=0 to max_font_id do - @ + @; +undump_math_data @ @= begin dump_font(k); @@ -29548,6 +25728,79 @@ dump_language_data @ @= undump_language_data +@ Store some of the pdftex data structures in the format. The idea here is +to ensure that any data structures referenced from pdftex-specific whatsit +nodes are retained. For the sake of simplicity and speed, all the filled parts +of |pdf_mem| and |obj_tab| are retained, in the present implementation. We also +retain three of the linked lists that start from |head_tab|, so that it is +possible to, say, load an image in the \.{INITEX} run and then reference it in a +\.{VIRTEX} run that uses the dumped format. + +@= +begin +dumpimagemeta; {the image information array } +dump_int(pdf_mem_size); +dump_int(pdf_mem_ptr); +for k:=1 to pdf_mem_ptr-1 do begin + dump_int(pdf_mem[k]); + end; +print_ln; print_int(pdf_mem_ptr-1); print(" words of pdf memory"); +dump_int(obj_tab_size); +dump_int(obj_ptr); +dump_int(sys_obj_ptr); +for k:=1 to sys_obj_ptr do begin + dump_int(obj_tab[k].int0); + dump_int(obj_tab[k].int1); + dump_int(obj_tab[k].int3); + dump_int(obj_tab[k].int4); + end; +print_ln; print_int(sys_obj_ptr); print(" indirect objects"); +dump_int(pdf_obj_count); +dump_int(pdf_xform_count); +dump_int(pdf_ximage_count); +dump_int(head_tab[obj_type_obj]); +dump_int(head_tab[obj_type_xform]); +dump_int(head_tab[obj_type_ximage]); +dump_int(pdf_last_obj); +dump_int(pdf_last_xform); +dump_int(pdf_last_ximage); +end + +@ And restoring the pdftex data structures from the format. The +two function arguments to |undumpimagemeta| have been restored +already in an earlier module. + +@= +begin +undumpimagemeta(pdf_minor_version,pdf_inclusion_errorlevel); {the image information array } +undump_int(pdf_mem_size); +pdf_mem := xreallocarray(pdf_mem, integer, pdf_mem_size); +undump_int(pdf_mem_ptr); +for k:=1 to pdf_mem_ptr-1 do begin + undump_int(pdf_mem[k]); + end; +undump_int(obj_tab_size); +undump_int(obj_ptr); +undump_int(sys_obj_ptr); +for k:=1 to sys_obj_ptr do begin + undump_int(obj_tab[k].int0); + undump_int(obj_tab[k].int1); + obj_tab[k].int2 := -1; + undump_int(obj_tab[k].int3); + undump_int(obj_tab[k].int4); + end; +undump_int(pdf_obj_count); +undump_int(pdf_xform_count); +undump_int(pdf_ximage_count); +undump_int(head_tab[obj_type_obj]); +undump_int(head_tab[obj_type_xform]); +undump_int(head_tab[obj_type_ximage]); +undump_int(pdf_last_obj); +undump_int(pdf_last_xform); +undump_int(pdf_last_ximage); +end + + @ This is also done in C @= @@ -29583,7 +25836,7 @@ if interaction=batch_mode then selector:=log_only else selector:=term_and_log; pack_job_name(format_extension); while not w_open_out(fmt_file) do - prompt_file_name("format file name",format_extension); + prompt_file_name('format file name',format_extension); print_nl("Beginning to dump on file "); @.Beginning to dump...@> slow_print(w_make_name_string(fmt_file)); flush_string; @@ -29673,6 +25926,7 @@ ready_already:=314159; start_of_TEX: @; @; history:=spotless; {ready to go!} +@ main_control; {come to life} final_cleanup; {prepare for death} end_of_TEX: close_files_and_terminate; @@ -29703,6 +25957,8 @@ end; procedure print_version_banner; begin wterm(banner); +wterm(', build '); +do_write_wterm(luatex_svnversion); end; @@ -29723,52 +25979,54 @@ This program doesn't bother to close the input files that may still be open. @= procedure close_files_and_terminate; label done, done1; -var a, b, c, i, j, k, l: integer; {all-purpose index} - is_root: boolean; {|pdf_last_pages| is root of Pages tree?} +var a, b, i, j, k, l: integer; {all-purpose index} is_names: boolean; {flag for name tree output: is it Names or Kids?} root, outlines, threads, names_tree, dests: integer; xref_offset_width, names_head, names_tail: integer; - callback_id:integer; - res:boolean; + callback_id:integer; + res:boolean; begin callback_id:=callback_defined(stop_run_callback); @; @!stat if tracing_stats>0 then if callback_id=0 then @;@;@+tats@/ wake_up_terminal; -if not fixed_pdfoutput_set then +if not fixed_pdfoutput_set then {else there will be an infinite loop in error case} fix_pdfoutput; if fixed_pdfoutput > 0 then begin if history = fatal_error_stop then begin remove_pdffile; print_err(" ==> Fatal error occurred, no output PDF file produced!") - end + end else begin @; - if callback_id=0 then begin - if log_opened then - begin wlog_cr; - wlog_ln('PDF statistics:'); - wlog_ln(' ',obj_ptr:1,' PDF objects out of ',obj_tab_size:1, - ' (max. ',sup_obj_tab_size:1,')'); - if pdf_os_cntr > 0 then begin - wlog(' ',((pdf_os_cntr - 1) * pdf_os_max_objs + pdf_os_objidx + 1):1, - ' compressed objects within ',pdf_os_cntr:1,' object stream'); - if pdf_os_cntr > 1 then - wlog('s'); - wlog_cr; + if callback_id=0 then begin + if log_opened then + begin wlog_cr; + wlog_ln('PDF statistics:'); + wlog_ln(' ',obj_ptr:1,' PDF objects out of ',obj_tab_size:1, + ' (max. ',sup_obj_tab_size:1,')'); + if pdf_os_cntr > 0 then begin + wlog(' ',((pdf_os_cntr - 1) * pdf_os_max_objs + pdf_os_objidx + 1):1, + ' compressed objects within ',pdf_os_cntr:1,' object stream'); + if pdf_os_cntr > 1 then + wlog('s'); + wlog_cr; + end; + wlog_ln(' ',pdf_dest_names_ptr:1,' named destinations out of ',dest_names_size:1, + ' (max. ',sup_dest_names_size:1,')'); + wlog_ln(' ',pdf_mem_ptr:1,' words of extra memory for PDF output out of ',pdf_mem_size:1, + ' (max. ',sup_pdf_mem_size:1,')'); end; - wlog_ln(' ',pdf_dest_names_ptr:1,' named destinations out of ',dest_names_size:1, - ' (max. ',sup_dest_names_size:1,')'); - wlog_ln(' ',pdf_mem_ptr:1,' words of extra memory for PDF output out of ',pdf_mem_size:1, - ' (max. ',sup_pdf_mem_size:1,')'); - end; end; end; end else begin @; end; +@; +free_text_codes; +free_math_codes; if log_opened then begin wlog_cr; selector:=selector-2; if (selector=term_only)and(callback_id=0) then begin @@ -29827,8 +26085,8 @@ while input_ptr>0 do if state=token_list then end_token_list@+else end_file_reading; while open_parens>0 do begin - if tracefilenames then print(" )"); - decr(open_parens); + if tracefilenames then print(" )"); + decr(open_parens); end; if cur_level>level_one then begin print_nl("("); print_esc("end occurred "); @@ -29863,6 +26121,7 @@ if c=1 then delete_split_first_mark(i); delete_split_bot_mark(i); end; for c:=last_box_code to vsplit_code do flush_node_list(disc_ptr[c]); + if last_glue<>max_halfword then delete_glue_ref(last_glue); @; store_fmt_file; return;@+tini@/ print_nl("(\dump is performed only by INITEX)"); return; @@ -29907,7 +26166,7 @@ else buffer[limit]:=end_line_char; fix_date_and_time;@/ random_seed :=(microseconds*1000)+(epochseconds mod 1000000);@/ init_randoms(random_seed);@/ -@; +initialize_math; @; if (locescape) then start_input; {\.{\\input} assumed} @@ -30033,18 +26292,17 @@ case of \.{\\openout}, we need three words and three auxiliary subfields to hold the string numbers for name, area, and extension. @d open_node=0 {|subtype| in whatsits that represent files to \.{\\openout}} -@d open_node_size==4 {number of words in an open/whatsit node} @d write_node=1 {|subtype| in whatsits that represent things to \.{\\write}} -@d write_node_size==3 {number of words in a write/whatsit node} @d close_node=2 {|subtype| in whatsits that represent streams to \.{\\closeout}} -@d close_node_size==3 {number of words in a write/whatsit node} @d special_node=3 {|subtype| in whatsits that represent \.{\\special} things} -@d special_node_size==3 {number of words in a write/whatsit node} -@d dir_node_size=4 {number of words in change direction node} @d dir_dir(#)==vinfo(#+2) {keep the direction to be taken} @d dir_level(#)==vlink(#+2) {the save level at which the direction was defined} @d dir_dvi_ptr(#)==vinfo(#+3) {for reflecting dvi output} @d dir_dvi_h(#)==vlink(#+3) {for reflecting dvi output} +@d dir_box_pos_h(#)==vinfo(#+4) {for reflecting dvi output} +@d dir_box_pos_v(#)==vlink(#+4) {for reflecting dvi output} +@d dir_cur_h(#)==vinfo(#+5) {for reflecting dvi output} +@d dir_cur_v(#)==vlink(#+5) {for reflecting dvi output} @d what_lang(#)==vlink(#+2) {language number, in the range |0..255|} @d what_lhm(#)==type(#+2) {minimum left fragment, in the range |1..63|} @d what_rhm(#)==subtype(#+2) {minimum right fragment, in the range |1..63|} @@ -30132,15 +26390,12 @@ stays the same. @d pdf_annot_node == pdftex_first_extension_code + 7 @d pdf_start_link_node == pdftex_first_extension_code + 8 @d pdf_end_link_node == pdftex_first_extension_code + 9 -@d pdf_end_link_node_size==3 @d pdf_outline_code == pdftex_first_extension_code + 10 @d pdf_dest_node == pdftex_first_extension_code + 11 @d pdf_thread_node == pdftex_first_extension_code + 12 @d pdf_start_thread_node == pdftex_first_extension_code + 13 @d pdf_end_thread_node == pdftex_first_extension_code + 14 -@d pdf_end_thread_node_size==3 @d pdf_save_pos_node == pdftex_first_extension_code + 15 -@d pdf_save_pos_node_size==3 @d pdf_info_code == pdftex_first_extension_code + 16 @d pdf_thread_data_node == pdftex_first_extension_code + 16 @d pdf_catalog_code == pdftex_first_extension_code + 17 @@ -30155,7 +26410,6 @@ stays the same. @d set_random_seed_code == pdftex_first_extension_code + 25 @d pdf_glyph_to_unicode_code == pdftex_first_extension_code + 26 @d late_lua_node == pdftex_first_extension_code + 27 -@d close_lua_node == pdftex_first_extension_code + 28 @d save_cat_code_table_code == pdftex_first_extension_code + 29 @d init_cat_code_table_code == pdftex_first_extension_code + 30 @d pdf_colorstack_node == pdftex_first_extension_code + 31 @@ -30165,94 +26419,95 @@ stays the same. @d pdftex_last_extension_code == pdftex_first_extension_code + 34 @= -primitive("openout",extension,open_node);@/ +primitive_tex("openout",extension,open_node,0);@/ @!@:open_out_}{\.{\\openout} primitive@> -primitive("write",extension,write_node); write_loc:=cur_val;@/ +primitive_tex("write",extension,write_node,0); write_loc:=cur_val;@/ @!@:write_}{\.{\\write} primitive@> -primitive("closeout",extension,close_node);@/ +primitive_tex("closeout",extension,close_node,0);@/ @!@:close_out_}{\.{\\closeout} primitive@> -primitive("special",extension,special_node);@/ +primitive_tex("special",extension,special_node,0);@/ @!@:special_}{\.{\\special} primitive@> -primitive("immediate",extension,immediate_code);@/ +text(frozen_special):="special"; eqtb[frozen_special]:=eqtb[cur_val];@/ +primitive_tex("immediate",extension,immediate_code,0);@/ @!@:immediate_}{\.{\\immediate} primitive@> -primitive("localinterlinepenalty",assign_int,local_inter_line_penalty_code);@/ -primitive("localbrokenpenalty",assign_int,local_broken_penalty_code);@/ -primitive("pagedir",assign_dir,dir_base+page_direction_code);@/ -primitive("bodydir",assign_dir,dir_base+body_direction_code);@/ -primitive("pardir",assign_dir,dir_base+par_direction_code);@/ -primitive("textdir",assign_dir,dir_base+text_direction_code);@/ -primitive("mathdir",assign_dir,dir_base+math_direction_code);@/ -primitive("pagerightoffset",assign_dimen,dimen_base+page_right_offset_code); -primitive("pagebottomoffset",assign_dimen,dimen_base+page_bottom_offset_code); -primitive("pdfliteral",extension,pdf_literal_node);@/ +primitive_omega("localinterlinepenalty",assign_int,int_base+local_inter_line_penalty_code,int_base);@/ +primitive_omega("localbrokenpenalty",assign_int,int_base+local_broken_penalty_code,int_base);@/ +primitive_omega("pagedir",assign_dir,dir_base+page_direction_code,dir_base);@/ +primitive_omega("bodydir",assign_dir,dir_base+body_direction_code,dir_base);@/ +primitive_omega("pardir",assign_dir,dir_base+par_direction_code,dir_base);@/ +primitive_omega("textdir",assign_dir,dir_base+text_direction_code,dir_base);@/ +primitive_omega("mathdir",assign_dir,dir_base+math_direction_code,dir_base);@/ +primitive_luatex("pageleftoffset",assign_dimen,dimen_base+page_left_offset_code,dimen_base); +primitive_luatex("pagetopoffset",assign_dimen,dimen_base+page_top_offset_code,dimen_base); +primitive_aleph("pagerightoffset",assign_dimen,dimen_base+page_right_offset_code,dimen_base); +primitive_aleph("pagebottomoffset",assign_dimen,dimen_base+page_bottom_offset_code,dimen_base); +primitive_pdftex("pdfliteral",extension,pdf_literal_node,0);@/ @!@:pdf_literal_}{\.{\\pdfliteral} primitive@> -primitive("pdfcolorstack",extension,pdf_colorstack_node);@/ +primitive_pdftex("pdfcolorstack",extension,pdf_colorstack_node,0);@/ @!@:pdf_colorstack_}{\.{\\pdfcolorstack} primitive@> -primitive("pdfsetmatrix",extension,pdf_setmatrix_node);@/ +primitive_pdftex("pdfsetmatrix",extension,pdf_setmatrix_node,0);@/ @!@:pdf_setmatrix_}{\.{\\pdfsetmatrix} primitive@> -primitive("pdfsave",extension,pdf_save_node);@/ +primitive_pdftex("pdfsave",extension,pdf_save_node,0);@/ @!@:pdf_save_}{\.{\\pdfsave} primitive@> -primitive("pdfrestore",extension,pdf_restore_node);@/ +primitive_pdftex("pdfrestore",extension,pdf_restore_node,0);@/ @!@:pdf_restore_}{\.{\\pdfrestore} primitive@> -primitive("pdfobj",extension,pdf_obj_code);@/ +primitive_pdftex("pdfobj",extension,pdf_obj_code,0);@/ @!@:pdf_obj_}{\.{\\pdfobj} primitive@> -primitive("pdfrefobj",extension,pdf_refobj_node);@/ +primitive_pdftex("pdfrefobj",extension,pdf_refobj_node,0);@/ @!@:pdf_refobj_}{\.{\\pdfrefobj} primitive@> -primitive("pdfxform",extension,pdf_xform_code);@/ +primitive_pdftex("pdfxform",extension,pdf_xform_code,0);@/ @!@:pdf_xform_}{\.{\\pdfxform} primitive@> -primitive("pdfrefxform",extension,pdf_refxform_node);@/ +primitive_pdftex("pdfrefxform",extension,pdf_refxform_node,0);@/ @!@:pdf_refxform_}{\.{\\pdfrefxform} primitive@> -primitive("pdfximage",extension,pdf_ximage_code);@/ +primitive_pdftex("pdfximage",extension,pdf_ximage_code,0);@/ @!@:pdf_ximage_}{\.{\\pdfximage} primitive@> -primitive("pdfrefximage",extension,pdf_refximage_node);@/ +primitive_pdftex("pdfrefximage",extension,pdf_refximage_node,0);@/ @!@:pdf_refximage_}{\.{\\pdfrefximage} primitive@> -primitive("pdfannot",extension,pdf_annot_node);@/ +primitive_pdftex("pdfannot",extension,pdf_annot_node,0);@/ @!@:pdf_annot_}{\.{\\pdfannot} primitive@> -primitive("pdfstartlink",extension,pdf_start_link_node);@/ +primitive_pdftex("pdfstartlink",extension,pdf_start_link_node,0);@/ @!@:pdf_start_link_}{\.{\\pdfstartlink} primitive@> -primitive("pdfendlink",extension,pdf_end_link_node);@/ +primitive_pdftex("pdfendlink",extension,pdf_end_link_node,0);@/ @!@:pdf_end_link_}{\.{\\pdfendlink} primitive@> -primitive("pdfoutline",extension,pdf_outline_code);@/ +primitive_pdftex("pdfoutline",extension,pdf_outline_code,0);@/ @!@:pdf_outline_}{\.{\\pdfoutline} primitive@> -primitive("pdfdest",extension,pdf_dest_node);@/ +primitive_pdftex("pdfdest",extension,pdf_dest_node,0);@/ @!@:pdf_dest_}{\.{\\pdfdest} primitive@> -primitive("pdfthread",extension,pdf_thread_node);@/ +primitive_pdftex("pdfthread",extension,pdf_thread_node,0);@/ @!@:pdf_thread_}{\.{\\pdfthread} primitive@> -primitive("pdfstartthread",extension,pdf_start_thread_node);@/ +primitive_pdftex("pdfstartthread",extension,pdf_start_thread_node,0);@/ @!@:pdf_start_thread_}{\.{\\pdfstartthread} primitive@> -primitive("pdfendthread",extension,pdf_end_thread_node);@/ +primitive_pdftex("pdfendthread",extension,pdf_end_thread_node,0);@/ @!@:pdf_end_thread_}{\.{\\pdfendthread} primitive@> -primitive("pdfsavepos",extension,pdf_save_pos_node);@/ +primitive_pdftex("pdfsavepos",extension,pdf_save_pos_node,0);@/ @!@:pdf_save_pos_}{\.{\\pdfsavepos} primitive@> -primitive("pdfinfo",extension,pdf_info_code);@/ +primitive_pdftex("pdfinfo",extension,pdf_info_code,0);@/ @!@:pdf_info_}{\.{\\pdfinfo} primitive@> -primitive("pdfcatalog",extension,pdf_catalog_code);@/ +primitive_pdftex("pdfcatalog",extension,pdf_catalog_code,0);@/ @!@:pdf_catalog_}{\.{\\pdfcatalog} primitive@> -primitive("pdfnames",extension,pdf_names_code);@/ +primitive_pdftex("pdfnames",extension,pdf_names_code,0);@/ @!@:pdf_names_}{\.{\\pdfnames} primitive@> -primitive("pdfincludechars",extension,pdf_include_chars_code);@/ +primitive_pdftex("pdfincludechars",extension,pdf_include_chars_code,0);@/ @!@:pdf_include_chars_}{\.{\\pdfincludechars} primitive@> -primitive("pdffontattr",extension,pdf_font_attr_code);@/ +primitive_pdftex("pdffontattr",extension,pdf_font_attr_code,0);@/ @!@:pdf_font_attr_}{\.{\\pdffontattr} primitive@> -primitive("pdfmapfile",extension,pdf_map_file_code);@/ +primitive_pdftex("pdfmapfile",extension,pdf_map_file_code,0);@/ @!@:pdf_map_file_}{\.{\\pdfmapfile} primitive@> -primitive("pdfmapline",extension,pdf_map_line_code);@/ +primitive_pdftex("pdfmapline",extension,pdf_map_line_code,0);@/ @!@:pdf_map_line_}{\.{\\pdfmapline} primitive@> -primitive("pdftrailer",extension,pdf_trailer_code);@/ +primitive_pdftex("pdftrailer",extension,pdf_trailer_code,0);@/ @!@:pdf_trailer_}{\.{\\pdftrailer} primitive@> -primitive("savecatcodetable",extension,save_cat_code_table_code);@/ +primitive_luatex("savecatcodetable",extension,save_cat_code_table_code,0);@/ @!@:save_cat_code_table_}{\.{\\savecatcodetable} primitive@> -primitive("initcatcodetable",extension,init_cat_code_table_code);@/ +primitive_luatex("initcatcodetable",extension,init_cat_code_table_code,0);@/ @!@:init_cat_code_table_}{\.{\\initcatcodetable} primitive@> -primitive("pdfsetrandomseed",extension,set_random_seed_code);@/ +primitive_pdftex("pdfsetrandomseed",extension,set_random_seed_code,0);@/ @!@:set_random_seed_code}{\.{\\pdfsetrandomseed} primitive@> -primitive("latelua",extension,late_lua_node);@/ +primitive_luatex("latelua",extension,late_lua_node,0);@/ @!@:late_lua_node_}{\.{\\latelua} primitive@> -primitive("closelua",extension,close_lua_node);@/ -@!@:close_lua_node_}{\.{\\closelua} primitive@> -primitive("pdffontexpand",extension,pdf_font_expand_code);@/ +primitive_pdftex("pdffontexpand",extension,pdf_font_expand_code,0);@/ @!@:pdf_font_expand_}{\.{\\pdffontexpand} primitive@> -primitive("pdfglyphtounicode",extension,pdf_glyph_to_unicode_code);@/ +primitive_pdftex("pdfglyphtounicode",extension,pdf_glyph_to_unicode_code,0);@/ @!@:pdf_glyph_to_unicode_}{\.{\\pdfglyphtounicode} primitive@> @ The variable |write_loc| just introduced is used to provide an @@ -30261,52 +26516,6 @@ appropriate error message in case of ``runaway'' write texts. @= @!write_loc:pointer; {|eqtb| address of \.{\\write}} -@ @= -extension: case chr_code of - open_node:print_esc("openout"); - write_node:print_esc("write"); - close_node:print_esc("closeout"); - special_node:print_esc("special"); - immediate_code:print_esc("immediate"); - pdf_annot_node: print_esc("pdfannot"); - pdf_catalog_code: print_esc("pdfcatalog"); - pdf_dest_node: print_esc("pdfdest"); - pdf_end_link_node: print_esc("pdfendlink"); - pdf_end_thread_node: print_esc("pdfendthread"); - pdf_font_attr_code: print_esc("pdffontattr"); - pdf_font_expand_code: print_esc("pdffontexpand"); - pdf_include_chars_code: print_esc("pdfincludechars"); - pdf_info_code: print_esc("pdfinfo"); - pdf_literal_node: print_esc("pdfliteral"); - pdf_colorstack_node: print_esc("pdfcolorstack"); - pdf_setmatrix_node: print_esc("pdfsetmatrix"); - pdf_save_node: print_esc("pdfsave"); - pdf_restore_node: print_esc("pdfrestore"); - pdf_map_file_code: print_esc("pdfmapfile"); - pdf_map_line_code: print_esc("pdfmapline"); - pdf_names_code: print_esc("pdfnames"); - pdf_obj_code: print_esc("pdfobj"); - pdf_outline_code: print_esc("pdfoutline"); - pdf_refobj_node: print_esc("pdfrefobj"); - pdf_refxform_node: print_esc("pdfrefxform"); - pdf_refximage_node: print_esc("pdfrefximage"); - pdf_save_pos_node: print_esc("pdfsavepos"); - pdf_start_link_node: print_esc("pdfstartlink"); - pdf_start_thread_node: print_esc("pdfstartthread"); - pdf_thread_node: print_esc("pdfthread"); - pdf_trailer_code: print_esc("pdftrailer"); - pdf_xform_code: print_esc("pdfxform"); - pdf_ximage_code: print_esc("pdfximage"); - save_cat_code_table_code: print_esc("savecatcodetable"); - init_cat_code_table_code: print_esc("initcatcodetable"); - set_random_seed_code: print_esc("pdfsetrandomseed"); - pdf_glyph_to_unicode_code: print_esc("pdfglyphtounicode"); - late_lua_node: print_esc("latelua"); - close_lua_node: print_esc("closelua"); - cancel_boundary_node: print_esc("noboundary"); - othercases print("[unknown extension!]") - endcases; - @ When an |extension| command occurs in |main_control|, in any mode, the |do_extension| routine is called. @@ -30318,6 +26527,7 @@ any_mode(extension):do_extension; procedure do_extension; var i,@!j,@!k:integer; {all-purpose integers} @!p,@!q,@!r:pointer; {all-purpose pointers} +@!sn:integer; {a potential lua state name} begin case cur_chr of open_node:@; write_node:@; @@ -30358,7 +26568,6 @@ begin case cur_chr of set_random_seed_code: @; pdf_glyph_to_unicode_code: @; late_lua_node: @; - close_lua_node: @; othercases confusion("ext1") @:this can't happen ext1}{\quad ext1@> endcases; @@ -30468,9 +26677,9 @@ end; begin check_pdfoutput("\pdfliteral", true); new_whatsit(pdf_literal_node); - if scan_keyword("direct") then + if scan_keyword('direct') then pdf_literal_mode(tail) := direct_always - else if scan_keyword("page") then + else if scan_keyword('page') then pdf_literal_mode(tail) := direct_page else pdf_literal_mode(tail) := set_origin; @@ -30497,20 +26706,20 @@ begin print_err("Invalid negative color stack number"); @.Invalid negative color stack number@> help2("I'll use default color stack 0 here.")@/ - ("Proceed, with fingers corssed."); + ("Proceed, with fingers crossed."); error; cur_val := 0; end; - if scan_keyword("set") then begin + if scan_keyword('set') then begin i := colorstack_set; end - else if scan_keyword("push") then begin + else if scan_keyword('push') then begin i := colorstack_push; end - else if scan_keyword("pop") then begin + else if scan_keyword('pop') then begin i := colorstack_pop; end - else if scan_keyword("current") then begin + else if scan_keyword('current') then begin i := colorstack_current; end else begin @@ -30520,7 +26729,7 @@ begin new_whatsit(pdf_colorstack_node); pdf_colorstack_stack(tail) := cur_val; pdf_colorstack_cmd(tail) := i; - pdf_colorstack_data(tail) := null; + pdf_colorstack_data(tail) := null; if i <= colorstack_data then begin scan_pdf_ext_toks; pdf_colorstack_data(tail) := def_ref; @@ -30561,20 +26770,17 @@ end begin check_pdfoutput("\latelua", true); new_whatsit(late_lua_node); - scan_register_num; - late_lua_reg(tail) := cur_val; - scan_pdf_ext_toks; + if scan_keyword('name') then begin + scan_pdf_ext_toks; + late_lua_name(tail) := def_ref; + end; + sn:=0; + @; + if sn then late_lua_name(tail) := sn; + call_func(scan_toks(false, false)); late_lua_data(tail) := def_ref; end -@ @= -begin - check_pdfoutput("\closelua", true); - new_whatsit(close_lua_node); - scan_register_num; - late_lua_reg(tail) := cur_val; -end - @ The \.{\\pdfobj} primitive is used to create a ``raw'' object in the PDF output file. The object contents will be hold in memory and will be written out only when the object is referenced by \.{\\pdfrefobj}. When \.{\\pdfobj} @@ -30588,7 +26794,7 @@ end @ @= begin check_pdfoutput("\pdfobj", true); - if scan_keyword("reserveobjnum") then begin + if scan_keyword('reserveobjnum') then begin @; incr(pdf_obj_count); pdf_create_obj(obj_type_obj, pdf_obj_count); @@ -30596,7 +26802,7 @@ begin end else begin k := -1; - if scan_keyword("useobjnum") then begin + if scan_keyword('useobjnum') then begin scan_int; k := cur_val; if (k <= 0) or (k > obj_ptr) or (obj_data_ptr(k) <> 0) then begin @@ -30611,9 +26817,9 @@ begin k := obj_ptr; end; obj_data_ptr(k) := pdf_get_mem(pdfmem_obj_size); - if scan_keyword("stream") then begin + if scan_keyword('stream') then begin obj_obj_is_stream(k) := 1; - if scan_keyword("attr") then begin + if scan_keyword('attr') then begin scan_pdf_ext_toks; obj_obj_stream_attr(k) := def_ref; end @@ -30622,7 +26828,7 @@ begin end else obj_obj_is_stream(k) := 0; - if scan_keyword("file") then + if scan_keyword('file') then obj_obj_is_file(k) := 1 else obj_obj_is_file(k) := 0; @@ -30684,27 +26890,27 @@ begin pdf_create_obj(obj_type_xform, pdf_xform_count); k := obj_ptr; obj_data_ptr(k) := pdf_get_mem(pdfmem_xform_size); - if scan_keyword("attr") then begin + if scan_keyword('attr') then begin scan_pdf_ext_toks; obj_xform_attr(k) := def_ref; end else obj_xform_attr(k) := null; - if scan_keyword("resources") then begin + if scan_keyword('resources') then begin scan_pdf_ext_toks; obj_xform_resources(k) := def_ref; end else obj_xform_resources(k) := null; scan_int; - p:=box(cur_val); + p:=box(cur_val); if p = null then pdf_error("ext1", "\pdfxform cannot be used with a void box"); obj_xform_width(k) := width(p); obj_xform_height(k) := height(p); obj_xform_depth(k) := depth(p); obj_xform_box(k) := p; {save pointer to the box} - box(cur_val):=null; + box(cur_val):=null; pdf_last_xform := k; end @@ -30740,15 +26946,15 @@ warn_pdfpagebox := true; function scan_pdf_box_spec: integer; {scans PDF pagebox specification} begin scan_pdf_box_spec := 0; - if scan_keyword("mediabox") then + if scan_keyword('mediabox') then scan_pdf_box_spec := pdf_box_spec_media - else if scan_keyword("cropbox") then + else if scan_keyword('cropbox') then scan_pdf_box_spec := pdf_box_spec_crop - else if scan_keyword("bleedbox") then + else if scan_keyword('bleedbox') then scan_pdf_box_spec := pdf_box_spec_bleed - else if scan_keyword("trimbox") then + else if scan_keyword('trimbox') then scan_pdf_box_spec := pdf_box_spec_trim - else if scan_keyword("artbox") then + else if scan_keyword('artbox') then scan_pdf_box_spec := pdf_box_spec_art end; @@ -30761,17 +26967,17 @@ begin height(alt_rule) := null_flag; depth(alt_rule) := null_flag; reswitch: - if scan_keyword("width") then begin + if scan_keyword('width') then begin scan_normal_dimen; width(alt_rule) := cur_val; goto reswitch; end; - if scan_keyword("height") then begin + if scan_keyword('height') then begin scan_normal_dimen; height(alt_rule) := cur_val; goto reswitch; end; - if scan_keyword("depth") then begin + if scan_keyword('depth') then begin scan_normal_dimen; depth(alt_rule) := cur_val; goto reswitch; @@ -30780,7 +26986,7 @@ end; procedure scan_image; label reswitch; -var i, k, img_wd, img_ht, img_dp, ref: integer; +var k, img_wd, img_ht, img_dp, ref: integer; named, attr: str_number; s: str_number; page, pagebox, colorspace: integer; @@ -30796,22 +27002,22 @@ begin named := 0; page := 1; colorspace := 0; - if scan_keyword("attr") then begin + if scan_keyword('attr') then begin scan_pdf_ext_toks; attr := tokens_to_string(def_ref); delete_token_ref(def_ref); end; - if scan_keyword("named") then begin + if scan_keyword('named') then begin scan_pdf_ext_toks; named := tokens_to_string(def_ref); delete_token_ref(def_ref); page := 0; end - else if scan_keyword("page") then begin + else if scan_keyword('page') then begin scan_int; page := cur_val; end; - if scan_keyword("colorspace") then begin + if scan_keyword('colorspace') then begin scan_int; colorspace := cur_val; end; @@ -30868,7 +27074,7 @@ begin pdf_check_obj(obj_type_ximage, cur_val); new_whatsit(pdf_refximage_node); j := obj_data_ptr(cur_val); - pdf_ximage_ref(tail) := j; + pdf_ximage_idx(tail) := j; pdf_width(tail) := image_width(j); pdf_height(tail) := image_height(j); pdf_depth(tail) := image_depth(j); @@ -30941,11 +27147,11 @@ var p: integer; begin p := new_node(action_node,0); scan_action := p; - if scan_keyword("user") then + if scan_keyword('user') then pdf_action_type(p) := pdf_action_user - else if scan_keyword("goto") then + else if scan_keyword('goto') then pdf_action_type(p) := pdf_action_goto - else if scan_keyword("thread") then + else if scan_keyword('thread') then pdf_action_type(p) := pdf_action_thread else pdf_error("ext1", "action type missing"); @@ -30954,11 +27160,11 @@ begin pdf_action_tokens(p) := def_ref; return; end; - if scan_keyword("file") then begin + if scan_keyword('file') then begin scan_pdf_ext_toks; pdf_action_file(p) := def_ref; end; - if scan_keyword("page") then begin + if scan_keyword('page') then begin if pdf_action_type(p) <> pdf_action_goto then pdf_error("ext1", "only GoTo action can be used with `page'"); pdf_action_type(p) := pdf_action_page; @@ -30970,12 +27176,12 @@ begin scan_pdf_ext_toks; pdf_action_tokens(p) := def_ref; end - else if scan_keyword("name") then begin + else if scan_keyword('name') then begin scan_pdf_ext_toks; pdf_action_named_id(p) := 1; pdf_action_id(p) := def_ref; end - else if scan_keyword("num") then begin + else if scan_keyword('num') then begin if (pdf_action_type(p) = pdf_action_goto) and (pdf_action_file(p) <> null) then pdf_error("ext1", @@ -30988,10 +27194,10 @@ begin end else pdf_error("ext1", "identifier type missing"); - if scan_keyword("newwindow") then begin + if scan_keyword('newwindow') then begin pdf_action_new_window(p) := 1; @; end - else if scan_keyword("nonewwindow") then begin + else if scan_keyword('nonewwindow') then begin pdf_action_new_window(p) := 2; @; end else @@ -31013,7 +27219,7 @@ begin pdf_height(tail) := height(alt_rule); pdf_depth(tail) := depth(alt_rule); if (w = pdf_thread_node) or (w = pdf_start_thread_node) then begin - if scan_keyword("attr") then begin + if scan_keyword('attr') then begin scan_pdf_ext_toks; pdf_thread_attr(tail) := def_ref; end @@ -31028,11 +27234,11 @@ end; @ @= begin check_pdfoutput("\pdfannot", true); - if scan_keyword("reserveobjnum") then begin + if scan_keyword('reserveobjnum') then begin pdf_last_annot := pdf_new_objnum; @; end else begin - if scan_keyword("useobjnum") then begin + if scan_keyword('useobjnum') then begin scan_int; k := cur_val; if (k <= 0) or (k > obj_ptr) or (obj_annot_ptr(k) <> 0) then @@ -31059,8 +27265,8 @@ begin pdf_error("ext1", "\pdfstartlink cannot be used in vertical mode"); k := pdf_new_objnum; new_annot_whatsit(pdf_start_link_node); - pdf_link_attr(tail) := null; - if scan_keyword("attr") then begin + pdf_link_attr(tail) := null; + if scan_keyword('attr') then begin scan_pdf_ext_toks; pdf_link_attr(tail) := def_ref; end; @@ -31096,14 +27302,14 @@ end; @ @= begin check_pdfoutput("\pdfoutline", true); - if scan_keyword("attr") then begin + if scan_keyword('attr') then begin scan_pdf_ext_toks; r := def_ref; end else r := 0; p := scan_action; - if scan_keyword("count") then begin + if scan_keyword('count') then begin scan_int; i := cur_val; end @@ -31198,7 +27404,7 @@ begin check_pdfoutput("\pdfdest", true); q := tail; new_whatsit(pdf_dest_node); - if scan_keyword("num") then begin + if scan_keyword('num') then begin scan_int; if cur_val <= 0 then pdf_error("ext1", "num identifier must be positive"); @@ -31207,16 +27413,16 @@ begin pdf_dest_id(tail) := cur_val; pdf_dest_named_id(tail) := 0; end - else if scan_keyword("name") then begin + else if scan_keyword('name') then begin scan_pdf_ext_toks; pdf_dest_id(tail) := def_ref; pdf_dest_named_id(tail) := 1; end else pdf_error("ext1", "identifier type missing"); - if scan_keyword("xyz") then begin + if scan_keyword('xyz') then begin pdf_dest_type(tail) := pdf_dest_xyz; - if scan_keyword("zoom") then begin + if scan_keyword('zoom') then begin scan_int; if cur_val > max_halfword then pdf_error("ext1", "number too big"); @@ -31225,19 +27431,19 @@ begin else pdf_dest_xyz_zoom(tail) := null; end - else if scan_keyword("fitbh") then + else if scan_keyword('fitbh') then pdf_dest_type(tail) := pdf_dest_fitbh - else if scan_keyword("fitbv") then + else if scan_keyword('fitbv') then pdf_dest_type(tail) := pdf_dest_fitbv - else if scan_keyword("fitb") then + else if scan_keyword('fitb') then pdf_dest_type(tail) := pdf_dest_fitb - else if scan_keyword("fith") then + else if scan_keyword('fith') then pdf_dest_type(tail) := pdf_dest_fith - else if scan_keyword("fitv") then + else if scan_keyword('fitv') then pdf_dest_type(tail) := pdf_dest_fitv - else if scan_keyword("fitr") then + else if scan_keyword('fitr') then pdf_dest_type(tail) := pdf_dest_fitr - else if scan_keyword("fit") then + else if scan_keyword('fit') then pdf_dest_type(tail) := pdf_dest_fit else pdf_error("ext1", "destination type missing"); @@ -31267,7 +27473,7 @@ end @ @= procedure scan_thread_id; begin - if scan_keyword("num") then begin + if scan_keyword('num') then begin scan_int; if cur_val <= 0 then pdf_error("ext1", "num identifier must be positive"); @@ -31276,7 +27482,7 @@ begin pdf_thread_id(tail) := cur_val; pdf_thread_named_id(tail) := 0; end - else if scan_keyword("name") then begin + else if scan_keyword('name') then begin scan_pdf_ext_toks; pdf_thread_id(tail) := def_ref; pdf_thread_named_id(tail) := 1; @@ -31348,7 +27554,7 @@ begin scan_pdf_ext_toks; if pdf_output > 0 then pdf_catalog_toks := concat_tokens(pdf_catalog_toks, def_ref); - if scan_keyword("openaction") then begin + if scan_keyword('openaction') then begin if pdf_catalog_openaction <> 0 then pdf_error("ext1", "duplicate of openaction") else begin @@ -31398,14 +27604,14 @@ end @ @= begin scan_int; - if (cur_val<0)or(cur_val>@"FFFFFFF) then begin - print_err("Invalid \catcode table"); - help1("All \catcode table ids must be between 0 and 0xFFFFFFF"); - error; + if (cur_val<0)or(cur_val>@"FFFF) then begin + print_err("Invalid \catcode table"); + help1("All \catcode table ids must be between 0 and 0xFFFF"); + error; end else begin if cur_val=cat_code_table then begin print_err("Invalid \catcode table"); - help1("You cannot overwrite the current \catcode table"); + help1("You cannot overwrite the current \catcode table"); error; end else @@ -31416,15 +27622,15 @@ end @ @= begin scan_int; - if (cur_val<0)or(cur_val>@"FFFFFFF) then begin - print_err("Invalid \catcode table"); - help1("All \catcode table ids must be between 0 and 0xFFFFFFF"); - error; + if (cur_val<0)or(cur_val>@"FFFF) then begin + print_err("Invalid \catcode table"); + help1("All \catcode table ids must be between 0 and 0xFFFF"); + error; end else begin if cur_val=cat_code_table then begin print_err("Invalid \catcode table"); - help1("You cannot overwrite the current \catcode table"); - error; + help1("You cannot overwrite the current \catcode table"); + error; end else initex_cat_codes(cur_val); @@ -31599,284 +27805,36 @@ begin pdf_indirect_ln("V", obj_bead_prev(a)); pdf_indirect_ln("N", obj_bead_next(a)); pdf_indirect_ln("P", obj_bead_page(a)); - pdf_indirect_ln("R", obj_bead_rect(a)); - pdf_end_dict; - a := obj_bead_next(a); - until a = b; -end; - -@ @ for whatsit node created by \pdfTeX@>= -print("("); -print_rule_dimen(pdf_height(p)); -print_char("+"); -print_rule_dimen(pdf_depth(p)); -print(")x"); -print_rule_dimen(pdf_width(p)) - -@ Each new type of node that appears in our data structure must be capable -of being displayed, copied, destroyed, and so on. The routines that we -need for write-oriented whatsits are somewhat like those for mark nodes; -other extensions might, of course, involve more subtlety here. - -@= -procedure print_write_whatsit(@!s:str_number;@!p:pointer); -begin print_esc(s); -if write_stream(p)<16 then print_int(write_stream(p)) -else if write_stream(p)=16 then print_char("*") -@.*\relax@> -else print_char("-"); -end; - -@ Three extra node types carry information from |main_control|. - -@ |cancel_boundary_nodes| indicate that the next left boundary be -ignored. These are created by the \.{\\noboundary} command in -horizontal mode. - -@d cancel_boundary_node==pdf_restore_node+1 -@d cancel_boundary_size==3 - -@= -begin new_whatsit(cancel_boundary_node); -end - -@ User defined whatsits can be inserted into node lists to pass data -along from one lua call to anotherb without interference from the -typesetting engine itself. Each has an id, a type, and a value. The -type of the value depends on the |user_node_type| field. - -@d user_defined_node==cancel_boundary_node+1 -@d user_defined_node_size=4 -@d user_node_id(#)==vlink(#+2) -@d user_node_type(#)==vinfo(#+2) -@d user_node_value(#)==vinfo(#+3) - -@ @= -case subtype(p) of -open_node:begin print_write_whatsit("openout",p); - print_char("="); print_file_name(open_name(p),open_area(p),open_ext(p)); - end; -write_node:begin print_write_whatsit("write",p); - print_mark(write_tokens(p)); - end; -close_node:print_write_whatsit("closeout",p); -special_node:begin print_esc("special"); - print_mark(write_tokens(p)); - end; -dir_node: - if dir_dir(p)<0 then begin - print_esc("enddir"); print(" "); print_dir(dir_dir(p)+64); - end - else begin - print_esc("begindir"); print(" "); print_dir(dir_dir(p)); - end; -@; -pdf_literal_node: begin - print_esc("pdfliteral"); - case pdf_literal_mode(p) of - set_origin: - do_nothing; - direct_page: - print(" page"); - direct_always: - print(" direct"); - othercases confusion("literal2") - endcases; - print_mark(pdf_literal_data(p)); -end; -pdf_colorstack_node: begin - print_esc("pdfcolorstack "); - print_int(pdf_colorstack_stack(p)); - case pdf_colorstack_cmd(p) of - colorstack_set: - print(" set "); - colorstack_push: - print(" push "); - colorstack_pop: - print(" pop"); - colorstack_current: - print(" current"); - othercases confusion("pdfcolorstack") - endcases; - if pdf_colorstack_cmd(p) <= colorstack_data then - print_mark(pdf_colorstack_data(p)); -end; -pdf_setmatrix_node: begin - print_esc("pdfsetmatrix"); - print_mark(pdf_setmatrix_data(p)); -end; -pdf_save_node: begin - print_esc("pdfsave"); -end; -pdf_restore_node: begin - print_esc("pdfrestore"); -end; -cancel_boundary_node: begin - print_esc("noboundary"); -end; -late_lua_node: begin - print_esc("latelua"); - print_int(late_lua_reg(p)); - print_mark(late_lua_data(p)); -end; -close_lua_node: begin - print_esc("closelua"); - print_int(late_lua_reg(p)); -end; -pdf_refobj_node: begin - print_esc("pdfrefobj"); - if obj_obj_is_stream(pdf_obj_objnum(p)) > 0 then begin - if obj_obj_stream_attr(pdf_obj_objnum(p)) <> null then begin - print(" attr"); - print_mark(obj_obj_stream_attr(pdf_obj_objnum(p))); - end; - print(" stream"); - end; - if obj_obj_is_file(pdf_obj_objnum(p)) > 0 then - print(" file"); - print_mark(obj_obj_data(pdf_obj_objnum(p))); -end; -pdf_refxform_node: begin - print_esc("pdfrefxform"); - print("("); - print_scaled(obj_xform_height(pdf_xform_objnum(p))); - print_char("+"); - print_scaled(obj_xform_depth(pdf_xform_objnum(p))); - print(")x"); - print_scaled(obj_xform_width(pdf_xform_objnum(p))); -end; -pdf_refximage_node: begin - print_esc("pdfrefximage"); - print("("); - print_scaled(pdf_height(p)); - print_char("+"); - print_scaled(pdf_depth(p)); - print(")x"); - print_scaled(pdf_width(p)); -end; -pdf_annot_node: begin - print_esc("pdfannot"); - @ for whatsit node created by \pdfTeX@>; - print_mark(pdf_annot_data(p)); -end; -pdf_start_link_node: begin - print_esc("pdflink"); - @ for whatsit node created by \pdfTeX@>; - if pdf_link_attr(p) <> null then begin - print(" attr"); - print_mark(pdf_link_attr(p)); - end; - print(" action"); - if pdf_action_type(pdf_link_action(p)) = pdf_action_user then begin - print(" user"); - print_mark(pdf_action_tokens(pdf_link_action(p))); - return; - end; - if pdf_action_file(pdf_link_action(p)) <> null then begin - print(" file"); - print_mark(pdf_action_file(pdf_link_action(p))); - end; - case pdf_action_type(pdf_link_action(p)) of - pdf_action_goto: begin - if pdf_action_named_id(pdf_link_action(p)) > 0 then begin - print(" goto name"); - print_mark(pdf_action_id(pdf_link_action(p))); - end - else begin - print(" goto num"); - print_int(pdf_action_id(pdf_link_action(p))) - end; - end; - pdf_action_page: begin - print(" page"); - print_int(pdf_action_id(pdf_link_action(p))); - print_mark(pdf_action_tokens(pdf_link_action(p))); - end; - pdf_action_thread: begin - if pdf_action_named_id(pdf_link_action(p)) > 0 then begin - print(" thread name"); - print_mark(pdf_action_id(pdf_link_action(p))); - end - else begin - print(" thread num"); - print_int(pdf_action_id(pdf_link_action(p))); - end; - end; - othercases pdf_error("displaying", "unknown action type"); - endcases; -end; -pdf_end_link_node: print_esc("pdfendlink"); -pdf_dest_node: begin - print_esc("pdfdest"); - if pdf_dest_named_id(p) > 0 then begin - print(" name"); - print_mark(pdf_dest_id(p)); - end - else begin - print(" num"); - print_int(pdf_dest_id(p)); - end; - print(" "); - case pdf_dest_type(p) of - pdf_dest_xyz: begin - print("xyz"); - if pdf_dest_xyz_zoom(p) <> null then begin - print(" zoom"); - print_int(pdf_dest_xyz_zoom(p)); - end; - end; - pdf_dest_fitbh: print("fitbh"); - pdf_dest_fitbv: print("fitbv"); - pdf_dest_fitb: print("fitb"); - pdf_dest_fith: print("fith"); - pdf_dest_fitv: print("fitv"); - pdf_dest_fitr: begin - print("fitr"); - @ for whatsit node created by \pdfTeX@>; - end; - pdf_dest_fit: print("fit"); - othercases print("unknown!"); - endcases; -end; -pdf_thread_node, -pdf_start_thread_node: begin - if subtype(p) = pdf_thread_node then - print_esc("pdfthread") - else - print_esc("pdfstartthread"); - print("("); print_rule_dimen(pdf_height(p)); print_char("+"); - print_rule_dimen(pdf_depth(p)); print(")x"); - print_rule_dimen(pdf_width(p)); - if pdf_thread_attr(p) <> null then begin - print(" attr"); - print_mark(pdf_thread_attr(p)); - end; - if pdf_thread_named_id(p) > 0 then begin - print(" name"); - print_mark(pdf_thread_id(p)); - end - else begin - print(" num"); - print_int(pdf_thread_id(p)); - end; + pdf_indirect_ln("R", obj_bead_rect(a)); + pdf_end_dict; + a := obj_bead_next(a); + until a = b; end; -pdf_end_thread_node: print_esc("pdfendthread"); -pdf_save_pos_node: print_esc("pdfsavepos"); -user_defined_node: begin - print_esc("whatsit"); - print_int(user_node_id(p)); - print_char("="); - case user_node_type(p) of - "a": print("<>"); - "n": begin print("["); show_node_list(user_node_value(p)); print("]"); end; - "s": begin print(""""); print(user_node_value(p)); print(""""); end; - "t": print_mark(user_node_value(p)); - othercases { only d } - print_int(user_node_value(p)); - endcases; - end; -othercases print("whatsit?") -endcases + + +@ Three extra node types carry information from |main_control|. + +@ |cancel_boundary_nodes| indicate that the next left boundary be +ignored. These are created by the \.{\\noboundary} command in +horizontal mode. + +@d cancel_boundary_node==pdf_restore_node+1 +@d cancel_boundary_size==3 + +@= +begin new_whatsit(cancel_boundary_node); +end + +@ User defined whatsits can be inserted into node lists to pass data +along from one lua call to anotherb without interference from the +typesetting engine itself. Each has an id, a type, and a value. The +type of the value depends on the |user_node_type| field. + +@d user_defined_node==cancel_boundary_node+1 +@d user_node_id(#)==vlink(#+2) +@d user_node_type(#)==vinfo(#+2) +@d user_node_value(#)==vinfo(#+3) + @ @= if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then @@ -31901,12 +27859,6 @@ end; end; end -@ @= -if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then - d := pdf_width(p) -else - d := 0 - @ @= begin if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then @@ -31939,7 +27891,7 @@ that actually send out the requested data. Let's do \.{\\special} first procedure special_out(@!p:pointer); var old_setting:0..max_selector; {holds print |selector|} @!k:pool_pointer; {index into |str_pool|} -begin synch_h; synch_v;@/ +begin synch_dvi_with_cur;@/ old_setting:=selector; selector:=new_string; show_token_list(link(write_tokens(p)),null,pool_size-pool_ptr); selector:=old_setting; @@ -31983,6 +27935,13 @@ else begin {write to the terminal if file isn't open} token_show(def_ref); print_ln; flush_list(def_ref); selector:=old_setting; end; +procedure expand_late_lua(@!p:pointer); +var @!old_mode:integer; {saved |mode|} +@!q,@!r:pointer; {temporary variables for list manipulation} +begin @; +end; + @ The final line of this routine is slightly subtle; at least, the author didn't think about it until getting burnt! There is a used-up token list @@ -32029,18 +27988,20 @@ open_node,write_node,close_node:@; special_node:special_out(p); pdf_save_pos_node: - @; + @; local_par_node:do_nothing; cancel_boundary_node: do_nothing; +user_defined_node: do_nothing; othercases confusion("ext4") {TH: those will be pdf extension nodes in dvi mode, most likely} @:this can't happen ext4}{\quad ext4@> endcases; end; -@ @= +@ @= begin - pdf_last_x_pos := cur_h + one_inch; - pdf_last_y_pos := cur_page_height - cur_v - one_inch; + synch_pos_with_cur; + pdf_last_x_pos := pos.h; + pdf_last_y_pos := pos.v; end @ We don't implement \.{\\write} inside of leaders. (The reason is that @@ -32060,7 +28021,7 @@ if not doing_leaders then if cur_ext="" then cur_ext:=".tex"; pack_cur_name; while not lua_a_open_out(write_file[j],(j+1)) do - prompt_file_name("output file name",".tex"); + prompt_file_name('output file name','.tex'); write_file[j]:= name_file_pointer; write_open[j]:=true; end; @@ -32081,10 +28042,6 @@ if cur_cmd=extension then begin flush_node_list(tail); tail:=p; vlink(p):=null; end else case cur_chr of - close_lua_node: begin - scan_register_num; - closelua(cur_val); - end; pdf_obj_code: begin do_extension; {scan object and set |pdf_last_obj|} if obj_data_ptr(pdf_last_obj) = 0 then {this object has not been initialized yet} @@ -32118,7 +28075,6 @@ for k:=0 to 15 do if write_open[k] then lua_a_close_out(write_file[k]) @d local_box_right(#)==vlink(#+4) {\.{\\localleftbox}} @d local_box_right_width(#)==vinfo(#+4) @d local_par_dir(#)==vinfo(#+5) -@d local_par_size==6 @= function make_local_par_node:pointer; @@ -32140,51 +28096,18 @@ local_par_dir(p):=par_direction; make_local_par_node:=p; end -@ @= -local_par_node: begin - print_esc("whatsit"); - append_char("."); - print_ln; print_current_string; - print_esc("localinterlinepenalty"); print("="); - print_int(local_pen_inter(p)); - print_ln; print_current_string; - print_esc("localbrokenpenalty"); print("="); - print_int(local_pen_broken(p)); - print_ln; print_current_string; - print_esc("localleftbox"); - if local_box_left(p)=null then print("=null") - else begin - append_char("."); - show_node_list(local_box_left(p)); - decr(pool_ptr); - end; - print_ln; print_current_string; - print_esc("localrightbox"); - if local_box_right(p)=null then print("=null") - else begin - append_char("."); - show_node_list(local_box_right(p)); - decr(pool_ptr); - end; - decr(pool_ptr); - end - @ @= begin tail_append(make_local_par_node) end @ @= case cur_chr of dir_base+page_direction_code: begin - if its_all_over then begin scan_direction; eq_word_define(dir_base+page_direction_code,cur_val); - end; end; dir_base+body_direction_code: begin - if its_all_over then begin scan_direction; eq_word_define(dir_base+body_direction_code,cur_val); - end; end; dir_base+par_direction_code: begin scan_direction; @@ -32239,12 +28162,6 @@ dir_dir(p):=s; dir_dvi_ptr(p):=-1; dir_level(p):=cur_level; new_dir:=p; end -@ @= -tail_append(new_dir(math_direction)) - -@ @= -tail_append(new_dir(math_direction-64)) - @ @= tail_append(new_dir(text_direction)) @@ -32267,26 +28184,6 @@ begin pop_dir_node end -@ @= -begin -unsave; -decr(save_ptr); -flush_node_list(text_dir_ptr); -text_dir_ptr:=saved(0); -end - -@ @= -begin -saved(0):=text_dir_ptr; -text_dir_ptr:=new_dir(math_direction); -incr(save_ptr); -new_save_level(c); -eq_word_define(dir_base+body_direction_code,math_direction); -eq_word_define(dir_base+par_direction_code,math_direction); -eq_word_define(dir_base+text_direction_code,math_direction); -eq_word_define(int_base+level_local_dir_code,cur_level); -end - @ @= begin if spec_direction<>-1 then begin @@ -32328,92 +28225,36 @@ end @ @= begin -if dir_dir(p)>=0 then - begin synch_h; synch_v; - push_dir_node(p); - if dir_opposite(dir_secondary[dir_dir(dir_ptr)])(dir_secondary[dvi_direction]) - then begin - if (dir_secondary[dvi_direction]=0) or - (dir_secondary[dvi_direction]=2) then - dvi_out(down4) - else - dvi_out(right4); - dir_dvi_ptr(dir_ptr):=dvi_ptr; - dir_dvi_h(dir_ptr):=dvi_h; - dvi_four(0); - cur_h:=0; dvi_h:=0; - end - else begin - dir_dvi_ptr(dir_ptr):=dvi_ptr; - dir_dvi_h(dir_ptr):=dvi_h; - end; - dvi_direction:=dir_dir(dir_ptr); + if dir_dir(p)>=0 then begin + push_dir_node(p); + @<(PDF) Calculate the needed width to the matching |enddir|, and store it in |w|, as + well as in the enddir's |dir_dvi_h|@>; + if (dir_opposite(dir_secondary[dir_dir(dir_ptr)])(dir_secondary[dvi_direction])) + or (dir_eq(dir_secondary[dir_dir(dir_ptr)])(dir_secondary[dvi_direction])) + then begin + dir_cur_h(temp_ptr) := cur.h + w; + if dir_opposite(dir_secondary[dir_dir(dir_ptr)])(dir_secondary[dvi_direction]) then + cur.h := cur.h + w; + end else + dir_cur_h(temp_ptr) := cur.h; + dir_cur_v(temp_ptr) := cur.v; + dir_box_pos_h(temp_ptr) := box_pos.h; + dir_box_pos_v(temp_ptr) := box_pos.v; + synch_pos_with_cur; {no need for |synch_dvi_with_cur|, as there is no DVI grouping} + box_pos := pos; {fake a nested |hlist_out|} + set_to_zero(cur); + dvi_direction:=dir_dir(dir_ptr); end -else begin - dvi_dir_h:=dir_dvi_h(dir_ptr); - dvi_dir_ptr:=dir_dvi_ptr(dir_ptr); - pop_dir_node; - synch_h; synch_v; - if dir_ptr<>null then - dvi_direction:=dir_dir(dir_ptr) - else - dvi_direction:=0; - if dir_opposite(dir_secondary[dir_dir(p)+64])(dir_secondary[dvi_direction]) - then begin - dvi_temp_ptr:=dvi_ptr; - dvi_ptr:=dvi_dir_ptr; - if (dir_secondary[dvi_direction]=0) or - (dir_secondary[dvi_direction]=1) then - dvi_four(dvi_h) - else - dvi_four(-dvi_h); - dvi_ptr:=dvi_temp_ptr; - if (dir_secondary[dvi_direction]=0) or - (dir_secondary[dvi_direction]=2) then - dvi_out(down4) - else - dvi_out(right4); - if (dir_secondary[dvi_direction]=0) or - (dir_secondary[dvi_direction]=1) then - dvi_four(dvi_h) + else begin + pop_dir_node; + box_pos.h := dir_box_pos_h(p); + box_pos.v := dir_box_pos_v(p); + cur.h := dir_cur_h(p); + cur.v := dir_cur_v(p); + if dir_ptr<>null then + dvi_direction:=dir_dir(dir_ptr) else - dvi_four(-dvi_h); - end; - cur_h:=dvi_dir_h+dvi_h; dvi_h:=cur_h; - end -end - -@ Many things regarding output work differently in pdf compared to dvi -output. The easiest way to deal with in-line direction changes in pdf -mode seems to be to move forward to find the needed width of the -reversed section, then skip forward (or backward, depending on your -viewpont) by that distance. - -@<(PDF) Output a reflection instruction if the direction has changed@>= -begin -if dir_dir(p)>=0 then begin - push_dir_node(p); - if dir_opposite(dir_secondary[dir_dir(dir_ptr)])(dir_secondary[dvi_direction]) - then begin - @<(PDF) Calculate the needed width to the matching |enddir|, and store it in |w|, as - well as in the enddir's |dir_dvi_h|@>; - case box_direction(dvi_direction) of - dir_TL_,dir_BL_: pdf_dvicmd_right(w); - dir_TR_,dir_BR_: pdf_dvicmd_left(w); - end; - end; - dvi_direction:=dir_dir(dir_ptr); - end -else begin - pop_dir_node; - if dir_ptr<>null then - dvi_direction:=dir_dir(dir_ptr) - else - dvi_direction:=0; - case box_direction(dvi_direction) of - dir_TL_,dir_BL_: pdf_dvicmd_right(dir_dvi_h(p)); - dir_TR_,dir_BR_: pdf_dvicmd_left(dir_dvi_h(p)); - end; + dvi_direction:=0; end end @@ -32423,7 +28264,34 @@ this segment, it stores the accumulated with in the |dir_dvi_h| field of that end node, so that when that node is found later in the processing, the correct glue correction can be applied. -@<(PDF) Calculate the needed width to the matching |enddir|...@>= +@p +function simple_advance_width(p:halfword):scaled; +var q:halfword; +@!w:scaled; +begin + q:=p; w:=0; + while (q<>null) and (vlink(q)<>null) do begin + q:=vlink(q); + if is_char_node(q) then begin + w:=w+glyph_width(q); + end + else begin + case type(q) of + hlist_node_case,vlist_node_case,rule_node_case, + margin_kern_node_case,kern_node_case: + w:=w+width(q); + disc_node_case: if vlink(no_break(q))<>null then begin + w:=w+simple_advance_width(no_break(q)); + end; + othercases do_nothing; + endcases; + end; + end; + simple_advance_width:=w; +end; + + +@ @<(PDF) Calculate the needed width to the matching |enddir|...@>= begin q:=p; w:=0; save_cur_g:=cur_g; @@ -32433,15 +28301,15 @@ begin {|w:=w-cur_g; cur_glue:=0;|} dir_nest:=1; while (q<>null) and (vlink(q)<>null) do begin - q:=vlink(q); + q:=vlink(q); if is_char_node(q) then begin w:=w+glyph_width(q); {TODO no vertical support for now} end else begin case type(q) of - hlist_node,vlist_node,rule_node, - margin_kern_node,kern_node:w:=w+width(q); - glue_node: begin + hlist_node_case,vlist_node_case,rule_node_case, + margin_kern_node_case,kern_node_case:w:=w+width(q); + glue_node_case: begin g:=glue_ptr(q); w:=w+width(g)-cur_g; if g_sign<>normal then @@ -32460,13 +28328,17 @@ begin end; w:=w+cur_g; end; - math_node: w:=w+surround(q); - whatsit_node: begin + disc_node_case: if vlink(no_break(q))<>null then begin + w:=w+simple_advance_width(no_break(q)); + end; + math_node_case: w:=w+surround(q); + whatsit_node_case: begin if subtype(q)=dir_node then begin if dir_dir(q)>=0 then incr(dir_nest) else decr(dir_nest); if dir_nest=0 then begin dir_dvi_h(q) := w; - q:=null; + temp_ptr := q; + q:=null; end; end else if (subtype(q) = pdf_refxform_node) or @@ -32491,10 +28363,7 @@ dest_name_entry = record end; @ @= -@!cur_page_width: scaled; {width of page being shipped} -@!cur_page_height: scaled; {height of page being shipped} -@!cur_right_offset: scaled; {horizontal inverted offset of page being shipped} -@!cur_bottom_offset: scaled; {vertical inverted offset of page being shipped} +@!cur_page_size: scaledpos; {width and height of page being shipped} @!pdf_obj_list: pointer; {list of objects in the current page} @!pdf_xform_list: pointer; {list of forms in the current page} @!pdf_ximage_list: pointer; {list of images in the current page} @@ -32621,33 +28490,39 @@ begin d:=0; pdf_print_ln(" >>"); end; -procedure set_rect_dimens(p, parent_box: pointer; x, y, w, h, d, margin: scaled); +procedure set_rect_dimens(p, parent_box: pointer; x, y, wd, ht, dp, margin: scaled); +var ll, ur, pos_ll, pos_ur, tmp: scaledpos; begin - pdf_left(p) := cur_h; - if is_running(w) then - pdf_right(p) := x + width(parent_box) + ll.h := cur.h; + if is_running(dp) then + ll.v := y + depth(parent_box) else - pdf_right(p) := cur_h + w; - if is_running(h) then - pdf_top(p) := y - height(parent_box) + ll.v := cur.v + dp; + if is_running(wd) then + ur.h := x + width(parent_box) else - pdf_top(p) := cur_v - h; - if is_running(d) then - pdf_bottom(p) := y + depth(parent_box) + ur.h := cur.h + wd; + if is_running(ht) then + ur.v := y - height(parent_box) else - pdf_bottom(p) := cur_v + d; + ur.v := cur.v - ht; + pos_ll := synch_p_with_c(ll); + pos_ur := synch_p_with_c(ur); + if pos_ll.h > pos_ur.h then begin + tmp.h := pos_ll.h; pos_ll.h := pos_ur.h; pos_ur.h := tmp.h; end; + if pos_ll.v > pos_ur.v then begin + tmp.v := pos_ll.v; pos_ll.v := pos_ur.v; pos_ur.v := tmp.v; end; if is_shipping_page and matrixused then begin - matrixtransformrect(pdf_left(p), cur_page_height - pdf_bottom(p), - pdf_right(p), cur_page_height - pdf_top(p)); - pdf_left(p) := getllx; - pdf_bottom(p) := cur_page_height - getlly; - pdf_right(p) := geturx; - pdf_top(p) := cur_page_height - getury; + matrixtransformrect(pos_ll.h, pos_ll.v, pos_ur.h, pos_ur.v); + pos_ll.h := getllx; + pos_ll.v := getlly; + pos_ur.h := geturx; + pos_ur.v := getury; end; - pdf_left(p) := pdf_left(p) - margin; - pdf_top(p) := pdf_top(p) - margin; - pdf_right(p) := pdf_right(p) + margin; - pdf_bottom(p) := pdf_bottom(p) + margin; + pdf_ann_left(p) := pos_ll.h - margin; + pdf_ann_bottom(p) := pos_ll.v - margin; + pdf_ann_right(p) := pos_ur.h + margin; + pdf_ann_top(p) := pos_ur.v + margin; end; procedure do_annot(p, parent_box: pointer; x, y: scaled); @@ -32656,13 +28531,16 @@ begin pdf_error("ext4", "annotations cannot be inside an XForm"); if doing_leaders then return; + if is_obj_scheduled(pdf_annot_objnum(p)) then + pdf_annot_objnum(p) := pdf_new_objnum; set_rect_dimens(p, parent_box, x, y, pdf_width(p), pdf_height(p), pdf_depth(p), 0); obj_annot_ptr(pdf_annot_objnum(p)) := p; pdf_append_list(pdf_annot_objnum(p))(pdf_annot_list); + set_obj_scheduled(pdf_annot_objnum(p)); end; -@ To implement nesting link annotations, we need a stack to hold copy of +@ To implement nested link annotations, we need a stack to hold copy of |pdf_start_link_node|'s that are being written out, together with their box nesting level. @@ -32673,7 +28551,7 @@ nesting level. @ @= @!pdf_link_stack_record = record - nesting_level: small_number; + nesting_level: integer; link_node: pointer; {holds a copy of the corresponding |pdf_start_link_node|} ref_link_node: pointer; {points to original |pdf_start_link_node|, or a copy of |link_node| created by |append_link| in @@ -32711,6 +28589,8 @@ begin if not is_shipping_page then pdf_error("ext4", "link annotations cannot be inside an XForm"); pdfassert(type(parent_box) = hlist_node); + if is_obj_scheduled(pdf_link_objnum(p)) then + pdf_link_objnum(p) := pdf_new_objnum; push_link_level(p); set_rect_dimens(p, parent_box, x, y, pdf_width(p), pdf_height(p), pdf_depth(p), @@ -32718,10 +28598,12 @@ begin obj_annot_ptr(pdf_link_objnum(p)) := p; {the reference for the pdf annot object must be set here} pdf_append_list(pdf_link_objnum(p))(pdf_link_list); + set_obj_scheduled(pdf_link_objnum(p)); end; procedure end_link; var p: pointer; +tmp1, tmp2: scaledpos; begin if pdf_link_stack_ptr < 1 then pdf_error("ext4", "pdf_link_stack empty, \pdfendlink used without \pdfstartlink?"); @@ -32734,14 +28616,22 @@ begin if is_running(pdf_width(pdf_link_stack_top.link_node)) then begin p := pdf_link_stack_top.ref_link_node; if is_shipping_page and matrixused then begin - matrixrecalculate(cur_h + pdf_link_margin); - pdf_left(p) := getllx - pdf_link_margin; - pdf_top(p) := cur_page_height - getury - pdf_link_margin; - pdf_right(p) := geturx + pdf_link_margin; - pdf_bottom(p) := cur_page_height - getlly + pdf_link_margin; - end - else - pdf_right(p) := cur_h + pdf_link_margin; + matrixrecalculate(cur.h + pdf_link_margin); + pdf_ann_left(p) := getllx - pdf_link_margin; + pdf_ann_top(p) := cur_page_size.v - getury - pdf_link_margin; + pdf_ann_right(p) := geturx + pdf_link_margin; + pdf_ann_bottom(p) := cur_page_size.v - getlly + pdf_link_margin; + end + else begin + tmp1.h := cur.h; tmp1.v := cur.v; + tmp2 := synch_p_with_c(tmp1); + case box_direction(dvi_direction) of + dir_TL_, dir_BL_: pdf_ann_right(p) := tmp2.h + pdf_link_margin; + dir_TR_, dir_BR_: pdf_ann_left(p) := tmp2.h - pdf_link_margin; + dir_LT_, dir_RT_: pdf_ann_bottom(p) := tmp2.v - pdf_link_margin; + dir_LB_, dir_RB_: pdf_ann_top(p) := tmp2.v + pdf_link_margin; + endcases; + end; end; pop_link_level; end; @@ -32846,11 +28736,20 @@ begin end; procedure end_thread; +var tmp1, tmp2: scaledpos; begin if pdf_thread_level <> cur_s then pdf_error("ext4", "\pdfendthread ended up in different nesting level than \pdfstartthread"); - if is_running(pdf_thread_dp) and (last_thread <> null) then - pdf_bottom(last_thread) := cur_v + pdf_thread_margin; + if is_running(pdf_thread_dp) and (last_thread <> null) then begin + tmp1.h := cur.h; tmp1.v := cur.v; + tmp2 := synch_p_with_c(tmp1); + case box_direction(dvi_direction) of + dir_TL_, dir_TR_: pdf_ann_bottom(last_thread) := tmp2.v - pdf_thread_margin; + dir_BL_, dir_BR_: pdf_ann_top(last_thread) := tmp2.v + pdf_thread_margin; + dir_LT_, dir_LB_: pdf_ann_right(last_thread) := tmp2.h + pdf_thread_margin; + dir_RT_, dir_RB_: pdf_ann_left(last_thread) := tmp2.h - pdf_thread_margin; + endcases; + end; if pdf_last_thread_named_id then delete_token_ref(pdf_last_thread_id); last_thread := null; @@ -32884,6 +28783,7 @@ end; procedure do_dest(p, parent_box: pointer; x, y: scaled); var k: integer; +tmp1, tmp2: scaledpos; begin if not is_shipping_page then pdf_error("ext4", "destinations cannot be inside an XForm"); @@ -32904,8 +28804,10 @@ begin pdf_width(p), pdf_height(p), pdf_depth(p), pdf_dest_margin) else begin - pdf_left(p) := cur_h; - pdf_top(p) := cur_v; + tmp1.h := cur.h; tmp1.v := cur.v; + tmp2 := synch_p_with_c(tmp1); + pdf_ann_left(p) := tmp2.h; + pdf_ann_top(p) := tmp2.v; end; pdf_dest_fith, pdf_dest_fitbh: @@ -32913,16 +28815,22 @@ begin set_rect_dimens(p, parent_box, x, y, pdf_width(p), pdf_height(p), pdf_depth(p), pdf_dest_margin) - else - pdf_top(p) := cur_v; + else begin + tmp1.h := cur.h; tmp1.v := cur.v; + tmp2 := synch_p_with_c(tmp1); + pdf_ann_top(p) := tmp2.v; + end; pdf_dest_fitv, pdf_dest_fitbv: - if matrixused then + if matrixused then set_rect_dimens(p, parent_box, x, y, pdf_width(p), pdf_height(p), pdf_depth(p), pdf_dest_margin) - else - pdf_left(p) := cur_h; + else begin + tmp1.h := cur.h; tmp1.v := cur.v; + tmp2 := synch_p_with_c(tmp1); + pdf_ann_left(p) := tmp2.h; + end; pdf_dest_fit, pdf_dest_fitb: do_nothing; @@ -32933,20 +28841,20 @@ begin endcases; end; -procedure out_form(p: pointer); -var v: scaled; +procedure output_form(p: pointer); begin - pdf_end_text; - pdf_print_ln("q"); + pdf_goto_pagemode; + pdf_place_form(pos.h, pos.v, obj_info(pdf_xform_objnum(p))); if pdf_lookup_list(pdf_xform_list, pdf_xform_objnum(p)) = null then pdf_append_list(pdf_xform_objnum(p))(pdf_xform_list); - v := cur_v + obj_xform_depth(pdf_xform_objnum(p)); - pdf_set_origin_temp(cur_h, v); - pdf_print("/Fm"); - pdf_print_int(obj_info(pdf_xform_objnum(p))); - pdf_print_resname_prefix; - pdf_print_ln(" Do"); - pdf_print_ln("Q"); +end; + +procedure output_image(idx: integer); +begin + pdf_goto_pagemode; + out_image(idx, pos.h, pos.v); + if pdf_lookup_list(pdf_ximage_list, image_objnum(idx)) = null then + pdf_append_list(image_objnum(idx))(pdf_ximage_list); end; @ @= @@ -32963,14 +28871,15 @@ pdf_restore_node: pdf_out_restore; late_lua_node: do_late_lua(p); -close_lua_node: - closelua(late_lua_reg(p)); pdf_refobj_node: - pdf_append_list(pdf_obj_objnum(p))(pdf_obj_list); + if not is_obj_scheduled(pdf_obj_objnum(p)) then begin + pdf_append_list(pdf_obj_objnum(p))(pdf_obj_list); + set_obj_scheduled(pdf_obj_objnum(p)); + end; pdf_refxform_node: @; pdf_refximage_node: - @; + @; pdf_annot_node: do_annot(p, this_box, left_edge, top_edge + height(this_box)); pdf_start_link_node: @@ -32985,7 +28894,7 @@ pdf_start_thread_node: pdf_end_thread_node: end_thread; pdf_save_pos_node: - @; + @; special_node: pdf_special(p); othercases out_what(p); @@ -32994,25 +28903,56 @@ endcases @ @= @!is_shipping_page: boolean; {set to |shipping_page| when |pdf_ship_out| starts} -@ @= -begin - pdf_last_x_pos := cur_h; - pdf_last_y_pos := cur_page_height - cur_v -end - -@ @= -begin cur_v:=cur_v+pdf_height(p)+pdf_depth(p); - cur_h:=left_edge; - out_image(pdf_ximage_ref(p), cur_h-pdf_origin_h, pdf_origin_v-cur_v); - if pdf_lookup_list(pdf_ximage_list, image_objnum(pdf_ximage_ref(p))) = null then - pdf_append_list(image_objnum(pdf_ximage_ref(p)))(pdf_ximage_list); +@ @= +begin cur.h:=left_edge; + synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: begin + pos_down(pdf_height(p)+pdf_depth(p)); + end; + dir_TR_: begin + pos_left(pdf_width(p)); + pos_down(pdf_height(p)+pdf_depth(p)); + end; + dir_BL_: begin + end; + dir_BR_: begin + pos_left(pdf_width(p)); + end; + dir_LT_: begin + pos_down(pdf_width(p)); + end; + dir_RT_: begin + pos_left(pdf_height(p)+pdf_depth(p)); + pos_down(pdf_width(p)); + end; + dir_LB_: begin + end; + dir_RB_: begin + pos_left(pdf_height(p)+pdf_depth(p)); + end; + othercases + endcases; + output_image(pdf_ximage_idx(p)); + cur.v:=cur.v+pdf_height(p)+pdf_depth(p); end @ @= -begin cur_v:=cur_v+pdf_height(p); - cur_h:=left_edge; - out_form(p); - cur_v:=cur_v+pdf_depth(p); +begin + cur.h:=left_edge; + synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: begin + pos_down(pdf_height(p)+pdf_depth(p)); + end; + dir_TR_: begin + pos_left(pdf_width(p)); + pos_down(pdf_height(p)+pdf_depth(p)); + end; + othercases + endcases; + output_form(p); + cur.v:=cur.v+pdf_height(p)+pdf_depth(p); end @ @= @@ -33029,14 +28969,15 @@ pdf_restore_node: pdf_out_restore; late_lua_node: do_late_lua(p); -close_lua_node: - closelua(late_lua_reg(p)); pdf_refobj_node: - pdf_append_list(pdf_obj_objnum(p))(pdf_obj_list); + if not is_obj_scheduled(pdf_obj_objnum(p)) then begin + pdf_append_list(pdf_obj_objnum(p))(pdf_obj_list); + set_obj_scheduled(pdf_obj_objnum(p)); + end; pdf_refxform_node: @; pdf_refximage_node: - @; + @; pdf_annot_node: do_annot(p, this_box, left_edge, base_line); pdf_start_link_node: @@ -33052,27 +28993,68 @@ pdf_start_thread_node: pdf_end_thread_node: pdf_error("ext4", "\pdfendthread ended up in hlist"); pdf_save_pos_node: - @; + @; special_node: pdf_special(p); othercases if subtype(p)<>dir_node then out_what(p) -else @<(PDF) Output a reflection instruction if the direction has changed@>; +else @; endcases -@ @= +@ @= begin - cur_v:=base_line+pdf_depth(p); - out_image(pdf_ximage_ref(p), cur_h-pdf_origin_h, pdf_origin_v-cur_v); - if pdf_lookup_list(pdf_ximage_list, image_objnum(pdf_ximage_ref(p))) = null then - pdf_append_list(image_objnum(pdf_ximage_ref(p)))(pdf_ximage_list); - edge:=cur_h+pdf_width(p); cur_h:=edge; cur_v:=base_line; + cur.v:=base_line; + synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: begin + pos_down(pdf_depth(p)); + end; + dir_TR_: begin + pos_left(pdf_width(p)); + pos_down(pdf_depth(p)); + end; + dir_BL_: begin + pos_down(pdf_height(p)); + end; + dir_BR_: begin + pos_left(pdf_width(p)); + pos_down(pdf_height(p)); + end; + dir_LT_: begin + pos_left(pdf_height(p)); + pos_down(pdf_width(p)); + end; + dir_RT_: begin + pos_left(pdf_depth(p)); + pos_down(pdf_width(p)); + end; + dir_LB_: begin + pos_left(pdf_height(p)); + end; + dir_RB_: begin + pos_left(pdf_depth(p)); + end; + othercases + endcases; + output_image(pdf_ximage_idx(p)); + edge:=cur.h+pdf_width(p); cur.h:=edge; end @ @= begin - cur_v:=base_line; - out_form(p); - edge:=cur_h+pdf_width(p); cur_h:=edge; + cur.v:=base_line; + synch_pos_with_cur; + case box_direction(dvi_direction) of + dir_TL_: begin + pos_down(pdf_depth(p)); + end; + dir_TR_: begin + pos_down(pdf_depth(p)); + pos_left(pdf_width(p)); + end; + othercases + endcases; + output_form(p); + edge:=cur.h+pdf_width(p); cur.h:=edge; end @* \[53a] The extended features of \eTeX. @@ -33122,39 +29104,30 @@ that integer. @d Aleph_revision_code=job_name_code+1 {command code for \.{\\Alephrevision}} @d Omega_revision_code=job_name_code+2 {command code for \.{\\Omegarevision}} @d eTeX_revision_code=job_name_code+3 {command code for \.{\\eTeXrevision}} +@d font_identifier_code==job_name_code+4 {command code for \.{tex.fontidentifer} (lua)} @= -primitive("lastnodetype",last_item,last_node_type_code); +primitive_etex("lastnodetype",last_item,last_node_type_code,0); @!@:last_node_type_}{\.{\\lastnodetype} primitive@> -primitive("Alephversion",last_item,Aleph_version_code); +primitive_aleph("Alephversion",last_item,Aleph_version_code,0); @!@:eTeX_version_}{\.{\\Alephversion} primitive@> -primitive("Omegaversion",last_item,Omega_version_code); +primitive_aleph("Omegaversion",last_item,Omega_version_code,0); @!@:eTeX_version_}{\.{\\Omegaversion} primitive@> -primitive("eTeXversion",last_item,eTeX_version_code); +primitive_etex("eTeXversion",last_item,eTeX_version_code,0); @!@:eTeX_version_}{\.{\\eTeXversion} primitive@> -primitive("Alephminorversion",last_item,Aleph_minor_version_code); +primitive_aleph("Alephminorversion",last_item,Aleph_minor_version_code,0); @!@:eTeX_minor_version_}{\.{\\Alephminorversion} primitive@> -primitive("Omegaminorversion",last_item,Omega_minor_version_code); +primitive_aleph("Omegaminorversion",last_item,Omega_minor_version_code,0); @!@:eTeX_minor_version_}{\.{\\Omegaminorversion} primitive@> -primitive("eTeXminorversion",last_item,eTeX_minor_version_code); +primitive_etex("eTeXminorversion",last_item,eTeX_minor_version_code,0); @!@:eTeX_minor_version_}{\.{\\eTeXminorversion} primitive@> -primitive("Alephrevision",convert,Aleph_revision_code);@/ +primitive_aleph("Alephrevision",convert,Aleph_revision_code,0);@/ @!@:eTeX_revision_}{\.{\\Alephrevision} primitive@> -primitive("Omegarevision",convert,Omega_revision_code);@/ +primitive_aleph("Omegarevision",convert,Omega_revision_code,0);@/ @!@:eTeX_revision_}{\.{\\Omegarevision} primitive@> -primitive("eTeXrevision",convert,eTeX_revision_code);@/ +primitive_etex("eTeXrevision",convert,eTeX_revision_code,0);@/ @!@:eTeX_revision_}{\.{\\eTeXrevision} primitive@> -@ @= -last_node_type_code: print_esc("lastnodetype"); -Aleph_version_code: print_esc("Alephversion"); -Omega_version_code: print_esc("Omegaversion"); -eTeX_version_code: print_esc("eTeXversion"); -Aleph_minor_version_code: print_esc("Alephminorversion"); -Omega_minor_version_code: print_esc("Omegaminorversion"); -eTeX_minor_version_code: print_esc("eTeXminorversion"); - - @ @= Aleph_version_code: cur_val:=Aleph_version; Omega_version_code: cur_val:=Omega_version; @@ -33163,11 +29136,6 @@ Aleph_minor_version_code: cur_val:=Aleph_minor_version; Omega_minor_version_code: cur_val:=Omega_minor_version; eTeX_minor_version_code: cur_val:=eTeX_minor_version; -@ @= -Aleph_revision_code: print_esc("Alephrevision"); -Omega_revision_code: print_esc("Omegarevision"); -eTeX_revision_code: print_esc("eTeXrevision"); - @ @= Aleph_revision_code: do_nothing; Omega_revision_code: do_nothing; @@ -33182,35 +29150,39 @@ eTeX_revision_code: print(eTeX_revision); equivalents. @= -primitive("everyeof",assign_toks,every_eof_loc); +primitive_etex("everyeof",assign_toks,every_eof_loc,local_base); @!@:every_eof_}{\.{\\everyeof} primitive@> -primitive("tracingassigns",assign_int,int_base+tracing_assigns_code);@/ +primitive_etex("tracingassigns",assign_int,int_base+tracing_assigns_code,int_base);@/ @!@:tracing_assigns_}{\.{\\tracingassigns} primitive@> -primitive("tracinggroups",assign_int,int_base+tracing_groups_code);@/ +primitive_etex("tracinggroups",assign_int,int_base+tracing_groups_code,int_base);@/ @!@:tracing_groups_}{\.{\\tracinggroups} primitive@> -primitive("tracingifs",assign_int,int_base+tracing_ifs_code);@/ +primitive_etex("tracingifs",assign_int,int_base+tracing_ifs_code,int_base);@/ @!@:tracing_ifs_}{\.{\\tracingifs} primitive@> -primitive("tracingscantokens",assign_int,int_base+tracing_scan_tokens_code);@/ +primitive_etex("tracingscantokens",assign_int,int_base+tracing_scan_tokens_code,int_base);@/ @!@:tracing_scan_tokens_}{\.{\\tracingscantokens} primitive@> -primitive("tracingnesting",assign_int,int_base+tracing_nesting_code);@/ +primitive_etex("tracingnesting",assign_int,int_base+tracing_nesting_code,int_base);@/ @!@:tracing_nesting_}{\.{\\tracingnesting} primitive@> -primitive("predisplaydirection", - assign_int,int_base+pre_display_direction_code);@/ +primitive_etex("predisplaydirection", assign_int,int_base+pre_display_direction_code,int_base);@/ @!@:pre_display_direction_}{\.{\\predisplaydirection} primitive@> -primitive("lastlinefit",assign_int,int_base+last_line_fit_code);@/ +primitive_etex("lastlinefit",assign_int,int_base+last_line_fit_code,int_base);@/ @!@:last_line_fit_}{\.{\\lastlinefit} primitive@> -primitive("savingvdiscards",assign_int,int_base+saving_vdiscards_code);@/ +primitive_etex("savingvdiscards",assign_int,int_base+saving_vdiscards_code,int_base);@/ @!@:saving_vdiscards_}{\.{\\savingvdiscards} primitive@> -primitive("savinghyphcodes",assign_int,int_base+saving_hyph_codes_code);@/ +primitive_etex("savinghyphcodes",assign_int,int_base+saving_hyph_codes_code,int_base);@/ @!@:saving_hyph_codes_}{\.{\\savinghyphcodes} primitive@> -primitive("suppressfontnotfounderror",assign_int,int_base+suppress_fontnotfound_error_code);@/ -@!@:suppress_fontnotfound_error_codes_}{\.{\\suppressfontnotfounderror} primitive@> +primitive_luatex("suppressfontnotfounderror",assign_int,int_base+suppress_fontnotfound_error_code,int_base);@/ +@!@:suppress_fontnotfound_error_code_}{\.{\\suppressfontnotfounderror} primitive@> +primitive_luatex("suppresslongerror",assign_int,int_base+suppress_long_error_code,int_base);@/ +@!@:suppress_long_error_code_}{\.{\\suppresslongerror} primitive@> +primitive_luatex("suppressifcsnameerror",assign_int,int_base+suppress_ifcsname_error_code,int_base);@/ +@!@:suppress_ifcsname_error_code_}{\.{\\suppressifcsnameerror} primitive@> +primitive_luatex("suppressoutererror",assign_int,int_base+suppress_outer_error_code,int_base);@/ +@!@:suppress_outer_error_code_}{\.{\\suppressoutererror} primitive@> +primitive_luatex("synctex",assign_int,int_base+synctex_code,int_base);@/ +@!@:synctex_}{\.{\\synctex} primitive@> @ @d every_eof==equiv(every_eof_loc) -@= -every_eof_loc: print_esc("everyeof"); - @ @= tracing_assigns_code:print_esc("tracingassigns"); tracing_groups_code:print_esc("tracinggroups"); @@ -33222,6 +29194,9 @@ last_line_fit_code:print_esc("lastlinefit"); saving_vdiscards_code:print_esc("savingvdiscards"); saving_hyph_codes_code:print_esc("savinghyphcodes"); suppress_fontnotfound_error_code:print_esc("suppressfontnotfounderror"); +suppress_long_error_code:print_esc("suppresslongerror"); +suppress_outer_error_code:print_esc("suppressoutererror"); +synctex_code:print_esc("synctex"); @ In order to handle \.{\\everyeof} we need an array |eof_seen| of boolean variables. @@ -33290,15 +29265,11 @@ respectively. @d current_group_type_code=eTeX_int+2 {code for \.{\\currentgrouptype}} @= -primitive("currentgrouplevel",last_item,current_group_level_code); +primitive_etex("currentgrouplevel",last_item,current_group_level_code,0); @!@:current_group_level_}{\.{\\currentgrouplevel} primitive@> -primitive("currentgrouptype",last_item,current_group_type_code); +primitive_etex("currentgrouptype",last_item,current_group_type_code,0); @!@:current_group_type_}{\.{\\currentgrouptype} primitive@> -@ @= -current_group_level_code: print_esc("currentgrouplevel"); -current_group_type_code: print_esc("currentgrouptype"); - @ @= current_group_level_code: cur_val:=cur_level-level_one; current_group_type_code: cur_val:=cur_group; @@ -33312,18 +29283,13 @@ and the type and branch of the current conditional. @d current_if_branch_code=eTeX_int+5 {code for \.{\\currentifbranch}} @= -primitive("currentiflevel",last_item,current_if_level_code); +primitive_etex("currentiflevel",last_item,current_if_level_code,0); @!@:current_if_level_}{\.{\\currentiflevel} primitive@> -primitive("currentiftype",last_item,current_if_type_code); +primitive_etex("currentiftype",last_item,current_if_type_code,0); @!@:current_if_type_}{\.{\\currentiftype} primitive@> -primitive("currentifbranch",last_item,current_if_branch_code); +primitive_etex("currentifbranch",last_item,current_if_branch_code,0); @!@:current_if_branch_}{\.{\\currentifbranch} primitive@> -@ @= -current_if_level_code: print_esc("currentiflevel"); -current_if_type_code: print_esc("currentiftype"); -current_if_branch_code: print_esc("currentifbranch"); - @ @= current_if_level_code: begin q:=cond_ptr; cur_val:=0; while q<>null do @@ -33348,25 +29314,19 @@ font. @d font_char_ic_code=eTeX_dim+3 {code for \.{\\fontcharic}} @= -primitive("charwd",last_item,font_char_wd_code); -primitive("fontcharwd",last_item,font_char_wd_code); +primitive_omega("charwd",last_item,font_char_wd_code,0); +primitive_etex("fontcharwd",last_item,font_char_wd_code,0); @!@:font_char_wd_}{\.{\\fontcharwd} primitive@> -primitive("charht",last_item,font_char_ht_code); -primitive("fontcharht",last_item,font_char_ht_code); +primitive_omega("charht",last_item,font_char_ht_code,0); +primitive_etex("fontcharht",last_item,font_char_ht_code,0); @!@:font_char_ht_}{\.{\\fontcharht} primitive@> -primitive("chardp",last_item,font_char_dp_code); -primitive("fontchardp",last_item,font_char_dp_code); +primitive_omega("chardp",last_item,font_char_dp_code,0); +primitive_etex("fontchardp",last_item,font_char_dp_code,0); @!@:font_char_dp_}{\.{\\fontchardp} primitive@> -primitive("charic",last_item,font_char_ic_code); -primitive("fontcharic",last_item,font_char_ic_code); +primitive_omega("charit",last_item,font_char_ic_code,0); +primitive_etex("fontcharic",last_item,font_char_ic_code,0); @!@:font_char_ic_}{\.{\\fontcharic} primitive@> -@ @= -font_char_wd_code: print_esc("fontcharwd"); -font_char_ht_code: print_esc("fontcharht"); -font_char_dp_code: print_esc("fontchardp"); -font_char_ic_code: print_esc("fontcharic"); - @ @= font_char_wd_code, font_char_ht_code, @@ -33393,18 +29353,13 @@ commands return the indent and length parameters of the current @d par_shape_dimen_code=eTeX_dim+6 {code for \.{\\parshapedimen}} @= -primitive("parshapelength",last_item,par_shape_length_code); +primitive_etex("parshapelength",last_item,par_shape_length_code,0); @!@:par_shape_length_}{\.{\\parshapelength} primitive@> -primitive("parshapeindent",last_item,par_shape_indent_code); +primitive_etex("parshapeindent",last_item,par_shape_indent_code,0); @!@:par_shape_indent_}{\.{\\parshapeindent} primitive@> -primitive("parshapedimen",last_item,par_shape_dimen_code); +primitive_etex("parshapedimen",last_item,par_shape_dimen_code,0); @!@:par_shape_dimen_}{\.{\\parshapedimen} primitive@> -@ @= -par_shape_length_code: print_esc("parshapelength"); -par_shape_indent_code: print_esc("parshapeindent"); -par_shape_dimen_code: print_esc("parshapedimen"); - @ @= par_shape_length_code, par_shape_indent_code, @@ -33413,8 +29368,8 @@ par_shape_dimen_code: begin q:=cur_chr-par_shape_length_code; scan_int; else begin if q=2 then begin q:=cur_val mod 2; cur_val:=(cur_val+q)div 2; end; - if cur_val>vinfo(par_shape_ptr) then cur_val:=vinfo(par_shape_ptr); - cur_val:=vmem(par_shape_ptr+2*cur_val-q).sc; + if cur_val>vinfo(par_shape_ptr+1) then cur_val:=vinfo(par_shape_ptr+1); + cur_val:=vmem(par_shape_ptr+2*cur_val-q+1).sc; end; cur_val_level:=dimen_val; end; @@ -33425,12 +29380,9 @@ levels. @d show_groups=4 { \.{\\showgroups} } @= -primitive("showgroups",xray,show_groups); +primitive_etex("showgroups",xray,show_groups,0); @!@:show_groups_}{\.{\\showgroups} primitive@> -@ @= -show_groups:print_esc("showgroups"); - @ @= show_groups: begin begin_diagnostic; show_save_groups; end; @@ -33498,7 +29450,7 @@ loop@+begin print_nl("### "); print_group(true); goto found2; end; insert_group: - begin if saved(-2)=255 then print_esc("vadjust") + begin if saved(-2)=output_box then print_esc("vadjust") else begin print_esc("insert"); print_int(saved(-2)); end; goto found2; @@ -33515,7 +29467,7 @@ loop@+begin print_nl("### "); print_group(true); print_char("$"); goto found; end; math_left_group: - begin if type(nest[p+1].eTeX_aux_field)=left_noad then print_esc("left") + begin if subtype(nest[p+1].eTeX_aux_field)=left_noad_side then print_esc("left") else print_esc("middle"); goto found; end; @@ -33596,12 +29548,9 @@ end; @d show_tokens=5 { \.{\\showtokens} , must be odd! } @= -primitive("showtokens",xray,show_tokens); +primitive_etex("showtokens",xray,show_tokens,0); @!@:show_tokens_}{\.{\\showtokens} primitive@> -@ @= -show_tokens:print_esc("showtokens"); - @ The \.{\\unexpanded} primitive prevents expansion of tokens much as the result from \.{\\the} applied to a token variable. The \.{\\detokenize} primitive converts a token list into a list of @@ -33611,15 +29560,11 @@ use the fact that the command modifiers for \.{\\unexpanded} and are even. @= -primitive("unexpanded",the,1);@/ +primitive_etex("unexpanded",the,1,0);@/ @!@:unexpanded_}{\.{\\unexpanded} primitive@> -primitive("detokenize",the,show_tokens);@/ +primitive_etex("detokenize",the,show_tokens,0);@/ @!@:detokenize_}{\.{\\detokenize} primitive@> -@ @= -else if chr_code=1 then print_esc("unexpanded") -else print_esc("detokenize") - @ @= if odd(cur_chr) then begin c:=cur_chr; scan_general_text; @@ -33637,12 +29582,9 @@ if odd(cur_chr) then @d show_ifs=6 { \.{\\showifs} } @= -primitive("showifs",xray,show_ifs); +primitive_etex("showifs",xray,show_ifs,0); @!@:show_ifs_}{\.{\\showifs} primitive@> -@ @= -show_ifs:print_esc("showifs"); - @ @d print_if_line(#)==if #<>0 then begin print(" entered on line "); print_int(#); @@ -33669,12 +29611,9 @@ show_ifs: begin begin_diagnostic; print_nl(""); print_ln; interaction mode. @= -primitive("interactionmode",set_page_int,2); +primitive_etex("interactionmode",set_page_int,2,0); @!@:interaction_mode_}{\.{\\interactionmode} primitive@> -@ @= -else if chr_code=2 then print_esc("interactionmode") - @ @= else if m=2 then cur_val:=interaction @@ -33694,29 +29633,15 @@ else if c=2 then end; end -@ The |middle| feature of \eTeX\ allows one ore several \.{\\middle} -delimiters to appear between \.{\\left} and \.{\\right}. - -@= -primitive("middle",left_right,middle_noad); -@!@:middle_}{\.{\\middle} primitive@> - -@ @= -else if chr_code=middle_noad then print_esc("middle") - @ The |scan_tokens| feature of \eTeX\ defines the \.{\\scantokens} primitive. @= -primitive("scantokens",input,2); +primitive_etex("scantokens",input,2,0); @!@:scan_tokens_}{\.{\\scantokens} primitive@> -primitive("scantextokens",input,3); +primitive_luatex("scantextokens",input,3,0); @!@:scan_tex_tokens_}{\.{\\scantextokens} primitive@> -@ @= -else if chr_code=2 then print_esc("scantokens") -else if chr_code=3 then print_esc("scantextokens") - @ @= else if cur_chr=2 then pseudo_start else if cur_chr=3 then begin pseudo_start; name := 19; end @@ -33783,7 +29708,10 @@ if tracing_scan_tokens>0 then else if (term_offset>0)or(file_offset>0) then print_char(" "); name:=20; print("( "); incr(open_parens); update_terminal; end -else name:=18 +else begin + name:=18; + @; +end @ Here we read a line from the current pseudo file into |buffer|. @@ -33819,7 +29747,7 @@ end; @= procedure pseudo_close; {close the top level pseudo file} -var p,@!q: pointer; +var p: pointer; begin p:=vlink(pseudo_files); flush_node(pseudo_files); pseudo_files:=p; @@ -33829,12 +29757,9 @@ end; while pseudo_files<>null do pseudo_close; {flush pseudo files} @ @= -primitive("readline",read_to_cs,1);@/ +primitive_etex("readline",read_to_cs,1,0);@/ @!@:read_line_}{\.{\\readline} primitive@> -@ @= -else print_esc("readline") - @ @= if j=1 then begin while loc<=limit do {current line not yet finished} @@ -33857,36 +29782,25 @@ if j=1 then @d if_abs_dim_code=23 { `\.{\\ifabsdim}' } @= -primitive("unless",expand_after,1);@/ +primitive_etex("unless",expand_after,1,0);@/ @!@:unless_}{\.{\\unless} primitive@> -primitive("ifdefined",if_test,if_def_code); +primitive_etex("ifdefined",if_test,if_def_code,0); @!@:if_defined_}{\.{\\ifdefined} primitive@> -primitive("ifcsname",if_test,if_cs_code); +primitive_etex("ifcsname",if_test,if_cs_code,0); @!@:if_cs_name_}{\.{\\ifcsname} primitive@> -primitive("iffontchar",if_test,if_font_char_code); +primitive_etex("iffontchar",if_test,if_font_char_code,0); @!@:if_font_char_}{\.{\\iffontchar} primitive@> -primitive("ifincsname",if_test,if_in_csname_code); +primitive_pdftex("ifincsname",if_test,if_in_csname_code,0); @!@:if_in_csname_}{\.{\\ifincsname} primitive@> -primitive("ifabsnum",if_test,if_abs_num_code); +primitive_luatex("ifabsnum",if_test,if_abs_num_code,0); @!@:if_abs_num_}{\.{\\ifabsnum} primitive@> -primitive("ifabsdim",if_test,if_abs_dim_code); +primitive_luatex("ifabsdim",if_test,if_abs_dim_code,0); @!@:if_abs_dim_}{\.{\\ifabsdim} primitive@> -primitive("ifpdfabsnum",if_test,if_abs_num_code); +primitive_pdftex("ifpdfabsnum",if_test,if_abs_num_code,0); @!@:if_abs_num_}{\.{\\ifpdfabsnum} primitive@> -primitive("ifpdfabsdim",if_test,if_abs_dim_code); +primitive_pdftex("ifpdfabsdim",if_test,if_abs_dim_code,0); @!@:if_abs_dim_}{\.{\\ifpdfabsdim} primitive@> -@ @= -else print_esc("unless") - -@ @= -if_def_code:print_esc("ifdefined"); -if_cs_code:print_esc("ifcsname"); -if_font_char_code:print_esc("iffontchar"); -if_in_csname_code:print_esc("ifincsname"); -if_abs_num_code:print_esc("ifabsnum"); -if_abs_dim_code:print_esc("ifabsdim"); - @ The result of a boolean condition is reversed when the conditional is preceded by \.{\\unless}. @@ -33926,10 +29840,22 @@ if_cs_code:begin n:=get_avail; p:=n; {head of the list of characters} repeat get_x_token; if cur_cs=0 then store_new_token(cur_tok); until cur_cs<>0; - if cur_cmd<>end_cs_name then @; - @; + if cur_cmd<>end_cs_name then begin + if suppress_ifcsname_error then begin + repeat get_x_token; + until cur_cmd=end_cs_name; + end + else begin + @; + @; + b:=(eq_type(cur_cs)<>undefined_cs); + end; + end + else begin + @; + b:=(eq_type(cur_cs)<>undefined_cs); + end; flush_list(n); - b:=(eq_type(cur_cs)<>undefined_cs); end; @ @= @@ -34002,12 +29928,9 @@ expansions when lists of expanded tokens are built, e.g., for \.{\\edef} or during \.{\\write}. @= -primitive("protected",prefix,8); +primitive_etex("protected",prefix,8,0); @!@:protected_}{\.{\\protected} primitive@> -@ @= -else if chr_code=8 then print_esc("protected") - @ The |get_x_or_protected| procedure is like |get_x_token| except that protected macros are not expanded. @@ -34138,21 +30061,15 @@ end; @ Here are the additional \eTeX\ primitives for expressions. @= -primitive("numexpr",last_item,eTeX_expr-int_val+int_val); +primitive_etex("numexpr",last_item,eTeX_expr-int_val+int_val,0); @!@:num_expr_}{\.{\\numexpr} primitive@> -primitive("dimexpr",last_item,eTeX_expr-int_val+dimen_val); +primitive_etex("dimexpr",last_item,eTeX_expr-int_val+dimen_val,0); @!@:dim_expr_}{\.{\\dimexpr} primitive@> -primitive("glueexpr",last_item,eTeX_expr-int_val+glue_val); +primitive_etex("glueexpr",last_item,eTeX_expr-int_val+glue_val,0); @!@:glue_expr_}{\.{\\glueexpr} primitive@> -primitive("muexpr",last_item,eTeX_expr-int_val+mu_val); +primitive_etex("muexpr",last_item,eTeX_expr-int_val+mu_val,0); @!@:mu_expr_}{\.{\\muexpr} primitive@> -@ @= -eTeX_expr-int_val+int_val: print_esc("numexpr"); -eTeX_expr-int_val+dimen_val: print_esc("dimexpr"); -eTeX_expr-int_val+glue_val: print_esc("glueexpr"); -eTeX_expr-int_val+mu_val: print_esc("muexpr"); - @ This code for reducing |cur_val_level| and\slash or negating the result is similar to the one for all the other cases of |scan_something_internal|, with the difference that |scan_expr| has @@ -34305,7 +30222,6 @@ expression so far and |r| is the state of its evaluation; |t| is the term so far and |s| is the state of its evaluation; finally |n| is the numerator for a combined multiplication and division, if any. -@d expr_node=39 { stack entry for subexpressions} @d expr_type(#)==type(#+1) @d expr_state(#)==subtype(#+1) @d expr_e_field(#)==vlink(#+1) {saved expression so far} @@ -34562,21 +30478,15 @@ and their orders of ``infinity'' of a glue specification. @d glue_shrink_code=eTeX_dim+8 {code for \.{\\glueshrink}} @= -primitive("gluestretchorder",last_item,glue_stretch_order_code); +primitive_etex("gluestretchorder",last_item,glue_stretch_order_code,0); @!@:glue_stretch_order_}{\.{\\gluestretchorder} primitive@> -primitive("glueshrinkorder",last_item,glue_shrink_order_code); +primitive_etex("glueshrinkorder",last_item,glue_shrink_order_code,0); @!@:glue_shrink_order_}{\.{\\glueshrinkorder} primitive@> -primitive("gluestretch",last_item,glue_stretch_code); +primitive_etex("gluestretch",last_item,glue_stretch_code,0); @!@:glue_stretch_}{\.{\\gluestretch} primitive@> -primitive("glueshrink",last_item,glue_shrink_code); +primitive_etex("glueshrink",last_item,glue_shrink_code,0); @!@:glue_shrink_}{\.{\\glueshrink} primitive@> -@ @= -glue_stretch_order_code: print_esc("gluestretchorder"); -glue_shrink_order_code: print_esc("glueshrinkorder"); -glue_stretch_code: print_esc("gluestretch"); -glue_shrink_code: print_esc("glueshrink"); - @ @= glue_stretch_order_code, glue_shrink_order_code: begin scan_normal_glue; q:=cur_val; @@ -34601,15 +30511,11 @@ into normal glue and vice versa; they allow to manipulate math glue with @d glue_to_mu_code=eTeX_mu {code for \.{\\gluetomu}} @= -primitive("mutoglue",last_item,mu_to_glue_code); +primitive_etex("mutoglue",last_item,mu_to_glue_code,0); @!@:mu_to_glue_}{\.{\\mutoglue} primitive@> -primitive("gluetomu",last_item,glue_to_mu_code); +primitive_etex("gluetomu",last_item,glue_to_mu_code,0); @!@:glue_to_mu_}{\.{\\gluetomu} primitive@> -@ @= -mu_to_glue_code: print_esc("mutoglue"); -glue_to_mu_code: print_esc("gluetomu"); - @ @= mu_to_glue_code: scan_mu_glue; @@ -34640,15 +30546,11 @@ distinguished by their |chr_code| values |last_box_code| and |copy_code|. @= -primitive("pagediscards",un_vbox,last_box_code);@/ +primitive_etex("pagediscards",un_vbox,last_box_code,0);@/ @!@:page_discards_}{\.{\\pagediscards} primitive@> -primitive("splitdiscards",un_vbox,vsplit_code);@/ +primitive_etex("splitdiscards",un_vbox,vsplit_code,0);@/ @!@:split_discards_}{\.{\\splitdiscards} primitive@> -@ @= -else if chr_code=last_box_code then print_esc("pagediscards") -else if chr_code=vsplit_code then print_esc("splitdiscards") - @ @= begin vlink(tail):=disc_ptr[cur_chr]; disc_ptr[cur_chr]:=null; goto done; @@ -34664,27 +30566,22 @@ penalty values to be used instead of the corresponding single values. @d display_widow_penalties_ptr==equiv(display_widow_penalties_loc) @= -primitive("interlinepenalties",set_shape,inter_line_penalties_loc);@/ +primitive_etex("interlinepenalties",set_etex_shape,inter_line_penalties_loc,etex_pen_base);@/ @!@:inter_line_penalties_}{\.{\\interlinepenalties} primitive@> -primitive("clubpenalties",set_shape,club_penalties_loc);@/ +primitive_etex("clubpenalties",set_etex_shape,club_penalties_loc,etex_pen_base);@/ @!@:club_penalties_}{\.{\\clubpenalties} primitive@> -primitive("widowpenalties",set_shape,widow_penalties_loc);@/ +primitive_etex("widowpenalties",set_etex_shape,widow_penalties_loc,etex_pen_base);@/ @!@:widow_penalties_}{\.{\\widowpenalties} primitive@> -primitive("displaywidowpenalties",set_shape,display_widow_penalties_loc);@/ +primitive_etex("displaywidowpenalties",set_etex_shape,display_widow_penalties_loc,etex_pen_base);@/ @!@:display_widow_penalties_}{\.{\\displaywidowpenalties} primitive@> -@ @= -inter_line_penalties_loc: print_esc("interlinepenalties"); -club_penalties_loc: print_esc("clubpenalties"); -widow_penalties_loc: print_esc("widowpenalties"); -display_widow_penalties_loc: print_esc("displaywidowpenalties"); - @ @= begin scan_int; if (equiv(m)=null)or(cur_val<0) then cur_val:=0 else begin if cur_val>penalty(equiv(m)) then cur_val:=penalty(equiv(m)); cur_val:=penalty(equiv(m)+cur_val); end; +cur_val_level:=int_val; end @ This is needed to get the relative order of the marks code correct @@ -34715,11 +30612,28 @@ end; function set_tex_dimen_register (j:integer;v:scaled):integer; var a:small_number; begin {return non-nil for error} -a:=0; +if global_defs>0 then a:=4 else a:=0; word_define(j+scaled_base,v); set_tex_dimen_register := 0; end; +function get_tex_skip_register (j:integer):halfword; +begin + get_tex_skip_register := skip(j); +end; + +function set_tex_skip_register (j:integer;v:halfword):integer; +var a:small_number; +begin {return non-nil for error} + if global_defs>0 then a:=4 else a:=0; + if type(v) <> glue_spec_node then + set_tex_skip_register := 1 + else begin + word_define(j+skip_base,v); + set_tex_skip_register := 0; + end; +end; + function get_tex_count_register (j:integer):scaled; begin get_tex_count_register := count(j); @@ -34728,9 +30642,9 @@ end; function set_tex_count_register (j:integer;v:scaled):integer; var a:small_number; begin {return non-nil for error} -a:=0; -word_define(j+count_base,v); -set_tex_count_register := 0; + if global_defs>0 then a:=4 else a:=0; + word_define(j+count_base,v); + set_tex_count_register := 0; end; function get_tex_attribute_register (j:integer):scaled; @@ -34741,7 +30655,9 @@ end; function set_tex_attribute_register (j:integer;v:scaled):integer; var a:small_number; begin {return non-nil for error} -a:=0; +if global_defs>0 then a:=4 else a:=0; +if (j)>max_used_attr then max_used_attr:=(j); +attr_list_cache:=cache_disabled; word_define(j+attribute_base,v); set_tex_attribute_register := 0; end; @@ -34751,7 +30667,7 @@ var s:str_number; begin s:=""; if toks(j) <> min_halfword then begin - s := tokens_to_string(toks(j)); + s := tokens_to_string(toks(j)); end; get_tex_toks_register := s; end; @@ -34770,7 +30686,7 @@ begin pool_ptr := s_pool_ptr; token_ref_count(ref) := 0; link(ref) := link(temp_token_head); - a:=0; + if global_defs>0 then a:=4 else a:=0; define(j+toks_base,call,ref); flush_str(s); end; @@ -34783,8 +30699,8 @@ end; function set_tex_box_register (j:integer;v:scaled):integer; var a:small_number; begin {return non-nil for error} -a:=0; -eq_define(j+box_base,box_ref,v); +if global_defs>0 then a:=4 else a:=0; +define(j+box_base,box_ref,v); set_tex_box_register := 0; end; @@ -34851,12 +30767,12 @@ end; function get_cur_v: integer; begin - get_cur_v := cur_page_height - cur_v; + get_cur_v := cur_page_size.v - cur.v; end; function get_cur_h: integer; begin - get_cur_h := cur_h; + get_cur_h := cur.h; end; @* \[54] $\Omega$ changes. @@ -35067,22 +30983,25 @@ state:=mid_line; start:=first; last:=start; loc:=start; +line_catcode_table:=DEFAULT_CAT_TABLE; line_partial:=false; for otp_counter:=1 to otp_output_end do begin { convert back to utf-8 } - t := otp_output_buf[otp_counter]; - if otp_counter < otp_output_end then - if ((t>=@"D800) and (t<@"DC00)) then - if (otp_output_buf[otp_counter+1]>=@"DC00) - and (otp_output_buf[otp_counter+1]<@"E000) then begin - incr(otp_counter); - t := (t-@"D800) * @"400 + (otp_output_buf[otp_counter]-@"DC00) + @"10000; - end - else if ((t>=@"DC00) and (t<@"E000)) then - if (otp_output_buf[otp_counter+1]>=@"D800) - and (otp_output_buf[otp_counter+1]<@"DC00) then begin - incr(otp_counter); - t := (otp_output_buf[otp_counter]-@"D800) * @"400 + (t-@"DC00) + @"10000; - end; + t := otp_output_buf[otp_counter]; + if otp_counter < otp_output_end then begin + if ((t>=@"D800) and (t<@"DC00)) then begin + if (otp_output_buf[otp_counter+1]>=@"DC00) + and (otp_output_buf[otp_counter+1]<@"E000) then begin + incr(otp_counter); + t := (t-@"D800) * @"400 + (otp_output_buf[otp_counter]-@"DC00) + @"10000; + end + else if ((t>=@"DC00) and (t<@"E000)) then + if (otp_output_buf[otp_counter+1]>=@"D800) + and (otp_output_buf[otp_counter+1]<@"DC00) then begin + incr(otp_counter); + t := (otp_output_buf[otp_counter]-@"D800) * @"400 + (t-@"DC00) + @"10000; + end; + end; + end; if t <= @"7F then buffer[last]:= t else if t<=@"7FF then begin @@ -35092,7 +31011,7 @@ for otp_counter:=1 to otp_output_end do begin @; buffer[last]:=@"80 + t mod @"40; end - else if t<=@"FFFF then begin + else if t<=@"FFFF then begin buffer[last]:=@"E0 + t div @"1000; incr(last); if last=buf_size-2 then @@ -35550,38 +31469,19 @@ end end @ @= -primitive("ocp", def_ocp, 0); -primitive("externalocp", def_ocp, 1); -primitive("ocplist", def_ocp_list, 0); -primitive("pushocplist", push_ocp_list, 0); -primitive("popocplist", pop_ocp_list, 0); -primitive("clearocplists", clear_ocp_lists, 0); -primitive("addbeforeocplist", ocp_list_op, add_before_op); -primitive("addafterocplist", ocp_list_op, add_after_op); -primitive("removebeforeocplist", ocp_list_op, remove_before_op); -primitive("removeafterocplist", ocp_list_op, remove_after_op); -primitive("ocptracelevel", ocp_trace_level, 0); +primitive_omega("ocp", def_ocp, 0,0); +primitive_omega("externalocp", def_ocp, 1,0); +primitive_omega("ocplist", def_ocp_list, 0,0); +primitive_omega("pushocplist", push_ocp_list, 0,0); +primitive_omega("popocplist", pop_ocp_list, 0,0); +primitive_omega("clearocplists", clear_ocp_lists, 0,0); +primitive_omega("addbeforeocplist", ocp_list_op, add_before_op,0); +primitive_omega("addafterocplist", ocp_list_op, add_after_op,0); +primitive_omega("removebeforeocplist", ocp_list_op, remove_before_op,0); +primitive_omega("removeafterocplist", ocp_list_op, remove_after_op,0); +primitive_omega("ocptracelevel", ocp_trace_level, 0,0); equiv(ocp_trace_level_base):=0; -@ @= -set_ocp: begin - print("select ocp "); - slow_print(ocp_name(chr_code)); - end; -def_ocp: if cur_chr=0 then print_esc("ocp") - else print_esc("externalocp"); -set_ocp_list: print("select ocp list "); -def_ocp_list: print_esc("ocplist"); -push_ocp_list: print_esc("pushocplist"); -pop_ocp_list: print_esc("popocplist"); -clear_ocp_lists: print_esc("clearocplists"); -ocp_list_op: - if chr_code=add_before_op then print_esc("addbeforeocplist") - else if chr_code=add_after_op then print_esc("addafterocplist") - else if chr_code=remove_before_op then print_esc("removebeforeocplist") - else {|chr_code|=|remove_after_op|} print_esc("removeafterocplist"); -ocp_trace_level: print_esc("ocptracelevel"); - @ @= set_ocp: begin print_err("To use ocps, use the "); print_esc("pushocplist"); @@ -35611,7 +31511,6 @@ label common_ending; var u:pointer; {user's ocp identifier} @!f:internal_ocp_number; {runs through existing ocps} @!t:str_number; {name for the frozen ocp identifier} -@!old_setting:0..max_selector; {holds |selector| setting} @!flushable_string:str_number; {string not yet referenced} @!external_ocp:boolean; {external binary file} begin if job_name=0 then open_log_file; @@ -35620,13 +31519,7 @@ begin if job_name=0 then open_log_file; if cur_chr=1 then external_ocp:=true else external_ocp:=false; get_r_token; u:=cur_cs; -if u>=hash_base then t:=text(u) -else if u=null_cs then t:="OCP" -else begin old_setting:=selector; selector:=new_string; - print("OCP"); print(u-active_base); selector:=old_setting; -@.OCPx@> - str_room(1); t:=make_string; - end; +if u>=hash_base then t:=text(u) else t:="OCP"; define(u,set_ocp,null_ocp); scan_optional_equals; scan_file_name; @; @@ -35659,18 +31552,11 @@ procedure new_ocp_list(@!a:small_number); var u:pointer; {user's ocp list identifier} @!f:internal_ocp_list_number; {runs through existing ocp lists} @!t:str_number; {name for the frozen ocp list identifier} -@!old_setting:0..max_selector; {holds |selector| setting} begin if job_name=0 then open_log_file; {avoid confusing \.{texput} with the ocp list name} @.texput@> get_r_token; u:=cur_cs; -if u>=hash_base then t:=text(u) -else if u=null_cs then t:="OCPLIST" -else begin old_setting:=selector; selector:=new_string; - print("OCPLIST"); print(u-active_base); selector:=old_setting; -@.OCPx@> - str_room(1); t:=make_string; - end; +if u>=hash_base then t:=text(u) else t:="OCPLIST"; define(u,set_ocp_list,null_ocp_list); scan_optional_equals; f:=read_ocp_list; equiv(u) := f; eqtb[ocp_list_id_base+f] := eqtb[u]; @@ -35744,6 +31630,203 @@ define(ocp_active_max_ptr_base, data, active_max_ptr); end; +@* \[54/SyncTeX] The {\sl Synchronize \TeX nology}. +This section is devoted to the {\sl Synchronize \TeX nology} +- or simply {\sl Sync\TeX} - used to synchronize between input and output. +This section explains how synchronization basics are implemented. +Before we enter into more technical details, +let us recall in a few words what is synchronization. + +\TeX\ typesetting system clearly separates the input and the output material, +and synchronization will provide a new link between both that can help +text editors and viewers to work together. +More precisely, forwards synchronization is the ability, +given a location in the input source file, +to find what is the corresponding place in the output. +Backwards synchronization just performs the opposite: +given a location in the output, +retrieve the corresponding material in the input source file. + +For better code management and maintainance, we adopt a naming convention. +Throughout this program, code related to the {\sl Synchronize \TeX nology} is tagged +with the ``{\sl synctex}'' key word. Any code extract where {\sl Sync\TeX} plays +its part, either explicitly or implicitly, (should) contain the string ``{\sl synctex}''. +This naming convention also holds for external files. +Moreover, all the code related to {\sl Sync\TeX} is gathered in this section, +except the definitions. + +@ Enabling synchronization should be performed from the command line, +|synctexoption| is used for that purpose. +This global integer variable is declared here but it is not used here. +This is just a placeholder where the command line controller will put +the {\sl Sync\TeX} related options, and the {\sl Sync\TeX} controller will read them. + +@ @= +@!synctexoption:integer; + +@ A convenient primitive is provided: +\.{\\synctex=1} in the input source file enables synchronization whereas +\.{\\synctex=0} disables it. +Its memory address is |synctex_code|. +It is initialized by the {\sl Sync\TeX} controller to the command-line option if given. +The controller may filter some reserved bits. + +@ In order to give the {\sl Sync\TeX} controller read and write access to +the contents of the \.{\\synctex} primitive, we declare |synctexoffset|, +such that |mem[synctexoffset]| and \.{\\synctex} correspond to +the same memory storage. |synctexoffset| is initialized to +the correct value when quite everything is initialized. + +@ @= +@!synctexoffset:integer; {holds the true value of |synctex_code|} + +@ @= +synctexoffset:=int_base+synctex_code; + +@ @= +synctex_init_command; + +@ Synchronization is achieved with the help of an auxiliary file named +`\.{{\sl jobname}.synctex}' ({\sl jobname} is the contents of the +\.{\\jobname} macro), where a {\sl Sync\TeX} controller implemented +in the external |synctex.c| file will store geometrical information. +This {\sl Sync\TeX} controller will take care of every technical details +concerning the {\sl Sync\TeX} file, we will only focus on the messages +the controller will receive from the \TeX\ program. + +The most accurate synchronization information should allow to map +any character of the input source file to the corresponding location +in the output, if relevant. +Ideally, the synchronization information of the input material consists of +the file name, the line and column numbers of every character. +The synchronization information in the output is simply the page number and +either point coordinates, or box dimensions and position. +The problem is that the mapping between these informations is only known at +ship out time, which means that we must keep track of the input +synchronization information until the pages ship out. + +As \TeX\ only knows about file names and line numbers, +but forgets the column numbers, we only consider a +restricted input synchronization information called {\sl Sync\TeX\ information}. +It consists of a unique file name identifier, the {\sl Sync\TeX\ file tag}, +and the line number. + +Keeping track of such information, +should be different whether characters or nodes are involved. +Actually, only certain nodes are involved in {\sl Sync\TeX}, +we call them {\sl synchronized nodes}. +Synchronized nodes store the {\sl Sync\TeX} information in their last two words: +the first one contains a {\sl Sync\TeX\ file tag} uniquely identifying +the input file, and the second one contains the current line number, +as returned by the \.{\\inputlineno} primitive. +The |synctex_field_size| macro contains the necessary size to store +the {\sl Sync\TeX} information in a node. + +When declaring the size of a new node, it is recommanded to use the following +convention: if the node is synchronized, use a definition similar to +|my_synchronized_node_size|={\sl xxx}+|synctex_field_size|. +Moreover, one should expect that the {\sl Sync\TeX} information is always stored +in the last two words of a synchronized node. + +@ By default, every node with a sufficiently big size is initialized +at creation time in the |get_node| routine with the current +{\sl Sync\TeX} information, whether or not the node is synchronized. +One purpose is to set this information very early in order to minimize code +dependencies, including forthcoming extensions. +Another purpose is to avoid the assumption that every node type has a dedicated getter, +where initialization should take place. Actually, it appears that some nodes are created +using directly the |get_node| routine and not the dedicated constructor. +And finally, initializing the node at only one place is less error prone. + +@ Instead of storing the input file name, it is better to store just an identifier. +Each time \TeX\ opens a new file, it notifies the {\sl Sync\TeX} controller with +a |synctex_start_input| message. +This controller will create a new {\sl Sync\TeX} file tag and +will update the current input state record accordingly. +If the input comes from the terminal or a pseudo file, the |synctex_tag| is set to 0. +It results in automatically disabling synchronization for material +input from the terminal or pseudo files. + +@ @= +synctex_start_input; {Give control to the {\sl Sync\TeX} controller} + +@ @= +synctex_tag:=0; + +@ @= +synctex_tag:=0; + +@ @= +synctex_terminate(log_opened); {Let the {\sl Sync\TeX} controller close its files.} + +@ Synchronized nodes are boxes, math, kern and glue nodes. +Other nodes should be synchronized too, in particular math noads. +\TeX\ assumes that math, kern and glue nodes have the same size, +this is why both are synchronized. +{\sl In fine}, only horizontal lists are really used in {\sl Sync\TeX}, +but all box nodes are considered the same with respect to synchronization, +because a box node type is allowed to change at execution time. + +The next sections are the various messages sent to the {\sl Sync\TeX} controller. +The argument is either the box or the node currently shipped out. +The vertical boxes are not recorded, but the code is available for clients. + +@ @= +pdf_output_value:=pdf_output; {{\sl Sync\TeX}: we assume that |pdf_output| is properly set up} +synctex_sheet(mag); + +@ @= +synctex_teehs; + +@ @= +synctex_vlist(this_box); + +@ @= +synctex_tsilv(this_box); + +@ @= +synctex_hlist(this_box); + +@ @= +synctex_tsilh(this_box); + +@ @= + if type(p)=vlist_node then begin + synctex_void_vlist(p,this_box); + end + else begin + synctex_void_hlist(p,this_box); + end; + +@ @= +synctex_current; + +@ @= +synctex_horizontal_rule_or_glue(p,this_box); + +@ @= +synctex_kern(p,this_box); + +@ @= +synctex_math(p,this_box); + + +@ {\sl Nota Bene:} +The {\sl Sync\TeX} code is very close to the memory model. +It is not connected to any other part of the code, +except for memory management. It is possible to neutralize the {\sl Sync\TeX} code +rather simply. The first step is to define a null |synctex_field_size|. +The second step is to comment out the code in ``Initialize bigger nodes...'' and every +``Copy ... {\sl Sync\TeX} information''. +The last step will be to comment out the |synctex_tag_field| related code in the +definition of |synctex_tag| and the various ``Prepare ... {\sl Sync\TeX} information''. +Then all the remaining code should be just harmless. +The resulting program would behave exactly the same as if absolutely no {\sl Sync\TeX} +related code was there, including memory management. +Of course, all this assumes that {\sl Sync\TeX} is turned off from the command line. +@^synctex@> +@^synchronization@> + @* \[54] System-dependent changes. This section should be replaced, if necessary, by any special modifications of the program diff --git a/Build/source/texk/web2c/luatexdir/luatexextra.in b/Build/source/texk/web2c/luatexdir/luatexextra.in index ffbd65f3c1c..faa2ef972d8 100644 --- a/Build/source/texk/web2c/luatexdir/luatexextra.in +++ b/Build/source/texk/web2c/luatexdir/luatexextra.in @@ -1,32 +1,31 @@ -/* -Copyright (c) 1996-2004 Han The Thanh, +/* luatexextra.in: banner etc. for luaTeX. + + Copyright 1996-2006 Han The Thanh + Copyright 2006-2008 Taco Hoekwater -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ -$Id$ -*/ - -/* luatexextra.in: banner etc. for luaTeX. +/* $Id$ */ +/* This is included by luaTeX, from ../luatexextra.c (generated from ../lib/texmfmp.c). */ -#define BANNER "This is luaTeX, Version 3.141592-LUATEX-VERSION-ETEX-VERSION" +#define BANNER "This is LuaTeX, Version LUATEX-VERSION" #define COPYRIGHT_HOLDER "Taco Hoekwater" #define AUTHOR NULL #define PROGRAM_HELP LUATEXHELP @@ -39,4 +38,3 @@ $Id$ #define INI_PROGRAM "luainitex" #define VIR_PROGRAM "luavirtex" #define TEXMFENGINENAME "luatex" - diff --git a/Build/source/texk/web2c/luatexdir/luatexlib.mk b/Build/source/texk/web2c/luatexdir/luatexlib.mk index d16ed88a709..55e9ce8dd2a 100644 --- a/Build/source/texk/web2c/luatexdir/luatexlib.mk +++ b/Build/source/texk/web2c/luatexdir/luatexlib.mk @@ -1,4 +1,4 @@ -## luatexlib.mk - Makefile fragment for libraries used by pdf[ex]tex. +## luatexlib.mk - Makefile fragment for libraries used by luatex. # $Id$ # Public domain. @@ -10,16 +10,12 @@ Makefile: luatexdir/luatexlib.mk # libpdf itself luapdflib = luatexdir/libpdf.a -luapdflib_sources = $(srcdir)/luatexdir/*.c $(srcdir)/luatexdir/*.cc \ - $(srcdir)/luatexdir/*.h +luapdflib_sources = $(srcdir)/luatexdir/*.c $(srcdir)/luatexdir/*.h \ + $(srcdir)/luatexdir/*/*.c $(srcdir)/luatexdir/*/*.h \ + $(srcdir)/luatexdir/*/*.cc $(luapdflib): $(luapdflib_sources) luatexdir/luatexextra.h ctangle - cd luatexdir && mkdir -p font image lua lang tex && $(MAKE) $(common_makeargs) libpdf.a - -# makecpool: - -luatexdir/makecpool: luatexdir/makecpool.c - cd luatexdir && $(MAKE) $(common_makeargs) makecpool + cd luatexdir && mkdir -p font image lua lang pdf tex utils && $(MAKE) $(common_makeargs) libpdf.a # lua @@ -35,9 +31,6 @@ ifeq ($(target),i386-mingw32) luatarget = mingw endif else -ifeq ($(target),i386-linux) - luatarget = posix -endif endif @@ -63,7 +56,7 @@ $(SLNUNICODEDEP): $(SLNUNICODEDIR)/slnunico.c $(SLNUNICODEDIR)/slnudata.c # because the zlib path is relative and can't be found otherwise. # # final trickyness: configure writes a Makefile in the source -# directory. it is not needed by anything, so I delete it right away +# directory. it is needed by anything, so I delete it right away zzipretarget= @@ -102,6 +95,19 @@ $(LUAFSDEP): $(LUAFSDIR)/src/lfs.c $(LUAFSDIR)/src/lfs.h mkdir -p $(LUAFSDIR) && cd $(LUAFSDIR) && cp -R $(LUAFSSRCDIR)/* . && \ cd src && $(CC) $(CFLAGS) $(LUAFSINC) -g -o lfs.o -c lfs.c + +# luasocket + +LUASOCKETDIR=../../libs/luasocket +LUASOCKETSRCDIR=$(srcdir)/$(LUASOCKETDIR) +LUASOCKETDEP=$(LUASOCKETDIR)/src/socket.a +LUASOCKETINC=-I../../lua51 + +$(LUASOCKETDEP): $(LUASOCKETDIR)/src/luasocket.c $(LUASOCKETDIR)/src/luasocket.h + mkdir -p $(LUASOCKETDIR) && cd $(LUASOCKETDIR) && cp -R $(LUASOCKETSRCDIR)/* . && \ + cd src && make + + # luapeg LUAPEGDIR=../../libs/luapeg LUAPEGSRCDIR=$(srcdir)/$(LUAPEGDIR) @@ -124,10 +130,14 @@ LUAFFDIR=../../libs/luafontforge LUAFFSRCDIR=$(srcdir)/$(LUAFFDIR) LUAFFDEP=$(LUAFFDIR)/libff.a $(LUAFFDEP): always - mkdir -p $(LUAFFDIR) && cp -f $(LUAFFSRCDIR)/Makefile $(LUAFFDIR) - mkdir -p $(LUAFFDIR)/fontforge && cp -f $(LUAFFSRCDIR)/fontforge/fontforge/Makefile $(LUAFFDIR)/fontforge - mkdir -p $(LUAFFDIR)/Unicode && cp -f $(LUAFFSRCDIR)/fontforge/Unicode/Makefile $(LUAFFDIR)/Unicode - cd $(LUAFFDIR) && $(MAKE) + mkdir -p $(LUAFFDIR) && cd $(LUAFFDIR) && cp -f $(LUAFFSRCDIR)/Makefile . && $(MAKE) + +# luaprof +LUAPROFDIR=../../libs/luaprofiler +LUAPROFSRCDIR=$(srcdir)/$(LUAPROFDIR) +LUAPROFDEP=$(LUAPROFDIR)/libprofiler.a +$(LUAPROFDEP): always + mkdir -p $(LUAPROFDIR) && cd $(LUAPROFDIR) && cp -f $(LUAPROFSRCDIR)/Makefile . && $(MAKE) # luazlib @@ -138,16 +148,20 @@ LUAZLIBINC=-I$(ZLIBSRCDIR) -I$(LIBLUASRCDIR) $(LUAZLIBDEP): $(LUAZLIBDIR)/lgzip.c $(LUAZLIBDIR)/lzlib.c mkdir -p $(LUAZLIBDIR) && cd $(LUAZLIBDIR) && cp -f $(LUAZLIBSRCDIR)/* . && $(CC) $(CFLAGS) $(LUAZLIBINC) -g -o lgzip.o -c lgzip.c && $(CC) $(CFLAGS) $(LUAZLIBINC) -g -o lzlib.o -c lzlib.c +# mplib (temporary) + +LIBMPDIR=mpdir +LIBMPLIBDEP=$(LIBMPDIR)/lmplib.o $(LIBMPDIR)/.libs/libmplib.a # Convenience variables. luatexlibs = $(luapdflib) $(LDLIBPNG) $(LDZLIB) $(LDLIBXPDF) $(LIBMD5DEP) $(LDLIBOBSD) \ - $(LIBLUADEP) $(SLNUNICODEDEP) $(LUAZIPDEP) $(ZZIPLIBDEP) $(LUAFSDEP) \ - $(LUAPEGDEP) $(LUAMDVDEP) $(LUAZLIBDEP) $(LUAFFDEP) + $(LIBLUADEP) $(SLNUNICODEDEP) $(LUAZIPDEP) $(ZZIPLIBDEP) $(LUAFSDEP) $(LUASOCKETDEP) \ + $(LUAPEGDEP) $(LUAMDVDEP) $(LUAZLIBDEP) $(LUAFFDEP) $(LUAPROFDEP) $(LIBMPLIBDEP) luatexlibsdep = $(luapdflib) $(LIBPNGDEP) $(ZLIBDEP) $(LIBXPDFDEP) $(LIBMD5DEP) $(LIBOBSDDEP) \ - $(LIBLUADEP) $(SLNUNICODEDEP) $(ZZIPLIBDEP) $(LUAZIPDEP) $(LUAFSDEP) \ - $(LUAPEGDEP) $(LUAMDVDEP) $(LUAZLIBDEP) $(LUAFFDEP) $(makecpool) + $(LIBLUADEP) $(SLNUNICODEDEP) $(ZZIPLIBDEP) $(LUAZIPDEP) $(LUAFSDEP) $(LUASOCKETDEP) \ + $(LUAPEGDEP) $(LUAMDVDEP) $(LUAZLIBDEP) $(LUAFFDEP) $(LUAPROFDEP) $(makecpool) ## end of luatexlib.mk - Makefile fragment for libraries used by pdf[ex]tex. diff --git a/Build/source/texk/web2c/luatexdir/luazlib/lzlib.c b/Build/source/texk/web2c/luatexdir/luazlib/lzlib.c index 74c9dd21a64..69558e31d96 100644 --- a/Build/source/texk/web2c/luatexdir/luazlib/lzlib.c +++ b/Build/source/texk/web2c/luatexdir/luazlib/lzlib.c @@ -195,7 +195,7 @@ static int lzlib_inflate(lua_State *L) static int lzstream_decompress(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZINFLATE); - s->next_in = (char*)luaL_checkstring(L, 2); + s->next_in = (Bytef*)luaL_checkstring(L, 2); s->avail_in = lua_strlen(L, 2); { @@ -204,7 +204,7 @@ static int lzstream_decompress(lua_State *L) luaL_buffinit(L, &b); do { - s->next_out = luaL_prepbuffer(&b); + s->next_out = (Bytef*)luaL_prepbuffer(&b); s->avail_out = LUAL_BUFFERSIZE; /* munch some more */ @@ -231,7 +231,7 @@ static int lzstream_decompress(lua_State *L) static int lzstream_compress(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZDEFLATE); - s->next_in = (char*)luaL_checkstring(L, 2); + s->next_in = (Bytef*)luaL_checkstring(L, 2); s->avail_in = lua_strlen(L, 2); { @@ -240,7 +240,7 @@ static int lzstream_compress(lua_State *L) luaL_buffinit(L, &b); do { - s->next_out = luaL_prepbuffer(&b); + s->next_out = (Bytef*)luaL_prepbuffer(&b); s->avail_out = LUAL_BUFFERSIZE; /* bake some more */ @@ -273,7 +273,7 @@ static int lzstream_flush(lua_State *L) return 1; } - s->next_in = ""; + s->next_in = (Bytef*)""; s->avail_in = 0; { @@ -282,7 +282,7 @@ static int lzstream_flush(lua_State *L) luaL_buffinit(L, &b); do { - s->next_out = luaL_prepbuffer(&b); + s->next_out = (Bytef*)luaL_prepbuffer(&b); s->avail_out = LUAL_BUFFERSIZE; r = deflate(s, Z_FINISH); @@ -349,7 +349,7 @@ static int lzlib_adler32(lua_State *L) const char* buf = luaL_checkstring(L, 2); int len = lua_strlen(L, 2); - lua_pushnumber(L, adler32(adler, buf, len)); + lua_pushnumber(L, adler32(adler, (const Bytef*)buf, len)); } return 1; } @@ -369,7 +369,7 @@ static int lzlib_crc32(lua_State *L) const char* buf = luaL_checkstring(L, 2); int len = lua_strlen(L, 2); - lua_pushnumber(L, crc32(crc, buf, len)); + lua_pushnumber(L, crc32(crc, (const Bytef*)buf, len)); } return 1; } @@ -409,12 +409,12 @@ static int lzlib_compress(lua_State *L) return 2; } - zs.next_in = (char*)next_in; + zs.next_in = (Bytef*)next_in; zs.avail_in = avail_in; for(;;) { - zs.next_out = luaL_prepbuffer(&b); + zs.next_out = (Bytef*)luaL_prepbuffer(&b); zs.avail_out = LUAL_BUFFERSIZE; /* munch some more */ @@ -453,6 +453,7 @@ static int lzlib_decompress(lua_State *L) luaL_Buffer b; luaL_buffinit(L, &b); + zs.zalloc = Z_NULL; zs.zfree = Z_NULL; @@ -470,12 +471,12 @@ static int lzlib_decompress(lua_State *L) return 2; } - zs.next_in = (char*)next_in; + zs.next_in = (Bytef*)next_in; zs.avail_in = avail_in; for(;;) { - zs.next_out = luaL_prepbuffer(&b); + zs.next_out = (Bytef*)luaL_prepbuffer(&b); zs.avail_out = LUAL_BUFFERSIZE; /* bake some more */ diff --git a/Build/source/texk/web2c/luatexdir/macnames.c b/Build/source/texk/web2c/luatexdir/macnames.c deleted file mode 100644 index 832e05e052d..00000000000 --- a/Build/source/texk/web2c/luatexdir/macnames.c +++ /dev/null @@ -1,312 +0,0 @@ -/* -Copyright (c) 1996-2002 Han The Thanh, - -This file is part of pdfTeX. - -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id$ -*/ - -const char notdef[] = ".notdef"; - -const char *mac_glyph_names[] = { -/* 0x00 */ - notdef, - ".null", - "CR", - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", -/* 0x10 */ - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", -/* 0x20 */ - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", -/* 0x30 */ - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", -/* 0x40 */ - "bracketright", - "asciicircum", - "underscore", - "grave", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", -/* 0x50 */ - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", -/* 0x60 */ - "braceright", - "asciitilde", - "Adieresis", - "Aring", - "Ccedilla", - "Eacute", - "Ntilde", - "Odieresis", - "Udieresis", - "aacute", - "agrave", - "acircumflex", - "adieresis", - "atilde", - "aring", - "ccedilla", -/* 0x70 */ - "eacute", - "egrave", - "ecircumflex", - "edieresis", - "iacute", - "igrave", - "icircumflex", - "idieresis", - "ntilde", - "oacute", - "ograve", - "ocircumflex", - "odieresis", - "otilde", - "uacute", - "ugrave", -/* 0x80 */ - "ucircumflex", - "udieresis", - "dagger", - "degree", - "cent", - "sterling", - "section", - "bullet", - "paragraph", - "germandbls", - "registered", - "copyright", - "trademark", - "acute", - "dieresis", - "notequal", -/* 0x90 */ - "AE", - "Oslash", - "infinity", - "plusminus", - "lessequal", - "greaterequal", - "yen", - "mu", - "partialdiff", - "Sigma", - "Pi", - "pi", - "integral", - "ordfeminine", - "ordmasculine", - "Omega", -/* 0xa0 */ - "ae", - "oslash", - "questiondown", - "exclamdown", - "logicalnot", - "radical", - "florin", - "approxequal", - "Delta", - "guillemotleft", - "guillemotright", - "ellipsis", - "nbspace", - "Agrave", - "Atilde", - "Otilde", -/* 0xb0 */ - "OE", - "oe", - "endash", - "emdash", - "quotedblleft", - "quotedblright", - "quoteleft", - "quoteright", - "divide", - "lozenge", - "ydieresis", - "Ydieresis", - "fraction", - "currency", - "guilsinglleft", - "guilsinglright", -/* 0xc0 */ - "fi", - "fl", - "daggerdbl", - "periodcentered", - "quotesinglbase", - "quotedblbase", - "perthousand", - "Acircumflex", - "Ecircumflex", - "Aacute", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", -/* 0xd0 */ - "Oacute", - "Ocircumflex", - "applelogo", - "Ograve", - "Uacute", - "Ucircumflex", - "Ugrave", - "dotlessi", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "ring", - "cedilla", - "hungarumlaut", -/* 0xe0 */ - "ogonek", - "caron", - "Lslash", - "lslash", - "Scaron", - "scaron", - "Zcaron", - "zcaron", - "brokenbar", - "Eth", - "eth", - "Yacute", - "yacute", - "Thorn", - "thorn", - "minus", -/* 0xf0 */ - "multiply", - "onesuperior", - "twosuperior", - "threesuperior", - "onehalf", - "onequarter", - "threequarters", - "franc", - "Gbreve", - "gbreve", - "Idot", - "Scedilla", - "scedilla", - "Cacute", - "cacute", - "Ccaron", -/* 0x100 */ - "ccaron", - "dmacron" -}; - -const char *ambiguous_names[] = { - "Delta", /* increment */ - "Omega", /* Ohm */ - "Pi", /* product */ - "Sigma", /* summation */ - "dmacron", /* dslash */ - "macron", /* overscore */ - "periodcentered", /* middot */ - NULL -}; diff --git a/Build/source/texk/web2c/luatexdir/makecpool.c b/Build/source/texk/web2c/luatexdir/makecpool.c new file mode 100644 index 00000000000..dd5b31f0b92 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/makecpool.c @@ -0,0 +1,93 @@ +/* Copyright 2007, 2008 Taco Hoekwater. + You may freely use, modify and/or distribute this file. */ + +#include +#include +#include + +static const char __svn_version[] = + "$Id: makecpool.c 1230 2008-05-03 11:11:32Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/makecpool.c $"; + +int main(int argc, char *argv[]) +{ + char *filename; + char *headername; + FILE *fh; + char data[1024]; + int is_metafont = 0; + int is_metapost = 0; + int is_luatex = 0; + if (argc != 3) { + fprintf(stderr, + "%s: need exactly two arguments (pool name and C header name).\n", + argv[0]); + exit(EXIT_FAILURE); + } + filename = argv[1]; + headername = argv[2]; + fh = fopen(filename, "r"); + if (!fh) { + fprintf(stderr, "%s: can't open %s for reading.\n", argv[0], filename); + exit(EXIT_FAILURE); + } + if (strstr(filename, "luatex.pool") != NULL) + is_luatex = 1; + else if (strstr(filename, "mp.pool") != NULL) + is_metapost = 1; + else if (strstr(filename, "mf.pool") != NULL) + is_metafont = 1; + printf("/*\n" + " * This file is auto-generated by makecpool.\n" + " * %s %s %s\n" + " */\n" + "\n" + "#include \n" + "#include \n" + "#include \"%s\"\n" + "\n" + "static const char *poolfilearr[] = {\n", argv[0], filename, + headername, headername); + while (fgets(data, 1024, fh)) { + int i; + int len = strlen(data); + int o = 0; /* skip first bytes */ + if (data[len - 1] == '\n') { + data[len - 1] = 0; + len--; + } + if (data[0] == '*') + break; + if (data[0] >= '0' && data[0] <= '9' && data[1] >= '0' + && data[1] <= '9') { + o = 2; + } + printf(" \""); + for (i = o; i < len; i++) { + if (data[i] == '"' || data[i] == '\\') + putchar('\\'); + if (data[i] == '?') + printf("\" \""); /* suppress trigraphs */ + putchar(data[i]); + } + printf("\",\n"); + } + fclose(fh); + printf(" NULL };\n" + "int loadpoolstrings (integer spare_size) {\n" + " const char *s;\n" + " strnumber g=0;\n" + " int i=0,j=0;\n" + " while ((s = poolfilearr[j++])) {\n" + " int l = strlen (s);\n" + " i += l;\n" " if (i>=spare_size) return 0;\n"); + if (is_luatex) + printf(" while (l-- > 0) str_pool[pool_ptr++] = *s++;\n" + " g = make_string();\n"); + else + printf(" while (l-- > 0) strpool[poolptr++] = *s++;\n" + " g = makestring();\n"); + if (is_metapost || is_metafont) + printf(" strref[g]= 127;\n"); + printf(" }\n" " return g;\n" "}\n"); + return EXIT_SUCCESS; +} diff --git a/Build/source/texk/web2c/luatexdir/managed-sa.c b/Build/source/texk/web2c/luatexdir/managed-sa.c index cc63d7e75f5..97872c1efe3 100644 --- a/Build/source/texk/web2c/luatexdir/managed-sa.c +++ b/Build/source/texk/web2c/luatexdir/managed-sa.c @@ -1,245 +1,287 @@ +/* managed-sa.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "managed-sa.h" +static const char __svn_version[] = + "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/managed-sa.c $"; -static void -store_sa_stack (sa_tree a, integer n, integer v, integer gl) { - sa_stack_item st; - st.code = n; - st.value = v; - st.level = gl; - if (a->stack == NULL) { - a->stack = Mxmalloc_array(sa_stack_item,a->stack_size); - } else if (((a->stack_ptr)+1)>=a->stack_size) { - a->stack_size += a->stack_step; - a->stack = Mxrealloc_array(a->stack,sa_stack_item,a->stack_size); - } - (a->stack_ptr)++; - a->stack[a->stack_ptr] = st; +static void store_sa_stack(sa_tree a, integer n, integer v, integer gl) +{ + sa_stack_item st; + st.code = n; + st.value = v; + st.level = gl; + if (a->stack == NULL) { + a->stack = Mxmalloc_array(sa_stack_item, a->stack_size); + } else if (((a->stack_ptr) + 1) >= a->stack_size) { + a->stack_size += a->stack_step; + a->stack = Mxrealloc_array(a->stack, sa_stack_item, a->stack_size); + } + (a->stack_ptr)++; + a->stack[a->stack_ptr] = st; } -static void -skip_in_stack (sa_tree a, integer n) { - int p = a->stack_ptr; - if (a->stack == NULL) - return; - while (p>0) { - if (a->stack[p].code == n && a->stack[p].level > 0) { - a->stack[p].level = -(a->stack[p].level); +static void skip_in_stack(sa_tree a, integer n) +{ + int p = a->stack_ptr; + if (a->stack == NULL) + return; + while (p > 0) { + if (a->stack[p].code == n && a->stack[p].level > 0) { + a->stack[p].level = -(a->stack[p].level); + } + p--; } - p--; - } } -sa_tree_item -get_sa_item (const sa_tree head, const integer n) { - register int h; - register int m; - if (head->tree != NULL) { - h = HIGHPART_PART(n); - if (head->tree[h] != NULL) { - m = MIDPART_PART(n); - if (head->tree[h][m] != NULL) { - return head->tree[h][m][LOWPART_PART(n)]; - } +sa_tree_item get_sa_item(const sa_tree head, const integer n) +{ + register int h; + register int m; + if (head->tree != NULL) { + h = HIGHPART_PART(n); + if (head->tree[h] != NULL) { + m = MIDPART_PART(n); + if (head->tree[h][m] != NULL) { + return head->tree[h][m][LOWPART_PART(n)]; + } + } } - } - return head->dflt; + return head->dflt; } -void -set_sa_item (sa_tree head, integer n, sa_tree_item v, integer gl) { - int h,m,l; - int i; - h = HIGHPART_PART(n); - m = MIDPART_PART(n); - l = LOWPART_PART(n); - if (head->tree == NULL) { - head->tree = (sa_tree_item ***) Mxmalloc_array(sa_tree_item **,HIGHPART); - for (i=0; itree[i] = NULL; } - } - if (head->tree[h] == NULL) { - head->tree[h] = (sa_tree_item **) Mxmalloc_array(sa_tree_item *,MIDPART); - for (i=0; itree[h][i] = NULL; } - } - if (head->tree[h][m] == NULL) { - head->tree[h][m] = (sa_tree_item *) Mxmalloc_array(sa_tree_item,LOWPART); - for (i=0; itree[h][m][i] = head->dflt; } - } - if (gl<=1) { - skip_in_stack(head,n); - } else { - store_sa_stack(head,n,head->tree[h][m][l],gl); - } - head->tree[h][m][l] = v; +void set_sa_item(sa_tree head, integer n, sa_tree_item v, integer gl) +{ + int h, m, l; + int i; + h = HIGHPART_PART(n); + m = MIDPART_PART(n); + l = LOWPART_PART(n); + if (head->tree == NULL) { + head->tree = + (sa_tree_item ***) Mxmalloc_array(sa_tree_item **, HIGHPART); + for (i = 0; i < HIGHPART; i++) { + head->tree[i] = NULL; + } + } + if (head->tree[h] == NULL) { + head->tree[h] = + (sa_tree_item **) Mxmalloc_array(sa_tree_item *, MIDPART); + for (i = 0; i < MIDPART; i++) { + head->tree[h][i] = NULL; + } + } + if (head->tree[h][m] == NULL) { + head->tree[h][m] = + (sa_tree_item *) Mxmalloc_array(sa_tree_item, LOWPART); + for (i = 0; i < LOWPART; i++) { + head->tree[h][m][i] = head->dflt; + } + } + if (gl <= 1) { + skip_in_stack(head, n); + } else { + store_sa_stack(head, n, head->tree[h][m][l], gl); + } + head->tree[h][m][l] = v; } -static void -rawset_sa_item (sa_tree head, integer n, integer v) { - head->tree[HIGHPART_PART(n)][MIDPART_PART(n)][LOWPART_PART(n)] = v; +void rawset_sa_item(sa_tree head, integer n, integer v) +{ + head->tree[HIGHPART_PART(n)][MIDPART_PART(n)][LOWPART_PART(n)] = v; } -void -clear_sa_stack (sa_tree a) { - if (a->stack != NULL) { - Mxfree(a->stack); - } - a->stack = NULL; - a->stack_ptr = 0; - a->stack_size = a->stack_step; +void clear_sa_stack(sa_tree a) +{ + if (a->stack != NULL) { + Mxfree(a->stack); + } + a->stack = NULL; + a->stack_ptr = 0; + a->stack_size = a->stack_step; } -void -destroy_sa_tree (sa_tree a) { - int h,m; - if (a == NULL) - return; - if (a->tree != NULL) { - for (h=0; htree[h] != NULL) { - for (m=0; mtree[h][m] != NULL) { - Mxfree(a->tree[h][m]); - } - } - Mxfree(a->tree[h]); - } +void destroy_sa_tree(sa_tree a) +{ + int h, m; + if (a == NULL) + return; + if (a->tree != NULL) { + for (h = 0; h < HIGHPART; h++) { + if (a->tree[h] != NULL) { + for (m = 0; m < MIDPART; m++) { + if (a->tree[h][m] != NULL) { + Mxfree(a->tree[h][m]); + } + } + Mxfree(a->tree[h]); + } + } + Mxfree(a->tree); } - Mxfree(a->tree); - } - if (a->stack != NULL) { - Mxfree(a->stack); - } - Mxfree(a); + if (a->stack != NULL) { + Mxfree(a->stack); + } + Mxfree(a); } -sa_tree -copy_sa_tree(sa_tree b) { - int h,m,l; - sa_tree a = (sa_tree)Mxmalloc_array(sa_tree_head,1); - a->stack_step = b->stack_step; - a->stack_size = b->stack_size; - a->dflt = b->dflt; - a->stack = NULL; - a->stack_ptr = 0; - a->tree = NULL; - if (b->tree !=NULL) { - a->tree = (sa_tree_item ***)Mxmalloc_array(void *,HIGHPART); - for (h=0; htree[h] != NULL) { - a->tree[h]=(sa_tree_item **)Mxmalloc_array(void *,MIDPART); - for (m=0; mtree[h][m]!=NULL) { - a->tree[h][m]=Mxmalloc_array(sa_tree_item,LOWPART); - for (l=0; ltree[h][m][l] = b->tree[h][m][l] ; - } - } else { - a->tree[h][m] = NULL; - } - } - } else { - a->tree[h]= NULL; - } - } - } - return a; +sa_tree copy_sa_tree(sa_tree b) +{ + int h, m, l; + sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1); + a->stack_step = b->stack_step; + a->stack_size = b->stack_size; + a->dflt = b->dflt; + a->stack = NULL; + a->stack_ptr = 0; + a->tree = NULL; + if (b->tree != NULL) { + a->tree = (sa_tree_item ***) Mxmalloc_array(void *, HIGHPART); + for (h = 0; h < HIGHPART; h++) { + if (b->tree[h] != NULL) { + a->tree[h] = (sa_tree_item **) Mxmalloc_array(void *, MIDPART); + for (m = 0; m < MIDPART; m++) { + if (b->tree[h][m] != NULL) { + a->tree[h][m] = Mxmalloc_array(sa_tree_item, LOWPART); + for (l = 0; l < LOWPART; l++) { + a->tree[h][m][l] = b->tree[h][m][l]; + } + } else { + a->tree[h][m] = NULL; + } + } + } else { + a->tree[h] = NULL; + } + } + } + return a; } -sa_tree -new_sa_tree (integer size, sa_tree_item dflt) { - sa_tree_head *a; - a = (sa_tree_head *)xmalloc(sizeof(sa_tree_head)); - a->dflt = dflt; - a->stack = NULL; - a->tree = NULL; - a->stack_size = size; - a->stack_step = size; - a->stack_ptr = 0; - return (sa_tree)a; +sa_tree new_sa_tree(integer size, sa_tree_item dflt) +{ + sa_tree_head *a; + a = (sa_tree_head *) xmalloc(sizeof(sa_tree_head)); + a->dflt = dflt; + a->stack = NULL; + a->tree = NULL; + a->stack_size = size; + a->stack_step = size; + a->stack_ptr = 0; + return (sa_tree) a; } -void -restore_sa_stack (sa_tree head, integer gl) { - sa_stack_item st; - if (head->stack == NULL) - return; - while (head->stack_ptr>0 && abs(head->stack[head->stack_ptr].level)>=gl) { - st = head->stack[head->stack_ptr]; - if (st.level>0) { - rawset_sa_item (head, st.code, st.value); - } - (head->stack_ptr)--; - } +void restore_sa_stack(sa_tree head, integer gl) +{ + sa_stack_item st; + if (head->stack == NULL) + return; + while (head->stack_ptr > 0 && abs(head->stack[head->stack_ptr].level) >= gl) { + st = head->stack[head->stack_ptr]; + if (st.level > 0) { + rawset_sa_item(head, st.code, st.value); + } + (head->stack_ptr)--; + } } -void -dump_sa_tree (sa_tree a) { - boolean f; - unsigned int x; - int h,m,l; - if (a == NULL) - return; - dump_int(a->stack_step); - dump_int(a->dflt); - if (a->tree != NULL) { - for (h=0; htree[h] != NULL) { - f = 1; dump_qqqq(f); - for (m=0; mtree[h][m] != NULL) { - f = 1; dump_qqqq(f); - for (l=0;ltree[h][m][l]; dump_int(x); - } - } else { - f = 0; dump_qqqq(f); - } - } - } else { - f = 0; dump_qqqq(f); - } +void dump_sa_tree(sa_tree a) +{ + boolean f; + unsigned int x; + int h, m, l; + assert(a != NULL); + dump_int(a->stack_step); + dump_int(a->dflt); + if (a->tree != NULL) { + dump_int(1); + for (h = 0; h < HIGHPART; h++) { + if (a->tree[h] != NULL) { + f = 1; + dump_qqqq(f); + for (m = 0; m < MIDPART; m++) { + if (a->tree[h][m] != NULL) { + f = 1; + dump_qqqq(f); + for (l = 0; l < LOWPART; l++) { + x = a->tree[h][m][l]; + dump_int(x); + } + } else { + f = 0; + dump_qqqq(f); + } + } + } else { + f = 0; + dump_qqqq(f); + } + } + } else { + dump_int(0); } - } } -sa_tree -undump_sa_tree(void) { - unsigned int x; - int h,m,l; - boolean f; - sa_tree a = (sa_tree)Mxmalloc_array(sa_tree_head,1); - undump_int(x) ; a->stack_step = x; a->stack_size = x; - undump_int(x) ; a->dflt = x; - a->stack = Mxmalloc_array(sa_stack_item,a->stack_size); - a->stack_ptr = 0; - a->tree = (sa_tree_item ***)Mxmalloc_array(void *,HIGHPART); - for (h=0; h0) { - a->tree[h]=(sa_tree_item **)Mxmalloc_array(void *,MIDPART); - for (m=0; m0) { - a->tree[h][m]=Mxmalloc_array(sa_tree_item,LOWPART); - for (l=0; ltree[h][m][l] = x; - } - } else { - a->tree[h][m] = NULL; - } - } - } else { - a->tree[h]= NULL; - } - } - return a; +sa_tree undump_sa_tree(void) +{ + unsigned int x; + int h, m, l; + boolean f; + sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1); + undump_int(x); + a->stack_step = x; + a->stack_size = x; + undump_int(x); + a->dflt = x; + a->stack = Mxmalloc_array(sa_stack_item, a->stack_size); + a->stack_ptr = 0; + a->tree = NULL; + undump_int(x); + if (x == 0) + return a; + a->tree = (sa_tree_item ***) Mxmalloc_array(void *, HIGHPART); + for (h = 0; h < HIGHPART; h++) { + undump_qqqq(f); + if (f > 0) { + a->tree[h] = (sa_tree_item **) Mxmalloc_array(void *, MIDPART); + for (m = 0; m < MIDPART; m++) { + undump_qqqq(f); + if (f > 0) { + a->tree[h][m] = Mxmalloc_array(sa_tree_item, LOWPART); + for (l = 0; l < LOWPART; l++) { + undump_int(x); + a->tree[h][m][l] = x; + } + } else { + a->tree[h][m] = NULL; + } + } + } else { + a->tree[h] = NULL; + } + } + return a; } - - diff --git a/Build/source/texk/web2c/luatexdir/managed-sa.h b/Build/source/texk/web2c/luatexdir/managed-sa.h index b73aece81b1..880a6acd9bc 100644 --- a/Build/source/texk/web2c/luatexdir/managed-sa.h +++ b/Build/source/texk/web2c/luatexdir/managed-sa.h @@ -1,74 +1,74 @@ -/* - Copyright (c) 2007 Taco Hoekwater - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - LuaTeX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with LuaTeX; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - $Id$ */ +/* managed-sa.h + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +/* $Id$ */ #ifndef MANAGED_SA_H -#define MANAGED_SA_H 1 +# define MANAGED_SA_H 1 /* the next two sets of three had better match up exactly, but using bare numbers is easier on the C compiler */ -#define HIGHPART 128 -#define MIDPART 128 -#define LOWPART 128 +# define HIGHPART 128 +# define MIDPART 128 +# define LOWPART 128 -#define HIGHPART_PART(a) ((a>>14)&127) -#define MIDPART_PART(a) ((a>>7)&127) -#define LOWPART_PART(a) (a&127) +# define HIGHPART_PART(a) (((a)>>14)&127) +# define MIDPART_PART(a) (((a)>>7)&127) +# define LOWPART_PART(a) ((a)&127) -#define Mxmalloc_array(a,b) xmalloc(b*sizeof(a)) -#define Mxrealloc_array(a,b,c) xrealloc(a,c*sizeof(b)) -#define Mxfree(a) free(a); a=NULL +# define Mxmalloc_array(a,b) xmalloc((b)*sizeof(a)) +# define Mxrealloc_array(a,b,c) xrealloc((a),(c)*sizeof(b)) +# define Mxfree(a) free(a); a=NULL -typedef unsigned int sa_tree_item; +typedef unsigned int sa_tree_item; typedef struct { - int code; - int level; - sa_tree_item value; + int code; + int level; + sa_tree_item value; } sa_stack_item; typedef struct { - int stack_size; /* initial stack size */ - int stack_step; /* increment stack step */ - int stack_ptr; /* current stack point */ - int dflt; /* default item value */ - sa_tree_item *** tree; /* item tree head */ - sa_stack_item * stack; /* stack tree head */ + int stack_size; /* initial stack size */ + int stack_step; /* increment stack step */ + int stack_ptr; /* current stack point */ + int dflt; /* default item value */ + sa_tree_item ***tree; /* item tree head */ + sa_stack_item *stack; /* stack tree head */ } sa_tree_head; typedef sa_tree_head *sa_tree; -extern sa_tree_item get_sa_item (const sa_tree head, const integer n) ; -extern void set_sa_item (sa_tree head, integer n, sa_tree_item v, integer gl) ; +extern sa_tree_item get_sa_item(const sa_tree head, const integer n); +extern void set_sa_item(sa_tree head, integer n, sa_tree_item v, integer gl); -extern sa_tree new_sa_tree (integer size, sa_tree_item dflt); +extern sa_tree new_sa_tree(integer size, sa_tree_item dflt); -extern sa_tree copy_sa_tree (sa_tree head); -extern void destroy_sa_tree (sa_tree head); +extern sa_tree copy_sa_tree(sa_tree head); +extern void destroy_sa_tree(sa_tree head); -extern void dump_sa_tree (sa_tree a); -extern sa_tree undump_sa_tree (void) ; +extern void dump_sa_tree(sa_tree a); +extern sa_tree undump_sa_tree(void); -extern void restore_sa_stack (sa_tree a, integer gl); -extern void clear_sa_stack (sa_tree a); +extern void restore_sa_stack(sa_tree a, integer gl); +extern void clear_sa_stack(sa_tree a); #endif diff --git a/Build/source/texk/web2c/luatexdir/mathcodes.c b/Build/source/texk/web2c/luatexdir/mathcodes.c index 77e15e7c66c..ef5af17afc0 100644 --- a/Build/source/texk/web2c/luatexdir/mathcodes.c +++ b/Build/source/texk/web2c/luatexdir/mathcodes.c @@ -1,191 +1,471 @@ +/* mathnodes.c + + Copyright 2006-2008 Taco Hoekwater -/* -Copyright (c) 2006 Taco Hoekwater, + This file is part of LuaTeX. -This file is part of LuaTeX. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -LuaTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -LuaTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LuaTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id $ -*/ + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ #include "luatex-api.h" #include #include "managed-sa.h" +#include "commands.h" -/* the 0xFFFFFFFF is a flag value */ +extern void rawset_sa_item(sa_tree head, integer n, integer v); + +static const char __svn_version[] = + "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/mathcodes.c $"; + +/* math codes */ +static sa_tree mathcode_head = NULL; + +#define MATHCODEHEAP 8 + +static mathcodeval *mathcode_heap = NULL; +static int mathcode_heapsize = MATHCODEHEAP; +static int mathcode_heapptr = 0; + +/* the 0xFFFFFFFF is a flag value */ #define MATHCODESTACK 8 #define MATHCODEDEFAULT 0xFFFFFFFF -static sa_tree mathcode_head = NULL; +/* delcodes */ + +static sa_tree delcode_head = NULL; -typedef struct delcodeval { - integer valuea; - integer valueb; -} delcodeval; +#define DELCODEHEAP 8 -/* delcodes are a bit more work */ +static delcodeval *delcode_heap = NULL; +static int delcode_heapsize = DELCODEHEAP; +static int delcode_heapptr = 0; #define DELCODESTACK 4 #define DELCODEDEFAULT 0xFFFFFFFF -static sa_tree delcode_head = NULL; +/* some helpers for mathcode printing */ + +#define print_hex_digit(A) do { \ + if ((A)>=10) print_char('A'+(A)-10); \ + else print_char('0'+(A)); \ + } while (0) + +#define two_hex(A) do { \ + print_hex_digit((A)/16); \ + print_hex_digit((A)%16); \ + } while (0) + +#define four_hex(A) do { \ + two_hex((A)/256); \ + two_hex((A)%256); \ + } while (0) + +#define six_hex(A) do { \ + two_hex((A)/65536); \ + two_hex(((A)%65536)/256); \ + two_hex((A)%256); \ + } while (0) + +void show_mathcode_value(mathcodeval c) +{ + if (c.origin_value == aleph_mathcode) { + print_char('"'); + print_hex_digit(c.class_value); + two_hex(c.family_value); + four_hex(c.character_value); + } else if (c.origin_value == xetex_mathcode) { + print_char('"'); + print_hex_digit(c.class_value); + print_char('"'); + two_hex(c.family_value); + print_char('"'); + six_hex(c.character_value); + } else if (c.origin_value == xetexnum_mathcode) { + int m; + m = (c.class_value + (c.family_value * 8)) * 2097152 + + c.character_value; + print_int(m); + } else { + print_char('"'); + print_hex_digit(c.class_value); + print_hex_digit(c.family_value); + two_hex(c.character_value); + } +} -#define DELCODEHEAP 8 -static delcodeval * delcode_heap = NULL; -static int delcode_heapsize = DELCODEHEAP; -static int delcode_heapptr = 0; +void show_mathcode(integer n) +{ + mathcodeval c = get_math_code(n); + if (c.origin_value == aleph_mathcode) { + tprint_esc("omathcode"); + } else if (c.origin_value == xetex_mathcode) { + tprint_esc("Umathcode"); + } else if (c.origin_value == xetexnum_mathcode) { + tprint_esc("Umathcodenum"); + } else { + tprint_esc("mathcode"); + } + print_int(n); + print_char('='); + show_mathcode_value(c); +} -void -unsavemathcode (quarterword gl) { - restore_sa_stack(mathcode_head,gl); +void unsavemathcode(quarterword gl) +{ + sa_stack_item st; + if (mathcode_head->stack == NULL) + return; + while (mathcode_head->stack_ptr > 0 && + abs(mathcode_head->stack[mathcode_head->stack_ptr].level) + >= (integer) gl) { + st = mathcode_head->stack[mathcode_head->stack_ptr]; + if (st.level > 0) { + rawset_sa_item(mathcode_head, st.code, st.value); + /* now do a trace message, if requested */ + if (int_par(param_tracing_restores_code) > 0) { + begin_diagnostic(); + print_char('{'); + tprint("restoring"); + print_char(' '); + show_mathcode(st.code); + print_char('}'); + end_diagnostic(false); + } + } + (mathcode_head->stack_ptr)--; + } } -void -set_math_code (integer n, halfword v, quarterword gl) { - set_sa_item(mathcode_head,n,v,gl); +void set_math_code(integer n, + integer commandorigin, + integer mathclass, + integer mathfamily, integer mathcharacter, quarterword level) +{ + mathcodeval d; + d.origin_value = commandorigin; + d.class_value = mathclass; + d.family_value = mathfamily; + d.character_value = mathcharacter; + if (mathcode_heapptr == mathcode_heapsize) { + mathcode_heapsize += MATHCODEHEAP; + mathcode_heap = + Mxrealloc_array(mathcode_heap, mathcodeval, mathcode_heapsize); + } + mathcode_heap[mathcode_heapptr] = d; + set_sa_item(mathcode_head, n, mathcode_heapptr, level); + mathcode_heapptr++; + if (int_par(param_tracing_assigns_code) > 0) { + begin_diagnostic(); + print_char('{'); + tprint("assigning"); + print_char(' '); + show_mathcode(n); + print_char('}'); + end_diagnostic(false); + } } -halfword -get_math_code (integer n) { - unsigned int ret; - ret = get_sa_item(mathcode_head,n); - if (ret==MATHCODEDEFAULT) { - return (halfword)n; - } else { - return (halfword)ret; - } +mathcodeval get_math_code(integer n) +{ + unsigned int ret; + ret = get_sa_item(mathcode_head, n); + if (ret == MATHCODEDEFAULT) { + mathcodeval d; + d.class_value = 0; + d.family_value = 0; + d.origin_value = (n < 256 ? tex_mathcode : + (n < 65536 ? aleph_mathcode : xetex_mathcode)); + d.character_value = n; + return d; + } else { + return mathcode_heap[ret]; + } } -void -initializemathcode (void) { - mathcode_head = new_sa_tree(MATHCODESTACK,MATHCODEDEFAULT); + +integer get_math_code_num(integer n) +{ + mathcodeval mval; + mval = get_math_code(n); + if (mval.origin_value == tex_mathcode) { + return (mval.class_value * 16 + mval.family_value) * 256 + + mval.character_value; + } else if (mval.origin_value == aleph_mathcode) { + return (mval.class_value * 256 + mval.family_value) * 65536 + + mval.character_value; + } else if (mval.origin_value == xetexnum_mathcode + || mval.origin_value == xetex_mathcode) { + return (mval.class_value + (mval.family_value * 8)) * (65536 * 32) + + mval.character_value; + } + return 0; } -void -dumpmathcode (void) { - dump_sa_tree(mathcode_head); +void initializemathcode(void) +{ + mathcode_head = new_sa_tree(MATHCODESTACK, MATHCODEDEFAULT); + mathcode_heap = Mxmalloc_array(mathcodeval, MATHCODEHEAP); } -void -undumpmathcode (void) { - mathcode_head = undump_sa_tree(); +void dumpmathcode(void) +{ + int k; + mathcodeval d; + dump_sa_tree(mathcode_head); + dump_int(mathcode_heapsize); + dump_int(mathcode_heapptr); + for (k = 0; k < mathcode_heapptr; k++) { + d = mathcode_heap[k]; + dump_int(d.origin_value); + dump_int(d.class_value); + dump_int(d.family_value); + dump_int(d.character_value); + } } +void undumpmathcode(void) +{ + int k; + mathcodeval d; + mathcode_head = undump_sa_tree(); + undump_int(mathcode_heapsize); + undump_int(mathcode_heapptr); + mathcode_heap = Mxmalloc_array(mathcodeval, mathcode_heapsize); + for (k = 0; k < mathcode_heapptr; k++) { + undump_int(d.origin_value); + undump_int(d.class_value); + undump_int(d.family_value); + undump_int(d.character_value); + mathcode_heap[k] = d; + } + d.origin_value = 0; + d.class_value = 0; + d.family_value = 0; + d.character_value = 0; + for (k = mathcode_heapptr; k < mathcode_heapsize; k++) { + mathcode_heap[k] = d; + } +} + + +void show_delcode(integer n) +{ + delcodeval c; + c = get_del_code(n); + if (c.origin_value == tex_mathcode) { + tprint_esc("delcode"); + } else if (c.origin_value == aleph_mathcode) { + tprint_esc("odelcode"); + } else if (c.origin_value == xetex_mathcode) { + tprint_esc("Udelcode"); + } else if (c.origin_value == xetexnum_mathcode) { + tprint_esc("Udelcodenum"); + } + print_int(n); + print_char('='); + if (c.small_family_value < 0) { + print_char('-'); + print_char('1'); + } else { + if (c.origin_value == tex_mathcode) { + print_char('"'); + print_hex_digit(c.small_family_value); + two_hex(c.small_character_value); + print_hex_digit(c.large_family_value); + two_hex(c.large_character_value); + } else if (c.origin_value == aleph_mathcode) { + print_char('"'); + two_hex(c.small_family_value); + four_hex(c.small_character_value); + print_char('"'); + two_hex(c.large_family_value); + four_hex(c.large_character_value); + } else if (c.origin_value == xetex_mathcode) { + print_char('"'); + two_hex(c.small_family_value); + six_hex(c.small_character_value); + } else if (c.origin_value == xetexnum_mathcode) { + int m; + m = c.small_family_value * 2097152 + c.small_character_value; + print_int(m); + } + } +} + + + /* TODO: clean up the heap */ -void -unsavedelcode (quarterword gl) { - restore_sa_stack(delcode_head,gl); -} - -void -set_del_code (integer n, halfword v, halfword w, quarterword gl) { - delcodeval d; - d.valuea = v; d.valueb = w; - if (delcode_heapptr==delcode_heapsize) { - delcode_heapsize += DELCODEHEAP; - delcode_heap = Mxrealloc_array(delcode_heap,delcodeval,delcode_heapsize); - } - delcode_heap[delcode_heapptr] = d; - set_sa_item(delcode_head,n,delcode_heapptr,gl); - delcode_heapptr++; -} - -halfword -get_del_code_a (integer n) { - int ret; - ret = get_sa_item(delcode_head,n); - if (ret==DELCODEDEFAULT) { - return (halfword)-1; - } else { - return (halfword)delcode_heap[ret].valuea; - } -} - -halfword -get_del_code_b (integer n) { - unsigned int ret; - ret = get_sa_item(delcode_head,n); - if (ret==DELCODEDEFAULT) { - return (halfword)-1; - } else { - return (halfword)delcode_heap[ret].valueb; - } -} - -void -initializedelcode (void) { - delcode_head = new_sa_tree(DELCODESTACK,DELCODEDEFAULT); - delcode_heap = Mxmalloc_array(delcodeval,DELCODEHEAP); -} - -void -dumpdelcode (void) { - int k; - delcodeval d; - dump_sa_tree(delcode_head); - dump_int(delcode_heapsize); - dump_int(delcode_heapptr); - for (k=0;kstack == NULL) + return; + while (delcode_head->stack_ptr > 0 && + abs(delcode_head->stack[delcode_head->stack_ptr].level) + >= (integer) gl) { + st = delcode_head->stack[delcode_head->stack_ptr]; + if (st.level > 0) { + rawset_sa_item(delcode_head, st.code, st.value); + /* now do a trace message, if requested */ + if (int_par(param_tracing_restores_code) > 0) { + begin_diagnostic(); + print_char('{'); + tprint("restoring"); + print_char(' '); + show_delcode(st.code); + print_char('}'); + end_diagnostic(false); + } + } + (delcode_head->stack_ptr)--; + } + +} + +void set_del_code(integer n, + integer commandorigin, + integer smathfamily, + integer smathcharacter, + integer lmathfamily, integer lmathcharacter, quarterword gl) +{ + delcodeval d; + d.class_value = 0; + d.origin_value = commandorigin; + d.small_family_value = smathfamily; + d.small_character_value = smathcharacter; + d.large_family_value = lmathfamily; + d.large_character_value = lmathcharacter; + if (delcode_heapptr == delcode_heapsize) { + delcode_heapsize += DELCODEHEAP; + delcode_heap = + Mxrealloc_array(delcode_heap, delcodeval, delcode_heapsize); + } + delcode_heap[delcode_heapptr] = d; + set_sa_item(delcode_head, n, delcode_heapptr, gl); + if (int_par(param_tracing_assigns_code) > 0) { + begin_diagnostic(); + print_char('{'); + tprint("assigning"); + print_char(' '); + show_delcode(n); + print_char('}'); + end_diagnostic(false); + } + delcode_heapptr++; +} + +delcodeval get_del_code(integer n) +{ + unsigned ret; + ret = get_sa_item(delcode_head, n); + if (ret == DELCODEDEFAULT) { + delcodeval d; + d.class_value = 0; + d.origin_value = tex_mathcode; + d.small_family_value = -1; + d.small_character_value = 0; + d.large_family_value = 0; + d.large_character_value = 0; + return d; + } else { + return delcode_heap[ret]; + } +} + +void initializedelcode(void) +{ + delcode_head = new_sa_tree(DELCODESTACK, DELCODEDEFAULT); + delcode_heap = Mxmalloc_array(delcodeval, DELCODEHEAP); +} + +void dumpdelcode(void) +{ + int k; + delcodeval d; + dump_sa_tree(delcode_head); + dump_int(delcode_heapsize); + dump_int(delcode_heapptr); + for (k = 0; k < delcode_heapptr; k++) { + d = delcode_heap[k]; + dump_int(d.origin_value); + dump_int(d.class_value); + dump_int(d.small_family_value); + dump_int(d.small_character_value); + dump_int(d.large_family_value); + dump_int(d.large_character_value); + } +} + +void undumpdelcode(void) +{ + int k; + delcodeval d; + delcode_head = undump_sa_tree(); + undump_int(delcode_heapsize); + undump_int(delcode_heapptr); + delcode_heap = Mxmalloc_array(delcodeval, delcode_heapsize); + for (k = 0; k < delcode_heapptr; k++) { + undump_int(d.origin_value); + undump_int(d.class_value); + undump_int(d.small_family_value); + undump_int(d.small_character_value); + undump_int(d.large_family_value); + undump_int(d.large_character_value); + delcode_heap[k] = d; + } + d.origin_value = tex_mathcode; + d.class_value = 0; + d.small_family_value = -1; + d.small_character_value = 0; + d.large_family_value = 0; + d.large_character_value = 0; + for (k = delcode_heapptr; k < delcode_heapsize; k++) { + delcode_heap[k] = d; + } +} + +void unsave_math_codes(quarterword grouplevel) +{ + unsavemathcode(grouplevel); + unsavedelcode(grouplevel); +} + +void initialize_math_codes(void) +{ + initializemathcode(); + initializedelcode(); +} + +void free_math_codes(void) +{ + destroy_sa_tree(mathcode_head); + xfree(mathcode_heap); + destroy_sa_tree(delcode_head); + xfree(delcode_heap); +} + +void dump_math_codes(void) +{ + dumpmathcode(); + dumpdelcode(); +} + +void undump_math_codes(void) +{ + undumpmathcode(); + undumpdelcode(); } diff --git a/Build/source/texk/web2c/luatexdir/mp/avl.c b/Build/source/texk/web2c/luatexdir/mp/avl.c new file mode 100644 index 00000000000..703c4b2e72d --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/mp/avl.c @@ -0,0 +1,792 @@ +/* Produced by texiweb from libavl.w on 2003/01/06 at 18:07. */ + +/* libavl - library for manipulation of binary trees. + Copyright (C) 1998-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + + The author may be contacted at on the Internet, or + write to Ben Pfaff, Stanford University, Computer Science Dept., 353 + Serra Mall, Stanford CA 94305, USA. +*/ + +#include +#include +#include +#include +#include "avl.h" + +/* Creates and returns a new table + with comparison function |compare| using parameter |param| + and memory allocator |allocator|. + Returns |NULL| if memory allocation failed. */ +struct avl_table *avl_create (avl_comparison_func * compare, void *param, + struct libavl_allocator *allocator) +{ + struct avl_table *tree; + + assert (compare != NULL); + + if (allocator == NULL) + allocator = &avl_allocator_default; + + tree = allocator->libavl_malloc (allocator, sizeof *tree); + if (tree == NULL) + return NULL; + + tree->avl_root = NULL; + tree->avl_compare = compare; + tree->avl_param = param; + tree->avl_alloc = allocator; + tree->avl_count = 0; + tree->avl_generation = 0; + + return tree; +} + +/* Search |tree| for an item matching |item|, and return it if found. + Otherwise return |NULL|. */ +void *avl_find (const struct avl_table *tree, const void *item) +{ + const struct avl_node *p; + + assert (tree != NULL && item != NULL); + for (p = tree->avl_root; p != NULL;) { + int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param); + + if (cmp < 0) + p = p->avl_link[0]; + else if (cmp > 0) + p = p->avl_link[1]; + else /* |cmp == 0| */ + return p->avl_data; + } + + return NULL; +} + +/* Inserts |item| into |tree| and returns a pointer to |item|'s address. + If a duplicate item is found in the tree, + returns a pointer to the duplicate without inserting |item|. + Returns |NULL| in case of memory allocation failure. */ +void **avl_probe (struct avl_table *tree, void *item) +{ + struct avl_node *y, *z; /* Top node to update balance factor, and parent. */ + struct avl_node *p, *q; /* Iterator, and parent. */ + struct avl_node *n; /* Newly inserted node. */ + struct avl_node *w; /* New root of rebalanced subtree. */ + int dir; /* Direction to descend. */ + + unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */ + int k = 0; /* Number of cached results. */ + + assert (tree != NULL && item != NULL); + + z = (struct avl_node *) &tree->avl_root; + y = tree->avl_root; + dir = 0; + for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir]) { + int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param); + if (cmp == 0) + return &p->avl_data; + + if (p->avl_balance != 0) + z = q, y = p, k = 0; + da[k++] = dir = cmp > 0; + } + + n = q->avl_link[dir] = + tree->avl_alloc->libavl_malloc (tree->avl_alloc, sizeof *n); + if (n == NULL) + return NULL; + + tree->avl_count++; + n->avl_data = item; + n->avl_link[0] = n->avl_link[1] = NULL; + n->avl_balance = 0; + if (y == NULL) + return &n->avl_data; + + for (p = y, k = 0; p != n; p = p->avl_link[da[k]], k++) + if (da[k] == 0) + p->avl_balance--; + else + p->avl_balance++; + + if (y->avl_balance == -2) { + struct avl_node *x = y->avl_link[0]; + if (x->avl_balance == -1) { + w = x; + y->avl_link[0] = x->avl_link[1]; + x->avl_link[1] = y; + x->avl_balance = y->avl_balance = 0; + } else { + assert (x->avl_balance == +1); + w = x->avl_link[1]; + x->avl_link[1] = w->avl_link[0]; + w->avl_link[0] = x; + y->avl_link[0] = w->avl_link[1]; + w->avl_link[1] = y; + if (w->avl_balance == -1) + x->avl_balance = 0, y->avl_balance = +1; + else if (w->avl_balance == 0) + x->avl_balance = y->avl_balance = 0; + else /* |w->avl_balance == +1| */ + x->avl_balance = -1, y->avl_balance = 0; + w->avl_balance = 0; + } + } else if (y->avl_balance == +2) { + struct avl_node *x = y->avl_link[1]; + if (x->avl_balance == +1) { + w = x; + y->avl_link[1] = x->avl_link[0]; + x->avl_link[0] = y; + x->avl_balance = y->avl_balance = 0; + } else { + assert (x->avl_balance == -1); + w = x->avl_link[0]; + x->avl_link[0] = w->avl_link[1]; + w->avl_link[1] = x; + y->avl_link[1] = w->avl_link[0]; + w->avl_link[0] = y; + if (w->avl_balance == +1) + x->avl_balance = 0, y->avl_balance = -1; + else if (w->avl_balance == 0) + x->avl_balance = y->avl_balance = 0; + else /* |w->avl_balance == -1| */ + x->avl_balance = +1, y->avl_balance = 0; + w->avl_balance = 0; + } + } else + return &n->avl_data; + z->avl_link[y != z->avl_link[0]] = w; + + tree->avl_generation++; + return &n->avl_data; +} + +/* Inserts |item| into |table|. + Returns |NULL| if |item| was successfully inserted + or if a memory allocation error occurred. + Otherwise, returns the duplicate item. */ +void *avl_insert (struct avl_table *table, void *item) +{ + void **p = avl_probe (table, item); + return p == NULL || *p == item ? NULL : *p; +} + +/* Inserts |item| into |table|, replacing any duplicate item. + Returns |NULL| if |item| was inserted without replacing a duplicate, + or if a memory allocation error occurred. + Otherwise, returns the item that was replaced. */ +void *avl_replace (struct avl_table *table, void *item) +{ + void **p = avl_probe (table, item); + if (p == NULL || *p == item) + return NULL; + else { + void *r = *p; + *p = item; + return r; + } +} + +/* Deletes from |tree| and returns an item matching |item|. + Returns a null pointer if no matching item found. */ +void *avl_delete (struct avl_table *tree, const void *item) +{ + /* Stack of nodes. */ + struct avl_node *pa[AVL_MAX_HEIGHT]; /* Nodes. */ + unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */ + int k; /* Stack pointer. */ + + struct avl_node *p; /* Traverses tree to find node to delete. */ + int cmp; /* Result of comparison between |item| and |p|. */ + + assert (tree != NULL && item != NULL); + + k = 0; + p = (struct avl_node *) &tree->avl_root; + for (cmp = -1; cmp != 0; + cmp = tree->avl_compare (item, p->avl_data, tree->avl_param)) { + int dir = cmp > 0; + + pa[k] = p; + da[k++] = dir; + + p = p->avl_link[dir]; + if (p == NULL) + return NULL; + } + item = p->avl_data; + + if (p->avl_link[1] == NULL) + pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0]; + else { + struct avl_node *r = p->avl_link[1]; + if (r->avl_link[0] == NULL) { + r->avl_link[0] = p->avl_link[0]; + r->avl_balance = p->avl_balance; + pa[k - 1]->avl_link[da[k - 1]] = r; + da[k] = 1; + pa[k++] = r; + } else { + struct avl_node *s; + int j = k++; + + for (;;) { + da[k] = 0; + pa[k++] = r; + s = r->avl_link[0]; + if (s->avl_link[0] == NULL) + break; + + r = s; + } + + s->avl_link[0] = p->avl_link[0]; + r->avl_link[0] = s->avl_link[1]; + s->avl_link[1] = p->avl_link[1]; + s->avl_balance = p->avl_balance; + + pa[j - 1]->avl_link[da[j - 1]] = s; + da[j] = 1; + pa[j] = s; + } + } + + tree->avl_alloc->libavl_free (tree->avl_alloc, p); + + assert (k > 0); + while (--k > 0) { + struct avl_node *y = pa[k]; + + if (da[k] == 0) { + y->avl_balance++; + if (y->avl_balance == +1) + break; + else if (y->avl_balance == +2) { + struct avl_node *x = y->avl_link[1]; + if (x->avl_balance == -1) { + struct avl_node *w; + assert (x->avl_balance == -1); + w = x->avl_link[0]; + x->avl_link[0] = w->avl_link[1]; + w->avl_link[1] = x; + y->avl_link[1] = w->avl_link[0]; + w->avl_link[0] = y; + if (w->avl_balance == +1) + x->avl_balance = 0, y->avl_balance = -1; + else if (w->avl_balance == 0) + x->avl_balance = y->avl_balance = 0; + else /* |w->avl_balance == -1| */ + x->avl_balance = +1, y->avl_balance = 0; + w->avl_balance = 0; + pa[k - 1]->avl_link[da[k - 1]] = w; + } else { + y->avl_link[1] = x->avl_link[0]; + x->avl_link[0] = y; + pa[k - 1]->avl_link[da[k - 1]] = x; + if (x->avl_balance == 0) { + x->avl_balance = -1; + y->avl_balance = +1; + break; + } else + x->avl_balance = y->avl_balance = 0; + } + } + } else { + y->avl_balance--; + if (y->avl_balance == -1) + break; + else if (y->avl_balance == -2) { + struct avl_node *x = y->avl_link[0]; + if (x->avl_balance == +1) { + struct avl_node *w; + assert (x->avl_balance == +1); + w = x->avl_link[1]; + x->avl_link[1] = w->avl_link[0]; + w->avl_link[0] = x; + y->avl_link[0] = w->avl_link[1]; + w->avl_link[1] = y; + if (w->avl_balance == -1) + x->avl_balance = 0, y->avl_balance = +1; + else if (w->avl_balance == 0) + x->avl_balance = y->avl_balance = 0; + else /* |w->avl_balance == +1| */ + x->avl_balance = -1, y->avl_balance = 0; + w->avl_balance = 0; + pa[k - 1]->avl_link[da[k - 1]] = w; + } else { + y->avl_link[0] = x->avl_link[1]; + x->avl_link[1] = y; + pa[k - 1]->avl_link[da[k - 1]] = x; + if (x->avl_balance == 0) { + x->avl_balance = +1; + y->avl_balance = -1; + break; + } else + x->avl_balance = y->avl_balance = 0; + } + } + } + } + + tree->avl_count--; + tree->avl_generation++; + return (void *) item; +} + +/* Refreshes the stack of parent pointers in |trav| + and updates its generation number. */ +static void trav_refresh (struct avl_traverser *trav) +{ + assert (trav != NULL); + + trav->avl_generation = trav->avl_table->avl_generation; + + if (trav->avl_node != NULL) { + avl_comparison_func *cmp = trav->avl_table->avl_compare; + void *param = trav->avl_table->avl_param; + struct avl_node *node = trav->avl_node; + struct avl_node *i; + + trav->avl_height = 0; + for (i = trav->avl_table->avl_root; i != node;) { + assert (trav->avl_height < AVL_MAX_HEIGHT); + assert (i != NULL); + + trav->avl_stack[trav->avl_height++] = i; + i = i->avl_link[cmp (node->avl_data, i->avl_data, param) > 0]; + } + } +} + +/* Initializes |trav| for use with |tree| + and selects the null node. */ +void avl_t_init (struct avl_traverser *trav, struct avl_table *tree) +{ + trav->avl_table = tree; + trav->avl_node = NULL; + trav->avl_height = 0; + trav->avl_generation = tree->avl_generation; +} + +/* Initializes |trav| for |tree| + and selects and returns a pointer to its least-valued item. + Returns |NULL| if |tree| contains no nodes. */ +void *avl_t_first (struct avl_traverser *trav, struct avl_table *tree) +{ + struct avl_node *x; + + assert (tree != NULL && trav != NULL); + + trav->avl_table = tree; + trav->avl_height = 0; + trav->avl_generation = tree->avl_generation; + + x = tree->avl_root; + if (x != NULL) + while (x->avl_link[0] != NULL) { + assert (trav->avl_height < AVL_MAX_HEIGHT); + trav->avl_stack[trav->avl_height++] = x; + x = x->avl_link[0]; + } + trav->avl_node = x; + + return x != NULL ? x->avl_data : NULL; +} + +/* Initializes |trav| for |tree| + and selects and returns a pointer to its greatest-valued item. + Returns |NULL| if |tree| contains no nodes. */ +void *avl_t_last (struct avl_traverser *trav, struct avl_table *tree) +{ + struct avl_node *x; + + assert (tree != NULL && trav != NULL); + + trav->avl_table = tree; + trav->avl_height = 0; + trav->avl_generation = tree->avl_generation; + + x = tree->avl_root; + if (x != NULL) + while (x->avl_link[1] != NULL) { + assert (trav->avl_height < AVL_MAX_HEIGHT); + trav->avl_stack[trav->avl_height++] = x; + x = x->avl_link[1]; + } + trav->avl_node = x; + + return x != NULL ? x->avl_data : NULL; +} + +/* Searches for |item| in |tree|. + If found, initializes |trav| to the item found and returns the item + as well. + If there is no matching item, initializes |trav| to the null item + and returns |NULL|. */ +void *avl_t_find (struct avl_traverser *trav, struct avl_table *tree, + void *item) +{ + struct avl_node *p, *q; + + assert (trav != NULL && tree != NULL && item != NULL); + trav->avl_table = tree; + trav->avl_height = 0; + trav->avl_generation = tree->avl_generation; + for (p = tree->avl_root; p != NULL; p = q) { + int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param); + + if (cmp < 0) + q = p->avl_link[0]; + else if (cmp > 0) + q = p->avl_link[1]; + else { /* |cmp == 0| */ + + trav->avl_node = p; + return p->avl_data; + } + + assert (trav->avl_height < AVL_MAX_HEIGHT); + trav->avl_stack[trav->avl_height++] = p; + } + + trav->avl_height = 0; + trav->avl_node = NULL; + return NULL; +} + +/* Attempts to insert |item| into |tree|. + If |item| is inserted successfully, it is returned and |trav| is + initialized to its location. + If a duplicate is found, it is returned and |trav| is initialized to + its location. No replacement of the item occurs. + If a memory allocation failure occurs, |NULL| is returned and |trav| + is initialized to the null item. */ +void *avl_t_insert (struct avl_traverser *trav, struct avl_table *tree, + void *item) +{ + void **p; + + assert (trav != NULL && tree != NULL && item != NULL); + + p = avl_probe (tree, item); + if (p != NULL) { + trav->avl_table = tree; + trav->avl_node = ((struct avl_node *) + ((char *) p - offsetof (struct avl_node, avl_data))); + trav->avl_generation = tree->avl_generation - 1; + return *p; + } else { + avl_t_init (trav, tree); + return NULL; + } +} + +/* Initializes |trav| to have the same current node as |src|. */ +void *avl_t_copy (struct avl_traverser *trav, const struct avl_traverser *src) +{ + assert (trav != NULL && src != NULL); + + if (trav != src) { + trav->avl_table = src->avl_table; + trav->avl_node = src->avl_node; + trav->avl_generation = src->avl_generation; + if (trav->avl_generation == trav->avl_table->avl_generation) { + trav->avl_height = src->avl_height; + memcpy (trav->avl_stack, (const void *) src->avl_stack, + sizeof *trav->avl_stack * trav->avl_height); + } + } + + return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL; +} + +/* Returns the next data item in inorder + within the tree being traversed with |trav|, + or if there are no more data items returns |NULL|. */ +void *avl_t_next (struct avl_traverser *trav) +{ + struct avl_node *x; + + assert (trav != NULL); + + if (trav->avl_generation != trav->avl_table->avl_generation) + trav_refresh (trav); + + x = trav->avl_node; + if (x == NULL) { + return avl_t_first (trav, trav->avl_table); + } else if (x->avl_link[1] != NULL) { + assert (trav->avl_height < AVL_MAX_HEIGHT); + trav->avl_stack[trav->avl_height++] = x; + x = x->avl_link[1]; + + while (x->avl_link[0] != NULL) { + assert (trav->avl_height < AVL_MAX_HEIGHT); + trav->avl_stack[trav->avl_height++] = x; + x = x->avl_link[0]; + } + } else { + struct avl_node *y; + + do { + if (trav->avl_height == 0) { + trav->avl_node = NULL; + return NULL; + } + + y = x; + x = trav->avl_stack[--trav->avl_height]; + } + while (y == x->avl_link[1]); + } + trav->avl_node = x; + + return x->avl_data; +} + +/* Returns the previous data item in inorder + within the tree being traversed with |trav|, + or if there are no more data items returns |NULL|. */ +void *avl_t_prev (struct avl_traverser *trav) +{ + struct avl_node *x; + + assert (trav != NULL); + + if (trav->avl_generation != trav->avl_table->avl_generation) + trav_refresh (trav); + + x = trav->avl_node; + if (x == NULL) { + return avl_t_last (trav, trav->avl_table); + } else if (x->avl_link[0] != NULL) { + assert (trav->avl_height < AVL_MAX_HEIGHT); + trav->avl_stack[trav->avl_height++] = x; + x = x->avl_link[0]; + + while (x->avl_link[1] != NULL) { + assert (trav->avl_height < AVL_MAX_HEIGHT); + trav->avl_stack[trav->avl_height++] = x; + x = x->avl_link[1]; + } + } else { + struct avl_node *y; + + do { + if (trav->avl_height == 0) { + trav->avl_node = NULL; + return NULL; + } + + y = x; + x = trav->avl_stack[--trav->avl_height]; + } + while (y == x->avl_link[0]); + } + trav->avl_node = x; + + return x->avl_data; +} + +/* Returns |trav|'s current item. */ +void *avl_t_cur (struct avl_traverser *trav) +{ + assert (trav != NULL); + + return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL; +} + +/* Replaces the current item in |trav| by |new| and returns the item replaced. + |trav| must not have the null item selected. + The new item must not upset the ordering of the tree. */ +void *avl_t_replace (struct avl_traverser *trav, void *new) +{ + void *old; + + assert (trav != NULL && trav->avl_node != NULL && new != NULL); + old = trav->avl_node->avl_data; + trav->avl_node->avl_data = new; + return old; +} + +static void +copy_error_recovery (struct avl_node **stack, int height, + struct avl_table *new, avl_item_func * destroy) +{ + assert (stack != NULL && height >= 0 && new != NULL); + + for (; height > 2; height -= 2) + stack[height - 1]->avl_link[1] = NULL; + avl_destroy (new, destroy); +} + +/* Copies |org| to a newly created tree, which is returned. + If |copy != NULL|, each data item in |org| is first passed to |copy|, + and the return values are inserted into the tree, + with |NULL| return values taken as indications of failure. + On failure, destroys the partially created new tree, + applying |destroy|, if non-null, to each item in the new tree so far, + and returns |NULL|. + If |allocator != NULL|, it is used for allocation in the new tree. + Otherwise, the same allocator used for |org| is used. */ +struct avl_table *avl_copy (const struct avl_table *org, avl_copy_func * copy, + avl_item_func * destroy, + struct libavl_allocator *allocator) +{ + struct avl_node *stack[2 * (AVL_MAX_HEIGHT + 1)]; + int height = 0; + + struct avl_table *new; + const struct avl_node *x; + struct avl_node *y; + + assert (org != NULL); + new = avl_create (org->avl_compare, org->avl_param, + allocator != NULL ? allocator : org->avl_alloc); + if (new == NULL) + return NULL; + new->avl_count = org->avl_count; + if (new->avl_count == 0) + return new; + + x = (const struct avl_node *) &org->avl_root; + y = (struct avl_node *) &new->avl_root; + for (;;) { + while (x->avl_link[0] != NULL) { + assert (height < 2 * (AVL_MAX_HEIGHT + 1)); + + y->avl_link[0] = + new->avl_alloc->libavl_malloc (new->avl_alloc, + sizeof *y->avl_link[0]); + if (y->avl_link[0] == NULL) { + if (y != (struct avl_node *) &new->avl_root) { + y->avl_data = NULL; + y->avl_link[1] = NULL; + } + + copy_error_recovery (stack, height, new, destroy); + return NULL; + } + + stack[height++] = (struct avl_node *) x; + stack[height++] = y; + x = x->avl_link[0]; + y = y->avl_link[0]; + } + y->avl_link[0] = NULL; + + for (;;) { + y->avl_balance = x->avl_balance; + if (copy == NULL) + y->avl_data = x->avl_data; + else { + y->avl_data = copy (x->avl_data, org->avl_param); + if (y->avl_data == NULL) { + y->avl_link[1] = NULL; + copy_error_recovery (stack, height, new, destroy); + return NULL; + } + } + + if (x->avl_link[1] != NULL) { + y->avl_link[1] = + new->avl_alloc->libavl_malloc (new->avl_alloc, + sizeof *y->avl_link[1]); + if (y->avl_link[1] == NULL) { + copy_error_recovery (stack, height, new, destroy); + return NULL; + } + + x = x->avl_link[1]; + y = y->avl_link[1]; + break; + } else + y->avl_link[1] = NULL; + + if (height <= 2) + return new; + + y = stack[--height]; + x = stack[--height]; + } + } +} + +/* Frees storage allocated for |tree|. + If |destroy != NULL|, applies it to each data item in inorder. */ +void avl_destroy (struct avl_table *tree, avl_item_func * destroy) +{ + struct avl_node *p, *q; + + assert (tree != NULL); + + for (p = tree->avl_root; p != NULL; p = q) + if (p->avl_link[0] == NULL) { + q = p->avl_link[1]; + if (destroy != NULL && p->avl_data != NULL) + destroy (p->avl_data, tree->avl_param); + tree->avl_alloc->libavl_free (tree->avl_alloc, p); + } else { + q = p->avl_link[0]; + p->avl_link[0] = q->avl_link[1]; + q->avl_link[1] = p; + } + + tree->avl_alloc->libavl_free (tree->avl_alloc, tree); +} + +/* Allocates |size| bytes of space using |malloc()|. + Returns a null pointer if allocation fails. */ +void *avl_malloc (struct libavl_allocator *allocator, size_t size) +{ + assert (allocator != NULL && size > 0); + return malloc (size); +} + +/* Frees |block|. */ +void avl_free (struct libavl_allocator *allocator, void *block) +{ + assert (allocator != NULL && block != NULL); + free (block); +} + +/* Default memory allocator that uses |malloc()| and |free()|. */ +struct libavl_allocator avl_allocator_default = { + avl_malloc, + avl_free +}; + +#undef NDEBUG +#include + +/* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */ +void + (avl_assert_insert) (struct avl_table * table, void *item) { + void **p = avl_probe (table, item); + assert (p != NULL && *p == item); +} + +/* Asserts that |avl_delete()| really removes |item| from |table|, + and returns the removed item. */ +void *(avl_assert_delete) (struct avl_table * table, void *item) { + void *p = avl_delete (table, item); + assert (p != NULL); + return p; +} diff --git a/Build/source/texk/web2c/luatexdir/mp/avl.h b/Build/source/texk/web2c/luatexdir/mp/avl.h new file mode 100644 index 00000000000..acdf8bacc53 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/mp/avl.h @@ -0,0 +1,118 @@ +/* Produced by texiweb from libavl.w on 2003/01/06 at 18:07. */ + +/* libavl - library for manipulation of binary trees. + Copyright (C) 1998-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + + The author may be contacted at on the Internet, or + write to Ben Pfaff, Stanford University, Computer Science Dept., 353 + Serra Mall, Stanford CA 94305, USA. +*/ + +#ifndef AVL_H +# define AVL_H 1 + +# include +# if defined(__cplusplus) +extern "C" { +# endif + + +/* Function types. */ + typedef int avl_comparison_func (const void *avl_a, const void *avl_b, + void *avl_param); + typedef void avl_item_func (void *avl_item, void *avl_param); + typedef void *avl_copy_func (void *avl_item, void *avl_param); + +# ifndef LIBAVL_ALLOCATOR +# define LIBAVL_ALLOCATOR +/* Memory allocator. */ + struct libavl_allocator { + void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size); + void (*libavl_free) (struct libavl_allocator *, void *libavl_block); + }; +# endif + +/* Default memory allocator. */ + extern struct libavl_allocator avl_allocator_default; + void *avl_malloc (struct libavl_allocator *, size_t); + void avl_free (struct libavl_allocator *, void *); + +/* Maximum AVL height. */ +# ifndef AVL_MAX_HEIGHT +# define AVL_MAX_HEIGHT 32 +# endif + +/* Tree data structure. */ + struct avl_table { + struct avl_node *avl_root; /* Tree's root. */ + avl_comparison_func *avl_compare; /* Comparison function. */ + void *avl_param; /* Extra argument to |avl_compare|. */ + struct libavl_allocator *avl_alloc; /* Memory allocator. */ + size_t avl_count; /* Number of items in tree. */ + unsigned long avl_generation; /* Generation number. */ + }; + +/* An AVL tree node. */ + struct avl_node { + struct avl_node *avl_link[2]; /* Subtrees. */ + void *avl_data; /* Pointer to data. */ + signed char avl_balance; /* Balance factor. */ + }; + +/* AVL traverser structure. */ + struct avl_traverser { + struct avl_table *avl_table; /* Tree being traversed. */ + struct avl_node *avl_node; /* Current node in tree. */ + struct avl_node *avl_stack[AVL_MAX_HEIGHT]; + /* All the nodes above |avl_node|. */ + size_t avl_height; /* Number of nodes in |avl_parent|. */ + unsigned long avl_generation; /* Generation number. */ + }; + +/* Table functions. */ + struct avl_table *avl_create (avl_comparison_func *, void *, + struct libavl_allocator *); + struct avl_table *avl_copy (const struct avl_table *, avl_copy_func *, + avl_item_func *, struct libavl_allocator *); + void avl_destroy (struct avl_table *, avl_item_func *); + void **avl_probe (struct avl_table *, void *); + void *avl_insert (struct avl_table *, void *); + void *avl_replace (struct avl_table *, void *); + void *avl_delete (struct avl_table *, const void *); + void *avl_find (const struct avl_table *, const void *); + void avl_assert_insert (struct avl_table *, void *); + void *avl_assert_delete (struct avl_table *, void *); + +# define avl_count(table) ((size_t) (table)->avl_count) + +/* Table traverser functions. */ + void avl_t_init (struct avl_traverser *, struct avl_table *); + void *avl_t_first (struct avl_traverser *, struct avl_table *); + void *avl_t_last (struct avl_traverser *, struct avl_table *); + void *avl_t_find (struct avl_traverser *, struct avl_table *, void *); + void *avl_t_insert (struct avl_traverser *, struct avl_table *, void *); + void *avl_t_copy (struct avl_traverser *, const struct avl_traverser *); + void *avl_t_next (struct avl_traverser *); + void *avl_t_prev (struct avl_traverser *); + void *avl_t_cur (struct avl_traverser *); + void *avl_t_replace (struct avl_traverser *, void *); + +# if defined(__cplusplus) +} +# endif +#endif /* avl.h */ diff --git a/Build/source/texk/web2c/luatexdir/mp/lmplib.c b/Build/source/texk/web2c/luatexdir/mp/lmplib.c new file mode 100644 index 00000000000..7bea10e1406 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/mp/lmplib.c @@ -0,0 +1,1238 @@ +/* lmplib.c + + Copyright 2006-2008 Taco Hoekwater + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see . */ + +#include "config.h" +#include +#include +#include +#include /* temporary */ + +#ifndef pdfTeX +# include +# include +# include +#else +# include <../lua51/lua.h> +# include <../lua51/lauxlib.h> +# include <../lua51/lualib.h> +#endif + +#include "mplib.h" +#include "mplibps.h" + + /*@unused@*/ static const char _svn_version[] = + "$Id: lmplib.c 1364 2008-07-04 16:09:46Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lmplib.c $"; + +/* metatable identifiers and tests */ + +#define MPLIB_METATABLE "MPlib" +#define MPLIB_FIG_METATABLE "MPlib.fig" +#define MPLIB_GR_METATABLE "MPlib.gr" + +#define is_mp(L,b) (MP *)luaL_checkudata(L,b,MPLIB_METATABLE) +#define is_fig(L,b) (struct mp_edge_object **)luaL_checkudata(L,b,MPLIB_FIG_METATABLE) +#define is_gr_object(L,b) (struct mp_graphic_object **)luaL_checkudata(L,b,MPLIB_GR_METATABLE) + +/* Lua string pre-hashing */ + +#define mplib_init_S(a) do { \ + lua_pushliteral(L,#a); \ + mplib_##a##_ptr = (char *)lua_tostring(L,-1); \ + mplib_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \ + } while (0) + +#define mplib_push_S(a) do { \ + lua_rawgeti(L,LUA_REGISTRYINDEX,mplib_##a##_index); \ + } while (0) + +#define mplib_is_S(a,i) (mplib_##a##_ptr==(char *)lua_tostring(L,i)) + +#define mplib_make_S(a) \ + static int mplib_##a##_index = 0; \ + static char *mplib_##a##_ptr = NULL + +static int mplib_type_Ses[mp_special_code + 1] = { 0 }; /* [0] is not used */ + +mplib_make_S(fill); +mplib_make_S(outline); +mplib_make_S(text); +mplib_make_S(special); +mplib_make_S(start_bounds); +mplib_make_S(stop_bounds); +mplib_make_S(start_clip); +mplib_make_S(stop_clip); + +mplib_make_S(left_type); +mplib_make_S(right_type); +mplib_make_S(x_coord); +mplib_make_S(y_coord); +mplib_make_S(left_x); +mplib_make_S(left_y); +mplib_make_S(right_x); +mplib_make_S(right_y); + +mplib_make_S(color); +mplib_make_S(dash); +mplib_make_S(depth); +mplib_make_S(dsize); +mplib_make_S(font); +mplib_make_S(height); +mplib_make_S(htap); +mplib_make_S(linecap); +mplib_make_S(linejoin); +mplib_make_S(miterlimit); +mplib_make_S(path); +mplib_make_S(pen); +mplib_make_S(postscript); +mplib_make_S(prescript); +mplib_make_S(transform); +mplib_make_S(type); +mplib_make_S(width); + +static void mplib_init_Ses(lua_State * L) +{ + mplib_init_S(fill); + mplib_init_S(outline); + mplib_init_S(text); + mplib_init_S(start_bounds); + mplib_init_S(stop_bounds); + mplib_init_S(start_clip); + mplib_init_S(stop_clip); + mplib_init_S(special); + + mplib_type_Ses[mp_fill_code] = mplib_fill_index; + mplib_type_Ses[mp_stroked_code] = mplib_outline_index; + mplib_type_Ses[mp_text_code] = mplib_text_index; + mplib_type_Ses[mp_start_bounds_code] = mplib_start_bounds_index; + mplib_type_Ses[mp_stop_bounds_code] = mplib_stop_bounds_index; + mplib_type_Ses[mp_start_clip_code] = mplib_start_clip_index; + mplib_type_Ses[mp_stop_clip_code] = mplib_stop_clip_index; + mplib_type_Ses[mp_special_code] = mplib_special_index; + + mplib_init_S(left_type); + mplib_init_S(right_type); + mplib_init_S(x_coord); + mplib_init_S(y_coord); + mplib_init_S(left_x); + mplib_init_S(left_y); + mplib_init_S(right_x); + mplib_init_S(right_y); + + mplib_init_S(color); + mplib_init_S(dash); + mplib_init_S(depth); + mplib_init_S(dsize); + mplib_init_S(font); + mplib_init_S(height); + mplib_init_S(htap); + mplib_init_S(linecap); + mplib_init_S(linejoin); + mplib_init_S(miterlimit); + mplib_init_S(path); + mplib_init_S(pen); + mplib_init_S(postscript); + mplib_init_S(prescript); + mplib_init_S(transform); + mplib_init_S(type); + mplib_init_S(width); +} + + +/* Enumeration arrays to map MPlib enums to Lua strings */ + +static const char *interaction_options[] = + { "unknown", "batch", "nonstop", "scroll", "errorstop", NULL }; + +static const char *mplib_filetype_names[] = + { "term", "error", "mp", "log", "ps", "mem", "tfm", "map", "pfb", "enc", NULL }; + +static const char *knot_type_enum[] = + { "endpoint", "explicit", "given", "curl", "open", "end_cycle" }; + +static const char *fill_fields[] = + { "type", "path", "htap", "pen", "color", "linejoin", "miterlimit", + "prescript", "postscript", NULL }; + +static const char *stroked_fields[] = + { "type", "path", "pen", "color", "linejoin", "miterlimit", "linecap", + "dash", "prescript", "postscript", NULL }; + +static const char *text_fields[] = + { "type", "text", "dsize", "font", "color", "width", "height", "depth", + "transform", "prescript", "postscript", NULL }; + +static const char *special_fields[] = + { "type", "prescript", NULL }; + +static const char *start_bounds_fields[] = + { "type", "path", NULL }; + +static const char *start_clip_fields[] = + { "type", "path", NULL }; + +static const char *stop_bounds_fields[] = + { "type", NULL }; + +static const char *stop_clip_fields[] = + { "type", NULL }; + +static const char *no_fields[] = + { NULL }; + + +/* The list of supported MPlib options (not all make sense) */ + +typedef enum { + P_ERROR_LINE, P_MAX_LINE, + P_MAIN_MEMORY, P_HASH_SIZE, P_PARAM_SIZE, P_IN_OPEN, P_RANDOM_SEED, + P_INTERACTION, P_INI_VERSION, P_MEM_NAME, P_JOB_NAME, P_FIND_FILE, + P__SENTINEL } mplib_parm_idx; + +typedef struct { + const char *name; /* parameter name */ + mplib_parm_idx idx; /* parameter index */ +} mplib_parm_struct; + +static mplib_parm_struct mplib_parms[] = { + {"error_line", P_ERROR_LINE }, + {"print_line", P_MAX_LINE }, + {"main_memory", P_MAIN_MEMORY }, + {"hash_size", P_HASH_SIZE }, + {"param_size", P_PARAM_SIZE }, + {"max_in_open", P_IN_OPEN }, + {"random_seed", P_RANDOM_SEED }, + {"interaction", P_INTERACTION }, + {"ini_version", P_INI_VERSION }, + {"mem_name", P_MEM_NAME }, + {"job_name", P_JOB_NAME }, + {"find_file", P_FIND_FILE }, + {NULL, P__SENTINEL } +}; + + +/* Start by defining the needed callback routines for the library */ + +static char *mplib_find_file(MP mp, const char *fname, const char *fmode, int ftype) +{ + lua_State *L = (lua_State *)mp_userdata(mp); + lua_checkstack(L, 4); + lua_getfield(L, LUA_REGISTRYINDEX, "mplib_file_finder"); + if (lua_isfunction(L, -1)) { + char *s = NULL, *x = NULL; + lua_pushstring(L, fname); + lua_pushstring(L, fmode); + if (ftype >= mp_filetype_text) { + lua_pushnumber(L, (lua_Number)(ftype - mp_filetype_text)); + } else { + lua_pushstring(L, mplib_filetype_names[ftype]); + } + if (lua_pcall(L, 3, 1, 0) != 0) { + fprintf(stdout, "Error in mp.find_file: %s\n", + (char *) lua_tostring(L, -1)); + return NULL; + } + x = (char *) lua_tostring(L, -1); + if (x != NULL) + s = strdup(x); + lua_pop(L, 1); /* pop the string */ + return s; + } else { + lua_pop(L, 1); + } + if (fmode[0] != 'r' || (!access(fname, R_OK)) || ftype) { + return strdup(fname); + } + return NULL; +} + +static int mplib_find_file_function(lua_State * L) +{ + if (!(lua_isfunction(L, -1) || lua_isnil(L, -1))) { + return 1; /* error */ + } + lua_pushstring(L, "mplib_file_finder"); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + return 0; +} + +#define xfree(A) if ((A)!=NULL) { free((A)); A = NULL; } + +static int mplib_new(lua_State * L) +{ + MP *mp_ptr; + mp_ptr = lua_newuserdata(L, sizeof(MP *)); + if (mp_ptr) { + int i; + struct MP_options *options = mp_options(); + options->userdata = (void *) L; + options->noninteractive = 1; /* required ! */ + options->find_file = mplib_find_file; + options->print_found_names = 1; + if (lua_type(L, 1) == LUA_TTABLE) { + for (i = 0; mplib_parms[i].name != NULL; i++) { + lua_getfield(L, 1, mplib_parms[i].name); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + continue; /* skip unset */ + } + switch (mplib_parms[i].idx) { + case P_ERROR_LINE: + options->error_line = (int)lua_tointeger(L, -1); + if (options->error_line<60) options->error_line =60; + if (options->error_line>250) options->error_line = 250; + options->half_error_line = (options->error_line/2)+10; + break; + case P_MAX_LINE: + options->max_print_line = (int)lua_tointeger(L, -1); + if (options->max_print_line<60) options->max_print_line = 60; + break; + case P_MAIN_MEMORY: + options->main_memory = (int)lua_tointeger(L, -1); + break; + case P_HASH_SIZE: + options->hash_size = (unsigned)lua_tointeger(L, -1); + break; + case P_PARAM_SIZE: + options->param_size = (int)lua_tointeger(L, -1); + break; + case P_IN_OPEN: + options->max_in_open = (int)lua_tointeger(L, -1); + break; + case P_RANDOM_SEED: + options->random_seed = (int)lua_tointeger(L, -1); + break; + case P_INTERACTION: + options->interaction = + luaL_checkoption(L, -1, "errorstopmode", + interaction_options); + break; + case P_INI_VERSION: + options->ini_version = lua_toboolean(L, -1); + break; + case P_MEM_NAME: + options->mem_name = strdup((char *) lua_tostring(L, -1)); + break; + case P_JOB_NAME: + options->job_name = strdup((char *) lua_tostring(L, -1)); + break; + case P_FIND_FILE: + if (mplib_find_file_function(L)) { /* error here */ + fprintf(stdout, + "Invalid arguments to mp.new({find_file=...})\n"); + } + break; + default: + break; + } + lua_pop(L, 1); + } + } + *mp_ptr = mp_initialize(options); + xfree(options->command_line); + xfree(options->mem_name); + free(options); + if (*mp_ptr) { + luaL_getmetatable(L, MPLIB_METATABLE); + lua_setmetatable(L, -2); + return 1; + } + } + lua_pushnil(L); + return 1; +} + +static int mplib_collect(lua_State * L) +{ + MP *mp_ptr = is_mp(L, 1); + if (*mp_ptr != NULL) { + (void)mp_finish(*mp_ptr); + *mp_ptr = NULL; + } + return 0; +} + +static int mplib_tostring(lua_State * L) +{ + MP *mp_ptr = is_mp(L, 1); + if (*mp_ptr != NULL) { + (void)lua_pushfstring(L, "", *mp_ptr); + return 1; + } + return 0; +} + +static int mplib_wrapresults(lua_State * L, mp_run_data *res, int status) +{ + lua_checkstack(L, 5); + lua_newtable(L); + if (res->term_out.size != 0) { + lua_pushstring(L, res->term_out.data); + lua_setfield(L, -2, "term"); + } + if (res->error_out.size != 0) { + lua_pushstring(L, res->error_out.data); + lua_setfield(L, -2, "error"); + } + if (res->log_out.size != 0) { + lua_pushstring(L, res->log_out.data); + lua_setfield(L, -2, "log"); + } + if (res->edges != NULL) { + struct mp_edge_object **v; + struct mp_edge_object *p = res->edges; + int i = 1; + lua_newtable(L); + while (p != NULL) { + v = lua_newuserdata(L, sizeof(struct mp_edge_object *)); + *v = p; + luaL_getmetatable(L, MPLIB_FIG_METATABLE); + lua_setmetatable(L, -2); + lua_rawseti(L, -2, i); + i++; + p = p->next; + } + lua_setfield(L, -2, "fig"); + res->edges = NULL; + } + lua_pushnumber(L, (lua_Number)status); + lua_setfield(L, -2, "status"); + return 1; +} + +static int mplib_execute(lua_State * L) +{ + MP *mp_ptr = is_mp(L, 1); + if (*mp_ptr != NULL && lua_isstring(L, 2)) { + size_t l; + char *s = (char *) lua_tolstring(L, 2, &l); + int h = mp_execute(*mp_ptr, s, l); + mp_run_data *res = mp_rundata(*mp_ptr); + return mplib_wrapresults(L, res, h); + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_finish(lua_State * L) +{ + MP *mp_ptr = is_mp(L, 1); + if (*mp_ptr != NULL) { + int i; + int h = mp_execute(*mp_ptr,NULL,0); + mp_run_data *res = mp_rundata(*mp_ptr); + i = mplib_wrapresults(L, res, h); + (void)mp_finish(*mp_ptr); + *mp_ptr = NULL; + return i; + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_char_dimension(lua_State * L, int t) +{ + MP *mp_ptr = is_mp(L, 1); + if (*mp_ptr != NULL) { + char *fname = (char *)luaL_checkstring(L,2); + int charnum = (int)luaL_checkinteger(L,3); + if (charnum<0 || charnum>255) { + lua_pushnumber(L, (lua_Number)0); + } else { + lua_pushnumber(L,(lua_Number)mp_get_char_dimension(*mp_ptr,fname,charnum,t)); + } + } else { + lua_pushnumber(L, (lua_Number)0); + } + return 1; +} + +static int mplib_charwidth(lua_State * L) +{ + return mplib_char_dimension(L, 'w'); +} + +static int mplib_chardepth(lua_State * L) +{ + return mplib_char_dimension(L, 'd'); +} + +static int mplib_charheight(lua_State * L) +{ + return mplib_char_dimension(L, 'h'); +} + +static int mplib_version(lua_State * L) +{ + char *s = mp_metapost_version(); + lua_pushstring(L, s); + free(s); + return 1; +} + +static int mplib_statistics(lua_State * L) +{ + MP *mp_ptr = is_mp(L, 1); + if (*mp_ptr != NULL) { + lua_newtable(L); + lua_pushnumber(L, (lua_Number)mp_memory_usage(*mp_ptr)); + lua_setfield(L, -2, "main_memory"); + lua_pushnumber(L, (lua_Number)mp_hash_usage(*mp_ptr)); + lua_setfield(L, -2, "hash_size"); + lua_pushnumber(L, (lua_Number)mp_param_usage(*mp_ptr)); + lua_setfield(L, -2, "param_size"); + lua_pushnumber(L, (lua_Number)mp_open_usage(*mp_ptr)); + lua_setfield(L, -2, "max_in_open"); + } else { + lua_pushnil(L); + } + return 1; +} + + +/* figure methods */ + +static int mplib_fig_collect(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + if (*hh != NULL) { + mp_gr_toss_objects(*hh); + *hh = NULL; + } + return 0; +} + +static int mplib_fig_body(lua_State * L) +{ + int i = 1; + struct mp_graphic_object **v; + struct mp_graphic_object *p; + struct mp_edge_object **hh = is_fig(L, 1); + lua_newtable(L); + p = (*hh)->body; + while (p != NULL) { + v = lua_newuserdata(L, sizeof(struct mp_graphic_object *)); + *v = p; + luaL_getmetatable(L, MPLIB_GR_METATABLE); + lua_setmetatable(L, -2); + lua_rawseti(L, -2, i); + i++; + p = p->next; + } + (*hh)->body = NULL; /* prevent double free */ + return 1; +} + +static int mplib_fig_copy_body(lua_State * L) +{ + int i = 1; + struct mp_graphic_object **v; + struct mp_graphic_object *p; + struct mp_edge_object **hh = is_fig(L, 1); + lua_newtable(L); + p = (*hh)->body; + while (p != NULL) { + v = lua_newuserdata(L, sizeof(struct mp_graphic_object *)); + *v = mp_gr_copy_object((*hh)->parent, p); + luaL_getmetatable(L, MPLIB_GR_METATABLE); + lua_setmetatable(L, -2); + lua_rawseti(L, -2, i); + i++; + p = p->next; + } + return 1; +} + + +static int mplib_fig_tostring(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + (void)lua_pushfstring(L, "
", *hh); + return 1; +} + +static int mplib_fig_postscript(lua_State * L) +{ + mp_run_data *res; + struct mp_edge_object **hh = is_fig(L, 1); + int prologues = (int)luaL_optnumber(L, 2, (lua_Number)-1); + int procset = (int)luaL_optnumber(L, 3, (lua_Number)-1); + if (mp_ps_ship_out(*hh, prologues, procset) + && (res = mp_rundata((*hh)->parent)) + && (res->ps_out.size != 0)) { + lua_pushstring(L, res->ps_out.data); + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_fig_filename(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + if (*hh != NULL) { + char *s = (*hh)->filename; + lua_pushstring(L, s); + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_fig_width(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + if (*hh != NULL) { + lua_pushnumber(L, (double) (*hh)->width / 65536.0); + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_fig_height(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + if (*hh != NULL) { + lua_pushnumber(L, (double) (*hh)->height / 65536.0); + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_fig_depth(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + if (*hh != NULL) { + lua_pushnumber(L, (double) (*hh)->depth / 65536.0); + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_fig_italcorr(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + if (*hh != NULL) { + lua_pushnumber(L, (double) (*hh)->ital_corr / 65536.0); + } else { + lua_pushnil(L); + } + return 1; +} + +static int mplib_fig_charcode(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + if (*hh != NULL) { + lua_pushnumber(L, (lua_Number)(*hh)->charcode); + } else { + lua_pushnil(L); + } + return 1; +} + + + +static int mplib_fig_bb(lua_State * L) +{ + struct mp_edge_object **hh = is_fig(L, 1); + lua_newtable(L); + lua_pushnumber(L, (double) (*hh)->minx / 65536.0); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, (double) (*hh)->miny / 65536.0); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, (double) (*hh)->maxx / 65536.0); + lua_rawseti(L, -2, 3); + lua_pushnumber(L, (double) (*hh)->maxy / 65536.0); + lua_rawseti(L, -2, 4); + return 1; +} + +/* object methods */ + +static int mplib_gr_collect(lua_State * L) +{ + struct mp_graphic_object **hh = is_gr_object(L, 1); + if (*hh != NULL) { + mp_gr_toss_object(*hh); + *hh = NULL; + } + return 0; +} + +static int mplib_gr_tostring(lua_State * L) +{ + struct mp_graphic_object **hh = is_gr_object(L, 1); + (void)lua_pushfstring(L, "", *hh); + return 1; +} + +#define pyth(a,b) (sqrt((a)*(a) + (b)*(b))) + +#define aspect_bound (10.0/65536.0) +#define aspect_default (1.0/65536.0) + +static double eps = 0.0001; + +static double coord_range_x (mp_knot *h, double dz) { + double z; + double zlo = 0.0, zhi = 0.0; + mp_knot *f = h; + while (h != NULL) { + z = (double)h->x_coord; + if (z < zlo) zlo = z; else if (z > zhi) zhi = z; + z = (double)h->right_x; + if (z < zlo) zlo = z; else if (z > zhi) zhi = z; + z = (double)h->left_x; + if (z < zlo) zlo = z; else if (z > zhi) zhi = z; + h = h->next; + if (h==f) + break; + } + return (zhi - zlo <= dz ? aspect_bound : aspect_default); +} + +static double coord_range_y (mp_knot *h, double dz) { + double z; + double zlo = 0.0, zhi = 0.0; + mp_knot *f = h; + while (h != NULL) { + z = (double)h->y_coord; + if (z < zlo) zlo = z; else if (z > zhi) zhi = z; + z = (double)h->right_y; + if (z < zlo) zlo = z; else if (z > zhi) zhi = z; + z = (double)h->left_y; + if (z < zlo) zlo = z; else if (z > zhi) zhi = z; + h = h->next; + if (h==f) + break; + } + return (zhi - zlo <= dz ? aspect_bound : aspect_default); +} + + +static int mplib_gr_peninfo(lua_State * L) { + double x_coord, y_coord, left_x, left_y, right_x, right_y; + double wx, wy; + double rx = 1.0, sx = 0.0, sy = 0.0, ry = 1.0, tx = 0.0, ty = 0.0; + double divider = 1.0; + double width = 1.0; + mp_knot *p = NULL, *path = NULL; + struct mp_graphic_object **hh = is_gr_object(L, -1); + if (!*hh) { + lua_pushnil(L); + return 1; + } + if ((*hh)->type == mp_fill_code) { + p = ((mp_fill_object *)(*hh))->pen_p; + path = ((mp_fill_object *)(*hh))->path_p; + } else if ((*hh)->type == mp_stroked_code) { + p = ((mp_stroked_object *)(*hh))->pen_p; + path = ((mp_stroked_object *)(*hh))->path_p; + } + if (p==NULL || path == NULL) { + lua_pushnil(L); + return 1; + } + x_coord = p->x_coord/65536.0; + y_coord = p->y_coord/65536.0; + left_x = p->left_x/65536.0; + left_y = p->left_y/65536.0; + right_x = p->right_x/65536.0; + right_y = p->right_y/65536.0; + if ((right_x == x_coord) && (left_y == y_coord)) { + wx = fabs(left_x - x_coord); + wy = fabs(right_y - y_coord); + } else { + wx = pyth(left_x - x_coord, right_x - x_coord); + wy = pyth(left_y - y_coord, right_y - y_coord); + } + if ((wy/coord_range_x(path, wx)) >= (wx/coord_range_y(path, wy))) + width = wy; + else + width = wx; + tx = x_coord; + ty = y_coord; + sx = left_x - tx; + rx = left_y - ty; + ry = right_x - tx; + sy = right_y - ty; + if (width !=1.0) { + if (width == 0.0) { + sx = 1.0; sy = 1.0; + } else { + rx/=width; ry/=width; sx/=width; sy/=width; + } + } + if (fabs(sx) < eps) sx = eps; + if (fabs(sy) < eps) sy = eps; + divider = sx*sy - rx*ry; + lua_newtable(L); + lua_pushnumber(L,width); lua_setfield(L,-2,"width"); + lua_pushnumber(L,rx); lua_setfield(L,-2,"rx"); + lua_pushnumber(L,sx); lua_setfield(L,-2,"sx"); + lua_pushnumber(L,sy); lua_setfield(L,-2,"sy"); + lua_pushnumber(L,ry); lua_setfield(L,-2,"ry"); + lua_pushnumber(L,tx); lua_setfield(L,-2,"tx"); + lua_pushnumber(L,ty); lua_setfield(L,-2,"ty"); + return 1; +} + + +static int mplib_gr_fields(lua_State * L) +{ + const char **fields; + int i; + struct mp_graphic_object **hh = is_gr_object(L, 1); + if (*hh) { + switch ((*hh)->type) { + case mp_fill_code: + fields = fill_fields; + break; + case mp_stroked_code: + fields = stroked_fields; + break; + case mp_text_code: + fields = text_fields; + break; + case mp_special_code: + fields = special_fields; + break; + case mp_start_clip_code: + fields = start_clip_fields; + break; + case mp_start_bounds_code: + fields = start_bounds_fields; + break; + case mp_stop_clip_code: + fields = stop_clip_fields; + break; + case mp_stop_bounds_code: + fields = stop_bounds_fields; + break; + default: + fields = no_fields; + } + lua_newtable(L); + for (i = 0; fields[i] != NULL; i++) { + lua_pushstring(L, fields[i]); + lua_rawseti(L, -2, (i + 1)); + } + } else { + lua_pushnil(L); + } + return 1; +} + + +#define mplib_push_number(L,x) lua_pushnumber(L,(lua_Number)(x)/65536.0) + +#define MPLIB_PATH 0 +#define MPLIB_PEN 1 + +static void mplib_push_path(lua_State * L, struct mp_knot *h, int is_pen) +{ + struct mp_knot *p; /* for scanning the path */ + int i = 1; + p = h; + if (p != NULL) { + lua_newtable(L); + do { + lua_createtable(L, 0, 6); + if (!is_pen) { + if (p->left_type != mp_explicit) { + mplib_push_S(left_type); + lua_pushstring(L, knot_type_enum[p->left_type]); + lua_rawset(L, -3); + } + if (p->right_type != mp_explicit) { + mplib_push_S(right_type); + lua_pushstring(L, knot_type_enum[p->right_type]); + lua_rawset(L, -3); + } + } + mplib_push_S(x_coord); + mplib_push_number(L, p->x_coord); + lua_rawset(L, -3); + mplib_push_S(y_coord); + mplib_push_number(L, p->y_coord); + lua_rawset(L, -3); + mplib_push_S(left_x); + mplib_push_number(L, p->left_x); + lua_rawset(L, -3); + mplib_push_S(left_y); + mplib_push_number(L, p->left_y); + lua_rawset(L, -3); + mplib_push_S(right_x); + mplib_push_number(L, p->right_x); + lua_rawset(L, -3); + mplib_push_S(right_y); + mplib_push_number(L, p->right_y); + lua_rawset(L, -3); + lua_rawseti(L, -2, i); + i++; + if (p->right_type == mp_endpoint) { + return; + } + p = p->next; + } while (p != h); + } else { + lua_pushnil(L); + } +} + +/* this assumes that the top of the stack is a table + or nil already in the case + */ +static void mplib_push_pentype(lua_State * L, struct mp_knot *h) +{ + struct mp_knot *p; /* for scanning the path */ + p = h; + if (p == NULL) { + /* do nothing */ + } else if (p == p->next) { + mplib_push_S(type); + lua_pushstring(L, "elliptical"); + lua_rawset(L, -3); + } else { + } +} + +#define set_color_objects(pq) \ + object_color_model = pq->color_model; \ + object_color_a = pq->color.a_val; \ + object_color_b = pq->color.b_val; \ + object_color_c = pq->color.c_val; \ + object_color_d = pq->color.d_val; + + +static void mplib_push_color(lua_State * L, struct mp_graphic_object *p) +{ + int object_color_model; + int object_color_a, object_color_b, object_color_c, object_color_d; + if (p != NULL) { + if (p->type == mp_fill_code) { + mp_fill_object *h = (mp_fill_object *) p; + set_color_objects(h); + } else if (p->type == mp_stroked_code) { + mp_stroked_object *h = (mp_stroked_object *) p; + set_color_objects(h); + } else { + mp_text_object *h = (mp_text_object *) p; + set_color_objects(h); + } + lua_newtable(L); + if (object_color_model >= mp_grey_model) { + mplib_push_number(L, object_color_a); + lua_rawseti(L, -2, 1); + if (object_color_model >= mp_rgb_model) { + mplib_push_number(L, object_color_b); + lua_rawseti(L, -2, 2); + mplib_push_number(L, object_color_c); + lua_rawseti(L, -2, 3); + if (object_color_model == mp_cmyk_model) { + mplib_push_number(L, object_color_d); + lua_rawseti(L, -2, 4); + } + } + } + } else { + lua_pushnil(L); + } +} + +/* the dash scale is not exported, the field has no external value */ +static void mplib_push_dash(lua_State * L, struct mp_stroked_object *h) +{ + mp_dash_object *d; + double ds; + if (h != NULL && h->dash_p != NULL) { + d = h->dash_p; + lua_newtable(L); + mplib_push_number(L, d->offset); + lua_setfield(L, -2, "offset"); + if (d->array != NULL) { + int i = 0; + lua_newtable(L); + while (*(d->array + i) != -1) { + ds = *(d->array + i) / 65536.0; + lua_pushnumber(L, ds); + i++; + lua_rawseti(L, -2, i); + } + lua_setfield(L, -2, "dashes"); + } + } else { + lua_pushnil(L); + } +} + +static void mplib_push_transform(lua_State * L, struct mp_text_object *h) +{ + int i = 1; + if (h != NULL) { + lua_createtable(L, 6, 0); + mplib_push_number(L, h->tx); + lua_rawseti(L, -2, i); + i++; + mplib_push_number(L, h->ty); + lua_rawseti(L, -2, i); + i++; + mplib_push_number(L, h->txx); + lua_rawseti(L, -2, i); + i++; + mplib_push_number(L, h->tyx); + lua_rawseti(L, -2, i); + i++; + mplib_push_number(L, h->txy); + lua_rawseti(L, -2, i); + i++; + mplib_push_number(L, h->tyy); + lua_rawseti(L, -2, i); + i++; + } else { + lua_pushnil(L); + } +} + +#define FIELD(A) (mplib_is_S(A,2)) + +static void mplib_fill(lua_State * L, struct mp_fill_object *h) +{ + if (FIELD(path)) { + mplib_push_path(L, h->path_p, MPLIB_PATH); + } else if (FIELD(htap)) { + mplib_push_path(L, h->htap_p, MPLIB_PATH); + } else if (FIELD(pen)) { + mplib_push_path(L, h->pen_p, MPLIB_PEN); + mplib_push_pentype(L, h->pen_p); + } else if (FIELD(color)) { + mplib_push_color(L, (mp_graphic_object *) h); + } else if (FIELD(linejoin)) { + lua_pushnumber(L, (lua_Number)h->ljoin); + } else if (FIELD(miterlimit)) { + mplib_push_number(L, h->miterlim); + } else if (FIELD(prescript)) { + lua_pushstring(L, h->pre_script); + } else if (FIELD(postscript)) { + lua_pushstring(L, h->post_script); + } else { + lua_pushnil(L); + } +} + +static void mplib_stroked(lua_State * L, struct mp_stroked_object *h) +{ + if (FIELD(path)) { + mplib_push_path(L, h->path_p, MPLIB_PATH); + } else if (FIELD(pen)) { + mplib_push_path(L, h->pen_p, MPLIB_PEN); + mplib_push_pentype(L, h->pen_p); + } else if (FIELD(color)) { + mplib_push_color(L, (mp_graphic_object *) h); + } else if (FIELD(dash)) { + mplib_push_dash(L, h); + } else if (FIELD(linecap)) { + lua_pushnumber(L, (lua_Number)h->lcap); + } else if (FIELD(linejoin)) { + lua_pushnumber(L, (lua_Number)h->ljoin); + } else if (FIELD(miterlimit)) { + mplib_push_number(L, h->miterlim); + } else if (FIELD(prescript)) { + lua_pushstring(L, h->pre_script); + } else if (FIELD(postscript)) { + lua_pushstring(L, h->post_script); + } else { + lua_pushnil(L); + } +} + +static void mplib_text(lua_State * L, struct mp_text_object *h) +{ + if (FIELD(text)) { + lua_pushstring(L, h->text_p); + } else if (FIELD(dsize)) { + mplib_push_number(L, (h->font_dsize / 16)); + } else if (FIELD(font)) { + lua_pushstring(L, h->font_name); + } else if (FIELD(color)) { + mplib_push_color(L, (mp_graphic_object *) h); + } else if (FIELD(width)) { + mplib_push_number(L, h->width); + } else if (FIELD(height)) { + mplib_push_number(L, h->height); + } else if (FIELD(depth)) { + mplib_push_number(L, h->depth); + } else if (FIELD(transform)) { + mplib_push_transform(L, h); + } else if (FIELD(prescript)) { + lua_pushstring(L, h->pre_script); + } else if (FIELD(postscript)) { + lua_pushstring(L, h->post_script); + } else { + lua_pushnil(L); + } +} + +static void mplib_special(lua_State * L, struct mp_special_object *h) +{ + if (FIELD(prescript)) { + lua_pushstring(L, h->pre_script); + } else { + lua_pushnil(L); + } +} + +static void mplib_start_bounds(lua_State * L, struct mp_bounds_object *h) +{ + if (FIELD(path)) { + mplib_push_path(L, h->path_p, MPLIB_PATH); + } else { + lua_pushnil(L); + } +} + +static void mplib_start_clip(lua_State * L, struct mp_clip_object *h) +{ + if (FIELD(path)) { + mplib_push_path(L, h->path_p, MPLIB_PATH); + } else { + lua_pushnil(L); + } +} + +static int mplib_gr_index(lua_State * L) +{ + struct mp_graphic_object **hh = is_gr_object(L, 1); + if (*hh) { + struct mp_graphic_object *h = *hh; + + if (mplib_is_S(type, 2)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, mplib_type_Ses[h->type]); + } else { + switch (h->type) { + case mp_fill_code: + mplib_fill(L, (mp_fill_object *) h); + break; + case mp_stroked_code: + mplib_stroked(L, (mp_stroked_object *) h); + break; + case mp_text_code: + mplib_text(L, (mp_text_object *) h); + break; + case mp_special_code: + mplib_special(L, (mp_special_object *) h); + break; + case mp_start_clip_code: + mplib_start_clip(L, (mp_clip_object *) h); + break; + case mp_start_bounds_code: + mplib_start_bounds(L, (mp_bounds_object *) h); + break; + case mp_stop_clip_code: + case mp_stop_bounds_code: + default: + lua_pushnil(L); + } + } + } else { + lua_pushnil(L); + } + return 1; +} + + +static const struct luaL_reg mplib_meta[] = { + {"__gc", mplib_collect}, + {"__tostring", mplib_tostring}, + {NULL, NULL} /* sentinel */ +}; + +static const struct luaL_reg mplib_fig_meta[] = { + {"__gc", mplib_fig_collect}, + {"__tostring", mplib_fig_tostring}, + {"objects", mplib_fig_body}, + {"copy_objects", mplib_fig_copy_body}, + {"filename", mplib_fig_filename}, + {"postscript", mplib_fig_postscript}, + {"boundingbox", mplib_fig_bb}, + {"width", mplib_fig_width}, + {"height", mplib_fig_height}, + {"depth", mplib_fig_depth}, + {"italcorr", mplib_fig_italcorr}, + {"charcode", mplib_fig_charcode}, + {NULL, NULL} /* sentinel */ +}; + +static const struct luaL_reg mplib_gr_meta[] = { + {"__gc", mplib_gr_collect}, + {"__tostring", mplib_gr_tostring}, + {"__index", mplib_gr_index}, + {NULL, NULL} /* sentinel */ +}; + +static const struct luaL_reg mplib_d[] = { + {"execute", mplib_execute}, + {"finish", mplib_finish}, + {"char_width", mplib_charwidth}, + {"char_height", mplib_charheight}, + {"char_depth", mplib_chardepth}, + {"statistics", mplib_statistics}, + {NULL, NULL} /* sentinel */ +}; + + +static const struct luaL_reg mplib_m[] = { + {"new", mplib_new}, + {"version", mplib_version}, + {"fields", mplib_gr_fields}, + {"pen_info", mplib_gr_peninfo}, + {NULL, NULL} /* sentinel */ +}; + + +int luaopen_mplib(lua_State * L) +{ + mplib_init_Ses(L); + + luaL_newmetatable(L, MPLIB_GR_METATABLE); + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, mplib_gr_meta); /* object meta methods */ + lua_pop(L, 1); + + luaL_newmetatable(L, MPLIB_FIG_METATABLE); + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, mplib_fig_meta); /* figure meta methods */ + lua_pop(L, 1); + + luaL_newmetatable(L, MPLIB_METATABLE); + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, mplib_meta); /* meta methods */ + luaL_register(L, NULL, mplib_d); /* dict methods */ + luaL_register(L, "mplib", mplib_m); /* module functions */ + return 1; +} diff --git a/Build/source/texk/web2c/luatexdir/mp/memio.w b/Build/source/texk/web2c/luatexdir/mp/memio.w new file mode 100644 index 00000000000..06bf9bf91d4 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/mp/memio.w @@ -0,0 +1,405 @@ +% $Id: psout.w 616 2008-07-09 14:05:55Z taco $ +% +% Copyright 2008 Taco Hoekwater. +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 2 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . +% +% TeX is a trademark of the American Mathematical Society. +% METAFONT is a trademark of Addison-Wesley Publishing Company. +% PostScript is a trademark of Adobe Systems Incorporated. + +% Here is TeX material that gets inserted after \input webmac + +\font\tenlogo=logo10 % font used for the METAFONT logo +\def\MP{{\tenlogo META}\-{\tenlogo POST}} +\def\title{MetaPost MEM reading and writing} +\def\topofcontents{\hsize 5.5in + \vglue -30pt plus 1fil minus 1.5in + \def\?##1]{\hbox to 1in{\hfil##1.\ }} + } +\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in} +\pdfoutput=1 +\pageno=3 + +@ As usual, need true and false. + +@d true 1 +@d false 0 +@d null 0 /* the null pointer */ +@d incr(A) (A)=(A)+1 /* increase a variable by unity */ +@d decr(A) (A)=(A)-1 /* decrease a variable by unity */ +@d qo(A) (A) /* to read eight bits from a quarterword */ +@d qi(A) (quarterword)(A) /* to store eight bits in a quarterword */ +@d max_quarterword 0x3FFF /* largest allowable value in a |quarterword| */ +@d max_halfword 0xFFFFFFF /* largest allowable value in a |halfword| */ +@d max_str_ref 127 /* ``infinite'' number of references */ + + +@c +#include "config.h" +#include +#include +#include +#include "mplib.h" +#include "mpmp.h" + +@ @c void mp_store_mem_file (MP mp) { + integer k; /* all-purpose index */ + pointer p,q; /* all-purpose pointers */ + integer x; /* something to dump */ + four_quarters w; /* four ASCII codes */ + memory_word WW; + @; + @; + @; + @; + @; + @; + @; +} + +@ Corresponding to the procedure that dumps a mem file, we also have a function +that reads~one~in. The function returns |false| if the dumped mem is +incompatible with the present \MP\ table sizes, etc. + +@d too_small(A) { wake_up_terminal; + wterm_ln("---! Must increase the "); wterm((A)); +@.Must increase the x@> + goto OFF_BASE; + } + +@c +boolean mp_load_mem_file (MP mp) { + integer k; /* all-purpose index */ + pointer p,q; /* all-purpose pointers */ + integer x; /* something undumped */ + str_number s; /* some temporary string */ + four_quarters w; /* four ASCII codes */ + memory_word WW; + @; + @; + @; + @; + return true; /* it worked! */ +OFF_BASE: + wake_up_terminal; + wterm_ln("(Fatal mem file error; I'm stymied)\n"); +@.Fatal mem file error@> + return false; +} + +@ Mem files consist of |memory_word| items, and we use the following +macros to dump words of different types: + +@d dump_wd(A) { WW=(A); (mp->write_binary_file)(mp,mp->mem_file,&WW,sizeof(WW)); } +@d dump_int(A) { int cint=(A); (mp->write_binary_file)(mp,mp->mem_file,&cint,sizeof(cint)); } +@d dump_hh(A) { WW.hh=(A); (mp->write_binary_file)(mp,mp->mem_file,&WW,sizeof(WW)); } +@d dump_qqqq(A) { WW.qqqq=(A); (mp->write_binary_file)(mp,mp->mem_file,&WW,sizeof(WW)); } +@d dump_string(A) { dump_int((int)(strlen(A)+1)); + (mp->write_binary_file)(mp,mp->mem_file,A,strlen(A)+1); } + +@ The inverse macros are slightly more complicated, since we need to check +the range of the values we are reading in. We say `|undump(a)(b)(x)|' to +read an integer value |x| that is supposed to be in the range |a<=x<=b|. + +@d mgeti(A) do { + size_t wanted = sizeof(A); + void *A_ptr = &A; + (mp->read_binary_file)(mp, mp->mem_file,&A_ptr,&wanted); + if (wanted!=sizeof(A)) goto OFF_BASE; +} while (0) + +@d mgetw(A) do { + size_t wanted = sizeof(A); + void *A_ptr = &A; + (mp->read_binary_file)(mp, mp->mem_file,&A_ptr,&wanted); + if (wanted!=sizeof(A)) goto OFF_BASE; +} while (0) + +@d undump_wd(A) { mgetw(WW); A=WW; } +@d undump_int(A) { int cint; mgeti(cint); A=cint; } +@d undump_hh(A) { mgetw(WW); A=WW.hh; } +@d undump_qqqq(A) { mgetw(WW); A=WW.qqqq; } +@d undump_strings(A,B,C) { + undump_int(x); if ( (x<(A)) || (x>(B)) ) goto OFF_BASE; else C=str(x); } +@d undump(A,B,C) { undump_int(x); + if ( (x<(A)) || (x>(int)(B)) ) goto OFF_BASE; else C=x; } +@d undump_size(A,B,C,D) { undump_int(x); + if (x<(A)) goto OFF_BASE; + if (x>(B)) too_small((C)); else D=x; } +@d undump_string(A) { + size_t the_wanted; + void *the_string; + integer XX=0; + undump_int(XX); + the_wanted = (size_t)XX; + the_string = mp_xmalloc(mp,(size_t)XX,1); + (mp->read_binary_file)(mp,mp->mem_file,&the_string,&the_wanted); + A = (char *)the_string; + if (the_wanted!=(size_t)XX) goto OFF_BASE; +} + +@ The next few sections of the program should make it clear how we use the +dump/undump macros. + +@= +x = metapost_magic; dump_int(x); +dump_int(mp->mem_top); +dump_int((integer)mp->hash_size); +dump_int(mp->hash_prime) +dump_int(mp->param_size); +dump_int(mp->max_in_open); + +@ Sections of a \.{WEB} program that are ``commented out'' still contribute +strings to the string pool; therefore \.{INIMP} and \MP\ will have +the same strings. (And it is, of course, a good thing that they do.) +@.WEB@> +@^string pool@> + +@ @c +int mp_undump_constants (MP mp) { + integer x; + undump_int(x); + if (x!=metapost_magic) return x; + undump_int(x); mp->mem_top = x; + undump_int(x); mp->hash_size = (unsigned)x; + undump_int(x); mp->hash_prime = x; + undump_int(x); mp->param_size = x; + undump_int(x); mp->max_in_open = x; + return metapost_magic; + OFF_BASE: + return -1; +} + +@ We do string pool compaction to avoid dumping unused strings. + +@d dump_four_ASCII + w.b0=qi(mp->str_pool[k]); w.b1=qi(mp->str_pool[k+1]); + w.b2=qi(mp->str_pool[k+2]); w.b3=qi(mp->str_pool[k+3]); + dump_qqqq(w) + +@= +mp_do_compaction(mp, mp->pool_size); +dump_int(mp->pool_ptr); +dump_int(mp->max_str_ptr); +dump_int(mp->str_ptr); +k=0; +while ( (mp->next_str[k]==k+1) && (k<=mp->max_str_ptr) ) + k++; +dump_int(k); +while ( k<=mp->max_str_ptr ) { + dump_int(mp->next_str[k]); incr(k); +} +k=0; +while (1) { + dump_int(mp->str_start[k]); /* TODO: valgrind warning here */ + if ( k==mp->str_ptr ) { + break; + } else { + k=mp->next_str[k]; + } +} +k=0; +while (k+4pool_ptr ) { + dump_four_ASCII; k=k+4; +} +k=mp->pool_ptr-4; dump_four_ASCII; +mp_print_ln(mp); mp_print(mp, "at most "); mp_print_int(mp, mp->max_str_ptr); +mp_print(mp, " strings of total length "); +mp_print_int(mp, mp->pool_ptr) + +@ @d undump_four_ASCII + undump_qqqq(w); + mp->str_pool[k]=(ASCII_code)qo(w.b0); mp->str_pool[k+1]=(ASCII_code)qo(w.b1); + mp->str_pool[k+2]=(ASCII_code)qo(w.b2); mp->str_pool[k+3]=(ASCII_code)qo(w.b3) + +@= +undump_int(mp->pool_ptr); +mp_reallocate_pool(mp, mp->pool_ptr) ; +undump_int(mp->max_str_ptr); +mp_reallocate_strings (mp,mp->max_str_ptr) ; +undump(0,mp->max_str_ptr,mp->str_ptr); +undump(0,mp->max_str_ptr+1,s); +for (k=0;k<=s-1;k++) + mp->next_str[k]=k+1; +for (k=s;k<=mp->max_str_ptr;k++) + undump(s+1,mp->max_str_ptr+1,mp->next_str[k]); +mp->fixed_str_use=0; +k=0; +while (1) { + undump(0,mp->pool_ptr,mp->str_start[k]); + if ( k==mp->str_ptr ) break; + mp->str_ref[k]=max_str_ref; + incr(mp->fixed_str_use); + mp->last_fixed_str=k; k=mp->next_str[k]; +} +k=0; +while ( k+4pool_ptr ) { + undump_four_ASCII; k=k+4; +} +k=mp->pool_ptr-4; undump_four_ASCII; +mp->init_str_use=mp->fixed_str_use; mp->init_pool_ptr=mp->pool_ptr; +mp->max_pool_ptr=mp->pool_ptr; +mp->strs_used_up=mp->fixed_str_use; +mp->pool_in_use=mp->str_start[mp->str_ptr]; mp->strs_in_use=mp->fixed_str_use; +mp->max_pl_used=mp->pool_in_use; mp->max_strs_used=mp->strs_in_use; +mp->pact_count=0; mp->pact_chars=0; mp->pact_strs=0; + +@ By sorting the list of available spaces in the variable-size portion of +|mem|, we are usually able to get by without having to dump very much +of the dynamic memory. + +We recompute |var_used| and |dyn_used|, so that \.{INIMP} dumps valid +information even when it has not been gathering statistics. + +@= +mp_sort_avail(mp); mp->var_used=0; +dump_int(mp->lo_mem_max); dump_int(mp->rover); +p=0; q=mp->rover; x=0; +do { + for (k=p;k<= q+1;k++) + dump_wd(mp->mem[k]); + x=x+q+2-p; mp->var_used=mp->var_used+q-p; + p=q+node_size(q); q=rmp_link(q); +} while (q!=mp->rover); +mp->var_used=mp->var_used+mp->lo_mem_max-p; +mp->dyn_used=mp->mem_end+1-mp->hi_mem_min; +for (k=p;k<= mp->lo_mem_max;k++ ) + dump_wd(mp->mem[k]); +x=x+mp->lo_mem_max+1-p; +dump_int(mp->hi_mem_min); dump_int(mp->avail); +for (k=mp->hi_mem_min;k<=mp->mem_end;k++ ) + dump_wd(mp->mem[k]); +x=x+mp->mem_end+1-mp->hi_mem_min; +p=mp->avail; +while ( p!=null ) { + decr(mp->dyn_used); p=mp_link(p); +} +dump_int(mp->var_used); dump_int(mp->dyn_used); +mp_print_ln(mp); mp_print_int(mp, x); +mp_print(mp, " memory locations dumped; current usage is "); +mp_print_int(mp, mp->var_used); mp_print_char(mp, xord('&')); mp_print_int(mp, mp->dyn_used) + +@ @= +undump(lo_mem_stat_max+1000,hi_mem_stat_min-1,mp->lo_mem_max); +undump(lo_mem_stat_max+1,mp->lo_mem_max,mp->rover); +p=0; q=mp->rover; +do { + for (k=p;k<= q+1; k++) + undump_wd(mp->mem[k]); + p=q+node_size(q); + if ( (p>mp->lo_mem_max)||((q>=rmp_link(q))&&(rmp_link(q)!=mp->rover)) ) + goto OFF_BASE; + q=rmp_link(q); +} while (q!=mp->rover); +for (k=p;k<=mp->lo_mem_max;k++ ) + undump_wd(mp->mem[k]); +undump(mp->lo_mem_max+1,hi_mem_stat_min,mp->hi_mem_min); +undump(null,mp->mem_top,mp->avail); mp->mem_end=mp->mem_top; +mp->last_pending=spec_head; +for (k=mp->hi_mem_min;k<= mp->mem_end;k++) + undump_wd(mp->mem[k]); +undump_int(mp->var_used); undump_int(mp->dyn_used) + +@ A different scheme is used to compress the hash table, since its lower region +is usually sparse. When |text(p)<>0| for |p<=hash_used|, we output three +words: |p|, |hash[p]|, and |eqtb[p]|. The hash table is, of course, densely +packed for |p>=hash_used|, so the remaining entries are output in~a~block. + +@= +dump_int(mp->hash_used); +mp->st_count=frozen_inaccessible-1-mp->hash_used; +for (p=1;p<=mp->hash_used;p++) { + if ( text(p)!=0 ) { + dump_int(p); dump_hh(mp->hash[p]); dump_hh(mp->eqtb[p]); incr(mp->st_count); + } +} +for (p=mp->hash_used+1;p<=(int)hash_end;p++) { + dump_hh(mp->hash[p]); dump_hh(mp->eqtb[p]); +} +dump_int(mp->st_count); +mp_print_ln(mp); mp_print_int(mp, mp->st_count); mp_print(mp, " symbolic tokens") + +@ @= +undump(1,frozen_inaccessible,mp->hash_used); +p=0; +do { + undump(p+1,mp->hash_used,p); + undump_hh(mp->hash[p]); undump_hh(mp->eqtb[p]); +} while (p!=mp->hash_used); +for (p=mp->hash_used+1;p<=(int)hash_end;p++ ) { + undump_hh(mp->hash[p]); undump_hh(mp->eqtb[p]); +} +undump_int(mp->st_count) + +@ We have already printed a lot of statistics, so we set |mp_tracing_stats:=0| +to prevent them appearing again. + +@= +dump_int(mp->max_internal); +dump_int(mp->int_ptr); +for (k=1;k<= mp->int_ptr;k++ ) { + dump_int(mp->internal[k]); + dump_string(mp->int_name[k]); +} +dump_int(mp->start_sym); +dump_int(mp->interaction); +dump_string(mp->mem_ident); +dump_int(mp->bg_loc); dump_int(mp->eg_loc); dump_int(mp->serial_no); dump_int(69073); +mp->internal[mp_tracing_stats]=0 + +@ @= +undump_int(x); +if (x>mp->max_internal) mp_grow_internals(mp,x); +undump_int(mp->int_ptr); +for (k=1;k<= mp->int_ptr;k++) { + undump_int(mp->internal[k]); + undump_string(mp->int_name[k]); +} +undump(0,frozen_inaccessible,mp->start_sym); +if (mp->interaction==mp_unspecified_mode) { + undump(mp_unspecified_mode,mp_error_stop_mode,mp->interaction); +} else { + undump(mp_unspecified_mode,mp_error_stop_mode,x); +} +undump_string(mp->mem_ident); +undump(1,hash_end,mp->bg_loc); +undump(1,hash_end,mp->eg_loc); +undump_int(mp->serial_no); +undump_int(x); +if (x!=69073) goto OFF_BASE + +@ @= +{ + char *tmp = mp_xmalloc(mp,11,1); + mp_xfree(mp->mem_ident); + mp->mem_ident = mp_xmalloc(mp,256,1); + mp_snprintf(tmp,11,"%04d.%02d.%02d", + (int)mp_round_unscaled(mp, mp->internal[mp_year]), + (int)mp_round_unscaled(mp, mp->internal[mp_month]), + (int)mp_round_unscaled(mp, mp->internal[mp_day])); + mp_snprintf(mp->mem_ident,256," (mem=%s %s)",mp->job_name, tmp); + mp_xfree(tmp); + mp_pack_job_name(mp, ".mem"); + while (! mp_w_open_out(mp, &mp->mem_file) ) + mp_prompt_file_name(mp, "mem file name", ".mem"); + mp_print_nl(mp, "Beginning to dump on file "); +@.Beginning to dump...@> + mp_print(mp, mp->name_of_file); + mp_print_nl(mp, mp->mem_ident); +} + +@ @= +(mp->close_file)(mp,mp->mem_file) diff --git a/Build/source/texk/web2c/luatexdir/mp/mp.w b/Build/source/texk/web2c/luatexdir/mp/mp.w new file mode 100644 index 00000000000..ef61a38f820 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/mp/mp.w @@ -0,0 +1,26390 @@ +% $Id: mp.w 806 2008-12-23 16:22:29Z taco $ +% +% Copyright 2008 Taco Hoekwater. +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 2 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . +% +% TeX is a trademark of the American Mathematical Society. +% METAFONT is a trademark of Addison-Wesley Publishing Company. +% PostScript is a trademark of Adobe Systems Incorporated. + +% Here is TeX material that gets inserted after \input webmac +\def\hang{\hangindent 3em\noindent\ignorespaces} +\def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces} +\def\ps{PostScript} +\def\psqrt#1{\sqrt{\mathstrut#1}} +\def\k{_{k+1}} +\def\pct!{{\char`\%}} % percent sign in ordinary text +\font\tenlogo=logo10 % font used for the METAFONT logo +\font\logos=logosl10 +\def\MF{{\tenlogo META}\-{\tenlogo FONT}} +\def\MP{{\tenlogo META}\-{\tenlogo POST}} +\def\[#1]{\ignorespaces} % left over from pascal web +\def\<#1>{$\langle#1\rangle$} +\def\section{\mathhexbox278} +\let\swap=\leftrightarrow +\def\round{\mathop{\rm round}\nolimits} +\mathchardef\vbv="026A % synonym for `\|' +\def\vb{\relax\ifmmode\vbv\else$\vbv$\fi} + +\def\(#1){} % this is used to make section names sort themselves better +\def\9#1{} % this is used for sort keys in the index via @@:sort key}{entry@@> +\def\title{MetaPost} +\pdfoutput=1 +\pageno=3 + +@* \[1] Introduction. + +This is \MP\ by John Hobby, a graphics-language processor based on D. E. Knuth's \MF. + +Much of the original Pascal version of this program was copied with +permission from MF.web Version 1.9. It interprets a language very +similar to D.E. Knuth's METAFONT, but with changes designed to make it +more suitable for PostScript output. + +The main purpose of the following program is to explain the algorithms of \MP\ +as clearly as possible. However, the program has been written so that it +can be tuned to run efficiently in a wide variety of operating environments +by making comparatively few changes. Such flexibility is possible because +the documentation that follows is written in the \.{WEB} language, which is +at a higher level than C. + +A large piece of software like \MP\ has inherent complexity that cannot +be reduced below a certain level of difficulty, although each individual +part is fairly simple by itself. The \.{WEB} language is intended to make +the algorithms as readable as possible, by reflecting the way the +individual program pieces fit together and by providing the +cross-references that connect different parts. Detailed comments about +what is going on, and about why things were done in certain ways, have +been liberally sprinkled throughout the program. These comments explain +features of the implementation, but they rarely attempt to explain the +\MP\ language itself, since the reader is supposed to be familiar with +{\sl The {\logos METAFONT\/}book} as well as the manual +@.WEB@> +@:METAFONTbook}{\sl The {\logos METAFONT\/}book@> +{\sl A User's Manual for MetaPost}, Computing Science Technical Report 162, +AT\AM T Bell Laboratories. + +@ The present implementation is a preliminary version, but the possibilities +for new features are limited by the desire to remain as nearly compatible +with \MF\ as possible. + +On the other hand, the \.{WEB} description can be extended without changing +the core of the program, and it has been designed so that such +extensions are not extremely difficult to make. +The |banner| string defined here should be changed whenever \MP\ +undergoes any modifications, so that it will be clear which version of +\MP\ might be the guilty party when a problem arises. +@^extensions to \MP@> +@^system dependencies@> + +@d default_banner "This is MetaPost, Version 1.102" /* printed when \MP\ starts */ +@d true 1 +@d false 0 + +@(mpmp.h@>= +#define metapost_version "1.102" +#define metapost_magic (('M'*256) + 'P')*65536 + 1102 +#define metapost_old_magic (('M'*256) + 'P')*65536 + 1080 + +@ The external library header for \MP\ is |mplib.h|. It contains a +few typedefs and the header defintions for the externally used +fuctions. + +The most important of the typedefs is the definition of the structure +|MP_options|, that acts as a small, configurable front-end to the fairly +large |MP_instance| structure. + +@(mplib.h@>= +typedef struct MP_instance * MP; +@ +typedef struct MP_options { + @
0 ) { + if ( a; + if ( big ) { + if ( aarith_error=true; a=el_gordo; + }; + } + } + return a; +} + +@ The key idea here is to reflect the vector $(a,b)$ about the +line through $(a,b/2)$. + +@= +while (1) { + r=mp_make_fraction(mp, b,a); + r=mp_take_fraction(mp, r,r); /* now $r\approx b^2/a^2$ */ + if ( r==0 ) break; + r=mp_make_fraction(mp, r,fraction_four+r); + a=a+mp_take_fraction(mp, a+a,r); b=mp_take_fraction(mp, b,r); +} + + +@ Here is a similar algorithm for $\psqrt{a^2-b^2}$. +It converges slowly when $b$ is near $a$, but otherwise it works fine. + +@c +static integer mp_pyth_sub (MP mp,integer a, integer b) { + fraction r; /* register used to transform |a| and |b| */ + boolean big; /* is the input dangerously near $2^{31}$? */ + a=abs(a); b=abs(b); + if ( a<=b ) { + @; + } else { + if ( a; + if ( big ) double(a); + } + return a; +} + +@ @= +while (1) { + r=mp_make_fraction(mp, b,a); + r=mp_take_fraction(mp, r,r); /* now $r\approx b^2/a^2$ */ + if ( r==0 ) break; + r=mp_make_fraction(mp, r,fraction_four-r); + a=a-mp_take_fraction(mp, a+a,r); b=mp_take_fraction(mp, b,r); +} + +@ @= +{ + if ( a + help2("Since I don't take square roots of negative numbers,", + "I'm zeroing this one. Proceed, with fingers crossed."); + mp_error(mp); + } + a=0; +} + +@ The subroutines for logarithm and exponential involve two tables. +The first is simple: |two_to_the[k]| equals $2^k$. The second involves +a bit more calculation, which the author claims to have done correctly: +|spec_log[k]| is $2^{27}$ times $\ln\bigl(1/(1-2^{-k})\bigr)= +2^{-k}+{1\over2}2^{-2k}+{1\over3}2^{-3k}+\cdots\,$, rounded to the +nearest integer. + +@d two_to_the(A) (1<<(unsigned)(A)) + +@= +static const integer spec_log[29] = { 0, /* special logarithms */ +93032640, 38612034, 17922280, 8662214, 4261238, 2113709, +1052693, 525315, 262400, 131136, 65552, 32772, 16385, +8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 1 }; + +@ @= +integer k; /* all-purpose loop index */ + + +@ Here is the routine that calculates $2^8$ times the natural logarithm +of a |scaled| quantity; it is an integer approximation to $2^{24}\ln(x/2^{16})$, +when |x| is a given positive integer. + +The method is based on exercise 1.2.2--25 in {\sl The Art of Computer +Programming\/}: During the main iteration we have $1\L 2^{-30}x<1/(1-2^{1-k})$, +and the logarithm of $2^{30}x$ remains to be added to an accumulator +register called~$y$. Three auxiliary bits of accuracy are retained in~$y$ +during the calculation, and sixteen auxiliary bits to extend |y| are +kept in~|z| during the initial argument reduction. (We add +$100\cdot2^{16}=6553600$ to~|z| and subtract 100 from~|y| so that |z| will +not become negative; also, the actual amount subtracted from~|y| is~96, +not~100, because we want to add~4 for rounding before the final division by~8.) + +@c +static scaled mp_m_log (MP mp,scaled x) { + integer y,z; /* auxiliary registers */ + integer k; /* iteration counter */ + if ( x<=0 ) { + @; + } else { + y=1302456956+4-100; /* $14\times2^{27}\ln2\approx1302456956.421063$ */ + z=27595+6553600; /* and $2^{16}\times .421063\approx 27595$ */ + while ( xfraction_four+4 ) { + @; + } + return (y / 8); + } +} + +@ @= +{ + z=((x-1) / two_to_the(k))+1; /* $z=\lceil x/2^k\rceil$ */ + while ( x= +{ + print_err("Logarithm of "); +@.Logarithm...replaced by 0@> + mp_print_scaled(mp, x); mp_print(mp, " has been replaced by 0"); + help2("Since I don't take logs of non-positive numbers,", + "I'm zeroing this one. Proceed, with fingers crossed."); + mp_error(mp); + return 0; +} + +@ Conversely, the exponential routine calculates $\exp(x/2^8)$, +when |x| is |scaled|. The result is an integer approximation to +$2^{16}\exp(x/2^{24})$, when |x| is regarded as an integer. + +@c +static scaled mp_m_exp (MP mp,scaled x) { + quarterword k; /* loop control index */ + integer y,z; /* auxiliary registers */ + if ( x>174436200 ) { + /* $2^{24}\ln((2^{31}-1)/2^{16})\approx 174436199.51$ */ + mp->arith_error=true; + return el_gordo; + } else if ( x<-197694359 ) { + /* $2^{24}\ln(2^{-1}/2^{16})\approx-197694359.45$ */ + return 0; + } else { + if ( x<=0 ) { + z=-8*x; y=04000000; /* $y=2^{20}$ */ + } else { + if ( x<=127919879 ) { + z=1023359037-8*x; + /* $2^{27}\ln((2^{31}-1)/2^{20})\approx 1023359037.125$ */ + } else { + z=8*(174436200-x); /* |z| is always nonnegative */ + } + y=el_gordo; + }; + @; + if ( x<=127919879 ) + return ((y+8) / 16); + else + return y; + } +} + +@ The idea here is that subtracting |spec_log[k]| from |z| corresponds +to multiplying |y| by $1-2^{-k}$. + +A subtle point (which had to be checked) was that if $x=127919879$, the +value of~|y| will decrease so that |y+8| doesn't overflow. In fact, +$z$ will be 5 in this case, and |y| will decrease by~64 when |k=25| +and by~16 when |k=27|. + +@= +k=1; +while ( z>0 ) { + while ( z>=spec_log[k] ) { + z-=spec_log[k]; + y=y-1-((y-two_to_the(k-1)) / two_to_the(k)); + } + k++; +} + +@ The trigonometric subroutines use an auxiliary table such that +|spec_atan[k]| contains an approximation to the |angle| whose tangent +is~$1/2^k$. $\arctan2^{-k}$ times $2^{20}\cdot180/\pi$ + +@= +static const angle spec_atan[27] = { 0, 27855475, 14718068, 7471121, 3750058, +1876857, 938658, 469357, 234682, 117342, 58671, 29335, 14668, 7334, 3667, +1833, 917, 458, 229, 115, 57, 29, 14, 7, 4, 2, 1 }; + +@ Given integers |x| and |y|, not both zero, the |n_arg| function +returns the |angle| whose tangent points in the direction $(x,y)$. +This subroutine first determines the correct octant, then solves the +problem for |0<=y<=x|, then converts the result appropriately to +return an answer in the range |-one_eighty_deg<=@t$\theta$@><=one_eighty_deg|. +(The answer is |+one_eighty_deg| if |y=0| and |x<0|, but an answer of +|-one_eighty_deg| is possible if, for example, |y=-1| and $x=-2^{30}$.) + +The octants are represented in a ``Gray code,'' since that turns out +to be computationally simplest. + +@d negate_x 1 +@d negate_y 2 +@d switch_x_and_y 4 +@d first_octant 1 +@d second_octant (first_octant+switch_x_and_y) +@d third_octant (first_octant+switch_x_and_y+negate_x) +@d fourth_octant (first_octant+negate_x) +@d fifth_octant (first_octant+negate_x+negate_y) +@d sixth_octant (first_octant+switch_x_and_y+negate_x+negate_y) +@d seventh_octant (first_octant+switch_x_and_y+negate_y) +@d eighth_octant (first_octant+negate_y) + +@c +static angle mp_n_arg (MP mp,integer x, integer y) { + angle z; /* auxiliary register */ + integer t; /* temporary storage */ + quarterword k; /* loop counter */ + int octant; /* octant code */ + if ( x>=0 ) { + octant=first_octant; + } else { + negate(x); octant=first_octant+negate_x; + } + if ( y<0 ) { + negate(y); octant=octant+negate_y; + } + if ( x; + } else { + @; + @; + } +} + +@ @= +{ + print_err("angle(0,0) is taken as zero"); +@.angle(0,0)...zero@> + help2("The `angle' between two identical points is undefined.", + "I'm zeroing this one. Proceed, with fingers crossed."); + mp_error(mp); + return 0; +} + +@ @= +switch (octant) { +case first_octant: return z; +case second_octant: return (ninety_deg-z); +case third_octant: return (ninety_deg+z); +case fourth_octant: return (one_eighty_deg-z); +case fifth_octant: return (z-one_eighty_deg); +case sixth_octant: return (-z-ninety_deg); +case seventh_octant: return (z-ninety_deg); +case eighth_octant: return (-z); +}; /* there are no other cases */ +return 0 + +@ At this point we have |x>=y>=0|, and |x>0|. The numbers are scaled up +or down until $2^{28}\L x<2^{29}$, so that accurate fixed-point calculations +will be made. + +@= +while ( x>=fraction_two ) { + x=halfp(x); y=halfp(y); +} +z=0; +if ( y>0 ) { + while ( x; +} + +@ During the calculations of this section, variables |x| and~|y| +represent actual coordinates $(x,2^{-k}y)$. We will maintain the +condition |x>=y|, so that the tangent will be at most $2^{-k}$. +If $x<2y$, the tangent is greater than $2^{-k-1}$. The transformation +$(a,b)\mapsto(a+b\tan\phi,b-a\tan\phi)$ replaces $(a,b)$ by +coordinates whose angle has decreased by~$\phi$; in the special case +$a=x$, $b=2^{-k}y$, and $\tan\phi=2^{-k-1}$, this operation reduces +to the particularly simple iteration shown here. [Cf.~John E. Meggitt, +@^Meggitt, John E.@> +{\sl IBM Journal of Research and Development\/ \bf6} (1962), 210--226.] + +The initial value of |x| will be multiplied by at most +$(1+{1\over2})(1+{1\over8})(1+{1\over32})\cdots\approx 1.7584$; hence +there is no chance of integer overflow. + +@= +k=0; +do { + y+=y; k++; + if ( y>x ){ + z=z+spec_atan[k]; t=x; x=x+(y / two_to_the(k+k)); y=y-t; + }; +} while (k!=15); +do { + y+=y; k++; + if ( y>x ) { z=z+spec_atan[k]; y=y-x; }; +} while (k!=26) + +@ Conversely, the |n_sin_cos| routine takes an |angle| and produces the sine +and cosine of that angle. The results of this routine are +stored in global integer variables |n_sin| and |n_cos|. + +@= +fraction n_sin;fraction n_cos; /* results computed by |n_sin_cos| */ + +@ Given an integer |z| that is $2^{20}$ times an angle $\theta$ in degrees, +the purpose of |n_sin_cos(z)| is to set +|x=@t$r\cos\theta$@>| and |y=@t$r\sin\theta$@>| (approximately), +for some rather large number~|r|. The maximum of |x| and |y| +will be between $2^{28}$ and $2^{30}$, so that there will be hardly +any loss of accuracy. Then |x| and~|y| are divided by~|r|. + +@c +static void mp_n_sin_cos (MP mp,angle z) { /* computes a multiple of the sine + and cosine */ + quarterword k; /* loop control variable */ + int q; /* specifies the quadrant */ + fraction r; /* magnitude of |(x,y)| */ + integer x,y,t; /* temporary registers */ + while ( z<0 ) z=z+three_sixty_deg; + z=z % three_sixty_deg; /* now |0<=z; + @; + r=mp_pyth_add(mp, x,y); + mp->n_cos=mp_make_fraction(mp, x,r); + mp->n_sin=mp_make_fraction(mp, y,r); +} + +@ In this case the octants are numbered sequentially. + +@= +switch (q) { +case 0: break; +case 1: t=x; x=y; y=t; break; +case 2: t=x; x=-y; y=t; break; +case 3: negate(x); break; +case 4: negate(x); negate(y); break; +case 5: t=x; x=-y; y=-t; break; +case 6: t=x; x=y; y=-t; break; +case 7: negate(y); break; +} /* there are no other cases */ + +@ The main iteration of |n_sin_cos| is similar to that of |n_arg| but +applied in reverse. The values of |spec_atan[k]| decrease slowly enough +that this loop is guaranteed to terminate before the (nonexistent) value +|spec_atan[27]| would be required. + +@= +k=1; +while ( z>0 ){ + if ( z>=spec_atan[k] ) { + z=z-spec_atan[k]; t=x; + x=t+y / two_to_the(k); + y=y-t / two_to_the(k); + } + k++; +} +if ( y<0 ) y=0 /* this precaution may never be needed */ + +@ And now let's complete our collection of numeric utility routines +by considering random number generation. +\MP\ generates pseudo-random numbers with the additive scheme recommended +in Section 3.6 of {\sl The Art of Computer Programming}; however, the +results are random fractions between 0 and |fraction_one-1|, inclusive. + +There's an auxiliary array |randoms| that contains 55 pseudo-random +fractions. Using the recurrence $x_n=(x_{n-55}-x_{n-31})\bmod 2^{28}$, +we generate batches of 55 new $x_n$'s at a time by calling |new_randoms|. +The global variable |j_random| tells which element has most recently +been consumed. +The global variable |random_seed| was introduced in version 0.9, +for the sole reason of stressing the fact that the initial value of the +random seed is system-dependant. The initialization code below will initialize +this variable to |(internal[mp_time] div unity)+internal[mp_day]|, but this +is not good enough on modern fast machines that are capable of running +multiple MetaPost processes within the same second. +@^system dependencies@> + +@= +fraction randoms[55]; /* the last 55 random values generated */ +int j_random; /* the number of unused |randoms| */ + +@ @