summaryrefslogtreecommitdiff
path: root/Build/source/texk
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2010-04-04 13:55:46 +0000
committerTaco Hoekwater <taco@elvenkind.com>2010-04-04 13:55:46 +0000
commitf372862c42d234710b6057449b46818e63181c90 (patch)
treea9ebec66dd31ac37aed442502ebd1b9fe76245ec /Build/source/texk
parent2dad291ab056f30816e0aea61970f38033c2f6a5 (diff)
import luatex 0.60.0 (with small local changes, see luatexdir/ChangeLog)
and do an autoreconf git-svn-id: svn://tug.org/texlive/trunk@17680 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk')
-rw-r--r--Build/source/texk/web2c/ChangeLog7
-rw-r--r--Build/source/texk/web2c/Makefile.am2
-rw-r--r--Build/source/texk/web2c/Makefile.in3123
-rw-r--r--Build/source/texk/web2c/aclocal.m4889
-rw-r--r--Build/source/texk/web2c/c-auto.in22
-rwxr-xr-xBuild/source/texk/web2c/configure425
-rw-r--r--Build/source/texk/web2c/configure.ac4
-rw-r--r--Build/source/texk/web2c/doc/Makefile.in8
-rw-r--r--Build/source/texk/web2c/lib/Makefile.in8
-rw-r--r--Build/source/texk/web2c/luatexdir/NEWS638
-rw-r--r--Build/source/texk/web2c/luatexdir/README87
-rw-r--r--Build/source/texk/web2c/luatexdir/am/libluatex.am639
-rw-r--r--Build/source/texk/web2c/luatexdir/am/luafontforge.am6
-rw-r--r--Build/source/texk/web2c/luatexdir/am/luamisc.am3
-rw-r--r--Build/source/texk/web2c/luatexdir/am/luatangle.am30
-rw-r--r--Build/source/texk/web2c/luatexdir/am/luatex.am45
-rw-r--r--Build/source/texk/web2c/luatexdir/change-files.txt35
-rw-r--r--Build/source/texk/web2c/luatexdir/commands.h554
-rw-r--r--Build/source/texk/web2c/luatexdir/dvi/dvigen.h193
-rw-r--r--Build/source/texk/web2c/luatexdir/dvi/dvigen.w1420
-rw-r--r--Build/source/texk/web2c/luatexdir/font/dofont.c179
-rw-r--r--Build/source/texk/web2c/luatexdir/font/dofont.w147
-rw-r--r--Build/source/texk/web2c/luatexdir/font/luafont.w (renamed from Build/source/texk/web2c/luatexdir/font/luafont.c)694
-rw-r--r--Build/source/texk/web2c/luatexdir/font/luatexfont.h80
-rw-r--r--Build/source/texk/web2c/luatexdir/font/macnames.c313
-rw-r--r--Build/source/texk/web2c/luatexdir/font/mapfile.h106
-rw-r--r--Build/source/texk/web2c/luatexdir/font/mapfile.w (renamed from Build/source/texk/web2c/luatexdir/font/mapfile.c)493
-rw-r--r--Build/source/texk/web2c/luatexdir/font/pkin.w (renamed from Build/source/texk/web2c/luatexdir/font/pkin.c)203
-rw-r--r--Build/source/texk/web2c/luatexdir/font/sfnt.h8
-rw-r--r--Build/source/texk/web2c/luatexdir/font/sfnt.w (renamed from Build/source/texk/web2c/luatexdir/font/sfnt.c)311
-rw-r--r--Build/source/texk/web2c/luatexdir/font/subfont.txt103
-rw-r--r--Build/source/texk/web2c/luatexdir/font/subfont.w (renamed from Build/source/texk/web2c/luatexdir/font/subfont.c)112
-rw-r--r--Build/source/texk/web2c/luatexdir/font/texfont.h283
-rw-r--r--Build/source/texk/web2c/luatexdir/font/texfont.w (renamed from Build/source/texk/web2c/luatexdir/font/texfont.c)630
-rw-r--r--Build/source/texk/web2c/luatexdir/font/tfmofm.w (renamed from Build/source/texk/web2c/luatexdir/font/tfmofm.c)299
-rw-r--r--Build/source/texk/web2c/luatexdir/font/tounicode.w (renamed from Build/source/texk/web2c/luatexdir/font/tounicode.c)232
-rw-r--r--Build/source/texk/web2c/luatexdir/font/tt_glyf.w (renamed from Build/source/texk/web2c/luatexdir/font/tt_glyf.c)200
-rw-r--r--Build/source/texk/web2c/luatexdir/font/tt_table.w (renamed from Build/source/texk/web2c/luatexdir/font/tt_table.c)125
-rw-r--r--Build/source/texk/web2c/luatexdir/font/vfovf.w (renamed from Build/source/texk/web2c/luatexdir/font/vfovf.c)544
-rw-r--r--Build/source/texk/web2c/luatexdir/font/vfpacket.w (renamed from Build/source/texk/web2c/luatexdir/font/vfpacket.c)192
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writecff.h6
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writecff.w (renamed from Build/source/texk/web2c/luatexdir/font/writecff.c)858
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writeenc.c187
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writeenc.w161
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writefont.w (renamed from Build/source/texk/web2c/luatexdir/font/writefont.c)639
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writet1.w (renamed from Build/source/texk/web2c/luatexdir/font/writet1.c)750
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writet3.w (renamed from Build/source/texk/web2c/luatexdir/font/writet3.c)247
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writettf.h18
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writettf.w (renamed from Build/source/texk/web2c/luatexdir/font/writettf.c)866
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writetype0.c125
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writetype0.w123
-rw-r--r--Build/source/texk/web2c/luatexdir/font/writetype2.w (renamed from Build/source/texk/web2c/luatexdir/font/writetype2.c)327
-rwxr-xr-xBuild/source/texk/web2c/luatexdir/get_svnversion.sh13
-rwxr-xr-xBuild/source/texk/web2c/luatexdir/getluatexsvnversion.sh25
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.c81
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.h211
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.w34
-rw-r--r--Build/source/texk/web2c/luatexdir/image/image.h94
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc1103
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.h10
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.c959
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.h57
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.w823
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejbig2.h6
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejbig2.w (renamed from Build/source/texk/web2c/luatexdir/image/writejbig2.c)257
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejpg.h6
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejpg.w (renamed from Build/source/texk/web2c/luatexdir/image/writejpg.c)111
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writepng.h8
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writepng.w (renamed from Build/source/texk/web2c/luatexdir/image/writepng.c)406
-rw-r--r--Build/source/texk/web2c/luatexdir/inc-epdf.h8
-rw-r--r--Build/source/texk/web2c/luatexdir/inc-extra.h4
-rw-r--r--Build/source/texk/web2c/luatexdir/inc-vfovf.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/hnjalloc.c74
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/hnjalloc.h10
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/hnjalloc.w66
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/hyphen.c850
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/hyphen.h (renamed from Build/source/texk/web2c/luatexdir/hyphen.h)1
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/hyphen.w857
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/texlang.h82
-rw-r--r--Build/source/texk/web2c/luatexdir/lang/texlang.w (renamed from Build/source/texk/web2c/luatexdir/lang/texlang.c)368
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c49
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lepdflib.cc58
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lfontlib.c86
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/limglib.c195
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/liolib.c21
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lkpselib.c427
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/llanglib.c60
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/llualib.c92
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lnodelib.c701
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/loslibext.c147
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lpdflib.c754
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lstatslib.c194
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/ltexiolib.c47
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/ltexlib.c1434
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/ltokenlib.c81
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luagen.h27
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luagen.w55
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luainit.w (renamed from Build/source/texk/web2c/luatexdir/lua/luainit.c)455
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luanode.w (renamed from Build/source/texk/web2c/luatexdir/lua/luanode.c)128
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luastuff.w (renamed from Build/source/texk/web2c/luatexdir/lua/luastuff.c)227
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatex-api.h (renamed from Build/source/texk/web2c/luatexdir/luatex-api.h)109
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatex.c364
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatoken.w (renamed from Build/source/texk/web2c/luatexdir/lua/luatoken.c)319
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/texluac.w (renamed from Build/source/texk/web2c/luatexdir/lua/texluac.c)88
-rw-r--r--Build/source/texk/web2c/luatexdir/lua51/lcoco.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/lua51/loadlib.c23
-rw-r--r--Build/source/texk/web2c/luatexdir/lua51/luaconf.h35
-rw-r--r--Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c60
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/Makefile.in2
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/cjk.c30
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c175
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ucharmap.c276
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c8
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c13
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c1946
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c166
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c5
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c701
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c13
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h11
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/chardata.h4
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/ustring.h4
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/src/ffdummies.c324
-rw-r--r--Build/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c4196
-rw-r--r--Build/source/texk/web2c/luatexdir/luamd5/luamd5.h (renamed from Build/source/texk/web2c/luatexdir/luamd5/md5.h)4
-rw-r--r--Build/source/texk/web2c/luatexdir/luamd5/md5.c5
-rw-r--r--Build/source/texk/web2c/luatexdir/luamd5/md5_lua.c38
-rw-r--r--Build/source/texk/web2c/luatexdir/luamd5/md5lib.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/luatangle.ch508
-rwxr-xr-xBuild/source/texk/web2c/luatexdir/luatangle.test10
-rw-r--r--Build/source/texk/web2c/luatexdir/luatangle.web3329
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex.c1063
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex.ch2176
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex.defines900
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex.h161
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex.mk158
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex.web31941
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex_svnversion.h1
-rw-r--r--Build/source/texk/web2c/luatexdir/makecpool.c93
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/ocp.h52
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/ocp.w201
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/ocplist.h91
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/ocplist.w357
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/readocp.h61
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/readocp.w273
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/runocp.h60
-rw-r--r--Build/source/texk/web2c/luatexdir/ocp/runocp.w1069
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pagetree.h8
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pagetree.w (renamed from Build/source/texk/web2c/luatexdir/pdf/pagetree.c)155
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfaction.h78
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfaction.w207
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfannot.h37
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfannot.w99
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h44
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w386
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfdest.h66
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfdest.w417
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdffont.h48
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdffont.w495
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfgen.h239
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfgen.w2479
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h30
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w222
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfimage.h28
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfimage.w156
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflink.h39
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflink.w166
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflistout.h50
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflistout.w1139
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h34
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w154
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfobj.h66
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfobj.w214
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h28
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w240
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfpage.c561
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfpage.h67
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfpage.w292
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfrule.h27
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfrule.w70
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h37
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w88
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h52
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w238
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h30
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w332
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdftables.h136
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdftables.w456
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfthread.h71
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfthread.w290
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdftypes.h291
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfxform.h56
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfxform.w128
-rw-r--r--Build/source/texk/web2c/luatexdir/ptexlib.h590
-rw-r--r--Build/source/texk/web2c/luatexdir/ptexmac.h172
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/align.h55
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/align.w1153
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/arithmetic.h81
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/arithmetic.w734
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/buildpage.h75
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/buildpage.w1057
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/commands.h355
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/commands.w1223
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/conditional.h82
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/conditional.w539
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/directions.h347
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/directions.w202
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/dumpdata.h115
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/dumpdata.w527
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/equivalents.h560
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/equivalents.w1171
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/errors.h102
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/errors.w625
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/expand.h102
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/expand.w789
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/extensions.h118
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/extensions.w1217
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/filename.c353
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/filename.h34
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/filename.w349
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/inputstack.h353
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/inputstack.w800
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/linebreak.h106
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/linebreak.w (renamed from Build/source/texk/web2c/luatexdir/tex/linebreak.c)767
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mainbody.h252
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mainbody.w745
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.h196
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.w3610
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mathcodes.h76
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mathcodes.w (renamed from Build/source/texk/web2c/luatexdir/mathcodes.c)171
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/memoryword.h129
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/memoryword.w58
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mlist.h (renamed from Build/source/texk/web2c/luatexdir/luatexextra.in)39
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mlist.w (renamed from Build/source/texk/web2c/luatexdir/tex/mlist.c)1543
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/nesting.h71
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/nesting.w447
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/packaging.h150
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/packaging.w1789
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/postlinebreak.h59
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/postlinebreak.w (renamed from Build/source/texk/web2c/luatexdir/tex/postlinebreak.c)168
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/primitive.h (renamed from Build/source/texk/web2c/luatexdir/primitive.h)40
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/primitive.w (renamed from Build/source/texk/web2c/luatexdir/tex/primitive.c)366
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/printing.h124
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/printing.w984
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/scanning.h111
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/scanning.w2641
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/stringpool.h146
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/stringpool.w492
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texdeffont.h31
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texdeffont.w (renamed from Build/source/texk/web2c/luatexdir/tex/texdeffont.c)90
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texfileio.h144
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texfileio.w1368
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texmath.h (renamed from Build/source/texk/web2c/luatexdir/texmath.h)25
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texmath.w (renamed from Build/source/texk/web2c/luatexdir/tex/math.c)925
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.h (renamed from Build/source/texk/web2c/luatexdir/nodes.h)208
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.w (renamed from Build/source/texk/web2c/luatexdir/tex/texnodes.c)1083
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texpdf.c186
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textcodes.h46
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textcodes.w (renamed from Build/source/texk/web2c/luatexdir/textcodes.c)82
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textoken.c1173
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textoken.h179
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textoken.w2410
-rw-r--r--Build/source/texk/web2c/luatexdir/tokens.h86
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/avl.c7
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/avl.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/avlstuff.c181
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/avlstuff.h5
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/avlstuff.w63
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/managed-sa.h (renamed from Build/source/texk/web2c/luatexdir/managed-sa.h)25
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/managed-sa.w (renamed from Build/source/texk/web2c/luatexdir/managed-sa.c)139
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/synctex-common.h51
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/synctex-luatex.h99
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/synctex.c1661
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/synctex.h48
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/utils.c1809
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/utils.h69
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/utils.w465
-rw-r--r--Build/source/texk/web2c/luatexdir/utils/writezip.c99
-rw-r--r--Build/source/texk/web2c/man/Makefile.in8
-rw-r--r--Build/source/texk/web2c/omegafonts/Makefile.in8
-rw-r--r--Build/source/texk/web2c/otps/Makefile.in8
-rw-r--r--Build/source/texk/web2c/web2c/Makefile.in13
-rw-r--r--Build/source/texk/web2c/web2c/aclocal.m46
-rwxr-xr-xBuild/source/texk/web2c/web2c/configure6
-rw-r--r--Build/source/texk/web2c/window/Makefile.in8
288 files changed, 69737 insertions, 63681 deletions
diff --git a/Build/source/texk/web2c/ChangeLog b/Build/source/texk/web2c/ChangeLog
index 73fe188aa29..bd758d091be 100644
--- a/Build/source/texk/web2c/ChangeLog
+++ b/Build/source/texk/web2c/ChangeLog
@@ -1,3 +1,10 @@
+2010-04-04 Taco Hoekwater <taco@luatex.org>
+
+ * configure.ac: Append LT_LIB_DLLOAD to the end,
+ needed for the current 0.60.0 luatex build system.
+ * Makefile.am: Comment out the luatexdir/am/luatangle.am line
+ * autoreconf
+
2010-03-24 Peter Breitenlohner <peb@mppmu.mpg.de>
* configure.ac: Check if dlopen() requires `-ldl'.
diff --git a/Build/source/texk/web2c/Makefile.am b/Build/source/texk/web2c/Makefile.am
index e6de8dbd64b..e6abcf2fdbd 100644
--- a/Build/source/texk/web2c/Makefile.am
+++ b/Build/source/texk/web2c/Makefile.am
@@ -167,7 +167,7 @@ include $(srcdir)/pdftexdir/am/pdftosrc.am
## luaTeX
include $(srcdir)/luatexdir/am/luatex.am
-include $(srcdir)/luatexdir/am/luatangle.am
+## include $(srcdir)/luatexdir/am/luatangle.am
include $(srcdir)/luatexdir/am/liblua51.am
include $(srcdir)/luatexdir/am/luasocket.am
include $(srcdir)/luatexdir/am/luamisc.am
diff --git a/Build/source/texk/web2c/Makefile.in b/Build/source/texk/web2c/Makefile.in
index 4088baafdc8..19e5377943f 100644
--- a/Build/source/texk/web2c/Makefile.in
+++ b/Build/source/texk/web2c/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -37,8 +37,7 @@ host_triplet = @host@
EXTRA_PROGRAMS = $(am__EXEEXT_1) tex$(EXEEXT) mf$(EXEEXT) \
mf-nowin$(EXEEXT) mpost$(EXEEXT) etex$(EXEEXT) pdftex$(EXEEXT) \
ttf2afm$(EXEEXT) pdftosrc$(EXEEXT) luatex$(EXEEXT) \
- luatangle$(EXEEXT) xetex$(EXEEXT) $(am__EXEEXT_4) \
- aleph$(EXEEXT)
+ xetex$(EXEEXT) $(am__EXEEXT_4) aleph$(EXEEXT)
bin_PROGRAMS = tangle$(EXEEXT) ctangle$(EXEEXT) $(am__EXEEXT_5) \
ctie$(EXEEXT) cweave$(EXEEXT) tie$(EXEEXT) $(am__EXEEXT_6) \
$(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \
@@ -51,8 +50,7 @@ check_PROGRAMS = $(am__EXEEXT_17) $(am__EXEEXT_18) $(am__EXEEXT_19) \
TESTS = tangle.test $(am__EXEEXT_24) ctiedir/ctie.test \
cwebdir/cweave.test tiedir/tie.test $(am__append_4) \
$(am__append_10) $(am__append_13) $(am__append_17) \
- $(am__append_23) $(am__append_39) $(am__append_40) \
- libmd5/md5.test
+ $(am__append_38) $(am__append_39) libmd5/md5.test
DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \
$(srcdir)/../../build-aux/config.guess \
$(srcdir)/../../build-aux/config.sub \
@@ -69,7 +67,6 @@ DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \
$(srcdir)/luatexdir/am/luafontforge.am \
$(srcdir)/luatexdir/am/luamisc.am \
$(srcdir)/luatexdir/am/luasocket.am \
- $(srcdir)/luatexdir/am/luatangle.am \
$(srcdir)/luatexdir/am/luatex.am \
$(srcdir)/mplibdir/am/libmplib.am \
$(srcdir)/mplibdir/am/mplib.am \
@@ -111,25 +108,24 @@ DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \
@MINGW32_TRUE@ pdftexdir/regex/regex.c \
@MINGW32_TRUE@ pdftexdir/regex/regex.h
-@LUATEX_TRUE@am__append_22 = luatex luatangle
-@LUATEX_TRUE@am__append_23 = luatexdir/luatangle.test
-@MINGW32_FALSE@am__append_24 = -DLUA_USE_POSIX
-@XETEX_TRUE@am__append_25 = xetex
-@XETEX_MACOSX_TRUE@am__append_26 = -DXETEX_MAC
-@XETEX_MACOSX_TRUE@am__append_27 = libxetexmm.a
-@XETEX_MACOSX_FALSE@am__append_28 = -DXETEX_OTHER $(XPDF_INCLUDES) \
+@LUATEX_TRUE@am__append_22 = luatex
+@MINGW32_FALSE@am__append_23 = -DLUA_USE_POSIX
+@XETEX_TRUE@am__append_24 = xetex
+@XETEX_MACOSX_TRUE@am__append_25 = -DXETEX_MAC
+@XETEX_MACOSX_TRUE@am__append_26 = libxetexmm.a
+@XETEX_MACOSX_FALSE@am__append_27 = -DXETEX_OTHER $(XPDF_INCLUDES) \
@XETEX_MACOSX_FALSE@ $(LIBPNG_INCLUDES) $(FONTCONFIG_INCLUDES)
-@XETEX_MACOSX_FALSE@am__append_29 = $(XPDF_LIBS) $(LIBPNG_LIBS) $(FONTCONFIG_LIBS)
-@XETEX_MACOSX_FALSE@am__append_30 = $(XPDF_DEPEND) $(LIBPNG_DEPEND)
-@XETEX_GRAPHITE_TRUE@am__append_31 = -DXETEX_GRAPHITE $(GRAPHITE_INCLUDES)
-@XETEX_GRAPHITE_TRUE@am__append_32 = $(GRAPHITE_LIBS)
-@XETEX_GRAPHITE_TRUE@am__append_33 = $(GRAPHITE_DEPEND)
-@XETEX_MACOSX_TRUE@am__append_34 = \
+@XETEX_MACOSX_FALSE@am__append_28 = $(XPDF_LIBS) $(LIBPNG_LIBS) $(FONTCONFIG_LIBS)
+@XETEX_MACOSX_FALSE@am__append_29 = $(XPDF_DEPEND) $(LIBPNG_DEPEND)
+@XETEX_GRAPHITE_TRUE@am__append_30 = -DXETEX_GRAPHITE $(GRAPHITE_INCLUDES)
+@XETEX_GRAPHITE_TRUE@am__append_31 = $(GRAPHITE_LIBS)
+@XETEX_GRAPHITE_TRUE@am__append_32 = $(GRAPHITE_DEPEND)
+@XETEX_MACOSX_TRUE@am__append_33 = \
@XETEX_MACOSX_TRUE@ xetexdir/XeTeXFontInst_Mac.cpp \
@XETEX_MACOSX_TRUE@ xetexdir/XeTeXFontInst_Mac.h \
@XETEX_MACOSX_TRUE@ xetexdir/XeTeX_mac.c
-@XETEX_MACOSX_FALSE@am__append_35 = \
+@XETEX_MACOSX_FALSE@am__append_34 = \
@XETEX_MACOSX_FALSE@ xetexdir/XeTeXFontMgr_FC.cpp \
@XETEX_MACOSX_FALSE@ xetexdir/XeTeXFontMgr_FC.h \
@XETEX_MACOSX_FALSE@ xetexdir/XeTeX_pic.c \
@@ -146,38 +142,38 @@ DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \
@XETEX_MACOSX_FALSE@ xetexdir/pngimage.c \
@XETEX_MACOSX_FALSE@ xetexdir/pngimage.h
-@XETEX_GRAPHITE_TRUE@am__append_36 = \
+@XETEX_GRAPHITE_TRUE@am__append_35 = \
@XETEX_GRAPHITE_TRUE@ xetexdir/XeTeXGrLayout.cpp \
@XETEX_GRAPHITE_TRUE@ xetexdir/XeTeXGrLayout.h
-@OTANGLE_TRUE@am__append_37 = $(omegaware_tools)
-@OMFONTS_FALSE@@OTANGLE_TRUE@am__append_38 = $(omegaware_font_tools)
-@OTANGLE_TRUE@am__append_39 = $(OTANGLE_tests)
-@OMFONTS_FALSE@@OTANGLE_TRUE@am__append_40 = $(OMFONTS_tests)
-@OTANGLE_TRUE@am__append_41 = pltotf tftopl
-@ALEPH_TRUE@am__append_42 = aleph
-@TEX_SYNCTEX_TRUE@am__append_43 = -I$(srcdir)/synctexdir \
+@OTANGLE_TRUE@am__append_36 = $(omegaware_tools)
+@OMFONTS_FALSE@@OTANGLE_TRUE@am__append_37 = $(omegaware_font_tools)
+@OTANGLE_TRUE@am__append_38 = $(OTANGLE_tests)
+@OMFONTS_FALSE@@OTANGLE_TRUE@am__append_39 = $(OMFONTS_tests)
+@OTANGLE_TRUE@am__append_40 = pltotf tftopl
+@ALEPH_TRUE@am__append_41 = aleph
+@TEX_SYNCTEX_TRUE@am__append_42 = -I$(srcdir)/synctexdir \
@TEX_SYNCTEX_TRUE@ $(ZLIB_INCLUDES) -D__SyncTeX__
-@TEX_SYNCTEX_TRUE@am__append_44 = $(ZLIB_LIBS)
-@TEX_SYNCTEX_TRUE@am__append_45 = $(ZLIB_DEPEND)
-@TEX_SYNCTEX_TRUE@am__append_46 = \
+@TEX_SYNCTEX_TRUE@am__append_43 = $(ZLIB_LIBS)
+@TEX_SYNCTEX_TRUE@am__append_44 = $(ZLIB_DEPEND)
+@TEX_SYNCTEX_TRUE@am__append_45 = \
@TEX_SYNCTEX_TRUE@ synctex.c
-@ETEX_SYNCTEX_TRUE@am__append_47 = -I$(srcdir)/synctexdir \
+@ETEX_SYNCTEX_TRUE@am__append_46 = -I$(srcdir)/synctexdir \
@ETEX_SYNCTEX_TRUE@ $(ZLIB_INCLUDES) -D__SyncTeX__
-@ETEX_SYNCTEX_TRUE@am__append_48 = $(ZLIB_LIBS)
-@ETEX_SYNCTEX_TRUE@am__append_49 = $(ZLIB_DEPEND)
-@ETEX_SYNCTEX_TRUE@am__append_50 = \
+@ETEX_SYNCTEX_TRUE@am__append_47 = $(ZLIB_LIBS)
+@ETEX_SYNCTEX_TRUE@am__append_48 = $(ZLIB_DEPEND)
+@ETEX_SYNCTEX_TRUE@am__append_49 = \
@ETEX_SYNCTEX_TRUE@ synctex-e.c
-@PDFTEX_SYNCTEX_TRUE@am__append_51 = -I$(srcdir)/synctexdir \
+@PDFTEX_SYNCTEX_TRUE@am__append_50 = -I$(srcdir)/synctexdir \
@PDFTEX_SYNCTEX_TRUE@ -D__SyncTeX__
-@PDFTEX_SYNCTEX_TRUE@am__append_52 = \
+@PDFTEX_SYNCTEX_TRUE@am__append_51 = \
@PDFTEX_SYNCTEX_TRUE@ synctex-pdf.c
-@XETEX_SYNCTEX_TRUE@am__append_53 = -I$(srcdir)/synctexdir \
+@XETEX_SYNCTEX_TRUE@am__append_52 = -I$(srcdir)/synctexdir \
@XETEX_SYNCTEX_TRUE@ -D__SyncTeX__
-@XETEX_SYNCTEX_TRUE@am__append_54 = \
+@XETEX_SYNCTEX_TRUE@am__append_53 = \
@XETEX_SYNCTEX_TRUE@ synctex-xe.c
subdir = .
@@ -223,27 +219,25 @@ ARFLAGS = cru
libff_a_AR = $(AR) $(ARFLAGS)
libff_a_LIBADD =
am_libff_a_OBJECTS = libff_a-ArabicForms.$(OBJEXT) \
- libff_a-alphabet.$(OBJEXT) libff_a-backtrns.$(OBJEXT) \
- libff_a-char.$(OBJEXT) libff_a-cjk.$(OBJEXT) \
- libff_a-dump.$(OBJEXT) libff_a-gwwiconv.$(OBJEXT) \
+ libff_a-alphabet.$(OBJEXT) libff_a-char.$(OBJEXT) \
+ libff_a-cjk.$(OBJEXT) libff_a-gwwiconv.$(OBJEXT) \
libff_a-memory.$(OBJEXT) libff_a-ucharmap.$(OBJEXT) \
- libff_a-unialt.$(OBJEXT) libff_a-ustring.$(OBJEXT) \
- libff_a-utype.$(OBJEXT) libff_a-autohint.$(OBJEXT) \
- libff_a-clipnoui.$(OBJEXT) libff_a-cvundoes.$(OBJEXT) \
- libff_a-dumppfa.$(OBJEXT) libff_a-encoding.$(OBJEXT) \
- libff_a-featurefile.$(OBJEXT) libff_a-fontviewbase.$(OBJEXT) \
- libff_a-fvcomposit.$(OBJEXT) libff_a-fvfonts.$(OBJEXT) \
- libff_a-lookups.$(OBJEXT) libff_a-macbinary.$(OBJEXT) \
- libff_a-macenc.$(OBJEXT) libff_a-mathconstants.$(OBJEXT) \
- libff_a-mm.$(OBJEXT) libff_a-namelist.$(OBJEXT) \
- libff_a-noprefs.$(OBJEXT) libff_a-nouiutil.$(OBJEXT) \
- libff_a-parsepfa.$(OBJEXT) libff_a-parsettf.$(OBJEXT) \
- libff_a-parsettfatt.$(OBJEXT) libff_a-parsettfvar.$(OBJEXT) \
- libff_a-psread.$(OBJEXT) libff_a-pua.$(OBJEXT) \
- libff_a-python.$(OBJEXT) libff_a-sfd1.$(OBJEXT) \
- libff_a-splinechar.$(OBJEXT) libff_a-splinefill.$(OBJEXT) \
- libff_a-splinefont.$(OBJEXT) libff_a-splineorder2.$(OBJEXT) \
- libff_a-splineoverlap.$(OBJEXT) \
+ libff_a-ustring.$(OBJEXT) libff_a-utype.$(OBJEXT) \
+ libff_a-autohint.$(OBJEXT) libff_a-clipnoui.$(OBJEXT) \
+ libff_a-cvundoes.$(OBJEXT) libff_a-dumppfa.$(OBJEXT) \
+ libff_a-encoding.$(OBJEXT) libff_a-featurefile.$(OBJEXT) \
+ libff_a-fontviewbase.$(OBJEXT) libff_a-fvcomposit.$(OBJEXT) \
+ libff_a-fvfonts.$(OBJEXT) libff_a-lookups.$(OBJEXT) \
+ libff_a-macbinary.$(OBJEXT) libff_a-macenc.$(OBJEXT) \
+ libff_a-mathconstants.$(OBJEXT) libff_a-mm.$(OBJEXT) \
+ libff_a-namelist.$(OBJEXT) libff_a-noprefs.$(OBJEXT) \
+ libff_a-nouiutil.$(OBJEXT) libff_a-parsepfa.$(OBJEXT) \
+ libff_a-parsettf.$(OBJEXT) libff_a-parsettfatt.$(OBJEXT) \
+ libff_a-parsettfvar.$(OBJEXT) libff_a-psread.$(OBJEXT) \
+ libff_a-pua.$(OBJEXT) libff_a-python.$(OBJEXT) \
+ libff_a-sfd1.$(OBJEXT) libff_a-splinechar.$(OBJEXT) \
+ libff_a-splinefill.$(OBJEXT) libff_a-splinefont.$(OBJEXT) \
+ libff_a-splineorder2.$(OBJEXT) libff_a-splineoverlap.$(OBJEXT) \
libff_a-splinerefigure.$(OBJEXT) libff_a-splinesave.$(OBJEXT) \
libff_a-splinesaveafm.$(OBJEXT) libff_a-splinestroke.$(OBJEXT) \
libff_a-splineutil.$(OBJEXT) libff_a-splineutil2.$(OBJEXT) \
@@ -275,7 +269,8 @@ libluamisc_a_AR = $(AR) $(ARFLAGS)
libluamisc_a_LIBADD =
am_libluamisc_a_OBJECTS = libluamisc_a-lfs.$(OBJEXT) \
libluamisc_a-md5.$(OBJEXT) libluamisc_a-md5lib.$(OBJEXT) \
- libluamisc_a-lpeg.$(OBJEXT) libluamisc_a-clocks.$(OBJEXT) \
+ libluamisc_a-md5_lua.$(OBJEXT) libluamisc_a-lpeg.$(OBJEXT) \
+ libluamisc_a-clocks.$(OBJEXT) \
libluamisc_a-core_profiler.$(OBJEXT) \
libluamisc_a-function_meter.$(OBJEXT) \
libluamisc_a-stack.$(OBJEXT) \
@@ -298,67 +293,163 @@ am_libluasocket_a_OBJECTS = libluasocket_a-auxiliar.$(OBJEXT) \
libluasocket_a_OBJECTS = $(am_libluasocket_a_OBJECTS)
libluatex_a_AR = $(AR) $(ARFLAGS)
libluatex_a_LIBADD =
-am_libluatex_a_OBJECTS = libluatex_a-dofont.$(OBJEXT) \
- libluatex_a-luafont.$(OBJEXT) libluatex_a-mapfile.$(OBJEXT) \
- libluatex_a-pkin.$(OBJEXT) libluatex_a-sfnt.$(OBJEXT) \
- libluatex_a-subfont.$(OBJEXT) libluatex_a-texfont.$(OBJEXT) \
- libluatex_a-tfmofm.$(OBJEXT) libluatex_a-tounicode.$(OBJEXT) \
- libluatex_a-tt_glyf.$(OBJEXT) libluatex_a-tt_table.$(OBJEXT) \
- libluatex_a-vfovf.$(OBJEXT) libluatex_a-vfpacket.$(OBJEXT) \
- libluatex_a-writecff.$(OBJEXT) libluatex_a-writeenc.$(OBJEXT) \
- libluatex_a-writefont.$(OBJEXT) libluatex_a-writet1.$(OBJEXT) \
- libluatex_a-writet3.$(OBJEXT) libluatex_a-writettf.$(OBJEXT) \
+am__objects_1 = libluatex_a-dvigen.$(OBJEXT) \
+ libluatex_a-dofont.$(OBJEXT) libluatex_a-luafont.$(OBJEXT) \
+ libluatex_a-mapfile.$(OBJEXT) libluatex_a-pkin.$(OBJEXT) \
+ libluatex_a-sfnt.$(OBJEXT) libluatex_a-subfont.$(OBJEXT) \
+ libluatex_a-texfont.$(OBJEXT) libluatex_a-tfmofm.$(OBJEXT) \
+ libluatex_a-tounicode.$(OBJEXT) libluatex_a-tt_glyf.$(OBJEXT) \
+ libluatex_a-tt_table.$(OBJEXT) libluatex_a-vfovf.$(OBJEXT) \
+ libluatex_a-vfpacket.$(OBJEXT) libluatex_a-writecff.$(OBJEXT) \
+ libluatex_a-writeenc.$(OBJEXT) libluatex_a-writefont.$(OBJEXT) \
+ libluatex_a-writet1.$(OBJEXT) libluatex_a-writet3.$(OBJEXT) \
+ libluatex_a-writettf.$(OBJEXT) \
libluatex_a-writetype0.$(OBJEXT) \
libluatex_a-writetype2.$(OBJEXT) libluatex_a-epdf.$(OBJEXT) \
- libluatex_a-pdftoepdf.$(OBJEXT) libluatex_a-writeimg.$(OBJEXT) \
+ libluatex_a-writeimg.$(OBJEXT) \
libluatex_a-writejbig2.$(OBJEXT) \
libluatex_a-writejpg.$(OBJEXT) libluatex_a-writepng.$(OBJEXT) \
- libluatex_a-hnjalloc.$(OBJEXT) libluatex_a-hyphen.$(OBJEXT) \
- libluatex_a-texlang.$(OBJEXT) \
+ libluatex_a-luagen.$(OBJEXT) libluatex_a-luainit.$(OBJEXT) \
+ libluatex_a-luanode.$(OBJEXT) libluatex_a-luastuff.$(OBJEXT) \
+ libluatex_a-luatoken.$(OBJEXT) libluatex_a-texluac.$(OBJEXT) \
+ libluatex_a-ocp.$(OBJEXT) libluatex_a-ocplist.$(OBJEXT) \
+ libluatex_a-readocp.$(OBJEXT) libluatex_a-runocp.$(OBJEXT) \
+ libluatex_a-texlang.$(OBJEXT) libluatex_a-hyphen.$(OBJEXT) \
+ libluatex_a-hnjalloc.$(OBJEXT) libluatex_a-pagetree.$(OBJEXT) \
+ libluatex_a-pdfaction.$(OBJEXT) libluatex_a-pdfannot.$(OBJEXT) \
+ libluatex_a-pdfcolorstack.$(OBJEXT) \
+ libluatex_a-pdfdest.$(OBJEXT) libluatex_a-pdffont.$(OBJEXT) \
+ libluatex_a-pdfgen.$(OBJEXT) libluatex_a-pdfglyph.$(OBJEXT) \
+ libluatex_a-pdfimage.$(OBJEXT) libluatex_a-pdflink.$(OBJEXT) \
+ libluatex_a-pdflistout.$(OBJEXT) \
+ libluatex_a-pdfliteral.$(OBJEXT) libluatex_a-pdfobj.$(OBJEXT) \
+ libluatex_a-pdfoutline.$(OBJEXT) libluatex_a-pdfpage.$(OBJEXT) \
+ libluatex_a-pdfrule.$(OBJEXT) \
+ libluatex_a-pdfsaverestore.$(OBJEXT) \
+ libluatex_a-pdfsetmatrix.$(OBJEXT) \
+ libluatex_a-pdfshipout.$(OBJEXT) \
+ libluatex_a-pdftables.$(OBJEXT) \
+ libluatex_a-pdfthread.$(OBJEXT) libluatex_a-pdfxform.$(OBJEXT) \
+ libluatex_a-align.$(OBJEXT) libluatex_a-dumpdata.$(OBJEXT) \
+ libluatex_a-expand.$(OBJEXT) libluatex_a-inputstack.$(OBJEXT) \
+ libluatex_a-maincontrol.$(OBJEXT) libluatex_a-mlist.$(OBJEXT) \
+ libluatex_a-postlinebreak.$(OBJEXT) \
+ libluatex_a-scanning.$(OBJEXT) \
+ libluatex_a-texdeffont.$(OBJEXT) \
+ libluatex_a-texnodes.$(OBJEXT) \
+ libluatex_a-arithmetic.$(OBJEXT) \
+ libluatex_a-conditional.$(OBJEXT) \
+ libluatex_a-equivalents.$(OBJEXT) \
+ libluatex_a-extensions.$(OBJEXT) \
+ libluatex_a-commands.$(OBJEXT) libluatex_a-linebreak.$(OBJEXT) \
+ libluatex_a-mathcodes.$(OBJEXT) libluatex_a-nesting.$(OBJEXT) \
+ libluatex_a-primitive.$(OBJEXT) \
+ libluatex_a-texfileio.$(OBJEXT) \
+ libluatex_a-textcodes.$(OBJEXT) \
+ libluatex_a-buildpage.$(OBJEXT) \
+ libluatex_a-directions.$(OBJEXT) libluatex_a-errors.$(OBJEXT) \
+ libluatex_a-filename.$(OBJEXT) libluatex_a-mainbody.$(OBJEXT) \
+ libluatex_a-memoryword.$(OBJEXT) \
+ libluatex_a-packaging.$(OBJEXT) libluatex_a-printing.$(OBJEXT) \
+ libluatex_a-stringpool.$(OBJEXT) libluatex_a-texmath.$(OBJEXT) \
+ libluatex_a-textoken.$(OBJEXT) libluatex_a-utils.$(OBJEXT) \
+ libluatex_a-avlstuff.$(OBJEXT) \
+ libluatex_a-managed-sa.$(OBJEXT)
+am_libluatex_a_OBJECTS = libluatex_a-pdftoepdf.$(OBJEXT) \
libluatex_a-lcallbacklib.$(OBJEXT) \
libluatex_a-lfontlib.$(OBJEXT) libluatex_a-limglib.$(OBJEXT) \
- libluatex_a-lkpselib.$(OBJEXT) libluatex_a-llanglib.$(OBJEXT) \
- libluatex_a-llualib.$(OBJEXT) libluatex_a-lnodelib.$(OBJEXT) \
- libluatex_a-loslibext.$(OBJEXT) libluatex_a-liolib.$(OBJEXT) \
- libluatex_a-lpdflib.$(OBJEXT) libluatex_a-lstatslib.$(OBJEXT) \
+ libluatex_a-lepdflib.$(OBJEXT) libluatex_a-lkpselib.$(OBJEXT) \
+ libluatex_a-llanglib.$(OBJEXT) libluatex_a-llualib.$(OBJEXT) \
+ libluatex_a-lnodelib.$(OBJEXT) libluatex_a-loslibext.$(OBJEXT) \
+ libluatex_a-liolib.$(OBJEXT) libluatex_a-lpdflib.$(OBJEXT) \
+ libluatex_a-lstatslib.$(OBJEXT) \
libluatex_a-ltexiolib.$(OBJEXT) libluatex_a-ltexlib.$(OBJEXT) \
- libluatex_a-ltokenlib.$(OBJEXT) libluatex_a-luainit.$(OBJEXT) \
+ libluatex_a-ltokenlib.$(OBJEXT) libluatex_a-avl.$(OBJEXT) \
+ libluatex_a-synctex.$(OBJEXT) $(am__objects_1) \
+ libluatex_a-lmplib.$(OBJEXT)
+nodist_libluatex_a_OBJECTS = libluatex_a-dvigen.$(OBJEXT) \
+ libluatex_a-dofont.$(OBJEXT) libluatex_a-luafont.$(OBJEXT) \
+ libluatex_a-mapfile.$(OBJEXT) libluatex_a-pkin.$(OBJEXT) \
+ libluatex_a-sfnt.$(OBJEXT) libluatex_a-subfont.$(OBJEXT) \
+ libluatex_a-texfont.$(OBJEXT) libluatex_a-tfmofm.$(OBJEXT) \
+ libluatex_a-tounicode.$(OBJEXT) libluatex_a-tt_glyf.$(OBJEXT) \
+ libluatex_a-tt_table.$(OBJEXT) libluatex_a-vfovf.$(OBJEXT) \
+ libluatex_a-vfpacket.$(OBJEXT) libluatex_a-writecff.$(OBJEXT) \
+ libluatex_a-writeenc.$(OBJEXT) libluatex_a-writefont.$(OBJEXT) \
+ libluatex_a-writet1.$(OBJEXT) libluatex_a-writet3.$(OBJEXT) \
+ libluatex_a-writettf.$(OBJEXT) \
+ libluatex_a-writetype0.$(OBJEXT) \
+ libluatex_a-writetype2.$(OBJEXT) libluatex_a-epdf.$(OBJEXT) \
+ libluatex_a-writeimg.$(OBJEXT) \
+ libluatex_a-writejbig2.$(OBJEXT) \
+ libluatex_a-writejpg.$(OBJEXT) libluatex_a-writepng.$(OBJEXT) \
+ libluatex_a-luagen.$(OBJEXT) libluatex_a-luainit.$(OBJEXT) \
libluatex_a-luanode.$(OBJEXT) libluatex_a-luastuff.$(OBJEXT) \
- libluatex_a-luatex.$(OBJEXT) libluatex_a-luatoken.$(OBJEXT) \
- libluatex_a-texluac.$(OBJEXT) libluatex_a-makecpool.$(OBJEXT) \
- libluatex_a-managed-sa.$(OBJEXT) \
- libluatex_a-mathcodes.$(OBJEXT) libluatex_a-pagetree.$(OBJEXT) \
- libluatex_a-pdfpage.$(OBJEXT) libluatex_a-filename.$(OBJEXT) \
- libluatex_a-linebreak.$(OBJEXT) libluatex_a-math.$(OBJEXT) \
- libluatex_a-mlist.$(OBJEXT) \
+ libluatex_a-luatoken.$(OBJEXT) libluatex_a-texluac.$(OBJEXT) \
+ libluatex_a-ocp.$(OBJEXT) libluatex_a-ocplist.$(OBJEXT) \
+ libluatex_a-readocp.$(OBJEXT) libluatex_a-runocp.$(OBJEXT) \
+ libluatex_a-texlang.$(OBJEXT) libluatex_a-hyphen.$(OBJEXT) \
+ libluatex_a-hnjalloc.$(OBJEXT) libluatex_a-pagetree.$(OBJEXT) \
+ libluatex_a-pdfaction.$(OBJEXT) libluatex_a-pdfannot.$(OBJEXT) \
+ libluatex_a-pdfcolorstack.$(OBJEXT) \
+ libluatex_a-pdfdest.$(OBJEXT) libluatex_a-pdffont.$(OBJEXT) \
+ libluatex_a-pdfgen.$(OBJEXT) libluatex_a-pdfglyph.$(OBJEXT) \
+ libluatex_a-pdfimage.$(OBJEXT) libluatex_a-pdflink.$(OBJEXT) \
+ libluatex_a-pdflistout.$(OBJEXT) \
+ libluatex_a-pdfliteral.$(OBJEXT) libluatex_a-pdfobj.$(OBJEXT) \
+ libluatex_a-pdfoutline.$(OBJEXT) libluatex_a-pdfpage.$(OBJEXT) \
+ libluatex_a-pdfrule.$(OBJEXT) \
+ libluatex_a-pdfsaverestore.$(OBJEXT) \
+ libluatex_a-pdfsetmatrix.$(OBJEXT) \
+ libluatex_a-pdfshipout.$(OBJEXT) \
+ libluatex_a-pdftables.$(OBJEXT) \
+ libluatex_a-pdfthread.$(OBJEXT) libluatex_a-pdfxform.$(OBJEXT) \
+ libluatex_a-align.$(OBJEXT) libluatex_a-dumpdata.$(OBJEXT) \
+ libluatex_a-expand.$(OBJEXT) libluatex_a-inputstack.$(OBJEXT) \
+ libluatex_a-maincontrol.$(OBJEXT) libluatex_a-mlist.$(OBJEXT) \
libluatex_a-postlinebreak.$(OBJEXT) \
- libluatex_a-primitive.$(OBJEXT) \
+ libluatex_a-scanning.$(OBJEXT) \
libluatex_a-texdeffont.$(OBJEXT) \
- libluatex_a-texnodes.$(OBJEXT) libluatex_a-texpdf.$(OBJEXT) \
- libluatex_a-textoken.$(OBJEXT) libluatex_a-textcodes.$(OBJEXT) \
- libluatex_a-avl.$(OBJEXT) libluatex_a-avlstuff.$(OBJEXT) \
- libluatex_a-synctex.$(OBJEXT) libluatex_a-utils.$(OBJEXT) \
- libluatex_a-writezip.$(OBJEXT) libluatex_a-lmplib.$(OBJEXT)
-libluatex_a_OBJECTS = $(am_libluatex_a_OBJECTS)
+ libluatex_a-texnodes.$(OBJEXT) \
+ libluatex_a-arithmetic.$(OBJEXT) \
+ libluatex_a-conditional.$(OBJEXT) \
+ libluatex_a-equivalents.$(OBJEXT) \
+ libluatex_a-extensions.$(OBJEXT) \
+ libluatex_a-commands.$(OBJEXT) libluatex_a-linebreak.$(OBJEXT) \
+ libluatex_a-mathcodes.$(OBJEXT) libluatex_a-nesting.$(OBJEXT) \
+ libluatex_a-primitive.$(OBJEXT) \
+ libluatex_a-texfileio.$(OBJEXT) \
+ libluatex_a-textcodes.$(OBJEXT) \
+ libluatex_a-buildpage.$(OBJEXT) \
+ libluatex_a-directions.$(OBJEXT) libluatex_a-errors.$(OBJEXT) \
+ libluatex_a-filename.$(OBJEXT) libluatex_a-mainbody.$(OBJEXT) \
+ libluatex_a-memoryword.$(OBJEXT) \
+ libluatex_a-packaging.$(OBJEXT) libluatex_a-printing.$(OBJEXT) \
+ libluatex_a-stringpool.$(OBJEXT) libluatex_a-texmath.$(OBJEXT) \
+ libluatex_a-textoken.$(OBJEXT) libluatex_a-utils.$(OBJEXT) \
+ libluatex_a-avlstuff.$(OBJEXT) \
+ libluatex_a-managed-sa.$(OBJEXT)
+libluatex_a_OBJECTS = $(am_libluatex_a_OBJECTS) \
+ $(nodist_libluatex_a_OBJECTS)
libmd5_a_AR = $(AR) $(ARFLAGS)
libmd5_a_LIBADD =
am_libmd5_a_OBJECTS = libmd5_a-md5.$(OBJEXT)
libmd5_a_OBJECTS = $(am_libmd5_a_OBJECTS)
libmf_a_AR = $(AR) $(ARFLAGS)
libmf_a_LIBADD =
-am__objects_1 = libmf_a-mfini.$(OBJEXT) libmf_a-mf0.$(OBJEXT)
-nodist_libmf_a_OBJECTS = $(am__objects_1) libmf_a-mf-pool.$(OBJEXT)
+am__objects_2 = libmf_a-mfini.$(OBJEXT) libmf_a-mf0.$(OBJEXT)
+nodist_libmf_a_OBJECTS = $(am__objects_2) libmf_a-mf-pool.$(OBJEXT)
libmf_a_OBJECTS = $(nodist_libmf_a_OBJECTS)
libmplib_a_AR = $(AR) $(ARFLAGS)
libmplib_a_LIBADD =
am_libmplib_a_OBJECTS = libmplib_a-avl.$(OBJEXT)
-am__objects_2 = libmplib_a-memio.$(OBJEXT)
-am__objects_3 = libmplib_a-mp.$(OBJEXT)
-am__objects_4 = libmplib_a-psout.$(OBJEXT)
-am__objects_5 = libmplib_a-svgout.$(OBJEXT)
-am__objects_6 = libmplib_a-tfmin.$(OBJEXT)
-nodist_libmplib_a_OBJECTS = $(am__objects_2) $(am__objects_3) \
- $(am__objects_4) $(am__objects_5) $(am__objects_6)
+am__objects_3 = libmplib_a-memio.$(OBJEXT)
+am__objects_4 = libmplib_a-mp.$(OBJEXT)
+am__objects_5 = libmplib_a-psout.$(OBJEXT)
+am__objects_6 = libmplib_a-svgout.$(OBJEXT)
+am__objects_7 = libmplib_a-tfmin.$(OBJEXT)
+nodist_libmplib_a_OBJECTS = $(am__objects_3) $(am__objects_4) \
+ $(am__objects_5) $(am__objects_6) $(am__objects_7)
libmplib_a_OBJECTS = $(am_libmplib_a_OBJECTS) \
$(nodist_libmplib_a_OBJECTS)
libpdftex_a_AR = $(AR) $(ARFLAGS)
@@ -376,7 +467,7 @@ am__libpdftex_a_SOURCES_DIST = pdftexdir/avl.c pdftexdir/avl.h \
pdftexdir/writettf.c pdftexdir/writettf.h pdftexdir/writezip.c \
pdftexdir/regex/regex.c pdftexdir/regex/regex.h \
pdftexdir/inc-epdf.h pdftexdir/inc-extra.h
-@MINGW32_TRUE@am__objects_7 = libpdftex_a-regex.$(OBJEXT)
+@MINGW32_TRUE@am__objects_8 = libpdftex_a-regex.$(OBJEXT)
am_libpdftex_a_OBJECTS = libpdftex_a-avl.$(OBJEXT) \
libpdftex_a-avlstuff.$(OBJEXT) libpdftex_a-epdf.$(OBJEXT) \
libpdftex_a-mapfile.$(OBJEXT) libpdftex_a-pdftoepdf.$(OBJEXT) \
@@ -388,7 +479,7 @@ am_libpdftex_a_OBJECTS = libpdftex_a-avl.$(OBJEXT) \
libpdftex_a-writejpg.$(OBJEXT) libpdftex_a-writepng.$(OBJEXT) \
libpdftex_a-writet1.$(OBJEXT) libpdftex_a-writet3.$(OBJEXT) \
libpdftex_a-writettf.$(OBJEXT) libpdftex_a-writezip.$(OBJEXT) \
- $(am__objects_7)
+ $(am__objects_8)
libpdftex_a_OBJECTS = $(am_libpdftex_a_OBJECTS)
libxetex_a_AR = $(AR) $(ARFLAGS)
libxetex_a_LIBADD =
@@ -413,10 +504,10 @@ am__libxetex_a_SOURCES_DIST = xetexdir/MathTable.h \
xetexdir/numbers.c xetexdir/numbers.h xetexdir/pdfimage.cpp \
xetexdir/pdfimage.h xetexdir/pngimage.c xetexdir/pngimage.h \
xetexdir/XeTeXGrLayout.cpp xetexdir/XeTeXGrLayout.h
-@XETEX_MACOSX_TRUE@am__objects_8 = \
+@XETEX_MACOSX_TRUE@am__objects_9 = \
@XETEX_MACOSX_TRUE@ libxetex_a-XeTeXFontInst_Mac.$(OBJEXT) \
@XETEX_MACOSX_TRUE@ libxetex_a-XeTeX_mac.$(OBJEXT)
-@XETEX_MACOSX_FALSE@am__objects_9 = \
+@XETEX_MACOSX_FALSE@am__objects_10 = \
@XETEX_MACOSX_FALSE@ libxetex_a-XeTeXFontMgr_FC.$(OBJEXT) \
@XETEX_MACOSX_FALSE@ libxetex_a-XeTeX_pic.$(OBJEXT) \
@XETEX_MACOSX_FALSE@ libxetex_a-bmpimage.$(OBJEXT) \
@@ -425,7 +516,7 @@ am__libxetex_a_SOURCES_DIST = xetexdir/MathTable.h \
@XETEX_MACOSX_FALSE@ libxetex_a-numbers.$(OBJEXT) \
@XETEX_MACOSX_FALSE@ libxetex_a-pdfimage.$(OBJEXT) \
@XETEX_MACOSX_FALSE@ libxetex_a-pngimage.$(OBJEXT)
-@XETEX_GRAPHITE_TRUE@am__objects_10 = \
+@XETEX_GRAPHITE_TRUE@am__objects_11 = \
@XETEX_GRAPHITE_TRUE@ libxetex_a-XeTeXGrLayout.$(OBJEXT)
am_libxetex_a_OBJECTS = libxetex_a-FontTableCache.$(OBJEXT) \
libxetex_a-XeTeXFontInst.$(OBJEXT) \
@@ -435,8 +526,8 @@ am_libxetex_a_OBJECTS = libxetex_a-FontTableCache.$(OBJEXT) \
libxetex_a-XeTeXOTLayoutEngine.$(OBJEXT) \
libxetex_a-XeTeXOTMath.$(OBJEXT) \
libxetex_a-XeTeX_ext.$(OBJEXT) libxetex_a-cmaps.$(OBJEXT) \
- libxetex_a-trans.$(OBJEXT) $(am__objects_8) $(am__objects_9) \
- $(am__objects_10)
+ libxetex_a-trans.$(OBJEXT) $(am__objects_9) $(am__objects_10) \
+ $(am__objects_11)
libxetex_a_OBJECTS = $(am_libxetex_a_OBJECTS)
libxetexmm_a_AR = $(AR) $(ARFLAGS)
libxetexmm_a_LIBADD =
@@ -459,7 +550,7 @@ am__EXEEXT_4 = $(am__EXEEXT_2) $(am__EXEEXT_3)
@ETEX_TRUE@am__EXEEXT_10 = etex$(EXEEXT)
@PDFTEX_TRUE@am__EXEEXT_11 = pdftex$(EXEEXT) ttf2afm$(EXEEXT) \
@PDFTEX_TRUE@ pdftosrc$(EXEEXT)
-@LUATEX_TRUE@am__EXEEXT_12 = luatex$(EXEEXT) luatangle$(EXEEXT)
+@LUATEX_TRUE@am__EXEEXT_12 = luatex$(EXEEXT)
@XETEX_TRUE@am__EXEEXT_13 = xetex$(EXEEXT)
@OTANGLE_TRUE@am__EXEEXT_14 = $(am__EXEEXT_2)
@OMFONTS_FALSE@@OTANGLE_TRUE@am__EXEEXT_15 = $(am__EXEEXT_3)
@@ -475,8 +566,8 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
@OTANGLE_TRUE@am__EXEEXT_21 = pltotf$(EXEEXT) tftopl$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am_aleph_OBJECTS = aleph-aleph.$(OBJEXT) aleph-alephbis.$(OBJEXT)
-am__objects_11 = aleph-alephini.$(OBJEXT) aleph-aleph0.$(OBJEXT)
-nodist_aleph_OBJECTS = $(am__objects_11) aleph-aleph-pool.$(OBJEXT) \
+am__objects_12 = aleph-alephini.$(OBJEXT) aleph-aleph0.$(OBJEXT)
+nodist_aleph_OBJECTS = $(am__objects_12) aleph-aleph-pool.$(OBJEXT) \
aleph-alephextra.$(OBJEXT)
aleph_OBJECTS = $(am_aleph_OBJECTS) $(nodist_aleph_OBJECTS)
am__DEPENDENCIES_1 =
@@ -525,10 +616,10 @@ dvitype_DEPENDENCIES = $(proglib) $(am__DEPENDENCIES_1)
am__dist_etex_SOURCES_DIST = synctexdir/synctex.h \
synctexdir/synctex-common.h synctexdir/synctex-etex.h
dist_etex_OBJECTS =
-am__objects_12 = etex-etexini.$(OBJEXT) etex-etex0.$(OBJEXT)
-@ETEX_SYNCTEX_TRUE@am__objects_13 = etex-synctex-e.$(OBJEXT)
-nodist_etex_OBJECTS = $(am__objects_12) etex-etex-pool.$(OBJEXT) \
- etex-etexextra.$(OBJEXT) $(am__objects_13)
+am__objects_13 = etex-etexini.$(OBJEXT) etex-etex0.$(OBJEXT)
+@ETEX_SYNCTEX_TRUE@am__objects_14 = etex-synctex-e.$(OBJEXT)
+nodist_etex_OBJECTS = $(am__objects_13) etex-etex-pool.$(OBJEXT) \
+ etex-etexextra.$(OBJEXT) $(am__objects_14)
etex_OBJECTS = $(dist_etex_OBJECTS) $(nodist_etex_OBJECTS)
@ETEX_SYNCTEX_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1)
etex_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
@@ -549,21 +640,15 @@ nodist_gftype_OBJECTS = gftype.$(OBJEXT)
gftype_OBJECTS = $(nodist_gftype_OBJECTS)
gftype_LDADD = $(LDADD)
gftype_DEPENDENCIES = $(proglib) $(am__DEPENDENCIES_1)
-nodist_luatangle_OBJECTS = luatangle.$(OBJEXT)
-luatangle_OBJECTS = $(nodist_luatangle_OBJECTS)
-luatangle_LDADD = $(LDADD)
-luatangle_DEPENDENCIES = $(proglib) $(am__DEPENDENCIES_1)
-am__objects_14 = luatex-luatexini.$(OBJEXT) luatex-luatex0.$(OBJEXT)
-nodist_luatex_OBJECTS = $(am__objects_14) luatex-luatex-pool.$(OBJEXT) \
- luatex-luatexextra.$(OBJEXT)
-luatex_OBJECTS = $(nodist_luatex_OBJECTS)
+am_luatex_OBJECTS = luatex-luatex.$(OBJEXT)
+luatex_OBJECTS = $(am_luatex_OBJECTS)
am__DEPENDENCIES_4 = libluatex.a libff.a libluamisc.a libluasocket.a \
liblua51.a $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) libmd5.a libmplib.a
luatex_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(luatex_CXXFLAGS) $(CXXFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ $(luatex_LDFLAGS) $(LDFLAGS) -o $@
am_md5main_OBJECTS = md5main-md5main.$(OBJEXT)
md5main_OBJECTS = $(am_md5main_OBJECTS)
md5main_DEPENDENCIES = libmd5.a
@@ -766,7 +851,7 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
SOURCES = $(libff_a_SOURCES) $(liblua51_a_SOURCES) \
$(libluamisc_a_SOURCES) $(EXTRA_libluamisc_a_SOURCES) \
$(libluasocket_a_SOURCES) $(libluatex_a_SOURCES) \
- $(EXTRA_libluatex_a_SOURCES) $(libmd5_a_SOURCES) \
+ $(nodist_libluatex_a_SOURCES) $(libmd5_a_SOURCES) \
$(nodist_libmf_a_SOURCES) $(libmplib_a_SOURCES) \
$(nodist_libmplib_a_SOURCES) $(libpdftex_a_SOURCES) \
$(EXTRA_libpdftex_a_SOURCES) $(libxetex_a_SOURCES) \
@@ -777,39 +862,38 @@ SOURCES = $(libff_a_SOURCES) $(liblua51_a_SOURCES) \
$(nodist_dvicopy_SOURCES) $(nodist_dvitype_SOURCES) \
$(dist_etex_SOURCES) $(nodist_etex_SOURCES) $(gftodvi_SOURCES) \
$(nodist_gftodvi_SOURCES) $(nodist_gftopk_SOURCES) \
- $(nodist_gftype_SOURCES) $(nodist_luatangle_SOURCES) \
- $(nodist_luatex_SOURCES) $(nodist_EXTRA_luatex_SOURCES) \
- $(md5main_SOURCES) $(nodist_mf_SOURCES) \
- $(nodist_mf_nowin_SOURCES) $(nodist_mft_SOURCES) \
- $(nodist_mpost_SOURCES) $(nodist_odvicopy_SOURCES) \
- $(nodist_odvitype_SOURCES) $(nodist_ofm2opl_SOURCES) \
- $(nodist_opl2ofm_SOURCES) $(nodist_otangle_SOURCES) \
- $(nodist_ovf2ovp_SOURCES) $(nodist_ovp2ovf_SOURCES) \
- $(nodist_patgen_SOURCES) $(dist_pdftex_SOURCES) \
- $(nodist_pdftex_SOURCES) $(nodist_EXTRA_pdftex_SOURCES) \
- $(pdftosrc_SOURCES) $(nodist_EXTRA_pdftosrc_SOURCES) \
- $(nodist_pktogf_SOURCES) $(nodist_pktype_SOURCES) \
- $(nodist_pltotf_SOURCES) $(nodist_pooltype_SOURCES) \
- $(synctex_SOURCES) $(nodist_tangle_SOURCES) \
- $(nodist_tangleboot_SOURCES) $(dist_tex_SOURCES) \
- $(nodist_tex_SOURCES) $(nodist_tftopl_SOURCES) \
- $(nodist_tie_SOURCES) $(ttf2afm_SOURCES) \
- $(EXTRA_ttf2afm_SOURCES) $(nodist_vftovp_SOURCES) \
- $(nodist_vptovf_SOURCES) $(nodist_weave_SOURCES) \
- $(dist_xetex_SOURCES) $(nodist_xetex_SOURCES) \
- $(nodist_EXTRA_xetex_SOURCES)
+ $(nodist_gftype_SOURCES) $(luatex_SOURCES) \
+ $(nodist_EXTRA_luatex_SOURCES) $(md5main_SOURCES) \
+ $(nodist_mf_SOURCES) $(nodist_mf_nowin_SOURCES) \
+ $(nodist_mft_SOURCES) $(nodist_mpost_SOURCES) \
+ $(nodist_odvicopy_SOURCES) $(nodist_odvitype_SOURCES) \
+ $(nodist_ofm2opl_SOURCES) $(nodist_opl2ofm_SOURCES) \
+ $(nodist_otangle_SOURCES) $(nodist_ovf2ovp_SOURCES) \
+ $(nodist_ovp2ovf_SOURCES) $(nodist_patgen_SOURCES) \
+ $(dist_pdftex_SOURCES) $(nodist_pdftex_SOURCES) \
+ $(nodist_EXTRA_pdftex_SOURCES) $(pdftosrc_SOURCES) \
+ $(nodist_EXTRA_pdftosrc_SOURCES) $(nodist_pktogf_SOURCES) \
+ $(nodist_pktype_SOURCES) $(nodist_pltotf_SOURCES) \
+ $(nodist_pooltype_SOURCES) $(synctex_SOURCES) \
+ $(nodist_tangle_SOURCES) $(nodist_tangleboot_SOURCES) \
+ $(dist_tex_SOURCES) $(nodist_tex_SOURCES) \
+ $(nodist_tftopl_SOURCES) $(nodist_tie_SOURCES) \
+ $(ttf2afm_SOURCES) $(EXTRA_ttf2afm_SOURCES) \
+ $(nodist_vftovp_SOURCES) $(nodist_vptovf_SOURCES) \
+ $(nodist_weave_SOURCES) $(dist_xetex_SOURCES) \
+ $(nodist_xetex_SOURCES) $(nodist_EXTRA_xetex_SOURCES)
DIST_SOURCES = $(libff_a_SOURCES) $(liblua51_a_SOURCES) \
$(libluamisc_a_SOURCES) $(EXTRA_libluamisc_a_SOURCES) \
$(libluasocket_a_SOURCES) $(libluatex_a_SOURCES) \
- $(EXTRA_libluatex_a_SOURCES) $(libmd5_a_SOURCES) \
- $(libmplib_a_SOURCES) $(am__libpdftex_a_SOURCES_DIST) \
- $(EXTRA_libpdftex_a_SOURCES) $(am__libxetex_a_SOURCES_DIST) \
- $(libxetexmm_a_SOURCES) $(aleph_SOURCES) \
- $(am__dist_etex_SOURCES_DIST) $(gftodvi_SOURCES) \
- $(md5main_SOURCES) $(am__dist_pdftex_SOURCES_DIST) \
- $(pdftosrc_SOURCES) $(synctex_SOURCES) \
- $(am__dist_tex_SOURCES_DIST) $(ttf2afm_SOURCES) \
- $(EXTRA_ttf2afm_SOURCES) $(am__dist_xetex_SOURCES_DIST)
+ $(libmd5_a_SOURCES) $(libmplib_a_SOURCES) \
+ $(am__libpdftex_a_SOURCES_DIST) $(EXTRA_libpdftex_a_SOURCES) \
+ $(am__libxetex_a_SOURCES_DIST) $(libxetexmm_a_SOURCES) \
+ $(aleph_SOURCES) $(am__dist_etex_SOURCES_DIST) \
+ $(gftodvi_SOURCES) $(luatex_SOURCES) $(md5main_SOURCES) \
+ $(am__dist_pdftex_SOURCES_DIST) $(pdftosrc_SOURCES) \
+ $(synctex_SOURCES) $(am__dist_tex_SOURCES_DIST) \
+ $(ttf2afm_SOURCES) $(EXTRA_ttf2afm_SOURCES) \
+ $(am__dist_xetex_SOURCES_DIST)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
@@ -955,6 +1039,10 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBOBJS = @LIBOBJS@
LIBPNG_DEPEND = @LIBPNG_DEPEND@
LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
@@ -964,6 +1052,8 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
LUATANGLE = @LUATANGLE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -1158,10 +1248,7 @@ EXTRA_DIST = PROJECTS cftests config.h cpascal.h help.h triptrap-sh \
pdftexdir/README pdftexdir/change-files.txt \
pdftexdir/pdftex.mak pdftexdir/pdftex.mk \
pdftexdir/regex/COPYING.LIB pdftexdir/regex/README \
- $(luatex_sources) luatexdir/luatex.defines \
- luatexdir/luatexextra.in luatexdir/ptexlib.h \
- luatexdir/luatex.mk $(luatangle_sources) \
- luatexdir/luatangle.test luatexdir/lua51/Makefile \
+ luatexdir/ptexlib.h luatexdir/lua51/Makefile \
luatexdir/lua51/liolib.c luatexdir/lua51/lua.c \
luatexdir/lua51/luac.c luatexdir/lua51/print.c \
luatexdir/luasocket/src/socket_lua.c \
@@ -1256,17 +1343,16 @@ EXTRA_DIST = PROJECTS cftests config.h cpascal.h help.h triptrap-sh \
luatexdir/luafontloader/fontforge/gutils/Makefile.in \
luatexdir/luafontloader/fontforge/inc/config.h.in \
luatexdir/luafontloader/fontforge/plugins/Makefile.in \
- luatexdir/ChangeLog luatexdir/NEWS luatexdir/README \
- luatexdir/change-files.txt luatexdir/font/subfont.txt \
- $(xetex_web_srcs) xetexdir/xetex.defines \
- xetexdir/xetexextra.in xetexdir/pool2c.pl \
- xetexdir/unicode-char-prep.pl xetexdir/appleGlyphNames.c \
- xetexdir/XeTeXFontMgr_Mac.mm xetexdir/ChangeLog \
- xetexdir/LICENSE.txt xetexdir/xetex.mk omegaware/README \
- omegaware/ChangeLog $(odvicopy_sources) $(odvitype_sources) \
- $(ofm2opl_sources) $(opl2ofm_sources) $(otangle_sources) \
- $(ovf2ovp_sources) $(ovp2ovf_sources) $(OTANGLE_tests) \
- $(OMFONTS_tests) omegaware/tests/level1.opl \
+ $(libluatex_web) luatexdir/ChangeLog luatexdir/NEWS \
+ luatexdir/README luatexdir/font/subfont.txt $(xetex_web_srcs) \
+ xetexdir/xetex.defines xetexdir/xetexextra.in \
+ xetexdir/pool2c.pl xetexdir/unicode-char-prep.pl \
+ xetexdir/appleGlyphNames.c xetexdir/XeTeXFontMgr_Mac.mm \
+ xetexdir/ChangeLog xetexdir/LICENSE.txt xetexdir/xetex.mk \
+ omegaware/README omegaware/ChangeLog $(odvicopy_sources) \
+ $(odvitype_sources) $(ofm2opl_sources) $(opl2ofm_sources) \
+ $(otangle_sources) $(ovf2ovp_sources) $(ovp2ovf_sources) \
+ $(OTANGLE_tests) $(OMFONTS_tests) omegaware/tests/level1.opl \
omegaware/tests/ofontd1.dvi omegaware/tests/ofontd1.typ \
omegaware/tests/ofontd2.dvi omegaware/tests/ofontd2.typ \
omegaware/tests/ofontd3.dvi omegaware/tests/ofontd3.typ \
@@ -1330,9 +1416,7 @@ DISTCLEANFILES = $(EXTRA_LIBRARIES) tangle.c tangle.h tangle.p \
etex.pool etex-tangle etexdir/etex.version etrip.diffs \
$(nodist_pdftex_SOURCES) pdftex.ch pdftex-web2c pdftex.p \
pdftex.pool pdftex-tangle pdftexdir/pdftex.version \
- $(nodist_luatex_SOURCES) luatex-web2c luatex.p luatex.pool \
- luatex-tangle luatexdir/luatex.version luatangle.c luatangle.h \
- luatangle-web2c luatangle.p cftest.p $(nodist_xetex_SOURCES) \
+ $(nodist_libluatex_a_SOURCES) $(nodist_xetex_SOURCES) \
xetex.web xetex-web2c xetex.p xetex.pool xetex-tangle \
xetexdir/etex.version xetexdir/xetex.version \
$(omegaware_programs:=.c) $(omegaware_programs:=.h) \
@@ -1432,18 +1516,18 @@ cweave_CFLAGS = $(WARNING_CFLAGS)
nodist_tie_SOURCES = tie.c
tie_CPPFLAGS = -DNOT_WEB2C
tie_CFLAGS = $(WARNING_CFLAGS)
-tex_CPPFLAGS = $(am__append_43)
+tex_CPPFLAGS = $(am__append_42)
tex_CFLAGS = $(WARNING_CFLAGS)
# With --enable-ipc, TeX may need to link with -lsocket.
-tex_LDADD = $(LDADD) $(ipc_socketlibs) $(am__append_44)
+tex_LDADD = $(LDADD) $(ipc_socketlibs) $(am__append_43)
# TeX C sources
tex_c_h = texini.c tex0.c texcoerce.h texd.h
-nodist_tex_SOURCES = $(tex_c_h) tex-pool.c texextra.c $(am__append_46)
+nodist_tex_SOURCES = $(tex_c_h) tex-pool.c texextra.c $(am__append_45)
# We must create texd.h before building the tex_OBJECTS.
-tex_prereq = texd.h $(am__append_45)
+tex_prereq = texd.h $(am__append_44)
tex_ch_srcs = \
tex.web \
tex.ch \
@@ -1506,19 +1590,19 @@ svgout_c_h = mplibsvg.h mpsvgout.h svgout.c
tfmin_c_h = mptfmin.h tfmin.c
libmplib_web = mplibdir/mp.w mplibdir/psout.w mplibdir/svgout.w \
mplibdir/memio.w mplibdir/tfmin.w
-etex_CPPFLAGS = $(am__append_47)
+etex_CPPFLAGS = $(am__append_46)
etex_CFLAGS = $(WARNING_CFLAGS)
# With --enable-ipc, e-TeX may need to link with -lsocket.
-etex_LDADD = $(LDADD) $(ipc_socketlibs) $(am__append_48)
+etex_LDADD = $(LDADD) $(ipc_socketlibs) $(am__append_47)
# e-TeX C sources
etex_c_h = etexini.c etex0.c etexcoerce.h etexd.h
nodist_etex_SOURCES = $(etex_c_h) etex-pool.c etexextra.c \
- etexdir/etexextra.h $(am__append_50)
+ etexdir/etexextra.h $(am__append_49)
# We must create etexd.h before building the etex_OBJECTS.
-etex_prereq = etexd.h $(am__append_49)
+etex_prereq = etexd.h $(am__append_48)
etex_web_srcs = \
tex.web \
etexdir/etex.ch \
@@ -1549,7 +1633,7 @@ pdftex_dependencies = $(proglib) $(KPATHSEA_DEPEND) $(LIBPNG_DEPEND) \
# Force Automake to use CXXLD for linking
nodist_EXTRA_pdftex_SOURCES = dummy.cxx
pdf_tangle = WEBINPUTS=.:$(srcdir)/pdftexdir $(SHELL) ./tangle-sh $@ $(TANGLE)
-pdftex_CPPFLAGS = $(pdftex_cppflags) $(am__append_51)
+pdftex_CPPFLAGS = $(pdftex_cppflags) $(am__append_50)
pdftex_CFLAGS = $(WARNING_CFLAGS)
pdftex_CXXFLAGS = $(WARNING_CXXFLAGS)
@@ -1558,7 +1642,7 @@ pdftex_LDADD = libpdftex.a $(pdftex_ldadd) $(LDADD) $(ipc_socketlibs)
pdftex_DEPENDENCIES = $(pdftex_dependencies) libpdftex.a
pdftex_c_h = pdftexini.c pdftex0.c pdftexcoerce.h pdftexd.h
nodist_pdftex_SOURCES = $(pdftex_c_h) pdftex-pool.c pdftexextra.c \
- pdftexdir/pdftexextra.h $(am__append_52)
+ pdftexdir/pdftexextra.h $(am__append_51)
pdftex_ch_srcs = \
pdftexdir/pdftex.web \
pdftexdir/tex.ch0 \
@@ -1600,7 +1684,6 @@ pdftosrc_DEPENDENCIES = $(pdftex_dependencies)
# Force Automake to use CXXLD for linking
nodist_EXTRA_luatex_SOURCES = dummy.cxx
-luatex_tangle = WEBINPUTS=$(srcdir)/luatexdir $(SHELL) ./tangle-sh $@ '$(LUATANGLE) --underlines'
luatex_CPPFLAGS = $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES) $(XPDF_INCLUDES) \
$(OBSDCOMPAT_INCLUDES) -I$(srcdir)/libmd5 -Iluatexdir \
-I$(srcdir)/luatexdir -I$(srcdir)/luatexdir/lua51 \
@@ -1610,16 +1693,13 @@ luatex_CXXFLAGS = $(WARNING_CXXFLAGS)
luatex_ldadd = libluatex.a libff.a libluamisc.a libluasocket.a \
liblua51.a $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) \
$(XPDF_LIBS) $(OBSDCOMPAT_LIBS) libmd5.a libmplib.a
-luatex_LDADD = $(luatex_ldadd) $(LDADD) $(lua_socketlibs)
+luatex_LDFLAGS = -export-dynamic
+luatex_LDADD = $(luatex_ldadd) $(LDADD) $(LIBADD_DLOPEN) $(lua_socketlibs)
luatex_DEPENDENCIES = $(proglib) $(KPATHSEA_DEPEND) libluatex.a \
$(LIBPNG_DEPEND) $(ZLIB_DEPEND) $(XPDF_DEPEND) \
$(OBSDCOMPAT_DEPEND) libmd5.a libmplib.a
-luatex_c_h = luatexini.c luatex0.c luatexcoerce.h luatexd.h
-nodist_luatex_SOURCES = $(luatex_c_h) luatex-pool.c luatexextra.c luatexdir/luatexextra.h
-luatex_sources = luatexdir/luatex.web luatexdir/luatex.ch
-nodist_luatangle_SOURCES = luatangle.c luatangle.h
-luatangle_sources = luatexdir/luatangle.web luatexdir/luatangle.ch
-liblua51_a_CPPFLAGS = -I$(top_srcdir)/luatexdir/lua51 $(am__append_24)
+luatex_SOURCES = luatexdir/luatex_svnversion.h luatexdir/luatex.c luatexdir/luatex.h
+liblua51_a_CPPFLAGS = -I$(top_srcdir)/luatexdir/lua51 $(am__append_23)
liblua51_a_CFLAGS = # $(WARNING_CFLAGS)
liblua51_a_SOURCES = \
luatexdir/lua51/lapi.c \
@@ -1722,8 +1802,9 @@ libluamisc_a_SOURCES = \
luatexdir/luafilesystem/src/lfs.c \
luatexdir/luafilesystem/src/lfs.h \
luatexdir/luamd5/md5.c \
- luatexdir/luamd5/md5.h \
+ luatexdir/luamd5/luamd5.h \
luatexdir/luamd5/md5lib.c \
+ luatexdir/luamd5/md5_lua.c \
luatexdir/luapeg/lpeg.c \
luatexdir/luaprofiler/clocks.c \
luatexdir/luaprofiler/clocks.h \
@@ -1755,15 +1836,12 @@ libff_a_CFLAGS = # $(WARNING_CFLAGS)
libff_a_SOURCES = \
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 \
@@ -1853,8 +1931,7 @@ libff_a_SOURCES = \
luatexdir/luafontloader/fontforge/inc/ustring.h \
luatexdir/luafontloader/fontforge/inc/utype.h \
luatexdir/luafontloader/src/ffdummies.c \
- luatexdir/luafontloader/src/luafflib.c \
- luatexdir/luafontloader/src/luafflib.h
+ luatexdir/luafontloader/src/luafflib.c
libluatex_a_DEPENDENCIES = libff.a
libluatex_a_CPPFLAGS = $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES) \
@@ -1863,82 +1940,213 @@ libluatex_a_CPPFLAGS = $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES) \
-DpdfTeX
libluatex_a_CFLAGS = $(WARNING_CFLAGS)
libluatex_a_CXXFLAGS = # $(WARNING_CXXFLAGS)
-libluatex_a_SOURCES = luatexdir/commands.h luatexdir/font/dofont.c \
- luatexdir/font/luatexfont.h luatexdir/font/luafont.c \
- luatexdir/font/mapfile.c luatexdir/font/mapfile.h \
- luatexdir/font/pkin.c luatexdir/font/sfnt.c \
- luatexdir/font/sfnt.h luatexdir/font/subfont.c \
- luatexdir/font/texfont.c luatexdir/font/texfont.h \
- luatexdir/font/tfmofm.c luatexdir/font/tounicode.c \
- luatexdir/font/tt_glyf.c luatexdir/font/tt_glyf.h \
- luatexdir/font/tt_table.c luatexdir/font/tt_table.h \
- luatexdir/font/vfovf.c luatexdir/font/vfpacket.c \
- luatexdir/font/writecff.c luatexdir/font/writecff.h \
- luatexdir/font/writeenc.c luatexdir/font/writefont.c \
- luatexdir/font/writet1.c luatexdir/font/writet3.c \
- luatexdir/font/writettf.c 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 \
- luatexdir/image/image.h luatexdir/image/pdftoepdf.cc \
- luatexdir/image/pdftoepdf.h luatexdir/image/writeimg.c \
- luatexdir/image/writeimg.h luatexdir/image/writejbig2.c \
- luatexdir/image/writejbig2.h luatexdir/image/writejpg.c \
- luatexdir/image/writejpg.h luatexdir/image/writepng.c \
- luatexdir/image/writepng.h luatexdir/lang/hnjalloc.c \
- luatexdir/lang/hnjalloc.h luatexdir/lang/hyphen.c \
- luatexdir/lang/texlang.c luatexdir/lua/lcallbacklib.c \
- luatexdir/lua/lfontlib.c luatexdir/lua/limglib.c \
- luatexdir/lua/lkpselib.c luatexdir/lua/llanglib.c \
- luatexdir/lua/llualib.c luatexdir/lua/lnodelib.c \
- luatexdir/lua/loslibext.c luatexdir/lua/liolib.c \
- luatexdir/lua/lpdflib.c luatexdir/lua/lstatslib.c \
- luatexdir/lua/ltexiolib.c luatexdir/lua/ltexlib.c \
- luatexdir/lua/ltokenlib.c luatexdir/lua/luainit.c \
- luatexdir/lua/luanode.c luatexdir/lua/luastuff.c \
- luatexdir/lua/luatex.c luatexdir/lua/luatoken.c \
- 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/nodes.h \
- luatexdir/pdf/pagetree.c luatexdir/pdf/pagetree.h \
- luatexdir/pdf/pdfpage.c luatexdir/pdf/pdfpage.h \
- luatexdir/primitive.h luatexdir/ptexmac.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/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/utils.h \
- luatexdir/utils/writezip.c mplibdir/lmplib.c \
- luatexdir/inc-epdf.h luatexdir/inc-extra.h \
- luatexdir/inc-vfovf.h
-EXTRA_libluatex_a_SOURCES = luatexdir/font/macnames.c
+luatex_dvi_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/dvi $(ctangle)
+libluatex_web = luatexdir/dvi/dvigen.w luatexdir/font/dofont.w \
+ luatexdir/font/luafont.w luatexdir/font/mapfile.w \
+ luatexdir/font/pkin.w luatexdir/font/sfnt.w \
+ luatexdir/font/subfont.w luatexdir/font/texfont.w \
+ luatexdir/font/tfmofm.w luatexdir/font/tounicode.w \
+ luatexdir/font/tt_glyf.w luatexdir/font/tt_table.w \
+ luatexdir/font/vfovf.w luatexdir/font/vfpacket.w \
+ luatexdir/font/writecff.w luatexdir/font/writeenc.w \
+ luatexdir/font/writefont.w luatexdir/font/writet1.w \
+ luatexdir/font/writet3.w luatexdir/font/writettf.w \
+ luatexdir/font/writetype0.w luatexdir/font/writetype2.w \
+ luatexdir/image/epdf.w luatexdir/image/writeimg.w \
+ luatexdir/image/writejbig2.w luatexdir/image/writejpg.w \
+ luatexdir/image/writepng.w luatexdir/lua/luagen.w \
+ luatexdir/lua/luainit.w luatexdir/lua/luanode.w \
+ luatexdir/lua/luastuff.w luatexdir/lua/luatoken.w \
+ luatexdir/lua/texluac.w luatexdir/ocp/ocp.w \
+ luatexdir/ocp/ocplist.w luatexdir/ocp/readocp.w \
+ luatexdir/ocp/runocp.w luatexdir/lang/texlang.w \
+ luatexdir/lang/hyphen.w luatexdir/lang/hnjalloc.w \
+ luatexdir/pdf/pagetree.w luatexdir/pdf/pdfaction.w \
+ luatexdir/pdf/pdfannot.w luatexdir/pdf/pdfcolorstack.w \
+ luatexdir/pdf/pdfdest.w luatexdir/pdf/pdffont.w \
+ luatexdir/pdf/pdfgen.w luatexdir/pdf/pdfglyph.w \
+ luatexdir/pdf/pdfimage.w luatexdir/pdf/pdflink.w \
+ luatexdir/pdf/pdflistout.w luatexdir/pdf/pdfliteral.w \
+ luatexdir/pdf/pdfobj.w luatexdir/pdf/pdfoutline.w \
+ luatexdir/pdf/pdfpage.w luatexdir/pdf/pdfrule.w \
+ luatexdir/pdf/pdfsaverestore.w luatexdir/pdf/pdfsetmatrix.w \
+ luatexdir/pdf/pdfshipout.w luatexdir/pdf/pdftables.w \
+ luatexdir/pdf/pdfthread.w luatexdir/pdf/pdfxform.w \
+ luatexdir/tex/align.w luatexdir/tex/dumpdata.w \
+ luatexdir/tex/expand.w luatexdir/tex/inputstack.w \
+ luatexdir/tex/maincontrol.w luatexdir/tex/mlist.w \
+ luatexdir/tex/postlinebreak.w luatexdir/tex/scanning.w \
+ luatexdir/tex/texdeffont.w luatexdir/tex/texnodes.w \
+ luatexdir/tex/arithmetic.w luatexdir/tex/conditional.w \
+ luatexdir/tex/equivalents.w luatexdir/tex/extensions.w \
+ luatexdir/tex/commands.w luatexdir/tex/linebreak.w \
+ luatexdir/tex/mathcodes.w luatexdir/tex/nesting.w \
+ luatexdir/tex/primitive.w luatexdir/tex/texfileio.w \
+ luatexdir/tex/textcodes.w luatexdir/tex/buildpage.w \
+ luatexdir/tex/directions.w luatexdir/tex/errors.w \
+ luatexdir/tex/filename.w luatexdir/tex/mainbody.w \
+ luatexdir/tex/memoryword.w luatexdir/tex/packaging.w \
+ luatexdir/tex/printing.w luatexdir/tex/stringpool.w \
+ luatexdir/tex/texmath.w luatexdir/tex/textoken.w \
+ luatexdir/utils/utils.w luatexdir/utils/avlstuff.w \
+ luatexdir/utils/managed-sa.w
+nodist_libluatex_a_SOURCES = dvigen.c dofont.c luafont.c mapfile.c \
+ pkin.c sfnt.c subfont.c texfont.c tfmofm.c tounicode.c \
+ tt_glyf.c tt_table.c vfovf.c vfpacket.c writecff.c writeenc.c \
+ writefont.c writet1.c writet3.c writettf.c writetype0.c \
+ writetype2.c epdf.c writeimg.c writejbig2.c writejpg.c \
+ writepng.c luagen.c luainit.c luanode.c luastuff.c luatoken.c \
+ texluac.c ocp.c ocplist.c readocp.c runocp.c texlang.c \
+ hyphen.c hnjalloc.c pagetree.c pdfaction.c pdfannot.c \
+ pdfcolorstack.c pdfdest.c pdffont.c pdfgen.c pdfglyph.c \
+ pdfimage.c pdflink.c pdflistout.c pdfliteral.c pdfobj.c \
+ pdfoutline.c pdfpage.c pdfrule.c pdfsaverestore.c \
+ pdfsetmatrix.c pdfshipout.c pdftables.c pdfthread.c pdfxform.c \
+ align.c dumpdata.c expand.c inputstack.c maincontrol.c mlist.c \
+ postlinebreak.c scanning.c texdeffont.c texnodes.c \
+ arithmetic.c conditional.c equivalents.c extensions.c \
+ commands.c linebreak.c mathcodes.c nesting.c primitive.c \
+ texfileio.c textcodes.c buildpage.c directions.c errors.c \
+ filename.c mainbody.c memoryword.c packaging.c printing.c \
+ stringpool.c texmath.c textoken.c utils.c avlstuff.c \
+ managed-sa.c
+luatex_font_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/font $(ctangle)
+luatex_image_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/image $(ctangle)
+luatex_lua_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/lua $(ctangle)
+luatex_ocp_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/ocp $(ctangle)
+luatex_lang_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/lang $(ctangle)
+luatex_pdf_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/pdf $(ctangle)
+luatex_tex_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/tex $(ctangle)
+luatex_utils_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/utils $(ctangle)
+libluatex_a_SOURCES = \
+ luatexdir/dvi/dvigen.h \
+ luatexdir/font/luatexfont.h \
+ luatexdir/font/mapfile.h \
+ luatexdir/font/sfnt.h \
+ luatexdir/font/texfont.h \
+ luatexdir/font/tt_glyf.h \
+ luatexdir/font/tt_table.h \
+ luatexdir/font/writecff.h \
+ luatexdir/font/writettf.h \
+ luatexdir/image/epdf.h \
+ luatexdir/image/image.h \
+ luatexdir/image/pdftoepdf.cc \
+ luatexdir/image/pdftoepdf.h \
+ luatexdir/image/writeimg.h \
+ luatexdir/image/writejbig2.h \
+ luatexdir/image/writejpg.h \
+ luatexdir/image/writepng.h \
+ luatexdir/lang/hnjalloc.h \
+ luatexdir/lang/hyphen.h \
+ luatexdir/lang/texlang.h \
+ luatexdir/lua/lcallbacklib.c \
+ luatexdir/lua/lfontlib.c \
+ luatexdir/lua/limglib.c \
+ luatexdir/lua/lepdflib.cc \
+ luatexdir/lua/lkpselib.c \
+ luatexdir/lua/llanglib.c \
+ luatexdir/lua/llualib.c \
+ luatexdir/lua/lnodelib.c \
+ luatexdir/lua/loslibext.c \
+ luatexdir/lua/liolib.c \
+ luatexdir/lua/lpdflib.c \
+ luatexdir/lua/lstatslib.c \
+ luatexdir/lua/ltexiolib.c \
+ luatexdir/lua/ltexlib.c \
+ luatexdir/lua/ltokenlib.c \
+ luatexdir/lua/luagen.h \
+ luatexdir/lua/luatex-api.h \
+ luatexdir/luatex.h \
+ luatexdir/ocp/ocp.h \
+ luatexdir/ocp/ocplist.h \
+ luatexdir/ocp/readocp.h \
+ luatexdir/ocp/runocp.h \
+ luatexdir/pdf/pagetree.h \
+ luatexdir/pdf/pdfaction.h \
+ luatexdir/pdf/pdfannot.h \
+ luatexdir/pdf/pdfcolorstack.h \
+ luatexdir/pdf/pdfdest.h \
+ luatexdir/pdf/pdffont.h \
+ luatexdir/pdf/pdfgen.h \
+ luatexdir/pdf/pdfglyph.h \
+ luatexdir/pdf/pdfimage.h \
+ luatexdir/pdf/pdflink.h \
+ luatexdir/pdf/pdflistout.h \
+ luatexdir/pdf/pdfliteral.h \
+ luatexdir/pdf/pdfobj.h \
+ luatexdir/pdf/pdfoutline.h \
+ luatexdir/pdf/pdfpage.h \
+ luatexdir/pdf/pdfrule.h \
+ luatexdir/pdf/pdfsaverestore.h \
+ luatexdir/pdf/pdfsetmatrix.h \
+ luatexdir/pdf/pdfshipout.h \
+ luatexdir/pdf/pdftables.h \
+ luatexdir/pdf/pdfthread.h \
+ luatexdir/pdf/pdftypes.h \
+ luatexdir/pdf/pdfxform.h \
+ luatexdir/tex/align.h \
+ luatexdir/tex/arithmetic.h \
+ luatexdir/tex/buildpage.h \
+ luatexdir/tex/commands.h \
+ luatexdir/tex/conditional.h \
+ luatexdir/tex/directions.h \
+ luatexdir/tex/dumpdata.h \
+ luatexdir/tex/equivalents.h \
+ luatexdir/tex/errors.h \
+ luatexdir/tex/expand.h \
+ luatexdir/tex/extensions.h \
+ luatexdir/tex/filename.h \
+ luatexdir/tex/inputstack.h \
+ luatexdir/tex/linebreak.h \
+ luatexdir/tex/mainbody.h \
+ luatexdir/tex/maincontrol.h \
+ luatexdir/tex/mathcodes.h \
+ luatexdir/tex/memoryword.h \
+ luatexdir/tex/mlist.h \
+ luatexdir/tex/nesting.h \
+ luatexdir/tex/packaging.h \
+ luatexdir/tex/postlinebreak.h \
+ luatexdir/tex/primitive.h \
+ luatexdir/tex/printing.h \
+ luatexdir/tex/scanning.h \
+ luatexdir/tex/stringpool.h \
+ luatexdir/tex/texdeffont.h \
+ luatexdir/tex/texfileio.h \
+ luatexdir/tex/texmath.h \
+ luatexdir/tex/texnodes.h \
+ luatexdir/tex/textoken.h \
+ luatexdir/tex/textcodes.h \
+ luatexdir/utils/avl.c \
+ luatexdir/utils/avl.h \
+ luatexdir/utils/avlstuff.h \
+ luatexdir/utils/managed-sa.h \
+ luatexdir/utils/synctex.h \
+ luatexdir/utils/synctex.c \
+ luatexdir/utils/utils.h \
+ $(nodist_libluatex_a_SOURCES) \
+ mplibdir/lmplib.c
+
# Force Automake to use CXXLD for linking
nodist_EXTRA_xetex_SOURCES = dummy.cxx
-libxetex = libxetex.a $(am__append_27)
+libxetex = libxetex.a $(am__append_26)
xetex_cppflags = -I$(srcdir)/xetexdir $(ICU_INCLUDES) \
- $(FREETYPE2_INCLUDES) $(TECKIT_INCLUDES) $(am__append_26) \
- $(am__append_28) $(am__append_31) $(ZLIB_INCLUDES)
-xetex_ldadd = $(libxetex) $(ICU_LIBS) $(TECKIT_LIBS) $(am__append_29) \
- $(am__append_32) $(FREETYPE2_LIBS) $(ZLIB_LIBS)
+ $(FREETYPE2_INCLUDES) $(TECKIT_INCLUDES) $(am__append_25) \
+ $(am__append_27) $(am__append_30) $(ZLIB_INCLUDES)
+xetex_ldadd = $(libxetex) $(ICU_LIBS) $(TECKIT_LIBS) $(am__append_28) \
+ $(am__append_31) $(FREETYPE2_LIBS) $(ZLIB_LIBS)
xetex_dependencies = $(proglib) $(KPATHSEA_DEPEND) $(ICU_DEPEND) \
- $(TECKIT_DEPEND) $(am__append_30) $(am__append_33) \
+ $(TECKIT_DEPEND) $(am__append_29) $(am__append_32) \
$(FREETYPE2_DEPEND) $(ZLIB_DEPEND)
@XETEX_MACOSX_TRUE@xetex_LDFLAGS = -framework Carbon -framework Cocoa -framework QuickTime
-xetex_CPPFLAGS = $(xetex_cppflags) $(am__append_53)
+xetex_CPPFLAGS = $(xetex_cppflags) $(am__append_52)
xetex_CFLAGS = # $(WARNING_CFLAGS)
xetex_CXXFLAGS = # $(WARNING_CXXFLAGS)
xetex_LDADD = $(xetex_ldadd) $(LDADD) $(ipc_socketlibs)
xetex_prereq = $(libxetex)
xetex_c_h = xetexini.c xetex0.c xetexcoerce.h xetexd.h
nodist_xetex_SOURCES = $(xetex_c_h) xetex_pool.c xetexextra.c \
- xetexdir/xetexextra.h $(am__append_54)
+ xetexdir/xetexextra.h $(am__append_53)
xetex_web_srcs = \
tex.web \
etexdir/etex.ch \
@@ -1966,8 +2174,8 @@ libxetex_a_SOURCES = xetexdir/MathTable.h xetexdir/FontTableCache.cpp \
xetexdir/XeTeXOTMath.h xetexdir/XeTeX_ext.c \
xetexdir/XeTeX_ext.h xetexdir/XeTeXswap.h xetexdir/cmaps.cpp \
xetexdir/cmaps.h xetexdir/sfnt.h xetexdir/trans.c \
- xetexdir/trans.h xetexdir/xetex.h $(am__append_34) \
- $(am__append_35) $(am__append_36)
+ xetexdir/trans.h xetexdir/xetex.h $(am__append_33) \
+ $(am__append_34) $(am__append_35)
# We must create xetexd.h etc. before building the libxetex_a_OBJECTS.
libxetex_prereq = xetexd.h $(xetex_dependencies)
@@ -2146,7 +2354,7 @@ all: c-auto.h ff-config.h
.SUFFIXES: .c .cc .cin .cpp .cxx .h .hin .lo .o .obj .p .pin
am--refresh:
@:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/am/bootstrap.am $(srcdir)/am/web.am $(srcdir)/am/cweb.am $(srcdir)/am/texmf.am $(srcdir)/mplibdir/am/mplib.am $(srcdir)/mplibdir/am/libmplib.am $(srcdir)/etexdir/am/etex.am $(srcdir)/pdftexdir/am/pdftex.am $(srcdir)/pdftexdir/am/libpdftex.am $(srcdir)/pdftexdir/am/ttf2afm.am $(srcdir)/pdftexdir/am/pdftosrc.am $(srcdir)/luatexdir/am/luatex.am $(srcdir)/luatexdir/am/luatangle.am $(srcdir)/luatexdir/am/liblua51.am $(srcdir)/luatexdir/am/luasocket.am $(srcdir)/luatexdir/am/luamisc.am $(srcdir)/luatexdir/am/luafontforge.am $(srcdir)/luatexdir/am/libluatex.am $(srcdir)/xetexdir/am/xetex.am $(srcdir)/omegaware/am/omegaware.am $(srcdir)/alephdir/am/aleph.am $(srcdir)/synctexdir/am/synctex.am $(srcdir)/libmd5/am/md5.am $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/am/bootstrap.am $(srcdir)/am/web.am $(srcdir)/am/cweb.am $(srcdir)/am/texmf.am $(srcdir)/mplibdir/am/mplib.am $(srcdir)/mplibdir/am/libmplib.am $(srcdir)/etexdir/am/etex.am $(srcdir)/pdftexdir/am/pdftex.am $(srcdir)/pdftexdir/am/libpdftex.am $(srcdir)/pdftexdir/am/ttf2afm.am $(srcdir)/pdftexdir/am/pdftosrc.am $(srcdir)/luatexdir/am/luatex.am $(srcdir)/luatexdir/am/liblua51.am $(srcdir)/luatexdir/am/luasocket.am $(srcdir)/luatexdir/am/luamisc.am $(srcdir)/luatexdir/am/luafontforge.am $(srcdir)/luatexdir/am/libluatex.am $(srcdir)/xetexdir/am/xetex.am $(srcdir)/omegaware/am/omegaware.am $(srcdir)/alephdir/am/aleph.am $(srcdir)/synctexdir/am/synctex.am $(srcdir)/libmd5/am/md5.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -2351,9 +2559,6 @@ gftopk$(EXEEXT): $(gftopk_OBJECTS) $(gftopk_DEPENDENCIES)
gftype$(EXEEXT): $(gftype_OBJECTS) $(gftype_DEPENDENCIES)
@rm -f gftype$(EXEEXT)
$(LINK) $(gftype_OBJECTS) $(gftype_LDADD) $(LIBS)
-luatangle$(EXEEXT): $(luatangle_OBJECTS) $(luatangle_DEPENDENCIES)
- @rm -f luatangle$(EXEEXT)
- $(LINK) $(luatangle_OBJECTS) $(luatangle_LDADD) $(LIBS)
luatex$(EXEEXT): $(luatex_OBJECTS) $(luatex_DEPENDENCIES)
@rm -f luatex$(EXEEXT)
$(luatex_LINK) $(luatex_OBJECTS) $(luatex_LDADD) $(LIBS)
@@ -2481,12 +2686,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-ArabicForms.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-alphabet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-autohint.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-backtrns.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-char.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-cjk.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-clipnoui.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-cvundoes.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-dump.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-dumppfa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-encoding.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-featurefile.Po@am__quote@
@@ -2533,7 +2736,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-tottfgpos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-ttfspecial.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-ucharmap.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-unialt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-ustring.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libff_a-utype.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblua51_a-lapi.Po@am__quote@
@@ -2575,6 +2777,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluamisc_a-luazip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluamisc_a-lzlib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluamisc_a-md5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluamisc_a-md5_lua.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluamisc_a-md5lib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluamisc_a-slnudata.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluamisc_a-slnunico.Po@am__quote@
@@ -2593,14 +2796,28 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluasocket_a-tcp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluasocket_a-timeout.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluasocket_a-udp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-align.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-arithmetic.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-avl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-avlstuff.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-buildpage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-commands.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-conditional.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-directions.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-dofont.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-dumpdata.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-dvigen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-epdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-equivalents.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-errors.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-expand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-extensions.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-filename.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-hnjalloc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-hyphen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-inputstack.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-lcallbacklib.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-lepdflib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-lfontlib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-limglib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-linebreak.Po@am__quote@
@@ -2617,33 +2834,63 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-ltexlib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-ltokenlib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-luafont.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-luagen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-luainit.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-luanode.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-luastuff.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-luatex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-luatoken.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-macnames.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-makecpool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-mainbody.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-maincontrol.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-managed-sa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-mapfile.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-math.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-mathcodes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-memoryword.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-mlist.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-nesting.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-ocp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-ocplist.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-packaging.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pagetree.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfaction.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfannot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfcolorstack.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfdest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdffont.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfgen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfglyph.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfimage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdflink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdflistout.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfliteral.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfobj.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfoutline.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfpage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfrule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfsaverestore.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfsetmatrix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfshipout.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdftables.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfthread.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdftoepdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pdfxform.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-pkin.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-postlinebreak.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-primitive.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-printing.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-readocp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-runocp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-scanning.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-sfnt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-stringpool.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-subfont.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-synctex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texdeffont.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texfileio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texfont.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texlang.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texluac.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texmath.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texnodes.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-texpdf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-textcodes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-textoken.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-tfmofm.Po@am__quote@
@@ -2665,7 +2912,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-writettf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-writetype0.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-writetype2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libluatex_a-writezip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmd5_a-md5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmf_a-mf-pool.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmf_a-mf0.Po@am__quote@
@@ -2723,12 +2969,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxetex_a-pngimage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxetex_a-trans.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxetexmm_a-XeTeXFontMgr_Mac.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luatangle.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luatex-dummy.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luatex-luatex-pool.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luatex-luatex0.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luatex-luatexextra.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luatex-luatexini.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luatex-luatex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5main-md5main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mf-mfextra.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mf_nowin-mfextra.Po@am__quote@
@@ -2828,20 +3070,6 @@ libff_a-alphabet.obj: luatexdir/luafontloader/fontforge/Unicode/alphabet.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-alphabet.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/alphabet.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/alphabet.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/alphabet.c'; fi`
-libff_a-backtrns.o: luatexdir/luafontloader/fontforge/Unicode/backtrns.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-backtrns.o -MD -MP -MF $(DEPDIR)/libff_a-backtrns.Tpo -c -o libff_a-backtrns.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/backtrns.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/backtrns.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-backtrns.Tpo $(DEPDIR)/libff_a-backtrns.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luafontloader/fontforge/Unicode/backtrns.c' object='libff_a-backtrns.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-backtrns.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/backtrns.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/backtrns.c
-
-libff_a-backtrns.obj: luatexdir/luafontloader/fontforge/Unicode/backtrns.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-backtrns.obj -MD -MP -MF $(DEPDIR)/libff_a-backtrns.Tpo -c -o libff_a-backtrns.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/backtrns.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/backtrns.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/backtrns.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-backtrns.Tpo $(DEPDIR)/libff_a-backtrns.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luafontloader/fontforge/Unicode/backtrns.c' object='libff_a-backtrns.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-backtrns.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/backtrns.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/backtrns.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/backtrns.c'; fi`
-
libff_a-char.o: luatexdir/luafontloader/fontforge/Unicode/char.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-char.o -MD -MP -MF $(DEPDIR)/libff_a-char.Tpo -c -o libff_a-char.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/char.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/char.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-char.Tpo $(DEPDIR)/libff_a-char.Po
@@ -2870,20 +3098,6 @@ libff_a-cjk.obj: luatexdir/luafontloader/fontforge/Unicode/cjk.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-cjk.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/cjk.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/cjk.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/cjk.c'; fi`
-libff_a-dump.o: luatexdir/luafontloader/fontforge/Unicode/dump.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-dump.o -MD -MP -MF $(DEPDIR)/libff_a-dump.Tpo -c -o libff_a-dump.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/dump.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/dump.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-dump.Tpo $(DEPDIR)/libff_a-dump.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luafontloader/fontforge/Unicode/dump.c' object='libff_a-dump.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-dump.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/dump.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/dump.c
-
-libff_a-dump.obj: luatexdir/luafontloader/fontforge/Unicode/dump.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-dump.obj -MD -MP -MF $(DEPDIR)/libff_a-dump.Tpo -c -o libff_a-dump.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/dump.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/dump.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/dump.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-dump.Tpo $(DEPDIR)/libff_a-dump.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luafontloader/fontforge/Unicode/dump.c' object='libff_a-dump.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-dump.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/dump.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/dump.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/dump.c'; fi`
-
libff_a-gwwiconv.o: luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-gwwiconv.o -MD -MP -MF $(DEPDIR)/libff_a-gwwiconv.Tpo -c -o libff_a-gwwiconv.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-gwwiconv.Tpo $(DEPDIR)/libff_a-gwwiconv.Po
@@ -2926,20 +3140,6 @@ libff_a-ucharmap.obj: luatexdir/luafontloader/fontforge/Unicode/ucharmap.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-ucharmap.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/ucharmap.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/ucharmap.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/ucharmap.c'; fi`
-libff_a-unialt.o: luatexdir/luafontloader/fontforge/Unicode/unialt.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-unialt.o -MD -MP -MF $(DEPDIR)/libff_a-unialt.Tpo -c -o libff_a-unialt.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/unialt.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/unialt.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-unialt.Tpo $(DEPDIR)/libff_a-unialt.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luafontloader/fontforge/Unicode/unialt.c' object='libff_a-unialt.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-unialt.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/unialt.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/unialt.c
-
-libff_a-unialt.obj: luatexdir/luafontloader/fontforge/Unicode/unialt.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-unialt.obj -MD -MP -MF $(DEPDIR)/libff_a-unialt.Tpo -c -o libff_a-unialt.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/unialt.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/unialt.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/unialt.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-unialt.Tpo $(DEPDIR)/libff_a-unialt.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luafontloader/fontforge/Unicode/unialt.c' object='libff_a-unialt.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -c -o libff_a-unialt.obj `if test -f 'luatexdir/luafontloader/fontforge/Unicode/unialt.c'; then $(CYGPATH_W) 'luatexdir/luafontloader/fontforge/Unicode/unialt.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luafontloader/fontforge/Unicode/unialt.c'; fi`
-
libff_a-ustring.o: luatexdir/luafontloader/fontforge/Unicode/ustring.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libff_a_CPPFLAGS) $(CPPFLAGS) $(libff_a_CFLAGS) $(CFLAGS) -MT libff_a-ustring.o -MD -MP -MF $(DEPDIR)/libff_a-ustring.Tpo -c -o libff_a-ustring.o `test -f 'luatexdir/luafontloader/fontforge/Unicode/ustring.c' || echo '$(srcdir)/'`luatexdir/luafontloader/fontforge/Unicode/ustring.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libff_a-ustring.Tpo $(DEPDIR)/libff_a-ustring.Po
@@ -4060,6 +4260,20 @@ libluamisc_a-md5lib.obj: luatexdir/luamd5/md5lib.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluamisc_a_CPPFLAGS) $(CPPFLAGS) $(libluamisc_a_CFLAGS) $(CFLAGS) -c -o libluamisc_a-md5lib.obj `if test -f 'luatexdir/luamd5/md5lib.c'; then $(CYGPATH_W) 'luatexdir/luamd5/md5lib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luamd5/md5lib.c'; fi`
+libluamisc_a-md5_lua.o: luatexdir/luamd5/md5_lua.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluamisc_a_CPPFLAGS) $(CPPFLAGS) $(libluamisc_a_CFLAGS) $(CFLAGS) -MT libluamisc_a-md5_lua.o -MD -MP -MF $(DEPDIR)/libluamisc_a-md5_lua.Tpo -c -o libluamisc_a-md5_lua.o `test -f 'luatexdir/luamd5/md5_lua.c' || echo '$(srcdir)/'`luatexdir/luamd5/md5_lua.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluamisc_a-md5_lua.Tpo $(DEPDIR)/libluamisc_a-md5_lua.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luamd5/md5_lua.c' object='libluamisc_a-md5_lua.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluamisc_a_CPPFLAGS) $(CPPFLAGS) $(libluamisc_a_CFLAGS) $(CFLAGS) -c -o libluamisc_a-md5_lua.o `test -f 'luatexdir/luamd5/md5_lua.c' || echo '$(srcdir)/'`luatexdir/luamd5/md5_lua.c
+
+libluamisc_a-md5_lua.obj: luatexdir/luamd5/md5_lua.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluamisc_a_CPPFLAGS) $(CPPFLAGS) $(libluamisc_a_CFLAGS) $(CFLAGS) -MT libluamisc_a-md5_lua.obj -MD -MP -MF $(DEPDIR)/libluamisc_a-md5_lua.Tpo -c -o libluamisc_a-md5_lua.obj `if test -f 'luatexdir/luamd5/md5_lua.c'; then $(CYGPATH_W) 'luatexdir/luamd5/md5_lua.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luamd5/md5_lua.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluamisc_a-md5_lua.Tpo $(DEPDIR)/libluamisc_a-md5_lua.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luamd5/md5_lua.c' object='libluamisc_a-md5_lua.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluamisc_a_CPPFLAGS) $(CPPFLAGS) $(libluamisc_a_CFLAGS) $(CFLAGS) -c -o libluamisc_a-md5_lua.obj `if test -f 'luatexdir/luamd5/md5_lua.c'; then $(CYGPATH_W) 'luatexdir/luamd5/md5_lua.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luamd5/md5_lua.c'; fi`
+
libluamisc_a-lpeg.o: luatexdir/luapeg/lpeg.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluamisc_a_CPPFLAGS) $(CPPFLAGS) $(libluamisc_a_CFLAGS) $(CFLAGS) -MT libluamisc_a-lpeg.o -MD -MP -MF $(DEPDIR)/libluamisc_a-lpeg.Tpo -c -o libluamisc_a-lpeg.o `test -f 'luatexdir/luapeg/lpeg.c' || echo '$(srcdir)/'`luatexdir/luapeg/lpeg.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluamisc_a-lpeg.Tpo $(DEPDIR)/libluamisc_a-lpeg.Po
@@ -4410,985 +4624,1587 @@ libluasocket_a-udp.obj: luatexdir/luasocket/src/udp.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluasocket_a_CPPFLAGS) $(CPPFLAGS) $(libluasocket_a_CFLAGS) $(CFLAGS) -c -o libluasocket_a-udp.obj `if test -f 'luatexdir/luasocket/src/udp.c'; then $(CYGPATH_W) 'luatexdir/luasocket/src/udp.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luasocket/src/udp.c'; fi`
-libluatex_a-dofont.o: luatexdir/font/dofont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dofont.o -MD -MP -MF $(DEPDIR)/libluatex_a-dofont.Tpo -c -o libluatex_a-dofont.o `test -f 'luatexdir/font/dofont.c' || echo '$(srcdir)/'`luatexdir/font/dofont.c
+libluatex_a-lcallbacklib.o: luatexdir/lua/lcallbacklib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lcallbacklib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lcallbacklib.Tpo -c -o libluatex_a-lcallbacklib.o `test -f 'luatexdir/lua/lcallbacklib.c' || echo '$(srcdir)/'`luatexdir/lua/lcallbacklib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lcallbacklib.Tpo $(DEPDIR)/libluatex_a-lcallbacklib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lcallbacklib.c' object='libluatex_a-lcallbacklib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lcallbacklib.o `test -f 'luatexdir/lua/lcallbacklib.c' || echo '$(srcdir)/'`luatexdir/lua/lcallbacklib.c
+
+libluatex_a-lcallbacklib.obj: luatexdir/lua/lcallbacklib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lcallbacklib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lcallbacklib.Tpo -c -o libluatex_a-lcallbacklib.obj `if test -f 'luatexdir/lua/lcallbacklib.c'; then $(CYGPATH_W) 'luatexdir/lua/lcallbacklib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lcallbacklib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lcallbacklib.Tpo $(DEPDIR)/libluatex_a-lcallbacklib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lcallbacklib.c' object='libluatex_a-lcallbacklib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lcallbacklib.obj `if test -f 'luatexdir/lua/lcallbacklib.c'; then $(CYGPATH_W) 'luatexdir/lua/lcallbacklib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lcallbacklib.c'; fi`
+
+libluatex_a-lfontlib.o: luatexdir/lua/lfontlib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lfontlib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lfontlib.Tpo -c -o libluatex_a-lfontlib.o `test -f 'luatexdir/lua/lfontlib.c' || echo '$(srcdir)/'`luatexdir/lua/lfontlib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lfontlib.Tpo $(DEPDIR)/libluatex_a-lfontlib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lfontlib.c' object='libluatex_a-lfontlib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lfontlib.o `test -f 'luatexdir/lua/lfontlib.c' || echo '$(srcdir)/'`luatexdir/lua/lfontlib.c
+
+libluatex_a-lfontlib.obj: luatexdir/lua/lfontlib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lfontlib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lfontlib.Tpo -c -o libluatex_a-lfontlib.obj `if test -f 'luatexdir/lua/lfontlib.c'; then $(CYGPATH_W) 'luatexdir/lua/lfontlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lfontlib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lfontlib.Tpo $(DEPDIR)/libluatex_a-lfontlib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lfontlib.c' object='libluatex_a-lfontlib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lfontlib.obj `if test -f 'luatexdir/lua/lfontlib.c'; then $(CYGPATH_W) 'luatexdir/lua/lfontlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lfontlib.c'; fi`
+
+libluatex_a-limglib.o: luatexdir/lua/limglib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-limglib.o -MD -MP -MF $(DEPDIR)/libluatex_a-limglib.Tpo -c -o libluatex_a-limglib.o `test -f 'luatexdir/lua/limglib.c' || echo '$(srcdir)/'`luatexdir/lua/limglib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-limglib.Tpo $(DEPDIR)/libluatex_a-limglib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/limglib.c' object='libluatex_a-limglib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-limglib.o `test -f 'luatexdir/lua/limglib.c' || echo '$(srcdir)/'`luatexdir/lua/limglib.c
+
+libluatex_a-limglib.obj: luatexdir/lua/limglib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-limglib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-limglib.Tpo -c -o libluatex_a-limglib.obj `if test -f 'luatexdir/lua/limglib.c'; then $(CYGPATH_W) 'luatexdir/lua/limglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/limglib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-limglib.Tpo $(DEPDIR)/libluatex_a-limglib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/limglib.c' object='libluatex_a-limglib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-limglib.obj `if test -f 'luatexdir/lua/limglib.c'; then $(CYGPATH_W) 'luatexdir/lua/limglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/limglib.c'; fi`
+
+libluatex_a-lkpselib.o: luatexdir/lua/lkpselib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lkpselib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lkpselib.Tpo -c -o libluatex_a-lkpselib.o `test -f 'luatexdir/lua/lkpselib.c' || echo '$(srcdir)/'`luatexdir/lua/lkpselib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lkpselib.Tpo $(DEPDIR)/libluatex_a-lkpselib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lkpselib.c' object='libluatex_a-lkpselib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lkpselib.o `test -f 'luatexdir/lua/lkpselib.c' || echo '$(srcdir)/'`luatexdir/lua/lkpselib.c
+
+libluatex_a-lkpselib.obj: luatexdir/lua/lkpselib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lkpselib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lkpselib.Tpo -c -o libluatex_a-lkpselib.obj `if test -f 'luatexdir/lua/lkpselib.c'; then $(CYGPATH_W) 'luatexdir/lua/lkpselib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lkpselib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lkpselib.Tpo $(DEPDIR)/libluatex_a-lkpselib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lkpselib.c' object='libluatex_a-lkpselib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lkpselib.obj `if test -f 'luatexdir/lua/lkpselib.c'; then $(CYGPATH_W) 'luatexdir/lua/lkpselib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lkpselib.c'; fi`
+
+libluatex_a-llanglib.o: luatexdir/lua/llanglib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llanglib.o -MD -MP -MF $(DEPDIR)/libluatex_a-llanglib.Tpo -c -o libluatex_a-llanglib.o `test -f 'luatexdir/lua/llanglib.c' || echo '$(srcdir)/'`luatexdir/lua/llanglib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llanglib.Tpo $(DEPDIR)/libluatex_a-llanglib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llanglib.c' object='libluatex_a-llanglib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llanglib.o `test -f 'luatexdir/lua/llanglib.c' || echo '$(srcdir)/'`luatexdir/lua/llanglib.c
+
+libluatex_a-llanglib.obj: luatexdir/lua/llanglib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llanglib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-llanglib.Tpo -c -o libluatex_a-llanglib.obj `if test -f 'luatexdir/lua/llanglib.c'; then $(CYGPATH_W) 'luatexdir/lua/llanglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llanglib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llanglib.Tpo $(DEPDIR)/libluatex_a-llanglib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llanglib.c' object='libluatex_a-llanglib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llanglib.obj `if test -f 'luatexdir/lua/llanglib.c'; then $(CYGPATH_W) 'luatexdir/lua/llanglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llanglib.c'; fi`
+
+libluatex_a-llualib.o: luatexdir/lua/llualib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llualib.o -MD -MP -MF $(DEPDIR)/libluatex_a-llualib.Tpo -c -o libluatex_a-llualib.o `test -f 'luatexdir/lua/llualib.c' || echo '$(srcdir)/'`luatexdir/lua/llualib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llualib.Tpo $(DEPDIR)/libluatex_a-llualib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llualib.c' object='libluatex_a-llualib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llualib.o `test -f 'luatexdir/lua/llualib.c' || echo '$(srcdir)/'`luatexdir/lua/llualib.c
+
+libluatex_a-llualib.obj: luatexdir/lua/llualib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llualib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-llualib.Tpo -c -o libluatex_a-llualib.obj `if test -f 'luatexdir/lua/llualib.c'; then $(CYGPATH_W) 'luatexdir/lua/llualib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llualib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llualib.Tpo $(DEPDIR)/libluatex_a-llualib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llualib.c' object='libluatex_a-llualib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llualib.obj `if test -f 'luatexdir/lua/llualib.c'; then $(CYGPATH_W) 'luatexdir/lua/llualib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llualib.c'; fi`
+
+libluatex_a-lnodelib.o: luatexdir/lua/lnodelib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lnodelib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lnodelib.Tpo -c -o libluatex_a-lnodelib.o `test -f 'luatexdir/lua/lnodelib.c' || echo '$(srcdir)/'`luatexdir/lua/lnodelib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lnodelib.Tpo $(DEPDIR)/libluatex_a-lnodelib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lnodelib.c' object='libluatex_a-lnodelib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lnodelib.o `test -f 'luatexdir/lua/lnodelib.c' || echo '$(srcdir)/'`luatexdir/lua/lnodelib.c
+
+libluatex_a-lnodelib.obj: luatexdir/lua/lnodelib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lnodelib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lnodelib.Tpo -c -o libluatex_a-lnodelib.obj `if test -f 'luatexdir/lua/lnodelib.c'; then $(CYGPATH_W) 'luatexdir/lua/lnodelib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lnodelib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lnodelib.Tpo $(DEPDIR)/libluatex_a-lnodelib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lnodelib.c' object='libluatex_a-lnodelib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lnodelib.obj `if test -f 'luatexdir/lua/lnodelib.c'; then $(CYGPATH_W) 'luatexdir/lua/lnodelib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lnodelib.c'; fi`
+
+libluatex_a-loslibext.o: luatexdir/lua/loslibext.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-loslibext.o -MD -MP -MF $(DEPDIR)/libluatex_a-loslibext.Tpo -c -o libluatex_a-loslibext.o `test -f 'luatexdir/lua/loslibext.c' || echo '$(srcdir)/'`luatexdir/lua/loslibext.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-loslibext.Tpo $(DEPDIR)/libluatex_a-loslibext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/loslibext.c' object='libluatex_a-loslibext.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-loslibext.o `test -f 'luatexdir/lua/loslibext.c' || echo '$(srcdir)/'`luatexdir/lua/loslibext.c
+
+libluatex_a-loslibext.obj: luatexdir/lua/loslibext.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-loslibext.obj -MD -MP -MF $(DEPDIR)/libluatex_a-loslibext.Tpo -c -o libluatex_a-loslibext.obj `if test -f 'luatexdir/lua/loslibext.c'; then $(CYGPATH_W) 'luatexdir/lua/loslibext.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/loslibext.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-loslibext.Tpo $(DEPDIR)/libluatex_a-loslibext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/loslibext.c' object='libluatex_a-loslibext.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-loslibext.obj `if test -f 'luatexdir/lua/loslibext.c'; then $(CYGPATH_W) 'luatexdir/lua/loslibext.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/loslibext.c'; fi`
+
+libluatex_a-liolib.o: luatexdir/lua/liolib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-liolib.o -MD -MP -MF $(DEPDIR)/libluatex_a-liolib.Tpo -c -o libluatex_a-liolib.o `test -f 'luatexdir/lua/liolib.c' || echo '$(srcdir)/'`luatexdir/lua/liolib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-liolib.Tpo $(DEPDIR)/libluatex_a-liolib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/liolib.c' object='libluatex_a-liolib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-liolib.o `test -f 'luatexdir/lua/liolib.c' || echo '$(srcdir)/'`luatexdir/lua/liolib.c
+
+libluatex_a-liolib.obj: luatexdir/lua/liolib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-liolib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-liolib.Tpo -c -o libluatex_a-liolib.obj `if test -f 'luatexdir/lua/liolib.c'; then $(CYGPATH_W) 'luatexdir/lua/liolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/liolib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-liolib.Tpo $(DEPDIR)/libluatex_a-liolib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/liolib.c' object='libluatex_a-liolib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-liolib.obj `if test -f 'luatexdir/lua/liolib.c'; then $(CYGPATH_W) 'luatexdir/lua/liolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/liolib.c'; fi`
+
+libluatex_a-lpdflib.o: luatexdir/lua/lpdflib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lpdflib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lpdflib.Tpo -c -o libluatex_a-lpdflib.o `test -f 'luatexdir/lua/lpdflib.c' || echo '$(srcdir)/'`luatexdir/lua/lpdflib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lpdflib.Tpo $(DEPDIR)/libluatex_a-lpdflib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lpdflib.c' object='libluatex_a-lpdflib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lpdflib.o `test -f 'luatexdir/lua/lpdflib.c' || echo '$(srcdir)/'`luatexdir/lua/lpdflib.c
+
+libluatex_a-lpdflib.obj: luatexdir/lua/lpdflib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lpdflib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lpdflib.Tpo -c -o libluatex_a-lpdflib.obj `if test -f 'luatexdir/lua/lpdflib.c'; then $(CYGPATH_W) 'luatexdir/lua/lpdflib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lpdflib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lpdflib.Tpo $(DEPDIR)/libluatex_a-lpdflib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lpdflib.c' object='libluatex_a-lpdflib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lpdflib.obj `if test -f 'luatexdir/lua/lpdflib.c'; then $(CYGPATH_W) 'luatexdir/lua/lpdflib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lpdflib.c'; fi`
+
+libluatex_a-lstatslib.o: luatexdir/lua/lstatslib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lstatslib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lstatslib.Tpo -c -o libluatex_a-lstatslib.o `test -f 'luatexdir/lua/lstatslib.c' || echo '$(srcdir)/'`luatexdir/lua/lstatslib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lstatslib.Tpo $(DEPDIR)/libluatex_a-lstatslib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lstatslib.c' object='libluatex_a-lstatslib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lstatslib.o `test -f 'luatexdir/lua/lstatslib.c' || echo '$(srcdir)/'`luatexdir/lua/lstatslib.c
+
+libluatex_a-lstatslib.obj: luatexdir/lua/lstatslib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lstatslib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lstatslib.Tpo -c -o libluatex_a-lstatslib.obj `if test -f 'luatexdir/lua/lstatslib.c'; then $(CYGPATH_W) 'luatexdir/lua/lstatslib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lstatslib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lstatslib.Tpo $(DEPDIR)/libluatex_a-lstatslib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lstatslib.c' object='libluatex_a-lstatslib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lstatslib.obj `if test -f 'luatexdir/lua/lstatslib.c'; then $(CYGPATH_W) 'luatexdir/lua/lstatslib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lstatslib.c'; fi`
+
+libluatex_a-ltexiolib.o: luatexdir/lua/ltexiolib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexiolib.o -MD -MP -MF $(DEPDIR)/libluatex_a-ltexiolib.Tpo -c -o libluatex_a-ltexiolib.o `test -f 'luatexdir/lua/ltexiolib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexiolib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexiolib.Tpo $(DEPDIR)/libluatex_a-ltexiolib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexiolib.c' object='libluatex_a-ltexiolib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexiolib.o `test -f 'luatexdir/lua/ltexiolib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexiolib.c
+
+libluatex_a-ltexiolib.obj: luatexdir/lua/ltexiolib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexiolib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ltexiolib.Tpo -c -o libluatex_a-ltexiolib.obj `if test -f 'luatexdir/lua/ltexiolib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexiolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexiolib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexiolib.Tpo $(DEPDIR)/libluatex_a-ltexiolib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexiolib.c' object='libluatex_a-ltexiolib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexiolib.obj `if test -f 'luatexdir/lua/ltexiolib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexiolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexiolib.c'; fi`
+
+libluatex_a-ltexlib.o: luatexdir/lua/ltexlib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexlib.o -MD -MP -MF $(DEPDIR)/libluatex_a-ltexlib.Tpo -c -o libluatex_a-ltexlib.o `test -f 'luatexdir/lua/ltexlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexlib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexlib.Tpo $(DEPDIR)/libluatex_a-ltexlib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexlib.c' object='libluatex_a-ltexlib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexlib.o `test -f 'luatexdir/lua/ltexlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexlib.c
+
+libluatex_a-ltexlib.obj: luatexdir/lua/ltexlib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexlib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ltexlib.Tpo -c -o libluatex_a-ltexlib.obj `if test -f 'luatexdir/lua/ltexlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexlib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexlib.Tpo $(DEPDIR)/libluatex_a-ltexlib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexlib.c' object='libluatex_a-ltexlib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexlib.obj `if test -f 'luatexdir/lua/ltexlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexlib.c'; fi`
+
+libluatex_a-ltokenlib.o: luatexdir/lua/ltokenlib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltokenlib.o -MD -MP -MF $(DEPDIR)/libluatex_a-ltokenlib.Tpo -c -o libluatex_a-ltokenlib.o `test -f 'luatexdir/lua/ltokenlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltokenlib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltokenlib.Tpo $(DEPDIR)/libluatex_a-ltokenlib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltokenlib.c' object='libluatex_a-ltokenlib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltokenlib.o `test -f 'luatexdir/lua/ltokenlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltokenlib.c
+
+libluatex_a-ltokenlib.obj: luatexdir/lua/ltokenlib.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltokenlib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ltokenlib.Tpo -c -o libluatex_a-ltokenlib.obj `if test -f 'luatexdir/lua/ltokenlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltokenlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltokenlib.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltokenlib.Tpo $(DEPDIR)/libluatex_a-ltokenlib.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltokenlib.c' object='libluatex_a-ltokenlib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltokenlib.obj `if test -f 'luatexdir/lua/ltokenlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltokenlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltokenlib.c'; fi`
+
+libluatex_a-avl.o: luatexdir/utils/avl.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avl.o -MD -MP -MF $(DEPDIR)/libluatex_a-avl.Tpo -c -o libluatex_a-avl.o `test -f 'luatexdir/utils/avl.c' || echo '$(srcdir)/'`luatexdir/utils/avl.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avl.Tpo $(DEPDIR)/libluatex_a-avl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/avl.c' object='libluatex_a-avl.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avl.o `test -f 'luatexdir/utils/avl.c' || echo '$(srcdir)/'`luatexdir/utils/avl.c
+
+libluatex_a-avl.obj: luatexdir/utils/avl.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avl.obj -MD -MP -MF $(DEPDIR)/libluatex_a-avl.Tpo -c -o libluatex_a-avl.obj `if test -f 'luatexdir/utils/avl.c'; then $(CYGPATH_W) 'luatexdir/utils/avl.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/avl.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avl.Tpo $(DEPDIR)/libluatex_a-avl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/avl.c' object='libluatex_a-avl.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avl.obj `if test -f 'luatexdir/utils/avl.c'; then $(CYGPATH_W) 'luatexdir/utils/avl.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/avl.c'; fi`
+
+libluatex_a-synctex.o: luatexdir/utils/synctex.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-synctex.o -MD -MP -MF $(DEPDIR)/libluatex_a-synctex.Tpo -c -o libluatex_a-synctex.o `test -f 'luatexdir/utils/synctex.c' || echo '$(srcdir)/'`luatexdir/utils/synctex.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-synctex.Tpo $(DEPDIR)/libluatex_a-synctex.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/synctex.c' object='libluatex_a-synctex.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-synctex.o `test -f 'luatexdir/utils/synctex.c' || echo '$(srcdir)/'`luatexdir/utils/synctex.c
+
+libluatex_a-synctex.obj: luatexdir/utils/synctex.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-synctex.obj -MD -MP -MF $(DEPDIR)/libluatex_a-synctex.Tpo -c -o libluatex_a-synctex.obj `if test -f 'luatexdir/utils/synctex.c'; then $(CYGPATH_W) 'luatexdir/utils/synctex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/synctex.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-synctex.Tpo $(DEPDIR)/libluatex_a-synctex.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/synctex.c' object='libluatex_a-synctex.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-synctex.obj `if test -f 'luatexdir/utils/synctex.c'; then $(CYGPATH_W) 'luatexdir/utils/synctex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/synctex.c'; fi`
+
+libluatex_a-dvigen.o: dvigen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dvigen.o -MD -MP -MF $(DEPDIR)/libluatex_a-dvigen.Tpo -c -o libluatex_a-dvigen.o `test -f 'dvigen.c' || echo '$(srcdir)/'`dvigen.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-dvigen.Tpo $(DEPDIR)/libluatex_a-dvigen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dvigen.c' object='libluatex_a-dvigen.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dvigen.o `test -f 'dvigen.c' || echo '$(srcdir)/'`dvigen.c
+
+libluatex_a-dvigen.obj: dvigen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dvigen.obj -MD -MP -MF $(DEPDIR)/libluatex_a-dvigen.Tpo -c -o libluatex_a-dvigen.obj `if test -f 'dvigen.c'; then $(CYGPATH_W) 'dvigen.c'; else $(CYGPATH_W) '$(srcdir)/dvigen.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-dvigen.Tpo $(DEPDIR)/libluatex_a-dvigen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dvigen.c' object='libluatex_a-dvigen.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dvigen.obj `if test -f 'dvigen.c'; then $(CYGPATH_W) 'dvigen.c'; else $(CYGPATH_W) '$(srcdir)/dvigen.c'; fi`
+
+libluatex_a-dofont.o: dofont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dofont.o -MD -MP -MF $(DEPDIR)/libluatex_a-dofont.Tpo -c -o libluatex_a-dofont.o `test -f 'dofont.c' || echo '$(srcdir)/'`dofont.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-dofont.Tpo $(DEPDIR)/libluatex_a-dofont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/dofont.c' object='libluatex_a-dofont.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dofont.c' object='libluatex_a-dofont.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dofont.o `test -f 'luatexdir/font/dofont.c' || echo '$(srcdir)/'`luatexdir/font/dofont.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dofont.o `test -f 'dofont.c' || echo '$(srcdir)/'`dofont.c
-libluatex_a-dofont.obj: luatexdir/font/dofont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dofont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-dofont.Tpo -c -o libluatex_a-dofont.obj `if test -f 'luatexdir/font/dofont.c'; then $(CYGPATH_W) 'luatexdir/font/dofont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/dofont.c'; fi`
+libluatex_a-dofont.obj: dofont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dofont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-dofont.Tpo -c -o libluatex_a-dofont.obj `if test -f 'dofont.c'; then $(CYGPATH_W) 'dofont.c'; else $(CYGPATH_W) '$(srcdir)/dofont.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-dofont.Tpo $(DEPDIR)/libluatex_a-dofont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/dofont.c' object='libluatex_a-dofont.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dofont.c' object='libluatex_a-dofont.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dofont.obj `if test -f 'luatexdir/font/dofont.c'; then $(CYGPATH_W) 'luatexdir/font/dofont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/dofont.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dofont.obj `if test -f 'dofont.c'; then $(CYGPATH_W) 'dofont.c'; else $(CYGPATH_W) '$(srcdir)/dofont.c'; fi`
-libluatex_a-luafont.o: luatexdir/font/luafont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luafont.o -MD -MP -MF $(DEPDIR)/libluatex_a-luafont.Tpo -c -o libluatex_a-luafont.o `test -f 'luatexdir/font/luafont.c' || echo '$(srcdir)/'`luatexdir/font/luafont.c
+libluatex_a-luafont.o: luafont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luafont.o -MD -MP -MF $(DEPDIR)/libluatex_a-luafont.Tpo -c -o libluatex_a-luafont.o `test -f 'luafont.c' || echo '$(srcdir)/'`luafont.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luafont.Tpo $(DEPDIR)/libluatex_a-luafont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/luafont.c' object='libluatex_a-luafont.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luafont.c' object='libluatex_a-luafont.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luafont.o `test -f 'luatexdir/font/luafont.c' || echo '$(srcdir)/'`luatexdir/font/luafont.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luafont.o `test -f 'luafont.c' || echo '$(srcdir)/'`luafont.c
-libluatex_a-luafont.obj: luatexdir/font/luafont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luafont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luafont.Tpo -c -o libluatex_a-luafont.obj `if test -f 'luatexdir/font/luafont.c'; then $(CYGPATH_W) 'luatexdir/font/luafont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/luafont.c'; fi`
+libluatex_a-luafont.obj: luafont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luafont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luafont.Tpo -c -o libluatex_a-luafont.obj `if test -f 'luafont.c'; then $(CYGPATH_W) 'luafont.c'; else $(CYGPATH_W) '$(srcdir)/luafont.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luafont.Tpo $(DEPDIR)/libluatex_a-luafont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/luafont.c' object='libluatex_a-luafont.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luafont.c' object='libluatex_a-luafont.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luafont.obj `if test -f 'luatexdir/font/luafont.c'; then $(CYGPATH_W) 'luatexdir/font/luafont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/luafont.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luafont.obj `if test -f 'luafont.c'; then $(CYGPATH_W) 'luafont.c'; else $(CYGPATH_W) '$(srcdir)/luafont.c'; fi`
-libluatex_a-mapfile.o: luatexdir/font/mapfile.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mapfile.o -MD -MP -MF $(DEPDIR)/libluatex_a-mapfile.Tpo -c -o libluatex_a-mapfile.o `test -f 'luatexdir/font/mapfile.c' || echo '$(srcdir)/'`luatexdir/font/mapfile.c
+libluatex_a-mapfile.o: mapfile.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mapfile.o -MD -MP -MF $(DEPDIR)/libluatex_a-mapfile.Tpo -c -o libluatex_a-mapfile.o `test -f 'mapfile.c' || echo '$(srcdir)/'`mapfile.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mapfile.Tpo $(DEPDIR)/libluatex_a-mapfile.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/mapfile.c' object='libluatex_a-mapfile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mapfile.c' object='libluatex_a-mapfile.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mapfile.o `test -f 'luatexdir/font/mapfile.c' || echo '$(srcdir)/'`luatexdir/font/mapfile.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mapfile.o `test -f 'mapfile.c' || echo '$(srcdir)/'`mapfile.c
-libluatex_a-mapfile.obj: luatexdir/font/mapfile.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mapfile.obj -MD -MP -MF $(DEPDIR)/libluatex_a-mapfile.Tpo -c -o libluatex_a-mapfile.obj `if test -f 'luatexdir/font/mapfile.c'; then $(CYGPATH_W) 'luatexdir/font/mapfile.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/mapfile.c'; fi`
+libluatex_a-mapfile.obj: mapfile.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mapfile.obj -MD -MP -MF $(DEPDIR)/libluatex_a-mapfile.Tpo -c -o libluatex_a-mapfile.obj `if test -f 'mapfile.c'; then $(CYGPATH_W) 'mapfile.c'; else $(CYGPATH_W) '$(srcdir)/mapfile.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mapfile.Tpo $(DEPDIR)/libluatex_a-mapfile.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/mapfile.c' object='libluatex_a-mapfile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mapfile.c' object='libluatex_a-mapfile.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mapfile.obj `if test -f 'luatexdir/font/mapfile.c'; then $(CYGPATH_W) 'luatexdir/font/mapfile.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/mapfile.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mapfile.obj `if test -f 'mapfile.c'; then $(CYGPATH_W) 'mapfile.c'; else $(CYGPATH_W) '$(srcdir)/mapfile.c'; fi`
-libluatex_a-pkin.o: luatexdir/font/pkin.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pkin.o -MD -MP -MF $(DEPDIR)/libluatex_a-pkin.Tpo -c -o libluatex_a-pkin.o `test -f 'luatexdir/font/pkin.c' || echo '$(srcdir)/'`luatexdir/font/pkin.c
+libluatex_a-pkin.o: pkin.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pkin.o -MD -MP -MF $(DEPDIR)/libluatex_a-pkin.Tpo -c -o libluatex_a-pkin.o `test -f 'pkin.c' || echo '$(srcdir)/'`pkin.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pkin.Tpo $(DEPDIR)/libluatex_a-pkin.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/pkin.c' object='libluatex_a-pkin.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pkin.c' object='libluatex_a-pkin.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pkin.o `test -f 'luatexdir/font/pkin.c' || echo '$(srcdir)/'`luatexdir/font/pkin.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pkin.o `test -f 'pkin.c' || echo '$(srcdir)/'`pkin.c
-libluatex_a-pkin.obj: luatexdir/font/pkin.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pkin.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pkin.Tpo -c -o libluatex_a-pkin.obj `if test -f 'luatexdir/font/pkin.c'; then $(CYGPATH_W) 'luatexdir/font/pkin.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/pkin.c'; fi`
+libluatex_a-pkin.obj: pkin.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pkin.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pkin.Tpo -c -o libluatex_a-pkin.obj `if test -f 'pkin.c'; then $(CYGPATH_W) 'pkin.c'; else $(CYGPATH_W) '$(srcdir)/pkin.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pkin.Tpo $(DEPDIR)/libluatex_a-pkin.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/pkin.c' object='libluatex_a-pkin.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pkin.c' object='libluatex_a-pkin.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pkin.obj `if test -f 'luatexdir/font/pkin.c'; then $(CYGPATH_W) 'luatexdir/font/pkin.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/pkin.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pkin.obj `if test -f 'pkin.c'; then $(CYGPATH_W) 'pkin.c'; else $(CYGPATH_W) '$(srcdir)/pkin.c'; fi`
-libluatex_a-sfnt.o: luatexdir/font/sfnt.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-sfnt.o -MD -MP -MF $(DEPDIR)/libluatex_a-sfnt.Tpo -c -o libluatex_a-sfnt.o `test -f 'luatexdir/font/sfnt.c' || echo '$(srcdir)/'`luatexdir/font/sfnt.c
+libluatex_a-sfnt.o: sfnt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-sfnt.o -MD -MP -MF $(DEPDIR)/libluatex_a-sfnt.Tpo -c -o libluatex_a-sfnt.o `test -f 'sfnt.c' || echo '$(srcdir)/'`sfnt.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-sfnt.Tpo $(DEPDIR)/libluatex_a-sfnt.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/sfnt.c' object='libluatex_a-sfnt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sfnt.c' object='libluatex_a-sfnt.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-sfnt.o `test -f 'luatexdir/font/sfnt.c' || echo '$(srcdir)/'`luatexdir/font/sfnt.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-sfnt.o `test -f 'sfnt.c' || echo '$(srcdir)/'`sfnt.c
-libluatex_a-sfnt.obj: luatexdir/font/sfnt.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-sfnt.obj -MD -MP -MF $(DEPDIR)/libluatex_a-sfnt.Tpo -c -o libluatex_a-sfnt.obj `if test -f 'luatexdir/font/sfnt.c'; then $(CYGPATH_W) 'luatexdir/font/sfnt.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/sfnt.c'; fi`
+libluatex_a-sfnt.obj: sfnt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-sfnt.obj -MD -MP -MF $(DEPDIR)/libluatex_a-sfnt.Tpo -c -o libluatex_a-sfnt.obj `if test -f 'sfnt.c'; then $(CYGPATH_W) 'sfnt.c'; else $(CYGPATH_W) '$(srcdir)/sfnt.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-sfnt.Tpo $(DEPDIR)/libluatex_a-sfnt.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/sfnt.c' object='libluatex_a-sfnt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sfnt.c' object='libluatex_a-sfnt.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-sfnt.obj `if test -f 'luatexdir/font/sfnt.c'; then $(CYGPATH_W) 'luatexdir/font/sfnt.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/sfnt.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-sfnt.obj `if test -f 'sfnt.c'; then $(CYGPATH_W) 'sfnt.c'; else $(CYGPATH_W) '$(srcdir)/sfnt.c'; fi`
-libluatex_a-subfont.o: luatexdir/font/subfont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-subfont.o -MD -MP -MF $(DEPDIR)/libluatex_a-subfont.Tpo -c -o libluatex_a-subfont.o `test -f 'luatexdir/font/subfont.c' || echo '$(srcdir)/'`luatexdir/font/subfont.c
+libluatex_a-subfont.o: subfont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-subfont.o -MD -MP -MF $(DEPDIR)/libluatex_a-subfont.Tpo -c -o libluatex_a-subfont.o `test -f 'subfont.c' || echo '$(srcdir)/'`subfont.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-subfont.Tpo $(DEPDIR)/libluatex_a-subfont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/subfont.c' object='libluatex_a-subfont.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='subfont.c' object='libluatex_a-subfont.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-subfont.o `test -f 'luatexdir/font/subfont.c' || echo '$(srcdir)/'`luatexdir/font/subfont.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-subfont.o `test -f 'subfont.c' || echo '$(srcdir)/'`subfont.c
-libluatex_a-subfont.obj: luatexdir/font/subfont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-subfont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-subfont.Tpo -c -o libluatex_a-subfont.obj `if test -f 'luatexdir/font/subfont.c'; then $(CYGPATH_W) 'luatexdir/font/subfont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/subfont.c'; fi`
+libluatex_a-subfont.obj: subfont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-subfont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-subfont.Tpo -c -o libluatex_a-subfont.obj `if test -f 'subfont.c'; then $(CYGPATH_W) 'subfont.c'; else $(CYGPATH_W) '$(srcdir)/subfont.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-subfont.Tpo $(DEPDIR)/libluatex_a-subfont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/subfont.c' object='libluatex_a-subfont.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='subfont.c' object='libluatex_a-subfont.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-subfont.obj `if test -f 'luatexdir/font/subfont.c'; then $(CYGPATH_W) 'luatexdir/font/subfont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/subfont.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-subfont.obj `if test -f 'subfont.c'; then $(CYGPATH_W) 'subfont.c'; else $(CYGPATH_W) '$(srcdir)/subfont.c'; fi`
-libluatex_a-texfont.o: luatexdir/font/texfont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texfont.o -MD -MP -MF $(DEPDIR)/libluatex_a-texfont.Tpo -c -o libluatex_a-texfont.o `test -f 'luatexdir/font/texfont.c' || echo '$(srcdir)/'`luatexdir/font/texfont.c
+libluatex_a-texfont.o: texfont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texfont.o -MD -MP -MF $(DEPDIR)/libluatex_a-texfont.Tpo -c -o libluatex_a-texfont.o `test -f 'texfont.c' || echo '$(srcdir)/'`texfont.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texfont.Tpo $(DEPDIR)/libluatex_a-texfont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/texfont.c' object='libluatex_a-texfont.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texfont.c' object='libluatex_a-texfont.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texfont.o `test -f 'luatexdir/font/texfont.c' || echo '$(srcdir)/'`luatexdir/font/texfont.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texfont.o `test -f 'texfont.c' || echo '$(srcdir)/'`texfont.c
-libluatex_a-texfont.obj: luatexdir/font/texfont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texfont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texfont.Tpo -c -o libluatex_a-texfont.obj `if test -f 'luatexdir/font/texfont.c'; then $(CYGPATH_W) 'luatexdir/font/texfont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/texfont.c'; fi`
+libluatex_a-texfont.obj: texfont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texfont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texfont.Tpo -c -o libluatex_a-texfont.obj `if test -f 'texfont.c'; then $(CYGPATH_W) 'texfont.c'; else $(CYGPATH_W) '$(srcdir)/texfont.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texfont.Tpo $(DEPDIR)/libluatex_a-texfont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/texfont.c' object='libluatex_a-texfont.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texfont.c' object='libluatex_a-texfont.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texfont.obj `if test -f 'luatexdir/font/texfont.c'; then $(CYGPATH_W) 'luatexdir/font/texfont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/texfont.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texfont.obj `if test -f 'texfont.c'; then $(CYGPATH_W) 'texfont.c'; else $(CYGPATH_W) '$(srcdir)/texfont.c'; fi`
-libluatex_a-tfmofm.o: luatexdir/font/tfmofm.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tfmofm.o -MD -MP -MF $(DEPDIR)/libluatex_a-tfmofm.Tpo -c -o libluatex_a-tfmofm.o `test -f 'luatexdir/font/tfmofm.c' || echo '$(srcdir)/'`luatexdir/font/tfmofm.c
+libluatex_a-tfmofm.o: tfmofm.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tfmofm.o -MD -MP -MF $(DEPDIR)/libluatex_a-tfmofm.Tpo -c -o libluatex_a-tfmofm.o `test -f 'tfmofm.c' || echo '$(srcdir)/'`tfmofm.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tfmofm.Tpo $(DEPDIR)/libluatex_a-tfmofm.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tfmofm.c' object='libluatex_a-tfmofm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tfmofm.c' object='libluatex_a-tfmofm.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tfmofm.o `test -f 'luatexdir/font/tfmofm.c' || echo '$(srcdir)/'`luatexdir/font/tfmofm.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tfmofm.o `test -f 'tfmofm.c' || echo '$(srcdir)/'`tfmofm.c
-libluatex_a-tfmofm.obj: luatexdir/font/tfmofm.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tfmofm.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tfmofm.Tpo -c -o libluatex_a-tfmofm.obj `if test -f 'luatexdir/font/tfmofm.c'; then $(CYGPATH_W) 'luatexdir/font/tfmofm.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tfmofm.c'; fi`
+libluatex_a-tfmofm.obj: tfmofm.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tfmofm.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tfmofm.Tpo -c -o libluatex_a-tfmofm.obj `if test -f 'tfmofm.c'; then $(CYGPATH_W) 'tfmofm.c'; else $(CYGPATH_W) '$(srcdir)/tfmofm.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tfmofm.Tpo $(DEPDIR)/libluatex_a-tfmofm.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tfmofm.c' object='libluatex_a-tfmofm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tfmofm.c' object='libluatex_a-tfmofm.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tfmofm.obj `if test -f 'luatexdir/font/tfmofm.c'; then $(CYGPATH_W) 'luatexdir/font/tfmofm.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tfmofm.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tfmofm.obj `if test -f 'tfmofm.c'; then $(CYGPATH_W) 'tfmofm.c'; else $(CYGPATH_W) '$(srcdir)/tfmofm.c'; fi`
-libluatex_a-tounicode.o: luatexdir/font/tounicode.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tounicode.o -MD -MP -MF $(DEPDIR)/libluatex_a-tounicode.Tpo -c -o libluatex_a-tounicode.o `test -f 'luatexdir/font/tounicode.c' || echo '$(srcdir)/'`luatexdir/font/tounicode.c
+libluatex_a-tounicode.o: tounicode.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tounicode.o -MD -MP -MF $(DEPDIR)/libluatex_a-tounicode.Tpo -c -o libluatex_a-tounicode.o `test -f 'tounicode.c' || echo '$(srcdir)/'`tounicode.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tounicode.Tpo $(DEPDIR)/libluatex_a-tounicode.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tounicode.c' object='libluatex_a-tounicode.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tounicode.c' object='libluatex_a-tounicode.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tounicode.o `test -f 'luatexdir/font/tounicode.c' || echo '$(srcdir)/'`luatexdir/font/tounicode.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tounicode.o `test -f 'tounicode.c' || echo '$(srcdir)/'`tounicode.c
-libluatex_a-tounicode.obj: luatexdir/font/tounicode.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tounicode.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tounicode.Tpo -c -o libluatex_a-tounicode.obj `if test -f 'luatexdir/font/tounicode.c'; then $(CYGPATH_W) 'luatexdir/font/tounicode.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tounicode.c'; fi`
+libluatex_a-tounicode.obj: tounicode.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tounicode.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tounicode.Tpo -c -o libluatex_a-tounicode.obj `if test -f 'tounicode.c'; then $(CYGPATH_W) 'tounicode.c'; else $(CYGPATH_W) '$(srcdir)/tounicode.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tounicode.Tpo $(DEPDIR)/libluatex_a-tounicode.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tounicode.c' object='libluatex_a-tounicode.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tounicode.c' object='libluatex_a-tounicode.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tounicode.obj `if test -f 'luatexdir/font/tounicode.c'; then $(CYGPATH_W) 'luatexdir/font/tounicode.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tounicode.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tounicode.obj `if test -f 'tounicode.c'; then $(CYGPATH_W) 'tounicode.c'; else $(CYGPATH_W) '$(srcdir)/tounicode.c'; fi`
-libluatex_a-tt_glyf.o: luatexdir/font/tt_glyf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_glyf.o -MD -MP -MF $(DEPDIR)/libluatex_a-tt_glyf.Tpo -c -o libluatex_a-tt_glyf.o `test -f 'luatexdir/font/tt_glyf.c' || echo '$(srcdir)/'`luatexdir/font/tt_glyf.c
+libluatex_a-tt_glyf.o: tt_glyf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_glyf.o -MD -MP -MF $(DEPDIR)/libluatex_a-tt_glyf.Tpo -c -o libluatex_a-tt_glyf.o `test -f 'tt_glyf.c' || echo '$(srcdir)/'`tt_glyf.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tt_glyf.Tpo $(DEPDIR)/libluatex_a-tt_glyf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tt_glyf.c' object='libluatex_a-tt_glyf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tt_glyf.c' object='libluatex_a-tt_glyf.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_glyf.o `test -f 'luatexdir/font/tt_glyf.c' || echo '$(srcdir)/'`luatexdir/font/tt_glyf.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_glyf.o `test -f 'tt_glyf.c' || echo '$(srcdir)/'`tt_glyf.c
-libluatex_a-tt_glyf.obj: luatexdir/font/tt_glyf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_glyf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tt_glyf.Tpo -c -o libluatex_a-tt_glyf.obj `if test -f 'luatexdir/font/tt_glyf.c'; then $(CYGPATH_W) 'luatexdir/font/tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tt_glyf.c'; fi`
+libluatex_a-tt_glyf.obj: tt_glyf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_glyf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tt_glyf.Tpo -c -o libluatex_a-tt_glyf.obj `if test -f 'tt_glyf.c'; then $(CYGPATH_W) 'tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/tt_glyf.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tt_glyf.Tpo $(DEPDIR)/libluatex_a-tt_glyf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tt_glyf.c' object='libluatex_a-tt_glyf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tt_glyf.c' object='libluatex_a-tt_glyf.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_glyf.obj `if test -f 'luatexdir/font/tt_glyf.c'; then $(CYGPATH_W) 'luatexdir/font/tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tt_glyf.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_glyf.obj `if test -f 'tt_glyf.c'; then $(CYGPATH_W) 'tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/tt_glyf.c'; fi`
-libluatex_a-tt_table.o: luatexdir/font/tt_table.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_table.o -MD -MP -MF $(DEPDIR)/libluatex_a-tt_table.Tpo -c -o libluatex_a-tt_table.o `test -f 'luatexdir/font/tt_table.c' || echo '$(srcdir)/'`luatexdir/font/tt_table.c
+libluatex_a-tt_table.o: tt_table.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_table.o -MD -MP -MF $(DEPDIR)/libluatex_a-tt_table.Tpo -c -o libluatex_a-tt_table.o `test -f 'tt_table.c' || echo '$(srcdir)/'`tt_table.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tt_table.Tpo $(DEPDIR)/libluatex_a-tt_table.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tt_table.c' object='libluatex_a-tt_table.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tt_table.c' object='libluatex_a-tt_table.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_table.o `test -f 'luatexdir/font/tt_table.c' || echo '$(srcdir)/'`luatexdir/font/tt_table.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_table.o `test -f 'tt_table.c' || echo '$(srcdir)/'`tt_table.c
-libluatex_a-tt_table.obj: luatexdir/font/tt_table.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_table.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tt_table.Tpo -c -o libluatex_a-tt_table.obj `if test -f 'luatexdir/font/tt_table.c'; then $(CYGPATH_W) 'luatexdir/font/tt_table.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tt_table.c'; fi`
+libluatex_a-tt_table.obj: tt_table.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-tt_table.obj -MD -MP -MF $(DEPDIR)/libluatex_a-tt_table.Tpo -c -o libluatex_a-tt_table.obj `if test -f 'tt_table.c'; then $(CYGPATH_W) 'tt_table.c'; else $(CYGPATH_W) '$(srcdir)/tt_table.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-tt_table.Tpo $(DEPDIR)/libluatex_a-tt_table.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/tt_table.c' object='libluatex_a-tt_table.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tt_table.c' object='libluatex_a-tt_table.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_table.obj `if test -f 'luatexdir/font/tt_table.c'; then $(CYGPATH_W) 'luatexdir/font/tt_table.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/tt_table.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-tt_table.obj `if test -f 'tt_table.c'; then $(CYGPATH_W) 'tt_table.c'; else $(CYGPATH_W) '$(srcdir)/tt_table.c'; fi`
-libluatex_a-vfovf.o: luatexdir/font/vfovf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfovf.o -MD -MP -MF $(DEPDIR)/libluatex_a-vfovf.Tpo -c -o libluatex_a-vfovf.o `test -f 'luatexdir/font/vfovf.c' || echo '$(srcdir)/'`luatexdir/font/vfovf.c
+libluatex_a-vfovf.o: vfovf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfovf.o -MD -MP -MF $(DEPDIR)/libluatex_a-vfovf.Tpo -c -o libluatex_a-vfovf.o `test -f 'vfovf.c' || echo '$(srcdir)/'`vfovf.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-vfovf.Tpo $(DEPDIR)/libluatex_a-vfovf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/vfovf.c' object='libluatex_a-vfovf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vfovf.c' object='libluatex_a-vfovf.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfovf.o `test -f 'luatexdir/font/vfovf.c' || echo '$(srcdir)/'`luatexdir/font/vfovf.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfovf.o `test -f 'vfovf.c' || echo '$(srcdir)/'`vfovf.c
-libluatex_a-vfovf.obj: luatexdir/font/vfovf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfovf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-vfovf.Tpo -c -o libluatex_a-vfovf.obj `if test -f 'luatexdir/font/vfovf.c'; then $(CYGPATH_W) 'luatexdir/font/vfovf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/vfovf.c'; fi`
+libluatex_a-vfovf.obj: vfovf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfovf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-vfovf.Tpo -c -o libluatex_a-vfovf.obj `if test -f 'vfovf.c'; then $(CYGPATH_W) 'vfovf.c'; else $(CYGPATH_W) '$(srcdir)/vfovf.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-vfovf.Tpo $(DEPDIR)/libluatex_a-vfovf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/vfovf.c' object='libluatex_a-vfovf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vfovf.c' object='libluatex_a-vfovf.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfovf.obj `if test -f 'luatexdir/font/vfovf.c'; then $(CYGPATH_W) 'luatexdir/font/vfovf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/vfovf.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfovf.obj `if test -f 'vfovf.c'; then $(CYGPATH_W) 'vfovf.c'; else $(CYGPATH_W) '$(srcdir)/vfovf.c'; fi`
-libluatex_a-vfpacket.o: luatexdir/font/vfpacket.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfpacket.o -MD -MP -MF $(DEPDIR)/libluatex_a-vfpacket.Tpo -c -o libluatex_a-vfpacket.o `test -f 'luatexdir/font/vfpacket.c' || echo '$(srcdir)/'`luatexdir/font/vfpacket.c
+libluatex_a-vfpacket.o: vfpacket.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfpacket.o -MD -MP -MF $(DEPDIR)/libluatex_a-vfpacket.Tpo -c -o libluatex_a-vfpacket.o `test -f 'vfpacket.c' || echo '$(srcdir)/'`vfpacket.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-vfpacket.Tpo $(DEPDIR)/libluatex_a-vfpacket.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/vfpacket.c' object='libluatex_a-vfpacket.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vfpacket.c' object='libluatex_a-vfpacket.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfpacket.o `test -f 'luatexdir/font/vfpacket.c' || echo '$(srcdir)/'`luatexdir/font/vfpacket.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfpacket.o `test -f 'vfpacket.c' || echo '$(srcdir)/'`vfpacket.c
-libluatex_a-vfpacket.obj: luatexdir/font/vfpacket.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfpacket.obj -MD -MP -MF $(DEPDIR)/libluatex_a-vfpacket.Tpo -c -o libluatex_a-vfpacket.obj `if test -f 'luatexdir/font/vfpacket.c'; then $(CYGPATH_W) 'luatexdir/font/vfpacket.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/vfpacket.c'; fi`
+libluatex_a-vfpacket.obj: vfpacket.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-vfpacket.obj -MD -MP -MF $(DEPDIR)/libluatex_a-vfpacket.Tpo -c -o libluatex_a-vfpacket.obj `if test -f 'vfpacket.c'; then $(CYGPATH_W) 'vfpacket.c'; else $(CYGPATH_W) '$(srcdir)/vfpacket.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-vfpacket.Tpo $(DEPDIR)/libluatex_a-vfpacket.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/vfpacket.c' object='libluatex_a-vfpacket.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vfpacket.c' object='libluatex_a-vfpacket.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfpacket.obj `if test -f 'luatexdir/font/vfpacket.c'; then $(CYGPATH_W) 'luatexdir/font/vfpacket.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/vfpacket.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-vfpacket.obj `if test -f 'vfpacket.c'; then $(CYGPATH_W) 'vfpacket.c'; else $(CYGPATH_W) '$(srcdir)/vfpacket.c'; fi`
-libluatex_a-writecff.o: luatexdir/font/writecff.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writecff.o -MD -MP -MF $(DEPDIR)/libluatex_a-writecff.Tpo -c -o libluatex_a-writecff.o `test -f 'luatexdir/font/writecff.c' || echo '$(srcdir)/'`luatexdir/font/writecff.c
+libluatex_a-writecff.o: writecff.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writecff.o -MD -MP -MF $(DEPDIR)/libluatex_a-writecff.Tpo -c -o libluatex_a-writecff.o `test -f 'writecff.c' || echo '$(srcdir)/'`writecff.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writecff.Tpo $(DEPDIR)/libluatex_a-writecff.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writecff.c' object='libluatex_a-writecff.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writecff.c' object='libluatex_a-writecff.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writecff.o `test -f 'luatexdir/font/writecff.c' || echo '$(srcdir)/'`luatexdir/font/writecff.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writecff.o `test -f 'writecff.c' || echo '$(srcdir)/'`writecff.c
-libluatex_a-writecff.obj: luatexdir/font/writecff.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writecff.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writecff.Tpo -c -o libluatex_a-writecff.obj `if test -f 'luatexdir/font/writecff.c'; then $(CYGPATH_W) 'luatexdir/font/writecff.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writecff.c'; fi`
+libluatex_a-writecff.obj: writecff.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writecff.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writecff.Tpo -c -o libluatex_a-writecff.obj `if test -f 'writecff.c'; then $(CYGPATH_W) 'writecff.c'; else $(CYGPATH_W) '$(srcdir)/writecff.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writecff.Tpo $(DEPDIR)/libluatex_a-writecff.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writecff.c' object='libluatex_a-writecff.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writecff.c' object='libluatex_a-writecff.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writecff.obj `if test -f 'luatexdir/font/writecff.c'; then $(CYGPATH_W) 'luatexdir/font/writecff.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writecff.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writecff.obj `if test -f 'writecff.c'; then $(CYGPATH_W) 'writecff.c'; else $(CYGPATH_W) '$(srcdir)/writecff.c'; fi`
-libluatex_a-writeenc.o: luatexdir/font/writeenc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeenc.o -MD -MP -MF $(DEPDIR)/libluatex_a-writeenc.Tpo -c -o libluatex_a-writeenc.o `test -f 'luatexdir/font/writeenc.c' || echo '$(srcdir)/'`luatexdir/font/writeenc.c
+libluatex_a-writeenc.o: writeenc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeenc.o -MD -MP -MF $(DEPDIR)/libluatex_a-writeenc.Tpo -c -o libluatex_a-writeenc.o `test -f 'writeenc.c' || echo '$(srcdir)/'`writeenc.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writeenc.Tpo $(DEPDIR)/libluatex_a-writeenc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writeenc.c' object='libluatex_a-writeenc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeenc.c' object='libluatex_a-writeenc.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeenc.o `test -f 'luatexdir/font/writeenc.c' || echo '$(srcdir)/'`luatexdir/font/writeenc.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeenc.o `test -f 'writeenc.c' || echo '$(srcdir)/'`writeenc.c
-libluatex_a-writeenc.obj: luatexdir/font/writeenc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeenc.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writeenc.Tpo -c -o libluatex_a-writeenc.obj `if test -f 'luatexdir/font/writeenc.c'; then $(CYGPATH_W) 'luatexdir/font/writeenc.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writeenc.c'; fi`
+libluatex_a-writeenc.obj: writeenc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeenc.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writeenc.Tpo -c -o libluatex_a-writeenc.obj `if test -f 'writeenc.c'; then $(CYGPATH_W) 'writeenc.c'; else $(CYGPATH_W) '$(srcdir)/writeenc.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writeenc.Tpo $(DEPDIR)/libluatex_a-writeenc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writeenc.c' object='libluatex_a-writeenc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeenc.c' object='libluatex_a-writeenc.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeenc.obj `if test -f 'luatexdir/font/writeenc.c'; then $(CYGPATH_W) 'luatexdir/font/writeenc.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writeenc.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeenc.obj `if test -f 'writeenc.c'; then $(CYGPATH_W) 'writeenc.c'; else $(CYGPATH_W) '$(srcdir)/writeenc.c'; fi`
-libluatex_a-writefont.o: luatexdir/font/writefont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writefont.o -MD -MP -MF $(DEPDIR)/libluatex_a-writefont.Tpo -c -o libluatex_a-writefont.o `test -f 'luatexdir/font/writefont.c' || echo '$(srcdir)/'`luatexdir/font/writefont.c
+libluatex_a-writefont.o: writefont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writefont.o -MD -MP -MF $(DEPDIR)/libluatex_a-writefont.Tpo -c -o libluatex_a-writefont.o `test -f 'writefont.c' || echo '$(srcdir)/'`writefont.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writefont.Tpo $(DEPDIR)/libluatex_a-writefont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writefont.c' object='libluatex_a-writefont.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writefont.c' object='libluatex_a-writefont.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writefont.o `test -f 'luatexdir/font/writefont.c' || echo '$(srcdir)/'`luatexdir/font/writefont.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writefont.o `test -f 'writefont.c' || echo '$(srcdir)/'`writefont.c
-libluatex_a-writefont.obj: luatexdir/font/writefont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writefont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writefont.Tpo -c -o libluatex_a-writefont.obj `if test -f 'luatexdir/font/writefont.c'; then $(CYGPATH_W) 'luatexdir/font/writefont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writefont.c'; fi`
+libluatex_a-writefont.obj: writefont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writefont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writefont.Tpo -c -o libluatex_a-writefont.obj `if test -f 'writefont.c'; then $(CYGPATH_W) 'writefont.c'; else $(CYGPATH_W) '$(srcdir)/writefont.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writefont.Tpo $(DEPDIR)/libluatex_a-writefont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writefont.c' object='libluatex_a-writefont.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writefont.c' object='libluatex_a-writefont.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writefont.obj `if test -f 'luatexdir/font/writefont.c'; then $(CYGPATH_W) 'luatexdir/font/writefont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writefont.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writefont.obj `if test -f 'writefont.c'; then $(CYGPATH_W) 'writefont.c'; else $(CYGPATH_W) '$(srcdir)/writefont.c'; fi`
-libluatex_a-writet1.o: luatexdir/font/writet1.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet1.o -MD -MP -MF $(DEPDIR)/libluatex_a-writet1.Tpo -c -o libluatex_a-writet1.o `test -f 'luatexdir/font/writet1.c' || echo '$(srcdir)/'`luatexdir/font/writet1.c
+libluatex_a-writet1.o: writet1.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet1.o -MD -MP -MF $(DEPDIR)/libluatex_a-writet1.Tpo -c -o libluatex_a-writet1.o `test -f 'writet1.c' || echo '$(srcdir)/'`writet1.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writet1.Tpo $(DEPDIR)/libluatex_a-writet1.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writet1.c' object='libluatex_a-writet1.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writet1.c' object='libluatex_a-writet1.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet1.o `test -f 'luatexdir/font/writet1.c' || echo '$(srcdir)/'`luatexdir/font/writet1.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet1.o `test -f 'writet1.c' || echo '$(srcdir)/'`writet1.c
-libluatex_a-writet1.obj: luatexdir/font/writet1.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet1.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writet1.Tpo -c -o libluatex_a-writet1.obj `if test -f 'luatexdir/font/writet1.c'; then $(CYGPATH_W) 'luatexdir/font/writet1.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writet1.c'; fi`
+libluatex_a-writet1.obj: writet1.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet1.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writet1.Tpo -c -o libluatex_a-writet1.obj `if test -f 'writet1.c'; then $(CYGPATH_W) 'writet1.c'; else $(CYGPATH_W) '$(srcdir)/writet1.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writet1.Tpo $(DEPDIR)/libluatex_a-writet1.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writet1.c' object='libluatex_a-writet1.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writet1.c' object='libluatex_a-writet1.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet1.obj `if test -f 'luatexdir/font/writet1.c'; then $(CYGPATH_W) 'luatexdir/font/writet1.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writet1.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet1.obj `if test -f 'writet1.c'; then $(CYGPATH_W) 'writet1.c'; else $(CYGPATH_W) '$(srcdir)/writet1.c'; fi`
-libluatex_a-writet3.o: luatexdir/font/writet3.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet3.o -MD -MP -MF $(DEPDIR)/libluatex_a-writet3.Tpo -c -o libluatex_a-writet3.o `test -f 'luatexdir/font/writet3.c' || echo '$(srcdir)/'`luatexdir/font/writet3.c
+libluatex_a-writet3.o: writet3.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet3.o -MD -MP -MF $(DEPDIR)/libluatex_a-writet3.Tpo -c -o libluatex_a-writet3.o `test -f 'writet3.c' || echo '$(srcdir)/'`writet3.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writet3.Tpo $(DEPDIR)/libluatex_a-writet3.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writet3.c' object='libluatex_a-writet3.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writet3.c' object='libluatex_a-writet3.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet3.o `test -f 'luatexdir/font/writet3.c' || echo '$(srcdir)/'`luatexdir/font/writet3.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet3.o `test -f 'writet3.c' || echo '$(srcdir)/'`writet3.c
-libluatex_a-writet3.obj: luatexdir/font/writet3.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet3.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writet3.Tpo -c -o libluatex_a-writet3.obj `if test -f 'luatexdir/font/writet3.c'; then $(CYGPATH_W) 'luatexdir/font/writet3.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writet3.c'; fi`
+libluatex_a-writet3.obj: writet3.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writet3.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writet3.Tpo -c -o libluatex_a-writet3.obj `if test -f 'writet3.c'; then $(CYGPATH_W) 'writet3.c'; else $(CYGPATH_W) '$(srcdir)/writet3.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writet3.Tpo $(DEPDIR)/libluatex_a-writet3.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writet3.c' object='libluatex_a-writet3.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writet3.c' object='libluatex_a-writet3.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet3.obj `if test -f 'luatexdir/font/writet3.c'; then $(CYGPATH_W) 'luatexdir/font/writet3.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writet3.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writet3.obj `if test -f 'writet3.c'; then $(CYGPATH_W) 'writet3.c'; else $(CYGPATH_W) '$(srcdir)/writet3.c'; fi`
-libluatex_a-writettf.o: luatexdir/font/writettf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writettf.o -MD -MP -MF $(DEPDIR)/libluatex_a-writettf.Tpo -c -o libluatex_a-writettf.o `test -f 'luatexdir/font/writettf.c' || echo '$(srcdir)/'`luatexdir/font/writettf.c
+libluatex_a-writettf.o: writettf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writettf.o -MD -MP -MF $(DEPDIR)/libluatex_a-writettf.Tpo -c -o libluatex_a-writettf.o `test -f 'writettf.c' || echo '$(srcdir)/'`writettf.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writettf.Tpo $(DEPDIR)/libluatex_a-writettf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writettf.c' object='libluatex_a-writettf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writettf.c' object='libluatex_a-writettf.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writettf.o `test -f 'luatexdir/font/writettf.c' || echo '$(srcdir)/'`luatexdir/font/writettf.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writettf.o `test -f 'writettf.c' || echo '$(srcdir)/'`writettf.c
-libluatex_a-writettf.obj: luatexdir/font/writettf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writettf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writettf.Tpo -c -o libluatex_a-writettf.obj `if test -f 'luatexdir/font/writettf.c'; then $(CYGPATH_W) 'luatexdir/font/writettf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writettf.c'; fi`
+libluatex_a-writettf.obj: writettf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writettf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writettf.Tpo -c -o libluatex_a-writettf.obj `if test -f 'writettf.c'; then $(CYGPATH_W) 'writettf.c'; else $(CYGPATH_W) '$(srcdir)/writettf.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writettf.Tpo $(DEPDIR)/libluatex_a-writettf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writettf.c' object='libluatex_a-writettf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writettf.c' object='libluatex_a-writettf.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writettf.obj `if test -f 'luatexdir/font/writettf.c'; then $(CYGPATH_W) 'luatexdir/font/writettf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writettf.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writettf.obj `if test -f 'writettf.c'; then $(CYGPATH_W) 'writettf.c'; else $(CYGPATH_W) '$(srcdir)/writettf.c'; fi`
-libluatex_a-writetype0.o: luatexdir/font/writetype0.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype0.o -MD -MP -MF $(DEPDIR)/libluatex_a-writetype0.Tpo -c -o libluatex_a-writetype0.o `test -f 'luatexdir/font/writetype0.c' || echo '$(srcdir)/'`luatexdir/font/writetype0.c
+libluatex_a-writetype0.o: writetype0.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype0.o -MD -MP -MF $(DEPDIR)/libluatex_a-writetype0.Tpo -c -o libluatex_a-writetype0.o `test -f 'writetype0.c' || echo '$(srcdir)/'`writetype0.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writetype0.Tpo $(DEPDIR)/libluatex_a-writetype0.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writetype0.c' object='libluatex_a-writetype0.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writetype0.c' object='libluatex_a-writetype0.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype0.o `test -f 'luatexdir/font/writetype0.c' || echo '$(srcdir)/'`luatexdir/font/writetype0.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype0.o `test -f 'writetype0.c' || echo '$(srcdir)/'`writetype0.c
-libluatex_a-writetype0.obj: luatexdir/font/writetype0.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype0.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writetype0.Tpo -c -o libluatex_a-writetype0.obj `if test -f 'luatexdir/font/writetype0.c'; then $(CYGPATH_W) 'luatexdir/font/writetype0.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writetype0.c'; fi`
+libluatex_a-writetype0.obj: writetype0.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype0.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writetype0.Tpo -c -o libluatex_a-writetype0.obj `if test -f 'writetype0.c'; then $(CYGPATH_W) 'writetype0.c'; else $(CYGPATH_W) '$(srcdir)/writetype0.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writetype0.Tpo $(DEPDIR)/libluatex_a-writetype0.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writetype0.c' object='libluatex_a-writetype0.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writetype0.c' object='libluatex_a-writetype0.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype0.obj `if test -f 'luatexdir/font/writetype0.c'; then $(CYGPATH_W) 'luatexdir/font/writetype0.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writetype0.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype0.obj `if test -f 'writetype0.c'; then $(CYGPATH_W) 'writetype0.c'; else $(CYGPATH_W) '$(srcdir)/writetype0.c'; fi`
-libluatex_a-writetype2.o: luatexdir/font/writetype2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype2.o -MD -MP -MF $(DEPDIR)/libluatex_a-writetype2.Tpo -c -o libluatex_a-writetype2.o `test -f 'luatexdir/font/writetype2.c' || echo '$(srcdir)/'`luatexdir/font/writetype2.c
+libluatex_a-writetype2.o: writetype2.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype2.o -MD -MP -MF $(DEPDIR)/libluatex_a-writetype2.Tpo -c -o libluatex_a-writetype2.o `test -f 'writetype2.c' || echo '$(srcdir)/'`writetype2.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writetype2.Tpo $(DEPDIR)/libluatex_a-writetype2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writetype2.c' object='libluatex_a-writetype2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writetype2.c' object='libluatex_a-writetype2.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype2.o `test -f 'luatexdir/font/writetype2.c' || echo '$(srcdir)/'`luatexdir/font/writetype2.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype2.o `test -f 'writetype2.c' || echo '$(srcdir)/'`writetype2.c
-libluatex_a-writetype2.obj: luatexdir/font/writetype2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype2.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writetype2.Tpo -c -o libluatex_a-writetype2.obj `if test -f 'luatexdir/font/writetype2.c'; then $(CYGPATH_W) 'luatexdir/font/writetype2.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writetype2.c'; fi`
+libluatex_a-writetype2.obj: writetype2.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writetype2.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writetype2.Tpo -c -o libluatex_a-writetype2.obj `if test -f 'writetype2.c'; then $(CYGPATH_W) 'writetype2.c'; else $(CYGPATH_W) '$(srcdir)/writetype2.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writetype2.Tpo $(DEPDIR)/libluatex_a-writetype2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/writetype2.c' object='libluatex_a-writetype2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writetype2.c' object='libluatex_a-writetype2.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype2.obj `if test -f 'luatexdir/font/writetype2.c'; then $(CYGPATH_W) 'luatexdir/font/writetype2.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/writetype2.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writetype2.obj `if test -f 'writetype2.c'; then $(CYGPATH_W) 'writetype2.c'; else $(CYGPATH_W) '$(srcdir)/writetype2.c'; fi`
-libluatex_a-epdf.o: luatexdir/image/epdf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-epdf.o -MD -MP -MF $(DEPDIR)/libluatex_a-epdf.Tpo -c -o libluatex_a-epdf.o `test -f 'luatexdir/image/epdf.c' || echo '$(srcdir)/'`luatexdir/image/epdf.c
+libluatex_a-epdf.o: epdf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-epdf.o -MD -MP -MF $(DEPDIR)/libluatex_a-epdf.Tpo -c -o libluatex_a-epdf.o `test -f 'epdf.c' || echo '$(srcdir)/'`epdf.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-epdf.Tpo $(DEPDIR)/libluatex_a-epdf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/epdf.c' object='libluatex_a-epdf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='epdf.c' object='libluatex_a-epdf.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-epdf.o `test -f 'luatexdir/image/epdf.c' || echo '$(srcdir)/'`luatexdir/image/epdf.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-epdf.o `test -f 'epdf.c' || echo '$(srcdir)/'`epdf.c
-libluatex_a-epdf.obj: luatexdir/image/epdf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-epdf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-epdf.Tpo -c -o libluatex_a-epdf.obj `if test -f 'luatexdir/image/epdf.c'; then $(CYGPATH_W) 'luatexdir/image/epdf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/epdf.c'; fi`
+libluatex_a-epdf.obj: epdf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-epdf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-epdf.Tpo -c -o libluatex_a-epdf.obj `if test -f 'epdf.c'; then $(CYGPATH_W) 'epdf.c'; else $(CYGPATH_W) '$(srcdir)/epdf.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-epdf.Tpo $(DEPDIR)/libluatex_a-epdf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/epdf.c' object='libluatex_a-epdf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='epdf.c' object='libluatex_a-epdf.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-epdf.obj `if test -f 'luatexdir/image/epdf.c'; then $(CYGPATH_W) 'luatexdir/image/epdf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/epdf.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-epdf.obj `if test -f 'epdf.c'; then $(CYGPATH_W) 'epdf.c'; else $(CYGPATH_W) '$(srcdir)/epdf.c'; fi`
-libluatex_a-writeimg.o: luatexdir/image/writeimg.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeimg.o -MD -MP -MF $(DEPDIR)/libluatex_a-writeimg.Tpo -c -o libluatex_a-writeimg.o `test -f 'luatexdir/image/writeimg.c' || echo '$(srcdir)/'`luatexdir/image/writeimg.c
+libluatex_a-writeimg.o: writeimg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeimg.o -MD -MP -MF $(DEPDIR)/libluatex_a-writeimg.Tpo -c -o libluatex_a-writeimg.o `test -f 'writeimg.c' || echo '$(srcdir)/'`writeimg.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writeimg.Tpo $(DEPDIR)/libluatex_a-writeimg.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writeimg.c' object='libluatex_a-writeimg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeimg.c' object='libluatex_a-writeimg.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeimg.o `test -f 'luatexdir/image/writeimg.c' || echo '$(srcdir)/'`luatexdir/image/writeimg.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeimg.o `test -f 'writeimg.c' || echo '$(srcdir)/'`writeimg.c
-libluatex_a-writeimg.obj: luatexdir/image/writeimg.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeimg.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writeimg.Tpo -c -o libluatex_a-writeimg.obj `if test -f 'luatexdir/image/writeimg.c'; then $(CYGPATH_W) 'luatexdir/image/writeimg.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writeimg.c'; fi`
+libluatex_a-writeimg.obj: writeimg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writeimg.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writeimg.Tpo -c -o libluatex_a-writeimg.obj `if test -f 'writeimg.c'; then $(CYGPATH_W) 'writeimg.c'; else $(CYGPATH_W) '$(srcdir)/writeimg.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writeimg.Tpo $(DEPDIR)/libluatex_a-writeimg.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writeimg.c' object='libluatex_a-writeimg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeimg.c' object='libluatex_a-writeimg.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeimg.obj `if test -f 'luatexdir/image/writeimg.c'; then $(CYGPATH_W) 'luatexdir/image/writeimg.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writeimg.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writeimg.obj `if test -f 'writeimg.c'; then $(CYGPATH_W) 'writeimg.c'; else $(CYGPATH_W) '$(srcdir)/writeimg.c'; fi`
-libluatex_a-writejbig2.o: luatexdir/image/writejbig2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejbig2.o -MD -MP -MF $(DEPDIR)/libluatex_a-writejbig2.Tpo -c -o libluatex_a-writejbig2.o `test -f 'luatexdir/image/writejbig2.c' || echo '$(srcdir)/'`luatexdir/image/writejbig2.c
+libluatex_a-writejbig2.o: writejbig2.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejbig2.o -MD -MP -MF $(DEPDIR)/libluatex_a-writejbig2.Tpo -c -o libluatex_a-writejbig2.o `test -f 'writejbig2.c' || echo '$(srcdir)/'`writejbig2.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writejbig2.Tpo $(DEPDIR)/libluatex_a-writejbig2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writejbig2.c' object='libluatex_a-writejbig2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writejbig2.c' object='libluatex_a-writejbig2.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejbig2.o `test -f 'luatexdir/image/writejbig2.c' || echo '$(srcdir)/'`luatexdir/image/writejbig2.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejbig2.o `test -f 'writejbig2.c' || echo '$(srcdir)/'`writejbig2.c
-libluatex_a-writejbig2.obj: luatexdir/image/writejbig2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejbig2.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writejbig2.Tpo -c -o libluatex_a-writejbig2.obj `if test -f 'luatexdir/image/writejbig2.c'; then $(CYGPATH_W) 'luatexdir/image/writejbig2.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writejbig2.c'; fi`
+libluatex_a-writejbig2.obj: writejbig2.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejbig2.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writejbig2.Tpo -c -o libluatex_a-writejbig2.obj `if test -f 'writejbig2.c'; then $(CYGPATH_W) 'writejbig2.c'; else $(CYGPATH_W) '$(srcdir)/writejbig2.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writejbig2.Tpo $(DEPDIR)/libluatex_a-writejbig2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writejbig2.c' object='libluatex_a-writejbig2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writejbig2.c' object='libluatex_a-writejbig2.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejbig2.obj `if test -f 'luatexdir/image/writejbig2.c'; then $(CYGPATH_W) 'luatexdir/image/writejbig2.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writejbig2.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejbig2.obj `if test -f 'writejbig2.c'; then $(CYGPATH_W) 'writejbig2.c'; else $(CYGPATH_W) '$(srcdir)/writejbig2.c'; fi`
-libluatex_a-writejpg.o: luatexdir/image/writejpg.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejpg.o -MD -MP -MF $(DEPDIR)/libluatex_a-writejpg.Tpo -c -o libluatex_a-writejpg.o `test -f 'luatexdir/image/writejpg.c' || echo '$(srcdir)/'`luatexdir/image/writejpg.c
+libluatex_a-writejpg.o: writejpg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejpg.o -MD -MP -MF $(DEPDIR)/libluatex_a-writejpg.Tpo -c -o libluatex_a-writejpg.o `test -f 'writejpg.c' || echo '$(srcdir)/'`writejpg.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writejpg.Tpo $(DEPDIR)/libluatex_a-writejpg.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writejpg.c' object='libluatex_a-writejpg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writejpg.c' object='libluatex_a-writejpg.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejpg.o `test -f 'luatexdir/image/writejpg.c' || echo '$(srcdir)/'`luatexdir/image/writejpg.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejpg.o `test -f 'writejpg.c' || echo '$(srcdir)/'`writejpg.c
-libluatex_a-writejpg.obj: luatexdir/image/writejpg.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejpg.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writejpg.Tpo -c -o libluatex_a-writejpg.obj `if test -f 'luatexdir/image/writejpg.c'; then $(CYGPATH_W) 'luatexdir/image/writejpg.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writejpg.c'; fi`
+libluatex_a-writejpg.obj: writejpg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writejpg.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writejpg.Tpo -c -o libluatex_a-writejpg.obj `if test -f 'writejpg.c'; then $(CYGPATH_W) 'writejpg.c'; else $(CYGPATH_W) '$(srcdir)/writejpg.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writejpg.Tpo $(DEPDIR)/libluatex_a-writejpg.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writejpg.c' object='libluatex_a-writejpg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writejpg.c' object='libluatex_a-writejpg.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejpg.obj `if test -f 'luatexdir/image/writejpg.c'; then $(CYGPATH_W) 'luatexdir/image/writejpg.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writejpg.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writejpg.obj `if test -f 'writejpg.c'; then $(CYGPATH_W) 'writejpg.c'; else $(CYGPATH_W) '$(srcdir)/writejpg.c'; fi`
-libluatex_a-writepng.o: luatexdir/image/writepng.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writepng.o -MD -MP -MF $(DEPDIR)/libluatex_a-writepng.Tpo -c -o libluatex_a-writepng.o `test -f 'luatexdir/image/writepng.c' || echo '$(srcdir)/'`luatexdir/image/writepng.c
+libluatex_a-writepng.o: writepng.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writepng.o -MD -MP -MF $(DEPDIR)/libluatex_a-writepng.Tpo -c -o libluatex_a-writepng.o `test -f 'writepng.c' || echo '$(srcdir)/'`writepng.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writepng.Tpo $(DEPDIR)/libluatex_a-writepng.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writepng.c' object='libluatex_a-writepng.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writepng.c' object='libluatex_a-writepng.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writepng.o `test -f 'luatexdir/image/writepng.c' || echo '$(srcdir)/'`luatexdir/image/writepng.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writepng.o `test -f 'writepng.c' || echo '$(srcdir)/'`writepng.c
-libluatex_a-writepng.obj: luatexdir/image/writepng.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writepng.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writepng.Tpo -c -o libluatex_a-writepng.obj `if test -f 'luatexdir/image/writepng.c'; then $(CYGPATH_W) 'luatexdir/image/writepng.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writepng.c'; fi`
+libluatex_a-writepng.obj: writepng.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writepng.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writepng.Tpo -c -o libluatex_a-writepng.obj `if test -f 'writepng.c'; then $(CYGPATH_W) 'writepng.c'; else $(CYGPATH_W) '$(srcdir)/writepng.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writepng.Tpo $(DEPDIR)/libluatex_a-writepng.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/image/writepng.c' object='libluatex_a-writepng.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writepng.c' object='libluatex_a-writepng.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writepng.obj `if test -f 'luatexdir/image/writepng.c'; then $(CYGPATH_W) 'luatexdir/image/writepng.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/writepng.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writepng.obj `if test -f 'writepng.c'; then $(CYGPATH_W) 'writepng.c'; else $(CYGPATH_W) '$(srcdir)/writepng.c'; fi`
-libluatex_a-hnjalloc.o: luatexdir/lang/hnjalloc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hnjalloc.o -MD -MP -MF $(DEPDIR)/libluatex_a-hnjalloc.Tpo -c -o libluatex_a-hnjalloc.o `test -f 'luatexdir/lang/hnjalloc.c' || echo '$(srcdir)/'`luatexdir/lang/hnjalloc.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hnjalloc.Tpo $(DEPDIR)/libluatex_a-hnjalloc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lang/hnjalloc.c' object='libluatex_a-hnjalloc.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luagen.o: luagen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luagen.o -MD -MP -MF $(DEPDIR)/libluatex_a-luagen.Tpo -c -o libluatex_a-luagen.o `test -f 'luagen.c' || echo '$(srcdir)/'`luagen.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luagen.Tpo $(DEPDIR)/libluatex_a-luagen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luagen.c' object='libluatex_a-luagen.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hnjalloc.o `test -f 'luatexdir/lang/hnjalloc.c' || echo '$(srcdir)/'`luatexdir/lang/hnjalloc.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luagen.o `test -f 'luagen.c' || echo '$(srcdir)/'`luagen.c
-libluatex_a-hnjalloc.obj: luatexdir/lang/hnjalloc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hnjalloc.obj -MD -MP -MF $(DEPDIR)/libluatex_a-hnjalloc.Tpo -c -o libluatex_a-hnjalloc.obj `if test -f 'luatexdir/lang/hnjalloc.c'; then $(CYGPATH_W) 'luatexdir/lang/hnjalloc.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lang/hnjalloc.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hnjalloc.Tpo $(DEPDIR)/libluatex_a-hnjalloc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lang/hnjalloc.c' object='libluatex_a-hnjalloc.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luagen.obj: luagen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luagen.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luagen.Tpo -c -o libluatex_a-luagen.obj `if test -f 'luagen.c'; then $(CYGPATH_W) 'luagen.c'; else $(CYGPATH_W) '$(srcdir)/luagen.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luagen.Tpo $(DEPDIR)/libluatex_a-luagen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luagen.c' object='libluatex_a-luagen.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hnjalloc.obj `if test -f 'luatexdir/lang/hnjalloc.c'; then $(CYGPATH_W) 'luatexdir/lang/hnjalloc.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lang/hnjalloc.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luagen.obj `if test -f 'luagen.c'; then $(CYGPATH_W) 'luagen.c'; else $(CYGPATH_W) '$(srcdir)/luagen.c'; fi`
-libluatex_a-hyphen.o: luatexdir/lang/hyphen.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hyphen.o -MD -MP -MF $(DEPDIR)/libluatex_a-hyphen.Tpo -c -o libluatex_a-hyphen.o `test -f 'luatexdir/lang/hyphen.c' || echo '$(srcdir)/'`luatexdir/lang/hyphen.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hyphen.Tpo $(DEPDIR)/libluatex_a-hyphen.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lang/hyphen.c' object='libluatex_a-hyphen.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luainit.o: luainit.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luainit.o -MD -MP -MF $(DEPDIR)/libluatex_a-luainit.Tpo -c -o libluatex_a-luainit.o `test -f 'luainit.c' || echo '$(srcdir)/'`luainit.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luainit.Tpo $(DEPDIR)/libluatex_a-luainit.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luainit.c' object='libluatex_a-luainit.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hyphen.o `test -f 'luatexdir/lang/hyphen.c' || echo '$(srcdir)/'`luatexdir/lang/hyphen.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luainit.o `test -f 'luainit.c' || echo '$(srcdir)/'`luainit.c
-libluatex_a-hyphen.obj: luatexdir/lang/hyphen.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hyphen.obj -MD -MP -MF $(DEPDIR)/libluatex_a-hyphen.Tpo -c -o libluatex_a-hyphen.obj `if test -f 'luatexdir/lang/hyphen.c'; then $(CYGPATH_W) 'luatexdir/lang/hyphen.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lang/hyphen.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hyphen.Tpo $(DEPDIR)/libluatex_a-hyphen.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lang/hyphen.c' object='libluatex_a-hyphen.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luainit.obj: luainit.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luainit.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luainit.Tpo -c -o libluatex_a-luainit.obj `if test -f 'luainit.c'; then $(CYGPATH_W) 'luainit.c'; else $(CYGPATH_W) '$(srcdir)/luainit.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luainit.Tpo $(DEPDIR)/libluatex_a-luainit.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luainit.c' object='libluatex_a-luainit.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hyphen.obj `if test -f 'luatexdir/lang/hyphen.c'; then $(CYGPATH_W) 'luatexdir/lang/hyphen.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lang/hyphen.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luainit.obj `if test -f 'luainit.c'; then $(CYGPATH_W) 'luainit.c'; else $(CYGPATH_W) '$(srcdir)/luainit.c'; fi`
-libluatex_a-texlang.o: luatexdir/lang/texlang.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texlang.o -MD -MP -MF $(DEPDIR)/libluatex_a-texlang.Tpo -c -o libluatex_a-texlang.o `test -f 'luatexdir/lang/texlang.c' || echo '$(srcdir)/'`luatexdir/lang/texlang.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texlang.Tpo $(DEPDIR)/libluatex_a-texlang.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lang/texlang.c' object='libluatex_a-texlang.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luanode.o: luanode.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luanode.o -MD -MP -MF $(DEPDIR)/libluatex_a-luanode.Tpo -c -o libluatex_a-luanode.o `test -f 'luanode.c' || echo '$(srcdir)/'`luanode.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luanode.Tpo $(DEPDIR)/libluatex_a-luanode.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luanode.c' object='libluatex_a-luanode.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texlang.o `test -f 'luatexdir/lang/texlang.c' || echo '$(srcdir)/'`luatexdir/lang/texlang.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luanode.o `test -f 'luanode.c' || echo '$(srcdir)/'`luanode.c
-libluatex_a-texlang.obj: luatexdir/lang/texlang.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texlang.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texlang.Tpo -c -o libluatex_a-texlang.obj `if test -f 'luatexdir/lang/texlang.c'; then $(CYGPATH_W) 'luatexdir/lang/texlang.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lang/texlang.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texlang.Tpo $(DEPDIR)/libluatex_a-texlang.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lang/texlang.c' object='libluatex_a-texlang.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luanode.obj: luanode.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luanode.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luanode.Tpo -c -o libluatex_a-luanode.obj `if test -f 'luanode.c'; then $(CYGPATH_W) 'luanode.c'; else $(CYGPATH_W) '$(srcdir)/luanode.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luanode.Tpo $(DEPDIR)/libluatex_a-luanode.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luanode.c' object='libluatex_a-luanode.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texlang.obj `if test -f 'luatexdir/lang/texlang.c'; then $(CYGPATH_W) 'luatexdir/lang/texlang.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lang/texlang.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luanode.obj `if test -f 'luanode.c'; then $(CYGPATH_W) 'luanode.c'; else $(CYGPATH_W) '$(srcdir)/luanode.c'; fi`
-libluatex_a-lcallbacklib.o: luatexdir/lua/lcallbacklib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lcallbacklib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lcallbacklib.Tpo -c -o libluatex_a-lcallbacklib.o `test -f 'luatexdir/lua/lcallbacklib.c' || echo '$(srcdir)/'`luatexdir/lua/lcallbacklib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lcallbacklib.Tpo $(DEPDIR)/libluatex_a-lcallbacklib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lcallbacklib.c' object='libluatex_a-lcallbacklib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luastuff.o: luastuff.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luastuff.o -MD -MP -MF $(DEPDIR)/libluatex_a-luastuff.Tpo -c -o libluatex_a-luastuff.o `test -f 'luastuff.c' || echo '$(srcdir)/'`luastuff.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luastuff.Tpo $(DEPDIR)/libluatex_a-luastuff.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luastuff.c' object='libluatex_a-luastuff.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lcallbacklib.o `test -f 'luatexdir/lua/lcallbacklib.c' || echo '$(srcdir)/'`luatexdir/lua/lcallbacklib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luastuff.o `test -f 'luastuff.c' || echo '$(srcdir)/'`luastuff.c
-libluatex_a-lcallbacklib.obj: luatexdir/lua/lcallbacklib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lcallbacklib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lcallbacklib.Tpo -c -o libluatex_a-lcallbacklib.obj `if test -f 'luatexdir/lua/lcallbacklib.c'; then $(CYGPATH_W) 'luatexdir/lua/lcallbacklib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lcallbacklib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lcallbacklib.Tpo $(DEPDIR)/libluatex_a-lcallbacklib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lcallbacklib.c' object='libluatex_a-lcallbacklib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luastuff.obj: luastuff.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luastuff.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luastuff.Tpo -c -o libluatex_a-luastuff.obj `if test -f 'luastuff.c'; then $(CYGPATH_W) 'luastuff.c'; else $(CYGPATH_W) '$(srcdir)/luastuff.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luastuff.Tpo $(DEPDIR)/libluatex_a-luastuff.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luastuff.c' object='libluatex_a-luastuff.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lcallbacklib.obj `if test -f 'luatexdir/lua/lcallbacklib.c'; then $(CYGPATH_W) 'luatexdir/lua/lcallbacklib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lcallbacklib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luastuff.obj `if test -f 'luastuff.c'; then $(CYGPATH_W) 'luastuff.c'; else $(CYGPATH_W) '$(srcdir)/luastuff.c'; fi`
-libluatex_a-lfontlib.o: luatexdir/lua/lfontlib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lfontlib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lfontlib.Tpo -c -o libluatex_a-lfontlib.o `test -f 'luatexdir/lua/lfontlib.c' || echo '$(srcdir)/'`luatexdir/lua/lfontlib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lfontlib.Tpo $(DEPDIR)/libluatex_a-lfontlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lfontlib.c' object='libluatex_a-lfontlib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luatoken.o: luatoken.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luatoken.o -MD -MP -MF $(DEPDIR)/libluatex_a-luatoken.Tpo -c -o libluatex_a-luatoken.o `test -f 'luatoken.c' || echo '$(srcdir)/'`luatoken.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luatoken.Tpo $(DEPDIR)/libluatex_a-luatoken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatoken.c' object='libluatex_a-luatoken.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lfontlib.o `test -f 'luatexdir/lua/lfontlib.c' || echo '$(srcdir)/'`luatexdir/lua/lfontlib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luatoken.o `test -f 'luatoken.c' || echo '$(srcdir)/'`luatoken.c
-libluatex_a-lfontlib.obj: luatexdir/lua/lfontlib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lfontlib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lfontlib.Tpo -c -o libluatex_a-lfontlib.obj `if test -f 'luatexdir/lua/lfontlib.c'; then $(CYGPATH_W) 'luatexdir/lua/lfontlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lfontlib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lfontlib.Tpo $(DEPDIR)/libluatex_a-lfontlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lfontlib.c' object='libluatex_a-lfontlib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-luatoken.obj: luatoken.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luatoken.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luatoken.Tpo -c -o libluatex_a-luatoken.obj `if test -f 'luatoken.c'; then $(CYGPATH_W) 'luatoken.c'; else $(CYGPATH_W) '$(srcdir)/luatoken.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luatoken.Tpo $(DEPDIR)/libluatex_a-luatoken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatoken.c' object='libluatex_a-luatoken.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lfontlib.obj `if test -f 'luatexdir/lua/lfontlib.c'; then $(CYGPATH_W) 'luatexdir/lua/lfontlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lfontlib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luatoken.obj `if test -f 'luatoken.c'; then $(CYGPATH_W) 'luatoken.c'; else $(CYGPATH_W) '$(srcdir)/luatoken.c'; fi`
-libluatex_a-limglib.o: luatexdir/lua/limglib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-limglib.o -MD -MP -MF $(DEPDIR)/libluatex_a-limglib.Tpo -c -o libluatex_a-limglib.o `test -f 'luatexdir/lua/limglib.c' || echo '$(srcdir)/'`luatexdir/lua/limglib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-limglib.Tpo $(DEPDIR)/libluatex_a-limglib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/limglib.c' object='libluatex_a-limglib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-texluac.o: texluac.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texluac.o -MD -MP -MF $(DEPDIR)/libluatex_a-texluac.Tpo -c -o libluatex_a-texluac.o `test -f 'texluac.c' || echo '$(srcdir)/'`texluac.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texluac.Tpo $(DEPDIR)/libluatex_a-texluac.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texluac.c' object='libluatex_a-texluac.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-limglib.o `test -f 'luatexdir/lua/limglib.c' || echo '$(srcdir)/'`luatexdir/lua/limglib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texluac.o `test -f 'texluac.c' || echo '$(srcdir)/'`texluac.c
-libluatex_a-limglib.obj: luatexdir/lua/limglib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-limglib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-limglib.Tpo -c -o libluatex_a-limglib.obj `if test -f 'luatexdir/lua/limglib.c'; then $(CYGPATH_W) 'luatexdir/lua/limglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/limglib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-limglib.Tpo $(DEPDIR)/libluatex_a-limglib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/limglib.c' object='libluatex_a-limglib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-texluac.obj: texluac.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texluac.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texluac.Tpo -c -o libluatex_a-texluac.obj `if test -f 'texluac.c'; then $(CYGPATH_W) 'texluac.c'; else $(CYGPATH_W) '$(srcdir)/texluac.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texluac.Tpo $(DEPDIR)/libluatex_a-texluac.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texluac.c' object='libluatex_a-texluac.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-limglib.obj `if test -f 'luatexdir/lua/limglib.c'; then $(CYGPATH_W) 'luatexdir/lua/limglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/limglib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texluac.obj `if test -f 'texluac.c'; then $(CYGPATH_W) 'texluac.c'; else $(CYGPATH_W) '$(srcdir)/texluac.c'; fi`
-libluatex_a-lkpselib.o: luatexdir/lua/lkpselib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lkpselib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lkpselib.Tpo -c -o libluatex_a-lkpselib.o `test -f 'luatexdir/lua/lkpselib.c' || echo '$(srcdir)/'`luatexdir/lua/lkpselib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lkpselib.Tpo $(DEPDIR)/libluatex_a-lkpselib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lkpselib.c' object='libluatex_a-lkpselib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-ocp.o: ocp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ocp.o -MD -MP -MF $(DEPDIR)/libluatex_a-ocp.Tpo -c -o libluatex_a-ocp.o `test -f 'ocp.c' || echo '$(srcdir)/'`ocp.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ocp.Tpo $(DEPDIR)/libluatex_a-ocp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ocp.c' object='libluatex_a-ocp.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lkpselib.o `test -f 'luatexdir/lua/lkpselib.c' || echo '$(srcdir)/'`luatexdir/lua/lkpselib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ocp.o `test -f 'ocp.c' || echo '$(srcdir)/'`ocp.c
-libluatex_a-lkpselib.obj: luatexdir/lua/lkpselib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lkpselib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lkpselib.Tpo -c -o libluatex_a-lkpselib.obj `if test -f 'luatexdir/lua/lkpselib.c'; then $(CYGPATH_W) 'luatexdir/lua/lkpselib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lkpselib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lkpselib.Tpo $(DEPDIR)/libluatex_a-lkpselib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lkpselib.c' object='libluatex_a-lkpselib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-ocp.obj: ocp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ocp.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ocp.Tpo -c -o libluatex_a-ocp.obj `if test -f 'ocp.c'; then $(CYGPATH_W) 'ocp.c'; else $(CYGPATH_W) '$(srcdir)/ocp.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ocp.Tpo $(DEPDIR)/libluatex_a-ocp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ocp.c' object='libluatex_a-ocp.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lkpselib.obj `if test -f 'luatexdir/lua/lkpselib.c'; then $(CYGPATH_W) 'luatexdir/lua/lkpselib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lkpselib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ocp.obj `if test -f 'ocp.c'; then $(CYGPATH_W) 'ocp.c'; else $(CYGPATH_W) '$(srcdir)/ocp.c'; fi`
-libluatex_a-llanglib.o: luatexdir/lua/llanglib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llanglib.o -MD -MP -MF $(DEPDIR)/libluatex_a-llanglib.Tpo -c -o libluatex_a-llanglib.o `test -f 'luatexdir/lua/llanglib.c' || echo '$(srcdir)/'`luatexdir/lua/llanglib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llanglib.Tpo $(DEPDIR)/libluatex_a-llanglib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llanglib.c' object='libluatex_a-llanglib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-ocplist.o: ocplist.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ocplist.o -MD -MP -MF $(DEPDIR)/libluatex_a-ocplist.Tpo -c -o libluatex_a-ocplist.o `test -f 'ocplist.c' || echo '$(srcdir)/'`ocplist.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ocplist.Tpo $(DEPDIR)/libluatex_a-ocplist.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ocplist.c' object='libluatex_a-ocplist.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llanglib.o `test -f 'luatexdir/lua/llanglib.c' || echo '$(srcdir)/'`luatexdir/lua/llanglib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ocplist.o `test -f 'ocplist.c' || echo '$(srcdir)/'`ocplist.c
-libluatex_a-llanglib.obj: luatexdir/lua/llanglib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llanglib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-llanglib.Tpo -c -o libluatex_a-llanglib.obj `if test -f 'luatexdir/lua/llanglib.c'; then $(CYGPATH_W) 'luatexdir/lua/llanglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llanglib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llanglib.Tpo $(DEPDIR)/libluatex_a-llanglib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llanglib.c' object='libluatex_a-llanglib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-ocplist.obj: ocplist.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ocplist.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ocplist.Tpo -c -o libluatex_a-ocplist.obj `if test -f 'ocplist.c'; then $(CYGPATH_W) 'ocplist.c'; else $(CYGPATH_W) '$(srcdir)/ocplist.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ocplist.Tpo $(DEPDIR)/libluatex_a-ocplist.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ocplist.c' object='libluatex_a-ocplist.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llanglib.obj `if test -f 'luatexdir/lua/llanglib.c'; then $(CYGPATH_W) 'luatexdir/lua/llanglib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llanglib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ocplist.obj `if test -f 'ocplist.c'; then $(CYGPATH_W) 'ocplist.c'; else $(CYGPATH_W) '$(srcdir)/ocplist.c'; fi`
-libluatex_a-llualib.o: luatexdir/lua/llualib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llualib.o -MD -MP -MF $(DEPDIR)/libluatex_a-llualib.Tpo -c -o libluatex_a-llualib.o `test -f 'luatexdir/lua/llualib.c' || echo '$(srcdir)/'`luatexdir/lua/llualib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llualib.Tpo $(DEPDIR)/libluatex_a-llualib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llualib.c' object='libluatex_a-llualib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-readocp.o: readocp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-readocp.o -MD -MP -MF $(DEPDIR)/libluatex_a-readocp.Tpo -c -o libluatex_a-readocp.o `test -f 'readocp.c' || echo '$(srcdir)/'`readocp.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-readocp.Tpo $(DEPDIR)/libluatex_a-readocp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='readocp.c' object='libluatex_a-readocp.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llualib.o `test -f 'luatexdir/lua/llualib.c' || echo '$(srcdir)/'`luatexdir/lua/llualib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-readocp.o `test -f 'readocp.c' || echo '$(srcdir)/'`readocp.c
-libluatex_a-llualib.obj: luatexdir/lua/llualib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-llualib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-llualib.Tpo -c -o libluatex_a-llualib.obj `if test -f 'luatexdir/lua/llualib.c'; then $(CYGPATH_W) 'luatexdir/lua/llualib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llualib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-llualib.Tpo $(DEPDIR)/libluatex_a-llualib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/llualib.c' object='libluatex_a-llualib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-readocp.obj: readocp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-readocp.obj -MD -MP -MF $(DEPDIR)/libluatex_a-readocp.Tpo -c -o libluatex_a-readocp.obj `if test -f 'readocp.c'; then $(CYGPATH_W) 'readocp.c'; else $(CYGPATH_W) '$(srcdir)/readocp.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-readocp.Tpo $(DEPDIR)/libluatex_a-readocp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='readocp.c' object='libluatex_a-readocp.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-llualib.obj `if test -f 'luatexdir/lua/llualib.c'; then $(CYGPATH_W) 'luatexdir/lua/llualib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/llualib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-readocp.obj `if test -f 'readocp.c'; then $(CYGPATH_W) 'readocp.c'; else $(CYGPATH_W) '$(srcdir)/readocp.c'; fi`
-libluatex_a-lnodelib.o: luatexdir/lua/lnodelib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lnodelib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lnodelib.Tpo -c -o libluatex_a-lnodelib.o `test -f 'luatexdir/lua/lnodelib.c' || echo '$(srcdir)/'`luatexdir/lua/lnodelib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lnodelib.Tpo $(DEPDIR)/libluatex_a-lnodelib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lnodelib.c' object='libluatex_a-lnodelib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-runocp.o: runocp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-runocp.o -MD -MP -MF $(DEPDIR)/libluatex_a-runocp.Tpo -c -o libluatex_a-runocp.o `test -f 'runocp.c' || echo '$(srcdir)/'`runocp.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-runocp.Tpo $(DEPDIR)/libluatex_a-runocp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runocp.c' object='libluatex_a-runocp.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lnodelib.o `test -f 'luatexdir/lua/lnodelib.c' || echo '$(srcdir)/'`luatexdir/lua/lnodelib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-runocp.o `test -f 'runocp.c' || echo '$(srcdir)/'`runocp.c
-libluatex_a-lnodelib.obj: luatexdir/lua/lnodelib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lnodelib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lnodelib.Tpo -c -o libluatex_a-lnodelib.obj `if test -f 'luatexdir/lua/lnodelib.c'; then $(CYGPATH_W) 'luatexdir/lua/lnodelib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lnodelib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lnodelib.Tpo $(DEPDIR)/libluatex_a-lnodelib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lnodelib.c' object='libluatex_a-lnodelib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-runocp.obj: runocp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-runocp.obj -MD -MP -MF $(DEPDIR)/libluatex_a-runocp.Tpo -c -o libluatex_a-runocp.obj `if test -f 'runocp.c'; then $(CYGPATH_W) 'runocp.c'; else $(CYGPATH_W) '$(srcdir)/runocp.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-runocp.Tpo $(DEPDIR)/libluatex_a-runocp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runocp.c' object='libluatex_a-runocp.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lnodelib.obj `if test -f 'luatexdir/lua/lnodelib.c'; then $(CYGPATH_W) 'luatexdir/lua/lnodelib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lnodelib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-runocp.obj `if test -f 'runocp.c'; then $(CYGPATH_W) 'runocp.c'; else $(CYGPATH_W) '$(srcdir)/runocp.c'; fi`
-libluatex_a-loslibext.o: luatexdir/lua/loslibext.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-loslibext.o -MD -MP -MF $(DEPDIR)/libluatex_a-loslibext.Tpo -c -o libluatex_a-loslibext.o `test -f 'luatexdir/lua/loslibext.c' || echo '$(srcdir)/'`luatexdir/lua/loslibext.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-loslibext.Tpo $(DEPDIR)/libluatex_a-loslibext.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/loslibext.c' object='libluatex_a-loslibext.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-texlang.o: texlang.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texlang.o -MD -MP -MF $(DEPDIR)/libluatex_a-texlang.Tpo -c -o libluatex_a-texlang.o `test -f 'texlang.c' || echo '$(srcdir)/'`texlang.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texlang.Tpo $(DEPDIR)/libluatex_a-texlang.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texlang.c' object='libluatex_a-texlang.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-loslibext.o `test -f 'luatexdir/lua/loslibext.c' || echo '$(srcdir)/'`luatexdir/lua/loslibext.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texlang.o `test -f 'texlang.c' || echo '$(srcdir)/'`texlang.c
-libluatex_a-loslibext.obj: luatexdir/lua/loslibext.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-loslibext.obj -MD -MP -MF $(DEPDIR)/libluatex_a-loslibext.Tpo -c -o libluatex_a-loslibext.obj `if test -f 'luatexdir/lua/loslibext.c'; then $(CYGPATH_W) 'luatexdir/lua/loslibext.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/loslibext.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-loslibext.Tpo $(DEPDIR)/libluatex_a-loslibext.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/loslibext.c' object='libluatex_a-loslibext.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-texlang.obj: texlang.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texlang.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texlang.Tpo -c -o libluatex_a-texlang.obj `if test -f 'texlang.c'; then $(CYGPATH_W) 'texlang.c'; else $(CYGPATH_W) '$(srcdir)/texlang.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texlang.Tpo $(DEPDIR)/libluatex_a-texlang.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texlang.c' object='libluatex_a-texlang.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-loslibext.obj `if test -f 'luatexdir/lua/loslibext.c'; then $(CYGPATH_W) 'luatexdir/lua/loslibext.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/loslibext.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texlang.obj `if test -f 'texlang.c'; then $(CYGPATH_W) 'texlang.c'; else $(CYGPATH_W) '$(srcdir)/texlang.c'; fi`
-libluatex_a-liolib.o: luatexdir/lua/liolib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-liolib.o -MD -MP -MF $(DEPDIR)/libluatex_a-liolib.Tpo -c -o libluatex_a-liolib.o `test -f 'luatexdir/lua/liolib.c' || echo '$(srcdir)/'`luatexdir/lua/liolib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-liolib.Tpo $(DEPDIR)/libluatex_a-liolib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/liolib.c' object='libluatex_a-liolib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-hyphen.o: hyphen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hyphen.o -MD -MP -MF $(DEPDIR)/libluatex_a-hyphen.Tpo -c -o libluatex_a-hyphen.o `test -f 'hyphen.c' || echo '$(srcdir)/'`hyphen.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hyphen.Tpo $(DEPDIR)/libluatex_a-hyphen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hyphen.c' object='libluatex_a-hyphen.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-liolib.o `test -f 'luatexdir/lua/liolib.c' || echo '$(srcdir)/'`luatexdir/lua/liolib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hyphen.o `test -f 'hyphen.c' || echo '$(srcdir)/'`hyphen.c
-libluatex_a-liolib.obj: luatexdir/lua/liolib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-liolib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-liolib.Tpo -c -o libluatex_a-liolib.obj `if test -f 'luatexdir/lua/liolib.c'; then $(CYGPATH_W) 'luatexdir/lua/liolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/liolib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-liolib.Tpo $(DEPDIR)/libluatex_a-liolib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/liolib.c' object='libluatex_a-liolib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-hyphen.obj: hyphen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hyphen.obj -MD -MP -MF $(DEPDIR)/libluatex_a-hyphen.Tpo -c -o libluatex_a-hyphen.obj `if test -f 'hyphen.c'; then $(CYGPATH_W) 'hyphen.c'; else $(CYGPATH_W) '$(srcdir)/hyphen.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hyphen.Tpo $(DEPDIR)/libluatex_a-hyphen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hyphen.c' object='libluatex_a-hyphen.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-liolib.obj `if test -f 'luatexdir/lua/liolib.c'; then $(CYGPATH_W) 'luatexdir/lua/liolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/liolib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hyphen.obj `if test -f 'hyphen.c'; then $(CYGPATH_W) 'hyphen.c'; else $(CYGPATH_W) '$(srcdir)/hyphen.c'; fi`
-libluatex_a-lpdflib.o: luatexdir/lua/lpdflib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lpdflib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lpdflib.Tpo -c -o libluatex_a-lpdflib.o `test -f 'luatexdir/lua/lpdflib.c' || echo '$(srcdir)/'`luatexdir/lua/lpdflib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lpdflib.Tpo $(DEPDIR)/libluatex_a-lpdflib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lpdflib.c' object='libluatex_a-lpdflib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-hnjalloc.o: hnjalloc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hnjalloc.o -MD -MP -MF $(DEPDIR)/libluatex_a-hnjalloc.Tpo -c -o libluatex_a-hnjalloc.o `test -f 'hnjalloc.c' || echo '$(srcdir)/'`hnjalloc.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hnjalloc.Tpo $(DEPDIR)/libluatex_a-hnjalloc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hnjalloc.c' object='libluatex_a-hnjalloc.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lpdflib.o `test -f 'luatexdir/lua/lpdflib.c' || echo '$(srcdir)/'`luatexdir/lua/lpdflib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hnjalloc.o `test -f 'hnjalloc.c' || echo '$(srcdir)/'`hnjalloc.c
-libluatex_a-lpdflib.obj: luatexdir/lua/lpdflib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lpdflib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lpdflib.Tpo -c -o libluatex_a-lpdflib.obj `if test -f 'luatexdir/lua/lpdflib.c'; then $(CYGPATH_W) 'luatexdir/lua/lpdflib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lpdflib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lpdflib.Tpo $(DEPDIR)/libluatex_a-lpdflib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lpdflib.c' object='libluatex_a-lpdflib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-hnjalloc.obj: hnjalloc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-hnjalloc.obj -MD -MP -MF $(DEPDIR)/libluatex_a-hnjalloc.Tpo -c -o libluatex_a-hnjalloc.obj `if test -f 'hnjalloc.c'; then $(CYGPATH_W) 'hnjalloc.c'; else $(CYGPATH_W) '$(srcdir)/hnjalloc.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-hnjalloc.Tpo $(DEPDIR)/libluatex_a-hnjalloc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hnjalloc.c' object='libluatex_a-hnjalloc.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lpdflib.obj `if test -f 'luatexdir/lua/lpdflib.c'; then $(CYGPATH_W) 'luatexdir/lua/lpdflib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lpdflib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-hnjalloc.obj `if test -f 'hnjalloc.c'; then $(CYGPATH_W) 'hnjalloc.c'; else $(CYGPATH_W) '$(srcdir)/hnjalloc.c'; fi`
-libluatex_a-lstatslib.o: luatexdir/lua/lstatslib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lstatslib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lstatslib.Tpo -c -o libluatex_a-lstatslib.o `test -f 'luatexdir/lua/lstatslib.c' || echo '$(srcdir)/'`luatexdir/lua/lstatslib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lstatslib.Tpo $(DEPDIR)/libluatex_a-lstatslib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lstatslib.c' object='libluatex_a-lstatslib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pagetree.o: pagetree.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pagetree.o -MD -MP -MF $(DEPDIR)/libluatex_a-pagetree.Tpo -c -o libluatex_a-pagetree.o `test -f 'pagetree.c' || echo '$(srcdir)/'`pagetree.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pagetree.Tpo $(DEPDIR)/libluatex_a-pagetree.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pagetree.c' object='libluatex_a-pagetree.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lstatslib.o `test -f 'luatexdir/lua/lstatslib.c' || echo '$(srcdir)/'`luatexdir/lua/lstatslib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pagetree.o `test -f 'pagetree.c' || echo '$(srcdir)/'`pagetree.c
-libluatex_a-lstatslib.obj: luatexdir/lua/lstatslib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lstatslib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lstatslib.Tpo -c -o libluatex_a-lstatslib.obj `if test -f 'luatexdir/lua/lstatslib.c'; then $(CYGPATH_W) 'luatexdir/lua/lstatslib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lstatslib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lstatslib.Tpo $(DEPDIR)/libluatex_a-lstatslib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/lstatslib.c' object='libluatex_a-lstatslib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pagetree.obj: pagetree.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pagetree.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pagetree.Tpo -c -o libluatex_a-pagetree.obj `if test -f 'pagetree.c'; then $(CYGPATH_W) 'pagetree.c'; else $(CYGPATH_W) '$(srcdir)/pagetree.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pagetree.Tpo $(DEPDIR)/libluatex_a-pagetree.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pagetree.c' object='libluatex_a-pagetree.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lstatslib.obj `if test -f 'luatexdir/lua/lstatslib.c'; then $(CYGPATH_W) 'luatexdir/lua/lstatslib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lstatslib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pagetree.obj `if test -f 'pagetree.c'; then $(CYGPATH_W) 'pagetree.c'; else $(CYGPATH_W) '$(srcdir)/pagetree.c'; fi`
-libluatex_a-ltexiolib.o: luatexdir/lua/ltexiolib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexiolib.o -MD -MP -MF $(DEPDIR)/libluatex_a-ltexiolib.Tpo -c -o libluatex_a-ltexiolib.o `test -f 'luatexdir/lua/ltexiolib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexiolib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexiolib.Tpo $(DEPDIR)/libluatex_a-ltexiolib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexiolib.c' object='libluatex_a-ltexiolib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfaction.o: pdfaction.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfaction.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfaction.Tpo -c -o libluatex_a-pdfaction.o `test -f 'pdfaction.c' || echo '$(srcdir)/'`pdfaction.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfaction.Tpo $(DEPDIR)/libluatex_a-pdfaction.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfaction.c' object='libluatex_a-pdfaction.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexiolib.o `test -f 'luatexdir/lua/ltexiolib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexiolib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfaction.o `test -f 'pdfaction.c' || echo '$(srcdir)/'`pdfaction.c
-libluatex_a-ltexiolib.obj: luatexdir/lua/ltexiolib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexiolib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ltexiolib.Tpo -c -o libluatex_a-ltexiolib.obj `if test -f 'luatexdir/lua/ltexiolib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexiolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexiolib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexiolib.Tpo $(DEPDIR)/libluatex_a-ltexiolib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexiolib.c' object='libluatex_a-ltexiolib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfaction.obj: pdfaction.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfaction.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfaction.Tpo -c -o libluatex_a-pdfaction.obj `if test -f 'pdfaction.c'; then $(CYGPATH_W) 'pdfaction.c'; else $(CYGPATH_W) '$(srcdir)/pdfaction.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfaction.Tpo $(DEPDIR)/libluatex_a-pdfaction.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfaction.c' object='libluatex_a-pdfaction.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexiolib.obj `if test -f 'luatexdir/lua/ltexiolib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexiolib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexiolib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfaction.obj `if test -f 'pdfaction.c'; then $(CYGPATH_W) 'pdfaction.c'; else $(CYGPATH_W) '$(srcdir)/pdfaction.c'; fi`
-libluatex_a-ltexlib.o: luatexdir/lua/ltexlib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexlib.o -MD -MP -MF $(DEPDIR)/libluatex_a-ltexlib.Tpo -c -o libluatex_a-ltexlib.o `test -f 'luatexdir/lua/ltexlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexlib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexlib.Tpo $(DEPDIR)/libluatex_a-ltexlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexlib.c' object='libluatex_a-ltexlib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfannot.o: pdfannot.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfannot.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfannot.Tpo -c -o libluatex_a-pdfannot.o `test -f 'pdfannot.c' || echo '$(srcdir)/'`pdfannot.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfannot.Tpo $(DEPDIR)/libluatex_a-pdfannot.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfannot.c' object='libluatex_a-pdfannot.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexlib.o `test -f 'luatexdir/lua/ltexlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltexlib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfannot.o `test -f 'pdfannot.c' || echo '$(srcdir)/'`pdfannot.c
-libluatex_a-ltexlib.obj: luatexdir/lua/ltexlib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltexlib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ltexlib.Tpo -c -o libluatex_a-ltexlib.obj `if test -f 'luatexdir/lua/ltexlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexlib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltexlib.Tpo $(DEPDIR)/libluatex_a-ltexlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltexlib.c' object='libluatex_a-ltexlib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfannot.obj: pdfannot.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfannot.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfannot.Tpo -c -o libluatex_a-pdfannot.obj `if test -f 'pdfannot.c'; then $(CYGPATH_W) 'pdfannot.c'; else $(CYGPATH_W) '$(srcdir)/pdfannot.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfannot.Tpo $(DEPDIR)/libluatex_a-pdfannot.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfannot.c' object='libluatex_a-pdfannot.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltexlib.obj `if test -f 'luatexdir/lua/ltexlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltexlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltexlib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfannot.obj `if test -f 'pdfannot.c'; then $(CYGPATH_W) 'pdfannot.c'; else $(CYGPATH_W) '$(srcdir)/pdfannot.c'; fi`
-libluatex_a-ltokenlib.o: luatexdir/lua/ltokenlib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltokenlib.o -MD -MP -MF $(DEPDIR)/libluatex_a-ltokenlib.Tpo -c -o libluatex_a-ltokenlib.o `test -f 'luatexdir/lua/ltokenlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltokenlib.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltokenlib.Tpo $(DEPDIR)/libluatex_a-ltokenlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltokenlib.c' object='libluatex_a-ltokenlib.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfcolorstack.o: pdfcolorstack.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfcolorstack.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfcolorstack.Tpo -c -o libluatex_a-pdfcolorstack.o `test -f 'pdfcolorstack.c' || echo '$(srcdir)/'`pdfcolorstack.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfcolorstack.Tpo $(DEPDIR)/libluatex_a-pdfcolorstack.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfcolorstack.c' object='libluatex_a-pdfcolorstack.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltokenlib.o `test -f 'luatexdir/lua/ltokenlib.c' || echo '$(srcdir)/'`luatexdir/lua/ltokenlib.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfcolorstack.o `test -f 'pdfcolorstack.c' || echo '$(srcdir)/'`pdfcolorstack.c
-libluatex_a-ltokenlib.obj: luatexdir/lua/ltokenlib.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-ltokenlib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-ltokenlib.Tpo -c -o libluatex_a-ltokenlib.obj `if test -f 'luatexdir/lua/ltokenlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltokenlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltokenlib.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-ltokenlib.Tpo $(DEPDIR)/libluatex_a-ltokenlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/ltokenlib.c' object='libluatex_a-ltokenlib.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfcolorstack.obj: pdfcolorstack.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfcolorstack.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfcolorstack.Tpo -c -o libluatex_a-pdfcolorstack.obj `if test -f 'pdfcolorstack.c'; then $(CYGPATH_W) 'pdfcolorstack.c'; else $(CYGPATH_W) '$(srcdir)/pdfcolorstack.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfcolorstack.Tpo $(DEPDIR)/libluatex_a-pdfcolorstack.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfcolorstack.c' object='libluatex_a-pdfcolorstack.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-ltokenlib.obj `if test -f 'luatexdir/lua/ltokenlib.c'; then $(CYGPATH_W) 'luatexdir/lua/ltokenlib.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/ltokenlib.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfcolorstack.obj `if test -f 'pdfcolorstack.c'; then $(CYGPATH_W) 'pdfcolorstack.c'; else $(CYGPATH_W) '$(srcdir)/pdfcolorstack.c'; fi`
-libluatex_a-luainit.o: luatexdir/lua/luainit.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luainit.o -MD -MP -MF $(DEPDIR)/libluatex_a-luainit.Tpo -c -o libluatex_a-luainit.o `test -f 'luatexdir/lua/luainit.c' || echo '$(srcdir)/'`luatexdir/lua/luainit.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luainit.Tpo $(DEPDIR)/libluatex_a-luainit.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luainit.c' object='libluatex_a-luainit.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfdest.o: pdfdest.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfdest.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfdest.Tpo -c -o libluatex_a-pdfdest.o `test -f 'pdfdest.c' || echo '$(srcdir)/'`pdfdest.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfdest.Tpo $(DEPDIR)/libluatex_a-pdfdest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfdest.c' object='libluatex_a-pdfdest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luainit.o `test -f 'luatexdir/lua/luainit.c' || echo '$(srcdir)/'`luatexdir/lua/luainit.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfdest.o `test -f 'pdfdest.c' || echo '$(srcdir)/'`pdfdest.c
-libluatex_a-luainit.obj: luatexdir/lua/luainit.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luainit.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luainit.Tpo -c -o libluatex_a-luainit.obj `if test -f 'luatexdir/lua/luainit.c'; then $(CYGPATH_W) 'luatexdir/lua/luainit.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luainit.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luainit.Tpo $(DEPDIR)/libluatex_a-luainit.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luainit.c' object='libluatex_a-luainit.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfdest.obj: pdfdest.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfdest.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfdest.Tpo -c -o libluatex_a-pdfdest.obj `if test -f 'pdfdest.c'; then $(CYGPATH_W) 'pdfdest.c'; else $(CYGPATH_W) '$(srcdir)/pdfdest.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfdest.Tpo $(DEPDIR)/libluatex_a-pdfdest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfdest.c' object='libluatex_a-pdfdest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luainit.obj `if test -f 'luatexdir/lua/luainit.c'; then $(CYGPATH_W) 'luatexdir/lua/luainit.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luainit.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfdest.obj `if test -f 'pdfdest.c'; then $(CYGPATH_W) 'pdfdest.c'; else $(CYGPATH_W) '$(srcdir)/pdfdest.c'; fi`
-libluatex_a-luanode.o: luatexdir/lua/luanode.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luanode.o -MD -MP -MF $(DEPDIR)/libluatex_a-luanode.Tpo -c -o libluatex_a-luanode.o `test -f 'luatexdir/lua/luanode.c' || echo '$(srcdir)/'`luatexdir/lua/luanode.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luanode.Tpo $(DEPDIR)/libluatex_a-luanode.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luanode.c' object='libluatex_a-luanode.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdffont.o: pdffont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdffont.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdffont.Tpo -c -o libluatex_a-pdffont.o `test -f 'pdffont.c' || echo '$(srcdir)/'`pdffont.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdffont.Tpo $(DEPDIR)/libluatex_a-pdffont.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdffont.c' object='libluatex_a-pdffont.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luanode.o `test -f 'luatexdir/lua/luanode.c' || echo '$(srcdir)/'`luatexdir/lua/luanode.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdffont.o `test -f 'pdffont.c' || echo '$(srcdir)/'`pdffont.c
-libluatex_a-luanode.obj: luatexdir/lua/luanode.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luanode.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luanode.Tpo -c -o libluatex_a-luanode.obj `if test -f 'luatexdir/lua/luanode.c'; then $(CYGPATH_W) 'luatexdir/lua/luanode.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luanode.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luanode.Tpo $(DEPDIR)/libluatex_a-luanode.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luanode.c' object='libluatex_a-luanode.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdffont.obj: pdffont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdffont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdffont.Tpo -c -o libluatex_a-pdffont.obj `if test -f 'pdffont.c'; then $(CYGPATH_W) 'pdffont.c'; else $(CYGPATH_W) '$(srcdir)/pdffont.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdffont.Tpo $(DEPDIR)/libluatex_a-pdffont.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdffont.c' object='libluatex_a-pdffont.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luanode.obj `if test -f 'luatexdir/lua/luanode.c'; then $(CYGPATH_W) 'luatexdir/lua/luanode.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luanode.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdffont.obj `if test -f 'pdffont.c'; then $(CYGPATH_W) 'pdffont.c'; else $(CYGPATH_W) '$(srcdir)/pdffont.c'; fi`
-libluatex_a-luastuff.o: luatexdir/lua/luastuff.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luastuff.o -MD -MP -MF $(DEPDIR)/libluatex_a-luastuff.Tpo -c -o libluatex_a-luastuff.o `test -f 'luatexdir/lua/luastuff.c' || echo '$(srcdir)/'`luatexdir/lua/luastuff.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luastuff.Tpo $(DEPDIR)/libluatex_a-luastuff.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luastuff.c' object='libluatex_a-luastuff.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfgen.o: pdfgen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfgen.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfgen.Tpo -c -o libluatex_a-pdfgen.o `test -f 'pdfgen.c' || echo '$(srcdir)/'`pdfgen.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfgen.Tpo $(DEPDIR)/libluatex_a-pdfgen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfgen.c' object='libluatex_a-pdfgen.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luastuff.o `test -f 'luatexdir/lua/luastuff.c' || echo '$(srcdir)/'`luatexdir/lua/luastuff.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfgen.o `test -f 'pdfgen.c' || echo '$(srcdir)/'`pdfgen.c
-libluatex_a-luastuff.obj: luatexdir/lua/luastuff.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luastuff.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luastuff.Tpo -c -o libluatex_a-luastuff.obj `if test -f 'luatexdir/lua/luastuff.c'; then $(CYGPATH_W) 'luatexdir/lua/luastuff.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luastuff.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luastuff.Tpo $(DEPDIR)/libluatex_a-luastuff.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luastuff.c' object='libluatex_a-luastuff.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfgen.obj: pdfgen.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfgen.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfgen.Tpo -c -o libluatex_a-pdfgen.obj `if test -f 'pdfgen.c'; then $(CYGPATH_W) 'pdfgen.c'; else $(CYGPATH_W) '$(srcdir)/pdfgen.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfgen.Tpo $(DEPDIR)/libluatex_a-pdfgen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfgen.c' object='libluatex_a-pdfgen.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luastuff.obj `if test -f 'luatexdir/lua/luastuff.c'; then $(CYGPATH_W) 'luatexdir/lua/luastuff.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luastuff.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfgen.obj `if test -f 'pdfgen.c'; then $(CYGPATH_W) 'pdfgen.c'; else $(CYGPATH_W) '$(srcdir)/pdfgen.c'; fi`
-libluatex_a-luatex.o: luatexdir/lua/luatex.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luatex.o -MD -MP -MF $(DEPDIR)/libluatex_a-luatex.Tpo -c -o libluatex_a-luatex.o `test -f 'luatexdir/lua/luatex.c' || echo '$(srcdir)/'`luatexdir/lua/luatex.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luatex.Tpo $(DEPDIR)/libluatex_a-luatex.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luatex.c' object='libluatex_a-luatex.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfglyph.o: pdfglyph.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfglyph.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfglyph.Tpo -c -o libluatex_a-pdfglyph.o `test -f 'pdfglyph.c' || echo '$(srcdir)/'`pdfglyph.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfglyph.Tpo $(DEPDIR)/libluatex_a-pdfglyph.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfglyph.c' object='libluatex_a-pdfglyph.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luatex.o `test -f 'luatexdir/lua/luatex.c' || echo '$(srcdir)/'`luatexdir/lua/luatex.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfglyph.o `test -f 'pdfglyph.c' || echo '$(srcdir)/'`pdfglyph.c
-libluatex_a-luatex.obj: luatexdir/lua/luatex.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luatex.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luatex.Tpo -c -o libluatex_a-luatex.obj `if test -f 'luatexdir/lua/luatex.c'; then $(CYGPATH_W) 'luatexdir/lua/luatex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luatex.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luatex.Tpo $(DEPDIR)/libluatex_a-luatex.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luatex.c' object='libluatex_a-luatex.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfglyph.obj: pdfglyph.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfglyph.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfglyph.Tpo -c -o libluatex_a-pdfglyph.obj `if test -f 'pdfglyph.c'; then $(CYGPATH_W) 'pdfglyph.c'; else $(CYGPATH_W) '$(srcdir)/pdfglyph.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfglyph.Tpo $(DEPDIR)/libluatex_a-pdfglyph.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfglyph.c' object='libluatex_a-pdfglyph.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luatex.obj `if test -f 'luatexdir/lua/luatex.c'; then $(CYGPATH_W) 'luatexdir/lua/luatex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luatex.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfglyph.obj `if test -f 'pdfglyph.c'; then $(CYGPATH_W) 'pdfglyph.c'; else $(CYGPATH_W) '$(srcdir)/pdfglyph.c'; fi`
-libluatex_a-luatoken.o: luatexdir/lua/luatoken.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luatoken.o -MD -MP -MF $(DEPDIR)/libluatex_a-luatoken.Tpo -c -o libluatex_a-luatoken.o `test -f 'luatexdir/lua/luatoken.c' || echo '$(srcdir)/'`luatexdir/lua/luatoken.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luatoken.Tpo $(DEPDIR)/libluatex_a-luatoken.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luatoken.c' object='libluatex_a-luatoken.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfimage.o: pdfimage.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfimage.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfimage.Tpo -c -o libluatex_a-pdfimage.o `test -f 'pdfimage.c' || echo '$(srcdir)/'`pdfimage.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfimage.Tpo $(DEPDIR)/libluatex_a-pdfimage.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfimage.c' object='libluatex_a-pdfimage.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luatoken.o `test -f 'luatexdir/lua/luatoken.c' || echo '$(srcdir)/'`luatexdir/lua/luatoken.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfimage.o `test -f 'pdfimage.c' || echo '$(srcdir)/'`pdfimage.c
-libluatex_a-luatoken.obj: luatexdir/lua/luatoken.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-luatoken.obj -MD -MP -MF $(DEPDIR)/libluatex_a-luatoken.Tpo -c -o libluatex_a-luatoken.obj `if test -f 'luatexdir/lua/luatoken.c'; then $(CYGPATH_W) 'luatexdir/lua/luatoken.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luatoken.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-luatoken.Tpo $(DEPDIR)/libluatex_a-luatoken.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/luatoken.c' object='libluatex_a-luatoken.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfimage.obj: pdfimage.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfimage.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfimage.Tpo -c -o libluatex_a-pdfimage.obj `if test -f 'pdfimage.c'; then $(CYGPATH_W) 'pdfimage.c'; else $(CYGPATH_W) '$(srcdir)/pdfimage.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfimage.Tpo $(DEPDIR)/libluatex_a-pdfimage.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfimage.c' object='libluatex_a-pdfimage.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-luatoken.obj `if test -f 'luatexdir/lua/luatoken.c'; then $(CYGPATH_W) 'luatexdir/lua/luatoken.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/luatoken.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfimage.obj `if test -f 'pdfimage.c'; then $(CYGPATH_W) 'pdfimage.c'; else $(CYGPATH_W) '$(srcdir)/pdfimage.c'; fi`
-libluatex_a-texluac.o: luatexdir/lua/texluac.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texluac.o -MD -MP -MF $(DEPDIR)/libluatex_a-texluac.Tpo -c -o libluatex_a-texluac.o `test -f 'luatexdir/lua/texluac.c' || echo '$(srcdir)/'`luatexdir/lua/texluac.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texluac.Tpo $(DEPDIR)/libluatex_a-texluac.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/texluac.c' object='libluatex_a-texluac.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdflink.o: pdflink.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdflink.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdflink.Tpo -c -o libluatex_a-pdflink.o `test -f 'pdflink.c' || echo '$(srcdir)/'`pdflink.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdflink.Tpo $(DEPDIR)/libluatex_a-pdflink.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdflink.c' object='libluatex_a-pdflink.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texluac.o `test -f 'luatexdir/lua/texluac.c' || echo '$(srcdir)/'`luatexdir/lua/texluac.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdflink.o `test -f 'pdflink.c' || echo '$(srcdir)/'`pdflink.c
-libluatex_a-texluac.obj: luatexdir/lua/texluac.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texluac.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texluac.Tpo -c -o libluatex_a-texluac.obj `if test -f 'luatexdir/lua/texluac.c'; then $(CYGPATH_W) 'luatexdir/lua/texluac.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/texluac.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texluac.Tpo $(DEPDIR)/libluatex_a-texluac.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/lua/texluac.c' object='libluatex_a-texluac.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdflink.obj: pdflink.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdflink.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdflink.Tpo -c -o libluatex_a-pdflink.obj `if test -f 'pdflink.c'; then $(CYGPATH_W) 'pdflink.c'; else $(CYGPATH_W) '$(srcdir)/pdflink.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdflink.Tpo $(DEPDIR)/libluatex_a-pdflink.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdflink.c' object='libluatex_a-pdflink.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texluac.obj `if test -f 'luatexdir/lua/texluac.c'; then $(CYGPATH_W) 'luatexdir/lua/texluac.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/texluac.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdflink.obj `if test -f 'pdflink.c'; then $(CYGPATH_W) 'pdflink.c'; else $(CYGPATH_W) '$(srcdir)/pdflink.c'; fi`
-libluatex_a-makecpool.o: luatexdir/makecpool.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-makecpool.o -MD -MP -MF $(DEPDIR)/libluatex_a-makecpool.Tpo -c -o libluatex_a-makecpool.o `test -f 'luatexdir/makecpool.c' || echo '$(srcdir)/'`luatexdir/makecpool.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-makecpool.Tpo $(DEPDIR)/libluatex_a-makecpool.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/makecpool.c' object='libluatex_a-makecpool.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdflistout.o: pdflistout.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdflistout.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdflistout.Tpo -c -o libluatex_a-pdflistout.o `test -f 'pdflistout.c' || echo '$(srcdir)/'`pdflistout.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdflistout.Tpo $(DEPDIR)/libluatex_a-pdflistout.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdflistout.c' object='libluatex_a-pdflistout.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-makecpool.o `test -f 'luatexdir/makecpool.c' || echo '$(srcdir)/'`luatexdir/makecpool.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdflistout.o `test -f 'pdflistout.c' || echo '$(srcdir)/'`pdflistout.c
-libluatex_a-makecpool.obj: luatexdir/makecpool.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-makecpool.obj -MD -MP -MF $(DEPDIR)/libluatex_a-makecpool.Tpo -c -o libluatex_a-makecpool.obj `if test -f 'luatexdir/makecpool.c'; then $(CYGPATH_W) 'luatexdir/makecpool.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/makecpool.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-makecpool.Tpo $(DEPDIR)/libluatex_a-makecpool.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/makecpool.c' object='libluatex_a-makecpool.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdflistout.obj: pdflistout.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdflistout.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdflistout.Tpo -c -o libluatex_a-pdflistout.obj `if test -f 'pdflistout.c'; then $(CYGPATH_W) 'pdflistout.c'; else $(CYGPATH_W) '$(srcdir)/pdflistout.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdflistout.Tpo $(DEPDIR)/libluatex_a-pdflistout.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdflistout.c' object='libluatex_a-pdflistout.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-makecpool.obj `if test -f 'luatexdir/makecpool.c'; then $(CYGPATH_W) 'luatexdir/makecpool.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/makecpool.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdflistout.obj `if test -f 'pdflistout.c'; then $(CYGPATH_W) 'pdflistout.c'; else $(CYGPATH_W) '$(srcdir)/pdflistout.c'; fi`
-libluatex_a-managed-sa.o: luatexdir/managed-sa.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-managed-sa.o -MD -MP -MF $(DEPDIR)/libluatex_a-managed-sa.Tpo -c -o libluatex_a-managed-sa.o `test -f 'luatexdir/managed-sa.c' || echo '$(srcdir)/'`luatexdir/managed-sa.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-managed-sa.Tpo $(DEPDIR)/libluatex_a-managed-sa.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/managed-sa.c' object='libluatex_a-managed-sa.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfliteral.o: pdfliteral.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfliteral.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfliteral.Tpo -c -o libluatex_a-pdfliteral.o `test -f 'pdfliteral.c' || echo '$(srcdir)/'`pdfliteral.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfliteral.Tpo $(DEPDIR)/libluatex_a-pdfliteral.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfliteral.c' object='libluatex_a-pdfliteral.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-managed-sa.o `test -f 'luatexdir/managed-sa.c' || echo '$(srcdir)/'`luatexdir/managed-sa.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfliteral.o `test -f 'pdfliteral.c' || echo '$(srcdir)/'`pdfliteral.c
-libluatex_a-managed-sa.obj: luatexdir/managed-sa.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-managed-sa.obj -MD -MP -MF $(DEPDIR)/libluatex_a-managed-sa.Tpo -c -o libluatex_a-managed-sa.obj `if test -f 'luatexdir/managed-sa.c'; then $(CYGPATH_W) 'luatexdir/managed-sa.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/managed-sa.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-managed-sa.Tpo $(DEPDIR)/libluatex_a-managed-sa.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/managed-sa.c' object='libluatex_a-managed-sa.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfliteral.obj: pdfliteral.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfliteral.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfliteral.Tpo -c -o libluatex_a-pdfliteral.obj `if test -f 'pdfliteral.c'; then $(CYGPATH_W) 'pdfliteral.c'; else $(CYGPATH_W) '$(srcdir)/pdfliteral.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfliteral.Tpo $(DEPDIR)/libluatex_a-pdfliteral.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfliteral.c' object='libluatex_a-pdfliteral.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-managed-sa.obj `if test -f 'luatexdir/managed-sa.c'; then $(CYGPATH_W) 'luatexdir/managed-sa.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/managed-sa.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfliteral.obj `if test -f 'pdfliteral.c'; then $(CYGPATH_W) 'pdfliteral.c'; else $(CYGPATH_W) '$(srcdir)/pdfliteral.c'; fi`
-libluatex_a-mathcodes.o: luatexdir/mathcodes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mathcodes.o -MD -MP -MF $(DEPDIR)/libluatex_a-mathcodes.Tpo -c -o libluatex_a-mathcodes.o `test -f 'luatexdir/mathcodes.c' || echo '$(srcdir)/'`luatexdir/mathcodes.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mathcodes.Tpo $(DEPDIR)/libluatex_a-mathcodes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/mathcodes.c' object='libluatex_a-mathcodes.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfobj.o: pdfobj.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfobj.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfobj.Tpo -c -o libluatex_a-pdfobj.o `test -f 'pdfobj.c' || echo '$(srcdir)/'`pdfobj.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfobj.Tpo $(DEPDIR)/libluatex_a-pdfobj.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfobj.c' object='libluatex_a-pdfobj.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mathcodes.o `test -f 'luatexdir/mathcodes.c' || echo '$(srcdir)/'`luatexdir/mathcodes.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfobj.o `test -f 'pdfobj.c' || echo '$(srcdir)/'`pdfobj.c
-libluatex_a-mathcodes.obj: luatexdir/mathcodes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mathcodes.obj -MD -MP -MF $(DEPDIR)/libluatex_a-mathcodes.Tpo -c -o libluatex_a-mathcodes.obj `if test -f 'luatexdir/mathcodes.c'; then $(CYGPATH_W) 'luatexdir/mathcodes.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/mathcodes.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mathcodes.Tpo $(DEPDIR)/libluatex_a-mathcodes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/mathcodes.c' object='libluatex_a-mathcodes.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfobj.obj: pdfobj.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfobj.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfobj.Tpo -c -o libluatex_a-pdfobj.obj `if test -f 'pdfobj.c'; then $(CYGPATH_W) 'pdfobj.c'; else $(CYGPATH_W) '$(srcdir)/pdfobj.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfobj.Tpo $(DEPDIR)/libluatex_a-pdfobj.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfobj.c' object='libluatex_a-pdfobj.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mathcodes.obj `if test -f 'luatexdir/mathcodes.c'; then $(CYGPATH_W) 'luatexdir/mathcodes.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/mathcodes.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfobj.obj `if test -f 'pdfobj.c'; then $(CYGPATH_W) 'pdfobj.c'; else $(CYGPATH_W) '$(srcdir)/pdfobj.c'; fi`
-libluatex_a-pagetree.o: luatexdir/pdf/pagetree.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pagetree.o -MD -MP -MF $(DEPDIR)/libluatex_a-pagetree.Tpo -c -o libluatex_a-pagetree.o `test -f 'luatexdir/pdf/pagetree.c' || echo '$(srcdir)/'`luatexdir/pdf/pagetree.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pagetree.Tpo $(DEPDIR)/libluatex_a-pagetree.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/pdf/pagetree.c' object='libluatex_a-pagetree.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfoutline.o: pdfoutline.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfoutline.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfoutline.Tpo -c -o libluatex_a-pdfoutline.o `test -f 'pdfoutline.c' || echo '$(srcdir)/'`pdfoutline.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfoutline.Tpo $(DEPDIR)/libluatex_a-pdfoutline.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfoutline.c' object='libluatex_a-pdfoutline.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pagetree.o `test -f 'luatexdir/pdf/pagetree.c' || echo '$(srcdir)/'`luatexdir/pdf/pagetree.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfoutline.o `test -f 'pdfoutline.c' || echo '$(srcdir)/'`pdfoutline.c
-libluatex_a-pagetree.obj: luatexdir/pdf/pagetree.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pagetree.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pagetree.Tpo -c -o libluatex_a-pagetree.obj `if test -f 'luatexdir/pdf/pagetree.c'; then $(CYGPATH_W) 'luatexdir/pdf/pagetree.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/pdf/pagetree.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pagetree.Tpo $(DEPDIR)/libluatex_a-pagetree.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/pdf/pagetree.c' object='libluatex_a-pagetree.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfoutline.obj: pdfoutline.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfoutline.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfoutline.Tpo -c -o libluatex_a-pdfoutline.obj `if test -f 'pdfoutline.c'; then $(CYGPATH_W) 'pdfoutline.c'; else $(CYGPATH_W) '$(srcdir)/pdfoutline.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfoutline.Tpo $(DEPDIR)/libluatex_a-pdfoutline.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfoutline.c' object='libluatex_a-pdfoutline.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pagetree.obj `if test -f 'luatexdir/pdf/pagetree.c'; then $(CYGPATH_W) 'luatexdir/pdf/pagetree.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/pdf/pagetree.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfoutline.obj `if test -f 'pdfoutline.c'; then $(CYGPATH_W) 'pdfoutline.c'; else $(CYGPATH_W) '$(srcdir)/pdfoutline.c'; fi`
-libluatex_a-pdfpage.o: luatexdir/pdf/pdfpage.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfpage.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfpage.Tpo -c -o libluatex_a-pdfpage.o `test -f 'luatexdir/pdf/pdfpage.c' || echo '$(srcdir)/'`luatexdir/pdf/pdfpage.c
+libluatex_a-pdfpage.o: pdfpage.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfpage.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfpage.Tpo -c -o libluatex_a-pdfpage.o `test -f 'pdfpage.c' || echo '$(srcdir)/'`pdfpage.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfpage.Tpo $(DEPDIR)/libluatex_a-pdfpage.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/pdf/pdfpage.c' object='libluatex_a-pdfpage.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfpage.c' object='libluatex_a-pdfpage.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfpage.o `test -f 'luatexdir/pdf/pdfpage.c' || echo '$(srcdir)/'`luatexdir/pdf/pdfpage.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfpage.o `test -f 'pdfpage.c' || echo '$(srcdir)/'`pdfpage.c
-libluatex_a-pdfpage.obj: luatexdir/pdf/pdfpage.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfpage.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfpage.Tpo -c -o libluatex_a-pdfpage.obj `if test -f 'luatexdir/pdf/pdfpage.c'; then $(CYGPATH_W) 'luatexdir/pdf/pdfpage.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/pdf/pdfpage.c'; fi`
+libluatex_a-pdfpage.obj: pdfpage.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfpage.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfpage.Tpo -c -o libluatex_a-pdfpage.obj `if test -f 'pdfpage.c'; then $(CYGPATH_W) 'pdfpage.c'; else $(CYGPATH_W) '$(srcdir)/pdfpage.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfpage.Tpo $(DEPDIR)/libluatex_a-pdfpage.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/pdf/pdfpage.c' object='libluatex_a-pdfpage.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfpage.c' object='libluatex_a-pdfpage.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfpage.obj `if test -f 'luatexdir/pdf/pdfpage.c'; then $(CYGPATH_W) 'luatexdir/pdf/pdfpage.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/pdf/pdfpage.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfpage.obj `if test -f 'pdfpage.c'; then $(CYGPATH_W) 'pdfpage.c'; else $(CYGPATH_W) '$(srcdir)/pdfpage.c'; fi`
-libluatex_a-filename.o: luatexdir/tex/filename.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-filename.o -MD -MP -MF $(DEPDIR)/libluatex_a-filename.Tpo -c -o libluatex_a-filename.o `test -f 'luatexdir/tex/filename.c' || echo '$(srcdir)/'`luatexdir/tex/filename.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-filename.Tpo $(DEPDIR)/libluatex_a-filename.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/filename.c' object='libluatex_a-filename.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfrule.o: pdfrule.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfrule.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfrule.Tpo -c -o libluatex_a-pdfrule.o `test -f 'pdfrule.c' || echo '$(srcdir)/'`pdfrule.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfrule.Tpo $(DEPDIR)/libluatex_a-pdfrule.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfrule.c' object='libluatex_a-pdfrule.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-filename.o `test -f 'luatexdir/tex/filename.c' || echo '$(srcdir)/'`luatexdir/tex/filename.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfrule.o `test -f 'pdfrule.c' || echo '$(srcdir)/'`pdfrule.c
-libluatex_a-filename.obj: luatexdir/tex/filename.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-filename.obj -MD -MP -MF $(DEPDIR)/libluatex_a-filename.Tpo -c -o libluatex_a-filename.obj `if test -f 'luatexdir/tex/filename.c'; then $(CYGPATH_W) 'luatexdir/tex/filename.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/filename.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-filename.Tpo $(DEPDIR)/libluatex_a-filename.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/filename.c' object='libluatex_a-filename.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfrule.obj: pdfrule.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfrule.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfrule.Tpo -c -o libluatex_a-pdfrule.obj `if test -f 'pdfrule.c'; then $(CYGPATH_W) 'pdfrule.c'; else $(CYGPATH_W) '$(srcdir)/pdfrule.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfrule.Tpo $(DEPDIR)/libluatex_a-pdfrule.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfrule.c' object='libluatex_a-pdfrule.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-filename.obj `if test -f 'luatexdir/tex/filename.c'; then $(CYGPATH_W) 'luatexdir/tex/filename.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/filename.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfrule.obj `if test -f 'pdfrule.c'; then $(CYGPATH_W) 'pdfrule.c'; else $(CYGPATH_W) '$(srcdir)/pdfrule.c'; fi`
-libluatex_a-linebreak.o: luatexdir/tex/linebreak.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-linebreak.o -MD -MP -MF $(DEPDIR)/libluatex_a-linebreak.Tpo -c -o libluatex_a-linebreak.o `test -f 'luatexdir/tex/linebreak.c' || echo '$(srcdir)/'`luatexdir/tex/linebreak.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-linebreak.Tpo $(DEPDIR)/libluatex_a-linebreak.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/linebreak.c' object='libluatex_a-linebreak.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfsaverestore.o: pdfsaverestore.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfsaverestore.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfsaverestore.Tpo -c -o libluatex_a-pdfsaverestore.o `test -f 'pdfsaverestore.c' || echo '$(srcdir)/'`pdfsaverestore.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfsaverestore.Tpo $(DEPDIR)/libluatex_a-pdfsaverestore.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfsaverestore.c' object='libluatex_a-pdfsaverestore.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-linebreak.o `test -f 'luatexdir/tex/linebreak.c' || echo '$(srcdir)/'`luatexdir/tex/linebreak.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfsaverestore.o `test -f 'pdfsaverestore.c' || echo '$(srcdir)/'`pdfsaverestore.c
-libluatex_a-linebreak.obj: luatexdir/tex/linebreak.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-linebreak.obj -MD -MP -MF $(DEPDIR)/libluatex_a-linebreak.Tpo -c -o libluatex_a-linebreak.obj `if test -f 'luatexdir/tex/linebreak.c'; then $(CYGPATH_W) 'luatexdir/tex/linebreak.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/linebreak.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-linebreak.Tpo $(DEPDIR)/libluatex_a-linebreak.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/linebreak.c' object='libluatex_a-linebreak.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-pdfsaverestore.obj: pdfsaverestore.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfsaverestore.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfsaverestore.Tpo -c -o libluatex_a-pdfsaverestore.obj `if test -f 'pdfsaverestore.c'; then $(CYGPATH_W) 'pdfsaverestore.c'; else $(CYGPATH_W) '$(srcdir)/pdfsaverestore.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfsaverestore.Tpo $(DEPDIR)/libluatex_a-pdfsaverestore.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfsaverestore.c' object='libluatex_a-pdfsaverestore.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfsaverestore.obj `if test -f 'pdfsaverestore.c'; then $(CYGPATH_W) 'pdfsaverestore.c'; else $(CYGPATH_W) '$(srcdir)/pdfsaverestore.c'; fi`
+
+libluatex_a-pdfsetmatrix.o: pdfsetmatrix.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfsetmatrix.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfsetmatrix.Tpo -c -o libluatex_a-pdfsetmatrix.o `test -f 'pdfsetmatrix.c' || echo '$(srcdir)/'`pdfsetmatrix.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfsetmatrix.Tpo $(DEPDIR)/libluatex_a-pdfsetmatrix.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfsetmatrix.c' object='libluatex_a-pdfsetmatrix.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfsetmatrix.o `test -f 'pdfsetmatrix.c' || echo '$(srcdir)/'`pdfsetmatrix.c
+
+libluatex_a-pdfsetmatrix.obj: pdfsetmatrix.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfsetmatrix.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfsetmatrix.Tpo -c -o libluatex_a-pdfsetmatrix.obj `if test -f 'pdfsetmatrix.c'; then $(CYGPATH_W) 'pdfsetmatrix.c'; else $(CYGPATH_W) '$(srcdir)/pdfsetmatrix.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfsetmatrix.Tpo $(DEPDIR)/libluatex_a-pdfsetmatrix.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfsetmatrix.c' object='libluatex_a-pdfsetmatrix.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfsetmatrix.obj `if test -f 'pdfsetmatrix.c'; then $(CYGPATH_W) 'pdfsetmatrix.c'; else $(CYGPATH_W) '$(srcdir)/pdfsetmatrix.c'; fi`
+
+libluatex_a-pdfshipout.o: pdfshipout.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfshipout.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfshipout.Tpo -c -o libluatex_a-pdfshipout.o `test -f 'pdfshipout.c' || echo '$(srcdir)/'`pdfshipout.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfshipout.Tpo $(DEPDIR)/libluatex_a-pdfshipout.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfshipout.c' object='libluatex_a-pdfshipout.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfshipout.o `test -f 'pdfshipout.c' || echo '$(srcdir)/'`pdfshipout.c
+
+libluatex_a-pdfshipout.obj: pdfshipout.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfshipout.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfshipout.Tpo -c -o libluatex_a-pdfshipout.obj `if test -f 'pdfshipout.c'; then $(CYGPATH_W) 'pdfshipout.c'; else $(CYGPATH_W) '$(srcdir)/pdfshipout.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfshipout.Tpo $(DEPDIR)/libluatex_a-pdfshipout.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfshipout.c' object='libluatex_a-pdfshipout.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfshipout.obj `if test -f 'pdfshipout.c'; then $(CYGPATH_W) 'pdfshipout.c'; else $(CYGPATH_W) '$(srcdir)/pdfshipout.c'; fi`
+
+libluatex_a-pdftables.o: pdftables.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdftables.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdftables.Tpo -c -o libluatex_a-pdftables.o `test -f 'pdftables.c' || echo '$(srcdir)/'`pdftables.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdftables.Tpo $(DEPDIR)/libluatex_a-pdftables.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdftables.c' object='libluatex_a-pdftables.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdftables.o `test -f 'pdftables.c' || echo '$(srcdir)/'`pdftables.c
+
+libluatex_a-pdftables.obj: pdftables.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdftables.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdftables.Tpo -c -o libluatex_a-pdftables.obj `if test -f 'pdftables.c'; then $(CYGPATH_W) 'pdftables.c'; else $(CYGPATH_W) '$(srcdir)/pdftables.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdftables.Tpo $(DEPDIR)/libluatex_a-pdftables.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdftables.c' object='libluatex_a-pdftables.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdftables.obj `if test -f 'pdftables.c'; then $(CYGPATH_W) 'pdftables.c'; else $(CYGPATH_W) '$(srcdir)/pdftables.c'; fi`
+
+libluatex_a-pdfthread.o: pdfthread.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfthread.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfthread.Tpo -c -o libluatex_a-pdfthread.o `test -f 'pdfthread.c' || echo '$(srcdir)/'`pdfthread.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfthread.Tpo $(DEPDIR)/libluatex_a-pdfthread.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfthread.c' object='libluatex_a-pdfthread.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfthread.o `test -f 'pdfthread.c' || echo '$(srcdir)/'`pdfthread.c
+
+libluatex_a-pdfthread.obj: pdfthread.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfthread.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfthread.Tpo -c -o libluatex_a-pdfthread.obj `if test -f 'pdfthread.c'; then $(CYGPATH_W) 'pdfthread.c'; else $(CYGPATH_W) '$(srcdir)/pdfthread.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfthread.Tpo $(DEPDIR)/libluatex_a-pdfthread.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfthread.c' object='libluatex_a-pdfthread.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfthread.obj `if test -f 'pdfthread.c'; then $(CYGPATH_W) 'pdfthread.c'; else $(CYGPATH_W) '$(srcdir)/pdfthread.c'; fi`
+
+libluatex_a-pdfxform.o: pdfxform.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfxform.o -MD -MP -MF $(DEPDIR)/libluatex_a-pdfxform.Tpo -c -o libluatex_a-pdfxform.o `test -f 'pdfxform.c' || echo '$(srcdir)/'`pdfxform.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfxform.Tpo $(DEPDIR)/libluatex_a-pdfxform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfxform.c' object='libluatex_a-pdfxform.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfxform.o `test -f 'pdfxform.c' || echo '$(srcdir)/'`pdfxform.c
+
+libluatex_a-pdfxform.obj: pdfxform.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-pdfxform.obj -MD -MP -MF $(DEPDIR)/libluatex_a-pdfxform.Tpo -c -o libluatex_a-pdfxform.obj `if test -f 'pdfxform.c'; then $(CYGPATH_W) 'pdfxform.c'; else $(CYGPATH_W) '$(srcdir)/pdfxform.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-pdfxform.Tpo $(DEPDIR)/libluatex_a-pdfxform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pdfxform.c' object='libluatex_a-pdfxform.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-pdfxform.obj `if test -f 'pdfxform.c'; then $(CYGPATH_W) 'pdfxform.c'; else $(CYGPATH_W) '$(srcdir)/pdfxform.c'; fi`
+
+libluatex_a-align.o: align.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-align.o -MD -MP -MF $(DEPDIR)/libluatex_a-align.Tpo -c -o libluatex_a-align.o `test -f 'align.c' || echo '$(srcdir)/'`align.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-align.Tpo $(DEPDIR)/libluatex_a-align.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='align.c' object='libluatex_a-align.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-align.o `test -f 'align.c' || echo '$(srcdir)/'`align.c
+
+libluatex_a-align.obj: align.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-align.obj -MD -MP -MF $(DEPDIR)/libluatex_a-align.Tpo -c -o libluatex_a-align.obj `if test -f 'align.c'; then $(CYGPATH_W) 'align.c'; else $(CYGPATH_W) '$(srcdir)/align.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-align.Tpo $(DEPDIR)/libluatex_a-align.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='align.c' object='libluatex_a-align.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-align.obj `if test -f 'align.c'; then $(CYGPATH_W) 'align.c'; else $(CYGPATH_W) '$(srcdir)/align.c'; fi`
+
+libluatex_a-dumpdata.o: dumpdata.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dumpdata.o -MD -MP -MF $(DEPDIR)/libluatex_a-dumpdata.Tpo -c -o libluatex_a-dumpdata.o `test -f 'dumpdata.c' || echo '$(srcdir)/'`dumpdata.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-dumpdata.Tpo $(DEPDIR)/libluatex_a-dumpdata.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dumpdata.c' object='libluatex_a-dumpdata.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dumpdata.o `test -f 'dumpdata.c' || echo '$(srcdir)/'`dumpdata.c
+
+libluatex_a-dumpdata.obj: dumpdata.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-dumpdata.obj -MD -MP -MF $(DEPDIR)/libluatex_a-dumpdata.Tpo -c -o libluatex_a-dumpdata.obj `if test -f 'dumpdata.c'; then $(CYGPATH_W) 'dumpdata.c'; else $(CYGPATH_W) '$(srcdir)/dumpdata.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-dumpdata.Tpo $(DEPDIR)/libluatex_a-dumpdata.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dumpdata.c' object='libluatex_a-dumpdata.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-dumpdata.obj `if test -f 'dumpdata.c'; then $(CYGPATH_W) 'dumpdata.c'; else $(CYGPATH_W) '$(srcdir)/dumpdata.c'; fi`
+
+libluatex_a-expand.o: expand.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-expand.o -MD -MP -MF $(DEPDIR)/libluatex_a-expand.Tpo -c -o libluatex_a-expand.o `test -f 'expand.c' || echo '$(srcdir)/'`expand.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-expand.Tpo $(DEPDIR)/libluatex_a-expand.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='expand.c' object='libluatex_a-expand.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-linebreak.obj `if test -f 'luatexdir/tex/linebreak.c'; then $(CYGPATH_W) 'luatexdir/tex/linebreak.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/linebreak.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-expand.o `test -f 'expand.c' || echo '$(srcdir)/'`expand.c
-libluatex_a-math.o: luatexdir/tex/math.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-math.o -MD -MP -MF $(DEPDIR)/libluatex_a-math.Tpo -c -o libluatex_a-math.o `test -f 'luatexdir/tex/math.c' || echo '$(srcdir)/'`luatexdir/tex/math.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-math.Tpo $(DEPDIR)/libluatex_a-math.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/math.c' object='libluatex_a-math.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-expand.obj: expand.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-expand.obj -MD -MP -MF $(DEPDIR)/libluatex_a-expand.Tpo -c -o libluatex_a-expand.obj `if test -f 'expand.c'; then $(CYGPATH_W) 'expand.c'; else $(CYGPATH_W) '$(srcdir)/expand.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-expand.Tpo $(DEPDIR)/libluatex_a-expand.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='expand.c' object='libluatex_a-expand.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-math.o `test -f 'luatexdir/tex/math.c' || echo '$(srcdir)/'`luatexdir/tex/math.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-expand.obj `if test -f 'expand.c'; then $(CYGPATH_W) 'expand.c'; else $(CYGPATH_W) '$(srcdir)/expand.c'; fi`
-libluatex_a-math.obj: luatexdir/tex/math.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-math.obj -MD -MP -MF $(DEPDIR)/libluatex_a-math.Tpo -c -o libluatex_a-math.obj `if test -f 'luatexdir/tex/math.c'; then $(CYGPATH_W) 'luatexdir/tex/math.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/math.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-math.Tpo $(DEPDIR)/libluatex_a-math.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/math.c' object='libluatex_a-math.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-inputstack.o: inputstack.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-inputstack.o -MD -MP -MF $(DEPDIR)/libluatex_a-inputstack.Tpo -c -o libluatex_a-inputstack.o `test -f 'inputstack.c' || echo '$(srcdir)/'`inputstack.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-inputstack.Tpo $(DEPDIR)/libluatex_a-inputstack.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='inputstack.c' object='libluatex_a-inputstack.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-math.obj `if test -f 'luatexdir/tex/math.c'; then $(CYGPATH_W) 'luatexdir/tex/math.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/math.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-inputstack.o `test -f 'inputstack.c' || echo '$(srcdir)/'`inputstack.c
-libluatex_a-mlist.o: luatexdir/tex/mlist.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mlist.o -MD -MP -MF $(DEPDIR)/libluatex_a-mlist.Tpo -c -o libluatex_a-mlist.o `test -f 'luatexdir/tex/mlist.c' || echo '$(srcdir)/'`luatexdir/tex/mlist.c
+libluatex_a-inputstack.obj: inputstack.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-inputstack.obj -MD -MP -MF $(DEPDIR)/libluatex_a-inputstack.Tpo -c -o libluatex_a-inputstack.obj `if test -f 'inputstack.c'; then $(CYGPATH_W) 'inputstack.c'; else $(CYGPATH_W) '$(srcdir)/inputstack.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-inputstack.Tpo $(DEPDIR)/libluatex_a-inputstack.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='inputstack.c' object='libluatex_a-inputstack.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-inputstack.obj `if test -f 'inputstack.c'; then $(CYGPATH_W) 'inputstack.c'; else $(CYGPATH_W) '$(srcdir)/inputstack.c'; fi`
+
+libluatex_a-maincontrol.o: maincontrol.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-maincontrol.o -MD -MP -MF $(DEPDIR)/libluatex_a-maincontrol.Tpo -c -o libluatex_a-maincontrol.o `test -f 'maincontrol.c' || echo '$(srcdir)/'`maincontrol.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-maincontrol.Tpo $(DEPDIR)/libluatex_a-maincontrol.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maincontrol.c' object='libluatex_a-maincontrol.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-maincontrol.o `test -f 'maincontrol.c' || echo '$(srcdir)/'`maincontrol.c
+
+libluatex_a-maincontrol.obj: maincontrol.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-maincontrol.obj -MD -MP -MF $(DEPDIR)/libluatex_a-maincontrol.Tpo -c -o libluatex_a-maincontrol.obj `if test -f 'maincontrol.c'; then $(CYGPATH_W) 'maincontrol.c'; else $(CYGPATH_W) '$(srcdir)/maincontrol.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-maincontrol.Tpo $(DEPDIR)/libluatex_a-maincontrol.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maincontrol.c' object='libluatex_a-maincontrol.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-maincontrol.obj `if test -f 'maincontrol.c'; then $(CYGPATH_W) 'maincontrol.c'; else $(CYGPATH_W) '$(srcdir)/maincontrol.c'; fi`
+
+libluatex_a-mlist.o: mlist.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mlist.o -MD -MP -MF $(DEPDIR)/libluatex_a-mlist.Tpo -c -o libluatex_a-mlist.o `test -f 'mlist.c' || echo '$(srcdir)/'`mlist.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mlist.Tpo $(DEPDIR)/libluatex_a-mlist.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/mlist.c' object='libluatex_a-mlist.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mlist.c' object='libluatex_a-mlist.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mlist.o `test -f 'luatexdir/tex/mlist.c' || echo '$(srcdir)/'`luatexdir/tex/mlist.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mlist.o `test -f 'mlist.c' || echo '$(srcdir)/'`mlist.c
-libluatex_a-mlist.obj: luatexdir/tex/mlist.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mlist.obj -MD -MP -MF $(DEPDIR)/libluatex_a-mlist.Tpo -c -o libluatex_a-mlist.obj `if test -f 'luatexdir/tex/mlist.c'; then $(CYGPATH_W) 'luatexdir/tex/mlist.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/mlist.c'; fi`
+libluatex_a-mlist.obj: mlist.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mlist.obj -MD -MP -MF $(DEPDIR)/libluatex_a-mlist.Tpo -c -o libluatex_a-mlist.obj `if test -f 'mlist.c'; then $(CYGPATH_W) 'mlist.c'; else $(CYGPATH_W) '$(srcdir)/mlist.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mlist.Tpo $(DEPDIR)/libluatex_a-mlist.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/mlist.c' object='libluatex_a-mlist.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mlist.c' object='libluatex_a-mlist.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mlist.obj `if test -f 'luatexdir/tex/mlist.c'; then $(CYGPATH_W) 'luatexdir/tex/mlist.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/mlist.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mlist.obj `if test -f 'mlist.c'; then $(CYGPATH_W) 'mlist.c'; else $(CYGPATH_W) '$(srcdir)/mlist.c'; fi`
-libluatex_a-postlinebreak.o: luatexdir/tex/postlinebreak.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-postlinebreak.o -MD -MP -MF $(DEPDIR)/libluatex_a-postlinebreak.Tpo -c -o libluatex_a-postlinebreak.o `test -f 'luatexdir/tex/postlinebreak.c' || echo '$(srcdir)/'`luatexdir/tex/postlinebreak.c
+libluatex_a-postlinebreak.o: postlinebreak.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-postlinebreak.o -MD -MP -MF $(DEPDIR)/libluatex_a-postlinebreak.Tpo -c -o libluatex_a-postlinebreak.o `test -f 'postlinebreak.c' || echo '$(srcdir)/'`postlinebreak.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-postlinebreak.Tpo $(DEPDIR)/libluatex_a-postlinebreak.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/postlinebreak.c' object='libluatex_a-postlinebreak.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='postlinebreak.c' object='libluatex_a-postlinebreak.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-postlinebreak.o `test -f 'luatexdir/tex/postlinebreak.c' || echo '$(srcdir)/'`luatexdir/tex/postlinebreak.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-postlinebreak.o `test -f 'postlinebreak.c' || echo '$(srcdir)/'`postlinebreak.c
-libluatex_a-postlinebreak.obj: luatexdir/tex/postlinebreak.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-postlinebreak.obj -MD -MP -MF $(DEPDIR)/libluatex_a-postlinebreak.Tpo -c -o libluatex_a-postlinebreak.obj `if test -f 'luatexdir/tex/postlinebreak.c'; then $(CYGPATH_W) 'luatexdir/tex/postlinebreak.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/postlinebreak.c'; fi`
+libluatex_a-postlinebreak.obj: postlinebreak.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-postlinebreak.obj -MD -MP -MF $(DEPDIR)/libluatex_a-postlinebreak.Tpo -c -o libluatex_a-postlinebreak.obj `if test -f 'postlinebreak.c'; then $(CYGPATH_W) 'postlinebreak.c'; else $(CYGPATH_W) '$(srcdir)/postlinebreak.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-postlinebreak.Tpo $(DEPDIR)/libluatex_a-postlinebreak.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/postlinebreak.c' object='libluatex_a-postlinebreak.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='postlinebreak.c' object='libluatex_a-postlinebreak.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-postlinebreak.obj `if test -f 'luatexdir/tex/postlinebreak.c'; then $(CYGPATH_W) 'luatexdir/tex/postlinebreak.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/postlinebreak.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-postlinebreak.obj `if test -f 'postlinebreak.c'; then $(CYGPATH_W) 'postlinebreak.c'; else $(CYGPATH_W) '$(srcdir)/postlinebreak.c'; fi`
-libluatex_a-primitive.o: luatexdir/tex/primitive.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-primitive.o -MD -MP -MF $(DEPDIR)/libluatex_a-primitive.Tpo -c -o libluatex_a-primitive.o `test -f 'luatexdir/tex/primitive.c' || echo '$(srcdir)/'`luatexdir/tex/primitive.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-primitive.Tpo $(DEPDIR)/libluatex_a-primitive.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/primitive.c' object='libluatex_a-primitive.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-scanning.o: scanning.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-scanning.o -MD -MP -MF $(DEPDIR)/libluatex_a-scanning.Tpo -c -o libluatex_a-scanning.o `test -f 'scanning.c' || echo '$(srcdir)/'`scanning.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-scanning.Tpo $(DEPDIR)/libluatex_a-scanning.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scanning.c' object='libluatex_a-scanning.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-primitive.o `test -f 'luatexdir/tex/primitive.c' || echo '$(srcdir)/'`luatexdir/tex/primitive.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-scanning.o `test -f 'scanning.c' || echo '$(srcdir)/'`scanning.c
-libluatex_a-primitive.obj: luatexdir/tex/primitive.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-primitive.obj -MD -MP -MF $(DEPDIR)/libluatex_a-primitive.Tpo -c -o libluatex_a-primitive.obj `if test -f 'luatexdir/tex/primitive.c'; then $(CYGPATH_W) 'luatexdir/tex/primitive.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/primitive.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-primitive.Tpo $(DEPDIR)/libluatex_a-primitive.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/primitive.c' object='libluatex_a-primitive.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-scanning.obj: scanning.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-scanning.obj -MD -MP -MF $(DEPDIR)/libluatex_a-scanning.Tpo -c -o libluatex_a-scanning.obj `if test -f 'scanning.c'; then $(CYGPATH_W) 'scanning.c'; else $(CYGPATH_W) '$(srcdir)/scanning.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-scanning.Tpo $(DEPDIR)/libluatex_a-scanning.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scanning.c' object='libluatex_a-scanning.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-primitive.obj `if test -f 'luatexdir/tex/primitive.c'; then $(CYGPATH_W) 'luatexdir/tex/primitive.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/primitive.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-scanning.obj `if test -f 'scanning.c'; then $(CYGPATH_W) 'scanning.c'; else $(CYGPATH_W) '$(srcdir)/scanning.c'; fi`
-libluatex_a-texdeffont.o: luatexdir/tex/texdeffont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texdeffont.o -MD -MP -MF $(DEPDIR)/libluatex_a-texdeffont.Tpo -c -o libluatex_a-texdeffont.o `test -f 'luatexdir/tex/texdeffont.c' || echo '$(srcdir)/'`luatexdir/tex/texdeffont.c
+libluatex_a-texdeffont.o: texdeffont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texdeffont.o -MD -MP -MF $(DEPDIR)/libluatex_a-texdeffont.Tpo -c -o libluatex_a-texdeffont.o `test -f 'texdeffont.c' || echo '$(srcdir)/'`texdeffont.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texdeffont.Tpo $(DEPDIR)/libluatex_a-texdeffont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/texdeffont.c' object='libluatex_a-texdeffont.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texdeffont.c' object='libluatex_a-texdeffont.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texdeffont.o `test -f 'luatexdir/tex/texdeffont.c' || echo '$(srcdir)/'`luatexdir/tex/texdeffont.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texdeffont.o `test -f 'texdeffont.c' || echo '$(srcdir)/'`texdeffont.c
-libluatex_a-texdeffont.obj: luatexdir/tex/texdeffont.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texdeffont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texdeffont.Tpo -c -o libluatex_a-texdeffont.obj `if test -f 'luatexdir/tex/texdeffont.c'; then $(CYGPATH_W) 'luatexdir/tex/texdeffont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/texdeffont.c'; fi`
+libluatex_a-texdeffont.obj: texdeffont.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texdeffont.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texdeffont.Tpo -c -o libluatex_a-texdeffont.obj `if test -f 'texdeffont.c'; then $(CYGPATH_W) 'texdeffont.c'; else $(CYGPATH_W) '$(srcdir)/texdeffont.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texdeffont.Tpo $(DEPDIR)/libluatex_a-texdeffont.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/texdeffont.c' object='libluatex_a-texdeffont.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texdeffont.c' object='libluatex_a-texdeffont.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texdeffont.obj `if test -f 'luatexdir/tex/texdeffont.c'; then $(CYGPATH_W) 'luatexdir/tex/texdeffont.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/texdeffont.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texdeffont.obj `if test -f 'texdeffont.c'; then $(CYGPATH_W) 'texdeffont.c'; else $(CYGPATH_W) '$(srcdir)/texdeffont.c'; fi`
-libluatex_a-texnodes.o: luatexdir/tex/texnodes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texnodes.o -MD -MP -MF $(DEPDIR)/libluatex_a-texnodes.Tpo -c -o libluatex_a-texnodes.o `test -f 'luatexdir/tex/texnodes.c' || echo '$(srcdir)/'`luatexdir/tex/texnodes.c
+libluatex_a-texnodes.o: texnodes.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texnodes.o -MD -MP -MF $(DEPDIR)/libluatex_a-texnodes.Tpo -c -o libluatex_a-texnodes.o `test -f 'texnodes.c' || echo '$(srcdir)/'`texnodes.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texnodes.Tpo $(DEPDIR)/libluatex_a-texnodes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/texnodes.c' object='libluatex_a-texnodes.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texnodes.c' object='libluatex_a-texnodes.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texnodes.o `test -f 'luatexdir/tex/texnodes.c' || echo '$(srcdir)/'`luatexdir/tex/texnodes.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texnodes.o `test -f 'texnodes.c' || echo '$(srcdir)/'`texnodes.c
-libluatex_a-texnodes.obj: luatexdir/tex/texnodes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texnodes.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texnodes.Tpo -c -o libluatex_a-texnodes.obj `if test -f 'luatexdir/tex/texnodes.c'; then $(CYGPATH_W) 'luatexdir/tex/texnodes.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/texnodes.c'; fi`
+libluatex_a-texnodes.obj: texnodes.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texnodes.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texnodes.Tpo -c -o libluatex_a-texnodes.obj `if test -f 'texnodes.c'; then $(CYGPATH_W) 'texnodes.c'; else $(CYGPATH_W) '$(srcdir)/texnodes.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texnodes.Tpo $(DEPDIR)/libluatex_a-texnodes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/texnodes.c' object='libluatex_a-texnodes.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texnodes.c' object='libluatex_a-texnodes.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texnodes.obj `if test -f 'luatexdir/tex/texnodes.c'; then $(CYGPATH_W) 'luatexdir/tex/texnodes.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/texnodes.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texnodes.obj `if test -f 'texnodes.c'; then $(CYGPATH_W) 'texnodes.c'; else $(CYGPATH_W) '$(srcdir)/texnodes.c'; fi`
-libluatex_a-texpdf.o: luatexdir/tex/texpdf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texpdf.o -MD -MP -MF $(DEPDIR)/libluatex_a-texpdf.Tpo -c -o libluatex_a-texpdf.o `test -f 'luatexdir/tex/texpdf.c' || echo '$(srcdir)/'`luatexdir/tex/texpdf.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texpdf.Tpo $(DEPDIR)/libluatex_a-texpdf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/texpdf.c' object='libluatex_a-texpdf.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-arithmetic.o: arithmetic.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-arithmetic.o -MD -MP -MF $(DEPDIR)/libluatex_a-arithmetic.Tpo -c -o libluatex_a-arithmetic.o `test -f 'arithmetic.c' || echo '$(srcdir)/'`arithmetic.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-arithmetic.Tpo $(DEPDIR)/libluatex_a-arithmetic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='arithmetic.c' object='libluatex_a-arithmetic.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texpdf.o `test -f 'luatexdir/tex/texpdf.c' || echo '$(srcdir)/'`luatexdir/tex/texpdf.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-arithmetic.o `test -f 'arithmetic.c' || echo '$(srcdir)/'`arithmetic.c
-libluatex_a-texpdf.obj: luatexdir/tex/texpdf.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texpdf.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texpdf.Tpo -c -o libluatex_a-texpdf.obj `if test -f 'luatexdir/tex/texpdf.c'; then $(CYGPATH_W) 'luatexdir/tex/texpdf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/texpdf.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texpdf.Tpo $(DEPDIR)/libluatex_a-texpdf.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/texpdf.c' object='libluatex_a-texpdf.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-arithmetic.obj: arithmetic.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-arithmetic.obj -MD -MP -MF $(DEPDIR)/libluatex_a-arithmetic.Tpo -c -o libluatex_a-arithmetic.obj `if test -f 'arithmetic.c'; then $(CYGPATH_W) 'arithmetic.c'; else $(CYGPATH_W) '$(srcdir)/arithmetic.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-arithmetic.Tpo $(DEPDIR)/libluatex_a-arithmetic.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='arithmetic.c' object='libluatex_a-arithmetic.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texpdf.obj `if test -f 'luatexdir/tex/texpdf.c'; then $(CYGPATH_W) 'luatexdir/tex/texpdf.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/texpdf.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-arithmetic.obj `if test -f 'arithmetic.c'; then $(CYGPATH_W) 'arithmetic.c'; else $(CYGPATH_W) '$(srcdir)/arithmetic.c'; fi`
-libluatex_a-textoken.o: luatexdir/tex/textoken.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textoken.o -MD -MP -MF $(DEPDIR)/libluatex_a-textoken.Tpo -c -o libluatex_a-textoken.o `test -f 'luatexdir/tex/textoken.c' || echo '$(srcdir)/'`luatexdir/tex/textoken.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-textoken.Tpo $(DEPDIR)/libluatex_a-textoken.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/textoken.c' object='libluatex_a-textoken.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-conditional.o: conditional.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-conditional.o -MD -MP -MF $(DEPDIR)/libluatex_a-conditional.Tpo -c -o libluatex_a-conditional.o `test -f 'conditional.c' || echo '$(srcdir)/'`conditional.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-conditional.Tpo $(DEPDIR)/libluatex_a-conditional.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conditional.c' object='libluatex_a-conditional.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textoken.o `test -f 'luatexdir/tex/textoken.c' || echo '$(srcdir)/'`luatexdir/tex/textoken.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-conditional.o `test -f 'conditional.c' || echo '$(srcdir)/'`conditional.c
-libluatex_a-textoken.obj: luatexdir/tex/textoken.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textoken.obj -MD -MP -MF $(DEPDIR)/libluatex_a-textoken.Tpo -c -o libluatex_a-textoken.obj `if test -f 'luatexdir/tex/textoken.c'; then $(CYGPATH_W) 'luatexdir/tex/textoken.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/textoken.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-textoken.Tpo $(DEPDIR)/libluatex_a-textoken.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/tex/textoken.c' object='libluatex_a-textoken.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-conditional.obj: conditional.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-conditional.obj -MD -MP -MF $(DEPDIR)/libluatex_a-conditional.Tpo -c -o libluatex_a-conditional.obj `if test -f 'conditional.c'; then $(CYGPATH_W) 'conditional.c'; else $(CYGPATH_W) '$(srcdir)/conditional.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-conditional.Tpo $(DEPDIR)/libluatex_a-conditional.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conditional.c' object='libluatex_a-conditional.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-conditional.obj `if test -f 'conditional.c'; then $(CYGPATH_W) 'conditional.c'; else $(CYGPATH_W) '$(srcdir)/conditional.c'; fi`
+
+libluatex_a-equivalents.o: equivalents.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-equivalents.o -MD -MP -MF $(DEPDIR)/libluatex_a-equivalents.Tpo -c -o libluatex_a-equivalents.o `test -f 'equivalents.c' || echo '$(srcdir)/'`equivalents.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-equivalents.Tpo $(DEPDIR)/libluatex_a-equivalents.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='equivalents.c' object='libluatex_a-equivalents.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-equivalents.o `test -f 'equivalents.c' || echo '$(srcdir)/'`equivalents.c
+
+libluatex_a-equivalents.obj: equivalents.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-equivalents.obj -MD -MP -MF $(DEPDIR)/libluatex_a-equivalents.Tpo -c -o libluatex_a-equivalents.obj `if test -f 'equivalents.c'; then $(CYGPATH_W) 'equivalents.c'; else $(CYGPATH_W) '$(srcdir)/equivalents.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-equivalents.Tpo $(DEPDIR)/libluatex_a-equivalents.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='equivalents.c' object='libluatex_a-equivalents.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-equivalents.obj `if test -f 'equivalents.c'; then $(CYGPATH_W) 'equivalents.c'; else $(CYGPATH_W) '$(srcdir)/equivalents.c'; fi`
+
+libluatex_a-extensions.o: extensions.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-extensions.o -MD -MP -MF $(DEPDIR)/libluatex_a-extensions.Tpo -c -o libluatex_a-extensions.o `test -f 'extensions.c' || echo '$(srcdir)/'`extensions.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-extensions.Tpo $(DEPDIR)/libluatex_a-extensions.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='extensions.c' object='libluatex_a-extensions.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-extensions.o `test -f 'extensions.c' || echo '$(srcdir)/'`extensions.c
+
+libluatex_a-extensions.obj: extensions.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-extensions.obj -MD -MP -MF $(DEPDIR)/libluatex_a-extensions.Tpo -c -o libluatex_a-extensions.obj `if test -f 'extensions.c'; then $(CYGPATH_W) 'extensions.c'; else $(CYGPATH_W) '$(srcdir)/extensions.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-extensions.Tpo $(DEPDIR)/libluatex_a-extensions.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='extensions.c' object='libluatex_a-extensions.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-extensions.obj `if test -f 'extensions.c'; then $(CYGPATH_W) 'extensions.c'; else $(CYGPATH_W) '$(srcdir)/extensions.c'; fi`
+
+libluatex_a-commands.o: commands.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-commands.o -MD -MP -MF $(DEPDIR)/libluatex_a-commands.Tpo -c -o libluatex_a-commands.o `test -f 'commands.c' || echo '$(srcdir)/'`commands.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-commands.Tpo $(DEPDIR)/libluatex_a-commands.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='commands.c' object='libluatex_a-commands.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textoken.obj `if test -f 'luatexdir/tex/textoken.c'; then $(CYGPATH_W) 'luatexdir/tex/textoken.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/tex/textoken.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-commands.o `test -f 'commands.c' || echo '$(srcdir)/'`commands.c
-libluatex_a-textcodes.o: luatexdir/textcodes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textcodes.o -MD -MP -MF $(DEPDIR)/libluatex_a-textcodes.Tpo -c -o libluatex_a-textcodes.o `test -f 'luatexdir/textcodes.c' || echo '$(srcdir)/'`luatexdir/textcodes.c
+libluatex_a-commands.obj: commands.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-commands.obj -MD -MP -MF $(DEPDIR)/libluatex_a-commands.Tpo -c -o libluatex_a-commands.obj `if test -f 'commands.c'; then $(CYGPATH_W) 'commands.c'; else $(CYGPATH_W) '$(srcdir)/commands.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-commands.Tpo $(DEPDIR)/libluatex_a-commands.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='commands.c' object='libluatex_a-commands.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-commands.obj `if test -f 'commands.c'; then $(CYGPATH_W) 'commands.c'; else $(CYGPATH_W) '$(srcdir)/commands.c'; fi`
+
+libluatex_a-linebreak.o: linebreak.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-linebreak.o -MD -MP -MF $(DEPDIR)/libluatex_a-linebreak.Tpo -c -o libluatex_a-linebreak.o `test -f 'linebreak.c' || echo '$(srcdir)/'`linebreak.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-linebreak.Tpo $(DEPDIR)/libluatex_a-linebreak.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='linebreak.c' object='libluatex_a-linebreak.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-linebreak.o `test -f 'linebreak.c' || echo '$(srcdir)/'`linebreak.c
+
+libluatex_a-linebreak.obj: linebreak.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-linebreak.obj -MD -MP -MF $(DEPDIR)/libluatex_a-linebreak.Tpo -c -o libluatex_a-linebreak.obj `if test -f 'linebreak.c'; then $(CYGPATH_W) 'linebreak.c'; else $(CYGPATH_W) '$(srcdir)/linebreak.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-linebreak.Tpo $(DEPDIR)/libluatex_a-linebreak.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='linebreak.c' object='libluatex_a-linebreak.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-linebreak.obj `if test -f 'linebreak.c'; then $(CYGPATH_W) 'linebreak.c'; else $(CYGPATH_W) '$(srcdir)/linebreak.c'; fi`
+
+libluatex_a-mathcodes.o: mathcodes.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mathcodes.o -MD -MP -MF $(DEPDIR)/libluatex_a-mathcodes.Tpo -c -o libluatex_a-mathcodes.o `test -f 'mathcodes.c' || echo '$(srcdir)/'`mathcodes.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mathcodes.Tpo $(DEPDIR)/libluatex_a-mathcodes.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mathcodes.c' object='libluatex_a-mathcodes.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mathcodes.o `test -f 'mathcodes.c' || echo '$(srcdir)/'`mathcodes.c
+
+libluatex_a-mathcodes.obj: mathcodes.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mathcodes.obj -MD -MP -MF $(DEPDIR)/libluatex_a-mathcodes.Tpo -c -o libluatex_a-mathcodes.obj `if test -f 'mathcodes.c'; then $(CYGPATH_W) 'mathcodes.c'; else $(CYGPATH_W) '$(srcdir)/mathcodes.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mathcodes.Tpo $(DEPDIR)/libluatex_a-mathcodes.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mathcodes.c' object='libluatex_a-mathcodes.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mathcodes.obj `if test -f 'mathcodes.c'; then $(CYGPATH_W) 'mathcodes.c'; else $(CYGPATH_W) '$(srcdir)/mathcodes.c'; fi`
+
+libluatex_a-nesting.o: nesting.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-nesting.o -MD -MP -MF $(DEPDIR)/libluatex_a-nesting.Tpo -c -o libluatex_a-nesting.o `test -f 'nesting.c' || echo '$(srcdir)/'`nesting.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-nesting.Tpo $(DEPDIR)/libluatex_a-nesting.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nesting.c' object='libluatex_a-nesting.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-nesting.o `test -f 'nesting.c' || echo '$(srcdir)/'`nesting.c
+
+libluatex_a-nesting.obj: nesting.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-nesting.obj -MD -MP -MF $(DEPDIR)/libluatex_a-nesting.Tpo -c -o libluatex_a-nesting.obj `if test -f 'nesting.c'; then $(CYGPATH_W) 'nesting.c'; else $(CYGPATH_W) '$(srcdir)/nesting.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-nesting.Tpo $(DEPDIR)/libluatex_a-nesting.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nesting.c' object='libluatex_a-nesting.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-nesting.obj `if test -f 'nesting.c'; then $(CYGPATH_W) 'nesting.c'; else $(CYGPATH_W) '$(srcdir)/nesting.c'; fi`
+
+libluatex_a-primitive.o: primitive.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-primitive.o -MD -MP -MF $(DEPDIR)/libluatex_a-primitive.Tpo -c -o libluatex_a-primitive.o `test -f 'primitive.c' || echo '$(srcdir)/'`primitive.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-primitive.Tpo $(DEPDIR)/libluatex_a-primitive.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='primitive.c' object='libluatex_a-primitive.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-primitive.o `test -f 'primitive.c' || echo '$(srcdir)/'`primitive.c
+
+libluatex_a-primitive.obj: primitive.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-primitive.obj -MD -MP -MF $(DEPDIR)/libluatex_a-primitive.Tpo -c -o libluatex_a-primitive.obj `if test -f 'primitive.c'; then $(CYGPATH_W) 'primitive.c'; else $(CYGPATH_W) '$(srcdir)/primitive.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-primitive.Tpo $(DEPDIR)/libluatex_a-primitive.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='primitive.c' object='libluatex_a-primitive.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-primitive.obj `if test -f 'primitive.c'; then $(CYGPATH_W) 'primitive.c'; else $(CYGPATH_W) '$(srcdir)/primitive.c'; fi`
+
+libluatex_a-texfileio.o: texfileio.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texfileio.o -MD -MP -MF $(DEPDIR)/libluatex_a-texfileio.Tpo -c -o libluatex_a-texfileio.o `test -f 'texfileio.c' || echo '$(srcdir)/'`texfileio.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texfileio.Tpo $(DEPDIR)/libluatex_a-texfileio.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texfileio.c' object='libluatex_a-texfileio.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texfileio.o `test -f 'texfileio.c' || echo '$(srcdir)/'`texfileio.c
+
+libluatex_a-texfileio.obj: texfileio.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texfileio.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texfileio.Tpo -c -o libluatex_a-texfileio.obj `if test -f 'texfileio.c'; then $(CYGPATH_W) 'texfileio.c'; else $(CYGPATH_W) '$(srcdir)/texfileio.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texfileio.Tpo $(DEPDIR)/libluatex_a-texfileio.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texfileio.c' object='libluatex_a-texfileio.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texfileio.obj `if test -f 'texfileio.c'; then $(CYGPATH_W) 'texfileio.c'; else $(CYGPATH_W) '$(srcdir)/texfileio.c'; fi`
+
+libluatex_a-textcodes.o: textcodes.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textcodes.o -MD -MP -MF $(DEPDIR)/libluatex_a-textcodes.Tpo -c -o libluatex_a-textcodes.o `test -f 'textcodes.c' || echo '$(srcdir)/'`textcodes.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-textcodes.Tpo $(DEPDIR)/libluatex_a-textcodes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/textcodes.c' object='libluatex_a-textcodes.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='textcodes.c' object='libluatex_a-textcodes.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textcodes.o `test -f 'luatexdir/textcodes.c' || echo '$(srcdir)/'`luatexdir/textcodes.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textcodes.o `test -f 'textcodes.c' || echo '$(srcdir)/'`textcodes.c
-libluatex_a-textcodes.obj: luatexdir/textcodes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textcodes.obj -MD -MP -MF $(DEPDIR)/libluatex_a-textcodes.Tpo -c -o libluatex_a-textcodes.obj `if test -f 'luatexdir/textcodes.c'; then $(CYGPATH_W) 'luatexdir/textcodes.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/textcodes.c'; fi`
+libluatex_a-textcodes.obj: textcodes.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textcodes.obj -MD -MP -MF $(DEPDIR)/libluatex_a-textcodes.Tpo -c -o libluatex_a-textcodes.obj `if test -f 'textcodes.c'; then $(CYGPATH_W) 'textcodes.c'; else $(CYGPATH_W) '$(srcdir)/textcodes.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-textcodes.Tpo $(DEPDIR)/libluatex_a-textcodes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/textcodes.c' object='libluatex_a-textcodes.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='textcodes.c' object='libluatex_a-textcodes.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textcodes.obj `if test -f 'luatexdir/textcodes.c'; then $(CYGPATH_W) 'luatexdir/textcodes.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/textcodes.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textcodes.obj `if test -f 'textcodes.c'; then $(CYGPATH_W) 'textcodes.c'; else $(CYGPATH_W) '$(srcdir)/textcodes.c'; fi`
-libluatex_a-avl.o: luatexdir/utils/avl.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avl.o -MD -MP -MF $(DEPDIR)/libluatex_a-avl.Tpo -c -o libluatex_a-avl.o `test -f 'luatexdir/utils/avl.c' || echo '$(srcdir)/'`luatexdir/utils/avl.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avl.Tpo $(DEPDIR)/libluatex_a-avl.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/avl.c' object='libluatex_a-avl.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-buildpage.o: buildpage.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-buildpage.o -MD -MP -MF $(DEPDIR)/libluatex_a-buildpage.Tpo -c -o libluatex_a-buildpage.o `test -f 'buildpage.c' || echo '$(srcdir)/'`buildpage.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-buildpage.Tpo $(DEPDIR)/libluatex_a-buildpage.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='buildpage.c' object='libluatex_a-buildpage.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avl.o `test -f 'luatexdir/utils/avl.c' || echo '$(srcdir)/'`luatexdir/utils/avl.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-buildpage.o `test -f 'buildpage.c' || echo '$(srcdir)/'`buildpage.c
-libluatex_a-avl.obj: luatexdir/utils/avl.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avl.obj -MD -MP -MF $(DEPDIR)/libluatex_a-avl.Tpo -c -o libluatex_a-avl.obj `if test -f 'luatexdir/utils/avl.c'; then $(CYGPATH_W) 'luatexdir/utils/avl.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/avl.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avl.Tpo $(DEPDIR)/libluatex_a-avl.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/avl.c' object='libluatex_a-avl.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-buildpage.obj: buildpage.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-buildpage.obj -MD -MP -MF $(DEPDIR)/libluatex_a-buildpage.Tpo -c -o libluatex_a-buildpage.obj `if test -f 'buildpage.c'; then $(CYGPATH_W) 'buildpage.c'; else $(CYGPATH_W) '$(srcdir)/buildpage.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-buildpage.Tpo $(DEPDIR)/libluatex_a-buildpage.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='buildpage.c' object='libluatex_a-buildpage.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avl.obj `if test -f 'luatexdir/utils/avl.c'; then $(CYGPATH_W) 'luatexdir/utils/avl.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/avl.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-buildpage.obj `if test -f 'buildpage.c'; then $(CYGPATH_W) 'buildpage.c'; else $(CYGPATH_W) '$(srcdir)/buildpage.c'; fi`
-libluatex_a-avlstuff.o: luatexdir/utils/avlstuff.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avlstuff.o -MD -MP -MF $(DEPDIR)/libluatex_a-avlstuff.Tpo -c -o libluatex_a-avlstuff.o `test -f 'luatexdir/utils/avlstuff.c' || echo '$(srcdir)/'`luatexdir/utils/avlstuff.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avlstuff.Tpo $(DEPDIR)/libluatex_a-avlstuff.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/avlstuff.c' object='libluatex_a-avlstuff.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-directions.o: directions.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-directions.o -MD -MP -MF $(DEPDIR)/libluatex_a-directions.Tpo -c -o libluatex_a-directions.o `test -f 'directions.c' || echo '$(srcdir)/'`directions.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-directions.Tpo $(DEPDIR)/libluatex_a-directions.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='directions.c' object='libluatex_a-directions.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avlstuff.o `test -f 'luatexdir/utils/avlstuff.c' || echo '$(srcdir)/'`luatexdir/utils/avlstuff.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-directions.o `test -f 'directions.c' || echo '$(srcdir)/'`directions.c
-libluatex_a-avlstuff.obj: luatexdir/utils/avlstuff.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avlstuff.obj -MD -MP -MF $(DEPDIR)/libluatex_a-avlstuff.Tpo -c -o libluatex_a-avlstuff.obj `if test -f 'luatexdir/utils/avlstuff.c'; then $(CYGPATH_W) 'luatexdir/utils/avlstuff.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/avlstuff.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avlstuff.Tpo $(DEPDIR)/libluatex_a-avlstuff.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/avlstuff.c' object='libluatex_a-avlstuff.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-directions.obj: directions.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-directions.obj -MD -MP -MF $(DEPDIR)/libluatex_a-directions.Tpo -c -o libluatex_a-directions.obj `if test -f 'directions.c'; then $(CYGPATH_W) 'directions.c'; else $(CYGPATH_W) '$(srcdir)/directions.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-directions.Tpo $(DEPDIR)/libluatex_a-directions.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='directions.c' object='libluatex_a-directions.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avlstuff.obj `if test -f 'luatexdir/utils/avlstuff.c'; then $(CYGPATH_W) 'luatexdir/utils/avlstuff.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/avlstuff.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-directions.obj `if test -f 'directions.c'; then $(CYGPATH_W) 'directions.c'; else $(CYGPATH_W) '$(srcdir)/directions.c'; fi`
-libluatex_a-synctex.o: luatexdir/utils/synctex.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-synctex.o -MD -MP -MF $(DEPDIR)/libluatex_a-synctex.Tpo -c -o libluatex_a-synctex.o `test -f 'luatexdir/utils/synctex.c' || echo '$(srcdir)/'`luatexdir/utils/synctex.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-synctex.Tpo $(DEPDIR)/libluatex_a-synctex.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/synctex.c' object='libluatex_a-synctex.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-errors.o: errors.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-errors.o -MD -MP -MF $(DEPDIR)/libluatex_a-errors.Tpo -c -o libluatex_a-errors.o `test -f 'errors.c' || echo '$(srcdir)/'`errors.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-errors.Tpo $(DEPDIR)/libluatex_a-errors.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='errors.c' object='libluatex_a-errors.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-synctex.o `test -f 'luatexdir/utils/synctex.c' || echo '$(srcdir)/'`luatexdir/utils/synctex.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-errors.o `test -f 'errors.c' || echo '$(srcdir)/'`errors.c
-libluatex_a-synctex.obj: luatexdir/utils/synctex.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-synctex.obj -MD -MP -MF $(DEPDIR)/libluatex_a-synctex.Tpo -c -o libluatex_a-synctex.obj `if test -f 'luatexdir/utils/synctex.c'; then $(CYGPATH_W) 'luatexdir/utils/synctex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/synctex.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-synctex.Tpo $(DEPDIR)/libluatex_a-synctex.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/synctex.c' object='libluatex_a-synctex.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-errors.obj: errors.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-errors.obj -MD -MP -MF $(DEPDIR)/libluatex_a-errors.Tpo -c -o libluatex_a-errors.obj `if test -f 'errors.c'; then $(CYGPATH_W) 'errors.c'; else $(CYGPATH_W) '$(srcdir)/errors.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-errors.Tpo $(DEPDIR)/libluatex_a-errors.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='errors.c' object='libluatex_a-errors.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-synctex.obj `if test -f 'luatexdir/utils/synctex.c'; then $(CYGPATH_W) 'luatexdir/utils/synctex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/synctex.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-errors.obj `if test -f 'errors.c'; then $(CYGPATH_W) 'errors.c'; else $(CYGPATH_W) '$(srcdir)/errors.c'; fi`
+
+libluatex_a-filename.o: filename.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-filename.o -MD -MP -MF $(DEPDIR)/libluatex_a-filename.Tpo -c -o libluatex_a-filename.o `test -f 'filename.c' || echo '$(srcdir)/'`filename.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-filename.Tpo $(DEPDIR)/libluatex_a-filename.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='filename.c' object='libluatex_a-filename.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-filename.o `test -f 'filename.c' || echo '$(srcdir)/'`filename.c
+
+libluatex_a-filename.obj: filename.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-filename.obj -MD -MP -MF $(DEPDIR)/libluatex_a-filename.Tpo -c -o libluatex_a-filename.obj `if test -f 'filename.c'; then $(CYGPATH_W) 'filename.c'; else $(CYGPATH_W) '$(srcdir)/filename.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-filename.Tpo $(DEPDIR)/libluatex_a-filename.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='filename.c' object='libluatex_a-filename.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-filename.obj `if test -f 'filename.c'; then $(CYGPATH_W) 'filename.c'; else $(CYGPATH_W) '$(srcdir)/filename.c'; fi`
+
+libluatex_a-mainbody.o: mainbody.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mainbody.o -MD -MP -MF $(DEPDIR)/libluatex_a-mainbody.Tpo -c -o libluatex_a-mainbody.o `test -f 'mainbody.c' || echo '$(srcdir)/'`mainbody.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mainbody.Tpo $(DEPDIR)/libluatex_a-mainbody.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainbody.c' object='libluatex_a-mainbody.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mainbody.o `test -f 'mainbody.c' || echo '$(srcdir)/'`mainbody.c
+
+libluatex_a-mainbody.obj: mainbody.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-mainbody.obj -MD -MP -MF $(DEPDIR)/libluatex_a-mainbody.Tpo -c -o libluatex_a-mainbody.obj `if test -f 'mainbody.c'; then $(CYGPATH_W) 'mainbody.c'; else $(CYGPATH_W) '$(srcdir)/mainbody.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-mainbody.Tpo $(DEPDIR)/libluatex_a-mainbody.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainbody.c' object='libluatex_a-mainbody.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-mainbody.obj `if test -f 'mainbody.c'; then $(CYGPATH_W) 'mainbody.c'; else $(CYGPATH_W) '$(srcdir)/mainbody.c'; fi`
+
+libluatex_a-memoryword.o: memoryword.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-memoryword.o -MD -MP -MF $(DEPDIR)/libluatex_a-memoryword.Tpo -c -o libluatex_a-memoryword.o `test -f 'memoryword.c' || echo '$(srcdir)/'`memoryword.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-memoryword.Tpo $(DEPDIR)/libluatex_a-memoryword.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='memoryword.c' object='libluatex_a-memoryword.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-memoryword.o `test -f 'memoryword.c' || echo '$(srcdir)/'`memoryword.c
-libluatex_a-utils.o: luatexdir/utils/utils.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-utils.o -MD -MP -MF $(DEPDIR)/libluatex_a-utils.Tpo -c -o libluatex_a-utils.o `test -f 'luatexdir/utils/utils.c' || echo '$(srcdir)/'`luatexdir/utils/utils.c
+libluatex_a-memoryword.obj: memoryword.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-memoryword.obj -MD -MP -MF $(DEPDIR)/libluatex_a-memoryword.Tpo -c -o libluatex_a-memoryword.obj `if test -f 'memoryword.c'; then $(CYGPATH_W) 'memoryword.c'; else $(CYGPATH_W) '$(srcdir)/memoryword.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-memoryword.Tpo $(DEPDIR)/libluatex_a-memoryword.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='memoryword.c' object='libluatex_a-memoryword.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-memoryword.obj `if test -f 'memoryword.c'; then $(CYGPATH_W) 'memoryword.c'; else $(CYGPATH_W) '$(srcdir)/memoryword.c'; fi`
+
+libluatex_a-packaging.o: packaging.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-packaging.o -MD -MP -MF $(DEPDIR)/libluatex_a-packaging.Tpo -c -o libluatex_a-packaging.o `test -f 'packaging.c' || echo '$(srcdir)/'`packaging.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-packaging.Tpo $(DEPDIR)/libluatex_a-packaging.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packaging.c' object='libluatex_a-packaging.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-packaging.o `test -f 'packaging.c' || echo '$(srcdir)/'`packaging.c
+
+libluatex_a-packaging.obj: packaging.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-packaging.obj -MD -MP -MF $(DEPDIR)/libluatex_a-packaging.Tpo -c -o libluatex_a-packaging.obj `if test -f 'packaging.c'; then $(CYGPATH_W) 'packaging.c'; else $(CYGPATH_W) '$(srcdir)/packaging.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-packaging.Tpo $(DEPDIR)/libluatex_a-packaging.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packaging.c' object='libluatex_a-packaging.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-packaging.obj `if test -f 'packaging.c'; then $(CYGPATH_W) 'packaging.c'; else $(CYGPATH_W) '$(srcdir)/packaging.c'; fi`
+
+libluatex_a-printing.o: printing.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-printing.o -MD -MP -MF $(DEPDIR)/libluatex_a-printing.Tpo -c -o libluatex_a-printing.o `test -f 'printing.c' || echo '$(srcdir)/'`printing.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-printing.Tpo $(DEPDIR)/libluatex_a-printing.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='printing.c' object='libluatex_a-printing.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-printing.o `test -f 'printing.c' || echo '$(srcdir)/'`printing.c
+
+libluatex_a-printing.obj: printing.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-printing.obj -MD -MP -MF $(DEPDIR)/libluatex_a-printing.Tpo -c -o libluatex_a-printing.obj `if test -f 'printing.c'; then $(CYGPATH_W) 'printing.c'; else $(CYGPATH_W) '$(srcdir)/printing.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-printing.Tpo $(DEPDIR)/libluatex_a-printing.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='printing.c' object='libluatex_a-printing.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-printing.obj `if test -f 'printing.c'; then $(CYGPATH_W) 'printing.c'; else $(CYGPATH_W) '$(srcdir)/printing.c'; fi`
+
+libluatex_a-stringpool.o: stringpool.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-stringpool.o -MD -MP -MF $(DEPDIR)/libluatex_a-stringpool.Tpo -c -o libluatex_a-stringpool.o `test -f 'stringpool.c' || echo '$(srcdir)/'`stringpool.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-stringpool.Tpo $(DEPDIR)/libluatex_a-stringpool.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stringpool.c' object='libluatex_a-stringpool.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-stringpool.o `test -f 'stringpool.c' || echo '$(srcdir)/'`stringpool.c
+
+libluatex_a-stringpool.obj: stringpool.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-stringpool.obj -MD -MP -MF $(DEPDIR)/libluatex_a-stringpool.Tpo -c -o libluatex_a-stringpool.obj `if test -f 'stringpool.c'; then $(CYGPATH_W) 'stringpool.c'; else $(CYGPATH_W) '$(srcdir)/stringpool.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-stringpool.Tpo $(DEPDIR)/libluatex_a-stringpool.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stringpool.c' object='libluatex_a-stringpool.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-stringpool.obj `if test -f 'stringpool.c'; then $(CYGPATH_W) 'stringpool.c'; else $(CYGPATH_W) '$(srcdir)/stringpool.c'; fi`
+
+libluatex_a-texmath.o: texmath.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texmath.o -MD -MP -MF $(DEPDIR)/libluatex_a-texmath.Tpo -c -o libluatex_a-texmath.o `test -f 'texmath.c' || echo '$(srcdir)/'`texmath.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texmath.Tpo $(DEPDIR)/libluatex_a-texmath.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texmath.c' object='libluatex_a-texmath.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texmath.o `test -f 'texmath.c' || echo '$(srcdir)/'`texmath.c
+
+libluatex_a-texmath.obj: texmath.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-texmath.obj -MD -MP -MF $(DEPDIR)/libluatex_a-texmath.Tpo -c -o libluatex_a-texmath.obj `if test -f 'texmath.c'; then $(CYGPATH_W) 'texmath.c'; else $(CYGPATH_W) '$(srcdir)/texmath.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-texmath.Tpo $(DEPDIR)/libluatex_a-texmath.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='texmath.c' object='libluatex_a-texmath.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-texmath.obj `if test -f 'texmath.c'; then $(CYGPATH_W) 'texmath.c'; else $(CYGPATH_W) '$(srcdir)/texmath.c'; fi`
+
+libluatex_a-textoken.o: textoken.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textoken.o -MD -MP -MF $(DEPDIR)/libluatex_a-textoken.Tpo -c -o libluatex_a-textoken.o `test -f 'textoken.c' || echo '$(srcdir)/'`textoken.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-textoken.Tpo $(DEPDIR)/libluatex_a-textoken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='textoken.c' object='libluatex_a-textoken.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textoken.o `test -f 'textoken.c' || echo '$(srcdir)/'`textoken.c
+
+libluatex_a-textoken.obj: textoken.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-textoken.obj -MD -MP -MF $(DEPDIR)/libluatex_a-textoken.Tpo -c -o libluatex_a-textoken.obj `if test -f 'textoken.c'; then $(CYGPATH_W) 'textoken.c'; else $(CYGPATH_W) '$(srcdir)/textoken.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-textoken.Tpo $(DEPDIR)/libluatex_a-textoken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='textoken.c' object='libluatex_a-textoken.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-textoken.obj `if test -f 'textoken.c'; then $(CYGPATH_W) 'textoken.c'; else $(CYGPATH_W) '$(srcdir)/textoken.c'; fi`
+
+libluatex_a-utils.o: utils.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-utils.o -MD -MP -MF $(DEPDIR)/libluatex_a-utils.Tpo -c -o libluatex_a-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-utils.Tpo $(DEPDIR)/libluatex_a-utils.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/utils.c' object='libluatex_a-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='libluatex_a-utils.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-utils.o `test -f 'luatexdir/utils/utils.c' || echo '$(srcdir)/'`luatexdir/utils/utils.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
-libluatex_a-utils.obj: luatexdir/utils/utils.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-utils.obj -MD -MP -MF $(DEPDIR)/libluatex_a-utils.Tpo -c -o libluatex_a-utils.obj `if test -f 'luatexdir/utils/utils.c'; then $(CYGPATH_W) 'luatexdir/utils/utils.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/utils.c'; fi`
+libluatex_a-utils.obj: utils.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-utils.obj -MD -MP -MF $(DEPDIR)/libluatex_a-utils.Tpo -c -o libluatex_a-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-utils.Tpo $(DEPDIR)/libluatex_a-utils.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/utils.c' object='libluatex_a-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='libluatex_a-utils.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-utils.obj `if test -f 'luatexdir/utils/utils.c'; then $(CYGPATH_W) 'luatexdir/utils/utils.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/utils.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi`
-libluatex_a-writezip.o: luatexdir/utils/writezip.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writezip.o -MD -MP -MF $(DEPDIR)/libluatex_a-writezip.Tpo -c -o libluatex_a-writezip.o `test -f 'luatexdir/utils/writezip.c' || echo '$(srcdir)/'`luatexdir/utils/writezip.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writezip.Tpo $(DEPDIR)/libluatex_a-writezip.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/writezip.c' object='libluatex_a-writezip.o' libtool=no @AMDEPBACKSLASH@
+libluatex_a-avlstuff.o: avlstuff.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avlstuff.o -MD -MP -MF $(DEPDIR)/libluatex_a-avlstuff.Tpo -c -o libluatex_a-avlstuff.o `test -f 'avlstuff.c' || echo '$(srcdir)/'`avlstuff.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avlstuff.Tpo $(DEPDIR)/libluatex_a-avlstuff.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='avlstuff.c' object='libluatex_a-avlstuff.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writezip.o `test -f 'luatexdir/utils/writezip.c' || echo '$(srcdir)/'`luatexdir/utils/writezip.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avlstuff.o `test -f 'avlstuff.c' || echo '$(srcdir)/'`avlstuff.c
-libluatex_a-writezip.obj: luatexdir/utils/writezip.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-writezip.obj -MD -MP -MF $(DEPDIR)/libluatex_a-writezip.Tpo -c -o libluatex_a-writezip.obj `if test -f 'luatexdir/utils/writezip.c'; then $(CYGPATH_W) 'luatexdir/utils/writezip.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/writezip.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-writezip.Tpo $(DEPDIR)/libluatex_a-writezip.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/utils/writezip.c' object='libluatex_a-writezip.obj' libtool=no @AMDEPBACKSLASH@
+libluatex_a-avlstuff.obj: avlstuff.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-avlstuff.obj -MD -MP -MF $(DEPDIR)/libluatex_a-avlstuff.Tpo -c -o libluatex_a-avlstuff.obj `if test -f 'avlstuff.c'; then $(CYGPATH_W) 'avlstuff.c'; else $(CYGPATH_W) '$(srcdir)/avlstuff.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-avlstuff.Tpo $(DEPDIR)/libluatex_a-avlstuff.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='avlstuff.c' object='libluatex_a-avlstuff.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-writezip.obj `if test -f 'luatexdir/utils/writezip.c'; then $(CYGPATH_W) 'luatexdir/utils/writezip.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/utils/writezip.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-avlstuff.obj `if test -f 'avlstuff.c'; then $(CYGPATH_W) 'avlstuff.c'; else $(CYGPATH_W) '$(srcdir)/avlstuff.c'; fi`
+
+libluatex_a-managed-sa.o: managed-sa.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-managed-sa.o -MD -MP -MF $(DEPDIR)/libluatex_a-managed-sa.Tpo -c -o libluatex_a-managed-sa.o `test -f 'managed-sa.c' || echo '$(srcdir)/'`managed-sa.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-managed-sa.Tpo $(DEPDIR)/libluatex_a-managed-sa.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='managed-sa.c' object='libluatex_a-managed-sa.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-managed-sa.o `test -f 'managed-sa.c' || echo '$(srcdir)/'`managed-sa.c
+
+libluatex_a-managed-sa.obj: managed-sa.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-managed-sa.obj -MD -MP -MF $(DEPDIR)/libluatex_a-managed-sa.Tpo -c -o libluatex_a-managed-sa.obj `if test -f 'managed-sa.c'; then $(CYGPATH_W) 'managed-sa.c'; else $(CYGPATH_W) '$(srcdir)/managed-sa.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-managed-sa.Tpo $(DEPDIR)/libluatex_a-managed-sa.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='managed-sa.c' object='libluatex_a-managed-sa.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-managed-sa.obj `if test -f 'managed-sa.c'; then $(CYGPATH_W) 'managed-sa.c'; else $(CYGPATH_W) '$(srcdir)/managed-sa.c'; fi`
libluatex_a-lmplib.o: mplibdir/lmplib.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-lmplib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lmplib.Tpo -c -o libluatex_a-lmplib.o `test -f 'mplibdir/lmplib.c' || echo '$(srcdir)/'`mplibdir/lmplib.c
@@ -5404,20 +6220,6 @@ libluatex_a-lmplib.obj: mplibdir/lmplib.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-lmplib.obj `if test -f 'mplibdir/lmplib.c'; then $(CYGPATH_W) 'mplibdir/lmplib.c'; else $(CYGPATH_W) '$(srcdir)/mplibdir/lmplib.c'; fi`
-libluatex_a-macnames.o: luatexdir/font/macnames.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-macnames.o -MD -MP -MF $(DEPDIR)/libluatex_a-macnames.Tpo -c -o libluatex_a-macnames.o `test -f 'luatexdir/font/macnames.c' || echo '$(srcdir)/'`luatexdir/font/macnames.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-macnames.Tpo $(DEPDIR)/libluatex_a-macnames.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/macnames.c' object='libluatex_a-macnames.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-macnames.o `test -f 'luatexdir/font/macnames.c' || echo '$(srcdir)/'`luatexdir/font/macnames.c
-
-libluatex_a-macnames.obj: luatexdir/font/macnames.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -MT libluatex_a-macnames.obj -MD -MP -MF $(DEPDIR)/libluatex_a-macnames.Tpo -c -o libluatex_a-macnames.obj `if test -f 'luatexdir/font/macnames.c'; then $(CYGPATH_W) 'luatexdir/font/macnames.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/macnames.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-macnames.Tpo $(DEPDIR)/libluatex_a-macnames.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/font/macnames.c' object='libluatex_a-macnames.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CFLAGS) $(CFLAGS) -c -o libluatex_a-macnames.obj `if test -f 'luatexdir/font/macnames.c'; then $(CYGPATH_W) 'luatexdir/font/macnames.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/font/macnames.c'; fi`
-
libmd5_a-md5.o: libmd5/md5.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmd5_a_CPPFLAGS) $(CPPFLAGS) $(libmd5_a_CFLAGS) $(CFLAGS) -MT libmd5_a-md5.o -MD -MP -MF $(DEPDIR)/libmd5_a-md5.Tpo -c -o libmd5_a-md5.o `test -f 'libmd5/md5.c' || echo '$(srcdir)/'`libmd5/md5.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libmd5_a-md5.Tpo $(DEPDIR)/libmd5_a-md5.Po
@@ -6244,61 +7046,19 @@ etex-synctex-e.obj: synctex-e.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(etex_CPPFLAGS) $(CPPFLAGS) $(etex_CFLAGS) $(CFLAGS) -c -o etex-synctex-e.obj `if test -f 'synctex-e.c'; then $(CYGPATH_W) 'synctex-e.c'; else $(CYGPATH_W) '$(srcdir)/synctex-e.c'; fi`
-luatex-luatexini.o: luatexini.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatexini.o -MD -MP -MF $(DEPDIR)/luatex-luatexini.Tpo -c -o luatex-luatexini.o `test -f 'luatexini.c' || echo '$(srcdir)/'`luatexini.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatexini.Tpo $(DEPDIR)/luatex-luatexini.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexini.c' object='luatex-luatexini.o' libtool=no @AMDEPBACKSLASH@
+luatex-luatex.o: luatexdir/luatex.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatex.o -MD -MP -MF $(DEPDIR)/luatex-luatex.Tpo -c -o luatex-luatex.o `test -f 'luatexdir/luatex.c' || echo '$(srcdir)/'`luatexdir/luatex.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatex.Tpo $(DEPDIR)/luatex-luatex.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luatex.c' object='luatex-luatex.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatexini.o `test -f 'luatexini.c' || echo '$(srcdir)/'`luatexini.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatex.o `test -f 'luatexdir/luatex.c' || echo '$(srcdir)/'`luatexdir/luatex.c
-luatex-luatexini.obj: luatexini.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatexini.obj -MD -MP -MF $(DEPDIR)/luatex-luatexini.Tpo -c -o luatex-luatexini.obj `if test -f 'luatexini.c'; then $(CYGPATH_W) 'luatexini.c'; else $(CYGPATH_W) '$(srcdir)/luatexini.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatexini.Tpo $(DEPDIR)/luatex-luatexini.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexini.c' object='luatex-luatexini.obj' libtool=no @AMDEPBACKSLASH@
+luatex-luatex.obj: luatexdir/luatex.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatex.obj -MD -MP -MF $(DEPDIR)/luatex-luatex.Tpo -c -o luatex-luatex.obj `if test -f 'luatexdir/luatex.c'; then $(CYGPATH_W) 'luatexdir/luatex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luatex.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatex.Tpo $(DEPDIR)/luatex-luatex.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexdir/luatex.c' object='luatex-luatex.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatexini.obj `if test -f 'luatexini.c'; then $(CYGPATH_W) 'luatexini.c'; else $(CYGPATH_W) '$(srcdir)/luatexini.c'; fi`
-
-luatex-luatex0.o: luatex0.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatex0.o -MD -MP -MF $(DEPDIR)/luatex-luatex0.Tpo -c -o luatex-luatex0.o `test -f 'luatex0.c' || echo '$(srcdir)/'`luatex0.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatex0.Tpo $(DEPDIR)/luatex-luatex0.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatex0.c' object='luatex-luatex0.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatex0.o `test -f 'luatex0.c' || echo '$(srcdir)/'`luatex0.c
-
-luatex-luatex0.obj: luatex0.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatex0.obj -MD -MP -MF $(DEPDIR)/luatex-luatex0.Tpo -c -o luatex-luatex0.obj `if test -f 'luatex0.c'; then $(CYGPATH_W) 'luatex0.c'; else $(CYGPATH_W) '$(srcdir)/luatex0.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatex0.Tpo $(DEPDIR)/luatex-luatex0.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatex0.c' object='luatex-luatex0.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatex0.obj `if test -f 'luatex0.c'; then $(CYGPATH_W) 'luatex0.c'; else $(CYGPATH_W) '$(srcdir)/luatex0.c'; fi`
-
-luatex-luatex-pool.o: luatex-pool.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatex-pool.o -MD -MP -MF $(DEPDIR)/luatex-luatex-pool.Tpo -c -o luatex-luatex-pool.o `test -f 'luatex-pool.c' || echo '$(srcdir)/'`luatex-pool.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatex-pool.Tpo $(DEPDIR)/luatex-luatex-pool.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatex-pool.c' object='luatex-luatex-pool.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatex-pool.o `test -f 'luatex-pool.c' || echo '$(srcdir)/'`luatex-pool.c
-
-luatex-luatex-pool.obj: luatex-pool.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatex-pool.obj -MD -MP -MF $(DEPDIR)/luatex-luatex-pool.Tpo -c -o luatex-luatex-pool.obj `if test -f 'luatex-pool.c'; then $(CYGPATH_W) 'luatex-pool.c'; else $(CYGPATH_W) '$(srcdir)/luatex-pool.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatex-pool.Tpo $(DEPDIR)/luatex-luatex-pool.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatex-pool.c' object='luatex-luatex-pool.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatex-pool.obj `if test -f 'luatex-pool.c'; then $(CYGPATH_W) 'luatex-pool.c'; else $(CYGPATH_W) '$(srcdir)/luatex-pool.c'; fi`
-
-luatex-luatexextra.o: luatexextra.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatexextra.o -MD -MP -MF $(DEPDIR)/luatex-luatexextra.Tpo -c -o luatex-luatexextra.o `test -f 'luatexextra.c' || echo '$(srcdir)/'`luatexextra.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatexextra.Tpo $(DEPDIR)/luatex-luatexextra.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexextra.c' object='luatex-luatexextra.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatexextra.o `test -f 'luatexextra.c' || echo '$(srcdir)/'`luatexextra.c
-
-luatex-luatexextra.obj: luatexextra.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -MT luatex-luatexextra.obj -MD -MP -MF $(DEPDIR)/luatex-luatexextra.Tpo -c -o luatex-luatexextra.obj `if test -f 'luatexextra.c'; then $(CYGPATH_W) 'luatexextra.c'; else $(CYGPATH_W) '$(srcdir)/luatexextra.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/luatex-luatexextra.Tpo $(DEPDIR)/luatex-luatexextra.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='luatexextra.c' object='luatex-luatexextra.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatexextra.obj `if test -f 'luatexextra.c'; then $(CYGPATH_W) 'luatexextra.c'; else $(CYGPATH_W) '$(srcdir)/luatexextra.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(luatex_CPPFLAGS) $(CPPFLAGS) $(luatex_CFLAGS) $(CFLAGS) -c -o luatex-luatex.obj `if test -f 'luatexdir/luatex.c'; then $(CYGPATH_W) 'luatexdir/luatex.c'; else $(CYGPATH_W) '$(srcdir)/luatexdir/luatex.c'; fi`
md5main-md5main.o: libmd5/md5main.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(md5main_CPPFLAGS) $(CPPFLAGS) $(md5main_CFLAGS) $(CFLAGS) -MT md5main-md5main.o -MD -MP -MF $(DEPDIR)/md5main-md5main.Tpo -c -o md5main-md5main.o `test -f 'libmd5/md5main.c' || echo '$(srcdir)/'`libmd5/md5main.c
@@ -6699,6 +7459,20 @@ libluatex_a-pdftoepdf.obj: luatexdir/image/pdftoepdf.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CXXFLAGS) $(CXXFLAGS) -c -o libluatex_a-pdftoepdf.obj `if test -f 'luatexdir/image/pdftoepdf.cc'; then $(CYGPATH_W) 'luatexdir/image/pdftoepdf.cc'; else $(CYGPATH_W) '$(srcdir)/luatexdir/image/pdftoepdf.cc'; fi`
+libluatex_a-lepdflib.o: luatexdir/lua/lepdflib.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CXXFLAGS) $(CXXFLAGS) -MT libluatex_a-lepdflib.o -MD -MP -MF $(DEPDIR)/libluatex_a-lepdflib.Tpo -c -o libluatex_a-lepdflib.o `test -f 'luatexdir/lua/lepdflib.cc' || echo '$(srcdir)/'`luatexdir/lua/lepdflib.cc
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lepdflib.Tpo $(DEPDIR)/libluatex_a-lepdflib.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='luatexdir/lua/lepdflib.cc' object='libluatex_a-lepdflib.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CXXFLAGS) $(CXXFLAGS) -c -o libluatex_a-lepdflib.o `test -f 'luatexdir/lua/lepdflib.cc' || echo '$(srcdir)/'`luatexdir/lua/lepdflib.cc
+
+libluatex_a-lepdflib.obj: luatexdir/lua/lepdflib.cc
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CXXFLAGS) $(CXXFLAGS) -MT libluatex_a-lepdflib.obj -MD -MP -MF $(DEPDIR)/libluatex_a-lepdflib.Tpo -c -o libluatex_a-lepdflib.obj `if test -f 'luatexdir/lua/lepdflib.cc'; then $(CYGPATH_W) 'luatexdir/lua/lepdflib.cc'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lepdflib.cc'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libluatex_a-lepdflib.Tpo $(DEPDIR)/libluatex_a-lepdflib.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='luatexdir/lua/lepdflib.cc' object='libluatex_a-lepdflib.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluatex_a_CPPFLAGS) $(CPPFLAGS) $(libluatex_a_CXXFLAGS) $(CXXFLAGS) -c -o libluatex_a-lepdflib.obj `if test -f 'luatexdir/lua/lepdflib.cc'; then $(CYGPATH_W) 'luatexdir/lua/lepdflib.cc'; else $(CYGPATH_W) '$(srcdir)/luatexdir/lua/lepdflib.cc'; fi`
+
libpdftex_a-pdftoepdf.o: pdftexdir/pdftoepdf.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpdftex_a_CPPFLAGS) $(CPPFLAGS) $(libpdftex_a_CXXFLAGS) $(CXXFLAGS) -MT libpdftex_a-pdftoepdf.o -MD -MP -MF $(DEPDIR)/libpdftex_a-pdftoepdf.Tpo -c -o libpdftex_a-pdftoepdf.o `test -f 'pdftexdir/pdftoepdf.cc' || echo '$(srcdir)/'`pdftexdir/pdftoepdf.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpdftex_a-pdftoepdf.Tpo $(DEPDIR)/libpdftex_a-pdftoepdf.Po
@@ -7099,7 +7873,7 @@ uninstall-man5:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @fail= failcom='exit 1'; \
+ @failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -7124,7 +7898,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @fail= failcom='exit 1'; \
+ @failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -7396,8 +8170,7 @@ distdir: $(DISTFILES)
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-hook
-test -n "$(am__skip_mode_fix)" \
- || find "$(distdir)" -type d ! -perm -755 \
- -exec chmod u+rwx,go+rx {} \; -o \
+ || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
@@ -7441,17 +8214,17 @@ dist dist-all: distdir
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
- bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
@@ -8041,28 +8814,7 @@ $(libpdftex_a_OBJECTS): pdftexd.h $(XPDF_DEPEND) $(ZLIB_DEPEND) $(LIBPNG_DEPEND)
$(pdftosrc_OBJECTS): $(ZLIB_DEPEND) $(LIBPNG_DEPEND) $(XPDF_DEPEND) $(OBSDCOMPAT_DEPEND)
-# We must create libluatex.a and libmplib.a before building the luatex_OBJECTS.
$(luatex_OBJECTS): libluatex.a libmplib.a
-$(luatex_c_h): luatex-web2c
- @$(web2c) luatex
-luatex-web2c: luatex.p $(web2c_texmf) luatexdir/luatex.defines
- @$(web2c) luatex
-luatexextra.c: luatexd.h luatexdir/luatexextra.h lib/texmfmp.c
- sed s/TEX-OR-MF-OR-MP/luatex/ $(srcdir)/lib/texmfmp.c >$@
-luatex.p luatex.pool: luatex-tangle
- @$(luatex_tangle) luatex luatex
-luatex-tangle: luatangle$(EXEEXT) $(luatex_sources) tangle-sh
- @$(luatex_tangle) luatex luatex
-luatex-pool.c: luatex.pool luatexd.h $(makecpool_stamp)
- $(makecpool) luatex >$@ || rm -f $@
-# Extract luatex version
-luatexdir/luatex.version: luatexdir/luatex.web
- $(MKDIR_P) luatexdir
- grep '^@d luatex_version_string==' $(srcdir)/luatexdir/luatex.web \
- | sed "s/^.*=='//;s/'.*$$//" >luatexdir/luatex.version
-luatexdir/luatexextra.h: luatexdir/luatexextra.in luatexdir/luatex.version
- sed -e s/LUATEX-VERSION/`cat luatexdir/luatex.version`/ \
- $(srcdir)/luatexdir/luatexextra.in >$@
# Double-colon rules since we do something similar in mplibdir (maybe others).
@LUATEX_TRUE@install-exec-hook::
@@ -8073,12 +8825,6 @@ luatexdir/luatexextra.h: luatexdir/luatexextra.in luatexdir/luatex.version
@LUATEX_TRUE@uninstall-hook::
@LUATEX_TRUE@ rm -f $(DESTDIR)$(bindir)/texlua$(EXEEXT)
@LUATEX_TRUE@ rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT)
-luatangle.c luatangle.h: luatangle-web2c
- @$(web2c) luatangle
-luatangle-web2c: luatangle.p $(web2c_depend)
- @$(web2c) luatangle
-luatangle.p: tangle$(EXEEXT) $(luatangle_sources)
- WEBINPUTS=$(srcdir)/luatexdir $(buildenv) $(TANGLE) luatangle luatangle
$(libluasocket_a_OBJECTS): liblua51.a
@@ -8086,8 +8832,267 @@ $(libluamisc_a_OBJECTS): $(libluamisc_a_DEPENDENCIES)
$(libff_a_OBJECTS): $(libff_a_DEPENDENCIES)
-# We must create libff.a and luatexd.h before building the libluatex_a_OBJECTS
-$(libluatex_a_OBJECTS): libff.a luatexd.h luatexdir/luatexextra.h
+dvigen.c: ctangle$(EXEEXT) luatexdir/dvi/dvigen.w
+ $(luatex_dvi_ctangle) dvigen.w
+
+dofont.c: ctangle$(EXEEXT) luatexdir/font/dofont.w
+ $(luatex_font_ctangle) dofont.w
+luafont.c: ctangle$(EXEEXT) luatexdir/font/luafont.w
+ $(luatex_font_ctangle) luafont.w
+mapfile.c: ctangle$(EXEEXT) luatexdir/font/mapfile.w
+ $(luatex_font_ctangle) mapfile.w
+pkin.c: ctangle$(EXEEXT) luatexdir/font/pkin.w
+ $(luatex_font_ctangle) pkin.w
+sfnt.c: ctangle$(EXEEXT) luatexdir/font/sfnt.w
+ $(luatex_font_ctangle) sfnt.w
+subfont.c: ctangle$(EXEEXT) luatexdir/font/subfont.w
+ $(luatex_font_ctangle) subfont.w
+texfont.c: ctangle$(EXEEXT) luatexdir/font/texfont.w
+ $(luatex_font_ctangle) texfont.w
+tfmofm.c: ctangle$(EXEEXT) luatexdir/font/tfmofm.w
+ $(luatex_font_ctangle) tfmofm.w
+tounicode.c: ctangle$(EXEEXT) luatexdir/font/tounicode.w
+ $(luatex_font_ctangle) tounicode.w
+tt_glyf.c: ctangle$(EXEEXT) luatexdir/font/tt_glyf.w
+ $(luatex_font_ctangle) tt_glyf.w
+tt_table.c: ctangle$(EXEEXT) luatexdir/font/tt_table.w
+ $(luatex_font_ctangle) tt_table.w
+vfovf.c: ctangle$(EXEEXT) luatexdir/font/vfovf.w
+ $(luatex_font_ctangle) vfovf.w
+vfpacket.c: ctangle$(EXEEXT) luatexdir/font/vfpacket.w
+ $(luatex_font_ctangle) vfpacket.w
+writecff.c: ctangle$(EXEEXT) luatexdir/font/writecff.w
+ $(luatex_font_ctangle) writecff.w
+writeenc.c: ctangle$(EXEEXT) luatexdir/font/writeenc.w
+ $(luatex_font_ctangle) writeenc.w
+writefont.c: ctangle$(EXEEXT) luatexdir/font/writefont.w
+ $(luatex_font_ctangle) writefont.w
+writet1.c: ctangle$(EXEEXT) luatexdir/font/writet1.w
+ $(luatex_font_ctangle) writet1.w
+writet3.c: ctangle$(EXEEXT) luatexdir/font/writet3.w
+ $(luatex_font_ctangle) writet3.w
+writettf.c: ctangle$(EXEEXT) luatexdir/font/writettf.w
+ $(luatex_font_ctangle) writettf.w
+writetype0.c: ctangle$(EXEEXT) luatexdir/font/writetype0.w
+ $(luatex_font_ctangle) writetype0.w
+writetype2.c: ctangle$(EXEEXT) luatexdir/font/writetype2.w
+ $(luatex_font_ctangle) writetype2.w
+
+epdf.c: ctangle$(EXEEXT) luatexdir/image/epdf.w
+ $(luatex_image_ctangle) epdf.w
+writeimg.c: ctangle$(EXEEXT) luatexdir/image/writeimg.w
+ $(luatex_image_ctangle) writeimg.w
+writejbig2.c: ctangle$(EXEEXT) luatexdir/image/writejbig2.w
+ $(luatex_image_ctangle) writejbig2.w
+writejpg.c: ctangle$(EXEEXT) luatexdir/image/writejpg.w
+ $(luatex_image_ctangle) writejpg.w
+writepng.c: ctangle$(EXEEXT) luatexdir/image/writepng.w
+ $(luatex_image_ctangle) writepng.w
+
+luagen.c: ctangle$(EXEEXT) luatexdir/lua/luagen.w
+ $(luatex_lua_ctangle) luagen.w
+luainit.c: ctangle$(EXEEXT) luatexdir/lua/luainit.w
+ $(luatex_lua_ctangle) luainit.w
+luanode.c: ctangle$(EXEEXT) luatexdir/lua/luanode.w
+ $(luatex_lua_ctangle) luanode.w
+luastuff.c: ctangle$(EXEEXT) luatexdir/lua/luastuff.w
+ $(luatex_lua_ctangle) luastuff.w
+luatoken.c: ctangle$(EXEEXT) luatexdir/lua/luatoken.w
+ $(luatex_lua_ctangle) luatoken.w
+texluac.c: ctangle$(EXEEXT) luatexdir/lua/texluac.w
+ $(luatex_lua_ctangle) texluac.w
+
+ocp.c: ctangle$(EXEEXT) luatexdir/ocp/ocp.w
+ $(luatex_ocp_ctangle) ocp.w
+
+runocp.c: ctangle$(EXEEXT) luatexdir/ocp/runocp.w
+ $(luatex_ocp_ctangle) runocp.w
+
+readocp.c: ctangle$(EXEEXT) luatexdir/ocp/readocp.w
+ $(luatex_ocp_ctangle) readocp.w
+
+ocplist.c: ctangle$(EXEEXT) luatexdir/ocp/ocplist.w
+ $(luatex_ocp_ctangle) ocplist.w
+
+hnjalloc.c: ctangle$(EXEEXT) luatexdir/lang/hnjalloc.w
+ $(luatex_lang_ctangle) hnjalloc.w
+
+hyphen.c: ctangle$(EXEEXT) luatexdir/lang/hyphen.w
+ $(luatex_lang_ctangle) hyphen.w
+
+texlang.c: ctangle$(EXEEXT) luatexdir/lang/texlang.w
+ $(luatex_lang_ctangle) texlang.w
+
+pagetree.c: ctangle$(EXEEXT) luatexdir/pdf/pagetree.w
+ $(luatex_pdf_ctangle) pagetree.w
+
+pdfaction.c: ctangle$(EXEEXT) luatexdir/pdf/pdfaction.w
+ $(luatex_pdf_ctangle) pdfaction.w
+
+pdfannot.c: ctangle$(EXEEXT) luatexdir/pdf/pdfannot.w
+ $(luatex_pdf_ctangle) pdfannot.w
+
+pdfcolorstack.c: ctangle$(EXEEXT) luatexdir/pdf/pdfcolorstack.w
+ $(luatex_pdf_ctangle) pdfcolorstack.w
+
+pdfdest.c: ctangle$(EXEEXT) luatexdir/pdf/pdfdest.w
+ $(luatex_pdf_ctangle) pdfdest.w
+
+pdffont.c: ctangle$(EXEEXT) luatexdir/pdf/pdffont.w
+ $(luatex_pdf_ctangle) pdffont.w
+
+pdfgen.c: ctangle$(EXEEXT) luatexdir/pdf/pdfgen.w
+ $(luatex_pdf_ctangle) pdfgen.w
+
+pdfglyph.c: ctangle$(EXEEXT) luatexdir/pdf/pdfglyph.w
+ $(luatex_pdf_ctangle) pdfglyph.w
+
+pdfimage.c: ctangle$(EXEEXT) luatexdir/pdf/pdfimage.w
+ $(luatex_pdf_ctangle) pdfimage.w
+
+pdflink.c: ctangle$(EXEEXT) luatexdir/pdf/pdflink.w
+ $(luatex_pdf_ctangle) pdflink.w
+
+pdflistout.c: ctangle$(EXEEXT) luatexdir/pdf/pdflistout.w
+ $(luatex_pdf_ctangle) pdflistout.w
+
+pdfliteral.c: ctangle$(EXEEXT) luatexdir/pdf/pdfliteral.w
+ $(luatex_pdf_ctangle) pdfliteral.w
+
+pdfobj.c: ctangle$(EXEEXT) luatexdir/pdf/pdfobj.w
+ $(luatex_pdf_ctangle) pdfobj.w
+
+pdfoutline.c: ctangle$(EXEEXT) luatexdir/pdf/pdfoutline.w
+ $(luatex_pdf_ctangle) pdfoutline.w
+
+pdfpage.c: ctangle$(EXEEXT) luatexdir/pdf/pdfpage.w
+ $(luatex_pdf_ctangle) pdfpage.w
+
+pdfrule.c: ctangle$(EXEEXT) luatexdir/pdf/pdfrule.w
+ $(luatex_pdf_ctangle) pdfrule.w
+
+pdfsaverestore.c: ctangle$(EXEEXT) luatexdir/pdf/pdfsaverestore.w
+ $(luatex_pdf_ctangle) pdfsaverestore.w
+
+pdfsetmatrix.c: ctangle$(EXEEXT) luatexdir/pdf/pdfsetmatrix.w
+ $(luatex_pdf_ctangle) pdfsetmatrix.w
+
+pdfshipout.c: ctangle$(EXEEXT) luatexdir/pdf/pdfshipout.w
+ $(luatex_pdf_ctangle) pdfshipout.w
+
+pdftables.c: ctangle$(EXEEXT) luatexdir/pdf/pdftables.w
+ $(luatex_pdf_ctangle) pdftables.w
+
+pdfthread.c: ctangle$(EXEEXT) luatexdir/pdf/pdfthread.w
+ $(luatex_pdf_ctangle) pdfthread.w
+
+pdfxform.c: ctangle$(EXEEXT) luatexdir/pdf/pdfxform.w
+ $(luatex_pdf_ctangle) pdfxform.w
+
+align.c: ctangle$(EXEEXT) luatexdir/tex/align.w
+ $(luatex_tex_ctangle) align.w
+
+dumpdata.c: ctangle$(EXEEXT) luatexdir/tex/dumpdata.w
+ $(luatex_tex_ctangle) dumpdata.w
+
+expand.c: ctangle$(EXEEXT) luatexdir/tex/expand.w
+ $(luatex_tex_ctangle) expand.w
+
+inputstack.c: ctangle$(EXEEXT) luatexdir/tex/inputstack.w
+ $(luatex_tex_ctangle) inputstack.w
+
+maincontrol.c: ctangle$(EXEEXT) luatexdir/tex/maincontrol.w
+ $(luatex_tex_ctangle) maincontrol.w
+
+mlist.c: ctangle$(EXEEXT) luatexdir/tex/mlist.w
+ $(luatex_tex_ctangle) mlist.w
+
+postlinebreak.c: ctangle$(EXEEXT) luatexdir/tex/postlinebreak.w
+ $(luatex_tex_ctangle) postlinebreak.w
+
+scanning.c: ctangle$(EXEEXT) luatexdir/tex/scanning.w
+ $(luatex_tex_ctangle) scanning.w
+
+texdeffont.c: ctangle$(EXEEXT) luatexdir/tex/texdeffont.w
+ $(luatex_tex_ctangle) texdeffont.w
+
+texnodes.c: ctangle$(EXEEXT) luatexdir/tex/texnodes.w
+ $(luatex_tex_ctangle) texnodes.w
+
+arithmetic.c: ctangle$(EXEEXT) luatexdir/tex/arithmetic.w
+ $(luatex_tex_ctangle) arithmetic.w
+
+conditional.c: ctangle$(EXEEXT) luatexdir/tex/conditional.w
+ $(luatex_tex_ctangle) conditional.w
+
+equivalents.c: ctangle$(EXEEXT) luatexdir/tex/equivalents.w
+ $(luatex_tex_ctangle) equivalents.w
+
+extensions.c: ctangle$(EXEEXT) luatexdir/tex/extensions.w
+ $(luatex_tex_ctangle) extensions.w
+
+commands.c: ctangle$(EXEEXT) luatexdir/tex/commands.w
+ $(luatex_tex_ctangle) commands.w
+
+linebreak.c: ctangle$(EXEEXT) luatexdir/tex/linebreak.w
+ $(luatex_tex_ctangle) linebreak.w
+
+mathcodes.c: ctangle$(EXEEXT) luatexdir/tex/mathcodes.w
+ $(luatex_tex_ctangle) mathcodes.w
+
+nesting.c: ctangle$(EXEEXT) luatexdir/tex/nesting.w
+ $(luatex_tex_ctangle) nesting.w
+
+primitive.c: ctangle$(EXEEXT) luatexdir/tex/primitive.w
+ $(luatex_tex_ctangle) primitive.w
+
+texfileio.c: ctangle$(EXEEXT) luatexdir/tex/texfileio.w
+ $(luatex_tex_ctangle) texfileio.w
+
+textcodes.c: ctangle$(EXEEXT) luatexdir/tex/textcodes.w
+ $(luatex_tex_ctangle) textcodes.w
+
+buildpage.c: ctangle$(EXEEXT) luatexdir/tex/buildpage.w
+ $(luatex_tex_ctangle) buildpage.w
+
+directions.c: ctangle$(EXEEXT) luatexdir/tex/directions.w
+ $(luatex_tex_ctangle) directions.w
+
+errors.c: ctangle$(EXEEXT) luatexdir/tex/errors.w
+ $(luatex_tex_ctangle) errors.w
+
+filename.c: ctangle$(EXEEXT) luatexdir/tex/filename.w
+ $(luatex_tex_ctangle) filename.w
+
+mainbody.c: ctangle$(EXEEXT) luatexdir/tex/mainbody.w
+ $(luatex_tex_ctangle) mainbody.w
+
+memoryword.c: ctangle$(EXEEXT) luatexdir/tex/memoryword.w
+ $(luatex_tex_ctangle) memoryword.w
+
+packaging.c: ctangle$(EXEEXT) luatexdir/tex/packaging.w
+ $(luatex_tex_ctangle) packaging.w
+
+printing.c: ctangle$(EXEEXT) luatexdir/tex/printing.w
+ $(luatex_tex_ctangle) printing.w
+
+stringpool.c: ctangle$(EXEEXT) luatexdir/tex/stringpool.w
+ $(luatex_tex_ctangle) stringpool.w
+
+texmath.c: ctangle$(EXEEXT) luatexdir/tex/texmath.w
+ $(luatex_tex_ctangle) texmath.w
+
+textoken.c: ctangle$(EXEEXT) luatexdir/tex/textoken.w
+ $(luatex_tex_ctangle) textoken.w
+
+utils.c: ctangle$(EXEEXT) luatexdir/utils/utils.w
+ $(luatex_utils_ctangle) utils.w
+managed-sa.c: ctangle$(EXEEXT) luatexdir/utils/managed-sa.w
+ $(luatex_utils_ctangle) managed-sa.w
+avlstuff.c: ctangle$(EXEEXT) luatexdir/utils/avlstuff.w
+ $(luatex_utils_ctangle) avlstuff.w
+
+$(libluatex_a_OBJECTS): libff.a
$(xetex_OBJECTS): $(xetex_prereq)
$(xetex_c_h): xetex-web2c
diff --git a/Build/source/texk/web2c/aclocal.m4 b/Build/source/texk/web2c/aclocal.m4
index 7fe1e663592..ed964362b42 100644
--- a/Build/source/texk/web2c/aclocal.m4
+++ b/Build/source/texk/web2c/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.11 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
@@ -19,115 +19,804 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
-# longlong.m4 serial 13
-dnl Copyright (C) 1999-2007 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
+# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*-
+#
+# Copyright (C) 1999-2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Thomas Tanner, 1999
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 17 LTDL_INIT
+
+# LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE])
+# ------------------------------------------
+# DIRECTORY contains the libltdl sources. It is okay to call this
+# function multiple times, as long as the same DIRECTORY is always given.
+AC_DEFUN([LT_CONFIG_LTDL_DIR],
+[AC_BEFORE([$0], [LTDL_INIT])
+_$0($*)
+])# LT_CONFIG_LTDL_DIR
+
+# We break this out into a separate macro, so that we can call it safely
+# internally without being caught accidentally by the sed scan in libtoolize.
+m4_defun([_LT_CONFIG_LTDL_DIR],
+[dnl remove trailing slashes
+m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$]))
+m4_case(_LTDL_DIR,
+ [], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply `.'
+ m4_if(_ARG_DIR, [.],
+ [],
+ [m4_define([_LTDL_DIR], _ARG_DIR)
+ _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])],
+ [m4_if(_ARG_DIR, _LTDL_DIR,
+ [],
+ [m4_fatal([multiple libltdl directories: `]_LTDL_DIR[', `]_ARG_DIR['])])])
+m4_popdef([_ARG_DIR])
+])# _LT_CONFIG_LTDL_DIR
+
+# Initialise:
+m4_define([_LTDL_DIR], [])
+
+
+# _LT_BUILD_PREFIX
+# ----------------
+# If Autoconf is new enough, expand to `${top_build_prefix}', otherwise
+# to `${top_builddir}/'.
+m4_define([_LT_BUILD_PREFIX],
+[m4_ifdef([AC_AUTOCONF_VERSION],
+ [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]),
+ [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX],
+ [${top_build_prefix}],
+ [${top_builddir}/])],
+ [${top_build_prefix}])],
+ [${top_builddir}/])[]dnl
+])
-dnl From Paul Eggert.
-# Define HAVE_LONG_LONG_INT if 'long long int' works.
-# This fixes a bug in Autoconf 2.61, but can be removed once we
-# assume 2.62 everywhere.
+# LTDL_CONVENIENCE
+# ----------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called here. LIBLTDL will be prefixed with
+# '${top_build_prefix}' if available, otherwise with '${top_builddir}/',
+# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
+# quotes!). If your package is not flat and you're not using automake,
+# define top_build_prefix, top_builddir, and top_srcdir appropriately
+# in your Makefiles.
+AC_DEFUN([LTDL_CONVENIENCE],
+[AC_BEFORE([$0], [LTDL_INIT])dnl
+dnl Although the argument is deprecated and no longer documented,
+dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one
+dnl here make sure it is the same as any other declaration of libltdl's
+dnl location! This also ensures lt_ltdl_dir is set when configure.ac is
+dnl not yet using an explicit LT_CONFIG_LTDL_DIR.
+m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl
+_$0()
+])# LTDL_CONVENIENCE
+
+# AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools,
+# now we have LT_CONFIG_LTDL_DIR:
+AU_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])])
+_LTDL_CONVENIENCE])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [])
+
+
+# _LTDL_CONVENIENCE
+# -----------------
+# Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]).
+m4_defun([_LTDL_CONVENIENCE],
+[case $enable_ltdl_convenience in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+esac
+LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la"
+LTDLDEPS=$LIBLTDL
+LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}"
+
+AC_SUBST([LIBLTDL])
+AC_SUBST([LTDLDEPS])
+AC_SUBST([LTDLINCL])
+
+# For backwards non-gettext consistent compatibility...
+INCLTDL="$LTDLINCL"
+AC_SUBST([INCLTDL])
+])# _LTDL_CONVENIENCE
+
+
+# LTDL_INSTALLABLE
+# ----------------
+# sets LIBLTDL to the link flags for the libltdl installable library
+# and LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called from here. If an installed libltdl
+# is not found, LIBLTDL will be prefixed with '${top_build_prefix}' if
+# available, otherwise with '${top_builddir}/', and LTDLINCL will be
+# prefixed with '${top_srcdir}/' (note the single quotes!). If your
+# package is not flat and you're not using automake, define top_build_prefix,
+# top_builddir, and top_srcdir appropriately in your Makefiles.
+# In the future, this macro may have to be called after LT_INIT.
+AC_DEFUN([LTDL_INSTALLABLE],
+[AC_BEFORE([$0], [LTDL_INIT])dnl
+dnl Although the argument is deprecated and no longer documented,
+dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one
+dnl here make sure it is the same as any other declaration of libltdl's
+dnl location! This also ensures lt_ltdl_dir is set when configure.ac is
+dnl not yet using an explicit LT_CONFIG_LTDL_DIR.
+m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl
+_$0()
+])# LTDL_INSTALLABLE
+
+# AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools,
+# now we have LT_CONFIG_LTDL_DIR:
+AU_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])])
+_LTDL_INSTALLABLE])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [])
+
+
+# _LTDL_INSTALLABLE
+# -----------------
+# Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]).
+m4_defun([_LTDL_INSTALLABLE],
+[AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes])
+ if test x"${lt_lib_ltdl-no}" = xyes; then
+ if test x"$enable_ltdl_install" != xyes; then
+ AC_MSG_WARN([not overwriting installed libltdl, force with `--enable-ltdl-install'])
+ enable_ltdl_install=no
+ fi
+ elif test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ fi
-# Note: If the type 'long long int' exists but is only 32 bits large
-# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
-# defined. In this case you can treat 'long long int' like 'long int'.
+# If configure.ac declared an installable ltdl, and the user didn't override
+# with --disable-ltdl-install, we will install the shipped libltdl.
+case $enable_ltdl_install in
+ no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ LTDLDEPS=
+ LTDLINCL=
+ ;;
+ *) enable_ltdl_install=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la"
+ LTDLDEPS=$LIBLTDL
+ LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}"
+ ;;
+esac
-AC_DEFUN([AC_TYPE_LONG_LONG_INT],
-[
- AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
- [AC_LINK_IFELSE(
- [_AC_TYPE_LONG_LONG_SNIPPET],
- [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
- dnl If cross compiling, assume the bug isn't important, since
- dnl nobody cross compiles for this platform as far as we know.
- AC_RUN_IFELSE(
- [AC_LANG_PROGRAM(
- [[@%:@include <limits.h>
- @%:@ifndef LLONG_MAX
- @%:@ define HALF \
- (1LL << (sizeof (long long int) * CHAR_BIT - 2))
- @%:@ define LLONG_MAX (HALF - 1 + HALF)
- @%:@endif]],
- [[long long int n = 1;
- int i;
- for (i = 0; ; i++)
- {
- long long int m = n << i;
- if (m >> i != n)
- return 1;
- if (LLONG_MAX / 2 < m)
- break;
- }
- return 0;]])],
- [ac_cv_type_long_long_int=yes],
- [ac_cv_type_long_long_int=no],
- [ac_cv_type_long_long_int=yes])],
- [ac_cv_type_long_long_int=no])])
- if test $ac_cv_type_long_long_int = yes; then
- AC_DEFINE([HAVE_LONG_LONG_INT], 1,
- [Define to 1 if the system has the type `long long int'.])
+AC_SUBST([LIBLTDL])
+AC_SUBST([LTDLDEPS])
+AC_SUBST([LTDLINCL])
+
+# For backwards non-gettext consistent compatibility...
+INCLTDL="$LTDLINCL"
+AC_SUBST([INCLTDL])
+])# LTDL_INSTALLABLE
+
+
+# _LTDL_MODE_DISPATCH
+# -------------------
+m4_define([_LTDL_MODE_DISPATCH],
+[dnl If _LTDL_DIR is `.', then we are configuring libltdl itself:
+m4_if(_LTDL_DIR, [],
+ [],
+ dnl if _LTDL_MODE was not set already, the default value is `subproject':
+ [m4_case(m4_default(_LTDL_MODE, [subproject]),
+ [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR)
+ _LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"])],
+ [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"; lt_libobj_prefix="$lt_ltdl_dir/"])],
+ [recursive], [],
+ [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl
+dnl Be careful not to expand twice:
+m4_define([$0], [])
+])# _LTDL_MODE_DISPATCH
+
+
+# _LT_LIBOBJ(MODULE_NAME)
+# -----------------------
+# Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead
+# of into LIBOBJS.
+AC_DEFUN([_LT_LIBOBJ], [
+ m4_pattern_allow([^_LT_LIBOBJS$])
+ _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext"
+])# _LT_LIBOBJS
+
+
+# LTDL_INIT([OPTIONS])
+# --------------------
+# Clients of libltdl can use this macro to allow the installer to
+# choose between a shipped copy of the ltdl sources or a preinstalled
+# version of the library. If the shipped ltdl sources are not in a
+# subdirectory named libltdl, the directory name must be given by
+# LT_CONFIG_LTDL_DIR.
+AC_DEFUN([LTDL_INIT],
+[dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+dnl We need to keep our own list of libobjs separate from our parent project,
+dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while
+dnl we look for our own LIBOBJs.
+m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ]))
+m4_pushdef([AC_LIBSOURCES])
+
+dnl If not otherwise defined, default to the 1.5.x compatible subproject mode:
+m4_if(_LTDL_MODE, [],
+ [m4_define([_LTDL_MODE], m4_default([$2], [subproject]))
+ m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])],
+ [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])
+
+AC_ARG_WITH([included_ltdl],
+ [AS_HELP_STRING([--with-included-ltdl],
+ [use the GNU ltdl sources included here])])
+
+if test "x$with_included_ltdl" != xyes; then
+ # We are not being forced to use the included libltdl sources, so
+ # decide whether there is a useful installed version we can use.
+ AC_CHECK_HEADER([ltdl.h],
+ [AC_CHECK_DECL([lt_dlinterface_register],
+ [AC_CHECK_LIB([ltdl], [lt_dladvise_preload],
+ [with_included_ltdl=no],
+ [with_included_ltdl=yes])],
+ [with_included_ltdl=yes],
+ [AC_INCLUDES_DEFAULT
+ #include <ltdl.h>])],
+ [with_included_ltdl=yes],
+ [AC_INCLUDES_DEFAULT]
+ )
+fi
+
+dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE
+dnl was called yet, then for old times' sake, we assume libltdl is in an
+dnl eponymous directory:
+AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])])
+
+AC_ARG_WITH([ltdl_include],
+ [AS_HELP_STRING([--with-ltdl-include=DIR],
+ [use the ltdl headers installed in DIR])])
+
+if test -n "$with_ltdl_include"; then
+ if test -f "$with_ltdl_include/ltdl.h"; then :
+ else
+ AC_MSG_ERROR([invalid ltdl include directory: `$with_ltdl_include'])
+ fi
+else
+ with_ltdl_include=no
+fi
+
+AC_ARG_WITH([ltdl_lib],
+ [AS_HELP_STRING([--with-ltdl-lib=DIR],
+ [use the libltdl.la installed in DIR])])
+
+if test -n "$with_ltdl_lib"; then
+ if test -f "$with_ltdl_lib/libltdl.la"; then :
+ else
+ AC_MSG_ERROR([invalid ltdl library directory: `$with_ltdl_lib'])
fi
+else
+ with_ltdl_lib=no
+fi
+
+case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in
+ ,yes,no,no,)
+ m4_case(m4_default(_LTDL_TYPE, [convenience]),
+ [convenience], [_LTDL_CONVENIENCE],
+ [installable], [_LTDL_INSTALLABLE],
+ [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)])
+ ;;
+ ,no,no,no,)
+ # If the included ltdl is not to be used, then use the
+ # preinstalled libltdl we found.
+ AC_DEFINE([HAVE_LTDL], [1],
+ [Define this if a modern libltdl is already installed])
+ LIBLTDL=-lltdl
+ LTDLDEPS=
+ LTDLINCL=
+ ;;
+ ,no*,no,*)
+ AC_MSG_ERROR([`--with-ltdl-include' and `--with-ltdl-lib' options must be used together])
+ ;;
+ *) with_included_ltdl=no
+ LIBLTDL="-L$with_ltdl_lib -lltdl"
+ LTDLDEPS=
+ LTDLINCL="-I$with_ltdl_include"
+ ;;
+esac
+INCLTDL="$LTDLINCL"
+
+# Report our decision...
+AC_MSG_CHECKING([where to find libltdl headers])
+AC_MSG_RESULT([$LTDLINCL])
+AC_MSG_CHECKING([where to find libltdl library])
+AC_MSG_RESULT([$LIBLTDL])
+
+_LTDL_SETUP
+
+dnl restore autoconf definition.
+m4_popdef([AC_LIBOBJ])
+m4_popdef([AC_LIBSOURCES])
+
+AC_CONFIG_COMMANDS_PRE([
+ _ltdl_libobjs=
+ _ltdl_ltlibobjs=
+ if test -n "$_LT_LIBOBJS"; then
+ # Remove the extension.
+ _lt_sed_drop_objext='s/\.o$//;s/\.obj$//'
+ for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do
+ _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext"
+ _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo"
+ done
+ fi
+ AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs])
+ AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs])
])
-# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
-# This fixes a bug in Autoconf 2.61, but can be removed once we
-# assume 2.62 everywhere.
+# Only expand once:
+m4_define([LTDL_INIT])
+])# LTDL_INIT
+
+# Old names:
+AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)])
+AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)])
+AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIB_LTDL], [])
+dnl AC_DEFUN([AC_WITH_LTDL], [])
+dnl AC_DEFUN([LT_WITH_LTDL], [])
+
+
+# _LTDL_SETUP
+# -----------
+# Perform all the checks necessary for compilation of the ltdl objects
+# -- including compiler checks and header checks. This is a public
+# interface mainly for the benefit of libltdl's own configure.ac, most
+# other users should call LTDL_INIT instead.
+AC_DEFUN([_LTDL_SETUP],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_SYS_MODULE_EXT])dnl
+AC_REQUIRE([LT_SYS_MODULE_PATH])dnl
+AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl
+AC_REQUIRE([LT_LIB_DLLOAD])dnl
+AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl
+AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl
+AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl
+AC_REQUIRE([gl_FUNC_ARGZ])dnl
+
+m4_require([_LT_CHECK_OBJDIR])dnl
+m4_require([_LT_HEADER_DLFCN])dnl
+m4_require([_LT_CHECK_DLPREOPEN])dnl
+m4_require([_LT_DECL_SED])dnl
+
+dnl Don't require this, or it will be expanded earlier than the code
+dnl that sets the variables it relies on:
+_LT_ENABLE_INSTALL
+
+dnl _LTDL_MODE specific code must be called at least once:
+_LTDL_MODE_DISPATCH
+
+# In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS
+# the user used. This is so that ltdl.h can pick up the parent projects
+# config.h file, The first file in AC_CONFIG_HEADERS must contain the
+# definitions required by ltdl.c.
+# FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility).
+AC_CONFIG_COMMANDS_PRE([dnl
+m4_pattern_allow([^LT_CONFIG_H$])dnl
+m4_ifset([AH_HEADER],
+ [LT_CONFIG_H=AH_HEADER],
+ [m4_ifset([AC_LIST_HEADERS],
+ [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's,^[[ ]]*,,;s,[[ :]].*$,,'`],
+ [])])])
+AC_SUBST([LT_CONFIG_H])
+
+AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h],
+ [], [], [AC_INCLUDES_DEFAULT])
+
+AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])])
+AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])])
+
+AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension])
+
+name=ltdl
+LTDLOPEN=`eval "\\$ECHO \"$libname_spec\""`
+AC_SUBST([LTDLOPEN])
+])# _LTDL_SETUP
+
+
+# _LT_ENABLE_INSTALL
+# ------------------
+m4_define([_LT_ENABLE_INSTALL],
+[AC_ARG_ENABLE([ltdl-install],
+ [AS_HELP_STRING([--enable-ltdl-install], [install libltdl])])
+
+case ,${enable_ltdl_install},${enable_ltdl_convenience} in
+ *yes*) ;;
+ *) enable_ltdl_convenience=yes ;;
+esac
+
+m4_ifdef([AM_CONDITIONAL],
+[AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno)
+ AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)])
+])# _LT_ENABLE_INSTALL
+
+
+# LT_SYS_DLOPEN_DEPLIBS
+# ---------------------
+AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_CACHE_CHECK([whether deplibs are loaded by dlopen],
+ [lt_cv_sys_dlopen_deplibs],
+ [# PORTME does your system automatically load deplibs for dlopen?
+ # or its logical equivalent (e.g. shl_load for HP-UX < 11)
+ # For now, we just catch OSes we know something about -- in the
+ # future, we'll try test this programmatically.
+ lt_cv_sys_dlopen_deplibs=unknown
+ case $host_os in
+ aix3*|aix4.1.*|aix4.2.*)
+ # Unknown whether this is true for these versions of AIX, but
+ # we want this `case' here to explicitly catch those versions.
+ lt_cv_sys_dlopen_deplibs=unknown
+ ;;
+ aix[[4-9]]*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ lt_cv_sys_dlopen_deplibs=no
+ ;;
+ esac
+ ;;
+ darwin*)
+ # Assuming the user has installed a libdl from somewhere, this is true
+ # If you are looking for one http://www.opendarwin.org/projects/dlcompat
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ freebsd* | dragonfly*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ gnu* | linux* | k*bsd*-gnu)
+ # GNU and its variants, using gnu ld.so (Glibc)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ hpux10*|hpux11*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ interix*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ irix[[12345]]*|irix6.[[01]]*)
+ # Catch all versions of IRIX before 6.2, and indicate that we don't
+ # know how it worked for any of those versions.
+ lt_cv_sys_dlopen_deplibs=unknown
+ ;;
+ irix*)
+ # The case above catches anything before 6.2, and it's known that
+ # at 6.2 and later dlopen does load deplibs.
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ netbsd*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ openbsd*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ osf[[1234]]*)
+ # dlopen did load deplibs (at least at 4.x), but until the 5.x series,
+ # it did *not* use an RPATH in a shared library to find objects the
+ # library depends on, so we explicitly say `no'.
+ lt_cv_sys_dlopen_deplibs=no
+ ;;
+ osf5.0|osf5.0a|osf5.1)
+ # dlopen *does* load deplibs and with the right loader patch applied
+ # it even uses RPATH in a shared library to search for shared objects
+ # that the library depends on, but there's no easy way to know if that
+ # patch is installed. Since this is the case, all we can really
+ # say is unknown -- it depends on the patch being installed. If
+ # it is, this changes to `yes'. Without it, it would be `no'.
+ lt_cv_sys_dlopen_deplibs=unknown
+ ;;
+ osf*)
+ # the two cases above should catch all versions of osf <= 5.1. Read
+ # the comments above for what we know about them.
+ # At > 5.1, deplibs are loaded *and* any RPATH in a shared library
+ # is used to find them so we can finally say `yes'.
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ qnx*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ solaris*)
+ lt_cv_sys_dlopen_deplibs=yes
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ libltdl_cv_sys_dlopen_deplibs=yes
+ ;;
+ esac
+ ])
+if test "$lt_cv_sys_dlopen_deplibs" != yes; then
+ AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1],
+ [Define if the OS needs help to load dependent libraries for dlopen().])
+fi
+])# LT_SYS_DLOPEN_DEPLIBS
+
+# Old name:
+AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], [])
-# Note: If the type 'unsigned long long int' exists but is only 32 bits
-# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
-# will not be defined. In this case you can treat 'unsigned long long int'
-# like 'unsigned long int'.
-AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
+# LT_SYS_MODULE_EXT
+# -----------------
+AC_DEFUN([LT_SYS_MODULE_EXT],
+[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl
+AC_CACHE_CHECK([which extension is used for runtime loadable modules],
+ [libltdl_cv_shlibext],
[
- AC_CACHE_CHECK([for unsigned long long int],
- [ac_cv_type_unsigned_long_long_int],
- [AC_LINK_IFELSE(
- [_AC_TYPE_LONG_LONG_SNIPPET],
- [ac_cv_type_unsigned_long_long_int=yes],
- [ac_cv_type_unsigned_long_long_int=no])])
- if test $ac_cv_type_unsigned_long_long_int = yes; then
- AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1,
- [Define to 1 if the system has the type `unsigned long long int'.])
+module=yes
+eval libltdl_cv_shlibext=$shrext_cmds
+ ])
+if test -n "$libltdl_cv_shlibext"; then
+ m4_pattern_allow([LT_MODULE_EXT])dnl
+ AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"],
+ [Define to the extension used for runtime loadable modules, say, ".so".])
+fi
+])# LT_SYS_MODULE_EXT
+
+# Old name:
+AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SHLIBEXT], [])
+
+
+# LT_SYS_MODULE_PATH
+# ------------------
+AC_DEFUN([LT_SYS_MODULE_PATH],
+[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl
+AC_CACHE_CHECK([which variable specifies run-time module search path],
+ [lt_cv_module_path_var], [lt_cv_module_path_var="$shlibpath_var"])
+if test -n "$lt_cv_module_path_var"; then
+ m4_pattern_allow([LT_MODULE_PATH_VAR])dnl
+ AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"],
+ [Define to the name of the environment variable that determines the run-time module search path.])
+fi
+])# LT_SYS_MODULE_PATH
+
+# Old name:
+AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SHLIBPATH], [])
+
+
+# LT_SYS_DLSEARCH_PATH
+# --------------------
+AC_DEFUN([LT_SYS_DLSEARCH_PATH],
+[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl
+AC_CACHE_CHECK([for the default library search path],
+ [lt_cv_sys_dlsearch_path],
+ [lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec"])
+if test -n "$lt_cv_sys_dlsearch_path"; then
+ sys_dlsearch_path=
+ for dir in $lt_cv_sys_dlsearch_path; do
+ if test -z "$sys_dlsearch_path"; then
+ sys_dlsearch_path="$dir"
+ else
+ sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir"
+ fi
+ done
+ m4_pattern_allow([LT_DLSEARCH_PATH])dnl
+ AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"],
+ [Define to the system default library search path.])
+fi
+])# LT_SYS_DLSEARCH_PATH
+
+# Old name:
+AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], [])
+
+
+# _LT_CHECK_DLPREOPEN
+# -------------------
+m4_defun([_LT_CHECK_DLPREOPEN],
+[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen],
+ [libltdl_cv_preloaded_symbols],
+ [if test -n "$lt_cv_sys_global_symbol_pipe"; then
+ libltdl_cv_preloaded_symbols=yes
+ else
+ libltdl_cv_preloaded_symbols=no
fi
-])
+ ])
+if test x"$libltdl_cv_preloaded_symbols" = xyes; then
+ AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1],
+ [Define if libtool can extract symbol lists from object files.])
+fi
+])# _LT_CHECK_DLPREOPEN
-# Expands to a C program that can be used to test for simultaneous support
-# of 'long long' and 'unsigned long long'. We don't want to say that
-# 'long long' is available if 'unsigned long long' is not, or vice versa,
-# because too many programs rely on the symmetry between signed and unsigned
-# integer types (excluding 'bool').
-AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
-[
- AC_LANG_PROGRAM(
- [[/* Test preprocessor. */
- #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
- error in preprocessor;
- #endif
- #if ! (18446744073709551615ULL <= -1ull)
- error in preprocessor;
- #endif
- /* Test literals. */
- long long int ll = 9223372036854775807ll;
- long long int nll = -9223372036854775807LL;
- unsigned long long int ull = 18446744073709551615ULL;
- /* Test constant expressions. */
- typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
- ? 1 : -1)];
- typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
- ? 1 : -1)];
- int i = 63;]],
- [[/* Test availability of runtime routines for shift and division. */
- long long int llmax = 9223372036854775807ll;
- unsigned long long int ullmax = 18446744073709551615ull;
- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
- | (llmax / ll) | (llmax % ll)
- | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
- | (ullmax / ull) | (ullmax % ull));]])
-])
+
+# LT_LIB_DLLOAD
+# -------------
+AC_DEFUN([LT_LIB_DLLOAD],
+[m4_pattern_allow([^LT_DLLOADERS$])
+LT_DLLOADERS=
+AC_SUBST([LT_DLLOADERS])
+
+AC_LANG_PUSH([C])
+
+LIBADD_DLOPEN=
+AC_SEARCH_LIBS([dlopen], [dl],
+ [AC_DEFINE([HAVE_LIBDL], [1],
+ [Define if you have the libdl library or equivalent.])
+ if test "$ac_cv_search_dlopen" != "none required" ; then
+ LIBADD_DLOPEN="-ldl"
+ fi
+ libltdl_cv_lib_dl_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+ ]], [[dlopen(0, 0);]])],
+ [AC_DEFINE([HAVE_LIBDL], [1],
+ [Define if you have the libdl library or equivalent.])
+ libltdl_cv_func_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [AC_DEFINE([HAVE_LIBDL], [1],
+ [Define if you have the libdl library or equivalent.])
+ LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])])
+if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes
+then
+ lt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBADD_DLOPEN"
+ AC_CHECK_FUNCS([dlerror])
+ LIBS="$lt_save_LIBS"
+fi
+AC_SUBST([LIBADD_DLOPEN])
+
+LIBADD_SHL_LOAD=
+AC_CHECK_FUNC([shl_load],
+ [AC_DEFINE([HAVE_SHL_LOAD], [1],
+ [Define if you have the shl_load function.])
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [AC_DEFINE([HAVE_SHL_LOAD], [1],
+ [Define if you have the shl_load function.])
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"
+ LIBADD_SHL_LOAD="-ldld"])])
+AC_SUBST([LIBADD_SHL_LOAD])
+
+case $host_os in
+darwin[[1567]].*)
+# We only want this for pre-Mac OS X 10.4.
+ AC_CHECK_FUNC([_dyld_func_lookup],
+ [AC_DEFINE([HAVE_DYLD], [1],
+ [Define if you have the _dyld_func_lookup function.])
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"])
+ ;;
+beos*)
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la"
+ ;;
+cygwin* | mingw* | os2* | pw32*)
+ AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include <sys/cygwin.h>]])
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la"
+ ;;
+esac
+
+AC_CHECK_LIB([dld], [dld_link],
+ [AC_DEFINE([HAVE_DLD], [1],
+ [Define if you have the GNU dld library.])
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"])
+AC_SUBST([LIBADD_DLD_LINK])
+
+m4_pattern_allow([^LT_DLPREOPEN$])
+LT_DLPREOPEN=
+if test -n "$LT_DLLOADERS"
+then
+ for lt_loader in $LT_DLLOADERS; do
+ LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader "
+ done
+ AC_DEFINE([HAVE_LIBDLLOADER], [1],
+ [Define if libdlloader will be built on this platform])
+fi
+AC_SUBST([LT_DLPREOPEN])
+
+dnl This isn't used anymore, but set it for backwards compatibility
+LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD"
+AC_SUBST([LIBADD_DL])
+
+AC_LANG_POP
+])# LT_LIB_DLLOAD
+
+# Old name:
+AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_DLLIB], [])
+
+
+# LT_SYS_SYMBOL_USCORE
+# --------------------
+# does the compiler prefix global symbols with an underscore?
+AC_DEFUN([LT_SYS_SYMBOL_USCORE],
+[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+AC_CACHE_CHECK([for _ prefix in compiled symbols],
+ [lt_cv_sys_symbol_underscore],
+ [lt_cv_sys_symbol_underscore=no
+ cat > conftest.$ac_ext <<_LT_EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+_LT_EOF
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ lt_cv_sys_symbol_underscore=yes
+ else
+ if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ fi
+ else
+ echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.c >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf conftest*
+ ])
+ sys_symbol_underscore=$lt_cv_sys_symbol_underscore
+ AC_SUBST([sys_symbol_underscore])
+])# LT_SYS_SYMBOL_USCORE
+
+# Old name:
+AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], [])
+
+
+# LT_FUNC_DLSYM_USCORE
+# --------------------
+AC_DEFUN([LT_FUNC_DLSYM_USCORE],
+[AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl
+if test x"$lt_cv_sys_symbol_underscore" = xyes; then
+ if test x"$libltdl_cv_func_dlopen" = xyes ||
+ test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then
+ AC_CACHE_CHECK([whether we have to add an underscore for dlsym],
+ [libltdl_cv_need_uscore],
+ [libltdl_cv_need_uscore=unknown
+ save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBADD_DLOPEN"
+ _LT_TRY_DLOPEN_SELF(
+ [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes],
+ [], [libltdl_cv_need_uscore=cross])
+ LIBS="$save_LIBS"
+ ])
+ fi
+fi
+
+if test x"$libltdl_cv_need_uscore" = xyes; then
+ AC_DEFINE([NEED_USCORE], [1],
+ [Define if dlsym() requires a leading underscore in symbol names.])
+fi
+])# LT_FUNC_DLSYM_USCORE
+
+# Old name:
+AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], [])
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
#
@@ -144,7 +833,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
+m4_if([$1], [1.11], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -160,7 +849,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
+[AM_AUTOMAKE_VERSION([1.11])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
diff --git a/Build/source/texk/web2c/c-auto.in b/Build/source/texk/web2c/c-auto.in
index 18418d6c175..ec96c318b77 100644
--- a/Build/source/texk/web2c/c-auto.in
+++ b/Build/source/texk/web2c/c-auto.in
@@ -64,13 +64,26 @@
/* Define to 1 if you have the Mac OS X Carbon framework. */
#undef HAVE_CARBON
+/* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if
+ you don't. */
+#undef HAVE_DECL_CYGWIN_CONV_PATH
+
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
+/* Define if you have the GNU dld library. */
+#undef HAVE_DLD
+
+/* Define to 1 if you have the `dlerror' function. */
+#undef HAVE_DLERROR
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Define if you have the _dyld_func_lookup function. */
+#undef HAVE_DYLD
+
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
@@ -110,6 +123,12 @@
/* Define to 1 if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
+/* Define if you have the libdl library or equivalent. */
+#undef HAVE_LIBDL
+
+/* Define if libdlloader will be built on this platform */
+#undef HAVE_LIBDLLOADER
+
/* Define if you have libfontconfig. */
#undef HAVE_LIBFONTCONFIG
@@ -165,6 +184,9 @@
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
+/* Define if you have the shl_load function. */
+#undef HAVE_SHL_LOAD
+
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
diff --git a/Build/source/texk/web2c/configure b/Build/source/texk/web2c/configure
index cdeb5ec7be3..810b17bfa4a 100755
--- a/Build/source/texk/web2c/configure
+++ b/Build/source/texk/web2c/configure
@@ -748,6 +748,12 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+LIBADD_DL
+LT_DLPREOPEN
+LIBADD_DLD_LINK
+LIBADD_SHL_LOAD
+LIBADD_DLOPEN
+LT_DLLOADERS
subdirs
LUATANGLE
OTANGLE
@@ -2769,6 +2775,45 @@ rm -f conftest.val
as_fn_set_status $ac_retval
} # ac_fn_c_compute_int
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $2
+ (void) $2;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_decl
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
@@ -5226,13 +5271,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:5229: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:5274: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:5232: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:5277: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:5235: output\"" >&5)
+ (eval echo "\"\$as_me:5280: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -6435,7 +6480,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 6438 "configure"' > conftest.$ac_ext
+ echo '#line 6483 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -8365,11 +8410,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8368: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8413: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8372: \$? = $ac_status" >&5
+ echo "$as_me:8417: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8704,11 +8749,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8707: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8752: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8711: \$? = $ac_status" >&5
+ echo "$as_me:8756: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8809,11 +8854,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8812: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8857: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8816: \$? = $ac_status" >&5
+ echo "$as_me:8861: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -8864,11 +8909,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8867: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8912: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8871: \$? = $ac_status" >&5
+ echo "$as_me:8916: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -11231,7 +11276,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11234 "configure"
+#line 11279 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11327,7 +11372,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11330 "configure"
+#line 11375 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15128,11 +15173,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15131: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15176: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15135: \$? = $ac_status" >&5
+ echo "$as_me:15180: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -15227,11 +15272,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15230: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15275: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15234: \$? = $ac_status" >&5
+ echo "$as_me:15279: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -15279,11 +15324,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15282: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15327: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15286: \$? = $ac_status" >&5
+ echo "$as_me:15331: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -19064,13 +19109,10 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- /* Test preprocessor. */
- #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
- error in preprocessor;
- #endif
- #if ! (18446744073709551615ULL <= -1ull)
- error in preprocessor;
- #endif
+ /* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
/* Test literals. */
long long int ll = 9223372036854775807ll;
long long int nll = -9223372036854775807LL;
@@ -21981,6 +22023,329 @@ ac_config_files="$ac_config_files ctangleboot-sh"
+
+
+LT_DLLOADERS=
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ac_link="./libtool --mode=link --tag=CC $ac_link"
+
+
+LIBADD_DLOPEN=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+$as_echo_n "checking for library containing dlopen... " >&6; }
+if test "${ac_cv_search_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_dlopen=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_dlopen+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_dlopen+set}" = set; then :
+
+else
+ ac_cv_search_dlopen=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
+$as_echo "$ac_cv_search_dlopen" >&6; }
+ac_res=$ac_cv_search_dlopen
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_LIBDL 1" >>confdefs.h
+
+ if test "$ac_cv_search_dlopen" != "none required" ; then
+ LIBADD_DLOPEN="-ldl"
+ fi
+ libltdl_cv_lib_dl_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
+int
+main ()
+{
+dlopen(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+$as_echo "#define HAVE_LIBDL 1" >>confdefs.h
+
+ libltdl_cv_func_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+
+$as_echo "#define HAVE_LIBDL 1" >>confdefs.h
+
+ LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes"
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+
+if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes
+then
+ lt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBADD_DLOPEN"
+ for ac_func in dlerror
+do :
+ ac_fn_c_check_func "$LINENO" "dlerror" "ac_cv_func_dlerror"
+if test "x$ac_cv_func_dlerror" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLERROR 1
+_ACEOF
+
+fi
+done
+
+ LIBS="$lt_save_LIBS"
+fi
+
+
+LIBADD_SHL_LOAD=
+ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+
+$as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h
+
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+
+$as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h
+
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"
+ LIBADD_SHL_LOAD="-ldld"
+fi
+
+fi
+
+
+
+case $host_os in
+darwin[1567].*)
+# We only want this for pre-Mac OS X 10.4.
+ ac_fn_c_check_func "$LINENO" "_dyld_func_lookup" "ac_cv_func__dyld_func_lookup"
+if test "x$ac_cv_func__dyld_func_lookup" = x""yes; then :
+
+$as_echo "#define HAVE_DYLD 1" >>confdefs.h
+
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"
+fi
+
+ ;;
+beos*)
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la"
+ ;;
+cygwin* | mingw* | os2* | pw32*)
+ ac_fn_c_check_decl "$LINENO" "cygwin_conv_path" "ac_cv_have_decl_cygwin_conv_path" "#include <sys/cygwin.h>
+"
+if test "x$ac_cv_have_decl_cygwin_conv_path" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_CYGWIN_CONV_PATH $ac_have_decl
+_ACEOF
+
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+
+$as_echo "#define HAVE_DLD 1" >>confdefs.h
+
+ LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"
+fi
+
+
+
+
+LT_DLPREOPEN=
+if test -n "$LT_DLLOADERS"
+then
+ for lt_loader in $LT_DLLOADERS; do
+ LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader "
+ done
+
+$as_echo "#define HAVE_LIBDLLOADER 1" >>confdefs.h
+
+fi
+
+
+LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ac_link="./libtool --mode=link --tag=CC $ac_link"
+
+
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -22632,9 +22997,9 @@ esac
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-config_commands="$ac_config_commands"
+config_files="`echo $ac_config_files`"
+config_headers="`echo $ac_config_headers`"
+config_commands="`echo $ac_config_commands`"
_ACEOF
diff --git a/Build/source/texk/web2c/configure.ac b/Build/source/texk/web2c/configure.ac
index e1ea7cca29d..a0e9eb96c04 100644
--- a/Build/source/texk/web2c/configure.ac
+++ b/Build/source/texk/web2c/configure.ac
@@ -375,4 +375,8 @@ AC_CONFIG_COMMANDS_POST([AS_IF([test "x$cross_compiling" = xyes],
CC='$BUILDCC' CPPFLAGS='$BUILDCPPFLAGS'\
CFLAGS='$BUILDCFLAGS' LDFLAGS='$BUILDLDFLAGS'"])])
+dnl for luatex dynamic loading
+
+LT_LIB_DLLOAD
+
AC_OUTPUT
diff --git a/Build/source/texk/web2c/doc/Makefile.in b/Build/source/texk/web2c/doc/Makefile.in
index 24e22f59310..20df3d41c47 100644
--- a/Build/source/texk/web2c/doc/Makefile.in
+++ b/Build/source/texk/web2c/doc/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -170,6 +170,10 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBOBJS = @LIBOBJS@
LIBPNG_DEPEND = @LIBPNG_DEPEND@
LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
@@ -179,6 +183,8 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
LUATANGLE = @LUATANGLE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
diff --git a/Build/source/texk/web2c/lib/Makefile.in b/Build/source/texk/web2c/lib/Makefile.in
index 4d9d1d52781..130deaaa1ca 100644
--- a/Build/source/texk/web2c/lib/Makefile.in
+++ b/Build/source/texk/web2c/lib/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -162,6 +162,10 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBOBJS = @LIBOBJS@
LIBPNG_DEPEND = @LIBPNG_DEPEND@
LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
@@ -171,6 +175,8 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
LUATANGLE = @LUATANGLE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
diff --git a/Build/source/texk/web2c/luatexdir/NEWS b/Build/source/texk/web2c/luatexdir/NEWS
index e8225664548..d4031c5adc4 100644
--- a/Build/source/texk/web2c/luatexdir/NEWS
+++ b/Build/source/texk/web2c/luatexdir/NEWS
@@ -1,3 +1,638 @@
+
+This file is in the public domain.
+
+==============================================================
+Luatex beta-0.60.0 was released 20100404
+==============================================================
+
+New features:
+
+* os.name now knows about CYGWIN (from Elie Roux)
+
+* Internal handling of direction specifiers is faster now.
+
+* Each glyph node now has three new virtual read-only fields:
+ width, height, and depth (values in scaled points, of course)
+
+* There are new functions node.protrusion_skipable() and
+ tex.badness() (useful for paragraph breaking in lua)
+
+* Also new: tex.linebreak(). See the manual for details.
+
+* All lua errors now report file and line numbers to aid in
+ debugging.
+
+* Import of metapost 1.211.
+
+* pdf.pdfcatalog will be replaced soon by the new pdf.catalog
+ pdf.pdfinfo will be replaced soon by the new pdf.info
+ pdf.pdfnames will be replaced soon by the new pdf.names
+ pdf.pdftrailer will be replaced soon by the new pdf.trailer
+
+* pdf.pdfmapfile and pdf.pdfmapline are replaced by the new
+ pdf.mapfile() and pdf.mapline() functions. (a function interface
+ fits these parameters better because they never return anything).
+
+* New read-write lua variables: pdf.pageattributes, pdf.pageresources,
+ pdf.pagesresources
+
+* getluatexsvnversion.sh now correctly detects git-svn and still
+ manages to find a valid SVN revision number (from Patrick Gundlach)
+
+* Many of the source files have been converted to CWEB.
+
+Bug fixes:
+
+* GNU libtool is now used to solve the various technical issues with
+ dynamic loading of lua modules.
+
+* Error detection in scan_integer_part was wrong due to missing
+ initialization of OK_so_far (spotted by Javier Mugica)
+
+* Synctex was broken in 0.51-0.52.
+
+* \lastlinefit was broken since ... well, nearly forever.
+
+* Reading of binary files with length zero was broken.
+
+* Trapping of unitialized rules (this was for sloppily created
+ rule nodes from lua)
+
+* pdf.immediateobj('streamfile') was broken on 64-bit platforms.
+
+* tex.linebreak did not take the given left and right skip, but
+ instead used the current TeX-side values (bug #356).
+
+* the found 'MAKE' command in build.sh is now fed into configure to fix
+ problems with that not finding GNU make even when it is actually
+ installed.
+
+* dofile(<nil>) and loadfile(<nil>) in batch mode now give an
+ error and continue instead of pointlessly waiting for user input.
+
+* Reverted commit #3417 (the buildpage experiment) as it causes bad
+ things to happen when items are waiting during page breaks.
+
+* Overrule loaders[4] in --safer mode, make require() behave
+ closer to normal lua 5.1, and add some nicer error messages
+ (based on an email and patches from Manuel Pegourie-Gonnard)
+
+* Added an extra sanity check for GDEF loading in luafontloader,
+ based on a crash caused by Linux' AkaashNormal.ttf.
+
+
+==============================================================
+Luatex beta-0.52.0 was released 20100316
+==============================================================
+
+New features:
+
+* Various small manual improvements.
+
+* A better version of getluatexsvnversion.sh, from Tomek.
+
+* node.copy_list() now allows the second (optional) argument to
+ be nil.
+
+* An import of the current state of the texlive repository
+ (kpathsea and build system).
+
+Bug fixes:
+
+* An attempt fix for bug #345 (math kerning is not perfect): when the
+ current math font is a new math font, check against \catcode <cur_c>
+ == 11 to suppress the italic correction, instead of looking at
+ the value of space(<cur_f>).
+
+* There is a new <tfmtable> key: 'units_per_em' (defaults to 0).
+ This is part of a fix for bug #200 (Problem with CFF fonts having
+ em-size other than 1000): there is a special correction to the
+ embedded cff font itself and the font scale if the font to be output
+ is opentype or type1 in unicode encoding and the 'units_per_em
+ differs' from zero.
+ <tfmtable>.units_per_em has to be passed back to luatex from
+ the lua font loading code for this to work.
+
+* A fix for bug #314 (problem with pk file).
+
+* lua code can no longer change the internal preallocated glue_spec
+ nodes (as that resulted in weird spacing bugs). For this, glue_specs
+ now have a new field: 'writable'. If that field is false, a copy
+ has to be made of the glue_spec instead of doing an assignment
+ to it.
+
+* Setting of \textdir inside the output routine could trash output
+ on following pages due to a lingering internal variable.
+
+* \pdfthread crashed because the arguments were handled in reverse
+ order.
+
+==============================================================
+Luatex beta-0.51.0 was released 20100312
+==============================================================
+
+New features:
+
+* Various small manual improvements.
+* The backend message "cannot open Type 1 font file for reading"
+ now reports which Type1 font it was looking for.
+* Fontforge clears some font names at loading time that will be
+ refilled in at font generation time, but the fontloader should not
+ do that. Patch from Khaled Hosny.
+* New synctex code imported from TeXLive.
+* luamd5/md5.h is renamed to luamd5/luamd5.h to avoid confusion.
+* Embedded mplib is now 1.209.
+* Some experimental tweaking of buildpage_filter, see the manual
+ for details.
+* Luatex now detects kfreebsd (from Alan Braslau)
+* The new lua function tex.sp() converts a string to a number
+ representing scaled points.
+* There is now support for revision numbers in the banner and stats
+ library again.
+* The command line help and manual documentation page is extended.
+* node.hpack() now also accepts "cal_expand_ratio" and "subst_ex_font"
+ modifiers.
+* node.hpack() and node.vpack() now give back the badness of the box
+ as second return value.
+* node.copy_list() now allows a second (stop) argument, this stopper
+ is not copied.
+* new lua functions in lfs: lfs.readlink() and lfs.shortname().
+* new lua function tex.tprint() that can combine multiple catcode
+ regime prints in one function call.
+* new lua sub-table: tex.nest[] (read/write access to the semantic
+ nest state).
+* New lua functions in kpse: kpse.lookup() and kpse.version(). See
+ the manual for more details.
+* New lua function tex.shipout().
+
+Bug fixes:
+
+* There problems in the pdf output for Type3 (pk) fonts.
+* Fix a bug that allowed bad commandline quoting.
+* Fix a bug that sometimes caused crashes when \pdfprotrudechars.
+* The build script now exports CONFIG_SHELL to avoid problems with
+ /bin/dash.
+* The was a bug in the generated /Image /ProcSet.
+* status.font_bytes reported the wrong value.
+* Lots of compiler warnings are removed (thanks Javier Mugica).
+* Patch to fontloader.info() to accept filenames with embedded
+ parentheses.
+* Fix a \write error with docstrip package.
+* Fixed a crash on AdobeMyungjoStd-Medium.otf.
+* Fix coco stack overflows, needed for lpeg.
+* \pdfcompresslevel wasn't initialized for early immediate objects.
+* Fix for slanted fonts when HZ was on (slant angle was multiplied).
+* When concatenating content streams, put a space between them.
+* Allow pfb lines to end with \r as well as \n (for msam10.pfb).
+* Fix the internal string->scaled point conversion in the lua
+ interface.
+* Memory leaks in the fontloader removed, thanks to patches from
+ Elie Roux.
+* Fix a crash caused by the combination of coroutines and font.each().
+
+Removed features:
+
+* Support for Type3 .pgc files (nobody used them).
+
+==============================================================
+Luatex beta-0.50.0 was released 20091224
+==============================================================
+
+New features:
+
+* Fonts now listen also to the 'extend' key in the lua font
+ metrics table, and the processing for this is done via de
+ pdf text matrix instead of via the font matrix, which means
+ it now works for all font types.
+
+* The embedded Metapost library is now at version 1.209.
+
+Dropped features:
+
+* It is no longer possible for fonts from embedded pdf files
+ to be replaced by / merged with the document fonts of the
+ enveloping pdf. This regression may be temporary, depending
+ on how the rewritten font backend will look after beta 0.60.
+
+Bug fixes:
+
+* Use of \middle confused the \mathstyle operation.
+
+* \pdfcolorstack handling was broken.
+
+* node.unset_attribute() had a bug whereby it inverted the
+ requested result in some cases (the node on which the unset
+ was called was sometimes the only node at the current level
+ that *kept* the attribute).
+
+* During font expansion, the internal font copy had one character
+ information object less than the original, resulting in the
+ disappearance of a glyph in some fonts when font expansion
+ was active.
+
+* Placement of operator scripts of OT MATH fonts is adjusted
+ to be conformant with Word's logic where the italic correction
+ is only used to tuck in the subscript and for nothing else.
+
+* luafontloader.open() no longer writes directly to stderr in
+ case of internal font errors.
+
+* Any <pdf_refobj_node>.objnum could not be assigned to.
+
+* The lua 'pdf' table could not be assigned to.
+
+* The lua 'md5' library was returning incorrect results on
+ 64-bit architectures.
+
+* Luatex now compiles on GNU Hurd systems.
+
+* Fix segfault when embedding stream file object (these
+ backend segfaults were a side-effect of the string pool
+ patches).
+
+==============================================================
+Luatex beta-0.47.0 was released 20091218
+==============================================================
+
+New features:
+
+* New read-write lua variables pdf.pdfcatalog, pdf.pdfnames,
+ pdf.pdfinfo, pdf.pdftrailer
+
+* The horizontal mode nodes that are added to lines during line
+ breaking now inherit the attributes from the first and last node
+ inside the created line.
+
+* The new function pdf.registerannot(<number>) registers an
+ annotation object number to be included in the current
+ page's /Annots list.
+
+* The variables <metrics>.Mathconstants.FractionDelimiterSize
+ and <metrics>.Mathconstants.FractionDelimiterDisplayStyleSize
+ are added to the font table. This allows proper setting of the
+ size parameters for TeX's ...withdelims math primitives.
+
+* The internal representation of the string pool is reorganized
+ (the pool of string characters is now allocated dynamically),
+ and as a side-effect the lua variable status.init_pool_ptr
+ is deprecated and will be removed in a later version. Also,
+ status.pool_ptr now simply returns the current number of bytes
+ in use for string characters.
+
+* There are new lua variables pdf.pdfmapline and pdf.pdfmapfile
+ (write-only strings that mimic \pdfmapline and \pdfmapfile).
+
+* \pdfobj data and attribute are now stored as C strings instead
+ of as token lists (this should speed up cases with a lot of data).
+
+* Artificially slanted fonts now work via the pdf text matrix
+ (instead of adjusting the actual font) so that it now also
+ works for non-Type1 fonts. The lua <metrics>.slant font key is
+ now obeyed in all cases.
+
+* The lua function font.id(<string>) returns the internal font id
+ number belonging to a control sequence name.
+
+* Pdf image inclusion is optimized such that objects from an
+ external pdf will now be included only once even if they are
+ referenced from multiple inclusions.
+
+Bug fixes:
+
+* Protrusion for non-TLT documents did not work properly for
+ the hyphenation character.
+
+* \lastbox could not remove the paragraph indent box for non-TLT
+ documents.
+
+* Pdf images (\pdfximage) are no longer kept open during the
+ whole run, but closed and reopened. An error is raised if
+ the file has changed between \pdfximage and \pdfrefximage.
+ This prevents the 'too many open files' error when lots of
+ images are included.
+
+* On Win32 Pdf image files are locked during the time that it is
+ open, to prevent unnoticed file changes by external sources.
+
+* Compilation now again works on FreeBSD.
+
+* Format sharing between 32-bit and 64-bit architectures was
+ broken.
+
+* Unsetting attributes from lua could sometimes result in
+ the unset state persisting beyond the current group level.
+
+* If something went wrong in the scanning of pdf action items,
+ the error message reported the current primitive name
+ incorrectly.
+
+* Luatex would crash on non-existant pdfs that were referenced
+ from map file entries.
+
+==============================================================
+Luatex beta-0.46.0 was released 20091126
+==============================================================
+
+New features:
+
+* The build.sh script now has better support for new MacOSX-es
+ (patch from Mojca).
+
+* Luatex now has experimental support for dynamic loading of
+ external compiled lua libraries. Building luatex and loading
+ external .so/.dll files is reported to work on Windows,
+ linux and osx, other platforms are still unknown.
+
+* pdf.obj{type="stream"} no longer converts its argument to and
+ from a tokenlist. This allows the use of binary data in the
+ "string" argument. Such data does still have to hidden from
+ the normal file parser by putting the code in a dofile()
+ or by using string.char(), though.
+
+Bug fixes:
+
+* Luatex 0.45.0 was not able to find truetype nor opentype fonts
+ if there were no callbacks defined (patch from Pawel).
+
+* 0.45.0 printed the user input instead of the full pathname
+ for \input-ed tex files.
+
+* The TFM reader now rejects fonts with tfm names that are
+ longer than 255 characters because such font names cannot
+ be stored in a DVI file.
+
+* The combination of \immediate\pdfxform followed by a later
+ \pdfrefxform could cause broken pdf output files because
+ the box used for the form could have been freed and even
+ reused already at that moment in time, sometimes resulting
+ in an invalid transformation matrix.
+
+* The placement of super- and subscripts for displaystyle
+ \int's in CambriaMath is now better than before. It still
+ needs a tweak to the metrics though: in the current version,
+ the italic correction has to be substracted from the width
+ of the integral sign to get correct placement (context mkiv
+ does this). to be continued ...
+
+==============================================================
+Luatex beta-0.45.0 was released 20091118
+==============================================================
+
+New features:
+
+* Loading big OTF fonts via lua is now much faster than before,
+ at the expense of a bit of precision loss in the calculated
+ bounding boxes.
+
+* Two new token lists are provided: \pdfxformresources and
+ \pdfxformattr, as an alternative to \pdfxform keywords.
+
+* \input and \openin now accept braced filenames.
+
+* The \endlinechar can now be set to any value between 0 and 127.
+
+* Luatex can now optionally use kpathsea to find lua require()
+ files.
+
+* The new primitives \aligntab and \alignmark are aliases for
+ the use of & and # in alignments.
+
+* \pdfrefximage [width <dimen>] [height <dimen>] [depth <dimen>] <imageref>
+ overrules settings from \pdfximage for this \pdfrefximage call only
+
+* The print precision for small numbers in lua code (tostring)
+ has been improved.
+
+* Akira Kakuto suppled a patch that restricts writing to files
+ with names such as latex.bat etc. (on windows only)
+
+* (un-feature): from now on luatex now only handles 4 direction
+ specifiers: TLT (latin), TRT (arabic), RTT (cjk), and LTL
+ (mongolian). The other directions now generate an error.
+
+* (un-feature): xpdf's automatic lower- and uppercasing retry attempts
+ for nonfound image pdf files has been removed.
+
+* The callbacks hpack_filter, vpack_filter and pre_output_filter
+ pass on an extra string argument for the direction, when known
+ (nil == use default).
+
+* The lua functions node.hpack(), node.vpack() and node.dimensions()
+ now accept an optional direction argument (not given == use default).
+
+* \pdfrefxform [width <dimen>] [height <dimen>] [depth <dimen>] <formref>
+ scales a form object; similar principle as with \pdfximage: depth alone
+ doesn't scale, it shifts vertically.
+
+* A change to the relative ordering inside font name discovery for use
+ by the backend: now it tries <f>.psname first, as that is much less
+ likely to contain spaces.
+
+* For ttc fonts, now the used subfont name and its index id are printed
+ to the terminal, and if the backend cannot find a ttc subfont, the
+ run is aborted.
+
+Bug fixes:
+
+* Prevent crashes for lua-loaded fonts without a (tfm) name.
+
+* Remove spurious newlines in the output pdf that could be the
+ result of using \pdfximage for an included pdf figure too early.
+
+* Full font embedding for wide otf and ttf fonts now really
+ works (older versions only pretended that it did work).
+
+* node.dimensions() sometimes continued past the 'stop' node.
+
+* Images inside virtual fonts were broken.
+
+* The processing of \language=-1 was wrong, resulting in
+ hyphenation attempts even though there was no proper language
+ set up.
+
+* Fix for finding files in --output-directory.
+
+* Fix for handling of --file-line-error.
+
+* tex.box[] assingments are now checked to make sure the assigned
+ node has the right id (hlist or vlist).
+
+* show_node_list (as in \showbox) produced spurious local_par
+ whatsit prints in the output after direction nodes.
+
+* The handling of pdf literals has been sped up.
+
+==============================================================
+Luatex beta-0.44.0 was released 20091027
+==============================================================
+
+New features:
+
+* libpng is now 1.2.40.
+
+* hlist nodes now have a subtype to distinguish hlists generated
+ by the paragraph breaking, explicit \hbox commands, and other
+ (as-yet-undefined) sources.
+
+* \pdfobj now has an extra optional keyword: 'uncompressed',
+ which forces the object to be written to the PDF in plain
+ text (see the manual for the exact details).
+
+* The lua file from the luamd5 library (which provides the
+ md5.hexsuma() function) is now embedded in the executable.
+
+Bug fixes:
+
+* \latelua now works in DVI mode again.
+
+* status.output_file_name could crash when used too soon.
+
+* In 0.43, rules were not output at all in DVI mode.
+
+* \leavevmode\penalty-10000\penalty-10000 crashed luatex.
+
+* the API of margin kern nodes to lua was using the wrong
+ fields in the nodes.
+
+* A few fixes to the manual.
+
+* PDF Xref stream dicts were slightly non-conformant.
+
+* There was too much space between two consecutive math displays
+ (this bug was inherited from Aleph)
+
+* Synctex was broken (thanks, Akira)
+
+* Font mark classes were handled incorrectly by the fontloader
+ code.
+
+* There was a crash possible with certain types of named PDF
+ destinations.
+
+* Math delimiters and large operators in new MATH fonts no
+ longer apply the italic correction (this fixes placements
+ of super- and subscripts on such items for those fonts).
+
+* The converter from lua strings to token lists (for the node
+ interface) sometimes generated invalid tokens.
+
+* CFF (OpenType) fonts now listen to 'embedding="full"'. TTF
+ is still todo.
+
+* Font tables with 'embedding="no"' would cause luatex to crash.
+
+* \pdfobj file {} failed to find the file if there was no lua
+ callback in place.
+
+* An optimization in MS Mincho caused luatex to crash.
+
+==============================================================
+Luatex beta-0.43.0 was released 20090819
+==============================================================
+
+New features:
+
+* There is a new allowed key in the table trhat is returned
+ by lua-loaded fonts: <f>.psname. This value should be set
+ to the original PostScript font name of the font. Fonts inside
+ dfont and ttc collections are fetched using this field
+ (if it is missing, <f>.fullname will be used instead).
+
+* It is now possible to use Apple dfont font files
+ (those that contain at least one outline font).
+
+* \latelua is now allowed inside leaders.
+
+* There is a new callback: process_output_buffer, from Manuel
+ Pégourié-Gonnard. This callback is called just before
+ \write acts, so it can be used to alter the file encoding
+ of text output files.
+
+* There is a new node.dimensions() function, which calculates
+ the natural size of (part of) a list of nodes.
+
+* The new primitive \gleaders provides 'globally aligned'
+ leaders.
+
+* The DVI and PDF backends now share much code internally.
+
+* The embedded MPlib is now 1.207.
+
+* libpng is now 1.2.39.
+
+Bugfixes:
+
+* We fixed lots of anonymous bugs introduced in 0.42.0 (as expected)
+
+* fontloader.info() errors are no longer fatal, the function now
+ just returns a nil,"error string" pair.
+
+* Automatically inserted kerns for \accents are now once again
+ valid word ends, as in \TEX.
+
+* Fixed the placement of math displays in mixed direction
+ settings.
+
+* The \pdfcompresslevel is now dynamic again.
+
+==============================================================
+Luatex beta-0.42.0 was released 20090717
+==============================================================
+
+* There is a new node.tail() function
+
+* lua-loaded fonts now support a 'nomath' key to speed up
+ loading the lua table.
+
+* A bugfix in the ttf reader for the inclusion backend, and
+ (also in the backend) support for treating ttc files by
+ pretending they are single ttf fonts (both patches from pdftex)
+
+* Add Khaled Hosny's man page to the repository
+
+* The \pdfcompresslevel is now effectively fixed as soon as
+ output to the pdf file has occurred.
+
+* Patched status.filename so that it (nearly) always returns a
+ file name.
+
+* fix '\the\delcode' and disable '\the\odelcode', '\the\Udelcode',
+ and '\the\Udelcodenum'
+
+* Handle jfifs where either xres or yres is 0 and the other
+ res is != 0 (from pdftex)
+
+* The single-argument version of lang.hyphenate() was broken.
+
+* Get rid of the \directlua/\latelua number warning.
+
+* The Lua coroutine patch (coco) is now disabled on linux
+ powerpc architectures (because it caused crashes)
+
+* Removed obsolete pdftex primitives:
+ \pdfoptionalwaysusepdfpagebox
+ \pdfoptionpdfinclusionerrorlevel
+ \pdfforcepagebox
+ \pdfmovechars
+
+* The loading speed of large fonts (especially ttf) via the
+ fontloader library, and the inclusion speed for subsetting
+ in the backend have both been improved.
+
+* The 'pdf' lua library has been enhanced with various new
+ functions, see the manual for details.
+
+* BLT and BRT glyph position fixed.
+
+* Various fixes for synctex offsets.
+
+* Support for exotic font string encodings has been removed
+ from the fontloader library.
+
+* The embedded MPlib is now 1.205.
+
+* libpng is now 1.2.38.
+
==============================================================
Luatex beta-0.40.6 was released 20090625
==============================================================
@@ -8,7 +643,6 @@ Luatex beta-0.40.6 was released 20090625
* Sometimes pdf.print() could be used before the proper structures
were initialized.
-
* There was a bug in the type codes for the lua package filter
callback: wrong extra info was passed to lua for the alignment
@@ -849,7 +1483,7 @@ Other news:
we probably introduced new problems as well).
* Most (all?) files now have a corrected Copyright header,
- and link in $Id$ and $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/NEWS $ into the object file.
+ and link in $Id$ and $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/NEWS $ into the object file.
* Some unnecessary files were removed from the distribution.
diff --git a/Build/source/texk/web2c/luatexdir/README b/Build/source/texk/web2c/luatexdir/README
deleted file mode 100644
index f1e142f1b25..00000000000
--- a/Build/source/texk/web2c/luatexdir/README
+++ /dev/null
@@ -1,87 +0,0 @@
-pdfTeX
-======
-
-README for version 3.14159-1.40.0-beta-20060811
-===============================================
-
-This directory contains the version 1.40.0-alpha-20060811 of pdfTeX, an
-extended version of eTeX that can create PDF directly from TeX source files
-and enhance the result of TeX typesetting with the help of PDF. When PDF
-output is not selected, pdfTeX produces normal DVI output, otherwise it
-produces PDF output that looks identical to the DVI output. An important
-aspect of this project is to investigate alternative justification
-algorithms, optionally making use of multiple master fonts.
-
-pdfTeX is based on the original eTeX sources and Web2c, and has been
-successfully compiled on Unix, Win32 and DOS systems. It is still under
-development and features may change; it produces reasonable PDF code.
-
-See the file NEWS for changes to the program.
-
-Documentation about pdfTeX can be found at http://www.pdftex.org
-
-There is also a mailing list on pdfTeX; go to
-http://tug.org/mailman/listinfo/pdftex for more information about it. Its
-searchable archive can be found at http://tug.org/pipermail/pdftex/
-Please read http://www.catb.org/~esr/faqs/smart-questions.html before
-asking any questions on the pdfTeX mailing list.
-
-A mailing list for the developement of pdfTeX can be found at
-http://www.ntg.nl/mailman/listinfo/ntg-pdftex
-
-
-LEGAL ISSUES
-============
-
-pdfTeX is copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org>
-
-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
-
-pdfTeX uses code from TeX; for these parts the original copyright by Don
-Knuth applies. See the source files for details.
-
-pdfeTeX uses code from eTeX; for these parts the original copyright by
-Peter Breitenlohner applies. See the source files for details.
-
-
-WHAT TO DO IF YOU BELIEVE YOU HAVE FOUND A BUG IN pdfTeX
-========================================================
-
-Please read http://www.chiark.greenend.org.uk/~sgtatham/bugs.html and
-follow the guidelines there. Then go to the sarovar site of pdfTeX
-(http://sarovar.org/projects/pdftex/) and submit your bug report there.
-Here you can also report feature requests or patches.
-
-
-CONTRIBUTORS
-============
-
-Peter Breitenlohner, Ricardo Sanchez Carmenes, Otfried Cheong, Thomas
-Esser, Hans Hagen, Hartmut Henkel, Taco Hoekwater, Pawel Jackowski, Tom
-Kacvinsky, Akira Kakuto, Reinhard Kotucha, Derek B. Noonburg, Heiko
-Oberdiek, Jiri Osoba, Fabrice Popineau, Sebastian Rahtz, Tomas Rokicki,
-Martin Schröder, Petr Sojka, Ralf Utermann, Olaf Weber, Jiri Zlatuska.
-
-pdfTeX is built on top of TeX, written by Donald Knuth cum suis (Liang and
-so), and eTeX, written by Peter Breitenlohner cum suis; part of the
-paragraph optimization is inspired by the work of Hermann Zapf.
-
-
-------------------------------------------------------------------------------
-
-Please send bug reports, offers of help, etc. to martin@pdftex.org
-
-$Id$
-// vim: tw=75
diff --git a/Build/source/texk/web2c/luatexdir/am/libluatex.am b/Build/source/texk/web2c/luatexdir/am/libluatex.am
index 626cdc4ab64..9a0397ddd3f 100644
--- a/Build/source/texk/web2c/luatexdir/am/libluatex.am
+++ b/Build/source/texk/web2c/luatexdir/am/libluatex.am
@@ -16,59 +16,528 @@ libluatex_a_CPPFLAGS += -DpdfTeX
libluatex_a_CFLAGS = $(WARNING_CFLAGS)
libluatex_a_CXXFLAGS = # $(WARNING_CXXFLAGS)
+luatex_dvi_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/dvi $(ctangle)
+
+dvigen.c: ctangle$(EXEEXT) luatexdir/dvi/dvigen.w
+ $(luatex_dvi_ctangle) dvigen.w
+
+libluatex_web = luatexdir/dvi/dvigen.w
+
+nodist_libluatex_a_SOURCES = dvigen.c
+
+luatex_font_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/font $(ctangle)
+
+dofont.c: ctangle$(EXEEXT) luatexdir/font/dofont.w
+ $(luatex_font_ctangle) dofont.w
+luafont.c: ctangle$(EXEEXT) luatexdir/font/luafont.w
+ $(luatex_font_ctangle) luafont.w
+mapfile.c: ctangle$(EXEEXT) luatexdir/font/mapfile.w
+ $(luatex_font_ctangle) mapfile.w
+pkin.c: ctangle$(EXEEXT) luatexdir/font/pkin.w
+ $(luatex_font_ctangle) pkin.w
+sfnt.c: ctangle$(EXEEXT) luatexdir/font/sfnt.w
+ $(luatex_font_ctangle) sfnt.w
+subfont.c: ctangle$(EXEEXT) luatexdir/font/subfont.w
+ $(luatex_font_ctangle) subfont.w
+texfont.c: ctangle$(EXEEXT) luatexdir/font/texfont.w
+ $(luatex_font_ctangle) texfont.w
+tfmofm.c: ctangle$(EXEEXT) luatexdir/font/tfmofm.w
+ $(luatex_font_ctangle) tfmofm.w
+tounicode.c: ctangle$(EXEEXT) luatexdir/font/tounicode.w
+ $(luatex_font_ctangle) tounicode.w
+tt_glyf.c: ctangle$(EXEEXT) luatexdir/font/tt_glyf.w
+ $(luatex_font_ctangle) tt_glyf.w
+tt_table.c: ctangle$(EXEEXT) luatexdir/font/tt_table.w
+ $(luatex_font_ctangle) tt_table.w
+vfovf.c: ctangle$(EXEEXT) luatexdir/font/vfovf.w
+ $(luatex_font_ctangle) vfovf.w
+vfpacket.c: ctangle$(EXEEXT) luatexdir/font/vfpacket.w
+ $(luatex_font_ctangle) vfpacket.w
+writecff.c: ctangle$(EXEEXT) luatexdir/font/writecff.w
+ $(luatex_font_ctangle) writecff.w
+writeenc.c: ctangle$(EXEEXT) luatexdir/font/writeenc.w
+ $(luatex_font_ctangle) writeenc.w
+writefont.c: ctangle$(EXEEXT) luatexdir/font/writefont.w
+ $(luatex_font_ctangle) writefont.w
+writet1.c: ctangle$(EXEEXT) luatexdir/font/writet1.w
+ $(luatex_font_ctangle) writet1.w
+writet3.c: ctangle$(EXEEXT) luatexdir/font/writet3.w
+ $(luatex_font_ctangle) writet3.w
+writettf.c: ctangle$(EXEEXT) luatexdir/font/writettf.w
+ $(luatex_font_ctangle) writettf.w
+writetype0.c: ctangle$(EXEEXT) luatexdir/font/writetype0.w
+ $(luatex_font_ctangle) writetype0.w
+writetype2.c: ctangle$(EXEEXT) luatexdir/font/writetype2.w
+ $(luatex_font_ctangle) writetype2.w
+
+
+libluatex_web += luatexdir/font/dofont.w luatexdir/font/luafont.w luatexdir/font/mapfile.w
+libluatex_web += luatexdir/font/pkin.w luatexdir/font/sfnt.w luatexdir/font/subfont.w
+libluatex_web += luatexdir/font/texfont.w luatexdir/font/tfmofm.w
+libluatex_web += luatexdir/font/tounicode.w luatexdir/font/tt_glyf.w
+libluatex_web += luatexdir/font/tt_table.w luatexdir/font/vfovf.w
+libluatex_web += luatexdir/font/vfpacket.w luatexdir/font/writecff.w
+libluatex_web += luatexdir/font/writeenc.w luatexdir/font/writefont.w
+libluatex_web += luatexdir/font/writet1.w luatexdir/font/writet3.w
+libluatex_web += luatexdir/font/writettf.w luatexdir/font/writetype0.w
+libluatex_web += luatexdir/font/writetype2.w
+
+nodist_libluatex_a_SOURCES += dofont.c luafont.c mapfile.c pkin.c sfnt.c subfont.c
+nodist_libluatex_a_SOURCES += texfont.c tfmofm.c tounicode.c tt_glyf.c tt_table.c vfovf.c vfpacket.c
+nodist_libluatex_a_SOURCES += writecff.c writeenc.c writefont.c writet1.c writet3.c writettf.c
+nodist_libluatex_a_SOURCES += writetype0.c writetype2.c
+
+luatex_image_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/image $(ctangle)
+
+epdf.c: ctangle$(EXEEXT) luatexdir/image/epdf.w
+ $(luatex_image_ctangle) epdf.w
+writeimg.c: ctangle$(EXEEXT) luatexdir/image/writeimg.w
+ $(luatex_image_ctangle) writeimg.w
+writejbig2.c: ctangle$(EXEEXT) luatexdir/image/writejbig2.w
+ $(luatex_image_ctangle) writejbig2.w
+writejpg.c: ctangle$(EXEEXT) luatexdir/image/writejpg.w
+ $(luatex_image_ctangle) writejpg.w
+writepng.c: ctangle$(EXEEXT) luatexdir/image/writepng.w
+ $(luatex_image_ctangle) writepng.w
+
+libluatex_web += luatexdir/image/epdf.w luatexdir/image/writeimg.w
+libluatex_web += luatexdir/image/writejbig2.w luatexdir/image/writejpg.w luatexdir/image/writepng.w
+
+nodist_libluatex_a_SOURCES += epdf.c writeimg.c writejbig2.c writejpg.c writepng.c
+
+
+luatex_lua_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/lua $(ctangle)
+
+luagen.c: ctangle$(EXEEXT) luatexdir/lua/luagen.w
+ $(luatex_lua_ctangle) luagen.w
+luainit.c: ctangle$(EXEEXT) luatexdir/lua/luainit.w
+ $(luatex_lua_ctangle) luainit.w
+luanode.c: ctangle$(EXEEXT) luatexdir/lua/luanode.w
+ $(luatex_lua_ctangle) luanode.w
+luastuff.c: ctangle$(EXEEXT) luatexdir/lua/luastuff.w
+ $(luatex_lua_ctangle) luastuff.w
+luatoken.c: ctangle$(EXEEXT) luatexdir/lua/luatoken.w
+ $(luatex_lua_ctangle) luatoken.w
+texluac.c: ctangle$(EXEEXT) luatexdir/lua/texluac.w
+ $(luatex_lua_ctangle) texluac.w
+
+libluatex_web += luatexdir/lua/luagen.w luatexdir/lua/luainit.w luatexdir/lua/luanode.w
+libluatex_web += luatexdir/lua/luastuff.w luatexdir/lua/luatoken.w luatexdir/lua/texluac.w
+
+nodist_libluatex_a_SOURCES += luagen.c luainit.c luanode.c luastuff.c luatoken.c texluac.c
+
+
+luatex_ocp_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/ocp $(ctangle)
+
+ocp.c: ctangle$(EXEEXT) luatexdir/ocp/ocp.w
+ $(luatex_ocp_ctangle) ocp.w
+
+runocp.c: ctangle$(EXEEXT) luatexdir/ocp/runocp.w
+ $(luatex_ocp_ctangle) runocp.w
+
+readocp.c: ctangle$(EXEEXT) luatexdir/ocp/readocp.w
+ $(luatex_ocp_ctangle) readocp.w
+
+ocplist.c: ctangle$(EXEEXT) luatexdir/ocp/ocplist.w
+ $(luatex_ocp_ctangle) ocplist.w
+
+libluatex_web += luatexdir/ocp/ocp.w luatexdir/ocp/ocplist.w luatexdir/ocp/readocp.w luatexdir/ocp/runocp.w
+
+nodist_libluatex_a_SOURCES += ocp.c ocplist.c readocp.c runocp.c
+
+luatex_lang_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/lang $(ctangle)
+
+hnjalloc.c: ctangle$(EXEEXT) luatexdir/lang/hnjalloc.w
+ $(luatex_lang_ctangle) hnjalloc.w
+
+hyphen.c: ctangle$(EXEEXT) luatexdir/lang/hyphen.w
+ $(luatex_lang_ctangle) hyphen.w
+
+texlang.c: ctangle$(EXEEXT) luatexdir/lang/texlang.w
+ $(luatex_lang_ctangle) texlang.w
+
+libluatex_web += luatexdir/lang/texlang.w luatexdir/lang/hyphen.w luatexdir/lang/hnjalloc.w
+
+nodist_libluatex_a_SOURCES += texlang.c hyphen.c hnjalloc.c
+
+luatex_pdf_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/pdf $(ctangle)
+
+pagetree.c: ctangle$(EXEEXT) luatexdir/pdf/pagetree.w
+ $(luatex_pdf_ctangle) pagetree.w
+
+pdfaction.c: ctangle$(EXEEXT) luatexdir/pdf/pdfaction.w
+ $(luatex_pdf_ctangle) pdfaction.w
+
+pdfannot.c: ctangle$(EXEEXT) luatexdir/pdf/pdfannot.w
+ $(luatex_pdf_ctangle) pdfannot.w
+
+pdfcolorstack.c: ctangle$(EXEEXT) luatexdir/pdf/pdfcolorstack.w
+ $(luatex_pdf_ctangle) pdfcolorstack.w
+
+pdfdest.c: ctangle$(EXEEXT) luatexdir/pdf/pdfdest.w
+ $(luatex_pdf_ctangle) pdfdest.w
+
+pdffont.c: ctangle$(EXEEXT) luatexdir/pdf/pdffont.w
+ $(luatex_pdf_ctangle) pdffont.w
+
+pdfgen.c: ctangle$(EXEEXT) luatexdir/pdf/pdfgen.w
+ $(luatex_pdf_ctangle) pdfgen.w
+
+pdfglyph.c: ctangle$(EXEEXT) luatexdir/pdf/pdfglyph.w
+ $(luatex_pdf_ctangle) pdfglyph.w
+
+pdfimage.c: ctangle$(EXEEXT) luatexdir/pdf/pdfimage.w
+ $(luatex_pdf_ctangle) pdfimage.w
+
+pdflink.c: ctangle$(EXEEXT) luatexdir/pdf/pdflink.w
+ $(luatex_pdf_ctangle) pdflink.w
+
+pdflistout.c: ctangle$(EXEEXT) luatexdir/pdf/pdflistout.w
+ $(luatex_pdf_ctangle) pdflistout.w
+
+pdfliteral.c: ctangle$(EXEEXT) luatexdir/pdf/pdfliteral.w
+ $(luatex_pdf_ctangle) pdfliteral.w
+
+pdfobj.c: ctangle$(EXEEXT) luatexdir/pdf/pdfobj.w
+ $(luatex_pdf_ctangle) pdfobj.w
+
+pdfoutline.c: ctangle$(EXEEXT) luatexdir/pdf/pdfoutline.w
+ $(luatex_pdf_ctangle) pdfoutline.w
+
+pdfpage.c: ctangle$(EXEEXT) luatexdir/pdf/pdfpage.w
+ $(luatex_pdf_ctangle) pdfpage.w
+
+pdfrule.c: ctangle$(EXEEXT) luatexdir/pdf/pdfrule.w
+ $(luatex_pdf_ctangle) pdfrule.w
+
+pdfsaverestore.c: ctangle$(EXEEXT) luatexdir/pdf/pdfsaverestore.w
+ $(luatex_pdf_ctangle) pdfsaverestore.w
+
+pdfsetmatrix.c: ctangle$(EXEEXT) luatexdir/pdf/pdfsetmatrix.w
+ $(luatex_pdf_ctangle) pdfsetmatrix.w
+
+pdfshipout.c: ctangle$(EXEEXT) luatexdir/pdf/pdfshipout.w
+ $(luatex_pdf_ctangle) pdfshipout.w
+
+pdftables.c: ctangle$(EXEEXT) luatexdir/pdf/pdftables.w
+ $(luatex_pdf_ctangle) pdftables.w
+
+pdfthread.c: ctangle$(EXEEXT) luatexdir/pdf/pdfthread.w
+ $(luatex_pdf_ctangle) pdfthread.w
+
+pdfxform.c: ctangle$(EXEEXT) luatexdir/pdf/pdfxform.w
+ $(luatex_pdf_ctangle) pdfxform.w
+
+libluatex_web += luatexdir/pdf/pagetree.w luatexdir/pdf/pdfaction.w luatexdir/pdf/pdfannot.w
+libluatex_web += luatexdir/pdf/pdfcolorstack.w luatexdir/pdf/pdfdest.w
+libluatex_web += luatexdir/pdf/pdffont.w luatexdir/pdf/pdfgen.w luatexdir/pdf/pdfglyph.w
+libluatex_web += luatexdir/pdf/pdfimage.w luatexdir/pdf/pdflink.w luatexdir/pdf/pdflistout.w
+libluatex_web += luatexdir/pdf/pdfliteral.w luatexdir/pdf/pdfobj.w luatexdir/pdf/pdfoutline.w
+libluatex_web += luatexdir/pdf/pdfpage.w luatexdir/pdf/pdfrule.w
+libluatex_web += luatexdir/pdf/pdfsaverestore.w luatexdir/pdf/pdfsetmatrix.w
+libluatex_web += luatexdir/pdf/pdfshipout.w luatexdir/pdf/pdftables.w
+libluatex_web += luatexdir/pdf/pdfthread.w luatexdir/pdf/pdfxform.w
+
+nodist_libluatex_a_SOURCES += pagetree.c pdfaction.c pdfannot.c pdfcolorstack.c pdfdest.c pdffont.c
+nodist_libluatex_a_SOURCES += pdfgen.c pdfglyph.c pdfimage.c pdflink.c pdflistout.c pdfliteral.c
+nodist_libluatex_a_SOURCES += pdfobj.c pdfoutline.c pdfpage.c pdfrule.c pdfsaverestore.c
+nodist_libluatex_a_SOURCES += pdfsetmatrix.c pdfshipout.c pdftables.c pdfthread.c pdfxform.c
+
+luatex_tex_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/tex $(ctangle)
+
+align.c: ctangle$(EXEEXT) luatexdir/tex/align.w
+ $(luatex_tex_ctangle) align.w
+
+libluatex_web += luatexdir/tex/align.w
+
+nodist_libluatex_a_SOURCES += align.c
+
+dumpdata.c: ctangle$(EXEEXT) luatexdir/tex/dumpdata.w
+ $(luatex_tex_ctangle) dumpdata.w
+
+nodist_libluatex_a_SOURCES += dumpdata.c
+
+libluatex_web += luatexdir/tex/dumpdata.w
+
+
+expand.c: ctangle$(EXEEXT) luatexdir/tex/expand.w
+ $(luatex_tex_ctangle) expand.w
+
+nodist_libluatex_a_SOURCES += expand.c
+
+libluatex_web += luatexdir/tex/expand.w
+
+
+inputstack.c: ctangle$(EXEEXT) luatexdir/tex/inputstack.w
+ $(luatex_tex_ctangle) inputstack.w
+
+nodist_libluatex_a_SOURCES += inputstack.c
+
+libluatex_web += luatexdir/tex/inputstack.w
+
+
+maincontrol.c: ctangle$(EXEEXT) luatexdir/tex/maincontrol.w
+ $(luatex_tex_ctangle) maincontrol.w
+
+nodist_libluatex_a_SOURCES += maincontrol.c
+
+libluatex_web += luatexdir/tex/maincontrol.w
+
+
+mlist.c: ctangle$(EXEEXT) luatexdir/tex/mlist.w
+ $(luatex_tex_ctangle) mlist.w
+
+nodist_libluatex_a_SOURCES += mlist.c
+
+libluatex_web += luatexdir/tex/mlist.w
+
+
+postlinebreak.c: ctangle$(EXEEXT) luatexdir/tex/postlinebreak.w
+ $(luatex_tex_ctangle) postlinebreak.w
+
+nodist_libluatex_a_SOURCES += postlinebreak.c
+
+libluatex_web += luatexdir/tex/postlinebreak.w
+
+
+scanning.c: ctangle$(EXEEXT) luatexdir/tex/scanning.w
+ $(luatex_tex_ctangle) scanning.w
+
+nodist_libluatex_a_SOURCES += scanning.c
+
+libluatex_web += luatexdir/tex/scanning.w
+
+
+texdeffont.c: ctangle$(EXEEXT) luatexdir/tex/texdeffont.w
+ $(luatex_tex_ctangle) texdeffont.w
+
+nodist_libluatex_a_SOURCES += texdeffont.c
+
+libluatex_web += luatexdir/tex/texdeffont.w
+
+
+texnodes.c: ctangle$(EXEEXT) luatexdir/tex/texnodes.w
+ $(luatex_tex_ctangle) texnodes.w
+
+nodist_libluatex_a_SOURCES += texnodes.c
+
+libluatex_web += luatexdir/tex/texnodes.w
+
+
+arithmetic.c: ctangle$(EXEEXT) luatexdir/tex/arithmetic.w
+ $(luatex_tex_ctangle) arithmetic.w
+
+nodist_libluatex_a_SOURCES += arithmetic.c
+
+libluatex_web += luatexdir/tex/arithmetic.w
+
+
+conditional.c: ctangle$(EXEEXT) luatexdir/tex/conditional.w
+ $(luatex_tex_ctangle) conditional.w
+
+nodist_libluatex_a_SOURCES += conditional.c
+
+libluatex_web += luatexdir/tex/conditional.w
+
+
+equivalents.c: ctangle$(EXEEXT) luatexdir/tex/equivalents.w
+ $(luatex_tex_ctangle) equivalents.w
+
+nodist_libluatex_a_SOURCES += equivalents.c
+
+libluatex_web += luatexdir/tex/equivalents.w
+
+
+extensions.c: ctangle$(EXEEXT) luatexdir/tex/extensions.w
+ $(luatex_tex_ctangle) extensions.w
+
+nodist_libluatex_a_SOURCES += extensions.c
+
+libluatex_web += luatexdir/tex/extensions.w
+
+commands.c: ctangle$(EXEEXT) luatexdir/tex/commands.w
+ $(luatex_tex_ctangle) commands.w
+
+nodist_libluatex_a_SOURCES += commands.c
+
+libluatex_web += luatexdir/tex/commands.w
+
+
+linebreak.c: ctangle$(EXEEXT) luatexdir/tex/linebreak.w
+ $(luatex_tex_ctangle) linebreak.w
+
+nodist_libluatex_a_SOURCES += linebreak.c
+
+libluatex_web += luatexdir/tex/linebreak.w
+
+
+mathcodes.c: ctangle$(EXEEXT) luatexdir/tex/mathcodes.w
+ $(luatex_tex_ctangle) mathcodes.w
+
+nodist_libluatex_a_SOURCES += mathcodes.c
+
+libluatex_web += luatexdir/tex/mathcodes.w
+
+
+nesting.c: ctangle$(EXEEXT) luatexdir/tex/nesting.w
+ $(luatex_tex_ctangle) nesting.w
+
+nodist_libluatex_a_SOURCES += nesting.c
+
+libluatex_web += luatexdir/tex/nesting.w
+
+
+primitive.c: ctangle$(EXEEXT) luatexdir/tex/primitive.w
+ $(luatex_tex_ctangle) primitive.w
+
+nodist_libluatex_a_SOURCES += primitive.c
+
+libluatex_web += luatexdir/tex/primitive.w
+
+
+texfileio.c: ctangle$(EXEEXT) luatexdir/tex/texfileio.w
+ $(luatex_tex_ctangle) texfileio.w
+
+nodist_libluatex_a_SOURCES += texfileio.c
+
+libluatex_web += luatexdir/tex/texfileio.w
+
+
+textcodes.c: ctangle$(EXEEXT) luatexdir/tex/textcodes.w
+ $(luatex_tex_ctangle) textcodes.w
+
+nodist_libluatex_a_SOURCES += textcodes.c
+
+libluatex_web += luatexdir/tex/textcodes.w
+
+
+buildpage.c: ctangle$(EXEEXT) luatexdir/tex/buildpage.w
+ $(luatex_tex_ctangle) buildpage.w
+
+nodist_libluatex_a_SOURCES += buildpage.c
+
+libluatex_web += luatexdir/tex/buildpage.w
+
+
+directions.c: ctangle$(EXEEXT) luatexdir/tex/directions.w
+ $(luatex_tex_ctangle) directions.w
+
+nodist_libluatex_a_SOURCES += directions.c
+
+libluatex_web += luatexdir/tex/directions.w
+
+
+errors.c: ctangle$(EXEEXT) luatexdir/tex/errors.w
+ $(luatex_tex_ctangle) errors.w
+
+nodist_libluatex_a_SOURCES += errors.c
+
+libluatex_web += luatexdir/tex/errors.w
+
+
+filename.c: ctangle$(EXEEXT) luatexdir/tex/filename.w
+ $(luatex_tex_ctangle) filename.w
+
+nodist_libluatex_a_SOURCES += filename.c
+
+libluatex_web += luatexdir/tex/filename.w
+
+
+mainbody.c: ctangle$(EXEEXT) luatexdir/tex/mainbody.w
+ $(luatex_tex_ctangle) mainbody.w
+
+nodist_libluatex_a_SOURCES += mainbody.c
+
+libluatex_web += luatexdir/tex/mainbody.w
+
+
+memoryword.c: ctangle$(EXEEXT) luatexdir/tex/memoryword.w
+ $(luatex_tex_ctangle) memoryword.w
+
+nodist_libluatex_a_SOURCES += memoryword.c
+
+libluatex_web += luatexdir/tex/memoryword.w
+
+
+packaging.c: ctangle$(EXEEXT) luatexdir/tex/packaging.w
+ $(luatex_tex_ctangle) packaging.w
+
+nodist_libluatex_a_SOURCES += packaging.c
+
+libluatex_web += luatexdir/tex/packaging.w
+
+
+printing.c: ctangle$(EXEEXT) luatexdir/tex/printing.w
+ $(luatex_tex_ctangle) printing.w
+
+nodist_libluatex_a_SOURCES += printing.c
+
+libluatex_web += luatexdir/tex/printing.w
+
+
+stringpool.c: ctangle$(EXEEXT) luatexdir/tex/stringpool.w
+ $(luatex_tex_ctangle) stringpool.w
+
+nodist_libluatex_a_SOURCES += stringpool.c
+
+libluatex_web += luatexdir/tex/stringpool.w
+
+
+texmath.c: ctangle$(EXEEXT) luatexdir/tex/texmath.w
+ $(luatex_tex_ctangle) texmath.w
+
+nodist_libluatex_a_SOURCES += texmath.c
+
+libluatex_web += luatexdir/tex/texmath.w
+
+
+textoken.c: ctangle$(EXEEXT) luatexdir/tex/textoken.w
+ $(luatex_tex_ctangle) textoken.w
+
+nodist_libluatex_a_SOURCES += textoken.c
+
+libluatex_web += luatexdir/tex/textoken.w
+
+
+luatex_utils_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/utils $(ctangle)
+
+utils.c: ctangle$(EXEEXT) luatexdir/utils/utils.w
+ $(luatex_utils_ctangle) utils.w
+managed-sa.c: ctangle$(EXEEXT) luatexdir/utils/managed-sa.w
+ $(luatex_utils_ctangle) managed-sa.w
+avlstuff.c: ctangle$(EXEEXT) luatexdir/utils/avlstuff.w
+ $(luatex_utils_ctangle) avlstuff.w
+
+libluatex_web += luatexdir/utils/utils.w luatexdir/utils/avlstuff.w luatexdir/utils/managed-sa.w
+
+nodist_libluatex_a_SOURCES += utils.c avlstuff.c managed-sa.c
+
+
libluatex_a_SOURCES = \
- luatexdir/commands.h \
- luatexdir/font/dofont.c \
+ luatexdir/dvi/dvigen.h \
luatexdir/font/luatexfont.h \
- luatexdir/font/luafont.c \
- luatexdir/font/mapfile.c \
luatexdir/font/mapfile.h \
- luatexdir/font/pkin.c \
- luatexdir/font/sfnt.c \
luatexdir/font/sfnt.h \
- luatexdir/font/subfont.c \
- luatexdir/font/texfont.c \
luatexdir/font/texfont.h \
- luatexdir/font/tfmofm.c \
- luatexdir/font/tounicode.c \
- luatexdir/font/tt_glyf.c \
luatexdir/font/tt_glyf.h \
- luatexdir/font/tt_table.c \
luatexdir/font/tt_table.h \
- luatexdir/font/vfovf.c \
- luatexdir/font/vfpacket.c \
- luatexdir/font/writecff.c \
luatexdir/font/writecff.h \
- luatexdir/font/writeenc.c \
- luatexdir/font/writefont.c \
- luatexdir/font/writet1.c \
- luatexdir/font/writet3.c \
- luatexdir/font/writettf.c \
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 \
luatexdir/image/image.h \
luatexdir/image/pdftoepdf.cc \
luatexdir/image/pdftoepdf.h \
- luatexdir/image/writeimg.c \
luatexdir/image/writeimg.h \
- luatexdir/image/writejbig2.c \
luatexdir/image/writejbig2.h \
- luatexdir/image/writejpg.c \
luatexdir/image/writejpg.h \
- luatexdir/image/writepng.c \
luatexdir/image/writepng.h \
- luatexdir/lang/hnjalloc.c \
luatexdir/lang/hnjalloc.h \
- luatexdir/lang/hyphen.c \
- luatexdir/lang/texlang.c \
+ luatexdir/lang/hyphen.h \
+ luatexdir/lang/texlang.h \
luatexdir/lua/lcallbacklib.c \
luatexdir/lua/lfontlib.c \
luatexdir/lua/limglib.c \
+ luatexdir/lua/lepdflib.cc \
luatexdir/lua/lkpselib.c \
luatexdir/lua/llanglib.c \
luatexdir/lua/llualib.c \
@@ -80,65 +549,87 @@ libluatex_a_SOURCES = \
luatexdir/lua/ltexiolib.c \
luatexdir/lua/ltexlib.c \
luatexdir/lua/ltokenlib.c \
- luatexdir/lua/luainit.c \
- luatexdir/lua/luanode.c \
- luatexdir/lua/luastuff.c \
- luatexdir/lua/luatex.c \
- luatexdir/lua/luatoken.c \
- luatexdir/lua/texluac.c \
- luatexdir/luatex-api.h \
+ luatexdir/lua/luagen.h \
+ luatexdir/lua/luatex-api.h \
luatexdir/luatex.h \
- luatexdir/makecpool.c \
- luatexdir/managed-sa.c \
- luatexdir/managed-sa.h \
- luatexdir/mathcodes.c \
- luatexdir/nodes.h \
- luatexdir/pdf/pagetree.c \
+ luatexdir/ocp/ocp.h \
+ luatexdir/ocp/ocplist.h \
+ luatexdir/ocp/readocp.h \
+ luatexdir/ocp/runocp.h \
luatexdir/pdf/pagetree.h \
- luatexdir/pdf/pdfpage.c \
+ luatexdir/pdf/pdfaction.h \
+ luatexdir/pdf/pdfannot.h \
+ luatexdir/pdf/pdfcolorstack.h \
+ luatexdir/pdf/pdfdest.h \
+ luatexdir/pdf/pdffont.h \
+ luatexdir/pdf/pdfgen.h \
+ luatexdir/pdf/pdfglyph.h \
+ luatexdir/pdf/pdfimage.h \
+ luatexdir/pdf/pdflink.h \
+ luatexdir/pdf/pdflistout.h \
+ luatexdir/pdf/pdfliteral.h \
+ luatexdir/pdf/pdfobj.h \
+ luatexdir/pdf/pdfoutline.h \
luatexdir/pdf/pdfpage.h \
- luatexdir/primitive.h \
- luatexdir/ptexmac.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/pdf/pdfrule.h \
+ luatexdir/pdf/pdfsaverestore.h \
+ luatexdir/pdf/pdfsetmatrix.h \
+ luatexdir/pdf/pdfshipout.h \
+ luatexdir/pdf/pdftables.h \
+ luatexdir/pdf/pdfthread.h \
+ luatexdir/pdf/pdftypes.h \
+ luatexdir/pdf/pdfxform.h \
+ luatexdir/tex/align.h \
+ luatexdir/tex/arithmetic.h \
+ luatexdir/tex/buildpage.h \
+ luatexdir/tex/commands.h \
+ luatexdir/tex/conditional.h \
+ luatexdir/tex/directions.h \
+ luatexdir/tex/dumpdata.h \
+ luatexdir/tex/equivalents.h \
+ luatexdir/tex/errors.h \
+ luatexdir/tex/expand.h \
+ luatexdir/tex/extensions.h \
+ luatexdir/tex/filename.h \
+ luatexdir/tex/inputstack.h \
+ luatexdir/tex/linebreak.h \
+ luatexdir/tex/mainbody.h \
+ luatexdir/tex/maincontrol.h \
+ luatexdir/tex/mathcodes.h \
+ luatexdir/tex/memoryword.h \
+ luatexdir/tex/mlist.h \
+ luatexdir/tex/nesting.h \
+ luatexdir/tex/packaging.h \
+ luatexdir/tex/postlinebreak.h \
+ luatexdir/tex/primitive.h \
+ luatexdir/tex/printing.h \
+ luatexdir/tex/scanning.h \
+ luatexdir/tex/stringpool.h \
+ luatexdir/tex/texdeffont.h \
+ luatexdir/tex/texfileio.h \
+ luatexdir/tex/texmath.h \
+ luatexdir/tex/texnodes.h \
+ luatexdir/tex/textoken.h \
+ luatexdir/tex/textcodes.h \
luatexdir/utils/avl.c \
luatexdir/utils/avl.h \
- luatexdir/utils/avlstuff.c \
luatexdir/utils/avlstuff.h \
+ luatexdir/utils/managed-sa.h \
luatexdir/utils/synctex.h \
luatexdir/utils/synctex.c \
- luatexdir/utils/utils.c \
luatexdir/utils/utils.h \
- luatexdir/utils/writezip.c \
+ $(nodist_libluatex_a_SOURCES) \
mplibdir/lmplib.c
-## FIXME: temporary additional headers:
-libluatex_a_SOURCES += \
- luatexdir/inc-epdf.h \
- luatexdir/inc-extra.h \
- luatexdir/inc-vfovf.h
+$(libluatex_a_OBJECTS): libff.a
-## included by luatexdir/font/writettf.c
-EXTRA_libluatex_a_SOURCES = luatexdir/font/macnames.c
+EXTRA_DIST += $(libluatex_web)
-# We must create libff.a and luatexd.h before building the libluatex_a_OBJECTS
-$(libluatex_a_OBJECTS): libff.a luatexd.h luatexdir/luatexextra.h
+DISTCLEANFILES += $(nodist_libluatex_a_SOURCES)
EXTRA_DIST += \
luatexdir/ChangeLog \
luatexdir/NEWS \
luatexdir/README \
- luatexdir/change-files.txt \
luatexdir/font/subfont.txt
diff --git a/Build/source/texk/web2c/luatexdir/am/luafontforge.am b/Build/source/texk/web2c/luatexdir/am/luafontforge.am
index f137f43fe7f..8f1770d07d6 100644
--- a/Build/source/texk/web2c/luatexdir/am/luafontforge.am
+++ b/Build/source/texk/web2c/luatexdir/am/luafontforge.am
@@ -23,15 +23,12 @@ libff_a_CFLAGS = # $(WARNING_CFLAGS)
libff_a_SOURCES = \
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 \
@@ -121,8 +118,7 @@ libff_a_SOURCES = \
luatexdir/luafontloader/fontforge/inc/ustring.h \
luatexdir/luafontloader/fontforge/inc/utype.h \
luatexdir/luafontloader/src/ffdummies.c \
- luatexdir/luafontloader/src/luafflib.c \
- luatexdir/luafontloader/src/luafflib.h
+ luatexdir/luafontloader/src/luafflib.c
EXTRA_DIST += \
luatexdir/luafontloader/ChangeLog \
diff --git a/Build/source/texk/web2c/luatexdir/am/luamisc.am b/Build/source/texk/web2c/luatexdir/am/luamisc.am
index 07a80dab334..5f43cf2b64a 100644
--- a/Build/source/texk/web2c/luatexdir/am/luamisc.am
+++ b/Build/source/texk/web2c/luatexdir/am/luamisc.am
@@ -22,8 +22,9 @@ libluamisc_a_SOURCES = \
luatexdir/luafilesystem/src/lfs.c \
luatexdir/luafilesystem/src/lfs.h \
luatexdir/luamd5/md5.c \
- luatexdir/luamd5/md5.h \
+ luatexdir/luamd5/luamd5.h \
luatexdir/luamd5/md5lib.c \
+ luatexdir/luamd5/md5_lua.c \
luatexdir/luapeg/lpeg.c \
luatexdir/luaprofiler/clocks.c \
luatexdir/luaprofiler/clocks.h \
diff --git a/Build/source/texk/web2c/luatexdir/am/luatangle.am b/Build/source/texk/web2c/luatexdir/am/luatangle.am
index 75fa50ca29d..39218db3d56 100644
--- a/Build/source/texk/web2c/luatexdir/am/luatangle.am
+++ b/Build/source/texk/web2c/luatexdir/am/luatangle.am
@@ -3,33 +3,3 @@
## Copyright (C) 2009 Peter Breitenlohner <tex-live@tug.org>
## You may freely use, modify and/or distribute this file.
-## luatangle
-##
-if LUATEX
-bin_PROGRAMS += luatangle
-endif LUATEX
-EXTRA_PROGRAMS += luatangle
-
-nodist_luatangle_SOURCES = luatangle.c luatangle.h
-luatangle.c luatangle.h: luatangle-web2c
- @$(web2c) luatangle
-luatangle-web2c: luatangle.p $(web2c_depend)
- @$(web2c) luatangle
-
-EXTRA_DIST += $(luatangle_sources)
-
-luatangle_sources = luatexdir/luatangle.web luatexdir/luatangle.ch
-luatangle.p: tangle$(EXEEXT) $(luatangle_sources)
- WEBINPUTS=$(srcdir)/luatexdir $(buildenv) $(TANGLE) luatangle luatangle
-
-DISTCLEANFILES += luatangle.c luatangle.h luatangle-web2c luatangle.p
-
-## Tests
-##
-EXTRA_DIST += luatexdir/luatangle.test
-
-if LUATEX
-TESTS += luatexdir/luatangle.test
-endif LUATEX
-
-DISTCLEANFILES += cftest.p
diff --git a/Build/source/texk/web2c/luatexdir/am/luatex.am b/Build/source/texk/web2c/luatexdir/am/luatex.am
index 19f891fc7a6..e979f60865a 100644
--- a/Build/source/texk/web2c/luatexdir/am/luatex.am
+++ b/Build/source/texk/web2c/luatexdir/am/luatex.am
@@ -13,8 +13,6 @@ EXTRA_PROGRAMS += luatex
# Force Automake to use CXXLD for linking
nodist_EXTRA_luatex_SOURCES = dummy.cxx
-luatex_tangle = WEBINPUTS=$(srcdir)/luatexdir $(SHELL) ./tangle-sh $@ '$(LUATANGLE) --underlines'
-
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 -I$(srcdir)/mplibdir
@@ -24,40 +22,19 @@ luatex_CXXFLAGS = $(WARNING_CXXFLAGS)
luatex_ldadd = libluatex.a libff.a libluamisc.a libluasocket.a liblua51.a
luatex_ldadd += $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) $(XPDF_LIBS)
-luatex_ldadd += $(OBSDCOMPAT_LIBS) libmd5.a libmplib.a
+luatex_ldadd += $(OBSDCOMPAT_LIBS) libmd5.a libmplib.a
+
+luatex_LDFLAGS = -export-dynamic
-luatex_LDADD = $(luatex_ldadd) $(LDADD) $(lua_socketlibs)
+luatex_LDADD = $(luatex_ldadd) $(LDADD) $(LIBADD_DLOPEN) $(lua_socketlibs)
luatex_DEPENDENCIES = $(proglib) $(KPATHSEA_DEPEND) libluatex.a
luatex_DEPENDENCIES += $(LIBPNG_DEPEND) $(ZLIB_DEPEND) $(XPDF_DEPEND)
luatex_DEPENDENCIES += $(OBSDCOMPAT_DEPEND) libmd5.a libmplib.a
-# We must create libluatex.a and libmplib.a before building the luatex_OBJECTS.
$(luatex_OBJECTS): libluatex.a libmplib.a
-luatex_c_h = luatexini.c luatex0.c luatexcoerce.h luatexd.h
-nodist_luatex_SOURCES = $(luatex_c_h) luatex-pool.c luatexextra.c luatexdir/luatexextra.h
-$(luatex_c_h): luatex-web2c
- @$(web2c) luatex
-luatex-web2c: luatex.p $(web2c_texmf) luatexdir/luatex.defines
- @$(web2c) luatex
-luatexextra.c: luatexd.h luatexdir/luatexextra.h lib/texmfmp.c
- sed s/TEX-OR-MF-OR-MP/luatex/ $(srcdir)/lib/texmfmp.c >$@
-luatex_sources = luatexdir/luatex.web luatexdir/luatex.ch
-luatex.p luatex.pool: luatex-tangle
- @$(luatex_tangle) luatex luatex
-luatex-tangle: luatangle$(EXEEXT) $(luatex_sources) tangle-sh
- @$(luatex_tangle) luatex luatex
-luatex-pool.c: luatex.pool luatexd.h $(makecpool_stamp)
- $(makecpool) luatex >$@ || rm -f $@
-# Extract luatex version
-luatexdir/luatex.version: luatexdir/luatex.web
- $(MKDIR_P) luatexdir
- grep '^@d luatex_version_string==' $(srcdir)/luatexdir/luatex.web \
- | sed "s/^.*=='//;s/'.*$$//" >luatexdir/luatex.version
-luatexdir/luatexextra.h: luatexdir/luatexextra.in luatexdir/luatex.version
- sed -e s/LUATEX-VERSION/`cat luatexdir/luatex.version`/ \
- $(srcdir)/luatexdir/luatexextra.in >$@
+luatex_SOURCES = luatexdir/luatex_svnversion.h luatexdir/luatex.c luatexdir/luatex.h
# Double-colon rules since we do something similar in mplibdir (maybe others).
if LUATEX
@@ -71,15 +48,5 @@ uninstall-hook::
rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT)
endif LUATEX
-EXTRA_DIST += $(luatex_sources) \
- luatexdir/luatex.defines \
- luatexdir/luatexextra.in \
- luatexdir/ptexlib.h
-
-DISTCLEANFILES += $(nodist_luatex_SOURCES) luatex-web2c \
- luatex.p luatex.pool luatex-tangle luatexdir/luatex.version
-
-## Eventually delete these files
-##
-EXTRA_DIST += luatexdir/luatex.mk
+EXTRA_DIST += luatexdir/ptexlib.h
diff --git a/Build/source/texk/web2c/luatexdir/change-files.txt b/Build/source/texk/web2c/luatexdir/change-files.txt
deleted file mode 100644
index c6a3387f41d..00000000000
--- a/Build/source/texk/web2c/luatexdir/change-files.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-How change files are applied for pdftex/pdfetex?
-
-============================= pdftex =============================
-
-2) pdftex.ch is generated from
- ./tie -c pdftex.ch pdftex.web \
- $(srcdir)/pdftexdir/tex.ch0 \
- $(srcdir)/tex.ch \
- $(srcdir)/pdftexdir/tex.ch1 \
- $(srcdir)/pdftexdir/tex.pch
-
-Input:
- pdftex.web:
- pdftex without system-dependent changes
-
- pdftexdir/tex.ch0:
- % Change file to assist in creating the web2c-specific change file.
- % This one comes first, resolves inconsistencies between the
- % generated pdftex.web and tex.ch
-
- change the pdftex banner to tex banner, so tex.ch can be applied
-
- tex.ch:
- the main web2c-specific (or other system-dependent) change file
-
- pdftexdir/pdftex.ch:
-
- % Change file to assist in creating the web2c-specific change file.
- % This one resolves inconsistencies between tex.ch and tex.pch.
-
- change the tex banner to pdftex banner (reverse tex.ch0)
-
-Output:
- pdftex.ch (not pdftexdir/pdftex.ch):
- additional & system-dependent changes
diff --git a/Build/source/texk/web2c/luatexdir/commands.h b/Build/source/texk/web2c/luatexdir/commands.h
deleted file mode 100644
index b9a50adca8e..00000000000
--- a/Build/source/texk/web2c/luatexdir/commands.h
+++ /dev/null
@@ -1,554 +0,0 @@
-/* commands.h
-
- Copyright 2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-/* $Id: commands.h 2554 2009-06-21 07:58:02Z 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 \<v_j> 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} ) */
- super_sub_script_cmd, /* explicit super- or subscript */
- math_shift_cs_cmd, /* start- and endmath */
- 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_math_style_code, /* command code for \.{\\mathstyle} */
- 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}' */
- 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;
-
-#define max_group_code local_box_group
diff --git a/Build/source/texk/web2c/luatexdir/dvi/dvigen.h b/Build/source/texk/web2c/luatexdir/dvi/dvigen.h
new file mode 100644
index 00000000000..29989a3e10c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/dvi/dvigen.h
@@ -0,0 +1,193 @@
+/* dvigen.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: dvigen.h 3404 2010-01-28 11:17:10Z taco $ */
+
+#ifndef DVIGEN_H
+# define DVIGEN_H
+
+extern int total_pages;
+extern scaled max_v;
+extern scaled max_h;
+extern int max_push;
+extern int last_bop;
+extern int dead_cycles;
+extern boolean doing_leaders;
+extern int c, f;
+extern int oval, ocmd;
+extern halfword g;
+extern int lq, lr;
+extern int cur_s;
+
+typedef int dvi_index; /* an index into the output buffer */
+
+extern int dvi_buf_size;
+extern eight_bits *dvi_buf; /* 0 is unused */
+extern dvi_index half_buf;
+extern dvi_index dvi_limit;
+extern dvi_index dvi_ptr;
+extern int dvi_offset;
+extern int dvi_gone;
+
+/*
+To put a byte in the buffer without paying the cost of invoking a procedure
+each time, we use the macro |dvi_out|.
+*/
+
+# define dvi_out(A) do { \
+ dvi_buf[dvi_ptr++]=(eight_bits)(A); \
+ if (dvi_ptr==dvi_limit) dvi_swap(); \
+ } while (0)
+
+extern void dvi_swap(void);
+extern void dvi_four(int x);
+extern void dvi_push(void);
+extern void dvi_pop(int l);
+extern void out_cmd(void);
+extern void dvi_font_def(internal_font_number f);
+
+# define dvi_set(A,B) do { \
+ oval=A; ocmd=set1; out_cmd(); dvi.h += (B); \
+ } while (0)
+
+# define dvi_put(A) do { \
+ oval=A; ocmd=put1; out_cmd(); \
+ } while (0)
+
+# define location(A) varmem[(A)+1].cint
+
+extern halfword down_ptr, right_ptr; /* heads of the down and right stacks */
+
+/*
+The |vinfo| fields in the entries of the down stack or the right stack
+have six possible settings: |y_here| or |z_here| mean that the \.{DVI}
+command refers to |y| or |z|, respectively (or to |w| or |x|, in the
+case of horizontal motion); |yz_OK| means that the \.{DVI} command is
+\\{down} (or \\{right}) but can be changed to either |y| or |z| (or
+to either |w| or |x|); |y_OK| means that it is \\{down} and can be changed
+to |y| but not |z|; |z_OK| is similar; and |d_fixed| means it must stay
+\\{down}.
+
+The four settings |yz_OK|, |y_OK|, |z_OK|, |d_fixed| would not need to
+be distinguished from each other if we were simply solving the
+digit-subscripting problem mentioned above. But in \TeX's case there is
+a complication because of the nested structure of |push| and |pop|
+commands. Suppose we add parentheses to the digit-subscripting problem,
+redefining hits so that $\delta_y\ldots \delta_y$ is a hit if all $y$'s between
+the $\delta$'s are enclosed in properly nested parentheses, and if the
+parenthesis level of the right-hand $\delta_y$ is deeper than or equal to
+that of the left-hand one. Thus, `(' and `)' correspond to `|push|'
+and `|pop|'. Now if we want to assign a subscript to the final 1 in the
+sequence
+$$2_y\,7_d\,1_d\,(\,8_z\,2_y\,8_z\,)\,1$$
+we cannot change the previous $1_d$ to $1_y$, since that would invalidate
+the $2_y\ldots2_y$ hit. But we can change it to $1_z$, scoring a hit
+since the intervening $8_z$'s are enclosed in parentheses.
+*/
+
+typedef enum {
+ y_here = 1, /* |vinfo| when the movement entry points to a |y| command */
+ z_here = 2, /* |vinfo| when the movement entry points to a |z| command */
+ yz_OK = 3, /* |vinfo| corresponding to an unconstrained \\{down} command */
+ y_OK = 4, /* |vinfo| corresponding to a \\{down} that can't become a |z| */
+ z_OK = 5, /* |vinfo| corresponding to a \\{down} that can't become a |y| */
+ d_fixed = 6, /* |vinfo| corresponding to a \\{down} that can't change */
+} movement_codes;
+
+/* As we search through the stack, we are in one of three states,
+ |y_seen|, |z_seen|, or |none_seen|, depending on whether we have
+ encountered |y_here| or |z_here| nodes. These states are encoded as
+ multiples of 6, so that they can be added to the |info| fields for quick
+ decision-making. */
+
+# define none_seen 0 /* no |y_here| or |z_here| nodes have been encountered yet */
+# define y_seen 6 /* we have seen |y_here| but not |z_here| */
+# define z_seen 12 /* we have seen |z_here| but not |y_here| */
+
+extern void movement(scaled w, eight_bits o);
+extern void prune_movements(int l);
+
+/*
+The actual distances by which we want to move might be computed as the
+sum of several separate movements. For example, there might be several
+glue nodes in succession, or we might want to move right by the width of
+some box plus some amount of glue. More importantly, the baselineskip
+distances are computed in terms of glue together with the depth and
+height of adjacent boxes, and we want the \.{DVI} file to lump these
+three quantities together into a single motion.
+
+Therefore, \TeX\ maintains two pairs of global variables: |dvi.h| and |dvi.v|
+are the |h| and |v| coordinates corresponding to the commands actually
+output to the \.{DVI} file, while |cur.h| and |cur.v| are the coordinates
+corresponding to the current state of the output routines. Coordinate
+changes will accumulate in |cur.h| and |cur.v| without being reflected
+in the output, until such a change becomes necessary or desirable; we
+can call the |movement| procedure whenever we want to make |dvi.h=pos.h|
+or |dvi.v=pos.v|.
+
+The current font reflected in the \.{DVI} output is called |dvi_f|;
+there is no need for a `\\{cur\_f}' variable.
+
+The depth of nesting of |hlist_out| and |vlist_out| is called |cur_s|;
+this is essentially the depth of |push| commands in the \.{DVI} output.
+*/
+
+# define synch_h(p) do { \
+ if (p.h != dvi.h) { \
+ movement(p.h - dvi.h, right1); \
+ dvi.h = p.h; \
+ } \
+ } while (0)
+
+# define synch_v(p) do { \
+ if (p.v != dvi.v) { \
+ movement(dvi.v - p.v, down1); \
+ dvi.v = p.v; \
+ } \
+ } while (0)
+
+# define synch_dvi_with_pos(p) do {synch_h(p); synch_v(p); } while (0)
+
+# define billion 1000000000.0
+
+# define vet_glue(A) do { glue_temp=A; \
+ if (glue_temp>billion) \
+ glue_temp=billion; \
+ else if (glue_temp<-billion) \
+ glue_temp=-billion; \
+ } while (0)
+
+extern scaled_whd rule;
+extern scaledpos dvi;
+extern scaledpos cur_page_size; /* width and height of page being shipped */
+
+extern void expand_macros_in_tokenlist(halfword p);
+extern void write_out(halfword p);
+extern void dvi_special(PDF pdf, halfword p);
+
+extern void ensure_dvi_header_written(PDF pdf);
+extern void finish_dvi_file(PDF pdf, int version, int revision);
+
+extern void dvi_place_glyph(PDF pdf, internal_font_number f, int c);
+extern void dvi_place_rule(PDF pdf, halfword q, scaledpos size);
+
+extern void dvi_begin_page(PDF pdf);
+extern void dvi_end_page(PDF pdf);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/dvi/dvigen.w b/Build/source/texk/web2c/luatexdir/dvi/dvigen.w
new file mode 100644
index 00000000000..240d589fee1
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/dvi/dvigen.w
@@ -0,0 +1,1420 @@
+%dvigen.w
+
+%Copyright 2009-2010 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.
+
+%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 <http://www.gnu.org/licenses/>.
+
+\def\MF{MetaFont}
+\def\MP{MetaPost}
+\def\PASCAL{Pascal}
+\def\[#1]{#1}
+\pdfoutput=1
+\pdfmapline{cmtex10 < cmtex10.pfb}
+\pdfmapfile{pdftex.map}
+
+\title{: generation of DVI output}
+
+@ Initial identification of this file, and the needed headers.
+@c
+static const char _svn_version[] =
+ "$Id: dvigen.w 3535 2010-03-21 17:02:05Z oneiros $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/dvi/dvigen.w $";
+
+#include "ptexlib.h"
+
+@ Here is the start of the actual C file.
+@c
+#undef write_dvi
+
+#define mode cur_list.mode_field /* current mode */
+
+#define pdf_output int_par(pdf_output_code)
+#define mag int_par(mag_code)
+#define tracing_output int_par(tracing_output_code)
+#define tracing_stats int_par(tracing_stats_code)
+#define tracing_online int_par(tracing_online_code)
+#define page_direction int_par(page_direction_code)
+#define page_width dimen_par(page_width_code)
+#define page_height dimen_par(page_height_code)
+#define page_left_offset dimen_par(page_left_offset_code)
+#define page_right_offset dimen_par(page_right_offset_code)
+#define page_top_offset dimen_par(page_top_offset_code)
+#define page_bottom_offset dimen_par(page_bottom_offset_code)
+#define h_offset dimen_par(h_offset_code)
+#define v_offset dimen_par(v_offset_code)
+
+#define count(A) eqtb[count_base+(A)].cint
+
+@ The most important output produced by a run of \TeX\ is the ``device
+independent'' (\.{DVI}) file that specifies where characters and rules
+are to appear on printed pages. The form of these files was designed by
+David R. Fuchs in 1979. Almost any reasonable typesetting device can be
+@^Fuchs, David Raymond@>
+@:DVI_files}{\.{DVI} files@>
+driven by a program that takes \.{DVI} files as input, and dozens of such
+\.{DVI}-to-whatever programs have been written. Thus, it is possible to
+print the output of \TeX\ on many different kinds of equipment, using \TeX\
+as a device-independent ``front end.''
+
+A \.{DVI} file is a stream of 8-bit bytes, which may be regarded as a
+series of commands in a machine-like language. The first byte of each command
+is the operation code, and this code is followed by zero or more bytes
+that provide parameters to the command. The parameters themselves may consist
+of several consecutive bytes; for example, the `|set_rule|' command has two
+parameters, each of which is four bytes long. Parameters are usually
+regarded as nonnegative integers; but four-byte-long parameters,
+and shorter parameters that denote distances, can be
+either positive or negative. Such parameters are given in two's complement
+notation. For example, a two-byte-long distance parameter has a value between
+$-2^{15}$ and $2^{15}-1$. As in \.{TFM} files, numbers that occupy
+more than one byte position appear in BigEndian order.
+
+A \.{DVI} file consists of a ``preamble,'' followed by a sequence of one
+or more ``pages,'' followed by a ``postamble.'' The preamble is simply a
+|pre| command, with its parameters that define the dimensions used in the
+file; this must come first. Each ``page'' consists of a |bop| command,
+followed by any number of other commands that tell where characters are to
+be placed on a physical page, followed by an |eop| command. The pages
+appear in the order that \TeX\ generated them. If we ignore |nop| commands
+and \\{fnt\_def} commands (which are allowed between any two commands in
+the file), each |eop| command is immediately followed by a |bop| command,
+or by a |post| command; in the latter case, there are no more pages in the
+file, and the remaining bytes form the postamble. Further details about
+the postamble will be explained later.
+
+Some parameters in \.{DVI} commands are ``pointers.'' These are four-byte
+quantities that give the location number of some other byte in the file;
+the first byte is number~0, then comes number~1, and so on. For example,
+one of the parameters of a |bop| command points to the previous |bop|;
+this makes it feasible to read the pages in backwards order, in case the
+results are being directed to a device that stacks its output face up.
+Suppose the preamble of a \.{DVI} file occupies bytes 0 to 99. Now if the
+first page occupies bytes 100 to 999, say, and if the second
+page occupies bytes 1000 to 1999, then the |bop| that starts in byte 1000
+points to 100 and the |bop| that starts in byte 2000 points to 1000. (The
+very first |bop|, i.e., the one starting in byte 100, has a pointer of~$-1$.)
+
+@ The \.{DVI} format is intended to be both compact and easily interpreted
+by a machine. Compactness is achieved by making most of the information
+implicit instead of explicit. When a \.{DVI}-reading program reads the
+commands for a page, it keeps track of several quantities: (a)~The current
+font |f| is an integer; this value is changed only
+by \\{fnt} and \\{fnt\_num} commands. (b)~The current position on the page
+is given by two numbers called the horizontal and vertical coordinates,
+|h| and |v|. Both coordinates are zero at the upper left corner of the page;
+moving to the right corresponds to increasing the horizontal coordinate, and
+moving down corresponds to increasing the vertical coordinate. Thus, the
+coordinates are essentially Cartesian, except that vertical directions are
+flipped; the Cartesian version of |(h,v)| would be |(h,-v)|. (c)~The
+current spacing amounts are given by four numbers |w|, |x|, |y|, and |z|,
+where |w| and~|x| are used for horizontal spacing and where |y| and~|z|
+are used for vertical spacing. (d)~There is a stack containing
+|(h,v,w,x,y,z)| values; the \.{DVI} commands |push| and |pop| are used to
+change the current level of operation. Note that the current font~|f| is
+not pushed and popped; the stack contains only information about
+positioning.
+
+The values of |h|, |v|, |w|, |x|, |y|, and |z| are signed integers having up
+to 32 bits, including the sign. Since they represent physical distances,
+there is a small unit of measurement such that increasing |h| by~1 means
+moving a certain tiny distance to the right. The actual unit of
+measurement is variable, as explained below; \TeX\ sets things up so that
+its \.{DVI} output is in sp units, i.e., scaled points, in agreement with
+all the |scaled| dimensions in \TeX's data structures.
+
+@ Here is a list of all the commands that may appear in a \.{DVI} file. Each
+command is specified by its symbolic name (e.g., |bop|), its opcode byte
+(e.g., 139), and its parameters (if any). The parameters are followed
+by a bracketed number telling how many bytes they occupy; for example,
+`|p[4]|' means that parameter |p| is four bytes long.
+
+\yskip\hang|set_char_0| 0. Typeset character number~0 from font~|f|
+such that the reference point of the character is at |(h,v)|. Then
+increase |h| by the width of that character. Note that a character may
+have zero or negative width, so one cannot be sure that |h| will advance
+after this command; but |h| usually does increase.
+
+\yskip\hang\\{set\_char\_1} through \\{set\_char\_127} (opcodes 1 to 127).
+Do the operations of |set_char_0|; but use the character whose number
+matches the opcode, instead of character~0.
+
+\yskip\hang|set1| 128 |c[1]|. Same as |set_char_0|, except that character
+number~|c| is typeset. \TeX82 uses this command for characters in the
+range |128<=c<256|.
+
+\yskip\hang|@!set2| 129 |c[2]|. Same as |set1|, except that |c|~is two
+bytes long, so it is in the range |0<=c<65536|. \TeX82 never uses this
+command, but it should come in handy for extensions of \TeX\ that deal
+with oriental languages.
+@^oriental characters@>@^Chinese characters@>@^Japanese characters@>
+
+\yskip\hang|@!set3| 130 |c[3]|. Same as |set1|, except that |c|~is three
+bytes long, so it can be as large as $2^{24}-1$. Not even the Chinese
+language has this many characters, but this command might prove useful
+in some yet unforeseen extension.
+
+\yskip\hang|@!set4| 131 |c[4]|. Same as |set1|, except that |c|~is four
+bytes long. Imagine that.
+
+\yskip\hang|set_rule| 132 |a[4]| |b[4]|. Typeset a solid black rectangle
+of height~|a| and width~|b|, with its bottom left corner at |(h,v)|. Then
+set |h:=h+b|. If either |a<=0| or |b<=0|, nothing should be typeset. Note
+that if |b<0|, the value of |h| will decrease even though nothing else happens.
+See below for details about how to typeset rules so that consistency with
+\MF\ is guaranteed.
+
+\yskip\hang|@!put1| 133 |c[1]|. Typeset character number~|c| from font~|f|
+such that the reference point of the character is at |(h,v)|. (The `put'
+commands are exactly like the `set' commands, except that they simply put out a
+character or a rule without moving the reference point afterwards.)
+
+\yskip\hang|@!put2| 134 |c[2]|. Same as |set2|, except that |h| is not changed.
+
+\yskip\hang|@!put3| 135 |c[3]|. Same as |set3|, except that |h| is not changed.
+
+\yskip\hang|@!put4| 136 |c[4]|. Same as |set4|, except that |h| is not changed.
+
+\yskip\hang|put_rule| 137 |a[4]| |b[4]|. Same as |set_rule|, except that
+|h| is not changed.
+
+\yskip\hang|nop| 138. No operation, do nothing. Any number of |nop|'s
+may occur between \.{DVI} commands, but a |nop| cannot be inserted between
+a command and its parameters or between two parameters.
+
+\yskip\hang|bop| 139 $c_0[4]$ $c_1[4]$ $\ldots$ $c_9[4]$ $p[4]$. Beginning
+of a page: Set |(h,v,w,x,y,z):=(0,0,0,0,0,0)| and set the stack empty. Set
+the current font |f| to an undefined value. The ten $c_i$ parameters hold
+the values of \.{\\count0} $\ldots$ \.{\\count9} in \TeX\ at the time
+\.{\\shipout} was invoked for this page; they can be used to identify
+pages, if a user wants to print only part of a \.{DVI} file. The parameter
+|p| points to the previous |bop| in the file; the first
+|bop| has $p=-1$.
+
+\yskip\hang|eop| 140. End of page: Print what you have read since the
+previous |bop|. At this point the stack should be empty. (The \.{DVI}-reading
+programs that drive most output devices will have kept a buffer of the
+material that appears on the page that has just ended. This material is
+largely, but not entirely, in order by |v| coordinate and (for fixed |v|) by
+|h|~coordinate; so it usually needs to be sorted into some order that is
+appropriate for the device in question.)
+
+\yskip\hang|push| 141. Push the current values of |(h,v,w,x,y,z)| onto the
+top of the stack; do not change any of these values. Note that |f| is
+not pushed.
+
+\yskip\hang|pop| 142. Pop the top six values off of the stack and assign
+them respectively to |(h,v,w,x,y,z)|. The number of pops should never
+exceed the number of pushes, since it would be highly embarrassing if the
+stack were empty at the time of a |pop| command.
+
+\yskip\hang|right1| 143 |b[1]|. Set |h:=h+b|, i.e., move right |b| units.
+The parameter is a signed number in two's complement notation, |-128<=b<128|;
+if |b<0|, the reference point moves left.
+
+\yskip\hang|right2| 144 |b[2]|. Same as |right1|, except that |b| is a
+two-byte quantity in the range |-32768<=b<32768|.
+
+\yskip\hang|right3| 145 |b[3]|. Same as |right1|, except that |b| is a
+three-byte quantity in the range |@t$-2^{23}$@><=b<@t$2^{23}$@>|.
+
+\yskip\hang|right4| 146 |b[4]|. Same as |right1|, except that |b| is a
+four-byte quantity in the range |@t$-2^{31}$@><=b<@t$2^{31}$@>|.
+
+\yskip\hang|w0| 147. Set |h:=h+w|; i.e., move right |w| units. With luck,
+this parameterless command will usually suffice, because the same kind of motion
+will occur several times in succession; the following commands explain how
+|w| gets particular values.
+
+\yskip\hang|w1| 148 |b[1]|. Set |w:=b| and |h:=h+b|. The value of |b| is a
+signed quantity in two's complement notation, |-128<=b<128|. This command
+changes the current |w|~spacing and moves right by |b|.
+
+\yskip\hang|@!w2| 149 |b[2]|. Same as |w1|, but |b| is two bytes long,
+|-32768<=b<32768|.
+
+\yskip\hang|@!w3| 150 |b[3]|. Same as |w1|, but |b| is three bytes long,
+|@t$-2^{23}$@><=b<@t$2^{23}$@>|.
+
+\yskip\hang|@!w4| 151 |b[4]|. Same as |w1|, but |b| is four bytes long,
+|@t$-2^{31}$@><=b<@t$2^{31}$@>|.
+
+\yskip\hang|x0| 152. Set |h:=h+x|; i.e., move right |x| units. The `|x|'
+commands are like the `|w|' commands except that they involve |x| instead
+of |w|.
+
+\yskip\hang|x1| 153 |b[1]|. Set |x:=b| and |h:=h+b|. The value of |b| is a
+signed quantity in two's complement notation, |-128<=b<128|. This command
+changes the current |x|~spacing and moves right by |b|.
+
+\yskip\hang|@!x2| 154 |b[2]|. Same as |x1|, but |b| is two bytes long,
+|-32768<=b<32768|.
+
+\yskip\hang|@!x3| 155 |b[3]|. Same as |x1|, but |b| is three bytes long,
+|@t$-2^{23}$@><=b<@t$2^{23}$@>|.
+
+\yskip\hang|@!x4| 156 |b[4]|. Same as |x1|, but |b| is four bytes long,
+|@t$-2^{31}$@><=b<@t$2^{31}$@>|.
+
+\yskip\hang|down1| 157 |a[1]|. Set |v:=v+a|, i.e., move down |a| units.
+The parameter is a signed number in two's complement notation, |-128<=a<128|;
+if |a<0|, the reference point moves up.
+
+\yskip\hang|@!down2| 158 |a[2]|. Same as |down1|, except that |a| is a
+two-byte quantity in the range |-32768<=a<32768|.
+
+\yskip\hang|@!down3| 159 |a[3]|. Same as |down1|, except that |a| is a
+three-byte quantity in the range |@t$-2^{23}$@><=a<@t$2^{23}$@>|.
+
+\yskip\hang|@!down4| 160 |a[4]|. Same as |down1|, except that |a| is a
+four-byte quantity in the range |@t$-2^{31}$@><=a<@t$2^{31}$@>|.
+
+\yskip\hang|y0| 161. Set |v:=v+y|; i.e., move down |y| units. With luck,
+this parameterless command will usually suffice, because the same kind of motion
+will occur several times in succession; the following commands explain how
+|y| gets particular values.
+
+\yskip\hang|y1| 162 |a[1]|. Set |y:=a| and |v:=v+a|. The value of |a| is a
+signed quantity in two's complement notation, |-128<=a<128|. This command
+changes the current |y|~spacing and moves down by |a|.
+
+\yskip\hang|@!y2| 163 |a[2]|. Same as |y1|, but |a| is two bytes long,
+|-32768<=a<32768|.
+
+\yskip\hang|@!y3| 164 |a[3]|. Same as |y1|, but |a| is three bytes long,
+|@t$-2^{23}$@><=a<@t$2^{23}$@>|.
+
+\yskip\hang|@!y4| 165 |a[4]|. Same as |y1|, but |a| is four bytes long,
+|@t$-2^{31}$@><=a<@t$2^{31}$@>|.
+
+\yskip\hang|z0| 166. Set |v:=v+z|; i.e., move down |z| units. The `|z|' commands
+are like the `|y|' commands except that they involve |z| instead of |y|.
+
+\yskip\hang|z1| 167 |a[1]|. Set |z:=a| and |v:=v+a|. The value of |a| is a
+signed quantity in two's complement notation, |-128<=a<128|. This command
+changes the current |z|~spacing and moves down by |a|.
+
+\yskip\hang|@!z2| 168 |a[2]|. Same as |z1|, but |a| is two bytes long,
+|-32768<=a<32768|.
+
+\yskip\hang|@!z3| 169 |a[3]|. Same as |z1|, but |a| is three bytes long,
+|@t$-2^{23}$@><=a<@t$2^{23}$@>|.
+
+\yskip\hang|@!z4| 170 |a[4]|. Same as |z1|, but |a| is four bytes long,
+|@t$-2^{31}$@><=a<@t$2^{31}$@>|.
+
+\yskip\hang|fnt_num_0| 171. Set |f:=0|. Font 0 must previously have been
+defined by a \\{fnt\_def} instruction, as explained below.
+
+\yskip\hang\\{fnt\_num\_1} through \\{fnt\_num\_63} (opcodes 172 to 234). Set
+|f:=1|, \dots, \hbox{|f:=63|}, respectively.
+
+\yskip\hang|fnt1| 235 |k[1]|. Set |f:=k|. \TeX82 uses this command for font
+numbers in the range |64<=k<256|.
+
+\yskip\hang|@!fnt2| 236 |k[2]|. Same as |fnt1|, except that |k|~is two
+bytes long, so it is in the range |0<=k<65536|. \TeX82 never generates this
+command, but large font numbers may prove useful for specifications of
+color or texture, or they may be used for special fonts that have fixed
+numbers in some external coding scheme.
+
+\yskip\hang|@!fnt3| 237 |k[3]|. Same as |fnt1|, except that |k|~is three
+bytes long, so it can be as large as $2^{24}-1$.
+
+\yskip\hang|@!fnt4| 238 |k[4]|. Same as |fnt1|, except that |k|~is four
+bytes long; this is for the really big font numbers (and for the negative ones).
+
+\yskip\hang|xxx1| 239 |k[1]| |x[k]|. This command is undefined in
+general; it functions as a $(k+2)$-byte |nop| unless special \.{DVI}-reading
+programs are being used. \TeX82 generates |xxx1| when a short enough
+\.{\\special} appears, setting |k| to the number of bytes being sent. It
+is recommended that |x| be a string having the form of a keyword followed
+by possible parameters relevant to that keyword.
+
+\yskip\hang|@!xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0<=k<65536|.
+
+\yskip\hang|@!xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0<=k<@t$2^{24}$@>|.
+
+\yskip\hang|xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be ridiculously
+large. \TeX82 uses |xxx4| when sending a string of length 256 or more.
+
+\yskip\hang|fnt_def1| 243 |k[1]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
+Define font |k|, where |0<=k<256|; font definitions will be explained shortly.
+
+\yskip\hang|@!fnt_def2| 244 |k[2]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
+Define font |k|, where |0<=k<65536|.
+
+\yskip\hang|@!fnt_def3| 245 |k[3]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
+Define font |k|, where |0<=k<@t$2^{24}$@>|.
+
+\yskip\hang|@!fnt_def4| 246 |k[4]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
+Define font |k|, where |@t$-2^{31}$@><=k<@t$2^{31}$@>|.
+
+\yskip\hang|pre| 247 |i[1]| |num[4]| |den[4]| |mag[4]| |k[1]| |x[k]|.
+Beginning of the preamble; this must come at the very beginning of the
+file. Parameters |i|, |num|, |den|, |mag|, |k|, and |x| are explained below.
+
+\yskip\hang|post| 248. Beginning of the postamble, see below.
+
+\yskip\hang|post_post| 249. Ending of the postamble, see below.
+
+\yskip\noindent Commands 250--255 are undefined at the present time.
+
+@c
+#define set_char_0 0 /* typeset character 0 and move right */
+#define set1 128 /* 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 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 right4 146 /* move right, 4 bytes */
+#define w0 147 /* move right by |w| */
+#define w1 148 /* move right and set |w| */
+#define x0 152 /* move right by |x| */
+#define x1 153 /* move right and set |x| */
+#define down1 157 /* 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 z0 166 /* move down by |z| */
+#define z1 167 /* move down and set |z| */
+#define fnt_num_0 171 /* set current font to 0 */
+#define fnt1 235 /* set current font */
+#define xxx1 239 /* 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 */
+
+@ The preamble contains basic information about the file as a whole. As
+stated above, there are six parameters:
+$$\hbox{|@!i[1]| |@!num[4]| |@!den[4]| |@!mag[4]| |@!k[1]| |@!x[k]|.}$$
+The |i| byte identifies \.{DVI} format; currently this byte is always set
+to~2. (The value |i=3| is currently used for an extended format that
+allows a mixture of right-to-left and left-to-right typesetting.
+Some day we will set |i=4|, when \.{DVI} format makes another
+incompatible change---perhaps in the year 2048.)
+
+The next two parameters, |num| and |den|, are positive integers that define
+the units of measurement; they are the numerator and denominator of a
+fraction by which all dimensions in the \.{DVI} file could be multiplied
+in order to get lengths in units of $10^{-7}$ meters. Since $\rm 7227{pt} =
+254{cm}$, and since \TeX\ works with scaled points where there are $2^{16}$
+sp in a point, \TeX\ sets
+$|num|/|den|=(254\cdot10^5)/(7227\cdot2^{16})=25400000/473628672$.
+@^sp@>
+
+The |mag| parameter is what \TeX\ calls \.{\\mag}, i.e., 1000 times the
+desired magnification. The actual fraction by which dimensions are
+multiplied is therefore $|mag|\cdot|num|/1000|den|$. Note that if a \TeX\
+source document does not call for any `\.{true}' dimensions, and if you
+change it only by specifying a different \.{\\mag} setting, the \.{DVI}
+file that \TeX\ creates will be completely unchanged except for the value
+of |mag| in the preamble and postamble. (Fancy \.{DVI}-reading programs allow
+users to override the |mag|~setting when a \.{DVI} file is being printed.)
+
+Finally, |k| and |x| allow the \.{DVI} writer to include a comment, which is not
+interpreted further. The length of comment |x| is |k|, where |0<=k<256|.
+
+
+@c
+#define id_byte 2 /* identifies the kind of \.{DVI} files described here */
+
+@ Font definitions for a given font number |k| contain further parameters
+$$\hbox{|c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.}$$
+The four-byte value |c| is the check sum that \TeX\ found in the \.{TFM}
+file for this font; |c| should match the check sum of the font found by
+programs that read this \.{DVI} file.
+@^check sum@>
+
+Parameter |s| contains a fixed-point scale factor that is applied to
+the character widths in font |k|; font dimensions in \.{TFM} files and
+other font files are relative to this quantity, which is called the
+``at size'' elsewhere in this documentation. The value of |s| is
+always positive and less than $2^{27}$. It is given in the same units
+as the other \.{DVI} dimensions, i.e., in sp when \TeX82 has made the
+file. Parameter |d| is similar to |s|; it is the ``design size,'' and
+(like~|s|) it is given in \.{DVI} units. Thus, font |k| is to be used
+at $|mag|\cdot s/1000d$ times its normal size.
+
+The remaining part of a font definition gives the external name of the font,
+which is an ASCII string of length |a+l|. The number |a| is the length
+of the ``area'' or directory, and |l| is the length of the font name itself;
+the standard local system font area is supposed to be used when |a=0|.
+The |n| field contains the area in its first |a| bytes.
+
+Font definitions must appear before the first use of a particular font number.
+Once font |k| is defined, it must not be defined again; however, we
+shall see below that font definitions appear in the postamble as well as
+in the pages, so in this sense each font number is defined exactly twice,
+if at all. Like |nop| commands, font definitions can
+appear before the first |bop|, or between an |eop| and a |bop|.
+
+@ Sometimes it is desirable to make horizontal or vertical rules line up
+precisely with certain features in characters of a font. It is possible to
+guarantee the correct matching between \.{DVI} output and the characters
+generated by \MF\ by adhering to the following principles: (1)~The \MF\
+characters should be positioned so that a bottom edge or left edge that is
+supposed to line up with the bottom or left edge of a rule appears at the
+reference point, i.e., in row~0 and column~0 of the \MF\ raster. This
+ensures that the position of the rule will not be rounded differently when
+the pixel size is not a perfect multiple of the units of measurement in
+the \.{DVI} file. (2)~A typeset rule of height $a>0$ and width $b>0$
+should be equivalent to a \MF-generated character having black pixels in
+precisely those raster positions whose \MF\ coordinates satisfy
+|0<=x<@t$\alpha$@>b| and |0<=y<@t$\alpha$@>a|, where $\alpha$ is the number
+of pixels per \.{DVI} unit.
+@:METAFONT}{\MF@>
+@^alignment of rules with characters@>
+@^rules aligning with characters@>
+
+@ The last page in a \.{DVI} file is followed by `|post|'; this command
+introduces the postamble, which summarizes important facts that \TeX\ has
+accumulated about the file, making it possible to print subsets of the data
+with reasonable efficiency. The postamble has the form
+$$\vbox{\halign{\hbox{#\hfil}\cr
+ |post| |p[4]| |num[4]| |den[4]| |mag[4]| |l[4]| |u[4]| |s[2]| |t[2]|\cr
+ $\langle\,$font definitions$\,\rangle$\cr
+ |post_post| |q[4]| |i[1]| 223's$[{\G}4]$\cr}}$$
+Here |p| is a pointer to the final |bop| in the file. The next three
+parameters, |num|, |den|, and |mag|, are duplicates of the quantities that
+appeared in the preamble.
+
+Parameters |l| and |u| give respectively the height-plus-depth of the tallest
+page and the width of the widest page, in the same units as other dimensions
+of the file. These numbers might be used by a \.{DVI}-reading program to
+position individual ``pages'' on large sheets of film or paper; however,
+the standard convention for output on normal size paper is to position each
+page so that the upper left-hand corner is exactly one inch from the left
+and the top. Experience has shown that it is unwise to design \.{DVI}-to-printer
+software that attempts cleverly to center the output; a fixed position of
+the upper left corner is easiest for users to understand and to work with.
+Therefore |l| and~|u| are often ignored.
+
+Parameter |s| is the maximum stack depth (i.e., the largest excess of
+|push| commands over |pop| commands) needed to process this file. Then
+comes |t|, the total number of pages (|bop| commands) present.
+
+The postamble continues with font definitions, which are any number of
+\\{fnt\_def} commands as described above, possibly interspersed with |nop|
+commands. Each font number that is used in the \.{DVI} file must be defined
+exactly twice: Once before it is first selected by a \\{fnt} command, and once
+in the postamble.
+
+@ The last part of the postamble, following the |post_post| byte that
+signifies the end of the font definitions, contains |q|, a pointer to the
+|post| command that started the postamble. An identification byte, |i|,
+comes next; this currently equals~2, as in the preamble.
+
+The |i| byte is followed by four or more bytes that are all equal to
+the decimal number 223 (i.e., '337 in octal). \TeX\ puts out four to seven of
+these trailing bytes, until the total length of the file is a multiple of
+four bytes, since this works out best on machines that pack four bytes per
+word; but any number of 223's is allowed, as long as there are at least four
+of them. In effect, 223 is a sort of signature that is added at the very end.
+@^Fuchs, David Raymond@>
+
+This curious way to finish off a \.{DVI} file makes it feasible for
+\.{DVI}-reading programs to find the postamble first, on most computers,
+even though \TeX\ wants to write the postamble last. Most operating
+systems permit random access to individual words or bytes of a file, so
+the \.{DVI} reader can start at the end and skip backwards over the 223's
+until finding the identification byte. Then it can back up four bytes, read
+|q|, and move to byte |q| of the file. This byte should, of course,
+contain the value 248 (|post|); now the postamble can be read, so the
+\.{DVI} reader can discover all the information needed for typesetting the
+pages. Note that it is also possible to skip through the \.{DVI} file at
+reasonably high speed to locate a particular page, if that proves
+desirable. This saves a lot of time, since \.{DVI} files used in production
+jobs tend to be large.
+
+Unfortunately, however, standard \PASCAL\ does not include the ability to
+@^system dependencies@>
+access a random position in a file, or even to determine the length of a file.
+Almost all systems nowadays provide the necessary capabilities, so \.{DVI}
+format has been designed to work most efficiently with modern operating systems.
+But if \.{DVI} files have to be processed under the restrictions of standard
+\PASCAL, one can simply read them from front to back, since the necessary
+header information is present in the preamble and in the font definitions.
+(The |l| and |u| and |s| and |t| parameters, which appear only in the
+postamble, are ``frills'' that are handy but not absolutely necessary.)
+
+
+@* \[32] Shipping pages out.
+After considering \TeX's eyes and stomach, we come now to the bowels.
+@^bowels@>
+
+The |ship_out| procedure is given a pointer to a box; its mission is
+to describe that box in \.{DVI} form, outputting a ``page'' to |dvi_file|.
+The \.{DVI} coordinates $(h,v)=(0,0)$ should correspond to the upper left
+corner of the box being shipped.
+
+Since boxes can be inside of boxes inside of boxes, the main work of
+|ship_out| is done by two mutually recursive routines, |hlist_out|
+and |vlist_out|, which traverse the hlists and vlists inside of horizontal
+and vertical boxes.
+
+As individual pages are being processed, we need to accumulate
+information about the entire set of pages, since such statistics must be
+reported in the postamble. The global variables |total_pages|, |max_v|,
+|max_h|, |max_push|, and |last_bop| are used to record this information.
+
+The variable |doing_leaders| is |true| while leaders are being output.
+The variable |dead_cycles| contains the number of times an output routine
+has been initiated since the last |ship_out|.
+
+A few additional global variables are also defined here for use in
+|vlist_out| and |hlist_out|. They could have been local variables, but
+that would waste stack space when boxes are deeply nested, since the
+values of these variables are not needed during recursive calls.
+@^recursion@>
+
+@c
+int total_pages = 0; /* the number of pages that have been shipped out */
+scaled max_v = 0; /* maximum height-plus-depth of pages shipped so far */
+scaled max_h = 0; /* maximum width of pages shipped so far */
+int max_push = 0; /* deepest nesting of |push| commands encountered so far */
+int last_bop = -1; /* location of previous |bop| in the \.{DVI} output */
+int dead_cycles = 0; /* recent outputs that didn't ship anything out */
+boolean doing_leaders = false; /* are we inside a leader box? */
+int c, f; /* character and font in current |char_node| */
+int oval, ocmd; /* used by |out_cmd| for generating |set|, |fnt| and |fnt_def| commands */
+pointer g; /* current glue specification */
+int lq, lr; /* quantities used in calculations for leaders */
+int cur_s = -1; /* current depth of output box nesting, initially $-1$ */
+
+@ The \.{DVI} bytes are output to a buffer instead of being written directly
+to the output file. This makes it possible to reduce the overhead of
+subroutine calls, thereby measurably speeding up the computation, since
+output of \.{DVI} bytes is part of \TeX's inner loop. And it has another
+advantage as well, since we can change instructions in the buffer in order to
+make the output more compact. For example, a `|down2|' command can be
+changed to a `|y2|', thereby making a subsequent `|y0|' command possible,
+saving two bytes.
+
+The output buffer is divided into two parts of equal size; the bytes found
+in |dvi_buf[0..half_buf-1]| constitute the first half, and those in
+|dvi_buf[half_buf..dvi_buf_size-1]| constitute the second. The global
+variable |dvi_ptr| points to the position that will receive the next
+output byte. When |dvi_ptr| reaches |dvi_limit|, which is always equal
+to one of the two values |half_buf| or |dvi_buf_size|, the half buffer that
+is about to be invaded next is sent to the output and |dvi_limit| is
+changed to its other value. Thus, there is always at least a half buffer's
+worth of information present, except at the very beginning of the job.
+
+Bytes of the \.{DVI} file are numbered sequentially starting with 0;
+the next byte to be generated will be number |dvi_offset+dvi_ptr|.
+A byte is present in the buffer only if its number is |>=dvi_gone|.
+
+Some systems may find it more efficient to make |dvi_buf| a |packed|
+array, since output of four bytes at once may be facilitated.
+@^system dependencies@>
+
+
+@ Initially the buffer is all in one piece; we will output half of it only
+after it first fills up.
+
+@c
+int dvi_buf_size = 800; /* size of the output buffer; must be a multiple of 8 */
+eight_bits *dvi_buf; /* buffer for \.{DVI} output */
+dvi_index half_buf = 0; /* half of |dvi_buf_size| */
+dvi_index dvi_limit = 0; /* end of the current half buffer */
+dvi_index dvi_ptr = 0; /* the next available buffer address */
+int dvi_offset = 0; /* |dvi_buf_size| times the number of times the output buffer has been fully emptied */
+int dvi_gone = 0; /* the number of bytes already output to |dvi_file| */
+
+@ The actual output of |dvi_buf[a..b]| to |dvi_file| is performed by calling
+|write_dvi(a,b)|. For best results, this procedure should be optimized to
+run as fast as possible on each particular system, since it is part of
+\TeX's inner loop. It is safe to assume that |a| and |b+1| will both be
+multiples of 4 when |write_dvi(a,b)| is called; therefore it is possible on
+many machines to use efficient methods to pack four bytes per word and to
+output an array of words with one system call.
+@^system dependencies@>
+@^inner loop@>
+@^defecation@>
+
+@c
+void write_dvi(dvi_index a, dvi_index b)
+{
+ dvi_index k;
+ for (k = a; k <= b; k++)
+ fputc(dvi_buf[k], static_pdf->file);
+}
+
+/* outputs half of the buffer */
+void dvi_swap(void)
+{
+ if (dvi_limit == dvi_buf_size) {
+ write_dvi(0, half_buf - 1);
+ dvi_limit = half_buf;
+ dvi_offset = dvi_offset + dvi_buf_size;
+ dvi_ptr = 0;
+ } else {
+ write_dvi(half_buf, dvi_buf_size - 1);
+ dvi_limit = dvi_buf_size;
+ }
+ dvi_gone = dvi_gone + half_buf;
+}
+
+@ The |dvi_four| procedure outputs four bytes in two's complement notation,
+without risking arithmetic overflow.
+
+@c
+void dvi_four(int x)
+{
+ if (x >= 0) {
+ dvi_out(x / 0100000000);
+ } else {
+ x = x + 010000000000;
+ x = x + 010000000000;
+ dvi_out((x / 0100000000) + 128);
+ }
+ x = x % 0100000000;
+ dvi_out(x / 0200000);
+ x = x % 0200000;
+ dvi_out(x / 0400);
+ dvi_out(x % 0400);
+}
+
+@
+A mild optimization of the output is performed by the |dvi_pop|
+routine, which issues a |pop| unless it is possible to cancel a
+`|push| |pop|' pair. The parameter to |dvi_pop| is the byte address
+following the old |push| that matches the new |pop|.
+
+
+@c
+void dvi_push(void)
+{
+ dvi_out(push);
+}
+
+void dvi_pop(int l)
+{
+ if ((l == dvi_offset + dvi_ptr) && (dvi_ptr > 0))
+ decr(dvi_ptr);
+ else
+ dvi_out(pop);
+}
+
+@ Here's a procedure that outputs a font definition. $\Omega$ allows
+more than 256 different fonts per job, so the right font definition
+command must be selected.
+
+@c
+void out_cmd(void)
+{
+ if ((oval < 0x100) && (oval >= 0)) {
+ if ((ocmd != set1) || (oval > 127)) {
+ if ((ocmd == fnt1) && (oval < 64))
+ oval += fnt_num_0;
+ else
+ dvi_out(ocmd);
+ }
+ } else {
+ if ((oval < 0x10000) && (oval >= 0)) {
+ dvi_out(ocmd + 1);
+ } else {
+ if ((oval < 0x1000000) && (oval >= 0)) {
+ dvi_out(ocmd + 2);
+ } else {
+ dvi_out(ocmd + 3);
+ if (oval >= 0) {
+ dvi_out(oval / 0x1000000);
+ } else {
+ oval += 0x40000000;
+ oval += 0x40000000;
+ dvi_out((oval / 0x1000000) + 128);
+ oval = oval % 0x1000000;
+ }
+ dvi_out(oval / 0x10000);
+ oval = oval % 0x10000;
+ }
+ dvi_out(oval / 0x10000);
+ oval = oval % 0x10000;
+ }
+ dvi_out(oval / 0x100);
+ oval = oval % 0x100;
+ }
+ dvi_out(oval);
+}
+
+void dvi_font_def(internal_font_number f)
+{
+ char *fa;
+ oval = f - 1;
+ ocmd = fnt_def1;
+ out_cmd();
+ dvi_out(font_check_0(f));
+ dvi_out(font_check_1(f));
+ dvi_out(font_check_2(f));
+ dvi_out(font_check_3(f));
+ dvi_four(font_size(f));
+ dvi_four(font_dsize(f));
+ dvi_out(0); /* |font_area(f)| is unused */
+ dvi_out(strlen(font_name(f)));
+ /* Output the font name whose internal number is |f| */
+ fa = font_name(f);
+ while (*fa != '\0') {
+ dvi_out(*fa++);
+ }
+}
+
+@ Versions of \TeX\ intended for small computers might well choose to omit
+the ideas in the next few parts of this program, since it is not really
+necessary to optimize the \.{DVI} code by making use of the |w0|, |x0|,
+|y0|, and |z0| commands. Furthermore, the algorithm that we are about to
+describe does not pretend to give an optimum reduction in the length
+of the \.{DVI} code; after all, speed is more important than compactness.
+But the method is surprisingly effective, and it takes comparatively little
+time.
+
+We can best understand the basic idea by first considering a simpler problem
+that has the same essential characteristics. Given a sequence of digits,
+say $3\,1\,4\,1\,5\,9\,2\,6\,5\,3\,5\,8\,9$, we want to assign subscripts
+$d$, $y$, or $z$ to each digit so as to maximize the number of ``$y$-hits''
+and ``$z$-hits''; a $y$-hit is an instance of two appearances of the same
+digit with the subscript $y$, where no $y$'s intervene between the two
+appearances, and a $z$-hit is defined similarly. For example, the sequence
+above could be decorated with subscripts as follows:
+$$3_z\,1_y\,4_d\,1_y\,5_y\,9_d\,2_d\,6_d\,5_y\,3_z\,5_y\,8_d\,9_d.$$
+There are three $y$-hits ($1_y\ldots1_y$ and $5_y\ldots5_y\ldots5_y$) and
+one $z$-hit ($3_z\ldots3_z$); there are no $d$-hits, since the two appearances
+of $9_d$ have $d$'s between them, but we don't count $d$-hits so it doesn't
+matter how many there are. These subscripts are analogous to the \.{DVI}
+commands called \\{down}, $y$, and $z$, and the digits are analogous to
+different amounts of vertical motion; a $y$-hit or $z$-hit corresponds to
+the opportunity to use the one-byte commands |y0| or |z0| in a \.{DVI} file.
+
+\TeX's method of assigning subscripts works like this: Append a new digit,
+say $\delta$, to the right of the sequence. Now look back through the
+sequence until one of the following things happens: (a)~You see
+$\delta_y$ or $\delta_z$, and this was the first time you encountered a
+$y$ or $z$ subscript, respectively. Then assign $y$ or $z$ to the new
+$\delta$; you have scored a hit. (b)~You see $\delta_d$, and no $y$
+subscripts have been encountered so far during this search. Then change
+the previous $\delta_d$ to $\delta_y$ (this corresponds to changing a
+command in the output buffer), and assign $y$ to the new $\delta$; it's
+another hit. (c)~You see $\delta_d$, and a $y$ subscript has been seen
+but not a $z$. Change the previous $\delta_d$ to $\delta_z$ and assign
+$z$ to the new $\delta$. (d)~You encounter both $y$ and $z$ subscripts
+before encountering a suitable $\delta$, or you scan all the way to the
+front of the sequence. Assign $d$ to the new $\delta$; this assignment may
+be changed later.
+
+The subscripts $3_z\,1_y\,4_d\ldots\,$ in the example above were, in fact,
+produced by this procedure, as the reader can verify. (Go ahead and try it.)
+
+@ In order to implement such an idea, \TeX\ maintains a stack of pointers
+to the \\{down}, $y$, and $z$ commands that have been generated for the
+current page. And there is a similar stack for \\{right}, |w|, and |x|
+commands. These stacks are called the down stack and right stack, and their
+top elements are maintained in the variables |down_ptr| and |right_ptr|.
+
+Each entry in these stacks contains four fields: The |width| field is
+the amount of motion down or to the right; the |location| field is the
+byte number of the \.{DVI} command in question (including the appropriate
+|dvi_offset|); the |vlink| field points to the next item below this one
+on the stack; and the |vinfo| field encodes the options for possible change
+in the \.{DVI} command.
+
+@c
+#define location(A) varmem[(A)+1].cint /* \.{DVI} byte number for a movement command */
+
+halfword down_ptr = null, right_ptr = null; /* heads of the down and right stacks */
+
+@ Here is a subroutine that produces a \.{DVI} command for some specified
+downward or rightward motion. It has two parameters: |w| is the amount
+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|.
+
+@c
+void movement(scaled w, eight_bits o)
+{
+ small_number mstate; /* have we seen a |y| or |z|? */
+ halfword p, q; /* current and top nodes on the stack */
+ int k; /* index into |dvi_buf|, modulo |dvi_buf_size| */
+ if (false) { /* TODO: HUH? */
+ 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) {
+ vlink(q) = down_ptr;
+ down_ptr = q;
+ } else {
+ vlink(q) = right_ptr;
+ right_ptr = q;
+ }
+ /* Look at the other stack entries until deciding what sort of \.{DVI} command
+ to generate; |goto found| if node |p| is a ``hit'' */
+ p = vlink(q);
+ mstate = none_seen;
+ while (p != null) {
+ if (width(p) == w) {
+ /* Consider a node with matching width;|goto found| if it's a hit */
+ /* We might find a valid hit in a |y| or |z| byte that is already gone
+ from the buffer. But we can't change bytes that are gone forever; ``the
+ moving finger writes, $\ldots\,\,$.'' */
+
+ switch (mstate + vinfo(p)) {
+ case none_seen + yz_OK:
+ case none_seen + y_OK:
+ case z_seen + yz_OK:
+ case z_seen + y_OK:
+ if (location(p) < dvi_gone) {
+ goto NOT_FOUND;
+ } else {
+ /* Change buffered instruction to |y| or |w| and |goto found| */
+ k = location(p) - dvi_offset;
+ if (k < 0)
+ k = k + dvi_buf_size;
+ dvi_buf[k] = (eight_bits) (dvi_buf[k] + y1 - down1);
+ vinfo(p) = y_here;
+ goto FOUND;
+ }
+ break;
+ case none_seen + z_OK:
+ case y_seen + yz_OK:
+ case y_seen + z_OK:
+ if (location(p) < dvi_gone) {
+ goto NOT_FOUND;
+ } else {
+ /* Change buffered instruction to |z| or |x| and |goto found| */
+ k = location(p) - dvi_offset;
+ if (k < 0)
+ k = k + dvi_buf_size;
+ dvi_buf[k] = (eight_bits) (dvi_buf[k] + z1 - down1);
+ vinfo(p) = z_here;
+ goto FOUND;
+ }
+ break;
+ case none_seen + y_here:
+ case none_seen + z_here:
+ case y_seen + z_here:
+ case z_seen + y_here:
+ goto FOUND;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (mstate + vinfo(p)) {
+ case none_seen + y_here:
+ mstate = y_seen;
+ break;
+ case none_seen + z_here:
+ mstate = z_seen;
+ break;
+ case y_seen + z_here:
+ case z_seen + y_here:
+ goto NOT_FOUND;
+ break;
+ default:
+ break;
+ }
+ }
+ p = vlink(p);
+ }
+ }
+ NOT_FOUND:
+ /* Generate a |down| or |right| command for |w| and |return| */
+ if (abs(w) >= 040000000) {
+ dvi_out(o + 3); /* |down4| or |right4| */
+ dvi_four(w);
+ return;
+ }
+ if (abs(w) >= 0100000) {
+ dvi_out(o + 2); /* |down3| or |right3| */
+ if (w < 0)
+ w = w + 0100000000;
+ dvi_out(w / 0200000);
+ w = w % 0200000;
+ goto TWO;
+ }
+ if (abs(w) >= 0200) {
+ dvi_out(o + 1); /* |down2| or |right2| */
+ if (w < 0)
+ w = w + 0200000;
+ goto TWO;
+ }
+ dvi_out(o); /* |down1| or |right1| */
+ if (w < 0)
+ w = w + 0400;
+ goto ONE;
+ TWO:
+ dvi_out(w / 0400);
+ ONE:
+ dvi_out(w % 0400);
+ return;
+ FOUND:
+ /* Generate a |y0| or |z0| command in order to reuse a previous appearance of~|w| */
+ /* The program below removes movement nodes that are introduced after a |push|,
+ before it outputs the corresponding |pop|. */
+ /*
+ When the |movement| procedure gets to the label |found|, the value of
+ |vinfo(p)| will be either |y_here| or |z_here|. If it is, say, |y_here|,
+ the procedure generates a |y0| command (or a |w0| command), and marks
+ all |vinfo| fields between |q| and |p| so that |y| is not OK in that range.
+ */
+ vinfo(q) = vinfo(p);
+ if (vinfo(q) == y_here) {
+ dvi_out(o + y0 - down1); /* |y0| or |w0| */
+ while (vlink(q) != p) {
+ q = vlink(q);
+ switch (vinfo(q)) {
+ case yz_OK:
+ vinfo(q) = z_OK;
+ break;
+ case y_OK:
+ vinfo(q) = d_fixed;
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ dvi_out(o + z0 - down1); /* |z0| or |x0| */
+ while (vlink(q) != p) {
+ q = vlink(q);
+ switch (vinfo(q)) {
+ case yz_OK:
+ vinfo(q) = y_OK;
+ break;
+ case z_OK:
+ vinfo(q) = d_fixed;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+@ In case you are wondering when all the movement nodes are removed from
+\TeX's memory, the answer is that they are recycled just before
+|hlist_out| and |vlist_out| finish outputting a box. This restores the
+down and right stacks to the state they were in before the box was output,
+except that some |vinfo|'s may have become more restrictive.
+
+
+@c
+/* delete movement nodes with |location>=l| */
+void prune_movements(int l)
+{
+ pointer p; /* node being deleted */
+ while (down_ptr != null) {
+ if (location(down_ptr) < l)
+ break;
+ p = down_ptr;
+ down_ptr = vlink(p);
+ flush_node(p);
+ }
+ while (right_ptr != null) {
+ if (location(right_ptr) < l)
+ return;
+ p = right_ptr;
+ right_ptr = vlink(p);
+ flush_node(p);
+ }
+}
+
+scaledpos dvi; /* a \.{DVI} position in page coordinates, in sync with DVI file */
+
+scaledpos cur_page_size;
+
+@ 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)|.
+
+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)|.
+@^recursion@>
+
+@ 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.
+
+@c
+void dvi_place_rule(PDF pdf, halfword q, scaledpos size)
+{
+ (void) q;
+ synch_dvi_with_pos(pdf->posstruct->pos);
+ if (textdir_is_L(pdf->posstruct->dir)) {
+ dvi_out(set_rule); /* movement optimization for |dir_*L*| */
+ dvi.h += size.h;
+ } else
+ dvi_out(put_rule);
+ dvi_four(size.v);
+ dvi_four(size.h);
+}
+
+void dvi_place_glyph(PDF pdf, internal_font_number f, int c)
+{
+ scaled_whd ci;
+ synch_dvi_with_pos(pdf->posstruct->pos);
+ if (f != pdf->f_cur) {
+ /* Change font |f_cur| to |f| */
+ if (!font_used(f)) {
+ dvi_font_def(f);
+ set_font_used(f, true);
+ }
+ oval = f - 1;
+ ocmd = fnt1;
+ out_cmd();
+ pdf->f_cur = f;
+ }
+ if (textdir_is_L(pdf->posstruct->dir)) {
+ ci = get_charinfo_whd(f, c);
+ dvi_set(c, ci.wd); /* movement optimization for |dir_*L*| */
+ } else
+ dvi_put(c);
+}
+
+void dvi_special(PDF pdf, halfword p)
+{
+ int old_setting; /* holds print |selector| */
+ unsigned k; /* index into |cur_string| */
+ synch_dvi_with_pos(pdf->posstruct->pos);
+ old_setting = selector;
+ selector = new_string;
+ show_token_list(token_link(write_tokens(p)), null, -1);
+ selector = old_setting;
+ if (cur_length < 256) {
+ dvi_out(xxx1);
+ dvi_out(cur_length);
+ } else {
+ dvi_out(xxx4);
+ dvi_four((int) cur_length);
+ }
+ for (k = 0; k < cur_length; k++)
+ dvi_out(cur_string[k]);
+ cur_length = 0; /* erase the string */
+}
+
+@ 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
+@^Knuth, Donald Ervin@>
+on the stack, namely the one that contained |end_write_token|. (We
+insert this artificial `\.{\\endwrite}' to prevent runaways, as explained
+above.) If it were not removed, and if there were numerous writes on a
+single page, the stack would overflow.
+
+@c
+/* TODO: keep track of this value */
+#define end_write_token cs_token_flag+end_write
+
+void expand_macros_in_tokenlist(halfword p)
+{
+ int old_mode; /* saved |mode| */
+ pointer q, r; /* temporary variables for list manipulation */
+ q = get_avail();
+ token_info(q) = right_brace_token + '}';
+ r = get_avail();
+ token_link(q) = r;
+ token_info(r) = end_write_token;
+ begin_token_list(q, inserted);
+ begin_token_list(write_tokens(p), write_text);
+ q = get_avail();
+ token_info(q) = left_brace_token + '{';
+ begin_token_list(q, inserted);
+ /* now we're ready to scan
+ `\.\{$\langle\,$token list$\,\rangle$\.{\} \\endwrite}' */
+ old_mode = mode;
+ mode = 0;
+ /* disable \.{\\prevdepth}, \.{\\spacefactor}, \.{\\lastskip}, \.{\\prevgraf} */
+ cur_cs = write_loc;
+ q = scan_toks(false, true); /* expand macros, etc. */
+ get_token();
+ if (cur_tok != end_write_token) {
+ /* Recover from an unbalanced write command */
+ const char *hlp[] = {
+ "On this page there's a \\write with fewer real {'s than }'s.",
+ "I can't handle that very well; good luck.", NULL
+ };
+ tex_error("Unbalanced write command", hlp);
+ do {
+ get_token();
+ } while (cur_tok != end_write_token);
+ }
+ mode = old_mode;
+ end_token_list(); /* conserve stack space */
+}
+
+void write_out(halfword p)
+{
+ int old_setting; /* holds print |selector| */
+ int j; /* write stream number */
+ boolean clobbered; /* system string is ok? */
+ int ret; /* return value from |runsystem| */
+ char *s, *ss; /* line to be written, as a C string */
+ int callback_id;
+ int lua_retval;
+ expand_macros_in_tokenlist(p);
+ old_setting = selector;
+ j = write_stream(p);
+ if (j == 18) {
+ selector = new_string;
+ } else if (write_open[j]) {
+ selector = j;
+ } else { /* write to the terminal if file isn't open */
+ if ((j == 17) && (selector == term_and_log))
+ selector = log_only;
+ tprint_nl("");
+ }
+ s = tokenlist_to_cstring(def_ref, false, NULL);
+ if (selector < no_print) { /* selector is a file */
+ /* fix up the output buffer using callbacks */
+ callback_id = callback_defined(process_output_buffer_callback);
+ if (callback_id > 0) {
+ lua_retval = run_callback(callback_id, "S->S", s, &ss);
+ if ((lua_retval == true) && (ss != NULL))
+ s = ss;
+ }
+ }
+ tprint(s);
+ print_ln();
+ flush_list(def_ref);
+ if (j == 18) {
+ cur_string[cur_length] = '\0'; /* Convert newline to null. */
+ if (tracing_online <= 0)
+ selector = log_only; /* Show what we're doing in the log file. */
+ else
+ selector = term_and_log; /* Show what we're doing. */
+ /* If the log file isn't open yet, we can only send output to the terminal.
+ Calling |open_log_file| from here seems to result in bad data in the log.
+ */
+ if (!log_opened)
+ selector = term_only;
+ tprint_nl("runsystem(");
+ tprint((char *) cur_string);
+ tprint(")...");
+ if (shellenabledp) {
+ clobbered = false;
+ if (strlen((char *) cur_string) != cur_length)
+ clobbered = true;
+ /* minimal checking: NUL not allowed in argument string of |system|() */
+ if (clobbered) {
+ tprint("clobbered");
+ } else {
+ /* We have the command. See if we're allowed to execute it,
+ and report in the log. We don't check the actual exit status of
+ the command, or do anything with the output. */
+ ret = runsystem((char *) cur_string);
+ if (ret == -1)
+ tprint("quotation error in system command");
+ else if (ret == 0)
+ tprint("disabled (restricted)");
+ else if (ret == 1)
+ tprint("executed");
+ else if (ret == 2)
+ tprint("executed safely (allowed)");
+ }
+ } else {
+ tprint("disabled"); /* |shellenabledp| false */
+ }
+ print_char('.');
+ tprint_nl("");
+ print_ln();
+ cur_length = 0; /* erase the string */
+ }
+ selector = old_setting;
+}
+
+@ 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|.
+
+@c
+void ensure_dvi_header_written(PDF pdf)
+{
+ unsigned l;
+ unsigned s; /* index into |str_pool| */
+ int old_setting; /* saved |selector| setting */
+ assert(pdf->o_mode == OMODE_DVI);
+ assert(pdf->o_state == ST_FILE_OPEN);
+
+ if (half_buf == 0) {
+ half_buf = dvi_buf_size / 2;
+ dvi_limit = dvi_buf_size;
+ }
+
+ dvi_out(pre);
+ dvi_out(id_byte); /* output the preamble */
+ dvi_four(25400000);
+ dvi_four(473628672); /* conversion ratio for sp */
+ prepare_mag();
+ dvi_four(mag); /* magnification factor is frozen */
+ if (output_comment) {
+ l = (unsigned) strlen(output_comment);
+ dvi_out(l);
+ for (s = 0; s <= l - 1; s++)
+ dvi_out(output_comment[s]);
+ } else { /* the default code is unchanged */
+ old_setting = selector;
+ selector = new_string;
+ tprint(" LuaTeX output ");
+ print_int(int_par(year_code));
+ print_char('.');
+ print_two(int_par(month_code));
+ print_char('.');
+ print_two(int_par(day_code));
+ print_char(':');
+ print_two(int_par(time_code) / 60);
+ print_two(int_par(time_code) % 60);
+ selector = old_setting;
+ dvi_out(cur_length);
+ for (s = 0; s < cur_length; s++)
+ dvi_out(cur_string[s]);
+ cur_length = 0;
+ }
+}
+
+void dvi_begin_page(PDF pdf)
+{
+ int k;
+ int page_loc; /* location of the current |bop| */
+ ensure_output_state(pdf, ST_HEADER_WRITTEN);
+ /* Initialize variables as |ship_out| begins */
+ page_loc = dvi_offset + dvi_ptr;
+ dvi_out(bop);
+ for (k = 0; k <= 9; k++)
+ dvi_four(count(k));
+ dvi_four(last_bop);
+ last_bop = page_loc;
+}
+
+void dvi_end_page(PDF pdf)
+{
+ (void) pdf;
+ dvi_out(eop);
+
+#ifdef IPC
+ if (ipcon > 0) {
+ if (dvi_limit == half_buf) {
+ write_dvi(half_buf, dvi_buf_size - 1);
+ fflush(static_pdf->file);
+ dvi_gone = dvi_gone + half_buf;
+ }
+ if (dvi_ptr > 0) {
+ write_dvi(0, dvi_ptr - 1);
+ fflush(static_pdf->file);
+ dvi_offset = dvi_offset + dvi_ptr;
+ dvi_gone = dvi_gone + dvi_ptr;
+ }
+ dvi_ptr = 0;
+ dvi_limit = dvi_buf_size;
+ ipcpage(dvi_gone);
+ }
+#endif /* IPC */
+}
+
+@ 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. And if
+|max_push>=65536|, the user deserves whatever chaos might ensue.
+
+@c
+void finish_dvi_file(PDF pdf, int version, int revision)
+{
+ int k;
+ boolean res;
+ int callback_id = callback_defined(stop_run_callback);
+ (void) version;
+ (void) revision;
+ while (cur_s > -1) {
+ if (cur_s > 0) {
+ dvi_out(pop);
+ } else {
+ dvi_out(eop);
+ incr(total_pages);
+ }
+ decr(cur_s);
+ }
+ if (total_pages == 0) {
+ if (callback_id == 0)
+ tprint_nl("No pages of output.");
+ else if (callback_id > 0)
+ res = run_callback(callback_id, "->");
+ } else {
+ dvi_out(post); /* beginning of the postamble */
+ dvi_four(last_bop);
+ last_bop = dvi_offset + dvi_ptr - 5; /* |post| location */
+ dvi_four(25400000);
+ dvi_four(473628672); /* conversion ratio for sp */
+ prepare_mag();
+ dvi_four(mag); /* magnification factor */
+ dvi_four(max_v);
+ dvi_four(max_h);
+ dvi_out(max_push / 256);
+ dvi_out(max_push % 256);
+ dvi_out((total_pages / 256) % 256);
+ dvi_out(total_pages % 256);
+ /* Output the font definitions for all fonts that were used */
+ k = max_font_id();
+ while (k > 0) {
+ if (font_used(k)) {
+ dvi_font_def(k);
+ }
+ decr(k);
+ }
+
+ dvi_out(post_post);
+ dvi_four(last_bop);
+ dvi_out(id_byte);
+#ifndef IPC
+ k = 4 + ((dvi_buf_size - dvi_ptr) % 4); /* the number of 223's */
+#else
+ k = 7 - ((3 + dvi_offset + dvi_ptr) % 4); /* the number of 223's */
+#endif
+
+ while (k > 0) {
+ dvi_out(223);
+ decr(k);
+ }
+ /* Empty the last bytes out of |dvi_buf| */
+ /* Here is how we clean out the buffer when \TeX\ is all through; |dvi_ptr|
+ will be a multiple of~4. */
+ if (dvi_limit == half_buf)
+ write_dvi(half_buf, dvi_buf_size - 1);
+ if (dvi_ptr > 0)
+ write_dvi(0, dvi_ptr - 1);
+
+ if (callback_id == 0) {
+ tprint_nl("Output written on ");
+ tprint(pdf->file_name);
+ tprint(" (");
+ print_int(total_pages);
+ tprint(" page");
+ if (total_pages != 1)
+ print_char('s');
+ tprint(", ");
+ print_int(dvi_offset + dvi_ptr);
+ tprint(" bytes).");
+ } else if (callback_id > 0) {
+ res = run_callback(callback_id, "->");
+ }
+ close_file(pdf->file);
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/font/dofont.c b/Build/source/texk/web2c/luatexdir/font/dofont.c
deleted file mode 100644
index 4e026f339a3..00000000000
--- a/Build/source/texk/web2c/luatexdir/font/dofont.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* dofont.c
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "ptexlib.h"
-
-#include "luatex-api.h"
-
-static const char _svn_version[] =
- "$Id: dofont.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/dofont.c $";
-
-#define TIMERS 0
-
-#if TIMERS
-# include <sys/time.h>
-#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));
- const 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, const char *cnom, scaled s, integer natural_dir)
-{
-
- 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) {
- cnam = xstrdup(cnom);
-#if TIMERS
- gettimeofday(&tva, NULL);
-#endif
- 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);
-#endif
- 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);
-#endif
- 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);
-#endif
- /* 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 if (callback_id == 0) {
- res = read_tfm_info(f, cnom, s);
- if (res) {
- set_hyphen_char(f, get_default_hyphen_char());
- set_skew_char(f, get_default_skew_char());
- }
- }
- if (res) {
- 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;
- }
-
-}
-
-int read_font_info(pointer u, str_number 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, s, natural_dir))) {
- free(cnom);
- return f;
- } else {
- const 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<same font id>=<substitute font name>'.",
- 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(const char *nom, scaled s)
-{
- integer f;
- f = new_font();
- if ((f = do_define_font(f, nom, s, -1))) {
- return f;
- } else {
- return 0;
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/font/dofont.w b/Build/source/texk/web2c/luatexdir/font/dofont.w
new file mode 100644
index 00000000000..38278e8d1cb
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/font/dofont.w
@@ -0,0 +1,147 @@
+% dofont.w
+%
+% Copyright 2006-2010 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.
+%
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+#include "lua/luatex-api.h"
+
+static const char _svn_version[] =
+ "$Id: dofont.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/dofont.w $";
+
+@ a bit more interfacing is needed for proper error reporting
+
+@c
+static char *font_error_message(pointer u, char *nom, scaled s)
+{
+ char *str = xmalloc(256);
+ char *c = makecstring(cs_text(u));
+ const 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);
+ }
+ free(c);
+ return str;
+}
+
+static int do_define_font(int f, const char *cnom, scaled s, int natural_dir)
+{
+
+ boolean res; /* was the callback successful? */
+ int callback_id;
+ char *cnam;
+ int r;
+ res = 0;
+
+ callback_id = callback_defined(define_font_callback);
+ if (callback_id > 0) {
+ cnam = xstrdup(cnom);
+ callback_id = run_and_save_callback(callback_id, "Sdd->", cnam, s, f);
+ 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)) {
+ res = font_from_lua(Luas, f);
+ destroy_saved_callback(callback_id);
+ /* |lua_pop(Luas, 1);| *//* done by |font_from_lua| */
+ } else if (lua_isnumber(Luas, -1)) {
+ lua_number2int(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 if (callback_id == 0) {
+ res = read_tfm_info(f, cnom, s);
+ if (res) {
+ set_hyphen_char(f, int_par(default_hyphen_char_code));
+ set_skew_char(f, int_par(default_skew_char_code));
+ }
+ }
+ if (font_name(f) && strlen(font_name(f)) > 255) {
+ /* the font name has to fit in the dvi file's single byte storage */
+ /* no need to test area, as we are never using it */
+ res = 0;
+ }
+ if (res) {
+ 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;
+ }
+
+}
+
+int read_font_info(pointer u, char *cnom, scaled s, int natural_dir)
+{
+ int f;
+ char *msg;
+
+ f = new_font();
+ if ((f = do_define_font(f, cnom, s, natural_dir))) {
+ return f;
+ } else {
+ const 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<same font id>=<substitute font name>'.",
+ NULL
+ };
+ if (int_par(suppress_fontnotfound_error_code) == 0) {
+ msg = font_error_message(u, cnom, s);
+ tex_error(msg, help);
+ free(msg);
+ }
+ 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
+
+@c
+int find_font_id(const char *nom, scaled s)
+{
+ int f;
+ f = new_font();
+ if ((f = do_define_font(f, nom, 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.w
index 11bafd8b1ec..bde66530fb4 100644
--- a/Build/source/texk/web2c/luatexdir/font/luafont.c
+++ b/Build/source/texk/web2c/luatexdir/font/luafont.w
@@ -1,36 +1,38 @@
-/* luafont.c
-
- Copyright 2006-2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "luatex-api.h"
-#include <ptexlib.h>
-
-#include "nodes.h"
-
+% luafont.w
+%
+% Copyright 2006-2010 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.
+%
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
static const char _svn_version[] =
- "$Id: luafont.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/luafont.c $";
+ "$Id: luafont.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/luafont.w $";
+
+#include "ptexlib.h"
+#include "lua/luatex-api.h"
#define noVERBOSE
const char *font_type_strings[] = { "unknown", "virtual", "real", NULL };
const char *font_format_strings[] =
{ "unknown", "type1", "type3", "truetype", "opentype", NULL };
-const char *font_embedding_strings[] = { "unknown", "no", "subset", "full", NULL };
+const char *font_embedding_strings[] =
+ { "unknown", "no", "subset", "full", NULL };
+
const char *ligature_type_strings[] =
{ "=:", "=:|", "|=:", "|=:|", "", "=:|>", "|=:>", "|=:|>", "", "", "",
"|=:|>>", NULL
@@ -96,6 +98,8 @@ const char *MATH_param_names[] = {
"RadicalDegreeBottomRaisePercent",
"MinConnectorOverlap",
"SubscriptShiftDownWithSuperscript",
+ "FractionDelimiterSize",
+ "FractionDelimiterDisplayStyleSize",
NULL,
};
@@ -107,7 +111,7 @@ static void dump_intfield(lua_State * L, const char *n, int c)
}
-static void dump_math_kerns(lua_State * L, charinfo * co, int l, int id)
+void dump_math_kerns(lua_State * L, charinfo * co, int l, int id)
{
int i;
for (i = 0; i < l; i++) {
@@ -132,7 +136,7 @@ static void dump_math_kerns(lua_State * L, charinfo * co, int l, int id)
}
-static void font_char_to_lua(lua_State * L, internalfontnumber f, charinfo * co)
+void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * co)
{
int i, j;
liginfo *l;
@@ -359,7 +363,7 @@ static void write_lua_parameters(lua_State * L, int f)
lua_setfield(L, -2, "parameters");
}
-
+@ @c
static void write_lua_math_parameters(lua_State * L, int f)
{
int k;
@@ -382,8 +386,8 @@ int font_to_lua(lua_State * L, int f)
int k;
charinfo *co;
if (font_cache_id(f) > 0) {
- /* fetch the table from the registry if it was
- saved there by font_from_lua() */
+ /* 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);
@@ -405,6 +409,10 @@ int font_to_lua(lua_State * L, int f)
lua_pushstring(L, font_fullname(f));
lua_setfield(L, -2, "fullname");
}
+ if (font_psname(f) != NULL) {
+ lua_pushstring(L, font_psname(f));
+ lua_setfield(L, -2, "psname");
+ }
if (font_encodingname(f) != NULL) {
lua_pushstring(L, font_encodingname(f));
lua_setfield(L, -2, "encodingname");
@@ -421,6 +429,8 @@ int font_to_lua(lua_State * L, int f)
lua_pushstring(L, font_embedding_strings[font_embedding(f)]);
lua_setfield(L, -2, "embedding");
+ lua_pushnumber(L, font_units_per_em(f));
+ lua_setfield(L, -2, "units_per_em");
lua_pushnumber(L, font_size(f));
lua_setfield(L, -2, "size");
lua_pushnumber(L, font_dsize(f));
@@ -440,11 +450,7 @@ int font_to_lua(lua_State * L, int f)
/* 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 0
if (pdf_font_num(f) != 0) {
lua_pushnumber(L,pdf_font_num(f));
lua_setfield(L,-2,"pdf_num");
@@ -457,30 +463,32 @@ int font_to_lua(lua_State * L, int f)
lua_pushnumber(L,pdf_font_elink(f));
lua_setfield(L,-2,"pdf_elink");
}
- */
+#endif
/* the next one is read only */
- if (pdf_font_expand_ratio(f) != 0) {
- lua_pushnumber(L, pdf_font_expand_ratio(f));
+ if (font_expand_ratio(f) != 0) {
+ lua_pushnumber(L, font_expand_ratio(f));
lua_setfield(L, -2, "expand_ratio");
}
- if (pdf_font_shrink(f) != 0) {
- lua_pushnumber(L, pdf_font_shrink(f));
+ if (font_shrink(f) != 0) {
+ lua_pushnumber(L, font_shrink(f));
lua_setfield(L, -2, "shrink");
}
- if (pdf_font_stretch(f) != 0) {
- lua_pushnumber(L, pdf_font_stretch(f));
+ if (font_stretch(f) != 0) {
+ lua_pushnumber(L, font_stretch(f));
lua_setfield(L, -2, "stretch");
}
- if (pdf_font_step(f) != 0) {
- lua_pushnumber(L, pdf_font_step(f));
+ if (font_step(f) != 0) {
+ lua_pushnumber(L, font_step(f));
lua_setfield(L, -2, "step");
}
- if (pdf_font_auto_expand(f) != 0) {
- lua_pushboolean(L, pdf_font_auto_expand(f));
+ if (font_auto_expand(f) != 0) {
+ lua_pushboolean(L, font_auto_expand(f));
lua_setfield(L, -2, "auto_expand");
}
if (pdf_font_attr(f) != 0) {
- lua_pushstring(L, makecstring(pdf_font_attr(f)));
+ char *s = makecstring(pdf_font_attr(f));
+ lua_pushstring(L, s);
+ free(s);
lua_setfield(L, -2, "attributes");
}
@@ -503,7 +511,7 @@ int font_to_lua(lua_State * L, int f)
}
for (k = font_bc(f); k <= font_ec(f); k++) {
- if (char_exists(f, k)) {
+ if (quick_char_exists(f, k)) {
lua_pushnumber(L, k);
co = get_charinfo(f, k);
font_char_to_lua(L, f, co);
@@ -513,9 +521,9 @@ int font_to_lua(lua_State * L, int f)
lua_setfield(L, -2, "characters");
if (font_cache_id(f) == 0) { /* renew */
- integer r;
+ int r;
lua_pushvalue(L, -1);
- r = luaL_ref(Luas, LUA_REGISTRYINDEX); /* pops the table */
+ r = luaL_ref(L, LUA_REGISTRYINDEX); /* pops the table */
set_font_cache_id(f, r);
}
return 1;
@@ -541,9 +549,10 @@ static int count_hash_items(lua_State * L, int name_index)
return n;
}
+@ @c
#define streq(a,b) (strcmp(a,b)==0)
-#define append_packet(k) { cpackets[np++] = k; }
+#define append_packet(k) { cpackets[np++] = (eight_bits)(k); }
#define do_store_four(l) { \
append_packet((l&0xFF000000)>>24); \
@@ -581,7 +590,8 @@ static int n_numeric_field(lua_State * L, int name_index, int dflt)
}
-static int enum_field(lua_State * L, const char *name, int dflt, const char **values)
+static int enum_field(lua_State * L, const char *name, int dflt,
+ const char **values)
{
int k;
const char *s;
@@ -589,7 +599,7 @@ static int enum_field(lua_State * L, const char *name, int dflt, const char **va
lua_pushstring(L, name);
lua_rawget(L, -2);
if (lua_isnumber(L, -1)) {
- i = lua_tonumber(L, -1);
+ lua_number2int(i, lua_tonumber(L, -1));
} else if (lua_isstring(L, -1)) {
s = lua_tostring(L, -1);
k = 0;
@@ -646,7 +656,7 @@ static char *string_field(lua_State * L, const char *name, const char *dflt)
return i;
}
-static char *n_string_field(lua_State * L, int name_index, const char *dflt)
+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 */
@@ -662,10 +672,10 @@ static char *n_string_field(lua_State * L, int name_index, const char *dflt)
return i;
}
-#define init_luaS_index(a) do { \
- lua_pushliteral(L,#a); \
- luaS_##a##_ptr = 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 = lua_tostring(L,-1); \
+ luaS_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \
} while (0)
#define make_luaS_index(a) \
@@ -729,7 +739,7 @@ make_luaS_index(vert_variants);
make_luaS_index(mathkern);
make_luaS_index(commands);
-static void init_font_string_pointers(lua_State * L)
+void init_font_string_pointers(lua_State * L)
{
init_luaS_index(width);
init_luaS_index(height);
@@ -827,7 +837,7 @@ static int count_char_packet_bytes(lua_State * L)
(void) lua_tolstring(L, -1, &len);
lua_pop(L, 1);
if (len > 0) {
- l = l + 5 + len;
+ l = (int) (l + 5 + (int) len);
}
} else if (luaS_ptr_eq(s, image)) {
l += 5;
@@ -846,7 +856,7 @@ static int count_char_packet_bytes(lua_State * L)
-static scaled sp_to_dvi(halfword sp, halfword atsize)
+scaled sp_to_dvi(halfword sp, halfword atsize)
{
double result, mult;
mult = (double) (atsize / 65536.0);
@@ -854,15 +864,15 @@ static scaled sp_to_dvi(halfword sp, halfword atsize)
return floor(result / mult);
}
-
+@ @c
static void
-read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
+read_char_packets(lua_State * L, int *l_fonts, charinfo * co, int atsize)
{
int i, n, m;
size_t l;
int cmd;
const char *s;
- real_eight_bits *cpackets;
+ eight_bits *cpackets;
int ff = 0;
int np = 0;
int max_f = 0;
@@ -874,7 +884,7 @@ read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
while (l_fonts[(max_f + 1)] != 0)
max_f++;
- cpackets = xmalloc(pc + 1);
+ cpackets = xmalloc((unsigned) (pc + 1));
for (i = 1; i <= (int) lua_objlen(L, -1); i++) {
lua_rawgeti(L, -1, i);
if (lua_istable(L, -1)) {
@@ -895,10 +905,10 @@ read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
} else if (luaS_ptr_eq(s, slot)) {
cmd = packet_nop_code;
lua_rawgeti(L, -2, 2);
- n = lua_tointeger(L, -1);
+ n = (int) lua_tointeger(L, -1);
ff = (n > max_f ? l_fonts[1] : l_fonts[n]);
lua_rawgeti(L, -3, 3);
- n = lua_tointeger(L, -1);
+ n = (int) lua_tointeger(L, -1);
lua_pop(L, 2);
append_packet(packet_font_code);
do_store_four(ff);
@@ -932,7 +942,7 @@ read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
case packet_font_code:
append_packet(cmd);
lua_rawgeti(L, -2, 2);
- n = lua_tointeger(L, -1);
+ n = (int) lua_tointeger(L, -1);
ff = (n > max_f ? l_fonts[1] : l_fonts[n]);
do_store_four(ff);
lua_pop(L, 1);
@@ -947,7 +957,7 @@ read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
case packet_char_code:
append_packet(cmd);
lua_rawgeti(L, -2, 2);
- n = lua_tointeger(L, -1);
+ n = (int) lua_tointeger(L, -1);
do_store_four(n);
lua_pop(L, 1);
break;
@@ -955,17 +965,17 @@ read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
case packet_down_code:
append_packet(cmd);
lua_rawgeti(L, -2, 2);
- n = lua_tointeger(L, -1);
+ n = (int) 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);
+ n = (int) lua_tointeger(L, -1);
do_store_four(sp_to_dvi(n, atsize));
lua_rawgeti(L, -3, 3);
- n = lua_tointeger(L, -1);
+ n = (int) lua_tointeger(L, -1);
do_store_four(sp_to_dvi(n, atsize));
lua_pop(L, 2);
break;
@@ -1021,6 +1031,7 @@ read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
}
+@ @c
static void read_lua_cidinfo(lua_State * L, int f)
{
int i;
@@ -1040,6 +1051,7 @@ static void read_lua_cidinfo(lua_State * L, int f)
}
+@ @c
static void read_lua_parameters(lua_State * L, int f)
{
int i, n;
@@ -1051,7 +1063,7 @@ static void read_lua_parameters(lua_State * L, int f)
lua_pushnil(L); /* first key */
while (lua_next(L, -2) != 0) {
if (lua_isnumber(L, -2)) {
- i = lua_tonumber(L, -2);
+ lua_number2int(i, lua_tonumber(L, -2));
if (i > n)
n = i;
}
@@ -1071,7 +1083,7 @@ static void read_lua_parameters(lua_State * L, int f)
lua_pushnil(L); /* first key */
while (lua_next(L, -2) != 0) {
if (lua_isnumber(L, -2)) {
- i = lua_tointeger(L, -2);
+ i = (int) lua_tointeger(L, -2);
if (i >= 8) {
n = (lua_isnumber(L, -1) ? lua_roundnumber(L, -1) : 0);
set_font_param(f, i, n);
@@ -1102,6 +1114,7 @@ static void read_lua_parameters(lua_State * L, int f)
}
+@ @c
static void read_lua_math_parameters(lua_State * L, int f)
{
int i = 0, n = 0;
@@ -1110,11 +1123,11 @@ static void read_lua_math_parameters(lua_State * L, int f)
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
if (lua_isnumber(L, -2)) {
- i = lua_tonumber(L, -2);
+ lua_number2int(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);
+ lua_number2int(n, lua_tonumber(L, -1));
if (i != 0) {
set_font_math_param(f, i, n);
}
@@ -1124,27 +1137,30 @@ static void read_lua_math_parameters(lua_State * L, int f)
lua_pop(L, 1);
}
+@ @c
#define MIN_INF -0x7FFFFFFF
static void store_math_kerns(lua_State * L, charinfo * co, int id)
{
- int l, k;
+ int l, k, i;
scaled ht, krn;
- if (lua_istable(L, -1) && ((k = lua_objlen(L, -1)) > 0)) {
+ if (lua_istable(L, -1) && ((k = (int) lua_objlen(L, -1)) > 0)) {
for (l = 0; l < k; l++) {
lua_rawgeti(L, -1, (l + 1));
if (lua_istable(L, -1)) {
lua_getfield(L, -1, "height");
if (lua_isnumber(L, -1)) {
- ht = (scaled) lua_tonumber(L, -1);
+ lua_number2int(i, lua_tonumber(L, -1));
+ ht = (scaled) i;
} else {
ht = MIN_INF;
}
lua_pop(L, 1);
lua_getfield(L, -1, "kern");
if (lua_isnumber(L, -1)) {
- krn = (scaled) lua_tonumber(L, -1);
+ lua_number2int(i, lua_tonumber(L, -1));
+ krn = (scaled) i;
} else {
krn = MIN_INF;
}
@@ -1157,16 +1173,17 @@ static void store_math_kerns(lua_State * L, charinfo * co, int id)
}
}
-static void
-font_char_from_lua(lua_State * L, internal_font_number f, integer i,
- integer * l_fonts)
+@ @c
+void
+font_char_from_lua(lua_State * L, internal_font_number f, int i,
+ int *l_fonts, boolean has_math)
{
int k, r, t;
charinfo *co;
kerninfo *ckerns;
liginfo *cligs;
scaled j;
- char *s;
+ const char *s;
int nl = 0; /* number of ligature table items */
int nk = 0; /* number of kern table items */
int ctr = 0;
@@ -1182,10 +1199,6 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
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);
@@ -1197,117 +1210,131 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
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);
+ if (s != NULL)
+ set_charinfo_name(co, xstrdup(s));
+ else
+ set_charinfo_name(co, NULL);
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_rawgeti(L, LUA_REGISTRYINDEX, luaS_extensible_index);
- lua_rawget(L, -2);
- 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);
+ if (s != NULL)
+ set_charinfo_tounicode(co, xstrdup(s));
+ else
+ set_charinfo_tounicode(co, NULL);
+
+ if (has_math) {
+ 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);
+ 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);
- lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_horiz_variants_index);
- lua_rawget(L, -2);
- 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);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_extensible_index);
+ lua_rawget(L, -2);
+ 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 {
- lua_pop(L, 1);
- break;
+ pdftex_warn
+ ("lua-loaded font %s char [U+%X] has an invalid extensible field!",
+ font_name(f), (int) i);
}
}
- }
- lua_pop(L, 1);
+ lua_pop(L, 1);
- lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_vert_variants_index);
- lua_rawget(L, -2);
- 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_rawgeti(L, LUA_REGISTRYINDEX, luaS_horiz_variants_index);
+ lua_rawget(L, -2);
+ 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;
+ }
}
}
- }
- lua_pop(L, 1);
-
- /* Here is a complete example:
- ["mathkern"]={
- ["bottom_left"] ={ { ["height"]=420, ["kern"]=80 }, { ["height"]=520, ["kern"]=4 } },
- ["bottom_right"]={ { ["height"]=0, ["kern"]=48 } },
- ["top_left"] ={ { ["height"]=620, ["kern"]=0 }, { ["height"]=720, ["kern"]=-80 } },
- ["top_right"] ={ { ["height"]=676, ["kern"]=115 }, { ["height"]=776, ["kern"]=45 } },
- }
- */
- lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_mathkern_index);
- lua_rawget(L, -2);
- if (lua_istable(L, -1)) {
- lua_getfield(L, -1, "top_left");
- store_math_kerns(L, co, top_left_kern);
- lua_pop(L, 1);
- lua_getfield(L, -1, "top_right");
- store_math_kerns(L, co, top_right_kern);
lua_pop(L, 1);
- lua_getfield(L, -1, "bottom_right");
- store_math_kerns(L, co, bottom_right_kern);
+
+ lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_vert_variants_index);
+ lua_rawget(L, -2);
+ 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);
- lua_getfield(L, -1, "bottom_left");
- store_math_kerns(L, co, bottom_left_kern);
+
+/* Here is a complete example:
+
+ |["mathkern"]={|
+ |["bottom_left"] ={ { ["height"]=420, ["kern"]=80 }, { ["height"]=520, ["kern"]=4 } },|
+ |["bottom_right"]={ { ["height"]=0, ["kern"]=48 } },|
+ |["top_left"] ={ { ["height"]=620, ["kern"]=0 }, { ["height"]=720, ["kern"]=-80 } },|
+ |["top_right"] ={ { ["height"]=676, ["kern"]=115 }, { ["height"]=776, ["kern"]=45 } },|
+ |}|
+ */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_mathkern_index);
+ lua_rawget(L, -2);
+ if (lua_istable(L, -1)) {
+ lua_getfield(L, -1, "top_left");
+ store_math_kerns(L, co, top_left_kern);
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "top_right");
+ store_math_kerns(L, co, top_right_kern);
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "bottom_right");
+ store_math_kerns(L, co, bottom_right_kern);
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "bottom_left");
+ store_math_kerns(L, co, bottom_left_kern);
+ lua_pop(L, 1);
+ }
lua_pop(L, 1);
}
- lua_pop(L, 1);
-
+ /* end of |has_math| */
nk = count_hash_items(L, luaS_index(kerns));
if (nk > 0) {
- ckerns = xcalloc((nk + 1), sizeof(kerninfo));
+ ckerns = xcalloc((unsigned) (nk + 1), sizeof(kerninfo));
lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(kerns));
lua_rawget(L, -2);
if (lua_istable(L, -1)) { /* there are kerns */
@@ -1316,11 +1343,12 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
while (lua_next(L, -2) != 0) {
k = non_boundarychar;
if (lua_isnumber(L, -2)) {
- k = lua_tonumber(L, -2); /* adjacent char */
+ lua_number2int(k, lua_tonumber(L, -2)); /* adjacent char */
if (k < 0)
k = non_boundarychar;
} else if (lua_isstring(L, -2)) {
- if (luaS_ptr_eq(lua_tostring(L, -2), right_boundary)) {
+ s = lua_tostring(L, -2);
+ if (luaS_ptr_eq(s, right_boundary)) {
k = right_boundarychar;
if (!has_right_boundary(f))
set_right_boundary(f,
@@ -1359,7 +1387,7 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
lua_pushnil(L); /* first key */
if (lua_next(L, -2) != 0) {
lua_pop(L, 2);
- read_char_packets(L, (integer *) l_fonts, co, atsize);
+ read_char_packets(L, (int *) l_fonts, co, atsize);
}
}
lua_pop(L, 1);
@@ -1368,7 +1396,7 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
nl = count_hash_items(L, luaS_index(ligatures));
if (nl > 0) {
- cligs = xcalloc((nl + 1), sizeof(liginfo));
+ cligs = xcalloc((unsigned) (nl + 1), sizeof(liginfo));
lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(ligatures));
lua_rawget(L, -2);
if (lua_istable(L, -1)) { /* do ligs */
@@ -1377,12 +1405,13 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
while (lua_next(L, -2) != 0) {
k = non_boundarychar;
if (lua_isnumber(L, -2)) {
- k = lua_tonumber(L, -2); /* adjacent char */
+ lua_number2int(k, lua_tonumber(L, -2)); /* adjacent char */
if (k < 0) {
k = non_boundarychar;
}
} else if (lua_isstring(L, -2)) {
- if (luaS_ptr_eq(lua_tostring(L, -2), right_boundary)) {
+ s = lua_tostring(L, -2);
+ if (luaS_ptr_eq(s, right_boundary)) {
k = right_boundarychar;
if (!has_right_boundary(f))
set_right_boundary(f,
@@ -1396,7 +1425,8 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
}
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);
+ set_ligature_item(cligs[ctr], (char) ((t * 2) + 1), k,
+ r);
ctr++;
} else {
pdftex_warn
@@ -1422,9 +1452,9 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i,
-/* The caller has to fix the state of the lua stack when there is an error! */
-
+@ The caller has to fix the state of the lua stack when there is an error!
+@c
int font_from_lua(lua_State * L, int f)
{
int i, n, r, t;
@@ -1432,8 +1462,10 @@ int font_from_lua(lua_State * L, int f)
int bc; /* first char index */
int ec; /* last char index */
char *s;
- integer *l_fonts = NULL;
- integer save_ref = 1; /* unneeded, really */
+ const char *ss;
+ int *l_fonts = NULL;
+ int save_ref = 1; /* unneeded, really */
+ boolean no_math = false;
/* will we save a cache of the luat table? */
s = string_field(L, "cache", "yes");
@@ -1466,41 +1498,43 @@ int font_from_lua(lua_State * L, int f)
pdftex_fail("lua-loaded font [%d] has no name!", f);
return false;
}
+ s = string_field(L, "psname", NULL);
+ set_font_psname(f, s);
+ i = numeric_field(L, "units_per_em", 0);
+ set_font_units_per_em(f, i);
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);
+ set_font_checksum(f, (unsigned) i);
i = numeric_field(L, "direction", 0);
set_font_natural_dir(f, i);
i = numeric_field(L, "encodingbytes", 0);
- set_font_encodingbytes(f, i);
+ set_font_encodingbytes(f, (char) 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_tounicode(f, (char) i);
+
+ i = numeric_field(L, "extend", 1000);
+ if (i < FONT_EXTEND_MIN)
+ i = FONT_EXTEND_MIN;
+ if (i > FONT_EXTEND_MAX)
+ i = FONT_EXTEND_MAX;
set_font_extend(f, i);
i = numeric_field(L, "slant", 0);
- if (i < -1000)
- i = -1000;
- if (i > 1000)
- i = 1000;
+ if (i < FONT_SLANT_MIN)
+ i = FONT_SLANT_MIN;
+ if (i > FONT_SLANT_MAX)
+ i = FONT_SLANT_MAX;
set_font_slant(f, i);
- i = numeric_field(L, "hyphenchar", get_default_hyphen_char());
+ i = numeric_field(L, "hyphenchar", int_par(default_hyphen_char_code));
set_hyphen_char(f, i);
- i = numeric_field(L, "skewchar", get_default_skew_char());
+ i = numeric_field(L, "skewchar", int_par(default_skew_char_code));
set_skew_char(f, i);
i = boolean_field(L, "used", 0);
- set_font_used(f, i);
+ set_font_used(f, (char) i);
s = string_field(L, "attributes", NULL);
if (s != NULL && strlen(s) > 0) {
@@ -1523,9 +1557,8 @@ int font_from_lua(lua_State * L, int f)
/* now fetch the base fonts, if needed */
n = count_hash_items(L, luaS_index(fonts));
if (n > 0) {
- const char *cs;
- l_fonts = xmalloc((n + 2) * sizeof(integer));
- memset(l_fonts, 0, (n + 2) * sizeof(integer));
+ l_fonts = xmalloc((unsigned) ((unsigned) (n + 2) * sizeof(int)));
+ memset(l_fonts, 0, (size_t) ((unsigned) (n + 2) * sizeof(int)));
lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(fonts));
lua_rawget(L, -2);
for (i = 1; i <= n; i++) {
@@ -1533,33 +1566,33 @@ int font_from_lua(lua_State * L, int f)
if (lua_istable(L, -1)) {
lua_getfield(L, -1, "id");
if (lua_isnumber(L, -1)) {
- l_fonts[i] = lua_tonumber(L, -1);
+ lua_number2int(l_fonts[i], lua_tonumber(L, -1));
lua_pop(L, 2); /* pop id and entry */
continue;
}
lua_pop(L, 1); /* pop id */
};
- cs = NULL;
+ ss = NULL;
if (lua_istable(L, -1)) {
lua_getfield(L, -1, "name");
if (lua_isstring(L, -1)) {
- cs = lua_tostring(L, -1);
+ ss = lua_tostring(L, -1);
}
lua_pop(L, 1); /* pop name */
}
- if (cs != NULL) {
+ if (ss != 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
+ /* 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)
+ if (strcmp(font_name(f), ss) == 0)
l_fonts[i] = f;
else
- l_fonts[i] = find_font_id(s, t);
+ l_fonts[i] = find_font_id(ss, t);
lua_settop(L, s_top);
} else {
pdftex_fail("Invalid local font in font %s!\n", font_name(f));
@@ -1571,7 +1604,7 @@ int font_from_lua(lua_State * L, int f)
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 = xmalloc(3 * sizeof(int));
l_fonts[0] = 0;
l_fonts[1] = f;
l_fonts[2] = 0;
@@ -1579,22 +1612,28 @@ int font_from_lua(lua_State * L, int f)
}
/* parameters */
+ no_math = boolean_field(L, "nomath", 0);
read_lua_parameters(L, f);
- read_lua_math_parameters(L, f);
+ if (!no_math) {
+ 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 */
+ int num = 0; /* number of charinfo's to add */
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);
+ i = (int) lua_tointeger(L, -2);
if (i >= 0) {
if (lua_istable(L, -1)) {
+ num++;
if (i > ec)
ec = i;
if (bc < 0)
@@ -1606,31 +1645,35 @@ int font_from_lua(lua_State * L, int f)
}
lua_pop(L, 1);
}
-
if (bc != -1) {
- /* fprintf(stdout,"defined a font at %d with %d-%d\n",f,bc,ec); */
+#if 0
+ fprintf(stdout,"defined a font at %d with %d-%d\n",f,bc,ec);
+#endif
+ font_malloc_charinfo(f, num);
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);
+ lua_number2int(i, lua_tonumber(L, -2));
if (i >= 0) {
- font_char_from_lua(L, f, i, l_fonts);
+ font_char_from_lua(L, f, i, l_fonts, !no_math);
}
} else if (lua_isstring(L, -2)) {
- const char *cs = lua_tostring(L, -2);
- if (luaS_ptr_eq(cs, left_boundary)) {
- font_char_from_lua(L, f, left_boundarychar, l_fonts);
- } else if (luaS_ptr_eq(cs, right_boundary)) {
- font_char_from_lua(L, f, right_boundarychar, l_fonts);
+ const char *ss = lua_tostring(L, -2);
+ if (luaS_ptr_eq(ss, left_boundary)) {
+ font_char_from_lua(L, f, left_boundarychar, l_fonts,
+ !no_math);
+ } else if (luaS_ptr_eq(ss, right_boundary)) {
+ font_char_from_lua(L, f, right_boundarychar, l_fonts,
+ !no_math);
}
}
lua_pop(L, 1);
}
lua_pop(L, 1);
- /* handle font expansion last: the |copy_font| routine is called eventually,
+ /* 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);
@@ -1666,10 +1709,10 @@ int font_from_lua(lua_State * L, int f)
}
if (save_ref > 0) {
- r = luaL_ref(Luas, LUA_REGISTRYINDEX); /* pops the table */
+ r = luaL_ref(L, LUA_REGISTRYINDEX); /* pops the table */
set_font_cache_id(f, r);
} else {
- lua_pop(Luas, 1);
+ lua_pop(L, 1);
set_font_cache_id(f, save_ref);
}
} else { /* jikes, no characters */
@@ -1682,23 +1725,24 @@ int font_from_lua(lua_State * L, int f)
return true;
}
-/* ====================================================================
- *
- * L I G A T U R I N G
- *
- * ==================================================================== */
+@* Ligaturing.
+
+@c
#define assert_disc(a) \
- assert(pre_break(a)!=null); /* expect head_node */ \
+ assert(pre_break(a)!=null); /* expect |head_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((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((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((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));
+ 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)
{
@@ -1785,7 +1829,7 @@ static int try_ligature(halfword * frst, halfword fwd)
set_is_ligature(newgl);
/* below might not be correct in contrived border case.
- * but we use it only for debugging, so ... */
+ but we use it only for debugging, so ... */
if (character(cur) < 0) {
set_is_leftboundary(newgl);
}
@@ -1805,8 +1849,8 @@ static int try_ligature(halfword * frst, halfword fwd)
}
/* 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 */
+ 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);
@@ -1827,7 +1871,7 @@ static int try_ligature(halfword * frst, halfword fwd)
/* right side */
if (keep_right) {
halfword new_second = copy_node(fwd);
- /* correct, because we _know_ lig_ptr points to _one_ node */
+ /* correct, because we {\it know\/} |lig_ptr| points to {\it one\/} node */
couple_nodes(lig_ptr(newgl), new_second);
couple_nodes(newgl, fwd);
if (move_after) {
@@ -1837,7 +1881,7 @@ static int try_ligature(halfword * frst, halfword fwd)
} else {
halfword next = vlink(fwd);
uncouple_node(fwd);
- /* correct, because we _know_ lig_ptr points to _one_ node */
+ /* correct, because we {\it know\/} |lig_ptr| points to {\it one\/} node */
couple_nodes(lig_ptr(newgl), fwd);
if (next != null) {
couple_nodes(newgl, next);
@@ -1845,7 +1889,6 @@ static int try_ligature(halfword * frst, halfword fwd)
}
/* check and return */
- /* assert(move_after==0); */
*frst = cur;
return 1;
}
@@ -1853,9 +1896,11 @@ static int try_ligature(halfword * frst, halfword fwd)
}
-/* 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 */
+@ 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|.
+
+@c
static halfword handle_lig_nest(halfword root, halfword cur)
{
if (cur == null)
@@ -1876,11 +1921,10 @@ static halfword handle_lig_nest(halfword root, halfword cur)
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 */
+ /* no need to uncouple |cur|, it is freed */
flush_node(cur);
if (fwd == null) {
vlink(prev) = fwd;
@@ -1900,7 +1944,6 @@ static halfword handle_lig_word(halfword cur)
if (has_right_boundary(font(cur))) {
right = new_glyph(font(cur), right_boundarychar);
}
-
while (1) {
/* A glyph followed by ... */
if (type(cur) == glyph_node) {
@@ -1908,20 +1951,20 @@ static halfword handle_lig_word(halfword cur)
if (fwd == null) { /* last character of paragraph */
if (right == null)
break;
- /* --\par prohibits use of couple_nodes here */
+ /* \.{--\\par} prohibits use of |couple_nodes| here */
try_couple_nodes(cur, right);
right = null;
continue;
}
assert(alink(fwd) == cur);
- if (type(fwd) == glyph_node) { /* GLYPH - GLYPH */
+ 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 */
+ } else if (type(fwd) == disc_node) { /* |GLYPH - DISC| */
- /* if a{bx}{}{y} and a+b=>B convert to {Bx}{}{ay} */
+ /* 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;
@@ -1939,7 +1982,7 @@ static halfword handle_lig_word(halfword cur)
uncouple_node(cur);
couple_nodes(prev, fwd);
nesting_prepend(no_break(fwd), cur);
- /* now ligature the pre_break */
+ /* 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;
@@ -1948,27 +1991,27 @@ static halfword handle_lig_word(halfword cur)
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 */
+ /* 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 */
+ couple_nodes(no_break(fwd), cur); /* we {\it 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 */
+ /* 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 */
+ couple_nodes(cur, next); /* we {\it know\/} this works */
tlink(no_break(fwd)) = next; /* and make sure the list is correct */
- /* now copy next to the post_break */
+ /* 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 */
+ /* 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) {
@@ -1977,7 +2020,7 @@ static halfword handle_lig_word(halfword cur)
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 */
+ /* no need to reset |right|, we're going to leave the loop anyway */
}
break;
} else { /* fwd is something unknown */
@@ -1992,10 +2035,21 @@ static halfword handle_lig_word(halfword cur)
} else if (type(cur) == disc_node) {
assert_disc(cur);
- /* If {?}{x}{?} or {?}{?}{y} then ... */
+ /* If \.{{?}{x}{?}} or \.{{?}{?}{y}} then ... */
if (vlink_no_break(cur) != null || vlink_post_break(cur) != null) {
+ halfword prev = 0;
halfword fwd;
liginfo lig;
+ if (subtype(cur) == select_disc) {
+ prev = alink(cur);
+ assert(type(prev) == disc_node
+ && subtype(prev) == init_disc);
+ if (vlink_post_break(cur) != null)
+ handle_lig_nest(post_break(prev),
+ vlink_post_break(prev));
+ if (vlink_no_break(cur) != null)
+ handle_lig_nest(no_break(prev), vlink_no_break(prev));
+ }
if (vlink_post_break(cur) != null)
handle_lig_nest(post_break(cur), vlink_post_break(cur));
if (vlink_no_break(cur) != null)
@@ -2004,13 +2058,40 @@ static halfword handle_lig_word(halfword cur)
halfword nob, pst, next;
if (type(fwd) != glyph_node)
break;
- nob = tlink_no_break(cur);
- pst = tlink_post_break(cur);
- if ((nob == null || !test_ligature(&lig, nob, fwd)) &&
- (pst == null || !test_ligature(&lig, pst, fwd)))
- break;
- nesting_append(no_break(cur), copy_node(fwd));
- handle_lig_nest(no_break(cur), nob);
+ if (subtype(cur) != select_disc) {
+ nob = tlink_no_break(cur);
+ pst = tlink_post_break(cur);
+ if ((nob == null || !test_ligature(&lig, nob, fwd)) &&
+ (pst == null || !test_ligature(&lig, pst, fwd)))
+ break;
+ nesting_append(no_break(cur), copy_node(fwd));
+ handle_lig_nest(no_break(cur), nob);
+ } else {
+ int dobreak = 0;
+ nob = tlink_no_break(prev);
+ pst = tlink_post_break(prev);
+ if ((nob == null || !test_ligature(&lig, nob, fwd)) &&
+ (pst == null || !test_ligature(&lig, pst, fwd)))
+ dobreak = 1;
+ if (!dobreak) {
+ nesting_append(no_break(prev), copy_node(fwd));
+ handle_lig_nest(no_break(prev), nob);
+ nesting_append(post_break(prev), copy_node(fwd));
+ handle_lig_nest(post_break(prev), pst);
+ }
+ dobreak = 0;
+ nob = tlink_no_break(cur);
+ pst = tlink_post_break(cur);
+ if ((nob == null || !test_ligature(&lig, nob, fwd)) &&
+ (pst == null || !test_ligature(&lig, pst, fwd)))
+ dobreak = 1;
+ if (!dobreak) {
+ nesting_append(no_break(cur), copy_node(fwd));
+ handle_lig_nest(no_break(cur), nob);
+ }
+ if (dobreak)
+ break;
+ }
next = vlink(fwd);
uncouple_node(fwd);
try_couple_nodes(cur, next);
@@ -2027,35 +2108,35 @@ static halfword handle_lig_word(halfword cur)
test_ligature(&lig, tlink_post_break(cur), next)) ||
(tlink_no_break(cur) != null &&
test_ligature(&lig, tlink_no_break(cur), next)))) {
- /* Building an init_disc followed by a select_disc
- * {a-}{b}{AB} {-}{}{} 'c'
+ /* Building an |init_disc| followed by a |select_disc|
+ \.{{a-}{b}{AB} {-}{}{}} 'c'
*/
halfword last = vlink(next), tail;
uncouple_node(next);
try_couple_nodes(fwd, last);
- /* {a-}{b}{AB} {-}{c}{} */
+ /* \.{{a-}{b}{AB} {-}{c}{}} */
nesting_append(post_break(fwd), copy_node(next));
- /* {a-}{b}{AB} {-}{c}{-} */
+ /* \.{{a-}{b}{AB} {-}{c}{-}} */
if (vlink_no_break(cur) != null) {
nesting_prepend(no_break(fwd),
copy_node(vlink_pre_break(fwd)));
}
- /* {a-}{b}{AB} {b-}{c}{-} */
+ /* \.{{a-}{b}{AB} {b-}{c}{-}} */
if (vlink_post_break(cur) != null)
nesting_prepend_list(pre_break(fwd),
copy_node_list(vlink_post_break
(cur)));
- /* {a-}{b}{AB} {b-}{c}{AB-} */
+ /* \.{{a-}{b}{AB} {b-}{c}{AB-}} */
if (vlink_no_break(cur) != null) {
nesting_prepend_list(no_break(fwd),
copy_node_list(vlink_no_break
(cur)));
}
- /* {a-}{b}{ABC} {b-}{c}{AB-} */
+ /* \.{{a-}{b}{ABC} {b-}{c}{AB-}} */
tail = tlink_no_break(cur);
nesting_append(no_break(cur), copy_node(next));
handle_lig_nest(no_break(cur), tail);
- /* {a-}{BC}{ABC} {b-}{c}{AB-} */
+ /* \.{{a-}{BC}{ABC} {b-}{c}{AB-}} */
tail = tlink_post_break(cur);
nesting_append(post_break(cur), next);
handle_lig_nest(post_break(cur), tail);
@@ -2067,14 +2148,16 @@ static halfword handle_lig_word(halfword cur)
}
} else { /* NO GLYPH NOR DISC */
- /* fprintf(stdout,"This is a %d node\n",type(cur)); */
- /* assert(0); *//* TODO howcome there can be a glue here? */
+#if 0
+ fprintf(stdout,"This is a %d node\n",type(cur));
+ assert(0); /* TODO howcome there can be a glue here? */
+#endif
return cur;
}
/* step-to-next-node */
{
halfword prev = cur;
- /* --\par allows vlink(cur) to be null */
+ /* \.{--\\par} allows |vlink(cur)| to be null */
cur = vlink(cur);
if (cur != null) {
assert(alink(cur) == prev);
@@ -2085,11 +2168,12 @@ static halfword handle_lig_word(halfword cur)
return cur;
}
-/* return = new tail, head should be a dummy */
+@ Return value is the new tail, head should be a dummy
+@c
halfword handle_ligaturing(halfword head, halfword tail)
{
- halfword save_tail; /* trick to allow explicit node==null tests */
+ halfword save_tail; /* trick to allow explicit |node==null| tests */
halfword cur, prev;
if (vlink(head) == null)
@@ -2097,7 +2181,7 @@ halfword handle_ligaturing(halfword head, halfword tail)
save_tail = vlink(tail);
vlink(tail) = null;
- /* if (fix_node_lists) */
+ /* |if (fix_node_lists)| */
fix_node_list(head);
prev = head;
@@ -2123,12 +2207,9 @@ halfword handle_ligaturing(halfword head, halfword tail)
}
-/* ====================================================================
- *
- * K E R N I N G
- *
- * ==================================================================== */
+@* Kerning.
+@c
static void add_kern_before(halfword left, halfword right)
{
if ((!is_rightghost(right)) &&
@@ -2253,12 +2334,9 @@ halfword handle_kerning(halfword head, halfword tail)
return tail;
}
-/* ====================================================================
- *
- * L I G A T U R I N G and K E R N I N G : L U A - I N T E R F A C E
- *
- * ==================================================================== */
+@* ligaturing and kerning : lua-interface.
+@c
static halfword
run_lua_ligkern_callback(halfword head, halfword tail, int callback_id)
{
diff --git a/Build/source/texk/web2c/luatexdir/font/luatexfont.h b/Build/source/texk/web2c/luatexdir/font/luatexfont.h
index 987517266ed..fa2d2ac6c6d 100644
--- a/Build/source/texk/web2c/luatexdir/font/luatexfont.h
+++ b/Build/source/texk/web2c/luatexdir/font/luatexfont.h
@@ -1,6 +1,6 @@
/* luatexfont.h --- General font definitions
- Copyright 2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2008-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: luatexfont.h 2332 2009-04-18 17:17:56Z hhenkel $ */
+/* $Id: luatexfont.h 3433 2010-02-20 10:03:04Z hhenkel $ */
#ifndef LUATEXFONT_H
# define LUATEXFONT_H
@@ -83,19 +83,18 @@ typedef struct {
} intparm;
typedef struct {
- integer fe_objnum; /* object number */
+ int fe_objnum; /* object number */
char *name; /* encoding file name */
char **glyph_names; /* array of glyph names */
struct avl_table *tx_tree; /* tree of encoding positions marked as used by TeX */
} fe_entry;
typedef struct fd_entry_ {
- integer fd_objnum; /* object number of the font descriptor object */
+ int fd_objnum; /* object number of the font descriptor object */
char *fontname; /* /FontName (without subset tag) */
char *subset_tag; /* 6-character subset tag */
boolean ff_found;
- integer ff_objnum; /* object number of the font program stream */
- integer fn_objnum; /* font name object number (embedded PDF) */
+ int ff_objnum; /* object number of the font program stream */
boolean all_glyphs; /* embed all glyphs? */
boolean write_ttf_glyph_names;
intparm font_dim[FONT_KEYS_NUM];
@@ -107,16 +106,16 @@ typedef struct fd_entry_ {
} fd_entry;
typedef struct fo_entry_ {
- integer fo_objnum; /* object number of the font dictionary */
- internalfontnumber tex_font; /* needed only for \pdffontattr{} */
+ int fo_objnum; /* object number of the font dictionary */
+ internal_font_number tex_font; /* needed only for \pdffontattr{} */
fm_entry *fm; /* pointer to font map structure for this font dictionary */
fd_entry *fd; /* pointer to /FontDescriptor object structure */
fe_entry *fe; /* pointer to encoding structure */
- integer cw_objnum; /* object number of the font program object */
- integer first_char; /* first character used in this font */
- integer last_char; /* last character used in this font */
+ int cw_objnum; /* object number of the font program object */
+ int first_char; /* first character used in this font */
+ int last_char; /* last character used in this font */
struct avl_table *tx_tree; /* tree of non-reencoded TeX characters marked as used */
- integer tounicode_objnum; /* object number of ToUnicode */
+ int tounicode_objnum; /* object number of ToUnicode */
} fo_entry;
typedef struct {
@@ -132,7 +131,7 @@ typedef struct glw_entry_ { /* subset glyphs for inclusion in CID-based font
} glw_entry;
typedef struct {
- integer charcode, cwidth, cheight, xoff, yoff, xescape, rastersize;
+ int charcode, cwidth, cheight, xoff, yoff, xescape, rastersize;
halfword *raster;
} chardesc;
@@ -141,41 +140,38 @@ typedef struct {
# include "texfont.h"
/* tounicode.c */
-integer write_cid_tounicode(fo_entry * fo, internalfontnumber f);
+int write_cid_tounicode(PDF, fo_entry *, internal_font_number);
void glyph_unicode_free(void);
void def_tounicode(str_number, str_number);
-integer write_tounicode(char **, char *);
+int write_tounicode(PDF, char **, char *);
/* vfpacket.c */
-void replace_packet_fonts(internal_font_number f, integer * old_fontid,
- integer * new_fontid, int count);
-integer *packet_local_fonts(internal_font_number f, integer * num);
+void replace_packet_fonts(internal_font_number f, int *old_fontid,
+ int *new_fontid, int count);
+int *packet_local_fonts(internal_font_number f, int *num);
-/* writeccf.c */
-void writetype1w(fd_entry * fd);
+/* writecff.c */
+void writetype1w(PDF pdf, fd_entry * fd);
/* writetype0.c */
-void writetype0(fd_entry * fd);
+void writetype0(PDF pdf, fd_entry * fd);
/* writefont.c */
-void do_pdf_font(integer, internalfontnumber);
-fd_entry *lookup_fd_entry(char *, integer, integer);
+void do_pdf_font(PDF, internal_font_number);
+fd_entry *lookup_fd_entry(char *);
fd_entry *new_fd_entry(void);
-void write_fontstuff(void);
-integer get_fd_objnum(fd_entry * fd);
-integer get_fn_objnum(fd_entry * fd);
-void embed_whole_font(fd_entry * fd);
+void write_fontstuff(PDF);
void register_fd_entry(fd_entry * fd);
/* writet1.c */
boolean t1_subset(char *, char *, unsigned char *);
char **load_enc_file(char *);
-void writet1(fd_entry *);
+void writet1(PDF, fd_entry *);
void t1_free(void);
-extern integer t1_length1, t1_length2, t1_length3;
+extern int t1_length1, t1_length2, t1_length3;
/* writetype2.c */
-void writetype2(fd_entry * fd);
+void writetype2(PDF, fd_entry *);
extern unsigned long cidtogid_obj;
pdf_obj *pdf_new_stream(void);
void pdf_add_stream(pdf_obj * stream, unsigned char *buf, long len);
@@ -188,37 +184,35 @@ boolean handle_subfont_fm(fm_entry *, int);
/* writeenc.c */
fe_entry *get_fe_entry(char *);
void enc_free(void);
-void write_fontencodings(void);
+void write_fontencodings(PDF pdf);
/* writettf.c */
-void writettf(fd_entry *);
-void writeotf(fd_entry *);
+void writettf(PDF, fd_entry *);
+void writeotf(PDF, fd_entry *);
void ttf_free(void);
-extern integer ttf_length;
+extern int ttf_length;
/* pkin.c */
int readchar(boolean, chardesc *);
/* macnames.c */
-extern const char notdef[];
+extern char notdef[];
/* vfovf.c */
void vf_expand_local_fonts(internal_font_number f);
internal_font_number letter_space_font(halfword u, internal_font_number f,
- integer e);
-internal_font_number auto_expand_font(internal_font_number f, integer e);
-str_number expand_font_name(internal_font_number f, integer e);
-void pdf_check_vf_cur_val(void);
+ int e);
+internal_font_number auto_expand_font(internal_font_number f, int e);
+void pdf_check_vf(internal_font_number f);
internal_font_number copy_font_info(internal_font_number f);
/* writet3.c */
extern FILE *t3_file;
-void writet3(int, internalfontnumber);
-scaled get_pk_char_width(internalfontnumber, scaled);
+void writet3(PDF, internal_font_number);
extern unsigned char *t3_buffer;
-extern integer t3_size;
-extern integer t3_curbyte;
+extern int t3_size;
+extern int t3_curbyte;
# define t3_read_file() readbinfile(t3_file, &t3_buffer, &t3_size)
# define t3_close() xfclose(t3_file, cur_file_name)
diff --git a/Build/source/texk/web2c/luatexdir/font/macnames.c b/Build/source/texk/web2c/luatexdir/font/macnames.c
deleted file mode 100644
index a62de50edcb..00000000000
--- a/Build/source/texk/web2c/luatexdir/font/macnames.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/* macnames.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-static const char __svn_version[] =
- "$Id: macnames.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/macnames.c $";
-
-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/font/mapfile.h b/Build/source/texk/web2c/luatexdir/font/mapfile.h
index e4242a21255..544ebd9c9c3 100644
--- a/Build/source/texk/web2c/luatexdir/font/mapfile.h
+++ b/Build/source/texk/web2c/luatexdir/font/mapfile.h
@@ -17,39 +17,48 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: mapfile.h 2331 2009-04-18 16:39:50Z hhenkel $ */
+/* $Id: mapfile.h 3404 2010-01-28 11:17:10Z taco $ */
#ifndef MAPFILE_H
# define MAPFILE_H
-# define F_INCLUDED 0x01
-# define F_SUBSETTED 0x02
-# define F_STDT1FONT 0x04
-# define F_SUBFONT 0x08
-# define F_TYPE1 0x10
-# define F_TRUETYPE 0x20
-# define F_OTF 0x40
-# define F_CIDKEYED 0x80
-
-# define set_included(fm) ((fm)->type |= F_INCLUDED)
-# define set_subsetted(fm) ((fm)->type |= F_SUBSETTED)
-# define set_std_t1font(fm) ((fm)->type |= F_STDT1FONT)
-# define set_subfont(fm) ((fm)->type |= F_SUBFONT)
-# define set_type1(fm) ((fm)->type |= F_TYPE1)
-# define set_truetype(fm) ((fm)->type |= F_TRUETYPE)
-# define set_opentype(fm) ((fm)->type |= F_OTF)
-# define set_subfont(fm) ((fm)->type |= F_SUBFONT)
-# define set_cidkeyed(fm) ((fm)->type |= F_CIDKEYED)
-
-# define unset_included(fm) ((fm)->type &= ~F_INCLUDED)
-# define unset_subsetted(fm) ((fm)->type &= ~F_SUBSETTED)
-# define unset_std_t1font(fm)((fm)->type &= ~F_STDT1FONT)
-# define unset_subfont(fm) ((fm)->type &= ~F_SUBFONT)
-# define unset_type1(fm) ((fm)->type &= ~F_TYPE1)
-# define unset_truetype(fm) ((fm)->type &= ~F_TRUETYPE)
-# define unset_opentype(fm) ((fm)->type &= ~F_OTF)
-# define unset_subfont(fm) ((fm)->type &= ~F_SUBFONT)
-# define unset_cidkeyed(fm) ((fm)->type &= ~F_CIDKEYED)
+# define F_INCLUDED (1 << 0)
+# define F_SUBSETTED (1 << 1)
+# define F_STDT1FONT (1 << 2)
+# define F_SUBFONT (1 << 3)
+# define F_TYPE1 (1 << 4)
+# define F_TRUETYPE (1 << 5)
+# define F_OTF (1 << 6)
+# define F_CIDKEYED (1 << 7)
+# define F_SLANTSET (1 << 8)
+# define F_EXTENDSET (1 << 9)
+# define F_INUSE (1 << 10)
+
+typedef enum { MAPFILE, MAPLINE } maptype;
+
+# define set_included(fm) ((fm)->type = (unsigned short)((fm)->type | F_INCLUDED))
+# define set_subsetted(fm) ((fm)->type = (unsigned short)((fm)->type | F_SUBSETTED))
+# define set_std_t1font(fm) ((fm)->type = (unsigned short)((fm)->type | F_STDT1FONT))
+# define set_subfont(fm) ((fm)->type = (unsigned short)((fm)->type | F_SUBFONT))
+# define set_type1(fm) ((fm)->type = (unsigned short)((fm)->type | F_TYPE1))
+# define set_truetype(fm) ((fm)->type = (unsigned short)((fm)->type | F_TRUETYPE))
+# define set_opentype(fm) ((fm)->type = (unsigned short)((fm)->type | F_OTF))
+# define set_cidkeyed(fm) ((fm)->type = (unsigned short)((fm)->type | F_CIDKEYED))
+# define set_slantset(fm) ((fm)->type = (unsigned short)((fm)->type | F_SLANTSET))
+# define set_extendset(fm) ((fm)->type = (unsigned short)((fm)->type | F_EXTENDSET))
+# define set_inuse(fm) ((fm)->type = (unsigned short)((fm)->type | F_INUSE))
+
+# define unset_included(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_INCLUDED))
+# define unset_subsetted(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_SUBSETTED))
+# define unset_std_t1font(fm)((fm)->type = (unsigned short)((fm)->type & ~F_STDT1FONT))
+# define unset_subfont(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_SUBFONT))
+# define unset_type1(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_TYPE1))
+# define unset_truetype(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_TRUETYPE))
+# define unset_opentype(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_OTF))
+# define unset_cidkeyed(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_CIDKEYED))
+# define unset_slantset(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_SLANTSET))
+# define unset_extendset(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_EXTENDSET))
+# define unset_inuse(fm) ((fm)->type = (unsigned short)((fm)->type & ~F_INUSE))
# define is_included(fm) (((fm)->type & F_INCLUDED) != 0)
# define is_subsetted(fm) (((fm)->type & F_SUBSETTED) != 0)
@@ -58,8 +67,10 @@
# define is_type1(fm) (((fm)->type & F_TYPE1) != 0)
# define is_truetype(fm) (((fm)->type & F_TRUETYPE) != 0)
# define is_opentype(fm) (((fm)->type & F_OTF) != 0)
-# define is_subfont(fm) (((fm)->type & F_SUBFONT) != 0)
# define is_cidkeyed(fm) (((fm)->type & F_CIDKEYED) != 0)
+# define is_slantset(fm) (((fm)->type & F_SLANTSET) != 0)
+# define is_extendset(fm) (((fm)->type & F_EXTENDSET) != 0)
+# define is_inuse(fm) (((fm)->type & F_INUSE) != 0)
# define fm_slant(fm) (fm)->slant
# define fm_extend(fm) (fm)->extend
@@ -70,15 +81,6 @@
# define is_t1fontfile(fm) (is_fontfile(fm) && is_type1(fm))
# define is_builtin(fm) (!is_fontfile(fm))
-# define LINK_TFM 0x01
-# define LINK_PS 0x02
-# define set_tfmlink(fm) ((fm)->links |= LINK_TFM)
-# define set_pslink(fm) ((fm)->links |= LINK_PS)
-# define unset_tfmlink(fm) ((fm)->links &= ~LINK_TFM)
-# define unset_pslink(fm) ((fm)->links &= ~LINK_PS)
-# define has_tfmlink(fm) ((fm)->links & LINK_TFM)
-# define has_pslink(fm) ((fm)->links & LINK_PS)
-
/**********************************************************************/
typedef struct {
@@ -86,9 +88,9 @@ typedef struct {
char *tfm_name; /* TFM file name (1st field in map line) */
char *sfd_name; /* subfont directory name, like @sfd_name@ */
char *ps_name; /* PostScript name (optional 2nd field in map line) */
- integer fd_flags; /* font descriptor /Flags (PDF Ref. section 5.7.1) */
- integer slant; /* SlantFont */
- integer extend; /* ExtendFont */
+ int fd_flags; /* font descriptor /Flags (PDF Ref. section 5.7.1) */
+ int slant; /* SlantFont */
+ int extend; /* ExtendFont */
char *encname; /* encoding file name */
char *ff_name; /* font file name */
unsigned short type; /* various flags */
@@ -96,8 +98,6 @@ typedef struct {
short eid; /* Eid for truetype fonts */
/* parameters NOT scanned from the map file: */
subfont_entry *subfont; /* subfont mapping */
- unsigned short links; /* link flags from tfm_tree and ps_tree */
- boolean in_use; /* true if this structure has been referenced already */
} fm_entry;
typedef struct {
@@ -107,18 +107,24 @@ typedef struct {
/**********************************************************************/
-fm_entry *lookup_fontmap(char *);
-boolean hasfmentry(internalfontnumber);
+# define FONT_SLANT_MIN -2000
+# define FONT_SLANT_MAX 2000
+# define FONT_EXTEND_MIN -5000
+# define FONT_EXTEND_MAX 5000
+
+/**********************************************************************/
+
+fm_entry *getfontmap(char *tfm_name);
void fm_free(void);
-void fm_read_info(void);
ff_entry *check_ff_exist(char *, boolean);
-void pdfmapfile(integer);
-void pdfmapline(integer);
-void pdf_init_map_file(string map_name);
+void pdfmapfile(int);
+void pdfmapline(int);
+void pdf_init_map_file(char *map_name);
fm_entry *new_fm_entry(void);
void delete_fm_entry(fm_entry *);
int avl_do_entry(fm_entry *, int);
int check_std_t1font(char *s);
int is_subsetable(fm_entry * fm);
+void process_map_item(char *s, int type);
#endif /* MAPFILE_H */
diff --git a/Build/source/texk/web2c/luatexdir/font/mapfile.c b/Build/source/texk/web2c/luatexdir/font/mapfile.w
index fe5155da23e..3d129183d6f 100644
--- a/Build/source/texk/web2c/luatexdir/font/mapfile.c
+++ b/Build/source/texk/web2c/luatexdir/font/mapfile.w
@@ -1,7 +1,8 @@
+@ @c
/* mapfile.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+
+ Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
This file is part of LuaTeX.
@@ -18,29 +19,26 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
+static const char _svn_version[] =
+ "$Id: mapfile.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/mapfile.w $";
+
#include <math.h>
#include "ptexlib.h"
#include <kpathsea/c-auto.h>
#include <kpathsea/c-memstr.h>
#include <string.h>
-#include "luatex-api.h"
-
-static const char _svn_version[] =
- "$Id: mapfile.c 2331 2009-04-18 16:39:50Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/mapfile.c $";
#define FM_BUF_SIZE 1024
static FILE *fm_file;
static unsigned char *fm_buffer = NULL;
-static integer fm_size = 0;
-static integer fm_curbyte = 0;
+static int fm_size = 0;
+static int fm_curbyte = 0;
-#define fm_open() \
- (fm_file = fopen((char *) nameoffile + 1, FOPEN_RBIN_MODE))
-#define fm_read_file() \
- readbinfile(fm_file,&fm_buffer,&fm_size)
+#define fm_open(a) (fm_file = fopen((char *)(a), 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)
@@ -48,7 +46,6 @@ static integer fm_curbyte = 0;
(c == 10 || c == '*' || c == '#' || c == ';' || c == '%')
typedef enum { FM_DUPIGNORE, FM_REPLACE, FM_DELETE } updatemode;
-typedef enum { MAPFILE, MAPLINE } maptype;
typedef struct mitem {
updatemode mode; /* FM_DUPIGNORE or FM_REPLACE or FM_DELETE */
@@ -58,8 +55,6 @@ typedef struct mitem {
} mapitem;
mapitem *mitem = NULL;
-static const char nontfm[] = "<nontfm>";
-
#define read_field(r, q, buf) do { \
q = buf; \
while (*r != ' ' && *r != '<' && *r != '"' && *r != '\0') \
@@ -87,12 +82,13 @@ fm_entry *new_fm_entry(void)
fm->encname = NULL;
fm->type = 0;
fm->slant = 0;
- fm->extend = 0;
- fm->links = 0;
+ fm->extend = 1000;
fm->pid = -1;
fm->eid = -1;
fm->subfont = NULL;
- fm->in_use = false;
+ unset_slantset(fm);
+ unset_extendset(fm);
+ unset_inuse(fm);
return fm;
}
@@ -121,18 +117,11 @@ static void delete_ff_entry(ff_entry * ff)
xfree(ff);
}
-static fm_entry *dummy_fm_entry(void)
-{
- static const fm_entry const_fm_entry;
- return (fm_entry *) & const_fm_entry;
-}
-
/**********************************************************************/
-struct avl_table *tfm_tree = NULL;
-struct avl_table *ps_tree = NULL;
-struct avl_table *ff_tree = NULL;
-struct avl_table *encname_tree = NULL;
+static struct avl_table *tfm_tree = NULL;
+static struct avl_table *ff_tree = NULL;
+static struct avl_table *encname_tree = NULL;
/* AVL sort fm_entry into tfm_tree by tfm_name */
@@ -143,21 +132,6 @@ static int comp_fm_entry_tfm(const void *pa, const void *pb, void *p)
((const fm_entry *) pb)->tfm_name);
}
-/* AVL sort fm_entry into ps_tree by ps_name, slant, and extend */
-
-static int comp_fm_entry_ps(const void *pa, const void *pb, void *p)
-{
- int i;
- const fm_entry *p1 = (const fm_entry *) pa, *p2 = (const fm_entry *) pb;
- (void) p;
- assert(p1->ps_name != NULL && p2->ps_name != NULL);
- if ((i = strcmp(p1->ps_name, p2->ps_name)))
- return i;
- cmp_return(p1->slant, p2->slant);
- cmp_return(p1->extend, p2->extend);
- return 0;
-}
-
/* AVL sort ff_entry into ff_tree by ff_name */
static int comp_ff_entry(const void *pa, const void *pb, void *p)
@@ -172,9 +146,6 @@ static void create_avl_trees(void)
assert(tfm_tree == NULL);
tfm_tree = avl_create(comp_fm_entry_tfm, NULL, &avl_xallocator);
assert(tfm_tree != NULL);
- assert(ps_tree == NULL);
- ps_tree = avl_create(comp_fm_entry_ps, NULL, &avl_xallocator);
- assert(ps_tree != NULL);
assert(ff_tree == NULL);
ff_tree = avl_create(comp_ff_entry, NULL, &avl_xallocator);
assert(ff_tree != NULL);
@@ -183,90 +154,46 @@ static void create_avl_trees(void)
assert(encname_tree != NULL);
}
-/*
-The function avl_do_entry() is not completely symmetrical with regards
-to tfm_name and ps_name handling, e. g. a duplicate tfm_name gives a
-"goto exit", and no ps_name link is tried. This is to keep it compatible
-with the original version.
-*/
-
int avl_do_entry(fm_entry * fm, int mode)
{
fm_entry *p;
void *a;
void **aa;
-
- /* handle tfm_name link */
-
- if (strcmp(fm->tfm_name, nontfm)) {
- p = (fm_entry *) avl_find(tfm_tree, fm);
- if (p != NULL) {
- switch (mode) {
- case FM_DUPIGNORE:
+ int delete_new = 0;
+ if (tfm_tree == NULL)
+ create_avl_trees();
+ p = (fm_entry *) avl_find(tfm_tree, fm);
+ if (p != NULL) {
+ switch (mode) {
+ case FM_DUPIGNORE:
+ pdftex_warn
+ ("fontmap entry for `%s' already exists, duplicates ignored",
+ fm->tfm_name);
+ delete_new = 1;
+ break;
+ case FM_REPLACE:
+ case FM_DELETE:
+ if (is_inuse(p)) {
pdftex_warn
- ("fontmap entry for `%s' already exists, duplicates ignored",
+ ("fontmap entry for `%s' has been used, replace/delete not allowed",
fm->tfm_name);
- goto exit;
- break;
- case FM_REPLACE:
- case FM_DELETE:
- if (p->in_use) {
- pdftex_warn
- ("fontmap entry for `%s' has been used, replace/delete not allowed",
- fm->tfm_name);
- goto exit;
- }
+ delete_new = 1;
+ } else {
a = avl_delete(tfm_tree, p);
assert(a != NULL);
- unset_tfmlink(p);
- if (!has_pslink(p))
- delete_fm_entry(p);
- break;
- default:
- assert(0);
+ delete_fm_entry(p);
}
- }
- if (mode != FM_DELETE) {
- aa = avl_probe(tfm_tree, fm);
- assert(aa != NULL);
- set_tfmlink(fm);
- }
- }
-
- /* handle ps_name link */
-
- if (fm->ps_name != NULL) {
- p = (fm_entry *) avl_find(ps_tree, fm);
- if (p != NULL) {
- switch (mode) {
- case FM_DUPIGNORE:
- goto exit;
- break;
- case FM_REPLACE:
- case FM_DELETE:
- if (p->in_use)
- goto exit;
- a = avl_delete(ps_tree, p);
- assert(a != NULL);
- unset_pslink(p);
- if (!has_tfmlink(p))
- delete_fm_entry(p);
- break;
- default:
- assert(0);
- }
- }
- if (mode != FM_DELETE && is_t1fontfile(fm) && is_included(fm)) {
- aa = avl_probe(ps_tree, fm);
- assert(aa != NULL);
- set_pslink(fm);
+ break;
+ default:
+ assert(0);
}
}
- exit:
- if (!has_tfmlink(fm) && !has_pslink(fm)) /* e. g. after FM_DELETE */
- return 1; /* deallocation of fm_entry structure required */
- else
- return 0;
+ if ((mode == FM_DUPIGNORE || mode == FM_REPLACE) && delete_new == 0) {
+ aa = avl_probe(tfm_tree, fm);
+ assert(aa != NULL);
+ } else
+ delete_new = 1;
+ return delete_new;
}
/* add the encoding name to an AVL tree. this has nothing to do with writeenc.c */
@@ -320,25 +247,15 @@ static int check_fm_entry(fm_entry * fm, boolean warn)
a += 2;
}
- /* SlantFont and ExtendFont can be used only with Type1 fonts */
- if ((fm->slant != 0 || fm->extend != 0)
- && !(is_t1fontfile(fm) && is_included(fm))) {
- if (warn)
- pdftex_warn
- ("invalid entry for `%s': SlantFont/ExtendFont can be used only with embedded Type1 fonts",
- fm->tfm_name);
- a += 4;
- }
-
/* the value of SlantFont and ExtendFont must be reasonable */
- if (abs(fm->slant) > 1000) {
+ if (fm->slant < FONT_SLANT_MIN || fm->slant > FONT_SLANT_MAX) {
if (warn)
pdftex_warn
("invalid entry for `%s': too big value of SlantFont (%g)",
fm->tfm_name, fm->slant / 1000.0);
a += 8;
}
- if (abs(fm->extend) > 2000) {
+ if (fm->extend < FONT_EXTEND_MIN || fm->extend > FONT_EXTEND_MAX) {
if (warn)
pdftex_warn
("invalid entry for `%s': too big value of ExtendFont (%g)",
@@ -409,14 +326,14 @@ int check_std_t1font(char *s)
if (k > -1 && !strcmp(std_t1font_names[k], s))
return k;
return -1;
-};
-
+}
/**********************************************************************/
static void fm_scan_line(void)
{
int a, b, c, j, u = 0, v = 0;
+ char cc;
float d;
fm_entry *fm;
char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE];
@@ -427,12 +344,12 @@ static void fm_scan_line(void)
while (!fm_eof()) {
if (fm_curbyte == fm_size) {
fm_curbyte++;
- c = 10;
+ cc = 10;
} else {
- c = fm_getchar();
+ cc = (char) fm_getchar();
}
- append_char_to_buf(c, p, fm_line, FM_BUF_SIZE);
- if (c == 10)
+ append_char_to_buf(cc, p, fm_line, FM_BUF_SIZE);
+ if (cc == 10)
break;
}
*(--p) = '\0';
@@ -476,14 +393,14 @@ static void fm_scan_line(void)
if (*(s - 1) == 'E' || *(s - 1) == 'e')
s--; /* e. g. 0.5ExtendFont: %f = 0.5E */
if (str_prefix(s, "SlantFont")) {
- d *= 1000.0; /* correct rounding also for neg. numbers */
- fm->slant = (integer) (d > 0 ? d + 0.5 : d - 0.5);
+ d *= (float) 1000.0; /* correct rounding also for neg. numbers */
+ fm->slant = (int) (d > 0 ? d + 0.5 : d - 0.5);
+ set_slantset(fm);
r = s + strlen("SlantFont");
} else if (str_prefix(s, "ExtendFont")) {
- d *= 1000.0;
- fm->extend = (integer) (d > 0 ? d + 0.5 : d - 0.5);
- if (fm->extend == 1000)
- fm->extend = 0;
+ d *= (float) 1000.0;
+ fm->extend = (int) (d > 0 ? d + 0.5 : d - 0.5);
+ set_extendset(fm);
r = s + strlen("ExtendFont");
} else { /* unknown name */
for (r = s; *r != ' ' && *r != '"' && *r != '\0'; r++); /* jump over name */
@@ -492,7 +409,7 @@ static void fm_scan_line(void)
pdftex_warn
("invalid entry for `%s': unknown name `%s' ignored",
fm->tfm_name, s);
- *r = c;
+ *r = (char) c;
}
} else
for (; *r != ' ' && *r != '"' && *r != '\0'; r++);
@@ -509,8 +426,8 @@ static void fm_scan_line(void)
break;
case 'P': /* handle cases for subfonts like 'PidEid=3,1' */
if (sscanf(r, "PidEid=%i, %i %n", &a, &b, &c) >= 2) {
- fm->pid = a;
- fm->eid = b;
+ fm->pid = (short) a;
+ fm->eid = (short) b;
r += c;
break;
}
@@ -552,6 +469,8 @@ static void fm_scan_line(void)
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, ".ttc") == 0)
+ set_truetype(fm);
else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".otf") == 0)
set_opentype(fm);
else
@@ -567,7 +486,7 @@ static void fm_scan_line(void)
*/
if (handle_subfont_fm(fm, mitem->mode)) /* is this a subfont? */
return;
- if (avl_do_entry(fm, mitem->mode) == 0) /* if success */
+ if (avl_do_entry(fm, mitem->mode) == 0)
return;
bad_line:
delete_fm_entry(fm);
@@ -575,11 +494,11 @@ static void fm_scan_line(void)
/**********************************************************************/
-void fm_read_info(void)
+static void fm_read_info(void)
{
int callback_id;
int file_opened = 0;
- char *ftemp = NULL;
+
if (tfm_tree == NULL)
create_avl_trees();
if (mitem->line == NULL) /* nothing to do */
@@ -587,75 +506,49 @@ void fm_read_info(void)
mitem->lineno = 1;
switch (mitem->type) {
case MAPFILE:
- set_cur_file_name(mitem->line);
- if (fm_buffer != NULL) {
- xfree(fm_buffer);
- fm_buffer = NULL;
- }
+ xfree(fm_buffer);
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++;
+ cur_file_name = luatex_find_file(mitem->line, find_map_file_callback);
+ if (cur_file_name) {
+ callback_id = callback_defined(read_map_file_callback);
+ if (callback_id > 0) {
+ if (run_callback(callback_id, "S->bSd", cur_file_name,
+ &file_opened, &fm_buffer, &fm_size)) {
+ if (file_opened) {
+ if (fm_size > 0) {
+ if (tracefilenames)
+ tex_printf("{%s", cur_file_name);
+ while (!fm_eof()) {
+ fm_scan_line();
+ mitem->lineno++;
+ }
+ if (tracefilenames)
+ tex_printf("}");
+ fm_file = NULL;
}
- if (tracefilenames)
- tex_printf("}");
- fm_file = NULL;
+ } else {
+ pdftex_warn("cannot open font map file");
}
} 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++;
+ if (!fm_open(cur_file_name)) {
+ pdftex_warn("cannot open font map file");
+ } else {
+ fm_read_file();
+ tex_printf("{%s", cur_file_name);
+ while (!fm_eof()) {
+ fm_scan_line();
+ mitem->lineno++;
+ }
+ fm_close();
+ tex_printf("}");
+ fm_file = NULL;
}
- fm_close();
- tex_printf("}");
- fm_file = NULL;
}
+ cur_file_name = NULL;
}
break;
case MAPLINE:
@@ -672,145 +565,20 @@ void fm_read_info(void)
/**********************************************************************/
-static fm_entry_ptr fmlookup(internalfontnumber f)
+fm_entry *getfontmap(char *tfm_name)
{
- char *tfm;
fm_entry *fm;
fm_entry tmp;
+ if (tfm_name == NULL) /* wide, lua loaded fonts may not have a name */
+ return NULL;
if (tfm_tree == NULL)
fm_read_info(); /* only to read default map file */
- tfm = font_name(f);
- assert(strcmp(tfm, nontfm));
-
- /* Look up for full <tfmname>[+-]<expand> */
- tmp.tfm_name = tfm;
+ tmp.tfm_name = tfm_name; /* Look up for tfmname */
fm = (fm_entry *) avl_find(tfm_tree, &tmp);
- if (fm != NULL) {
- fm->in_use = true;
- return (fm_entry_ptr) fm;
- }
- return (fm_entry_ptr) dummy_fm_entry();
-}
-
-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();
-}
-
-/* check whether a map entry is valid for font replacement */
-
-static boolean fm_valid_for_font_replacement(fm_entry * fm)
-{
- ff_entry *ff;
-
- assert(fm != NULL);
- assert(is_fontfile(fm)); /* ps_tree should contain only entries with font file */
- assert(is_type1(fm)); /* ps_tree should contain only Type1 entries */
-
- ff = check_ff_exist(fm->ff_name, false);
- assert(ff != NULL);
- if (ff->ff_path == NULL) /* ...there is no font file available */
- return false;
- return true; /* all tests passed */
-}
-
-/**********************************************************************/
-/*
- * lookup fontmap by ps_name;
- * used for Type1 font replacement when embedding of PDF files
- */
-
-fm_entry *lookup_fontmap(char *ps_name)
-{
- fm_entry *fm, *fm2, tmp;
- char *a, *b, *c, *d, *e, *s;
- int i, sl, ex;
- struct avl_traverser t, t2;
- if (tfm_tree == NULL)
- fm_read_info(); /* only to read default map file */
- assert(ps_name != NULL);
- s = ps_name;
- if (strlen(ps_name) > 7) { /* check for subsetted name tag */
- for (i = 0; i < 6; i++, s++)
- if (*s < 'A' || *s > 'Z')
- break;
- if (i == 6 && *s == '+')
- s++; /* if name tag found, skip behind it */
- else
- s = ps_name;
- }
-
- /*
- * Scan -Slant_<slant> and -Extend_<extend> font name extensions;
- * three valid formats:
- * <fontname>-Slant_<slant>
- * <fontname>-Slant_<slant>-Extend_<extend>
- * <fontname>-Extend_<extend>
- * Slant entry must come _before_ Extend entry
- */
-
- tmp.slant = 0;
- tmp.extend = 0;
- if ((a = strstr(s, "-Slant_")) != NULL) {
- b = a + strlen("-Slant_");
- sl = (int) strtol(b, &e, 10);
- if ((e != b) && (e == strend(b))) {
- tmp.slant = sl;
- *a = '\0'; /* ps_name string ends before "-Slant_" */
- } else {
- if (e != b) { /* only if <slant> is valid number */
- if ((c = strstr(e, "-Extend_")) != NULL) {
- d = c + strlen("-Extend_");
- ex = (int) strtol(d, &e, 10);
- if ((e != d) && (e == strend(d))) {
- tmp.slant = sl;
- tmp.extend = ex;
- *a = '\0'; /* ps_name string ends before "-Slant_" */
- }
- }
- }
- }
- } else {
- if ((a = strstr(s, "-Extend_")) != NULL) {
- b = a + strlen("-Extend_");
- ex = (int) strtol(b, &e, 10);
- if ((e != b) && (e == strend(b))) {
- tmp.extend = ex;
- *a = '\0'; /* ps_name string ends before "-Extend_" */
- }
- }
- }
- tmp.ps_name = s;
-
- fm = (fm_entry *) avl_t_find(&t, ps_tree, &tmp);
if (fm == NULL)
- return NULL; /* no entry found */
-
- /* at this point we know there is at least one fm_entry with given ps_name;
- * we test all such entries and return the first one that is valid for font
- * replacement */
-
- t2 = t;
- fm2 = (fm_entry *) avl_t_prev(&t2);
-
- /* search forward */
- do {
- if (fm_valid_for_font_replacement(fm))
- return fm;
- fm = (fm_entry *) avl_t_next(&t);
- } while (fm != NULL && comp_fm_entry_ps(fm, &tmp, NULL) == 0);
-
- /* search backward */
- while (fm2 != NULL && comp_fm_entry_ps(fm2, &tmp, NULL) == 0) {
- if (fm_valid_for_font_replacement(fm2))
- return fm2;
- fm2 = (fm_entry *) avl_t_prev(&t2);
- }
-
- return NULL;
+ return NULL;
+ set_inuse(fm);
+ return fm;
}
/**********************************************************************/
@@ -821,7 +589,7 @@ fm_entry *lookup_fontmap(char *ps_name)
* ignored.
*/
-static void process_map_item(char *s, int type)
+void process_map_item(char *s, int type)
{
char *p;
int mode;
@@ -868,19 +636,21 @@ static void process_map_item(char *s, int type)
}
}
-void pdfmapfile(integer t)
+void pdfmapfile(int t)
{
- process_map_item(makecstring(tokens_to_string(t)), MAPFILE);
- flush_str(last_tokens_string);
+ char *s = tokenlist_to_cstring(t, true, NULL);
+ process_map_item(s, MAPFILE);
+ free(s);
}
-void pdfmapline(integer t)
+void pdfmapline(int t)
{
- process_map_item(makecstring(tokens_to_string(t)), MAPLINE);
- flush_str(last_tokens_string);
+ char *s = tokenlist_to_cstring(t, true, NULL);
+ process_map_item(s, MAPLINE);
+ free(s);
}
-void pdf_init_map_file(string map_name)
+void pdf_init_map_file(char *map_name)
{
assert(mitem == NULL);
mitem = xtalloc(1, mapitem);
@@ -898,7 +668,7 @@ void pdf_init_map_file(string map_name)
* same fonts are to be embedded.
*
* The ff_tree contains only font files, which are actually needed,
- * so this tree typically is much smaller than the tfm_tree or ps_tree.
+ * so this tree typically is much smaller than the tfm_tree.
*/
ff_entry *check_ff_exist(char *ff_name, boolean is_tt)
@@ -958,21 +728,7 @@ static void destroy_fm_entry_tfm(void *pa, void *pb)
fm_entry *fm;
(void) pb;
fm = (fm_entry *) pa;
- if (!has_pslink(fm))
- delete_fm_entry(fm);
- else
- unset_tfmlink(fm);
-}
-
-static void destroy_fm_entry_ps(void *pa, void *pb)
-{
- fm_entry *fm;
- (void) pb;
- fm = (fm_entry *) pa;
- if (!has_tfmlink(fm))
- delete_fm_entry(fm);
- else
- unset_pslink(fm);
+ delete_fm_entry(fm);
}
static void destroy_ff_entry(void *pa, void *pb)
@@ -989,15 +745,8 @@ void fm_free(void)
avl_destroy(tfm_tree, destroy_fm_entry_tfm);
tfm_tree = NULL;
}
- if (ps_tree != NULL) {
- avl_destroy(ps_tree, destroy_fm_entry_ps);
- ps_tree = NULL;
- }
if (ff_tree != NULL) {
avl_destroy(ff_tree, destroy_ff_entry);
ff_tree = NULL;
}
}
-
-/**********************************************************************/
-/* end of mapfile.c */
diff --git a/Build/source/texk/web2c/luatexdir/font/pkin.c b/Build/source/texk/web2c/luatexdir/font/pkin.w
index 0576901ba65..077680eb596 100644
--- a/Build/source/texk/web2c/luatexdir/font/pkin.c
+++ b/Build/source/texk/web2c/luatexdir/font/pkin.w
@@ -1,57 +1,65 @@
-/* pkin.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-/*
- * NAME
- * pkin.c - implementation of readchar()
- * DESCRIPTION
- * This implementation of readchar() uses parts of the program dvips
- * written by Tomas Rokicki--the inventor of the pkformat--(loadfont.c,
- * download.c and unpack.c). Dvips in turn is derived from pktype.
- * Pktype(TeX) is described in debt in ``The PKtype processor'',
- * which is available as pktype.weave as part of the METAFONTware.
- * What was needed to implement readchar() is rearranged in pkfile.c to
- * get more modularity in the style of MODULA2.
- * BUGFIXES
- * May 1997: Eric Delaunay <delaunay@lix.polytechnique.fr> reports a
- * problem with huge fonts (greater than 1008 DPI). The code for
- * handling PK characters in `extended format' was wrongly derived
- * from dvips. Made some minor improvements regarding error handling.
- * REDESIGN
- * Piet Tutelaers
- * rcpt@urc.tue.nl
- *
- * Modified for use with pdftex by Han The Thanh <thanh@fi.muni.cz>.
- */
-
+% pkin.w
+%
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2008 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.
+%
+% 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 <http://www.gnu.org/licenses/>.
+
+@
+NAME
+
+pkin.c - implementation of readchar()
+
+DESCRIPTION
+
+This implementation of readchar() uses parts of the program dvips
+written by Tomas Rokicki--the inventor of the pkformat--(loadfont.c,
+download.c and unpack.c). Dvips in turn is derived from pktype.
+Pktype(TeX) is described in debt in ``The PKtype processor'',
+which is available as pktype.weave as part of the METAFONTware.
+What was needed to implement readchar() is rearranged in pkfile.c to
+get more modularity in the style of MODULA2.
+
+BUGFIXES
+
+May 1997: Eric Delaunay <delaunay@@lix.polytechnique.fr> reports a
+problem with huge fonts (greater than 1008 DPI). The code for
+handling PK characters in `extended format' was wrongly derived
+from dvips. Made some minor improvements regarding error handling.
+
+REDESIGN
+
+Piet Tutelaers <rcpt@@urc.tue.nl>
+
+Modified for use with pdftex by Han The Thanh <thanh@@fi.muni.cz>.
+
+@c
#include "ptexlib.h"
-#include "luatexfont.h"
-static const char _svn_version[] =
- "$Id: pkin.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/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.
- */
+typedef short shalfword;
+static const char _svn_version[] =
+ "$Id: pkin.w 3584 2010-04-02 17:45:55Z hhenkel $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/pkin.w $";
+
+@
+Now we have some routines to get stuff from the pk file. pkbyte returns
+the next byte from the pk file.
+
+@c
static shalfword pkbyte(void)
{
register shalfword i;
@@ -61,9 +69,9 @@ static shalfword pkbyte(void)
return (i);
}
-static integer pkduo(void)
+static int pkduo(void)
{
- register integer i;
+ register int i;
i = pkbyte();
if (i > 127)
@@ -72,9 +80,9 @@ static integer pkduo(void)
return (i);
}
-static integer pktrio(void)
+static int pktrio(void)
{
- register integer i;
+ register int i;
i = pkbyte();
if (i > 127)
@@ -84,9 +92,9 @@ static integer pktrio(void)
return (i);
}
-static integer pkquad(void)
+static int pkquad(void)
{
- register integer i;
+ register int i;
i = pkbyte();
if (i > 127)
@@ -97,15 +105,14 @@ static integer pkquad(void)
return (i);
}
-/*
- * The next part is devoted to unpacking the character data.
- */
-/*
- * We need procedures to get a nybble, bit, and packed word from the
- * packed data structure.
- */
+@ The next part is devoted to unpacking the character data.
+
+@ We need procedures to get a nybble, bit, and packed word from the
+packed data structure.
+
+@c
static halfword inputbyte, flagbyte;
static halfword bitweight;
static halfword dynf;
@@ -122,7 +129,7 @@ static shalfword getnyb(void)
bitweight = 0;
temp = inputbyte & 15;
}
- return (temp);
+ return (shalfword) (temp);
}
static boolean getbit(void)
@@ -150,8 +157,8 @@ static halfword pkpackednum(void)
} while (!(j != 0));
if (i > 3) {
/*
- * Damn, we got a huge count! We *fake* it by giving an artificially
- * large repeat count.
+ Damn, we got a huge count! We {\it fake} it by giving an artificially
+ large repeat count.
*/
return (handlehuge(i, j));
} else {
@@ -189,7 +196,7 @@ static halfword rest(void)
pk_remainder = 4000 - pk_remainder;
return (4000);
} else {
- i = pk_remainder;
+ i = (halfword) pk_remainder;
pk_remainder = 0;
realfunc = pkpackednum;
return (i);
@@ -213,17 +220,17 @@ static halfword handlehuge(halfword i, halfword k)
return (rest());
}
-/*
- * And now we have our unpacking routine.
- */
+@ And now we have our unpacking routine.
+
+@c
static halfword gpower[17] = { 0, 1, 3, 7, 15, 31, 63, 127,
255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535
};
static void unpack(chardesc * cd)
{
- register integer i, j;
+ register int i, j;
register halfword word, wordweight;
halfword *raster;
shalfword rowsleft;
@@ -232,14 +239,14 @@ static void unpack(chardesc * cd)
halfword count;
shalfword wordwidth;
- wordwidth = (cd->cwidth + 15) / 16;
- i = 2 * cd->cheight * (long) wordwidth;
+ wordwidth = (shalfword) ((cd->cwidth + 15) / 16);
+ i = (int) (2 * cd->cheight * (long) wordwidth);
if (i <= 0)
i = 2;
if (i > cd->rastersize) {
xfree(cd->raster);
cd->rastersize = i;
- cd->raster = xtalloc(cd->rastersize, halfword);
+ cd->raster = xtalloc((unsigned) cd->rastersize, halfword);
}
raster = cd->raster;
realfunc = pkpackednum;
@@ -264,8 +271,8 @@ static void unpack(chardesc * cd)
*raster++ = word;
}
} else {
- rowsleft = cd->cheight;
- hbit = cd->cwidth;
+ rowsleft = (shalfword) cd->cheight;
+ hbit = (shalfword) cd->cwidth;
repeatcount = 0;
wordweight = 16;
word = 0;
@@ -282,7 +289,7 @@ static void unpack(chardesc * cd)
if ((count < wordweight) && (count < hbit)) {
if (turnon)
word += gpower[wordweight] - gpower[wordweight - count];
- hbit -= count;
+ hbit = (shalfword) (hbit - count);
wordweight -= count;
count = 0;
} else if ((count >= hbit) && (hbit <= wordweight)) {
@@ -295,50 +302,44 @@ static void unpack(chardesc * cd)
raster++;
}
}
- rowsleft -= repeatcount + 1;
+ rowsleft = (shalfword) (rowsleft - repeatcount - 1);
repeatcount = 0;
word = 0;
wordweight = 16;
count -= hbit;
- hbit = cd->cwidth;
+ hbit = (shalfword) cd->cwidth;
} else {
if (turnon)
word += gpower[wordweight];
*raster++ = word;
word = 0;
count -= wordweight;
- hbit -= wordweight;
+ hbit = (shalfword) (hbit - wordweight);
wordweight = 16;
}
}
turnon = !turnon;
}
- if ((rowsleft != 0) || ((integer) hbit != cd->cwidth))
+ if ((rowsleft != 0) || ((int) hbit != cd->cwidth))
pdftex_fail("error while unpacking; more bits than required");
}
}
-/*
- * readchar(): the main routine
- * Reads the character definition of character `c' into `cd' if available,
- * return FALSE (0) otherwise.
- */
-
-/*
- * readchar(): the main routine
- * check pk preamble if necessary,
- * read the next character definition into `cd',
- * return EOF if no character definition is available
- */
+@
+|readchar()|: the main routine
+check pk preamble if necessary,
+Reads the character definition of character `c' into `cd' if available,
+return FALSE (0) otherwise.
+@c
int readchar(boolean check_preamble, chardesc * cd)
{
register shalfword i;
- register integer k;
- register integer length = 0;
+ register int k;
+ register int length = 0;
/*
- * Check the preamble of the pkfile
+ Check the preamble of the pkfile
*/
if (check_preamble) {
if (pkbyte() != 247)
@@ -353,7 +354,7 @@ int readchar(boolean check_preamble, chardesc * cd)
k = pkquad(); /* vppp */
}
/*
- * Now we skip to the desired character definition
+ Now we skip to the desired character definition
*/
while ((flagbyte = pkbyte()) != 245) {
if (flagbyte < 240) {
@@ -378,8 +379,8 @@ int readchar(boolean check_preamble, chardesc * cd)
case 4:
case 5:
case 6:
- length = (flagbyte & 3) * 65536L + pkbyte() * 256L;
- length = length + pkbyte() - 4L;
+ length = (int) ((flagbyte & 3) * 65536L + pkbyte() * 256L);
+ length = (int) (length + pkbyte() - 4L);
cd->charcode = pkbyte();
(void) pktrio(); /* TFMwidth */
cd->xescape = pkduo(); /* pixelwidth */
@@ -389,7 +390,7 @@ int readchar(boolean check_preamble, chardesc * cd)
cd->yoff = pkduo();
break;
case 7:
- length = pkquad() - 9L;
+ length = (int) (pkquad() - 9L);
cd->charcode = pkquad();
(void) pkquad(); /* TFMwidth */
cd->xescape = pkquad(); /* pixelwidth */
diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.h b/Build/source/texk/web2c/luatexdir/font/sfnt.h
index 5d9bd2c973f..d41c019ffcf 100644
--- a/Build/source/texk/web2c/luatexdir/font/sfnt.h
+++ b/Build/source/texk/web2c/luatexdir/font/sfnt.h
@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: sfnt.h 2271 2009-04-12 23:42:21Z oneiros $ */
+/* $Id: sfnt.h 3404 2010-01-28 11:17:10Z taco $ */
#ifndef _SFNT_H_
# define _SFNT_H_
@@ -157,7 +157,7 @@ extern int put_big_endian(void *s, LONG q, int n);
# ifdef XETEX
extern sfnt *sfnt_open(FT_Face face, int accept_types);
# elif defined(pdfTeX)
-extern sfnt *sfnt_open(unsigned char *buffer, integer buflen);
+extern sfnt *sfnt_open(unsigned char *buffer, int buflen);
# else
extern sfnt *sfnt_open(FILE * fp);
# endif
@@ -181,8 +181,8 @@ typedef struct {
# 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 NEW(a,b) xmalloc((unsigned)((unsigned)(a)*sizeof(b)))
+# define RENEW(a,b,c) xrealloc(a, (unsigned)((unsigned)(b)*sizeof(c)))
# define TT_ERROR pdftex_fail
# define WARN printf
diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.c b/Build/source/texk/web2c/luatexdir/font/sfnt.w
index 8812cd7fa6c..25fb3fcd086 100644
--- a/Build/source/texk/web2c/luatexdir/font/sfnt.c
+++ b/Build/source/texk/web2c/luatexdir/font/sfnt.w
@@ -1,168 +1,62 @@
-/* sfnt.c
-
- Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
- the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% sfnt.w
+%
+% Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
+% the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr>
+% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-/* Based on dvipdfmx-0.13.2c */
+@ Based on dvipdfmx-0.13.2c
+@c
#if HAVE_CONFIG_H
# include "config.h"
-#endif /* HAVE_CONFIG_H_ */
+#endif /* |HAVE_CONFIG_H_| */
#include <string.h>
-#ifndef pdfTeX
-# include "system.h"
-
-# include "error.h"
-# include "mem.h"
-# include "mfileio.h"
-#else
# include "ptexlib.h"
-#endif
-
-#include "sfnt.h"
+#include "font/sfnt.h"
static const char _svn_version[] =
- "$Id: sfnt.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/sfnt.c $";
-
-#ifdef XETEX
-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;
-}
-
-SIGNED_BYTE ft_signed_byte(sfnt * f)
-{
- int b = ft_unsigned_byte(f);
- if (b >= 0x80)
- b -= 0x100;
- return (SIGNED_BYTE) b;
-}
-
-UNSIGNED_PAIR ft_unsigned_pair(sfnt * f)
-{
- unsigned char buf[2];
- unsigned long length = 2;
+ "$Id: sfnt.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/sfnt.w $";
- 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)
-{
- int p = ft_unsigned_pair(f);
- if (p >= 0x8000U)
- p -= 0x10000U;
+@ type:
- return (SIGNED_PAIR) p;
-}
+ `true' (0x74727565): TrueType (Mac)
-UNSIGNED_QUAD ft_unsigned_quad(sfnt * f)
-{
- unsigned char buf[4];
- unsigned long length = 4;
+ `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper
- if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0)
- TT_ERROR("sfnt: Freetype failure...");
- f->loc += 4;
+ 0x00010000: TrueType (Win)/OpenType
- 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 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;
-}
-#endif
+ `OTTO': PostScript CFF font with OpenType wrapper
+ `ttcf': TrueType Collection
-/*
- * type:
- * `true' (0x74727565): TrueType (Mac)
- * `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper
- * 0x00010000: TrueType (Win)/OpenType
- * `OTTO': PostScript CFF font with OpenType wrapper
- * `ttcf': TrueType Collection
-*/
+@c
#define SFNT_TRUETYPE 0x00010000UL
#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 *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)
+sfnt *sfnt_open(unsigned char *buffer, int buflen)
{
sfnt *sfont;
ULONG type;
@@ -188,40 +82,6 @@ sfnt *sfnt_open(unsigned char *buffer, integer buflen)
sfont->directory = NULL;
return sfont;
}
-# else
-sfnt *sfnt_open(FILE * fp)
-{
- sfnt *sfont;
- ULONG type;
-
- ASSERT(fp);
-
- rewind(fp);
-
- sfont = NEW(1, sfnt);
-
- sfont->stream = fp;
-
- 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;
- }
-
- rewind(sfont->stream);
-
- sfont->directory = NULL;
-
- return sfont;
-}
-# endif
-#endif
static void release_directory(struct sfnt_table_directory *td)
{
@@ -269,9 +129,9 @@ int put_big_endian(void *s, LONG q, int n)
return n;
}
-/* Convert four-byte number to big endianess
- * in a machine independent way.
- */
+@ Convert four-byte number to big endianess in a machine independent way.
+
+@c
static void convert_tag(char *tag, unsigned long u_tag)
{
int i;
@@ -284,9 +144,10 @@ static void convert_tag(char *tag, unsigned long u_tag)
return;
}
-/*
- * Computes the max power of 2 <= n
- */
+
+@ Computes the max power of 2 <= n
+
+@c
static unsigned max2floor(unsigned n)
{
int val = 1;
@@ -296,12 +157,13 @@ static unsigned max2floor(unsigned n)
val *= 2;
}
- return val;
+ return (unsigned) val;
}
-/*
- * Computes the log2 of the max power of 2 <= n
- */
+
+@ Computes the log2 of the max power of 2 <= n
+
+@c
static unsigned log2floor(unsigned n)
{
unsigned val = 0;
@@ -314,16 +176,17 @@ static unsigned log2floor(unsigned n)
return val;
}
+@ @c
static ULONG sfnt_calc_checksum(void *data, ULONG length)
{
ULONG chksum = 0;
BYTE *p, *endptr;
- int count = 0;
+ ULONG count = 0;
p = (BYTE *) data;
endptr = p + length;
while (p < endptr) {
- chksum += (p[0] << (8 * (3 - count)));
+ chksum = chksum + (ULONG) (p[0] << (8 * (3 - count)));
count = ((count + 1) & 3);
p++;
}
@@ -331,6 +194,7 @@ static ULONG sfnt_calc_checksum(void *data, ULONG length)
return chksum;
}
+@ @c
static int find_table_index(struct sfnt_table_directory *td, const char *tag)
{
int idx;
@@ -346,6 +210,7 @@ static int find_table_index(struct sfnt_table_directory *td, const char *tag)
return -1;
}
+@ @c
void sfnt_set_table(sfnt * sfont, const char *tag, void *data, ULONG length)
{
struct sfnt_table_directory *td;
@@ -371,6 +236,7 @@ void sfnt_set_table(sfnt * sfont, const char *tag, void *data, ULONG length)
return;
}
+@ @c
ULONG sfnt_find_table_len(sfnt * sfont, const char *tag)
{
ULONG length;
@@ -390,6 +256,7 @@ ULONG sfnt_find_table_len(sfnt * sfont, const char *tag)
return length;
}
+@ @c
ULONG sfnt_find_table_pos(sfnt * sfont, const char *tag)
{
ULONG offset;
@@ -409,6 +276,7 @@ ULONG sfnt_find_table_pos(sfnt * sfont, const char *tag)
return offset;
}
+@ @c
ULONG sfnt_locate_table(sfnt * sfont, const char *tag)
{
ULONG offset;
@@ -419,11 +287,12 @@ ULONG sfnt_locate_table(sfnt * sfont, const char *tag)
if (offset == 0)
TT_ERROR("sfnt: table not found...");
- sfnt_seek_set(sfont, offset);
+ sfnt_seek_set(sfont, (long) offset);
return offset;
}
+@ @c
int sfnt_read_table_directory(sfnt * sfont, ULONG offset)
{
struct sfnt_table_directory *td;
@@ -435,15 +304,8 @@ int sfnt_read_table_directory(sfnt * sfont, ULONG offset)
release_directory(sfont->directory);
sfont->directory = td = NEW(1, struct sfnt_table_directory);
-#ifdef XETEX
- ASSERT(sfont->ft_face);
-#elif defined(pdfTeX)
ASSERT(sfont->buffer);
-#else
- ASSERT(sfont->stream);
-#endif
-
- sfnt_seek_set(sfont, offset);
+ sfnt_seek_set(sfont, (long) offset);
td->version = sfnt_get_ulong(sfont);
td->num_tables = sfnt_get_ushort(sfont);
@@ -471,6 +333,7 @@ int sfnt_read_table_directory(sfnt * sfont, ULONG offset)
return 0;
}
+@ @c
int sfnt_require_table(sfnt * sfont, const char *tag, int must_exist)
{
struct sfnt_table_directory *td;
@@ -491,36 +354,28 @@ int sfnt_require_table(sfnt * sfont, const char *tag, int must_exist)
return 0;
}
-#ifndef pdfTeX
-# include "pdfobj.h"
-#endif
-
-/*
- * o All tables begin on four byte boundries, and pad any remaining space
- * between tables with zeros
- *
- * o Entries in the Table Directory must be sorted in ascending order by tag
- *
- * o The head table contains checksum of the whole font file.
- * To compute: first set it to 0, sum the entire font as ULONG,
- * then store 0xB1B0AFBA - sum.
- */
-
-#ifdef pdfTeX
-# include "luatexfont.h"
+
+
+@ All tables begin on four byte boundries, and pad any remaining space
+ between tables with zeros
+
+ Entries in the Table Directory must be sorted in ascending order by tag
+
+ The head table contains checksum of the whole font file.
+ To compute: first set it to 0, sum the entire font as ULONG,
+ then store 0xB1B0AFBA - sum.
+
+@c
+# include "font/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 };
pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont)
{
pdf_obj *stream;
-#ifndef pdfTeX
- pdf_obj *stream_dict;
-#endif
struct sfnt_table_directory *td;
long offset, nb_read, length;
int i, sr;
@@ -534,9 +389,9 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont)
/* Header */
p = (char *) wbuf;
- p += sfnt_put_ulong(p, td->version);
+ p += sfnt_put_ulong(p, (LONG) td->version);
p += sfnt_put_ushort(p, td->num_kept_tables);
- sr = max2floor(td->num_kept_tables) * 16;
+ sr = (int) (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);
@@ -544,7 +399,7 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont)
pdf_add_stream(stream, wbuf, 12);
/*
- * Compute start of actual tables (after headers).
+ Compute start of actual tables (after headers).
*/
offset = 12 + 16 * td->num_kept_tables;
for (i = 0; i < td->num_tables; i++) {
@@ -557,12 +412,12 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont)
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, (LONG) td->tables[i].check_sum);
p += sfnt_put_ulong(p, offset);
- p += sfnt_put_ulong(p, td->tables[i].length);
+ p += sfnt_put_ulong(p, (LONG) td->tables[i].length);
pdf_add_stream(stream, wbuf, 16);
- offset += td->tables[i].length;
+ offset = (long) (offset + (long) td->tables[i].length);
}
}
@@ -575,23 +430,17 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont)
offset += length;
}
if (!td->tables[i].data) {
-#ifdef XETEX
- if (!sfont->ft_face)
-#elif defined(pdfTeX)
if (!sfont->buffer)
-#else
- 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);
+ length = (long) td->tables[i].length;
+ sfnt_seek_set(sfont, (long) td->tables[i].offset);
while (length > 0) {
- nb_read = sfnt_read(wbuf, MIN(length, 1024), sfont);
+ nb_read = sfnt_read(wbuf, (int) MIN(length, 1024), sfont);
if (nb_read < 0) {
pdf_release_obj(stream);
TT_ERROR("Reading file failed...");
@@ -604,18 +453,14 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont)
} else {
pdf_add_stream(stream,
(unsigned char *) td->tables[i].data,
- td->tables[i].length);
+ (long) td->tables[i].length);
RELEASE(td->tables[i].data);
td->tables[i].data = NULL;
}
/* Set offset for next table */
- offset += td->tables[i].length;
+ offset = (long) (offset + (long) 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));
-#endif
return stream;
}
diff --git a/Build/source/texk/web2c/luatexdir/font/subfont.txt b/Build/source/texk/web2c/luatexdir/font/subfont.txt
index 9fe053cbb9c..eaefae02813 100644
--- a/Build/source/texk/web2c/luatexdir/font/subfont.txt
+++ b/Build/source/texk/web2c/luatexdir/font/subfont.txt
@@ -1,74 +1,43 @@
-map entry:
+map entry:cyberb @ Unicode @ <cyberbit.ttf PidEid = 3, 1 means cyberb < INFIX > = >look at Unicode.sfd = >find the mapping = >charcode = >PidEid = 3, 1 = >glyphs eg cyberb01 = >subfont 01 in Unicode.sfd = >charcodes Infix can be anything, thus the question:given a tfm name, how to find out
+ whether this is a subfont ?
+ It is safe to limit the infix to be composed from hexadecimal digits only ?
+ If so, one possibility is : (1)
+ while last
+ -char -of - tfmname is a hexdigit
+ do
+ remove the last char from tfmname
+ do
+ a lookup for the tfmname
+ if found an entry with subfont flag then break enddo(2)
+ Or, when a map entry with subfont flag is scanned,
+ let pdftex create all the relevant entries.
+ Which may be a safer and faster solution(but wastes more memory)
-cyberb@Unicode@ <cyberbit.ttf PidEid=3,1
-means
-
-cyberb<INFIX> => look at Unicode.sfd => find the mapping => charcode
- => PidEid=3,1 => glyphs
-
-eg cyberb01 => subfont 01 in Unicode.sfd => charcodes
-
-Infix can be anything, thus the question: given a tfm name, how to find out
-whether this is a subfont?
-
-It is safe to limit the infix to be composed from hexadecimal digits only?
-
-If so, one possibility is:
-
-(1)
-while last-char-of-tfmname is a hexdigit do
- remove the last char from tfmname
- do a lookup for the tfmname
- if found an entry with subfont flag then
- break
-enddo
-
-(2)
-Or, when a map entry with subfont flag is scanned, let pdftex create all
-the relevant entries. Which may be a safer and faster solution (but wastes more
-memory)
-
-
-Let's do (2), as infix can be any word.
+ Let 's do (2), as infix can be any word.
Implementation:
-- let's have a map entry:
-
-cyberb@Unicode@ <cyberbit.ttf PidEid=3,1
-
-- actions:
- - read Unicode.sfd
- - create corresponding sfd mapping like ("01", "Unicode") => long[256]
- - added those subfont to an AVL tree
- - create map entries for cyberb01--cyberbff, each has a pointer to the
- corresponding sfd mapping entry
-
-- extended attributes for map entry:
- - Pid
- - Eid
- - sfd_map
-
-- sfd_mapping:
- - name: sfd name, eg "Unicode"
- - infix, eg "01"
- - mapping: long[256]
-
-- how to find out whether a sfd has been loaded:
- - lookup for any entry with the given sfd name
-
-- functions:
- - load_sfd
- - lookup_subfont
- - extend reading map entries
-
-- when writting ttf:
- - if re-encoded --> process like in case of type1 fonts
- - if PidEid is being used:
- - read cmap tables: store (ttfname, pid, eid)
- - search for used chars
- - use sfd to find the charcodes
- - look into cmap to
+- let' s have a map entry : cyberb @ Unicode @ <cyberbit.ttf PidEid = 3, 1 - actions:
+ -read Unicode.sfd
+ - create corresponding sfd mapping like("01", "Unicode") =
+ >long[256]
+ - added those subfont to an AVL tree -
+ create map entries for cyberb01-- cyberbff,
+ each has a pointer to the corresponding sfd mapping entry -
+ extended attributes for map entry:-Pid - Eid - sfd_map -
+ sfd_mapping:-name:sfd name, eg "Unicode" - infix,
+ eg "01" - mapping:long[256]
+
+-how to find out whether a sfd has been loaded:
+ -lookup for any entry with the given sfd
+ name - functions:-load_sfd -
+ lookup_subfont -
+ extend reading map entries -
+ when writting ttf:-if re - encoded-- >
+ process like in case of type1 fonts -
+ if PidEid is being used:-read cmap
+ tables:store(ttfname, pid, eid)
+ -search for used chars - use sfd to find the charcodes - look into cmap to
diff --git a/Build/source/texk/web2c/luatexdir/font/subfont.c b/Build/source/texk/web2c/luatexdir/font/subfont.w
index 183c78b4f34..5ae8639bb41 100644
--- a/Build/source/texk/web2c/luatexdir/font/subfont.c
+++ b/Build/source/texk/web2c/luatexdir/font/subfont.w
@@ -1,39 +1,42 @@
-/* subfont.c
-
- Copyright 2005-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% subfont.w
+%
+% Copyright 2005-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
#include "ptexlib.h"
#include <string.h>
static const char _svn_version[] =
- "$Id: subfont.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/subfont.c $";
+ "$Id: subfont.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/subfont.w $";
+@ @c
static struct avl_table *sfd_tree = NULL;
static unsigned char *sfd_buffer = NULL;
-static integer sfd_size = 0;
-static integer sfd_curbyte = 0;
+static int sfd_size = 0;
+static int sfd_curbyte = 0;
#define SFD_BUF_SIZE SMALL_BUF_SIZE
#define sfd_close() xfclose(sfd_file, cur_file_name)
-#define sfd_open() (sfd_file = fopen((char *) nameoffile + 1, FOPEN_RBIN_MODE))
+#define sfd_open(a) (sfd_file = fopen((char *)(a), FOPEN_RBIN_MODE))
#define sfd_read_file() readbinfile(sfd_file,&sfd_buffer,&sfd_size)
#define sfd_getchar() sfd_buffer[sfd_curbyte++]
@@ -96,7 +99,7 @@ void sfd_free(void)
static void sfd_getline(boolean expect_eof)
{
char *p;
- int c;
+ char c;
restart:
if (sfd_eof()) {
if (expect_eof)
@@ -106,7 +109,7 @@ static void sfd_getline(boolean expect_eof)
}
p = sfd_line;
do {
- c = sfd_getchar();
+ c = (char) 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);
@@ -114,12 +117,13 @@ static void sfd_getline(boolean expect_eof)
goto restart;
}
+@ @c
static sfd_entry *read_sfd(char *sfd_name)
{
void **aa;
sfd_entry *sfd, tmp_sfd;
subfont_entry *sf;
- char *ftemp = NULL;
+
char buf[SMALL_BUF_SIZE], *p;
long int i, j, k;
int n;
@@ -134,44 +138,30 @@ static sfd_entry *read_sfd(char *sfd_name)
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;
- }
+ xfree(sfd_buffer);
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);
+ cur_file_name = luatex_find_file(sfd_name, find_sfd_file_callback);
+ if (cur_file_name) {
+ 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(cur_file_name)) {
+ pdftex_warn("cannot open SFD file for reading");
+ cur_file_name = NULL;
+ return NULL;
+ }
+ sfd_read_file();
+ sfd_close();
}
- } 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("%s", cur_file_name);
@@ -220,6 +210,7 @@ static sfd_entry *read_sfd(char *sfd_name)
return sfd;
}
+@ @c
boolean handle_subfont_fm(fm_entry * fm, int mode)
{
size_t l;
@@ -230,16 +221,16 @@ boolean handle_subfont_fm(fm_entry * fm, int mode)
char buf[SMALL_BUF_SIZE];
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 != (int) 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 */
+ l = (size_t) (r - (q + 1)); /* length of sfd name */
strncpy(buf, q + 1, l);
buf[l] = 0;
check_buf(strlen(buf) + 4, SMALL_BUF_SIZE);
@@ -250,13 +241,12 @@ boolean handle_subfont_fm(fm_entry * fm, int mode)
/* at this point we know fm is a subfont */
set_subfont(fm);
xfree(fm->ps_name);
- fm->ps_name = NULL;
/* set default values for PidEid */
if (fm->pid == -1) {
fm->pid = 3;
fm->eid = 1;
}
- l = q - p; /* length of base tfm name (prefix) */
+ l = (size_t) (q - p); /* length of base tfm name (prefix) */
for (sf = sfd->subfont; sf != NULL; sf = sf->next) {
strncpy(buf, p, l);
buf[l] = 0;
diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.h b/Build/source/texk/web2c/luatexdir/font/texfont.h
index 4963f71cad2..6a021726748 100644
--- a/Build/source/texk/web2c/luatexdir/font/texfont.h
+++ b/Build/source/texk/web2c/luatexdir/font/texfont.h
@@ -1,6 +1,6 @@
/* texfont.h Main font API implementation for the pascal parts
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,31 +17,29 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: texfont.h 2448 2009-06-08 07:43:50Z taco $ */
+/* $Id: texfont.h 3482 2010-03-13 11:18:28Z 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
keep web2c happy */
/* this file is read at the end of ptexlib.h, which is called for at
- the end of luatexcoerce.h, as well as from the C sources
+ the end of luatexcoerce.h, as well as from the C sources
*/
#ifndef TEXFONT_H
# define TEXFONT_H
-# include "luatexdir/managed-sa.h"
-
# define pointer halfword
typedef struct liginfo {
- integer adj;
- integer lig;
+ int adj;
+ int lig;
char type;
} liginfo;
typedef struct kerninfo {
- integer adj;
+ int adj;
scaled sc;
} kerninfo;
@@ -53,23 +51,23 @@ typedef struct extinfo {
int advance;
int extender;
} extinfo;
-
+/* todo: maybe create a 'math info structure' */
typedef struct charinfo {
char *name; /* postscript character name */
liginfo *ligatures; /* ligature items */
kerninfo *kerns; /* kern items */
- real_eight_bits *packets; /* virtual commands. */
+ eight_bits *packets; /* virtual commands. */
unsigned short index; /* CID index */
- integer remainder; /* spare value for odd items, could be union-ed with extensible */
+ int 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 */
+ int ef; /* font expansion factor */
+ int lp; /* left protruding factor */
+ int rp; /* right protruding factor */
char tag; /* list / ext taginfo */
char used; /* char is typeset ? */
char *tounicode; /* unicode equivalent */
@@ -85,20 +83,6 @@ typedef struct charinfo {
scaled *bottom_left_math_kern_array;
} charinfo;
-
-/* this is for speed reasons, it is called from the web source
- when more than two of the traditional four char values are needed
- at the same time. the structure |charinfo_short| is defined in
- web */
-
-# ifndef luaTeX
-typedef struct charinfo_short {
- scaled ci_wd; /* width */
- scaled ci_ht; /* height */
- scaled ci_dp; /* depth */
-} charinfo_short;
-# endif
-
# define EXT_NORMAL 0
# define EXT_REPEAT 1
@@ -114,66 +98,69 @@ 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);
+extern scaled_whd get_charinfo_whd(internal_font_number f, int c);
typedef struct texfont {
- integer _font_size;
- integer _font_dsize;
+ int _font_size;
+ int _font_dsize;
+ int _font_units_per_em;
char *_font_name;
char *_font_area;
char *_font_filename;
char *_font_fullname;
+ char *_font_psname;
char *_font_encodingname;
char *_font_cidregistry;
char *_font_cidordering;
- integer _font_cidversion;
- integer _font_cidsupplement;
+ int _font_cidversion;
+ int _font_cidsupplement;
- integer _font_ec;
+ int _font_ec;
unsigned _font_checksum; /* internal information */
char _font_used; /* internal information */
char _font_touched; /* internal information */
- integer _font_cache_id; /* internal information */
+ int _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 */
+
+ int _font_slant; /* a slant in ppt */
+ int _font_extend; /* an extension in ppt, or 1000 */
+ int _font_expand_ratio; /* expansion ratio of a particular font */
+ internal_font_number _font_shrink; /* font at limit of shrinking */
+ internal_font_number _font_stretch; /* font at limit of stretching */
+ int _font_step; /* amount of one step of expansion */
+ boolean _font_auto_expand; /* this font is auto-expanded? */
+
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;
+ fm_entry *_font_map;
+ int _font_type;
+ int _font_format;
+ int _font_embedding;
+ int _font_bc;
+ int _hyphen_char;
+ int _skew_char;
+ int _font_natural_dir;
charinfo *_left_boundary;
charinfo *_right_boundary;
- integer _font_params;
+ int _font_params;
scaled *_param_base;
- integer _font_math_params;
+ int _font_math_params;
scaled *_math_param_base;
sa_tree characters;
- integer charinfo_count;
- integer charinfo_size;
+ int charinfo_count;
+ int charinfo_size;
charinfo *charinfo;
int *charinfo_cache;
- integer ligatures_disabled;
+ int ligatures_disabled;
- integer _pdf_font_num; /* maps to a PDF resource ID */
- scaled _pdf_font_size; /* maps to a PDF font size */
+ int _pdf_font_num; /* maps to a PDF resource ID */
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;
@@ -216,19 +203,20 @@ extern const char *font_embedding_strings[];
# define font_dsize(a) font_tables[a]->_font_dsize
# define set_font_dsize(a,b) font_dsize(a) = b
+# define font_units_per_em(a) font_tables[a]->_font_units_per_em
+# define set_font_units_per_em(a,b) font_units_per_em(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))
-boolean cmp_font_name(integer, str_number);
-
# 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, str_number);
+boolean cmp_font_area(int, str_number);
# define font_reassign(a,b) { if (a!=NULL) free(a); a = b; }
@@ -238,11 +226,12 @@ boolean cmp_font_area(integer, str_number);
# define font_fullname(a) font_tables[a]->_font_fullname
# define set_font_fullname(f,b) font_reassign(font_fullname(f),b)
+# define font_psname(a) font_tables[a]->_font_psname
+# define set_font_psname(f,b) font_reassign(font_psname(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);
-
# 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 || \
@@ -300,6 +289,21 @@ boolean font_shareable(internal_font_number, internal_font_number);
# define font_extend(a) font_tables[a]->_font_extend
# define set_font_extend(a,b) font_extend(a) = b
+# define font_expand_ratio(a) font_tables[a]->_font_expand_ratio
+# define set_font_expand_ratio(a,b) font_expand_ratio(a) = b
+
+# define font_shrink(a) font_tables[a]->_font_shrink
+# define set_font_shrink(a,b) font_shrink(a) = b
+
+# define font_stretch(a) font_tables[a]->_font_stretch
+# define set_font_stretch(a,b) font_stretch(a) = b
+
+# define font_step(a) font_tables[a]->_font_step
+# define set_font_step(a,b) font_step(a) = b
+
+# define font_auto_expand(a) font_tables[a]->_font_auto_expand
+# define set_font_auto_expand(a,b) font_auto_expand(a) = b
+
# define font_tounicode(a) font_tables[a]->_font_tounicode
# define set_font_tounicode(a,b) font_tounicode(a) = b
@@ -312,32 +316,14 @@ boolean font_shareable(internal_font_number, internal_font_number);
# 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_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_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_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_blink(a) font_tables[a]->_pdf_font_blink
+# define set_pdf_font_blink(a,b) pdf_font_blink(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_elink(a) font_tables[a]->_pdf_font_elink
+# define set_pdf_font_elink(a,b) pdf_font_elink(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
@@ -412,9 +398,15 @@ typedef enum {
top_left_kern = 4
} font_math_kern_codes;
-extern charinfo *get_charinfo(internal_font_number f, integer c);
-extern integer char_exists(internal_font_number f, integer c);
-extern charinfo *char_info(internal_font_number f, integer c);
+extern charinfo *get_charinfo(internal_font_number f, int c);
+extern int char_exists(internal_font_number f, int c);
+extern charinfo *char_info(internal_font_number f, int c);
+
+/* Here is a quick way to test if a glyph exists, when you are
+already certain the font |f| exists, and that the |c| is a regular
+glyph id, not one of the two special boundary objects.
+*/
+# define quick_char_exists(f,c) get_sa_item(font_tables[f]->characters,c)
extern void set_charinfo_width(charinfo * ci, scaled val);
extern void set_charinfo_height(charinfo * ci, scaled val);
@@ -430,7 +422,7 @@ extern void set_charinfo_name(charinfo * ci, char *val);
extern void set_charinfo_tounicode(charinfo * ci, char *val);
extern void set_charinfo_ligatures(charinfo * ci, liginfo * val);
extern void set_charinfo_kerns(charinfo * ci, kerninfo * val);
-extern void set_charinfo_packets(charinfo * ci, real_eight_bits * val);
+extern void set_charinfo_packets(charinfo * ci, eight_bits * val);
extern void set_charinfo_extensible(charinfo * ci, int a, int b, int c, int d);
extern void set_charinfo_ef(charinfo * ci, scaled val);
extern void set_charinfo_lp(charinfo * ci, scaled val);
@@ -452,23 +444,23 @@ extern scaled get_charinfo_italic(charinfo * ci);
extern scaled get_charinfo_top_accent(charinfo * ci);
extern scaled get_charinfo_bot_accent(charinfo * ci);
extern char get_charinfo_tag(charinfo * ci);
-extern integer get_charinfo_remainder(charinfo * ci);
+extern int get_charinfo_remainder(charinfo * ci);
extern char get_charinfo_used(charinfo * ci);
-extern integer get_charinfo_index(charinfo * ci);
+extern int get_charinfo_index(charinfo * ci);
extern char *get_charinfo_name(charinfo * ci);
extern char *get_charinfo_tounicode(charinfo * ci);
extern liginfo *get_charinfo_ligatures(charinfo * ci);
extern kerninfo *get_charinfo_kerns(charinfo * ci);
-extern real_eight_bits *get_charinfo_packets(charinfo * ci);
-extern integer get_charinfo_ef(charinfo * ci);
-extern integer get_charinfo_rp(charinfo * ci);
-extern integer get_charinfo_lp(charinfo * ci);
-extern integer get_charinfo_extensible(charinfo * ci, int which);
+extern eight_bits *get_charinfo_packets(charinfo * ci);
+extern int get_charinfo_ef(charinfo * ci);
+extern int get_charinfo_rp(charinfo * ci);
+extern int get_charinfo_lp(charinfo * ci);
+extern int get_charinfo_extensible(charinfo * ci, int which);
-extern integer ext_top(internal_font_number f, integer c);
-extern integer ext_bot(internal_font_number f, integer c);
-extern integer ext_rep(internal_font_number f, integer c);
-extern integer ext_mid(internal_font_number f, integer c);
+extern int ext_top(internal_font_number f, int c);
+extern int ext_bot(internal_font_number f, int c);
+extern int ext_rep(internal_font_number f, int c);
+extern int ext_mid(internal_font_number f, int c);
# define set_ligature_item(f,b,c,d) { f.type = b; f.adj = c; f.lig = d; }
@@ -514,30 +506,30 @@ extern integer ext_mid(internal_font_number f, integer c);
# 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 scaled char_height(internal_font_number f, int c);
+extern scaled char_width(internal_font_number f, int c);
+extern scaled char_depth(internal_font_number f, int c);
+extern scaled char_italic(internal_font_number f, int c);
+extern scaled char_top_accent(internal_font_number f, int c);
+extern scaled char_bot_accent(internal_font_number f, int 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);
+extern liginfo *char_ligatures(internal_font_number f, int c);
+extern kerninfo *char_kerns(internal_font_number f, int c);
+extern eight_bits *char_packets(internal_font_number f, int 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);
+extern int char_remainder(internal_font_number f, int c);
+extern char char_tag(internal_font_number f, int c);
+extern char char_used(internal_font_number f, int c);
+extern char *char_name(internal_font_number f, int c);
+extern int char_index(internal_font_number f, int 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);
+scaled raw_get_kern(internal_font_number f, int lc, int rc);
+scaled get_kern(internal_font_number f, int lc, int rc);
+liginfo get_ligature(internal_font_number f, int lc, int rc);
# define EXT_TOP 0
# define EXT_BOT 1
@@ -546,44 +538,43 @@ liginfo get_ligature(internalfontnumber f, integer lc, integer rc);
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);
+int new_font(void);
+extern void font_malloc_charinfo(internal_font_number f, int num);
+int copy_font(int id);
+int scale_font(int id, int atsize);
+int max_font_id(void);
+void set_max_font_id(int id);
+int new_font_id(void);
void create_null_font(void);
-void delete_font(integer id);
-boolean is_valid_font(integer id);
+void delete_font(int id);
+boolean is_valid_font(int id);
void dump_font(int font_number);
void undump_font(int font_number);
-integer test_no_ligatures(internal_font_number f);
+int 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 int get_tag_code(internal_font_number f, int c);
+extern int get_lp_code(internal_font_number f, int c);
+extern int get_rp_code(internal_font_number f, int c);
+extern int get_ef_code(internal_font_number f, int 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, int c, int i);
+extern void set_lp_code(internal_font_number f, int c, int i);
+extern void set_rp_code(internal_font_number f, int c, int i);
+extern void set_ef_code(internal_font_number f, int c, int i);
int read_tfm_info(internal_font_number f, const char *nom, scaled s);
/* from dofont.c */
-extern int read_font_info(pointer u, str_number nom, scaled s, integer ndir);
+extern int read_font_info(pointer u, char *cnom, scaled s, int ndir);
extern int find_font_id(const char *nom, 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,
@@ -598,11 +589,23 @@ typedef enum { packet_char_code,
packet_end_code
} packet_command_codes;
-extern scaled store_scaled_f(scaled sq, integer fw);
+extern scaled store_scaled_f(scaled sq, int fw);
-extern void do_vf_packet(internal_font_number vf_f, integer c);
+extern void do_vf_packet(PDF pdf, internal_font_number vf_f, int c);
extern int vf_packet_bytes(charinfo * co);
-charinfo *copy_charinfo(charinfo * ci);
+extern charinfo *copy_charinfo(charinfo * ci);
+
+/* this function is in vfovf.c for the moment */
+extern int make_vf_table(lua_State * L, const char *name, scaled s);
+
+/* some bits of the old interface, used by e.g. writet3.c */
+
+# define get_x_height(f) x_height(f)
+# define get_quad(f) quad(f)
+# define get_slant(f) slant(f)
+# define get_charwidth(f,c) (char_exists(f,c) ? char_width(f,c) : 0)
+# define get_charheight(f,c) (char_exists(f,c) ? char_height(f,c) : 0)
+# define get_chardepth(f,c) (char_exists(f,c) ? char_depth(f,c) : 0)
#endif /* TEXFONT_H */
diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.c b/Build/source/texk/web2c/luatexdir/font/texfont.w
index 6e64053aa9a..19dcb0769af 100644
--- a/Build/source/texk/web2c/luatexdir/font/texfont.c
+++ b/Build/source/texk/web2c/luatexdir/font/texfont.w
@@ -1,60 +1,65 @@
-/* texfont.c Main font API implementation for the pascal parts
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-/* Main font API implementation for the pascal parts */
-
-/* stuff to watch out for:
- *
- * - Knuth had a 'null_character' that was used when a character could
- * not be found by the fetch() routine, to signal an error. This has
- * been deleted, but it may mean that the output of luatex is
- * incompatible with TeX after fetch() has detected an error condition.
- *
- * - Knuth also had a font_glue() optimization. I've removed that
- * because it was a bit of dirty programming and it also was
- * problematic if 0 != null.
- */
+% texfont.w
-#include "ptexlib.h"
-#include "luatex-api.h"
-#include "luatexfont.h"
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
-#define noDEBUG
+% 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 <http://www.gnu.org/licenses/>.
+
+
+@* Main font API implementation for the original pascal parts.
+
+Stuff to watch out for:
+\item{} Knuth had a |'null_character'| that was used when a character could
+not be found by the |fetch()| routine, to signal an error. This has
+been deleted, but it may mean that the output of luatex is
+incompatible with TeX after |fetch()| has detected an error condition.
+
+\item{} Knuth also had a |font_glue()| optimization. I've removed that
+because it was a bit of dirty programming and it also was
+problematic |if 0 != null|.
+
+@c
static const char _svn_version[] =
- "$Id: texfont.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/texfont.c $";
+ "$Id: texfont.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/texfont.w $";
+
+#include "ptexlib.h"
+#include "lua/luatex-api.h"
+
+@ @c
+#define noDEBUG
#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))
+#define do_realloc(a,b,d) a = xrealloc(a,(unsigned)((unsigned)(b)*sizeof(d)))
texfont **font_tables = NULL;
-static integer font_arr_max = 0;
-static integer font_id_maxval = 0;
+static int font_arr_max = 0;
+static int font_id_maxval = 0;
-static void grow_font_table(integer id)
+@ @c
+static void grow_font_table(int 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 *));
+ font_bytes +=
+ (int) (((id + 8 - font_arr_max) * (int) sizeof(texfont *)));
+ font_tables =
+ xrealloc(font_tables,
+ (unsigned) (((unsigned) id + 8) * sizeof(texfont *)));
j = 8;
while (j--) {
font_tables[id + j] = NULL;
@@ -63,7 +68,7 @@ static void grow_font_table(integer id)
}
}
-integer new_font_id(void)
+int new_font_id(void)
{
int i;
for (i = 0; i < font_arr_max; i++) {
@@ -78,29 +83,31 @@ integer new_font_id(void)
return i;
}
-integer max_font_id(void)
+int max_font_id(void)
{
return font_id_maxval;
}
-void set_max_font_id(integer i)
+void set_max_font_id(int i)
{
font_id_maxval = i;
}
-integer new_font(void)
+@ @c
+int new_font(void)
{
int k;
int id;
charinfo *ci;
id = new_font_id();
- font_bytes += sizeof(texfont);
+ font_bytes += (int) 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_psname = NULL;
font_tables[id]->_font_encodingname = NULL;
font_tables[id]->_font_cidregistry = NULL;
font_tables[id]->_font_cidordering = NULL;
@@ -112,6 +119,8 @@ integer new_font(void)
set_font_bc(id, 1); /* ec = 0 */
set_hyphen_char(id, '-');
set_skew_char(id, -1);
+ font_slant(id) = 0; /* vertical */
+ font_extend(id) = 1000; /* normal width */
/* allocate eight values including 0 */
set_font_params(id, 7);
@@ -130,9 +139,21 @@ integer new_font(void)
return id;
}
+@ @c
+void font_malloc_charinfo(internal_font_number f, int num)
+{
+ int glyph = font_tables[f]->charinfo_size;
+ font_bytes += (int) (num * (int) sizeof(charinfo));
+ do_realloc(font_tables[f]->charinfo, (unsigned) (glyph + num), charinfo);
+ memset(&(font_tables[f]->charinfo[glyph]), 0,
+ (size_t) (num * (int) sizeof(charinfo)));
+ font_tables[f]->charinfo_size += num;
+}
+
+@ @c
#define find_charinfo_id(f,c) get_sa_item(font_tables[f]->characters,c)
-charinfo *get_charinfo(internal_font_number f, integer c)
+charinfo *get_charinfo(internal_font_number f, int c)
{
sa_tree_item glyph;
charinfo *ci;
@@ -140,29 +161,26 @@ charinfo *get_charinfo(internal_font_number f, integer c)
glyph = get_sa_item(font_tables[f]->characters, c);
if (!glyph) {
- glyph = ++font_tables[f]->charinfo_count;
- if (glyph >= (unsigned) font_tables[f]->charinfo_size) {
- font_bytes += (16 * sizeof(charinfo));
- do_realloc(font_tables[f]->charinfo, (glyph + 16), charinfo);
- memset(&(font_tables[f]->charinfo[glyph]), 0,
- (16 * sizeof(charinfo)));
- font_tables[f]->charinfo_size += 16;
+ int tglyph = ++font_tables[f]->charinfo_count;
+ if (tglyph >= font_tables[f]->charinfo_size) {
+ font_malloc_charinfo(f, 256);
}
- font_tables[f]->charinfo[glyph].ef = 1000; /* init */
- set_sa_item(font_tables[f]->characters, c, glyph, 1); /* 1= global */
+ font_tables[f]->charinfo[tglyph].ef = 1000; /* init */
+ set_sa_item(font_tables[f]->characters, c, (sa_tree_item) tglyph, 1); /* 1= global */
+ glyph = (sa_tree_item) tglyph;
}
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);
+ font_bytes += (int) 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);
+ font_bytes += (int) sizeof(charinfo);
set_right_boundary(f, ci);
}
return right_boundary(f);
@@ -170,7 +188,8 @@ charinfo *get_charinfo(internal_font_number f, integer c)
return &(font_tables[f]->charinfo[0]);
}
-static void set_charinfo(internal_font_number f, integer c, charinfo * ci)
+@ @c
+void set_charinfo(internal_font_number f, int c, charinfo * ci)
{
sa_tree_item glyph;
if (proper_char_index(c)) {
@@ -187,14 +206,13 @@ static void set_charinfo(internal_font_number f, integer c, charinfo * ci)
}
}
-
-
+@ @c
charinfo *copy_charinfo(charinfo * ci)
{
- int x;
+ int x, k;
kerninfo *kern;
liginfo *lig;
- real_eight_bits *packet;
+ eight_bits *packet;
charinfo *co = NULL;
if (ci == NULL)
return NULL;
@@ -221,8 +239,8 @@ charinfo *copy_charinfo(charinfo * ci)
x++;
}
x++;
- co->kerns = xmalloc(x * sizeof(kerninfo));
- memcpy(co->kerns, ci->kerns, (x * sizeof(kerninfo)));
+ co->kerns = xmalloc((unsigned) (x * (int) sizeof(kerninfo)));
+ memcpy(co->kerns, ci->kerns, (size_t) (x * (int) sizeof(kerninfo)));
}
/* ligs */
if ((lig = get_charinfo_ligatures(ci)) != NULL) {
@@ -231,14 +249,15 @@ charinfo *copy_charinfo(charinfo * ci)
x++;
}
x++;
- co->ligatures = xmalloc(x * sizeof(liginfo));
- memcpy(co->ligatures, ci->ligatures, (x * sizeof(liginfo)));
+ co->ligatures = xmalloc((unsigned) (x * (int) sizeof(liginfo)));
+ memcpy(co->ligatures, ci->ligatures,
+ (size_t) (x * (int) 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);
+ co->packets = xmalloc((unsigned) x);
+ memcpy(co->packets, ci->packets, (size_t) x);
}
/* horizontal and vertical extenders */
@@ -251,11 +270,11 @@ charinfo *copy_charinfo(charinfo * ci)
set_charinfo_hor_variants(co,
copy_variants(get_charinfo_hor_variants(ci)));
}
- /* TODO: copy mathkerns */
x = ci->top_left_math_kerns;
co->top_left_math_kerns = x;
if (x > 0) {
- co->top_left_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ co->top_left_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < co->top_left_math_kerns; k++) {
co->top_left_math_kern_array[(2 * k)] =
ci->top_left_math_kern_array[(2 * k)];
@@ -266,7 +285,8 @@ charinfo *copy_charinfo(charinfo * ci)
x = ci->top_right_math_kerns;
co->top_right_math_kerns = x;
if (x > 0) {
- co->top_right_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ co->top_right_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < co->top_right_math_kerns; k++) {
co->top_right_math_kern_array[(2 * k)] =
ci->top_right_math_kern_array[(2 * k)];
@@ -277,7 +297,8 @@ charinfo *copy_charinfo(charinfo * ci)
x = ci->bottom_right_math_kerns;
co->bottom_right_math_kerns = x;
if (x > 0) {
- co->bottom_right_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ co->bottom_right_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < co->bottom_right_math_kerns; k++) {
co->bottom_right_math_kern_array[(2 * k)] =
ci->bottom_right_math_kern_array[(2 * k)];
@@ -288,7 +309,8 @@ charinfo *copy_charinfo(charinfo * ci)
x = ci->bottom_left_math_kerns;
co->bottom_left_math_kerns = x;
if (x > 0) {
- co->bottom_left_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ co->bottom_left_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < co->bottom_left_math_kerns; k++) {
co->bottom_left_math_kern_array[(2 * k)] =
ci->bottom_left_math_kern_array[(2 * k)];
@@ -301,12 +323,12 @@ charinfo *copy_charinfo(charinfo * ci)
return co;
}
-charinfo *char_info(internal_font_number f, integer c)
+charinfo *char_info(internal_font_number f, int c)
{
if (f > font_id_maxval)
return 0;
if (proper_char_index(c)) {
- register int glyph = find_charinfo_id(f, c);
+ register int glyph = (int) find_charinfo_id(f, c);
return &(font_tables[f]->charinfo[glyph]);
} else if (c == left_boundarychar && left_boundary(f) != NULL) {
return left_boundary(f);
@@ -316,23 +338,25 @@ charinfo *char_info(internal_font_number f, integer c)
return &(font_tables[f]->charinfo[0]);
}
-charinfo_short char_info_short(internal_font_number f, integer c)
+@ @c
+scaled_whd get_charinfo_whd(internal_font_number f, int c)
{
- charinfo_short s;
+ scaled_whd s;
charinfo *i;
i = char_info(f, c);
- s.ci_wd = i->width;
- s.ci_dp = i->depth;
- s.ci_ht = i->height;
+ s.wd = i->width;
+ s.dp = i->depth;
+ s.ht = i->height;
return s;
}
-integer char_exists(internal_font_number f, integer c)
+@ @c
+int char_exists(internal_font_number f, int c)
{
if (f > font_id_maxval)
return 0;
if (proper_char_index(c)) {
- return find_charinfo_id(f, c);
+ return (int) 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)) {
@@ -341,10 +365,10 @@ integer char_exists(internal_font_number f, integer c)
return 0;
}
-#if 0 /* unused */
-static int lua_char_exists_callback(internal_font_number f, integer c)
+@ @c
+int lua_char_exists_callback(internal_font_number f, int c)
{
- integer callback_id;
+ int callback_id;
lua_State *L = Luas;
int ret = 0;
callback_id = callback_defined(char_exists_callback);
@@ -365,9 +389,9 @@ static int lua_char_exists_callback(internal_font_number f, integer c)
}
return ret;
}
-#endif
+@ @c
extinfo *new_variant(int glyph, int startconnect, int endconnect,
int advance, int repeater)
{
@@ -383,7 +407,8 @@ extinfo *new_variant(int glyph, int startconnect, int endconnect,
}
-static extinfo *copy_variant(extinfo * old)
+@ @c
+extinfo *copy_variant(extinfo * old)
{
extinfo *ext;
ext = xmalloc(sizeof(extinfo));
@@ -396,7 +421,8 @@ static extinfo *copy_variant(extinfo * old)
return ext;
}
-static void dump_variant(extinfo * ext)
+@ @c
+void dump_variant(extinfo * ext)
{
dump_int(ext->glyph);
dump_int(ext->start_overlap);
@@ -407,9 +433,10 @@ static void dump_variant(extinfo * ext)
}
-static extinfo *undump_variant(void)
+@ @c
+extinfo *undump_variant(void)
{
- integer x;
+ int x;
extinfo *ext;
undump_int(x);
if (x == 0)
@@ -428,6 +455,7 @@ static extinfo *undump_variant(void)
return ext;
}
+@ @c
void add_charinfo_vert_variant(charinfo * ci, extinfo * ext)
{
if (ci->vert_variants == NULL) {
@@ -441,6 +469,7 @@ void add_charinfo_vert_variant(charinfo * ci, extinfo * ext)
}
+@ @c
void add_charinfo_hor_variant(charinfo * ci, extinfo * ext)
{
if (ci->hor_variants == NULL) {
@@ -454,6 +483,7 @@ void add_charinfo_hor_variant(charinfo * ci, extinfo * ext)
}
+@ @c
extinfo *copy_variants(extinfo * o)
{
extinfo *c, *t = NULL, *h = NULL;
@@ -471,7 +501,8 @@ extinfo *copy_variants(extinfo * o)
}
-static void dump_charinfo_variants(extinfo * o)
+@ @c
+void dump_charinfo_variants(extinfo * o)
{
while (o != NULL) {
dump_variant(o);
@@ -481,7 +512,8 @@ static void dump_charinfo_variants(extinfo * o)
return;
}
-static extinfo *undump_charinfo_variants(void)
+@ @c
+extinfo *undump_charinfo_variants(void)
{
extinfo *c, *t, *h = NULL;
c = undump_variant();
@@ -497,6 +529,9 @@ static extinfo *undump_charinfo_variants(void)
}
+@ Note that mant more small things like this are implemented
+as macros in the header file.
+@c
void set_charinfo_width(charinfo * ci, scaled val)
{
ci->width = val;
@@ -529,7 +564,7 @@ void set_charinfo_bot_accent(charinfo * ci, scaled val)
void set_charinfo_tag(charinfo * ci, scaled val)
{
- ci->tag = val;
+ ci->tag = (char) val;
}
void set_charinfo_remainder(charinfo * ci, scaled val)
@@ -539,20 +574,24 @@ void set_charinfo_remainder(charinfo * ci, scaled val)
void set_charinfo_used(charinfo * ci, scaled val)
{
- ci->used = val;
+ ci->used = (char) val;
}
void set_charinfo_index(charinfo * ci, scaled val)
{
- ci->index = val;
+ ci->index = (unsigned short) val;
}
+
void set_charinfo_name(charinfo * ci, char *val)
{
- dxfree(ci->name, val);
+ xfree(ci->name);
+ ci->name = val;
}
+
void set_charinfo_tounicode(charinfo * ci, char *val)
{
- dxfree(ci->tounicode, val);
+ xfree(ci->tounicode);
+ ci->tounicode = val;
}
void set_charinfo_ligatures(charinfo * ci, liginfo * val)
@@ -565,7 +604,7 @@ void set_charinfo_kerns(charinfo * ci, kerninfo * val)
dxfree(ci->kerns, val);
}
-void set_charinfo_packets(charinfo * ci, real_eight_bits * val)
+void set_charinfo_packets(charinfo * ci, eight_bits * val)
{
dxfree(ci->packets, val);
}
@@ -585,6 +624,7 @@ void set_charinfo_rp(charinfo * ci, scaled val)
ci->rp = val;
}
+@ @c
void set_charinfo_vert_variants(charinfo * ci, extinfo * ext)
{
extinfo *c, *lst;
@@ -599,6 +639,7 @@ void set_charinfo_vert_variants(charinfo * ci, extinfo * ext)
ci->vert_variants = ext;
}
+@ @c
void set_charinfo_hor_variants(charinfo * ci, extinfo * ext)
{
extinfo *c, *lst;
@@ -614,10 +655,11 @@ void set_charinfo_hor_variants(charinfo * ci, extinfo * ext)
}
+@ @c
int get_charinfo_math_kerns(charinfo * ci, int id)
{
- int k = 0; /* all callers check for result>0 */
+ int k = 0; /* all callers check for |result>0| */
if (id == top_left_kern) {
k = ci->top_left_math_kerns;
} else if (id == bottom_left_kern) {
@@ -627,11 +669,12 @@ int get_charinfo_math_kerns(charinfo * ci, int id)
} else if (id == top_right_kern) {
k = ci->top_right_math_kerns;
} else {
- tconfusion("get_charinfo_math_kerns");
+ confusion("get_charinfo_math_kerns");
}
return k;
}
+@ @c
void add_charinfo_math_kern(charinfo * ci, int id, scaled ht, scaled krn)
{
int k;
@@ -663,14 +706,15 @@ void add_charinfo_math_kern(charinfo * ci, int id, scaled ht, scaled krn)
ci->top_right_math_kern_array[(2 * (k)) + 1] = krn;
ci->top_right_math_kerns++;
} else {
- tconfusion("add_charinfo_math_kern");
+ confusion("add_charinfo_math_kern");
}
}
+@ @c
static void dump_math_kerns(charinfo * ci)
{
- integer k, l;
+ int k, l;
l = ci->top_left_math_kerns;
dump_int(l);
for (k = 0; k < l; k++) {
@@ -697,14 +741,16 @@ static void dump_math_kerns(charinfo * ci)
}
}
+@ @c
static void undump_math_kerns(charinfo * ci)
{
int k;
- integer x;
+ int x;
undump_int(x);
- ci->top_left_math_kerns = (int) x;
+ ci->top_left_math_kerns = x;
if (x > 0)
- ci->top_left_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ ci->top_left_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < ci->top_left_math_kerns; k++) {
undump_int(x);
ci->top_left_math_kern_array[(2 * k)] = (scaled) x;
@@ -712,9 +758,10 @@ static void undump_math_kerns(charinfo * ci)
ci->top_left_math_kern_array[(2 * k) + 1] = (scaled) x;
}
undump_int(x);
- ci->bottom_left_math_kerns = (int) x;
+ ci->bottom_left_math_kerns = x;
if (x > 0)
- ci->bottom_left_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ ci->bottom_left_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < ci->bottom_left_math_kerns; k++) {
undump_int(x);
ci->bottom_left_math_kern_array[(2 * k)] = (scaled) x;
@@ -722,9 +769,10 @@ static void undump_math_kerns(charinfo * ci)
ci->bottom_left_math_kern_array[(2 * k) + 1] = (scaled) x;
}
undump_int(x);
- ci->bottom_right_math_kerns = (int) x;
+ ci->bottom_right_math_kerns = x;
if (x > 0)
- ci->bottom_right_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ ci->bottom_right_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < ci->bottom_right_math_kerns; k++) {
undump_int(x);
ci->bottom_right_math_kern_array[(2 * k)] = (scaled) x;
@@ -732,9 +780,10 @@ static void undump_math_kerns(charinfo * ci)
ci->bottom_right_math_kern_array[(2 * k) + 1] = (scaled) x;
}
undump_int(x);
- ci->top_right_math_kerns = (int) x;
+ ci->top_right_math_kerns = x;
if (x > 0)
- ci->top_right_math_kern_array = xmalloc(2 * sizeof(scaled) * x);
+ ci->top_right_math_kern_array =
+ xmalloc((unsigned) (2 * (int) sizeof(scaled) * x));
for (k = 0; k < ci->top_right_math_kerns; k++) {
undump_int(x);
ci->top_right_math_kern_array[(2 * k)] = (scaled) x;
@@ -744,15 +793,16 @@ static void undump_math_kerns(charinfo * ci)
}
-/* In TeX, extensibles were fairly simple things.
+@ 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
-*/
+ |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
+
+ a small complication arises if |rep| is the only non-zero: it needs to be
doubled as a non-repeatable to avoid mayhem */
+@c
void set_charinfo_extensible(charinfo * ci, int top, int bot, int mid, int rep)
{
extinfo *ext;
@@ -786,6 +836,10 @@ void set_charinfo_extensible(charinfo * ci, int top, int bot, int mid, int rep)
}
}
+@ Note that many more simple things like this are implemented as macros
+in the header file.
+
+@c
scaled get_charinfo_width(charinfo * ci)
{
return ci->width;
@@ -821,7 +875,7 @@ char get_charinfo_tag(charinfo * ci)
return ci->tag;
}
-integer get_charinfo_remainder(charinfo * ci)
+int get_charinfo_remainder(charinfo * ci)
{
return ci->remainder;
}
@@ -831,7 +885,7 @@ char get_charinfo_used(charinfo * ci)
return ci->used;
}
-integer get_charinfo_index(charinfo * ci)
+int get_charinfo_index(charinfo * ci)
{
return ci->index;
}
@@ -856,22 +910,22 @@ kerninfo *get_charinfo_kerns(charinfo * ci)
return ci->kerns;
}
-real_eight_bits *get_charinfo_packets(charinfo * ci)
+eight_bits *get_charinfo_packets(charinfo * ci)
{
return ci->packets;
}
-integer get_charinfo_ef(charinfo * ci)
+int get_charinfo_ef(charinfo * ci)
{
return ci->ef;
}
-integer get_charinfo_rp(charinfo * ci)
+int get_charinfo_rp(charinfo * ci)
{
return ci->rp;
}
-integer get_charinfo_lp(charinfo * ci)
+int get_charinfo_lp(charinfo * ci)
{
return ci->lp;
}
@@ -893,105 +947,103 @@ extinfo *get_charinfo_hor_variants(charinfo * ci)
}
-scaled char_width(internal_font_number f, integer c)
+scaled char_width(internal_font_number f, int 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)
+scaled char_depth(internal_font_number f, int 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)
+scaled char_height(internal_font_number f, int 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)
+scaled char_italic(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_italic(ci);
}
-scaled char_top_accent(internal_font_number f, integer c)
+scaled char_top_accent(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_top_accent(ci);
}
-scaled char_bot_accent(internal_font_number f, integer c)
+scaled char_bot_accent(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_bot_accent(ci);
}
-integer char_remainder(internal_font_number f, integer c)
+int char_remainder(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_remainder(ci);
}
-char char_tag(internal_font_number f, integer c)
+char char_tag(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_tag(ci);
}
-char char_used(internal_font_number f, integer c)
+char char_used(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_used(ci);
}
-char *char_name(internal_font_number f, integer c)
+char *char_name(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_name(ci);
}
-integer char_index(internal_font_number f, integer c)
+int char_index(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_index(ci);
}
-liginfo *char_ligatures(internal_font_number f, integer c)
+liginfo *char_ligatures(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_ligatures(ci);
}
-kerninfo *char_kerns(internal_font_number f, integer c)
+kerninfo *char_kerns(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_kerns(ci);
}
-real_eight_bits *char_packets(internal_font_number f, integer c)
+eight_bits *char_packets(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_packets(ci);
}
-
+@ @c
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_bytes +=
+ (int) ((b - (int) font_params(f) + 1) * (int) sizeof(scaled));
+ do_realloc(param_base(f), (b + 2), int);
font_params(f) = b;
if (b > i) {
while (i < b) {
@@ -1002,13 +1054,15 @@ void set_font_params(internal_font_number f, int b)
}
}
+@ @c
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_bytes +=
+ ((b - (int) font_math_params(f) + 1) * (int) sizeof(scaled));
+ do_realloc(math_param_base(f), (b + 2), int);
font_math_params(f) = b;
if (b > i) {
while (i < b) {
@@ -1020,14 +1074,24 @@ void set_font_math_params(internal_font_number f, int b)
}
-
-integer copy_font(integer f)
+@ @c
+int copy_font(int f)
{
- int i;
+ int i, ci_cnt, ci_size;
charinfo *ci;
- integer k = new_font();
- memcpy(font_tables[k], font_tables[f], sizeof(texfont));
+ int k = new_font();
+
+ {
+ ci = font_tables[k]->charinfo;
+ ci_cnt = font_tables[k]->charinfo_count;
+ ci_size = font_tables[k]->charinfo_size;
+ memcpy(font_tables[k], font_tables[f], sizeof(texfont));
+ font_tables[k]->charinfo = ci;
+ font_tables[k]->charinfo_count = ci_cnt;
+ font_tables[k]->charinfo_size = ci_size;
+ }
+ font_malloc_charinfo(k, font_tables[f]->charinfo_count);
set_font_cache_id(k, 0);
set_font_used(k, 0);
set_font_touched(k, 0);
@@ -1035,6 +1099,7 @@ integer copy_font(integer f)
font_tables[k]->_font_name = NULL;
font_tables[k]->_font_filename = NULL;
font_tables[k]->_font_fullname = NULL;
+ font_tables[k]->_font_psname = NULL;
font_tables[k]->_font_encodingname = NULL;
font_tables[k]->_font_area = NULL;
font_tables[k]->_font_cidregistry = NULL;
@@ -1047,6 +1112,8 @@ integer copy_font(integer f)
set_font_filename(k, xstrdup(font_filename(f)));
if (font_fullname(f) != NULL)
set_font_fullname(k, xstrdup(font_fullname(f)));
+ if (font_psname(f) != NULL)
+ set_font_psname(k, xstrdup(font_psname(f)));
if (font_encodingname(f) != NULL)
set_font_encodingname(k, xstrdup(font_encodingname(f)));
if (font_area(f) != NULL)
@@ -1056,23 +1123,20 @@ integer copy_font(integer f)
if (font_cidordering(f) != NULL)
set_font_cidordering(k, xstrdup(font_cidordering(f)));
- i = sizeof(*param_base(f)) * font_params(f);
+ i = (int) (sizeof(*param_base(f)) * (unsigned) font_params(f));
font_bytes += i;
- param_base(k) = xmalloc(i);
- memcpy(param_base(k), param_base(f), i);
+ param_base(k) = xmalloc((unsigned) i);
+ memcpy(param_base(k), param_base(f), (size_t) i);
if (font_math_params(f) > 0) {
- i = sizeof(*math_param_base(f)) * font_math_params(f);
+ i = (int) (sizeof(*math_param_base(f)) *
+ (unsigned) font_math_params(f));
font_bytes += i;
- math_param_base(k) = xmalloc(i);
- memcpy(math_param_base(k), math_param_base(f), i);
+ math_param_base(k) = xmalloc((unsigned) i);
+ memcpy(math_param_base(k), math_param_base(f), (size_t) i);
}
- i = sizeof(charinfo) * (font_tables[f]->charinfo_size + 1);
- font_bytes += i;
- font_tables[k]->charinfo = xmalloc(i);
- memset(font_tables[k]->charinfo, 0, i);
- for (i = 0; i < font_tables[k]->charinfo_size; i++) {
+ for (i = 0; i <= font_tables[f]->charinfo_count; i++) {
ci = copy_charinfo(&font_tables[f]->charinfo[i]);
font_tables[k]->charinfo[i] = *ci;
}
@@ -1089,7 +1153,8 @@ integer copy_font(integer f)
return k;
}
-void delete_font(integer f)
+@ @c
+void delete_font(int f)
{
int i;
charinfo *co;
@@ -1098,6 +1163,7 @@ void delete_font(integer f)
set_font_name(f, NULL);
set_font_filename(f, NULL);
set_font_fullname(f, NULL);
+ set_font_psname(f, NULL);
set_font_encodingname(f, NULL);
set_font_area(f, NULL);
set_font_cidregistry(f, NULL);
@@ -1106,7 +1172,7 @@ void delete_font(integer f)
set_right_boundary(f, NULL);
for (i = font_bc(f); i <= font_ec(f); i++) {
- if (char_exists(f, i)) {
+ if (quick_char_exists(f, i)) {
co = char_info(f, i);
set_charinfo_name(co, NULL);
set_charinfo_tounicode(co, NULL);
@@ -1134,6 +1200,7 @@ void delete_font(integer f)
}
}
+@ @c
void create_null_font(void)
{
int i = new_font();
@@ -1143,7 +1210,8 @@ void create_null_font(void)
set_font_touched(i, 1);
}
-boolean is_valid_font(integer id)
+@ @c
+boolean is_valid_font(int id)
{
int ret = 0;
if (id >= 0 && id <= font_id_maxval && font_tables[id] != NULL)
@@ -1151,22 +1219,8 @@ boolean is_valid_font(integer id)
return ret;
}
-/* return 1 == identical */
-boolean cmp_font_name(integer id, str_number 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;
-}
-
-boolean cmp_font_area(integer id, str_number t)
+@ @c
+boolean cmp_font_area(int id, str_number t)
{
char *tt = NULL;
char *tid = font_area(id);
@@ -1181,68 +1235,23 @@ boolean cmp_font_area(integer id, str_number t)
return 1;
if (tt == NULL || strcmp(tid, tt) != 0)
return 0;
+ free(tt);
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;
- /* 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 &&
- font_fullname(k) != NULL && font_fullname(f) != NULL &&
- strcmp(font_fullname(k), font_fullname(f)) == 0)
- || (pdf_font_auto_expand(f)
- && (pdf_font_blink(f) != 0) /* 0 = nullfont */
- &&same_font_name(k, pdf_font_blink(f)))) {
- ret = 1;
- }
-#ifdef DEBUG
- printf("font_shareable(%d:%s:%s,%d:%s:%s): => %d\n",
- f, font_filename(f), font_fullname(f),
- k, font_filename(k), font_fullname(k), ret);
-#endif
- }
- return ret;
-}
-
-integer test_no_ligatures(internal_font_number f)
+@ @c
+int test_no_ligatures(internal_font_number f)
{
- integer c;
+ int c;
for (c = font_bc(f); c <= font_ec(f); c++) {
- if (has_lig(f, c)) /* char_exists(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)
+@ @c
+int get_tag_code(internal_font_number f, int c)
{
small_number i;
if (char_exists(f, c)) {
@@ -1259,30 +1268,32 @@ integer get_tag_code(internal_font_number f, integer c)
return -1;
}
-integer get_lp_code(internal_font_number f, integer c)
+@ @c
+int get_lp_code(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_lp(ci);
}
-integer get_rp_code(internal_font_number f, integer c)
+int get_rp_code(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_rp(ci);
}
-integer get_ef_code(internal_font_number f, integer c)
+int get_ef_code(internal_font_number f, int c)
{
charinfo *ci = char_info(f, c);
return get_charinfo_ef(ci);
}
-void set_tag_code(internal_font_number f, integer c, integer i)
+@ @c
+void set_tag_code(internal_font_number f, int c, int i)
{
- integer fixedi;
+ int fixedi;
charinfo *co;
if (char_exists(f, c)) {
- /* abs(fix_int(i-7,0)) */
+ /* |abs(fix_int(i-7,0))| */
fixedi = -(i < -7 ? -7 : (i > 0 ? 0 : i));
co = char_info(f, c);
if (fixedi >= 4) {
@@ -1305,7 +1316,8 @@ void set_tag_code(internal_font_number f, integer c, integer i)
}
-void set_lp_code(internal_font_number f, integer c, integer i)
+@ @c
+void set_lp_code(internal_font_number f, int c, int i)
{
charinfo *co;
if (char_exists(f, c)) {
@@ -1314,7 +1326,7 @@ void set_lp_code(internal_font_number f, integer c, integer i)
}
}
-void set_rp_code(internal_font_number f, integer c, integer i)
+void set_rp_code(internal_font_number f, int c, int i)
{
charinfo *co;
if (char_exists(f, c)) {
@@ -1323,7 +1335,7 @@ void set_rp_code(internal_font_number f, integer c, integer i)
}
}
-void set_ef_code(internal_font_number f, integer c, integer i)
+void set_ef_code(internal_font_number f, int c, int i)
{
charinfo *co;
if (char_exists(f, c)) {
@@ -1332,9 +1344,10 @@ void set_ef_code(internal_font_number f, integer c, integer i)
}
}
+@ @c
void set_no_ligatures(internal_font_number f)
{
- integer c;
+ int c;
charinfo *co;
if (font_tables[f]->ligatures_disabled)
@@ -1351,8 +1364,10 @@ void set_no_ligatures(internal_font_number f)
font_tables[f]->ligatures_disabled = 1;
}
-liginfo get_ligature(internal_font_number f, integer lc, integer rc)
+@ @c
+liginfo get_ligature(internal_font_number f, int lc, int rc)
{
+ int k;
liginfo t, u;
charinfo *co;
t.lig = 0;
@@ -1379,9 +1394,10 @@ liginfo get_ligature(internal_font_number f, integer lc, integer rc)
}
-scaled raw_get_kern(internal_font_number f, integer lc, integer rc)
+@ @c
+scaled raw_get_kern(internal_font_number f, int lc, int rc)
{
- integer k;
+ int k;
kerninfo u;
charinfo *co;
if (lc == non_boundarychar || rc == non_boundarychar)
@@ -1404,7 +1420,8 @@ scaled raw_get_kern(internal_font_number f, integer lc, integer rc)
}
-scaled get_kern(internal_font_number f, integer lc, integer rc)
+@ @c
+scaled get_kern(internal_font_number f, int lc, int rc)
{
if (lc == non_boundarychar || rc == non_boundarychar || (!has_kern(f, lc)))
return 0;
@@ -1412,20 +1429,21 @@ scaled get_kern(internal_font_number f, integer lc, integer rc)
}
-/* dumping and undumping fonts */
+@ 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); \
- }
+@c
+#define dump_string(a) \
+ if (a!=NULL) { \
+ x = (int)(strlen(a)+1); \
+ dump_int(x); dump_things(*a, x); \
+ } else { \
+ x = 0; dump_int(x); \
+ }
-static void dump_charinfo(int f, int c)
+void dump_charinfo(int f, int c)
{
charinfo *co;
- integer x;
+ int x;
liginfo *lig;
kerninfo *kern;
dump_int(c);
@@ -1485,20 +1503,27 @@ static void dump_charinfo(int f, int c)
dump_math_kerns(co);
}
-static void dump_font_entry(texfont * f)
+void dump_font_entry(texfont * f)
{
+ int x;
dump_int(f->_font_size);
dump_int(f->_font_dsize);
dump_int(f->_font_cidversion);
dump_int(f->_font_cidsupplement);
dump_int(f->_font_ec);
- dump_int(f->_font_checksum);
+ x = (int) f->_font_checksum;
+ dump_int(x);
dump_int(f->_font_used);
dump_int(f->_font_touched);
dump_int(f->_font_cache_id);
dump_int(f->_font_encodingbytes);
dump_int(f->_font_slant);
dump_int(f->_font_extend);
+ dump_int(f->_font_expand_ratio);
+ dump_int(f->_font_shrink);
+ dump_int(f->_font_stretch);
+ dump_int(f->_font_step);
+ dump_int(f->_font_auto_expand);
dump_int(f->_font_tounicode);
dump_int(f->_font_type);
dump_int(f->_font_format);
@@ -1511,20 +1536,14 @@ static void dump_font_entry(texfont * f)
dump_int(f->_font_math_params);
dump_int(f->ligatures_disabled);
dump_int(f->_pdf_font_num);
- dump_int(f->_pdf_font_size);
dump_int(f->_pdf_font_blink);
dump_int(f->_pdf_font_elink);
- dump_int(f->_pdf_font_expand_ratio);
- dump_int(f->_pdf_font_shrink);
- dump_int(f->_pdf_font_stretch);
- dump_int(f->_pdf_font_step);
- dump_int(f->_pdf_font_auto_expand);
dump_int(f->_pdf_font_attr);
}
void dump_font(int f)
{
- integer i, x;
+ int i, x;
set_font_used(f, 0);
font_tables[f]->charinfo_cache = NULL;
@@ -1533,6 +1552,7 @@ void dump_font(int f)
dump_string(font_area(f));
dump_string(font_filename(f));
dump_string(font_fullname(f));
+ dump_string(font_psname(f));
dump_string(font_encodingname(f));
dump_string(font_cidregistry(f));
dump_string(font_cidordering(f));
@@ -1556,20 +1576,21 @@ void dump_font(int f)
}
for (i = font_bc(f); i <= font_ec(f); i++) {
- if (char_exists(f, i)) {
+ if (quick_char_exists(f, i)) {
dump_charinfo(f, i);
}
}
}
-static int undump_charinfo(int f)
+@ @c
+int undump_charinfo(int f)
{
charinfo *co;
- integer x, i;
+ int x, i;
char *s = NULL;
liginfo *lig = NULL;
kerninfo *kern = NULL;
- real_eight_bits *packet = NULL;
+ eight_bits *packet = NULL;
undump_int(i);
co = get_charinfo(f, i);
@@ -1604,7 +1625,7 @@ static int undump_charinfo(int f)
undump_int(x);
if (x > 0) {
font_bytes += x;
- s = xmalloc(x);
+ s = xmalloc((unsigned) x);
undump_things(*s, x);
}
set_charinfo_name(co, s);
@@ -1612,23 +1633,23 @@ static int undump_charinfo(int f)
undump_int(x);
if (x > 0) {
font_bytes += x;
- s = xmalloc(x);
+ s = xmalloc((unsigned) 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));
+ font_bytes += (int) ((unsigned) x * sizeof(liginfo));
+ lig = xmalloc((unsigned) ((unsigned) 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));
+ font_bytes += (int) ((unsigned) x * sizeof(kerninfo));
+ kern = xmalloc((unsigned) ((unsigned) x * sizeof(kerninfo)));
undump_things(*kern, x);
}
set_charinfo_kerns(co, kern);
@@ -1637,7 +1658,7 @@ static int undump_charinfo(int f)
undump_int(x);
if (x > 0) {
font_bytes += x;
- packet = xmalloc(x);
+ packet = xmalloc((unsigned) x);
undump_things(*packet, x);
}
set_charinfo_packets(co, packet);
@@ -1650,30 +1671,35 @@ static int undump_charinfo(int f)
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((unsigned)x); undump_things(*s,x); \
a(f,s); }
-static void undump_font_entry(texfont * f)
+void undump_font_entry(texfont * f)
{
- integer x = 0;
- /* *INDENT-OFF* */
+ int x = 0;
+ /* *INDENT-OFF* */
undump_int(x); f->_font_size = x;
undump_int(x); f->_font_dsize = x;
undump_int(x); f->_font_cidversion = x;
undump_int(x); f->_font_cidsupplement = x;
undump_int(x); f->_font_ec = x;
- undump_int(x); f->_font_checksum = x;
- undump_int(x); f->_font_used = x;
- undump_int(x); f->_font_touched = x;
+ undump_int(x); f->_font_checksum = (unsigned)x;
+ undump_int(x); f->_font_used = (char)x;
+ undump_int(x); f->_font_touched = (char)x;
undump_int(x); f->_font_cache_id = x;
- undump_int(x); f->_font_encodingbytes = x;
+ undump_int(x); f->_font_encodingbytes = (char)x;
undump_int(x); f->_font_slant = x;
undump_int(x); f->_font_extend = x;
- undump_int(x); f->_font_tounicode = x;
+ undump_int(x); f->_font_expand_ratio = x;
+ undump_int(x); f->_font_shrink = x;
+ undump_int(x); f->_font_stretch = x;
+ undump_int(x); f->_font_step = x;
+ undump_int(x); f->_font_auto_expand = x;
+ undump_int(x); f->_font_tounicode = (char)x;
undump_int(x); f->_font_type = x;
undump_int(x); f->_font_format = x;
undump_int(x); f->_font_embedding = x;
@@ -1685,30 +1711,24 @@ static void undump_font_entry(texfont * f)
undump_int(x); f->_font_math_params = x;
undump_int(x); f->ligatures_disabled = x;
undump_int(x); f->_pdf_font_num = x;
- undump_int(x); f->_pdf_font_size = x;
undump_int(x); f->_pdf_font_blink = x;
undump_int(x); f->_pdf_font_elink = x;
- undump_int(x); f->_pdf_font_expand_ratio = x;
- undump_int(x); f->_pdf_font_shrink = x;
- undump_int(x); f->_pdf_font_stretch = x;
- undump_int(x); f->_pdf_font_step = x;
- undump_int(x); f->_pdf_font_auto_expand = x;
undump_int(x); f->_pdf_font_attr = x;
- /* *INDENT-ON* */
+ /* *INDENT-ON* */
}
void undump_font(int f)
{
- integer x, i;
+ int x, i;
texfont *tt;
charinfo *ci;
char *s;
grow_font_table(f);
tt = xmalloc(sizeof(texfont));
memset(tt, 0, sizeof(texfont));
- font_bytes += sizeof(texfont);
+ font_bytes += (int) sizeof(texfont);
undump_font_entry(tt);
font_tables[f] = tt;
@@ -1716,19 +1736,21 @@ void undump_font(int f)
undump_font_string(set_font_area);
undump_font_string(set_font_filename);
undump_font_string(set_font_fullname);
+ undump_font_string(set_font_psname);
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);
+ i = (int) (sizeof(*param_base(f)) * ((unsigned) font_params(f) + 1));
font_bytes += i;
- param_base(f) = xmalloc(i);
+ param_base(f) = xmalloc((unsigned) 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);
+ i = (int) (sizeof(*math_param_base(f)) *
+ ((unsigned) font_math_params(f) + 1));
font_bytes += i;
- math_param_base(f) = xmalloc(i);
+ math_param_base(f) = xmalloc((unsigned) i);
undump_things(*math_param_base(f), (font_math_params(f) + 1));
}
diff --git a/Build/source/texk/web2c/luatexdir/font/tfmofm.c b/Build/source/texk/web2c/luatexdir/font/tfmofm.w
index 6c99a9dd498..842af38b405 100644
--- a/Build/source/texk/web2c/luatexdir/font/tfmofm.c
+++ b/Build/source/texk/web2c/luatexdir/font/tfmofm.w
@@ -1,31 +1,31 @@
-/* tfmofm.c
-
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% tfmofm.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
#include "ptexlib.h"
-#include "luatex-api.h"
-#include "luatexfont.h"
static const char _svn_version[] =
- "$Id: tfmofm.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/tfmofm.c $";
-
-/* Here are some macros that help process ligatures and kerns */
+ "$Id: tfmofm.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/tfmofm.w $";
+@ Here are some macros that help process ligatures and kerns
+@c
#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 */
@@ -36,8 +36,8 @@ static const char _svn_version[] =
#define rem_byte(z) lig_kerns[z].b3
#define lig_kern_restart(c) (256*op_byte(c)+rem_byte(c))
-/*
+@
The information in a \.{TFM} file appears in a sequence of 8-bit bytes.
Since the number of bytes is always a multiple of 4, we could
also regard the file as a sequence of 32-bit words, but \TeX\ uses the
@@ -54,9 +54,9 @@ is not aware of this.
The documentation below describes \.{TFM} files, with slight additions
to show where \.{OFM} files differ.
- */
-/*
-@ The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit
+
+@
+The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit
integers that give the lengths of the various subsequent portions
of the file. These twelve integers are, in order:
$$\vbox{\halign{\hfil#&$\null=\null$#\hfil\cr
@@ -94,11 +94,12 @@ $$\hbox{|lf=13+lh+2*(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$
Note that an \.{OFM} font may contain as many as 65536 characters
(if |bc=0| and |ec=65535|), and as few as 0 characters (if |bc=ec+1|).
-@ The rest of the \.{TFM} file may be regarded as a sequence of ten data
+The rest of the \.{TFM} file may be regarded as a sequence of ten data
arrays having the informal specification
$$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2}
-\vbox{\halign{\hfil\\{#}&$\,:\,$\arr#\hfil\cr
-header&|[0..lh-1]@t\\{stuff}@>|\cr
+\def\doarr\PB#1{\arr#1}
+\vbox{\halign{\hfil\\{#}&$\,:\,$\doarr#\hfil\cr
+header&|[0..lh-1]stuff|\cr
char\_info&|[bc..ec]char_info_word|\cr
width&|[0..nw-1]fix_word|\cr
height&|[0..nh-1]fix_word|\cr
@@ -107,7 +108,7 @@ italic&|[0..ni-1]fix_word|\cr
lig\_kern&|[0..nl-1]lig_kern_command|\cr
kern&|[0..nk-1]fix_word|\cr
exten&|[0..ne-1]extensible_recipe|\cr
-param&|[1..np]fix_word|\cr}}$$
+param&\omit |[1..np]fix_word|\cr}}$$
The most important data type used here is a |@!fix_word|, which is
a 32-bit representation of a binary fraction. A |fix_word| is a signed
quantity, with the two's complement of the entire word used to represent
@@ -116,7 +117,7 @@ binary point; thus, the largest |fix_word| value is $2048-2^{-20}$, and
the smallest is $-2048$. We will see below, however, that all but two of
the |fix_word| values must lie between $-16$ and $+16$.
-@ The first data array is a block of header information, which contains
+The first data array is a block of header information, which contains
general facts about the font. The header must contain at least two words,
|header[0]| and |header[1]|, whose meaning is explained below.
Additional header information of use to other software routines might
@@ -160,7 +161,7 @@ value; thus, |header[1]| and |param[1]| are the only |fix_word|
entries in the whole \.{TFM} file whose first byte might be something
besides 0 or 255.
-@ Next comes the |char_info| array, which contains one |@!char_info_word|
+Next comes the |char_info| array, which contains one |@!char_info_word|
per character. Each word in this part of a \.{TFM} file contains six fields
packed into four bytes as follows.
@@ -203,9 +204,8 @@ Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]=
value of zero. The |width_index| should never be zero unless the
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
@@ -222,22 +222,17 @@ It returns the value of the internal font number that was just loaded.
If an error is detected, an error message is issued and no font
information is stored; |null_font| is returned in this case.
-@d bad_tfm=11 {label for |read_font_info|}
-@d abort==goto bad_tfm {do this when the \.{TFM} data is wrong}
-
-*/
-
-/*
+@
The |tag| field in a |char_info_word| has four values that explain how to
interpret the |remainder| field.
-\yskip\hangg|tag=0| (|no_tag|) means that |remainder| is unused.\par
-\hangg|tag=1| (|lig_tag|) means that this character has a ligature/kerning
+\yskip\hang|tag=0| (|no_tag|) means that |remainder| is unused.\par
+\hang|tag=1| (|lig_tag|) means that this character has a ligature/kerning
program starting at position |remainder| in the |lig_kern| array.\par
-\hangg|tag=2| (|list_tag|) means that this character is part of a chain of
+\hang|tag=2| (|list_tag|) means that this character is part of a chain of
characters of ascending sizes, and not the largest in the chain. The
|remainder| field gives the character code of the next larger character.\par
-\hangg|tag=3| (|ext_tag|) means that this character code represents an
+\hang|tag=3| (|ext_tag|) means that this character code represents an
extensible character, i.e., a character that is built up of smaller pieces
so that it can be made arbitrarily large. The pieces are specified in
|@!exten[remainder]|.\par
@@ -246,9 +241,9 @@ Characters with |tag=2| and |tag=3| are treated as characters with |tag=0|
unless they are used in special circumstances in math formulas. For example,
the \.{\\sum} operation looks for a |list_tag|, and the \.{\\left}
operation looks for both |list_tag| and |ext_tag|.
-*/
-/* The |lig_kern| array contains instructions in a simple programming language
+
+@ The |lig_kern| array contains instructions in a simple programming language
that explains what to do for special letter pairs. Each word in this array,
in a \.{TFM} file, is a |@!lig_kern_command| of four bytes.
@@ -299,10 +294,9 @@ $$\hbox{|256*op_byte+remainder<nl|.}$$
If such an instruction is encountered during
normal program execution, it denotes an unconditional halt; no ligature
or kerning command is performed.
-*/
-/*
- Extensible characters are specified by an |@!extensible_recipe|, which
+
+@ Extensible characters are specified by an |@!extensible_recipe|, which
consists of four bytes in a \.{TFM} file,
called |@!top|, |@!mid|, |@!bot|, and |@!rep| (in this order).
In an \.{OFM} file, each field takes two bytes, for eight in total.
@@ -318,9 +312,9 @@ in the latter case we can have $TR^kB$ for both even and odd values of~|k|.
The width of the extensible character is the width of $R$; and the
height-plus-depth is the sum of the individual height-plus-depths of the
components used, since the pieces are butted together in a vertical list.
-*/
-/*
+
+@
The final portion of a \.{TFM} file is the |param| array, which is another
sequence of |fix_word| values.
@@ -350,17 +344,16 @@ ends of sentences.
If fewer than seven parameters are present, \TeX\ sets the missing parameters
to zero. Fonts used for math symbols are required to have
additional parameter information, which is explained later.
-*/
-/*
+
+@
There are programs called \.{TFtoPL} and \.{PLtoTF} that convert
between the \.{TFM} format and a symbolic property-list format
that can be easily edited. These programs contain extensive
diagnostic information, so \TeX\ does not have to bother giving
precise details about why it rejects a particular \.{TFM} file.
-*/
-
+@c
#define tfm_abort { font_tables[f]->_font_name = NULL; \
font_tables[f]->_font_area = NULL; \
xfree(tfm_buffer); xfree(kerns); \
@@ -374,32 +367,31 @@ additional parameter information, which is explained later.
xfree(italics); xfree(extens); xfree(lig_kerns); \
xfree(xligs); xfree(xkerns); return 1; }
-
-static int open_tfm_file(const char *nom, unsigned char **tfm_buf, integer * tfm_siz)
+@ @c
+static int open_tfm_file(const char *nom, unsigned char **tfm_buf, int *tfm_siz)
{
boolean res; /* was the callback successful? */
boolean opened; /* was |tfm_file| successfully opened? */
- integer callback_id;
+ int 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);
+ char *fname = luatex_find_file(nom, find_font_file_callback);
+ if (!fname)
+ return -1;
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);
+ res =
+ run_callback(callback_id, "S->bSd", fname, &opened, tfm_buf,
+ tfm_siz);
if (res && opened && (*tfm_siz > 0)) {
return 1;
}
if (!opened)
return -1;
} else {
- if (ofm_open_in(tfm_file)) {
+ if (luatex_open_input
+ (&(tfm_file), fname, kpse_ofm_format, FOPEN_RBIN_MODE, true)) {
res = read_tfm_file(tfm_file, tfm_buf, tfm_siz);
- b_close(tfm_file);
+ close_file(tfm_file);
if (res) {
return 1;
}
@@ -411,7 +403,7 @@ static int open_tfm_file(const char *nom, unsigned char **tfm_buf, integer * tfm
}
-/*
+@
Note: A malformed \.{TFM} file might be shorter than it claims to be;
thus |eof(tfm_file)| might be true when |read_font_info| refers to
|tfm_file^| or when it says |get(tfm_file)|. If such circumstances
@@ -419,7 +411,7 @@ static int open_tfm_file(const char *nom, unsigned char **tfm_buf, integer * tfm
for example by defining |fget| to be `\ignorespaces|begin get(tfm_file);|
|if eof(tfm_file) then abort; end|\unskip'.
@^system dependencies@>
-*/
+@c
#define fget tfm_byte++
#define fbyte tfm_buffer[tfm_byte]
@@ -456,7 +448,7 @@ static int open_tfm_file(const char *nom, unsigned char **tfm_buf, integer * tfm
ci._depth_index=b%256; \
fget; read_sixteen_unsigned(c); \
ci._italic_index=c>>8; \
- ci._tag=c%4; \
+ ci._tag=(unsigned char)(c%4); \
fget; read_sixteen_unsigned(d); \
ci._remainder=d; \
} else { \
@@ -467,28 +459,28 @@ static int open_tfm_file(const char *nom, unsigned char **tfm_buf, integer * tfm
ci._depth_index=b%16; \
c=tfm_buffer[++tfm_byte]; \
ci._italic_index=c>>2; \
- ci._tag=c%4; \
+ ci._tag=(unsigned char)(c%4); \
d=tfm_buffer[++tfm_byte]; \
ci._remainder=d; \
} }
#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; \
- } 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; \
- d=tfm_buffer[++tfm_byte]; q.b3=d; \
+ { if (font_level!=-1) { \
+ fget; read_sixteen_unsigned(a); q.b0=(quarterword)a; \
+ fget; read_sixteen_unsigned(b); q.b1=(quarterword)b; \
+ fget; read_sixteen_unsigned(c); q.b2=(quarterword)c; \
+ fget; read_sixteen_unsigned(d); q.b3=(quarterword)d; \
+ } else { \
+ a=tfm_buffer[++tfm_byte]; q.b0=(quarterword)a; \
+ b=tfm_buffer[++tfm_byte]; q.b1=(quarterword)b; \
+ c=tfm_buffer[++tfm_byte]; q.b2=(quarterword)c; \
+ d=tfm_buffer[++tfm_byte]; q.b3=(quarterword)d; \
} }
#define check_byte_range(z) { if ((z<bc)||(z>ec)) tfm_abort ; }
-/* A |fix_word| whose four bytes are $(a,b,c,d)$ from left to right represents
+@ A |fix_word| whose four bytes are $(a,b,c,d)$ from left to right represents
the number
$$x=\left\{\vcenter{\halign{$#$,\hfil\qquad&if $#$\hfil\cr
b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=0;\cr
@@ -505,8 +497,8 @@ static int open_tfm_file(const char *nom, unsigned char **tfm_buf, integer * tfm
if $a=0$, or the same quantity minus $\alpha=2^{4+e}z^\prime$ if $a=255$.
This calculation must be done exactly, in order to guarantee portability
of \TeX\ between computers.
-*/
+@c
#define store_scaled(zz) \
{ fget; a=fbyte; fget; b=fbyte; \
fget; c=fbyte; fget; d=fbyte; \
@@ -518,9 +510,9 @@ scaled store_scaled_f(scaled sq, scaled z_in)
{
eight_bits a, b, c, d;
scaled sw;
- static integer alpha, beta; /* beta:1..16 */
+ static int alpha, beta; /* beta:1..16 */
static scaled z, z_prev = 0;
- /* @<Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$@>; */
+ /* Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */
if (z_in != z_prev || z_prev == 0) {
z = z_prev = z_in;
alpha = 16;
@@ -532,22 +524,22 @@ scaled store_scaled_f(scaled sq, scaled z_in)
alpha *= z;
};
if (sq >= 0) {
- d = sq % 256; /* any "mod 256" not really needed, would typecast alone be safe? */
+ d = (eight_bits) (sq % 256);
sq = sq / 256;
- c = sq % 256;
+ c = (eight_bits) (sq % 256);
sq = sq / 256;
- b = sq % 256;
+ b = (eight_bits) (sq % 256);
sq = sq / 256;
- a = sq % 256;
+ a = (eight_bits) (sq % 256);
} else {
sq = (sq + 1073741824) + 1073741824; /* braces for optimizing compiler */
- d = sq % 256;
+ d = (eight_bits) (sq % 256);
sq = sq / 256;
- c = sq % 256;
+ c = (eight_bits) (sq % 256);
sq = sq / 256;
- b = sq % 256;
+ b = (eight_bits) (sq % 256);
sq = sq / 256;
- a = (sq + 128) % 256;
+ a = (eight_bits) ((sq + 128) % 256);
}
sw = (((((d * z) >> 8) + (c * z)) >> 8) + (b * z)) / beta;
if (a == 0)
@@ -555,56 +547,59 @@ scaled store_scaled_f(scaled sq, scaled z_in)
else if (a == 255)
return (sw - alpha);
else
- pdf_error(maketexstring("vf"), maketexstring("vf scaling"));
+ pdf_error("vf", "vf scaling");
return sw; /* not reached, just to make the compiler happy */
}
+@ @c
#define check_existence(z) \
{ check_byte_range(z); \
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;
+ int _kern_index;
+ int _lig_index;
+ int _width_index;
+ int _height_index;
+ int _depth_index;
+ int _italic_index;
+ int _remainder;
unsigned char _tag;
} tfmcharacterinfo;
-int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
+@ @c
+int read_tfm_info(internal_font_number f, const char *cnom, scaled s)
{
- integer k; /* index into |font_info| */
+ int 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;
+ int a, b, c, d; /* byte variables */
+ int i; /* counter */
+ int font_level, header_length;
+ int 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;
+ int bch_label; /* left boundary start location, or infinity */
+ int bchar; /* |:0..too_big_char;| *//* right boundary character, or |too_big_char| */
+ int first_two;
scaled z; /* the design size or the ``at'' size */
- integer alpha;
+ int alpha;
char beta; /* :1..16 */
- integer *xligs, *xkerns; /* aux. for ligkern processing */
+ int *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| */
+ int tfm_byte = 0; /* index into |tfm_buffer| */
+ int 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 */
+ int tfm_size = 0; /* total size of the tfm file */
+ int tmp;
widths = NULL;
heights = NULL;
@@ -634,7 +629,7 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
set_font_name(f, tmpnam);
set_font_area(f, NULL);
- /* @<Read the {\.{TFM}} size fields@>; */
+ /* Read the {\.{TFM}} size fields */
nco = 0;
ncw = 0;
npc = 0;
@@ -716,28 +711,29 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
if (lf * 4 > tfm_size)
tfm_abort;
- /* @<Use size fields to allocate font information@>; */
+ /* Use size fields to allocate font information */
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));
+ widths = xmalloc((unsigned) ((unsigned) nw * sizeof(scaled)));
+ heights = xmalloc((unsigned) ((unsigned) nh * sizeof(scaled)));
+ depths = xmalloc((unsigned) ((unsigned) nd * sizeof(scaled)));
+ italics = xmalloc((unsigned) ((unsigned) ni * sizeof(scaled)));
+ extens = xmalloc((unsigned) ((unsigned) ne * sizeof(four_quarters)));
+ lig_kerns = xmalloc((unsigned) ((unsigned) nl * sizeof(four_quarters)));
+ kerns = xmalloc((unsigned) ((unsigned) nk * sizeof(scaled)));
- /* @<Read the {\.{TFM}} header@>; */
+ /* Read the {\.{TFM}} header */
/* 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));
+ store_four_bytes(tmp);
+ font_checksum(f) = (unsigned) tmp;
fget;
read_sixteen(z); /* this rejects a negative design size */
fget;
@@ -768,17 +764,17 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
saved_tfm_byte = tfm_byte;
tfm_byte = (header_length + slh + ncw) * 4 - 1;
- /* @<Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$@>; */
+ /* Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */
alpha = 16;
while (z >= 040000000) {
z = z >> 1;
alpha = alpha + alpha;
};
- beta = 256 / alpha;
+ beta = (char) (256 / alpha);
alpha = alpha * z;
- /* @<Read box dimensions@>; */
+ /* Read box dimensions */
for (k = 0; k < nw; k++) {
store_scaled(sw);
@@ -806,7 +802,7 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
tfm_abort; /* \\{italic}[0] must be zero */
- /* @<Read ligature/kern program@>; */
+ /* Read ligature/kern program */
bch_label = nl; /* infinity */
bchar = 65536;
@@ -820,9 +816,13 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
if (a == 255 && k == 0)
bchar = b;
} else {
- /* if (b!=bchar) check_existence(b); */
+#if 0
+ if (b!=bchar) check_existence(b);
+#endif
if (c < 128) {
- /* check_existence(d); *//* check ligature */
+#if 0
+ check_existence(d); /* check ligature */
+#endif
} else if (256 * (c - 128) + d >= nk) {
tfm_abort; /* check kern */
}
@@ -840,13 +840,13 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
kerns[k] = sw;
}
- /* @<Read extensible character recipes@>; */
+ /* Read extensible character recipes */
for (k = 0; k < ne; k++) {
read_four_quarters(qw);
extens[k] = qw;
}
- /* @<Read font parameters@>; */
+ /* Read font parameters */
if (np > 7) {
set_font_params(f, np);
@@ -876,10 +876,10 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
fkerns = 0;
if (bch_label != nl) {
k = bch_label;
- /*
+#if 0
if (skip_byte(k) > stop_flag)
k = lig_kern_restart(k);
- */
+#endif
while (1) {
if (skip_byte(k) <= stop_flag) {
if (op_byte(k) >= kern_flag) { /* kern */
@@ -899,16 +899,16 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
}
if (fkerns > 0 || fligs > 0) {
if (fligs > 0)
- cligs = xcalloc((fligs + 1), sizeof(liginfo));
+ cligs = xcalloc((unsigned) (fligs + 1), sizeof(liginfo));
if (fkerns > 0)
- ckerns = xcalloc((fkerns + 1), sizeof(kerninfo));
+ ckerns = xcalloc((unsigned) (fkerns + 1), sizeof(kerninfo));
fligs = 0;
fkerns = 0;
k = bch_label;
- /*
- if (skip_byte(k) > stop_flag)
+#if 0
+ if (skip_byte(k) > stop_flag)
k = lig_kern_restart(k);
- */
+#endif
while (1) {
if (skip_byte(k) <= stop_flag) {
if (op_byte(k) >= kern_flag) { /* kern */
@@ -917,7 +917,7 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
rem_byte(k)]);
fkerns++;
} else { /* lig */
- set_ligature_item(cligs[fligs], (op_byte(k) * 2 + 1),
+ set_ligature_item(cligs[fligs], (char) (op_byte(k) * 2 + 1),
next_char(k), rem_byte(k));
fligs++;
}
@@ -946,7 +946,7 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
}
}
- /* @<Read character data@>; */
+ /* Read character data */
for (k = bc; k <= ec; k++) {
store_char_info(k);
if (ci._width_index == 0)
@@ -971,7 +971,7 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
the largest character code in the cycle.
*/
check_byte_range(d);
- while (d < k) { /* current_character == k */
+ 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 */
@@ -1002,8 +1002,8 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
/* first pass: count ligs and kerns */
- xligs = xcalloc((ec + 1), sizeof(integer));
- xkerns = xcalloc((ec + 1), sizeof(integer));
+ xligs = xcalloc((unsigned) (ec + 1), sizeof(int));
+ xkerns = xcalloc((unsigned) (ec + 1), sizeof(int));
for (i = bc; i <= ec; i++) {
if (char_tag(f, i) == lig_tag) {
@@ -1046,9 +1046,9 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
k = lig_kern_restart(k);
/* now k is the start index */
if (xligs[i] > 0)
- cligs = xcalloc((xligs[i] + 1), sizeof(liginfo));
+ cligs = xcalloc((unsigned) (xligs[i] + 1), sizeof(liginfo));
if (xkerns[i] > 0)
- ckerns = xcalloc((xkerns[i] + 1), sizeof(kerninfo));
+ ckerns = xcalloc((unsigned) (xkerns[i] + 1), sizeof(kerninfo));
while (1) {
if (skip_byte(k) <= stop_flag) {
if (op_byte(k) >= kern_flag) { /* kern */
@@ -1065,11 +1065,12 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
} else { /* lig */
if (next_char(k) == bchar) {
set_ligature_item(cligs[fligs],
- (op_byte(k) * 2 + 1),
+ (char) (op_byte(k) * 2 + 1),
right_boundarychar, rem_byte(k));
fligs++;
}
- set_ligature_item(cligs[fligs], (op_byte(k) * 2 + 1),
+ set_ligature_item(cligs[fligs],
+ (char) (op_byte(k) * 2 + 1),
next_char(k), rem_byte(k));
fligs++;
}
@@ -1100,7 +1101,7 @@ int read_tfm_info(internalfontnumber f, const char *cnom, scaled s)
}
- /* @<Make final adjustments and |goto done|@> */
+ /* Make final adjustments and |goto done| */
/* 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
diff --git a/Build/source/texk/web2c/luatexdir/font/tounicode.c b/Build/source/texk/web2c/luatexdir/font/tounicode.w
index a4029f5220d..9ca84210606 100644
--- a/Build/source/texk/web2c/luatexdir/font/tounicode.c
+++ b/Build/source/texk/web2c/luatexdir/font/tounicode.w
@@ -1,31 +1,35 @@
-/* tounicode.c
- Copyright 2006 Han The Thanh, <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% tounicode.w
- This file is part of LuaTeX.
+% Copyright 2006 Han The Thanh, <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: tounicode.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/tounicode.c $";
+ "$Id: tounicode.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/tounicode.w $";
+@ @c
#define isXdigit(c) (isdigit(c) || ('A' <= (c) && (c) <= 'F'))
#define UNI_UNDEF -1
-#define UNI_STRING -2 /* string allocated by def_tounicode() */
-#define UNI_EXTRA_STRING -3 /* string allocated by set_glyph_unicode() */
+#define UNI_STRING -2 /* string allocated by |def_tounicode()| */
+#define UNI_EXTRA_STRING -3 /* string allocated by |set_glyph_unicode()| */
static struct avl_table *glyph_unicode_tree = NULL;
@@ -63,9 +67,10 @@ void glyph_unicode_free(void)
avl_destroy(glyph_unicode_tree, destroy_glyph_unicode_entry);
}
+@ @c
void def_tounicode(str_number glyph, str_number unistr)
{
- char buf[SMALL_BUF_SIZE], *p;
+ char buf[SMALL_BUF_SIZE], *p, *ph;
char buf2[SMALL_BUF_SIZE], *q;
int valid_unistr; /* 0: invalid; 1: unicode value; 2: string */
int i, l;
@@ -74,11 +79,13 @@ void def_tounicode(str_number glyph, str_number unistr)
p = makecstring(glyph);
assert(strlen(p) < SMALL_BUF_SIZE);
- strcpy(buf, p); /* copy the result to buf before next call of makecstring() */
+ strcpy(buf, p);
+ free(p);
p = makecstring(unistr);
+ ph = p;
while (*p == ' ')
p++; /* ignore leading spaces */
- l = strlen(p);
+ l = (int) strlen(p);
while (l > 0 && p[l - 1] == ' ')
l--; /* ignore traling spaces */
valid_unistr = 1; /* a unicode value is the most common case */
@@ -125,12 +132,14 @@ void def_tounicode(str_number glyph, str_number unistr)
}
aa = avl_probe(glyph_unicode_tree, gu);
assert(aa != NULL);
+ free(ph);
}
+@ @c
static long check_unicode_value(char *s, boolean multiple_value)
{
- int l = strlen(s);
+ int l = (int) strlen(s);
int i;
long code;
@@ -165,6 +174,7 @@ static long check_unicode_value(char *s, boolean multiple_value)
return code;
}
+@ @c
static char *utf16be_str(long code)
{
static char buf[SMALL_BUF_SIZE];
@@ -177,17 +187,18 @@ static char *utf16be_str(long code)
sprintf(buf, "%04lX", code);
else {
v = code - 0x10000;
- vh = v / 0x400 + 0xD800;
- vl = v % 0x400 + 0xDC00;
+ vh = (unsigned) (v / 0x400 + 0xD800);
+ vl = (unsigned) (v % 0x400 + 0xDC00);
sprintf(buf, "%04X%04X", vh, vl);
}
return buf;
}
-/* this function set proper values to *gp based on s; in case it returns
- * gp->code == UNI_EXTRA_STRING then the caller is responsible for freeing
- * gp->unicode_seq too */
+@ This function set proper values to |*gp| based on |s|; in case it returns
+ |gp->code == UNI_EXTRA_STRING| then the caller is responsible for freeing
+ |gp->unicode_seq| too.
+@c
static void set_glyph_unicode(char *s, glyph_unicode_entry * gp)
{
char buf[SMALL_BUF_SIZE], buf2[SMALL_BUF_SIZE], *p;
@@ -203,14 +214,14 @@ static void set_glyph_unicode(char *s, glyph_unicode_entry * gp)
p = strchr(s, '.');
if (p != NULL) {
*buf = 0;
- strncat(buf, s, p - s);
+ strncat(buf, s, (size_t) (p - s));
s = buf;
}
if (strlen(s) == 0)
return;
- /* check for case of multiple components separated by '_' */
+ /* check for case of multiple components separated by |'_'| */
p = strchr(s, '_');
if (p != NULL) {
assert(strlen(s) < sizeof(buf));
@@ -293,12 +304,13 @@ static void set_glyph_unicode(char *s, glyph_unicode_entry * gp)
}
}
+@ @c
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) {
+ (s = get_charinfo_tounicode(char_info(f, (int) index))) != NULL) {
gp->code = UNI_EXTRA_STRING;
gp->unicode_seq = xstrdup(s);
} else {
@@ -307,19 +319,22 @@ static void set_cid_glyph_unicode(long index, glyph_unicode_entry * gp,
}
-integer write_tounicode(char **glyph_names, char *name)
+@ @c
+int write_tounicode(PDF pdf, char **glyph_names, char *name)
{
char buf[SMALL_BUF_SIZE], *p;
static char builtin_suffix[] = "-builtin";
short range_size[257];
glyph_unicode_entry gtab[257];
- integer objnum;
+ int objnum;
int i, j;
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!"); */
- fixed_gen_tounicode = 0;
+#ifdef DEBUG
+ pdftex_warn("no GlyphToUnicode entry has been inserted yet!");
+#endif
+ pdf->gen_tounicode = 0;
return 0;
}
strcpy(buf, name);
@@ -328,27 +343,27 @@ integer write_tounicode(char **glyph_names, char *name)
else
strcat(buf, builtin_suffix); /* ".enc" not present, this is a builtin
encoding so the name is eg "cmr10-builtin" */
- objnum = pdf_new_objnum();
- pdf_begin_dict(objnum, 0);
- pdf_begin_stream();
- pdf_printf("%%!PS-Adobe-3.0 Resource-CMap\n"
- "%%%%DocumentNeededResources: ProcSet (CIDInit)\n"
- "%%%%IncludeResource: ProcSet (CIDInit)\n"
- "%%%%BeginResource: CMap (TeX-%s-0)\n"
- "%%%%Title: (TeX-%s-0 TeX %s 0)\n"
- "%%%%Version: 1.000\n"
- "%%%%EndComments\n"
- "/CIDInit /ProcSet findresource begin\n"
- "12 dict begin\n"
- "begincmap\n"
- "/CIDSystemInfo\n"
- "<< /Registry (TeX)\n"
- "/Ordering (%s)\n"
- "/Supplement 0\n"
- ">> def\n"
- "/CMapName /TeX-%s-0 def\n"
- "/CMapType 2 def\n"
- "1 begincodespacerange\n"
+ objnum = pdf_new_objnum(pdf);
+ pdf_begin_dict(pdf, objnum, 0);
+ pdf_begin_stream(pdf);
+ pdf_printf(pdf, "%%!PS-Adobe-3.0 Resource-CMap\n"@/
+ "%%%%DocumentNeededResources: ProcSet (CIDInit)\n"@/
+ "%%%%IncludeResource: ProcSet (CIDInit)\n"@/
+ "%%%%BeginResource: CMap (TeX-%s-0)\n"@/
+ "%%%%Title: (TeX-%s-0 TeX %s 0)\n"@/
+ "%%%%Version: 1.000\n"@/
+ "%%%%EndComments\n"@/
+ "/CIDInit /ProcSet findresource begin\n"@/
+ "12 dict begin\n"@/
+ "begincmap\n"@/
+ "/CIDSystemInfo\n"@/
+ "<< /Registry (TeX)\n"@/
+ "/Ordering (%s)\n"@/
+ "/Supplement 0\n"@/
+ ">> def\n"@/
+ "/CMapName /TeX-%s-0 def\n"@/
+ "/CMapType 2 def\n"@/
+ "1 begincodespacerange\n"@/
"<00> <FF>\n" "endcodespacerange\n", buf, buf, buf, buf, buf);
/* set gtab */
@@ -358,7 +373,7 @@ integer write_tounicode(char **glyph_names, char *name)
}
gtab[256].code = UNI_UNDEF;
- /* set range_size */
+ /* set |range_size| */
for (i = 0; i < 256;) {
if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) {
range_size[i] = 1; /* single entry */
@@ -373,11 +388,11 @@ integer write_tounicode(char **glyph_names, char *name)
i++;
/* at this point i is the last entry of the subrange */
i++; /* move i to the next entry */
- range_size[j] = i - j;
+ range_size[j] = (short) (i - j);
}
}
- /* calculate bfrange_count and bfchar_count */
+ /* calculate |bfrange_count| and |bfchar_count| */
bfrange_count = 0;
bfchar_count = 0;
for (i = 0; i < 256;) {
@@ -399,16 +414,16 @@ integer write_tounicode(char **glyph_names, char *name)
else
subrange_count = bfrange_count;
bfrange_count -= subrange_count;
- pdf_printf("%i beginbfrange\n", subrange_count);
+ pdf_printf(pdf, "%i beginbfrange\n", subrange_count);
for (j = 0; j < subrange_count; j++) {
while (range_size[i] <= 1 && i < 256)
i++;
assert(i < 256);
- pdf_printf("<%02X> <%02X> <%s>\n", i, i + range_size[i] - 1,
+ pdf_printf(pdf, "<%02X> <%02X> <%s>\n", i, i + range_size[i] - 1,
utf16be_str(gtab[i].code));
i += range_size[i];
}
- pdf_printf("endbfrange\n");
+ pdf_printf(pdf, "endbfrange\n");
if (bfrange_count > 0)
goto write_bfrange;
@@ -420,79 +435,80 @@ integer write_tounicode(char **glyph_names, char *name)
else
subrange_count = bfchar_count;
bfchar_count -= subrange_count;
- pdf_printf("%i beginbfchar\n", subrange_count);
+ pdf_printf(pdf, "%i beginbfchar\n", subrange_count);
for (j = 0; j < subrange_count; j++) {
while (i < 256) {
if (range_size[i] > 1)
i += range_size[i];
else if (range_size[i] == 0)
i++;
- else /* range_size[i] == 1 */
+ else /* |range_size[i] == 1| */
break;
}
assert(i < 256 && gtab[i].code != UNI_UNDEF);
if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) {
assert(gtab[i].unicode_seq != NULL);
- pdf_printf("<%02X> <%s>\n", i, gtab[i].unicode_seq);
+ pdf_printf(pdf, "<%02X> <%s>\n", i, gtab[i].unicode_seq);
} else
- pdf_printf("<%02X> <%s>\n", i, utf16be_str(gtab[i].code));
+ pdf_printf(pdf, "<%02X> <%s>\n", i, utf16be_str(gtab[i].code));
i++;
}
- pdf_printf("endbfchar\n");
+ pdf_printf(pdf, "endbfchar\n");
if (bfchar_count > 0)
goto write_bfchar;
- /* free strings allocated by set_glyph_unicode() */
+ /* free strings allocated by |set_glyph_unicode()| */
for (i = 0; i < 256; ++i) {
if (gtab[i].code == UNI_EXTRA_STRING)
xfree(gtab[i].unicode_seq);
}
- pdf_printf("endcmap\n"
+ pdf_printf(pdf, "endcmap\n"
"CMapName currentdict /CMap defineresource pop\n"
"end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n");
- pdf_end_stream();
+ pdf_end_stream(pdf);
return objnum;
}
-integer write_cid_tounicode(fo_entry * fo, internalfontnumber f)
+@ @c
+int write_cid_tounicode(PDF pdf, fo_entry * fo, internal_font_number f)
{
int range_size[65537];
glyph_unicode_entry gtab[65537];
- integer objnum;
+ int objnum;
int i, j, k;
int bfchar_count, bfrange_count, subrange_count;
char *buf;
assert(fo->fd->fontname);
- buf = xmalloc(strlen(fo->fd->fontname) + 8);
+ buf = xmalloc((unsigned) (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);
- pdf_begin_stream();
- pdf_printf("%%!PS-Adobe-3.0 Resource-CMap\n"
- "%%%%DocumentNeededResources: ProcSet (CIDInit)\n"
- "%%%%IncludeResource: ProcSet (CIDInit)\n"
- "%%%%BeginResource: CMap (TeX-%s-0)\n"
- "%%%%Title: (TeX-%s-0 TeX %s 0)\n"
- "%%%%Version: 1.000\n"
- "%%%%EndComments\n"
- "/CIDInit /ProcSet findresource begin\n"
- "12 dict begin\n"
- "begincmap\n"
- "/CIDSystemInfo\n"
- "<< /Registry (TeX)\n"
- "/Ordering (%s)\n"
- "/Supplement 0\n"
- ">> def\n"
- "/CMapName /TeX-Identity-%s def\n"
- "/CMapType 2 def\n"
- "1 begincodespacerange\n"
- "<0000> <FFFF>\n"
+ objnum = pdf_new_objnum(pdf);
+ pdf_begin_dict(pdf, objnum, 0);
+ pdf_begin_stream(pdf);
+ pdf_printf(pdf, "%%!PS-Adobe-3.0 Resource-CMap\n"@/
+ "%%%%DocumentNeededResources: ProcSet (CIDInit)\n"@/
+ "%%%%IncludeResource: ProcSet (CIDInit)\n"@/
+ "%%%%BeginResource: CMap (TeX-%s-0)\n"@/
+ "%%%%Title: (TeX-%s-0 TeX %s 0)\n"@/
+ "%%%%Version: 1.000\n"@/
+ "%%%%EndComments\n"@/
+ "/CIDInit /ProcSet findresource begin\n"@/
+ "12 dict begin\n"@/
+ "begincmap\n"@/
+ "/CIDSystemInfo\n"@/
+ "<< /Registry (TeX)\n"@/
+ "/Ordering (%s)\n"@/
+ "/Supplement 0\n"@/
+ ">> def\n"@/
+ "/CMapName /TeX-Identity-%s def\n"@/
+ "/CMapType 2 def\n"@/
+ "1 begincodespacerange\n"@/
+ "<0000> <FFFF>\n"@/
"endcodespacerange\n", buf, buf, buf, buf, buf);
xfree(buf);
/* set up gtab */
@@ -502,7 +518,7 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber 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)) {
+ if (quick_char_exists(k, i) && char_used(k, i)) {
j = char_index(k, i);
if (gtab[j].code == UNI_UNDEF) {
set_cid_glyph_unicode(i, &gtab[j], f);
@@ -512,7 +528,7 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber f)
}
}
- /* set range_size */
+ /* set |range_size| */
for (i = 0; i < 65536;) {
if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) {
range_size[i] = 1; /* single entry */
@@ -520,7 +536,7 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber f)
} else if (gtab[i].code == UNI_UNDEF) {
range_size[i] = 0; /* no entry */
i++;
- } else { /* gtab[i].code >= 0 */
+ } else { /* |gtab[i].code >= 0| */
j = i;
while (i < 65536 && gtab[i + 1].code >= 0 &&
gtab[i].code + 1 == gtab[i + 1].code)
@@ -531,7 +547,7 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber f)
}
}
- /* calculate bfrange_count and bfchar_count */
+ /* calculate |bfrange_count| and |bfchar_count| */
bfrange_count = 0;
bfchar_count = 0;
for (i = 0; i < 65536;) {
@@ -553,16 +569,16 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber f)
else
subrange_count = bfrange_count;
bfrange_count -= subrange_count;
- pdf_printf("%i beginbfrange\n", subrange_count);
+ pdf_printf(pdf, "%i beginbfrange\n", subrange_count);
for (j = 0; j < subrange_count; j++) {
while (range_size[i] <= 1 && i < 65536)
i++;
assert(i < 65536);
- pdf_printf("<%04X> <%04X> <%s>\n", i, i + range_size[i] - 1,
+ pdf_printf(pdf, "<%04X> <%04X> <%s>\n", i, i + range_size[i] - 1,
utf16be_str(gtab[i].code));
i += range_size[i];
}
- pdf_printf("endbfrange\n");
+ pdf_printf(pdf, "endbfrange\n");
if (bfrange_count > 0)
goto write_bfrange;
@@ -574,37 +590,37 @@ integer write_cid_tounicode(fo_entry * fo, internalfontnumber f)
else
subrange_count = bfchar_count;
bfchar_count -= subrange_count;
- pdf_printf("%i beginbfchar\n", subrange_count);
+ pdf_printf(pdf, "%i beginbfchar\n", subrange_count);
for (j = 0; j < subrange_count; j++) {
while (i < 65536) {
if (range_size[i] > 1)
i += range_size[i];
else if (range_size[i] == 0)
i++;
- else /* range_size[i] == 1 */
+ else /* |range_size[i] == 1| */
break;
}
assert(i < 65536 && gtab[i].code != UNI_UNDEF);
if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) {
assert(gtab[i].unicode_seq != NULL);
- pdf_printf("<%04X> <%s>\n", i, gtab[i].unicode_seq);
+ pdf_printf(pdf, "<%04X> <%s>\n", i, gtab[i].unicode_seq);
} else
- pdf_printf("<%04X> <%s>\n", i, utf16be_str(gtab[i].code));
+ pdf_printf(pdf, "<%04X> <%s>\n", i, utf16be_str(gtab[i].code));
i++;
}
- pdf_printf("endbfchar\n");
+ pdf_printf(pdf, "endbfchar\n");
if (bfchar_count > 0)
goto write_bfchar;
- /* free strings allocated by set_glyph_unicode() */
+ /* free strings allocated by |set_glyph_unicode()| */
for (i = 0; i < 65536; ++i) {
if (gtab[i].code == UNI_EXTRA_STRING)
xfree(gtab[i].unicode_seq);
}
- pdf_printf("endcmap\n"
+ pdf_printf(pdf, "endcmap\n"
"CMapName currentdict /CMap defineresource pop\n"
"end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n");
- pdf_end_stream();
+ pdf_end_stream(pdf);
return objnum;
}
diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c b/Build/source/texk/web2c/luatexdir/font/tt_glyf.w
index 1ca35e8800f..b22d5748284 100644
--- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c
+++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.w
@@ -1,39 +1,39 @@
-/* tt_glyf.c
-
- Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
- the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% tt_glyf.w
+%
+% Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
+% the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-/*
- * Subsetting glyf, updating loca, hmtx, ...
- *
- */
+@* Subsetting glyf, updating loca, hmtx, etc.
+@ @c
#include "ptexlib.h"
-#include "sfnt.h"
-#include "tt_table.h"
-#include "tt_glyf.h"
-#include "writettf.h"
+#include "font/sfnt.h"
+#include "font/tt_table.h"
+#include "font/tt_glyf.h"
+#include "font/writettf.h"
static const char _svn_version[] =
- "$Id: tt_glyf.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/tt_glyf.c $";
+ "$Id: tt_glyf.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/tt_glyf.w $";
+@ @c
#define NUM_GLYPH_LIMIT 65534
#define TABLE_DATA_ALLOC_SIZE 40960
#define GLYPH_ARRAY_ALLOC_SIZE 256
@@ -97,15 +97,17 @@ USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid)
TT_ERROR("Too many glyphs.");
if (g->num_glyphs >= g->max_glyphs) {
- g->max_glyphs += GLYPH_ARRAY_ALLOC_SIZE;
+ g->max_glyphs = (USHORT) (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;
+ g->used_slot[new_gid / 8] =
+ (unsigned char) (g->used_slot[new_gid /
+ 8] | (1 << (7 - (new_gid % 8))));
+ g->num_glyphs++;
}
if (new_gid > g->last_gid) {
@@ -115,9 +117,9 @@ USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid)
return new_gid;
}
-/*
- * Initialization
- */
+
+@ Initialization
+@c
struct tt_glyphs *tt_build_init(void)
{
struct tt_glyphs *g;
@@ -173,6 +175,7 @@ static int glyf_cmp(const void *v1, const void *v2)
return cmp;
}
+@ @c
int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
{
char *hmtx_table_data = NULL, *loca_table_data = NULL;
@@ -198,12 +201,15 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
TT_ERROR("Too many glyphs.");
/*
- * Read head, hhea, maxp, loca:
- *
- * unitsPerEm --> head
- * numHMetrics --> hhea
- * indexToLocFormat --> head
- * numGlyphs --> maxp
+ 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);
@@ -219,8 +225,8 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
os2 = tt_read_os2__table(sfont);
if (os2) {
- g->default_advh = os2->sTypoAscender - os2->sTypoDescender;
- g->default_tsb = g->default_advh - os2->sTypoAscender;
+ g->default_advh = (USHORT) (os2->sTypoAscender - os2->sTypoDescender);
+ g->default_tsb = (SHORT) (g->default_advh - os2->sTypoAscender);
/* dvipdfmx does this elsewhere! */
fd_cur->font_dim[STEMV_CODE].val =
@@ -252,17 +258,18 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
}
w_stat = NEW(g->emsize + 2, USHORT);
- memset(w_stat, 0, sizeof(USHORT) * (g->emsize + 2));
+ memset(w_stat, 0,
+ (size_t) (sizeof(USHORT) * ((long unsigned) 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.
+ 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 */
@@ -291,9 +298,9 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
g->gd[i].length = len;
g->gd[i].data = NULL;
if (g->gd[i].advw <= g->emsize) {
- w_stat[g->gd[i].advw] += 1;
+ w_stat[g->gd[i].advw]++;
} else {
- w_stat[g->emsize + 1] += 1; /* larger than em */
+ w_stat[g->emsize + 1]++; /* larger than em */
}
if (len == 0) { /* Does not contains any data. */
@@ -305,7 +312,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
g->gd[i].data = p = NEW(len, BYTE);
endptr = p + len;
- sfnt_seek_set(sfont, offset + loc);
+ sfnt_seek_set(sfont, (long) (offset + loc));
number_of_contours = sfnt_get_short(sfont);
p += sfnt_put_short(p, number_of_contours);
@@ -314,10 +321,11 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
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_ */
+ /* |_FIXME_| */
#if 1
- if (!vmtx) /* vertOriginY == sTypeAscender */
- g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury;
+ if (!vmtx) /* |vertOriginY == sTypeAscender| */
+ g->gd[i].tsb =
+ (SHORT) (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);
@@ -325,9 +333,9 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
p += sfnt_put_short(p, g->gd[i].ury);
/* Read evrything else. */
- sfnt_read(p, len - 10, sfont);
+ sfnt_read(p, (int) len - 10, sfont);
/*
- * Fix GIDs of composite glyphs.
+ Fix GIDs of composite glyphs.
*/
if (number_of_contours < 0) {
USHORT flags, cgid, new_gid; /* flag, gid of a component */
@@ -338,9 +346,9 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
/*
* Flags and gid of component glyph are both USHORT.
*/
- flags = ((*p) << 8) | *(p + 1);
+ flags = (USHORT) (((*p) << 8) | *(p + 1));
p += 2;
- cgid = ((*p) << 8) | *(p + 1);
+ cgid = (USHORT) (((*p) << 8) | *(p + 1));
if (cgid >= maxp->numGlyphs) {
TT_ERROR("Invalid gid (%u > %u) in composite glyph %u.",
cgid, maxp->numGlyphs, gid);
@@ -362,9 +370,11 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
p += 8;
} while (flags & MORE_COMPONENTS);
/*
- * TrueType instructions comes here:
- * length_of_instruction (ushort)
- * instruction (byte * length_of_instruction)
+ TrueType instructions comes here:
+
+ |length_of_instruction| (|ushort|)
+
+ instruction (|byte * length_of_instruction|)
*/
}
}
@@ -380,7 +390,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
for (i = 0; i < g->emsize + 1; i++) {
if (w_stat[i] > max_count) {
max_count = w_stat[i];
- g->dw = i;
+ g->dw = (USHORT) i;
}
}
}
@@ -396,10 +406,11 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
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;
+ padlen =
+ (int) ((g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0);
+ glyf_table_size += (ULONG) (g->gd[i].length + (ULONG) padlen);
if (!num_hm_known && last_advw != g->gd[i].advw) {
- hhea->numberOfHMetrics = g->gd[i].gid + 2;
+ hhea->numberOfHMetrics = (USHORT) (g->gd[i].gid + 2);
num_hm_known = 1;
}
}
@@ -407,18 +418,19 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
if (!num_hm_known) {
hhea->numberOfHMetrics = 1;
}
- hmtx_table_size = hhea->numberOfHMetrics * 2 + (g->last_gid + 1) * 2;
+ hmtx_table_size =
+ (ULONG) (hhea->numberOfHMetrics * 2 + (g->last_gid + 1) * 2);
/*
- * Choosing short format does not always give good result
- * when compressed. Sometimes increases size.
+ 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;
+ loca_table_size = (ULONG) ((g->last_gid + 2) * 2);
} else {
head->indexToLocFormat = 1;
- loca_table_size = (g->last_gid + 2) * 4;
+ loca_table_size = (ULONG) ((g->last_gid + 2) * 4);
}
hmtx_table_data = p = NEW(hmtx_table_size, char);
@@ -440,10 +452,11 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
if (head->indexToLocFormat == 0) {
q += sfnt_put_ushort(q, (USHORT) (offset / 2));
} else {
- q += sfnt_put_ulong(q, offset);
+ q += sfnt_put_ulong(q, (LONG) offset);
}
}
- padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0;
+ padlen =
+ (int) ((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);
}
@@ -451,11 +464,12 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
if (head->indexToLocFormat == 0) {
q += sfnt_put_ushort(q, (USHORT) (offset / 2));
} else {
- q += sfnt_put_ulong(q, offset);
+ q += sfnt_put_ulong(q, (LONG) offset);
}
- memset(glyf_table_data + offset, 0, g->gd[i].length + padlen);
+ memset(glyf_table_data + offset, 0,
+ (size_t) (g->gd[i].length + (ULONG) padlen));
memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length);
- offset += g->gd[i].length + padlen;
+ offset += (g->gd[i].length + (ULONG) padlen);
prev = g->gd[i].gid;
/* free data here since it consume much memory */
RELEASE(g->gd[i].data);
@@ -465,7 +479,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
if (head->indexToLocFormat == 0) {
q += sfnt_put_ushort(q, (USHORT) (offset / 2));
} else {
- q += sfnt_put_ulong(q, offset);
+ q += sfnt_put_ulong(q, (LONG) offset);
}
sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data,
@@ -477,7 +491,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g)
}
head->checkSumAdjustment = 0;
- maxp->numGlyphs = g->last_gid + 1;
+ maxp->numGlyphs = (USHORT) (g->last_gid + 1);
/* TODO */
sfnt_set_table(sfont, "maxp", tt_pack_maxp_table(maxp), TT_MAXP_TABLE_SIZE);
@@ -521,12 +535,15 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
TT_ERROR("Invalid font type");
/*
- * Read head, hhea, maxp, loca:
- *
- * unitsPerEm --> head
- * numHMetrics --> hhea
- * indexToLocFormat --> head
- * numGlyphs --> maxp
+ 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);
@@ -541,8 +558,8 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
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;
+ g->default_advh = (USHORT) (os2->sTypoAscender - os2->sTypoDescender);
+ g->default_tsb = (SHORT) (g->default_advh - os2->sTypoAscender);
if (sfnt_find_table_pos(sfont, "vmtx") > 0) {
struct tt_vhea_table *vhea;
@@ -569,9 +586,9 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
}
w_stat = NEW(g->emsize + 2, USHORT);
- memset(w_stat, 0, sizeof(USHORT) * (g->emsize + 2));
+ memset(w_stat, 0, (size_t) ((int) sizeof(USHORT) * (g->emsize + 2)));
/*
- * Read glyf table.
+ Read glyf table.
*/
offset = sfnt_locate_table(sfont, "glyf");
for (i = 0; i < g->num_glyphs; i++) {
@@ -598,9 +615,9 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
g->gd[i].data = NULL;
if (g->gd[i].advw <= g->emsize) {
- w_stat[g->gd[i].advw] += 1;
+ w_stat[g->gd[i].advw]++;
} else {
- w_stat[g->emsize + 1] += 1; /* larger than em */
+ w_stat[g->emsize + 1]++; /* larger than em */
}
if (len == 0) { /* Does not contains any data. */
@@ -609,7 +626,7 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
TT_ERROR("Invalid TrueType glyph data (gid %u).", gid);
}
- sfnt_seek_set(sfont, offset + loc);
+ sfnt_seek_set(sfont, (long) (offset + loc));
number_of_contours = sfnt_get_short(sfont);
/* BoundingBox: FWord x 4 */
@@ -617,10 +634,11 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
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_ */
+ /* |_FIXME_| */
#if 1
- if (!vmtx) /* vertOriginY == sTypeAscender */
- g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury;
+ if (!vmtx) /* |vertOriginY == sTypeAscender| */
+ g->gd[i].tsb =
+ (SHORT) (g->default_advh - g->default_tsb - g->gd[i].ury);
#endif
}
RELEASE(location);
@@ -640,7 +658,7 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g)
for (i = 0; i < g->emsize + 1; i++) {
if (w_stat[i] > max_count) {
max_count = w_stat[i];
- g->dw = i;
+ g->dw = (USHORT) i;
}
}
}
diff --git a/Build/source/texk/web2c/luatexdir/font/tt_table.c b/Build/source/texk/web2c/luatexdir/font/tt_table.w
index d979542b476..35da4284ee8 100644
--- a/Build/source/texk/web2c/luatexdir/font/tt_table.c
+++ b/Build/source/texk/web2c/luatexdir/font/tt_table.w
@@ -1,49 +1,46 @@
-/* tt_table.c
-
- Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
- the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% tt_table.w
+%
+% Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata,
+% the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
#include <stdio.h>
-#ifndef pdfTeX
-# include "system.h"
-# include "error.h"
-# include "mem.h"
-# include "mfileio.h"
-#else
-# include "ptexlib.h"
-#endif
-
-#include "sfnt.h"
-#include "tt_table.h"
+#include "ptexlib.h"
+#include "font/sfnt.h"
+#include "font/tt_table.h"
static const char _svn_version[] =
- "$Id: tt_table.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/tt_table.c $";
+ "$Id: tt_table.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/tt_table.w $";
+
+@ tables contains information refered by other tables
+
+ |maxp->numGlyphs, etc --> loca, etc|
-/*
- tables contains information refered by other tables
- maxp->numGlyphs, etc --> loca, etc
- hhea->numberOfHMetrics --> hmtx
- head->indexToLocFormat --> loca
- head->glyphDataFormat --> glyf
-*/
+ |hhea->numberOfHMetrics --> hmtx|
+ |head->indexToLocFormat --> loca|
+
+ |head->glyphDataFormat --> glyf|
+
+@c
char *tt_pack_head_table(struct tt_head_table *table)
{
int i;
@@ -53,17 +50,17 @@ char *tt_pack_head_table(struct tt_head_table *table)
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_ulong(p, (LONG) table->version);
+ p += sfnt_put_ulong(p, (LONG) table->fontRevision);
+ p += sfnt_put_ulong(p, (LONG) table->checkSumAdjustment);
+ p += sfnt_put_ulong(p, (LONG) 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];
+ *(p++) = (char) (table->created)[i];
}
for (i = 0; i < 8; i++) {
- *(p++) = (table->modified)[i];
+ *(p++) = (char) (table->modified)[i];
}
p += sfnt_put_short(p, table->xMin);
p += sfnt_put_short(p, table->yMin);
@@ -103,8 +100,8 @@ struct tt_head_table *tt_read_head_table(sfnt * 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->macStyle = (USHORT) sfnt_get_short(sfont);
+ table->lowestRecPPEM = (USHORT) sfnt_get_short(sfont);
table->fontDirectionHint = sfnt_get_short(sfont);
table->indexToLocFormat = sfnt_get_short(sfont);
table->glyphDataFormat = sfnt_get_short(sfont);
@@ -117,7 +114,7 @@ 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_ulong(p, (LONG) table->version);
p += sfnt_put_ushort(p, table->numGlyphs);
p += sfnt_put_ushort(p, table->maxPoints);
p += sfnt_put_ushort(p, table->maxContours);
@@ -168,7 +165,7 @@ char *tt_pack_hhea_table(struct tt_hhea_table *table)
char *p, *data;
p = data = NEW(TT_HHEA_TABLE_SIZE, char);
- p += sfnt_put_ulong(p, table->version);
+ p += sfnt_put_ulong(p, (LONG) table->version);
p += sfnt_put_short(p, table->Ascender);
p += sfnt_put_short(p, table->Descender);
p += sfnt_put_short(p, table->LineGap);
@@ -216,14 +213,15 @@ struct tt_hhea_table *tt_read_hhea_table(sfnt * sfont)
return table;
}
-/* vhea */
+@ vhea
+@c
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_ulong(p, (LONG) table->version);
p += sfnt_put_short(p, table->vertTypoAscender);
p += sfnt_put_short(p, table->vertTypoDescender);
p += sfnt_put_short(p, table->vertTypoLineGap);
@@ -304,12 +302,12 @@ struct tt_VORG_table *tt_read_VORG_table(sfnt * sfont)
return vorg;
}
-/*
- * hmtx and vmtx
- *
- * Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea.
- */
+@ hmtx and vmtx
+
+Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea.
+
+@c
struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs,
USHORT numLongMetrics)
{
@@ -327,8 +325,10 @@ struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs,
return m;
}
-/* OS/2 table */
-/* this table may not exist */
+@ OS/2 table
+
+this table may not exist
+@c
struct tt_os2__table *tt_read_os2__table(sfnt * sfont)
{
struct tt_os2__table *table = NULL;
@@ -420,9 +420,9 @@ tt_get_name(sfnt * sfont, char *dest, USHORT destlen,
if (length > destlen - 1) {
fprintf(stderr,
"\n** Notice: Name string too long. Truncating **\n");
- length = destlen - 1;
+ length = (USHORT) (destlen - 1);
}
- sfnt_seek_set(sfont, name_offset + string_offset + offset);
+ sfnt_seek_set(sfont, (long) (name_offset + string_offset + offset));
sfnt_read((unsigned char *) dest, length, sfont);
dest[length] = '\0';
break;
@@ -439,18 +439,6 @@ USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen)
{
USHORT namelen = 0;
-#ifdef XETEX
-
- 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);
-
-#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 ||
@@ -470,7 +458,6 @@ USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen)
*/
namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1);
}
-#endif
return namelen;
}
diff --git a/Build/source/texk/web2c/luatexdir/font/vfovf.c b/Build/source/texk/web2c/luatexdir/font/vfovf.w
index 407076c215e..cc3c93ad8b5 100644
--- a/Build/source/texk/web2c/luatexdir/font/vfovf.c
+++ b/Build/source/texk/web2c/luatexdir/font/vfovf.w
@@ -1,32 +1,31 @@
-/* vfovf.c
+% vfovf.w
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
#include "ptexlib.h"
-#include "luatex-api.h"
-#include "luatexfont.h"
-#include "inc-vfovf.h"
static const char _svn_version[] =
- "$Id: vfovf.c 2448 2009-06-08 07:43:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/vfovf.c $";
+ "$Id: vfovf.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/vfovf.w $";
+@ @c
/* this is a hack! */
#define font_max 5000
@@ -97,13 +96,14 @@ static const char _svn_version[] =
#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 */
+@ go out \.{VF} processing with an error message
+@c
#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"); \
+ tprint("Error in processing VF font ("); \
+ tprint(font_name(f)); \
+ tprint(".vf): "); \
+ tprint(a); \
+ tprint(", virtual font will be ignored"); \
print_ln(); return; }
#define lua_bad_vf(a) { xfree(vf_buffer); \
@@ -120,6 +120,7 @@ static const char _svn_version[] =
#define vf_stack_size 100 /* \.{DVI} files shouldn't |push| beyond this depth */
+@ @c
typedef unsigned char vf_stack_index; /* an index into the stack */
typedef struct vf_stack_record {
@@ -128,11 +129,11 @@ typedef struct vf_stack_record {
boolean auto_expand_vf(internal_font_number f); /* forward */
-/* get a byte from\.{VF} file */
-
+@ get a byte from\.{VF} file
+@c
#define vf_byte(a) \
{ \
- real_eight_bits vf_tmp_b; \
+ eight_bits vf_tmp_b; \
if (vf_cur >= vf_size) { \
pdftex_fail("unexpected eof on virtual font"); \
} \
@@ -140,6 +141,7 @@ boolean auto_expand_vf(internal_font_number f); /* forward */
a = vf_tmp_b; \
}
+@ @c
#define vf_replace_z() \
{ \
vf_alpha = 16; \
@@ -147,19 +149,20 @@ boolean auto_expand_vf(internal_font_number f); /* forward */
vf_z = vf_z / 2; \
vf_alpha += vf_alpha; \
} \
- vf_beta = 256 / vf_alpha; \
- vf_alpha = vf_alpha * vf_z; \
+ vf_beta = (char)(256 / vf_alpha); \
+ vf_alpha = (vf_alpha * vf_z); \
}
-/* read |k| bytes as an integer from \.{VF} file */
-/* beware: the vf_read() macro differs from vf_read() in vftovp.web for 1...3 byte words */
+@ read |k| bytes as an integer from \.{VF} file
+beware: the |vf_read()| macro differs from |vf_read()| in vftovp.web for 1...3 byte words.
+@c
#define vf_read(k, l) \
{ \
- integer itmp = 0, dtmp = k, jtmp = 0; \
+ int itmp = 0, dtmp = (int)(k), jtmp = 0; \
while (dtmp > 0) { \
vf_byte(jtmp); \
- if ((dtmp == (integer) k) && jtmp > 127) \
+ if ((dtmp == (int) k) && jtmp > 127) \
jtmp = jtmp - 256; \
itmp = itmp * 256 + jtmp; \
decr(dtmp); \
@@ -169,7 +172,8 @@ boolean auto_expand_vf(internal_font_number f); /* forward */
#define vf_read_u(k, l) \
{ \
- unsigned int dtmp = k, itmp = 0, jtmp = 0; \
+ int dtmp = (int)(k); \
+ unsigned int itmp = 0, jtmp = 0; \
while (dtmp-- > 0) { \
vf_byte(jtmp); \
itmp = itmp * 256 + jtmp; \
@@ -177,52 +181,51 @@ boolean auto_expand_vf(internal_font_number f); /* forward */
l = itmp; \
}
-void pdf_check_vf_cur_val(void)
+@ @c
+void pdf_check_vf(internal_font_number f)
{
- 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"));
+ pdf_error("font", "command cannot be used with virtual font");
}
static void
-vf_local_font_warning(internal_font_number f, internal_font_number k, const char *s,
- integer a, integer b)
+vf_local_font_warning(internal_font_number f, internal_font_number k,
+ const char *s, int a, int b)
{
print_nlp();
- print_string(s);
- print_string(" in local font ");
- print_string(font_name(k));
- print_string(" (");
+ tprint(s);
+ tprint(" in local font ");
+ tprint(font_name(k));
+ tprint(" (");
print_int(b);
- print_string(" != ");
+ tprint(" != ");
print_int(a);
- print_string(") in virtual font ");
- print_string(font_name(f));
- print_string(".vf ignored.");
+ tprint(") in virtual font ");
+ tprint(font_name(f));
+ tprint(".vf ignored.");
}
-/* process a local font in \.{VF} file */
-
-static internal_font_number
-vf_def_font(internal_font_number f, unsigned char *vf_buffer, integer * vf_cr)
+@ process a local font in \.{VF} file
+@c
+internal_font_number
+vf_def_font(internal_font_number f, unsigned char *vf_buffer, int *vf_cr)
{
internal_font_number k;
str_number s;
+ char *st;
scaled ds, fs;
four_quarters cs;
memory_word tmp_w; /* accumulator */
- integer junk;
+ int 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;
+ checksum = (unsigned)
+ (cs.b0 * 256 * 256 * 256 + cs.b1 * 256 * 256 + cs.b2 * 256 + cs.b3);
k = vf_buffer[(*vf_cr)];
(*vf_cr)++;
if (k > 127)
@@ -258,67 +261,50 @@ vf_def_font(internal_font_number f, unsigned char *vf_buffer, integer * vf_cr)
tmp_b0--;
(*vf_cr)++; /* skip the font path */
}
- string_room(tmp_b1);
+ str_room((unsigned) tmp_b1);
while (tmp_b1 > 0) {
tmp_b1--;
junk = vf_buffer[(*vf_cr)];
(*vf_cr)++;
- append_pool_char(junk);
+ append_char(junk);
}
s = make_string();
- k = tfm_lookup(s, fs);
+ st = makecstring(s);
+ k = tfm_lookup(st, fs, font_expand_ratio(f));
if (k == null_font)
- k = read_font_info(get_nullcs(), s, fs, -1);
+ k = read_font_info(null_cs, st, fs, -1);
+ free(st);
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));
+ vf_local_font_warning(f, k, "checksum mismatch", (int) checksum,
+ (int) 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));
+ if (font_expand_ratio(f) != 0)
+ set_expand_params(k, font_auto_expand(f),
+ font_expand_ratio(font_stretch(f)),
+ -font_expand_ratio(font_shrink(f)),
+ font_step(f), font_expand_ratio(f));
return k;
}
-
-static int open_vf_file(const char *fn, unsigned char **vbuffer, integer * vsize)
+@ @c
+static int open_vf_file(const char *fn, unsigned char **vbuffer, int *vsize)
{
boolean res; /* was the callback successful? */
- integer callback_id;
- boolean file_read; /* was |vf_file| successfully read? */
+ int callback_id;
+ boolean file_read = false; /* was |vf_file| successfully read? */
FILE *vf_file;
- char *fnam = NULL;
-
-
+ const char *fname = luatex_find_file(fn, find_vf_file_callback);
+ if (!fname)
+ fname = 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)) {
- /* @<Fixup |nameoffile| after callback@>; */
- 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),
+ res = run_callback(callback_id, "S->bSd", fname,
&file_read, vbuffer, vsize);
if (res && file_read && (*vsize > 0)) {
return 1;
@@ -326,9 +312,12 @@ static int open_vf_file(const char *fn, unsigned char **vbuffer, integer * vsize
if (!file_read)
return 0; /* -1 */
} else {
- if (ovf_b_open_in(vf_file) || vf_b_open_in(vf_file)) {
+ if (luatex_open_input
+ (&(vf_file), fname, kpse_ovf_format, FOPEN_RBIN_MODE, false)
+ || luatex_open_input(&(vf_file), fname, kpse_vf_format,
+ FOPEN_RBIN_MODE, false)) {
res = read_vf_file(vf_file, vbuffer, vsize);
- b_close(vf_file);
+ close_file(vf_file);
if (res) {
return 1;
}
@@ -340,19 +329,20 @@ static int open_vf_file(const char *fn, unsigned char **vbuffer, integer * vsize
}
-/*
- @ The |do_vf| procedure attempts to read the \.{VF} file for a font, and sets
+
+@ The |do_vf| procedure attempts to read the \.{VF} file for a font, and sets
|font_type()| to |real_font_type| if the \.{VF} file could not be found
or loaded, otherwise sets |font_type()| to |virtual_font_type|. At this
time, |tmp_f| is the internal font number of the current \.{TFM} font. To
process font definitions in virtual font we call |vf_def_font|.
-*/
-#define append_packet(k) vpackets[vf_np++] = k
+@c
+#define append_packet(k) vpackets[vf_np++] = (eight_bits)(k)
-/* life is easier if all internal font commands are fnt4 and
- all character commands are set4 or put4 */
+@ life is easier if all internal font commands are fnt4 and
+ all character commands are set4 or put4
+@c
#define append_fnt_set(k) \
{ \
assert(k > 0); \
@@ -368,8 +358,9 @@ static int open_vf_file(const char *fn, unsigned char **vbuffer, integer * vsize
append_packet((k & 0x000000FF)); \
}
-/* some of these things happen twice, adding a define is simplest */
+@ some of these things happen twice, adding a define is simplest
+@c
#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)) && \
@@ -378,9 +369,9 @@ static int open_vf_file(const char *fn, unsigned char **vbuffer, integer * vsize
((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 "); } }
+ tprint("checksum mismatch in font "); \
+ tprint(font_name(f)); \
+ tprint(".vf ignored "); } }
#define test_dsize() \
{ \
@@ -388,21 +379,22 @@ static int open_vf_file(const char *fn, unsigned char **vbuffer, integer * vsize
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"); \
+ tprint("design size mismatch in font "); \
+ tprint(font_name(f)); \
+ tprint(".vf ignored"); \
} \
}
-static int count_packet_bytes(real_eight_bits * vf_buf, int cur_bute, int count)
+@ @c
+int count_packet_bytes(eight_bits * vf_buf, int cur_bute, int count)
{
- int k = 0;
+ unsigned 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];
+ while (k < (unsigned) count) {
+ cmd = vf_buf[cur_bute + (int) k];
k++;
if (cmd < set1) {
if (ff == 0) {
@@ -604,40 +596,40 @@ static int count_packet_bytes(real_eight_bits * vf_buf, int cur_bute, int count)
k += 4;
break;
case xxx1:
- d = vf_buf[cur_bute + k];
+ d = vf_buf[cur_bute + (int) k];
k++;
k += d;
- acc += 5 + d;
+ acc += 5 + (int) d;
break;
case xxx2:
- d = vf_buf[cur_bute + k];
+ d = vf_buf[cur_bute + (int) k];
k++;
- d = d * 256 + vf_buf[cur_bute + k];
+ d = d * 256 + vf_buf[cur_bute + (int) k];
k++;
k += d;
- acc += 5 + d;
+ acc += 5 + (int) d;
break;
case xxx3:
- d = vf_buf[cur_bute + k];
+ d = vf_buf[cur_bute + (int) k];
k++;
- d = d * 256 + vf_buf[cur_bute + k];
+ d = d * 256 + vf_buf[cur_bute + (int) k];
k++;
- d = d * 256 + vf_buf[cur_bute + k];
+ d = d * 256 + vf_buf[cur_bute + (int) k];
k++;
k += d;
- acc += 5 + d;
+ acc += 5 + (int) d;
break;
case xxx4:
- d = vf_buf[cur_bute + k];
+ d = vf_buf[cur_bute + (int) k];
k++;
- d = d * 256 + vf_buf[cur_bute + k];
+ d = d * 256 + vf_buf[cur_bute + (int) k];
k++;
- d = d * 256 + vf_buf[cur_bute + k];
+ d = d * 256 + vf_buf[cur_bute + (int) k];
k++;
- d = d * 256 + vf_buf[cur_bute + k];
+ d = d * 256 + vf_buf[cur_bute + (int) k];
k++;
k += d;
- acc += 5 + d;
+ acc += 5 + (int) d;
break;
case w0:
acc += 5;
@@ -665,29 +657,32 @@ static int count_packet_bytes(real_eight_bits * vf_buf, int cur_bute, int count)
return (acc + 1);
}
+@ @c
void do_vf(internal_font_number f)
{
- integer k, i;
+ int k, i;
unsigned cmd, n;
scaled x, y, w, z, h, v;
- integer cc, cmd_length, packet_length;
+ int cc, cmd_length;
+ unsigned packet_length;
charinfo *co;
scaled tfm_width;
- integer save_cur_byte;
+ int save_cur_byte;
vf_stack_index stack_level;
- integer vf_z; /* multiplier */
- integer vf_alpha; /* correction for negative values */
+ int vf_z; /* multiplier */
+ int vf_alpha; /* correction for negative values */
char vf_beta; /* divisor */
- integer vf_np;
- real_eight_bits *vpackets;
+ int vf_np;
+ eight_bits *vpackets;
memory_word tmp_w; /* accumulator */
vf_stack_record vf_stack[256];
- integer junk;
+ int junk;
+ unsigned utmp;
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 */
+ int vf_size;
+ int vf_cur;
+ unsigned *vf_local_fnts = NULL; /* external font ids */
+ unsigned *vf_real_fnts = NULL; /* internal font ids */
unsigned vf_nf = 0; /* local font counter */
if (font_type(f) != unknown_font_type)
@@ -696,13 +691,13 @@ void do_vf(internal_font_number f)
if (auto_expand_vf(f))
return; /* auto-expanded virtual font */
stack_level = 0;
- /* @<Open |vf_file|, return if not found@>; */
+ /* Open |vf_file|, return if not found */
vf_cur = 0;
vf_buffer = NULL;
vf_size = 0;
if (!open_vf_file(font_name(f), &vf_buffer, &vf_size))
return;
- /* @<Process the preamble@>;@/ */
+ /* Process the preamble */
set_font_type(f, virtual_font_type);
vf_byte(k);
if (k != pre)
@@ -715,16 +710,15 @@ void do_vf(internal_font_number f)
vf_byte(junk);
test_checksum();
test_dsize();
- /* update_terminal; */
vf_z = font_size(f);
vf_replace_z();
- /* @<Process the font definitions@>;@/ */
+ /* Process the font definitions */
/* 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), junk);
+ vf_read_u((cmd - fnt_def1 + 1), utmp);
vf_read(4, junk);
vf_read(4, junk);
vf_read(4, junk);
@@ -741,15 +735,15 @@ void do_vf(internal_font_number f)
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);
+ unsigned ii = (unsigned) ((unsigned) vf_nf * sizeof(int));
+ vf_local_fnts = xmalloc(ii);
+ memset(vf_local_fnts, 0, ii);
+ vf_real_fnts = xmalloc(ii);
+ memset(vf_real_fnts, 0, ii);
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);
+ vf_real_fnts[vf_nf] = (unsigned) vf_def_font(f, vf_buffer, &vf_cur);
incr(vf_nf);
vf_byte(cmd);
}
@@ -757,11 +751,12 @@ void do_vf(internal_font_number f)
while (cmd <= long_char) {
- /* @<Build a character packet@>;@/ */
+ /* Build a character packet */
vf_np = 0;
if (cmd == long_char) {
vf_read_u(4, packet_length);
- vf_read_u(4, cc);
+ vf_read_u(4, utmp);
+ cc = (int) utmp;
if (!char_exists(f, cc)) {
bad_vf("invalid character code");
}
@@ -773,21 +768,22 @@ void do_vf(internal_font_number f)
if (!char_exists(f, cc)) {
bad_vf("invalid character code");
}
- vf_read_u(3, k); /* cf. vftovp.web, line 1028 */
+ vf_read_u(3, utmp);
+ k = (int) utmp; /* cf. vftovp.web, line 1028 */
tfm_width = store_scaled_f(k, font_size(f));
}
- if (packet_length < 0)
- bad_vf("negative packet length");
+
+
if (tfm_width != char_width(f, cc)) {
if (tfm_width != char_width(f, cc)) {
print_nlp();
- print_string("character width mismatch in font ");
- print_string(font_name(f));
- print_string(".vf ignored");
+ tprint("character width mismatch in font ");
+ tprint(font_name(f));
+ tprint(".vf ignored");
}
}
- k = count_packet_bytes(vf_buffer, vf_cur, packet_length);
- vpackets = xmalloc(k + 1); /* need one extra extra for packet_end */
+ k = count_packet_bytes(vf_buffer, vf_cur, (int) packet_length);
+ vpackets = xmalloc((unsigned) (k + 1)); /* need one extra extra for |packet_end| */
co = get_charinfo(f, cc);
k = 0;
w = 0;
@@ -800,7 +796,7 @@ void do_vf(internal_font_number f)
if (cmd < set1) {
if (k == 0) {
- k = vf_real_fnts[0];
+ k = (int) vf_real_fnts[0];
append_fnt_set(k);
}
append_packet(packet_char_code);
@@ -811,20 +807,21 @@ void do_vf(internal_font_number f)
} 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);
+ vf_read_u((cmd - fnt1 + 1), utmp);
+ k = (int) utmp;
packet_length -= (cmd - fnt1 + 1);
} else {
- k = cmd - fnt_num_0;
+ k = (int) cmd - fnt_num_0;
}
/* change from local to external font id */
n = 0;
- while ((n < vf_nf) && (vf_local_fnts[n] != k))
+ while ((n < vf_nf) && (vf_local_fnts[n] != (unsigned) k))
n++;
if (n == vf_nf)
bad_vf("undefined local font");
- k = vf_real_fnts[n];
+ k = (int) vf_real_fnts[n];
append_fnt_set(k);
cmd_length = 0;
cmd = nop;
@@ -853,10 +850,11 @@ void do_vf(internal_font_number f)
case set3:
case set4:
if (k == 0) {
- k = vf_real_fnts[0];
+ k = (int) vf_real_fnts[0];
append_fnt_set(k);
}
- vf_read_u((cmd - set1 + 1), i);
+ vf_read_u((cmd - set1 + 1), utmp);
+ i = (int) utmp;
append_packet(packet_char_code);
append_four(i);
packet_length -= (cmd - set1 + 1);
@@ -866,10 +864,11 @@ void do_vf(internal_font_number f)
case put3:
case put4:
if (k == 0) {
- k = vf_real_fnts[0];
+ k = (int) vf_real_fnts[0];
append_fnt_set(k);
}
- vf_read_u((cmd - put1 + 1), i);
+ vf_read_u((cmd - put1 + 1), utmp);
+ i = (int) utmp;
append_packet(packet_push_code);
append_packet(packet_char_code);
append_four(i);
@@ -934,11 +933,12 @@ void do_vf(internal_font_number f)
case xxx2:
case xxx3:
case xxx4:
- vf_read_u((cmd - xxx1 + 1), cmd_length);
+ vf_read_u((cmd - xxx1 + 1), utmp);
+ cmd_length = (int) utmp;
packet_length -= (cmd - xxx1 + 1);
if (cmd_length <= 0)
bad_vf("special of negative length");
- packet_length -= cmd_length;
+ packet_length -= (unsigned) cmd_length;
append_packet(packet_special_code);
append_four(cmd_length);
@@ -968,8 +968,7 @@ void do_vf(internal_font_number f)
break;
case push:
if (stack_level == vf_stack_size) {
- overflow_string("virtual font stack size",
- vf_stack_size);
+ overflow("virtual font stack size", vf_stack_size);
} else {
vf_stack[stack_level].stack_w = w;
vf_stack[stack_level].stack_x = x;
@@ -1003,7 +1002,7 @@ void do_vf(internal_font_number f)
bad_vf("more PUSHs than POPs in character packet");
if (packet_length != 0)
bad_vf("invalid packet length or DVI command in packet");
- /* @<Store the packet being built@>; */
+ /* \.{Store the packet being built} */
set_charinfo_packets(co, vpackets);
vf_byte(cmd);
}
@@ -1013,6 +1012,7 @@ void do_vf(internal_font_number f)
xfree(vf_buffer);
}
+@ @c
#define make_command0(N,K) { \
lua_newtable(L); \
lua_pushstring(L, N); \
@@ -1052,29 +1052,31 @@ void do_vf(internal_font_number f)
int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
{
- integer cmd, k, i;
- integer cc, cmd_length, packet_length;
+ int cmd, k, i;
+ int cc;
+ unsigned cmd_length, packet_length;
scaled tfm_width;
vf_stack_index stack_level;
- integer vf_z; /* multiplier */
- integer vf_alpha; /* correction for negative values */
+ int vf_z; /* multiplier */
+ int vf_alpha; /* correction for negative values */
char vf_beta; /* divisor */
- char *s;
+ eight_bits *s;
scaled h, v;
scaled w, x, y, z;
- integer s_top; /* lua stack */
- integer vf_nf; /* local font counter */
+ int s_top; /* lua stack */
+ int 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;
+ int vf_size;
+ int vf_cur;
+ unsigned utmp;
stack_level = 0;
- /* @<Open |vf_file|, return if not found@>; */
+ /* Open |vf_file|, return if not found */
vf_cur = 0;
vf_buffer = NULL;
vf_size = 0;
@@ -1087,7 +1089,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
s_top = lua_gettop(L);
lua_newtable(L);
- /* @<Process the preamble@>;@/ */
+ /* Process the preamble */
vf_byte(k);
if (k != pre)
lua_bad_vf("PRE command expected");
@@ -1097,10 +1099,10 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
vf_byte(cmd_length);
s = xmalloc(cmd_length);
- for (k = 1; k <= cmd_length; k++)
+ for (k = 1; k <= (int) cmd_length; k++)
vf_byte(s[(k - 1)]);
- lua_pushlstring(L, s, cmd_length);
+ lua_pushlstring(L, (char *) s, (size_t) cmd_length);
free(s);
lua_setfield(L, -2, "header");
@@ -1109,8 +1111,8 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
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_Number) ((cs.b0 << 24) + (cs.b1 << 16) +
+ (cs.b2 << 8) + cs.b3));
lua_setfield(L, -2, "checksum");
vf_read(4, k);
@@ -1125,11 +1127,9 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
lua_pushinteger(L, atsize);
lua_setfield(L, -2, "size");
-
- /* update_terminal; */
vf_z = atsize;
vf_replace_z();
- /* @<Process the font definitions@>;@/ */
+ /* Process the font definitions */
vf_byte(cmd);
lua_newtable(L);
@@ -1137,7 +1137,8 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
while ((cmd >= fnt_def1) && (cmd <= fnt_def1 + 3)) {
lua_newtable(L);
- vf_read_u((cmd - fnt_def1 + 1), vf_nf);
+ vf_read_u((cmd - fnt_def1 + 1), utmp);
+ vf_nf = (int) utmp;
vf_nf++;
/* checksum */
vf_byte(cs.b0);
@@ -1161,13 +1162,13 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
vf_byte(k);
} /* skip the font path */
- s = xmalloc(tmp_b1 + 1);
+ s = xmalloc((unsigned) (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_pushstring(L, xstrdup((char *) s));
free(s);
lua_rawset(L, -3);
@@ -1184,18 +1185,20 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
lua_newtable(L); /* 'characters' */
while (cmd <= long_char) {
- /* @<Build a character packet@>;@/ */
+ /* Build a character packet */
if (cmd == long_char) {
vf_read_u(4, packet_length);
- vf_read_u(4, cc);
+ vf_read_u(4, utmp);
+ cc = (int) utmp;
vf_read(4, tfm_width);
} else {
- packet_length = cmd;
+ packet_length = (unsigned) cmd;
vf_byte(cc);
- vf_read_u(3, tfm_width);
+ vf_read_u(3, utmp);
+ tfm_width = (int) utmp;
}
- if (packet_length < 0)
- lua_bad_vf("negative packet length");
+
+
lua_newtable(L); /* for this character */
@@ -1224,9 +1227,10 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
} 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_read_u((cmd - fnt1 + 1), utmp);
+ vf_nf = (int) utmp;
vf_nf++;
- packet_length -= (cmd - fnt1 + 1);
+ packet_length -= (unsigned) (cmd - fnt1 + 1);
} else {
vf_nf = cmd - fnt_num_0 + 1;
}
@@ -1257,9 +1261,10 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
vf_nf = 1;
make_command1("font", vf_nf, k);
}
- vf_read_u((cmd - set1 + 1), i);
+ vf_read_u((cmd - set1 + 1), utmp);
+ i = (int) utmp;
make_command1("char", i, k);
- packet_length -= (cmd - set1 + 1);
+ packet_length -= (unsigned) (cmd - set1 + 1);
break;
case put1:
case put2:
@@ -1269,11 +1274,12 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
vf_nf = 1;
make_command1("font", vf_nf, k);
}
- vf_read_u((cmd - put1 + 1), i);
+ vf_read_u((cmd - put1 + 1), utmp);
+ i = (int) utmp;
make_command0("push", k);
make_command1("char", i, k);
make_command0("pop", k);
- packet_length -= (cmd - put1 + 1);
+ packet_length -= (unsigned) (cmd - put1 + 1);
break;
case right1:
case right2:
@@ -1281,7 +1287,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
case right4:
vf_read((cmd - right1 + 1), i);
make_command1("right", store_scaled_f(i, atsize), k);
- packet_length -= (cmd - right1 + 1);
+ packet_length -= (unsigned) (cmd - right1 + 1);
break;
case w1:
case w2:
@@ -1289,7 +1295,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
case w4:
vf_read((cmd - w1 + 1), w);
make_command1("right", store_scaled_f(w, atsize), k);
- packet_length -= (cmd - w1 + 1);
+ packet_length -= (unsigned) (cmd - w1 + 1);
break;
case x1:
case x2:
@@ -1297,7 +1303,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
case x4:
vf_read((cmd - x1 + 1), x);
make_command1("right", store_scaled_f(x, atsize), k);
- packet_length -= (cmd - x1 + 1);
+ packet_length -= (unsigned) (cmd - x1 + 1);
break;
case down1:
case down2:
@@ -1305,7 +1311,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
case down4:
vf_read((cmd - down1 + 1), i);
make_command1("down", store_scaled_f(i, atsize), k);
- packet_length -= (cmd - down1 + 1);
+ packet_length -= (unsigned) (cmd - down1 + 1);
break;
case y1:
case y2:
@@ -1313,7 +1319,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
case y4:
vf_read((cmd - y1 + 1), y);
make_command1("down", store_scaled_f(y, atsize), k);
- packet_length -= (cmd - y1 + 1);
+ packet_length -= (unsigned) (cmd - y1 + 1);
break;
case z1:
case z2:
@@ -1321,19 +1327,19 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
case z4:
vf_read((cmd - z1 + 1), z);
make_command1("down", store_scaled_f(z, atsize), k);
- packet_length -= (cmd - z1 + 1);
+ packet_length -= (unsigned) (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);
+ packet_length -= (unsigned) (cmd - xxx1 + 1);
if (cmd_length <= 0)
lua_bad_vf("special of negative length");
packet_length -= cmd_length;
- s = xmalloc(cmd_length + 1);
+ s = xmalloc((cmd_length + 1));
i = 0;
while (cmd_length > 0) {
cmd_length--;
@@ -1341,7 +1347,8 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
i++;
}
s[i] = 0;
- make_commands("special", strdup(s), i, k);
+ make_commands("special", xstrdup((char *) s), (size_t) i,
+ k);
free(s);
break;
case w0:
@@ -1360,8 +1367,7 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
break;
case push:
if (stack_level == vf_stack_size) {
- overflow_string("virtual font stack size",
- vf_stack_size);
+ overflow("virtual font stack size", vf_stack_size);
} else {
vf_stack[stack_level].stack_w = w;
vf_stack[stack_level].stack_x = x;
@@ -1409,29 +1415,30 @@ int make_vf_table(lua_State * L, const char *cnom, scaled atsize)
}
-/* This function is called from |do_vf|, and fixes up the virtual data
- inside an auto-expanded virtual font */
+@ This function is called from |do_vf|, and fixes up the virtual data
+inside an auto-expanded virtual font
+@c
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;
+ int e, k;
+ int *vf_old_fonts, *vf_new_fonts;
+ int num = 0;
- if ((!pdf_font_auto_expand(f)) || (pdf_font_blink(f) == null_font))
+ if ((!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);
+ e = font_expand_ratio(f);
vf_old_fonts = packet_local_fonts(bf, &num);
if (num > 0) {
- vf_new_fonts = xmalloc(num * sizeof(integer));
+ vf_new_fonts = xmalloc((unsigned) ((unsigned) num * sizeof(int)));
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);
@@ -1444,37 +1451,19 @@ boolean auto_expand_vf(internal_font_number f)
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();
-}
-
-
-internal_font_number auto_expand_font(internal_font_number f, integer e)
+@ @c
+internal_font_number auto_expand_font(internal_font_number f, int e)
{
internal_font_number k;
kerninfo *krn;
charinfo *co;
- char *fn;
- integer i;
+ int 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);
+ set_font_name(k, font_name(f));
+ set_font_expand_ratio(k, e);
for (i = font_bc(k); i <= font_ec(k); i++) {
- if (char_exists(k, i)) {
+ if (quick_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);
@@ -1493,21 +1482,22 @@ internal_font_number auto_expand_font(internal_font_number f, integer e)
return k;
}
+@ @c
void vf_expand_local_fonts(internal_font_number f)
{
internal_font_number lf;
- integer k, num;
- integer *vf_old_fonts;
+ int k, num;
+ int *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 < 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));
+ set_expand_params(lf, font_auto_expand(f),
+ font_expand_ratio(font_stretch(f)),
+ -font_expand_ratio(font_shrink(f)),
+ font_step(f), font_expand_ratio(f));
if (font_type(lf) == virtual_font_type)
vf_expand_local_fonts(lf);
}
@@ -1515,33 +1505,34 @@ void vf_expand_local_fonts(internal_font_number f)
}
}
+@ @c
internal_font_number
-letter_space_font(halfword u, internal_font_number f, integer e)
+letter_space_font(halfword u, internal_font_number f, int e)
{
internal_font_number k;
scaled w, r;
char *new_font_name;
- integer vf_z;
- integer vf_alpha;
- integer vf_beta;
+ int vf_z;
+ int vf_alpha;
+ int 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), font_size(f), font_natural_dir(f));
+ k = read_font_info(u, font_name(f), font_size(f), font_natural_dir(f));
set_no_ligatures(k); /* disable ligatures for letter-spaced fonts */
-/*
+#if 0
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));
}
-*/
+#endif
/* append eg '+100ls' to font name */
- new_font_name = xmalloc(strlen(font_name(k)) + 8); /* |abs(e) <= 1000| */
+ new_font_name = xmalloc((unsigned) (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 */
+ /* minus from \%i */
sprintf(new_font_name, "%s%ils", font_name(k), (int) e);
}
set_font_name(k, new_font_name);
@@ -1559,22 +1550,22 @@ letter_space_font(halfword u, internal_font_number f, integer e)
w = vf_alpha + w;
}
r = w * vf_beta;
- tmp_b1 = r / vf_z;
+ tmp_b1 = (quarterword) (r / vf_z);
r = r % vf_z;
if (r == 0) {
tmp_b2 = 0;
} else {
r = r * 256;
- tmp_b2 = r / vf_z;
+ tmp_b2 = (quarterword) (r / vf_z);
r = r % vf_z;
}
if (r == 0) {
tmp_b3 = 0;
} else {
r = r * 256;
- tmp_b3 = r / vf_z;
+ tmp_b3 = (quarterword) (r / vf_z);
}
- /*
+#if 0
vf_packet_base[k] = new_vf_packet(k);
for (c=font_bc(k);c<=font_ec(k);c++) {
@@ -1598,14 +1589,13 @@ letter_space_font(halfword u, internal_font_number f, integer e)
store_packet(k, c, s);
flush_str(s);
}
- */
+#endif
return k;
}
-/* the fontname has [+-]\d+ls at the end */
-
-#if 0 /* unused */
-static boolean is_letterspaced_font(internal_font_number f)
+@ the fontname has [+-]\d+ls at the end
+@c
+boolean is_letterspaced_font(internal_font_number f)
{
char *i, *j;
if (font_type(f) != virtual_font_type)
@@ -1626,10 +1616,8 @@ static boolean is_letterspaced_font(internal_font_number f)
return false;
return true;
}
-#endif
-
-/* TODO */
+@ @c
internal_font_number copy_font_info(internal_font_number f)
{
return copy_font(f);
diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.c b/Build/source/texk/web2c/luatexdir/font/vfpacket.w
index 161330469e3..eb28fcdcc4c 100644
--- a/Build/source/texk/web2c/luatexdir/font/vfpacket.c
+++ b/Build/source/texk/web2c/luatexdir/font/vfpacket.w
@@ -1,38 +1,40 @@
-/* vfpacket.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% vfpacket.w
- This file is part of LuaTeX.
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: vfpacket.c 2414 2009-06-03 12:57:01Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/vfpacket.c $";
+ "$Id: vfpacket.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/vfpacket.w $";
+
-/*
- The |do_vf_packet| procedure is called in order to interpret the
+@ The |do_vf_packet| procedure is called in order to interpret the
character packet for a virtual character. Such a packet may contain
the instruction to typeset a character from the same or an other
virtual font; in such cases |do_vf_packet| calls itself
recursively. The recursion level, i.e., the number of times this has
happened, is kept in the global variable |packet_cur_s| and should
not exceed |packet_max_recursion|.
-*/
+@c
#define packet_max_recursion 100
typedef unsigned char packet_stack_index; /* an index into the stack */
@@ -48,8 +50,8 @@ static packet_stack_record packet_stack[packet_max_recursion];
static packet_stack_index packet_stack_ptr = 0; /* pointer into |packet_stack| */
-/* Some macros for processing character packets. */
-
+@ Some macros for processing character packets.
+@c
#define do_packet_byte() vf_packets[cur_packet_byte++]
#define packet_number(fw) { \
@@ -58,7 +60,7 @@ static packet_stack_index packet_stack_ptr = 0; /* pointer into |packet_stack| *
fw = fw*256 + do_packet_byte(); \
fw = fw*256 + do_packet_byte(); }
-#define packet_scaled(a,fs) { integer fw; \
+#define packet_scaled(a,fs) { int fw; \
fw = do_packet_byte(); \
if (fw>127) fw = fw - 256; \
fw = fw*256 + do_packet_byte(); \
@@ -67,11 +69,12 @@ static packet_stack_index packet_stack_ptr = 0; /* pointer into |packet_stack| *
a = store_scaled_f(fw, fs); }
-/* count the number of bytes in a command packet */
+@ count the number of bytes in a command packet
+@c
int vf_packet_bytes(charinfo * co)
{
- real_eight_bits *vf_packets;
- integer cur_packet_byte;
+ eight_bits *vf_packets;
+ int cur_packet_byte;
unsigned k;
int cmd;
@@ -98,7 +101,7 @@ int vf_packet_bytes(charinfo * co)
break;
case packet_special_code:
packet_number(k); /* +4 */
- cur_packet_byte += k;
+ cur_packet_byte = (cur_packet_byte + (int) k);
break;
case packet_image_code:
cur_packet_byte += 4;
@@ -106,61 +109,64 @@ int vf_packet_bytes(charinfo * co)
case packet_nop_code:
break;
default:
- pdf_error(maketexstring("vf"),
- maketexstring("invalid DVI command (1)"));
+ pdf_error("vf", "invalid DVI command (1)");
}
};
return (cur_packet_byte + 1);
}
-/* typeset the \.{DVI} commands in the
- character packet for character |c| in current font |f| */
-
-#if 0 /* unused */
-static char *packet_command_names[] = {
+@ typeset the \.{DVI} commands in the
+ character packet for character |c| in current font |f|
+@c
+const char *packet_command_names[] = {
"char", "font", "pop", "push", "special", "image",
"right", "down", "rule", "node", "nop", "end", NULL
};
-#endif
-void do_vf_packet(internal_font_number vf_f, integer c)
+void do_vf_packet(PDF pdf, internal_font_number vf_f, int c)
{
internal_font_number lf;
charinfo *co;
- scaledpos save_cur;
- real_eight_bits *vf_packets;
- integer cur_packet_byte;
- integer cmd, fs_f;
+ scaledpos cur = { 0, 0 }, size;
+ eight_bits *vf_packets;
+ int cur_packet_byte;
+ int cmd, fs_f;
scaled i;
unsigned k;
str_number s;
- packet_cur_s++;
- if (packet_cur_s >= packet_max_recursion)
- overflow_string("max level recursion of virtual fonts",
- packet_max_recursion);
- save_cur = cur;
+ posstructure localpos; /* the position structure local within this function */
+ posstructure *refpos; /* the list origin pos. on the page, provided by the caller */
lf = 0; /* for -Wall */
+ packet_cur_s++;
+ if (packet_cur_s >= packet_max_recursion)
+ overflow("max level recursion of virtual fonts", packet_max_recursion);
co = get_charinfo(vf_f, c);
vf_packets = get_charinfo_packets(co);
if (vf_packets == NULL) {
packet_cur_s--;
return;
}
+
+ refpos = pdf->posstruct;
+ pdf->posstruct = &localpos; /* use local structure for recursion */
+ localpos.pos = refpos->pos;
+ localpos.dir = dir_TLT; /* invariably for vf */
+
cur_packet_byte = 0;
fs_f = font_size(vf_f);
while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) {
cur_packet_byte++;
- /*
+#ifdef DEBUG
if (cmd>packet_end_code) {
fprintf(stdout, "do_vf_packet(%i,%i) command code = illegal \n", vf_f,c);
} else {
fprintf(stdout, "do_vf_packet(%i,%i) command code = %s\n",vf_f, c, packet_command_names[cmd]);
}
- */
+#endif
switch (cmd) {
case packet_font_code:
packet_number(lf);
@@ -177,26 +183,22 @@ void do_vf_packet(internal_font_number vf_f, integer c)
break;
case packet_char_code:
packet_number(k);
- if (!char_exists(lf, k)) {
- char_warning(lf, k);
+ if (!char_exists(lf, (int) k)) {
+ char_warning(lf, (int) k);
} else {
- if (has_packet(lf, k))
- do_vf_packet(lf, k);
- else {
- pos = synch_p_with_c(cur);
- pdf_place_glyph(lf, k);
- }
+ if (has_packet(lf, (int) k))
+ do_vf_packet(pdf, lf, (int) k);
+ else
+ pdf_place_glyph(pdf, lf, (int) k);
}
- cur.h = cur.h + char_width(lf, k);
+ cur.h = cur.h + char_width(lf, (int) k);
break;
case packet_rule_code:
- packet_scaled(rule_ht, fs_f);
- packet_scaled(rule_wd, fs_f);
- if ((rule_wd > 0) && (rule_ht > 0)) {
- pos = synch_p_with_c(cur);
- pdf_place_rule(pos.h, pos.v, rule_wd, rule_ht);
- }
- cur.h = cur.h + rule_wd;
+ packet_scaled(size.v, fs_f); /* height (where is depth?) */
+ packet_scaled(size.h, fs_f);
+ if (size.h > 0 && size.v > 0)
+ pdf_place_rule(pdf, 0, size); /* the 0 is unused */
+ cur.h = cur.h + size.h;
break;
case packet_right_code:
packet_scaled(i, fs_f);
@@ -208,48 +210,46 @@ void do_vf_packet(internal_font_number vf_f, integer c)
break;
case packet_special_code:
packet_number(k);
- string_room(k);
+ str_room((unsigned) k);
while (k > 0) {
k--;
- append_pool_char(do_packet_byte());
+ append_char(do_packet_byte());
}
s = make_string();
- literal(s, scan_special, false);
+ pdf_literal(pdf, s, scan_special, false);
flush_str(s);
break;
case packet_image_code:
packet_number(k);
- pos = synch_p_with_c(cur);
- vf_out_image(k);
+ vf_out_image(pdf, k);
break;
case packet_node_code:
packet_number(k);
- temp_ptr = k;
- pdf_hlist_out();
+ hlist_out(pdf, (halfword) k);
break;
case packet_nop_code:
break;
default:
- pdf_error(maketexstring("vf"),
- maketexstring("invalid DVI command (2)"));
+ pdf_error("vf", "invalid DVI command (2)");
}
- };
- cur = save_cur;
+ synch_pos_with_cur(&localpos, refpos, cur); /* trivial case, always TLT */
+ }
packet_cur_s--;
+ pdf->posstruct = refpos;
}
-
-integer *packet_local_fonts(internal_font_number f, integer * num)
+@ @c
+int *packet_local_fonts(internal_font_number f, int *num)
{
int c, cmd, cur_packet_byte, lf, k, l, i;
- integer localfonts[256] = { 0 };
- integer *lfs;
+ int localfonts[256] = { 0 };
+ int *lfs;
charinfo *co;
- real_eight_bits *vf_packets;
+ eight_bits *vf_packets;
k = 0;
for (c = font_bc(f); c <= font_ec(f); c++) {
- if (char_exists(f, c)) {
+ if (quick_char_exists(f, c)) {
co = get_charinfo(f, c);
vf_packets = get_charinfo_packets(co);
if (vf_packets == NULL)
@@ -291,33 +291,33 @@ integer *packet_local_fonts(internal_font_number f, integer * num)
cur_packet_byte += 4;
break;
default:
- pdf_error(maketexstring("vf"),
- maketexstring("invalid DVI command (3)"));
+ pdf_error("vf", "invalid DVI command (3)");
}
}
}
}
*num = k;
if (k > 0) {
- lfs = xmalloc(k * sizeof(integer));
- memcpy(lfs, localfonts, k * sizeof(integer));
+ lfs = xmalloc((unsigned) ((unsigned) k * sizeof(int)));
+ memcpy(lfs, localfonts, (size_t) ((unsigned) k * sizeof(int)));
return lfs;
}
return NULL;
}
+@ @c
void
-replace_packet_fonts(internal_font_number f, integer * old_fontid,
- integer * new_fontid, int count)
+replace_packet_fonts(internal_font_number f, int *old_fontid,
+ int *new_fontid, int count)
{
int c, cmd, cur_packet_byte, lf, k, l;
charinfo *co;
- real_eight_bits *vf_packets;
+ eight_bits *vf_packets;
k = 0;
for (c = font_bc(f); c <= font_ec(f); c++) {
- if (char_exists(f, c)) {
+ if (quick_char_exists(f, c)) {
co = get_charinfo(f, c);
vf_packets = get_charinfo_packets(co);
if (vf_packets == NULL)
@@ -335,13 +335,14 @@ replace_packet_fonts(internal_font_number f, integer * old_fontid,
}
if (l < count) {
k = new_fontid[l];
- vf_packets[(cur_packet_byte - 4)] =
- (k & 0xFF000000) >> 24;
- vf_packets[(cur_packet_byte - 3)] =
- (k & 0x00FF0000) >> 16;
- vf_packets[(cur_packet_byte - 2)] =
- (k & 0x0000FF00) >> 8;
- vf_packets[(cur_packet_byte - 1)] = (k & 0x000000FF);
+ vf_packets[(cur_packet_byte - 4)] = (eight_bits)
+ ((k & 0xFF000000) >> 24);
+ vf_packets[(cur_packet_byte - 3)] = (eight_bits)
+ ((k & 0x00FF0000) >> 16);
+ vf_packets[(cur_packet_byte - 2)] = (eight_bits)
+ ((k & 0x0000FF00) >> 8);
+ vf_packets[(cur_packet_byte - 1)] =
+ (eight_bits) (k & 0x000000FF);
}
break;
case packet_push_code:
@@ -366,8 +367,7 @@ replace_packet_fonts(internal_font_number f, integer * old_fontid,
cur_packet_byte += 4;
break;
default:
- pdf_error(maketexstring("vf"),
- maketexstring("invalid DVI command (4)"));
+ pdf_error("vf", "invalid DVI command (4)");
}
}
}
diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.h b/Build/source/texk/web2c/luatexdir/font/writecff.h
index bec0add205b..266cc9d1f6d 100644
--- a/Build/source/texk/web2c/luatexdir/font/writecff.h
+++ b/Build/source/texk/web2c/luatexdir/font/writecff.h
@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writecff.h 2271 2009-04-12 23:42:21Z oneiros $ */
+/* $Id: writecff.h 3400 2010-01-27 16:10:42Z taco $ */
#ifndef _CFF_LIMITS_H_
# define _CFF_LIMITS_H_
@@ -340,5 +340,5 @@ extern long cs_copy_charstring(card8 * dest, long destlen,
extern cff_font *read_cff(unsigned char *buf, long buflength, int subf);
-extern void write_cff(cff_font * cff, fd_entry * fd);
-extern void write_cid_cff(cff_font * cffont, fd_entry * fd);
+extern void write_cff(PDF pdf, cff_font * cff, fd_entry * fd);
+extern void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd);
diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.c b/Build/source/texk/web2c/luatexdir/font/writecff.w
index 82b52d96d7c..91d1f3c9af2 100644
--- a/Build/source/texk/web2c/luatexdir/font/writecff.c
+++ b/Build/source/texk/web2c/luatexdir/font/writecff.w
@@ -1,33 +1,36 @@
-/* writecff.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% writecff.w
- This file is part of LuaTeX.
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% 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 <http://www.gnu.org/licenses/>. */
+
+@ @c
#include "ptexlib.h"
+#include "lua/luatex-api.h"
-#include "writecff.h"
+#include "font/writecff.h"
static const char _svn_version[] =
- "$Id: writecff.c 2448 2009-06-08 07:43:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/writecff.c $";
+ "$Id: writecff.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writecff.w $";
+@ @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)
+#define get_card8(a) (card8)(a->stream[a->offset++])
+#define get_card16(a) (card16)(get_unsigned(a,2))
#undef b0
#undef b1
@@ -46,6 +49,7 @@ static unsigned long get_unsigned(cff_font * cff, int n)
return v;
}
+@ @c
#define CFF_ERROR pdftex_fail
#undef WARN
#define WARN pdftex_warn
@@ -147,7 +151,8 @@ const char *const cff_stdstr[CFF_STDSTR_MAX] = {
};
-/* Only read header part but not body */
+@ Only read header part but not body
+@c
cff_index *cff_get_index_header(cff_font * cff)
{
cff_index *idx;
@@ -161,7 +166,8 @@ cff_index *cff_get_index_header(cff_font * cff)
if (idx->offsize < 1 || idx->offsize > 4)
CFF_ERROR("invalid offsize data");
- idx->offset = xcalloc(count + 1, sizeof(l_offset));
+ idx->offset =
+ xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset)));
for (i = 0; i < count + 1; i++) {
(idx->offset)[i] = get_offset(cff, idx->offsize);
}
@@ -181,11 +187,12 @@ cff_index *cff_get_index_header(cff_font * cff)
+@ @c
cff_index *cff_get_index(cff_font * cff)
{
cff_index *idx;
card16 i, count;
- long length;
+ size_t length;
idx = xcalloc(1, sizeof(cff_index));
@@ -195,7 +202,8 @@ cff_index *cff_get_index(cff_font * cff)
if (idx->offsize < 1 || idx->offsize > 4)
CFF_ERROR("invalid offsize data");
- idx->offset = xcalloc((count + 1), sizeof(l_offset));
+ idx->offset =
+ xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset)));
for (i = 0; i < count + 1; i++) {
idx->offset[i] = get_offset(cff, idx->offsize);
}
@@ -203,9 +211,9 @@ cff_index *cff_get_index(cff_font * cff)
if (idx->offset[0] != 1)
CFF_ERROR("Invalid CFF Index offset data");
- length = idx->offset[count] - idx->offset[0];
+ length = (size_t) (idx->offset[count] - idx->offset[0]);
- idx->data = xcalloc(length, sizeof(card8));
+ idx->data = xmalloc((unsigned) length * sizeof(card8));
memcpy(idx->data, &cff->stream[cff->offset], length);
cff->offset += length;
@@ -218,6 +226,7 @@ cff_index *cff_get_index(cff_font * cff)
}
+@ @c
long cff_pack_index(cff_index * idx, card8 * dest, long destlen)
{
long len = 0;
@@ -237,8 +246,8 @@ long cff_pack_index(cff_index * idx, card8 * dest, long destlen)
if (destlen < len)
CFF_ERROR("Not enough space available...");
- *(dest++) = (idx->count >> 8) & 0xff;
- *(dest++) = idx->count & 0xff;
+ *(dest++) = (card8) ((idx->count >> 8) & 0xff);
+ *(dest++) = (card8) (idx->count & 0xff);
if (datalen < 0xffUL) {
idx->offsize = 1;
@@ -277,6 +286,7 @@ long cff_pack_index(cff_index * idx, card8 * dest, long destlen)
return len;
}
+@ @c
long cff_index_size(cff_index * idx)
{
if (idx->count > 0) {
@@ -292,12 +302,13 @@ long cff_index_size(cff_index * idx)
} else {
idx->offsize = 4;
}
- return (3 + (idx->offsize) * (idx->count + 1) + datalen);
+ return (3 + (idx->offsize) * (idx->count + 1) + (long) datalen);
} else {
return 2;
}
}
+@ @c
cff_index *cff_new_index(card16 count)
{
cff_index *idx;
@@ -307,7 +318,7 @@ cff_index *cff_new_index(card16 count)
idx->offsize = 0;
if (count > 0) {
- idx->offset = xcalloc(count + 1, sizeof(l_offset));
+ idx->offset = xcalloc((unsigned) (count + 1), sizeof(l_offset));
(idx->offset)[0] = 1;
} else {
idx->offset = NULL;
@@ -318,6 +329,7 @@ cff_index *cff_new_index(card16 count)
}
+@ @c
void cff_release_index(cff_index * idx)
{
if (idx) {
@@ -327,6 +339,7 @@ void cff_release_index(cff_index * idx)
}
}
+@ @c
void cff_release_dict(cff_dict * dict)
{
if (dict) {
@@ -342,6 +355,7 @@ void cff_release_dict(cff_dict * dict)
}
+@ @c
void cff_release_encoding(cff_encoding * encoding)
{
if (encoding) {
@@ -361,6 +375,7 @@ void cff_release_encoding(cff_encoding * encoding)
}
}
+@ @c
void cff_release_charsets(cff_charsets * charset)
{
if (charset) {
@@ -381,6 +396,7 @@ void cff_release_charsets(cff_charsets * charset)
}
}
+@ @c
void cff_release_fdselect(cff_fdselect * fdselect)
{
if (fdselect) {
@@ -394,13 +410,13 @@ void cff_release_fdselect(cff_fdselect * fdselect)
}
+@ @c
void cff_close(cff_font * cff)
{
card16 i;
if (cff) {
- if (cff->fontname)
- xfree(cff->fontname);
+ xfree(cff->fontname);
if (cff->name)
cff_release_index(cff->name);
if (cff->topdict)
@@ -446,6 +462,7 @@ void cff_close(cff_font * cff)
return;
}
+@ @c
char *cff_get_name(cff_font * cff)
{
char *fontname;
@@ -454,7 +471,7 @@ char *cff_get_name(cff_font * cff)
idx = cff->name;
len = idx->offset[cff->index + 1] - idx->offset[cff->index];
- fontname = xmalloc((len + 1) * sizeof(char));
+ fontname = xmalloc((unsigned) (len + 1) * sizeof(char));
memcpy(fontname, idx->data + idx->offset[cff->index] - 1, len);
fontname[len] = '\0';
@@ -462,6 +479,7 @@ char *cff_get_name(cff_font * cff)
}
+@ @c
long cff_set_name(cff_font * cff, char *name)
{
cff_index *idx;
@@ -478,10 +496,10 @@ long cff_set_name(cff_font * cff, char *name)
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' */
+ idx->data = xmalloc((unsigned) strlen(name) * sizeof(card8));
+ memmove(idx->data, name, strlen(name)); /* no trailing |'\0'| */
- return 5 + strlen(name);
+ return (long) (5 + strlen(name));
}
long cff_put_header(cff_font * cff, card8 * dest, long destlen)
@@ -501,6 +519,7 @@ long cff_put_header(cff_font * cff, card8 * dest, long destlen)
return 4;
}
+@ @c
#define CFF_PARSE_OK 0
#define CFF_CFF_ERROR_PARSE_CFF_ERROR -1
#define CFF_CFF_ERROR_STACK_OVERFLOW -2
@@ -516,32 +535,33 @@ cff_dict *cff_new_dict(void)
dict = xcalloc(1, sizeof(cff_dict));
dict->max = DICT_ENTRY_MAX;
dict->count = 0;
- dict->entries = xcalloc(dict->max, sizeof(cff_dict_entry));
+ dict->entries = xcalloc((unsigned) dict->max, sizeof(cff_dict_entry));
return dict;
}
-/*
- * Operand stack:
- * only numbers are stored (as double)
- *
- * Operand types:
- *
- * number : double (integer or real)
- * boolean: stored as a number
- * SID : stored as a number
- * array : array of numbers
- * delta : array of numbers
- */
+@
+
+Operand stack:
+ only numbers are stored (as double)
+
+Operand types:
+number : double (integer or real)
+boolean: stored as a number
+SID : stored as a number
+array : array of numbers
+delta : array of numbers
+
+@c
#define CFF_DICT_STACK_LIMIT 64
static int stack_top = 0;
static double arg_stack[CFF_DICT_STACK_LIMIT];
-/*
- * CFF DICT encoding:
- * TODO: default values
- */
-
+@
+CFF DICT encoding:
+TODO: default values
+
+@c
#define CFF_LAST_DICT_OP1 22
#define CFF_LAST_DICT_OP2 39
#define CFF_LAST_DICT_OP (CFF_LAST_DICT_OP1 + CFF_LAST_DICT_OP2)
@@ -623,7 +643,8 @@ static struct {
"FDSelect", CFF_TYPE_OFFSET}, {
"FontName", CFF_TYPE_SID},};
-/* Parse DICT data */
+@ Parse DICT data
+@c
static double get_integer(card8 ** data, card8 * endptr, int *status)
{
long result = 0;
@@ -660,7 +681,8 @@ static double get_integer(card8 ** data, card8 * endptr, int *status)
return (double) result;
}
-/* Simply uses strtod */
+@ Simply uses strtod
+@c
static double get_real(card8 ** data, card8 * endptr, int *status)
{
double result = 0.0;
@@ -684,7 +706,7 @@ static double get_real(card8 ** data, card8 * endptr, int *status)
nibble = (**data >> 4) & 0x0f;
}
if (nibble >= 0x00 && nibble <= 0x09) {
- work_buffer[len++] = nibble + '0';
+ work_buffer[len++] = (char) (nibble + '0');
} else if (nibble == 0x0a) { /* . */
work_buffer[len++] = '.';
} else if (nibble == 0x0b || nibble == 0x0c) { /* E, E- */
@@ -721,11 +743,12 @@ static double get_real(card8 ** data, card8 * endptr, int *status)
return result;
}
-/* operators */
+@ operators
+@c
static void add_dict(cff_dict * dict,
card8 ** data, card8 * endptr, int *status)
{
- int id, argtype;
+ int id, argtype, t;
id = **data;
if (id == 0x0c) {
@@ -750,7 +773,9 @@ static void add_dict(cff_dict * dict,
dict->max += DICT_ENTRY_MAX;
/* not zeroed! */
dict->entries =
- xrealloc(dict->entries, dict->max * sizeof(cff_dict_entry));
+ xrealloc(dict->entries,
+ (unsigned) ((unsigned) dict->max *
+ sizeof(cff_dict_entry)));
}
(dict->entries)[dict->count].id = id;
@@ -771,15 +796,21 @@ static void add_dict(cff_dict * dict,
} else {
/* just ignore operator if there were no operands provided;
don't treat this as underflow (e.g. StemSnapV in TemporaLGCUni-Italic.otf) */
- if (stack_top > 0) {
+ if ((t = stack_top) > 0) {
(dict->entries)[dict->count].count = stack_top;
(dict->entries)[dict->count].values =
- xcalloc(stack_top, sizeof(double));
+ xmalloc((unsigned) ((unsigned) stack_top * sizeof(double)));
while (stack_top > 0) {
stack_top--;
(dict->entries)[dict->count].values[stack_top] =
arg_stack[stack_top];
}
+ if (t > 3 && strcmp(dict_operator[id].opname, "FontMatrix") == 0) {
+ /* reset FontMatrix to [0.001 * * 0.001 * *],
+ fix mantis bug \# 0000200 (acroread "feature") */
+ (dict->entries)[dict->count].values[0] = 0.001;
+ (dict->entries)[dict->count].values[3] = 0.001;
+ }
dict->count += 1;
}
}
@@ -789,11 +820,12 @@ static void add_dict(cff_dict * dict,
return;
}
-/*
- * All operands are treated as number or array of numbers.
- * Private: two numbers, size and offset
- * ROS : three numbers, SID, SID, and a number
- */
+
+@ All operands are treated as number or array of numbers.
+ Private: two numbers, size and offset
+ ROS : three numbers, SID, SID, and a number
+
+@c
cff_dict *cff_dict_unpack(card8 * data, card8 * endptr)
{
cff_dict *dict;
@@ -834,7 +866,7 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr)
return dict;
}
-
+@ @c
int cff_dict_known(cff_dict * dict, const char *key)
{
int i;
@@ -848,6 +880,7 @@ int cff_dict_known(cff_dict * dict, const char *key)
return 0;
}
+@ @c
double cff_dict_get(cff_dict * dict, const char *key, int idx)
{
double value = 0.0;
@@ -871,6 +904,7 @@ double cff_dict_get(cff_dict * dict, const char *key, int idx)
return value;
}
+@ @c
card8 cff_fdselect_lookup(cff_font * cff, card16 gid)
{
card8 fd = 0xff;
@@ -913,6 +947,7 @@ card8 cff_fdselect_lookup(cff_font * cff, card16 gid)
return fd;
}
+@ @c
long cff_read_subrs(cff_font * cff)
{
long len = 0;
@@ -945,7 +980,7 @@ long cff_read_subrs(cff_font * cff)
} 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->offset = (l_offset) offset;
(cff->subrs)[i] = cff_get_index(cff);
len += cff_index_size((cff->subrs)[i]);
}
@@ -957,7 +992,7 @@ long cff_read_subrs(cff_font * cff)
} else {
offset = (long) cff_dict_get(cff->topdict, "Private", 1);
offset += (long) cff_dict_get(cff->private[0], "Subrs", 0);
- cff->offset = offset;
+ cff->offset = (l_offset) offset;
(cff->subrs)[0] = cff_get_index(cff);
len += cff_index_size((cff->subrs)[0]);
}
@@ -967,6 +1002,7 @@ long cff_read_subrs(cff_font * cff)
}
+@ @c
long cff_read_fdarray(cff_font * cff)
{
long len = 0;
@@ -982,13 +1018,13 @@ long cff_read_fdarray(cff_font * cff)
/* must exist */
offset = (long) cff_dict_get(cff->topdict, "FDArray", 0);
- cff->offset = offset;
+ cff->offset = (l_offset) offset;
idx = cff_get_index(cff);
cff->num_fds = (card8) idx->count;
- cff->fdarray = xcalloc(idx->count, sizeof(cff_dict *));
+ cff->fdarray = xmalloc((unsigned) (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];
+ size = (long) ((idx->offset)[i + 1] - (idx->offset)[i]);
if (size > 0) {
(cff->fdarray)[i] = cff_dict_unpack(data, data + size);
} else {
@@ -1002,6 +1038,7 @@ long cff_read_fdarray(cff_font * cff)
}
+@ @c
long cff_read_private(cff_font * cff)
{
long len = 0;
@@ -1014,17 +1051,17 @@ long cff_read_private(cff_font * cff)
if (cff->fdarray == NULL)
cff_read_fdarray(cff);
- cff->private = xcalloc(cff->num_fds, sizeof(cff_dict *));
+ cff->private = xmalloc((unsigned) (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->offset = (l_offset) offset;
+ data = xmalloc((unsigned) size * sizeof(card8));
+ memcpy(data, &cff->stream[cff->offset], (size_t) size);
+ cff->offset = (l_offset) size;
(cff->private)[i] = cff_dict_unpack(data, data + size);
xfree(data);
len += size;
@@ -1034,14 +1071,14 @@ long cff_read_private(cff_font * cff)
}
} else {
cff->num_fds = 1;
- cff->private = xcalloc(1, sizeof(cff_dict *));
+ cff->private = xmalloc(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->offset = (l_offset) offset;
+ data = xmalloc((unsigned) size * sizeof(card8));
+ memcpy(data, &cff->stream[cff->offset], (size_t) size);
+ cff->offset = (l_offset) size;
cff->private[0] = cff_dict_unpack(data, data + size);
xfree(data);
len += size;
@@ -1055,6 +1092,7 @@ long cff_read_private(cff_font * cff)
}
+@ @c
cff_font *read_cff(unsigned char *buf, long buflength, int n)
{
cff_font *cff;
@@ -1065,7 +1103,7 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n)
cff = xcalloc(1, sizeof(cff_font));
cff->stream = buf;
- cff->stream_size = buflength;
+ cff->stream_size = (l_offset) buflength;
cff->index = n;
cff->header_major = get_card8(cff);
@@ -1133,7 +1171,7 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n)
/* Number of glyphs */
offset = (long) cff_dict_get(cff->topdict, "CharStrings", 0);
- cff->offset = offset;
+ cff->offset = (l_offset) offset;
cff->num_glyphs = get_card16(cff);
/* Check for font type */
@@ -1160,11 +1198,10 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n)
return cff;
}
-/* write a cff for opentype */
-
-
+@* write a cff for opentype.
-/* Pack DICT data */
+@ Pack DICT data
+@c
static long pack_integer(card8 * dest, long destlen, long value)
{
long len = 0;
@@ -1172,42 +1209,43 @@ static long pack_integer(card8 * dest, long destlen, long value)
if (value >= -107 && value <= 107) {
if (destlen < 1)
CFF_ERROR("Buffer overflow.");
- dest[0] = (value + 139) & 0xff;
+ dest[0] = (card8) ((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;
+ value = (long) 0xf700u + value - 108;
+ dest[0] = (card8) ((value >> 8) & 0xff);
+ dest[1] = (card8) (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;
+ value = (long) 0xfb00u - value - 108;
+ dest[0] = (card8) ((value >> 8) & 0xff);
+ dest[1] = (card8) (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;
+ dest[1] = (card8) ((value >> 8) & 0xff);
+ dest[2] = (card8) (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;
+ dest[1] = (card8) ((value >> 24) & 0xff);
+ dest[2] = (card8) ((value >> 16) & 0xff);
+ dest[3] = (card8) ((value >> 8) & 0xff);
+ dest[4] = (card8) (value & 0xff);
len = 5;
}
return len;
}
+@ @c
static long pack_real(card8 * dest, long destlen, double value)
{
long e;
@@ -1251,7 +1289,7 @@ static long pack_real(card8 * dest, long destlen, double value)
} else if (work_buffer[i] == '.') {
ch = 0x0a;
} else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') {
- ch = work_buffer[i] - '0';
+ ch = (unsigned char) (work_buffer[i] - '0');
} else {
CFF_ERROR("Invalid character.");
}
@@ -1260,29 +1298,29 @@ static long pack_real(card8 * dest, long destlen, double value)
CFF_ERROR("Buffer overflow.");
if (pos % 2) {
- dest[pos / 2] += ch;
+ dest[pos / 2] = (card8) (dest[pos / 2] + ch);
} else {
- dest[pos / 2] = (ch << 4);
+ dest[pos / 2] = (card8) (ch << 4);
}
pos++;
}
if (e > 0) {
if (pos % 2) {
- dest[pos / 2] += 0x0b;
+ dest[pos / 2] = (card8) (dest[pos / 2] + 0x0b);
} else {
if (destlen < pos / 2 + 1)
CFF_ERROR("Buffer overflow.");
- dest[pos / 2] = 0xb0;
+ dest[pos / 2] = (card8) (0xb0);
}
pos++;
} else if (e < 0) {
if (pos % 2) {
- dest[pos / 2] += 0x0c;
+ dest[pos / 2] = (card8) (dest[pos / 2] + 0x0c);
} else {
if (destlen < pos / 2 + 1)
CFF_ERROR("Buffer overflow.");
- dest[pos / 2] = 0xc0;
+ dest[pos / 2] = (card8) (0xc0);
}
e *= -1;
pos++;
@@ -1297,7 +1335,7 @@ static long pack_real(card8 * dest, long destlen, double value)
} else if (work_buffer[i] == '.') {
ch = 0x0a;
} else if (work_buffer[i] >= '0' && work_buffer[i] <= '9') {
- ch = work_buffer[i] - '0';
+ ch = (unsigned char) (work_buffer[i] - '0');
} else {
CFF_ERROR("Invalid character.");
}
@@ -1306,27 +1344,28 @@ static long pack_real(card8 * dest, long destlen, double value)
CFF_ERROR("Buffer overflow.");
if (pos % 2) {
- dest[pos / 2] += ch;
+ dest[pos / 2] = (card8) (dest[pos / 2] + ch);
} else {
- dest[pos / 2] = (ch << 4);
+ dest[pos / 2] = (card8) (ch << 4);
}
pos++;
}
}
if (pos % 2) {
- dest[pos / 2] += 0x0f;
+ dest[pos / 2] = (card8) (dest[pos / 2] + 0x0f);
pos++;
} else {
if (destlen < pos / 2 + 1)
CFF_ERROR("Buffer overflow.");
- dest[pos / 2] = 0xff;
+ dest[pos / 2] = (card8) (0xff);
pos += 2;
}
return pos / 2;
}
+@ @c
static long cff_dict_put_number(double value,
card8 * dest, long destlen, int type)
{
@@ -1342,10 +1381,10 @@ static long cff_dict_put_number(double 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;
+ dest[1] = (card8) ((lvalue >> 24) & 0xff);
+ dest[2] = (card8) ((lvalue >> 16) & 0xff);
+ dest[3] = (card8) ((lvalue >> 8) & 0xff);
+ dest[4] = (card8) (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);
@@ -1356,6 +1395,7 @@ static long cff_dict_put_number(double value,
return len;
}
+@ @c
static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen)
{
long len = 0;
@@ -1376,12 +1416,12 @@ static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen)
if (id >= 0 && id < CFF_LAST_DICT_OP1) {
if (len + 1 > destlen)
CFF_ERROR("Buffer overflow.");
- dest[len++] = id;
+ dest[len++] = (card8) 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;
+ dest[len++] = (card8) (id - CFF_LAST_DICT_OP1);
} else {
CFF_ERROR("Invalid CFF DICT operator ID.");
}
@@ -1390,6 +1430,7 @@ static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen)
return len;
}
+@ @c
long cff_dict_pack(cff_dict * dict, card8 * dest, long destlen)
{
long len = 0;
@@ -1411,6 +1452,7 @@ long cff_dict_pack(cff_dict * dict, card8 * dest, long destlen)
}
+@ @c
void cff_dict_add(cff_dict * dict, const char *key, int count)
{
int id, i;
@@ -1435,15 +1477,17 @@ void cff_dict_add(cff_dict * dict, const char *key, int count)
if (dict->count + 1 >= dict->max) {
dict->max += 8;
dict->entries =
- xrealloc(dict->entries, (dict->max) * sizeof(cff_dict_entry));
+ xrealloc(dict->entries,
+ (unsigned) ((unsigned) dict->max *
+ sizeof(cff_dict_entry)));
}
(dict->entries)[dict->count].id = id;
(dict->entries)[dict->count].key = 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);
+ (dict->entries)[dict->count].values =
+ xcalloc((unsigned) count, sizeof(double));
} else {
(dict->entries)[dict->count].values = NULL;
}
@@ -1453,19 +1497,19 @@ void cff_dict_add(cff_dict * dict, const char *key, int count)
}
+@ @c
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;
+ xfree((dict->entries)[i].values);
}
}
}
+@ @c
void cff_dict_set(cff_dict * dict, const char *key, int idx, double value)
{
int i;
@@ -1487,23 +1531,24 @@ void cff_dict_set(cff_dict * dict, const char *key, int idx, double value)
}
-/* Strings */
+@ Strings
+@c
char *cff_get_string(cff_font * cff, s_SID id)
{
char *result = NULL;
- long len;
+ size_t len;
if (id < CFF_STDSTR_MAX) {
len = strlen(cff_stdstr[id]);
- result = xcalloc(len + 1, sizeof(char));
+ result = xmalloc((unsigned) (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;
+ id = (s_SID) (id - CFF_STDSTR_MAX);
if (id < strings->count) {
len = (strings->offset)[id + 1] - (strings->offset)[id];
- result = xcalloc(len + 1, sizeof(char));
+ result = xmalloc((unsigned) (len + 1) * sizeof(char));
memmove(result, strings->data + (strings->offset)[id] - 1, len);
result[len] = '\0';
}
@@ -1512,6 +1557,7 @@ char *cff_get_string(cff_font * cff, s_SID id)
return result;
}
+@ @c
long cff_get_sid(cff_font * cff, const char *str)
{
card16 i;
@@ -1538,6 +1584,7 @@ long cff_get_sid(cff_font * cff, const char *str)
}
+@ @c
void cff_update_string(cff_font * cff)
{
if (cff == NULL)
@@ -1550,6 +1597,7 @@ void cff_update_string(cff_font * cff)
}
+@ @c
s_SID cff_add_string(cff_font * cff, const char *str)
{
card16 idx;
@@ -1568,7 +1616,7 @@ s_SID cff_add_string(cff_font * cff, const char *str)
offset = strings->offset[idx];
if (size == strlen(str) &&
!memcmp(strings->data + offset - 1, str, strlen(str)))
- return (idx + CFF_STDSTR_MAX);
+ return (s_SID) (idx + CFF_STDSTR_MAX);
}
for (idx = 0; idx < CFF_STDSTR_MAX; idx++) {
@@ -1577,20 +1625,24 @@ s_SID cff_add_string(cff_font * cff, const char *str)
}
offset = (strings->count > 0) ? strings->offset[strings->count] : 1;
strings->offset =
- xrealloc(strings->offset, (strings->count + 2) * sizeof(l_offset));
+ xrealloc(strings->offset,
+ (unsigned) (((unsigned) strings->count +
+ 2) * sizeof(l_offset)));
if (strings->count == 0)
strings->offset[0] = 1;
idx = strings->count;
- strings->count += 1;
+ strings->count = (card16) (strings->count + 1);
strings->offset[strings->count] = offset + strlen(str);
strings->data =
- xrealloc(strings->data, (offset + strlen(str) - 1) * sizeof(card8));
+ xrealloc(strings->data,
+ (unsigned) ((offset + strlen(str) - 1) * sizeof(card8)));
memcpy(strings->data + offset - 1, str, strlen(str));
- return (idx + CFF_STDSTR_MAX);
+ return (s_SID) (idx + CFF_STDSTR_MAX);
}
+@ @c
void cff_dict_update(cff_dict * dict, cff_font * cff)
{
int i;
@@ -1603,14 +1655,14 @@ void cff_dict_update(cff_dict * dict, cff_font * cff)
id = (dict->entries)[i].id;
if (dict_operator[id].argtype == CFF_TYPE_SID) {
- str = cff_get_string(cff, (dict->entries)[i].values[0]);
+ str = cff_get_string(cff, (s_SID) (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]);
+ str = cff_get_string(cff, (s_SID) (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]);
+ str = cff_get_string(cff, (s_SID) (dict->entries)[i].values[1]);
(dict->entries)[i].values[1] = cff_add_string(cff, str);
xfree(str);
}
@@ -1619,8 +1671,8 @@ void cff_dict_update(cff_dict * dict, cff_font * cff)
}
}
-/* charsets */
-
+@ charsets
+@c
long cff_read_charsets(cff_font * cff)
{
cff_charsets *charset;
@@ -1652,19 +1704,20 @@ long cff_read_charsets(cff_font * cff)
return 0;
}
- cff->offset = offset;
+ cff->offset = (l_offset) offset;
cff->charsets = charset = xcalloc(1, sizeof(cff_charsets));
charset->format = get_card8(cff);
charset->num_entries = 0;
- count = cff->num_glyphs - 1;
+ count = (card16) (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));
+ charset->num_entries = (card16) (cff->num_glyphs - 1); /* no .notdef */
+ charset->data.glyphs =
+ xmalloc((unsigned) (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);
@@ -1677,11 +1730,12 @@ long cff_read_charsets(cff_font * cff)
while (count > 0 && charset->num_entries < cff->num_glyphs) {
ranges =
xrealloc(ranges,
- (charset->num_entries + 1) * sizeof(cff_range1));
+ (unsigned) (((unsigned) 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;
+ count = (card16) (count - ranges[charset->num_entries].n_left + 1); /* no-overrap */
+ charset->num_entries++;
charset->data.range1 = ranges;
}
length += (charset->num_entries) * 3;
@@ -1693,11 +1747,12 @@ long cff_read_charsets(cff_font * cff)
while (count > 0 && charset->num_entries < cff->num_glyphs) {
ranges =
xrealloc(ranges,
- (charset->num_entries + 1) * sizeof(cff_range2));
+ (unsigned) (((unsigned) 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;
+ count = (card16) (count - (ranges[charset->num_entries].n_left + 1)); /* non-overrapping */
+ charset->num_entries++;
}
charset->data.range2 = ranges;
length += (charset->num_entries) * 4;
@@ -1709,12 +1764,15 @@ long cff_read_charsets(cff_font * cff)
break;
}
- if (count > 0)
+ if (count > 0) {
+ fprintf(stdout, "count=%d\n", count);
CFF_ERROR("Charset data possibly broken");
+ }
return length;
}
+@ @c
long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen)
{
long len = 0;
@@ -1736,8 +1794,8 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen)
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;
+ dest[len++] = (card8) ((sid >> 8) & 0xff);
+ dest[len++] = (card8) (sid & 0xff);
}
break;
case 1:
@@ -1745,9 +1803,10 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen)
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;
+ dest[len++] =
+ (card8) (((charset->data).range1[i].first >> 8) & 0xff);
+ dest[len++] = (card8) ((charset->data).range1[i].first & 0xff);
+ dest[len++] = (card8) ((charset->data).range1[i].n_left);
}
}
break;
@@ -1756,10 +1815,12 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen)
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;
+ dest[len++] =
+ (card8) (((charset->data).range2[i].first >> 8) & 0xff);
+ dest[len++] = (card8) ((charset->data).range2[i].first & 0xff);
+ dest[len++] =
+ (card8) (((charset->data).range2[i].n_left >> 8) & 0xff);
+ dest[len++] = (card8) ((charset->data).range2[i].n_left & 0xff);
}
}
break;
@@ -1773,33 +1834,33 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen)
-/*
- * Type 2 Charstring support:
- * Decode and encode Type 2 charstring
- *
- * All local/global subroutine calls in a given charstring is replace by the
- * content of subroutine charstrings. We do this because some PostScript RIP
- * may have problems with sparse subroutine array. Workaround for this is to
- * re-order subroutine array so that no gap appears in the subroutine array,
- * or put dummy charstrings that contains only `return' in the gap. However,
- * re-ordering of subroutine is rather difficult for Type 2 charstrings due
- * to the bias which depends on the total number of subroutines. Replacing
- * callgsubr/callsubr calls with the content of the corresponding subroutine
- * charstring may be more efficient than putting dummy subroutines in the
- * case of subsetted font. Adobe distiller seems doing same thing.
- *
- * And also note that subroutine numbers within subroutines can depend on the
- * content of operand stack as follows:
- *
- * ... l m callsubr << subr #(m+bias): n add callsubr >> ...
- *
- * I've not implemented the `random' operator which generates a pseudo-random
- * number in the range (0, 1] and push them into argument stack.
- * How pseudo-random sequences are generated is not documented in the Type 2
- * charstring spec..
- */
+@* Type 2 Charstring support.
+
+Decode and encode Type 2 charstring
+All local/global subroutine calls in a given charstring is replace by the
+content of subroutine charstrings. We do this because some PostScript RIP
+may have problems with sparse subroutine array. Workaround for this is to
+re-order subroutine array so that no gap appears in the subroutine array,
+or put dummy charstrings that contains only `return' in the gap. However,
+re-ordering of subroutine is rather difficult for Type 2 charstrings due
+to the bias which depends on the total number of subroutines. Replacing
+callgsubr/callsubr calls with the content of the corresponding subroutine
+charstring may be more efficient than putting dummy subroutines in the
+case of subsetted font. Adobe distiller seems doing same thing.
+And also note that subroutine numbers within subroutines can depend on the
+content of operand stack as follows:
+
+\.{ ... l m callsubr << subr \#(m+bias): n add callsubr >> ...}
+
+I've not implemented the `random' operator which generates a pseudo-random
+number in the range (0, 1] and push them into argument stack.
+How pseudo-random sequences are generated is not documented in the Type 2
+charstring spec..
+
+
+@c
#define CS_TYPE2_DEBUG_STR "Type2 Charstring Parser"
#define CS_TYPE2_DEBUG 5
@@ -1829,29 +1890,29 @@ static int cs2_nest = 0;
static int have_width = 0;
static double width = 0.0;
-/*
- * Standard Encoding Accented Characters:
- * Optional four arguments for endchar. See, CFF spec., p.35.
- * This is obsolete feature and is no longer supported.
- */
+@
+ Standard Encoding Accented Characters:
+ Optional four arguments for endchar. See, CFF spec., p.35.
+ This is obsolete feature and is no longer supported.
+@c
#if 0
/* adx ady bchar achar endchar */
static double seac[4] = { 0.0, 0.0, 0.0, 0.0 };
#endif
-/* Operand stack and Transient array */
+@ Operand stack and Transient array
+@c
static int cs2_stack_top = 0;
static double cs2_arg_stack[CS_ARG_STACK_MAX];
static double trn_array[CS_TRANS_ARRAY_MAX];
-/*
- * Type 2 CharString encoding
- */
+@ Type 2 CharString encoding
+@c
/*
- * 1-byte CharString operaotrs:
- * cs_escape is first byte of two-byte operator
- */
+ 1-byte CharString operaotrs:
+ |cs_escape| is first byte of two-byte operator
+*/
/* RESERVED 0 */
#define cs_hstem 1
@@ -1862,11 +1923,11 @@ static double trn_array[CS_TRANS_ARRAY_MAX];
#define cs_hlineto 6
#define cs_vlineto 7
#define cs_rrcurveto 8
-/* cs_closepath 9 : TYPE1 */
+/* |cs_closepath| 9 : TYPE1 */
#define cs_callsubr 10
#define cs_return 11
#define cs_escape 12
-/* cs_hsbw 13 : TYPE1 */
+/* |cs_hsbw| 13 : TYPE1 */
#define cs_endchar 14
/* RESERVED 15 */
/* RESERVED 16 */
@@ -1887,18 +1948,18 @@ static double trn_array[CS_TRANS_ARRAY_MAX];
#define cs_hvcurveto 31
/*
- * 2-byte CharString operaotrs:
- * "dotsection" is obsoleted in Type 2 charstring.
+ 2-byte CharString operaotrs:
+ "dotsection" is obsoleted in Type 2 charstring.
*/
#define cs_dotsection 0
-/* cs_vstem3 1 : TYPE1 */
-/* cs_hstem3 2 : TYPE1 */
+/* |cs_vstem3| 1 : TYPE1 */
+/* |cs_hstem3| 2 : TYPE1 */
#define cs_and 3
#define cs_or 4
#define cs_not 5
-/* cs_seac 6 : TYPE1 */
-/* cs_sbw 7 : TYPE1 */
+/* |cs_seac| 6 : TYPE1 */
+/* |cs_sbw| 7 : TYPE1 */
/* RESERVED 8 */
#define cs_abs 9
#define cs_add 10
@@ -1907,8 +1968,8 @@ static double trn_array[CS_TRANS_ARRAY_MAX];
/* RESERVED 13 */
#define cs_neg 14
#define cs_eq 15
-/* cs_callothersubr 16 : TYPE1 */
-/* cs_pop 17 : TYPE1 */
+/* |cs_callothersubr| 16 : TYPE1 */
+/* |cs_pop| 17 : TYPE1 */
#define cs_drop 18
/* RESERVED 19 */
#define cs_put 20
@@ -1922,7 +1983,7 @@ static double trn_array[CS_TRANS_ARRAY_MAX];
#define cs_exch 28
#define cs_index 29
#define cs_roll 30
-/* cs_setcurrentpoint 31 : TYPE1 */
+/* |cs_setcurrentpoint| 31 : TYPE1 */
/* RESERVED 32 */
/* RESERVED 33 */
#define cs_hflex 34
@@ -1930,9 +1991,9 @@ static double trn_array[CS_TRANS_ARRAY_MAX];
#define cs_hflex1 36
#define cs_flex1 37
-/*
- * clear_stack() put all operands sotred in operand stack to dest.
- */
+@
+|clear_stack()| put all operands sotred in operand stack to dest.
+@c
static void clear_stack(card8 ** dest, card8 * limit)
{
int i;
@@ -1945,39 +2006,39 @@ static void clear_stack(card8 ** dest, card8 * limit)
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.
+ 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) {
+ } else if (fabs(value - (double) 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;
+ *(*dest)++ = (card8) ((ivalue >> 8) & 0xff);
+ *(*dest)++ = (card8) (ivalue & 0xff);
+ ivalue = (long) ((value - (double) ivalue) * 0x10000l); /* fraction */
+ *(*dest)++ = (card8) ((ivalue >> 8) & 0xff);
+ *(*dest)++ = (card8) (ivalue & 0xff);
/* Everything else are integers. */
} else if (ivalue >= -107 && ivalue <= 107) {
DST_NEED(limit, *dest + 1);
- *(*dest)++ = ivalue + 139;
+ *(*dest)++ = (card8) (ivalue + 139);
} else if (ivalue >= 108 && ivalue <= 1131) {
DST_NEED(limit, *dest + 2);
- ivalue = 0xf700u + ivalue - 108;
- *(*dest)++ = (ivalue >> 8) & 0xff;
- *(*dest)++ = ivalue & 0xff;
+ ivalue = (long) 0xf700u + ivalue - 108;
+ *(*dest)++ = (card8) ((ivalue >> 8) & 0xff);
+ *(*dest)++ = (card8) (ivalue & 0xff);
} else if (ivalue >= -1131 && ivalue <= -108) {
DST_NEED(limit, *dest + 2);
- ivalue = 0xfb00u - ivalue - 108;
- *(*dest)++ = (ivalue >> 8) & 0xff;
- *(*dest)++ = ivalue & 0xff;
+ ivalue = (long) 0xfb00u - ivalue - 108;
+ *(*dest)++ = (card8) ((ivalue >> 8) & 0xff);
+ *(*dest)++ = (card8) (ivalue & 0xff);
} else if (ivalue >= -32768 && ivalue <= 32767) { /* shortint */
DST_NEED(limit, *dest + 3);
*(*dest)++ = 28;
- *(*dest)++ = (ivalue >> 8) & 0xff;
- *(*dest)++ = (ivalue) & 0xff;
+ *(*dest)++ = (card8) ((ivalue >> 8) & 0xff);
+ *(*dest)++ = (card8) ((ivalue) & 0xff);
} else { /* Shouldn't come here */
CFF_ERROR("Unexpected error.");
}
@@ -1988,16 +2049,16 @@ static void clear_stack(card8 ** dest, card8 * limit)
return;
}
-/*
- * Single byte operators:
- * Path construction, Operator for finishing a path, Hint operators.
- *
- * phase:
- * 0: inital state
- * 1: hint declaration, first stack-clearing operator appeared
- * 2: in path construction
- */
+@
+ Single byte operators:
+ Path construction, Operator for finishing a path, Hint operators.
+
+ phase:
+ \item 0: inital state
+ \item 1: hint declaration, first stack-clearing operator appeared
+ \item 2: in path construction
+@c
static void
do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr)
{
@@ -2037,7 +2098,7 @@ do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr)
int masklen = (num_stems + 7) / 8;
DST_NEED(limit, *dest + masklen);
SRC_NEED(endptr, *data + masklen);
- memmove(*dest, *data, masklen);
+ memmove(*dest, *data, (size_t) masklen);
*data += masklen;
*dest += masklen;
}
@@ -2117,13 +2178,14 @@ do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr)
return;
}
-/*
- * Double byte operators:
- * Flex, arithmetic, conditional, and storage operators.
- *
- * Following operators are not supported:
- * random: How random ?
- */
+@
+ Double byte operators:
+ Flex, arithmetic, conditional, and storage operators.
+
+ Following operators are not supported:
+ random: How random ?
+
+@c
static void
do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr)
{
@@ -2331,10 +2393,10 @@ do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr)
return;
}
-/*
- * integer:
- * exactly the same as the DICT encoding (except 29)
- */
+@
+ integer:
+ exactly the same as the DICT encoding (except 29)
+@c
static void cs2_get_integer(card8 ** data, card8 * endptr)
{
long result = 0;
@@ -2373,9 +2435,9 @@ static void cs2_get_integer(card8 ** data, card8 * endptr)
return;
}
-/*
- * Signed 16.16-bits fixed number for Type 2 charstring encoding
- */
+@
+Signed 16.16-bits fixed number for Type 2 charstring encoding
+@c
static void get_fixed(card8 ** data, card8 * endptr)
{
long ivalue;
@@ -2386,7 +2448,7 @@ static void get_fixed(card8 ** data, card8 * endptr)
SRC_NEED(endptr, *data + 4);
ivalue = *(*data) * 0x100 + *(*data + 1);
- rvalue = (ivalue > 0x7fffL) ? (ivalue - 0x10000L) : ivalue;
+ rvalue = (double) ((ivalue > 0x7fffL) ? (ivalue - 0x10000L) : ivalue);
ivalue = *(*data + 2) * 0x100 + *(*data + 3);
rvalue += ((double) ivalue) / 0x10000L;
@@ -2397,15 +2459,16 @@ static void get_fixed(card8 ** data, card8 * endptr)
return;
}
-/*
- * Subroutines:
- * The bias for subroutine number is introduced in type 2 charstrings.
- *
- * subr: set to a pointer to the subroutine charstring.
- * len: set to the length of subroutine charstring.
- * subr_idx: CFF INDEX data that contains subroutines.
- * id: biased subroutine number.
- */
+@
+ Subroutines:
+ The bias for subroutine number is introduced in type 2 charstrings.
+
+ subr: set to a pointer to the subroutine charstring.
+ len: set to the length of subroutine charstring.
+ |subr_idx|: CFF INDEX data that contains subroutines.
+ id: biased subroutine number.
+
+@c
static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id)
{
card16 count;
@@ -2429,19 +2492,19 @@ static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id)
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];
+ *len = (long) ((subr_idx->offset)[id + 1] - (subr_idx->offset)[id]);
*subr = subr_idx->data + (subr_idx->offset)[id] - 1;
return;
}
-/*
- * NOTE:
- * The Type 2 interpretation of a number encoded in five-bytes (those with
- * an initial byte value of 255) differs from how it is interpreted in the
- * Type 1 format.
- */
+@ NOTE:
+ The Type 2 interpretation of a number encoded in five-bytes (those with
+ an initial byte value of 255) differs from how it is interpreted in the
+ Type 1 format.
+
+@c
static void
do_charstring(card8 ** dest, card8 * limit,
card8 ** data, card8 * endptr,
@@ -2514,6 +2577,7 @@ do_charstring(card8 ** dest, card8 * limit,
return;
}
+@ @c
static void cs_parse_init(void)
{
status = CS_PARSE_OK;
@@ -2523,9 +2587,9 @@ static void cs_parse_init(void)
cs2_stack_top = 0;
}
-/*
- * Not just copying...
- */
+
+@ Not just copying...
+@c
long
cs_copy_charstring(card8 * dst, long dstlen,
card8 * src, long srclen,
@@ -2554,13 +2618,13 @@ cs_copy_charstring(card8 * dst, long dstlen,
return (long) (dst - save);
}
-/* encodings */
+@* encodings.
-/*
- * Encoding and Charset
- *
- * Encoding and Charset arrays always begin with GID = 1.
- */
+@ Encoding and Charset
+
+Encoding and Charset arrays always begin with GID = 1.
+
+@c
long cff_read_encoding(cff_font * cff)
{
cff_encoding *encoding;
@@ -2588,7 +2652,7 @@ long cff_read_encoding(cff_font * cff)
return 0;
}
- cff->offset = offset;
+ cff->offset = (l_offset) offset;
cff->encoding = encoding = xcalloc(1, sizeof(cff_encoding));
encoding->format = get_card8(cff);
length = 1;
@@ -2596,7 +2660,7 @@ long cff_read_encoding(cff_font * cff)
switch (encoding->format & (~0x80)) {
case 0:
encoding->num_entries = get_card8(cff);
- (encoding->data).codes = xcalloc(encoding->num_entries, sizeof(card8));
+ (encoding->data).codes = xmalloc(encoding->num_entries * sizeof(card8));
for (i = 0; i < (encoding->num_entries); i++) {
(encoding->data).codes[i] = get_card8(cff);
}
@@ -2639,6 +2703,7 @@ long cff_read_encoding(cff_font * cff)
return length;
}
+@ @c
long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen)
{
long len = 0;
@@ -2668,8 +2733,8 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen)
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;
+ dest[len++] = (card8) ((encoding->data).range1[i].first & 0xff);
+ dest[len++] = (card8) ((encoding->data).range1[i].n_left);
}
}
break;
@@ -2683,16 +2748,17 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen)
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;
+ dest[len++] = (card8) ((encoding->supp)[i].code);
+ dest[len++] = (card8) (((encoding->supp)[i].glyph >> 8) & 0xff);
+ dest[len++] = (card8) ((encoding->supp)[i].glyph & 0xff);
}
}
return len;
}
-/* CID-Keyed font specific */
+@ CID-Keyed font specific
+@c
long cff_read_fdselect(cff_font * cff)
{
cff_fdselect *fdsel;
@@ -2706,7 +2772,7 @@ long cff_read_fdselect(cff_font * cff)
return 0;
offset = (long) cff_dict_get(cff->topdict, "FDSelect", 0);
- cff->offset = offset;
+ cff->offset = (l_offset) offset;
cff->fdselect = fdsel = xcalloc(1, sizeof(cff_fdselect));
fdsel->format = get_card8(cff);
@@ -2715,7 +2781,7 @@ long cff_read_fdselect(cff_font * cff)
switch (fdsel->format) {
case 0:
fdsel->num_entries = cff->num_glyphs;
- (fdsel->data).fds = xcalloc(fdsel->num_entries, sizeof(card8));
+ (fdsel->data).fds = xmalloc(fdsel->num_entries * sizeof(card8));
for (i = 0; i < (fdsel->num_entries); i++) {
(fdsel->data).fds[i] = get_card8(cff);
}
@@ -2748,6 +2814,7 @@ long cff_read_fdselect(cff_font * cff)
}
+@ @c
long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen)
{
cff_fdselect *fdsel;
@@ -2781,16 +2848,17 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen)
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;
+ dest[len++] =
+ (card8) (((fdsel->data).ranges[i].first >> 8) & 0xff);
+ dest[len++] = (card8) ((fdsel->data).ranges[i].first & 0xff);
+ dest[len++] = (card8) ((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;
+ dest[len++] = (card8) ((cff->num_glyphs >> 8) & 0xff);
+ dest[len++] = (card8) (cff->num_glyphs & 0xff);
+ dest[1] = (card8) (((len / 3 - 1) >> 8) & 0xff);
+ dest[2] = (card8) ((len / 3 - 1) & 0xff);
}
break;
default:
@@ -2803,10 +2871,10 @@ 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)
+@ Create an instance of embeddable font.
+
+@c
+static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname)
{
cff_index *topdict, *fdarray, *private;
unsigned char *dest;
@@ -2823,9 +2891,9 @@ static void write_fontfile(cff_font * cffont, char *fullname)
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;
+ topdict->offset[1] = (l_offset) 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]) {
@@ -2835,10 +2903,13 @@ static void write_fontfile(cff_font * cffont, char *fullname)
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);
+ (private->offset)[i + 1] =
+ (unsigned long) ((private->offset)[i] + (unsigned) size);
+ (fdarray->offset)[i + 1] =
+ (unsigned long) ((fdarray->offset)[i] + (unsigned)
+ cff_dict_pack(cffont->fdarray[i],
+ (card8 *) work_buffer,
+ WORK_BUFFER_SIZE));
}
destlen = 4; /* header size */
@@ -2850,9 +2921,9 @@ static void write_fontfile(cff_font * cffont, char *fullname)
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 */
+ destlen = (long) (destlen + (long) private->offset[private->count] - 1); /* Private is not INDEX */
- dest = xcalloc(destlen, sizeof(card8));
+ dest = xcalloc((unsigned) destlen, sizeof(card8));
offset = 0;
/* Header */
@@ -2868,36 +2939,38 @@ static void write_fontfile(cff_font * cffont, char *fullname)
offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset);
/* charset */
- cff_dict_set(cffont->topdict, "charset", 0, offset);
+ cff_dict_set(cffont->topdict, "charset", 0, (double) offset);
offset += cff_pack_charsets(cffont, dest + offset, destlen - offset);
/* FDSelect */
- cff_dict_set(cffont->topdict, "FDSelect", 0, offset);
+ cff_dict_set(cffont->topdict, "FDSelect", 0, (double) offset);
offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset);
/* CharStrings */
- cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
+ cff_dict_set(cffont->topdict, "CharStrings", 0, (double) 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);
+ cff_dict_set(cffont->topdict, "FDArray", 0, (double) offset);
fdarray_offset = offset;
offset += cff_index_size(fdarray);
- fdarray->data = xcalloc(fdarray->offset[fdarray->count] - 1, sizeof(card8));
+ fdarray->data =
+ xcalloc((unsigned) (fdarray->offset[fdarray->count] - 1),
+ sizeof(card8));
for (i = 0; i < cffont->num_fds; i++) {
- size = private->offset[i + 1] - private->offset[i];
+ size = (long) (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_set(cffont->fdarray[i], "Private", 0, (double) size);
+ cff_dict_set(cffont->fdarray[i], "Private", 1, (double) offset);
}
cff_dict_pack(cffont->fdarray[i],
fdarray->data + (fdarray->offset)[i] - 1,
- fdarray->offset[fdarray->count] - 1);
+ (long) (fdarray->offset[fdarray->count] - 1));
offset += size;
}
@@ -2906,45 +2979,47 @@ static void write_fontfile(cff_font * cffont, char *fullname)
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);
+ topdict->data =
+ xcalloc((unsigned) (topdict->offset[topdict->count] - 1),
+ sizeof(card8));
+ cff_dict_pack(cffont->topdict, topdict->data,
+ (long) (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]);
+ fb_putchar(pdf, dest[i]);
- /*fprintf(stdout," (%i/%i)",offset,cffont->stream_size); */
xfree(dest);
return;
}
-/* this block is used a few times */
-
+@ this block is used a few times
+@c
#define DO_COPY_CHARSTRING() \
if ((avl_find(fd->gl_tree,glyph) != NULL)) { \
- size = cs_idx->offset[code+1] - cs_idx->offset[code]; \
+ size = (long)(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)); \
+ max_len = (long)(charstring_len + 2 * CS_STR_LEN_MAX); \
+ charstrings->data = xrealloc(charstrings->data, (unsigned)((unsigned)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); \
+ (charstrings->offset)[gid] = (unsigned)(charstring_len + 1); \
+ cffont->offset= (l_offset)((unsigned)offset + (cs_idx->offset)[code] - 1); \
+ memcpy(data,&cffont->stream[cffont->offset],(size_t)size); \
charstring_len += cs_copy_charstring(charstrings->data + charstring_len, \
- max_len - 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)
+@ @c
+void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd)
{
cff_index *charstrings, *cs_idx;
@@ -2961,7 +3036,7 @@ void write_cff(cff_font * cffont, fd_entry * fd)
glw_entry *glyph, *found;
struct avl_traverser t;
- fullname = xcalloc(8 + strlen(fd->fontname), 1);
+ fullname = xcalloc((unsigned) (8 + strlen(fd->fontname)), 1);
sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname);
/* finish parsing the CFF */
@@ -2969,7 +3044,7 @@ void write_cff(cff_font * cffont, fd_entry * fd)
cff_read_subrs(cffont);
/*
- * Widths
+ Widths
*/
if (cffont->private[0] &&
cff_dict_known(cffont->private[0], "defaultWidthX")) {
@@ -3001,7 +3076,7 @@ void write_cff(cff_font * cffont, fd_entry * fd)
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;
+ last_cid = (card16) found->id;
num_glyphs++;
}
@@ -3022,7 +3097,7 @@ void write_cff(cff_font * cffont, fd_entry * fd)
charset = xcalloc(1, sizeof(cff_charsets));
charset->format = 0;
- charset->num_entries = num_glyphs - 1;
+ charset->num_entries = (card16) (num_glyphs - 1);
charset->data.glyphs = xcalloc(num_glyphs, sizeof(s_SID));
gid = 0;
@@ -3031,7 +3106,7 @@ void write_cff(cff_font * cffont, fd_entry * fd)
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;
+ charset->data.glyphs[gid] = (s_SID) found->id;
gid++;
}
}
@@ -3060,19 +3135,19 @@ void write_cff(cff_font * cffont, fd_entry * fd)
cff_dict_remove(cffont->topdict, "Private");
cff_dict_remove(cffont->topdict, "Encoding");
- cffont->offset = cff_dict_get(cffont->topdict, "CharStrings", 0);
+ cffont->offset = (l_offset) cff_dict_get(cffont->topdict, "CharStrings", 0);
cs_idx = cff_get_index_header(cffont);
- offset = cffont->offset;
+ offset = (long) 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);
+ charstrings = cff_new_index((card16) (cs_count + 1));
max_len = 2 * CS_STR_LEN_MAX;
- charstrings->data = xcalloc(max_len, sizeof(card8));
+ charstrings->data = xcalloc((unsigned) max_len, sizeof(card8));
charstring_len = 0;
gid = 0;
@@ -3081,7 +3156,7 @@ void write_cff(cff_font * cffont, fd_entry * fd)
{
int i;
for (i = 0; i < cs_count; i++) {
- code = i;
+ code = (card16) i;
glyph->id = code;
DO_COPY_CHARSTRING();
}
@@ -3096,13 +3171,13 @@ void write_cff(cff_font * cffont, fd_entry * fd)
xfree(data);
cff_release_index(cs_idx);
- (charstrings->offset)[num_glyphs] = charstring_len + 1;
+ (charstrings->offset)[num_glyphs] = (l_offset) (charstring_len + 1);
charstrings->count = num_glyphs;
cffont->num_glyphs = num_glyphs;
cffont->cstrings = charstrings;
/*
- * We don't use subroutines at all.
+ We don't use subroutines at all.
*/
if (cffont->gsubr)
cff_release_index(cffont->gsubr);
@@ -3131,17 +3206,20 @@ void write_cff(cff_font * cffont, fd_entry * fd)
(double) cff_get_sid(cffont, "Identity"));
cff_dict_set(cffont->topdict, "ROS", 2, 0.0);
- write_fontfile(cffont, fullname);
+ write_fontfile(pdf, cffont, fullname);
xfree(fullname);
cff_close(cffont);
}
+@ @c
+#undef ERROR /* for mingw */
#define ERROR(a) { perror(a); return 0; }
-/* Input : SID or CID (16-bit unsigned int)
- * Output: glyph index
- */
+@ Input : SID or CID (16-bit unsigned int)
+ Output: glyph index
+
+@c
card16 cff_charsets_lookup(cff_font * cff, card16 cid)
{
card16 gid = 0;
@@ -3165,7 +3243,7 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid)
case 0:
for (i = 0; i < charset->num_entries; i++) {
if (cid == charset->data.glyphs[i]) {
- gid = i + 1;
+ gid = (card16) (i + 1);
return gid;
}
}
@@ -3176,10 +3254,10 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid)
cid <=
charset->data.range1[i].first +
charset->data.range1[i].n_left) {
- gid += cid - charset->data.range1[i].first + 1;
+ gid = (card16) (gid + cid - charset->data.range1[i].first + 1);
return gid;
}
- gid += charset->data.range1[i].n_left + 1;
+ gid = (card16) (gid + charset->data.range1[i].n_left + 1);
}
break;
case 2:
@@ -3188,10 +3266,10 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid)
cid <=
charset->data.range2[i].first +
charset->data.range2[i].n_left) {
- gid += cid - charset->data.range2[i].first + 1;
+ gid = (card16) (gid + cid - charset->data.range2[i].first + 1);
return gid;
}
- gid += charset->data.range2[i].n_left + 1;
+ gid = (card16) (gid + charset->data.range2[i].n_left + 1);
}
break;
default:
@@ -3202,10 +3280,11 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid)
}
+@ @c
#define is_cidfont(a) ((a)->flag & FONTTYPE_CIDFONT)
#define CID_MAX 65535
-void write_cid_cff(cff_font * cffont, fd_entry * fd)
+void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd)
{
cff_index *charstrings, *cs_idx;
@@ -3232,7 +3311,7 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
return;
}
- fullname = xcalloc(8 + strlen(fd->fontname), 1);
+ fullname = xcalloc((unsigned) (8 + strlen(fd->fontname)), 1);
sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname);
/* finish parsing the CFF */
@@ -3243,8 +3322,9 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
cid_count = CFF_CIDCOUNT_DEFAULT;
}
cff_read_charsets(cffont);
- CIDToGIDMap = xmalloc((2 * cid_count) * sizeof(unsigned char));
- memset(CIDToGIDMap, 0, 2 * cid_count);
+ CIDToGIDMap = xmalloc((unsigned)
+ ((2 * (unsigned) cid_count) * sizeof(unsigned char)));
+ memset(CIDToGIDMap, 0, (size_t) (2 * cid_count));
glyph = xtalloc(1, glw_entry);
@@ -3259,12 +3339,12 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
last_cid = 0;
num_glyphs = 0;
for (cid = 0; cid <= CID_MAX; cid++) {
- glyph->id = cid;
+ glyph->id = (unsigned) 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;
+ gid = (card16) cff_charsets_lookup(cffont, (card16) cid);
+ CIDToGIDMap[2 * cid] = (unsigned char) ((gid >> 8) & 0xff);
+ CIDToGIDMap[2 * cid + 1] = (unsigned char) (gid & 0xff);
+ last_cid = (card16) cid;
num_glyphs++;
}
}
@@ -3276,10 +3356,10 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
cff_read_subrs(cffont);
- cffont->offset = cff_dict_get(cffont->topdict, "CharStrings", 0);
+ cffont->offset = (l_offset) cff_dict_get(cffont->topdict, "CharStrings", 0);
cs_idx = cff_get_index_header(cffont);
- offset = cffont->offset;
+ offset = (long) cffont->offset;
cs_count = cs_idx->count;
if (cs_count < 2) {
CFF_ERROR("No valid charstring data found.");
@@ -3295,9 +3375,9 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
fdselect->num_entries = 0;
fdselect->data.ranges = xcalloc(num_glyphs, sizeof(cff_range3));
- charstrings = cff_new_index(cs_count + 1);
+ charstrings = cff_new_index((card16) (cs_count + 1));
max_len = 2 * CS_STR_LEN_MAX;
- charstrings->data = xcalloc(max_len, sizeof(card8));
+ charstrings->data = xcalloc((unsigned) max_len, sizeof(card8));
charstring_len = 0;
prev_fd = -1;
@@ -3306,23 +3386,27 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
for (cid = 0; cid <= last_cid; cid++) {
unsigned short gid_org;
- glyph->id = cid;
+ glyph->id = (unsigned) 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];
+ gid_org =
+ (short unsigned) ((CIDToGIDMap[2 * cid] << 8) |
+ (CIDToGIDMap[2 * cid + 1]));
+ size = (long) (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));
+ xrealloc(charstrings->data,
+ (unsigned) ((unsigned) 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);
+ (charstrings->offset)[gid] = (l_offset) (charstring_len + 1);
+ cffont->offset =
+ (l_offset) ((unsigned) offset + (cs_idx->offset)[gid_org] - 1);
+ memcpy(data, &cffont->stream[cffont->offset], (size_t) size);
fdsel = cff_fdselect_lookup(cffont, gid_org);
charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
max_len - charstring_len,
@@ -3332,13 +3416,13 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
NULL);
if (cid > 0 && gid_org > 0) {
- charset->data.glyphs[charset->num_entries] = cid;
- charset->num_entries += 1;
+ charset->data.glyphs[charset->num_entries] = (s_SID) cid;
+ charset->num_entries++;
}
if (fdsel != prev_fd) {
fdselect->data.ranges[fdselect->num_entries].first = gid;
- fdselect->data.ranges[fdselect->num_entries].fd = fdsel;
- fdselect->num_entries += 1;
+ fdselect->data.ranges[fdselect->num_entries].fd = (card8) fdsel;
+ fdselect->num_entries++;
prev_fd = fdsel;
}
gid++;
@@ -3351,7 +3435,7 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
xfree(CIDToGIDMap);
- (charstrings->offset)[num_glyphs] = charstring_len + 1;
+ (charstrings->offset)[num_glyphs] = (l_offset) (charstring_len + 1);
charstrings->count = num_glyphs;
cffont->num_glyphs = num_glyphs;
cffont->cstrings = charstrings;
@@ -3378,20 +3462,18 @@ void write_cid_cff(cff_font * cffont, fd_entry * fd)
}
}
- write_fontfile(cffont, fullname);
+ write_fontfile(pdf, cffont, fullname);
xfree(fullname);
cff_close(cffont);
}
+@ here is a sneaky trick: fontforge knows how to convert Type1 to CFF, so
+I have defined a utility function in luafflib.c that does exactly that.
+If it works out ok, I will clean up this code.
-/* here is a sneaky trick: fontforge knows how to convert Type1 to CFF, so
- * I have defined a utility function in luafflib.c that does exactly that.
- * If it works out ok, I will clean up this code.
- */
-#include <luafontloader/src/luafflib.h>
-
-void writetype1w(fd_entry * fd)
+@c
+void writetype1w(PDF pdf, fd_entry * fd)
{
cff_font *cff;
int i;
@@ -3423,10 +3505,10 @@ void writetype1w(fd_entry * fd)
if (tfm_size > 0) {
cff = read_cff(tfm_buffer, tfm_size, 0);
if (cff != NULL) {
- write_cff(cff, fd);
+ write_cff(pdf, cff, fd);
} else {
for (i = 0; i < tfm_size; i++)
- fb_putchar(tfm_buffer[i]);
+ fb_putchar(pdf, tfm_buffer[i]);
}
fd->ff_found = 1;
} else {
diff --git a/Build/source/texk/web2c/luatexdir/font/writeenc.c b/Build/source/texk/web2c/luatexdir/font/writeenc.c
deleted file mode 100644
index e0cd7bc43a0..00000000000
--- a/Build/source/texk/web2c/luatexdir/font/writeenc.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* writeenc.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "ptexlib.h"
-#include "inc-epdf.h"
-
-static const char _svn_version[] =
- "$Id: writeenc.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/writeenc.c $";
-
-/**********************************************************************/
-/* All encoding entries go into AVL tree for fast search by name. */
-
-struct avl_table *fe_tree = NULL;
-
-/* AVL sort fe_entry into fe_tree by name */
-
-static int comp_fe_entry(const void *pa, const void *pb, void *p)
-{
- (void) p;
- return strcmp(((const fe_entry *) pa)->name, ((const fe_entry *) pb)->name);
-}
-
-static fe_entry *new_fe_entry(void)
-{
- fe_entry *fe;
- fe = xtalloc(1, fe_entry);
- fe->name = NULL;
- fe->fe_objnum = 0;
- fe->glyph_names = NULL; /* encoding file not yet read in */
- fe->tx_tree = NULL;
- return fe;
-}
-
-static fe_entry *lookup_fe_entry(char *s)
-{
- fe_entry fe;
- assert(s != NULL);
- fe.name = s;
- if (fe_tree == NULL) {
- fe_tree = avl_create(comp_fe_entry, NULL, &avl_xallocator);
- assert(fe_tree != NULL);
- }
- return (fe_entry *) avl_find(fe_tree, &fe);
-}
-
-static void register_fe_entry(fe_entry * fe)
-{
- void **aa;
- if (fe_tree == NULL) {
- fe_tree = avl_create(comp_fe_entry, NULL, &avl_xallocator);
- assert(fe_tree != NULL);
- }
- assert(fe != NULL);
- assert(fe->name != NULL);
- assert(lookup_fe_entry(fe->name) == NULL); /* encoding not yet registered */
- aa = avl_probe(fe_tree, fe);
- assert(aa != NULL);
-}
-
-fe_entry *get_fe_entry(char *s)
-{
- fe_entry *fe;
- char **gl;
- if ((fe = lookup_fe_entry(s)) == NULL && (gl = load_enc_file(s)) != NULL) {
- fe = new_fe_entry();
- fe->name = s;
- fe->glyph_names = gl;
- register_fe_entry(fe);
- }
- return fe;
-}
-
-/**********************************************************************/
-
-void epdf_write_enc(char **glyph_names, integer fe_objnum)
-{
- int i, i_old;
- assert(glyph_names != NULL);
- assert(fe_objnum != 0);
- pdf_begin_dict(fe_objnum, 1);
- pdf_puts("/Type /Encoding\n");
- pdf_puts("/Differences [");
- for (i = 0, i_old = -2; i < 256; i++)
- if (glyph_names[i] != notdef) {
- if (i == i_old + 1) /* no gap */
- pdf_printf("/%s", glyph_names[i]);
- else {
- if (i_old == -2)
- pdf_printf("%i/%s", i, glyph_names[i]);
- else
- pdf_printf(" %i/%s", i, glyph_names[i]);
- }
- i_old = i;
- }
- pdf_puts("]\n");
- pdf_end_dict();
-}
-
-static void write_enc(char **glyph_names, struct avl_table *tx_tree, integer fe_objnum)
-{
- int i_old, *p;
- struct avl_traverser t;
- assert(glyph_names != NULL);
- assert(tx_tree != NULL);
- assert(fe_objnum != 0);
- pdf_begin_dict(fe_objnum, 1);
- pdf_puts("/Type /Encoding\n");
- 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)) {
- if (*p == i_old + 1) /* no gap */
- pdf_printf("/%s", glyph_names[*p]);
- else {
- if (i_old == -2)
- pdf_printf("%i/%s", *p, glyph_names[*p]);
- else
- pdf_printf(" %i/%s", *p, glyph_names[*p]);
- }
- i_old = *p;
- }
- pdf_puts("]\n");
- pdf_end_dict();
-}
-
-static void write_fontencoding(fe_entry * fe)
-{
- assert(fe != NULL);
- write_enc(fe->glyph_names, fe->tx_tree, fe->fe_objnum);
-}
-
-void write_fontencodings(void)
-{
- fe_entry *fe;
- struct avl_traverser t;
- if (fe_tree == NULL)
- return;
- avl_t_init(&t, fe_tree);
- for (fe = (fe_entry *) avl_t_first(&t, fe_tree); fe != NULL;
- fe = (fe_entry *) avl_t_next(&t))
- if (fe->fe_objnum != 0)
- write_fontencoding(fe);
-}
-
-/**********************************************************************/
-/* cleaning up... */
-
-static void destroy_fe_entry(void *pa, void *pb)
-{
- fe_entry *p;
- int i;
- (void) pb;
- p = (fe_entry *) pa;
- xfree(p->name);
- if (p->glyph_names != NULL)
- for (i = 0; i < 256; i++)
- if (p->glyph_names[i] != notdef)
- xfree(p->glyph_names[i]);
- xfree(p->glyph_names);
- xfree(p);
-}
-
-void enc_free(void)
-{
- if (fe_tree != NULL)
- avl_destroy(fe_tree, destroy_fe_entry);
- fe_tree = NULL;
-}
-
-/**********************************************************************/
diff --git a/Build/source/texk/web2c/luatexdir/font/writeenc.w b/Build/source/texk/web2c/luatexdir/font/writeenc.w
new file mode 100644
index 00000000000..1b98c824970
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/font/writeenc.w
@@ -0,0 +1,161 @@
+% writeenc.w
+%
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2008 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.
+
+% 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 <http://www.gnu.org/licenses/>. */
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: writeenc.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writeenc.w $";
+
+@ All encoding entries go into AVL tree for fast search by name.
+@c
+struct avl_table *fe_tree = NULL;
+
+@ AVL sort |fe_entry| into |fe_tree| by name
+@c
+static int comp_fe_entry(const void *pa, const void *pb, void *p)
+{
+ (void) p;
+ return strcmp(((const fe_entry *) pa)->name, ((const fe_entry *) pb)->name);
+}
+
+fe_entry *new_fe_entry(void)
+{
+ fe_entry *fe;
+ fe = xtalloc(1, fe_entry);
+ fe->name = NULL;
+ fe->fe_objnum = 0;
+ fe->glyph_names = NULL; /* encoding file not yet read in */
+ fe->tx_tree = NULL;
+ return fe;
+}
+
+fe_entry *lookup_fe_entry(char *s)
+{
+ fe_entry fe;
+ assert(s != NULL);
+ fe.name = s;
+ if (fe_tree == NULL) {
+ fe_tree = avl_create(comp_fe_entry, NULL, &avl_xallocator);
+ assert(fe_tree != NULL);
+ }
+ return (fe_entry *) avl_find(fe_tree, &fe);
+}
+
+void register_fe_entry(fe_entry * fe)
+{
+ void **aa;
+ if (fe_tree == NULL) {
+ fe_tree = avl_create(comp_fe_entry, NULL, &avl_xallocator);
+ assert(fe_tree != NULL);
+ }
+ assert(fe != NULL);
+ assert(fe->name != NULL);
+ assert(lookup_fe_entry(fe->name) == NULL); /* encoding not yet registered */
+ aa = avl_probe(fe_tree, fe);
+ assert(aa != NULL);
+}
+
+fe_entry *get_fe_entry(char *s)
+{
+ fe_entry *fe;
+ char **gl;
+ if ((fe = lookup_fe_entry(s)) == NULL && (gl = load_enc_file(s)) != NULL) {
+ fe = new_fe_entry();
+ fe->name = s;
+ fe->glyph_names = gl;
+ register_fe_entry(fe);
+ }
+ return fe;
+}
+
+@ @c
+void write_enc(PDF pdf, char **glyph_names, struct avl_table *tx_tree,
+ int fe_objnum)
+{
+ int i_old, *p;
+ struct avl_traverser t;
+ assert(glyph_names != NULL);
+ assert(tx_tree != NULL);
+ assert(fe_objnum != 0);
+ pdf_begin_dict(pdf, fe_objnum, 1);
+ pdf_puts(pdf, "/Type /Encoding\n");
+ pdf_puts(pdf, "/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)) {
+ if (*p == i_old + 1) /* no gap */
+ pdf_printf(pdf, "/%s", glyph_names[*p]);
+ else {
+ if (i_old == -2)
+ pdf_printf(pdf, "%i/%s", *p, glyph_names[*p]);
+ else
+ pdf_printf(pdf, " %i/%s", *p, glyph_names[*p]);
+ }
+ i_old = *p;
+ }
+ pdf_puts(pdf, "]\n");
+ pdf_end_dict(pdf);
+}
+
+void write_fontencoding(PDF pdf, fe_entry * fe)
+{
+ assert(fe != NULL);
+ write_enc(pdf, fe->glyph_names, fe->tx_tree, fe->fe_objnum);
+}
+
+void write_fontencodings(PDF pdf)
+{
+ fe_entry *fe;
+ struct avl_traverser t;
+ if (fe_tree == NULL)
+ return;
+ avl_t_init(&t, fe_tree);
+ for (fe = (fe_entry *) avl_t_first(&t, fe_tree); fe != NULL;
+ fe = (fe_entry *) avl_t_next(&t))
+ if (fe->fe_objnum != 0)
+ write_fontencoding(pdf, fe);
+}
+
+@ cleaning up...
+@c
+
+static void destroy_fe_entry(void *pa, void *pb)
+{
+ fe_entry *p;
+ int i;
+ (void) pb;
+ p = (fe_entry *) pa;
+ xfree(p->name);
+ if (p->glyph_names != NULL)
+ for (i = 0; i < 256; i++)
+ if (p->glyph_names[i] != notdef)
+ xfree(p->glyph_names[i]);
+ xfree(p->glyph_names);
+ xfree(p);
+}
+
+void enc_free(void)
+{
+ if (fe_tree != NULL)
+ avl_destroy(fe_tree, destroy_fe_entry);
+ fe_tree = NULL;
+}
diff --git a/Build/source/texk/web2c/luatexdir/font/writefont.c b/Build/source/texk/web2c/luatexdir/font/writefont.w
index 5dd861f88ee..523cae59740 100644
--- a/Build/source/texk/web2c/luatexdir/font/writefont.c
+++ b/Build/source/texk/web2c/luatexdir/font/writefont.w
@@ -1,33 +1,33 @@
-/* writefont.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% writefont.w
- This file is part of LuaTeX.
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% 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.
-#include "ptexlib.h"
-#include "luatexfont.h"
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
+@ @c
static const char _svn_version[] =
- "$Id: writefont.c 2331 2009-04-18 16:39:50Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/writefont.c $";
+ "$Id: writefont.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writefont.w $";
+
+#include "ptexlib.h"
+#include "lua/luatex-api.h"
-void write_cid_fontdictionary(fo_entry * fo, internalfontnumber f);
-void create_cid_fontdictionary(fm_entry * fm, integer font_objnum,
- internalfontnumber f);
+void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f);
+static void create_cid_fontdictionary(PDF pdf, internal_font_number f);
const key_entry font_key[FONT_KEYS_NUM] = {
{"Ascent", "Ascender", 1}
@@ -43,8 +43,8 @@ const key_entry font_key[FONT_KEYS_NUM] = {
, {"FontName", "FontName", 1}
};
-/**********************************************************************/
-
+@
+@c
struct avl_table *fo_tree = NULL; /* tree of font dictionaries */
struct avl_table *fd_tree = NULL; /* tree of font descriptor objects */
@@ -57,22 +57,16 @@ static int comp_fo_entry(const void *pa, const void *pb, void *p)
static int comp_fd_entry(const void *pa, const void *pb, void *p)
{
- int i;
const fd_entry *p1 = (const fd_entry *) pa, *p2 = (const fd_entry *) pb;
(void) p;
assert(p1->fm != NULL && is_fontfile(p1->fm) &&
p2->fm != NULL && is_fontfile(p2->fm));
- if ((i = strcmp(p1->fm->ff_name, p2->fm->ff_name)) != 0)
- return i;
- cmp_return(p1->fm->slant, p2->fm->slant);
- cmp_return(p1->fm->extend, p2->fm->extend);
- return 0;
+ return strcmp(p1->fm->ff_name, p2->fm->ff_name);
}
-/**********************************************************************/
-/* initialize data structure for /Type /Font */
-
-static fo_entry *new_fo_entry(void)
+@ initialize data structure for /Type /Font
+@c
+fo_entry *new_fo_entry(void)
{
fo_entry *fo;
fo = xtalloc(1, fo_entry);
@@ -89,8 +83,8 @@ static fo_entry *new_fo_entry(void)
return fo;
}
-/* initialize data structure for /Type /FontDescriptor */
-
+@ initialize data structure for /Type /FontDescriptor
+@c
fd_entry *new_fd_entry(void)
{
fd_entry *fd;
@@ -101,7 +95,6 @@ fd_entry *new_fd_entry(void)
fd->subset_tag = NULL;
fd->ff_found = false;
fd->ff_objnum = 0;
- fd->fn_objnum = 0;
fd->all_glyphs = false;
fd->write_ttf_glyph_names = false;
for (i = 0; i < FONT_KEYS_NUM; i++) {
@@ -116,33 +109,30 @@ fd_entry *new_fd_entry(void)
return fd;
}
-/**********************************************************************/
-/*
- * Only fallback values of font metrics are taken from the TFM info
- * of f by preset_fontmetrics(). During reading of the font file,
- * these values are replaced by metrics from the font, if available.
- */
+@
+Only fallback values of font metrics are taken from the TFM info
+of |f| by |preset_fontmetrics|. During reading of the font file,
+these values are replaced by metrics from the font, if available.
-static void preset_fontmetrics(fd_entry * fd, internalfontnumber f)
+@c
+static void preset_fontmetrics(fd_entry * fd, internal_font_number 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);
+ fd->font_dim[ITALIC_ANGLE_CODE].val = 0;
fd->font_dim[ASCENT_CODE].val =
- divide_scaled(char_height(f, 'h'), pdf_font_size(f), 3);
+ divide_scaled(char_height(f, 'h'), font_size(f), 3);
fd->font_dim[CAPHEIGHT_CODE].val =
- divide_scaled(char_height(f, 'H'), pdf_font_size(f), 3);
- i = -divide_scaled(char_depth(f, 'y'), pdf_font_size(f), 3);
+ divide_scaled(char_height(f, 'H'), font_size(f), 3);
+ i = -divide_scaled(char_depth(f, 'y'), 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, 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), 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), 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;
@@ -183,59 +173,52 @@ static void fix_fontmetrics(fd_entry * fd)
}
}
-static void write_fontmetrics(fd_entry * fd)
+static void write_fontmetrics(PDF pdf, fd_entry * fd)
{
int i;
fix_fontmetrics(fd);
- pdf_printf("/%s [%i %i %i %i]\n", font_key[FONTBBOX1_CODE].pdfname,
+ pdf_printf(pdf, "/%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);
+ pdf_printf(pdf, "/%s %i\n", font_key[i].pdfname,
+ fd->font_dim[i].val);
}
-/**********************************************************************/
-
-static void preset_fontname(fo_entry * fo)
+@
+@c
+static void preset_fontname(fo_entry * fo, internal_font_number f)
{
if (fo->fm->ps_name != NULL)
fo->fd->fontname = xstrdup(fo->fm->ps_name); /* just fallback */
+ else if (font_fullname(f) != NULL)
+ fo->fd->fontname = xstrdup(font_fullname(f));
else
fo->fd->fontname = xstrdup(fo->fm->tfm_name);
}
-static void write_fontname(fd_entry * fd, const char *key)
+static void write_fontname(PDF pdf, fd_entry * fd, const char *key)
{
assert(fd->fontname != NULL);
- pdf_puts("/");
+ pdf_puts(pdf, "/");
if (key != NULL)
- pdf_printf("%s /", key);
+ pdf_printf(pdf, "%s /", key);
if (fd->subset_tag != NULL)
- pdf_printf("%s+", fd->subset_tag);
- pdf_printf("%s\n", fd->fontname);
-}
-
-static void write_fontname_object(fd_entry * fd)
-{
- assert(fd->fn_objnum != 0);
- pdf_begin_obj(fd->fn_objnum, 1);
- write_fontname(fd, NULL);
- pdf_end_obj();
+ pdf_printf(pdf, "%s+", fd->subset_tag);
+ pdf_printf(pdf, "%s\n", fd->fontname);
}
-/**********************************************************************/
-
-fd_entry *lookup_fd_entry(char *s, integer slant, integer extend)
+@
+@c
+fd_entry *lookup_fd_entry(char *s)
{
fd_entry fd;
fm_entry fm;
assert(s != NULL);
fm.ff_name = s;
- fm.slant = slant;
- fm.extend = extend;
fd.fm = &fm;
if (fd_tree == NULL) {
fd_tree = avl_create(comp_fd_entry, NULL, &avl_xallocator);
@@ -244,12 +227,12 @@ fd_entry *lookup_fd_entry(char *s, integer slant, integer extend)
return (fd_entry *) avl_find(fd_tree, &fd);
}
-static fd_entry *lookup_fontdescriptor(fo_entry * fo)
+fd_entry *lookup_fontdescriptor(fo_entry * fo)
{
assert(fo != NULL);
assert(fo->fm != NULL);
assert(is_fontfile(fo->fm));
- return lookup_fd_entry(fo->fm->ff_name, fo->fm->slant, fo->fm->extend);
+ return lookup_fd_entry(fo->fm->ff_name);
}
void register_fd_entry(fd_entry * fd)
@@ -260,18 +243,18 @@ void register_fd_entry(fd_entry * fd)
assert(fd_tree != NULL);
}
assert(fd != NULL && fd->fm != NULL && is_fontfile(fd->fm));
- assert(lookup_fd_entry(fd->fm->ff_name, fd->fm->slant, fd->fm->extend) == NULL); /* font descriptor not yet registered */
+ assert(lookup_fd_entry(fd->fm->ff_name) == NULL); /* font descriptor not yet registered */
aa = avl_probe(fd_tree, fd);
assert(aa != NULL);
}
-static void create_fontdescriptor(fo_entry * fo, internalfontnumber f)
+void create_fontdescriptor(fo_entry * fo, internal_font_number f)
{
assert(fo != NULL);
assert(fo->fm != NULL);
assert(fo->fd == NULL);
fo->fd = new_fd_entry();
- preset_fontname(fo);
+ preset_fontname(fo, f);
preset_fontmetrics(fo->fd, f);
fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */
fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */
@@ -279,32 +262,13 @@ static void create_fontdescriptor(fo_entry * fo, internalfontnumber f)
assert(fo->fd->gl_tree != NULL);
}
-integer get_fd_objnum(fd_entry * fd)
-{
- assert(fd->fd_objnum != 0);
- return fd->fd_objnum;
-}
-
-integer get_fn_objnum(fd_entry * fd)
-{
- if (fd->fn_objnum == 0)
- fd->fn_objnum = pdf_new_objnum();
- return fd->fn_objnum;
-}
-
-void embed_whole_font(fd_entry * fd)
-{
- fd->all_glyphs = true;
-}
-
-/**********************************************************************/
-/*
- * For all used characters of TeX font f, get corresponding glyph names
- * from external reencoding (.enc) file and collect these in the glyph
- * tree gl_tree of font descriptor fd referenced by font dictionary fo.
- */
+@
+For all used characters of \TeX font |f|, get corresponding glyph names
+from external reencoding (.enc) file and collect these in the glyph
+tree |gl_tree| of font descriptor |fd| referenced by font dictionary |fo|.
-static void mark_reenc_glyphs(fo_entry * fo, internalfontnumber f)
+@c
+void mark_reenc_glyphs(fo_entry * fo, internal_font_number f)
{
int i;
char **g;
@@ -324,14 +288,14 @@ static void mark_reenc_glyphs(fo_entry * fo, internalfontnumber f)
}
}
-/*
- * Function mark_chars() has 2 uses:
- * 1. Mark characters as chars on TeX level.
- * 2. Mark encoding pairs used by TeX to optimize encoding vector.
- */
+@
+Function |mark_chars| has 2 uses:
+\item 1. Mark characters as chars on \TeX\ level.
+\item 2. Mark encoding pairs used by \TeX\ to optimize encoding vector.
-static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree,
- internalfontnumber f)
+@c
+struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree,
+ internal_font_number f)
{
int i, *j;
void **aa;
@@ -350,13 +314,13 @@ static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree,
return tx_tree;
}
-/**********************************************************************/
-
-static void get_char_range(fo_entry * fo, internalfontnumber f)
+@
+@c
+void get_char_range(fo_entry * fo, internal_font_number 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;
@@ -371,10 +335,10 @@ static void get_char_range(fo_entry * fo, internalfontnumber f)
}
}
-static int font_has_subset(internalfontnumber f)
+static int font_has_subset(internal_font_number f)
{
int i, s;
- 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;
s = i;
@@ -387,40 +351,40 @@ static int font_has_subset(internalfontnumber f)
return 1;
}
-static void write_charwidth_array(fo_entry * fo, internalfontnumber f)
+@
+@c
+static void write_charwidth_array(PDF pdf, fo_entry * fo,
+ internal_font_number f)
{
int i, j, *ip, *fip;
struct avl_traverser t;
assert(fo->tx_tree != NULL);
assert(fo->cw_objnum == 0);
- fo->cw_objnum = pdf_new_objnum();
- pdf_begin_obj(fo->cw_objnum, 1);
+ fo->cw_objnum = pdf_new_objnum(pdf);
+ pdf_begin_obj(pdf, fo->cw_objnum, 1);
avl_t_init(&t, fo->tx_tree);
fip = (int *) avl_t_first(&t, fo->tx_tree);
assert(fip != NULL);
- pdf_puts("[");
+ pdf_puts(pdf, "[");
for (ip = fip, j = *ip; ip != NULL; ip = (int *) avl_t_next(&t)) {
if (ip != fip)
- pdf_puts(" ");
+ pdf_puts(pdf, " ");
i = *ip;
while (j < i - 1) {
- pdf_puts("0 ");
+ pdf_puts(pdf, "0 ");
j++;
}
j = i;
- pdf_print_charwidth(f, i);
+ pdf_print_charwidth(pdf, f, i);
}
- pdf_puts("]\n");
- pdf_end_obj();
+ pdf_puts(pdf, "]\n");
+ pdf_end_obj(pdf);
}
-/**********************************************************************/
-/*
- * Remark: Font objects from embedded PDF files are never registered
- * into fo_tree; they are individually written out.
- */
-
-static fo_entry *lookup_fo_entry(char *s)
+@ Remark: Font objects from embedded PDF files are never registered
+into |fo_tree|; they are individually written out.
+@c
+fo_entry *lookup_fo_entry(char *s)
{
fo_entry fo;
fm_entry fm;
@@ -434,7 +398,7 @@ static fo_entry *lookup_fo_entry(char *s)
return (fo_entry *) avl_find(fo_tree, &fo);
}
-static void register_fo_entry(fo_entry * fo)
+void register_fo_entry(fo_entry * fo)
{
void **aa;
if (fo_tree == NULL) {
@@ -449,63 +413,65 @@ static void register_fo_entry(fo_entry * fo)
assert(aa != NULL);
}
-/**********************************************************************/
-
-static void write_fontfile(fd_entry * fd)
+@
+@c
+static void write_fontfile(PDF pdf, fd_entry * fd)
{
assert(is_included(fd->fm));
if (is_cidkeyed(fd->fm)) {
if (is_opentype(fd->fm))
- writetype0(fd);
+ writetype0(pdf, fd);
else if (is_truetype(fd->fm))
- writetype2(fd);
+ writetype2(pdf, fd);
else if (is_type1(fd->fm))
- writetype1w(fd);
+ writetype1w(pdf, fd);
else
assert(0);
} else {
if (is_type1(fd->fm))
- writet1(fd);
+ writet1(pdf, fd);
else if (is_truetype(fd->fm))
- writettf(fd);
+ writettf(pdf, fd);
else if (is_opentype(fd->fm))
- writeotf(fd);
+ writeotf(pdf, 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 */
+ fd->ff_objnum = pdf_new_objnum(pdf);
+ pdf_begin_dict(pdf, 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"); */
+ pdf_puts(pdf, "/Subtype /CIDFontType0C\n");
+#if 0
+ else
+ pdf_puts(pdf,"/Subtype /OpenType\n");
+#endif
} else {
if (is_type1(fd->fm))
- pdf_printf("/Length1 %i\n/Length2 %i\n/Length3 %i\n",
+ pdf_printf(pdf, "/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);
+ pdf_printf(pdf, "/Length1 %i\n", (int) ttf_length);
else if (is_opentype(fd->fm))
- pdf_puts("/Subtype /Type1C\n");
+ pdf_puts(pdf, "/Subtype /Type1C\n");
else
assert(0);
}
- pdf_begin_stream();
- fb_flush();
- pdf_end_stream();
+ pdf_begin_stream(pdf);
+ fb_flush(pdf);
+ pdf_end_stream(pdf);
}
-/**********************************************************************/
-
-static void write_fontdescriptor(fd_entry * fd)
+@
+@c
+static void write_fontdescriptor(PDF pdf, fd_entry * fd)
{
static const int std_flags[] = {
- /* indices for << start with 0, but bits start with 1, so the numbers
+ /* 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 */
@@ -529,15 +495,13 @@ static void write_fontdescriptor(fd_entry * fd)
int fd_flags;
assert(fd != NULL && fd->fm != NULL);
- if (is_fontfile(fd->fm))
- write_fontfile(fd); /* this will set fd->ff_found if font file is found */
- if (fd->fn_objnum != 0)
- write_fontname_object(fd);
+ if (is_fontfile(fd->fm) && is_included(fd->fm))
+ write_fontfile(pdf, fd); /* this will set |fd->ff_found| if font file is found */
if (fd->fd_objnum == 0)
- fd->fd_objnum = pdf_new_objnum();
- pdf_begin_dict(fd->fd_objnum, 1);
- pdf_puts("/Type /FontDescriptor\n");
- write_fontname(fd, "FontName");
+ fd->fd_objnum = pdf_new_objnum(pdf);
+ pdf_begin_dict(pdf, fd->fd_objnum, 1);
+ pdf_puts(pdf, "/Type /FontDescriptor\n");
+ write_fontname(pdf, fd, "FontName");
if (fd->fm->fd_flags != FD_FLAGS_NOT_SET_IN_MAPLINE)
fd_flags = (int) fd->fm->fd_flags;
else if (fd->ff_found)
@@ -552,15 +516,15 @@ static void write_fontdescriptor(fd_entry * fd)
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);
+ pdf_printf(pdf, "/Flags %i\n", fd_flags);
+ write_fontmetrics(pdf, fd);
if (is_cidkeyed(fd->fm)) {
if (is_type1(fd->fm))
- pdf_printf("/FontFile3 %i 0 R\n", (int) fd->ff_objnum);
+ pdf_printf(pdf, "/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);
+ pdf_printf(pdf, "/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);
+ pdf_printf(pdf, "/FontFile3 %i 0 R\n", (int) fd->ff_objnum);
else
assert(0);
} else {
@@ -569,35 +533,35 @@ static void write_fontdescriptor(fd_entry * fd)
/* /CharSet is optional; names may appear in any order */
assert(fd->gl_tree != NULL);
avl_t_init(&t, fd->gl_tree);
- pdf_puts("/CharSet (");
+ pdf_puts(pdf, "/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");
+ pdf_printf(pdf, "/%s", glyph);
+ pdf_puts(pdf, ")\n");
}
if (is_type1(fd->fm))
- pdf_printf("/FontFile %i 0 R\n", (int) fd->ff_objnum);
+ pdf_printf(pdf, "/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);
+ pdf_printf(pdf, "/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);
+ pdf_printf(pdf, "/FontFile3 %i 0 R\n", (int) fd->ff_objnum);
else
assert(0);
}
}
- /* TODO: Optional keys for CID fonts.
+ /* TODO: Optional keys for CID fonts.
The most interesting ones are
- /Style << /Panose <12-byte string>>>
+ \.{/Style << /Panose <12-byte string>>>}
and
- /CIDSET <stream>
+ \.{/CIDSET <stream>}
the latter can be used in subsets, to give the included CIDs
as a bitmap on the whole list.
*/
- pdf_end_dict();
+ pdf_end_dict(pdf);
}
-static void write_fontdescriptors(void)
+void write_fontdescriptors(PDF pdf)
{
fd_entry *fd;
struct avl_traverser t;
@@ -606,59 +570,60 @@ static void write_fontdescriptors(void)
avl_t_init(&t, fd_tree);
for (fd = (fd_entry *) avl_t_first(&t, fd_tree); fd != NULL;
fd = (fd_entry *) avl_t_next(&t))
- write_fontdescriptor(fd);
+ write_fontdescriptor(pdf, fd);
}
-/**********************************************************************/
-
-static void write_fontdictionary(fo_entry * fo)
+@
+@c
+void write_fontdictionary(PDF pdf, fo_entry * fo)
{
assert(fo != NULL);
assert(fo->fm != NULL);
- assert(fo->fo_objnum != 0); /* reserved as pdf_font_num(f) in pdftex.web */
+ assert(fo->fo_objnum != 0); /* reserved as |pdf_font_num(f)| elsewhere */
/* write ToUnicode entry if needed */
- if (fixed_gen_tounicode > 0 && fo->fd != NULL) {
+ if (pdf->gen_tounicode > 0 && fo->fd != NULL) {
if (fo->fe != NULL) {
fo->tounicode_objnum =
- write_tounicode(fo->fe->glyph_names, fo->fe->name);
+ write_tounicode(pdf, fo->fe->glyph_names, fo->fe->name);
} else if (is_type1(fo->fm)) {
assert(fo->fd->builtin_glyph_names != NULL);
fo->tounicode_objnum =
- write_tounicode(fo->fd->builtin_glyph_names, fo->fm->tfm_name);
+ write_tounicode(pdf, fo->fd->builtin_glyph_names,
+ fo->fm->tfm_name);
}
}
-
- pdf_begin_dict(fo->fo_objnum, 1);
- pdf_puts("/Type /Font\n");
- pdf_puts("/Subtype /");
+ pdf_begin_dict(pdf, fo->fo_objnum, 1);
+ pdf_puts(pdf, "/Type /Font\n");
+ pdf_puts(pdf, "/Subtype /");
if (is_type1(fo->fm))
- pdf_printf("%s\n", "Type1");
+ pdf_printf(pdf, "%s\n", "Type1");
else if (is_truetype(fo->fm))
- pdf_printf("%s\n", "TrueType");
+ pdf_printf(pdf, "%s\n", "TrueType");
else if (is_opentype(fo->fm))
- pdf_printf("%s\n", "Type1");
+ pdf_printf(pdf, "%s\n", "Type1");
else
assert(0);
assert(fo->fd != NULL && fo->fd->fd_objnum != 0);
- write_fontname(fo->fd, "BaseFont");
- pdf_printf("/FontDescriptor %i 0 R\n", (int) fo->fd->fd_objnum);
+ write_fontname(pdf, fo->fd, "BaseFont");
+ pdf_printf(pdf, "/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",
+ pdf_printf(pdf, "/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)
- pdf_printf("/Encoding %i 0 R\n", (int) fo->fe->fe_objnum);
+ pdf_printf(pdf, "/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_puts("\n");
+ pdf_printf(pdf, "/ToUnicode %i 0 R\n", (int) fo->tounicode_objnum);
+ if (pdf_font_attr(fo->tex_font) != get_nullstr() &&
+ pdf_font_attr(fo->tex_font) != 0) {
+ pdf_print(pdf, pdf_font_attr(fo->tex_font));
+ pdf_puts(pdf, "\n");
}
- pdf_end_dict();
+ pdf_end_dict(pdf);
}
-static void write_fontdictionaries(void)
+void write_fontdictionaries(PDF pdf)
{
fo_entry *fo;
struct avl_traverser t;
@@ -667,46 +632,44 @@ static void write_fontdictionaries(void)
avl_t_init(&t, fo_tree);
for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL;
fo = (fo_entry *) avl_t_next(&t))
- write_fontdictionary(fo);
+ write_fontdictionary(pdf, fo);
}
-/**********************************************************************/
-/*
- * Final flush of all font related stuff by call from
- * @<Output fonts definition@>= in pdftex.web.
- */
+@ Final flush of all font related stuff by call from
+ \.{Output fonts definitions} elsewhere
-void write_fontstuff(void)
+@c
+void write_fontstuff(PDF pdf)
{
- write_fontdescriptors();
- write_fontencodings(); /* see writeenc.c */
- write_fontdictionaries();
+ write_fontdescriptors(pdf);
+ write_fontencodings(pdf); /* see \.{writeenc.w} */
+ write_fontdictionaries(pdf);
}
-/**********************************************************************/
-
-static void create_fontdictionary(fm_entry * fm, integer font_objnum,
- internalfontnumber f)
+@
+@c
+static void create_fontdictionary(PDF pdf, internal_font_number f)
{
fo_entry *fo = new_fo_entry();
- get_char_range(fo, f); /* set fo->first_char and fo->last_char from f */
+ fm_entry *fm = font_map(f);
+ 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 */
+ 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;
+ fo->fo_objnum = pdf_font_num(f);
fo->tex_font = f;
if (is_reencoded(fo->fm)) { /* at least the map entry tells so */
- fo->fe = get_fe_entry(fo->fm->encname); /* returns NULL if .enc file couldn't be opened */
+ 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(pdf); /* 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);
}
}
- fo->tx_tree = mark_chars(fo, fo->tx_tree, f); /* for write_charwidth_array() */
- write_charwidth_array(fo, f);
+ fo->tx_tree = mark_chars(fo, fo->tx_tree, f); /* for |write_charwidth_array| */
+ write_charwidth_array(pdf, fo, f);
if (!is_builtin(fo->fm)) {
if (is_type1(fo->fm)) {
if ((fo->fd = lookup_fontdescriptor(fo)) == NULL) {
@@ -728,13 +691,13 @@ static void create_fontdictionary(fm_entry * fm, integer font_objnum,
/* 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);
+ write_fontdescriptor(pdf, 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);
+ write_fontdescriptor(pdf, 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",
@@ -743,11 +706,11 @@ static void create_fontdictionary(fm_entry * fm, integer font_objnum,
if (is_type1(fo->fm))
register_fo_entry(fo);
else
- write_fontdictionary(fo);
+ write_fontdictionary(pdf, fo);
}
-/**********************************************************************/
-
+@
+@c
static int has_ttf_outlines(fm_entry * fm)
{
FILE *f = fopen(fm->ff_name, "rb");
@@ -764,29 +727,54 @@ static int has_ttf_outlines(fm_entry * fm)
return 0;
}
-void do_pdf_font(integer font_objnum, internalfontnumber f)
+void do_pdf_font(PDF pdf, internal_font_number f)
{
+ int del_file = 0;
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;
+ /* TODO 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_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.
+ rest of the font inclusion mechanism.
*/
- fm = new_fm_entry();
+ fm = font_map(f) = new_fm_entry();
fm->tfm_name = font_name(f); /* or whatever, not a real tfm */
fm->ff_name = font_filename(f); /* the actual file */
+ if (font_psname(f) != NULL)
+ fm->ps_name = font_psname(f); /* the true name */
+ else
+ fm->ps_name = font_fullname(f); /* the true name */
+ if (fm->ff_name
+ && strlen(fm->ff_name) >= 6
+ && strstr(fm->ff_name,
+ ".dfont") == (fm->ff_name + strlen(fm->ff_name) - 6)) {
+ /* In case of a .dfont, we will extract the correct ttf here,
+ and adjust |fm->ff_name| to point to the temporary file.
+ This file will be deleted later. Todo: keep a nicer name
+ somewhere for the terminal message.
+ */
+ char *s = FindResourceTtfFont(fm->ff_name, fm->ps_name);
+ if (s != NULL) {
+ fm->ff_name = s;
+ del_file = 1;
+ } else {
+ pdftex_fail
+ ("writefont.c: The file (%s) does not contain font `%s'",
+ fm->ff_name, fm->ps_name);
+ }
+ }
fm->encname = font_encodingname(f); /* for the CIDSystemInfo */
- fm->ps_name = font_fullname(f); /* the true name */
fm->slant = font_slant(f); /* slant factor */
+ set_slantset(fm);
fm->extend = font_extend(f); /* extension factor */
+ set_extendset(fm);
fm->fd_flags = 4; /* can perhaps be done better */
- fm->in_use = true;
+ set_inuse(fm);
switch (font_format(f)) {
case opentype_format:
@@ -815,47 +803,48 @@ void do_pdf_font(integer font_objnum, internalfontnumber f)
}
}
set_cidkeyed(fm);
- create_cid_fontdictionary(fm, font_objnum, f);
+ create_cid_fontdictionary(pdf, f);
+
+ if (del_file)
+ unlink(fm->ff_name);
} 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);
+ /* by now |font_map(f)|, if any, should have been set via |pdf_init_font()| */
+ if ((fm = font_map(f)) == NULL
+ || (fm->ps_name == NULL && fm->ff_name == NULL))
+ writet3(pdf, f);
else
- create_fontdictionary(fm, font_objnum, f);
+ create_fontdictionary(pdf, f);
}
}
-/**********************************************************************/
-
-
-/*
- The glyph width is included in |glw_entry|, because that width
+@ The glyph width is included in |glw_entry|, because that width
depends on the value it has in the font where it is actually
typeset from, not the font that is the 'owner' of the fd entry.
TODO: It is possible that the user messes with the metric width,
but handling that properly would require access to the 'hmtx' table
at this point in the program.
-*/
-static int comp_glw_entry(const void *pa, const void *pb, void *p)
+@c
+int comp_glw_entry(const void *pa, const void *pb, void *p
+ __attribute__ ((unused)))
{
unsigned short i, j;
- (void) p;
- i = (*(const glw_entry *) pa).id;
- j = (*(const glw_entry *) pb).id;
+
+ i = (unsigned short) (*(const glw_entry *) pa).id;
+ j = (unsigned short) (*(const glw_entry *) pb).id;
cmp_return(i, j);
return 0;
}
-static void create_cid_fontdescriptor(fo_entry * fo, internalfontnumber f)
+void create_cid_fontdescriptor(fo_entry * fo, internal_font_number f)
{
assert(fo != NULL);
assert(fo->fm != NULL);
assert(fo->fd == NULL);
fo->fd = new_fd_entry();
- preset_fontname(fo);
+ preset_fontname(fo, f);
preset_fontmetrics(fo->fd, f);
fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */
fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */
@@ -863,12 +852,12 @@ static void create_cid_fontdescriptor(fo_entry * fo, internalfontnumber f)
assert(fo->fd->gl_tree != NULL);
}
-/*
- The values |font_bc()| and |font_ec()| are potentially large
+
+@ The values |font_bc()| and |font_ec()| are potentially large
character ids, but the strings that are written out use CID
indexes, and those are limited to 16-bit values.
-*/
+@c
static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f)
{
int i, k, l;
@@ -876,11 +865,11 @@ static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f)
void *aa;
for (k = 1; k <= max_font_id(); k++) {
if (k == f || -f == pdf_font_num(k)) {
- l = pdf_font_size(k);
+ l = font_size(k);
for (i = font_bc(k); i <= font_ec(k); i++) {
- if (char_exists(k, i) && char_used(k, i)) {
+ if (quick_char_exists(k, i) && char_used(k, i)) {
j = xtalloc(1, glw_entry);
- j->id = char_index(k, i);
+ j->id = (unsigned) 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);
@@ -894,132 +883,128 @@ static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f)
}
}
-/*
- It is possible to compress the widths array even better, by using the
- alternate 'range' syntax and possibly even using /DW to set
+
+@ It is possible to compress the widths array even better, by using the
+ alternate 'range' syntax and possibly even using /DW to set
a default value.
-
+
There is a some optimization here already: glyphs that are
- not used do not appear in the widths array at all.
+ not used do not appear in the widths array at all.
We have to make sure that we do not output an (incorrect!)
width for a character that exists in the font, but is not used
in typesetting. An enormous negative width is used as sentinel value
-*/
-
-static void write_cid_charwidth_array(fo_entry * fo)
+@c
+static void write_cid_charwidth_array(PDF pdf, 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);
+ fo->cw_objnum = pdf_new_objnum(pdf);
+ pdf_begin_obj(pdf, 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);
+ i = (int) glyph->id;
+ pdf_printf(pdf, "[ %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);
+ pdf_printf(pdf, "] %i [", glyph->id);
j = glyph->wd;
}
if (glyph->id == (unsigned) (i + 1))
- pdf_puts(" ");
+ pdf_puts(pdf, " ");
if (j < 0) {
- pdf_puts("-");
+ pdf_puts(pdf, "-");
j = -j;
}
- /* pdf_print_charwidth(f, i); */
-
- pdf_printf("%i", (j / 10));
+ pdf_printf(pdf, "%i", (j / 10));
if ((j % 10) != 0)
- pdf_printf(".%i", (j % 10));
+ pdf_printf(pdf, ".%i", (j % 10));
- i = glyph->id;
+ i = (int) glyph->id;
}
- pdf_puts("]]\n");
- pdf_end_obj();
+ pdf_puts(pdf, "]]\n");
+ pdf_end_obj(pdf);
}
-
-void create_cid_fontdictionary(fm_entry * fm, integer font_objnum,
- internalfontnumber f)
+static void create_cid_fontdictionary(PDF pdf, internal_font_number f)
{
+ fm_entry *fm = font_map(f);
fo_entry *fo = new_fo_entry();
- get_char_range(fo, f); /* set fo->first_char and fo->last_char from f */
+ get_char_range(fo, f); /* set |fo->first_char| and |fo->last_char| from |f| */
assert(fo->last_char >= fo->first_char);
fo->fm = fm;
- fo->fo_objnum = font_objnum;
+ fo->fo_objnum = pdf_font_num(f);
fo->tex_font = 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);
}
- write_cid_charwidth_array(fo);
- write_fontdescriptor(fo->fd);
+ write_cid_charwidth_array(pdf, fo);
+ write_fontdescriptor(pdf, fo->fd);
- write_cid_fontdictionary(fo, f);
+ write_cid_fontdictionary(pdf, fo, f);
xfree(fo);
}
-void write_cid_fontdictionary(fo_entry * fo, internalfontnumber f)
+@ @c
+void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f)
{
int i;
- fo->tounicode_objnum = write_cid_tounicode(fo, f);
+ fo->tounicode_objnum = write_cid_tounicode(pdf, 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();
- pdf_printf("/DescendantFonts [%i 0 R]\n", i);
+ pdf_begin_dict(pdf, fo->fo_objnum, 1);
+ pdf_puts(pdf, "/Type /Font\n");
+ pdf_puts(pdf, "/Subtype /Type0\n");
+ pdf_puts(pdf, "/Encoding /Identity-H\n");
+ write_fontname(pdf, fo->fd, "BaseFont");
+ i = pdf_new_objnum(pdf);
+ pdf_printf(pdf, "/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);
+ pdf_printf(pdf, "/ToUnicode %i 0 R\n", (int) fo->tounicode_objnum);
- pdf_end_dict();
+ pdf_end_dict(pdf);
- pdf_begin_dict(i, 1);
- pdf_puts("/Type /Font\n");
+ pdf_begin_dict(pdf, i, 1);
+ pdf_puts(pdf, "/Type /Font\n");
if (is_opentype(fo->fm) || is_type1(fo->fm)) {
- pdf_puts("/Subtype /CIDFontType0\n");
+ pdf_puts(pdf, "/Subtype /CIDFontType0\n");
} else {
- pdf_puts("/Subtype /CIDFontType2\n");
- pdf_printf("/CIDToGIDMap /Identity\n");
+ pdf_puts(pdf, "/Subtype /CIDFontType2\n");
+ pdf_printf(pdf, "/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("/CIDSystemInfo <<\n");
- pdf_printf("/Registry (%s)\n",
+ write_fontname(pdf, fo->fd, "BaseFont");
+ pdf_printf(pdf, "/FontDescriptor %i 0 R\n", (int) fo->fd->fd_objnum);
+ pdf_printf(pdf, "/W %i 0 R\n", (int) fo->cw_objnum);
+ pdf_printf(pdf, "/CIDSystemInfo <<\n");
+ pdf_printf(pdf, "/Registry (%s)\n",
(font_cidregistry(f) ? font_cidregistry(f) : "Adobe"));
- pdf_printf("/Ordering (%s)\n",
+ pdf_printf(pdf, "/Ordering (%s)\n",
(font_cidordering(f) ? font_cidordering(f) : "Identity"));
- pdf_printf("/Supplement %u\n", (unsigned int) font_cidsupplement(f));
- pdf_printf(">>\n");
+ pdf_printf(pdf, "/Supplement %u\n", (unsigned int) font_cidsupplement(f));
+ pdf_printf(pdf, ">>\n");
/* I doubt there is anything useful that could be written here */
- /*
+#if 0
if (pdf_font_attr(fo->tex_font) != get_nullstr()) {
pdf_print(pdf_font_attr(fo->tex_font));
- pdf_puts("\n");
+ pdf_puts(pdf,"\n");
}
- */
- pdf_end_dict();
-
+#endif
+ pdf_end_dict(pdf);
}
diff --git a/Build/source/texk/web2c/luatexdir/font/writet1.c b/Build/source/texk/web2c/luatexdir/font/writet1.w
index 01881ccbb52..69ac40bac04 100644
--- a/Build/source/texk/web2c/luatexdir/font/writet1.c
+++ b/Build/source/texk/web2c/luatexdir/font/writet1.w
@@ -1,29 +1,30 @@
-/* writet1.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
+% writet1.w
+%
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 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.
+%
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: writet1.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writet1.w $";
#include "ptexlib.h"
#include <string.h>
-#include "luatex-api.h"
-
-static const char _svn_version[] =
- "$Id: writet1.c 2599 2009-06-25 10:35:26Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/writet1.c $";
#define t1_log(str) if(tracefilenames) tex_printf("%s", str)
#define get_length1() t1_length1 = t1_offset() - t1_save_offset
@@ -31,8 +32,8 @@ static const char _svn_version[] =
#define get_length3() t1_length3 = fixedcontent? t1_offset() - t1_save_offset : 0
#define save_offset() t1_save_offset = t1_offset()
-#define t1_putchar fb_putchar
-#define t1_offset fb_offset
+#define t1_putchar(A) fb_putchar(pdf,(A))
+#define t1_offset() fb_offset(pdf)
#define out_eexec_char t1_putchar
#define end_last_eexec_line() \
@@ -41,17 +42,18 @@ static const char _svn_version[] =
#define embed_all_glyphs(tex_font) fm_cur->all_glyphs
#define extra_charset() fm_cur->charset
#define update_subset_tag() \
- strncpy(fb_array + t1_fontname_offset, fm_cur->subset_tag, 6)
+ strncpy(pdf->fb_array + t1_fontname_offset, fm_cur->subset_tag, 6)
#define fixedcontent false
-integer t1_length1, t1_length2, t1_length3;
-static integer t1_save_offset;
-static integer t1_fontname_offset;
+int t1_length1, t1_length2, t1_length3;
+static int t1_save_offset;
+static int t1_fontname_offset;
static unsigned char *t1_buffer = NULL;
-static integer t1_size = 0;
-static integer t1_curbyte = 0;
+static int t1_size = 0;
+static int t1_curbyte = 0;
+@ @c
#define t1_read_file() \
readbinfile(t1_file,&t1_buffer,&t1_size)
#define t1_close() xfclose(t1_file,cur_file_name)
@@ -69,11 +71,12 @@ static integer t1_curbyte = 0;
#define t1_cleartomark() t1_prefix("cleartomark")
static unsigned char *enc_buffer = NULL;
-static integer enc_size = 0;
-static integer enc_curbyte = 0;
+static int enc_size = 0;
+static int enc_curbyte = 0;
-#define enc_open() \
- (enc_file = fopen((char *)nameoffile+1, FOPEN_RBIN_MODE))
+@ @c
+#define enc_open(a) \
+ (enc_file = fopen((char *)(a), FOPEN_RBIN_MODE))
#define enc_read_file() \
readbinfile(enc_file,&enc_buffer,&enc_size)
#define enc_close() xfclose(enc_file,cur_file_name)
@@ -83,6 +86,7 @@ static integer enc_curbyte = 0;
#define valid_code(c) (c >= 0 && c < 256)
#define fixedcontent false
+@ @c
static const char *standard_glyph_names[256] = {
/* 0x00 */
notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
@@ -140,6 +144,7 @@ static const char *standard_glyph_names[256] = {
"oslash", "oe", "germandbls", notdef, notdef, notdef, notdef
};
+@ @c
static fd_entry *fd_cur;
static char charstringname[] = "/CharStrings";
@@ -149,6 +154,7 @@ enum { ENC_STANDARD, ENC_BUILTIN } t1_encoding;
#define T1_BUF_SIZE 0x10
#define ENC_BUF_SIZE 0x1000
+@ @c
#define CS_HSTEM 1
#define CS_VSTEM 3
#define CS_VMOVETO 4
@@ -180,6 +186,7 @@ enum { ENC_STANDARD, ENC_BUILTIN } t1_encoding;
#define CS_2BYTE_MAX (CS_SETCURRENTPOINT + 1)
#define CS_MAX CS_2BYTE_MAX
+@ @c
typedef unsigned char byte;
typedef struct {
@@ -204,12 +211,14 @@ static unsigned short t1_cslen;
static short t1_lenIV;
static char enc_line[ENC_BUF_SIZE];
-/* define t1_line_ptr, t1_line_array & t1_line_limit */
-typedef char t1_line_entry;
+@ define |t1_line_ptr|, |t1_line_array|, and |t1_line_limit|
+@c
+#define t1_line_entry char
define_array(t1_line);
-/* define t1_buf_ptr, t1_buf_array & t1_buf_limit */
-typedef char t1_buf_entry;
+@ define |t1_buf_ptr|, |t1_buf_array|, and |t1_buf_limit|
+@c
+#define t1_buf_entry char
define_array(t1_buf);
static int cs_start;
@@ -222,9 +231,10 @@ static cs_entry *subr_tab;
static char *subr_array_start, *subr_array_end;
static int subr_max, subr_size, subr_size_pos;
-/* This list contains the begin/end tokens commonly used in the */
-/* /Subrs array of a Type 1 font. */
+@ This list contains the begin/end tokens commonly used in the
+/Subrs array of a Type 1 font.
+@c
static const char *cs_token_pairs_list[][2] = {
{" RD", "NP"},
{" -|", "|"},
@@ -232,6 +242,8 @@ static const char *cs_token_pairs_list[][2] = {
{" -|", "noaccess put"},
{NULL, NULL}
};
+
+@ @c
static const char **cs_token_pair;
static boolean t1_pfa, t1_cs, t1_scan, t1_eexec_encrypt, t1_synthetic;
@@ -241,16 +253,17 @@ static int last_hexbyte;
static FILE *t1_file;
static FILE *enc_file;
+@ @c
static void enc_getline(void)
{
char *p;
- int c;
+ char c;
restart:
if (enc_eof())
pdftex_fail("unexpected end of file");
p = enc_line;
do {
- c = enc_getchar();
+ c = (char) enc_getchar();
append_char_to_buf(c, p, enc_line, ENC_BUF_SIZE);
}
while (c != 10 && !enc_eof());
@@ -259,56 +272,34 @@ static void enc_getline(void)
goto restart;
}
-/* read encoding from .enc file, return glyph_names array, or pdffail() */
-
+@ read encoding from .enc file, return |glyph_names array|, or |pdffail()|
+@c
char **load_enc_file(char *enc_name)
{
int callback_id = 0;
int file_opened = 0;
- char *ftemp = NULL;
+
char buf[ENC_BUF_SIZE], *p, *r;
int i, names_count;
char **glyph_names;
- char *tempname;
- set_cur_file_name(enc_name);
- callback_id = callback_defined(find_enc_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 {
- pdftex_fail("cannot find encoding file for reading");
- }
- }
- } else {
- ftemp = kpse_find_file((char *) (nameoffile + 1), kpse_enc_format, 0);
- if (ftemp == NULL) {
- pdftex_fail("cannot find encoding file for reading");
- } else {
- free(nameoffile);
- namelength = strlen(ftemp);
- nameoffile = xmalloc(namelength + 2);
- strcpy((char *) (nameoffile + 1), ftemp);
- free(ftemp);
- }
+
+ cur_file_name = luatex_find_file(enc_name, find_enc_file_callback);
+
+ if (cur_file_name == NULL) {
+ pdftex_fail("cannot find encoding file for reading");
}
callback_id = callback_defined(read_enc_file_callback);
enc_curbyte = 0;
enc_size = 0;
if (callback_id > 0) {
- if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1),
+ if (run_callback(callback_id, "S->bSd", cur_file_name,
&file_opened, &enc_buffer, &enc_size)) {
if ((!file_opened) || enc_size == 0) {
pdftex_fail("cannot open encoding file for reading");
}
}
} else {
- if (!enc_open()) {
+ if (!enc_open(cur_file_name)) {
pdftex_fail("cannot open encoding file for reading");
}
enc_read_file();
@@ -319,9 +310,6 @@ char **load_enc_file(char *enc_name)
glyph_names[i] = (char *) notdef;
t1_log("{");
- tempname = xmalloc(namelength + 2);
- strcpy(tempname, (char *) (nameoffile + 1));
- set_cur_file_name(tempname);
t1_log(cur_file_name);
enc_getline();
if (*enc_line != '/' || (r = strchr(enc_line, '[')) == NULL) {
@@ -364,8 +352,8 @@ char **load_enc_file(char *enc_name)
return glyph_names;
}
-#if 0 /* unused */
-static void free_glyph_names(char **glyph_names)
+@ @c
+void free_glyph_names(char **glyph_names)
{
int i;
assert(glyph_names != NULL);
@@ -374,7 +362,6 @@ static void free_glyph_names(char **glyph_names)
xfree(glyph_names[i]);
xfree(glyph_names);
}
-#endif
static void t1_check_pfa(void)
@@ -425,32 +412,33 @@ static byte edecrypt(byte cipher)
byte plain;
if (t1_pfa) {
while (cipher == 10 || cipher == 13)
- cipher = t1_getbyte();
- last_hexbyte = cipher = (hexval(cipher) << 4) + hexval(t1_getbyte());
+ cipher = (byte) t1_getbyte();
+ last_hexbyte = cipher =
+ (byte) ((hexval(cipher) << 4) + hexval(t1_getbyte()));
}
- plain = (cipher ^ (t1_dr >> 8));
- t1_dr = (cipher + t1_dr) * t1_c1 + t1_c2;
+ plain = (byte) (cipher ^ (t1_dr >> 8));
+ t1_dr = (unsigned short) ((cipher + t1_dr) * t1_c1 + t1_c2);
return plain;
}
static byte cdecrypt(byte cipher, unsigned short *cr)
{
- const byte plain = (cipher ^ (*cr >> 8));
- *cr = (cipher + *cr) * t1_c1 + t1_c2;
+ const byte plain = (byte) (cipher ^ (*cr >> 8));
+ *cr = (unsigned short) ((cipher + *cr) * t1_c1 + t1_c2);
return plain;
}
static byte eencrypt(byte plain)
{
- const byte cipher = (plain ^ (t1_er >> 8));
- t1_er = (cipher + t1_er) * t1_c1 + t1_c2;
+ const byte cipher = (byte) (plain ^ (t1_er >> 8));
+ t1_er = (unsigned short) ((cipher + t1_er) * t1_c1 + t1_c2);
return cipher;
}
static byte cencrypt(byte plain, unsigned short *cr)
{
- const byte cipher = (plain ^ (*cr >> 8));
- *cr = (cipher + *cr) * t1_c1 + t1_c2;
+ const byte cipher = (byte) (plain ^ (*cr >> 8));
+ *cr = (unsigned short) ((cipher + *cr) * t1_c1 + t1_c2);
return cipher;
}
@@ -493,12 +481,13 @@ static boolean str_suffix(const char *begin_buf, const char *end_buf,
return s2 < s;
}
+@ @c
static void t1_getline(void)
{
int c, l, eexec_scan;
char *p;
static const char eexec_str[] = "currentfile eexec";
- static int eexec_len = 17; /* strlen(eexec_str) */
+ static int eexec_len = 17; /* |strlen(eexec_str)| */
restart:
if (t1_eof())
pdftex_fail("unexpected end of file");
@@ -511,73 +500,81 @@ static void t1_getline(void)
goto exit;
while (!t1_eof()) {
if (t1_in_eexec == 1)
- c = edecrypt(c);
+ c = edecrypt((byte) c);
alloc_array(t1_line, 1, T1_BUF_SIZE);
- append_char_to_buf(c, t1_line_ptr, t1_line_array, t1_line_limit);
+ {
+ char cc = (char) c;
+ append_char_to_buf(cc, t1_line_ptr, t1_line_array, t1_line_limit);
+ }
if (t1_in_eexec == 0 && eexec_scan >= 0 && eexec_scan < eexec_len) {
if (t1_line_array[eexec_scan] == eexec_str[eexec_scan])
eexec_scan++;
else
eexec_scan = -1;
}
- if (c == 10 || (t1_pfa && eexec_scan == eexec_len && c == 32))
+ if (c == 10 || c == 13
+ || (t1_pfa && eexec_scan == eexec_len && c == 32)) {
break;
+ }
if (t1_cs && t1_cslen == 0 && (t1_line_ptr - t1_line_array > 4) &&
(t1_suffix(" RD ") || t1_suffix(" -| "))) {
p = t1_line_ptr - 5;
while (*p != ' ')
p--;
- t1_cslen = l = t1_scan_num(p + 1, 0);
- cs_start = t1_line_ptr - t1_line_array; /* cs_start is an index now */
+ l = (int) t1_scan_num(p + 1, 0);
+ t1_cslen = (unsigned short) l;
+ cs_start = (int) (t1_line_ptr - t1_line_array); /* |cs_start| is an index now */
alloc_array(t1_line, l, T1_BUF_SIZE);
while (l-- > 0)
- *t1_line_ptr++ = edecrypt(t1_getbyte());
+ *t1_line_ptr++ = (t1_line_entry) edecrypt((byte) t1_getbyte());
}
c = t1_getbyte();
}
- alloc_array(t1_line, 2, T1_BUF_SIZE); /* append_eol can append 2 chars */
+ alloc_array(t1_line, 2, T1_BUF_SIZE); /* |append_eol| can append 2 chars */
append_eol(t1_line_ptr, t1_line_array, t1_line_limit);
if (t1_line_ptr - t1_line_array < 2)
goto restart;
if (eexec_scan == eexec_len)
t1_in_eexec = 1;
exit:
- /* ensure that t1_buf_array has as much room as t1_line_array */
+ /* ensure that |t1_buf_array| has as much room as |t1_line_array| */
t1_buf_ptr = t1_buf_array;
alloc_array(t1_buf, t1_line_limit, t1_line_limit);
}
-static void t1_putline(void)
+@ @c
+static void t1_putline(PDF pdf)
{
char *p = t1_line_array;
if (t1_line_ptr - t1_line_array <= 1)
return;
if (t1_eexec_encrypt) {
while (p < t1_line_ptr)
- t1_putchar(eencrypt(*p++));
+ t1_putchar((eight_bits) eencrypt((byte) * p++));
} else
while (p < t1_line_ptr)
- t1_putchar(*p++);
+ t1_putchar((eight_bits) * p++);
}
-static void t1_puts(const char *s)
+static void t1_puts(PDF pdf, const char *s)
{
if (s != t1_line_array)
strcpy(t1_line_array, s);
t1_line_ptr = strend(t1_line_array);
- t1_putline();
+ t1_putline(pdf);
}
-__attribute__ ((format(printf, 1, 2)))
-static void t1_printf(const char *fmt, ...)
+__attribute__ ((format(printf, 2, 3)))
+static void t1_printf(PDF pdf, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsprintf(t1_line_array, fmt, args);
- t1_puts(t1_line_array);
+ t1_puts(pdf, t1_line_array);
va_end(args);
}
+@ @c
static void t1_init_params(const char *open_name_prefix)
{
t1_log(open_name_prefix);
@@ -607,14 +604,15 @@ static void t1_check_block_len(boolean decrypt)
return;
c = t1_getbyte();
if (decrypt)
- c = edecrypt(c);
- l = t1_block_length;
+ c = edecrypt((byte) c);
+ l = (int) t1_block_length;
if (!(l == 0 && (c == 10 || c == 13))) {
pdftex_fail("%i bytes more than expected were ignored", l + 1);
}
}
-static void t1_start_eexec(void)
+@ @c
+static void t1_start_eexec(PDF pdf)
{
int i;
assert(is_included(fd_cur->fm));
@@ -624,14 +622,14 @@ static void t1_start_eexec(void)
if (!t1_pfa)
t1_check_block_len(false);
for (t1_line_ptr = t1_line_array, i = 0; i < 4; i++) {
- edecrypt(t1_getbyte());
+ edecrypt((byte) t1_getbyte());
*t1_line_ptr++ = 0;
}
t1_eexec_encrypt = true;
- t1_putline(); /* to put the first four bytes */
+ t1_putline(pdf); /* to put the first four bytes */
}
-static void t1_stop_eexec(void)
+static void t1_stop_eexec(PDF pdf)
{
int c;
assert(is_included(fd_cur->fm));
@@ -641,10 +639,10 @@ static void t1_stop_eexec(void)
if (!t1_pfa)
t1_check_block_len(true);
else {
- c = edecrypt(t1_getbyte());
+ c = edecrypt((byte) t1_getbyte());
if (!(c == 10 || c == 13)) {
if (last_hexbyte == 0)
- t1_puts("00");
+ t1_puts(pdf, "00");
else
pdftex_fail("unexpected data after eexec");
}
@@ -653,17 +651,19 @@ static void t1_stop_eexec(void)
t1_in_eexec = 2;
}
-/* macros for various transforms; currently only slant and extend are used */
-
-#define do_xshift(x,a) {x[4]+=a;}
-#define do_yshift(x,a) {x[5]+=a;}
-#define do_xscale(x,a) {x[0]*=a; x[2]*=a; x[4]*=a;}
-#define do_yscale(x,a) {x[1]*=a; x[3]*=a; x[5]*=a;}
-#define do_extend(x,a) {do_xscale(x,a);}
-#define do_scale(x,a) {do_xscale(x,a); do_yscale(x,a);}
-#define do_slant(x,a) {x[0]+=x[1]*(a); x[2]+=x[3]*(a); x[4]+=x[5]*(a);}
-#define do_shear(x,a) {x[1]+=x[0]*(a); x[3]+=x[2]*(a); x[5]+=x[4]*(a);}
-#define do_rotate(x,a) \
+@ macros for various transforms; unused, left for reference
+
+@c
+#ifdef T1TRANSFORMMACROS
+# define do_xshift(x,a) {x[4]+=a;}
+# define do_yshift(x,a) {x[5]+=a;}
+# define do_xscale(x,a) {x[0]*=a; x[2]*=a; x[4]*=a;}
+# define do_yscale(x,a) {x[1]*=a; x[3]*=a; x[5]*=a;}
+# define do_extend(x,a) {do_xscale(x,a);}
+# define do_scale(x,a) {do_xscale(x,a); do_yscale(x,a);}
+# define do_slant(x,a) {x[0]+=x[1]*(a); x[2]+=x[3]*(a); x[4]+=x[5]*(a);}
+# define do_shear(x,a) {x[1]+=x[0]*(a); x[3]+=x[2]*(a); x[5]+=x[4]*(a);}
+# define do_rotate(x,a) \
{float t, u=cos(a), v=sin(a); \
t =x[0]*u+x[1]*-v; \
x[1] =x[0]*v+x[1]* u; x[0]=t; \
@@ -671,121 +671,31 @@ static void t1_stop_eexec(void)
x[3] =x[2]*v+x[3]* u; x[2]=t; \
t =x[4]*u+x[5]*-v; \
x[5] =x[4]*v+x[5]* u; x[4]=t;}
+#endif
-static void t1_modify_fm(void)
-{
- /*
- * font matrix is given as six numbers a0..a5, which stands for the matrix
- *
- * a0 a1 0
- * M = a2 a3 0
- * a4 a5 1
- *
- * ExtendFont is given as
- *
- * e 0 0
- * E = 0 1 0
- * 0 0 1
- *
- * SlantFont is given as
- *
- * 1 0 0
- * S = s 1 0
- * 0 0 1
- *
- * The slant transform must be done _before_ the extend transform
- * for compatibility!
- */
- float a[6];
- int i, c;
- char *p, *q, *r;
- if ((p = strchr(t1_line_array, '[')) == 0)
- if ((p = strchr(t1_line_array, '{')) == 0) {
- remove_eol(p, t1_line_array);
- pdftex_fail("FontMatrix: an array expected: `%s'", t1_line_array);
- }
- c = *p++; /* save the character '[' resp. '{' */
- strncpy(t1_buf_array, t1_line_array, (size_t) (p - t1_line_array));
- r = t1_buf_array + (p - t1_line_array);
- for (i = 0; i < 6; i++) {
- a[i] = t1_scan_num(p, &q);
- p = q;
- }
- if (fm_slant(fd_cur->fm) != 0)
- do_slant(a, fm_slant(fd_cur->fm) * 1E-3);
- if (fm_extend(fd_cur->fm) != 0)
- do_extend(a, fm_extend(fd_cur->fm) * 1E-3);
- for (i = 0; i < 6; i++) {
- sprintf(r, "%g ", a[i]);
- r = strend(r);
- }
- if (c == '[') {
- while (*p != ']' && *p != 0)
- p++;
- } else {
- while (*p != '}' && *p != 0)
- p++;
- }
- if (*p == 0) {
- remove_eol(p, t1_line_array);
- pdftex_fail
- ("FontMatrix: cannot find the corresponding character to '%c': `%s'",
- c, t1_line_array);
- }
- strcpy(r, p);
- strcpy(t1_line_array, t1_buf_array);
- t1_line_ptr = eol(t1_line_array);
-}
-
-static void t1_modify_italic(void)
-{
- float a;
- char *p, *r;
- if (fm_slant(fd_cur->fm) == 0)
- return;
- p = strchr(t1_line_array, ' ');
- strncpy(t1_buf_array, t1_line_array, (size_t) (p - t1_line_array + 1));
- a = t1_scan_num(p + 1, &r);
- a -= atan(fm_slant(fd_cur->fm) * 1E-3) * (180 / M_PI);
- sprintf(t1_buf_array + (p - t1_line_array + 1), "%g", a);
- strcpy(strend(t1_buf_array), r);
- strcpy(t1_line_array, t1_buf_array);
- t1_line_ptr = eol(t1_line_array);
- fd_cur->font_dim[ITALIC_ANGLE_CODE].val = round(a);
- fd_cur->font_dim[ITALIC_ANGLE_CODE].set = true;
-}
-
-static void t1_scan_keys(void)
+@ @c
+static void t1_scan_keys(PDF pdf)
{
int i, k;
char *p, *q, *r;
const key_entry *key;
- if (fm_extend(fd_cur->fm) != 0 || fm_slant(fd_cur->fm) != 0) {
- if (t1_prefix("/FontMatrix")) {
- t1_modify_fm();
- return;
- }
- if (t1_prefix("/ItalicAngle")) {
- t1_modify_italic();
- return;
- }
- }
if (t1_prefix("/FontType")) {
p = t1_line_array + strlen("FontType") + 1;
- if ((i = t1_scan_num(p, 0)) != 1)
+ if ((i = (int) t1_scan_num(p, 0)) != 1)
pdftex_fail("Type%d fonts unsupported by pdfTeX", i);
return;
}
- for (key = font_key; key - font_key < FONT_KEYS_NUM; key++) {
- if (key->t1name[0] != '\0' &&
- str_prefix(t1_line_array + 1, key->t1name))
+ for (key = (const key_entry *) font_key; key - font_key < FONT_KEYS_NUM;
+ key++) {
+ if (key->t1name[0] != '\0'
+ && str_prefix(t1_line_array + 1, key->t1name))
break;
}
if (key - font_key == FONT_KEYS_NUM)
return;
p = t1_line_array + strlen(key->t1name) + 1;
skip(p, ' ');
- if ((k = key - font_key) == FONTNAME_CODE) {
+ if ((k = (int) (key - font_key)) == FONTNAME_CODE) {
if (*p != '/') {
remove_eol(p, t1_line_array);
pdftex_fail("a name expected: `%s'", t1_line_array);
@@ -793,54 +703,47 @@ static void t1_scan_keys(void)
r = ++p; /* skip the slash */
for (q = t1_buf_array; *p != ' ' && *p != 10; *q++ = *p++);
*q = 0;
- if (fm_slant(fd_cur->fm) != 0) {
- sprintf(q, "-Slant_%i", (int) fm_slant(fd_cur->fm));
- q = strend(q);
- }
- if (fm_extend(fd_cur->fm) != 0) {
- sprintf(q, "-Extend_%i", (int) fm_extend(fd_cur->fm));
- }
xfree(fd_cur->fontname);
fd_cur->fontname = xstrdup(t1_buf_array);
- /* at this moment we cannot call make_subset_tag() yet, as the encoding
- * is not read; thus we mark the offset of the subset tag and write it
- * later */
+ /* at this moment we cannot call |make_subset_tag()| yet, as the encoding
+ is not read; thus we mark the offset of the subset tag and write it
+ later */
if (is_subsetted(fd_cur->fm)) {
assert(is_included(fd_cur->fm));
- t1_fontname_offset = t1_offset() + (r - t1_line_array);
+ t1_fontname_offset = (int) (t1_offset() + (r - t1_line_array));
strcpy(t1_buf_array, p);
sprintf(r, "ABCDEF+%s%s", fd_cur->fontname, t1_buf_array);
t1_line_ptr = eol(r);
}
return;
}
- if ((k == STEMV_CODE || k == FONTBBOX1_CODE)
- && (*p == '[' || *p == '{'))
+ if ((k == STEMV_CODE || k == FONTBBOX1_CODE) && (*p == '[' || *p == '{'))
p++;
if (k == FONTBBOX1_CODE) {
for (i = 0; i < 4; i++, k++) {
- fd_cur->font_dim[k].val = t1_scan_num(p, &r);
+ fd_cur->font_dim[k].val = (int) t1_scan_num(p, &r);
fd_cur->font_dim[k].set = true;
p = r;
}
return;
}
- fd_cur->font_dim[k].val = t1_scan_num(p, 0);
+ fd_cur->font_dim[k].val = (int) t1_scan_num(p, 0);
fd_cur->font_dim[k].set = true;
}
-static void t1_scan_param(void)
+@ @c
+static void t1_scan_param(PDF pdf)
{
static const char *lenIV = "/lenIV";
if (!t1_scan || *t1_line_array != '/')
return;
if (t1_prefix(lenIV)) {
- t1_lenIV = t1_scan_num(t1_line_array + strlen(lenIV), 0);
+ t1_lenIV = (short) t1_scan_num(t1_line_array + strlen(lenIV), 0);
if (t1_lenIV < 0)
pdftex_fail("negative value of lenIV is not supported");
return;
}
- t1_scan_keys();
+ t1_scan_keys(pdf);
}
static void copy_glyph_names(char **glyph_names, int a, int b)
@@ -854,13 +757,14 @@ static void copy_glyph_names(char **glyph_names, int a, int b)
}
}
-/* read encoding from Type1 font file, return glyph_names array, or pdffail() */
+@ read encoding from Type1 font file, return |glyph_names| array, or |pdffail()|
-static char **t1_builtin_enc(void)
+@c
+char **t1_builtin_enc(void)
{
int i, a, b, c, counter = 0;
char *r, *p, **glyph_names;
- /* At this moment "/Encoding" is the prefix of t1_line_array */
+ /* At this moment \.{/Encoding} is the prefix of |t1_line_array| */
glyph_names = xtalloc(256, char *);
for (i = 0; i < 256; i++)
glyph_names[i] = (char *) notdef;
@@ -878,20 +782,21 @@ static char **t1_builtin_enc(void)
("cannot subset font (unknown predefined encoding `%s')",
t1_buf_array);
}
- /* At this moment "/Encoding" is the prefix of t1_line_array, and the encoding is
- * not a predefined encoding.
- *
- * We have two possible forms of Encoding vector. The first case is
- *
- * /Encoding [/a /b /c...] readonly def
- *
- * and the second case can look like
- *
- * /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for
- * dup 0 /x put
- * dup 1 /y put
- * ...
- * readonly def
+ /* At this moment \.{/Encoding} is the prefix of |t1_line_array|, and the encoding is
+ not a predefined encoding.
+
+ We have two possible forms of Encoding vector. The first case is
+
+ \.{/Encoding [/a /b /c...] readonly def}
+
+ and the second case can look like
+
+ {\obeylines
+ \.{/Encoding 256 array 0 1 255 {1 index exch /.notdef put} for}
+ \.{dup 0 /x put}
+ \.{dup 1 /y put}
+ \.{...}
+ \.{readonly def}}
*/
t1_encoding = ENC_BUILTIN;
if (t1_prefix("/Encoding [") || t1_prefix("/Encoding[")) { /* the first case */
@@ -911,8 +816,7 @@ static char **t1_builtin_enc(void)
counter++;
}
if (*r != 10 && *r != '%') {
- if (str_prefix(r, "] def")
- || str_prefix(r, "] readonly def"))
+ if (str_prefix(r, "] def") || str_prefix(r, "] readonly def"))
break;
else {
remove_eol(r, t1_line_array);
@@ -932,7 +836,7 @@ static char **t1_builtin_enc(void)
p = t1_line_array;
}
/*
- check for `dup <index> <glyph> put'
+ check for \.{dup <index> <glyph> put}
*/
if (sscanf(p, "dup %i%256s put", &i, t1_buf_array) == 2 &&
*t1_buf_array == '/' && valid_code(i)) {
@@ -942,7 +846,7 @@ static char **t1_builtin_enc(void)
skip(p, ' ');
}
/*
- check for `dup dup <to> exch <from> get put'
+ check for \.{dup dup <to> exch <from> get put}
*/
else if (sscanf(p, "dup dup %i exch %i get put", &b, &a) == 2
&& valid_code(a) && valid_code(b)) {
@@ -951,7 +855,7 @@ static char **t1_builtin_enc(void)
skip(p, ' ');
}
/*
- check for `dup dup <from> <size> getinterval <to> exch putinterval'
+ check for \.{dup dup <from> <size> getinterval <to> exch putinterval}
*/
else if (sscanf
(p, "dup dup %i %i getinterval %i exch putinterval",
@@ -963,7 +867,7 @@ static char **t1_builtin_enc(void)
skip(p, ' ');
}
/*
- check for `def' or `readonly def'
+ check for \.{def} or \.{readonly def}
*/
else if ((p == t1_line_array || (p > t1_line_array && p[-1] == ' '))
&& strcmp(p, "def\n") == 0)
@@ -982,92 +886,92 @@ static char **t1_builtin_enc(void)
}
-static void t1_check_end(void)
+@
+@c
+static void t1_check_end(PDF pdf)
{
if (t1_eof())
return;
t1_getline();
if (t1_prefix("{restore}"))
- t1_putline();
+ t1_putline(pdf);
}
+@
+@c
static boolean t1_open_fontfile(const char *open_name_prefix)
{
+ ff_entry *ff;
int callback_id = 0;
int file_opened = 0;
- char *ftemp = NULL;
- ff_entry *ff;
- ff = check_ff_exist(fd_cur->fm->ff_name, is_truetype(fd_cur->fm));
t1_curbyte = 0;
t1_size = 0;
- if (ff->ff_path != NULL) {
- callback_id = callback_defined(find_type1_file_callback);
- if (callback_id > 0) {
- if (run_callback(callback_id, "S->S", ff->ff_path, &ftemp)) {
- if (ftemp != NULL && strlen(ftemp)) {
- strcpy(ff->ff_path, ftemp);
- }
- }
- }
- callback_id = callback_defined(read_type1_file_callback);
- if (callback_id > 0) {
- if (run_callback(callback_id, "S->bSd", ff->ff_path,
- &file_opened, &t1_buffer, &t1_size)
- && file_opened && t1_size > 0) {
- cur_file_name = ff->ff_path;
- } else {
- set_cur_file_name(fd_cur->fm->ff_name);
- pdftex_warn("cannot open Type 1 font file for reading");
- return false;
- }
- } else {
- t1_file = xfopen(cur_file_name = ff->ff_path, FOPEN_RBIN_MODE);
- t1_read_file();
- t1_close();
+ ff = check_ff_exist(fd_cur->fm->ff_name, is_truetype(fd_cur->fm));
+ if (ff->ff_path == NULL) {
+ pdftex_fail("cannot open Type 1 font file for reading (%s)",
+ fd_cur->fm->ff_name);
+ return false;
+ }
+ cur_file_name = luatex_find_file(ff->ff_path, find_type1_file_callback);
+ if (cur_file_name == NULL) {
+ pdftex_fail("cannot open Type 1 font file for reading (%s)",
+ ff->ff_path);
+ return false;
+ }
+ callback_id = callback_defined(read_type1_file_callback);
+ if (callback_id > 0) {
+ if (!run_callback(callback_id, "S->bSd", cur_file_name,
+ &file_opened, &t1_buffer, &t1_size)
+ && file_opened && t1_size > 0) {
+ pdftex_warn("cannot open Type 1 font file for reading (%s)",
+ cur_file_name);
+ return false;
}
- recorder_record_input(ff->ff_path);
} else {
- set_cur_file_name(fd_cur->fm->ff_name);
- pdftex_fail("cannot open Type 1 font file for reading");
- return false;
+ t1_file = xfopen(cur_file_name, FOPEN_RBIN_MODE);
+ t1_read_file();
+ t1_close();
}
+ recorder_record_input(cur_file_name);
t1_init_params(open_name_prefix);
return true;
}
-static void t1_include(void)
+static void t1_include(PDF pdf)
{
do {
t1_getline();
- t1_scan_param();
- t1_putline();
+ t1_scan_param(pdf);
+ t1_putline(pdf);
}
while (t1_in_eexec == 0);
- t1_start_eexec();
+ t1_start_eexec(pdf);
do {
t1_getline();
- t1_scan_param();
- t1_putline();
+ t1_scan_param(pdf);
+ t1_putline(pdf);
}
while (!(t1_charstrings() || t1_subrs()));
t1_cs = true;
do {
t1_getline();
- t1_putline();
+ t1_putline(pdf);
}
while (!t1_end_eexec());
- t1_stop_eexec();
+ t1_stop_eexec(pdf);
if (fixedcontent) { /* copy 512 zeros (not needed for PDF) */
do {
t1_getline();
- t1_putline();
+ t1_putline(pdf);
}
while (!t1_cleartomark());
- t1_check_end(); /* write "{restore}if" if found */
+ t1_check_end(pdf); /* write "{restore}if" if found */
}
get_length3();
}
+@
+@c
#define check_subr(subr) \
if (subr >= subr_size || subr < 0) \
pdftex_fail("Subrs array: entry index out of range (%i)", subr);
@@ -1090,7 +994,7 @@ static void cs_store(boolean is_subr)
*t1_buf_ptr++ = *p++);
*t1_buf_ptr = 0;
if (is_subr) {
- subr = t1_scan_num(p + 1, 0);
+ subr = (int) t1_scan_num(p + 1, 0);
check_subr(subr);
ptr = subr_tab + subr;
} else {
@@ -1103,16 +1007,16 @@ static void cs_store(boolean is_subr)
else
ptr->name = xstrdup(t1_buf_array + 1);
}
- /* copy " RD " + cs data to t1_buf_array */
+ /* copy |" RD " + cs data| to |t1_buf_array| */
memcpy(t1_buf_array, t1_line_array + cs_start - 4,
(unsigned) (t1_cslen + 4));
- /* copy the end of cs data to t1_buf_array */
+ /* copy the end of cs data to |t1_buf_array| */
for (p = t1_line_array + cs_start + t1_cslen, t1_buf_ptr =
t1_buf_array + t1_cslen + 4; *p != 10; *t1_buf_ptr++ = *p++);
*t1_buf_ptr++ = 10;
if (is_subr && cs_token_pair == NULL)
cs_token_pair = check_cs_token_pair();
- ptr->len = t1_buf_ptr - t1_buf_array;
+ ptr->len = (unsigned short) (t1_buf_ptr - t1_buf_array);
ptr->cslen = t1_cslen;
xfree(ptr->data); /* mem leak? */
ptr->data = xtalloc(ptr->len, byte);
@@ -1120,12 +1024,14 @@ static void cs_store(boolean is_subr)
ptr->valid = true;
}
+@
+@c
#define store_subr() cs_store(true)
#define store_cs() cs_store(false)
#define CC_STACK_SIZE 24
-static integer cc_stack[CC_STACK_SIZE], *stack_ptr = cc_stack;
+static int cc_stack[CC_STACK_SIZE], *stack_ptr = cc_stack;
static cc_entry cc_tab[CS_MAX];
static boolean is_cc_init = false;
@@ -1141,22 +1047,6 @@ static boolean is_cc_init = false;
goto cs_error; \
}
-/*
-static integer cc_get(integer index)
-{
- if (index < 0) {
- if (stack_ptr + index < cc_stack )
- stack_error(stack_ptr - cc_stack + index);
- return *(stack_ptr + index);
- }
- else {
- if (cc_stack + index >= stack_ptr)
- stack_error(index);
- return cc_stack[index];
- }
-}
-*/
-
#define cc_get(N) ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N)))
#define cc_push(V) *stack_ptr++ = V
@@ -1185,9 +1075,9 @@ static void cc_init(void)
set_cc(CS_CLOSEPATH, false, 0, true);
set_cc(CS_CALLSUBR, false, 1, false);
set_cc(CS_RETURN, false, 0, false);
- /*
+#if 0
set_cc(CS_ESCAPE, false, 0, false);
- */
+#endif
set_cc(CS_HSBW, true, 2, true);
set_cc(CS_ENDCHAR, false, 0, true);
set_cc(CS_RMOVETO, true, 2, true);
@@ -1206,12 +1096,14 @@ static void cc_init(void)
is_cc_init = true;
}
+@
+@c
#define cs_getchar() cdecrypt(*data++, &cr)
#define mark_subr(n) cs_mark(0, n)
#define mark_cs(s) cs_mark(s, 0)
-__attribute__ ((format(printf, 3, 4)))
+__attribute__ ((noreturn, format(printf, 3, 4)))
static void cs_fail(const char *cs_name, int subr, const char *fmt, ...)
{
char buf[SMALL_BUF_SIZE];
@@ -1225,7 +1117,8 @@ static void cs_fail(const char *cs_name, int subr, const char *fmt, ...)
pdftex_fail("CharString (/%s): %s", cs_name, buf);
}
-/* fix a return-less subr by appending CS_RETURN */
+@ fix a return-less subr by appending |CS_RETURN|
+@c
static void append_cs_return(cs_entry * ptr)
{
unsigned short cr;
@@ -1233,7 +1126,7 @@ static void append_cs_return(cs_entry * ptr)
byte *p, *q, *data, *new_data;
assert(ptr != NULL && ptr->valid && ptr->used);
- /* decrypt the cs data to t1_buf_array, append CS_RETURN */
+ /* decrypt the cs data to |t1_buf_array|, append |CS_RETURN| */
p = (byte *) t1_buf_array;
data = ptr->data + 4;
cr = 4330;
@@ -1241,32 +1134,34 @@ static void append_cs_return(cs_entry * ptr)
*p++ = cs_getchar();
*p = CS_RETURN;
- /* encrypt the new cs data to new_data */
- new_data = xtalloc(ptr->len + 1, byte);
+ /* encrypt the new cs data to |new_data| */
+ new_data = xtalloc((unsigned) (ptr->len + 1), byte);
memcpy(new_data, ptr->data, 4);
p = new_data + 4;
q = (byte *) t1_buf_array;
cr = 4330;
for (i = 0; i < ptr->cslen + 1; i++)
*p++ = cencrypt(*q++, &cr);
- memcpy(p, ptr->data + 4 + ptr->cslen, ptr->len - ptr->cslen - 4);
+ memcpy(p, ptr->data + 4 + ptr->cslen, (size_t) (ptr->len - ptr->cslen - 4));
- /* update *ptr */
+ /* update |*ptr| */
xfree(ptr->data);
ptr->data = new_data;
ptr->len++;
ptr->cslen++;
}
+@
+@c
static void cs_mark(const char *cs_name, int subr)
{
byte *data;
int i, b, cs_len;
int last_cmd = 0;
- integer a, a1, a2;
+ int a, a1, a2;
unsigned short cr;
- static integer lastargOtherSubr3 = 3; /* the argument of last call to
- OtherSubrs[3] */
+ static int lastargOtherSubr3 = 3; /* the argument of last call to
+ OtherSubrs[3] */
cs_entry *ptr;
cc_entry *cc;
if (cs_name == NULL) {
@@ -1318,7 +1213,7 @@ static void cs_mark(const char *cs_name, int subr)
a |= (cs_getchar() & 0xff) << 16;
a |= (cs_getchar() & 0xff) << 8;
a |= (cs_getchar() & 0xff) << 0;
- if (sizeof(integer) > 4 && (a & 0x80000000))
+ if (sizeof(int) > 4 && (a & 0x80000000))
a |= ~0x7FFFFFFF;
}
cc_push(a);
@@ -1401,16 +1296,15 @@ static void cs_mark(const char *cs_name, int subr)
ptr->used = false;
}
-/**********************************************************************/
-/* AVL search tree for glyph code by glyph name */
-
-static int comp_t1_glyphs(const void *pa, const void *pb, void *p)
+@ AVL search tree for glyph code by glyph name
+@c
+static int comp_t1_glyphs(const void *pa, const void *pb, void *p
+ __attribute__ ((unused)))
{
- (void) p;
- return strcmp(*((const char * const *) pa), *((const char * const *) pb));
+ return strcmp(*(const char *const *) pa, *(const char *const *) pb);
}
-static struct avl_table *create_t1_glyph_tree(char **glyph_names)
+struct avl_table *create_t1_glyph_tree(char **glyph_names)
{
int i;
void **aa;
@@ -1420,7 +1314,7 @@ static struct avl_table *create_t1_glyph_tree(char **glyph_names)
for (i = 0; i < 256; i++) {
if (glyph_names[i] != notdef &&
(char **) avl_find(gl_tree, &glyph_names[i]) == NULL) {
- /* no strdup here, just point to the glyph_names array members */
+ /* no |strdup| here, just point to the |glyph_names| array members */
aa = avl_probe(gl_tree, &glyph_names[i]);
assert(aa != NULL);
}
@@ -1428,15 +1322,15 @@ static struct avl_table *create_t1_glyph_tree(char **glyph_names)
return gl_tree;
}
-static void destroy_t1_glyph_tree(struct avl_table *gl_tree)
+void destroy_t1_glyph_tree(struct avl_table *gl_tree)
{
assert(gl_tree != NULL);
avl_destroy(gl_tree, NULL);
}
-/**********************************************************************/
-
-static void t1_subset_ascii_part(void)
+@
+@c
+static void t1_subset_ascii_part(PDF pdf)
{
int j, *p;
char *glyph, **gg, **glyph_names;
@@ -1447,8 +1341,8 @@ static void t1_subset_ascii_part(void)
assert(fd_cur->gl_tree != NULL);
t1_getline();
while (!t1_prefix("/Encoding")) {
- t1_scan_param();
- t1_putline();
+ t1_scan_param(pdf);
+ t1_putline(pdf);
t1_getline();
}
glyph_names = t1_builtin_enc();
@@ -1456,7 +1350,7 @@ static void t1_subset_ascii_part(void)
if (is_subsetted(fd_cur->fm)) {
assert(is_included(fd_cur->fm));
if (fd_cur->tx_tree != NULL) {
- /* take over collected non-reencoded characters from TeX */
+ /* take over collected non-reencoded characters from \TeX */
avl_t_init(&t, fd_cur->tx_tree);
for (p = (int *) avl_t_first(&t, fd_cur->tx_tree); p != NULL;
p = (int *) avl_t_next(&t)) {
@@ -1469,42 +1363,45 @@ static void t1_subset_ascii_part(void)
}
make_subset_tag(fd_cur);
assert(t1_fontname_offset != 0);
- strncpy(fb_array + t1_fontname_offset, fd_cur->subset_tag, 6);
+ strncpy(pdf->fb_array + t1_fontname_offset, fd_cur->subset_tag, 6);
}
- /* now really all glyphs needed from this font are in the fd_cur->gl_tree */
+ /* now really all glyphs needed from this font are in the |fd_cur->gl_tree| */
if (t1_encoding == ENC_STANDARD)
- t1_puts("/Encoding StandardEncoding def\n");
+ t1_puts(pdf, "/Encoding StandardEncoding def\n");
else {
t1_puts
- ("/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n");
+ (pdf,
+ "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n");
gl_tree = create_t1_glyph_tree(glyph_names);
avl_t_init(&t, fd_cur->gl_tree);
j = 0;
for (glyph = (char *) avl_t_first(&t, fd_cur->gl_tree); glyph != NULL;
glyph = (char *) avl_t_next(&t)) {
if ((gg = (char **) avl_find(gl_tree, &glyph)) != NULL) {
- t1_printf("dup %i /%s put\n", (int) (gg - glyph_names), *gg);
+ t1_printf(pdf, "dup %i /%s put\n", (int) (gg - glyph_names),
+ *gg);
j++;
}
}
destroy_t1_glyph_tree(gl_tree);
if (j == 0)
- /* We didn't mark anything for the Encoding array. */
- /* We add "dup 0 /.notdef put" for compatibility */
- /* with Acrobat 5.0. */
- t1_puts("dup 0 /.notdef put\n");
- t1_puts("readonly def\n");
+ /* We didn't mark anything for the Encoding array.
+ We add \.{dup 0 /.notdef put} for compatibility with Acrobat 5.0. */
+ t1_puts(pdf, "dup 0 /.notdef put\n");
+ t1_puts(pdf, "readonly def\n");
}
do {
t1_getline();
- t1_scan_param();
+ t1_scan_param(pdf);
if (!t1_prefix("/UniqueID")) /* ignore UniqueID for subsetted fonts */
- t1_putline();
+ t1_putline(pdf);
}
while (t1_in_eexec == 0);
}
+@
+@c
static void cs_init(void)
{
cs_ptr = cs_tab = NULL;
@@ -1526,15 +1423,17 @@ static void init_cs_entry(cs_entry * cs)
cs->valid = false;
}
-static void t1_read_subrs(void)
+@
+@c
+static void t1_read_subrs(PDF pdf)
{
int i, s;
cs_entry *ptr;
t1_getline();
while (!(t1_charstrings() || t1_subrs())) {
- t1_scan_param();
+ t1_scan_param(pdf);
if (!t1_prefix("/UniqueID")) /* ignore UniqueID for subsetted fonts */
- t1_putline();
+ t1_putline(pdf);
t1_getline();
}
found:
@@ -1543,14 +1442,14 @@ static void t1_read_subrs(void)
if (!t1_subrs())
return;
subr_size_pos = strlen("/Subrs") + 1;
- /* subr_size_pos points to the number indicating dict size after "/Subrs" */
- subr_size = t1_scan_num(t1_line_array + subr_size_pos, 0);
+ /* |subr_size_pos| points to the number indicating dict size after |"Subrs"| */
+ subr_size = (int) t1_scan_num(t1_line_array + subr_size_pos, 0);
if (subr_size == 0) {
while (!t1_charstrings())
t1_getline();
return;
}
- subr_tab = xtalloc(subr_size, cs_entry);
+ subr_tab = xtalloc((unsigned) subr_size, cs_entry);
for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
init_cs_entry(ptr);
subr_array_start = xstrdup(t1_line_array);
@@ -1563,9 +1462,9 @@ static void t1_read_subrs(void)
for (i = 0; i < subr_size && i < 4; i++)
subr_tab[i].used = true;
/* the end of the Subrs array might have more than one line so we need to
- concatnate them to subr_array_end. Unfortunately some fonts don't have
+ concatenate them to |subr_array_end|. Unfortunately some fonts don't have
the Subrs array followed by the CharStrings dict immediately (synthetic
- fonts). If we cannot find CharStrings in next POST_SUBRS_SCAN lines then
+ fonts). If we cannot find CharStrings in next |POST_SUBRS_SCAN| lines then
we will treat the font as synthetic and ignore everything until next
Subrs is found
*/
@@ -1575,7 +1474,7 @@ static void t1_read_subrs(void)
for (i = 0; i < POST_SUBRS_SCAN; i++) {
if (t1_charstrings())
break;
- s += t1_line_ptr - t1_line_array;
+ s = (int) (s + t1_line_ptr - t1_line_array);
alloc_array(t1_buf, s, T1_BUF_SIZE);
strcat(t1_buf_array, t1_line_array);
t1_getline();
@@ -1598,10 +1497,12 @@ static void t1_read_subrs(void)
}
}
-#define t1_subr_flush() t1_flush_cs(true)
-#define t1_cs_flush() t1_flush_cs(false)
+@
+@c
+#define t1_subr_flush() t1_flush_cs(pdf, true)
+#define t1_cs_flush() t1_flush_cs(pdf, false)
-static void t1_flush_cs(boolean is_subr)
+static void t1_flush_cs(PDF pdf, boolean is_subr)
{
char *p;
byte *r, *return_cs = NULL;
@@ -1632,16 +1533,16 @@ static void t1_flush_cs(boolean is_subr)
sprintf(t1_line_ptr, "%u", count);
strcat(t1_line_ptr, p);
t1_line_ptr = eol(t1_line_array);
- t1_putline();
+ t1_putline(pdf);
cs_len = 0; /* for -Wall */
- /* create return_cs to replace unsused subr's */
+ /* create |return_cs| to replace unsused subr's */
if (is_subr) {
cr = 4330;
cs_len = 0;
- /* at this point we have t1_lenIV >= 0;
- * a negative value would be caught in t1_scan_param() */
- return_cs = xtalloc(t1_lenIV + 1, byte);
+ /* at this point we have |t1_lenIV >= 0;|
+ a negative value would be caught in |t1_scan_param| */
+ return_cs = xtalloc((unsigned) (t1_lenIV + 1), byte);
for (cs_len = 0, r = return_cs; cs_len < t1_lenIV; cs_len++, r++)
*r = cencrypt(0x00, &cr);
*r = cencrypt(CS_RETURN, &cr);
@@ -1658,19 +1559,19 @@ static void t1_flush_cs(boolean is_subr)
p = strend(t1_line_array);
memcpy(p, ptr->data, ptr->len);
t1_line_ptr = p + ptr->len;
- t1_putline();
+ t1_putline(pdf);
} else {
- /* replace unsused subr's by return_cs */
+ /* replace unsused subr's by |return_cs| */
if (is_subr) {
sprintf(t1_line_array, "dup %li %u%s ", (long int) (ptr - tab),
cs_len, cs_token_pair[0]);
p = strend(t1_line_array);
memcpy(p, return_cs, cs_len);
t1_line_ptr = p + cs_len;
- t1_putline();
+ t1_putline(pdf);
sprintf(t1_line_array, " %s", cs_token_pair[1]);
t1_line_ptr = eol(t1_line_array);
- t1_putline();
+ t1_putline(pdf);
}
}
xfree(ptr->data);
@@ -1679,7 +1580,7 @@ static void t1_flush_cs(boolean is_subr)
}
sprintf(t1_line_array, "%s", line_end);
t1_line_ptr = eol(t1_line_array);
- t1_putline();
+ t1_putline(pdf);
if (is_subr)
xfree(return_cs);
xfree(tab);
@@ -1687,6 +1588,8 @@ static void t1_flush_cs(boolean is_subr)
xfree(line_end);
}
+@
+@c
static void t1_mark_glyphs(void)
{
char *glyph;
@@ -1714,19 +1617,22 @@ static void t1_mark_glyphs(void)
if (subr_tab != NULL)
for (subr_max = -1, ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
if (ptr->used && ptr - subr_tab > subr_max)
- subr_max = ptr - subr_tab;
+ subr_max = (int) (ptr - subr_tab);
}
-static void t1_subset_charstrings(void)
+@
+@c
+static void t1_subset_charstrings(PDF pdf)
{
cs_entry *ptr;
- cs_size_pos = strstr(t1_line_array, charstringname) + strlen(charstringname)
- - t1_line_array + 1;
- /* cs_size_pos points to the number indicating
- dict size after "/CharStrings" */
- cs_size = t1_scan_num(t1_line_array + cs_size_pos, 0);
- cs_ptr = cs_tab = xtalloc(cs_size, cs_entry);
+ cs_size_pos = (int) (strstr(t1_line_array,
+ charstringname) + strlen(charstringname) -
+ t1_line_array + 1);
+ /* |cs_size_pos| points to the number indicating
+ dict size after |"/CharStrings"| */
+ cs_size = (int) t1_scan_num(t1_line_array + cs_size_pos, 0);
+ cs_ptr = cs_tab = xtalloc((unsigned) cs_size, cs_entry);
for (ptr = cs_tab; ptr - cs_tab < cs_size; ptr++)
init_cs_entry(ptr);
cs_notdef = NULL;
@@ -1750,36 +1656,40 @@ static void t1_subset_charstrings(void)
t1_cs_flush();
}
-static void t1_subset_end(void)
+@
+@c
+static void t1_subset_end(PDF pdf)
{
- if (t1_synthetic) { /* copy to "dup /FontName get exch definefont pop" */
+ if (t1_synthetic) { /* copy to \.{dup /FontName get exch definefont pop} */
while (!strstr(t1_line_array, "definefont")) {
t1_getline();
- t1_putline();
+ t1_putline(pdf);
}
while (!t1_end_eexec())
t1_getline(); /* ignore the rest */
- t1_putline(); /* write "mark currentfile closefile" */
+ t1_putline(pdf); /* write \.{mark currentfile closefile} */
} else
- while (!t1_end_eexec()) { /* copy to "mark currentfile closefile" */
+ while (!t1_end_eexec()) { /* copy to \.{mark currentfile closefile} */
t1_getline();
- t1_putline();
+ t1_putline(pdf);
}
- t1_stop_eexec();
+ t1_stop_eexec(pdf);
if (fixedcontent) { /* copy 512 zeros (not needed for PDF) */
while (!t1_cleartomark()) {
t1_getline();
- t1_putline();
+ t1_putline(pdf);
}
- if (!t1_synthetic) /* don't check "{restore}if" for synthetic fonts */
- t1_check_end(); /* write "{restore}if" if found */
+ if (!t1_synthetic) /* don't check \.{{restore}if} for synthetic fonts */
+ t1_check_end(pdf); /* write \.{{restore}if} if found */
}
get_length3();
}
-void writet1(fd_entry * fd)
+@
+@c
+void writet1(PDF pdf, fd_entry * fd)
{
- fd_cur = fd; /* fd_cur is global inside writet1.c */
+ fd_cur = fd; /* |fd_cur| is global inside \.{writet1.w} */
assert(fd_cur->fm != NULL);
assert(is_type1(fd->fm));
assert(is_included(fd->fm));
@@ -1788,7 +1698,7 @@ void writet1(fd_entry * fd)
if (!is_subsetted(fd_cur->fm)) { /* include entire font */
if (!(fd->ff_found = t1_open_fontfile("<<")))
return;
- t1_include();
+ t1_include(pdf);
t1_close_font_file(">>");
xfree(t1_buffer);
return;
@@ -1796,17 +1706,19 @@ void writet1(fd_entry * fd)
/* partial downloading */
if (!(fd->ff_found = t1_open_fontfile("<")))
return;
- t1_subset_ascii_part();
- t1_start_eexec();
+ t1_subset_ascii_part(pdf);
+ t1_start_eexec(pdf);
cc_init();
cs_init();
- t1_read_subrs();
- t1_subset_charstrings();
- t1_subset_end();
+ t1_read_subrs(pdf);
+ t1_subset_charstrings(pdf);
+ t1_subset_end(pdf);
t1_close_font_file(">");
xfree(t1_buffer);
}
+@
+@c
void t1_free(void)
{
xfree(t1_line_array);
diff --git a/Build/source/texk/web2c/luatexdir/font/writet3.c b/Build/source/texk/web2c/luatexdir/font/writet3.w
index 30dab2e8b14..9301ba5f4f3 100644
--- a/Build/source/texk/web2c/luatexdir/font/writet3.c
+++ b/Build/source/texk/web2c/luatexdir/font/writet3.w
@@ -1,31 +1,32 @@
-/* writet3.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% writet3.w
- This file is part of LuaTeX.
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: writet3.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writet3.w $";
#include "ptexlib.h"
#include <kpathsea/tex-glyph.h>
#include <kpathsea/magstep.h>
#include <string.h>
-#include "luatexfont.h"
-
-static const char _svn_version[] =
- "$Id: writet3.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/writet3.c $";
#define T3_BUF_SIZE 1024
@@ -35,24 +36,25 @@ define_array(t3_line);
FILE *t3_file;
static boolean t3_image_used;
-static integer t3_char_procs[256];
+static int t3_char_procs[256];
static float t3_char_widths[256];
static int t3_glyph_num;
static float t3_font_scale;
-static integer t3_b0, t3_b1, t3_b2, t3_b3;
+static int t3_b0, t3_b1, t3_b2, t3_b3;
static boolean is_pk_font;
/* not static because used by pkin.c */
unsigned char *t3_buffer = NULL;
-integer t3_size = 0;
-integer t3_curbyte = 0;
+int t3_size = 0;
+int 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,
+@
+@c
+static void update_bbox(int llx, int lly, int urx, int ury,
boolean is_first_glyph)
{
if (is_first_glyph) {
@@ -72,59 +74,54 @@ static void update_bbox(integer llx, integer lly, integer urx, integer ury,
}
}
-static integer get_pk_font_scale(internalfontnumber f)
+static int get_pk_font_scale(internal_font_number f, int precision,
+ int scale_factor)
{
return
- divide_scaled(pk_scale_factor,
- divide_scaled(pdf_font_size(f), one_hundred_bp,
- fixed_decimal_digits + 2), 0);
+ divide_scaled(scale_factor,
+ divide_scaled(font_size(f), one_hundred_bp,
+ precision + 2), 0);
}
-static integer pk_char_width(internalfontnumber f, scaled w)
+static int pk_char_width(internal_font_number f, scaled w, int precision,
+ int scale_factor)
{
return
- divide_scaled(divide_scaled(w, pdf_font_size(f), 7),
- get_pk_font_scale(f), 0);
+ divide_scaled(divide_scaled(w, font_size(f), 7),
+ get_pk_font_scale(f, precision, scale_factor), 0);
}
-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);
-}
-
-static boolean writepk(internalfontnumber f)
+@
+@c
+static boolean writepk(PDF pdf, internal_font_number f)
{
kpse_glyph_file_type font_ret;
- integer llx, lly, urx, ury;
- integer cw, rw, i, j;
+ int llx, lly, urx, ury;
+ int cw, rw, i, j;
halfword *row;
char *name;
char *ftemp = NULL;
chardesc cd;
boolean is_null_glyph, check_preamble;
- integer dpi;
+ int dpi;
int callback_id = 0;
int file_opened = 0;
- int mallocsize = 0;
- if (t3_buffer != NULL) {
- xfree(t3_buffer);
- t3_buffer = NULL;
- }
+ unsigned mallocsize = 0;
+ xfree(t3_buffer);
t3_curbyte = 0;
t3_size = 0;
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 = round((float) pdf->pk_resolution *
+ (((float) font_size(f)) / (float) font_dsize(f)));
/* <base>.dpi/<fontname>.<tdpi>pk */
cur_file_name = font_name(f);
- mallocsize = strlen(cur_file_name) + 24 + 9;
+ mallocsize = (unsigned) (strlen(cur_file_name) + 24 + 9);
name = xmalloc(mallocsize);
- snprintf(name, mallocsize, "%ddpi/%s.%dpk", (int) fixed_pk_resolution,
- cur_file_name, (int) dpi);
+ snprintf(name, (size_t) mallocsize, "%ddpi/%s.%dpk",
+ (int) pdf->pk_resolution, cur_file_name, (int) dpi);
if (run_callback(callback_id, "S->S", name, &ftemp)) {
if (ftemp != NULL && strlen(ftemp)) {
free(name);
@@ -133,11 +130,11 @@ static boolean writepk(internalfontnumber f)
}
}
} else {
- dpi =
- kpse_magstep_fix(round
- (fixed_pk_resolution *
- (((float) pdf_font_size(f)) / font_dsize(f))),
- fixed_pk_resolution, NULL);
+ dpi = (int)
+ kpse_magstep_fix((unsigned) round
+ ((float) pdf->pk_resolution *
+ ((float) font_size(f) / (float) font_dsize(f))),
+ (unsigned) pdf->pk_resolution, NULL);
cur_file_name = font_name(f);
name = kpse_find_pk(cur_file_name, (unsigned) dpi, &font_ret);
if (name == NULL ||
@@ -167,14 +164,15 @@ static boolean writepk(internalfontnumber f)
if (tracefilenames)
tex_printf(" <%s", (char *) name);
cd.rastersize = 256;
- cd.raster = xtalloc(cd.rastersize, halfword);
+ cd.raster = xtalloc((unsigned long) cd.rastersize, halfword);
check_preamble = true;
while (readchar(check_preamble, &cd) != 0) {
check_preamble = false;
if (!pdf_char_marked(f, cd.charcode))
continue;
- t3_char_widths[cd.charcode] =
- pk_char_width(f, get_charwidth(f, cd.charcode));
+ t3_char_widths[cd.charcode] = (float)
+ pk_char_width(f, get_charwidth(f, cd.charcode),
+ pdf->decimal_digits, pdf->pk_scale_factor);
if (cd.cwidth < 1 || cd.cheight < 1) {
cd.xescape = cd.cwidth = round(t3_char_widths[cd.charcode] / 100.0);
cd.cheight = 1;
@@ -189,71 +187,65 @@ static boolean writepk(internalfontnumber f)
ury = cd.cheight + lly;
update_bbox(llx, lly, urx, ury, t3_glyph_num == 0);
t3_glyph_num++;
- 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",
+ pdf_new_dict(pdf, obj_type_others, 0, 0);
+ t3_char_procs[cd.charcode] = pdf->obj_ptr;
+ pdf_begin_stream(pdf);
+ pdf_print_real(pdf, (int) t3_char_widths[cd.charcode], 2);
+ pdf_printf(pdf, " 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,
+ pdf_printf(pdf, "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(pdf, "/W %i\n/H %i\n", (int) cd.cwidth, (int) cd.cheight);
+ pdf_puts(pdf, "/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);
+ pdf_out(pdf, (unsigned char) (*row / 256));
+ pdf_out(pdf, (unsigned char) (*row % 256));
row++;
}
- pdfout(*row / 256);
+ pdf_out(pdf, (unsigned char) (*row / 256));
if (2 * rw == cw)
- pdfout(*row % 256);
+ pdf_out(pdf, (unsigned char) (*row % 256));
row++;
}
- pdf_puts("\nEI\nQ\n");
+ pdf_puts(pdf, "\nEI\nQ\n");
end_stream:
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
xfree(cd.raster);
cur_file_name = NULL;
return true;
}
-void writet3(int objnum, internalfontnumber f)
+@
+@c
+void writet3(PDF pdf, internal_font_number f)
{
int i;
- integer wptr, eptr, cptr;
+ int wptr, eptr, cptr;
int first_char, last_char;
- integer pk_font_scale;
+ int pk_font_scale;
boolean is_notdef;
-
t3_glyph_num = 0;
t3_image_used = false;
for (i = 0; i < 256; i++) {
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());
is_pk_font = false;
- if (t3_buffer != NULL) {
- xfree(t3_buffer);
- t3_buffer = NULL;
- }
+ xfree(t3_buffer);
t3_curbyte = 0;
t3_size = 0;
- if (!writepk(f)) {
- cur_file_name = NULL;
+ if (!writepk(pdf, f))
return;
- }
for (i = font_bc(f); i <= font_ec(f); i++)
if (pdf_char_marked(f, i))
break;
@@ -262,76 +254,77 @@ void writet3(int objnum, internalfontnumber f)
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(pdf, pdf_font_num(f), 1); /* Type 3 font dictionary */
+ pdf_puts(pdf, "/Type /Font\n/Subtype /Type3\n");
+ pdf_printf(pdf, "/Name /F%i\n", (int) f);
+ if (pdf_font_attr(f) != get_nullstr() && pdf_font_attr(f) != 0) {
+ pdf_print(pdf, pdf_font_attr(f));
+ pdf_puts(pdf, "\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->decimal_digits, pdf->pk_scale_factor);
+ pdf_puts(pdf, "/FontMatrix [");
+ pdf_print_real(pdf, pk_font_scale, 5);
+ pdf_puts(pdf, " 0 0 ");
+ pdf_print_real(pdf, pk_font_scale, 5);
+ pdf_puts(pdf, " 0 0]\n");
} else
- pdf_printf("/FontMatrix [%g 0 0 %g 0 0]\n",
+ pdf_printf(pdf, "/FontMatrix [%g 0 0 %g 0 0]\n",
(double) t3_font_scale, (double) t3_font_scale);
- pdf_printf("/%s [ %i %i %i %i ]\n",
+ pdf_printf(pdf, "/%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",
+ pdf_printf(pdf, "/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",
+ pdf_printf(pdf, "/FirstChar %i\n/LastChar %i\n", first_char, last_char);
+ wptr = pdf_new_objnum(pdf);
+ eptr = pdf_new_objnum(pdf);
+ cptr = pdf_new_objnum(pdf);
+ pdf_printf(pdf, "/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_end_dict(pdf);
+ pdf_begin_obj(pdf, wptr, 1); /* chars width array */
+ pdf_puts(pdf, "[");
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(pdf, (int) t3_char_widths[i], 2);
+ pdf_puts(pdf, " ");
} 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(pdf, "%i ", (int) t3_char_widths[i]);
+ pdf_puts(pdf, "]\n");
+ pdf_end_obj(pdf);
+ pdf_begin_dict(pdf, eptr, 1); /* encoding dictionary */
+ pdf_printf(pdf, "/Type /Encoding\n/Differences [%i", first_char);
if (t3_char_procs[first_char] == 0) {
- pdf_printf("/%s", notdef);
+ pdf_printf(pdf, "/%s", notdef);
is_notdef = true;
} else {
- pdf_printf("/a%i", first_char);
+ pdf_printf(pdf, "/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(pdf, " %i/%s", i, notdef);
is_notdef = true;
}
} else {
if (is_notdef) {
- pdf_printf(" %i", i);
+ pdf_printf(pdf, " %i", i);
is_notdef = false;
}
- pdf_printf("/a%i", i);
+ pdf_printf(pdf, "/a%i", i);
}
}
- pdf_puts("]\n");
- pdf_end_dict();
- pdf_begin_dict(cptr, 1); /* CharProcs dictionary */
+ pdf_puts(pdf, "]\n");
+ pdf_end_dict(pdf);
+ pdf_begin_dict(pdf, 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();
+ pdf_printf(pdf, "/a%i %i 0 R\n", (int) i, (int) t3_char_procs[i]);
+ pdf_end_dict(pdf);
if (tracefilenames)
tex_printf(">");
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 03b5cc9da12..a66cf011251 100644
--- a/Build/source/texk/web2c/luatexdir/font/writettf.h
+++ b/Build/source/texk/web2c/luatexdir/font/writettf.h
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writettf.h 2271 2009-04-12 23:42:21Z oneiros $ */
+/* $Id: writettf.h 3400 2010-01-27 16:10:42Z taco $ */
#ifndef WRITETTF_H
# define WRITETTF_H 1
@@ -74,7 +74,7 @@ typedef unsigned short TTF_F2DOT14;
# 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_num(t,n) ((t)ttf_putnum(pdf,t##_SIZE, n))
# define put_char(n) (void)put_num(TTF_CHAR, n)
# define put_byte(n) (void)put_num(TTF_BYTE, n)
@@ -146,8 +146,8 @@ typedef struct {
extern fd_entry *fd_cur; /* pointer to the current font descriptor */
extern unsigned char *ttf_buffer;
-extern integer ttf_size;
-extern integer ttf_curbyte;
+extern int ttf_size;
+extern int ttf_curbyte;
extern glyph_entry *glyph_tab;
extern dirtab_entry *dir_tab;
extern dirtab_entry *ttf_name_lookup(const char *s, boolean required);
@@ -161,16 +161,16 @@ extern void ttf_read_post(void);
extern FILE *ttf_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_open(a) \
+ (ttf_file = fopen((char *) (a), FOPEN_RBIN_MODE))
+# define otf_open(a) \
+ (ttf_file = fopen((char *) (a), 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_putnum(PDF pdf, int s, long n);
extern long ttf_getnum(int s);
#endif
diff --git a/Build/source/texk/web2c/luatexdir/font/writettf.c b/Build/source/texk/web2c/luatexdir/font/writettf.w
index 0e4bb43802c..bbeb346c020 100644
--- a/Build/source/texk/web2c/luatexdir/font/writettf.c
+++ b/Build/source/texk/web2c/luatexdir/font/writettf.w
@@ -1,47 +1,48 @@
-/* writettf.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% writettf.w
+%
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
#include "ptexlib.h"
-#include "writettf.h"
+#include "font/writettf.h"
#include <string.h>
static const char _svn_version[] =
- "$Id: writettf.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/writettf.c $";
+ "$Id: writettf.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writettf.w $";
#define DEFAULT_NTABS 14
#define NEW_CMAP_SIZE 2
-#define ttf_putchar fb_putchar
-#define ttf_offset fb_offset
-#define ttf_seek_outbuf fb_seek
-
- /* #define INFILE ttf_file */
+#define ttf_putchar(A) fb_putchar(pdf,(A))
+#define ttf_offset() fb_offset(pdf)
+#define ttf_seek_outbuf(A) fb_seek(pdf,(A))
unsigned char *ttf_buffer = NULL;
-integer ttf_size = 0;
-integer ttf_curbyte = 0;
+int ttf_size = 0;
+int ttf_curbyte = 0;
typedef struct {
- const char *name; /* name of glyph */
+ char *name; /* name of glyph */
long code; /* charcode in case of subfonts */
long newindex; /* new index of glyph in output file */
+
} ttfenc_entry;
typedef struct {
@@ -93,9 +94,301 @@ fd_entry *fd_cur; /* pointer to the current font descriptor */
static struct avl_table *ttf_cmap_tree = NULL;
-integer ttf_length;
+int ttf_length;
+
+@ This used to be macnames.c
+
+@c
+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"
+};
-#include "macnames.c"
+const char *ambiguous_names[] = {
+ "Delta", /* increment */
+ "Omega", /* Ohm */
+ "Pi", /* product */
+ "Sigma", /* summation */
+ "dmacron", /* dslash */
+ "macron", /* overscore */
+ "periodcentered", /* middot */
+ NULL
+};
static const char *newtabnames[] = {
"OS/2",
@@ -114,7 +407,10 @@ static const char *newtabnames[] = {
"prep"
};
-static ttf_cmap_entry *new_ttf_cmap_entry(void)
+@ Back to code. Low-level helpers first.
+
+@c
+ttf_cmap_entry *new_ttf_cmap_entry(void)
{
ttf_cmap_entry *e;
e = xtalloc(1, ttf_cmap_entry);
@@ -164,24 +460,24 @@ static unsigned char ttf_addchksm(unsigned char b)
return b;
}
-static TTF_ULONG ttf_getchksm(void)
+static TTF_ULONG ttf_getchksm(PDF pdf)
{
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(PDF pdf, int s, long n)
{
long i = n;
char buf[TTF_LONG_SIZE + 1], *p = buf;
while (s-- > 0) {
- *p++ = i & 0xFF;
+ *p++ = (char) (i & 0xFF);
i >>= 8;
}
p--;
while (p >= buf)
- ttf_putchar(ttf_addchksm(*p--));
+ ttf_putchar(ttf_addchksm((unsigned char) (*p--)));
return n;
}
@@ -207,7 +503,7 @@ static long ttf_funit(long n)
return (n / upem) * 1000 + ((n % upem) * 1000) / upem;
}
-static void ttf_ncopy(int n)
+static void ttf_ncopy(PDF pdf, int n)
{
while (n-- > 0)
copy_byte();
@@ -231,15 +527,13 @@ dirtab_entry *ttf_name_lookup(const char *s, boolean required)
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;
+ ttf_curbyte = (int) (tab->offset + (unsigned long) offset);
return tab;
}
static void ttf_seek_off(TTF_LONG offset)
{
- ttf_curbyte = offset;
- //xfseek (INFILE, offset, SEEK_SET, cur_file_name);
+ ttf_curbyte = (int) offset;
}
static void ttf_copy_encoding(void)
@@ -252,14 +546,14 @@ static void ttf_copy_encoding(void)
struct avl_traverser t;
ttfenc_entry *e = ttfenc_tab;
- assert(fd_cur->tx_tree != NULL); /* this must be set in create_fontdictionary */
+ assert(fd_cur->tx_tree != NULL); /* this must be set in |create_fontdictionary| */
if (fd_cur->fe != NULL) {
glyph_names = fd_cur->fe->glyph_names;
assert(glyph_names != NULL);
for (i = 0; i < 256; i++)
- ttfenc_tab[i].name = notdef;
+ ttfenc_tab[i].name = (char *) notdef;
/* a workaround for a bug of AcroReader 4.0 */
if (strcmp(glyph_names[97], "a") == 0) {
@@ -270,7 +564,7 @@ static void ttf_copy_encoding(void)
}
/* end of workaround */
- /* take over collected characters from TeX, reencode them */
+ /* take over collected characters from \TeX, reencode them */
avl_t_init(&t, fd_cur->tx_tree);
for (q = (int *) avl_t_first(&t, fd_cur->tx_tree); q != NULL;
q = (int *) avl_t_next(&t)) {
@@ -285,7 +579,7 @@ static void ttf_copy_encoding(void)
for (i = 0; i < 256; i++)
ttfenc_tab[i].code = -1;
- /* take over collected characters from TeX */
+ /* take over collected characters from \TeX */
avl_t_init(&t, fd_cur->tx_tree);
for (q = (int *) avl_t_first(&t, fd_cur->tx_tree); q != NULL;
q = (int *) avl_t_next(&t)) {
@@ -308,6 +602,8 @@ static void ttf_copy_encoding(void)
assert(0);
}
+@
+@c
#define ttf_append_byte(B)\
do {\
if (name_tab[i].platform_id == 3)\
@@ -340,10 +636,11 @@ static void ttf_read_name(void)
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);
+ name_tab = xtalloc((unsigned) name_record_num, name_record);
+ name_buf_size = (int) ((unsigned) tab->length -
+ (3 * TTF_USHORT_SIZE +
+ (TTF_ULONG) name_record_num * 6 * TTF_USHORT_SIZE));
+ name_buf = xtalloc((unsigned) name_buf_size, char);
ttf_skip(TTF_USHORT_SIZE);
for (i = 0; i < name_record_num; i++) {
name_tab[i].platform_id = get_ushort();
@@ -378,7 +675,7 @@ static void ttf_read_name(void)
*p++ = name_buf[name_tab[i].offset + j + 1];
*p = 0;
fd_cur->fontname =
- xstrdup(strip_spaces_and_delims(buf, strlen(buf)));
+ xstrdup(strip_spaces_and_delims(buf, (int) strlen(buf)));
fd_cur->font_dim[FONTNAME_CODE].set = true;
break;
}
@@ -390,14 +687,15 @@ 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);
+ glyph_tab =
+ xtalloc((unsigned) (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 = notdef;
+ glyph->name = (char *) notdef;
}
- glyph_index = xtalloc(glyphs_count, long);
+ glyph_index = xtalloc((unsigned) (glyphs_count + 1), long);
glyph_index[0] = 0; /* index of ".notdef" glyph */
glyph_index[1] = 1; /* index of ".null" glyph */
}
@@ -408,10 +706,10 @@ void ttf_read_head(void)
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());
- fd_cur->font_dim[FONTBBOX4_CODE].val = ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX1_CODE].val = (int) ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX2_CODE].val = (int) ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX3_CODE].val = (int) ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX4_CODE].val = (int) ttf_funit(get_fword());
fd_cur->font_dim[FONTBBOX1_CODE].set = true;
fd_cur->font_dim[FONTBBOX2_CODE].set = true;
fd_cur->font_dim[FONTBBOX3_CODE].set = true;
@@ -423,8 +721,8 @@ void ttf_read_head(void)
void ttf_read_hhea(void)
{
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].val = (int) ttf_funit(get_fword());
+ fd_cur->font_dim[DESCENT_CODE].val = (int) 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 +
@@ -437,9 +735,9 @@ void ttf_read_pclt(void)
if (ttf_name_lookup("PCLT", false) == NULL)
return;
ttf_seek_tab("PCLT", TTF_FIXED_SIZE + TTF_ULONG_SIZE + TTF_USHORT_SIZE);
- fd_cur->font_dim[XHEIGHT_CODE].val = ttf_funit(get_ushort());
+ fd_cur->font_dim[XHEIGHT_CODE].val = (int) ttf_funit(get_ushort());
ttf_skip(2 * TTF_USHORT_SIZE);
- fd_cur->font_dim[CAPHEIGHT_CODE].val = ttf_funit(get_ushort());
+ fd_cur->font_dim[CAPHEIGHT_CODE].val = (int) ttf_funit(get_ushort());
fd_cur->font_dim[XHEIGHT_CODE].set = true;
fd_cur->font_dim[CAPHEIGHT_CODE].set = true;
}
@@ -451,13 +749,13 @@ static void ttf_read_hmtx(void)
ttf_seek_tab("hmtx", 0);
for (glyph = glyph_tab; glyph - glyph_tab < nhmtxs; glyph++) {
glyph->advWidth = get_ufword();
- glyph->lsb = get_ufword();
+ glyph->lsb = (TTF_FWORD) 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 = (TTF_FWORD) get_ufword();
}
}
}
@@ -474,14 +772,14 @@ void ttf_read_post(void)
const dirtab_entry *tab = ttf_seek_tab("post", 0);
post_format = get_fixed();
italic_angle = get_fixed();
- int_part = italic_angle >> 16;
+ int_part = (long) (italic_angle >> 16);
if (int_part > 0x7FFF) { /* a negative number */
int_part = 0x10000 - int_part;
sign = -1;
}
- frac_part = italic_angle % 0x10000;
+ frac_part = (long) (italic_angle % 0x10000);
fd_cur->font_dim[ITALIC_ANGLE_CODE].val =
- sign * (int_part + frac_part * 1.0 / 0x10000);
+ (int) (sign * ((double) int_part + (double) frac_part * 1.0 / 0x10000));
fd_cur->font_dim[ITALIC_ANGLE_CODE].set = true;
if (glyph_tab == NULL)
return; /* being called from writeotf() */
@@ -489,17 +787,18 @@ void ttf_read_post(void)
switch (post_format) {
case 0x10000:
for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) {
- glyph->name = mac_glyph_names[glyph - glyph_tab];
- glyph->name_index = glyph - glyph_tab;
+ glyph->name = (const char *) mac_glyph_names[glyph - glyph_tab];
+ glyph->name_index = (TTF_USHORT) (glyph - glyph_tab);
}
break;
case 0x20000:
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); */
- length = tab->length - (ttf_curbyte - tab->offset);
- glyph_name_buf = xtalloc(length, char);
+ length =
+ (long) ((long) tab->length -
+ (long) ((long) ttf_curbyte - (long) tab->offset));
+ glyph_name_buf = xtalloc((unsigned) length, char);
for (p = glyph_name_buf; p - glyph_name_buf < length;) {
for (k = get_byte(); k > 0; k--)
*p++ = get_char();
@@ -519,7 +818,7 @@ void ttf_read_post(void)
break;
case 0x00030000:
for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) {
- glyph->name_index = glyph - glyph_tab;
+ glyph->name_index = (TTF_USHORT) (glyph - glyph_tab);
}
break;
default:
@@ -534,7 +833,7 @@ static void ttf_read_loca(void)
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 = (TTF_LONG) get_ulong();
else
for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count + 1; glyph++)
glyph->offset = get_ushort() << 1;
@@ -567,10 +866,10 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid,
ttf_cmap_entry tmp_e, *p;
void **aa;
- /* loop up in ttf_cmap_tree first, return if found */
+ /* look up in |ttf_cmap_tree| first, return if found */
tmp_e.ttf_name = ttf_name;
- tmp_e.pid = pid;
- tmp_e.eid = eid;
+ tmp_e.pid = (TTF_USHORT) pid;
+ tmp_e.eid = (TTF_USHORT) eid;
if (ttf_cmap_tree == NULL) {
ttf_cmap_tree = avl_create(comp_ttf_cmap_entry, NULL, &avl_xallocator);
assert(ttf_cmap_tree != NULL);
@@ -580,17 +879,16 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid,
return p;
/* not found, have to read it */
- ttf_seek_tab("cmap", TTF_USHORT_SIZE); /* skip the table vesrion number (=0) */
+ ttf_seek_tab("cmap", TTF_USHORT_SIZE); /* skip the table version 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_offset = (TTF_ULONG) (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();
if (tmp_pid == pid && tmp_eid == eid) {
- ttf_seek_off(cmap_offset + tmp_offset);
+ ttf_seek_off((TTF_LONG) (cmap_offset + tmp_offset));
format = get_ushort();
if (format == 4)
goto read_cmap_format_4;
@@ -609,8 +907,8 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid,
/* initialize the new entry */
p = new_ttf_cmap_entry();
p->ttf_name = xstrdup(ttf_name);
- p->pid = pid;
- p->eid = eid;
+ p->pid = (TTF_USHORT) pid;
+ p->eid = (TTF_USHORT) eid;
p->table = xtalloc(0x10000, long);
for (i = 0; i < 0x10000; ++i)
p->table[i] = -1; /* unassigned yet */
@@ -634,7 +932,7 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid,
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((unsigned) n, TTF_USHORT);
for (i = 0; i < n; i++)
glyphId[i] = get_ushort();
for (s = seg_tab; s - seg_tab < segCount; s++) {
@@ -672,6 +970,8 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid,
return p;
}
+@
+@c
static void ttf_read_font(void)
{
ttf_read_tabdir();
@@ -693,37 +993,39 @@ static void ttf_read_font(void)
ttf_read_name();
}
-static void ttf_reset_chksm(dirtab_entry * tab)
+static void ttf_reset_chksm(PDF pdf, dirtab_entry * tab)
{
checksum = 0;
tab_length = 0;
tmp_ulong = 0;
- tab->offset = ttf_offset();
+ tab->offset = (TTF_ULONG) ttf_offset();
if (tab->offset % 4 != 0)
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(PDF pdf, dirtab_entry * tab)
{
- tab->length = ttf_offset() - tab->offset;
- tab->checksum = ttf_getchksm();
+ tab->length = (TTF_ULONG) ttf_offset() - tab->offset;
+ tab->checksum = ttf_getchksm(pdf);
}
-static void ttf_copytab(const char *name)
+static void ttf_copytab(PDF pdf, const char *name)
{
long i;
dirtab_entry *tab = ttf_seek_tab(name, 0);
- ttf_reset_chksm(tab);
- for (i = tab->length; i > 0; i--)
+ ttf_reset_chksm(pdf, tab);
+ for (i = (long) tab->length; i > 0; i--)
copy_char();
- ttf_set_chksm(tab);
+ ttf_set_chksm(pdf, tab);
}
+@
+@c
#define BYTE_ENCODING_LENGTH \
((256)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE)
-static void ttf_byte_encoding(void)
+static void ttf_byte_encoding(PDF pdf)
{
ttfenc_entry *e;
(void) put_ushort(0); /* format number (0: byte encoding table) */
@@ -741,9 +1043,11 @@ static void ttf_byte_encoding(void)
}
}
+@
+@c
#define TRIMMED_TABLE_MAP_LENGTH (TTF_USHORT_SIZE*(5 + (256)))
-static void ttf_trimmed_table_map(void)
+static void ttf_trimmed_table_map(PDF pdf)
{
ttfenc_entry *e;
(void) put_ushort(6); /* format number (6): trimmed table mapping */
@@ -755,9 +1059,11 @@ static void ttf_trimmed_table_map(void)
(void) put_ushort(e->newindex);
}
+@
+@c
#define SEG_MAP_DELTA_LENGTH ((16 + (256))*TTF_USHORT_SIZE)
-static void ttf_seg_map_delta(void)
+static void ttf_seg_map_delta(PDF pdf)
{
ttfenc_entry *e;
(void) put_ushort(4); /* format number (4: segment mapping to delta values) */
@@ -780,6 +1086,8 @@ static void ttf_seg_map_delta(void)
(void) put_ushort(e->newindex);
}
+@
+@c
#define CMAP_ENTRY_LENGTH (2*TTF_USHORT_SIZE + TTF_ULONG_SIZE)
static void ttf_select_cmap(void)
@@ -787,25 +1095,25 @@ static void ttf_select_cmap(void)
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 */
- : 6; /* trimmed table mapping */
+ new_cmap_tab[0].format = (TTF_USHORT) (new_glyphs_count < 256 ? 0 /* byte encoding */
+ : 6); /* trimmed table mapping */
new_cmap_tab[1].platform_id = 3; /* Microsoft */
new_cmap_tab[1].encoding_id = 0; /* Symbol; ignore code page */
new_cmap_tab[1].format = 4; /* segment mapping to delta */
}
-static void ttf_write_cmap(void)
+static void ttf_write_cmap(PDF pdf)
{
cmap_entry *ce;
long offset;
dirtab_entry *tab = ttf_name_lookup("cmap", true);
ttf_select_cmap();
- ttf_reset_chksm(tab);
+ ttf_reset_chksm(pdf, 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;
+ ce->offset = (TTF_ULONG) offset;
switch (ce->format) {
case 0:
offset += BYTE_ENCODING_LENGTH;
@@ -821,24 +1129,26 @@ static void ttf_write_cmap(void)
}
(void) put_ushort(ce->platform_id);
(void) put_ushort(ce->encoding_id);
- put_ulong(ce->offset);
+ put_ulong((long) 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(pdf);
break;
case 4:
- ttf_seg_map_delta();
+ ttf_seg_map_delta(pdf);
break;
case 6:
- ttf_trimmed_table_map();
+ ttf_trimmed_table_map(pdf);
break;
}
}
- ttf_set_chksm(tab);
+ ttf_set_chksm(pdf, tab);
}
+@
+@c
static int prepend_subset_tags(int index, char *p)
{
boolean is_unicode;
@@ -862,7 +1172,7 @@ static int prepend_subset_tags(int index, char *p)
}
-static void ttf_write_name(void)
+static void ttf_write_name(PDF pdf)
{
int i, l;
char *p;
@@ -874,12 +1184,12 @@ static void ttf_write_name(void)
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((unsigned) l, char);
/* additional space for subset tags */
p = new_name_buf;
for (i = 0; i < name_record_num; i++) {
n = name_tab + i;
- n->new_offset = p - new_name_buf;
+ n->new_offset = (TTF_USHORT) (p - new_name_buf);
if ((n->name_id == 1 || n->name_id == 3 ||
n->name_id == 4 || n->name_id == 6) &&
((n->platform_id == 1 && n->encoding_id == 0) ||
@@ -891,14 +1201,14 @@ static void ttf_write_name(void)
l = 0;
memcpy(p, name_buf + n->offset, n->length);
p += n->length;
- n->new_length = n->length + l;
+ n->new_length = (TTF_USHORT) (n->length + l);
}
- new_name_buf_size = p - new_name_buf;
+ new_name_buf_size = (int) (p - new_name_buf);
} else {
new_name_buf = name_buf;
new_name_buf_size = name_buf_size;
}
- ttf_reset_chksm(tab);
+ ttf_reset_chksm(pdf, tab);
(void) put_ushort(0); /* Format selector */
(void) put_ushort(name_record_num);
(void) put_ushort(3 * TTF_USHORT_SIZE +
@@ -913,17 +1223,19 @@ static void ttf_write_name(void)
}
for (p = new_name_buf; p - new_name_buf < new_name_buf_size; p++)
put_char(*p);
- ttf_set_chksm(tab);
+ ttf_set_chksm(pdf, tab);
if (new_name_buf != name_buf)
xfree(new_name_buf);
}
-static void ttf_write_dirtab(void)
+@
+@c
+static void ttf_write_dirtab(PDF pdf)
{
dirtab_entry *tab;
TTF_ULONG i, k;
char *p;
- const integer save_offset = ttf_offset();
+ const int save_offset = ttf_offset();
ttf_seek_outbuf(TABDIR_OFF);
if (is_subsetted(fd_cur->fm)) {
for (i = 0; i < DEFAULT_NTABS; i++) {
@@ -932,24 +1244,24 @@ static void ttf_write_dirtab(void)
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_ulong((long) tab->checksum);
+ put_ulong((long) tab->offset);
+ put_ulong((long) 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_ulong((long) tab->checksum);
+ put_ulong((long) tab->offset);
+ put_ulong((long) tab->length);
}
}
/* adjust checkSumAdjustment */
tmp_ulong = 0;
checksum = 0;
- for (p = fb_array, i = 0; i < (unsigned) save_offset;) {
- tmp_ulong = (tmp_ulong << 8) + *p++;
+ for (p = pdf->fb_array, i = 0; i < (unsigned) save_offset;) {
+ tmp_ulong = (tmp_ulong << 8) + (TTF_ULONG) * p++;
i++;
if (i % 4 == 0) {
checksum += tmp_ulong;
@@ -961,61 +1273,70 @@ static void ttf_write_dirtab(void)
checksum <<= 8 * (4 - i % 4);
}
k = 0xB1B0AFBA - checksum;
- ttf_seek_outbuf(checkSumAdjustment_offset);
- put_ulong(k);
+ ttf_seek_outbuf((int) checkSumAdjustment_offset);
+ put_ulong((long) k);
ttf_seek_outbuf(save_offset);
}
-static void ttf_write_glyf(void)
+@
+@c
+static void ttf_write_glyf(PDF pdf)
{
long *id, k;
TTF_USHORT idx;
TTF_USHORT flags;
dirtab_entry *tab = ttf_name_lookup("glyf", true);
- const long glyf_offset = tab->offset;
+ const long glyf_offset = (long) tab->offset;
const long new_glyf_offset = ttf_offset();
- ttf_reset_chksm(tab);
+ ttf_reset_chksm(pdf, tab);
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
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_ncopy(pdf, 4 * TTF_FWORD_SIZE);
if (k < 0) {
do {
flags = copy_ushort();
idx = get_ushort();
if (glyph_tab[idx].newindex < 0) {
- glyph_tab[idx].newindex = new_glyphs_count;
+ glyph_tab[idx].newindex = (TTF_SHORT) new_glyphs_count;
glyph_index[new_glyphs_count++] = idx;
/*
- N.B.: Here we change `new_glyphs_count',
- which appears in the condition of the `for' loop
+ N.B.: Here we change |new_glyphs_count|,
+ which appears in the condition of the |for| loop
*/
}
(void) put_ushort(glyph_tab[idx].newindex);
if (flags & ARG_1_AND_2_ARE_WORDS)
- ttf_ncopy(2 * TTF_SHORT_SIZE);
+ ttf_ncopy(pdf, 2 * TTF_SHORT_SIZE);
else
- ttf_ncopy(TTF_USHORT_SIZE);
+ ttf_ncopy(pdf, TTF_USHORT_SIZE);
if (flags & WE_HAVE_A_SCALE)
- ttf_ncopy(TTF_F2DOT14_SIZE);
+ ttf_ncopy(pdf, TTF_F2DOT14_SIZE);
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- ttf_ncopy(2 * TTF_F2DOT14_SIZE);
+ ttf_ncopy(pdf, 2 * TTF_F2DOT14_SIZE);
else if (flags & WE_HAVE_A_TWO_BY_TWO)
- ttf_ncopy(4 * TTF_F2DOT14_SIZE);
+ ttf_ncopy(pdf, 4 * TTF_F2DOT14_SIZE);
} while (flags & MORE_COMPONENTS);
if (flags & WE_HAVE_INSTRUCTIONS)
- ttf_ncopy(copy_ushort());
+ ttf_ncopy(pdf, copy_ushort());
} else
- ttf_ncopy(glyph_tab[*id + 1].offset - glyph_tab[*id].offset -
- TTF_USHORT_SIZE - 4 * TTF_FWORD_SIZE);
+ ttf_ncopy(pdf, (int)
+ (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_ULONG) ttf_offset() - (TTF_ULONG) new_glyf_offset;
+ ttf_set_chksm(pdf, tab);
}
+@ Reindexing glyphs: we append index of used glyphs to |glyph_index|
+ while going through |ttfenc_tab|. After appending a new entry to
+ |glyph_index| we set field |newindex| of corresponding entries in both
+ |glyph_tab| and |ttfenc_tab| to the newly created index.
+
+@c
static void ttf_reindex_glyphs(void)
{
ttfenc_entry *e;
@@ -1025,12 +1346,6 @@ static void ttf_reindex_glyphs(void)
ttf_cmap_entry *cmap = NULL;
boolean cmap_not_found = false;
- /*
- * reindexing glyphs: we append index of used glyphs to `glyph_index'
- * while going through `ttfenc_tab'. After appending a new entry to
- * `glyph_index' we set field `newindex' of corresponding entries in both
- * `glyph_tab' and `ttfenc_tab' to the newly created index
- */
for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) {
e->newindex = 0; /* index of ".notdef" glyph */
@@ -1118,60 +1433,88 @@ static void ttf_reindex_glyphs(void)
assert(glyph > glyph_tab && glyph - glyph_tab < glyphs_count);
if (glyph->newindex < 0) {
glyph_index[new_glyphs_count] = (short) (glyph - glyph_tab);
- glyph->newindex = new_glyphs_count;
+ glyph->newindex = (TTF_SHORT) new_glyphs_count;
new_glyphs_count++;
}
e->newindex = glyph->newindex;
}
}
-static void ttf_write_head(void)
+@ To calculate the checkSum for the 'head' table which itself includes the
+ checkSumAdjustment entry for the entire font, do the following:
+
+ \item Set the checkSumAdjustment to 0.
+ \item Calculate the checksum for all the tables including the 'head' table
+ and enter that value into the table directory.
+ \item Calculate the checksum for the entire font.
+ \item Subtract that value from the hex value B1B0AFBA.
+ \item Store the result in checkSumAdjustment.
+
+ The checkSum for the 'head table which includes the checkSumAdjustment
+ entry for the entire font is now incorrect. That is not a problem. Do not
+ change it. An application attempting to verify that the 'head' table has
+ not changed should calculate the checkSum for that table by not including
+ the checkSumAdjustment value, and compare the result with the entry in the
+ table directory.
+
+ The table directory also includes the offset of the associated tagged
+ table from the beginning of the font file and the length of that table.
+
+
+@c
+static void ttf_write_head(PDF pdf)
{
dirtab_entry *tab;
tab = ttf_seek_tab("head", 0);
- ttf_reset_chksm(tab);
- ttf_ncopy(2 * TTF_FIXED_SIZE);
- checkSumAdjustment_offset = ttf_offset();
+ ttf_reset_chksm(pdf, tab);
+ ttf_ncopy(pdf, 2 * TTF_FIXED_SIZE);
+ checkSumAdjustment_offset = (TTF_ULONG) ttf_offset();
put_ulong(0);
ttf_skip(TTF_ULONG_SIZE); /* skip checkSumAdjustment */
- ttf_ncopy(TTF_ULONG_SIZE + 2 * TTF_USHORT_SIZE + 16 +
+ ttf_ncopy(pdf, 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);
} else
- ttf_ncopy(2 * TTF_SHORT_SIZE);
- ttf_set_chksm(tab);
+ ttf_ncopy(pdf, 2 * TTF_SHORT_SIZE);
+ ttf_set_chksm(pdf, tab);
}
-static void ttf_write_hhea(void)
+@
+@c
+static void ttf_write_hhea(PDF pdf)
{
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 +
+ ttf_reset_chksm(pdf, tab);
+ ttf_ncopy(pdf, 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);
+ ttf_set_chksm(pdf, tab);
}
-static void ttf_write_htmx(void)
+@
+@c
+static void ttf_write_htmx(PDF pdf)
{
long *id;
dirtab_entry *tab = ttf_seek_tab("hmtx", 0);
- ttf_reset_chksm(tab);
+ ttf_reset_chksm(pdf, tab);
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
put_ufword(glyph_tab[*id].advWidth);
put_ufword(glyph_tab[*id].lsb);
}
- ttf_set_chksm(tab);
+ ttf_set_chksm(pdf, tab);
}
-static void ttf_write_loca(void)
+@
+@c
+static void ttf_write_loca(PDF pdf)
{
long *id;
dirtab_entry *tab = ttf_seek_tab("loca", 0);
- ttf_reset_chksm(tab);
+ ttf_reset_chksm(pdf, tab);
loca_format = 0;
if (last_glyf_offset >= 0x00020000 || (last_glyf_offset & 1))
loca_format = 1;
@@ -1184,51 +1527,58 @@ 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((long) 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((long) (last_glyf_offset / 2));
}
- ttf_set_chksm(tab);
+ ttf_set_chksm(pdf, tab);
}
-static void ttf_write_mapx(void)
+@
+@c
+static void ttf_write_mapx(PDF pdf)
{
dirtab_entry *tab = ttf_seek_tab("maxp", TTF_FIXED_SIZE + TTF_USHORT_SIZE);
- ttf_reset_chksm(tab);
+ ttf_reset_chksm(pdf, tab);
put_fixed(0x00010000);
(void) put_ushort(new_glyphs_count);
- ttf_ncopy(13 * TTF_USHORT_SIZE);
- ttf_set_chksm(tab);
+ ttf_ncopy(pdf, 13 * TTF_USHORT_SIZE);
+ ttf_set_chksm(pdf, tab);
}
-static void ttf_write_OS2(void)
+@
+@c
+static void ttf_write_OS2(PDF pdf)
{
dirtab_entry *tab = ttf_seek_tab("OS/2", 0);
TTF_USHORT version;
- ttf_reset_chksm(tab);
+ ttf_reset_chksm(pdf, 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_ncopy(pdf,
+ 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_ncopy(pdf, 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);
+ ttf_ncopy(pdf, 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);
+ ttf_set_chksm(pdf, tab);
}
+@
+@c
static boolean unsafe_name(const char *s)
{
const char **p;
@@ -1238,43 +1588,47 @@ static boolean unsafe_name(const char *s)
return false;
}
-static void ttf_write_post(void)
+static void ttf_write_post(PDF pdf)
{
dirtab_entry *tab = ttf_seek_tab("post", TTF_FIXED_SIZE);
glyph_entry *glyph;
const char *s;
long *id;
- int l;
- ttf_reset_chksm(tab);
+ int k, l;
+ ttf_reset_chksm(pdf, 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);
+ ttf_ncopy(pdf,
+ 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);
+ ttf_ncopy(pdf,
+ 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))
- glyph->name_index = NMACGLYPHS + k++;
+ glyph->name_index = (TTF_USHORT) (NMACGLYPHS + k++);
(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);
+ l = (int) strlen(s);
put_byte(l);
while (l-- > 0)
put_char(*s++);
}
}
}
- ttf_set_chksm(tab);
+ ttf_set_chksm(pdf, tab);
}
-static void ttf_init_font(int n)
+@
+@c
+static void ttf_init_font(PDF pdf, int n)
{
int i, k;
for (i = 1, k = 0; i <= n; i <<= 1, k++);
@@ -1286,92 +1640,86 @@ static void ttf_init_font(int n)
ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE);
}
-static void ttf_subset_font(void)
+@
+@c
+static void ttf_subset_font(PDF pdf)
{
- ttf_init_font(new_ntabs);
+ ttf_init_font(pdf, new_ntabs);
if (ttf_name_lookup("PCLT", false) != NULL)
- ttf_copytab("PCLT");
+ ttf_copytab(pdf, "PCLT");
if (ttf_name_lookup("fpgm", false) != NULL)
- ttf_copytab("fpgm");
+ ttf_copytab(pdf, "fpgm");
if (ttf_name_lookup("cvt ", false) != NULL)
- ttf_copytab("cvt ");
+ ttf_copytab(pdf, "cvt ");
if (ttf_name_lookup("prep", false) != NULL)
- ttf_copytab("prep");
+ ttf_copytab(pdf, "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_write_glyf(pdf);
+ ttf_write_loca(pdf);
+ ttf_write_OS2(pdf);
+ ttf_write_head(pdf);
+ ttf_write_hhea(pdf);
+ ttf_write_htmx(pdf);
+ ttf_write_mapx(pdf);
+ ttf_write_name(pdf);
+ ttf_write_post(pdf);
+ ttf_write_cmap(pdf);
+ ttf_write_dirtab(pdf);
}
-static void ttf_copy_font(void)
+@
+@c
+static void ttf_copy_font(PDF pdf)
{
dirtab_entry *tab;
- ttf_init_font(ntabs);
+ ttf_init_font(pdf, ntabs);
for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
if (strncmp(tab->tag, "head", 4) == 0)
- ttf_write_head();
+ ttf_write_head(pdf);
else
- ttf_copytab(tab->tag);
+ ttf_copytab(pdf, tab->tag);
}
- ttf_write_dirtab();
+ ttf_write_dirtab(pdf);
}
-void writettf(fd_entry * fd)
+@
+@c
+void writettf(PDF pdf, fd_entry * fd)
{
int callback_id;
int file_opened = 0;
- char *ftemp = NULL;
- fd_cur = fd; /* fd_cur is global inside writettf.c */
+ fd_cur = fd; /* |fd_cur| is global inside \.{writettf.w} */
assert(fd_cur->fm != NULL);
assert(is_truetype(fd_cur->fm));
assert(is_included(fd_cur->fm));
- set_cur_file_name(fd_cur->fm->ff_name);
-
if (is_subsetted(fd_cur->fm) && (fd_cur->fe == NULL)
&& !is_subfont(fd_cur->fm)) {
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);
- }
- }
- }
+ cur_file_name =
+ luatex_find_file(fd_cur->fm->ff_name, find_truetype_file_callback);
+ if (cur_file_name == NULL) {
+ pdftex_fail("cannot find TrueType font file for reading");
+ }
callback_id = callback_defined(read_truetype_file_callback);
if (callback_id > 0) {
- if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1),
+ if (run_callback(callback_id, "S->bSd", cur_file_name,
&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()) {
+ if (!ttf_open(cur_file_name)) {
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);
@@ -1389,14 +1737,14 @@ void writettf(fd_entry * fd)
name_buf = NULL;
ttf_read_font();
- pdf_save_offset = pdfoffset();
- pdf_flush();
+ pdf_save_offset(pdf);
+ pdf_flush(pdf);
if (is_subsetted(fd_cur->fm)) {
ttf_copy_encoding();
- ttf_subset_font();
+ ttf_subset_font(pdf);
} else
- ttf_copy_font();
+ ttf_copy_font(pdf);
ttf_length = ttf_offset();
xfree(dir_tab);
@@ -1415,7 +1763,7 @@ void writettf(fd_entry * fd)
cur_file_name = NULL;
}
-static void do_writeotf(fd_entry * fd)
+void do_writeotf(PDF pdf, fd_entry * fd)
{
long i;
dirtab_entry *tab;
@@ -1436,83 +1784,51 @@ static void do_writeotf(fd_entry * fd)
ttf_read_post();
/* copy font file */
tab = ttf_seek_tab("CFF ", 0);
- for (i = tab->length; i > 0; i--)
+ for (i = (long) tab->length; i > 0; i--)
copy_char();
xfree(dir_tab);
- /* ttf_close (); */
if (tracefilenames)
tex_printf(">>");
}
-void writeotf(fd_entry * fd)
+@
+@c
+void writeotf(PDF pdf, fd_entry * fd)
{
int callback_id;
int file_opened = 0;
- char *ftemp = NULL;
-
- fd_cur = fd; /* fd_cur is global inside writettf.c */
+ fd_cur = fd;
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);
- }
- }
+ cur_file_name =
+ luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback);
+ if (cur_file_name == NULL) {
+ pdftex_fail("cannot find OpenType font file for reading");
}
callback_id = callback_defined(read_opentype_file_callback);
if (callback_id > 0) {
- if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1),
+ if (run_callback(callback_id, "S->bSd", cur_file_name,
&file_opened, &ttf_buffer, &ttf_size) &&
file_opened && ttf_size > 0) {
} else {
pdftex_fail("cannot open OpenType font file for reading");
}
} else {
- if (!otf_open()) {
+ if (!otf_open(cur_file_name)) {
pdftex_fail("cannot open OpenType font file for reading");
}
ttf_read_file();
ttf_close();
}
- cur_file_name = (char *) nameoffile + 1;
fd_cur->ff_found = true;
- do_writeotf(fd);
+ do_writeotf(pdf, fd);
xfree(ttf_buffer);
cur_file_name = NULL;
}
-/*
- To calculate the checkSum for the 'head' table which itself includes the
- checkSumAdjustment entry for the entire font, do the following:
-
- * Set the checkSumAdjustment to 0.
- * Calculate the checksum for all the tables including the 'head' table
- and enter that value into the table directory.
- * Calculate the checksum for the entire font.
- * Subtract that value from the hex value B1B0AFBA.
- * Store the result in checkSumAdjustment.
-
- The checkSum for the 'head table which includes the checkSumAdjustment
- entry for the entire font is now incorrect. That is not a problem. Do not
- change it. An application attempting to verify that the 'head' table has
- not changed should calculate the checkSum for that table by not including
- the checkSumAdjustment value, and compare the result with the entry in the
- table directory.
-
- The table directory also includes the offset of the associated tagged
- table from the beginning of the font file and the length of that table.
- */
diff --git a/Build/source/texk/web2c/luatexdir/font/writetype0.c b/Build/source/texk/web2c/luatexdir/font/writetype0.c
deleted file mode 100644
index 796c6e5aa37..00000000000
--- a/Build/source/texk/web2c/luatexdir/font/writetype0.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* writetype0.c
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "ptexlib.h"
-#include "writettf.h"
-#include "writecff.h"
-
-static const char _svn_version[] =
- "$Id: writetype0.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/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) {
- } else {
- pdftex_fail("cannot open OpenType font file for reading");
- }
- } else {
- if (!otf_open()) {
- pdftex_fail("cannot open OpenType font file for reading");
- }
- 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();
-
- /* 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 {
- /* 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(">>");
- }
- cur_file_name = NULL;
-}
diff --git a/Build/source/texk/web2c/luatexdir/font/writetype0.w b/Build/source/texk/web2c/luatexdir/font/writetype0.w
new file mode 100644
index 00000000000..f902ad89a2a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/font/writetype0.w
@@ -0,0 +1,123 @@
+% writetype0.w
+%
+% Copyright 2006-2008 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+#include "font/writettf.h"
+#include "font/writecff.h"
+
+static const char _svn_version[] =
+ "$Id: writetype0.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writetype0.w $";
+
+@ @c
+void writetype0(PDF pdf, fd_entry * fd)
+{
+ int callback_id;
+ int file_opened = 0;
+ long i;
+ dirtab_entry *tab;
+ cff_font *cff;
+
+ dir_tab = NULL;
+ glyph_tab = NULL;
+
+ fd_cur = fd; /* |fd_cur| is global inside \.{writettf.w} */
+ assert(fd_cur->fm != NULL);
+ assert(is_opentype(fd_cur->fm));
+ assert(is_included(fd_cur->fm));
+
+ ttf_curbyte = 0;
+ ttf_size = 0;
+ cur_file_name =
+ luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback);
+ if (cur_file_name == NULL) {
+ pdftex_fail("cannot find OpenType font file for reading");
+ }
+ callback_id = callback_defined(read_opentype_file_callback);
+ if (callback_id > 0) {
+ if (run_callback(callback_id, "S->bSd", cur_file_name,
+ &file_opened, &ttf_buffer, &ttf_size) &&
+ file_opened && ttf_size > 0) {
+ } else {
+ pdftex_fail("cannot open OpenType font file for reading");
+ }
+ } else {
+ if (!otf_open(cur_file_name)) {
+ pdftex_fail("cannot open OpenType font file for reading");
+ }
+ ttf_read_file();
+ ttf_close();
+ }
+
+ 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();
+
+ /* copy font file */
+ tab = ttf_seek_tab("CFF ", 0);
+
+ /* TODO the next 0 is a subfont index */
+ cff = read_cff(ttf_buffer + ttf_curbyte, (long) tab->length, 0);
+ if (!is_subsetted(fd_cur->fm)) {
+ /* not subsetted, just do a copy */
+ for (i = (long) tab->length; i > 0; i--)
+ fb_putchar(pdf, (eight_bits) ttf_getnum(1));
+ } else {
+ if (cff != NULL) {
+ if (cff_is_cidfont(cff)) {
+ write_cid_cff(pdf, cff, fd_cur);
+#if 0
+ for (i = tab->length; i > 0; i--)
+ fb_putchar (ttf_getnum(1));
+#endif
+ } else {
+ write_cff(pdf, cff, fd_cur);
+ }
+ } else {
+ /* not understood, just do a copy */
+ for (i = (long) tab->length; i > 0; i--)
+ fb_putchar(pdf, (eight_bits) ttf_getnum(1));
+ }
+ }
+ xfree(dir_tab);
+ xfree(ttf_buffer);
+ if (tracefilenames) {
+ if (is_subsetted(fd_cur->fm))
+ tex_printf(">");
+ else
+ tex_printf(">>");
+ }
+ cur_file_name = NULL;
+}
diff --git a/Build/source/texk/web2c/luatexdir/font/writetype2.c b/Build/source/texk/web2c/luatexdir/font/writetype2.w
index 4d187b59a83..5081d9f0986 100644
--- a/Build/source/texk/web2c/luatexdir/font/writetype2.c
+++ b/Build/source/texk/web2c/luatexdir/font/writetype2.w
@@ -1,39 +1,43 @@
-/* writetype0.c
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
+% writetype0.w
+%
+% Copyright 2006-2010 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.
+%
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
#include "ptexlib.h"
-#include "writettf.h"
-#include "writecff.h"
+#include "font/writettf.h"
+#include "font/writecff.h"
+#include "lua/luatex-api.h"
-#include "sfnt.h"
-#include "tt_glyf.h"
+#include "font/sfnt.h"
+#include "font/tt_glyf.h"
static const char _svn_version[] =
- "$Id: writetype2.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/font/writetype2.c $";
+ "$Id: writetype2.w 3584 2010-04-02 17:45:55Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/writetype2.w $";
-/* forward*/
-void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen);
+@ forward declaration
+@c
+void make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buffer, int buflen);
+@ @c
unsigned long cidtogid_obj = 0;
-/* low-level helpers */
-
+@ low-level helpers
+@c
#define test_loc(l) \
if ((f->loc+l)>f->buflen) { \
fprintf (stderr,"File ended prematurely\n"); \
@@ -45,22 +49,22 @@ 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++)];
-};
+}
USHORT get_unsigned_pair(sfnt * f)
{
USHORT l;
test_loc(2);
l = f->buffer[(f->loc++)];
- l = l * 0x100 + f->buffer[(f->loc++)];
+ l = (USHORT) (l * 0x100 + f->buffer[(f->loc++)]);
return l;
-};
+}
SHORT get_signed_pair(sfnt * f)
{
@@ -70,8 +74,8 @@ SHORT get_signed_pair(sfnt * f)
if (l > 0x80)
l -= 0x100;
l = l * 0x100 + f->buffer[(f->loc++)];
- return l;
-};
+ return (SHORT) l;
+}
ULONG get_unsigned_quad(sfnt * f)
{
@@ -82,7 +86,7 @@ ULONG get_unsigned_quad(sfnt * f)
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)
{
@@ -93,7 +97,7 @@ int do_sfnt_read(unsigned char *dest, int len, sfnt * f)
}
f->loc += len;
return len;
-};
+}
pdf_obj *pdf_new_stream(void)
{
@@ -101,22 +105,23 @@ pdf_obj *pdf_new_stream(void)
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);
+ stream->data = xmalloc((unsigned) len);
} else {
- stream->data = xrealloc(stream->data, len + stream->length);
+ stream->data =
+ xrealloc(stream->data, (unsigned) len + (unsigned) stream->length);
}
for (i = 0; i < len; i++) {
*(stream->data + stream->length + i) = *(buf + i);
}
- stream->length += len;
-};
+ stream->length += (unsigned) len;
+}
void pdf_release_obj(pdf_obj * stream)
{
@@ -126,61 +131,45 @@ void pdf_release_obj(pdf_obj * stream)
}
xfree(stream);
}
-};
-
+}
-void writetype2(fd_entry * fd)
+@ The main function.
+@c
+void writetype2(PDF pdf, 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 */
+ fd_cur = fd; /* |fd_cur| is global inside \.{writettf.w} */
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);
- }
- }
+ cur_file_name =
+ luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback);
+ if (cur_file_name == NULL) {
+ pdftex_fail("cannot find OpenType font file for reading");
}
callback_id = callback_defined(read_opentype_file_callback);
if (callback_id > 0) {
- if (run_callback(callback_id, "S->bSd", (char *) (nameoffile + 1),
+ if (run_callback(callback_id, "S->bSd", cur_file_name,
&file_opened, &ttf_buffer, &ttf_size) &&
file_opened && ttf_size > 0) {
} else {
pdftex_fail("cannot open OpenType font file for reading");
}
} else {
- if (!otf_open()) {
+ if (!otf_open(cur_file_name)) {
pdftex_fail("cannot open OpenType font file for reading");
}
ttf_read_file();
ttf_close();
}
- cur_file_name = (char *) nameoffile + 1;
fd_cur->ff_found = true;
if (tracefilenames) {
@@ -192,9 +181,10 @@ void writetype2(fd_entry * fd)
/* here is the real work */
- make_tt_subset(fd, ttf_buffer, ttf_size);
-
- /*xfree (dir_tab); */
+ make_tt_subset(pdf, fd, ttf_buffer, ttf_size);
+#if 0
+ xfree (dir_tab);
+#endif
xfree(ttf_buffer);
if (tracefilenames) {
if (is_subsetted(fd_cur->fm))
@@ -205,28 +195,27 @@ void writetype2(fd_entry * fd)
cur_file_name = NULL;
}
-/*
- * PDF viewer applications use following tables (CIDFontType 2)
- *
- * head, hhea, loca, maxp, glyf, hmtx, fpgm, cvt_, prep
- *
- * - from PDF Ref. v.1.3, 2nd ed.
- *
- * The fpgm, cvt_, and prep tables appears only when TrueType instructions
- * requires them. Those tables must be preserved if they exist.
- * We use must_exist flag to indicate `preserve it if present'
- * and to make sure not to cause an error when it does not exist.
- *
- * post and name table must exist in ordinary TrueType font file,
- * but when a TrueType font is converted to CIDFontType 2 font, those tables
- * are no longer required.
- *
- * The OS/2 table (required for TrueType font for Windows and OS/2) contains
- * liscencing information, but PDF viewers seems not using them.
- *
- * The 'name' table added. See comments in ttf.c.
- */
-
+@ PDF viewer applications use following tables (CIDFontType 2)
+
+\.{head, hhea, loca, maxp, glyf, hmtx, fpgm, cvt\_, prep}
+
+\rightline{from PDF Ref. v.1.3, 2nd ed.}
+
+ The \.{fpgm}, \.{cvt\_} and \.{prep} tables appears only when TrueType instructions
+ requires them. Those tables must be preserved if they exist.
+ We use |must_exist| flag to indicate `preserve it if present'
+ and to make sure not to cause an error when it does not exist.
+
+ \.{post} and \.{name} table must exist in ordinary TrueType font file,
+ but when a TrueType font is converted to CIDFontType 2 font, those tables
+ are no longer required.
+
+ The OS/2 table (required for TrueType font for Windows and OS/2) contains
+ liscencing information, but PDF viewers seems not using them.
+
+ The \.{name} table added. See comments in \.{writettf.w}.
+
+@c
static struct {
const char *name;
int must_exist;
@@ -237,7 +226,7 @@ static struct {
"head", 1}, {
"hhea", 1}, {
"loca", 1}, {
- "maxp", 1}, {
+ "maxp", 0}, {
"name", 1}, {
"glyf", 1}, {
"hmtx", 1}, {
@@ -248,9 +237,9 @@ static struct {
};
-static unsigned long ttc_read_offset(sfnt * sfont, int ttc_idx)
+unsigned long ttc_read_offset(sfnt * sfont, int ttc_idx)
{
- long version;
+ ULONG version;
unsigned long offset = 0;
unsigned long num_dirs = 0;
@@ -262,16 +251,15 @@ static unsigned long ttc_read_offset(sfnt * sfont, int ttc_idx)
fprintf(stderr, "Invalid TTC index number\n");
uexit(1);
}
-
sfnt_seek_set(sfont, 12 + ttc_idx * 4);
offset = sfnt_get_ulong(sfont);
return offset;
}
-#include <luafontloader/src/luafflib.h>
-
-void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen)
+@ Creating the subset.
+@c
+void make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buffer, int buflen)
{
long i, cid;
@@ -281,7 +269,7 @@ void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen)
unsigned char *cidtogidmap;
unsigned short num_glyphs, gid;
struct tt_glyphs *glyphs;
- char *used_chars;
+ char *used_chars = NULL;
sfnt *sfont;
pdf_obj *fontfile;
int verbose = 0, error = 0;
@@ -292,7 +280,9 @@ void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer 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));
+ tex_printf("(%s:%ld)", (fd->fm->ps_name ? fd->fm->ps_name : ""), i);
+ error =
+ sfnt_read_table_directory(sfont, ttc_read_offset(sfont, (int) i));
} else {
error = sfnt_read_table_directory(sfont, 0);
}
@@ -301,72 +291,72 @@ void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen)
fprintf(stderr, "Could not parse the ttf directory.\n");
uexit(1);
}
+ if (is_subsetted(fd->fm)) {
+ /* rebuild the glyph tables and create a fresh cidmap */
+ glyphs = tt_build_init();
- glyphs = tt_build_init();
-
- last_cid = 0;
+ 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 <= (long) 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 = (short unsigned) cid;
#ifndef NO_GHOSTSCRIPT_BUG
- gid = tt_add_glyph(glyphs, gid, cid);
+ gid = tt_add_glyph(glyphs, (USHORT) gid, (USHORT) 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 */
+ gid = tt_add_glyph(glyphs, (USHORT) gid, (USHORT) num_glyphs);
+ cidtogidmap[2 * cid] = gid >> 8;
+ cidtogidmap[2 * cid + 1] = gid & 0xff;
+#endif /* |!NO_GHOSTSCRIPT_BUG| */
- num_glyphs++;
- }
+ num_glyphs++;
+ }
- if (num_glyphs == 1) {
- fprintf(stderr, "No glyphs in subset?.\n");
- uexit(1);
- }
+ if (num_glyphs == 1) {
+ fprintf(stderr, "No glyphs in subset?.\n");
+ uexit(1);
+ }
- if (tt_build_tables(sfont, glyphs) < 0) {
- fprintf(stderr, "Could not parse the ttf buffer.\n");
- uexit(1);
- }
+ 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 (verbose > 1) {
+ fprintf(stdout, "[%u glyphs (Max CID: %u)]", glyphs->num_glyphs,
+ last_cid);
+ }
- tt_build_finish(glyphs);
+ tt_build_finish(glyphs);
+ }
/* Create font file */
@@ -387,30 +377,28 @@ void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen)
/* 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);
+ cidtogid_obj = (unsigned long) pdf_new_objnum(pdf);
+ pdf_begin_dict(pdf, (int) cidtogid_obj, 0);
+ pdf_printf(pdf, "/Length %i\n", ((last_cid + 1) * 2));
+ pdf_end_dict(pdf);
+ pdf_printf(pdf, "stream\n");
+ pdf_room(pdf, (int) ((last_cid + 1) * 2));
for (i = 0; i < ((int) (last_cid + 1) * 2); i++) {
- pdf_buf[pdf_ptr++] = cidtogidmap[i];
+ pdf_quick_out(pdf, cidtogidmap[i]);
}
- pdf_printf("\nendstream\n");
+ pdf_printf(pdf, "\nendstream\n");
}
/* the tff subset */
for (i = 0; i < (int) (fontfile->length); i++)
- fb_putchar(fontfile->data[i]);
+ fb_putchar(pdf, fontfile->data[i]);
pdf_release_obj(fontfile);
- /* other stuff that needs fixing: */
+ /* TODO other stuff that needs fixing: */
- /*
- * DW, W, DW2, and W2
- */
- /*
+ /* DW, W, DW2, and W2 */
+#if 0
if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) {
pdf_add_dict(font->fontdict,
pdf_new_name("DW"), pdf_new_number(1000.0));
@@ -419,12 +407,9 @@ void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen)
if (v_used_chars)
add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid);
}
- */
-
- /*
- * CIDSet
- */
- /*
+#endif
+ /* CIDSet */
+#if 0
{
pdf_obj *cidset;
@@ -435,7 +420,7 @@ void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen)
pdf_ref_obj(cidset));
pdf_release_obj(cidset);
}
- */
+#endif
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
deleted file mode 100755
index 1c544342799..00000000000
--- a/Build/source/texk/web2c/luatexdir/get_svnversion.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/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/getluatexsvnversion.sh b/Build/source/texk/web2c/luatexdir/getluatexsvnversion.sh
new file mode 100755
index 00000000000..a59bc81db56
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/getluatexsvnversion.sh
@@ -0,0 +1,25 @@
+#! /bin/sh
+
+# This script should be run within the source directory.
+
+$DEBUG
+
+FILE="texk/web2c/luatexdir/luatex_svnversion.h"
+
+LANG=C
+if [ ! -r $FILE ]
+then
+ echo '#define luatex_svn_revision -1' > $FILE
+fi
+if ( [ -d ./.svn ] && svnversion > /dev/null )
+then
+ # svn up > /dev/null
+ DEFREV=`cat $FILE`
+ SVNREV=`svnversion -c . | sed -ne 's/^[0-9]*:*\([0-9]*\).*/#define luatex_svn_revision \1/p'`
+ test "$DEFREV" != "$SVNREV" && echo "$SVNREV" > $FILE
+elif ( [ -f ../.git/refs/remotes/git-svn ] && git svn --version > /dev/null )
+then
+ DEFREV=`cat $FILE`
+ SVNREV=`git svn info | sed -ne 's/^Revision: \([0-9]*\).*$/#define luatex_svn_revision \1/p'`
+ test "$DEFREV" != "$SVNREV" && echo "$SVNREV" > $FILE
+fi
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.c b/Build/source/texk/web2c/luatexdir/image/epdf.c
deleted file mode 100644
index cf86a38fa34..00000000000
--- a/Build/source/texk/web2c/luatexdir/image/epdf.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* epdf.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "ptexlib.h"
-#include "inc-epdf.h"
-
-#include <string.h>
-
-static const char _svn_version[] =
- "$Id: epdf.c 2599 2009-06-25 10:35:26Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/epdf.c $";
-
-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) {
- fm->in_use = true;
- fd = new_fd_entry();
- fd->fm = fm;
- register_fd_entry(fd);
- fd->fd_objnum = pdf_new_objnum();
- assert(fm->ps_name != NULL);
- fd->fontname = xstrdup(fm->ps_name); /* just fallback */
- // 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);
- }
- return fd;
-}
-
-/***********************************************************************
- * Mark glyphs used by embedded PDF file:
- * 1. build fontdescriptor, if not yet existing
- * 2. mark glyphs directly there
- *
- * Input charset from xpdf is a string of glyph names including
- * leading slashes, but without blanks between them, like: /a/b/c
-***********************************************************************/
-
-void epdf_mark_glyphs(fd_entry * fd, char *charset)
-{
- char *p, *q, *s;
- char *glyph;
- void **aa;
- if (charset == NULL)
- return;
- assert(fd != NULL);
- for (s = charset + 1, q = charset + strlen(charset); s < q; s = p + 1) {
- for (p = s; *p != '\0' && *p != '/'; p++);
- *p = '\0';
- if ((char *) avl_find(fd->gl_tree, s) == NULL) {
- glyph = xstrdup(s);
- aa = avl_probe(fd->gl_tree, glyph);
- assert(aa != NULL);
- }
- }
-}
-
-void epdf_free(void)
-{
- epdf_check_mem();
-}
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h
index c619b20f08f..6d2632b0e54 100644
--- a/Build/source/texk/web2c/luatexdir/image/epdf.h
+++ b/Build/source/texk/web2c/luatexdir/image/epdf.h
@@ -1,8 +1,7 @@
/* epdf.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
-
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
LuaTeX is free software; you can redistribute it and/or modify it under
@@ -18,11 +17,50 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: epdf.h 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: epdf.h 3407 2010-01-28 16:27:39Z taco $ */
+
+// this is the common header file for C++ sources pdftoepdf.cc and lepdflib.cc
+
+#ifndef EPDF_H
+# define EPDF_H
+
+# include <stdlib.h>
+# include <math.h>
+# include <stddef.h>
+# include <stdio.h>
+# include <string.h>
+# include <kpathsea/c-ctype.h>
+# include <sys/stat.h>
+# ifdef POPPLER_VERSION
+# define GString GooString
+# include <dirent.h>
+# include <poppler-config.h>
+# include <goo/GooString.h>
+# include <goo/gmem.h>
+# include <goo/gfile.h>
+# else
+# include <aconf.h>
+# include <GString.h>
+# include <gmem.h>
+# include <gfile.h>
+# include <assert.h>
+# endif
+# include "Object.h"
+# include "Stream.h"
+# include "Array.h"
+# include "Dict.h"
+# include "XRef.h"
+# include "Catalog.h"
+# include "Link.h"
+# include "Page.h"
+# include "GfxFont.h"
+# include "PDFDoc.h"
+# include "GlobalParams.h"
+# include "Error.h"
extern "C" {
-#include <kpathsea/c-auto.h>
+# include <kpathsea/c-auto.h>
extern char *xstrdup(const char *);
@@ -30,91 +68,106 @@ extern "C" {
typedef const char *const_string; /* including kpathsea/types.h doesn't work on some systems */
-#define KPATHSEA_CONFIG_H /* avoid including other kpathsea header files */
+# define KPATHSEA_CONFIG_H /* avoid including other kpathsea header files */
/* from web2c/config.h */
-#ifdef CONFIG_H /* CONFIG_H has been defined by some xpdf */
-# undef CONFIG_H /* header file */
-#endif
+# ifdef CONFIG_H /* CONFIG_H has been defined by some xpdf */
+# undef CONFIG_H /* header file */
+# endif
-#include <web2c/c-auto.h> /* define SIZEOF_LONG */
-#include <web2c/config.h> /* define type integer */
+# include <web2c/c-auto.h> /* define SIZEOF_LONG */
-#include <web2c/luatexdir/ptexmac.h>
-#include "openbsd-compat.h"
-#include "image.h"
-#include "../utils/avlstuff.h"
+# include "openbsd-compat.h"
+# include "image.h"
+# include "utils/avlstuff.h"
+# include "pdf/pdftypes.h"
- extern void unrefPdfDocument(char *);
+# include "lua51/lua.h"
+# include "lua51/lauxlib.h"
- 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;
- extern integer pdf_box_spec_bleed;
- extern integer pdf_box_spec_trim;
- extern integer pdf_box_spec_art;
-
- 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[];
-
- extern integer fixed_replace_font;
-
- extern int is_subsetable(struct fm_entry *);
- extern struct fm_entry *lookup_fontmap(char *);
- extern integer get_fontfile(struct fm_entry *);
- extern integer get_fontname(struct fm_entry *);
- extern integer pdf_new_objnum(void);
- extern void read_pdf_info(image_dict *, integer, integer);
- extern void embed_whole_font(struct fd_entry *);
- extern void epdf_check_mem(void);
+ /* pdfgen.c */
+ __attribute__ ((format(printf, 2, 3)))
+ extern void pdf_printf(PDF, const char *fmt, ...);
+ extern void pdf_puts(PDF, const char *);
+ extern void pdf_begin_obj(PDF, int, bool);
+ extern void pdf_end_obj(PDF);
+ extern void pdf_begin_stream(PDF);
+ extern void pdf_end_stream(PDF);
+ extern void pdf_room(PDF, int);
+# define pdf_out(B,A) do { pdf_room(B,1); B->buf[B->ptr++] = A; } while (0)
+
+ /* pdftables.c */
+ extern int pdf_new_objnum(PDF);
+
+ /* epdf.c */
extern void epdf_free(void);
+
+ /* pdftoepdf.cc */
+ extern void read_pdf_info(image_dict *, int, int, img_readtype_e);
+ extern void write_epdf(PDF, image_dict *);
+ extern void unrefPdfDocument(char *);
+ extern void epdf_check_mem(void);
+
+ /* utils.c */
__attribute__ ((format(printf, 1, 2)))
- extern void pdf_printf(const char *fmt, ...);
- extern void pdf_puts(const char *);
- extern void pdf_begin_stream(void);
- extern void pdf_end_obj(void);
- extern void pdf_end_stream(void);
- extern void pdf_flush(void);
+ extern void pdftex_warn(const char *fmt, ...);
__attribute__ ((noreturn, format(printf, 1, 2)))
extern void pdftex_fail(const char *fmt, ...);
- __attribute__ ((format(printf, 1, 2)))
- extern void pdftex_warn(const char *fmt, ...);
- __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);
- extern void zpdf_new_dict(integer, integer, bool);
- extern void zpdf_os_get_os_buf(integer);
-
-/* epdf.c */
- extern int get_fd_objnum(struct fd_entry *);
- extern int get_fn_objnum(struct fd_entry *);
-
-#include "../inc-epdf.h"
-
-/* utils.c */
extern char *convertStringToPDFString(char *in, int len);
extern char *stripzeros(char *a);
-/* config.c */
- extern integer cfgpar(integer);
-
-/* avlstuff.c */
- extern void avl_put_obj(integer, integer);
- extern integer avl_find_obj(integer, integer, integer);
-}
+ /* lepdflib.c */
+ int luaopen_epdf(lua_State * L);
+
+};
+
+/**********************************************************************/
+
+// PdfObject encapsulates the xpdf Object type,
+// and properly frees its resources on destruction.
+// Use obj-> to access members of the Object,
+// 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
+ }
+ ~PdfObject() {
+ iObject.free();
+ }
+ Object *operator->() {
+ return &iObject;
+ }
+ Object *operator&() {
+ return &iObject;
+ }
+ private: // no copying or assigning
+ PdfObject(const PdfObject &);
+ void operator=(const PdfObject &);
+ public:
+ Object iObject;
+};
+// *INDENT-ON*
+
+/**********************************************************************/
+
+struct InObj {
+ Ref ref; // ref in original PDF
+ int num; // new object number in output PDF
+ InObj *next; // next entry in list of indirect objects
+};
+
+struct PdfDocument {
+ char *file_path; // full file name including path
+ char *checksum; // for reopening
+ PDFDoc *doc;
+ InObj *inObjList; // temporary linked list
+ avl_table *ObjMapTree; // permanent over luatex run
+ int occurences; // number of references to the PdfDocument; it can be deleted when occurences == 0
+};
+
+PdfDocument *refPdfDocument(char *file_path);
+
+#endif /* EPDF_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.w b/Build/source/texk/web2c/luatexdir/image/epdf.w
new file mode 100644
index 00000000000..c52f148ffdf
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/image/epdf.w
@@ -0,0 +1,34 @@
+% epdf.w
+
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: epdf.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/epdf.w $";
+
+#include "ptexlib.h"
+
+@ This must the be shortest C file we have that actually does something.
+
+@c
+void epdf_free(void)
+{
+ epdf_check_mem();
+}
diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h
index a2d47f6a471..c4d0c3963f7 100644
--- a/Build/source/texk/web2c/luatexdir/image/image.h
+++ b/Build/source/texk/web2c/luatexdir/image/image.h
@@ -1,7 +1,7 @@
/* image.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -18,23 +18,20 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: image.h 2336 2009-04-19 08:38:24Z hhenkel $ */
+/* $Id: image.h 3388 2010-01-26 10:59:04Z taco $ */
#ifndef IMAGE_H
# define IMAGE_H
# include <png.h>
+# include "pdf/pdftypes.h" /* for scaled_whd */
# define JPG_UINT16 unsigned int
# define JPG_UINT32 unsigned long
# define JPG_UINT8 unsigned char
-# define IMAGE_COLOR_B 1
-# define IMAGE_COLOR_C 2
-# define IMAGE_COLOR_I 4
-
-extern integer zround(double); /* from zround.c */
-# define bp2int(p) zround(p * (one_hundred_bp / 100.0))
+extern int do_zround(double r); /* from utils.c */
+# define bp2int(p) do_zround(p * (one_hundred_bp / 100.0))
# define int2bp(i) (i * 100.0 / one_hundred_bp)
# define TYPE_IMG "image"
@@ -83,31 +80,33 @@ typedef enum { PDF_BOX_SPEC_NONE, PDF_BOX_SPEC_MEDIA, PDF_BOX_SPEC_CROP,
/**********************************************************************/
typedef struct {
- integer objnum;
- integer index; /* /Im1, /Im2, ... */
- integer x_size; /* dimensions in pixel counts as in JPG/PNG/JBIG2 file */
- integer y_size;
- integer x_orig; /* origin in sp for PDF files */
- 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) */
+ int objnum;
+ int index; /* /Im1, /Im2, ... */
+ scaled_whd dimen; /* TeX dimensions given to \pdfximage */
+ int transform; /* transform given to \pdfximage */
+ int x_size; /* dimensions in pixel counts as in JPG/PNG/JBIG2 file */
+ int y_size;
+ int x_orig; /* origin in sp for PDF files */
+ int y_orig;
+ int x_res; /* pixel resolution as in JPG/PNG/JBIG2 file */
+ int y_res;
+ int rotation; /* rotation (multiples of 90 deg.) for PDF files */
+ int colorspace; /* number of /ColorSpace object */
+ int group_ref; /* if it's <=0, the page has no group */
+ int total_pages;
+ int page_num; /* requested page (by number) */
char *pagename; /* requested page (by name) */
char *filename; /* requested raw file name */
char *filepath; /* full file path after kpathsea */
char *attr; /* additional image dict entries */
FILE *file;
imgtype_e image_type;
- int color_space; /* used color space. See JPG_ constants */
+ int procset; /* /ProcSet flags */
int color_depth; /* color depth */
pdfboxspec_e page_box_spec; /* PDF page box spec.: media/crop/bleed/trim/art */
- integer bbox[4];
+ int bbox[4];
dict_state state;
- integer flags;
+ int flags;
union {
pdf_stream_struct *pdfstream;
png_img_struct *png;
@@ -118,6 +117,11 @@ typedef struct {
# define img_objnum(N) ((N)->objnum)
# define img_index(N) ((N)->index)
+# define img_dimen(N) ((N)->dimen)
+# define img_width(N) ((N)->dimen.wd)
+# define img_height(N) ((N)->dimen.ht)
+# define img_depth(N) ((N)->dimen.dp)
+# define img_transform(N) ((N)->transform)
# define img_xsize(N) ((N)->x_size)
# define img_ysize(N) ((N)->y_size)
# define img_xorig(N) ((N)->x_orig)
@@ -135,11 +139,12 @@ typedef struct {
# define img_attr(N) ((N)->attr)
# define img_file(N) ((N)->file)
# define img_type(N) ((N)->image_type)
-# define img_color(N) ((N)->color_space)
+# define img_procset(N) ((N)->procset)
# 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_flags(N) ((N)->flags)
# define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream)
# define img_pdfstream_stream(N) ((N)->img_struct.pdfstream->stream)
@@ -154,42 +159,39 @@ typedef struct {
# define img_jb2_ptr(N) ((N)->img_struct.jb2)
# define F_FLAG_BBOX (1 << 0)
+# define F_FLAG_GROUP (1 << 1)
# 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)
+# define img_set_group(N) (img_flags(N) |= F_FLAG_GROUP)
+# define img_unset_group(N) (img_flags(N) &= ~F_FLAG_GROUP)
+# define img_is_group(N) ((img_flags(N) & F_FLAG_GROUP) != 0)
+
+# define epdf_xsize(a) img_xsize(idict_array[a])
+# define epdf_ysize(a) img_ysize(idict_array[a])
+# define epdf_orig_x(a) img_xorig(idict_array[a])
+# define epdf_orig_y(a) img_yorig(idict_array[a])
+
+# define is_pdf_image(a) (img_type(idict_array[a]) == IMG_TYPE_PDF)
+# define is_png_image(a) (img_type(idict_array[a]) == IMG_TYPE_PNG)
+
+# define img_is_refered(N) (img_index(N) != -1)
+
/**********************************************************************/
+/* image structure corresponds to pdfrefximage node */
typedef struct {
- integer width; /* requested/actual TeX dimensions */
- integer height;
- integer depth;
- integer transform;
- integer flags;
+ scaled_whd dimen; /* requested/actual TeX dimensions */
+ int transform;
image_dict *dict;
- int array_idx; /* index within img_array */
int dict_ref; /* luaL_ref() reference */
} image;
-# define img_width(N) ((N)->width)
-# define img_height(N) ((N)->height)
-# define img_depth(N) ((N)->depth)
-# 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 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_unset_scaled(N) (img_flags(N) &= ~F_FLAG_SCALED)
-# define img_is_scaled(N) ((img_flags(N) & F_FLAG_SCALED) != 0)
-
# define set_wd_running(N) (img_width(N) = null_flag)
# define set_ht_running(N) (img_height(N) = null_flag)
# define set_dp_running(N) (img_depth(N) = null_flag)
diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
index 536c6398cd7..8a177163a76 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
@@ -1,7 +1,7 @@
/* pdftoepdf.cc
-
+
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -18,46 +18,13 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include <stdlib.h>
-#include <math.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef POPPLER_VERSION
-# define GString GooString
-# include <dirent.h>
-# include <poppler-config.h>
-# include <goo/GooString.h>
-# include <goo/gmem.h>
-# include <goo/gfile.h>
-#else
-# include <aconf.h>
-# include <GString.h>
-# include <gmem.h>
-# include <gfile.h>
-# include <assert.h>
-#endif
-#include "Object.h"
-#include "Stream.h"
-#include "Array.h"
-#include "Dict.h"
-#include "XRef.h"
-#include "Catalog.h"
-#include "Link.h"
-#include "Page.h"
-#include "GfxFont.h"
-#include "PDFDoc.h"
-#include "GlobalParams.h"
-#include "Error.h"
+static const char _svn_version[] =
+ "$Id: pdftoepdf.cc 3431 2010-02-17 20:35:50Z oneiros $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/pdftoepdf.cc $";
#include "epdf.h"
-static const char _svn_version[] =
- "$Id: pdftoepdf.cc 2448 2009-06-08 07:43:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/pdftoepdf.cc $";
-
-#define one_hundred_bp 6578176 /* 7227 * 65536 / 72 */
+#define one_hundred_bp 6578176 // one_hundred_bp = 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++.
@@ -67,81 +34,16 @@ static const char _svn_version[] =
#define pdfkeyprefix "PTEX"
-// PdfObject encapsulates the xpdf Object type,
-// and properly frees its resources on destruction.
-// Use obj-> to access members of the Object,
-// 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
- }
- ~PdfObject() {
- iObject.free();
- }
- Object *operator->() {
- return &iObject;
- }
- Object *operator&() {
- return &iObject;
- }
- private: // no copying or assigning
- PdfObject(const PdfObject &);
- void operator=(const 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
-// copying, but get a new object number from pdfTeX and then will be
-// appended into a linked list. Duplicates are checked and removed from the
-// list of indirect objects during appending.
-
-enum InObjType { objFont, objFontDesc, objOther };
-
-struct InObj {
- Ref ref; // ref in original PDF
- InObjType type; // object type
- integer num; // new object number in output PDF
- fd_entry *fd; // pointer to /FontDescriptor object structure
- integer enc_objnum; // Encoding for objFont
- int written; // has it been written to output PDF?
- InObj *next; // next entry in list of indirect objects
-};
-
-struct UsedEncoding {
- integer enc_objnum;
- GfxFont *font;
- UsedEncoding *next;
-};
-
-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
+// Maintain AVL tree of all PDF files for embedding
static avl_table *PdfDocumentTree = NULL;
-struct PdfDocument {
- char *file_path; // full file name including path
- PDFDoc *doc;
- XRef *xref;
- InObj *inObjList;
- int occurences; // number of references to the PdfDocument; it can be deleted when occurences == 0
-};
-
-/* AVL sort PdfDocument into PdfDocumentTree by file_path */
+// AVL sort PdfDocument into PdfDocumentTree by file_path
-static int CompPdfDocument(const void *pa, const void *pb, void *p)
+static int CompPdfDocument(const void *pa, const void *pb, void * /*p */ )
{
return strcmp(((const PdfDocument *) pa)->file_path,
((const PdfDocument *) pb)->file_path);
@@ -154,8 +56,7 @@ static PdfDocument *findPdfDocument(char *file_path)
PdfDocument *pdf_doc, tmp;
assert(file_path != NULL);
if (PdfDocumentTree == NULL)
- PdfDocumentTree = avl_create(CompPdfDocument, NULL, &avl_xallocator);
- assert(PdfDocumentTree != NULL);
+ return NULL;
tmp.file_path = file_path;
pdf_doc = (PdfDocument *) avl_find(PdfDocumentTree, &tmp);
return pdf_doc;
@@ -164,26 +65,35 @@ static PdfDocument *findPdfDocument(char *file_path)
// Returns pointer to PdfDocument structure for PDF file.
// Creates a new structure if it doesn't exist yet.
-static PdfDocument *refPdfDocument(char *file_path)
+char *get_file_checksum(char *a);
+
+PdfDocument *refPdfDocument(char *file_path)
{
PdfDocument *pdf_doc = findPdfDocument(file_path);
if (pdf_doc == NULL) {
+ if (PdfDocumentTree == NULL)
+ PdfDocumentTree =
+ avl_create(CompPdfDocument, NULL, &avl_xallocator);
pdf_doc = new PdfDocument;
pdf_doc->file_path = xstrdup(file_path);
+ pdf_doc->checksum = get_file_checksum(file_path);
void **aa = avl_probe(PdfDocumentTree, pdf_doc);
assert(aa != NULL);
+ pdf_doc->ObjMapTree = NULL;
+ pdf_doc->doc = NULL;
+ }
+ if (pdf_doc->doc == NULL) {
GString *docName = new GString(pdf_doc->file_path);
pdf_doc->doc = new PDFDoc(docName); // takes ownership of docName
if (!pdf_doc->doc->isOk() || !pdf_doc->doc->okToPrint())
pdftex_fail("xpdf: reading PDF image failed");
- pdf_doc->xref = NULL;
pdf_doc->inObjList = NULL;
pdf_doc->occurences = 0; // 0 = unreferenced
+ }
#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Creating %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
+ fprintf(stderr, "\nluatex Debug: Creating %s (%d)\n",
+ pdf_doc->file_path, pdf_doc->occurences);
#endif
- }
pdf_doc->occurences++;
#ifdef DEBUG
fprintf(stderr, "\nluatex Debug: Incrementing %s (%d)\n",
@@ -192,293 +102,94 @@ static PdfDocument *refPdfDocument(char *file_path)
return pdf_doc;
}
-static void deletePdfDocument(PdfDocument *);
+//**********************************************************************
+// AVL sort ObjMap into ObjMapTree by object number and generation
-// Called when an image has been written and its resources in image_tab are
-// freed and it's not referenced anymore.
+// keep the ObjMap struct small, as these are accumulated until the end
-void unrefPdfDocument(char *file_path)
+struct ObjMap {
+ Ref in; // object num/gen in orig. PDF file
+ int out_num; // object num after embedding (gen == 0)
+};
+
+static int CompObjMap(const void *pa, const void *pb, void * /*p */ )
{
- PdfDocument *pdf_doc = findPdfDocument(file_path);
- assert(pdf_doc != NULL);
- assert(pdf_doc->occurences > 0); // aim for point landing
- pdf_doc->occurences--;
-#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Decrementing %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
- if (pdf_doc->occurences == 0) {
-#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Deleting %s\n", pdf_doc->file_path);
-#endif
- void *a = avl_delete(PdfDocumentTree, pdf_doc);
- assert((PdfDocument *) a == pdf_doc);
- deletePdfDocument(pdf_doc);
- }
+ const Ref *a = &(((const ObjMap *) pa)->in);
+ const Ref *b = &(((const ObjMap *) pb)->in);
+ if (a->num > b->num)
+ return 1;
+ if (a->num < b->num)
+ return -1;
+ if (a->gen == b->gen) // most likely gen == 0 anyway
+ return 0;
+ if (a->gen < b->gen)
+ return -1;
+ return 1;
}
-//**********************************************************************
-
-// Replacement for
-// Object *initDict(Dict *dict1){ initObj(objDict); dict = dict1; return this; }
-
-static void initDictFromDict(PdfObject & obj, Dict * dict)
+static ObjMap *findObjMap(PdfDocument * pdf_doc, Ref in)
{
- obj->initDict(xref);
- for (int i = 0, l = dict->getLength(); i < l; i++) {
- Object obj1;
- obj->dictAdd(copyString(dict->getKey(i)), dict->getValNF(i, &obj1));
- }
+ ObjMap *obj_map, tmp;
+ assert(pdf_doc != NULL);
+ if (pdf_doc->ObjMapTree == NULL)
+ return NULL;
+ tmp.in = in;
+ obj_map = (ObjMap *) avl_find(pdf_doc->ObjMapTree, &tmp);
+ return obj_map;
}
-static int addEncoding(GfxFont * gfont)
+static void addObjMap(PdfDocument * pdf_doc, Ref in, int out_num)
{
- UsedEncoding *n;
- n = new UsedEncoding;
- n->next = encodingList;
- encodingList = n;
- n->font = gfont;
- n->enc_objnum = pdf_new_objnum();
- return n->enc_objnum;
+ ObjMap *obj_map = NULL;
+ assert(findObjMap(pdf_doc, in) == NULL);
+ if (pdf_doc->ObjMapTree == NULL)
+ pdf_doc->ObjMapTree = avl_create(CompObjMap, NULL, &avl_xallocator);
+ obj_map = new ObjMap;
+ obj_map->in = in;
+ obj_map->out_num = out_num;
+ void **aa = avl_probe(pdf_doc->ObjMapTree, obj_map);
+ assert(aa != NULL);
}
-#define addFont(ref, fd, enc_objnum) \
- addInObj(objFont, ref, fd, enc_objnum)
+// When copying the Resources of the selected page, all objects are
+// copied recursively top-down. The findObjMap() function checks if an
+// object has already been copied; if so, instead of copying just the
+// new object number will be referenced. The ObjMapTree guarantees,
+// that during the entire LuaTeX run any object from any embedded PDF
+// file will end up max. once in the output PDF file. Indirect objects
+// are not fetched during copying, but get a new object number from
+// LuaTeX and then will be appended into a linked list.
-// addFontDesc is only used to avoid writing the original FontDescriptor
-// from the PDF file.
-
-#define addFontDesc(ref, fd) \
- addInObj(objFontDesc, ref, fd, 0)
-
-#define addOther(ref) \
- addInObj(objOther, ref, NULL, 0)
-
-static int addInObj(InObjType type, Ref ref, fd_entry * fd, integer e)
+static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref)
{
- InObj *p, *q, *n = new InObj;
- if (ref.num == 0)
- pdftex_fail("PDF inclusion: invalid reference");
+ ObjMap *obj_map;
+ InObj *p, *q, *n;
+ if (ref.num == 0) {
+ pdftex_fail("PDF inclusion: reference to invalid object"
+ " (is the included pdf broken?)");
+ }
+ if ((obj_map = findObjMap(pdf_doc, ref)) != NULL)
+ return obj_map->out_num;
+ n = new InObj;
n->ref = ref;
- n->type = type;
n->next = NULL;
- n->fd = fd;
- n->enc_objnum = e;
- n->written = 0;
- if (inObjList == NULL)
- inObjList = n;
+ n->num = pdf_new_objnum(pdf);
+ addObjMap(pdf_doc, ref, n->num);
+ if (pdf_doc->inObjList == NULL)
+ pdf_doc->inObjList = n;
else {
- for (p = inObjList; p != NULL; p = p->next) {
- if (p->ref.num == ref.num && p->ref.gen == ref.gen) {
- delete n;
- return p->num;
- }
- q = p;
- }
// it is important to add new objects at the end of the list,
// because new objects are being added while the list is being
// written out by writeRefs().
+ for (p = pdf_doc->inObjList; p != NULL; p = p->next)
+ q = p;
q->next = n;
}
- if (type == objFontDesc)
- n->num = get_fd_objnum(fd);
- else
- n->num = pdf_new_objnum();
return n->num;
}
-static void copyName(char *s)
-{
- pdf_puts("/");
- for (; *s != 0; s++) {
- if (isdigit(*s) || isupper(*s) || islower(*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)
-{
- PdfObject obj1;
- copyName(obj->dictGetKey(i));
- pdf_puts(" ");
- obj->dictGetValNF(i, &obj1);
- copyObject(&obj1);
- pdf_puts("\n");
-}
-
-static void copyDict(Object * obj)
-{
- int i, l;
- if (!obj->isDict())
- pdftex_fail("PDF inclusion: invalid dict type <%s>",
- obj->getTypeName());
- for (i = 0, l = obj->dictGetLength(); i < l; ++i)
- copyDictEntry(obj, i);
-}
-
-static void copyFontDict(Object * obj, InObj * r)
-{
- int i, l;
- char *key;
- if (!obj->isDict())
- pdftex_fail("PDF inclusion: invalid dict type <%s>",
- obj->getTypeName());
- pdf_puts("<<\n");
- assert(r->type == objFont); // FontDescriptor is in fd_tree
- for (i = 0, l = obj->dictGetLength(); i < l; ++i) {
- key = obj->dictGetKey(i);
- if (strncmp("FontDescriptor", key, strlen("FontDescriptor")) == 0
- || strncmp("BaseFont", key, strlen("BaseFont")) == 0
- || strncmp("Encoding", key, strlen("Encoding")) == 0)
- continue; // skip original values
- copyDictEntry(obj, i);
- }
- // write new FontDescriptor, BaseFont, and Encoding
- pdf_printf("/FontDescriptor %d 0 R\n", (int) get_fd_objnum(r->fd));
- pdf_printf("/BaseFont %d 0 R\n", (int) get_fn_objnum(r->fd));
- pdf_printf("/Encoding %d 0 R\n", (int) r->enc_objnum);
- pdf_puts(">>");
-}
-
-static void copyStream(Stream * str)
-{
- int c;
- str->reset();
- while ((c = str->getChar()) != EOF) {
- pdfout(c);
- pdf_last_byte = c;
- }
-}
-
-static void copyProcSet(Object * obj)
-{
- int i, l;
- PdfObject procset;
- if (!obj->isArray())
- pdftex_fail("PDF inclusion: invalid ProcSet array type <%s>",
- obj->getTypeName());
- pdf_puts("/ProcSet [ ");
- for (i = 0, l = obj->arrayGetLength(); i < l; ++i) {
- obj->arrayGetNF(i, &procset);
- if (!procset->isName())
- pdftex_fail("PDF inclusion: invalid ProcSet entry type <%s>",
- procset->getTypeName());
- copyName(procset->getName());
- pdf_puts(" ");
- }
- pdf_puts("]\n");
-}
-
-#define REPLACE_TYPE1C true
-
-static void copyFont(char *tag, Object * fontRef)
-{
- PdfObject fontdict, subtype, basefont, fontdescRef, fontdesc, charset,
- fontfile, ffsubtype, stemV;
- GfxFont *gfont;
- fd_entry *fd;
- fm_entry *fontmap;
- // Check whether the font has already been embedded before analysing it.
- InObj *p;
- Ref ref = fontRef->getRef();
- for (p = inObjList; p; p = p->next) {
- if (p->ref.num == ref.num && p->ref.gen == ref.gen) {
- copyName(tag);
- pdf_printf(" %d 0 R ", (int) p->num);
- return;
- }
- }
- // 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_inclusion_copy_font && fontRef->fetch(xref, &fontdict)->isDict()
- && fontdict->dictLookup("Subtype", &subtype)->isName()
- && !strcmp(subtype->getName(), "Type1")
- && fontdict->dictLookup("BaseFont", &basefont)->isName()
- && fontdict->dictLookupNF("FontDescriptor", &fontdescRef)->isRef()
- && fontdescRef->fetch(xref, &fontdesc)->isDict()
- && (fontdesc->dictLookup("FontFile", &fontfile)->isStream()
- || (REPLACE_TYPE1C
- && fontdesc->dictLookup("FontFile3", &fontfile)->isStream()
- && fontfile->streamGetDict()->lookup("Subtype",
- &ffsubtype)->isName()
- && !strcmp(ffsubtype->getName(), "Type1C")))
- && (fontmap = lookup_fontmap(basefont->getName())) != NULL) {
- // 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());
- else
- embed_whole_font(fd);
- addFontDesc(fontdescRef->getRef(), fd);
- copyName(tag);
- gfont = GfxFont::makeFont(xref, tag, fontRef->getRef(),
- fontdict->getDict());
- pdf_printf(" %d 0 R ", addFont(fontRef->getRef(), fd,
- addEncoding(gfont)));
- } else {
- copyName(tag);
- pdf_puts(" ");
- copyObject(fontRef);
- }
-}
-
-static void copyFontResources(Object * obj)
-{
- PdfObject fontRef;
- int i, l;
- if (!obj->isDict())
- pdftex_fail("PDF inclusion: invalid font resources dict type <%s>",
- obj->getTypeName());
- pdf_puts("/Font << ");
- for (i = 0, l = obj->dictGetLength(); i < l; ++i) {
- obj->dictGetValNF(i, &fontRef);
- if (fontRef->isRef())
- copyFont(obj->dictGetKey(i), &fontRef);
- else
- pdftex_fail("PDF inclusion: invalid font in reference type <%s>",
- fontRef->getTypeName());
- }
- pdf_puts(">>\n");
-}
-
-static void copyOtherResources(Object * obj, char *key)
-{
- // copies all other resources (write_epdf handles Fonts and ProcSets),
- // but gives a warning if an object is not a dictionary.
-
- if (!obj->isDict())
- //FIXME: Write the message only to the log file
- pdftex_warn("PDF inclusion: invalid other resource which is no dict"
- " (key '%s', type <%s>); copying it anyway.",
- key, obj->getTypeName());
- copyName(key);
- pdf_puts(" ");
- copyObject(obj);
-}
-
-// Function onverts double to string; very small and very large numbers
+//**********************************************************************
+// Function converts double to string; very small and very large numbers
// are NOT converted to scientific notation.
// n must be a number or real conforming to the implementation limits
// of PDF as specified in appendix C.1 of the PDF Ref.
@@ -536,165 +247,215 @@ static char *convertNumToPDF(double n)
return (char *) buf;
}
-static void copyObject(Object * obj)
+static void copyObject(PDF, PdfDocument *, Object *);
+
+static void copyString(PDF pdf, GString * string)
{
- PdfObject obj1;
- int i, l, c;
- Ref ref;
char *p;
- GString *s;
- if (obj->isBool()) {
- pdf_printf("%s", obj->getBool()? "true" : "false");
- } else if (obj->isInt()) {
- pdf_printf("%i", obj->getInt());
- } else if (obj->isReal()) {
- pdf_printf("%s", convertNumToPDF(obj->getReal()));
- } else if (obj->isNum()) {
- pdf_printf("%s", convertNumToPDF(obj->getNum()));
- } else if (obj->isString()) {
- s = obj->getString();
- p = s->getCString();
- l = s->getLength();
- if (strlen(p) == (unsigned int) l) {
- pdf_puts("(");
- for (; *p != 0; p++) {
- c = (unsigned char) *p;
- if (c == '(' || c == ')' || c == '\\')
- pdf_printf("\\%c", c);
- else if (c < 0x20 || c > 0x7F)
- pdf_printf("\\%03o", c);
- else
- pdfout(c);
- }
- pdf_puts(")");
- } else {
- pdf_puts("<");
- for (i = 0; i < l; i++) {
- c = s->getChar(i) & 0xFF;
- pdf_printf("%.2x", c);
- }
- pdf_puts(">");
- }
- } else if (obj->isName()) {
- copyName(obj->getName());
- } else if (obj->isNull()) {
- pdf_puts("null");
- } else if (obj->isArray()) {
- pdf_puts("[");
- for (i = 0, l = obj->arrayGetLength(); i < l; ++i) {
- obj->arrayGetNF(i, &obj1);
- if (!obj1->isName())
- pdf_puts(" ");
- copyObject(&obj1);
+ unsigned char c;
+ size_t i, l;
+ p = string->getCString();
+ l = (size_t) string->getLength();
+ if (strlen(p) == l) {
+ pdf_puts(pdf, "(");
+ for (; *p != 0; p++) {
+ c = (unsigned char) *p;
+ if (c == '(' || c == ')' || c == '\\')
+ pdf_printf(pdf, "\\%c", c);
+ else if (c < 0x20 || c > 0x7F)
+ pdf_printf(pdf, "\\%03o", (int) c);
+ else
+ pdf_out(pdf, c);
}
- pdf_puts("]");
- } else if (obj->isDict()) {
- pdf_puts("<<\n");
- copyDict(obj);
- pdf_puts(">>");
- } else if (obj->isStream()) {
- initDictFromDict(obj1, obj->streamGetDict());
- obj->streamGetDict()->incRef();
- pdf_puts("<<\n");
- copyDict(&obj1);
- pdf_puts(">>\n");
- pdf_puts("stream\n");
- 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_fail
- ("PDF inclusion: reference to invalid object"
- " (is the included pdf broken?)");
- } else
- pdf_printf("%d 0 R", addOther(ref));
+ pdf_puts(pdf, ")");
} else {
- pdftex_fail("PDF inclusion: type <%s> cannot be copied",
- obj->getTypeName());
+ pdf_puts(pdf, "<");
+ for (i = 0; i < l; i++) {
+ c = (unsigned char) string->getChar(i);
+ pdf_printf(pdf, "%.2x", (int) c);
+ }
+ pdf_puts(pdf, ">");
}
}
-static void writeRefs()
+static void copyName(PDF pdf, char *s)
{
- InObj *r;
- for (r = inObjList; r != NULL; r = r->next) {
- if (!r->written) {
- Object obj1;
- r->written = 1;
- xref->fetch(r->ref.num, r->ref.gen, &obj1);
- if (r->type == objFont) {
- assert(!obj1.isStream());
- zpdf_begin_obj(r->num, 2); // \pdfobjcompresslevel = 2 is for this
- copyFontDict(&obj1, r);
- pdf_puts("\n");
- pdf_end_obj();
- } else if (r->type != objFontDesc) { // /FontDescriptor is written via write_fontdescriptor()
- if (obj1.isStream())
- zpdf_begin_obj(r->num, 0);
- else
- zpdf_begin_obj(r->num, 2); // \pdfobjcompresslevel = 2 is for this
- copyObject(&obj1);
- pdf_puts("\n");
- pdf_end_obj();
- }
- obj1.free();
- }
+ pdf_puts(pdf, "/");
+ for (; *s != 0; s++) {
+ if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' ||
+ *s == '.' || *s == '-' || *s == '+')
+ pdf_out(pdf, *s);
+ else
+ pdf_printf(pdf, "#%.2X", *s & 0xFF);
}
}
-static void writeEncodings()
+static void copyArray(PDF pdf, PdfDocument * pdf_doc, Array * array)
{
- UsedEncoding *r, *n;
- char *glyphNames[256], *s;
- int i;
- for (r = encodingList; r != NULL; r = r->next) {
- for (i = 0; i < 256; i++) {
- if (r->font->isCIDFont()) {
- 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;
- else
- glyphNames[i] = notdef;
- }
- epdf_write_enc(glyphNames, r->enc_objnum);
+ int i, l;
+ PdfObject obj1;
+ pdf_puts(pdf, "[");
+ for (i = 0, l = array->getLength(); i < l; ++i) {
+ array->getNF(i, &obj1);
+ if (!obj1->isName())
+ pdf_puts(pdf, " ");
+ copyObject(pdf, pdf_doc, &obj1);
+ }
+ pdf_puts(pdf, "]");
+}
+
+static void copyDict(PDF pdf, PdfDocument * pdf_doc, Dict * dict)
+{
+ int i, l;
+ PdfObject obj1;
+ pdf_puts(pdf, "<<");
+ for (i = 0, l = dict->getLength(); i < l; ++i) {
+ copyName(pdf, dict->getKey(i));
+ pdf_puts(pdf, " ");
+ dict->getValNF(i, &obj1);
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
+ }
+ pdf_puts(pdf, ">>");
+}
+
+static void copyStreamStream(PDF pdf, Stream * str)
+{
+ int c;
+ str->reset();
+ while ((c = str->getChar()) != EOF) {
+ pdf_out(pdf, c);
+ pdf->last_byte = c;
+ }
+}
+
+static void copyStream(PDF pdf, PdfDocument * pdf_doc, Stream * stream)
+{
+ copyDict(pdf, pdf_doc, stream->getDict());
+ pdf_puts(pdf, "stream\n");
+ copyStreamStream(pdf, stream->getUndecodedStream());
+ if (pdf->last_byte != '\n')
+ pdf_puts(pdf, "\n");
+ pdf_puts(pdf, "endstream"); // can't simply write pdf_end_stream()
+}
+
+static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj)
+{
+ switch (obj->getType()) {
+ case objBool:
+ pdf_printf(pdf, "%s", obj->getBool()? "true" : "false");
+ break;
+ case objInt:
+ pdf_printf(pdf, "%i", obj->getInt());
+ break;
+ case objReal:
+ pdf_printf(pdf, "%s", convertNumToPDF(obj->getReal()));
+ break;
+ // not needed:
+ // GBool isNum() { return type == objInt || type == objReal; }
+ case objString:
+ copyString(pdf, obj->getString());
+ break;
+ case objName:
+ copyName(pdf, obj->getName());
+ break;
+ case objNull:
+ pdf_puts(pdf, "null");
+ break;
+ case objArray:
+ copyArray(pdf, pdf_doc, obj->getArray());
+ break;
+ case objDict:
+ copyDict(pdf, pdf_doc, obj->getDict());
+ break;
+ case objStream:
+ copyStream(pdf, pdf_doc, obj->getStream());
+ break;
+ case objRef:
+ pdf_printf(pdf, "%d 0 R", addInObj(pdf, pdf_doc, obj->getRef()));
+ break;
+ case objCmd:
+ case objError:
+ case objEOF:
+ case objNone:
+ pdftex_fail("PDF inclusion: type <%s> cannot be copied",
+ obj->getTypeName());
+ break;
+ default:
+ assert(0); // xpdf doesn't have any other types
}
- for (r = encodingList; r != NULL; r = n) {
+}
+
+//**********************************************************************
+
+static void writeRefs(PDF pdf, PdfDocument * pdf_doc)
+{
+ InObj *r, *n;
+ XRef *xref;
+ xref = pdf_doc->doc->getXRef();
+ for (r = pdf_doc->inObjList; r != NULL;) {
+ PdfObject obj1;
+ xref->fetch(r->ref.num, r->ref.gen, &obj1);
+ if (obj1->isStream())
+ pdf_begin_obj(pdf, r->num, 0);
+ else
+ pdf_begin_obj(pdf, r->num, 2); // \pdfobjcompresslevel = 2 is for this
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
+ pdf_end_obj(pdf);
n = r->next;
-#ifdef POPPLER_VERSION
- r->font->decRefCnt();
-#else
- delete r->font;
-#endif
delete r;
+ pdf_doc->inObjList = r = n;
}
}
-// get the pagebox according to the pagebox_spec
+// get the pagebox coordinates according to the pagebox_spec
-static PDFRectangle *get_pagebox(Page * page, integer pagebox_spec)
+static PDFRectangle *get_pagebox(Page * page, int pagebox_spec)
{
- if (pagebox_spec == pdf_box_spec_media)
+ switch (pagebox_spec) {
+ case PDF_BOX_SPEC_MEDIA:
return page->getMediaBox();
- else if (pagebox_spec == pdf_box_spec_crop)
+ break;
+ case PDF_BOX_SPEC_CROP:
return page->getCropBox();
- else if (pagebox_spec == pdf_box_spec_bleed)
+ break;
+ case PDF_BOX_SPEC_BLEED:
return page->getBleedBox();
- else if (pagebox_spec == pdf_box_spec_trim)
+ break;
+ case PDF_BOX_SPEC_TRIM:
return page->getTrimBox();
- else if (pagebox_spec == pdf_box_spec_art)
+ break;
+ case PDF_BOX_SPEC_ART:
return page->getArtBox();
- else
+ break;
+ default:
pdftex_fail("PDF inclusion: unknown value of pagebox spec (%i)",
(int) pagebox_spec);
+ }
return page->getMediaBox(); // to make the compiler happy
}
+#define PDF_CHECKSUM_SIZE 32
+char *get_file_checksum(char *a)
+{
+ struct stat finfo;
+ char *ck = NULL;
+ if (stat(a, &finfo) == 0) {
+ off_t size = finfo.st_size;
+ time_t mtime = finfo.st_mtime;
+ ck = (char *) malloc(PDF_CHECKSUM_SIZE);
+ if (ck == NULL)
+ pdftex_fail("PDF inclusion: out of memory while processing '%s'",
+ a);
+ snprintf(ck, PDF_CHECKSUM_SIZE, "%llu_%llu", (unsigned long long) size,
+ (unsigned long long) mtime);
+ } else {
+ pdftex_fail("PDF inclusion: could not stat() file '%s'", a);
+ }
+ return ck;
+}
+
// Reads various information about the PDF and sets it up for later inclusion.
// This will fail if the PDF version of the PDF is higher than
// minor_pdf_version_wanted or page_name is given and can not be found.
@@ -702,47 +463,37 @@ static PDFRectangle *get_pagebox(Page * page, integer pagebox_spec)
// Returns the page number.
void
-read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted,
- integer pdf_inclusion_errorlevel)
+read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
+ int pdf_inclusion_errorlevel, img_readtype_e readtype)
{
PdfDocument *pdf_doc;
Page *page;
int rotate;
+ char *checksum;
PDFRectangle *pagebox;
-#ifdef HAVE_GETPDFMAJORVERSION
- int pdf_major_version_found, pdf_minor_version_found;
-#else
- float pdf_version_found, pdf_version_wanted;
-#endif
- float xsize, ysize, xorig, yorig;
+ float pdf_version_found, pdf_version_wanted, xsize, ysize, xorig, yorig;
assert(idict != NULL);
assert(img_type(idict) == IMG_TYPE_PDF);
+ assert(readtype == IMG_CLOSEINBETWEEN); // only this is implemented
// initialize
if (isInit == gFalse) {
globalParams = new GlobalParams();
globalParams->setErrQuiet(gFalse);
isInit = gTrue;
}
+ // calculate a checksum string
+ checksum = get_file_checksum(img_filepath(idict));
// open PDF file
pdf_doc = refPdfDocument(img_filepath(idict));
+ if (strncmp(pdf_doc->checksum, checksum, PDF_CHECKSUM_SIZE) != 0) {
+ pdftex_fail("PDF inclusion: file has changed '%s'",
+ img_filename(idict));
+ }
+ free(checksum);
// check PDF version
// this works only for PDF 1.x -- but since any versions of PDF newer
// than 1.x will not be backwards compatible to PDF 1.x, pdfTeX will
// then have to changed drastically anyway.
-#ifdef HAVE_GETPDFMAJORVERSION
- pdf_major_version_found = pdf_doc->doc->getPDFMajorVersion();
- pdf_minor_version_found = pdf_doc->doc->getPDFMinorVersion();
- if ((pdf_major_version_found > 1)
- || (pdf_minor_version_found > minor_pdf_version_wanted)) {
- const char *msg =
- "PDF inclusion: found PDF version <%d.%d>, but at most version <1.%d> allowed";
- if (pdf_inclusion_errorlevel > 0) {
- pdftex_fail(msg, pdf_major_version_found, pdf_minor_version_found, minor_pdf_version_wanted);
- } else {
- pdftex_warn(msg, pdf_major_version_found, pdf_minor_version_found, minor_pdf_version_wanted);
- }
- }
-#else
pdf_version_found = pdf_doc->doc->getPDFVersion();
pdf_version_wanted = 1 + (minor_pdf_version_wanted * 0.1);
if (pdf_version_found > pdf_version_wanted + 0.01) {
@@ -754,7 +505,6 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted,
pdftex_warn(msg, pdf_version_found, pdf_version_wanted);
}
}
-#endif
img_totalpages(idict) = pdf_doc->doc->getCatalog()->getNumPages();
if (img_pagename(idict)) {
// get page by name
@@ -777,11 +527,10 @@ 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.
+ // get the pagebox coordinates (media, crop,...) to use.
pagebox = get_pagebox(page, img_pagebox(idict));
if (pagebox->x2 > pagebox->x1) {
xorig = pagebox->x1;
@@ -824,67 +573,60 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted,
("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;
- }
+ // currently unused info whether PDF contains a /Group
+ if (page->getGroup() != NULL)
+ img_set_group(idict);
+
+ if (readtype == IMG_CLOSEINBETWEEN)
+ unrefPdfDocument(img_filepath(idict));
}
+//**********************************************************************
// Writes the current epf_doc.
-// Here the included PDF is copied, so most errors that can happen during PDF
-// inclusion will arise here.
+// Here the included PDF is copied, so most errors that can happen
+// during PDF inclusion will arise here.
-static void write_epdf1(image_dict * idict)
+static void write_epdf1(PDF pdf, image_dict * idict)
{
+ PdfDocument *pdf_doc;
Page *page;
- PdfObject contents, obj1, obj2;
- PdfObject metadata, pieceinfo, separationInfo;
- Object info;
- char *key;
+ PdfObject info, contents, metadata, obj1;
+ Object *metadataNF, *resourcesNF;
+ char *checksum;
char s[256];
int i, l;
- PdfDocument *pdf_doc = (PdfDocument *) findPdfDocument(img_filepath(idict));
- assert(pdf_doc != NULL);
- xref = pdf_doc->xref;
- inObjList = pdf_doc->inObjList;
- encodingList = NULL;
+ assert(idict != NULL);
+ // calculate a checksum string
+ checksum = get_file_checksum(img_filepath(idict));
+ // open PDF file
+ pdf_doc = refPdfDocument(img_filepath(idict));
+ if (strncmp(pdf_doc->checksum, checksum, PDF_CHECKSUM_SIZE) != 0) {
+ pdftex_fail("PDF inclusion: file has changed '%s'",
+ img_filename(idict));
+ }
+ free(checksum);
+ (void) pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
PDFRectangle *pagebox;
float bbox[4];
// write the Page header
- pdf_puts("/Type /XObject\n/Subtype /Form\n");
+ pdf_puts(pdf, "/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");
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_puts(pdf, "/FormType 1\n");
// write additional information
- pdf_printf("/%s.FileName (%s)\n", pdfkeyprefix,
+ pdf_printf(pdf, "/%s.FileName (%s)\n", pdfkeyprefix,
convertStringToPDFString(pdf_doc->file_path,
strlen(pdf_doc->file_path)));
- pdf_printf("/%s.PageNumber %i\n", pdfkeyprefix, (int) img_pagenum(idict));
+ pdf_printf(pdf, "/%s.PageNumber %i\n", pdfkeyprefix,
+ (int) img_pagenum(idict));
pdf_doc->doc->getDocInfoNF(&info);
- if (info.isRef()) {
+ if (info->isRef()) {
// the info dict must be indirect (PDF Ref p. 61)
- pdf_printf("/%s.InfoDict ", pdfkeyprefix);
- pdf_printf("%d 0 R\n", addOther(info.getRef()));
+ pdf_printf(pdf, "/%s.InfoDict ", pdfkeyprefix);
+ pdf_printf(pdf, "%d 0 R\n", addInObj(pdf, pdf_doc, info->getRef()));
}
if (img_is_bbox(idict)) {
bbox[0] = int2bp(img_bbox(idict)[0]);
@@ -892,7 +634,7 @@ static void write_epdf1(image_dict * idict)
bbox[2] = int2bp(img_bbox(idict)[2]);
bbox[3] = int2bp(img_bbox(idict)[3]);
} else {
- // get the pagebox (media, crop...) to use.
+ // get the pagebox coordinates (media, crop,...) to use.
pagebox = get_pagebox(page, img_pagebox(idict));
bbox[0] = pagebox->x1;
bbox[1] = pagebox->y1;
@@ -901,77 +643,57 @@ static void write_epdf1(image_dict * idict)
}
sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", bbox[0], bbox[1], bbox[2],
bbox[3]);
- pdf_puts(stripzeros(s));
+ pdf_puts(pdf, stripzeros(s));
// The /Matrix calculation is replaced by transforms in out_img().
- // write the page Group if it's there
- if (epdf_lastGroupObjectNum > 0) {
- if (page->getGroup() != NULL) {
- initDictFromDict(lastGroup, page->getGroup());
- if (lastGroup->dictGetLength() > 0) {
- pdf_puts("/Group ");
- groupIsIndirect = lastGroup->isRef();
- pdf_printf("%d 0 R", (int) epdf_lastGroupObjectNum);
- pdf_puts("\n");
- }
- }
+ // Now all relevant parts of the /Page dictionary are copied:
+
+ // write the /Resources dictionary
+ if (page->getResourceDict() == NULL) {
+ // Resources can be missing (files without them have been spotted
+ // in the wild); in which case the /Resouces of the /Page will be used.
+ // "This practice is not recommended".
+ pdftex_warn
+ ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref.)");
+ } else {
+#if 0 // TEMP, waiting for XPDF patch
+ resourcesNF = page->getResourcesNF();
+ pdf_puts(pdf, "/Resources ");
+ copyObject(pdf, pdf_doc, resourcesNF);
+#endif
}
- // write the page Metadata if it's there
+ // write the page /Metadata if it's there (as a stream it must be indirect)
if (page->getMetadata() != NULL) {
- metadata->initStream(page->getMetadata());
- pdf_puts("/Metadata ");
- copyObject(&metadata);
- pdf_puts("\n");
+#if 0 // TEMP, waiting for XPDF patch
+ metadataNF = page->getMetadataNF(); // *NF = "don't resolve indirects"
+ if (!metadataNF->isRef())
+ pdftex_warn("PDF inclusion: /Metadata must be indirect object");
+ else {
+ pdf_printf(pdf, "/Metadata %d 0 R",
+ addInObj(pdf, pdf_doc, metadataNF->getRef()));
+ }
+#endif
}
- // write the page PieceInfo if it's there
+ // write the page /Group if it's there
+ if (page->getGroup() != NULL) {
+ pdf_puts(pdf, "/Group ");
+ copyDict(pdf, pdf_doc, page->getGroup());
+ }
+ // write the page /PieceInfo if it's there
if (page->getPieceInfo() != NULL) {
- initDictFromDict(pieceinfo, page->getPieceInfo());
- if (pieceinfo->dictGetLength() > 0) {
- pdf_puts("/PieceInfo ");
- copyObject(&pieceinfo);
- pdf_puts("\n");
- }
+ pdf_puts(pdf, "/PieceInfo ");
+ copyDict(pdf, pdf_doc, page->getPieceInfo());
+ }
+ // write the page /SeparationInfo if it's there
+ if (page->getSeparationInfo() != NULL) {
+ pdf_puts(pdf, "/SeparationInfo ");
+ copyDict(pdf, pdf_doc, page->getSeparationInfo());
}
// copy LastModified (needed when PieceInfo is there)
if (page->getLastModified() != NULL) {
- pdf_printf("/LastModified (%s)\n",
+ pdf_printf(pdf, "/LastModified (%s)\n",
page->getLastModified()->getCString());
}
- // write the page SeparationInfo if it's there
- if (page->getSeparationInfo() != NULL) {
- initDictFromDict(separationInfo, page->getSeparationInfo());
- if (separationInfo->dictGetLength() > 0) {
- pdf_puts("/SeparationInfo ");
- copyObject(&separationInfo);
- pdf_puts("\n");
- }
- }
- // write the Resources dictionary
- if (page->getResourceDict() == NULL) {
- // Resources can be missing (files without them have been spotted
- // in the wild); in which case the /Resouces of the /Page will be used.
- // "This practice is not recommended".
- pdftex_warn
- ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)");
- } else {
- initDictFromDict(obj1, page->getResourceDict());
- page->getResourceDict()->incRef();
- if (!obj1->isDict())
- pdftex_fail("PDF inclusion: invalid resources dict type <%s>",
- obj1->getTypeName());
- pdf_puts("/Resources <<\n");
- for (i = 0, l = obj1->dictGetLength(); i < l; ++i) {
- obj1->dictGetVal(i, &obj2);
- key = obj1->dictGetKey(i);
- if (strcmp("Font", key) == 0)
- copyFontResources(&obj2);
- else if (strcmp("ProcSet", key) == 0)
- copyProcSet(&obj2);
- else
- copyOtherResources(&obj2, key);
- }
- pdf_puts(">>\n");
- }
// write the page contents
page->getContents(&contents);
if (contents->isStream()) {
@@ -979,84 +701,108 @@ static void write_epdf1(image_dict * idict)
// of \pdfcompresslevel
//
// pdfbeginstream();
- // copyStream(contents->getStream());
+ // copyStreamStream(contents->getStream());
// pdfendstream();
// Variant B: copy stream without recompressing
//
- contents->streamGetDict()->lookup("F", &obj1);
+ contents->streamGetDict()->lookup((char *) "F", &obj1);
if (!obj1->isNull()) {
pdftex_fail("PDF inclusion: Unsupported external stream");
}
- contents->streamGetDict()->lookup("Length", &obj1);
+ contents->streamGetDict()->lookup((char *) "Length", &obj1);
assert(!obj1->isNull());
- pdf_puts("/Length ");
- copyObject(&obj1);
- pdf_puts("\n");
- contents->streamGetDict()->lookup("Filter", &obj1);
+ pdf_puts(pdf, "/Length ");
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
+ contents->streamGetDict()->lookup((char *) "Filter", &obj1);
if (!obj1->isNull()) {
- pdf_puts("/Filter ");
- copyObject(&obj1);
- pdf_puts("\n");
- contents->streamGetDict()->lookup("DecodeParms", &obj1);
+ pdf_puts(pdf, "/Filter ");
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
+ contents->streamGetDict()->lookup((char *) "DecodeParms", &obj1);
if (!obj1->isNull()) {
- pdf_puts("/DecodeParms ");
- copyObject(&obj1);
- pdf_puts("\n");
+ pdf_puts(pdf, "/DecodeParms ");
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
}
}
- pdf_puts(">>\nstream\n");
- copyStream(contents->getStream()->getBaseStream());
- pdf_end_stream();
+ pdf_puts(pdf, ">>\nstream\n");
+ copyStreamStream(pdf, contents->getStream()->getBaseStream());
+ pdf_end_stream(pdf);
} else if (contents->isArray()) {
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
for (i = 0, l = contents->arrayGetLength(); i < l; ++i) {
- Object contentsobj;
- copyStream((contents->arrayGet(i, &contentsobj))->getStream());
- contentsobj.free();
+ PdfObject contentsobj;
+ copyStreamStream(pdf,
+ (contents->arrayGet(i, &contentsobj))->
+ getStream());
+ if (i < (l - 1)) {
+ // put a space between streams to be on the safe side (streams
+ // should have a trailing space here, but one never knows)
+ pdf_puts(pdf, " ");
+ }
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
} else { // the contents are optional, but we need to include an empty stream
- pdf_begin_stream();
- pdf_end_stream();
+ pdf_begin_stream(pdf);
+ pdf_end_stream(pdf);
}
// write out all indirect objects
- writeRefs();
- // write out all used encodings (and delete list)
- writeEncodings();
- // save object list
- pdf_doc->inObjList = inObjList;
- assert(xref == pdf_doc->xref); // xref should be unchanged
+ writeRefs(pdf, pdf_doc);
}
-void write_epdf(image_dict * idict)
+// this relay function is needed to keep some destructor quiet (???)
+
+void write_epdf(PDF pdf, image_dict * idict)
{
- assert(idict != NULL);
- write_epdf1(idict);
+ write_epdf1(pdf, idict);
unrefPdfDocument(img_filepath(idict));
}
//**********************************************************************
// Deallocate a PdfDocument with all its resources
-static void deletePdfDocument(PdfDocument * pdf_doc)
+static void deletePdfDocumentPdfDoc(PdfDocument * pdf_doc)
{
- assert(pdf_doc != NULL);
- // free PdfDocument's resources
InObj *r, *n;
+ assert(pdf_doc != NULL);
+ // this may be probably needed for an emergency destroyPdfDocument()
for (r = pdf_doc->inObjList; r != NULL; r = n) {
n = r->next;
delete r;
}
delete pdf_doc->doc;
- xfree(pdf_doc->file_path);
- delete pdf_doc;
+ pdf_doc->doc = NULL;
}
-static void destroyPdfDocument(void *pa, void *pb)
+static void destroyPdfDocument(void *pa, void * /*pb */ )
{
PdfDocument *pdf_doc = (PdfDocument *) pa;
- deletePdfDocument(pdf_doc);
+ deletePdfDocumentPdfDoc(pdf_doc);
+ // TODO: delete rest of pdf_doc
+}
+
+// Called when an image has been written and its resources in image_tab are
+// freed and it's not referenced anymore.
+
+void unrefPdfDocument(char *file_path)
+{
+ PdfDocument *pdf_doc = findPdfDocument(file_path);
+ assert(pdf_doc != NULL);
+ assert(pdf_doc->occurences > 0); // aim for point landing
+ pdf_doc->occurences--;
+#ifdef DEBUG
+ fprintf(stderr, "\nluatex Debug: Decrementing %s (%d)\n",
+ pdf_doc->file_path, pdf_doc->occurences);
+#endif
+ if (pdf_doc->occurences == 0) {
+#ifdef DEBUG
+ fprintf(stderr, "\nluatex Debug: Deleting %s\n", pdf_doc->file_path);
+#endif
+ assert(pdf_doc->inObjList == NULL); // should be eaten up already
+ deletePdfDocumentPdfDoc(pdf_doc);
+ }
}
// Called when PDF embedding system is finalized.
@@ -1071,14 +817,3 @@ 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/pdftoepdf.h b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
index 50d89c0a861..05bb85eeaa5 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
@@ -18,22 +18,20 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: pdftoepdf.h 2331 2009-04-18 16:39:50Z hhenkel $ */
+/* $Id: pdftoepdf.h 3319 2009-12-27 20:05:36Z hhenkel $ */
#ifndef PDFTOEPDF_H
# define PDFTOEPDF_H
# include "image.h"
-void read_pdf_info(image_dict *, integer, integer);
+void read_pdf_info(image_dict *, int, int, img_readtype_e);
void unrefPdfDocument(char *);
-void write_additional_epdf_objects(void);
-void write_epdf(image_dict *);
+void write_epdf(PDF, image_dict *);
void epdf_check_mem(void);
/* epdf.c --- this should go in an own header file */
-extern integer get_fontfile_num(int);
-extern integer get_fontname_num(int);
+
extern void epdf_free(void);
#endif /* PDFTOEPDF_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.c b/Build/source/texk/web2c/luatexdir/image/writeimg.c
deleted file mode 100644
index f570fd46996..00000000000
--- a/Build/source/texk/web2c/luatexdir/image/writeimg.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/* writeimg.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include <assert.h>
-#include "ptexlib.h"
-#include <kpathsea/c-auto.h>
-#include <kpathsea/c-memstr.h>
-
-#include "image.h"
-#include "writejpg.h"
-#include "writepng.h"
-#include "writejbig2.h"
-#include "pdftoepdf.h"
-
-#include <../lua51/lua.h>
-#include <../lua51/lauxlib.h>
-
-static const char _svn_version[] =
- "$Id: writeimg.c 2448 2009-06-08 07:43:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writeimg.c $";
-
-/**********************************************************************/
-/*
- Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek.
-
- Function "readimage" performs some basic initializations.
- Then it looks at the file extension to determine the
- image type and calls specific code/functions.
- The main disadvantage is that standard file extensions
- have to be used, otherwise pdfTeX is not able to detect
- the correct image type.
-
- The patch now looks at the file header first regardless of
- the file extension. This is implemented in function
- "check_type_by_header". If this check fails, the traditional
- test of standard file extension is tried, done in function
- "check_type_by_extension".
-
- Magic headers:
-
- * "PNG (Portable Network Graphics) Specification", Version 1.2
- (http://www.libpng.org/pub/png):
-
- | 3.1. PNG file signature
- |
- | The first eight bytes of a PNG file always contain the following
- | (decimal) values:
- |
- | 137 80 78 71 13 10 26 10
-
- Translation to C: "\x89PNG\r\n\x1A\n"
-
- * "JPEG File Interchange Format", Version 1.02:
-
- | o you can identify a JFIF file by looking for the following
- | sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>,
- | "JFIF", X'00'.
-
- Function "check_type_by_header" only looks at the first two bytes:
- "\xFF\xD8"
-
- * ISO/IEC JTC 1/SC 29/WG 1
- (ITU-T SG8)
- Coding of Still Pictures
- Title: 14492 FCD
- Source: JBIG Committee
- Project: JTC 1.29.10
- Status: Final Committee Draft
-
- | D.4.1, ID string
- |
- | This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A
- | 0x1A 0x0A.
-
- * "PDF Reference", third edition:
- * The first line should contain "%PDF-1.0" until "%PDF-1.4"
- (section 3.4.1 "File Header").
- * The "implementation notes" say:
-
- | 3.4.1, File Header
- | 12. Acrobat viewers require only that the header appear
- | somewhere within the first 1024 bytes of the file.
- | 13. Acrobat viewers will also accept a header of the form
- | %!PS-Adobe-N.n PDF-M.m
-
- The check in function "check_type_by_header" only implements
- the first issue. The implementation notes are not considered.
- Therefore files with garbage at start of file must have the
- standard extension.
-
- Functions "check_type_by_header" and "check_type_by_extension":
- 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 IMG_TYPE_NONE indicates that a
- type has been found.
-*/
-
-#define HEADER_JPG "\xFF\xD8"
-#define HEADER_PNG "\x89PNG\r\n\x1A\n"
-#define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A"
-#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;
- FILE *file = NULL;
- char header[MAX_HEADER];
-
- assert(idict != NULL);
- if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
- return;
- /* read the header */
- file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);
- for (i = 0; (unsigned) i < MAX_HEADER; i++) {
- header[i] = xgetc(file);
- if (feof(file))
- pdftex_fail("reading image file failed");
- }
- xfclose(file, img_filepath(idict));
- /* tests */
- if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0)
- img_type(idict) = IMG_TYPE_JPG;
- else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0)
- img_type(idict) = IMG_TYPE_PNG;
- else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0)
- img_type(idict) = IMG_TYPE_JBIG2;
- else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0)
- img_type(idict) = IMG_TYPE_PDF;
-}
-
-static void check_type_by_extension(image_dict * idict)
-{
- char *image_suffix;
-
- assert(idict != NULL);
- if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
- return;
- /* tests */
- if ((image_suffix = strrchr(img_filename(idict), '.')) == 0)
- img_type(idict) = IMG_TYPE_NONE;
- else if (strcasecmp(image_suffix, ".png") == 0)
- img_type(idict) = IMG_TYPE_PNG;
- else if (strcasecmp(image_suffix, ".jpg") == 0 ||
- strcasecmp(image_suffix, ".jpeg") == 0)
- img_type(idict) = IMG_TYPE_JPG;
- else if (strcasecmp(image_suffix, ".jbig2") == 0 ||
- strcasecmp(image_suffix, ".jb2") == 0)
- img_type(idict) = IMG_TYPE_JBIG2;
- else if (strcasecmp(image_suffix, ".pdf") == 0)
- 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;
-}
-
-/**********************************************************************/
-
-void init_image(image * p)
-{
- assert(p != NULL);
- set_wd_running(p);
- set_ht_running(p);
- set_dp_running(p);
- img_transform(p) = 0;
- img_flags(p) = 0;
- img_unset_scaled(p);
- img_dict(p) = NULL;
- img_arrayidx(p) = -1; /* -1 = unused, used count from 0 */
- img_dictref(p) = LUA_NOREF;
-}
-
-image *new_image(void)
-{
- image *p = xtalloc(1, image);
- init_image(p);
- return p;
-}
-
-void init_image_dict(image_dict * p)
-{
- assert(p != NULL);
- img_objnum(p) = 0;
- img_index(p) = 0;
- img_xsize(p) = 0;
- img_ysize(p) = 0;
- img_xorig(p) = 0;
- 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;
- img_filename(p) = NULL;
- img_filepath(p) = NULL;
- img_attr(p) = NULL;
- img_file(p) = NULL;
- 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 */
-}
-
-image_dict *new_image_dict(void)
-{
- image_dict *p = xtalloc(1, image_dict);
- init_image_dict(p);
- return p;
-}
-
-static void free_dict_strings(image_dict * p)
-{
- if (img_filename(p) != NULL)
- xfree(img_filename(p));
- img_filename(p) = NULL;
- if (img_filepath(p) != NULL)
- xfree(img_filepath(p));
- img_filepath(p) = NULL;
- if (img_attr(p) != NULL)
- xfree(img_attr(p));
- img_attr(p) = NULL;
- if (img_pagename(p) != NULL)
- xfree(img_pagename(p));
- img_pagename(p) = NULL;
-}
-
-void free_image_dict(image_dict * p)
-{
- 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 IMG_TYPE_PDF:
- unrefPdfDocument(img_filepath(p));
- break;
- case IMG_TYPE_PNG: /* assuming IMG_CLOSEINBETWEEN */
- assert(img_png_ptr(p) == NULL);
- break;
- case IMG_TYPE_JPG: /* assuming IMG_CLOSEINBETWEEN */
- assert(img_jpg_ptr(p) == NULL);
- break;
- case IMG_TYPE_JBIG2: /* todo: writejbig2.c cleanup */
- break;
- 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);
- }
- free_dict_strings(p);
- assert(img_file(p) == NULL);
- xfree(p);
-}
-
-/**********************************************************************/
-
-void pdf_print_resname_prefix(void)
-{
- if (pdf_resname_prefix != 0)
- pdf_printf(makecstring(pdf_resname_prefix));
-}
-
-void read_img(image_dict * idict, integer pdf_minor_version,
- integer pdf_inclusion_errorlevel)
-{
- char *filepath;
- int callback_id;
- assert(idict != NULL);
- if (img_filename(idict) == NULL)
- pdftex_fail("image file name missing");
- callback_id = callback_defined(find_image_file_callback);
- if (img_filepath(idict) == NULL) {
- if (callback_id > 0
- && run_callback(callback_id, "S->S", img_filename(idict),
- &filepath)) {
- if (filepath && (strlen(filepath) > 0))
- img_filepath(idict) = strdup(filepath);
- } else
- img_filepath(idict) =
- kpse_find_file(img_filename(idict), kpse_tex_format, true);
- }
- 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 IMG_TYPE_PDF:
- read_pdf_info(idict, pdf_minor_version, pdf_inclusion_errorlevel);
- img_group_ref(idict) = epdf_lastGroupObjectNum;
- break;
- case IMG_TYPE_PNG:
- read_png_info(idict, IMG_CLOSEINBETWEEN);
- break;
- case IMG_TYPE_JPG:
- read_jpg_info(idict, IMG_CLOSEINBETWEEN);
- break;
- 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",
- (int) pdf_minor_version);
- }
- read_jbig2_info(idict);
- break;
- default:
- 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, 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);
- 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 (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 (img_type(idict) == IMG_TYPE_PDF
- || img_type(idict) == IMG_TYPE_PDFSTREAM) {
- w = x;
- h = y;
- } else {
- default_res = fix_int(get_pdf_image_resolution(), 0, 65535);
- if (default_res > 0 && (xr == 0 || yr == 0)) {
- xr = default_res;
- yr = default_res;
- }
- if (is_wd_running(img) && is_ht_running(img)) {
- if (xr > 0 && yr > 0) {
- w = ext_xn_over_d(one_hundred_inch, x, 100 * xr);
- h = ext_xn_over_d(one_hundred_inch, y, 100 * yr);
- } else {
- w = ext_xn_over_d(one_hundred_inch, x, 7200);
- h = ext_xn_over_d(one_hundred_inch, y, 7200);
- }
- }
- }
- if (is_wd_running(img) && is_ht_running(img) && is_dp_running(img)) {
- img_width(img) = w;
- img_height(img) = h;
- img_depth(img) = 0;
- } else if (is_wd_running(img)) {
- /* image depth or height is explicitly specified */
- if (is_ht_running(img)) {
- /* image depth is explicitly specified */
- img_width(img) = ext_xn_over_d(h, x, y);
- img_height(img) = h - img_depth(img);
- } else if (is_dp_running(img)) {
- /* image height is explicitly specified */
- img_width(img) = ext_xn_over_d(img_height(img), x, y);
- img_depth(img) = 0;
- } else {
- /* both image depth and height are explicitly specified */
- img_width(img) =
- ext_xn_over_d(img_height(img) + img_depth(img), x, y);
- }
- } else {
- /* image width is explicitly specified */
- if (is_ht_running(img) && is_dp_running(img)) {
- /* both image depth and height are not specified */
- img_height(img) = ext_xn_over_d(img_width(img), y, x);
- img_depth(img) = 0;
- }
- /* image depth is explicitly specified */
- else if (is_ht_running(img)) {
- img_height(img) =
- ext_xn_over_d(img_width(img), y, x) - img_depth(img);
- }
- /* image height is explicitly specified */
- else if (is_dp_running(img)) {
- img_depth(img) = 0;
- }
- /* else both image depth and height are explicitly specified */
- }
- img_set_scaled(img);
-}
-
-static 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 */
- 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);
- a[0] = a[3] = 1.0e6;
- a[1] = a[2] = 0;
- 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 {
- /* 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;
- }
- if ((img_transform(img) & 7) > 3) { // mirror cases
- a[0] *= -1;
- xoff *= -1;
- }
- switch ((img_transform(img) + img_rotation(idict)) & 3) {
- case 0: /* no transform */
- break;
- case 1: /* rot. 90 deg. (counterclockwise) */
- a[1] = a[0];
- a[2] = -a[3];
- a[3] = a[0] = 0;
- tmp = yoff;
- yoff = xoff;
- xoff = -tmp;
- break;
- case 2: /* rot. 180 deg. (counterclockwise) */
- a[0] *= -1;
- a[3] *= -1;
- xoff *= -1;
- yoff *= -1;
- break;
- case 3: /* rot. 270 deg. (counterclockwise) */
- a[1] = -a[0];
- a[2] = a[3];
- a[3] = a[0] = 0;
- tmp = yoff;
- yoff = -xoff;
- xoff = tmp;
- break;
- default:;
- }
- xoff *= wd;
- yoff *= ht + dp;
- a[0] *= wd;
- a[1] *= ht + dp;
- a[2] *= wd;
- a[3] *= ht + dp;
- 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 */
- break;
- case 1: /* rot. 90 deg. (counterclockwise) */
- a[4] += wd;
- break;
- case 2: /* rot. 180 deg. */
- a[4] += wd;
- a[5] += ht + dp;
- break;
- case 3: /* rot. 270 deg. */
- a[5] += ht + dp;
- break;
- default:;
- }
- /* 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_cm(cm);
- pdf_printf("/Im");
- pdf_print_int(img_index(idict));
- pdf_print_resname_prefix();
- pdf_printf(" Do\nQ\n");
- if (img_state(idict) < DICT_OUTIMG)
- img_state(idict) = DICT_OUTIMG;
-}
-
-void write_img(image_dict * idict)
-{
- assert(idict != NULL);
- if (img_state(idict) < DICT_WRITTEN) {
- if (tracefilenames)
- tex_printf(" <%s", img_filepath(idict));
- switch (img_type(idict)) {
- case IMG_TYPE_PNG:
- write_png(idict);
- break;
- case IMG_TYPE_JPG:
- write_jpg(idict);
- break;
- case IMG_TYPE_JBIG2:
- write_jbig2(idict);
- break;
- 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 (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;
-}
-
-/**********************************************************************/
-
-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 */
-/* avoid use of size_t */
-img_entry *img_ptr, *img_array = NULL;
-size_t img_limit;
-
-integer img_to_array(image * img)
-{
- assert(img != NULL);
- alloc_array(img, 1, SMALL_BUF_SIZE);
- *img_ptr = 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, str_number filename,
- integer page_num, str_number page_name, str_number attr,
- integer colorspace, integer page_box,
- integer pdf_minor_version, integer pdf_inclusion_errorlevel)
-{
- image_dict *idict;
- 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;
- img_index(idict) = index;
- /* img_xsize, img_ysize, img_xres, img_yres set by read_img() */
- img_colorspace(idict) = colorspace;
- img_pagenum(idict) = page_num;
- /* img_totalpages set by read_img() */
- if (page_name != 0)
- img_pagename(idict) = xstrdup(makecstring(page_name));
- cur_file_name = makecfilename(filename);
- assert(cur_file_name != NULL);
- img_filename(idict) = xstrdup(cur_file_name);
- if (attr != 0)
- img_attr(idict) = xstrdup(makecstring(attr));
- img_pagebox(idict) = page_box;
- read_img(idict, pdf_minor_version, pdf_inclusion_errorlevel);
- img_unset_scaled(a);
- return img_arrayidx(a);
-}
-
-void set_image_dimensions(integer ref, integer wd, integer ht, integer dp)
-{
- image *a = img_array[ref];
- img_width(a) = wd;
- img_height(a) = ht;
- img_depth(a) = dp;
-}
-
-void scale_image(integer ref)
-{
- scale_img(img_array[ref]);
-}
-
-void out_image(integer ref, scaled hpos, scaled vpos)
-{
- image *a = img_array[ref];
- scaledpos pos;
- pos.h = hpos;
- pos.v = vpos;
- out_img(a, pstruct, &pos);
-}
-
-void write_image(integer ref)
-{
- write_img(img_dict(img_array[ref]));
-}
-
-integer image_pages(integer ref)
-{
- return img_totalpages(img_dict(img_array[ref]));
-}
-
-integer image_colordepth(integer ref)
-{
- return img_colordepth(img_dict(img_array[ref]));
-}
-
-#if 0 /* unused */
-static integer image_group_ref(integer ref)
-{
- return img_group_ref(img_dict(img_array[ref]));
-}
-#endif
-
-/* 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]));
-}
-
-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]));
-}
-
-integer image_index(integer ref)
-{
- return img_index(img_dict(img_array[ref]));
-}
-
-integer image_width(integer ref)
-{
- return img_width(img_array[ref]);
-}
-
-integer image_height(integer ref)
-{
- return img_height(img_array[ref]);
-}
-
-integer image_depth(integer ref)
-{
- return img_depth(img_array[ref]);
-}
-
-void update_image_procset(integer ref)
-{
- pdf_image_procset |= img_color(img_dict(img_array[ref]));
-}
-
-boolean check_image_b(integer procset)
-{
- return procset & IMAGE_COLOR_B;
-}
-
-boolean check_image_c(integer procset)
-{
- return procset & IMAGE_COLOR_C;
-}
-
-boolean check_image_i(integer procset)
-{
- return procset & IMAGE_COLOR_I;
-}
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.h b/Build/source/texk/web2c/luatexdir/image/writeimg.h
index bee82acaa97..66ef946d842 100644
--- a/Build/source/texk/web2c/luatexdir/image/writeimg.h
+++ b/Build/source/texk/web2c/luatexdir/image/writeimg.h
@@ -18,50 +18,35 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writeimg.h 2448 2009-06-08 07:43:50Z taco $ */
+/* $Id: writeimg.h 3388 2010-01-26 10:59:04Z taco $ */
#ifndef WRITEIMG_H
# define WRITEIMG_H
+# include "dvi/dvigen.h" /* for scaled_whd only */
# include "image.h"
+# include "pdf/pdfpage.h"
-boolean check_image_b(integer);
-boolean check_image_c(integer);
-boolean check_image_i(integer);
-boolean is_pdf_image(integer);
-boolean is_png_image(integer);
-image_dict *new_image_dict(void);
+typedef image_dict *idict_entry;
+idict_entry *idict_array;
+
+void new_img_pdfstream_struct(image_dict *);
image *new_image(void);
-integer epdf_orig_x(integer i);
-integer epdf_orig_y(integer i);
-integer epdf_xsize(integer i);
-integer epdf_ysize(integer i);
-integer image_colordepth(integer img);
-integer image_depth(integer);
-integer image_height(integer);
-integer image_index(integer);
-integer image_objnum(integer);
-integer image_pages(integer);
-integer image_width(integer);
-integer img_to_array(image *);
-integer read_image(integer, integer, str_number, integer, str_number,
- str_number, integer, integer, integer, integer);
+/*void init_image_dict(image_dict *);*/
+image_dict *new_image_dict(void);
+void free_image_dict(image_dict * p);
+void read_img(PDF, image_dict *, int, int);
+void scan_pdfximage(PDF pdf);
+void scan_pdfrefximage(PDF pdf);
+scaled_whd tex_scale(scaled_whd nat, scaled_whd tex);
+scaled_whd scale_img(image_dict *, scaled_whd, int);
+void write_img(PDF, image_dict *);
+void pdf_write_image(PDF pdf, int n);
void check_pdfstream_dict(image_dict *);
+void write_pdfstream(PDF, image_dict *);
+void idict_to_array(image_dict *);
void dumpimagemeta(void);
-void free_image_dict(image_dict * p);
-void init_image_dict(image_dict *);
-void init_image(image *);
-void new_img_pdfstream_struct(image_dict *);
-void out_image(integer, scaled, scaled);
-void pdf_print_resname_prefix(void);
-void read_img(image_dict *, integer, integer);
-void scale_image(integer);
-void scale_img(image *);
-void set_image_dimensions(integer, integer, integer, integer);
-void undumpimagemeta(integer, integer);
-void update_image_procset(integer);
-void write_image(integer);
-void write_img(image_dict *);
-void write_pdfstream(image_dict *);
+void undumpimagemeta(PDF, int, int);
+scaled_whd scan_alt_rule(void);
#endif /* WRITEIMG_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w
new file mode 100644
index 00000000000..a6b03ee4290
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w
@@ -0,0 +1,823 @@
+% writeimg.w
+
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@* Image inclusion.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: writeimg.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writeimg.w $";
+
+#include <assert.h>
+#include "ptexlib.h"
+#include <kpathsea/c-auto.h>
+#include <kpathsea/c-memstr.h>
+
+@ @c
+#include "image/image.h"
+#include "image/writejpg.h"
+#include "image/writepng.h"
+#include "image/writejbig2.h"
+
+#include "lua51/lua.h" /* for |LUA_NOREF| */
+#include "lua51/lauxlib.h"
+
+@ @c
+#define pdf_image_resolution int_par(pdf_image_resolution_code)
+#define pdf_pagebox int_par(pdf_pagebox_code)
+
+@* Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek.
+
+ Function |readimage| performs some basic initializations.
+ Then it looks at the file extension to determine the
+ image type and calls specific code/functions.
+
+ The main disadvantage is that standard file extensions
+ have to be used, otherwise pdfTeX is not able to detect
+ the correct image type.
+
+ The patch now looks at the file header first regardless of
+ the file extension. This is implemented in function
+ |check_type_by_header|. If this check fails, the traditional
+ test of standard file extension is tried, done in function
+ |check_type_by_extension|.
+
+ Magic headers:
+
+ * "PNG (Portable Network Graphics) Specification", Version 1.2
+ (http://www.libpng.org/pub/png):
+
+ 3.1. PNG file signature
+
+ The first eight bytes of a PNG file always contain the following
+ (decimal) values:
+
+ 137 80 78 71 13 10 26 10
+
+ Translation to C: |"\x89PNG\r\n\x1A\n"|
+
+ * "JPEG File Interchange Format", Version 1.02:
+
+ o you can identify a JFIF file by looking for the following
+ sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>,
+ "JFIF", X'00'.
+
+ Function |check_type_by_header| only looks at the first two bytes:
+ |"\xFF\xD8"|
+
+ * ISO/IEC JTC 1/SC 29/WG 1
+ (ITU-T SG8)
+ Coding of Still Pictures
+ Title: 14492 FCD
+ Source: JBIG Committee
+ Project: JTC 1.29.10
+ Status: Final Committee Draft
+
+ D.4.1, ID string
+
+ This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A
+ 0x1A 0x0A.
+
+ * "PDF Reference", third edition:
+
+ * The first line should contain "\%PDF-1.0" until "\%PDF-1.4"
+ (section 3.4.1 "File Header").
+ * The "implementation notes" say:
+
+ 3.4.1, File Header
+ 12. Acrobat viewers require only that the header appear
+ somewhere within the first 1024 bytes of the file.
+ 13. Acrobat viewers will also accept a header of the form
+ \%!PS-Adobe-N.n PDF-M.m
+
+ The check in function |check_type_by_header| only implements
+ the first issue. The implementation notes are not considered.
+ Therefore files with garbage at start of file must have the
+ standard extension.
+
+ Functions |check_type_by_header| and |check_type_by_extension|:
+ |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 |IMG_TYPE_NONE| indicates that a
+ type has been found.
+
+@c
+#define HEADER_JPG "\xFF\xD8"
+#define HEADER_PNG "\x89PNG\r\n\x1A\n"
+#define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A"
+#define HEADER_PDF "%PDF-1."
+#define MAX_HEADER (sizeof(HEADER_PNG)-1)
+
+static void check_type_by_header(image_dict * idict)
+{
+ int i;
+ FILE *file = NULL;
+ char header[MAX_HEADER];
+
+ assert(idict != NULL);
+ if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
+ return;
+ /* read the header */
+ file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);
+ for (i = 0; (unsigned) i < MAX_HEADER; i++) {
+ header[i] = (char) xgetc(file);
+ if (feof(file))
+ pdftex_fail("reading image file failed");
+ }
+ xfclose(file, img_filepath(idict));
+ /* tests */
+ if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0)
+ img_type(idict) = IMG_TYPE_JPG;
+ else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0)
+ img_type(idict) = IMG_TYPE_PNG;
+ else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0)
+ img_type(idict) = IMG_TYPE_JBIG2;
+ else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0)
+ img_type(idict) = IMG_TYPE_PDF;
+}
+
+@ @c
+static void check_type_by_extension(image_dict * idict)
+{
+ char *image_suffix;
+
+ assert(idict != NULL);
+ if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
+ return;
+ /* tests */
+ if ((image_suffix = strrchr(img_filename(idict), '.')) == 0)
+ img_type(idict) = IMG_TYPE_NONE;
+ else if (strcasecmp(image_suffix, ".png") == 0)
+ img_type(idict) = IMG_TYPE_PNG;
+ else if (strcasecmp(image_suffix, ".jpg") == 0 ||
+ strcasecmp(image_suffix, ".jpeg") == 0)
+ img_type(idict) = IMG_TYPE_JPG;
+ else if (strcasecmp(image_suffix, ".jbig2") == 0 ||
+ strcasecmp(image_suffix, ".jb2") == 0)
+ img_type(idict) = IMG_TYPE_JBIG2;
+ else if (strcasecmp(image_suffix, ".pdf") == 0)
+ img_type(idict) = IMG_TYPE_PDF;
+}
+
+@ @c
+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;
+}
+
+@ @c
+static void init_image(image * p)
+{
+ assert(p != NULL);
+ set_wd_running(p);
+ set_ht_running(p);
+ set_dp_running(p);
+ img_transform(p) = 0;
+ img_dict(p) = NULL;
+ img_dictref(p) = LUA_NOREF;
+}
+
+@ @c
+image *new_image(void)
+{
+ image *p = xtalloc(1, image);
+ init_image(p);
+ return p;
+}
+
+@ @c
+static void init_image_dict(image_dict * p)
+{
+ assert(p != NULL);
+ memset(p, 0, sizeof(image_dict));
+ set_wd_running(p);
+ set_ht_running(p);
+ set_dp_running(p);
+ img_transform(p) = 0;
+ img_pagenum(p) = 1;
+ img_type(p) = IMG_TYPE_NONE;
+ img_pagebox(p) = PDF_BOX_SPEC_MEDIA;
+ img_unset_bbox(p);
+ img_unset_group(p);
+ img_state(p) = DICT_NEW;
+ img_index(p) = -1; /* -1 = unused, used count from 0 */
+}
+
+@ @c
+image_dict *new_image_dict(void)
+{
+ image_dict *p = xtalloc(1, image_dict);
+ init_image_dict(p);
+ return p;
+}
+
+@ @c
+static void free_dict_strings(image_dict * p)
+{
+ xfree(img_filename(p));
+ xfree(img_filepath(p));
+ xfree(img_attr(p));
+ xfree(img_pagename(p));
+}
+
+@ @c
+void free_image_dict(image_dict * p)
+{
+ 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 IMG_TYPE_PDF:
+ unrefPdfDocument(img_filepath(p));
+ break;
+ case IMG_TYPE_PNG: /* assuming |IMG_CLOSEINBETWEEN| */
+ assert(img_png_ptr(p) == NULL);
+ break;
+ case IMG_TYPE_JPG: /* assuming |IMG_CLOSEINBETWEEN| */
+ assert(img_jpg_ptr(p) == NULL);
+ break;
+ case IMG_TYPE_JBIG2: /* todo: writejbig2.w cleanup */
+ break;
+ case IMG_TYPE_PDFSTREAM:
+ if (img_pdfstream_ptr(p) != NULL) {
+ xfree(img_pdfstream_stream(p));
+ xfree(img_pdfstream_ptr(p));
+ }
+ break;
+ case IMG_TYPE_NONE:
+ break;
+ default:
+ assert(0);
+ }
+ free_dict_strings(p);
+ assert(img_file(p) == NULL);
+ xfree(p);
+}
+
+@ @c
+void read_img(PDF pdf,
+ image_dict * idict, int minor_version, int inclusion_errorlevel)
+{
+ char *filepath;
+ int callback_id;
+ assert(idict != NULL);
+ if (img_filename(idict) == NULL)
+ pdftex_fail("image file name missing");
+ callback_id = callback_defined(find_image_file_callback);
+ if (img_filepath(idict) == NULL) {
+ if (callback_id > 0
+ && run_callback(callback_id, "S->S", img_filename(idict),
+ &filepath)) {
+ if (filepath && (strlen(filepath) > 0))
+ img_filepath(idict) = strdup(filepath);
+ } else
+ img_filepath(idict) =
+ kpse_find_file(img_filename(idict), kpse_tex_format, true);
+ 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 IMG_TYPE_PDF:
+ assert(pdf != NULL); /* TODO! */
+ read_pdf_info(idict, minor_version, inclusion_errorlevel,
+ IMG_CLOSEINBETWEEN);
+ break;
+ case IMG_TYPE_PNG:
+ read_png_info(pdf, idict, IMG_CLOSEINBETWEEN);
+ break;
+ case IMG_TYPE_JPG:
+ read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN);
+ break;
+ case IMG_TYPE_JBIG2:
+ if (minor_version < 4) {
+ pdftex_fail
+ ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i",
+ (int) minor_version);
+ }
+ read_jbig2_info(idict);
+ break;
+ default:
+ pdftex_fail("internal error: unknown image type (2)");
+ }
+ cur_file_name = NULL;
+ if (img_state(idict) < DICT_FILESCANNED)
+ img_state(idict) = DICT_FILESCANNED;
+}
+
+@ @c
+static image_dict *read_image(PDF pdf, char *file_name, int page_num,
+ char *page_name, int colorspace,
+ int page_box, int minor_version,
+ int inclusion_errorlevel)
+{
+ image *a = new_image();
+ image_dict *idict = img_dict(a) = new_image_dict();
+ incr(pdf->ximage_count);
+ pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count);
+ img_objnum(idict) = pdf->obj_ptr;
+ img_index(idict) = pdf->ximage_count;
+ set_obj_data_ptr(pdf, img_objnum(idict), img_index(idict));
+ idict_to_array(idict);
+ img_colorspace(idict) = colorspace;
+ img_pagenum(idict) = page_num;
+ img_pagename(idict) = page_name;
+ assert(file_name != NULL);
+ cur_file_name = file_name;
+ img_filename(idict) = file_name;
+ img_pagebox(idict) = page_box;
+ read_img(pdf, idict, minor_version, inclusion_errorlevel);
+ return idict;
+}
+
+@ scans PDF pagebox specification
+@c
+static pdfboxspec_e scan_pdf_box_spec(void)
+{
+ if (scan_keyword("mediabox"))
+ return PDF_BOX_SPEC_MEDIA;
+ else if (scan_keyword("cropbox"))
+ return PDF_BOX_SPEC_CROP;
+ else if (scan_keyword("bleedbox"))
+ return PDF_BOX_SPEC_BLEED;
+ else if (scan_keyword("trimbox"))
+ return PDF_BOX_SPEC_TRIM;
+ else if (scan_keyword("artbox"))
+ return PDF_BOX_SPEC_ART;
+ return PDF_BOX_SPEC_NONE;
+}
+
+@ @c
+void scan_pdfximage(PDF pdf)
+{
+ scaled_whd alt_rule;
+ image_dict *idict;
+ int transform = 0, page = 1, pagebox, colorspace = 0;
+ char *named = NULL, *attr = NULL, *file_name = NULL;
+ alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
+ if (scan_keyword("attr")) {
+ scan_pdf_ext_toks();
+ attr = tokenlist_to_cstring(def_ref, true, NULL);
+ delete_token_ref(def_ref);
+ }
+ if (scan_keyword("named")) {
+ scan_pdf_ext_toks();
+ named = tokenlist_to_cstring(def_ref, true, NULL);
+ delete_token_ref(def_ref);
+ page = 0;
+ } else if (scan_keyword("page")) {
+ scan_int();
+ page = cur_val;
+ }
+ if (scan_keyword("colorspace")) {
+ scan_int();
+ colorspace = cur_val;
+ }
+ pagebox = scan_pdf_box_spec();
+ if (pagebox == PDF_BOX_SPEC_NONE) {
+ pagebox = pdf_pagebox;
+ if (pagebox == PDF_BOX_SPEC_NONE)
+ pagebox = PDF_BOX_SPEC_CROP;
+ }
+ scan_pdf_ext_toks();
+ file_name = tokenlist_to_cstring(def_ref, true, NULL);
+ assert(file_name != NULL);
+ delete_token_ref(def_ref);
+ idict =
+ read_image(pdf, file_name, page, named, colorspace, pagebox,
+ pdf_minor_version, pdf_inclusion_errorlevel);
+ img_attr(idict) = attr;
+ img_dimen(idict) = alt_rule;
+ img_transform(idict) = transform;
+ pdf_last_ximage = img_objnum(idict);
+ pdf_last_ximage_pages = img_totalpages(idict);
+ pdf_last_ximage_colordepth = img_colordepth(idict);
+}
+
+@ @c
+#define tail cur_list.tail_field
+
+void scan_pdfrefximage(PDF pdf)
+{
+ int transform = 0; /* one could scan transform as well */
+ image_dict *idict;
+ scaled_whd alt_rule, dim;
+ alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
+ scan_int();
+ check_obj_exists(pdf, obj_type_ximage, cur_val);
+ new_whatsit(pdf_refximage_node);
+ idict = idict_array[obj_data_ptr(pdf, cur_val)];
+ if (alt_rule.wd != null_flag || alt_rule.ht != null_flag
+ || alt_rule.dp != null_flag)
+ dim = scale_img(idict, alt_rule, transform);
+ else
+ dim = scale_img(idict, img_dimen(idict), img_transform(idict));
+ width(tail) = dim.wd;
+ height(tail) = dim.ht;
+ depth(tail) = dim.dp;
+ pdf_ximage_transform(tail) = transform;
+ pdf_ximage_index(tail) = img_index(idict);
+}
+
+@ |tex_scale()| sequence of decisions:
+
+{\obeylines\obeyspaces\tt
+wd ht dp : res = tex;
+wd ht --
+wd -- dp
+wd -- --
+-- ht dp
+-- ht --
+-- -- dp
+-- -- -- : res = nat;
+}
+
+@c
+scaled_whd tex_scale(scaled_whd nat, scaled_whd tex)
+{
+ scaled_whd res;
+ if (!is_running(tex.wd) && !is_running(tex.ht) && !is_running(tex.dp)) {
+ /* width, height, and depth specified */
+ res = tex;
+ } else /* max. 2 dimensions are specified */ if (!is_running(tex.wd)) {
+ res.wd = tex.wd;
+ if (!is_running(tex.ht)) {
+ res.ht = tex.ht;
+ /* width and height specified */
+ res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht);
+ } else if (!is_running(tex.dp)) {
+ res.dp = tex.dp;
+ /* width and depth specified */
+ res.ht = ext_xn_over_d(tex.wd, nat.ht + nat.dp, nat.wd) - tex.dp;
+ } else {
+ /* only width specified */
+ res.ht = ext_xn_over_d(tex.wd, nat.ht, nat.wd);
+ res.dp = ext_xn_over_d(tex.wd, nat.dp, nat.wd);
+ }
+ } else if (!is_running(tex.ht)) {
+ res.ht = tex.ht;
+ if (!is_running(tex.dp)) {
+ res.dp = tex.dp;
+ /* height and depth specified */
+ res.wd = ext_xn_over_d(tex.ht + tex.dp, nat.wd, nat.ht + nat.dp);
+ } else {
+ /* only height specified */
+ res.wd = ext_xn_over_d(tex.ht, nat.wd, nat.ht);
+ res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht);
+ }
+ } else if (!is_running(tex.dp)) {
+ res.dp = tex.dp;
+ /* only depth specified */
+ res.ht = nat.ht - (tex.dp - nat.dp);
+ res.wd = nat.wd;
+ } else {
+ /* nothing specified */
+ res = nat;
+ }
+ return res;
+}
+
+@ 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.
+
+@c
+scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform)
+{
+ int x, y, xr, yr, tmp; /* size and resolution of image */
+ scaled_whd nat; /* natural size corresponding to image resolution */
+ int default_res;
+ assert(idict != NULL);
+ 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 (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 (((transform - img_rotation(idict)) & 1) == 1) {
+ tmp = x;
+ x = y;
+ y = tmp;
+ tmp = xr;
+ xr = yr;
+ yr = tmp;
+ }
+ nat.dp = 0; /* always for images */
+ if (img_type(idict) == IMG_TYPE_PDF
+ || img_type(idict) == IMG_TYPE_PDFSTREAM) {
+ nat.wd = x;
+ nat.ht = y;
+ } else {
+ default_res = fix_int(pdf_image_resolution, 0, 65535);
+ if (default_res > 0 && (xr == 0 || yr == 0)) {
+ xr = default_res;
+ yr = default_res;
+ }
+ if (xr > 0 && yr > 0) {
+ nat.wd = ext_xn_over_d(one_hundred_inch, x, 100 * xr);
+ nat.ht = ext_xn_over_d(one_hundred_inch, y, 100 * yr);
+ } else {
+ nat.wd = ext_xn_over_d(one_hundred_inch, x, 7200);
+ nat.ht = ext_xn_over_d(one_hundred_inch, y, 7200);
+ }
+ }
+ return tex_scale(nat, alt_rule);
+}
+
+@ @c
+void write_img(PDF pdf, image_dict * idict)
+{
+ assert(idict != NULL);
+ if (img_state(idict) < DICT_WRITTEN) {
+ if (tracefilenames)
+ tex_printf(" <%s", img_filepath(idict));
+ switch (img_type(idict)) {
+ case IMG_TYPE_PNG:
+ write_png(pdf, idict);
+ break;
+ case IMG_TYPE_JPG:
+ write_jpg(pdf, idict);
+ break;
+ case IMG_TYPE_JBIG2:
+ write_jbig2(pdf, idict);
+ break;
+ case IMG_TYPE_PDF:
+ write_epdf(pdf, idict);
+ break;
+ case IMG_TYPE_PDFSTREAM:
+ write_pdfstream(pdf, idict);
+ break;
+ default:
+ pdftex_fail("internal error: unknown image type (1)");
+ }
+ if (tracefilenames)
+ tex_printf(">");
+ if (img_type(idict) == IMG_TYPE_PNG) {
+ write_additional_png_objects(pdf);
+ }
+ }
+ if (img_state(idict) < DICT_WRITTEN)
+ img_state(idict) = DICT_WRITTEN;
+}
+
+@ write an image
+@c
+void pdf_write_image(PDF pdf, int n)
+{
+ pdf_begin_dict(pdf, n, 0);
+ if (pdf->draftmode == 0)
+ write_img(pdf, idict_array[obj_data_ptr(pdf, n)]);
+}
+
+@ @c
+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;
+}
+
+@ @c
+void write_pdfstream(PDF pdf, image_dict * idict)
+{
+ char s[256];
+ assert(img_pdfstream_ptr(idict) != NULL);
+ assert(img_is_bbox(idict));
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n");
+ if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_puts(pdf, "/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(pdf, stripzeros(s));
+ pdf_begin_stream(pdf);
+ if (img_pdfstream_stream(idict) != NULL)
+ pdf_puts(pdf, img_pdfstream_stream(idict));
+ pdf_end_stream(pdf);
+}
+
+@ @c
+/* define |idict_ptr|, |idict_array|, and |idict_limit| */
+idict_entry *idict_ptr, *idict_array = NULL;
+size_t idict_limit;
+
+void idict_to_array(image_dict * idict)
+{
+ assert(idict != NULL);
+ if (idict_ptr - idict_array == 0) { /* align to count from 1 */
+ alloc_array(idict, 1, SMALL_BUF_SIZE); /* /Im0 unused */
+ idict_ptr++;
+ }
+ alloc_array(idict, 1, SMALL_BUF_SIZE);
+ *idict_ptr = idict;
+ assert(img_index(idict) == idict_ptr - idict_array);
+ idict_ptr++;
+}
+
+
+@ 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.
+
+@c
+#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.
+
+@c
+#define dumpcharptr(a) \
+ do { \
+ int x; \
+ if (a!=NULL) { \
+ x = (int)strlen(a)+1; \
+ dumpinteger(x); dump_things(*a, x); \
+ } else { \
+ x = 0; dumpinteger(x); \
+ } \
+ } while (0)
+
+#define undumpcharptr(s) \
+ do { \
+ int x; \
+ char *a; \
+ undumpinteger (x); \
+ if (x>0) { \
+ a = xmalloc((unsigned)x); \
+ undump_things(*a,x); \
+ s = a ; \
+ } else { s = NULL; } \
+ } while (0)
+
+@ @c
+void dumpimagemeta(void)
+{
+ int cur_index, i;
+ image_dict *idict;
+
+ i = (int) idict_limit;
+ dumpinteger(i);
+ cur_index = (int) (idict_ptr - idict_array);
+ dumpinteger(cur_index);
+
+ for (i = 1; i < cur_index; i++) {
+ idict = idict_array[i];
+ assert(idict != NULL);
+ dumpcharptr(img_filename(idict));
+ dumpinteger(img_type(idict));
+ dumpinteger(img_procset(idict));
+ dumpinteger(img_xsize(idict));
+ dumpinteger(img_ysize(idict));
+ dumpinteger(img_xres(idict));
+ dumpinteger(img_yres(idict));
+ dumpinteger(img_totalpages(idict));
+ dumpinteger(img_colorspace(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));
+ }
+
+ }
+}
+
+@ @c
+void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel)
+{
+ int cur_index, i;
+ image_dict *idict;
+
+ assert(pdf != NULL);
+ undumpinteger(i);
+ idict_limit = (size_t) i;
+
+ idict_array = xtalloc(idict_limit, idict_entry);
+ undumpinteger(cur_index);
+ idict_ptr = idict_array + cur_index;
+
+ for (i = 1; i < cur_index; i++) {
+ idict = new_image_dict();
+ assert(idict != NULL);
+ assert(img_index(idict) == -1);
+ idict_to_array(idict);
+ undumpcharptr(img_filename(idict));
+ undumpinteger(img_type(idict));
+ undumpinteger(img_procset(idict));
+ undumpinteger(img_xsize(idict));
+ undumpinteger(img_ysize(idict));
+ undumpinteger(img_xres(idict));
+ undumpinteger(img_yres(idict));
+ undumpinteger(img_totalpages(idict));
+ undumpinteger(img_colorspace(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(pdf, idict, pdfversion, pdfinclusionerrorlevel);
+ }
+}
+
+@ scans rule spec to |alt_rule|
+@c
+scaled_whd scan_alt_rule(void)
+{
+ scaled_whd alt_rule;
+ alt_rule.wd = null_flag;
+ alt_rule.ht = null_flag;
+ alt_rule.dp = null_flag;
+ RESWITCH:
+ if (scan_keyword("width")) {
+ scan_normal_dimen();
+ alt_rule.wd = cur_val;
+ goto RESWITCH;
+ }
+ if (scan_keyword("height")) {
+ scan_normal_dimen();
+ alt_rule.ht = cur_val;
+ goto RESWITCH;
+ }
+ if (scan_keyword("depth")) {
+ scan_normal_dimen();
+ alt_rule.dp = cur_val;
+ goto RESWITCH;
+ }
+ return alt_rule;
+}
diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.h b/Build/source/texk/web2c/luatexdir/image/writejbig2.h
index f28e91281fe..a5715d5732e 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejbig2.h
+++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.h
@@ -18,15 +18,15 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writejbig2.h 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: writejbig2.h 2579 2009-06-23 14:12:23Z taco $ */
#ifndef WRITEJBIG2_H
# define WRITEJBIG2_H
# include "image.h"
-void flush_jbig2_page0_objects(void);
+void flush_jbig2_page0_objects(PDF);
void read_jbig2_info(image_dict *);
-void write_jbig2(image_dict *);
+void write_jbig2(PDF, image_dict *);
#endif /* WRITEJBIG"_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.c b/Build/source/texk/web2c/luatexdir/image/writejbig2.w
index c22c27e11b6..936ae29c6bd 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejbig2.c
+++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.w
@@ -1,24 +1,24 @@
-/* writejbig2.c
+% writejbig2.w
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-/***********************************************************************
+@
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.
@@ -40,21 +40,21 @@ http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf
News
====
-31 May 2006: no need to wait for endoffileflag in sequential access
+31 May 2006: no need to wait for |endoffileflag| in sequential access
organization.
-10 May 2006: ygetc() for some catching of broken JBIG2 files; modify to
+10 May 2006: |ygetc()| for some catching of broken JBIG2 files; modify to
accept Example 3.4 from PDFRef 5th ed. with short end-of-file segment.
-09 May 2006: pages_maketree() and segments_maketree() by AVL tree,
+09 May 2006: |pages_maketree()| and |segments_maketree()| by AVL tree,
some cleaning up.
-06 May 2006: File list replaced by AVL tree; new_fileinfo(),
-new_pageinfo().
+06 May 2006: File list replaced by AVL tree; |new_fileinfo()|,
+|new_pageinfo()|.
04 May 2006: Updated for pdftex-1.40-beta-20060213.
-08 Jan. 2003: Added flushjbig2page0objects() function. Now at the end
+08 Jan. 2003: Added |flushjbig2page0objects()| function. Now at the end
of the pdfTeX run all pending page0 objects are written out.
08 Jan. 2003: Release on private webpage.
@@ -78,11 +78,10 @@ object exists, reference it. Else create fresh one.
09 Dec. 2002: JBIG2 seg. page numbers > 0 are now set to 1, see PDF Ref.
-***********************************************************************/
-
+@ @c
static const char _svn_version[] =
- "$Id: writejbig2.c 2315 2009-04-17 23:34:42Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writejbig2.c $";
+ "$Id: writejbig2.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writejbig2.w $";
#undef DEBUG
@@ -90,11 +89,9 @@ static const char _svn_version[] =
#include <stdio.h>
#include <assert.h>
#include "ptexlib.h"
-#include "ptexmac.h"
-#include "image.h"
-
-/**********************************************************************/
+#include "image/image.h"
+@ @c
/* 7.3 Segment types */
#define M_SymbolDictionary 0
#define M_IntermediateTextRegion 4
@@ -118,8 +115,7 @@ static const char _svn_version[] =
#define M_Tables 53
#define M_Extension 62
-/**********************************************************************/
-
+@ @c
typedef enum { INITIAL, HAVEINFO, WRITEPDF } PHASE;
typedef struct _LITEM {
@@ -177,13 +173,12 @@ typedef struct _FILEINFO {
unsigned int filehdrflags; /* set by readfilehdr() */
boolean sequentialaccess; /* set by readfilehdr() */
unsigned long numofpages; /* set by readfilehdr() */
- unsigned long streamstart; /* set by get_jbig2_info() */
+ unsigned long streamstart; /* set by |get_jbig2_info()| */
unsigned long pdfpage0objnum;
PHASE phase;
} FILEINFO;
-/**********************************************************************/
-
+@ @c
static struct avl_table *file_tree = NULL;
static int comp_file_entry(const void *pa, const void *pb, void *p)
@@ -196,17 +191,18 @@ static int comp_file_entry(const void *pa, const void *pb, void *p)
static int comp_page_entry(const void *pa, const void *pb, void *p)
{
(void) p;
- return ((const PAGEINFO *) pa)->pagenum - ((const PAGEINFO *) pb)->pagenum;
+ return (int) (((const PAGEINFO *) pa)->pagenum -
+ ((const PAGEINFO *) pb)->pagenum);
}
static int comp_segment_entry(const void *pa, const void *pb, void *p)
{
(void) p;
- return ((const SEGINFO *) pa)->segnum - ((const SEGINFO *) pb)->segnum;
+ return (int) (((const SEGINFO *) pa)->segnum -
+ ((const SEGINFO *) pb)->segnum);
}
-/**********************************************************************/
-
+@ @c
static int ygetc(FILE * stream)
{
int c = getc(stream);
@@ -219,8 +215,7 @@ static int ygetc(FILE * stream)
return c;
}
-/**********************************************************************/
-
+@ @c
static void initlinkedlist(LIST * lp)
{
lp->first = NULL;
@@ -245,8 +240,7 @@ static LIST *litem_append(LIST * lp)
return lp;
}
-/**********************************************************************/
-
+@ @c
static FILEINFO *new_fileinfo(void)
{
FILEINFO *fip;
@@ -265,6 +259,7 @@ static FILEINFO *new_fileinfo(void)
return fip;
}
+@ @c
static PAGEINFO *new_pageinfo(void)
{
PAGEINFO *pip;
@@ -281,6 +276,7 @@ static PAGEINFO *new_pageinfo(void)
return pip;
}
+@ @c
static void init_seginfo(SEGINFO * sip)
{
sip->segnum = 0;
@@ -304,8 +300,7 @@ static void init_seginfo(SEGINFO * sip)
sip->endoffileflag = false;
}
-/**********************************************************************/
-
+@ @c
static void pages_maketree(LIST * plp)
{
LITEM *ip;
@@ -319,6 +314,7 @@ static void pages_maketree(LIST * plp)
}
}
+@ @c
static void segments_maketree(LIST * slp)
{
LITEM *ip;
@@ -332,8 +328,7 @@ static void segments_maketree(LIST * slp)
}
}
-/**********************************************************************/
-
+@ @c
static PAGEINFO *find_pageinfo(LIST * plp, unsigned long pagenum)
{
PAGEINFO tmp;
@@ -342,6 +337,7 @@ static PAGEINFO *find_pageinfo(LIST * plp, unsigned long pagenum)
return (PAGEINFO *) avl_find(plp->tree, &tmp);
}
+@ @c
static SEGINFO *find_seginfo(LIST * slp, unsigned long segnum)
{
SEGINFO tmp;
@@ -350,22 +346,21 @@ static SEGINFO *find_seginfo(LIST * slp, unsigned long segnum)
return (SEGINFO *) avl_find(slp->tree, &tmp);
}
-/**********************************************************************/
-
+@ @c
static unsigned int read2bytes(FILE * f)
{
- unsigned int c = ygetc(f);
- return (c << 8) + ygetc(f);
+ unsigned int c = (unsigned int) ygetc(f);
+ return (c << 8) + (unsigned int) ygetc(f);
}
+@ @c
static unsigned long read4bytes(FILE * f)
{
unsigned int l = read2bytes(f);
return (l << 16) + read2bytes(f);
}
-/**********************************************************************/
-
+@ @c
static unsigned long getstreamlen(LITEM * slip, boolean refer)
{
SEGINFO *sip;
@@ -378,8 +373,7 @@ static unsigned long getstreamlen(LITEM * slip, boolean refer)
return len;
}
-/**********************************************************************/
-
+@ @c
static void readfilehdr(FILEINFO * fip)
{
unsigned int i;
@@ -392,7 +386,7 @@ static void readfilehdr(FILEINFO * fip)
pdftex_fail
("readfilehdr(): reading JBIG2 image file failed: ID string missing");
/* Annex D.4.2 File header flags */
- fip->filehdrflags = ygetc(fip->file);
+ fip->filehdrflags = (unsigned int) ygetc(fip->file);
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);
@@ -405,8 +399,7 @@ static void readfilehdr(FILEINFO * fip)
/* --- at end of file header --- */
}
-/**********************************************************************/
-
+@ @c
static void checkseghdrflags(SEGINFO * sip)
{
sip->endofstripeflag = false;
@@ -453,9 +446,9 @@ static void checkseghdrflags(SEGINFO * sip)
}
}
-/**********************************************************************/
-/* for first reading of file; return value tells if header been read */
+@ for first reading of file; return value tells if header been read
+@c
static boolean readseghdr(FILEINFO * fip, SEGINFO * sip)
{
unsigned int i;
@@ -471,7 +464,7 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip)
printf(" segnum %d\n", sip->segnum);
#endif
/* 7.2.3 Segment header flags */
- sip->seghdrflags = ygetc(fip->file);
+ sip->seghdrflags = (unsigned int) ygetc(fip->file);
#ifdef DEBUG
printf(" hdrflags %d\n", sip->seghdrflags & 0x3f);
#endif
@@ -510,18 +503,17 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip)
}
/* 7.2.6 Segment page association */
if (sip->pageassocsizeflag)
- sip->segpage = read4bytes(fip->file);
+ sip->segpage = (long int) read4bytes(fip->file);
else
sip->segpage = ygetc(fip->file);
/* 7.2.7 Segment data length */
sip->segdatalen = read4bytes(fip->file);
- sip->hdrend = (long) xftello(fip->file, fip->filepath);
+ sip->hdrend = (unsigned long) xftello(fip->file, fip->filepath);
/* ---- at end of segment header ---- */
return true;
}
-/**********************************************************************/
-
+@ @c
static void checkseghdr(FILEINFO * fip, SEGINFO * sip);
static void markpage0seg(FILEINFO * fip, unsigned long referedseg)
@@ -537,10 +529,10 @@ static void markpage0seg(FILEINFO * fip, unsigned long referedseg)
}
}
-/**********************************************************************/
-/* for writing, marks refered page0 segments, sets segpage > 0 to 1 */
+@ for writing, marks refered page0 segments, sets segpage > 0 to 1
-static void writeseghdr(FILEINFO * fip, SEGINFO * sip)
+@c
+static void writeseghdr(PDF pdf, FILEINFO * fip, SEGINFO * sip)
{
unsigned int i;
unsigned long referedseg = 0;
@@ -548,25 +540,25 @@ static void writeseghdr(FILEINFO * fip, SEGINFO * sip)
/* 7.2.3 Segment header flags */
/* 7.2.4 Referred-to segment count and retention flags */
for (i = 0; i < 5 + sip->fieldlen; i++)
- pdfout(ygetc(fip->file));
+ pdf_out(pdf, ygetc(fip->file));
/* 7.2.5 Referred-to segment numbers */
for (i = 0; i < sip->countofrefered; i++) {
switch (sip->segnumwidth) {
case 1:
- referedseg = ygetc(fip->file);
- pdfout(referedseg);
+ referedseg = (unsigned long) ygetc(fip->file);
+ pdf_out(pdf, referedseg);
break;
case 2:
referedseg = read2bytes(fip->file);
- pdfout((referedseg >> 8) & 0xff);
- pdfout(referedseg & 0xff);
+ pdf_out(pdf, (referedseg >> 8) & 0xff);
+ pdf_out(pdf, referedseg & 0xff);
break;
case 4:
referedseg = read4bytes(fip->file);
- pdfout((referedseg >> 24) & 0xff);
- pdfout((referedseg >> 16) & 0xff);
- pdfout((referedseg >> 8) & 0xff);
- pdfout(referedseg & 0xff);
+ pdf_out(pdf, (referedseg >> 24) & 0xff);
+ pdf_out(pdf, (referedseg >> 16) & 0xff);
+ pdf_out(pdf, (referedseg >> 8) & 0xff);
+ pdf_out(pdf, referedseg & 0xff);
break;
}
if (fip->page0.last != NULL && !sip->refers)
@@ -578,19 +570,18 @@ static void writeseghdr(FILEINFO * fip, SEGINFO * sip)
if (sip->pageassocsizeflag)
for (i = 0; i < 3; i++) {
(void) ygetc(fip->file);
- pdfout(0);
+ pdf_out(pdf, 0);
}
(void) ygetc(fip->file);
- pdfout((sip->segpage > 0) ? 1 : 0);
+ pdf_out(pdf, (unsigned char) ((sip->segpage > 0) ? 1 : 0));
/* 7.2.7 Segment data length */
for (i = 0; i < 4; i++)
- pdfout(ygetc(fip->file));
+ pdf_out(pdf, ygetc(fip->file));
/* ---- at end of segment header ---- */
}
-/**********************************************************************/
-/* for recursive marking of refered page0 segments */
-
+@ for recursive marking of refered page0 segments
+@c
static void checkseghdr(FILEINFO * fip, SEGINFO * sip)
{
unsigned int i;
@@ -603,7 +594,7 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip)
for (i = 0; i < sip->countofrefered; i++) {
switch (sip->segnumwidth) {
case 1:
- referedseg = ygetc(fip->file);
+ referedseg = (unsigned long) ygetc(fip->file);
break;
case 2:
referedseg = read2bytes(fip->file);
@@ -626,8 +617,7 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip)
/* ---- at end of segment header ---- */
}
-/**********************************************************************/
-
+@ @c
static unsigned long findstreamstart(FILEINFO * fip)
{
SEGINFO tmp;
@@ -640,8 +630,7 @@ static unsigned long findstreamstart(FILEINFO * fip)
return fip->streamstart;
}
-/**********************************************************************/
-
+@ @c
static void rd_jbig2_info(FILEINFO * fip)
{
unsigned long seekdist = 0; /* for sequential-access only */
@@ -667,7 +656,7 @@ static void rd_jbig2_info(FILEINFO * fip)
if (sip->segpage > (int) currentpage) {
plp = litem_append(&(fip->pages));
plp->last->d = new_pageinfo();
- currentpage = sip->segpage;
+ currentpage = (unsigned long) sip->segpage;
}
pip = fip->pages.last->d;
} else {
@@ -689,31 +678,31 @@ static void rd_jbig2_info(FILEINFO * fip)
sip->dataend = sip->datastart + sip->segdatalen;
if (!fip->sequentialaccess
&& (sip->pageinfoflag || sip->endofstripeflag))
- xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath);
+ xfseeko(fip->file, (off_t) sip->datastart, SEEK_SET, fip->filepath);
seekdist = sip->segdatalen;
/* 7.4.8 Page information segment syntax */
if (sip->pageinfoflag) {
- pip->pagenum = sip->segpage;
- pip->width = read4bytes(fip->file);
- pip->height = read4bytes(fip->file);
- pip->xres = read4bytes(fip->file);
- pip->yres = read4bytes(fip->file);
- pip->pagesegmentflags = ygetc(fip->file);
+ pip->pagenum = (unsigned long) sip->segpage;
+ pip->width = (unsigned) read4bytes(fip->file);
+ pip->height = (unsigned) read4bytes(fip->file);
+ pip->xres = (unsigned) read4bytes(fip->file);
+ pip->yres = (unsigned) read4bytes(fip->file);
+ pip->pagesegmentflags = (unsigned) ygetc(fip->file);
/* 7.4.8.6 Page striping information */
pip->stripinginfo = read2bytes(fip->file);
seekdist -= 19;
}
if (sip->endofstripeflag) {
- pip->stripedheight = read4bytes(fip->file);
+ pip->stripedheight = (unsigned) read4bytes(fip->file);
seekdist -= 4;
}
if (!fip->sequentialaccess
&& (sip->pageinfoflag || sip->endofstripeflag))
- xfseeko(fip->file, sip->hdrend, SEEK_SET, fip->filepath);
+ xfseeko(fip->file, (off_t) sip->hdrend, SEEK_SET, fip->filepath);
if (!fip->sequentialaccess)
streampos += sip->segdatalen;
if (fip->sequentialaccess)
- xfseeko(fip->file, seekdist, SEEK_CUR, fip->filepath);
+ xfseeko(fip->file, (off_t) seekdist, SEEK_CUR, fip->filepath);
if (sip->endofpageflag && currentpage && (pip->stripinginfo >> 15))
pip->height = pip->stripedheight;
}
@@ -723,9 +712,8 @@ static void rd_jbig2_info(FILEINFO * fip)
xfclose(fip->file, fip->filepath);
}
-/**********************************************************************/
-
-static void wr_jbig2(FILEINFO * fip, unsigned long page)
+@ @c
+static void wr_jbig2(PDF pdf, FILEINFO * fip, unsigned long page)
{
LITEM *slip;
PAGEINFO *pip;
@@ -734,47 +722,48 @@ static void wr_jbig2(FILEINFO * fip, unsigned long page)
if (page > 0) {
pip = find_pageinfo(&(fip->pages), page);
assert(pip != NULL);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
- pdf_printf("/Width %i\n", pip->width);
- pdf_printf("/Height %i\n", pip->height);
- pdf_puts("/ColorSpace /DeviceGray\n");
- pdf_puts("/BitsPerComponent 1\n");
- pdf_printf("/Length %lu\n", getstreamlen(pip->segments.first, true));
- pdf_puts("/Filter [/JBIG2Decode]\n");
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
+ pdf_printf(pdf, "/Width %i\n", pip->width);
+ pdf_printf(pdf, "/Height %i\n", pip->height);
+ pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
+ pdf_puts(pdf, "/BitsPerComponent 1\n");
+ pdf_printf(pdf, "/Length %lu\n",
+ getstreamlen(pip->segments.first, true));
+ pdf_puts(pdf, "/Filter [/JBIG2Decode]\n");
if (fip->page0.last != NULL) {
if (fip->pdfpage0objnum == 0) {
- pdf_create_obj(0, 0);
- fip->pdfpage0objnum = obj_ptr;
+ pdf_create_obj(pdf, obj_type_others, 0);
+ fip->pdfpage0objnum = (unsigned long) pdf->obj_ptr;
}
- pdf_printf("/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n",
+ pdf_printf(pdf, "/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n",
fip->pdfpage0objnum);
}
} else {
pip = find_pageinfo(&(fip->page0), page);
assert(pip != NULL);
- pdf_begin_dict(fip->pdfpage0objnum, 0);
- pdf_printf("/Length %lu\n", getstreamlen(pip->segments.first, false));
+ pdf_begin_dict(pdf, (int) fip->pdfpage0objnum, 0);
+ pdf_printf(pdf, "/Length %lu\n",
+ getstreamlen(pip->segments.first, false));
}
- pdf_puts(">>\n");
- pdf_puts("stream\n");
+ pdf_puts(pdf, ">>\n");
+ pdf_puts(pdf, "stream\n");
fip->file = xfopen(fip->filepath, FOPEN_RBIN_MODE);
for (slip = pip->segments.first; slip != NULL; slip = slip->next) { /* loop over page segments */
sip = slip->d;
if (sip->isrefered || page > 0) {
- xfseeko(fip->file, sip->hdrstart, SEEK_SET, fip->filepath);
+ xfseeko(fip->file, (off_t) sip->hdrstart, SEEK_SET, fip->filepath);
/* mark refered-to page 0 segments, change segpages > 1 to 1 */
- writeseghdr(fip, sip);
- xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath);
+ writeseghdr(pdf, fip, sip);
+ xfseeko(fip->file, (off_t) sip->datastart, SEEK_SET, fip->filepath);
for (i = sip->datastart; i < sip->dataend; i++)
- pdfout(ygetc(fip->file));
+ pdf_out(pdf, ygetc(fip->file));
}
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
xfclose(fip->file, fip->filepath);
}
-/**********************************************************************/
-
+@ @c
void read_jbig2_info(image_dict * idict)
{
FILEINFO *fip, tmp;
@@ -807,19 +796,20 @@ void read_jbig2_info(image_dict * idict)
segments_maketree(&(pip->segments));
}
}
- pip = find_pageinfo(&(fip->pages), img_pagenum(idict));
+ pip = find_pageinfo(&(fip->pages), (unsigned long) img_pagenum(idict));
if (pip == NULL)
pdftex_fail("read_jbig2_info(): page %d not found in JBIG2 image file",
(int) img_pagenum(idict));
- img_totalpages(idict) = fip->numofpages;
- img_xsize(idict) = pip->width;
- img_ysize(idict) = pip->height;
+ img_totalpages(idict) = (int) fip->numofpages;
+ img_xsize(idict) = (int) pip->width;
+ img_ysize(idict) = (int) pip->height;
img_xres(idict) = (int) (pip->xres * 0.0254 + 0.5);
img_yres(idict) = (int) (pip->yres * 0.0254 + 0.5);
img_colordepth(idict) = 1;
}
-void write_jbig2(image_dict * idict)
+@ @c
+void write_jbig2(PDF pdf, image_dict * idict)
{
FILEINFO *fip, tmp;
PAGEINFO *pip;
@@ -828,14 +818,15 @@ void write_jbig2(image_dict * idict)
tmp.filepath = img_filepath(idict);
fip = (FILEINFO *) avl_find(file_tree, &tmp);
assert(fip != NULL);
- assert(fip->phase == HAVEINFO); /* don't write before rd_jbig2_info() call */
- pip = find_pageinfo(&(fip->pages), img_pagenum(idict));
+ assert(fip->phase == HAVEINFO); /* don't write before |rd_jbig2_info()| call */
+ pip = find_pageinfo(&(fip->pages), (unsigned long) img_pagenum(idict));
assert(pip != NULL);
- wr_jbig2(fip, pip->pagenum);
+ wr_jbig2(pdf, fip, pip->pagenum);
img_file(idict) = NULL;
}
-void flush_jbig2_page0_objects(void)
+@ @c
+void flush_jbig2_page0_objects(PDF pdf)
{
FILEINFO *fip;
struct avl_traverser t;
@@ -844,9 +835,7 @@ void flush_jbig2_page0_objects(void)
for (fip = avl_t_first(&t, file_tree); fip != NULL;
fip = avl_t_next(&t)) {
if (fip->page0.last != NULL)
- wr_jbig2(fip, 0);
+ wr_jbig2(pdf, fip, 0);
}
}
}
-
-/**********************************************************************/
diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.h b/Build/source/texk/web2c/luatexdir/image/writejpg.h
index bd497c9e114..d3c7cdb806a 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejpg.h
+++ b/Build/source/texk/web2c/luatexdir/image/writejpg.h
@@ -18,14 +18,14 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writejpg.h 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: writejpg.h 2653 2009-06-27 14:30:05Z taco $ */
#ifndef WRITEJPG_H
# define WRITEJPG_H
# include "image.h"
-void read_jpg_info(image_dict *, img_readtype_e);
-void write_jpg(image_dict *);
+void read_jpg_info(PDF, image_dict *, img_readtype_e);
+void write_jpg(PDF, image_dict *);
#endif /* WRITEJPG_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.c b/Build/source/texk/web2c/luatexdir/image/writejpg.w
index 187c55ea6c2..cb0e2fedcde 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejpg.c
+++ b/Build/source/texk/web2c/luatexdir/image/writejpg.w
@@ -1,32 +1,33 @@
-/* writejpg.c
+% writejpg.w
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: writejpg.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writejpg.w $";
#include <assert.h>
#include "ptexlib.h"
-#include "image.h"
-#include "writejpg.h"
-
-static const char _svn_version[] =
- "$Id: writejpg.c 2320 2009-04-18 08:52:30Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writejpg.c $";
+#include "image/image.h"
+@ @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 */
@@ -98,12 +99,14 @@ typedef enum { /* JPEG marker codes */
M_ERROR = 0x100 /* dummy marker, internal use only */
} JPEG_MARKER;
+@ @c
static JPG_UINT16 read2bytes(FILE * f)
{
int c = xgetc(f);
- return (c << 8) + xgetc(f);
+ return (JPG_UINT16) ((c << 8) + (int) xgetc(f));
}
+@ @c
static void close_and_cleanup_jpg(image_dict * idict)
{
assert(idict != NULL);
@@ -116,7 +119,8 @@ static void close_and_cleanup_jpg(image_dict * idict)
img_jpg_ptr(idict) = NULL;
}
-void read_jpg_info(image_dict * idict, img_readtype_e readtype)
+@ @c
+void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
{
int i, units = 0;
unsigned char jpg_id[] = "JFIF";
@@ -134,7 +138,7 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
if (read2bytes(img_file(idict)) != 0xFFD8)
pdftex_fail("reading JPEG image failed (no JPEG header found)");
- /* currently only true JFIF files allow extracting img_xres and img_yres */
+ /* currently only true JFIF files allow extracting |img_xres| and |img_yres| */
if (read2bytes(img_file(idict)) == 0xFFE0) { /* check for JFIF */
(void) read2bytes(img_file(idict));
for (i = 0; i < 5; i++) {
@@ -144,20 +148,27 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
if (i == 5) { /* it's JFIF */
read2bytes(img_file(idict));
units = xgetc(img_file(idict));
- img_xres(idict) = read2bytes(img_file(idict));
- img_yres(idict) = read2bytes(img_file(idict));
+ img_xres(idict) = (int) read2bytes(img_file(idict));
+ img_yres(idict) = (int) read2bytes(img_file(idict));
switch (units) {
case 1:
break; /* pixels per inch */
case 2:
- img_xres(idict) *= 2.54;
- img_yres(idict) *= 2.54;
+ img_xres(idict) = (int) ((double) img_xres(idict) * 2.54);
+ img_yres(idict) = (int) ((double) img_yres(idict) * 2.54);
break; /* pixels per cm */
default:
img_xres(idict) = img_yres(idict) = 0;
break;
}
}
+ /* if either xres or yres is 0 but the other isn't, set it to the value of the other */
+ if ((img_xres(idict) == 0) && (img_yres(idict) != 0)) {
+ img_xres(idict) = img_yres(idict);
+ }
+ if ((img_yres(idict) == 0) && (img_xres(idict) != 0)) {
+ img_yres(idict) = img_xres(idict);
+ }
}
xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
while (1) {
@@ -177,26 +188,26 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
case M_SOF15:
pdftex_fail("unsupported type of compression");
case M_SOF2:
- if (fixed_pdf_minor_version <= 2)
+ if (pdf->minor_version <= 2)
pdftex_fail("cannot use progressive DCT with PDF-1.2");
case M_SOF0:
case M_SOF1:
case M_SOF3:
(void) read2bytes(img_file(idict)); /* read segment length */
img_colordepth(idict) = xgetc(img_file(idict));
- img_ysize(idict) = read2bytes(img_file(idict));
- img_xsize(idict) = read2bytes(img_file(idict));
+ img_ysize(idict) = (int) read2bytes(img_file(idict));
+ img_xsize(idict) = (int) read2bytes(img_file(idict));
img_jpg_color(idict) = xgetc(img_file(idict));
xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
switch (img_jpg_color(idict)) {
case JPG_GRAY:
- img_color(idict) = IMAGE_COLOR_B;
+ img_procset(idict) |= PROCSET_IMAGE_B;
break;
case JPG_RGB:
- img_color(idict) = IMAGE_COLOR_C;
+ img_procset(idict) |= PROCSET_IMAGE_C;
break;
case JPG_CMYK:
- img_color(idict) = IMAGE_COLOR_C;
+ img_procset(idict) |= PROCSET_IMAGE_C;
break;
default:
pdftex_fail("Unsupported color space %i",
@@ -226,56 +237,58 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
assert(0);
}
-static void reopen_jpg(image_dict * idict)
+@ @c
+static void reopen_jpg(PDF pdf, image_dict * idict)
{
- integer width, height, xres, yres;
+ int width, height, xres, yres;
width = img_xsize(idict);
height = img_ysize(idict);
xres = img_xres(idict);
yres = img_yres(idict);
- read_jpg_info(idict, IMG_KEEPOPEN);
+ read_jpg_info(pdf, idict, IMG_KEEPOPEN);
if (width != img_xsize(idict) || height != img_ysize(idict)
|| xres != img_xres(idict) || yres != img_yres(idict))
pdftex_fail("writejpg: image dimensions have changed");
}
-void write_jpg(image_dict * idict)
+@ @c
+void write_jpg(PDF pdf, image_dict * idict)
{
long unsigned l;
FILE *f;
assert(idict != NULL);
if (img_file(idict) == NULL)
- reopen_jpg(idict);
+ reopen_jpg(pdf, idict);
assert(img_jpg_ptr(idict) != NULL);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
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/Length %i\n",
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n",
(int) img_xsize(idict),
(int) img_ysize(idict),
(int) img_colordepth(idict), (int) img_jpg_ptr(idict)->length);
- pdf_puts("/ColorSpace ");
+ pdf_puts(pdf, "/ColorSpace ");
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
switch (img_jpg_color(idict)) {
case JPG_GRAY:
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
break;
case JPG_RGB:
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
break;
case JPG_CMYK:
- pdf_puts("/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
+ pdf_puts(pdf, "/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
break;
default:
pdftex_fail("Unsupported color space %i",
(int) img_jpg_color(idict));
}
}
- pdf_puts("/Filter /DCTDecode\n>>\nstream\n");
+ pdf_puts(pdf, "/Filter /DCTDecode\n>>\nstream\n");
for (l = img_jpg_ptr(idict)->length, f = img_file(idict); l > 0; l--)
- pdfout(xgetc(f));
- pdf_end_stream();
+ pdf_out(pdf, xgetc(f));
+ pdf_end_stream(pdf);
close_and_cleanup_jpg(idict);
}
diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.h b/Build/source/texk/web2c/luatexdir/image/writepng.h
index 4683e694a0c..56a96436389 100644
--- a/Build/source/texk/web2c/luatexdir/image/writepng.h
+++ b/Build/source/texk/web2c/luatexdir/image/writepng.h
@@ -18,15 +18,15 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writepng.h 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: writepng.h 2580 2009-06-23 15:55:52Z taco $ */
#ifndef WRITEPNG_H
# define WRITEPNG_H
# include "image.h"
-void read_png_info(image_dict *, img_readtype_e);
-void write_additional_png_objects(void);
-void write_png(image_dict *);
+void read_png_info(PDF, image_dict *, img_readtype_e);
+void write_additional_png_objects(PDF);
+void write_png(PDF, image_dict *);
#endif /* WRITEPNG_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.c b/Build/source/texk/web2c/luatexdir/image/writepng.w
index 154a8a351c2..1b8ecb56b49 100644
--- a/Build/source/texk/web2c/luatexdir/image/writepng.c
+++ b/Build/source/texk/web2c/luatexdir/image/writepng.w
@@ -1,32 +1,33 @@
-/* writepng.c
+% writepng.w
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: writepng.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writepng.w $";
#include <assert.h>
#include "ptexlib.h"
-#include "image.h"
-#include "writepng.h"
-
-static const char _svn_version[] =
- "$Id: writepng.c 2317 2009-04-18 00:12:18Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writepng.c $";
+#include "image/image.h"
+@ @c
static int transparent_page_group = -1;
static void close_and_cleanup_png(image_dict * idict)
@@ -43,7 +44,8 @@ static void close_and_cleanup_png(image_dict * idict)
img_png_ptr(idict) = NULL;
}
-void read_png_info(image_dict * idict, img_readtype_e readtype)
+@ @c
+void read_png_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
{
double gamma;
png_structp png_p;
@@ -73,43 +75,43 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
png_set_tRNS_to_alpha(png_p);
}
/* alpha channel support */
- if (fixed_pdf_minor_version < 4 && png_p->color_type | PNG_COLOR_MASK_ALPHA)
+ if (pdf->minor_version < 4 && png_p->color_type | PNG_COLOR_MASK_ALPHA)
png_set_strip_alpha(png_p);
/* 16bit depth support */
- if (fixed_pdf_minor_version < 5)
- fixed_image_hicolor = 0;
- if (info_p->bit_depth == 16 && !fixed_image_hicolor)
+ if (pdf->minor_version < 5)
+ pdf->image_hicolor = 0;
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor == 0))
png_set_strip_16(png_p);
/* gamma support */
- if (fixed_image_apply_gamma) {
+ if (pdf->image_apply_gamma) {
if (png_get_gAMA(png_p, info_p, &gamma))
- png_set_gamma(png_p, (fixed_gamma / 1000.0), gamma);
+ png_set_gamma(png_p, (pdf->gamma / 1000.0), gamma);
else
- png_set_gamma(png_p, (fixed_gamma / 1000.0),
- (1000.0 / fixed_image_gamma));
+ png_set_gamma(png_p, (pdf->gamma / 1000.0),
+ (1000.0 / pdf->image_gamma));
}
/* reset structure */
png_read_update_info(png_p, info_p);
/* resolution support */
- img_xsize(idict) = info_p->width;
- img_ysize(idict) = info_p->height;
+ img_xsize(idict) = (int) info_p->width;
+ img_ysize(idict) = (int) info_p->height;
if (info_p->valid & PNG_INFO_pHYs) {
img_xres(idict) =
- round(0.0254 * png_get_x_pixels_per_meter(png_p, info_p));
+ round(0.0254 * (double) png_get_x_pixels_per_meter(png_p, info_p));
img_yres(idict) =
- round(0.0254 * png_get_y_pixels_per_meter(png_p, info_p));
+ round(0.0254 * (double) png_get_y_pixels_per_meter(png_p, info_p));
}
switch (info_p->color_type) {
case PNG_COLOR_TYPE_PALETTE:
- img_color(idict) = IMAGE_COLOR_C | IMAGE_COLOR_I;
+ img_procset(idict) |= PROCSET_IMAGE_C | PROCSET_IMAGE_I;
break;
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_GRAY_ALPHA:
- img_color(idict) = IMAGE_COLOR_B;
+ img_procset(idict) |= PROCSET_IMAGE_B;
break;
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGB_ALPHA:
- img_color(idict) = IMAGE_COLOR_C;
+ img_procset(idict) |= PROCSET_IMAGE_C;
break;
default:
pdftex_fail("unsupported type of color_type <%i>", info_p->color_type);
@@ -119,32 +121,33 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
close_and_cleanup_png(idict);
}
+@ @c
#define write_gray_pixel_16(r) \
- if (j % 4 == 0||j % 4 == 1) pdf_buf[pdf_ptr++] = *r++; \
+ if (j % 4 == 0||j % 4 == 1) pdf_quick_out(pdf,*r++); \
else smask[smask_ptr++] = *r++
#define write_gray_pixel_8(r) \
- if (j % 2 == 0) pdf_buf[pdf_ptr++] = *r++; \
+ if (j % 2 == 0) pdf_quick_out(pdf,*r++); \
else smask[smask_ptr++] = *r++
#define write_rgb_pixel_16(r) \
- if (!(j % 8 == 6||j % 8 == 7)) pdf_buf[pdf_ptr++] = *r++; \
+ if (!(j % 8 == 6||j % 8 == 7)) pdf_quick_out(pdf,*r++); \
else smask[smask_ptr++] = *r++
#define write_rgb_pixel_8(r) \
- if (j % 4 != 3) pdf_buf[pdf_ptr++] = *r++; \
+ if (j % 4 != 3) pdf_quick_out(pdf,*r++); \
else smask[smask_ptr++] = *r++
-#define write_simple_pixel(r) pdf_buf[pdf_ptr++] = *r++
+#define write_simple_pixel(r) pdf_quick_out(pdf,*r++)
#define write_noninterlaced(outmac) \
for (i = 0; i < (int)info_p->height; i++) { \
png_read_row(png_p, row, NULL); \
r = row; \
- k = info_p->rowbytes; \
+ k = (int)info_p->rowbytes; \
while(k > 0) { \
- l = (k > pdf_buf_size)? pdf_buf_size : k; \
- pdfroom(l); \
+ l = (k > pdf->buf_size)? pdf->buf_size : k; \
+ pdf_room(pdf,l); \
for (j = 0; j < l; j++) { \
outmac; \
} \
@@ -155,10 +158,10 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
#define write_interlaced(outmac) \
for (i = 0; i < (int)info_p->height; i++) { \
row = rows[i]; \
- k = info_p->rowbytes; \
+ k = (int)info_p->rowbytes; \
while(k > 0) { \
- l = (k > pdf_buf_size)? pdf_buf_size : k;\
- pdfroom(l); \
+ l = (k > pdf->buf_size)?pdf->buf_size: k;\
+ pdf_room(pdf,l); \
for (j = 0; j < l; j++) { \
outmac; \
} \
@@ -167,22 +170,23 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
xfree(rows[i]); \
}
-static void write_png_palette(image_dict * idict)
+@ @c
+static void write_png_palette(PDF pdf, image_dict * idict)
{
int i, j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
- integer palette_objnum = 0;
+ int palette_objnum = 0;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_create_obj(0, 0);
- palette_objnum = obj_ptr;
- pdf_printf("[/Indexed /DeviceRGB %i %i 0 R]\n",
+ pdf_create_obj(pdf, obj_type_others, 0);
+ palette_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
(int) (info_p->num_palette - 1), (int) palette_objnum);
}
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
write_noninterlaced(write_simple_pixel(r));
@@ -198,32 +202,33 @@ static void write_png_palette(image_dict * idict)
write_interlaced(write_simple_pixel(row));
xfree(rows);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
if (palette_objnum > 0) {
- pdf_begin_dict(palette_objnum, 0);
- pdf_begin_stream();
+ pdf_begin_dict(pdf, palette_objnum, 0);
+ pdf_begin_stream(pdf);
for (i = 0; (unsigned) i < info_p->num_palette; i++) {
- pdfroom(3);
- pdf_buf[pdf_ptr++] = info_p->palette[i].red;
- pdf_buf[pdf_ptr++] = info_p->palette[i].green;
- pdf_buf[pdf_ptr++] = info_p->palette[i].blue;
+ pdf_room(pdf, 3);
+ pdf_quick_out(pdf, info_p->palette[i].red);
+ pdf_quick_out(pdf, info_p->palette[i].green);
+ pdf_quick_out(pdf, info_p->palette[i].blue);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
}
-static void write_png_gray(image_dict * idict)
+@ @c
+static void write_png_gray(PDF pdf, image_dict * idict)
{
int i, j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
}
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
write_noninterlaced(write_simple_pixel(r));
@@ -239,34 +244,35 @@ static void write_png_gray(image_dict * idict)
write_interlaced(write_simple_pixel(row));
xfree(rows);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
-static void write_png_gray_alpha(image_dict * idict)
+@ @c
+static void write_png_gray_alpha(PDF pdf, image_dict * idict)
{
int i, j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
- integer smask_objnum = 0;
+ int smask_objnum = 0;
png_bytep smask;
- integer smask_ptr = 0;
- integer smask_size = 0;
+ int smask_ptr = 0;
+ int smask_size = 0;
int bitdepth;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
}
- pdf_create_obj(0, 0);
- smask_objnum = obj_ptr;
- pdf_printf("/SMask %i 0 R\n", (int) smask_objnum);
- smask_size = (info_p->rowbytes / 2) * info_p->height;
- smask = xtalloc(smask_size, png_byte);
- pdf_begin_stream();
+ pdf_create_obj(pdf, obj_type_others, 0);
+ smask_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
+ smask_size = (int) ((info_p->rowbytes / 2) * info_p->height);
+ smask = xtalloc((unsigned) smask_size, png_byte);
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_noninterlaced(write_gray_pixel_16(r));
} else {
write_noninterlaced(write_gray_pixel_8(r));
@@ -280,49 +286,50 @@ static void write_png_gray_alpha(image_dict * idict)
for (i = 0; (unsigned) i < info_p->height; i++)
rows[i] = xtalloc(info_p->rowbytes, png_byte);
png_read_image(png_p, rows);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_interlaced(write_gray_pixel_16(row));
} else {
write_interlaced(write_gray_pixel_8(row));
}
xfree(rows);
}
- pdf_end_stream();
- pdf_flush();
+ pdf_end_stream(pdf);
+ pdf_flush(pdf);
/* now write the Smask object */
bitdepth = (int) info_p->bit_depth;
- pdf_begin_dict(smask_objnum, 0);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ pdf_begin_dict(pdf, smask_objnum, 0);
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
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",
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
(int) info_p->width,
(int) info_p->height, (bitdepth == 16 ? 8 : bitdepth));
- pdf_puts("/ColorSpace /DeviceGray\n");
- pdf_begin_stream();
+ pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
+ pdf_begin_stream(pdf);
for (i = 0; i < smask_size; i++) {
if (i % 8 == 0)
- pdfroom(8);
- pdf_buf[pdf_ptr++] = smask[i];
+ pdf_room(pdf, 8);
+ pdf_quick_out(pdf, smask[i]);
if (bitdepth == 16)
i++;
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
xfree(smask);
}
-static void write_png_rgb(image_dict * idict)
+@ @c
+static void write_png_rgb(PDF pdf, image_dict * idict)
{
int i, j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
}
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
write_noninterlaced(write_simple_pixel(r));
@@ -338,34 +345,35 @@ static void write_png_rgb(image_dict * idict)
write_interlaced(write_simple_pixel(row));
xfree(rows);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
-static void write_png_rgb_alpha(image_dict * idict)
+@ @c
+static void write_png_rgb_alpha(PDF pdf, image_dict * idict)
{
int i, j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
- integer smask_objnum = 0;
+ int smask_objnum = 0;
png_bytep smask;
- integer smask_ptr = 0;
- integer smask_size = 0;
+ int smask_ptr = 0;
+ int smask_size = 0;
int bitdepth;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
}
- pdf_create_obj(0, 0);
- smask_objnum = obj_ptr;
- pdf_printf("/SMask %i 0 R\n", (int) smask_objnum);
- smask_size = (info_p->rowbytes / 2) * info_p->height;
- smask = xtalloc(smask_size, png_byte);
- pdf_begin_stream();
+ pdf_create_obj(pdf, obj_type_others, 0);
+ smask_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
+ smask_size = (int) ((info_p->rowbytes / 2) * info_p->height);
+ smask = xtalloc((unsigned) smask_size, png_byte);
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_noninterlaced(write_rgb_pixel_16(r));
} else {
write_noninterlaced(write_rgb_pixel_8(r));
@@ -379,51 +387,50 @@ static void write_png_rgb_alpha(image_dict * idict)
for (i = 0; (unsigned) i < info_p->height; i++)
rows[i] = xtalloc(info_p->rowbytes, png_byte);
png_read_image(png_p, rows);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_interlaced(write_rgb_pixel_16(row));
} else {
write_interlaced(write_rgb_pixel_8(row));
}
xfree(rows);
}
- pdf_end_stream();
- pdf_flush();
+ pdf_end_stream(pdf);
+ pdf_flush(pdf);
/* now write the Smask object */
if (smask_objnum > 0) {
bitdepth = (int) info_p->bit_depth;
- pdf_begin_dict(smask_objnum, 0);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ pdf_begin_dict(pdf, smask_objnum, 0);
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
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",
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
(int) info_p->width,
(int) info_p->height, (bitdepth == 16 ? 8 : bitdepth));
- pdf_puts("/ColorSpace /DeviceGray\n");
- pdf_begin_stream();
+ pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
+ pdf_begin_stream(pdf);
for (i = 0; i < smask_size; i++) {
if (i % 8 == 0)
- pdfroom(8);
- pdf_buf[pdf_ptr++] = smask[i];
+ pdf_room(pdf, 8);
+ pdf_quick_out(pdf, smask[i]);
if (bitdepth == 16)
i++;
}
xfree(smask);
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
}
-/**********************************************************************/
-/*
- * The |copy_png| function is from Hartmut Henkel. The goal is to use
- * pdf's native FlateDecode support if that is possible.
- *
- * Only a subset of the png files allows this, but when possible it
- * greatly improves inclusion speed.
- *
- * Code cheerfully gleaned from Thomas Merz' PDFlib,
- * file p_png.c "SPNG - Simple PNG"
- */
+@ The |copy_png| function is from Hartmut Henkel. The goal is to use
+pdf's native FlateDecode support if that is possible.
+Only a subset of the png files allows this, but when possible it
+greatly improves inclusion speed.
+
+Code cheerfully gleaned from Thomas Merz' PDFlib,
+file |p_png.c| "SPNG - Simple PNG"
+
+
+@c
static int spng_getint(FILE * fp)
{
unsigned char buf[4];
@@ -435,7 +442,7 @@ static int spng_getint(FILE * fp)
#define SPNG_CHUNK_IDAT 0x49444154
#define SPNG_CHUNK_IEND 0x49454E44
-static void copy_png(image_dict * idict)
+static void copy_png(PDF pdf, image_dict * idict)
{
png_structp png_p;
png_infop info_p;
@@ -464,7 +471,7 @@ static void copy_png(image_dict * idict)
pdftex_fail("writepng: fseek in PNG file failed");
}
} while (endflag == false);
- pdf_printf("/Length %d\n"
+ pdf_printf(pdf, "/Length %d\n"
"/Filter/FlateDecode\n"
"/DecodeParms<<"
"/Colors %d"
@@ -486,17 +493,17 @@ static void copy_png(image_dict * idict)
pdftex_fail("writepng: IDAT chunk sequence broken");
idat = 1;
while (len > 0) {
- i = (len > pdf_buf_size) ? pdf_buf_size : len;
- pdfroom(i);
- fread(&pdf_buf[pdf_ptr], 1, i, fp);
- pdf_ptr += i;
+ i = (len > pdf->buf_size) ? pdf->buf_size : len;
+ pdf_room(pdf, i);
+ fread(&pdf->buf[pdf->ptr], 1, (size_t) i, fp);
+ pdf->ptr += i;
len -= i;
}
if (fseek(fp, 4, SEEK_CUR) != 0)
pdftex_fail("writepng: fseek in PNG file failed");
break;
case SPNG_CHUNK_IEND: /* done */
- pdf_end_stream();
+ pdf_end_stream(pdf);
endflag = true;
break;
default:
@@ -508,97 +515,99 @@ static void copy_png(image_dict * idict)
} while (endflag == false);
}
-static void reopen_png(image_dict * idict)
+@ @c
+static void reopen_png(PDF pdf, image_dict * idict)
{
- integer width, height, xres, yres;
+ int width, height, xres, yres;
width = img_xsize(idict); /* do consistency check */
height = img_ysize(idict);
xres = img_xres(idict);
yres = img_yres(idict);
- read_png_info(idict, IMG_KEEPOPEN);
+ read_png_info(pdf, idict, IMG_KEEPOPEN);
if (width != img_xsize(idict) || height != img_ysize(idict)
|| xres != img_xres(idict) || yres != img_yres(idict))
pdftex_fail("writepng: image dimensions have changed");
}
+@ @c
static boolean last_png_needs_page_group;
-void write_png(image_dict * idict)
+void write_png(PDF pdf, image_dict * idict)
{
double gamma, checked_gamma;
int i;
- integer palette_objnum = 0;
+ int palette_objnum = 0;
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);
+ reopen_png(pdf, idict);
assert(img_png_ptr(idict) != NULL);
png_p = img_png_png_ptr(idict);
info_p = img_png_info_ptr(idict);
- if (fixed_pdf_minor_version < 5)
- fixed_image_hicolor = 0;
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ if (pdf->minor_version < 5)
+ pdf->image_hicolor = 0;
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
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",
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
(int) info_p->width,
(int) info_p->height, (int) info_p->bit_depth);
- pdf_puts("/ColorSpace ");
+ pdf_puts(pdf, "/ColorSpace ");
checked_gamma = 1.0;
- if (fixed_image_apply_gamma) {
+ if (pdf->image_apply_gamma) {
if (png_get_gAMA(png_p, info_p, &gamma)) {
- checked_gamma = (fixed_gamma / 1000.0) * gamma;
+ checked_gamma = (pdf->gamma / 1000.0) * gamma;
} else {
- checked_gamma =
- (fixed_gamma / 1000.0) * (1000.0 / fixed_image_gamma);
+ checked_gamma = (pdf->gamma / 1000.0) * (1000.0 / pdf->image_gamma);
}
}
/* the switching between |info_p| and |png_p| queries has been trial and error.
*/
- if (fixed_pdf_minor_version > 1 && info_p->interlace_type == PNG_INTERLACE_NONE && (png_p->transformations == 0 || png_p->transformations == 0x2000) /* gamma */
+ if (pdf->minor_version > 1 && info_p->interlace_type == PNG_INTERLACE_NONE &&
+ (png_p->transformations == 0 || png_p->transformations == 0x2000) /* gamma */
&&!(png_p->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
png_p->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- && (fixed_image_hicolor || (png_p->bit_depth <= 8))
+ && ((pdf->image_hicolor != 0) || (png_p->bit_depth <= 8))
&& (checked_gamma <= 1.01 && checked_gamma > 0.99)
) {
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
switch (info_p->color_type) {
case PNG_COLOR_TYPE_PALETTE:
- pdf_create_obj(0, 0);
- palette_objnum = obj_ptr;
- pdf_printf("[/Indexed /DeviceRGB %i %i 0 R]\n",
+ pdf_create_obj(pdf, obj_type_others, 0);
+ palette_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
(int) (info_p->num_palette - 1),
(int) palette_objnum);
break;
case PNG_COLOR_TYPE_GRAY:
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
break;
default: /* RGB */
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
};
}
if (tracefilenames)
tex_printf(" (PNG copy)");
- copy_png(idict);
+ copy_png(pdf, idict);
if (palette_objnum > 0) {
- pdf_begin_dict(palette_objnum, 0);
- pdf_begin_stream();
+ pdf_begin_dict(pdf, palette_objnum, 0);
+ pdf_begin_stream(pdf);
for (i = 0; (unsigned) i < info_p->num_palette; i++) {
- pdfroom(3);
- pdf_buf[pdf_ptr++] = info_p->palette[i].red;
- pdf_buf[pdf_ptr++] = info_p->palette[i].green;
- pdf_buf[pdf_ptr++] = info_p->palette[i].blue;
+ pdf_room(pdf, 3);
+ pdf_quick_out(pdf, info_p->palette[i].red);
+ pdf_quick_out(pdf, info_p->palette[i].green);
+ pdf_quick_out(pdf, info_p->palette[i].blue);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
} else {
if (0) {
tex_printf(" PNG copy skipped because: ");
- if (fixed_image_apply_gamma &&
+ if ((pdf->image_apply_gamma != 0) &&
(checked_gamma > 1.01 || checked_gamma < 0.99))
tex_printf("gamma delta=%lf ", checked_gamma);
if (png_p->transformations != PNG_TRANSFORM_IDENTITY)
@@ -607,8 +616,8 @@ void write_png(image_dict * idict)
&& (info_p->color_type != PNG_COLOR_TYPE_RGB)
&& (info_p->color_type != PNG_COLOR_TYPE_PALETTE))
tex_printf("colortype ");
- if (fixed_pdf_minor_version <= 1)
- tex_printf("version=%d ", (int) fixed_pdf_minor_version);
+ if (pdf->minor_version <= 1)
+ tex_printf("version=%d ", pdf->minor_version);
if (info_p->interlace_type != PNG_INTERLACE_NONE)
tex_printf("interlaced ");
if (info_p->bit_depth > 8)
@@ -618,56 +627,63 @@ void write_png(image_dict * idict)
}
switch (info_p->color_type) {
case PNG_COLOR_TYPE_PALETTE:
- write_png_palette(idict);
+ write_png_palette(pdf, idict);
break;
case PNG_COLOR_TYPE_GRAY:
- write_png_gray(idict);
+ write_png_gray(pdf, idict);
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
- if (fixed_pdf_minor_version >= 4) {
- write_png_gray_alpha(idict);
+ if (pdf->minor_version >= 4) {
+ write_png_gray_alpha(pdf, idict);
last_png_needs_page_group = true;
} else
- write_png_gray(idict);
+ write_png_gray(pdf, idict);
break;
case PNG_COLOR_TYPE_RGB:
- write_png_rgb(idict);
+ write_png_rgb(pdf, idict);
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
- if (fixed_pdf_minor_version >= 4) {
- write_png_rgb_alpha(idict);
+ if (pdf->minor_version >= 4) {
+ write_png_rgb_alpha(pdf, idict);
last_png_needs_page_group = true;
} else
- write_png_rgb(idict);
+ write_png_rgb(pdf, idict);
break;
default:
pdftex_fail("unsupported type of color_type <%i>",
info_p->color_type);
}
}
- pdf_flush();
+ pdf_flush(pdf);
close_and_cleanup_png(idict);
}
+@ @c
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)
+@ Called after the xobject generated by |write_png| has been finished; used to
+write out additional objects
+@c
+void write_additional_png_objects(PDF pdf)
{
- return; /* this interferes with current macro-based usage and cannot be configured */
+ (void) pdf;
+ (void) transparent_page_group;
+ (void) transparent_page_group_was_written;
+ return; /* this interferes with current macro-based usage and cannot be configured */
+#if 0
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_begin_obj(pdf, transparent_page_group, 2);
+ if (pdf->compress_level == 0) {
+ pdf_puts(pdf, "%PTEX Group needed for transparent pngs\n");
}
pdf_puts
- ("<</Type/Group /S/Transparency /CS/DeviceRGB /I true /K true>>\n");
- pdf_end_obj();
+ (pdf,
+ "<</Type/Group /S/Transparency /CS/DeviceRGB /I true /K true>>\n");
+ pdf_end_obj(pdf);
}
}
+#endif
}
diff --git a/Build/source/texk/web2c/luatexdir/inc-epdf.h b/Build/source/texk/web2c/luatexdir/inc-epdf.h
deleted file mode 100644
index b59a2e1be9f..00000000000
--- a/Build/source/texk/web2c/luatexdir/inc-epdf.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* prototypes used in image/pdftoepdf.cc and in C code */
-
-/* image/epdf.c */
- extern void epdf_mark_glyphs(fd_entry *, char *);
- extern fd_entry *epdf_create_fontdescriptor(fm_entry *, int);
-
-/* font/writeenc.c */
- extern void epdf_write_enc(char **, integer);
diff --git a/Build/source/texk/web2c/luatexdir/inc-extra.h b/Build/source/texk/web2c/luatexdir/inc-extra.h
deleted file mode 100644
index 98ca98f8670..00000000000
--- a/Build/source/texk/web2c/luatexdir/inc-extra.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* from lua/lnodelib.c */
-
-extern halfword *check_isnode(lua_State * L, int ud);
-extern void lua_nodelib_push_fast(lua_State * L, halfword n);
diff --git a/Build/source/texk/web2c/luatexdir/inc-vfovf.h b/Build/source/texk/web2c/luatexdir/inc-vfovf.h
deleted file mode 100644
index eb624f9519c..00000000000
--- a/Build/source/texk/web2c/luatexdir/inc-vfovf.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* this function is in vfovf.c for the moment */
-extern int make_vf_table(lua_State * L, const char *name, scaled s);
diff --git a/Build/source/texk/web2c/luatexdir/lang/hnjalloc.c b/Build/source/texk/web2c/luatexdir/lang/hnjalloc.c
deleted file mode 100644
index 6072152f4f5..00000000000
--- a/Build/source/texk/web2c/luatexdir/lang/hnjalloc.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* LibHnj is dual licensed under LGPL and MPL. Boilerplate for both
- * licenses follows.
- */
-
-/* LibHnj - a library for high quality hyphenation and justification
- * Copyright (C) 1998 Raph Levien, (C) 2001 ALTLinux, Moscow
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307 USA.
-*/
-
-/*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "MPL"); you may not use this file except in
- * compliance with the MPL. You may obtain a copy of the MPL at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the MPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MPL
- * for the specific language governing rights and limitations under the
- * MPL.
- *
- */
-/* wrappers for malloc */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "hnjalloc.h"
-
-void *
-hnj_malloc (int size)
-{
- void *p;
-
- p = malloc (size);
- if (p == NULL)
- {
- fprintf (stderr, "can't allocate %d bytes\n", size);
- exit (1);
- }
- return p;
-}
-
-void *
-hnj_realloc (void *p, int size)
-{
- p = realloc (p, size);
- if (p == NULL)
- {
- fprintf (stderr, "can't allocate %d bytes\n", size);
- exit (1);
- }
- return p;
-}
-
-void
-hnj_free (void *p)
-{
- free (p);
-}
-
diff --git a/Build/source/texk/web2c/luatexdir/lang/hnjalloc.h b/Build/source/texk/web2c/luatexdir/lang/hnjalloc.h
index db82fb9c758..1af5a3f0ea3 100644
--- a/Build/source/texk/web2c/luatexdir/lang/hnjalloc.h
+++ b/Build/source/texk/web2c/luatexdir/lang/hnjalloc.h
@@ -35,12 +35,8 @@
*/
/* wrappers for malloc */
-void *
-hnj_malloc (int size);
+void *hnj_malloc(int size);
-void *
-hnj_realloc (void *p, int size);
-
-void
-hnj_free (void *p);
+void *hnj_realloc(void *p, int size);
+void hnj_free(void *p);
diff --git a/Build/source/texk/web2c/luatexdir/lang/hnjalloc.w b/Build/source/texk/web2c/luatexdir/lang/hnjalloc.w
new file mode 100644
index 00000000000..c7d595cdd75
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lang/hnjalloc.w
@@ -0,0 +1,66 @@
+% LibHnj is dual licensed under LGPL and MPL. Boilerplate for both
+% licenses follows.
+%
+%
+% LibHnj - a library for high quality hyphenation and justification
+% Copyright (C) 1998 Raph Levien, (C) 2001 ALTLinux, Moscow
+%
+% This library is free software; you can redistribute it and/or
+% modify it under the terms of the GNU Library General Public
+% License as published by the Free Software Foundation; either
+% version 2 of the License, or (at your option) any later version.
+%
+% This library is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% Library General Public License for more details.
+%
+% You should have received a copy of the GNU Library General Public
+% License along with this library; if not, write to the
+% Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+% Boston, MA 02111-1307 USA.
+%
+%
+%
+% The contents of this file are subject to the Mozilla Public License
+% Version 1.0 (the "MPL"); you may not use this file except in
+% compliance with the MPL. You may obtain a copy of the MPL at
+% http://www.mozilla.org/MPL/
+%
+% Software distributed under the MPL is distributed on an "AS IS" basis,
+% WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MPL
+% for the specific language governing rights and limitations under the
+% MPL.
+
+@ wrappers for malloc
+@c
+
+#include <stdlib.h>
+#include <stdio.h>
+
+void *hnj_malloc(int size)
+{
+ void *p;
+
+ p = malloc((size_t) size);
+ if (p == NULL) {
+ fprintf(stderr, "can't allocate %d bytes\n", size);
+ exit(1);
+ }
+ return p;
+}
+
+void *hnj_realloc(void *p, int size)
+{
+ p = realloc(p, (size_t) size);
+ if (p == NULL) {
+ fprintf(stderr, "can't allocate %d bytes\n", size);
+ exit(1);
+ }
+ return p;
+}
+
+void hnj_free(void *p)
+{
+ free(p);
+}
diff --git a/Build/source/texk/web2c/luatexdir/lang/hyphen.c b/Build/source/texk/web2c/luatexdir/lang/hyphen.c
deleted file mode 100644
index edcad69adff..00000000000
--- a/Build/source/texk/web2c/luatexdir/lang/hyphen.c
+++ /dev/null
@@ -1,850 +0,0 @@
-/* Libhnj is dual licensed under LGPL and MPL. Boilerplate for both
- * licenses follows.
- */
-
-/* LibHnj - a library for high quality hyphenation and justification
- * Copyright (C) 1998 Raph Levien,
- * (C) 2001 ALTLinux, Moscow (http://www.alt-linux.org),
- * (C) 2001 Peter Novodvorsky (nidd@cs.msu.su)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307 USA.
-*/
-
-/*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "MPL"); you may not use this file except in
- * compliance with the MPL. You may obtain a copy of the MPL at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the MPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MPL
- * for the specific language governing rights and limitations under the
- * MPL.
- *
- */
-#include <stdlib.h> /* for NULL, malloc */
-#include <stdio.h> /* for fprintf */
-#include <string.h> /* for strdup */
-#include <stdlib.h> /* for malloc used by substring inclusion*/
-
-#define MAXPATHS 40960
-
-#ifdef UNX
-#include <unistd.h> /* for exit */
-#endif
-
-#include <ctype.h>
-
-/*#define VERBOSE*/
-
-#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
-) {
- unsigned char *new;
- int l;
-
- l = strlen ((const char*)s);
- new = hnj_malloc (l + 1);
- memcpy (new, s, l);
- new[l] = 0;
- return new;
-}
-
-static int is_utf8_follow(
- unsigned char c
-) {
- if (c>=0x80 && c<0xC0) return 1;
- return 0;
-}
-
-/* --------------------------------------------------------------------
- *
- * Type definitions
- *
- * --------------------------------------------------------------------
- */
-
-/* a little bit of a hash table implementation. This simply maps strings
- to state numbers */
-
-typedef struct _HashTab HashTab;
-typedef struct _HashEntry HashEntry;
-typedef struct _HashIter HashIter;
-typedef union _HashVal HashVal;
-
-/* A cheap, but effective, hack. */
-#define HASH_SIZE 31627
-
-struct _HashTab {
- HashEntry *entries[HASH_SIZE];
-};
-
-union _HashVal {
- int state;
- char* hyppat;
-};
-
-struct _HashEntry {
- HashEntry *next;
- unsigned char *key;
- HashVal u;
-};
-
-struct _HashIter {
- HashEntry** e;
- HashEntry* cur;
- int ndx;
-};
-
-/* State machine */
-typedef struct _HyphenState HyphenState;
-typedef struct _HyphenTrans HyphenTrans;
-#define MAX_CHARS 256
-#define MAX_NAME 20
-
-struct _HyphenDict {
- int num_states;
- int pat_length;
- char cset[MAX_NAME];
- HyphenState *states;
- HashTab *patterns;
- HashTab *merged;
- HashTab *state_num;
-};
-
-struct _HyphenState {
- char *match;
- /*char *repl;*/
- /*signed char replindex;*/
- /*signed char replcut;*/
- int fallback_state;
- int num_trans;
- HyphenTrans *trans;
-};
-
-struct _HyphenTrans {
- int uni_ch;
- int new_state;
-};
-
-
-/* Combine two right-aligned number patterns, 04000 + 020 becomes 04020*/
-static char *combine(
- char *expr,
- const char *subexpr
-) {
- int l1 = strlen(expr);
- int l2 = strlen(subexpr);
- int off = l1-l2;
- int j;
- /* this works also for utf8 sequences because the substring is identical
- * to the last substring-length bytes of expr except for the (single byte)
- * hyphenation encoders
- */
- for (j=0; j<l2; j++) {
- if (expr[off+j]<subexpr[j]) expr[off+j] = subexpr[j];
- }
- return expr;
-}
-
-
-/* --------------------------------------------------------------------
- * ORIGINAL CODE
- * --------------------------------------------------------------------
- */
-
-static HashIter* new_HashIter(
- HashTab* h
-) {
- HashIter* i = hnj_malloc(sizeof(HashIter));
- i->e = h->entries;
- i->cur = NULL;
- i->ndx = -1;
- return i;
-}
-
-
-static int nextHashStealPattern(
- HashIter*i,
- unsigned char**word,
- char **pattern
-) {
- while (i->cur==NULL) {
- if (i->ndx >= HASH_SIZE-1) return 0;
- i->cur = i->e[++i->ndx];
- }
- *word = i->cur->key;
- *pattern = i->cur->u.hyppat;
- i->cur->u.hyppat = NULL;
- i->cur = i->cur->next;
- return 1;
-}
-
-
-static int nextHash(
- HashIter*i,
- unsigned char**word
-) {
- while (i->cur==NULL) {
- if (i->ndx >= HASH_SIZE-1) return 0;
- i->cur = i->e[++i->ndx];
- }
- *word = i->cur->key;
- i->cur = i->cur->next;
- return 1;
-}
-
-
-static int eachHash(
- HashIter*i,
- unsigned char**word,
- char**pattern
-) {
- while (i->cur==NULL) {
- if (i->ndx >= HASH_SIZE-1) return 0;
- i->cur = i->e[++i->ndx];
- }
- *word = i->cur->key;
- *pattern = i->cur->u.hyppat;
- i->cur = i->cur->next;
- return 1;
-}
-
-
-static void delete_HashIter(
- HashIter*i
-) {
- hnj_free(i);
-}
-
-
-/* a char* hash function from ASU - adapted from Gtk+ */
-static unsigned int hnj_string_hash (
- const unsigned char *s
-) {
- const unsigned char *p;
- unsigned int h=0, g;
-
- for (p = s; *p != '\0'; p += 1) {
- h = ( h << 4 ) + *p;
- if ( ( g = h & 0xf0000000 ) ) {
- h = h ^ (g >> 24);
- h = h ^ g;
- }
- }
- return h /* % M */;
-}
-
-
-/* assumes that key is not already present! */
-static void state_insert(
- HashTab *hashtab,
- unsigned char *key,
- int state
-) {
- int i;
- HashEntry *e;
-
- i = hnj_string_hash (key) % HASH_SIZE;
- e = hnj_malloc (sizeof(HashEntry));
- e->next = hashtab->entries[i];
- e->key = key;
- e->u.state = state;
- hashtab->entries[i] = e;
-}
-
-
-/* assumes that key is not already present! */
-static void hyppat_insert(
- HashTab *hashtab,
- unsigned char *key,
- char* hyppat
-) {
- int i;
- HashEntry *e;
-
- 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) {
- 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;
- }
- }
- e = hnj_malloc (sizeof(HashEntry));
- e->next = hashtab->entries[i];
- e->key = key;
- e->u.hyppat = hyppat;
- hashtab->entries[i] = e;
-}
-
-
-/* return state if found, otherwise -1 */
-static int state_lookup(
- HashTab *hashtab,
- const unsigned char *key
-) {
- int i;
- HashEntry *e;
-
- i = hnj_string_hash (key) % HASH_SIZE;
- for (e = hashtab->entries[i]; e; e = e->next) {
- if (!strcmp ((const char*)key, (const char*)e->key)) {
- return e->u.state;
- }
- }
- return -1;
-}
-
-
-/* return state if found, otherwise -1 */
-static char* hyppat_lookup(
- HashTab *hashtab,
- const unsigned char *chars,
- int l
-) {
- int i;
- HashEntry *e;
- unsigned char key[128]; /* should be ample*/
- strncpy((char*)key,(const char*)chars,l); key[l]=0;
- i = hnj_string_hash (key) % HASH_SIZE;
- for (e = hashtab->entries[i]; e; e = e->next) {
- if (!strcmp ((char*)key, (char*)e->key)) {
- return e->u.hyppat;
- }
- }
- return NULL;
-}
-
-
-/* Get the state number, allocating a new state if necessary. */
-static int hnj_get_state(
- HyphenDict *dict,
- const unsigned char *string,
- int *state_num
-) {
- *state_num = state_lookup(dict->state_num, string);
-
- if (*state_num >= 0)
- return *state_num;
-
- state_insert(dict->state_num, hnj_strdup(string), dict->num_states);
- /* predicate is true if dict->num_states is a power of two */
- if (!(dict->num_states & (dict->num_states - 1))) {
- dict->states = hnj_realloc(
- dict->states,
- (dict->num_states << 1) * sizeof(HyphenState));
- }
- dict->states[dict->num_states].match = NULL;
- dict->states[dict->num_states].fallback_state = -1;
- dict->states[dict->num_states].num_trans = 0;
- dict->states[dict->num_states].trans = NULL;
- return dict->num_states++;
-}
-
-
-/* add a transition from state1 to state2 through ch - assumes that the
- transition does not already exist */
-static void hnj_add_trans(
- HyphenDict *dict,
- int state1,
- int state2,
- int uni_ch
-) {
- int num_trans;
- /* TH: this test was a bit too strict, it is quite normal for old
- patterns to have chars in the range 0-31 or 127-159 (inclusive).
- To ease the transition, let's only disallow NUL for now
- (this is probably a requirement of the code anyway).
- */
- if (uni_ch==0) {
- fprintf(stderr,"Character out of bounds: u%04x \n",uni_ch);
- exit(1);
- }
- num_trans = dict->states[state1].num_trans;
- if (num_trans == 0) {
- dict->states[state1].trans = hnj_malloc(sizeof(HyphenTrans));
- } else if (!(num_trans & (num_trans - 1))) {
- dict->states[state1].trans = hnj_realloc(
- dict->states[state1].trans,
- (num_trans << 1) * sizeof(HyphenTrans));
- }
- dict->states[state1].trans[num_trans].uni_ch = uni_ch;
- dict->states[state1].trans[num_trans].new_state = state2;
- dict->states[state1].num_trans++;
-}
-
-
-#ifdef VERBOSE
-
-static unsigned char *get_state_str(
- int state
-) {
- int i;
- HashEntry *e;
-
- for (i = 0; i < HASH_SIZE; i++)
- for (e = global->entries[i]; e; e = e->next)
- if (e->u.state == state)
- return e->key;
- return NULL;
-}
-#endif
-
-
-/* I've changed the semantics a bit here: hnj_hyphen_load used to
- operate on a file, but now the argument is a string buffer.
- */
-
-static const unsigned char* next_pattern(
- size_t* length,
- const unsigned char **buf
-) {
- const unsigned char *here, *rover = *buf;
- while (*rover && isspace(*rover)) rover++;
- here = rover;
- while (*rover) {
- if (isspace(*rover)) {
- *length = rover-here;
- *buf = rover;
- return here;
- }
- rover++;
- }
- *length = rover-here;
- *buf = rover;
- return *length ? here : NULL; /* zero sensed */
-}
-
-static void init_hash(
- HashTab**h
-) {
- int i;
- if (*h) return;
- *h = hnj_malloc(sizeof(HashTab));
- for (i = 0; i < HASH_SIZE; i++) (*h)->entries[i] = NULL;
-}
-
-
-static void clear_state_hash(
- HashTab**h
-) {
- int i;
- if (*h==NULL) return;
- for (i = 0; i < HASH_SIZE; i++) {
- HashEntry *e, *next;
- for (e = (*h)->entries[i]; e; e = next) {
- next = e->next;
- hnj_free (e->key);
- hnj_free (e);
- }
- }
- hnj_free(*h);
- *h=NULL;
-}
-
-
-static void clear_hyppat_hash(
- HashTab**h
-) {
- int i;
- if (*h==NULL) return;
- for (i = 0; i < HASH_SIZE; i++) {
- HashEntry *e, *next;
- for (e = (*h)->entries[i]; e; e = next) {
- next = e->next;
- hnj_free(e->key);
- if (e->u.hyppat) hnj_free(e->u.hyppat);
- hnj_free(e);
- }
- }
- hnj_free(*h);
- *h=NULL;
-}
-
-
-static void init_dict(
- HyphenDict* dict
-) {
- dict->num_states = 1;
- dict->pat_length = 0;
- dict->states = hnj_malloc (sizeof(HyphenState));
- dict->states[0].match = NULL;
- dict->states[0].fallback_state = -1;
- dict->states[0].num_trans = 0;
- dict->states[0].trans = NULL;
- dict->patterns = NULL;
- dict->merged = NULL;
- dict->state_num = NULL;
- init_hash(&dict->patterns);
-}
-
-
-static void clear_dict(
- HyphenDict* dict
-) {
- int state_num;
- for (state_num = 0; state_num < dict->num_states; state_num++) {
- HyphenState *hstate = &dict->states[state_num];
- if (hstate->match) hnj_free (hstate->match);
- if (hstate->trans) hnj_free (hstate->trans);
- }
- hnj_free (dict->states);
- clear_hyppat_hash(&dict->patterns);
- clear_hyppat_hash(&dict->merged);
- clear_state_hash(&dict->state_num);
-}
-
-
-
-HyphenDict* hnj_hyphen_new(void) {
- HyphenDict* dict = hnj_malloc (sizeof(HyphenDict));
- init_dict(dict);
- return dict;
-}
-
-
-void hnj_hyphen_clear(
- HyphenDict* dict
-) {
- clear_dict(dict);
- init_dict(dict);
-}
-
-
-void hnj_hyphen_free(
- HyphenDict *dict
-) {
- clear_dict(dict);
- hnj_free(dict);
-}
-
-unsigned char* hnj_serialize(
- HyphenDict* dict
-) {
- HashIter *v;
- unsigned char* word;
- char* pattern;
- unsigned char* buf = hnj_malloc(dict->pat_length);
- unsigned char* cur = buf;
- v = new_HashIter(dict->patterns);
- while (eachHash(v,&word,&pattern)) {
- int i=0, e=0;
- while(word[e+i]) {
- if (pattern[i]!='0') *cur++ = (unsigned char) pattern[i];
- *cur++ = word[e+i++];
- while (is_utf8_follow(word[e+i])) *cur++ = word[i+e++];
- }
- if (pattern[i]!='0') *cur++ = (unsigned char) pattern[i];
- *cur++ = ' ';
- }
- delete_HashIter(v);
- *cur = 0;
- return buf;
-}
-
-
-void hnj_free_serialize(
- unsigned char* c
-) {
- hnj_free(c);
-}
-
-
-/* hyphenation pattern:
- * signed bytes
- * 0 indicates end (actually any negative number)
- * : prio(1+),startpos,length,len1,[replace],len2,[replace]
- * most basic example is:
- * p n 0 0 0
- * for a hyphenation point between characters
- */
-
-
-void hnj_hyphen_load(
- HyphenDict* dict,
- const unsigned char *f
-) {
- int state_num, last_state;
- int i, j = 0;
- int ch;
- int found;
- HashEntry *e;
- HashIter *v;
- unsigned char* word;
- char* pattern;
- size_t l = 0;
-
-
- /***************************************/
-
- 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;
- /*
- printf("%s\n",format);
- char* repl = strnchr(format, '/',l);
- int replindex = 0;
- int replcut = 0;
- if (repl) {
- int clen = l-(repl-format);
- l = repl-format;
- char * index = strnchr(repl + 1, ',',clen);
- if (index) {
- char * index2 = strnchr(index + 1, ',',clen-(index-repl));
- if (index2) {
- replindex = (signed char) atoi(index + 1) - 1;
- replcut = (signed char) atoi(index2 + 1);
- }
- } else {
- hnj_strchomp(repl + 1);
- replindex = 0;
- replcut = strlen(buf);
- }
- repl = hnj_strdup(repl + 1);
- }
- */
- for (i=0,j=0,e=0; (unsigned)i<l; i++) {
- if (format[i]>='0'&&format[i]<='9') j++;
- 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*/
- org[0] = '0';
- for (i=0,j=0,e=0; (unsigned)i<l; i++) {
- unsigned char c = format[i];
- if (is_utf8_follow(c)) {
- pat[j+e++] = c;
- } else if (c<'0' || c>'9') {
- pat[e+j++] = c;
- org[j] = '0';
- } else {
- org[j] = c;
- }
- }
- pat[e+j] = 0;
- org[j+1] = 0;
- hyppat_insert(dict->patterns,pat,org);
- }
- dict->pat_length += (f-begin)+2; /* 2 for spurious spaces*/
- init_hash(&dict->merged);
- v = new_HashIter(dict->patterns);
- while (nextHash(v,&word)) {
- int wordsize = strlen((char*)word);
- int j,l;
- for (l=1; l<=wordsize; l++) {
- if (is_utf8_follow(word[l])) continue; /* Do not clip an utf8 sequence*/
- for (j=1; j<=l; j++) {
- char *subpat_pat;
- int i = l-j;
- if (is_utf8_follow(word[i])) continue; /* Do not start halfway an utf8 sequence*/
- if ((subpat_pat = hyppat_lookup(dict->patterns,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;
- strncpy((char*)newword, (char*)word,l); newword[l]=0;
- for (i=0; i<l; i++) if (is_utf8_follow(newword[i])) e++;
- neworg = malloc(l+2-e);
- sprintf(neworg,"%0*d",l+1-e,0); /* fill with right amount of '0'*/
- hyppat_insert(dict->merged,newword,combine(neworg,subpat_pat));
- } else {
- combine(newpat_pat,subpat_pat);
- }
- }
- }
- }
- }
- delete_HashIter(v);
-
- init_hash(&dict->state_num);
- state_insert(dict->state_num, hnj_strdup((const unsigned char*)""), 0);
- v = new_HashIter(dict->merged);
- while (nextHashStealPattern(v,&word,&pattern)) {
- static unsigned char mask[] = {0x3F,0x1F,0xF,0x7};
- int j = strlen((char*)word);
-#ifdef VERBOSE
- printf ("word %s pattern %s, j = %d\n", word, pattern, j);
-#endif
- state_num = hnj_get_state( dict, word, &found );
- dict->states[state_num].match = pattern;
-
- /* now, put in the prefix transitions */
- while (found < 0) {
- j--;
- last_state = state_num;
- ch = word[j];
- if (ch>=0x80) {
- int m;
- int i=1;
- while (is_utf8_follow(word[j-i])) i++;
- ch = word[j-i] & mask[i];
- m = j-i;
- while (i--) {
- ch = (ch<<6)+(0x3F & word[j-i]);
- }
- j = m;
- }
- word[j] = '\0';
- state_num = hnj_get_state (dict, word, &found);
- hnj_add_trans (dict, state_num, last_state, ch);
- }
- }
- delete_HashIter(v);
- clear_hyppat_hash(&dict->merged);
-
- /***************************************/
-
- /* put in the fallback states */
- for (i = 0; i < HASH_SIZE; i++) {
- for (e = dict->state_num->entries[i]; e; e = e->next) {
- /* do not do state==0 otherwise things get confused*/
- if (e->u.state) {
- for (j = 1; 1; j++) {
- state_num = state_lookup(dict->state_num, e->key + j);
- if (state_num >= 0) break;
- }
- dict->states[e->u.state].fallback_state = state_num;
- }
- }
- }
-#ifdef VERBOSE
- for (i = 0; i < HASH_SIZE; i++) {
- for (e = dict->state_num->entries[i]; e; e = e->next) {
- printf ("%d string %s state %d, fallback=%d\n", i, e->key, e->u.state,
- dict->states[e->u.state].fallback_state);
- for (j = 0; j < dict->states[e->u.state].num_trans; j++) {
- printf (" u%4x->%d\n", (int)dict->states[e->u.state].trans[j].uni_ch,
- dict->states[e->u.state].trans[j].new_state);
- }
- }
- }
-#endif
- clear_state_hash(&dict->state_num);
-}
-
-
-void hnj_hyphen_hyphenate(
- HyphenDict *dict,
- halfword first,
- halfword last,
- int length,
- halfword left,
- 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);
-
- /* Add a '.' to beginning and end to facilitate matching*/
- set_vlink(begin_point,first);
- set_vlink(end_point,get_vlink(last));
- set_vlink(last,end_point);
-
- for (char_num = 0; char_num < hyphen_len; char_num++) {
- /* hyphens[char_num*2] = '0'; */ /* LATER */
- /* hyphens[char_num*2+1] = '0'; */ /* LATER */
- hyphens[char_num] = '0';
- }
- /*hyphens[hyphen_len*2] = 0; */ /* LATER */
- hyphens[hyphen_len] = 0;
-
- /* now, run the finite state machine */
- 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;
- /* printf(" state %d\n",state);*/
- match = dict->states[state].match;
- if (match) {
- /* +2 because:
- * 1 string length is one bigger than offset
- * 1 hyphenation starts before first character
- */
- int offset = char_num + 2 - strlen (match);
- /* printf ("%*s%s\n", offset,"", match);*/
- int m;
- for (m = 0; match[m]; m++) {
- if (hyphens[offset+m] < match[m]) hyphens[offset+m] = match[m];
- }
- }
- goto try_next_letter;
- }
- }
- state = hstate->fallback_state;
- /* printf (" back to %d\n", state);*/
- }
- /* nothing worked, let's go to the next character*/
- state = 0;
-try_next_letter: ;
- char_num++;
- }
-
- /* restore the correct pointers*/
- set_vlink(last,get_vlink(end_point));
-
- /* pattern is ^.^w^o^r^d^.^ word_len=4, ext_word_len=6, hyphens=7
- * check ^ ^ ^ so drop first two and stop after word_len-1
- */
- for (here=first,char_num=2; here!=left; here=get_vlink(here)) char_num++;
- for (; here!=right; here=get_vlink(here)) {
- if (hyphens[char_num] & 1)
- here = insert_syllable_discretionary(here, lan);
- char_num++;
- }
- hnj_free(hyphens);
-}
diff --git a/Build/source/texk/web2c/luatexdir/hyphen.h b/Build/source/texk/web2c/luatexdir/lang/hyphen.h
index 842049e263c..8e5e5785c93 100644
--- a/Build/source/texk/web2c/luatexdir/hyphen.h
+++ b/Build/source/texk/web2c/luatexdir/lang/hyphen.h
@@ -43,7 +43,6 @@ extern "C" {
typedef struct _HyphenDict HyphenDict;
# include "ptexlib.h"
-# include "nodes.h"
HyphenDict *hnj_hyphen_new(void);
void hnj_hyphen_load(HyphenDict * dict, const unsigned char *fn);
diff --git a/Build/source/texk/web2c/luatexdir/lang/hyphen.w b/Build/source/texk/web2c/luatexdir/lang/hyphen.w
new file mode 100644
index 00000000000..f7bbe6bd843
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lang/hyphen.w
@@ -0,0 +1,857 @@
+% Libhnj is dual licensed under LGPL and MPL. Boilerplate for both
+% licenses follows.
+%
+%
+% LibHnj - a library for high quality hyphenation and justification
+% Copyright (C) 1998 Raph Levien,
+% (C) 2001 ALTLinux, Moscow (http://www.alt-linux.org),
+% (C) 2001 Peter Novodvorsky (nidd@@cs.msu.su)
+%
+% This library is free software; you can redistribute it and/or
+% modify it under the terms of the GNU Library General Public
+% License as published by the Free Software Foundation; either
+% version 2 of the License, or (at your option) any later version.
+%
+% This library is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% Library General Public License for more details.
+%
+% You should have received a copy of the GNU Library General Public
+% License along with this library; if not, write to the
+% Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+% Boston, MA 02111-1307 USA.
+%
+%
+%
+% The contents of this file are subject to the Mozilla Public License
+% Version 1.0 (the "MPL"); you may not use this file except in
+% compliance with the MPL. You may obtain a copy of the MPL at
+% http://www.mozilla.org/MPL/
+%
+% Software distributed under the MPL is distributed on an "AS IS" basis,
+% WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MPL
+% for the specific language governing rights and limitations under the
+% MPL.
+
+
+@ @c
+#include <stdlib.h> /* for NULL, malloc */
+#include <stdio.h> /* for fprintf */
+#include <string.h> /* for strdup */
+#include <stdlib.h> /* for malloc used by substring inclusion */
+
+#define MAXPATHS 40960
+
+#ifdef UNX
+# include <unistd.h> /* for exit */
+#endif
+
+#include <kpathsea/c-ctype.h>
+
+#define noVERBOSE
+
+#include "lang/hnjalloc.h"
+#include "lang/hyphen.h"
+
+@ @c
+static const char _svn_version[] =
+ "$Id: hyphen.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lang/hyphen.w $";
+
+@ TODO: should be moved to separate library
+
+@c
+static unsigned char *hnj_strdup(const unsigned char *s)
+{
+ unsigned char *new;
+ size_t l;
+
+ l = strlen((const char *) s);
+ new = hnj_malloc((int) l + 1);
+ memcpy(new, s, l);
+ new[l] = 0;
+ return new;
+}
+
+static int is_utf8_follow(unsigned char c)
+{
+ if (c >= 0x80 && c < 0xC0)
+ return 1;
+ return 0;
+}
+
+@* Type definitions.
+
+@ a little bit of a hash table implementation. This simply maps strings
+ to state numbers
+
+@c
+typedef struct _HashTab HashTab;
+typedef struct _HashEntry HashEntry;
+typedef struct _HashIter HashIter;
+typedef union _HashVal HashVal;
+
+/* A cheap, but effective, hack. */
+#define HASH_SIZE 31627
+
+struct _HashTab {
+ HashEntry *entries[HASH_SIZE];
+};
+
+union _HashVal {
+ int state;
+ char *hyppat;
+};
+
+struct _HashEntry {
+ HashEntry *next;
+ unsigned char *key;
+ HashVal u;
+};
+
+struct _HashIter {
+ HashEntry **e;
+ HashEntry *cur;
+ int ndx;
+};
+
+@ State machine
+
+@c
+typedef struct _HyphenState HyphenState;
+typedef struct _HyphenTrans HyphenTrans;
+#define MAX_CHARS 256
+#define MAX_NAME 20
+
+struct _HyphenDict {
+ int num_states;
+ int pat_length;
+ char cset[MAX_NAME];
+ HyphenState *states;
+ HashTab *patterns;
+ HashTab *merged;
+ HashTab *state_num;
+};
+
+struct _HyphenState {
+ char *match;
+ /*char *repl; */
+ /*signed char replindex; */
+ /*signed char replcut; */
+ int fallback_state;
+ int num_trans;
+ HyphenTrans *trans;
+};
+
+struct _HyphenTrans {
+ int uni_ch;
+ int new_state;
+};
+
+
+@ Combine two right-aligned number patterns, 04000 + 020 becomes 04020
+
+@c
+static char *combine(char *expr, const char *subexpr)
+{
+ size_t l1 = strlen(expr);
+ size_t l2 = strlen(subexpr);
+ size_t off = l1 - l2;
+ unsigned j;
+ /* this works also for utf8 sequences because the substring is identical
+ to the last substring-length bytes of expr except for the (single byte)
+ hyphenation encoders
+ */
+ for (j = 0; j < l2; j++) {
+ if (expr[off + j] < subexpr[j])
+ expr[off + j] = subexpr[j];
+ }
+ return expr;
+}
+
+
+@ ORIGINAL CODE
+@c
+HashIter *new_HashIter(HashTab * h)
+{
+ HashIter *i = hnj_malloc(sizeof(HashIter));
+ i->e = h->entries;
+ i->cur = NULL;
+ i->ndx = -1;
+ return i;
+}
+
+
+int nextHashStealPattern(HashIter * i, unsigned char **word, char **pattern)
+{
+ while (i->cur == NULL) {
+ if (i->ndx >= HASH_SIZE - 1)
+ return 0;
+ i->cur = i->e[++i->ndx];
+ }
+ *word = i->cur->key;
+ *pattern = i->cur->u.hyppat;
+ i->cur->u.hyppat = NULL;
+ i->cur = i->cur->next;
+ return 1;
+}
+
+
+int nextHash(HashIter * i, unsigned char **word)
+{
+ while (i->cur == NULL) {
+ if (i->ndx >= HASH_SIZE - 1)
+ return 0;
+ i->cur = i->e[++i->ndx];
+ }
+ *word = i->cur->key;
+ i->cur = i->cur->next;
+ return 1;
+}
+
+
+int eachHash(HashIter * i, unsigned char **word, char **pattern)
+{
+ while (i->cur == NULL) {
+ if (i->ndx >= HASH_SIZE - 1)
+ return 0;
+ i->cur = i->e[++i->ndx];
+ }
+ *word = i->cur->key;
+ *pattern = i->cur->u.hyppat;
+ i->cur = i->cur->next;
+ return 1;
+}
+
+
+void delete_HashIter(HashIter * i)
+{
+ hnj_free(i);
+}
+
+
+@ a |char*| hash function from ASU - adapted from Gtk+
+
+@c
+static unsigned int hnj_string_hash(const unsigned char *s)
+{
+ const unsigned char *p;
+ unsigned int h = 0, g;
+
+ for (p = s; *p != '\0'; p += 1) {
+ h = (h << 4) + *p;
+ if ((g = (h & 0xf0000000))) {
+ h = h ^ (g >> 24);
+ h = h ^ g;
+ }
+ }
+ return h /* \% M */ ;
+}
+
+
+@ assumes that key is not already present!
+
+@c
+static void state_insert(HashTab * hashtab, unsigned char *key, int state)
+{
+ int i;
+ HashEntry *e;
+
+ i = (int) (hnj_string_hash(key) % HASH_SIZE);
+ e = hnj_malloc(sizeof(HashEntry));
+ e->next = hashtab->entries[i];
+ e->key = key;
+ e->u.state = state;
+ hashtab->entries[i] = e;
+}
+
+
+@ assumes that key is not already present!
+
+@c
+static void hyppat_insert(HashTab * hashtab, unsigned char *key, char *hyppat)
+{
+ int i;
+ HashEntry *e;
+
+ i = (int) (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) {
+ if (hyppat
+ && strcmp((char *) e->u.hyppat, (char *) hyppat) != 0) {
+ print_err("Conflicting pattern ignored");
+ error();
+ }
+ hnj_free(e->u.hyppat);
+ }
+ e->u.hyppat = hyppat;
+ hnj_free(key);
+ return;
+ }
+ }
+ e = hnj_malloc(sizeof(HashEntry));
+ e->next = hashtab->entries[i];
+ e->key = key;
+ e->u.hyppat = hyppat;
+ hashtab->entries[i] = e;
+}
+
+
+@ return state if found, otherwise $-1$
+
+@c
+static int state_lookup(HashTab * hashtab, const unsigned char *key)
+{
+ int i;
+ HashEntry *e;
+
+ i = (int) (hnj_string_hash(key) % HASH_SIZE);
+ for (e = hashtab->entries[i]; e; e = e->next) {
+ if (!strcmp((const char *) key, (const char *) e->key)) {
+ return e->u.state;
+ }
+ }
+ return -1;
+}
+
+
+@ return state if found, otherwise $-1$
+
+@c
+static char *hyppat_lookup(HashTab * hashtab, const unsigned char *chars, int l)
+{
+ int i;
+ HashEntry *e;
+ unsigned char key[128]; /* should be ample */
+ strncpy((char *) key, (const char *) chars, (size_t) l);
+ key[l] = 0;
+ i = (int) (hnj_string_hash(key) % HASH_SIZE);
+ for (e = hashtab->entries[i]; e; e = e->next) {
+ if (!strcmp((char *) key, (char *) e->key)) {
+ return e->u.hyppat;
+ }
+ }
+ return NULL;
+}
+
+
+@ Get the state number, allocating a new state if necessary.
+
+@c
+static int hnj_get_state(HyphenDict * dict,
+ const unsigned char *str, int *state_num)
+{
+ *state_num = state_lookup(dict->state_num, str);
+
+ if (*state_num >= 0)
+ return *state_num;
+
+ state_insert(dict->state_num, hnj_strdup(str), dict->num_states);
+ /* predicate is true if |dict->num_states| is a power of two */
+ if (!(dict->num_states & (dict->num_states - 1))) {
+ dict->states = hnj_realloc(dict->states,
+ (int) ((dict->num_states << 1) *
+ (int) sizeof(HyphenState)));
+ }
+ dict->states[dict->num_states].match = NULL;
+ dict->states[dict->num_states].fallback_state = -1;
+ dict->states[dict->num_states].num_trans = 0;
+ dict->states[dict->num_states].trans = NULL;
+ return dict->num_states++;
+}
+
+
+@ Add a transition from state1 to state2 through ch - assumes that the
+ transition does not already exist
+
+@c
+static void hnj_add_trans(HyphenDict * dict, int state1, int state2, int uni_ch)
+{
+ int num_trans;
+ /* TH: this test was a bit too strict, it is quite normal for old
+ patterns to have chars in the range 0-31 or 127-159 (inclusive).
+ To ease the transition, let's only disallow NUL for now
+ (this is probably a requirement of the code anyway).
+ */
+ if (uni_ch == 0) {
+ fprintf(stderr, "Character out of bounds: u%04x \n", uni_ch);
+ exit(1);
+ }
+ num_trans = dict->states[state1].num_trans;
+ if (num_trans == 0) {
+ dict->states[state1].trans = hnj_malloc(sizeof(HyphenTrans));
+ } else if (!(num_trans & (num_trans - 1))) {
+ dict->states[state1].trans = hnj_realloc(dict->states[state1].trans,
+ (int) (num_trans << 1 *
+ sizeof(HyphenTrans)));
+ }
+ dict->states[state1].trans[num_trans].uni_ch = uni_ch;
+ dict->states[state1].trans[num_trans].new_state = state2;
+ dict->states[state1].num_trans++;
+}
+
+
+#ifdef VERBOSE
+
+static unsigned char *get_state_str(int state)
+{
+ int i;
+ HashEntry *e;
+
+ for (i = 0; i < HASH_SIZE; i++)
+ for (e = global->entries[i]; e; e = e->next)
+ if (e->u.state == state)
+ return e->key;
+ return NULL;
+}
+#endif
+
+
+@ I've changed the semantics a bit here: |hnj_hyphen_load| used to
+ operate on a file, but now the argument is a string buffer.
+
+@c
+static const unsigned char *next_pattern(size_t * length,
+ const unsigned char **buf)
+{
+ const unsigned char *here, *rover = *buf;
+ while (*rover && isspace(*rover))
+ rover++;
+ here = rover;
+ while (*rover) {
+ if (isspace(*rover)) {
+ *length = (size_t) (rover - here);
+ *buf = rover;
+ return here;
+ }
+ rover++;
+ }
+ *length = (size_t) (rover - here);
+ *buf = rover;
+ return *length ? here : NULL; /* zero sensed */
+}
+
+static void init_hash(HashTab ** h)
+{
+ int i;
+ if (*h)
+ return;
+ *h = hnj_malloc(sizeof(HashTab));
+ for (i = 0; i < HASH_SIZE; i++)
+ (*h)->entries[i] = NULL;
+}
+
+
+static void clear_state_hash(HashTab ** h)
+{
+ int i;
+ if (*h == NULL)
+ return;
+ for (i = 0; i < HASH_SIZE; i++) {
+ HashEntry *e, *next;
+ for (e = (*h)->entries[i]; e; e = next) {
+ next = e->next;
+ hnj_free(e->key);
+ hnj_free(e);
+ }
+ }
+ hnj_free(*h);
+ *h = NULL;
+}
+
+
+static void clear_hyppat_hash(HashTab ** h)
+{
+ int i;
+ if (*h == NULL)
+ return;
+ for (i = 0; i < HASH_SIZE; i++) {
+ HashEntry *e, *next;
+ for (e = (*h)->entries[i]; e; e = next) {
+ next = e->next;
+ hnj_free(e->key);
+ if (e->u.hyppat)
+ hnj_free(e->u.hyppat);
+ hnj_free(e);
+ }
+ }
+ hnj_free(*h);
+ *h = NULL;
+}
+
+
+static void init_dict(HyphenDict * dict)
+{
+ dict->num_states = 1;
+ dict->pat_length = 0;
+ dict->states = hnj_malloc(sizeof(HyphenState));
+ dict->states[0].match = NULL;
+ dict->states[0].fallback_state = -1;
+ dict->states[0].num_trans = 0;
+ dict->states[0].trans = NULL;
+ dict->patterns = NULL;
+ dict->merged = NULL;
+ dict->state_num = NULL;
+ init_hash(&dict->patterns);
+}
+
+
+static void clear_dict(HyphenDict * dict)
+{
+ int state_num;
+ for (state_num = 0; state_num < dict->num_states; state_num++) {
+ HyphenState *hstate = &dict->states[state_num];
+ if (hstate->match)
+ hnj_free(hstate->match);
+ if (hstate->trans)
+ hnj_free(hstate->trans);
+ }
+ hnj_free(dict->states);
+ clear_hyppat_hash(&dict->patterns);
+ clear_hyppat_hash(&dict->merged);
+ clear_state_hash(&dict->state_num);
+}
+
+
+
+HyphenDict *hnj_hyphen_new(void)
+{
+ HyphenDict *dict = hnj_malloc(sizeof(HyphenDict));
+ init_dict(dict);
+ return dict;
+}
+
+
+void hnj_hyphen_clear(HyphenDict * dict)
+{
+ clear_dict(dict);
+ init_dict(dict);
+}
+
+
+void hnj_hyphen_free(HyphenDict * dict)
+{
+ clear_dict(dict);
+ hnj_free(dict);
+}
+
+unsigned char *hnj_serialize(HyphenDict * dict)
+{
+ HashIter *v;
+ unsigned char *word;
+ char *pattern;
+ unsigned char *buf = hnj_malloc(dict->pat_length);
+ unsigned char *cur = buf;
+ v = new_HashIter(dict->patterns);
+ while (eachHash(v, &word, &pattern)) {
+ int i = 0, e = 0;
+ while (word[e + i]) {
+ if (pattern[i] != '0')
+ *cur++ = (unsigned char) pattern[i];
+ *cur++ = word[e + i++];
+ while (is_utf8_follow(word[e + i]))
+ *cur++ = word[i + e++];
+ }
+ if (pattern[i] != '0')
+ *cur++ = (unsigned char) pattern[i];
+ *cur++ = ' ';
+ }
+ delete_HashIter(v);
+ *cur = 0;
+ return buf;
+}
+
+
+void hnj_free_serialize(unsigned char *c)
+{
+ hnj_free(c);
+}
+
+
+@ hyphenation pattern:
+
+signed bytes
+
+0 indicates end (actually any negative number)
+
+: prio(1+),startpos,length,len1,[replace],len2,[replace]
+
+most basic example is:
+
+p n 0 0 0
+
+for a hyphenation point between characters
+
+
+@c
+void hnj_hyphen_load(HyphenDict * dict, const unsigned char *f)
+{
+ int state_num, last_state;
+ int i, j = 0;
+ int ch;
+ int found;
+ HashEntry *e;
+ HashIter *v;
+ unsigned char *word;
+ char *pattern;
+ size_t l = 0;
+
+ 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;
+#if 0
+ printf("%s\n",format);
+ char* repl = strnchr(format, '/',l);
+ int replindex = 0;
+ int replcut = 0;
+ if (repl) {
+ int clen = l-(repl-format);
+ l = repl-format;
+ char * index = strnchr(repl + 1, ',',clen);
+ if (index) {
+ char * index2 = strnchr(index + 1, ',',clen-(index-repl));
+ if (index2) {
+ replindex = (signed char) atoi(index + 1) - 1;
+ replcut = (signed char) atoi(index2 + 1);
+ }
+ } else {
+ hnj_strchomp(repl + 1);
+ replindex = 0;
+ replcut = strlen(buf);
+ }
+ repl = hnj_strdup(repl + 1);
+ }
+#endif
+ for (i = 0, j = 0, e = 0; (unsigned) i < l; i++) {
+ if (format[i] >= '0' && format[i] <= '9')
+ j++;
+ if (is_utf8_follow(format[i]))
+ e++;
+ }
+ /* |l-e| => number of {\it characters} not {\it bytes} */
+ /* |l-j| => number of pattern bytes */
+ /* |l-e-j| => number of pattern characters */
+ pat = (unsigned char *) malloc((1 + l - (size_t) j));
+ org = (char *) malloc((size_t) (2 + l - (size_t) e - (size_t) j));
+ /* remove hyphenation encoders (digits) from pat */
+ org[0] = '0';
+ for (i = 0, j = 0, e = 0; (unsigned) i < l; i++) {
+ unsigned char c = format[i];
+ if (is_utf8_follow(c)) {
+ pat[j + e++] = c;
+ } else if (c < '0' || c > '9') {
+ pat[e + j++] = c;
+ org[j] = '0';
+ } else {
+ org[j] = (char) c;
+ }
+ }
+ pat[e + j] = 0;
+ org[j + 1] = 0;
+ hyppat_insert(dict->patterns, pat, org);
+ }
+ dict->pat_length += (int) ((f - begin) + 2); /* 2 for spurious spaces */
+ init_hash(&dict->merged);
+ v = new_HashIter(dict->patterns);
+ while (nextHash(v, &word)) {
+ int wordsize = (int) strlen((char *) word);
+ int j, l;
+ for (l = 1; l <= wordsize; l++) {
+ if (is_utf8_follow(word[l]))
+ continue; /* Do not clip an utf8 sequence */
+ for (j = 1; j <= l; j++) {
+ char *subpat_pat;
+ int i = l - j;
+ if (is_utf8_follow(word[i]))
+ continue; /* Do not start halfway an utf8 sequence */
+ if ((subpat_pat =
+ hyppat_lookup(dict->patterns, 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((size_t) (l + 1));
+ int e = 0;
+ strncpy((char *) newword, (char *) word, (size_t) l);
+ newword[l] = 0;
+ for (i = 0; i < l; i++)
+ if (is_utf8_follow(newword[i]))
+ e++;
+ neworg = malloc((size_t) (l + 2 - e));
+ sprintf(neworg, "%0*d", l + 1 - e, 0); /* fill with right amount of '0' */
+ hyppat_insert(dict->merged, newword,
+ combine(neworg, subpat_pat));
+ } else {
+ combine(newpat_pat, subpat_pat);
+ }
+ }
+ }
+ }
+ }
+ delete_HashIter(v);
+
+ init_hash(&dict->state_num);
+ state_insert(dict->state_num, hnj_strdup((const unsigned char *) ""), 0);
+ v = new_HashIter(dict->merged);
+ while (nextHashStealPattern(v, &word, &pattern)) {
+ static unsigned char mask[] = { 0x3F, 0x1F, 0xF, 0x7 };
+ int j = (int) strlen((char *) word);
+#ifdef VERBOSE
+ printf("word %s pattern %s, j = %d\n", word, pattern, j);
+#endif
+ state_num = hnj_get_state(dict, word, &found);
+ dict->states[state_num].match = pattern;
+
+ /* now, put in the prefix transitions */
+ while (found < 0) {
+ j--;
+ last_state = state_num;
+ ch = word[j];
+ if (ch >= 0x80) {
+ int m;
+ int i = 1;
+ while (is_utf8_follow(word[j - i]))
+ i++;
+ ch = word[j - i] & mask[i];
+ m = j - i;
+ while (i--) {
+ ch = (ch << 6) + (0x3F & word[j - i]);
+ }
+ j = m;
+ }
+ word[j] = '\0';
+ state_num = hnj_get_state(dict, word, &found);
+ hnj_add_trans(dict, state_num, last_state, ch);
+ }
+ }
+ delete_HashIter(v);
+ clear_hyppat_hash(&dict->merged);
+
+ /* put in the fallback states */
+ for (i = 0; i < HASH_SIZE; i++) {
+ for (e = dict->state_num->entries[i]; e; e = e->next) {
+ /* do not do state==0 otherwise things get confused */
+ if (e->u.state) {
+ for (j = 1; 1; j++) {
+ state_num = state_lookup(dict->state_num, e->key + j);
+ if (state_num >= 0)
+ break;
+ }
+ dict->states[e->u.state].fallback_state = state_num;
+ }
+ }
+ }
+#ifdef VERBOSE
+ for (i = 0; i < HASH_SIZE; i++) {
+ for (e = dict->state_num->entries[i]; e; e = e->next) {
+ printf("%d string %s state %d, fallback=%d\n", i, e->key,
+ e->u.state, dict->states[e->u.state].fallback_state);
+ for (j = 0; j < dict->states[e->u.state].num_trans; j++) {
+ printf(" u%4x->%d\n",
+ (int) dict->states[e->u.state].trans[j].uni_ch,
+ dict->states[e->u.state].trans[j].new_state);
+ }
+ }
+ }
+#endif
+ clear_state_hash(&dict->state_num);
+}
+
+@ @c
+void hnj_hyphen_hyphenate(HyphenDict * dict,
+ halfword first,
+ halfword last,
+ int length,
+ halfword left, 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 + 1);
+
+ /* Add a '.' to beginning and end to facilitate matching */
+ set_vlink(begin_point, first);
+ set_vlink(end_point, get_vlink(last));
+ set_vlink(last, end_point);
+
+ for (char_num = 0; char_num < hyphen_len; char_num++) {
+ hyphens[char_num] = '0';
+ }
+ hyphens[hyphen_len] = 0;
+
+ /* now, run the finite state machine */
+ 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) {
+#if 0
+ printf("%*s%s%c",char_num-strlen(get_state_str(state)),"",get_state_str(state),(char)ch);
+#endif
+ 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;
+#if 0
+ printf(" state %d\n",state);
+#endif
+ match = dict->states[state].match;
+ if (match) {
+ /* +2 because:
+ 1 string length is one bigger than offset
+ 1 hyphenation starts before first character
+ */
+ int offset = (int) (char_num + 2 - (int) strlen(match));
+#if 0
+ printf ("%*s%s\n", offset,"", match);
+#endif
+ int m;
+ for (m = 0; match[m]; m++) {
+ if (hyphens[offset + m] < match[m])
+ hyphens[offset + m] = match[m];
+ }
+ }
+ goto try_next_letter;
+ }
+ }
+ state = hstate->fallback_state;
+#if 0
+ printf (" back to %d\n", state);
+#endif
+ }
+ /* nothing worked, let's go to the next character */
+ state = 0;
+ try_next_letter:;
+ char_num++;
+ }
+
+ /* restore the correct pointers */
+ set_vlink(last, get_vlink(end_point));
+
+ /* pattern is \.{\^.\^w\^o\^r\^d\^.\^} |word_len|=4, |ext_word_len|=6, |hyphens|=7
+ * check \.{ \^ \^ \^ } so drop first two and stop after |word_len-1|
+ */
+ for (here = first, char_num = 2; here != left; here = get_vlink(here))
+ char_num++;
+ for (; here != right; here = get_vlink(here)) {
+ if (hyphens[char_num] & 1)
+ here = insert_syllable_discretionary(here, lan);
+ char_num++;
+ }
+ hnj_free(hyphens);
+}
diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.h b/Build/source/texk/web2c/luatexdir/lang/texlang.h
new file mode 100644
index 00000000000..b312dab1a3a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lang/texlang.h
@@ -0,0 +1,82 @@
+/* texlang.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: texlang.h 3394 2010-01-26 14:20:46Z taco $ */
+
+#ifndef TEXLANG_H
+# define TEXLANG_H
+
+typedef struct _lang_variables {
+ int pre_hyphen_char;
+ int post_hyphen_char;
+ int pre_exhyphen_char;
+ int post_exhyphen_char;
+} lang_variables;
+
+# include "lang/hyphen.h"
+
+struct tex_language {
+ HyphenDict *patterns;
+ int exceptions; /* lua registry pointer, should be replaced */
+ int id;
+ int pre_hyphen_char;
+ int post_hyphen_char;
+ int pre_exhyphen_char;
+ int post_exhyphen_char;
+};
+
+# define MAX_WORD_LEN 256 /* in chars */
+
+extern struct tex_language *new_language(int n);
+extern struct tex_language *get_language(int n);
+extern void load_patterns(struct tex_language *lang, const unsigned char *buf);
+extern void load_hyphenation(struct tex_language *lang,
+ const unsigned char *buf);
+extern int hyphenate_string(struct tex_language *lang, char *w, char **ret);
+
+extern void new_hyphenation(halfword h, halfword t);
+extern void clear_patterns(struct tex_language *lang);
+extern void clear_hyphenation(struct tex_language *lang);
+extern const char *clean_hyphenation(const char *buffer, char **cleaned);
+extern void hnj_hyphenation(halfword head, halfword tail);
+
+extern void set_pre_hyphen_char(int lan, int val);
+extern void set_post_hyphen_char(int lan, int val);
+extern int get_pre_hyphen_char(int lan);
+extern int get_post_hyphen_char(int lan);
+
+extern void set_pre_exhyphen_char(int lan, int val);
+extern void set_post_exhyphen_char(int lan, int val);
+extern int get_pre_exhyphen_char(int lan);
+extern int get_post_exhyphen_char(int lan);
+extern halfword compound_word_break(halfword t, int clang);
+
+extern void dump_language_data(void);
+extern void undump_language_data(void);
+extern char *exception_strings(struct tex_language *lang);
+
+extern void new_hyph_exceptions(void);
+extern void new_patterns(void);
+extern void new_pre_hyphen_char(void);
+extern void new_post_hyphen_char(void);
+extern void new_pre_exhyphen_char(void);
+extern void new_post_exhyphen_char(void);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.c b/Build/source/texk/web2c/luatexdir/lang/texlang.w
index 5a17b2c34b6..6fcb7180820 100644
--- a/Build/source/texk/web2c/luatexdir/lang/texlang.c
+++ b/Build/source/texk/web2c/luatexdir/lang/texlang.w
@@ -1,105 +1,112 @@
-/* texlang.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% texlang.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
+@ @c
+#include "ptexlib.h"
#include <string.h>
-#include "nodes.h"
-#include "font/texfont.h"
-#include "hyphen.h"
+#include "lua/luatex-api.h"
+
static const char _svn_version[] =
- "$Id: texlang.c 2596 2009-06-25 09:26:59Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $";
+ "$Id: texlang.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lang/texlang.w $";
+
+
+@ Low-level helpers
-/* functions copied from the fontforge unicode library */
+@c
+static char *uni2string(char *utf8_text, unsigned ch)
+{
+ /* Increment and deposit character */
+ if (ch >= 17 * 65536)
+ return (utf8_text);
+
+ if (ch <= 127)
+ *utf8_text++ = (char) ch;
+ else if (ch <= 0x7ff) {
+ *utf8_text++ = (char) (0xc0 | (ch >> 6));
+ *utf8_text++ = (char) (0x80 | (ch & 0x3f));
+ } else if (ch <= 0xffff) {
+ *utf8_text++ = (char) (0xe0 | (ch >> 12));
+ *utf8_text++ = (char) (0x80 | ((ch >> 6) & 0x3f));
+ *utf8_text++ = (char) (0x80 | (ch & 0x3f));
+ } else {
+ unsigned val = ch - 0x10000;
+ unsigned u = ((val & 0xf0000) >> 16) + 1, z = (val & 0x0f000) >> 12, y =
+ (val & 0x00fc0) >> 6, x = val & 0x0003f;
+ *utf8_text++ = (char) (0xf0 | (u >> 2));
+ *utf8_text++ = (char) (0x80 | ((u & 3) << 4) | z);
+ *utf8_text++ = (char) (0x80 | y);
+ *utf8_text++ = (char) (0x80 | x);
+ }
+ return (utf8_text);
+}
-static unsigned int *utf82u_strcpy(unsigned int * ubuf, const char *utf8buf)
+static unsigned u_length(register unsigned int *str)
{
- int len = strlen(utf8buf) + 1;
+ register unsigned len = 0;
+ while (*str++ != '\0')
+ ++len;
+ return (len);
+}
+
+
+static void utf82u_strcpy(unsigned int *ubuf, const char *utf8buf)
+{
+ int len = (int) strlen(utf8buf) + 1;
unsigned int *upt = ubuf, *uend = ubuf + len - 1;
- const unsigned char *pt = (const unsigned char *) utf8buf, *end = pt + strlen(utf8buf);
+ const unsigned char *pt = (const unsigned char *) 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);
+ *upt = (unsigned int) (((*pt & 0x1f) << 6) | (pt[1] & 0x3f));
pt += 2;
} else if (*pt <= 0xef) {
- *upt = ((*pt & 0xf) << 12) | ((pt[1] & 0x3f) << 6) | (pt[2] & 0x3f);
+ *upt =
+ (unsigned int) (((*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;
+ *upt = (unsigned int) (w * 0x400 + w2 + 0x10000);
pt += 4;
}
++upt;
}
*upt = '\0';
- return (ubuf);
-}
-
-char *utf8_idpb(char *utf8_text, unsigned int 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 {
- unsigned int 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 unsigned int * str)
-{
- register int len = 0;
- while (*str++ != '\0')
- ++len;
- return (len);
}
+@ @c
#define noVERBOSE
#define MAX_TEX_LANGUAGES 32768
static struct tex_language *tex_languages[MAX_TEX_LANGUAGES] = { NULL };
+
static int next_lang_id = 0;
struct tex_language *new_language(int n)
@@ -114,12 +121,12 @@ struct tex_language *new_language(int n)
} else {
while (tex_languages[next_lang_id] != NULL)
next_lang_id++;
- l = next_lang_id++;
+ l = (unsigned) 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->id = (int) l;
lang->exceptions = 0;
lang->patterns = NULL;
lang->pre_hyphen_char = '-';
@@ -145,14 +152,15 @@ struct tex_language *get_language(int n)
}
}
-void set_pre_hyphen_char(integer n, integer v)
+@ @c
+void set_pre_hyphen_char(int n, int 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)
+void set_post_hyphen_char(int n, int v)
{
struct tex_language *l = get_language((int) n);
if (l != NULL)
@@ -160,14 +168,14 @@ void set_post_hyphen_char(integer n, integer v)
}
-void set_pre_exhyphen_char(integer n, integer v)
+void set_pre_exhyphen_char(int n, int v)
{
struct tex_language *l = get_language((int) n);
if (l != NULL)
l->pre_exhyphen_char = (int) v;
}
-void set_post_exhyphen_char(integer n, integer v)
+void set_post_exhyphen_char(int n, int v)
{
struct tex_language *l = get_language((int) n);
if (l != NULL)
@@ -175,40 +183,40 @@ void set_post_exhyphen_char(integer n, integer v)
}
-
-integer get_pre_hyphen_char(integer n)
+int get_pre_hyphen_char(int n)
{
struct tex_language *l = get_language((int) n);
if (l == NULL)
return -1;
- return (integer) l->pre_hyphen_char;
+ return (int) l->pre_hyphen_char;
}
-integer get_post_hyphen_char(integer n)
+int get_post_hyphen_char(int n)
{
struct tex_language *l = get_language((int) n);
if (l == NULL)
return -1;
- return (integer) l->post_hyphen_char;
+ return (int) l->post_hyphen_char;
}
-integer get_pre_exhyphen_char(integer n)
+int get_pre_exhyphen_char(int n)
{
struct tex_language *l = get_language((int) n);
if (l == NULL)
return -1;
- return (integer) l->pre_exhyphen_char;
+ return (int) l->pre_exhyphen_char;
}
-integer get_post_exhyphen_char(integer n)
+int get_post_exhyphen_char(int n)
{
struct tex_language *l = get_language((int) n);
if (l == NULL)
return -1;
- return (integer) l->post_exhyphen_char;
+ return (int) l->post_exhyphen_char;
}
+@ @c
void load_patterns(struct tex_language *lang, const unsigned char *buffer)
{
if (lang == NULL || buffer == NULL || strlen((const char *) buffer) == 0)
@@ -231,12 +239,13 @@ void clear_patterns(struct tex_language *lang)
void load_tex_patterns(int curlang, halfword head)
{
char *s = tokenlist_to_cstring(head, 1, NULL);
- load_patterns(get_language(curlang), (const unsigned char *) s);
+ load_patterns(get_language(curlang), (unsigned char *) s);
}
+@ @c
#define STORE_CHAR(x) do { \
- word[w] = x; \
+ word[w] = (unsigned char)x; \
if (w<MAX_WORD_LEN) w++; \
} while (0)
@@ -298,9 +307,11 @@ const char *clean_hyphenation(const char *buffer, char **cleaned)
return s;
}
+@ @c
void load_hyphenation(struct tex_language *lang, const unsigned char *buffer)
{
- const char *s, *value;
+ const char *s;
+ const char *value;
char *cleaned;
lua_State *L = Luas;
if (lang == NULL)
@@ -320,7 +331,7 @@ void load_hyphenation(struct tex_language *lang, const unsigned char *buffer)
if (cleaned != NULL) {
if ((s - value) > 0) {
lua_pushstring(L, cleaned);
- lua_pushlstring(L, value, (s - value));
+ lua_pushlstring(L, value, (size_t) (s - value));
lua_rawset(L, -3);
}
free(cleaned);
@@ -348,13 +359,14 @@ void clear_hyphenation(struct tex_language *lang)
void load_tex_hyphenation(int curlang, halfword head)
{
char *s = tokenlist_to_cstring(head, 1, NULL);
- load_hyphenation(get_language(curlang), (const unsigned char *) s);
+ load_hyphenation(get_language(curlang), (unsigned char *) s);
}
-/* TODO: clean this up. The delete_attribute_ref() statements are not very
+@ 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. */
+ attribute list from |vlink(n)|. No rush, as it is currently not used much.
+@c
halfword insert_discretionary(halfword t, halfword pre, halfword post,
halfword replace)
{
@@ -454,6 +466,7 @@ halfword insert_word_discretionary(halfword t, lang_variables * lan)
return insert_discretionary(t, pre, pos, null);
}
+@ @c
halfword compound_word_break(halfword t, int clang)
{
int disc;
@@ -486,7 +499,7 @@ halfword insert_character(halfword t, int c)
return p;
}
-
+@ @c
void set_disc_field(halfword f, halfword t)
{
if (t != null) {
@@ -500,7 +513,8 @@ void set_disc_field(halfword f, halfword t)
-static char *hyphenation_exception(int exceptions, char *w)
+@ @c
+char *hyphenation_exception(int exceptions, char *w)
{
char *ret = NULL;
lua_State *L = Luas;
@@ -520,6 +534,7 @@ static char *hyphenation_exception(int exceptions, char *w)
}
+@ @c
char *exception_strings(struct tex_language *lang)
{
const char *value;
@@ -537,8 +552,11 @@ char *exception_strings(struct tex_language *lang)
while (lua_next(L, -2) != 0) {
value = 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 =
+ xrealloc(ret,
+ (unsigned) ((size + size / 5) + current + l +
+ 1024));
+ size = (size + size / 5) + current + l + 1024;
}
*(ret + current) = ' ';
strcpy(ret + current + 1, value);
@@ -550,20 +568,21 @@ char *exception_strings(struct tex_language *lang)
}
-/* the sequence from |wordstart| to |r| can contain only normal characters */
-/* it could be faster to modify a halfword pointer and return an integer */
+@ the sequence from |wordstart| to |r| can contain only normal characters
+it could be faster to modify a halfword pointer and return an integer
-static halfword find_exception_part(unsigned int *j, int *uword, int len)
+@c
+halfword find_exception_part(unsigned int *j, unsigned int *uword, int len)
{
halfword g = null, gg = null;
- register int i = *j;
- i++; /* this puts uword[i] on the '{' */
- while (i < len && uword[i + 1] != '}') {
+ register unsigned i = *j;
+ i++; /* this puts uword[i] on the |{| */
+ while (i < (unsigned) len && uword[i + 1] != '}') {
if (g == null) {
- gg = new_char(0, uword[i + 1]);
+ gg = new_char(0, (int) uword[i + 1]);
g = gg;
} else {
- halfword s = new_char(0, uword[i + 1]);
+ halfword s = new_char(0, (int) uword[i + 1]);
couple_nodes(g, s);
g = vlink(g);
}
@@ -573,12 +592,12 @@ static halfword find_exception_part(unsigned int *j, int *uword, int len)
return gg;
}
-static int count_exception_part(unsigned int *j, int *uword, int len)
+int count_exception_part(unsigned int *j, unsigned int *uword, int len)
{
int ret = 0;
- register int i = *j;
- i++; /* this puts uword[i] on the '{' */
- while (i < len && uword[i + 1] != '}') {
+ register unsigned i = *j;
+ i++; /* this puts uword[i] on the |{| */
+ while (i < (unsigned) len && uword[i + 1] != '}') {
ret++;
i++;
}
@@ -587,22 +606,23 @@ static int count_exception_part(unsigned int *j, int *uword, int len)
}
+@ @c
static const char *PAT_ERROR[] = {
"Exception discretionaries should contain three pairs of braced items.",
"No intervening spaces are allowed.",
NULL
};
-static void do_exception(halfword wordstart, halfword r, char *replacement)
+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);
+ unsigned uword[MAX_WORD_LEN + 1] = { 0 };
+ utf82u_strcpy(uword, replacement);
+ len = u_length(uword);
i = 0;
t = wordstart;
clang = char_lang(wordstart);
@@ -624,15 +644,15 @@ static void do_exception(halfword wordstart, halfword r, char *replacement)
} else if (uword[i + 1] == '{') {
halfword gg, hh, replace = null;
int repl;
- gg = find_exception_part(&i, uword, len);
+ gg = find_exception_part(&i, uword, (int) len);
if (i == len || uword[i + 1] != '{') {
tex_error("broken pattern 1", PAT_ERROR);
}
- hh = find_exception_part(&i, uword, len);
+ hh = find_exception_part(&i, uword, (int) len);
if (i == len || uword[i + 1] != '{') {
tex_error("broken pattern 2", PAT_ERROR);
}
- repl = count_exception_part(&i, uword, len);
+ repl = count_exception_part(&i, uword, (int) len);
if (i == len) {
tex_error("broken pattern 3", PAT_ERROR);
}
@@ -659,7 +679,7 @@ static void do_exception(halfword wordstart, halfword r, char *replacement)
}
}
-/* This is a documentation section from the pascal web file. It is not
+@ This is a documentation section from the pascal web file. It is not
true any more, but I do not have time right now to rewrite it -- Taco
When the line-breaking routine is unable to find a feasible sequence of
@@ -722,15 +742,14 @@ When a word been set up to contain a candidate for hyphenation,
hyphens are inserted based on patterns that appear within the given word,
using an algorithm due to Frank~M. Liang.
@^Liang, Franklin Mark@>
-*/
-/*
- * 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 the best idea ever.
- */
-static halfword find_next_wordstart(halfword r)
+@ 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 the best idea ever.
+
+@c
+halfword find_next_wordstart(halfword r)
{
register int l;
register int start_ok = 1;
@@ -770,27 +789,30 @@ static halfword find_next_wordstart(halfword r)
return r;
}
-static int valid_wordend(halfword s)
+@ @c
+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))) {
+ && 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))
+ || (type(r) == kern_node
+ && (subtype(r) == explicit || subtype(r) == acc_kern)))
return 1;
return 0;
}
+@ @c
void hnj_hyphenation(halfword head, halfword tail)
{
int lchar, i;
@@ -804,17 +826,17 @@ void hnj_hyphenation(halfword head, halfword tail)
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.
+ \item{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|).
+ \item{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 */
+ /* this will make |r| a glyph node with subtype character */
r = find_next_wordstart(r);
if (r == null)
return;
@@ -844,7 +866,7 @@ void hnj_hyphenation(halfword head, halfword tail)
clang == char_lang(r) &&
(lchar = get_lc_code(character(r))) > 0) {
wordlen++;
- hy = utf8_idpb(hy, lchar);
+ hy = uni2string(hy, (unsigned) lchar);
/* this should not be needed any more */
/*if (vlink(r)!=null) alink(vlink(r))=r; */
end_word = r;
@@ -897,12 +919,13 @@ void hnj_hyphenation(halfword head, halfword tail)
}
+@ @c
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()! */
+ fix_node_list(head);
callback_id = callback_defined(hyphenate_callback);
if (callback_id > 0) {
lua_State *L = Luas;
@@ -924,21 +947,22 @@ void new_hyphenation(halfword head, halfword tail)
}
}
-/* dumping and undumping fonts */
+@ dumping and undumping languages
+@c
#define dump_string(a) \
if (a!=NULL) { \
- x = strlen(a)+1; \
+ x = (int)strlen(a)+1; \
dump_int(x); dump_things(*a, x); \
} else { \
x = 0; dump_int(x); \
}
-static void dump_one_language(int i)
+void dump_one_language(int i)
{
char *s = NULL;
- integer x = 0;
+ int x = 0;
struct tex_language *lang;
lang = tex_languages[i];
dump_int(lang->id);
@@ -965,7 +989,7 @@ static void dump_one_language(int i)
void dump_language_data(void)
{
- integer i;
+ int i;
dump_int(next_lang_id);
for (i = 0; i < next_lang_id; i++) {
if (tex_languages[i]) {
@@ -978,10 +1002,10 @@ void dump_language_data(void)
}
-static void undump_one_language(int i)
+void undump_one_language(int i)
{
char *s = NULL;
- integer x = 0;
+ int x = 0;
struct tex_language *lang = get_language(i);
undump_int(x);
lang->id = x;
@@ -996,24 +1020,24 @@ static void undump_one_language(int i)
/* patterns */
undump_int(x);
if (x > 0) {
- s = xmalloc(x);
+ s = xmalloc((unsigned) x);
undump_things(*s, x);
- load_patterns(lang, (const unsigned char *) s);
+ load_patterns(lang, (unsigned char *) s);
free(s);
}
/* exceptions */
undump_int(x);
if (x > 0) {
- s = xmalloc(x);
+ s = xmalloc((unsigned) x);
undump_things(*s, x);
- load_hyphenation(lang, (const unsigned char *) s);
+ load_hyphenation(lang, (unsigned char *) s);
free(s);
}
}
void undump_language_data(void)
{
- integer i, x, numlangs;
+ int i, x, numlangs;
undump_int(numlangs);
next_lang_id = numlangs;
for (i = 0; i < numlangs; i++) {
@@ -1023,3 +1047,65 @@ void undump_language_data(void)
}
}
}
+
+
+@ When \TeX\ has scanned `\.{\\hyphenation}', it calls on a procedure named
+|new_hyph_exceptions| to do the right thing.
+
+@c
+void new_hyph_exceptions(void)
+{ /* enters new exceptions */
+ (void) scan_toks(false, true);
+ load_tex_hyphenation(int_par(language_code), def_ref);
+ flush_list(def_ref);
+}
+
+@ Similarly, when \TeX\ has scanned `\.{\\patterns}', it calls on a
+procedure named |new_patterns|.
+
+@c
+void new_patterns(void)
+{ /* initializes the hyphenation pattern data */
+ (void) scan_toks(false, true);
+ load_tex_patterns(int_par(language_code), def_ref);
+ flush_list(def_ref);
+}
+
+@ `\.{\\prehyphenchar}', sets the |pre_break| character, and
+`\.{\\posthyphenchar}' the |post_break| character. Their respective
+defaults are ascii hyphen ("-") and zero (nul).
+
+@c
+void new_pre_hyphen_char(void)
+{
+ scan_optional_equals();
+ scan_int();
+ set_pre_hyphen_char(int_par(language_code), cur_val);
+}
+
+void new_post_hyphen_char(void)
+{
+ scan_optional_equals();
+ scan_int();
+ set_post_hyphen_char(int_par(language_code), cur_val);
+}
+
+
+@ `\.{\\preexhyphenchar}', sets the |pre_break| character, and
+`\.{\\postexhyphenchar}' the |post_break| character. Their
+defaults are both zero (nul).
+
+@c
+void new_pre_exhyphen_char(void)
+{
+ scan_optional_equals();
+ scan_int();
+ set_pre_exhyphen_char(int_par(language_code), cur_val);
+}
+
+void new_post_exhyphen_char(void)
+{
+ scan_optional_equals();
+ scan_int();
+ set_post_exhyphen_char(int_par(language_code), cur_val);
+}
diff --git a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c
index adbbd43becb..c29f2de0e96 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c
@@ -17,13 +17,11 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: lcallbacklib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lcallbacklib.c $";
-
-static int do_run_callback(int special, const char *values, va_list vl);
+ "$Id: lcallbacklib.c 3404 2010-01-28 11:17:10Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lcallbacklib.c $";
int callback_count = 0;
int saved_callback_count = 0;
@@ -49,7 +47,7 @@ static const char *const callbacknames[] = {
"find_sfd_file", "read_sfd_file",
"find_pk_file", "read_pk_file",
"show_error_hook",
- "process_input_buffer",
+ "process_input_buffer", "process_output_buffer",
"start_page_number", "stop_page_number",
"start_run", "stop_run",
"define_font",
@@ -79,9 +77,9 @@ void get_lua_boolean(const char *table, const char *name, boolean * target)
if (lua_istable(Luas, -1)) {
lua_getfield(Luas, -1, name);
if (lua_isboolean(Luas, -1)) {
- *target = (lua_toboolean(Luas, -1));
+ *target = (boolean) (lua_toboolean(Luas, -1));
} else if (lua_isnumber(Luas, -1)) {
- *target = (lua_tonumber(Luas, -1) == 0 ? 0 : 1);
+ *target = (boolean) (lua_tonumber(Luas, -1) == 0 ? 0 : 1);
}
}
lua_settop(Luas, stacktop);
@@ -97,16 +95,16 @@ void get_saved_lua_boolean(int r, const char *name, boolean * target)
if (lua_istable(Luas, -1)) {
lua_getfield(Luas, -1, name);
if (lua_isboolean(Luas, -1)) {
- *target = lua_toboolean(Luas, -1);
+ *target = (boolean) lua_toboolean(Luas, -1);
} else if (lua_isnumber(Luas, -1)) {
- *target = (lua_tonumber(Luas, -1) == 0 ? 0 : 1);
+ *target = (boolean) (lua_tonumber(Luas, -1) == 0 ? 0 : 1);
}
}
lua_settop(Luas, stacktop);
return;
}
-void get_lua_number(const char *table, const char *name, integer * target)
+void get_lua_number(const char *table, const char *name, int *target)
{
int stacktop;
stacktop = lua_gettop(Luas);
@@ -115,14 +113,14 @@ void get_lua_number(const char *table, const char *name, integer * target)
if (lua_istable(Luas, -1)) {
lua_getfield(Luas, -1, name);
if (lua_isnumber(Luas, -1)) {
- *target = lua_tonumber(Luas, -1);
+ lua_number2int(*target, lua_tonumber(Luas, -1));
}
}
lua_settop(Luas, stacktop);
return;
}
-void get_saved_lua_number(int r, const char *name, integer * target)
+void get_saved_lua_number(int r, const char *name, int *target)
{
int stacktop;
stacktop = lua_gettop(Luas);
@@ -131,7 +129,7 @@ void get_saved_lua_number(int r, const char *name, integer * target)
if (lua_istable(Luas, -1)) {
lua_getfield(Luas, -1, name);
if (lua_isnumber(Luas, -1)) {
- *target = lua_tonumber(Luas, -1);
+ lua_number2int(*target, lua_tonumber(Luas, -1));
}
}
lua_settop(Luas, stacktop);
@@ -139,7 +137,7 @@ void get_saved_lua_number(int r, const char *name, integer * target)
}
-void get_lua_string(const char *table, const char *name, const char **target)
+void get_lua_string(const char *table, const char *name, char **target)
{
int stacktop;
stacktop = lua_gettop(Luas);
@@ -148,14 +146,14 @@ void get_lua_string(const char *table, const char *name, const char **target)
if (lua_istable(Luas, -1)) {
lua_getfield(Luas, -1, name);
if (lua_isstring(Luas, -1)) {
- *target = lua_tostring(Luas, -1);
+ *target = xstrdup(lua_tostring(Luas, -1));
}
}
lua_settop(Luas, stacktop);
return;
}
-void get_saved_lua_string(int r, const char *name, const char **target)
+void get_saved_lua_string(int r, const char *name, char **target)
{
int stacktop;
stacktop = lua_gettop(Luas);
@@ -164,7 +162,7 @@ void get_saved_lua_string(int r, const char *name, const char **target)
if (lua_istable(Luas, -1)) {
lua_getfield(Luas, -1, name);
if (lua_isstring(Luas, -1)) {
- *target = lua_tostring(Luas, -1);
+ *target = xstrdup(lua_tostring(Luas, -1));
}
}
lua_settop(Luas, stacktop);
@@ -266,7 +264,7 @@ int do_run_callback(int special, const char *values, va_list vl)
}
ss = index(values, '>');
assert(ss);
- luaL_checkstack(L, (ss - values + 1), "out of stack space");
+ luaL_checkstack(L, (int) (ss - values + 1), "out of stack space");
ss = NULL;
for (narg = 0; *values; narg++) {
switch (*values++) {
@@ -289,7 +287,8 @@ int do_run_callback(int special, const char *values, va_list vl)
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));
+ lua_pushlstring(L, (char *) (buffer + first),
+ (size_t) va_arg(vl, int));
break;
case '-':
narg--;
@@ -301,7 +300,7 @@ int do_run_callback(int special, const char *values, va_list vl)
}
}
ENDARGS:
- nres = strlen(values);
+ nres = (int) strlen(values);
if (special == 1) {
nres++;
}
@@ -350,7 +349,7 @@ int do_run_callback(int special, const char *values, va_list vl)
lua_typename(L, lua_type(L, nres)));
goto EXIT;
}
- b = lua_tonumber(L, nres);
+ lua_number2int(b, lua_tonumber(L, nres));
*va_arg(vl, int *) = b;
break;
case CALLBACK_LINE: /* TeX line */
@@ -365,9 +364,9 @@ int do_run_callback(int special, const char *values, va_list vl)
bufloc = va_arg(vl, int *);
if (len != 0) {
ret = *bufloc;
- check_buffer_overflow(ret + len);
+ check_buffer_overflow(ret + (int) len);
strncpy((char *) (buffer + ret), s, len);
- *bufloc += len;
+ *bufloc += (int) len;
/* while (len--) { buffer[(*bufloc)++] = *s++; } */
while ((*bufloc) - 1 > ret && buffer[(*bufloc) - 1] == ' ')
(*bufloc)--;
@@ -404,7 +403,7 @@ int do_run_callback(int special, const char *values, va_list vl)
if (s == NULL) /* |len| can be zero */
*va_arg(vl, int *) = 0;
else {
- ss = xmalloc(len + 1);
+ ss = xmalloc((unsigned) (len + 1));
(void) memcpy(ss, s, (len + 1));
*va_arg(vl, char **) = ss;
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc
new file mode 100644
index 00000000000..551cc2d1ee3
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/lepdflib.cc
@@ -0,0 +1,58 @@
+/* lepdflib.cc
+
+ Copyright 2009-2010 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+static const char _svn_version[] =
+ "$Id: lepdflib.cc 3366 2010-01-20 14:49:31Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lepdflib.cc $";
+
+#include "image/epdf.h"
+
+//**********************************************************************
+
+int l_new_pdfdoc(lua_State * L)
+{
+ PdfDocument *pdf_doc;
+ char *file_path;
+ if (lua_gettop(L) != 1)
+ luaL_error(L, "epdf.new() needs exactly 1 argument");
+ if (!lua_isstring(L, -1))
+ luaL_error(L, "epdf.new() needs filename (string)");
+ file_path = (char *) lua_tostring(L, -1);
+
+ printf("\n======================== 1 <%s>\n", file_path);
+
+ pdf_doc = refPdfDocument(file_path);
+
+ return 0;
+}
+
+//**********************************************************************
+
+static const struct luaL_Reg epdflib[] = {
+ // {"new", l_new_pdfdoc},
+ {NULL, NULL} /* sentinel */
+};
+
+int luaopen_epdf(lua_State * L)
+{
+ luaL_register(L, "epdf", epdflib);
+ return 1;
+}
+
+//**********************************************************************
diff --git a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c
index c07da9d0717..32b9e776fc1 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c
@@ -1,6 +1,6 @@
/* lfontlib.c
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,12 +17,12 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "nodes.h"
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
+
static const char _svn_version[] =
- "$Id: lfontlib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lfontlib.c $";
+ "$Id: lfontlib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lfontlib.c $";
#define TIMERS 0
@@ -30,7 +30,6 @@ static const char _svn_version[] =
# include <sys/time.h>
#endif
-#include "inc-vfovf.h"
static int get_fontid(void)
{
@@ -42,14 +41,14 @@ static int get_fontid(void)
static int font_read_tfm(lua_State * L)
{
- internalfontnumber f;
+ internal_font_number f;
scaled s;
int k;
const char *cnom;
if (lua_isstring(L, 1)) {
cnom = lua_tostring(L, 1);
if (lua_isnumber(L, 2)) {
- s = (integer) lua_tonumber(L, 2);
+ lua_number2int(s, lua_tonumber(L, 2));
if (strlen(cnom)) {
f = get_fontid();
if (read_tfm_info(f, cnom, s)) {
@@ -58,20 +57,16 @@ static int font_read_tfm(lua_State * L)
return k;
} else {
delete_font(f);
- lua_pushstring(L, "font loading failed");
- lua_error(L);
+ luaL_error(L, "font loading failed");
}
} else {
- lua_pushstring(L, "expected tfm name as first argument");
- lua_error(L);
+ luaL_error(L, "expected tfm name as first argument");
}
} else {
- lua_pushstring(L, "expected an integer size as second argument");
- lua_error(L);
+ luaL_error(L, "expected an integer size as second argument");
}
} else {
- lua_pushstring(L, "expected tfm name as first argument");
- lua_error(L);
+ luaL_error(L, "expected tfm name as first argument");
}
return 2; /* not reached */
}
@@ -79,24 +74,22 @@ static int font_read_tfm(lua_State * L)
static int font_read_vf(lua_State * L)
{
- scaled s;
+ int i;
const char *cnom;
if (lua_isstring(L, 1)) {
cnom = lua_tostring(L, 1);
if (strlen(cnom)) {
if (lua_isnumber(L, 2)) {
- s = lua_tonumber(L, 2);
- return make_vf_table(L, cnom, s);
+ lua_number2int(i, lua_tonumber(L, 2));
+ return make_vf_table(L, cnom, (scaled) i);
} else {
- lua_pushstring(L,
+ luaL_error(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);
+ luaL_error(L, "expected vf name as first argument");
return 2; /* not reached */
}
@@ -109,8 +102,7 @@ static int tex_current_font(lua_State * L)
zset_cur_font(i);
return 0;
} else {
- lua_pushstring(L, "expected a valid font id");
- lua_error(L);
+ luaL_error(L, "expected a valid font id");
return 2; /* not reached */
}
} else {
@@ -129,8 +121,8 @@ static int tex_max_font(lua_State * L)
static int tex_each_font_next(lua_State * L)
{
int i, m; /* id */
- m = lua_tonumber(L, 1);
- i = lua_tonumber(L, 2);
+ lua_number2int(m, lua_tonumber(L, 1));
+ lua_number2int(i, lua_tonumber(L, 2));
i++;
while (i <= m && !is_valid_font(i))
i++;
@@ -139,7 +131,8 @@ static int tex_each_font_next(lua_State * L)
return 1;
} else {
lua_pushnumber(L, i);
- font_to_lua(L, i);
+ if (!font_to_lua(L, i))
+ lua_pushnil(L);
return 2;
}
}
@@ -168,8 +161,7 @@ static int frozenfont(lua_State * L)
}
return 1;
} else {
- lua_pushstring(L, "expected an integer argument");
- lua_error(L);
+ luaL_error(L, "expected an integer argument");
}
return 0; /* not reached */
}
@@ -185,13 +177,11 @@ static int setfont(lua_State * L)
if (!(font_touched(i) || font_used(i))) {
font_from_lua(L, i);
} else {
- lua_pushstring(L,
+ luaL_error(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);
+ luaL_error(L, "that integer id is not a valid font");
}
}
return 0;
@@ -227,8 +217,7 @@ static int deffont(lua_State * L)
} else {
lua_pop(L, 1); /* pop the broken table */
delete_font(i);
- lua_pushstring(L, "font creation failed");
- lua_error(L);
+ luaL_error(L, "font creation failed");
}
return 0; /* not reached */
}
@@ -254,6 +243,30 @@ static int getfont(lua_State * L)
}
+static int getfontid(lua_State * L)
+{
+ const char *s;
+ size_t ff;
+ int cur_cs;
+ int f;
+ if (lua_type(L, 1) == LUA_TSTRING) {
+ s = lua_tolstring(L, 1, &ff);
+ cur_cs = string_lookup(s, ff);
+ if (cur_cs == undefined_control_sequence || cur_cs == undefined_cs_cmd
+ || eq_type(cur_cs) != set_font_cmd) {
+ lua_pushstring(L, "not a valid font csname");
+ f = -1;
+ } else {
+ f = equiv(cur_cs);
+ }
+ lua_pushnumber(L, f);
+ } else {
+ luaL_error(L, "expected font csname string as argument");
+ }
+ return 1;
+}
+
+
static const struct luaL_reg fontlib[] = {
{"read_tfm", font_read_tfm},
{"read_vf", font_read_vf},
@@ -264,6 +277,7 @@ static const struct luaL_reg fontlib[] = {
{"setfont", setfont},
{"define", deffont},
{"nextid", nextfontid},
+ {"id", getfontid},
{"frozen", frozenfont},
{NULL, NULL} /* sentinel */
};
diff --git a/Build/source/texk/web2c/luatexdir/lua/limglib.c b/Build/source/texk/web2c/luatexdir/lua/limglib.c
index 7663d022c03..0c2d7e4d65e 100644
--- a/Build/source/texk/web2c/luatexdir/lua/limglib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/limglib.c
@@ -1,6 +1,6 @@
/* limglib.c
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,18 +17,17 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
+static const char _svn_version[] =
+ "$Id: limglib.c 3404 2010-01-28 11:17:10Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/limglib.c $";
+
#include <stdio.h>
#include <string.h>
#include <assert.h>
-#include <../lua51/lua.h>
-#include <../lua51/lauxlib.h>
-#include <ptexlib.h>
-#include "luatex-api.h"
-#include "inc-extra.h"
-
-static const char _svn_version[] =
- "$Id: limglib.c 2329 2009-04-18 14:25:30Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/limglib.c $";
+#include "lua51/lua.h"
+#include "lua51/lauxlib.h"
+#include "ptexlib.h"
+#include "lua/luatex-api.h"
/**********************************************************************/
@@ -48,7 +47,7 @@ void stackDump(lua_State * L, char *s)
printf(lua_toboolean(L, i) ? "true" : "false");
break;
case LUA_TNUMBER: /* numbers */
- printf("%g", lua_tonumber(L, i));
+ printf("%g", (double) lua_tonumber(L, i));
break;
default: /* other values */
printf("%s", lua_typename(L, t));
@@ -68,12 +67,7 @@ typedef enum { P__ZERO, P_ATTR, P_BBOX, P_COLORDEPTH, P_COLORSPACE, P_DEPTH,
P_WIDTH, P_XRES, P_XSIZE, P_YRES, P_YSIZE, P__SENTINEL
} parm_idx;
-typedef struct {
- const char *name; /* parameter name */
- parm_idx idx; /* index within img_parms array */
-} parm_struct;
-
-const parm_struct img_parms[] = {
+static const parm_struct img_parms[] = {
{NULL, P__ZERO}, /* dummy; lua indices run from 1 */
{"attr", P_ATTR},
{"bbox", P_BBOX},
@@ -120,7 +114,7 @@ static void image_to_lua(lua_State * L, image * a)
if (!lua_isnumber(L, -1)) /* !i k u ... */
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 ... */
+ i = (int) lua_tointeger(L, -1); /* i k u ... */
lua_pop(L, 2); /* u ... */
switch (i) {
case P_WIDTH:
@@ -281,59 +275,47 @@ static void lua_to_image(lua_State * L, image * a)
if (!lua_isnumber(L, -1)) /* !i v k t ... */
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 ... */
+ i = (int) lua_tointeger(L, -1); /* i v k t ... */
lua_pop(L, 1); /* v k t ... */
switch (i) {
case P_WIDTH:
- if (img_is_refered(a))
- luaL_error(L, "image.width is now read-only");
if (lua_isnil(L, -1))
set_wd_running(a);
else if (lua_type(L, -1) == LUA_TNUMBER)
- img_width(a) = lua_tointeger(L, -1);
+ img_width(a) = (int) lua_tointeger(L, -1);
else if (lua_type(L, -1) == LUA_TSTRING)
img_width(a) = dimen_to_number(L, lua_tostring(L, -1));
else
luaL_error(L,
"image.width needs integer or nil value or dimension string");
- img_unset_scaled(a);
break;
case P_HEIGHT:
- if (img_is_refered(a))
- luaL_error(L, "image.height is now read-only");
if (lua_isnil(L, -1))
set_ht_running(a);
else if (lua_type(L, -1) == LUA_TNUMBER)
- img_height(a) = lua_tointeger(L, -1);
+ img_height(a) = (int) lua_tointeger(L, -1);
else if (lua_type(L, -1) == LUA_TSTRING)
img_height(a) = dimen_to_number(L, lua_tostring(L, -1));
else
luaL_error(L,
"image.height needs integer or nil value or dimension string");
- img_unset_scaled(a);
break;
case P_DEPTH:
- if (img_is_refered(a))
- luaL_error(L, "image.depth is now read-only");
if (lua_isnil(L, -1))
set_dp_running(a);
else if (lua_type(L, -1) == LUA_TNUMBER)
- img_depth(a) = lua_tointeger(L, -1);
+ img_depth(a) = (int) lua_tointeger(L, -1);
else if (lua_type(L, -1) == LUA_TSTRING)
img_depth(a) = dimen_to_number(L, lua_tostring(L, -1));
else
luaL_error(L,
"image.depth needs integer or nil value or dimension string");
- img_unset_scaled(a);
break;
case P_TRANSFORM:
- if (img_is_refered(a))
- luaL_error(L, "image.transform is now read-only");
if (lua_isnumber(L, -1))
- img_transform(a) = lua_tointeger(L, -1);
+ img_transform(a) = (int) lua_tointeger(L, -1);
else
luaL_error(L, "image.transform needs integer value");
- img_unset_scaled(a);
break;
/* now follow all image_dict entries */
case P_FILENAME:
@@ -342,8 +324,7 @@ static void lua_to_image(lua_State * L, image * a)
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));
+ xfree(img_filename(d));
img_filename(d) = xstrdup(lua_tostring(L, -1));
} else
luaL_error(L, "image.filename needs string value");
@@ -352,8 +333,7 @@ static void lua_to_image(lua_State * L, image * a)
if (img_state(d) >= DICT_FILESCANNED)
luaL_error(L, "image.attr is now read-only");
if (lua_isstring(L, -1) || lua_isnil(L, -1)) {
- if (img_attr(d) != NULL)
- xfree(img_attr(d));
+ xfree(img_attr(d));
if (lua_isstring(L, -1))
img_attr(d) = xstrdup(lua_tostring(L, -1));
} else
@@ -363,15 +343,12 @@ static void lua_to_image(lua_State * L, image * a)
if (img_state(d) >= DICT_FILESCANNED)
luaL_error(L, "image.page is now read-only");
if (lua_type(L, -1) == LUA_TSTRING) {
- if (img_pagename(d) != NULL)
- xfree(img_pagename(d));
+ xfree(img_pagename(d));
img_pagename(d) = xstrdup(lua_tostring(L, -1));
img_pagenum(d) = 0;
} else if (lua_type(L, -1) == LUA_TNUMBER) {
- img_pagenum(d) = lua_tointeger(L, -1);
- if (img_pagename(d) != NULL)
- xfree(img_pagename(d));
- img_pagename(d) = NULL;
+ img_pagenum(d) = (int) lua_tointeger(L, -1);
+ xfree(img_pagename(d));
} else
luaL_error(L, "image.page needs integer or string value");
break;
@@ -381,7 +358,7 @@ static void lua_to_image(lua_State * L, image * a)
if (lua_isnil(L, -1))
img_colorspace(d) = 0;
else if (lua_isnumber(L, -1))
- img_colorspace(d) = lua_tointeger(L, -1);
+ img_colorspace(d) = (int) lua_tointeger(L, -1);
else
luaL_error(L, "image.colorspace needs integer or nil value");
break;
@@ -406,17 +383,15 @@ static void lua_to_image(lua_State * L, image * a)
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);
+ img_bbox(d)[i - 1] = (int) lua_tointeger(L, -1);
else if (lua_type(L, -1) == LUA_TSTRING)
- img_bbox(d)[i - 1] =
- dimen_to_number(L, lua_tostring(L, -1));
+ img_bbox(d)[i - 1] = dimen_to_number(L, 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)
@@ -425,11 +400,9 @@ static void lua_to_image(lua_State * L, image * a)
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));
+ 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:
@@ -451,17 +424,7 @@ static void lua_to_image(lua_State * L, image * a)
/**********************************************************************/
-static void fix_image_size(lua_State * L, image * a)
-{
- if (!img_is_scaled(a) || is_wd_running(a) || is_ht_running(a)
- || is_dp_running(a)) {
- if (img_is_refered(a))
- luaL_error(L, "image is read-only");
- scale_img(a);
- }
-}
-
-static void copy_image(lua_State * L, lua_Number scale)
+void copy_image(lua_State * L, lua_Number scale)
{
image *a, **aa, *b, **bb;
if (lua_gettop(L) != 1)
@@ -474,11 +437,11 @@ static void copy_image(lua_State * L, lua_Number scale)
lua_setmetatable(L, -2); /* b */
b = *bb = new_image();
if (!is_wd_running(a))
- img_width(b) = zround(img_width(a) * scale);
+ img_width(b) = do_zround(img_width(a) * scale);
if (!is_ht_running(a))
- img_height(b) = zround(img_height(a) * scale);
+ img_height(b) = do_zround(img_height(a) * scale);
if (!is_dp_running(a))
- img_depth(b) = zround(img_depth(a) * scale);
+ img_depth(b) = do_zround(img_depth(a) * scale);
img_transform(b) = img_transform(a);
img_dict(b) = img_dict(a);
if (img_dictref(a) != LUA_NOREF) {
@@ -530,7 +493,7 @@ static int l_copy_image(lua_State * L)
return 1; /* image */
}
-static void read_scale_img(lua_State * L, image * a)
+static void read_scale_img(image * a)
{
image_dict *ad;
assert(a != NULL);
@@ -540,18 +503,13 @@ static void read_scale_img(lua_State * L, image * a)
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_pdf_minorversion(static_pdf);
+ read_img(static_pdf,
+ ad, pdf_minor_version, pdf_inclusion_errorlevel);
}
}
- fix_image_size(L, a);
+ if (is_wd_running(a) || is_ht_running(a) || is_dp_running(a))
+ img_dimen(a) = scale_img(ad, img_dimen(a), img_transform(a));
}
static int l_scan_image(lua_State * L)
@@ -563,13 +521,13 @@ static int l_scan_image(lua_State * L)
(void) l_new_image(L); /* image --- if everything worked well */
aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */
a = *aa;
- check_pdfoutput(maketexstring("img.scan()"), true);
- flush_str(last_tex_string);
- read_scale_img(L, a);
+ check_o_mode(static_pdf, "img.scan()", 1 << OMODE_PDF, false);
+ /* flush_str(last_tex_string); *//* ?? */
+ read_scale_img(a);
return 1; /* image */
}
-static halfword img_to_node(image * a, integer ref)
+static halfword img_to_node(image * a)
{
image_dict *ad;
halfword n;
@@ -578,10 +536,11 @@ static halfword img_to_node(image * a, integer ref)
assert(ad != NULL);
assert(img_objnum(ad) != 0);
n = new_node(whatsit_node, pdf_refximage_node);
- pdf_ximage_ref(n) = ref;
- pdf_width(n) = img_width(a);
- pdf_height(n) = img_height(a);
- pdf_depth(n) = img_depth(a);
+ pdf_ximage_index(n) = img_index(ad);
+ width(n) = img_width(a);
+ height(n) = img_height(a);
+ depth(n) = img_depth(a);
+ pdf_ximage_transform(n) = img_transform(a);
return n;
}
@@ -589,22 +548,21 @@ typedef enum { WR_WRITE, WR_IMMEDIATEWRITE, WR_NODE, WR_VF_IMG } wrtype_e;
const char *wrtype_s[] =
{ "img.write()", "img.immediatewrite()", "img.node()", "write vf image" };
-static void setup_image(lua_State * L, image * a, wrtype_e writetype)
+static void setup_image(PDF pdf, 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 */
+ check_o_mode(pdf, wrtype_s[writetype], 1 << OMODE_PDF, false);
+ /* flush_str(last_tex_string); *//* ?? */
+ read_scale_img(a);
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);
+ pdf->ximage_count++;
+ pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count);
+ img_objnum(ad) = pdf->obj_ptr;
+ img_index(ad) = pdf->ximage_count;
+ idict_to_array(ad); /* now ad is read-only */
+ obj_data_ptr(pdf, pdf->obj_ptr) = img_index(ad);
}
}
@@ -620,20 +578,19 @@ static void write_image_or_node(lua_State * L, wrtype_e writetype)
aa = (image **) luaL_checkudata(L, 1, TYPE_IMG); /* image */
a = *aa;
ad = img_dict(a);
- setup_image(L, a, writetype);
+ setup_image(static_pdf, a, writetype);
switch (writetype) {
case WR_WRITE:
- n = img_to_node(a, img_arrayidx(a));
- new_tail_append(n);
+ n = img_to_node(a);
+ tail_append(n);
break; /* image */
case WR_IMMEDIATEWRITE:
- check_pdfminorversion(); /* does initialization stuff */
- pdf_begin_dict(img_objnum(ad), 0);
- write_img(ad);
+ pdf_begin_dict(static_pdf, img_objnum(ad), 0);
+ write_img(static_pdf, ad);
break; /* image */
case WR_NODE: /* image */
lua_pop(L, 1); /* - */
- n = img_to_node(a, img_arrayidx(a));
+ n = img_to_node(a);
lua_nodelib_push_fast(L, n);
break; /* node */
default:
@@ -651,6 +608,7 @@ static int l_write_image(lua_State * L)
static int l_immediatewrite_image(lua_State * L)
{
+ check_o_mode(static_pdf, "img.immediatewrite()", 1 << OMODE_PDF, true);
write_image_or_node(L, WR_IMMEDIATEWRITE);
return 1; /* image */
}
@@ -720,16 +678,18 @@ static const struct luaL_Reg imglib[] = {
/**********************************************************************/
-void vf_out_image(unsigned i)
+void vf_out_image(PDF pdf, unsigned i)
{
image *a, **aa;
+ image_dict *ad;
lua_State *L = Luas; /* ... */
- lua_rawgeti(L, LUA_GLOBALSINDEX, i); /* image ... */
+ lua_rawgeti(L, LUA_GLOBALSINDEX, (int) 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));
+ ad = img_dict(a);
+ assert(ad != NULL);
+ setup_image(pdf, a, WR_VF_IMG); /* image ... */
+ place_img(pdf, ad, img_dimen(a), img_transform(a));
lua_pop(L, 1); /* ... */
}
@@ -784,13 +744,15 @@ static int m_img_print(lua_State * L)
static int m_img_gc(lua_State * L)
{
image *a, **aa;
+ image_dict *d;
aa = (image **) luaL_checkudata(L, 1, TYPE_IMG);
a = *aa;
+ d = img_dict(*aa);
#ifdef DEBUG
printf("\n===== IMG GC ===== a=%d ad=%d\n", a, img_dict(a));
#endif
luaL_unref(L, LUA_GLOBALSINDEX, img_dictref(a));
- if (!img_is_refered(a))
+ if (!img_is_refered(d))
xfree(a);
return 0;
}
@@ -827,19 +789,6 @@ static const struct luaL_Reg img_dict_m[] = {
/**********************************************************************/
-static void preset_environment(lua_State * L, const parm_struct * p)
-{
- int i;
- lua_newtable(L); /* t */
- for (i = 1, ++p; p->name != NULL; i++, p++) {
- assert(i == (int) p->idx);
- lua_pushstring(L, p->name); /* k t */
- lua_pushinteger(L, (int) p->idx); /* v k t */
- lua_settable(L, -3); /* t */
- }
- lua_replace(L, LUA_ENVIRONINDEX); /* - */
-}
-
int luaopen_img(lua_State * L)
{
preset_environment(L, img_parms);
diff --git a/Build/source/texk/web2c/luatexdir/lua/liolib.c b/Build/source/texk/web2c/luatexdir/lua/liolib.c
index 28cfced022e..93d21b23697 100644
--- a/Build/source/texk/web2c/luatexdir/lua/liolib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c 2376 2009-05-08 08:40:13Z taco $
+** $Id: liolib.c 3404 2010-01-28 11:17:10Z taco $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -22,7 +22,7 @@
#include "lauxlib.h"
#include "lualib.h"
-#include <ptexlib.h>
+#include "ptexlib.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
@@ -203,7 +203,7 @@ static int io_popen(lua_State * L)
if (restrictedshell == 0)
allow = 1;
else
- allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname);
+ allow = shell_cmd_is_allowed(&cmd, &safecmd, &cmdname);
if (allow == 1) {
*pf = lua_popen(L, cmd, mode);
@@ -415,16 +415,16 @@ static int read_chars(lua_State * L, FILE * f, size_t n)
static int read_all(lua_State * L, FILE * f)
{
/* attempt to speed up reading whole files */
- size_t rlen; /* how much to read */
+ long rlen; /* how much to read */
size_t nr; /* number of chars actually read */
- size_t old; /* old file location */
+ long old; /* old file location */
char *p;
old = ftell(f);
if (old > 0 && (fseek(f, 0, SEEK_END) >= 0) && ((rlen = ftell(f)) > 0) && rlen < 1000 * 1000 * 100) { /* 100 MB */
fseek(f, old, SEEK_SET);
- p = malloc(rlen);
+ p = malloc((size_t) rlen);
if (p != NULL) {
- nr = fread(p, sizeof(char), rlen, f);
+ nr = fread(p, sizeof(char), (size_t) rlen, f);
lua_pushlstring(L, p, nr);
free(p);
return 1;
@@ -565,12 +565,13 @@ static int f_seek(lua_State * L)
static int f_setvbuf(lua_State * L)
{
+ int sz, op, res;
static const int mode[] = { _IONBF, _IOFBF, _IOLBF };
static const char *const modenames[] = { "no", "full", "line", NULL };
FILE *f = tofile(L);
- int op = luaL_checkoption(L, 2, NULL, modenames);
- lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
- int res = setvbuf(f, NULL, mode[op], sz);
+ op = luaL_checkoption(L, 2, NULL, modenames);
+ lua_number2int(sz, luaL_optinteger(L, 3, LUAL_BUFFERSIZE));
+ res = setvbuf(f, NULL, mode[op], (size_t) sz);
return pushresult(L, res == 0, NULL);
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c
index 71c772eb732..16c6a4ba23a 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c
@@ -17,17 +17,20 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
#include <kpathsea/expand.h>
#include <kpathsea/variable.h>
#include <kpathsea/tex-glyph.h>
#include <kpathsea/readable.h>
+#include <kpathsea/pathsearch.h>
+#include <kpathsea/str-list.h>
+#include <kpathsea/tex-file.h>
static const char _svn_version[] =
- "$Id: lkpselib.c 2414 2009-06-03 12:57:01Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lkpselib.c $";
+ "$Id: lkpselib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lkpselib.c $";
-static const int filetypes[] = {
+static const unsigned filetypes[] = {
kpse_gf_format,
kpse_pk_format,
kpse_any_glyph_format,
@@ -83,7 +86,8 @@ static const int filetypes[] = {
kpse_fea_format,
kpse_cid_format,
kpse_mlbib_format,
- kpse_mlbst_format
+ kpse_mlbst_format,
+ kpse_clua_format
};
static const char *const filetypenames[] = {
@@ -143,6 +147,7 @@ static const char *const filetypenames[] = {
"cid maps",
"mlbib",
"mlbst",
+ "clua",
NULL
};
@@ -155,8 +160,7 @@ int program_name_set = 0;
#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 luaL_error(L, "Please call kpse.set_program_name() before using the library"); \
} \
} while (0)
@@ -164,12 +168,11 @@ static int find_file(lua_State * L)
{
int i;
const char *st;
- int ftype = kpse_tex_format;
+ unsigned 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);
+ luaL_error(L, "not a file name");
}
st = lua_tostring(L, 1);
i = lua_gettop(L);
@@ -177,7 +180,7 @@ static int find_file(lua_State * L)
if (lua_isboolean(L, i)) {
mexist = lua_toboolean(L, i);
} else if (lua_isnumber(L, i)) {
- mexist = lua_tonumber(L, i);
+ lua_number2int(mexist, lua_tonumber(L, i));
} else if (lua_isstring(L, i)) {
int op = luaL_checkoption(L, i, NULL, filetypenames);
ftype = filetypes[op];
@@ -188,7 +191,7 @@ static int find_file(lua_State * L)
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));
+ lua_pushstring(L, kpse_find_glyph(st, (unsigned) mexist, ftype, &ret));
} else {
if (mexist > 0)
mexist = 1;
@@ -203,16 +206,16 @@ static int find_file(lua_State * L)
static int lua_kpathsea_find_file(lua_State * L)
{
int i;
- int ftype = kpse_tex_format;
+ unsigned ftype = kpse_tex_format;
int mexist = 0;
kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE);
const char *st = luaL_checkstring(L, 2);
i = lua_gettop(L);
while (i > 2) {
if (lua_isboolean(L, i)) {
- mexist = lua_toboolean(L, i);
+ mexist = (boolean) lua_toboolean(L, i);
} else if (lua_isnumber(L, i)) {
- mexist = lua_tonumber(L, i);
+ lua_number2int(mexist, lua_tonumber(L, i));
} else if (lua_isstring(L, i)) {
int op = luaL_checkoption(L, i, NULL, filetypenames);
ftype = filetypes[op];
@@ -223,7 +226,9 @@ static int lua_kpathsea_find_file(lua_State * L)
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));
+ lua_pushstring(L,
+ kpathsea_find_glyph(*kp, st, (unsigned) mexist, ftype,
+ &ret));
} else {
if (mexist > 0)
mexist = 1;
@@ -238,7 +243,7 @@ static int lua_kpathsea_find_file(lua_State * L)
static int show_path(lua_State * L)
{
int op = luaL_checkoption(L, -1, "tex", filetypenames);
- int user_format = filetypes[op];
+ unsigned 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);
@@ -250,7 +255,7 @@ 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];
+ unsigned 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);
@@ -323,6 +328,374 @@ static int lua_kpathsea_var_value(lua_State * L)
return 1;
}
+static unsigned find_dpi(const_string s)
+{
+ unsigned dpi_number = 0;
+ string extension = find_suffix(s);
+
+ if (extension != NULL)
+ sscanf(extension, "%u", &dpi_number);
+
+ return dpi_number;
+}
+
+/* Return newly-allocated NULL-terminated list of strings from MATCHES
+ that are prefixed with any of the subdirectories in SUBDIRS. That
+ is, for a string S in MATCHES, its dirname must end with one of the
+ elements in SUBDIRS. For instance, if subdir=foo/bar, that will
+ match a string foo/bar/baz or /some/texmf/foo/bar/baz.
+
+ We don't reallocate the actual strings, just the list elements.
+ Perhaps later we will implement wildcards or // or something. */
+
+static string *subdir_match(str_list_type subdirs, string * matches)
+{
+ string *ret = XTALLOC1(string);
+ unsigned len = 1;
+ unsigned m;
+
+ for (m = 0; matches[m]; m++) {
+ size_t loc;
+ unsigned e;
+ string s = xstrdup(matches[m]);
+ for (loc = strlen(s); loc > 0 && !IS_DIR_SEP(s[loc - 1]); loc--);
+ while (loc > 0 && IS_DIR_SEP(s[loc - 1])) {
+ loc--;
+ }
+ s[loc] = 0; /* wipe out basename */
+
+ for (e = 0; e < STR_LIST_LENGTH(subdirs); e++) {
+ string subdir = STR_LIST_ELT(subdirs, e);
+ size_t subdir_len = strlen(subdir);
+ while (subdir_len > 0 && IS_DIR_SEP(subdir[subdir_len - 1])) {
+ subdir_len--;
+ subdir[subdir_len] = 0; /* remove trailing slashes from subdir spec */
+ }
+ if (FILESTRCASEEQ(subdir, s + loc - subdir_len)) {
+ /* matched, save this one. */
+ XRETALLOC(ret, len + 1, string);
+ ret[len - 1] = matches[m];
+ len++;
+ }
+ }
+ free(s);
+ }
+ ret[len - 1] = NULL;
+ return ret;
+}
+
+/* Use the file type from -format if that was specified (i.e., the
+ user_format global variable), else guess dynamically from NAME.
+ Return kpse_last_format if undeterminable. This function is also
+ used to parse the -format string, a case which we distinguish by
+ setting is_filename to false.
+
+ A few filenames have been hard-coded for format types that
+ differ from what would be inferred from their extensions. */
+
+static kpse_file_format_type
+find_format(kpathsea kpse, const_string name, boolean is_filename)
+{
+ kpse_file_format_type ret;
+
+ if (FILESTRCASEEQ(name, "config.ps")) {
+ ret = kpse_dvips_config_format;
+ } else if (FILESTRCASEEQ(name, "dvipdfmx.cfg")) {
+ ret = kpse_program_text_format;
+ } else if (FILESTRCASEEQ(name, "fmtutil.cnf")) {
+ ret = kpse_web2c_format;
+ } else if (FILESTRCASEEQ(name, "glyphlist.txt")) {
+ ret = kpse_fontmap_format;
+ } else if (FILESTRCASEEQ(name, "mktex.cnf")) {
+ ret = kpse_web2c_format;
+ } else if (FILESTRCASEEQ(name, "pdfglyphlist.txt")) {
+ ret = kpse_fontmap_format;
+ } else if (FILESTRCASEEQ(name, "pdftex.cfg")) {
+ ret = kpse_pdftex_config_format;
+ } else if (FILESTRCASEEQ(name, "texmf.cnf")) {
+ ret = kpse_cnf_format;
+ } else if (FILESTRCASEEQ(name, "updmap.cfg")) {
+ ret = kpse_web2c_format;
+ } else if (FILESTRCASEEQ(name, "XDvi")) {
+ ret = kpse_program_text_format;
+ } else {
+ int f = 0; /* kpse_file_format_type */
+ size_t name_len = strlen(name);
+
+/* Have to rely on `try_len' being declared here, since we can't assume
+ GNU C and statement expressions. */
+#define TRY_SUFFIX(ftry) (\
+ try_len = (ftry) ? strlen (ftry) : 0, \
+ (ftry) && try_len <= name_len \
+ && FILESTRCASEEQ (ftry, name + name_len - try_len))
+
+ while (f != kpse_last_format) {
+ size_t try_len;
+ const_string *ext;
+ const_string ftry;
+ boolean found = false;
+
+ if (!kpse->format_info[f].type)
+ kpathsea_init_format(kpse, (kpse_file_format_type) f);
+
+ if (!is_filename) {
+ /* Allow the long name, but only in the -format option. We don't
+ want a filename confused with a format name. */
+ ftry = kpse->format_info[f].type;
+ found = TRY_SUFFIX(ftry);
+ }
+ for (ext = kpse->format_info[f].suffix; !found && ext && *ext;
+ ext++) {
+ found = TRY_SUFFIX(*ext);
+ }
+ for (ext = kpse->format_info[f].alt_suffix; !found && ext && *ext;
+ ext++) {
+ found = TRY_SUFFIX(*ext);
+ }
+
+ if (found)
+ break;
+
+ /* Some trickery here: the extensions for kpse_fmt_format can
+ * clash with other extensions in use, and we prefer for those
+ * others to be preferred. And we don't want to change the
+ * integer value of kpse_fmt_format. So skip it when first
+ * enountered, then use it when we've done everything else,
+ * and use it as the end-guard.
+ */
+ if (f == kpse_fmt_format) {
+ f = kpse_last_format;
+ } else if (++f == kpse_fmt_format) {
+ f++;
+ } else if (f == kpse_last_format) {
+ f = kpse_fmt_format;
+ }
+ }
+
+ /* If there was a match, f will be one past the correct value. */
+ ret = f;
+ }
+
+ return ret;
+}
+
+/* kpse:lookup("plain.tex", {}) */
+static int do_lua_kpathsea_lookup(lua_State * L, kpathsea kpse, int idx)
+{
+ int i;
+ string ret = NULL;
+ string *ret_list = NULL;
+ const_string name = NULL;
+ string user_path = NULL;
+ boolean show_all = false;
+ boolean must_exist = false;
+ kpse_file_format_type user_format = kpse_last_format;
+ int dpi = 600;
+ str_list_type subdir_paths = { 0, NULL };
+ unsigned saved_debug = kpse->debug;
+ int saved_mktexpk = kpse->format_info[kpse_pk_format].program_enabled_p;
+ int saved_mktexmf = kpse->format_info[kpse_mf_format].program_enabled_p;
+ int saved_mktextex = kpse->format_info[kpse_tex_format].program_enabled_p;
+ int saved_mktextfm = kpse->format_info[kpse_tfm_format].program_enabled_p;
+ name = luaL_checkstring(L, idx);
+ /* todo: fetch parameter values */
+
+ if (lua_type(L, idx + 1) == LUA_TTABLE) {
+ lua_pushstring(L, "format");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TSTRING) {
+ int op = luaL_checkoption(L, -1, NULL, filetypenames);
+ user_format = filetypes[op];
+ }
+ lua_pop(L, 1);
+ lua_pushstring(L, "dpi");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TNUMBER) {
+ lua_number2int(dpi, lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_pushstring(L, "debug");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TNUMBER) {
+ int d = 0;
+ lua_number2int(d, lua_tonumber(L, -1));
+ kpse->debug |= d;
+ }
+ lua_pop(L, 1);
+ lua_pushstring(L, "path");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TSTRING) {
+ user_path = xstrdup(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_pushstring(L, "all");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TBOOLEAN) {
+ show_all = lua_toboolean(L, -1);
+ }
+ lua_pop(L, 1);
+
+ lua_pushstring(L, "mktexpk");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TBOOLEAN) {
+ kpathsea_maketex_option(kpse, "pk", lua_toboolean(L, -1));
+ }
+ lua_pop(L, 1);
+
+ lua_pushstring(L, "mktextex");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TBOOLEAN) {
+ kpathsea_maketex_option(kpse, "tex", lua_toboolean(L, -1));
+ }
+ lua_pop(L, 1);
+
+ lua_pushstring(L, "mktexmf");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TBOOLEAN) {
+ kpathsea_maketex_option(kpse, "mf", lua_toboolean(L, -1));
+ }
+ lua_pop(L, 1);
+
+ lua_pushstring(L, "mktextfm");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TBOOLEAN) {
+ kpathsea_maketex_option(kpse, "tfm", lua_toboolean(L, -1));
+ }
+ lua_pop(L, 1);
+
+
+ lua_pushstring(L, "must-exist");
+ lua_gettable(L, idx + 1);
+ if (lua_type(L, -1) == LUA_TBOOLEAN) {
+ must_exist = lua_toboolean(L, -1);
+ }
+ lua_pop(L, 1);
+ lua_pushstring(L, "subdir");
+ lua_gettable(L, idx + 1);
+ if (lua_istable(L, -1)) {
+ lua_pushnil(L);
+ while (lua_next(L, -2) != 0) { /* numeric value */
+ if (lua_isstring(L, -1)) {
+ char *s = xstrdup(lua_tostring(L, -1));
+ str_list_add(&subdir_paths, s);
+ xfree(s);
+ }
+ lua_pop(L, 1);
+ }
+ } else if (lua_isstring(L, -1)) {
+ char *s = xstrdup(lua_tostring(L, -1));
+ str_list_add(&subdir_paths, s);
+ xfree(s);
+ }
+ lua_pop(L, 1);
+ if (STR_LIST_LENGTH(subdir_paths) > 0) {
+ show_all = 1;
+ }
+ }
+ if (user_path) {
+ /* Translate ; to : if that's our ENV_SEP. See cnf.c. */
+ if (IS_ENV_SEP(':')) {
+ string loc;
+ for (loc = user_path; *loc; loc++) {
+ if (*loc == ';')
+ *loc = ':';
+ }
+ }
+ user_path = kpathsea_path_expand(kpse, user_path);
+ if (show_all) {
+ ret_list = kpathsea_all_path_search(kpse, user_path, name);
+ } else {
+ ret = kpathsea_path_search(kpse, user_path, name, must_exist);
+ }
+ free(user_path);
+ } else {
+ /* No user-specified search path, check user format or guess from NAME. */
+ kpse_file_format_type fmt;
+ if (user_format != kpse_last_format)
+ fmt = user_format;
+ else
+ fmt = find_format(kpse, name, true);
+
+ switch (fmt) {
+ case kpse_pk_format:
+ case kpse_gf_format:
+ case kpse_any_glyph_format:
+ {
+ kpse_glyph_file_type glyph_ret;
+ /* Try to extract the resolution from the name. */
+ unsigned local_dpi = find_dpi(name);
+ if (!local_dpi)
+ local_dpi = (unsigned) dpi;
+ ret =
+ kpathsea_find_glyph(kpse, remove_suffix(name), local_dpi,
+ fmt, &glyph_ret);
+ }
+ break;
+
+ case kpse_last_format:
+ /* If the suffix isn't recognized, assume it's a tex file. */
+ fmt = kpse_tex_format;
+ /* fall through */
+
+ default:
+ if (show_all) {
+ ret_list =
+ kpathsea_find_file_generic(kpse, name, fmt, must_exist,
+ true);
+ } else {
+ ret = kpathsea_find_file(kpse, name, fmt, must_exist);
+ }
+ }
+ }
+
+ /* Turn single return into a null-terminated list for uniform treatment. */
+ if (ret) {
+ ret_list = XTALLOC(2, string);
+ ret_list[0] = ret;
+ ret_list[1] = NULL;
+ }
+
+ /* Filter by subdirectories, if specified. */
+ if (STR_LIST_LENGTH(subdir_paths) > 0) {
+ string *new_list = subdir_match(subdir_paths, ret_list);
+ free(ret_list);
+ ret_list = new_list;
+ }
+ kpse->debug = saved_debug;
+ kpse->format_info[kpse_pk_format].program_enabled_p = saved_mktexpk;
+ kpse->format_info[kpse_mf_format].program_enabled_p = saved_mktexmf;
+ kpse->format_info[kpse_tex_format].program_enabled_p = saved_mktextex;
+ kpse->format_info[kpse_tfm_format].program_enabled_p = saved_mktextfm;
+
+ /* Print output. */
+ i = 0;
+ if (ret_list) {
+ for (; ret_list[i]; i++) {
+ lua_pushstring(L, ret_list[i]);
+ }
+ free(ret_list);
+ }
+ if (i == 0) {
+ i++;
+ lua_pushnil(L);
+ }
+ return i;
+}
+
+
+static int lua_kpathsea_lookup(lua_State * L)
+{
+ kpathsea *kpsep = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE);
+ kpathsea kpse = *kpsep;
+ return do_lua_kpathsea_lookup(L, kpse, 2);
+}
+
+static int lua_kpse_lookup(lua_State * L)
+{
+ TEST_PROGRAM_NAME_SET;
+ return do_lua_kpathsea_lookup(L, kpse_def, 1);
+}
+
/* Engine support is a bit of a problem, because we do not want
* to interfere with the normal format discovery of |luatex|.
@@ -354,7 +727,7 @@ static int set_program_name(lua_State * L)
static int init_prog(lua_State * L)
{
const char *prefix = luaL_checkstring(L, 1);
- unsigned dpi = luaL_checkinteger(L, 2);
+ unsigned dpi = (unsigned) luaL_checkinteger(L, 2);
const char *mode = luaL_checkstring(L, 3);
const char *fallback = luaL_optstring(L, 4, NULL);
TEST_PROGRAM_NAME_SET;
@@ -366,18 +739,24 @@ 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);
+ unsigned dpi = (unsigned) 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 lua_kpse_version(lua_State * L)
+{
+ lua_pushstring(L, kpathsea_version_string);
+ return 1;
+}
+
static int readable_file(lua_State * L)
{
const char *name = luaL_checkstring(L, 1);
TEST_PROGRAM_NAME_SET;
- lua_pushstring(L, kpse_readable_file(name));
+ lua_pushstring(L, (char *) kpse_readable_file(name));
return 1;
}
@@ -385,7 +764,7 @@ 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, kpathsea_readable_file(*kp, name));
+ lua_pushstring(L, (char *) kpathsea_readable_file(*kp, name));
return 1;
}
@@ -422,6 +801,8 @@ static const struct luaL_reg kpselib_m[] = {
{"expand_braces", lua_kpathsea_expand_braces},
{"var_value", lua_kpathsea_var_value},
{"show_path", lua_kpathsea_show_path},
+ {"lookup", lua_kpathsea_lookup},
+ {"version", lua_kpse_version},
{NULL, NULL} /* sentinel */
};
@@ -436,6 +817,8 @@ static const struct luaL_reg kpselib_l[] = {
{"expand_braces", expand_braces},
{"var_value", var_value},
{"show_path", show_path},
+ {"lookup", lua_kpse_lookup},
+ {"version", lua_kpse_version},
{NULL, NULL} /* sentinel */
};
diff --git a/Build/source/texk/web2c/luatexdir/lua/llanglib.c b/Build/source/texk/web2c/luatexdir/lua/llanglib.c
index 2e5544ca37f..093593d1301 100644
--- a/Build/source/texk/web2c/luatexdir/lua/llanglib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/llanglib.c
@@ -17,20 +17,18 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
+
-#include "nodes.h"
-#include "inc-extra.h"
static const char _svn_version[] =
- "$Id: llanglib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/llanglib.c $";
+ "$Id: llanglib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/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)
-
static int lang_new(lua_State * L)
{
struct tex_language **lang;
@@ -38,16 +36,16 @@ static int lang_new(lua_State * L)
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);
+ return luaL_error(L, "lang.new(): no room for a new language");
}
} else {
+ int lualang;
lang = lua_newuserdata(L, sizeof(struct tex_language *));
- *lang = get_language(lua_tonumber(L, 1));
+ lua_number2int(lualang, lua_tonumber(L, 1));
+ *lang = get_language(lualang);
if (!*lang) {
- lua_pushfstring(L, "lang.new(%d): undefined language",
+ return luaL_error(L, "lang.new(%d): undefined language",
lua_tonumber(L, 1));
- return lua_error(L);
}
}
luaL_getmetatable(L, LANG_METATABLE);
@@ -69,8 +67,7 @@ static int lang_patterns(lua_State * L)
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);
+ return luaL_error(L, "lang.patterns(): argument should be a string");
}
load_patterns(*lang_ptr, (const unsigned char *) lua_tostring(L, 2));
return 0;
@@ -99,9 +96,8 @@ static int lang_hyphenation(lua_State * L)
lang_ptr = check_islang(L, 1);
if (lua_gettop(L) != 1) {
if (!lua_isstring(L, 2)) {
- lua_pushstring(L,
+ return luaL_error(L,
"lang.hyphenation(): argument should be a string");
- return lua_error(L);
}
load_hyphenation(*lang_ptr, (const unsigned char *) lua_tostring(L, 2));
return 0;
@@ -121,11 +117,10 @@ static int lang_pre_hyphen_char(lua_State * L)
lang_ptr = check_islang(L, 1);
if (lua_gettop(L) != 1) {
if (!lua_isnumber(L, 2)) {
- lua_pushstring(L,
+ return luaL_error(L,
"lang.prehyphenchar(): argument should be a character number");
- return lua_error(L);
}
- (*lang_ptr)->pre_hyphen_char = lua_tonumber(L, 2);
+ lua_number2int((*lang_ptr)->pre_hyphen_char, lua_tonumber(L, 2));
return 0;
} else {
lua_pushnumber(L, (*lang_ptr)->pre_hyphen_char);
@@ -139,11 +134,10 @@ static int lang_post_hyphen_char(lua_State * L)
lang_ptr = check_islang(L, 1);
if (lua_gettop(L) != 1) {
if (!lua_isnumber(L, 2)) {
- lua_pushstring(L,
+ return luaL_error(L,
"lang.posthyphenchar(): argument should be a character number");
- return lua_error(L);
}
- (*lang_ptr)->post_hyphen_char = lua_tonumber(L, 2);
+ lua_number2int((*lang_ptr)->post_hyphen_char, lua_tonumber(L, 2));
return 0;
} else {
lua_pushnumber(L, (*lang_ptr)->post_hyphen_char);
@@ -158,11 +152,10 @@ static int lang_pre_exhyphen_char(lua_State * L)
lang_ptr = check_islang(L, 1);
if (lua_gettop(L) != 1) {
if (!lua_isnumber(L, 2)) {
- lua_pushstring(L,
+ return luaL_error(L,
"lang.preexhyphenchar(): argument should be a character number");
- return lua_error(L);
}
- (*lang_ptr)->pre_exhyphen_char = lua_tonumber(L, 2);
+ lua_number2int((*lang_ptr)->pre_exhyphen_char, lua_tonumber(L, 2));
return 0;
} else {
lua_pushnumber(L, (*lang_ptr)->pre_exhyphen_char);
@@ -176,11 +169,10 @@ static int lang_post_exhyphen_char(lua_State * L)
lang_ptr = check_islang(L, 1);
if (lua_gettop(L) != 1) {
if (!lua_isnumber(L, 2)) {
- lua_pushstring(L,
+ return luaL_error(L,
"lang.postexhyphenchar(): argument should be a character number");
- return lua_error(L);
}
- (*lang_ptr)->post_exhyphen_char = lua_tonumber(L, 2);
+ lua_number2int((*lang_ptr)->post_exhyphen_char, lua_tonumber(L, 2));
return 0;
} else {
lua_pushnumber(L, (*lang_ptr)->post_exhyphen_char);
@@ -202,8 +194,7 @@ 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);
+ return luaL_error(L, "lang.clean(): argument should be a string");
}
(void) clean_hyphenation(lua_tostring(L, 1), &cleaned);
lua_pushstring(L, cleaned);
@@ -212,17 +203,18 @@ static int do_lang_clean(lua_State * L)
static int do_lang_hyphenate(lua_State * L)
{
- halfword *h, *t;
+ halfword *h, *t, tt;
h = check_isnode(L, 1);
if (lua_isuserdata(L, 2)) {
t = check_isnode(L, 2);
+ tt = *t;
lua_pop(L, 1);
} else {
- t = h;
- while (vlink(*t) != null)
- *t = vlink(*t);
+ tt = *h;
+ while (vlink(tt) != null)
+ tt = vlink(tt);
}
- hnj_hyphenation(*h, *t);
+ hnj_hyphenation(*h, tt);
lua_pushboolean(L, 1);
return 1;
}
diff --git a/Build/source/texk/web2c/luatexdir/lua/llualib.c b/Build/source/texk/web2c/luatexdir/lua/llualib.c
index 57cffe36ab1..eded8dd8f25 100644
--- a/Build/source/texk/web2c/luatexdir/lua/llualib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/llualib.c
@@ -17,11 +17,11 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: llualib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/llualib.c $";
+ "$Id: llualib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/llualib.c $";
#define LOAD_BUF_SIZE 256
#define UINT_MAX32 0xFFFFFFFF
@@ -38,7 +38,7 @@ static bytecode *lua_bytecode_registers = NULL;
int luabytecode_max = -1;
unsigned int luabytecode_bytes = 0;
-static char *luanames[65536] = { NULL };
+char *luanames[65536] = { NULL };
char *get_lua_name(int i)
{
@@ -49,8 +49,8 @@ char *get_lua_name(int i)
void dump_luac_registers(void)
{
- integer x;
- integer k, n;
+ int x;
+ int k, n;
bytecode b;
dump_int(luabytecode_max);
if (lua_bytecode_registers != NULL) {
@@ -72,7 +72,7 @@ void dump_luac_registers(void)
for (k = 0; k < 65536; k++) {
char *a = luanames[k];
if (a != NULL) {
- x = strlen(a) + 1;
+ x = (int) strlen(a) + 1;
dump_int(x);
dump_things(*a, x);
} else {
@@ -84,18 +84,18 @@ void dump_luac_registers(void)
void undump_luac_registers(void)
{
- integer x;
- integer k, n;
+ int 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"));
+ i = (unsigned) (luabytecode_max + 1);
+ if ((int) (UINT_MAX32 / (int) sizeof(bytecode) + 1) <= i) {
+ lua_fatal_error("Corrupt format file");
}
- lua_bytecode_registers = xmalloc(i * sizeof(bytecode));
- luabytecode_bytes = i * sizeof(bytecode);
+ lua_bytecode_registers = xmalloc((unsigned) (i * sizeof(bytecode)));
+ luabytecode_bytes = (unsigned) (i * sizeof(bytecode));
for (i = 0; i <= (unsigned) luabytecode_max; i++) {
lua_bytecode_registers[i].done = 0;
lua_bytecode_registers[i].size = 0;
@@ -106,9 +106,9 @@ void undump_luac_registers(void)
undump_int(k);
undump_int(x);
b.size = x;
- b.buf = xmalloc(b.size);
- luabytecode_bytes += b.size;
- memset(b.buf, 0, b.size);
+ b.buf = xmalloc((unsigned) b.size);
+ luabytecode_bytes += (unsigned) b.size;
+ memset(b.buf, 0, (size_t) 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;
@@ -118,7 +118,7 @@ void undump_luac_registers(void)
for (k = 0; k < 65536; k++) {
undump_int(x);
if (x > 0) {
- char *s = xmalloc(x);
+ char *s = xmalloc((unsigned) x);
undump_things(*s, x);
luanames[k] = s;
}
@@ -157,21 +157,23 @@ static int bytecode_register_shadow_get(lua_State * L, int k)
}
-static int writer(lua_State * L, const void *b, size_t size, void *B)
+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;
+ if ((int) (buf->size + (int) size) > buf->alloc) {
+ buf->buf =
+ xrealloc(buf->buf,
+ (unsigned) (buf->alloc + (int) size + LOAD_BUF_SIZE));
+ buf->alloc = buf->alloc + (int) size + LOAD_BUF_SIZE;
}
memcpy(buf->buf + buf->size, b, size);
- buf->size += size;
- luabytecode_bytes += size;
+ buf->size += (int) size;
+ luabytecode_bytes += (unsigned) size;
return 0;
}
-static const char *reader(lua_State * L, void *ud, size_t * size)
+const char *reader(lua_State * L, void *ud, size_t * size)
{
bytecode *buf = (bytecode *) ud;
(void) L; /* for -Wunused */
@@ -180,12 +182,12 @@ static const char *reader(lua_State * L, void *ud, size_t * size)
buf->done = 0;
return NULL;
}
- *size = buf->size;
+ *size = (size_t) buf->size;
buf->done = buf->size;
return (const char *) buf->buf;
}
-static int get_bytecode(lua_State * L)
+int get_bytecode(lua_State * L)
{
int k;
k = (int) luaL_checkinteger(L, -1);
@@ -196,8 +198,7 @@ static int get_bytecode(lua_State * L)
if (lua_load
(L, reader, (void *) (lua_bytecode_registers + k),
"bytecode")) {
- lua_error(L);
- lua_pushnil(L);
+ return luaL_error(L, "bad bytecode register");
} else {
lua_pushvalue(L, -1);
bytecode_register_shadow_set(L, k);
@@ -209,34 +210,34 @@ static int get_bytecode(lua_State * L)
return 1;
}
-static int set_bytecode(lua_State * L)
+int set_bytecode(lua_State * L)
{
int k, ltype;
unsigned int i;
k = (int) luaL_checkinteger(L, -2);
- i = k + 1;
+ i = (unsigned) k + 1;
if ((int) (UINT_MAX32 / sizeof(bytecode) + 1) < i) {
- lua_pushstring(L, "value too large");
- lua_error(L);
+ luaL_error(L, "value too large");
}
if (k < 0) {
- lua_pushstring(L, "negative values not allowed");
- lua_error(L);
+ luaL_error(L, "negative values not allowed");
}
ltype = lua_type(L, -1);
if (ltype != LUA_TFUNCTION && ltype != LUA_TNIL) {
- lua_pushstring(L, "unsupported type");
- lua_error(L);
+ luaL_error(L, "unsupported type");
}
if (k > luabytecode_max) {
- i = sizeof(bytecode) * (k + 1);
+ i = (unsigned) (sizeof(bytecode) * ((unsigned) k + 1));
lua_bytecode_registers = xrealloc(lua_bytecode_registers, i);
if (luabytecode_max == -1) {
- luabytecode_bytes += sizeof(bytecode) * (k + 1);
+ luabytecode_bytes +=
+ (unsigned) (sizeof(bytecode) * (unsigned) (k + 1));
} else {
- luabytecode_bytes += sizeof(bytecode) * (k + 1 - luabytecode_max);
+ luabytecode_bytes +=
+ (unsigned) (sizeof(bytecode) *
+ (unsigned) (k + 1 - luabytecode_max));
}
- for (i = (luabytecode_max + 1); i <= (unsigned) k; i++) {
+ for (i = (unsigned) (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;
@@ -245,8 +246,7 @@ static int set_bytecode(lua_State * L)
}
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;
+ luabytecode_bytes -= (unsigned) lua_bytecode_registers[k].size;
lua_bytecode_registers[k].size = 0;
lua_bytecode_registers[k].done = 0;
lua_pushnil(L);
@@ -263,7 +263,7 @@ static int set_bytecode(lua_State * L)
}
-static int set_luaname(lua_State * L)
+int set_luaname(lua_State * L)
{
int k;
const char *s;
@@ -286,7 +286,7 @@ static int set_luaname(lua_State * L)
return 0;
}
-static int get_luaname(lua_State * L)
+int get_luaname(lua_State * L)
{
int k;
k = (int) luaL_checkinteger(L, 2);
@@ -314,7 +314,7 @@ static const struct luaL_reg lualib[] = {
{NULL, NULL} /* sentinel */
};
-int luaopen_lua(lua_State * L, const char *fname)
+int luaopen_lua(lua_State * L, char *fname)
{
luaL_register(L, "lua", lualib);
make_table(L, "bytecode", "getbytecode", "setbytecode");
diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c
index 4b5738da4be..3b626826e58 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c
@@ -1,6 +1,6 @@
/* lnodelib.c
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,20 +17,16 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
-
-#include "nodes.h"
-#include "inc-extra.h"
-
-#include "commands.h"
-
static const char _svn_version[] =
- "$Id: lnodelib.c 2476 2009-06-12 19:39:05Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lnodelib.c $";
+ "$Id: lnodelib.c 3560 2010-03-29 09:27:08Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lnodelib.c $";
+
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
#define init_luaS_index(a) do { \
lua_pushliteral(L,#a); \
- luaS_##a##_ptr = lua_tostring(L,-1); \
+ luaS_##a##_ptr = lua_tostring(L,-1); \
luaS_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \
} while (0)
@@ -77,7 +73,7 @@ int do_get_node_type_id(lua_State * L, int n, node_info * data)
return j;
}
} else if (lua_type(L, n) == LUA_TNUMBER) {
- register int i = lua_tointeger(L, n);
+ register int i = (int) lua_tointeger(L, n);
for (j = 0; data[j].id != -1; j++) {
if (data[j].id == i)
return j;
@@ -95,13 +91,10 @@ 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",
- (const char *) lua_tostring(L, n));
+ luaL_error(L, "Invalid node type id: %s", lua_tostring(L, n));
} else {
- lua_pushfstring(L, "Invalid node type id: %d",
- (int) lua_tonumber(L, n));
+ luaL_error(L, "Invalid node type id: %d", lua_tonumber(L, n));
}
- return lua_error(L);
}
return i;
}
@@ -112,13 +105,12 @@ 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",
- (const char *) lua_tostring(L, n));
+ luaL_error(L, "Invalid whatsit node id: %s",
+ lua_tostring(L, n));
} else {
- lua_pushfstring(L, "Invalid whatsit node id: %d",
- (int) lua_tonumber(L, n));
+ luaL_error(L, "Invalid whatsit node id: %d",
+ lua_tonumber(L, n));
}
- return lua_error(L);
}
return i;
}
@@ -138,7 +130,7 @@ void lua_nodelib_push(lua_State * L)
halfword *a;
n = -1;
if (lua_isnumber(L, -1)) {
- n = lua_tointeger(L, -1);
+ n = (int) lua_tointeger(L, -1);
}
lua_pop(L, 1);
if ((n == null) || (n < 0) || (n > var_mem_max)) {
@@ -153,6 +145,29 @@ void lua_nodelib_push(lua_State * L)
return;
}
+/* |spec_ptr| fields can legally be zero, which is why there is a special function. */
+
+static void lua_nodelib_push_spec(lua_State * L)
+{
+ halfword n;
+ halfword *a;
+ n = -1;
+ if (lua_isnumber(L, -1)) {
+ n = (halfword) lua_tointeger(L, -1);
+ }
+ lua_pop(L, 1);
+ if ((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;
@@ -169,7 +184,7 @@ void lua_nodelib_push_fast(lua_State * L, halfword n)
static int lua_nodelib_id(lua_State * L)
{
- integer i = get_node_type_id(L, 1);
+ int i = get_node_type_id(L, 1);
if (i >= 0) {
lua_pushnumber(L, i);
} else {
@@ -181,7 +196,7 @@ static int lua_nodelib_id(lua_State * L)
static int lua_nodelib_subtype(lua_State * L)
{
- integer i = get_node_subtype_id(L, 1);
+ int i = get_node_subtype_id(L, 1);
if (i >= 0) {
lua_pushnumber(L, i);
} else {
@@ -194,7 +209,7 @@ static int lua_nodelib_subtype(lua_State * L)
static int lua_nodelib_type(lua_State * L)
{
- integer i = get_node_type_id(L, 1);
+ int i = get_node_type_id(L, 1);
if (i >= 0) {
lua_pushstring(L, node_data[i].name);
} else {
@@ -218,14 +233,13 @@ static int lua_nodelib_new(lua_State * L)
j = get_valid_node_subtype_id(L, 2);
}
if (j < 0) {
- lua_pushstring(L,
+ luaL_error(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);
+ j = (int) lua_tointeger(L, 2);
}
}
n = new_node(i, j);
@@ -284,8 +298,7 @@ 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);
+ luaL_error(L, "Not enough arguments for node.remove()");
}
head = *(check_isnode(L, 1));
if (lua_isnil(L, 2)) {
@@ -304,9 +317,8 @@ static int lua_nodelib_remove(lua_State * L)
if (t == null || vlink(t) != current) {
set_t_to_prev(head, current);
if (t == null) { /* error! */
- lua_pushstring(L,
+ luaL_error(L,
"Attempt to node.remove() a non-existing node");
- lua_error(L);
}
}
/* t is now the previous node */
@@ -329,8 +341,7 @@ 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);
+ luaL_error(L, "Not enough arguments for node.insert_before()");
}
if (lua_isnil(L, 3)) {
lua_pop(L, 1);
@@ -357,9 +368,8 @@ static int lua_nodelib_insert_before(lua_State * L)
if (t == null || vlink(t) != current) {
set_t_to_prev(head, current);
if (t == null) { /* error! */
- lua_pushstring(L,
+ luaL_error(L,
"Attempt to node.insert_before() a non-existing node");
- lua_error(L);
}
}
couple_nodes(t, n);
@@ -379,8 +389,7 @@ 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);
+ luaL_error(L, "Not enough arguments for node.insert_after()");
}
if (lua_isnil(L, 3)) {
lua_pop(L, 1);
@@ -417,13 +426,17 @@ static int lua_nodelib_insert_after(lua_State * L)
static int lua_nodelib_copy_list(lua_State * L)
{
- halfword *n;
+ halfword n, s = null;
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);
+ n = *check_isnode(L, 1);
+ if ((lua_gettop(L) > 1) && (!lua_isnil(L,2))) {
+ s = *check_isnode(L, 2);
+ }
+ m = do_copy_node_list(n, s);
+ lua_pushnumber(L, m);
+ lua_nodelib_push(L);
return 1;
}
@@ -452,10 +465,10 @@ static int lua_nodelib_append(lua_State * L)
for (i = 1; i <= j; i++) {
n = check_isnode(L, i);
m = *n;
- new_tail_append(m);
+ tail_append(m);
while (vlink(m) != null) {
m = vlink(m);
- new_tail_append(m);
+ tail_append(m);
}
}
return 0;
@@ -478,11 +491,12 @@ static int lua_nodelib_hpack(lua_State * L)
{
halfword n, p;
const char *s;
- integer w = 0;
+ int w = 0;
int m = 1;
+ int d = -1;
n = *(check_isnode(L, 1));
if (lua_gettop(L) > 1) {
- w = lua_tointeger(L, 2);
+ w = (int) lua_tointeger(L, 2);
if (lua_gettop(L) > 2) {
if (lua_type(L, 3) == LUA_TSTRING) {
s = lua_tostring(L, 3);
@@ -490,23 +504,78 @@ static int lua_nodelib_hpack(lua_State * L)
m = 1;
else if (strcmp(s, "exactly") == 0)
m = 0;
+ else if (strcmp(s, "cal_expand_ratio") == 0)
+ m = 2;
+ else if (strcmp(s, "subst_ex_font") == 0)
+ m = 3;
else {
- lua_pushstring(L,
+ luaL_error(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 if (lua_type(L, 3) == LUA_TNUMBER) {
+ lua_number2int(m, lua_tonumber(L, 3));
} else {
lua_pushstring(L, "incorrect 3rd argument");
}
+ if (lua_gettop(L) > 3) {
+ if (lua_type(L, 4) == LUA_TSTRING) {
+ d = nodelib_getdir(L, 4);
+ } else {
+ lua_pushstring(L, "incorrect 4th argument");
+ }
+ }
}
}
- p = hpack(n, w, m);
+ p = hpack(n, w, m, d);
lua_nodelib_push_fast(L, p);
- return 1;
+ lua_pushnumber(L, last_badness);
+ return 2;
+}
+
+
+static int lua_nodelib_dimensions(lua_State * L)
+{
+ int top;
+ top = lua_gettop(L);
+ if (top > 0) {
+ scaled_whd siz;
+ glue_ratio g_mult = 1.0;
+ int g_sign = normal;
+ int g_order = normal;
+ int i = 1;
+ int d = -1;
+ halfword n = null, p = null;
+ if (lua_isnumber(L, 1)) {
+ if (top < 4) {
+ lua_pushnil(L);
+ return 1;
+ }
+ i += 3;
+ g_mult = (glue_ratio) lua_tonumber(L, 1);
+ lua_number2int(g_sign, lua_tonumber(L, 2));
+ lua_number2int(g_order, lua_tonumber(L, 3));
+ }
+ n = *(check_isnode(L, i));
+ if (lua_gettop(L) > i && !lua_isnil(L, (i + 1))) {
+ if (lua_type(L, (i + 1)) == LUA_TSTRING) {
+ d = nodelib_getdir(L, (i + 1));
+ } else {
+ p = *(check_isnode(L, (i + 1)));
+ }
+ }
+ if (lua_gettop(L) > (i + 1) && lua_type(L, (i + 2)) == LUA_TSTRING) {
+ d = nodelib_getdir(L, (i + 2));
+ }
+ siz = natural_sizes(n, p, g_mult, g_sign, g_order, d);
+ lua_pushnumber(L, siz.wd);
+ lua_pushnumber(L, siz.ht);
+ lua_pushnumber(L, siz.dp);
+ return 3;
+ } else {
+ luaL_error(L,
+ "missing argument to 'dimensions' (luatex_node expected)");
+ }
+ return 0; /* not reached */
}
@@ -515,11 +584,12 @@ static int lua_nodelib_vpack(lua_State * L)
{
halfword n, p;
const char *s;
- integer w = 0;
+ int w = 0;
int m = 1;
+ int d = -1;
n = *(check_isnode(L, 1));
if (lua_gettop(L) > 1) {
- w = lua_tointeger(L, 2);
+ w = (int) lua_tointeger(L, 2);
if (lua_gettop(L) > 2) {
if (lua_type(L, 3) == LUA_TSTRING) {
s = lua_tostring(L, 3);
@@ -528,22 +598,29 @@ static int lua_nodelib_vpack(lua_State * L)
else if (strcmp(s, "exactly") == 0)
m = 0;
else {
- lua_pushstring(L,
+ luaL_error(L,
"3rd argument should be either additional or exactly");
- lua_error(L);
+ }
+ if (lua_gettop(L) > 3) {
+ if (lua_type(L, 4) == LUA_TSTRING) {
+ d = nodelib_getdir(L, 4);
+ } else {
+ lua_pushstring(L, "incorrect 4th argument");
+ }
}
}
else if (lua_type(L, 3) == LUA_TNUMBER) {
- m = lua_tonumber(L, 3);
+ lua_number2int(m, lua_tonumber(L, 3));
} else {
lua_pushstring(L, "incorrect 3rd argument");
}
}
}
- p = vpackage(n, w, m, max_dimen);
+ p = vpackage(n, w, m, max_dimen, d);
lua_nodelib_push_fast(L, p);
- return 1;
+ lua_pushnumber(L, last_badness);
+ return 2;
}
@@ -558,10 +635,7 @@ static int lua_nodelib_mlist_to_hlist(lua_State * L)
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();
+ mlist_to_hlist_args(n, w, m);
lua_nodelib_push_fast(L, vlink(temp_head));
return 1;
}
@@ -569,9 +643,9 @@ static int lua_nodelib_mlist_to_hlist(lua_State * L)
static int lua_nodelib_mfont(lua_State * L)
{
int f, s;
- f = luaL_checkinteger(L, 1);
+ f = (int) luaL_checkinteger(L, 1);
if (lua_gettop(L) == 2)
- s = lua_tointeger(L, 2); /* this should be a multiple of 256 ! */
+ s = (int) lua_tointeger(L, 2); /* this should be a multiple of 256 ! */
else
s = 0;
lua_pushnumber(L, fam_fnt(f, s));
@@ -605,9 +679,13 @@ make_luaS_index(uchyph);
make_luaS_index(components);
make_luaS_index(xoffset);
make_luaS_index(yoffset);
+make_luaS_index(width);
+make_luaS_index(height);
+make_luaS_index(depth);
+make_luaS_index(expansion_factor);
-static void initialize_luaS_indexes(lua_State * L)
+void initialize_luaS_indexes(lua_State * L)
{
init_luaS_index(id);
init_luaS_index(next);
@@ -623,6 +701,10 @@ static void initialize_luaS_indexes(lua_State * L)
init_luaS_index(components);
init_luaS_index(xoffset);
init_luaS_index(yoffset);
+ init_luaS_index(width);
+ init_luaS_index(height);
+ init_luaS_index(depth);
+ init_luaS_index(expansion_factor);
}
static int get_node_field_id(lua_State * L, int n, int node)
@@ -658,6 +740,14 @@ static int get_node_field_id(lua_State * L, int n, int node)
return 11;
} else if (luaS_ptr_eq(s, yoffset)) {
return 12;
+ } else if (luaS_ptr_eq(s, width)) {
+ return 13;
+ } else if (luaS_ptr_eq(s, height)) {
+ return 14;
+ } else if (luaS_ptr_eq(s, depth)) {
+ return 15;
+ } else if (luaS_ptr_eq(s, expansion_factor)) {
+ return 16;
}
} else if (luaS_ptr_eq(s, prev)) {
return -1;
@@ -683,9 +773,8 @@ 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) {
const char *s = lua_tostring(L, n);
- lua_pushfstring(L, "Invalid field id %s for node type %s (%d)", s,
+ luaL_error(L, "Invalid field id %s for node type %s (%d)", s,
node_data[type(node)].name, subtype(node));
- lua_error(L);
}
return i;
}
@@ -778,6 +867,24 @@ static int lua_nodelib_tail(lua_State * L)
return 1;
}
+static int lua_nodelib_tail_only(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 */
+ while (vlink(t) != null) {
+ 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)
@@ -786,8 +893,8 @@ static int lua_nodelib_has_attribute(lua_State * L)
int i, val;
n = check_isnode(L, 1);
if (n != NULL) {
- i = lua_tointeger(L, 2);
- val = luaL_optinteger(L, 3, UNUSED_ATTRIBUTE);
+ i = (int) lua_tointeger(L, 2);
+ val = (int) luaL_optinteger(L, 3, UNUSED_ATTRIBUTE);
if ((val = has_attribute(*n, i, val)) > UNUSED_ATTRIBUTE) {
lua_pushnumber(L, val);
return 1;
@@ -802,8 +909,8 @@ 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);
+ i = (int) lua_tointeger(L, 2);
+ val = (int) lua_tointeger(L, 3);
n = check_isnode(L, 1);
if (val == UNUSED_ATTRIBUTE) {
(void) unset_attribute(*n, i, val);
@@ -811,8 +918,7 @@ static int lua_nodelib_set_attribute(lua_State * L)
set_attribute(*n, i, val);
}
} else {
- lua_pushstring(L, "incorrect number of arguments");
- lua_error(L);
+ luaL_error(L, "incorrect number of arguments");
}
return 0;
}
@@ -823,8 +929,8 @@ 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, UNUSED_ATTRIBUTE);
+ lua_number2int(i, luaL_checknumber(L, 2));
+ lua_number2int(val, luaL_optnumber(L, 3, UNUSED_ATTRIBUTE));
n = check_isnode(L, 1);
ret = unset_attribute(*n, i, val);
if (ret > UNUSED_ATTRIBUTE) {
@@ -834,8 +940,7 @@ static int lua_nodelib_unset_attribute(lua_State * L)
}
return 1;
} else {
- lua_pushstring(L, "incorrect number of arguments");
- return lua_error(L);
+ return luaL_error(L, "incorrect number of arguments");
}
}
@@ -851,7 +956,7 @@ static int nodelib_aux_nil(lua_State * L)
static int nodelib_aux_next_filtered(lua_State * L)
{
register halfword t; /* traverser */
- register int i = lua_tointeger(L, lua_upvalueindex(1));
+ register int i = (int) lua_tointeger(L, lua_upvalueindex(1));
if (lua_isnil(L, 2)) { /* first call */
t = *check_isnode(L, 1);
} else {
@@ -955,7 +1060,7 @@ static int lua_nodelib_count(lua_State * L)
halfword n;
halfword m = null;
int i = -1;
- i = lua_tointeger(L, 1);
+ i = (int) lua_tointeger(L, 1);
if (lua_isnil(L, 2)) {
lua_pushnumber(L, 0);
return 1;
@@ -970,23 +1075,32 @@ static int lua_nodelib_count(lua_State * L)
#define nodelib_pushlist(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); }
#define nodelib_pushattr(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); }
-#define nodelib_pushspec(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); }
+#define nodelib_pushspec(L,n) { lua_pushnumber(L,n); lua_nodelib_push_spec(L); }
#define nodelib_pushaction(L,n) { lua_pushnumber(L,n); lua_nodelib_push(L); }
-#define nodelib_pushstring(L,n) { lua_pushstring(L,makecstring(n)); }
+#define nodelib_pushstring(L,n) { char *ss=makecstring(n); lua_pushstring(L,ss); free(ss); }
static void nodelib_pushdir(lua_State * L, int n, boolean dirnode)
{
- int f = 0;
- char dirstring[5] = { 0 };
+ char s[2];
if (dirnode) {
- dirstring[f++] = (n < 0 ? '-' : '+');
+ s[0] = (char) (n < 0 ? '-' : '+');
+ s[1] = 0;
+ } else {
+ s[0] = 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);
+ if (n == dir_TLT) {
+ lua_pushfstring(L, "%sTLT", s);
+ } else if (n == dir_TRT) {
+ lua_pushfstring(L, "%sTRT", s);
+ } else if (n == dir_LTL) {
+ lua_pushfstring(L, "%sLTL", s);
+ } else if (n == dir_RTT) {
+ lua_pushfstring(L, "%sRTT", s);
+ } else {
+ lua_pushstring(L, "???");
+ }
}
static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field)
@@ -1116,13 +1230,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field)
case pdf_refxform_node:
switch (field) {
case 4:
- lua_pushnumber(L, pdf_width(n));
+ lua_pushnumber(L, width(n));
break;
case 5:
- lua_pushnumber(L, pdf_height(n));
+ lua_pushnumber(L, depth(n));
break;
case 6:
- lua_pushnumber(L, pdf_depth(n));
+ lua_pushnumber(L, height(n));
break;
case 7:
lua_pushnumber(L, pdf_xform_objnum(n));
@@ -1134,16 +1248,19 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field)
case pdf_refximage_node:
switch (field) {
case 4:
- lua_pushnumber(L, pdf_width(n));
+ lua_pushnumber(L, width(n));
break;
case 5:
- lua_pushnumber(L, pdf_height(n));
+ lua_pushnumber(L, depth(n));
break;
case 6:
- lua_pushnumber(L, pdf_depth(n));
+ lua_pushnumber(L, height(n));
break;
case 7:
- lua_pushnumber(L, pdf_ximage_objnum(n));
+ lua_pushnumber(L, pdf_ximage_transform(n));
+ break;
+ case 8:
+ lua_pushnumber(L, pdf_ximage_index(n));
break;
default:
lua_pushnil(L);
@@ -1152,13 +1269,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field)
case pdf_annot_node:
switch (field) {
case 4:
- lua_pushnumber(L, pdf_width(n));
+ lua_pushnumber(L, width(n));
break;
case 5:
- lua_pushnumber(L, pdf_height(n));
+ lua_pushnumber(L, depth(n));
break;
case 6:
- lua_pushnumber(L, pdf_depth(n));
+ lua_pushnumber(L, height(n));
break;
case 7:
lua_pushnumber(L, pdf_annot_objnum(n));
@@ -1173,13 +1290,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field)
case pdf_start_link_node:
switch (field) {
case 4:
- lua_pushnumber(L, pdf_width(n));
+ lua_pushnumber(L, width(n));
break;
case 5:
- lua_pushnumber(L, pdf_height(n));
+ lua_pushnumber(L, depth(n));
break;
case 6:
- lua_pushnumber(L, pdf_depth(n));
+ lua_pushnumber(L, height(n));
break;
case 7:
lua_pushnumber(L, pdf_link_objnum(n));
@@ -1197,13 +1314,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field)
case pdf_dest_node:
switch (field) {
case 4:
- lua_pushnumber(L, pdf_width(n));
+ lua_pushnumber(L, width(n));
break;
case 5:
- lua_pushnumber(L, pdf_height(n));
+ lua_pushnumber(L, depth(n));
break;
case 6:
- lua_pushnumber(L, pdf_depth(n));
+ lua_pushnumber(L, height(n));
break;
case 7:
lua_pushnumber(L, pdf_dest_named_id(n));
@@ -1231,13 +1348,13 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field)
case pdf_start_thread_node:
switch (field) {
case 4:
- lua_pushnumber(L, pdf_width(n));
+ lua_pushnumber(L, width(n));
break;
case 5:
- lua_pushnumber(L, pdf_height(n));
+ lua_pushnumber(L, depth(n));
break;
case 6:
- lua_pushnumber(L, pdf_depth(n));
+ lua_pushnumber(L, height(n));
break;
case 7:
lua_pushnumber(L, pdf_thread_named_id(n));
@@ -1588,6 +1705,9 @@ static int lua_nodelib_getfield(lua_State * L)
case 8:
lua_pushnumber(L, glue_ref_count(n));
break;
+ case 9:
+ lua_pushboolean(L, valid_node(n));
+ break;
default:
lua_pushnil(L);
}
@@ -1600,6 +1720,8 @@ static int lua_nodelib_getfield(lua_State * L)
case 4:
lua_pushnumber(L, width(n));
break;
+ case 5:
+ lua_pushnumber(L, ex_kern(n));
default:
lua_pushnil(L);
}
@@ -1648,6 +1770,18 @@ static int lua_nodelib_getfield(lua_State * L)
case 12:
lua_pushnumber(L, y_displace(n));
break;
+ case 13:
+ lua_pushnumber(L, char_width(font(n),character(n)));
+ break;
+ case 14:
+ lua_pushnumber(L, char_height(font(n),character(n)));
+ break;
+ case 15:
+ lua_pushnumber(L, char_depth(font(n),character(n)));
+ break;
+ case 16:
+ lua_pushnumber(L, ex_glyph(n));
+ break;
default:
lua_pushnil(L);
}
@@ -1878,10 +2012,10 @@ static int lua_nodelib_getfield(lua_State * L)
case 2:
lua_pushnumber(L, subtype(n));
break;
- case 3:
+ case 4:
lua_pushnumber(L, width(n));
break;
- case 4:
+ case 5:
nodelib_pushlist(L, margin_char(n));
break;
default:
@@ -1970,11 +2104,10 @@ static int nodelib_getlist(lua_State * L, int n)
}
}
-static int nodelib_getdir(lua_State * L, int n)
+int nodelib_getdir(lua_State * L, int n)
{
const char *s = NULL;
int d = 32; /* invalid number */
- int a = -1, b = -1, c = -1;
if (lua_type(L, n) == LUA_TSTRING) {
s = lua_tostring(L, n);
if (strlen(s) == 3) {
@@ -1988,42 +2121,22 @@ static int nodelib_getdir(lua_State * L, int n)
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* */
+ if (strcmp(s, "TLT") == 0) {
+ d += dir_TLT;
+ } else if (strcmp(s, "TRT") == 0) {
+ d += dir_TRT;
+ } else if (strcmp(s, "LTL") == 0) {
+ d += dir_LTL;
+ } else if (strcmp(s, "RTT") == 0) {
+ d += dir_RTT;
}
- 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);
+ } else {
+ luaL_error(L, "Direction specifiers have to be strings");
}
if ((d > 31) || (d < -64) || (d < 0 && (d + 64) > 31)) {
d = 0;
- lua_pushfstring(L, "Bad direction specifier %s",
- (const char *) lua_tostring(L, n));
- lua_error(L);
+ luaL_error(L, "Bad direction specifier %s", lua_tostring(L, n));
}
return d;
}
@@ -2056,9 +2169,8 @@ static void nodelib_setattr(lua_State * L, int stackindex, halfword n)
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",
+ luaL_error(L, "You cannot set field %d in a node of type %s",
field, node_data[type(n)].name);
- lua_error(L);
return 0;
}
@@ -2068,7 +2180,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case open_node:
switch (field) {
case 4:
- write_stream(n) = lua_tointeger(L, 3);
+ write_stream(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
open_name(n) = nodelib_getstring(L, 3);
@@ -2086,7 +2198,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case write_node:
switch (field) {
case 4:
- write_stream(n) = lua_tointeger(L, 3);
+ write_stream(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
write_tokens(n) = nodelib_gettoks(L, 3);
@@ -2098,7 +2210,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case close_node:
switch (field) {
case 4:
- write_stream(n) = lua_tointeger(L, 3);
+ write_stream(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2116,10 +2228,10 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case local_par_node:
switch (field) {
case 4:
- local_pen_inter(n) = lua_tointeger(L, 3);
+ local_pen_inter(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- local_pen_broken(n) = lua_tointeger(L, 3);
+ local_pen_broken(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
local_par_dir(n) = nodelib_getdir(L, 3);
@@ -2128,13 +2240,13 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
local_box_left(n) = nodelib_getlist(L, 3);
break;
case 8:
- local_box_left_width(n) = lua_tointeger(L, 3);
+ local_box_left_width(n) = (halfword) 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);
+ local_box_right_width(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2146,13 +2258,13 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
dir_dir(n) = nodelib_getdir(L, 3);
break;
case 5:
- dir_level(n) = lua_tointeger(L, 3);
+ dir_level(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- dir_dvi_ptr(n) = lua_tointeger(L, 3);
+ dir_dvi_ptr(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- dir_dvi_h(n) = lua_tointeger(L, 3);
+ dir_dvi_h(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2161,7 +2273,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_literal_node:
switch (field) {
case 4:
- pdf_literal_mode(n) = lua_tointeger(L, 3);
+ pdf_literal_mode(n) = (quarterword) lua_tointeger(L, 3);
break;
case 5:
if (ini_version) {
@@ -2179,7 +2291,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_refobj_node:
switch (field) {
case 4:
- pdf_obj_objnum(n) = lua_tointeger(L, 3);
+ pdf_obj_objnum(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2188,16 +2300,16 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_refxform_node:
switch (field) {
case 4:
- pdf_width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- pdf_height(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- pdf_depth(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- pdf_xform_objnum(n) = lua_tointeger(L, 3);
+ pdf_xform_objnum(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2206,16 +2318,19 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_refximage_node:
switch (field) {
case 4:
- pdf_width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- pdf_height(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- pdf_depth(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- pdf_ximage_objnum(n) = lua_tointeger(L, 3);
+ pdf_ximage_transform(n) = (halfword) lua_tointeger(L, 3);
+ break;
+ case 8:
+ pdf_ximage_index(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2224,16 +2339,16 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_annot_node:
switch (field) {
case 4:
- pdf_width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- pdf_height(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- pdf_depth(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- pdf_annot_objnum(n) = lua_tointeger(L, 3);
+ pdf_annot_objnum(n) = (halfword) lua_tointeger(L, 3);
break;
case 8:
pdf_annot_data(n) = nodelib_gettoks(L, 3);
@@ -2245,16 +2360,16 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_start_link_node:
switch (field) {
case 4:
- pdf_width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- pdf_height(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- pdf_depth(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- pdf_link_objnum(n) = lua_tointeger(L, 3);
+ pdf_link_objnum(n) = (halfword) lua_tointeger(L, 3);
break;
case 8:
pdf_link_attr(n) = nodelib_gettoks(L, 3);
@@ -2275,31 +2390,31 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_dest_node:
switch (field) {
case 4:
- pdf_width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- pdf_height(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- pdf_depth(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- pdf_dest_named_id(n) = lua_tointeger(L, 3);
+ pdf_dest_named_id(n) = (quarterword) 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);
+ pdf_dest_id(n) = (halfword) lua_tointeger(L, 3);
break;
case 9:
- pdf_dest_type(n) = lua_tointeger(L, 3);
+ pdf_dest_type(n) = (quarterword) lua_tointeger(L, 3);
break;
case 10:
- pdf_dest_xyz_zoom(n) = lua_tointeger(L, 3);
+ pdf_dest_xyz_zoom(n) = (halfword) lua_tointeger(L, 3);
break;
case 11:
- pdf_dest_objnum(n) = lua_tointeger(L, 3);
+ pdf_dest_objnum(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2309,22 +2424,22 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_start_thread_node:
switch (field) {
case 4:
- pdf_width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- pdf_height(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- pdf_depth(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- pdf_thread_named_id(n) = lua_tointeger(L, 3);
+ pdf_thread_named_id(n) = (quarterword) 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);
+ pdf_thread_id(n) = (halfword) lua_tointeger(L, 3);
break;
case 9:
pdf_thread_attr(n) = nodelib_gettoks(L, 3);
@@ -2340,7 +2455,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case late_lua_node:
switch (field) {
case 4:
- late_lua_reg(n) = lua_tointeger(L, 3);
+ late_lua_reg(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
late_lua_data(n) = nodelib_gettoks(L, 3);
@@ -2355,7 +2470,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case close_lua_node:
switch (field) {
case 4:
- late_lua_reg(n) = lua_tointeger(L, 3);
+ late_lua_reg(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2364,10 +2479,10 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case pdf_colorstack_node:
switch (field) {
case 4:
- pdf_colorstack_stack(n) = lua_tointeger(L, 3);
+ pdf_colorstack_stack(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- pdf_colorstack_cmd(n) = lua_tointeger(L, 3);
+ pdf_colorstack_cmd(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
pdf_colorstack_data(n) = nodelib_gettoks(L, 3);
@@ -2393,10 +2508,10 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
case user_defined_node:
switch (field) {
case 4:
- user_node_id(n) = lua_tointeger(L, 3);
+ user_node_id(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- user_node_type(n) = lua_tointeger(L, 3);
+ user_node_type(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
switch (user_node_type(n)) {
@@ -2404,7 +2519,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
user_node_value(n) = nodelib_getlist(L, 3);
break;
case 'd':
- user_node_value(n) = lua_tointeger(L, 3);
+ user_node_value(n) = (halfword) lua_tointeger(L, 3);
break;
case 'n':
user_node_value(n) = nodelib_getlist(L, 3);
@@ -2416,7 +2531,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field)
user_node_value(n) = nodelib_gettoks(L, 3);
break;
default:
- user_node_value(n) = lua_tointeger(L, 3);
+ user_node_value(n) = (halfword) lua_tointeger(L, 3);
break;
}
break;
@@ -2439,6 +2554,11 @@ static int lua_nodelib_setfield(lua_State * L)
field = get_valid_node_field_id(L, 2, n);
if (field < -1)
return 0;
+ if (field !=0 && /* .next assignments are always allowed */
+ !valid_node(n)) {
+ return luaL_error(L, "You can't assign to this %s node (%d)\n", node_data[type(n)].name, n);
+ /* return implied */
+ }
if (field == 0) {
vlink(n) = nodelib_getlist(L, 3);
} else if (field == -1) {
@@ -2448,34 +2568,38 @@ static int lua_nodelib_setfield(lua_State * L)
} else if (type(n) == glyph_node) {
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- character(n) = lua_tointeger(L, 3);
+ character(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- font(n) = lua_tointeger(L, 3);
+ font(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- set_char_lang(n, lua_tointeger(L, 3));
+ set_char_lang(n, (halfword) lua_tointeger(L, 3));
break;
case 7:
- set_char_lhmin(n, lua_tointeger(L, 3));
+ set_char_lhmin(n, (halfword) lua_tointeger(L, 3));
break;
case 8:
- set_char_rhmin(n, lua_tointeger(L, 3));
+ set_char_rhmin(n, (halfword) lua_tointeger(L, 3));
break;
case 9:
- set_char_uchyph(n, lua_tointeger(L, 3));
+ set_char_uchyph(n, (halfword) lua_tointeger(L, 3));
break;
case 10:
lig_ptr(n) = nodelib_getlist(L, 3);
break;
case 11:
- x_displace(n) = lua_tointeger(L, 3);
+ x_displace(n) = (halfword) lua_tointeger(L, 3);
break;
case 12:
- y_displace(n) = lua_tointeger(L, 3);
+ y_displace(n) = (halfword) lua_tointeger(L, 3);
+ break;
+ /* 13,14,15 are virtual width, height, depth */
+ case 16:
+ ex_glyph(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2486,31 +2610,31 @@ static int lua_nodelib_setfield(lua_State * L)
case vlist_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- depth(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- height(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
box_dir(n) = nodelib_getdir(L, 3);
break;
case 8:
- shift_amount(n) = lua_tointeger(L, 3);
+ shift_amount(n) = (halfword) lua_tointeger(L, 3);
break;
case 9:
- glue_order(n) = lua_tointeger(L, 3);
+ glue_order(n) = (quarterword) lua_tointeger(L, 3);
break;
case 10:
- glue_sign(n) = lua_tointeger(L, 3);
+ glue_sign(n) = (quarterword) lua_tointeger(L, 3);
break;
case 11:
- glue_set(n) = (double) lua_tonumber(L, 3);
+ glue_set(n) = (glue_ratio) lua_tonumber(L, 3);
break;
case 12:
list_ptr(n) = nodelib_getlist(L, 3);
@@ -2524,31 +2648,31 @@ static int lua_nodelib_setfield(lua_State * L)
case 2: /* dummy subtype */
break;
case 4:
- width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- depth(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- height(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- box_dir(n) = lua_tointeger(L, 3);
+ box_dir(n) = (halfword) lua_tointeger(L, 3);
break;
case 8:
- glue_shrink(n) = lua_tointeger(L, 3);
+ glue_shrink(n) = (halfword) lua_tointeger(L, 3);
break;
case 9:
- glue_order(n) = lua_tointeger(L, 3);
+ glue_order(n) = (quarterword) lua_tointeger(L, 3);
break;
case 10:
- glue_sign(n) = lua_tointeger(L, 3);
+ glue_sign(n) = (quarterword) lua_tointeger(L, 3);
break;
case 11:
- glue_stretch(n) = lua_tointeger(L, 3);
+ glue_stretch(n) = (halfword) lua_tointeger(L, 3);
break;
case 12:
- span_count(n) = lua_tointeger(L, 3);
+ span_count(n) = (quarterword) lua_tointeger(L, 3);
break;
case 13:
list_ptr(n) = nodelib_getlist(L, 3);
@@ -2562,13 +2686,13 @@ static int lua_nodelib_setfield(lua_State * L)
case 2: /* dummy subtype */
break;
case 4:
- width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- depth(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- height(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
rule_dir(n) = nodelib_getdir(L, 3);
@@ -2580,16 +2704,16 @@ static int lua_nodelib_setfield(lua_State * L)
case ins_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- float_cost(n) = lua_tointeger(L, 3);
+ float_cost(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- depth(n) = lua_tointeger(L, 3);
+ depth(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- height(n) = lua_tointeger(L, 3);
+ height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
split_top_ptr(n) = nodelib_getspec(L, 3);
@@ -2604,10 +2728,10 @@ static int lua_nodelib_setfield(lua_State * L)
case mark_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- mark_class(n) = lua_tointeger(L, 3);
+ mark_class(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
mark_ptr(n) = nodelib_gettoks(L, 3);
@@ -2619,7 +2743,7 @@ static int lua_nodelib_setfield(lua_State * L)
case adjust_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
adjust_ptr(n) = nodelib_getlist(L, 3);
@@ -2631,7 +2755,7 @@ static int lua_nodelib_setfield(lua_State * L)
case disc_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
set_disc_field(pre_break(n), nodelib_getlist(L, 3));
@@ -2649,10 +2773,10 @@ static int lua_nodelib_setfield(lua_State * L)
case math_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- surround(n) = lua_tointeger(L, 3);
+ surround(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2661,7 +2785,7 @@ static int lua_nodelib_setfield(lua_State * L)
case glue_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
glue_ptr(n) = nodelib_getspec(L, 3);
@@ -2678,34 +2802,38 @@ static int lua_nodelib_setfield(lua_State * L)
case 2: /* dummy subtype */
break;
case 3:
- width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
break;
case 4:
- stretch(n) = lua_tointeger(L, 3);
+ stretch(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- shrink(n) = lua_tointeger(L, 3);
+ shrink(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- stretch_order(n) = lua_tointeger(L, 3);
+ stretch_order(n) = (quarterword) lua_tointeger(L, 3);
break;
case 7:
- shrink_order(n) = lua_tointeger(L, 3);
+ shrink_order(n) = (quarterword) lua_tointeger(L, 3);
break;
case 8:
- glue_ref_count(n) = lua_tointeger(L, 3);
+ glue_ref_count(n) = (halfword) 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);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- width(n) = lua_tointeger(L, 3);
+ width(n) = (halfword) lua_tointeger(L, 3);
+ break;
+ case 5:
+ ex_kern(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2716,7 +2844,7 @@ static int lua_nodelib_setfield(lua_State * L)
case 2: /* dummy subtype */
break;
case 4:
- penalty(n) = lua_tointeger(L, 3);
+ penalty(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2727,29 +2855,29 @@ static int lua_nodelib_setfield(lua_State * L)
case 2: /* dummy subtype */
break;
case 3:
- pdf_action_type(n) = lua_tointeger(L, 3);
+ pdf_action_type(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- pdf_action_named_id(n) = lua_tointeger(L, 3);
+ pdf_action_named_id(n) = (quarterword) 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);
+ pdf_action_id(n) = (halfword) 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);
+ pdf_action_new_window(n) = (halfword) 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);
+ pdf_action_refcount(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2760,7 +2888,9 @@ static int lua_nodelib_setfield(lua_State * L)
case 2: /* dummy subtype */
break;
case 4:
- subtype(n) = luaL_checkoption(L, 3, "text", math_style_names);
+ subtype(n) =
+ (quarterword) luaL_checkoption(L, 3, "text",
+ math_style_names);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2769,7 +2899,7 @@ static int lua_nodelib_setfield(lua_State * L)
case choice_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
display_mlist(n) = nodelib_getlist(L, 3);
@@ -2790,7 +2920,7 @@ static int lua_nodelib_setfield(lua_State * L)
case simple_noad:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
nucleus(n) = nodelib_getlist(L, 3);
@@ -2808,7 +2938,7 @@ static int lua_nodelib_setfield(lua_State * L)
case radical_noad:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
nucleus(n) = nodelib_getlist(L, 3);
@@ -2832,10 +2962,10 @@ static int lua_nodelib_setfield(lua_State * L)
case fraction_noad:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- thickness(n) = lua_tointeger(L, 3);
+ thickness(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
numerator(n) = nodelib_getlist(L, 3);
@@ -2856,7 +2986,7 @@ static int lua_nodelib_setfield(lua_State * L)
case accent_noad:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
nucleus(n) = nodelib_getlist(L, 3);
@@ -2880,7 +3010,7 @@ static int lua_nodelib_setfield(lua_State * L)
case fence_noad:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
delimiter(n) = nodelib_getlist(L, 3);
@@ -2893,13 +3023,13 @@ static int lua_nodelib_setfield(lua_State * L)
case math_text_char_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- math_fam(n) = lua_tointeger(L, 3);
+ math_fam(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- math_character(n) = lua_tointeger(L, 3);
+ math_character(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2909,7 +3039,7 @@ static int lua_nodelib_setfield(lua_State * L)
case sub_mlist_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
math_list(n) = nodelib_getlist(L, 3);
@@ -2921,19 +3051,19 @@ static int lua_nodelib_setfield(lua_State * L)
case delim_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
- small_fam(n) = lua_tointeger(L, 3);
+ small_fam(n) = (halfword) lua_tointeger(L, 3);
break;
case 5:
- small_char(n) = lua_tointeger(L, 3);
+ small_char(n) = (halfword) lua_tointeger(L, 3);
break;
case 6:
- large_fam(n) = lua_tointeger(L, 3);
+ large_fam(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- large_char(n) = lua_tointeger(L, 3);
+ large_char(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -2942,12 +3072,12 @@ static int lua_nodelib_setfield(lua_State * L)
case margin_kern_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
- break;
- case 3:
- width(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 4:
+ width(n) = (halfword) lua_tointeger(L, 3);
+ break;
+ case 5:
margin_char(n) = nodelib_getlist(L, 3);
break;
default:
@@ -2957,7 +3087,7 @@ static int lua_nodelib_setfield(lua_State * L)
case inserting_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 3:
last_ins_ptr(n) = nodelib_getlist(L, 3);
@@ -2972,7 +3102,7 @@ static int lua_nodelib_setfield(lua_State * L)
case split_up_node:
switch (field) {
case 2:
- subtype(n) = lua_tointeger(L, 3);
+ subtype(n) = (quarterword) lua_tointeger(L, 3);
break;
case 3:
last_ins_ptr(n) = nodelib_getlist(L, 3);
@@ -3003,10 +3133,10 @@ static int lua_nodelib_setfield(lua_State * L)
case 2: /* dummy subtype */
break;
case 3:
- attribute_id(n) = lua_tointeger(L, 3);
+ attribute_id(n) = (halfword) lua_tointeger(L, 3);
break;
case 4:
- attribute_value(n) = lua_tointeger(L, 3);
+ attribute_value(n) = (halfword) lua_tointeger(L, 3);
break;
default:
return nodelib_cantset(L, field, n);
@@ -3118,7 +3248,7 @@ static int lua_nodelib_protect_glyphs(lua_State * L)
register int s = subtype(head);
if (s <= 256) {
t = 1;
- subtype(head) = (s == 1 ? 256 : 256 + s);
+ subtype(head) = (quarterword) (s == 1 ? 256 : 256 + s);
}
}
head = vlink(head);
@@ -3137,7 +3267,7 @@ static int lua_nodelib_unprotect_glyphs(lua_State * L)
register int s = subtype(head);
if (s > 256) {
t = 1;
- subtype(head) = s - 256;
+ subtype(head) = (quarterword) (s - 256);
}
}
head = vlink(head);
@@ -3178,7 +3308,7 @@ static int lua_nodelib_first_character(lua_State * L)
/* this is too simplistic, but it helps Hans to get going */
-static halfword do_ligature_n(halfword prev, halfword stop, halfword lig)
+halfword do_ligature_n(halfword prev, halfword stop, halfword lig)
{
vlink(lig) = vlink(stop);
vlink(stop) = null;
@@ -3216,6 +3346,14 @@ static int lua_nodelib_usedlist(lua_State * L)
return 1;
}
+/* node.protrusion_skipable(node m) */
+static int lua_nodelib_cp_skipable(lua_State * L)
+{
+ halfword n;
+ n = *(check_isnode(L, 1));
+ lua_pushboolean(L, cp_skipable(n));
+ return 1;
+}
static const struct luaL_reg nodelib_f[] = {
{"id", lua_nodelib_id},
@@ -3226,6 +3364,7 @@ static const struct luaL_reg nodelib_f[] = {
{"count", lua_nodelib_count},
{"traverse", lua_nodelib_traverse},
{"traverse_id", lua_nodelib_traverse_filtered},
+ {"tail", lua_nodelib_tail_only},
{"slide", lua_nodelib_tail},
{"types", lua_nodelib_types},
{"whatsits", lua_nodelib_whatsits},
@@ -3240,6 +3379,7 @@ static const struct luaL_reg nodelib_f[] = {
{"last_node", lua_nodelib_last_node},
{"copy", lua_nodelib_copy},
{"copy_list", lua_nodelib_copy_list},
+ {"dimensions", lua_nodelib_dimensions},
{"hpack", lua_nodelib_hpack},
{"vpack", lua_nodelib_vpack},
{"mlist_to_hlist", lua_nodelib_mlist_to_hlist},
@@ -3254,7 +3394,8 @@ static const struct luaL_reg nodelib_f[] = {
{"usedlist", lua_nodelib_usedlist},
{"protect_glyphs", lua_nodelib_protect_glyphs},
{"unprotect_glyphs", lua_nodelib_unprotect_glyphs},
- {NULL, NULL} /* sentinel */
+ {"protrusion_skipable", lua_nodelib_cp_skipable},
+ {NULL, NULL} /* sentinel */
};
static const struct luaL_reg nodelib_m[] = {
diff --git a/Build/source/texk/web2c/luatexdir/lua/loslibext.c b/Build/source/texk/web2c/luatexdir/lua/loslibext.c
index f79b0f0daf0..9130f488d59 100644
--- a/Build/source/texk/web2c/luatexdir/lua/loslibext.c
+++ b/Build/source/texk/web2c/luatexdir/lua/loslibext.c
@@ -17,17 +17,17 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
-#include <sys/stat.h>
-#include <sys/types.h>
+#include <kpathsea/c-stat.h>
+#include <kpathsea/c-dir.h>
#include <time.h>
static const char _svn_version[] =
- "$Id: loslibext.c 2376 2009-05-08 08:40:13Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/loslibext.c $";
+ "$Id: loslibext.c 3518 2010-03-17 09:57:13Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/loslibext.c $";
-#if defined(_WIN32) || defined(WIN32) || defined(__NT__)
+#if defined(_WIN32) || defined(__NT__)
# define MKDIR(a,b) mkdir(a)
#else
# define MKDIR(a,b) mkdir(a,b)
@@ -39,7 +39,7 @@ static const char _svn_version[] =
successfully compile without major prorting effort
(amiga|mac|os2|vms) */
-#if defined(_WIN32) || defined(WIN32) || defined(__NT__)
+#if defined(_WIN32) || defined(__NT__)
# define OS_PLATTYPE "windows"
# define OS_PLATNAME "windows"
#elif defined(__GO32__) || defined(__DJGPP__) || defined(__DOS__)
@@ -51,6 +51,8 @@ static const char _svn_version[] =
/* this is just a first guess */
# if defined(__BSD__)
# define OS_PLATNAME "bsd"
+# elif defined(__CYGWIN__)
+# define OS_PLATNAME "cygwin"
# elif defined(__SYSV__)
# define OS_PLATNAME "sysv"
# else
@@ -63,6 +65,9 @@ static const char _svn_version[] =
# elif defined(__FREEBSD__) || defined(__FreeBSD__) || defined(__FreeBSD)
# undef OS_PLATNAME
# define OS_PLATNAME "freebsd"
+# elif defined(__FreeBSD_kernel__)
+# undef OS_PLATNAME
+# define OS_PLATNAME "kfreebsd"
# elif defined(__OPENBSD__) || defined(__OpenBSD)
# undef OS_PLATNAME
# define OS_PLATNAME "openbsd"
@@ -81,6 +86,9 @@ static const char _svn_version[] =
# elif defined(__MACH__) && defined(__APPLE__)
# undef OS_PLATNAME
# define OS_PLATNAME "macosx"
+# elif defined(__GNU__)
+# undef OS_PLATNAME
+# define OS_PLATNAME "gnu"
# endif
#endif
@@ -93,7 +101,7 @@ static const char _svn_version[] =
* gettimeofday() for win32 is using an alternative definition
*/
-#if (! defined(WIN32)) && (! defined(__SUNOS__))
+#if (! defined(_WIN32)) && (! defined(__SUNOS__))
# include <sys/time.h> /* gettimeofday() */
# include <sys/times.h> /* times() */
# include <sys/wait.h>
@@ -103,7 +111,7 @@ static const char _svn_version[] =
#define DONT_REALLY_EXIT 1
-#ifdef WIN32
+#ifdef _WIN32
# include <process.h>
# define spawn_command(a,b,c) _spawnvpe(_P_WAIT,(const char *)a,(const char* const*)b,(const char* const*)c)
# if DONT_REALLY_EXIT
@@ -117,7 +125,7 @@ static const char _svn_version[] =
static int exec_command(const char *file, char *const *argv, char *const *envp)
{
- char path[PATH_MAX];
+ char *path;
const char *searchpath, *esp;
size_t prefixlen, filelen, totallen;
@@ -125,6 +133,7 @@ static int exec_command(const char *file, char *const *argv, char *const *envp)
return execve(file, argv, envp);
filelen = strlen(file);
+ path = NULL;
searchpath = getenv("PATH");
if (!searchpath)
@@ -135,20 +144,26 @@ static int exec_command(const char *file, char *const *argv, char *const *envp)
do {
esp = strchr(searchpath, ':');
if (esp)
- prefixlen = esp - searchpath;
+ prefixlen = (size_t) (esp - searchpath);
else
prefixlen = strlen(searchpath);
if (prefixlen == 0 || searchpath[prefixlen - 1] == '/') {
totallen = prefixlen + filelen;
+# ifdef PATH_MAX
if (totallen >= PATH_MAX)
continue;
+# endif
+ path = malloc(totallen + 1);
memcpy(path, searchpath, prefixlen);
memcpy(path + prefixlen, file, filelen);
} else {
totallen = prefixlen + filelen + 1;
+# ifdef PATH_MAX
if (totallen >= PATH_MAX)
continue;
+# endif
+ path = malloc(totallen + 1);
memcpy(path, searchpath, prefixlen);
path[prefixlen] = '/';
memcpy(path + prefixlen + 1, file, filelen);
@@ -156,6 +171,8 @@ static int exec_command(const char *file, char *const *argv, char *const *envp)
path[totallen] = '\0';
execve(path, argv, envp);
+ free(path);
+ path = NULL;
if (errno == E2BIG || errno == ENOEXEC ||
errno == ENOMEM || errno == ETXTBSY)
break; /* Report this as an error, no more search */
@@ -242,13 +259,44 @@ static int spawn_command(const char *file, char *const *argv, char *const *envp)
#endif
-extern char **environ;
+#ifdef _WIN32
+static char *get_command_name(char *maincmd)
+{
+ /* retrieve argv[0] part from the command string,
+ it will be truncated to MAX_PATH if it's too long */
+ char *cmdname = (char *) malloc(sizeof(char) * MAX_PATH);
+ int i, k, quoted;
+ quoted = k = 0;
+ for (i = 0; (i < MAX_PATH) && maincmd[i] &&
+ (maincmd[i] != ' ' && maincmd[i] != '\t' || quoted); i++) {
+ if (maincmd[i] == '"') {
+ quoted = !quoted;
+ } else {
+ cmdname[k] = maincmd[i];
+ k++;
+ }
+ }
+ cmdname[k] = '\0';
+ return cmdname;
+}
+#endif
-static char **do_split_command(const char *maincmd)
+static char **do_split_command(const char *maincmd, char **runcmd)
{
+ char **cmdline = NULL;
+#ifdef _WIN32
+ /* On WIN32 don't split anything, because
+ _spawnvpe can't put it back together properly
+ if there are quoted arguments with spaces.
+ Instead, dump everything into one argument
+ and it will be passed through as is */
+ cmdline = malloc(sizeof(char *) * 2);
+ cmdline[0] = xstrdup(maincmd);
+ cmdline[1] = NULL;
+ *runcmd = get_command_name(cmdline[0]);
+#else
char *piece, *start_piece;
const char *cmd;
- char **cmdline = NULL;
unsigned int i, j;
int ret = 0;
int in_string = 0;
@@ -298,12 +346,15 @@ static char **do_split_command(const char *maincmd)
quoted = 0;
}
xfree(start_piece);
+ *runcmd = cmdline[0];
+#endif
return cmdline;
}
static char **do_flatten_command(lua_State * L, char **runcmd)
{
- unsigned int i, j;
+ unsigned int i;
+ int j;
const char *s;
char **cmdline = NULL;
*runcmd = NULL;
@@ -318,10 +369,10 @@ static char **do_flatten_command(lua_State * L, char **runcmd)
}
if (j == 1)
return NULL;
- cmdline = malloc(sizeof(char *) * (j + 1));
- for (i = 1; i <= j; i++) {
+ cmdline = malloc(sizeof(char *) * (unsigned) (j + 1));
+ for (i = 1; i <= (unsigned) j; i++) {
cmdline[i] = NULL;
- lua_rawgeti(L, -1, i);
+ lua_rawgeti(L, -1, (int) i);
if (lua_isnil(L, -1) || (s = lua_tostring(L, -1)) == NULL) {
lua_pop(L, 1);
if (i == 1) {
@@ -339,7 +390,11 @@ static char **do_flatten_command(lua_State * L, char **runcmd)
lua_rawgeti(L, -1, 0);
if (lua_isnil(L, -1) || (s = lua_tostring(L, -1)) == NULL) {
+#ifdef _WIN32
+ *runcmd = get_command_name(cmdline[0]);
+#else
*runcmd = cmdline[0];
+#endif
} else {
*runcmd = xstrdup(s);
}
@@ -369,8 +424,7 @@ static int os_exec(lua_State * L)
}
if (lua_type(L, 1) == LUA_TSTRING) {
maincmd = lua_tostring(L, 1);
- cmdline = do_split_command(maincmd);
- runcmd = cmdline[0];
+ cmdline = do_split_command(maincmd, &runcmd);
} else if (lua_type(L, 1) == LUA_TTABLE) {
cmdline = do_flatten_command(L, &runcmd);
}
@@ -380,13 +434,15 @@ static int os_exec(lua_State * L)
* but I am not so eager to attempt to fix that. Just document
* that os.exec() checks only the command name.
*/
- if (restrictedshell == 0)
+ if (restrictedshell == 0) {
allow = 1;
- else
- allow = shell_cmd_is_allowed(runcmd, &safecmd, &cmdname);
+ } else {
+ const char *theruncmd = runcmd;
+ allow = shell_cmd_is_allowed(&theruncmd, &safecmd, &cmdname);
+ }
if (allow > 0 && cmdline != NULL && runcmd != NULL) {
-#if defined(WIN32) && DONT_REALLY_EXIT
+#if defined(_WIN32) && DONT_REALLY_EXIT
if (allow == 2)
exec_command(safecmd, cmdline, environ);
else
@@ -449,8 +505,7 @@ static int os_spawn(lua_State * L)
}
if (lua_type(L, 1) == LUA_TSTRING) {
maincmd = lua_tostring(L, 1);
- cmdline = do_split_command(maincmd);
- runcmd = cmdline[0];
+ cmdline = do_split_command(maincmd, &runcmd);
} else if (lua_type(L, 1) == LUA_TTABLE) {
cmdline = do_flatten_command(L, &runcmd);
}
@@ -460,10 +515,12 @@ static int os_spawn(lua_State * L)
* but I am not so eager to attempt to fix that. Just document
* that os.exec() checks only the command name.
*/
- if (restrictedshell == 0)
+ if (restrictedshell == 0) {
allow = 1;
- else
- allow = shell_cmd_is_allowed(runcmd, &safecmd, &cmdname);
+ } else {
+ const char *theruncmd = runcmd;
+ allow = shell_cmd_is_allowed(&theruncmd, &safecmd, &cmdname);
+ }
if (allow > 0 && cmdline != NULL && runcmd != NULL) {
if (allow == 2)
i = spawn_command(safecmd, cmdline, environ);
@@ -479,7 +536,7 @@ static int os_spawn(lua_State * L)
} else if (i == -1) {
/* this branch covers WIN32 as well as fork() and waitpid() errors */
do_error_return(strerror(errno), errno);
-#ifndef WIN32
+#ifndef _WIN32
} else if (i == INVALID_RET_E2BIG) {
do_error_return(strerror(E2BIG), i);
} else if (i == INVALID_RET_ENOENT) {
@@ -518,19 +575,19 @@ static int os_spawn(lua_State * L)
static int os_setenv(lua_State * L)
{
- char *value;
const char *key, *val;
+ char *value;
key = luaL_optstring(L, 1, NULL);
val = luaL_optstring(L, 2, NULL);
if (key) {
if (val) {
- value = xmalloc(strlen(key) + strlen(val) + 2);
+ value = xmalloc((unsigned) (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)
+#if defined(_WIN32) || defined(__sun__) || defined(__sun) || defined(_AIX)
value = xmalloc(strlen(key) + 2);
sprintf(value, "%s=", key);
if (putenv(value)) {
@@ -546,7 +603,7 @@ static int os_setenv(lua_State * L)
}
-static void find_env(lua_State * L)
+void find_env(lua_State * L)
{
char *envitem, *envitem_orig;
char *envkey;
@@ -583,17 +640,17 @@ static int ex_sleep(lua_State * L)
{
lua_Number interval = luaL_checknumber(L, 1);
lua_Number units = luaL_optnumber(L, 2, 1);
-#ifdef WIN32
- Sleep(1e3 * interval / units);
+#ifdef _WIN32
+ Sleep((DWORD) (1e3 * interval / units));
#else /* assumes posix or bsd */
- usleep(1e6 * interval / units);
+ usleep((unsigned) (1e6 * interval / units));
#endif
return 0;
}
-#ifdef WIN32
+#ifdef _WIN32
# define _UTSNAME_LENGTH 65
/* Structure describing the system and machine. */
@@ -754,7 +811,7 @@ static int ex_uname(lua_State * L)
}
-#if (! defined (WIN32)) && (! defined (__SUNOS__))
+#if (! defined (_WIN32)) && (! defined (__SUNOS__))
static int os_times(lua_State * L)
{
struct tms r;
@@ -791,7 +848,7 @@ static int os_times(lua_State * L)
static int os_gettimeofday(lua_State * L)
{
double v;
-# ifndef WIN32
+# ifndef _WIN32
struct timeval tv;
gettimeofday(&tv, NULL);
v = (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
@@ -813,21 +870,20 @@ static int os_gettimeofday(lua_State * L)
}
#endif
-#ifndef HAVE_MKDTEMP
static const char repl[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static int dirs_made = 0;
#define MAXTRIES 36*36*36
-static 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));
+ srand((unsigned) time(NULL));
}
value = rand();
for (count = 0; count < MAXTRIES; value += 8413, ++count) {
@@ -852,7 +908,6 @@ static char *do_mkdtemp(char *tmpl)
}
return NULL;
}
-#endif
static int os_tmpdir(lua_State * L)
{
@@ -900,7 +955,7 @@ static int os_execute(lua_State * L)
if (restrictedshell == 0)
allow = 1;
else
- allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname);
+ allow = shell_cmd_is_allowed(&cmd, &safecmd, &cmdname);
if (allow == 1) {
lua_pushinteger(L, system(cmd));
@@ -937,7 +992,7 @@ void open_oslibext(lua_State * L, int safer_option)
lua_setfield(L, -2, "name");
lua_pushcfunction(L, ex_uname);
lua_setfield(L, -2, "uname");
-#if (! defined (WIN32)) && (! defined (__SUNOS__))
+#if (! defined (_WIN32)) && (! defined (__SUNOS__))
lua_pushcfunction(L, os_times);
lua_setfield(L, -2, "times");
#endif
diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c
index 6de1ae112a9..b715f02b24b 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c
@@ -1,6 +1,6 @@
/* lpdflib.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,151 +17,751 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
-
static const char _svn_version[] =
- "$Id: lpdflib.c 2329 2009-04-18 14:25:30Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lpdflib.c $";
+ "$Id: lpdflib.c 3582 2010-04-02 16:37:08Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lpdflib.c $";
-static int findcurv(lua_State * L)
-{
- int j;
- j = get_cur_v();
- lua_pushnumber(L, j);
- return 1;
-}
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
-static int findcurh(lua_State * L)
-{
- int j;
- j = get_cur_h();
- lua_pushnumber(L, j);
- return 1;
+#define buf_to_pdfbuf_macro(p, s, l) \
+for (i = 0; i < (l); i++) { \
+ if (i % 16 == 0) \
+ pdf_room(p, 16); \
+ pdf_quick_out(p, ((const unsigned char *) (s))[i]); \
}
-static int luapdfprint(lua_State * L)
+int luapdfprint(lua_State * L)
{
int n;
unsigned i;
- size_t len;
- const char *outputstr, *st;
+ const_lstring st, modestr;
ctm_transform_modes literal_mode;
+ st.s = modestr.s = NULL;
n = lua_gettop(L);
if (!lua_isstring(L, -1)) {
- lua_pushstring(L, "no string to print");
- lua_error(L);
+ luaL_error(L, "no string to print");
}
literal_mode = set_origin;
if (n == 2) {
if (!lua_isstring(L, -2)) {
- lua_pushstring(L, "invalid argument for print literal mode");
- lua_error(L);
+ luaL_error(L, "invalid argument for print literal mode");
} else {
- outputstr = lua_tostring(L, -2);
- if (strcmp(outputstr, "direct") == 0)
+ modestr.s = lua_tolstring(L, -2, &modestr.l);
+ if (modestr.l == 6 && strncmp(modestr.s, "direct", 6) == 0)
literal_mode = direct_always;
- else if (strcmp(outputstr, "page") == 0)
+ else if (modestr.l == 4 && strncmp(modestr.s, "page", 4) == 0)
literal_mode = direct_page;
else {
- lua_pushstring(L, "invalid argument for print literal mode");
- lua_error(L);
+ luaL_error(L, "invalid argument for print literal mode");
}
}
} else {
if (n != 1) {
- lua_pushstring(L, "invalid number of arguments");
- lua_error(L);
+ luaL_error(L, "invalid number of arguments");
}
}
- check_pdfminorversion();
+ check_o_mode(static_pdf, "pdf.print()", 1 << OMODE_PDF, true);
switch (literal_mode) {
case (set_origin):
- pdf_goto_pagemode();
- pos = synch_p_with_c(cur);
- pdf_set_pos(pos.h, pos.v);
+ pdf_goto_pagemode(static_pdf);
+ pdf_set_pos(static_pdf, static_pdf->posstruct->pos);
+ (void) calc_pdfpos(static_pdf->pstruct, static_pdf->posstruct->pos);
break;
case (direct_page):
- pdf_goto_pagemode();
+ pdf_goto_pagemode(static_pdf);
+ (void) calc_pdfpos(static_pdf->pstruct, static_pdf->posstruct->pos);
break;
case (direct_always):
- pdf_end_string_nl();
+ pdf_end_string_nl(static_pdf);
break;
default:
assert(0);
}
- st = lua_tolstring(L, n, &len);
- for (i = 0; i < len; i++) {
- if (i % 16 == 0)
- pdfroom(16);
- pdf_buf[pdf_ptr++] = st[i];
- }
+ st.s = lua_tolstring(L, n, &st.l);
+ buf_to_pdfbuf_macro(static_pdf, st.s, st.l);
return 0;
}
+unsigned char *fread_to_buf(lua_State * L, const char *filename, size_t * len)
+{
+ int i = 0;
+ int ilen = 0;
+ FILE *f;
+ unsigned char *buf = NULL;
+ if ((f = fopen(filename, "rb")) == NULL)
+ luaL_error(L, "pdf.immediateobj() cannot open input file");
+ if ((i = readbinfile(f, &buf, &ilen)) == 0)
+ luaL_error(L, "pdf.immediateobj() cannot read input file");
+ fclose(f);
+ *len = (size_t) ilen;
+ return buf;
+}
+
static int l_immediateobj(lua_State * L)
{
+ int n, first_arg = 1;
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);
- 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);
+ int k;
+ lstring buf;
+ const_lstring st1, st2, st3;
+ st1.s = st2.s = st3.s = NULL;
+ check_o_mode(static_pdf, "immediateobj()", 1 << OMODE_PDF, true);
+ n = lua_gettop(L);
+ if (n > 0 && lua_type(L, 1) == LUA_TNUMBER) {
+ first_arg++;
+ lua_number2int(k, lua_tonumber(L, 1));
+ check_obj_exists(static_pdf, obj_type_obj, k);
+ if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0)
+ luaL_error(L, "pdf.immediateobj() object in use");
+ } else {
+ incr(static_pdf->obj_count);
+ pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1);
+ k = static_pdf->sys_obj_ptr;
+ }
+ pdf_last_obj = k;
+ switch (n - first_arg + 1) {
+ case 0:
+ luaL_error(L, "pdf.immediateobj() needs at least one argument");
+ break;
+ case 1:
+ if (!lua_isstring(L, first_arg))
+ luaL_error(L, "pdf.immediateobj() 1st argument must be string");
+ pdf_begin_obj(static_pdf, k, 1);
+ st1.s = lua_tolstring(L, first_arg, &st1.l);
+ buf_to_pdfbuf_macro(static_pdf, st1.s, st1.l);
+ if (st1.s[st1.l - 1] != '\n')
+ pdf_puts(static_pdf, "\n");
+ pdf_end_obj(static_pdf);
+ break;
+ case 2:
+ case 3:
+ if (!lua_isstring(L, first_arg))
+ luaL_error(L, "pdf.immediateobj() 1st argument must be string");
+ if (!lua_isstring(L, first_arg + 1))
+ luaL_error(L, "pdf.immediateobj() 2nd argument must be string");
+ st1.s = lua_tolstring(L, first_arg, &st1.l);
+ st2.s = lua_tolstring(L, first_arg + 1, &st2.l);
+ if (st1.l == 4 && strncmp((const char *) st1.s, "file", 4) == 0) {
+ if (n == first_arg + 2)
+ luaL_error(L,
+ "pdf.immediateobj() 3rd argument forbidden in file mode");
+ pdf_begin_obj(static_pdf, k, 1);
+ buf.s = fread_to_buf(L, st2.s, &buf.l);
+ buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l);
+ if (buf.s[buf.l - 1] != '\n')
+ pdf_puts(static_pdf, "\n");
+ xfree(buf.s);
+ pdf_end_obj(static_pdf);
+ } else {
+ pdf_begin_dict(static_pdf, k, 0); /* 0 = not an object stream candidate! */
+ if (n == first_arg + 2) { /* write attr text */
+ if (!lua_isstring(L, first_arg + 2))
+ luaL_error(L,
+ "pdf.immediateobj() 3rd argument must be string");
+ st3.s = lua_tolstring(L, first_arg + 2, &st3.l);
+ buf_to_pdfbuf_macro(static_pdf, st3.s, st3.l);
+ if (st3.s[st3.l - 1] != '\n')
+ pdf_puts(static_pdf, "\n");
+ }
+ pdf_begin_stream(static_pdf);
+ if (st1.l == 6 && strncmp((const char *) st1.s, "stream", 6) == 0) {
+ buf_to_pdfbuf_macro(static_pdf, st2.s, st2.l);
+ } else if (st1.l == 10
+ && strncmp((const char *) st1.s, "streamfile",
+ 10) == 0) {
+ buf.s = fread_to_buf(L, st2.s, &buf.l);
+ buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l);
+ xfree(buf.s);
+ } else
+ luaL_error(L, "pdf.immediateobj() invalid argument");
+ pdf_end_stream(static_pdf);
+ }
+ break;
+ default:
+ luaL_error(L, "pdf.immediateobj() allows max. 3 arguments");
+ }
+ lua_pushinteger(L, k);
return 1;
}
+/**********************************************************************/
+/* for LUA_ENVIRONINDEX table lookup (instead of repeated strcmp()) */
+
+typedef enum { P__ZERO,
+ P_CATALOG,
+ P_H,
+ P_INFO,
+ P_NAMES,
+ P_PAGEATTRIBUTES,
+ P_PAGERESOURCES,
+ P_PAGESATTRIBUTES,
+ P_PDFCATALOG,
+ P_PDFINFO,
+ P_PDFNAMES,
+ P_PDFTRAILER,
+ P_RAW,
+ P_STREAM,
+ P_TRAILER,
+ P_V,
+ P__SENTINEL
+} parm_idx;
+
+static const parm_struct pdf_parms[] = {
+ {NULL, P__ZERO}, /* dummy; lua indices run from 1 */
+ {"catalog", P_CATALOG},
+ {"h", P_H},
+ {"info", P_INFO},
+ {"names", P_NAMES},
+ {"pageattributes", P_PAGEATTRIBUTES},
+ {"pageresources", P_PAGERESOURCES},
+ {"pagesattributes", P_PAGESATTRIBUTES},
+ {"pdfcatalog", P_PDFCATALOG}, /* obsolescent */
+ {"pdfinfo", P_PDFINFO}, /* obsolescent */
+ {"pdfnames", P_PDFNAMES}, /* obsolescent */
+ {"pdftrailer", P_PDFTRAILER}, /* obsolescent */
+ {"raw", P_RAW},
+ {"stream", P_STREAM},
+ {"trailer", P_TRAILER},
+ {"v", P_V},
+ {NULL, P__SENTINEL}
+};
+
+/**********************************************************************/
+
+static int table_obj(lua_State * L)
+{
+ int k, type;
+ int compress_level = -1; /* unset */
+ int os_level = 1; /* default: put non-stream objects into object streams */
+ int saved_compress_level = static_pdf->compress_level;
+ const_lstring attr, st;
+ lstring buf;
+ size_t i;
+ int immediate = 0; /* default: not immediate */
+ attr.s = st.s = NULL;
+ attr.l = 0;
+ assert(lua_istable(L, 1)); /* t */
+
+ /* get object "type" */
+
+ lua_pushstring(L, "type"); /* ks t */
+ lua_gettable(L, -2); /* vs? t */
+ if (lua_isnil(L, -1)) /* !vs t */
+ luaL_error(L, "pdf.obj(): object \"type\" missing");
+ if (!lua_isstring(L, -1)) /* !vs t */
+ luaL_error(L, "pdf.obj(): object \"type\" must be string");
+ lua_pushvalue(L, -1); /* vs vs t */
+ lua_gettable(L, LUA_ENVIRONINDEX); /* i? vs t */
+ if (!lua_isnumber(L, -1)) /* !i vs t */
+ luaL_error(L, "pdf.obj(): \"%s\" is not a valid object type",
+ lua_tostring(L, -2));
+ type = (int) lua_tointeger(L, -1); /* i vs t */
+ switch (type) {
+ case P_RAW:
+ case P_STREAM:
+ break;
+ default:
+ luaL_error(L, "pdf.obj(): \"%s\" is not a valid object type", lua_tostring(L, -2)); /* i vs t */
+ }
+ lua_pop(L, 2); /* t */
+
+ /* get optional "immediate" */
+
+ lua_pushstring(L, "immediate"); /* ks t */
+ lua_gettable(L, -2); /* b? t */
+ if (!lua_isnil(L, -1)) { /* b? t */
+ if (!lua_isboolean(L, -1)) /* !b t */
+ luaL_error(L, "pdf.obj(): \"immediate\" must be boolean");
+ immediate = lua_toboolean(L, -1); /* 0 or 1 */
+ }
+ lua_pop(L, 1); /* t */
+
+ /* is a reserved object referenced by "objnum"? */
+
+ lua_pushstring(L, "objnum"); /* ks t */
+ lua_gettable(L, -2); /* vi? t */
+ if (!lua_isnil(L, -1)) { /* vi? t */
+ if (!lua_isnumber(L, -1)) /* !vi t */
+ luaL_error(L, "pdf.obj(): \"objnum\" must be integer");
+ k = (int) lua_tointeger(L, -1); /* vi t */
+ check_obj_exists(static_pdf, obj_type_obj, k);
+ if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0)
+ luaL_error(L, "pdf.obj() object in use");
+ } else {
+ incr(static_pdf->obj_count);
+ pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1);
+ k = static_pdf->sys_obj_ptr;
+ }
+ pdf_last_obj = k;
+ if (immediate == 0) {
+ obj_data_ptr(static_pdf, k) = pdf_get_mem(static_pdf, pdfmem_obj_size);
+ init_obj_obj(static_pdf, k);
+ }
+ lua_pop(L, 1); /* t */
+
+ /* get optional "attr" (allowed only for stream case) */
+
+ lua_pushstring(L, "attr"); /* ks t */
+ lua_gettable(L, -2); /* attr-s? t */
+ if (!lua_isnil(L, -1)) { /* attr-s? t */
+ if (type != P_STREAM)
+ luaL_error(L,
+ "pdf.obj(): \"attr\" key not allowed for non-stream object");
+ if (!lua_isstring(L, -1)) /* !attr-s t */
+ luaL_error(L, "pdf.obj(): object \"attr\" must be string");
+ if (immediate == 1) {
+ attr.s = lua_tolstring(L, -1, &attr.l); /* attr-s t */
+ lua_pop(L, 1); /* t */
+ } else
+ obj_obj_stream_attr(static_pdf, k) = luaL_ref(Luas, LUA_REGISTRYINDEX); /* t */
+ } else
+ lua_pop(L, 1); /* t */
+
+ /* get optional "compresslevel" (allowed only for stream case) */
+
+ lua_pushstring(L, "compresslevel"); /* ks t */
+ lua_gettable(L, -2); /* vi? t */
+ if (!lua_isnil(L, -1)) { /* vi? t */
+ if (type == P_RAW)
+ luaL_error(L,
+ "pdf.obj(): \"compresslevel\" key not allowed for raw object");
+ if (!lua_isnumber(L, -1)) /* !vi t */
+ luaL_error(L, "pdf.obj(): \"compresslevel\" must be integer");
+ compress_level = (int) lua_tointeger(L, -1); /* vi t */
+ if (compress_level > 9)
+ luaL_error(L, "pdf.obj(): \"compresslevel\" must be <= 9");
+ else if (compress_level < 0)
+ luaL_error(L, "pdf.obj(): \"compresslevel\" must be >= 0");
+ if (immediate == 0)
+ obj_obj_pdfcompresslevel(static_pdf, k) = compress_level;
+ }
+ lua_pop(L, 1); /* t */
+
+ /* get optional "objcompression" (allowed only for non-stream case) */
+
+ lua_pushstring(L, "objcompression"); /* ks t */
+ lua_gettable(L, -2); /* b? t */
+ if (!lua_isnil(L, -1)) { /* b? t */
+ if (type == P_STREAM)
+ luaL_error(L,
+ "pdf.obj(): \"objcompression\" key not allowed for stream object");
+ if (!lua_isboolean(L, -1)) /* !b t */
+ luaL_error(L, "pdf.obj(): \"objcompression\" must be boolean");
+ os_level = lua_toboolean(L, -1); /* 0 or 1 */
+ /* 0: never compress; 1: depends then on \pdfobjcompresslevel */
+ if (immediate == 0)
+ obj_obj_pdfoslevel(static_pdf, k) = os_level;
+ }
+ lua_pop(L, 1); /* t */
+
+ /* now the object contents for all cases are handled */
+
+ lua_pushstring(L, "string"); /* ks t */
+ lua_gettable(L, -2); /* string-s? t */
+ lua_pushstring(L, "file"); /* ks string-s? t */
+ lua_gettable(L, -3); /* file-s? string-s? t */
+ if (!lua_isnil(L, -1) && !lua_isnil(L, -2)) /* file-s? string-s? t */
+ luaL_error(L,
+ "pdf.obj(): \"string\" and \"file\" must not be given together");
+ if (lua_isnil(L, -1) && lua_isnil(L, -2)) /* nil nil t */
+ luaL_error(L, "pdf.obj(): no \"string\" or \"file\" given");
+
+ switch (type) {
+ case P_RAW:
+ if (immediate == 1)
+ pdf_begin_obj(static_pdf, k, os_level);
+ if (!lua_isnil(L, -2)) { /* file-s? string-s? t */
+ /* from string */
+ lua_pop(L, 1); /* string-s? t */
+ if (!lua_isstring(L, -1)) /* !string-s t */
+ luaL_error(L,
+ "pdf.obj(): \"string\" must be string for raw object");
+ if (immediate == 1) {
+ st.s = lua_tolstring(L, -1, &st.l);
+ buf_to_pdfbuf_macro(static_pdf, st.s, st.l);
+ if (st.s[st.l - 1] != '\n')
+ pdf_puts(static_pdf, "\n");
+ } else
+ obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* t */
+ } else {
+ /* from file */
+ if (!lua_isstring(L, -1)) /* !file-s nil t */
+ luaL_error(L,
+ "pdf.obj(): \"file\" name must be string for raw object");
+ if (immediate == 1) {
+ st.s = lua_tolstring(L, -1, &st.l); /* file-s nil t */
+ buf.s = fread_to_buf(L, st.s, &buf.l);
+ buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l);
+ if (buf.s[buf.l - 1] != '\n')
+ pdf_puts(static_pdf, "\n");
+ xfree(buf.s);
+ } else {
+ set_obj_obj_is_file(static_pdf, k);
+ obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* nil t */
+ }
+ }
+ if (immediate == 1)
+ pdf_end_obj(static_pdf);
+ break;
+ case P_STREAM:
+ if (immediate == 1) {
+ pdf_begin_dict(static_pdf, k, 0); /* 0 = not an object stream candidate! */
+ if (attr.s != NULL) {
+ buf_to_pdfbuf_macro(static_pdf, attr.s, attr.l);
+ if (attr.s[attr.l - 1] != '\n')
+ pdf_puts(static_pdf, "\n");
+ }
+ if (compress_level > -1)
+ static_pdf->compress_level = compress_level;
+ pdf_begin_stream(static_pdf);
+ } else {
+ set_obj_obj_is_stream(static_pdf, k);
+ if (compress_level > -1)
+ obj_obj_pdfcompresslevel(static_pdf, k) = compress_level;
+ }
+ if (!lua_isnil(L, -2)) { /* file-s? string-s? t */
+ /* from string */
+ lua_pop(L, 1); /* string-s? t */
+ if (!lua_isstring(L, -1)) /* !string-s t */
+ luaL_error(L,
+ "pdf.obj(): \"string\" must be string for stream object");
+ if (immediate == 1) {
+ st.s = lua_tolstring(L, -1, &st.l); /* string-s t */
+ buf_to_pdfbuf_macro(static_pdf, st.s, st.l);
+ } else
+ obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* t */
+ } else {
+ /* from file */
+ if (!lua_isstring(L, -1)) /* !file-s nil t */
+ luaL_error(L,
+ "pdf.obj(): \"file\" name must be string for stream object");
+ if (immediate == 1) {
+ st.s = lua_tolstring(L, -1, &st.l); /* file-s nil t */
+ buf.s = fread_to_buf(L, st.s, &buf.l);
+ buf_to_pdfbuf_macro(static_pdf, buf.s, buf.l);
+ xfree(buf.s);
+ } else {
+ set_obj_obj_is_file(static_pdf, k);
+ obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* nil t */
+ }
+ }
+ if (immediate == 1)
+ pdf_end_stream(static_pdf);
+ break;
+ default:
+ assert(0);
+ }
+ static_pdf->compress_level = saved_compress_level;
+ return k;
+}
+
+static int orig_obj(lua_State * L)
+{
+ int n, first_arg = 1;
+ int k;
+ const_lstring st;
+ st.s = NULL;
+ n = lua_gettop(L);
+ if (n > 0 && lua_type(L, 1) == LUA_TNUMBER) {
+ first_arg++;
+ lua_number2int(k, lua_tonumber(L, 1));
+ check_obj_exists(static_pdf, obj_type_obj, k);
+ if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0)
+ luaL_error(L, "pdf.obj() object in use");
+ } else {
+ incr(static_pdf->obj_count);
+ pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1);
+ k = static_pdf->sys_obj_ptr;
+ }
+ pdf_last_obj = k;
+ obj_data_ptr(static_pdf, k) = pdf_get_mem(static_pdf, pdfmem_obj_size);
+ init_obj_obj(static_pdf, k);
+ switch (n - first_arg + 1) {
+ case 0:
+ luaL_error(L, "pdf.obj() needs at least one argument");
+ break;
+ case 1:
+ if (!lua_isstring(L, first_arg))
+ luaL_error(L, "pdf.obj() 1st argument must be string");
+ break;
+ case 2:
+ case 3:
+ if (!lua_isstring(L, first_arg))
+ luaL_error(L, "pdf.obj() 1st argument must be string");
+ if (!lua_isstring(L, first_arg + 1))
+ luaL_error(L, "pdf.obj() 2nd argument must be string");
+ st.s = lua_tolstring(L, first_arg, &st.l);
+ if (st.l == 4 && strncmp((const char *) st.s, "file", 4) == 0) {
+ if (n == first_arg + 2)
+ luaL_error(L, "pdf.obj() 3rd argument forbidden in file mode");
+ set_obj_obj_is_file(static_pdf, k);
+ } else {
+ if (n == first_arg + 2) { /* write attr text */
+ if (!lua_isstring(L, -1))
+ luaL_error(L, "pdf.obj() 3rd argument must be string");
+ obj_obj_stream_attr(static_pdf, k) =
+ luaL_ref(Luas, LUA_REGISTRYINDEX);
+ }
+ if (st.l == 6 && strncmp((const char *) st.s, "stream", 6) == 0) {
+ set_obj_obj_is_stream(static_pdf, k);
+ } else if (st.l == 10
+ && strncmp((const char *) st.s, "streamfile", 10) == 0) {
+ set_obj_obj_is_stream(static_pdf, k);
+ set_obj_obj_is_file(static_pdf, k);
+ } else
+ luaL_error(L, "pdf.obj() invalid argument");
+ }
+ break;
+ default:
+ luaL_error(L, "pdf.obj() allows max. 3 arguments");
+ }
+ obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX);
+ return k;
+}
+
+static int l_obj(lua_State * L)
+{
+ int n;
+ int k;
+ ensure_output_state(static_pdf, ST_HEADER_WRITTEN);
+ n = lua_gettop(L);
+ if (n == 1 && lua_istable(L, 1))
+ k = table_obj(L); /* new */
+ else
+ k = orig_obj(L);
+ lua_pushinteger(L, k);
+ return 1;
+}
+
+static int l_reserveobj(lua_State * L)
+{
+ int n;
+ const_lstring st;
+ st.s = 0;
+ n = lua_gettop(L);
+ switch (n) {
+ case 0:
+ incr(static_pdf->obj_count);
+ pdf_create_obj(static_pdf, obj_type_obj, static_pdf->sys_obj_ptr + 1);
+ pdf_last_obj = static_pdf->sys_obj_ptr;
+ break;
+ case 1:
+ if (!lua_isstring(L, -1))
+ luaL_error(L, "pdf.reserveobj() optional argument must be string");
+ st.s = lua_tolstring(L, 1, &st.l);
+ if (st.l == 5 && strncmp((const char *) st.s, "annot", 5) == 0) {
+ pdf_create_obj(static_pdf, obj_type_annot, 0);
+ pdf_last_annot = static_pdf->sys_obj_ptr;
+ } else {
+ luaL_error(L, "pdf.reserveobj() optional string must be \"annot\"");
+ }
+ lua_pop(L, 1);
+ break;
+ default:
+ luaL_error(L, "pdf.reserveobj() allows max. 1 argument");
+ }
+ lua_pushinteger(L, static_pdf->obj_ptr);
+ return 1;
+}
+
+static int l_registerannot(lua_State * L)
+{
+ int n, i;
+ n = lua_gettop(L);
+ switch (n) {
+ case 1:
+ if (!is_shipping_page)
+ luaL_error(L, "pdf.registerannot() can only be used in late lua");
+ i = (int) luaL_checkinteger(L, 1);
+ if (i <= 0)
+ luaL_error(L,
+ "pdf.registerannot() can only register positive object numbers");
+ addto_page_resources(static_pdf, obj_type_annot, -i);
+ break;
+ default:
+ luaL_error(L, "pdf.registerannot() needs exactly 1 argument");
+ }
+ return 0;
+}
+
static int getpdf(lua_State * L)
{
+ char *s;
const char *st;
- if (lua_isstring(L, 2)) {
- st = lua_tostring(L, 2);
- if (st && *st) {
- if (*st == 'h')
- return findcurh(L);
- else if (*st == 'v')
- return findcurv(L);
+ int i, l;
+ if (lua_isstring(L, 2) && (st = lua_tostring(L, 2)) != NULL) {
+ lua_pushvalue(L, 2); /* st ... */
+ lua_gettable(L, LUA_ENVIRONINDEX); /* i? ... */
+ if (lua_isnumber(L, -1)) { /* i ... */
+ i = (int) lua_tointeger(L, -1); /* i ... */
+ lua_pop(L, 1); /* ... */
+ switch (i) {
+ case P_PAGEATTRIBUTES:
+ s = tokenlist_to_cstring(pdf_pageattributes_toks, true, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ break;
+ case P_PAGERESOURCES:
+ s = tokenlist_to_cstring(pdf_pageresources_toks, true, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ break;
+ case P_PAGESATTRIBUTES:
+ s = tokenlist_to_cstring(pdf_pagesattributes_toks, true, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ break;
+ case P_PDFCATALOG:
+ case P_CATALOG:
+ s = tokenlist_to_cstring(pdf_catalog_toks, true, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ break;
+ case P_PDFINFO:
+ case P_INFO:
+ s = tokenlist_to_cstring(pdf_info_toks, true, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ break;
+ case P_PDFNAMES:
+ case P_NAMES:
+ s = tokenlist_to_cstring(pdf_names_toks, true, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ break;
+ case P_PDFTRAILER:
+ case P_TRAILER:
+ s = tokenlist_to_cstring(pdf_trailer_toks, true, &l);
+ lua_pushlstring(L, s, (size_t) l);
+ break;
+ case P_H:
+ lua_pushnumber(L, static_pdf->posstruct->pos.h);
+ break;
+ case P_V:
+ lua_pushnumber(L, static_pdf->posstruct->pos.v);
+ break;
+ default:
+ lua_rawget(L, -2);
+ }
+ } else {
+ lua_pop(L, 1); /* ... */
+ lua_rawget(L, -2);
}
+ } else {
+ lua_pushnil(L);
}
- lua_pushnil(L);
return 1;
}
static int setpdf(lua_State * L)
{
- return (L == NULL ? 0 : 0); /* for -Wall */
+ int i;
+ if (lua_gettop(L) != 3) {
+ return 0;
+ }
+ (void) luaL_checkstring(L, 2); /* ... */
+ lua_pushvalue(L, 2); /* st ... */
+ lua_gettable(L, LUA_ENVIRONINDEX); /* i? ... */
+ if (lua_isnumber(L, -1)) { /* i ... */
+ i = (int) lua_tointeger(L, -1); /* i ... */
+ lua_pop(L, 1); /* ... */
+ switch (i) {
+ case P_PAGEATTRIBUTES:
+ pdf_pageattributes_toks = tokenlist_from_lua(L);
+ break;
+ case P_PAGERESOURCES:
+ pdf_pageresources_toks = tokenlist_from_lua(L);
+ break;
+ case P_PAGESATTRIBUTES:
+ pdf_pagesattributes_toks = tokenlist_from_lua(L);
+ break;
+ case P_PDFCATALOG:
+ case P_CATALOG:
+ pdf_catalog_toks = tokenlist_from_lua(L);
+ break;
+ case P_PDFINFO:
+ case P_INFO:
+ pdf_info_toks = tokenlist_from_lua(L);
+ break;
+ case P_PDFNAMES:
+ case P_NAMES:
+ pdf_names_toks = tokenlist_from_lua(L);
+ break;
+ case P_PDFTRAILER:
+ case P_TRAILER:
+ pdf_trailer_toks = tokenlist_from_lua(L);
+ break;
+ case P_H:
+ case P_V:
+ /* can't set |h| and |v| yet */
+ default:
+ lua_rawset(L, -3);
+ }
+ } else {
+ lua_pop(L, 1); /* ... */
+ lua_rawset(L, -3);
+ }
+ return 0;
+}
+
+static int l_mapfile(lua_State * L)
+{
+ char *s;
+ const char *st;
+ if (lua_isstring(L, -1) && (st = lua_tostring(L, -1)) != NULL) {
+ s = xstrdup(st);
+ process_map_item(s, MAPFILE);
+ free(s);
+ }
+ return 0;
+}
+
+static int l_mapline(lua_State * L)
+{
+ char *s;
+ const char *st;
+ if (lua_isstring(L, -1) && (st = lua_tostring(L, -1)) != NULL) {
+ s = xstrdup(st);
+ process_map_item(s, MAPLINE);
+ free(s);
+ }
+ return 0;
+}
+
+static int l_pdfmapfile(lua_State * L)
+{
+ luaL_error(L, "pdf.pdfmapfile() is obsolete. Use pdf.mapfile() instead.");
+ return 0;
+}
+
+static int l_pdfmapline(lua_State * L)
+{
+ luaL_error(L, "pdf.pdfmapline() is obsolete. Use pdf.mapline() instead.");
+ return 0;
}
static const struct luaL_reg pdflib[] = {
- {"print", luapdfprint},
{"immediateobj", l_immediateobj},
+ {"mapfile", l_mapfile},
+ {"mapline", l_mapline},
+ {"obj", l_obj},
+ {"pdfmapfile", l_pdfmapfile}, /* obsolete */
+ {"pdfmapline", l_pdfmapline}, /* obsolete */
+ {"print", luapdfprint},
+ {"registerannot", l_registerannot},
+ {"reserveobj", l_reserveobj},
{NULL, NULL} /* sentinel */
};
+/**********************************************************************/
int luaopen_pdf(lua_State * L)
{
+ preset_environment(L, pdf_parms);
luaL_register(L, "pdf", pdflib);
/* build meta table */
luaL_newmetatable(L, "pdf_meta");
lua_pushstring(L, "__index");
lua_pushcfunction(L, getpdf);
/* do these later, NYI */
- if (0) {
- lua_settable(L, -3);
- lua_pushstring(L, "__newindex");
- lua_pushcfunction(L, setpdf);
- }
+ lua_settable(L, -3);
+ lua_pushstring(L, "__newindex");
+ lua_pushcfunction(L, setpdf);
lua_settable(L, -3);
lua_setmetatable(L, -2); /* meta to itself */
return 1;
diff --git a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c
index 1f264cd55bb..4d233c43e4a 100644
--- a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c
@@ -1,6 +1,6 @@
/* lstatslib.c
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,13 +17,12 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "inc-extra.h"
-
-
static const char _svn_version[] =
- "$Id: lstatslib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/lstatslib.c $";
+ "$Id: lstatslib.c 3477 2010-03-12 13:59:34Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/lstatslib.c $";
+
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
typedef struct statistic {
const char *name;
@@ -32,48 +31,147 @@ typedef struct statistic {
} statistic;
typedef const char *(*charfunc) (void);
-typedef integer(*intfunc) (void);
+typedef lua_Number(*numfunc) (void);
+typedef int (*intfunc) (void);
static const char *getbanner(void)
{
- return ptexbanner;
+ return (const char *) ptexbanner;
+}
+
+static const char *getlogname(void)
+{
+ return (const char *) texmf_log_name;
+}
+
+static const char *get_pdftex_banner(void)
+{
+ return (const char *) pdftex_banner;
+}
+
+static const char *get_output_file_name(void)
+{
+ if (static_pdf != NULL)
+ return (const char *) static_pdf->file_name;
+ return NULL;
+}
+
+static const char *getfilename(void)
+{
+ int t = 0;
+ int level = in_open;
+ while ((level > 0)) {
+ t = input_stack[level--].name_field;
+ if (t >= STRING_OFFSET)
+ return (const char *) str_string(t);
+ }
+ return "";
+}
+
+static const char *getlasterror(void)
+{
+ return last_error;
+}
+
+static const char *luatexrevision(void)
+{
+ return (const char *) (strrchr(luatex_version_string, '.') + 1);
+}
+
+static lua_Number get_pdf_gone(void)
+{
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->gone;
+ return (lua_Number) 0;
}
-/* hack, I really should implement the makecstring */
-static char *getfilename(void)
+static lua_Number get_pdf_ptr(void)
{
- integer t;
- t = get_current_name();
- if (t > (1 << 21))
- return makecstring(t);
- else
- return xstrdup("");
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->ptr;
+ return (lua_Number) 0;
}
-static char *getlasterror(void)
+static lua_Number get_pdf_os_cntr(void)
{
- return makecstring(last_error);
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->os_cntr;
+ return (lua_Number) 0;
}
-static char *luatexrevision(void)
+static lua_Number get_pdf_os_objidx(void)
{
- return makecstring(get_luatexrevision());
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->os_idx;
+ return (lua_Number) 0;
+}
+
+static lua_Number get_pdf_mem_size(void)
+{
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->mem_size;
+ return (lua_Number) 0;
+}
+
+static lua_Number get_pdf_mem_ptr(void)
+{
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->mem_ptr;
+ return (lua_Number) 0;
+}
+
+
+static lua_Number get_obj_ptr(void)
+{
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->obj_ptr;
+ return (lua_Number) 0;
+}
+
+static lua_Number get_obj_tab_size(void)
+{
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->obj_tab_size;
+ return (lua_Number) 0;
+}
+
+static lua_Number get_dest_names_size(void)
+{
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->dest_names_size;
+ return (lua_Number) 0;
+}
+
+static lua_Number get_dest_names_ptr(void)
+{
+ if (static_pdf != NULL)
+ return (lua_Number) static_pdf->dest_names_ptr;
+ return (lua_Number) 0;
+}
+
+static int get_hash_size(void)
+{
+ return hash_size; /* is a #define */
}
static int luastate_max = 1; /* fixed value */
+/* temp, for backward compat */
+static int init_pool_ptr = 0;
+
static struct statistic stats[] = {
- {"pdf_gone", 'g', &pdf_gone},
- {"pdf_ptr", 'g', &pdf_ptr},
+ {"pdf_gone", 'N', &get_pdf_gone},
+ {"pdf_ptr", 'N', &get_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},
+ {"output_file_name", 'S', (void *) &get_output_file_name},
+ {"log_name", 'S', (void *) &getlogname},
+ {"banner", 'S', (void *) &getbanner},
+ {"pdftex_banner", 'S', (void *) &get_pdftex_banner},
+ {"luatex_svn", 'G', &get_luatexsvn},
{"luatex_version", 'G', &get_luatexversion},
- {"luatex_revision", 'S', &luatexrevision},
+ {"luatex_revision", 'S', (void *) &luatexrevision},
{"ini_version", 'b', &ini_version},
/*
* mem stat
@@ -86,7 +184,7 @@ static struct statistic stats[] = {
{"str_ptr", 'g', &str_ptr},
{"init_str_ptr", 'g', &init_str_ptr},
{"max_strings", 'g', &max_strings},
- {"pool_ptr", 'g', &pool_ptr},
+ {"pool_ptr", 'g', &pool_size},
{"init_pool_ptr", 'g', &init_pool_ptr},
{"pool_size", 'g', &pool_size},
{"var_mem_max", 'g', &var_mem_max},
@@ -109,21 +207,21 @@ static struct statistic stats[] = {
{"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},
+ {"obj_ptr", 'N', &get_obj_ptr},
+ {"obj_tab_size", 'N', &get_obj_tab_size},
+ {"pdf_os_cntr", 'N', &get_pdf_os_cntr},
+ {"pdf_os_objidx", 'N', &get_pdf_os_objidx},
+ {"pdf_dest_names_ptr", 'N', &get_dest_names_ptr},
+ {"dest_names_size", 'N', &get_dest_names_size},
+ {"pdf_mem_ptr", 'N', &get_pdf_mem_ptr},
+ {"pdf_mem_size", 'N', &get_pdf_mem_size},
{"largest_used_mark", 'g', &biggest_used_mark},
- {"filename", 'S', &getfilename},
- {"inputid", 'G', &get_current_name},
+ {"filename", 'S', (void *) &getfilename},
+ {"inputid", 'g', &(iname)},
{"linenumber", 'g', &line},
- {"lasterrorstring", 'S', &getlasterror},
+ {"lasterrorstring", 'S', (void *) &getlasterror},
{"luabytecodes", 'g', &luabytecode_max},
{"luabytecode_bytes", 'g', &luabytecode_bytes},
@@ -137,7 +235,6 @@ static struct statistic stats[] = {
{NULL, 0, 0}
};
-
static int stats_name_to_id(const char *name)
{
int i;
@@ -154,6 +251,7 @@ static int do_getstat(lua_State * L, int i)
const char *st;
charfunc f;
intfunc g;
+ numfunc n;
int str;
t = stats[i].type;
switch (t) {
@@ -163,19 +261,25 @@ static int do_getstat(lua_State * L, int i)
lua_pushstring(L, st);
break;
case 's':
- str = *(integer *) (stats[i].value);
+ str = *(int *) (stats[i].value);
if (str) {
- lua_pushstring(L, makecstring(str));
+ char *ss = makecstring(str);
+ lua_pushstring(L, ss);
+ free(ss);
} else {
lua_pushnil(L);
}
break;
+ case 'N':
+ n = stats[i].value;
+ lua_pushnumber(L, n());
+ break;
case 'G':
g = stats[i].value;
lua_pushnumber(L, g());
break;
case 'g':
- lua_pushnumber(L, *(integer *) (stats[i].value));
+ lua_pushnumber(L, *(int *) (stats[i].value));
break;
case 'B':
g = stats[i].value;
@@ -188,7 +292,7 @@ static int do_getstat(lua_State * L, int i)
lua_pushnil(L);
break;
case 'b':
- lua_pushboolean(L, *(integer *) (stats[i].value));
+ lua_pushboolean(L, *(int *) (stats[i].value));
break;
default:
lua_pushnil(L);
diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c
index 458b4e240bc..79f92f83d53 100644
--- a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c
@@ -1,6 +1,6 @@
/* ltexiolib.c
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,17 +17,17 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: ltexiolib.c 2321 2009-04-18 09:17:13Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/ltexiolib.c $";
+ "$Id: ltexiolib.c 3550 2010-03-26 14:37:09Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/ltexiolib.c $";
-typedef void (*texio_printer) (str_number s);
+typedef void (*texio_printer) (const char *);
static char *loggable_info = NULL;
-static boolean get_selector_value(lua_State * L, int i, char *l)
+static boolean get_selector_value(lua_State * L, int i, int *l)
{
boolean r = false;
if (lua_isstring(L, i)) {
@@ -43,24 +43,19 @@ static boolean get_selector_value(lua_State * L, int i, char *l)
r = true;
}
} else {
- lua_pushstring(L, "first argument is not a string");
- lua_error(L);
+ luaL_error(L, "first argument is not a string");
}
return r;
}
static int do_texio_print(lua_State * L, texio_printer printfunction)
{
- str_number texs;
const char *s;
- size_t k;
int i = 1;
- str_number u = 0;
- char save_selector = selector;
+ int save_selector = selector;
int n = lua_gettop(L);
if (n == 0 || !lua_isstring(L, -1)) {
- lua_pushstring(L, "no string to print");
- lua_error(L);
+ luaL_error(L, "no string to print");
}
if (n > 1) {
if (get_selector_value(L, i, &selector))
@@ -70,23 +65,15 @@ static int do_texio_print(lua_State * L, texio_printer printfunction)
&& 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 = lua_tolstring(L, i, &k);
- texs = maketexlstring(s, k);
- printfunction(texs);
- flush_str(texs);
+ s = lua_tostring(L, i);
+ printfunction(s);
} else {
- lua_pushstring(L, "argument is not a string");
- lua_error(L);
+ luaL_error(L, "argument is not a string");
}
}
selector = save_selector;
- if (u != 0)
- str_ptr--;
return 0;
}
@@ -94,7 +81,7 @@ static void do_texio_ini_print(lua_State * L, const char *extra)
{
const char *s;
int i = 1;
- char l = term_and_log;
+ int l = term_and_log;
int n = lua_gettop(L);
if (n > 1) {
if (get_selector_value(L, i, &l))
@@ -120,20 +107,20 @@ static void do_texio_ini_print(lua_State * L, const char *extra)
static int texio_print(lua_State * L)
{
- if (ready_already != 314159 || pool_ptr == 0 || job_name == 0) {
+ if (ready_already != 314159 || job_name == 0) {
do_texio_ini_print(L, "");
return 0;
}
- return do_texio_print(L, zprint);
+ return do_texio_print(L, tprint);
}
static int texio_printnl(lua_State * L)
{
- if (ready_already != 314159 || pool_ptr == 0 || job_name == 0) {
+ if (ready_already != 314159 || job_name == 0) {
do_texio_ini_print(L, "\n");
return 0;
}
- return do_texio_print(L, zprint_nl);
+ return do_texio_print(L, tprint_nl);
}
/* at the point this function is called, the selector is log_only */
diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
index 82a54cc35bc..fa0544a1853 100644
--- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c
@@ -1,6 +1,6 @@
/* ltexlib.c
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,22 +17,29 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "nodes.h"
-#include "inc-extra.h"
-#include "commands.h"
-#include "tokens.h"
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
+
+
static const char _svn_version[] =
- "$Id: ltexlib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/ltexlib.c $";
+ "$Id: ltexlib.c 3550 2010-03-26 14:37:09Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/ltexlib.c $";
+
+#define attribute(A) eqtb[attribute_base+(A)].hh.rh
+#define dimen(A) eqtb[scaled_base+(A)].hh.rh
+#undef skip
+#define skip(A) eqtb[skip_base+(A)].hh.rh
+#define mu_skip(A) eqtb[mu_skip_base+(A)].hh.rh
+#define count(A) eqtb[count_base+(A)].hh.rh
+#define box(A) equiv(box_base+(A))
+
typedef struct {
char *text;
unsigned int tsize;
void *next;
boolean partial;
- integer cattable;
+ int cattable;
} rope;
typedef struct {
@@ -51,20 +58,20 @@ 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)
+static void luac_store(lua_State * L, int i, int partial, int cattable)
{
char *st;
const char *sttemp;
size_t tsize;
rope *rn = NULL;
sttemp = lua_tolstring(L, i, &tsize);
- st = xmalloc((tsize + 1));
+ st = xmalloc((unsigned) (tsize + 1));
memcpy(st, sttemp, (tsize + 1));
if (st) {
luacstrings++;
rn = (rope *) xmalloc(sizeof(rope));
rn->text = st;
- rn->tsize = tsize;
+ rn->tsize = (unsigned) tsize;
rn->partial = partial;
rn->cattable = cattable;
rn->next = NULL;
@@ -83,12 +90,12 @@ static void luac_store(lua_State * L, int i, int partial, integer cattable)
static int do_luacprint(lua_State * L, int partial, int deftable)
{
int i, n;
- integer cattable = (integer) deftable;
+ 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);
+ lua_number2int(cattable, lua_tonumber(L, 1));
startstrings = 2;
}
}
@@ -105,8 +112,7 @@ static int do_luacprint(lua_State * L, int partial, int deftable)
} else {
for (i = startstrings; i <= n; i++) {
if (!lua_isstring(L, i)) {
- lua_pushstring(L, "no string to print");
- lua_error(L);
+ luaL_error(L, "no string to print");
}
luac_store(L, i, partial, cattable);
}
@@ -114,24 +120,61 @@ static int do_luacprint(lua_State * L, int partial, int deftable)
return 0;
}
-static int luacwrite(lua_State * L)
+int luacwrite(lua_State * L)
{
return do_luacprint(L, FULL_LINE, NO_CAT_TABLE);
}
-static int luacprint(lua_State * L)
+int luacprint(lua_State * L)
{
return do_luacprint(L, FULL_LINE, DEFAULT_CAT_TABLE);
}
-static int luacsprint(lua_State * L)
+int luacsprint(lua_State * L)
{
return do_luacprint(L, PARTIAL_LINE, DEFAULT_CAT_TABLE);
}
-integer luacstring_cattable(void)
+int luactprint(lua_State * L)
{
- return (integer) read_spindle.tail->cattable;
+ int i, j, n;
+ int cattable, startstrings;
+ n = lua_gettop(L);
+ for (i = 1; i <= n; i++) {
+ cattable = DEFAULT_CAT_TABLE;
+ startstrings = 1;
+ if (lua_type(L, i) != LUA_TTABLE) {
+ luaL_error(L, "no string to print");
+ }
+ lua_pushvalue(L, i); /* push the table */
+ lua_pushnumber(L, 1);
+ lua_gettable(L, -2);
+ if (lua_type(L, -1) == LUA_TNUMBER) {
+ lua_number2int(cattable, lua_tonumber(L, -1));
+ startstrings = 2;
+ }
+ lua_pop(L, 1);
+
+ for (j = startstrings;; j++) {
+ lua_pushnumber(L, j);
+ lua_gettable(L, -2);
+ if (lua_type(L, -1) == LUA_TSTRING) {
+ luac_store(L, -1, PARTIAL_LINE, cattable);
+ lua_pop(L, 1);
+ } else {
+ lua_pop(L, 1);
+ break;
+ }
+ }
+ lua_pop(L, 1); /* pop the table */
+ }
+ return 0;
+}
+
+
+int luacstring_cattable(void)
+{
+ return (int) read_spindle.tail->cattable;
}
int luacstring_partial(void)
@@ -164,11 +207,10 @@ int luacstring_input(void)
/* 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);
+ check_buffer_overflow(last + (int) t->tsize);
+
while (t->tsize-- > 0)
- buffer[last++] = *st++;
+ buffer[last++] = (packed_ASCII_code) * st++;
if (!t->partial) {
while (last - 1 > ret && buffer[last - 1] == ' ')
last--;
@@ -190,7 +232,10 @@ 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 =
+ xrealloc(spindles,
+ (unsigned) (sizeof(spindle) *
+ (unsigned) (spindle_size + 1)));
spindles[spindle_index].head = NULL;
spindles[spindle_index].tail = NULL;
spindles[spindle_index].complete = 0;
@@ -222,70 +267,330 @@ void luacstring_close(int n)
/* local (static) versions */
-#define width_offset 1
-#define depth_offset 2
-#define height_offset 3
-
#define check_index_range(j,s) \
if (j<0 || j > 65535) { \
- lua_pushfstring(L, "incorrect index value %d for tex.%s()", (int)j, s); \
- lua_error(L); }
+ luaL_error(L, "incorrect index value %d for tex.%s()", (int)j, s); }
+
+
+static const char *scan_integer_part(lua_State * L, const char *ss, int *ret,
+ int *radix_ret)
+{
+ boolean negative = false; /* should the answer be negated? */
+ int m; /* |$2^{31}$ / radix|, the threshold of danger */
+ int d; /* the digit just scanned */
+ boolean vacuous; /* have no digits appeared? */
+ boolean OK_so_far; /* has an error message been issued? */
+ int radix = 0; /* the radix of the integer */
+ int c = 0; /* the current character */
+ const char *s; /* where we stopped in the string |ss| */
+ integer cur_val = 0; /* return value */
+ s = ss;
+ do {
+ do {
+ c = *s++;
+ } while (c && c == ' ');
+ if (c == '-') {
+ negative = !negative;
+ c = '+';
+ }
+ } while (c == '+');
+
+
+ radix = 10;
+ m = 214748364;
+ if (c == '\'') {
+ radix = 8;
+ m = 02000000000;
+ c = *s++;
+ } else if (c == '"') {
+ radix = 16;
+ m = 01000000000;
+ c = *s++;
+ }
+ vacuous = true;
+ cur_val = 0;
+ OK_so_far = true;
+
+ /* Accumulate the constant until |cur_tok| is not a suitable digit */
+ while (1) {
+ if ((c < '0' + radix) && (c >= '0') && (c <= '0' + 9)) {
+ d = c - '0';
+ } else if (radix == 16) {
+ if ((c <= 'A' + 5) && (c >= 'A')) {
+ d = c - 'A' + 10;
+ } else if ((c <= 'a' + 5) && (c >= 'a')) {
+ d = c - 'a' + 10;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ vacuous = false;
+ if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10))) {
+ if (OK_so_far) {
+ luaL_error(L, "Number too big");
+ cur_val = infinity;
+ OK_so_far = false;
+ }
+ } else {
+ cur_val = cur_val * radix + d;
+ }
+ c = *s++;
+ }
+ if (vacuous) {
+ /* Express astonishment that no number was here */
+ luaL_error(L, "Missing number, treated as zero");
+ }
+ if (negative)
+ cur_val = -cur_val;
+ *ret = cur_val;
+ *radix_ret = radix;
+ if (c != ' ' && s > ss)
+ s--;
+ return s;
+}
+
+#define set_conversion(A,B) do { num=(A); denom=(B); } while(0)
+
+
+static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret)
+/* sets |cur_val| to a dimension */
+{
+ boolean negative = false; /* should the answer be negated? */
+ int f = 0; /* numerator of a fraction whose denominator is $2^{16}$ */
+ int num, denom; /* conversion ratio for the scanned units */
+ int k; /* number of digits in a decimal fraction */
+ scaled v; /* an internal dimension */
+ int save_cur_val; /* temporary storage of |cur_val| */
+ int arith_error = false;
+ int c; /* the current character */
+ const char *s = ss; /* where we are in the string */
+ int radix = 0; /* the current radix */
+ int rdig[18]; /* to save the |dig[]| array */
+ int saved_tex_remainder; /* to save |tex_remainder| */
+ int saved_arith_error; /* to save |arith_error| */
+ int saved_cur_val; /* to save the global |cur_val| */
+ saved_tex_remainder = tex_remainder;
+ saved_arith_error = arith_error;
+ saved_cur_val = cur_val;
+ /* Get the next non-blank non-sign... */
+ do {
+ /* Get the next non-blank non-call token */
+ do {
+ c = *s++;
+ } while (c && c == ' ');
+ if (c == '-') {
+ negative = !negative;
+ c = '+';
+ }
+ } while (c == '+');
+ if (c == ',') {
+ c = '.';
+ }
+ if (c != '.') {
+ s = scan_integer_part(L, (s > ss ? (s - 1) : ss), &cur_val, &radix);
+ c = *s;
+ } else {
+ radix = 10;
+ cur_val = 0;
+ c = *(--s);
+ }
+ if (c == ',')
+ c = '.';
+ if ((radix == 10) && (c == '.')) {
+ /* Scan decimal fraction */
+ for (k = 0; k < 18; k++)
+ rdig[k] = dig[k];
+ k = 0;
+ s++; /* get rid of the '.' */
+ while (1) {
+ c = *s++;
+ if ((c > '0' + 9) || (c < '0'))
+ break;
+ if (k < 17) { /* digits for |k>=17| cannot affect the result */
+ dig[k++] = c - '0';
+ }
+ }
+ f = round_decimals(k);
+ if (c != ' ')
+ c = *(--s);
+ for (k = 0; k < 18; k++)
+ dig[k] = rdig[k];
+ }
+ if (cur_val < 0) { /* in this case |f=0| */
+ negative = !negative;
+ cur_val = -cur_val;
+ }
+
+ /* Scan for (u)units that are internal dimensions;
+ |goto attach_sign| with |cur_val| set if found */
+ save_cur_val = cur_val;
+ /* Get the next non-blank non-call... */
+ do {
+ c = *s++;
+ } while (c && c == ' ');
+ if (c != ' ')
+ c = *(--s);
+ if (strncmp(s, "em", 2) == 0) {
+ s += 2;
+ v = (quad(get_cur_font()));
+ } else if (strncmp(s, "ex", 2) == 0) {
+ s += 2;
+ v = (x_height(get_cur_font()));
+ } else if (strncmp(s, "px", 2) == 0) {
+ s += 2;
+ v = dimen_par(pdf_px_dimen_code);
+ } else {
+ goto NOT_FOUND;
+ }
+ c = *s++;
+ if (c != ' ') {
+ c = *(--s);
+ }
+ cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000));
+ goto ATTACH_SIGN;
+ NOT_FOUND:
+
+ /* Scan for (m)\.{mu} units and |goto attach_fraction| */
+ if (strncmp(s, "mu", 2) == 0) {
+ s += 2;
+ goto ATTACH_FRACTION;
+ }
+ if (strncmp(s, "true", 4) == 0) {
+ /* Adjust (f)for the magnification ratio */
+ s += 4;
+ prepare_mag();
+ if (int_par(mag_code) != 1000) {
+ cur_val = xn_over_d(cur_val, 1000, int_par(mag_code));
+ f = (1000 * f + 0200000 * tex_remainder) / int_par(mag_code);
+ cur_val = cur_val + (f / 0200000);
+ f = f % 0200000;
+ }
+ do {
+ c = *s++;
+ } while (c && c == ' ');
+ c = *(--s);
+ }
+ if (strncmp(s, "pt", 2) == 0) {
+ s += 2;
+ goto ATTACH_FRACTION; /* the easy case */
+ }
+ /* Scan for (a)all other units and adjust |cur_val| and |f| accordingly;
+ |goto done| in the case of scaled points */
+
+ if (strncmp(s, "in", 2) == 0) {
+ s += 2;
+ set_conversion(7227, 100);
+ } else if (strncmp(s, "pc", 2) == 0) {
+ s += 2;
+ set_conversion(12, 1);
+ } else if (strncmp(s, "cm", 2) == 0) {
+ s += 2;
+ set_conversion(7227, 254);
+ } else if (strncmp(s, "mm", 2) == 0) {
+ s += 2;
+ set_conversion(7227, 2540);
+ } else if (strncmp(s, "bp", 2) == 0) {
+ s += 2;
+ set_conversion(7227, 7200);
+ } else if (strncmp(s, "dd", 2) == 0) {
+ s += 2;
+ set_conversion(1238, 1157);
+ } else if (strncmp(s, "cc", 2) == 0) {
+ s += 2;
+ set_conversion(14856, 1157);
+ } else if (strncmp(s, "nd", 2) == 0) {
+ s += 2;
+ set_conversion(685, 642);
+ } else if (strncmp(s, "nc", 2) == 0) {
+ s += 2;
+ set_conversion(1370, 107);
+ } else if (strncmp(s, "sp", 2) == 0) {
+ s += 2;
+ goto DONE;
+ } else {
+ /* Complain about unknown unit and |goto done2| */
+ luaL_error(L, "Illegal unit of measure (pt inserted)");
+ goto DONE2;
+ }
+ cur_val = xn_over_d(cur_val, num, denom);
+ f = (num * f + 0200000 * tex_remainder) / denom;
+ cur_val = cur_val + (f / 0200000);
+ f = f % 0200000;
+ DONE2:
+ ATTACH_FRACTION:
+ if (cur_val >= 040000)
+ arith_error = true;
+ else
+ cur_val = cur_val * 65536 + f;
+ DONE:
+ /* Scan an optional space */
+ c = *s++;
+ if (c != ' ')
+ s--;
+ ATTACH_SIGN:
+ if (arith_error || (abs(cur_val) >= 010000000000)) {
+ /* Report that this dimension is out of range */
+ luaL_error(L, "Dimension too large");
+ cur_val = max_dimen;
+ }
+ if (negative)
+ cur_val = -cur_val;
+ *ret = cur_val;
+ tex_remainder = saved_tex_remainder;
+ arith_error = saved_arith_error;
+ cur_val = saved_cur_val;
+ return s;
+}
int dimen_to_number(lua_State * L, const 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);
+ int j = 0;
+ const char *d = scan_dimen_part(L, s, &j);
+ if (*d) {
+ luaL_error(L, "conversion failed (trailing junk?)");
j = 0;
}
return j;
}
-static integer get_item_index(lua_State * L, int i, integer base)
+static int tex_scaledimen(lua_State * L)
+{ /* following vsetdimen() */
+ int sp;
+ if (!lua_isnumber(L, 1)) {
+ if (lua_isstring(L, 1)) {
+ sp = dimen_to_number(L, lua_tostring(L, 1));
+ } else {
+ luaL_error(L, "argument must be a string or a number");
+ return 0;
+ }
+ } else {
+ lua_number2int(sp, lua_tonumber(L, 1));
+ }
+ lua_pushnumber(L, sp);
+ return 1;
+}
+
+
+int get_item_index(lua_State * L, int i, int base)
{
size_t kk;
- integer k;
+ int k;
int cur_cs;
const char *s;
if (lua_type(L, i) == LUA_TSTRING) {
s = lua_tolstring(L, i, &kk);
cur_cs = string_lookup(s, kk);
- if (cur_cs == static_undefined_control_sequence ||
- is_undefined_cs(cur_cs)) {
+ if (cur_cs == undefined_control_sequence || cur_cs == undefined_cs_cmd) {
k = -1; /* guarandeed invalid */
} else {
- k = (zget_equiv(cur_cs) - base);
+ k = (equiv(cur_cs) - base);
}
} else {
- k = (integer) luaL_checkinteger(L, i);
+ k = (int) luaL_checkinteger(L, i);
}
return k;
}
@@ -294,28 +599,28 @@ static integer get_item_index(lua_State * L, int i, integer base)
static int vsetdimen(lua_State * L, int is_global)
{
int i, j, err;
- integer k;
- integer save_global_defs = int_par(param_global_defs_code);
+ int k;
+ int save_global_defs = int_par(global_defs_code);
if (is_global)
- int_par(param_global_defs_code) = 1;
+ int_par(global_defs_code) = 1;
i = lua_gettop(L);
j = 0;
/* find the value */
- if (!lua_isnumber(L, i))
+ if (!lua_isnumber(L, i)) {
if (lua_isstring(L, i)) {
j = dimen_to_number(L, lua_tostring(L, i));
} else {
- lua_pushstring(L, "unsupported value type");
- lua_error(L);
- } else
- j = (int) lua_tonumber(L, i);
- k = get_item_index(L, (i - 1), get_scaled_base());
+ luaL_error(L, "unsupported value type");
+ }
+ } else {
+ lua_number2int(j, lua_tonumber(L, i));
+ }
+ k = get_item_index(L, (i - 1), scaled_base);
check_index_range(k, "setdimen");
err = set_tex_dimen_register(k, j);
- int_par(param_global_defs_code) = save_global_defs;
+ int_par(global_defs_code) = save_global_defs;
if (err) {
- lua_pushstring(L, "incorrect value");
- lua_error(L);
+ luaL_error(L, "incorrect value");
}
return 0;
}
@@ -335,8 +640,8 @@ static int setdimen(lua_State * L)
static int getdimen(lua_State * L)
{
int j;
- integer k;
- k = get_item_index(L, lua_gettop(L), get_scaled_base());
+ int k;
+ k = get_item_index(L, lua_gettop(L), scaled_base);
check_index_range(k, "getdimen");
j = get_tex_dimen_register(k);
lua_pushnumber(L, j);
@@ -347,19 +652,18 @@ static int vsetskip(lua_State * L, int is_global)
{
int i, err;
halfword *j;
- integer k;
- integer save_global_defs = int_par(param_global_defs_code);
+ int k;
+ int save_global_defs = int_par(global_defs_code);
if (is_global)
- int_par(param_global_defs_code) = 1;
+ int_par(global_defs_code) = 1;
i = lua_gettop(L);
j = check_isnode(L, i); /* the value */
- k = get_item_index(L, (i - 1), get_skip_base());
+ k = get_item_index(L, (i - 1), skip_base);
check_index_range(k, "setskip"); /* the index */
err = set_tex_skip_register(k, *j);
- int_par(param_global_defs_code) = save_global_defs;
+ int_par(global_defs_code) = save_global_defs;
if (err) {
- lua_pushstring(L, "incorrect value");
- lua_error(L);
+ luaL_error(L, "incorrect value");
}
return 0;
}
@@ -376,11 +680,11 @@ static int setskip(lua_State * L)
return vsetskip(L, isglobal);
}
-static int getskip(lua_State * L)
+int getskip(lua_State * L)
{
halfword j;
- integer k;
- k = get_item_index(L, lua_gettop(L), get_skip_base());
+ int k;
+ k = get_item_index(L, lua_gettop(L), skip_base);
check_index_range(k, "getskip");
j = get_tex_skip_register(k);
lua_nodelib_push_fast(L, j);
@@ -392,19 +696,18 @@ static int getskip(lua_State * L)
static int vsetcount(lua_State * L, int is_global)
{
int i, j, err;
- integer k;
- integer save_global_defs = int_par(param_global_defs_code);
+ int k;
+ int save_global_defs = int_par(global_defs_code);
if (is_global)
- int_par(param_global_defs_code) = 1;
+ int_par(global_defs_code) = 1;
i = lua_gettop(L);
j = (int) luaL_checkinteger(L, i);
- k = get_item_index(L, (i - 1), get_count_base());
+ k = get_item_index(L, (i - 1), count_base);
check_index_range(k, "setcount");
err = set_tex_count_register(k, j);
- int_par(param_global_defs_code) = save_global_defs;
+ int_par(global_defs_code) = save_global_defs;
if (err) {
- lua_pushstring(L, "incorrect value");
- lua_error(L);
+ luaL_error(L, "incorrect value");
}
return 0;
}
@@ -424,8 +727,8 @@ static int setcount(lua_State * L)
static int getcount(lua_State * L)
{
int j;
- integer k;
- k = get_item_index(L, lua_gettop(L), get_count_base());
+ int k;
+ k = get_item_index(L, lua_gettop(L), count_base);
check_index_range(k, "getcount");
j = get_tex_count_register(k);
lua_pushnumber(L, j);
@@ -436,19 +739,18 @@ static int getcount(lua_State * L)
static int vsetattribute(lua_State * L, int is_global)
{
int i, j, err;
- integer k;
- integer save_global_defs = int_par(param_global_defs_code);
+ int k;
+ int save_global_defs = int_par(global_defs_code);
if (is_global)
- int_par(param_global_defs_code) = 1;
+ int_par(global_defs_code) = 1;
i = lua_gettop(L);
j = (int) luaL_checkinteger(L, i);
- k = get_item_index(L, (i - 1), get_attribute_base());
+ k = get_item_index(L, (i - 1), attribute_base);
check_index_range(k, "setattribute");
err = set_tex_attribute_register(k, j);
- int_par(param_global_defs_code) = save_global_defs;
+ int_par(global_defs_code) = save_global_defs;
if (err) {
- lua_pushstring(L, "incorrect value");
- lua_error(L);
+ luaL_error(L, "incorrect value");
}
return 0;
}
@@ -468,38 +770,34 @@ static int setattribute(lua_State * L)
static int getattribute(lua_State * L)
{
int j;
- integer k;
- k = get_item_index(L, lua_gettop(L), get_attribute_base());
+ int k;
+ k = get_item_index(L, lua_gettop(L), attribute_base);
check_index_range(k, "getattribute");
j = get_tex_attribute_register(k);
lua_pushnumber(L, j);
return 1;
}
-static int vsettoks(lua_State * L, int is_global)
+int vsettoks(lua_State * L, int is_global)
{
- int i, j, err;
- size_t len;
- integer k;
- const char *st;
- integer save_global_defs = int_par(param_global_defs_code);
+ int i, err;
+ int k;
+ lstring str;
+ int save_global_defs = int_par(global_defs_code);
if (is_global)
- int_par(param_global_defs_code) = 1;
+ int_par(global_defs_code) = 1;
i = lua_gettop(L);
if (!lua_isstring(L, i)) {
- lua_pushstring(L, "unsupported value type");
- lua_error(L);
+ luaL_error(L, "unsupported value type");
}
- st = lua_tolstring(L, i, &len);
- k = get_item_index(L, (i - 1), get_toks_base());
+ str.s = (unsigned char *) xstrdup(lua_tolstring(L, i, &str.l));
+ k = get_item_index(L, (i - 1), toks_base);
check_index_range(k, "settoks");
- j = maketexlstring(st, len);
- err = zset_tex_toks_register(k, j);
- int_par(param_global_defs_code) = save_global_defs;
+ err = set_tex_toks_register(k, str);
+ xfree(str.s);
+ int_par(global_defs_code) = save_global_defs;
if (err) {
- flush_str(j);
- lua_pushstring(L, "incorrect value");
- lua_error(L);
+ luaL_error(L, "incorrect value");
}
return 0;
}
@@ -518,12 +816,15 @@ static int settoks(lua_State * L)
static int gettoks(lua_State * L)
{
- integer k;
+ int k;
str_number t;
- k = get_item_index(L, lua_gettop(L), get_toks_base());
+ char *ss;
+ k = get_item_index(L, lua_gettop(L), toks_base);
check_index_range(k, "gettoks");
t = get_tex_toks_register(k);
- lua_pushstring(L, makecstring(t));
+ ss = makecstring(t);
+ lua_pushstring(L, ss);
+ free(ss);
flush_str(t);
return 1;
}
@@ -531,19 +832,19 @@ static int gettoks(lua_State * L)
static int get_box_id(lua_State * L, int i)
{
const char *s;
- integer cur_cs, cur_cmd;
+ int cur_cs, cur_cmd;
size_t k = 0;
int j = -1;
if (lua_type(L, i) == LUA_TSTRING) {
s = lua_tolstring(L, i, &k);
cur_cs = string_lookup(s, k);
- cur_cmd = zget_eq_type(cur_cs);
+ cur_cmd = 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);
+ j = equiv(cur_cs);
}
} else {
- j = (int) lua_tonumber(L, (i));
+ lua_number2int(j, lua_tonumber(L, (i)));
}
return j;
}
@@ -561,9 +862,9 @@ static int getbox(lua_State * L)
static int vsetbox(lua_State * L, int is_global)
{
int i, j, k, err;
- integer save_global_defs = int_par(param_global_defs_code);
+ int save_global_defs = int_par(global_defs_code);
if (is_global)
- int_par(param_global_defs_code) = 1;
+ int_par(global_defs_code) = 1;
k = get_box_id(L, -2);
check_index_range(k, "setbox");
i = get_tex_box_register(k);
@@ -575,12 +876,17 @@ static int vsetbox(lua_State * L, int is_global)
return 0;
} else {
j = nodelist_from_lua(L);
+ if (j != null && type(j) != hlist_node && type(j) != vlist_node) {
+ luaL_error(L, "setbox: incompatible node type (%s)\n",
+ get_node_name(type(j), subtype(j)));
+ return 0;
+ }
+
}
err = set_tex_box_register(k, j);
- int_par(param_global_defs_code) = save_global_defs;
+ int_par(global_defs_code) = save_global_defs;
if (err) {
- lua_pushstring(L, "incorrect value");
- lua_error(L);
+ luaL_error(L, "incorrect value");
}
return 0;
}
@@ -604,8 +910,7 @@ static int getboxdim(lua_State * L, int whichdim)
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);
+ luaL_error(L, "incorrect index");
}
switch (whichdim) {
case width_offset:
@@ -620,17 +925,17 @@ static int getboxdim(lua_State * L, int whichdim)
return 1;
}
-static int getboxwd(lua_State * L)
+int getboxwd(lua_State * L)
{
return getboxdim(L, width_offset);
}
-static int getboxht(lua_State * L)
+int getboxht(lua_State * L)
{
return getboxdim(L, height_offset);
}
-static int getboxdp(lua_State * L)
+int getboxdp(lua_State * L)
{
return getboxdim(L, depth_offset);
}
@@ -638,20 +943,19 @@ static int getboxdp(lua_State * L)
static int vsetboxdim(lua_State * L, int whichdim, int is_global)
{
int i, j, k, err;
- integer save_global_defs = int_par(param_global_defs_code);
+ int save_global_defs = int_par(global_defs_code);
if (is_global)
- int_par(param_global_defs_code) = 1;
+ int_par(global_defs_code) = 1;
i = lua_gettop(L);
if (!lua_isnumber(L, i)) {
j = dimen_to_number(L, lua_tostring(L, i));
} else {
- j = (int) lua_tonumber(L, i);
+ lua_number2int(j, 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);
+ luaL_error(L, "incorrect index");
}
err = 0;
switch (whichdim) {
@@ -664,10 +968,9 @@ static int vsetboxdim(lua_State * L, int whichdim, int is_global)
case depth_offset:
err = set_tex_box_depth(k, j);
}
- int_par(param_global_defs_code) = save_global_defs;
+ int_par(global_defs_code) = save_global_defs;
if (err) {
- lua_pushstring(L, "not a box");
- lua_error(L);
+ luaL_error(L, "not a box");
}
return 0;
}
@@ -708,7 +1011,7 @@ static int setboxdp(lua_State * L)
return vsetboxdim(L, depth_offset, isglobal);
}
-static int settex(lua_State * L)
+int settex(lua_State * L)
{
const char *st;
int i, j, texstr;
@@ -728,94 +1031,84 @@ static int settex(lua_State * L)
}
cur_cs = string_lookup(st, k);
flush_str(texstr);
- cur_cmd = zget_eq_type(cur_cs);
+ cur_cmd = eq_type(cur_cs);
if (is_int_assign(cur_cmd)) {
if (lua_isnumber(L, i)) {
+ int luai;
+ lua_number2int(luai, lua_tonumber(L, i));
assign_internal_value((isglobal ? 4 : 0),
- zget_equiv(cur_cs), lua_tonumber(L,
- i));
+ equiv(cur_cs), luai);
} else {
- lua_pushstring(L, "unsupported value type");
- lua_error(L);
+ luaL_error(L, "unsupported value type");
}
} else if (is_dim_assign(cur_cmd)) {
if (!lua_isnumber(L, i)) {
if (lua_isstring(L, i)) {
j = dimen_to_number(L, lua_tostring(L, i));
} else {
- lua_pushstring(L, "unsupported value type");
- lua_error(L);
+ luaL_error(L, "unsupported value type");
}
} else {
- j = (int) lua_tonumber(L, i);
+ lua_number2int(j, lua_tonumber(L, i));
}
- assign_internal_value((isglobal ? 4 : 0), zget_equiv(cur_cs),
- j);
+ assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs), j);
+ } else if (is_toks_assign(cur_cmd)) {
+ if (lua_isstring(L, i)) {
+ j = tokenlist_from_lua(L); /* uses stack -1 */
+ assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs), j);
+
+ } else {
+ luaL_error(L, "unsupported value type");
+ }
+
} else {
- lua_pushstring(L, "unsupported tex internal assignment");
- lua_error(L);
+ luaL_error(L, "unsupported tex internal assignment");
}
} else {
- lua_rawset(L, (i - 2));
+ if (lua_istable(L, (i - 2)))
+ lua_rawset(L, (i - 2));
}
} else {
- lua_rawset(L, (i - 2));
+ if (lua_istable(L, (i - 2)))
+ lua_rawset(L, (i - 2));
}
return 0;
}
-#if 0 /* unused */
-static 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;
-}
-#endif
-
-static int do_convert(lua_State * L, int cur_code)
+int do_convert(lua_State * L, int cur_code)
{
int texstr;
- integer i = -1;
+ int i = -1;
char *str = NULL;
switch (cur_code) {
- case convert_pdf_creation_date_code: /* ? */
- case convert_pdf_insert_ht_code: /* arg <register int> */
- 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 */
+ case pdf_creation_date_code: /* ? */
+ case pdf_insert_ht_code: /* arg <register int> */
+ case pdf_ximage_bbox_code: /* arg 2 ints */
+ case lua_code: /* arg complex */
+ case lua_escape_string_code: /* arg token list */
+ case pdf_colorstack_init_code: /* arg complex */
+ case left_margin_kern_code: /* arg box */
+ case right_margin_kern_code: /* arg box */
break;
- case convert_string_code: /* arg token */
- case convert_meaning_code: /* arg token */
+ case string_code: /* arg token */
+ case 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 */
+ case font_name_code: /* arg fontid */
+ case font_identifier_code: /* arg fontid */
+ case pdf_font_name_code: /* arg fontid */
+ case pdf_font_objnum_code: /* arg fontid */
+ case pdf_font_size_code: /* arg fontid */
+ case uniform_deviate_code: /* arg int */
+ case number_code: /* arg int */
+ case roman_numeral_code: /* arg int */
+ case pdf_page_ref_code: /* arg int */
+ case pdf_xform_name_code: /* arg int */
if (lua_gettop(L) < 1) {
/* error */
}
- i = lua_tonumber(L, 1); /* these fall through! */
+ lua_number2int(i, lua_tonumber(L, 1)); /* these fall through! */
default:
texstr = the_convert_string(cur_code, i);
if (texstr) {
@@ -823,22 +1116,24 @@ static int do_convert(lua_State * L, int cur_code)
flush_str(texstr);
}
}
- if (str)
+ if (str) {
lua_pushstring(L, str);
- else
+ free(str);
+ } else {
lua_pushnil(L);
+ }
return 1;
}
-static int do_scan_internal(lua_State * L, int cur_cmd, int cur_code)
+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);
+ scan_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) {
@@ -848,10 +1143,12 @@ static int do_scan_internal(lua_State * L, int cur_cmd, int cur_code)
} else { /* dir_val_level, mu_val_level, tok_val_level */
texstr = the_scanned_result();
str = makecstring(texstr);
- if (str)
+ if (str) {
lua_pushstring(L, str);
- else
+ free(str);
+ } else {
lua_pushnil(L);
+ }
flush_str(texstr);
}
cur_val = save_cur_val;
@@ -859,74 +1156,74 @@ static int do_scan_internal(lua_State * L, int cur_cmd, int cur_code)
return 1;
}
-static int do_lastitem(lua_State * L, int cur_code)
+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:
+ case lastattr_code:
+ case 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:
+ case numexpr_code:
+ case dimexpr_code:
+ case glueexpr_code:
+ case 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:
+ case mu_to_glue_code:
+ case glue_to_mu_code:
+ case glue_stretch_order_code:
+ case glue_shrink_order_code:
+ case glue_stretch_code:
+ case 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:
+ case font_char_wd_code:
+ case font_char_ht_code:
+ case font_char_dp_code:
+ case 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:
+ case par_shape_length_code:
+ case par_shape_indent_code:
+ case 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:
+ case lastpenalty_code:
+ case lastkern_code:
+ case lastskip_code:
+ case last_node_type_code:
+ case input_line_no_code:
+ case badness_code:
+ case pdftex_version_code:
+ case pdf_last_obj_code:
+ case pdf_last_xform_code:
+ case pdf_last_ximage_code:
+ case pdf_last_ximage_pages_code:
+ case pdf_last_annot_code:
+ case pdf_last_x_pos_code:
+ case pdf_last_y_pos_code:
+ case pdf_retval_code:
+ case pdf_last_ximage_colordepth_code:
+ case random_seed_code:
+ case pdf_last_link_code:
+ case luatex_version_code:
+ case Aleph_version_code:
+ case Omega_version_code:
+ case Aleph_minor_version_code:
+ case Omega_minor_version_code:
+ case eTeX_minor_version_code:
+ case eTeX_version_code:
+ case current_group_level_code:
+ case current_group_type_code:
+ case current_if_level_code:
+ case current_if_type_code:
+ case current_if_branch_code:
retval = do_scan_internal(L, last_item_cmd, cur_code);
break;
default:
@@ -939,7 +1236,7 @@ static int do_lastitem(lua_State * L, int cur_code)
static int tex_setmathparm(lua_State * L)
{
int i, j;
- scaled k;
+ int k;
int n;
int l = cur_level;
n = lua_gettop(L);
@@ -952,8 +1249,8 @@ static int tex_setmathparm(lua_State * L)
}
i = luaL_checkoption(L, (n - 2), NULL, math_param_names);
j = luaL_checkoption(L, (n - 1), NULL, math_style_names);
- k = (scaled) lua_tonumber(L, n);
- def_math_param(i, j, k, l);
+ lua_number2int(k, lua_tonumber(L, n));
+ def_math_param(i, j, (scaled) k, l);
}
return 0;
}
@@ -973,59 +1270,59 @@ static int tex_getmathparm(lua_State * L)
static int getfontname(lua_State * L)
{
- return do_convert(L, convert_font_name_code);
+ return do_convert(L, font_name_code);
}
static int getfontidentifier(lua_State * L)
{
- return do_convert(L, convert_font_identifier_code);
+ return do_convert(L, font_identifier_code);
}
static int getpdffontname(lua_State * L)
{
- return do_convert(L, convert_pdf_font_name_code);
+ return do_convert(L, pdf_font_name_code);
}
static int getpdffontobjnum(lua_State * L)
{
- return do_convert(L, convert_pdf_font_objnum_code);
+ return do_convert(L, pdf_font_objnum_code);
}
static int getpdffontsize(lua_State * L)
{
- return do_convert(L, convert_pdf_font_size_code);
+ return do_convert(L, pdf_font_size_code);
}
static int getuniformdeviate(lua_State * L)
{
- return do_convert(L, convert_uniform_deviate_code);
+ return do_convert(L, uniform_deviate_code);
}
static int getnumber(lua_State * L)
{
- return do_convert(L, convert_number_code);
+ return do_convert(L, number_code);
}
static int getromannumeral(lua_State * L)
{
- return do_convert(L, convert_roman_numeral_code);
+ return do_convert(L, roman_numeral_code);
}
static int getpdfpageref(lua_State * L)
{
- return do_convert(L, convert_pdf_page_ref_code);
+ return do_convert(L, pdf_page_ref_code);
}
static int getpdfxformname(lua_State * L)
{
- return do_convert(L, convert_pdf_xform_name_code);
+ return do_convert(L, pdf_xform_name_code);
}
-static int get_parshape(lua_State * L)
+int get_parshape(lua_State * L)
{
int n;
- halfword par_shape_ptr = get_par_shape_ptr();
+ halfword par_shape_ptr = equiv(par_shape_loc);
if (par_shape_ptr != 0) {
int m = 1;
n = vinfo(par_shape_ptr + 1);
@@ -1046,7 +1343,7 @@ static int get_parshape(lua_State * L)
}
-static int gettex(lua_State * L)
+int gettex(lua_State * L)
{
int cur_cs = -1;
int retval = 1; /* default is to return nil */
@@ -1100,7 +1397,7 @@ static int gettex(lua_State * L)
}
-static int getlist(lua_State * L)
+int getlist(lua_State * L)
{
const char *str;
if (lua_isstring(L, 2)) {
@@ -1148,7 +1445,7 @@ static int getlist(lua_State * L)
return 1;
}
-static int setlist(lua_State * L)
+int setlist(lua_State * L)
{
halfword *n_ptr;
const char *str;
@@ -1156,9 +1453,9 @@ static int setlist(lua_State * L)
if (lua_isstring(L, 2)) {
str = lua_tostring(L, 2);
if (strcmp(str, "best_size") == 0) {
- best_size = lua_tointeger(L, 3);
+ best_size = (int) lua_tointeger(L, 3);
} else if (strcmp(str, "least_page_cost") == 0) {
- least_page_cost = lua_tointeger(L, 3);
+ least_page_cost = (int) lua_tointeger(L, 3);
} else {
if (!lua_isnil(L, 3)) {
n_ptr = check_isnode(L, 3);
@@ -1176,10 +1473,7 @@ static int setlist(lua_State * L)
} 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 */
+ contrib_tail = contrib_head;
}
} else if (strcmp(str, "best_page_break") == 0) {
best_page_break = n;
@@ -1204,11 +1498,142 @@ static int setlist(lua_State * L)
return 0;
}
-#define infinity 2147483647
+#define NEST_METATABLE "luatex.nest"
+
+static int lua_nest_getfield(lua_State * L)
+{
+ list_state_record *r, **rv = lua_touserdata(L, -2);
+ const char *field = lua_tostring(L, -1);
+ r = *rv;
+ if (strcmp(field, "mode") == 0) {
+ lua_pushnumber(L, r->mode_field);
+ } else if (strcmp(field, "head") == 0) {
+ lua_nodelib_push_fast(L, r->head_field);
+ } else if (strcmp(field, "tail") == 0) {
+ lua_nodelib_push_fast(L, r->tail_field);
+ } else if (strcmp(field, "delimptr") == 0) {
+ lua_pushnumber(L, r->eTeX_aux_field);
+ lua_nodelib_push(L);
+ } else if (strcmp(field, "prevgraf") == 0) {
+ lua_pushnumber(L, r->pg_field);
+ } else if (strcmp(field, "modeline") == 0) {
+ lua_pushnumber(L, r->ml_field);
+ } else if (strcmp(field, "prevdepth") == 0) {
+ lua_pushnumber(L, r->prev_depth_field);
+ } else if (strcmp(field, "spacefactor") == 0) {
+ lua_pushnumber(L, r->space_factor_field);
+ } else if (strcmp(field, "noad") == 0) {
+ lua_pushnumber(L, r->incompleat_noad_field);
+ lua_nodelib_push(L);
+ } else if (strcmp(field, "dirs") == 0) {
+ lua_pushnumber(L, r->dirs_field);
+ lua_nodelib_push(L);
+ } else if (strcmp(field, "mathdir") == 0) {
+ lua_pushboolean(L, r->math_field);
+ } else if (strcmp(field, "mathstyle") == 0) {
+ lua_pushnumber(L, r->math_style_field);
+ } else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
+static int lua_nest_setfield(lua_State * L)
+{
+ halfword *n;
+ int i;
+ list_state_record *r, **rv = lua_touserdata(L, -3);
+ const char *field = lua_tostring(L, -2);
+ r = *rv;
+ if (strcmp(field, "mode") == 0) {
+ lua_number2int(i, lua_tonumber(L, -1));
+ r->mode_field = i;
+ } else if (strcmp(field, "head") == 0) {
+ n = check_isnode(L, -1);
+ r->head_field = *n;
+ } else if (strcmp(field, "tail") == 0) {
+ n = check_isnode(L, -1);
+ r->tail_field = *n;
+ } else if (strcmp(field, "delimptr") == 0) {
+ n = check_isnode(L, -1);
+ r->eTeX_aux_field = *n;
+ } else if (strcmp(field, "prevgraf") == 0) {
+ lua_number2int(i, lua_tonumber(L, -1));
+ r->pg_field = i;
+ } else if (strcmp(field, "modeline") == 0) {
+ lua_number2int(i, lua_tonumber(L, -1));
+ r->ml_field = i;
+ } else if (strcmp(field, "prevdepth") == 0) {
+ lua_number2int(i, lua_tonumber(L, -1));
+ r->prev_depth_field = i;
+ } else if (strcmp(field, "spacefactor") == 0) {
+ lua_number2int(i, lua_tonumber(L, -1));
+ r->space_factor_field = i;
+ } else if (strcmp(field, "noad") == 0) {
+ n = check_isnode(L, -1);
+ r->incompleat_noad_field = *n;
+ } else if (strcmp(field, "dirs") == 0) {
+ n = check_isnode(L, -1);
+ r->dirs_field = *n;
+ } else if (strcmp(field, "mathdir") == 0) {
+ r->math_field = lua_toboolean(L, -1);
+ } else if (strcmp(field, "mathstyle") == 0) {
+ lua_number2int(i, lua_tonumber(L, -1));
+ r->math_style_field = i;
+ }
+ return 0;
+}
+
+static const struct luaL_reg nest_m[] = {
+ {"__index", lua_nest_getfield},
+ {"__newindex", lua_nest_setfield},
+ {NULL, NULL} /* sentinel */
+};
+
+static void init_nest_lib(lua_State * L)
+{
+ luaL_newmetatable(L, NEST_METATABLE);
+ luaL_register(L, NULL, nest_m);
+ lua_pop(L, 1);
+}
+
+static int getnest(lua_State * L)
+{
+ int ptr;
+ list_state_record **nestitem;
+ if (lua_isnumber(L, 2)) {
+ lua_number2int(ptr, lua_tonumber(L, 2));
+ if (ptr >= 0 && ptr <= nest_ptr) {
+ nestitem = lua_newuserdata(L, sizeof(list_state_record *));
+ *nestitem = &nest[ptr];
+ luaL_getmetatable(L, NEST_METATABLE);
+ lua_setmetatable(L, -2);
+ } else {
+ lua_pushnil(L);
+ }
+ } else if (lua_isstring(L, 2)) {
+ const char *s = lua_tostring(L, 2);
+ if (strcmp(s, "ptr") == 0) {
+ lua_pushnumber(L, nest_ptr);
+ } else {
+ lua_pushnil(L);
+ }
+ } else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
+static int setnest(lua_State * L)
+{
+ luaL_error(L, "You can't modify the semantic nest array directly");
+ return 2;
+}
static int do_integer_error(double m)
{
- const char *help[] = { "I can only go up to 2147483647='17777777777=" "7FFFFFFF,",
+ const char *help[] =
+ { "I can only go up to 2147483647='17777777777=" "7FFFFFFF,",
"so I'm using that number instead of yours.",
NULL
};
@@ -1219,7 +1644,7 @@ static int do_integer_error(double m)
static int tex_roundnumber(lua_State * L)
{
- double m = lua_tonumber(L, 1) + 0.5;
+ double m = (double) lua_tonumber(L, 1) + 0.5;
if (abs(m) > (double) infinity)
lua_pushnumber(L, do_integer_error(m));
else
@@ -1237,7 +1662,7 @@ static int tex_scaletable(lua_State * L)
lua_pushvalue(L, -2);
lua_insert(L, -2);
if (lua_isnumber(L, -1)) {
- double m = lua_tonumber(L, -1) * delta + 0.5;
+ double m = (double) lua_tonumber(L, -1) * delta + 0.5;
lua_pop(L, 1);
if (abs(m) > (double) infinity)
lua_pushnumber(L, do_integer_error(m));
@@ -1247,7 +1672,7 @@ static int tex_scaletable(lua_State * L)
lua_rawset(L, 3);
}
} else if (lua_isnumber(L, 1)) {
- double m = lua_tonumber(L, 1) * delta + 0.5;
+ double m = (double) lua_tonumber(L, 1) * delta + 0.5;
if (abs(m) > (double) infinity)
lua_pushnumber(L, do_integer_error(m));
else
@@ -1280,7 +1705,7 @@ static int tex_definefont(lua_State * L)
i = 2;
}
csname = luaL_checklstring(L, i, &l);
- f = luaL_checkinteger(L, (i + 1));
+ f = (int) luaL_checkinteger(L, (i + 1));
t = maketexlstring(csname, l);
no_new_control_sequence = 0;
u = string_lookup(csname, l);
@@ -1289,8 +1714,8 @@ static int tex_definefont(lua_State * L)
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;
+ eqtb[font_id_base + f] = eqtb[u];
+ hash_text(font_id_base + f) = t;
return 0;
}
@@ -1299,14 +1724,15 @@ 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);
+ char *ss = makecstring(s);
+ lua_pushstring(L, ss);
+ free(ss);
+ cmd = eq_type(cs);
+ chr = equiv(cs);
make_token_table(L, cmd, chr, cs);
lua_rawset(L, -3);
}
@@ -1324,7 +1750,9 @@ static int tex_primitives(lua_State * L)
while (cs < prim_size) {
s = get_prim_text(cs);
if (s > 0) {
- lua_pushstring(L, makecstring(s));
+ char *ss = makecstring(s);
+ lua_pushstring(L, ss);
+ free(ss);
cmd = get_prim_eq_type(cs);
chr = get_prim_equiv(cs);
make_token_table(L, cmd, chr, 0);
@@ -1373,7 +1801,9 @@ static int tex_extraprimitives(lua_State * L)
s = get_prim_text(cs);
if (s > 0) {
if (get_prim_origin(cs) & mask) {
- lua_pushstring(L, makecstring(s));
+ char *ss = makecstring(s);
+ lua_pushstring(L, ss);
+ free(ss);
lua_rawseti(L, -2, i++);
}
}
@@ -1386,8 +1816,7 @@ 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);
+ luaL_error(L, "wrong number of arguments");
} else {
size_t l;
int i;
@@ -1404,24 +1833,25 @@ static int tex_enableprimitives(lua_State * L)
halfword prim_val = prim_lookup(s);
if (prim_val != undefined_primitive) {
char *newprim;
- integer val;
+ int val;
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);
+ newprim = (char *) xmalloc((unsigned) (newl + 1));
strcpy(newprim, pre);
strcat(newprim + l, prim);
} else {
newl = strlen(prim);
- newprim = (char *) xmalloc(newl + 1);
+ newprim = (char *) xmalloc((unsigned) (newl + 1));
strcpy(newprim, prim);
}
val = string_lookup(newprim, newl);
- if (val == static_undefined_control_sequence ||
- zget_eq_type(val) == undefined_cs_cmd) {
- primitive_def(newprim, newl, cur_cmd, cur_chr);
+ if (val == undefined_control_sequence ||
+ eq_type(val) == undefined_cs_cmd) {
+ primitive_def(newprim, newl, (quarterword) cur_cmd,
+ cur_chr);
}
free(newprim);
}
@@ -1436,17 +1866,390 @@ static int tex_enableprimitives(lua_State * L)
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);
+ luaL_error(L, "Expected an array of names as second argument");
+ }
+ }
+ return 0;
+}
+
+#define get_int_par(A,B,C) do { \
+ lua_pushstring(L,(A)); \
+ lua_gettable(L,-2); \
+ if (lua_type(L, -1) == LUA_TNUMBER) { \
+ lua_number2int(B,lua_tonumber(L, -1)); \
+ } else { \
+ B = (C); \
+ } \
+ lua_pop(L,1); \
+ } while (0)
+
+
+#define get_intx_par(A,B,C,D,E) do { \
+ lua_pushstring(L,(A)); \
+ lua_gettable(L,-2); \
+ if (lua_type(L, -1) == LUA_TNUMBER) { \
+ lua_number2int(B,lua_tonumber(L, -1)); \
+ D = null; \
+ } else if (lua_type(L, -1) == LUA_TTABLE){ \
+ B = 0; \
+ D = nodelib_topenalties(L, lua_gettop(L)); \
+ } else { \
+ B = (C); \
+ D = (E); \
+ } \
+ lua_pop(L,1); \
+ } while (0)
+
+#define get_dimen_par(A,B,C) do { \
+ lua_pushstring(L,(A)); \
+ lua_gettable(L,-2); \
+ if (lua_type(L, -1) == LUA_TNUMBER) { \
+ lua_number2int(B,lua_tonumber(L, -1)); \
+ } else { \
+ B = (C); \
+ } \
+ lua_pop(L,1); \
+ } while (0)
+
+
+#define get_glue_par(A,B,C) do { \
+ lua_pushstring(L,(A)); \
+ lua_gettable(L,-2); \
+ if (lua_type(L, -1) != LUA_TNIL) { \
+ B = *check_isnode(L, -1); \
+ } else { \
+ B = (C); \
+ } \
+ lua_pop(L,1); \
+ } while (0)
+
+
+static halfword nodelib_toparshape(lua_State * L, int i)
+{
+ halfword p;
+ int n = 0;
+ int width, indent, j;
+ /* find |n| */
+ lua_pushnil(L);
+ while (lua_next(L, i) != 0) {
+ n++;
+ lua_pop(L, 1);
+ }
+ if (n == 0)
+ return null;
+ p = new_node(shape_node, 2 * (n + 1) + 1);
+ vinfo(p + 1) = n;
+ /* fill |p| */
+ lua_pushnil(L);
+ j = 0;
+ while (lua_next(L, i) != 0) {
+ /* don't give an error for non-tables, we may add special syntaxes at some point */
+ j++;
+ if (lua_type(L, i) == LUA_TTABLE) {
+ lua_rawgeti(L, -1, 1); /* indent */
+ if (lua_type(L, -1) == LUA_TNUMBER) {
+ lua_number2int(indent, lua_tonumber(L, -1));
+ lua_pop(L, 1);
+ lua_rawgeti(L, -1, 2); /* width */
+ if (lua_type(L, -1) == LUA_TNUMBER) {
+ lua_number2int(width, lua_tonumber(L, -1));
+ lua_pop(L, 1);
+ varmem[p + 2 * j].cint = indent;
+ varmem[p + 2 * j + 1].cint = width;
+ }
+ }
+ }
+ lua_pop(L, 1);
+ }
+ return p;
+}
+
+/* penalties */
+
+static halfword nodelib_topenalties(lua_State * L, int i)
+{
+ halfword p;
+ int n = 0;
+ int j;
+ /* find |n| */
+ lua_pushnil(L);
+ while (lua_next(L, i) != 0) {
+ n++;
+ lua_pop(L, 1);
+ }
+ if (n == 0)
+ return null;
+ p = new_node(shape_node, 2 * ((n / 2) + 1) + 1 + 1);
+ vinfo(p + 1) = (n / 2) + 1;
+ varmem[p + 2].cint = n;
+ lua_pushnil(L);
+ j = 2;
+ while (lua_next(L, i) != 0) {
+ j++;
+ if (lua_isnumber(L, -1)) {
+ int pen = 0;
+ lua_number2int(pen, lua_tonumber(L, -1));
+ varmem[p+j].cint = pen;
+ }
+ lua_pop(L, 1);
+ }
+ if (!odd(n))
+ varmem[p+j+1].cint = 0;
+ return p;
+}
+
+
+
+
+static int tex_run_linebreak(lua_State * L)
+{
+
+ halfword *j;
+ halfword p;
+ halfword final_par_glue;
+ int paragraph_dir = 0;
+ /* locally initialized parameters for line breaking */
+ int pretolerance, tracingparagraphs, tolerance, looseness, hyphenpenalty,
+ exhyphenpenalty, pdfadjustspacing, adjdemerits, pdfprotrudechars,
+ linepenalty, lastlinefit, doublehyphendemerits, finalhyphendemerits,
+ hangafter, interlinepenalty, widowpenalty, clubpenalty, brokenpenalty;
+ halfword emergencystretch, hangindent, hsize, leftskip, rightskip,
+ pdfeachlineheight, pdfeachlinedepth, pdffirstlineheight,
+ pdflastlinedepth, pdfignoreddimen, parshape;
+ int fewest_demerits = 0, actual_looseness = 0;
+ halfword clubpenalties, interlinepenalties, widowpenalties;
+
+ /* push a new nest level */
+ push_nest();
+ /* save_vlink_cur_head = vlink(cur_list.head_field); */
+
+ j = check_isnode(L, 1); /* the value */
+ vlink(temp_head) = *j;
+ p = *j;
+ if ((!is_char_node(vlink(*j)))
+ && ((type(vlink(*j)) == whatsit_node)
+ && (subtype(vlink(*j)) == local_par_node))) {
+ paragraph_dir = local_par_dir(vlink(*j));
+ }
+
+ while (vlink(p) != null)
+ p = vlink(p);
+ final_par_glue = p;
+
+ /* initialize local parameters */
+
+ if (lua_gettop(L) != 2 || lua_type(L, 2) != LUA_TTABLE) {
+ lua_checkstack(L, 3);
+ lua_newtable(L);
+ }
+ lua_pushstring(L, "pardir");
+ lua_gettable(L, -2);
+ if (lua_type(L, -1) == LUA_TSTRING) {
+ paragraph_dir = nodelib_getdir(L, -1);
+ }
+ lua_pop(L, 1);
+
+ lua_pushstring(L, "parshape");
+ lua_gettable(L, -2);
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ parshape = nodelib_toparshape(L, lua_gettop(L));
+ } else {
+ parshape = equiv(par_shape_loc);
+ }
+ lua_pop(L, 1);
+
+ get_int_par("pretolerance", pretolerance, int_par(pretolerance_code));
+ get_int_par("tracingparagraphs", tracingparagraphs,
+ int_par(tracing_paragraphs_code));
+ get_int_par("tolerance", tolerance, int_par(tolerance_code));
+ get_int_par("looseness", looseness, int_par(looseness_code));
+ get_int_par("hyphenpenalty", hyphenpenalty, int_par(hyphen_penalty_code));
+ get_int_par("exhyphenpenalty", exhyphenpenalty,
+ int_par(ex_hyphen_penalty_code));
+ get_int_par("pdfadjustspacing", pdfadjustspacing,
+ int_par(pdf_adjust_spacing_code));
+ get_int_par("adjdemerits", adjdemerits, int_par(adj_demerits_code));
+ get_int_par("pdfprotrudechars", pdfprotrudechars,
+ int_par(pdf_protrude_chars_code));
+ get_int_par("linepenalty", linepenalty, int_par(line_penalty_code));
+ get_int_par("lastlinefit", lastlinefit, int_par(last_line_fit_code));
+ get_int_par("doublehyphendemerits", doublehyphendemerits,
+ int_par(double_hyphen_demerits_code));
+ get_int_par("finalhyphendemerits", finalhyphendemerits,
+ int_par(final_hyphen_demerits_code));
+ get_int_par("hangafter", hangafter, int_par(hang_after_code));
+ get_intx_par("interlinepenalty", interlinepenalty,int_par(inter_line_penalty_code),
+ interlinepenalties, equiv(inter_line_penalties_loc));
+ get_intx_par("clubpenalty", clubpenalty, int_par(club_penalty_code),
+ clubpenalties, equiv(club_penalties_loc));
+ get_intx_par("widowpenalty", widowpenalty, int_par(widow_penalty_code),
+ widowpenalties, equiv(widow_penalties_loc));
+ get_int_par("brokenpenalty", brokenpenalty, int_par(broken_penalty_code));
+ get_dimen_par("emergencystretch", emergencystretch,
+ dimen_par(emergency_stretch_code));
+ get_dimen_par("hangindent", hangindent, dimen_par(hang_indent_code));
+ get_dimen_par("hsize", hsize, dimen_par(hsize_code));
+ get_glue_par("leftskip", leftskip, glue_par(left_skip_code));
+ get_glue_par("rightskip", rightskip, glue_par(right_skip_code));
+ get_dimen_par("pdfeachlineheight", pdfeachlineheight,
+ dimen_par(pdf_each_line_height_code));
+ get_dimen_par("pdfeachlinedepth", pdfeachlinedepth,
+ dimen_par(pdf_each_line_depth_code));
+ get_dimen_par("pdffirstlineheight", pdffirstlineheight,
+ dimen_par(pdf_first_line_height_code));
+ get_dimen_par("pdflastlinedepth", pdflastlinedepth,
+ dimen_par(pdf_last_line_depth_code));
+ get_dimen_par("pdfignoreddimen", pdfignoreddimen,
+ dimen_par(pdf_ignored_dimen_code));
+
+ ext_do_line_break(paragraph_dir,
+ pretolerance, tracingparagraphs, tolerance,
+ emergencystretch,
+ looseness, hyphenpenalty, exhyphenpenalty,
+ pdfadjustspacing,
+ parshape,
+ adjdemerits, pdfprotrudechars,
+ linepenalty, lastlinefit,
+ doublehyphendemerits, finalhyphendemerits,
+ hangindent, hsize, hangafter, leftskip, rightskip,
+ pdfeachlineheight, pdfeachlinedepth,
+ pdffirstlineheight, pdflastlinedepth,
+ interlinepenalties,
+ interlinepenalty, clubpenalty,
+ clubpenalties,
+ widowpenalties,
+ widowpenalty, brokenpenalty,
+ final_par_glue, pdfignoreddimen);
+
+ /* return the generated list, and its prevdepth */
+ get_linebreak_info (&fewest_demerits, &actual_looseness) ;
+ lua_nodelib_push_fast(L, vlink(cur_list.head_field));
+ lua_newtable(L);
+ lua_pushstring(L, "demerits");
+ lua_pushnumber(L, fewest_demerits);
+ lua_settable(L, -3);
+ lua_pushstring(L, "looseness");
+ lua_pushnumber(L, actual_looseness);
+ lua_settable(L, -3);
+ lua_pushstring(L, "prevdepth");
+ lua_pushnumber(L, cur_list.prev_depth_field);
+ lua_settable(L, -3);
+ lua_pushstring(L, "prevgraf");
+ lua_pushnumber(L, cur_list.pg_field);
+ lua_settable(L, -3);
+
+ /* restore nest stack */
+ pop_nest();
+ if (parshape != equiv(par_shape_loc))
+ flush_node(parshape);
+ return 2;
+}
+
+static int tex_shipout(lua_State * L)
+{
+ int boxnum = get_box_id(L, 1);
+ ship_out(static_pdf, box(boxnum), true);
+ box(boxnum) = null;
+ return 0;
+}
+
+static int tex_badness(lua_State * L)
+{
+ scaled t,s;
+ lua_number2int(t,lua_tonumber(L,1));
+ lua_number2int(s,lua_tonumber(L,2));
+ lua_pushnumber(L, badness(t,s));
+ return 1;
+}
+
+
+static int tex_run_boot(lua_State * L)
+{
+ int n = lua_gettop(L);
+ const char *format = NULL;
+ if (n >= 1) {
+ ini_version = 0;
+ format = luaL_checkstring(L, 1);
+ } else {
+ ini_version = 1;
+ }
+ if (main_initialize()) { /* > 0 = failure */
+ lua_pushboolean(L, 0); /* false */
+ return 1;
+ }
+ if (format) {
+ if (!zopen_w_input(&fmt_file, format, DUMP_FORMAT, FOPEN_RBIN_MODE)) {
+ lua_pushboolean(L, 0); /* false */
+ return 1;
}
+ if (!load_fmt_file(format)) {
+ zwclose(fmt_file);
+ lua_pushboolean(L, 0); /* false */
+ return 1;
+ }
+ zwclose(fmt_file);
}
+ fix_date_and_time();
+ if (format == NULL)
+ make_pdftex_banner();
+ random_seed = (microseconds * 1000) + (epochseconds % 1000000);
+ init_randoms(random_seed);
+ initialize_math();
+ fixup_selector(log_opened);
+ check_texconfig_init();
+ text_dir_ptr = new_dir(0);
+ history = spotless; /* ready to go! */
+ /* Initialize synctex primitive */
+ synctexinitcommand();
+ /* tex is ready to go, now */
+ 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);
+
+ lua_pushboolean(L, 1); /* true */
+ return 1;
+
+}
+
+static int tex_run_main(lua_State * L)
+{
+ (void) L;
+ main_control();
return 0;
}
+static int tex_run_end(lua_State * L)
+{
+ (void) L;
+ final_cleanup(); /* prepare for death */
+ close_files_and_terminate();
+ do_final_end();
+ return 0;
+}
+
+void init_tex_table(lua_State * L)
+{
+ lua_createtable(L, 0, 3);
+ lua_pushcfunction(L, tex_run_boot);
+ lua_setfield(L, -2, "initialize");
+ lua_pushcfunction(L, tex_run_main);
+ lua_setfield(L, -2, "run");
+ lua_pushcfunction(L, tex_run_end);
+ lua_setfield(L, -2, "finish");
+ lua_setglobal(L, "tex");
+}
+
+
+
static const struct luaL_reg texlib[] = {
+ {"run", tex_run_main}, /* may be needed */
+ {"finish", tex_run_end}, /* may be needed */
+ {"write", luacwrite},
{"write", luacwrite},
{"print", luacprint},
+ {"tprint", luactprint},
{"sprint", luacsprint},
{"set", settex},
{"get", gettex},
@@ -1470,8 +2273,11 @@ static const struct luaL_reg texlib[] = {
{"getboxht", getboxht},
{"setboxdp", setboxdp},
{"getboxdp", getboxdp},
+ {"setnest", setnest},
+ {"getnest", getnest},
{"round", tex_roundnumber},
{"scale", tex_scaletable},
+ {"sp", tex_scaledimen},
{"fontname", getfontname},
{"fontidentifier", getfontidentifier},
{"pdffontname", getpdffontname},
@@ -1487,8 +2293,11 @@ static const struct luaL_reg texlib[] = {
{"primitives", tex_primitives},
{"extraprimitives", tex_extraprimitives},
{"enableprimitives", tex_enableprimitives},
+ {"shipout", tex_shipout},
+ {"badness", tex_badness},
{"setmath", tex_setmathparm},
{"getmath", tex_getmathparm},
+ {"linebreak", tex_run_linebreak},
{NULL, NULL} /* sentinel */
};
@@ -1506,7 +2315,9 @@ int luaopen_tex(lua_State * L)
make_table(L, "ht", "getboxht", "setboxht");
make_table(L, "dp", "getboxdp", "setboxdp");
make_table(L, "lists", "getlist", "setlist");
+ make_table(L, "nest", "getnest", "setnest");
/* *INDENT-ON* */
+ init_nest_lib(L);
/* make the meta entries */
/* fetch it back */
luaL_newmetatable(L, "tex_meta");
@@ -1525,6 +2336,5 @@ int luaopen_tex(lua_State * L)
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 1ba1e609aef..02e6d84dff6 100644
--- a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c
+++ b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c
@@ -17,17 +17,11 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "tokens.h"
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: ltokenlib.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/ltokenlib.c $";
-
-static int max_command = 0;
-static int null_cs = 0;
-
-#define protected_token 0x1C00001
+ "$Id: ltokenlib.c 3404 2010-01-28 11:17:10Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/ltokenlib.c $";
#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)
@@ -36,17 +30,28 @@ static int null_cs = 0;
#define is_active_string(s) (strlen((char *)s)>3 && *s==0xEF && *(s+1)==0xBF && *(s+2)==0xBF)
+static unsigned char *get_cs_text(int cs)
+{
+ if (cs == null_cs)
+ return (unsigned char *) xstrdup("\\csname\\endcsname");
+ else if ((cs_text(cs) < 0) || (cs_text(cs) >= str_ptr))
+ return (unsigned char *) xstrdup("");
+ else
+ return (unsigned char *) makecstring(cs_text(cs));
+}
+
+
static int test_expandable(lua_State * L)
{
- integer cmd = -1;
+ int cmd = -1;
if (is_valid_token(L, -1)) {
get_token_cmd(L, -1);
if (lua_isnumber(L, -1)) {
- cmd = lua_tointeger(L, -1);
+ cmd = (int) lua_tointeger(L, -1);
} else if (lua_isstring(L, -1)) {
cmd = get_command_id(lua_tostring(L, -1));
}
- if (cmd > max_command) {
+ if (cmd > max_command_cmd) {
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
@@ -60,15 +65,15 @@ static int test_expandable(lua_State * L)
static int test_protected(lua_State * L)
{
- integer chr = -1;
+ int chr = -1;
if (is_valid_token(L, -1)) {
get_token_chr(L, -1);
if (lua_isnumber(L, -1)) {
- chr = lua_tointeger(L, -1);
+ chr = (int) lua_tointeger(L, -1);
} else if (lua_isstring(L, -1)) {
chr = get_command_id(lua_tostring(L, -1));
}
- if (fixmem[fixmem[chr].hhrh].hhlh == protected_token) {
+ if (token_info(token_link(chr)) == protected_token) {
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
@@ -82,15 +87,14 @@ static int test_protected(lua_State * L)
static int test_activechar(lua_State * L)
{
if (is_valid_token(L, -1)) {
- str_number n;
- integer cs = 0;
+ unsigned char *s;
+ int cs = 0;
get_token_cs(L, -1);
if (lua_isnumber(L, -1)) {
- cs = lua_tointeger(L, -1);
+ cs = (int) 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 (cs != 0 && ((s = get_cs_text(cs)) != (unsigned char *) NULL)) {
if (is_active_string(s)) {
free(s);
lua_pushboolean(L, 1);
@@ -110,7 +114,7 @@ static int run_get_command_name(lua_State * L)
if (is_valid_token(L, -1)) {
get_token_cmd(L, -1);
if (lua_isnumber(L, -1)) {
- cs = lua_tointeger(L, -1);
+ cs = (int) lua_tointeger(L, -1);
lua_pushstring(L, command_names[cs].cmd_name);
} else {
lua_pushstring(L, "");
@@ -124,23 +128,22 @@ static int run_get_command_name(lua_State * L)
static int run_get_csname_name(lua_State * L)
{
- int cs, cmd, n;
-
+ int cs, cmd;
+ unsigned char *s;
if (is_valid_token(L, -1)) {
get_token_cmd(L, -1);
if (lua_isnumber(L, -1)) {
- cmd = lua_tointeger(L, -1);
+ cmd = (int) 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);
+ cs = (int) 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 (cs != 0 && ((s = get_cs_text(cs)) != (unsigned char *) NULL)) {
if (is_active_string(s))
lua_pushstring(L, (char *) (s + 3));
else
@@ -171,9 +174,9 @@ static int run_get_csname_id(lua_State * L)
size_t k, cs = 0;
if (lua_isstring(L, -1)) {
s = lua_tolstring(L, -1, &k);
- cs = string_lookup(s, k);
+ cs = (size_t) string_lookup(s, k);
}
- lua_pushnumber(L, cs);
+ lua_pushnumber(L, (lua_Number) cs);
return 1;
}
@@ -212,17 +215,17 @@ static int run_lookup(lua_State * L)
{
const char *s;
size_t l;
- integer cs, cmd, chr;
+ int cs, cmd, chr;
int save_nncs;
if (lua_isstring(L, -1)) {
s = 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 = id_lookup((last + 1), (int) l); /* cleans up the lookup buffer */
cs = string_lookup(s, l);
- cmd = zget_eq_type(cs);
- chr = zget_equiv(cs);
+ cmd = eq_type(cs);
+ chr = equiv(cs);
make_token_table(L, cmd, chr, cs);
no_new_control_sequence = save_nncs;
return 1;
@@ -234,11 +237,11 @@ static int run_lookup(lua_State * L)
static int run_build(lua_State * L)
{
- integer cmd, chr, cs;
+ int 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));
+ chr = (int) lua_tointeger(L, 1);
+ cmd = (int) 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)",
@@ -248,8 +251,8 @@ static int run_build(lua_State * L)
}
if (cmd == 13) {
cs = active_to_cs(chr, false);
- cmd = zget_eq_type(cs);
- chr = zget_equiv(cs);
+ cmd = eq_type(cs);
+ chr = equiv(cs);
}
make_token_table(L, cmd, chr, cs);
return 1;
@@ -277,7 +280,5 @@ static const struct luaL_reg tokenlib[] = {
int luaopen_token(lua_State * L)
{
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/luagen.h b/Build/source/texk/web2c/luatexdir/lua/luagen.h
new file mode 100644
index 00000000000..9ab2e8e8c2f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/luagen.h
@@ -0,0 +1,27 @@
+/* luagen.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: luagen.h 3261 2009-12-18 11:38:21Z taco $ */
+
+extern void lua_begin_page(PDF pdf);
+extern void lua_end_page(PDF pdf);
+
+extern void lua_place_glyph(PDF pdf, internal_font_number f, int c);
+extern void lua_place_rule(PDF pdf, scaledpos size);
+extern void finish_lua_file(PDF pdf);
diff --git a/Build/source/texk/web2c/luatexdir/lua/luagen.w b/Build/source/texk/web2c/luatexdir/lua/luagen.w
new file mode 100644
index 00000000000..292176575c0
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/luagen.w
@@ -0,0 +1,55 @@
+% luagen.w
+%
+% Copyright 2009 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: luagen.w 3583 2010-04-02 17:40:44Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luagen.w $";
+
+#include "ptexlib.h"
+#include "pdf/pdfpage.h"
+
+@ @c
+void lua_begin_page(PDF pdf)
+{
+ (void) pdf;
+}
+
+void lua_end_page(PDF pdf)
+{
+ (void) pdf;
+}
+
+void lua_place_glyph(PDF pdf, internal_font_number f, int c)
+{
+ (void) pdf;
+ (void) f;
+ printf("%c", (int) c);
+}
+
+void lua_place_rule(PDF pdf, scaledpos size)
+{
+ (void) pdf;
+ (void) size;
+}
+
+void finish_lua_file(PDF pdf)
+{
+ (void) pdf;
+}
diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.c b/Build/source/texk/web2c/luatexdir/lua/luainit.w
index 917cf462f7e..cd8c8872a7f 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luainit.c
+++ b/Build/source/texk/web2c/luatexdir/lua/luainit.w
@@ -1,49 +1,55 @@
-/* luainit.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% luainit.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include <sys/stat.h>
-
-#include "luatex-api.h"
-#include <ptexlib.h>
+@ @c
+#include "openbsd-compat.h"
+#ifdef HAVE_ASPRINTF /* asprintf is not defined in openbsd-compat.h, but in stdio.h */
+# include <stdio.h>
+#endif
+#include <kpathsea/c-stat.h>
-#include <luatexdir/luatexextra.h>
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: luainit.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/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
- *
- */
+ "$Id: luainit.w 3583 2010-04-02 17:40:44Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luainit.w $";
+
+@
+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
+@c
const_string LUATEX_IHELP[] = {
"Usage: luatex --lua=FILE [OPTION]... [TEXNAME[.tex]] [COMMANDS]",
" or: luatex --lua=FILE [OPTION]... \\FIRST-LINE",
@@ -60,22 +66,52 @@ const_string LUATEX_IHELP[] = {
"",
" If no arguments or options are specified, prompt for input.",
"",
- " --lua=FILE the lua initialization file",
- " --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",
- " --version output version information and exit",
+ " The following regular options are understood: ",
"",
- " Alternate behaviour models can be obtained by special switches",
+ " --8bit ignored, input is assumed to be in UTF-8 encoding",
+ " --credits display credits and exit",
+ " --debug-format enable format debugging",
+ " --default-translate-file= ignored, input is assumed to be in UTF-8 encoding",
+ " --disable-write18 disable \\write18{SHELL COMMAND}",
+ " --draftmode switch on draft mode (generates no output PDF)",
+ " --enable-write18 enable \\write18{SHELL COMMAND}",
+ " --etex ignored, the etex extensions are always active",
+ " --[no-]file-line-error disable/enable file:line:error style messages",
+ " --[no-]file-line-error-style aliases of --[no-]file-line-error",
+ " --fmt=FORMAT load the format file FORMAT",
+ " --halt-on-error stop processing at the first error",
+ " --help display help and exit",
+ " --ini be iniluatex, for dumping formats",
+ " --interaction=STRING set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)",
+ " --jobname=STRING set the job name to STRING",
+ " --kpathsea-debug=NUMBER set path searching debugging flags according to the bits of NUMBER",
+ " --lua=s load and execute a lua initialization script",
+ " --[no-]mktex=FMT disable/enable mktexFMT generation (FMT=tex/tfm)",
+ " --nosocket disable the lua socket library",
+ " --output-comment=STRING use STRING for DVI file comment instead of date (no effect for PDF)",
+ " --output-directory=DIR use DIR as the directory to write files to",
+ " --output-format=FORMAT use FORMAT for job output; FORMAT is 'dvi' or 'pdf'",
+ " --[no-]parse-first-line disable/enable parsing of the first line of the input file",
+ " --progname=STRING set the program name to STRING",
+ " --recorder enable filename recorder",
+ " --safer disable easily exploitable lua commands",
+ " --[no-]shell-escape disable/enable \\write18{SHELL COMMAND}",
+ " --shell-restricted restrict \\write18 to a list of commands given in texmf.cnf",
+ " --synctex=NUMBER enable synctex",
+ " --translate-file= ignored, input is assumed to be in UTF-8 encoding",
+ " --version display version and exit",
+ "",
+ "Alternate behaviour models can be obtained by special switches",
"",
" --luaonly run a lua file, then exit",
" --luaconly byte-compile a lua file, then exit",
+ "",
+ "See the reference manual for more information about the startup process.",
NULL
};
-static char *ex_selfdir(char *argv0)
+@ @c
+char *ex_selfdir(char *argv0)
{
#if defined(WIN32)
char short_path[PATH_MAX], path[PATH_MAX], *fp;
@@ -83,9 +119,6 @@ static char *ex_selfdir(char *argv0)
/* 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))
@@ -97,6 +130,7 @@ static char *ex_selfdir(char *argv0)
#endif
}
+@ @c
static void
prepare_cmdline(lua_State * L, char **argv, int argc, int zero_offset)
{
@@ -117,22 +151,25 @@ prepare_cmdline(lua_State * L, char **argv, int argc, int zero_offset)
return;
}
-const_string input_name = NULL;
+@ @c
+string input_name = NULL;
-static const_string user_progname = NULL;
+static string user_progname = NULL;
-const char *startup_filename = NULL;
+char *startup_filename = NULL;
int lua_only = 0;
int lua_offset = 0;
int safer_option = 0;
int nosocket_option = 0;
-/* Reading the options. */
+@ Reading the options.
+
+@ Test whether getopt found an option ``A''.
+Assumes the option index is in the variable |option_index|, and the
+option table in a variable |long_options|.
-/* Test whether getopt found an option ``A''.
- Assumes the option index is in the variable `option_index', and the
- option table in a variable `long_options'. */
+@c
#define ARGUMENT_IS(a) STREQ (long_options[option_index].name, a)
/* SunOS cc can't initialize automatic structs, so make this static. */
@@ -158,8 +195,6 @@ static struct option long_options[]
{"output-format", 1, 0, 0},
{"shell-escape", 0, &shellenabledp, 1},
{"no-shell-escape", 0, &shellenabledp, -1},
-{"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},
@@ -182,6 +217,7 @@ static struct option long_options[]
{0, 0, 0, 0}
};
+@ @c
static void parse_options(int argc, char **argv)
{
int g; /* `getopt' return code. */
@@ -223,12 +259,12 @@ static void parse_options(int argc, char **argv)
output_directory = optarg;
} else if (ARGUMENT_IS("output-comment")) {
- unsigned len = strlen(optarg);
+ size_t len = strlen(optarg);
if (len < 256) {
output_comment = optarg;
} else {
WARNING2("Comment truncated to 255 characters from %d. (%s)",
- len, optarg);
+ (int) len, optarg);
output_comment = (string) xmalloc(256);
strncpy(output_comment, optarg, 255);
output_comment[255] = 0;
@@ -261,7 +297,7 @@ static void parse_options(int argc, char **argv)
kpse_maketex_option(optarg, false);
} else if (ARGUMENT_IS("interaction")) {
- /* These numbers match @d's in *.ch */
+ /* These numbers match CPP defines */
if (STREQ(optarg, "batchmode")) {
interactionoption = 0;
} else if (STREQ(optarg, "nonstopmode")) {
@@ -320,7 +356,7 @@ static void parse_options(int argc, char **argv)
uexit(0);
}
}
- /* attempt to find dump_name */
+ /* attempt to find |dump_name| */
if (argv[optind] && argv[optind][0] == '&') {
dump_name = strdup(argv[optind] + 1);
} else if (argv[optind] && argv[optind][0] != '\\') {
@@ -366,11 +402,13 @@ static void parse_options(int argc, char **argv)
}
}
-/* test for readability */
+@ test for readability
+@c
#define is_readable(a) (stat(a,&finfo)==0) && S_ISREG(finfo.st_mode) && \
(f=fopen(a,"r")) != NULL && !fclose(f)
-static const char *find_filename(const char *name, const char *envkey)
+@ @c
+static char *find_filename(char *name, const char *envkey)
{
struct stat finfo;
char *dirname = NULL;
@@ -385,7 +423,7 @@ static const char *find_filename(const char *name, const char *envkey)
if (*(dirname + strlen(dirname) - 1) == '/') {
*(dirname + strlen(dirname) - 1) = 0;
}
- filename = xmalloc(strlen(dirname) + strlen(name) + 2);
+ filename = xmalloc((unsigned) (strlen(dirname) + strlen(name) + 2));
filename = concat3(dirname, "/", name);
if (is_readable(filename)) {
xfree(dirname);
@@ -398,7 +436,8 @@ static const char *find_filename(const char *name, const char *envkey)
}
-static char *cleaned_invocation_name(char *arg)
+@ @c
+char *cleaned_invocation_name(char *arg)
{
char *ret, *dot;
const char *start = xbasename(arg);
@@ -410,7 +449,8 @@ static char *cleaned_invocation_name(char *arg)
return ret;
}
-static void init_kpse(void)
+@ @c
+void init_kpse(void)
{
if (!user_progname) {
@@ -439,34 +479,249 @@ static void init_kpse(void)
program_name_set = 1;
}
-static void fix_dumpname(void)
+@ @c
+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);
+ dist = (int) (strlen(dump_name) - strlen(DUMP_EXT));
if (strstr(dump_name, DUMP_EXT) == dump_name + dist)
- DUMP_VAR = concat(" ", dump_name);
+ TEX_format_default = dump_name;
else
- DUMP_VAR = concat3(" ", dump_name, DUMP_EXT);
- DUMP_LENGTH_VAR = strlen(DUMP_VAR + 1);
+ TEX_format_default = concat(dump_name, DUMP_EXT);
} else {
- /* For dump_name to be NULL is a bug. */
+ /* For |dump_name| to be NULL is a bug. */
if (!ini_version)
abort();
}
}
+@ lua require patch
+
+@ Auxiliary function for kpse search
+
+@c
+static const char *luatex_kpse_find_aux(lua_State *L, const char *name,
+ kpse_file_format_type format, const char *errname)
+{
+ const char *filename;
+ const char *altname;
+ altname = luaL_gsub(L, name, ".", "/"); /* Lua convention */
+ filename = kpse_find_file(altname, format, false);
+ if (filename == NULL) {
+ filename = kpse_find_file(name, format, false);
+ }
+ if (filename == NULL) {
+ lua_pushfstring(L, "\n\t[kpse %s searcher] file not found: " LUA_QS,
+ errname, name);
+ }
+ return filename;
+}
+
+@ The lua search function.
+
+When kpathsea is not initialized, then it runs the
+normal lua function that is saved in the registry, otherwise
+it uses kpathsea.
+
+two registry ref variables are needed: one for the actual lua
+function, the other for its environment .
+
+@c
+static int lua_loader_function = 0;
+static int lua_loader_env = 0;
+
+static int luatex_kpse_lua_find(lua_State * L)
+{
+ const char *filename;
+ const char *name;
+ name = luaL_checkstring(L, 1);
+ if (program_name_set == 0) {
+ lua_CFunction orig_func;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, lua_loader_function);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, lua_loader_env);
+ lua_replace(L, LUA_ENVIRONINDEX);
+ orig_func = lua_tocfunction(L, -1);
+ lua_pop(L, 1);
+ return (orig_func) (L);
+ }
+ filename = luatex_kpse_find_aux(L, name, kpse_lua_format, "lua");
+ if (filename == NULL)
+ return 1; /* library not found in this path */
+ if (luaL_loadfile(L, filename) != 0) {
+ luaL_error(L, "error loading module %s from file %s:\n\t%s",
+ lua_tostring(L, 1), filename, lua_tostring(L, -1));
+ }
+ return 1; /* library loaded successfully */
+}
+
+@ @c
+static int clua_loader_function = 0;
+static int clua_loader_env = 0;
+
+static int luatex_kpse_clua_find(lua_State * L)
+{
+ const char *filename;
+ const char *name;
+ if (safer_option) {
+ lua_pushliteral(L, "\n\t[C searcher disabled in safer mode]");
+ return 1; /* library not found in this path */
+ }
+ name = luaL_checkstring(L, 1);
+ if (program_name_set == 0) {
+ lua_CFunction orig_func;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loader_function);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loader_env);
+ lua_replace(L, LUA_ENVIRONINDEX);
+ orig_func = lua_tocfunction(L, -1);
+ lua_pop(L, 1);
+ return (orig_func) (L);
+ }
+ filename = luatex_kpse_find_aux(L, name, kpse_clua_format, "C");
+ if (filename == NULL)
+ return 1; /* library not found in this path */
+ return loader_C_luatex(L, name, filename);
+}
+
+@ @c
+static int clua_loadall_function = 0;
+static int clua_loadall_env = 0;
+
+static int luatex_kpse_cluaall_find(lua_State * L)
+{
+ const char *filename;
+ const char *name;
+ char *fixedname;
+ const char *p = NULL;
+ if (safer_option) {
+ lua_pushliteral(L, "\n\t[All-in-one searcher disabled in safer mode]");
+ return 1; /* library not found in this path */
+ }
+ name = luaL_checkstring(L, 1);
+ p = strchr(name, '.');
+ if (program_name_set == 0) {
+ lua_CFunction orig_func;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loadall_function);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, clua_loadall_env);
+ lua_replace(L, LUA_ENVIRONINDEX);
+ orig_func = lua_tocfunction(L, -1);
+ lua_pop(L, 1);
+ return (orig_func) (L);
+ }
+ if (p == NULL) return 0; /* is root */
+ fixedname = xmalloc((size_t)(p - name)+1);
+ memcpy(fixedname,name,(size_t)(p - name));
+ fixedname[(p - name)] = '\0';
+ filename = luatex_kpse_find_aux(L, fixedname, kpse_clua_format, "All-in-one");
+ free(fixedname);
+ if (filename == NULL)
+ return 1; /* library not found in this path */
+ return loader_Call_luatex(L, name, filename);
+}
+
+@ Setting up the new search functions.
+
+ This replaces package.loaders[2] with the function defined above.
+
+@c
+static void setup_lua_path(lua_State * L)
+{
+ lua_getglobal(L, "package");
+ lua_getfield(L, -1, "loaders");
+ lua_rawgeti(L, -1, 2); /* package.loaders[2] */
+ lua_getfenv(L, -1);
+ lua_loader_env = luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_loader_function = luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_pushcfunction(L, luatex_kpse_lua_find);
+ lua_rawseti(L, -2, 2); /* replace the normal lua loader */
+
+ lua_rawgeti(L, -1, 3); /* package.loaders[3] */
+ lua_getfenv(L, -1);
+ clua_loader_env = luaL_ref(L, LUA_REGISTRYINDEX);
+ clua_loader_function = luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_pushcfunction(L, luatex_kpse_clua_find);
+ lua_rawseti(L, -2, 3); /* replace the normal lua lib loader */
+
+ lua_rawgeti(L, -1, 4); /* package.loaders[4] */
+ lua_getfenv(L, -1);
+ clua_loadall_env = luaL_ref(L, LUA_REGISTRYINDEX);
+ clua_loadall_function = luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_pushcfunction(L, luatex_kpse_cluaall_find);
+ lua_rawseti(L, -2, 4); /* replace the normal lua lib loader */
+
+ lua_pop(L, 2); /* pop the array and table */
+}
+
+@ helper variables for the safe keeping of table ids
+
+@c
+int tex_table_id;
+int pdf_table_id;
+int token_table_id;
+int node_table_id;
+
+
+#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
+char **suffixlist;
+
+# define EXE_SUFFIXES ".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.ws;.tcl;.py;.pyw"
+
+@ @c
+static void mk_suffixlist(void)
+{
+ char **p;
+ char *q, *r, *v;
+ int n;
+
+# if defined(__CYGWIN__)
+ v = xstrdup(EXE_SUFFIXES);
+# else
+ v = (char *) getenv("PATHEXT");
+ if (v) /* strlwr() exists also in MingW */
+ v = (char *) strlwr(xstrdup(v));
+ else
+ v = xstrdup(EXE_SUFFIXES);
+# endif
+
+ q = v;
+ n = 0;
+
+ while ((r = strchr(q, ';')) != NULL) {
+ n++;
+ r++;
+ q = r;
+ }
+ if (*q)
+ n++;
+ suffixlist = (char **) xmalloc((n + 2) * sizeof(char *));
+ p = suffixlist;
+ *p = xstrdup(".dll");
+ p++;
+ q = v;
+ while ((r = strchr(q, ';')) != NULL) {
+ *r = '\0';
+ *p = xstrdup(q);
+ p++;
+ r++;
+ q = r;
+ }
+ if (*q) {
+ *p = xstrdup(q);
+ p++;
+ }
+ *p = NULL;
+ free(v);
+}
+#endif
+
+@ @c
void lua_initialize(int ac, char **av)
{
char *given_file = NULL;
+ char *banner;
int kpse_init;
- int tex_table_id;
- int pdf_table_id;
- int token_table_id;
- int node_table_id;
- /* Non-const initialized variables for putenv(). */
static char LC_CTYPE_C[] = "LC_CTYPE=C";
static char LC_COLLATE_C[] = "LC_COLLATE=C";
static char LC_NUMERIC_C[] = "LC_NUMERIC=C";
@@ -475,7 +730,18 @@ void lua_initialize(int ac, char **av)
argc = ac;
argv = av;
- ptexbanner = BANNER;
+ if (luatex_svn < 0) {
+ if (asprintf(&banner, "This is LuaTeX, Version %s-%d",
+ luatex_version_string, luatex_date_info) < 0) {
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ if (asprintf(&banner, "This is LuaTeX, Version %s-%d (rev %d)",
+ luatex_version_string, luatex_date_info, luatex_svn) < 0) {
+ exit(EXIT_FAILURE);
+ }
+ }
+ ptexbanner = banner;
program_invocation_name = cleaned_invocation_name(argv[0]);
@@ -485,16 +751,19 @@ void lua_initialize(int ac, char **av)
STREQ(argv[1], "--luaconly") || STREQ(argv[1], "--luac"))) {
exit(luac_main(ac, av));
}
+#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
+ mk_suffixlist();
+#endif
/* Must be initialized before options are parsed. */
interactionoption = 4;
dump_name = NULL;
/* 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. */
+ 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;
@@ -504,6 +773,7 @@ void lua_initialize(int ac, char **av)
shellenabledp = true;
/* make sure that the locale is 'sane' (for lua) */
+
putenv(LC_CTYPE_C);
putenv(LC_COLLATE_C);
putenv(LC_NUMERIC_C);
@@ -514,6 +784,7 @@ void lua_initialize(int ac, char **av)
luainterpreter();
prepare_cmdline(Luas, argv, argc, lua_offset); /* collect arguments */
+ setup_lua_path(Luas);
if (startup_filename != NULL) {
given_file = xstrdup(startup_filename);
@@ -521,7 +792,7 @@ void lua_initialize(int ac, char **av)
}
/* now run the file */
if (startup_filename != NULL) {
- const char *v1;
+ char *v1;
/* hide the 'tex' and 'pdf' table */
tex_table_id = hide_lua_table(Luas, "tex");
token_table_id = hide_lua_table(Luas, "token");
@@ -532,6 +803,8 @@ void lua_initialize(int ac, char **av)
fprintf(stdout, "%s\n", lua_tostring(Luas, -1));
exit(1);
}
+ /* */
+ init_tex_table(Luas);
if (lua_pcall(Luas, 0, 0, 0)) {
fprintf(stdout, "%s\n", lua_tostring(Luas, -1));
exit(1);
@@ -556,7 +829,7 @@ void lua_initialize(int ac, char **av)
unhide_lua_table(Luas, "token", token_table_id);
unhide_lua_table(Luas, "node", node_table_id);
- /* kpse_init */
+ /* |kpse_init| */
kpse_init = -1;
get_lua_boolean("texconfig", "kpse_init", &kpse_init);
@@ -564,19 +837,19 @@ void lua_initialize(int ac, char **av)
luainit = 0; /* re-enable loading of texmf.cnf values, see luatex.ch */
init_kpse();
}
- /* prohibit_file_trace (boolean) */
+ /* |prohibit_file_trace| (boolean) */
tracefilenames = 1;
get_lua_boolean("texconfig", "trace_file_names", &tracefilenames);
- /* file_line_error */
+ /* |file_line_error| */
filelineerrorstylep = false;
get_lua_boolean("texconfig", "file_line_error", &filelineerrorstylep);
- /* halt_on_error */
+ /* |halt_on_error| */
haltonerrorp = false;
get_lua_boolean("texconfig", "halt_on_error", &haltonerrorp);
- /* restrictedshell */
+ /* |restrictedshell| */
v1 = NULL;
get_lua_string("texconfig", "shell_escape", &v1);
if (v1) {
@@ -617,6 +890,7 @@ void lua_initialize(int ac, char **av)
}
}
+@ @c
void check_texconfig_init(void)
{
if (Luas != NULL) {
@@ -636,7 +910,8 @@ void check_texconfig_init(void)
}
}
-void write_svnversion(const char *v)
+@ @c
+void write_svnversion(char *v)
{
char *a_head, *n;
char *a = strdup(v);
diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.c b/Build/source/texk/web2c/luatexdir/lua/luanode.w
index a9daa106920..81e6b4fa74e 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luanode.c
+++ b/Build/source/texk/web2c/luatexdir/lua/luanode.w
@@ -1,33 +1,32 @@
-/* luanode.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% luanode.w
+%
+% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "nodes.h"
+@ @c
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
-static const char _svn_version[] =
- "$Id: luanode.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/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 const char _svn_version[] =
+ "$Id: luanode.w 3583 2010-04-02 17:40:44Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luanode.w $";
+@ @c
static const char *group_code_names[] = {
"",
"simple",
@@ -54,9 +53,10 @@ static const char *group_code_names[] = {
"fin_row"
};
-static const char *pack_type_name[] = { "exactly", "additional" };
+const char *pack_type_name[] = { "exactly", "additional" };
+@ @c
void lua_node_filter_s(int filterid, const char *extrainfo)
{
lua_State *L = Luas;
@@ -79,6 +79,7 @@ void lua_node_filter_s(int filterid, const char *extrainfo)
return;
}
+@ @c
void
lua_node_filter(int filterid, int xextrainfo, halfword head_node,
halfword * tail_node)
@@ -126,6 +127,7 @@ lua_node_filter(int filterid, int xextrainfo, halfword head_node,
}
+@ @c
int
lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
{
@@ -161,8 +163,10 @@ lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head)
+@ @c
halfword
-lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo)
+lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo,
+ int pack_direction)
{
halfword ret;
lua_State *L = Luas;
@@ -177,7 +181,11 @@ lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo)
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 */
+ if (pack_direction >= 0)
+ lua_pushstring(L, string_dir(pack_direction));
+ else
+ lua_pushnil(L);
+ 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();
@@ -193,18 +201,21 @@ lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo)
ret = nodelist_from_lua(L);
}
lua_pop(L, 2); /* result and callback container table */
- /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); */
+#if 0
+ lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
+#endif
if (fix_node_lists)
fix_node_list(ret);
return ret;
}
+@ @c
halfword
lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
- int extrainfo)
+ int extrainfo, int pack_direction)
{
halfword ret;
- integer callback_id;
+ int callback_id;
lua_State *L = Luas;
if (head_node == null)
return head_node;
@@ -225,7 +236,11 @@ lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
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 */
+ if (pack_direction >= 0)
+ lua_pushstring(L, string_dir(pack_direction));
+ else
+ lua_pushnil(L);
+ if (lua_pcall(L, 6, 1, 0) != 0) { /* no arg, 1 result */
fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
lua_pop(L, 2);
error();
@@ -241,46 +256,59 @@ lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd,
ret = nodelist_from_lua(L);
}
lua_pop(L, 2); /* result and callback container table */
- /* lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE); */
+#if 0
+ lua_gc(L,LUA_GCSTEP, LUA_GC_STEP_SIZE);
+#endif
if (fix_node_lists)
fix_node_list(ret);
return ret;
}
-/* This is a quick hack to fix etex's \lastnodetype now that
- * there are many more visible node types. TODO: check the
- * eTeX manual for the expected return values.
- */
-
+@ This is a quick hack to fix etex's \.{\\lastnodetype} now that
+ there are many more visible node types. TODO: check the
+ eTeX manual for the expected return values.
+
+@c
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;
+ if (i == glyph_node) {
+ if (is_ligature(n))
+ return 7; /* old ligature value */
+ else
+ return 0; /* old character value */
+ }
+ if (i <= unset_node) {
+ return i + 1;
+ } else if (i <= delim_node) {
+ return 15; /* so-called math nodes */
+ } else {
+ return -1;
+ }
}
-void lua_pdf_literal(int i)
+@ @c
+void lua_pdf_literal(PDF pdf, int i)
{
- const char *s;
+ const char *s = NULL;
size_t l = 0;
lua_rawgeti(Luas, LUA_REGISTRYINDEX, i);
s = lua_tolstring(Luas, -1, &l);
- while (l--) {
- pdf_room(1);
- pdf_buf[pdf_ptr++] = *s++;
+ if (l < max_single_pdf_print) {
+ pdf_out_block(pdf, s, l);
+ } else {
+ while (l--) {
+ pdf_out(pdf, *s++);
+ }
}
- pdf_buf[pdf_ptr++] = 10; /* pdf_print_nl */
+ pdf_out(pdf, 10); /* |pdf_print_nl| */
lua_pop(Luas, 1);
}
+@ @c
void copy_pdf_literal(pointer r, pointer p)
{
pdf_literal_type(r) = pdf_literal_type(p);
@@ -295,6 +323,7 @@ void copy_pdf_literal(pointer r, pointer p)
}
+@ @c
void free_pdf_literal(pointer p)
{
if (pdf_literal_type(p) == normal) {
@@ -304,6 +333,7 @@ void free_pdf_literal(pointer p)
}
}
+@ @c
void show_pdf_literal(pointer p)
{
tprint_esc("pdfliteral");
@@ -317,7 +347,7 @@ void show_pdf_literal(pointer p)
tprint(" direct");
break;
default:
- tconfusion("literal2");
+ confusion("literal2");
break;
}
if (pdf_literal_type(p) == normal) {
diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.c b/Build/source/texk/web2c/luatexdir/lua/luastuff.w
index 75bdaf367ef..06547bc4de9 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luastuff.c
+++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.w
@@ -1,57 +1,63 @@
-/* luastuff.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% luastuff.w
- This file is part of LuaTeX.
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% 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.
-#include "luatex-api.h"
-#include <ptexlib.h>
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
static const char _svn_version[] =
- "$Id: luastuff.c 2321 2009-04-18 09:17:13Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luastuff.c $";
+ "$Id: luastuff.w 3583 2010-04-02 17:40:44Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luastuff.w $";
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
+
+@ @c
lua_State *Luas = NULL;
int luastate_bytes = 0;
int lua_active = 0;
-void make_table(lua_State * L, const char *tab, const char *getfunc, const char *setfunc)
+@ @c
+void make_table(lua_State * L, const char *tab, const char *getfunc,
+ const char *setfunc)
{
- /* make the table *//* [{<tex>}] */
- lua_pushstring(L, tab); /* [{<tex>},"dimen"] */
- lua_newtable(L); /* [{<tex>},"dimen",{}] */
- lua_settable(L, -3); /* [{<tex>}] */
+ /* make the table *//* |[{<tex>}]| */
+ lua_pushstring(L, tab); /* |[{<tex>},"dimen"]| */
+ lua_newtable(L); /* |[{<tex>},"dimen",{}]| */
+ lua_settable(L, -3); /* |[{<tex>}]| */
/* fetch it back */
- lua_pushstring(L, tab); /* [{<tex>},"dimen"] */
- lua_gettable(L, -2); /* [{<tex>},{<dimen>}] */
+ lua_pushstring(L, tab); /* |[{<tex>},"dimen"]| */
+ lua_gettable(L, -2); /* |[{<tex>},{<dimen>}]| */
/* make the meta entries */
- luaL_newmetatable(L, tab); /* [{<tex>},{<dimen>},{<dimen_m>}] */
- lua_pushstring(L, "__index"); /* [{<tex>},{<dimen>},{<dimen_m>},"__index"] */
- lua_pushstring(L, getfunc); /* [{<tex>},{<dimen>},{<dimen_m>},"__index","getdimen"] */
- lua_gettable(L, -5); /* [{<tex>},{<dimen>},{<dimen_m>},"__index",<tex.getdimen>] */
- lua_settable(L, -3); /* [{<tex>},{<dimen>},{<dimen_m>}] */
- lua_pushstring(L, "__newindex"); /* [{<tex>},{<dimen>},{<dimen_m>},"__newindex"] */
- lua_pushstring(L, setfunc); /* [{<tex>},{<dimen>},{<dimen_m>},"__newindex","setdimen"] */
- lua_gettable(L, -5); /* [{<tex>},{<dimen>},{<dimen_m>},"__newindex",<tex.setdimen>] */
- lua_settable(L, -3); /* [{<tex>},{<dimen>},{<dimen_m>}] */
- lua_setmetatable(L, -2); /* [{<tex>},{<dimen>}] : assign the metatable */
- lua_pop(L, 1); /* [{<tex>}] : clean the stack */
+ luaL_newmetatable(L, tab); /* |[{<tex>},{<dimen>},{<dimen_m>}]| */
+ lua_pushstring(L, "__index"); /* |[{<tex>},{<dimen>},{<dimen_m>},"__index"]| */
+ lua_pushstring(L, getfunc); /* |[{<tex>},{<dimen>},{<dimen_m>},"__index","getdimen"]| */
+ lua_gettable(L, -5); /* |[{<tex>},{<dimen>},{<dimen_m>},"__index",<tex.getdimen>]| */
+ lua_settable(L, -3); /* |[{<tex>},{<dimen>},{<dimen_m>}]| */
+ lua_pushstring(L, "__newindex"); /* |[{<tex>},{<dimen>},{<dimen_m>},"__newindex"]| */
+ lua_pushstring(L, setfunc); /* |[{<tex>},{<dimen>},{<dimen_m>},"__newindex","setdimen"]| */
+ lua_gettable(L, -5); /* |[{<tex>},{<dimen>},{<dimen_m>},"__newindex",<tex.setdimen>]| */
+ lua_settable(L, -3); /* |[{<tex>},{<dimen>},{<dimen_m>}]| */
+ lua_setmetatable(L, -2); /* |[{<tex>},{<dimen>}]| : assign the metatable */
+ lua_pop(L, 1); /* |[{<tex>}]| : clean the stack */
}
+@ @c
static
const char *getS(lua_State * L, void *ud, size_t * size)
{
@@ -64,7 +70,8 @@ const char *getS(lua_State * L, void *ud, size_t * size)
return ls->s;
}
-static void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize)
+@ @c
+void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
void *ret = NULL;
(void) ud; /* for -Wunused */
@@ -72,10 +79,11 @@ static void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize)
free(ptr);
else
ret = realloc(ptr, nsize);
- luastate_bytes += (nsize - osize);
+ luastate_bytes += (int) (nsize - osize);
return ret;
}
+@ @c
static int my_luapanic(lua_State * L)
{
(void) L; /* to avoid warnings */
@@ -84,6 +92,7 @@ static int my_luapanic(lua_State * L)
return 0;
}
+@ @c
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{"package", luaopen_package},
@@ -103,6 +112,7 @@ static const luaL_Reg lualibs[] = {
};
+@ @c
static void do_openlibs(lua_State * L)
{
const luaL_Reg *lib = lualibs;
@@ -113,6 +123,52 @@ static void do_openlibs(lua_State * L)
}
}
+@ @c
+static int load_aux (lua_State *L, int status) {
+ if (status == 0) /* OK? */
+ return 1;
+ else {
+ lua_pushnil(L);
+ lua_insert(L, -2); /* put before error message */
+ return 2; /* return nil plus error message */
+ }
+}
+
+@ @c
+static int luatex_loadfile (lua_State *L) {
+ const char *fname = luaL_optstring(L, 1, NULL);
+ if (!lua_only && !fname) {
+ if (interaction == batch_mode) {
+ lua_pushnil(L);
+ lua_pushstring(L, "reading from stdin is disabled in batch mode");
+ return 2; /* return nil plus error message */
+ } else {
+ tprint_nl("lua> ");
+ }
+ }
+ return load_aux(L, luaL_loadfile(L, fname));
+}
+
+@ @c
+static int luatex_dofile (lua_State *L) {
+ const char *fname = luaL_optstring(L, 1, NULL);
+ int n = lua_gettop(L);
+ if (!lua_only && !fname) {
+ if (interaction == batch_mode) {
+ lua_pushnil(L);
+ lua_pushstring(L, "reading from stdin is disabled in batch mode");
+ return 2; /* return nil plus error message */
+ } else {
+ tprint_nl("lua> ");
+ }
+ }
+ if (luaL_loadfile(L, fname) != 0) lua_error(L);
+ lua_call(L, 0, LUA_MULTRET);
+ return lua_gettop(L) - n;
+}
+
+
+@ @c
void luainterpreter(void)
{
lua_State *L;
@@ -124,19 +180,21 @@ void luainterpreter(void)
lua_atpanic(L, &my_luapanic);
do_openlibs(L); /* does all the 'simple' libraries */
+
+ lua_pushcfunction(L,luatex_dofile);
+ lua_setglobal(L, "dofile");
+ lua_pushcfunction(L,luatex_loadfile);
+ lua_setglobal(L, "loadfile");
- open_oslibext(L, safer_option);
+ luatex_md5_lua_open(L);
- lua_getglobal(L, "package");
- lua_pushstring(L, "");
- lua_setfield(L, -2, "cpath");
- lua_pop(L, 1); /* pop the table */
+ open_oslibext(L, safer_option);
/* 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.
+ 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");
@@ -166,7 +224,6 @@ void luainterpreter(void)
/* our own libraries */
luaopen_ff(L);
- luaopen_pdf(L);
luaopen_tex(L);
luaopen_token(L);
luaopen_node(L);
@@ -179,11 +236,22 @@ void luainterpreter(void)
luaopen_lang(L);
luaopen_mplib(L);
- /* luaopen_img(L); */
+ /* |luaopen_pdf(L);| */
+ /* environment table at |LUA_ENVIRONINDEX| needs to load this way: */
+ lua_pushcfunction(L, luaopen_pdf);
+ lua_pushstring(L, "pdf");
+ lua_call(L, 1, 0);
+
+ /* |luaopen_img(L);| */
lua_pushcfunction(L, luaopen_img);
lua_pushstring(L, "img");
lua_call(L, 1, 0);
+ /* |luaopen_epdf(L);| */
+ lua_pushcfunction(L, luaopen_epdf);
+ lua_pushstring(L, "epdf");
+ lua_call(L, 1, 0);
+
lua_createtable(L, 0, 0);
lua_setglobal(L, "texconfig");
@@ -209,6 +277,7 @@ void luainterpreter(void)
Luas = L;
}
+@ @c
int hide_lua_table(lua_State * L, const char *name)
{
int r = 0;
@@ -221,6 +290,7 @@ int hide_lua_table(lua_State * L, const char *name)
return r;
}
+@ @c
void unhide_lua_table(lua_State * L, const char *name, int r)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, r);
@@ -228,6 +298,7 @@ void unhide_lua_table(lua_State * L, const char *name, int r)
luaL_unref(L, LUA_REGISTRYINDEX, r);
}
+@ @c
int hide_lua_value(lua_State * L, const char *name, const char *item)
{
int r = 0;
@@ -241,6 +312,7 @@ int hide_lua_value(lua_State * L, const char *name, const char *item)
return r;
}
+@ @c
void unhide_lua_value(lua_State * L, const char *name, const char *item, int r)
{
lua_getglobal(L, name);
@@ -252,7 +324,8 @@ void unhide_lua_value(lua_State * L, const char *name, const char *item, int r)
}
-static int lua_traceback(lua_State * L)
+@ @c
+int lua_traceback(lua_State * L)
{
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(L, -1)) {
@@ -270,7 +343,8 @@ static int lua_traceback(lua_State * L)
return 1;
}
-void luacall(int p, int nameptr)
+@ @c
+static void luacall(int p, int nameptr)
{
LoadS ls;
int i, l;
@@ -284,7 +358,7 @@ void luacall(int p, int nameptr)
lua_active++;
s = tokenlist_to_cstring(p, 1, &l);
ls.s = s;
- ls.size = l;
+ ls.size = (size_t) l;
if (ls.size > 0) {
if (nameptr > 0) {
@@ -320,6 +394,16 @@ void luacall(int p, int nameptr)
lua_active--;
}
+@ @c
+void late_lua(PDF pdf, halfword p)
+{
+ (void) pdf;
+ expand_macros_in_tokenlist(p); /* sets |def_ref| */
+ luacall(def_ref, late_lua_name(p));
+ flush_list(def_ref);
+}
+
+@ @c
void luatokencall(int p, int nameptr)
{
LoadS ls;
@@ -331,7 +415,7 @@ void luatokencall(int p, int nameptr)
lua_active++;
s = tokenlist_to_cstring(p, 1, &l);
ls.s = s;
- ls.size = l;
+ ls.size = (size_t) l;
if (ls.size > 0) {
if (nameptr > 0) {
lua_id = tokenlist_to_cstring(nameptr, 1, &l);
@@ -365,42 +449,45 @@ void luatokencall(int p, int nameptr)
lua_active--;
}
-
-
-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];
-}
-
-
+@ @c
lua_State *luatex_error(lua_State * L, int is_fatal)
{
- str_number 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);
+ err = (char *) xmalloc((unsigned) (len + 1));
+ len = (size_t) 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
+ /* 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);
+ lua_fatal_error(err);
/* never reached */
xfree(err);
lua_close(L);
return (lua_State *) NULL;
} else {
- s = maketexlstring(err, len);
- lua_norm_error(s);
- flush_str(s);
+ lua_norm_error(err);
xfree(err);
return L;
}
}
+
+@ @c
+void preset_environment(lua_State * L, const parm_struct * p)
+{
+ int i;
+ assert(L != NULL);
+ lua_newtable(L); /* t */
+ for (i = 1, ++p; p->name != NULL; i++, p++) {
+ assert(i == p->idx);
+ lua_pushstring(L, p->name); /* k t */
+ lua_pushinteger(L, p->idx); /* v k t */
+ lua_settable(L, -3); /* t */
+ }
+ lua_replace(L, LUA_ENVIRONINDEX); /* - */
+}
diff --git a/Build/source/texk/web2c/luatexdir/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h
index 89bbf1230c1..155fb6a3cb6 100644
--- a/Build/source/texk/web2c/luatexdir/luatex-api.h
+++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h
@@ -1,6 +1,6 @@
/* luatex-api.h
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,15 +17,17 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id$ */
+/* $Id: luatex-api.h 3558 2010-03-29 07:21:45Z taco $ */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <../lua51/lua.h>
-#include <../lua51/lauxlib.h>
-#include <../lua51/lualib.h>
+#ifndef LUATEX_API_H
+# define LUATEX_API_H 1
+# include <stdlib.h>
+# include <stdio.h>
+# include <stdarg.h>
+# include "lua51/lua.h"
+# include "lua51/lauxlib.h"
+# include "lua51/lualib.h"
typedef struct LoadS {
const char *s;
@@ -34,7 +36,8 @@ typedef struct LoadS {
extern lua_State *Luas;
-extern void make_table(lua_State * L, const char *tab, const char *getfunc, const char *setfunc);
+extern void make_table(lua_State * L, const char *tab, const char *getfunc,
+ const char *setfunc);
extern int luac_main(int argc, char *argv[]);
@@ -42,14 +45,12 @@ extern int luaopen_tex(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_lang(lua_State * L);
-extern void luatex_load_init(int s, LoadS * ls);
-
extern lua_State *luatex_error(lua_State * L, int fatal);
extern int luaopen_unicode(lua_State * L);
@@ -57,6 +58,8 @@ 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 luatex_md5_lua_open(lua_State * L);
+
extern int luaopen_zlib(lua_State * L);
extern int luaopen_gzip(lua_State * L);
extern int luaopen_ff(lua_State * L);
@@ -68,6 +71,7 @@ extern void luatex_socketlua_open(lua_State * L);
extern int luaopen_img(lua_State * L);
extern int l_new_image(lua_State * L);
+extern int luaopen_epdf(lua_State * L);
extern int luaopen_mplib(lua_State * L);
extern void open_oslibext(lua_State * L, int safer_option);
@@ -84,7 +88,7 @@ extern int luaopen_kpse(lua_State * L);
extern int luaopen_callback(lua_State * L);
-extern int luaopen_lua(lua_State * L, const char *fname);
+extern int luaopen_lua(lua_State * L, char *fname);
extern int luaopen_stats(lua_State * L);
@@ -93,33 +97,38 @@ 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 void lua_nodelib_push(lua_State * L);
+extern int nodelib_getdir(lua_State * L, int n);
+
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, const char *s);
+extern int get_command_id(const char *s);
+
extern void dump_luac_registers(void);
extern void undump_luac_registers(void);
+extern int lua_only;
extern void unhide_lua_table(lua_State * lua, const char *name, int r);
extern int hide_lua_table(lua_State * lua, const char *name);
-extern void unhide_lua_value(lua_State * lua, const char *name, const char *item, int r);
+extern void unhide_lua_value(lua_State * lua, const char *name,
+ const char *item, int r);
extern int hide_lua_value(lua_State * lua, const char *name, const char *item);
typedef struct command_item_ {
const char *cmd_name;
int command_offset;
- char **commands;
+ const char **commands;
} command_item;
extern command_item command_names[];
@@ -127,17 +136,67 @@ extern int callback_callbacks_id;
extern void luainterpreter(void);
-extern int program_name_set;
-
-extern const char *startup_filename;
-extern int safer_option;
-extern int nosocket_option;
-
extern int luabytecode_max;
extern unsigned int luabytecode_bytes;
extern int luastate_bytes;
+
extern int callback_count;
extern int saved_callback_count;
-#define utf8_idpb lua_utf8_idpb /* avoid name conflict with fontforge library */
-extern char *utf8_idpb(char *utf8_text, unsigned int ch);
+extern const char *ptexbanner;
+
+/* luastuff.h */
+
+typedef struct {
+ const char *name; /* parameter name */
+ int idx; /* index within img_parms array */
+} parm_struct;
+
+extern void preset_environment(lua_State * L, const parm_struct * p);
+
+extern char *startup_filename;
+extern int safer_option;
+extern int nosocket_option;
+
+extern char *last_source_name;
+extern int last_lineno;
+
+extern int program_name_set; /* in lkpselib.c */
+
+/* for topenin() */
+extern char **argv;
+extern int argc;
+
+
+extern int loader_C_luatex(lua_State * L, const char *name,
+ const char *filename);
+extern int loader_Call_luatex (lua_State *L, const char *name,
+ const char *filename);
+
+
+extern void init_tex_table(lua_State * L);
+
+extern int tex_table_id;
+extern int pdf_table_id;
+extern int token_table_id;
+extern int node_table_id;
+extern int main_initialize(void);
+
+extern int do_run_callback(int special, const char *values, va_list vl);
+extern int lua_traceback(lua_State * L);
+
+extern int luainit;
+
+extern char *luanames[];
+
+extern int ff_get_ttc_index(char *ffname, char *psname); /* luafontloader/src/luafflib.c */
+extern int ff_createcff(char *, unsigned char **, int *); /* luafontloader/src/luafflib.c */
+
+extern char *FindResourceTtfFont(char *filename, char *fontname); /* luafontloader/fontforge/fontforge/macbinary.c */
+
+extern char charsetstr[]; /* from mpdir/psout.w */
+
+extern char **environ;
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex.c b/Build/source/texk/web2c/luatexdir/lua/luatex.c
deleted file mode 100644
index 88903fe338b..00000000000
--- a/Build/source/texk/web2c/luatexdir/lua/luatex.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/* luatex.c
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include <zlib.h>
-
-static const char _svn_version[] =
- "$Id: luatex.c 2599 2009-06-25 10:35:26Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luatex.c $";
-
-/* do this aleph stuff here, for now */
-
-void b_test_in(void)
-{
- 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;
-
-void
-allocate_ocp_table (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;
- }
- 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;
- }
-}
-
-void
-dump_ocp_table (int ocp_number)
-{
- dump_things(ocp_tables[ocp_number][0], ocp_tables[ocp_number][0] + 1);
-}
-
-void
-undump_ocp_table (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;
- }
- 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);
-}
-
-
-void
-run_external_ocp (string external_ocp_name)
-{
- 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);
- in_file = fopen(in_file_name, FOPEN_WBIN_MODE);
-#else
- 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 = fopen(out_file_name, FOPEN_RBIN_MODE);
-#else
- 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);
- 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 */
-
-/* Earlier versions recast *f from FILE * to gzFile, but there is
- * no guarantee that these have the same size, so a static variable
- * is needed.
- */
-
-static gzFile gz_fmtfile = NULL;
-
-void do_zdump(char *p, int item_size, int nitems, FILE * out_file)
-{
- int err;
- (void) out_file;
- 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)
-{
- int err;
- (void) in_file;
- 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_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);
- }
- return res;
-}
-
-void zwclose(FILE * f)
-{
- (void) f;
- gzclose(gz_fmtfile);
-}
-
-/* create the dvi or pdf file */
-
-int open_outfile(FILE ** f, const char *name, const 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;
-}
diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.c b/Build/source/texk/web2c/luatexdir/lua/luatoken.w
index 628dbf21478..7a96fcd1a11 100644
--- a/Build/source/texk/web2c/luatexdir/lua/luatoken.c
+++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.w
@@ -1,31 +1,31 @@
-/* luatoken.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% luatoken.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-
-#include "tokens.h"
-#include "commands.h"
+@ @c
+#include "lua/luatex-api.h"
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: luatoken.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/luatoken.c $";
+ "$Id: luatoken.w 3583 2010-04-02 17:40:44Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/luatoken.w $";
+@ @c
command_item command_names[] = {
{"relax", relax_cmd, NULL},
{"left_brace", left_brace_cmd, NULL},
@@ -177,6 +177,7 @@ command_item command_names[] = {
};
+@ @c
int get_command_id(const char *s)
{
int i;
@@ -191,24 +192,25 @@ int get_command_id(const char *s)
return cmd;
}
+@ @c
static int get_cur_cmd(lua_State * L)
{
int r = 0;
- int len = lua_objlen(L, -1);
+ size_t 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);
+ cur_cmd = (int) lua_tointeger(L, -1);
lua_rawgeti(L, -2, 2);
- cur_chr = lua_tointeger(L, -1);
+ cur_chr = (halfword) lua_tointeger(L, -1);
if (len == 3) {
lua_rawgeti(L, -3, 3);
- cur_cs = lua_tointeger(L, -1);
+ cur_cs = (halfword) lua_tointeger(L, -1);
}
- lua_pop(L, len);
+ lua_pop(L, (int) len);
if (cur_cs == 0)
- cur_tok = (cur_cmd * string_offset) + cur_chr;
+ cur_tok = token_val(cur_cmd, cur_chr);
else
cur_tok = cs_token_flag + cur_cs;
}
@@ -216,23 +218,24 @@ static int get_cur_cmd(lua_State * L)
}
+@ @c
static int token_from_lua(lua_State * L)
{
int cmd, chr;
int cs = 0;
- int len = lua_objlen(L, -1);
+ size_t len = lua_objlen(L, -1);
if (len == 3 || len == 2) {
lua_rawgeti(L, -1, 1);
- cmd = lua_tointeger(L, -1);
+ cmd = (int) lua_tointeger(L, -1);
lua_rawgeti(L, -2, 2);
- chr = lua_tointeger(L, -1);
+ chr = (int) lua_tointeger(L, -1);
if (len == 3) {
lua_rawgeti(L, -3, 3);
- cs = lua_tointeger(L, -1);
+ cs = (int) lua_tointeger(L, -1);
}
- lua_pop(L, len);
+ lua_pop(L, (int) len);
if (cs == 0) {
- return (cmd * string_offset) + chr;
+ return token_val(cmd, chr);
} else {
return cs_token_flag + cs;
}
@@ -240,12 +243,13 @@ static int token_from_lua(lua_State * L)
return -1;
}
+@ @c
static int get_cur_cs(lua_State * L)
{
const char *s;
unsigned j;
size_t l;
- integer cs;
+ int cs;
int save_nncs;
int ret;
ret = 0;
@@ -254,17 +258,17 @@ static int get_cur_cs(lua_State * L)
if (lua_isstring(L, -1)) {
s = lua_tolstring(L, -1, &l);
if (l > 0) {
- if ((int) (last + l) > buf_size)
- check_buffer_overflow(last + l);
+ if ((last + (int) l) > buf_size)
+ check_buffer_overflow((last + (int) l));
for (j = 0; j < l; j++) {
- buffer[last + 1 + j] = *s++;
+ buffer[(unsigned) last + 1 + j] = (packed_ASCII_code) * s++;
}
save_nncs = no_new_control_sequence;
no_new_control_sequence = false;
- cs = id_lookup((last + 1), l);
+ cs = id_lookup((last + 1), (int) l);
cur_tok = cs_token_flag + cs;
- cur_cmd = zget_eq_type(cs);
- cur_chr = zget_equiv(cs);
+ cur_cmd = eq_type(cs);
+ cur_chr = equiv(cs);
no_new_control_sequence = save_nncs;
ret = 1;
}
@@ -273,232 +277,46 @@ static int get_cur_cs(lua_State * L)
return ret;
}
-
-#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) { \
- const char *v = b; \
- if (e>0 && e<string_offset) { \
- Print_uchar (e); Print_uchar (e); \
- } \
- while (*v) { Print_char(*v); v++; } \
- }
-
-#define single_letter(a) (length(a)==1)|| \
- ((length(a)==4)&&(str_pool[str_start_macro(a)]>=0xF0))|| \
- ((length(a)==3)&&(str_pool[str_start_macro(a)]>=0xE0))|| \
- ((length(a)==2)&&(str_pool[str_start_macro(a)]>=0xC0))
-
-#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 null_cs = 0;
-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;
-}
-
-
+@ @c
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) {
+ while (v != null && v < (int) fix_mem_end) {
i++;
- v = link(v);
+ v = token_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);
+ while (p != null && p < (int) fix_mem_end) {
+ if (token_info(p) >= cs_token_flag) {
+ cs = token_info(p) - cs_token_flag;
+ cmd = eq_type(cs);
+ chr = equiv(cs);
make_token_table(L, cmd, chr, cs);
} else {
- cmd = info(p) / string_offset;
- chr = info(p) % string_offset;
+ cmd = token_cmd(token_info(p));
+ chr = token_chr(token_info(p));
make_token_table(L, cmd, chr, 0);
}
lua_rawseti(L, -2, i++);
- p = link(p);
+ p = token_link(p);
}
}
-
+@ @c
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);
+ lua_pushlstring(L, s, (size_t) l);
}
+@ @c
int tokenlist_from_lua(lua_State * L)
{
const char *s;
@@ -506,14 +324,14 @@ int tokenlist_from_lua(lua_State * L)
size_t i, j;
halfword p, q, r;
r = get_avail();
- info(r) = 0; /* ref count */
- link(r) = null;
+ token_info(r) = 0; /* ref count */
+ token_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);
+ lua_rawgeti(L, -1, (int) i);
tok = token_from_lua(L);
if (tok >= 0) {
store_new_token(tok);
@@ -526,9 +344,11 @@ int tokenlist_from_lua(lua_State * L)
s = lua_tolstring(L, -1, &j);
for (i = 0; i < j; i++) {
if (s[i] == 32) {
- tok = (10 * string_offset) + s[i];
+ tok = token_val(10, s[i]);
} else {
- tok = (12 * string_offset) + s[i];
+ int j = (int) str2uni((const unsigned char *) (s + i));
+ i = i + (size_t) (utf8_size(j) - 1);
+ tok = token_val(12, j);
}
store_new_token(tok);
}
@@ -539,7 +359,8 @@ int tokenlist_from_lua(lua_State * L)
}
}
-void do_get_token_lua(integer callback_id)
+@ @c
+void do_get_token_lua(int callback_id)
{
lua_State *L = Luas;
while (1) {
@@ -556,8 +377,8 @@ void do_get_token_lua(integer callback_id)
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;
+ int p, q, r;
+ size_t i, j;
lua_pop(L, 1); /* container, result */
/* build a token list */
r = get_avail();
@@ -565,7 +386,7 @@ void do_get_token_lua(integer callback_id)
j = lua_objlen(L, -1);
if (j > 0) {
for (i = 1; i <= j; i++) {
- lua_rawgeti(L, -1, i);
+ lua_rawgeti(L, -1, (int) i);
if (get_cur_cmd(L) || get_cur_cs(L)) {
store_new_token(cur_tok);
}
@@ -573,7 +394,7 @@ void do_get_token_lua(integer callback_id)
}
}
if (p != r) {
- p = link(r);
+ p = token_link(r);
free_avail(r);
begin_token_list(p, inserted);
cur_input.nofilter_field = true;
diff --git a/Build/source/texk/web2c/luatexdir/lua/texluac.c b/Build/source/texk/web2c/luatexdir/lua/texluac.w
index c994785bd08..108e27864dc 100644
--- a/Build/source/texk/web2c/luatexdir/lua/texluac.c
+++ b/Build/source/texk/web2c/luatexdir/lua/texluac.w
@@ -1,31 +1,30 @@
-/* texlua.c
-
-* Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining
-* a copy of this software and associated documentation files (the
-* "Software"), to deal in the Software without restriction, including
-* without limitation the rights to use, copy, modify, merge, publish,
-* distribute, sublicense, and/or sell copies of the Software, and to
-* permit persons to whom the Software is furnished to do so, subject to
-* the following conditions:
+% texlua.w
+%
+% Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved.
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+%
+% Permission is hereby granted, free of charge, to any person obtaining
+% a copy of this software and associated documentation files (the
+% "Software"), to deal in the Software without restriction, including
+% without limitation the rights to use, copy, modify, merge, publish,
+% distribute, sublicense, and/or sell copies of the Software, and to
+% permit persons to whom the Software is furnished to do so, subject to
+% the following conditions:
*
-* The above copyright notice and this permission notice shall be
-* included in all copies or substantial portions of the Software.
+% The above copyright notice and this permission notice shall be
+% included in all copies or substantial portions of the Software.
*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+% IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+% CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+% TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+% SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- This file is part of LuaTeX.
-*/
+% This file is part of LuaTeX.
+@ @c
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -34,37 +33,42 @@
#define luac_c
#define LUA_CORE
-#include <../lua51/lua.h>
-#include <../lua51/lauxlib.h>
+#include "lua51/lua.h"
+#include "lua51/lauxlib.h"
-#include <../lua51/ldo.h>
-#include <../lua51/lfunc.h>
-#include <../lua51/lmem.h>
-#include <../lua51/lobject.h>
-#include <../lua51/lopcodes.h>
-#include <../lua51/lstring.h>
-#include <../lua51/lundump.h>
-
-#include "luatex-api.h"
+#include "lua51/ldo.h"
+#include "lua51/lfunc.h"
+#include "lua51/lmem.h"
+#include "lua51/lobject.h"
+#include "lua51/lopcodes.h"
+#include "lua51/lstring.h"
+#include "lua51/lundump.h"
+@ @c
static const char _svn_version[] =
- "$Id: texluac.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/lua/texluac.c $";
+ "$Id: texluac.w 3583 2010-04-02 17:40:44Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/lua/texluac.w $";
+@ @c
#define PROGNAME "texluac" /* default program name */
#define OUTPUT PROGNAME ".out" /* default output file */
static int dumping = 1; /* dump bytecodes? */
static int stripping = 0; /* strip debug information? */
static char Output[] = { OUTPUT }; /* default output file name */
+
static const char *output = Output; /* actual output file name */
static const char *progname = PROGNAME; /* actual program name */
+@ @c
+__attribute__ ((noreturn))
static void fatal(const char *message)
{
fprintf(stderr, "%s: %s\n", progname, message);
exit(EXIT_FAILURE);
}
+@ @c
+__attribute__ ((noreturn))
static void cannot(const char *what)
{
fprintf(stderr, "%s: cannot %s %s: %s\n", progname, what, output,
@@ -72,6 +76,8 @@ static void cannot(const char *what)
exit(EXIT_FAILURE);
}
+@ @c
+__attribute__ ((noreturn))
static void usage(const char *message)
{
if (*message == '-')
@@ -91,6 +97,7 @@ static void usage(const char *message)
exit(EXIT_FAILURE);
}
+@ @c
#define IS(s) (strcmp(argv[i],s)==0)
static int doargs(int argc, char *argv[])
@@ -140,6 +147,7 @@ static int doargs(int argc, char *argv[])
return i;
}
+@ @c
#define toproto(L,i) (clvalue(L->top+(i))->l.p)
static const Proto *combine(lua_State * L, int n)
@@ -154,9 +162,9 @@ static const Proto *combine(lua_State * L, int n)
f->source = luaS_newliteral(L, "=(" PROGNAME ")");
f->maxstacksize = 1;
pc = 2 * n + 1;
- f->code = luaM_newvector(L, pc, Instruction);
+ f->code = luaM_newvector(L, (unsigned long) pc, Instruction);
f->sizecode = pc;
- f->p = luaM_newvector(L, n, Proto *);
+ f->p = luaM_newvector(L, (unsigned long) n, Proto *);
f->sizep = n;
pc = 0;
for (i = 0; i < n; i++) {
@@ -169,17 +177,20 @@ static const Proto *combine(lua_State * L, int n)
}
}
+@ @c
static int writer(lua_State * L, const void *p, size_t size, void *u)
{
UNUSED(L);
return (fwrite(p, size, 1, (FILE *) u) != 1) && (size != 0);
}
+@ @c
struct Smain {
int argc;
char **argv;
};
+@ @c
static int pmain(lua_State * L)
{
struct Smain *s = (struct Smain *) lua_touserdata(L, 1);
@@ -210,6 +221,7 @@ static int pmain(lua_State * L)
return 0;
}
+@ @c
int luac_main(int argc, char *argv[])
{
lua_State *L;
diff --git a/Build/source/texk/web2c/luatexdir/lua51/lcoco.c b/Build/source/texk/web2c/luatexdir/lua51/lcoco.c
index 45080285eae..2a234edbfc7 100644
--- a/Build/source/texk/web2c/luatexdir/lua51/lcoco.c
+++ b/Build/source/texk/web2c/luatexdir/lua51/lcoco.c
@@ -468,7 +468,7 @@ typedef void (*coco_MainFunc)(void);
/* Don't use multiples of 64K to avoid D-cache aliasing conflicts. */
#ifndef COCO_DEFAULT_CSTACKSIZE
-#define COCO_DEFAULT_CSTACKSIZE (65536-4096)
+#define COCO_DEFAULT_CSTACKSIZE ((16*65536)-4096)
#endif
static int defaultcstacksize = COCO_DEFAULT_CSTACKSIZE;
diff --git a/Build/source/texk/web2c/luatexdir/lua51/loadlib.c b/Build/source/texk/web2c/luatexdir/lua51/loadlib.c
index 0d401eba1cf..ea62dff7a16 100644
--- a/Build/source/texk/web2c/luatexdir/lua51/loadlib.c
+++ b/Build/source/texk/web2c/luatexdir/lua51/loadlib.c
@@ -410,6 +410,14 @@ static int loader_C (lua_State *L) {
return 1; /* library loaded successfully */
}
+int loader_C_luatex (lua_State *L, const char *name, const char *filename) {
+ const char *funcname;
+ funcname = mkfuncname(L, name);
+ if (ll_loadfunc(L, filename, funcname) != 0)
+ loaderror(L, filename);
+ return 1; /* library loaded successfully */
+}
+
static int loader_Croot (lua_State *L) {
const char *funcname;
@@ -431,6 +439,21 @@ static int loader_Croot (lua_State *L) {
return 1;
}
+int loader_Call_luatex (lua_State *L, const char *name, const char *filename) {
+ const char *funcname;
+ int stat;
+ if (filename == NULL) return 1; /* root not found */
+ funcname = mkfuncname(L, name);
+ if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
+ if (stat != ERRFUNC) loaderror(L, filename); /* real error */
+ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
+ name, filename);
+ return 1; /* function not found */
+ }
+ return 1; /* library loaded successfully */
+}
+
+
static int loader_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
diff --git a/Build/source/texk/web2c/luatexdir/lua51/luaconf.h b/Build/source/texk/web2c/luatexdir/lua51/luaconf.h
index 0650f2c7f64..fac58d8cb5c 100644
--- a/Build/source/texk/web2c/luatexdir/lua51/luaconf.h
+++ b/Build/source/texk/web2c/luatexdir/lua51/luaconf.h
@@ -11,6 +11,7 @@
#include <limits.h>
#include <stddef.h>
+#include <web2c/c-auto.h>
/*
** ==================================================================
@@ -44,6 +45,11 @@
#define LUA_DL_DYLD /* does not need extra library */
#endif
+#if !defined(_WIN32)
+#if defined(HAVE_DLFCN_H)
+#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
+#endif
+#endif
/*
@@ -521,15 +527,23 @@
#define LUA_NUMBER_SCAN "%lf"
#define LUA_NUMBER_FMT "%.14g"
-#define lua_number2str(s,n) if (((n)<0.000001) && ((n)>-0.000001)) \
- sprintf((s), "0"); else if (((n)<0.0001) && ((n)>-0.0001)) { \
- sprintf((s), "%.6f", (n)); \
- if (n>0) { if (s[7] == '0') { s[7] = 0; } } \
- else { if (s[8] == '0') { s[8] = 0; } } \
- } else sprintf((s), LUA_NUMBER_FMT, (n));
-
-
-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
+#define lua_number2str(s,n) do { \
+ if (n<0.0001 && n>=-0.0001) { \
+ sprintf((s), "%.14f", (n)); \
+ if (strchr(s,'.')) { \
+ size_t s_l ; \
+ s_l = strlen(s); \
+ while (s_l>0 && s_l--) { \
+ if (s[s_l] == '0') s[s_l] = '\0'; \
+ else break; \
+ } \
+ if (s[s_l] == '.') s[s_l] = '\0'; \
+ } \
+ } else sprintf((s), LUA_NUMBER_FMT, (n)); \
+ } while (0)
+
+
+#define LUAI_MAXNUMBER2STR 64 /* 16 digits, sign, point, and \0 */
#define lua_str2number(s,p) strtod((s), (p))
@@ -568,7 +582,8 @@
/* On a Microsoft compiler, use assembler */
#if defined(_MSC_VER)
-#define lua_number2int(i,d) __asm fld d __asm fistp i
+#define lua_number2int(i,d) \
+{int N__; double D__=d; {__asm fld D__ __asm fistp N__} i = N__;}
#define lua_number2integer(i,n) lua_number2int(i, n)
/* the next trick should work on any Pentium, but sometimes clashes
diff --git a/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c b/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c
index cdcbcf0d90f..c4598e41aae 100644
--- a/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c
+++ b/Build/source/texk/web2c/luatexdir/luafilesystem/src/lfs.c
@@ -34,6 +34,7 @@
#include <sys/locking.h>
#include <sys/utime.h>
#include <fcntl.h>
+#include <windows.h>
#else
#include <unistd.h>
#include <dirent.h>
@@ -566,7 +567,7 @@ static void push_st_size (lua_State *L, STAT_STRUCT *info) {
lua_pushnumber (L, (lua_Number)info->st_size);
}
/* permssions string */
-static void push_st_perm (lua_State *L, struct stat *info) {
+static void push_st_perm (lua_State *L, STAT_STRUCT *info) {
lua_pushstring (L, perm2string (info->st_mode));
}
#ifndef _WIN32
@@ -653,6 +654,28 @@ static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
return 1;
}
+#ifndef WIN32
+static int pusherror(lua_State *L, const char *info)
+{
+ lua_pushnil(L);
+ if (info==NULL)
+ lua_pushstring(L, strerror(errno));
+ else
+ lua_pushfstring(L, "%s: %s", info, strerror(errno));
+ lua_pushinteger(L, errno);
+ return 3;
+}
+
+static int Preadlink(lua_State *L) /** readlink(path) */
+{
+ char b[PATH_MAX];
+ const char *path = luaL_checkstring(L, 1);
+ int n = readlink(path, b, sizeof(b));
+ if (n==-1) return pusherror(L, path);
+ lua_pushlstring(L, b, n);
+ return 1;
+}
+#endif
/*
** Get file information using stat.
@@ -661,7 +684,6 @@ static int file_info (lua_State *L) {
return _file_info_ (L, STAT_FUNC);
}
-
/*
** Get symbolic link information using lstat.
*/
@@ -669,12 +691,44 @@ static int file_info (lua_State *L) {
static int link_info (lua_State *L) {
return _file_info_ (L, LSTAT_FUNC);
}
+static int read_link (lua_State *L) {
+ return Preadlink (L);
+}
+static int get_short_name (lua_State *L) {
+ /* simply do nothing */
+ return 1;
+}
#else
static int link_info (lua_State *L) {
lua_pushboolean(L, 0);
lua_pushliteral(L, "symlinkattributes not supported on this platform");
return 2;
}
+static int read_link (lua_State *L) {
+ lua_pushboolean(L, 0);
+ lua_pushliteral(L, "readlink not supported on this platform");
+ return 2;
+}
+static int get_short_name (lua_State *L) {
+ long length = 0;
+ TCHAR* buffer = NULL;
+ const char *lpszPath = luaL_checkstring (L, 1);
+ length = GetShortPathName(lpszPath, NULL, 0);
+ if (length == 0) {
+ lua_pushnil(L);
+ lua_pushfstring(L, "operating system error: %d", (int)GetLastError());
+ return 2;
+ }
+ buffer = (TCHAR *)xmalloc(length * sizeof(TCHAR));
+ length = GetShortPathName(lpszPath, buffer, length);
+ if (length == 0) {
+ lua_pushnil(L);
+ lua_pushfstring(L, "operating system error: %d", (int)GetLastError());
+ return 2;
+ }
+ lua_pushlstring(L, (const char *)buffer, (size_t)length);
+ return 1;
+}
#endif
@@ -744,6 +798,8 @@ static const struct luaL_reg fslib[] = {
{"mkdir", make_dir},
{"rmdir", remove_dir},
{"symlinkattributes", link_info},
+ {"readlink", read_link},
+ {"shortname", get_short_name},
{"setmode", lfs_f_setmode},
{"touch", file_utime},
{"unlock", file_unlock},
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/Makefile.in b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/Makefile.in
index ea21c43be1d..7cb2bc9acfe 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/Makefile.in
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/Makefile.in
@@ -14,7 +14,7 @@ GU_AGE=0
LIBTOOL = @LIBTOOL@
CC = @CC@
-libgunicode_OBJECTS = ArabicForms.lo alphabet.lo backtrns.lo char.lo \
+libgunicode_OBJECTS = ArabicForms.lo alphabet.lo char.lo \
cjk.lo memory.lo ucharmap.lo unialt.lo ustring.lo utype.lo \
gwwiconv.lo
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/cjk.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/cjk.c
index a2f01f3131a..412947d5b70 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/cjk.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/cjk.c
@@ -1,7 +1,10 @@
#include <chardata.h>
+#ifdef TO_CJK_ICONV
const unsigned short u_allzeros[256] = { 0 };
+#endif
+#ifdef FROM_CJK_ICONV
const unichar_t unicode_from_jis208[] = {
0x2003, 0x3001, 0x3002, 0xff0c, 0xff0e, 0x30fb, 0xff1a, 0xff1b,
0xff1f, 0xff01, 0x309b, 0x309c, 0x00b4, 0xff40, 0x00a8, 0xff3e,
@@ -2219,7 +2222,9 @@ const unichar_t unicode_from_jis212[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x2003, 0x3001, 0x3002, 0xff0c,
0xff0e, 0x30fb, 0xff1a, 0xff1b, 0xff1f, 0xff01, 0x309b, 0x309c
};
+#endif
+#ifdef TO_CJK_ICONV
static const unsigned short jis_from_unicode_0[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -5806,6 +5811,9 @@ static const unsigned short * const jis_from_unicode_[] = {
struct charmap2 jis_from_unicode = { 0, 255, (unsigned short **) jis_from_unicode_, (unichar_t *) unicode_from_jis212 };
+#endif
+
+#ifdef FROM_CJK_ICONV
const unichar_t unicode_from_big5[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -8881,7 +8889,9 @@ const unichar_t unicode_from_big5[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xfe4f, 0xffffffff, 0x00ff, 0x0000, 0x0100, 0x0002, 0x6000, 0x804f240
};
+#endif
+#ifdef TO_CJK_ICONV
static const unsigned short big5_from_unicode_0[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -12712,7 +12722,9 @@ static const unsigned short * const big5_from_unicode_[] = {
};
struct charmap2 big5_from_unicode = { 0, 255, (unsigned short **) big5_from_unicode_, (unichar_t *) unicode_from_big5 };
+#endif
+#ifdef FROM_CJK_ICONV
const unichar_t unicode_from_big5hkscs[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -16812,7 +16824,9 @@ const unichar_t unicode_from_big5hkscs[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x79d4, 0xfefe, 0x00ff, 0x0000, 0x0100, 0x0005, 0x8000, 0x804f240
};
+#endif
+#ifdef TO_CJK_ICONV
static const unsigned short big5hkscs_from_unicode_0[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -22534,6 +22548,9 @@ static const unsigned short * const big5hkscs_from_unicode_[] = {
struct charmap2 big5hkscs_from_unicode = { 0, 255, (unsigned short **) big5hkscs_from_unicode_, (unichar_t *) unicode_from_big5hkscs };
+#endif
+
+#ifdef FROM_CJK_ICONV
const unichar_t unicode_from_ksc5601[] = {
0x3164, 0x3001, 0x3002, 0x30fb, 0x2025, 0x22ef, 0x00a8, 0x3003,
0x2013, 0x2014, 0x2016, 0xff3c, 0xff5e, 0x2018, 0x2019, 0x201c,
@@ -23642,7 +23659,9 @@ const unichar_t unicode_from_ksc5601[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffffffff,
0xffffffff, 0xffffffff, 0x0000, 0x0000, 0x79d4, 0x0004, 0x2288, 0x804f240
};
+#endif
+#ifdef TO_CJK_ICONV
static unsigned short ksc5601_from_unicode_0[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -28909,6 +28928,9 @@ static const unsigned short * const ksc5601_from_unicode_[] = {
struct charmap2 ksc5601_from_unicode = { 0, 255, (unsigned short **) ksc5601_from_unicode_, (unichar_t *) unicode_from_ksc5601 };
+#endif
+
+#ifdef FROM_CJK_ICONV
const unichar_t unicode_from_johab[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -32880,7 +32902,9 @@ const unichar_t unicode_from_johab[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x3164, 0x3001, 0x3002, 0x30fb, 0x2025, 0x22ef, 0x00a8, 0x3003
};
+#endif
+#ifdef TO_CJK_ICONV
static unsigned short johab_from_unicode_0[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -38147,6 +38171,9 @@ static const unsigned short * const johab_from_unicode_[] = {
struct charmap2 johab_from_unicode = { 0, 255, (unsigned short **) johab_from_unicode_, (unichar_t *) unicode_from_johab };
+#endif
+
+#ifdef FROM_CJK_ICONV
const unichar_t unicode_from_gb2312[] = {
0x3000, 0x3001, 0x3002, 0x00b7, 0x02c9, 0x02c7, 0x00a8, 0x3003,
0x3005, 0x2014, 0xff5e, 0x2016, 0x2026, 0x2018, 0x2019, 0x201c,
@@ -39255,7 +39282,9 @@ const unichar_t unicode_from_gb2312[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x9f44, 0xffffffff, 0x00ff, 0x0000,
0x0100, 0x0003, 0x2288, 0x804f240, 0x0100, 0x0005, 0x00f8, 0x42130a14
};
+#endif
+#ifdef TO_CJK_ICONV
static unsigned short gb2312_from_unicode_0[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -43017,3 +43046,4 @@ static const unsigned short * const gb2312_from_unicode_[] = {
struct charmap2 gb2312_from_unicode = { 0, 255, (unsigned short **) gb2312_from_unicode_, (unichar_t *) unicode_from_gb2312 };
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c
index 5576de5c18e..70f9e064dc3 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c
@@ -114,16 +114,14 @@ static enum encoding name_to_enc(const char *encname) {
{ "mac", e_mac },
{ "Macintosh", e_mac },
{ "MS-ANSI", e_win },
+#ifdef FROM_CJK_ICONV
{ "EUC-KR", e_wansung },
{ "johab", e_johab },
- { "ISO-2022-KR", e_jiskorean },
- { "ISO-2022-CN", e_jisgb },
{ "EUC-CN", e_jisgbpk },
{ "big5", e_big5 },
{ "big5hkscs", e_big5hkscs },
- { "ISO-2022-JP", e_jis },
- { "ISO-2022-JP-2", e_jis2 },
{ "Sjis", e_sjis },
+#endif
{ "UTF-8", e_utf8 },
{ "UTF8", e_utf8 },
{ NULL }};
@@ -242,6 +240,7 @@ return( (size_t) -1 ); /* Incomplete multi-byte sequence */
} else
return( (size_t) -1 );
}
+#ifdef TO_CJK_ICONV
} else if ( cd->to==e_johab || cd->to==e_big5 || cd->to==e_big5hkscs ) {
struct charmap2 *table = cd->to==e_johab ? &johab_from_unicode :
cd->to==e_big5 ? &big5_from_unicode :
@@ -274,6 +273,8 @@ return( (size_t) -1 );
} else
return( (size_t) -1 );
}
+#endif
+#ifdef TO_CJK_ICONV
} else if ( cd->to==e_wansung || cd->to==e_jisgbpk ) {
struct charmap2 *table = cd->to==e_wansung ? &ksc5601_from_unicode :
&gb2312_from_unicode;
@@ -305,6 +306,8 @@ return( (size_t) -1 );
} else
return( (size_t) -1 );
}
+#endif
+#ifdef TO_CJK_ICONV
} else if ( cd->to==e_sjis ) {
unsigned char *plane1;
unsigned short *plane;
@@ -341,39 +344,7 @@ return( (size_t) -1 );
} else
return( (size_t) -1 );
}
- } else if ( cd->to==e_jis || cd->to==e_jis2 ||
- cd->to==e_jiskorean || cd->to==e_jisgb ) {
- struct charmap2 *table = cd->to==e_jisgb ? &gb2312_from_unicode :
- cd->to==e_jiskorean ? &ksc5601_from_unicode :
- &jis_from_unicode;
- unsigned short *plane;
- while ( *inlen>1 && *outlen>1 ) {
- int highch, lowch;
- if ( endian == end_little ) {
- highch = ((unsigned char *) *inbuf)[1], lowch = *(unsigned char *) *inbuf;
- } else {
- highch = *(unsigned char *) *inbuf, lowch = ((unsigned char *) *inbuf)[1];
- }
- if ( highch>=table->first && highch<=table->last &&
- (plane = table->table[highch])!=NULL &&
- (ch=plane[lowch])!=0 ) {
- if ( ch>=0x8000 ) {
- if ( cd->to!=e_jis2 )
-return( (size_t) -1 );
- ch -= 0x8000;
- } else {
- if ( cd->to==e_jis2 )
-return( (size_t) -1 );
- }
- *((*outbuf)++) = (ch>>8);
- *((*outbuf)++) = (ch&0xff);
- *outlen -= 2;
- *inlen -= 2;
- *inbuf += 2;
- ++char_cnt;
- } else
-return( (size_t) -1 );
- }
+#endif
} else if ( cd->to==e_utf8 ) {
while ( *inlen>1 && *outlen>0 ) {
unichar_t uch;
@@ -450,6 +421,7 @@ return( (size_t) -1 ); /* Incomplete multi-byte sequence */
} else
return( (size_t) -1 );
}
+#ifdef TO_CJK_ICONV
} else if ( cd->to==e_johab || cd->to==e_big5 || cd->to==e_big5hkscs ) {
struct charmap2 *table = cd->to==e_johab ? &johab_from_unicode :
cd->to==e_big5 ? &big5_from_unicode :
@@ -482,6 +454,8 @@ return( (size_t) -1 );
} else
return( (size_t) -1 );
}
+#endif
+#ifdef TO_CJK_ICONV
} else if ( cd->to==e_wansung || cd->to==e_jisgbpk ) {
struct charmap2 *table = cd->to==e_wansung ? &ksc5601_from_unicode :
&gb2312_from_unicode;
@@ -513,6 +487,8 @@ return( (size_t) -1 );
} else
return( (size_t) -1 );
}
+#endif
+#ifdef TO_CJK_ICONV
} else if ( cd->to==e_sjis ) {
unsigned char *plane1;
unsigned short *plane;
@@ -549,39 +525,7 @@ return( (size_t) -1 );
} else
return( (size_t) -1 );
}
- } else if ( cd->to==e_jis || cd->to==e_jis2 ||
- cd->to==e_jiskorean || cd->to==e_jisgb ) {
- struct charmap2 *table = cd->to==e_jisgb ? &gb2312_from_unicode :
- cd->to==e_jiskorean ? &ksc5601_from_unicode :
- &jis_from_unicode;
- unsigned short *plane;
- while ( *inlen>1 && *outlen>1 ) {
- int highch, lowch;
- if ( endian == end_little ) {
- highch = ((unsigned char *) *inbuf)[1], lowch = *(unsigned char *) *inbuf;
- } else {
- highch = ((unsigned char *) *inbuf)[2], lowch = ((unsigned char *) *inbuf)[3];
- }
- if ( highch>=table->first && highch<=table->last &&
- (plane = table->table[highch])!=NULL &&
- (ch=plane[lowch])!=0 ) {
- if ( ch>=0x8000 ) {
- if ( cd->to!=e_jis2 )
-return( (size_t) -1 );
- ch -= 0x8000;
- } else {
- if ( cd->to==e_jis2 )
-return( (size_t) -1 );
- }
- *((*outbuf)++) = (ch>>8);
- *((*outbuf)++) = (ch&0xff);
- *outlen -= 2;
- *inlen -= 4;
- *inbuf += 4;
- ++char_cnt;
- } else
-return( (size_t) -1 );
- }
+#endif
} else if ( cd->to==e_utf8 ) {
while ( *inlen>1 && *outlen>0 ) {
int uch;
@@ -648,62 +592,7 @@ return( (size_t) -1 );
*outlen -= sizeof(unichar_t);
++char_cnt;
}
- } else if ( cd->from==e_jis || cd->from==e_jis2 ||
- cd->from==e_jiskorean || cd->from==e_jisgb ) {
- table = cd->from==e_jisgb ? unicode_from_gb2312 :
- cd->from==e_jiskorean ? unicode_from_ksc5601 :
- cd->from==e_jis ? unicode_from_jis208 :
- unicode_from_jis212;
- while ( *inlen>1 && *outlen>1 ) {
- unsigned char *ipt = (unsigned char *) *inbuf;
- int ch;
- if ( *ipt<0x21 || *ipt>0x7e || ipt[1]<0x21 || ipt[1]>0x7e )
-return( (size_t) -1 );
- ch = (*ipt-0x21)*94 + (ipt[1]-0x21);
- ch = table[ch];
- *inlen -= 2;
- *inbuf = (char *) ipt+2;
- if ( endian==end_little ) {
- *((*outbuf)++) = ch&0xff;
- *((*outbuf)++) = ch>>8;
- } else {
- *((*outbuf)++) = ch>>8;
- *((*outbuf)++) = ch&0xff;
- }
- *outlen -= sizeof(unichar_t);
- ++char_cnt;
- }
- if ( *inlen==1 && *outlen>0 )
-return( (size_t) -1 ); /* Incomplete multi-byte sequence */
- } else if ( cd->from==e_wansung || cd->from==e_jisgbpk ) {
- table = cd->from==e_jisgbpk ? unicode_from_gb2312 :
- unicode_from_ksc5601 ;
- while ( *inlen>0 && *outlen>1 ) {
- unsigned char *ipt = (unsigned char *) *inbuf;
- int ch;
- if ( *ipt<0x7f ) {
- ch = *ipt;
- --*inlen;
- *inbuf = (char *) ipt+1;
- } else {
- if ( *ipt<0xa1 || *ipt>0xfe || ipt[1]<0xa1 || ipt[1]>0xfe ||
- *inlen==1 )
-return( (size_t) -1 );
- ch = (*ipt-0xa1)*94 + (ipt[1]-0xa1);
- ch = table[ch];
- *inlen -= 2;;
- *inbuf = (char *) ipt+2;
- }
- if ( endian==end_little ) {
- *((*outbuf)++) = ch&0xff;
- *((*outbuf)++) = ch>>8;
- } else {
- *((*outbuf)++) = ch>>8;
- *((*outbuf)++) = ch&0xff;
- }
- *outlen -= sizeof(unichar_t);
- ++char_cnt;
- }
+#ifdef FROM_CJK_ICONV
} else if ( cd->from==e_johab || cd->from==e_big5 || cd->from==e_big5hkscs ) {
int offset;
if ( cd->from==e_big5 ) {
@@ -786,6 +675,7 @@ return( (size_t) -1 );
*outlen -= sizeof(unichar_t);
++char_cnt;
}
+#endif
} else if ( cd->from==e_utf8 ) {
while ( *inlen>0 && *outlen>sizeof(unichar_t) ) {
unsigned char *ipt = (unsigned char *) *inbuf;
@@ -856,37 +746,7 @@ return( (size_t) -1 );
*outlen -= sizeof(unichar_t);
++char_cnt;
}
- } else if ( cd->from==e_jis || cd->from==e_jis2 ||
- cd->from==e_jiskorean || cd->from==e_jisgb ) {
- table = cd->from==e_jisgb ? unicode_from_gb2312 :
- cd->from==e_jiskorean ? unicode_from_ksc5601 :
- cd->from==e_jis ? unicode_from_jis208 :
- unicode_from_jis212;
- while ( *inlen>1 && *outlen>1 ) {
- unsigned char *ipt = (unsigned char *) *inbuf;
- int ch;
- if ( *ipt<0x21 || *ipt>0x7e || ipt[1]<0x21 || ipt[1]>0x7e )
-return( (size_t) -1 );
- ch = (*ipt-0x21)*94 + (ipt[1]-0x21);
- ch = table[ch];
- *inlen -= 2;
- *inbuf = (char *) ipt+2;
- if ( endian==end_little ) {
- *((*outbuf)++) = 0;
- *((*outbuf)++) = 0;
- *((*outbuf)++) = ch&0xff;
- *((*outbuf)++) = ch>>8;
- } else {
- *((*outbuf)++) = ch>>8;
- *((*outbuf)++) = ch&0xff;
- *((*outbuf)++) = 0;
- *((*outbuf)++) = 0;
- }
- *outlen -= sizeof(unichar_t);
- ++char_cnt;
- }
- if ( *inlen==1 && *outlen>0 )
-return( (size_t) -1 ); /* Incomplete multi-byte sequence */
+#ifdef FROM_CJK_ICONV
} else if ( cd->from==e_wansung || cd->from==e_jisgbpk ) {
table = cd->from==e_jisgbpk ? unicode_from_gb2312 :
unicode_from_ksc5601 ;
@@ -1010,6 +870,7 @@ return( (size_t) -1 );
*outlen -= sizeof(unichar_t);
++char_cnt;
}
+#endif
} else if ( cd->from==e_utf8 ) {
while ( *inlen>0 && *outlen>sizeof(unichar_t) ) {
unsigned char *ipt = (unsigned char *) *inbuf;
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ucharmap.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ucharmap.c
index 316234246a9..b97aa3a633f 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ucharmap.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/Unicode/ucharmap.c
@@ -75,6 +75,7 @@ unichar_t *encoding2u_strncpy(unichar_t *uto, const char *_from, int n, enum enc
fprintf( stderr, "Unexpected encoding %d, I'll pretend it's latin1\n", cs );
}
return( encoding2u_strncpy(uto,_from,n,e_iso8859_1));
+#ifdef FROM_CJK_ICONV
case e_johab: case e_big5: case e_big5hkscs:
if ( cs==e_big5 ) {
offset = 0xa100;
@@ -141,6 +142,7 @@ return( encoding2u_strncpy(uto,_from,n,e_iso8859_1));
--n;
}
break;
+#endif
}
} else if ( cs==e_unicode ) {
unichar_t *ufrom = (unichar_t *) from;
@@ -206,194 +208,6 @@ return( encoding2u_strncpy(uto,_from,n,e_iso8859_1));
return( uto );
}
-char *u2encoding_strncpy(char *to, const unichar_t *ufrom, int n, enum encoding cs) {
- char *pt = to;
-
- /* we just ignore anything that doesn't fit in the encoding we look at */
- if ( cs<e_first2byte ) {
- struct charmap *table = NULL;
- unsigned char *plane;
- table = alphabets_from_unicode[cs];
- if ( table==NULL ) { /* ASCII */
- while ( *ufrom && n>0 ) {
- int ch = *ufrom;
- if ( ch<127 ) {
- *pt++ = ch;
- --n;
- }
- ++ufrom;
- }
- } else {
- while ( *ufrom && n>0 ) {
- int highch = *ufrom>>8, ch;
- if ( highch>=table->first && highch<=table->last &&
- (plane = table->table[highch])!=NULL &&
- (ch=plane[*ufrom&0xff])!=0 ) {
- *pt++ = ch;
- --n;
- }
- ++ufrom;
- }
- }
- if ( n>0 )
- *pt = '\0';
- } else if ( cs<e_unicode ) {
- struct charmap2 *table;
- unsigned short *plane;
- unsigned char *plane1;
-
- *to = '\0';
- switch ( cs ) {
- default:
- if ( !bad_enc_warn ) {
- bad_enc_warn = true;
- fprintf( stderr, "Unexpected encoding %d, I'll pretend it's latin1\n", cs );
- }
-return( u2encoding_strncpy(to,ufrom,n,e_iso8859_1));
- case e_johab: case e_big5: case e_big5hkscs:
- table = cs==e_big5 ? &big5_from_unicode :
- cs==e_big5hkscs ? &big5hkscs_from_unicode :
- &johab_from_unicode;
- while ( *ufrom && n>0 ) {
- int highch = *ufrom>>8, ch;
- if ( *ufrom<0x80 ) {
- *pt++ = *ufrom;
- --n;
- } else if ( highch>=table->first && highch<=table->last &&
- (plane = table->table[highch-table->first])!=NULL &&
- (ch=plane[*ufrom&0xff])!=0 ) {
- *pt++ = ch>>8;
- *pt++ = ch&0xff;
- n -= 2;
- }
- ufrom ++;
- }
- break;
- case e_wansung:
- while ( *ufrom && n>0 ) {
- int highch = *ufrom>>8, ch;
- if ( *ufrom<0x80 ) {
- *pt++ = *ufrom;
- --n;
- } else if ( highch>=ksc5601_from_unicode.first && highch<=ksc5601_from_unicode.last &&
- (plane = ksc5601_from_unicode.table[highch-ksc5601_from_unicode.first])!=NULL &&
- (ch=plane[*ufrom&0xff])!=0 ) {
- *pt++ = (ch>>8) + 0x80;
- *pt++ = (ch&0xff) + 0x80;
- n -= 2;
- }
- ufrom ++;
- }
- break;
- case e_jisgb:
- while ( *ufrom && n>0 ) {
- int highch = *ufrom>>8, ch;
- if ( *ufrom<0x80 ) {
- *pt++ = *ufrom;
- --n;
- } else if ( highch>=gb2312_from_unicode.first && highch<=gb2312_from_unicode.last &&
- (plane = gb2312_from_unicode.table[highch-gb2312_from_unicode.first])!=NULL &&
- (ch=plane[*ufrom&0xff])!=0 ) {
- *pt++ = (ch>>8) + 0x80;
- *pt++ = (ch&0xff) + 0x80;
- n -= 2;
- }
- ufrom ++;
- }
- break;
- case e_sjis:
- while ( *ufrom && n>0 ) {
- int highch = *ufrom>>8, ch;
- if ( highch>=jis201_from_unicode.first && highch<=jis201_from_unicode.last &&
- (plane1 = jis201_from_unicode.table[highch-jis201_from_unicode.first])!=NULL &&
- (ch=plane1[*ufrom&0xff])!=0 ) {
- *pt++ = ch;
- --n;
- } else if ( *ufrom<' ' ) { /* control chars */
- *pt++ = *ufrom;
- --n;
- } else if ( highch>=jis_from_unicode.first && highch<=jis_from_unicode.last &&
- (plane = jis_from_unicode.table[highch-jis_from_unicode.first])!=NULL &&
- (ch=plane[*ufrom&0xff])!=0 && ch<0x8000 ) { /* no jis212 */
- int j1 = ch>>8, j2 = ch&0xff;
- int ro = j1<95 ? 112 : 176;
- int co = (j1&1) ? (j2>95?32:31) : 126;
- *pt++ = ((j1+1)>>1)+ro;
- *pt++ = j2+co;
- n -= 2;
- }
- ++ufrom;
- }
- break;
- }
- if ( n>0 )
- *pt = '\0';
- } else if ( cs==e_unicode ) {
- unichar_t *uto = (unichar_t *) to;
- while ( *ufrom && n>1 ) {
- *uto++ = *ufrom++;
- n-=sizeof(unichar_t);
- }
- if ( n>1 )
- *uto = '\0';
- } else if ( cs==e_unicode_backwards ) {
- unichar_t *uto = (unichar_t *) to;
- while ( *ufrom && n>sizeof(unichar_t)-1 ) {
-#ifdef UNICHAR_16
- unichar_t ch = (*ufrom>>8)|((*ufrom&0xff)<<8);
-#else
- unichar_t ch = (*ufrom>>24)|((*ufrom>>8)&0xff00)|
- ((*ufrom<<8)&0xff0000)|(*ufrom<<24);
-#endif
- *uto++ = ch;
- ++ufrom;
- n-=sizeof(unichar_t);
- }
- if ( n>1 )
- *uto = '\0';
- } else if ( cs==e_utf8 ) {
- while ( *ufrom ) {
- if ( *ufrom<0x80 ) {
- if ( n<=1 )
- break;
- *pt++ = *ufrom;
- --n;
- } else if ( *ufrom<0x800 ) {
- if ( n<=2 )
- break;
- *pt++ = 0xc0 | (*ufrom>>6);
- *pt++ = 0x80 | (*ufrom&0x3f);
- n -= 2;
- } else if ( *ufrom>=0xd800 && *ufrom<0xdc00 && ufrom[1]>=0xdc00 && ufrom[1]<0xe000 ) {
- int u = ((*ufrom>>6)&0xf)+1, y = ((*ufrom&3)<<4) | ((ufrom[1]>>6)&0xf);
- if ( n<=4 )
- break;
- *pt++ = 0xf0 | (u>>2);
- *pt++ = 0x80 | ((u&3)<<4) | ((*ufrom>>2)&0xf);
- *pt++ = 0x80 | y;
- *pt++ = 0x80 | (ufrom[1]&0x3f);
- n -= 4;
- } else {
- if ( n<=3 )
- break;
- *pt++ = 0xe0 | (*ufrom>>12);
- *pt++ = 0x80 | ((*ufrom>>6)&0x3f);
- *pt++ = 0x80 | (*ufrom&0x3f);
- }
- ++ufrom;
- }
- if ( n>1 )
- *pt = '\0';
- } else {
- if ( !bad_enc_warn ) {
- bad_enc_warn = true;
- fprintf( stderr, "Unexpected encoding %d, I'll pretend it's latin1\n", cs );
- }
-return( u2encoding_strncpy(to,ufrom,n,e_iso8859_1));
- }
-
-return( to );
-}
#if HAVE_ICONV_H
static char *old_local_name=NULL;
@@ -522,23 +336,6 @@ return( uto );
return( encoding2u_strncpy(uto,from,n,local_encoding));
}
-char *u2def_strncpy(char *to, const unichar_t *ufrom, int n) {
-#if HAVE_ICONV_H
- if ( my_iconv_setup() ) {
- size_t in_left = sizeof(unichar_t)*n, out_left = n;
- char *cfrom = (char *) ufrom, *cto=to;
- iconv(from_unicode, (iconv_arg2_t) &cfrom, &in_left, &cto, &out_left);
- if ( cto<to+n ) *cto++ = '\0';
- if ( cto<to+n ) *cto++ = '\0';
-#ifndef UNICHAR_16
- if ( cto<to+n ) *cto++ = '\0';
- if ( cto<to+n ) *cto++ = '\0';
-#endif
-return( to );
- }
-#endif
-return( u2encoding_strncpy(to,ufrom,n,local_encoding));
-}
unichar_t *def2u_copy(const char *from) {
int len;
@@ -570,45 +367,6 @@ return( uto );
return( ret );
}
-char *u2def_copy(const unichar_t *ufrom) {
- int len;
- char *to, *ret;
-
- if ( ufrom==NULL )
-return( NULL );
- len = u_strlen(ufrom);
-#if HAVE_ICONV_H
- if ( my_iconv_setup() ) {
- size_t in_left = sizeof(unichar_t)*len, out_left = 3*len;
- char *cfrom = (char *) ufrom, *cto;
- cto = to = galloc(3*len+2);
- iconv(from_unicode, (iconv_arg2_t) &cfrom, &in_left, &cto, &out_left);
- *cto++ = '\0';
- *cto++ = '\0';
-#ifndef UNICHAR_16
- *cto++ = '\0';
- *cto++ = '\0';
-#endif
-return( to );
- }
-#endif
- if ( local_encoding==e_utf8 )
- len *= 3;
- if ( local_encoding>=e_first2byte )
- len *= 2;
- to = galloc(len+sizeof(unichar_t));
- ret = u2encoding_strncpy(to,ufrom,len,local_encoding);
- if ( ret==NULL )
- free( to );
- else if ( local_encoding<e_first2byte )
- to[len] = '\0';
- else {
- to[len] = '\0';
- to[len+1] = '\0';
- }
-return( ret );
-}
-
char *def2utf8_copy(const char *from) {
int len;
char *ret;
@@ -643,33 +401,3 @@ return( NULL );
return( ret );
}
-char *utf82def_copy(const char *ufrom) {
- int len;
- char *ret;
- unichar_t *u2from;
-
- if ( ufrom==NULL )
-return( NULL );
- len = strlen(ufrom);
-#if HAVE_ICONV_H
- if ( my_iconv_setup() ) {
- size_t in_left = len, out_left = 3*len;
- char *cfrom = (char *) ufrom, *cto, *to;
- cto = to = galloc(3*len+2);
- iconv(from_utf8, (iconv_arg2_t) &cfrom, &in_left, &cto, &out_left);
- *cto++ = '\0';
- *cto++ = '\0';
-#ifndef UNICHAR_16
- *cto++ = '\0';
- *cto++ = '\0';
-#endif
-return( to );
- }
-#endif
- if ( local_encoding==e_utf8 )
-return( copy( ufrom )); /* Well that's easy */
- u2from = utf82u_copy(ufrom);
- ret = u2def_copy(u2from);
- free(u2from);
-return( ret );
-}
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c
index a55a3d3d637..38e3b1b3b48 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c
@@ -94,17 +94,21 @@ void FindBlues( SplineFont *sf, int layer, real blues[14], real otherblues[10])
for ( i=0; i<sf->glyphcnt; ++i ) {
if ( sf->glyphs[i]!=NULL && sf->glyphs[i]->layers[layer].splines!=NULL ) {
int enc = sf->glyphs[i]->unicodeenc;
+#ifndef LUA_FF_LIB
const unichar_t *upt;
+#endif
if ( enc<0x10000 && isalnum(enc) &&
((enc>=32 && enc<128 ) || enc == 0xfe || enc==0xf0 || enc==0xdf ||
enc==0x131 ||
(enc>=0x391 && enc<=0x3f3 ) ||
(enc>=0x400 && enc<=0x4e9 ) )) {
/* no accented characters (or ligatures) */
+#ifndef LUA_FF_LIB
if ( unicode_alternates[enc>>8]!=NULL &&
(upt =unicode_alternates[enc>>8][enc&0xff])!=NULL &&
upt[1]!='\0' )
continue;
+#endif
SplineCharFindBounds(sf->glyphs[i],&b);
if ( b.miny==0 && b.maxy==0 )
continue;
@@ -256,16 +260,20 @@ void FindBlues( SplineFont *sf, int layer, real blues[14], real otherblues[10])
base[3] = base[4] = 0;
for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
int enc = sf->glyphs[i]->unicodeenc;
+#ifndef LUA_FF_LIB
const unichar_t *upt;
+#endif
if ( enc<0x10000 && isalnum(enc) &&
((enc>=32 && enc<128 ) || enc == 0xfe || enc==0xf0 || enc==0xdf ||
(enc>=0x391 && enc<=0x3f3 ) ||
(enc>=0x400 && enc<=0x4e9 ) )) {
/* no accented characters (or ligatures) */
+#ifndef LUA_FF_LIB
if ( unicode_alternates[enc>>8]!=NULL &&
(upt =unicode_alternates[enc>>8][enc&0xff])!=NULL &&
upt[1]!='\0' )
continue;
+#endif
SplineCharFindBounds(sf->glyphs[i],&b);
if ( b.miny==0 && b.maxy==0 )
continue;
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c
index 6fccf29e8ae..b4be6b5b5fe 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c
@@ -289,16 +289,8 @@ return( &unicodefull );
/* Mac seems to work ok */
if ( strcasecmp(name,"win")==0 || strcasecmp(name,"ansi")==0 )
iconv_name = "MS-ANSI"; /* "WINDOWS-1252";*/
- else if ( strncasecmp(name,"jis208",6)==0 || strncasecmp(name,"jisx0208",8)==0 )
- iconv_name = "ISO-2022-JP";
- else if ( strncasecmp(name,"jis212",6)==0 || strncasecmp(name,"jisx0212",8)==0 )
- iconv_name = "ISO-2022-JP-2";
- else if ( strncasecmp(name,"ksc5601",7)==0 )
- iconv_name = "ISO-2022-KR";
else if ( strcasecmp(name,"gb2312pk")==0 || strcasecmp(name,"gb2312packed")==0 )
- iconv_name = "EUC-CN";
- else if ( strncasecmp(name,"gb2312",6)==0 )
- iconv_name = "ISO-2022-CN";
+ iconv_name = "EUC-CN";
else if ( strcasecmp(name,"wansung")==0 )
iconv_name = "EUC-KR";
else if ( strcasecmp(name,"EUC-CN")==0 ) {
@@ -720,8 +712,7 @@ return( maybe );
maybefile = NULL;
}
} else {
- file = utf82def_copy(uret);
- free(uret);
+ file = uret; /* no utf82def() call for luatex */
}
}
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c
index 2f92df3e03e..63212410578 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c
@@ -36,15 +36,15 @@
#include "ttf.h"
#include "psfont.h"
#ifdef LUA_FF_LIB
-#undef __Mac
+# undef __Mac
#endif
#if __Mac
-# include <ctype.h>
-# include </Developer/Headers/FlatCarbon/Files.h>
+# include <ctype.h>
+# include </Developer/Headers/FlatCarbon/Files.h>
#else
-# include <utype.h>
-#undef __Mac
-#define __Mac 0
+# include <utype.h>
+# undef __Mac
+# define __Mac 0
#endif
const int mac_dpi = 72;
@@ -123,82 +123,90 @@ struct resourcetype {
struct macbinaryheader {
char *macfilename;
- char *binfilename; /* if macfilename is null and this is set we will figure out macfilename by removing .bin */
+ char *binfilename; /* if macfilename is null and this is set we will figure out macfilename by removing .bin */
uint32 type;
uint32 creator;
};
-
+
enum psstyle_flags { psf_bold = 1, psf_italic = 2, psf_outline = 4,
- psf_shadow = 0x8, psf_condense = 0x10, psf_extend = 0x20 };
+ psf_shadow = 0x8, psf_condense = 0x10, psf_extend = 0x20
+};
-uint16 _MacStyleCode( char *styles, SplineFont *sf, uint16 *psstylecode ) {
- unsigned short stylecode= 0, psstyle=0;
+uint16 _MacStyleCode(char *styles, SplineFont * sf, uint16 * psstylecode)
+{
+ unsigned short stylecode = 0, psstyle = 0;
- if ( strstrmatch( styles, "Bold" ) || strstrmatch(styles,"Demi") ||
- strstrmatch( styles,"Heav") || strstrmatch(styles,"Blac") ||
+ if (strstrmatch(styles, "Bold") || strstrmatch(styles, "Demi") ||
+ strstrmatch(styles, "Heav") || strstrmatch(styles, "Blac") ||
/* A few fonts have German/French styles in their names */
- strstrmatch( styles,"Fett") || strstrmatch(styles,"Gras") ) {
- stylecode = sf_bold;
- psstyle = psf_bold;
- } else if ( sf!=NULL && sf->weight!=NULL &&
- (strstrmatch( sf->weight, "Bold" ) || strstrmatch(sf->weight,"Demi") ||
- strstrmatch( sf->weight,"Heav") || strstrmatch(sf->weight,"Blac") ||
- strstrmatch( sf->weight,"Fett") || strstrmatch(sf->weight,"Gras")) ) {
- stylecode = sf_bold;
- psstyle = psf_bold;
+ strstrmatch(styles, "Fett") || strstrmatch(styles, "Gras")) {
+ stylecode = sf_bold;
+ psstyle = psf_bold;
+ } else if (sf != NULL && sf->weight != NULL &&
+ (strstrmatch(sf->weight, "Bold")
+ || strstrmatch(sf->weight, "Demi")
+ || strstrmatch(sf->weight, "Heav")
+ || strstrmatch(sf->weight, "Blac")
+ || strstrmatch(sf->weight, "Fett")
+ || strstrmatch(sf->weight, "Gras"))) {
+ stylecode = sf_bold;
+ psstyle = psf_bold;
}
/* URW uses four leter abbreviations of Italic and Oblique */
/* Somebody else uses two letter abbrevs */
- if ( (sf!=NULL && sf->italicangle!=0) ||
- strstrmatch( styles, "Ital" ) ||
- strstrmatch( styles, "Obli" ) ||
- strstrmatch(styles, "Slanted") ||
- strstrmatch(styles, "Kurs") ||
- strstr( styles,"It" ) ) {
- stylecode |= sf_italic;
- psstyle |= psf_italic;
+ if ((sf != NULL && sf->italicangle != 0) ||
+ strstrmatch(styles, "Ital") ||
+ strstrmatch(styles, "Obli") ||
+ strstrmatch(styles, "Slanted") ||
+ strstrmatch(styles, "Kurs") || strstr(styles, "It")) {
+ stylecode |= sf_italic;
+ psstyle |= psf_italic;
}
- if ( strstrmatch( styles, "Underline" ) ) {
- stylecode |= sf_underline;
+ if (strstrmatch(styles, "Underline")) {
+ stylecode |= sf_underline;
}
- if ( strstrmatch( styles, "Outl" ) ) {
- stylecode |= sf_outline;
- psstyle |= psf_outline;
+ if (strstrmatch(styles, "Outl")) {
+ stylecode |= sf_outline;
+ psstyle |= psf_outline;
}
- if ( strstr(styles,"Shadow")!=NULL ) {
- stylecode |= sf_shadow;
- psstyle |= psf_shadow;
+ if (strstr(styles, "Shadow") != NULL) {
+ stylecode |= sf_shadow;
+ psstyle |= psf_shadow;
}
- if ( strstrmatch( styles, "Cond" ) || strstr( styles,"Cn") ||
- strstrmatch( styles, "Narrow") ) {
- stylecode |= sf_condense;
- psstyle |= psf_condense;
+ if (strstrmatch(styles, "Cond") || strstr(styles, "Cn") ||
+ strstrmatch(styles, "Narrow")) {
+ stylecode |= sf_condense;
+ psstyle |= psf_condense;
}
- if ( strstrmatch( styles, "Exte" ) || strstr( styles,"Ex") ) {
- stylecode |= sf_extend;
- psstyle |= psf_extend;
+ if (strstrmatch(styles, "Exte") || strstr(styles, "Ex")) {
+ stylecode |= sf_extend;
+ psstyle |= psf_extend;
}
- if ( (psstyle&psf_extend) && (psstyle&psf_condense) ) {
- if ( sf!=NULL )
- LogError( _("Warning: %s(%s) is both extended and condensed. That's impossible.\n"),
- sf->fontname, sf->origname );
- else
- LogError( _("Warning: Both extended and condensed. That's impossible.\n") );
- psstyle &= ~psf_extend;
- stylecode &= ~sf_extend;
+ if ((psstyle & psf_extend) && (psstyle & psf_condense)) {
+ if (sf != NULL)
+ LogError(_
+ ("Warning: %s(%s) is both extended and condensed. That's impossible.\n"),
+ sf->fontname, sf->origname);
+ else
+ LogError(_
+ ("Warning: Both extended and condensed. That's impossible.\n"));
+ psstyle &= ~psf_extend;
+ stylecode &= ~sf_extend;
}
- if ( psstylecode!=NULL )
- *psstylecode = psstyle;
-return( stylecode );
+ if (psstylecode != NULL)
+ *psstylecode = psstyle;
+ return (stylecode);
}
/* ******************************** Reading ********************************* */
-static SplineFont *SearchPostscriptResources(FILE *f,long rlistpos,int subcnt,long rdata_pos,
- long name_list, int flags) {
+static SplineFont *SearchPostscriptResources(FILE * f, long rlistpos,
+ int subcnt, long rdata_pos,
+ long name_list, int flags)
+{
long here = ftell(f);
long *offsets, lenpos;
int rname = -1, tmp;
@@ -209,242 +217,257 @@ static SplineFont *SearchPostscriptResources(FILE *f,long rlistpos,int subcnt,lo
/* postscript font. It appears to be split up into chunks where the */
/* maximum chunk size is 0x800, each section (ascii, binary, ascii, eof) */
/* has its own set of chunks (ie chunks don't cross sections) */
- char *buffer=NULL;
+ char *buffer = NULL;
int max = 0;
FILE *pfb;
FontDict *fd;
SplineFont *sf;
- (void)name_list;
- fseek(f,rlistpos,SEEK_SET);
- rsrcids = gcalloc(subcnt,sizeof(short));
- offsets = gcalloc(subcnt,sizeof(long));
- for ( i=0; i<subcnt; ++i ) {
- rsrcids[i] = getushort(f);
- tmp = (short) getushort(f);
- if ( rname==-1 ) rname = tmp;
- /* flags = */ getc(f);
- ch1 = getc(f); ch2 = getc(f);
- offsets[i] = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f));
- /* mbz = */ getlong(f);
+ (void) name_list;
+ fseek(f, rlistpos, SEEK_SET);
+ rsrcids = gcalloc(subcnt, sizeof(short));
+ offsets = gcalloc(subcnt, sizeof(long));
+ for (i = 0; i < subcnt; ++i) {
+ rsrcids[i] = getushort(f);
+ tmp = (short) getushort(f);
+ if (rname == -1)
+ rname = tmp;
+ /* flags = */ getc(f);
+ ch1 = getc(f);
+ ch2 = getc(f);
+ offsets[i] = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f));
+ /* mbz = */ getlong(f);
}
pfb = tmpfile();
- if ( pfb==NULL ) {
- LogError( _("Can't open temporary file for postscript output\n") );
- fseek(f,here,SEEK_SET );
- free(offsets);
-return(NULL);
+ if (pfb == NULL) {
+ LogError(_("Can't open temporary file for postscript output\n"));
+ fseek(f, here, SEEK_SET);
+ free(offsets);
+ return (NULL);
}
- putc(0x80,pfb);
- putc(1,pfb);
+ putc(0x80, pfb);
+ putc(1, pfb);
lenpos = ftell(pfb);
- putc(0,pfb);
- putc(0,pfb);
- putc(0,pfb);
- putc(0,pfb);
- len = 0; type = 1;
+ putc(0, pfb);
+ putc(0, pfb);
+ putc(0, pfb);
+ putc(0, pfb);
+ len = 0;
+ type = 1;
id = 501;
- for ( i=0; i<subcnt; ++i ) {
- for ( j=0; j<subcnt; ++j )
- if ( rsrcids[j]==id )
- break;
- if ( j == subcnt ) {
- LogError( _("Missing POST resource %u\n"), id );
- break;
- }
- id = id + 1;
- fseek(f,offsets[j],SEEK_SET);
- rlen = getlong(f);
- ch1 = getc(f); ch2 = getc(f);
- rlen -= 2; /* those two bytes don't count as real data */
- if ( ch1==type )
- len += rlen;
- else {
- long hold = ftell(pfb);
- fseek(pfb,lenpos,SEEK_SET);
- putc(len>>24,pfb);
- putc((len>>16)&0xff,pfb);
- putc((len>>8)&0xff,pfb);
- putc(len&0xff,pfb);
- fseek(pfb,hold,SEEK_SET);
- if ( ch1==5 ) /* end of font mark */
- break;
- putc(0x80,pfb);
- putc(ch1,pfb);
- lenpos = ftell(pfb);
- putc(0,pfb);
- putc(0,pfb);
- putc(0,pfb);
- putc(0,pfb);
- type = ch1;
- len = rlen;
- }
- if ( rlen>max ) {
- free(buffer);
- max = rlen;
- if ( max<0x800 ) max = 0x800;
- buffer=galloc(max);
- if ( buffer==NULL ) {
- LogError( _("Out of memory\n") );
- exit( 1 );
- }
- }
- fread(buffer,1,rlen,f);
- fwrite(buffer,1,rlen,pfb);
+ for (i = 0; i < subcnt; ++i) {
+ for (j = 0; j < subcnt; ++j)
+ if (rsrcids[j] == id)
+ break;
+ if (j == subcnt) {
+ LogError(_("Missing POST resource %u\n"), id);
+ break;
+ }
+ id = id + 1;
+ fseek(f, offsets[j], SEEK_SET);
+ rlen = getlong(f);
+ ch1 = getc(f);
+ ch2 = getc(f);
+ rlen -= 2; /* those two bytes don't count as real data */
+ if (ch1 == type)
+ len += rlen;
+ else {
+ long hold = ftell(pfb);
+ fseek(pfb, lenpos, SEEK_SET);
+ putc(len >> 24, pfb);
+ putc((len >> 16) & 0xff, pfb);
+ putc((len >> 8) & 0xff, pfb);
+ putc(len & 0xff, pfb);
+ fseek(pfb, hold, SEEK_SET);
+ if (ch1 == 5) /* end of font mark */
+ break;
+ putc(0x80, pfb);
+ putc(ch1, pfb);
+ lenpos = ftell(pfb);
+ putc(0, pfb);
+ putc(0, pfb);
+ putc(0, pfb);
+ putc(0, pfb);
+ type = ch1;
+ len = rlen;
+ }
+ if (rlen > max) {
+ free(buffer);
+ max = rlen;
+ if (max < 0x800)
+ max = 0x800;
+ buffer = galloc(max);
+ if (buffer == NULL) {
+ LogError(_("Out of memory\n"));
+ exit(1);
+ }
+ }
+ fread(buffer, 1, rlen, f);
+ fwrite(buffer, 1, rlen, pfb);
}
free(buffer);
free(offsets);
- free(rsrcids);
- putc(0x80,pfb);
- putc(3,pfb);
- fseek(pfb,lenpos,SEEK_SET);
- putc(len>>24,pfb);
- putc((len>>16)&0xff,pfb);
- putc((len>>8)&0xff,pfb);
- putc(len&0xff,pfb);
- fseek(f,here,SEEK_SET);
+ free(rsrcids);
+ putc(0x80, pfb);
+ putc(3, pfb);
+ fseek(pfb, lenpos, SEEK_SET);
+ putc(len >> 24, pfb);
+ putc((len >> 16) & 0xff, pfb);
+ putc((len >> 8) & 0xff, pfb);
+ putc(len & 0xff, pfb);
+ fseek(f, here, SEEK_SET);
rewind(pfb);
- if ( flags&ttf_onlynames )
-return( (SplineFont *) _NamesReadPostscript(pfb) ); /* This closes the font for us */
+ if (flags & ttf_onlynames)
+ return ((SplineFont *) _NamesReadPostscript(pfb)); /* This closes the font for us */
fd = _ReadPSFont(pfb);
sf = NULL;
- if ( fd!=NULL ) {
- sf = SplineFontFromPSFont(fd);
- PSFontFree(fd);
- /* There is no FOND in a postscript file, so we can't read any kerning*/
+ if (fd != NULL) {
+ sf = SplineFontFromPSFont(fd);
+ PSFontFree(fd);
+ /* There is no FOND in a postscript file, so we can't read any kerning */
}
fclose(pfb);
-return( sf );
+ return (sf);
}
-static SplineFont *SearchTtfResources(FILE *f,long rlistpos,int subcnt,long rdata_pos,
- long name_list,char *filename,int flags,enum openflags openflags) {
+static SplineFont *SearchTtfResources(FILE * f, long rlistpos, int subcnt,
+ long rdata_pos, long name_list,
+ char *filename, int flags,
+ enum openflags openflags)
+{
long here, start = ftell(f);
long roff;
int rname = -1;
int ch1, ch2;
int len, i, rlen, ilen;
/* The sfnt resource is just a copy of the ttf file */
- char *buffer=NULL;
+ char *buffer = NULL;
int max = 0;
FILE *ttf;
SplineFont *sf;
int which = 0;
char **names;
- char *pt,*lparen, *rparen;
- char *chosenname=NULL;
- (void)name_list;
- fseek(f,rlistpos,SEEK_SET);
- if ( subcnt>1 || (flags&ttf_onlynames) ) {
- names = gcalloc(subcnt+1,sizeof(char *));
- for ( i=0; i<subcnt; ++i ) {
- /* resource id = */ getushort(f);
- /* rname = (short) */ getushort(f);
- /* flags = */ getc(f);
- ch1 = getc(f); ch2 = getc(f);
- roff = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f));
- /* mbz = */ getlong(f);
- here = ftell(f);
- names[i] = TTFGetFontName(f,roff+4,roff+4);
- if ( names[i]==NULL ) {
- char buffer[32];
- sprintf( buffer, "Nameless%d", i );
- names[i] = copy(buffer);
- }
- fseek(f,here,SEEK_SET);
- }
- if ( flags&ttf_onlynames ) {
-return( (SplineFont *) names );
- }
- if ((pt = strrchr(filename,'/'))==NULL ) pt = filename;
- /* Someone gave me a font "Nafees Nastaleeq(Updated).ttf" and complained */
- /* that ff wouldn't open it */
- /* Now someone will complain about "Nafees(Updated).ttc(fo(ob)ar)" */
- if ( (lparen = strrchr(pt,'('))!=NULL &&
- (rparen = strrchr(lparen,')'))!=NULL &&
- rparen[1]=='\0' ) {
- char *find = copy(lparen+1);
- pt = strchr(find,')');
- if ( pt!=NULL ) *pt='\0';
- for ( which=subcnt-1; which>=0; --which )
- if ( strcmp(names[which],find)==0 )
- break;
- if ( which==-1 ) {
- char *end;
- which = strtol(find,&end,10);
- if ( *end!='\0' )
- which = -1;
- }
- if ( which==-1 ) {
- char *fn = copy(filename);
- fn[lparen-filename] = '\0';
- ff_post_error(_("Not in Collection"),_("%s is not in %.100s"),find,fn);
- free(fn);
- }
- free(find);
- } else
- which = 0;
- if ( lparen==NULL && which!=-1 )
- chosenname = copy(names[which]);
- for ( i=0; i<subcnt; ++i )
- free(names[i]);
- free(names);
- fseek(f,rlistpos,SEEK_SET);
+ char *pt, *lparen, *rparen;
+ char *chosenname = NULL;
+ (void) name_list;
+ fseek(f, rlistpos, SEEK_SET);
+ if (subcnt > 1 || (flags & ttf_onlynames)) {
+ names = gcalloc(subcnt + 1, sizeof(char *));
+ for (i = 0; i < subcnt; ++i) {
+ /* resource id = */ getushort(f);
+ /* rname = (short) */ getushort(f);
+ /* flags = */ getc(f);
+ ch1 = getc(f);
+ ch2 = getc(f);
+ roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f));
+ /* mbz = */ getlong(f);
+ here = ftell(f);
+ names[i] = TTFGetFontName(f, roff + 4, roff + 4);
+ if (names[i] == NULL) {
+ char buffer[32];
+ sprintf(buffer, "Nameless%d", i);
+ names[i] = copy(buffer);
+ }
+ fseek(f, here, SEEK_SET);
+ }
+ if (flags & ttf_onlynames) {
+ return ((SplineFont *) names);
+ }
+ if ((pt = strrchr(filename, '/')) == NULL)
+ pt = filename;
+ /* Someone gave me a font "Nafees Nastaleeq(Updated).ttf" and complained */
+ /* that ff wouldn't open it */
+ /* Now someone will complain about "Nafees(Updated).ttc(fo(ob)ar)" */
+ if ((lparen = strrchr(pt, '(')) != NULL &&
+ (rparen = strrchr(lparen, ')')) != NULL && rparen[1] == '\0') {
+ char *find = copy(lparen + 1);
+ pt = strchr(find, ')');
+ if (pt != NULL)
+ *pt = '\0';
+ for (which = subcnt - 1; which >= 0; --which)
+ if (strcmp(names[which], find) == 0)
+ break;
+ if (which == -1) {
+ char *end;
+ which = strtol(find, &end, 10);
+ if (*end != '\0')
+ which = -1;
+ }
+ if (which == -1) {
+ char *fn = copy(filename);
+ fn[lparen - filename] = '\0';
+ ff_post_error(_("Not in Collection"), _("%s is not in %.100s"),
+ find, fn);
+ free(fn);
+ }
+ free(find);
+ } else
+ which = 0;
+ if (lparen == NULL && which != -1)
+ chosenname = copy(names[which]);
+ for (i = 0; i < subcnt; ++i)
+ free(names[i]);
+ free(names);
+ fseek(f, rlistpos, SEEK_SET);
}
- for ( i=0; i<subcnt; ++i ) {
- /* resource id = */ getushort(f);
- rname = (short) getushort(f);
- /* flags = */ getc(f);
- ch1 = getc(f); ch2 = getc(f);
- roff = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f));
- /* mbz = */ getlong(f);
- if ( i!=which )
- continue;
- here = ftell(f);
-
- ttf = tmpfile();
- if ( ttf==NULL ) {
- LogError( _("Can't open temporary file for truetype output.\n") );
- continue;
- }
-
- fseek(f,roff,SEEK_SET);
- ilen = rlen = getlong(f);
- if ( rlen>16*1024 )
- ilen = 16*1024;
- if ( ilen>max ) {
- free(buffer);
- max = ilen;
- if ( max<0x800 ) max = 0x800;
- buffer=malloc(max);
- }
- for ( len=0; len<rlen; ) {
- int temp = ilen;
- if ( rlen-len<ilen ) temp = rlen-len;
- temp = fread(buffer,1,temp,f);
- if ( temp==EOF )
- break;
- fwrite(buffer,1,temp,ttf);
- len += temp;
- }
- rewind(ttf);
- sf = _SFReadTTF(ttf,flags,openflags,NULL,NULL);
- fclose(ttf);
- if ( sf!=NULL ) {
- free(buffer);
- fseek(f,start,SEEK_SET);
- if ( sf->chosenname==NULL ) sf->chosenname = chosenname;
-return( sf );
- }
- fseek(f,here,SEEK_SET);
+ for (i = 0; i < subcnt; ++i) {
+ /* resource id = */ getushort(f);
+ rname = (short) getushort(f);
+ /* flags = */ getc(f);
+ ch1 = getc(f);
+ ch2 = getc(f);
+ roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f));
+ /* mbz = */ getlong(f);
+ if (i != which)
+ continue;
+ here = ftell(f);
+
+ ttf = tmpfile();
+ if (ttf == NULL) {
+ LogError(_("Can't open temporary file for truetype output.\n"));
+ continue;
+ }
+
+ fseek(f, roff, SEEK_SET);
+ ilen = rlen = getlong(f);
+ if (rlen > 16 * 1024)
+ ilen = 16 * 1024;
+ if (ilen > max) {
+ free(buffer);
+ max = ilen;
+ if (max < 0x800)
+ max = 0x800;
+ buffer = malloc(max);
+ }
+ for (len = 0; len < rlen;) {
+ int temp = ilen;
+ if (rlen - len < ilen)
+ temp = rlen - len;
+ temp = fread(buffer, 1, temp, f);
+ if (temp == EOF)
+ break;
+ fwrite(buffer, 1, temp, ttf);
+ len += temp;
+ }
+ rewind(ttf);
+ sf = _SFReadTTF(ttf, flags, openflags, NULL, NULL);
+ fclose(ttf);
+ if (sf != NULL) {
+ free(buffer);
+ fseek(f, start, SEEK_SET);
+ if (sf->chosenname == NULL)
+ sf->chosenname = chosenname;
+ return (sf);
+ }
+ fseek(f, here, SEEK_SET);
}
free(chosenname);
free(buffer);
- fseek(f,start,SEEK_SET);
-return( NULL );
+ fseek(f, start, SEEK_SET);
+ return (NULL);
}
typedef struct fond {
@@ -452,69 +475,70 @@ typedef struct fond {
int first, last;
int assoc_cnt;
struct assoc {
- short size, style, id;
+ short size, style, id;
} *assoc;
- /* size==0 => scalable */
- /* style>>8 is the bit depth (0=>1, 1=>2, 2=>4, 3=>8) */
- /* search order for ID is sfnt, NFNT, FONT */
+ /* size==0 => scalable */
+ /* style>>8 is the bit depth (0=>1, 1=>2, 2=>4, 3=>8) */
+ /* search order for ID is sfnt, NFNT, FONT */
int stylewidthcnt;
struct stylewidths {
- short style;
- short *widthtab; /* 4.12 fixed number with the width specified as a fraction of an em */
+ short style;
+ short *widthtab; /* 4.12 fixed number with the width specified as a fraction of an em */
} *stylewidths;
int stylekerncnt;
struct stylekerns {
- short style;
- int kernpairs;
- struct kerns {
- unsigned char ch1, ch2;
- short offset; /* 4.12 */
- } *kerns;
+ short style;
+ int kernpairs;
+ struct kerns {
+ unsigned char ch1, ch2;
+ short offset; /* 4.12 */
+ } *kerns;
} *stylekerns;
char *psnames[48];
struct fond *next;
} FOND;
struct MacFontRec {
- short fontType;
- short firstChar;
- short lastChar;
- short widthMax;
- short kernMax; /* bb learing */
- short Descent; /* maximum negative distance below baseline*/
- short fRectWidth; /* bounding box width */
- short fRectHeight; /* bounding box height */
- unsigned short *offsetWidths;/* offset to start of offset/width table */
- /* 0xffff => undefined, else high byte is offset in locTable, */
- /* low byte is width */
- short ascent;
- short descent;
- short leading;
- short rowWords; /* shorts per row */
- unsigned short *fontImage; /* rowWords*fRectHeight */
- /* Images for all characters plus one extra for undefined */
- unsigned short *locs; /* lastchar-firstchar+3 words */
- /* Horizontal offset to start of n'th character. Note: applies */
- /* to each row. Missing characters have same loc as following */
+ short fontType;
+ short firstChar;
+ short lastChar;
+ short widthMax;
+ short kernMax; /* bb learing */
+ short Descent; /* maximum negative distance below baseline */
+ short fRectWidth; /* bounding box width */
+ short fRectHeight; /* bounding box height */
+ unsigned short *offsetWidths; /* offset to start of offset/width table */
+ /* 0xffff => undefined, else high byte is offset in locTable, */
+ /* low byte is width */
+ short ascent;
+ short descent;
+ short leading;
+ short rowWords; /* shorts per row */
+ unsigned short *fontImage; /* rowWords*fRectHeight */
+ /* Images for all characters plus one extra for undefined */
+ unsigned short *locs; /* lastchar-firstchar+3 words */
+ /* Horizontal offset to start of n'th character. Note: applies */
+ /* to each row. Missing characters have same loc as following */
};
-static void FondListFree(FOND *list) {
+static void FondListFree(FOND * list)
+{
FOND *next;
int i;
- while ( list!=NULL ) {
- next = list->next;
- free(list->assoc);
- for ( i=0; i<list->stylewidthcnt; ++i )
- free(list->stylewidths[i].widthtab);
- free(list->stylewidths);
- for ( i=0; i<list->stylekerncnt; ++i )
- free(list->stylekerns[i].kerns);
- free(list->stylekerns);
- for ( i=0; i<48; ++i )
- free(list->psnames[i]);
- free(list);
- list = next;
+ while (list != NULL) {
+ next = list->next;
+ free(list->assoc);
+ for (i = 0; i < list->stylewidthcnt; ++i)
+ free(list->stylewidths[i].widthtab);
+ free(list->stylewidths);
+ for (i = 0; i < list->stylekerncnt; ++i)
+ free(list->stylekerns[i].kerns);
+ free(list->stylekerns);
+ for (i = 0; i < 48; ++i)
+ free(list->psnames[i]);
+ free(list);
+ list = next;
}
}
@@ -526,180 +550,190 @@ static void FondListFree(FOND *list) {
/* to get the font association tables */
/* to get the style flags */
/* http://developer.apple.com/techpubs/mac/Text/Text-269.html */
-static FOND *BuildFondList(FILE *f,long rlistpos,int subcnt,long rdata_pos,
- long name_list,int flags) {
+static FOND *BuildFondList(FILE * f, long rlistpos, int subcnt, long rdata_pos,
+ long name_list, int flags)
+{
long here, start = ftell(f);
long offset;
int rname = -1;
char name[300];
int ch1, ch2;
int i, j, k, cnt, isfixed;
- FOND *head=NULL, *cur;
+ FOND *head = NULL, *cur;
long widoff, kernoff, styleoff;
- fseek(f,rlistpos,SEEK_SET);
- for ( i=0; i<subcnt; ++i ) {
- /* resource id = */ getushort(f);
- rname = (short) getushort(f);
- /* flags = */ getc(f);
- ch1 = getc(f); ch2 = getc(f);
- offset = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f));
- /* mbz = */ getlong(f);
- here = ftell(f);
-
- cur = gcalloc(1,sizeof(FOND));
- cur->next = head;
- head = cur;
-
- if ( rname!=-1 ) {
- fseek(f,name_list+rname,SEEK_SET);
- ch1 = getc(f);
- fread(name,1,ch1,f);
- name[ch1] = '\0';
- cur->fondname = copy(name);
- }
-
- offset += 4;
- fseek(f,offset,SEEK_SET);
- isfixed = getushort(f)&0x8000?1:0;
- /* family id = */ getushort(f);
- cur->first = getushort(f);
- cur->last = getushort(f);
+ fseek(f, rlistpos, SEEK_SET);
+ for (i = 0; i < subcnt; ++i) {
+ /* resource id = */ getushort(f);
+ rname = (short) getushort(f);
+ /* flags = */ getc(f);
+ ch1 = getc(f);
+ ch2 = getc(f);
+ offset = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f));
+ /* mbz = */ getlong(f);
+ here = ftell(f);
+
+ cur = gcalloc(1, sizeof(FOND));
+ cur->next = head;
+ head = cur;
+
+ if (rname != -1) {
+ fseek(f, name_list + rname, SEEK_SET);
+ ch1 = getc(f);
+ fread(name, 1, ch1, f);
+ name[ch1] = '\0';
+ cur->fondname = copy(name);
+ }
+
+ offset += 4;
+ fseek(f, offset, SEEK_SET);
+ isfixed = getushort(f) & 0x8000 ? 1 : 0;
+ /* family id = */ getushort(f);
+ cur->first = getushort(f);
+ cur->last = getushort(f);
/* on a 1 point font... */
- /* ascent = */ getushort(f);
- /* descent = (short) */ getushort(f);
- /* leading = */ getushort(f);
- /* widmax = */ getushort(f);
- if ( (widoff = getlong(f))!=0 ) widoff += offset;
- if ( (kernoff = getlong(f))!=0 ) kernoff += offset;
- if ( (styleoff = getlong(f))!=0 ) styleoff += offset;
- for ( j=0; j<9; ++j )
- getushort(f);
- /* internal & undefined, for international scripts = */ getlong(f);
- /* version = */ getushort(f);
- cur->assoc_cnt = getushort(f)+1;
- cur->assoc = gcalloc(cur->assoc_cnt,sizeof(struct assoc));
- for ( j=0; j<cur->assoc_cnt; ++j ) {
- cur->assoc[j].size = getushort(f);
- cur->assoc[j].style = getushort(f);
- cur->assoc[j].id = getushort(f);
- }
- if ( widoff!=0 ) {
- fseek(f,widoff,SEEK_SET);
- cnt = getushort(f)+1;
- cur->stylewidthcnt = cnt;
- cur->stylewidths = gcalloc(cnt,sizeof(struct stylewidths));
- for ( j=0; j<cnt; ++j ) {
- cur->stylewidths[j].style = getushort(f);
- cur->stylewidths[j].widthtab = galloc((cur->last-cur->first+3)*sizeof(short));
- for ( k=cur->first; k<=cur->last+2; ++k )
- cur->stylewidths[j].widthtab[k] = getushort(f);
- }
- }
- if ( kernoff!=0 && (flags&ttf_onlykerns) ) {
- fseek(f,kernoff,SEEK_SET);
- cnt = getushort(f)+1;
- cur->stylekerncnt = cnt;
- cur->stylekerns = gcalloc(cnt,sizeof(struct stylekerns));
- for ( j=0; j<cnt; ++j ) {
- cur->stylekerns[j].style = getushort(f);
- cur->stylekerns[j].kernpairs = getushort(f);
- cur->stylekerns[j].kerns = galloc(cur->stylekerns[j].kernpairs*sizeof(struct kerns));
- for ( k=0; k<cur->stylekerns[j].kernpairs; ++k ) {
- cur->stylekerns[j].kerns[k].ch1 = getc(f);
- cur->stylekerns[j].kerns[k].ch2 = getc(f);
- cur->stylekerns[j].kerns[k].offset = getushort(f);
- }
- }
- }
- if ( styleoff!=0 ) {
- uint8 stringoffsets[48];
- int strcnt, stringlen, format;
- char **strings, *pt;
- fseek(f,styleoff,SEEK_SET);
- /* class = */ getushort(f);
- /* glyph encoding offset = */ getlong(f);
- /* reserved = */ getlong(f);
- for ( j=0; j<48; ++j )
- stringoffsets[j] = getc(f);
- strcnt = getushort(f);
- strings = galloc(strcnt*sizeof(char *));
- for ( j=0; j<strcnt; ++j ) {
- stringlen = getc(f);
- strings[j] = galloc(stringlen+2);
- strings[j][0] = stringlen;
- strings[j][stringlen+1] = '\0';
- for ( k=0; k<stringlen; ++k )
- strings[j][k+1] = getc(f);
- }
- for ( j=0; j<48; ++j ) {
- for ( k=j-1; k>=0; --k )
- if ( stringoffsets[j]==stringoffsets[k] )
- break;
- if ( k!=-1 )
- continue; /* this style doesn't exist */
- format = stringoffsets[j]-1;
- stringlen = strings[0][0];
- if ( format!=0 )
- for ( k=0; k<strings[format][0]; ++k )
- stringlen += strings[ strings[format][k+1]-1 ][0];
- pt = cur->psnames[j] = galloc(stringlen+1);
- strcpy(pt,strings[ 0 ]+1);
- pt += strings[ 0 ][0];
- if ( format!=0 )
- for ( k=0; k<strings[format][0]; ++k ) {
- strcpy(pt,strings[ strings[format][k+1]-1 ]+1);
- pt += strings[ strings[format][k+1]-1 ][0];
- }
- *pt = '\0';
- }
- for ( j=0; j<strcnt; ++j )
- free(strings[j]);
- free(strings);
- }
- fseek(f,here,SEEK_SET);
+ /* ascent = */ getushort(f);
+ /* descent = (short) */ getushort(f);
+ /* leading = */ getushort(f);
+ /* widmax = */ getushort(f);
+ if ((widoff = getlong(f)) != 0)
+ widoff += offset;
+ if ((kernoff = getlong(f)) != 0)
+ kernoff += offset;
+ if ((styleoff = getlong(f)) != 0)
+ styleoff += offset;
+ for (j = 0; j < 9; ++j)
+ getushort(f);
+ /* internal & undefined, for international scripts = */ getlong(f);
+ /* version = */ getushort(f);
+ cur->assoc_cnt = getushort(f) + 1;
+ cur->assoc = gcalloc(cur->assoc_cnt, sizeof(struct assoc));
+ for (j = 0; j < cur->assoc_cnt; ++j) {
+ cur->assoc[j].size = getushort(f);
+ cur->assoc[j].style = getushort(f);
+ cur->assoc[j].id = getushort(f);
+ }
+ if (widoff != 0) {
+ fseek(f, widoff, SEEK_SET);
+ cnt = getushort(f) + 1;
+ cur->stylewidthcnt = cnt;
+ cur->stylewidths = gcalloc(cnt, sizeof(struct stylewidths));
+ for (j = 0; j < cnt; ++j) {
+ cur->stylewidths[j].style = getushort(f);
+ cur->stylewidths[j].widthtab =
+ galloc((cur->last - cur->first + 3) * sizeof(short));
+ for (k = cur->first; k <= cur->last + 2; ++k)
+ cur->stylewidths[j].widthtab[k] = getushort(f);
+ }
+ }
+ if (kernoff != 0 && (flags & ttf_onlykerns)) {
+ fseek(f, kernoff, SEEK_SET);
+ cnt = getushort(f) + 1;
+ cur->stylekerncnt = cnt;
+ cur->stylekerns = gcalloc(cnt, sizeof(struct stylekerns));
+ for (j = 0; j < cnt; ++j) {
+ cur->stylekerns[j].style = getushort(f);
+ cur->stylekerns[j].kernpairs = getushort(f);
+ cur->stylekerns[j].kerns =
+ galloc(cur->stylekerns[j].kernpairs * sizeof(struct kerns));
+ for (k = 0; k < cur->stylekerns[j].kernpairs; ++k) {
+ cur->stylekerns[j].kerns[k].ch1 = getc(f);
+ cur->stylekerns[j].kerns[k].ch2 = getc(f);
+ cur->stylekerns[j].kerns[k].offset = getushort(f);
+ }
+ }
+ }
+ if (styleoff != 0) {
+ uint8 stringoffsets[48];
+ int strcnt, stringlen, format;
+ char **strings, *pt;
+ fseek(f, styleoff, SEEK_SET);
+ /* class = */ getushort(f);
+ /* glyph encoding offset = */ getlong(f);
+ /* reserved = */ getlong(f);
+ for (j = 0; j < 48; ++j)
+ stringoffsets[j] = getc(f);
+ strcnt = getushort(f);
+ strings = galloc(strcnt * sizeof(char *));
+ for (j = 0; j < strcnt; ++j) {
+ stringlen = getc(f);
+ strings[j] = galloc(stringlen + 2);
+ strings[j][0] = stringlen;
+ strings[j][stringlen + 1] = '\0';
+ for (k = 0; k < stringlen; ++k)
+ strings[j][k + 1] = getc(f);
+ }
+ for (j = 0; j < 48; ++j) {
+ for (k = j - 1; k >= 0; --k)
+ if (stringoffsets[j] == stringoffsets[k])
+ break;
+ if (k != -1)
+ continue; /* this style doesn't exist */
+ format = stringoffsets[j] - 1;
+ stringlen = strings[0][0];
+ if (format != 0)
+ for (k = 0; k < strings[format][0]; ++k)
+ stringlen += strings[strings[format][k + 1] - 1][0];
+ pt = cur->psnames[j] = galloc(stringlen + 1);
+ strcpy(pt, strings[0] + 1);
+ pt += strings[0][0];
+ if (format != 0)
+ for (k = 0; k < strings[format][0]; ++k) {
+ strcpy(pt, strings[strings[format][k + 1] - 1] + 1);
+ pt += strings[strings[format][k + 1] - 1][0];
+ }
+ *pt = '\0';
+ }
+ for (j = 0; j < strcnt; ++j)
+ free(strings[j]);
+ free(strings);
+ }
+ fseek(f, here, SEEK_SET);
}
- fseek(f,start,SEEK_SET);
-return( head );
+ fseek(f, start, SEEK_SET);
+ return (head);
}
-static char *BuildName(char *family,int style) {
+static char *BuildName(char *family, int style)
+{
char buffer[350];
- strncpy(buffer,family,200);
- if ( style!=0 )
- strcat(buffer,"-");
- if ( style&sf_bold )
- strcat(buffer,"Bold");
- if ( style&sf_italic )
- strcat(buffer,"Italic");
- if ( style&sf_underline )
- strcat(buffer,"Underline");
- if ( style&sf_outline )
- strcat(buffer,"Outline");
- if ( style&sf_shadow )
- strcat(buffer,"Shadow");
- if ( style&sf_condense )
- strcat(buffer,"Condensed");
- if ( style&sf_extend )
- strcat(buffer,"Extended");
-return( copy(buffer));
+ strncpy(buffer, family, 200);
+ if (style != 0)
+ strcat(buffer, "-");
+ if (style & sf_bold)
+ strcat(buffer, "Bold");
+ if (style & sf_italic)
+ strcat(buffer, "Italic");
+ if (style & sf_underline)
+ strcat(buffer, "Underline");
+ if (style & sf_outline)
+ strcat(buffer, "Outline");
+ if (style & sf_shadow)
+ strcat(buffer, "Shadow");
+ if (style & sf_condense)
+ strcat(buffer, "Condensed");
+ if (style & sf_extend)
+ strcat(buffer, "Extended");
+ return (copy(buffer));
}
-static int GuessStyle(char *fontname,int *styles,int style_cnt) {
+static int GuessStyle(char *fontname, int *styles, int style_cnt)
+{
int which, style;
- char *stylenames = _GetModifiers(fontname,NULL,NULL);
+ char *stylenames = _GetModifiers(fontname, NULL, NULL);
- style = _MacStyleCode(stylenames,NULL,NULL);
- for ( which = style_cnt; which>=0; --which )
- if ( styles[which] == style )
-return( which );
+ style = _MacStyleCode(stylenames, NULL, NULL);
+ for (which = style_cnt; which >= 0; --which)
+ if (styles[which] == style)
+ return (which);
-return( -1 );
+ return (-1);
}
-static FOND *PickFOND(FOND *fondlist,char *filename,char **name, int *style) {
- int i,j;
+static FOND *PickFOND(FOND * fondlist, char *filename, char **name, int *style)
+{
+ int i, j;
FOND *test;
uint8 stylesused[96];
char **names;
@@ -709,163 +743,180 @@ static FOND *PickFOND(FOND *fondlist,char *filename,char **name, int *style) {
char *pt, *lparen;
char *find = NULL;
- if ((pt = strrchr(filename,'/'))!=NULL ) pt = filename;
- if ( (lparen = strchr(filename,'('))!=NULL && strchr(lparen,')')!=NULL ) {
- find = copy(lparen+1);
- pt = strchr(find,')');
- if ( pt!=NULL ) *pt='\0';
- for ( test=fondlist; test!=NULL; test=test->next ) {
- for ( i=0; i<48; ++i )
- if ( test->psnames[i]!=NULL && strcmp(find,test->psnames[i])==0 ) {
- *style = (i&3) | ((i&~3)<<1); /* PS styles skip underline bit */
- *name = copy(test->psnames[i]);
-return( test );
- }
- }
+ if ((pt = strrchr(filename, '/')) != NULL)
+ pt = filename;
+ if ((lparen = strchr(filename, '(')) != NULL && strchr(lparen, ')') != NULL) {
+ find = copy(lparen + 1);
+ pt = strchr(find, ')');
+ if (pt != NULL)
+ *pt = '\0';
+ for (test = fondlist; test != NULL; test = test->next) {
+ for (i = 0; i < 48; ++i)
+ if (test->psnames[i] != NULL
+ && strcmp(find, test->psnames[i]) == 0) {
+ *style = (i & 3) | ((i & ~3) << 1); /* PS styles skip underline bit */
+ *name = copy(test->psnames[i]);
+ return (test);
+ }
+ }
}
/* The file may contain multiple families, and each family may contain */
/* multiple styles (and each style may contain multiple sizes, but that's */
/* not an issue for us here) */
names = NULL;
- for ( i=0; i<2; ++i ) {
- cnt = 0;
- for ( test=fondlist; test!=NULL; test=test->next ) if ( test->fondname!=NULL ) {
- memset(stylesused,0,sizeof(stylesused));
- for ( j=0; j<test->assoc_cnt; ++j ) {
- if ( test->assoc[j].size!=0 && !stylesused[test->assoc[j].style]) {
- stylesused[test->assoc[j].style]=true;
- if ( names!=NULL ) {
- names[cnt] = BuildName(test->fondname,test->assoc[j].style);
- styles[cnt] = test->assoc[j].style;
- fonds[cnt] = test;
- }
- ++cnt;
- }
- }
- }
- if ( names==NULL ) {
- names = gcalloc(cnt+1,sizeof(char *));
- fonds = galloc(cnt*sizeof(FOND *));
- styles = galloc(cnt*sizeof(int));
- }
+ for (i = 0; i < 2; ++i) {
+ cnt = 0;
+ for (test = fondlist; test != NULL; test = test->next)
+ if (test->fondname != NULL) {
+ memset(stylesused, 0, sizeof(stylesused));
+ for (j = 0; j < test->assoc_cnt; ++j) {
+ if (test->assoc[j].size != 0
+ && !stylesused[test->assoc[j].style]) {
+ stylesused[test->assoc[j].style] = true;
+ if (names != NULL) {
+ names[cnt] =
+ BuildName(test->fondname, test->assoc[j].style);
+ styles[cnt] = test->assoc[j].style;
+ fonds[cnt] = test;
+ }
+ ++cnt;
+ }
+ }
+ }
+ if (names == NULL) {
+ names = gcalloc(cnt + 1, sizeof(char *));
+ fonds = galloc(cnt * sizeof(FOND *));
+ styles = galloc(cnt * sizeof(int));
+ }
}
- if ( find!=NULL ) {
- for ( which=cnt-1; which>=0; --which )
- if ( strcmp(names[which],find)==0 )
- break;
- if ( which==-1 && strstrmatch(find,test->fondname)!=NULL )
- which = GuessStyle(find,styles,cnt);
- if ( which==-1 ) {
- char *fn = copy(filename);
- fn[lparen-filename] = '\0';
- ff_post_error(_("Not in Collection"),_("%s is not in %.100s"),find,fn);
- free(fn);
- }
- free(find);
- } else
- which = 0;
-
- if ( which!=-1 ) {
- fond = fonds[which];
- *name = copy(names[which]);
- *style = styles[which];
+ if (find != NULL) {
+ for (which = cnt - 1; which >= 0; --which)
+ if (strcmp(names[which], find) == 0)
+ break;
+ if (which == -1 && strstrmatch(find, test->fondname) != NULL)
+ which = GuessStyle(find, styles, cnt);
+ if (which == -1) {
+ char *fn = copy(filename);
+ fn[lparen - filename] = '\0';
+ ff_post_error(_("Not in Collection"), _("%s is not in %.100s"),
+ find, fn);
+ free(fn);
+ }
+ free(find);
+ } else
+ which = 0;
+
+ if (which != -1) {
+ fond = fonds[which];
+ *name = copy(names[which]);
+ *style = styles[which];
}
- for ( i=0; i<cnt; ++i )
- free(names[i]);
- free(names); free(fonds); free(styles);
- if ( which==-1 )
-return( NULL );
-
-return( fond );
+ for (i = 0; i < cnt; ++i)
+ free(names[i]);
+ free(names);
+ free(fonds);
+ free(styles);
+ if (which == -1)
+ return (NULL);
+
+ return (fond);
}
/* Look for kerning info and merge it into the currently existing font "into" */
-static SplineFont *FindFamilyStyleKerns(SplineFont *into,EncMap *map,FOND *fondlist,char *filename) {
+static SplineFont *FindFamilyStyleKerns(SplineFont * into, EncMap * map,
+ FOND * fondlist, char *filename)
+{
char *name;
int style;
FOND *fond;
- int i,j;
+ int i, j;
int ch1, ch2, offset;
KernPair *kp;
SplineChar *sc1, *sc2;
- fond = PickFOND(fondlist,filename,&name,&style);
- if ( fond==NULL || into==NULL )
-return( NULL );
- for ( i=0; i<fond->stylekerncnt; ++i )
- if ( fond->stylekerns[i].style==style )
- break;
- if ( i==fond->stylekerncnt ) {
- LogError(_("No kerning table for %s\n"), name );
- free(name);
-return( NULL );
+ fond = PickFOND(fondlist, filename, &name, &style);
+ if (fond == NULL || into == NULL)
+ return (NULL);
+ for (i = 0; i < fond->stylekerncnt; ++i)
+ if (fond->stylekerns[i].style == style)
+ break;
+ if (i == fond->stylekerncnt) {
+ LogError(_("No kerning table for %s\n"), name);
+ free(name);
+ return (NULL);
}
- for ( j=0; j<fond->stylekerns[i].kernpairs; ++j ) {
- ch1 = fond->stylekerns[i].kerns[j].ch1;
- ch2 = fond->stylekerns[i].kerns[j].ch2;
- offset = (fond->stylekerns[i].kerns[j].offset*(into->ascent+into->descent)+(1<<11))>>12;
- sc1 = SFMakeChar(into,map,ch1);
- sc2 = SFMakeChar(into,map,ch2);
- for ( kp=sc1->kerns; kp!=NULL; kp=kp->next )
- if ( kp->sc==sc2 )
- break;
- if ( kp==NULL ) {
- uint32 script;
- kp = chunkalloc(sizeof(KernPair));
- kp->sc = sc2;
- kp->next = sc1->kerns;
- sc1->kerns = kp;
- script = SCScriptFromUnicode(sc1);
- if ( script==DEFAULT_SCRIPT )
- script = SCScriptFromUnicode(sc2);
- kp->subtable = SFSubTableFindOrMake(sc1->parent,CHR('k','e','r','n'),
- script, gpos_pair);
- }
- kp->off = offset;
+ for (j = 0; j < fond->stylekerns[i].kernpairs; ++j) {
+ ch1 = fond->stylekerns[i].kerns[j].ch1;
+ ch2 = fond->stylekerns[i].kerns[j].ch2;
+ offset =
+ (fond->stylekerns[i].kerns[j].offset *
+ (into->ascent + into->descent) + (1 << 11)) >> 12;
+ sc1 = SFMakeChar(into, map, ch1);
+ sc2 = SFMakeChar(into, map, ch2);
+ for (kp = sc1->kerns; kp != NULL; kp = kp->next)
+ if (kp->sc == sc2)
+ break;
+ if (kp == NULL) {
+ uint32 script;
+ kp = chunkalloc(sizeof(KernPair));
+ kp->sc = sc2;
+ kp->next = sc1->kerns;
+ sc1->kerns = kp;
+ script = SCScriptFromUnicode(sc1);
+ if (script == DEFAULT_SCRIPT)
+ script = SCScriptFromUnicode(sc2);
+ kp->subtable =
+ SFSubTableFindOrMake(sc1->parent, CHR('k', 'e', 'r', 'n'),
+ script, gpos_pair);
+ }
+ kp->off = offset;
}
-return( into );
+ return (into);
}
/* Look for a bare truetype font in a binhex/macbinary wrapper */
-static SplineFont *MightBeTrueType(FILE *binary,int32 pos,int32 dlen,int flags,
- enum openflags openflags) {
+static SplineFont *MightBeTrueType(FILE * binary, int32 pos, int32 dlen,
+ int flags, enum openflags openflags)
+{
FILE *temp = tmpfile();
char *buffer = galloc(8192);
int len;
SplineFont *sf;
- if ( flags&ttf_onlynames ) {
- char **ret;
- char *temp = TTFGetFontName(binary,pos,pos);
- if ( temp==NULL )
-return( NULL );
- ret = galloc(2*sizeof(char *));
- ret[0] = temp;
- ret[1] = NULL;
-return( (SplineFont *) ret );
+ if (flags & ttf_onlynames) {
+ char **ret;
+ char *temp = TTFGetFontName(binary, pos, pos);
+ if (temp == NULL)
+ return (NULL);
+ ret = galloc(2 * sizeof(char *));
+ ret[0] = temp;
+ ret[1] = NULL;
+ return ((SplineFont *) ret);
}
- fseek(binary,pos,SEEK_SET);
- while ( dlen>0 ) {
- len = dlen > 8192 ? 8192 : dlen;
- len = fread(buffer,1,dlen > 8192 ? 8192 : dlen,binary);
- if ( len==0 )
- break;
- fwrite(buffer,1,len,temp);
- dlen -= len;
+ fseek(binary, pos, SEEK_SET);
+ while (dlen > 0) {
+ len = dlen > 8192 ? 8192 : dlen;
+ len = fread(buffer, 1, dlen > 8192 ? 8192 : dlen, binary);
+ if (len == 0)
+ break;
+ fwrite(buffer, 1, len, temp);
+ dlen -= len;
}
rewind(temp);
- sf = _SFReadTTF(temp,flags,openflags,NULL,NULL);
+ sf = _SFReadTTF(temp, flags, openflags, NULL, NULL);
fclose(temp);
free(buffer);
-return( sf );
+ return (sf);
}
-static SplineFont *IsResourceFork(FILE *f, long offset,char *filename,int flags,
- enum openflags openflags, SplineFont *into,EncMap *map) {
+static SplineFont *IsResourceFork(FILE * f, long offset, char *filename,
+ int flags, enum openflags openflags,
+ SplineFont * into, EncMap * map)
+{
/* If it is a good resource fork then the first 16 bytes are repeated */
/* at the location specified in bytes 4-7 */
/* We include an offset because if we are looking at a mac binary file */
@@ -876,326 +927,599 @@ static SplineFont *IsResourceFork(FILE *f, long offset,char *filename,int flags,
int32 rdata_len, map_len;
uint32 nfnt_pos, font_pos, fond_pos;
unsigned long tag;
- int i, cnt, subcnt, nfnt_subcnt=0, font_subcnt=0, fond_subcnt=0;
+ int i, cnt, subcnt, nfnt_subcnt = 0, font_subcnt = 0, fond_subcnt = 0;
SplineFont *sf;
- FOND *fondlist=NULL;
- fond_pos=0;
- fseek(f,offset,SEEK_SET);
- if ( fread(buffer,1,16,f)!=16 )
-return( NULL );
- rdata_pos = offset + ((buffer[0]<<24)|(buffer[1]<<16)|(buffer[2]<<8)|buffer[3]);
- map_pos = offset + ((buffer[4]<<24)|(buffer[5]<<16)|(buffer[6]<<8)|buffer[7]);
- rdata_len = ((buffer[8]<<24)|(buffer[9]<<16)|(buffer[10]<<8)|buffer[11]);
- map_len = ((buffer[12]<<24)|(buffer[13]<<16)|(buffer[14]<<8)|buffer[15]);
- if ( rdata_pos+rdata_len!=map_pos || rdata_len==0 )
-return( NULL );
- fseek(f,map_pos,SEEK_SET);
- buffer2[15] = buffer[15]+1; /* make it be different */
- if ( fread(buffer2,1,16,f)!=16 )
-return( NULL );
+ FOND *fondlist = NULL;
+ fond_pos = 0;
+ fseek(f, offset, SEEK_SET);
+ if (fread(buffer, 1, 16, f) != 16)
+ return (NULL);
+ rdata_pos =
+ offset +
+ ((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]);
+ map_pos =
+ offset +
+ ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]);
+ rdata_len =
+ ((buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) |
+ buffer[11]);
+ map_len =
+ ((buffer[12] << 24) | (buffer[13] << 16) | (buffer[14] << 8) |
+ buffer[15]);
+ if (rdata_pos + rdata_len != map_pos || rdata_len == 0)
+ return (NULL);
+ fseek(f, map_pos, SEEK_SET);
+ buffer2[15] = buffer[15] + 1; /* make it be different */
+ if (fread(buffer2, 1, 16, f) != 16)
+ return (NULL);
/* Apple's data fork resources appear to have a bunch of zeroes here instead */
/* of a copy of the first 16 bytes */
- for ( i=0; i<16; ++i )
- if ( buffer2[i]!=0 )
- break;
- if ( i!=16 ) {
- for ( i=0; i<16; ++i )
- if ( buffer[i]!=buffer2[i] )
-return( NULL );
+ for (i = 0; i < 16; ++i)
+ if (buffer2[i] != 0)
+ break;
+ if (i != 16) {
+ for (i = 0; i < 16; ++i)
+ if (buffer[i] != buffer2[i])
+ return (NULL);
}
- getlong(f); /* skip the handle to the next resource map */
- getushort(f); /* skip the file resource number */
- getushort(f); /* skip the attributes */
+ getlong(f); /* skip the handle to the next resource map */
+ getushort(f); /* skip the file resource number */
+ getushort(f); /* skip the attributes */
type_list = map_pos + getushort(f);
name_list = map_pos + getushort(f);
- fseek(f,type_list,SEEK_SET);
- cnt = getushort(f)+1;
- for ( i=0; i<cnt; ++i ) {
- tag = getlong(f);
- /* printf( "%c%c%c%c\n", tag>>24, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff );*/
- subcnt = getushort(f)+1;
- rpos = type_list+getushort(f);
- sf = NULL;
- if ( tag==CHR('P','O','S','T') && !(flags&(ttf_onlystrikes|ttf_onlykerns))) /* No FOND */
- sf = SearchPostscriptResources(f,rpos,subcnt,rdata_pos,name_list,flags);
- else if ( tag==CHR('s','f','n','t') && !(flags&ttf_onlykerns))
- sf = SearchTtfResources(f,rpos,subcnt,rdata_pos,name_list,filename,flags,openflags);
- else if ( tag==CHR('N','F','N','T') ) {
- nfnt_pos = rpos;
- nfnt_subcnt = subcnt;
- } else if ( tag==CHR('F','O','N','T') ) {
- font_pos = rpos;
- font_subcnt = subcnt;
- } else if ( tag==CHR('F','O','N','D') ) {
- fond_pos = rpos;
- fond_subcnt = subcnt;
- }
- if ( sf!=NULL )
-return( sf );
+ fseek(f, type_list, SEEK_SET);
+ cnt = getushort(f) + 1;
+ for (i = 0; i < cnt; ++i) {
+ tag = getlong(f);
+ /* printf( "%c%c%c%c\n", tag>>24, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff ); */
+ subcnt = getushort(f) + 1;
+ rpos = type_list + getushort(f);
+ sf = NULL;
+ if (tag == CHR('P', 'O', 'S', 'T') && !(flags & (ttf_onlystrikes | ttf_onlykerns))) /* No FOND */
+ sf = SearchPostscriptResources(f, rpos, subcnt, rdata_pos,
+ name_list, flags);
+ else if (tag == CHR('s', 'f', 'n', 't') && !(flags & ttf_onlykerns))
+ sf = SearchTtfResources(f, rpos, subcnt, rdata_pos, name_list,
+ filename, flags, openflags);
+ else if (tag == CHR('N', 'F', 'N', 'T')) {
+ nfnt_pos = rpos;
+ nfnt_subcnt = subcnt;
+ } else if (tag == CHR('F', 'O', 'N', 'T')) {
+ font_pos = rpos;
+ font_subcnt = subcnt;
+ } else if (tag == CHR('F', 'O', 'N', 'D')) {
+ fond_pos = rpos;
+ fond_subcnt = subcnt;
+ }
+ if (sf != NULL)
+ return (sf);
}
- if ( flags&ttf_onlynames ) /* Not interested in bitmap resources here */
-return( NULL );
-
- if ( flags&ttf_onlykerns ) { /* For kerns */
- if ( fond_subcnt!=0 )
- fondlist = BuildFondList(f,fond_pos,fond_subcnt,rdata_pos,name_list,flags);
- into = FindFamilyStyleKerns(into,map,fondlist,filename);
- FondListFree(fondlist);
-return( into );
+ if (flags & ttf_onlynames) /* Not interested in bitmap resources here */
+ return (NULL);
+
+ if (flags & ttf_onlykerns) { /* For kerns */
+ if (fond_subcnt != 0)
+ fondlist =
+ BuildFondList(f, fond_pos, fond_subcnt, rdata_pos, name_list,
+ flags);
+ into = FindFamilyStyleKerns(into, map, fondlist, filename);
+ FondListFree(fondlist);
+ return (into);
}
/* Ok. If no outline font, try for a bitmap */
- if ( nfnt_subcnt==0 ) {
- nfnt_pos = font_pos;
- nfnt_subcnt = font_subcnt;
+ if (nfnt_subcnt == 0) {
+ nfnt_pos = font_pos;
+ nfnt_subcnt = font_subcnt;
}
-return( (SplineFont *) -1 ); /* It's a valid resource file, but just has no fonts */
+ return ((SplineFont *) - 1); /* It's a valid resource file, but just has no fonts */
}
-static SplineFont *IsResourceInBinary(FILE *f,char *filename,int flags,
- enum openflags openflags, SplineFont *into,EncMap *map) {
+static SplineFont *IsResourceInBinary(FILE * f, char *filename, int flags,
+ enum openflags openflags,
+ SplineFont * into, EncMap * map)
+{
unsigned char header[128];
unsigned long offset, dlen, rlen;
- if ( fread(header,1,128,f)!=128 )
-return( NULL );
- if ( header[0]!=0 || header[74]!=0 || header[82]!=0 || header[1]<=0 ||
- header[1]>33 || header[63]!=0 || header[2+header[1]]!=0 )
-return( NULL );
- dlen = ((header[0x53]<<24)|(header[0x54]<<16)|(header[0x55]<<8)|header[0x56]);
- rlen = ((header[0x57]<<24)|(header[0x58]<<16)|(header[0x59]<<8)|header[0x5a]);
- /* 128 bytes for header, then the dlen is padded to a 128 byte boundary */
- offset = 128 + ((dlen+127)&~127);
+ if (fread(header, 1, 128, f) != 128)
+ return (NULL);
+ if (header[0] != 0 || header[74] != 0 || header[82] != 0 || header[1] <= 0
+ || header[1] > 33 || header[63] != 0 || header[2 + header[1]] != 0)
+ return (NULL);
+ dlen =
+ ((header[0x53] << 24) | (header[0x54] << 16) | (header[0x55] << 8) |
+ header[0x56]);
+ rlen =
+ ((header[0x57] << 24) | (header[0x58] << 16) | (header[0x59] << 8) |
+ header[0x5a]);
+ /* 128 bytes for header, then the dlen is padded to a 128 byte boundary */
+ offset = 128 + ((dlen + 127) & ~127);
/* Look for a bare truetype font in a binhex/macbinary wrapper */
- if ( dlen!=0 && rlen<=dlen) {
- int pos = ftell(f);
- fread(header,1,4,f);
- header[5] = '\0';
- if ( strcmp((char *) header,"OTTO")==0 || strcmp((char *) header,"true")==0 ||
- strcmp((char *) header,"ttcf")==0 ||
- (header[0]==0 && header[1]==1 && header[2]==0 && header[3]==0))
-return( MightBeTrueType(f,pos,dlen,flags,openflags));
+ if (dlen != 0 && rlen <= dlen) {
+ int pos = ftell(f);
+ fread(header, 1, 4, f);
+ header[5] = '\0';
+ if (strcmp((char *) header, "OTTO") == 0
+ || strcmp((char *) header, "true") == 0
+ || strcmp((char *) header, "ttcf") == 0 || (header[0] == 0
+ && header[1] == 1
+ && header[2] == 0
+ && header[3] == 0))
+ return (MightBeTrueType(f, pos, dlen, flags, openflags));
}
-return( IsResourceFork(f,offset,filename,flags,openflags,into,map));
+ return (IsResourceFork(f, offset, filename, flags, openflags, into, map));
}
-static int lastch=0, repeat = 0;
-static void outchr(FILE *binary, int ch) {
+static int lastch = 0, repeat = 0;
+static void outchr(FILE * binary, int ch)
+{
int i;
- if ( repeat ) {
- if ( ch==0 ) {
- /* no repeat, output a literal 0x90 (the repeat flag) */
- lastch=0x90;
- putc(lastch,binary);
- } else {
- for ( i=1; i<ch; ++i )
- putc(lastch,binary);
- }
- repeat = 0;
- } else if ( ch==0x90 ) {
- repeat = 1;
+ if (repeat) {
+ if (ch == 0) {
+ /* no repeat, output a literal 0x90 (the repeat flag) */
+ lastch = 0x90;
+ putc(lastch, binary);
+ } else {
+ for (i = 1; i < ch; ++i)
+ putc(lastch, binary);
+ }
+ repeat = 0;
+ } else if (ch == 0x90) {
+ repeat = 1;
} else {
- putc(ch,binary);
- lastch = ch;
+ putc(ch, binary);
+ lastch = ch;
}
}
-static SplineFont *IsResourceInHex(FILE *f,char *filename,int flags,enum openflags openflags,
- SplineFont *into,EncMap *map) {
+static SplineFont *IsResourceInHex(FILE * f, char *filename, int flags,
+ enum openflags openflags, SplineFont * into,
+ EncMap * map)
+{
/* convert file from 6bit to 8bit */
/* interesting data is enclosed between two colons */
FILE *binary = tmpfile();
- char *sixbit = "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
+ char *sixbit =
+ "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
int ch, val, cnt, i, dlen, rlen;
- unsigned char header[20]; char *pt;
+ unsigned char header[20];
+ char *pt;
SplineFont *ret;
- if ( binary==NULL ) {
- LogError( _("can't create temporary file\n") );
-return( NULL );
+ if (binary == NULL) {
+ LogError(_("can't create temporary file\n"));
+ return (NULL);
}
lastch = repeat = 0;
- while ( (ch=getc(f))!=':' ); /* There may be comments before file start */
+ while ((ch = getc(f)) != ':'); /* There may be comments before file start */
cnt = val = 0;
- while ( (ch=getc(f))!=':' ) {
- if ( isspace(ch))
- continue;
- for ( pt=sixbit; *pt!=ch && *pt!='\0'; ++pt );
- if ( *pt=='\0' ) {
- fclose(binary);
-return( NULL );
- }
- val = (val<<6) | (pt-sixbit);
- if ( ++cnt==4 ) {
- outchr(binary,(val>>16)&0xff);
- outchr(binary,(val>>8)&0xff);
- outchr(binary,val&0xff);
- val = cnt = 0;
- }
+ while ((ch = getc(f)) != ':') {
+ if (isspace(ch))
+ continue;
+ for (pt = sixbit; *pt != ch && *pt != '\0'; ++pt);
+ if (*pt == '\0') {
+ fclose(binary);
+ return (NULL);
+ }
+ val = (val << 6) | (pt - sixbit);
+ if (++cnt == 4) {
+ outchr(binary, (val >> 16) & 0xff);
+ outchr(binary, (val >> 8) & 0xff);
+ outchr(binary, val & 0xff);
+ val = cnt = 0;
+ }
}
- if ( cnt!=0 ) {
- if ( cnt==1 )
- outchr(binary,val<<2);
- else if ( cnt==2 ) {
- val<<=4;
- outchr(binary,(val>>8)&0xff);
- outchr(binary,val&0xff);
- } else if ( cnt==3 ) {
- val<<=6;
- outchr(binary,(val>>16)&0xff);
- outchr(binary,(val>>8)&0xff);
- outchr(binary,val&0xff);
- }
+ if (cnt != 0) {
+ if (cnt == 1)
+ outchr(binary, val << 2);
+ else if (cnt == 2) {
+ val <<= 4;
+ outchr(binary, (val >> 8) & 0xff);
+ outchr(binary, val & 0xff);
+ } else if (cnt == 3) {
+ val <<= 6;
+ outchr(binary, (val >> 16) & 0xff);
+ outchr(binary, (val >> 8) & 0xff);
+ outchr(binary, val & 0xff);
+ }
}
rewind(binary);
- ch = getc(binary); /* Name length */
+ ch = getc(binary); /* Name length */
/* skip name */
- for ( i=0; i<ch; ++i )
- getc(binary);
- if ( getc(binary)!='\0' ) {
- fclose(binary);
-return( NULL );
+ for (i = 0; i < ch; ++i)
+ getc(binary);
+ if (getc(binary) != '\0') {
+ fclose(binary);
+ return (NULL);
}
- fread(header,1,20,binary);
- dlen = (header[10]<<24)|(header[11]<<16)|(header[12]<<8)|header[13];
- rlen = (header[14]<<24)|(header[15]<<16)|(header[16]<<8)|header[17];
+ fread(header, 1, 20, binary);
+ dlen =
+ (header[10] << 24) | (header[11] << 16) | (header[12] << 8) |
+ header[13];
+ rlen =
+ (header[14] << 24) | (header[15] << 16) | (header[16] << 8) |
+ header[17];
/* Look for a bare truetype font in a binhex/macbinary wrapper */
- if ( dlen!=0 && rlen<dlen ) {
- int pos = ftell(binary);
- fread(header,1,4,binary);
- header[5] = '\0';
- if ( strcmp((char *) header,"OTTO")==0 || strcmp((char *) header,"true")==0 ||
- strcmp((char *) header,"ttcf")==0 ||
- (header[0]==0 && header[1]==1 && header[2]==0 && header[3]==0)) {
- ret = MightBeTrueType(binary,pos,dlen,flags,openflags);
- fclose(binary);
-return( ret );
- }
+ if (dlen != 0 && rlen < dlen) {
+ int pos = ftell(binary);
+ fread(header, 1, 4, binary);
+ header[5] = '\0';
+ if (strcmp((char *) header, "OTTO") == 0
+ || strcmp((char *) header, "true") == 0
+ || strcmp((char *) header, "ttcf") == 0 || (header[0] == 0
+ && header[1] == 1
+ && header[2] == 0
+ && header[3] == 0)) {
+ ret = MightBeTrueType(binary, pos, dlen, flags, openflags);
+ fclose(binary);
+ return (ret);
+ }
}
- if ( rlen==0 ) {
- fclose(binary);
-return( NULL );
+ if (rlen == 0) {
+ fclose(binary);
+ return (NULL);
}
- ret = IsResourceFork(binary,ftell(binary)+dlen+2,filename,flags,openflags,into,map);
+ ret =
+ IsResourceFork(binary, ftell(binary) + dlen + 2, filename, flags,
+ openflags, into, map);
fclose(binary);
-return( ret );
+ return (ret);
}
-static SplineFont *IsResourceInFile(char *filename,int flags,enum openflags openflags,
- SplineFont *into, EncMap *map) {
+static SplineFont *IsResourceInFile(char *filename, int flags,
+ enum openflags openflags, SplineFont * into,
+ EncMap * map)
+{
FILE *f;
char *spt, *pt;
SplineFont *sf;
- char *temp=filename, *lparen;
+ char *temp = filename, *lparen;
- if (( pt=strrchr(filename,'/'))==NULL ) pt = filename;
- if ( (lparen = strchr(pt,'('))!=NULL && strchr(lparen,')')!=NULL ) {
- temp = copy(filename);
- temp[lparen-filename] = '\0';
+ if ((pt = strrchr(filename, '/')) == NULL)
+ pt = filename;
+ if ((lparen = strchr(pt, '(')) != NULL && strchr(lparen, ')') != NULL) {
+ temp = copy(filename);
+ temp[lparen - filename] = '\0';
}
- f = fopen(temp,"rb");
- if ( temp!=filename ) free(temp);
- if ( f==NULL )
-return( NULL );
- spt = strrchr(filename,'/');
- if ( spt==NULL ) spt = filename;
- pt = strrchr(spt,'.');
- if ( pt!=NULL && (pt[1]=='b' || pt[1]=='B') && (pt[2]=='i' || pt[2]=='I') &&
- (pt[3]=='n' || pt[3]=='N') && (pt[4]=='\0' || pt[4]=='(') ) {
- if ( (sf = IsResourceInBinary(f,filename,flags,openflags,into,map))) {
- fclose(f);
-return( sf );
- }
- } else if ( pt!=NULL && (pt[1]=='h' || pt[1]=='H') && (pt[2]=='q' || pt[2]=='Q') &&
- (pt[3]=='x' || pt[3]=='X') && (pt[4]=='\0' || pt[4]=='(')) {
- if ( (sf = IsResourceInHex(f,filename,flags,openflags,into,map))) {
- fclose(f);
-return( sf );
- }
+ f = fopen(temp, "rb");
+ if (temp != filename)
+ free(temp);
+ if (f == NULL)
+ return (NULL);
+ spt = strrchr(filename, '/');
+ if (spt == NULL)
+ spt = filename;
+ pt = strrchr(spt, '.');
+ if (pt != NULL && (pt[1] == 'b' || pt[1] == 'B')
+ && (pt[2] == 'i' || pt[2] == 'I') && (pt[3] == 'n' || pt[3] == 'N')
+ && (pt[4] == '\0' || pt[4] == '(')) {
+ if ((sf = IsResourceInBinary(f, filename, flags, openflags, into, map))) {
+ fclose(f);
+ return (sf);
+ }
+ } else if (pt != NULL && (pt[1] == 'h' || pt[1] == 'H')
+ && (pt[2] == 'q' || pt[2] == 'Q') && (pt[3] == 'x'
+ || pt[3] == 'X')
+ && (pt[4] == '\0' || pt[4] == '(')) {
+ if ((sf = IsResourceInHex(f, filename, flags, openflags, into, map))) {
+ fclose(f);
+ return (sf);
+ }
}
- sf = IsResourceFork(f,0,filename,flags,openflags,into,map);
+ sf = IsResourceFork(f, 0, filename, flags, openflags, into, map);
fclose(f);
#if __Mac
- if ( sf==NULL )
- sf = HasResourceFork(filename,flags,openflags,into,map);
+ if (sf == NULL)
+ sf = HasResourceFork(filename, flags, openflags, into, map);
#endif
-return( sf );
+ return (sf);
}
-static SplineFont *FindResourceFile(char *filename,int flags,enum openflags openflags,
- SplineFont *into,EncMap *map) {
+static SplineFont *FindResourceFile(char *filename, int flags,
+ enum openflags openflags, SplineFont * into,
+ EncMap * map)
+{
char *spt, *pt, *dpt;
char buffer[1400];
SplineFont *sf;
- if ( (sf = IsResourceInFile(filename,flags,openflags,into,map)))
-return( sf );
+ if ((sf = IsResourceInFile(filename, flags, openflags, into, map)))
+ return (sf);
/* Well, look in the resource fork directory (if it exists), the resource */
/* fork is placed there in a seperate file on (some) non-Mac disks */
- strcpy(buffer,filename);
- spt = strrchr(buffer,'/');
- if ( spt==NULL ) { spt = buffer; pt = filename; }
- else { ++spt; pt = filename + (spt-buffer); }
- strcpy(spt,"resource.frk/");
- strcat(spt,pt);
- if ( (sf=IsResourceInFile(buffer,flags,openflags,into,map)))
-return( sf );
+ strcpy(buffer, filename);
+ spt = strrchr(buffer, '/');
+ if (spt == NULL) {
+ spt = buffer;
+ pt = filename;
+ } else {
+ ++spt;
+ pt = filename + (spt - buffer);
+ }
+ strcpy(spt, "resource.frk/");
+ strcat(spt, pt);
+ if ((sf = IsResourceInFile(buffer, flags, openflags, into, map)))
+ return (sf);
/* however the resource fork does not appear to do long names properly */
/* names are always lower case 8.3, do some simple things to check */
- spt = strrchr(buffer,'/')+1;
- for ( pt=spt; *pt; ++pt )
- if ( isupper( *pt ))
- *pt = tolower( *pt );
- dpt = strchr(spt,'.');
- if ( dpt==NULL ) dpt = spt+strlen(spt);
- if ( dpt-spt>8 || strlen(dpt)>4 ) {
- char exten[8];
- strncpy(exten,dpt,7);
- exten[4] = '\0'; /* it includes the dot */
- if ( dpt-spt>6 )
- dpt = spt+6;
- *dpt++ = '~';
- *dpt++ = '1';
- strcpy(dpt,exten);
+ spt = strrchr(buffer, '/') + 1;
+ for (pt = spt; *pt; ++pt)
+ if (isupper(*pt))
+ *pt = tolower(*pt);
+ dpt = strchr(spt, '.');
+ if (dpt == NULL)
+ dpt = spt + strlen(spt);
+ if (dpt - spt > 8 || strlen(dpt) > 4) {
+ char exten[8];
+ strncpy(exten, dpt, 7);
+ exten[4] = '\0'; /* it includes the dot */
+ if (dpt - spt > 6)
+ dpt = spt + 6;
+ *dpt++ = '~';
+ *dpt++ = '1';
+ strcpy(dpt, exten);
+ }
+ return (IsResourceInFile(buffer, flags, openflags, into, map));
+}
+
+
+static char *createtmpfile(char *filename)
+{
+ char *p, *tempname;
+ p = strrchr(filename,'/');
+ if (p != NULL) {
+ filename = p+1;
+ }
+ assert(strlen(filename)>=5);
+ tempname = malloc(strlen(filename)+2);
+ if (tempname == NULL) {
+ LogError(_("Out of memory\n"));
+ exit(1);
+ }
+ strcpy(tempname,filename);
+ strcpy(tempname+strlen(tempname)-5,"XXXXXX"); /* dfont -> XXXXXX */
+
+#ifdef HAVE_MKSTEMP
+ int i = mkstemp(tempname);
+ if (i) {
+ close(i);
}
-return( IsResourceInFile(buffer,flags,openflags,into,map));
+#else
+ mktemp(tempname);
+#endif
+ return tempname;
}
-SplineFont *SFReadMacBinary(char *filename,int flags,enum openflags openflags) {
- SplineFont *sf = FindResourceFile(filename,flags,openflags,NULL,NULL);
+static char *SearchTtfResourcesFile(FILE * f, long rlistpos, int subcnt,
+ long rdata_pos, long name_list,
+ char *filename, char *fontname)
+{
+ long here;
+ long roff;
+ int rname = -1;
+ int ch1, ch2;
+ int len, i, rlen, ilen;
+ /* The sfnt resource is just a copy of the ttf file */
+ char *buffer = NULL;
+ int max = 0;
+ FILE *ttf;
+ char *sf = NULL;
+ int which = 0;
+ char **names;
+ (void)name_list;
+ fseek(f, rlistpos, SEEK_SET);
+ if (subcnt > 1) {
+ names = gcalloc(subcnt + 1, sizeof(char *));
+ for (i = 0; i < subcnt; ++i) {
+ /* resource id = */ getushort(f);
+ /* rname = (short) */ getushort(f);
+ /* flags = */ getc(f);
+ ch1 = getc(f);
+ ch2 = getc(f);
+ roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f));
+ /* mbz = */ getlong(f);
+ here = ftell(f);
+ names[i] = TTFGetPSFontName(f, roff + 4, roff + 4);
+ if (names[i] == NULL) {
+ char buffer[32];
+ sprintf(buffer, "Nameless%d", i);
+ names[i] = copy(buffer);
+ }
+ fseek(f, here, SEEK_SET);
+ }
+ if (1) {
+ char *find = fontname;
+ for (which = subcnt - 1; which >= 0; --which)
+ if (strcmp(names[which], find) == 0)
+ break;
+ if (which == -1) {
+ char *end;
+ which = strtol(find, &end, 10);
+ if (*end != '\0')
+ which = -1;
+ }
+ if (which == -1) {
+ ff_post_error(_("Not in Collection"), _("%s is not in %.100s"),
+ find, filename);
+ }
+ } else {
+ which = 0;
+ }
+ for (i = 0; i < subcnt; ++i)
+ free(names[i]);
+ free(names);
+ fseek(f, rlistpos, SEEK_SET);
+ }
+
+ for (i = 0; i < subcnt; ++i) {
+ /* resource id = */ getushort(f);
+ rname = (short) getushort(f);
+ /* flags = */ getc(f);
+ ch1 = getc(f);
+ ch2 = getc(f);
+ roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f));
+ /* mbz = */ getlong(f);
+ if (i != which)
+ continue;
+ here = ftell(f);
+
+ sf = createtmpfile(filename);
+ ttf = fopen(sf, "wb");
+ if (ttf == NULL) {
+ LogError(_("Can't open temporary file for truetype output.\n"));
+ continue;
+ }
+
+ fseek(f, roff, SEEK_SET);
+ ilen = rlen = getlong(f);
+ if (rlen > 16 * 1024)
+ ilen = 16 * 1024;
+ if (ilen > max) {
+ free(buffer);
+ max = ilen;
+ if (max < 0x800)
+ max = 0x800;
+ buffer = malloc(max);
+ }
+ for (len = 0; len < rlen;) {
+ int temp = ilen;
+ if (rlen - len < ilen)
+ temp = rlen - len;
+ temp = fread(buffer, 1, temp, f);
+ if (temp == EOF)
+ break;
+ fwrite(buffer, 1, temp, ttf);
+ len += temp;
+ }
+ fclose(ttf);
+ }
+ free(buffer);
+ return sf;
+}
+
+static char *IsResourceForkFile(FILE * f, char *filename, char *fontname)
+{
+ /* If it is a good resource fork then the first 16 bytes are repeated */
+ /* at the location specified in bytes 4-7 */
+ /* We include an offset because if we are looking at a mac binary file */
+ /* the resource fork will actually start somewhere in the middle of the */
+ /* file, not at the beginning */
+ unsigned char buffer[16], buffer2[16];
+ long rdata_pos, map_pos, type_list, name_list, rpos;
+ int32 rdata_len, map_len;
+ uint32 fond_pos;
+ unsigned long tag;
+ int i, cnt, subcnt;
+ char *sf = NULL;
+ fond_pos = 0;
+ fseek(f, 0, SEEK_SET);
+ if (fread(buffer, 1, 16, f) != 16)
+ return (NULL);
+ rdata_pos =
+ ((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]);
+ map_pos =
+ ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]);
+ rdata_len =
+ ((buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) |
+ buffer[11]);
+ map_len =
+ ((buffer[12] << 24) | (buffer[13] << 16) | (buffer[14] << 8) |
+ buffer[15]);
+ if (rdata_pos + rdata_len != map_pos || rdata_len == 0)
+ return (NULL);
+ fseek(f, map_pos, SEEK_SET);
+ buffer2[15] = buffer[15] + 1; /* make it be different */
+ if (fread(buffer2, 1, 16, f) != 16)
+ return (NULL);
+ for (i = 0; i < 16; ++i)
+ if (buffer2[i] != 0)
+ break;
+ if (i != 16) {
+ for (i = 0; i < 16; ++i)
+ if (buffer[i] != buffer2[i])
+ return (NULL);
+ }
+ getlong(f); /* skip the handle to the next resource map */
+ getushort(f); /* skip the file resource number */
+ getushort(f); /* skip the attributes */
+ type_list = map_pos + getushort(f);
+ name_list = map_pos + getushort(f);
+ fseek(f, type_list, SEEK_SET);
+ cnt = getushort(f) + 1;
+ for (i = 0; i < cnt; ++i) {
+ tag = getlong(f);
+ subcnt = getushort(f) + 1;
+ rpos = type_list + getushort(f);
+ sf = NULL;
+ if (tag == CHR('s', 'f', 'n', 't')) {
+ sf = SearchTtfResourcesFile(f, rpos, subcnt, rdata_pos, name_list,
+ filename, fontname);
+ }
+ if (sf != NULL)
+ return (sf);
+ }
+ return NULL;
+}
+
+
+/* filename "/opt/tex/texmf-fonts/fonts/data/LucidaGrande.dfont",
+ fontname "Lucida Grande Bold"
+ */
+char *FindResourceTtfFont(char *filename, char *fontname)
+{
+ char *sf = NULL;
+ FILE *f = fopen(filename, "rb");
+ if (f == NULL)
+ return (NULL);
+ sf = IsResourceForkFile(f, filename, fontname);
+ fclose(f);
+ return sf;
+}
- if ( sf==NULL )
- LogError( _("Couldn't find a font file named %s\n"), filename );
- else if ( sf==(SplineFont *) (-1) ) {
- LogError( _("%s is a mac resource file but contains no postscript or truetype fonts\n"), filename );
- sf = NULL;
+SplineFont *SFReadMacBinary(char *filename, int flags, enum openflags openflags)
+{
+ SplineFont *sf = FindResourceFile(filename, flags, openflags, NULL, NULL);
+
+ if (sf == NULL)
+ LogError(_("Couldn't find a font file named %s\n"), filename);
+ else if (sf == (SplineFont *) (-1)) {
+ LogError(_
+ ("%s is a mac resource file but contains no postscript or truetype fonts\n"),
+ filename);
+ sf = NULL;
}
-return( sf );
+ return (sf);
}
-char **NamesReadMacBinary(char *filename) {
-return( (char **) FindResourceFile(filename,ttf_onlynames,0,NULL,NULL));
+char **NamesReadMacBinary(char *filename)
+{
+ return ((char **) FindResourceFile(filename, ttf_onlynames, 0, NULL, NULL));
}
/* should try to optimize this */
-SplineFont *SFReadMacBinaryInfo(char *filename,int flags,enum openflags openflags) {
- SplineFont *sf = FindResourceFile(filename,flags,openflags,NULL,NULL);
-
- if ( sf==NULL )
- LogError( _("Couldn't find a font file named %s\n"), filename );
- else if ( sf==(SplineFont *) (-1) ) {
- LogError( _("%s is a mac resource file but contains no postscript or truetype fonts\n"), filename );
- sf = NULL;
+SplineFont *SFReadMacBinaryInfo(char *filename, int flags,
+ enum openflags openflags)
+{
+ SplineFont *sf = FindResourceFile(filename, flags, openflags, NULL, NULL);
+
+ if (sf == NULL)
+ LogError(_("Couldn't find a font file named %s\n"), filename);
+ else if (sf == (SplineFont *) (-1)) {
+ LogError(_
+ ("%s is a mac resource file but contains no postscript or truetype fonts\n"),
+ filename);
+ sf = NULL;
}
-return( sf );
+ return (sf);
}
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c
index d3199f05ee7..3eb886c352f 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c
@@ -42,7 +42,7 @@ static void NOUI_IError(const char *format,...) {
static void NOUI__LogError(const char *format,va_list ap) {
char buffer[400], *str;
vsnprintf(buffer,sizeof(buffer),format,ap);
- str = utf82def_copy(buffer);
+ str = (char *)buffer;
fprintf(stderr,"%s",str);
if ( str[strlen(str)-1]!='\n' )
putc('\n',stderr);
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c
index 1f75c22cddc..9ccd1d393dd 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c
@@ -33,11 +33,19 @@
#include <gwidget.h>
#include "ttf.h"
+extern char *AdobeStandardEncoding[], *AdobeExpertEncoding[];
+extern const char *ttfstandardnames[];
+extern int ask_user_for_cmap;
+extern char *SaveTablesPref;
+
#ifdef LUA_FF_LIB
SplineFont *_SFReadTTFInfo(FILE *ttf, int flags,enum openflags openflags, char *filename,struct fontdict *fd);
void THPatchSplineChar(SplineChar *sc);
#endif
+int THtest_duplicate_glyph_names = 0;
+int THread_ttf_glyph_data = 0;
+
char *SaveTablesPref;
int ask_user_for_cmap = false;
@@ -579,6 +587,57 @@ return( NULL );
return( _readencstring(ttf,stringoffset+fullstr,fulllen,fullplat,fullspec,fulllang));
}
+
+char *TTFGetPSFontName(FILE *ttf,int32 offset,int32 off2) {
+ int i,num;
+ int32 tag, length, stringoffset;
+ int name, len, off;
+ int32 nameoffset = 0;
+
+ fseek(ttf,offset,SEEK_SET);
+ /* version = */ getlong(ttf);
+ num = getushort(ttf);
+ /* srange = */ getushort(ttf);
+ /* esel = */ getushort(ttf);
+ /* rshift = */ getushort(ttf);
+ for ( i=0; i<num; ++i ) {
+ tag = getlong(ttf);
+ /* checksum = */ getlong(ttf);
+ nameoffset = off2+getlong(ttf);
+ length = getlong(ttf);
+ if ( tag==CHR('n','a','m','e'))
+ break;
+ }
+ if ( i==num )
+ return( NULL );
+
+ fseek(ttf,nameoffset,SEEK_SET);
+ /* format = */ getushort(ttf);
+ num = getushort(ttf);
+ stringoffset = nameoffset+getushort(ttf);
+
+ for ( i=0; i<num; ++i ) {
+ /* plat */ getushort(ttf);
+ /* spec */ getushort(ttf);
+ /* lang */ getushort(ttf);
+ name = getushort(ttf);
+ len = getushort(ttf);
+ off = getushort(ttf);
+ if (name == 6) {
+ char *str = malloc(len+1);
+ if (str) {
+ fseek (ttf, stringoffset+off, SEEK_SET);
+ if(fread(str,1,len,ttf)==(size_t)len) {
+ str[len] = '\0';
+ return str;
+ }
+ free(str);
+ }
+ }
+ }
+ return NULL;
+}
+
static int PickTTFFont(FILE *ttf,char *filename,char **chosenname) {
int32 *offsets, cnt, i, choice, j;
char **names;
@@ -660,7 +719,6 @@ return( choice );
}
static void ParseSaveTablesPref(struct ttfinfo *info) {
- extern char *SaveTablesPref;
char *pt, *spt;
int cnt;
@@ -2185,26 +2243,23 @@ return( sc );
sc->xmax = getushort(ttf);
sc->ymax = getushort(ttf);
sc->lsidebearing = sc->xmin;
-#else
- /* xmin = */ sc->lsidebearing = getushort(ttf);
- /* ymin = */ getushort(ttf);
- /* xmax = */ getushort(ttf);
- /* ymax = */ /* sc->lsidebearing = */ getushort(ttf); /* what was this for? */
#endif
- if ( path_cnt>=0 )
+ if (THread_ttf_glyph_data) {
+ if ( path_cnt>=0 )
readttfsimpleglyph(ttf,info,sc,path_cnt);
- else
+ else
readttfcompositglyph(ttf,info,sc,info->glyph_start+end);
- if ( start>end ) {
+ if ( start>end ) {
LogError(_("Bad glyph (%d), disordered 'loca' table (start comes after end)\n"), gid );
info->bad_glyph_data = true;
- } else if ( ftell(ttf)>info->glyph_start+end ) {
+ } else if ( ftell(ttf)>(long)(info->glyph_start+end) ) {
LogError(_("Bad glyph (%d), its definition extends beyond the space allowed for it\n"), gid );
info->bad_glyph_data = true;
+ }
+
+ /* find the bb */
+ THPatchSplineChar(sc);
}
-
- /* find the bb */
- THPatchSplineChar(sc);
return( sc );
}
@@ -3284,7 +3339,6 @@ return( strings[sid-nStdStrings]);
static void readcffenc(FILE *ttf,struct topdicts *dict,struct ttfinfo *info,
char **strings, int scnt) {
int format, cnt, i, j, pos, first, last, dupenc, sid;
- extern char *AdobeStandardEncoding[], *AdobeExpertEncoding[];
const char *name;
EncMap *map;
@@ -3722,7 +3776,7 @@ static void cfffigure(struct ttfinfo *info, struct topdicts *dict,
info->chars = gcalloc(info->glyph_cnt,sizeof(SplineChar *));
for ( i=0; i<info->glyph_cnt; ++i ) {
- info->chars[i] = PSCharStringToSplines(
+ info->chars[i] = PSCharStringToBB(
dict->glyphs.values[i], dict->glyphs.lens[i],&pscontext,
subrs,gsubrs,FFgetsid(dict->charset[i],strings,scnt,info));
info->chars[i]->vwidth = info->emsize;
@@ -3805,7 +3859,7 @@ static void cidfigure(struct ttfinfo *info, struct topdicts *dict,
cid = dict->charset[i];
/*encmap->map[cid] = cid;*/
uni = CID2NameUni(map,cid,buffer,sizeof(buffer));
- info->chars[i] = PSCharStringToSplines(
+ info->chars[i] = PSCharStringToBB(
dict->glyphs.values[i], dict->glyphs.lens[i],&pscontext,
subrs,gsubrs,buffer);
info->chars[i]->vwidth = sf->ascent+sf->descent;
@@ -4129,6 +4183,7 @@ static int umodenc(int enc,int modtype, struct ttfinfo *info) {
return( -1 );
if ( modtype<=1 /* Unicode */ ) {
/* No conversion needed, already unicode */;
+#ifdef FROM_CJK_ICONV
} else if ( modtype==2 /* SJIS */ ) {
if ( enc<=127 ) {
/* Latin */
@@ -4186,6 +4241,10 @@ return( -1 );
enc = unicode_from_johab[enc-0x8400];
else if ( enc>0x100 )
enc = badencoding(info);
+#else
+ } else {
+ enc = badencoding(info);
+#endif
}
if ( enc==0 )
enc = -1;
@@ -4464,7 +4523,6 @@ static void readttfencodings(FILE *ttf,struct ttfinfo *info, int justinuse) {
Encoding *temp;
EncMap *map;
struct cmap_encs *cmap_encs, desired_cmaps[2], *dcmap;
- extern int ask_user_for_cmap;
fseek(ttf,info->encoding_start,SEEK_SET);
version = getushort(ttf);
@@ -5093,7 +5151,6 @@ static void readttfpostnames(FILE *ttf,struct ttfinfo *info) {
const char *name;
char buffer[30];
uint16 *indexes;
- extern const char *ttfstandardnames[];
int notdefwarned = false;
int anynames = false;
@@ -5211,7 +5268,7 @@ static void readttfpostnames(FILE *ttf,struct ttfinfo *info) {
name = NULL;
} else {
name = StdGlyphName(buffer,info->chars[i]->unicodeenc,info->uni_interp,NULL);
- if ( anynames ) {
+ if (THtest_duplicate_glyph_names && anynames ) {
for ( j=0; j<info->glyph_cnt; ++j ) {
if ( info->chars[j]!=NULL && j!=i && info->chars[j]->name!=NULL ) {
if ( strcmp(info->chars[j]->name,name)==0 ) {
@@ -5942,56 +5999,6 @@ return;
map->backmap[map->map[i]] = i;
}
-void TTF_PSDupsDefault(SplineFont *sf) {
- struct ttflangname *english;
- char versionbuf[40];
-
- /* Ok, if we've just loaded a ttf file then we've got a bunch of langnames*/
- /* we copied some of them (copyright, family, fullname, etc) into equiv */
- /* postscript entries in the sf. If we then use FontInfo and change the */
- /* obvious postscript entries we are left with the old ttf entries. If */
- /* we generate a ttf file and then load it the old values pop up. */
- /* Solution: Anything we can generate by default should be set to NULL */
- for ( english=sf->names; english!=NULL && english->lang!=0x409; english=english->next );
- if ( english==NULL )
-return;
- if ( english->names[ttf_family]!=NULL &&
- strcmp(english->names[ttf_family],sf->familyname)==0 ) {
- free(english->names[ttf_family]);
- english->names[ttf_family]=NULL;
- }
- if ( english->names[ttf_copyright]!=NULL &&
- strcmp(english->names[ttf_copyright],sf->copyright)==0 ) {
- free(english->names[ttf_copyright]);
- english->names[ttf_copyright]=NULL;
- }
- if ( english->names[ttf_fullname]!=NULL &&
- strcmp(english->names[ttf_fullname],sf->fullname)==0 ) {
- free(english->names[ttf_fullname]);
- english->names[ttf_fullname]=NULL;
- }
- if ( sf->subfontcnt!=0 || sf->version!=NULL ) {
- if ( sf->subfontcnt!=0 )
- sprintf( versionbuf, "Version %f", sf->cidversion );
- else
- sprintf(versionbuf,"Version %.20s ", sf->version);
- if ( english->names[ttf_version]!=NULL &&
- strcmp(english->names[ttf_version],versionbuf)==0 ) {
- free(english->names[ttf_version]);
- english->names[ttf_version]=NULL;
- }
- }
- if ( english->names[ttf_subfamily]!=NULL &&
- strcmp(english->names[ttf_subfamily],SFGetModifiers(sf))==0 ) {
- free(english->names[ttf_subfamily]);
- english->names[ttf_subfamily]=NULL;
- }
-
- /* User should not be allowed any access to this one, not ever */
- free(english->names[ttf_postscriptname]);
- english->names[ttf_postscriptname]=NULL;
-}
-
static SplineFont *SFFillFromTTF(struct ttfinfo *info) {
SplineFont *sf, *_sf;
int i,k;
@@ -6175,21 +6182,6 @@ static SplineFont *SFFillFromTTF(struct ttfinfo *info) {
sf->subfonts[i]->hasvmetrics = sf->hasvmetrics;
}
}
- TTF_PSDupsDefault(sf);
-#if 0
- if ( info->gsub_start==0 && info->mort_start==0 && info->morx_start==0 ) {
- /* Get default ligature values, etc. */
- k=0;
- do {
- _sf = k<sf->subfontcnt?sf->subfonts[k]:sf;
- for ( i=0; i<sf->glyphcnt; ++i ) {
- if ( _sf->glyphs[i]!=NULL ) /* Might be null in ttc files */
- SCLigDefault(_sf->glyphs[i]);
- }
- ++k;
- } while ( k<sf->subfontcnt );
- }
-#endif
/* I thought the languages were supposed to be ordered, but it seems */
/* that is not always the case. Order everything, just in case */
@@ -6382,11 +6374,13 @@ return( SFFillFromTTFInfo(&info));
SplineFont *SFReadTTFInfo(char *filename, int flags, enum openflags openflags) {
FILE *ttf;
SplineFont *sf;
- char *temp=filename, *pt, *lparen;
+ char *temp=filename, *pt, *lparen, *rparen;
pt = strrchr(filename,'/');
if ( pt==NULL ) pt = filename;
- if ( (lparen=strchr(pt,'('))!=NULL && strchr(lparen,')')!=NULL ) {
+ if ( (lparen = strrchr(pt,'('))!=NULL &&
+ (rparen = strrchr(lparen,')'))!=NULL &&
+ rparen[1]=='\0' ) {
temp = copy(filename);
pt = temp + (lparen-filename);
*pt = '\0';
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c
index 8b86752fc20..fa466564027 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c
@@ -316,7 +316,10 @@ static uint16 *getClassDefTable(FILE *ttf, int classdef_offset, struct ttfinfo *
} else if ( ftell(ttf)+2*glyphcnt > g_bounds ) {
LogError( _("Class definition sub-table extends beyond end of table\n") );
info->bad_ot = true;
- glyphcnt = (g_bounds-ftell(ttf))/2;
+ if (g_bounds<ftell(ttf))
+ glyphcnt = 0;
+ else
+ glyphcnt = (g_bounds-ftell(ttf))/2;
}
for ( i=0; i<glyphcnt; ++i )
glist[start+i] = getushort(ttf);
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c
index c5e4958d0f5..cb3b0676699 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c
@@ -36,6 +36,10 @@
# include <ieeefp.h> /* Solaris defines isnan in ieeefp rather than math.h */
#endif
+int THdo_hint_guessing = 0;
+int THdo_set_reversing = 0;
+int THdo_catagorize = 0;
+
typedef struct _io {
char *macro, *start;
FILE *ps, *fog;
@@ -2673,7 +2677,7 @@ static void EntityDefaultStrokeFill(Entity *ent) {
static SplinePointList *SplinesFromEntityChar(EntityChar *ec,int *flags,int is_stroked) {
Entity *ent, *next;
- SplinePointList *head=NULL, *last, *new, *nlast, *temp, *each, *transed;
+ SplinePointList *head=NULL, *last=NULL, *new, *nlast=NULL, *temp, *each, *transed;
StrokeInfo si;
real inversetrans[6];
/*SplineSet *spl;*/
@@ -4072,7 +4076,8 @@ SplineChar *PSCharStringToSplines(uint8 *type1, int len, struct pscontext *conte
done:
if ( pcsp!=0 )
LogError( _("end of subroutine reached with no return in %s\n"), name );
- SCCatagorizePoints(ret);
+ if (THdo_catagorize)
+ SCCatagorizePoints(ret);
ret->hstem = HintsAppend(ret->hstem,activeh); activeh=NULL;
ret->vstem = HintsAppend(ret->vstem,activev); activev=NULL;
@@ -4097,27 +4102,699 @@ SplineChar *PSCharStringToSplines(uint8 *type1, int len, struct pscontext *conte
SplineMake3(cur->last,cur->first);
cur->last = cur->first;
}
-
/* Oh, I see. PS and TT disagree on which direction to use, so Fontographer*/
/* chose the TT direction and we must reverse postscript */
- for ( cur = ret->layers[ly_fore].splines; cur!=NULL; cur = cur->next )
+ if (THdo_set_reversing) {
+ for ( cur = ret->layers[ly_fore].splines; cur!=NULL; cur = cur->next )
SplineSetReverse(cur);
+ }
if ( ret->hstem==NULL && ret->vstem==NULL )
ret->manualhints = false;
if ( !is_type2 && context->instance_count!=0 ) {
UnblendFree(ret->hstem);
UnblendFree(ret->vstem);
}
- ret->hstem = HintCleanup(ret->hstem,true,context->instance_count);
- ret->vstem = HintCleanup(ret->vstem,true,context->instance_count);
- SCGuessHHintInstancesList(ret,ly_fore);
- SCGuessVHintInstancesList(ret,ly_fore);
- ret->hconflicts = StemListAnyConflicts(ret->hstem);
- ret->vconflicts = StemListAnyConflicts(ret->vstem);
- if ( context->instance_count==1 && !ret->hconflicts && !ret->vconflicts )
+ if (THdo_hint_guessing) {
+ ret->hstem = HintCleanup(ret->hstem,true,context->instance_count);
+ ret->vstem = HintCleanup(ret->vstem,true,context->instance_count);
+ SCGuessHHintInstancesList(ret,ly_fore);
+ SCGuessVHintInstancesList(ret,ly_fore);
+ ret->hconflicts = StemListAnyConflicts(ret->hstem);
+ ret->vconflicts = StemListAnyConflicts(ret->vstem);
+ if ( context->instance_count==1 && !ret->hconflicts && !ret->vconflicts )
SCClearHintMasks(ret,ly_fore,false);
- HintsRenumber(ret);
+ HintsRenumber(ret);
+ }
if ( name!=NULL && strcmp(name,".notdef")!=0 )
ret->widthset = true;
return( ret );
}
+
+
+/* This finds the 'connect-the-dots' boundingbox of a Type2 charstring */
+/* It is a simplified version of PSCharStringToSplines, above */
+
+SplineChar *PSCharStringToBB(uint8 *type1, int len, struct pscontext *context,
+ struct pschars *subrs, struct pschars *gsubrs, const char *name) {
+ real stack[50]; int sp=0, v; /* Type1 stack is about 25 long, Type2 stack is 48 */
+ real transient[32];
+ SplineChar *ret = SplineCharCreate(2);
+
+ DBasePoint current, ll, ur;
+ real dx, dy, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6=0, dy6;
+
+ int first = 1; /* to flag extra set width */
+ /* subroutines may be nested to a depth of 10 */
+ struct substate { unsigned char *type1; int len; int subnum; } pcstack[11];
+ int pcsp=0;
+
+ real pops[30];
+ int popsp=0;
+ int base, polarity;
+
+ struct pschars *s;
+ int hint_cnt = 0;
+
+ int last_was_b1=false, old_last_was_b1;
+
+ ret->name = copy( name );
+ ret->unicodeenc = -1;
+ ret->width = (int16) 0x8000;
+ if ( name==NULL ) name = "unnamed";
+ ret->manualhints = true;
+ if ( !context->is_type2 ) {
+ LogError( _("Quick boundingbox mode only does CFF charstrings, not Type1 (font %s)\n"), name );
+ return (ret);
+ }
+
+ current.x = current.y = 0;
+ ll.x = ll.y = (int16) 0x7FFF;
+ ur.x = ur.y = (int16) -0x7FFF;
+
+ while ( len>0 ) {
+ if ( sp>48 ) {
+ LogError( _("Stack got too big in %s\n"), name );
+ sp = 48;
+ }
+ base = 0;
+ --len;
+ if ( (v = *type1++)>=32 ) {
+ if ( v<=246) {
+ stack[sp++] = v - 139;
+ } else if ( v<=250 ) {
+ stack[sp++] = (v-247)*256 + *type1++ + 108;
+ --len;
+ } else if ( v<=254 ) {
+ stack[sp++] = -(v-251)*256 - *type1++ - 108;
+ --len;
+ } else {
+ int val = (*type1<<24) | (type1[1]<<16) | (type1[2]<<8) | type1[3];
+ stack[sp++] = val;
+ type1 += 4;
+ len -= 4;
+ stack[sp-1] /= 65536.;
+ }
+ } else if ( v==28 ) {
+ stack[sp++] = (short) ((type1[0]<<8) | type1[1]);
+ type1 += 2;
+ len -= 2;
+ /* In the Dict tables of CFF, a 5byte fixed value is prefixed by a */
+ /* 29 code. In Type2 strings the prefix is 255. */
+ } else if ( v==12 ) {
+ old_last_was_b1 = last_was_b1; last_was_b1 = false;
+ v = *type1++;
+ --len;
+ switch ( v ) {
+ case 0: /* dotsection */
+ sp = 0;
+ break;
+ case 1: /* vstem3 */ /* specifies three v hints zones at once */
+ if ( sp<6 ) LogError( _("Stack underflow on vstem3 in %s\n"), name );
+ /* according to the standard, if there is a vstem3 there can't */
+ /* be any vstems, so there can't be any confusion about hint order */
+ /* so we don't need to worry about unblended stuff */
+ hint_cnt+=3;
+ sp = 0;
+ break;
+ case 2: /* hstem3 */ /* specifies three h hints zones at once */
+ if ( sp<6 ) LogError( _("Stack underflow on hstem3 in %s\n"), name );
+ hint_cnt+=3;
+ sp = 0;
+ break;
+ case 6: /* seac */ /* build accented characters */
+ seac:
+ if ( sp<5 ) LogError( _("Stack underflow on seac in %s\n"), name );
+ /* stack[0] must be the lsidebearing of the accent. I'm not sure why */
+ sp = 0;
+ break;
+ case 7: /* sbw */ /* generalized width/sidebearing command */
+ if ( sp<4 ) LogError( _("Stack underflow on sbw in %s\n"), name );
+ ret->lsidebearing = stack[0];
+ /* stack[1] is lsidebearing y (only for vertical writing styles, CJK) */
+ ret->width = stack[2];
+ /* stack[3] is height (for vertical writing styles, CJK) */
+ sp = 0;
+ break;
+ case 5: case 9: case 14: case 26:
+ if ( sp<1 ) LogError( _("Stack underflow on unary operator in %s\n"), name );
+ switch ( v ) {
+ case 5: stack[sp-1] = (stack[sp-1]==0); break; /* not */
+ case 9: if ( stack[sp-1]<0 ) stack[sp-1]= -stack[sp-1]; break; /* abs */
+ case 14: stack[sp-1] = -stack[sp-1]; break; /* neg */
+ case 26: stack[sp-1] = sqrt(stack[sp-1]); break; /* sqrt */
+ }
+ break;
+ case 3: case 4: case 10: case 11: case 12: case 15: case 24:
+ if ( sp<2 ) LogError( _("Stack underflow on binary operator in %s\n"), name );
+ else switch ( v ) {
+ case 3: /* and */
+ stack[sp-2] = (stack[sp-1]!=0 && stack[sp-2]!=0);
+ break;
+ case 4: /* and */
+ stack[sp-2] = (stack[sp-1]!=0 || stack[sp-2]!=0);
+ break;
+ case 10: /* add */
+ stack[sp-2] += stack[sp-1];
+ break;
+ case 11: /* sub */
+ stack[sp-2] -= stack[sp-1];
+ break;
+ case 12: /* div */
+ stack[sp-2] /= stack[sp-1];
+ break;
+ case 24: /* mul */
+ stack[sp-2] *= stack[sp-1];
+ break;
+ case 15: /* eq */
+ stack[sp-2] = (stack[sp-1]==stack[sp-2]);
+ break;
+ }
+ --sp;
+ break;
+ case 22: /* ifelse */
+ if ( sp<4 ) LogError( _("Stack underflow on ifelse in %s\n"), name );
+ else {
+ if ( stack[sp-2]>stack[sp-1] )
+ stack[sp-4] = stack[sp-3];
+ sp -= 3;
+ }
+ break;
+ case 23: /* random */
+ /* This function returns something (0,1]. It's not clear to me*/
+ /* if rand includes 0 and RAND_MAX or not, but this approach */
+ /* should work no matter what */
+ do {
+ stack[sp] = (rand()/(RAND_MAX-1));
+ } while ( stack[sp]==0 || stack[sp]>1 );
+ ++sp;
+ break;
+ case 20: /* put */
+ if ( sp<2 ) LogError( _("Too few items on stack for put in %s\n"), name );
+ else if ( stack[sp-1]<0 || stack[sp-1]>=32 ) LogError( _("Reference to transient memory out of bounds in put in %s\n"), name );
+ else {
+ transient[(int)stack[sp-1]] = stack[sp-2];
+ sp -= 2;
+ }
+ break;
+ case 21: /* get */
+ if ( sp<1 ) LogError( _("Too few items on stack for get in %s\n"), name );
+ else if ( stack[sp-1]<0 || stack[sp-1]>=32 ) LogError( _("Reference to transient memory out of bounds in put in %s\n"), name );
+ else
+ stack[sp-1] = transient[(int)stack[sp-1]];
+ break;
+ case 17: /* pop */
+ /* pops something from the postscript stack and pushes it on ours */
+ /* used to get a return value from an othersubr call */
+ /* Bleah. Adobe wants the pops to return the arguments if we */
+ /* don't understand the call. What use is the subroutine then?*/
+ if ( popsp<=0 )
+ LogError( _("Pop stack underflow on pop in %s\n"), name );
+ else
+ stack[sp++] = pops[--popsp];
+ break;
+ case 18: /* drop */
+ if ( sp>0 ) --sp;
+ break;
+ case 27: /* dup */
+ if ( sp>=1 ) {
+ stack[sp] = stack[sp-1];
+ ++sp;
+ }
+ break;
+ case 28: /* exch */
+ if ( sp>=2 ) {
+ real temp = stack[sp-1];
+ stack[sp-1] = stack[sp-2]; stack[sp-2] = temp;
+ }
+ break;
+ case 29: /* index */
+ if ( sp>=1 ) {
+ int index = stack[--sp];
+ if ( index<0 || sp<index+1 )
+ LogError( _("Index out of range in %s\n"), name );
+ else {
+ stack[sp] = stack[sp-index-1];
+ ++sp;
+ }
+ }
+ break;
+ case 30: /* roll */
+ if ( sp>=2 ) {
+ int j = stack[sp-1], N=stack[sp-2];
+ if ( N>sp || j>=N || j<0 || N<0 )
+ LogError( _("roll out of range in %s\n"), name );
+ else if ( j==0 || N==0 )
+ /* No op */;
+ else {
+ real *temp = galloc(N*sizeof(real));
+ int i;
+ for ( i=0; i<N; ++i )
+ temp[i] = stack[sp-N+i];
+ for ( i=0; i<N; ++i )
+ stack[sp-N+i] = temp[(i+j)%N];
+ free(temp);
+ }
+ }
+ break;
+ case 33: /* setcurrentpoint */
+ if ( sp<2 ) LogError( _("Stack underflow on setcurrentpoint in %s\n"), name );
+ else {
+ current.x = stack[0];
+ current.y = stack[1];
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ }
+ sp = 0;
+ break;
+ case 34: /* hflex */
+ case 35: /* flex */
+ case 36: /* hflex1 */
+ case 37: /* flex1 */
+ dy = dy3 = dy4 = dy5 = dy6 = 0;
+ dx = stack[base++];
+ if ( v!=34 )
+ dy = stack[base++];
+ dx2 = stack[base++];
+ dy2 = stack[base++];
+ dx3 = stack[base++];
+ if ( v!=34 && v!=36 )
+ dy3 = stack[base++];
+ dx4 = stack[base++];
+ if ( v!=34 && v!=36 )
+ dy4 = stack[base++];
+ dx5 = stack[base++];
+ if ( v==34 )
+ dy5 = -dy2;
+ else
+ dy5 = stack[base++];
+ switch ( v ) {
+ real xt, yt;
+ case 35: /* flex */
+ dx6 = stack[base++];
+ dy6 = stack[base++];
+ break;
+ case 34: /* hflex */
+ dx6 = stack[base++];
+ break;
+ case 36: /* hflex1 */
+ dx6 = stack[base++];
+ dy6 = -dy-dy2-dy5;
+ break;
+ case 37: /* flex1 */
+ xt = dx+dx2+dx3+dx4+dx5;
+ yt = dy+dy2+dy3+dy4+dy5;
+ if ( xt<0 ) xt= -xt;
+ if ( yt<0 ) yt= -yt;
+ if ( xt>yt ) {
+ dx6 = stack[base++];
+ dy6 = -dy-dy2-dy3-dy4-dy5;
+ } else {
+ dy6 = stack[base++];
+ dx6 = -dx-dx2-dx3-dx4-dx5;
+ }
+ break;
+ }
+ current.x = current.x+dx; current.y = current.y+dy;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ current.x = current.x+dx2; current.y = current.y+dy2;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ current.x = current.x+dx3; current.y = current.y+dy3;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+
+ current.x = current.x+dx4; current.y = current.y+dy4;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ current.x = current.x+dx5; current.y = current.y+dy5;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ current.x = current.x+dx6; current.y = current.y+dy6;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ sp = 0;
+ break;
+ default:
+ LogError( _("Uninterpreted opcode 12,%d in %s\n"), v, name );
+ break;
+ }
+ } else { last_was_b1 = false; switch ( v ) {
+ case 1: /* hstem */
+ case 18: /* hstemhm */
+ base = 0;
+ if ( (sp&1) && ret->width == (int16) 0x8000 )
+ ret->width = stack[0];
+ if ( sp&1 )
+ base=1;
+ if ( sp-base<2 )
+ LogError( _("Stack underflow on hstem in %s\n"), name );
+ /* stack[0] is absolute y for start of horizontal hint */
+ /* (actually relative to the y specified as lsidebearing y in sbw*/
+ /* stack[1] is relative y for height of hint zone */
+
+
+ while ( sp-base>=2 ) {
+ hint_cnt++;
+ base+=2;
+ }
+ sp = 0;
+ break;
+ case 19: /* hintmask */
+ case 20: /* cntrmask */
+ /* If there's anything on the stack treat it as a vstem hint */
+ case 3: /* vstem */
+ case 23: /* vstemhm */
+ base = 0;
+ if ( first || v==3 || v==23 ) {
+ if ( (sp&1) && ret->width == (int16) 0x8000 ) {
+ ret->width = stack[0];
+ }
+ if ( sp&1 )
+ base=1;
+ if ( sp-base<2 && v!=19 && v!=20 )
+ LogError( _("Stack underflow on vstem in %s\n"), name );
+ /* stack[0] is absolute x for start of vertical hint */
+ /* (actually relative to the x specified as lsidebearing in h/sbw*/
+ /* stack[1] is relative x for height of hint zone */
+
+
+ while ( sp-base>=2 ) {
+ hint_cnt++;
+ base+=2;
+ }
+ sp = 0;
+ }
+ if ( v==19 || v==20 ) { /* hintmask, cntrmask */
+ unsigned bytes = (hint_cnt+7)/8;
+ if ( bytes>sizeof(HintMask) ) bytes = sizeof(HintMask);
+ if ( bytes!=(unsigned)hint_cnt/8 ) {
+ int mask = 0xff>>(hint_cnt&7);
+ if ( type1[bytes-1]&mask )
+ LogError( _("Hint mask (or counter mask) with too many hints in %s\n"), name );
+ }
+ type1 += bytes;
+ len -= bytes;
+ }
+ break;
+ case 14: /* endchar */
+ /* endchar is allowed to terminate processing even within a subroutine */
+ if ( (sp&1) && ret->width == (int16) 0x8000 )
+ ret->width = stack[0];
+ pcsp = 0;
+ if ( sp==4 ) {
+ /* In Type2 strings endchar has a depreciated function of doing */
+ /* a seac (which doesn't exist at all). Except enchar takes */
+ /* 4 args and seac takes 5. Bleah */
+ stack[4] = stack[3]; stack[3] = stack[2]; stack[2] = stack[1]; stack[1] = stack[0];
+ stack[0] = 0;
+ sp = 5;
+ goto seac;
+ } else if ( sp==5 ) {
+ /* same as above except also specified a width */
+ stack[0] = 0;
+ goto seac;
+ }
+ /* the docs say that endchar must be the last command in a char */
+ goto done;
+ break;
+ case 13: /* hsbw (set left sidebearing and width) */
+ if ( sp<2 ) LogError( _("Stack underflow on hsbw in %s\n"), name );
+ ret->lsidebearing = stack[0];
+ current.x = stack[0]; /* sets the current point too */
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ ret->width = stack[1];
+ sp = 0;
+ break;
+ case 9: /* closepath */
+ sp = 0;
+ break;
+ case 21: /* rmoveto */
+ case 22: /* hmoveto */
+ case 4: /* vmoveto */
+ if (( (v==21 && sp==3) || (v!=21 && sp==2)) && ret->width == (int16) 0x8000 )
+ /* Character's width may be specified on the first moveto */
+ ret->width = stack[0];
+ if ( v==21 && sp>2 ) {
+ stack[0] = stack[sp-2]; stack[1] = stack[sp-1];
+ sp = 2;
+ } else if ( v!=21 && sp>1 ) {
+ stack[0] = stack[sp-1];
+ sp = 1;
+ }
+ /* fall through */
+ case 5: /* rlineto */
+ case 6: /* hlineto */
+ case 7: /* vlineto */
+ polarity = 0;
+ base = 0;
+ while ( base<sp ) {
+ dx = dy = 0;
+ if ( v==5 || v==21 ) {
+ if ( sp<base+2 ) {
+ LogError( _("Stack underflow on rlineto/rmoveto in %s\n"), name );
+ break;
+ }
+ dx = stack[base++];
+ dy = stack[base++];
+ } else if ( (v==6 && !(polarity&1)) || (v==7 && (polarity&1)) || v==22 ) {
+ if ( sp<=base ) {
+ LogError( _("Stack underflow on hlineto/hmoveto in %s\n"), name );
+ break;
+ }
+ dx = stack[base++];
+ } else /*if ( (v==7 && !(parity&1)) || (v==6 && (parity&1) || v==4 )*/ {
+ if ( sp<=base ) {
+ LogError( _("Stack underflow on vlineto/vmoveto in %s\n"), name );
+ break;
+ }
+ dy = stack[base++];
+ }
+ ++polarity;
+ current.x = current.x+dx; current.y = current.y+dy;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ if ( v==4 || v==21 || v==22 ) {
+ first = 0;
+ break;
+ } else {
+ first = 0;
+ }
+ }
+ sp = 0;
+ break;
+ case 25: /* rlinecurve */
+ base = 0;
+ while ( sp>base+6 ) {
+ current.x = current.x+stack[base++]; current.y = current.y+stack[base++];
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ first = 0;
+ }
+ case 24: /* rcurveline */
+ case 8: /* rrcurveto */
+ case 31: /* hvcurveto */
+ case 30: /* vhcurveto */
+ case 27: /* hhcurveto */
+ case 26: /* vvcurveto */
+ polarity = 0;
+ while ( sp>base+2 ) {
+ dx = dy = dx2 = dy2 = dx3 = dy3 = 0;
+ if ( v==8 || v==25 || v==24 ) {
+ if ( sp<6+base ) {
+ LogError( _("Stack underflow on rrcurveto in %s\n"), name );
+ base = sp;
+ } else {
+ dx = stack[base++];
+ dy = stack[base++];
+ dx2 = stack[base++];
+ dy2 = stack[base++];
+ dx3 = stack[base++];
+ dy3 = stack[base++];
+ }
+ } else if ( v==27 ) { /* hhcurveto */
+ if ( sp<4+base ) {
+ LogError( _("Stack underflow on hhcurveto in %s\n"), name );
+ base = sp;
+ } else {
+ if ( (sp-base)&1 ) dy = stack[base++];
+ dx = stack[base++];
+ dx2 = stack[base++];
+ dy2 = stack[base++];
+ dx3 = stack[base++];
+ }
+ } else if ( v==26 ) { /* vvcurveto */
+ if ( sp<4+base ) {
+ LogError( _("Stack underflow on hhcurveto in %s\n"), name );
+ base = sp;
+ } else {
+ if ( (sp-base)&1 ) dx = stack[base++];
+ dy = stack[base++];
+ dx2 = stack[base++];
+ dy2 = stack[base++];
+ dy3 = stack[base++];
+ }
+ } else if ( (v==31 && !(polarity&1)) || (v==30 && (polarity&1)) ) {
+ if ( sp<4+base ) {
+ LogError( _("Stack underflow on hvcurveto in %s\n"), name );
+ base = sp;
+ } else {
+ dx = stack[base++];
+ dx2 = stack[base++];
+ dy2 = stack[base++];
+ dy3 = stack[base++];
+ if ( sp==base+1 )
+ dx3 = stack[base++];
+ }
+ } else /*if ( (v==30 && !(polarity&1)) || (v==31 && (polarity&1)) )*/ {
+ if ( sp<4+base ) {
+ LogError( _("Stack underflow on vhcurveto in %s\n"), name );
+ base = sp;
+ } else {
+ dy = stack[base++];
+ dx2 = stack[base++];
+ dy2 = stack[base++];
+ dx3 = stack[base++];
+ if ( sp==base+1 )
+ dy3 = stack[base++];
+ }
+ }
+ ++polarity;
+ current.x = current.x+dx; current.y = current.y+dy;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ current.x = current.x+dx2; current.y = current.y+dy2;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ current.x = current.x+dx3; current.y = current.y+dy3;
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ }
+ if ( v==24 ) {
+ current.x = current.x+stack[base++]; current.y = current.y+stack[base++];
+ if (ll.y>current.y) ll.y = current.y;
+ if (ur.y<current.y) ur.y = current.y;
+ if (ll.x>current.x) ll.x = current.x;
+ if (ur.x<current.x) ur.x = current.x;
+ }
+ sp = 0;
+ break;
+ case 29: /* callgsubr */
+ case 10: /* callsubr */
+ /* stack[sp-1] contains the number of the subroutine to call */
+ if ( sp<1 ) {
+ LogError( _("Stack underflow on callsubr in %s\n"), name );
+ break;
+ } else if ( pcsp>10 ) {
+ LogError( _("Too many subroutine calls in %s\n"), name );
+ break;
+ }
+ s=subrs; if ( v==29 ) s = gsubrs;
+ if ( s!=NULL ) stack[sp-1] += s->bias;
+ /* Type2 subrs have a bias that must be added to the subr-number */
+ /* Type1 subrs do not. We set the bias on them to 0 */
+ if ( s==NULL || stack[sp-1]>=s->cnt || stack[sp-1]<0 ||
+ s->values[(int) stack[sp-1]]==NULL )
+ LogError( _("Subroutine number out of bounds in %s\n"), name );
+ else {
+ pcstack[pcsp].type1 = type1;
+ pcstack[pcsp].len = len;
+ pcstack[pcsp].subnum = stack[sp-1];
+ ++pcsp;
+ type1 = s->values[(int) stack[sp-1]];
+ len = s->lens[(int) stack[sp-1]];
+ }
+ if ( --sp<0 ) sp = 0;
+ break;
+ case 11: /* return */
+ /* return from a subr outine */
+ if ( pcsp<1 ) LogError( _("return when not in subroutine in %s\n"), name );
+ else {
+ --pcsp;
+ type1 = pcstack[pcsp].type1;
+ len = pcstack[pcsp].len;
+ }
+ break;
+ case 16: { /* blend -- obsolete type 2 multiple master operator */
+ int cnt,i,j;
+ if ( context->instance_count==0 )
+ LogError( _("Attempt to use a multiple master subroutine in a non-mm font.\n") );
+ else if ( sp<1 || sp<context->instance_count*stack[sp-1]+1 )
+ LogError( _("Too few items on stack for blend in %s\n"), name );
+ else {
+ if ( !context->blend_warn ) {
+ LogError( _("Use of obsolete blend operator.\n") );
+ context->blend_warn = true;
+ }
+ cnt = stack[sp-1];
+ sp -= context->instance_count*stack[sp-1]+1;
+ for ( i=0; i<cnt; ++i ) {
+ for ( j=1; j<context->instance_count; ++j )
+ stack[sp+i] += context->blend_values[j]*stack[sp+
+ cnt+ i*(context->instance_count-1)+ j-1];
+ }
+ /* there will always be fewer pushes than there were pops */
+ /* so I don't bother to check the stack */
+ sp += cnt;
+ }
+ }
+ break;
+ default:
+ LogError( _("Uninterpreted opcode %d in %s\n"), v, name );
+ break;
+ }}
+ }
+done:
+ if ( pcsp!=0 )
+ LogError( _("end of subroutine reached with no return in %s\n"), name );
+
+ if ( name!=NULL && strcmp(name,".notdef")!=0 )
+ ret->widthset = true;
+ if (ur.x == -0x7FFF) ur.x = 0;
+ if (ur.y == -0x7FFF) ur.y = 0;
+ if (ll.x == 0x7FFF) ll.x = 0;
+ if (ll.y == 0x7FFF) ll.y = 0;
+ if (ll.x>ur.x) ll.x = ur.x;
+ if (ll.y>ur.y) ll.y = ur.y;
+
+
+ ret->xmin = rint(ll.x);
+ ret->ymin = rint(ll.y);
+ ret->xmax = rint(ur.x);
+ ret->ymax = rint(ur.y);
+ /* free the curves */
+ if (ret->layers!=NULL && ret->layers[ly_fore].splines != NULL) {
+ SplinePointListsFree(ret->layers[ly_fore].splines);
+ ret->layers[ly_fore].splines=NULL;
+ }
+ if (ret->layers[ly_fore].refs!=NULL) {
+ RefCharsFree(ret->layers[ly_fore].refs);
+ ret->layers[ly_fore].refs = NULL;
+ }
+ return( ret );
+}
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c
index 1fa40c46072..9f0ed92305f 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c
@@ -498,7 +498,7 @@ return( _ReadSplineFont(NULL,filename,openflags));
SplineFont *ReadSplineFontInfo(char *filename,enum openflags openflags) {
SplineFont *sf, *sf_ptr;
char **fontlist;
- char *pt =NULL, *strippedname=filename, *paren=NULL, *fullname=filename;
+ char *pt =NULL, *strippedname=filename, *paren=NULL, *rparen=NULL, *fullname=filename;
FILE *foo = NULL;
int checked = 0;
char s[512] = {0};
@@ -508,9 +508,14 @@ return( NULL );
pt = strrchr(filename,'/');
if ( pt==NULL ) pt = filename;
- if ( (paren=strchr(pt,'('))!=NULL && strchr(paren,')')!=NULL ) {
- strippedname = copy(filename);
- strippedname[paren-filename] = '\0';
+ /* Someone gave me a font "Nafees Nastaleeq(Updated).ttf" and complained */
+ /* that ff wouldn't open it */
+ /* Now someone will complain about "Nafees(Updated).ttc(fo(ob)ar)" */
+ if ( (paren = strrchr(pt,'('))!=NULL &&
+ (rparen = strrchr(paren,')'))!=NULL &&
+ rparen[1]=='\0' ) {
+ strippedname = copy(filename);
+ strippedname[paren-filename] = '\0';
}
sf = NULL;
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h
index fa989d61543..a15b6b75325 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h
@@ -1866,8 +1866,11 @@ struct findsel;
struct charprocs;
struct enc;
-extern void *chunkalloc(int size);
-extern void chunkfree(void *, int size);
+/* extern void *chunkalloc(int size); */
+/* extern void chunkfree(void *, int size); */
+
+#define chunkalloc(size) gcalloc(1,size)
+#define chunkfree(item,size) free(item)
extern char *strconcat(const char *str, const char *str2);
extern char *strconcat3(const char *str, const char *str2, const char *str3);
@@ -1946,7 +1949,6 @@ extern long mactime(void);
extern int WriteSVGFont(char *fontname,SplineFont *sf,enum fontformat format,int flags,EncMap *enc,int layer);
extern int WriteUFOFont(char *fontname,SplineFont *sf,enum fontformat format,int flags,EncMap *enc,int layer);
extern void SfListFree(struct sflist *sfs);
-extern void TTF_PSDupsDefault(SplineFont *sf);
extern void DefaultTTFEnglishNames(struct ttflangname *dummy, SplineFont *sf);
extern void TeXDefaultParams(SplineFont *sf);
extern int AlreadyMSSymbolArea(SplineFont *sf,EncMap *map);
@@ -2506,6 +2508,7 @@ extern SplineFont *_SFDRead(char *filename,FILE *sfd);
extern SplineFont *SFDirRead(char *filename);
extern SplineChar *SFDReadOneChar(SplineFont *sf,const char *name);
extern char *TTFGetFontName(FILE *ttf,int32 offset,int32 off2);
+extern char *TTFGetPSFontName(FILE *ttf,int32 offset,int32 off2);
extern void TTFLoadBitmaps(FILE *ttf,struct ttfinfo *info, int onlyone);
enum ttfflags { ttf_onlystrikes=1, ttf_onlyonestrike=2, ttf_onlykerns=4, ttf_onlynames=8 };
extern SplineFont *_SFReadTTF(FILE *ttf,int flags,enum openflags openflags,
@@ -2601,6 +2604,8 @@ struct pscontext {
extern int UnblendedCompare(real u1[MmMax], real u2[MmMax], int cnt);
extern SplineChar *PSCharStringToSplines(uint8 *type1, int len, struct pscontext *context,
struct pschars *subrs, struct pschars *gsubrs, const char *name);
+extern SplineChar *PSCharStringToBB(uint8 *type1, int len, struct pscontext *context,
+ struct pschars *subrs, struct pschars *gsubrs, const char *name);
extern void MatMultiply(real m1[6], real m2[6], real to[6]);
extern int NameToEncoding(SplineFont *sf,EncMap *map,const char *uname);
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c
index 43626aec6dc..ce80d837f87 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c
@@ -1377,7 +1377,7 @@ Spline *SplineAddExtrema(Spline *s,int always,real lenbound, real offsetbound,
uint8 rmfrom[4], rmto[4];
int p, i,j, p_s, mini;
SplinePoint *sp;
- real len;
+ real len = 0; /* Init variable to silence compiler warnings */
if ( !always ) {
real xlen, ylen;
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c
index e5722cfc27d..559867543f2 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c
@@ -95,6 +95,8 @@ return( false );
if ( features->ismac || OTTagToMacFeature(features->featuretag,&ft,&fs))
return( true );
}
+ default: /* handle this to silence compiler warnings */
+ break;
}
return( false );
}
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/chardata.h b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/chardata.h
index fd2247f7e1b..cfeaf7a24d5 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/chardata.h
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/chardata.h
@@ -72,7 +72,3 @@ extern struct charmap2 johab_from_unicode;
extern const unichar_t unicode_from_gb2312[];
extern struct charmap2 gb2312_from_unicode;
-/* a mask for each character saying what charset(s) it may be found in */
-extern const unsigned long * const unicode_backtrans[];
-
-extern const unichar_t *const * const unicode_alternates[];
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/ustring.h b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/ustring.h
index a5e21e87dc9..22e0a55a189 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/ustring.h
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/inc/ustring.h
@@ -105,7 +105,6 @@ extern char *utf8_2_latin1_copy(const char *utf8buf);
extern int utf8_strlen(const char *utf8_str); /* how many characters in the string */
extern int utf82u_strlen(const char *utf8_str); /* how many long would this be in shorts (UCS2) */
extern char *def2utf8_copy(const char *from);
-extern char *utf82def_copy(const char *ufrom);
extern char *utf8_strchr(const char *utf8_str, int search_char);
extern unichar_t *utf82u_strncpy(unichar_t *ubuf,const char *utf8buf,int len);
@@ -117,11 +116,8 @@ extern char *u2utf8_strcpy(char *utf8buf,const unichar_t *ubuf);
extern char *u2utf8_copy(const unichar_t *ubuf);
extern char *u2utf8_copyn(const unichar_t *ubuf,int len);
extern unichar_t *encoding2u_strncpy(unichar_t *uto, const char *from, int n, enum encoding cs);
-extern char *u2encoding_strncpy(char *to, const unichar_t *ufrom, int n, enum encoding cs);
extern unichar_t *def2u_strncpy(unichar_t *uto, const char *from, int n);
-extern char *u2def_strncpy(char *to, const unichar_t *ufrom, int n);
extern unichar_t *def2u_copy(const char *from);
-extern char *u2def_copy(const unichar_t *ufrom);
extern int u_sprintf(unichar_t *str, const unichar_t *format, ... );
extern int u_snprintf(unichar_t *str, int len, const unichar_t *format, ... );
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/src/ffdummies.c b/Build/source/texk/web2c/luatexdir/luafontloader/src/ffdummies.c
index 88757af288c..731eafe7430 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/src/ffdummies.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/src/ffdummies.c
@@ -1,3 +1,21 @@
+/* ffdummies.c
+
+ Copyright 2006-2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
/* some dummy functions and variables so that a few ff source files can be ignored */
@@ -9,154 +27,195 @@
#include <basics.h>
#include <ustring.h>
+static const char _svn_version[] =
+ "$Id: ffdummies.c 3360 2010-01-12 21:12:15Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/luafontloader/src/ffdummies.c $";
+
char **gww_errors = NULL;
int gww_error_count = 0;
-void gwwv_errors_free (void) {
- int i;
- if (gww_error_count>0) {
- for (i=0;i<gww_error_count;i++) {
- free(gww_errors[i]);
- }
- free(gww_errors);
- gww_error_count = 0;
- gww_errors = NULL;
- }
+void gwwv_errors_free(void)
+{
+ int i;
+ if (gww_error_count > 0) {
+ for (i = 0; i < gww_error_count; i++) {
+ free(gww_errors[i]);
+ }
+ free(gww_errors);
+ gww_error_count = 0;
+ gww_errors = NULL;
+ }
}
-
-static void LUAUI_IError(const char *format,...) {
+__attribute__ ((format(printf, 1, 0)))
+static void LUAUI_IError(const char *format, ...)
+{
va_list ap;
- va_start(ap,format);
- fprintf(stderr, "Internal Error: " );
- vfprintf(stderr,format,ap);
+ size_t l;
+ char buffer[400], *str;
+ l = strlen("Internal Error: ");
+ snprintf(buffer, sizeof(buffer), "Internal Error: ");
+ va_start(ap, format);
+ vsnprintf(buffer+l, sizeof(buffer)-l, format, ap);
va_end(ap);
+ str = xstrdup((char *) buffer);
+ gww_errors = realloc(gww_errors, (gww_error_count + 2) * sizeof(char *));
+ if (gww_errors == NULL) {
+ perror("memory allocation failed");
+ exit(EXIT_FAILURE);
+ }
+ gww_errors[gww_error_count] = str;
+ gww_error_count++;
+ gww_errors[gww_error_count] = NULL;
}
-static void LUAUI__LogError(const char *format,va_list ap) {
+__attribute__ ((format(printf, 1, 0)))
+static void LUAUI__LogError(const char *format, va_list ap)
+{
char buffer[400], *str;
- vsnprintf(buffer,sizeof(buffer),format,ap);
- str = utf82def_copy(buffer);
- gww_errors = realloc(gww_errors, (gww_error_count+2)*sizeof(char *));
- if (gww_errors==NULL) {
- perror("memory allocation failed");
- exit(EXIT_FAILURE);
+ vsnprintf(buffer, sizeof(buffer), format, ap);
+ str = xstrdup((char *) buffer);
+ gww_errors = realloc(gww_errors, (gww_error_count + 2) * sizeof(char *));
+ if (gww_errors == NULL) {
+ perror("memory allocation failed");
+ exit(EXIT_FAILURE);
}
- gww_errors[gww_error_count ] = str ;
- gww_error_count ++;
- gww_errors[gww_error_count ] = NULL;
+ gww_errors[gww_error_count] = str;
+ gww_error_count++;
+ gww_errors[gww_error_count] = NULL;
}
/* this is not static because it is used by gwwiconv.c */
-void LUAUI_LogError(const char *format,...) {
+__attribute__ ((format(printf, 1, 2)))
+void LUAUI_LogError(const char *format, ...)
+{
va_list ap;
- va_start(ap,format);
- LUAUI__LogError(format,ap);
+ va_start(ap, format);
+ LUAUI__LogError(format, ap);
va_end(ap);
}
-static void LUAUI_post_notice(const char *title,const char *statement,...) {
+__attribute__ ((format(printf, 2, 3)))
+static void LUAUI_post_notice(const char *title, const char *statement, ...)
+{
va_list ap;
- (void)title;
- va_start(ap,statement);
- LUAUI__LogError(statement,ap);
+ (void) title;
+ va_start(ap, statement);
+ LUAUI__LogError(statement, ap);
va_end(ap);
}
-static void LUAUI_post_error(const char *title,const char *statement,...) {
+__attribute__ ((format(printf, 2, 3)))
+static void LUAUI_post_error(const char *title, const char *statement, ...)
+{
va_list ap;
- (void)title;
- va_start(ap,statement);
- LUAUI__LogError(statement,ap);
+ (void) title;
+ va_start(ap, statement);
+ LUAUI__LogError(statement, ap);
va_end(ap);
}
static int LUAUI_ask(const char *title, const char **answers,
- int def, int cancel,const char *question,...) {
- (void)title;
- (void)answers;
- (void)cancel;
- (void)question;
-return( def );
+ int def, int cancel, const char *question, ...)
+{
+ (void) title;
+ (void) answers;
+ (void) cancel;
+ (void) question;
+ return (def);
}
-static int LUAUI_choose(const char *title, const char **choices,int cnt, int def,
- const char *question,...) {
- (void)title;
- (void)choices;
- (void)cnt;
- (void)question;
-return( def );
+static int LUAUI_choose(const char *title, const char **choices, int cnt,
+ int def, const char *question, ...)
+{
+ (void) title;
+ (void) choices;
+ (void) cnt;
+ (void) question;
+ return (def);
}
-static int LUAUI_choose_multiple(char *title, const char **choices,char *sel,
- int cnt, char *buts[2], const char *question,...) {
- (void)title;
- (void)choices;
- (void)sel;
- (void)cnt;
- (void)buts;
- (void)question;
-return( -1 );
+static int LUAUI_choose_multiple(char *title, const char **choices, char *sel,
+ int cnt, char *buts[2], const char *question,
+ ...)
+{
+ (void) title;
+ (void) choices;
+ (void) sel;
+ (void) cnt;
+ (void) buts;
+ (void) question;
+ return (-1);
}
static char *LUAUI_ask_string(const char *title, const char *def,
- const char *question,...) {
- (void)title;
- (void)def;
- (void)question;
-return( (char *) def );
+ const char *question, ...)
+{
+ (void) title;
+ (void) def;
+ (void) question;
+ return ((char *) def);
}
static char *LUAUI_open_file(const char *title, const char *defaultfile,
- const char *initial_filter) {
- (void)title;
- (void)initial_filter;
- (void)defaultfile;
-return( NULL );
+ const char *initial_filter)
+{
+ (void) title;
+ (void) initial_filter;
+ (void) defaultfile;
+ return (NULL);
}
static char *LUAUI_saveas_file(const char *title, const char *defaultfile,
- const char *initial_filter) {
- (void)title;
- (void)initial_filter;
-return( copy(defaultfile) );
+ const char *initial_filter)
+{
+ (void) title;
+ (void) initial_filter;
+ return (copy(defaultfile));
}
-static void LUAUI_progress_start(int delay, const char *title, const char *line1,
- const char *line2, int tot, int stages) {
- (void)delay;
- (void)title;
- (void)line1;
- (void)line2;
- (void)tot;
- (void)stages;
+static void LUAUI_progress_start(int delay, const char *title,
+ const char *line1, const char *line2, int tot,
+ int stages)
+{
+ (void) delay;
+ (void) title;
+ (void) line1;
+ (void) line2;
+ (void) tot;
+ (void) stages;
}
-static void LUAUI_void_void_noop(void) {
+static void LUAUI_void_void_noop(void)
+{
}
-static void LUAUI_void_int_noop(int useless) {
- (void)useless;
+static void LUAUI_void_int_noop(int useless)
+{
+ (void) useless;
}
-static int LUAUI_int_int_noop(int useless) {
- (void)useless;
-return( true );
+static int LUAUI_int_int_noop(int useless)
+{
+ (void) useless;
+ return (true);
}
-static void LUAUI_void_str_noop(const char * useless) {
- (void)useless;
+static void LUAUI_void_str_noop(const char *useless)
+{
+ (void) useless;
}
-static int LUAUI_alwaystrue(void) {
-return( true );
+static int LUAUI_alwaystrue(void)
+{
+ return (true);
}
-static int LUAUI_DefaultStrokeFlags(void) {
-return( sf_correctdir );
+static int LUAUI_DefaultStrokeFlags(void)
+{
+ return (sf_correctdir);
}
struct ui_interface luaui_interface = {
@@ -168,7 +227,7 @@ struct ui_interface luaui_interface = {
LUAUI_choose,
LUAUI_choose_multiple,
LUAUI_ask_string,
- LUAUI_ask_string, /* password */
+ LUAUI_ask_string, /* password */
LUAUI_open_file,
LUAUI_saveas_file,
@@ -197,60 +256,71 @@ struct ui_interface luaui_interface = {
/* some bits and pieces */
-int URLFromFile(char *url,FILE *from) {
- (void)url;
- (void)from;
- return false;
+int URLFromFile(char *url, FILE * from)
+{
+ (void) url;
+ (void) from;
+ return false;
}
/* print.c */
-int pagewidth = 0, pageheight=0; /* In points */
-char *printlazyprinter=NULL;
-char *printcommand=NULL;
+int pagewidth = 0, pageheight = 0; /* In points */
+char *printlazyprinter = NULL;
+char *printcommand = NULL;
int printtype = 0;
-void ScriptPrint(FontViewBase *fv,int type,int32 *pointsizes,char *samplefile,
- unichar_t *sample, char *outputfile) {
- (void)fv;
- (void)type;
- (void)pointsizes;
- (void)samplefile;
- (void)sample;
- (void)outputfile;
+void ScriptPrint(FontViewBase * fv, int type, int32 * pointsizes,
+ char *samplefile, unichar_t * sample, char *outputfile)
+{
+ (void) fv;
+ (void) type;
+ (void) pointsizes;
+ (void) samplefile;
+ (void) sample;
+ (void) outputfile;
}
-int PdfDumpGlyphResources(void *pi, SplineChar *sc) {
- (void)pi;
- (void)sc;
- return 0;
+int PdfDumpGlyphResources(void *pi, SplineChar * sc)
+{
+ (void) pi;
+ (void) sc;
+ return 0;
}
/* autotrace.c */
-int autotrace_ask=0, mf_ask=0, mf_clearbackgrounds=0, mf_showerrors=0;
+int autotrace_ask = 0, mf_ask = 0, mf_clearbackgrounds = 0, mf_showerrors = 0;
char *mf_args = NULL;
-int preferpotrace=0;
+int preferpotrace = 0;
-void *GetAutoTraceArgs(void) {
-return NULL;
+void *GetAutoTraceArgs(void)
+{
+ return NULL;
}
-void SetAutoTraceArgs(void *a) {
- (void)a;
+void SetAutoTraceArgs(void *a)
+{
+ (void) a;
}
-void FVAutoTrace(FontViewBase *fv,int ask) {
- (void)fv; (void)ask;
+void FVAutoTrace(FontViewBase * fv, int ask)
+{
+ (void) fv;
+ (void) ask;
}
-SplineFont *SFFromMF(char *filename) {
- (void)filename;
-return NULL;
+SplineFont *SFFromMF(char *filename)
+{
+ (void) filename;
+ return NULL;
}
/* http.c */
-FILE *URLToTempFile(char *url,void *_lock) {
- (void)_lock; (void)url;
- ff_post_error(_("Could not parse URL"),_("FontForge only handles ftp and http URLs at the moment"));
-return( NULL );
+FILE *URLToTempFile(char *url, void *_lock)
+{
+ (void) _lock;
+ (void) url;
+ ff_post_error(_("Could not parse URL"),
+ _("FontForge only handles ftp and http URLs at the moment"));
+ return (NULL);
}
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c b/Build/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c
index 8462ae9b2e5..8b7d2bd9415 100644
--- a/Build/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c
+++ b/Build/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c
@@ -1,5 +1,23 @@
+/* luafflib.c
+
+ Copyright 2007-2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
/**
-* $Id $
* @desc Support interface for fontforge 20070607
* @version 1.0
* @author Taco Hoekwater
@@ -13,340 +31,362 @@
#include "pfaedit.h"
#include "ustring.h"
+static const char _svn_version[] =
+ "$Id: luafflib.c 3456 2010-03-07 09:12:36Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c $";
+
extern char **gww_errors;
extern int gww_error_count;
-extern void gwwv_errors_free (void);
+extern void gwwv_errors_free(void);
extern struct ui_interface luaui_interface;
-extern int readbinfile(FILE *f, unsigned char **b, int *s);
+extern int readbinfile(FILE * f, unsigned char **b, int *s);
#define FONT_METATABLE "fontloader.splinefont"
#define LUA_OTF_VERSION "0.3"
-static char *possub_type_enum[] = {
- "null", "position", "pair", "substitution",
- "alternate", "multiple", "ligature", "lcaret",
- "kerning", "vkerning", "anchors", "contextpos",
- "contextsub", "chainpos", "chainsub","reversesub",
- "max", "kernback", "vkernback", NULL };
+static char *possub_type_enum[] = {
+ "null", "position", "pair", "substitution",
+ "alternate", "multiple", "ligature", "lcaret",
+ "kerning", "vkerning", "anchors", "contextpos",
+ "contextsub", "chainpos", "chainsub", "reversesub",
+ "max", "kernback", "vkernback", NULL
+};
#define LAST_POSSUB_TYPE_ENUM 18
#define eight_nulls() NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-static char *asm_type_enum[] = {
- "indic", "context", "lig", NULL, "simple", "insert", NULL, NULL,
- eight_nulls(),
- NULL, "kern" };
-
-static char *otf_lookup_type_enum[] = {
- "gsub_start", "gsub_single", "gsub_multiple", "gsub_alternate",
- "gsub_ligature", "gsub_context", "gsub_contextchain", NULL,
- "gsub_reversecontextchain", NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*0x00F */
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(), NULL, NULL, NULL, NULL, NULL, "morx_indic", "morx_context", "morx_insert", /* 0x0FF*/
- "gpos_start", "gpos_single", "gpos_pair", "gpos_cursive",
- "gpos_mark2base", "gpos_mark2ligature", "gpos_mark2mark", "gpos_context",
- "gpos_contextchain", NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x10F */
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(),eight_nulls(),
- eight_nulls(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, "kern_statemachine", /* 0x1FF*/
+static char *asm_type_enum[] = {
+ "indic", "context", "lig", NULL, "simple", "insert", NULL, NULL,
+ eight_nulls(),
+ NULL, "kern"
+};
+
+static char *otf_lookup_type_enum[] = {
+ "gsub_start", "gsub_single", "gsub_multiple", "gsub_alternate",
+ "gsub_ligature", "gsub_context", "gsub_contextchain", NULL,
+ "gsub_reversecontextchain", NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*0x00F */
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), NULL, NULL, NULL, NULL, NULL, "morx_indic", "morx_context", "morx_insert", /* 0x0FF */
+ "gpos_start", "gpos_single", "gpos_pair", "gpos_cursive",
+ "gpos_mark2base", "gpos_mark2ligature", "gpos_mark2mark", "gpos_context",
+ "gpos_contextchain", NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x10F */
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), eight_nulls(),
+ eight_nulls(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, "kern_statemachine", /* 0x1FF */
};
-static char *anchor_type_enum[] = {
- "mark", "basechar", "baselig", "basemark", "centry", "cexit", "max", NULL };
+static char *anchor_type_enum[] = {
+ "mark", "basechar", "baselig", "basemark", "centry", "cexit", "max", NULL
+};
#define MAX_ANCHOR_TYPE 7
-static char *anchorclass_type_enum[] = {
- "mark", "mkmk", "curs", "mklg", NULL };
+static char *anchorclass_type_enum[] = {
+ "mark", "mkmk", "curs", "mklg", NULL
+};
-static char *glyph_class_enum[] = {
- "automatic", "none" ,"base", "ligature","mark", "component", NULL };
+static char *glyph_class_enum[] = {
+ "automatic", "none", "base", "ligature", "mark", "component", NULL
+};
-static char *ttfnames_enum[ttf_namemax] = {
+static char *ttfnames_enum[ttf_namemax] = {
"copyright", "family", "subfamily", "uniqueid",
"fullname", "version", "postscriptname", "trademark",
"manufacturer", "designer", "descriptor", "venderurl",
"designerurl", "license", "licenseurl", "idontknow",
"preffamilyname", "prefmodifiers", "compatfull", "sampletext",
- "cidfindfontname", "wwsfamily", "wwssubfamily" };
+ "cidfindfontname", "wwsfamily", "wwssubfamily"
+};
-static char *fpossub_format_enum [] = {
- "glyphs", "class","coverage","reversecoverage" , NULL};
+static char *fpossub_format_enum[] = {
+ "glyphs", "class", "coverage", "reversecoverage", NULL
+};
-static char *tex_type_enum[4] = { "unset", "text", "math", "mathext"};
+static char *tex_type_enum[4] = { "unset", "text", "math", "mathext" };
/* has an offset of 1, ui_none = 0. */
static char *uni_interp_enum[9] = {
- "unset", "none", "adobe", "greek", "japanese",
- "trad_chinese", "simp_chinese", "korean", "ams" };
-
+ "unset", "none", "adobe", "greek", "japanese",
+ "trad_chinese", "simp_chinese", "korean", "ams"
+};
+
#define check_isfont(L,b) (SplineFont **)luaL_checkudata(L,b,FONT_METATABLE)
-void handle_generic_pst (lua_State *L, struct generic_pst *pst); /* forward */
-void handle_generic_fpst (lua_State *L, struct generic_fpst *fpst); /* forward */
-void handle_generic_asm (lua_State *L, struct generic_asm *sm) ;
-void handle_kernclass (lua_State *L, struct kernclass *kerns);
-void handle_anchorclass (lua_State *L, struct anchorclass *anchor);
-void handle_splinefont(lua_State *L, struct splinefont *sf) ;
+void handle_generic_pst(lua_State * L, struct generic_pst *pst); /* forward */
+void handle_generic_fpst(lua_State * L, struct generic_fpst *fpst); /* forward */
+void handle_generic_asm(lua_State * L, struct generic_asm *sm);
+void handle_kernclass(lua_State * L, struct kernclass *kerns);
+void handle_anchorclass(lua_State * L, struct anchorclass *anchor);
+void handle_splinefont(lua_State * L, struct splinefont *sf);
+
+
+void lua_ff_pushfont(lua_State * L, SplineFont * sf)
+{
+ SplineFont **a;
+ if (sf == NULL) {
+ lua_pushnil(L);
+ } else {
+ a = lua_newuserdata(L, sizeof(SplineFont *));
+ *a = sf;
+ luaL_getmetatable(L, FONT_METATABLE);
+ lua_setmetatable(L, -2);
+ }
+ return;
+}
-void
-lua_ff_pushfont(lua_State *L, SplineFont *sf) {
- SplineFont **a;
- if (sf==NULL) {
- lua_pushnil(L);
- } else {
- a = lua_newuserdata(L,sizeof(SplineFont *));
- *a = sf;
- luaL_getmetatable(L,FONT_METATABLE);
- lua_setmetatable(L,-2);
- }
- return;
-}
-
-
-static int
-ff_open (lua_State *L) {
- SplineFont *sf;
- const char *fontname;
- FILE *l;
- char s[511];
- size_t len;
- int args,i ;
- int openflags = 1;
- fontname = luaL_checkstring(L,1);
- /* test fontname for existance */
- if ((l = fopen(fontname,"r"))) {
- fclose(l);
- } else {
- lua_pushfstring(L,"font loading failed for %s (read error)\n", fontname);
- lua_error(L);
- }
- args = lua_gettop(L);
- if (args>=2 && lua_isstring(L,2)) {
- if (*(fontname+strlen(fontname))!=')') {
- /* possibly fails for embedded parens in the font name */
- snprintf(s,511,"%s(%s)", fontname, lua_tolstring(L,2,&len));
- if (len==0) {
- snprintf(s,511,"%s", fontname);
- }
- }
- } else {
- snprintf(s,511,"%s", fontname);
- }
- if (strlen(s)>0) {
- gww_error_count=0;
- sf = ReadSplineFont((char *)s,openflags);
- if (sf==NULL) {
- lua_pushfstring(L,"font loading failed for %s\n", s);
- if (gww_error_count>0) {
- for (i=0;i<gww_error_count;i++) {
- lua_pushstring(L,gww_errors[i]);
- lua_concat(L,2);
- }
- gwwv_errors_free();
- }
- lua_error(L);
- } else {
- FVAppend(_FontViewCreate(sf));
- lua_ff_pushfont(L,sf);
- if (gww_error_count>0) {
- lua_newtable(L);
- for (i=0;i<gww_error_count;i++) {
- lua_pushstring(L,gww_errors[i]);
- lua_rawseti(L,-2,(i+1));
- }
- gwwv_errors_free();
- } else {
- lua_pushnil(L);
- }
- }
- } else {
- lua_pushfstring(L,"font loading failed: empty string given\n", fontname);
- lua_error(L);
- }
- return 2;
-}
-
-
-static int
-ff_close (lua_State *L) {
- SplineFont **sf;
- /*fputs("ff_close called",stderr);*/
- sf = check_isfont(L,1);
- if (*sf!=NULL) {
- SplineFontFree(*sf);
- *sf = NULL;
- }
- return 0;
-}
-
-static int
-ff_apply_featurefile (lua_State *L) {
- SplineFont **sf;
- char *fname;
- sf = check_isfont(L,1);
- fname = (char *)luaL_checkstring(L,2);
- SFApplyFeatureFilename(*sf,fname);
- return 0;
-}
-
-static int
-ff_apply_afmfile (lua_State *L) {
- SplineFont **sf;
- char *fname;
- sf = check_isfont(L,1);
- fname = (char *)luaL_checkstring(L,2);
- CheckAfmOfPostscript(*sf,fname,(*sf)->map);
-
- return 0;
-}
-
-
-
-static void
-dump_intfield (lua_State *L, char *name, long int field) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushnumber(L,field);
- lua_rawset(L,-3);
-}
-
-static void
-dump_realfield (lua_State *L, char *name, real field) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushnumber(L,field);
- lua_rawset(L,-3);
+static int ff_open(lua_State * L)
+{
+ SplineFont *sf;
+ const char *fontname;
+ FILE *l;
+ char s[511];
+ size_t len;
+ int args, i;
+ int openflags = 1;
+ fontname = luaL_checkstring(L, 1);
+ /* test fontname for existance */
+ if ((l = fopen(fontname, "r"))) {
+ fclose(l);
+ } else {
+ lua_pushnil(L);
+ lua_pushfstring(L, "font loading failed for %s (read error)\n",
+ fontname);
+ return 2;
+ }
+ args = lua_gettop(L);
+ if (args >= 2 && lua_isstring(L, 2)) {
+ if (*(fontname + strlen(fontname)) != ')') {
+ /* possibly fails for embedded parens in the font name */
+ snprintf(s, 511, "%s(%s)", fontname, lua_tolstring(L, 2, &len));
+ if (len == 0) {
+ snprintf(s, 511, "%s", fontname);
+ }
+ }
+ } else {
+ snprintf(s, 511, "%s", fontname);
+ }
+ if (strlen(s) > 0) {
+ gww_error_count = 0;
+ sf = ReadSplineFont((char *) s, openflags);
+ if (sf == NULL) {
+ lua_pushnil(L);
+ lua_pushfstring(L, "font loading failed for %s\n", s);
+ if (gww_error_count > 0) {
+ for (i = 0; i < gww_error_count; i++) {
+ lua_pushstring(L, gww_errors[i]);
+ lua_concat(L, 2);
+ }
+ gwwv_errors_free();
+ }
+ } else {
+ FVAppend(_FontViewCreate(sf));
+ lua_ff_pushfont(L, sf);
+ if (gww_error_count > 0) {
+ lua_newtable(L);
+ for (i = 0; i < gww_error_count; i++) {
+ lua_pushstring(L, gww_errors[i]);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ gwwv_errors_free();
+ } else {
+ lua_pushnil(L);
+ }
+ }
+ } else {
+ lua_pushnil(L);
+ lua_pushfstring(L, "font loading failed: empty string given\n",
+ fontname);
+ }
+ return 2;
+}
+
+
+static int ff_close(lua_State * L)
+{
+ SplineFont **sf;
+ /*fputs("ff_close called",stderr); */
+ sf = check_isfont(L, 1);
+ if (*sf != NULL) {
+ if ((*sf)->fv) { // condition might be improved
+ FontViewClose((*sf)->fv);
+ } else {
+ EncMapFree((*sf)->map);
+ SplineFontFree(*sf);
+ }
+ *sf = NULL;
+ }
+ return 0;
+}
+
+static int ff_apply_featurefile(lua_State * L)
+{
+ SplineFont **sf;
+ char *fname;
+ sf = check_isfont(L, 1);
+ fname = (char *) luaL_checkstring(L, 2);
+ SFApplyFeatureFilename(*sf, fname);
+ return 0;
+}
+
+static int ff_apply_afmfile(lua_State * L)
+{
+ SplineFont **sf;
+ char *fname;
+ sf = check_isfont(L, 1);
+ fname = (char *) luaL_checkstring(L, 2);
+ CheckAfmOfPostscript(*sf, fname, (*sf)->map);
+
+ return 0;
+}
+
+
+
+static void dump_intfield(lua_State * L, char *name, long int field)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushnumber(L, field);
+ lua_rawset(L, -3);
+}
+
+static void dump_realfield(lua_State * L, char *name, real field)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushnumber(L, field);
+ lua_rawset(L, -3);
}
#define dump_cond_intfield(a,b,c) if ((c)!=0) { dump_intfield ((a),(b),(c)); }
-static void
-dump_stringfield (lua_State *L, char *name, char *field) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushstring(L,field);
- lua_rawset(L,-3);
+static void dump_stringfield(lua_State * L, char *name, char *field)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushstring(L, field);
+ lua_rawset(L, -3);
}
-static void
-dump_char_ref (lua_State *L, struct splinechar *spchar) {
- lua_checkstack(L,2);
- lua_pushstring(L,"char");
- lua_pushstring(L,spchar->name);
- lua_rawset(L,-3);
+static void dump_char_ref(lua_State * L, struct splinechar *spchar)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, "char");
+ lua_pushstring(L, spchar->name);
+ lua_rawset(L, -3);
}
-static void
-dump_lstringfield (lua_State *L, char *name, char *field, int len) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushlstring(L,field,len);
- lua_rawset(L,-3);
+static void dump_lstringfield(lua_State * L, char *name, char *field, int len)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushlstring(L, field, len);
+ lua_rawset(L, -3);
}
-static void
-dump_enumfield (lua_State *L, char *name, int fid, char **fields) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushstring(L,fields[fid]);
- lua_rawset(L,-3);
+static void dump_enumfield(lua_State * L, char *name, int fid, char **fields)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushstring(L, fields[fid]);
+ lua_rawset(L, -3);
}
-static void
-dump_floatfield (lua_State *L, char *name, double field) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushnumber(L,field);
- lua_rawset(L,-3);
+static void dump_floatfield(lua_State * L, char *name, double field)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushnumber(L, field);
+ lua_rawset(L, -3);
}
-static char tag_string [5] = {0};
+static char tag_string[5] = { 0 };
-static char *make_tag_string (unsigned int field) {
- tag_string[0] = (field&0xFF000000) >> 24;
- tag_string[1] = (field&0x00FF0000) >> 16;
- tag_string[2] = (field&0x0000FF00) >> 8;
- tag_string[3] = (field&0x000000FF);
- return (char *)tag_string;
+static char *make_tag_string(unsigned int field)
+{
+ tag_string[0] = (field & 0xFF000000) >> 24;
+ tag_string[1] = (field & 0x00FF0000) >> 16;
+ tag_string[2] = (field & 0x0000FF00) >> 8;
+ tag_string[3] = (field & 0x000000FF);
+ return (char *) tag_string;
}
-static char featbuf[32] = {0};
+static char featbuf[32] = { 0 };
-static char *make_mactag_string (unsigned int field) {
- sprintf( featbuf, "<%d,%d>", field>>16, field&0xffff );
- return (char *)featbuf;
+static char *make_mactag_string(unsigned int field)
+{
+ sprintf(featbuf, "<%d,%d>", field >> 16, field & 0xffff);
+ return (char *) featbuf;
}
-static void
-dump_tag (lua_State *L, char *name, unsigned int field) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushlstring(L,make_tag_string(field),4);
- lua_rawset(L,-3);
+static void dump_tag(lua_State * L, char *name, unsigned int field)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushlstring(L, make_tag_string(field), 4);
+ lua_rawset(L, -3);
}
-static void
-dump_mactag (lua_State *L, char *name, unsigned int field) {
- lua_checkstack(L,2);
- lua_pushstring(L,name);
- lua_pushstring(L,make_mactag_string(field));
- lua_rawset(L,-3);
+static void dump_mactag(lua_State * L, char *name, unsigned int field)
+{
+ lua_checkstack(L, 2);
+ lua_pushstring(L, name);
+ lua_pushstring(L, make_mactag_string(field));
+ lua_rawset(L, -3);
}
-void
-dump_subtable_name (lua_State *L, char *name, struct lookup_subtable *s) {
- /* this is likely a backref */
- if (s==NULL)
- return;
- lua_checkstack(L,2);
- if (s->next == NULL) {
- dump_stringfield(L,name,s->subtable_name);
- } else {
- /* can this really happen ? */
- int i = 0;
- lua_newtable(L);
- while (s!=NULL) {
- lua_pushstring(L, s->subtable_name);
- lua_rawseti(L, -2, ++i);
- s = s->next;
+void dump_subtable_name(lua_State * L, char *name, struct lookup_subtable *s)
+{
+ /* this is likely a backref */
+ if (s == NULL)
+ return;
+ lua_checkstack(L, 2);
+ if (s->next == NULL) {
+ dump_stringfield(L, name, s->subtable_name);
+ } else {
+ /* can this really happen ? */
+ int i = 0;
+ lua_newtable(L);
+ while (s != NULL) {
+ lua_pushstring(L, s->subtable_name);
+ lua_rawseti(L, -2, ++i);
+ s = s->next;
+ }
+ lua_setfield(L, -2, name);
}
- lua_setfield(L, -2, name);
- }
}
@@ -363,188 +403,221 @@ dump_subtable_name (lua_State *L, char *name, struct lookup_subtable *s) {
next = next->next; \
} }
-void
-do_handle_scriptlanglist (lua_State *L, struct scriptlanglist *sl) {
- int k;
- dump_tag(L,"script", sl->script);
-
- lua_checkstack(L,3);
- lua_newtable(L);
- for (k=0;k<MAX_LANG;k++) {
- if (sl->langs[k] != 0) {
- lua_pushnumber(L,(k+1));
- lua_pushstring(L,make_tag_string(sl->langs[k]));
- lua_rawset(L,-3);
- }
- }
-
- if (sl->lang_cnt>=MAX_LANG) {
- for (k=MAX_LANG;k<sl->lang_cnt;k++) {
- lua_pushnumber(L,(k+1));
- lua_pushstring(L,make_tag_string(sl->morelangs[k-MAX_LANG]));
- lua_rawset(L,-3);
- }
- }
- lua_setfield(L,-2,"langs");
-}
+#define NESTED_TABLE_SF(a,b,c,d) { \
+ int k = 1; \
+ next = b; \
+ while (next != NULL) { \
+ lua_checkstack(L,2); \
+ lua_pushnumber(L,k); k++; \
+ lua_createtable(L,0,d); \
+ a(L, next, c); \
+ lua_rawset(L,-3); \
+ next = next->next; \
+ } }
-void
-handle_scriptlanglist (lua_State *L, struct scriptlanglist *sll) {
- struct scriptlanglist *next;
- NESTED_TABLE(do_handle_scriptlanglist,sll,4);
+
+void do_handle_scriptlanglist(lua_State * L, struct scriptlanglist *sl)
+{
+ int k;
+ dump_tag(L, "script", sl->script);
+
+ lua_checkstack(L, 3);
+ lua_newtable(L);
+ for (k = 0; k < MAX_LANG; k++) {
+ if (sl->langs[k] != 0) {
+ lua_pushnumber(L, (k + 1));
+ lua_pushstring(L, make_tag_string(sl->langs[k]));
+ lua_rawset(L, -3);
+ }
+ }
+
+ if (sl->lang_cnt >= MAX_LANG) {
+ for (k = MAX_LANG; k < sl->lang_cnt; k++) {
+ lua_pushnumber(L, (k + 1));
+ lua_pushstring(L, make_tag_string(sl->morelangs[k - MAX_LANG]));
+ lua_rawset(L, -3);
+ }
+ }
+ lua_setfield(L, -2, "langs");
}
-void
-do_handle_featurescriptlanglist (lua_State *L, struct featurescriptlanglist *features) {
- if (features->ismac) {
- dump_mactag (L,"tag",features->featuretag);
- } else {
- dump_tag (L,"tag",features->featuretag);
- }
- lua_newtable(L);
- handle_scriptlanglist(L, features->scripts);
- lua_setfield(L,-2,"scripts");
- dump_cond_intfield (L,"ismac",features->ismac);
-}
+void handle_scriptlanglist(lua_State * L, struct scriptlanglist *sll)
+{
+ struct scriptlanglist *next;
+ NESTED_TABLE(do_handle_scriptlanglist, sll, 4);
+}
void
-handle_featurescriptlanglist (lua_State *L, struct featurescriptlanglist *features) {
- struct featurescriptlanglist *next;
- NESTED_TABLE(do_handle_featurescriptlanglist,features,3);
+do_handle_featurescriptlanglist(lua_State * L,
+ struct featurescriptlanglist *features)
+{
+ if (features->ismac) {
+ dump_mactag(L, "tag", features->featuretag);
+ } else {
+ dump_tag(L, "tag", features->featuretag);
+ }
+ lua_newtable(L);
+ handle_scriptlanglist(L, features->scripts);
+ lua_setfield(L, -2, "scripts");
+ dump_cond_intfield(L, "ismac", features->ismac);
}
-void
-do_handle_lookup_subtable (lua_State *L, struct lookup_subtable *subtable) {
+void
+handle_featurescriptlanglist(lua_State * L,
+ struct featurescriptlanglist *features)
+{
+ struct featurescriptlanglist *next;
+ NESTED_TABLE(do_handle_featurescriptlanglist, features, 3);
+}
- dump_stringfield(L,"name", subtable->subtable_name);
- dump_stringfield(L,"suffix", subtable->suffix);
+void do_handle_lookup_subtable(lua_State * L, struct lookup_subtable *subtable)
+{
- /* struct otlookup *lookup; */ /* this is the parent */
+ dump_stringfield(L, "name", subtable->subtable_name);
+ dump_stringfield(L, "suffix", subtable->suffix);
- /* dump_intfield (L,"unused", subtable->unused); */
- /* The next one is true if there is no fpst, false otherwise */
- /*
- dump_intfield (L,"per_glyph_pst_or_kern",subtable->per_glyph_pst_or_kern);
- */
- dump_cond_intfield (L,"anchor_classes", subtable->anchor_classes);
- dump_cond_intfield (L,"vertical_kerning", subtable->vertical_kerning);
+ /* struct otlookup *lookup; *//* this is the parent */
- if (subtable->kc != NULL) {
- lua_newtable(L);
- handle_kernclass(L, subtable->kc);
- lua_setfield(L,-2, "kernclass");
- }
+ /* dump_intfield (L,"unused", subtable->unused); */
+ /* The next one is true if there is no fpst, false otherwise */
+ /*
+ dump_intfield (L,"per_glyph_pst_or_kern",subtable->per_glyph_pst_or_kern);
+ */
+ dump_cond_intfield(L, "anchor_classes", subtable->anchor_classes);
+ dump_cond_intfield(L, "vertical_kerning", subtable->vertical_kerning);
+ if (subtable->kc != NULL) {
+ lua_newtable(L);
+ handle_kernclass(L, subtable->kc);
+ lua_setfield(L, -2, "kernclass");
+ }
#if 0
- if (subtable->fpst != NULL) {
- /* lua_newtable(L); */
- handle_generic_fpst(L, subtable->fpst);
- /* lua_setfield(L,-2, "fpst"); */
- }
+ if (subtable->fpst != NULL) {
+ /* lua_newtable(L); */
+ handle_generic_fpst(L, subtable->fpst);
+ /* lua_setfield(L,-2, "fpst"); */
+ }
#endif
- if (subtable->sm != NULL) {
- lua_newtable(L);
- handle_generic_asm(L, subtable->sm);
- lua_setfield(L,-2, "sm");
- }
- /* int subtable_offset; */ /* used by OTF file generation */
- /* int32 *extra_subtables; */ /* used by OTF file generation */
+ if (subtable->sm != NULL) {
+ lua_newtable(L);
+ handle_generic_asm(L, subtable->sm);
+ lua_setfield(L, -2, "sm");
+ }
+ /* int subtable_offset; *//* used by OTF file generation */
+ /* int32 *extra_subtables; *//* used by OTF file generation */
}
-void
-handle_lookup_subtable (lua_State *L, struct lookup_subtable *subtable) {
- struct lookup_subtable *next;
- NESTED_TABLE(do_handle_lookup_subtable,subtable,2);
+void handle_lookup_subtable(lua_State * L, struct lookup_subtable *subtable)
+{
+ struct lookup_subtable *next;
+ NESTED_TABLE(do_handle_lookup_subtable, subtable, 2);
}
-void
-do_handle_lookup (lua_State *L, struct otlookup *lookup ) {
+void do_handle_lookup(lua_State * L, struct otlookup *lookup, SplineFont * sf)
+{
+ int mc;
+
+ dump_enumfield(L, "type", lookup->lookup_type, otf_lookup_type_enum);
+
+ lua_newtable(L);
+ if (lookup->lookup_flags & pst_r2l) {
+ lua_pushstring(L, "r2l");
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+ }
+ if (lookup->lookup_flags & pst_ignorebaseglyphs) {
+ lua_pushstring(L, "ignorebaseglyphs");
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+ }
+ if (lookup->lookup_flags & pst_ignoreligatures) {
+ lua_pushstring(L, "ignoreligatures");
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+ }
+ if (lookup->lookup_flags & pst_ignorecombiningmarks) {
+ lua_pushstring(L, "ignorecombiningmarks");
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+ }
+ mc = (lookup->lookup_flags >> 8);
+ if (mc > 0 && mc < sf->mark_class_cnt && sf->mark_class_names[mc] != NULL) {
+ lua_pushstring(L, "mark_class");
+ lua_pushstring(L, sf->mark_class_names[mc]);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "flags");
- dump_enumfield (L,"type", lookup->lookup_type, otf_lookup_type_enum);
- lua_newtable(L);
- if (lookup->lookup_flags & pst_r2l) {
- lua_pushstring(L,"r2l"); lua_pushboolean(L,1); lua_rawset(L,-3);
- }
- if (lookup->lookup_flags & pst_ignorebaseglyphs) {
- lua_pushstring(L,"ignorebaseglyphs"); lua_pushboolean(L,1); lua_rawset(L,-3);
- }
- if (lookup->lookup_flags & pst_ignoreligatures) {
- lua_pushstring(L,"ignoreligatures"); lua_pushboolean(L,1); lua_rawset(L,-3);
- }
- if (lookup->lookup_flags & pst_ignorecombiningmarks) {
- lua_pushstring(L,"ignorecombiningmarks"); lua_pushboolean(L,1); lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"flags");
+ dump_stringfield(L, "name", lookup->lookup_name);
- dump_stringfield (L,"name", lookup->lookup_name);
+ if (lookup->features != NULL) {
+ lua_newtable(L);
+ handle_featurescriptlanglist(L, lookup->features);
+ lua_setfield(L, -2, "features");
+ }
- if (lookup->features != NULL) {
- lua_newtable(L);
- handle_featurescriptlanglist(L,lookup->features);
- lua_setfield(L,-2,"features");
- }
+ if (lookup->subtables != NULL) {
+ lua_newtable(L);
+ handle_lookup_subtable(L, lookup->subtables);
+ lua_setfield(L, -2, "subtables");
+ }
- if (lookup->subtables != NULL) {
- lua_newtable(L);
- handle_lookup_subtable(L,lookup->subtables);
- lua_setfield(L,-2,"subtables");
- }
-
- /* dump_intfield (L,"unused", lookup->unused); */
- /* dump_intfield (L,"empty", lookup->empty); */
- /* dump_intfield (L,"store_in_afm", lookup->store_in_afm); */
- /* dump_intfield (L,"needs_extension", lookup->needs_extension); */
- /* dump_intfield (L,"temporary_kern", lookup->temporary_kern); */
- /* dump_intfield (L,"def_lang_checked", lookup->def_lang_checked); */
- /* dump_intfield (L,"def_lang_found", lookup->def_lang_found); */
- /* dump_intfield (L,"ticked", lookup->ticked); */
- /* dump_intfield (L,"subcnt", lookup->subcnt); */
- /* dump_intfield (L,"lookup_index", lookup->lookup_index); */ /* identical to array index */
- /* dump_intfield (L,"lookup_offset", lookup->lookup_offset); */
- /* dump_intfield (L,"lookup_length", lookup->lookup_length); */
- /* dump_stringfield(L,"tempname", lookup->tempname); */
+ /* dump_intfield (L,"unused", lookup->unused); */
+ /* dump_intfield (L,"empty", lookup->empty); */
+ /* dump_intfield (L,"store_in_afm", lookup->store_in_afm); */
+ /* dump_intfield (L,"needs_extension", lookup->needs_extension); */
+ /* dump_intfield (L,"temporary_kern", lookup->temporary_kern); */
+ /* dump_intfield (L,"def_lang_checked", lookup->def_lang_checked); */
+ /* dump_intfield (L,"def_lang_found", lookup->def_lang_found); */
+ /* dump_intfield (L,"ticked", lookup->ticked); */
+ /* dump_intfield (L,"subcnt", lookup->subcnt); */
+ /* dump_intfield (L,"lookup_index", lookup->lookup_index); *//* identical to array index */
+ /* dump_intfield (L,"lookup_offset", lookup->lookup_offset); */
+ /* dump_intfield (L,"lookup_length", lookup->lookup_length); */
+ /* dump_stringfield(L,"tempname", lookup->tempname); */
}
-void
-handle_lookup (lua_State *L, struct otlookup *lookup ) {
- struct otlookup *next;
- NESTED_TABLE(do_handle_lookup,lookup,18); /* 18 is a guess */
+void handle_lookup(lua_State * L, struct otlookup *lookup, SplineFont * sf)
+{
+ struct otlookup *next;
+ NESTED_TABLE_SF(do_handle_lookup, lookup, sf, 18); /* 18 is a guess */
}
-void
-do_handle_kernpair (lua_State *L, struct kernpair *kp) {
+void do_handle_kernpair(lua_State * L, struct kernpair *kp)
+{
- if (kp->sc != NULL)
- dump_char_ref(L, kp->sc);
- dump_intfield(L,"off", kp->off);
- /* uint16 kcid; */ /* temporary value */
- dump_subtable_name(L, "lookup", kp->subtable);
+ if (kp->sc != NULL)
+ dump_char_ref(L, kp->sc);
+ dump_intfield(L, "off", kp->off);
+ /* uint16 kcid; *//* temporary value */
+ dump_subtable_name(L, "lookup", kp->subtable);
}
-void
-handle_kernpair (lua_State *L, struct kernpair *kp) {
- struct kernpair *next;
- NESTED_TABLE(do_handle_kernpair,kp,4);
+void handle_kernpair(lua_State * L, struct kernpair *kp)
+{
+ struct kernpair *next;
+ NESTED_TABLE(do_handle_kernpair, kp, 4);
}
-void
-handle_splinecharlist (lua_State *L, struct splinecharlist *scl) {
+void handle_splinecharlist(lua_State * L, struct splinecharlist *scl)
+{
- struct splinecharlist *next = scl;
- int k = 1;
- lua_checkstack(L,10);
- while( next != NULL) {
- if (next->sc != NULL) {
- lua_pushnumber(L,k); k++;
- lua_pushstring(L,next->sc->name);
- lua_rawset(L,-3);
+ struct splinecharlist *next = scl;
+ int k = 1;
+ lua_checkstack(L, 10);
+ while (next != NULL) {
+ if (next->sc != NULL) {
+ lua_pushnumber(L, k);
+ k++;
+ lua_pushstring(L, next->sc->name);
+ lua_rawset(L, -3);
+ }
+ next = next->next;
}
- next = next->next;
- }
}
@@ -556,750 +629,801 @@ handle_splinecharlist (lua_State *L, struct splinecharlist *scl) {
/* variant shape. The specifics depend on the selector and script */
/* fid is currently unused, but may, someday, be used to do ttcs */
/* NOTE: GlyphInfo displays vs==-1 as vs==0, and fixes things up */
-void
-handle_altuni (lua_State *L, struct altuni *au) {
- struct altuni *next = au;
- int k = 1;
- lua_checkstack(L,3);
- while( next != NULL) {
- lua_newtable(L);
- dump_intfield(L, "unicode", next->unienc);
- if (next->vs != -1)
- dump_intfield(L, "variant", next->vs);
- /* dump_intfield(L, "fid", next->fid); */
- lua_rawseti(L, -2, k++);
- next = next->next;
- }
+void handle_altuni(lua_State * L, struct altuni *au)
+{
+ struct altuni *next = au;
+ int k = 1;
+ lua_checkstack(L, 3);
+ while (next != NULL) {
+ lua_newtable(L);
+ dump_intfield(L, "unicode", next->unienc);
+ if (next->vs != -1)
+ dump_intfield(L, "variant", next->vs);
+ /* dump_intfield(L, "fid", next->fid); */
+ lua_rawseti(L, -2, k++);
+ next = next->next;
+ }
}
#define interesting_vr(a) (((a)->xoff!=0) || ((a)->yoff!=0) || ((a)->h_adv_off!=0) || ((a)->v_adv_off!=0))
-void handle_vr (lua_State *L, struct vr *pos) {
+void handle_vr(lua_State * L, struct vr *pos)
+{
- dump_cond_intfield(L,"x", pos->xoff);
- dump_cond_intfield(L,"y", pos->yoff);
- dump_cond_intfield(L,"h", pos->h_adv_off);
- dump_cond_intfield(L,"v", pos->v_adv_off);
+ dump_cond_intfield(L, "x", pos->xoff);
+ dump_cond_intfield(L, "y", pos->yoff);
+ dump_cond_intfield(L, "h", pos->h_adv_off);
+ dump_cond_intfield(L, "v", pos->v_adv_off);
}
-void
-do_handle_generic_pst (lua_State *L, struct generic_pst *pst) {
- int k;
- if (pst->type>LAST_POSSUB_TYPE_ENUM) {
- dump_tag(L,"type", pst->type);
- } else {
- dump_enumfield(L,"type", pst->type, possub_type_enum);
- }
- /* unsigned int ticked: 1;*/
- /* unsigned int temporary: 1;*/ /* Used in afm ligature closure */
- /* struct lookup_subtable *subtable; */ /* handled by caller */
-
- lua_checkstack(L,4);
- lua_pushstring(L,"specification");
- lua_createtable(L,0,4);
- if (pst->type == pst_position) {
- handle_vr (L, &pst->u.pos);
- } else if (pst->type == pst_pair) {
- dump_stringfield(L,"paired",pst->u.pair.paired);
- if (pst->u.pair.vr != NULL) {
- lua_pushstring(L,"offsets");
- lua_createtable(L,2,0);
- if (interesting_vr(pst->u.pair.vr)) {
- lua_createtable(L,0,4);
- handle_vr (L, pst->u.pair.vr);
- lua_rawseti(L,-2,1);
- }
- if (interesting_vr(pst->u.pair.vr+1)) {
- lua_createtable(L,0,4);
- handle_vr (L, pst->u.pair.vr+1);
- lua_rawseti(L,-2,2);
- }
- lua_rawset(L,-3);
- }
- } else if (pst->type == pst_substitution) {
- dump_stringfield(L,"variant",pst->u.subs.variant);
- } else if (pst->type == pst_alternate) {
- dump_stringfield(L,"components",pst->u.mult.components);
- } else if (pst->type == pst_multiple) {
- dump_stringfield(L,"components",pst->u.alt.components);
- } else if (pst->type == pst_ligature) {
- dump_stringfield(L,"components",pst->u.lig.components);
- if (pst->u.lig.lig != NULL) {
- dump_char_ref(L,pst->u.lig.lig);
- }
- } else if (pst->type == pst_lcaret) {
- for (k=0;k<pst->u.lcaret.cnt;k++) {
- lua_pushnumber(L,(k+1));
- lua_pushnumber(L,pst->u.lcaret.carets[k]);
- lua_rawset(L,-3);
- }
- }
- lua_rawset(L,-3);
+void do_handle_generic_pst(lua_State * L, struct generic_pst *pst)
+{
+ int k;
+ if (pst->type > LAST_POSSUB_TYPE_ENUM) {
+ dump_tag(L, "type", pst->type);
+ } else {
+ dump_enumfield(L, "type", pst->type, possub_type_enum);
+ }
+ /* unsigned int ticked: 1; */
+ /* unsigned int temporary: 1; *//* Used in afm ligature closure */
+ /* struct lookup_subtable *subtable; *//* handled by caller */
+
+ lua_checkstack(L, 4);
+ lua_pushstring(L, "specification");
+ lua_createtable(L, 0, 4);
+ if (pst->type == pst_position) {
+ handle_vr(L, &pst->u.pos);
+ } else if (pst->type == pst_pair) {
+ dump_stringfield(L, "paired", pst->u.pair.paired);
+ if (pst->u.pair.vr != NULL) {
+ lua_pushstring(L, "offsets");
+ lua_createtable(L, 2, 0);
+ if (interesting_vr(pst->u.pair.vr)) {
+ lua_createtable(L, 0, 4);
+ handle_vr(L, pst->u.pair.vr);
+ lua_rawseti(L, -2, 1);
+ }
+ if (interesting_vr(pst->u.pair.vr + 1)) {
+ lua_createtable(L, 0, 4);
+ handle_vr(L, pst->u.pair.vr + 1);
+ lua_rawseti(L, -2, 2);
+ }
+ lua_rawset(L, -3);
+ }
+ } else if (pst->type == pst_substitution) {
+ dump_stringfield(L, "variant", pst->u.subs.variant);
+ } else if (pst->type == pst_alternate) {
+ dump_stringfield(L, "components", pst->u.mult.components);
+ } else if (pst->type == pst_multiple) {
+ dump_stringfield(L, "components", pst->u.alt.components);
+ } else if (pst->type == pst_ligature) {
+ dump_stringfield(L, "components", pst->u.lig.components);
+ if (pst->u.lig.lig != NULL) {
+ dump_char_ref(L, pst->u.lig.lig);
+ }
+ } else if (pst->type == pst_lcaret) {
+ for (k = 0; k < pst->u.lcaret.cnt; k++) {
+ lua_pushnumber(L, (k + 1));
+ lua_pushnumber(L, pst->u.lcaret.carets[k]);
+ lua_rawset(L, -3);
+ }
+ }
+ lua_rawset(L, -3);
}
-void
-handle_generic_pst (lua_State *L, struct generic_pst *pst) {
- struct generic_pst *next;
- int k;
- int l = 1;
- next = pst;
- /* most likely everything arrives in proper order. But to prevent
- * surprises, better do this is the proper way
- */
- while (next != NULL) {
- if (next->subtable !=NULL &&
- next->subtable->subtable_name !=NULL) {
- lua_checkstack(L,3); /* just in case */
- lua_getfield(L,-1,next->subtable->subtable_name);
- if (!lua_istable(L,-1)) {
- lua_pop(L,1);
- lua_newtable(L);
- lua_setfield(L,-2,next->subtable->subtable_name);
- lua_getfield(L,-1,next->subtable->subtable_name);
- }
- k = lua_objlen(L,-1) + 1;
- lua_pushnumber(L,k);
- lua_createtable(L,0,4);
- do_handle_generic_pst(L, next);
- lua_rawset(L,-3);
- next = next->next;
- lua_pop(L,1); /* pop the subtable */
- } else {
- /* Found a pst without subtable, or without subtable name */
- lua_pushnumber(L,l); l++;
- lua_createtable(L,0,4);
- do_handle_generic_pst(L, next);
- lua_rawset(L,-3);
- next = next->next;
- }
- }
+void handle_generic_pst(lua_State * L, struct generic_pst *pst)
+{
+ struct generic_pst *next;
+ int k;
+ int l = 1;
+ next = pst;
+ /* most likely everything arrives in proper order. But to prevent
+ * surprises, better do this is the proper way
+ */
+ while (next != NULL) {
+ if (next->subtable != NULL && next->subtable->subtable_name != NULL) {
+ lua_checkstack(L, 3); /* just in case */
+ lua_getfield(L, -1, next->subtable->subtable_name);
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ lua_newtable(L);
+ lua_setfield(L, -2, next->subtable->subtable_name);
+ lua_getfield(L, -1, next->subtable->subtable_name);
+ }
+ k = lua_objlen(L, -1) + 1;
+ lua_pushnumber(L, k);
+ lua_createtable(L, 0, 4);
+ do_handle_generic_pst(L, next);
+ lua_rawset(L, -3);
+ next = next->next;
+ lua_pop(L, 1); /* pop the subtable */
+ } else {
+ /* Found a pst without subtable, or without subtable name */
+ lua_pushnumber(L, l);
+ l++;
+ lua_createtable(L, 0, 4);
+ do_handle_generic_pst(L, next);
+ lua_rawset(L, -3);
+ next = next->next;
+ }
+ }
}
-void
-do_handle_liglist (lua_State *L, struct liglist *ligofme) {
- lua_checkstack(L,2);
- if(ligofme->lig != NULL) {
- lua_createtable(L,0,6);
- handle_generic_pst (L,ligofme->lig);
- lua_setfield(L,-2,"lig");
- }
- dump_char_ref(L,ligofme->first);
- if (ligofme->components != NULL) {
- lua_newtable(L);
- handle_splinecharlist (L,ligofme->components);
- lua_setfield(L,-2,"components");
- }
- dump_intfield(L,"ccnt",ligofme->ccnt);
+void do_handle_liglist(lua_State * L, struct liglist *ligofme)
+{
+ lua_checkstack(L, 2);
+ if (ligofme->lig != NULL) {
+ lua_createtable(L, 0, 6);
+ handle_generic_pst(L, ligofme->lig);
+ lua_setfield(L, -2, "lig");
+ }
+ dump_char_ref(L, ligofme->first);
+ if (ligofme->components != NULL) {
+ lua_newtable(L);
+ handle_splinecharlist(L, ligofme->components);
+ lua_setfield(L, -2, "components");
+ }
+ dump_intfield(L, "ccnt", ligofme->ccnt);
}
-void
-handle_liglist (lua_State *L, struct liglist *ligofme) {
- struct liglist *next;
- NESTED_TABLE(do_handle_liglist,ligofme,3);
+void handle_liglist(lua_State * L, struct liglist *ligofme)
+{
+ struct liglist *next;
+ NESTED_TABLE(do_handle_liglist, ligofme, 3);
}
-void
-do_handle_anchorpoint (lua_State *L, struct anchorpoint *anchor) {
+void do_handle_anchorpoint(lua_State * L, struct anchorpoint *anchor)
+{
- if (anchor->anchor==NULL) {
- return;
- }
- if (anchor->type>=0 && anchor->type <= MAX_ANCHOR_TYPE ) {
- lua_pushstring(L,anchor_type_enum[anchor->type]);
- } else {
- lua_pushstring(L,"Anchorpoint has an unknown type!");
- lua_error(L);
- }
- /* unsigned int selected: 1; */
- /* unsigned int ticked: 1; */
-
- lua_rawget(L,-2);
- if (!lua_istable(L,-1)) {
- /* create the table first */
- lua_pop(L,1);
- lua_pushstring(L,anchor_type_enum[anchor->type]);
- lua_pushvalue(L,-1);
- lua_newtable(L);
- lua_rawset(L,-4);
- lua_rawget(L,-2);
- }
- /* now the 'type' table is top of stack */
- if (anchor->type==at_baselig) {
- lua_pushstring(L,anchor->anchor->name);
- lua_rawget(L,-2);
- if (!lua_istable(L,-1)) {
- /* create the table first */
- lua_pop(L,1);
- lua_pushstring(L,anchor->anchor->name);
- lua_pushvalue(L,-1);
- lua_newtable(L);
- lua_rawset(L,-4);
- lua_rawget(L,-2);
+ if (anchor->anchor == NULL) {
+ return;
}
- lua_newtable(L);
- dump_intfield(L,"x", anchor->me.x);
- dump_intfield(L,"y", anchor->me.y);
- if (anchor->has_ttf_pt)
- dump_intfield(L,"ttf_pt_index", anchor->ttf_pt_index);
- dump_intfield(L,"lig_index", anchor->lig_index);
- lua_rawseti(L,-2,(anchor->lig_index+1));
- lua_pop(L,1);
- } else {
- lua_pushstring(L,anchor->anchor->name);
- lua_newtable(L);
- dump_intfield(L,"x", anchor->me.x);
- dump_intfield(L,"y", anchor->me.y);
- if (anchor->has_ttf_pt)
- dump_intfield(L,"ttf_pt_index", anchor->ttf_pt_index);
- dump_intfield(L,"lig_index", anchor->lig_index);
- lua_rawset(L,-3);
- }
- lua_pop(L,1);
+ if (anchor->type >= 0 && anchor->type <= MAX_ANCHOR_TYPE) {
+ lua_pushstring(L, anchor_type_enum[anchor->type]);
+ } else {
+ lua_pushstring(L, "Anchorpoint has an unknown type!");
+ lua_error(L);
+ }
+ /* unsigned int selected: 1; */
+ /* unsigned int ticked: 1; */
+
+ lua_rawget(L, -2);
+ if (!lua_istable(L, -1)) {
+ /* create the table first */
+ lua_pop(L, 1);
+ lua_pushstring(L, anchor_type_enum[anchor->type]);
+ lua_pushvalue(L, -1);
+ lua_newtable(L);
+ lua_rawset(L, -4);
+ lua_rawget(L, -2);
+ }
+ /* now the 'type' table is top of stack */
+ if (anchor->type == at_baselig) {
+ lua_pushstring(L, anchor->anchor->name);
+ lua_rawget(L, -2);
+ if (!lua_istable(L, -1)) {
+ /* create the table first */
+ lua_pop(L, 1);
+ lua_pushstring(L, anchor->anchor->name);
+ lua_pushvalue(L, -1);
+ lua_newtable(L);
+ lua_rawset(L, -4);
+ lua_rawget(L, -2);
+ }
+ lua_newtable(L);
+ dump_intfield(L, "x", anchor->me.x);
+ dump_intfield(L, "y", anchor->me.y);
+ if (anchor->has_ttf_pt)
+ dump_intfield(L, "ttf_pt_index", anchor->ttf_pt_index);
+ dump_intfield(L, "lig_index", anchor->lig_index);
+ lua_rawseti(L, -2, (anchor->lig_index + 1));
+ lua_pop(L, 1);
+ } else {
+ lua_pushstring(L, anchor->anchor->name);
+ lua_newtable(L);
+ dump_intfield(L, "x", anchor->me.x);
+ dump_intfield(L, "y", anchor->me.y);
+ if (anchor->has_ttf_pt)
+ dump_intfield(L, "ttf_pt_index", anchor->ttf_pt_index);
+ dump_intfield(L, "lig_index", anchor->lig_index);
+ lua_rawset(L, -3);
+ }
+ lua_pop(L, 1);
}
-void
-handle_anchorpoint (lua_State *L, struct anchorpoint *anchor) {
- struct anchorpoint *next;
- next = anchor;
- while (next != NULL) {
- do_handle_anchorpoint(L, next);
- next = next->next;
- }
+void handle_anchorpoint(lua_State * L, struct anchorpoint *anchor)
+{
+ struct anchorpoint *next;
+ next = anchor;
+ while (next != NULL) {
+ do_handle_anchorpoint(L, next);
+ next = next->next;
+ }
}
-void
-handle_glyphvariants (lua_State *L, struct glyphvariants *vars) {
- int i ;
- dump_stringfield(L, "variants", vars->variants);
- dump_intfield (L, "italic_correction", vars->italic_correction);
- lua_newtable(L);
- for (i=0; i< vars->part_cnt; i++) {
- lua_newtable(L);
- dump_stringfield(L, "component", vars->parts[i].component);
- dump_intfield(L, "extender", vars->parts[i].is_extender);
- dump_intfield(L, "start", vars->parts[i].startConnectorLength);
- dump_intfield(L, "end", vars->parts[i].endConnectorLength);
- dump_intfield(L, "advance", vars->parts[i].fullAdvance);
- lua_rawseti(L,-2,(i+1));
- }
- lua_setfield(L, -2, "parts");
-}
-
-void handle_mathkernvertex (lua_State *L, struct mathkernvertex *mkv) {
- int i;
- for (i=0; i<mkv->cnt;i++) {
- lua_newtable(L);
- dump_intfield(L, "height", mkv->mkd[i].height );
- dump_intfield(L, "kern", mkv->mkd[i].kern );
- lua_rawseti(L,-2, (i+1));
- }
-}
-
-void handle_mathkern (lua_State *L, struct mathkern *mk) {
- lua_newtable(L);
- handle_mathkernvertex(L, &(mk->top_right));
- lua_setfield(L, -2, "top_right");
- lua_newtable(L);
- handle_mathkernvertex(L, &(mk->top_left));
- lua_setfield(L, -2, "top_left");
- lua_newtable(L);
- handle_mathkernvertex(L, &(mk->bottom_right));
- lua_setfield(L, -2, "bottom_right");
- lua_newtable(L);
- handle_mathkernvertex(L, &(mk->bottom_left));
- lua_setfield(L, -2, "bottom_left");
-}
-
-
-
-void
-handle_splinechar (lua_State *L,struct splinechar *glyph, int hasvmetrics) {
- DBounds bb;
- if (glyph->xmax==0 && glyph->ymax==0 && glyph->xmin==0 && glyph->ymin==0) {
- SplineCharFindBounds(glyph,&bb);
- glyph->xmin = bb.minx;
- glyph->ymin = bb.miny;
- glyph->xmax = bb.maxx;
- glyph->ymax = bb.maxy;
- }
- dump_stringfield(L,"name", glyph->name);
- dump_intfield(L,"unicode", glyph->unicodeenc);
- lua_createtable(L,4,0);
- lua_pushnumber(L,1); lua_pushnumber(L,glyph->xmin); lua_rawset(L,-3);
- lua_pushnumber(L,2); lua_pushnumber(L,glyph->ymin); lua_rawset(L,-3);
- lua_pushnumber(L,3); lua_pushnumber(L,glyph->xmax); lua_rawset(L,-3);
- lua_pushnumber(L,4); lua_pushnumber(L,glyph->ymax); lua_rawset(L,-3);
- lua_setfield(L,-2,"boundingbox");
- /*dump_intfield(L,"orig_pos", glyph->orig_pos);*/
- if (hasvmetrics)
- dump_intfield(L,"vwidth", glyph->vwidth);
- dump_intfield(L,"width", glyph->width);
-
- if (glyph->lsidebearing != glyph->xmin) {
- dump_cond_intfield(L,"lsidebearing", glyph->lsidebearing);
- }
- /* dump_intfield(L,"ttf_glyph", glyph->ttf_glyph); */
-
- /* Layer layers[2]; */ /* TH Not used */
- /* int layer_cnt; */ /* TH Not used */
- /* StemInfo *hstem; */ /* TH Not used */
- /* StemInfo *vstem; */ /* TH Not used */
- /* DStemInfo *dstem; */ /* TH Not used */
-
- /* MinimumDistance *md; */ /* TH Not used */
- /* struct charviewbase *views; */ /* TH Not used */
- /* struct charinfo *charinfo; */ /* TH ? (charinfo.c) */
- /* struct splinefont *parent; */ /* TH Not used */
-
- if (glyph->glyph_class>0) {
- dump_enumfield(L,"class", glyph->glyph_class, glyph_class_enum);
- }
- /* TH: internal fontforge stuff
- dump_intfield(L,"changed", glyph->changed);
- dump_intfield(L,"changedsincelasthinted", glyph->changedsincelasthinted);
- dump_intfield(L,"manualhints", glyph->manualhints);
- dump_intfield(L,"ticked", glyph->ticked);
- dump_intfield(L,"changed_since_autosave", glyph->changed_since_autosave);
- dump_intfield(L,"widthset", glyph->widthset);
- dump_intfield(L,"vconflicts", glyph->vconflicts);
- dump_intfield(L,"hconflicts", glyph->hconflicts);
- dump_intfield(L,"searcherdummy", glyph->searcherdummy);
- dump_intfield(L,"changed_since_search", glyph->changed_since_search);
- dump_intfield(L,"wasopen", glyph->wasopen);
- dump_intfield(L,"namechanged", glyph->namechanged);
- dump_intfield(L,"blended", glyph->blended);
- dump_intfield(L,"ticked2", glyph->ticked2);
- dump_intfield(L,"unused_so_far", glyph->unused_so_far);
- dump_intfield(L,"numberpointsbackards", glyph->numberpointsbackards);
- dump_intfield(L,"instructions_out_of_date", glyph->instructions_out_of_date);
- dump_intfield(L,"complained_about_ptnums", glyph->complained_about_ptnums);
- unsigned int vs_open: 1;
- unsigned int unlink_rm_ovrlp_save_undo: 1;
- unsigned int inspiro: 1;
- unsigned int lig_caret_cnt_fixed: 1;
-
-
- uint8 *ttf_instrs;
- int16 ttf_instrs_len;
- int16 countermask_cnt;
- HintMask *countermasks;
- */
-
- if (glyph->kerns != NULL) {
- lua_newtable(L);
- handle_kernpair(L,glyph->kerns);
- lua_setfield(L,-2,"kerns");
- }
- if (glyph->vkerns != NULL) {
- lua_newtable(L);
- handle_kernpair(L,glyph->vkerns);
- lua_setfield(L,-2,"vkerns");
- }
-
- if (glyph->dependents != NULL) {
- lua_newtable(L);
- handle_splinecharlist(L,glyph->dependents);
- lua_setfield(L,-2,"dependents");
-
- }
- if (glyph->possub != NULL) {
- lua_newtable(L);
- handle_generic_pst(L,glyph->possub);
- lua_setfield(L,-2,"lookups");
- }
-
- if (glyph->ligofme != NULL) {
- lua_newtable(L);
- handle_liglist(L,glyph->ligofme);
- lua_setfield(L,-2,"ligatures");
- }
-
- if (glyph->comment != NULL)
- dump_stringfield(L,"comment", glyph->comment);
-
- /* Color color; */ /* dont care */
-
- if (glyph->anchor != NULL) {
- lua_newtable(L);
- handle_anchorpoint(L,glyph->anchor);
- lua_setfield(L,-2,"anchors");
- }
-
- if (glyph->altuni != NULL) {
- lua_newtable(L);
- handle_altuni(L, glyph->altuni);
- lua_setfield(L,-2,"altuni");
- }
-
- if (glyph->tex_height != TEX_UNDEF)
- dump_intfield(L,"tex_height", glyph->tex_height);
- if (glyph->tex_depth != TEX_UNDEF)
- dump_intfield(L,"tex_depth", glyph->tex_depth);
-
- dump_cond_intfield(L, "is_extended_shape", glyph->is_extended_shape);
- if (glyph->italic_correction != TEX_UNDEF)
- dump_intfield(L, "italic_correction", glyph->italic_correction);
- if (glyph->top_accent_horiz != TEX_UNDEF)
- dump_intfield(L, "top_accent", glyph->top_accent_horiz);
-
- if (glyph->vert_variants != NULL) {
- lua_newtable(L);
- handle_glyphvariants(L, glyph->vert_variants);
- lua_setfield(L,-2,"vert_variants");
- }
- if (glyph->horiz_variants != NULL) {
- lua_newtable(L);
- handle_glyphvariants(L, glyph->horiz_variants);
- lua_setfield(L,-2,"horiz_variants");
- }
- if (glyph->mathkern != NULL) {
+void handle_glyphvariants(lua_State * L, struct glyphvariants *vars)
+{
+ int i;
+ dump_stringfield(L, "variants", vars->variants);
+ dump_intfield(L, "italic_correction", vars->italic_correction);
lua_newtable(L);
- handle_mathkern(L, glyph->mathkern);
- lua_setfield(L,-2,"mathkern");
- }
-}
-
-char *panose_values_0[] = { "Any", "No Fit", "Text and Display", "Script", "Decorative", "Pictorial" };
-
-char *panose_values_1[] = { "Any", "No Fit", "Cove", "Obtuse Cove", "Square Cove", "Obtuse Square Cove",
- "Square", "Thin", "Bone", "Exaggerated", "Triangle", "Normal Sans",
- "Obtuse Sans", "Perp Sans", "Flared", "Rounded" } ;
-
-char *panose_values_2[] = { "Any", "No Fit", "Very Light", "Light", "Thin", "Book",
- "Medium", "Demi", "Bold", "Heavy", "Black", "Nord" } ;
-
-char *panose_values_3[] = { "Any", "No Fit", "Old Style", "Modern", "Even Width",
- "Expanded", "Condensed", "Very Expanded", "Very Condensed", "Monospaced" };
-
-char *panose_values_4[] = { "Any", "No Fit", "None", "Very Low", "Low", "Medium Low",
- "Medium", "Medium High", "High", "Very High" };
-
-char *panose_values_5[] = { "Any", "No Fit", "Gradual/Diagonal", "Gradual/Transitional","Gradual/Vertical",
- "Gradual/Horizontal", "Rapid/Vertical", "Rapid/Horizontal", "Instant/Vertical" };
-
-char *panose_values_6[] = {"Any","No Fit","Straight Arms/Horizontal","Straight Arms/Wedge","Straight Arms/Vertical",
- "Straight Arms/Single Serif","Straight Arms/Double Serif","Non-Straight Arms/Horizontal",
- "Non-Straight Arms/Wedge","Non-Straight Arms/Vertical","Non-Straight Arms/Single Serif",
- "Non-Straight Arms/Double Serif" };
-
-char *panose_values_7[] = { "Any", "No Fit","Normal/Contact","Normal/Weighted","Normal/Boxed","Normal/Flattened",
- "Normal/Rounded","Normal/Off Center","Normal/Square","Oblique/Contact","Oblique/Weighted",
- "Oblique/Boxed","Oblique/Flattened","Oblique/Rounded","Oblique/Off Center","Oblique/Square" };
-
-char *panose_values_8[] = { "Any","No Fit","Standard/Trimmed","Standard/Pointed","Standard/Serifed","High/Trimmed",
- "High/Pointed","High/Serifed","Constant/Trimmed","Constant/Pointed","Constant/Serifed",
- "Low/Trimmed","Low/Pointed","Low/Serifed"};
-
-char *panose_values_9[] = { "Any","No Fit", "Constant/Small", "Constant/Standard",
- "Constant/Large", "Ducking/Small", "Ducking/Standard", "Ducking/Large" };
-
-
-void
-handle_pfminfo (lua_State *L, struct pfminfo pfm) {
-
- dump_intfield (L, "pfmset", pfm.pfmset);
- dump_intfield (L, "winascent_add", pfm.winascent_add);
- dump_intfield (L, "windescent_add", pfm.windescent_add);
- dump_intfield (L, "hheadascent_add", pfm.hheadascent_add);
- dump_intfield (L, "hheaddescent_add", pfm.hheaddescent_add);
- dump_intfield (L, "typoascent_add", pfm.typoascent_add);
- dump_intfield (L, "typodescent_add", pfm.typodescent_add);
- dump_intfield (L, "subsuper_set", pfm.subsuper_set);
- dump_intfield (L, "panose_set", pfm.panose_set);
- dump_intfield (L, "hheadset", pfm.hheadset);
- dump_intfield (L, "vheadset", pfm.vheadset);
- dump_intfield (L, "pfmfamily", pfm.pfmfamily);
- dump_intfield (L, "weight", pfm.weight);
- dump_intfield (L, "width", pfm.width);
- dump_intfield (L, "avgwidth", pfm.avgwidth);
- dump_intfield (L, "firstchar", pfm.firstchar);
- dump_intfield (L, "lastchar", pfm.lastchar);
- lua_createtable(L,0,10);
- dump_enumfield(L,"familytype", pfm.panose[0], panose_values_0);
- dump_enumfield(L,"serifstyle", pfm.panose[1], panose_values_1);
- dump_enumfield(L,"weight", pfm.panose[2], panose_values_2);
- dump_enumfield(L,"proportion", pfm.panose[3], panose_values_3);
- dump_enumfield(L,"contrast", pfm.panose[4], panose_values_4);
- dump_enumfield(L,"strokevariation", pfm.panose[5], panose_values_5);
- dump_enumfield(L,"armstyle", pfm.panose[6], panose_values_6);
- dump_enumfield(L,"letterform", pfm.panose[7], panose_values_7);
- dump_enumfield(L,"midline", pfm.panose[8], panose_values_8);
- dump_enumfield(L,"xheight", pfm.panose[9], panose_values_9);
- lua_setfield (L,-2,"panose");
-
- dump_intfield (L, "fstype", pfm.fstype);
- dump_intfield (L, "linegap", pfm.linegap);
- dump_intfield (L, "vlinegap", pfm.vlinegap);
- dump_intfield (L, "hhead_ascent", pfm.hhead_ascent);
- dump_intfield (L, "hhead_descent", pfm.hhead_descent);
- dump_intfield (L, "hhead_descent", pfm.hhead_descent);
- dump_intfield (L, "os2_typoascent", pfm.os2_typoascent );
- dump_intfield (L, "os2_typodescent", pfm.os2_typodescent );
- dump_intfield (L, "os2_typolinegap", pfm.os2_typolinegap );
- dump_intfield (L, "os2_winascent", pfm.os2_winascent );
- dump_intfield (L, "os2_windescent", pfm.os2_windescent );
- dump_intfield (L, "os2_subxsize", pfm.os2_subxsize );
- dump_intfield (L, "os2_subysize", pfm.os2_subysize );
- dump_intfield (L, "os2_subxoff", pfm.os2_subxoff );
- dump_intfield (L, "os2_subyoff", pfm.os2_subyoff );
- dump_intfield (L, "os2_supxsize", pfm.os2_supxsize );
- dump_intfield (L, "os2_supysize", pfm.os2_supysize );
- dump_intfield (L, "os2_supxoff", pfm.os2_supxoff );
- dump_intfield (L, "os2_supyoff", pfm.os2_supyoff );
- dump_intfield (L, "os2_strikeysize", pfm.os2_strikeysize );
- dump_intfield (L, "os2_strikeypos", pfm.os2_strikeypos );
- dump_lstringfield (L, "os2_vendor", pfm.os2_vendor, 4);
- dump_intfield (L, "os2_family_class", pfm.os2_family_class);
- dump_intfield (L, "os2_xheight", pfm.os2_xheight);
- dump_intfield (L, "os2_capheight", pfm.os2_capheight);
- dump_intfield (L, "os2_defaultchar", pfm.os2_defaultchar);
- dump_intfield (L, "os2_breakchar", pfm.os2_breakchar);
- if (pfm.hascodepages) {
- lua_newtable(L);
- lua_pushnumber(L, pfm.codepages[0]); lua_rawseti(L,-2,1);
- lua_pushnumber(L, pfm.codepages[1]); lua_rawseti(L,-2,2);
- lua_setfield(L,-2,"codepages");
- }
- if (pfm.hasunicoderanges) {
+ for (i = 0; i < vars->part_cnt; i++) {
+ lua_newtable(L);
+ dump_stringfield(L, "component", vars->parts[i].component);
+ dump_intfield(L, "extender", vars->parts[i].is_extender);
+ dump_intfield(L, "start", vars->parts[i].startConnectorLength);
+ dump_intfield(L, "end", vars->parts[i].endConnectorLength);
+ dump_intfield(L, "advance", vars->parts[i].fullAdvance);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "parts");
+}
+
+void handle_mathkernvertex(lua_State * L, struct mathkernvertex *mkv)
+{
+ int i;
+ for (i = 0; i < mkv->cnt; i++) {
+ lua_newtable(L);
+ dump_intfield(L, "height", mkv->mkd[i].height);
+ dump_intfield(L, "kern", mkv->mkd[i].kern);
+ lua_rawseti(L, -2, (i + 1));
+ }
+}
+
+void handle_mathkern(lua_State * L, struct mathkern *mk)
+{
lua_newtable(L);
- lua_pushnumber(L, pfm.unicoderanges[0]); lua_rawseti(L,-2,1);
- lua_pushnumber(L, pfm.unicoderanges[1]); lua_rawseti(L,-2,2);
- lua_pushnumber(L, pfm.unicoderanges[2]); lua_rawseti(L,-2,3);
- lua_pushnumber(L, pfm.unicoderanges[3]); lua_rawseti(L,-2,4);
- lua_setfield(L,-2,"unicoderanges");
- }
-}
-
-
-void
-do_handle_enc (lua_State *L, struct enc *enc) {
- int i;
-
- dump_stringfield(L,"enc_name", enc->enc_name);
- dump_intfield (L,"char_cnt", enc->char_cnt);
-
- lua_checkstack(L,4);
- if (enc->char_cnt && enc->unicode != NULL) {
- lua_createtable(L,enc->char_cnt,1);
- for (i=0;i<enc->char_cnt;i++) {
- lua_pushnumber(L,i);
- lua_pushnumber(L,enc->unicode[i]);
- lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"unicode");
- }
-
- if (enc->char_cnt && enc->psnames != NULL) {
- lua_createtable(L,enc->char_cnt,1);
- for (i=0;i<enc->char_cnt;i++) {
- lua_pushnumber(L,i);
- lua_pushstring(L,enc->psnames[i]);
- lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"psnames");
- }
- dump_intfield (L,"builtin", enc->builtin );
- dump_intfield (L,"hidden", enc->hidden );
- dump_intfield (L,"only_1byte", enc->only_1byte );
- dump_intfield (L,"has_1byte", enc->has_1byte );
- dump_intfield (L,"has_2byte", enc->has_2byte );
- dump_cond_intfield (L,"is_unicodebmp", enc->is_unicodebmp );
- dump_cond_intfield (L,"is_unicodefull", enc->is_unicodefull );
- dump_cond_intfield (L,"is_custom", enc->is_custom );
- dump_cond_intfield (L,"is_original", enc->is_original );
- dump_cond_intfield (L,"is_compact", enc->is_compact );
- dump_cond_intfield (L,"is_japanese", enc->is_japanese );
- dump_cond_intfield (L,"is_korean", enc->is_korean );
- dump_cond_intfield (L,"is_tradchinese", enc->is_tradchinese );
- dump_cond_intfield (L,"is_simplechinese", enc->is_simplechinese);
-
- if (enc->iso_2022_escape_len > 0) {
- dump_lstringfield (L,"iso_2022_escape", enc->iso_2022_escape, enc->iso_2022_escape_len);
- }
- dump_intfield (L,"low_page", enc->low_page);
- dump_intfield(L,"high_page", enc->high_page);
-
- dump_stringfield(L,"iconv_name", enc->iconv_name);
-
- dump_intfield (L,"char_max", enc->char_max);
-}
-
-void
-handle_enc (lua_State *L, struct enc *enc) {
- struct enc *next;
- NESTED_TABLE(do_handle_enc,enc,24);
-}
-
-void
-handle_encmap (lua_State *L, struct encmap *map, int notdef_loc) {
- int i;
- dump_intfield(L,"enccount", map->enccount) ;
- dump_intfield(L,"encmax", map->encmax) ;
- dump_intfield(L,"backmax", map->backmax) ;
- /*dump_intfield(L,"ticked", map->ticked) ;*/
- if (map->remap != NULL) {
+ handle_mathkernvertex(L, &(mk->top_right));
+ lua_setfield(L, -2, "top_right");
lua_newtable(L);
- dump_intfield(L,"firstenc", map->remap->firstenc) ;
- dump_intfield(L,"lastenc", map->remap->lastenc) ;
- dump_intfield(L,"infont", map->remap->infont) ;
- lua_setfield(L,-2,"remap");
- }
- lua_checkstack(L,4);
- if (map->encmax > 0 && map->map != NULL) {
- lua_createtable(L,map->encmax,1);
- for (i=0;i<map->encmax;i++) {
- if (map->map[i]!=-1) {
- int l = map->map[i];
- lua_pushnumber(L,i);
- if (l<notdef_loc)
- lua_pushnumber(L,(l+1));
- else
- lua_pushnumber(L,l);
- lua_rawset(L,-3);
- }
- }
- lua_setfield(L,-2,"map");
- }
-
- if (map->backmax > 0 && map->backmap != NULL) {
+ handle_mathkernvertex(L, &(mk->top_left));
+ lua_setfield(L, -2, "top_left");
lua_newtable(L);
- for (i=0;i<map->backmax;i++) {
- if (map->backmap[i]!=-1) { /* TODO: check this, because valgrind sometimes says
- "Conditional jump or move depends on uninitialised value(s)"
- needs a test file.
- */
- if (i<notdef_loc)
- lua_pushnumber(L,(i+1));
- else
- lua_pushnumber(L,i);
- lua_pushnumber(L,map->backmap[i]);
- lua_rawset(L,-3);
- }
- }
- lua_setfield(L,-2,"backmap");
- }
-
- if (map->enc != NULL) {
+ handle_mathkernvertex(L, &(mk->bottom_right));
+ lua_setfield(L, -2, "bottom_right");
lua_newtable(L);
- handle_enc(L,map->enc);
- lua_setfield(L,-2,"enc");
- }
+ handle_mathkernvertex(L, &(mk->bottom_left));
+ lua_setfield(L, -2, "bottom_left");
}
-static void
-handle_psdict (lua_State *L, struct psdict *private) {
- int k;
- if (private->keys != NULL && private->values != NULL) {
- for (k=0;k<private->next;k++) {
- lua_pushstring(L,private->keys[k]);
- lua_pushstring(L,private->values[k]);
- lua_rawset(L,-3);
- }
- }
+
+
+void handle_splinechar(lua_State * L, struct splinechar *glyph, int hasvmetrics)
+{
+ DBounds bb;
+ if (glyph->xmax == 0 && glyph->ymax == 0 && glyph->xmin == 0
+ && glyph->ymin == 0) {
+ SplineCharFindBounds(glyph, &bb);
+ glyph->xmin = bb.minx;
+ glyph->ymin = bb.miny;
+ glyph->xmax = bb.maxx;
+ glyph->ymax = bb.maxy;
+ }
+ dump_stringfield(L, "name", glyph->name);
+ dump_intfield(L, "unicode", glyph->unicodeenc);
+ lua_createtable(L, 4, 0);
+ lua_pushnumber(L, 1);
+ lua_pushnumber(L, glyph->xmin);
+ lua_rawset(L, -3);
+ lua_pushnumber(L, 2);
+ lua_pushnumber(L, glyph->ymin);
+ lua_rawset(L, -3);
+ lua_pushnumber(L, 3);
+ lua_pushnumber(L, glyph->xmax);
+ lua_rawset(L, -3);
+ lua_pushnumber(L, 4);
+ lua_pushnumber(L, glyph->ymax);
+ lua_rawset(L, -3);
+ lua_setfield(L, -2, "boundingbox");
+ /*dump_intfield(L,"orig_pos", glyph->orig_pos); */
+ if (hasvmetrics)
+ dump_intfield(L, "vwidth", glyph->vwidth);
+ dump_intfield(L, "width", glyph->width);
+
+ if (glyph->lsidebearing != glyph->xmin) {
+ dump_cond_intfield(L, "lsidebearing", glyph->lsidebearing);
+ }
+ /* dump_intfield(L,"ttf_glyph", glyph->ttf_glyph); */
+
+ /* Layer layers[2]; *//* TH Not used */
+ /* int layer_cnt; *//* TH Not used */
+ /* StemInfo *hstem; *//* TH Not used */
+ /* StemInfo *vstem; *//* TH Not used */
+ /* DStemInfo *dstem; *//* TH Not used */
+
+ /* MinimumDistance *md; *//* TH Not used */
+ /* struct charviewbase *views; *//* TH Not used */
+ /* struct charinfo *charinfo; *//* TH ? (charinfo.c) */
+ /* struct splinefont *parent; *//* TH Not used */
+
+ if (glyph->glyph_class > 0) {
+ dump_enumfield(L, "class", glyph->glyph_class, glyph_class_enum);
+ }
+ /* TH: internal fontforge stuff
+ dump_intfield(L,"changed", glyph->changed);
+ dump_intfield(L,"changedsincelasthinted", glyph->changedsincelasthinted);
+ dump_intfield(L,"manualhints", glyph->manualhints);
+ dump_intfield(L,"ticked", glyph->ticked);
+ dump_intfield(L,"changed_since_autosave", glyph->changed_since_autosave);
+ dump_intfield(L,"widthset", glyph->widthset);
+ dump_intfield(L,"vconflicts", glyph->vconflicts);
+ dump_intfield(L,"hconflicts", glyph->hconflicts);
+ dump_intfield(L,"searcherdummy", glyph->searcherdummy);
+ dump_intfield(L,"changed_since_search", glyph->changed_since_search);
+ dump_intfield(L,"wasopen", glyph->wasopen);
+ dump_intfield(L,"namechanged", glyph->namechanged);
+ dump_intfield(L,"blended", glyph->blended);
+ dump_intfield(L,"ticked2", glyph->ticked2);
+ dump_intfield(L,"unused_so_far", glyph->unused_so_far);
+ dump_intfield(L,"numberpointsbackards", glyph->numberpointsbackards);
+ dump_intfield(L,"instructions_out_of_date", glyph->instructions_out_of_date);
+ dump_intfield(L,"complained_about_ptnums", glyph->complained_about_ptnums);
+ unsigned int vs_open: 1;
+ unsigned int unlink_rm_ovrlp_save_undo: 1;
+ unsigned int inspiro: 1;
+ unsigned int lig_caret_cnt_fixed: 1;
+
+
+ uint8 *ttf_instrs;
+ int16 ttf_instrs_len;
+ int16 countermask_cnt;
+ HintMask *countermasks;
+ */
+
+ if (glyph->kerns != NULL) {
+ lua_newtable(L);
+ handle_kernpair(L, glyph->kerns);
+ lua_setfield(L, -2, "kerns");
+ }
+ if (glyph->vkerns != NULL) {
+ lua_newtable(L);
+ handle_kernpair(L, glyph->vkerns);
+ lua_setfield(L, -2, "vkerns");
+ }
+
+ if (glyph->dependents != NULL) {
+ lua_newtable(L);
+ handle_splinecharlist(L, glyph->dependents);
+ lua_setfield(L, -2, "dependents");
+
+ }
+ if (glyph->possub != NULL) {
+ lua_newtable(L);
+ handle_generic_pst(L, glyph->possub);
+ lua_setfield(L, -2, "lookups");
+ }
+
+ if (glyph->ligofme != NULL) {
+ lua_newtable(L);
+ handle_liglist(L, glyph->ligofme);
+ lua_setfield(L, -2, "ligatures");
+ }
+
+ if (glyph->comment != NULL)
+ dump_stringfield(L, "comment", glyph->comment);
+
+ /* Color color; *//* dont care */
+
+ if (glyph->anchor != NULL) {
+ lua_newtable(L);
+ handle_anchorpoint(L, glyph->anchor);
+ lua_setfield(L, -2, "anchors");
+ }
+
+ if (glyph->altuni != NULL) {
+ lua_newtable(L);
+ handle_altuni(L, glyph->altuni);
+ lua_setfield(L, -2, "altuni");
+ }
+
+ if (glyph->tex_height != TEX_UNDEF)
+ dump_intfield(L, "tex_height", glyph->tex_height);
+ if (glyph->tex_depth != TEX_UNDEF)
+ dump_intfield(L, "tex_depth", glyph->tex_depth);
+
+ dump_cond_intfield(L, "is_extended_shape", glyph->is_extended_shape);
+ if (glyph->italic_correction != TEX_UNDEF)
+ dump_intfield(L, "italic_correction", glyph->italic_correction);
+ if (glyph->top_accent_horiz != TEX_UNDEF)
+ dump_intfield(L, "top_accent", glyph->top_accent_horiz);
+
+ if (glyph->vert_variants != NULL) {
+ lua_newtable(L);
+ handle_glyphvariants(L, glyph->vert_variants);
+ lua_setfield(L, -2, "vert_variants");
+ }
+ if (glyph->horiz_variants != NULL) {
+ lua_newtable(L);
+ handle_glyphvariants(L, glyph->horiz_variants);
+ lua_setfield(L, -2, "horiz_variants");
+ }
+ if (glyph->mathkern != NULL) {
+ lua_newtable(L);
+ handle_mathkern(L, glyph->mathkern);
+ lua_setfield(L, -2, "mathkern");
+ }
}
-void
-do_handle_ttflangname (lua_State *L, struct ttflangname *names) {
- int k;
- dump_stringfield(L,"lang", (char *)MSLangString(names->lang)) ;
- lua_checkstack(L,4);
- lua_createtable(L,0,ttf_namemax);
- for (k=0;k<ttf_namemax;k++) {
- lua_pushstring(L,ttfnames_enum[k]);
- lua_pushstring(L,names->names[k]);
- lua_rawset(L,-3);
- }
- lua_setfield(L, -2 , "names");
+char *panose_values_0[] =
+ { "Any", "No Fit", "Text and Display", "Script", "Decorative",
+ "Pictorial"
+};
+
+char *panose_values_1[] =
+ { "Any", "No Fit", "Cove", "Obtuse Cove", "Square Cove",
+ "Obtuse Square Cove",
+ "Square", "Thin", "Bone", "Exaggerated", "Triangle", "Normal Sans",
+ "Obtuse Sans", "Perp Sans", "Flared", "Rounded"
+};
+
+char *panose_values_2[] =
+ { "Any", "No Fit", "Very Light", "Light", "Thin", "Book",
+ "Medium", "Demi", "Bold", "Heavy", "Black", "Nord"
+};
+
+char *panose_values_3[] =
+ { "Any", "No Fit", "Old Style", "Modern", "Even Width",
+ "Expanded", "Condensed", "Very Expanded", "Very Condensed", "Monospaced"
+};
+
+char *panose_values_4[] =
+ { "Any", "No Fit", "None", "Very Low", "Low", "Medium Low",
+ "Medium", "Medium High", "High", "Very High"
+};
+
+char *panose_values_5[] =
+ { "Any", "No Fit", "Gradual/Diagonal", "Gradual/Transitional",
+ "Gradual/Vertical",
+ "Gradual/Horizontal", "Rapid/Vertical", "Rapid/Horizontal",
+ "Instant/Vertical"
+};
+
+char *panose_values_6[] =
+ { "Any", "No Fit", "Straight Arms/Horizontal", "Straight Arms/Wedge",
+ "Straight Arms/Vertical",
+ "Straight Arms/Single Serif", "Straight Arms/Double Serif",
+ "Non-Straight Arms/Horizontal",
+ "Non-Straight Arms/Wedge", "Non-Straight Arms/Vertical",
+ "Non-Straight Arms/Single Serif",
+ "Non-Straight Arms/Double Serif"
+};
+
+char *panose_values_7[] =
+ { "Any", "No Fit", "Normal/Contact", "Normal/Weighted", "Normal/Boxed",
+ "Normal/Flattened",
+ "Normal/Rounded", "Normal/Off Center", "Normal/Square", "Oblique/Contact",
+ "Oblique/Weighted",
+ "Oblique/Boxed", "Oblique/Flattened", "Oblique/Rounded",
+ "Oblique/Off Center", "Oblique/Square"
+};
+
+char *panose_values_8[] =
+ { "Any", "No Fit", "Standard/Trimmed", "Standard/Pointed",
+ "Standard/Serifed", "High/Trimmed",
+ "High/Pointed", "High/Serifed", "Constant/Trimmed", "Constant/Pointed",
+ "Constant/Serifed",
+ "Low/Trimmed", "Low/Pointed", "Low/Serifed"
+};
+
+char *panose_values_9[] =
+ { "Any", "No Fit", "Constant/Small", "Constant/Standard",
+ "Constant/Large", "Ducking/Small", "Ducking/Standard", "Ducking/Large"
+};
+
+
+void handle_pfminfo(lua_State * L, struct pfminfo pfm)
+{
+
+ dump_intfield(L, "pfmset", pfm.pfmset);
+ dump_intfield(L, "winascent_add", pfm.winascent_add);
+ dump_intfield(L, "windescent_add", pfm.windescent_add);
+ dump_intfield(L, "hheadascent_add", pfm.hheadascent_add);
+ dump_intfield(L, "hheaddescent_add", pfm.hheaddescent_add);
+ dump_intfield(L, "typoascent_add", pfm.typoascent_add);
+ dump_intfield(L, "typodescent_add", pfm.typodescent_add);
+ dump_intfield(L, "subsuper_set", pfm.subsuper_set);
+ dump_intfield(L, "panose_set", pfm.panose_set);
+ dump_intfield(L, "hheadset", pfm.hheadset);
+ dump_intfield(L, "vheadset", pfm.vheadset);
+ dump_intfield(L, "pfmfamily", pfm.pfmfamily);
+ dump_intfield(L, "weight", pfm.weight);
+ dump_intfield(L, "width", pfm.width);
+ dump_intfield(L, "avgwidth", pfm.avgwidth);
+ dump_intfield(L, "firstchar", pfm.firstchar);
+ dump_intfield(L, "lastchar", pfm.lastchar);
+ lua_createtable(L, 0, 10);
+ dump_enumfield(L, "familytype", pfm.panose[0], panose_values_0);
+ dump_enumfield(L, "serifstyle", pfm.panose[1], panose_values_1);
+ dump_enumfield(L, "weight", pfm.panose[2], panose_values_2);
+ dump_enumfield(L, "proportion", pfm.panose[3], panose_values_3);
+ dump_enumfield(L, "contrast", pfm.panose[4], panose_values_4);
+ dump_enumfield(L, "strokevariation", pfm.panose[5], panose_values_5);
+ dump_enumfield(L, "armstyle", pfm.panose[6], panose_values_6);
+ dump_enumfield(L, "letterform", pfm.panose[7], panose_values_7);
+ dump_enumfield(L, "midline", pfm.panose[8], panose_values_8);
+ dump_enumfield(L, "xheight", pfm.panose[9], panose_values_9);
+ lua_setfield(L, -2, "panose");
+
+ dump_intfield(L, "fstype", pfm.fstype);
+ dump_intfield(L, "linegap", pfm.linegap);
+ dump_intfield(L, "vlinegap", pfm.vlinegap);
+ dump_intfield(L, "hhead_ascent", pfm.hhead_ascent);
+ dump_intfield(L, "hhead_descent", pfm.hhead_descent);
+ dump_intfield(L, "hhead_descent", pfm.hhead_descent);
+ dump_intfield(L, "os2_typoascent", pfm.os2_typoascent);
+ dump_intfield(L, "os2_typodescent", pfm.os2_typodescent);
+ dump_intfield(L, "os2_typolinegap", pfm.os2_typolinegap);
+ dump_intfield(L, "os2_winascent", pfm.os2_winascent);
+ dump_intfield(L, "os2_windescent", pfm.os2_windescent);
+ dump_intfield(L, "os2_subxsize", pfm.os2_subxsize);
+ dump_intfield(L, "os2_subysize", pfm.os2_subysize);
+ dump_intfield(L, "os2_subxoff", pfm.os2_subxoff);
+ dump_intfield(L, "os2_subyoff", pfm.os2_subyoff);
+ dump_intfield(L, "os2_supxsize", pfm.os2_supxsize);
+ dump_intfield(L, "os2_supysize", pfm.os2_supysize);
+ dump_intfield(L, "os2_supxoff", pfm.os2_supxoff);
+ dump_intfield(L, "os2_supyoff", pfm.os2_supyoff);
+ dump_intfield(L, "os2_strikeysize", pfm.os2_strikeysize);
+ dump_intfield(L, "os2_strikeypos", pfm.os2_strikeypos);
+ dump_lstringfield(L, "os2_vendor", pfm.os2_vendor, 4);
+ dump_intfield(L, "os2_family_class", pfm.os2_family_class);
+ dump_intfield(L, "os2_xheight", pfm.os2_xheight);
+ dump_intfield(L, "os2_capheight", pfm.os2_capheight);
+ dump_intfield(L, "os2_defaultchar", pfm.os2_defaultchar);
+ dump_intfield(L, "os2_breakchar", pfm.os2_breakchar);
+ if (pfm.hascodepages) {
+ lua_newtable(L);
+ lua_pushnumber(L, pfm.codepages[0]);
+ lua_rawseti(L, -2, 1);
+ lua_pushnumber(L, pfm.codepages[1]);
+ lua_rawseti(L, -2, 2);
+ lua_setfield(L, -2, "codepages");
+ }
+ if (pfm.hasunicoderanges) {
+ lua_newtable(L);
+ lua_pushnumber(L, pfm.unicoderanges[0]);
+ lua_rawseti(L, -2, 1);
+ lua_pushnumber(L, pfm.unicoderanges[1]);
+ lua_rawseti(L, -2, 2);
+ lua_pushnumber(L, pfm.unicoderanges[2]);
+ lua_rawseti(L, -2, 3);
+ lua_pushnumber(L, pfm.unicoderanges[3]);
+ lua_rawseti(L, -2, 4);
+ lua_setfield(L, -2, "unicoderanges");
+ }
}
-void
-handle_ttflangname (lua_State *L, struct ttflangname *names) {
- struct ttflangname *next;
- NESTED_TABLE(do_handle_ttflangname,names,2);
+void do_handle_enc(lua_State * L, struct enc *enc)
+{
+ int i;
+
+ dump_stringfield(L, "enc_name", enc->enc_name);
+ dump_intfield(L, "char_cnt", enc->char_cnt);
+
+ lua_checkstack(L, 4);
+ if (enc->char_cnt && enc->unicode != NULL) {
+ lua_createtable(L, enc->char_cnt, 1);
+ for (i = 0; i < enc->char_cnt; i++) {
+ lua_pushnumber(L, i);
+ lua_pushnumber(L, enc->unicode[i]);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "unicode");
+ }
+
+ if (enc->char_cnt && enc->psnames != NULL) {
+ lua_createtable(L, enc->char_cnt, 1);
+ for (i = 0; i < enc->char_cnt; i++) {
+ lua_pushnumber(L, i);
+ lua_pushstring(L, enc->psnames[i]);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "psnames");
+ }
+ dump_intfield(L, "builtin", enc->builtin);
+ dump_intfield(L, "hidden", enc->hidden);
+ dump_intfield(L, "only_1byte", enc->only_1byte);
+ dump_intfield(L, "has_1byte", enc->has_1byte);
+ dump_intfield(L, "has_2byte", enc->has_2byte);
+ dump_cond_intfield(L, "is_unicodebmp", enc->is_unicodebmp);
+ dump_cond_intfield(L, "is_unicodefull", enc->is_unicodefull);
+ dump_cond_intfield(L, "is_custom", enc->is_custom);
+ dump_cond_intfield(L, "is_original", enc->is_original);
+ dump_cond_intfield(L, "is_compact", enc->is_compact);
+ dump_cond_intfield(L, "is_japanese", enc->is_japanese);
+ dump_cond_intfield(L, "is_korean", enc->is_korean);
+ dump_cond_intfield(L, "is_tradchinese", enc->is_tradchinese);
+ dump_cond_intfield(L, "is_simplechinese", enc->is_simplechinese);
+
+ if (enc->iso_2022_escape_len > 0) {
+ dump_lstringfield(L, "iso_2022_escape", enc->iso_2022_escape,
+ enc->iso_2022_escape_len);
+ }
+ dump_intfield(L, "low_page", enc->low_page);
+ dump_intfield(L, "high_page", enc->high_page);
+
+ dump_stringfield(L, "iconv_name", enc->iconv_name);
+
+ dump_intfield(L, "char_max", enc->char_max);
}
+void handle_enc(lua_State * L, struct enc *enc)
+{
+ struct enc *next;
+ NESTED_TABLE(do_handle_enc, enc, 24);
+}
-void
-do_handle_anchorclass (lua_State *L, struct anchorclass *anchor) {
+void handle_encmap(lua_State * L, struct encmap *map, int notdef_loc)
+{
+ int i;
+ dump_intfield(L, "enccount", map->enccount);
+ dump_intfield(L, "encmax", map->encmax);
+ dump_intfield(L, "backmax", map->backmax);
+ /*dump_intfield(L,"ticked", map->ticked) ; */
+ if (map->remap != NULL) {
+ lua_newtable(L);
+ dump_intfield(L, "firstenc", map->remap->firstenc);
+ dump_intfield(L, "lastenc", map->remap->lastenc);
+ dump_intfield(L, "infont", map->remap->infont);
+ lua_setfield(L, -2, "remap");
+ }
+ lua_checkstack(L, 4);
+ if (map->encmax > 0 && map->map != NULL) {
+ lua_createtable(L, map->encmax, 1);
+ for (i = 0; i < map->encmax; i++) {
+ if (map->map[i] != -1) {
+ int l = map->map[i];
+ lua_pushnumber(L, i);
+ if (l < notdef_loc)
+ lua_pushnumber(L, (l + 1));
+ else
+ lua_pushnumber(L, l);
+ lua_rawset(L, -3);
+ }
+ }
+ lua_setfield(L, -2, "map");
+ }
+
+ if (map->backmax > 0 && map->backmap != NULL) {
+ lua_newtable(L);
+ for (i = 0; i < map->backmax; i++) {
+ if (map->backmap[i] != -1) { /* TODO: check this, because valgrind sometimes says
+ "Conditional jump or move depends on uninitialised value(s)"
+ needs a test file.
+ */
+ if (i < notdef_loc)
+ lua_pushnumber(L, (i + 1));
+ else
+ lua_pushnumber(L, i);
+ lua_pushnumber(L, map->backmap[i]);
+ lua_rawset(L, -3);
+ }
+ }
+ lua_setfield(L, -2, "backmap");
+ }
- dump_stringfield(L,"name", anchor->name);
- dump_subtable_name (L, "lookup", anchor->subtable);
- dump_enumfield(L,"type", anchor->type, anchorclass_type_enum);
- /* uint8 has_base; */
- /* uint8 processed, has_mark, matches, ac_num; */
- /* uint8 ticked; */
+ if (map->enc != NULL) {
+ lua_newtable(L);
+ handle_enc(L, map->enc);
+ lua_setfield(L, -2, "enc");
+ }
}
-void
-handle_anchorclass (lua_State *L, struct anchorclass *anchor) {
- struct anchorclass *next;
- NESTED_TABLE(do_handle_anchorclass,anchor,10);
+static void handle_psdict(lua_State * L, struct psdict *private)
+{
+ int k;
+ if (private->keys != NULL && private->values != NULL) {
+ for (k = 0; k < private->next; k++) {
+ lua_pushstring(L, private->keys[k]);
+ lua_pushstring(L, private->values[k]);
+ lua_rawset(L, -3);
+ }
+ }
+}
+
+void do_handle_ttflangname(lua_State * L, struct ttflangname *names)
+{
+ int k;
+ dump_stringfield(L, "lang", (char *) MSLangString(names->lang));
+ lua_checkstack(L, 4);
+ lua_createtable(L, 0, ttf_namemax);
+ for (k = 0; k < ttf_namemax; k++) {
+ lua_pushstring(L, ttfnames_enum[k]);
+ lua_pushstring(L, names->names[k]);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "names");
}
-void
-do_handle_ttf_table (lua_State *L, struct ttf_table *ttf_tab) {
- dump_tag(L,"tag", ttf_tab->tag);
- dump_intfield(L,"len", ttf_tab->len);
- dump_intfield(L,"maxlen", ttf_tab->maxlen);
- dump_lstringfield(L,"data", (char *)ttf_tab->data, ttf_tab->len);
+void handle_ttflangname(lua_State * L, struct ttflangname *names)
+{
+ struct ttflangname *next;
+ NESTED_TABLE(do_handle_ttflangname, names, 2);
}
-void
-handle_ttf_table (lua_State *L, struct ttf_table *ttf_tab) {
- struct ttf_table *next;
- NESTED_TABLE(do_handle_ttf_table,ttf_tab,4);
+
+void do_handle_anchorclass(lua_State * L, struct anchorclass *anchor)
+{
+
+ dump_stringfield(L, "name", anchor->name);
+ dump_subtable_name(L, "lookup", anchor->subtable);
+ dump_enumfield(L, "type", anchor->type, anchorclass_type_enum);
+ /* uint8 has_base; */
+ /* uint8 processed, has_mark, matches, ac_num; */
+ /* uint8 ticked; */
}
-void
-do_handle_kernclass (lua_State *L, struct kernclass *kerns) {
- int k;
-
- /*
- * dump_intfield(L,"first_cnt", kerns->first_cnt);
- * dump_intfield(L,"second_cnt", kerns->second_cnt);
- */
- lua_checkstack(L,4);
- lua_createtable(L,kerns->first_cnt,1);
- for (k=0;k<kerns->first_cnt;k++) {
- lua_pushnumber(L,(k+1));
- lua_pushstring(L,kerns->firsts[k]);
- lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"firsts");
-
- lua_createtable(L,kerns->second_cnt,1);
- for (k=0;k<kerns->second_cnt;k++) {
- lua_pushnumber(L,(k+1));
- lua_pushstring(L,kerns->seconds[k]);
- lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"seconds");
-
- dump_subtable_name(L, "lookup", kerns->subtable);
- /*dump_intfield(L,"kcid", kerns->kcid); *//* probably not needed */
-
- lua_createtable(L,kerns->second_cnt*kerns->first_cnt,1);
- for (k=0;k<(kerns->second_cnt*kerns->first_cnt);k++) {
- if (kerns->offsets[k]!=0) {
- lua_pushnumber(L,(k+1));
- lua_pushnumber(L,kerns->offsets[k]);
- lua_rawset(L,-3);
- }
- }
- lua_setfield(L,-2,"offsets");
+void handle_anchorclass(lua_State * L, struct anchorclass *anchor)
+{
+ struct anchorclass *next;
+ NESTED_TABLE(do_handle_anchorclass, anchor, 10);
+}
+void do_handle_ttf_table(lua_State * L, struct ttf_table *ttf_tab)
+{
+
+ dump_tag(L, "tag", ttf_tab->tag);
+ dump_intfield(L, "len", ttf_tab->len);
+ dump_intfield(L, "maxlen", ttf_tab->maxlen);
+ dump_lstringfield(L, "data", (char *) ttf_tab->data, ttf_tab->len);
}
-void
-handle_kernclass (lua_State *L, struct kernclass *kerns) {
- struct kernclass *next;
- NESTED_TABLE(do_handle_kernclass,kerns,8);
+void handle_ttf_table(lua_State * L, struct ttf_table *ttf_tab)
+{
+ struct ttf_table *next;
+ NESTED_TABLE(do_handle_ttf_table, ttf_tab, 4);
+}
+
+void do_handle_kernclass(lua_State * L, struct kernclass *kerns)
+{
+ int k;
+
+ /*
+ * dump_intfield(L,"first_cnt", kerns->first_cnt);
+ * dump_intfield(L,"second_cnt", kerns->second_cnt);
+ */
+ lua_checkstack(L, 4);
+ lua_createtable(L, kerns->first_cnt, 1);
+ for (k = 0; k < kerns->first_cnt; k++) {
+ lua_pushnumber(L, (k + 1));
+ lua_pushstring(L, kerns->firsts[k]);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "firsts");
+
+ lua_createtable(L, kerns->second_cnt, 1);
+ for (k = 0; k < kerns->second_cnt; k++) {
+ lua_pushnumber(L, (k + 1));
+ lua_pushstring(L, kerns->seconds[k]);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "seconds");
+
+ dump_subtable_name(L, "lookup", kerns->subtable);
+ /*dump_intfield(L,"kcid", kerns->kcid); *//* probably not needed */
+
+ lua_createtable(L, kerns->second_cnt * kerns->first_cnt, 1);
+ for (k = 0; k < (kerns->second_cnt * kerns->first_cnt); k++) {
+ if (kerns->offsets[k] != 0) {
+ lua_pushnumber(L, (k + 1));
+ lua_pushnumber(L, kerns->offsets[k]);
+ lua_rawset(L, -3);
+ }
+ }
+ lua_setfield(L, -2, "offsets");
+
+}
+
+void handle_kernclass(lua_State * L, struct kernclass *kerns)
+{
+ struct kernclass *next;
+ NESTED_TABLE(do_handle_kernclass, kerns, 8);
}
@@ -1335,200 +1459,209 @@ handle_kernclass (lua_State *L, struct kernclass *kerns) {
lua_setfield(L,-2,s); } }
-void handle_fpst_rule (lua_State *L, struct fpst_rule *rule, int format) {
- int k;
+void handle_fpst_rule(lua_State * L, struct fpst_rule *rule, int format)
+{
+ int k;
- if (format == pst_glyphs) {
+ if (format == pst_glyphs) {
- lua_newtable(L);
- dump_stringfield(L,"names",rule->u.glyph.names);
- dump_stringfield(L,"back",rule->u.glyph.back);
- dump_stringfield(L,"fore",rule->u.glyph.fore);
- lua_setfield(L,-2,fpossub_format_enum[format]);
+ lua_newtable(L);
+ dump_stringfield(L, "names", rule->u.glyph.names);
+ dump_stringfield(L, "back", rule->u.glyph.back);
+ dump_stringfield(L, "fore", rule->u.glyph.fore);
+ lua_setfield(L, -2, fpossub_format_enum[format]);
- } else if (format == pst_class) {
-
- lua_newtable(L);
- DUMP_NUMBER_ARRAY("current", rule->u.class.ncnt,rule->u.class.nclasses);
- DUMP_NUMBER_ARRAY("before", rule->u.class.bcnt,rule->u.class.bclasses);
- DUMP_NUMBER_ARRAY("after", rule->u.class.fcnt,rule->u.class.fclasses);
+ } else if (format == pst_class) {
+
+ lua_newtable(L);
+ DUMP_NUMBER_ARRAY("current", rule->u.class.ncnt,
+ rule->u.class.nclasses);
+ DUMP_NUMBER_ARRAY("before", rule->u.class.bcnt, rule->u.class.bclasses);
+ DUMP_NUMBER_ARRAY("after", rule->u.class.fcnt, rule->u.class.fclasses);
#if 0
- DUMP_NUMBER_ARRAY("allclasses", 0,rule->u.class.allclasses);
+ DUMP_NUMBER_ARRAY("allclasses", 0, rule->u.class.allclasses);
#endif
- lua_setfield(L,-2,fpossub_format_enum[format]);
+ lua_setfield(L, -2, fpossub_format_enum[format]);
- } else if (format == pst_coverage) {
+ } else if (format == pst_coverage) {
- lua_newtable(L);
- DUMP_STRING_ARRAY("current", rule->u.coverage.ncnt,rule->u.coverage.ncovers);
- DUMP_STRING_ARRAY("before", rule->u.coverage.bcnt,rule->u.coverage.bcovers);
- DUMP_STRING_ARRAY("after", rule->u.coverage.fcnt,rule->u.coverage.fcovers);
- lua_setfield(L,-2,fpossub_format_enum[format]);
+ lua_newtable(L);
+ DUMP_STRING_ARRAY("current", rule->u.coverage.ncnt,
+ rule->u.coverage.ncovers);
+ DUMP_STRING_ARRAY("before", rule->u.coverage.bcnt,
+ rule->u.coverage.bcovers);
+ DUMP_STRING_ARRAY("after", rule->u.coverage.fcnt,
+ rule->u.coverage.fcovers);
+ lua_setfield(L, -2, fpossub_format_enum[format]);
- } else if (format == pst_reversecoverage) {
+ } else if (format == pst_reversecoverage) {
- lua_newtable(L);
- DUMP_STRING_ARRAY("current", rule->u.rcoverage.always1,rule->u.rcoverage.ncovers);
- DUMP_STRING_ARRAY("before", rule->u.rcoverage.bcnt,rule->u.rcoverage.bcovers);
- DUMP_STRING_ARRAY("after", rule->u.rcoverage.fcnt,rule->u.rcoverage.fcovers);
- dump_stringfield(L,"replacements", rule->u.rcoverage.replacements);
- lua_setfield(L,-2,fpossub_format_enum[format]);
- } else {
- fprintf(stderr,"handle_fpst_rule(): Unknown rule format: %d\n",format);
- }
-
- if (rule->lookup_cnt>0) {
- lua_newtable(L);
- for (k=0;k<rule->lookup_cnt;k++) {
- lua_pushnumber(L,(rule->lookups[k].seq+1));
- if (rule->lookups[k].lookup!=NULL) {
- lua_pushstring(L,rule->lookups[k].lookup->lookup_name);
- } else {
- lua_pushnil(L);
- }
- lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"lookups");
- } else {
- /*fprintf(stderr,"handle_fpst_rule(): No lookups?\n");*/
- }
-}
-
-void
-do_handle_generic_fpst(lua_State *L, struct generic_fpst *fpst) {
- int k;
-
- if (fpst->type>LAST_POSSUB_TYPE_ENUM) {
- dump_intfield(L,"type", fpst->type);
- } else {
- dump_enumfield(L,"type", fpst->type, possub_type_enum);
- }
- dump_enumfield(L,"format", fpst->format, fpossub_format_enum);
-
- if (fpst->format==pst_class) {
- DUMP_EXACT_STRING_ARRAY("current_class",fpst->nccnt,fpst->nclass);
- DUMP_EXACT_STRING_ARRAY("before_class",fpst->bccnt,fpst->bclass);
- DUMP_EXACT_STRING_ARRAY("after_class",fpst->fccnt,fpst->fclass);
- } else {
- DUMP_STRING_ARRAY("current_class",fpst->nccnt,fpst->nclass);
- DUMP_STRING_ARRAY("before_class",fpst->bccnt,fpst->bclass);
- DUMP_STRING_ARRAY("after_class",fpst->fccnt,fpst->fclass);
- }
-
- lua_checkstack(L,4);
- if (fpst->rule_cnt>0) {
- lua_createtable(L,fpst->rule_cnt,1);
- for (k=0;k<fpst->rule_cnt;k++) {
- lua_pushnumber(L,(k+1));
- lua_newtable(L);
- handle_fpst_rule(L,&(fpst->rules[k]),fpst->format);
- lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"rules");
- }
- /*dump_intfield (L,"ticked", fpst->ticked);*/
-}
-
-void
-handle_generic_fpst(lua_State *L, struct generic_fpst *fpst) {
- struct generic_fpst *next;
- int k = 1;
- lua_checkstack(L,3);
- if (fpst->subtable != NULL &&
- fpst->subtable->subtable_name != NULL) {
- lua_pushstring(L,fpst->subtable->subtable_name);
- } else {
- lua_pushnumber(L,k); k++;
- }
- lua_createtable(L,0,10);
- do_handle_generic_fpst(L,fpst);
- lua_rawset(L,-3);
- next = fpst->next;
- while (next != NULL) {
- lua_checkstack(L,3);
- if (next->subtable != NULL &&
- next->subtable->subtable_name != NULL) {
- lua_pushstring(L,next->subtable->subtable_name);
- } else {
- lua_pushnumber(L,k); k++;
- }
- lua_createtable(L,0,10);
- do_handle_generic_fpst(L, next);
- lua_rawset(L,-3);
- next = next->next;
- }
+ lua_newtable(L);
+ DUMP_STRING_ARRAY("current", rule->u.rcoverage.always1,
+ rule->u.rcoverage.ncovers);
+ DUMP_STRING_ARRAY("before", rule->u.rcoverage.bcnt,
+ rule->u.rcoverage.bcovers);
+ DUMP_STRING_ARRAY("after", rule->u.rcoverage.fcnt,
+ rule->u.rcoverage.fcovers);
+ dump_stringfield(L, "replacements", rule->u.rcoverage.replacements);
+ lua_setfield(L, -2, fpossub_format_enum[format]);
+ } else {
+ fprintf(stderr, "handle_fpst_rule(): Unknown rule format: %d\n",
+ format);
+ }
+
+ if (rule->lookup_cnt > 0) {
+ lua_newtable(L);
+ for (k = 0; k < rule->lookup_cnt; k++) {
+ lua_pushnumber(L, (rule->lookups[k].seq + 1));
+ if (rule->lookups[k].lookup != NULL) {
+ lua_pushstring(L, rule->lookups[k].lookup->lookup_name);
+ } else {
+ lua_pushnil(L);
+ }
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "lookups");
+ } else {
+ /*fprintf(stderr,"handle_fpst_rule(): No lookups?\n"); */
+ }
}
-void
-do_handle_otfname (lua_State *L, struct otfname *oname) {
- dump_intfield(L,"lang", oname->lang);
- dump_stringfield(L,"name", oname->name);
+void do_handle_generic_fpst(lua_State * L, struct generic_fpst *fpst)
+{
+ int k;
+
+ if (fpst->type > LAST_POSSUB_TYPE_ENUM) {
+ dump_intfield(L, "type", fpst->type);
+ } else {
+ dump_enumfield(L, "type", fpst->type, possub_type_enum);
+ }
+ dump_enumfield(L, "format", fpst->format, fpossub_format_enum);
+
+ if (fpst->format == pst_class) {
+ DUMP_EXACT_STRING_ARRAY("current_class", fpst->nccnt, fpst->nclass);
+ DUMP_EXACT_STRING_ARRAY("before_class", fpst->bccnt, fpst->bclass);
+ DUMP_EXACT_STRING_ARRAY("after_class", fpst->fccnt, fpst->fclass);
+ } else {
+ DUMP_STRING_ARRAY("current_class", fpst->nccnt, fpst->nclass);
+ DUMP_STRING_ARRAY("before_class", fpst->bccnt, fpst->bclass);
+ DUMP_STRING_ARRAY("after_class", fpst->fccnt, fpst->fclass);
+ }
+
+ lua_checkstack(L, 4);
+ if (fpst->rule_cnt > 0) {
+ lua_createtable(L, fpst->rule_cnt, 1);
+ for (k = 0; k < fpst->rule_cnt; k++) {
+ lua_pushnumber(L, (k + 1));
+ lua_newtable(L);
+ handle_fpst_rule(L, &(fpst->rules[k]), fpst->format);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "rules");
+ }
+ /*dump_intfield (L,"ticked", fpst->ticked); */
+}
+
+void handle_generic_fpst(lua_State * L, struct generic_fpst *fpst)
+{
+ struct generic_fpst *next;
+ int k = 1;
+ lua_checkstack(L, 3);
+ if (fpst->subtable != NULL && fpst->subtable->subtable_name != NULL) {
+ lua_pushstring(L, fpst->subtable->subtable_name);
+ } else {
+ lua_pushnumber(L, k);
+ k++;
+ }
+ lua_createtable(L, 0, 10);
+ do_handle_generic_fpst(L, fpst);
+ lua_rawset(L, -3);
+ next = fpst->next;
+ while (next != NULL) {
+ lua_checkstack(L, 3);
+ if (next->subtable != NULL && next->subtable->subtable_name != NULL) {
+ lua_pushstring(L, next->subtable->subtable_name);
+ } else {
+ lua_pushnumber(L, k);
+ k++;
+ }
+ lua_createtable(L, 0, 10);
+ do_handle_generic_fpst(L, next);
+ lua_rawset(L, -3);
+ next = next->next;
+ }
}
-void
-handle_otfname (lua_State *L, struct otfname *oname) {
- struct otfname *next;
- NESTED_TABLE(do_handle_otfname,oname,2);
+void do_handle_otfname(lua_State * L, struct otfname *oname)
+{
+ dump_intfield(L, "lang", oname->lang);
+ dump_stringfield(L, "name", oname->name);
}
-void
-do_handle_macname (lua_State *L, struct macname *featname) {
- dump_intfield(L,"enc", featname->enc);
- dump_intfield(L,"lang", featname->lang);
- dump_stringfield(L,"name", featname->name);
+void handle_otfname(lua_State * L, struct otfname *oname)
+{
+ struct otfname *next;
+ NESTED_TABLE(do_handle_otfname, oname, 2);
}
-void
-handle_macname (lua_State *L, struct macname *featname) {
- struct macname *next;
- NESTED_TABLE(do_handle_macname,featname,3);
+void do_handle_macname(lua_State * L, struct macname *featname)
+{
+ dump_intfield(L, "enc", featname->enc);
+ dump_intfield(L, "lang", featname->lang);
+ dump_stringfield(L, "name", featname->name);
}
-void
-do_handle_macsetting (lua_State *L, struct macsetting *settings) {
- dump_intfield(L,"setting", settings->setting);
- dump_intfield(L,"strid", settings->strid);
- dump_intfield(L,"initially_enabled", settings->initially_enabled);
- if (settings->setname != NULL) {
- lua_newtable(L);
- handle_macname(L,settings->setname);
- lua_setfield(L,-2,"setname");
- }
+void handle_macname(lua_State * L, struct macname *featname)
+{
+ struct macname *next;
+ NESTED_TABLE(do_handle_macname, featname, 3);
}
-void
-handle_macsetting (lua_State *L, struct macsetting *settings) {
- struct macsetting *next;
- NESTED_TABLE(do_handle_macsetting,settings,4);
+void do_handle_macsetting(lua_State * L, struct macsetting *settings)
+{
+ dump_intfield(L, "setting", settings->setting);
+ dump_intfield(L, "strid", settings->strid);
+ dump_intfield(L, "initially_enabled", settings->initially_enabled);
+ if (settings->setname != NULL) {
+ lua_newtable(L);
+ handle_macname(L, settings->setname);
+ lua_setfield(L, -2, "setname");
+ }
}
+void handle_macsetting(lua_State * L, struct macsetting *settings)
+{
+ struct macsetting *next;
+ NESTED_TABLE(do_handle_macsetting, settings, 4);
+}
-void
-do_handle_macfeat (lua_State *L, struct macfeat *features) {
- dump_intfield(L,"feature", features->feature);
- dump_intfield(L,"ismutex", features->ismutex);
- dump_intfield(L,"default_setting", features->default_setting);
- dump_intfield(L,"strid", features->strid);
+void do_handle_macfeat(lua_State * L, struct macfeat *features)
+{
- if (features->featname != NULL) {
- lua_newtable(L);
- handle_macname(L,features->featname);
- lua_setfield(L,-2,"featname");
- }
+ dump_intfield(L, "feature", features->feature);
+ dump_intfield(L, "ismutex", features->ismutex);
+ dump_intfield(L, "default_setting", features->default_setting);
+ dump_intfield(L, "strid", features->strid);
- if (features->settings != NULL) {
- lua_newtable(L);
- handle_macsetting(L,features->settings);
- lua_setfield(L,-2,"settings");
- }
+ if (features->featname != NULL) {
+ lua_newtable(L);
+ handle_macname(L, features->featname);
+ lua_setfield(L, -2, "featname");
+ }
+
+ if (features->settings != NULL) {
+ lua_newtable(L);
+ handle_macsetting(L, features->settings);
+ lua_setfield(L, -2, "settings");
+ }
}
-void
-handle_macfeat (lua_State *L, struct macfeat *features) {
- struct macfeat *next;
- NESTED_TABLE(do_handle_macfeat,features,6);
+void handle_macfeat(lua_State * L, struct macfeat *features)
+{
+ struct macfeat *next;
+ NESTED_TABLE(do_handle_macfeat, features, 6);
}
@@ -1564,818 +1697,875 @@ handle_macfeat (lua_State *L, struct macfeat *features) {
0x3fff value offset
*/
/* to be tested */
-void
-do_handle_generic_asm (lua_State *L, struct generic_asm *sm) {
- int i, k;
-
- dump_enumfield (L,"type", sm->type, asm_type_enum);
- /* backref */
- dump_subtable_name(L, "lookup", sm->subtable);
- /* uint8 ticked; */
- lua_newtable(L);
- if (sm->flags & asm_vert) {
- lua_pushstring(L,"vert"); lua_pushboolean(L,1); lua_rawset(L,-3);
- }
- if (sm->flags & asm_descending) {
- lua_pushstring(L,"descending"); lua_pushboolean(L,1); lua_rawset(L,-3);
- }
- if (sm->flags & asm_always) {
- lua_pushstring(L,"always"); lua_pushboolean(L,1); lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"flags");
-
- if (sm->class_cnt >0) {
+void do_handle_generic_asm(lua_State * L, struct generic_asm *sm)
+{
+ int i, k;
+
+ dump_enumfield(L, "type", sm->type, asm_type_enum);
+ /* backref */
+ dump_subtable_name(L, "lookup", sm->subtable);
+ /* uint8 ticked; */
lua_newtable(L);
- for (i=0; i<sm->class_cnt; i++) {
- if (sm->classes[i]!=NULL) {
- lua_pushstring(L,sm->classes[i]);
- lua_rawseti(L,-2,(i+1));
- }
- }
- lua_setfield(L,-2,"classes");
- }
- if (sm->state_cnt >0) {
- lua_newtable(L);
- for (i=0; i<(sm->class_cnt * sm->state_cnt); i++) {
- struct asm_state as = sm->state[i];
- dump_intfield(L,"next", as.next_state);
- dump_intfield(L,"flags", as.flags);
- if (sm->type==asm_context) {
- lua_newtable(L);
- if (as.u.context.mark_lookup!=NULL)
- dump_stringfield(L,"mark", as.u.context.mark_lookup->lookup_name); /* backref */
- if (as.u.context.cur_lookup!=NULL)
- dump_stringfield(L,"cur", as.u.context.cur_lookup->lookup_name); /* backref */
- lua_setfield(L,-2,"context");
- } else if (sm->type==asm_insert) {
- lua_newtable(L);
- lua_pushstring(L, as.u.insert.mark_ins);
- lua_setfield(L, -2, "mark");
- lua_pushstring(L, as.u.insert.cur_ins);
- lua_setfield(L, -2, "cur");
- lua_setfield(L,-2,"insert");
- } else if (sm->type==asm_kern) {
- lua_newtable(L);
- for (k=0;k<as.u.kern.kcnt;k++) {
- lua_pushnumber(L,as.u.kern.kerns[k]);
- lua_rawseti(L,-2, (k+1));
- }
- lua_setfield(L,-2,"kerns");
- }
- }
- lua_setfield(L,-2,"states");
- }
-}
-
-void
-handle_generic_asm (lua_State *L, struct generic_asm *sm) {
- struct generic_asm *next;
- NESTED_TABLE(do_handle_generic_asm,sm,6);
-}
-
-
-
-
-void handle_MATH (lua_State *L, struct MATH *MATH) {
- dump_intfield(L,"ScriptPercentScaleDown",MATH->ScriptPercentScaleDown);
- dump_intfield(L,"ScriptScriptPercentScaleDown",MATH->ScriptScriptPercentScaleDown);
- dump_intfield(L,"DelimitedSubFormulaMinHeight",MATH->DelimitedSubFormulaMinHeight);
- dump_intfield(L,"DisplayOperatorMinHeight",MATH->DisplayOperatorMinHeight);
- dump_intfield(L,"MathLeading",MATH->MathLeading);
- dump_intfield(L,"AxisHeight",MATH->AxisHeight);
- dump_intfield(L,"AccentBaseHeight",MATH->AccentBaseHeight);
- dump_intfield(L,"FlattenedAccentBaseHeight",MATH->FlattenedAccentBaseHeight);
- dump_intfield(L,"SubscriptShiftDown",MATH->SubscriptShiftDown);
- dump_intfield(L,"SubscriptTopMax",MATH->SubscriptTopMax);
- dump_intfield(L,"SubscriptBaselineDropMin",MATH->SubscriptBaselineDropMin);
- dump_intfield(L,"SuperscriptShiftUp",MATH->SuperscriptShiftUp);
- dump_intfield(L,"SuperscriptShiftUpCramped",MATH->SuperscriptShiftUpCramped);
- dump_intfield(L,"SuperscriptBottomMin",MATH->SuperscriptBottomMin);
- dump_intfield(L,"SuperscriptBaselineDropMax",MATH->SuperscriptBaselineDropMax);
- dump_intfield(L,"SubSuperscriptGapMin",MATH->SubSuperscriptGapMin);
- dump_intfield(L,"SuperscriptBottomMaxWithSubscript",MATH->SuperscriptBottomMaxWithSubscript);
- dump_intfield(L,"SpaceAfterScript",MATH->SpaceAfterScript);
- dump_intfield(L,"UpperLimitGapMin",MATH->UpperLimitGapMin);
- dump_intfield(L,"UpperLimitBaselineRiseMin",MATH->UpperLimitBaselineRiseMin);
- dump_intfield(L,"LowerLimitGapMin",MATH->LowerLimitGapMin);
- dump_intfield(L,"LowerLimitBaselineDropMin",MATH->LowerLimitBaselineDropMin);
- dump_intfield(L,"StackTopShiftUp",MATH->StackTopShiftUp);
- dump_intfield(L,"StackTopDisplayStyleShiftUp",MATH->StackTopDisplayStyleShiftUp);
- dump_intfield(L,"StackBottomShiftDown",MATH->StackBottomShiftDown);
- dump_intfield(L,"StackBottomDisplayStyleShiftDown",MATH->StackBottomDisplayStyleShiftDown);
- dump_intfield(L,"StackGapMin",MATH->StackGapMin);
- dump_intfield(L,"StackDisplayStyleGapMin",MATH->StackDisplayStyleGapMin);
- dump_intfield(L,"StretchStackTopShiftUp",MATH->StretchStackTopShiftUp);
- dump_intfield(L,"StretchStackBottomShiftDown",MATH->StretchStackBottomShiftDown);
- dump_intfield(L,"StretchStackGapAboveMin",MATH->StretchStackGapAboveMin);
- dump_intfield(L,"StretchStackGapBelowMin",MATH->StretchStackGapBelowMin);
- dump_intfield(L,"FractionNumeratorShiftUp",MATH->FractionNumeratorShiftUp);
- dump_intfield(L,"FractionNumeratorDisplayStyleShiftUp",MATH->FractionNumeratorDisplayStyleShiftUp);
- dump_intfield(L,"FractionDenominatorShiftDown",MATH->FractionDenominatorShiftDown);
- dump_intfield(L,"FractionDenominatorDisplayStyleShiftDown",MATH->FractionDenominatorDisplayStyleShiftDown);
- dump_intfield(L,"FractionNumeratorGapMin",MATH->FractionNumeratorGapMin);
- dump_intfield(L,"FractionNumeratorDisplayStyleGapMin",MATH->FractionNumeratorDisplayStyleGapMin);
- dump_intfield(L,"FractionRuleThickness",MATH->FractionRuleThickness);
- dump_intfield(L,"FractionDenominatorGapMin",MATH->FractionDenominatorGapMin);
- dump_intfield(L,"FractionDenominatorDisplayStyleGapMin",MATH->FractionDenominatorDisplayStyleGapMin);
- dump_intfield(L,"SkewedFractionHorizontalGap",MATH->SkewedFractionHorizontalGap);
- dump_intfield(L,"SkewedFractionVerticalGap",MATH->SkewedFractionVerticalGap);
- dump_intfield(L,"OverbarVerticalGap",MATH->OverbarVerticalGap);
- dump_intfield(L,"OverbarRuleThickness",MATH->OverbarRuleThickness);
- dump_intfield(L,"OverbarExtraAscender",MATH->OverbarExtraAscender);
- dump_intfield(L,"UnderbarVerticalGap",MATH->UnderbarVerticalGap);
- dump_intfield(L,"UnderbarRuleThickness",MATH->UnderbarRuleThickness);
- dump_intfield(L,"UnderbarExtraDescender",MATH->UnderbarExtraDescender);
- dump_intfield(L,"RadicalVerticalGap",MATH->RadicalVerticalGap);
- dump_intfield(L,"RadicalDisplayStyleVerticalGap",MATH->RadicalDisplayStyleVerticalGap);
- dump_intfield(L,"RadicalRuleThickness",MATH->RadicalRuleThickness);
- dump_intfield(L,"RadicalExtraAscender",MATH->RadicalExtraAscender);
- dump_intfield(L,"RadicalKernBeforeDegree",MATH->RadicalKernBeforeDegree);
- dump_intfield(L,"RadicalKernAfterDegree",MATH->RadicalKernAfterDegree);
- dump_intfield(L,"RadicalDegreeBottomRaisePercent",MATH->RadicalDegreeBottomRaisePercent);
- dump_intfield(L,"MinConnectorOverlap",MATH->MinConnectorOverlap);
+ if (sm->flags & asm_vert) {
+ lua_pushstring(L, "vert");
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+ }
+ if (sm->flags & asm_descending) {
+ lua_pushstring(L, "descending");
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+ }
+ if (sm->flags & asm_always) {
+ lua_pushstring(L, "always");
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "flags");
+
+ if (sm->class_cnt > 0) {
+ lua_newtable(L);
+ for (i = 0; i < sm->class_cnt; i++) {
+ if (sm->classes[i] != NULL) {
+ lua_pushstring(L, sm->classes[i]);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ }
+ lua_setfield(L, -2, "classes");
+ }
+ if (sm->state_cnt > 0) {
+ lua_newtable(L);
+ for (i = 0; i < (sm->class_cnt * sm->state_cnt); i++) {
+ struct asm_state as = sm->state[i];
+ dump_intfield(L, "next", as.next_state);
+ dump_intfield(L, "flags", as.flags);
+ if (sm->type == asm_context) {
+ lua_newtable(L);
+ if (as.u.context.mark_lookup != NULL)
+ dump_stringfield(L, "mark", as.u.context.mark_lookup->lookup_name); /* backref */
+ if (as.u.context.cur_lookup != NULL)
+ dump_stringfield(L, "cur", as.u.context.cur_lookup->lookup_name); /* backref */
+ lua_setfield(L, -2, "context");
+ } else if (sm->type == asm_insert) {
+ lua_newtable(L);
+ lua_pushstring(L, as.u.insert.mark_ins);
+ lua_setfield(L, -2, "mark");
+ lua_pushstring(L, as.u.insert.cur_ins);
+ lua_setfield(L, -2, "cur");
+ lua_setfield(L, -2, "insert");
+ } else if (sm->type == asm_kern) {
+ lua_newtable(L);
+ for (k = 0; k < as.u.kern.kcnt; k++) {
+ lua_pushnumber(L, as.u.kern.kerns[k]);
+ lua_rawseti(L, -2, (k + 1));
+ }
+ lua_setfield(L, -2, "kerns");
+ }
+ }
+ lua_setfield(L, -2, "states");
+ }
+}
+
+void handle_generic_asm(lua_State * L, struct generic_asm *sm)
+{
+ struct generic_asm *next;
+ NESTED_TABLE(do_handle_generic_asm, sm, 6);
+}
+
+
+
+
+void handle_MATH(lua_State * L, struct MATH *MATH)
+{
+ dump_intfield(L, "ScriptPercentScaleDown", MATH->ScriptPercentScaleDown);
+ dump_intfield(L, "ScriptScriptPercentScaleDown",
+ MATH->ScriptScriptPercentScaleDown);
+ dump_intfield(L, "DelimitedSubFormulaMinHeight",
+ MATH->DelimitedSubFormulaMinHeight);
+ dump_intfield(L, "DisplayOperatorMinHeight",
+ MATH->DisplayOperatorMinHeight);
+ dump_intfield(L, "MathLeading", MATH->MathLeading);
+ dump_intfield(L, "AxisHeight", MATH->AxisHeight);
+ dump_intfield(L, "AccentBaseHeight", MATH->AccentBaseHeight);
+ dump_intfield(L, "FlattenedAccentBaseHeight",
+ MATH->FlattenedAccentBaseHeight);
+ dump_intfield(L, "SubscriptShiftDown", MATH->SubscriptShiftDown);
+ dump_intfield(L, "SubscriptTopMax", MATH->SubscriptTopMax);
+ dump_intfield(L, "SubscriptBaselineDropMin",
+ MATH->SubscriptBaselineDropMin);
+ dump_intfield(L, "SuperscriptShiftUp", MATH->SuperscriptShiftUp);
+ dump_intfield(L, "SuperscriptShiftUpCramped",
+ MATH->SuperscriptShiftUpCramped);
+ dump_intfield(L, "SuperscriptBottomMin", MATH->SuperscriptBottomMin);
+ dump_intfield(L, "SuperscriptBaselineDropMax",
+ MATH->SuperscriptBaselineDropMax);
+ dump_intfield(L, "SubSuperscriptGapMin", MATH->SubSuperscriptGapMin);
+ dump_intfield(L, "SuperscriptBottomMaxWithSubscript",
+ MATH->SuperscriptBottomMaxWithSubscript);
+ dump_intfield(L, "SpaceAfterScript", MATH->SpaceAfterScript);
+ dump_intfield(L, "UpperLimitGapMin", MATH->UpperLimitGapMin);
+ dump_intfield(L, "UpperLimitBaselineRiseMin",
+ MATH->UpperLimitBaselineRiseMin);
+ dump_intfield(L, "LowerLimitGapMin", MATH->LowerLimitGapMin);
+ dump_intfield(L, "LowerLimitBaselineDropMin",
+ MATH->LowerLimitBaselineDropMin);
+ dump_intfield(L, "StackTopShiftUp", MATH->StackTopShiftUp);
+ dump_intfield(L, "StackTopDisplayStyleShiftUp",
+ MATH->StackTopDisplayStyleShiftUp);
+ dump_intfield(L, "StackBottomShiftDown", MATH->StackBottomShiftDown);
+ dump_intfield(L, "StackBottomDisplayStyleShiftDown",
+ MATH->StackBottomDisplayStyleShiftDown);
+ dump_intfield(L, "StackGapMin", MATH->StackGapMin);
+ dump_intfield(L, "StackDisplayStyleGapMin", MATH->StackDisplayStyleGapMin);
+ dump_intfield(L, "StretchStackTopShiftUp", MATH->StretchStackTopShiftUp);
+ dump_intfield(L, "StretchStackBottomShiftDown",
+ MATH->StretchStackBottomShiftDown);
+ dump_intfield(L, "StretchStackGapAboveMin", MATH->StretchStackGapAboveMin);
+ dump_intfield(L, "StretchStackGapBelowMin", MATH->StretchStackGapBelowMin);
+ dump_intfield(L, "FractionNumeratorShiftUp",
+ MATH->FractionNumeratorShiftUp);
+ dump_intfield(L, "FractionNumeratorDisplayStyleShiftUp",
+ MATH->FractionNumeratorDisplayStyleShiftUp);
+ dump_intfield(L, "FractionDenominatorShiftDown",
+ MATH->FractionDenominatorShiftDown);
+ dump_intfield(L, "FractionDenominatorDisplayStyleShiftDown",
+ MATH->FractionDenominatorDisplayStyleShiftDown);
+ dump_intfield(L, "FractionNumeratorGapMin", MATH->FractionNumeratorGapMin);
+ dump_intfield(L, "FractionNumeratorDisplayStyleGapMin",
+ MATH->FractionNumeratorDisplayStyleGapMin);
+ dump_intfield(L, "FractionRuleThickness", MATH->FractionRuleThickness);
+ dump_intfield(L, "FractionDenominatorGapMin",
+ MATH->FractionDenominatorGapMin);
+ dump_intfield(L, "FractionDenominatorDisplayStyleGapMin",
+ MATH->FractionDenominatorDisplayStyleGapMin);
+ dump_intfield(L, "SkewedFractionHorizontalGap",
+ MATH->SkewedFractionHorizontalGap);
+ dump_intfield(L, "SkewedFractionVerticalGap",
+ MATH->SkewedFractionVerticalGap);
+ dump_intfield(L, "OverbarVerticalGap", MATH->OverbarVerticalGap);
+ dump_intfield(L, "OverbarRuleThickness", MATH->OverbarRuleThickness);
+ dump_intfield(L, "OverbarExtraAscender", MATH->OverbarExtraAscender);
+ dump_intfield(L, "UnderbarVerticalGap", MATH->UnderbarVerticalGap);
+ dump_intfield(L, "UnderbarRuleThickness", MATH->UnderbarRuleThickness);
+ dump_intfield(L, "UnderbarExtraDescender", MATH->UnderbarExtraDescender);
+ dump_intfield(L, "RadicalVerticalGap", MATH->RadicalVerticalGap);
+ dump_intfield(L, "RadicalDisplayStyleVerticalGap",
+ MATH->RadicalDisplayStyleVerticalGap);
+ dump_intfield(L, "RadicalRuleThickness", MATH->RadicalRuleThickness);
+ dump_intfield(L, "RadicalExtraAscender", MATH->RadicalExtraAscender);
+ dump_intfield(L, "RadicalKernBeforeDegree", MATH->RadicalKernBeforeDegree);
+ dump_intfield(L, "RadicalKernAfterDegree", MATH->RadicalKernAfterDegree);
+ dump_intfield(L, "RadicalDegreeBottomRaisePercent",
+ MATH->RadicalDegreeBottomRaisePercent);
+ dump_intfield(L, "MinConnectorOverlap", MATH->MinConnectorOverlap);
}
/* the handling of BASE is untested, no font */
-void handle_baselangextent (lua_State *L, struct baselangextent *ble);
+void handle_baselangextent(lua_State * L, struct baselangextent *ble);
-void
-do_handle_baselangextent (lua_State *L, struct baselangextent *ble) {
- dump_tag(L,"tag",ble->lang);
- dump_intfield(L,"ascent",ble->ascent);
- dump_intfield(L,"descent",ble->descent);
- lua_newtable(L);
- handle_baselangextent(L, ble->features);
- lua_setfield(L,-2,"features");
+void do_handle_baselangextent(lua_State * L, struct baselangextent *ble)
+{
+ dump_tag(L, "tag", ble->lang);
+ dump_intfield(L, "ascent", ble->ascent);
+ dump_intfield(L, "descent", ble->descent);
+ lua_newtable(L);
+ handle_baselangextent(L, ble->features);
+ lua_setfield(L, -2, "features");
}
-void handle_baselangextent (lua_State *L, struct baselangextent *ble) {
- struct baselangextent *next;
- NESTED_TABLE(do_handle_baselangextent,ble,4);
+void handle_baselangextent(lua_State * L, struct baselangextent *ble)
+{
+ struct baselangextent *next;
+ NESTED_TABLE(do_handle_baselangextent, ble, 4);
}
-void handle_base (lua_State *L, struct Base *Base) {
- int i;
- struct basescript *next = Base->scripts;
- lua_newtable(L);
- for ( i=0; i<Base->baseline_cnt; i++ ) {
- lua_pushstring(L,make_tag_string(Base->baseline_tags[i]));
- lua_rawseti(L,-2,(i+1));
- }
- lua_setfield(L,-2,"tags");
- if (next != NULL) {
+void handle_base(lua_State * L, struct Base *Base)
+{
+ int i;
+ struct basescript *next = Base->scripts;
lua_newtable(L);
- while (next != NULL) {
- lua_pushstring(L,make_tag_string(next->script));
- lua_newtable(L);
- dump_intfield(L, "default_baseline", (next->def_baseline+1)) ;
- lua_newtable(L);
- for ( i=0; i<Base->baseline_cnt; i++ ) {
- lua_pushnumber(L, next->baseline_pos[i]) ;
- lua_rawseti(L,-2, (i+1));
- }
- lua_setfield(L, -2, "baseline");
- lua_newtable(L);
- handle_baselangextent(L, next->langs);
- lua_setfield(L, -2, "lang");
- lua_rawset(L,-3);
- next = next->next;
- }
- lua_setfield(L,-2,"scripts");
- }
+ for (i = 0; i < Base->baseline_cnt; i++) {
+ lua_pushstring(L, make_tag_string(Base->baseline_tags[i]));
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "tags");
+ if (next != NULL) {
+ lua_newtable(L);
+ while (next != NULL) {
+ lua_pushstring(L, make_tag_string(next->script));
+ lua_newtable(L);
+ dump_intfield(L, "default_baseline", (next->def_baseline + 1));
+ lua_newtable(L);
+ for (i = 0; i < Base->baseline_cnt; i++) {
+ if (next->baseline_pos != NULL) /* default omitted */
+ lua_pushnumber(L, next->baseline_pos[i]);
+ else
+ lua_pushnumber(L, 0);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "baseline");
+ lua_newtable(L);
+ handle_baselangextent(L, next->langs);
+ lua_setfield(L, -2, "lang");
+ lua_rawset(L, -3);
+ next = next->next;
+ }
+ lua_setfield(L, -2, "scripts");
+ }
}
-void
-handle_axismap (lua_State *L, struct axismap *am) {
- int i;
- lua_checkstack(L,3);
- lua_newtable(L);
- for (i=0;i<am->points;i++) {
- lua_pushnumber(L, am->blends[i] ) ;
- lua_rawseti(L,-2, (i+1));
- }
- lua_setfield(L,-2,"blends");
- lua_newtable(L);
- for (i=0;i<am->points;i++) {
- lua_pushnumber(L, am->designs[i] ) ;
- lua_rawseti(L,-2, (i+1));
- }
- lua_setfield(L,-2,"designs");
- dump_realfield(L, "min", am->min) ;
- dump_realfield(L, "def", am->def) ;
- dump_realfield(L, "max", am->max) ;
- if (am->axisnames != NULL ){
+void handle_axismap(lua_State * L, struct axismap *am)
+{
+ int i;
+ lua_checkstack(L, 3);
lua_newtable(L);
- handle_macname(L, am->axisnames);
- lua_setfield(L,-2,"axisnames");
- }
-}
+ for (i = 0; i < am->points; i++) {
+ lua_pushnumber(L, am->blends[i]);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "blends");
+ lua_newtable(L);
+ for (i = 0; i < am->points; i++) {
+ lua_pushnumber(L, am->designs[i]);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "designs");
+ dump_realfield(L, "min", am->min);
+ dump_realfield(L, "def", am->def);
+ dump_realfield(L, "max", am->max);
+ if (am->axisnames != NULL) {
+ lua_newtable(L);
+ handle_macname(L, am->axisnames);
+ lua_setfield(L, -2, "axisnames");
+ }
+}
-void
-handle_mmset (lua_State *L, struct mmset *mm) {
- int i, k;
- lua_newtable(L);
- for (i=0;i<mm->axis_count;i++) {
- lua_pushstring(L, mm->axes[i]) ;
- lua_rawseti(L,-2, (i+1));
- }
- lua_setfield(L,-2,"axes");
-
- dump_intfield(L,"instance_count",mm->instance_count);
- /* SplineFont *normal; */ /* this is the parent */
- if (mm->instance_count>0) {
+void handle_mmset(lua_State * L, struct mmset *mm)
+{
+ int i, k;
lua_newtable(L);
- for (i=0;i<mm->instance_count*mm->axis_count;i++) {
- lua_pushnumber(L, mm->positions[i]) ;
- lua_rawseti(L,-2, (i+1));
+ for (i = 0; i < mm->axis_count; i++) {
+ lua_pushstring(L, mm->axes[i]);
+ lua_rawseti(L, -2, (i + 1));
}
- lua_setfield(L,-2,"positions");
+ lua_setfield(L, -2, "axes");
+
+ dump_intfield(L, "instance_count", mm->instance_count);
+ /* SplineFont *normal; *//* this is the parent */
+ if (mm->instance_count > 0) {
+ lua_newtable(L);
+ for (i = 0; i < mm->instance_count * mm->axis_count; i++) {
+ lua_pushnumber(L, mm->positions[i]);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "positions");
- /* better not to do this */
+ /* better not to do this */
#if 0
- {
- struct mmset *mmsave ;
- lua_newtable(L);
- for (i=0;i<mm->instance_count;i++) {
- lua_checkstack(L,20);
- lua_createtable(L,0,60);
- mmsave = mm->instances[i]->mm;
- mm->instances[i]->mm = NULL;
- handle_splinefont(L, mm->instances[i]);
- mm->instances[i]->mm = mmsave;
- lua_rawseti(L,-2, (i+1));
- }
- lua_setfield(L,-2,"instances");
- }
+ {
+ struct mmset *mmsave;
+ lua_newtable(L);
+ for (i = 0; i < mm->instance_count; i++) {
+ lua_checkstack(L, 20);
+ lua_createtable(L, 0, 60);
+ mmsave = mm->instances[i]->mm;
+ mm->instances[i]->mm = NULL;
+ handle_splinefont(L, mm->instances[i]);
+ mm->instances[i]->mm = mmsave;
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "instances");
+ }
#endif
- lua_newtable(L);
- for (i=0;i<mm->instance_count;i++) {
- lua_pushnumber(L, mm->defweights[i]) ;
- lua_rawseti(L,-2, (i+1));
- }
- lua_setfield(L,-2,"defweights");
- }
-
- if (mm->axismaps != NULL) {
- lua_newtable(L);
- for (i=0;i<mm->axis_count;i++) {
- lua_newtable(L);
- handle_axismap(L, &(mm->axismaps[i]));
- lua_rawseti(L, -2, (i+1));
+ lua_newtable(L);
+ for (i = 0; i < mm->instance_count; i++) {
+ lua_pushnumber(L, mm->defweights[i]);
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "defweights");
}
- lua_setfield(L,-2,"axismaps");
- }
- dump_stringfield(L,"cdv",mm->cdv);
- dump_stringfield(L,"ndv",mm->ndv);
- dump_intfield(L,"named_instance_count",mm->named_instance_count);
- if (mm->named_instance_count>0) {
- lua_newtable(L);
- for (i=0; i<mm->named_instance_count;i++) {
- struct named_instance *ni = &(mm->named_instances[i]);
+ if (mm->axismaps != NULL) {
lua_newtable(L);
+ for (i = 0; i < mm->axis_count; i++) {
+ lua_newtable(L);
+ handle_axismap(L, &(mm->axismaps[i]));
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "axismaps");
+ }
+ dump_stringfield(L, "cdv", mm->cdv);
+ dump_stringfield(L, "ndv", mm->ndv);
+ dump_intfield(L, "named_instance_count", mm->named_instance_count);
+ if (mm->named_instance_count > 0) {
+ lua_newtable(L);
+ for (i = 0; i < mm->named_instance_count; i++) {
+ struct named_instance *ni = &(mm->named_instances[i]);
+ lua_newtable(L);
+
+ lua_newtable(L);
+ for (k = 0; k <= mm->axis_count; k++) {
+ lua_pushnumber(L, ni->coords[k]);
+ lua_rawseti(L, -2, (k + 1));
+ }
+ lua_setfield(L, -2, "coords");
+
+ lua_newtable(L);
+ handle_macname(L, ni->names);
+ lua_setfield(L, -2, "names");
+
+ lua_rawseti(L, -2, (i + 1));
+ }
+ lua_setfield(L, -2, "named_instances");
+ }
+ /* unsigned int changed: 1; */
+ dump_intfield(L, "apple", mm->apple);
+}
+
+
+
+void handle_splinefont(lua_State * L, struct splinefont *sf)
+{
+ int k;
+ int fix_notdef = 0;
+ int l = -1;
+
+ dump_stringfield(L, "table_version", LUA_OTF_VERSION);
+ dump_stringfield(L, "fontname", sf->fontname);
+ dump_stringfield(L, "fullname", sf->fullname);
+ dump_stringfield(L, "familyname", sf->familyname);
+ dump_stringfield(L, "weight", sf->weight);
+ dump_stringfield(L, "copyright", sf->copyright);
+ dump_stringfield(L, "filename", sf->filename);
+ /* dump_stringfield(L,"defbasefilename", sf->defbasefilename); */
+ dump_stringfield(L, "version", sf->version);
+ dump_floatfield(L, "italicangle", sf->italicangle);
+ dump_floatfield(L, "upos", sf->upos);
+ dump_floatfield(L, "uwidth", sf->uwidth);
+ dump_intfield(L, "ascent", sf->ascent);
+ dump_intfield(L, "descent", sf->descent);
+ dump_intfield(L, "uniqueid", sf->uniqueid);
+ dump_intfield(L, "glyphcnt", sf->glyphcnt);
+ dump_intfield(L, "glyphmax", sf->glyphmax);
+ dump_intfield(L, "units_per_em", sf->units_per_em);
+
+ if (sf->possub != NULL) {
lua_newtable(L);
- for (k=0;k<=mm->axis_count;k++) {
- lua_pushnumber(L,ni->coords[k]);
- lua_rawseti(L,-2,(k+1));
+ handle_generic_fpst(L, sf->possub);
+ lua_setfield(L, -2, "lookups");
+ }
+
+ lua_checkstack(L, 4);
+ lua_createtable(L, sf->glyphcnt, 0);
+
+ /* This after-the-fact type discovery is not brilliant,
+ I should really add a 'format' key in the structure */
+ if ((sf->origname != NULL) &&
+ (strmatch(sf->origname + strlen(sf->origname) - 4, ".pfa") == 0 ||
+ strmatch(sf->origname + strlen(sf->origname) - 4, ".pfb") == 0)) {
+ fix_notdef = 1;
+ }
+
+ if (fix_notdef) {
+ /* some code to ensure that the .notdef ends up in slot 0
+ (this will actually be enforced by the CFF writer) */
+ for (k = 0; k < sf->glyphcnt; k++) {
+ if (sf->glyphs[k]) {
+ if (strcmp(sf->glyphs[k]->name, ".notdef") == 0) {
+ l = k;
+ }
+ }
+ }
+ if (l == -1) { /* fake a .notdef at the end */
+ l = sf->glyphcnt;
+ }
+ for (k = 0; k < l; k++) {
+ if (sf->glyphs[k]) {
+ lua_pushnumber(L, (k + 1));
+ lua_createtable(L, 0, 12);
+ handle_splinechar(L, sf->glyphs[k], sf->hasvmetrics);
+ lua_rawset(L, -3);
+ }
+ }
+ if (sf->glyphs != NULL && l < sf->glyphcnt) {
+ lua_pushnumber(L, 0);
+ if (sf->glyphs[l]) {
+ lua_createtable(L, 0, 12);
+ handle_splinechar(L, sf->glyphs[l], sf->hasvmetrics);
+ } else {
+ lua_createtable(L, 0, 0);
+ }
+ lua_rawset(L, -3);
+ }
+ }
+ if ((l + 1) < sf->glyphcnt) {
+ for (k = (l + 1); k < sf->glyphcnt; k++) {
+ if (sf->glyphs[k]) {
+ lua_pushnumber(L, k);
+ lua_createtable(L, 0, 12);
+ handle_splinechar(L, sf->glyphs[k], sf->hasvmetrics);
+ lua_rawset(L, -3);
+ }
}
- lua_setfield(L,-2,"coords");
+ }
+ lua_setfield(L, -2, "glyphs");
+
+ /* dump_intfield(L,"changed", sf->changed); */
+ dump_intfield(L, "hasvmetrics", sf->hasvmetrics);
+ dump_intfield(L, "onlybitmaps", sf->onlybitmaps);
+ dump_intfield(L, "serifcheck", sf->serifcheck);
+ dump_intfield(L, "isserif", sf->isserif);
+ dump_intfield(L, "issans", sf->issans);
+ dump_intfield(L, "encodingchanged", sf->encodingchanged);
+ dump_intfield(L, "strokedfont", sf->strokedfont);
+ dump_intfield(L, "use_typo_metrics", sf->use_typo_metrics);
+ dump_intfield(L, "weight_width_slope_only", sf->weight_width_slope_only);
+ dump_intfield(L, "head_optimized_for_cleartype",
+ sf->head_optimized_for_cleartype);
+
+ dump_enumfield(L, "uni_interp", (sf->uni_interp + 1), uni_interp_enum);
+
+ if (sf->map != NULL) {
+ lua_newtable(L);
+ handle_encmap(L, sf->map, l);
+ lua_setfield(L, -2, "map");
+ }
+
+ dump_stringfield(L, "origname", sf->origname); /* new */
+ if (sf->private != NULL) {
lua_newtable(L);
- handle_macname(L, ni->names);
- lua_setfield(L,-2,"names");
+ handle_psdict(L, sf->private);
+ lua_setfield(L, -2, "private");
+ }
- lua_rawseti(L,-2,(i+1));
- }
- lua_setfield(L,-2,"named_instances");
- }
- /* unsigned int changed: 1; */
- dump_intfield(L,"apple",mm->apple);
-}
+ dump_stringfield(L, "xuid", sf->xuid);
+ lua_createtable(L, 0, 40);
+ handle_pfminfo(L, sf->pfminfo);
+ lua_setfield(L, -2, "pfminfo");
+ if (sf->names != NULL) {
+ lua_newtable(L);
+ handle_ttflangname(L, sf->names);
+ lua_setfield(L, -2, "names");
+ }
-void
-handle_splinefont(lua_State *L, struct splinefont *sf) {
- int k;
- int fix_notdef = 0;
- int l = -1;
-
- dump_stringfield(L,"table_version", LUA_OTF_VERSION);
- dump_stringfield(L,"fontname", sf->fontname);
- dump_stringfield(L,"fullname", sf->fullname);
- dump_stringfield(L,"familyname", sf->familyname);
- dump_stringfield(L,"weight", sf->weight);
- dump_stringfield(L,"copyright", sf->copyright);
- dump_stringfield(L,"filename", sf->filename);
- /* dump_stringfield(L,"defbasefilename", sf->defbasefilename); */
- dump_stringfield(L,"version", sf->version);
- dump_floatfield (L,"italicangle", sf->italicangle);
- dump_floatfield (L,"upos", sf->upos);
- dump_floatfield (L,"uwidth", sf->uwidth);
- dump_intfield (L,"ascent", sf->ascent);
- dump_intfield (L,"descent", sf->descent);
- dump_intfield (L,"uniqueid", sf->uniqueid);
- dump_intfield (L,"glyphcnt", sf->glyphcnt);
- dump_intfield (L,"glyphmax", sf->glyphmax);
- dump_intfield (L,"units_per_em", sf->units_per_em);
-
- if (sf->possub != NULL) {
- lua_newtable(L);
- handle_generic_fpst(L,sf->possub);
- lua_setfield(L,-2,"lookups");
- }
-
- lua_checkstack(L,4);
- lua_createtable(L,sf->glyphcnt,0);
-
- /* This after-the-fact type discovery is not brilliant,
- I should really add a 'format' key in the structure */
- if ((sf->origname != NULL) &&
- (strmatch(sf->origname+strlen(sf->origname)-4, ".pfa")==0 ||
- strmatch(sf->origname+strlen(sf->origname)-4, ".pfb")==0)) {
- fix_notdef = 1;
- }
-
- if (fix_notdef) {
- /* some code to ensure that the .notdef ends up in slot 0
- (this will actually be enforced by the CFF writer) */
- for (k=0;k<sf->glyphcnt;k++) {
- if (sf->glyphs[k]) {
- if (strcmp(sf->glyphs[k]->name,".notdef") == 0) {
- l = k;
+ lua_createtable(L, 0, 4);
+ dump_stringfield(L, "registry", sf->cidregistry);
+ dump_stringfield(L, "ordering", sf->ordering);
+ dump_intfield(L, "version", sf->cidversion);
+ dump_intfield(L, "supplement", sf->supplement);
+ lua_setfield(L, -2, "cidinfo");
+
+ /* SplineFont *cidmaster *//* parent in a subfont */
+ if (sf->subfontcnt > 0) {
+ lua_createtable(L, sf->subfontcnt, 0);
+ for (k = 0; k < sf->subfontcnt; k++) {
+ lua_checkstack(L, 10);
+ lua_newtable(L);
+ handle_splinefont(L, sf->subfonts[k]);
+ lua_rawseti(L, -2, (k + 1));
}
- }
- }
- if (l==-1) { /* fake a .notdef at the end */
- l = sf->glyphcnt;
- }
- for (k=0;k<l;k++) {
- lua_pushnumber(L,(k+1));
- lua_createtable(L,0,12);
- if (sf->glyphs[k]) {
- handle_splinechar(L,sf->glyphs[k], sf->hasvmetrics);
- }
- lua_rawset(L,-3);
- }
- if (sf->glyphs != NULL && l<sf->glyphcnt) {
- lua_pushnumber(L,0);
- lua_createtable(L,0,12);
- if (sf->glyphs[l]) {
- handle_splinechar(L,sf->glyphs[l], sf->hasvmetrics);
- }
- lua_rawset(L,-3);
- }
- }
- if ((l+1)<sf->glyphcnt) {
- for (k=(l+1);k<sf->glyphcnt;k++) {
- lua_pushnumber(L,k);
- lua_createtable(L,0,12);
- if (sf->glyphs[k]) {
- handle_splinechar(L,sf->glyphs[k], sf->hasvmetrics);
- }
- lua_rawset(L,-3);
- }
- }
- lua_setfield(L,-2,"glyphs");
-
- /* dump_intfield(L,"changed", sf->changed); */
- dump_intfield(L,"hasvmetrics", sf->hasvmetrics);
- dump_intfield(L,"onlybitmaps", sf->onlybitmaps);
- dump_intfield(L,"serifcheck", sf->serifcheck);
- dump_intfield(L,"isserif", sf->isserif);
- dump_intfield(L,"issans", sf->issans);
- dump_intfield(L,"encodingchanged", sf->encodingchanged);
- dump_intfield(L,"strokedfont", sf->strokedfont);
- dump_intfield(L,"use_typo_metrics", sf->use_typo_metrics);
- dump_intfield(L,"weight_width_slope_only", sf->weight_width_slope_only);
- dump_intfield(L,"head_optimized_for_cleartype",sf->head_optimized_for_cleartype);
-
- dump_enumfield(L,"uni_interp", (sf->uni_interp+1), uni_interp_enum);
-
- if (sf->map != NULL ) {
- lua_newtable(L);
- handle_encmap(L,sf->map, l);
- lua_setfield(L,-2,"map");
- }
+ lua_setfield(L, -2, "subfonts");
+ }
- dump_stringfield(L,"origname", sf->origname); /* new */
+ dump_stringfield(L, "comments", sf->comments);
+ dump_stringfield(L, "fontlog", sf->fontlog);
- if (sf->private != NULL) {
- lua_newtable(L);
- handle_psdict(L, sf->private);
- lua_setfield(L,-2,"private");
- }
-
- dump_stringfield(L,"xuid", sf->xuid);
-
- lua_createtable(L,0,40);
- handle_pfminfo(L,sf->pfminfo);
- lua_setfield(L,-2,"pfminfo");
-
- if (sf->names != NULL) {
- lua_newtable(L);
- handle_ttflangname(L,sf->names);
- lua_setfield(L,-2,"names");
- }
-
- lua_createtable(L,0,4);
- dump_stringfield(L,"registry", sf->cidregistry);
- dump_stringfield(L,"ordering", sf->ordering);
- dump_intfield (L,"version", sf->cidversion);
- dump_intfield (L,"supplement", sf->supplement);
- lua_setfield(L,-2,"cidinfo");
-
- /* SplineFont *cidmaster */ /* parent in a subfont */
- if (sf->subfontcnt>0) {
- lua_createtable(L,sf->subfontcnt,0);
- for (k=0;k<sf->subfontcnt;k++) {
- lua_checkstack(L,10);
- lua_newtable(L);
- handle_splinefont(L,sf->subfonts[k]);
- lua_rawseti(L,-2,(k+1));
- }
- lua_setfield(L,-2,"subfonts");
- }
-
- dump_stringfield(L,"comments", sf->comments);
- dump_stringfield(L,"fontlog", sf->fontlog);
-
- if (sf->cvt_names != NULL) {
- lua_newtable(L);
- for (k=0; sf->cvt_names[k]!=END_CVT_NAMES; ++k) {
- lua_pushstring(L, sf->cvt_names[k]);
- lua_rawseti(L,-2,(k+1));
+ if (sf->cvt_names != NULL) {
+ lua_newtable(L);
+ for (k = 0; sf->cvt_names[k] != END_CVT_NAMES; ++k) {
+ lua_pushstring(L, sf->cvt_names[k]);
+ lua_rawseti(L, -2, (k + 1));
+ }
+ lua_setfield(L, -2, "cvt_names");
}
- lua_setfield(L,-2,"cvt_names");
- }
- if (sf->ttf_tables != NULL) {
- lua_newtable(L);
- handle_ttf_table(L,sf->ttf_tables);
- lua_setfield(L,-2,"ttf_tables");
- }
+ if (sf->ttf_tables != NULL) {
+ lua_newtable(L);
+ handle_ttf_table(L, sf->ttf_tables);
+ lua_setfield(L, -2, "ttf_tables");
+ }
- if (sf->ttf_tab_saved != NULL) {
- lua_newtable(L);
- handle_ttf_table(L,sf->ttf_tab_saved);
- lua_setfield(L,-2,"ttf_tab_saved");
- }
+ if (sf->ttf_tab_saved != NULL) {
+ lua_newtable(L);
+ handle_ttf_table(L, sf->ttf_tab_saved);
+ lua_setfield(L, -2, "ttf_tab_saved");
+ }
- if (sf->texdata.type != tex_unset) {
- lua_newtable(L);
- dump_enumfield(L,"type", sf->texdata.type, tex_type_enum);
- lua_newtable(L);
- for (k=0;k<22;k++) {
- lua_pushnumber(L,k);
- lua_pushnumber(L,sf->texdata.params[k]);
- lua_rawset(L,-3);
- }
- lua_setfield(L,-2,"params");
- lua_setfield(L,-2,"texdata");
- }
- if (sf->anchor != NULL) {
- lua_newtable(L);
- handle_anchorclass(L,sf->anchor);
- lua_setfield(L,-2,"anchor_classes");
- }
- if (sf->kerns != NULL) {
- lua_newtable(L);
- handle_kernclass(L,sf->kerns);
- lua_setfield(L,-2,"kerns");
- }
- if (sf->vkerns != NULL) {
- lua_newtable(L);
- handle_kernclass(L,sf->vkerns);
- lua_setfield(L,-2,"vkerns");
- }
- if (sf->gsub_lookups != NULL) {
- lua_newtable(L);
- handle_lookup(L,sf->gsub_lookups);
- lua_setfield(L,-2,"gsub");
- }
- if (sf->gpos_lookups != NULL) {
- lua_newtable(L);
- handle_lookup(L,sf->gpos_lookups);
- lua_setfield(L,-2,"gpos");
- }
+ if (sf->texdata.type != tex_unset) {
+ lua_newtable(L);
+ dump_enumfield(L, "type", sf->texdata.type, tex_type_enum);
+ lua_newtable(L);
+ for (k = 0; k < 22; k++) {
+ lua_pushnumber(L, k);
+ lua_pushnumber(L, sf->texdata.params[k]);
+ lua_rawset(L, -3);
+ }
+ lua_setfield(L, -2, "params");
+ lua_setfield(L, -2, "texdata");
+ }
+ if (sf->anchor != NULL) {
+ lua_newtable(L);
+ handle_anchorclass(L, sf->anchor);
+ lua_setfield(L, -2, "anchor_classes");
+ }
+ if (sf->kerns != NULL) {
+ lua_newtable(L);
+ handle_kernclass(L, sf->kerns);
+ lua_setfield(L, -2, "kerns");
+ }
+ if (sf->vkerns != NULL) {
+ lua_newtable(L);
+ handle_kernclass(L, sf->vkerns);
+ lua_setfield(L, -2, "vkerns");
+ }
+ if (sf->gsub_lookups != NULL) {
+ lua_newtable(L);
+ handle_lookup(L, sf->gsub_lookups, sf);
+ lua_setfield(L, -2, "gsub");
+ }
+ if (sf->gpos_lookups != NULL) {
+ lua_newtable(L);
+ handle_lookup(L, sf->gpos_lookups, sf);
+ lua_setfield(L, -2, "gpos");
+ }
- if (sf->sm != NULL) {
- lua_newtable(L);
- handle_generic_asm(L,sf->sm);
- lua_setfield(L,-2,"sm");
- }
- if (sf->features != NULL) {
- lua_newtable(L);
- handle_macfeat(L,sf->features);
- lua_setfield(L,-2,"features");
- }
- if (sf->mm != NULL) {
- lua_newtable(L);
- handle_mmset (L,sf->mm);
- lua_setfield(L,-2,"mm");
- }
- dump_stringfield(L,"chosenname", sf->chosenname);
-
- dump_intfield(L,"macstyle", sf->macstyle);
- dump_stringfield(L,"fondname", sf->fondname);
-
- dump_intfield(L,"design_size", sf->design_size);
- dump_intfield(L,"fontstyle_id", sf->fontstyle_id);
-
- if (sf->fontstyle_name != NULL) {
- lua_newtable(L);
- handle_otfname(L,sf->fontstyle_name);
- lua_setfield(L,-2,"fontstyle_name");
- }
-
- dump_intfield(L,"design_range_bottom",sf->design_range_bottom);
- dump_intfield(L,"design_range_top", sf->design_range_top);
- dump_floatfield(L,"strokewidth", sf->strokewidth);
-
- if (sf->mark_class_cnt>0) {
- lua_newtable(L);
- for ( k=0; k<sf->mark_class_cnt; ++k ) {
- lua_pushnumber(L,(k+1));
- lua_pushstring(L,sf->mark_classes[k]);
- lua_rawset(L,-3);
+ if (sf->sm != NULL) {
+ lua_newtable(L);
+ handle_generic_asm(L, sf->sm);
+ lua_setfield(L, -2, "sm");
+ }
+ if (sf->features != NULL) {
+ lua_newtable(L);
+ handle_macfeat(L, sf->features);
+ lua_setfield(L, -2, "features");
}
- lua_setfield(L,-1,"mark_classes");
+ if (sf->mm != NULL) {
+ lua_newtable(L);
+ handle_mmset(L, sf->mm);
+ lua_setfield(L, -2, "mm");
+ }
+ dump_stringfield(L, "chosenname", sf->chosenname);
- lua_newtable(L);
- for ( k=0; k<sf->mark_class_cnt; ++k ) {
- lua_pushnumber(L,(k+1));
- lua_pushstring(L,sf->mark_class_names[k]);
- lua_rawset(L,-3);
+ dump_intfield(L, "macstyle", sf->macstyle);
+ dump_stringfield(L, "fondname", sf->fondname);
+
+ dump_intfield(L, "design_size", sf->design_size);
+ dump_intfield(L, "fontstyle_id", sf->fontstyle_id);
+
+ if (sf->fontstyle_name != NULL) {
+ lua_newtable(L);
+ handle_otfname(L, sf->fontstyle_name);
+ lua_setfield(L, -2, "fontstyle_name");
}
- lua_setfield(L,-1,"mark_class_names");
- }
-
- dump_intfield(L,"creationtime", sf->creationtime);
- dump_intfield(L,"modificationtime", sf->modificationtime);
- dump_intfield(L,"os2_version", sf->os2_version);
- dump_intfield(L,"sfd_version", sf->sfd_version);
+ dump_intfield(L, "design_range_bottom", sf->design_range_bottom);
+ dump_intfield(L, "design_range_top", sf->design_range_top);
+ dump_floatfield(L, "strokewidth", sf->strokewidth);
- if (sf->MATH != NULL) {
- lua_newtable(L);
- handle_MATH(L, sf->MATH);
- lua_setfield(L,-2,"math");
- }
-
- if (sf->loadvalidation_state != 0) {
- int val, st;
- lua_newtable(L);
- val = 1;
- st = sf->loadvalidation_state;
- if (st & lvs_bad_ps_fontname) {
- lua_pushliteral(L, "bad_ps_fontname"); lua_rawseti(L,-2,val++);
+ if (sf->mark_class_cnt > 0) {
+ lua_newtable(L);
+ for (k = 0; k < sf->mark_class_cnt; k++) {
+ if (sf->mark_class_names[k] != NULL) {
+ lua_pushstring(L, sf->mark_class_names[k]);
+ lua_pushstring(L, sf->mark_classes[k]);
+ lua_rawset(L, -3);
+ }
+ }
+ lua_setfield(L, -2, "mark_classes");
}
- if (st & lvs_bad_glyph_table) {
- lua_pushliteral(L, "bad_glyph_table"); lua_rawseti(L,-2,val++);
+
+ dump_intfield(L, "creationtime", sf->creationtime);
+ dump_intfield(L, "modificationtime", sf->modificationtime);
+
+ dump_intfield(L, "os2_version", sf->os2_version);
+ dump_intfield(L, "sfd_version", sf->sfd_version);
+
+ if (sf->MATH != NULL) {
+ lua_newtable(L);
+ handle_MATH(L, sf->MATH);
+ lua_setfield(L, -2, "math");
+ }
+
+ if (sf->loadvalidation_state != 0) {
+ int val, st;
+ lua_newtable(L);
+ val = 1;
+ st = sf->loadvalidation_state;
+ if (st & lvs_bad_ps_fontname) {
+ lua_pushliteral(L, "bad_ps_fontname");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_glyph_table) {
+ lua_pushliteral(L, "bad_glyph_table");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_cff_table) {
+ lua_pushliteral(L, "bad_cff_table");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_metrics_table) {
+ lua_pushliteral(L, "bad_metrics_table");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_cmap_table) {
+ lua_pushliteral(L, "bad_cmap_table");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_bitmaps_table) {
+ lua_pushliteral(L, "bad_bitmaps_table");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_gx_table) {
+ lua_pushliteral(L, "bad_gx_table");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_ot_table) {
+ lua_pushliteral(L, "bad_ot_table");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_os2_version) {
+ lua_pushliteral(L, "bad_os2_version");
+ lua_rawseti(L, -2, val++);
+ }
+ if (st & lvs_bad_sfnt_header) {
+ lua_pushliteral(L, "bad_sfnt_header");
+ lua_rawseti(L, -2, val++);
+ }
+ lua_setfield(L, -2, "validation_state");
}
- if (st & lvs_bad_cff_table) {
- lua_pushliteral(L, "bad_cff_table"); lua_rawseti(L,-2,val++);
+
+ if (sf->horiz_base != NULL) {
+ lua_newtable(L);
+ handle_base(L, sf->horiz_base);
+ lua_setfield(L, -2, "horiz_base");
}
- if (st & lvs_bad_metrics_table) {
- lua_pushliteral(L, "bad_metrics_table"); lua_rawseti(L,-2,val++);
+ if (sf->vert_base != NULL) {
+ lua_newtable(L);
+ handle_base(L, sf->vert_base);
+ lua_setfield(L, -2, "vert_base");
}
- if (st & lvs_bad_cmap_table) {
- lua_pushliteral(L, "bad_cmap_table"); lua_rawseti(L,-2,val++);
+ dump_intfield(L, "extrema_bound", sf->extrema_bound);
+}
+
+int ff_make_table(lua_State * L)
+{
+ SplineFont *sf;
+ sf = *(check_isfont(L, 1));
+ if (sf == NULL) {
+ lua_pushboolean(L, 0);
+ } else {
+ lua_createtable(L, 0, 60);
+ handle_splinefont(L, sf);
}
- if (st & lvs_bad_bitmaps_table) {
- lua_pushliteral(L, "bad_bitmaps_table"); lua_rawseti(L,-2,val++);
+ return 1;
+}
+
+void do_ff_info(lua_State * L, SplineFont * sf)
+{
+ lua_newtable(L);
+ dump_stringfield(L, "familyname", sf->familyname);
+ dump_stringfield(L, "fontname", sf->fontname);
+ dump_stringfield(L, "fullname", sf->fullname);
+ dump_intfield(L, "italicangle", sf->italicangle);
+ dump_stringfield(L, "version", sf->version);
+ dump_stringfield(L, "weight", sf->weight);
+
+}
+
+static int ff_info(lua_State * L)
+{
+ SplineFont *sf;
+ FILE *l;
+ int i;
+ const char *fontname;
+ int openflags = 1;
+ fontname = luaL_checkstring(L, 1);
+ if (!strlen(fontname)) {
+ lua_pushnil(L);
+ lua_pushfstring(L, "font loading failed: empty string given\n",
+ fontname);
+ return 2;
}
- if (st & lvs_bad_gx_table) {
- lua_pushliteral(L, "bad_gx_table"); lua_rawseti(L,-2,val++);
+ /* test fontname for existance */
+ if ((l = fopen(fontname, "r"))) {
+ fclose(l);
+ } else {
+ lua_pushnil(L);
+ lua_pushfstring(L, "font loading failed for %s (read error)\n",
+ fontname);
+ return 2;
}
- if (st & lvs_bad_ot_table) {
- lua_pushliteral(L, "bad_ot_table"); lua_rawseti(L,-2,val++);
+ sf = ReadSplineFontInfo((char *) fontname, openflags);
+ if (sf == NULL) {
+ lua_pushnil(L);
+ lua_pushfstring(L, "font loading failed for %s\n", fontname);
+ return 2;
+ } else {
+ if (sf->next != NULL) {
+ SplineFont *sf_next;
+ i = 1;
+ lua_newtable(L);
+ while (sf) {
+ do_ff_info(L, sf);
+ lua_rawseti(L, -2, i);
+ i++;
+ sf_next = sf->next;
+ EncMapFree(sf->map);
+ SplineFontFree(sf);
+ sf = sf_next;
+ }
+ } else {
+ do_ff_info(L, sf);
+ EncMapFree(sf->map);
+ SplineFontFree(sf);
+ }
}
- if (st & lvs_bad_os2_version) {
- lua_pushliteral(L, "bad_os2_version"); lua_rawseti(L,-2,val++);
+ return 1;
+}
+
+static void ff_do_cff(SplineFont * sf, char *filename, unsigned char **buf,
+ int *bufsiz)
+{
+ FILE *f;
+ int32 *bsizes = NULL;
+ int flags = ps_flag_nocffsugar + ps_flag_nohints;
+ EncMap *map;
+
+ map = EncMap1to1(sf->glyphcnt);
+
+ if (WriteTTFFont
+ (filename, sf, ff_cff, bsizes, bf_none, flags, map, ly_fore)) {
+ /* success */
+ f = fopen(filename, "rb");
+ readbinfile(f, buf, bufsiz);
+ /*fprintf(stdout,"\n%s => CFF, size: %d\n", sf->filename, *bufsiz); */
+ fclose(f);
+ return;
}
- if (st & lvs_bad_sfnt_header) {
- lua_pushliteral(L, "bad_sfnt_header"); lua_rawseti(L,-2,val++);
+ /* errors */
+ fprintf(stdout, "\n%s => CFF, failed\n", sf->filename);
+
+}
+
+/* exported for writecff.c */
+
+int ff_createcff(char *file, unsigned char **buf, int *bufsiz)
+{
+ SplineFont *sf;
+ int k;
+ char s[] = "tempfile.cff";
+ int openflags = 1;
+ int notdefpos = 0;
+ sf = ReadSplineFont(file, openflags);
+ if (sf) {
+ /* this is not the best way. nicer to have no temp file at all */
+ ff_do_cff(sf, s, buf, bufsiz);
+ for (k = 0; k < sf->glyphcnt; k++) {
+ if (sf->glyphs[k] && strcmp(sf->glyphs[k]->name, ".notdef") == 0) {
+ notdefpos = k;
+ break;
+ }
+ }
+ remove(s);
+ EncMapFree(sf->map);
+ SplineFontFree(sf);
}
- lua_setfield(L,-2,"validation_state");
- }
+ return notdefpos;
+}
- if (sf->horiz_base != NULL) {
- lua_newtable(L);
- handle_base(L, sf->horiz_base);
- lua_setfield(L,-2,"horiz_base");
- }
- if (sf->vert_base != NULL) {
- lua_newtable(L);
- handle_base(L, sf->vert_base);
- lua_setfield(L,-2,"vert_base");
- }
- dump_intfield(L,"extrema_bound", sf->extrema_bound);
-}
-
-int
-ff_make_table (lua_State *L) {
- SplineFont *sf;
- sf = *(check_isfont(L,1));
- if (sf == NULL) {
- lua_pushboolean(L,0);
- } else {
- lua_createtable(L,0,60);
- handle_splinefont(L,sf);
- }
- return 1;
-}
-
-void do_ff_info (lua_State *L, SplineFont *sf) {
- lua_newtable(L);
- dump_stringfield(L,"familyname", sf->familyname);
- dump_stringfield(L,"fontname", sf->fontname);
- dump_stringfield(L,"fullname", sf->fullname);
- dump_intfield (L,"italicangle", sf->italicangle);
- dump_stringfield(L,"version", sf->version);
- dump_stringfield(L,"weight", sf->weight);
-
-}
-
-static int
-ff_info (lua_State *L) {
- SplineFont *sf;
- FILE *l;
- int i;
- const char *fontname;
- int openflags = 1;
- fontname = luaL_checkstring(L,1);
- if (!strlen(fontname)) {
- lua_pushfstring(L,"font loading failed: empty string given\n", fontname);
- lua_error(L);
- return 1;
- }
- /* test fontname for existance */
- if ((l = fopen(fontname,"r"))) {
- fclose(l);
- } else {
- lua_pushfstring(L,"font loading failed for %s (read error)\n", fontname);
- lua_error(L);
- }
- sf = ReadSplineFontInfo((char *)fontname,openflags);
- if (sf==NULL) {
- lua_pushfstring(L,"font loading failed for %s\n", fontname);
- lua_error(L);
- } else {
- if (sf->next != NULL) {
- SplineFont *sf_next;
- i = 1;
- lua_newtable(L);
- while (sf) {
- do_ff_info(L, sf);
- lua_rawseti(L,-2,i);
- i++;
- sf_next = sf->next;
- SplineFontFree(sf);
- sf = sf_next;
- }
- } else {
- do_ff_info(L, sf);
- SplineFontFree(sf);
- }
- }
- return 1;
-}
-
-static void ff_do_cff (SplineFont *sf, char *filename, unsigned char **buf, int *bufsiz) {
- FILE *f;
- int32 *bsizes = NULL;
- int flags = ps_flag_nocffsugar + ps_flag_nohints;
- EncMap *map;
-
- map = EncMap1to1(sf->glyphcnt);
-
- if(WriteTTFFont(filename, sf, ff_cff, bsizes, bf_none, flags, map, ly_fore)) {
- /* success */
- f = fopen(filename,"rb");
- readbinfile(f , buf, bufsiz);
- /*fprintf(stdout,"\n%s => CFF, size: %d\n", sf->filename, *bufsiz);*/
- fclose(f);
- return;
- }
- /* errors */
- fprintf(stdout,"\n%s => CFF, failed\n", sf->filename);
-
-}
-
-
-#include "luafflib.h"
-
-int ff_createcff (char *file, unsigned char **buf, int *bufsiz) {
- SplineFont *sf;
- int k ;
- char s[] = "tempfile.cff";
- int openflags = 1;
- int notdefpos = 0;
- sf = ReadSplineFont(file,openflags);
- if (sf) {
- /* this is not the best way. nicer to have no temp file at all */
- ff_do_cff(sf, s, buf,bufsiz);
- for (k=0;k<sf->glyphcnt;k++) {
- if (sf->glyphs[k] && strcmp(sf->glyphs[k]->name,".notdef")==0) {
- notdefpos=k;
- break;
- }
- }
- remove(s);
- SplineFontFree(sf);
- }
- return notdefpos;
-}
-
-int ff_get_ttc_index(char *ffname, char*psname) {
- SplineFont *sf;
- int i = 0;
- int openflags = 1;
- int index = 0;
-
- sf = ReadSplineFontInfo(ffname,openflags);
- if (sf==NULL) {
- perror("font loading failed unexpectedly\n");
- exit(EXIT_FAILURE);
- }
- while (sf != NULL) {
- if (strcmp(sf->fontname,psname)==0) {
- index = i;
- break;
- }
- i++;
- sf = sf->next;
- }
- return index;
+int ff_get_ttc_index(char *ffname, char *psname)
+{
+ SplineFont *sf;
+ int i = 0;
+ int openflags = 1;
+ int index = -1;
+
+ sf = ReadSplineFontInfo((char *) ffname, openflags);
+ if (sf == NULL) {
+ perror("font loading failed unexpectedly\n");
+ exit(EXIT_FAILURE);
+ }
+ while (sf != NULL) {
+ if (strcmp(sf->fontname, psname) == 0) {
+ index = i;
+ break;
+ }
+ i++;
+ sf = sf->next;
+ }
+ return index;
}
static int warning_given = 0;
-static int
-ffold_info (lua_State *L) {
- if (warning_given<5) {
- fprintf (stderr, "Warning: The 'fontforge' table has been renamed to 'fontloader'.\n");
- fprintf (stderr, " Please update your source file(s) accordingly.\n");
- warning_given ++;
+static int ffold_info(lua_State * L)
+{
+ if (warning_given < 5) {
+ fprintf(stderr,
+ "Warning: The 'fontforge' table has been renamed to 'fontloader'.\n");
+ fprintf(stderr, " Please update your source file(s) accordingly.\n");
+ warning_given++;
}
return ff_info(L);
}
-static int
-ffold_open (lua_State *L) {
- fprintf (stderr, "Warning: The 'fontforge' table has been renamed to 'fontloader'.\n");
- fprintf (stderr, " Please update your source file(s) accordingly.\n");
+static int ffold_open(lua_State * L)
+{
+ fprintf(stderr,
+ "Warning: The 'fontforge' table has been renamed to 'fontloader'.\n");
+ fprintf(stderr, " Please update your source file(s) accordingly.\n");
return ff_open(L);
}
static struct luaL_reg fflib[] = {
- {"open", ffold_open},
- {"info", ffold_info},
- {"close", ff_close},
- {"apply_afmfile", ff_apply_afmfile},
- {"apply_featurefile", ff_apply_featurefile},
- {"to_table", ff_make_table},
- {NULL, NULL}
+ {"open", ffold_open},
+ {"info", ffold_info},
+ {"close", ff_close},
+ {"apply_afmfile", ff_apply_afmfile},
+ {"apply_featurefile", ff_apply_featurefile},
+ {"to_table", ff_make_table},
+ {NULL, NULL}
};
static struct luaL_reg fllib[] = {
- {"open", ff_open},
- {"info", ff_info},
- {"close", ff_close},
- {"apply_afmfile", ff_apply_afmfile},
- {"apply_featurefile", ff_apply_featurefile},
- {"to_table", ff_make_table},
- {NULL, NULL}
+ {"open", ff_open},
+ {"info", ff_info},
+ {"close", ff_close},
+ {"apply_afmfile", ff_apply_afmfile},
+ {"apply_featurefile", ff_apply_featurefile},
+ {"to_table", ff_make_table},
+ {NULL, NULL}
};
-static const struct luaL_reg fflib_m [] = {
- {"__gc", ff_close }, /* doesnt work yet! */
- {NULL, NULL} /* sentinel */
+static const struct luaL_reg fflib_m[] = {
+ {"__gc", ff_close}, /* doesnt work yet! */
+ {NULL, NULL} /* sentinel */
};
extern char *SaveTablesPref;
-extern char *coord_sep ;
-
-int luaopen_ff (lua_State *L) {
- InitSimpleStuff();
- setlocale(LC_ALL,"C"); /* undo whatever InitSimpleStuff has caused */
- coord_sep = ",";
- FF_SetUiInterface(&luaui_interface);
- default_encoding = FindOrMakeEncoding("ISO8859-1");
- SaveTablesPref = "VORG,JSTF,acnt,bsln,fdsc,fmtx,hsty,just,trak,Zapf,LINO";
- luaL_newmetatable(L,FONT_METATABLE);
- luaL_register(L, NULL, fflib_m);
- luaL_openlib(L, "fontforge", fflib, 0);
- luaL_openlib(L, "fontloader", fllib, 0);
- return 1;
+extern char *coord_sep;
+
+int luaopen_ff(lua_State * L)
+{
+ InitSimpleStuff();
+ setlocale(LC_ALL, "C"); /* undo whatever InitSimpleStuff has caused */
+ coord_sep = ",";
+ FF_SetUiInterface(&luaui_interface);
+ default_encoding = FindOrMakeEncoding("ISO8859-1");
+ SaveTablesPref = "VORG,JSTF,acnt,bsln,fdsc,fmtx,hsty,just,trak,Zapf,LINO";
+ luaL_newmetatable(L, FONT_METATABLE);
+ luaL_register(L, NULL, fflib_m);
+ luaL_openlib(L, "fontforge", fflib, 0);
+ luaL_openlib(L, "fontloader", fllib, 0);
+ return 1;
}
-
diff --git a/Build/source/texk/web2c/luatexdir/luamd5/md5.h b/Build/source/texk/web2c/luatexdir/luamd5/luamd5.h
index 80d43f72687..c0470c6439d 100644
--- a/Build/source/texk/web2c/luatexdir/luamd5/md5.h
+++ b/Build/source/texk/web2c/luatexdir/luamd5/luamd5.h
@@ -5,8 +5,8 @@
*/
-#ifndef md5_h
-#define md5_h
+#ifndef luamd5_h
+#define luamd5_h
#include <lua.h>
diff --git a/Build/source/texk/web2c/luatexdir/luamd5/md5.c b/Build/source/texk/web2c/luatexdir/luamd5/md5.c
index 7e630bfc46b..685880bedf5 100644
--- a/Build/source/texk/web2c/luatexdir/luamd5/md5.c
+++ b/Build/source/texk/web2c/luatexdir/luamd5/md5.c
@@ -6,13 +6,14 @@
#include <string.h>
+#include <stdint.h>
-#include "md5.h"
+#include "luamd5.h"
#define WORD 32
#define MASK 0xFFFFFFFF
-typedef unsigned long WORD32;
+typedef uint32_t WORD32;
/**
diff --git a/Build/source/texk/web2c/luatexdir/luamd5/md5_lua.c b/Build/source/texk/web2c/luatexdir/luamd5/md5_lua.c
new file mode 100644
index 00000000000..5caebaececd
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luamd5/md5_lua.c
@@ -0,0 +1,38 @@
+/*
+ * This file is auto-generated by "lua2c md5.lua md5_lua"
+ */
+
+#include "lua.h"
+#include "lauxlib.h"
+
+int luatex_md5_lua_open (lua_State *L) {
+ static unsigned char B[] = {
+ 45, 45, 32,109,100, 53, 46,108,117, 97, 10, 45, 45, 32, 40,121,111,117, 32,115,
+104,111,117,108,100, 32,112,117,116, 32,116,104,105,115, 32,102,105,108,101, 32,
+105,110, 32, 97,110,121, 32,100,105,114,101, 99,116,111,114,121, 32,111,102, 32,
+121,111,117,114, 32, 76, 85, 65, 95, 80, 65, 84, 72, 41, 10, 10, 10, 45, 45, 32,
+ 99,104, 97,110,103,101, 32,116,104,101, 32,110,101,120,116, 32,108,105,110,101,
+ 32,116,111, 32,112,111,105,110,116, 32,116,111, 32,116,104,101, 32,109,100, 53,
+ 32,100,121,110, 97,109,105, 99, 32,108,105, 98,114, 97,114,121, 10, 10, 45, 45,
+ 32,108,111, 99, 97,108, 32,112, 97,116,104, 32, 61, 32, 34, 47,117,115,114, 47,
+108,111, 99, 97,108, 47,108,117, 97, 47,108,105, 98, 47,108,105, 98,109,100, 53,
+ 46,115,111, 34, 10, 45, 45,108,111, 99, 97,108, 32,112, 97,116,104, 32, 61, 32,
+ 34, 46, 47,108,105, 98,109,100, 53, 46,115,111, 34, 10, 10, 45, 45, 97,115,115,
+101,114,116, 40,108,111, 97,100,108,105, 98, 40,112, 97,116,104, 44, 32, 34,108,
+117, 97,111,112,101,110, 95,109,100, 53, 34, 41, 41, 40, 41, 10, 10, 10, 45, 45,
+ 32, 82,101,116,117,114,110,115, 32,116,104,101, 32,109,100, 53, 32,104, 97,115,
+104, 32,118, 97,108,117,101, 32, 97,115, 32, 97, 32,115,116,114,105,110,103, 32,
+111,102, 32,104,101,120, 97,100,101, 99,105,109, 97,108, 32,100,105,103,105,116,
+115, 10, 10,102,117,110, 99,116,105,111,110, 32,109,100, 53, 46,115,117,109,104,
+101,120, 97, 32, 40,107, 41, 10, 32, 32,107, 32, 61, 32,109,100, 53, 46,115,117,
+109, 40,107, 41, 10, 32, 32,114,101,116,117,114,110, 32, 40,115,116,114,105,110,
+103, 46,103,115,117, 98, 40,107, 44, 32, 34, 46, 34, 44, 32,102,117,110, 99,116,
+105,111,110, 32, 40, 99, 41, 10, 32, 32, 32, 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, 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, 32, 32, 32, 32, 32,101,110,100, 41, 41, 10,101,
+110,100, 10, 10,114,101,116,117,114,110, 32,109,100, 53, 10,
+ 0 };
+ return luaL_dostring(L, (const char*)B);
+} /* end of embedded lua code */
+
diff --git a/Build/source/texk/web2c/luatexdir/luamd5/md5lib.c b/Build/source/texk/web2c/luatexdir/luamd5/md5lib.c
index 7c72a16fcb6..de213d878a2 100644
--- a/Build/source/texk/web2c/luatexdir/luamd5/md5lib.c
+++ b/Build/source/texk/web2c/luatexdir/luamd5/md5lib.c
@@ -13,7 +13,7 @@
#include <lua.h>
#include <lauxlib.h>
-#include "md5.h"
+#include "luamd5.h"
/**
diff --git a/Build/source/texk/web2c/luatexdir/luatangle.ch b/Build/source/texk/web2c/luatexdir/luatangle.ch
deleted file mode 100644
index 9c5af9db75a..00000000000
--- a/Build/source/texk/web2c/luatexdir/luatangle.ch
+++ /dev/null
@@ -1,508 +0,0 @@
-% luatangle.ch: web2c changes to file tangle.ch
-% $Id$
-%
-% This file is part of LuaTeX.
-%
-% Copyright (c) 1994--1998 John Plaice and Yannis Haralambous
-% Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
-% applies only to the changes to the original tangle.ch.
-%
-% luatangle.ch for C compilation with web2c.
-%
-% 10/9/82 (HT) Original version
-% 11/29 (HT) New version, with conversion to lowercase handled properly
-% Also, new control sequence:
-% @=...text...@> Put ...text... verbatim on a line
-% by itself in the Pascal output.
-% (argument must fit on one line)
-% This control sequence facilitates putting #include "gcons.h"
-% (for example) in files meant for the pc compiler.
-% Also, changed command line usage, so that the absence of a
-% change file implies no change file, rather than one with the
-% same name as the web file, with .ch at the end.
-% 1/15/83 (HT) Changed to work with version 1.2, which incorporates the
-% above change (though unbundling the output line breaking),
-% so mainly had to remove stuff.
-% 2/17 (HT) Fixed bug that caused 0-9 in identifiers to be converted to
-% Q-Y on output.
-% 3/18 (HT) Brought up to work with Version 1.5. Added -r command line
-% flag to cause a .rpl file to be written with all the lines
-% of the .web file that were replaced because of the .ch file
-% (useful for comparing with previous .rpl files, to see if a
-% change file will still work with a new version of a .web file)
-% Also, made it write a newline just before exit.
-% 4/12 (PC) Merged with Pavel's version, including adding a call to exit()
-% at the end depending upon the value of history.
-% 4/16 (PC) Brought up to date with version 1.5 released April, 1983.
-% 6/28 (HWT) Brought up to date with version 1.7 released June, 1983.
-% With new change file format, the -r option is now unnecessary.
-% 7/17 (HWT) Brought up to date with version 2.0 released July, 1983.
-% 12/18/83 (ETM) Brought up to date with version 2.5 released November, 1983.
-% 11/07/84 (ETM) Brought up to date with version 2.6.
-% 12/15/85 (ETM) Brought up to date with version 2.8.
-% 03/07/88 (ETM) Converted for use with WEB2C
-% 01/02/89 (PAM) Cosmetic upgrade to version 2.9
-% 11/30/89 (KB) Version 4.
-% (more recent changes in the ChangeLog)
-
-@x [0] Print only changes.
-\pageno=\contentspagenumber \advance\pageno by 1
-@y
-\pageno=\contentspagenumber \advance\pageno by 1
-\let\maybe=\iffalse
-\def\title{TANGLE changes for C}
-@z
-
-@x [2] Eliminate the |end_of_TANGLE| label.
-@d end_of_TANGLE = 9999 {go here to wrap it up}
-
-@y
-@z
-@x
-label end_of_TANGLE; {go here to finish}
-@y
-@z
-
-@x [?] Define and call parse_arguments.
-procedure initialize;
- var @<Local variables for initialization@>@/
- begin @<Set initial values@>@/
-@y
-@<Define |parse_arguments|@>
-procedure initialize;
- var @<Local variables for initialization@>@/
- begin
- kpse_set_program_name (argv[0], nil);
- parse_arguments;
- @<Set initial values@>@/
-@z
-
-@x [8] Constants: increase id lengths, for TeX--XeT and tex2pdf.
-@!buf_size=100; {maximum length of input line}
-@y
-@!buf_size=3000; {maximum length of input line}
-@z
-@x
-@!max_names=10239; {number of identifiers, strings, module names;
- must be less than 10240}
-@!max_texts=10239; {number of replacement texts, must be less than 10240}
-@y
-@!max_names=10239; {number of identifiers, strings, module names;
- must be less than 10240}
-@!max_texts=10239; {number of replacement texts, must be less than 10240}
-@z
-
-@x
-@!stack_size=50; {number of simultaneous levels of macro expansion}
-@!max_id_length=12; {long identifiers are chopped to this length, which must
- not exceed |line_length|}
-@!unambig_length=7; {identifiers must be unique if chopped to this length}
- {note that 7 is more strict than \PASCAL's 8, but this can be varied}
-@y
-@!stack_size=100; {number of simultaneous levels of macro expansion}
-@!max_id_length=64; {long identifiers are chopped to this length, which must
- not exceed |line_length|}
-@!unambig_length=64; {identifiers must be unique if chopped to this length}
-@z
-
-% [??] The text_char type is used as an array index into xord. The
-% default type `char' produces signed integers, which are bad array
-% indices in C.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-@x
-@d text_char == char {the data type of characters in text files}
-@y
-@d text_char == ASCII_code {the data type of characters in text files}
-@z
-
-@x [17] enable maximum character set
-for i:=1 to @'37 do xchr[i]:=' ';
-for i:=@'200 to @'377 do xchr[i]:=' ';
-@y
-for i:=1 to @'37 do xchr[i]:=chr(i);
-for i:=@'200 to @'377 do xchr[i]:=chr(i);
-@z
-
-@x [20] terminal output: use standard i/o
-@d print(#)==write(term_out,#) {`|print|' means write on the terminal}
-@y
-@d term_out==stdout
-@d print(#)==write(term_out,#) {`|print|' means write on the terminal}
-@z
-
-@x
-@<Globals...@>=
-@!term_out:text_file; {the terminal as an output file}
-@y
-@z
-
-@x [21] init terminal
-@ Different systems have different ways of specifying that the output on a
-certain file will appear on the user's terminal. Here is one way to do this
-on the \PASCAL\ system that was used in \.{TANGLE}'s initial development:
-@^system dependencies@>
-
-@<Set init...@>=
-rewrite(term_out,'TTY:'); {send |term_out| output to the terminal}
-@y
-@ Different systems have different ways of specifying that the output on a
-certain file will appear on the user's terminal.
-@^system dependencies@>
-
-@<Set init...@>=
- {Nothing need be done for C.}
-@z
-
-@x [22] flush terminal buffer
-@d update_terminal == break(term_out) {empty the terminal output buffer}
-@y
-@d update_terminal == fflush(term_out) {empty the terminal output buffer}
-@z
-
-@x [24] open input files
-begin reset(web_file); reset(change_file);
-@y
-begin web_file := kpse_open_file(web_name, kpse_web_format);
-if chg_name then change_file := kpse_open_file(chg_name, kpse_web_format);
-@z
-
-@x [26] Open output files (except for the pool file).
-rewrite(Pascal_file); rewrite(pool);
-@y
-rewrite (Pascal_file, pascal_name);
-@z
-
-@x [28] Fix f^.
- begin buffer[limit]:=xord[f^]; get(f);
- incr(limit);
- if buffer[limit-1]<>" " then final_limit:=limit;
- if limit=buf_size then
- begin while not eoln(f) do get(f);
-@y
- begin buffer[limit]:=xord[getc(f)];
- incr(limit);
- if buffer[limit-1]<>" " then final_limit:=limit;
- if limit=buf_size then
- begin while not eoln(f) do vgetc(f);
-@z
-
-@x [??] Fix `jump_out'.
-@d fatal_error(#)==begin new_line; print(#); error; mark_fatal; jump_out;
- end
-
-@<Error handling...@>=
-procedure jump_out;
-begin goto end_of_TANGLE;
-end;
-@y
-@d jump_out==uexit(1)
-@d fatal_error(#)==begin new_line; write(stderr, #);
- error; mark_fatal; uexit(1);
- end
-@z
-
-@x [38] Provide for a larger `byte_mem' and `tok_mem'. Extra capacity:
-@d ww=2 {we multiply the byte capacity by approximately this amount}
-@d zz=3 {we multiply the token capacity by approximately this amount}
-@y
-@d ww=3 {we multiply the byte capacity by approximately this amount}
-@d zz=5 {we multiply the token capacity by approximately this amount}
-@z
-
-@x [58] Case smashing options/strict checking.
- begin if buffer[i]<>"_" then
- begin if buffer[i]>="a" then chopped_id[s]:=buffer[i]-@'40
- else chopped_id[s]:=buffer[i];
-@y
- begin if (buffer[i]<>"_") or (allow_underlines) then
- begin chopped_id[s]:=buffer[i];
-@z
-
-@x [63] Case smashing options/strict checking.
- if c<>"_" then
- begin if c>="a" then c:=c-@'40; {merge lowercase with uppercase}
-@y
- if c<>"_" or (allow_underlines) then
- begin
-@z
-
-@x [64] Delayed pool file opening.
-@<Define and output a new string...@>=
-begin ilk[p]:=numeric; {strings are like numeric macros}
-if l-double_chars=2 then {this string is for a single character}
- equiv[p]:=buffer[id_first+1]+1073741824
-else begin equiv[p]:=string_ptr+1073741824;
- l:=l-double_chars-1;
-@y
-@<Define and output a new string...@>=
-begin ilk[p]:=numeric; {strings are like numeric macros}
-if l-double_chars=2 then {this string is for a single character}
- equiv[p]:=buffer[id_first+1]+1073741824
-else begin
- {Avoid creating empty pool files.}
- if string_ptr = 2097152 then begin
- {Change |".web"| to |".pool"| and use the current directory.}
- pool_name := basename_change_suffix (web_name, '.web', '.pool');
- rewrite (pool, pool_name);
- end;
- equiv[p]:=string_ptr+1073741824;
- l:=l-double_chars-1;
-@z
-
-@x [105] Accept DIV, div, MOD, and mod
- (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@|
- ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) ))or@|
-@^uppercase@>
-@y
- (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@|
- ((out_contrib[1]="d")and(out_contrib[2]="i")and(out_contrib[3]="v")) or@|
- ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) or@|
- ((out_contrib[1]="m")and(out_contrib[2]="o")and(out_contrib[3]="d")) ))or@|
-@z
-
-@x [110] lowercase ids
-@^uppercase@>
- if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and
- (out_buf[out_ptr-1]="V"))or @/
- ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and
- (out_buf[out_ptr-1]="D")) then@/ goto bad_case
-@y
- if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and
- (out_buf[out_ptr-1]="V"))or @/
- ((out_buf[out_ptr-3]="d")and(out_buf[out_ptr-2]="i")and
- (out_buf[out_ptr-1]="v"))or @/
- ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and
- (out_buf[out_ptr-1]="D"))or @/
- ((out_buf[out_ptr-3]="m")and(out_buf[out_ptr-2]="o")and
- (out_buf[out_ptr-1]="d")) then@/ goto bad_case
-@z
-
-@x [114] lowercase operators (`and', `or', etc.)
-and_sign: begin out_contrib[1]:="A"; out_contrib[2]:="N"; out_contrib[3]:="D";
-@^uppercase@>
- send_out(ident,3);
- end;
-not_sign: begin out_contrib[1]:="N"; out_contrib[2]:="O"; out_contrib[3]:="T";
- send_out(ident,3);
- end;
-set_element_sign: begin out_contrib[1]:="I"; out_contrib[2]:="N";
- send_out(ident,2);
- end;
-or_sign: begin out_contrib[1]:="O"; out_contrib[2]:="R"; send_out(ident,2);
-@y
-and_sign: begin out_contrib[1]:="a"; out_contrib[2]:="n"; out_contrib[3]:="d";
- send_out(ident,3);
- end;
-not_sign: begin out_contrib[1]:="n"; out_contrib[2]:="o"; out_contrib[3]:="t";
- send_out(ident,3);
- end;
-set_element_sign: begin out_contrib[1]:="i"; out_contrib[2]:="n";
- send_out(ident,2);
- end;
-or_sign: begin out_contrib[1]:="o"; out_contrib[2]:="r"; send_out(ident,2);
-@z
-
-@x [116] Remove conversion to uppercase
-@ Single-character identifiers represent themselves, while longer ones
-appear in |byte_mem|. All must be converted to uppercase,
-with underlines removed. Extremely long identifiers must be chopped.
-
-(Some \PASCAL\ compilers work with lowercase letters instead of
-uppercase. If this module of \.{TANGLE} is changed, it's also necessary
-to change from uppercase to lowercase in the modules that are
-listed in the index under ``uppercase''.)
-@^system dependencies@>
-@^uppercase@>
-
-@d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14,
- #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,#
-
-@<Cases related to identifiers@>=
-"A",up_to("Z"): begin out_contrib[1]:=cur_char; send_out(ident,1);
- end;
-"a",up_to("z"): begin out_contrib[1]:=cur_char-@'40; send_out(ident,1);
- end;
-identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww;
- while (k<max_id_length)and(j<byte_start[cur_val+ww]) do
- begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j);
- if out_contrib[k]>="a" then out_contrib[k]:=out_contrib[k]-@'40
- else if out_contrib[k]="_" then decr(k);
- end;
- send_out(ident,k);
- end;
-@y
-@ Single-character identifiers represent themselves, while longer ones
-appear in |byte_mem|. All must be converted to lowercase,
-with underlines removed. Extremely long identifiers must be chopped.
-@^system dependencies@>
-
-@d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14,
- #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,#
-
-@<Cases related to identifiers@>=
-"A",up_to("Z"),
-"a",up_to("z"): begin out_contrib[1]:=cur_char; send_out(ident,1);
- end;
-identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww;
- while (k<max_id_length)and(j<byte_start[cur_val+ww]) do
- begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j);
- if not allow_underlines and (out_contrib[k]="_") then decr(k);
- end;
- send_out(ident,k);
- end;
-@z
-
-@x [??] Fix casting bug
-@d add_in(#)==begin accumulator:=accumulator+next_sign*(#); next_sign:=+1;
- end
-@y
-@d add_in(#)==begin accumulator:=accumulator+next_sign*intcast(#); next_sign:=+1;
- end
-@z
-
-@x [179] make term_in = input
-any error stop will set |debug_cycle| to zero.
-@y
-any error stop will set |debug_cycle| to zero.
-
-@d term_in==stdin
-@z
-
-@x
-@!term_in:text_file; {the user's terminal as an input file}
-@y
-@z
-
-@x [180] remove term_in reset
-reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|}
-@y
-@z
-
-@x [182] write newline just before exit; use value of |history|
-print_ln(banner); {print a ``banner line''}
-@y
-print (banner); {print a ``banner line''}
-print_ln (version_string);
-@z
-
-@x Eliminate the |end_of_TANGLE| label.
-end_of_TANGLE:
-@y
-@z
-
-@x
-@<Print the job |history|@>;
-@y
-@<Print the job |history|@>;
-new_line;
-if (history <> spotless) and (history <> harmless_message)
-then uexit (1)
-else uexit (0);
-@z
-
-@x [188] System-dependent changes.
-This module should be replaced, if necessary, by changes to the program
-that are necessary to make \.{TANGLE} work at a particular installation.
-It is usually best to design your change file so that all changes to
-previous modules preserve the module numbering; then everybody's version
-will be consistent with the printed program. More extensive changes,
-which introduce new modules, can be inserted here; then only the index
-itself will get a new module number.
-@^system dependencies@>
-@y
-Parse a Unix-style command line.
-
-@d argument_is (#) == (strcmp (long_options[option_index].name, #) = 0)
-
-@<Define |parse_arguments|@> =
-procedure parse_arguments;
-const n_options = 4; {Pascal won't count array lengths for us.}
-var @!long_options: array[0..n_options] of getopt_struct;
- @!getopt_return_val: integer;
- @!option_index: c_int_type;
- @!current_option: 0..n_options;
-begin
- @<Define the option table@>;
- repeat
- getopt_return_val := getopt_long_only (argc, argv, '', long_options,
- address_of (option_index));
- if getopt_return_val = -1 then begin
- {End of arguments; we exit the loop below.} ;
-
- end else if getopt_return_val = "?" then begin
- usage ('luatangle');
-
- end else if argument_is ('underlines') then begin
- allow_underlines := true;
-
- end else if argument_is ('help') then begin
- usage_help (LUATANGLE_HELP, nil);
-
- end else if argument_is ('version') then begin
- print_version_and_exit
- (banner, nil, 'J. Plaice, Y. Haralambous, D.E. Knuth', nil);
-
- end; {Else it was a flag; |getopt| has already done the assignment.}
- until getopt_return_val = -1;
-
- {Now |optind| is the index of first non-option on the command line.}
- if (optind + 1 <> argc) and (optind + 2 <> argc) then begin
- write_ln (stderr, 'otangle: Need one or two file arguments.');
- usage ('otangle');
- end;
-
- {Supply |".web"| and |".ch"| extensions if necessary.}
- web_name := extend_filename (cmdline (optind), 'web');
- if optind + 2 = argc then begin
- chg_name := extend_filename (cmdline (optind + 1), 'ch');
- end;
-
- {Change |".web"| to |".p"| and use the current directory.}
- pascal_name := basename_change_suffix (web_name, '.web', '.p');
-end;
-
-@ Here are the options we allow. The first is one of the standard GNU options.
-@.-help@>
-
-@<Define the option...@> =
-current_option := 0;
-long_options[current_option].name := 'help';
-long_options[current_option].has_arg := 0;
-long_options[current_option].flag := 0;
-long_options[current_option].val := 0;
-incr (current_option);
-
-@ Another of the standard options.
-@.-version@>
-
-@<Define the option...@> =
-long_options[current_option].name := 'version';
-long_options[current_option].has_arg := 0;
-long_options[current_option].flag := 0;
-long_options[current_option].val := 0;
-incr (current_option);
-
-@ Allow underlines.
-@.-underlines@>
-
-@<Define the option...@> =
-long_options[current_option].name := 'underlines';
-long_options[current_option].has_arg := 0;
-long_options[current_option].flag := 0;
-long_options[current_option].val := 0;
-incr (current_option);
-
-@ An element with all zeros always ends the list.
-
-@<Define the option...@> =
-long_options[current_option].name := 0;
-long_options[current_option].has_arg := 0;
-long_options[current_option].flag := 0;
-long_options[current_option].val := 0;
-
-@ Global filenames.
-
-@<Globals...@>=
-@!web_name,@!chg_name,@!pascal_name,@!pool_name:const_c_string;
-@!@!allow_underlines:boolean;
-@z
diff --git a/Build/source/texk/web2c/luatexdir/luatangle.test b/Build/source/texk/web2c/luatexdir/luatangle.test
deleted file mode 100755
index f519174e8b6..00000000000
--- a/Build/source/texk/web2c/luatexdir/luatangle.test
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/sh
-
-# Copyright (C) 2009 Peter Breitenlohner <tex-live@tug.org>
-# You may freely use, modify and/or distribute this file.
-
-TEXMFCNF=$srcdir/../kpathsea WEBINPUTS=$srcdir/cftests \
- ./luatangle cftest cftest || exit 1
-
-diff cftest.p $srcdir/cftests/lcftest.p || exit 1
-
diff --git a/Build/source/texk/web2c/luatexdir/luatangle.web b/Build/source/texk/web2c/luatexdir/luatangle.web
deleted file mode 100644
index 46ca98e1e14..00000000000
--- a/Build/source/texk/web2c/luatexdir/luatangle.web
+++ /dev/null
@@ -1,3329 +0,0 @@
-% luatangle.web: LuaTeX version of file tangle.web
-% $Id$
-%
-% This file is part of LuaTeX.
-%
-% Copyright (c) 1994--1998 John Plaice and Yannis Haralambous
-% Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
-% applies only to the changes to the original tangle.web.
-%
-% This program by D. E. Knuth is not copyrighted and can be used freely.
-% Version 0 was released in December, 1981.
-% Version 1 was released in September, 1982, with version 0 of TeX.
-% Slight changes were made in October, 1982, for version 0.6 of TeX.
-% Version 1.2 introduced {:nnn} comments, added @@= and @@\ (December, 1982).
-% Version 1.4 added "history" (February, 1983).
-% Version 1.5 conformed to TeX version 0.96 and fixed @@\ (March, 1983).
-% Version 1.7 introduced the new change file format (June, 1983).
-% Version 2.0 was released in July, 1983, with version 0.999 of TeX.
-% Version 2.5 was released in November, 1983, with version 1.0 of TeX.
-% Version 2.6 fixed a bug: force-line-break after a constant (August, 1984).
-% Version 2.7 fixed the definition of check_sum_prime (May, 1985).
-% Version 2.8 fixed a bug in change_buffer movement (August, 1985).
-% Version 2.9 allows nonnumeric macros before their def (December, 1988).
-% Version 3, for Sewell's book, fixed long-line bug in input_ln (March, 1989).
-% Version 4 was major change to allow 8-bit input (September, 1989).
-% Version 4.1 conforms to ANSI standard for-loop rules (September, 1990).
-% Version 4.2 fixes stat report if phase one dies (March, 1991).
-% Version 4.3 fixes @@ bug in verbatim, catches extra } (September, 1991).
-% Version 4.4 activates debug_help on errors as advertised (February, 1993).
-
-% Here is TeX material that gets inserted after \input webmac
-\def\hang{\hangindent 3em\indent\ignorespaces}
-\font\ninerm=cmr9
-\let\mc=\ninerm % medium caps for names like SAIL
-\def\PASCAL{Pascal}
-\def\pb{$\.|\ldots\.|$} % Pascal brackets (|...|)
-\def\v{\.{\char'174}} % vertical (|) in typewriter font
-\mathchardef\BA="3224 % double arrow
-\def\({} % kludge for alphabetizing certain module names
-
-\def\title{LUATANGLE}
-\def\contentspagenumber{123} % should be odd
-\def\topofcontents{\null\vfill
- \titlefalse % include headline on the contents page
- \def\rheader{\mainfont Appendix E\hfil \contentspagenumber}
- \centerline{\titlefont The {\ttitlefont LUATANGLE} processor}
- \vskip 15pt
- \centerline{(Version 4.4)}
- \vfill}
-\pageno=\contentspagenumber \advance\pageno by 1
-
-@* Introduction.
-This program converts a \.{WEB} file to a \PASCAL\ file. It was written
-by D. E. Knuth in September, 1981; a somewhat similar {\mc SAIL} program had
-been developed in March, 1979. Since this program describes itself, a
-bootstrapping process involving hand-translation had to be used to get started.
-
-For large \.{WEB} files one should have a large memory, since \.{TANGLE} keeps
-all the \PASCAL\ text in memory (in an abbreviated form). The program uses
-a few features of the local \PASCAL\ compiler that may need to be changed in
-other installations:
-
-\yskip\item{1)} Case statements have a default.
-\item{2)} Input-output routines may need to be adapted for use with a particular
-character set and/or for printing messages on the user's terminal.
-
-\yskip\noindent
-These features are also present in the \PASCAL\ version of \TeX, where they
-are used in a similar (but more complex) way. System-dependent portions
-of \.{TANGLE} can be identified by looking at the entries for `system
-dependencies' in the index below.
-@!@^system dependencies@>
-
-The ``banner line'' defined here should be changed whenever \.{TANGLE}
-is modified.
-
-@d banner=='This is LUATANGLE, Version 4.4'
-
-@ The program begins with a fairly normal header, made up of pieces that
-@^system dependencies@>
-will mostly be filled in later. The \.{WEB} input comes from files |web_file|
-and |change_file|, the \PASCAL\ output goes to file |Pascal_file|,
-and the string pool output goes to file |pool|.
-
-If it is necessary to abort the job because of a fatal error, the program
-calls the `|jump_out|' procedure, which goes to the label |end_of_TANGLE|.
-
-@d end_of_TANGLE = 9999 {go here to wrap it up}
-
-@p @t\4@>@<Compiler directives@>@/
-program LUATANGLE(@!web_file,@!change_file,@!Pascal_file,@!pool);
-label end_of_TANGLE; {go here to finish}
-const @<Constants in the outer block@>@/
-type @<Types in the outer block@>@/
-var @<Globals in the outer block@>@/
-@<Error handling procedures@>@/
-procedure initialize;
- var @<Local variables for initialization@>@/
- begin @<Set initial values@>@/
- end;
-
-@ Some of this code is optional for use when debugging only;
-such material is enclosed between the delimiters |debug| and $|gubed|$.
-Other parts, delimited by |stat| and $|tats|$, are optionally included if
-statistics about \.{TANGLE}'s memory usage are desired.
-
-@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging}
-@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging}
-@f debug==begin
-@f gubed==end
-@#
-@d stat==@{ {change this to `$\\{stat}\equiv\null$'
- when gathering usage statistics}
-@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$'
- when gathering usage statistics}
-@f stat==begin
-@f tats==end
-
-@ The \PASCAL\ compiler used to develop this system has ``compiler
-directives'' that can appear in comments whose first character is a dollar sign.
-In production versions of \.{TANGLE} these directives tell the compiler that
-@^system dependencies@>
-it is safe to avoid range checks and to leave out the extra code it inserts
-for the \PASCAL\ debugger's benefit, although interrupts will occur if
-there is arithmetic overflow.
-
-@<Compiler directives@>=
-@{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead}
-@!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging}
-
-@ Labels are given symbolic names by the following definitions. We insert
-the label `|exit|:' just before the `\ignorespaces|end|\unskip' of a
-procedure in which we have used the `|return|' statement defined below;
-the label `|restart|' is occasionally used at the very beginning of a
-procedure; and the label `|reswitch|' is occasionally used just prior to
-a \&{case} statement in which some cases change the conditions and we wish to
-branch to the newly applicable case.
-Loops that are set up with the \&{loop} construction defined below are
-commonly exited by going to `|done|' or to `|found|' or to `|not_found|',
-and they are sometimes repeated by going to `|continue|'.
-
-@d exit=10 {go here to leave a procedure}
-@d restart=20 {go here to start a procedure again}
-@d reswitch=21 {go here to start a case statement again}
-@d continue=22 {go here to resume a loop}
-@d done=30 {go here to exit a loop}
-@d found=31 {go here when you've found it}
-@d not_found=32 {go here when you've found something else}
-
-@ Here are some macros for common programming idioms.
-
-@d incr(#) == #:=#+1 {increase a variable by unity}
-@d decr(#) == #:=#-1 {decrease a variable by unity}
-@d loop == @+ while true do@+ {repeat over and over until a |goto| happens}
-@d do_nothing == {empty statement}
-@d return == goto exit {terminate a procedure call}
-@f return == nil
-@f loop == xclause
-
-@ We assume that |case| statements may include a default case that applies
-if no matching label is found. Thus, we shall use constructions like
-@^system dependencies@>
-$$\vbox{\halign{#\hfil\cr
-|case x of|\cr
-1: $\langle\,$code for $x=1\,\rangle$;\cr
-3: $\langle\,$code for $x=3\,\rangle$;\cr
-|othercases| $\langle\,$code for |x<>1| and |x<>3|$\,\rangle$\cr
-|endcases|\cr}}$$
-since most \PASCAL\ compilers have plugged this hole in the language by
-incorporating some sort of default mechanism. For example, the compiler
-used to develop \.{WEB} and \TeX\ allows `|others|:' as a default label,
-and other \PASCAL s allow syntaxes like `\ignorespaces|else|\unskip' or
-`\&{otherwise}' or `\\{otherwise}:', etc. The definitions of |othercases|
-and |endcases| should be changed to agree with local conventions. (Of
-course, if no default mechanism is available, the |case| statements of
-this program must be extended by listing all remaining cases. The author
-would have taken the trouble to modify \.{TANGLE} so that such extensions
-were done automatically, if he had not wanted to encourage \PASCAL\
-compiler writers to make this important change in \PASCAL, where it belongs.)
-
-@d othercases == others: {default for cases not listed explicitly}
-@d endcases == @+end {follows the default case in an extended |case| statement}
-@f othercases == else
-@f endcases == end
-
-@ The following parameters are set big enough to handle \TeX, so they
-should be sufficient for most applications of \.{TANGLE}.
-
-@<Constants...@>=
-@!buf_size=100; {maximum length of input line}
-@!max_bytes=65535; {|1/ww| times the number of bytes in identifiers,
- strings, and module names; must be less than 65536}
-@!max_toks=65535; {|1/zz| times the number of bytes in compressed \PASCAL\ code;
- must be less than 65536}
-@!max_names=10239; {number of identifiers, strings, module names;
- must be less than 10240}
-@!max_texts=10239; {number of replacement texts, must be less than 10240}
-@!hash_size=353; {should be prime}
-@!longest_name=400; {module names shouldn't be longer than this}
-@!line_length=72; {lines of \PASCAL\ output have at most this many characters}
-@!out_buf_size=144; {length of output buffer, should be twice |line_length|}
-@!stack_size=50; {number of simultaneous levels of macro expansion}
-@!max_id_length=12; {long identifiers are chopped to this length, which must
- not exceed |line_length|}
-@!unambig_length=7; {identifiers must be unique if chopped to this length}
- {note that 7 is more strict than \PASCAL's 8, but this can be varied}
-
-@ A global variable called |history| will contain one of four values
-at the end of every run: |spotless| means that no unusual messages were
-printed; |harmless_message| means that a message of possible interest
-was printed but no serious errors were detected; |error_message| means that
-at least one error was found; |fatal_message| means that the program
-terminated abnormally. The value of |history| does not influence the
-behavior of the program; it is simply computed for the convenience
-of systems that might want to use such information.
-
-@d spotless=0 {|history| value for normal jobs}
-@d harmless_message=1 {|history| value when non-serious info was printed}
-@d error_message=2 {|history| value when an error was noted}
-@d fatal_message=3 {|history| value when we had to stop prematurely}
-@#
-@d mark_harmless==@t@>@+if history=spotless then history:=harmless_message
-@d mark_error==history:=error_message
-@d mark_fatal==history:=fatal_message
-@d biggest_char=2097151
-@d number_chars=2097152
-
-@<Glob...@>=@!history:spotless..fatal_message; {how bad was this run?}
-
-@ @<Set init...@>=history:=spotless;
-
-@* The character set.
-One of the main goals in the design of \.{WEB} has been to make it readily
-portable between a wide variety of computers. Yet \.{WEB} by its very
-nature must use a greater variety of characters than most computer
-programs deal with, and character encoding is one of the areas in which
-existing machines differ most widely from each other.
-
-To resolve this problem, all input to \.{WEAVE} and \.{TANGLE} is converted
-to an internal eight-bit code that is essentially standard ASCII, the ``American
-Standard Code for Information Interchange.'' The conversion is done
-immediately when each character is read in. Conversely, characters are
-converted from ASCII to the user's external representation just before
-they are output. (The original ASCII code was seven bits only; \.{WEB} now
-allows eight bits in an attempt to keep up with modern times.)
-
-Such an internal code is relevant to users of \.{WEB} only because it is
-the code used for preprocessed constants like \.{"A"}. If you are writing
-a program in \.{WEB} that makes use of such one-character constants, you
-should convert your input to ASCII form, like \.{WEAVE} and \.{TANGLE} do.
-Otherwise \.{WEB}'s internal coding scheme does not affect you.
-@^ASCII code@>
-
-Here is a table of the standard visible ASCII codes:
-$$\def\:{\char\count255\global\advance\count255 by 1}
-\count255='40
-\vbox{
-\hbox{\hbox to 40pt{\it\hfill0\/\hfill}%
-\hbox to 40pt{\it\hfill1\/\hfill}%
-\hbox to 40pt{\it\hfill2\/\hfill}%
-\hbox to 40pt{\it\hfill3\/\hfill}%
-\hbox to 40pt{\it\hfill4\/\hfill}%
-\hbox to 40pt{\it\hfill5\/\hfill}%
-\hbox to 40pt{\it\hfill6\/\hfill}%
-\hbox to 40pt{\it\hfill7\/\hfill}}
-\vskip 4pt
-\hrule
-\def\^{\vrule height 10.5pt depth 4.5pt}
-\halign{\hbox to 0pt{\hskip -24pt\O{#0}\hfill}&\^
-\hbox to 40pt{\tt\hfill#\hfill\^}&
-&\hbox to 40pt{\tt\hfill#\hfill\^}\cr
-04&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-05&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-06&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-07&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-10&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-11&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-12&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-13&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-14&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-15&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-16&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
-17&\:&\:&\:&\:&\:&\:&\:\cr}
-\hrule width 280pt}$$
-(Actually, of course, code @'040 is an invisible blank space.) Code @'136
-was once an upward arrow (\.{\char'13}), and code @'137 was
-once a left arrow (\.^^X), in olden times when the first draft
-of ASCII code was prepared; but \.{WEB} works with today's standard
-ASCII in which those codes represent circumflex and underline as shown.
-
-@<Types...@>=
-@!ASCII_code=0..255; {eight-bit numbers, a subrange of the integers}
-
-@ The original \PASCAL\ compiler was designed in the late 60s, when six-bit
-character sets were common, so it did not make provision for lowercase
-letters. Nowadays, of course, we need to deal with both capital and small
-letters in a convenient way, so \.{WEB} assumes that it is being used
-with a \PASCAL\ whose character set contains at least the characters of
-standard ASCII as listed above. Some \PASCAL\ compilers use the original
-name |char| for the data type associated with the characters in text files,
-while other \PASCAL s consider |char| to be a 64-element subrange of a larger
-data type that has some other name.
-
-In order to accommodate this difference, we shall use the name |text_char|
-to stand for the data type of the characters in the input and output
-files. We shall also assume that |text_char| consists of the elements
-|chr(first_text_char)| through |chr(last_text_char)|, inclusive. The
-following definitions should be adjusted if necessary.
-@^system dependencies@>
-
-@d text_char == char {the data type of characters in text files}
-@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
-@d last_text_char=255 {ordinal number of the largest element of |text_char|}
-
-@<Types...@>=
-@!text_file=packed file of text_char;
-
-@ The \.{WEAVE} and \.{TANGLE} processors convert between ASCII code and
-the user's external character set by means of arrays |xord| and |xchr|
-that are analogous to \PASCAL's |ord| and |chr| functions.
-
-@<Globals...@>=
-@!xord: array [text_char] of ASCII_code;
- {specifies conversion of input characters}
-@!xchr: array [ASCII_code] of text_char;
- {specifies conversion of output characters}
-
-@ If we assume that every system using \.{WEB} is able to read and write the
-visible characters of standard ASCII (although not necessarily using the
-ASCII codes to represent them), the following assignment statements initialize
-most of the |xchr| array properly, without needing any system-dependent
-changes. For example, the statement \.{xchr[@@\'101]:=\'A\'} that appears
-in the present \.{WEB} file might be encoded in, say, {\mc EBCDIC} code
-on the external medium on which it resides, but \.{TANGLE} will convert from
-this external code to ASCII and back again. Therefore the assignment
-statement \.{XCHR[65]:=\'A\'} will appear in the corresponding \PASCAL\ file,
-and \PASCAL\ will compile this statement so that |xchr[65]| receives the
-character \.A in the external (|char|) code. Note that it would be quite
-incorrect to say \.{xchr[@@\'101]:="A"}, because |"A"| is a constant of
-type |integer|, not |char|, and because we have $|"A"|=65$ regardless of
-the external character set.
-
-@<Set init...@>=
-xchr[@'40]:=' ';
-xchr[@'41]:='!';
-xchr[@'42]:='"';
-xchr[@'43]:='#';
-xchr[@'44]:='$';
-xchr[@'45]:='%';
-xchr[@'46]:='&';
-xchr[@'47]:='''';@/
-xchr[@'50]:='(';
-xchr[@'51]:=')';
-xchr[@'52]:='*';
-xchr[@'53]:='+';
-xchr[@'54]:=',';
-xchr[@'55]:='-';
-xchr[@'56]:='.';
-xchr[@'57]:='/';@/
-xchr[@'60]:='0';
-xchr[@'61]:='1';
-xchr[@'62]:='2';
-xchr[@'63]:='3';
-xchr[@'64]:='4';
-xchr[@'65]:='5';
-xchr[@'66]:='6';
-xchr[@'67]:='7';@/
-xchr[@'70]:='8';
-xchr[@'71]:='9';
-xchr[@'72]:=':';
-xchr[@'73]:=';';
-xchr[@'74]:='<';
-xchr[@'75]:='=';
-xchr[@'76]:='>';
-xchr[@'77]:='?';@/
-xchr[@'100]:='@@';
-xchr[@'101]:='A';
-xchr[@'102]:='B';
-xchr[@'103]:='C';
-xchr[@'104]:='D';
-xchr[@'105]:='E';
-xchr[@'106]:='F';
-xchr[@'107]:='G';@/
-xchr[@'110]:='H';
-xchr[@'111]:='I';
-xchr[@'112]:='J';
-xchr[@'113]:='K';
-xchr[@'114]:='L';
-xchr[@'115]:='M';
-xchr[@'116]:='N';
-xchr[@'117]:='O';@/
-xchr[@'120]:='P';
-xchr[@'121]:='Q';
-xchr[@'122]:='R';
-xchr[@'123]:='S';
-xchr[@'124]:='T';
-xchr[@'125]:='U';
-xchr[@'126]:='V';
-xchr[@'127]:='W';@/
-xchr[@'130]:='X';
-xchr[@'131]:='Y';
-xchr[@'132]:='Z';
-xchr[@'133]:='[';
-xchr[@'134]:='\';
-xchr[@'135]:=']';
-xchr[@'136]:='^';
-xchr[@'137]:='_';@/
-xchr[@'140]:='`';
-xchr[@'141]:='a';
-xchr[@'142]:='b';
-xchr[@'143]:='c';
-xchr[@'144]:='d';
-xchr[@'145]:='e';
-xchr[@'146]:='f';
-xchr[@'147]:='g';@/
-xchr[@'150]:='h';
-xchr[@'151]:='i';
-xchr[@'152]:='j';
-xchr[@'153]:='k';
-xchr[@'154]:='l';
-xchr[@'155]:='m';
-xchr[@'156]:='n';
-xchr[@'157]:='o';@/
-xchr[@'160]:='p';
-xchr[@'161]:='q';
-xchr[@'162]:='r';
-xchr[@'163]:='s';
-xchr[@'164]:='t';
-xchr[@'165]:='u';
-xchr[@'166]:='v';
-xchr[@'167]:='w';@/
-xchr[@'170]:='x';
-xchr[@'171]:='y';
-xchr[@'172]:='z';
-xchr[@'173]:='{';
-xchr[@'174]:='|';
-xchr[@'175]:='}';
-xchr[@'176]:='~';@/
-xchr[0]:=' '; xchr[@'177]:=' '; {these ASCII codes are not used}
-
-@ Some of the ASCII codes below @'40 have been given symbolic names in
-\.{WEAVE} and \.{TANGLE} because they are used with a special meaning.
-
-@d and_sign=@'4 {equivalent to `\.{and}'}
-@d not_sign=@'5 {equivalent to `\.{not}'}
-@d set_element_sign=@'6 {equivalent to `\.{in}'}
-@d tab_mark=@'11 {ASCII code used as tab-skip}
-@d line_feed=@'12 {ASCII code thrown away at end of line}
-@d form_feed=@'14 {ASCII code used at end of page}
-@d carriage_return=@'15 {ASCII code used at end of line}
-@d left_arrow=@'30 {equivalent to `\.{:=}'}
-@d not_equal=@'32 {equivalent to `\.{<>}'}
-@d less_or_equal=@'34 {equivalent to `\.{<=}'}
-@d greater_or_equal=@'35 {equivalent to `\.{>=}'}
-@d equivalence_sign=@'36 {equivalent to `\.{==}'}
-@d or_sign=@'37 {equivalent to `\.{or}'}
-
-@ When we initialize the |xord| array and the remaining parts of |xchr|,
-it will be convenient to make use of an index variable, |i|.
-
-@<Local variables for init...@>=
-@!i:0..255;
-
-@ Here now is the system-dependent part of the character set.
-If \.{WEB} is being implemented on a garden-variety \PASCAL\ for which
-only standard ASCII codes will appear in the input and output files, you
-don't need to make any changes here. But if you have, for example, an extended
-character set like the one in Appendix~C of {\sl The \TeX book}, the first
-line of code in this module should be changed to
-$$\hbox{|for i:=1 to @'37 do xchr[i]:=chr(i);|}$$
-\.{WEB}'s character set is essentially identical to \TeX's, even with respect to
-characters less than @'40.
-@^system dependencies@>
-
-Changes to the present module will make \.{WEB} more friendly on computers
-that have an extended character set, so that one can type things like
-\.^^Z\ instead of \.{<>}. If you have an extended set of characters that
-are easily incorporated into text files, you can assign codes arbitrarily
-here, giving an |xchr| equivalent to whatever characters the users of
-\.{WEB} are allowed to have in their input files, provided that unsuitable
-characters do not correspond to special codes like |carriage_return|
-that are listed above.
-
-(The present file \.{TANGLE.WEB} does not contain any of the non-ASCII
-characters, because it is intended to be used with all implementations of
-\.{WEB}. It was originally created on a Stanford system that has a
-convenient extended character set, then ``sanitized'' by applying another
-program that transliterated all of the non-standard characters into
-standard equivalents.)
-
-@<Set init...@>=
-for i:=1 to @'37 do xchr[i]:=' ';
-for i:=@'200 to @'377 do xchr[i]:=' ';
-
-@ The following system-independent code makes the |xord| array contain a
-suitable inverse to the information in |xchr|.
-
-@<Set init...@>=
-for i:=first_text_char to last_text_char do xord[chr(i)]:=" ";
-for i:=1 to @'377 do xord[xchr[i]]:=i;
-xord[' ']:=" ";
-
-@* Input and output.
-The input conventions of this program are intended to be very much like those
-of \TeX\ (except, of course, that they are much simpler, because much less
-needs to be done). Furthermore they are identical to those of \.{WEAVE}.
-Therefore people who need to make modifications to all three systems
-should be able to do so without too many headaches.
-
-We use the standard \PASCAL\ input/output procedures in several places that
-\TeX\ cannot, since \.{TANGLE} does not have to deal with files that are named
-dynamically by the user, and since there is no input from the terminal.
-
-@ Terminal output is done by writing on file |term_out|, which is assumed to
-consist of characters of type |text_char|:
-@^system dependencies@>
-
-@d print(#)==write(term_out,#) {`|print|' means write on the terminal}
-@d print_ln(#)==write_ln(term_out,#) {`|print|' and then start new line}
-@d new_line==write_ln(term_out) {start new line}
-@d print_nl(#)== {print information starting on a new line}
- begin new_line; print(#);
- end
-
-@<Globals...@>=
-@!term_out:text_file; {the terminal as an output file}
-
-@ Different systems have different ways of specifying that the output on a
-certain file will appear on the user's terminal. Here is one way to do this
-on the \PASCAL\ system that was used in \.{TANGLE}'s initial development:
-@^system dependencies@>
-
-@<Set init...@>=
-rewrite(term_out,'TTY:'); {send |term_out| output to the terminal}
-
-@ The |update_terminal| procedure is called when we want
-to make sure that everything we have output to the terminal so far has
-actually left the computer's internal buffers and been sent.
-@^system dependencies@>
-
-@d update_terminal == break(term_out) {empty the terminal output buffer}
-
-@ The main input comes from |web_file|; this input may be overridden
-by changes in |change_file|. (If |change_file| is empty, there are no changes.)
-
-@<Globals...@>=
-@!web_file:text_file; {primary input}
-@!change_file:text_file; {updates}
-
-@ The following code opens the input files. Since these files were listed
-in the program header, we assume that the \PASCAL\ runtime system has
-already checked that suitable file names have been given; therefore no
-additional error checking needs to be done.
-@^system dependencies@>
-
-@p procedure open_input; {prepare to read |web_file| and |change_file|}
-begin reset(web_file); reset(change_file);
-end;
-
-@ The main output goes to |Pascal_file|, and string pool constants are
-written to the |pool| file.
-
-@<Globals...@>=
-@!Pascal_file: text_file;
-@!pool: text_file;
-
-@ The following code opens |Pascal_file| and |pool|.
-Since these files were listed in the program header, we assume that the
-\PASCAL\ runtime system has checked that suitable external file names have
-been given.
-@^system dependencies@>
-
-@<Set init...@>=
-rewrite(Pascal_file); rewrite(pool);
-
-@ Input goes into an array called |buffer|.
-
-@<Globals...@>=@!buffer: array[0..buf_size] of ASCII_code;
-
-@ The |input_ln| procedure brings the next line of input from the specified
-file into the |buffer| array and returns the value |true|, unless the file has
-already been entirely read, in which case it returns |false|. The conventions
-of \TeX\ are followed; i.e., |ASCII_code| numbers representing the next line
-of the file are input into |buffer[0]|, |buffer[1]|, \dots,
-|buffer[limit-1]|; trailing blanks are ignored;
-and the global variable |limit| is set to the length of the
-@^system dependencies@>
-line. The value of |limit| must be strictly less than |buf_size|.
-
-We assume that none of the |ASCII_code| values
-of |buffer[j]| for |0<=j<limit| is equal to 0, @'177, |line_feed|, |form_feed|,
-or |carriage_return|.
-
-@p function input_ln(var f:text_file):boolean;
- {inputs a line or returns |false|}
-var final_limit:0..buf_size; {|limit| without trailing blanks}
-begin limit:=0; final_limit:=0;
-if eof(f) then input_ln:=false
-else begin while not eoln(f) do
- begin buffer[limit]:=xord[f^]; get(f);
- incr(limit);
- if buffer[limit-1]<>" " then final_limit:=limit;
- if limit=buf_size then
- begin while not eoln(f) do get(f);
- decr(limit); {keep |buffer[buf_size]| empty}
- if final_limit>limit then final_limit:=limit;
- print_nl('! Input line too long'); loc:=0; error;
-@.Input line too long@>
- end;
- end;
- read_ln(f); limit:=final_limit; input_ln:=true;
- end;
-end;
-
-@* Reporting errors to the user.
-The \.{TANGLE} processor operates in two phases: first it inputs the source
-file and stores a compressed representation of the program, then it produces
-the \PASCAL\ output from the compressed representation.
-
-The global variable |phase_one| tells whether we are in Phase I or not.
-
-@<Globals...@>=
-@!phase_one: boolean; {|true| in Phase I, |false| in Phase II}
-
-@ If an error is detected while we are debugging,
-we usually want to look at the contents of memory.
-A special procedure will be declared later for this purpose.
-
-@<Error handling...@>=
-@!debug @+ procedure debug_help; forward;@+ gubed
-
-@ During the first phase, syntax errors are reported to the user by saying
-$$\hbox{`|err_print('! Error message')|'},$$
-followed by `|jump_out|' if no recovery from the error is provided.
-This will print the error message followed by an indication of where the error
-was spotted in the source file. Note that no period follows the error message,
-since the error routine will automatically supply a period.
-
-Errors that are noticed during the second phase are reported to the user
-in the same fashion, but the error message will be
-followed by an indication of where the error was spotted in the output file.
-
-The actual error indications are provided by a procedure called |error|.
-
-@d err_print(#)==begin new_line; print(#); error;
- end
-
-@<Error handling...@>=
-procedure error; {prints '\..' and location of error message}
-var j: 0..out_buf_size; {index into |out_buf|}
-@!k,@!l: 0..buf_size; {indices into |buffer|}
-begin if phase_one then @<Print error location based on input buffer@>
-else @<Print error location based on output buffer@>;
-update_terminal; mark_error;
-@!debug debug_skipped:=debug_cycle; debug_help;@+gubed
-end;
-
-@ The error locations during Phase I can be indicated by using the global
-variables |loc|, |line|, and |changing|, which tell respectively the first
-unlooked-at position in |buffer|, the current line number, and whether or not
-the current line is from |change_file| or |web_file|.
-This routine should be modified on systems whose standard text editor
-has special line-numbering conventions.
-@^system dependencies@>
-
-@<Print error location based on input buffer@>=
-begin if changing then print('. (change file ')@+else print('. (');
-print_ln('l.', line:1, ')');
-if loc>=limit then l:=limit else l:=loc;
-for k:=1 to l do
- if buffer[k-1]=tab_mark then print(' ')
- else print(xchr[buffer[k-1]]); {print the characters already read}
-new_line;
-for k:=1 to l do print(' '); {space out the next line}
-for k:=l+1 to limit do print(xchr[buffer[k-1]]); {print the part not yet read}
-print(' '); {this space separates the message from future asterisks}
-end
-
-@ The position of errors detected during the second phase can be indicated
-by outputting the partially-filled output buffer, which contains |out_ptr|
-entries.
-
-@<Print error location based on output...@>=
-begin print_ln('. (l.',line:1,')');
-for j:=1 to out_ptr do print(xchr[out_buf[j-1]]); {print current partial line}
-print('... '); {indicate that this information is partial}
-end
-
-@ The |jump_out| procedure just cuts across all active procedure levels
-and jumps out of the program. This is the only non-local |goto| statement
-in \.{TANGLE}. It is used when no recovery from a particular error has
-been provided.
-
-Some \PASCAL\ compilers do not implement non-local |goto| statements.
-@^system dependencies@>
-In such cases the code that appears at label |end_of_TANGLE| should be
-copied into the |jump_out| procedure, followed by a call to a system procedure
-that terminates the program.
-
-@d fatal_error(#)==begin new_line; print(#); error; mark_fatal; jump_out;
- end
-
-@<Error handling...@>=
-procedure jump_out;
-begin goto end_of_TANGLE;
-end;
-
-@ Sometimes the program's behavior is far different from what it should be,
-and \.{TANGLE} prints an error message that is really for the \.{TANGLE}
-maintenance person, not the user. In such cases the program says
-|confusion('indication of where we are')|.
-
-@d confusion(#)==fatal_error('! This can''t happen (',#,')')
-@.This can't happen@>
-
-@ An overflow stop occurs if \.{TANGLE}'s tables aren't large enough.
-
-@d overflow(#)==fatal_error('! Sorry, ',#,' capacity exceeded')
-@.Sorry, x capacity exceeded@>
-
-
-@* Data structures.
-Most of the user's \PASCAL\ code is packed into eight-bit integers
-in two large arrays called |byte_mem| and |tok_mem|.
-The |byte_mem| array holds the names of identifiers, strings, and modules;
-the |tok_mem| array holds the replacement texts
-for macros and modules. Allocation is sequential, since things are deleted only
-during Phase II, and only in a last-in-first-out manner.
-
-Auxiliary arrays |byte_start| and |tok_start| are used as directories to
-|byte_mem| and |tok_mem|, and the |link|, |ilk|, |equiv|, and |text_link|
-arrays give further information about names. These auxiliary arrays
-consist of sixteen-bit items.
-
-@<Types...@>=
-@!eight_bits=0..255; {unsigned one-byte quantity}
-@!sixteen_bits=integer; {not quite a two-byte quantity}
-
-@ \.{TANGLE} has been designed to avoid the need for indices that are more
-than sixteen bits wide, so that it can be used on most computers. But
-there are programs that need more than 65536 tokens, and some programs
-even need more than 65536 bytes; \TeX\ is one of these. To get around
-this problem, a slight complication has been added to the data structures:
-|byte_mem| and |tok_mem| are two-dimensional arrays, whose first index is
-either 0 or 1. (For generality, the first index is actually allowed to run
-between 0 and |ww-1| in |byte_mem|, or between 0 and |zz-1| in |tok_mem|,
-where |ww| and |zz| are set to 2 and~3; the program will work for any
-positive values of |ww| and |zz|, and it can be simplified in obvious ways
-if |ww=1| or |zz=1|.)
-
-@d ww=2 {we multiply the byte capacity by approximately this amount}
-@d zz=3 {we multiply the token capacity by approximately this amount}
-
-@<Globals...@>=
-@!byte_mem: packed array [0..ww-1,0..max_bytes] of ASCII_code;
- {characters of names}
-@!tok_mem: packed array [0..zz-1,0..max_toks] of eight_bits; {tokens}
-@!byte_start: array [0..max_names] of sixteen_bits; {directory into |byte_mem|}
-@!tok_start: array [0..max_texts] of sixteen_bits; {directory into |tok_mem|}
-@!link: array [0..max_names] of sixteen_bits; {hash table or tree links}
-@!ilk: array [0..max_names] of sixteen_bits; {type codes or tree links}
-@!equiv: array [0..max_names] of sixteen_bits; {info corresponding to names}
-@!text_link: array [0..max_texts] of sixteen_bits; {relates replacement texts}
-
-@ The names of identifiers are found by computing a hash address |h| and
-then looking at strings of bytes signified by |hash[h]|, |link[hash[h]]|,
-|link[link[hash[h]]]|, \dots, until either finding the desired name
-or encountering a zero.
-
-A `|name_pointer|' variable, which signifies a name, is an index into
-|byte_start|. The actual sequence of characters in the name pointed to by
-|p| appears in positions |byte_start[p]| to |byte_start[p+ww]-1|, inclusive,
-in the segment of |byte_mem| whose first index is |p mod ww|. Thus, when
-|ww=2| the even-numbered name bytes appear in |byte_mem[0,@t$*$@>]|
-and the odd-numbered ones appear in |byte_mem[1,@t$*$@>]|.
-The pointer 0 is used for undefined module names; we don't
-want to use it for the names of identifiers, since 0 stands for a null
-pointer in a linked list.
-
-Strings are treated like identifiers; the first character (a double-quote)
-distinguishes a string from an alphabetic name, but for \.{TANGLE}'s purposes
-strings behave like numeric macros. (A `string' here refers to the
-strings delimited by double-quotes that \.{TANGLE} processes. \PASCAL\
-string constants delimited by single-quote marks are not given such special
-treatment; they simply appear as sequences of characters in the \PASCAL\
-texts.) The total number of strings in the string
-pool is called |string_ptr|, and the total number of names in |byte_mem|
-is called |name_ptr|. The total number of bytes occupied in
-|byte_mem[w,@t$*$@>]| is called |byte_ptr[w]|.
-
-We usually have |byte_start[name_ptr+w]=byte_ptr[(name_ptr+w) mod ww]|
-for |0<=w<ww|, since these are the starting positions for the next |ww|
-names to be stored in |byte_mem|.
-
-@d length(#)==byte_start[#+ww]-byte_start[#] {the length of a name}
-
-@<Types...@>=
-@!name_pointer=0..max_names; {identifies a name}
-
-@ @<Global...@>=
-@!name_ptr:name_pointer; {first unused position in |byte_start|}
-@!string_ptr:name_pointer; {next number to be given to a string of length |<>1|}
-@!byte_ptr:array [0..ww-1] of 0..max_bytes;
- {first unused position in |byte_mem|}
-@!pool_check_sum:integer; {sort of a hash for the whole string pool}
-
-@ @<Local variables for init...@>=
-@!wi: 0..ww-1; {to initialize the |byte_mem| indices}
-
-@ @<Set init...@>=
-for wi:=0 to ww-1 do
- begin byte_start[wi]:=0; byte_ptr[wi]:=0;
- end;
-byte_start[ww]:=0; {this makes name 0 of length zero}
-name_ptr:=1; string_ptr:=number_chars; pool_check_sum:=271828;
-
-@ Replacement texts are stored in |tok_mem|, using similar conventions.
-A `|text_pointer|' variable is an index into |tok_start|, and the
-replacement text that corresponds to |p| runs from positions
-|tok_start[p]| to |tok_start[p+zz]-1|, inclusive, in the segment of
-|tok_mem| whose first index is |p mod zz|. Thus, when |zz=2| the
-even-numbered replacement texts appear in |tok_mem[0,@t$*$@>]| and the
-odd-numbered ones appear in |tok_mem[1,@t$*$@>]|. Furthermore,
-|text_link[p]| is used to connect pieces of text that have the same name,
-as we shall see later. The pointer 0 is used for undefined replacement
-texts.
-
-The first position of |tok_mem[z,@t$*$@>]| that is unoccupied by
-replacement text is called |tok_ptr[z]|, and the first unused location of
-|tok_start| is called |text_ptr|. We usually have the identity
-|tok_start[text_ptr+z]=tok_ptr[(text_ptr+z) mod zz]|, for |0<=z<zz|, since
-these are the starting positions for the next |zz| replacement texts to
-be stored in |tok_mem|.
-
-@<Types...@>=
-@!text_pointer=0..max_texts; {identifies a replacement text}
-
-@ It is convenient to maintain a variable |z| that is equal to |text_ptr
-mod zz|, so that we always insert tokens into segment |z| of |tok_mem|.
-
-@<Glob...@>=
-@t\hskip1em@>@!text_ptr:text_pointer; {first unused position in |tok_start|}
-@t\hskip1em@>@!tok_ptr:array[0..zz-1] of 0..max_toks;
- {first unused position in a given segment of |tok_mem|}
-@t\hskip1em@>@!z:0..zz-1; {current segment of |tok_mem|}
-stat @!max_tok_ptr:array[0..zz-1] of 0..max_toks;
- {largest values assumed by |tok_ptr|}
-tats
-
-@ @<Local variables for init...@>=
-@!zi:0..zz-1; {to initialize the |tok_mem| indices}
-
-@ @<Set init...@>=
-for zi:=0 to zz-1 do
- begin tok_start[zi]:=0; tok_ptr[zi]:=0;
- end;
-tok_start[zz]:=0; {this makes replacement text 0 of length zero}
-text_ptr:=1; z:=1 mod zz;
-
-@ Four types of identifiers are distinguished by their |ilk|:
-
-\yskip\hang |normal| identifiers will appear in the \PASCAL\ program as
-ordinary identifiers since they have not been defined to be macros; the
-corresponding value in the |equiv| array
-for such identifiers is a link in a secondary hash table that
-is used to check whether any two of them agree in their first |unambig_length|
-characters after underline symbols are removed and lowercase letters are
-changed to uppercase.
-
-\yskip\hang |numeric| identifiers have been defined to be numeric macros;
-their |equiv| value contains the corresponding numeric value plus $2^{15}$.
-Strings are treated as numeric macros.
-
-\yskip\hang |simple| identifiers have been defined to be simple macros;
-their |equiv| value points to the corresponding replacement text.
-
-\yskip\hang |parametric| identifiers have been defined to be parametric macros;
-like simple identifiers, their |equiv| value points to the replacement text.
-
-@d normal=0 {ordinary identifiers have |normal| ilk}
-@d numeric=1 {numeric macros and strings have |numeric| ilk}
-@d simple=2 {simple macros have |simple| ilk}
-@d parametric=3 {parametric macros have |parametric| ilk}
-
-@ The names of modules are stored in |byte_mem| together
-with the identifier names, but a hash table is not used for them because
-\.{TANGLE} needs to be able to recognize a module name when given a prefix of
-that name. A conventional binary seach tree is used to retrieve module names,
-with fields called |llink| and |rlink| in place of |link| and |ilk|. The
-root of this tree is |rlink[0]|. If |p| is a pointer to a module name,
-|equiv[p]| points to its replacement text, just as in simple and parametric
-macros, unless this replacement text has not yet been defined (in which case
-|equiv[p]=0|).
-
-@d llink==link {left link in binary search tree for module names}
-@d rlink==ilk {right link in binary search tree for module names}
-
-@<Set init...@>=
-rlink[0]:=0; {the binary search tree starts out with nothing in it}
-equiv[0]:=0; {the undefined module has no replacement text}
-
-@ Here is a little procedure that prints the text of a given name.
-
-@p procedure print_id(@!p:name_pointer); {print identifier or module name}
-var k:0..max_bytes; {index into |byte_mem|}
-@!w:0..ww-1; {segment of |byte_mem|}
-begin if p>=name_ptr then print('IMPOSSIBLE')
-else begin w:=p mod ww;
- for k:=byte_start[p] to byte_start[p+ww]-1 do print(xchr[byte_mem[w,k]]);
- end;
-end;
-
-@* Searching for identifiers.
-The hash table described above is updated by the |id_lookup| procedure,
-which finds a given identifier and returns a pointer to its index in
-|byte_start|. If the identifier was not already present, it is inserted with
-a given |ilk| code; and an error message is printed if the identifier is being
-doubly defined.
-
-Because of the way \.{TANGLE}'s scanning mechanism works, it is most convenient
-to let |id_lookup| search for an identifier that is present in the |buffer|
-array. Two other global variables specify its position in the buffer: the
-first character is |buffer[id_first]|, and the last is |buffer[id_loc-1]|.
-Furthermore, if the identifier is really a string, the global variable
-|double_chars| tells how many of the characters in the buffer appear
-twice (namely \.{@@@@} and \.{""}), since this additional information makes
-it easy to calculate the true length of the string. The final double-quote
-of the string is not included in its ``identifier,'' but the first one is,
-so the string length is |id_loc-id_first-double_chars-1|.
-
-We have mentioned that |normal| identifiers belong to two hash tables,
-one for their true names as they appear in the \.{WEB} file and the other
-when they have been reduced to their first |unambig_length| characters.
-The hash tables are kept by the method of simple chaining, where the
-heads of the individual lists appear in the |hash| and |chop_hash| arrays.
-If |h| is a hash code, the primary hash table list starts at |hash[h]| and
-proceeds through |link| pointers; the secondary hash table list starts at
-|chop_hash[h]| and proceeds through |equiv| pointers. Of course, the same
-identifier will probably have two different values of |h|.
-
-The |id_lookup| procedure uses an auxiliary array called |chopped_id| to
-contain up to |unambig_length| characters of the current identifier, if
-it is necessary to compute the secondary hash code. (This array could be
-declared local to |id_lookup|, but in general we are making all array
-declarations global in this program, because some compilers and some machine
-architectures make dynamic array allocation inefficient.)
-
-@<Glob...@>=
-@!id_first:0..buf_size; {where the current identifier begins in the buffer}
-@!id_loc:0..buf_size; {just after the current identifier in the buffer}
-@!double_chars:0..buf_size; {correction to length in case of strings}
-@#
-@!hash,@!chop_hash:array [0..hash_size] of sixteen_bits; {heads of hash lists}
-@!chopped_id:array [0..unambig_length] of ASCII_code; {chopped identifier}
-
-@ Initially all the hash lists are empty.
-
-@<Local variables for init...@>=
-@!h:0..hash_size; {index into hash-head arrays}
-
-@ @<Set init...@>=
-for h:=0 to hash_size-1 do
- begin hash[h]:=0; chop_hash[h]:=0;
- end;
-
-@ Here now is the main procedure for finding identifiers (and strings).
-The parameter |t| is set to |normal| except when the identifier is
-a macro name that is just being defined; in the latter case, |t| will be
-|numeric|, |simple|, or |parametric|.
-
-@p function id_lookup(@!t:eight_bits):name_pointer; {finds current identifier}
-label found, not_found;
-var c:eight_bits; {byte being chopped}
-@!i:0..buf_size; {index into |buffer|}
-@!h:0..hash_size; {hash code}
-@!k:0..max_bytes; {index into |byte_mem|}
-@!w:0..ww-1; {segment of |byte_mem|}
-@!l:0..buf_size; {length of the given identifier}
-@!p,@!q:name_pointer; {where the identifier is being sought}
-@!s:0..unambig_length; {index into |chopped_id|}
-begin l:=id_loc-id_first; {compute the length}
-@<Compute the hash code |h|@>;
-@<Compute the name location |p|@>;
-if (p=name_ptr)or(t<>normal) then
- @<Update the tables and check for possible errors@>;
-id_lookup:=p;
-end;
-
-@ A simple hash code is used: If the sequence of
-ASCII codes is $c_1c_2\ldots c_m$, its hash value will be
-$$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$
-
-@<Compute the hash...@>=
-h:=buffer[id_first]; i:=id_first+1;
-while i<id_loc do
- begin h:=(h+h+buffer[i]) mod hash_size; incr(i);
- end
-
-@ If the identifier is new, it will be placed in position |p=name_ptr|,
-otherwise |p| will point to its existing location.
-
-@<Compute the name location...@>=
-p:=hash[h];
-while p<>0 do
- begin if length(p)=l then
- @<Compare name |p| with current identifier, |goto found| if equal@>;
- p:=link[p];
- end;
-p:=name_ptr; {the current identifier is new}
-link[p]:=hash[h]; hash[h]:=p; {insert |p| at beginning of hash list}
-found:
-
-@ @<Compare name |p|...@>=
-begin i:=id_first; k:=byte_start[p]; w:=p mod ww;
-while (i<id_loc)and(buffer[i]=byte_mem[w,k]) do
- begin incr(i); incr(k);
- end;
-if i=id_loc then goto found; {all characters agree}
-end
-
-@ @<Update the tables...@>=
-begin if ((p<>name_ptr)and(t<>normal)and(ilk[p]=normal)) or
- ((p=name_ptr)and(t=normal)and(buffer[id_first]<>"""")) then
- @<Compute the secondary hash code |h| and put the first characters
- into the auxiliary array |chopped_id|@>;
-if p<>name_ptr then
- @<Give double-definition error, if necessary, and change |p| to type |t|@>
-else @<Enter a new identifier into the table at position |p|@>;
-end
-
-@ The following routine, which is called into play when it is necessary to
-look at the secondary hash table, computes the same hash function as before
-(but on the chopped data), and places a zero after the chopped identifier
-in |chopped_id| to serve as a convenient sentinel.
-
-@<Compute the secondary...@>=
-begin i:=id_first; s:=0; h:=0;
-while (i<id_loc)and(s<unambig_length) do
- begin if buffer[i]<>"_" then
- begin if buffer[i]>="a" then chopped_id[s]:=buffer[i]-@'40
- else chopped_id[s]:=buffer[i];
- h:=(h+h+chopped_id[s]) mod hash_size; incr(s);
- end;
- incr(i);
- end;
-chopped_id[s]:=0;
-end
-
-@ If a nonnumeric macro has appeared before it was defined, \.{TANGLE}
-will still work all right; after all, such behavior is typical of the
-replacement texts for modules, which act very much like macros.
-However, an undefined numeric macro may not be used on the right-hand
-side of another numeric macro definition, so \.{TANGLE} finds it
-simplest to make a blanket rule that numeric macros should be defined
-before they are used. The following routine gives an error message and
-also fixes up any damage that may have been caused.
-
-@<Give double...@>= {now |p<>name_ptr| and |t<>normal|}
-begin if ilk[p]=normal then
- begin if t=numeric then err_print('! This identifier has already appeared');
-@.This identifier has already...@>
- @<Remove |p| from secondary hash table@>;
- end
-else err_print('! This identifier was defined before');
-@.This identifier was defined...@>
-ilk[p]:=t;
-end
-
-@ When we have to remove a secondary hash entry, because a |normal| identifier
-is changing to another |ilk|, the hash code |h| and chopped identifier have
-already been computed.
-
-@<Remove |p| from secondary...@>=
-q:=chop_hash[h];
-if q=p then chop_hash[h]:=equiv[p]
-else begin while equiv[q]<>p do q:=equiv[q];
- equiv[q]:=equiv[p];
- end
-
-@ The following routine could make good use of a generalized |pack| procedure
-that puts items into just part of a packed array instead of the whole thing.
-
-@<Enter a new identifier...@>=
-begin if (t=normal)and(buffer[id_first]<>"""") then
- @<Check for ambiguity and update secondary hash@>;
-w:=name_ptr mod ww; k:=byte_ptr[w];
-if k+l>max_bytes then overflow('byte memory');
-if name_ptr>max_names-ww then overflow('name');
-i:=id_first; {get ready to move the identifier into |byte_mem|}
-while i<id_loc do
- begin byte_mem[w,k]:=buffer[i]; incr(k); incr(i);
- end;
-byte_ptr[w]:=k; byte_start[name_ptr+ww]:=k; incr(name_ptr);
-if buffer[id_first]<>"""" then ilk[p]:=t
-else @<Define and output a new string of the pool@>;
-end
-
-@ @<Check for ambig...@>=
-begin q:=chop_hash[h];
-while q<>0 do
- begin @<Check if |q| conflicts with |p|@>;
- q:=equiv[q];
- end;
-equiv[p]:=chop_hash[h]; chop_hash[h]:=p; {put |p| at front of secondary list}
-end
-
-@ @<Check if |q| conflicts...@>=
-begin k:=byte_start[q]; s:=0; w:=q mod ww;
-while (k<byte_start[q+ww]) and (s<unambig_length) do
- begin c:=byte_mem[w,k];
- if c<>"_" then
- begin if c>="a" then c:=c-@'40; {merge lowercase with uppercase}
- if chopped_id[s]<>c then goto not_found;
- incr(s);
- end;
- incr(k);
- end;
-if (k=byte_start[q+ww])and(chopped_id[s]<>0) then goto not_found;
-print_nl('! Identifier conflict with ');
-@.Identifier conflict...@>
-for k:=byte_start[q] to byte_start[q+ww]-1 do print(xchr[byte_mem[w,k]]);
-error; q:=0; {only one conflict will be printed, since |equiv[0]=0|}
-not_found:
-end
-
-@ We compute the string pool check sum by working modulo a prime number
-that is large but not so large that overflow might occur.
-
-@d check_sum_prime==@'3777777667 {$2^{29}-73$}
-@^preprocessed strings@>
-
-@<Define and output a new string...@>=
-begin ilk[p]:=numeric; {strings are like numeric macros}
-if l-double_chars=2 then {this string is for a single character}
- equiv[p]:=buffer[id_first+1]+1073741824
-else begin equiv[p]:=string_ptr+1073741824;
- l:=l-double_chars-1;
- if l>99 then err_print('! Preprocessed string is too long');
-@.Preprocessed string is too long@>
- incr(string_ptr);
- write(pool,xchr["0"+l div 10],xchr["0"+l mod 10]); {output the length}
- pool_check_sum:=pool_check_sum+pool_check_sum+l;
- while pool_check_sum>check_sum_prime do
- pool_check_sum:=pool_check_sum-check_sum_prime;
- i:=id_first+1;
- while i<id_loc do
- begin write(pool,xchr[buffer[i]]); {output characters of string}
- pool_check_sum:=pool_check_sum+pool_check_sum+buffer[i];
- while pool_check_sum>check_sum_prime do
- pool_check_sum:=pool_check_sum-check_sum_prime;
- if (buffer[i]="""") or (buffer[i]="@@") then
- i:=i+2 {omit second appearance of doubled character}
- else incr(i);
- end;
- write_ln(pool);
- end;
-end
-
-@* Searching for module names.
-The |mod_lookup| procedure finds the module name |mod_text[1..l]| in the
-search tree, after inserting it if necessary, and returns a pointer to
-where it was found.
-
-@<Glob...@>=
-@!mod_text:array [0..longest_name] of ASCII_code; {name being sought for}
-
-@ According to the rules of \.{WEB}, no module name
-should be a proper prefix of another, so a ``clean'' comparison should
-occur between any two names. The result of |mod_lookup| is 0 if this
-prefix condition is violated. An error message is printed when such violations
-are detected during phase two of \.{WEAVE}.
-
-@d less=0 {the first name is lexicographically less than the second}
-@d equal=1 {the first name is equal to the second}
-@d greater=2 {the first name is lexicographically greater than the second}
-@d prefix=3 {the first name is a proper prefix of the second}
-@d extension=4 {the first name is a proper extension of the second}
-
-@p function mod_lookup(@!l:sixteen_bits):name_pointer; {finds module name}
-label found;
-var c:less..extension; {comparison between two names}
-@!j:0..longest_name; {index into |mod_text|}
-@!k:0..max_bytes; {index into |byte_mem|}
-@!w:0..ww-1; {segment of |byte_mem|}
-@!p:name_pointer; {current node of the search tree}
-@!q:name_pointer; {father of node |p|}
-begin c:=greater; q:=0; p:=rlink[0]; {|rlink[0]| is the root of the tree}
-while p<>0 do
- begin @<Set \(|c| to the result of comparing the given name to
- name |p|@>;
- q:=p;
- if c=less then p:=llink[q]
- else if c=greater then p:=rlink[q]
- else goto found;
- end;
-@<Enter a new module name into the tree@>;
-found: if c<>equal then
- begin err_print('! Incompatible section names'); p:=0;
-@.Incompatible module names@>
- end;
-mod_lookup:=p;
-end;
-
-@ @<Enter a new module name...@>=
-w:=name_ptr mod ww; k:=byte_ptr[w];
-if k+l>max_bytes then overflow('byte memory');
-if name_ptr>max_names-ww then overflow('name');
-p:=name_ptr;
-if c=less then llink[q]:=p else rlink[q]:=p;
-llink[p]:=0; rlink[p]:=0; c:=equal; equiv[p]:=0;
-for j:=1 to l do byte_mem[w,k+j-1]:=mod_text[j];
-byte_ptr[w]:=k+l; byte_start[name_ptr+ww]:=k+l; incr(name_ptr);
-
-@ @<Set \(|c|...@>=
-begin k:=byte_start[p]; w:=p mod ww; c:=equal; j:=1;
-while (k<byte_start[p+ww]) and (j<=l) and (mod_text[j]=byte_mem[w,k]) do
- begin incr(k); incr(j);
- end;
-if k=byte_start[p+ww] then
- if j>l then c:=equal
- else c:=extension
-else if j>l then c:=prefix
-else if mod_text[j]<byte_mem[w,k] then c:=less
-else c:=greater;
-end
-
-@ The |prefix_lookup| procedure is supposed to find exactly one module
-name that has |mod_text[1..l]| as a prefix. Actually the algorithm silently
-accepts also the situation that some module name is a prefix of
-|mod_text[1..l]|, because the user who painstakingly typed in more than
-necessary probably doesn't want to be told about the wasted effort.
-
-@p function prefix_lookup(@!l:sixteen_bits):name_pointer; {finds name extension}
-var c:less..extension; {comparison between two names}
-@!count:0..max_names; {the number of hits}
-@!j:0..longest_name; {index into |mod_text|}
-@!k:0..max_bytes; {index into |byte_mem|}
-@!w:0..ww-1; {segment of |byte_mem|}
-@!p:name_pointer; {current node of the search tree}
-@!q:name_pointer; {another place to resume the search after one branch is done}
-@!r:name_pointer; {extension found}
-begin q:=0; p:=rlink[0]; count:=0; r:=0; {begin search at root of tree}
-while p<>0 do
- begin @<Set \(|c|...@>;
- if c=less then p:=llink[p]
- else if c=greater then p:=rlink[p]
- else begin r:=p; incr(count); q:=rlink[p]; p:=llink[p];
- end;
- if p=0 then
- begin p:=q; q:=0;
- end;
- end;
-if count<>1 then
- if count=0 then err_print('! Name does not match')
-@.Name does not match@>
- else err_print('! Ambiguous prefix');
-@.Ambiguous prefix@>
-prefix_lookup:=r; {the result will be 0 if there was no match}
-end;
-
-@* Tokens.
-Replacement texts, which represent \PASCAL\ code in a compressed format,
-appear in |tok_mem| as mentioned above. The codes in
-these texts are called `tokens'; some tokens occupy two consecutive
-eight-bit byte positions, and the others take just one byte.
-
-If $p>0$ points to a replacement text, |tok_start[p]| is the |tok_mem| position
-of the first eight-bit code of that text. If |text_link[p]=0|,
-this is the replacement text for a macro, otherwise it is the replacement
-text for a module. In the latter case |text_link[p]| is either equal to
-|module_flag|, which means that there is no further text for this module, or
-|text_link[p]| points to a
-continuation of this replacement text; such links are created when
-several modules have \PASCAL\ texts with the same name, and they also
-tie together all the \PASCAL\ texts of unnamed modules.
-The replacement text pointer for the first unnamed module
-appears in |text_link[0]|, and the most recent such pointer is |last_unnamed|.
-
-@d module_flag==max_texts {final |text_link| in module replacement texts}
-
-@<Glob...@>=
-@!last_unnamed:text_pointer; {most recent replacement text of unnamed module}
-
-@ @<Set init...@>= last_unnamed:=0; text_link[0]:=0;
-
-@ If the first byte of a token is less than @'200, the token occupies a
-single byte. Otherwise we make a sixteen-bit token by combining two consecutive
-bytes |a| and |b|. If |@'200<=a<@'250|, then $(a-@'200)\times2^8+b$ points
-to an identifier; if |@'250<=a<@'320|, then
-$(a-@'250)\times2^8+b$ points to a module name; otherwise, i.e., if
-|@'320<=a<@'400|, then $(a-@'320)\times2^8+b$ is the number of the module
-in which the current replacement text appears.
-
-Codes less than @'200 are 7-bit ASCII codes that represent themselves.
-In particular, a single-character identifier like `|x|' will be a one-byte
-token, while all longer identifiers will occupy two bytes.
-
-Some of the 7-bit ASCII codes will not be present, however, so we can
-use them for special purposes. The following symbolic names are used:
-
-\yskip\hang |param| denotes insertion of a parameter. This occurs only in
-the replacement texts of parametric macros, outside of single-quoted strings
-in those texts.
-
-\hang |begin_comment| denotes \.{@@\{}, which will become either
-\.{\{} or \.{[}.
-
-\hang |end_comment| denotes \.{@@\}}, which will become either
-\.{\}} or \.{]}.
-
-\hang |octal| denotes the \.{@@\'} that precedes an octal constant.
-
-\hang |hex| denotes the \.{@@"} that precedes a hexadecimal constant.
-
-\hang |check_sum| denotes the \.{@@\char'44} that denotes the string pool
-check sum.
-
-\hang |join| denotes the concatenation of adjacent items with no
-space or line breaks allowed between them (the \.{@@\&} operation of \.{WEB}).
-
-\hang |double_dot| denotes `\.{..}' in \PASCAL.
-
-\hang |verbatim| denotes the \.{@@=} that begins a verbatim \PASCAL\ string.
-It is also used for the end of the string.
-
-\hang |force_line| denotes the \.{@@\\} that forces a new line in the
-\PASCAL\ output.
-@^ASCII code@>
-
-@d param=0 {ASCII null code will not appear}
-@d verbatim=@'2 {extended ASCII alpha should not appear}
-@d force_line=@'3 {extended ASCII beta should not appear}
-@d begin_comment=@'11 {ASCII tab mark will not appear}
-@d end_comment=@'12 {ASCII line feed will not appear}
-@d octal=@'14 {ASCII form feed will not appear}
-@d hex=@'15 {ASCII carriage return will not appear}
-@d double_dot=@'40 {ASCII space will not appear except in strings}
-@d check_sum=@'175 {will not be confused with right brace}
-@d join=@'177 {ASCII delete will not appear}
-
-@ The following procedure is used to enter a two-byte value into
-|tok_mem| when a replacement text is being generated.
-
-@p procedure store_two_bytes(@!x:sixteen_bits);
- {stores high byte, then low byte}
-begin if tok_ptr[z]+2>max_toks then overflow('token');
-tok_mem[z,tok_ptr[z]]:=x div@'400; {this could be done by a shift command}
-tok_mem[z,tok_ptr[z]+1]:=x mod@'400; {this could be done by a logical and}
-tok_ptr[z]:=tok_ptr[z]+2;
-end;
-
-@ When \.{TANGLE} is being operated in debug mode, it has a procedure to display
-a replacement text in symbolic form. This procedure has not been spruced up to
-generate a real great format, but at least the results are not as bad as
-a memory dump.
-
-@p @!debug procedure print_repl(@!p:text_pointer);
-var k:0..max_toks; {index into |tok_mem|}
-@!a: sixteen_bits; {current byte(s)}
-@!zp: 0..zz-1; {segment of |tok_mem| being accessed}
-begin if p>=text_ptr then print('BAD')
-else begin k:=tok_start[p]; zp:=p mod zz;
- while k<tok_start[p+zz] do
- begin a:=tok_mem[zp,k];
- if a>=@'200 then @<Display two-byte token starting with |a|@>
- else @<Display one-byte token |a|@>;
- incr(k);
- end;
- end;
-end;
-gubed
-
-@ @<Display two-byte...@>=
-begin incr(k);
-if a<@'250 then {identifier or string}
- begin a:=(a-@'200)*@'400+tok_mem[zp,k]; print_id(a);
- if byte_mem[a mod ww,byte_start[a]]="""" then print('"')
- else print(' ');
- end
-else if a<@'320 then {module name}
- begin print('@@<'); print_id((a-@'250)*@'400+tok_mem[zp,k]);
- print('@@>');
- end
-else begin a:=(a-@'320)*@'400+tok_mem[zp,k]; {module number}
- print('@@',xchr["{"],a:1,'@@',xchr["}"]); {can't use right brace
- between \&{debug} and \&{gubed}}
- end;
-end
-
-@ @<Display one-byte...@>=
-case a of
-begin_comment: print('@@',xchr["{"]);
-end_comment: print('@@',xchr["}"]); {can't use right brace
- between \&{debug} and \&{gubed}}
-octal: print('@@''');
-hex: print('@@"');
-check_sum: print('@@$');
-param: print('#');
-"@@": print('@@@@');
-verbatim: print('@@=');
-force_line: print('@@\');
-othercases print(xchr[a])
-endcases
-
-@* Stacks for output.
-Let's make sure that our data structures contain enough information to
-produce the entire \PASCAL\ program as desired, by working next on the
-algorithms that actually do produce that program.
-
-@ The output process uses a stack to keep track of what is going on at
-different ``levels'' as the macros are being expanded.
-Entries on this stack have five parts:
-
-\yskip\hang |end_field| is the |tok_mem| location where the replacement
-text of a particular level will end;
-
-\hang |byte_field| is the |tok_mem| location from which the next token
-on a particular level will be read;
-
-\hang |name_field| points to the name corresponding to a particular level;
-
-\hang |repl_field| points to the replacement text currently being read
-at a particular level;
-
-\hang |mod_field| is the module number, or zero if this is a macro.
-
-\yskip\noindent The current values of these five quantities are referred to
-quite frequently, so they are stored in a separate place instead of in
-the |stack| array. We call the current values |cur_end|, |cur_byte|,
-|cur_name|, |cur_repl|, and |cur_mod|.
-
-The global variable |stack_ptr| tells how many levels of output are
-currently in progress. The end of all output occurs when the stack is
-empty, i.e., when |stack_ptr=0|.
-
-@<Types...@>=
-@t\4@>@!output_state=record
- @!end_field: sixteen_bits; {ending location of replacement text}
- @!byte_field: sixteen_bits; {present location within replacement text}
- @!name_field: name_pointer; {|byte_start| index for text being output}
- @!repl_field: text_pointer; {|tok_start| index for text being output}
- @!mod_field: 0..@'27777; {module number or zero if not a module}
- end;
-
-@ @d cur_end==cur_state.end_field {current ending location in |tok_mem|}
-@d cur_byte==cur_state.byte_field {location of next output byte in |tok_mem|}
-@d cur_name==cur_state.name_field {pointer to current name being expanded}
-@d cur_repl==cur_state.repl_field {pointer to current replacement text}
-@d cur_mod==cur_state.mod_field {current module number being expanded}
-
-@<Globals...@>=
-@!cur_state : output_state; {|cur_end|, |cur_byte|, |cur_name|,
- |cur_repl|, |cur_mod|}
-@!stack : array [1..stack_size] of output_state; {info for non-current levels}
-@!stack_ptr: 0..stack_size; {first unused location in the output state stack}
-
-@ It is convenient to keep a global variable |zo| equal to |cur_repl mod zz|.
-
-@<Glob...@>=
-@!zo:0..zz-1; {the segment of |tok_mem| from which output is coming}
-
-@ Parameters must also be stacked. They are placed in
-|tok_mem| just above the other replacement texts, and dummy parameter
-`names' are placed in |byte_start| just after the other names.
-The variables |text_ptr| and |tok_ptr[z]| essentially serve as parameter
-stack pointers during the output phase, so there is no need for a separate
-data structure to handle this problem.
-
-@ There is an implicit stack corresponding to meta-comments that are output
-via \.{@@\{} and \.{@@\}}. But this stack need not be represented in detail,
-because we only need to know whether it is empty or not. A global variable
-|brace_level| tells how many items would be on this stack if it were present.
-
-@<Globals...@>=
-@!brace_level: eight_bits; {current depth of $\.{@@\{}\ldots\.{@@\}}$ nesting}
-
-@ To get the output process started, we will perform the following
-initialization steps. We may assume that |text_link[0]| is nonzero, since it
-points to the \PASCAL\ text in the first unnamed module that generates
-code; if there are no such modules, there is nothing to output, and an
-error message will have been generated before we do any of the initialization.
-
-@<Initialize the output stacks@>=
-stack_ptr:=1; brace_level:=0; cur_name:=0; cur_repl:=text_link[0];
-zo:=cur_repl mod zz; cur_byte:=tok_start[cur_repl];
-cur_end:=tok_start[cur_repl+zz]; cur_mod:=0;
-
-@ When the replacement text for name |p| is to be inserted into the output,
-the following subroutine is called to save the old level of output and get
-the new one going.
-
-@p procedure push_level(@!p:name_pointer); {suspends the current level}
-begin if stack_ptr=stack_size then overflow('stack')
-else begin stack[stack_ptr]:=cur_state; {save |cur_end|, |cur_byte|, etc.}
- incr(stack_ptr);
- cur_name:=p; cur_repl:=equiv[p]; zo:=cur_repl mod zz;
- cur_byte:=tok_start[cur_repl]; cur_end:=tok_start[cur_repl+zz];
- cur_mod:=0;
- end;
-end;
-
-@ When we come to the end of a replacement text, the |pop_level| subroutine
-does the right thing: It either moves to the continuation of this replacement
-text or returns the state to the most recently stacked level. Part of this
-subroutine, which updates the parameter stack, will be given later when we
-study the parameter stack in more detail.
-
-@p procedure pop_level; {do this when |cur_byte| reaches |cur_end|}
-label exit;
-begin if text_link[cur_repl]=0 then {end of macro expansion}
- begin if ilk[cur_name]=parametric then
- @<Remove a parameter from the parameter stack@>;
- end
-else if text_link[cur_repl]<module_flag then {link to a continuation}
- begin cur_repl:=text_link[cur_repl]; {we will stay on the same level}
- zo:=cur_repl mod zz;
- cur_byte:=tok_start[cur_repl]; cur_end:=tok_start[cur_repl+zz];
- return;
- end;
-decr(stack_ptr); {we will go down to the previous level}
-if stack_ptr>0 then
- begin cur_state:=stack[stack_ptr]; zo:=cur_repl mod zz;
- end;
-exit: end;
-
-@ The heart of the output procedure is the |get_output| routine, which produces
-the next token of output that is not a reference to a macro. This procedure
-handles all the stacking and unstacking that is necessary. It returns the
-value |number| if the next output has a numeric value (the value of a
-numeric macro or string), in which case |cur_val| has been set to the
-number in question. The procedure also returns the value |module_number|
-if the next output begins or ends the replacement text of some module,
-in which case |cur_val| is that module's number (if beginning) or the
-negative of that value (if ending). And it returns the value |identifier|
-if the next output is an identifier of length two or more, in which case
-|cur_val| points to that identifier name.
-
-@d number=@'200 {code returned by |get_output| when next output is numeric}
-@d module_number=@'201 {code returned by |get_output| for module numbers}
-@d identifier=@'202 {code returned by |get_output| for identifiers}
-
-@<Globals...@>=
-@!cur_val:integer; {additional information corresponding to output token}
-
-@ If |get_output| finds that no more output remains, it returns the value zero.
-
-@p function get_output:sixteen_bits; {returns next token after macro expansion}
-label restart, done, found;
-var a:sixteen_bits; {value of current byte}
-@!b:eight_bits; {byte being copied}
-@!bal:sixteen_bits; {excess of \.( versus \.) while copying a parameter}
-@!k:0..max_bytes; {index into |byte_mem|}
-@!w:0..ww-1; {segment of |byte_mem|}
-begin restart: if stack_ptr=0 then
- begin a:=0; goto found;
- end;
-if cur_byte=cur_end then
- begin cur_val:=-cur_mod; pop_level;
- if cur_val=0 then goto restart;
- a:=module_number; goto found;
- end;
-a:=tok_mem[zo,cur_byte]; incr(cur_byte);
-if a<@'200 then {one-byte token}
- if a=param then
- @<Start scanning current macro parameter, |goto restart|@>
- else goto found;
-a:=(a-@'200)*@'400+tok_mem[zo,cur_byte]; incr(cur_byte);
-if a<@'24000 then {|@'24000=(@'250-@'200)*@'400|}
- @<Expand macro |a| and |goto found|, or |goto restart| if no output found@>;
-if a<@'50000 then {|@'50000=(@'320-@'200)*@'400|}
- @<Expand module |a-@'24000|, |goto restart|@>;
-cur_val:=a-@'50000; a:=module_number; cur_mod:=cur_val;
-found:
-@!debug if trouble_shooting then debug_help;@;@+gubed@/
-get_output:=a;
-end;
-
-@ The user may have forgotten to give any \PASCAL\ text for a module name,
-or the \PASCAL\ text may have been associated with a different name by mistake.
-
-@<Expand module |a-...@>=
-begin a:=a-@'24000;
-if equiv[a]<>0 then push_level(a)
-else if a<>0 then
- begin print_nl('! Not present: <'); print_id(a); print('>'); error;
-@.Not present: <section name>@>
- end;
-goto restart;
-end
-
-@ @<Expand macro ...@>=
-begin case ilk[a] of
-normal: begin cur_val:=a; a:=identifier;
- end;
-numeric: begin cur_val:=equiv[a]-1073741824; a:=number;
- end;
-simple: begin push_level(a); goto restart;
- end;
-parametric: begin @<Put a parameter on the parameter stack,
- or |goto restart| if error occurs@>;
- push_level(a); goto restart;
- end;
-othercases confusion('output')
-endcases;@/
-goto found;
-end
-
-@ We come now to the interesting part, the job of putting a parameter on
-the parameter stack. First we pop the stack if necessary until getting to
-a level that hasn't ended. Then the next character must be a `\.(';
-and since parentheses are balanced on each level, the entire parameter must
-be present, so we can copy it without difficulty.
-
-@<Put a parameter...@>=
-while (cur_byte=cur_end)and(stack_ptr>0) do pop_level;
-if (stack_ptr=0)or(tok_mem[zo,cur_byte]<>"(") then
- begin print_nl('! No parameter given for '); print_id(a); error;
-@.No parameter given for macro@>
- goto restart;
- end;
-@<Copy the parameter into |tok_mem|@>;
-equiv[name_ptr]:=text_ptr; ilk[name_ptr]:=simple; w:=name_ptr mod ww;
-k:=byte_ptr[w];
-@!debug if k=max_bytes then overflow('byte memory');
-byte_mem[w,k]:="#"; incr(k); byte_ptr[w]:=k;
-gubed {this code has set the parameter identifier for debugging printouts}
-if name_ptr>max_names-ww then overflow('name');
-byte_start[name_ptr+ww]:=k; incr(name_ptr);
-if text_ptr>max_texts-zz then overflow('text');
-text_link[text_ptr]:=0; tok_start[text_ptr+zz]:=tok_ptr[z];
-incr(text_ptr);
-z:=text_ptr mod zz
-
-@ The |pop_level| routine undoes the effect of parameter-pushing when
-a parameter macro is finished:
-
-@<Remove a parameter...@>=
-begin decr(name_ptr); decr(text_ptr);
-z:=text_ptr mod zz;
-stat if tok_ptr[z]>max_tok_ptr[z] then max_tok_ptr[z]:=tok_ptr[z];
-tats {the maximum value of |tok_ptr| occurs just before parameter popping}
-tok_ptr[z]:=tok_start[text_ptr];
-@!debug decr(byte_ptr[name_ptr mod ww]);@+gubed
-end
-
-@ When a parameter occurs in a replacement text, we treat it as a simple
-macro in position (|name_ptr-1|):
-
-@<Start scanning...@>=
-begin push_level(name_ptr-1); goto restart;
-end
-
-@ Similarly, a |param| token encountered as we copy a parameter is converted
-into a simple macro call for |name_ptr-1|.
-Some care is needed to handle cases like \\{macro}|(#; print('#)'))|; the
-\.{\#} token will have been changed to |param| outside of strings, but we
-still must distinguish `real' parentheses from those in strings.
-
-@d app_repl(#)==begin if tok_ptr[z]=max_toks then overflow('token');
- tok_mem[z,tok_ptr[z]]:=#; incr(tok_ptr[z]); end
-
-@<Copy the parameter...@>=
-bal:=1; incr(cur_byte); {skip the opening `\.('}
-loop@+ begin b:=tok_mem[zo,cur_byte]; incr(cur_byte);
- if b=param then store_two_bytes(name_ptr+@'77777)
- else begin if b>=@'200 then
- begin app_repl(b);
- b:=tok_mem[zo,cur_byte]; incr(cur_byte);
- end
- else case b of
- "(": incr(bal);
- ")": begin decr(bal);
- if bal=0 then goto done;
- end;
- "'": repeat app_repl(b);
- b:=tok_mem[zo,cur_byte]; incr(cur_byte);
- until b="'"; {copy string, don't change |bal|}
- othercases do_nothing
- endcases;
- app_repl(b);
- end;
- end;
-done:
-
-@* Producing the output.
-The |get_output| routine above handles most of the complexity of output
-generation, but there are two further considerations that have a nontrivial
-effect on \.{TANGLE}'s algorithms.
-
-First, we want to make sure that the output is broken into lines not
-exceeding |line_length| characters per line, where these breaks occur at
-valid places (e.g., not in the middle of a string or a constant or an
-identifier, not between `\.<' and `\.>', not at a `\.{@@\&}' position
-where quantities are being joined together). Therefore we assemble the
-output into a buffer before deciding where the line breaks will appear.
-However, we make very little attempt to make ``logical'' line breaks that
-would enhance the readability of the output; people are supposed to read
-the input of \.{TANGLE} or the \TeX ed output of \.{WEAVE}, but not the
-tangled-up output. The only concession to readability is that a break after
-a semicolon will be made if possible, since commonly used ``pretty
-printing'' routines give better results in such cases.
-
-Second, we want to decimalize non-decimal constants, and to combine integer
-quantities that are added or subtracted, because \PASCAL\ doesn't allow
-constant expressions in subrange types or in case labels. This means we
-want to have a procedure that treats a construction like \.{(E-15+17)}
-as equivalent to `\.{(E+2)}', while also leaving `\.{(1E-15+17)}' and
-`\.{(E-15+17*y)}' untouched. Consider also `\.{-15+17.5}' versus
-`\.{-15+17..5}'. We shall not combine integers preceding or following
-\.*, \./, \.{div}, \.{mod}, or \.{@@\&}. Note that if |y| has been defined
-to equal $-2$, we must expand `\.{x*y}' into `\.{x*(-2)}'; but `\.{x-y}'
-can expand into `\.{x+2}' and we can even change `\.{x - y mod z}' to
-@^mod@>
-`\.{x + 2 mod z}' because \PASCAL\ has a nonstandard \&{mod} operation!
-
-The following solution to these problems has been adopted: An array
-|out_buf| contains characters that have been generated but not yet output,
-and there are three pointers into this array. One of these, |out_ptr|, is
-the number of characters currently in the buffer, and we will have
-|1<=out_ptr<=line_length| most of the time. The second is |break_ptr|,
-which is the largest value |<=out_ptr| such that we are definitely entitled
-to end a line by outputting the characters |out_buf[1..(break_ptr-1)]|;
-we will always have |break_ptr<=line_length|. Finally, |semi_ptr| is either
-zero or the largest known value of a legal break after a semicolon or comment
-on the current line; we will always have |semi_ptr<=break_ptr|.
-
-@<Globals...@>=
-@!out_buf: array [0..out_buf_size] of ASCII_code; {assembled characters}
-@!out_ptr: 0..out_buf_size; {first available place in |out_buf|}
-@!break_ptr: 0..out_buf_size; {last breaking place in |out_buf|}
-@!semi_ptr: 0..out_buf_size; {last semicolon breaking place in |out_buf|}
-
-@ Besides having those three pointers,
-the output process is in one of several states:
-
-\yskip\hang |num_or_id| means that the last item in the buffer is a number or
-identifier, hence a blank space or line break must be inserted if the next
-item is also a number or identifier.
-
-\yskip\hang |unbreakable| means that the last item in the buffer was followed
-by the \.{@@\&} operation that inhibits spaces between it and the next item.
-
-\yskip\hang |sign| means that the last item in the buffer is to be followed
-by \.+ or \.-, depending on whether |out_app| is positive or negative.
-
-\yskip\hang |sign_val| means that the decimal equivalent of
-$\vert|out_val|\vert$ should be appended to the buffer. If |out_val<0|,
-or if |out_val=0| and |last_sign<0|, the number should be preceded by a minus
-sign. Otherwise it should be preceded by the character |out_sign| unless
-|out_sign=0|; the |out_sign| variable is either 0 or \.{"\ "} or \.{"+"}.
-
-\yskip\hang |sign_val_sign| is like |sign_val|, but also append \.+ or \.-
-afterwards, depending on whether |out_app| is positive or negative.
-
-\yskip\hang |sign_val_val| is like |sign_val|, but also append the decimal
-equivalent of |out_app| including its sign, using |last_sign| in case
-|out_app=0|.
-
-\yskip\hang |misc| means none of the above.
-
-\yskip\noindent
-For example, the output buffer and output state run through the following
-sequence as we generate characters from `\.{(x-15+19-2)}':
-$$\vbox{\halign{$\hfil#\hfil$\quad&#\hfil&\quad\hfil#\hfil&\quad
-\hfil#\hfil&\quad\hfil#\hfil&\quad\hfil#\hfil\quad&\hfil#\hfil\cr
-output&|out_buf|&|out_state|&|out_sign|&|out_val|&|out_app|&|last_sign|\cr
-\noalign{\vskip 3pt}
-(&\.(&|misc|\cr
-x&\.{(x}&|num_or_id|\cr
--&\.{(x}&|sign|&&&$-1$&$-1$\cr
-15&\.{(x}&|sign_val|&\.{"+"}&$-15$&&$-15$\cr
-+&\.{(x}&|sign_val_sign|&\.{"+"}&$-15$&$+1$&$+1$\cr
-19&\.{(x}&|sign_val_val|&\.{"+"}&$-15$&$+19$&$+1$\cr
--&\.{(x}&|sign_val_sign|&\.{"+"}&$+4$&$-1$&$-1$\cr
-2&\.{(x}&|sign_val_val|&\.{"+"}&$+4$&$-2$&$-2$\cr
-)&\.{(x+2)}&|misc|\cr}}$$
-At each stage we have put as much into the buffer as possible without
-knowing what is coming next. Examples like `\.{x-0.1}' indicate why
-|last_sign| is needed to associate the proper sign with an output of zero.
-
-In states |num_or_id|, |unbreakable|, and |misc| the last item in the buffer
-lies between |break_ptr| and |out_ptr-1|, inclusive; in the other states we
-have |break_ptr=out_ptr|.
-
-The numeric values assigned to |num_or_id|, etc., have been chosen to
-shorten some of the program logic; for example, the program makes use of
-the fact that |sign+2=sign_val_sign|.
-
-@d misc=0 {state associated with special characters}
-@d num_or_id=1 {state associated with numbers and identifiers}
-@d sign=2 {state associated with pending \.+ or \.-}
-@d sign_val=num_or_id+2 {state associated with pending sign and value}
-@d sign_val_sign=sign+2 {|sign_val| followed by another pending sign}
-@d sign_val_val=sign_val+2 {|sign_val| followed by another pending value}
-@d unbreakable=sign_val_val+1 {state associated with \.{@@\&}}
-
-@<Globals...@>=
-@!out_state:eight_bits; {current status of partial output}
-@!out_val,@!out_app:integer; {pending values}
-@!out_sign:ASCII_code; {sign to use if appending |out_val>=0|}
-@!last_sign:-1..+1; {sign to use if appending a zero}
-
-@ During the output process, |line| will equal the number of the next line
-to be output.
-
-@<Initialize the output buffer@>=
-out_state:=misc; out_ptr:=0; break_ptr:=0; semi_ptr:=0; out_buf[0]:=0; line:=1;
-
-@ Here is a routine that is invoked when |out_ptr>line_length|
-or when it is time to flush out the final line. The |flush_buffer| procedure
-often writes out the line up to the current |break_ptr| position, then moves the
-remaining information to the front of |out_buf|. However, it prefers to
-write only up to |semi_ptr|, if the residual line won't be too long.
-
-@d check_break==if out_ptr>line_length then flush_buffer
-
-@p procedure flush_buffer; {writes one line to output file}
-var k:0..out_buf_size; {index into |out_buf|}
-@!b:0..out_buf_size; {value of |break_ptr| upon entry}
-begin b:=break_ptr;
-if (semi_ptr<>0)and(out_ptr-semi_ptr<=line_length) then break_ptr:=semi_ptr;
-for k:=1 to break_ptr do write(Pascal_file,xchr[out_buf[k-1]]);
-write_ln(Pascal_file); incr(line);
-if line mod 100 = 0 then
- begin print('.');
- if line mod 500 = 0 then print(line:1);
- update_terminal; {progress report}
- end;
-if break_ptr<out_ptr then
- begin if out_buf[break_ptr]=" " then
- begin incr(break_ptr); {drop space at break}
- if break_ptr>b then b:=break_ptr;
- end;
- for k:=break_ptr to out_ptr-1 do out_buf[k-break_ptr]:=out_buf[k];
- end;
-out_ptr:=out_ptr-break_ptr; break_ptr:=b-break_ptr; semi_ptr:=0;
-if out_ptr>line_length then
- begin err_print('! Long line must be truncated'); out_ptr:=line_length;
-@.Long line must be truncated@>
- end;
-end;
-
-@ @<Empty the last line from the buffer@>=
-break_ptr:=out_ptr; semi_ptr:=0; flush_buffer;
-if brace_level<>0 then
- err_print('! Program ended at brace level ',brace_level:1);
-@.Program ended at brace level n@>
-
-@ Another simple and useful routine appends the decimal equivalent of
-a nonnegative integer to the output buffer.
-
-@d app(#)==begin out_buf[out_ptr]:=#; incr(out_ptr); {append a single character}
- end
-
-@p procedure app_val(@!v:integer); {puts |v| into buffer, assumes |v>=0|}
-var k:0..out_buf_size; {index into |out_buf|}
-begin k:=out_buf_size; {first we put the digits at the very end of |out_buf|}
-repeat out_buf[k]:=v mod 10; v:=v div 10; decr(k);
-until v=0;
-repeat incr(k); app(out_buf[k]+"0");
-until k=out_buf_size; {then we append them, most significant first}
-end;
-
-@ The output states are kept up to date by the output routines, which are
-called |send_out|, |send_val|, and |send_sign|. The |send_out| procedure
-has two parameters: |t| tells the type of information being sent and
-|v| contains the information proper. Some information may also be passed
-in the array |out_contrib|.
-
-\yskip\hang If |t=misc| then |v| is a character to be output.
-
-\hang If |t=str| then |v| is the length of a string or something like `\.{<>}'
-in |out_contrib|.
-
-\hang If |t=ident| then |v| is the length of an identifier in |out_contrib|.
-
-\hang If |t=frac| then |v| is the length of a fraction and/or exponent in
-|out_contrib|.
-
-@d str=1 {|send_out| code for a string}
-@d ident=2 {|send_out| code for an identifier}
-@d frac=3 {|send_out| code for a fraction}
-
-@<Glob...@>=
-@!out_contrib:array[1..line_length] of ASCII_code; {a contribution to |out_buf|}
-
-@ A slightly subtle point in the following code is that the user may ask
-for a |join| operation (i.e., \.{@@\&}) following whatever is being sent
-out. We will see later that |join| is implemented in part by calling
-|send_out(frac,0)|.
-
-@p procedure send_out(@!t:eight_bits; @!v:sixteen_bits);
- {outputs |v| of type |t|}
-label restart;
-var k: 0..line_length; {index into |out_contrib|}
-begin @<Get the buffer ready for appending the new information@>;
-if t<>misc then for k:=1 to v do app(out_contrib[k])
-else app(v);
-check_break;
-if (t=misc)and((v=";")or(v="}")) then
- begin semi_ptr:=out_ptr; break_ptr:=out_ptr;
- end;
-if t>=ident then out_state:=num_or_id {|t=ident| or |frac|}
-else out_state:=misc {|t=str| or |misc|}
-end;
-
-@ Here is where the buffer states for signs and values collapse into simpler
-states, because we are about to append something that doesn't combine with
-the previous integer constants.
-
-We use an ASCII-code trick: Since |","-1="+"| and |","+1="-"|, we have
-|","-c=@t sign of $c$@>|, when $\vert c\vert=1$.
-
-@<Get the buffer ready...@>=
-restart: case out_state of
-num_or_id: if t<>frac then
- begin break_ptr:=out_ptr;
- if t=ident then app(" ");
- end;
-sign: begin app(","-out_app); check_break; break_ptr:=out_ptr;
- end;
-sign_val,sign_val_sign: begin @<Append \(|out_val| to buffer@>;
- out_state:=out_state-2; goto restart;
- end;
-sign_val_val: @<Reduce |sign_val_val| to |sign_val| and |goto restart|@>;
-misc: if t<>frac then break_ptr:=out_ptr;@/
-othercases do_nothing {this is for |unbreakable| state}
-endcases
-
-@ @<Append \(|out_val|...@>=
-if (out_val<0)or((out_val=0)and(last_sign<0)) then app("-")
-else if out_sign>0 then app(out_sign);
-app_val(abs(out_val)); check_break;
-
-@ @<Reduce |sign_val_val|...@>=
-begin if (t=frac)or(@<Contribution is \.* or \./ or \.{DIV} or \.{MOD}@>) then
- begin @<Append \(|out_val| to buffer@>;
- out_sign:="+"; out_val:=out_app;
- end
-else out_val:=out_val+out_app;
-out_state:=sign_val; goto restart;
-end
-
-@ @<Contribution is \.*...@>=
-((t=ident)and(v=3)and@|
- (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@|
- ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) ))or@|
-@^uppercase@>
- ((t=misc)and((v="*")or(v="/")))
-
-@ The following routine is called with $v=\pm1$ when a plus or minus sign is
-appended to the output. It extends \PASCAL\ to allow repeated signs
-(e.g., `\.{--}' is equivalent to `\.+'), rather than to give an error message.
-The signs following `\.E' in real constants are treated as part of a fraction,
-so they are not seen by this routine.
-
-@p procedure send_sign(@!v:integer);
-begin case out_state of
-sign, sign_val_sign: out_app:=out_app*v;
-sign_val:begin out_app:=v; out_state:=sign_val_sign;
- end;
-sign_val_val: begin out_val:=out_val+out_app; out_app:=v;
- out_state:=sign_val_sign;
- end;
-othercases begin break_ptr:=out_ptr; out_app:=v; out_state:=sign;
- end
-endcases;@/
-last_sign:=out_app;
-end;
-
-@ When a (signed) integer value is to be output, we call |send_val|.
-
-@d bad_case=666 {this is a label used below}
-
-@p procedure send_val(@!v:integer); {output the (signed) value |v|}
-label bad_case, {go here if we can't keep |v| in the output state}
- exit;
-begin case out_state of
-num_or_id: begin @<If previous output was \.{DIV} or \.{MOD}, |goto bad_case|@>;
- out_sign:=" "; out_state:=sign_val; out_val:=v; break_ptr:=out_ptr;
- last_sign:=+1;
- end;
-misc: begin @<If previous output was \.* or \./, |goto bad_case|@>;
- out_sign:=0; out_state:=sign_val; out_val:=v; break_ptr:=out_ptr;
- last_sign:=+1;
- end;
-@t\4@>@<Handle cases of |send_val| when |out_state| contains a sign@>@;
-othercases goto bad_case
-endcases;@/
-return;
-bad_case: @<Append the decimal value of |v|, with parentheses if negative@>;
-exit: end;
-
-@ @<Handle cases of |send_val|...@>=
-sign: begin out_sign:="+"; out_state:=sign_val; out_val:=out_app*v;
- end;
-sign_val: begin out_state:=sign_val_val; out_app:=v;
- err_print('! Two numbers occurred without a sign between them');
- end;
-sign_val_sign: begin out_state:=sign_val_val; out_app:=out_app*v;
- end;
-sign_val_val: begin out_val:=out_val+out_app; out_app:=v;
- err_print('! Two numbers occurred without a sign between them');
-@.Two numbers occurred...@>
- end;
-
-@ @<If previous output was \.*...@>=
-if (out_ptr=break_ptr+1)and((out_buf[break_ptr]="*")or(out_buf[break_ptr]="/"))
- then goto bad_case
-
-@ @<If previous output was \.{DIV}...@>=
-if (out_ptr=break_ptr+3)or
- ((out_ptr=break_ptr+4)and(out_buf[break_ptr]=" ")) then
-@^uppercase@>
- if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and
- (out_buf[out_ptr-1]="V"))or @/
- ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and
- (out_buf[out_ptr-1]="D")) then@/ goto bad_case
-
-@ @<Append the decimal value...@>=
-if v>=0 then
- begin if out_state=num_or_id then
- begin break_ptr:=out_ptr; app(" ");
- end;
- app_val(v); check_break; out_state:=num_or_id;
- end
-else begin app("("); app("-"); app_val(-v); app(")"); check_break;
- out_state:=misc;
- end
-
-@* The big output switch.
-To complete the output process, we need a routine that takes the results
-of |get_output| and feeds them to |send_out|, |send_val|, or |send_sign|.
-This procedure `|send_the_output|' will be invoked just once, as follows:
-
-@<Phase II: Output the contents of the compressed tables@>=
-if text_link[0]=0 then
- begin print_nl('! No output was specified.'); mark_harmless;
-@.No output was specified@>
- end
-else begin print_nl('Writing the output file'); update_terminal;@/
- @<Initialize the output stacks@>;
- @<Initialize the output buffer@>;
- send_the_output;@/
- @<Empty the last line...@>;
- print_nl('Done.');
- end
-
-@ A many-way switch is used to send the output:
-
-@d get_fraction=2 {this label is used below}
-
-@p procedure send_the_output;
-label get_fraction, {go here to finish scanning a real constant}
- reswitch, continue;
-var cur_char:eight_bits; {the latest character received}
- @!k:0..line_length; {index into |out_contrib|}
- @!j:0..max_bytes; {index into |byte_mem|}
- @!w:0..ww-1; {segment of |byte_mem|}
- @!n:integer; {number being scanned}
-begin while stack_ptr>0 do
- begin cur_char:=get_output;
- reswitch: case cur_char of
- 0: do_nothing; {this case might arise if output ends unexpectedly}
- @t\4@>@<Cases related to identifiers@>@;
- @t\4@>@<Cases related to constants, possibly leading to
- |get_fraction| or |reswitch|@>@;
- "+","-": send_sign(","-cur_char);
- @t\4@>@<Cases like \.{<>} and \.{:=}@>@;
- "'": @<Send a string, |goto reswitch|@>;
- @<Other printable characters@>: send_out(misc,cur_char);
- @t\4@>@<Cases involving \.{@@\{} and \.{@@\}}@>@;
- join: begin send_out(frac,0); out_state:=unbreakable;
- end;
- verbatim: @<Send verbatim string@>;
- force_line: @<Force a line break@>;
- othercases err_print('! Can''t output ASCII code ',cur_char:1)
-@.Can't output ASCII code n@>
- endcases;@/
- goto continue;
- get_fraction: @<Special code to finish real constants@>;
- continue: end;
-end;
-
-@ @<Cases like \.{<>}...@>=
-and_sign: begin out_contrib[1]:="A"; out_contrib[2]:="N"; out_contrib[3]:="D";
-@^uppercase@>
- send_out(ident,3);
- end;
-not_sign: begin out_contrib[1]:="N"; out_contrib[2]:="O"; out_contrib[3]:="T";
- send_out(ident,3);
- end;
-set_element_sign: begin out_contrib[1]:="I"; out_contrib[2]:="N";
- send_out(ident,2);
- end;
-or_sign: begin out_contrib[1]:="O"; out_contrib[2]:="R"; send_out(ident,2);
- end;
-left_arrow: begin out_contrib[1]:=":"; out_contrib[2]:="="; send_out(str,2);
- end;
-not_equal: begin out_contrib[1]:="<"; out_contrib[2]:=">"; send_out(str,2);
- end;
-less_or_equal: begin out_contrib[1]:="<"; out_contrib[2]:="="; send_out(str,2);
- end;
-greater_or_equal: begin out_contrib[1]:=">"; out_contrib[2]:="=";
- send_out(str,2);
- end;
-equivalence_sign: begin out_contrib[1]:="="; out_contrib[2]:="=";
- send_out(str,2);
- end;
-double_dot: begin out_contrib[1]:="."; out_contrib[2]:="."; send_out(str,2);
- end;
-
-@ Please don't ask how all of the following characters can actually get
-through \.{TANGLE} outside of strings. It seems that |""""| and |"{"|
-cannot actually occur at this point of the program, but they have
-been included just in case \.{TANGLE} changes.
-
-If \.{TANGLE} is producing code for a \PASCAL\ compiler that uses `\.{(.}'
-and `\.{.)}' instead of square brackets (e.g., on machines with {\mc EBCDIC}
-code), one should remove |"["| and |"]"| from this list and put them into
-the preceding module in the appropriate way. Similarly, some compilers
-want `\.\^' to be converted to `\.{@@}'.
-@^system dependencies@>@^EBCDIC@>
-
-@<Other printable characters@>=
-"!","""","#","$","%","&","(",")","*",",","/",":",";","<","=",">","?",
-"@@","[","\","]","^","_","`","{","|"
-
-@ Single-character identifiers represent themselves, while longer ones
-appear in |byte_mem|. All must be converted to uppercase,
-with underlines removed. Extremely long identifiers must be chopped.
-
-(Some \PASCAL\ compilers work with lowercase letters instead of
-uppercase. If this module of \.{TANGLE} is changed, it's also necessary
-to change from uppercase to lowercase in the modules that are
-listed in the index under ``uppercase''.)
-@^system dependencies@>
-@^uppercase@>
-
-@d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14,
- #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,#
-
-@<Cases related to identifiers@>=
-"A",up_to("Z"): begin out_contrib[1]:=cur_char; send_out(ident,1);
- end;
-"a",up_to("z"): begin out_contrib[1]:=cur_char-@'40; send_out(ident,1);
- end;
-identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww;
- while (k<max_id_length)and(j<byte_start[cur_val+ww]) do
- begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j);
- if out_contrib[k]>="a" then out_contrib[k]:=out_contrib[k]-@'40
- else if out_contrib[k]="_" then decr(k);
- end;
- send_out(ident,k);
- end;
-
-@ After sending a string, we need to look ahead at the next character, in order
-to see if there were two consecutive single-quote marks. Afterwards we go to
-|reswitch| to process the next character.
-
-@<Send a string...@>=
-begin k:=1; out_contrib[1]:="'";
-repeat if k<line_length then incr(k);
-out_contrib[k]:=get_output;
-until (out_contrib[k]="'")or(stack_ptr=0);
-if k=line_length then err_print('! String too long');
-@.String too long@>
-send_out(str,k); cur_char:=get_output;
-if cur_char="'" then out_state:=unbreakable;
-goto reswitch;
-end
-
-@ Sending a verbatim string is similar, but we don't have to look ahead.
-
-@<Send verbatim string@>=
-begin k:=0;
-repeat if k<line_length then incr(k);
-out_contrib[k]:=get_output;
-until (out_contrib[k]=verbatim)or(stack_ptr=0);
-if k=line_length then err_print('! Verbatim string too long');
-@.Verbatim string too long@>
-send_out(str,k-1);
-end
-
-@ In order to encourage portable software, \.{TANGLE} complains
-if the constants get dangerously close to the largest value representable
-on a 32-bit computer ($2^{31}-1$).
-
-@d digits=="0","1","2","3","4","5","6","7","8","9"
-
-@<Cases related to constants...@>=
-digits: begin n:=0;
- repeat cur_char:=cur_char-"0";
- if n>=@'1463146314 then err_print('! Constant too big')
-@.Constant too big@>
- else n:=10*n+cur_char;
- cur_char:=get_output;
- until (cur_char>"9")or(cur_char<"0");
- send_val(n); k:=0;
- if cur_char="e" then cur_char:="E";
-@^uppercase@>
- if cur_char="E" then goto get_fraction
- else goto reswitch;
- end;
-check_sum: send_val(pool_check_sum);
-octal: begin n:=0; cur_char:="0";
- repeat cur_char:=cur_char-"0";
- if n>=@'2000000000 then err_print('! Constant too big')
- else n:=8*n+cur_char;
- cur_char:=get_output;
- until (cur_char>"7")or(cur_char<"0");
- send_val(n); goto reswitch;
- end;
-hex: begin n:=0; cur_char:="0";
- repeat if cur_char>="A" then cur_char:=cur_char+10-"A"
- else cur_char:=cur_char-"0";
- if n>=@"8000000 then err_print('! Constant too big')
- else n:=16*n+cur_char;
- cur_char:=get_output;
- until (cur_char>"F")or(cur_char<"0")or@|
- ((cur_char>"9")and(cur_char<"A"));
- send_val(n); goto reswitch;
- end;
-number: send_val(cur_val);
-".": begin k:=1; out_contrib[1]:="."; cur_char:=get_output;
- if cur_char="." then
- begin out_contrib[2]:="."; send_out(str,2);
- end
- else if (cur_char>="0")and(cur_char<="9") then goto get_fraction
- else begin send_out(misc,"."); goto reswitch;
- end;
- end;
-
-@ The following code appears at label `|get_fraction|', when we want to
-scan to the end of a real constant. The first |k| characters of a fraction
-have already been placed in |out_contrib|, and |cur_char| is the next character.
-
-@<Special code...@>=
-repeat if k<line_length then incr(k);
-out_contrib[k]:=cur_char; cur_char:=get_output;
-if (out_contrib[k]="E")and((cur_char="+")or(cur_char="-")) then
-@^uppercase@>
- begin if k<line_length then incr(k);
- out_contrib[k]:=cur_char; cur_char:=get_output;
- end
-else if cur_char="e" then cur_char:="E";
-until (cur_char<>"E")and((cur_char<"0")or(cur_char>"9"));
-if k=line_length then err_print('! Fraction too long');
-@.Fraction too long@>
-send_out(frac,k); goto reswitch
-
-@ Some \PASCAL\ compilers do not recognize comments in braces, so the
-comments must be delimited by `\.{(*}' and `\.{*)}'.
-@^system dependencies@>
-In such cases the statement `|send_out(misc,"{")|' that appears here should
-be replaced by `\ignorespaces|begin out_contrib[1]:="("; out_contrib[2]:="*";
-send_out(str,2); end|', and a similar change should be made to
-`|send_out(misc,"}")|'.
-
-@<Cases involving \.{@@\{} and \.{@@\}}@>=
-begin_comment: begin if brace_level=0 then send_out(misc,"{")
- else send_out(misc,"[");
- incr(brace_level);
- end;
-end_comment: if brace_level>0 then
- begin decr(brace_level);
- if brace_level=0 then send_out(misc,"}")
- else send_out(misc,"]");
- end
- else err_print('! Extra @@}');
-@.Extra \AT!\}@>
-module_number: begin if brace_level=0 then send_out(misc,"{")
- else send_out(misc,"[");
- if cur_val<0 then
- begin send_out(misc,":"); send_val(-cur_val);
- end
- else begin send_val(cur_val); send_out(misc,":");
- end;
- if brace_level=0 then send_out(misc,"}")
- else send_out(misc,"]");
- end;
-
-@ @<Force a line break@>=
-begin send_out(str,0); {normalize the buffer}
-while out_ptr>0 do
- begin if out_ptr<=line_length then break_ptr:=out_ptr;
- flush_buffer;
- end;
-out_state:=misc;
-end
-
-@* Introduction to the input phase.
-We have now seen that \.{TANGLE} will be able to output the full
-\PASCAL\ program, if we can only get that program into the byte memory in
-the proper format. The input process is something like the output process
-in reverse, since we compress the text as we read it in and we expand it
-as we write it out.
-
-There are three main input routines. The most interesting is the one that gets
-the next token of a \PASCAL\ text; the other two are used to scan rapidly past
-\TeX\ text in the \.{WEB} source code. One of the latter routines will jump to
-the next token that starts with `\.{@@}', and the other skips to the end
-of a \PASCAL\ comment.
-
-@ But first we need to consider the low-level routine |get_line|
-that takes care of merging |change_file| into |web_file|. The |get_line|
-procedure also updates the line numbers for error messages.
-
-@<Globals...@>=
-@!ii:integer; {general purpose |for| loop variable in the outer block}
-@!line:integer; {the number of the current line in the current file}
-@!other_line:integer; {the number of the current line in the input file that
- is not currently being read}
-@!temp_line:integer; {used when interchanging |line| with |other_line|}
-@!limit:0..buf_size; {the last character position occupied in the buffer}
-@!loc:0..buf_size; {the next character position to be read from the buffer}
-@!input_has_ended: boolean; {if |true|, there is no more input}
-@!changing: boolean; {if |true|, the current line is from |change_file|}
-
-@ As we change |changing| from |true| to |false| and back again, we must
-remember to swap the values of |line| and |other_line| so that the |err_print|
-routine will be sure to report the correct line number.
-
-@d change_changing==
- changing := not changing;
- temp_line:=other_line; other_line:=line; line:=temp_line
- {|line @t$\null\BA\null$@> other_line|}
-
-@ When |changing| is |false|, the next line of |change_file| is kept in
-|change_buffer[0..change_limit]|, for purposes of comparison with the next
-line of |web_file|. After the change file has been completely input, we
-set |change_limit:=0|, so that no further matches will be made.
-
-@<Globals...@>=
-@!change_buffer:array[0..buf_size] of ASCII_code;
-@!change_limit:0..buf_size; {the last position occupied in |change_buffer|}
-
-@ Here's a simple function that checks if the two buffers are different.
-
-@p function lines_dont_match:boolean;
-label exit;
-var k:0..buf_size; {index into the buffers}
-begin lines_dont_match:=true;
-if change_limit<>limit then return;
-if limit>0 then
- for k:=0 to limit-1 do if change_buffer[k]<>buffer[k] then return;
-lines_dont_match:=false;
-exit: end;
-
-@ Procedure |prime_the_change_buffer| sets |change_buffer| in preparation
-for the next matching operation. Since blank lines in the change file are
-not used for matching, we have |(change_limit=0)and not changing| if and
-only if the change file is exhausted. This procedure is called only
-when |changing| is true; hence error messages will be reported correctly.
-
-@p procedure prime_the_change_buffer;
-label continue, done, exit;
-var k:0..buf_size; {index into the buffers}
-begin change_limit:=0; {this value will be used if the change file ends}
-@<Skip over comment lines in the change file; |return| if end of file@>;
-@<Skip to the next nonblank line; |return| if end of file@>;
-@<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>;
-exit: end;
-
-@ While looking for a line that begins with \.{@@x} in the change file,
-we allow lines that begin with \.{@@}, as long as they don't begin with
-\.{@@y} or \.{@@z} (which would probably indicate that the change file is
-fouled up).
-
-@<Skip over comment lines in the change file...@>=
-loop@+ begin incr(line);
- if not input_ln(change_file) then return;
- if limit<2 then goto continue;
- if buffer[0]<>"@@" then goto continue;
- if (buffer[1]>="X")and(buffer[1]<="Z") then
- buffer[1]:=buffer[1]+"z"-"Z"; {lowercasify}
- if buffer[1]="x" then goto done;
- if (buffer[1]="y")or(buffer[1]="z") then
- begin loc:=2; err_print('! Where is the matching @@x?');
-@.Where is the match...@>
- end;
-continue: end;
-done:
-
-@ Here we are looking at lines following the \.{@@x}.
-
-@<Skip to the next nonblank line...@>=
-repeat incr(line);
- if not input_ln(change_file) then
- begin err_print('! Change file ended after @@x');
-@.Change file ended...@>
- return;
- end;
-until limit>0;
-
-@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>=
-begin change_limit:=limit;
-if limit>0 then for k:=0 to limit-1 do change_buffer[k]:=buffer[k];
-end
-
-@ The following procedure is used to see if the next change entry should
-go into effect; it is called only when |changing| is false.
-The idea is to test whether or not the current
-contents of |buffer| matches the current contents of |change_buffer|.
-If not, there's nothing more to do; but if so, a change is called for:
-All of the text down to the \.{@@y} is supposed to match. An error
-message is issued if any discrepancy is found. Then the procedure
-prepares to read the next line from |change_file|.
-
-@p procedure check_change; {switches to |change_file| if the buffers match}
-label exit;
-var n:integer; {the number of discrepancies found}
-@!k:0..buf_size; {index into the buffers}
-begin if lines_dont_match then return;
-n:=0;
-loop@+ begin change_changing; {now it's |true|}
- incr(line);
- if not input_ln(change_file) then
- begin err_print('! Change file ended before @@y');
-@.Change file ended...@>
- change_limit:=0; change_changing; {|false| again}
- return;
- end;
- @<If the current line starts with \.{@@y},
- report any discrepancies and |return|@>;
- @<Move |buffer| and |limit|...@>;
- change_changing; {now it's |false|}
- incr(line);
- if not input_ln(web_file) then
- begin err_print('! WEB file ended during a change');
-@.WEB file ended...@>
- input_has_ended:=true; return;
- end;
- if lines_dont_match then incr(n);
- end;
-exit: end;
-
-@ @<If the current line starts with \.{@@y}...@>=
-if limit>1 then if buffer[0]="@@" then
- begin if (buffer[1]>="X")and(buffer[1]<="Z") then
- buffer[1]:=buffer[1]+"z"-"Z"; {lowercasify}
- if (buffer[1]="x")or(buffer[1]="z") then
- begin loc:=2; err_print('! Where is the matching @@y?');
-@.Where is the match...@>
- end
- else if buffer[1]="y" then
- begin if n>0 then
- begin loc:=2; err_print('! Hmm... ',n:1,
- ' of the preceding lines failed to match');
-@.Hmm... n of the preceding...@>
- end;
- return;
- end;
- end
-
-@ @<Initialize the input system@>=
-open_input; line:=0; other_line:=0;@/
-changing:=true; prime_the_change_buffer; change_changing;@/
-limit:=0; loc:=1; buffer[0]:=" "; input_has_ended:=false;
-
-@ The |get_line| procedure is called when |loc>limit|; it puts the next
-line of merged input into the buffer and updates the other variables
-appropriately. A space is placed at the right end of the line.
-
-@p procedure get_line; {inputs the next line}
-label restart;
-begin restart: if changing then
- @<Read from |change_file| and maybe turn off |changing|@>;
-if not changing then
- begin @<Read from |web_file| and maybe turn on |changing|@>;
- if changing then goto restart;
- end;
-loc:=0; buffer[limit]:=" ";
-end;
-
-@ @<Read from |web_file|...@>=
-begin incr(line);
-if not input_ln(web_file) then input_has_ended:=true
-else if limit=change_limit then
- if buffer[0]=change_buffer[0] then
- if change_limit>0 then check_change;
-end
-
-@ @<Read from |change_file|...@>=
-begin incr(line);
-if not input_ln(change_file) then
- begin err_print('! Change file ended without @@z');
-@.Change file ended...@>
- buffer[0]:="@@"; buffer[1]:="z"; limit:=2;
- end;
-if limit>1 then {check if the change has ended}
- if buffer[0]="@@" then
- begin if (buffer[1]>="X")and(buffer[1]<="Z") then
- buffer[1]:=buffer[1]+"z"-"Z"; {lowercasify}
- if (buffer[1]="x")or(buffer[1]="y") then
- begin loc:=2; err_print('! Where is the matching @@z?');
-@.Where is the match...@>
- end
- else if buffer[1]="z" then
- begin prime_the_change_buffer; change_changing;
- end;
- end;
-end
-
-@ At the end of the program, we will tell the user if the change file
-had a line that didn't match any relevant line in |web_file|.
-
-@<Check that all changes have been read@>=
-if change_limit<>0 then {|changing| is false}
- begin for ii:=0 to change_limit do buffer[ii]:=change_buffer[ii];
- limit:=change_limit; changing:=true; line:=other_line; loc:=change_limit;
- err_print('! Change file entry did not match');
-@.Change file entry did not match@>
- end
-
-@ Important milestones are reached during the input phase when certain
-control codes are sensed.
-
-Control codes in \.{WEB} begin with `\.{@@}', and the next character
-identifies the code. Some of these are of interest only to \.{WEAVE},
-so \.{TANGLE} ignores them; the others are converted by \.{TANGLE} into
-internal code numbers by the |control_code| function below. The ordering
-of these internal code numbers has been chosen to simplify the program logic;
-larger numbers are given to the control codes that denote more significant
-milestones.
-
-@d ignore=0 {control code of no interest to \.{TANGLE}}
-@d control_text=@'203 {control code for `\.{@@t}', `\.{@@\^}', etc.}
-@d format=@'204 {control code for `\.{@@f}'}
-@d definition=@'205 {control code for `\.{@@d}'}
-@d begin_Pascal=@'206 {control code for `\.{@@p}'}
-@d module_name=@'207 {control code for `\.{@@<}'}
-@d new_module=@'210 {control code for `\.{@@\ }' and `\.{@@*}'}
-
-@p function control_code(@!c:ASCII_code):eight_bits; {convert |c| after \.{@@}}
-begin case c of
-"@@": control_code:="@@"; {`quoted' at sign}
-"'": control_code:=octal; {precedes octal constant}
-"""": control_code:=hex; {precedes hexadecimal constant}
-"$": control_code:=check_sum; {string pool check sum}
-" ",tab_mark: control_code:=new_module; {beginning of a new module}
-"*": begin print('*',module_count+1:1);
- update_terminal; {print a progress report}
- control_code:=new_module; {beginning of a new module}
- end;
-"D","d": control_code:=definition; {macro definition}
-"F","f": control_code:=format; {format definition}
-"{": control_code:=begin_comment; {begin-comment delimiter}
-"}": control_code:=end_comment; {end-comment delimiter}
-"P","p": control_code:=begin_Pascal; {\PASCAL\ text in unnamed module}
-"T","t","^",".",":": control_code:=control_text; {control text to be ignored}
-"&": control_code:=join; {concatenate two tokens}
-"<": control_code:=module_name; {beginning of a module name}
-"=": control_code:=verbatim; {beginning of \PASCAL\ verbatim mode}
-"\": control_code:=force_line; {force a new line in \PASCAL\ output}
-othercases control_code:=ignore {ignore all other cases}
-endcases;
-end;
-
-@ The |skip_ahead| procedure reads through the input at fairly high speed
-until finding the next non-ignorable control code, which it returns.
-
-@p function skip_ahead:eight_bits; {skip to next control code}
-label done;
-var c:eight_bits; {control code found}
-begin loop begin if loc>limit then
- begin get_line;
- if input_has_ended then
- begin c:=new_module; goto done;
- end;
- end;
- buffer[limit+1]:="@@";
- while buffer[loc]<>"@@" do incr(loc);
- if loc<=limit then
- begin loc:=loc+2; c:=control_code(buffer[loc-1]);
- if (c<>ignore)or(buffer[loc-1]=">") then goto done;
- end;
- end;
-done: skip_ahead:=c;
-end;
-
-@ The |skip_comment| procedure reads through the input at somewhat high speed
-until finding the first unmatched right brace or until coming to the end
-of the file. It ignores characters following `\.\\' characters, since all
-braces that aren't nested are supposed to be hidden in that way. For
-example, consider the process of skipping the first comment below,
-where the string containing the right brace has been typed as \.{\`\\.\\\}\'}
-in the \.{WEB} file.
-
-@p procedure skip_comment; {skips to next unmatched `\.\}'}
-label exit;
-var bal:eight_bits; {excess of left braces}
-@!c:ASCII_code; {current character}
-begin bal:=0;
-loop@+ begin if loc>limit then
- begin get_line;
- if input_has_ended then
- begin err_print('! Input ended in mid-comment');
-@.Input ended in mid-comment@>
- return;
- end;
- end;
- c:=buffer[loc]; incr(loc);
- @<Do special things when |c="@@", "\", "{", "}"|; |return| at end@>;
- end;
-exit:end;
-
-@ @<Do special things when |c="@@"...@>=
-if c="@@" then
- begin c:=buffer[loc];
- if (c<>" ")and(c<>tab_mark)and(c<>"*")and(c<>"z")and(c<>"Z") then incr(loc)
- else begin err_print('! Section ended in mid-comment');
-@.Section ended in mid-comment@>
- decr(loc); return;
- end
- end
-else if (c="\")and(buffer[loc]<>"@@") then incr(loc)
-else if c="{" then incr(bal)
-else if c="}" then
- begin if bal=0 then return;
- decr(bal);
- end
-
-@* Inputting the next token.
-As stated above, \.{TANGLE}'s most interesting input procedure is the
-|get_next| routine that inputs the next token. However, the procedure
-isn't especially difficult.
-
-In most cases the tokens output by |get_next| have the form used in
-replacement texts, except that two-byte tokens are not produced.
-An identifier that isn't one letter long is represented by the
-output `|identifier|', and in such a case the global variables
-|id_first| and |id_loc| will have been set to the appropriate values
-needed by the |id_lookup| procedure. A string that begins with a
-double-quote is also considered an |identifier|, and in such a case
-the global variable |double_chars| will also have been set appropriately.
-Control codes produce the corresponding output of the |control_code|
-function above; and if that code is |module_name|, the value of |cur_module|
-will point to the |byte_start| entry for that module name.
-
-Another global variable, |scanning_hex|, is |true| during the time that
-the letters \.A through \.F should be treated as if they were digits.
-
-@<Globals...@>=
-@!cur_module: name_pointer; {name of module just scanned}
-@!scanning_hex: boolean; {are we scanning a hexadecimal constant?}
-
-@ @<Set init...@>=
-scanning_hex:=false;
-
-@ At the top level, |get_next| is a multi-way switch based on the next
-character in the input buffer. A |new_module| code is inserted at the
-very end of the input file.
-
-@p function get_next:eight_bits; {produces the next input token}
-label restart,done,found;
-var c:eight_bits; {the current character}
-@!d:eight_bits; {the next character}
-@!j,@!k:0..longest_name; {indices into |mod_text|}
-begin restart: if loc>limit then
- begin get_line;
- if input_has_ended then
- begin c:=new_module; goto found;
- end;
- end;
-c:=buffer[loc]; incr(loc);
-if scanning_hex then @<Go to |found| if |c| is a hexadecimal digit,
- otherwise set |scanning_hex:=false|@>;
-case c of
-"A",up_to("Z"),"a",up_to("z"): @<Get an identifier@>;
-"""": @<Get a preprocessed string@>;
-"@@": @<Get control code and possible module name@>;
-@t\4@>@<Compress two-symbol combinations like `\.{:=}'@>@;
-" ",tab_mark: goto restart; {ignore spaces and tabs}
-"{": begin skip_comment; goto restart;
- end;
-"}": begin err_print('! Extra }'); goto restart;
-@.Extra \}@>
- end;
-othercases if c>=128 then goto restart {ignore nonstandard characters}
- else do_nothing
-endcases;
-found:@!debug if trouble_shooting then debug_help;@;@+gubed@/
-get_next:=c;
-end;
-
-@ @<Go to |found| if |c| is a hexadecimal digit...@>=
-if ((c>="0")and(c<="9"))or((c>="A")and(c<="F")) then goto found
-else scanning_hex:=false
-
-@ Note that the following code substitutes \.{@@\{} and \.{@@\}} for the
-respective combinations `\.{(*}' and `\.{*)}'. Explicit braces should be used
-for \TeX\ comments in \PASCAL\ text.
-
-@d compress(#)==begin if loc<=limit then begin c:=#; incr(loc); end; end
-
-@<Compress two-symbol...@>=
-".": if buffer[loc]="." then compress(double_dot)
- else if buffer[loc]=")" then compress("]");
-":": if buffer[loc]="=" then compress(left_arrow);
-"=": if buffer[loc]="=" then compress(equivalence_sign);
-">": if buffer[loc]="=" then compress(greater_or_equal);
-"<": if buffer[loc]="=" then compress(less_or_equal)
- else if buffer[loc]=">" then compress(not_equal);
-"(": if buffer[loc]="*" then compress(begin_comment)
- else if buffer[loc]="." then compress("[");
-"*": if buffer[loc]=")" then compress(end_comment);
-
-@ We have to look at the preceding character to make sure this isn't part
-of a real constant, before trying to find an identifier starting with
-`\.e' or `\.E'.
-
-@<Get an identifier@>=
-begin if ((c="e")or(c="E"))and(loc>1) then
- if (buffer[loc-2]<="9")and(buffer[loc-2]>="0") then c:=0;
-if c<>0 then
- begin decr(loc); id_first:=loc;
- repeat incr(loc); d:=buffer[loc];
- until ((d<"0")or((d>"9")and(d<"A"))or((d>"Z")and(d<"a"))or(d>"z")) and
- (d<>"_");
- if loc>id_first+1 then
- begin c:=identifier; id_loc:=loc;
- end;
- end
-else c:="E"; {exponent of a real constant}
-end
-
-@ A string that starts and ends with double-quote marks is converted into
-an identifier that behaves like a numeric macro by means of the following
-piece of the program.
-@^preprocessed strings@>
-
-@<Get a preprocessed string@>=
-begin double_chars:=0; id_first:=loc-1;
-repeat d:=buffer[loc]; incr(loc);
- if (d="""")or(d="@@") then
- if buffer[loc]=d then
- begin incr(loc); d:=0; incr(double_chars);
- end
- else begin if d="@@" then err_print('! Double @@ sign missing')
-@.Double \AT! sign missing@>
- end
- else if loc>limit then
- begin err_print('! String constant didn''t end'); d:="""";
-@.String constant didn't end@>
- end;
-until d="""";
-id_loc:=loc-1; c:=identifier;
-end
-
-@ After an \.{@@} sign has been scanned, the next character tells us
-whether there is more work to do.
-
-@<Get control code and possible module name@>=
-begin c:=control_code(buffer[loc]); incr(loc);
-if c=ignore then goto restart
-else if c=hex then scanning_hex:=true
-else if c=module_name then
- @<Scan the \(module name and make |cur_module| point to it@>
-else if c=control_text then
- begin repeat c:=skip_ahead;
- until c<>"@@";
- if buffer[loc-1]<>">" then
- err_print('! Improper @@ within control text');
-@.Improper \AT! within control text@>
- goto restart;
- end;
-end
-
-@ @<Scan the \(module name...@>=
-begin @<Put module name into |mod_text[1..k]|@>;
-if k>3 then
- begin if (mod_text[k]=".")and(mod_text[k-1]=".")and(mod_text[k-2]=".") then
- cur_module:=prefix_lookup(k-3)
- else cur_module:=mod_lookup(k);
- end
-else cur_module:=mod_lookup(k);
-end
-
-@ Module names are placed into the |mod_text| array with consecutive spaces,
-tabs, and carriage-returns replaced by single spaces. There will be no
-spaces at the beginning or the end. (We set |mod_text[0]:=" "| to facilitate
-this, since the |mod_lookup| routine uses |mod_text[1]| as the first
-character of the name.)
-
-@<Set init...@>=mod_text[0]:=" ";
-
-@ @<Put module name...@>=
-k:=0;
-loop@+ begin if loc>limit then
- begin get_line;
- if input_has_ended then
- begin err_print('! Input ended in section name');
-@.Input ended in section name@>
- goto done;
- end;
- end;
- d:=buffer[loc];
- @<If end of name, |goto done|@>;
- incr(loc); if k<longest_name-1 then incr(k);
- if (d=" ")or(d=tab_mark) then
- begin d:=" "; if mod_text[k-1]=" " then decr(k);
- end;
- mod_text[k]:=d;
- end;
-done: @<Check for overlong name@>;
-if (mod_text[k]=" ")and(k>0) then decr(k);
-
-@ @<If end of name,...@>=
-if d="@@" then
- begin d:=buffer[loc+1];
- if d=">" then
- begin loc:=loc+2; goto done;
- end;
- if (d=" ")or(d=tab_mark)or(d="*") then
- begin err_print('! Section name didn''t end'); goto done;
-@.Section name didn't end@>
- end;
- incr(k); mod_text[k]:="@@"; incr(loc); {now |d=buffer[loc]| again}
- end
-
-@ @<Check for overlong name@>=
-if k>=longest_name-2 then
- begin print_nl('! Section name too long: ');
-@.Section name too long@>
- for j:=1 to 25 do print(xchr[mod_text[j]]);
- print('...'); mark_harmless;
- end
-
-@* Scanning a numeric definition.
-When \.{TANGLE} looks at the \PASCAL\ text following the `\.=' of a numeric
-macro definition, it calls on the precedure |scan_numeric(p)|, where |p|
-points to the name that is to be defined. This procedure evaluates the
-right-hand side, which must consist entirely of integer constants and
-defined numeric macros connected with \.+ and \.- signs (no parentheses).
-It also sets the global variable |next_control| to the control code that
-terminated this definition.
-
-A definition ends with the control codes |definition|, |format|, |module_name|,
-|begin_Pascal|, and |new_module|, all of which can be recognized
-by the fact that they are the largest values |get_next| can return.
-
-@d end_of_definition(#)==(#>=format)
- {is |#| a control code ending a definition?}
-
-@<Global...@>=
-@!next_control:eight_bits; {control code waiting to be acted upon}
-
-@ The evaluation of a numeric expression makes use of two variables called the
-|accumulator| and the |next_sign|. At the beginning, |accumulator| is zero and
-|next_sign| is $+1$. When a \.+ or \.- is scanned, |next_sign| is multiplied
-by the value of that sign. When a numeric value is scanned, it is multiplied by
-|next_sign| and added to the |accumulator|, then |next_sign| is reset to $+1$.
-
-@d add_in(#)==begin accumulator:=accumulator+next_sign*(#); next_sign:=+1;
- end
-
-@p procedure scan_numeric(@!p:name_pointer); {defines numeric macros}
-label reswitch, done;
-var accumulator:integer; {accumulates sums}
-@!next_sign:-1..+1; {sign to attach to next value}
-@!q:name_pointer; {points to identifiers being evaluated}
-@!val:integer; {constants being evaluated}
-begin @<Set \(|accumulator| to the value of the right-hand side@>;
-if abs(accumulator)>=1073741824 then
- begin err_print('! Value too big: ',accumulator:1); accumulator:=0;
-@.Value too big@>
- end;
-equiv[p]:=accumulator+1073741824;
- {name |p| now is defined to equal |accumulator|}
-end;
-
-@ @<Set \(|accumulator| to the value of the right-hand side@>=
-accumulator:=0; next_sign:=+1;
-loop@+ begin next_control:=get_next;
- reswitch: case next_control of
- digits: begin @<Set |val| to value of decimal constant, and
- set |next_control| to the following token@>;
- add_in(val); goto reswitch;
- end;
- octal: begin @<Set |val| to value of octal constant, and
- set |next_control| to the following token@>;
- add_in(val); goto reswitch;
- end;
- hex: begin @<Set |val| to value of hexadecimal constant, and
- set |next_control| to the following token@>;
- add_in(val); goto reswitch;
- end;
- identifier: begin q:=id_lookup(normal);
- if ilk[q]<>numeric then
- begin next_control:="*"; goto reswitch; {leads to error}
- end;
- add_in(equiv[q]-1073741824);
- end;
- "+": do_nothing;
- "-": next_sign:=-next_sign;
- format, definition, module_name, begin_Pascal, new_module: goto done;
- ";": err_print('! Omit semicolon in numeric definition');
-@.Omit semicolon in numeric def...@>
- othercases @<Signal error, flush rest of the definition@>
- endcases;
- end;
-done:
-
-@ @<Signal error, flush rest...@>=
-begin err_print('! Improper numeric definition will be flushed');
-@.Improper numeric definition...@>
-repeat next_control:=skip_ahead
-until end_of_definition(next_control);
-if next_control=module_name then
- begin {we want to scan the module name too}
- loc:=loc-2; next_control:=get_next;
- end;
-accumulator:=0; goto done;
-end
-
-@ @<Set |val| to value of decimal...@>=
-val:=0;
-repeat val:=10*val+next_control-"0"; next_control:=get_next;
-until (next_control>"9")or(next_control<"0")
-
-@ @<Set |val| to value of octal...@>=
-val:=0; next_control:="0";
-repeat val:=8*val+next_control-"0"; next_control:=get_next;
-until (next_control>"7")or(next_control<"0")
-
-@ @<Set |val| to value of hex...@>=
-val:=0; next_control:="0";
-repeat if next_control>="A" then next_control:=next_control+"0"+10-"A";
-val:=16*val+next_control-"0"; next_control:=get_next;
-until (next_control>"F")or(next_control<"0")or@|
- ((next_control>"9")and(next_control<"A"))
-
-@* Scanning a macro definition.
-The rules for generating the replacement texts corresponding to simple
-macros, parametric macros, and \PASCAL\ texts of a module are almost
-identical, so a single procedure is used for all three cases. The
-differences are that
-
-\yskip\item{a)} The sign |#| denotes a parameter only when it appears
-outside of strings in a parametric macro; otherwise it stands for the
-ASCII character |#|. (This is not used in standard \PASCAL, but some
-\PASCAL s allow, for example, `\.{/\#}' after a certain kind of file name.)
-
-\item{b)}Module names are not allowed in simple macros or parametric macros;
-in fact, the appearance of a module name terminates such macros and denotes
-the name of the current module.
-
-\item{c)}The symbols \.{@@d} and \.{@@f} and \.{@@p} are not allowed after
-module names, while they terminate macro definitions.
-
-@ Therefore there is a procedure |scan_repl| whose parameter |t| specifies
-either |simple| or |parametric| or |module_name|. After |scan_repl| has
-acted, |cur_repl_text| will point to the replacement text just generated, and
-|next_control| will contain the control code that terminated the activity.
-
-@<Globals...@>=
-@!cur_repl_text:text_pointer; {replacement text formed by |scan_repl|}
-
-@ @p procedure scan_repl(@!t:eight_bits); {creates a replacement text}
-label continue, done, found, reswitch;
-var a:sixteen_bits; {the current token}
-@!b:ASCII_code; {a character from the buffer}
-@!bal:eight_bits; {left parentheses minus right parentheses}
-begin bal:=0;
-loop@+ begin continue: a:=get_next;
- case a of
- "(": incr(bal);
- ")": if bal=0 then err_print('! Extra )')
-@.Extra )@>
- else decr(bal);
- "'": @<Copy a string from the buffer to |tok_mem|@>;
- "#": if t=parametric then a:=param;
- @t\4@>@<In cases that |a| is a non-ASCII token (|identifier|,
- |module_name|, etc.), either process it and change |a| to a byte
- that should be stored, or |goto continue| if |a| should be ignored,
- or |goto done| if |a| signals the end of this replacement text@>@;
- othercases do_nothing
- endcases;@/
- app_repl(a); {store |a| in |tok_mem|}
- end;
-done: next_control:=a;
-@<Make sure the parentheses balance@>;
-if text_ptr>max_texts-zz then overflow('text');
-cur_repl_text:=text_ptr; tok_start[text_ptr+zz]:=tok_ptr[z];
-incr(text_ptr);
-if z=zz-1 then z:=0@+else incr(z);
-end;
-
-@ @<Make sure the parentheses balance@>=
-if bal>0 then
- begin if bal=1 then err_print('! Missing )')
- else err_print('! Missing ',bal:1,' )''s');
-@.Missing n )@>
- while bal>0 do
- begin app_repl(")"); decr(bal);
- end;
- end
-
-@ @<In cases that |a| is...@>=
-identifier: begin a:=id_lookup(normal); app_repl((a div @'400)+@'200);
- a:=a mod @'400;
- end;
-module_name: if t<>module_name then goto done
- else begin app_repl((cur_module div @'400)+@'250);
- a:=cur_module mod @'400;
- end;
-verbatim: @<Copy verbatim string from the buffer to |tok_mem|@>;
-definition, format, begin_Pascal: if t<>module_name then goto done
- else begin err_print('! @@',xchr[buffer[loc-1]],
-@.\AT!p is ignored in Pascal text@>
-@.\AT!d is ignored in Pascal text@>
-@.\AT!f is ignored in Pascal text@>
- ' is ignored in Pascal text'); goto continue;
- end;
-new_module: goto done;
-
-@ @<Copy a string...@>=
-begin b:="'";
-loop@+ begin app_repl(b);
- if b="@@" then
- if buffer[loc]="@@" then incr(loc) {store only one \.{@@}}
- else err_print('! You should double @@ signs in strings');
-@.You should double \AT! signs@>
- if loc=limit then
- begin err_print('! String didn''t end');
-@.String didn't end@>
- buffer[loc]:="'"; buffer[loc+1]:=0;
- end;
- b:=buffer[loc]; incr(loc);
- if b="'" then
- begin if buffer[loc]<>"'" then goto found
- else begin incr(loc); app_repl("'");
- end;
- end;
- end;
-found: end {now |a| holds the final |"'"| that will be stored}
-
-@ @<Copy verbatim string...@>=
-begin app_repl(verbatim);
-buffer[limit+1]:="@@";
-reswitch: if buffer[loc]="@@" then
- begin if loc<limit then if buffer[loc+1]="@@" then
- begin app_repl("@@");
- loc:=loc+2;
- goto reswitch;
- end;
- end
-else begin app_repl(buffer[loc]);
- incr(loc);
- goto reswitch;
- end;
-if loc>=limit then err_print('! Verbatim string didn''t end')
-@.Verbatim string didn't end@>
-else if buffer[loc+1]<>">" then
- err_print('! You should double @@ signs in verbatim strings');
-@.You should double \AT! signs@>
-loc:=loc+2;
-end {another |verbatim| byte will be stored, since |a=verbatim|}
-
-@ The following procedure is used to define a simple or parametric macro,
-just after the `\.{==}' of its definition has been scanned.
-
-@p procedure define_macro(@!t:eight_bits);
-var p:name_pointer; {the identifier being defined}
-begin p:=id_lookup(t); scan_repl(t);@/
-equiv[p]:=cur_repl_text; text_link[cur_repl_text]:=0;
-end;
-
-@* Scanning a module.
-The |scan_module| procedure starts when `\.{@@\ }' or `\.{@@*}' has been
-sensed in the input, and it proceeds until the end of that module. It
-uses |module_count| to keep track of the current module number; with luck,
-\.{WEAVE} and \.{TANGLE} will both assign the same numbers to modules.
-
-@<Globals...@>=
-@!module_count:0..@'27777; {the current module number}
-
-@ The top level of |scan_module| is trivial.
-@p procedure scan_module;
-label continue, done, exit;
-var p:name_pointer; {module name for the current module}
-begin incr(module_count);
-@<Scan the \(definition part of the current module@>;
-@<Scan the \PASCAL\ part of the current module@>;
-exit: end;
-
-@ @<Scan the \(definition part...@>=
-next_control:=0;
-loop@+ begin continue: while next_control<=format do
- begin next_control:=skip_ahead;
- if next_control=module_name then
- begin {we want to scan the module name too}
- loc:=loc-2; next_control:=get_next;
- end;
- end;
- if next_control<>definition then goto done;
- next_control:=get_next; {get identifier name}
- if next_control<>identifier then
- begin err_print('! Definition flushed, must start with ',
-@.Definition flushed...@>
- 'identifier of length > 1'); goto continue;
- end;
- next_control:=get_next; {get token after the identifier}
- if next_control="=" then
- begin scan_numeric(id_lookup(numeric)); goto continue;
- end
- else if next_control=equivalence_sign then
- begin define_macro(simple); goto continue;
- end
- else @<If the next text is `|(#)==|', call |define_macro|
- and |goto continue|@>;
- err_print('! Definition flushed since it starts badly');
-@.Definition flushed...@>
- end;
-done:
-
-@ @<If the next text is `|(#)==|'...@>=
-if next_control="(" then
- begin next_control:=get_next;
- if next_control="#" then
- begin next_control:=get_next;
- if next_control=")" then
- begin next_control:=get_next;
- if next_control="=" then
- begin err_print('! Use == for macros');
-@.Use == for macros@>
- next_control:=equivalence_sign;
- end;
- if next_control=equivalence_sign then
- begin define_macro(parametric); goto continue;
- end;
- end;
- end;
- end;
-
-@ @<Scan the \PASCAL...@>=
-case next_control of
-begin_Pascal:p:=0;
-module_name: begin p:=cur_module;
- @<Check that |=| or |==| follows this module name, otherwise |return|@>;
- end;
-othercases return
-endcases;@/
-@<Insert the module number into |tok_mem|@>;
-scan_repl(module_name); {now |cur_repl_text| points to the replacement text}
-@<Update the data structure so that the replacement text is accessible@>;
-
-@ @<Check that |=|...@>=
-repeat next_control:=get_next;
-until next_control<>"+"; {allow optional `\.{+=}'}
-if (next_control<>"=")and(next_control<>equivalence_sign) then
- begin err_print('! Pascal text flushed, = sign is missing');
-@.Pascal text flushed...@>
- repeat next_control:=skip_ahead;
- until next_control=new_module;
- return;
- end
-
-@ @<Insert the module number...@>=
-store_two_bytes(@'150000+module_count); {|@'150000=@'320*@'400|}
-
-@ @<Update the data...@>=
-if p=0 then {unnamed module}
- begin text_link[last_unnamed]:=cur_repl_text; last_unnamed:=cur_repl_text;
- end
-else if equiv[p]=0 then equiv[p]:=cur_repl_text {first module of this name}
-else begin p:=equiv[p];
- while text_link[p]<module_flag do p:=text_link[p]; {find end of list}
- text_link[p]:=cur_repl_text;
- end;
-text_link[cur_repl_text]:=module_flag;
- {mark this replacement text as a nonmacro}
-
-@* Debugging.
-The \PASCAL\ debugger with which \.{TANGLE} was developed allows breakpoints
-to be set, and variables can be read and changed, but procedures cannot be
-executed. Therefore a `|debug_help|' procedure has been inserted in the main
-loops of each phase of the program; when |ddt| and |dd| are set to appropriate
-values, symbolic printouts of various tables will appear.
-
-The idea is to set a breakpoint inside the |debug_help| routine, at the
-place of `\ignorespaces|breakpoint:|\unskip' below. Then when
-|debug_help| is to be activated, set |trouble_shooting| equal to |true|.
-The |debug_help| routine will prompt you for values of |ddt| and |dd|,
-discontinuing this when |ddt<=0|; thus you type $2n+1$ integers, ending
-with zero or a negative number. Then control either passes to the
-breakpoint, allowing you to look at and/or change variables (if you typed
-zero), or to exit the routine (if you typed a negative value).
-
-Another global variable, |debug_cycle|, can be used to skip silently
-past calls on |debug_help|. If you set |debug_cycle>1|, the program stops
-only every |debug_cycle| times |debug_help| is called; however,
-any error stop will set |debug_cycle| to zero.
-
-@<Globals...@>=
-@!debug@!trouble_shooting:boolean; {is |debug_help| wanted?}
-@!ddt:integer; {operation code for the |debug_help| routine}
-@!dd:integer; {operand in procedures performed by |debug_help|}
-@!debug_cycle:integer; {threshold for |debug_help| stopping}
-@!debug_skipped:integer; {we have skipped this many |debug_help| calls}
-@!term_in:text_file; {the user's terminal as an input file}
-gubed
-
-@ The debugging routine needs to read from the user's terminal.
-@^system dependencies@>
-@<Set init...@>=
-@!debug trouble_shooting:=true; debug_cycle:=1; debug_skipped:=0;@/
-trouble_shooting:=false; debug_cycle:=99999; {use these when it almost works}
-reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|}
-gubed
-
-@ @d breakpoint=888 {place where a breakpoint is desirable}
-@^system dependencies@>
-
-@p @!debug procedure debug_help; {routine to display various things}
-label breakpoint,exit;
-var k:integer; {index into various arrays}
-begin incr(debug_skipped);
-if debug_skipped<debug_cycle then return;
-debug_skipped:=0;
-loop@+ begin write(term_out,'#'); update_terminal; {prompt}
- read(term_in,ddt); {read a list of integers}
- if ddt<0 then return
- else if ddt=0 then
- begin goto breakpoint;@\ {go to every label at least once}
- breakpoint: ddt:=0;@\
- end
- else begin read(term_in,dd);
- case ddt of
- 1: print_id(dd);
- 2: print_repl(dd);
- 3: for k:=1 to dd do print(xchr[buffer[k]]);
- 4: for k:=1 to dd do print(xchr[mod_text[k]]);
- 5: for k:=1 to out_ptr do print(xchr[out_buf[k]]);
- 6: for k:=1 to dd do print(xchr[out_contrib[k]]);
- othercases print('?')
- endcases;
- end;
- end;
-exit:end;
-gubed
-
-@* The main program.
-We have defined plenty of procedures, and it is time to put the last
-pieces of the puzzle in place. Here is where \.{TANGLE} starts, and where
-it ends.
-@^system dependencies@>
-
-@p begin initialize;
-@<Initialize the input system@>;
-print_ln(banner); {print a ``banner line''}
-@<Phase I: Read all the user's text and compress it into |tok_mem|@>;
-stat for ii:=0 to zz-1 do max_tok_ptr[ii]:=tok_ptr[ii];@+tats@;@/
-@<Phase II:...@>;
-end_of_TANGLE:
-if string_ptr>number_chars then @<Finish off the string pool file@>;
-stat @<Print statistics about memory usage@>;@+tats@;@/
-@t\4\4@>{here files should be closed if the operating system requires it}
-@<Print the job |history|@>;
-end.
-
-@ @<Phase I:...@>=
-phase_one:=true;
-module_count:=0;
-repeat next_control:=skip_ahead;
-until next_control=new_module;
-while not input_has_ended do scan_module;
-@<Check that all changes have been read@>;
-phase_one:=false;
-
-@ @<Finish off the string pool file@>=
-begin print_nl(string_ptr-number_chars:1,
- ' strings written to string pool file.');
-write(pool,'*');
-for ii:=1 to 9 do
- begin out_buf[ii]:=pool_check_sum mod 10;
- pool_check_sum:=pool_check_sum div 10;
- end;
-for ii:=9 downto 1 do write(pool,xchr["0"+out_buf[ii]]);
-write_ln(pool);
-end
-
-@ @<Glob...@>=
-stat @!wo:0..ww-1; {segment of memory for which statistics are being printed}
-tats
-
-@ @<Print statistics about memory usage@>=
-print_nl('Memory usage statistics:');
-print_nl(name_ptr:1, ' names, ', text_ptr:1, ' replacement texts;');
-print_nl(byte_ptr[0]:1);
-for wo:=1 to ww-1 do print('+',byte_ptr[wo]:1);
-if phase_one then
- for ii:=0 to zz-1 do max_tok_ptr[ii]:=tok_ptr[ii];
-print(' bytes, ', max_tok_ptr[0]:1);
-for ii:=1 to zz-1 do print('+',max_tok_ptr[ii]:1);
-print(' tokens.');
-
-@ Some implementations may wish to pass the |history| value to the
-operating system so that it can be used to govern whether or not other
-programs are started. Here we simply report the history to the user.
-@^system dependencies@>
-
-@<Print the job |history|@>=
-case history of
-spotless: print_nl('(No errors were found.)');
-harmless_message: print_nl('(Did you see the warning message above?)');
-error_message: print_nl('(Pardon me, but I think I spotted something wrong.)');
-fatal_message: print_nl('(That was a fatal error, my friend.)');
-end {there are no other cases}
-
-@* System-dependent changes.
-This module should be replaced, if necessary, by changes to the program
-that are necessary to make \.{TANGLE} work at a particular installation.
-It is usually best to design your change file so that all changes to
-previous modules preserve the module numbering; then everybody's version
-will be consistent with the printed program. More extensive changes,
-which introduce new modules, can be inserted here; then only the index
-itself will get a new module number.
-@^system dependencies@>
-
-@* Index.
-Here is a cross-reference table for the \.{TANGLE} processor.
-All modules in which an identifier is
-used are listed with that identifier, except that reserved words are
-indexed only when they appear in format definitions, and the appearances
-of identifiers in module names are not indexed. Underlined entries
-correspond to where the identifier was declared. Error messages and
-a few other things like ``ASCII code'' are indexed here too.
diff --git a/Build/source/texk/web2c/luatexdir/luatex.c b/Build/source/texk/web2c/luatexdir/luatex.c
new file mode 100644
index 00000000000..1183b7d9de4
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luatex.c
@@ -0,0 +1,1063 @@
+/* texmf.c: Hand-coded routines for TeX or Metafont in C. Originally
+ written by Tim Morgan, drawing from other Unix ports of TeX. This is
+ a collection of miscellany, everything that's easier (or only
+ possible) to do in C.
+
+ This file is public domain. */
+
+/* This file is used to create texextra.c etc., with this line
+ changed to include texd.h or mfd.h. The ?d.h file is what
+ #defines TeX or MF, which avoids the need for a special
+ Makefile rule. */
+#include "luatex.h"
+
+#include "luatex_svnversion.h"
+
+static const char _svn_version[] =
+ "$Id: luatex.c 3588 2010-04-04 06:41:44Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/luatex.c $";
+
+#define TeX
+
+int luatex_svn = luatex_svn_revision;
+int luatex_version = 60; /* \.{\\luatexversion} */
+int luatex_revision = '0'; /* \.{\\luatexrevision} */
+int luatex_date_info = -extra_version_info; /* the compile date is negated */
+const char *luatex_version_string = "beta-0.60.0";
+const char *engine_name = "luatex"; /* the name of this engine */
+
+
+
+#include <kpathsea/c-ctype.h>
+#include <kpathsea/line.h>
+#include <kpathsea/readable.h>
+#include <kpathsea/variable.h>
+#include <kpathsea/absolute.h>
+#include <kpathsea/recorder.h>
+
+#include <time.h> /* For `struct tm'. */
+#if defined (HAVE_SYS_TIME_H)
+# include <sys/time.h>
+#elif defined (HAVE_SYS_TIMEB_H)
+# include <sys/timeb.h>
+#endif
+
+#if defined(__STDC__)
+# include <locale.h>
+#endif
+
+#include <signal.h> /* Catch interrupts. */
+
+#include <texmfmp-help.h>
+
+/* {tex,mf}d.h defines TeX, MF, INI, and other such symbols.
+ Unfortunately there's no way to get the banner into this code, so
+ just repeat the text. */
+#define edit_var "TEXEDIT"
+
+/* Shell escape.
+
+ If shellenabledp == 0, all shell escapes are forbidden.
+ If (shellenabledp == 1 && restrictedshell == 0), any command
+ is allowed for a shell escape.
+ If (shellenabledp == 1 && restrictedshell == 1), only commands
+ given in the configuration file as
+ shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun,...
+ (no spaces between commands) in texmf.cnf are allowed for a shell
+ escape in a restricted form: command name and arguments should be
+ separated by a white space. The first word should be a command
+ name. The quotation character for an argument with spaces,
+ including a pathname, should be ". ' should not be used.
+
+ Internally, all arguments are quoted by ' (Unix) or " (Windows)
+ before calling the system() function in order to forbid execution
+ of any embedded command. In addition, on Windows, special
+ characters of cmd.exe are escaped by using (^).
+
+ If the --shell-escape option is given, we set
+ shellenabledp = 1 and restrictedshell = 0, i.e., any command is allowed.
+ If the --shell-restricted option is given, we set
+ shellenabledp = 1 and restrictedshell = 1, i.e., only given cmds allowed.
+ If the --no-shell-escape option is given, we set
+ shellenabledp = -1 (and restrictedshell is irrelevant).
+ If none of these option are given, there are three cases:
+ (1) In the case where
+ shell_escape = y or
+ shell_escape = t or
+ shell_escape = 1
+ it becomes shellenabledp = 1 and restrictedshell = 0,
+ that is, any command is allowed.
+ (2) In the case where
+ shell_escape = p
+ it becomes shellenabledp = 1 and restrictedshell = 1,
+ that is, restricted shell escape is allowed.
+ (3) In all other cases, shellenabledp = 0, that is, shell
+ escape is forbidden. The value of restrictedshell is
+ irrelevant if shellenabledp == 0.
+*/
+
+#ifdef TeX
+
+/* cmdlist is a list of allowed commands which are given like this:
+ shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun
+ in texmf.cnf. */
+
+static char **cmdlist = NULL;
+
+void mk_shellcmdlist(char *v)
+{
+ char **p;
+ char *q, *r;
+ unsigned int n;
+
+ q = v;
+ n = 0;
+
+/* analyze the variable shell_escape_commands = foo,bar,...
+ spaces before and after (,) are not allowed. */
+
+ while ((r = strchr(q, ',')) != 0) {
+ n++;
+ r++;
+ q = r;
+ }
+ if (*q)
+ n++;
+ cmdlist = (char **) xmalloc((unsigned) ((n + 1) * sizeof(char *)));
+ p = cmdlist;
+ q = v;
+ while ((r = strchr(q, ',')) != 0) {
+ *r = '\0';
+ *p = (char *) xmalloc((unsigned) strlen(q) + 1);
+ strcpy(*p, q);
+ *r = ',';
+ r++;
+ q = r;
+ p++;
+ }
+ if (*q) {
+ *p = (char *) xmalloc((unsigned) strlen(q) + 1);
+ strcpy(*p, q);
+ p++;
+ *p = NULL;
+ } else
+ *p = NULL;
+}
+
+/* Called from maininit. Not static because also called from
+ luatexdir/lua/luainit.c. */
+
+void init_shell_escape(void)
+{
+ if (shellenabledp < 0) { /* --no-shell-escape on cmd line */
+ shellenabledp = 0;
+
+ } else {
+ if (shellenabledp == 0) { /* no shell options on cmd line, check cnf */
+ char *v1 = kpse_var_value("shell_escape");
+ if (v1) {
+ if (*v1 == 't' || *v1 == 'y' || *v1 == '1') {
+ shellenabledp = 1;
+ } else if (*v1 == 'p') {
+ shellenabledp = 1;
+ restrictedshell = 1;
+ }
+ free(v1);
+ }
+ }
+
+ /* If shell escapes are restricted, get allowed cmds from cnf. */
+ if (shellenabledp && restrictedshell == 1) {
+ char *v2 = kpse_var_value("shell_escape_commands");
+ if (v2) {
+ mk_shellcmdlist(v2);
+ free(v2);
+ }
+ }
+ }
+}
+
+# ifdef WIN32
+# define QUOTE '"'
+# else
+# define QUOTE '\''
+# endif
+
+# ifdef WIN32
+static int char_needs_quote(int c)
+{
+/* special characters of cmd.exe */
+
+ return (c == '&' || c == '|' || c == '%' || c == '<' ||
+ c == '>' || c == ';' || c == ',' || c == '(' || c == ')');
+}
+# endif
+
+static int Isspace(char c)
+{
+ return (c == ' ' || c == '\t');
+}
+
+/* return values:
+ -1 : invalid quotation of an argument
+ 0 : command is not allowed
+ 2 : restricted shell escape, CMD is allowed.
+
+ We set *SAFECMD to a safely-quoted version of *CMD; this is what
+ should get executed. And we set CMDNAME to its first word; this is
+ what is checked against the shell_escape_commands list. */
+
+int shell_cmd_is_allowed(const char **cmd, char **safecmd, char **cmdname)
+{
+ char **p;
+ char *buf;
+ char *s, *d;
+ const char *ss;
+ int pre;
+ unsigned spaces;
+ int allow = 0;
+
+ /* pre == 1 means that the previous character is a white space
+ pre == 0 means that the previous character is not a white space */
+ buf = (char *) xmalloc((unsigned) strlen(*cmd) + 1);
+ strcpy(buf, *cmd);
+ s = buf;
+ while (Isspace(*s))
+ s++;
+ d = s;
+ while (!Isspace(*d) && *d)
+ d++;
+ *d = '\0';
+
+ /* *cmdname is the first word of the command line. For example,
+ *cmdname == "kpsewhich" for
+ \write18{kpsewhich --progname=dvipdfm --format="other text files" config}
+ */
+ *cmdname = xstrdup(s);
+ free(buf);
+
+ /* Is *cmdname listed in a texmf.cnf vriable as
+ shell_escape_commands = foo,bar,... ? */
+ p = cmdlist;
+ if (p) {
+ while (*p) {
+ if (strcmp(*p, *cmdname) == 0) {
+ /* *cmdname is found in the list, so restricted shell escape
+ is allowed */
+ allow = 2;
+ break;
+ }
+ p++;
+ }
+ }
+ if (allow == 2) {
+ spaces = 0;
+ for (ss = *cmd; *ss; ss++) {
+ if (Isspace(*ss))
+ spaces++;
+ }
+
+ /* allocate enough memory (too much?) */
+# ifdef WIN32
+ *safecmd =
+ (char *) xmalloc(2 * (unsigned) strlen(*cmd) + 3 + 2 * spaces);
+# else
+ *safecmd = (char *) xmalloc((unsigned) strlen(*cmd) + 3 + 2 * spaces);
+# endif
+
+ /* make a safe command line *safecmd */
+ ss = *cmd;
+ while (Isspace(*ss))
+ ss++;
+ d = *safecmd;
+ while (!Isspace(*ss) && *ss)
+ *d++ = *ss++;
+
+ pre = 1;
+ while (*ss) {
+ /* Quotation given by a user. " should always be used; we
+ transform it below. On Unix, if ' is used, simply immediately
+ return a quotation error. */
+ if (*ss == '\'') {
+ return -1;
+ }
+
+ if (*ss == '"') {
+ /* All arguments are quoted as 'foo' (Unix) or "foo" (Windows)
+ before calling system(). Therefore closing QUOTE is necessary
+ if the previous character is not a white space.
+ example:
+ --format="other text files" becomes
+ '--format=''other text files' (Unix)
+ "--format=""other test files" (Windows) */
+
+ if (pre == 0)
+ *d++ = QUOTE;
+
+ pre = 0;
+ /* output the quotation mark for the quoted argument */
+ *d++ = QUOTE;
+ ss++;
+
+ while (*ss != '"') {
+ /* Illegal use of ', or closing quotation mark is missing */
+ if (*ss == '\'' || *ss == '\0')
+ return -1;
+# ifdef WIN32
+ if (char_needs_quote(*ss))
+ *d++ = '^';
+# endif
+ *d++ = *ss++;
+ }
+
+ /* Closing quotation mark will be output afterwards, so
+ we do nothing here */
+ ss++;
+
+ /* The character after the closing quotation mark
+ should be a white space or NULL */
+ if (!Isspace(*ss) && *ss)
+ return -1;
+
+ /* Beginning of a usual argument */
+ } else if (pre == 1 && !Isspace(*ss)) {
+ pre = 0;
+ *d++ = QUOTE;
+# ifdef WIN32
+ if (char_needs_quote(*ss))
+ *d++ = '^';
+# endif
+ *d++ = *ss++;
+ /* Ending of a usual argument */
+
+ } else if (pre == 0 && Isspace(*ss)) {
+ pre = 1;
+ /* Closing quotation mark */
+ *d++ = QUOTE;
+ *d++ = *ss++;
+ } else {
+ /* Copy a character from *cmd to *safecmd. */
+# ifdef WIN32
+ if (char_needs_quote(*ss))
+ *d++ = '^';
+# endif
+ *d++ = *ss++;
+ }
+ }
+ /* End of the command line */
+ if (pre == 0) {
+ *d++ = QUOTE;
+ }
+ *d = '\0';
+ }
+
+ return allow;
+}
+
+/* We should only be called with shellenabledp == 1.
+ Return value:
+ -1 if a quotation syntax error.
+ 0 if CMD is not allowed; given shellenabledp==1, this is because
+ shell escapes are restricted and CMD is not allowed.
+ 1 if shell escapes are not restricted, hence any command is allowed.
+ 2 if shell escapes are restricted and CMD is allowed. */
+
+int runsystem(char *cmd)
+{
+ int allow = 0;
+ char *safecmd = NULL;
+ char *cmdname = NULL;
+
+ if (shellenabledp <= 0) {
+ return 0;
+ }
+
+ /* If restrictedshell == 0, any command is allowed. */
+ if (restrictedshell == 0) {
+ allow = 1;
+ } else {
+ const char *thecmd = cmd;
+ allow = shell_cmd_is_allowed(&thecmd, &safecmd, &cmdname);
+ }
+
+ if (allow == 1)
+ (void) system(cmd);
+ else if (allow == 2)
+ (void) system(safecmd);
+
+ if (safecmd)
+ free(safecmd);
+ if (cmdname)
+ free(cmdname);
+
+ return allow;
+}
+
+#endif
+
+/* The main program, etc. */
+
+extern void lua_initialize(int ac, char **av);
+
+/* What we were invoked as and with. */
+char **argv;
+int argc;
+
+/* The C version of what might wind up in |TEX_format_default|. */
+string dump_name;
+
+/* The C version of the jobname, if given. */
+const_string c_job_name;
+
+/* Full source file name. */
+extern string fullnameoffile;
+
+/* The main body of the WEB is transformed into this procedure. */
+extern TEXDLL void mainbody(void);
+
+char *ptexbanner;
+
+#if !defined(WIN32) || defined(__MINGW32__)
+/* The entry point: set up for reading the command line, which will
+ happen in `topenin', then call the main body. */
+
+int main(int ac, string * av)
+{
+# ifdef __EMX__
+ _wildcard(&ac, &av);
+ _response(&ac, &av);
+# endif
+
+# ifdef WIN32
+ _setmaxstdio(2048);
+# endif
+
+ lua_initialize(ac, av);
+
+ /* Call the real main program. */
+ mainbody();
+
+ return EXIT_SUCCESS;
+}
+#endif /* !(WIN32 || __MINGW32__) */
+
+
+/* This is supposed to ``open the terminal for input'', but what we
+ really do is copy command line arguments into TeX's or Metafont's
+ buffer, so they can handle them. If nothing is available, or we've
+ been called already (and hence, argc==0), we return with
+ `last=first'. */
+
+void topenin(void)
+{
+ int i;
+
+
+ buffer[first] = 0; /* In case there are no arguments. */
+
+ if (optind < argc) { /* We have command line arguments. */
+ int k = first;
+ for (i = optind; i < argc; i++) {
+ char *ptr = &(argv[i][0]);
+ /* Don't use strcat, since in Aleph the buffer elements aren't
+ single bytes. */
+ while (*ptr) {
+ buffer[k++] = (packed_ASCII_code) * (ptr++);
+ }
+ buffer[k++] = ' ';
+ }
+ argc = 0; /* Don't do this again. */
+ buffer[k] = 0;
+ }
+
+ /* Find the end of the buffer. */
+ for (last = first; buffer[last]; ++last);
+
+ /* Make `last' be one past the last non-blank character in `buffer'. */
+ /* ??? The test for '\r' should not be necessary. */
+ for (--last; last >= first
+ && ISBLANK(buffer[last]) && buffer[last] != '\r'; --last);
+ last++;
+
+ /* One more time, this time converting to TeX's internal character
+ representation. */
+}
+
+/* IPC for TeX. By Tom Rokicki for the NeXT; it makes TeX ship out the
+ DVI file in a pipe to TeXView so that the output can be displayed
+ incrementally. Shamim Mohamed adapted it for Web2c. */
+#if defined (TeX) && defined (IPC)
+
+# include <sys/socket.h>
+# include <fcntl.h>
+# ifndef O_NONBLOCK /* POSIX */
+# ifdef O_NDELAY /* BSD */
+# define O_NONBLOCK O_NDELAY
+# else
+# ifdef FNDELAY /* NeXT */
+# define O_NONBLOCK O_FNDELAY
+# else
+what the fcntl ? cannot implement IPC without equivalent for O_NONBLOCK.
+# endif /* no FNDELAY */
+# endif /* no O_NDELAY */
+# endif /* no O_NONBLOCK */
+# ifndef IPC_PIPE_NAME /* $HOME is prepended to this. */
+# define IPC_PIPE_NAME "/.TeXview_Pipe"
+# endif
+# ifndef IPC_SERVER_CMD /* Command to run to start the server. */
+# define IPC_SERVER_CMD "open `which TeXview`"
+# endif
+ struct msg {
+ short namelength; /* length of auxiliary data */
+ int eof; /* new eof for dvi file */
+# if 0 /* see usage of struct msg below */
+ char more_data[0]; /* where the rest of the stuff goes */
+# endif
+};
+
+static char *ipc_name;
+static struct sockaddr *ipc_addr;
+static int ipc_addr_len;
+
+static int ipc_make_name(void)
+{
+ if (ipc_addr_len == 0) {
+ string s = getenv("HOME");
+ if (s) {
+ ipc_addr = (struct sockaddr *) xmalloc(strlen(s) + 40);
+ ipc_addr->sa_family = 0;
+ ipc_name = ipc_addr->sa_data;
+ strcpy(ipc_name, s);
+ strcat(ipc_name, IPC_PIPE_NAME);
+ ipc_addr_len = strlen(ipc_name) + 3;
+ }
+ }
+ return ipc_addr_len;
+}
+
+
+static int sock = -1;
+
+static int ipc_is_open(void)
+{
+ return sock >= 0;
+}
+
+
+static void ipc_open_out(void)
+{
+# ifdef IPC_DEBUG
+ fputs("tex: Opening socket for IPC output ...\n", stderr);
+# endif
+ if (sock >= 0) {
+ return;
+ }
+
+ if (ipc_make_name() < 0) {
+ sock = -1;
+ return;
+ }
+
+ sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (sock >= 0) {
+ if (connect(sock, ipc_addr, ipc_addr_len) != 0
+ || fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
+ close(sock);
+ sock = -1;
+ return;
+ }
+# ifdef IPC_DEBUG
+ fputs("tex: Successfully opened IPC socket.\n", stderr);
+# endif
+ }
+}
+
+
+static void ipc_close_out(void)
+{
+# ifdef IPC_DEBUG
+ fputs("tex: Closing output socket ...\n", stderr);
+# endif
+ if (ipc_is_open()) {
+ close(sock);
+ sock = -1;
+ }
+}
+
+
+static void ipc_snd(int n, int is_eof, char *data)
+{
+ struct {
+ struct msg msg;
+ char more_data[1024];
+ } ourmsg;
+
+# ifdef IPC_DEBUG
+ fputs("tex: Sending message to socket ...\n", stderr);
+# endif
+ if (!ipc_is_open()) {
+ return;
+ }
+
+ ourmsg.msg.namelength = n;
+ ourmsg.msg.eof = is_eof;
+ if (n) {
+ strcpy(ourmsg.more_data, data);
+ }
+ n += sizeof(struct msg);
+# ifdef IPC_DEBUG
+ fputs("tex: Writing to socket...\n", stderr);
+# endif
+ if (write(sock, &ourmsg, n) != n) {
+ ipc_close_out();
+ }
+# ifdef IPC_DEBUG
+ fputs("tex: IPC message sent.\n", stderr);
+# endif
+}
+
+
+/* This routine notifies the server if there is an eof, or the filename
+ if a new DVI file is starting. This is the routine called by TeX.
+ Aleph defines str_start(#) as str_start_ar[# - too_big_char], with
+ too_big_char = biggest_char + 1 = 65536 (omstr.ch).*/
+
+void ipcpage(int is_eof)
+{
+ static boolean begun = false;
+ unsigned len = 0;
+ string p = (string) "";
+
+ if (!begun) {
+ const_string name; /* Just the filename. */
+ string cwd = xgetcwd();
+
+ ipc_open_out();
+
+ /* Have to pass whole filename to the other end, since it may have
+ been started up and running as a daemon, e.g., as with the NeXT
+ preview program. */
+ name = (const_string) static_pdf->file_name;
+ p = concat3(cwd, DIR_SEP_STRING, name);
+ /* free(name); */
+ len = strlen(p);
+ begun = true;
+ }
+ ipc_snd(len, is_eof, p);
+
+ if (len > 0) {
+ free(p);
+ }
+}
+#endif /* TeX && IPC */
+
+/* Normalize quoting of filename -- that is, only quote if there is a space,
+ and always use the quote-name-quote style. */
+string normalize_quotes(const_string name, const_string mesg)
+{
+ boolean quoted = false;
+ boolean must_quote = (strchr(name, ' ') != NULL);
+ /* Leave room for quotes and NUL. */
+ string ret = (string) xmalloc((unsigned) strlen(name) + 3);
+ string p;
+ const_string q;
+ p = ret;
+ if (must_quote)
+ *p++ = '"';
+ for (q = name; *q; q++) {
+ if (*q == '"')
+ quoted = !quoted;
+ else
+ *p++ = *q;
+ }
+ if (must_quote)
+ *p++ = '"';
+ *p = '\0';
+ if (quoted) {
+ fprintf(stderr, "! Unbalanced quotes in %s %s\n", mesg, name);
+ uexit(1);
+ }
+ return ret;
+}
+
+
+/* All our interrupt handler has to do is set TeX's or Metafont's global
+ variable `interrupt'; then they will do everything needed. */
+#ifdef WIN32
+/* Win32 doesn't set SIGINT ... */
+BOOL WINAPI catch_interrupt(DWORD arg)
+{
+ switch (arg) {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ interrupt = 1;
+ return TRUE;
+ default:
+ /* No need to set interrupt as we are exiting anyway */
+ return FALSE;
+ }
+}
+#else /* not WIN32 */
+static RETSIGTYPE catch_interrupt(int arg)
+{
+ (void) arg;
+ interrupt = 1;
+# ifdef OS2
+ (void) signal(SIGINT, SIG_ACK);
+# else
+ (void) signal(SIGINT, catch_interrupt);
+# endif /* not OS2 */
+}
+#endif /* not WIN32 */
+
+/* Besides getting the date and time here, we also set up the interrupt
+ handler, for no particularly good reason. It's just that since the
+ `fix_date_and_time' routine is called early on (section 1337 in TeX,
+ ``Get the first line of input and prepare to start''), this is as
+ good a place as any. */
+
+void get_date_and_time(int *minutes, int *day, int *month, int *year)
+{
+ time_t myclock = time((time_t *) 0);
+ struct tm *tmptr = localtime(&myclock);
+
+ *minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
+ *day = tmptr->tm_mday;
+ *month = tmptr->tm_mon + 1;
+ *year = tmptr->tm_year + 1900;
+
+ {
+#ifdef SA_INTERRUPT
+ /* Under SunOS 4.1.x, the default action after return from the
+ signal handler is to restart the I/O if nothing has been
+ transferred. The effect on TeX is that interrupts are ignored if
+ we are waiting for input. The following tells the system to
+ return EINTR from read() in this case. From ken@cs.toronto.edu. */
+
+ struct sigaction a, oa;
+
+ a.sa_handler = catch_interrupt;
+ sigemptyset(&a.sa_mask);
+ sigaddset(&a.sa_mask, SIGINT);
+ a.sa_flags = SA_INTERRUPT;
+ sigaction(SIGINT, &a, &oa);
+ if (oa.sa_handler != SIG_DFL)
+ sigaction(SIGINT, &oa, (struct sigaction *) 0);
+#else /* no SA_INTERRUPT */
+# ifdef WIN32
+ SetConsoleCtrlHandler(catch_interrupt, TRUE);
+# else /* not WIN32 */
+ RETSIGTYPE(*old_handler) (int);
+
+ old_handler = signal(SIGINT, catch_interrupt);
+ if (old_handler != SIG_DFL)
+ signal(SIGINT, old_handler);
+# endif /* not WIN32 */
+#endif /* no SA_INTERRUPT */
+ }
+}
+
+/*
+ Getting a high resolution time.
+ */
+void get_seconds_and_micros(int *seconds, int *micros)
+{
+#if defined (HAVE_GETTIMEOFDAY)
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ *seconds = (int)tv.tv_sec;
+ *micros = (int)tv.tv_usec;
+#elif defined (HAVE_FTIME)
+ struct timeb tb;
+ ftime(&tb);
+ *seconds = tb.time;
+ *micros = tb.millitm * 1000;
+#else
+ time_t myclock = time((time_t *) NULL);
+ *seconds = (int) myclock;
+ *micros = 0;
+#endif
+}
+
+/*
+ Generating a better seed numbers
+ */
+int getrandomseed()
+{
+#if defined (HAVE_GETTIMEOFDAY)
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (int)(tv.tv_usec + 1000000 * tv.tv_usec);
+#elif defined (HAVE_FTIME)
+ struct timeb tb;
+ ftime(&tb);
+ return (tb.millitm + 1000 * tb.time);
+#else
+ time_t myclock = time((time_t *) NULL);
+ struct tm *tmptr = localtime(&myclock);
+ return (tmptr->tm_sec + 60 * (tmptr->tm_min + 60 * tmptr->tm_hour));
+#endif
+}
+
+/* Read a line of input as efficiently as possible while still looking
+ like Pascal. We set `last' to `first' and return `false' if we get
+ to eof. Otherwise, we return `true' and set last = first +
+ length(line except trailing whitespace). */
+
+boolean input_line(FILE * f)
+{
+ int i = EOF;
+
+ /* Recognize either LF or CR as a line terminator. */
+ last = first;
+ while (last < buf_size && (i = getc(f)) != EOF && i != '\n' && i != '\r')
+ buffer[last++] = (packed_ASCII_code) i;
+
+ if (i == EOF && errno != EINTR && last == first)
+ return false;
+
+ /* We didn't get the whole line because our buffer was too small. */
+ if (i != EOF && i != '\n' && i != '\r') {
+ fprintf(stderr, "! Unable to read an entire line---bufsize=%u.\n",
+ (unsigned) buf_size);
+ fputs("Please increase buf_size in texmf.cnf.\n", stderr);
+ uexit(1);
+ }
+
+ buffer[last] = ' ';
+ if (last >= max_buf_stack)
+ max_buf_stack = last;
+
+ /* If next char is LF of a CRLF, read it. */
+ if (i == '\r') {
+ while ((i = getc(f)) == EOF && errno == EINTR);
+ if (i != '\n')
+ ungetc(i, f);
+ }
+
+ /* Trim trailing whitespace. */
+ while (last > first && ISBLANK(buffer[last - 1]))
+ --last;
+
+ /* Don't bother using xord if we don't need to. */
+
+ return true;
+}
+
+
+/* This string specifies what the `e' option does in response to an
+ error message. */
+static const_string edit_value = EDITOR;
+
+/* This procedure originally due to sjc@s1-c. TeX & Metafont call it when
+ the user types `e' in response to an error, invoking a text editor on
+ the erroneous source file. FNSTART is how far into FILENAME the
+ actual filename starts; FNLENGTH is how long the filename is. */
+
+void
+calledit(packedASCIIcode * filename,
+ poolpointer fnstart, int fnlength, int linenumber)
+{
+ char *temp, *command;
+ char c;
+ int sdone, ddone, i;
+
+ sdone = ddone = 0;
+ filename += fnstart;
+
+ /* Close any open input files, since we're going to kill the job. */
+ for (i = 1; i <= in_open; i++)
+ xfclose(input_file[i], "inputfile");
+
+ /* Replace the default with the value of the appropriate environment
+ variable or config file value, if it's set. */
+ temp = kpse_var_value(edit_var);
+ if (temp != NULL)
+ edit_value = temp;
+
+ /* Construct the command string. The `11' is the maximum length an
+ integer might be. */
+ command =
+ (string) xmalloc((unsigned) strlen(edit_value) + (unsigned) fnlength +
+ 11);
+
+ /* So we can construct it as we go. */
+ temp = command;
+
+ while ((c = *edit_value++) != 0) {
+ if (c == '%') {
+ switch (c = *edit_value++) {
+ case 'd':
+ if (ddone)
+ FATAL("call_edit: `%%d' appears twice in editor command");
+ sprintf(temp, "%ld", (long int) linenumber);
+ while (*temp != '\0')
+ temp++;
+ ddone = 1;
+ break;
+
+ case 's':
+ if (sdone)
+ FATAL("call_edit: `%%s' appears twice in editor command");
+ for (i = 0; i < fnlength; i++)
+ *temp++ = (char) Xchr(filename[i]);
+ sdone = 1;
+ break;
+
+ case '\0':
+ *temp++ = '%';
+ /* Back up to the null to force termination. */
+ edit_value--;
+ break;
+
+ default:
+ *temp++ = '%';
+ *temp++ = c;
+ break;
+ }
+ } else
+ *temp++ = c;
+ }
+
+ *temp = 0;
+
+ /* Execute the command. */
+#ifdef WIN32
+ /* Win32 reimplementation of the system() command
+ provides opportunity to call it asynchronously */
+ if (win32_system(command, true) != 0)
+#else
+ if (system(command) != 0)
+#endif
+ fprintf(stderr, "! Trouble executing `%s'.\n", command);
+
+ /* Quit, since we found an error. */
+ uexit(1);
+}
+
+/* Read and write dump files. As distributed, these files are
+ architecture dependent; specifically, BigEndian and LittleEndian
+ architectures produce different files. These routines always output
+ BigEndian files. This still does not guarantee them to be
+ architecture-independent, because it is possible to make a format
+ that dumps a glue ratio, i.e., a floating-point number. Fortunately,
+ none of the standard formats do that. */
+
+#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE) /* this fn */
+
+/* This macro is always invoked as a statement. It assumes a variable
+ `temp'. */
+
+# define SWAP(x, y) temp = (x); (x) = (y); (y) = temp
+
+
+/* Make the NITEMS items pointed at by P, each of size SIZE, be the
+ opposite-endianness of whatever they are now. */
+
+static void swap_items(char *p, int nitems, int size)
+{
+ char temp;
+
+ /* Since `size' does not change, we can write a while loop for each
+ case, and avoid testing `size' for each time. */
+ switch (size) {
+ /* 16-byte items happen on the DEC Alpha machine when we are not
+ doing sharable memory dumps. */
+ case 16:
+ while (nitems--) {
+ SWAP(p[0], p[15]);
+ SWAP(p[1], p[14]);
+ SWAP(p[2], p[13]);
+ SWAP(p[3], p[12]);
+ SWAP(p[4], p[11]);
+ SWAP(p[5], p[10]);
+ SWAP(p[6], p[9]);
+ SWAP(p[7], p[8]);
+ p += size;
+ }
+ break;
+
+ case 8:
+ while (nitems--) {
+ SWAP(p[0], p[7]);
+ SWAP(p[1], p[6]);
+ SWAP(p[2], p[5]);
+ SWAP(p[3], p[4]);
+ p += size;
+ }
+ break;
+
+ case 4:
+ while (nitems--) {
+ SWAP(p[0], p[3]);
+ SWAP(p[1], p[2]);
+ p += size;
+ }
+ break;
+
+ case 2:
+ while (nitems--) {
+ SWAP(p[0], p[1]);
+ p += size;
+ }
+ break;
+
+ case 1:
+ /* Nothing to do. */
+ break;
+
+ default:
+ FATAL1("Can't swap a %d-byte item for (un)dumping", size);
+ }
+}
+#endif /* not WORDS_BIGENDIAN and not NO_DUMP_SHARE */
+
+
+/* Here we write NITEMS items, each item being ITEM_SIZE bytes long.
+ The pointer to the stuff to write is P, and we write to the file
+ OUT_FILE. */
+
+void do_dump(char *p, int item_size, int nitems, FILE * out_file)
+{
+#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
+ swap_items(p, nitems, item_size);
+#endif
+
+ if (fwrite(p, (size_t) item_size, (size_t) nitems, out_file) !=
+ (unsigned) nitems) {
+ fprintf(stderr, "! Could not write %d %d-byte item(s).\n", nitems,
+ item_size);
+ uexit(1);
+ }
+
+ /* Have to restore the old contents of memory, since some of it might
+ get used again. */
+#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
+ swap_items(p, nitems, item_size);
+#endif
+}
+
+
+/* Here is the dual of the writing routine. */
+
+void do_undump(char *p, int item_size, int nitems, FILE * in_file)
+{
+ if (fread(p, (size_t) item_size, (size_t) nitems, in_file) !=
+ (size_t) nitems)
+ FATAL2("Could not undump %d %d-byte item(s)", nitems, item_size);
+
+#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
+ swap_items(p, nitems, item_size);
+#endif
+}
+
+
+/* Get the job name to be used, which may have been set from the
+ command line. */
+str_number getjobname(str_number name)
+{
+ str_number ret = name;
+ if (c_job_name != NULL)
+ ret = maketexstring(c_job_name);
+ return ret;
+}
diff --git a/Build/source/texk/web2c/luatexdir/luatex.ch b/Build/source/texk/web2c/luatexdir/luatex.ch
deleted file mode 100644
index 7dd56dcb85f..00000000000
--- a/Build/source/texk/web2c/luatexdir/luatex.ch
+++ /dev/null
@@ -1,2176 +0,0 @@
-% luatex.ch
-%
-% Copyright 2006-2008 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.
-%
-% 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 <http://www.gnu.org/licenses/>.
-%
-% $Id$
-%
-@x
- \def\?##1]{\hbox to 1in{\hfil##1.\ }}
- }
-@y
- \def\?##1]{\hbox{Changes to \hbox to 1em{\hfil##1}.\ }}
- }
-\let\maybe=\iftrue
-@z
-
-@x
-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
-
-@x
-program TEX; {all file names are defined dynamically}
-label @<Labels in the outer block@>@/
-@y
-program TEX; {all file names are defined dynamically}
-@z
-
-@x
-@ Three labels must be declared in the main program, so we give them
-symbolic names.
-
-@d start_of_TEX=1 {go here when \TeX's variables are initialized}
-@d end_of_TEX=9998 {go here to close files and terminate gracefully}
-@d final_end=9999 {this label marks the ending of the program}
-
-@<Labels in the out...@>=
-start_of_TEX@t\hskip-2pt@>, end_of_TEX@t\hskip-2pt@>,@,final_end;
- {key control points}
-@y
-@ For Web2c, labels are not declared in the main program, but
-we still have to declare the symbolic names.
-
-@d start_of_TEX=1 {go here when \TeX's variables are initialized}
-@d final_end=9999 {this label marks the ending of the program}
-@z
-
-@x
-@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging}
-@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging}
-@y
-@d debug== ifdef('TEXMF_DEBUG')
-@d gubed== endif('TEXMF_DEBUG')
-@z
-
-@x
-@d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering
- usage statistics}
-@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering
- usage statistics}
-@y
-@d stat==ifdef('STAT')
-@d tats==endif('STAT')
-@z
-
-@x
-the codewords `$|init|\ldots|tini|$'.
-
-@d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version}
-@d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version}
-@y
-the codewords `$|init|\ldots|tini|$' for declarations and by the codewords
-`$|Init|\ldots|Tini|$' for executable code. This distinction is helpful for
-implementations where a run-time switch differentiates between the two
-versions of the program.
-
-@d init==ifdef('INITEX')
-@d tini==endif('INITEX')
-@d Init==init if ini_version then begin
-@d Tini==end;@+tini
-@f Init==begin
-@f Tini==end
-@z
-
-@x
-@!init @<Initialize table entries (done by \.{INITEX} only)@>@;@+tini
-@y
-@!Init @<Initialize table entries (done by \.{INITEX} only)@>@;@+Tini
-@z
-
-@x
-@<Constants...@>=
-@!buf_size=500; {maximum number of characters simultaneously present in
- current lines of open files and in control sequences between
- \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|}
-@!error_line=72; {width of context lines on terminal error messages}
-@!half_error_line=42; {width of first lines of contexts in terminal
- error messages; should be between 30 and |error_line-15|}
-@!max_print_line=79; {width of longest text lines output; should be at least 60}
-@!stack_size=200; {maximum number of simultaneous input sources}
-@!max_in_open=6; {maximum number of input files and error insertions that
- can be going on simultaneously}
-@!param_size=60; {maximum number of simultaneous macro parameters}
-@!nest_size=40; {maximum number of semantic levels simultaneously active}
-@!max_strings=3000; {maximum number of strings; must not exceed |max_halfword|}
-@!string_vacancies=8000; {the minimum number of characters that should be
- available for the user's control sequences and font names,
- after \TeX's own error messages are stored}
-@!pool_size=32000; {maximum number of characters in strings, including all
- error messages and help texts, and the names of all fonts and
- control sequences; must exceed |string_vacancies| by the total
- length of \TeX's own strings, which is currently about 23000}
-@!save_size=600; {space for saving values outside of current group; must be
- at most |max_halfword|}
-@!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8}
-@!expand_depth=10000; {limits recursive calls of the |expand| procedure}
-@!file_name_size=40; {file names shouldn't be longer than this}
-@!pool_name='TeXformats:TEX.POOL ';
- {string of length |file_name_size|; tells where the string pool appears}
-@y
-@d file_name_size == max_halfword-1 { has to be big enough to force namelength into integer }
-@d ssup_error_line = 255
-@d ssup_max_strings == 262143
-{Larger values than 65536 cause the arrays consume much more memory.}
-
-@<Constants...@>=
-@!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}
-@#
-
-@!inf_main_memory = 2000000;
-@!sup_main_memory = 32000000;
-
-@!inf_max_strings = 100000;
-@!sup_max_strings = ssup_max_strings;
-@!inf_strings_free = 100;
-@!sup_strings_free = sup_max_strings;
-
-@!inf_buf_size = 500;
-@!sup_buf_size = 100000000;
-
-@!inf_nest_size = 40;
-@!sup_nest_size = 4000;
-
-@!inf_max_in_open = 6;
-@!sup_max_in_open = 127;
-
-@!inf_param_size = 60;
-@!sup_param_size = 6000;
-
-@!inf_save_size = 600;
-@!sup_save_size = 80000;
-
-@!inf_stack_size = 200;
-@!sup_stack_size = 30000;
-
-@!inf_dvi_buf_size = 800;
-@!sup_dvi_buf_size = 65536;
-
-@!inf_pool_size = 128000;
-@!sup_pool_size = 40000000;
-@!inf_pool_free = 1000;
-@!sup_pool_free = sup_pool_size;
-@!inf_string_vacancies = 8000;
-@!sup_string_vacancies = sup_pool_size - 23000;
-
-@!sup_hash_extra = sup_max_strings;
-@!inf_hash_extra = 0;
-
-@!sup_ocp_list_size = 1000000;
-@!inf_ocp_list_size = 1000;
-@!sup_ocp_buf_size = 100000000;
-@!inf_ocp_buf_size = 1000;
-@!sup_ocp_stack_size = 1000000;
-@!inf_ocp_stack_size = 1000;
-
-@!inf_expand_depth = 100;
-@!sup_expand_depth = 1000000;
-@z
-
-@x
-@d incr(#) == #:=#+1 {increase a variable by unity}
-@d decr(#) == #:=#-1 {decrease a variable by unity}
-@y
-@z
-
-@x
-@d text_char == char {the data type of characters in text files}
-@y
-@d text_char == ASCII_code {the data type of characters in text files}
-@z
-
-@x
-@!nameoffile:packed array[1..file_name_size] of char;@;@/
- {on some systems this may be a \&{record} variable}
-@y
-@!nameoffile:^packed_ASCII_code;
-@z
-
-@x
-@ The \ph\ compiler with which the present version of \TeX\ was prepared has
-extended the rules of \PASCAL\ in a very convenient way. To open file~|f|,
-we can write
-$$\vbox{\halign{#\hfil\qquad&#\hfil\cr
-|reset(f,@t\\{name}@>,'/O')|&for input;\cr
-|rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$
-The `\\{name}' parameter, which is of type `{\bf packed array
-$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of
-the external file that is being opened for input or output.
-Blank spaces that might appear in \\{name} are ignored.
-
-The `\.{/O}' parameter tells the operating system not to issue its own
-error messages if something goes wrong. If a file of the specified name
-cannot be found, or if such a file cannot be opened for some other reason
-(e.g., someone may already be trying to write the same file), we will have
-|@!erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows
-\TeX\ to undertake appropriate corrective action.
-@:PASCAL H}{\ph@>
-@^system dependencies@>
-
-\TeX's file-opening procedures return |false| if no file identified by
-|nameoffile| could be opened.
-
-@d reset_OK(#)==erstat(#)=0
-@d rewrite_OK(#)==erstat(#)=0
-
-@p function a_open_in(var f:alpha_file):boolean;
- {open a text file for input}
-begin reset(f,nameoffile,'/O'); a_open_in:=reset_OK(f);
-end;
-@#
-function a_open_out(var f:alpha_file):boolean;
- {open a text file for output}
-begin rewrite(f,nameoffile,'/O'); a_open_out:=rewrite_OK(f);
-end;
-@#
-function b_open_in(var f:byte_file):boolean;
- {open a binary file for input}
-begin reset(f,nameoffile,'/O'); b_open_in:=reset_OK(f);
-end;
-@#
-function b_open_out(var f:byte_file):boolean;
- {open a binary file for output}
-begin rewrite(f,nameoffile,'/O'); b_open_out:=rewrite_OK(f);
-end;
-@#
-function w_open_in(var f:word_file):boolean;
- {open a word file for input}
-begin reset(f,nameoffile,'/O'); w_open_in:=reset_OK(f);
-end;
-@#
-function w_open_out(var f:word_file):boolean;
- {open a word file for output}
-begin rewrite(f,nameoffile,'/O'); w_open_out:=rewrite_OK(f);
-end;
-@y
-@ All of the file opening functions are defined in C.
-@z
-
-@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
-output, the |close| operation makes the corresponding external file appear
-on the user's area, ready to be read.
-
-These procedures should not generate error messages if a file is
-being closed before it has been successfully opened.
-
-@p procedure a_close(var f:alpha_file); {close a text file}
-begin close(f);
-end;
-@#
-procedure b_close(var f:byte_file); {close a binary file}
-begin close(f);
-end;
-@#
-procedure w_close(var f:word_file); {close a word file}
-begin close(f);
-end;
-@y
-@ And all the file closing routines as well.
-@z
-
-@x
-@!buffer:array[0..buf_size] of packed_ASCII_code; {lines of characters being read}
-@y
-@!buffer:^packed_ASCII_code; {lines of characters being read}
-@z
-
-@x
-@p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean;
- {inputs the next line or returns |false|}
-var last_nonblank:0..buf_size; {|last| with trailing blanks removed}
-begin if bypass_eoln then if not eof(f) then get(f);
- {input the first character of the line into |f^|}
-last:=first; {cf.\ Matthew 19\thinspace:\thinspace30}
-if eof(f) then input_ln:=false
-else begin last_nonblank:=first;
- while not eoln(f) do
- begin if last>=max_buf_stack then
- begin max_buf_stack:=last+1;
- if max_buf_stack=buf_size then
- @<Report overflow of the input buffer, and abort@>;
- end;
- buffer[last]:=f^; get(f); incr(last);
- if buffer[last-1]<>" " then last_nonblank:=last;
- end;
- last:=last_nonblank; input_ln:=true;
- end;
-end;
-@y
-We define |input_ln| in C, for efficiency. Nevertheless we quote the module
-`Report overflow of the input buffer, and abort' here in order to make
-\.{WEAVE} happy, since part of that module is needed by e-TeX.
-
-@p @{ @<Report overflow of the input buffer, and abort@> @}
-@z
-
-@x
-@<Glob...@>=
-@!term_in:alpha_file; {the terminal as an input file}
-@!term_out:alpha_file; {the terminal as an output file}
-@y
-@d term_in==stdin {the terminal as an input file}
-@d term_out==stdout {the terminal as an output file}
-
-@<Glob...@>=
-@!init
-@!ini_version:boolean; {are we \.{INITEX}?}
-@!dump_option:boolean; {was the dump name option used?}
-@!dump_line:boolean; {was a \.{\%\AM format} line seen?}
-tini@/
-@#
-@!bound_default:integer; {temporary for setup}
-@!bound_name:constcstring; {temporary for setup}
-@#
-@!error_line:integer; {width of context lines on terminal error messages}
-@!half_error_line:integer; {width of first lines of contexts in terminal
- error messages; should be between 30 and |error_line-15|}
-@!max_print_line:integer;
- {width of longest text lines output; should be at least 60}
-@!ocp_list_size:integer;
-@!ocp_buf_size:integer;
-@!ocp_stack_size:integer;
-@!max_strings:integer; {maximum number of strings; must not exceed |max_halfword|}
-@!strings_free:integer; {strings available after format loaded}
-@!string_vacancies:integer; {the minimum number of characters that should be
- available for the user's control sequences and font names,
- after \TeX's own error messages are stored}
-@!pool_size:integer; {maximum number of characters in strings, including all
- error messages and help texts, and the names of all fonts and
- control sequences; must exceed |string_vacancies| by the total
- length of \TeX's own strings, which is currently about 23000}
-@!pool_free:integer;{pool space free after format loaded}
-@!font_k:integer; {loop variable for initialization}
-@!buf_size:integer; {maximum number of characters simultaneously present in
- current lines of open files and in control sequences between
- \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|}
-@!stack_size:integer; {maximum number of simultaneous input sources}
-@!max_in_open:integer; {maximum number of input files and error insertions that
- can be going on simultaneously}
-@!param_size:integer; {maximum number of simultaneous macro parameters}
-@!nest_size:integer; {maximum number of semantic levels simultaneously active}
-@!save_size:integer; {space for saving values outside of current group; must be
- at most |max_halfword|}
-@!dvi_buf_size:integer; {size of the output buffer; must be a multiple of 8}
-@!expand_depth:integer; {limits recursive calls of the |expand| procedure}
-@!parsefirstlinep:cinttype; {parse the first line for options}
-@!filelineerrorstylep:cinttype; {format messages as file:line:error}
-@!haltonerrorp:cinttype; {stop at first error}
-@!quoted_filename:boolean; {current filename is quoted}
-@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}
-@d t_open_out==rewrite(term_out,'TTY:','/O') {open the terminal for text output}
-@y
-@ Here is how to open the terminal files. |t_open_out| does nothing.
-|t_open_in|, on the other hand, does the work of ``rescanning,'' or getting
-any command line arguments the user has provided. It's defined in C.
-
-@d t_open_out == {output already open for text output}
-@z
-
-@x
-these operations can be specified in \ph:
-@:PASCAL H}{\ph@>
-@^system dependencies@>
-
-@d update_terminal == break(term_out) {empty the terminal output buffer}
-@d clear_terminal == break_in(term_in,true) {clear the terminal input buffer}
-@y
-these operations can be specified with {\mc UNIX}. |update_terminal|
-does an |fflush|. |clear_terminal| is redefined
-to do nothing, since the user should control the terminal.
-@^system dependencies@>
-
-@d update_terminal == fflush (term_out)
-@d clear_terminal == do_nothing
-@z
-
-@x
-@<Report overflow of the input buffer, and abort@>=
-if format_ident=0 then
- begin writeln(term_out,'Buffer size exceeded!'); goto final_end;
-@.Buffer size exceeded@>
- end
-else
- check_buffer_overflow(buf_size+10) { need a little bit more}
-@y
-@<Report overflow of the input buffer, and abort@>=
- check_buffer_overflow(buf_size+10) { need a little bit more}
-@z
-
-@x
-@ The following program does the required initialization
-without retrieving a possible command line.
-It should be clear how to modify this routine to deal with command lines,
-if the system permits them.
-@^system dependencies@>
-
-@p function init_terminal:boolean; {gets the terminal input started}
-label exit;
-begin t_open_in;
-@y
-@ The following program does the required initialization.
-Iff anything has been specified on the command line, then |t_open_in|
-will return with |last > first|.
-@^system dependencies@>
-
-@p function init_terminal:boolean; {gets the terminal input started}
-label exit;
-begin t_open_in;
-if last > first then
- begin loc := first;
- while (loc < last) and (buffer[loc]=' ') do incr(loc);
- if loc < last then
- begin init_terminal := true; goto exit;
- end;
- end;
-@z
-
-@x
- write(term_out,'! End of file on the terminal... why?');
-@y
- writeln(term_out,'! End of file on the terminal... why?');
-@z
-
-@x
-@!str_pool:packed array[pool_pointer] of packed_ASCII_code; {the characters}
-@!str_start : array[str_number] of pool_pointer; {the starting pointers}
-@y
-@!str_pool: ^packed_ASCII_code; {the characters}
-@!str_start : ^pool_pointer; {the starting pointers}
-@z
-
-@x
-@p @!init function get_strings_started:boolean; {initializes the string pool,
-@y
-@p @t\4@>@<Declare additional routines for string recycling@>@/
-
-@!init function get_strings_started:boolean; {initializes the string pool,
-@z
-
-@x
-would like string @'32 to be the single character @'32 instead of the
-@y
-would like string @'32 to be printed as the single character @'32
-instead of the
-@z
-
-@x
-@!trick_buf:array[0..error_line] of packed_ASCII_code; {circular buffer for
-@y
-@!trick_buf:array[0..ssup_error_line] of packed_ASCII_code; {circular buffer for
-@z
-
-@x
-@d error_stop_mode=3 {stops at every opportunity to interact}
-@y
-@d error_stop_mode=3 {stops at every opportunity to interact}
-@d unspecified_mode=4 {extra value for command-line switch}
-@z
-
-@x
- print_nl("! "); print(#);
-@y
- if filelineerrorstylep then print_file_line
- else print_nl("! ");
- print(#);
-@z
-
-@x
-@!interaction:batch_mode..error_stop_mode; {current level of interaction}
-@y
-@!interaction:batch_mode..error_stop_mode; {current level of interaction}
-@!interactionoption:batch_mode..unspecified_mode; {set from command line}
-@z
-
-@x
-@ @<Set init...@>=interaction:=error_stop_mode;
-@y
-@ @<Set init...@>=if interactionoption=unspecified_mode then
- interaction:=error_stop_mode
-else
- interaction:=interactionoption;
-@z
-
-@x
-@<Error hand...@>=
-procedure jump_out;
-begin goto end_of_TEX;
-end;
-@y
-@d do_final_end==begin
- update_terminal;
- ready_already:=0;
- if (history <> spotless) and (history <> warning_issued) then
- uexit(1)
- else
- uexit(0);
- end
-
-@<Error hand...@>=
-procedure jump_out;
-begin
-close_files_and_terminate;
-do_final_end;
-end;
-@z
-
-@x
-show_context;
-@y
-show_context;
-if (haltonerrorp) then begin
- history:=fatal_error_stop; jump_out;
-end;
-@z
-
-@x
-|remainder|, holds the remainder after a division.
-
-@<Glob...@>=
-@y
-|remainder|, holds the remainder after a division.
-
-@d remainder==tex_remainder
-
-@<Glob...@>=
-@z
-
-@x
-@!glue_ratio=real; {one-word representation of a glue expansion factor}
-@y
-@z
-
-@x
-macros are simplified in the obvious way when |min_quarterword=0|.
-@^inner loop@>@^system dependencies@>
-
-@d qi(#)==#+min_quarterword
- {to put an |eight_bits| item into a quarterword}
-@d qo(#)==#-min_quarterword
- {to take an |eight_bits| item out of a quarterword}
-@d hi(#)==#+min_halfword
- {to put a sixteen-bit item into a halfword}
-@d ho(#)==#-min_halfword
- {to take a sixteen-bit item from a halfword}
-@y
-macros are simplified in the obvious way when |min_quarterword=0|.
-So they have been simplified here in the obvious way.
-@^inner loop@>@^system dependencies@>
-
-@d qi(#)==# {to put an |eight_bits| item into a quarterword}
-@d qo(#)==# {to take an |eight_bits| item from a quarterword}
-@d hi(#)==# {to put a sixteen-bit item into a halfword}
-@d ho(#)==# {to take a sixteen-bit item from a halfword}
-@z
-
-@x
-@!quarterword = min_quarterword..max_quarterword; {1/4 of a word}
-@!halfword=min_halfword..max_halfword; {1/2 of a word}
-@!two_choices = 1..2; {used when there are two variants in a record}
-@!four_choices = 1..4; {used when there are four variants in a record}
-@!two_halves = packed record@;@/
- @!rh:halfword;
- case two_choices of
- 1: (@!lh:halfword);
- 2: (@!b0:quarterword; @!b1:quarterword);
- end;
-@!four_quarters = packed record@;@/
- @!b0:quarterword;
- @!b1:quarterword;
- @!b2:quarterword;
- @!b3:quarterword;
- end;
-@!memory_word = record@;@/
- case four_choices of
- 1: (@!int:integer);
- 2: (@!gr:glue_ratio);
- 3: (@!hh:two_halves);
- 4: (@!qqqq:four_quarters);
- end;
-@y
-@!quarterword = min_quarterword..max_quarterword;
-@!halfword = min_halfword..max_halfword;
-@!two_choices = 1..2; {used when there are two variants in a record}
-@!four_choices = 1..4; {used when there are four variants in a record}
-@=#include "texmfmem.h";@>
-@z
-
-@x
-begin if m>0 then
- case m div (max_command+1) of
- 0:print("vertical");
- 1:print("horizontal");
- 2:print("display math");
- end
-else if m=0 then print("no")
-else case (-m) div (max_command+1) of
- 0:print("internal vertical");
- 1:print("restricted horizontal");
- 2:print("math");
- end;
-print(" mode");
-end;
-@y
-begin if m>0 then
- case m div (max_command+1) of
- 0:print("vertical mode");
- 1:print("horizontal mode");
- 2:print("display math mode");
- end
-else if m=0 then print("no mode")
-else case (-m) div (max_command+1) of
- 0:print("internal vertical mode");
- 1:print("restricted horizontal mode");
- 2:print("math mode");
- end;
-end;
-
-procedure print_in_mode(@!m:integer); {prints the mode represented by |m|}
-begin if m>0 then
- case m div (max_command+1) of
- 0:print("' in vertical mode");
- 1:print("' in horizontal mode");
- 2:print("' in display math mode");
- end
-else if m=0 then print("' in no mode")
-else case (-m) div (max_command+1) of
- 0:print("' in internal vertical mode");
- 1:print("' in restricted horizontal mode");
- 2:print("' in math mode");
- end;
-end;
-@z
-
-@x
-@!nest:array[0..nest_size] of list_state_record;
-@y
-@!nest:^list_state_record;
-@z
-
-@x
-@<Start a new current page@>;
-@y
-@/{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;
-page_depth:=0; page_max_depth:=0;
-@z
-
-@x
- print_int(nest[p].pg_field); print(" line");
- if nest[p].pg_field<>1 then print_char("s");
-@y
- print_int(nest[p].pg_field);
- if nest[p].pg_field<>1 then print(" lines")
- else print(" line");
-@z
-
-@x
-for k:=null_cs to undefined_control_sequence-1 do
- eqtb[k]:=eqtb[undefined_control_sequence];
-@y
-for k:=null_cs to eqtb_top do
- eqtb[k]:=eqtb[undefined_control_sequence];
-@z
-
-@x
-@ The following procedure, which is called just before \TeX\ initializes its
-input and output, establishes the initial values of the date and time.
-@^system dependencies@>
-Since standard \PASCAL\ cannot provide such information, something special
-is needed. The program here simply specifies July 4, 1776, at noon; but
-users probably want a better approximation to the truth.
-
-@p procedure fix_date_and_time;
-begin time:=12*60; {minutes since midnight}
-day:=4; {fourth day of the month}
-month:=7; {seventh month of the year}
-year:=1776; {Anno Domini}
-end;
-@y
-@ The following procedure, which is called just before \TeX\ initializes its
-input and output, establishes the initial values of the date and time.
-It calls a macro-defined |date_and_time| routine. |date_and_time|
-in turn is a C macro, which calls |get_date_and_time|, passing
-it the addresses of the day, month, etc., so they can be set by the
-routine. |get_date_and_time| also sets up interrupt catching if that
-is conditionally compiled in the C code.
-@^system dependencies@>
-
-@d fix_date_and_time==dateandtime(time,day,month,year)
-@z
-
-@x
-else if n<glue_base then @<Show equivalent |n|, in region 1 or 2@>
-@y
-else if (n<glue_base) or ((n>eqtb_size)and(n<=eqtb_top)) then
- @<Show equivalent |n|, in region 1 or 2@>
-@z
-
-@x
-@!eqtb:array[null_cs..eqtb_size] of memory_word;
-@y
-@!zeqtb:^memory_word;
-@z
-
-@x
-@!hash: array[hash_base..undefined_control_sequence-1] of two_halves;
- {the hash table}
-@!hash_used:pointer; {allocation pointer for |hash|}
-@y
-@!hash: ^two_halves; {the hash table}
-@!yhash: ^two_halves; {auxiliary pointer for freeing hash}
-@!hash_used:pointer; {allocation pointer for |hash|}
-@!hash_extra:pointer; {|hash_extra=hash| above |eqtb_size|}
-@!hash_top:pointer; {maximum of the hash array}
-@!eqtb_top:pointer; {maximum of the |eqtb|}
-@!hash_high:pointer; {pointer to next high hash location}
-@z
-
-@x
-next(hash_base):=0; text(hash_base):=0;
-for k:=hash_base+1 to undefined_control_sequence-1 do hash[k]:=hash[hash_base];
-@y
-@z
-
-@x
-hash_used:=frozen_control_sequence; {nothing is used}
-@y
-hash_used:=frozen_control_sequence; {nothing is used}
-hash_high:=0;
-@z
-
-@x
-else if p>=undefined_control_sequence then print_esc("IMPOSSIBLE.")
-@y
-else if ((p>=undefined_control_sequence)and(p<=eqtb_size))or(p>eqtb_top) then
- print_esc("IMPOSSIBLE.")
-@z
-
-@x
-else if (text(p)<0)or(text(p)>=str_ptr) then print_esc("NONEXISTENT.")
-@y
-else if (text(p)>=str_ptr) then print_esc("NONEXISTENT.")
-@z
-
-@x
-@!save_stack : array[0..save_size] of memory_word;
-@y
-@!save_stack : ^memory_word;
-@z
-
-@x
-if p<int_base then
-@y
-if (p<int_base)or(p>eqtb_size) then
-@z
-
-@x
-if cs_token_flag+undefined_control_sequence>max_halfword then bad:=21;
-@y
-if cs_token_flag+eqtb_size+hash_extra>max_halfword then bad:=21;
-if (hash_offset<0)or(hash_offset>hash_base) then bad:=42;
-@z
-
-@x
-@!input_stack : array[0..stack_size] of in_state_record;
-@y
-@!input_stack : ^in_state_record;
-@z
-
-@x
-@!input_file : array[1..max_in_open] of alpha_file;
-@!line : integer; {current line number in the current source file}
-@!line_stack : array[1..max_in_open] of integer;
-@y
-@!input_file : ^alpha_file;
-@!line : integer; {current line number in the current source file}
-@!line_stack : ^integer;
-@!source_filename_stack : ^str_number;
-@!full_source_filename_stack : ^str_number;
-@z
-
-@x
- begin print_nl("Runaway ");
-@.Runaway...@>
- case scanner_status of
- defining: begin print("definition"); p:=def_ref;
- end;
- matching: begin print("argument"); p:=temp_token_head;
- end;
- aligning: begin print("preamble"); p:=hold_token_head;
- end;
- absorbing: begin print("text"); p:=def_ref;
- end;
- end; {there are no other cases}
-@y
- begin
-@.Runaway...@>
- case scanner_status of
- defining: begin print_nl("Runaway definition"); p:=def_ref;
- end;
- matching: begin print_nl("Runaway argument"); p:=temp_token_head;
- end;
- aligning: begin print_nl("Runaway preamble"); p:=hold_token_head;
- end;
- absorbing: begin print_nl("Runaway text"); p:=def_ref;
- end;
- end; {there are no other cases}
-@z
-
-@x
-@!param_stack:array [0..param_size] of pointer;
- {token list pointers for parameters}
-@y
-@!param_stack: ^pointer;
- {token list pointers for parameters}
-@z
-
-@x
-incr(in_open); push_input; index:=in_open;
-@y
-incr(in_open); push_input; index:=in_open;
-source_filename_stack[index]:=0;full_source_filename_stack[index]:=0;
-@z
-
-@x
-begin input_ptr:=0; max_in_stack:=0;
-@y
-begin input_ptr:=0; max_in_stack:=0;
-source_filename_stack[0]:=0;full_source_filename_stack[0]:=0;
-@z
-
-@x
-if_eof_code: begin scan_four_bit_int; b:=(read_open[cur_val]=closed);
- end;
-@y
-if_eof_code: begin scan_four_bit_int_or_18;
- if cur_val=18 then b:=not shellenabledp
- else b:=(read_open[cur_val]=closed);
- end;
-@z
-
-@x
-@ The file names we shall deal with for illustrative purposes have the
-following structure: If the name contains `\.>' or `\.:', the file area
-consists of all characters up to and including the final such character;
-otherwise the file area is null. If the remaining file name contains
-`\..', the file extension consists of all such characters from the first
-remaining `\..' to the end, otherwise the file extension is null.
-@y
-@ The file names we shall deal with have the
-following structure: If the name contains `\./' or `\.:'
-(for Amiga only), the file area
-consists of all characters up to and including the final such character;
-otherwise the file area is null. If the remaining file name contains
-`\..', the file extension consists of all such characters from the last
-`\..' to the end, otherwise the file extension is null.
-@z
-
-@x
-@!area_delimiter:pool_pointer; {the most recent `\.>' or `\.:', if any}
-@!ext_delimiter:pool_pointer; {the relevant `\..', if any}
-@y
-@!area_delimiter:pool_pointer; {the most recent `\./', if any}
-@!ext_delimiter:pool_pointer; {the most recent `\..', if any}
-@z
-
-@x
-@d TEX_area=="TeXinputs:"
-@.TeXinputs@>
-@d TEX_font_area=="TeXfonts:"
-@.TeXfonts@>
-@y
-In C, the default paths are specified separately.
-@z
-
-@x
-@d append_to_name(#)==begin c:=#; incr(k);
- if k<=file_name_size then nameoffile[k]:=xchr[c];
- end
-@y
-@d append_to_name(#)==begin c:=#; if not (c="""") then begin incr(k);
- if k<=file_name_size then nameoffile[k]:=xchr[c];
- end end
-@z
-
-@x
-for j:=str_start_macro(a) to str_start_macro(a+1)-1 do append_to_name(so(str_pool[j]));
-@y
-if nameoffile then libcfree (nameoffile);
-nameoffile:= xmallocarray (packed_ASCII_code, length(a)+length(n)+length(e)+1);
-for j:=str_start_macro(a) to str_start_macro(a+1)-1 do append_to_name(so(str_pool[j]));
-@z
-
-@x
-for k:=namelength+1 to file_name_size do nameoffile[k]:=' ';
-@y
-nameoffile[namelength+1]:=0;
-@z
-
-@x
-@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}
-@y
-Under {\mc UNIX} we don't give the area part, instead depending
-on the path searching that will happen during file opening. Also, the
-length will be set in the main program.
-
-@d format_area_length=0 {length of its area part}
-@d format_ext_length=4 {length of its `\.{.fmt}' part}
-@z
-
-@x
-@!TEX_format_default:packed array[1..format_default_length] of char;
-
-@ @<Set init...@>=
-TEX_format_default:='TeXformats:plain.fmt';
-@y
-@!format_default_length: integer;
-@!TEX_format_default: ^char;
-
-@ We set the name of the default format file and the length of that name
-in C, instead of Pascal, since we want them to depend on the name of the
-program.
-@z
-
-@x
-for j:=1 to n do append_to_name(TEX_format_default[j]);
-@y
-if nameoffile then libcfree (nameoffile);
-nameoffile := xmallocarray (packed_ASCII_code, n+(b-a+1)+format_ext_length+1);
-for j:=1 to n do append_to_name(TEX_format_default[j]);
-@z
-
-@x
-for k:=namelength+1 to file_name_size do nameoffile[k]:=' ';
-@y
-nameoffile[namelength+1]:=0;
-@z
-
-@x
- pack_buffered_name(0,loc,j-1); {try first without the system file area}
- if w_open_in(fmt_file) then goto found;
- pack_buffered_name(format_area_length,loc,j-1);
- {now try the system format file area}
- if w_open_in(fmt_file) then goto found;
-@y
- pack_buffered_name(0,loc,j-1); {Kpathsea does everything}
- if w_open_in(fmt_file) then goto found;
-@z
-
-@x
- wterm_ln('Sorry, I can''t find that format;',' will try PLAIN.');
-@y
- wterm ('Sorry, I can''t find the format `');
- fputs (stringcast(nameoffile + 1), stdout);
- wterm ('''; will try `');
- fputs (TEX_format_default + 1, stdout);
- wterm_ln ('''.');
-@z
-
-@x
- wterm_ln('I can''t find the PLAIN format file!');
-@.I can't find PLAIN...@>
-@y
- wterm ('I can''t find the format file `');
- fputs (TEX_format_default + 1, stdout);
- wterm_ln ('''!');
-@.I can't find the format...@>
-@z
-
-@x
-@d ensure_dvi_open==if output_file_name=0 then
-@y
-@d log_name == texmf_log_name
-@d ensure_dvi_open==if output_file_name=0 then
-@z
-
-@x
-@!months:packed array [1..36] of char; {abbreviations of month names}
-@y
-@!months:constcstring;
-@z
-
-@x
-if job_name=0 then job_name:="texput";
-@.texput@>
-@y
-if job_name=0 then job_name:=getjobname("texput");
-@.texput@>
-pack_job_name('.fls');
-recorder_change_filename(stringcast(nameoffile+1));
-@z
-
-@x
-slow_print(format_ident); print(" ");
-@y
-wlog(versionstring);
-slow_print(format_ident); print(" ");
-@z
-
-@x
-months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC';
-@y
-months := ' JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC';
-@z
-
-@x
-end
-@y
-if shellenabledp then begin
- wlog_cr;
- wlog(' ');
- if restrictedshell then begin
- wlog('restricted ');
- end;
- wlog('\write18 enabled.')
- end;
-if filelineerrorstylep then begin
- wlog_cr;
- wlog(' file:line:error style messages enabled.')
- end;
-if parsefirstlinep then begin
- wlog_cr;
- wlog(' %&-line parsing enabled.');
- end;
-end
-@z
-
-@x
- prompt_file_name('input file name','.tex');
-@y
- prompt_file_name('input file name','');
-@z
-
-@x
-name:=a_make_name_string(cur_file);
-@y
-name:=a_make_name_string(cur_file);
-source_filename_stack[in_open]:=name;
-full_source_filename_stack[in_open]:=makefullnamestring;
-if name=str_ptr-1 then {we can try to conserve string pool space now}
- begin temp_str:=search_string(name);
- if temp_str>0 then
- begin name:=temp_str; flush_string;
- end;
- end;
-@z
-
-@x
- begin job_name:=cur_name; open_log_file;
-@y
- begin job_name:=getjobname(cur_name); open_log_file;
-@z
-
-@x
-if name=str_ptr-1 then {we can conserve string pool space now}
- begin flush_string; name:=cur_name;
- end;
-@y
-@z
-
-@x
-@!ocp_list_info:array[ocp_list_index] of memory_word;
- {the big collection of ocp list data}
-@!ocp_listmem_ptr:ocp_list_index; {first unused word of |ocp_list_info|}
-@!ocp_listmem_run_ptr:ocp_list_index; {temp unused word of |ocp_list_info|}
-@!ocp_lstack_info:array[ocp_lstack_index] of memory_word;
- {the big collection of ocp lstack data}
-@!ocp_lstackmem_ptr:ocp_lstack_index; {first unused word of |ocp_lstack_info|}
-@!ocp_lstackmem_run_ptr:ocp_lstack_index; {temp unused word of |ocp_lstack_info|}
-@!ocp_list_ptr:internal_ocp_list_number; {largest internal ocp list number in use}
-@!ocp_list_list:array[internal_ocp_list_number] of ocp_list_index;
-@y
-@!ocp_list_info:^memory_word;
- {the big collection of ocp list data}
-@!ocp_listmem_ptr:ocp_list_index; {first unused word of |ocp_list_info|}
-@!ocp_listmem_run_ptr:ocp_list_index; {temp unused word of |ocp_list_info|}
-@!ocp_lstack_info:^memory_word;
- {the big collection of ocp lstack data}
-@!ocp_lstackmem_ptr:ocp_lstack_index; {first unused word of |ocp_lstack_info|}
-@!ocp_lstackmem_run_ptr:ocp_lstack_index; {temp unused word of |ocp_lstack_info|}
-@!ocp_list_ptr:internal_ocp_list_number; {largest internal ocp list number in use}
-@!ocp_list_list:^ocp_list_index;
-@z
-
-@x
-@!dvi_buf:array[dvi_index] of real_eight_bits; {buffer for \.{DVI} output}
-@!half_buf:dvi_index; {half of |dvi_buf_size|}
-@!dvi_limit:dvi_index; {end of the current half buffer}
-@!dvi_ptr:dvi_index; {the next available buffer address}
-@y
-@!dvi_buf:^real_eight_bits; {buffer for \.{DVI} output}
-@!half_buf:integer; {half of |dvi_buf_size|}
-@!dvi_limit:integer; {end of the current half buffer}
-@!dvi_ptr:integer; {the next available buffer address}
-@z
-
-@x
-@p procedure write_dvi(@!a,@!b:dvi_index);
-var k:dvi_index;
-begin for k:=a to b do write(dvi_file,dvi_buf[k]);
-end;
-@y
-In C, we use a macro to call |fwrite| or |write| directly, writing all
-the bytes in one shot. Much better even than writing four
-bytes at a time.
-@z
-
-@x
- old_setting:=selector; selector:=new_string;
-@y
-if output_comment then
- begin l:=strlen(output_comment); dvi_out(l);
- for s:=0 to l-1 do dvi_out(output_comment[s]);
- end
-else begin {the default code is unchanged}
- old_setting:=selector; selector:=new_string;
-@z
-
-@x
- pool_ptr:=str_start_macro(str_ptr); {flush the current string}
-@y
- pool_ptr:=str_start_macro(str_ptr); {flush the current string}
-end;
-@z
-
-@x
-dvi_out(eop); incr(total_pages); cur_s:=-1;
-@y
-dvi_out(eop); incr(total_pages); cur_s:=-1;
-ifdef ('IPC')
-if ipcon>0 then
- begin if dvi_limit=half_buf then
- begin write_dvi(half_buf, dvi_buf_size-1);
- flush_dvi;
- dvi_gone:=dvi_gone+half_buf;
- end;
- if dvi_ptr>0 then
- begin write_dvi(0, dvi_ptr-1);
- flush_dvi;
- dvi_offset:=dvi_offset+dvi_ptr; dvi_gone:=dvi_gone+dvi_ptr;
- end;
- dvi_ptr:=0; dvi_limit:=dvi_buf_size;
- ipcpage(dvi_gone);
- end;
-endif ('IPC');
-@z
-
-@x
- k:=4+((dvi_buf_size-dvi_ptr) mod 4); {the number of 223's}
-@y
-ifdef ('IPC')
- k:=7-((3+dvi_offset+dvi_ptr) mod 4); {the number of 223's}
-endif ('IPC')
-ifndef ('IPC')
- k:=4+((dvi_buf_size-dvi_ptr) mod 4); {the number of 223's}
-endifn ('IPC')
-@z
-
-@x
- print_nl("Output written on "); slow_print(output_file_name);
-@y
- print_nl("Output written on "); print_file_name(0, output_file_name, 0);
-@z
-
-@x
- print(" ("); print_int(total_pages); print(" page");
- if total_pages<>1 then print_char("s");
-@y
- print(" ("); print_int(total_pages);
- if total_pages<>1 then print(" pages")
- else print(" page");
-@z
-
-@x
-@<Append character |cur_chr|...@>=
-continue: adjust_space_factor;@/
-@y
-@<Append character |cur_chr|...@>=
-continue: adjust_space_factor;@/
-@z
-
-@x
-print("' in "); print_mode(mode);
-@y
-print_in_mode(mode);
-@z
-
-@x
-if indented then begin
- p:=new_null_box; box_dir(p):=par_direction;
- width(p):=par_indent;@+
- tail_append(p);
-@y
-if indented then begin
- p:=new_null_box; box_dir(p):=par_direction;
- width(p):=par_indent;@+
- tail_append(p);
-@z
-
-@x
-begin print_err("Extra "); print_esc("endcsname");
-@.Extra \\endcsname@>
-help1("I'm ignoring this, since I wasn't doing a \csname.");
-@y
-begin
-if cur_chr = 10 then
-begin
- print_err("Extra "); print_esc("endmubyte");
-@.Extra \\endmubyte@>
- help1("I'm ignoring this, since I wasn't doing a \mubyte.");
-end else begin
- print_err("Extra "); print_esc("endcsname");
-@.Extra \\endcsname@>
- help1("I'm ignoring this, since I wasn't doing a \csname.");
-end;
-@z
-
-@x
-if (cur_cs=0)or(cur_cs>frozen_control_sequence) then
-@y
-if (cur_cs=0)or(cur_cs>eqtb_top)or
- ((cur_cs>frozen_control_sequence)and(cur_cs<=eqtb_size)) then
-@z
-
-@x
-interaction:=cur_chr;
-@y
-interaction:=cur_chr;
-if interaction = batch_mode
-then kpsemaketexdiscarderrors := 1
-else kpsemaketexdiscarderrors := 0;
-@z
-
-@x
-slow_print(s); update_terminal;
-@y
-print(s); update_terminal;
-@z
-
-@x
-begin print_err(""); slow_print(s);
-@y
-begin print_err(""); print(s);
-@z
-
-@x
-format_ident:=" (INITEX)";
-@y
-if ini_version then format_ident:=" (INITEX)";
-@z
-
-@x
-@!w: four_quarters; {four ASCII codes}
-@y
-@!format_engine: ^packed_ASCII_code;
-@z
-
-@x
-@!w: four_quarters; {four ASCII codes}
-@y
-@!format_engine: ^packed_ASCII_code;
-@z
-
-@x
-@d dump_wd(#)==begin fmt_file^:=#; put(fmt_file);@+end
-@d dump_int(#)==begin fmt_file^.int:=#; put(fmt_file);@+end
-@d dump_hh(#)==begin fmt_file^.hh:=#; put(fmt_file);@+end
-@d dump_qqqq(#)==begin fmt_file^.qqqq:=#; put(fmt_file);@+end
-@y
-@z
-
-@x
-@d undump_wd(#)==begin get(fmt_file); #:=fmt_file^;@+end
-@d undump_int(#)==begin get(fmt_file); #:=fmt_file^.int;@+end
-@d undump_hh(#)==begin get(fmt_file); #:=fmt_file^.hh;@+end
-@d undump_qqqq(#)==begin get(fmt_file); #:=fmt_file^.qqqq;@+end
-@y
-@z
-
-@x
-@d undump_size_end_end(#)==too_small(#)@+else undump_end_end
-@y
-@d format_debug_end(#)==
- writeln (stderr, ' = ', #);
- end;
-@d format_debug(#)==
- if debug_format_file then begin
- write (stderr, 'fmtdebug:', #);
- format_debug_end
-@d undump_size_end_end(#)==
- too_small(#)@+else format_debug (#)(x); undump_end_end
-@z
-
-@x
-dump_int(@$);@/
-@y
-dump_int(@"57325458); {Web2C \TeX's magic constant: "W2TX"}
-{Align engine to 4 bytes with one or more trailing NUL}
-x:=strlen(engine_name);
-format_engine:=xmallocarray(packed_ASCII_code,x+4);
-strcpy(stringcast(format_engine), conststringcast(engine_name));
-for k:=x to x+3 do format_engine[k]:=0;
-x:=x+4-(x mod 4);
-dump_int(x);dump_things(format_engine[0], x);
-libcfree(format_engine);@/
-dump_int(@$);@/
-dump_int(max_halfword);@/
-dump_int(hash_high);
-@z
-
-@x
-x:=fmt_file^.int;
-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(varmemcast(varmem));
-@+Tini
-undump_int(x);
-format_debug('format magic number')(x);
-if x<>@"57325458 then goto bad_fmt; {not a format file}
-undump_int(x);
-format_debug('engine name size')(x);
-if (x<0) or (x>256) then goto bad_fmt; {corrupted format file}
-format_engine:=xmallocarray(packed_ASCII_code, x);
-undump_things(format_engine[0], x);
-format_engine[x-1]:=0; {force string termination, just in case}
-if strcmp(conststringcast(engine_name), stringcast(format_engine)) then
- begin wake_up_terminal;
- wterm_ln('---! ', stringcast(nameoffile+1), ' was written by ', format_engine);
- libcfree(format_engine);
- goto bad_fmt;
-end;
-libcfree(format_engine);
-undump_int(x);
-format_debug('string pool checksum')(x);
-if x<>@$ then begin {check that strings are the same}
- wake_up_terminal;
- wterm_ln('---! ', stringcast(nameoffile+1), ' was written by an older version');
- goto bad_fmt;
-end;
-undump_int(x);
-if x<>max_halfword then goto bad_fmt; {check |max_halfword|}
-undump_int(hash_high);
- if (hash_high<0)or(hash_high>sup_hash_extra) then goto bad_fmt;
- if hash_extra<hash_high then hash_extra:=hash_high;
- eqtb_top:=eqtb_size+hash_extra;
- if hash_extra=0 then hash_top:=undefined_control_sequence else
- hash_top:=eqtb_top;
- yhash:=xmallocarray(two_halves,1+hash_top-hash_offset);
- hash:=yhash - hash_offset;
- next(hash_base):=0; text(hash_base):=0;
- for x:=hash_base+1 to hash_top do hash[x]:=hash[hash_base];
- zeqtb:=xmallocarray (memory_word,eqtb_top+1);
- eqtb:=zeqtb;
-
- eq_type(undefined_control_sequence):=undefined_cs;
- equiv(undefined_control_sequence):=null;
- eq_level(undefined_control_sequence):=level_zero;
- for x:=eqtb_size+1 to eqtb_top do
- eqtb[x]:=eqtb[undefined_control_sequence];
-@z
-
-@x
-dump_int(str_ptr);
-for k:=string_offset to str_ptr do dump_int(str_start_macro(k));
-k:=0;
-while k+4<pool_ptr do
- begin dump_four_ASCII; k:=k+4;
- end;
-k:=pool_ptr-4; dump_four_ASCII;
-@y
-dump_int((str_ptr-string_offset));
-dump_things(str_start[0], (str_ptr-string_offset)+1);
-dump_things(str_pool[0], pool_ptr);
-@z
-
-@x
-undump_size(0)(pool_size)('string pool size')(pool_ptr);
-undump_size(0)(max_strings)('max strings')(str_ptr);
-for k:=string_offset to str_ptr do undump(0)(pool_ptr)(str_start_macro(k));
-k:=0;
-while k+4<pool_ptr do
- begin undump_four_ASCII; k:=k+4;
- end;
-k:=pool_ptr-4; undump_four_ASCII;
-@y
-undump_size(0)(sup_pool_size-pool_free)('string pool size')(pool_ptr);
-if pool_size<pool_ptr+pool_free then
- pool_size:=pool_ptr+pool_free;
-undump_size(0)(sup_max_strings-strings_free)('sup strings')(str_ptr);@/
-if max_strings<str_ptr+strings_free then
- max_strings:=str_ptr+strings_free;
-str_start:=xmallocarray(pool_pointer, max_strings);
-str_ptr:=str_ptr + string_offset;
-undump_checked_things(0, pool_ptr, str_start[0], (str_ptr-string_offset)+1);@/
-str_pool:=xmallocarray(packed_ASCII_code, pool_size);
-undump_things(str_pool[0], pool_ptr);
-@z
-
-@x
-for k:=fix_mem_min to fix_mem_end do dump_wd(mem(k));
-@y
-dump_things(mem(fix_mem_min), fix_mem_end-fix_mem_min+1);
-@z
-
-@x
-for k:=fix_mem_min to fix_mem_end do undump_wd(mem(k));
-@y
-undump_things (mem(fix_mem_min), fix_mem_end-fix_mem_min+1);
-@z
-
-@x
-undump(hash_base)(frozen_control_sequence)(par_loc);
-par_token:=cs_token_flag+par_loc;@/
-undump(hash_base)(frozen_control_sequence)(write_loc);@/
-@y
-undump(hash_base)(hash_top)(par_loc);
-par_token:=cs_token_flag+par_loc;@/
-undump(hash_base)(hash_top)(write_loc);@/
-@z
-
-@x
-while k<l do
- begin dump_wd(eqtb[k]); incr(k);
- end;
-@y
-dump_things(eqtb[k], l-k);
-@z
-
-@x
-while k<l do
- begin dump_wd(eqtb[k]); incr(k);
- end;
-@y
-dump_things(eqtb[k], l-k);
-@z
-
-@x
-k:=j+1; dump_int(k-l);
-until k>eqtb_size
-@y
-k:=j+1; dump_int(k-l);
-until k>eqtb_size;
-if hash_high>0 then dump_things(eqtb[eqtb_size+1],hash_high);
- {dump |hash_extra| part}
-@z
-
-@x
-for j:=k to k+x-1 do undump_wd(eqtb[j]);
-@y
-undump_things(eqtb[k], x);
-@z
-
-@x
-until k>eqtb_size
-@y
-until k>eqtb_size;
-if hash_high>0 then undump_things(eqtb[eqtb_size+1],hash_high);
- {undump |hash_extra| part}
-@z
-
-@x
-dump_int(hash_used); cs_count:=frozen_control_sequence-1-hash_used;
-@y
-dump_int(hash_used); cs_count:=frozen_control_sequence-1-hash_used+hash_high;
-@z
-
-@x
-for p:=hash_used+1 to undefined_control_sequence-1 do dump_hh(hash[p]);
-@y
-dump_things(hash[hash_used+1], undefined_control_sequence-1-hash_used);
-if hash_high>0 then dump_things(hash[eqtb_size+1], hash_high);
-@z
-
-@x
-for p:=hash_used+1 to undefined_control_sequence-1 do undump_hh(hash[p]);
-@y
-undump_things (hash[hash_used+1], undefined_control_sequence-1-hash_used);
-if debug_format_file then begin
- print_csnames (hash_base, undefined_control_sequence - 1);
-end;
-if hash_high > 0 then begin
- undump_things (hash[eqtb_size+1], hash_high);
- if debug_format_file then begin
- print_csnames (eqtb_size + 1, hash_high - (eqtb_size + 1));
- end;
-end;
-@z
-
-@x
-@ @<Undump the array info for internal font number |k|@>=
-begin undump_font(k);@/
-end
-@y
-@ @<Undump the array info for internal font number |k|@>=
-begin undump_font(k);@/
-end;
-make_pdftex_banner
-@z
-
-@x
-for k:=0 to active_max_ptr-1 do dump_wd(active_info[k]);
-if active_max_ptr>0 then begin
- print_ln; print_int(active_max_ptr); print(" words of active ocps");
- end;
-
-@ @<Undump the active ocp information@>=
-undump_size(0)(active_mem_size)('active start point')(active_min_ptr);
-undump_size(0)(active_mem_size)('active mem size')(active_max_ptr);
-for k:=0 to active_max_ptr-1 do undump_wd(active_info[k]);
-@y
-if active_max_ptr>0 then
- dump_things(active_info[0], active_max_ptr);
-if active_max_ptr>0 then begin
- print_ln; print_int(active_max_ptr); print(" words of active ocps");
- end;
-
-@ @<Undump the active ocp information@>=
-undump_size(0)(active_mem_size)('active start point')(active_min_ptr);
-undump_size(0)(active_mem_size)('active mem size')(active_max_ptr);
-if active_max_ptr>0 then
- undump_things(active_info[0], active_max_ptr);
-@z
-
-@x
-@ @<Dump the ocp list information@>=
-dump_int(ocp_listmem_ptr);
-for k:=0 to ocp_listmem_ptr-1 do dump_wd(ocp_list_info[k]);
-dump_int(ocp_list_ptr);
-for k:=null_ocp_list to ocp_list_ptr do begin
- dump_int(ocp_list_list[k]);
- if null_ocp_list<>ocp_list_ptr then begin
- print_nl("\ocplist");
- print_esc(ocp_list_id_text(k));
- print_char("=");
- print_ocp_list(ocp_list_list[k]);
- end;
- end;
-dump_int(ocp_lstackmem_ptr);
-for k:=0 to ocp_lstackmem_ptr-1 do dump_wd(ocp_lstack_info[k])
-@y
-@ @<Dump the ocp list information@>=
-dump_int(ocp_listmem_ptr);
-dump_things(ocp_list_info[0], ocp_listmem_ptr);
-dump_int(ocp_list_ptr);
-dump_things(ocp_list_list[null_ocp_list], ocp_list_ptr+1-null_ocp_list);
-for k:=null_ocp_list to ocp_list_ptr do begin
- if null_ocp_list<>ocp_list_ptr then begin
- print_nl("\ocplist");
- print_esc(ocp_list_id_text(k));
- print_char("=");
- print_ocp_list(ocp_list_list[k]);
- end;
- end;
-dump_int(ocp_lstackmem_ptr);
-dump_things(ocp_lstack_info[0], ocp_lstackmem_ptr)
-@z
-
-@x
-@ @<Undump the ocp list information@>=
-undump_size(1)(1000000)('ocp list mem size')(ocp_listmem_ptr);
-for k:=0 to ocp_listmem_ptr-1 do undump_wd(ocp_list_info[k]);
-undump_size(ocp_list_base)(ocp_list_biggest)('ocp list max')(ocp_list_ptr);
-for k:=null_ocp_list to ocp_list_ptr do
- undump_int(ocp_list_list[k]);
-undump_size(1)(1000000)('ocp lstack mem size')(ocp_lstackmem_ptr);
-for k:=0 to ocp_lstackmem_ptr-1 do undump_wd(ocp_lstack_info[k])
-@y
-@ @<Undump the ocp list information@>=
-undump_size(1)(1000000)('ocp list mem size')(ocp_listmem_ptr);
-undump_things(ocp_list_info[0], ocp_listmem_ptr);
-undump_size(0)(1000000)('ocp list max')(ocp_list_ptr);
-undump_things(ocp_list_list[null_ocp_list], ocp_list_ptr+1-null_ocp_list);
-undump_size(0)(1000000)('ocp lstack mem size')(ocp_lstackmem_ptr);
-undump_things(ocp_lstack_info[0], ocp_lstackmem_ptr)
-@z
-
-@x
-undump(batch_mode)(error_stop_mode)(interaction);
-@y
-undump(batch_mode)(error_stop_mode)(interaction);
-if interactionoption<>unspecified_mode then interaction:=interactionoption;
-@z
-
-@x
-if (x<>69069)or eof(fmt_file) then goto bad_fmt
-@y
-if x<>69069 then goto bad_fmt
-@z
-
-@x
-print(" (preloaded format="); print(job_name); print_char(" ");
-@y
-print(" (format="); print(job_name); print_char(" ");
-@z
-
-@x
-@p begin @!{|start_here|}
-@y
-@d const_chk(#)==begin if # < inf_@&# then # := inf_@&# else
- if # > sup_@&# then # := sup_@&# end
-
-{|setup_bound_var| stuff duplicated in \.{mf.ch}.}
-@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;
- end
- else
- setupboundvariable(addressof(#), bound_name, bound_default);
-
-@p procedure main_body;
-begin @!{|start_here|}
-
-{Bounds that may be set from the configuration file. We want the user to
- be able to specify the names with underscores, but \.{TANGLE} removes
- underscores, so we're stuck giving the names twice, once as a string,
- once as the identifier. How ugly.}
-
- setup_bound_var (100000)('pool_size')(pool_size);
- setup_bound_var (75000)('string_vacancies')(string_vacancies);
- setup_bound_var (5000)('pool_free')(pool_free); {min pool avail after fmt}
- setup_bound_var (15000)('max_strings')(max_strings);
- setup_bound_var (100)('strings_free')(strings_free);
- setup_bound_var (3000)('buf_size')(buf_size);
- setup_bound_var (50)('nest_size')(nest_size);
- setup_bound_var (15)('max_in_open')(max_in_open);
- setup_bound_var (60)('param_size')(param_size);
- setup_bound_var (4000)('save_size')(save_size);
- setup_bound_var (300)('stack_size')(stack_size);
- setup_bound_var (16384)('dvi_buf_size')(dvi_buf_size);
- setup_bound_var (79)('error_line')(error_line);
- setup_bound_var (50)('half_error_line')(half_error_line);
- setup_bound_var (79)('max_print_line')(max_print_line);
- setup_bound_var(1000)('ocp_list_size')(ocp_list_size);
- setup_bound_var(1000)('ocp_buf_size')(ocp_buf_size);
- setup_bound_var(1000)('ocp_stack_size')(ocp_stack_size);
- setup_bound_var (0)('hash_extra')(hash_extra);
- setup_bound_var (72)('pk_dpi')(pk_dpi);
- setup_bound_var (10000)('expand_depth')(expand_depth);
-
- {Check other constants against their sup and inf.}
- const_chk (buf_size);
- const_chk (nest_size);
- const_chk (max_in_open);
- const_chk (param_size);
- const_chk (save_size);
- const_chk (stack_size);
- const_chk (dvi_buf_size);
- const_chk (pool_size);
- const_chk (string_vacancies);
- const_chk (pool_free);
- const_chk (max_strings);
- const_chk (strings_free);
- const_chk (hash_extra);
- const_chk (obj_tab_size);
- const_chk (pdf_mem_size);
- const_chk (dest_names_size);
- const_chk (pk_dpi);
- if error_line > ssup_error_line then error_line := ssup_error_line;
-
- {array memory allocation}
- buffer:=xmallocarray (packed_ASCII_code, buf_size);
- nest:=xmallocarray (list_state_record, nest_size);
- save_stack:=xmallocarray (memory_word, save_size);
- input_stack:=xmallocarray (in_state_record, stack_size);
- input_file:=xmallocarray (alpha_file, max_in_open);
- input_file_callback_id:=xmallocarray (integer, max_in_open);
- line_stack:=xmallocarray (integer, max_in_open);
- eof_seen:=xmallocarray (boolean, max_in_open);
- grp_stack:=xmallocarray (save_pointer, max_in_open);
- if_stack:=xmallocarray (pointer, max_in_open);
- source_filename_stack:=xmallocarray (str_number, max_in_open);
- full_source_filename_stack:=xmallocarray (str_number, max_in_open);
- param_stack:=xmallocarray (halfword, param_size);
- dvi_buf:=xmallocarray (real_eight_bits, dvi_buf_size);
- ocp_list_info:=xmallocarray (memory_word, ocp_list_size);
- memset(ocp_list_info,0,sizeof(memory_word)* ocp_list_size);
- ocp_lstack_info:=xmallocarray (memory_word, ocp_list_size);
- memset(ocp_lstack_info,0,sizeof(memory_word)* ocp_list_size);
- ocp_list_list:=xmallocarray (ocp_list_index, ocp_list_size);
- otp_init_input_buf:=xmallocarray (quarterword, ocp_buf_size);
- otp_input_buf:=xmallocarray (quarterword, ocp_buf_size);
- otp_output_buf:=xmallocarray (quarterword, ocp_buf_size);
- otp_stack_buf:=xmallocarray (quarterword, ocp_stack_size);
- otp_calcs:=xmallocarray (halfword, ocp_stack_size);
- otp_states:=xmallocarray (halfword, ocp_stack_size);
- obj_tab:=xmallocarray (obj_entry, inf_obj_tab_size); {will grow dynamically}
- obj_offset(0):=0;
- pdf_mem:=xmallocarray (integer, inf_pdf_mem_size); {will grow dynamically}
- dest_names:=xmallocarray (dest_name_entry, inf_dest_names_size); {will grow dynamically}
- pdf_op_buf:=xmallocarray (real_eight_bits, pdf_op_buf_size);
- pdf_os_buf:=xmallocarray (real_eight_bits, inf_pdf_os_buf_size); {will grow dynamically}
- pdf_os_objnum:=xmallocarray (integer, pdf_os_max_objs);
- pdf_os_objoff:=xmallocarray (integer, pdf_os_max_objs);
-@+Init
- fixmem:=xmallocarray (smemory_word, fix_mem_init+1);
- memset (voidcast(fixmem), 0, (fix_mem_init+1)*sizeof(smemory_word));
- fix_mem_min:=0;
- fix_mem_max:=fix_mem_init;
-
- eqtb_top := eqtb_size+hash_extra;
- if hash_extra=0 then hash_top:=undefined_control_sequence else
- hash_top:=eqtb_top;
- yhash:=xmallocarray (two_halves,1+hash_top-hash_offset);
- hash:=yhash - hash_offset; {Some compilers require |hash_offset=0|}
- next(hash_base):=0; text(hash_base):=0;
- for hash_used:=hash_base+1 to hash_top do hash[hash_used]:=hash[hash_base];
- zeqtb:=xmallocarray (memory_word, eqtb_top);
- eqtb:=zeqtb;
-
- str_start:=xmallocarray (pool_pointer, max_strings);
- str_pool:=xmallocarray (packed_ASCII_code, pool_size);
-@+Tini
-@z
-
-@x
-@!init if not get_strings_started then goto final_end;
-init_prim; {call |primitive| for each primitive}
-init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr; fix_date_and_time;
-tini@/
-@y
-@!Init if not get_strings_started then goto final_end;
-init_prim; {call |primitive| for each primitive}
-init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr; fix_date_and_time;
-Tini@/
-@z
-
-@x
-end_of_TEX: close_files_and_terminate;
-final_end: ready_already:=0;
-end.
-@y
-close_files_and_terminate;
-final_end: do_final_end;
-end {|main_body|};
-@z
-
-@x
- if format_ident=0 then wterm_ln(' (no format preloaded)')
- else begin slow_print(format_ident); print_ln;
- end;
-@y
- wterm(versionstring);
- if format_ident>0 then slow_print(format_ident);
- print_ln;
- if shellenabledp then begin
- wterm(' ');
- if restrictedshell then begin
- wterm('restricted ');
- end;
- wterm_ln('\write18 enabled.');
- end;
-@z
-
-@x
-write_svnversion(luatex_svnversion);
-@y
-wterm(versionstring);
-write_svnversion(luatex_svnversion);
-@z
-
-@x
- slow_print(log_name); print_char(".");
-@y
- print_file_name(0, log_name, 0); print_char(".");
-@z
-
-@x
- end;
-@y
- end;
-print_ln;
-if (edit_name_start<>0) and (interaction>batch_mode) then
- calledit(str_pool,edit_name_start,edit_name_length,edit_line);
-@z
-
-@x
- wlog_ln(' ',cs_count:1,' multiletter control sequences out of ',
- hash_size:1);@/
-@y
- wlog_ln(' ',cs_count:1,' multiletter control sequences out of ',
- hash_size:1, '+', hash_extra:1);@/
-@z
-
-@x
- begin @!init for i:=0 to biggest_used_mark do begin
-@y
- begin @!Init for i:=0 to biggest_used_mark do begin
-@z
-
-@x
- store_fmt_file; return;@+tini@/
-@y
- store_fmt_file; return;@+Tini@/
-@z
-
-@x
-if (format_ident=0)or(buffer[loc]="&") then
-@y
-if (format_ident=0)or(buffer[loc]="&")or dump_line then
-@z
-
-@x
- w_close(fmt_file);
-@y
- w_close(fmt_file);
- eqtb:=zeqtb;
-@z
-
-@x
-fix_date_and_time;@/
-@y
-fix_date_and_time;@/
-@!init
-make_pdftex_banner;
-tini@/
-@z
-
-@x
- begin goto breakpoint;@\ {go to every label at least once}
- breakpoint: m:=0; @{'BREAKPOINT'@}@\
- end
-@y
- abort {do something to cause a core dump}
-@z
-
-@x
- else if cur_val>15 then cur_val:=16;
-@y
- else if (cur_val>15) and (cur_val <> 18) then cur_val:=16;
-@z
-
-@x
-begin @<Expand macros in the token list
-@y
-@!d:integer; {number of characters in incomplete current string}
-@!clobbered:boolean; {system string is ok?}
-@!runsystem_ret:integer; {return value from |runsystem|}
-begin @<Expand macros in the token list
-@z
-
-@x
-if write_open[j] then selector:=j
-@y
-if j=18 then selector := new_string
-else if write_open[j] then selector:=j
-@z
-
-@x
-flush_list(def_ref); selector:=old_setting;
-@y
-flush_list(def_ref);
-if j=18 then
- begin if (tracing_online<=0) then
- selector:=log_only {Show what we're doing in the log file.}
- else selector:=term_and_log; {Show what we're doing.}
- {If the log file isn't open yet, we can only send output to the terminal.
- Calling |open_log_file| from here seems to result in bad data in the log.}
- if not log_opened then selector:=term_only;
- print_nl("runsystem(");
- for d:=0 to cur_length-1 do
- begin {|print| gives up if passed |str_ptr|, so do it by hand.}
- print(so(str_pool[str_start_macro(str_ptr)+d])); {N.B.: not |print_char|}
- end;
- print(")...");
- if shellenabledp then begin
- 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
- 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<cur_length-1) then clobbered:=true;
- {minimal checking: NUL not allowed in argument string of |system|()}
- end;
- if clobbered then print("clobbered")
- else begin {We have the command. See if we're allowed to execute it,
- and report in the log. We don't check the actual exit status of
- the command, or do anything with the output.}
- runsystem_ret := runsystem(stringcast(addressof(
- str_pool[str_start_macro(str_ptr)])));
- if runsystem_ret = -1 then print("quotation error in system command")
- else if runsystem_ret = 0 then print("disabled (restricted)")
- else if runsystem_ret = 1 then print("executed")
- else if runsystem_ret = 2 then print("executed safely (allowed)")
- end;
- end else begin
- print("disabled"); {|shellenabledp| false}
- end;
- print_char("."); print_nl(""); print_ln;
- pool_ptr:=str_start_macro(str_ptr); {erase the string}
-end;
-selector:=old_setting;
-@z
-
-@x
-@!eof_seen : array[1..max_in_open] of boolean; {has eof been seen?}
-@y
-@!eof_seen : ^boolean; {has eof been seen?}
-@z
-
-@x
-@!grp_stack : array[0..max_in_open] of save_pointer; {initial |cur_boundary|}
-@!if_stack : array[0..max_in_open] of pointer; {initial |cond_ptr|}
-@y
-@!grp_stack : ^save_pointer; {initial |cur_boundary|}
-@!if_stack : ^pointer; {initial |cond_ptr|}
-@z
-
-@x
-@!otp_init_input_buf:array[0..20000] of quarterword;
-
-@!otp_input_start:halfword;
-@!otp_input_last:halfword;
-@!otp_input_end:halfword;
-@!otp_input_buf:array[0..20000] of quarterword;
-
-@!otp_output_end:halfword;
-@!otp_output_buf:array[0..20000] of quarterword;
-
-@!otp_stack_used:halfword;
-@!otp_stack_last:halfword;
-@!otp_stack_new:halfword;
-@!otp_stack_buf:array[0..1000] of quarterword;
-
-@!otp_pc:halfword;
-
-@!otp_calc_ptr:halfword;
-@!otp_calcs:array[0..1000] of halfword;
-@!otp_state_ptr:halfword;
-@!otp_states:array[0..1000] of halfword;
-@y
-@!otp_init_input_buf:^quarterword;
-
-@!otp_input_start:halfword;
-@!otp_input_last:halfword;
-@!otp_input_end:halfword;
-@!otp_input_buf:^quarterword;
-
-@!otp_output_end:halfword;
-@!otp_output_buf:^quarterword;
-
-@!otp_stack_used:halfword;
-@!otp_stack_last:halfword;
-@!otp_stack_new:halfword;
-@!otp_stack_buf:^quarterword;
-
-@!otp_pc:halfword;
-
-@!otp_calc_ptr:halfword;
-@!otp_calcs:^halfword;
-@!otp_state_ptr:halfword;
-@!otp_states:^halfword;
-@z
-
-@x
-@* \[54] System-dependent changes.
-@y
-@* \[54/web2c] System-dependent changes for Web2c.
-Here are extra variables for Web2c. (This numbering of the
-system-dependent section allows easy integration of Web2c and e-\TeX, etc.)
-@^<system dependencies@>
-
-@<Glob...@>=
-@!edit_name_start: pool_pointer; {where the filename to switch to starts}
-@!edit_name_length,@!edit_line: integer; {what line to start editing at}
-@!ipcon: cinttype; {level of IPC action, 0 for none [default]}
-@!stop_at_space: boolean; {whether |more_name| returns false for space}
-
-@ The |edit_name_start| will be set to point into |str_pool| somewhere after
-its beginning if \TeX\ is supposed to switch to an editor on exit.
-
-@<Set init...@>=
-edit_name_start:=0;
-stop_at_space:=true;
-
-@ These are used when we regenerate the representation of the first 256
-strings.
-
-@<Global...@> =
-@!save_str_ptr: str_number;
-@!save_pool_ptr: pool_pointer;
-@!shellenabledp: cinttype;
-@!restrictedshell: cinttype;
-@!output_comment: ^char;
-@!k,l: 0..255; {used by `Make the first 256 strings', etc.}
-
-@ When debugging a macro package, it can be useful to see the exact
-control sequence names in the format file. For example, if ten new
-csnames appear, it's nice to know what they are, to help pinpoint where
-they came from. (This isn't a truly ``basic'' printing procedure, but
-that's a convenient module in which to put it.)
-
-@<Basic printing procedures@> =
-procedure print_csnames (hstart:integer; hfinish:integer);
-var c,h:integer;
-begin
- writeln(stderr, 'fmtdebug:csnames from ', hstart, ' to ', hfinish, ':');
- for h := hstart to hfinish do begin
- if text(h) > 0 then begin {if have anything at this position}
- for c := str_start_macro(text(h)) to str_start_macro(text(h) + 1) - 1
- do begin
- putbyte(str_pool[c], stderr); {print the characters}
- end;
- writeln(stderr, '|');
- end;
- end;
-end;
-
-@ Are we printing extra info as we read the format file?
-
-@<Glob...@> =
-@!debug_format_file: boolean;
-
-
-@ A helper for printing file:line:error style messages. Look for a
-filename in |full_source_filename_stack|, and if we fail to find
-one fall back on the non-file:line:error style.
-
-@<Basic print...@>=
-procedure print_file_line;
-var level: 0..max_in_open;
-begin
- level:=in_open;
- while (level>0) and (full_source_filename_stack[level]=0) do
- decr(level);
- if level=0 then
- print_nl("! ")
- else begin
- print_nl (""); print (full_source_filename_stack[level]); print (":");
- if level=in_open then print_int (line)
- else print_int (line_stack[index+1-(in_open-level)]);
- print (": ");
- end;
-end;
-
-@ To be able to determine whether \.{\\write18} is enabled from within
-\TeX\ we also implement \.{\\eof18}. We sort of cheat by having an
-additional route |scan_four_bit_int_or_18| which is the same as
-|scan_four_bit_int| except it also accepts the value 18.
-
-@<Declare procedures that scan restricted classes of integers@>=
-procedure scan_four_bit_int_or_18;
-begin scan_int;
-if (cur_val<0)or((cur_val>15)and(cur_val<>18)) then
- begin print_err("Bad number");
-@.Bad number@>
- help2("Since I expected to read a number between 0 and 15,")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-
-@* \[54/web2c-string] The string recycling routines. \TeX{} uses 2
-upto 4 {\it new\/} strings when scanning a filename in an \.{\\input},
-\.{\\openin}, or \.{\\openout} operation. These strings are normally
-lost because the reference to them are not saved after finishing the
-operation. |search_string| searches through the string pool for the
-given string and returns either 0 or the found string number.
-
-@<Declare additional routines for string recycling@>=
-function search_string(@!search:str_number):str_number;
-label found;
-var result: str_number;
-@!s: str_number; {running index}
-@!len: integer; {length of searched string}
-begin result:=0; len:=length(search);
-if len=0 then {trivial case}
- begin result:=""; goto found;
- end
-else begin s:=search-1; {start search with newest string below |s|; |search>1|!}
- while s>=string_offset do {first |string_offset| strings depend on implementation!!}
- begin if length(s)=len then
- if str_eq_str(s,search) then
- begin result:=s; goto found;
- end;
- decr(s);
- end;
- end;
-found:search_string:=result;
-end;
-
-@ The following routine is a variant of |make_string|. It searches
-the whole string pool for a string equal to the string currently built
-and returns a found string. Otherwise a new string is created and
-returned. Be cautious, you can not apply |flush_string| to a replaced
-string!
-
-@<Declare additional routines for string recycling@>=
-function slow_make_string : str_number;
-label exit;
-var s: str_number; {result of |search_string|}
-@!t: str_number; {new string}
-begin t:=make_string; s:=search_string(t);
-if s>0 then
- begin flush_string; slow_make_string:=s; return;
- end;
-slow_make_string:=t;
-exit:end;
-
-
-@* \[54] System-dependent changes.
-@z
-
-
-@x
-@* \[55] Index.
-@y
-
-@ This function used to be in pdftex, but is useful in tex too.
-
-@p function get_nullstr: str_number;
-begin
- get_nullstr := "";
-end;
-
-@* \[55] Index.
-@z
-
diff --git a/Build/source/texk/web2c/luatexdir/luatex.defines b/Build/source/texk/web2c/luatexdir/luatex.defines
deleted file mode 100644
index a36e3847b0f..00000000000
--- a/Build/source/texk/web2c/luatexdir/luatex.defines
+++ /dev/null
@@ -1,900 +0,0 @@
-{ luatex.defines
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. }
-
-{ $Id$ }
-
-{ luatex.defines: additions for LuaTeX }
-
-@define function simple_advance_width();
-
-@define function new_node();
-@define function new_glyph_node;
-@define procedure flush_node();
-@define function copy_node();
-@define procedure couple_nodes();
-@define function copy_node_list();
-@define procedure flush_node_list();
-@define function string_to_pseudo();
-@define function do_set_attribute();
-@define function copy_attribute_list();
-@define procedure add_node_attr_ref();
-@define procedure replace_attribute_list();
-@define procedure update_attribute_cache;
-@define const UNUSED_ATTRIBUTE;
-
-@define function new_span_node();
-
-@define function sizeof();
-@define procedure memset();
-@define function realloc();
-@define function malloc();
-@define function voidcast();
-@define function fixmemcast();
-@define function varmemcast();
-@define type void;
-@define procedure init_node_mem();
-@define procedure print_node_mem_stats;
-@define procedure dump_node_mem;
-@define procedure undump_node_mem;
-@define function visible_last_node_type();
-@define var NULL;
-@define var varmem;
-@define var var_mem_max;
-@define procedure check_buffer_overflow();
-@define procedure check_pool_overflow();
-
-@define function new_ligkern();
-@define function make_lang_data();
-@define procedure ext_do_line_break();
-@define procedure initialize_active;
-@define var prev_char_p;
-@define function cur_break();
-@define function break_node();
-
-@define function divide_scaled();
-@define function divide_scaled_n();
-
-@define procedure new_hyphenation();
-@define procedure load_tex_hyphenation();
-@define procedure load_tex_patterns();
-@define procedure dump_language_data;
-@define procedure undump_language_data;
-@define function insert_discretionary();
-@define const select_disc;
-@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();
-@define function tex_b_open_in();
-@define function vf_b_open_in ();
-@define procedure pdf_mark_char();
-@define procedure writepdf();
-@define procedure pdfassert();
-
-@define procedure luacall();
-@define procedure luatokencall();
-@define procedure closelua();
-@define function get_lua_name();
-
-{ for virtual file input }
-
-@define procedure luacstring_close();
-@define procedure luacstring_start();
-@define var DEFAULT_CAT_TABLE;
-
-{ for callbacks }
-
-@define function run_callback();
-@define function run_and_save_callback();
-@define function run_saved_callback();
-@define procedure destroy_saved_callback();
-@define function callback_defined();
-@define function callbackluaid();
-@define var find_write_file_callback;
-@define var find_output_file_callback;
-@define var find_image_file_callback;
-@define var find_format_file_callback;
-@define var find_read_file_callback;
-@define var open_read_file_callback;
-@define var find_ocp_file_callback;
-@define var read_ocp_file_callback;
-@define var find_vf_file_callback;
-@define var read_vf_file_callback;
-@define var find_data_file_callback;
-@define var read_data_file_callback;
-@define var find_font_file_callback;
-@define var read_font_file_callback;
-@define var find_map_file_callback;
-@define var read_map_file_callback;
-@define var find_enc_file_callback;
-@define var read_enc_file_callback;
-@define var find_type1_file_callback;
-@define var read_type1_file_callback;
-@define var find_truetype_file_callback;
-@define var read_truetype_file_callback;
-@define var find_opentype_file_callback;
-@define var read_opentype_file_callback;
-@define var find_sfd_file_callback;
-@define var read_sfd_file_callback;
-@define var find_pk_file_callback;
-@define var read_pk_file_callback;
-@define var show_error_hook_callback;
-@define var process_input_buffer_callback;
-@define var start_page_number_callback;
-@define var stop_page_number_callback;
-@define var start_run_callback;
-@define var stop_run_callback;
-@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();
-@define procedure get_saved_lua_string();
-@define procedure get_lua_boolean();
-@define procedure get_lua_number();
-@define procedure get_lua_string();
-
-@define procedure get_token_lua;
-@define procedure lua_node_filter();
-@define procedure lua_node_filter_s();
-@define function lua_hpack_filter();
-@define function lua_vpack_filter();
-
-@define procedure check_texconfig_init;
-
-@define procedure lua_pdf_literal();
-
-{ 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();
-@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 init_math_fields;
-@define procedure setup_math_style;
-@define procedure print_math_style;
-
-@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();
-
-@define function get_uc_code();
-@define procedure set_uc_code();
-
-@define function get_sf_code();
-@define procedure set_sf_code();
-
-@define function get_cat_code();
-@define procedure set_cat_code();
-
-@define function valid_catcode_table ();
-@define procedure clear_catcode_stack ();
-@define procedure copy_cat_codes ();
-@define procedure initex_cat_codes ();
-@define procedure unsave_cat_codes ();
-@define procedure unsave_text_codes ();
-@define procedure initializetextcodes;
-@define procedure free_text_codes;
-@define procedure dumptextcodes;
-@define procedure undumptextcodes;
-
-@define procedure dumpluacregisters;
-@define procedure undumpluacregisters;
-
-@define function do_a_open_out();
-@define function do_b_open_out();
-
-@define procedure flush_loggable_info;
-
-@define var extra_version_info;
-@define procedure write_svnversion();
-
-{ bits and pieces from aleph }
-
-@define procedure btestin ;
-
-@define function readtfmfile();
-@define function next_vf_byte;
-@define function read_vf_file();
-@define function read_ocp_file();
-@define function read_data_file();
-
-@define var ocp_tables;
-
-@define procedure allocate_ocp_table ();
-@define procedure dump_ocp_table ();
-@define procedure undump_ocp_table ();
-@define procedure run_external_ocp ();
-
-@define function copy_font_info();
-
-{ 'texfont' library definitions }
-
-@define procedure dump_font ();
-@define procedure undump_font ();
-@define function is_valid_font();
-@define function copy_font();
-@define function scale_font();
-@define function max_font_id;
-@define procedure set_max_font_id();
-
-@define function font_name();
-@define function font_area();
-@define function get_font_name();
-@define function get_font_area();
-@define function font_bc();
-@define function font_ec();
-
-@define function tex_font_name();
-@define function tex_font_area();
-@define procedure set_tex_font_name();
-
-@define procedure set_pdf_font_size();
-@define procedure set_pdf_font_num();
-@define procedure set_pdf_font_blink();
-@define procedure set_pdf_font_elink();
-@define procedure set_pdf_font_expand_ratio();
-@define procedure set_pdf_font_shrink();
-@define procedure set_pdf_font_stretch();
-@define procedure set_pdf_font_step();
-@define procedure set_pdf_font_auto_expand();
-@define procedure set_pdf_font_attr();
-
-@define function pdf_font_size();
-@define function pdf_font_num();
-@define function pdf_font_blink();
-@define function pdf_font_elink();
-@define function pdf_font_expand_ratio();
-@define function pdf_font_shrink();
-@define function pdf_font_stretch();
-@define function pdf_font_step();
-@define function pdf_font_auto_expand();
-@define function pdf_font_attr();
-
-@define function cmp_font_area();
-@define function cmp_font_name();
-@define function font_shareable();
-
-@define function fontglue();
-@define procedure setfontglue();
-
-@define function font_check_0();
-@define function font_check_1();
-@define function font_check_2();
-@define function font_check_3();
-
-@define function font_size();
-@define function font_slant();
-@define function font_extend();
-@define function font_used();
-@define procedure set_font_used();
-@define function font_touched();
-@define procedure set_font_touched();
-
-@define function font_dsize();
-@define function font_natural_dir();
-
-@define function font_params();
-@define function font_param();
-@define procedure set_font_params();
-@define procedure set_font_param();
-@define function slant();
-@define function quad();
-@define function x_height();
-@define function space();
-@define function extra_space();
-@define function space_stretch();
-@define function space_shrink();
-
-@define function font_kerns();
-@define function font_kern_sc();
-@define procedure adjust_font_kern();
-
-@define function font_italics();
-@define function font_italic();
-@define procedure set_font_italic();
-
-@define function has_lig();
-@define function has_kern();
-
-@define type liginfo;
-
-@define function get_ligature();
-@define function is_valid_ligature();
-@define function lig_type();
-@define function lig_replacement();
-
-@define function is_ligature();
-@define function is_leftboundary();
-@define function is_rightboundary();
-
-@define procedure set_to_character();
-@define procedure set_to_glyph();
-@define procedure set_is_leftghost();
-@define procedure set_is_rightghost();
-
-@define var non_boundarychar;
-
-@define function ext_top();
-@define function ext_mid();
-@define function ext_bot();
-@define function ext_rep();
-
-@define var ext_tag;
-@define var list_tag;
-
-@define var virtual_font_type;
-@define function font_type();
-
-@define function font_format();
-@define function char_index();
-@define function font_cidregistry();
-@define function font_encodingbytes();
-
-@define function font_map();
-@define procedure set_font_map();
-
-
-@define function hyphen_char();
-@define function skew_char();
-@define procedure set_hyphen_char();
-@define procedure set_skew_char();
-@define function char_exists();
-
-@define function char_used();
-@define function char_name();
-@define function char_width();
-@define function char_height();
-@define function char_depth();
-@define function char_italic();
-@define function char_tag();
-@define procedure set_char_tag();
-@define function char_remainder();
-
-@define function char_info_short();
-
-@define function has_packet();
-@define procedure do_vf_packet();
-@define function expand_font_name();
-@define function auto_expand_font();
-@define procedure vf_expand_local_fonts();
-@define function letter_space_font();
-@define function read_font_info();
-
-@define function get_tag_code();
-@define function get_lp_code();
-@define function get_rp_code();
-@define function get_ef_code();
-@define procedure set_tag_code();
-@define procedure set_lp_code();
-@define procedure set_rp_code();
-@define procedure set_ef_code();
-
-@define function test_no_ligatures();
-@define procedure set_no_ligatures();
-
-@define function get_kern();
-@define function charkern();
-
-{ functions from mapfile.c }
-@define function hasfmentry();
-@define procedure checkextfm();
-@define procedure pdfmapfile();
-@define procedure pdfmapline();
-@define procedure pdf_init_map_file();
-
-@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/utils.c }
-@define procedure escapehex();
-@define procedure escapename();
-@define procedure escapestring();
-@define function ext_xn_over_d();
-@define procedure getcreationdate;
-@define function get_resname_prefix;
-@define function makecstring();
-
-@define procedure append_string();
-@define procedure matchstrings();
-@define procedure libpdffinish;
-@define procedure makepdftexbanner;
-@define procedure printcreationdate;
-@define procedure printmoddate;
-@define procedure print_ID();
-@define procedure set_job_id();
-@define procedure unescapehex();
-@define procedure write_stream_length();
-@define procedure removepdffile;
-@define procedure garbagewarning;
-@define function newcolorstack();
-@define function colorstackset();
-@define function colorstackpush();
-@define function colorstackpop();
-@define function colorstackcurrent();
-@define function colorstackused;
-@define function colorstackskippagestart();
-@define procedure checkpdfsave();
-@define procedure checkpdfrestore();
-@define procedure pdfshipoutbegin();
-@define procedure pdfshipoutend();
-@define procedure pdfsetmatrix();
-@define procedure matrixtransformpoint();
-@define procedure matrixtransformrect();
-@define function matrixused;
-@define procedure matrixrecalculate();
-@define function getllx;
-@define function getlly;
-@define function geturx;
-@define function getury;
-
-{functions from pdf/pagetree.c }
-@define function pdf_do_page_divert();
-@define procedure pdf_do_page_undivert();
-@define function output_pages_tree;
-
-{ functions from pdf/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 texpdf.c }
-
-@define procedure pdf_print_char();
-@define procedure pdf_print();
-@define procedure pdf_print_int();
-@define procedure pdf_print_real();
-@define procedure pdf_print_str();
-
-{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();
-@define function packet_byte;
-@define procedure start_packet();
-@define procedure store_packet();
-
-{ functions from writefont.c }
-@define procedure do_pdf_font();
-
-{ functions from image/writeimg.c }
-@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_index();
-@define function image_width();
-@define function image_height();
-@define function image_depth();
-@define function image_objnum();
-@define function is_pdf_image();
-@define function is_png_image();
-@define function read_image();
-@define procedure update_image_procset();
-@define procedure write_image();
-@define procedure scale_image();
-@define procedure set_image_dimensions();
-@define procedure out_image();
-
-@define procedure dumpimagemeta;
-@define procedure undumpimagemeta();
-
-{ functions from lua/limglib.c }
-
-{ functions from writet3.c }
-@define function get_pk_char_width();
-
-{ functions from writezip.c }
-@define procedure write_zip();
-
-{ functions from avlstuff.c }
-@define procedure avl_put_obj();
-@define function avl_find_obj();
-
-{ functions from tounicode.c }
-@define procedure def_tounicode();
-
-{ functions from luatex.web }
-@define function auto_expand_vf();
-
-{ end of luatex.defines }
-
-{texmf.defines}
-
-@define type two_halves;
-@define type four_quarters;
-
-@define function input_ln ();
-@define function is_new_source ();
-@define function get_job_name ();
-@define function make_full_name_string;
-
-@define procedure seconds_and_micros ();
-@define function ocp_open_in ();
-@define function kpse_in_name_ok ();
-@define function kpse_out_name_ok ();
-
-@define function w_open_in ();
-@define function w_open_out ();
-
-@define procedure dump_hh ();
-@define procedure dump_int ();
-@define procedure dump_things ();
-@define procedure dump_wd ();
-
-@define procedure undump_hh ();
-@define procedure undump_int ();
-@define procedure undump_qqqq ();
-@define procedure undump_things ();
-@define procedure undump_checked_things ();
-@define procedure undump_upper_check_things ();
-@define procedure undump_wd ();
-@define procedure w_close ();
-
-{common.defines}
-
-@define type memory_word; {for gftodvi, TeX, and Metafont}
-
-@define function a_open_in ();
-@define procedure a_close ();
-@define procedure b_close ();
-@define function a_open_out ();
-@define function b_open_out ();
-
-@define procedure write_dvi ();
-@define procedure write_pdf ();
-@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 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 ord_noad_type;
-@define const op_noad_type_normal;
-@define const op_noad_type_limits;
-@define const op_noad_type_no_limits;
-@define const bin_noad_type;
-@define const rel_noad_type;
-@define const open_noad_type;
-@define const close_noad_type;
-@define const punct_noad_type;
-@define const inner_noad_type;
-@define const under_noad_type;
-@define const over_noad_type;
-@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 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 0d2d84eb8da..69ed3fe157c 100644
--- a/Build/source/texk/web2c/luatexdir/luatex.h
+++ b/Build/source/texk/web2c/luatexdir/luatex.h
@@ -20,61 +20,106 @@
/* $Id$ */
-
-extern void do_vf(internal_font_number tmp_f);
-
-extern int readbinfile(FILE * f, unsigned char **b, integer * s);
-
-#define read_tfm_file readbinfile
-#define read_vf_file readbinfile
-#define read_ocp_file readbinfile
-#define read_data_file readbinfile
-
-extern int **ocp_tables;
-
-extern void allocate_ocp_table(int ocp_number, int ocp_size);
-extern void dump_ocp_table(int ocp_number);
-extern void undump_ocp_table(int ocp_number);
-
-extern void run_external_ocp(string external_ocp_name);
-extern void b_test_in(void);
-
-/* Additions to texmfmp.h for pdfTeX */
-
-/* mark a char in font */
-#define pdf_mark_char(f,c) set_char_used(f,c,true)
-
-/* test whether a char in font is marked */
-#define pdf_char_marked char_used
-
-/* writepdf() always writes by fwrite() */
-#define write_pdf(a, b) \
- (void) fwrite ((char *) &pdf_buf[a], sizeof (pdf_buf[a]), \
- (int) ((b) - (a) + 1), pdf_file)
-
-#define tex_b_open_in(f) \
- open_input (&(f), kpse_tex_format, FOPEN_RBIN_MODE)
-#define ovf_b_open_in(f) \
- open_input (&(f), kpse_ovf_format, FOPEN_RBIN_MODE)
-#define vf_b_open_in(f) \
- open_input (&(f), kpse_vf_format, FOPEN_RBIN_MODE)
-
-extern int open_outfile(FILE ** f, const char *name, const char *mode);
-
-#define do_a_open_out(f) open_outfile(&(f),(const char *)(nameoffile+1),FOPEN_W_MODE)
-#define do_b_open_out(f) open_outfile(&(f),(const char *)(nameoffile+1),FOPEN_WBIN_MODE)
-
-#define pdfassert assert
-#define voidcast(a) (void *)(a)
-#define varmemcast(a) (memory_word *)(a)
-#define fixmemcast(a) (smemory_word *)(a)
-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 s);
-extern void dump_node_mem(void);
-extern void undump_node_mem(void);
-
-#include <luatexdir/ptexlib.h>
+#ifndef LUATEX_H
+# define LUATEX_H
+
+/* texmf.h: Main include file for TeX and Metafont in C. This file is
+ included by {tex,mf}d.h, which is the first include in the C files
+ output by web2c. */
+
+# include "cpascal.h"
+
+# include <kpathsea/c-pathch.h> /* for IS_DIR_SEP, used in the change files */
+# include <kpathsea/tex-make.h> /* for kpse_make_tex_discard_errors */
+
+/* If we have these macros, use them, as they provide a better guide to
+ the endianess when cross-compiling. */
+# if defined (BYTE_ORDER) && defined (BIG_ENDIAN) && defined (LITTLE_ENDIAN)
+# ifdef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+# if BYTE_ORDER == BIG_ENDIAN
+# define WORDS_BIGENDIAN
+# endif
+# endif
+/* More of the same, but now NeXT-specific. */
+# ifdef NeXT
+# ifdef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+# ifdef __BIG_ENDIAN__
+# define WORDS_BIGENDIAN
+# endif
+# endif
+
+
+/* Some things are the same except for the name. */
+
+# define TEXMFPOOLNAME "luatex.pool"
+# define TEXMFENGINENAME "luatex"
+
+# define DUMP_FILE fmt_file
+# define DUMP_FORMAT kpse_fmt_format
+# define write_dvi WRITE_OUT
+# define flush_dvi flush_out
+# define OUT_FILE dvi_file
+# define OUT_BUF dvi_buf
+
+/* Restore underscores. */
+# define kpsetexformat kpse_tex_format
+# define mainbody main_body
+# define t_open_in topenin
+
+/* Executing shell commands. */
+extern void mk_shellcmdlist(char *);
+extern void init_shell_escape(void);
+extern int shell_cmd_is_allowed(const char **cmd, char **safecmd,
+ char **cmdname);
+extern int runsystem(char *cmd);
+
+# ifndef GLUERATIO_TYPE
+# define GLUERATIO_TYPE double
+# endif
+typedef GLUERATIO_TYPE glueratio;
+
+# if defined(__DJGPP__) && defined (IPC)
+# undef IPC
+# endif
+
+# ifdef IPC
+extern void ipcpage(int);
+# endif /* IPC */
+
+
+/* How to output to the GF or DVI file. */
+# define WRITE_OUT(a, b) \
+ if (fwrite ((char *) &OUT_BUF[a], sizeof (OUT_BUF[a]), \
+ (int) ((b) - (a) + 1), OUT_FILE) \
+ != (int) ((b) - (a) + 1)) \
+ FATAL_PERROR ("fwrite");
+
+# define flush_out() fflush (OUT_FILE)
+
+/* Read a line of input as quickly as possible. */
+# define input_ln(stream, flag) input_line (stream)
+
+extern boolean input_line(FILE *);
+
+# include <luatexdir/ptexlib.h>
+
+# define COPYRIGHT_HOLDER "Taco Hoekwater"
+# define AUTHOR NULL
+# define PROGRAM_HELP LUATEXHELP
+# define BUG_ADDRESS "dev-luatex@ntg.nl"
+# define DUMP_OPTION "fmt"
+# define DUMP_EXT ".fmt"
+# define INPUT_FORMAT kpse_tex_format
+# define INI_PROGRAM "luainitex"
+# define VIR_PROGRAM "luavirtex"
+# define TEXMFENGINENAME "luatex"
+
+/* this counteracts the macro definition in cpascal.h */
+# undef Xchr
+# define Xchr(a) a
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/luatex.mk b/Build/source/texk/web2c/luatexdir/luatex.mk
deleted file mode 100644
index 6a0a5d6386d..00000000000
--- a/Build/source/texk/web2c/luatexdir/luatex.mk
+++ /dev/null
@@ -1,158 +0,0 @@
-# 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 luatex
-# $Id$
-
-# We build luatex
-luatex = @LTEX@ luatex
-luatexdir = luatexdir
-
-# libz
-ZLIBDIR=../../libs/zlib
-ZLIBSRCDIR=$(srcdir)/$(ZLIBDIR)
-# libpng
-LIBPNGDIR=../../libs/libpng
-LIBPNGSRCDIR=$(srcdir)/$(LIBPNGDIR)
-# libxpdf
-LIBXPDFDIR=../../libs/xpdf
-LIBXPDFSRCDIR=$(srcdir)/$(LIBXPDFDIR)
-# libobsdcompa
-LIBOBSDCOMPATDIR=../../libs/obsdcompat
-LIBOBSDCOMPATFSRCDIR=$(srcdir)/$(LIBOBSDCOMPATDIR)
-
-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
-linux_build_dir = $(HOME)/luatex/build/linux/texk/web2c
-
-
-# Extract luatex version
-$(luatexdir)/luatex.version: $(srcdir)/$(luatexdir)/luatex.web
- test -d $(luatexdir) || mkdir $(luatexdir)
- grep '^@d luatex_version_string==' $(srcdir)/$(luatexdir)/luatex.web \
- | sed "s/^.*=='//;s/' .*$$//" \
- >$(luatexdir)/luatex.version
-
-# The C sources.
-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) @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
-# $(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 >$@
-luatex-pool.c: luatex.pool
- $(makecpool) luatex.pool luatexdir/ptexlib.h >$@ || rm -f $@
-
-# luatangle we need a private version of tangle
-
-luatangle: luatangle.o
- $(kpathsea_link) luatangle.o $(LOADLIBES)
-
-luatangle.c luatangle.h: luatangle.p
- $(web2c) luatangle
-
-luatangle.p: tangle $(srcdir)/$(luatexdir)/luatangle.web $(srcdir)/$(luatexdir)/luatangle.ch
- $(TANGLE) $(srcdir)/$(luatexdir)/luatangle.web $(srcdir)/$(luatexdir)/luatangle.ch
-
-# Tangling
-luatex.p luatex.pool: luatangle $(srcdir)/$(luatexdir)/luatex.web $(srcdir)/$(luatexdir)/luatex.ch
- $(native)/luatangle --underlines $(srcdir)/$(luatexdir)/luatex.web $(srcdir)/$(luatexdir)/luatex.ch
-
-# Sources for luatex.ch:
-#luatex_ch_srcs = $(srcdir)/$(luatexdir)/luatex.web \
-# $(srcdir)/$(luatexdir)/lua.ch \
-# $(srcdir)/$(luatexdir)/lua.ch0
-
-# Rules:
-#luatex.ch: $(TIE) $(luatex_ch_srcs)
-# $(TIE) -c luatex.ch $(luatex_ch_srcs)
-
-# 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 $(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
-#luatex-all.pdf: luatex-all.tex
-# $(luatex) luatex-all.tex
-
-check: @LTEX@ luatex-check
-luatex-check: luatex luatex.fmt
-
-clean:: luatex-clean
-luatex-clean:
- $(LIBTOOL) --mode=clean $(RM) luatex
- rm -f $(luatex_o) $(luatex_c) luatexextra.c luatexcoerce.h
- rm -f $(luatexdir)/luatexextra.h
- rm -f luatexd.h luatex.p luatex.pool luatex.ch strpool.c
- rm -f luatex.fmt luatex.log
-
-# Dumps
-all_luafmts = @FMU@ luatex.fmt $(luafmts)
-
-dumps: @LTEX@ luafmts
-luafmts: $(all_luafmts)
-
-luafmtdir = $(web2cdir)/luatex
-$(luafmtdir)::
- $(SHELL) $(top_srcdir)/../mkinstalldirs $(luafmtdir)
-
-luatex.fmt: luatex
- $(dumpenv) $(MAKE) progname=luatex files="etex.src plain.tex cmr10.tfm" prereq-check
- $(dumpenv) ./luatex --progname=luatex --jobname=luatex --ini \*\\pdfoutput=1\\input etex.src \\dump </dev/null
-
-#
-# Installation.
-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
-
-#
-# luatex binaries archive
-luatexbin:
- $(MAKE) $(luatex_bin)
-
-luatex-cross:
- $(MAKE) luatex-web2c-cross
- $(MAKE) luatexbin
-
-luatex-web2c-cross: $(web2c_programs)
- @if test ! -x $(linux_build_dir)/luatangle; then echo Error: linux_build_dir not ready; exit -1; fi
- rm -f web2c/fixwrites web2c/splitup web2c/web2c
- cp -f $(linux_build_dir)/web2c/fixwrites web2c
- cp -f $(linux_build_dir)/web2c/splitup web2c
- cp -f $(linux_build_dir)/web2c/web2c web2c
- touch web2c/fixwrites web2c/splitup web2c/web2c
- $(MAKE) tangleboot && rm -f tangleboot && \
- cp -f $(linux_build_dir)/tangleboot . && touch tangleboot
- $(MAKE) ctangleboot && rm -f ctangleboot && \
- cp -f $(linux_build_dir)/ctangleboot . && touch ctangleboot
- $(MAKE) ctangle && rm -f ctangle && \
- cp -f $(linux_build_dir)/ctangle . && touch ctangle
- $(MAKE) tie && rm -f tie && \
- cp -f $(linux_build_dir)/tie . && touch tie
- $(MAKE) luatangle && rm -f luatangle && \
- cp -f $(linux_build_dir)/luatangle . && touch luatangle
-
-# vim: set noexpandtab
-# end of luatex.mk
diff --git a/Build/source/texk/web2c/luatexdir/luatex.web b/Build/source/texk/web2c/luatexdir/luatex.web
deleted file mode 100644
index 2a2589f7d07..00000000000
--- a/Build/source/texk/web2c/luatexdir/luatex.web
+++ /dev/null
@@ -1,31941 +0,0 @@
-% luatex.web
-%
-% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org>
-% Copyright 2006-2009 Hartmut Henkel <hartmut@@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.
-%
-% 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 <http://www.gnu.org/licenses/>.
-%
-% $Id$
-
-% pdfTeX is copyright (C) 1996-2006 Han The Thanh, <thanh@@pdftex.org>.
-% e-TeX is copyright (C) 1994,98 by Peter Breitenlohner.
-
-% This program is directly derived from Donald E. Knuth's TeX;
-% the change history which follows and the reward offered for finders of
-% bugs refer specifically to TeX; they should not be taken as referring
-% to e-TeX, although the change history is relevant in that it
-% demonstrates the evolutionary path followed. This program is not TeX;
-% that name is reserved strictly for the program which is the creation
-% and sole responsibility of Professor Knuth.
-
-% Version 0 was released in September 1982 after it passed a variety of tests.
-% Version 1 was released in November 1983 after thorough testing.
-% Version 1.1 fixed ``disappearing font identifiers'' et alia (July 1984).
-% Version 1.2 allowed `0' in response to an error, et alia (October 1984).
-% Version 1.3 made memory allocation more flexible and local (November 1984).
-% Version 1.4 fixed accents right after line breaks, et alia (April 1985).
-% Version 1.5 fixed \the\toks after other expansion in \edefs (August 1985).
-% Version 2.0 (almost identical to 1.5) corresponds to "Volume B" (April 1986).
-% Version 2.1 corrected anomalies in discretionary breaks (January 1987).
-% Version 2.2 corrected "(Please type...)" with null \endlinechar (April 1987).
-% Version 2.3 avoided incomplete page in premature termination (August 1987).
-% Version 2.4 fixed \noaligned rules in indented displays (August 1987).
-% Version 2.5 saved cur_order when expanding tokens (September 1987).
-% Version 2.6 added 10sp slop when shipping leaders (November 1987).
-% Version 2.7 improved rounding of negative-width characters (November 1987).
-% Version 2.8 fixed weird bug if no \patterns are used (December 1987).
-% Version 2.9 made \csname\endcsname's "relax" local (December 1987).
-% Version 2.91 fixed \outer\def\a0{}\a\a bug (April 1988).
-% Version 2.92 fixed \patterns, also file names with complex macros (May 1988).
-% Version 2.93 fixed negative halving in allocator when mem_min<0 (June 1988).
-% Version 2.94 kept open_log_file from calling fatal_error (November 1988).
-% Version 2.95 solved that problem a better way (December 1988).
-% Version 2.96 corrected bug in "Infinite shrinkage" recovery (January 1989).
-% Version 2.97 corrected blunder in creating 2.95 (February 1989).
-% Version 2.98 omitted save_for_after at outer level (March 1989).
-% Version 2.99 caught $$\begingroup\halign..$$ (June 1989).
-% Version 2.991 caught .5\ifdim.6... (June 1989).
-% Version 2.992 introduced major changes for 8-bit extensions (September 1989).
-% Version 2.993 fixed a save_stack synchronization bug et alia (December 1989).
-% Version 3.0 fixed unusual displays; was more \output robust (March 1990).
-% Version 3.1 fixed nullfont, disabled \write{\the\prevgraf} (September 1990).
-% Version 3.14 fixed unprintable font names and corrected typos (March 1991).
-% Version 3.141 more of same; reconstituted ligatures better (March 1992).
-% 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
-% 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
-% connection with the use or performance of this software. This work has
-% been a ``labor of love'' and the authors hope that users enjoy it.
-
-% Here is TeX material that gets inserted after \input webmac
-\def\hang{\hangindent 3em\noindent\ignorespaces}
-\def\hangg#1 {\hang\hbox{#1 }}
-\def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces}
-\font\ninerm=cmr9
-\let\mc=\ninerm % medium caps for names like SAIL
-\def\PASCAL{Pascal}
-\def\pdfTeX{pdf\TeX}
-\def\pdfeTeX{pdf\eTeX}
-\def\PDF{PDF}
-\def\Aleph{Aleph}
-\def\eTeX{e\TeX}
-\def\LuaTeX{Lua\TeX}
-\def\THANH{H\`an Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh}
-\def\ph{\hbox{Pascal-H}}
-\def\pct!{{\char`\%}} % percent sign in ordinary text
-\def\grp{\.{\char'173...\char'175}}
-\font\logo=logo10 % font used for the METAFONT logo
-\def\MF{{\logo META}\-{\logo FONT}}
-\def\<#1>{$\langle#1\rangle$}
-\def\section{\mathhexbox278}
-
-\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@@>
-
-\outer\def\N#1. \[#2]#3.{\MN#1.\vfil\eject % begin starred section
- \def\rhead{PART #2:\uppercase{#3}} % define running headline
- \message{*\modno} % progress report
- \edef\next{\write\cont{\Z{\?#2]#3}{\modno}{\the\pageno}}}\next
- \ifon\startsection{\bf\ignorespaces#3.\quad}\ignorespaces}
-\let\?=\relax % we want to be able to \write a \?
-
-\def\title{LuaTeX}
-\let\maybe=\iffalse % print only changed modules
-\def\topofcontents{\hsize 5.5in
- \vglue 0pt plus 1fil minus 1.5in
- \def\?##1]{\hbox to 1in{\hfil##1.\ }}
- }
-\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in}
-\pageno=3
-\def\glob{13} % this should be the section number of "<Global...>"
-\def\gglob{20, 26} % this should be the next two sections of "<Global...>"
-
-@* \[1] Introduction.
-
-This is LuaTeX, a continuation of $\pdfTeX$ and $\Aleph$. LuaTeX is a
-document compiler intended to simplify high-quality typesetting for
-many of the world's languages. It is an extension of D. E. Knuth's
-\TeX, which was designed essentially for the typesetting of languages
-using the Latin alphabet.
-
-The $\Aleph$ subsystem loosens many of the restrictions imposed by~\TeX:
-register numbers are no longer limited to 8~bits; fonts may have more
-than 256~characters; more than 256~fonts may be used; etc.
-
-The \PASCAL\ program that follows is the definition of \TeX82, a standard
-@:PASCAL}{\PASCAL@>
-@!@:TeX82}{\TeX82@>
-version of \TeX\ that is designed to be highly portable so that
-identical output will be obtainable on a great variety of computers.
-
-The main purpose of the following program is to explain the algorithms of \TeX\
-as clearly as possible. As a result, the program will not necessarily be very
-efficient when a particular \PASCAL\ compiler has translated it into a
-particular machine language. 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 \PASCAL; the preprocessing step that converts \.{WEB}
-to \PASCAL\ is able to introduce most of the necessary refinements.
-Semi-automatic translation to other languages is also feasible, because the
-program below does not make extensive use of features that are peculiar to
-\PASCAL.
-
-A large piece of software like \TeX\ 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
-\TeX\ language itself, since the reader is supposed to be familiar with
-{\sl The \TeX book}.
-@.WEB@>
-@:TeXbook}{\sl The \TeX book@>
-
-@ The present implementation has a long ancestry, beginning in the summer
-of~1977, when Michael~F. Plass and Frank~M. Liang designed and coded
-a prototype
-@^Plass, Michael Frederick@>
-@^Liang, Franklin Mark@>
-@^Knuth, Donald Ervin@>
-based on some specifications that the author had made in May of that year.
-This original proto\TeX\ included macro definitions and elementary
-manipulations on boxes and glue, but it did not have line-breaking,
-page-breaking, mathematical formulas, alignment routines, error recovery,
-or the present semantic nest; furthermore,
-it used character lists instead of token lists, so that a control sequence
-like \.{\\halign} was represented by a list of seven characters. A
-complete version of \TeX\ was designed and coded by the author in late
-1977 and early 1978; that program, like its prototype, was written in the
-{\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@>
-was written by the author during the latter part of 1981 and the early
-part of 1982, also incorporates ideas from the 1979 implementation of
-@^Guibas, Leonidas Ioannis@>
-@^Sedgewick, Robert@>
-@^Wyatt, Douglas Kirk@>
-\TeX\ in {\mc MESA} that was written by Leonidas Guibas, Robert Sedgewick,
-and Douglas Wyatt at the Xerox Palo Alto Research Center. Several hundred
-refinements were introduced into \TeX82 based on the experiences gained with
-the original implementations, so that essentially every part of the system
-has been substantially improved. After the appearance of ``Version 0'' in
-September 1982, this program benefited greatly from the comments of
-many other people, notably David~R. Fuchs and Howard~W. Trickey.
-A final revision in September 1989 extended the input character set to
-eight-bit codes and introduced the ability to hyphenate words from
-different languages, based on some ideas of Michael~J. Ferguson.
-@^Fuchs, David Raymond@>
-@^Trickey, Howard Wellington@>
-@^Ferguson, Michael John@>
-
-No doubt there still is plenty of room for improvement, but the author
-is firmly committed to keeping \TeX82 ``frozen'' from now on; stability
-and reliability are to be its main virtues.
-
-On the other hand, the \.{WEB} description can be extended without changing
-the core of \TeX82 itself, and the program has been designed so that such
-extensions are not extremely difficult to make.
-The |banner| string defined here should be changed whenever \TeX\
-undergoes any modifications, so that it will be clear which version of
-\TeX\ might be the guilty party when a problem arises.
-@^extensions to \TeX@>
-@^system dependencies@>
-
-This program contains code for various features extending \TeX,
-therefore this program is called `\eTeX' and not
-`\TeX'; the official name `\TeX' by itself is reserved
-for software systems that are fully compatible with each other.
-A special test suite called the ``\.{TRIP} test'' is available for
-helping to determine whether a particular implementation deserves to be
-known as `\TeX' [cf.~Stanford Computer Science report CS1027,
-November 1984].
-
-A similar test suite called the ``\.{e-TRIP} test'' is available for
-helping to determine whether a particular implementation deserves to be
-known as `\eTeX'.
-
-@d eTeX_version_string=="2.2" {current \eTeX\ version}
-@d Omega_version_string=="1.15" { \.{\\OmegaVersion} }
-@d Aleph_version_string=="0.0" { \.{\\AlephVersion} }
-@d eTeX_version=2 { \.{\\eTeXversion} }
-@d Omega_version=1 { \.{\\Omegaversion} }
-@d Aleph_version=0 { \.{\\Alephversion} }
-@d eTeX_minor_version=1 { \.{\\eTeXminorversion} }
-@d Omega_minor_version=15 { \.{\\Omegaminorversion} }
-@d Aleph_minor_version=0 { \.{\\Alephminorversion} }
-@d eTeX_revision==".2" { \.{\\eTeXrevision} }
-@d Omega_revision==".15" { \.{\\Omegarevision} }
-@d Aleph_revision==".0" { \.{\\Alephrevision} }
-@#
-@d pdftex_version==200 { \.{\\pdftexversion} }
-@d pdftex_revision=="0" { \.{\\pdftexrevision} }
-@d pdftex_version_string=='-2.00.0' {current \pdfTeX\ version}
-@#
-@d luatex_version==40 { \.{\\luatexversion} }
-@d luatex_revision=="6" { \.{\\luatexrevision} }
-@d luatex_version_string=='beta-0.40.6' {current \LuaTeX\ version}
-@d luatex_date_info==-extra_version_info { the compile date is negated }
-@d luatex_svnversion=='$Id$'
- {for long --version information, as proposed by Peter M\"unster}
-@#
-@d LuaTeX_banner=='This is LuaTeX, Version ',luatex_version_string,extra_version_info
- {printed when \LuaTeX\ starts}
-@#
-@d banner==LuaTeX_banner
-@#
-@d TEX==ETEX {change program name into |ETEX|}
-
-@ Different \PASCAL s have slightly different conventions, and the present
-@!@:PASCAL H}{\ph@>
-program expresses \TeX\ in terms of the \PASCAL\ that was
-available to the author in 1982. Constructions that apply to
-this particular compiler, which we shall call \ph, should help the
-reader see how to make an appropriate interface for other systems
-if necessary. (\ph\ is Charles Hedrick's modification of a compiler
-@^Hedrick, Charles Locke@>
-for the DECsystem-10 that was originally developed at the University of
-Hamburg; cf.\ {\sl SOFTWARE---Practice \AM\ Experience \bf6} (1976),
-29--42. The \TeX\ program below is intended to be adaptable, without
-extensive changes, to most other versions of \PASCAL, so it does not fully
-use the admirable features of \ph. Indeed, a conscious effort has been
-made here to avoid using several idiosyncratic features of standard
-\PASCAL\ itself, so that most of the code can be translated mechanically
-into other high-level languages. For example, the `\&{with}' and `\\{new}'
-features are not used, nor are pointer types, set types, or enumerated
-scalar types; there are no `\&{var}' parameters, except in the case of files
---- \eTeX, however, does use `\&{var}' parameters for the |reverse| function;
-there are no tag fields on variant records; there are no assignments
-|real:=integer|; no procedures are declared local to other procedures.)
-
-The portions of this program that involve system-dependent code, where
-changes might be necessary because of differences between \PASCAL\ compilers
-and/or differences between
-operating systems, can be identified by looking at the sections whose
-numbers are listed under `system dependencies' in the index. Furthermore,
-the index entries for `dirty \PASCAL' list all places where the restrictions
-of \PASCAL\ have not been followed perfectly, for one reason or another.
-@!@^system dependencies@>
-@!@^dirty \PASCAL@>
-
-Incidentally, \PASCAL's standard |round| function can be problematical,
-because it disagrees with the IEEE floating-point standard.
-Many implementors have
-therefore chosen to substitute their own home-grown rounding procedure.
-
-@ The program begins with a normal \PASCAL\ program heading, whose
-components will be filled in later, using the conventions of \.{WEB}.
-@.WEB@>
-For example, the portion of the program called `\X\glob:Global
-variables\X' below will be replaced by a sequence of variable declarations
-that starts in $\section\glob$ of this documentation. In this way, we are able
-to define each individual global variable when we are prepared to
-understand what it means; we do not have to define all of the globals at
-once. Cross references in $\section\glob$, where it says ``See also
-sections \gglob, \dots,'' also make it possible to look at the set of
-all global variables, if desired. Similar remarks apply to the other
-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:}
-@f mtype==type {`\&{mtype}' will be equivalent to `\&{type}'}
-@f type==true {but `|type|' will not be treated as a reserved word}
-
-@p @t\4@>@<Compiler directives@>@/
-program TEX; {all file names are defined dynamically}
-label @<Labels in the outer block@>@/
-const @<Constants in the outer block@>@/
-mtype @<Types in the outer block@>@/
-var @<Global variables@>@/
-@#
-procedure initialize; {this procedure gets things started properly}
- var @<Local variables for initialization@>@/
- begin @<Initialize whatever \TeX\ might access@>@;
- end;@#
-@t\4@>@<Basic printing procedures@>@/
-@t\4@>@<Error handling procedures@>@/
-
-@ 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
-
-@<Initialize whatever \TeX\ might access@>=
-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
-comment `|start_here|'. If you want to skip down to the
-main program now, you can look up `|start_here|' in the index.
-But the author suggests that the best way to understand this program
-is to follow pretty much the order of \TeX's components as they appear in the
-\.{WEB} description you are now reading, since the present ordering is
-intended to combine the advantages of the ``bottom up'' and ``top down''
-approaches to the problem of understanding a somewhat complicated system.
-
-@ Three labels must be declared in the main program, so we give them
-symbolic names.
-
-@d start_of_TEX=1 {go here when \TeX's variables are initialized}
-@d end_of_TEX=9998 {go here to close files and terminate gracefully}
-@d final_end=9999 {this label marks the ending of the program}
-
-@<Labels in the out...@>=
-start_of_TEX@t\hskip-2pt@>, end_of_TEX@t\hskip-2pt@>,@,final_end;
- {key control points}
-
-@ Some of the code below is intended to be used only when diagnosing the
-strange behavior that sometimes occurs when \TeX\ is being installed or
-when system wizards are fooling around with \TeX\ without quite knowing
-what they are doing. Such code will not normally be compiled; it is
-delimited by the codewords `$|debug|\ldots|gubed|$', with apologies
-to people who wish to preserve the purity of English.
-
-Similarly, there is some conditional code delimited by
-`$|stat|\ldots|tats|$' that is intended for use when statistics are to be
-kept about \TeX's memory usage. The |stat| $\ldots$ |tats| code also
-implements diagnostic information for \.{\\tracingparagraphs} and
-\.{\\tracingpages}.
-@^debugging@>
-
-@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging}
-@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging}
-@f debug==begin
-@f gubed==end
-@#
-@d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering
- usage statistics}
-@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering
- usage statistics}
-@f stat==begin
-@f tats==end
-
-@ This program has two important variations: (1) There is a long and slow
-version called \.{INITEX}, which does the extra calculations needed to
-@.INITEX@>
-initialize \TeX's internal tables; and (2)~there is a shorter and faster
-production version, which cuts the initialization to a bare minimum.
-Parts of the program that are needed in (1) but not in (2) are delimited by
-the codewords `$|init|\ldots|tini|$'.
-
-@d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version}
-@d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version}
-@f init==begin
-@f tini==end
-
-@<Initialize whatever...@>=
-@<Set initial values of key variables@>@/
-@!init @<Initialize table entries (done by \.{INITEX} only)@>@;@+tini
-
-@ If the first character of a \PASCAL\ comment is a dollar sign,
-\ph\ treats the comment as a list of ``compiler directives'' that will
-affect the translation of this program into machine language. The
-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@>
-
-@<Compiler directives@>=
-@{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead}
-@!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging}
-
-@ This \TeX\ implementation conforms to the rules of the {\sl Pascal User
-@:PASCAL}{\PASCAL@>
-@^system dependencies@>
-Manual} published by Jensen and Wirth in 1975, except where system-dependent
-@^Wirth, Niklaus@>
-@^Jensen, Kathleen@>
-code is necessary to make a useful system program, and except in another
-respect where such conformity would unnecessarily obscure the meaning
-and clutter up the code: We assume that |case| statements may include a
-default case that applies if no matching label is found. Thus, we shall use
-constructions like
-$$\vbox{\halign{\ignorespaces#\hfil\cr
-|case x of|\cr
-1: $\langle\,$code for $x=1\,\rangle$;\cr
-3: $\langle\,$code for $x=3\,\rangle$;\cr
-|othercases| $\langle\,$code for |x<>1| and |x<>3|$\,\rangle$\cr
-|endcases|\cr}}$$
-since most \PASCAL\ compilers have plugged this hole in the language by
-incorporating some sort of default mechanism. For example, the \ph\
-compiler allows `|others|:' as a default label, and other \PASCAL s allow
-syntaxes like `\&{else}' or `\&{otherwise}' or `\\{otherwise}:', etc. The
-definitions of |othercases| and |endcases| should be changed to agree with
-local conventions. Note that no semicolon appears before |endcases| in
-this program, so the definition of |endcases| should include a semicolon
-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}
-@f othercases == else
-@f endcases == end
-
-@ The following parameters can be changed at compile time to extend or
-reduce \TeX's capacity. They may have different values in \.{INITEX} and
-in production versions of \TeX.
-@.INITEX@>
-@^system dependencies@>
-
-@<Constants...@>=
-@!buf_size=500; {maximum number of characters simultaneously present in
- current lines of open files and in control sequences between
- \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|}
-@!error_line=72; {width of context lines on terminal error messages}
-@!half_error_line=42; {width of first lines of contexts in terminal
- error messages; should be between 30 and |error_line-15|}
-@!max_print_line=79; {width of longest text lines output; should be at least 60}
-@!stack_size=200; {maximum number of simultaneous input sources}
-@!max_in_open=6; {maximum number of input files and error insertions that
- can be going on simultaneously}
-@!param_size=60; {maximum number of simultaneous macro parameters}
-@!nest_size=40; {maximum number of semantic levels simultaneously active}
-@!max_strings=3000; {maximum number of strings; must not exceed |max_halfword|}
-@!string_vacancies=8000; {the minimum number of characters that should be
- available for the user's control sequences and font names,
- after \TeX's own error messages are stored}
-@!pool_size=32000; {maximum number of characters in strings, including all
- error messages and help texts, and the names of all fonts and
- control sequences; must exceed |string_vacancies| by the total
- length of \TeX's own strings, which is currently about 23000}
-@!save_size=600; {space for saving values outside of current group; must be
- at most |max_halfword|}
-@!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8}
-@!expand_depth=10000; {limits recursive calls of the |expand| procedure}
-@!file_name_size=40; {file names shouldn't be longer than this}
-@!pool_name='TeXformats:TEX.POOL ';
- {string of length |file_name_size|; tells where the string pool appears}
-@.TeXformats@>
-@!active_mem_size=50000; {number of words of |active_info| for active ocps}
-@!ocp_maxint=@"10000000;
-
-
-@ Like the preceding parameters, the following quantities can be changed
-at compile time to extend or reduce \TeX's capacity. But if they are changed,
-it is necessary to rerun the initialization program \.{INITEX}
-@.INITEX@>
-to generate new tables for the production \TeX\ program.
-One can't simply make helter-skelter changes to the following constants,
-since certain rather complex initialization
-numbers are computed from them. They are defined here using
-\.{WEB} macros, instead of being put into \PASCAL's |const| list, in order to
-emphasize this distinction.
-
-@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 |(fix_mem_max-fix_mem_min)/10|}
-@d ocp_base=0 {smallest internal ocp number; must not be less
- than |min_quarterword|}
-@d ocp_biggest=32767 {the real biggest ocp}
-@d number_ocps=ocp_biggest-ocp_base+1
-@d ocp_list_base=0 {smallest internal ocp list number; must not be less
- than |min_quarterword|}
-@d ocp_list_biggest=32727 {the real biggest ocp list}
-@d number_ocp_lists=ocp_list_biggest-ocp_list_base+1
-@d max_active_ocp_lists=32768
-@d biggest_reg=65535 {the largest allowed register number; must be |<=max_quarterword|}
-@d number_regs=65536 {|biggest_reg+1|}
-@d number_attrs=65536 {total numbeer of attributes}
-@d biggest_mark=65535 {the largest allowed marks class; must be |<=max_quarterword|}
-@d number_marks=65536 {|biggest_mark+1|}
-{using |2^20+2^16| characters instead of |2^21| saves 286MB on the virtual memory size
- of the running executable}
-@d biggest_char=1114111 {2097151} {the largest allowed character number; must be |<=max_halfword|}
-@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 string_offset=2097152
-@d font_biggest=5535 {the real biggest font}
-@d number_fonts=font_biggest-font_base+1
-@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=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,''
-\TeX\ checks them using a global variable called |bad|.
-
-This is the first of many sections of \TeX\ where global variables are
-defined.
-
-@<Glob...@>=
-@!bad:integer; {is some ``constant'' wrong?}
-@!luainit:boolean; {are we using lua for initializations }
-@!tracefilenames:boolean; { print file open-close info? }
-
-@ Later on we will say `\ignorespaces|if X>=max_halfword then bad:=14|',
-or something similar. (We can't do that until |max_halfword| has been defined.)
-
-@<Check the ``constant'' values for consistency@>=
-bad:=0;
-if not luainit then tracefilenames:=true;
-if (half_error_line<30)or(half_error_line>error_line-15) then bad:=1;
-if max_print_line<60 then bad:=2;
-if dvi_buf_size mod 8<>0 then bad:=3;
-if hash_prime>hash_size then bad:=5;
-if max_in_open>=128 then bad:=6;
-{ |if null_list<256 then bad:=7;| } {we will want |null_list>255|}
-
-@ Labels are given symbolic names by the following definitions, so that
-occasional |goto| statements will be meaningful. We insert the label
-`|exit|' just before the `\ignorespaces|end|\unskip' of a procedure in
-which we have used the `|return|' statement defined below; the label
-`|restart|' is occasionally used at the very beginning of a procedure; and
-the label `|reswitch|' is occasionally used just prior to a |case|
-statement in which some cases change the conditions and we wish to branch
-to the newly applicable case. Loops that are set up with the |loop|
-construction defined below are commonly exited by going to `|done|' or to
-`|found|' or to `|not_found|', and they are sometimes repeated by going to
-`|continue|'. If two or more parts of a subroutine start differently but
-end up the same, the shared code may be gathered together at
-`|common_ending|'.
-
-Incidentally, this program never declares a label that isn't actually used,
-because some fussy \PASCAL\ compilers will complain about redundant labels.
-
-@d exit=10 {go here to leave a procedure}
-@d restart=20 {go here to start a procedure again}
-@d reswitch=21 {go here to start a case statement again}
-@d continue=22 {go here to resume a loop}
-@d done=30 {go here to exit a loop}
-@d done1=31 {like |done|, when there is more than one loop}
-@d done2=32 {for exiting the second loop in a long block}
-@d done3=33 {for exiting the third loop in a very long block}
-@d done4=34 {for exiting the fourth loop in an extremely long block}
-@d done5=35 {for exiting the fifth loop in an immense block}
-@d done6=36 {for exiting the sixth loop in a block}
-@d found=40 {go here when you've found it}
-@d found1=41 {like |found|, when there's more than one per routine}
-@d found2=42 {like |found|, when there's more than two per routine}
-@d not_found=45 {go here when you've found nothing}
-@d not_found1=46 {like |not_found|, when there's more than one}
-@d not_found2=47 {like |not_found|, when there's more than two}
-@d not_found3=48 {like |not_found|, when there's more than three}
-@d not_found4=49 {like |not_found|, when there's more than four}
-@d common_ending=50 {go here when you want to merge with another branch}
-
-@ Here are some macros for common programming idioms.
-
-@d incr(#) == #:=#+1 {increase a variable by unity}
-@d decr(#) == #:=#-1 {decrease a variable by unity}
-@d negate(#) == #:=-# {change the sign of a variable}
-@d loop == @+ while true do@+ {repeat over and over until a |goto| happens}
-@f loop == xclause
- {\.{WEB}'s |xclause| acts like `\ignorespaces|while true do|\unskip'}
-@d do_nothing == pdfassert(1) {empty statement}
-@d return == goto exit {terminate a procedure call}
-@f return == nil
-@d empty=0 {symbolic name for a null constant}
-
-@* \[2] The character set.
-In order to make \TeX\ readily portable to a wide variety of
-computers, all of its input text is converted to an internal
-twenty-one-bit code that covers all of unicode, including ASCII, the
-``American Standard Code for Information Interchange.'' This
-conversion is done immediately when each character is read
-in. Conversely, characters are converted from ASCII to the user's
-external representation just before they are output to a text file.
-
-Such an internal code is relevant to users of \TeX\ primarily because it
-governs the positions of characters in the fonts. For example, the
-character `\.A' has ASCII code $65=@'101$, and when \TeX\ typesets
-this letter it specifies character number 65 in the current font.
-If that font actually has `\.A' in a different position, \TeX\ doesn't
-know what the real position is; the program that does the actual printing from
-\TeX's device-independent files is responsible for converting from ASCII to
-a particular font encoding.
-@^ASCII code@>
-
-\TeX's internal code also defines the value of constants
-that begin with a reverse apostrophe; and it provides an index to the
-\.{\\catcode}, \.{\\mathcode}, \.{\\uccode}, \.{\\lccode}, and \.{\\delcode}
-tables.
-
-@ Characters of text that have been converted to \TeX's internal form
-are said to be of type |ASCII_code|, which is a subrange of the integers.
-
-@<Types...@>=
-@!ASCII_code=0..biggest_char; {eight-bit numbers}
-@!BMP_code=0..65535; {sixteen-bit numbers}
-
-@ The original \PASCAL\ compiler was designed in the late 60s, when six-bit
-character sets were common, so it did not make provision for lowercase
-letters. Nowadays, of course, we need to deal with both capital and small
-letters in a convenient way, especially in a program for typesetting;
-so the present specification of \TeX\ has been written under the assumption
-that the \PASCAL\ compiler and run-time system permit the use of text files
-with more than 64 distinguishable characters. More precisely, we assume that
-the character set contains at least the letters and symbols associated
-with ASCII codes @'40 through @'176; all of these characters are now
-available on most computer terminals.
-
-Since we are dealing with more characters than were present in the first
-\PASCAL\ compilers, we have to decide what to call the associated data
-type. Some \PASCAL s use the original name |char| for the
-characters in text files, even though there now are more than 64 such
-characters, while other \PASCAL s consider |char| to be a 64-element
-subrange of a larger data type that has some other name.
-
-In order to accommodate this difference, we shall use the name |text_char|
-to stand for the data type of the characters that are converted to and
-from |ASCII_code| when they are input and output. We shall also assume
-that |text_char| consists of the elements |chr(first_text_char)| through
-|chr(last_text_char)|, inclusive. The following definitions should be
-adjusted if necessary.
-@^system dependencies@>
-
-@d text_char == char {the data type of characters in text files}
-@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
-@d last_text_char=255 {ordinal number of the largest element of |text_char|}
-
-@<Local variables for init...@>=
-@!i:integer;
-
-@ The \TeX\ processor converts between ASCII code and
-the user's external character set by means of arrays |xord| and |xchr|
-that are analogous to \PASCAL's |ord| and |chr| functions.
-
-@<Glob...@>=
-@!xchr: array [ASCII_code] of text_char;
- {specifies conversion of output characters}
-
-@ Since we are assuming that our \PASCAL\ system is able to read and
-write the visible characters of standard ASCII (although not
-necessarily using the ASCII codes to represent them), the following
-assignment statements initialize the standard part of the |xchr| array
-properly, without needing any system-dependent changes. On the other
-hand, it is possible to implement \TeX\ with less complete character
-sets, and in such cases it will be necessary to change something here.
-@^system dependencies@>
-
-@<Set init...@>=
-xchr[@'40]:=' ';
-xchr[@'41]:='!';
-xchr[@'42]:='"';
-xchr[@'43]:='#';
-xchr[@'44]:='$';
-xchr[@'45]:='%';
-xchr[@'46]:='&';
-xchr[@'47]:='''';@/
-xchr[@'50]:='(';
-xchr[@'51]:=')';
-xchr[@'52]:='*';
-xchr[@'53]:='+';
-xchr[@'54]:=',';
-xchr[@'55]:='-';
-xchr[@'56]:='.';
-xchr[@'57]:='/';@/
-xchr[@'60]:='0';
-xchr[@'61]:='1';
-xchr[@'62]:='2';
-xchr[@'63]:='3';
-xchr[@'64]:='4';
-xchr[@'65]:='5';
-xchr[@'66]:='6';
-xchr[@'67]:='7';@/
-xchr[@'70]:='8';
-xchr[@'71]:='9';
-xchr[@'72]:=':';
-xchr[@'73]:=';';
-xchr[@'74]:='<';
-xchr[@'75]:='=';
-xchr[@'76]:='>';
-xchr[@'77]:='?';@/
-xchr[@'100]:='@@';
-xchr[@'101]:='A';
-xchr[@'102]:='B';
-xchr[@'103]:='C';
-xchr[@'104]:='D';
-xchr[@'105]:='E';
-xchr[@'106]:='F';
-xchr[@'107]:='G';@/
-xchr[@'110]:='H';
-xchr[@'111]:='I';
-xchr[@'112]:='J';
-xchr[@'113]:='K';
-xchr[@'114]:='L';
-xchr[@'115]:='M';
-xchr[@'116]:='N';
-xchr[@'117]:='O';@/
-xchr[@'120]:='P';
-xchr[@'121]:='Q';
-xchr[@'122]:='R';
-xchr[@'123]:='S';
-xchr[@'124]:='T';
-xchr[@'125]:='U';
-xchr[@'126]:='V';
-xchr[@'127]:='W';@/
-xchr[@'130]:='X';
-xchr[@'131]:='Y';
-xchr[@'132]:='Z';
-xchr[@'133]:='[';
-xchr[@'134]:='\';
-xchr[@'135]:=']';
-xchr[@'136]:='^';
-xchr[@'137]:='_';@/
-xchr[@'140]:='`';
-xchr[@'141]:='a';
-xchr[@'142]:='b';
-xchr[@'143]:='c';
-xchr[@'144]:='d';
-xchr[@'145]:='e';
-xchr[@'146]:='f';
-xchr[@'147]:='g';@/
-xchr[@'150]:='h';
-xchr[@'151]:='i';
-xchr[@'152]:='j';
-xchr[@'153]:='k';
-xchr[@'154]:='l';
-xchr[@'155]:='m';
-xchr[@'156]:='n';
-xchr[@'157]:='o';@/
-xchr[@'160]:='p';
-xchr[@'161]:='q';
-xchr[@'162]:='r';
-xchr[@'163]:='s';
-xchr[@'164]:='t';
-xchr[@'165]:='u';
-xchr[@'166]:='v';
-xchr[@'167]:='w';@/
-xchr[@'170]:='x';
-xchr[@'171]:='y';
-xchr[@'172]:='z';
-xchr[@'173]:='{';
-xchr[@'174]:='|';
-xchr[@'175]:='}';
-xchr[@'176]:='~';@/
-
-@ Some of the ASCII codes without visible characters have been given symbolic
-names in this program because they are used with a special meaning.
-
-@d null_code=@'0 {ASCII code that might disappear}
-@d carriage_return=@'15 {ASCII code used at end of line}
-@d invalid_code=@'177 {ASCII code that many systems prohibit in text files}
-
-@ The ASCII code is ``standard'' only to a certain extent, since many
-computer installations have found it advantageous to have ready access
-to more than 94 printing characters. Appendix~C of {\sl The \TeX book\/}
-gives a complete specification of the intended correspondence between
-characters and \TeX's internal representation.
-@:TeXbook}{\sl The \TeX book@>
-
-If \TeX\ is being used
-on a garden-variety \PASCAL\ for which only standard ASCII
-codes will appear in the input and output files, it doesn't really matter
-what codes are specified in |xchr[0..@'37]|, but the safest policy is to
-blank everything out by using the code shown below.
-
-However, other settings of |xchr| will make \TeX\ more friendly on
-computers that have an extended character set, so that users can type things
-like `\.^^Z' instead of `\.{\\ne}'. People with extended character sets can
-assign codes arbitrarily, giving an |xchr| equivalent to whatever
-characters the users of \TeX\ are allowed to have in their input files.
-It is best to make the codes correspond to the intended interpretations as
-shown in Appendix~C whenever possible; but this is not necessary. For
-example, in countries with an alphabet of more than 26 letters, it is
-usually best to map the additional letters into codes less than~@'40.
-To get the most ``permissive'' character set, change |' '| on the
-right of these assignment statements to |chr(i)|.
-@^character set dependencies@>
-@^system dependencies@>
-
-@<Set init...@>=
-for i:=0 to biggest_char do xchr[i]:=i;
-
-@ The following system-independent code makes the |xord| array contain a
-suitable inverse to the information in |xchr|. Note that if |xchr[i]=xchr[j]|
-where |i<j<@'177|, the value of |xord[xchr[i]]| will turn out to be
-|j| or more; hence, standard ASCII code numbers will be used instead of
-codes below @'40 in case there is a coincidence.
-
-@<Set init...@>=
-
-@* \[3] Input and output.
-The bane of portability is the fact that different operating systems treat
-input and output quite differently, perhaps because computer scientists
-have not given sufficient attention to this problem. People have felt somehow
-that input and output are not part of ``real'' programming. Well, it is true
-that some kinds of programming are more fun than others. With existing
-input/output conventions being so diverse and so messy, the only sources of
-joy in such parts of the code are the rare occasions when one can find a
-way to make the program a little less bad than it might have been. We have
-two choices, either to attack I/O now and get it over with, or to postpone
-I/O until near the end. Neither prospect is very attractive, so let's
-get it over with.
-
-The basic operations we need to do are (1)~inputting and outputting of
-text, to or from a file or the user's terminal; (2)~inputting and
-outputting of eight-bit bytes, to or from a file; (3)~instructing the
-operating system to initiate (``open'') or to terminate (``close'') input or
-output from a specified file; (4)~testing whether the end of an input
-file has been reached.
-
-\TeX\ needs to deal with two kinds of files.
-We shall use the term |alpha_file| for a file that contains textual data,
-and the term |byte_file| for a file that contains eight-bit binary information.
-These two types turn out to be the same on many computers, but
-sometimes there is a significant distinction, so we shall be careful to
-distinguish between them. Standard protocols for transferring
-such files from computer to computer, via high-speed networks, are
-now becoming available to more and more communities of users.
-
-The program actually makes use also of a third kind of file, called a
-|word_file|, when dumping and reloading base information for its own
-initialization. We shall define a word file later; but it will be possible
-for us to specify simple operations on word files before they are defined.
-
-@<Types...@>=
-@!eight_bits=0..65535; {unsigned one-byte quantity}
-@!real_eight_bits=0..255; {unsigned one-byte quantity}
-@!alpha_file=packed file of text_char; {files that contain textual data}
-@!byte_file=packed file of real_eight_bits; {files that contain binary data}
-
-@ Most of what we need to do with respect to input and output can be handled
-by the I/O facilities that are standard in \PASCAL, i.e., the routines
-called |get|, |put|, |eof|, and so on. But
-standard \PASCAL\ does not allow file variables to be associated with file
-names that are determined at run time, so it cannot be used to implement
-\TeX; some sort of extension to \PASCAL's ordinary |reset| and |rewrite|
-is crucial for our purposes. We shall assume that |nameoffile| is a variable
-of an appropriate type such that the \PASCAL\ run-time system being used to
-implement \TeX\ can open a file whose external name is specified by
-|nameoffile|.
-@^system dependencies@>
-
-@<Glob...@>=
-@!nameoffile:packed array[1..file_name_size] of char;@;@/
- {on some systems this may be a \&{record} variable}
-@!namelength:0..file_name_size;@/{this many characters are actually
- relevant in |nameoffile| (the rest are blank)}
-@!name_file_pointer:alpha_file;
-
-@ The \ph\ compiler with which the present version of \TeX\ was prepared has
-extended the rules of \PASCAL\ in a very convenient way. To open file~|f|,
-we can write
-$$\vbox{\halign{#\hfil\qquad&#\hfil\cr
-|reset(f,@t\\{name}@>,'/O')|&for input;\cr
-|rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$
-The `\\{name}' parameter, which is of type `{\bf packed array
-$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of
-the external file that is being opened for input or output.
-Blank spaces that might appear in \\{name} are ignored.
-
-The `\.{/O}' parameter tells the operating system not to issue its own
-error messages if something goes wrong. If a file of the specified name
-cannot be found, or if such a file cannot be opened for some other reason
-(e.g., someone may already be trying to write the same file), we will have
-|@!erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows
-\TeX\ to undertake appropriate corrective action.
-@:PASCAL H}{\ph@>
-@^system dependencies@>
-
-\TeX's file-opening procedures return |false| if no file identified by
-|nameoffile| could be opened.
-
-@d reset_OK(#)==erstat(#)=0
-@d rewrite_OK(#)==erstat(#)=0
-
-@p function a_open_in(var f:alpha_file):boolean;
- {open a text file for input}
-begin reset(f,nameoffile,'/O'); a_open_in:=reset_OK(f);
-end;
-@#
-function a_open_out(var f:alpha_file):boolean;
- {open a text file for output}
-begin rewrite(f,nameoffile,'/O'); a_open_out:=rewrite_OK(f);
-end;
-@#
-function b_open_in(var f:byte_file):boolean;
- {open a binary file for input}
-begin reset(f,nameoffile,'/O'); b_open_in:=reset_OK(f);
-end;
-@#
-function b_open_out(var f:byte_file):boolean;
- {open a binary file for output}
-begin rewrite(f,nameoffile,'/O'); b_open_out:=rewrite_OK(f);
-end;
-@#
-function w_open_in(var f:word_file):boolean;
- {open a word file for input}
-begin reset(f,nameoffile,'/O'); w_open_in:=reset_OK(f);
-end;
-@#
-function w_open_out(var f:word_file):boolean;
- {open a word file for output}
-begin rewrite(f,nameoffile,'/O'); w_open_out:=rewrite_OK(f);
-end;
-
-@ When input files are opened via a callback, they will also be read using
-callbacks. for that purpose, the |open_read_file_callback| returns an
-integer to uniquely identify a callback table. This id replaces the file
-point |f| in this case, because the input does not have to be a file
-in the traditional sense.
-
-Signalling this fact is achieved by having two arrays of integers.
-
-@<Glob...@>=
-@!input_file_callback_id : ^integer;
-@!read_file_callback_id : array[0..16] of integer;
-
-@
-@p function lua_a_open_in(var f:alpha_file; n:quarterword):boolean;
-var k:integer; { a temporary value }
- fnam:str_number; { string returned by find callback }
- callback_id:integer;
- file_ok:boolean; { the status so far }
-begin
- file_ok:=true;
- if n=0 then begin
- texinputtype := 1; {Tell |open_input| we are \.{\\input}.}
- input_file_callback_id[index] := 0;
- end
- else begin
- texinputtype:=0;
- read_file_callback_id[n] := 0;
- end;
- callback_id:=callback_defined(find_read_file_callback);
- if callback_id>0 then begin
- fnam:=0;
- file_ok:=run_callback(callback_id,'dS->s',n,stringcast(nameoffile+1),addressof(fnam));
- if (file_ok)and(fnam<>0)and(length(fnam)>0) then begin
- @<Fixup |nameoffile| after callback@>;
- end
- else
- file_ok:=false; {file not found}
- end;
- if file_ok then begin
- callback_id:=callback_defined(open_read_file_callback);
- if callback_id>0 then begin
- k := run_and_save_callback(callback_id,'S->',stringcast(nameoffile+1));
- if k>0 then begin
- lua_a_open_in := true;
- if n=0 then
- input_file_callback_id[index] := k
- else
- read_file_callback_id[n] := k;
- end
- else
- file_ok:=false; {read failed}
- end
- else begin {no read callback}
- if kpse_in_name_ok(stringcast(nameoffile+1)) then begin
- lua_a_open_in := a_open_in(f,kpsetexformat);
- name_file_pointer := f;
- end
- else
- file_ok:=false; {open failed}
- end;
- end;
- if not file_ok then begin
- lua_a_open_in := false;
- name_file_pointer := 0;
- end;
-end;
-@#
-function lua_a_open_out(var f:alpha_file; n:quarterword):boolean;
-var test:boolean;
- k:integer;
- fnam:str_number;
- callback_id:integer;
-begin
- name_file_pointer := 0;
- callback_id:=callback_defined(find_write_file_callback);
- if callback_id>0 then begin
- fnam:=0;
- test:=run_callback(callback_id,'dS->s',n,stringcast(nameoffile+1),addressof(fnam));
- if (test)and(fnam<>0)and(length(fnam)>0) then begin
- @<Fixup |nameoffile| after callback@>;
- lua_a_open_out := do_a_open_out(f);
- name_file_pointer := f;
- end
- else
- lua_a_open_out := false;
- end
- else begin
- if kpse_out_name_ok(stringcast(nameoffile+1)) then begin
- lua_a_open_out := a_open_out(f);
- name_file_pointer := f;
- end
- else
- lua_a_open_out := false;
- end;
-end;
-function lua_b_open_out(var f:alpha_file):boolean;
-var test:boolean;
- k:integer;
- fnam:str_number;
- callback_id:integer;
-begin
- name_file_pointer := 0;
- callback_id:=callback_defined(find_output_file_callback);
- if callback_id>0 then begin
- fnam:=0;
- test:=run_callback(callback_id,'S->s',stringcast(nameoffile+1),addressof(fnam));
- if (test)and(fnam<>0)and(length(fnam)>0) then begin
- @<Fixup |nameoffile| after callback@>;
- lua_b_open_out := do_b_open_out(f);
- name_file_pointer := f;
- end
- else
- lua_b_open_out := false;
- end
- else begin
- if kpse_out_name_ok(stringcast(nameoffile+1)) then begin
- lua_b_open_out := b_open_out(f);
- name_file_pointer := f;
- end
- else
- lua_b_open_out := false;
- end;
-end;
-
-@
-@<Fixup |nameoffile| after callback@>=
-libcfree (nameoffile);
-nameoffile := xmallocarray (packed_ASCII_code, length(fnam)+2);
-for k:=str_start_macro(fnam) to str_start_macro(fnam+1)-1 do
- nameoffile[k-str_start_macro(fnam)+1] := str_pool[k];
-nameoffile[length(fnam)+1]:=0;
-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
-output, the |close| operation makes the corresponding external file appear
-on the user's area, ready to be read.
-
-These procedures should not generate error messages if a file is
-being closed before it has been successfully opened.
-
-@p procedure a_close(var f:alpha_file); {close a text file}
-begin close(f);
-end;
-@#
-procedure b_close(var f:byte_file); {close a binary file}
-begin close(f);
-end;
-@#
-procedure w_close(var f:word_file); {close a word file}
-begin close(f);
-end;
-
-
-@
-
-@p procedure lua_a_close_in(var f:alpha_file; n:quarterword); {close a text file}
-var ret:boolean;
- callback_id:integer;
-begin
-if n=0 then
- callback_id:=input_file_callback_id[index]
-else
- callback_id:=read_file_callback_id[n];
-if callback_id>0 then begin
- ret:=run_saved_callback(callback_id,'close','->');
- destroy_saved_callback(callback_id);
- if n=0 then
- input_file_callback_id[index] := 0
- else
- read_file_callback_id[n] := 0;
- end
-else
- a_close(f);
-end;
-@#
-procedure lua_a_close_out(var f:alpha_file); {close a text file}
-begin
- a_close(f);
-end;
-
-
-@ Binary input and output are done with \PASCAL's ordinary |get| and |put|
-procedures, so we don't have to make any other special arrangements for
-binary~I/O. Text output is also easy to do with standard \PASCAL\ routines.
-The treatment of text input is more difficult, however, because
-of the necessary translation to |ASCII_code| values.
-\TeX's conventions should be efficient, and they should
-blend nicely with the user's operating environment.
-
-@ Input from text files is read one line at a time, using a routine called
-|lua_input_ln|. This function is defined in terms of global variables called
-|buffer|, |first|, and |last| that will be described in detail later; for
-now, it suffices for us to know that |buffer| is an array of |ASCII_code|
-values, and that |first| and |last| are indices into this array
-representing the beginning and ending of a line of text.
-
-@<Glob...@>=
-@!buffer:array[0..buf_size] of packed_ASCII_code; {lines of characters being read}
-@!first:0..buf_size; {the first unused position in |buffer|}
-@!last:0..buf_size; {end of the line just input to |buffer|}
-@!max_buf_stack:0..buf_size; {largest index used in |buffer|}
-
-@ The |lua_input_ln| function brings the next line of input from the specified
-file into available positions of the buffer array and returns the value
-|true|, unless the file has already been entirely read, in which case it
-returns |false| and sets |last:=first|. In general, the |ASCII_code|
-numbers that represent the next line of the file are input into
-|buffer[first]|, |buffer[first+1]|, \dots, |buffer[last-1]|; and the
-global variable |last| is set equal to |first| plus the length of the
-line. Trailing blanks are removed from the line; thus, either |last=first|
-(in which case the line was entirely blank) or |buffer[last-1]<>" "|.
-
-An overflow error is given, however, if the normal actions of |lua_input_ln|
-would make |last>=buf_size|; this is done so that other parts of \TeX\
-can safely look at the contents of |buffer[last+1]| without overstepping
-the bounds of the |buffer| array. Upon entry to |lua_input_ln|, the condition
-|first<buf_size| will always hold, so that there is always room for an
-``empty'' line.
-
-The variable |max_buf_stack|, which is used to keep track of how large
-the |buf_size| parameter must be to accommodate the present job, is
-also kept up to date by |lua_input_ln|.
-
-If the |bypass_eoln| parameter is |true|, |lua_input_ln| will do a |get|
-before looking at the first character of the line; this skips over
-an |eoln| that was in |f^|. The procedure does not do a |get| when it
-reaches the end of the line; therefore it can be used to acquire input
-from the user's terminal as well as from ordinary text files.
-
-Standard \PASCAL\ says that a file should have |eoln| immediately
-before |eof|, but \TeX\ needs only a weaker restriction: If |eof|
-occurs in the middle of a line, the system function |eoln| should return
-a |true| result (even though |f^| will be undefined).
-
-Since the inner loop of |lua_input_ln| is part of \TeX's ``inner loop''---each
-character of input comes in at this place---it is wise to reduce system
-overhead by making use of special routines that read in an entire array
-of characters at once, if such routines are available. The following
-code uses standard \PASCAL\ to illustrate what needs to be done, but
-finer tuning is often possible at well-developed \PASCAL\ sites.
-@^inner loop@>
-
-@p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean;
- {inputs the next line or returns |false|}
-var last_nonblank:0..buf_size; {|last| with trailing blanks removed}
-begin if bypass_eoln then if not eof(f) then get(f);
- {input the first character of the line into |f^|}
-last:=first; {cf.\ Matthew 19\thinspace:\thinspace30}
-if eof(f) then input_ln:=false
-else begin last_nonblank:=first;
- while not eoln(f) do
- begin if last>=max_buf_stack then
- begin max_buf_stack:=last+1;
- if max_buf_stack=buf_size then
- @<Report overflow of the input buffer, and abort@>;
- end;
- buffer[last]:=f^; get(f); incr(last);
- if buffer[last-1]<>" " then last_nonblank:=last;
- end;
- last:=last_nonblank; input_ln:=true;
- end;
-end;
-
-function lua_input_ln(var f:alpha_file;n:quarterword;@!bypass_eoln:boolean):boolean;
-var lua_result:boolean;
- last_ptr:integer;
- callback_id:integer;
- bypass_p:boolean;
-begin
-if n=0 then
- callback_id:=input_file_callback_id[index]
-else
- callback_id:=read_file_callback_id[n];
-if callback_id>0 then begin
- last:=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;
- @<Fix up the input buffer using callbacks@>;
- end
- else
- lua_input_ln := false;
- end
- else begin
- bypass_p := bypass_eoln; {this is for -Wextra}
- lua_result := input_ln(f,bypass_p);
- if lua_result=true then begin
- lua_input_ln := true;
- @<Fix up the input buffer using callbacks@>;
- end
- else
- lua_input_ln := false;
- end
-end;
-
-@
-@<Fix up the input buffer using callbacks@>=
-if last>=first then begin
- callback_id := callback_defined(process_input_buffer_callback);
- if callback_id>0 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;
- end;
- end;
- end
-
-
-
-@ The user's terminal acts essentially like other files of text, except
-that it is used both for input and for output. When the terminal is
-considered an input file, the file variable is called |term_in|, and when it
-is considered an output file the file variable is |term_out|.
-@^system dependencies@>
-
-@<Glob...@>=
-@!term_in:alpha_file; {the terminal as an input file}
-@!term_out:alpha_file; {the terminal as an output file}
-
-@ 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}
-@d t_open_out==rewrite(term_out,'TTY:','/O') {open the terminal for text output}
-
-@ Sometimes it is necessary to synchronize the input/output mixture that
-happens on the user's terminal, and three system-dependent
-procedures are used for this
-purpose. The first of these, |update_terminal|, is called when we want
-to make sure that everything we have output to the terminal so far has
-actually left the computer's internal buffers and been sent.
-The second, |clear_terminal|, is called when we wish to cancel any
-input that the user may have typed ahead (since we are about to
-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}
-@d clear_terminal == break_in(term_in,true) {clear the terminal input buffer}
-@d wake_up_terminal == do_nothing {cancel the user's cancellation of output}
-
-@ We need a special routine to read the first line of \TeX\ input from
-the user's terminal. This line is different because it is read before we
-have opened the transcript file; there is sort of a ``chicken and
-egg'' problem here. If the user types `\.{\\input paper}' on the first
-line, or if some macro invoked by that line does such an \.{\\input},
-the transcript file will be named `\.{paper.log}'; but if no \.{\\input}
-commands are performed during the first line of terminal input, the transcript
-file will acquire its default name `\.{texput.log}'. (The transcript file
-will not contain error messages generated by the first line before the
-first \.{\\input} command.)
-@.texput@>
-
-The first line is even more special if we are lucky enough to have an operating
-system that treats \TeX\ differently from a run-of-the-mill \PASCAL\ object
-program. It's nice to let the user start running a \TeX\ job by typing
-a command line like `\.{tex paper}'; in such a case, \TeX\ will operate
-as if the first line of input were `\.{paper}', i.e., the first line will
-consist of the remainder of the command line, after the part that invoked
-\TeX.
-
-The first line is special also because it may be read before \TeX\ has
-input a format file. In such cases, normal error messages cannot yet
-be given. The following code uses concepts that will be explained later.
-(If the \PASCAL\ compiler does not support non-local |@!goto|\unskip, the
-@^system dependencies@>
-statement `|goto final_end|' should be replaced by something that
-quietly terminates the program.)
-
-@<Report overflow of the input buffer, and abort@>=
-if format_ident=0 then
- begin writeln(term_out,'Buffer size exceeded!'); goto final_end;
-@.Buffer size exceeded@>
- end
-else
- check_buffer_overflow(buf_size+10) { need a little bit more}
-
-@ Different systems have different ways to get started. But regardless of
-what conventions are adopted, the routine that initializes the terminal
-should satisfy the following specifications:
-
-\yskip\textindent{1)}It should open file |term_in| for input from the
- terminal. (The file |term_out| will already be open for output to the
- terminal.)
-
-\textindent{2)}If the user has given a command line, this line should be
- considered the first line of terminal input. Otherwise the
- user should be prompted with `\.{**}', and the first line of input
- should be whatever is typed in response.
-
-\textindent{3)}The first line of input, which might or might not be a
- command line, should appear in locations |first| to |last-1| of the
- |buffer| array.
-
-\textindent{4)}The global variable |loc| should be set so that the
- character to be read next by \TeX\ is in |buffer[loc]|. This
- character should not be blank, and we should have |loc<last|.
-
-\yskip\noindent(It may be necessary to prompt the user several times
-before a non-blank line comes in. The prompt is `\.{**}' instead of the
-later `\.*' because the meaning is slightly different: `\.{\\input}' need
-not be typed immediately after~`\.{**}'.)
-
-@d loc==cur_input.loc_field {location of first unread character in |buffer|}
-
-@ The following program does the required initialization
-without retrieving a possible command line.
-It should be clear how to modify this routine to deal with command lines,
-if the system permits them.
-@^system dependencies@>
-
-@p function init_terminal:boolean; {gets the terminal input started}
-label exit;
-begin t_open_in;
-loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal;
-@.**@>
- if not input_ln(term_in,true)
-then {this shouldn't happen}
- begin writeln(term_out);
- write(term_out,'! End of file on the terminal... why?');
-@.End of file on the terminal@>
- init_terminal:=false; return;
- end;
- loc:=first;
- while (loc<last)and(buffer[loc]=" ") do incr(loc);
- if loc<last then
- begin init_terminal:=true;
- return; {return unless the line was all blank}
- end;
- writeln(term_out,'Please type the name of your input file.');
- end;
-exit:end;
-
-@* \[4] String handling.
-Control sequence names and diagnostic messages are variable-length strings
-of eight-bit characters. Since \PASCAL\ does not have a well-developed string
-mechanism, \TeX\ does all of its string processing by homegrown methods.
-
-Elaborate facilities for dynamic strings are not needed, so all of the
-necessary operations can be handled with a simple data structure.
-The array |str_pool| contains all of the (eight-bit) ASCII codes in all
-of the strings, and the array |str_start| contains indices of the starting
-points of each string. Strings are referred to by integer numbers, so that
-string number |s| comprises the characters |str_pool[j]| for
-|str_start_macro(s)<=j<str_start_macro(s+1)|. Additional integer variables
-|pool_ptr| and |str_ptr| indicate the number of entries used so far
-in |str_pool| and |str_start|, respectively; locations
-|str_pool[pool_ptr]| and |str_start_macro(str_ptr)| are
-ready for the next string to be allocated.
-
-String numbers 0 to |biggest_char| are reserved for strings that correspond to single
-UNICODE characters. This is in accordance with the conventions of \.{WEB},
-@.WEB@>
-which converts single-character strings into the ASCII code number of the
-single character involved, while it converts other strings into integers
-and builds a string pool file. Thus, when the string constant \.{"."} appears
-in the program below, \.{WEB} converts it into the integer 46, which is the
-ASCII code for a period, while \.{WEB} will convert a string like \.{"hello"}
-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|}
-@d str_start_macro(#) == str_start[(#) - string_offset]
-
-@<Types...@>=
-@!pool_pointer = integer; {for variables that point into |str_pool|}
-@!str_number = integer; {for variables that point into |str_start|}
-@!packed_ASCII_code = 0..255; {elements of |str_pool| array}
-
-@ @<Glob...@>=
-@!str_pool:packed array[pool_pointer] of packed_ASCII_code; {the characters}
-@!str_start : array[str_number] of pool_pointer; {the starting pointers}
-@!pool_ptr : pool_pointer; {first unused position in |str_pool|}
-@!str_ptr : str_number; {number of the current string being created}
-@!init_pool_ptr : pool_pointer; {the starting value of |pool_ptr|}
-@!init_str_ptr : str_number; {the starting value of |str_ptr|}
-
-@ Several of the elementary string operations are performed using \.{WEB}
-macros instead of \PASCAL\ procedures, because many of the
-operations are done quite frequently and we want to avoid the
-overhead of procedure calls. For example, here is
-a simple macro that computes the length of a string.
-@.WEB@>
-
-@d length(#)==(str_start_macro(#+1)-str_start_macro(#)) {the number of characters
- in string number \#}
-
-@ The length of the current string is called |cur_length|:
-
-@d cur_length == (pool_ptr - str_start_macro(str_ptr))
-
-@ Strings are created by appending character codes to |str_pool|.
-The |append_char| macro, defined here, does not check to see if the
-value of |pool_ptr| has gotten too high; this test is supposed to be
-made before |append_char| is used. There is also a |flush_char|
-macro, which erases the last character appended.
-
-To test if there is room to append |l| more characters to |str_pool|,
-we shall write |str_room(l)|, which aborts \TeX\ and gives an
-apologetic error message if there isn't enough room.
-
-@d append_char(#) == {put |ASCII_code| \# at the end of |str_pool|}
-begin str_pool[pool_ptr]:=si(#); incr(pool_ptr);
-end
-@d flush_char == decr(pool_ptr) {forget the last character in the pool}
-@d str_room(#) == check_pool_overflow((pool_ptr+#)) {test or grow the pool}
-
-@p procedure string_room(t:integer);
-begin
- str_room(t);
-end;
-@#
-procedure append_pool_char(c:ASCII_code);
-begin
- append_char(c);
-end;
-
-
-@ Once a sequence of characters has been appended to |str_pool|, it
-officially becomes a string when the function |make_string| is called.
-This function returns the identification number of the new string as its
-value.
-
-@p function make_string : str_number; {current string enters the pool}
-begin if str_ptr=(max_strings+string_offset) then
- overflow("number of strings",max_strings-init_str_ptr);
-@:TeX capacity exceeded number of strings}{\quad number of strings@>
-incr(str_ptr); str_start_macro(str_ptr):=pool_ptr;
-make_string:=str_ptr-1;
-end;
-
-@ To destroy the most recently made string, we say |flush_string|.
-
-The helper routines reads one utf sequence from the pool resp. the
-buffer, and returns its character value.
-
-@d flush_string==begin decr(str_ptr); pool_ptr:=str_start_macro(str_ptr);
- end
-@d test_sequence_byte(#)==if (#<@"80) or (#>=@"C0) then begin
- print_err("Text line contains an invalid utf-8 sequence");
-@.Text line contains...@>
- help2("A funny symbol that I can't read has just been input.")@/
- ("Just continue, I'll change it to 0xFFFD.");@/
- deletions_allowed:=false; error; deletions_allowed:=true;
-{the assigment before return is needed because web2c generates incorrect code}
- a:=@"FFFD; buffer_to_unichar:=a; return; end
-
-
-@p function buffer_to_unichar(@!k:integer):integer;
-label exit;
-var a:@!integer; {a utf char}
-b:@!integer; { a utf nibble}
-begin
- b := buffer[k];
- 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);
- 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);
- end
- else if b>=@"C0 then begin
- 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");
-@.Text line contains...@>
- 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;
-exit:
- buffer_to_unichar := a;
-end ;
-
-
-
-@ The following subroutine compares string |s| with another string of the
-same length that appears in |buffer| starting at position |k|;
-the result is |true| if and only if the strings are equal.
-Empirical tests indicate that |str_eq_buf| is used in such a way that
-it tends to return |true| about 80 percent of the time.
-
-@p function str_eq_buf(@!s:str_number;@!k:integer):boolean;
- {test equality of strings}
-label not_found; {loop exit}
-var j: pool_pointer; {running index}
-a: ASCII_code; {a unicode character }
-@!result: boolean; {result of comparison}
-begin result:=false;
-if s<string_offset then begin
- a := buffer_to_unichar(k);
- if a<>s then goto not_found;
- end
-else begin
-j:=str_start_macro(s);
-while j<str_start_macro(s+1) do
- begin if so(str_pool[j])<>buffer[k] then
- begin goto not_found;
- end;
- incr(j); incr(k);
- end;
-end;
-result:=true;
-not_found: str_eq_buf:=result;
-end;
-
-@ Here is a similar routine, but it compares two strings in the string pool,
-and it does not assume that they have the same length.
-
-@p function str_eq_str(@!s,@!t:str_number):boolean;
- {test equality of strings}
-label found,not_found; {loop exit}
-var j,@!k: pool_pointer; {running indices}
-a: ASCII_code; {a utf char}
-@!result: boolean; {result of comparison}
-begin result:=false;
-a:= 0;
-if s<string_offset then begin
- if t>=string_offset then begin
- if s<=@"7F then
- if length(t)=1 then
- if str_pool[str_start_macro(t)]=s then
- goto found;
- a := pool_to_unichar(str_start_macro(t));
- if a<>s then goto not_found;
- end
- else
- if t<>s then goto not_found;
- end
-else if t<string_offset then begin
- if t<=@"7F then
- if length(s)=1 then
- if str_pool[str_start_macro(s)]=t then
- goto found;
- a := pool_to_unichar(str_start_macro(s));
- if a<>t then goto not_found;
- end
-else begin
- if length(s)<>length(t) then goto not_found;
- j:=str_start_macro(s); k:=str_start_macro(t);
- while j<str_start_macro(s+1) do
- begin if str_pool[j]<>str_pool[k] then goto not_found;
- incr(j); incr(k);
- end;
- end;
-found: result:=true;
-not_found: str_eq_str:=result;
-end;
-
-@ The initial values of |str_pool|, |str_start|, |pool_ptr|,
-and |str_ptr| are computed by the \.{INITEX} program, based in part
-on the information that \.{WEB} has output while processing \TeX.
-@.INITEX@>
-@^string pool@>
-
-The first |string_offset| strings are single-characters strings matching
-Unicode. There is no point in generating all of these. But |str_ptr| has
-initialized properly, otherwise |print_char| cannot see the difference
-between characters and strings.
-
-@p @!init function get_strings_started:boolean; {initializes the string pool,
- but returns |false| if something goes wrong}
-label done,exit;
-var @!g:str_number; {garbage}
-begin pool_ptr:=0; str_ptr:=string_offset; str_start[0]:=0;
-@<Read the other strings from the \.{TEX.POOL} file and return |true|,
- or give an error message and return |false|@>;
-exit:end;
-tini
-
-@ @d app_lc_hex(#)==l:=#;
- if l<10 then append_char(l+"0")@+else append_char(l-10+"a")
-
-@ The first 128 strings will contain 95 standard ASCII characters, and the
-other 33 characters will be printed in three-symbol form like `\.{\^\^A}'
-unless a system-dependent change is made here. Installations that have
-an extended character set, where for example |xchr[@'32]=@t\.{\'^^Z\'}@>|,
-would like string @'32 to be the single character @'32 instead of the
-three characters @'136, @'136, @'132 (\.{\^\^Z}). On the other hand,
-even people with an extended character set will want to represent string
-@'15 by \.{\^\^M}, since @'15 is |carriage_return|; the idea is to
-produce visible strings instead of tabs or line-feeds or carriage-returns
-or bell-rings or characters that are treated anomalously in text files.
-
-Unprintable characters of codes 128--255 are, similarly, rendered
-\.{\^\^80}--\.{\^\^ff}.
-
-Unprintable characters of codes 256--|65535| are, similarly, rendered
-\.{\^\^\^\^0100}--\.{\^\^\^\^ffff}.
-
-The boolean expression defined here should be |true| unless \TeX\
-internal code number~|k| corresponds to a non-troublesome visible
-symbol in the local character set. An appropriate formula for the
-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, @'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@>
-
-@ @<Read the other strings...@>=
- g := loadpoolstrings((pool_size-string_vacancies));
- if g=0 then begin
- wake_up_terminal; writeln(term_out,'! You have to increase POOLSIZE.');
- get_strings_started:=false;
- return;
- end;
- get_strings_started:=true;
-
-@* \[5] On-line and off-line printing.
-Messages that are sent to a user's terminal and to the transcript-log file
-are produced by several `|print|' procedures. These procedures will
-direct their output to a variety of places, based on the setting of
-the global variable |selector|, which has the following possible
-values:
-
-\yskip
-\hang |term_and_log|, the normal setting, prints on the terminal and on the
- transcript file.
-
-\hang |log_only|, prints only on the transcript file.
-
-\hang |term_only|, prints only on the terminal.
-
-\hang |no_print|, doesn't print at all. This is used only in rare cases
- before the transcript file is open.
-
-\hang |pseudo|, puts output into a cyclic buffer that is used
- by the |show_context| routine; when we get to that routine we shall discuss
- the reasoning behind this curious mode.
-
-\hang |new_string|, appends the output to the current string in the
- string pool.
-
-\hang 0 to 15, prints on one of the sixteen files for \.{\\write} output.
-
-\yskip
-\noindent The symbolic names `|term_and_log|', etc., have been assigned
-numeric codes that satisfy the convenient relations |no_print+1=term_only|,
-|no_print+2=log_only|, |term_only+2=log_only+1=term_and_log|.
-
-Three additional global variables, |tally| and |term_offset| and
-|file_offset|, record the number of characters that have been printed
-since they were most recently cleared to zero. We use |tally| to record
-the length of (possibly very long) stretches of printing; |term_offset|
-and |file_offset|, on the other hand, keep track of how many characters
-have appeared so far on the current line that has been output to the
-terminal or to the transcript file, respectively.
-
-@d no_print=16 {|selector| setting that makes data disappear}
-@d term_only=17 {printing is destined for the terminal only}
-@d log_only=18 {printing is destined for the transcript file only}
-@d term_and_log=19 {normal |selector| setting}
-@d pseudo=20 {special |selector| setting for |show_context|}
-@d new_string=21 {printing is deflected to the string pool}
-@d max_selector=21 {highest selector setting}
-
-@<Glob...@>=
-@!log_file : alpha_file; {transcript of \TeX\ session}
-@!term_out_mode:halfword;
-@!term_out_translation:halfword;
-@!selector : 0..max_selector; {where to print a message}
-@!dig : array[0..22] of 0..15; {digits in a number being output}
-@!tally : integer; {the number of characters recently printed}
-@!term_offset : 0..max_print_line;
- {the number of characters on the current terminal line}
-@!file_offset : 0..max_print_line;
- {the number of characters on the current file line}
-@!trick_buf:array[0..error_line] of packed_ASCII_code; {circular buffer for
- pseudoprinting}
-@!trick_count: integer; {threshold for pseudoprinting, explained later}
-@!first_count: integer; {another variable for pseudoprinting}
-@!inhibit_par_tokens:boolean; { for minor adjustments to |show_token_list| }
-
-@ @<Initialize the output routines@>=
-selector:=term_only; tally:=0; term_offset:=0; file_offset:=0;
-inhibit_par_tokens:=false;
-
-@ Macro abbreviations for output to the terminal and to the log file are
-defined here for convenience. Some systems need special conventions
-for terminal output, and it is possible to adhere to those conventions
-by changing |wterm|, |wterm_ln|, and |wterm_cr| in this section.
-@^system dependencies@>
-
-@d wterm(#)==write(term_out,#)
-@d wterm_ln(#)==writeln(term_out,#)
-@d wterm_cr==writeln(term_out)
-@d wlog(#)==write(log_file,#)
-@d wlog_ln(#)==writeln(log_file,#)
-@d wlog_cr==writeln(log_file)
-
-@ To end a line of text output, we call |print_ln|.
-
-@<Basic print...@>=
-procedure print_ln; {prints an end-of-line}
-begin case selector of
-term_and_log: begin wterm_cr; wlog_cr;
- term_offset:=0; file_offset:=0;
- end;
-log_only: begin wlog_cr; file_offset:=0;
- end;
-term_only: begin wterm_cr; term_offset:=0;
- end;
-no_print,pseudo,new_string: do_nothing;
-othercases writeln(write_file[selector])
-endcases;@/
-end; {|tally| is not affected}
-
-@ The |print_char| procedure sends one character to the desired destination,
-using the |xchr| array to map it into an external character compatible with
-|lua_input_ln|. All printing comes through |print_ln| or |print_char|.
-
-@d wterm_char(#)==begin if (#>=@"20)or(#=@"0A)or(#=@"0D)or(#=@"09) then wterm(xchr[#])
- else begin if term_offset+2>=max_print_line then begin
- wterm_cr; term_offset:=0;
- end;
- incr(term_offset); wterm('^'); incr(term_offset); wterm('^');
- wterm(xchr[#+64]);
- end; end
-@d fix_term_offset(#)==
- if ((#>=@"C0) and (#<=@"DF) and (term_offset+2>=max_print_line)) or
- ((#>=@"E0) and (#<=@"EF) and (term_offset+3>=max_print_line)) or
- ((#>=@"F0) and (term_offset+4>=max_print_line)) then begin
- wterm_cr; term_offset:=0;
- end
-@d fix_log_offset(#)==
- if ((#>=@"C0) and (#<=@"DF) and (file_offset+2>=max_print_line)) or
- ((#>=@"E0) and (#<=@"EF) and (file_offset+3>=max_print_line)) or
- ((#>=@"F0) and (file_offset+4>=max_print_line)) then begin
- wlog_cr; file_offset:=0;
- end
-
-@<Basic print...@>=
-procedure print_char(@!s:ASCII_code); {prints a single character}
-label exit;
-begin if @<Character |s| is the current new-line character@> then
- if selector<pseudo then
- begin print_ln; return;
- end;
-case selector of
-term_and_log: begin
- fix_term_offset(s); fix_log_offset(s);
- wterm_char(s); wlog(xchr[s]);
- incr(term_offset); incr(file_offset);
- if term_offset=max_print_line then
- begin wterm_cr; term_offset:=0;
- end;
- if file_offset=max_print_line then
- begin wlog_cr; file_offset:=0;
- end;
- end;
-log_only: begin
- fix_log_offset(s);
- wlog(xchr[s]); incr(file_offset);
- if file_offset=max_print_line then print_ln;
- end;
-term_only: begin
- fix_term_offset(s);
- wterm_char(s); incr(term_offset);
- if term_offset=max_print_line then print_ln;
- end;
-no_print: do_nothing;
-pseudo: if tally<trick_count then trick_buf[tally mod error_line]:=s;
-new_string: begin if pool_ptr<pool_size then append_char(s);
- end; {we drop characters if the string space is full}
-othercases write(write_file[selector],xchr[s])
-endcases;@/
-incr(tally);
-exit:end;
-
-@ An entire string is output by calling |print|. Note that if we are outputting
-the single standard ASCII character \.c, we could call |print("c")|, since
-|"c"=99| is the number of a single-character string, as explained above. But
-|print_char("c")| is quicker, so \TeX\ goes directly to the |print_char|
-routine when it knows that this is safe. (The present implementation
-assumes that it is always safe to print a visible ASCII character.)
-@^system dependencies@>
-
-The first 256 entries above the 17th unicode plane are used for a
-special trick: when \TeX\ has to print items in that range, it will
-instead print the character that results from substracting @"110000
-from that value. This allows byte-oriented output to things like
-\.{\\specials} and \.{\\pdfliterals}. Todo: Perhaps it would be useful
-to do the same substraction while typesetting.
-
-@d print_lc_hex(#)==l:=#;
- if l<10 then print_char(l+"0") else print_char(l-10+"a");
-
-@<Basic print...@>=
-function pool_to_unichar(@!t:pool_pointer):ASCII_code;
-var a,result:@!ASCII_code; {a utf char}
-b:@!quarterword; { a utf nibble}
-begin
- b := str_pool[t];
- 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);
- 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);
- end
- else if b>=@"C0 then begin
- 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');
-@.Text line contains...@>
- 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;
-result := a;
-pool_to_unichar := result;
-end ;
-
-procedure print(@!s:integer); {prints string |s|}
-label exit;
-var j:pool_pointer; {current character code position}
-@!v:integer; { a unicode char }
-begin if s>=str_ptr then s:="???" {this can't happen}
-@.???@>
-else if s<string_offset then begin
- if s<0 then s:="???" {can't happen}
- else begin
- {TH not sure about this, disabled for now!}
- if (false)and(selector>pseudo) then
- begin print_char(s); return; {internal strings are not expanded}
- end;
- if (@<Character |s| is the current new-line character@>) then
- if selector<pseudo then
- begin print_ln; return;
- end;
- if s<=@"7F then
- print_char(s)
- else if s<=@"7FF then begin
- print_char(@"C0 + (s div @"40));
- print_char(@"80 + (s mod @"40));
- end
- else if s<=@"FFFF then begin
- print_char(@"E0 + (s div @"1000));
- print_char(@"80 + ((s mod @"1000) div @"40));
- print_char(@"80 + ((s mod @"1000) mod @"40));
- end
- else begin
- if s>=@"110000 then
- print_char(s-@"110000)
- else begin
- print_char(@"F0 + (s div @"40000));
- print_char(@"80 + ((s mod @"40000) div @"1000));
- print_char(@"80 + (((s mod @"40000) mod @"1000) div @"40));
- print_char(@"80 + (((s mod @"40000) mod @"1000) mod @"40));
- end;
- end;
- return;
- end;
- end;
-j:=str_start_macro(s);
-while j<str_start_macro(s+1) do
- begin { 0x110000 in utf=8: 0xF4 0x90 0x80 0x80 }
- if (str_pool[j]=@"F4)and(j<str_start_macro(s+4))and(str_pool[j+1]=@"90) then begin
- v := (((7*64+63)*64)+ (str_pool[j+2]-128))*64 +(str_pool[j+3]-128);
- print_char(v-@"110000); j := j+4;
- end
- else begin
- print_char(str_pool[j]); incr(j);
- end;
- end;
-exit:end;
-
-procedure print_nl(@!s:str_number); {prints string |s| at beginning of line}
-begin if ((term_offset>0)and(odd(selector)))or@|
- ((file_offset>0)and(selector>=log_only)) then print_ln;
-print(s);
-end;
-
-procedure print_nlp; {move to beginning of a line}
-begin if ((term_offset>0)and(odd(selector)))or@|
- ((file_offset>0)and(selector>=log_only)) then print_ln;
-end;
-
-@ |slow_print| is the same as |print| nowadays, but the name is kept for now.
-
-@<Basic print...@>=
-procedure slow_print(@!s:integer); {prints string |s|}
-begin print(s);
-end;
-
-@ Here is the very first thing that \TeX\ prints: a headline that identifies
-the version number and format package. The |term_offset| variable is temporarily
-incorrect, but the discrepancy is not serious since we assume that the banner
-and format identifier together will occupy at most |max_print_line|
-character positions.
-
-@<Initialize the output...@>=
-print_banner;
-
-@ The procedure |print_nl| is like |print|, but it makes sure that the
-string appears at the beginning of a new line. (moved)
-
-@<Basic print...@>=
-
-@ The procedure |print_esc| prints a string that is preceded by
-the user's escape character (which is usually a backslash).
-
-@<Basic print...@>=
-procedure print_esc(@!s:str_number); {prints escape character, then |s|}
-var c:integer; {the escape character code}
-begin @<Set variable |c| to the current escape character@>;
-if c>=0 then if c<string_offset then print(c);
-slow_print(s);
-end;
-
-@ An array of digits in the range |0..15| is printed by |print_the_digs|.
-
-@<Basic print...@>=
-procedure print_the_digs(@!k:eight_bits);
- {prints |dig[k-1]|$\,\ldots\,$|dig[0]|}
-begin while k>0 do
- begin decr(k);
- if dig[k]<10 then print_char("0"+dig[k])
- else print_char("A"-10+dig[k]);
- end;
-end;
-
-@ The following procedure, which prints out the decimal representation of a
-given integer |n|, has been written carefully so that it works properly
-if |n=0| or if |(-n)| would cause overflow. It does not apply |mod| or |div|
-to negative arguments, since such operations are not implemented consistently
-by all \PASCAL\ compilers.
-
-@<Basic print...@>=
-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:longinteger; {used to negate |n| in possibly dangerous cases}
-begin k:=0;
-if n<0 then
- begin print_char("-");
- if n>-100000000 then negate(n)
- else begin m:=-1-n; n:=m div 10; m:=(m mod 10)+1; k:=1;
- if m<10 then dig[0]:=m
- else begin dig[0]:=0; incr(n);
- end;
- end;
- end;
-repeat dig[k]:=n mod 10; n:=n div 10; incr(k);
-until n=0;
-print_the_digs(k);
-end;
-
-@ Here is a trivial procedure to print two digits; it is usually called with
-a parameter in the range |0<=n<=99|.
-
-@p procedure print_two(@!n:integer); {prints two least significant digits}
-begin n:=abs(n) mod 100; print_char("0"+(n div 10));
-print_char("0"+(n mod 10));
-end;
-
-@ Hexadecimal printing of nonnegative integers is accomplished by |print_hex|.
-
-@p procedure print_hex(@!n:integer);
- {prints a positive integer in hexadecimal form}
-var k:0..22; {index to current digit; we assume that $0\L n<16^{22}$}
-begin k:=0; print_char("""");
-repeat dig[k]:=n mod 16; n:=n div 16; incr(k);
-until n=0;
-print_the_digs(k);
-end;
-
-@ Old versions of \TeX\ needed a procedure called |print_ASCII| whose function
-is now subsumed by |print|. We retain the old name here as a possible aid to
-future software arch\ae ologists.
-
-@d print_ASCII == print
-@d print_font_name(#)==begin print(tex_font_name(#)); flush_string; end
-
-@ Roman numerals are produced by the |print_roman_int| routine. Readers
-who like puzzles might enjoy trying to figure out how this tricky code
-works; therefore no explanation will be given. Notice that 1990 yields
-\.{mcmxc}, not \.{mxm}.
-
-@p procedure print_roman_int(@!n:integer);
-label exit;
-var j,@!k: pool_pointer; {mysterious indices into |str_pool|}
-@!u,@!v: nonnegative_integer; {mysterious numbers}
-begin j:=str_start_macro("m2d5c2l5x2v5i"); v:=1000;
-loop@+ begin while n>=v do
- begin print_char(so(str_pool[j])); n:=n-v;
- end;
- if n<=0 then return; {nonpositive input produces no output}
- k:=j+2; u:=v div (so(str_pool[k-1])-"0");
- if str_pool[k-1]=si("2") then
- begin k:=k+2; u:=u div (so(str_pool[k-1])-"0");
- end;
- if n+u>=v then
- begin print_char(so(str_pool[k])); n:=n+u;
- end
- else begin j:=j+2; v:=v div (so(str_pool[j-1])-"0");
- end;
- end;
-exit:end;
-
-@ The |print| subroutine will not print a string that is still being
-created. The following procedure will.
-
-@p procedure print_current_string; {prints a yet-unmade string}
-var j:pool_pointer; {points to current character code}
-begin j:=str_start_macro(str_ptr);
-while j<pool_ptr do
- begin print_char(so(str_pool[j])); incr(j);
- end;
-end;
-
-@ Here is a procedure that asks the user to type a line of input,
-assuming that the |selector| setting is either |term_only| or |term_and_log|.
-The input is placed into locations |first| through |last-1| of the
-|buffer| array, and echoed on the transcript file if appropriate.
-
-This procedure is never called when |interaction<scroll_mode|.
-
-@<Basic print...@>=
-procedure prompt_input(s:str_number);
-begin wake_up_terminal; print(s); term_input;
-end;
-
-@
-@p procedure term_input; {gets a line from the terminal}
-var k:0..buf_size; {index into |buffer|}
-begin update_terminal; {now the user sees the prompt for sure}
-if not input_ln(term_in,true)
-then fatal_error("End of file on the terminal!");
-@.End of file on the terminal@>
-term_offset:=0; {the user's line ended with \<\rm return>}
-decr(selector); {prepare to echo the input}
-if last<>first then for k:=first to last-1 do print(buffer[k]);
-print_ln; incr(selector); {restore previous status}
-end;
-
-@* \[6] Reporting errors.
-When something anomalous is detected, \TeX\ typically does something like this:
-$$\vbox{\halign{#\hfil\cr
-|print_err("Something anomalous has been detected");|\cr
-|help3("This is the first line of my offer to help.")|\cr
-|("This is the second line. I'm trying to")|\cr
-|("explain the best way for you to proceed.");|\cr
-|error;|\cr}}$$
-A two-line help message would be given using |help2|, etc.; these informal
-helps should use simple vocabulary that complements the words used in the
-official error message that was printed. (Outside the U.S.A., the help
-messages should preferably be translated into the local vernacular. Each
-line of help is at most 60 characters long, in the present implementation,
-so that |max_print_line| will not be exceeded.)
-
-The |print_err| procedure supplies a `\.!' before the official message,
-and makes sure that the terminal is awake if a stop is going to occur.
-The |error| procedure supplies a `\..' after the official message, then it
-shows the location of the error; and if |interaction=error_stop_mode|,
-it also enters into a dialog with the user, during which time the help
-message may be printed.
-@^system dependencies@>
-
-@ The global variable |interaction| has four settings, representing increasing
-amounts of user interaction:
-
-@d batch_mode=0 {omits all stops and omits terminal output}
-@d nonstop_mode=1 {omits all stops}
-@d scroll_mode=2 {omits error stops}
-@d error_stop_mode=3 {stops at every opportunity to interact}
-@d print_err(#)==begin if interaction=error_stop_mode then wake_up_terminal;
- print_nl("! "); print(#);
- last_error:=#; end
-@d print_warn(#)==begin if interaction=error_stop_mode then wake_up_terminal;
- if prepend_nl then begin print_nl(""); print_ln end;
- print_nl(#);
- end
-
-@<Glob...@>=
-@!interaction:batch_mode..error_stop_mode; {current level of interaction}
-@!last_error:str_number;
-
-@ @<Set init...@>=interaction:=error_stop_mode;
-
-@ \TeX\ is careful not to call |error| when the print |selector| setting
-might be unusual. The only possible values of |selector| at the time of
-error messages are
-
-\yskip\hang|no_print| (when |interaction=batch_mode|
- and |log_file| not yet open);
-
-\hang|term_only| (when |interaction>batch_mode| and |log_file| not yet open);
-
-\hang|log_only| (when |interaction=batch_mode| and |log_file| is open);
-
-\hang|term_and_log| (when |interaction>batch_mode| and |log_file| is open).
-
-@<Initialize the print |selector| based on |interaction|@>=
-if interaction=batch_mode then selector:=no_print@+else selector:=term_only
-
-@ A global variable |deletions_allowed| is set |false| if the |get_next|
-routine is active when |error| is called; this ensures that |get_next|
-and related routines like |get_token| will never be called recursively.
-A similar interlock is provided by |set_box_allowed|.
-@^recursion@>
-
-The global variable |history| records the worst level of error that
-has been detected. It has four possible values: |spotless|, |warning_issued|,
-|error_message_issued|, and |fatal_error_stop|.
-
-Another global variable, |error_count|, is increased by one when an
-|error| occurs without an interactive dialog, and it is reset to zero at
-the end of every paragraph. If |error_count| reaches 100, \TeX\ decides
-that there is no point in continuing further.
-
-@d spotless=0 {|history| value when nothing has been amiss yet}
-@d warning_issued=1 {|history| value when |begin_diagnostic| has been called}
-@d error_message_issued=2 {|history| value when |error| has been called}
-@d fatal_error_stop=3 {|history| value when termination was premature}
-
-@<Glob...@>=
-@!deletions_allowed:boolean; {is it safe for |error| to call |get_token|?}
-@!set_box_allowed:boolean; {is it safe to do a \.{\\setbox} assignment?}
-@!history:spotless..fatal_error_stop; {has the source input been clean so far?}
-@!error_count:-1..100; {the number of scrolled errors since the
- last paragraph ended}
-
-@ The value of |history| is initially |fatal_error_stop|, but it will
-be changed to |spotless| if \TeX\ survives the initialization process.
-
-@<Set init...@>=
-deletions_allowed:=true; set_box_allowed:=true;
-error_count:=0; {|history| is initialized elsewhere}
-
-@ Since errors can be detected almost anywhere in \TeX, we want to declare the
-error procedures near the beginning of the program. But the error procedures
-in turn use some other procedures, which need to be declared |forward|
-before we get to |error| itself.
-
-It is possible for |error| to be called recursively if some error arises
-when |get_token| is being used to delete a token, and/or if some fatal error
-occurs while \TeX\ is trying to fix a non-fatal one. But such recursion
-@^recursion@>
-is never more than two levels deep.
-
-@<Error handling...@>=
-procedure@?normalize_selector; forward;@t\2@>@/
-procedure@?get_token; forward;@t\2@>@/
-procedure@?term_input; forward;@t\2@>@/
-procedure@?show_context; forward;@t\2@>@/
-procedure@?begin_file_reading; forward;@t\2@>@/
-procedure@?open_log_file; forward;@t\2@>@/
-procedure@?close_files_and_terminate; forward;@t\2@>@/
-procedure@?clear_for_error_prompt; forward;@t\2@>@/
-procedure@?give_err_help; forward;@t\2@>@/
-@t\4\hskip-\fontdimen2\font@>@;@+@!debug@+procedure@?debug_help;
- forward;@;@+gubed
-
-@ Individual lines of help are recorded in the array |help_line|, which
-contains entries in positions |0..(help_ptr-1)|. They should be printed
-in reverse order, i.e., with |help_line[0]| appearing last.
-
-@d hlp1(#)==help_line[0]:=#;@+end
-@d hlp2(#)==help_line[1]:=#; hlp1
-@d hlp3(#)==help_line[2]:=#; hlp2
-@d hlp4(#)==help_line[3]:=#; hlp3
-@d hlp5(#)==help_line[4]:=#; hlp4
-@d hlp6(#)==help_line[5]:=#; hlp5
-@d help0==help_ptr:=0 {sometimes there might be no help}
-@d help1==@+begin help_ptr:=1; hlp1 {use this with one help line}
-@d help2==@+begin help_ptr:=2; hlp2 {use this with two help lines}
-@d help3==@+begin help_ptr:=3; hlp3 {use this with three help lines}
-@d help4==@+begin help_ptr:=4; hlp4 {use this with four help lines}
-@d help5==@+begin help_ptr:=5; hlp5 {use this with five help lines}
-@d help6==@+begin help_ptr:=6; hlp6 {use this with six help lines}
-
-@p
-procedure dohelp5 (@!a,b,c,d,e:str_number);
-begin
- help5(a)(b)(c)(d)(e);
-end;
-@#
-procedure dohelp4 (@!a,b,c,d:str_number);
-begin
- help4(a)(b)(c)(d);
-end;
-@#
-procedure dohelp3 (@!a,b,c:str_number);
-begin
- help3(a)(b)(c);
-end;
-@#
-procedure dohelp2 (@!a,b:str_number);
-begin
- help2(a)(b);
-end;
-@#
-procedure dohelp1 (@!a:str_number);
-begin
- help1(a);
-end;
-@#
-procedure dohelp0;
-begin
- help0;
-end;
-@#
-procedure do_print_err (s:str_number);
-begin
- print_err(s);
-end;
-
-@ @<Glob...@>=
-@!help_line:array[0..5] of str_number; {helps for the next |error|}
-@!help_ptr:0..6; {the number of help lines present}
-@!use_err_help:boolean; {should the |err_help| list be shown?}
-
-@ @<Set init...@>=
-help_ptr:=0; use_err_help:=false;
-
-@ The |jump_out| procedure just cuts across all active procedure levels and
-goes to |end_of_TEX|. This is the only nontrivial |@!goto| statement in the
-whole program. It is used when there is no recovery from a particular error.
-
-Some \PASCAL\ compilers do not implement non-local |goto| statements.
-@^system dependencies@>
-In such cases the body of |jump_out| should simply be
-`|close_files_and_terminate|;\thinspace' followed by a call on some system
-procedure that quietly terminates the program.
-
-@<Error hand...@>=
-procedure jump_out;
-begin goto end_of_TEX;
-end;
-
-@ Here now is the general |error| routine.
-
-@<Error hand...@>=
-procedure error; {completes the job of error reporting}
-label continue,exit;
-var c:ASCII_code; {what the user types}
-callback_id:integer;
-@!s1,@!s2,@!s3,@!s4:integer;
- {used to save global variables when deleting tokens}
-@!t:boolean;
-begin if history<error_message_issued then history:=error_message_issued;
-print_char(".");
-callback_id := callback_defined(show_error_hook_callback) ;
-if callback_id>0 then t := run_callback(callback_id,'->');
-show_context;
-if interaction=error_stop_mode then @<Get user's advice and |return|@>;
-incr(error_count);
-if error_count=100 then
- begin print_nl("(That makes 100 errors; please try again.)");
-@.That makes 100 errors...@>
- history:=fatal_error_stop; jump_out;
- end;
-@<Put help message on the transcript file@>;
-exit:end;
-
-@ @<Get user's advice...@>=
-loop@+begin continue: clear_for_error_prompt; prompt_input("? ");
-@.?\relax@>
- if last=first then return;
- c:=buffer[first];
- if c>="a" then c:=c+"A"-"a"; {convert to uppercase}
- @<Interpret code |c| and |return| if done@>;
- end
-
-@ It is desirable to provide an `\.E' option here that gives the user
-an easy way to return from \TeX\ to the system editor, with the offending
-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@>
-
-@<Interpret code |c| and |return| if done@>=
-case c of
-"0","1","2","3","4","5","6","7","8","9": if deletions_allowed then
- @<Delete \(c)|c-"0"| tokens and |goto continue|@>;
-@t\4\4@>@;@+@!debug "D": begin debug_help; goto continue;@+end;@+gubed@/
-"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;
- end;
-"H": @<Print the help information and |goto continue|@>;
-"I":@<Introduce new material from the terminal and |return|@>;
-"Q","R","S":@<Change the interaction level and |return|@>;
-"X":begin interaction:=scroll_mode; jump_out;
- end;
-othercases do_nothing
-endcases;@/
-@<Print the menu of available options@>
-
-@ @<Print the menu...@>=
-begin print("Type <return> to proceed, S to scroll future error messages,");@/
-@.Type <return> to proceed...@>
-print_nl("R to run without stopping, Q to run quietly,");@/
-print_nl("I to insert something, ");
-if base_ptr>0 then print("E to edit your file,");
-if deletions_allowed then
- print_nl("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
-print_nl("H for help, X to quit.");
-end
-
-@ Here the author of \TeX\ apologizes for making use of the numerical
-relation between |"Q"|, |"R"|, |"S"|, and the desired interaction settings
-|batch_mode|, |nonstop_mode|, |scroll_mode|.
-@^Knuth, Donald Ervin@>
-
-@<Change the interaction...@>=
-begin error_count:=0; interaction:=batch_mode+c-"Q";
-print("OK, entering ");
-case c of
-"Q":begin print_esc("batchmode"); decr(selector);
- end;
-"R":print_esc("nonstopmode");
-"S":print_esc("scrollmode");
-end; {there are no other cases}
-print("..."); print_ln; update_terminal; return;
-end
-
-@ When the following code is executed, |buffer[(first+1)..(last-1)]| may
-contain the material inserted by the user; otherwise another prompt will
-be given. In order to understand this part of the program fully, you need
-to be familiar with \TeX's input stacks.
-
-@<Introduce new material...@>=
-begin begin_file_reading; {enter a new syntactic level for terminal input}
-{now |state=mid_line|, so an initial blank space will count as a blank}
-if last>first+1 then
- begin loc:=first+1; buffer[first]:=" ";
- end
-else begin prompt_input("insert>"); loc:=first;
-@.insert>@>
- end;
-first:=last;
-cur_input.limit_field:=last-1; {no |end_line_char| ends this line}
-return;
-end
-
-@ We allow deletion of up to 99 tokens at a time.
-
-@<Delete \(c)|c-"0"| tokens...@>=
-begin s1:=cur_tok; s2:=cur_cmd; s3:=cur_chr; s4:=align_state;
-align_state:=1000000; OK_to_interrupt:=false;
-if (last>first+1) and (buffer[first+1]>="0")and(buffer[first+1]<="9") then
- c:=c*10+buffer[first+1]-"0"*11
-else c:=c-"0";
-while c>0 do
- begin get_token; {one-level recursive call of |error| is possible}
- decr(c);
- end;
-cur_tok:=s1; cur_cmd:=s2; cur_chr:=s3; align_state:=s4; OK_to_interrupt:=true;
-help2("I have just deleted some text, as you asked.")@/
-("You can now delete more, or insert, or whatever.");
-show_context; goto continue;
-end
-
-@ @<Print the help info...@>=
-begin if use_err_help then
- begin give_err_help; use_err_help:=false;
- end
-else begin if help_ptr=0 then
- help2("Sorry, I don't know how to help in this situation.")@/
- @t\kern1em@>("Maybe you should try asking a human?");
- repeat decr(help_ptr); print(help_line[help_ptr]); print_ln;
- until help_ptr=0;
- end;
-help4("Sorry, I already gave what help I could...")@/
- ("Maybe you should try asking a human?")@/
- ("An error might have occurred before I noticed any problems.")@/
- ("``If all else fails, read the instructions.''");@/
-goto continue;
-end
-
-@ @<Put help message on the transcript file@>=
-if interaction>batch_mode then decr(selector); {avoid terminal output}
-if use_err_help then
- begin print_ln; give_err_help;
- end
-else while help_ptr>0 do
- begin decr(help_ptr); print_nl(help_line[help_ptr]);
- end;
-print_ln;
-if interaction>batch_mode then incr(selector); {re-enable terminal output}
-print_ln
-
-@ A dozen or so error messages end with a parenthesized integer, so we
-save a teeny bit of program space by declaring the following procedure:
-
-@p procedure int_error(@!n:integer);
-begin print(" ("); print_int(n); print_char(")"); error;
-end;
-
-@ In anomalous cases, the print selector might be in an unknown state;
-the following subroutine is called to fix things just enough to keep
-running a bit longer.
-
-@p procedure normalize_selector;
-begin if log_opened then selector:=term_and_log
-else selector:=term_only;
-if job_name=0 then open_log_file;
-if interaction=batch_mode then decr(selector);
-end;
-
-@ The following procedure prints \TeX's last words before dying.
-
-@d succumb==begin if interaction=error_stop_mode then
- interaction:=scroll_mode; {no more interaction}
- if log_opened then error;
- @!debug if interaction>batch_mode then debug_help;@+gubed@;@/
- history:=fatal_error_stop; jump_out; {irrecoverable error}
- end
-
-@<Error hand...@>=
-procedure fatal_error(@!s:str_number); {prints |s|, and that's it}
-begin normalize_selector;@/
-print_err("Emergency stop"); help1(s); succumb;
-@.Emergency stop@>
-end;
-
-@ Here is the most dreaded error message.
-
-@<Error hand...@>=
-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 new_line_char:=10; normalize_selector;
-print_err("LuaTeX fatal error "); print(s);
-succumb;
-end;
-
-procedure overflow(@!s:str_number;@!n:integer); {stop due to finiteness}
-begin normalize_selector;
-print_err("TeX capacity exceeded, sorry [");
-@.TeX capacity exceeded ...@>
-print(s); print_char("="); print_int(n); print_char("]");
-help2("If you really absolutely need more capacity,")@/
- ("you can ask a wizard to enlarge me.");
-succumb;
-end;
-
-procedure overflow_ocp_buf_size;
-begin
-overflow("ocp_buf_size",ocp_buf_size);
-end;
-
-procedure overflow_ocp_stack_size;
-begin
-overflow("ocp_stack_size",ocp_stack_size);
-end;
-
-
-@ The program might sometime run completely amok, at which point there is
-no choice but to stop. If no previous error has been detected, that's bad
-news; a message is printed that is really intended for the \TeX\
-maintenance person instead of the user (unless the user has been
-particularly diabolical). The index entries for `this can't happen' may
-help to pinpoint the problem.
-@^dry rot@>
-
-@<Error hand...@>=
-procedure confusion(@!s:str_number);
- {consistency check violated; |s| tells where}
-begin normalize_selector;
-if history<error_message_issued then
- begin print_err("This can't happen ("); print(s); print_char(")");
-@.This can't happen@>
- help1("I'm broken. Please show this to someone who can fix can fix");
- end
-else begin print_err("I can't go on meeting you like this");
-@.I can't go on...@>
- help2("One of your faux pas seems to have wounded me deeply...")@/
- ("in fact, I'm barely conscious. Please fix it and try again.");
- end;
-succumb;
-end;
-
-@ Users occasionally want to interrupt \TeX\ while it's running.
-If the \PASCAL\ runtime system allows this, one can implement
-a routine that sets the global variable |interrupt| to some nonzero value
-when such an interrupt is signalled. Otherwise there is probably at least
-a way to make |interrupt| nonzero using the \PASCAL\ debugger.
-@^system dependencies@>
-@^debugging@>
-
-@<Global...@>=
-@!interrupt:integer; {should \TeX\ pause for instructions?}
-@!OK_to_interrupt:boolean; {should interrupts be observed?}
-@!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
-if interrupt<>0 then pause_for_instructions;
-end;
-
-
-@ @<Set init...@>=
-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
-the |error| routine. \TeX\ checks for interrupts only at times when it is
-safe to do this.
-
-@p procedure pause_for_instructions;
-begin if OK_to_interrupt then
- begin interaction:=error_stop_mode;
- if (selector=log_only)or(selector=no_print) then
- incr(selector);
- print_err("Interruption");
-@.Interruption@>
- help3("You rang?")@/
- ("Try to insert some instructions for me (e.g.,`I\showlists'),")@/
- ("unless you just want to quit by typing `X'.");
- deletions_allowed:=false; error; deletions_allowed:=true;
- interrupt:=0;
- end;
-end;
-
-@* \[7] Arithmetic with scaled dimensions.
-The principal computations performed by \TeX\ are done entirely in terms of
-integers less than $2^{31}$ in magnitude; and divisions are done only when both
-dividend and divisor are nonnegative. Thus, the arithmetic specified in this
-program can be carried out in exactly the same way on a wide variety of
-computers, including some small ones. Why? Because the arithmetic
-calculations need to be spelled out precisely in order to guarantee that
-\TeX\ will produce identical output on different machines. If some
-quantities were rounded differently in different implementations, we would
-find that line breaks and even page breaks might occur in different places.
-Hence the arithmetic of \TeX\ has been designed with care, and systems that
-claim to be implementations of \TeX82 should follow precisely the
-@:TeX82}{\TeX82@>
-calculations as they appear in the present program.
-
-(Actually there are three places where \TeX\ uses |div| with a possibly negative
-numerator. These are harmless; see |div| in the index. Also if the user
-sets the \.{\\time} or the \.{\\year} to a negative value, some diagnostic
-information will involve negative-numerator division. The same remarks
-apply for |mod| as well as for |div|.)
-
-@ Here is a routine that calculates half of an integer, using an
-unambiguous convention with respect to signed odd numbers.
-
-@p function half(@!x:integer):integer;
-begin if odd(x) then half:=(x+1) div 2
-else half:=x @!div 2;
-end;
-
-@ Fixed-point arithmetic is done on {\sl scaled integers\/} that are multiples
-of $2^{-16}$. In other words, a binary point is assumed to be sixteen bit
-positions from the right end of a binary computer word.
-
-@d unity == @'200000 {$2^{16}$, represents 1.00000}
-@d two == @'400000 {$2^{17}$, represents 2.00000}
-
-@<Types...@>=
-@!scaled = integer; {this type is used for scaled integers}
-@!nonnegative_integer=0..@'17777777777; {$0\L x<2^{31}$}
-@!small_number=0..63; {this type is self-explanatory}
-
-@ The following function is used to create a scaled integer from a given decimal
-fraction $(.d_0d_1\ldots d_{k-1})$, where |0<=k<=17|. The digit $d_i$ is
-given in |dig[i]|, and the calculation produces a correctly rounded result.
-
-@p function round_decimals(@!k:small_number) : scaled;
- {converts a decimal fraction}
-var a:integer; {the accumulator}
-begin a:=0;
-while k>0 do
- begin decr(k); a:=(a+dig[k]*two) div 10;
- end;
-round_decimals:=(a+1) div 2;
-end;
-
-@ Conversely, here is a procedure analogous to |print_int|. If the output
-of this procedure is subsequently read by \TeX\ and converted by the
-|round_decimals| routine above, it turns out that the original value will
-be reproduced exactly; the ``simplest'' such decimal number is output,
-but there is always at least one digit following the decimal point.
-
-The invariant relation in the \&{repeat} loop is that a sequence of
-decimal digits yet to be printed will yield the original number if and only if
-they form a fraction~$f$ in the range $s-\delta\L10\cdot2^{16}f<s$.
-We can stop if and only if $f=0$ satisfies this condition; the loop will
-terminate before $s$ can possibly become zero.
-
-@p procedure print_scaled(@!s:scaled); {prints scaled real, rounded to five
- digits}
-var delta:scaled; {amount of allowable inaccuracy}
-begin if s<0 then
- begin print_char("-"); negate(s); {print the sign, if negative}
- end;
-print_int(s div unity); {print the integer part}
-print_char(".");
-s:=10*(s mod unity)+5; delta:=10;
-repeat if delta>unity then s:=s+@'100000-50000; {round the last digit}
-print_char("0"+(s div unity)); s:=10*(s mod unity); delta:=delta*10;
-until s<=delta;
-end;
-
-@ Physical sizes that a \TeX\ user specifies for portions of documents are
-represented internally as scaled points. Thus, if we define an `sp' (scaled
-@^sp@>
-point) as a unit equal to $2^{-16}$ printer's points, every dimension
-inside of \TeX\ is an integer number of sp. There are exactly
-4,736,286.72 sp per inch. Users are not allowed to specify dimensions
-larger than $2^{30}-1$ sp, which is a distance of about 18.892 feet (5.7583
-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@>
-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
-such tests do not seem worthwhile.
-
-\TeX\ needs to do only a few arithmetic operations on scaled quantities,
-other than addition and subtraction, and the following subroutines do most of
-the work. A single computation might use several subroutine calls, and it is
-desirable to avoid producing multiple error messages in case of arithmetic
-overflow; so the routines set the global variable |arith_error| to |true|
-instead of reporting errors directly to the user. Another global variable,
-|remainder|, holds the remainder after a division.
-
-@<Glob...@>=
-@!arith_error:boolean; {has arithmetic overflow occurred recently?}
-@!remainder:scaled; {amount subtracted to get an exact division}
-
-@ The first arithmetical subroutine we need computes $nx+y$, where |x|
-and~|y| are |scaled| and |n| is an integer. We will also use it to
-multiply integers.
-
-@d nx_plus_y(#)==mult_and_add(#,@'7777777777)
-@d mult_integers(#)==mult_and_add(#,0,@'17777777777)
-
-@p function mult_and_add(@!n:integer;@!x,@!y,@!max_answer:scaled):scaled;
-begin if n<0 then
- begin negate(x); negate(n);
- end;
-if n=0 then mult_and_add:=y
-else if ((x<=(max_answer-y) div n)and(-x<=(max_answer+y) div n)) then
- mult_and_add:=n*x+y
-else begin arith_error:=true; mult_and_add:=0;
- end;
-end;
-
-@ We also need to divide scaled dimensions by integers.
-
-@p function x_over_n(@!x:scaled;@!n:integer):scaled;
-var negative:boolean; {should |remainder| be negated?}
-begin negative:=false;
-if n=0 then
- begin arith_error:=true; x_over_n:=0; remainder:=x;
- end
-else begin if n<0 then
- begin negate(x); negate(n); negative:=true;
- end;
- if x>=0 then
- begin x_over_n:=x div n; remainder:=x mod n;
- end
- else begin x_over_n:=-((-x) div n); remainder:=-((-x) mod n);
- end;
- end;
-if negative then negate(remainder);
-end;
-
-@ Then comes the multiplication of a scaled number by a fraction |n/d|,
-where |n| and |d| are nonnegative integers |<=@t$2^{16}$@>| and |d| is
-positive. It would be too dangerous to multiply by~|n| and then divide
-by~|d|, in separate operations, since overflow might well occur; and it
-would be too inaccurate to divide by |d| and then multiply by |n|. Hence
-this subroutine simulates 1.5-precision arithmetic.
-
-@p function xn_over_d(@!x:scaled; @!n,@!d:integer):scaled;
-var positive:boolean; {was |x>=0|?}
-@!t,@!u,@!v:nonnegative_integer; {intermediate quantities}
-begin if x>=0 then positive:=true
-else begin negate(x); positive:=false;
- end;
-t:=(x mod @'100000)*n;
-u:=(x div @'100000)*n+(t div @'100000);
-v:=(u mod d)*@'100000 + (t mod @'100000);
-if u div d>=@'100000 then arith_error:=true
-else u:=@'100000*(u div d) + (v div d);
-if positive then
- begin xn_over_d:=u; remainder:=v mod d;
- end
-else begin xn_over_d:=-u; remainder:=-(v mod d);
- end;
-end;
-
-@ The next subroutine is used to compute the ``badness'' of glue, when a
-total~|t| is supposed to be made from amounts that sum to~|s|. According
-to {\sl The \TeX book}, the badness of this situation is $100(t/s)^3$;
-however, badness is simply a heuristic, so we need not squeeze out the
-last drop of accuracy when computing it. All we really want is an
-approximation that has similar properties.
-@:TeXbook}{\sl The \TeX book@>
-
-The actual method used to compute the badness is easier to read from the
-program than to describe in words. It produces an integer value that is a
-reasonably close approximation to $100(t/s)^3$, and all implementations
-of \TeX\ should use precisely this method. Any badness of $2^{13}$ or more is
-treated as infinitely bad, and represented by 10000.
-
-It is not difficult to prove that $$\hbox{|badness(t+1,s)>=badness(t,s)
->=badness(t,s+1)|}.$$ The badness function defined here is capable of
-computing at most 1095 distinct values, but that is plenty.
-
-@d inf_bad = 10000 {infinitely bad value}
-
-@p function badness(@!t,@!s:scaled):halfword; {compute badness, given |t>=0|}
-var r:integer; {approximation to $\alpha t/s$, where $\alpha^3\approx
- 100\cdot2^{18}$}
-begin if t=0 then badness:=0
-else if s<=0 then badness:=inf_bad
-else begin if t<=7230584 then r:=(t*297) div s {$297^3=99.94\times2^{18}$}
- else if s>=1663497 then r:=t div (s div 297)
- else r:=t;
- if r>1290 then badness:=inf_bad {$1290^3<2^{31}<1291^3$}
- else badness:=(r*r*r+@'400000) div @'1000000;
- end; {that was $r^3/2^{18}$, rounded to the nearest integer}
-end;
-
-@ When \TeX\ ``packages'' a list into a box, it needs to calculate the
-proportionality ratio by which the glue inside the box should stretch
-or shrink. This calculation does not affect \TeX's decision making,
-so the precise details of rounding, etc., in the glue calculation are not
-of critical importance for the consistency of results on different computers.
-
-We shall use the type |glue_ratio| for such proportionality ratios.
-A glue ratio should take the same amount of memory as an
-|integer| (usually 32 bits) if it is to blend smoothly with \TeX's
-other data structures. Thus |glue_ratio| should be equivalent to
-|short_real| in some implementations of \PASCAL. Alternatively,
-it is possible to deal with glue ratios using nothing but fixed-point
-arithmetic; see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the
-routines cited there must be modified to allow negative glue ratios.)
-@^system dependencies@>
-
-@d set_glue_ratio_zero(#) == #:=0.0 {store the representation of zero ratio}
-@d set_glue_ratio_one(#) == #:=1.0 {store the representation of unit ratio}
-@d float(#) == # {convert from |glue_ratio| to type |real|}
-@d unfloat(#) == # {convert from |real| to type |glue_ratio|}
-@d float_constant(#) == #.0 {convert |integer| constant to |real|}
-
-@<Types...@>=
-@!glue_ratio=real; {one-word representation of a glue expansion factor}
-
-@* \[7b] Random numbers.
-
-\font\tenlogo=logo10 % font used for the METAFONT logo
-\def\MP{{\tenlogo META}\-{\tenlogo POST}}
-
-This section is (almost) straight from MetaPost. I had to change
-the types (use |integer| instead of |fraction|), but that should
-not have any influence on the actual calculations (the original
-comments refer to quantities like |fraction_four| ($2^{30}$), and
-that is the same as the numeric representation of |max_dimen|).
-
-I've copied the low-level variables and routines that are needed, but
-only those (e.g. |m_log|), not the accompanying ones like |m_exp|. Most
-of the following low-level numeric routines are only needed within the
-calculation of |norm_rand|. I've been forced to rename |make_fraction|
-to |make_frac| because TeX already has a routine by that name with
-a wholly different function (it creates a |fraction_noad| for math
-typesetting) -- Taco
-
-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.
-
-@<Glob...@>=
-@!randoms:array[0..54] of integer; {the last 55 random values generated}
-@!j_random:0..54; {the number of unused |randoms|}
-@!random_seed:scaled; {the default random seed}
-
-@ A small bit of metafont is needed.
-
-@d fraction_half==@'1000000000 {$2^{27}$, represents 0.50000000}
-@d fraction_one==@'2000000000 {$2^{28}$, represents 1.00000000}
-@d fraction_four==@'10000000000 {$2^{30}$, represents 4.00000000}
-@d el_gordo == @'17777777777 {$2^{31}-1$, the largest value that \MP\ likes}
-@d halfp(#)==(#) div 2
-@d double(#) == #:=#+# {multiply a variable by two}
-
-@ The |make_frac| routine produces the |fraction| equivalent of
-|p/q|, given integers |p| and~|q|; it computes the integer
-$f=\lfloor2^{28}p/q+{1\over2}\rfloor$, when $p$ and $q$ are
-positive. If |p| and |q| are both of the same scaled type |t|,
-the ``type relation'' |make_frac(t,t)=fraction| is valid;
-and it's also possible to use the subroutine ``backwards,'' using
-the relation |make_frac(t,fraction)=t| between scaled types.
-
-If the result would have magnitude $2^{31}$ or more, |make_frac|
-sets |arith_error:=true|. Most of \MP's internal computations have
-been designed to avoid this sort of error.
-
-If this subroutine were programmed in assembly language on a typical
-machine, we could simply compute |(@t$2^{28}$@>*p)div q|, since a
-double-precision product can often be input to a fixed-point division
-instruction. But when we are restricted to \PASCAL\ arithmetic it
-is necessary either to resort to multiple-precision maneuvering
-or to use a simple but slow iteration. The multiple-precision technique
-would be about three times faster than the code adopted here, but it
-would be comparatively long and tricky, involving about sixteen
-additional multiplications and divisions.
-
-This operation is part of \MP's ``inner loop''; indeed, it will
-consume nearly 10\pct! of the running time (exclusive of input and output)
-if the code below is left unchanged. A machine-dependent recoding
-will therefore make \MP\ run faster. The present implementation
-is highly portable, but slow; it avoids multiplication and division
-except in the initial stage. System wizards should be careful to
-replace it with a routine that is guaranteed to produce identical
-results in all cases.
-@^system dependencies@>
-
-As noted below, a few more routines should also be replaced by machine-dependent
-code, for efficiency. But when a procedure is not part of the ``inner loop,''
-such changes aren't advisable; simplicity and robustness are
-preferable to trickery, unless the cost is too high.
-@^inner loop@>
-
-@p function make_frac(@!p,@!q:integer):integer;
-var @!f:integer; {the fraction bits, with a leading 1 bit}
-@!n:integer; {the integer part of $\vert p/q\vert$}
-@!negative:boolean; {should the result be negated?}
-@!be_careful:integer; {disables certain compiler optimizations}
-begin if p>=0 then negative:=false
-else begin negate(p); negative:=true;
- end;
-if q<=0 then
- begin debug if q=0 then confusion("/");@;@+gubed@;@/
-@:this can't happen /}{\quad \./@>
- negate(q); negative:=not negative;
- end;
-n:=p div q; p:=p mod q;
-if n>=8 then
- begin arith_error:=true;
- if negative then make_frac:=-el_gordo@+else make_frac:=el_gordo;
- end
-else begin n:=(n-1)*fraction_one;
- @<Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$@>;
- if negative then make_frac:=-(f+n)@+else make_frac:=f+n;
- end;
-end;
-
-@ The |repeat| loop here preserves the following invariant relations
-between |f|, |p|, and~|q|:
-(i)~|0<=p<q|; (ii)~$fq+p=2^k(q+p_0)$, where $k$ is an integer and
-$p_0$ is the original value of~$p$.
-
-Notice that the computation specifies
-|(p-q)+p| instead of |(p+p)-q|, because the latter could overflow.
-Let us hope that optimizing compilers do not miss this point; a
-special variable |be_careful| is used to emphasize the necessary
-order of computation. Optimizing compilers should keep |be_careful|
-in a register, not store it in memory.
-@^inner loop@>
-
-@<Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$@>=
-f:=1;
-repeat be_careful:=p-q; p:=be_careful+p;
-if p>=0 then f:=f+f+1
-else begin double(f); p:=p+q;
- end;
-until f>=fraction_one;
-be_careful:=p-q;
-if be_careful+p>=0 then incr(f)
-
-@
-
-@p function take_frac(@!q:integer;@!f:integer):integer;
-var @!p:integer; {the fraction so far}
-@!negative:boolean; {should the result be negated?}
-@!n:integer; {additional multiple of $q$}
-@!be_careful:integer; {disables certain compiler optimizations}
-begin @<Reduce to the case that |f>=0| and |q>0|@>;
-if f<fraction_one then n:=0
-else begin n:=f div fraction_one; f:=f mod fraction_one;
- if q<=el_gordo div n then n:=n*q
- else begin arith_error:=true; n:=el_gordo;
- end;
- end;
-f:=f+fraction_one;
-@<Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$@>;
-be_careful:=n-el_gordo;
-if be_careful+p>0 then
- begin arith_error:=true; n:=el_gordo-p;
- end;
-if negative then take_frac:=-(n+p)
-else take_frac:=n+p;
-end;
-
-@ @<Reduce to the case that |f>=0| and |q>0|@>=
-if f>=0 then negative:=false
-else begin negate(f); negative:=true;
- end;
-if q<0 then
- begin negate(q); negative:=not negative;
- end;
-
-@ The invariant relations in this case are (i)~$\lfloor(qf+p)/2^k\rfloor
-=\lfloor qf_0/2^{28}+{1\over2}\rfloor$, where $k$ is an integer and
-$f_0$ is the original value of~$f$; (ii)~$2^k\L f<2^{k+1}$.
-@^inner loop@>
-
-@<Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$@>=
-p:=fraction_half; {that's $2^{27}$; the invariants hold now with $k=28$}
-if q<fraction_four then
- repeat if odd(f) then p:=halfp(p+q)@+else p:=halfp(p);
- f:=halfp(f);
- until f=1
-else repeat if odd(f) then p:=p+halfp(q-p)@+else p:=halfp(p);
- f:=halfp(f);
- until f=1
-
-@ 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.
-
-@<Glob...@>=
-@!two_to_the:array[0..30] of integer; {powers of two}
-@!spec_log:array[1..28] of integer; {special logarithms}
-
-
-@ @<Set init...@>=
-two_to_the[0]:=1;
-for k:=1 to 30 do two_to_the[k]:=2*two_to_the[k-1];
-spec_log[1]:=93032640;
-spec_log[2]:=38612034;
-spec_log[3]:=17922280;
-spec_log[4]:=8662214;
-spec_log[5]:=4261238;
-spec_log[6]:=2113709;
-spec_log[7]:=1052693;
-spec_log[8]:=525315;
-spec_log[9]:=262400;
-spec_log[10]:=131136;
-spec_log[11]:=65552;
-spec_log[12]:=32772;
-spec_log[13]:=16385;
-for k:=14 to 27 do spec_log[k]:=two_to_the[27-k];
-spec_log[28]:=1;
-
-@
-
-@p function m_log(@!x:integer):integer;
-var @!y,@!z:integer; {auxiliary registers}
-@!k:integer; {iteration counter}
-begin if x<=0 then @<Handle non-positive logarithm@>
-else begin y:=1302456956+4-100; {$14\times2^{27}\ln2\approx1302456956.421063$}
- z:=27595+6553600; {and $2^{16}\times .421063\approx 27595$}
- while x<fraction_four do
- begin double(x); y:=y-93032639; z:=z-48782;
- end; {$2^{27}\ln2\approx 93032639.74436163$
- and $2^{16}\times.74436163\approx 48782$}
- y:=y+(z div unity); k:=2;
- while x>fraction_four+4 do
- @<Increase |k| until |x| can be multiplied by a
- factor of $2^{-k}$, and adjust $y$ accordingly@>;
- m_log:=y div 8;
- end;
-end;
-
-@ @<Increase |k| until |x| can...@>=
-begin z:=((x-1) div two_to_the[k])+1; {$z=\lceil x/2^k\rceil$}
-while x<fraction_four+z do
- begin z:=halfp(z+1); k:=k+1;
- end;
-y:=y+spec_log[k]; x:=x-z;
-end
-
-@ @<Handle non-positive logarithm@>=
-begin print_err("Logarithm of ");
-@.Logarithm...replaced by 0@>
-print_scaled(x); print(" 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.");
-error; m_log:=0;
-end
-
-@ The following somewhat different subroutine tests rigorously if $ab$ is
-greater than, equal to, or less than~$cd$,
-given integers $(a,b,c,d)$. In most cases a quick decision is reached.
-The result is $+1$, 0, or~$-1$ in the three respective cases.
-
-@d return_sign(#)==begin ab_vs_cd:=#; return;
- end
-
-@p function ab_vs_cd(@!a,b,c,d:integer):integer;
-label exit;
-var @!q,@!r:integer; {temporary registers}
-begin @<Reduce to the case that |a,c>=0|, |b,d>0|@>;
-loop@+ begin q := a div d; r := c div b;
- if q<>r then begin
- if q>r then return_sign(1)@+else return_sign(-1);
- end;
- q := a mod d; r := c mod b;
- if r=0 then begin
- if q=0 then return_sign(0)@+else return_sign(1);
- end;
- if q=0 then return_sign(-1);
- a:=b; b:=q; c:=d; d:=r;
- end; {now |a>d>0| and |c>b>0|}
-exit:end;
-
-@ @<Reduce to the case that |a...@>=
-if a<0 then
- begin negate(a); negate(b);
- end;
-if c<0 then
- begin negate(c); negate(d);
- end;
-if d<=0 then
- begin if b>=0 then begin
- if ((a=0)or(b=0))and((c=0)or(d=0)) then return_sign(0)
- else return_sign(1);
- end;
- if d=0 then begin
- if a=0 then return_sign(0)@+else return_sign(-1);
- end;
- q:=a; a:=c; c:=q; q:=-b; b:=-d; d:=q;
- end
-else if b<=0 then
- begin if b<0 then if a>0 then return_sign(-1);
- if c=0 then return_sign(0) else return_sign(-1);
- end
-
-@ To consume a random integer, the program below will say `|next_random|'
-and then it will fetch |randoms[j_random]|.
-
-@d next_random==if j_random=0 then new_randoms
- else decr(j_random)
-
-@p procedure new_randoms;
-var @!k:0..54; {index into |randoms|}
-@!x:integer; {accumulator}
-begin for k:=0 to 23 do
- begin x:=randoms[k]-randoms[k+31];
- if x<0 then x:=x+fraction_one;
- randoms[k]:=x;
- end;
-for k:=24 to 54 do
- begin x:=randoms[k]-randoms[k-24];
- if x<0 then x:=x+fraction_one;
- randoms[k]:=x;
- end;
-j_random:=54;
-end;
-
-@ To initialize the |randoms| table, we call the following routine.
-
-@p procedure init_randoms(@!seed:integer);
-var @!j,@!jj,@!k:integer; {more or less random integers}
-@!i:0..54; {index into |randoms|}
-begin j:=abs(seed);
-while j>=fraction_one do j:=halfp(j);
-k:=1;
-for i:=0 to 54 do
- begin jj:=k; k:=j-k; j:=jj;
- if k<0 then k:=k+fraction_one;
- randoms[(i*21)mod 55]:=j;
- end;
-new_randoms; new_randoms; new_randoms; {``warm up'' the array}
-end;
-
-@ To produce a uniform random number in the range |0<=u<x| or |0>=u>x|
-or |0=u=x|, given a |scaled| value~|x|, we proceed as shown here.
-
-Note that the call of |take_frac| will produce the values 0 and~|x|
-with about half the probability that it will produce any other particular
-values between 0 and~|x|, because it rounds its answers.
-
-@p function unif_rand(@!x:integer):integer;
-var @!y:integer; {trial value}
-begin next_random; y:=take_frac(abs(x),randoms[j_random]);
-if y=abs(x) then unif_rand:=0
-else if x>0 then unif_rand:=y
-else unif_rand:=-y;
-end;
-
-@ Finally, a normal deviate with mean zero and unit standard deviation
-can readily be obtained with the ratio method (Algorithm 3.4.1R in
-{\sl The Art of Computer Programming\/}).
-
-@p function norm_rand:integer;
-var @!x,@!u,@!l:integer; {what the book would call $2^{16}X$, $2^{28}U$,
- and $-2^{24}\ln U$}
-begin repeat
- repeat next_random;
- x:=take_frac(112429,randoms[j_random]-fraction_half);
- {$2^{16}\sqrt{8/e}\approx 112428.82793$}
- next_random; u:=randoms[j_random];
- until abs(x)<u;
-x:=make_frac(x,u);
-l:=139548960-m_log(u); {$2^{24}\cdot12\ln2\approx139548959.6165$}
-until ab_vs_cd(1024,l,x,x)>=0;
-norm_rand:=x;
-end;
-
-@* \[8] Packed data.
-In order to make efficient use of storage space, \TeX\ bases its major data
-structures on a |memory_word|, which contains either a (signed) integer,
-possibly scaled, or a (signed) |glue_ratio|, or a small number of
-fields that are one half or one quarter of the size used for storing
-integers.
-
-If |x| is a variable of type |memory_word|, it contains up to four
-fields that can be referred to as follows:
-$$\vbox{\halign{\hfil#&#\hfil&#\hfil\cr
-|x|&.|int|&(an |integer|)\cr
-|x|&.|sc|\qquad&(a |scaled| integer)\cr
-|x|&.|gr|&(a |glue_ratio|)\cr
-|x.hh.lh|, |x.hh|&.|rh|&(two halfword fields)\cr
-|x.hh.b0|, |x.hh.b1|, |x.hh|&.|rh|&(two quarterword fields, one halfword
- field)\cr
-|x.qqqq.b0|, |x.qqqq.b1|, |x.qqqq|&.|b2|, |x.qqqq.b3|\hskip-100pt
- &\qquad\qquad\qquad(four quarterword fields)\cr}}$$
-This is somewhat cumbersome to write, and not very readable either, but
-macros will be used to make the notation shorter and more transparent.
-The \PASCAL\ code below gives a formal definition of |memory_word| and
-its subsidiary types, using packed variant records. \TeX\ makes no
-assumptions about the relative positions of the fields within a word.
-
-We are assuming 32-bit integers, a halfword must contain at least
-32 bits, and a quarterword must contain at least 16 bits.
-@^system dependencies@>
-
-N.B.: Valuable memory space will be dreadfully wasted unless \TeX\ is compiled
-by a \PASCAL\ that packs all of the |memory_word| variants into
-the space of a single integer. This means, for example, that |glue_ratio|
-words should be |short_real| instead of |real| on some computers. Some
-\PASCAL\ compilers will pack an integer whose subrange is `|0..255|' into
-an eight-bit field, but others insist on allocating space for an additional
-sign bit; on such systems you can get 256 values into a quarterword only
-if the subrange is `|-128..127|'.
-
-The present implementation tries to accommodate as many variations as possible,
-so it makes few assumptions. If integers having the subrange
-`|min_quarterword..max_quarterword|' can be packed into a quarterword,
-and if integers having the subrange `|min_halfword..max_halfword|'
-can be packed into a halfword, everything should work satisfactorily.
-
-It is usually most efficient to have |min_quarterword=min_halfword=0|,
-so one should try to achieve this unless it causes a severe problem.
-The values defined here are recommended for most 32-bit computers.
-
-We cannot use the full range of 32 bits in a halfword, because we have
-to allow negative values for potential backend tricks like web2c's
-dynamic allocation, and parshapes pointers have to be able to store at
-least twice the value |max_halfword| (see below). Therefore,
-|max_halfword| is $2^{30}-1$
-
-@d min_quarterword=0 {smallest allowable value in a |quarterword|}
-@d max_quarterword=65535 {largest allowable value in a |quarterword|}
-@d min_halfword==-@"3FFFFFFF {smallest allowable value in a |halfword|}
-@d max_halfword==@"3FFFFFFF {largest allowable value in a |halfword|}
-
-@ Here are the inequalities that the quarterword and halfword values
-must satisfy (or rather, the inequalities that they mustn't satisfy):
-
-@<Check the ``constant''...@>=
-if (min_quarterword>0)or(max_quarterword<@"7FFF) then bad:=11;
-if (min_halfword>0)or(max_halfword<@"3FFFFFFF) then bad:=12;
-if (min_quarterword<min_halfword)or@|
- (max_quarterword>max_halfword) then bad:=13;
-if font_base<min_quarterword then bad:=15;
-if (save_size>max_halfword)or(max_strings>max_halfword) then bad:=17;
-if buf_size>max_halfword then bad:=18;
-if max_quarterword-min_quarterword<@"FFFF then bad:=19;
-
-@ The operation of adding or subtracting |min_quarterword| occurs quite
-frequently in \TeX, so it is convenient to abbreviate this operation
-by using the macros |qi| and |qo| for input and output to and from
-quarterword format.
-
-The inner loop of \TeX\ will run faster with respect to compilers
-that don't optimize expressions like `|x+0|' and `|x-0|', if these
-macros are simplified in the obvious way when |min_quarterword=0|.
-@^inner loop@>@^system dependencies@>
-
-@d qi(#)==#+min_quarterword
- {to put an |eight_bits| item into a quarterword}
-@d qo(#)==#-min_quarterword
- {to take an |eight_bits| item out of a quarterword}
-@d hi(#)==#+min_halfword
- {to put a sixteen-bit item into a halfword}
-@d ho(#)==#-min_halfword
- {to take a sixteen-bit item from a halfword}
-
-@ The reader should study the following definitions closely:
-@^system dependencies@>
-
-@d sc==int {|scaled| data is equivalent to |integer|}
-
-@<Types...@>=
-@!quarterword = min_quarterword..max_quarterword; {1/4 of a word}
-@!halfword=min_halfword..max_halfword; {1/2 of a word}
-@!two_choices = 1..2; {used when there are two variants in a record}
-@!four_choices = 1..4; {used when there are four variants in a record}
-@!two_halves = packed record@;@/
- @!rh:halfword;
- case two_choices of
- 1: (@!lh:halfword);
- 2: (@!b0:quarterword; @!b1:quarterword);
- end;
-@!four_quarters = packed record@;@/
- @!b0:quarterword;
- @!b1:quarterword;
- @!b2:quarterword;
- @!b3:quarterword;
- end;
-@!memory_word = record@;@/
- case four_choices of
- 1: (@!int:integer);
- 2: (@!gr:glue_ratio);
- 3: (@!hh:two_halves);
- 4: (@!qqqq:four_quarters);
- end;
-@!word_file = file of memory_word;
-
-@ When debugging, we may want to print a |memory_word| without knowing
-what type it is; so we print it in all modes.
-@^dirty \PASCAL@>@^debugging@>
-
-@p @!debug procedure print_word(@!w:memory_word);
- {prints |w| in all ways}
-begin print_int(w.int); print_char(" ");@/
-print_scaled(w.sc); print_char(" ");@/
-print_scaled(round(unity*float(w.gr))); print_ln;@/
-@^real multiplication@>
-print_int(w.hh.lh); print_char("="); print_int(w.hh.b0); print_char(":");
-print_int(w.hh.b1); print_char(";"); print_int(w.hh.rh); print_char(" ");@/
-print_int(w.qqqq.b0); print_char(":"); print_int(w.qqqq.b1); print_char(":");
-print_int(w.qqqq.b2); print_char(":"); print_int(w.qqqq.b3);
-end;
-gubed
-
-@* \[9] Dynamic memory allocation.
-The \TeX\ system does nearly all of its own memory allocation, so that it
-can readily be transported into environments that do not have automatic
-facilities for strings, garbage collection, etc., and so that it can be in
-control of what error messages the user receives. The dynamic storage
-requirements of \TeX\ are handled by providing two large arrays called
-|fixmem| and |varmem| in which consecutive blocks of words are used as
-nodes by the \TeX\ routines.
-
-Pointer variables are indices into this array, or into another array
-called |eqtb| that will be explained later. A pointer variable might
-also be a special flag that lies outside the bounds of |mem|, so we
-allow pointers to assume any |halfword| value. The minimum halfword
-value represents a null pointer. \TeX\ does not assume that |mem[null]| exists.
-
-@d pointer==halfword {a flag or a location in |mem| or |eqtb|}
-@d null==0 {the null pointer}
-
-@<Glob...@>=
-@!temp_ptr:pointer; {a pointer variable for occasional emergency use}
-
-@ @<Types...@>=
-@!smemory_word = packed record@;@/
- @!hhrh:halfword;
- @!hhlh:halfword;
- end;
-
-
-@ The |mem| array is divided into two items that are allocated separately;
-they grow until finding their ``natural'' size in a particular job.
-Locations in |varmem| are used for storing variable-length records
-consisting of two or more words each. This region
-is maintained using an algorithm similar to the one described in exercise
-2.5--19 of {\sl The Art of Computer Programming}. However, no size field
-appears in the allocated nodes; the program is responsible for knowing the
-relevant size when a node is freed. Locations in |fixmem| are used for storing
-one-word records; a conventional \.{AVAIL} stack is used for allocation
-in this array.
-
-Empirical tests show that the present implementation of \TeX\ tends to
-spend about 9\pct! of its running time allocating nodes, and about 6\pct!
-deallocating them after their use.
-
-@d fix_mem_init==10000
-
-@<Glob...@>=
-@!fixmem : ^smemory_word; {the big dynamic storage area}
-@!fix_mem_min : pointer; {the smallest location of one-word memory in use}
-@!fix_mem_max : pointer; {the largest location of one-word memory in use}
-
-@ In order to study the memory requirements of particular applications, it
-is possible to prepare a version of \TeX\ that keeps track of current and
-maximum memory usage. When code between the delimiters |@!stat| $\ldots$
-|tats| is not ``commented out,'' \TeX\ will run a bit slower but it will
-report these statistics when |tracing_stats| is sufficiently large.
-
-@<Glob...@>=
-@!var_used, @!dyn_used : integer; {how much memory is in use}
-
-@ Let's consider the one-word memory region first, since it's the
-simplest. The pointer variable |fix_mem_end| holds the highest-numbered location
-of |mem| that has ever been used. The free locations of |mem| that
-occur between |hi_mem_min| and |fix_mem_end|, inclusive, are of type
-|two_halves|, and we write |info(p)| and |link(p)| for the |lh|
-and |rh| fields of |mem[p]| when it is of this type. The single-word
-free locations form a linked list
-$$|avail|,\;\hbox{|link(avail)|},\;\hbox{|link(link(avail))|},\;\ldots$$
-terminated by |null|.
-
-@d mem(#) == fixmem[#]
-@d link(#) == mem(#).hhrh {the |link| field of a memory word}
-@d info(#) == mem(#).hhlh {the |info| field of a memory word}
-
-@<Glob...@>=
-@!avail : pointer; {head of the list of available one-word nodes}
-@!fix_mem_end : pointer; {the last one-word node used in |mem|}
-
-@ If memory is exhausted, it might mean that the user has forgotten
-a right brace. We will define some procedures later that try to help
-pinpoint the trouble.
-
-@p @<Declare the procedure called |show_token_list|@>@/
-@<Declare the procedure called |runaway|@>
-
-@ The function |get_avail| returns a pointer to a new one-word node whose
-|link| field is null. However, \TeX\ will halt if there is no more room left.
-@^inner loop@>
-
-If the available-space list is empty, i.e., if |avail=null|,
-we try first to increase |fix_mem_end|. If that cannot be done, i.e., if
-|fix_mem_end=fix_mem_max|, we try to reallocate array |fixmem|.
-If, that doesn't work, we have to quit.
-
-@p function get_avail : pointer; {single-word node allocation}
-var p:pointer; {the new node being got}
-t:integer;
-begin p:=avail; {get top location in the |avail| stack}
-if p<>null then avail:=link(avail) {and pop it off}
-else if fix_mem_end<fix_mem_max then {or go into virgin territory}
- begin incr(fix_mem_end); p:=fix_mem_end;
- end
-else begin
- t:=(fix_mem_max/5);
- fixmem := fixmemcast(realloc(fixmem,sizeof(smemory_word)*(fix_mem_max+t+1)));
- if fixmem=NULL then
- begin runaway; {if memory is exhausted, display possible runaway text}
- overflow("token memory size",fix_mem_max);
- {quit; all one-word nodes are busy}
-@:TeX capacity exceeded main memory size}{\quad main memory size@>
- end;
- memset (voidcast(fixmem+fix_mem_max+1),0,t*sizeof(smemory_word));
- fix_mem_max:=fix_mem_max+t; incr(fix_mem_end); p:=fix_mem_end;
- end;
-link(p):=null; {provide an oft-desired initialization of the new node}
-@!stat incr(dyn_used);@+tats@;{maintain statistics}
-get_avail:=p;
-end;
-
-@ Conversely, a one-word node is recycled by calling |free_avail|.
-This routine is part of \TeX's ``inner loop,'' so we want it to be fast.
-@^inner loop@>
-
-@d free_avail(#)== {single-word node liberation}
- begin link(#):=avail; avail:=#;
- @!stat decr(dyn_used);@+tats@/
- end
-
-@ There's also a |fast_get_avail| routine, which saves the procedure-call
-overhead at the expense of extra programming. This routine is used in
-the places that would otherwise account for the most calls of |get_avail|.
-@^inner loop@>
-
-@d fast_get_avail(#)==@t@>@;@/
- begin #:=avail; {avoid |get_avail| if possible, to save time}
- if #=null then #:=get_avail
- else begin avail:=link(#); link(#):=null;
- @!stat incr(dyn_used);@+tats@/
- end;
- end
-
-@ The procedure |flush_list(p)| frees an entire linked list of
-one-word nodes that starts at position |p|.
-@^inner loop@>
-
-@p procedure flush_list(@!p:pointer); {makes list of single-word nodes available}
-var @!q,@!r:pointer; {list traversers}
-begin if p<>null then
- begin r:=p;
- repeat q:=r; r:=link(r); @!stat decr(dyn_used);@+tats@/
- until r=null; {now |q| is the last node on the list}
- link(q):=avail; avail:=p;
- end;
-end;
-
-@ The available-space list that keeps track of the variable-size portion
-of |mem| is a nonempty, doubly-linked circular list of empty nodes,
-pointed to by the roving pointer |rover|.
-
-@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}
-@d alink(#) == vlink(#+1) {backlink in doubly-linked list of empty nodes}
-
-@* \[10] Data structures for boxes and their friends.
-From the computer's standpoint, \TeX's chief mission is to create
-horizontal and vertical lists. We shall now investigate how the elements
-of these lists are represented internally as nodes in the dynamic memory.
-
-A horizontal or vertical list is linked together by |link| fields in
-the first word of each node. Individual nodes represent boxes, glue,
-penalties, or special things like discretionary hyphens; because of this
-variety, some nodes are longer than others, and we must distinguish different
-kinds of nodes. We do this by putting a `|type|' field in the first word,
-together with the link and an optional `|subtype|'.
-
-@d type(#) == vmem(#).hh.b0 {identifies what kind of node this is}
-@d subtype(#) == vmem(#).hh.b1 {secondary identification in some cases}
-
-@ TH: This module section is superceded.
-
-A |@!char_node|, which represents a single character, is the most important
-kind of node because it accounts for the vast majority of all boxes.
-Special precautions are therefore taken to ensure that a |char_node| does
-not take up much memory space. Every such node is one word long, and in fact
-it is identifiable by this property, since other kinds of nodes have at least
-two words, and they appear in |mem| locations less than |hi_mem_min|.
-This makes it possible to omit the |type| field in a |char_node|, leaving
-us room for two bytes that identify a |font| and a |character| within
-that font.
-
-Note that the format of a |char_node| allows for up to 256 different
-fonts and up to 256 characters per font; but most implementations will
-probably limit the total number of fonts to fewer than 75 per job,
-and most fonts will stick to characters whose codes are
-less than 128 (since higher codes
-are more difficult to access on most keyboards).
-
-Extensions of \TeX\ intended for oriental languages will need even more
-than $256\times256$ possible characters, when we consider different sizes
-@^oriental characters@>@^Chinese characters@>@^Japanese characters@>
-and styles of type. It is suggested that Chinese and Japanese fonts be
-handled by representing such characters in two consecutive |char_node|
-entries: The first of these has |font=font_base|, and its |link| points
-to the second;
-the second identifies the font and the character dimensions.
-The saving feature about oriental characters is that most of them have
-the same box dimensions. The |character| field of the first |char_node|
-is a ``\\{charext}'' that distinguishes between graphic symbols whose
-dimensions are identical for typesetting purposes. (See the \MF\ manual.)
-Such an extension of \TeX\ would not be difficult; further details are
-left to the reader.
-
-In order to make sure that the |character| code fits in a quarterword,
-\TeX\ adds the quantity |min_quarterword| to the actual code.
-
-Character nodes appear only in horizontal lists, never in vertical lists.
-
-@ Attribute lists need two extra globals to increase processing efficiency.
-|max_used_attr| limits the test loop that checks for set attributes, and
-|attr_list_cache| contains a pointer to an already created attribute list. It is
-set to the special value |cache_disabled| when the current value can no longer be
-trusted: after an assignment to an attribute register, and after a group has
-ended.
-
-@d cache_disabled==max_halfword
-
-@<Glob...@>=
-max_used_attr:integer; { maximum assigned attribute id }
-attr_list_cache:pointer;
-
-@ @<Set init...@>=
-max_used_attr:=-1; attr_list_cache:=cache_disabled;
-
-@ Attribute lists are maintained in C, but they need access to the current
-attributes in eqtb.
-
-@p function get_attribute(i:halfword):halfword;
-begin
- get_attribute := attribute(i);
-end;
-
-
-@ An |hlist_node| stands for a box that was made from a horizontal list.
-Each |hlist_node| is seven words long, and contains the following fields
-(in addition to the mandatory |type| and |link|, which we shall not
-mention explicitly when discussing the other node types): The |height| and
-|width| and |depth| are scaled integers denoting the dimensions of the
-box. There is also a |shift_amount| field, a scaled integer indicating
-how much this box should be lowered (if it appears in a horizontal list),
-or how much it should be moved to the right (if it appears in a vertical
-list). There is a |list_ptr| field, which points to the beginning of the
-list from which this box was fabricated; if |list_ptr| is |null|, the box
-is empty. Finally, there are three fields that represent the setting of
-the glue: |glue_set(p)| is a word of type |glue_ratio| that represents
-the proportionality constant for glue setting; |glue_sign(p)| is
-|stretching| or |shrinking| or |normal| depending on whether or not the
-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 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}
-@d width(#) == vmem(#+width_offset).sc {width of the box, in sp}
-@d depth(#) == vmem(#+depth_offset).sc {depth of the box, in sp}
-@d height(#) == vmem(#+height_offset).sc {height of the box, in sp}
-@d shift_amount(#) == vlink(#+5) {repositioning distance, in sp}
-@d box_dir(#) == vinfo(#+5) {position of |box_dir| in a box node}
-@d list_offset=6 {position of |list_ptr| field in a box node}
-@d list_ptr(#) == vlink(#+list_offset) {beginning of the list inside the box}
-@d glue_order(#) == subtype(#+list_offset) {applicable order of infinity}
-@d glue_sign(#) == type(#+list_offset) {stretching or shrinking}
-@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_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\{\}}'.
-The |subtype| field is set to |min_quarterword|, since that's the desired
-|span_count| value if this |hlist_node| is changed to an |unset_node|.
-
-@p function new_null_box:pointer; {creates a new box node}
-var p:pointer; {the new node}
-begin p:=new_node(hlist_node,min_quarterword);
-box_dir(p):=text_direction;
-new_null_box:=p;
-end;
-
-@ A |vlist_node| is like an |hlist_node| in all respects except that it
-contains a vertical list.
-
-@ 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
-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 null_flag==-@'10000000000 {$-2^{30}$, signifies a missing item}
-@d is_running(#) == (#=null_flag) {tests for a running dimension}
-@d rule_dir(#)==vlink(#+5)
-
-@ A new rule node is delivered by the |new_rule| function. It
-makes all the dimensions ``running,'' so you have to change the
-ones that are not allowed to run.
-
-@p
-function new_rule:pointer;
-var p:pointer; {the new node}
-begin p:=new_node(rule_node,0); {the |subtype| is not used}
-new_rule:=p;
-end;
-
-
-@ Insertions are represented by |ins_node| records, where the |subtype|
-indicates the corresponding box number. For example, `\.{\\insert 250}'
-leads to an |ins_node| whose |subtype| is |250+min_quarterword|.
-The |height| field of an |ins_node| is slightly misnamed; it actually holds
-the natural height plus depth of the vertical list being inserted.
-The |depth| field holds the |split_max_depth| to be used in case this
-insertion is split, and the |split_top_ptr| points to the corresponding
-|split_top_skip|. The |float_cost| field holds the |floating_penalty| that
-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 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}
-
-@ A |mark_node| has a |mark_ptr| field that points to the reference count
-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_ptr(#)==vlink(#+2) {head of the token list for a mark}
-@d mark_class(#)==vinfo(#+2) {the mark class}
-
-@ An |adjust_node|, which occurs only in horizontal lists,
-specifies material that will be moved out into the surrounding
-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_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|}
-@d append_list(#) == begin vlink(tail) := vlink(#); append_list_end
-@d append_list_end(#) == tail := #; end
-
-@ A |glyph_node|, which occurs only in horizontal lists, specifies a
-glyph in a particular font, along with its attribute list. Older
-versions of \TeX\ could use token memory for characters, because the
-font,char combination would fit in a single word (both values were
-required to be strictly less than $2^{16}$). In \LuaTeX, room is
-needed for characters that are larger than that, as well as a pointer
-to a potential attribute list, and the two displacement values.
-
-In turn, that made the node so large that it made sense to merge
-ligature glyphs as well, as that requires only one extra pointer. A
-few extra classes of glyph nodes will be introduced later. The
-unification of all those types makes it easier to manipulate lists of
-glyphs. The subtype differentiates various glyph kinds.
-
-First, here is a function that returns a pointer to a glyph node for a given
-glyph in a given font. If that glyph doesn't exist, |null| is returned
-instead. Nodes of this subtype are directly created only for accents
-and their base (through |make_accent|), and math nucleus items (in the
-conversion from |mlist| to |hlist|).
-
-
-@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|}
-@d lig_ptr(#)==vlink(#+3) {the list of characters for ligature replacements }
-@d lang_data(#)==vinfo(#+3) {language information }
-@d x_displace(#)==vinfo(#+4) { horizontal displacement }
-@d y_displace(#)==vlink(#+4) { vertical displacement }
-
-@p function new_glyph(@!f,@!c:integer):pointer;
-var p:pointer; {the new node}
-begin p:=null;
-if (f=0) or (char_exists(f,c)) then begin
- p:=new_glyph_node;
- set_to_glyph(p); font(p):=f; character(p):=c;
- end;
-new_glyph:=p;
-end;
-
-
-@ A subset of the glyphs nodes represent ligatures: characters
-fabricated from the interaction of two or more actual characters. The
-characters that generated the ligature have not been forgotten, since
-they are needed for diagnostic messages; the |lig_ptr| field points to
-a linked list of character nodes for all original characters that have
-been deleted. (This list might be empty if the characters that
-generated the ligature were retained in other nodes.)
-
-The |subtype| field of these |glyph_node|s is 1, plus 2 and/or 1 if
-the original source of the ligature included implicit left and/or
-right boundaries. These nodes are created by the C function |new_ligkern|.
-
-@ A third general type of glyphs could be called a character, as it
-only appears in lists that are not yet processed by the ligaturing and
-kerning steps of the program.
-
-|main_control| inserts these, and they are later converted to
-|subtype_normal| by |new_ligkern|.
-
-@p function norm_min(@!h:integer):quarterword;
-begin if h<=0 then norm_min:=1@+else if h>=255 then norm_min:=255@+
-else norm_min:=h;
-end;
-@#
-function new_char(@!f,@!c:integer):pointer;
-var p:pointer; {the new node}
-begin p:=new_glyph_node;
-set_to_character(p); font(p):=f; character(p):=c;
-lang_data(p):=make_lang_data(uc_hyph,cur_lang,left_hyphen_min,right_hyphen_min);
-new_char:=p;
-end;
-
-@ Left and right ghost glyph nodes are the result of \.{\\leftghost}
-and \.{\\rightghost}, respectively. They are going to be removed by
-|new_ligkern|, at the end of which they are no longer needed.
-
-@ Here are a few handy helpers used by the list output routines.
-
-@p
-function glyph_width(@!p:halfword):pointer;
-var w:integer;
-begin
- w := char_width(font(p),character(p)); { |+ x_displace(p);| }
- glyph_width := w;
-end;
-@#
-function glyph_height(@!p:halfword):pointer;
-var w:integer;
-begin
- w := char_height(font(p),character(p)) + y_displace(p);
- if w<0 then w:=0;
- glyph_height := w;
-end;
-@#
-function glyph_depth(@!p:halfword):pointer;
-var w:integer;
-begin
- w := char_depth(font(p),character(p));
- if y_displace(p)>0 then w := w - y_displace(p);
- if w<0 then w:=0;
- glyph_depth := w;
-end;
-
-
-@ A |disc_node|, which occurs only in horizontal lists, specifies a
-``dis\-cretion\-ary'' line break. If such a break occurs at node |p|, the text
-that starts at |pre_break(p)| will precede the break, the text that starts at
-|post_break(p)| will follow the break, and text that appears in
-|no_break(p)| nodes will be ignored. For example, an ordinary
-discretionary hyphen, indicated by `\.{\\-}', yields a |disc_node| with
-|pre_break| pointing to a |char_node| containing a hyphen, |post_break=null|,
-and |no_break=null|.
-
-{TODO: Knuth said: All three of the discretionary texts must be lists
-that consist entirely of character, kern, box and rule nodes.}
-
-If |subtype(p)=automatic_disc|, the |ex_hyphen_penalty| will be charged for this
-break. Otherwise the |hyphen_penalty| will be charged. The texts will
-actually be substituted into the list by the line-breaking algorithm if it
-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 automatic_disc=2
-@d syllable_disc=3
-@d disc_type==subtype {the kind of discretionary}
-@d pre_break(#)==vinfo(#+2) {text that precedes a discretionary break}
-@d post_break(#)==vlink(#+2) {text that follows a discretionary break}
-@d no_break(#)==vlink(#+3) {text this discretionary break replaces}
-@d pre_break_head(#)==(#+4)
-@d post_break_head(#)==(#+6)
-@d no_break_head(#)==(#+8)
-@d tlink(#)==vinfo(#+1)
-
-@p function new_disc:pointer; {creates an empty |disc_node|}
-var p:pointer; {the new node}
-begin p:=new_node(disc_node,0);
-new_disc:=p;
-end;
-
-@ A |whatsit_node| is a wild card reserved for extensions to \TeX. The
-|subtype| field in its first word says what `\\{whatsit}' it is, and
-implicitly determines the node size (which must be 2 or more) and the
-format of the remaining words. When a |whatsit_node| is encountered
-in a list, special actions are invoked; knowledgeable people who are
-careful not to mess up the rest of \TeX\ are able to make \TeX\ do new
-things by adding code at the end of the program. For example, there
-might be a `\TeX nicolor' extension to specify different colors of ink,
-@^extensions to \TeX@>
-and the whatsit node might contain the desired parameters.
-
-The present implementation of \TeX\ treats the features associated with
-`\.{\\write}' and `\.{\\special}' as if they were extensions, in order to
-illustrate how such routines might be coded. We shall defer further
-discussion of extensions until the end of this program.
-
-@ 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 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}
-
-@p function new_math(@!w:scaled;@!s:small_number):pointer;
-var p:pointer; {the new node}
-begin p:=new_node(math_node,s);
-surround(p):=w; new_math:=p;
-end;
-
-@ \TeX\ makes use of the fact that |hlist_node|, |vlist_node|,
-|rule_node|, |ins_node|, |mark_node|, |adjust_node|,
-|disc_node|, |whatsit_node|, and |math_node| are at the low end of the
-type codes, by permitting a break at glue in a list if and only if the
-|type| of the previous node is less than |math_node|. Furthermore, a
-node is discarded after a break if its type is |math_node| or~more.
-
-@d precedes_break(#)==(type(#)<math_node)
-@d non_discardable(#)==(type(#)<math_node)
-
-@ A |glue_node| represents glue in a list. However, it is really only
-a pointer to a separate glue specification, since \TeX\ makes use of the
-fact that many essentially identical nodes of glue are usually present.
-If |p| points to a |glue_node|, |glue_ptr(p)| points to
-another packet of words that specify the stretch and shrink components, etc.
-
-Glue nodes also serve to represent leaders; the |subtype| is used to
-distinguish between ordinary glue (which is called |normal|) and the three
-kinds of leaders (which are called |a_leaders|, |c_leaders|, and |x_leaders|).
-The |leader_ptr| field points to a rule node or to a box node containing the
-leaders; it is set to |null| in ordinary glue nodes.
-
-Many kinds of glue are computed from \TeX's ``skip'' parameters, and
-it is helpful to know which parameter has led to a particular glue node.
-Therefore the |subtype| is set to indicate the source of glue, whenever
-it originated as a parameter. We will be defining symbolic names for the
-parameter numbers later (e.g., |line_skip_code=0|, |baseline_skip_code=1|,
-etc.); it suffices for now to say that the |subtype| of parametric glue
-will be the same as the parameter number, plus~one.
-
-In math formulas there are two more possibilities for the |subtype| in a
-glue node: |mu_glue| denotes an \.{\\mskip} (where the units are scaled \.{mu}
-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 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}
-@d c_leaders=101 {|subtype| for centered leaders}
-@d x_leaders=102 {|subtype| for expanded leaders}
-@d glue_ptr(#)==vinfo(#+2) {pointer to a glue specification}
-@d leader_ptr(#)==vlink(#+2) {pointer to box or rule node for leaders}
-
-@ A glue specification has a halfword reference count in its first word,
-@^reference counts@>
-representing |null| plus the number of glue nodes that point to it (less one).
-Note that the reference count appears in the same position as
-the |link| field in list nodes; this is the field that is initialized
-to |null| when a node is allocated, and it is also the field that is flagged
-by |empty_flag| in empty nodes.
-
-Glue specifications also contain three |scaled| fields, for the |width|,
-|stretch|, and |shrink| dimensions. Finally, there are two one-byte
-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_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}
-@d stretch_order(#) == type(#+3) {order of infinity for stretching}
-@d shrink_order(#) == subtype(#+3) {order of infinity for shrinking}
-@d sfi=1 {first-order infinity}
-@d fil=2 {second-order infinity}
-@d fill=3 {third-order infinity}
-@d filll=4 {fourth-order infinity}
-
-@<Types...@>=
-@!glue_ord=normal..filll; {infinity to the 0, 1, 2, 3, or 4 power}
-
-@ Here is a function that returns a pointer to a copy of a glue spec.
-The reference count in the copy is |null|, because there is assumed
-to be exactly one reference to the new specification.
-
-@p function new_spec(@!p:pointer):pointer; {duplicates a glue specification}
-var q:pointer; {the new spec}
-begin q:=copy_node(p);
-glue_ref_count(q):=null;
-new_spec:=q;
-end;
-
-@ And here's a function that creates a glue node for a given parameter
-identified by its code number; for example,
-|new_param_glue(line_skip_code)| returns a pointer to a glue node for the
-current \.{\\lineskip}.
-
-@p function new_param_glue(@!n:small_number):pointer;
-var p:pointer; {the new node}
-@!q:pointer; {the glue specification}
-begin p:=new_node(glue_node,n+1);
-q:=@<Current |mem| equivalent of glue parameter number |n|@>@t@>;
-glue_ptr(p):=q; incr(glue_ref_count(q));
-new_param_glue:=p;
-end;
-
-@ Glue nodes that are more or less anonymous are created by |new_glue|,
-whose argument points to a glue specification.
-
-@p function new_glue(@!q:pointer):pointer;
-var p:pointer; {the new node}
-begin p:=new_node(glue_node,normal);
-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
-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,
-while the parameter will stay put. The global variable |temp_ptr| is
-set to the address of the new spec.
-
-@p function new_skip_param(@!n:small_number):pointer;
-var p:pointer; {the new node}
-begin temp_ptr:=new_spec(@<Current |mem| equivalent of glue parameter...@>);
-p:=new_glue(temp_ptr); glue_ref_count(temp_ptr):=null; subtype(p):=n+1;
-new_skip_param:=p;
-end;
-
-@ A |kern_node| has a |width| field to specify a (normally negative)
-amount of spacing. This spacing correction appears in horizontal lists
-between letters like A and V when the font designer said that it looks
-better to move them closer together or further apart. A kern node can
-also appear in a vertical list, when its `|width|' denotes additional
-spacing in the vertical direction. The |subtype| is either |normal| (for
-kerns inserted from font information or math mode calculations) or |explicit|
-(for kerns inserted from \.{\\kern} and \.{\\/} commands) or |acc_kern|
-(for kerns inserted from non-math accents) or |mu_glue| (for kerns
-inserted from \.{\\mkern} specifications in math formulas).
-
-@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_char(#) == vlink(#+3)
-
-@# {|subtype| of marginal kerns}
-@d left_side == 0
-@d right_side == 1
-
-@# {base for lp/rp/ef codes starts from 2:
- 0 for |hyphen_char|,
- 1 for |skew_char|}
-@d lp_code_base == 2
-@d rp_code_base == 3
-@d ef_code_base == 4
-@d tag_code == 5
-
-@d auto_kern == explicit
-@d no_lig_code == 6
-
-@ The |new_kern| function creates a kern node having a given width.
-
-@p function new_kern(@!w:scaled):pointer;
-var p:pointer; {the new node}
-begin p:=new_node(kern_node,normal);
-width(p):=w;
-new_kern:=p;
-end;
-
-@ A |penalty_node| specifies the penalty associated with line or page
-breaking, in its |penalty| field. This field is a fullword integer, but
-the full range of integer values is not used: Any penalty |>=10000| is
-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 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}
-
-@ Anyone who has been reading the last few sections of the program will
-be able to guess what comes next.
-
-@p function new_penalty(@!m:integer):pointer;
-var p:pointer; {the new node}
-begin p:=new_node(penalty_node,0); {the |subtype| is not used}
-penalty(p):=m; new_penalty:=p;
-end;
-
-@ You might think that we have introduced enough node types by now. Well,
-almost, but there is one more: An |unset_node| has nearly the same format
-as an |hlist_node| or |vlist_node|; it is used for entries in \.{\\halign}
-or \.{\\valign} that are not yet in their final form, since the box
-dimensions are their ``natural'' sizes before any glue adjustment has been
-made. The |glue_set| word is not present; instead, we have a |glue_stretch|
-field, which contains the total stretch of order |glue_order| that is
-present in the hlist or vlist being boxed.
-Similarly, the |shift_amount| field is replaced by a |glue_shrink| field,
-containing the total shrink of order |glue_sign| that is present.
-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 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}
-
-@ In fact, there are still more types coming. When we get to math formula
-processing we will see that a |style_node| has |type=14|; and a number
-of larger type codes will also be defined, for use in math mode only.
-
-@ Warning: If any changes are made to these data structure layouts, such as
-changing any of the node sizes or even reordering the words of nodes,
-the |copy_node_list| procedure and the memory initialization code
-below may have to be changed. Such potentially dangerous parts of the
-program are listed in the index under `data structure assumptions'.
-@!@^data structure assumptions@>
-However, other references to the nodes are made symbolically in terms of
-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}'. 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).
-
-
-@<Glob...@>=
-garbage:pointer; {head of a junk list, write only}
-temp_token_head:pointer; {head of a temporary list of some kind}
-hold_token_head:pointer; {head of a temporary list of another kind}
-omit_template:pointer; {a constant token list}
-null_list:pointer; {permanently empty list}
-backup_head:pointer; {head of token list built by |scan_keyword|}
-
-@ The following code gets |mem| off to a good start, when \TeX\ is
-initializing itself the slow~way.
-
-@<Local variables for init...@>=
-@!k:integer; {index into |mem|, |eqtb|, etc.}
-
-@ @<Initialize table entries...@>=
-procedure init_link_heads;forward;
-init_node_mem(500);
-avail:=null; fix_mem_end:=0;
-init_list_heads;
-@<Initialize the special list heads and constant nodes@>;
-initialize_active;
-dyn_used:=0; {initialize statistics}
-
-@ @p procedure init_list_heads; {initialize token list heads}
-var p:halfword;
-begin
-p:=get_avail; temp_token_head:=p; info(temp_token_head):=0;
-p:=get_avail; hold_token_head:=p; info(hold_token_head):=0;
-p:=get_avail; omit_template:=p; info(omit_template):=0;
-p:=get_avail; null_list:=p; info(null_list):=0;
-p:=get_avail; backup_head:=p; info(backup_head):=0;
-p:=get_avail; garbage:=p; info(garbage):=0;
-end;
-
-@ @p
-@<Declare procedures that need to be declared forward for \pdfTeX@>
-
-@* \[12] Displaying boxes.
-We can reinforce our knowledge of the data structures just introduced
-by considering two procedures that display a list in symbolic form.
-The first of these, called |short_display|, is used in ``overfull box''
-messages to give the top-level description of a list. The other one,
-called |show_node_list|, prints a detailed description of exactly what
-is in the data structure.
-
-The philosophy of |short_display| is to ignore the fine points about exactly
-what is inside boxes, except that ligatures and discretionary breaks are
-expanded. As a result, |short_display| is a recursive procedure, but the
-recursion is never more than one level deep.
-@^recursion@>
-
-A global variable |font_in_short_display| keeps track of the font code that
-is assumed to be present when |short_display| begins; deviations from this
-font will be printed.
-
-@<Glob...@>=
-@!font_in_short_display:integer; {an internal font number}
-
-@ Boxes, rules, inserts, whatsits, marks, and things in general that are
-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
- fonttext := font_id_text(f)
- else
- 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);
- if font_size(f) <> font_dsize(f) then begin
- print("@@");
- print_scaled(font_size(f));
- print("pt");
- end;
- print(")");
- end else
- if pdf_font_expand_ratio(f) <> 0 then begin
- print(" (");
- if pdf_font_expand_ratio(f) > 0 then
- print("+");
- print_int(pdf_font_expand_ratio(f));
- print(")");
- end;
-end;
-
-procedure short_display(@!p:integer); {prints highlights of list |p|}
-begin while p<>null do
- begin if is_char_node(p) then
- begin if lig_ptr(p)<>null then
- short_display(lig_ptr(p))
- else begin
- if font(p)<>font_in_short_display then
- begin if not is_valid_font(font(p)) then
- print_char("*")
-@.*\relax@>
- else print_font_identifier(font(p));
- print_char(" "); font_in_short_display:=font(p);
- end;
- print(qo(character(p)));
- end;
- end
- else @<Print a short indication of the contents of node |p|@>;
- p:=vlink(p);
- end;
-end;
-
-@ @<Print a short indication of the contents of node |p|@>=
-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
-its reference count, and one to print a rule dimension.
-
-@p procedure print_font_and_char(@!p:integer); {prints |char_node| data}
-begin if not is_valid_font(font(p)) then print_char("*")
-@.*\relax@>
- else print_font_identifier(font(p));
- print_char(" "); print(character(p));
-end;
-@#
-procedure print_mark(@!p:integer); {prints token list data in braces}
-begin print_char("{");
-if (p<fix_mem_min)or(p>fix_mem_end) then print_esc("CLOBBERED.")
-else show_token_list(link(p),null,max_print_line-10);
-print_char("}");
-end;
-@#
-procedure print_rule_dimen(@!d:scaled); {prints dimension in rule node}
-begin if is_running(d) then print_char("*") else print_scaled(d);
-@.*\relax@>
-end;
-@#
-procedure print_dir(d:integer);
-begin
-print(dir_names[dir_primary[d]]);
-print(dir_names[dir_secondary[d]]);
-print(dir_names[dir_tertiary[d]]);
-end;
-
-
-@ Then there is a subroutine that prints glue stretch and shrink, possibly
-followed by the name of finite units:
-
-@p procedure print_glue(@!d:scaled;@!order:integer;@!s:str_number);
- {prints a glue component}
-begin print_scaled(d);
-if (order<normal)or(order>filll) then print("foul")
-else if order>normal then
- begin print("fi");
- while order>sfi do
- begin print_char("l"); decr(order);
- end;
- end
-else if s<>0 then print(s);
-end;
-
-@ The next subroutine prints a whole glue specification.
-
-@p procedure print_spec(@!p:integer;@!s:str_number);
- {prints a glue specification}
-begin if p<0 then print_char("*")
-@.*\relax@>
-else begin print_scaled(width(p));
- if s<>0 then print(s);
- if stretch(p)<>0 then
- begin print(" plus "); print_glue(stretch(p),stretch_order(p),s);
- end;
- if shrink(p)<>0 then
- begin print(" minus "); print_glue(shrink(p),shrink_order(p),s);
- end;
- end;
-end;
-
-@ We also need to declare some procedures that appear later in this
-documentation.
-
-@p @<Declare the procedure called |print_skip_param|@>
-
-@ Since boxes can be inside of boxes, |show_node_list| is inherently recursive,
-@^recursion@>
-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.
-
-@ 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
-be given and no sublists will be traversed. Another global variable, called
-|breadth_max|, tells the maximum number of items to show at each level;
-|breadth_max| had better be positive, or you won't see anything.
-
-@<Glob...@>=
-@!depth_threshold : integer; {maximum nesting depth in box displays}
-@!breadth_max : integer; {maximum number of items shown at the same list level}
-
-
-@ The recursive machinery is started by calling |show_box|.
-@^recursion@>
-
-@p procedure show_box(@!p:pointer);
-begin @<Assign the values |depth_threshold:=show_box_depth| and
- |breadth_max:=show_box_breadth|@>;
-if breadth_max<=0 then breadth_max:=5;
-if pool_ptr+depth_threshold>=pool_size then
- depth_threshold:=pool_size-pool_ptr-1;
- {now there's enough room for prefix string}
-show_node_list(p); {the show starts at |p|}
-print_ln;
-end;
-
-@* \[13] Destroying boxes.
-When we are done with a node list, we are obliged to return it to free
-storage, including all of its sublists. The recursive procedure
-|flush_node_list| does this for us.
-
-@ First, however, we shall consider two non-recursive procedures that do
-simpler tasks. The first of these, |delete_token_ref|, is called when
-a pointer to a token list's reference count is being removed. This means
-that the token list should disappear if the reference count was |null|,
-otherwise the count should be decreased by one.
-@^reference counts@>
-
-@d token_ref_count(#) == info(#) {reference count preceding a token list}
-
-@p procedure delete_token_ref(@!p:pointer); {|p| points to the reference count
- of a token list that is losing one reference}
-begin pdfassert(token_ref_count(p)>=0);
-if token_ref_count(p)=0 then flush_list(p)
-else decr(token_ref_count(p));
-end;
-
-@ Similarly, |delete_glue_ref| is called when a pointer to a glue
-specification is being withdrawn.
-@^reference counts@>
-@d fast_delete_glue_ref(#)==@t@>@;@/
- begin if glue_ref_count(#)=null then begin
- flush_node(#);
- end
- else decr(glue_ref_count(#));
- end
-
-@p procedure delete_glue_ref(@!p:pointer); {|p| points to a glue specification}
-begin
- pdfassert(type(p)=glue_spec_node);
- fast_delete_glue_ref(p);
-end;
-
-@ Now we are ready to delete any node list, recursively.
-In practice, the nodes deleted are usually charnodes (about 2/3 of the time),
-and they are glue nodes in about half of the remaining cases.
-@^recursion@>
-
-
-@* \[14] Copying boxes.
-Another recursive operation that acts on boxes is sometimes needed: The
-procedure |copy_node_list| returns a pointer to another node list that has
-the same structure and meaning as the original. Note that since glue
-specifications and token lists have reference counts, we need not make
-copies of them. Reference counts can never get too large to fit in a
-halfword, since each pointer to a node is in a different memory address,
-and the total number of memory addresses fits in a halfword.
-@^recursion@>
-@^reference counts@>
-
-(Well, there actually are also references from outside |mem|; if the
-|save_stack| is made arbitrarily large, it would theoretically be possible
-to break \TeX\ by overflowing a reference count. But who would want to do that?)
-
-@d add_token_ref(#)==incr(token_ref_count(#)) {new reference to a token list}
-@d add_glue_ref(#)==incr(glue_ref_count(#)) {new reference to a glue spec}
-
-@p function tail_of_list (@!p:pointer):pointer;
-var q:pointer;
-begin
- q:=p;
- while vlink(q)<>null do q:=vlink(q);
- tail_of_list:=q;
-end;
-
-@* \[15] The command codes.
-Before we can go any further, we need to define symbolic names for the internal
-code numbers that represent the various commands obeyed by \TeX. These codes
-are somewhat arbitrary, but not completely so. For example, the command
-codes for character types are fixed by the language, since a user says,
-e.g., `\.{\\catcode \`\\\${} = 3}' to make \.{\char'44} a math delimiter,
-and the command code |math_shift| is equal to~3. Some other codes have
-been made adjacent so that |case| statements in the program need not consider
-cases that are widely spaced, or so that |case| statements can be replaced
-by |if| statements.
-
-At any rate, here is the list, for future reference. First come the
-``catcode'' commands, several of which share their numeric codes with
-ordinary commands when the catcode cannot emerge from \TeX's scanning routine.
-
-@d escape=0 {escape delimiter (called \.\\ in {\sl The \TeX book\/})}
-@:TeXbook}{\sl The \TeX book@>
-@d relax=0 {do nothing ( \.{\\relax} )}
-@d left_brace=1 {beginning of a group ( \.\{ )}
-@d right_brace=2 {ending of a group ( \.\} )}
-@d math_shift=3 {mathematics shift character ( \.\$ )}
-@d tab_mark=4 {alignment delimiter ( \.\&, \.{\\span} )}
-@d car_ret=5 {end of line ( |carriage_return|, \.{\\cr}, \.{\\crcr} )}
-@d out_param=5 {output a macro parameter}
-@d mac_param=6 {macro parameter symbol ( \.\# )}
-@d sup_mark=7 {superscript ( \.{\char'136} )}
-@d sub_mark=8 {subscript ( \.{\char'137} )}
-@d ignore=9 {characters to ignore ( \.{\^\^@@} )}
-@d endv=9 {end of \<v_j> list in alignment template}
-@d spacer=10 {characters equivalent to blank space ( \.{\ } )}
-@d letter=11 {characters regarded as letters ( \.{A..Z}, \.{a..z} )}
-@d other_char=12 {none of the special character types}
-@d active_char=13 {characters that invoke macros ( \.{\char`\~} )}
-@d par_end=13 {end of paragraph ( \.{\\par} )}
-@d match=13 {match a macro parameter}
-@d comment=14 {characters that introduce comments ( \.\% )}
-@d end_match=14 {end of parameters to macro}
-@d stop=14 {end of job ( \.{\\end}, \.{\\dump} )}
-@d invalid_char=15 {characters that shouldn't appear ( \.{\^\^?} )}
-@d delim_num=15 {specify delimiter numerically ( \.{\\delimiter} )}
-@d max_char_code=15 {largest catcode for individual characters}
-
-@ Next are the ordinary run-of-the-mill command codes. Codes that are
-|min_internal| or more represent internal quantities that might be
-expanded by `\.{\\the}'.
-
-@d char_num=16 {character specified numerically ( \.{\\char} )}
-@d math_char_num=17 {explicit math code ( \.{\\mathchar} )}
-@d mark=18 {mark definition ( \.{\\mark} )}
-@d xray=19 {peek inside of \TeX\ ( \.{\\show}, \.{\\showbox}, etc.~)}
-@d make_box=20 {make a box ( \.{\\box}, \.{\\copy}, \.{\\hbox}, etc.~)}
-@d hmove=21 {horizontal motion ( \.{\\moveleft}, \.{\\moveright} )}
-@d vmove=22 {vertical motion ( \.{\\raise}, \.{\\lower} )}
-@d un_hbox=23 {unglue a box ( \.{\\unhbox}, \.{\\unhcopy} )}
-@d un_vbox=24 {unglue a box ( \.{\\unvbox}, \.{\\unvcopy} )}
- {( or \.{\\pagediscards}, \.{\\splitdiscards} )}
-@d remove_item=25 {nullify last item ( \.{\\unpenalty},
- \.{\\unkern}, \.{\\unskip} )}
-@d hskip=26 {horizontal glue ( \.{\\hskip}, \.{\\hfil}, etc.~)}
-@d vskip=27 {vertical glue ( \.{\\vskip}, \.{\\vfil}, etc.~)}
-@d mskip=28 {math glue ( \.{\\mskip} )}
-@d kern=29 {fixed space ( \.{\\kern})}
-@d mkern=30 {math kern ( \.{\\mkern} )}
-@d leader_ship=31 {use a box ( \.{\\shipout}, \.{\\leaders}, etc.~)}
-@d halign=32 {horizontal table alignment ( \.{\\halign} )}
-@d valign=33 {vertical table alignment ( \.{\\valign} )}
-@d no_align=34 {temporary escape from alignment ( \.{\\noalign} )}
-@d vrule=35 {vertical rule ( \.{\\vrule} )}
-@d hrule=36 {horizontal rule ( \.{\\hrule} )}
-@d insert=37 {vlist inserted in box ( \.{\\insert} )}
-@d vadjust=38 {vlist inserted in enclosing paragraph ( \.{\\vadjust} )}
-@d ignore_spaces=39 {gobble |spacer| tokens ( \.{\\ignorespaces} )}
-@d after_assignment=40 {save till assignment is done ( \.{\\afterassignment} )}
-@d after_group=41 {save till group is done ( \.{\\aftergroup} )}
-@d break_penalty=42 {additional badness ( \.{\\penalty} )}
-@d start_par=43 {begin paragraph ( \.{\\indent}, \.{\\noindent} )}
-@d ital_corr=44 {italic correction ( \.{\\/} )}
-@d accent=45 {attach accent in text ( \.{\\accent} )}
-@d math_accent=46 {attach accent in math ( \.{\\mathaccent} )}
-@d discretionary=47 {discretionary texts ( \.{\\-}, \.{\\discretionary} )}
-@d eq_no=48 {equation number ( \.{\\eqno}, \.{\\leqno} )}
-@d left_right=49 {variable delimiter ( \.{\\left}, \.{\\right} )}
- {( or \.{\\middle} )}
-@d math_comp=50 {component of formula ( \.{\\mathbin}, etc.~)}
-@d limit_switch=51 {diddle limit conventions ( \.{\\displaylimits}, etc.~)}
-@d above=52 {generalized fraction ( \.{\\above}, \.{\\atop}, etc.~)}
-@d math_style=53 {style specification ( \.{\\displaystyle}, etc.~)}
-@d math_choice=54 {choice specification ( \.{\\mathchoice}, \.{\\Ustack} )}
-@d non_script=55 {conditional math glue ( \.{\\nonscript} )}
-@d vcenter=56 {vertically center a vbox ( \.{\\vcenter} )}
-@d case_shift=57 {force specific case ( \.{\\lowercase}, \.{\\uppercase}~)}
-@d message=58 {send to user ( \.{\\message}, \.{\\errmessage} )}
-@d extension=59 {extensions to \TeX\ ( \.{\\write}, \.{\\special}, etc.~)}
-@d in_stream=60 {files for reading ( \.{\\openin}, \.{\\closein} )}
-@d begin_group=61 {begin local grouping ( \.{\\begingroup} )}
-@d end_group=62 {end local grouping ( \.{\\endgroup} )}
-@d omit=63 {omit alignment template ( \.{\\omit} )}
-@d ex_space=64 {explicit space ( \.{\\\ } )}
-@d no_boundary=65 {suppress boundary ligatures ( \.{\\noboundary} )}
-@d radical=66 {square root and similar signs ( \.{\\radical} )}
-@d super_sub_script=67 {explicit super ( \.{\\Usuperscript} ) or subscript ( \.{\\Usubscript} )}
-@d math_shift_cs=68 {explicit math switch ( \.{\\Ustartmath}, etc.~)}
-@d end_cs_name=69 {end control sequence ( \.{\\endcsname} )}
-@d char_ghost=end_cs_name+1
- {\.{\\ghostleft}, \.{\\ghostright} character for kerning}
-@d assign_local_box=char_ghost+1
- {box for guillemets \.{\\localleftbox} or \.{\\localrightbox}}
-@d min_internal=assign_local_box+1 {the smallest code that can follow \.{\\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 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}}
-
-@ The next codes are special; they all relate to mode-independent
-assignment of values to \TeX's internal registers or tables.
-Codes that are |max_internal| or less represent internal quantities
-that might be expanded by `\.{\\the}'.
-
-There is no matching primitive to go with |assign_attr|, but even if
-there was no \.{\\attributedef}, a reserved number would still be
-needed because there is an implied correspondence between the
-|assign_xxx| commands and |xxx_val| expression values. That would
-break down otherwise.
-
-@d toks_register=max_non_prefixed_command+1
- {token list register ( \.{\\toks} )}
-@d assign_toks=toks_register+1
- {special token list ( \.{\\output}, \.{\\everypar}, etc.~)}
-@d assign_int=assign_toks+1
- {user-defined integer ( \.{\\tolerance}, \.{\\day}, etc.~)}
-@d assign_attr=assign_int+1 { user-defined attributes }
-@d assign_dimen=assign_attr+1
- {user-defined length ( \.{\\hsize}, etc.~)}
-@d assign_glue=assign_dimen+1
- {user-defined glue ( \.{\\baselineskip}, etc.~)}
-@d assign_mu_glue=assign_glue+1
- {user-defined muglue ( \.{\\thinmuskip}, etc.~)}
-@d assign_font_dimen=assign_mu_glue+1
- {user-defined font dimension ( \.{\\fontdimen} )}
-@d assign_font_int=assign_font_dimen+1
- {user-defined font integer ( \.{\\hyphenchar}, \.{\\skewchar} )}
-@d set_aux=assign_font_int+1
- {specify state info ( \.{\\spacefactor}, \.{\\prevdepth} )}
-@d set_prev_graf=set_aux+1
- {specify state info ( \.{\\prevgraf} )}
-@d set_page_dimen=set_prev_graf+1
- {specify state info ( \.{\\pagegoal}, etc.~)}
-@d set_page_int=set_page_dimen+1
- {specify state info ( \.{\\deadcycles},
- \.{\\insertpenalties} )}
-@d set_box_dimen=set_page_int+1
- {change dimension of box ( \.{\\wd}, \.{\\ht}, \.{\\dp} )}
-@d set_tex_shape=set_box_dimen+1
- {specify fancy paragraph shape ( \.{\\parshape} )}
-@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 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 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_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}, \.{\\bodydir}, \.{\\pardir}, \.{\\textdir}), \.{\\mathdir}}
-@d max_internal=assign_dir
- {the largest code that can follow \.{\\the}}
-@d advance=max_internal+1
- {advance a register or parameter ( \.{\\advance} )}
-@d multiply=advance+1
- {multiply a register or parameter ( \.{\\multiply} )}
-@d divide=multiply+1
- {divide a register or parameter ( \.{\\divide} )}
-@d prefix=divide+1
- {qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} )}
-@d let=prefix+1
- {assign a command code ( \.{\\let}, \.{\\futurelet} )}
-@d shorthand_def=let+1
- {code definition ( \.{\\chardef}, \.{\\countdef}, etc.~)}
-@d read_to_cs=shorthand_def+1
- {read into a control sequence ( \.{\\read} )}
-@d def=read_to_cs+1
- {macro definition ( \.{\\def}, \.{\\gdef}, \.{\\xdef}, \.{\\edef} )}
-@d set_box=def+1
- {set a box ( \.{\\setbox} )}
-@d hyph_data=set_box+1
- {hyphenation data ( \.{\\hyphenation}, \.{\\patterns} )}
-@d set_interaction=hyph_data+1
- {define level of interaction ( \.{\\batchmode}, etc.~)}
-@d letterspace_font=set_interaction+1
- {letterspace a font ( \.{\\letterspacefont} )}
-@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}
-@d set_ocp_list=def_ocp+1
- {Place a list of OCPs in the stream}
-@d def_ocp_list=set_ocp_list+1
- {Define a list of OCPs}
-@d clear_ocp_lists=def_ocp_list+1
- {Remove all active OCP lists}
-@d push_ocp_list=clear_ocp_lists+1
- {Add to the sequence of active OCP lists}
-@d pop_ocp_list=push_ocp_list+1
- {Remove from the sequence of active OCP lists}
-@d ocp_list_op=pop_ocp_list+1
- {Operations for building a list of OCPs}
-@d ocp_trace_level=ocp_list_op+1
- {Tracing of active OCPs, either 0 or 1}
-@d max_command=ocp_trace_level
- {the largest command code seen at |big_switch|}
-
-@ The remaining command codes are extra special, since they cannot get through
-\TeX's scanner to the main control routine. They have been given values higher
-than |max_command| so that their special nature is easily discernible.
-The ``expandable'' commands come first.
-
-@d undefined_cs=max_command+1 {initial state of most |eq_type| fields}
-@d expand_after=max_command+2 {special expansion ( \.{\\expandafter} )}
-@d no_expand=max_command+3 {special nonexpansion ( \.{\\noexpand} )}
-@d input=max_command+4 {input a source file ( \.{\\input}, \.{\\endinput} )}
- {( or \.{\\scantokens} or \.{\\scantextokens} )}
-@d if_test=max_command+5 {conditional text ( \.{\\if}, \.{\\ifcase}, etc.~)}
-@d fi_or_else=max_command+6 {delimiters for conditionals ( \.{\\else}, etc.~)}
-@d cs_name=max_command+7 {make a control sequence from tokens ( \.{\\csname} )}
-@d convert=max_command+8 {convert to text ( \.{\\number}, \.{\\string}, etc.~)}
-@d the=max_command+9 {expand an internal quantity ( \.{\\the} )}
- {( or \.{\\unexpanded}, \.{\\detokenize} )}
-@d top_bot_mark=max_command+10 {inserted mark ( \.{\\topmark}, etc.~)}
-@d call=max_command+11 {non-long, non-outer control sequence}
-@d long_call=max_command+12 {long, non-outer control sequence}
-@d outer_call=max_command+13 {non-long, outer control sequence}
-@d long_outer_call=max_command+14 {long, outer control sequence}
-@d end_template=max_command+15 {end of an alignment template}
-@d dont_expand=max_command+16 {the following token was marked by \.{\\noexpand}}
-@d glue_ref=max_command+17 {the equivalent points to a glue specification}
-@d shape_ref=max_command+18 {the equivalent points to a parshape specification}
-@d box_ref=max_command+19 {the equivalent points to a box node, or is |null|}
-@d data=max_command+20 {the equivalent is simply a halfword number}
-
-@* \[16] The semantic nest.
-\TeX\ is typically in the midst of building many lists at once. For example,
-when a math formula is being processed, \TeX\ is in math mode and
-working on an mlist; this formula has temporarily interrupted \TeX\ from
-being in horizontal mode and building the hlist of a paragraph; and this
-paragraph has temporarily interrupted \TeX\ from being in vertical mode
-and building the vlist for the next page of a document. Similarly, when a
-\.{\\vbox} occurs inside of an \.{\\hbox}, \TeX\ is temporarily
-interrupted from working in restricted horizontal mode, and it enters
-internal vertical mode. The ``semantic nest'' is a stack that
-keeps track of what lists and modes are currently suspended.
-
-At each level of processing we are in one of six modes:
-
-\yskip\hang|vmode| stands for vertical mode (the page builder);
-
-\hang|hmode| stands for horizontal mode (the paragraph builder);
-
-\hang|mmode| stands for displayed formula mode;
-
-\hang|-vmode| stands for internal vertical mode (e.g., in a \.{\\vbox});
-
-\hang|-hmode| stands for restricted horizontal mode (e.g., in an \.{\\hbox});
-
-\hang|-mmode| stands for math formula mode (not displayed).
-
-\yskip\noindent The mode is temporarily set to zero while processing \.{\\write}
-texts in the |ship_out| routine.
-
-Numeric values are assigned to |vmode|, |hmode|, and |mmode| so that
-\TeX's ``big semantic switch'' can select the appropriate thing to
-do by computing the value |abs(mode)+cur_cmd|, where |mode| is the current
-mode and |cur_cmd| is the current command code.
-
-@d vmode=1 {vertical mode}
-@d hmode=vmode+max_command+1 {horizontal mode}
-@d mmode=hmode+max_command+1 {math mode}
-
-@p procedure print_mode(@!m:integer); {prints the mode represented by |m|}
-begin if m>0 then
- case m div (max_command+1) of
- 0:print("vertical");
- 1:print("horizontal");
- 2:print("display math");
- end
-else if m=0 then print("no")
-else case (-m) div (max_command+1) of
- 0:print("internal vertical");
- 1:print("restricted horizontal");
- 2:print("math");
- end;
-print(" mode");
-end;
-function get_mode_id:integer; {returns the mode represented by |m|}
-var m:integer ;
-begin
- m := mode;
- if m>0 then
- case m div (max_command+1) of
- 0:get_mode_id := "v";
- 1:get_mode_id := "h";
- 2:get_mode_id := "m";
- othercases get_mode_id := "";
- end
-else if m=0 then get_mode_id := "n"
-else case (-m) div (max_command+1) of
- 0:get_mode_id := "V";
- 1:get_mode_id := "H";
- 2:get_mode_id := "M";
- othercases get_mode_id := "";
- end;
-end;
-
-@ The state of affairs at any semantic level can be represented by
-five values:
-
-\yskip\hang|mode| is the number representing the semantic mode, as
-just explained.
-
-\yskip\hang|head| is a |pointer| to a list head for the list being built;
-|link(head)| therefore points to the first element of the list, or
-to |null| if the list is empty.
-
-\yskip\hang|tail| is a |pointer| to the final node of the list being
-built; thus, |tail=head| if and only if the list is empty.
-
-\yskip\hang|prev_graf| is the number of lines of the current paragraph that
-have already been put into the present vertical list.
-
-\yskip\hang|aux| is an auxiliary |memory_word| that gives further information
-that is needed to characterize the situation.
-
-\yskip\noindent
-In vertical mode, |aux| is also known as |prev_depth|; it is the scaled
-value representing the depth of the previous box, for use in baseline
-calculations, or it is |<=-1000|pt if the next box on the vertical list is to
-be exempt from baseline calculations. In horizontal mode, |aux| is also
-known as |space_factor|; it holds the current space factor used in
-spacing calculations. In math mode, |aux| is also known as |incompleat_noad|;
-if not |null|, it points to a record that represents the numerator of a
-generalized fraction for which the denominator is currently being formed
-in the current list.
-
-There is also a sixth quantity, |mode_line|, which correlates
-the semantic nest with the user's input; |mode_line| contains the source
-line number at which the current level of nesting was entered. The negative
-of this line number is the |mode_line| at the level of the
-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 |fence_noad| of a |math_left_group|.
-
-In horizontal mode, the |prev_graf| field is used for initial language data.
-
-The semantic nest is an array called |nest| that holds the |mode|, |head|,
-|tail|, |prev_graf|, |aux|, and |mode_line| values for all semantic levels
-below the currently active one. Information about the currently active
-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.
-
-The math field is used by various bits and pieces in |math.c|
-
-@d ignore_depth==-65536000 {magic dimension value to mean `ignore me'}
-
-@<Types...@>=
-@!list_state_record=record@!mode_field:-mmode..mmode;@+
- @!head_field,@!tail_field: pointer;
- @!eTeX_aux_field: pointer;
- @!pg_field,@!ml_field: integer;@+
- @!aux_field: memory_word;
- @!dirs_field: halfword;
- @!math_field: integer;
- @!math_style_field: integer;
- end;
-
-@ @d mode==cur_list.mode_field {current mode}
-@d head==cur_list.head_field {header node of current list}
-@d tail==cur_list.tail_field {final node on current list}
-@d eTeX_aux==cur_list.eTeX_aux_field {auxiliary data for \eTeX}
-@d prev_graf==cur_list.pg_field {number of paragraph lines accumulated}
-@d aux==cur_list.aux_field {auxiliary data about the current list}
-@d prev_depth==aux.sc {the name of |aux| in vertical mode}
-@d space_factor==aux.hh.lh {part of |aux| in horizontal mode}
-@d incompleat_noad==aux.int {the name of |aux| in math mode}
-@d mode_line==cur_list.ml_field {source file line number at beginning of list}
-@d dir_save==cur_list.dirs_field {dir stack when a paragraph is interrupted}
-
-@<Glob...@>=
-@!nest:array[0..nest_size] of list_state_record;
-@!nest_ptr:0..nest_size; {first unused location of |nest|}
-@!max_nest_stack:0..nest_size; {maximum of |nest_ptr| when pushing}
-@!cur_list:list_state_record; {the ``top'' semantic state}
-@!shown_mode:-mmode..mmode; {most recent mode shown by \.{\\tracingcommands}}
-@!save_tail: pointer; {save |tail| so we can examine whether we have an auto
- kern before a glue}
-
-@ Here is a common way to make the current list grow:
-
-@p
-procedure tail_append(p:pointer);
-begin
-vlink(tail):=p; tail:=vlink(tail);
-end;
-@#
-procedure new_tail_append(p:pointer);
-begin
-couple_nodes(tail,p); tail:=vlink(tail);
-end;
-@#
-function pop_tail:pointer;
-label exit;
-var n,r:pointer;
-begin
- if tail<>head then begin
- r:=tail;
- if vlink(alink(tail))=tail then
- n:=alink(tail)
- else begin
- n:=head;
- while vlink(n)<>tail do n:=vlink(n);
- end;
- flush_node(tail);
- tail:=n;
- vlink(n):=null;
- pop_tail:=r;
- end
- else
- pop_tail:=null;
-exit:end;
-
-
-@ We will see later that the vertical list at the bottom semantic level is split
-into two parts; the ``current page'' runs from |page_head| to |page_tail|,
-and the ``contribution list'' runs from |contrib_head| to |tail| of
-semantic level zero. The idea is that contributions are first formed in
-vertical mode, then ``contributed'' to the current page (during which time
-the page-breaking decisions are made). For now, we don't need to know
-any more details about the page-building process.
-
-@<Set init...@>=
-nest_ptr:=0; max_nest_stack:=0;
-mode:=vmode; head:=contrib_head; tail:=contrib_head;
-eTeX_aux:=null;
-prev_depth:=ignore_depth; mode_line:=0;
-prev_graf:=0; shown_mode:=0;
-dir_save:=null; init_math_fields;
-@<Start a new current page@>;
-
-@ @p @<LOCAL: Declare |make_local_par_node|@>;
-
-@ @p @<DIR: Declare |new_dir|@>;
-
-@ When \TeX's work on one level is interrupted, the state is saved by
-calling |push_nest|. This routine changes |head| and |tail| so that
-a new (empty) list is begun; it does not change |mode| or |aux|.
-
-@p procedure push_nest; {enter a new semantic level, save the old}
-begin if nest_ptr>max_nest_stack then
- begin max_nest_stack:=nest_ptr;
- if nest_ptr=nest_size then overflow("semantic nest size",nest_size);
-@:TeX capacity exceeded semantic nest size}{\quad semantic nest size@>
- end;
-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; init_math_fields;
-eTeX_aux:=null;
-end;
-
-@ Conversely, when \TeX\ is finished on the current level, the former
-state is restored by calling |pop_nest|. This routine will never be
-called at the lowest semantic level, nor will it be called unless |head|
-is a node that should be returned to free memory.
-
-@p procedure pop_nest; {leave a semantic level, re-enter the old}
-begin
-flush_node(head); decr(nest_ptr); cur_list:=nest[nest_ptr];
-end;
-
-@ Here is a procedure that displays what \TeX\ is working on, at all levels.
-
-@p procedure@?print_totals; forward;@t\2@>
-procedure show_activities;
-var p:0..nest_size; {index into |nest|}
-@!m:-mmode..mmode; {mode}
-@!a:memory_word; {auxiliary}
-@!q,@!r:pointer; {for showing the current page}
-@!t:integer; {ditto}
-begin nest[nest_ptr]:=cur_list; {put the top level into the array}
-print_nl(""); print_ln;
-for p:=nest_ptr downto 0 do
- begin m:=nest[p].mode_field; a:=nest[p].aux_field;
- print_nl("### "); print_mode(m);
- print(" entered at line "); print_int(abs(nest[p].ml_field));
- if m=hmode then if nest[p].pg_field <> @'40600000 then
- begin print(" (language"); print_int(nest[p].pg_field mod @'200000);
- print(":hyphenmin"); print_int(nest[p].pg_field div @'20000000);
- print_char(","); print_int((nest[p].pg_field div @'200000) mod @'100);
- print_char(")");
- end;
- if nest[p].ml_field<0 then print(" (\output routine)");
- if p=0 then
- begin @<Show the status of the current page@>;
- if vlink(contrib_head)<>null then
- print_nl("### recent contributions:");
- end;
- show_box(vlink(nest[p].head_field));
- @<Show the auxiliary field, |a|@>;
- end;
-end;
-
-@ @<Show the auxiliary...@>=
-case abs(m) div (max_command+1) of
-0: begin print_nl("prevdepth ");
- if a.sc<=pdf_ignored_dimen then print("ignored")
- else print_scaled(a.sc);
- if nest[p].pg_field<>0 then
- begin print(", prevgraf ");
- print_int(nest[p].pg_field); print(" line");
- if nest[p].pg_field<>1 then print_char("s");
- end;
- end;
-1: begin print_nl("spacefactor "); print_int(a.hh.lh);
- if m>0 then@+ if a.hh.rh>0 then
- begin print(", current language "); print_int(a.hh.rh);@+
- end;
- end;
-2: if a.int<>null then
- begin print("this will be denominator of:"); show_box(a.int);@+
- end;
-end {there are no other cases}
-
-@* \[17] The table of equivalents.
-Now that we have studied the data structures for \TeX's semantic routines,
-we ought to consider the data structures used by its syntactic routines. In
-other words, our next concern will be
-the tables that \TeX\ looks at when it is scanning
-what the user has written.
-
-The biggest and most important such table is called |eqtb|. It holds the
-current ``equivalents'' of things; i.e., it explains what things mean
-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[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 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.
-
-\yskip\hangg 4) |eqtb[local_base..(int_base-1)]| holds the current
-equivalents of local halfword quantities like the current box registers,
-the current ``catcodes,'' the current font, and a pointer to the current
-paragraph shape.
-
-\yskip\hangg 5) |eqtb[int_base..(dimen_base-1)]| holds the current
-equivalents of fullword integer parameters like the current hyphenation
-penalty.
-
-\yskip\hangg 6) |eqtb[dimen_base..eqtb_size]| holds the current equivalents
-of fullword dimension parameters like the current hsize or amount of
-hanging indentation.
-
-\yskip\noindent Note that, for example, the current amount of
-baselineskip glue is determined by the setting of a particular location
-in region~3 of |eqtb|, while the current meaning of the control sequence
-`\.{\\baselineskip}' (which might have been changed by \.{\\def} or
-\.{\\let}) appears in region~2.
-
-@ Each entry in |eqtb| is a |memory_word|. Most of these words are of type
-|two_halves|, and subdivided into three fields:
-
-\yskip\hangg 1) The |eq_level| (a quarterword) is the level of grouping at
-which this equivalent was defined. If the level is |level_zero|, the
-equivalent has never been defined; |level_one| refers to the outer level
-(outside of all groups), and this level is also used for global
-definitions that never go away. Higher levels are for equivalents that
-will disappear at the end of their group. @^global definitions@>
-
-\yskip\hangg 2) The |eq_type| (another quarterword) specifies what kind of
-entry this is. There are many types, since each \TeX\ primitive like
-\.{\\hbox}, \.{\\def}, etc., has its own special code. The list of
-command codes above includes all possible settings of the |eq_type| field.
-
-\yskip\hangg 3) The |equiv| (a halfword) is the current equivalent value.
-This may be a font number, a pointer into |mem|, or a variety of other
-things.
-
-@d eq_level_field(#)==#.hh.b1
-@d eq_type_field(#)==#.hh.b0
-@d equiv_field(#)==#.hh.rh
-@d eq_level(#)==eq_level_field(eqtb[#]) {level of definition}
-@d eq_type(#)==eq_type_field(eqtb[#]) {command code for equivalent}
-@d equiv(#)==equiv_field(eqtb[#]) {equivalent value}
-@d level_zero=min_quarterword {level for undefined quantities}
-@d level_one=level_zero+1 {outermost level for defined quantities}
-
-@ Many locations in |eqtb| have symbolic names. The purpose of the next
-paragraphs is to define these names, and to set up the initial values of the
-equivalents.
-
-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
-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 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}
-@d frozen_cr=frozen_control_sequence+1 {permanent `\.{\\cr}'}
-@d frozen_end_group=frozen_control_sequence+2 {permanent `\.{\\endgroup}'}
-@d frozen_right=frozen_control_sequence+3 {permanent `\.{\\right}'}
-@d frozen_fi=frozen_control_sequence+4 {permanent `\.{\\fi}'}
-@d frozen_end_template=frozen_control_sequence+5 {permanent `\.{\\endtemplate}'}
-@d frozen_endv=frozen_control_sequence+6 {second permanent `\.{\\endtemplate}'}
-@d frozen_relax=frozen_control_sequence+7 {permanent `\.{\\relax}'}
-@d end_write=frozen_control_sequence+8 {permanent `\.{\\endwrite}'}
-@d frozen_dont_expand=frozen_control_sequence+9
- {permanent `\.{\\notexpanded:}'}
-@d frozen_primitive=frozen_control_sequence+11
- {permanent `\.{\\pdfprimitive}'}
-@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}
-@d frozen_null_ocp=frozen_null_font+number_fonts
- {permanent `\.{\\nullocp}'}
-@d ocp_id_base=frozen_null_ocp-ocp_base
- {begins table of |number_ocps| permanent ocp identifiers}
-@d frozen_null_ocp_list=frozen_null_ocp+number_ocps
- {permanent `\.{\\nullocplist}'}
-@d ocp_list_id_base=frozen_null_ocp_list-ocp_list_base
- {begins table of |number_ocp_lists| permanent ocp list identifiers}
-@d undefined_control_sequence=frozen_null_ocp_list+number_ocp_lists
-@d glue_base=undefined_control_sequence+1 {beginning of region 3}
-
-@<Initialize table entries...@>=
-eq_type(undefined_control_sequence):=undefined_cs;
-equiv(undefined_control_sequence):=null;
-eq_level(undefined_control_sequence):=level_zero;
-for k:=null_cs to undefined_control_sequence-1 do
- eqtb[k]:=eqtb[undefined_control_sequence];
-
-@ Create a C version of |undefined_control_sequence|.
-
-@<Global...@>=
-@!static_undefined_control_sequence:integer;
-
-@ @<Set init...@>=
-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.)
-
-@<Show equivalent |n|, in region 1 or 2@>=
-begin sprint_cs(n); print_char("="); print_cmd_chr(eq_type(n),equiv(n));
-if eq_type(n)>=call then
- begin print_char(":"); show_token_list(link(equiv(n)),null,32);
- end;
-end
-
-@ Region 3 of |eqtb| contains the |number_regs| \.{\\skip} registers, as well as the
-glue parameters defined here. It is important that the ``muskip''
-parameters have larger numbers than the others.
-
-@d line_skip_code=0 {interline glue if |baseline_skip| is infeasible}
-@d baseline_skip_code=1 {desired glue between baselines}
-@d par_skip_code=2 {extra glue just above a paragraph}
-@d above_display_skip_code=3 {extra glue just above displayed math}
-@d below_display_skip_code=4 {extra glue just below displayed math}
-@d above_display_short_skip_code=5
- {glue above displayed math following short lines}
-@d below_display_short_skip_code=6
- {glue below displayed math following short lines}
-@d left_skip_code=7 {glue at left of justified lines}
-@d right_skip_code=8 {glue at right of justified lines}
-@d top_skip_code=9 {glue at top of main pages}
-@d split_top_skip_code=10 {glue at top of split pages}
-@d tab_skip_code=11 {glue between aligned entries}
-@d space_skip_code=12 {glue between words (if not |zero_glue|)}
-@d xspace_skip_code=13 {glue after sentences (if not |zero_glue|)}
-@d par_fill_skip_code=14 {glue on last line of paragraph}
-@d thin_mu_skip_code=15 {thin space in math formula}
-@d med_mu_skip_code=16 {medium space in math formula}
-@d thick_mu_skip_code=17 {thick space in math formula}
-@d glue_pars=18 {total number of glue parameters}
-@d skip_base=glue_base+glue_pars {table of |number_regs| ``skip'' registers}
-@d mu_skip_base=skip_base+number_regs {table of |number_regs| ``muskip'' registers}
-@d local_base=mu_skip_base+number_regs {beginning of region 4}
-@#
-@d skip(#)==equiv(skip_base+#) {|mem| location of glue specification}
-@d mu_skip(#)==equiv(mu_skip_base+#) {|mem| location of math glue spec}
-@d glue_par(#)==equiv(glue_base+#) {|mem| location of glue specification}
-@d line_skip==glue_par(line_skip_code)
-@d baseline_skip==glue_par(baseline_skip_code)
-@d par_skip==glue_par(par_skip_code)
-@d above_display_skip==glue_par(above_display_skip_code)
-@d below_display_skip==glue_par(below_display_skip_code)
-@d above_display_short_skip==glue_par(above_display_short_skip_code)
-@d below_display_short_skip==glue_par(below_display_short_skip_code)
-@d left_skip==glue_par(left_skip_code)
-@d right_skip==glue_par(right_skip_code)
-@d top_skip==glue_par(top_skip_code)
-@d split_top_skip==glue_par(split_top_skip_code)
-@d tab_skip==glue_par(tab_skip_code)
-@d space_skip==glue_par(space_skip_code)
-@d xspace_skip==glue_par(xspace_skip_code)
-@d par_fill_skip==glue_par(par_fill_skip_code)
-@d thin_mu_skip==glue_par(thin_mu_skip_code)
-@d med_mu_skip==glue_par(med_mu_skip_code)
-@d thick_mu_skip==glue_par(thick_mu_skip_code)
-
-@<Current |mem| equivalent of glue parameter number |n|@>=glue_par(n)
-
-@ @<Set init...@>=
-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.
-
-@<Declare the procedure called |print_skip_param|@>=
-procedure print_skip_param(@!n:integer);
-begin case n of
-line_skip_code: print_esc("lineskip");
-baseline_skip_code: print_esc("baselineskip");
-par_skip_code: print_esc("parskip");
-above_display_skip_code: print_esc("abovedisplayskip");
-below_display_skip_code: print_esc("belowdisplayskip");
-above_display_short_skip_code: print_esc("abovedisplayshortskip");
-below_display_short_skip_code: print_esc("belowdisplayshortskip");
-left_skip_code: print_esc("leftskip");
-right_skip_code: print_esc("rightskip");
-top_skip_code: print_esc("topskip");
-split_top_skip_code: print_esc("splittopskip");
-tab_skip_code: print_esc("tabskip");
-space_skip_code: print_esc("spaceskip");
-xspace_skip_code: print_esc("xspaceskip");
-par_fill_skip_code: print_esc("parfillskip");
-thin_mu_skip_code: print_esc("thinmuskip");
-med_mu_skip_code: print_esc("medmuskip");
-thick_mu_skip_code: print_esc("thickmuskip");
-othercases print("[unknown glue parameter!]")
-endcases;
-end;
-
-@ The symbolic names for glue parameters are put into \TeX's hash table
-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.
-
-@<Put each of \TeX's primitives into the hash table@>=
-primitive_tex("lineskip",assign_glue,glue_base+line_skip_code,glue_base);@/
-@!@:line_skip_}{\.{\\lineskip} primitive@>
-primitive_tex("baselineskip",assign_glue,glue_base+baseline_skip_code,glue_base);@/
-@!@:baseline_skip_}{\.{\\baselineskip} primitive@>
-primitive_tex("parskip",assign_glue,glue_base+par_skip_code,glue_base);@/
-@!@:par_skip_}{\.{\\parskip} primitive@>
-primitive_tex("abovedisplayskip",assign_glue,glue_base+above_display_skip_code,glue_base);@/
-@!@:above_display_skip_}{\.{\\abovedisplayskip} primitive@>
-primitive_tex("belowdisplayskip",assign_glue,glue_base+below_display_skip_code,glue_base);@/
-@!@:below_display_skip_}{\.{\\belowdisplayskip} primitive@>
-primitive_tex("abovedisplayshortskip",assign_glue,glue_base+above_display_short_skip_code,glue_base);@/
-@!@:above_display_short_skip_}{\.{\\abovedisplayshortskip} primitive@>
-primitive_tex("belowdisplayshortskip",assign_glue,glue_base+below_display_short_skip_code,glue_base);@/
-@!@:below_display_short_skip_}{\.{\\belowdisplayshortskip} primitive@>
-primitive_tex("leftskip",assign_glue,glue_base+left_skip_code,glue_base);@/
-@!@:left_skip_}{\.{\\leftskip} primitive@>
-primitive_tex("rightskip",assign_glue,glue_base+right_skip_code,glue_base);@/
-@!@:right_skip_}{\.{\\rightskip} primitive@>
-primitive_tex("topskip",assign_glue,glue_base+top_skip_code,glue_base);@/
-@!@:top_skip_}{\.{\\topskip} primitive@>
-primitive_tex("splittopskip",assign_glue,glue_base+split_top_skip_code,glue_base);@/
-@!@:split_top_skip_}{\.{\\splittopskip} primitive@>
-primitive_tex("tabskip",assign_glue,glue_base+tab_skip_code,glue_base);@/
-@!@:tab_skip_}{\.{\\tabskip} primitive@>
-primitive_tex("spaceskip",assign_glue,glue_base+space_skip_code,glue_base);@/
-@!@:space_skip_}{\.{\\spaceskip} primitive@>
-primitive_tex("xspaceskip",assign_glue,glue_base+xspace_skip_code,glue_base);@/
-@!@:xspace_skip_}{\.{\\xspaceskip} primitive@>
-primitive_tex("parfillskip",assign_glue,glue_base+par_fill_skip_code,glue_base);@/
-@!@:par_fill_skip_}{\.{\\parfillskip} primitive@>
-primitive_tex("thinmuskip",assign_mu_glue,glue_base+thin_mu_skip_code,glue_base+thin_mu_skip_code);@/
-@!@:thin_mu_skip_}{\.{\\thinmuskip} primitive@>
-primitive_tex("medmuskip",assign_mu_glue,glue_base+med_mu_skip_code,glue_base+thin_mu_skip_code);@/
-@!@:med_mu_skip_}{\.{\\medmuskip} primitive@>
-primitive_tex("thickmuskip",assign_mu_glue,glue_base+thick_mu_skip_code,glue_base+thin_mu_skip_code);@/
-@!@:thick_mu_skip_}{\.{\\thickmuskip} primitive@>
-
-@ All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'.
-
-@<Initialize table entries...@>=
-equiv(glue_base):=zero_glue; eq_level(glue_base):=level_one;
-eq_type(glue_base):=glue_ref;
-for k:=glue_base+1 to local_base-1 do eqtb[k]:=eqtb[glue_base];
-glue_ref_count(zero_glue):=glue_ref_count(zero_glue)+local_base-glue_base;
-
-@ @<Show equivalent |n|, in region 3@>=
-begin
-if n<skip_base then
- begin print_skip_param(n-glue_base); print_char("=");
- if n<glue_base+thin_mu_skip_code then print_spec(equiv(n),"pt")
- else print_spec(equiv(n),"mu");
- end
-else if n<mu_skip_base then
- begin print_esc("skip"); print_int(n-skip_base); print_char("=");
- print_spec(equiv(n),"pt");
- end
-else begin print_esc("muskip"); print_int(n-mu_skip_base); print_char("=");
- print_spec(equiv(n),"mu");
- end;
-end
-
-@ Region 4 of |eqtb| contains the local quantities defined here. The
-bulk of this region is taken up by five tables that are indexed by eight-bit
-characters; these tables are important to both the syntactic and semantic
-portions of \TeX. There are also a bunch of special things like font and
-token parameters, as well as the tables of \.{\\toks} and \.{\\box}
-registers.
-
-@d par_shape_loc=local_base {specifies paragraph shape}
-@d output_routine_loc=local_base+1 {points to token list for \.{\\output}}
-@d every_par_loc=local_base+2 {points to token list for \.{\\everypar}}
-@d every_math_loc=local_base+3 {points to token list for \.{\\everymath}}
-@d every_display_loc=local_base+4 {points to token list for \.{\\everydisplay}}
-@d every_hbox_loc=local_base+5 {points to token list for \.{\\everyhbox}}
-@d every_vbox_loc=local_base+6 {points to token list for \.{\\everyvbox}}
-@d every_job_loc=local_base+7 {points to token list for \.{\\everyjob}}
-@d every_cr_loc=local_base+8 {points to token list for \.{\\everycr}}
-@d err_help_loc=local_base+9 {points to token list for \.{\\errhelp}}
-@d tex_toks=local_base+10 {end of \TeX's token list parameters}
-@#
-@d pdftex_first_loc = tex_toks {base for \pdfTeX's token list parameters}
-@d pdf_pages_attr_loc = pdftex_first_loc + 0 {points to token list for \.{\\pdfpagesattr}}
-@d pdf_page_attr_loc = pdftex_first_loc + 1 {points to token list for \.{\\pdfpageattr}}
-@d pdf_page_resources_loc = pdftex_first_loc + 2 {points to token list for \.{\\pdfpageresources}}
-@d pdf_pk_mode_loc = pdftex_first_loc + 3 {points to token list for \.{\\pdfpkmode}}
-@d pdf_toks=pdftex_first_loc+4 {end of \pdfTeX's token list parameters}
-@#
-@d etex_toks_base=pdf_toks {base for \eTeX's token list parameters}
-@d every_eof_loc=etex_toks_base {points to token list for \.{\\everyeof}}
-@d etex_toks=etex_toks_base+1 {end of \eTeX's token list parameters}
-@#
-@d ocp_trace_level_base=etex_toks
-@d ocp_active_number_base=ocp_trace_level_base+1
-@d ocp_active_min_ptr_base = ocp_active_number_base+1
-@d ocp_active_max_ptr_base = ocp_active_min_ptr_base+1
-@d ocp_active_base = ocp_active_max_ptr_base+1
-@d toks_base = ocp_active_base+max_active_ocp_lists
- {table of |number_regs| token list registers}
-@#
-@d etex_pen_base=toks_base+number_regs {start of table of \eTeX's penalties}
-@d inter_line_penalties_loc=etex_pen_base {additional penalties between lines}
-@d club_penalties_loc=etex_pen_base+1 {penalties for creating club lines}
-@d widow_penalties_loc=etex_pen_base+2 {penalties for creating widow lines}
-@d display_widow_penalties_loc=etex_pen_base+3 {ditto, just before a display}
-@d etex_pens=etex_pen_base+4 {end of table of \eTeX's penalties}
-@#
-@d local_left_box_base=etex_pens
-@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_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}
-@d math_code_base=sf_code_base+1 {table of |number_chars| math mode mappings}
-@d int_base=math_code_base+1 {beginning of region 5}
-@#
-@d par_shape_ptr==equiv(par_shape_loc)
-@d output_routine==equiv(output_routine_loc)
-@d every_par==equiv(every_par_loc)
-@d every_math==equiv(every_math_loc)
-@d every_display==equiv(every_display_loc)
-@d every_hbox==equiv(every_hbox_loc)
-@d every_vbox==equiv(every_vbox_loc)
-@d every_job==equiv(every_job_loc)
-@d every_cr==equiv(every_cr_loc)
-@d err_help==equiv(err_help_loc)
-@d pdf_pages_attr==equiv(pdf_pages_attr_loc)
-@d pdf_page_attr==equiv(pdf_page_attr_loc)
-@d pdf_page_resources==equiv(pdf_page_resources_loc)
-@d pdf_pk_mode==equiv(pdf_pk_mode_loc)
-@d toks(#)==equiv(toks_base+#)
-@d local_left_box==equiv(local_left_box_base)
-@d local_right_box==equiv(local_right_box_base)
-@d box(#)==equiv(box_base+#)
-@d cur_font==equiv(cur_font_loc)
-
-@<Put each...@>=
-primitive_tex("output",assign_toks,output_routine_loc,local_base);
-@!@:output_}{\.{\\output} primitive@>
-primitive_tex("everypar",assign_toks,every_par_loc,local_base);
-@!@:every_par_}{\.{\\everypar} primitive@>
-primitive_tex("everymath",assign_toks,every_math_loc,local_base);
-@!@:every_math_}{\.{\\everymath} primitive@>
-primitive_tex("everydisplay",assign_toks,every_display_loc,local_base);
-@!@:every_display_}{\.{\\everydisplay} primitive@>
-primitive_tex("everyhbox",assign_toks,every_hbox_loc,local_base);
-@!@:every_hbox_}{\.{\\everyhbox} primitive@>
-primitive_tex("everyvbox",assign_toks,every_vbox_loc,local_base);
-@!@:every_vbox_}{\.{\\everyvbox} primitive@>
-primitive_tex("everyjob",assign_toks,every_job_loc,local_base);
-@!@:every_job_}{\.{\\everyjob} primitive@>
-primitive_tex("everycr",assign_toks,every_cr_loc,local_base);
-@!@:every_cr_}{\.{\\everycr} primitive@>
-primitive_tex("errhelp",assign_toks,err_help_loc,local_base);
-@!@:err_help_}{\.{\\errhelp} primitive@>
-primitive_pdftex("pdfpagesattr",assign_toks,pdf_pages_attr_loc,local_base);
-@!@:pdf_pages_attr_}{\.{\\pdfpagesattr} primitive@>
-primitive_pdftex("pdfpageattr",assign_toks,pdf_page_attr_loc,local_base);
-@!@:pdf_page_attr_}{\.{\\pdfpageattr} primitive@>
-primitive_pdftex("pdfpageresources",assign_toks,pdf_page_resources_loc,local_base);
-@!@:pdf_page_resources_}{\.{\\pdfpageresources} primitive@>
-primitive_pdftex("pdfpkmode",assign_toks,pdf_pk_mode_loc,local_base);
-@!@:pdf_pk_mode_}{\.{\\pdfpkmode} primitive@>
-
-
-@ We initialize most things to null or undefined values. An undefined font
-is represented by the internal code |font_base|.
-
-However, the character code tables are given initial values based on the
-conventional interpretation of ASCII code. These initial values should
-not be changed when \TeX\ is adapted for use with non-English languages;
-all changes to the initialization conventions should be made in format
-packages, not in \TeX\ itself, so that global interchange of formats is
-possible.
-
-@d null_font==font_base
-@d null_ocp==ocp_base
-@d null_ocp_list==ocp_list_base
-@d var_code==7 {math code meaning ``use the current family''}
-
-@<Initialize table entries...@>=
-par_shape_ptr:=null; eq_type(par_shape_loc):=shape_ref;
-eq_level(par_shape_loc):=level_one;@/
-for k:=etex_pen_base to etex_pens-1 do
- eqtb[k]:=eqtb[par_shape_loc];
-for k:=output_routine_loc to toks_base+biggest_reg do
- eqtb[k]:=eqtb[undefined_control_sequence];
-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;@/
-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,tex_mathcode,var_code,0,k,level_one);@/
-for k:="A" to "Z" do begin
- 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);
- end;
-
-@ @<Set init...@>=
-static_int_base:=int_base;
-
-@ @<Show equivalent |n|, in region 4@>=
-begin
-if (n=par_shape_loc) or ((n>=etex_pen_base) and (n<etex_pens)) then
- begin if n=par_shape_loc then print_cmd_chr(set_tex_shape,n)
- else print_cmd_chr(set_etex_shape,n);
- print_char("=");
- if equiv(n)=null then print_char("0")
- else if n>par_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+1));
- end
-else if n<toks_base then
- {TH TODO make extra cases for ocps here! }
- begin print_cmd_chr(assign_toks,n); print_char("=");
- if equiv(n)<>null then show_token_list(link(equiv(n)),null,32);
- end
-else if n<box_base then
- begin print_esc("toks"); print_int(n-toks_base); print_char("=");
- if equiv(n)<>null then show_token_list(link(equiv(n)),null,32);
- end
-else if n<cur_font_loc then
- begin print_esc("box"); print_int(n-box_base); print_char("=");
- if equiv(n)=null then print("void")
- else begin depth_threshold:=0; breadth_max:=1; show_node_list(equiv(n));
- end;
- end
-else if n=cur_font_loc then @<Show the font identifier in |eqtb[n]|@>;
-end
-
-@ @<Show the font identifier in |eqtb[n]|@>=
-begin print("current font"); print_char("=");@/
-print_esc(hash[font_id_base+equiv(n)].rh);
- {that's |font_id_text(equiv(n))|}
-end
-
-@ Region 5 of |eqtb| contains the integer parameters and registers defined
-here, as well as the |del_code| table. The latter table differs from the
-|cat_code..math_code| tables that precede it, since delimiter codes are
-fullword integers while the other kinds of codes occupy at most a
-halfword. This is what makes region~5 different from region~4. We will
-store the |eq_level| information in an auxiliary array of quarterwords
-that will be defined later.
-
-@d pretolerance_code=0 {badness tolerance before hyphenation}
-@d tolerance_code=1 {badness tolerance after hyphenation}
-@d line_penalty_code=2 {added to the badness of every line}
-@d hyphen_penalty_code=3 {penalty for break after discretionary hyphen}
-@d ex_hyphen_penalty_code=4 {penalty for break after explicit hyphen}
-@d club_penalty_code=5 {penalty for creating a club line}
-@d widow_penalty_code=6 {penalty for creating a widow line}
-@d display_widow_penalty_code=7 {ditto, just before a display}
-@d broken_penalty_code=8 {penalty for breaking a page at a broken line}
-@d bin_op_penalty_code=9 {penalty for breaking after a binary operation}
-@d rel_penalty_code=10 {penalty for breaking after a relation}
-@d pre_display_penalty_code=11 {penalty for breaking just before a displayed formula}
-@d post_display_penalty_code=12 {penalty for breaking just after a displayed formula}
-@d inter_line_penalty_code=13 {additional penalty between lines}
-@d double_hyphen_demerits_code=14 {demerits for double hyphen break}
-@d final_hyphen_demerits_code=15 {demerits for final hyphen break}
-@d adj_demerits_code=16 {demerits for adjacent incompatible lines}
-@d mag_code=17 {magnification ratio}
-@d delimiter_factor_code=18 {ratio for variable-size delimiters}
-@d looseness_code=19 {change in number of lines for a paragraph}
-@d time_code=20 {current time of day}
-@d day_code=21 {current day of the month}
-@d month_code=22 {current month of the year}
-@d year_code=23 {current year of our Lord}
-@d show_box_breadth_code=24 {nodes per level in |show_box|}
-@d show_box_depth_code=25 {maximum level in |show_box|}
-@d hbadness_code=26 {hboxes exceeding this badness will be shown by |hpack|}
-@d vbadness_code=27 {vboxes exceeding this badness will be shown by |vpack|}
-@d pausing_code=28 {pause after each line is read from a file}
-@d tracing_online_code=29 {show diagnostic output on terminal}
-@d tracing_macros_code=30 {show macros as they are being expanded}
-@d tracing_stats_code=31 {show memory usage if \TeX\ knows it}
-@d tracing_paragraphs_code=32 {show line-break calculations}
-@d tracing_pages_code=33 {show page-break calculations}
-@d tracing_output_code=34 {show boxes when they are shipped out}
-@d tracing_lost_chars_code=35 {show characters that aren't in the font}
-@d tracing_commands_code=36 {show command codes at |big_switch|}
-@d tracing_restores_code=37 {show equivalents when they are restored}
-@d uc_hyph_code=38 {hyphenate words beginning with a capital letter}
-@d output_penalty_code=39 {penalty found at current page break}
-@d max_dead_cycles_code=40 {bound on consecutive dead cycles of output}
-@d hang_after_code=41 {hanging indentation changes after this many lines}
-@d floating_penalty_code=42 {penalty for insertions heldover after a split}
-@d global_defs_code=43 {override \.{\\global} specifications}
-@d cur_fam_code=44 {current family}
-@d escape_char_code=45 {escape character for token output}
-@d default_hyphen_char_code=46 {value of \.{\\hyphenchar} when a font is loaded}
-@d default_skew_char_code=47 {value of \.{\\skewchar} when a font is loaded}
-@d end_line_char_code=48 {character placed at the right end of the buffer}
-@d new_line_char_code=49 {character that prints as |print_ln|}
-@d language_code=50 {current hyphenation table}
-@d left_hyphen_min_code=51 {minimum left hyphenation fragment size}
-@d right_hyphen_min_code=52 {minimum right hyphenation fragment size}
-@d holding_inserts_code=53 {do not remove insertion nodes from \.{\\box255}}
-@d error_context_lines_code=54 {maximum intermediate line pairs shown}
-@d local_inter_line_penalty_code=55 {local \.{\\interlinepenalty}}
-@d local_broken_penalty_code=56 {local \.{\\brokenpenalty}}
-@d no_local_whatsits_code=57 {counts local whatsits}
-@d no_local_dirs_code=58
-@d level_local_dir_code=59
-@d luastartup_id_code=60
-@d disable_lig_code=61
-@d disable_kern_code=62
-@d cat_code_table_code=63
-@d output_box_code=64
-@d cur_lang_code=65 {current language id}
-@d ex_hyphen_char_code=66
-@d tex_int_pars=67 {total number of \.{\\TeX} + Aleph integer parameters}
-@#
-@d dir_base=int_base+tex_int_pars
-@d page_direction_code=0
-@d body_direction_code=1
-@d par_direction_code=2
-@d text_direction_code=3
-@d math_direction_code=4
-@d dir_pars=5
-@#
-@d pdftex_first_integer_code = tex_int_pars+dir_pars {base for \pdfTeX's integer parameters}
-@d pdf_output_code = pdftex_first_integer_code + 0 {switch on PDF output if positive}
-@d pdf_compress_level_code = pdftex_first_integer_code + 1 {compress level of streams}
-@d pdf_decimal_digits_code = pdftex_first_integer_code + 2 {digits after the decimal point of numbers}
-@d pdf_move_chars_code = pdftex_first_integer_code + 3 {move chars 0..31 to higher area if possible}
-@d pdf_image_resolution_code = pdftex_first_integer_code + 4 {default image resolution}
-@d pdf_pk_resolution_code = pdftex_first_integer_code + 5 {default resolution of PK font}
-@d pdf_unique_resname_code = pdftex_first_integer_code + 6 {generate unique names for resouces}
-@d pdf_option_always_use_pdfpagebox_code = pdftex_first_integer_code + 7 {if the PDF inclusion should always use a specific PDF page box}
-@d pdf_option_pdf_inclusion_errorlevel_code = pdftex_first_integer_code + 8 {if the PDF inclusion should treat pdfs newer than |pdf_minor_version| as an error}
-@d pdf_minor_version_code = pdftex_first_integer_code + 9 {fractional part of the PDF version produced}
-@d pdf_force_pagebox_code = pdftex_first_integer_code + 10 {if the PDF inclusion should always use a specific PDF page box}
-@d pdf_pagebox_code = pdftex_first_integer_code + 11 {default pagebox to use for PDF inclusion}
-@d pdf_inclusion_errorlevel_code = pdftex_first_integer_code + 12 {if the PDF inclusion should treat pdfs newer than |pdf_minor_version| as an error}
-@d pdf_gamma_code = pdftex_first_integer_code + 13
-@d pdf_image_gamma_code = pdftex_first_integer_code + 14
-@d pdf_image_hicolor_code = pdftex_first_integer_code + 15
-@d pdf_image_apply_gamma_code = pdftex_first_integer_code + 16
-@d pdf_adjust_spacing_code = pdftex_first_integer_code + 17 {level of spacing adjusting}
-@d pdf_protrude_chars_code = pdftex_first_integer_code + 18 {protrude chars at left/right edge of paragraphs}
-@d pdf_tracing_fonts_code = pdftex_first_integer_code + 19 {level of font detail in log}
-@d pdf_objcompresslevel_code = pdftex_first_integer_code + 20 {activate object streams}
-@d pdf_gen_tounicode_code = pdftex_first_integer_code + 24 {generate ToUnicode for fonts?}
-@d pdf_draftmode_code = pdftex_first_integer_code + 25 {switch on draftmode if positive}
-@d pdf_replace_font_code = pdftex_first_integer_code + 26 {generate ToUnicode for fonts?}
-@d pdf_inclusion_copy_font_code = pdftex_first_integer_code + 27 {generate ToUnicode for fonts?}
-@d pdf_int_pars=pdftex_first_integer_code + 28 {total number of \pdfTeX's integer parameters}
-@#
-@d etex_int_base=pdf_int_pars {base for \eTeX's integer parameters}
-@d tracing_assigns_code=etex_int_base {show assignments}
-@d tracing_groups_code=etex_int_base+1 {show save/restore groups}
-@d tracing_ifs_code=etex_int_base+2 {show conditionals}
-@d tracing_scan_tokens_code=etex_int_base+3 {show pseudo file open and close}
-@d tracing_nesting_code=etex_int_base+4 {show incomplete groups and ifs within files}
-@d pre_display_direction_code=etex_int_base+5 {text direction preceding a display}
-@d last_line_fit_code=etex_int_base+6 {adjustment for last line of paragraph}
-@d saving_vdiscards_code=etex_int_base+7 {save items discarded from vlists}
-@d saving_hyph_codes_code=etex_int_base+8 {save hyphenation codes for languages}
-@d suppress_fontnotfound_error_code=etex_int_base+9 {surpress errors for missing fonts}
-@d suppress_long_error_code=etex_int_base+10 {surpress errors for missing fonts}
-@d suppress_ifcsname_error_code=etex_int_base+11 {surpress errors for failed \.{\\ifcsname}}
-@d suppress_outer_error_code=etex_int_base+12 {surpress errors for \.{\\outer}}
-@d etex_int_pars=etex_int_base+13 {total number of \eTeX's integer parameters}
-@#
-@d synctex_code=etex_int_pars { is synctex file generation enabled ? }
-@d int_pars=synctex_code+1 {total number of integer parameters}
-@d count_base=int_base+int_pars {|number_regs| user \.{\\count} registers}
-@d attribute_base=count_base+number_regs {|number_attrs| user \.{\\attribute} registers}
-@d del_code_base=attribute_base+number_attrs {|number_chars| delimiter code mappings}
-@d dimen_base=del_code_base+1 {beginning of region 6}
-@#
-@d count(#)==eqtb[count_base+#].int
-@d attribute(#)==eqtb[attribute_base+#].int
-@d int_par(#)==eqtb[int_base+#].int {an integer parameter}
-@d pretolerance==int_par(pretolerance_code)
-@d tolerance==int_par(tolerance_code)
-@d line_penalty==int_par(line_penalty_code)
-@d hyphen_penalty==int_par(hyphen_penalty_code)
-@d ex_hyphen_penalty==int_par(ex_hyphen_penalty_code)
-@d club_penalty==int_par(club_penalty_code)
-@d widow_penalty==int_par(widow_penalty_code)
-@d display_widow_penalty==int_par(display_widow_penalty_code)
-@d broken_penalty==int_par(broken_penalty_code)
-@d bin_op_penalty==int_par(bin_op_penalty_code)
-@d rel_penalty==int_par(rel_penalty_code)
-@d pre_display_penalty==int_par(pre_display_penalty_code)
-@d post_display_penalty==int_par(post_display_penalty_code)
-@d inter_line_penalty==int_par(inter_line_penalty_code)
-@d double_hyphen_demerits==int_par(double_hyphen_demerits_code)
-@d final_hyphen_demerits==int_par(final_hyphen_demerits_code)
-@d adj_demerits==int_par(adj_demerits_code)
-@d mag==int_par(mag_code)
-@d delimiter_factor==int_par(delimiter_factor_code)
-@d looseness==int_par(looseness_code)
-@d time==int_par(time_code)
-@d day==int_par(day_code)
-@d month==int_par(month_code)
-@d year==int_par(year_code)
-@d show_box_breadth==int_par(show_box_breadth_code)
-@d show_box_depth==int_par(show_box_depth_code)
-@d hbadness==int_par(hbadness_code)
-@d vbadness==int_par(vbadness_code)
-@d pausing==int_par(pausing_code)
-@d tracing_online==int_par(tracing_online_code)
-@d tracing_macros==int_par(tracing_macros_code)
-@d tracing_stats==int_par(tracing_stats_code)
-@d tracing_paragraphs==int_par(tracing_paragraphs_code)
-@d tracing_pages==int_par(tracing_pages_code)
-@d tracing_output==int_par(tracing_output_code)
-@d tracing_lost_chars==int_par(tracing_lost_chars_code)
-@d tracing_commands==int_par(tracing_commands_code)
-@d tracing_restores==int_par(tracing_restores_code)
-@d uc_hyph==int_par(uc_hyph_code)
-@d output_penalty==int_par(output_penalty_code)
-@d max_dead_cycles==int_par(max_dead_cycles_code)
-@d hang_after==int_par(hang_after_code)
-@d floating_penalty==int_par(floating_penalty_code)
-@d global_defs==int_par(global_defs_code)
-@d cur_fam==int_par(cur_fam_code)
-@d escape_char==int_par(escape_char_code)
-@d default_hyphen_char==int_par(default_hyphen_char_code)
-@d default_skew_char==int_par(default_skew_char_code)
-@d end_line_char==int_par(end_line_char_code)
-@d new_line_char==int_par(new_line_char_code)
-@d local_inter_line_penalty==int_par(local_inter_line_penalty_code)
-@d local_broken_penalty==int_par(local_broken_penalty_code)
-@d no_local_whatsits==int_par(no_local_whatsits_code)
-@d no_local_dirs==int_par(no_local_dirs_code)
-@d level_local_dir==int_par(level_local_dir_code)
-@d dir_par(#)==eqtb[dir_base+#].int {a direction parameter}
-@d page_direction==dir_par(page_direction_code)
-@d body_direction==dir_par(body_direction_code)
-@d par_direction==dir_par(par_direction_code)
-@d text_direction==dir_par(text_direction_code)
-@d math_direction==dir_par(math_direction_code)
-@d language==int_par(language_code)
-@d cur_lang==int_par(cur_lang_code)
-@d ex_hyphen_char==int_par(ex_hyphen_char_code)
-@d left_hyphen_min==int_par(left_hyphen_min_code)
-@d right_hyphen_min==int_par(right_hyphen_min_code)
-@d holding_inserts==int_par(holding_inserts_code)
-@d error_context_lines==int_par(error_context_lines_code)
-@d luastartup_id==int_par(luastartup_id_code)
-@d disable_lig==int_par(disable_lig_code)
-@d disable_kern==int_par(disable_kern_code)
-@d cat_code_table==int_par(cat_code_table_code)
-@d output_box==int_par(output_box_code)
-@#
-@d pdf_adjust_spacing == int_par(pdf_adjust_spacing_code)
-@d pdf_protrude_chars == int_par(pdf_protrude_chars_code)
-@d pdf_tracing_fonts == int_par(pdf_tracing_fonts_code)
-@d pdf_gen_tounicode == int_par(pdf_gen_tounicode_code)
-@d pdf_output == int_par(pdf_output_code)
-@d pdf_compress_level == int_par(pdf_compress_level_code)
-@d pdf_objcompresslevel == int_par(pdf_objcompresslevel_code)
-@d pdf_decimal_digits == int_par(pdf_decimal_digits_code)
-@d pdf_move_chars == int_par(pdf_move_chars_code)
-@d pdf_image_resolution == int_par(pdf_image_resolution_code)
-@d pdf_pk_resolution == int_par(pdf_pk_resolution_code)
-@d pdf_unique_resname == int_par(pdf_unique_resname_code)
-@d pdf_option_always_use_pdfpagebox == int_par(pdf_option_always_use_pdfpagebox_code)
-@d pdf_option_pdf_inclusion_errorlevel == int_par(pdf_option_pdf_inclusion_errorlevel_code)
-@d pdf_minor_version == int_par(pdf_minor_version_code)
-@d pdf_force_pagebox == int_par(pdf_force_pagebox_code)
-@d pdf_pagebox == int_par(pdf_pagebox_code)
-@d pdf_inclusion_errorlevel == int_par(pdf_inclusion_errorlevel_code)
-@d pdf_gamma == int_par(pdf_gamma_code)
-@d pdf_image_gamma == int_par(pdf_image_gamma_code)
-@d pdf_image_hicolor == int_par(pdf_image_hicolor_code)
-@d pdf_image_apply_gamma == int_par(pdf_image_apply_gamma_code)
-@d pdf_draftmode == int_par(pdf_draftmode_code)
-@d pdf_inclusion_copy_font == int_par(pdf_inclusion_copy_font_code)
-@d pdf_replace_font == int_par(pdf_replace_font_code)
-@#
-@d tracing_assigns==int_par(tracing_assigns_code)
-@d tracing_groups==int_par(tracing_groups_code)
-@d tracing_ifs==int_par(tracing_ifs_code)
-@d tracing_scan_tokens==int_par(tracing_scan_tokens_code)
-@d tracing_nesting==int_par(tracing_nesting_code)
-@d pre_display_direction==int_par(pre_display_direction_code)
-@d last_line_fit==int_par(last_line_fit_code)
-@d saving_vdiscards==int_par(saving_vdiscards_code)
-@d saving_hyph_codes==int_par(saving_hyph_codes_code)
-@d suppress_fontnotfound_error==int_par(suppress_fontnotfound_error_code)
-@d suppress_long_error==int_par(suppress_long_error_code)
-@d suppress_ifcsname_error==int_par(suppress_ifcsname_error_code)
-@d synctex==int_par(synctex_code)
-
-@<Assign the values |depth_threshold:=show_box_depth|...@>=
-depth_threshold:=show_box_depth;
-breadth_max:=show_box_breadth
-
-
-@ @<Set init...@>=
-static_dimen_base:=dimen_base;
-
-@ We can print the symbolic name of an integer parameter as follows.
-
-@p procedure print_param(@!n:integer);
-begin case n of
-pretolerance_code:print_esc("pretolerance");
-tolerance_code:print_esc("tolerance");
-line_penalty_code:print_esc("linepenalty");
-hyphen_penalty_code:print_esc("hyphenpenalty");
-ex_hyphen_penalty_code:print_esc("exhyphenpenalty");
-club_penalty_code:print_esc("clubpenalty");
-widow_penalty_code:print_esc("widowpenalty");
-display_widow_penalty_code:print_esc("displaywidowpenalty");
-broken_penalty_code:print_esc("brokenpenalty");
-bin_op_penalty_code:print_esc("binoppenalty");
-rel_penalty_code:print_esc("relpenalty");
-pre_display_penalty_code:print_esc("predisplaypenalty");
-post_display_penalty_code:print_esc("postdisplaypenalty");
-inter_line_penalty_code:print_esc("interlinepenalty");
-double_hyphen_demerits_code:print_esc("doublehyphendemerits");
-final_hyphen_demerits_code:print_esc("finalhyphendemerits");
-adj_demerits_code:print_esc("adjdemerits");
-mag_code:print_esc("mag");
-delimiter_factor_code:print_esc("delimiterfactor");
-looseness_code:print_esc("looseness");
-time_code:print_esc("time");
-day_code:print_esc("day");
-month_code:print_esc("month");
-year_code:print_esc("year");
-show_box_breadth_code:print_esc("showboxbreadth");
-show_box_depth_code:print_esc("showboxdepth");
-hbadness_code:print_esc("hbadness");
-vbadness_code:print_esc("vbadness");
-pausing_code:print_esc("pausing");
-tracing_online_code:print_esc("tracingonline");
-tracing_macros_code:print_esc("tracingmacros");
-tracing_stats_code:print_esc("tracingstats");
-tracing_paragraphs_code:print_esc("tracingparagraphs");
-tracing_pages_code:print_esc("tracingpages");
-tracing_output_code:print_esc("tracingoutput");
-tracing_lost_chars_code:print_esc("tracinglostchars");
-tracing_commands_code:print_esc("tracingcommands");
-tracing_restores_code:print_esc("tracingrestores");
-uc_hyph_code:print_esc("uchyph");
-output_penalty_code:print_esc("outputpenalty");
-max_dead_cycles_code:print_esc("maxdeadcycles");
-hang_after_code:print_esc("hangafter");
-floating_penalty_code:print_esc("floatingpenalty");
-global_defs_code:print_esc("globaldefs");
-cur_fam_code:print_esc("fam");
-escape_char_code:print_esc("escapechar");
-default_hyphen_char_code:print_esc("defaulthyphenchar");
-default_skew_char_code:print_esc("defaultskewchar");
-end_line_char_code:print_esc("endlinechar");
-new_line_char_code:print_esc("newlinechar");
-language_code:print_esc("language");
-cur_lang_code:print_esc("setlanguage");
-ex_hyphen_char_code:print_esc("exhyphenchar");
-left_hyphen_min_code:print_esc("lefthyphenmin");
-right_hyphen_min_code:print_esc("righthyphenmin");
-holding_inserts_code:print_esc("holdinginserts");
-error_context_lines_code:print_esc("errorcontextlines");
-luastartup_id_code:print_esc("luastartup");
-disable_lig_code:print_esc("noligs");
-disable_kern_code:print_esc("nokerns");
-cat_code_table_code:print_esc("catcodetable");
-output_box_code:print_esc("outputbox");
-@#
-local_inter_line_penalty_code: print_esc("localinterlinepenalty");
-local_broken_penalty_code: print_esc("localbrokenpenalty");
-{the next three do not have a matching primitive}
-no_local_whatsits_code: print("[no_local_whatsits]");
-no_local_dirs_code: print("[no_local_dirs]");
-level_local_dir_code: print("[level_local_dir]");
-@#
-pdf_output_code: print_esc("pdfoutput");
-pdf_compress_level_code: print_esc("pdfcompresslevel");
-pdf_objcompresslevel_code: print_esc("pdfobjcompresslevel");
-pdf_decimal_digits_code: print_esc("pdfdecimaldigits");
-pdf_move_chars_code: print_esc("pdfmovechars");
-pdf_image_resolution_code: print_esc("pdfimageresolution");
-pdf_pk_resolution_code: print_esc("pdfpkresolution");
-pdf_unique_resname_code: print_esc("pdfuniqueresname");
-pdf_option_always_use_pdfpagebox_code: print_esc("pdfoptionalwaysusepdfpagebox");
-pdf_option_pdf_inclusion_errorlevel_code: print_esc("pdfoptionpdfinclusionerrorlevel");
-pdf_minor_version_code: print_esc("pdfminorversion");
-pdf_force_pagebox_code: print_esc("pdfforcepagebox");
-pdf_pagebox_code: print_esc("pdfpagebox");
-pdf_inclusion_errorlevel_code: print_esc("pdfinclusionerrorlevel");
-pdf_gamma_code: print_esc("pdfgamma");
-pdf_image_gamma_code: print_esc("pdfimagegamma");
-pdf_image_hicolor_code: print_esc("pdfimagehicolor");
-pdf_image_apply_gamma_code: print_esc("pdfimageapplygamma");
-pdf_adjust_spacing_code: print_esc("pdfadjustspacing");
-pdf_protrude_chars_code: print_esc("pdfprotrudechars");
-pdf_tracing_fonts_code: print_esc("pdftracingfonts");
-pdf_gen_tounicode_code: print_esc("pdfgentounicode");
-pdf_draftmode_code: print_esc("pdfdraftmode");
-pdf_inclusion_copy_font_code: print_esc("pdfinclusioncopyfonts");
-pdf_replace_font_code: print_esc("pdfreplacefont");
-@/@<Cases for |print_param|@>@/
-othercases begin print("[unknown integer parameter!]"); end
-endcases;
-end;
-
-@ The integer parameter names must be entered into the hash table.
-
-@<Put each...@>=
-primitive_tex("pretolerance",assign_int,int_base+pretolerance_code,int_base);@/
-@!@:pretolerance_}{\.{\\pretolerance} primitive@>
-primitive_tex("tolerance",assign_int,int_base+tolerance_code,int_base);@/
-@!@:tolerance_}{\.{\\tolerance} primitive@>
-primitive_tex("linepenalty",assign_int,int_base+line_penalty_code,int_base);@/
-@!@:line_penalty_}{\.{\\linepenalty} primitive@>
-primitive_tex("hyphenpenalty",assign_int,int_base+hyphen_penalty_code,int_base);@/
-@!@:hyphen_penalty_}{\.{\\hyphenpenalty} primitive@>
-primitive_tex("exhyphenpenalty",assign_int,int_base+ex_hyphen_penalty_code,int_base);@/
-@!@:ex_hyphen_penalty_}{\.{\\exhyphenpenalty} primitive@>
-primitive_tex("clubpenalty",assign_int,int_base+club_penalty_code,int_base);@/
-@!@:club_penalty_}{\.{\\clubpenalty} primitive@>
-primitive_tex("widowpenalty",assign_int,int_base+widow_penalty_code,int_base);@/
-@!@:widow_penalty_}{\.{\\widowpenalty} primitive@>
-primitive_tex("displaywidowpenalty", assign_int,int_base+display_widow_penalty_code,int_base);@/
-@!@:display_widow_penalty_}{\.{\\displaywidowpenalty} primitive@>
-primitive_tex("brokenpenalty",assign_int,int_base+broken_penalty_code,int_base);@/
-@!@:broken_penalty_}{\.{\\brokenpenalty} primitive@>
-primitive_tex("binoppenalty",assign_int,int_base+bin_op_penalty_code,int_base);@/
-@!@:bin_op_penalty_}{\.{\\binoppenalty} primitive@>
-primitive_tex("relpenalty",assign_int,int_base+rel_penalty_code,int_base);@/
-@!@:rel_penalty_}{\.{\\relpenalty} primitive@>
-primitive_tex("predisplaypenalty",assign_int,int_base+pre_display_penalty_code,int_base);@/
-@!@:pre_display_penalty_}{\.{\\predisplaypenalty} primitive@>
-primitive_tex("postdisplaypenalty",assign_int,int_base+post_display_penalty_code,int_base);@/
-@!@:post_display_penalty_}{\.{\\postdisplaypenalty} primitive@>
-primitive_tex("interlinepenalty",assign_int,int_base+inter_line_penalty_code,int_base);@/
-@!@:inter_line_penalty_}{\.{\\interlinepenalty} primitive@>
-primitive_tex("doublehyphendemerits", assign_int,int_base+double_hyphen_demerits_code,int_base);@/
-@!@:double_hyphen_demerits_}{\.{\\doublehyphendemerits} primitive@>
-primitive_tex("finalhyphendemerits", assign_int,int_base+final_hyphen_demerits_code,int_base);@/
-@!@:final_hyphen_demerits_}{\.{\\finalhyphendemerits} primitive@>
-primitive_tex("adjdemerits",assign_int,int_base+adj_demerits_code,int_base);@/
-@!@:adj_demerits_}{\.{\\adjdemerits} primitive@>
-primitive_tex("mag",assign_int,int_base+mag_code,int_base);@/
-@!@:mag_}{\.{\\mag} primitive@>
-primitive_tex("delimiterfactor",assign_int,int_base+delimiter_factor_code,int_base);@/
-@!@:delimiter_factor_}{\.{\\delimiterfactor} primitive@>
-primitive_tex("looseness",assign_int,int_base+looseness_code,int_base);@/
-@!@:looseness_}{\.{\\looseness} primitive@>
-primitive_tex("time",assign_int,int_base+time_code,int_base);@/
-@!@:time_}{\.{\\time} primitive@>
-primitive_tex("day",assign_int,int_base+day_code,int_base);@/
-@!@:day_}{\.{\\day} primitive@>
-primitive_tex("month",assign_int,int_base+month_code,int_base);@/
-@!@:month_}{\.{\\month} primitive@>
-primitive_tex("year",assign_int,int_base+year_code,int_base);@/
-@!@:year_}{\.{\\year} primitive@>
-primitive_tex("showboxbreadth",assign_int,int_base+show_box_breadth_code,int_base);@/
-@!@:show_box_breadth_}{\.{\\showboxbreadth} primitive@>
-primitive_tex("showboxdepth",assign_int,int_base+show_box_depth_code,int_base);@/
-@!@:show_box_depth_}{\.{\\showboxdepth} primitive@>
-primitive_tex("hbadness",assign_int,int_base+hbadness_code,int_base);@/
-@!@:hbadness_}{\.{\\hbadness} primitive@>
-primitive_tex("vbadness",assign_int,int_base+vbadness_code,int_base);@/
-@!@:vbadness_}{\.{\\vbadness} primitive@>
-primitive_tex("pausing",assign_int,int_base+pausing_code,int_base);@/
-@!@:pausing_}{\.{\\pausing} primitive@>
-primitive_tex("tracingonline",assign_int,int_base+tracing_online_code,int_base);@/
-@!@:tracing_online_}{\.{\\tracingonline} primitive@>
-primitive_tex("tracingmacros",assign_int,int_base+tracing_macros_code,int_base);@/
-@!@:tracing_macros_}{\.{\\tracingmacros} primitive@>
-primitive_tex("tracingstats",assign_int,int_base+tracing_stats_code,int_base);@/
-@!@:tracing_stats_}{\.{\\tracingstats} primitive@>
-primitive_tex("tracingparagraphs",assign_int,int_base+tracing_paragraphs_code,int_base);@/
-@!@:tracing_paragraphs_}{\.{\\tracingparagraphs} primitive@>
-primitive_tex("tracingpages",assign_int,int_base+tracing_pages_code,int_base);@/
-@!@:tracing_pages_}{\.{\\tracingpages} primitive@>
-primitive_tex("tracingoutput",assign_int,int_base+tracing_output_code,int_base);@/
-@!@:tracing_output_}{\.{\\tracingoutput} primitive@>
-primitive_tex("tracinglostchars",assign_int,int_base+tracing_lost_chars_code,int_base);@/
-@!@:tracing_lost_chars_}{\.{\\tracinglostchars} primitive@>
-primitive_tex("tracingcommands",assign_int,int_base+tracing_commands_code,int_base);@/
-@!@:tracing_commands_}{\.{\\tracingcommands} primitive@>
-primitive_tex("tracingrestores",assign_int,int_base+tracing_restores_code,int_base);@/
-@!@:tracing_restores_}{\.{\\tracingrestores} primitive@>
-primitive_tex("uchyph",assign_int,int_base+uc_hyph_code,int_base);@/
-@!@:uc_hyph_}{\.{\\uchyph} primitive@>
-primitive_tex("outputpenalty",assign_int,int_base+output_penalty_code,int_base);@/
-@!@:output_penalty_}{\.{\\outputpenalty} primitive@>
-primitive_tex("maxdeadcycles",assign_int,int_base+max_dead_cycles_code,int_base);@/
-@!@:max_dead_cycles_}{\.{\\maxdeadcycles} primitive@>
-primitive_tex("hangafter",assign_int,int_base+hang_after_code,int_base);@/
-@!@:hang_after_}{\.{\\hangafter} primitive@>
-primitive_tex("floatingpenalty",assign_int,int_base+floating_penalty_code,int_base);@/
-@!@:floating_penalty_}{\.{\\floatingpenalty} primitive@>
-primitive_tex("globaldefs",assign_int,int_base+global_defs_code,int_base);@/
-@!@:global_defs_}{\.{\\globaldefs} primitive@>
-primitive_tex("fam",assign_int,int_base+cur_fam_code,int_base);@/
-@!@:fam_}{\.{\\fam} primitive@>
-primitive_tex("escapechar",assign_int,int_base+escape_char_code,int_base);@/
-@!@:escape_char_}{\.{\\escapechar} primitive@>
-primitive_tex("defaulthyphenchar",assign_int,int_base+default_hyphen_char_code,int_base);@/
-@!@:default_hyphen_char_}{\.{\\defaulthyphenchar} primitive@>
-primitive_tex("defaultskewchar",assign_int,int_base+default_skew_char_code,int_base);@/
-@!@:default_skew_char_}{\.{\\defaultskewchar} primitive@>
-primitive_tex("endlinechar",assign_int,int_base+end_line_char_code,int_base);@/
-@!@:end_line_char_}{\.{\\endlinechar} primitive@>
-primitive_tex("newlinechar",assign_int,int_base+new_line_char_code,int_base);@/
-@!@:new_line_char_}{\.{\\newlinechar} primitive@>
-primitive_tex("language",assign_int,int_base+language_code,int_base);@/
-@!@:language_}{\.{\\language} primitive@>
-primitive_tex("setlanguage",assign_int,int_base+cur_lang_code,int_base);@/
-@!@:cur_lang_}{\.{\\setlanguage} primitive@>
-primitive_tex("exhyphenchar",assign_int,int_base+ex_hyphen_char_code,int_base);@/
-@!@:ex_hyphen_char_}{\.{\\exhyphenchar} primitive@>
-primitive_tex("lefthyphenmin",assign_int,int_base+left_hyphen_min_code,int_base);@/
-@!@:left_hyphen_min_}{\.{\\lefthyphenmin} primitive@>
-primitive_tex("righthyphenmin",assign_int,int_base+right_hyphen_min_code,int_base);@/
-@!@:right_hyphen_min_}{\.{\\righthyphenmin} primitive@>
-primitive_tex("holdinginserts",assign_int,int_base+holding_inserts_code,int_base);@/
-@!@:holding_inserts_}{\.{\\holdinginserts} primitive@>
-primitive_tex("errorcontextlines",assign_int,int_base+error_context_lines_code,int_base);@/
-@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
-primitive_luatex("luastartup",assign_int,int_base+luastartup_id_code,int_base);@/
-@!@:luastartup_id_}{\.{\\luastartup} primitive@>
-primitive_luatex("nokerns",assign_int,int_base+disable_kern_code,int_base);@/
-@!@:disable_kern_}{\.{\\noligkerns} primitive@>
-primitive_luatex("noligs",assign_int,int_base+disable_lig_code,int_base);@/
-@!@:disable_lig_}{\.{\\noligs} primitive@>
-primitive_luatex("catcodetable",assign_int,int_base+cat_code_table_code,int_base);@/
-@!@:cat_code_table_}{\.{\\catcodetable} primitive@>
-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_pdftex("pdfcompresslevel",assign_int,int_base+pdf_compress_level_code,int_base);@/
-@!@:pdf_compress_level_}{\.{\\pdfcompresslevel} primitive@>
-primitive_pdftex("pdfobjcompresslevel",assign_int,int_base+pdf_objcompresslevel_code,int_base);@/
-@!@:pdf_objcompresslevel_}{\.{\\pdfobjcompresslevel} primitive@>
-primitive_pdftex("pdfdecimaldigits",assign_int,int_base+pdf_decimal_digits_code,int_base);@/
-@!@:pdf_decimal_digits_}{\.{\\pdfdecimaldigits} primitive@>
-primitive_pdftex("pdfmovechars",assign_int,int_base+pdf_move_chars_code,int_base);@/
-@!@:pdf_move_chars_}{\.{\\pdfmovechars} primitive@>
-primitive_pdftex("pdfimageresolution",assign_int,int_base+pdf_image_resolution_code,int_base);@/
-@!@:pdf_image_resolution_}{\.{\\pdfimageresolution} primitive@>
-primitive_pdftex("pdfpkresolution",assign_int,int_base+pdf_pk_resolution_code,int_base);@/
-@!@:pdf_pk_resolution_}{\.{\\pdfpkresolution} primitive@>
-primitive_pdftex("pdfuniqueresname",assign_int,int_base+pdf_unique_resname_code,int_base);@/
-@!@:pdf_unique_resname_}{\.{\\pdfuniqueresname} primitive@>
-primitive_pdftex("pdfoptionpdfminorversion",assign_int,int_base+pdf_minor_version_code,int_base);@/
-@!@:pdf_minor_version_}{\.{\\pdfoptionpdfminorversion} primitive@>
-primitive_pdftex("pdfoptionalwaysusepdfpagebox",assign_int,int_base+pdf_option_always_use_pdfpagebox_code,int_base);@/
-@!@:pdf_option_always_use_pdfpagebox_}{\.{\\pdfoptionalwaysusepdfpagebox} primitive@>
-primitive_pdftex("pdfoptionpdfinclusionerrorlevel",assign_int,int_base+pdf_option_pdf_inclusion_errorlevel_code,int_base);@/
-@!@:pdf_option_pdf_inclusion_errorlevel_}{\.{\\pdfoptionpdfinclusionerrorlevel} primitive@>
-primitive_pdftex("pdfminorversion",assign_int,int_base+pdf_minor_version_code,int_base);@/
-@!@:pdf_minor_version_}{\.{\\pdfminorversion} primitive@>
-primitive_pdftex("pdfforcepagebox",assign_int,int_base+pdf_force_pagebox_code,int_base);@/
-@!@:pdf_force_pagebox_}{\.{\\pdfforcepagebox} primitive@>
-primitive_pdftex("pdfpagebox",assign_int,int_base+pdf_pagebox_code,int_base);@/
-@!@:pdf_pagebox_}{\.{\\pdfpagebox} primitive@>
-primitive_pdftex("pdfinclusionerrorlevel",assign_int,int_base+pdf_inclusion_errorlevel_code,int_base);@/
-@!@:pdf_inclusion_errorlevel_}{\.{\\pdfinclusionerrorlevel} primitive@>
-primitive_pdftex("pdfgamma",assign_int,int_base+pdf_gamma_code,int_base);@/
-@!@:pdf_gamma_}{\.{\\pdfgamma} primitive@>
-primitive_pdftex("pdfimagegamma",assign_int,int_base+pdf_image_gamma_code,int_base);@/
-@!@:pdf_image_gamma_}{\.{\\pdfimagegamma} primitive@>
-primitive_pdftex("pdfimagehicolor",assign_int,int_base+pdf_image_hicolor_code,int_base);@/
-@!@:pdf_image_hicolor_}{\.{\\pdfimagehicolor} primitive@>
-primitive_pdftex("pdfimageapplygamma",assign_int,int_base+pdf_image_apply_gamma_code,int_base);@/
-@!@:pdf_image_apply_gamma_}{\.{\\pdfimageapplygamma} primitive@>
-primitive_pdftex("pdfadjustspacing",assign_int,int_base+pdf_adjust_spacing_code,int_base);@/
-@!@:pdf_adjust_spacing_}{\.{\\pdfadjustspacing} primitive@>
-primitive_pdftex("pdfprotrudechars",assign_int,int_base+pdf_protrude_chars_code,int_base);@/
-@!@:pdf_protrude_chars_}{\.{\\pdfprotrudechars} primitive@>
-primitive_pdftex("pdftracingfonts",assign_int,int_base+pdf_tracing_fonts_code,int_base);@/
-@!@:pdf_tracing_fonts_}{\.{\\pdftracingfonts} primitive@>
-primitive_pdftex("pdfgentounicode",assign_int,int_base+pdf_gen_tounicode_code,int_base);@/
-@!@:pdf_gen_tounicode_}{\.{\\pdfgentounicode} primitive@>
-primitive_pdftex("pdfdraftmode",assign_int,int_base+pdf_draftmode_code,int_base);@/
-@!@:pdf_draftmode_}{\.{\\pdfdraftmode} primitive@>
-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@>
-
-@ The integer parameters should really be initialized by a macro package;
-the following initialization does the minimum to keep \TeX\ from
-complete failure.
-@^null delimiter@>
-
-@<Initialize table entries...@>=
-for k:=int_base to attribute_base-1 do eqtb[k].int:=0;
-for k:=attribute_base to del_code_base-1 do eqtb[k].int:=UNUSED_ATTRIBUTE;
-mag:=1000; tolerance:=10000; hang_after:=1; max_dead_cycles:=25;
-escape_char:="\"; end_line_char:=carriage_return;
-eqtb[int_base+level_local_dir_code].int:=level_one;
-set_del_code(".",tex_mathcode,0,0,0,0,level_one); {this null delimiter is used in error recovery}
-ex_hyphen_char:="-";
-output_box:=255;
-
-@ The following procedure, which is called just before \TeX\ initializes its
-input and output, establishes the initial values of the date and time.
-@^system dependencies@>
-Since standard \PASCAL\ cannot provide such information, something special
-is needed. The program here simply specifies July 4, 1776, at noon; but
-users probably want a better approximation to the truth.
-
-@p procedure fix_date_and_time;
-begin time:=12*60; {minutes since midnight}
-day:=4; {fourth day of the month}
-month:=7; {seventh month of the year}
-year:=1776; {Anno Domini}
-end;
-
-@ @<Show equivalent |n|, in region 5@>=
-begin if n<count_base then begin print_param(n-int_base);
- print_char("="); print_int(eqtb[n].int);
- end
-else if n<attribute_base then
- begin print_esc("count"); print_int(n-count_base);
- print_char("="); print_int(eqtb[n].int);
- end
-else if n<del_code_base then
- begin print_esc("attribute"); print_int(n-attribute_base);
- print_char("="); print_int(eqtb[n].int);
- end;
-end
-
-@ @<Set variable |c| to the current escape character@>=c:=escape_char
-
-@ @<Character |s| is the current new-line character@>=s=new_line_char
-
-@ \TeX\ is occasionally supposed to print diagnostic information that
-goes only into the transcript file, unless |tracing_online| is positive.
-Here are two routines that adjust the destination of print commands:
-
-@p procedure begin_diagnostic; {prepare to do some tracing}
-begin global_old_setting:=selector;
-if (tracing_online<=0)and(selector=term_and_log) then
- begin decr(selector);
- if history=spotless then history:=warning_issued;
- end;
-end;
-@#
-procedure end_diagnostic(@!blank_line:boolean);
- {restore proper conditions after tracing}
-begin print_nl("");
-if blank_line then print_ln;
-selector:=global_old_setting;
-end;
-
-@ Of course we had better declare another global variable, if the previous
-routines are going to work.
-
-@<Glob...@>=
-@!global_old_setting:0..max_selector;
-
-@ The final region of |eqtb| contains the dimension parameters defined
-here, and the |number_regs| \.{\\dimen} registers.
-
-@d par_indent_code=0 {indentation of paragraphs}
-@d math_surround_code=1 {space around math in text}
-@d line_skip_limit_code=2 {threshold for |line_skip| instead of |baseline_skip|}
-@d hsize_code=3 {line width in horizontal mode}
-@d vsize_code=4 {page height in vertical mode}
-@d max_depth_code=5 {maximum depth of boxes on main pages}
-@d split_max_depth_code=6 {maximum depth of boxes on split pages}
-@d box_max_depth_code=7 {maximum depth of explicit vboxes}
-@d hfuzz_code=8 {tolerance for overfull hbox messages}
-@d vfuzz_code=9 {tolerance for overfull vbox messages}
-@d delimiter_shortfall_code=10 {maximum amount uncovered by variable delimiters}
-@d null_delimiter_space_code=11 {blank space in null delimiters}
-@d script_space_code=12 {extra space after subscript or superscript}
-@d pre_display_size_code=13 {length of text preceding a display}
-@d display_width_code=14 {length of line for displayed equation}
-@d display_indent_code=15 {indentation of line for displayed equation}
-@d overfull_rule_code=16 {width of rule that identifies overfull hboxes}
-@d hang_indent_code=17 {amount of hanging indentation}
-@d h_offset_code=18 {amount of horizontal offset when shipping pages out}
-@d v_offset_code=19 {amount of vertical offset when shipping pages out}
-@d emergency_stretch_code=20 {reduces badnesses on final pass of line-breaking}
-@d page_left_offset_code=21
-@d page_top_offset_code=22
-@d page_right_offset_code=23
-@d page_bottom_offset_code=24
-@d pdftex_first_dimen_code = 25 {first number defined in this section}
-@d pdf_h_origin_code = pdftex_first_dimen_code + 0 {horigin of the PDF output}
-@d pdf_v_origin_code = pdftex_first_dimen_code + 1 {vorigin of the PDF output}
-@d page_width_code = pdftex_first_dimen_code + 2 {page width of the PDF output}
-@d page_height_code = pdftex_first_dimen_code + 3 {page height of the PDF output}
-@d pdf_link_margin_code = pdftex_first_dimen_code + 4 {link margin in the PDF output}
-@d pdf_dest_margin_code = pdftex_first_dimen_code + 5 {dest margin in the PDF output}
-@d pdf_thread_margin_code = pdftex_first_dimen_code + 6 {thread margin in the PDF output}
-@d pdf_first_line_height_code = pdftex_first_dimen_code + 7
-@d pdf_last_line_depth_code = pdftex_first_dimen_code + 8
-@d pdf_each_line_height_code = pdftex_first_dimen_code + 9
-@d pdf_each_line_depth_code = pdftex_first_dimen_code + 10
-@d pdf_ignored_dimen_code = pdftex_first_dimen_code + 11
-@d pdf_px_dimen_code = pdftex_first_dimen_code + 12
-@d pdftex_last_dimen_code = pdftex_first_dimen_code + 12 {last number defined in this section}
-@d dimen_pars = pdftex_last_dimen_code + 1 {total number of dimension parameters}
-@d scaled_base=dimen_base+dimen_pars
- {table of |number_regs| user-defined \.{\\dimen} registers}
-@d eqtb_size=scaled_base+biggest_reg {largest subscript of |eqtb|}
-@#
-@d dimen(#)==eqtb[scaled_base+#].sc
-@d dimen_par(#)==eqtb[dimen_base+#].sc {a scaled quantity}
-@d par_indent==dimen_par(par_indent_code)
-@d math_surround==dimen_par(math_surround_code)
-@d line_skip_limit==dimen_par(line_skip_limit_code)
-@d hsize==dimen_par(hsize_code)
-@d vsize==dimen_par(vsize_code)
-@d max_depth==dimen_par(max_depth_code)
-@d split_max_depth==dimen_par(split_max_depth_code)
-@d box_max_depth==dimen_par(box_max_depth_code)
-@d hfuzz==dimen_par(hfuzz_code)
-@d vfuzz==dimen_par(vfuzz_code)
-@d delimiter_shortfall==dimen_par(delimiter_shortfall_code)
-@d null_delimiter_space==dimen_par(null_delimiter_space_code)
-@d script_space==dimen_par(script_space_code)
-@d pre_display_size==dimen_par(pre_display_size_code)
-@d display_width==dimen_par(display_width_code)
-@d display_indent==dimen_par(display_indent_code)
-@d overfull_rule==dimen_par(overfull_rule_code)
-@d hang_indent==dimen_par(hang_indent_code)
-@d h_offset==dimen_par(h_offset_code)
-@d v_offset==dimen_par(v_offset_code)
-@d emergency_stretch==dimen_par(emergency_stretch_code)
-@d page_left_offset==dimen_par(page_left_offset_code)
-@d page_top_offset==dimen_par(page_top_offset_code)
-@d page_right_offset==dimen_par(page_right_offset_code)
-@d page_bottom_offset==dimen_par(page_bottom_offset_code)
-@d pdf_h_origin == dimen_par(pdf_h_origin_code)
-@d pdf_v_origin == dimen_par(pdf_v_origin_code)
-@d page_width == dimen_par(page_width_code)
-@d page_height == dimen_par(page_height_code)
-@d pdf_link_margin == dimen_par(pdf_link_margin_code)
-@d pdf_dest_margin == dimen_par(pdf_dest_margin_code)
-@d pdf_thread_margin == dimen_par(pdf_thread_margin_code)
-@d pdf_first_line_height == dimen_par(pdf_first_line_height_code)
-@d pdf_last_line_depth == dimen_par(pdf_last_line_depth_code)
-@d pdf_each_line_height == dimen_par(pdf_each_line_height_code)
-@d pdf_each_line_depth == dimen_par(pdf_each_line_depth_code)
-@d pdf_ignored_dimen == dimen_par(pdf_ignored_dimen_code)
-@d pdf_px_dimen == dimen_par(pdf_px_dimen_code)
-
-@p procedure print_length_param(@!n:integer);
-begin case n of
-par_indent_code:print_esc("parindent");
-math_surround_code:print_esc("mathsurround");
-line_skip_limit_code:print_esc("lineskiplimit");
-hsize_code:print_esc("hsize");
-vsize_code:print_esc("vsize");
-max_depth_code:print_esc("maxdepth");
-split_max_depth_code:print_esc("splitmaxdepth");
-box_max_depth_code:print_esc("boxmaxdepth");
-hfuzz_code:print_esc("hfuzz");
-vfuzz_code:print_esc("vfuzz");
-delimiter_shortfall_code:print_esc("delimitershortfall");
-null_delimiter_space_code:print_esc("nulldelimiterspace");
-script_space_code:print_esc("scriptspace");
-pre_display_size_code:print_esc("predisplaysize");
-display_width_code:print_esc("displaywidth");
-display_indent_code:print_esc("displayindent");
-overfull_rule_code:print_esc("overfullrule");
-hang_indent_code:print_esc("hangindent");
-h_offset_code:print_esc("hoffset");
-v_offset_code:print_esc("voffset");
-emergency_stretch_code:print_esc("emergencystretch");
-page_left_offset_code: print_esc("pageleftoffset");
-page_top_offset_code: print_esc("pagetopoffset");
-page_right_offset_code: print_esc("pagerightoffset");
-page_bottom_offset_code:print_esc("pagebottomoffset");
-pdf_h_origin_code: print_esc("pdfhorigin");
-pdf_v_origin_code: print_esc("pdfvorigin");
-page_width_code: print_esc("pagewidth");
-page_height_code: print_esc("pageheight");
-pdf_link_margin_code: print_esc("pdflinkmargin");
-pdf_dest_margin_code: print_esc("pdfdestmargin");
-pdf_thread_margin_code: print_esc("pdfthreadmargin");
-pdf_first_line_height_code: print_esc("pdffirstlineheight");
-pdf_last_line_depth_code: print_esc("pdflastlinedepth");
-pdf_each_line_height_code: print_esc("pdfeachlineheight");
-pdf_each_line_depth_code: print_esc("pdfeachlinedepth");
-pdf_ignored_dimen_code: print_esc("pdfignoreddimen");
-pdf_px_dimen_code: print_esc("pdfpxdimen");
-othercases print("[unknown dimen parameter!]")
-endcases;
-end;
-
-@ @<Put each...@>=
-primitive_tex("parindent",assign_dimen,dimen_base+par_indent_code,dimen_base);@/
-@!@:par_indent_}{\.{\\parindent} primitive@>
-primitive_tex("mathsurround",assign_dimen,dimen_base+math_surround_code,dimen_base);@/
-@!@:math_surround_}{\.{\\mathsurround} primitive@>
-primitive_tex("lineskiplimit",assign_dimen,dimen_base+line_skip_limit_code,dimen_base);@/
-@!@:line_skip_limit_}{\.{\\lineskiplimit} primitive@>
-primitive_tex("hsize",assign_dimen,dimen_base+hsize_code,dimen_base);@/
-@!@:hsize_}{\.{\\hsize} primitive@>
-primitive_tex("vsize",assign_dimen,dimen_base+vsize_code,dimen_base);@/
-@!@:vsize_}{\.{\\vsize} primitive@>
-primitive_tex("maxdepth",assign_dimen,dimen_base+max_depth_code,dimen_base);@/
-@!@:max_depth_}{\.{\\maxdepth} primitive@>
-primitive_tex("splitmaxdepth",assign_dimen,dimen_base+split_max_depth_code,dimen_base);@/
-@!@:split_max_depth_}{\.{\\splitmaxdepth} primitive@>
-primitive_tex("boxmaxdepth",assign_dimen,dimen_base+box_max_depth_code,dimen_base);@/
-@!@:box_max_depth_}{\.{\\boxmaxdepth} primitive@>
-primitive_tex("hfuzz",assign_dimen,dimen_base+hfuzz_code,dimen_base);@/
-@!@:hfuzz_}{\.{\\hfuzz} primitive@>
-primitive_tex("vfuzz",assign_dimen,dimen_base+vfuzz_code,dimen_base);@/
-@!@:vfuzz_}{\.{\\vfuzz} primitive@>
-primitive_tex("delimitershortfall", assign_dimen,dimen_base+delimiter_shortfall_code,dimen_base);@/
-@!@:delimiter_shortfall_}{\.{\\delimitershortfall} primitive@>
-primitive_tex("nulldelimiterspace", assign_dimen,dimen_base+null_delimiter_space_code,dimen_base);@/
-@!@:null_delimiter_space_}{\.{\\nulldelimiterspace} primitive@>
-primitive_tex("scriptspace",assign_dimen,dimen_base+script_space_code,dimen_base);@/
-@!@:script_space_}{\.{\\scriptspace} primitive@>
-primitive_tex("predisplaysize",assign_dimen,dimen_base+pre_display_size_code,dimen_base);@/
-@!@:pre_display_size_}{\.{\\predisplaysize} primitive@>
-primitive_tex("displaywidth",assign_dimen,dimen_base+display_width_code,dimen_base);@/
-@!@:display_width_}{\.{\\displaywidth} primitive@>
-primitive_tex("displayindent",assign_dimen,dimen_base+display_indent_code,dimen_base);@/
-@!@:display_indent_}{\.{\\displayindent} primitive@>
-primitive_tex("overfullrule",assign_dimen,dimen_base+overfull_rule_code,dimen_base);@/
-@!@:overfull_rule_}{\.{\\overfullrule} primitive@>
-primitive_tex("hangindent",assign_dimen,dimen_base+hang_indent_code,dimen_base);@/
-@!@:hang_indent_}{\.{\\hangindent} primitive@>
-primitive_tex("hoffset",assign_dimen,dimen_base+h_offset_code,dimen_base);@/
-@!@:h_offset_}{\.{\\hoffset} primitive@>
-primitive_tex("voffset",assign_dimen,dimen_base+v_offset_code,dimen_base);@/
-@!@:v_offset_}{\.{\\voffset} primitive@>
-primitive_tex("emergencystretch",assign_dimen,dimen_base+emergency_stretch_code,dimen_base);@/
-@!@:emergency_stretch_}{\.{\\emergencystretch} primitive@>
-primitive_pdftex("pdfhorigin",assign_dimen,dimen_base+pdf_h_origin_code,dimen_base);@/
-@!@:pdf_h_origin_}{\.{\\pdfhorigin} primitive@>
-primitive_pdftex("pdfvorigin",assign_dimen,dimen_base+pdf_v_origin_code,dimen_base);@/
-@!@:pdf_v_origin_}{\.{\\pdfvorigin} primitive@>
-@#
-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_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_pdftex("pdflinkmargin",assign_dimen,dimen_base+pdf_link_margin_code,dimen_base);@/
-@!@:pdf_link_margin_}{\.{\\pdflinkmargin} primitive@>
-primitive_pdftex("pdfdestmargin",assign_dimen,dimen_base+pdf_dest_margin_code,dimen_base);@/
-@!@:pdf_dest_margin_}{\.{\\pdfdestmargin} primitive@>
-primitive_pdftex("pdfthreadmargin",assign_dimen,dimen_base+pdf_thread_margin_code,dimen_base);@/
-@!@:pdf_thread_margin_}{\.{\\pdfthreadmargin} primitive@>
-primitive_pdftex("pdffirstlineheight",assign_dimen,dimen_base+pdf_first_line_height_code,dimen_base);@/
-@!@:pdf_first_line_height_}{\.{\\pdffirstlineheight} primitive@>
-primitive_pdftex("pdflastlinedepth",assign_dimen,dimen_base+pdf_last_line_depth_code,dimen_base);@/
-@!@:pdf_last_line_depth_}{\.{\\pdflastlinedepth} primitive@>
-primitive_pdftex("pdfeachlineheight",assign_dimen,dimen_base+pdf_each_line_height_code,dimen_base);@/
-@!@:pdf_each_line_height_}{\.{\\pdfeachlineheight} primitive@>
-primitive_pdftex("pdfeachlinedepth",assign_dimen,dimen_base+pdf_each_line_depth_code,dimen_base);@/
-@!@:pdf_each_line_depth_}{\.{\\pdfeachlinedepth} primitive@>
-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@>
-
-@ @<Initialize table entries...@>=
-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;
-
-@ @<Initialize table entries...@>=
-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;
-
-
-@ @<Show equivalent |n|, in region 6@>=
-begin if n<scaled_base then print_length_param(n-dimen_base)
-else begin print_esc("dimen"); print_int(n-scaled_base);
- end;
-print_char("="); print_scaled(eqtb[n].sc); print("pt");
-end
-
-@ Here is a procedure that displays the contents of |eqtb[n]|
-symbolically.
-
-@p
-@!stat procedure show_eqtb(@!n:pointer);
-begin if n<null_cs then print_char("?") {this can't happen}
-else if n<glue_base then @<Show equivalent |n|, in region 1 or 2@>
-else if n<local_base then @<Show equivalent |n|, in region 3@>
-else if n<int_base then @<Show equivalent |n|, in region 4@>
-else if n<dimen_base then @<Show equivalent |n|, in region 5@>
-else if n<=eqtb_size then @<Show equivalent |n|, in region 6@>
-else print_char("?"); {this can't happen either}
-end;
-tats
-
-@ The last two regions of |eqtb| have fullword values instead of the
-three fields |eq_level|, |eq_type|, and |equiv|. An |eq_type| is unnecessary,
-but \TeX\ needs to store the |eq_level| information in another array
-called |xeq_level|.
-
-@<Glob...@>=
-@!eqtb:array[null_cs..eqtb_size] of memory_word;
-@!xeq_level:array[null_cs..eqtb_size] of quarterword;
-
-@ @<Set init...@>=
-for k:=int_base to eqtb_size do xeq_level[k]:=level_one;
-
-@* \[18] The hash table.
-Control sequences are stored and retrieved by means of a fairly standard hash
-table algorithm called the method of ``coalescing lists'' (cf.\ Algorithm 6.4C
-in {\sl The Art of Computer Programming\/}). Once a control sequence enters the
-table, it is never removed, because there are complicated situations
-involving \.{\\gdef} where the removal of a control sequence at the end of
-a group would be a mistake preventable only by the introduction of a
-complicated reference-count mechanism.
-
-The actual sequence of letters forming a control sequence identifier is
-stored in the |str_pool| array together with all the other strings. An
-auxiliary array |hash| consists of items with two halfword fields per
-word. The first of these, called |next(p)|, points to the next identifier
-belonging to the same coalesced list as the identifier corresponding to~|p|;
-and the other, called |text(p)|, points to the |str_start| entry for
-|p|'s identifier. If position~|p| of the hash table is empty, we have
-|text(p)=0|; if position |p| is either empty or the end of a coalesced
-hash list, we have |next(p)=0|. An auxiliary pointer variable called
-|hash_used| is maintained in such a way that all locations |p>=hash_used|
-are nonempty. The global variable |cs_count| tells how many multiletter
-control sequences have been defined, if statistics are being kept.
-
-A global boolean variable called |no_new_control_sequence| is set to
-|true| during the time that new hash table entries are forbidden.
-
-@d next(#) == hash[#].lh {link for coalesced lists}
-@d text(#) == hash[#].rh {string number for control sequence name}
-@d hash_is_full == (hash_used=hash_base) {test if all positions are occupied}
-@d font_id_text(#) == text(font_id_base+#) {a frozen font identifier's name}
-@d ocp_id_text(#) == text(ocp_id_base+#) {a frozen ocp identifier's name}
-@d ocp_list_id_text(#) == text(ocp_list_id_base+#)
- {a frozen ocp list identifier's name}
-
-@<Glob...@>=
-@!hash: array[hash_base..undefined_control_sequence-1] of two_halves;
- {the hash table}
-@!hash_used:pointer; {allocation pointer for |hash|}
-@!no_new_control_sequence:boolean; {are new identifiers legal?}
-@!cs_count:integer; {total number of known identifiers}
-
-@ The extra set of functions make sure we can query the
-primitive meanings of thing s from C code
-
-@p
-function get_eq_type(p:integer):quarterword;
-begin
- get_eq_type := eq_type(p);
-end;
-function get_eq_level(p:integer):quarterword;
-begin
- get_eq_level := eq_level(p);
-end;
-function is_undefined_cs(cs:integer):boolean;
-begin
- is_undefined_cs := (cs=undefined_cs);
-end;
-function get_equiv(p:integer):halfword;
-begin
- get_equiv := equiv(p);
-end;
-function get_cs_text(cs:integer):str_number;
-begin if cs=null_cs then get_cs_text := "\csname\endcsname"
- else if (text(cs)<0)or(text(cs)>=str_ptr) then get_cs_text := ""
- else get_cs_text := text(cs);
-end;
-function get_max_command:integer;
-begin
- get_max_command := max_command;
-end;
-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;
-end;
-function get_scaled_base:halfword;
-begin
- get_scaled_base := scaled_base;
-end;
-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;
-end;
-function get_suppress_fontnotfound_error:boolean;
-begin
- get_suppress_fontnotfound_error := suppress_fontnotfound_error;
-end;
-function get_pdf_image_resolution:integer;
-begin
- get_pdf_image_resolution := pdf_image_resolution;
-end;
-function get_pdf_minor_version:integer;
-begin
- get_pdf_minor_version := pdf_minor_version;
-end;
-function get_pdf_inclusion_errorlevel:integer;
-begin
- get_pdf_inclusion_errorlevel := pdf_inclusion_errorlevel;
-end;
-
-@ @<Set init...@>=
-no_new_control_sequence:=true; {new identifiers are usually forbidden}
-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];
-
-@ @<Initialize table entries...@>=
-ini_init_primitives;
-hash_used:=frozen_control_sequence; {nothing is used}
-cs_count:=0;
-eq_type(frozen_dont_expand):=dont_expand;
-text(frozen_dont_expand):="notexpanded:";
-@.notexpanded:@>
-
-eq_type(frozen_primitive):=ignore_spaces;
-equiv(frozen_primitive):=1;
-eq_level(frozen_primitive):=level_one;
-text(frozen_primitive):="primitive";
-
-
-@ 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
-unless it is a single nonletter or an active character. This procedure
-might be invoked with invalid data, so it is ``extra robust.'' The
-individual characters must be printed one at a time using |print|, since
-they may be unprintable.
-
-@d single_letter(#)==(length(#)=1)or
- ((length(#)=4)and(str_pool[str_start_macro(#)]>=@"F0))or
- ((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)
-
-@<Basic printing...@>=
-procedure print_cs(@!p:integer); {prints a purported control sequence}
-begin if p<hash_base then { nullcs}
- if p=null_cs then
- begin print_esc("csname"); print_esc("endcsname");
- end
- else print_esc("IMPOSSIBLE.")
-@.IMPOSSIBLE@>
-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
- 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
- print_char(" ");
- end
- end;
-end;
-
-@ Here is a similar procedure; it avoids the error checks, and it never
-prints a space after the control sequence.
-
-@<Basic printing procedures@>=
-procedure sprint_cs(@!p:pointer); {prints a control sequence}
-begin if p=null_cs then begin
- print_esc("csname"); print_esc("endcsname");
- end
-else begin
- if is_active_csname(p) then
- print(active_csname_value(p))
- else
- print_esc(text(p));
- end;
-end;
-
-
-@ 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:
-
-@<Put each of \TeX's primitives into the hash table@>=
-primitive_tex(" ",ex_space,0,0);@/
-@!@:Single-character primitives /}{\quad\.{\\\ }@>
-primitive_tex("/",ital_corr,0,0);@/
-@!@:Single-character primitives /}{\quad\.{\\/}@>
-primitive_tex("accent",accent,0,0);@/
-@!@:accent_}{\.{\\accent} primitive@>
-primitive_tex("advance",advance,0,0);@/
-@!@:advance_}{\.{\\advance} primitive@>
-primitive_tex("afterassignment",after_assignment,0,0);@/
-@!@:after_assignment_}{\.{\\afterassignment} primitive@>
-primitive_tex("aftergroup",after_group,0,0);@/
-@!@:after_group_}{\.{\\aftergroup} primitive@>
-primitive_tex("begingroup",begin_group,0,0);@/
-@!@:begin_group_}{\.{\\begingroup} primitive@>
-primitive_tex("char",char_num,0,0);@/
-@!@:char_}{\.{\\char} primitive@>
-primitive_tex("csname",cs_name,0,0);@/
-@!@:cs_name_}{\.{\\csname} primitive@>
-primitive_tex("delimiter",delim_num,0,0);@/
-@!@:delimiter_}{\.{\\delimiter} primitive@>
-primitive_omega("odelimiter",delim_num,1,0);@/
-@!@:odelimiter_}{\.{\\odelimiter} primitive@>
-primitive_luatex("Udelimiter",delim_num,2,0);@/
-@!@:odelimiter_}{\.{\\Udelimiter} primitive@>
-primitive_tex("divide",divide,0,0);@/
-@!@:divide_}{\.{\\divide} primitive@>
-primitive_tex("endcsname",end_cs_name,0,0);@/
-@!@:end_cs_name_}{\.{\\endcsname} primitive@>
-primitive_tex("endgroup",end_group,0,0);
-@!@:end_group_}{\.{\\endgroup} primitive@>
-text(frozen_end_group):="endgroup"; eqtb[frozen_end_group]:=eqtb[cur_val];@/
-primitive_tex("expandafter",expand_after,0,0);@/
-@!@:expand_after_}{\.{\\expandafter} primitive@>
-primitive_tex("font",def_font,0,0);@/
-@!@:font_}{\.{\\font} primitive@>
-primitive_pdftex("letterspacefont",letterspace_font,0,0);@/
-@!@:letterspace_font_}{\.{\\letterspacefont} primitive@>
-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_tex("halign",halign,0,0);@/
-@!@:halign_}{\.{\\halign} primitive@>
-primitive_tex("hrule",hrule,0,0);@/
-@!@:hrule_}{\.{\\hrule} primitive@>
-primitive_tex("ignorespaces",ignore_spaces,0,0);@/
-@!@:ignore_spaces_}{\.{\\ignorespaces} primitive@>
-primitive_tex("insert",insert,0,0);@/
-@!@:insert_}{\.{\\insert} primitive@>
-primitive_omega("leftghost",char_ghost,0,0);@/
-@!@:leftghost_}{\.{\\leftghost} primitive@>
-primitive_tex("mark",mark,0,0);@/
-@!@:mark_}{\.{\\mark} primitive@>
-primitive_tex("mathaccent",math_accent,0,0);@/
-@!@:math_accent_}{\.{\\mathaccent} primitive@>
-primitive_omega("omathaccent",math_accent,1,0);@/
-@!@:math_accent_}{\.{\\omathaccent} primitive@>
-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_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_luatex("Ustack",math_choice,1,0);@/
-@!@:math_choice_}{\.{\\Ustack} primitive@>
-primitive_tex("multiply",multiply,0,0);@/
-@!@:multiply_}{\.{\\multiply} primitive@>
-primitive_tex("noalign",no_align,0,0);@/
-@!@:no_align_}{\.{\\noalign} primitive@>
-primitive_tex("noboundary",no_boundary,0,0);@/
-@!@:no_boundary_}{\.{\\noboundary} primitive@>
-primitive_tex("noexpand",no_expand,0,0);@/
-@!@:no_expand_}{\.{\\noexpand} primitive@>
-primitive_luatex("primitive",no_expand,1,0);@/
-@!@:primitive_}{\.{\\primitive} primitive@>
-primitive_pdftex("pdfprimitive",no_expand,1,0);@/
-@!@:pdfprimitive_}{\.{\\pdfprimitive} primitive@>
-primitive_tex("nonscript",non_script,0,0);@/
-@!@:non_script_}{\.{\\nonscript} primitive@>
-primitive_tex("omit",omit,0,0);@/
-@!@:omit_}{\.{\\omit} primitive@>
-primitive_tex("parshape",set_tex_shape,par_shape_loc,par_shape_loc);@/
-@!@:par_shape_}{\.{\\parshape} primitive@>
-primitive_tex("penalty",break_penalty,0,0);@/
-@!@:penalty_}{\.{\\penalty} primitive@>
-primitive_tex("prevgraf",set_prev_graf,0,0);@/
-@!@:prev_graf_}{\.{\\prevgraf} primitive@>
-primitive_tex("radical",radical,0,0);@/
-@!@:radical_}{\.{\\radical} primitive@>
-primitive_omega("oradical",radical,1,0);@/
-@!@:radical_}{\.{\\oradical} primitive@>
-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_tex("relax",relax,too_big_char,too_big_char);
-@!@:relax_}{\.{\\relax} primitive@>
-text(frozen_relax):="relax"; eqtb[frozen_relax]:=eqtb[cur_val];@/
-primitive_omega("rightghost",char_ghost,1,0);@/
-@!@:rightghost_}{\.{\\rightghost} primitive@>
-primitive_tex("setbox",set_box,0,0);@/
-@!@:set_box_}{\.{\\setbox} primitive@>
-primitive_tex("the",the,0,0);@/
-@!@:the_}{\.{\\the} primitive@>
-primitive_tex("toks",toks_register,0,0);@/
-@!@:toks_}{\.{\\toks} primitive@>
-primitive_tex("vadjust",vadjust,0,0);@/
-@!@:vadjust_}{\.{\\vadjust} primitive@>
-primitive_tex("valign",valign,0,0);@/
-@!@:valign_}{\.{\\valign} primitive@>
-primitive_tex("vcenter",vcenter,0,0);@/
-@!@:vcenter_}{\.{\\vcenter} primitive@>
-primitive_tex("vrule",vrule,0,0);@/
-@!@:vrule_}{\.{\\vrule} primitive@>
-
-@ Each primitive has a corresponding inverse, so that it is possible to
-display the cryptic numeric contents of |eqtb| in symbolic form.
-Every call of |primitive| in this program is therefore accompanied by some
-straightforward code that forms part of the |print_cmd_chr| routine
-below.
-
-@ 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
-that deal with formulas. It is easy to find where each particular
-primitive was treated by looking in the index at the end; for example, the
-section where |"radical"| entered |eqtb| is listed under `\.{\\radical}
-primitive'. (Primitives consisting of a single nonalphabetic character,
-@!like `\.{\\/}', are listed under `Single-character primitives'.)
-@!@^Single-character primitives@>
-
-
-@* \[19] Saving and restoring equivalents.
-The nested structure provided by `$\.{\char'173}\ldots\.{\char'175}$' groups
-in \TeX\ means that |eqtb| entries valid in outer groups should be saved
-and restored later if they are overridden inside the braces. When a new |eqtb|
-value is being assigned, the program therefore checks to see if the previous
-entry belongs to an outer level. In such a case, the old value is placed
-on the |save_stack| just before the new value enters |eqtb|. At the
-end of a grouping level, i.e., when the right brace is sensed, the
-|save_stack| is used to restore the outer values, and the inner ones are
-destroyed.
-
-Entries on the |save_stack| are of type |memory_word|. The top item on
-this stack is |save_stack[p]|, where |p=save_ptr-1|; it contains three
-fields called |save_type|, |save_level|, and |save_index|, and it is
-interpreted in one of four ways:
-
-\yskip\hangg 1) If |save_type(p)=restore_old_value|, then
-|save_index(p)| is a location in |eqtb| whose current value should
-be destroyed at the end of the current group and replaced by |save_stack[p-1]|.
-Furthermore if |save_index(p)>=int_base|, then |save_level(p)|
-should replace the corresponding entry in |xeq_level|.
-
-\yskip\hangg 2) If |save_type(p)=restore_zero|, then |save_index(p)|
-is a location in |eqtb| whose current value should be destroyed at the end
-of the current group, when it should be
-replaced by the current value of |eqtb[undefined_control_sequence]|.
-
-\yskip\hangg 3) If |save_type(p)=insert_token|, then |save_index(p)|
-is a token that should be inserted into \TeX's input when the current
-group ends.
-
-\yskip\hangg 4) If |save_type(p)=level_boundary|, then |save_level(p)|
-is a code explaining what kind of group we were previously in, and
-|save_index(p)| points to the level boundary word at the bottom of
-the entries for that group.
-Furthermore, in extended \eTeX\ mode, |save_stack[p-1]| contains the
-source line number at which the current level of grouping was entered.
-
-@d save_type(#)==save_stack[#].hh.b0 {classifies a |save_stack| entry}
-@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 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}
-@d level_boundary=3 {|save_type| corresponding to beginning of group}
-
-@p@t\4@>@<Declare \eTeX\ procedures for tracing and input@>
-
-@ Here are the group codes that are used to discriminate between different
-kinds of groups. They allow \TeX\ to decide what special actions, if any,
-should be performed when a group ends.
-\def\grp{\.{\char'173...\char'175}}
-
-Some groups are not supposed to be ended by right braces. For example,
-the `\.\$' that begins a math formula causes a |math_shift_group| to
-be started, and this should be terminated by a matching `\.\$'. Similarly,
-a group that starts with \.{\\left} should end with \.{\\right}, and
-one that starts with \.{\\begingroup} should end with \.{\\endgroup}.
-
-@d bottom_level=0 {group code for the outside world}
-@d simple_group=1 {group code for local structure only}
-@d hbox_group=2 {code for `\.{\\hbox}\grp'}
-@d adjusted_hbox_group=3 {code for `\.{\\hbox}\grp' in vertical mode}
-@d vbox_group=4 {code for `\.{\\vbox}\grp'}
-@d vtop_group=5 {code for `\.{\\vtop}\grp'}
-@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 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'}
-@d math_choice_group=13 {code for `\.{\\mathchoice}\grp\grp\grp\grp'}
-@d semi_simple_group=14 {code for `\.{\\begingroup...\\endgroup}'}
-@d math_shift_group=15 {code for `\.{\$...\$}'}
-@d math_left_group=16 {code for `\.{\\left...\\right}'}
-@d local_box_group=17 {code for `\.{\\localleftbox...\\localrightbox}'}
-@d max_group_code=17
-@d split_off_group=18 {box code for the top part of a \.{\\vsplit}}
-@d split_keep_group=19 {box code for the bottom part of a \.{\\vsplit}}
-@d preamble_group=20 {box code for the preamble processing in an alignment}
-@d align_set_group=21 {box code for the final item pass in an alignment}
-@d fin_row_group=22 {box code for a provisory line in an alignment}
-
-@<Types...@>=
-@!group_code=0..max_group_code; {|save_level| for a level boundary}
-
-@ The global variable |cur_group| keeps track of what sort of group we are
-currently in. Another global variable, |cur_boundary|, points to the
-topmost |level_boundary| word. And |cur_level| is the current depth of
-nesting. The routines are designed to preserve the condition that no entry
-in the |save_stack| or in |eqtb| ever has a level greater than |cur_level|.
-
-@ @<Glob...@>=
-@!save_stack : array[0..save_size] of memory_word;
-@!save_ptr : 0..save_size; {first unused entry on |save_stack|}
-@!max_save_stack:0..save_size; {maximum usage of save stack}
-@!cur_level: quarterword; {current nesting level for groups}
-@!cur_group: group_code; {current group type}
-@!cur_boundary: 0..save_size; {where the current level begins}
-
-@ At this time it might be a good idea for the reader to review the introduction
-to |eqtb| that was given above just before the long lists of parameter names.
-Recall that the ``outer level'' of the program is |level_one|, since
-undefined control sequences are assumed to be ``defined'' at |level_zero|.
-
-@<Set init...@>=
-save_ptr:=0; cur_level:=level_one; cur_group:=bottom_level; cur_boundary:=0;
-max_save_stack:=0;
-
-@ The following macro is used to test if there is room for up to eight more
-entries on |save_stack|. By making a conservative test like this, we can
-get by with testing for overflow in only a few places.
-
-@d check_full_save_stack==if save_ptr>max_save_stack then
- begin max_save_stack:=save_ptr;
- if max_save_stack>save_size-8 then overflow("save size",save_size);
-@:TeX capacity exceeded save size}{\quad save size@>
- end
-
-@ Procedure |new_save_level| is called when a group begins. The
-argument is a group identification code like `|hbox_group|'. After
-calling this routine, it is safe to put six more entries on |save_stack|.
-
-In some cases integer-valued items are placed onto the
-|save_stack| just below a |level_boundary| word, because this is a
-convenient place to keep information that is supposed to ``pop up'' just
-when the group has finished.
-For example, when `\.{\\hbox to 100pt}\grp' is being treated, the 100pt
-dimension is stored on |save_stack| just before |new_save_level| is
-called.
-
-We use the notation |saved(k)| to stand for an integer item that
-appears in location |save_ptr+k| of the save stack.
-
-@d saved(#)==save_stack[save_ptr+#].int
-
-@p procedure new_save_level(@!c:group_code); {begin a new level of grouping}
-begin check_full_save_stack;
-saved(0):=line; incr(save_ptr);
-save_type(save_ptr):=level_boundary; save_level(save_ptr):=cur_group;
-save_index(save_ptr):=cur_boundary;
-if cur_level=max_quarterword then overflow("grouping levels",
-@:TeX capacity exceeded grouping levels}{\quad grouping levels@>
- max_quarterword-min_quarterword);
- {quit if |(cur_level+1)| is too big to be stored in |eqtb|}
-cur_boundary:=save_ptr; cur_group:=c;
-@!stat if tracing_groups>0 then group_trace(false);@+tats@;@/
-incr(cur_level); incr(save_ptr);
-end;
-
-@ Just before an entry of |eqtb| is changed, the following procedure should
-be called to update the other data structures properly. It is important
-to keep in mind that reference counts in |mem| include references from
-within |save_stack|, so these counts must be handled carefully.
-@^reference counts@>
-
-@p procedure eq_destroy(@!w:memory_word); {gets ready to forget |w|}
-var q:pointer; {|equiv| field of |w|}
-begin case eq_type_field(w) of
-call,long_call,outer_call,long_outer_call: delete_token_ref(equiv_field(w));
-glue_ref: delete_glue_ref(equiv_field(w));
-shape_ref: begin q:=equiv_field(w); {we need to free a \.{\\parshape} block}
- if q<>null then flush_node(q);
- end; {such a block is |2n+1| words long, where |n=vinfo(q)|}
-box_ref: flush_node_list(equiv_field(w));
-othercases do_nothing
-endcases;
-end;
-
-@ To save a value of |eqtb[p]| that was established at level |l|, we
-can use the following subroutine.
-
-@p procedure eq_save(@!p:pointer;@!l:quarterword); {saves |eqtb[p]|}
-begin check_full_save_stack;
-if l=level_zero then save_type(save_ptr):=restore_zero
-else begin save_stack[save_ptr]:=eqtb[p]; incr(save_ptr);
- save_type(save_ptr):=restore_old_value;
- end;
-save_level(save_ptr):=l; save_index(save_ptr):=p; incr(save_ptr);
-end;
-
-@ The procedure |eq_define| defines an |eqtb| entry having specified
-|eq_type| and |equiv| fields, and saves the former value if appropriate.
-This procedure is used only for entries in the first four regions of |eqtb|,
-i.e., only for entries that have |eq_type| and |equiv| fields.
-After calling this routine, it is safe to put four more entries on
-|save_stack|, provided that there was room for four more entries before
-the call, since |eq_save| makes the necessary test.
-
-@d assign_trace(#)==@!stat if tracing_assigns>0 then restore_trace(#);
- tats
-
-@p procedure eq_define(@!p:pointer;@!t:quarterword;@!e:halfword);
- {new data for |eqtb|}
-label exit;
-begin if (eq_type(p)=t)and(equiv(p)=e) then
- begin assign_trace(p,"reassigning")@;@/
- eq_destroy(eqtb[p]); return;
- end;
-assign_trace(p,"changing")@;@/
-if eq_level(p)=cur_level then eq_destroy(eqtb[p])
-else if cur_level>level_one then eq_save(p,eq_level(p));
-eq_level(p):=cur_level; eq_type(p):=t; equiv(p):=e;
-assign_trace(p,"into")@;@/
-exit:end;
-
-@ The counterpart of |eq_define| for the remaining (fullword) positions in
-|eqtb| is called |eq_word_define|. Since |xeq_level[p]>=level_one| for all
-|p|, a `|restore_zero|' will never be used in this case.
-
-@p procedure eq_word_define(@!p:pointer;@!w:integer);
-label exit;
-begin if eqtb[p].int=w then
- begin assign_trace(p,"reassigning")@;@/
- return;
- end;
-assign_trace(p,"changing")@;@/
-if xeq_level[p]<>cur_level then
- begin eq_save(p,xeq_level[p]); xeq_level[p]:=cur_level;
- end;
-eqtb[p].int:=w;
-assign_trace(p,"into")@;@/
-exit:end;
-
-@ The |eq_define| and |eq_word_define| routines take care of local definitions.
-@^global definitions@>
-Global definitions are done in almost the same way, but there is no need
-to save old values, and the new value is associated with |level_one|.
-
-@p procedure geq_define(@!p:pointer;@!t:quarterword;@!e:halfword);
- {global |eq_define|}
-begin assign_trace(p,"globally changing")@;@/
-begin eq_destroy(eqtb[p]);
-eq_level(p):=level_one; eq_type(p):=t; equiv(p):=e;
-end;
-assign_trace(p,"into")@;@/
-end;
-@#
-procedure geq_word_define(@!p:pointer;@!w:integer); {global |eq_word_define|}
-begin assign_trace(p,"globally changing")@;@/
-begin eqtb[p].int:=w; xeq_level[p]:=level_one;
-end;
-assign_trace(p,"into")@;@/
-end;
-
-@ Subroutine |save_for_after| puts a token on the stack for save-keeping.
-
-@p procedure save_for_after(@!t:halfword);
-begin if cur_level>level_one then
- begin check_full_save_stack;
- save_type(save_ptr):=insert_token; save_level(save_ptr):=level_zero;
- save_index(save_ptr):=t; incr(save_ptr);
- end;
-end;
-
-@ The |unsave| routine goes the other way, taking items off of |save_stack|.
-This routine takes care of restoration when a level ends; everything
-belonging to the topmost group is cleared off of the save stack.
-
-@p
-procedure@?back_input; forward; @t\2@>
-procedure unsave; {pops the top level off the save stack}
-label done;
-var p:pointer; {position to be restored}
-@!l:quarterword; {saved level, if in fullword regions of |eqtb|}
-@!t:halfword; {saved value of |cur_tok|}
-@!a:boolean; {have we already processed an \.{\\aftergroup} ?}
-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);
- @<Clear off top level from |save_stack|@>;
- end
-else confusion("curlevel"); {|unsave| is not used when |cur_group=bottom_level|}
-@:this can't happen curlevel}{\quad curlevel@>
-attr_list_cache:=cache_disabled;
-end;
-
-@ @<Clear off...@>=
-loop@+begin decr(save_ptr);
- if save_type(save_ptr)=level_boundary then goto done;
- p:=save_index(save_ptr);
- if save_type(save_ptr)=insert_token then
- @<Insert token |p| into \TeX's input@>
- else begin if save_type(save_ptr)=restore_old_value then
- begin l:=save_level(save_ptr); decr(save_ptr);
- end
- else save_stack[save_ptr]:=eqtb[undefined_control_sequence];
- @<Store \(s)|save_stack[save_ptr]| in |eqtb[p]|, unless
- |eqtb[p]| holds a global value@>;
- end;
- end;
-done: @!stat if tracing_groups>0 then group_trace(true);@+tats@;@/
-if grp_stack[in_open]=cur_boundary then group_warning;
- {groups possibly not properly nested with files}
-cur_group:=save_level(save_ptr); cur_boundary:=save_index(save_ptr);
-decr(save_ptr)
-
-@ A global definition, which sets the level to |level_one|,
-@^global definitions@>
-will not be undone by |unsave|. If at least one global definition of
-|eqtb[p]| has been carried out within the group that just ended, the
-last such definition will therefore survive.
-
-@<Store \(s)|save...@>=
-if p<int_base then
- if eq_level(p)=level_one then
- begin eq_destroy(save_stack[save_ptr]); {destroy the saved value}
- @!stat if tracing_restores>0 then restore_trace(p,"retaining");@+tats@;@/
- end
- else begin eq_destroy(eqtb[p]); {destroy the current value}
- eqtb[p]:=save_stack[save_ptr]; {restore the saved value}
- @!stat if tracing_restores>0 then restore_trace(p,"restoring");@+tats@;@/
- end
-else if xeq_level[p]<>level_one then
- begin eqtb[p]:=save_stack[save_ptr]; xeq_level[p]:=l;
- @!stat if tracing_restores>0 then restore_trace(p,"restoring");@+tats@;@/
- end
-else begin
- @!stat if tracing_restores>0 then restore_trace(p,"retaining");@+tats@;@/
- end
-
-@ @<Declare \eTeX\ procedures for tr...@>=
-@!stat procedure restore_trace(@!p:pointer;@!s:str_number);
- {|eqtb[p]| has just been restored or retained}
-begin begin_diagnostic; print_char("{"); print(s); print_char(" ");
-show_eqtb(p); print_char("}");
-end_diagnostic(false);
-end;
-tats
-
-@ Most of the parameters kept in |eqtb| can be changed freely, but there's
-an exception: The magnification should not be used with two different
-values during any \TeX\ job, since a single magnification is applied to an
-entire run. The global variable |mag_set| is set to the current magnification
-whenever it becomes necessary to ``freeze'' it at a particular value.
-
-@<Glob...@>=
-@!mag_set:integer; {if nonzero, this magnification should be used henceforth}
-
-@ @<Set init...@>=
-mag_set:=0;
-
-@ The |prepare_mag| subroutine is called whenever \TeX\ wants to use |mag|
-for magnification.
-
-@p procedure prepare_mag;
-begin if (mag_set>0)and(mag<>mag_set) then
- begin print_err("Incompatible magnification ("); print_int(mag);
-@.Incompatible magnification@>
- print(");"); print_nl(" the previous value will be retained");
- help2("I can handle only one magnification ratio per job. So I've")@/
- ("reverted to the magnification you used earlier on this run.");@/
- int_error(mag_set);
- geq_word_define(int_base+mag_code,mag_set); {|mag:=mag_set|}
- end;
-if (mag<=0)or(mag>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(mag); geq_word_define(int_base+mag_code,1000);
- end;
-if (mag_set=0) and (mag<>mag_set) then begin
- if mag<>1000 then
- one_true_inch:=xn_over_d(one_hundred_inch,10,mag)
- else
- one_true_inch:=one_inch;
-end;
-mag_set:=mag;
-end;
-
-@* \[20] Token lists.
-A \TeX\ token is either a character or a control sequence, and it is
-@^token@>
-represented internally in one of two ways: (1)~A character whose ASCII
-code number is |c| and whose command code is |m| is represented as the
-number $2^{21}m+c$; the command code is in the range |1<=m<=14|. (2)~A control
-sequence whose |eqtb| address is |p| is represented as the number
-|cs_token_flag+p|. Here |cs_token_flag=@t$2^{25}-1$@>| is larger than
-$2^{21}m+c$, yet it is small enough that |cs_token_flag+p< max_halfword|;
-thus, a token fits comfortably in a halfword.
-
-A token |t| represents a |left_brace| command if and only if
-|t<left_brace_limit|; it represents a |right_brace| command if and only if
-we have |left_brace_limit<=t<right_brace_limit|; and it represents a |match| or
-|end_match| command if and only if |match_token<=t<=end_match_token|.
-The following definitions take care of these token-oriented constants
-and a few others.
-
-@d cs_token_flag==@"1FFFFFFF {amount added to the |eqtb| location in a
- token that stands for a control sequence; is a multiple of~$2^{21}$, less~1}
-@d left_brace_token=@"200000 {$2^{21}\cdot|left_brace|$}
-@d left_brace_limit=@"400000 {$2^{21}\cdot(|left_brace|+1)$}
-@d right_brace_token=@"400000 {$2^{21}\cdot|right_brace|$}
-@d right_brace_limit=@"600000 {$2^{21}\cdot(|right_brace|+1)$}
-@d math_shift_token= @"600000 {$2^{21}\cdot|math_shift|$}
-@d tab_token=@"800000 {$2^{21}\cdot|tab_mark|$}
-@d out_param_token=@"A00000 {$2^{21}\cdot|out_param|$}
-@d space_token=@"1400020 {$2^{21}\cdot|spacer|+|" "|$}
-@d letter_token=@"1600000 {$2^{21}\cdot|letter|$}
-@d other_token=@"1800000 {$2^{21}\cdot|other_char|$}
-@d match_token=@"1A00000 {$2^{21}\cdot|match|$}
-@d end_match_token=@"1C00000 {$2^{21}\cdot|end_match|$}
-@d protected_token=@"1C00001 {$2^{21}\cdot|end_match|+1$}
-
-@ @<Check the ``constant''...@>=
-if cs_token_flag+undefined_control_sequence>max_halfword then bad:=21;
-
-@ A token list is a singly linked list of one-word nodes in |mem|, where
-each word contains a token and a link. Macro definitions, output-routine
-definitions, marks, \.{\\write} texts, and a few other things
-are remembered by \TeX\ in the form
-of token lists, usually preceded by a node with a reference count in its
-|token_ref_count| field. The token stored in location |p| is called
-|info(p)|.
-
-Three special commands appear in the token lists of macro definitions.
-When |m=match|, it means that \TeX\ should scan a parameter
-for the current macro; when |m=end_match|, it means that parameter
-matching should end and \TeX\ should start reading the macro text; and
-when |m=out_param|, it means that \TeX\ should insert parameter
-number |c| into the text at this point.
-
-The enclosing \.{\char'173} and \.{\char'175} characters of a macro
-definition are omitted, but the final right brace of an output routine
-is included at the end of its token list.
-
-Here is an example macro definition that illustrates these conventions.
-After \TeX\ processes the text
-$$\.{\\def\\mac a\#1\#2 \\b \{\#1\\-a \#\#1\#2 \#2\}}$$
-the definition of \.{\\mac} is represented as a token list containing
-$$\def\,{\hskip2pt}
-\vbox{\halign{\hfil#\hfil\cr
-(reference count), |letter|\,\.a, |match|\,\#, |match|\,\#, |spacer|\,\.\ ,
-\.{\\b}, |end_match|,\cr
-|out_param|\,1, \.{\\-}, |letter|\,\.a, |spacer|\,\.\ , |mac_param|\,\#,
-|other_char|\,\.1,\cr
-|out_param|\,2, |spacer|\,\.\ , |out_param|\,2.\cr}}$$
-The procedure |scan_toks| builds such token lists, and |macro_call|
-does the parameter matching.
-@^reference counts@>
-
-Examples such as
-$$\.{\\def\\m\{\\def\\m\{a\}\ b\}}$$
-explain why reference counts would be needed even if \TeX\ had no \.{\\let}
-operation: When the token list for \.{\\m} is being read, the redefinition of
-\.{\\m} changes the |eqtb| entry before the token list has been fully
-consumed, so we dare not simply destroy a token list when its
-control sequence is being redefined.
-
-If the parameter-matching part of a definition ends with `\.{\#\{}',
-the corresponding token list will have `\.\{' just before the `|end_match|'
-and also at the very end. The first `\.\{' is used to delimit the parameter; the
-second one keeps the first from disappearing.
-
-@ The procedure |show_token_list|, which prints a symbolic form of
-the token list that starts at a given node |p|, illustrates these
-conventions. The token list being displayed should not begin with a reference
-count. However, the procedure is intended to be robust, so that if the
-memory links are awry or if |p| is not really a pointer to a token list,
-nothing catastrophic will happen.
-
-An additional parameter |q| is also given; this parameter is either null
-or it points to a node in the token list where a certain magic computation
-takes place that will be explained later. (Basically, |q| is non-null when
-we are printing the two-line context information at the time of an error
-message; |q| marks the place corresponding to where the second line
-should begin.)
-
-For example, if |p| points to the node containing the first \.a in the
-token list above, then |show_token_list| will print the string
-$$\hbox{`\.{a\#1\#2\ \\b\ ->\#1\\-a\ \#\#1\#2\ \#2}';}$$
-and if |q| points to the node containing the second \.a,
-the magic computation will be performed just before the second \.a is printed.
-
-The generation will stop, and `\.{\\ETC.}' will be printed, if the length
-of printing exceeds a given limit~|l|. Anomalous entries are printed in the
-form of control sequences that are not followed by a blank space, e.g.,
-`\.{\\BAD.}'; this cannot be confused with actual control sequences because
-a real control sequence named \.{BAD} would come out `\.{\\BAD\ }'.
-
-@<Declare the procedure called |show_token_list|@>=
-procedure show_token_list(@!p,@!q:integer;@!l:integer);
-label exit;
-var m,@!c:integer; {pieces of a token}
-@!match_chr:ASCII_code; {character used in a `|match|'}
-@!n:ASCII_code; {the highest parameter number, as an ASCII digit}
-begin match_chr:="#"; n:="0"; tally:=0;
-while (p<>null) and (tally<l) do
- begin if p=q then @<Do magic computation@>;
- @<Display token |p|, and |return| if there are problems@>;
- p:=link(p);
- end;
-if p<>null then print_esc("ETC.");
-@.ETC@>
-exit:
-end;
-
-@ @<Display token |p|...@>=
-if (p<fix_mem_min) or (p>fix_mem_end) then
- begin print_esc("CLOBBERED."); return;
-@.CLOBBERED@>
- 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);
- end
-else begin m:=info(p) div string_offset; c:=info(p) mod string_offset;
- if info(p)<0 then print_esc("BAD.")
-@.BAD@>
- else @<Display the token $(|m|,|c|)$@>;
- end
-
-@ The procedure usually ``learns'' the character code used for macro
-parameters by seeing one in a |match| command before it runs into any
-|out_param| commands.
-
-@<Display the token ...@>=
-case m of
-left_brace,right_brace,math_shift,tab_mark,sup_mark,sub_mark,spacer,
- letter,other_char: 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")
- else begin print_char("!"); return;
- end;
- end;
-match: begin match_chr:=c; print(c); incr(n); print_char(n);
- if n>"9" then return;
- end;
-end_match: if c=0 then print("->");
-@.->@>
-othercases print_esc("BAD.")
-@.BAD@>
-endcases
-
-@ Here's the way we sometimes want to display a token list, given a pointer
-to its reference count; the pointer may be null.
-
-@p procedure token_show(@!p:pointer);
-begin if p<>null then show_token_list(link(p),null,10000000);
-end;
-
-@ The |print_meaning| subroutine displays |cur_cmd| and |cur_chr| in
-symbolic form, including the expansion of a macro or mark.
-
-@p procedure print_meaning;
-begin print_cmd_chr(cur_cmd,cur_chr);
-if cur_cmd>=call then
- begin print_char(":"); print_ln; token_show(cur_chr);
- end
-else @<Show the meaning of a mark node@>;
-end;
-
-@* \[21] Introduction to the syntactic routines.
-Let's pause a moment now and try to look at the Big Picture.
-The \TeX\ program consists of three main parts: syntactic routines,
-semantic routines, and output routines. The chief purpose of the
-syntactic routines is to deliver the user's input to the semantic routines,
-one token at a time. The semantic routines act as an interpreter
-responding to these tokens, which may be regarded as commands. And the
-output routines are periodically called on to convert box-and-glue
-lists into a compact set of instructions that will be sent
-to a typesetter. We have discussed the basic data structures and utility
-routines of \TeX, so we are good and ready to plunge into the real activity by
-considering the syntactic routines.
-
-Our current goal is to come to grips with the |get_next| procedure,
-which is the keystone of \TeX's input mechanism. Each call of |get_next|
-sets the value of three variables |cur_cmd|, |cur_chr|, and |cur_cs|,
-representing the next input token.
-$$\vbox{\halign{#\hfil\cr
- \hbox{|cur_cmd| denotes a command code from the long list of codes
- given above;}\cr
- \hbox{|cur_chr| denotes a character code or other modifier of the command
- code;}\cr
- \hbox{|cur_cs| is the |eqtb| location of the current control sequence,}\cr
- \hbox{\qquad if the current token was a control sequence,
- otherwise it's zero.}\cr}}$$
-Underlying this external behavior of |get_next| is all the machinery
-necessary to convert from character files to tokens. At a given time we
-may be only partially finished with the reading of several files (for
-which \.{\\input} was specified), and partially finished with the expansion
-of some user-defined macros and/or some macro parameters, and partially
-finished with the generation of some text in a template for \.{\\halign},
-and so on. When reading a character file, special characters must be
-classified as math delimiters, etc.; comments and extra blank spaces must
-be removed, paragraphs must be recognized, and control sequences must be
-found in the hash table. Furthermore there are occasions in which the
-scanning routines have looked ahead for a word like `\.{plus}' but only
-part of that word was found, hence a few characters must be put back
-into the input and scanned again.
-
-To handle these situations, which might all be present simultaneously,
-\TeX\ uses various stacks that hold information about the incomplete
-activities, and there is a finite state control for each level of the
-input mechanism. These stacks record the current state of an implicitly
-recursive process, but the |get_next| procedure is not recursive.
-Therefore it will not be difficult to translate these algorithms into
-low-level languages that do not support recursion.
-
-@<Glob...@>=
-@!cur_cmd: eight_bits; {current command set by |get_next|}
-@!cur_chr: halfword; {operand of current command}
-@!cur_cs: pointer; {control sequence found here, zero if none found}
-@!cur_tok: halfword; {packed representative of |cur_cmd| and |cur_chr|}
-
-@ Here is a procedure that displays the current command.
-
-@p procedure show_cur_cmd_chr;
-var n:integer; {level of \.{\\if...\\fi} nesting}
-@!l:integer; {line where \.{\\if} started}
-@!p:pointer;
-begin begin_diagnostic; print_nl("{");
-if mode<>shown_mode then
- begin print_mode(mode); print(": "); shown_mode:=mode;
- end;
-print_cmd_chr(cur_cmd,cur_chr);
-if tracing_ifs>0 then
- if cur_cmd>=if_test then if cur_cmd<=fi_or_else then
- begin print(": ");
- if cur_cmd=fi_or_else then
- begin print_cmd_chr(if_test,cur_if); print_char(" ");
- n:=0; l:=if_line;
- end
- else begin n:=1; l:=line;
- end;
- p:=cond_ptr;
- while p<>null do
- begin incr(n); p:=vlink(p);
- end;
- print("(level "); print_int(n); print_char(")"); print_if_line(l);
- end;
-print_char("}");
-end_diagnostic(false);
-end;
-
-@* \[22] Input stacks and states.
-This implementation of
-\TeX\ uses two different conventions for representing sequential stacks.
-@^stack conventions@>@^conventions for representing stacks@>
-
-\yskip\hangg 1) If there is frequent access to the top entry, and if the
-stack is essentially never empty, then the top entry is kept in a global
-variable (even better would be a machine register), and the other entries
-appear in the array $\\{stack}[0\to(\\{ptr}-1)]$. For example, the
-semantic stack described above is handled this way, and so is the input
-stack that we are about to study.
-
-\yskip\hangg 2) If there is infrequent top access, the entire stack contents
-are in the array $\\{stack}[0\to(\\{ptr}-1)]$. For example, the |save_stack|
-is treated this way, as we have seen.
-
-\yskip\noindent
-The state of \TeX's input mechanism appears in the input stack, whose
-entries are records with six fields, called |state|, |index|, |start|, |loc|,
-|limit|, and |name|. This stack is maintained with
-convention~(1), so it is declared in the following way:
-
-@<Types...@>=
-@!in_state_record = record
- @!state_field, @!index_field: quarterword;
- @!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;
-
-@ @<Glob...@>=
-@!input_stack : array[0..stack_size] of in_state_record;
-@!input_ptr : 0..stack_size; {first unused location of |input_stack|}
-@!max_in_stack: 0..stack_size; {largest value of |input_ptr| when pushing}
-@!cur_input : in_state_record;
- {the ``top'' input state, according to convention (1)}
-
-@ We've already defined the special variable |loc==cur_input.loc_field|
-in our discussion of basic input-output routines. The other components of
-|cur_input| are defined in the same way:
-
-@d state==cur_input.state_field {current scanner state}
-@d index==cur_input.index_field {reference for buffer information}
-@d start==cur_input.start_field {starting position in |buffer|}
-@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|),
-assuming that \TeX\ is reading a line of characters that have been input
-from some file or from the user's terminal. There is an array called
-|buffer| that acts as a stack of all lines of characters that are
-currently being read from files, including all lines on subsidiary
-levels of the input stack that are not yet completed. \TeX\ will return to
-the other lines when it is finished with the present input file.
-
-(Incidentally, on a machine with byte-oriented addressing, it might be
-appropriate to combine |buffer| with the |str_pool| array,
-letting the buffer entries grow downward from the top of the string pool
-and checking that these two tables don't bump into each other.)
-
-The line we are currently working on begins in position |start| of the
-buffer; the next character we are about to read is |buffer[loc]|; and
-|limit| is the location of the last character present. If |loc>limit|,
-the line has been completely read. Usually |buffer[limit]| is the
-|end_line_char|, denoting the end of a line, but this is not
-true if the current line is an insertion that was entered on the user's
-terminal in response to an error message.
-
-The |name| variable is a string number that designates the name of
-the current file, if we are reading a text file. It is zero if we
-are reading from the terminal; it is |n+1| if we are reading from
-input stream |n|, where |0<=n<=16|. (Input stream 16 stands for
-an invalid stream number; in such cases the input is actually from
-the terminal, under control of the procedure |read_toks|.)
-Finally |18<=name<=20| indicates that we are reading a pseudo file
-created by the \.{\\scantokens} or \.{\\scantextokens} command.
-
-The |state| variable has one of three values, when we are scanning such
-files:
-$$\baselineskip 15pt\vbox{\halign{#\hfil\cr
-1) |state=mid_line| is the normal state.\cr
-2) |state=skip_blanks| is like |mid_line|, but blanks are ignored.\cr
-3) |state=new_line| is the state at the beginning of a line.\cr}}$$
-These state values are assigned numeric codes so that if we add the state
-code to the next character's command code, we get distinct values. For
-example, `|mid_line+spacer|' stands for the case that a blank
-space character occurs in the middle of a line when it is not being
-ignored; after this case is processed, the next value of |state| will
-be |skip_blanks|.
-
-@d mid_line=1 {|state| code when scanning a line of characters}
-@d skip_blanks=2+max_char_code {|state| code when ignoring blanks}
-@d new_line=3+max_char_code+max_char_code {|state| code at start of line}
-
-@ Additional information about the current line is available via the
-|index| variable, which counts how many lines of characters are present
-in the buffer below the current level. We have |index=0| when reading
-from the terminal and prompting the user for each line; then if the user types,
-e.g., `\.{\\input paper}', we will have |index=1| while reading
-the file \.{paper.tex}. However, it does not follow that |index| is the
-same as the input stack pointer, since many of the levels on the input
-stack may come from token lists. For example, the instruction `\.{\\input
-paper}' might occur in a token list.
-
-The global variable |in_open| is equal to the |index|
-value of the highest non-token-list level. Thus, the number of partially read
-lines in the buffer is |in_open+1|, and we have |in_open=index|
-when we are not reading a token list.
-
-If we are not currently reading from the terminal, or from an input
-stream, we are reading from the file variable |input_file[index]|. We use
-the notation |terminal_input| as a convenient abbreviation for |name=0|,
-and |cur_file| as an abbreviation for |input_file[index]|.
-
-The global variable |line| contains the line number in the topmost
-open file, for use in error messages. If we are not reading from
-the terminal, |line_stack[index]| holds the line number for the
-enclosing level, so that |line| can be restored when the current
-file has been read. Line numbers should never be negative, since the
-negative of the current line number is used to identify the user's output
-routine in the |mode_line| field of the semantic nest entries.
-
-If more information about the input state is needed, it can be
-included in small arrays like those shown here. For example,
-the current page or segment number in the input file might be
-put into a variable |@!page|, maintained for enclosing levels in
-`\ignorespaces|@!page_stack:array[1..max_in_open] of integer|\unskip'
-by analogy with |line_stack|.
-@^system dependencies@>
-
-@d terminal_input==(name=0) {are we reading from the terminal?}
-@d cur_file==input_file[index] {the current |alpha_file| variable}
-
-@<Glob...@>=
-@!in_open : 0..max_in_open; {the number of lines in the buffer, less one}
-@!open_parens : 0..max_in_open; {the number of open text files}
-@!input_file : array[1..max_in_open] of alpha_file;
-@!line : integer; {current line number in the current source file}
-@!line_stack : array[1..max_in_open] of integer;
-
-@ Users of \TeX\ sometimes forget to balance left and right braces properly,
-and one of the ways \TeX\ tries to spot such errors is by considering an
-input file as broken into subfiles by control sequences that
-are declared to be \.{\\outer}.
-
-A variable called |scanner_status| tells \TeX\ whether or not to complain
-when a subfile ends. This variable has six possible values:
-
-\yskip\hang|normal|, means that a subfile can safely end here without incident.
-
-\yskip\hang|skipping|, means that a subfile can safely end here, but not a file,
-because we're reading past some conditional text that was not selected.
-
-\yskip\hang|defining|, means that a subfile shouldn't end now because a
-macro is being defined.
-
-\yskip\hang|matching|, means that a subfile shouldn't end now because a
-macro is being used and we are searching for the end of its arguments.
-
-\yskip\hang|aligning|, means that a subfile shouldn't end now because we are
-not finished with the preamble of an \.{\\halign} or \.{\\valign}.
-
-\yskip\hang|absorbing|, means that a subfile shouldn't end now because we are
-reading a balanced token list for \.{\\message}, \.{\\write}, etc.
-
-\yskip\noindent
-If the |scanner_status| is not |normal|, the variable |warning_index| points
-to the |eqtb| location for the relevant control sequence name to print
-in an error message.
-
-@d skipping=1 {|scanner_status| when passing conditional text}
-@d defining=2 {|scanner_status| when reading a macro definition}
-@d matching=3 {|scanner_status| when reading macro arguments}
-@d aligning=4 {|scanner_status| when reading an alignment preamble}
-@d absorbing=5 {|scanner_status| when reading a balanced text}
-
-@<Glob...@>=
-@!scanner_status : normal..absorbing; {can a subfile end now?}
-@!warning_index : pointer; {identifier relevant to non-|normal| scanner status}
-@!def_ref : pointer; {reference count of token list being defined}
-
-@ Here is a procedure that uses |scanner_status| to print a warning message
-when a subfile has ended, and at certain other crucial times:
-
-@<Declare the procedure called |runaway|@>=
-procedure runaway;
-var p:pointer; {head of runaway list}
-begin p:=null;
- if scanner_status>skipping then
- begin print_nl("Runaway ");
-@.Runaway...@>
- case scanner_status of
- defining: begin print("definition"); p:=def_ref;
- end;
- matching: begin print("argument"); p:=temp_token_head;
- end;
- aligning: begin print("preamble"); p:=hold_token_head;
- end;
- absorbing: begin print("text"); p:=def_ref;
- end;
- end; {there are no other cases}
- print_char("?");print_ln; show_token_list(link(p),null,error_line-10);
- end;
-end;
-
-@ However, all this discussion about input state really applies only to the
-case that we are inputting from a file. There is another important case,
-namely when we are currently getting input from a token list. In this case
-|state=token_list|, and the conventions about the other state variables
-are different:
-
-\yskip\hang|loc| is a pointer to the current node in the token list, i.e.,
-the node that will be read next. If |loc=null|, the token list has been
-fully read.
-
-\yskip\hang|start| points to the first node of the token list; this node
-may or may not contain a reference count, depending on the type of token
-list involved.
-
-\yskip\hang|token_type|, which takes the place of |index| in the
-discussion above, is a code number that explains what kind of token list
-is being scanned.
-
-\yskip\hang|name| points to the |eqtb| address of the control sequence
-being expanded, if the current token list is a macro.
-
-\yskip\hang|param_start|, which takes the place of |limit|, tells where
-the parameters of the current macro begin in the |param_stack|, if the
-current token list is a macro.
-
-\yskip\noindent The |token_type| can take several values, depending on
-where the current token list came from:
-
-\yskip\hang|parameter|, if a parameter is being scanned;
-
-\hang|u_template|, if the \<u_j> part of an alignment
-template is being scanned;
-
-\hang|v_template|, if the \<v_j> part of an alignment
-template is being scanned;
-
-\hang|backed_up|, if the token list being scanned has been inserted as
-`to be read again'.
-
-\hang|inserted|, if the token list being scanned has been inserted as
-the text expansion of a \.{\\count} or similar variable;
-
-\hang|macro|, if a user-defined control sequence is being scanned;
-
-\hang|output_text|, if an \.{\\output} routine is being scanned;
-
-\hang|every_par_text|, if the text of \.{\\everypar} is being scanned;
-
-\hang|every_math_text|, if the text of \.{\\everymath} is being scanned;
-
-\hang|every_display_text|, if the text of \.{\\everydisplay} is being scanned;
-
-\hang|every_hbox_text|, if the text of \.{\\everyhbox} is being scanned;
-
-\hang|every_vbox_text|, if the text of \.{\\everyvbox} is being scanned;
-
-\hang|every_job_text|, if the text of \.{\\everyjob} is being scanned;
-
-\hang|every_cr_text|, if the text of \.{\\everycr} is being scanned;
-
-\hang|mark_text|, if the text of a \.{\\mark} is being scanned;
-
-\hang|write_text|, if the text of a \.{\\write} is being scanned.
-
-\yskip\noindent
-The codes for |output_text|, |every_par_text|, etc., are equal to a constant
-plus the corresponding codes for token list parameters |output_routine_loc|,
-|every_par_loc|, etc. The token list begins with a reference count if and
-only if |token_type>=macro|.
-@^reference counts@>
-
-Since \eTeX's additional token list parameters precede |toks_base|, the
-corresponding token types must precede |write_text|.
-
-@d token_list=0 {|state| code when scanning a token list}
-@d token_type==index {type of current token list}
-@d param_start==limit {base of macro parameters in |param_stack|}
-@d parameter=0 {|token_type| code for parameter}
-@d u_template=1 {|token_type| code for \<u_j> template}
-@d v_template=2 {|token_type| code for \<v_j> template}
-@d backed_up=3 {|token_type| code for text to be reread}
-@d inserted=4 {|token_type| code for inserted texts}
-@d macro=5 {|token_type| code for defined control sequences}
-@d output_text=6 {|token_type| code for output routines}
-@d every_par_text=7 {|token_type| code for \.{\\everypar}}
-@d every_math_text=8 {|token_type| code for \.{\\everymath}}
-@d every_display_text=9 {|token_type| code for \.{\\everydisplay}}
-@d every_hbox_text=10 {|token_type| code for \.{\\everyhbox}}
-@d every_vbox_text=11 {|token_type| code for \.{\\everyvbox}}
-@d every_job_text=12 {|token_type| code for \.{\\everyjob}}
-@d every_cr_text=13 {|token_type| code for \.{\\everycr}}
-@d mark_text=14 {|token_type| code for \.{\\topmark}, etc.}
-@#
-@d eTeX_text_offset=output_routine_loc-output_text
-@d every_eof_text=every_eof_loc-eTeX_text_offset
- {|token_type| code for \.{\\everyeof}}
-@#
-@d write_text=etex_toks-eTeX_text_offset {|token_type| code for \.{\\write}}
-
-@ The |param_stack| is an auxiliary array used to hold pointers to the token
-lists for parameters at the current level and subsidiary levels of input.
-This stack is maintained with convention (2), and it grows at a different
-rate from the others.
-
-@<Glob...@>=
-@!param_stack:array [0..param_size] of pointer;
- {token list pointers for parameters}
-@!param_ptr:0..param_size; {first unused entry in |param_stack|}
-@!max_param_stack:integer;
- {largest value of |param_ptr|, will be |<=param_size+9|}
-
-@ The input routines must also interact with the processing of
-\.{\\halign} and \.{\\valign}, since the appearance of tab marks and
-\.{\\cr} in certain places is supposed to trigger the beginning of special
-\<v_j> template text in the scanner. This magic is accomplished by an
-|align_state| variable that is increased by~1 when a `\.{\char'173}' is
-scanned and decreased by~1 when a `\.{\char'175}' is scanned. The |align_state|
-is nonzero during the \<u_j> template, after which it is set to zero; the
-\<v_j> template begins when a tab mark or \.{\\cr} occurs at a time that
-|align_state=0|.
-
-@<Glob...@>=
-@!align_state:integer; {group level with respect to current alignment}
-
-@ Thus, the ``current input state'' can be very complicated indeed; there
-can be many levels and each level can arise in a variety of ways. The
-|show_context| procedure, which is used by \TeX's error-reporting routine to
-print out the current input state on all levels down to the most recent
-line of characters from an input file, illustrates most of these conventions.
-The global variable |base_ptr| contains the lowest level that was
-displayed by this procedure.
-
-@<Glob...@>=
-@!base_ptr:0..stack_size; {shallowest level shown by |show_context|}
-
-@ The status at each level is indicated by printing two lines, where the first
-line indicates what was read so far and the second line shows what remains
-to be read. The context is cropped, if necessary, so that the first line
-contains at most |half_error_line| characters, and the second contains
-at most |error_line|. Non-current input levels whose |token_type| is
-`|backed_up|' are shown only if they have not been fully read.
-
-@p procedure show_context; {prints where the scanner is}
-label done;
-var old_setting:0..max_selector; {saved |selector| setting}
-@!nn:integer; {number of contexts shown so far, less one}
-@!bottom_line:boolean; {have we reached the final context to be shown?}
-@<Local variables for formatting calculations@>@/
-begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
- {store current state}
-nn:=-1; bottom_line:=false;
-loop@+begin cur_input:=input_stack[base_ptr]; {enter into the context}
- if (state<>token_list) then
- if (name>21) or (base_ptr=0) then bottom_line:=true;
- if (base_ptr=input_ptr)or bottom_line or(nn<error_context_lines) then
- @<Display the current context@>
- else if nn=error_context_lines then
- begin print_nl("..."); incr(nn); {omitted if |error_context_lines<0|}
- end;
- if bottom_line then goto done;
- decr(base_ptr);
- end;
-done: cur_input:=input_stack[input_ptr]; {restore original state}
-end;
-
-@ @<Display the current context@>=
-begin if (base_ptr=input_ptr) or (state<>token_list) or
- (token_type<>backed_up) or (loc<>null) then
- {we omit backed-up token lists that have already been read}
- begin tally:=0; {get ready to count characters}
- old_setting:=selector;
- if current_ocp_lstack>0 then
- begin print_nl("OCP stack "); print_scaled(current_ocp_lstack);
- print(" entry "); print_int(current_ocp_no); print(":");
- @<Pseudoprint the line@>;
- end
- else if state<>token_list then
- begin @<Print location of current line@>;
- @<Pseudoprint the line@>;
- end
- else begin @<Print type of token list@>;
- @<Pseudoprint the token list@>;
- end;
- selector:=old_setting; {stop pseudoprinting}
- @<Print two lines using the tricky pseudoprinted information@>;
- incr(nn);
- end;
-end
-
-@ This routine should be changed, if necessary, to give the best possible
-indication of where the current line resides in the input file.
-For example, on some systems it is best to print both a page and line number.
-@^system dependencies@>
-
-@<Print location of current line@>=
-if name<=17 then
- if terminal_input then
- if base_ptr=0 then print_nl("<*>") else print_nl("<insert> ")
- else begin print_nl("<read ");
- if name=17 then print_char("*")@+else print_int(name-1);
-@.*\relax@>
- print_char(">");
- end
-else if index<>in_open then {input from a pseudo file}
- begin print_nl("l."); print_int(line_stack[index+1]);
- end
-else begin print_nl("l."); print_int(line);
- end;
-print_char(" ")
-
-@ @<Print type of token list@>=
-case token_type of
-parameter: print_nl("<argument> ");
-u_template,v_template: print_nl("<template> ");
-backed_up: if loc=null then print_nl("<recently read> ")
- else print_nl("<to be read again> ");
-inserted: print_nl("<inserted text> ");
-macro: begin print_ln; print_cs(name);
- end;
-output_text: print_nl("<output> ");
-every_par_text: print_nl("<everypar> ");
-every_math_text: print_nl("<everymath> ");
-every_display_text: print_nl("<everydisplay> ");
-every_hbox_text: print_nl("<everyhbox> ");
-every_vbox_text: print_nl("<everyvbox> ");
-every_job_text: print_nl("<everyjob> ");
-every_cr_text: print_nl("<everycr> ");
-mark_text: print_nl("<mark> ");
-every_eof_text: print_nl("<everyeof> ");
-write_text: print_nl("<write> ");
-othercases print_nl("?") {this should never happen}
-endcases
-
-@ Here it is necessary to explain a little trick. We don't want to store a long
-string that corresponds to a token list, because that string might take up
-lots of memory; and we are printing during a time when an error message is
-being given, so we dare not do anything that might overflow one of \TeX's
-tables. So `pseudoprinting' is the answer: We enter a mode of printing
-that stores characters into a buffer of length |error_line|, where character
-$k+1$ is placed into \hbox{|trick_buf[k mod error_line]|} if
-|k<trick_count|, otherwise character |k| is dropped. Initially we set
-|tally:=0| and |trick_count:=1000000|; then when we reach the
-point where transition from line 1 to line 2 should occur, we
-set |first_count:=tally| and |trick_count:=@tmax@>(error_line,
-tally+1+error_line-half_error_line)|. At the end of the
-pseudoprinting, the values of |first_count|, |tally|, and
-|trick_count| give us all the information we need to print the two lines,
-and all of the necessary text is in |trick_buf|.
-
-Namely, let |l| be the length of the descriptive information that appears
-on the first line. The length of the context information gathered for that
-line is |k=first_count|, and the length of the context information
-gathered for line~2 is $m=\min(|tally|, |trick_count|)-k$. If |l+k<=h|,
-where |h=half_error_line|, we print |trick_buf[0..k-1]| after the
-descriptive information on line~1, and set |n:=l+k|; here |n| is the
-length of line~1. If $l+k>h$, some cropping is necessary, so we set |n:=h|
-and print `\.{...}' followed by
-$$\hbox{|trick_buf[(l+k-h+3)..k-1]|,}$$
-where subscripts of |trick_buf| are circular modulo |error_line|. The
-second line consists of |n|~spaces followed by |trick_buf[k..(k+m-1)]|,
-unless |n+m>error_line|; in the latter case, further cropping is done.
-This is easier to program than to explain.
-
-@<Local variables for formatting...@>=
-@!i:0..buf_size; {index into |buffer|}
-@!j:0..buf_size; {end of current line in |buffer|}
-@!l:0..half_error_line; {length of descriptive information on line 1}
-@!m:integer; {context information gathered for line 2}
-@!n:0..error_line; {length of line 1}
-@!p: integer; {starting or ending place in |trick_buf|}
-@!q: integer; {temporary index}
-
-@ The following code sets up the print routines so that they will gather
-the desired information.
-
-@d begin_pseudoprint==
- begin l:=tally; tally:=0; selector:=pseudo;
- trick_count:=1000000;
- end
-@d set_trick_count==
- begin first_count:=tally;
- trick_count:=tally+1+error_line-half_error_line;
- if trick_count<error_line then trick_count:=error_line;
- end
-
-@ And the following code uses the information after it has been gathered.
-
-@<Print two lines using the tricky pseudoprinted information@>=
-if trick_count=1000000 then set_trick_count;
- {|set_trick_count| must be performed}
-if tally<trick_count then m:=tally-first_count
-else m:=trick_count-first_count; {context on line 2}
-if l+first_count<=half_error_line then
- begin p:=0; n:=l+first_count;
- end
-else begin print("..."); p:=l+first_count-half_error_line+3;
- n:=half_error_line;
- end;
-for q:=p to first_count-1 do print_char(trick_buf[q mod error_line]);
-print_ln;
-for q:=1 to n do print_char(" "); {print |n| spaces to begin line~2}
-if m+n<=error_line then p:=first_count+m else p:=first_count+(error_line-n-3);
-for q:=first_count to p-1 do print_char(trick_buf[q mod error_line]);
-if m+n>error_line then print("...")
-
-@ But the trick is distracting us from our current goal, which is to
-understand the input state. So let's concentrate on the data structures that
-are being pseudoprinted as we finish up the |show_context| procedure.
-
-@<Pseudoprint the line@>=
-begin_pseudoprint;
-if buffer[limit]=end_line_char then j:=limit
-else j:=limit+1; {determine the effective end of the line}
-if j>0 then for i:=start to j-1 do
- begin if i=loc then set_trick_count;
- print_char(buffer[i]);
- end
-
-@ @<Pseudoprint the token list@>=
-begin_pseudoprint;
-if token_type<macro then show_token_list(start,loc,100000)
-else show_token_list(link(start),loc,100000) {avoid reference count}
-
-@ Here is the missing piece of |show_token_list| that is activated when the
-token beginning line~2 is about to be shown:
-
-@<Do magic computation@>=set_trick_count
-
-@* \[23] Maintaining the input stacks.
-The following subroutines change the input status in commonly needed ways.
-
-First comes |push_input|, which stores the current state and creates a
-new level (having, initially, the same properties as the old).
-
-@d push_input==@t@> {enter a new input level, save the old}
- begin if input_ptr>max_in_stack then
- begin max_in_stack:=input_ptr;
- if input_ptr=stack_size then overflow("input stack size",stack_size);
-@:TeX capacity exceeded input stack size}{\quad input stack size@>
- end;
- input_stack[input_ptr]:=cur_input; {stack the record}
- nofilter:=false;
- incr(input_ptr);
- end
-
-@ And of course what goes up must come down.
-
-@d pop_input==@t@> {leave an input level, re-enter the old}
- begin decr(input_ptr); cur_input:=input_stack[input_ptr];
- end
-
-@ Here is a procedure that starts a new level of token-list input, given
-a token list |p| and its type |t|. If |t=macro|, the calling routine should
-set |name| and |loc|.
-
-@d back_list(#)==begin_token_list(#,backed_up) {backs up a simple token list}
-@d ins_list(#)==begin_token_list(#,inserted) {inserts a simple token list}
-
-@p procedure begin_token_list(@!p:pointer;@!t:quarterword);
-begin push_input; state:=token_list; start:=p; token_type:=t;
-if t>=macro then {the token list starts with a reference count}
- begin add_token_ref(p);
- if t=macro then param_start:=param_ptr
- else begin loc:=link(p);
- if tracing_macros>1 then
- begin begin_diagnostic; print_nl("");
- case t of
- mark_text:print_esc("mark");
- write_text:print_esc("write");
- othercases print_cmd_chr(assign_toks,t-output_text+output_routine_loc)
- endcases;@/
- print("->"); token_show(p); end_diagnostic(false);
- end;
- end;
- end
-else loc:=p;
-end;
-
-@ When a token list has been fully scanned, the following computations
-should be done as we leave that level of input. The |token_type| tends
-to be equal to either |backed_up| or |inserted| about 2/3 of the time.
-@^inner loop@>
-
-@p procedure end_token_list; {leave a token-list input level}
-begin if token_type>=backed_up then {token list to be deleted}
- begin if token_type<=inserted then flush_list(start)
- else begin delete_token_ref(start); {update reference count}
- if token_type=macro then {parameters must be flushed}
- while param_ptr>param_start do
- begin decr(param_ptr);
- flush_list(param_stack[param_ptr]);
- end;
- end;
- end
-else if token_type=u_template then begin
- if align_state>500000 then align_state:=0
- else fatal_error("(interwoven alignment preambles are not allowed)");
-@.interwoven alignment preambles...@>
- end;
-pop_input;
-check_interrupt;
-end;
-
-@ Sometimes \TeX\ has read too far and wants to ``unscan'' what it has
-seen. The |back_input| procedure takes care of this by putting the token
-just scanned back into the input stream, ready to be read again. This
-procedure can be used only if |cur_tok| represents the token to be
-replaced. Some applications of \TeX\ use this procedure a lot,
-so it has been slightly optimized for speed.
-@^inner loop@>
-
-@p procedure back_input; {undoes one token of input}
-var p:pointer; {a token list of length one}
-begin while (state=token_list)and(loc=null)and(token_type<>v_template) do
- end_token_list; {conserve stack space}
-p:=get_avail; info(p):=cur_tok;
-if cur_tok<right_brace_limit then begin
- if cur_tok<left_brace_limit then decr(align_state)
- else incr(align_state);
- end;
-push_input; state:=token_list; start:=p; token_type:=backed_up;
-loc:=p; {that was |back_list(p)|, without procedure overhead}
-end;
-
-@ @<Insert token |p| into \TeX's input@>=
-begin t:=cur_tok; cur_tok:=p;
-if a then
- begin p:=get_avail; info(p):=cur_tok; link(p):=loc; loc:=p; start:=p;
- if cur_tok<right_brace_limit then begin
- if cur_tok<left_brace_limit then decr(align_state)
- else incr(align_state);
- end;
- end
-else begin back_input; a:=1; { etex is always on }
- end;
-cur_tok:=t;
-end
-
-@ The |back_error| routine is used when we want to replace an offending token
-just before issuing an error message. This routine, like |back_input|,
-requires that |cur_tok| has been set. We disable interrupts during the
-call of |back_input| so that the help message won't be lost.
-
-@p procedure back_error; {back up one token and call |error|}
-begin OK_to_interrupt:=false; back_input; OK_to_interrupt:=true; error;
-end;
-@#
-procedure ins_error; {back up one inserted token and call |error|}
-begin OK_to_interrupt:=false; back_input; token_type:=inserted;
-OK_to_interrupt:=true; error;
-end;
-
-@ The |begin_file_reading| procedure starts a new level of input for lines
-of characters to be read from a file, or as an insertion from the
-terminal. It does not take care of opening the file, nor does it set |loc|
-or |limit| or |line|.
-@^system dependencies@>
-
-@p procedure begin_file_reading;
-begin if in_open=max_in_open then overflow("text input levels",max_in_open);
-@:TeX capacity exceeded text input levels}{\quad text input levels@>
-if first=buf_size then check_buffer_overflow(first);
-@:TeX capacity exceeded buffer size}{\quad buffer size@>
-incr(in_open); push_input; index:=in_open;
-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;
-@<Prepare terminal input {\sl Sync\TeX} information@>;
-end;
-
-@ Conversely, the variables must be downdated when such a level of input
-is finished:
-
-@p procedure end_file_reading;
-begin first:=start; line:=line_stack[index];
-if (name>=18)and(name<=20) then pseudo_close else
-if name=21 then luacstring_close(index) else
-if name>17 then lua_a_close_in(cur_file,0); {forget it}
-pop_input; decr(in_open);
-end;
-
-@ In order to keep the stack from overflowing during a long sequence of
-inserted `\.{\\show}' commands, the following routine removes completed
-error-inserted lines from memory.
-
-@p procedure clear_for_error_prompt;
-begin while (state<>token_list)and terminal_input and@|
- (input_ptr>0)and(loc>limit) do end_file_reading;
-print_ln; clear_terminal;
-end;
-
-@ To get \TeX's whole input mechanism going, we perform the following
-actions.
-
-@<Initialize the input routines@>=
-begin input_ptr:=0; max_in_stack:=0;
-in_open:=0; open_parens:=0; max_buf_stack:=0;
-grp_stack[0]:=0; if_stack[0]:=null;
-param_ptr:=0; max_param_stack:=0;
-first:=buf_size; repeat buffer[first]:=0; decr(first); until first=0;
-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|}
-end
-
-@* \[24] Getting the next token.
-The heart of \TeX's input mechanism is the |get_next| procedure, which
-we shall develop in the next few sections of the program. Perhaps we
-shouldn't actually call it the ``heart,'' however, because it really acts
-as \TeX's eyes and mouth, reading the source files and gobbling them up.
-And it also helps \TeX\ to regurgitate stored token lists that are to be
-processed again.
-@^eyes and mouth@>
-
-The main duty of |get_next| is to input one token and to set |cur_cmd|
-and |cur_chr| to that token's command code and modifier. Furthermore, if
-the input token is a control sequence, the |eqtb| location of that control
-sequence is stored in |cur_cs|; otherwise |cur_cs| is set to zero.
-
-Underlying this simple description is a certain amount of complexity
-because of all the cases that need to be handled.
-However, the inner loop of |get_next| is reasonably short and fast.
-
-When |get_next| is asked to get the next token of a \.{\\read} line,
-it sets |cur_cmd=cur_chr=cur_cs=0| in the case that no more tokens
-appear on that line. (There might not be any tokens at all, if the
-|end_line_char| has |ignore| as its catcode.)
-
-@ The value of |par_loc| is the |eqtb| address of `\.{\\par}'. This quantity
-is needed because a blank line of input is supposed to be exactly equivalent
-to the appearance of \.{\\par}; we must set |cur_cs:=par_loc|
-when detecting a blank line.
-
-@<Glob...@>=
-@!par_loc:pointer; {location of `\.{\\par}' in |eqtb|}
-@!par_token:halfword; {token representing `\.{\\par}'}
-
-@ @<Put each...@>=
-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;
-
-@ 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@>
-
-@ The global variable |force_eof| is normally |false|; it is set |true|
-by an \.{\\endinput} command. |luacstrings| is the number of lua print
-statements waiting to be input, it is changed by |luatokencall|.
-
-|no_expand_flag| is a special character value that is inserted by
-|get_next| if it wants to suppress expansion.
-
-@d no_expand_flag==special_char {this characterizes a special variant of |relax|}
-@d end_line_char_inactive==(end_line_char<0)or(end_line_char>127)
-
-
-@<Glob...@>=
-@!force_eof:boolean; {should the next \.{\\input} be aborted early?}
-@!luacstrings:integer; {how many lua strings are waiting to be input?}
-
-@ If the user has set the |pausing| parameter to some positive value,
-and if nonstop mode has not been selected, each line of input is displayed
-on the terminal and the transcript file, followed by `\.{=>}'.
-\TeX\ waits for a response. If the response is simply |carriage_return|, the
-line is accepted as it stands, otherwise the line typed is
-used instead of the line in the file.
-
-@p procedure firm_up_the_line;
-var k:0..buf_size; {an index into |buffer|}
-begin limit:=last;
-if pausing>0 then if interaction>nonstop_mode then
- begin wake_up_terminal; print_ln;
- if start<limit then for k:=start to limit-1 do print(buffer[k]);
- first:=limit; prompt_input("=>"); {wait for user response}
-@.=>@>
- if last>first then
- begin for k:=first to last-1 do {move line down in buffer}
- buffer[k+start-first]:=buffer[k];
- limit:=start+last-first;
- end;
- end;
-end;
-
-@ Since |get_next| is used so frequently in \TeX, it is convenient
-to define three related procedures that do a little more:
-
-\yskip\hang|get_token| not only sets |cur_cmd| and |cur_chr|, it
-also sets |cur_tok|, a packed halfword version of the current token.
-
-\yskip\hang|get_x_token|, meaning ``get an expanded token,'' is like
-|get_token|, but if the current token turns out to be a user-defined
-control sequence (i.e., a macro call), or a conditional,
-or something like \.{\\topmark} or \.{\\expandafter} or \.{\\csname},
-it is eliminated from the input by beginning the expansion of the macro
-or the evaluation of the conditional.
-
-\yskip\hang|x_token| is like |get_x_token| except that it assumes that
-|get_next| has already been called.
-
-\yskip\noindent
-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
-|no_new_control_sequence| is always |true| at other times.
-
-@p procedure get_token; {sets |cur_cmd|, |cur_chr|, |cur_tok|}
-begin no_new_control_sequence:=false; get_filtered_next; no_new_control_sequence:=true;
-@^inner loop@>
-if cur_cs=0 then cur_tok:=(cur_cmd*string_offset)+cur_chr
-else cur_tok:=cs_token_flag+cur_cs;
-end;
-
-@* \[25] Expanding the next token.
-Only a dozen or so command codes |>max_command| can possibly be returned by
-|get_next|; in increasing order, they are |undefined_cs|, |expand_after|,
-|no_expand|, |input|, |if_test|, |fi_or_else|, |cs_name|, |convert|, |the|,
-|top_bot_mark|, |call|, |long_call|, |outer_call|, |long_outer_call|, and
-|end_template|.{\emergencystretch=40pt\par}
-
-@ Sometimes, recursive calls to the following |expand| routine may
-cause exhaustion of the run-time calling stack, resulting in
-forced execution stops by the operating system. To diminish the chance
-of this happening, a counter is used to keep track of the recursion
-depth, in conjunction with a constant called |expand_depth|.
-
-Note that this does not catch all possible infinite recursion loops,
-just the ones that exhaust the application calling stack. The
-actual maximum value of |expand_depth| is outside of our control, but
-the initial setting of |100| should be enough to prevent problems.
-@^system dependencies@>
-
-@<Global...@>=
-expand_depth_count:integer;
-
-@ @<Initialize whatever ...@>=
-expand_depth_count:=0;
-
-@ The |expand| subroutine is used when |cur_cmd>max_command|. It removes a
-``call'' or a conditional or one of the other special operations just
-listed. It follows that |expand| might invoke itself recursively. In all
-cases, |expand| destroys the current token, but it sets things up so that
-the next |get_next| will deliver the appropriate next token. The value of
-|cur_tok| need not be known when |expand| is called.
-
-Since several of the basic scanning routines communicate via global variables,
-their values are saved as local variables of |expand| so that
-recursive calls don't invalidate them.
-@^recursion@>
-
-@p@t\4@>@<Declare the procedure called |macro_call|@>@;@/
-@t\4@>@<Declare the procedure called |insert_relax|@>@;@/
-@t\4@>@<Declare \eTeX\ procedures for expanding@>@;@/
-procedure@?pass_text; forward;@t\2@>
-procedure@?start_input; forward;@t\2@>
-procedure@?conditional; forward;@t\2@>
-procedure@?get_x_token; forward;@t\2@>
-procedure@?conv_toks; forward;@t\2@>
-procedure@?ins_the_toks; forward;@t\2@>
-procedure expand;
-label reswitch;
-var t:halfword; {token that is being ``expanded after''}
-@!p,@!q,@!r:pointer; {for list manipulation}
-@!cur_ptr:pointer; { for a local token list pointer }
-@!j:0..buf_size; {index into |buffer|}
-@!s:ASCII_code; { a character }
-@!cv_backup:integer; {to save the global quantity |cur_val|}
-@!cvl_backup,@!radix_backup,@!co_backup:small_number;
- {to save |cur_val_level|, etc.}
-@!backup_backup:pointer; {to save |link(backup_head)|}
-@!save_scanner_status:small_number; {temporary storage of |scanner_status|}
-begin
-incr(expand_depth_count);
-if expand_depth_count>=expand_depth then overflow("expansion depth",expand_depth);
-cv_backup:=cur_val; cvl_backup:=cur_val_level; radix_backup:=radix;
-co_backup:=cur_order; backup_backup:=link(backup_head);
-reswitch:
-if cur_cmd<call then @<Expand a nonmacro@>
-else if cur_cmd<end_template then macro_call
-else @<Insert a token containing |frozen_endv|@>;
-cur_val:=cv_backup; cur_val_level:=cvl_backup; radix:=radix_backup;
-cur_order:=co_backup; link(backup_head):=backup_backup;
-decr(expand_depth_count);
-end;
-
-@ @<Glob...@>=
-@!is_in_csname: boolean;
-
-@ @<Set init...@>=
-is_in_csname := false;
-
-@ @<Expand a nonmacro@>=
-begin if tracing_commands>1 then show_cur_cmd_chr;
-case cur_cmd of
-top_bot_mark:@<Insert the \(a)appropriate mark text into the scanner@>;
-expand_after:if cur_chr=0 then @<Expand the token after the next token@>
- else @<Negate a boolean conditional and |goto reswitch|@>;
-no_expand: if cur_chr=0 then @<Suppress expansion of the next token@>
- else @<Implement \.{\\primitive}@>;
-cs_name:@<Manufacture a control sequence name@>;
-convert:conv_toks; {this procedure is discussed in Part 27 below}
-the:ins_the_toks; {this procedure is discussed in Part 27 below}
-if_test:conditional; {this procedure is discussed in Part 28 below}
-fi_or_else:@<Terminate the current conditional and skip to \.{\\fi}@>;
-input:@<Initiate or terminate input from a file@>;
-othercases @<Complain about an undefined macro@>
-endcases;
-end
-
-@ It takes only a little shuffling to do what \TeX\ calls \.{\\expandafter}.
-
-@<Expand the token after...@>=
-begin get_token; t:=cur_tok; get_token;
-if cur_cmd>max_command then expand@+else back_input;
-cur_tok:=t; back_input;
-end
-
-@ The implementation of \.{\\noexpand} is a bit trickier, because it is
-necessary to insert a special `|dont_expand|' marker into \TeX's reading
-mechanism. This special marker is processed by |get_next|, but it does
-not slow down the inner loop.
-
-Since \.{\\outer} macros might arise here, we must also
-clear the |scanner_status| temporarily.
-
-@<Suppress expansion...@>=
-begin save_scanner_status:=scanner_status; scanner_status:=normal;
-get_token; scanner_status:=save_scanner_status; t:=cur_tok;
-back_input; {now |start| and |loc| point to the backed-up token |t|}
-if t>=cs_token_flag then
- begin p:=get_avail; info(p):=cs_token_flag+frozen_dont_expand;
- link(p):=loc; start:=p; loc:=p;
- end;
-end
-
-@ The \.{\\primitive} handling. If the primitive meaning of the next
-token is an expandable command, it suffices to replace the current
-token with the primitive one and restart |expand|.
-
-Otherwise, the token we just read has to be pushed back, as well
-as a token matching the internal form of \.{\\primitive}, that is
-sneaked in as an alternate form of |ignore_spaces|.
-@!@:primitive_}{\.{\\primitive} primitive (internalized)@>
-
-An implementation problem surfaces: There really is no |cur_cs|
-attached to the inserted primitive command, so it is safer to set
-|cur_cs| to zero. |cur_tok| has a similar problem. And for the
-non-expanded branch, simply pushing back a token that matches the
-correct internal command does not work, because that approach would
-not survive roundtripping to a temporary file or even a token list.
-
-In a next version, it would be smart to create |frozen_| versions of
-all the primitives. Then, this problem would not happen, at the
-expense of a few hundred extra control sequences.
-
-@<Implement \.{\\primitive}@>=
-begin save_scanner_status := scanner_status; scanner_status:=normal;
-get_token; scanner_status:=save_scanner_status;
-cur_cs := prim_lookup(text(cur_cs));
-if cur_cs<>undefined_primitive then begin
- t:=get_prim_eq_type(cur_cs);
- if t>max_command then begin
- cur_cmd := t;
- cur_chr := get_prim_equiv(cur_cs);
- cur_tok := (cur_cmd*string_offset)+cur_chr;
- cur_cs := 0;
- goto reswitch;
- end
- else begin
- back_input; { now |loc| and |start| point to a one-item list }
- p:=get_avail; info(p):=cs_token_flag+frozen_primitive;
- link(p):=loc; loc:=p; start:=p;
- end;
- end
-else begin
- print_err("Missing primitive name");
- help2("The control sequence marked <to be read again> does not")@/
- ("represent any known primitive.");
- back_error;
- end;
-end
-
-
-@ This block deals with unexpandable \.{\\primitive} appearing at a spot where
-an integer or an internal values should have been found. It fetches the
-next token then resets |cur_cmd|, |cur_cs|, and |cur_tok|, based on the
-primitive value of that token. No expansion takes place, because the
-next token may be all sorts of things. This could trigger further
-expansion creating new errors.
-
-@<Reset |cur_tok| for unexpandable primitives, goto restart @>=
-begin
-get_token;
-cur_cs := prim_lookup(text(cur_cs));
-if cur_cs<>undefined_primitive then begin
- cur_cmd := get_prim_eq_type(cur_cs);
- cur_chr := get_prim_equiv(cur_cs);
- cur_tok := (cur_cmd*string_offset)+cur_chr;
- end
-else begin
- cur_cmd := relax;
- cur_chr := 0;
- cur_tok := cs_token_flag+frozen_relax;
- cur_cs := frozen_relax;
- end;
-goto restart;
-end
-
-@ @<Complain about an undefined macro@>=
-begin print_err("Undefined control sequence");
-@.Undefined control sequence@>
-help5("The control sequence at the end of the top line")@/
-("of your error message was never \def'ed. If you have")@/
-("misspelled it (e.g., `\hobx'), type `I' and the correct")@/
-("spelling (e.g., `I\hbox'). Otherwise just continue,")@/
-("and I'll forget about whatever was undefined.");
-error;
-end
-
-@ The |expand| procedure and some other routines that construct token
-lists find it convenient to use the following macros, which are valid only if
-the variables |p| and |q| are reserved for token-list building.
-
-@d store_new_token(#)==begin q:=get_avail; link(p):=q; info(q):=#;
- p:=q; {|link(p)| is |null|}
- end
-@d fast_store_new_token(#)==begin fast_get_avail(q); link(p):=q; info(q):=#;
- p:=q; {|link(p)| is |null|}
- end
-
-@ @<Manufacture a control...@>=
-begin r:=get_avail; p:=r; {head of the list of characters}
-is_in_csname := true;
-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 @<Complain about missing \.{\\endcsname}@>;
-is_in_csname := false;
-@<Look up the characters of list |r| in the hash table, and set |cur_cs|@>;
-flush_list(r);
-if eq_type(cur_cs)=undefined_cs then
- begin eq_define(cur_cs,relax,too_big_char); {N.B.: The |save_stack| might change}
- end; {the control sequence will now match `\.{\\relax}'}
-cur_tok:=cur_cs+cs_token_flag; back_input;
-end
-
-@ @<Complain about missing \.{\\endcsname}@>=
-begin print_err("Missing "); print_esc("endcsname"); print(" inserted");
-@.Missing \\endcsname...@>
-help2("The control sequence marked <to be read again> should")@/
- ("not appear between \csname and \endcsname.");
-back_error;
-end
-
-@ @<Look up the characters of list |r| in the hash table...@>=
-j:=first; p:=link(r);
-while p<>null do
- begin if j>=max_buf_stack then
- begin max_buf_stack:=j+4;
- if max_buf_stack=buf_size then
- check_buffer_overflow(max_buf_stack);
-@:TeX capacity exceeded buffer size}{\quad buffer size@>
- end;
- s := info(p) mod string_offset;
- if s <= @"7F then begin
- buffer[j]:=s; incr(j);
- end
- else if s<=@"7FF then begin
- buffer[j]:=@"C0 + s div @"40; incr(j);
- buffer[j]:=@"80 + s mod @"40; incr(j);
- end
- else if s<=@"FFFF then begin
- buffer[j]:=@"E0 + s div @"1000; incr(j);
- buffer[j]:=@"80 + (s mod @"1000) div @"40; incr(j);
- buffer[j]:=@"80 + (s mod @"1000) mod @"40; incr(j);
- end
- else begin
- buffer[j]:=@"F0 + s div @"40000; incr(j);
- buffer[j]:=@"80 + (s mod @"40000) div @"1000; incr(j);
- buffer[j]:=@"80 + ((s mod @"40000) mod @"1000) div @"40; incr(j);
- buffer[j]:=@"80 + ((s mod @"40000) mod @"1000) mod @"40; incr(j);
- end;
- p:=link(p);
- end;
-if j>first then
- begin no_new_control_sequence:=false; cur_cs:=id_lookup(first,j-first);
- no_new_control_sequence:=true;
- end
-else if j=first then cur_cs:=null_cs {the list is empty}
-
-@ An |end_template| command is effectively changed to an |endv| command
-by the following code. (The reason for this is discussed below; the
-|frozen_end_template| at the end of the template has passed the
-|check_outer_validity| test, so its mission of error detection has been
-accomplished.)
-
-@<Insert a token containing |frozen_endv|@>=
-begin cur_tok:=cs_token_flag+frozen_endv; back_input;
-end
-
-@ The processing of \.{\\input} involves the |start_input| subroutine,
-which will be declared later; the processing of \.{\\endinput} is trivial.
-
-@<Put each...@>=
-primitive_tex("input",input,0,0);@/
-@!@:input_}{\.{\\input} primitive@>
-primitive_tex("endinput",input,1,0);@/
-@!@:end_input_}{\.{\\endinput} primitive@>
-
-@ @<Initiate or terminate input...@>=
-if cur_chr=1 then force_eof:=true
-@/@<Cases for |input|@>@/
-else if name_in_progress then insert_relax
-else start_input
-
-@ Sometimes the expansion looks too far ahead, so we want to insert
-a harmless \.{\\relax} into the user's input.
-
-@<Declare the procedure called |insert_relax|@>=
-procedure insert_relax;
-begin cur_tok:=cs_token_flag+cur_cs; back_input;
-cur_tok:=cs_token_flag+frozen_relax; back_input; token_type:=inserted;
-end;
-
-@ Here is a recursive procedure that is \TeX's usual way to get the
-next token of input. It has been slightly optimized to take account of
-common cases.
-
-@p procedure get_x_token; {sets |cur_cmd|, |cur_chr|, |cur_tok|,
- and expands macros}
-label restart,done;
-begin restart: get_filtered_next;
-@^inner loop@>
-if cur_cmd<=max_command then goto done;
-if cur_cmd>=call then
- if cur_cmd<end_template then macro_call
- else begin cur_cs:=frozen_endv; cur_cmd:=endv;
- goto done; {|cur_chr=null_list|}
- end
-else expand;
-goto restart;
-done: if cur_cs=0 then cur_tok:=(cur_cmd*string_offset)+cur_chr
-else cur_tok:=cs_token_flag+cur_cs;
-end;
-
-@ The |get_x_token| procedure is equivalent to two consecutive
-procedure calls: |get_next; x_token|.
-
-@p procedure x_token; {|get_x_token| without the initial |get_next|}
-begin while cur_cmd>max_command do
- begin expand;
- get_filtered_next;
- end;
-if cur_cs=0 then cur_tok:=(cur_cmd*string_offset)+cur_chr
-else cur_tok:=cs_token_flag+cur_cs;
-end;
-
-@ The |get_filtered_next| procedure allows Lua code to mutate the
-output of |get_next| before \TeX\ looks at it. The implementation
-is in the C file |luatoken.c|.
-
-@d get_filtered_next==get_token_lua
-
-
-
-@ A control sequence that has been \.{\\def}'ed by the user is expanded by
-\TeX's |macro_call| procedure.
-
-Before we get into the details of |macro_call|, however, let's consider the
-treatment of primitives like \.{\\topmark}, since they are essentially
-macros without parameters. The token lists for such marks are kept in five
-global arrays of pointers; we refer to the individual entries of these
-arrays by symbolic macros |top_mark|, etc. The value of |top_mark(x)|, etc.
-is either |null| or a pointer to the reference count of a token list.
-
-The variable |biggest_used_mark| is an aid to try and keep the code
-somehwat efficient without too much extra work: it registers the
-highest mark class ever instantiated by the user, so the loops
-in |fire_up| and |vsplit| do not have to traverse the full range
-|0..biggest_mark|.
-
-@d top_mark_code=0 {the mark in effect at the previous page break}
-@d first_mark_code=1 {the first mark between |top_mark| and |bot_mark|}
-@d bot_mark_code=2 {the mark in effect at the current page break}
-@d split_first_mark_code=3 {the first mark found by \.{\\vsplit}}
-@d split_bot_mark_code=4 {the last mark found by \.{\\vsplit}}
-@#
-@d top_mark(#)==top_marks_array[#]
-@d first_mark(#)==first_marks_array[#]
-@d bot_mark(#)==bot_marks_array[#]
-@d split_first_mark(#)==split_first_marks_array[#]
-@d split_bot_mark(#)==split_bot_marks_array[#]
-@#
-@d delete_top_mark(#)==begin if top_mark(#)<>null then
- delete_token_ref(top_mark(#)); top_mark(#):=null; end
-@d delete_bot_mark(#)==begin if bot_mark(#)<>null then
- delete_token_ref(bot_mark(#)); bot_mark(#):=null; end
-@d delete_first_mark(#)==begin if first_mark(#)<>null then
- delete_token_ref(first_mark(#)); first_mark(#):=null; end
-@d delete_split_first_mark(#)==begin if split_first_mark(#)<>null then
- delete_token_ref(split_first_mark(#)); split_first_mark(#):=null; end
-@d delete_split_bot_mark(#)==begin if split_bot_mark(#)<>null then
- delete_token_ref(split_bot_mark(#)); split_bot_mark(#):=null; end
-@#
-@d clear_marks_code=1
-@d marks_code=5
-@#
-
-@<Glob...@>=
-@!top_marks_array:array[0..biggest_mark] of pointer;
-@!first_marks_array:array[0..biggest_mark] of pointer;
-@!bot_marks_array:array[0..biggest_mark] of pointer;
-@!split_first_marks_array:array[0..biggest_mark] of pointer;
-@!split_bot_marks_array:array[0..biggest_mark] of pointer;
-biggest_used_mark:halfword;
-
-@ @<Set init...@>=
-biggest_used_mark:=0;
-for i:=0 to biggest_mark do begin
- top_mark(i):=null;
- first_mark(i):=null;
- bot_mark(i):=null;
- split_first_mark(i):=null;
- split_bot_mark(i):=null;
-end;
-
-@ @<Put each...@>=
-primitive_tex("topmark",top_bot_mark,top_mark_code,0);
-@!@:top_mark_}{\.{\\topmark} primitive@>
-primitive_tex("firstmark",top_bot_mark,first_mark_code,0);
-@!@:first_mark_}{\.{\\firstmark} primitive@>
-primitive_tex("botmark",top_bot_mark,bot_mark_code,0);
-@!@:bot_mark_}{\.{\\botmark} primitive@>
-primitive_tex("splitfirstmark",top_bot_mark,split_first_mark_code,0);
-@!@:split_first_mark_}{\.{\\splitfirstmark} primitive@>
-primitive_tex("splitbotmark",top_bot_mark,split_bot_mark_code,0);
-@!@:split_bot_mark_}{\.{\\splitbotmark} primitive@>
-primitive_luatex("clearmarks",mark,clear_marks_code,0);@/
-@!@:clearmarks_}{\.{\\clearmarks} primitive@>
-primitive_etex("marks",mark,marks_code,0);
-@!@:marks_}{\.{\\marks} primitive@>
-primitive_etex("topmarks",top_bot_mark,top_mark_code+marks_code,0);
-@!@:top_marks_}{\.{\\topmarks} primitive@>
-primitive_etex("firstmarks",top_bot_mark,first_mark_code+marks_code,0);
-@!@:first_marks_}{\.{\\firstmarks} primitive@>
-primitive_etex("botmarks",top_bot_mark,bot_mark_code+marks_code,0);
-@!@:bot_marks_}{\.{\\botmarks} primitive@>
-primitive_etex("splitfirstmarks",top_bot_mark,split_first_mark_code+marks_code,0);
-@!@:split_first_marks_}{\.{\\splitfirstmarks} primitive@>
-primitive_etex("splitbotmarks",top_bot_mark,split_bot_mark_code+marks_code,0);
-@!@:split_bot_marks_}{\.{\\splitbotmarks} primitive@>
-
-@ The following code is activated when |cur_cmd=top_bot_mark| and
-when |cur_chr| is a code like |top_mark_code|.
-
-@<Insert the \(a)appropriate mark text into the scanner@>=
-begin t:=cur_chr mod marks_code;
-if cur_chr>=marks_code then scan_mark_num@+else cur_val:=0;
-case t of
- first_mark_code: cur_ptr:=first_mark(cur_val);
- bot_mark_code: cur_ptr:=bot_mark(cur_val);
- split_first_mark_code: cur_ptr:=split_first_mark(cur_val);
- split_bot_mark_code: cur_ptr:=split_bot_mark(cur_val);
- othercases cur_ptr:=top_mark(cur_val)
-endcases;
-if cur_ptr<>null then begin_token_list(cur_ptr,mark_text);
-end
-
-@ Now let's consider |macro_call| itself, which is invoked when \TeX\ is
-scanning a control sequence whose |cur_cmd| is either |call|, |long_call|,
-|outer_call|, or |long_outer_call|. The control sequence definition
-appears in the token list whose reference count is in location |cur_chr|
-of |mem|.
-
-The global variable |long_state| will be set to |call| or to |long_call|,
-depending on whether or not the control sequence disallows \.{\\par}
-in its parameters. The |get_next| routine will set |long_state| to
-|outer_call| and emit \.{\\par}, if a file ends or if an \.{\\outer}
-control sequence occurs in the midst of an argument.
-
-@<Glob...@>=
-@!long_state:call..long_outer_call; {governs the acceptance of \.{\\par}}
-
-@ The parameters, if any, must be scanned before the macro is expanded.
-Parameters are token lists without reference counts. They are placed on
-an auxiliary stack called |pstack| while they are being scanned, since
-the |param_stack| may be losing entries during the matching process.
-(Note that |param_stack| can't be gaining entries, since |macro_call| is
-the only routine that puts anything onto |param_stack|, and it
-is not recursive.)
-
-@<Glob...@>=
-@!pstack:array[0..8] of pointer; {arguments supplied to a macro}
-
-@ After parameter scanning is complete, the parameters are moved to the
-|param_stack|. Then the macro body is fed to the scanner; in other words,
-|macro_call| places the defined text of the control sequence at the
-top of\/ \TeX's input stack, so that |get_next| will proceed to read it
-next.
-
-The global variable |cur_cs| contains the |eqtb| address of the control sequence
-being expanded, when |macro_call| begins. If this control sequence has not been
-declared \.{\\long}, i.e., if its command code in the |eq_type| field is
-not |long_call| or |long_outer_call|, its parameters are not allowed to contain
-the control sequence \.{\\par}. If an illegal \.{\\par} appears, the macro
-call is aborted, and the \.{\\par} will be rescanned.
-
-@<Declare the procedure called |macro_call|@>=
-procedure macro_call; {invokes a user-defined control sequence}
-label exit, continue, done, done1, found;
-var r:pointer; {current node in the macro's token list}
-@!p:pointer; {current node in parameter token list being built}
-@!q:pointer; {new node being put into the token list}
-@!s:pointer; {backup pointer for parameter matching}
-@!t:pointer; {cycle pointer for backup recovery}
-@!u,@!v:pointer; {auxiliary pointers for backup recovery}
-@!rbrace_ptr:pointer; {one step before the last |right_brace| token}
-@!n:small_number; {the number of parameters scanned}
-@!unbalance:halfword; {unmatched left braces in current parameter}
-@!m:halfword; {the number of tokens or groups (usually)}
-@!ref_count:pointer; {start of the token list}
-@!save_scanner_status:small_number; {|scanner_status| upon entry}
-@!save_warning_index:pointer; {|warning_index| upon entry}
-@!match_chr:ASCII_code; {character used in parameter}
-begin save_scanner_status:=scanner_status; save_warning_index:=warning_index;
-warning_index:=cur_cs; ref_count:=cur_chr; r:=link(ref_count); n:=0;
-p:=null; m:=0; rbrace_ptr:=null; match_chr:=0;
-if tracing_macros>0 then @<Show the text of the macro being expanded@>;
-if info(r)=protected_token then r:=link(r);
-if info(r)<>end_match_token then
- @<Scan the parameters and make |link(r)| point to the macro body; but
- |return| if an illegal \.{\\par} is detected@>;
-@<Feed the macro body and its parameters to the scanner@>;
-exit:scanner_status:=save_scanner_status; warning_index:=save_warning_index;
-end;
-
-@ Before we put a new token list on the input stack, it is wise to clean off
-all token lists that have recently been depleted. Then a user macro that ends
-with a call to itself will not require unbounded stack space.
-
-@<Feed the macro body and its parameters to the scanner@>=
-while (state=token_list)and(loc=null)and(token_type<>v_template) do
- end_token_list; {conserve stack space}
-begin_token_list(ref_count,macro); name:=warning_index; loc:=link(r);
-if n>0 then
- begin if param_ptr+n>max_param_stack then
- begin max_param_stack:=param_ptr+n;
- if max_param_stack>param_size then
- overflow("parameter stack size",param_size);
-@:TeX capacity exceeded parameter stack size}{\quad parameter stack size@>
- end;
- for m:=0 to n-1 do param_stack[param_ptr+m]:=pstack[m];
- param_ptr:=param_ptr+n;
- end
-
-@ At this point, the reader will find it advisable to review the explanation
-of token list format that was presented earlier, since many aspects of that
-format are of importance chiefly in the |macro_call| routine.
-
-The token list might begin with a string of compulsory tokens before the
-first |match| or |end_match|. In that case the macro name is supposed to be
-followed by those tokens; the following program will set |s=null| to
-represent this restriction. Otherwise |s| will be set to the first token of
-a string that will delimit the next parameter.
-
-@<Scan the parameters and make |link(r)| point to the macro body...@>=
-begin scanner_status:=matching; unbalance:=0;
-long_state:=eq_type(cur_cs);
-if long_state>=outer_call then long_state:=long_state-2;
-repeat link(temp_token_head):=null;
-if (info(r)>=end_match_token)or(info(r)<match_token) then s:=null
-else begin match_chr:=info(r)-match_token; s:=link(r); r:=s;
- p:=temp_token_head; m:=0;
- end;
-@<Scan a parameter until its delimiter string has been found; or, if |s=null|,
- simply scan the delimiter string@>;@/
-{now |info(r)| is a token whose command code is either |match| or |end_match|}
-until info(r)=end_match_token;
-end
-
-@ If |info(r)| is a |match| or |end_match| command, it cannot be equal to
-any token found by |get_token|. Therefore an undelimited parameter---i.e.,
-a |match| that is immediately followed by |match| or |end_match|---will
-always fail the test `|cur_tok=info(r)|' in the following algorithm.
-
-@<Scan a parameter until its delimiter string has been found; or, ...@>=
-continue: get_token; {set |cur_tok| to the next token of input}
-if cur_tok=info(r) then
- @<Advance \(r)|r|; |goto found| if the parameter delimiter has been
- fully matched, otherwise |goto continue|@>;
-@<Contribute the recently matched tokens to the current parameter, and
- |goto continue| if a partial match is still in effect;
- but abort if |s=null|@>;
-if cur_tok=par_token then if long_state<>long_call then
- if not suppress_long_error then
- @<Report a runaway argument and abort@>;
-if cur_tok<right_brace_limit then
- if cur_tok<left_brace_limit then
- @<Contribute an entire group to the current parameter@>
- else @<Report an extra right brace and |goto continue|@>
-else @<Store the current token, but |goto continue| if it is
- a blank space that would become an undelimited parameter@>;
-incr(m);
-if info(r)>end_match_token then goto continue;
-if info(r)<match_token then goto continue;
-found: if s<>null then @<Tidy up the parameter just scanned, and tuck it away@>
-
-@ @<Store the current token, but |goto continue| if it is...@>=
-begin if cur_tok=space_token then
- if info(r)<=end_match_token then
- if info(r)>=match_token then goto continue;
-store_new_token(cur_tok);
-end
-
-@ A slightly subtle point arises here: When the parameter delimiter ends
-with `\.{\#\{}', the token list will have a left brace both before and
-after the |end_match|\kern-.4pt. Only one of these should affect the
-|align_state|, but both will be scanned, so we must make a correction.
-
-@<Advance \(r)|r|; |goto found| if the parameter delimiter has been fully...@>=
-begin r:=link(r);
-if (info(r)>=match_token)and(info(r)<=end_match_token) then
- begin if cur_tok<left_brace_limit then decr(align_state);
- goto found;
- end
-else goto continue;
-end
-
-@ @<Report an extra right brace and |goto continue|@>=
-begin back_input; print_err("Argument of "); sprint_cs(warning_index);
-@.Argument of \\x has...@>
-print(" has an extra }");
-help6("I've run across a `}' that doesn't seem to match anything.")@/
- ("For example, `\def\a#1{...}' and `\a}' would produce")@/
- ("this error. If you simply proceed now, the `\par' that")@/
- ("I've just inserted will cause me to report a runaway")@/
- ("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.
-
-@<Report a runaway argument and abort@>=
-begin if long_state=call then
- begin runaway; print_err("Paragraph ended before ");
-@.Paragraph ended before...@>
- sprint_cs(warning_index); print(" was complete");
- help3("I suspect you've forgotten a `}', causing me to apply this")@/
- ("control sequence to too much text. How can we recover?")@/
- ("My plan is to forget the whole thing and hope for the best.");
- back_error;
- end;
-pstack[n]:=link(temp_token_head); align_state:=align_state-unbalance;
-for m:=0 to n do flush_list(pstack[m]);
-return;
-end
-
-@ When the following code becomes active, we have matched tokens from |s| to
-the predecessor of |r|, and we have found that |cur_tok<>info(r)|. An
-interesting situation now presents itself: If the parameter is to be
-delimited by a string such as `\.{ab}', and if we have scanned `\.{aa}',
-we want to contribute one `\.a' to the current parameter and resume
-looking for a `\.b'. The program must account for such partial matches and
-for others that can be quite complex. But most of the time we have |s=r|
-and nothing needs to be done.
-
-Incidentally, it is possible for \.{\\par} tokens to sneak in to certain
-parameters of non-\.{\\long} macros. For example, consider a case like
-`\.{\\def\\a\#1\\par!\{...\}}' where the first \.{\\par} is not followed
-by an exclamation point. In such situations it does not seem appropriate
-to prohibit the \.{\\par}, so \TeX\ keeps quiet about this bending of
-the rules.
-
-@<Contribute the recently matched tokens to the current parameter...@>=
-if s<>r then begin
- if s=null then @<Report an improper use of the macro and abort@>
- else begin t:=s;
- repeat store_new_token(info(t)); incr(m); u:=link(t); v:=s;
- loop@+ begin if u=r then begin
- if cur_tok<>info(v) then goto done
- else begin r:=link(v); goto continue;
- end;
- end;
- if info(u)<>info(v) then goto done;
- u:=link(u); v:=link(v);
- end;
- done: t:=link(t);
- until t=r;
- r:=s; {at this point, no tokens are recently matched}
- end;
- end
-
-@ @<Report an improper use...@>=
-begin print_err("Use of "); sprint_cs(warning_index);
-@.Use of x doesn't match...@>
-print(" doesn't match its definition");
-help4("If you say, e.g., `\def\a1{...}', then you must always")@/
- ("put `1' after `\a', since control sequence names are")@/
- ("made up of letters only. The macro here has not been")@/
- ("followed by the required stuff, so I'm ignoring it.");
-error; return;
-end
-
-@ @<Contribute an entire group to the current parameter@>=
-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
- @<Report a runaway argument and abort@>;
- if cur_tok<right_brace_limit then begin
- if cur_tok<left_brace_limit then incr(unbalance)
- else begin decr(unbalance);
- if unbalance=0 then goto done1;
- end;
- end;
- end;
-done1: rbrace_ptr:=p; store_new_token(cur_tok);
-end
-
-@ If the parameter consists of a single group enclosed in braces, we must
-strip off the enclosing braces. That's why |rbrace_ptr| was introduced.
-
-@<Tidy up the parameter just scanned, and tuck it away@>=
-begin if (m=1)and(info(p)<right_brace_limit)and(p<>temp_token_head) then
- begin link(rbrace_ptr):=null; free_avail(p);
- p:=link(temp_token_head); pstack[n]:=link(p); free_avail(p);
- end
-else pstack[n]:=link(temp_token_head);
-incr(n);
-if tracing_macros>0 then
- begin begin_diagnostic; print_nl(match_chr); print_int(n);
- print("<-"); show_token_list(pstack[n-1],null,1000);
- end_diagnostic(false);
- end;
-end
-
-@ @<Show the text of the macro being expanded@>=
-begin begin_diagnostic; print_ln; print_cs(warning_index);
-token_show(ref_count); end_diagnostic(false);
-end
-
-@* \[26] Basic scanning subroutines.
-Let's turn now to some procedures that \TeX\ calls upon frequently to digest
-certain kinds of patterns in the input. Most of these are quite simple;
-some are quite elaborate. Almost all of the routines call |get_x_token|,
-which can cause them to be invoked recursively.
-@^stomach@>
-@^recursion@>
-
-@ The |scan_left_brace| routine is called when a left brace is supposed to be
-the next non-blank token. (The term ``left brace'' means, more precisely,
-a character whose catcode is |left_brace|.) \TeX\ allows \.{\\relax} to
-appear before the |left_brace|.
-
-@p procedure scan_left_brace; {reads a mandatory |left_brace|}
-begin @<Get the next non-blank non-relax non-call token@>;
-if cur_cmd<>left_brace then
- begin print_err("Missing { inserted");
-@.Missing \{ inserted@>
- help4("A left brace was mandatory here, so I've put one in.")@/
- ("You might want to delete and/or insert some corrections")@/
- ("so that I will find a matching right brace soon.")@/
- ("(If you're confused by all this, try typing `I}' now.)");
- back_error; cur_tok:=left_brace_token+"{"; cur_cmd:=left_brace;
- cur_chr:="{"; incr(align_state);
- end;
-end;
-
-@ @<Get the next non-blank non-relax non-call token@>=
-repeat get_x_token;
-until (cur_cmd<>spacer)and(cur_cmd<>relax)
-
-@ The |scan_optional_equals| routine looks for an optional `\.=' sign preceded
-by optional spaces; `\.{\\relax}' is not ignored here.
-
-@p procedure scan_optional_equals;
-begin @<Get the next non-blank non-call token@>;
-if cur_tok<>other_token+"=" then back_input;
-end;
-
-@ @<Get the next non-blank non-call token@>=
-repeat get_x_token;
-until cur_cmd<>spacer
-
-@ Here is a procedure that sounds an alarm when mu and non-mu units
-are being switched.
-
-@p procedure mu_error;
-begin print_err("Incompatible glue units");
-@.Incompatible glue units@>
-help1("I'm going to assume that 1mu=1pt when they're mixed.");
-error;
-end;
-
-@ The next routine `|scan_something_internal|' is used to fetch internal
-numeric quantities like `\.{\\hsize}', and also to handle the `\.{\\the}'
-when expanding constructions like `\.{\\the\\toks0}' and
-`\.{\\the\\baselineskip}'. Soon we will be considering the |scan_int|
-procedure, which calls |scan_something_internal|; on the other hand,
-|scan_something_internal| also calls |scan_int|, for constructions like
-`\.{\\catcode\`\\\$}' or `\.{\\fontdimen} \.3 \.{\\ff}'. So we
-have to declare |scan_int| as a |forward| procedure. A few other
-procedures are also declared at this point.
-
-@p procedure@?scan_int; forward; {scans an integer value}
-@t\4\4@>@<Declare procedures that scan restricted classes of integers@>@;
-@t\4\4@>@<Declare \eTeX\ procedures for scanning@>@;
-@t\4\4@>@<Declare procedures that scan font-related stuff@>
-@t\4\4@>@<Declare procedures that scan ocp-related stuff@>
-
-@ \TeX\ doesn't know exactly what to expect when
-|scan_something_internal| begins. For example, an integer or
-dimension or glue value could occur immediately after `\.{\\hskip}';
-and one can even say \.{\\the} with respect to token lists in
-constructions like `\.{\\xdef\\o\{\\the\\output\}}'. On the other
-hand, only integers are allowed after a construction like
-`\.{\\count}'. To handle the various possibilities,
-|scan_something_internal| has a |level| parameter, which tells the
-``highest'' kind of quantity that |scan_something_internal| is allowed
-to produce. Eight levels are distinguished, namely |int_val|,
-|attr_val|, |dimen_val|, |glue_val|, |mu_val|, |dir_val|, |ident_val|,
-and |tok_val|.
-
-The output of |scan_something_internal| (and of the other routines
-|scan_int|, |scan_dimen|, and |scan_glue| below) is put into the global
-variable |cur_val|, and its level is put into |cur_val_level|. The highest
-values of |cur_val_level| are special: |mu_val| is used only when
-|cur_val| points to something in a ``muskip'' register, or to one of the
-three parameters \.{\\thinmuskip}, \.{\\medmuskip}, \.{\\thickmuskip};
-|ident_val| is used only when |cur_val| points to a font identifier;
-|tok_val| is used only when |cur_val| points to |null| or to the reference
-count of a token list. The last two cases are allowed only when
-|scan_something_internal| is called with |level=tok_val|.
-
-If the output is glue, |cur_val| will point to a glue specification, and
-the reference count of that glue will have been updated to reflect this
-reference; if the output is a nonempty token list, |cur_val| will point to
-its reference count, but in this case the count will not have been updated.
-Otherwise |cur_val| will contain the integer or scaled value in question.
-
-@d int_val=0 {integer values}
-@d attr_val=1 {integer values}
-@d dimen_val=2 {dimension values}
-@d glue_val=3 {glue specifications}
-@d mu_val=4 {math glue specifications}
-@d dir_val=5 {directions}
-@d ident_val=6 {font identifier}
-@d tok_val=7 {token lists}
-
-@<Glob...@>=
-@!cur_val:integer; {value returned by numeric scanners}
-@!cur_val1:integer; {delcodes are now 51 digits}
-@!cur_val_level:int_val..tok_val; {the ``level'' of this value}
-
-@ The hash table is initialized with `\.{\\count}', `\.{\\attribute}',
-`\.{\\dimen}', `\.{\\skip}', and `\.{\\muskip}' all having |register|
-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|.
-
-@<Put each...@>=
-primitive_tex("count",register,int_val,0);
-@!@:count_}{\.{\\count} primitive@>
-primitive_luatex("attribute",register,attr_val,0);
-@!@:count_}{\.{\\attribute} primitive@>
-primitive_tex("dimen",register,dimen_val,0);
-@!@:dimen_}{\.{\\dimen} primitive@>
-primitive_tex("skip",register,glue_val,0);
-@!@:skip_}{\.{\\skip} primitive@>
-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.
-It is assumed that |cur_cmd| and |cur_chr| represent the first token of
-the internal quantity to be scanned; an error will be signalled if
-|cur_cmd<min_internal| or |cur_cmd>max_internal|.
-
-@d scanned_result_end(#)==cur_val_level:=#;@+end
-@d scanned_result(#)==@+begin cur_val:=#;scanned_result_end
-
-@p procedure scan_something_internal(@!level:small_number;@!negative:boolean);
- {fetch an internal parameter}
-label exit, restart;
-var m:halfword; {|chr_code| part of the operand token}
- n, k: integer; {accumulators}
-@!q:halfword; {general purpose index}
-@!p:0..nest_size; {index into |nest|}
-begin restart: m:=cur_chr;
-case cur_cmd of
-def_char_code: @<Fetch a character code from some table@>;
-def_del_code: @<Fetch a character code from some table@>;
-extdef_math_code: @<Fetch an ext character code from some table@>;
-extdef_del_code: @<Fetch an ext character code from some table@>;
-toks_register,assign_toks,set_font,def_font,letterspace_font,pdf_copy_font:
- @<Fetch a token list or font identifier, provided that |level=tok_val|@>;
-def_family:
- @<Fetch a math font identifier@>;
-set_math_param:
- @<Fetch a math param@>;
-assign_int: scanned_result(eqtb[m].int)(int_val);
-assign_attr: scanned_result(eqtb[m].int)(int_val);
-assign_box_dir: begin
- scan_register_num;
- m:=cur_val;
- if box(m)<>null then cur_val:=box_dir(box(m))
- else cur_val:=0;
- cur_val_level:=dir_val;
- end;
-assign_dir: scanned_result(eqtb[m].int)(dir_val);
-assign_dimen: scanned_result(eqtb[m].sc)(dimen_val);
-assign_glue: scanned_result(equiv(m))(glue_val);
-assign_mu_glue: scanned_result(equiv(m))(mu_val);
-math_style: scanned_result(m)(int_val);
-set_aux: @<Fetch the |space_factor| or the |prev_depth|@>;
-set_prev_graf: @<Fetch the |prev_graf|@>;
-set_page_int:@<Fetch the |dead_cycles| or the |insert_penalties|@>;
-set_page_dimen: @<Fetch something on the |page_so_far|@>;
-set_tex_shape: @<Fetch the |par_shape| size@>;
-set_etex_shape: @<Fetch a penalties array element@>;
-set_box_dimen: @<Fetch a box dimension@>;
-char_given,math_given,omath_given,xmath_given: scanned_result(cur_chr)(int_val);
-assign_font_dimen: @<Fetch a font dimension@>;
-assign_font_int: @<Fetch a font integer@>;
-register: @<Fetch a register@>;
-last_item: @<Fetch an item in the current node, if appropriate@>;
-ignore_spaces: {trap unexpandable primitives}
- if cur_chr=1 then @<Reset |cur_tok| for unexpandable primitives, goto restart@>;
-othercases @<Complain that \.{\\the} can't do this; give zero result@>
-endcases;@/
-while cur_val_level>level do @<Convert \(c)|cur_val| to a lower level@>;
-@<Fix the reference count, if any, and negate |cur_val| if |negative|@>;
-exit:end;
-
-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}
-@!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);
-assign_attr: scanned_result(eqtb[m].int)(int_val);
-assign_dir: scanned_result(eqtb[m].int)(dir_val);
-assign_dimen: scanned_result(eqtb[m].sc)(dimen_val);
-assign_glue: scanned_result(equiv(m))(glue_val);
-assign_mu_glue: scanned_result(equiv(m))(mu_val);
-math_style: scanned_result(m)(int_val);
-set_aux: @<Fetch the |space_factor| or the |prev_depth|@>;
-set_prev_graf: @<Fetch the |prev_graf|@>;
-set_page_int:@<Fetch the |dead_cycles| or the |insert_penalties|@>;
-set_page_dimen: @<Fetch something on the |page_so_far|@>;
-set_tex_shape: @<Fetch the |par_shape| size@>;
-set_etex_shape: @<Fetch a penalties array element@>;
-last_item: begin
- save_cur_chr:=cur_chr;
- cur_chr:=subitem;
- @<Fetch an item in the current node, if appropriate@>;
- cur_chr:=save_cur_chr;
- end;
-char_given,math_given,omath_given,xmath_given:
- scanned_result(m)(int_val); {TH: TODO, doesnt work}
-othercases @<Complain that |texlib| can't do this; give zero result@>
-endcases;@/
-exit:end;
-
-@ @<Fetch a character code from some table@>=
-begin scan_char_num;
-if m=math_code_base then begin
- cur_val1:=get_math_code_num(cur_val);
- scanned_result(cur_val1)(int_val);
- end
-else if m=lc_code_base then begin
- cur_val1:=get_lc_code(cur_val);
- scanned_result(cur_val1)(int_val);
- end
-else if m=uc_code_base then begin
- cur_val1:=get_uc_code(cur_val);
- scanned_result(cur_val1)(int_val);
- end
-else if m=sf_code_base then begin
- cur_val1:=get_sf_code(cur_val);
- scanned_result(cur_val1)(int_val);
- end
-else if m=cat_code_base then begin
- cur_val1:=get_cat_code(cat_code_table,cur_val);
- scanned_result(cur_val1)(int_val);
- end
-else if m<math_code_base then scanned_result(equiv(m+cur_val))(int_val)
-else scanned_result(eqtb[m+cur_val].int)(int_val);
-end
-
-@ @<Fetch an ext character code from some table@>=
-begin scan_char_num;
-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<math_code_base then scanned_result(equiv(m+cur_val))(int_val)
-else scanned_result(eqtb[m+cur_val].int)(int_val);
-end
-
-@ @<Fetch a token list...@>=
-if level<>tok_val then
- begin print_err("Missing number, treated as zero");
-@.Missing number...@>
- help3("A number should have been here; I inserted `0'.")@/
- ("(If you can't figure out why I needed to see a number,")@/
- ("look up `weird error' in the index to The TeXbook.)");
-@:TeXbook}{\sl The \TeX book@>
- back_error; scanned_result(0)(dimen_val);
- end
-else if cur_cmd<=assign_toks then
- begin if cur_cmd<assign_toks then {|cur_cmd=toks_register|}
- begin scan_register_num; m:=toks_base+cur_val;
- end;
- scanned_result(equiv(m))(tok_val);
- end
-else begin back_input; scan_font_ident;
- scanned_result(font_id_base+cur_val)(ident_val);
- end
-
-@ @<Fetch a math font identifier@>=
-begin scan_char_num; cur_val1:=fam_fnt(cur_val,m);
- scanned_result(font_id_base+cur_val1)(ident_val);
- end
-
-@ @<Fetch a math param@>=
-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<math_param_first_mu_glue then begin
- if cur_val1=math_param_radical_degree_raise then begin
- cur_val1 := get_math_param(cur_val1,cur_chr);
- scanned_result(cur_val1)(int_val);
- end
- else begin
- cur_val1 := get_math_param(cur_val1,cur_chr);
- scanned_result(cur_val1)(dimen_val);
- end;
- end
- else begin
- cur_val1 := get_math_param(cur_val1,cur_chr);
- if cur_val1=thin_mu_skip_code then cur_val1:=thin_mu_skip
- else if cur_val1=med_mu_skip_code then cur_val1:=med_mu_skip
- else if cur_val1=thick_mu_skip_code then cur_val1:=thick_mu_skip;
- scanned_result(cur_val1)(mu_val);
- end;
- end
-
-
-@ Users refer to `\.{\\the\\spacefactor}' only in horizontal
-mode, and to `\.{\\the\\prevdepth}' only in vertical mode; so we put the
-associated mode in the modifier part of the |set_aux| command.
-The |set_page_int| command has modifier 0 or 1, for `\.{\\deadcycles}' and
-`\.{\\insertpenalties}', respectively. The |set_box_dimen| command is
-modified by either |width_offset|, |height_offset|, or |depth_offset|.
-And the |last_item| command is modified by either |int_val|, |dimen_val|,
-|glue_val|, |input_line_no_code|, or |badness_code|.
-\pdfTeX\ adds the codes for its extensions: |pdftex_version_code|, \dots\ .
-\eTeX\ inserts |last_node_type_code| after |glue_val| and adds
-the codes for its extensions: |eTeX_version_code|, \dots\ .
-
-@d last_node_type_code=glue_val+1 {code for \.{\\lastnodetype}}
-@d input_line_no_code=glue_val+2 {code for \.{\\inputlineno}}
-@d badness_code=input_line_no_code+1 {code for \.{\\badness}}
-@#
-@d pdftex_first_rint_code = badness_code + 1 {base for \pdfTeX's command codes}
-@d pdftex_version_code = pdftex_first_rint_code + 0 {code for \.{\\pdftexversion}}
-@d pdf_last_obj_code = pdftex_first_rint_code + 1 {code for \.{\\pdflastobj}}
-@d pdf_last_xform_code = pdftex_first_rint_code + 2 {code for \.{\\pdflastxform}}
-@d pdf_last_ximage_code = pdftex_first_rint_code + 3 {code for \.{\\pdflastximage}}
-@d pdf_last_ximage_pages_code = pdftex_first_rint_code + 4 {code for \.{\\pdflastximagepages}}
-@d pdf_last_annot_code = pdftex_first_rint_code + 5 {code for \.{\\pdflastannot}}
-@d pdf_last_x_pos_code = pdftex_first_rint_code + 6 {code for \.{\\pdflastxpos}}
-@d pdf_last_y_pos_code = pdftex_first_rint_code + 7 {code for \.{\\pdflastypos}}
-@d pdf_retval_code = pdftex_first_rint_code + 8 {global multi-purpose return value}
-@d pdf_last_ximage_colordepth_code = pdftex_first_rint_code + 9 {code for \.{\\pdflastximagecolordepth}}
-@d random_seed_code = pdftex_first_rint_code + 10 {code for \.{\\pdfrandomseed}}
-@d pdf_last_link_code = pdftex_first_rint_code + 11 {code for \.{\\pdflastlink}}
-@d luatex_version_code = pdftex_first_rint_code + 12 {code for \.{\\luatexversion}}
-@d pdftex_last_item_codes = pdftex_first_rint_code + 12 {end of \pdfTeX's command codes}
-@#
-@d Aleph_int=pdftex_last_item_codes+1 {first of \Aleph\ codes for integers}
-@d Aleph_int_num=5 {number of \Aleph\ integers}
-@d eTeX_int=Aleph_int+Aleph_int_num {first of \eTeX\ codes for integers}
-@d eTeX_dim=eTeX_int+8 {first of \eTeX\ codes for dimensions}
-@d eTeX_glue=eTeX_dim+9 {first of \eTeX\ codes for glue}
-@d eTeX_mu=eTeX_glue+1 {first of \eTeX\ codes for muglue}
-@d eTeX_expr=eTeX_mu+1 {first of \eTeX\ codes for expressions}
-
-@<Put each...@>=
-primitive_tex("spacefactor",set_aux,hmode,0);
-@!@:space_factor_}{\.{\\spacefactor} primitive@>
-primitive_tex("prevdepth",set_aux,vmode,0);@/
-@!@:prev_depth_}{\.{\\prevdepth} primitive@>
-primitive_tex("deadcycles",set_page_int,0,0);
-@!@:dead_cycles_}{\.{\\deadcycles} primitive@>
-primitive_tex("insertpenalties",set_page_int,1,0);
-@!@:insert_penalties_}{\.{\\insertpenalties} primitive@>
-primitive_tex("wd",set_box_dimen,width_offset,0);
-@!@:wd_}{\.{\\wd} primitive@>
-primitive_tex("ht",set_box_dimen,height_offset,0);
-@!@:ht_}{\.{\\ht} primitive@>
-primitive_tex("dp",set_box_dimen,depth_offset,0);
-@!@:dp_}{\.{\\dp} primitive@>
-primitive_tex("lastpenalty",last_item,int_val,0);
-@!@:last_penalty_}{\.{\\lastpenalty} primitive@>
-primitive_tex("lastkern",last_item,dimen_val,0);
-@!@:last_kern_}{\.{\\lastkern} primitive@>
-primitive_tex("lastskip",last_item,glue_val,0);
-@!@:last_skip_}{\.{\\lastskip} primitive@>
-primitive_tex("inputlineno",last_item,input_line_no_code,0);
-@!@:input_line_no_}{\.{\\inputlineno} primitive@>
-primitive_tex("badness",last_item,badness_code,0);
-@!@:badness_}{\.{\\badness} primitive@>
-primitive_pdftex("pdftexversion",last_item,pdftex_version_code,0);@/
-@!@:pdftex_version_}{\.{\\pdftexversion} primitive@>
-primitive_luatex("luatexversion",last_item,luatex_version_code,0);@/
-@!@:luatex_version_}{\.{\\luatexversion} primitive@>
-primitive_pdftex("pdflastobj",last_item,pdf_last_obj_code,0);@/
-@!@:pdf_last_obj_}{\.{\\pdflastobj} primitive@>
-primitive_pdftex("pdflastxform",last_item,pdf_last_xform_code,0);@/
-@!@:pdf_last_xform_}{\.{\\pdflastxform} primitive@>
-primitive_pdftex("pdflastximage",last_item,pdf_last_ximage_code,0);@/
-@!@:pdf_last_ximage_}{\.{\\pdflastximage} primitive@>
-primitive_pdftex("pdflastximagepages",last_item,pdf_last_ximage_pages_code,0);@/
-@!@:pdf_last_ximage_pages_}{\.{\\pdflastximagepages} primitive@>
-primitive_pdftex("pdflastannot",last_item,pdf_last_annot_code,0);@/
-@!@:pdf_last_annot_}{\.{\\pdflastannot} primitive@>
-primitive_pdftex("pdflastxpos",last_item,pdf_last_x_pos_code,0);@/
-@!@:pdf_last_x_pos_}{\.{\\pdflastxpos} primitive@>
-primitive_pdftex("pdflastypos",last_item,pdf_last_y_pos_code,0);@/
-@!@:pdf_last_y_pos_}{\.{\\pdflastypos} primitive@>
-primitive_pdftex("pdfretval",last_item,pdf_retval_code,0);@/
-@!@:pdf_retval_}{\.{\\pdfretval} primitive@>
-primitive_pdftex("pdflastximagecolordepth",last_item,pdf_last_ximage_colordepth_code,0);@/
-@!@:pdf_last_ximage_colordepth_}{\.{\\pdflastximagecolordepth} primitive@>
-primitive_pdftex("pdfrandomseed",last_item,random_seed_code,0);
-@!@:random_seed_}{\.{\\pdfrandomseed} primitive@>
-primitive_pdftex("pdflastlink",last_item,pdf_last_link_code,0);@/
-@!@:pdf_last_link_}{\.{\\pdflastlink} primitive@>
-
-@ @<Fetch the |space_factor| or the |prev_depth|@>=
-if abs(mode)<>m then
- begin print_err("Improper "); print_cmd_chr(set_aux,m);
-@.Improper \\spacefactor@>
-@.Improper \\prevdepth@>
- help4("You can refer to \spacefactor only in horizontal mode;")@/
- ("you can refer to \prevdepth only in vertical mode; and")@/
- ("neither of these is meaningful inside \write. So")@/
- ("I'm forgetting what you said and using zero instead.");
- error;
- if level<>tok_val then scanned_result(0)(dimen_val)
- else scanned_result(0)(int_val);
- end
-else if m=vmode then scanned_result(prev_depth)(dimen_val)
-else scanned_result(space_factor)(int_val)
-
-@ @<Fetch the |dead_cycles| or the |insert_penalties|@>=
-begin if m=0 then cur_val:=dead_cycles
-@/@<Cases for `Fetch the |dead_cycles| or the |insert_penalties|'@>@/
-else cur_val:=insert_penalties;
-cur_val_level:=int_val;
-end
-
-@ @<Fetch a box dimension@>=
-begin scan_register_num;
-if box(cur_val)=null then cur_val:=0 @+else cur_val:=vmem(box(cur_val)+m).sc;
-cur_val_level:=dimen_val;
-end
-
-@ Inside an \.{\\output} routine, a user may wish to look at the page totals
-that were present at the moment when output was triggered.
-
-@d max_dimen==@'7777777777 {$2^{30}-1$}
-
-@<Fetch something on the |page_so_far|@>=
-begin if (page_contents=empty) and (not output_active) then
- if m=0 then cur_val:=max_dimen@+else cur_val:=0
-else cur_val:=page_so_far[m];
-cur_val_level:=dimen_val;
-end
-
-@ @<Fetch the |prev_graf|@>=
-if mode=0 then scanned_result(0)(int_val) {|prev_graf=0| within \.{\\write}}
-else begin nest[nest_ptr]:=cur_list; p:=nest_ptr;
- while abs(nest[p].mode_field)<>vmode do decr(p);
- scanned_result(nest[p].pg_field)(int_val);
- end
-
-@ @<Fetch the |par_shape| size@>=
-begin if par_shape_ptr=null then cur_val:=0
-else cur_val:=vinfo(par_shape_ptr+1);
-cur_val_level:=int_val;
-end
-
-@ Here is where \.{\\lastpenalty}, \.{\\lastkern}, and \.{\\lastskip} are
-implemented. The reference count for \.{\\lastskip} will be updated later.
-
-We also handle \.{\\inputlineno} and \.{\\badness} here, because they are
-legal in similar contexts.
-
-@<Fetch an item in the current node...@>=
-if m>=input_line_no_code then
- if m>=eTeX_glue then @<Process an expression and |return|@>@;
- else if m>=eTeX_dim then
- begin case m of
- @/@<Cases for fetching a dimension value@>@/
- end; {there are no other cases}
- cur_val_level:=dimen_val;
- end
- else begin case m of
- input_line_no_code: cur_val:=line;
- badness_code: cur_val:=last_badness;
- pdftex_version_code: cur_val := pdftex_version;
- luatex_version_code: cur_val := luatex_version;
- pdf_last_obj_code: cur_val := pdf_last_obj;
- pdf_last_xform_code: cur_val := pdf_last_xform;
- pdf_last_ximage_code: cur_val := pdf_last_ximage;
- pdf_last_ximage_pages_code: cur_val := pdf_last_ximage_pages;
- pdf_last_annot_code: cur_val := pdf_last_annot;
- pdf_last_x_pos_code: cur_val := pdf_last_x_pos;
- pdf_last_y_pos_code: cur_val := pdf_last_y_pos;
- pdf_retval_code: cur_val := pdf_retval;
- pdf_last_ximage_colordepth_code: cur_val := pdf_last_ximage_colordepth;
- random_seed_code: cur_val := random_seed;
- pdf_last_link_code: cur_val := pdf_last_link;
- @/@<Cases for fetching an integer value@>@/
- end; {there are no other cases}
- cur_val_level:=int_val;
- end
-else begin if cur_chr=glue_val then cur_val:=zero_glue@+else cur_val:=0;
- if cur_chr=last_node_type_code then
- begin cur_val_level:=int_val;
- if (tail=head)or(mode=0) then cur_val:=-1;
- end
- else cur_val_level:=cur_chr;
- {TODO: check this thoroughly! The structural change to the
- |is_char_node| macro was wreaking havoc here, and possibly elsewhere.}
- if tail<>contrib_head and not is_char_node(tail)and(mode<>0) then
- case cur_chr of
- int_val: if type(tail)=penalty_node then cur_val:=penalty(tail);
- dimen_val: if type(tail)=kern_node then cur_val:=width(tail);
- glue_val: if type(tail)=glue_node then
- begin cur_val:=glue_ptr(tail);
- if subtype(tail)=mu_glue then cur_val_level:=mu_val;
- end;
- last_node_type_code:
- cur_val := visible_last_node_type(tail);
- end {there are no other cases}
- else if (mode=vmode)and(tail=head) then
- case cur_chr of
- int_val: cur_val:=last_penalty;
- dimen_val: cur_val:=last_kern;
- glue_val: if last_glue<>max_halfword then cur_val:=last_glue;
- last_node_type_code: cur_val:=last_node_type;
- end; {there are no other cases}
- end
-
-@ @<Fetch a font dimension@>=
-get_font_dimen
-
-@ @<Fetch a font integer@>=
-begin scan_font_ident;
-if m=0 then scanned_result(hyphen_char(cur_val))(int_val)
-else if m=1 then scanned_result(skew_char(cur_val))(int_val)
-else if m=no_lig_code then scanned_result(test_no_ligatures(cur_val))(int_val)
-else begin
- n := cur_val;
- scan_char_num;
- k := cur_val;
- case m of
- lp_code_base: scanned_result(get_lp_code(n, k))(int_val);
- rp_code_base: scanned_result(get_rp_code(n, k))(int_val);
- ef_code_base: scanned_result(get_ef_code(n, k))(int_val);
- tag_code: scanned_result(get_tag_code(n, k))(int_val);
- end;
-end;
-end
-
-@ @<Fetch a register@>=
-begin scan_register_num;
-case m of
-int_val:cur_val:=count(cur_val);
-attr_val:cur_val:=attribute(cur_val);
-dimen_val:cur_val:=dimen(cur_val);
-glue_val: cur_val:=skip(cur_val);
-mu_val: cur_val:=mu_skip(cur_val);
-end; {there are no other cases}
-cur_val_level:=m;
-end
-
-@ @<Complain that \.{\\the} can't do this; give zero result@>=
-begin print_err("You can't use `"); print_cmd_chr(cur_cmd,cur_chr);
-@.You can't use x after ...@>
-print("' after "); print_esc("the");
-help1("I'm forgetting what you said and using zero instead.");
-error;
-if level<>tok_val then scanned_result(0)(dimen_val)
-else scanned_result(0)(int_val);
-end
-
-@ @<Complain that |texlib| can't do this; give zero result@>=
-begin print_err("You can't use `"); print_cmd_chr(cmd,m);
-print("' as tex library index");
-help1("I'm forgetting what you said and using zero instead.");
-error;
-if level<>tok_val then scanned_result(0)(dimen_val)
-else scanned_result(0)(int_val);
-end
-
-
-@ When a |glue_val| changes to a |dimen_val|, we use the width component
-of the glue; there is no need to decrease the reference count, since it
-has not yet been increased. When a |dimen_val| changes to an |int_val|,
-we use scaled points so that the value doesn't actually change. And when a
-|mu_val| changes to a |glue_val|, the value doesn't change either.
-
-@<Convert \(c)|cur_val| to a lower level@>=
-begin if cur_val_level=glue_val then cur_val:=width(cur_val)
-else if cur_val_level=mu_val then mu_error;
-decr(cur_val_level);
-end
-
-@ If |cur_val| points to a glue specification at this point, the reference
-count for the glue does not yet include the reference by |cur_val|.
-If |negative| is |true|, |cur_val_level| is known to be |<=mu_val|.
-
-@<Fix the reference count, if any, ...@>=
-if negative then begin
- if cur_val_level>=glue_val then
- begin cur_val:=new_spec(cur_val);
- @<Negate all three glue components of |cur_val|@>;
- end
- else negate(cur_val);
- end
-else if (cur_val_level>=glue_val)and(cur_val_level<=mu_val) then
- add_glue_ref(cur_val)
-
-@ @<Negate all three...@>=
-begin negate(width(cur_val));
-negate(stretch(cur_val));
-negate(shrink(cur_val));
-end
-
-@ Our next goal is to write the |scan_int| procedure, which scans anything that
-\TeX\ treats as an integer. But first we might as well look at some simple
-applications of |scan_int| that have already been made inside of
-|scan_something_internal|.
-
-@
-@d dir_T=0
-@d dir_L=1
-@d dir_B=2
-@d dir_R=3
-@d dir_eq_end(#)==(#)
-@d dir_eq(#)==(#)=dir_eq_end
-@d dir_ne_end(#)==(#)
-@d dir_ne(#)==(#)<>dir_ne_end
-@d dir_opposite_end(#)==((#) mod 4)
-@d dir_opposite(#)==(((#)+2) mod 4)=dir_opposite_end
-@d dir_parallel_end(#)==((#) mod 2)
-@d dir_parallel(#)==((#) mod 2)=dir_parallel_end
-@d dir_orthogonal_end(#)==(# mod 2)
-@d dir_orthogonal(#)==((#) mod 2)<>dir_orthogonal_end
-@d dir_next_end(#)==((#) mod 4)
-@d dir_next(#)==(((#)+3) mod 4)=dir_next_end
-@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
-@d dir_LT_=2
-@d dir_LB_=3
-@d dir_BL_=4
-@d dir_BR_=5
-@d dir_RT_=6
-@d dir_RB_=7
-
-{font directions}
-@d dir__LT= 0
-@d dir__LL= 1
-@d dir__LB= 2
-@d dir__LR= 3
-@d dir__RT= 4
-@d dir__RL= 5
-@d dir__RB= 6
-@d dir__RR= 7
-@d dir__TT= 8
-@d dir__TL= 9
-@d dir__TB=10
-@d dir__TR=11
-@d dir__BT=12
-@d dir__BL=13
-@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 font_direction(#)==(# mod 16)
-@d box_direction(#)==(# div 4)
-
-@ 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.
-
-@<Declare procedures that scan restricted classes of integers@>=
-procedure scan_register_num;
-begin scan_int;
-if (cur_val<0)or(cur_val>biggest_reg) then
- begin print_err("Bad register code");
-@.Bad register code@>
- help2("A register number must be between 0 and 65535.")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-procedure scan_mark_num;
-begin scan_int;
-if (cur_val<0)or(cur_val>biggest_mark) then
- begin print_err("Bad marks code");
-@.Bad marks code@>
- help2("A marks class must be between 0 and 65535.")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-
-@ @<Declare procedures that scan restricted classes of integers@>=
-procedure scan_char_num;
-begin scan_int;
-if (cur_val<0)or(cur_val>biggest_char) then
- begin print_err("Bad character code");
-@.Bad character code@>
- help2("A character number must be between 0 and biggest_char.")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-
-@ While we're at it, we might as well deal with similar routines that
-will be needed later.
-
-@<Declare procedures that scan restricted classes of integers@>=
-procedure scan_four_bit_int;
-begin scan_int;
-if (cur_val<0)or(cur_val>15) then
- begin print_err("Bad number");
-@.Bad number@>
- help2("Since I expected to read a number between 0 and 15,")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-procedure scan_math_family_int;
-begin scan_int;
-if (cur_val<0)or(cur_val>255) then
- begin print_err("Bad number");
-@.Bad number@>
- help2("Since I expected to read a number between 0 and 255,")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-
-@ @<Declare procedures that scan restricted classes of integers@>=
-procedure scan_real_fifteen_bit_int;
-begin scan_int;
-if (cur_val<0)or(cur_val>@'77777) then
- begin print_err("Bad mathchar");
-@.Bad mathchar@>
- help2("A mathchar number must be between 0 and 32767.")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-procedure scan_fifteen_bit_int;
-begin scan_int;
-if (cur_val<0)or(cur_val>@'77777) then
- begin print_err("Bad mathchar");
-@.Bad mathchar@>
- help2("A mathchar number must be between 0 and 32767.")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-cur_val := ((cur_val div @"1000) * @"1000000) +
- (((cur_val mod @"1000) div @"100) * @"10000) +
- (cur_val mod @"100);
-end;
-procedure scan_big_fifteen_bit_int;
-begin scan_int;
-if (cur_val<0)or(cur_val>@"7FFFFFF) then
- begin print_err("Bad extended mathchar");
-@.Bad mathchar@>
- help2("An extended mathchar number must be between 0 and ""7FFFFFF.")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-end;
-
-
-@ @<Declare procedures that scan restricted classes of integers@>=
-procedure scan_twenty_seven_bit_int;
-begin scan_int;
-if (cur_val<0)or(cur_val>@'777777777) then
- begin print_err("Bad delimiter code");
-@.Bad delimiter code@>
- 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;
-end;
-
-procedure scan_fifty_one_bit_int;
-var iiii:integer;
-begin scan_int;
-if (cur_val<0)or(cur_val>@'777777777) then
- begin print_err("Bad delimiter code");
-@.Bad delimiter code@>
- help2("A numeric delimiter (first part) must be between 0 and 2^{27}-1.")
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-iiii:=cur_val;
-scan_int;
-if (cur_val<0)or(cur_val>@"FFFFFF) then
- begin print_err("Bad delimiter code");
-@.Bad delimiter code@>
-help2("A numeric delimiter (second part) must be between 0 and 2^{24}-1.")@/
- ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
- end;
-cur_val1:=cur_val;
-cur_val:=iiii;
-end;
-
-
-procedure scan_string_argument;
-var s:integer;
-begin
-scan_left_brace;
-get_x_token;
-while (cur_cmd<>right_brace) do
- begin
- if (cur_cmd=letter) or (cur_cmd=other_char) then begin
- str_room(1); append_char(cur_chr);
- end
- else if (cur_cmd=spacer) then begin
- str_room(1); append_char(" ");
- end
- else begin
- print("Bad token appearing in string argument");
- end;
- get_x_token;
- end;
-s:=make_string;
-if str_eq_str("mi",s) then s:="mi";
-if str_eq_str("mo",s) then s:="mo";
-if str_eq_str("mn",s) then s:="mn";
-cur_val:=s;
-end;
-
-@ An integer number can be preceded by any number of spaces and `\.+' or
-`\.-' signs. Then comes either a decimal constant (i.e., radix 10), an
-octal constant (i.e., radix 8, preceded by~\.\'), a hexadecimal constant
-(radix 16, preceded by~\."), an alphabetic constant (preceded by~\.\`), or
-an internal variable. After scanning is complete,
-|cur_val| will contain the answer, which must be at most
-$2^{31}-1=2147483647$ in absolute value. The value of |radix| is set to
-10, 8, or 16 in the cases of decimal, octal, or hexadecimal constants,
-otherwise |radix| is set to zero. An optional space follows a constant.
-
-@d octal_token=other_token+"'" {apostrophe, indicates an octal constant}
-@d hex_token=other_token+"""" {double quote, indicates a hex constant}
-@d alpha_token=other_token+"`" {reverse apostrophe, precedes alpha constants}
-@d point_token=other_token+"." {decimal point}
-@d continental_point_token=other_token+"," {decimal point, Eurostyle}
-
-@<Glob...@>=
-@!radix:small_number; {|scan_int| sets this to 8, 10, 16, or zero}
-
-@ We initialize the following global variables just in case |expand|
-comes into action before any of the basic scanning routines has assigned
-them a value.
-
-@<Set init...@>=
-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
-|scan_int|. The |scan_dimen| routine assumes that |cur_tok=point_token|
-after the integer part of such a fraction has been scanned by |scan_int|,
-and that the decimal point has been backed up to be scanned again.
-
-@p procedure scan_int; {sets |cur_val| to an integer}
-label done, restart;
-var negative:boolean; {should the answer be negated?}
-@!m:integer; {|@t$2^{31}$@> div radix|, the threshold of danger}
-@!d:small_number; {the digit just scanned}
-@!vacuous:boolean; {have no digits appeared?}
-@!OK_so_far:boolean; {has an error message been issued?}
-begin radix:=0; OK_so_far:=true;@/
-@<Get the next non-blank non-sign token; set |negative| appropriately@>;
-restart:
-if cur_tok=alpha_token then @<Scan an alphabetic character code into |cur_val|@>
-else if cur_tok=cs_token_flag+frozen_primitive then
- @<Reset |cur_tok| for unexpandable primitives, goto restart@>
-else if cur_cmd=math_style then
- cur_val:=cur_chr
-else if (cur_cmd>=min_internal)and(cur_cmd<=max_internal) then
- scan_something_internal(int_val,false)
-else @<Scan a numeric constant@>;
-if negative then negate(cur_val);
-end;
-
-@ @<Get the next non-blank non-sign token...@>=
-negative:=false;
-repeat @<Get the next non-blank non-call token@>;
-if cur_tok=other_token+"-" then
- begin negative := not negative; cur_tok:=other_token+"+";
- end;
-until cur_tok<>other_token+"+"
-
-@ A space is ignored after an alphabetic character constant, so that
-such constants behave like numeric ones.
-
-@<Scan an alphabetic character code into |cur_val|@>=
-begin get_token; {suppress macro expansion}
-if cur_tok<cs_token_flag then
- begin cur_val:=cur_chr;
- if cur_cmd<=right_brace then begin
- if cur_cmd=right_brace then incr(align_state)
- else decr(align_state);
- end;
- end
-else begin {the value of a csname in this context is its name}
- if is_active_csname(cur_tok-cs_token_flag) then
- cur_val:=active_csname_value(cur_tok-cs_token_flag)
- else if single_letter(text(cur_tok-cs_token_flag)) then
- cur_val:=pool_to_unichar(str_start_macro(text(cur_tok-cs_token_flag)))
- else
- cur_val:=too_big_char;
-end;
-if cur_val>biggest_char then
- begin print_err("Improper alphabetic constant");
-@.Improper alphabetic constant@>
- help2("A one-character control sequence belongs after a ` mark.")@/
- ("So I'm essentially inserting \0 here.");
- cur_val:="0"; back_error;
- end
-else @<Scan an optional space@>;
-end
-
-@ @<Scan an optional space@>=
-begin get_x_token; if cur_cmd<>spacer then back_input;
-end
-
-@ @<Scan a numeric constant@>=
-begin radix:=10; m:=214748364;
-if cur_tok=octal_token then
- begin radix:=8; m:=@'2000000000; get_x_token;
- end
-else if cur_tok=hex_token then
- begin radix:=16; m:=@'1000000000; get_x_token;
- end;
-vacuous:=true; cur_val:=0;@/
-@<Accumulate the constant until |cur_tok| is not a suitable digit@>;
-if vacuous then @<Express astonishment that no number was here@>
-else if cur_cmd<>spacer then back_input;
-end
-
-@ @d infinity==@'17777777777 {the largest positive value that \TeX\ knows}
-@d zero_token=other_token+"0" {zero, the smallest digit}
-@d A_token=letter_token+"A" {the smallest special hex digit}
-@d other_A_token=other_token+"A" {special hex digit of type |other_char|}
-
-@<Accumulate the constant...@>=
-loop@+ begin if (cur_tok<zero_token+radix)and(cur_tok>=zero_token)and
- (cur_tok<=zero_token+9) then d:=cur_tok-zero_token
- else if radix=16 then
- if (cur_tok<=A_token+5)and(cur_tok>=A_token) then d:=cur_tok-A_token+10
- else if (cur_tok<=other_A_token+5)and(cur_tok>=other_A_token) then
- d:=cur_tok-other_A_token+10
- else goto done
- else goto done;
- vacuous:=false;
- if (cur_val>=m)and((cur_val>m)or(d>7)or(radix<>10)) then
- begin if OK_so_far then
- begin print_err("Number too big");
-@.Number too big@>
- help2("I can only go up to 2147483647='17777777777=""7FFFFFFF,")@/
- ("so I'm using that number instead of yours.");
- error; cur_val:=infinity; OK_so_far:=false;
- end;
- end
- else cur_val:=cur_val*radix+d;
- get_x_token;
- end;
-done:
-
-@ @<Express astonishment...@>=
-begin print_err("Missing number, treated as zero");
-@.Missing number...@>
-help3("A number should have been here; I inserted `0'.")@/
- ("(If you can't figure out why I needed to see a number,")@/
- ("look up `weird error' in the index to The TeXbook.)");
-@:TeXbook}{\sl The \TeX book@>
-back_error;
-end
-
-@ The |scan_dimen| routine is similar to |scan_int|, but it sets |cur_val| to
-a |scaled| value, i.e., an integral number of sp. One of its main tasks
-is therefore to interpret the abbreviations for various kinds of units and
-to convert measurements to scaled points.
-
-There are three parameters: |mu| is |true| if the finite units must be
-`\.{mu}', while |mu| is |false| if `\.{mu}' units are disallowed;
-|inf| is |true| if the infinite units `\.{fil}', `\.{fill}', `\.{filll}'
-are permitted; and |shortcut| is |true| if |cur_val| already contains
-an integer and only the units need to be considered.
-
-The order of infinity that was found in the case of infinite glue is returned
-in the global variable |cur_order|.
-
-@<Glob...@>=
-@!cur_order:glue_ord; {order of infinity found by |scan_dimen|}
-
-@ Constructions like `\.{-\'77 pt}' are legal dimensions, so |scan_dimen|
-may begin with |scan_int|. This explains why it is convenient to use
-|scan_int| also for the integer part of a decimal fraction.
-
-Several branches of |scan_dimen| work with |cur_val| as an integer and
-with an auxiliary fraction |f|, so that the actual quantity of interest is
-$|cur_val|+|f|/2^{16}$. At the end of the routine, this ``unpacked''
-representation is put into the single word |cur_val|, which suddenly
-switches significance from |integer| to |scaled|.
-
-@d attach_fraction=88 {go here to pack |cur_val| and |f| into |cur_val|}
-@d attach_sign=89 {go here when |cur_val| is correct except perhaps for sign}
-@d scan_normal_dimen==scan_dimen(false,false,false)
-
-@p procedure scan_dimen(@!mu,@!inf,@!shortcut:boolean);
- {sets |cur_val| to a dimension}
-label done, done1, done2, found, not_found, attach_fraction, attach_sign;
-var negative:boolean; {should the answer be negated?}
-@!f:integer; {numerator of a fraction whose denominator is $2^{16}$}
-@<Local variables for dimension calculations@>@;
-begin f:=0; arith_error:=false; cur_order:=normal; negative:=false;
-if not shortcut then
- begin @<Get the next non-blank non-sign...@>;
- if (cur_cmd>=min_internal)and(cur_cmd<=max_internal) then
- @<Fetch an internal dimension and |goto attach_sign|,
- or fetch an internal integer@>
- else begin back_input;
- if cur_tok=continental_point_token then cur_tok:=point_token;
- if cur_tok<>point_token then scan_int
- else begin radix:=10; cur_val:=0;
- end;
- if cur_tok=continental_point_token then cur_tok:=point_token;
- if (radix=10)and(cur_tok=point_token) then @<Scan decimal fraction@>;
- end;
- end;
-if cur_val<0 then {in this case |f=0|}
- begin negative := not negative; negate(cur_val);
- end;
-@<Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^{16})$, where there
- are |x| sp per unit; |goto attach_sign| if the units are internal@>;
-@<Scan an optional space@>;
-attach_sign: if arith_error or(abs(cur_val)>=@'10000000000) then
- @<Report that this dimension is out of range@>;
-if negative then negate(cur_val);
-end;
-
-@ @<Fetch an internal dimension and |goto attach_sign|...@>=
-if mu then
- begin scan_something_internal(mu_val,false);
- @<Coerce glue to a dimension@>;
- if cur_val_level=mu_val then goto attach_sign;
- if cur_val_level<>int_val then mu_error;
- end
-else begin scan_something_internal(dimen_val,false);
- if cur_val_level=dimen_val then goto attach_sign;
- end
-
-@ @<Local variables for dimension calculations@>=
-@!num,@!denom:1..65536; {conversion ratio for the scanned units}
-@!k,@!kk:small_number; {number of digits in a decimal fraction}
-@!p,@!q:pointer; {top of decimal digit stack}
-@!v:scaled; {an internal dimension}
-@!save_cur_val:integer; {temporary storage of |cur_val|}
-
-@ The following code is executed when |scan_something_internal| was
-called asking for |mu_val|, when we really wanted a ``mudimen'' instead
-of ``muglue.''
-
-@<Coerce glue to a dimension@>=
-if cur_val_level>=glue_val then
- begin v:=width(cur_val); delete_glue_ref(cur_val); cur_val:=v;
- end
-
-@ When the following code is executed, we have |cur_tok=point_token|, but this
-token has been backed up using |back_input|; we must first discard it.
-
-It turns out that a decimal point all by itself is equivalent to `\.{0.0}'.
-Let's hope people don't use that fact.
-
-@<Scan decimal fraction@>=
-begin k:=0; p:=null; get_token; {|point_token| is being re-scanned}
-loop@+ begin get_x_token;
- if (cur_tok>zero_token+9)or(cur_tok<zero_token) then goto done1;
- if k<17 then {digits for |k>=17| cannot affect the result}
- begin q:=get_avail; link(q):=p; info(q):=cur_tok-zero_token;
- p:=q; incr(k);
- end;
- end;
-done1: for kk:=k downto 1 do
- begin dig[kk-1]:=info(p); q:=p; p:=link(p); free_avail(q);
- end;
-f:=round_decimals(k);
-if cur_cmd<>spacer then back_input;
-end
-
-@ Now comes the harder part: At this point in the program, |cur_val| is a
-nonnegative integer and $f/2^{16}$ is a nonnegative fraction less than 1;
-we want to multiply the sum of these two quantities by the appropriate
-factor, based on the specified units, in order to produce a |scaled|
-result, and we want to do the calculation with fixed point arithmetic that
-does not overflow.
-
-@<Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^{16})$...@>=
-if inf then @<Scan for \(f)\.{fil} units; |goto attach_fraction| if found@>;
-@<Scan for \(u)units that are internal dimensions;
- |goto attach_sign| with |cur_val| set if found@>;
-if mu then @<Scan for \(m)\.{mu} units and |goto attach_fraction|@>;
-if scan_keyword('true') then @<Adjust \(f)for the magnification ratio@>;
-@.true@>
-if scan_keyword('pt') then goto attach_fraction; {the easy case}
-@.pt@>
-@<Scan for \(a)all other units and adjust |cur_val| and |f| accordingly;
- |goto done| in the case of scaled points@>;
-attach_fraction: if cur_val>=@'40000 then arith_error:=true
-else cur_val:=cur_val*unity+f;
-done:
-
-@ In traditional TeX, a specification like `\.{filllll}' or `\.{fill L L
-L}' will lead to two error messages (one for each additional keyword
-\.{"l"}).
-
-Not so for luatex, it just parses the construct in reverse.
-
-@<Scan for \(f)\.{fil} units...@>=
-begin
-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;
-end
-
-@ @<Scan for \(u)units that are internal dimensions...@>=
-save_cur_val:=cur_val;
-@<Get the next non-blank non-call...@>;
-if (cur_cmd<min_internal)or(cur_cmd>max_internal) then back_input
-else begin if mu then
- begin scan_something_internal(mu_val,false); @<Coerce glue...@>;
- if cur_val_level<>mu_val then mu_error;
- end
- else scan_something_internal(dimen_val,false);
- v:=cur_val; goto found;
- end;
-if mu then goto not_found;
-if scan_keyword('em') then v:=(@<The em width for |cur_font|@>)
-@.em@>
-else if scan_keyword('ex') then v:=(@<The x-height for |cur_font|@>)
-@.ex@>
-else if scan_keyword('px') then v:=pdf_px_dimen
-@.px@>
-else goto not_found;
-@<Scan an optional space@>;
-found:cur_val:=nx_plus_y(save_cur_val,v,xn_over_d(v,f,@'200000));
-goto attach_sign;
-not_found:
-
-@ @<Scan for \(m)\.{mu} units and |goto attach_fraction|@>=
-begin
-if scan_keyword('mu') then goto attach_fraction
-@.mu@>
-else begin print_err("Illegal unit of measure ("); print("mu inserted)");
-@.Illegal unit of measure@>
- help4("The unit of measurement in math glue must be mu.")@/
- ("To recover gracefully from this error, it's best to")@/
- ("delete the erroneous units; e.g., type `2' to delete")@/
- ("two letters. (See Chapter 27 of The TeXbook.)");
-@:TeXbook}{\sl The \TeX book@>
- error; goto attach_fraction;
- end;
-end
-
-@ @<Adjust \(f)for the magnification ratio@>=
-begin prepare_mag;
-if mag<>1000 then
- begin cur_val:=xn_over_d(cur_val,1000,mag);
- f:=(1000*f+@'200000*remainder) div mag;
- cur_val:=cur_val+(f div @'200000); f:=f mod @'200000;
- end;
-end
-
-@ The necessary conversion factors can all be specified exactly as
-fractions whose numerator and denominator add to 32768 or less.
-According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;
-this agrees well with the value $\rm1000.333\,mm$ cited by Bosshard
-@^Bosshard, Hans Rudolf@>
-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 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.
-
-@d set_conversion_end(#)== denom:=#; end
-@d set_conversion(#)==@+begin num:=#; set_conversion_end
-
-@<Scan for \(a)all other units and adjust |cur_val| and |f|...@>=
-if scan_keyword('in') then set_conversion(7227)(100)
-@.in@>
-else if scan_keyword('pc') then set_conversion(12)(1)
-@.pc@>
-else if scan_keyword('cm') then set_conversion(7227)(254)
-@.cm@>
-else if scan_keyword('mm') then set_conversion(7227)(2540)
-@.mm@>
-else if scan_keyword('bp') then set_conversion(7227)(7200)
-@.bp@>
-else if scan_keyword('dd') then set_conversion(1238)(1157)
-@.dd@>
-else if scan_keyword('cc') then set_conversion(14856)(1157)
-@.cc@>
-else if scan_keyword('nd') then set_conversion(685)(642)
-@.nd@>
-else if scan_keyword('nc') then set_conversion(1370)(107)
-@.nc@>
-else if scan_keyword('sp') then goto done
-@.sp@>
-else @<Complain about unknown unit and |goto done2|@>;
-cur_val:=xn_over_d(cur_val,num,denom);
-f:=(num*f+@'200000*remainder) div denom;@/
-cur_val:=cur_val+(f div @'200000); f:=f mod @'200000;
-done2:
-
-@ @<Complain about unknown unit...@>=
-begin print_err("Illegal unit of measure ("); print("pt inserted)");
-@.Illegal unit of measure@>
-help6("Dimensions can be in units of em, ex, in, pt, pc,")@/
- ("cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!")@/
- ("I'll assume that you meant to say pt, for printer's points.")@/
- ("To recover gracefully from this error, it's best to")@/
- ("delete the erroneous units; e.g., type `2' to delete")@/
- ("two letters. (See Chapter 27 of The TeXbook.)");
-@:TeXbook}{\sl The \TeX book@>
-error; goto done2;
-end
-
-
-@ @<Report that this dimension is out of range@>=
-begin print_err("Dimension too large");
-@.Dimension too large@>
-help2("I can't work with sizes bigger than about 19 feet.")@/
- ("Continue and I'll use the largest value I can.");@/
-error; cur_val:=max_dimen; arith_error:=false;
-end
-
-@ The final member of \TeX's value-scanning trio is |scan_glue|, which
-makes |cur_val| point to a glue specification. The reference count of that
-glue spec will take account of the fact that |cur_val| is pointing to~it.
-
-The |level| parameter should be either |glue_val| or |mu_val|.
-
-Since |scan_dimen| was so much more complex than |scan_int|, we might expect
-|scan_glue| to be even worse. But fortunately, it is very simple, since
-most of the work has already been done.
-
-@p procedure scan_glue(@!level:small_number);
- {sets |cur_val| to a glue spec pointer}
-label exit;
-var negative:boolean; {should the answer be negated?}
-@!q:pointer; {new glue specification}
-@!mu:boolean; {does |level=mu_val|?}
-begin mu:=(level=mu_val); @<Get the next non-blank non-sign...@>;
-if (cur_cmd>=min_internal)and(cur_cmd<=max_internal) then
- begin scan_something_internal(level,negative);
- if cur_val_level>=glue_val then
- begin if cur_val_level<>level then mu_error;
- return;
- end;
- if cur_val_level=int_val then scan_dimen(mu,false,true)
- else if level=mu_val then mu_error;
- end
-else begin back_input; scan_dimen(mu,false,false);
- if negative then negate(cur_val);
- end;
-@<Create a new glue specification whose width is |cur_val|; scan for its
- stretch and shrink components@>;
-exit:end;
-@#
-@<Declare procedures needed for expressions@>@;
-
-@ @<Create a new glue specification whose width is |cur_val|...@>=
-q:=new_spec(zero_glue); width(q):=cur_val;
-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
-@.minus@>
- begin scan_dimen(mu,true,false);
- shrink(q):=cur_val; shrink_order(q):=cur_order;
- end;
-cur_val:=q
-
-@ Here's a similar procedure that returns a pointer to a rule node. This
-routine is called just after \TeX\ has seen \.{\\hrule} or \.{\\vrule};
-therefore |cur_cmd| will be either |hrule| or |vrule|. The idea is to store
-the default rule dimensions in the node, then to override them if
-`\.{height}' or `\.{width}' or `\.{depth}' specifications are
-found (in any order).
-
-@d default_rule=26214 {0.4\thinspace pt}
-
-@p function scan_rule_spec:pointer;
-label reswitch;
-var q:pointer; {the rule node being created}
-begin q:=new_rule; {|width|, |depth|, and |height| all equal |null_flag| now}
-if cur_cmd=vrule then begin
- width(q):=default_rule;
- rule_dir(q):=body_direction;
- end
-else begin
- height(q):=default_rule; depth(q):=0;
- rule_dir(q):=text_direction;
-end;
-reswitch: if scan_keyword('width') then
-@.width@>
- begin scan_normal_dimen; width(q):=cur_val; goto reswitch;
- end;
-if scan_keyword('height') then
-@.height@>
- begin scan_normal_dimen; height(q):=cur_val; goto reswitch;
- end;
-if scan_keyword('depth') then
-@.depth@>
- begin scan_normal_dimen; depth(q):=cur_val; goto reswitch;
- end;
-scan_rule_spec:=q;
-end;
-
-@* \[27] Building token lists.
-The token lists for macros and for other things like \.{\\mark} and \.{\\output}
-and \.{\\write} are produced by a procedure called |scan_toks|.
-
-Before we get into the details of |scan_toks|, let's consider a much
-simpler task, that of converting the current string into a token list.
-The |str_toks| function does this; it classifies spaces as type |spacer|
-and everything else as type |other_char|.
-
-The token list created by |str_toks| begins at |link(temp_token_head)| and ends
-at the value |p| that is returned. (If |p=temp_token_head|, the list is empty.)
-
-|lua_str_toks| is almost identical, but it also escapes the three
-symbols that |lua| considers special while scanning a literal string
-
-@d unicode_incr(#)==if str_pool[#]>=@"F0 then #:=#+4 else if str_pool[#]>=@"E0
- then #:=#+3 else if str_pool[#]>=@"C0 then #:=#+2 else incr(#)
-
-
-@p @t\4@>@<Declare \eTeX\ procedures for token lists@>@;@/
-function lua_str_toks(@!b:pool_pointer):pointer;
- {changes the string |str_pool[b..pool_ptr]| to a token list}
-var p:pointer; {tail of the token list}
-@!q:pointer; {new node being added to the token list via |store_new_token|}
-@!t:halfword; {token being appended}
-@!k:pool_pointer; {index into |str_pool|}
-begin
-p:=temp_token_head; link(p):=null; k:=b;
-while k<pool_ptr do
- begin t:=pool_to_unichar(k);
- if t=" " then t:=space_token
- else
- begin
- if (t="\") or (t="""") or (t="'") or (t=10) or (t=13) then
- fast_store_new_token(other_token+"\");
- if (t=10) then
- t:="n";
- if (t=13) then
- t:="r";
- t:=other_token+t;
- end;
- fast_store_new_token(t);
- unicode_incr(k);
- end;
-pool_ptr:=b; lua_str_toks:=p;
-end;
-
-function str_toks(@!b:pool_pointer):pointer;
- {changes the string |str_pool[b..pool_ptr]| to a token list}
-var p:pointer; {tail of the token list}
-@!q:pointer; {new node being added to the token list via |store_new_token|}
-@!t:halfword; {token being appended}
-@!k:pool_pointer; {index into |str_pool|}
-begin
-p:=temp_token_head; link(p):=null; k:=b;
-while k<pool_ptr do
- begin t:=pool_to_unichar(k);
- if t=" " then t:=space_token
- else t:=other_token+t;
- fast_store_new_token(t);
- unicode_incr(k);
- end;
-pool_ptr:=b; str_toks:=p;
-end;
-
-@ The main reason for wanting |str_toks| is the next function,
-|the_toks|, which has similar input/output characteristics.
-
-This procedure is supposed to scan something like `\.{\\skip\\count12}',
-i.e., whatever can follow `\.{\\the}', and it constructs a token list
-containing something like `\.{-3.0pt minus 0.5fill}'.
-
-@p function the_toks:pointer;
-label exit;
-var old_setting:0..max_selector; {holds |selector| setting}
-@!p,@!q,@!r:pointer; {used for copying a token list}
-@!b:pool_pointer; {base of temporary string}
-@!c:small_number; {value of |cur_chr|}
-begin @<Handle \.{\\unexpanded} or \.{\\detokenize} and |return|@>;@/
-get_x_token; scan_something_internal(tok_val,false);
-if cur_val_level>=ident_val then begin
- @<Copy the token list@>;
- the_toks:=p;
- end
-else begin old_setting:=selector; selector:=new_string; b:=pool_ptr;
- case cur_val_level of
- int_val:print_int(cur_val);
- attr_val:print_int(cur_val);
- dir_val:print_dir(cur_val);
- dimen_val:begin print_scaled(cur_val); print("pt");
- end;
- glue_val: begin print_spec(cur_val,"pt"); delete_glue_ref(cur_val);
- end;
- mu_val: begin print_spec(cur_val,"mu"); delete_glue_ref(cur_val);
- end;
- end; {there are no other cases}
- selector:=old_setting; the_toks:=str_toks(b);
- end;
-exit:end;
-
-function the_scanned_result:str_number;
-var old_setting:0..max_selector; {holds |selector| setting}
-begin
-old_setting:=selector; selector:=new_string;
-if cur_val_level>=ident_val then begin
- if cur_val<>null then begin
- show_token_list(link(cur_val),null,pool_size-pool_ptr);
- the_scanned_result:=make_string;
- end
- else
- the_scanned_result:="";
- end
-else begin
- case cur_val_level of
- int_val:print_int(cur_val);
- attr_val:print_int(cur_val);
- dir_val:print_dir(cur_val);
- dimen_val:begin print_scaled(cur_val); print("pt");
- end;
- glue_val: begin print_spec(cur_val,"pt"); delete_glue_ref(cur_val);
- end;
- mu_val: begin print_spec(cur_val,"mu"); delete_glue_ref(cur_val);
- end;
- end; {there are no other cases}
- the_scanned_result:=make_string;
- end;
-selector:=old_setting;
-end;
-
-@ @<Copy the token list@>=
-begin p:=temp_token_head; link(p):=null;
-if cur_val_level=ident_val then store_new_token(cs_token_flag+cur_val)
-else if cur_val<>null then
- begin r:=link(cur_val); {do not copy the reference count}
- while r<>null do
- begin fast_store_new_token(info(r)); r:=link(r);
- end;
- end;
-end
-
-@ Here's part of the |expand| subroutine that we are now ready to complete:
-
-@p procedure ins_the_toks;
-var junk:pointer;
-begin junk:=the_toks; ins_list(link(temp_token_head));
-end;
-
-@ The primitives \.{\\number}, \.{\\romannumeral}, \.{\\string}, \.{\\meaning},
-\.{\\fontname}, and \.{\\jobname} are defined as follows.
-
-\eTeX\ adds \.{\\eTeXrevision} such that |job_name_code| remains last.
-
-\pdfTeX\ adds \.{\\eTeXrevision}, \.{\\pdftexrevision}, \.{\\pdftexbanner},
-\.{\\pdffontname}, \.{\\pdffontobjnum}, \.{\\pdffontsize}, and \.{\\pdfpageref}
-such that |job_name_code| remains last.
-
-@d number_code=0 {command code for \.{\\number}}
-@d roman_numeral_code=1 {command code for \.{\\romannumeral}}
-@d string_code=2 {command code for \.{\\string}}
-@d meaning_code=3 {command code for \.{\\meaning}}
-@d font_name_code=4 {command code for \.{\\fontname}}
-@d etex_code=5 {command code for \.{\\eTeXVersion}}
-@d omega_code=6 {command code for \.{\\OmegaVersion}}
-@d aleph_code=7 {command code for \.{\\AlephVersion}}
-@d format_name_code=8 {command code for \.{\\AlephVersion}}
-@d pdftex_first_expand_code = 9 {base for \pdfTeX's command codes}
-@d pdftex_revision_code = pdftex_first_expand_code + 0 {command code for \.{\\pdftexrevision}}
-@d pdftex_banner_code = pdftex_first_expand_code + 1 {command code for \.{\\pdftexbanner}}
-@d pdf_font_name_code = pdftex_first_expand_code + 2 {command code for \.{\\pdffontname}}
-@d pdf_font_objnum_code = pdftex_first_expand_code + 3 {command code for \.{\\pdffontobjnum}}
-@d pdf_font_size_code = pdftex_first_expand_code + 4 {command code for \.{\\pdffontsize}}
-@d pdf_page_ref_code = pdftex_first_expand_code + 5 {command code for \.{\\pdfpageref}}
-@d pdf_xform_name_code = pdftex_first_expand_code + 6 {command code for \.{\\pdfxformname}}
-@d left_margin_kern_code = pdftex_first_expand_code + 7 {command code for \.{\\leftmarginkern}}
-@d right_margin_kern_code = pdftex_first_expand_code + 8 {command code for \.{\\rightmarginkern}}
-@d pdf_creation_date_code = pdftex_first_expand_code + 9 {command code for \.{\\pdfcreationdate}}
-@d uniform_deviate_code = pdftex_first_expand_code + 10 {command code for \.{\\uniformdeviate}}
-@d normal_deviate_code = pdftex_first_expand_code + 11 {command code for \.{\\normaldeviate}}
-@d pdf_insert_ht_code = pdftex_first_expand_code + 12 {command code for \.{\\pdfinsertht}}
-@d pdf_ximage_bbox_code = pdftex_first_expand_code + 13 {command code for \.{\\pdfximagebbox}}
-@d lua_code = pdftex_first_expand_code + 14 {command code for \.{\\directlua}}
-@d lua_escape_string_code = pdftex_first_expand_code + 15 {command code for \.{\\luaescapestring}}
-@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 math_style_code = pdftex_first_expand_code + 19 {command code for \.{\\mathstyle}}
-@d expanded_code = pdftex_first_expand_code + 20 {command code for \.{\\expanded}}
-@d pdftex_convert_codes = pdftex_first_expand_code + 21 {end of \pdfTeX's command codes}
-@d job_name_code=pdftex_convert_codes {command code for \.{\\jobname}}
-
-
-@<Put each...@>=
-primitive_tex("number",convert,number_code,0);@/
-@!@:number_}{\.{\\number} primitive@>
-primitive_tex("romannumeral",convert,roman_numeral_code,0);@/
-@!@:roman_numeral_}{\.{\\romannumeral} primitive@>
-primitive_tex("string",convert,string_code,0);@/
-@!@:string_}{\.{\\string} primitive@>
-primitive_tex("meaning",convert,meaning_code,0);@/
-@!@:meaning_}{\.{\\meaning} primitive@>
-primitive_etex("eTeXVersion",convert,etex_code,0);@/
-@!@:omega_version_}{\.{\\OmegaVersion} primitive@>
-primitive_omega("OmegaVersion",convert,omega_code,0);@/
-@!@:omega_version_}{\.{\\OmegaVersion} primitive@>
-primitive_aleph("AlephVersion",convert,aleph_code,0);@/
-@!@:aleph_version_}{\.{\\AlephVersion} primitive@>
-primitive_tex("fontname",convert,font_name_code,0);@/
-@!@:font_name_}{\.{\\fontname} primitive@>
-primitive_pdftex("pdftexrevision",convert,pdftex_revision_code,0);@/
-@!@:pdftex_revision_}{\.{\\pdftexrevision} primitive@>
-primitive_luatex("luatexrevision",convert,luatex_revision_code,0);@/
-@!@:luatex_revision_}{\.{\\luatexrevision} primitive@>
-primitive_luatex("luatexdatestamp",convert,luatex_date_code,0);@/
-@!@:luatex_date_}{\.{\\luatexdatestamp} primitive@>
-primitive_pdftex("pdftexbanner",convert,pdftex_banner_code,0);@/
-@!@:pdftex_banner_}{\.{\\pdftexbanner} primitive@>
-primitive_pdftex("pdffontname",convert,pdf_font_name_code,0);@/
-@!@:pdf_font_name_}{\.{\\pdffontname} primitive@>
-primitive_pdftex("pdffontobjnum",convert,pdf_font_objnum_code,0);@/
-@!@:pdf_font_objnum_}{\.{\\pdffontobjnum} primitive@>
-primitive_pdftex("pdffontsize",convert,pdf_font_size_code,0);@/
-@!@:pdf_font_size_}{\.{\\pdffontsize} primitive@>
-primitive_pdftex("pdfpageref",convert,pdf_page_ref_code,0);@/
-@!@:pdf_page_ref_}{\.{\\pdfpageref} primitive@>
-primitive_pdftex("leftmarginkern",convert,left_margin_kern_code,0);@/
-@!@:left_margin_kern_}{\.{\\leftmarginkern} primitive@>
-primitive_pdftex("rightmarginkern",convert,right_margin_kern_code,0);@/
-@!@:right_margin_kern_}{\.{\\rightmarginkern} primitive@>
-primitive_pdftex("pdfxformname",convert,pdf_xform_name_code,0);@/
-@!@:pdf_xform_name_}{\.{\\pdfxformname} primitive@>
-primitive_pdftex("pdfcreationdate",convert,pdf_creation_date_code,0);@/
-@!@:pdf_creation_date_}{\.{\\pdfcreationdate} primitive@>
-primitive_pdftex("pdfuniformdeviate",convert,uniform_deviate_code,0);@/
-@!@:uniform_deviate_}{\.{\\pdfuniformdeviate} primitive@>
-primitive_pdftex("pdfcolorstackinit",convert,pdf_colorstack_init_code,0);@/
-@!@:pdf_colorstack_init_}{\.{\\pdfcolorstackinit} primitive@>
-primitive_pdftex("pdfnormaldeviate",convert,normal_deviate_code,0);@/
-@!@:normal_deviate_}{\.{\\pdfnormaldeviate} primitive@>
-primitive_core("directlua",convert,lua_code,0);@/
-@!@:lua_}{\.{\\directlua} primitive@>
-primitive_luatex("luaescapestring",convert,lua_escape_string_code,0);@/
-@!@:lua_}{\.{\\luaescapestring} primitive@>
-primitive_luatex("mathstyle",convert,math_style_code,0);@/
-@!@:math_style_}{\.{\\mathstyle} primitive@>
-primitive_pdftex("expanded",convert,expanded_code,0);@/
-@!@:expanded_}{\.{\\expanded} primitive@>
-@#
-primitive_tex("jobname",convert,job_name_code,0);@/
-@!@:job_name_}{\.{\\jobname} primitive@>
-primitive_luatex("formatname",convert,format_name_code,0);@/
-@!@:format_name_}{\.{\\formatname} primitive@>
-primitive_pdftex("pdfinsertht",convert,pdf_insert_ht_code,0);@/
-@!@:pdf_insert_ht_}{\.{\\pdfinsertht} primitive@>
-primitive_pdftex("pdfximagebbox",convert,pdf_ximage_bbox_code,0);@/
-@!@:pdf_ximage_bbox_}{\.{\\pdfximagebbox} primitive@>
-
-@ 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}'.
-
-The extra temp string |u| is needed because |pdf_scan_ext_toks| incorporates
-any pending string in its output. In order to save such a pending string,
-we have to create a temporary string that is destroyed immediately after.
-
-@d save_cur_string==if str_start_macro(str_ptr)<pool_ptr then u:=make_string
-@d restore_cur_string==if u<>0 then begin decr(str_ptr); u:=0; end
-
-@p procedure conv_toks;
-label exit;
-var old_setting:0..max_selector; {holds |selector| setting}
-p, q: pointer;
-@!c:number_code..job_name_code; {desired type of conversion}
-@!save_scanner_status:small_number; {|scanner_status| upon entry}
-@!save_def_ref: pointer; {|def_ref| upon entry, important if inside `\.{\\message}'}
-@!save_warning_index: pointer;
-@!bool: boolean; {temp boolean}
-@!i: integer; {first temp integer}
-@!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
-c:=cur_chr;
-u:=0; { will become non-nil if a string is already being built}
-j:=0; i:=0;
-@<Scan the argument for command |c|@>;
-old_setting:=selector; selector:=new_string; b:=pool_ptr;
-@<Print the result of command |c|@>;
-selector:=old_setting; junk:=str_toks(b); ins_list(link(temp_token_head));
-exit:
-end;
-
-@ @<Glob...@>=
-in_lua_escape:boolean;
-
-@ @<Set init...@>=
-in_lua_escape:=false;
-
-@ @<Scan the argument for command |c|@>=
-case c of
-number_code,roman_numeral_code: scan_int;
-string_code, meaning_code: begin save_scanner_status:=scanner_status;
- scanner_status:=normal; get_token; scanner_status:=save_scanner_status;
- end;
-etex_code: do_nothing;
-omega_code: do_nothing;
-aleph_code: do_nothing;
-font_name_code: scan_font_ident;
-pdftex_revision_code: do_nothing;
-luatex_revision_code: do_nothing;
-luatex_date_code: do_nothing;
-pdftex_banner_code: do_nothing;
-pdf_font_name_code, pdf_font_objnum_code, pdf_font_size_code: begin
- scan_font_ident;
- if cur_val = null_font then
- pdf_error("font", "invalid font identifier");
- if c <> pdf_font_size_code then begin
- pdf_check_vf_cur_val;
- if not font_used(cur_val) then
- pdf_init_font_cur_val;
- end;
-end;
-pdf_page_ref_code: begin
- scan_int;
- if cur_val <= 0 then
- pdf_error("pageref", "invalid page number");
-end;
-left_margin_kern_code, right_margin_kern_code: begin
- scan_int;
- if (box(cur_val) = null) or (type(box(cur_val)) <> hlist_node) then
- pdf_error("marginkern", "a non-empty hbox expected")
-end;
-pdf_xform_name_code: begin
- scan_int;
- pdf_check_obj(obj_type_xform, cur_val);
-end;
-pdf_creation_date_code:
- begin
- b := pool_ptr;
- getcreationdate;
- junk := str_toks(b);
- ins_list(link(temp_token_head));
- return;
- end;
-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
- cur_val := direct_always
- else
- if scan_keyword('page') then
- cur_val := direct_page
- else
- cur_val := set_origin;
- save_scanner_status := scanner_status;
- save_warning_index := warning_index;
- save_def_ref := def_ref;
- save_cur_string;
- scan_pdf_ext_toks;
- s := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- def_ref := save_def_ref;
- warning_index := save_warning_index;
- scanner_status := save_scanner_status;
- cur_val := newcolorstack(s, cur_val, bool);
- flush_str(s);
- cur_val_level := int_val;
- if cur_val < 0 then begin
- print_err("Too many color stacks");
-@.Too many color stacks@>
- help2("The number of color stacks is limited to 32768.")@/
- ("I'll use the default color stack 0 here.");
- error;
- cur_val := 0;
- restore_cur_string;
- end;
- end;
-uniform_deviate_code: scan_int;
-normal_deviate_code: do_nothing;
-lua_escape_string_code:
- begin
- u:=0;
- { check if a string is already being built}
- if str_start_macro(str_ptr)<pool_ptr then u:=make_string;
- save_scanner_status := scanner_status;
- save_def_ref := def_ref;
- save_warning_index := warning_index;
- scan_pdf_ext_toks;
- bool := in_lua_escape;
- in_lua_escape:=true;
- s := tokens_to_string(def_ref);
- in_lua_escape:=bool;
- delete_token_ref(def_ref);
- def_ref := save_def_ref;
- warning_index := save_warning_index;
- scanner_status := save_scanner_status;
- junk := lua_str_toks(str_start_macro(s));
- ins_list(link(temp_token_head));
- flush_str(s);
- if u<>0 then begin decr(str_ptr); u:=0; end;
- return;
- end;
-math_style_code: do_nothing;
-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;
- { 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)<pool_ptr then u:=make_string;
- save_scanner_status := scanner_status;
- save_def_ref := def_ref;
- save_warning_index := warning_index;
- sn:=0;
- if scan_keyword('name') then begin
- scan_pdf_ext_toks;
- sn := def_ref;
- end;
- @<Parse optional lua state integer, or an instance name to be stored in |sn|@>;
- 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(s,sn);
- delete_token_ref(s);
- 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));
- while i<length(u) do
- str_pool[pool_ptr+i]:=str_pool[str_start_macro(u)+i];
- end;
- end;
- if luacstrings>0 then
- lua_string_start;
- return;
- end;
-pdf_insert_ht_code: scan_register_num;
-pdf_ximage_bbox_code: begin
- scan_int;
- pdf_check_obj(obj_type_ximage, cur_val);
- i := obj_data_ptr(cur_val);
- scan_int;
- j := cur_val;
- if (j < 1) or (j > 4) then
- pdf_error("pdfximagebbox", "invalid parameter");
- end;
-@<Cases of `Scan the argument for command |c|'@>
-end {there are no other cases}
-
-@ @<Parse optional lua state...@>=
-begin
- @<Get the next non-blank non-relax non-call token@>;
- 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
-
-@ @<Print the result of command |c|@>=
-case c of
-number_code: print_int(cur_val);
-roman_numeral_code: print_roman_int(cur_val);
-string_code:if cur_cs<>0 then sprint_cs(cur_cs)
- else print(cur_chr);
-meaning_code: print_meaning;
-etex_code: print(eTeX_version_string);
-omega_code: print(Omega_version_string);
-aleph_code: print(Aleph_version_string);
-font_name_code: begin
- append_string(font_name(cur_val));
- if font_size(cur_val)<>font_dsize(cur_val) then
- begin print(" at "); print_scaled(font_size(cur_val));
- print("pt");
- end;
- end;
-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);
-pdf_font_name_code, pdf_font_objnum_code: begin
- set_ff(cur_val);
- 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(cur_val));
- print("pt");
-end;
-pdf_page_ref_code: print_int(get_obj(obj_type_page, cur_val, false));
-left_margin_kern_code: begin
- p := list_ptr(box(cur_val));
- if (p <> null) and (not is_char_node(p)) and
- (type(p) = glue_node) and (subtype(p) = left_skip_code + 1) then
- p := vlink(p);
- if (p <> null) and (not is_char_node(p)) and
- (type(p) = margin_kern_node) and (subtype(p) = left_side) then
- print_scaled(width(p))
- else
- print("0");
- print("pt");
-end;
-right_margin_kern_code: begin
- q := list_ptr(box(cur_val));
- p := null;
- if q <> null then begin
- p := prev_rightmost(q, null);
- if (p <> null) and (not is_char_node(p)) and
- (type(p) = glue_node) and (subtype(p) = right_skip_code + 1) then
- p := prev_rightmost(q, p);
- end;
- if (p <> null) and (not is_char_node(p)) and
- (type(p) = margin_kern_node) and (subtype(p) = right_side) then
- print_scaled(width(p))
- else
- print("0");
- print("pt");
-end;
-pdf_xform_name_code: print_int(obj_info(cur_val));
-pdf_colorstack_init_code: print_int(cur_val);
-uniform_deviate_code: print_int(unif_rand(cur_val));
-normal_deviate_code: print_int(norm_rand);
-math_style_code: print_math_style;
-pdf_insert_ht_code: begin
- i := qi(cur_val);
- p := page_ins_head;
- while i >= subtype(vlink(p)) do
- p := vlink(p);
- if subtype(p) = i then
- print_scaled(height(p))
- else
- print("0");
- print("pt");
-end;
-pdf_ximage_bbox_code: begin
- 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);
-job_name_code: print(job_name);
-@/@<Cases of `Print the result of command |c|'@>@/
-end {there are no other cases}
-
-@
-@p function is_convert(c:halfword):boolean;
-begin
- is_convert:=(c=convert);
-end;
-
-function the_convert_string (c:halfword;i:integer):str_number;
-var old_setting:0..max_selector; {saved |selector| setting}
- is_known:boolean;
-begin
- old_setting:=selector;
- selector:=new_string;
- is_known:=true;
- case c of
- 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);
- math_style_code: print_math_style;
- 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;
-
-@/@<Cases of `Print the result of command |c|'@>@/
- othercases is_known:=false
- end;
- if is_known then
- the_convert_string := make_string
- else
- the_convert_string := 0;
- selector:=old_setting;
-end;
-
-@ Now we can't postpone the difficulties any longer; we must bravely tackle
-|scan_toks|. This function returns a pointer to the tail of a new token
-list, and it also makes |def_ref| point to the reference count at the
-head of that list.
-
-There are two boolean parameters, |macro_def| and |xpand|. If |macro_def|
-is true, the goal is to create the token list for a macro definition;
-otherwise the goal is to create the token list for some other \TeX\
-primitive: \.{\\mark}, \.{\\output}, \.{\\everypar}, \.{\\lowercase},
-\.{\\uppercase}, \.{\\message}, \.{\\errmessage}, \.{\\write}, or
-\.{\\special}. In the latter cases a left brace must be scanned next; this
-left brace will not be part of the token list, nor will the matching right
-brace that comes at the end. If |xpand| is false, the token list will
-simply be copied from the input using |get_token|. Otherwise all expandable
-tokens will be expanded until unexpandable tokens are left, except that
-the results of expanding `\.{\\the}' are not expanded further.
-If both |macro_def| and |xpand| are true, the expansion applies
-only to the macro body (i.e., to the material following the first
-|left_brace| character).
-
-The value of |cur_cs| when |scan_toks| begins should be the |eqtb|
-address of the control sequence to display in ``runaway'' error
-messages.
-
-@p function scan_toks(@!macro_def,@!xpand:boolean):pointer;
-label found,done,done1,done2;
-var t:halfword; {token representing the highest parameter number}
-@!s:halfword; {saved token}
-@!p:pointer; {tail of the token list being built}
-@!q:pointer; {new node being added to the token list via |store_new_token|}
-@!unbalance:halfword; {number of unmatched left braces}
-@!hash_brace:halfword; {possible `\.{\#\{}' token}
-begin if macro_def then scanner_status:=defining
-@+else scanner_status:=absorbing;
-warning_index:=cur_cs; p:=get_avail; def_ref:=p; token_ref_count(def_ref):=0;
-p:=def_ref; hash_brace:=0; t:=zero_token;
-if macro_def then @<Scan and build the parameter part of the macro definition@>
-else scan_left_brace; {remove the compulsory left brace}
-@<Scan and build the body of the token list; |goto found| when finished@>;
-found: scanner_status:=normal;
-if hash_brace<>0 then store_new_token(hash_brace);
-scan_toks:=p;
-end;
-
-@ @<Scan and build the parameter part...@>=
-begin loop begin get_token; {set |cur_cmd|, |cur_chr|, |cur_tok|}
- if cur_tok<right_brace_limit then goto done1;
- if cur_cmd=mac_param then
- @<If the next character is a parameter number, make |cur_tok|
- a |match| token; but if it is a left brace, store
- `|left_brace|, |end_match|', set |hash_brace|, and |goto done|@>;
- store_new_token(cur_tok);
- end;
-done1: store_new_token(end_match_token);
-if cur_cmd=right_brace then
- @<Express shock at the missing left brace; |goto found|@>;
-done: end
-
-@ @<Express shock...@>=
-begin print_err("Missing { inserted"); incr(align_state);
-@.Missing \{ inserted@>
-help2("Where was the left brace? You said something like `\def\a}',")@/
- ("which I'm going to interpret as `\def\a{}'."); error; goto found;
-end
-
-@ @<If the next character is a parameter number...@>=
-begin s:=match_token+cur_chr; get_token;
-if cur_cmd=left_brace then
- begin hash_brace:=cur_tok;
- store_new_token(cur_tok); store_new_token(end_match_token);
- goto done;
- end;
-if t=zero_token+9 then
- begin print_err("You already have nine parameters");
-@.You already have nine...@>
- help1("I'm going to ignore the # sign you just used."); error;
- end
-else begin incr(t);
- if cur_tok<>t then
- begin print_err("Parameters must be numbered consecutively");
-@.Parameters...consecutively@>
- help2("I've inserted the digit you should have used after the #.")@/
- ("Type `1' to delete what you did use."); back_error;
- end;
- cur_tok:=s;
- end;
-end
-
-@ @<Scan and build the body of the token list; |goto found| when finished@>=
-unbalance:=1;
-loop@+ begin if xpand then @<Expand the next part of the input@>
- else get_token;
- if cur_tok<right_brace_limit then begin
- if cur_cmd<right_brace then incr(unbalance)
- else begin decr(unbalance);
- if unbalance=0 then goto found;
- end;
- end
- else if cur_cmd=mac_param then
- if macro_def then @<Look for parameter number or \.{\#\#}@>;
- store_new_token(cur_tok);
- end
-
-@ Here we insert an entire token list created by |the_toks| without
-expanding it further.
-
-@<Expand the next part of the input@>=
-begin loop begin get_filtered_next;
- if cur_cmd>=call then
- if info(link(cur_chr))=protected_token then
- begin cur_cmd:=relax; cur_chr:=no_expand_flag;
- end;
- if cur_cmd<=max_command then goto done2;
- if cur_cmd<>the then expand
- else begin q:=the_toks;
- if link(temp_token_head)<>null then
- begin link(p):=link(temp_token_head); p:=q;
- end;
- end;
- end;
-done2: x_token
-end
-
-@ @<Look for parameter number...@>=
-begin s:=cur_tok;
-if xpand then get_x_token else get_token;
-if cur_cmd<>mac_param then begin
- if (cur_tok<=zero_token)or(cur_tok>t) then
- begin print_err("Illegal parameter number in definition of ");
-@.Illegal parameter number...@>
- sprint_cs(warning_index);
- help3("You meant to type ## instead of #, right?")@/
- ("Or maybe a } was forgotten somewhere earlier, and things")@/
- ("are all screwed up? I'm going to assume that you meant ##.");
- back_error; cur_tok:=s;
- end
- else cur_tok:=out_param_token-"0"+cur_chr;
- end;
-end
-
-@ Another way to create a token list is via the \.{\\read} command. The
-sixteen files potentially usable for reading appear in the following
-global variables. The value of |read_open[n]| will be |closed| if
-stream number |n| has not been opened or if it has been fully read;
-|just_open| if an \.{\\openin} but not a \.{\\read} has been done;
-and |normal| if it is open and ready to read the next line.
-
-@d closed=2 {not open, or at end of file}
-@d just_open=1 {newly opened, first line not yet read}
-
-@<Glob...@>=
-@!read_file:array[0..15] of alpha_file; {used for \.{\\read}}
-@!read_open:array[0..16] of normal..closed; {state of |read_file[n]|}
-
-@ @<Set init...@>=
-for k:=0 to 16 do begin
- read_open[k]:=closed;
-end;
-
-@ The |read_toks| procedure constructs a token list like that for any
-macro definition, and makes |cur_val| point to it. Parameter |r| points
-to the control sequence that will receive this token list.
-
-@p procedure read_toks(@!n:integer;@!r:pointer;@!j:halfword);
-label done;
-var p:pointer; {tail of the token list}
-@!q:pointer; {new node being added to the token list via |store_new_token|}
-@!s:integer; {saved value of |align_state|}
-@!m:small_number; {stream number}
-begin scanner_status:=defining; warning_index:=r;
-p:=get_avail; def_ref:=p; token_ref_count(def_ref):=0;
-p:=def_ref; {the reference count}
-store_new_token(end_match_token);
-if (n<0)or(n>15) then m:=16@+else m:=n;
-s:=align_state; align_state:=1000000; {disable tab marks, etc.}
-repeat @<Input and store tokens from the next line of the file@>;
-until align_state=1000000;
-cur_val:=def_ref; scanner_status:=normal; align_state:=s;
-end;
-
-@ @<Input and store tokens from the next line of the file@>=
-begin_file_reading; name:=m+1;
-if read_open[m]=closed then @<Input for \.{\\read} from the terminal@>
-else if read_open[m]=just_open then @<Input the first line of |read_file[m]|@>
-else @<Input the next line of |read_file[m]|@>;
-limit:=last;
-if end_line_char_inactive then decr(limit)
-else buffer[limit]:=end_line_char;
-first:=limit+1; loc:=start; state:=new_line;@/
-@<Handle \.{\\readline} and |goto done|@>;@/
-loop@+ begin get_token;
- if cur_tok=0 then goto done;
- {|cur_cmd=cur_chr=0| will occur at the end of the line}
- if align_state<1000000 then {unmatched `\.\}' aborts the line}
- begin repeat get_token; until cur_tok=0;
- align_state:=1000000; goto done;
- end;
- store_new_token(cur_tok);
- end;
-done: end_file_reading
-
-@ Here we input on-line into the |buffer| array, prompting the user explicitly
-if |n>=0|. The value of |n| is set negative so that additional prompts
-will not be given in the case of multi-line input.
-
-@<Input for \.{\\read} from the terminal@>=
-if interaction>nonstop_mode then
- if n<0 then prompt_input("")
- else begin wake_up_terminal;
- print_ln; sprint_cs(r); prompt_input("="); n:=-1;
- end
-else fatal_error("*** (cannot \read from terminal in nonstop modes)")
-@.cannot \\read@>
-
-@ The first line of a file must be treated specially, since |lua_input_ln|
-must be told not to start with |get|.
-@^system dependencies@>
-
-@<Input the first line of |read_file[m]|@>=
-begin if lua_input_ln(read_file[m],(m+1),false) then read_open[m]:=normal
-else begin lua_a_close_in(read_file[m],(m+1)); read_open[m]:=closed;
- end;
-end
-
-@ An empty line is appended at the end of a |read_file|.
-@^empty line at end of file@>
-
-@<Input the next line of |read_file[m]|@>=
-begin if not lua_input_ln(read_file[m],(m+1),true) then
- begin lua_a_close_in(read_file[m],(m+1)); read_open[m]:=closed;
- if align_state<>1000000 then
- begin runaway;
- print_err("File ended within "); print_esc("read");
-@.File ended within \\read@>
- help1("This \read has unbalanced braces.");
- align_state:=1000000; error;
- end;
- end;
-end
-
-@* \[28] Conditional processing.
-We consider now the way \TeX\ handles various kinds of \.{\\if} commands.
-
-@d unless_code=32 {amount added for `\.{\\unless}' prefix}
-@#
-@d if_char_code=0 { `\.{\\if}' }
-@d if_cat_code=1 { `\.{\\ifcat}' }
-@d if_int_code=2 { `\.{\\ifnum}' }
-@d if_dim_code=3 { `\.{\\ifdim}' }
-@d if_odd_code=4 { `\.{\\ifodd}' }
-@d if_vmode_code=5 { `\.{\\ifvmode}' }
-@d if_hmode_code=6 { `\.{\\ifhmode}' }
-@d if_mmode_code=7 { `\.{\\ifmmode}' }
-@d if_inner_code=8 { `\.{\\ifinner}' }
-@d if_void_code=9 { `\.{\\ifvoid}' }
-@d if_hbox_code=10 { `\.{\\ifhbox}' }
-@d if_vbox_code=11 { `\.{\\ifvbox}' }
-@d ifx_code=12 { `\.{\\ifx}' }
-@d if_eof_code=13 { `\.{\\ifeof}' }
-@d if_true_code=14 { `\.{\\iftrue}' }
-@d if_false_code=15 { `\.{\\iffalse}' }
-@d if_case_code=16 { `\.{\\ifcase}' }
-@d if_primitive_code=21 { `\.{\\ifprimitive}' }
-
-@<Put each...@>=
-primitive_tex("if",if_test,if_char_code,0);
-@!@:if_char_}{\.{\\if} primitive@>
-primitive_tex("ifcat",if_test,if_cat_code,0);
-@!@:if_cat_code_}{\.{\\ifcat} primitive@>
-primitive_tex("ifnum",if_test,if_int_code,0);
-@!@:if_int_}{\.{\\ifnum} primitive@>
-primitive_tex("ifdim",if_test,if_dim_code,0);
-@!@:if_dim_}{\.{\\ifdim} primitive@>
-primitive_tex("ifodd",if_test,if_odd_code,0);
-@!@:if_odd_}{\.{\\ifodd} primitive@>
-primitive_tex("ifvmode",if_test,if_vmode_code,0);
-@!@:if_vmode_}{\.{\\ifvmode} primitive@>
-primitive_tex("ifhmode",if_test,if_hmode_code,0);
-@!@:if_hmode_}{\.{\\ifhmode} primitive@>
-primitive_tex("ifmmode",if_test,if_mmode_code,0);
-@!@:if_mmode_}{\.{\\ifmmode} primitive@>
-primitive_tex("ifinner",if_test,if_inner_code,0);
-@!@:if_inner_}{\.{\\ifinner} primitive@>
-primitive_tex("ifvoid",if_test,if_void_code,0);
-@!@:if_void_}{\.{\\ifvoid} primitive@>
-primitive_tex("ifhbox",if_test,if_hbox_code,0);
-@!@:if_hbox_}{\.{\\ifhbox} primitive@>
-primitive_tex("ifvbox",if_test,if_vbox_code,0);
-@!@:if_vbox_}{\.{\\ifvbox} primitive@>
-primitive_tex("ifx",if_test,ifx_code,0);
-@!@:ifx_}{\.{\\ifx} primitive@>
-primitive_tex("ifeof",if_test,if_eof_code,0);
-@!@:if_eof_}{\.{\\ifeof} primitive@>
-primitive_tex("iftrue",if_test,if_true_code,0);
-@!@:if_true_}{\.{\\iftrue} primitive@>
-primitive_tex("iffalse",if_test,if_false_code,0);
-@!@:if_false_}{\.{\\iffalse} primitive@>
-primitive_tex("ifcase",if_test,if_case_code,0);
-@!@:if_case_}{\.{\\ifcase} primitive@>
-primitive_luatex("ifprimitive",if_test,if_primitive_code,0);
-@!@:if_primitive_}{\.{\\ifprimitive} primitive@>
-primitive_pdftex("ifpdfprimitive",if_test,if_primitive_code,0);
-@!@:if_primitive_}{\.{\\ifpdfprimitive} primitive@>
-
-@ Conditions can be inside conditions, and this nesting has a stack
-that is independent of the |save_stack|.
-
-Four global variables represent the top of the condition stack:
-|cond_ptr| points to pushed-down entries, if any; |if_limit| specifies
-the largest code of a |fi_or_else| command that is syntactically legal;
-|cur_if| is the name of the current type of conditional; and |if_line|
-is the line number at which it began.
-
-If no conditions are currently in progress, the condition stack has the
-special state |cond_ptr=null|, |if_limit=normal|, |cur_if=0|, |if_line=0|.
-Otherwise |cond_ptr| points to a two-word node; the |type|, |subtype|, and
-|link| fields of the first word contain |if_limit|, |cur_if|, and
-|cond_ptr| at the next level, and the second word contains the
-corresponding |if_line|.
-
-@d if_limit_subtype(#)==subtype(#+1)
-@d if_limit_type(#)==type(#+1)
-@d if_line_field(#)==vlink(#+1)
-@d if_code=1 {code for \.{\\if...} being evaluated}
-@d fi_code=2 {code for \.{\\fi}}
-@d else_code=3 {code for \.{\\else}}
-@d or_code=4 {code for \.{\\or}}
-
-@<Glob...@>=
-@!cond_ptr:pointer; {top of the condition stack}
-@!if_limit:normal..or_code; {upper bound on |fi_or_else| codes}
-@!cur_if:small_number; {type of conditional being worked on}
-@!if_line:integer; {line where that conditional began}
-
-@ @<Set init...@>=
-cond_ptr:=null; if_limit:=normal; cur_if:=0; if_line:=0;
-
-@ @<Put each...@>=
-primitive_tex("fi",fi_or_else,fi_code,0);
-@!@:fi_}{\.{\\fi} primitive@>
-text(frozen_fi):="fi"; eqtb[frozen_fi]:=eqtb[cur_val];
-primitive_tex("or",fi_or_else,or_code,0);
-@!@:or_}{\.{\\or} primitive@>
-primitive_tex("else",fi_or_else,else_code,0);
-@!@:else_}{\.{\\else} primitive@>
-
-@ When we skip conditional text, we keep track of the line number
-where skipping began, for use in error messages.
-
-@<Glob...@>=
-@!skip_line:integer; {skipping began here}
-
-@ Here is a procedure that ignores text until coming to an \.{\\or},
-\.{\\else}, or \.{\\fi} at level zero of $\.{\\if}\ldots\.{\\fi}$
-nesting. After it has acted, |cur_chr| will indicate the token that
-was found, but |cur_tok| will not be set (because this makes the
-procedure run faster).
-
-@p procedure pass_text;
-label done;
-var l:integer; {level of $\.{\\if}\ldots\.{\\fi}$ nesting}
-@!save_scanner_status:small_number; {|scanner_status| upon entry}
-begin save_scanner_status:=scanner_status; scanner_status:=skipping; l:=0;
-skip_line:=line;
-loop@+ begin get_filtered_next;
- if cur_cmd=fi_or_else then
- begin if l=0 then goto done;
- if cur_chr=fi_code then decr(l);
- end
- else if cur_cmd=if_test then incr(l);
- end;
-done: scanner_status:=save_scanner_status;
-if tracing_ifs>0 then show_cur_cmd_chr;
-end;
-
-@ When we begin to process a new \.{\\if}, we set |if_limit:=if_code|; then
-if\/ \.{\\or} or \.{\\else} or \.{\\fi} occurs before the current \.{\\if}
-condition has been evaluated, \.{\\relax} will be inserted.
-For example, a sequence of commands like `\.{\\ifvoid1\\else...\\fi}'
-would otherwise require something after the `\.1'.
-
-@<Push the condition stack@>=
-begin p:=new_node(if_node,0); vlink(p):=cond_ptr;
-if_limit_type(p):=if_limit;
-if_limit_subtype(p):=cur_if;
-if_line_field(p):=if_line;
-cond_ptr:=p; cur_if:=cur_chr; if_limit:=if_code; if_line:=line;
-end
-
-@ @<Pop the condition stack@>=
-begin if if_stack[in_open]=cond_ptr then if_warning;
- {conditionals possibly not properly nested with files}
-p:=cond_ptr;
-if_line:=if_line_field(p);
-cur_if:=if_limit_subtype(p);
-if_limit:=if_limit_type(p);
-cond_ptr:=vlink(p);
-flush_node(p);
-end
-
-@ Here's a procedure that changes the |if_limit| code corresponding to
-a given value of |cond_ptr|.
-
-@p procedure change_if_limit(@!l:small_number;@!p:pointer);
-label exit;
-var q:pointer;
-begin if p=cond_ptr then if_limit:=l {that's the easy case}
-else begin q:=cond_ptr;
- loop@+ begin if q=null then confusion("if");
-@:this can't happen if}{\quad if@>
- if vlink(q)=p then
- begin if_limit_type(q):=l; return;
- end;
- q:=vlink(q);
- end;
- end;
-exit:end;
-
-@ A condition is started when the |expand| procedure encounters
-an |if_test| command; in that case |expand| reduces to |conditional|,
-which is a recursive procedure.
-@^recursion@>
-
-@p procedure conditional;
-label exit,common_ending;
-var b:boolean; {is the condition true?}
-@!r:"<"..">"; {relation to be evaluated}
-@!m,@!n,@!s:integer; {to be tested against the second operand}
-@!p,@!q:pointer; {for traversing token lists in \.{\\ifx} tests}
-@!save_scanner_status:small_number; {|scanner_status| upon entry}
-@!save_cond_ptr:pointer; {|cond_ptr| corresponding to this conditional}
-@!this_if:small_number; {type of this conditional}
-@!is_unless:boolean; {was this if preceded by `\.{\\unless}' ?}
-begin b:= false; {default is false, just in case}
-if tracing_ifs>0 then if tracing_commands<=1 then show_cur_cmd_chr;
-@<Push the condition stack@>;@+save_cond_ptr:=cond_ptr;
-is_unless:=(cur_chr>=unless_code); this_if:=cur_chr mod unless_code;@/
-@<Either process \.{\\ifcase} or set |b| to the value of a boolean condition@>;
-if is_unless then b:=not b;
-if tracing_commands>1 then @<Display the value of |b|@>;
-if b then
- begin change_if_limit(else_code,save_cond_ptr);
- return; {wait for \.{\\else} or \.{\\fi}}
- end;
-@<Skip to \.{\\else} or \.{\\fi}, then |goto common_ending|@>;
-common_ending: if cur_chr=fi_code then @<Pop the condition stack@>
-else if_limit:=fi_code; {wait for \.{\\fi}}
-exit:end;
-
-@ In a construction like `\.{\\if\\iftrue abc\\else d\\fi}', the first
-\.{\\else} that we come to after learning that the \.{\\if} is false is
-not the \.{\\else} we're looking for. Hence the following curious
-logic is needed.
-
-@ @<Skip to \.{\\else} or \.{\\fi}...@>=
-loop@+ begin pass_text;
- if cond_ptr=save_cond_ptr then
- begin if cur_chr<>or_code then goto common_ending;
- print_err("Extra "); print_esc("or");
-@.Extra \\or@>
- help1("I'm ignoring this; it doesn't match any \if.");
- error;
- end
- else if cur_chr=fi_code then @<Pop the condition stack@>;
- end
-
-@ @<Either process \.{\\ifcase} or set |b|...@>=
-case this_if of
-if_char_code, if_cat_code: @<Test if two characters match@>;
-if_int_code, if_dim_code: @<Test relation between integers or dimensions@>;
-if_odd_code: @<Test if an integer is odd@>;
-if_vmode_code: b:=(abs(mode)=vmode);
-if_hmode_code: b:=(abs(mode)=hmode);
-if_mmode_code: b:=(abs(mode)=mmode);
-if_inner_code: b:=(mode<0);
-if_void_code, if_hbox_code, if_vbox_code: @<Test box register status@>;
-ifx_code: @<Test if two tokens match@>;
-if_eof_code: begin scan_four_bit_int; b:=(read_open[cur_val]=closed);
- end;
-if_true_code: b:=true;
-if_false_code: b:=false;
-@/@<Cases for |conditional|@>@/
-if_case_code: @<Select the appropriate case
- and |return| or |goto common_ending|@>;
-if_primitive_code: begin
- save_scanner_status:=scanner_status;
- scanner_status:=normal;
- get_filtered_next;
- scanner_status:=save_scanner_status;
- m := prim_lookup(text(cur_cs));
- b :=((cur_cmd<>undefined_cs) and
- (m<>undefined_primitive) and
- (cur_cmd=get_prim_eq_type(m)) and
- (cur_chr=get_prim_equiv(m)));
- end;
-{there are no other cases, but for -Wall: }
-othercases
- b:=false;
-endcases
-
-@ @<Display the value of |b|@>=
-begin begin_diagnostic;
-if b then print("{true}")@+else print("{false}");
-end_diagnostic(false);
-end
-
-@ Here we use the fact that |"<"|, |"="|, and |">"| are consecutive ASCII
-codes.
-@^ASCII code@>
-
-@<Test relation between integers or dimensions@>=
-begin if this_if=if_int_code then scan_int@+else scan_normal_dimen;
-n:=cur_val; @<Get the next non-blank non-call...@>;
-if (cur_tok>=other_token+"<")and(cur_tok<=other_token+">") then
- r:=cur_tok-other_token
-else begin print_err("Missing = inserted for ");
-@.Missing = inserted@>
- print_cmd_chr(if_test,this_if);
- help1("I was expecting to see `<', `=', or `>'. Didn't.");
- back_error; r:="=";
- end;
-if this_if=if_int_code then scan_int@+else scan_normal_dimen;
-case r of
-"<": b:=(n<cur_val);
-"=": b:=(n=cur_val);
-">": b:=(n>cur_val);
-othercases b:=false; {can't happen}
-end;
-end
-
-@ @<Test if an integer is odd@>=
-begin scan_int; b:=odd(cur_val);
-end
-
-@ @<Test box register status@>=
-begin scan_register_num; p:=box(cur_val);
-if this_if=if_void_code then b:=(p=null)
-else if p=null then b:=false
-else if this_if=if_hbox_code then b:=(type(p)=hlist_node)
-else b:=(type(p)=vlist_node);
-end
-
-@ An active character will be treated as category 13 following
-\.{\\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 is_active_csname(cur_cs) then
- begin cur_cmd:=active_char;
- cur_chr:=active_csname_value(cur_tok-cs_token_flag);
- end;
- end
-
-@<Test if two characters match@>=
-begin get_x_token_or_active_char;
-if (cur_cmd>active_char)or(cur_chr>biggest_char) then {not a character}
- begin m:=relax; n:=too_big_char;
- end
-else begin m:=cur_cmd; n:=cur_chr;
- end;
-get_x_token_or_active_char;
-if (cur_cmd>active_char)or(cur_chr>biggest_char) then
- begin cur_cmd:=relax; cur_chr:=too_big_char;
- end;
-if this_if=if_char_code then b:=(n=cur_chr)@+else b:=(m=cur_cmd);
-end
-
-@ Note that `\.{\\ifx}' will declare two macros different if one is \\{long}
-or \\{outer} and the other isn't, even though the texts of the macros are
-the same.
-
-We need to reset |scanner_status|, since \.{\\outer} control sequences
-are allowed, but we might be scanning a macro definition or preamble.
-
-@<Test if two tokens match@>=
-begin save_scanner_status:=scanner_status; scanner_status:=normal;
-get_filtered_next; n:=cur_cs; p:=cur_cmd; q:=cur_chr;
-get_filtered_next; if cur_cmd<>p then b:=false
-else if cur_cmd<call then b:=(cur_chr=q)
-else @<Test if two macro texts match@>;
-scanner_status:=save_scanner_status;
-end
-
-@ Note also that `\.{\\ifx}' decides that macros \.{\\a} and \.{\\b} are
-different in examples like this:
-$$\vbox{\halign{\.{#}\hfil&\qquad\.{#}\hfil\cr
- {}\\def\\a\{\\c\}&
- {}\\def\\c\{\}\cr
- {}\\def\\b\{\\d\}&
- {}\\def\\d\{\}\cr}}$$
-
-@<Test if two macro texts match@>=
-begin p:=link(cur_chr); q:=link(equiv(n)); {omit reference counts}
-if p=q then b:=true
-else begin while (p<>null)and(q<>null) do
- if info(p)<>info(q) then p:=null
- else begin p:=link(p); q:=link(q);
- end;
- b:=((p=null)and(q=null));
- end;
-end
-
-@ @<Select the appropriate case and |return| or |goto common_ending|@>=
-begin scan_int; n:=cur_val; {|n| is the number of cases to pass}
-if tracing_commands>1 then
- begin begin_diagnostic; print("{case "); print_int(n); print_char("}");
- end_diagnostic(false);
- end;
-while n<>0 do
- begin pass_text;
- if cond_ptr=save_cond_ptr then
- if cur_chr=or_code then decr(n)
- else goto common_ending
- else if cur_chr=fi_code then @<Pop the condition stack@>;
- end;
-change_if_limit(or_code,save_cond_ptr);
-return; {wait for \.{\\or}, \.{\\else}, or \.{\\fi}}
-end
-
-@ The processing of conditionals is complete except for the following
-code, which is actually part of |expand|. It comes into play when
-\.{\\or}, \.{\\else}, or \.{\\fi} is scanned.
-
-@<Terminate the current conditional and skip to \.{\\fi}@>=
-begin if tracing_ifs>0 then if tracing_commands<=1 then show_cur_cmd_chr;
-if cur_chr>if_limit then
- if if_limit=if_code then insert_relax {condition not yet evaluated}
- else begin print_err("Extra "); print_cmd_chr(fi_or_else,cur_chr);
-@.Extra \\or@>
-@.Extra \\else@>
-@.Extra \\fi@>
- help1("I'm ignoring this; it doesn't match any \if.");
- error;
- end
-else begin while cur_chr<>fi_code do pass_text; {skip to \.{\\fi}}
- @<Pop the condition stack@>;
- end;
-end
-
-@* \[29] File names.
-It's time now to fret about file names. Besides the fact that different
-operating systems treat files in different ways, we must cope with the
-fact that completely different naming conventions are used by different
-groups of people. The following programs show what is required for one
-particular operating system; similar routines for other systems are not
-difficult to devise.
-@^fingers@>
-@^system dependencies@>
-
-\TeX\ assumes that a file name has three parts: the name proper; its
-``extension''; and a ``file area'' where it is found in an external file
-system. The extension of an input file or a write file is assumed to be
-`\.{.tex}' unless otherwise specified; it is `\.{.log}' on the
-transcript file that records each run of \TeX; it is `\.{.tfm}' on the font
-metric files that describe characters in the fonts \TeX\ uses; it is
-`\.{.dvi}' on the output files that specify typesetting information; and it
-is `\.{.fmt}' on the format files written by \.{INITEX} to initialize \TeX.
-The file area can be arbitrary on input files, but files are usually
-output to the user's current area. If an input file cannot be
-found on the specified area, \TeX\ will look for it on a special system
-area; this special area is intended for commonly used input files like
-\.{webmac.tex}.
-
-Simple uses of \TeX\ refer only to file names that have no explicit
-extension or area. For example, a person usually says `\.{\\input} \.{paper}'
-or `\.{\\font\\tenrm} \.= \.{helvetica}' instead of `\.{\\input}
-\.{paper.new}' or `\.{\\font\\tenrm} \.= \.{<csd.knuth>test}'. Simple file
-names are best, because they make the \TeX\ source files portable;
-whenever a file name consists entirely of letters and digits, it should be
-treated in the same way by all implementations of \TeX. However, users
-need the ability to refer to other files in their environment, especially
-when responding to error messages concerning unopenable files; therefore
-we want to let them use the syntax that appears in their favorite
-operating system.
-
-The following procedures don't allow spaces to be part of
-file names; but some users seem to like names that are spaced-out.
-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.
-
-@ Here are the global values that file names will be scanned into.
-
-@<Glob...@>=
-@!cur_name:str_number; {name of file just scanned}
-@!cur_area:str_number; {file area just scanned, or \.{""}}
-@!cur_ext:str_number; {file extension just scanned, or \.{""}}
-
-@ The file names we shall deal with for illustrative purposes have the
-following structure: If the name contains `\.>' or `\.:', the file area
-consists of all characters up to and including the final such character;
-otherwise the file area is null. If the remaining file name contains
-`\..', the file extension consists of all such characters from the first
-remaining `\..' to the end, otherwise the file extension is null.
-@^system dependencies@>
-
-We can scan such file names easily by using two global variables that keep track
-of the occurrences of area and extension delimiters:
-
-@<Glob...@>=
-@!area_delimiter:pool_pointer; {the most recent `\.>' or `\.:', if any}
-@!ext_delimiter:pool_pointer; {the relevant `\..', if any}
-
-@ Input files that can't be found in the user's area may appear in a standard
-system area called |TEX_area|. Font metric files whose areas are not given
-explicitly are assumed to appear in a standard system area called
-|TEX_font_area|. $\Omega$'s compiled translation process files whose areas
-are not given explicitly are assumed to appear in a standard system area
-called |OMEGA_ocp_area|. These system area names will, of course, vary
-from place to place.
-@^system dependencies@>
-
-@d TEX_area=="TeXinputs:"
-@.TeXinputs@>
-@d TEX_font_area=="TeXfonts:"
-@.TeXfonts@>
-@d OMEGA_ocp_area=="OmegaOCPs:"
-@.OmegaOCPs@>
-
-@ 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
-allows both lowercase and uppercase letters in the file name.
-@^system dependencies@>
-
-@d append_to_name(#)==begin c:=#; incr(k);
- if k<=file_name_size then nameoffile[k]:=xchr[c];
- end
-
-@p procedure pack_file_name(@!n,@!a,@!e:str_number);
-var k:integer; {number of positions filled in |nameoffile|}
-@!c: ASCII_code; {character being packed}
-@!j:pool_pointer; {index into |str_pool|}
-begin k:=0;
-for j:=str_start_macro(a) to str_start_macro(a+1)-1 do append_to_name(so(str_pool[j]));
-for j:=str_start_macro(n) to str_start_macro(n+1)-1 do append_to_name(so(str_pool[j]));
-for j:=str_start_macro(e) to str_start_macro(e+1)-1 do append_to_name(so(str_pool[j]));
-if k<=file_name_size then namelength:=k@+else namelength:=file_name_size;
-for k:=namelength+1 to file_name_size do nameoffile[k]:=' ';
-end;
-
-@ A messier routine is also needed, since format file names must be scanned
-before \TeX's string mechanism has been initialized. We shall use the
-global variable |TEX_format_default| to supply the text for default system areas
-and extensions related to format files.
-@^system dependencies@>
-
-@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}
-
-@<Glob...@>=
-@!TEX_format_default:packed array[1..format_default_length] of char;
-
-@ @<Set init...@>=
-TEX_format_default:='TeXformats:plain.fmt';
-@.TeXformats@>
-@.plain@>
-@^system dependencies@>
-
-@ @<Check the ``constant'' values for consistency@>=
-if format_default_length>file_name_size then bad:=31;
-
-@ Here is the messy routine that was just mentioned. It sets |nameoffile|
-from the first |n| characters of |TEX_format_default|, followed by
-|buffer[a..b]|, followed by the last |format_ext_length| characters of
-|TEX_format_default|.
-
-We dare not give error messages here, since \TeX\ calls this routine before
-the |error| routine is ready to roll. Instead, we simply drop excess characters,
-since the error will be detected in another way when a strange file name
-isn't found.
-@^system dependencies@>
-
-@p procedure pack_buffered_name(@!n:integer;@!a,@!b:integer);
-var k:integer; {number of positions filled in |nameoffile|}
-@!c: ASCII_code; {character being packed}
-@!j:integer; {index into |buffer| or |TEX_format_default|}
-begin if n+b-a+1+format_ext_length>file_name_size then
- b:=a+file_name_size-n-1-format_ext_length;
-k:=0;
-for j:=1 to n do append_to_name(TEX_format_default[j]);
-for j:=a to b do append_to_name(buffer[j]);
-for j:=format_default_length-format_ext_length+1 to format_default_length do
- append_to_name(TEX_format_default[j]);
-if k<=file_name_size then namelength:=k@+else namelength:=file_name_size;
-for k:=namelength+1 to file_name_size do nameoffile[k]:=' ';
-end;
-
-@ Here is the only place we use |pack_buffered_name|. This part of the program
-becomes active when a ``virgin'' \TeX\ is trying to get going, just after
-the preliminary initialization, or when the user is substituting another
-format file by typing `\.\&' after the initial `\.{**}' prompt. The buffer
-contains the first line of input in |buffer[loc..(last-1)]|, where
-|loc<last| and |buffer[loc]<>" "|.
-
-@<Declare the function called |open_fmt_file|@>=
-function open_fmt_file:boolean;
-label found,exit;
-var j:0..buf_size; {the first space after the format file name}
-begin j:=loc;
-if buffer[loc]="&" then
- begin incr(loc); j:=loc; buffer[last]:=" ";
- while buffer[j]<>" " do incr(j);
- pack_buffered_name(0,loc,j-1); {try first without the system file area}
- if w_open_in(fmt_file) then goto found;
- pack_buffered_name(format_area_length,loc,j-1);
- {now try the system format file area}
- if w_open_in(fmt_file) then goto found;
- wake_up_terminal;
- wterm_ln('Sorry, I can''t find that format;',' will try PLAIN.');
-@.Sorry, I can't find...@>
- update_terminal;
- end;
- {now pull out all the stops: try for the system \.{plain} file}
-pack_buffered_name(format_default_length-format_ext_length,1,0);
-if not w_open_in(fmt_file) then
- begin wake_up_terminal;
- wterm_ln('I can''t find the PLAIN format file!');
-@.I can't find PLAIN...@>
-@.plain@>
- open_fmt_file:=false; return;
- end;
-found:loc:=j; open_fmt_file:=true;
-exit:end;
-
-@ Operating systems often make it possible to determine the exact name (and
-possible version number) of a file that has been opened. The following routine,
-which simply makes a \TeX\ string from the value of |nameoffile|, should
-ideally be changed to deduce the full name of file~|f|, which is the file
-most recently opened, if it is possible to do this in a \PASCAL\ program.
-@^system dependencies@>
-
-This routine might be called after string memory has overflowed, hence
-we dare not use `|str_room|'.
-
-@d a_make_name_string(#)==make_name_string
-@d b_make_name_string(#)==make_name_string
-@d w_make_name_string(#)==make_name_string
-
-
-@ The global variable |name_in_progress| is used to prevent recursive
-use of |scan_file_name|, since the |begin_name| and other procedures
-communicate via global variables. Recursion would arise only by
-devious tricks like `\.{\\input\\input f}'; such attempts at sabotage
-must be thwarted. Furthermore, |name_in_progress| prevents \.{\\input}
-@^recursion@>
-from being initiated when a font size specification is being scanned.
-
-Another global variable, |job_name|, contains the file name that was first
-\.{\\input} by the user. This name is extended by `\.{.log}' and `\.{.dvi}'
-and `\.{.fmt}' in the names of \TeX's output files.
-
-@<Glob...@>=
-@!name_in_progress:boolean; {is a file name being scanned?}
-@!job_name:str_number; {principal file name}
-@!log_opened:boolean; {has the transcript file been opened?}
-
-@ Initially |job_name=0|; it becomes nonzero as soon as the true name is known.
-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.
-
-@d pack_cur_name==pack_file_name(cur_name,cur_area,cur_ext)
-
-@<Initialize the output...@>=
-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');
- while not lua_b_open_out(dvi_file) do
- prompt_file_name('file name for output','.dvi');
- dvi_file:=name_file_pointer ;
- output_file_name:=b_make_name_string(dvi_file);
- end
-
-@<Glob...@>=
-@!dvi_file: byte_file; {the device-independent output goes here}
-@!output_file_name: str_number; {full name of the output file}
-@!log_name:str_number; {full name of the log file}
-
-@ @<Initialize the output...@>=output_file_name:=0;
-
-@ The |open_log_file| routine is used to open the transcript file and to help
-it catch up to what has previously been printed on the terminal.
-
-@p procedure open_log_file;
-var old_setting:0..max_selector; {previous |selector| setting}
-@!k:0..buf_size; {index into |months| and |buffer|}
-@!l:0..buf_size; {end of first input line}
-@!months:packed array [1..36] of char; {abbreviations of month names}
-begin old_setting:=selector;
-if job_name=0 then job_name:="texput";
-@.texput@>
-pack_job_name('.log');
-while not lua_a_open_out(addressof(log_file),0) do @<Try to get a different log file name@>;
-log_file := name_file_pointer;
-log_name:=a_make_name_string(log_file);
-selector:=log_only; log_opened:=true;
-if callback_defined(start_run_callback)=0 then begin
- @<Print the banner line, including the date and time@>;
- input_stack[input_ptr]:=cur_input; {make sure bottom level is in memory}
- print_nl("**");
-@.**@>
- l:=input_stack[0].limit_field; {last position of first line}
- if buffer[l]=end_line_char then decr(l); { TODO: multichar endlinechar}
- for k:=1 to l do print_char(buffer[k]);
- print_ln; {now the transcript file contains the first line of input}
- end;
-flush_loggable_info; {should be done always}
-selector:=old_setting+2; {|log_only| or |term_and_log|}
-end;
-
-@ Sometimes |open_log_file| is called at awkward moments when \TeX\ is
-unable to print error messages or even to |show_context|.
-The |prompt_file_name| routine can result in a |fatal_error|, but the |error|
-routine will not be invoked because |log_opened| will be false.
-
-The normal idea of |batch_mode| is that nothing at all should be written
-on the terminal. However, in the unusual case that
-no log file could be opened, we make an exception and allow
-an explanatory message to be seen.
-
-Incidentally, the program always refers to the log file as a `\.{transcript
-file}', because some systems cannot use the extension `\.{.log}' for
-this file.
-
-@<Try to get a different log file name@>=
-begin selector:=term_only;
-prompt_file_name('transcript file name','.log');
-end
-
-@ @<Print the banner...@>=
-begin wlog(banner);
-slow_print(format_ident); print(" ");
-print_int(day); print_char(" ");
-months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC';
-for k:=3*month-2 to 3*month do wlog(months[k]);
-print_char(" "); print_int(year); print_char(" ");
-print_two(time div 60); print_char(":"); print_two(time mod 60);
-end
-
-@ Let's turn now to the procedure that is used to initiate file reading
-when an `\.{\\input}' command is being processed.
-
-@p procedure start_input; {\TeX\ will \.{\\input} something}
-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";|}
-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');
- end;
-done:
-cur_file := name_file_pointer;
-name:=a_make_name_string(cur_file);
-if job_name=0 then
- begin job_name:=cur_name; open_log_file;
- end; {|open_log_file| doesn't |show_context|, so |limit|
- and |loc| needn't be set to meaningful values yet}
-if tracefilenames then begin
- if term_offset+length(name)>max_print_line-2 then print_ln
- else if (term_offset>0)or(file_offset>0) then print_char(" ");
- print_char("(");
- print_file_name(0,name,0);
-end;
-incr(open_parens);
-update_terminal;
-state:=new_line;
-if name=str_ptr-1 then {we can conserve string pool space now}
- begin flush_string; name:=cur_name;
- end;
-@<Prepare new file {\sl Sync\TeX} information@>;
-@<Read the first line of the new file@>;
-end;
-
-@ Here we have to remember to tell the |lua_input_ln| routine not to
-start with a |get|. If the file is empty, it is considered to
-contain a single blank line.
-@^system dependencies@>
-@^empty line at end of file@>
-
-@<Read the first line...@>=
-begin line:=1;
-if lua_input_ln(cur_file,0,false) then do_nothing;
-firm_up_the_line;
-if end_line_char_inactive then decr(limit)
-else buffer[limit]:=end_line_char;
-first:=limit+1; loc:=start;
-end
-
-@* \[30] Font metric data and OCPS.
-\TeX\ gets its knowledge about fonts from font metric files, also called
-\.{TFM} files; the `\.T' in `\.{TFM}' stands for \TeX,
-but other programs know about them too.
-@:TFM files}{\.{TFM} files@>
-@^font metric files@>
-
-@ When the user defines \.{\\font\\f}, say, \TeX\ assigns an internal number
-to the user's font~\.{\\f}. Adding this number to |font_id_base| gives the
-|eqtb| location of a ``frozen'' control sequence that will always select
-the font.
-
-@<Types...@>=
-@!internal_font_number=integer; {|font| in a |char_node|}
-@!font_index=integer; {index into |font_info|}
-
-@ @<Glob...@>=
-@!font_bytes:integer;
-
-@ \TeX\ always knows at least one font, namely the null font. It has no
-characters, and its seven parameters are all equal to zero.
-
-@<Initialize table...@>=
-create_null_font;
-font_bytes:=0;
-
-@ @<Put each...@>=
-primitive_tex("nullfont",set_font,null_font,0);
-@!@:null_font_}{\.{\\nullfont} primitive@>
-text(frozen_null_font):="nullfont"; eqtb[frozen_null_font]:=eqtb[cur_val];
-
-@ @<The em width for |cur_font|@>=quad(cur_font)
-
-@ @<The x-height for |cur_font|@>=x_height(cur_font)
-
-@ Before we forget about the format of these tables, let's deal with two
-of \TeX's basic scanning routines related to font information.
-
-@<Declare procedures that scan font-related stuff@>=
-procedure scan_font_ident;
-var f:internal_font_number;
-@!m:halfword;
-begin @<Get the next non-blank non-call...@>;
-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:=fam_fnt(cur_val,m);
- set_font_touched(f,1);
- end
-else begin print_err("Missing font identifier");
-@.Missing font identifier@>
- help2("I was looking for a control sequence whose")@/
- ("current meaning has been defined by \font.");
- back_error; f:=null_font;
- end;
-cur_val:=f;
-end;
-
-@ The following routine is used to implement `\.{\\fontdimen} |n| |f|'.
-The boolean parameter |writing| is set |true| if the calling program
-intends to change the parameter value.
-
-@<Declare procedures that scan font-related stuff@>=
-procedure set_font_dimen;forward;
-procedure get_font_dimen;forward;
-
-@ @p
-procedure set_font_dimen;
-label exit;
-var f:internal_font_number;
-@!n:integer; {the parameter number}
-begin scan_int; n:=cur_val; scan_font_ident; f:=cur_val;
- if n<=0 then
- @<Issue a font parameter error message, and return@>
- else begin
- if n>font_params(f) then begin
- if font_touched(f) then @<Issue a font parameter error message, and return@>
- else @<Increase the number of parameters in the font@>;
- end;
- end;
- scan_optional_equals; scan_normal_dimen;
- set_font_param(f,n,cur_val);
-exit:
-end;
-@#
-procedure get_font_dimen;
-label exit;
-var f:internal_font_number;
-@!n:integer; {the parameter number}
-begin scan_int; n:=cur_val; scan_font_ident; f:=cur_val;
- cur_val:=0; { initialize return value }
- if n<=0 then
- @<Issue a font parameter error message, and return@>
- else begin
- if n>font_params(f) then begin
- if font_touched(f) then @<Issue a font parameter error message, and return@>
- else @<Increase the number of parameters in the font@>;
- end;
- end;
- cur_val:=font_param(f,n);
-exit:
- scanned_result(cur_val)(dimen_val);
-end;
-
-@ @<Issue a font parameter error message, and return@>=
-begin print_err("Font "); print_esc(font_id_text(f));
- print(" has only "); print_int(font_params(f));
- print(" fontdimen parameters");
-@.Font x has only...@>
- help2("To increase the number of font parameters, you must")@/
- ("use \fontdimen immediately after the \font is loaded.");
- error;
- return;
-end
-
-@ @<Increase the number of parameters...@>=
-begin repeat
- set_font_param(f,(font_params(f)+1),0);
-until n=font_params(f);
-end
-
-
-@ When \TeX\ wants to typeset a character that doesn't exist, the
-character node is not created; thus the output routine can assume
-that characters exist when it sees them. The following procedure
-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(" (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;
- tracing_online:=old_setting;
- end;
-end;
-
-@
-@<Types...@>=
-@!active_index=0..active_mem_size;
-
-@
-@d active_ocp(#)==active_info[#].hh.b0
-@d active_counter(#)==active_info[#].hh.b1
-@d active_lstack_no(#)==active_info[#+1].sc
-
-@<Glob...@>=
-@!active_info:array[active_index] of memory_word;
-@!active_min_ptr:active_index; {first unused word of |active_info|}
-@!active_max_ptr:active_index; {last unused word of |active_info|}
-@!active_real:active_index;
-@!holding:array[active_index] of ocp_list_index;
-
-@
-@<Initialize table...@>=
-active_min_ptr:=0;
-active_real:=0;
-
-@
-@p
-function is_last_ocp(llstack_no:scaled; counter:integer):integer;
-begin
-active_min_ptr:=equiv(ocp_active_min_ptr_base);
-active_max_ptr:=equiv(ocp_active_max_ptr_base);
-active_real:=active_min_ptr;
-while (active_real < active_max_ptr) and
- (active_lstack_no(active_real) < llstack_no) do begin
- active_real:=active_real+2;
- end;
-while (active_real < active_max_ptr) and
- (active_lstack_no(active_real) = llstack_no) and
- (active_counter(active_real) <= counter) do begin
- active_real:=active_real+2;
- end;
-is_last_ocp := (active_real=active_max_ptr);
-end;
-
-procedure print_active_ocps;
-var i:integer;
-begin
-print_nl("Active ocps: [");
-i:=active_min_ptr;
-while i<active_max_ptr do begin
- print("(");
- print_scaled(active_lstack_no(i));
- print(",");
- print_int(active_counter(i));
- print(",");
- print_esc(ocp_id_text(active_ocp(i)));
- print(")");
- if i<>(active_max_ptr-2) then print(",");
- i:=i+2;
- end;
-print("]");
-end;
-
-procedure add_ocp_stack(min_index:integer; min_value:scaled);
-var p:ocp_lstack_index;
- llstack_no:scaled;
- counter:integer;
- m:scaled;
-begin
-m:=min_value; { TH: whatever this is ..}
-p:=ocp_list_lstack(holding[min_index]);
-llstack_no:=ocp_list_lstack_no(holding[min_index]);
-counter:=0;
-while not (is_null_ocp_lstack(p)) do begin
- active_ocp(active_max_ptr):=ocp_lstack_ocp(p);
- active_counter(active_max_ptr):=counter;
- active_lstack_no(active_max_ptr):=llstack_no;
- p:=ocp_lstack_lnext(p);
- active_max_ptr:=active_max_ptr+2;
- incr(counter); {no overflow problem}
- end;
-end;
-
-procedure active_compile;
-var i:integer;
- min_index:integer;
- min_stack_ocp:scaled;
- old_min:scaled;
- max_active:integer;
- stack_value:scaled;
-begin
-active_min_ptr:=active_max_ptr;
-min_stack_ocp:=ocp_maxint;
-max_active:=equiv(ocp_active_number_base)-1;
-min_index:=max_active; {TH I hope ... }
-for i:=max_active downto 0 do begin
- holding[i]:=ocp_list_list[equiv(ocp_active_base+i)];
- stack_value:=ocp_list_lstack_no(holding[i]);
- if stack_value<min_stack_ocp then begin
- min_index:=i;
- min_stack_ocp:=stack_value;
- end;
- end;
-while min_stack_ocp<ocp_maxint do begin
- add_ocp_stack(min_index, min_stack_ocp);
- old_min:=min_stack_ocp;
- min_stack_ocp:=ocp_maxint;
- for i:=max_active downto 0 do begin
- stack_value:=ocp_list_lstack_no(holding[i]);
- while old_min=stack_value do begin
- holding[i]:=ocp_list_lnext(holding[i]);
- stack_value:=ocp_list_lstack_no(holding[i]);
- end;
- if stack_value<min_stack_ocp then begin
- min_index:=i;
- min_stack_ocp:=stack_value;
- end;
- end;
- end;
-end;
-
-@ Here we begin the \.{OCP} file handling.
-
-@<Glob...@>=
-@!ocp_file:byte_file;
-
-@ So that is what \.{OCP} files hold.
-
-When the user defines \.{\\ocp\\f}, say, \TeX\ assigns an internal number
-to the user's ocp~\.{\\f}. Adding this number to |ocp_id_base| gives the
-|eqtb| location of a ``frozen'' control sequence that will always select
-the ocp.
-
-@<Types...@>=
-@!internal_ocp_number=ocp_base..ocp_biggest;
-@!ocp_index=integer;
-
-@ Here now is the array of ocp arrays.
-
-@<Glob...@>=
-@!ocp_ptr:internal_ocp_number; {largest internal ocp number in use}
-@!ocp_buffer:^real_eight_bits; {byte buffer for ocp files}
-@!ocp_size:integer; {total size of the ocp file}
-@!ocp_cur:integer; {index into |ocp_buffer|}
-
-@ @<Set init...@>=
-ocp_buffer:=0; ocp_size:=0; ocp_cur:=0;
-
-@ Besides the arrays just enumerated, we have two directory arrays that
-make it easy to get at the individual entries in |ocp_info|.
-The beginning of the info for the |j|-th state in the |i|-th ocp is at
-location |ocp_info[ocp_state_base[i]+j]| and the |k|-th entry is in
-location |ocp_info[ocp_info[ocp_state_base[i]+j]+k]|.
-(These formulas assume that |min_quarterword| has already been
-added to |i|, |j| and |k|, since $\Omega$ stores its quarterwords that way.)
-
-@d ocp_info_end(#)==#]
-@d ocp_info(#)==ocp_tables[#,ocp_info_end
-@d offset_ocp_file_size=0
-@d offset_ocp_name=1
-@d offset_ocp_area=offset_ocp_name+1
-@d offset_ocp_external=offset_ocp_area+1
-@d offset_ocp_external_arg=offset_ocp_external+1
-@d offset_ocp_input=offset_ocp_external_arg+1
-@d offset_ocp_output=offset_ocp_input+1
-@d offset_ocp_no_tables=offset_ocp_output+1
-@d offset_ocp_no_states=offset_ocp_no_tables+1
-@d offset_ocp_table_base=offset_ocp_no_states+1
-@d offset_ocp_state_base=offset_ocp_table_base+1
-@d offset_ocp_info=offset_ocp_state_base+1
-@d ocp_file_size(#)==ocp_info(#)(offset_ocp_file_size)
-@d ocp_name(#)==ocp_info(#)(offset_ocp_name)
-@d ocp_area(#)==ocp_info(#)(offset_ocp_area)
-@d ocp_external(#)==ocp_info(#)(offset_ocp_external)
-@d ocp_external_arg(#)==ocp_info(#)(offset_ocp_external_arg)
-@d ocp_input(#)==ocp_info(#)(offset_ocp_input)
-@d ocp_output(#)==ocp_info(#)(offset_ocp_output)
-@d ocp_no_tables(#)==ocp_info(#)(offset_ocp_no_tables)
-@d ocp_no_states(#)==ocp_info(#)(offset_ocp_no_states)
-@d ocp_table_base(#)==ocp_info(#)(offset_ocp_table_base)
-@d ocp_state_base(#)==ocp_info(#)(offset_ocp_state_base)
-
-@ $\Omega$ always knows at least one ocp, namely the null ocp.
-It does nothing.
-
-@<Initialize table...@>=
-ocp_ptr:=null_ocp;
-allocate_ocp_table(null_ocp,17);
-ocp_file_size(null_ocp):=17;
-ocp_name(null_ocp):="nullocp"; ocp_area(null_ocp):="";
-ocp_external(null_ocp):=0; ocp_external_arg(null_ocp):=0;
-ocp_input(null_ocp):=1; ocp_output(null_ocp):=1;
-ocp_no_tables(null_ocp):=0;
-ocp_no_states(null_ocp):=1;
-ocp_table_base(f):=offset_ocp_info;
-ocp_state_base(f):=offset_ocp_info;
-ocp_info(null_ocp)(offset_ocp_info) := offset_ocp_info+2; {number of entries}
-ocp_info(null_ocp)(offset_ocp_info+1) := offset_ocp_info+5; {number of entries}
-ocp_info(null_ocp)(offset_ocp_info+2) := 23; {|OTP_LEFT_START|}
-ocp_info(null_ocp)(offset_ocp_info+3) := 3; {|OTP_RIGHT_CHAR|}
-ocp_info(null_ocp)(offset_ocp_info+4) := 36; {|OTP_STOP|}
-
-
-@ @<Put each...@>=
-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);
-geq_define(ocp_active_min_ptr_base, data, 0);
-geq_define(ocp_active_max_ptr_base, data, 0);
-
-@ Of course we want to define macros that suppress the detail of how ocp
-information is actually packed, so that we don't have to write things like
-$$\hbox{|ocp_info[k+ocp_info[j+ocp_state_base[i]]]|}$$
-too often. The \.{WEB} definitions here make |ocp_state_entry(i)(j)(k)|
-(|ocp_table_entry(i)(j)(k)|) the |k|-th word in the |j|-th state (table)
-of the |i|-th ocp.
-@^inner loop@>
-
-@d ocp_state_end(#)==#]
-@d ocp_state_one(#)==#*2]+ocp_state_end
-@d ocp_state_entry(#)==ocp_tables[#,ocp_tables[#,ocp_state_base(#)+ocp_state_one
-
-@d ocp_state_no_end(#)==#*2+1]
-@d ocp_state_no(#)==ocp_tables[#,ocp_state_base(#)+ocp_state_no_end
-
-@d ocp_table_end(#)==#]
-@d ocp_table_one(#)==#*2]+ocp_table_end
-@d ocp_table_entry(#)==ocp_tables[#,ocp_tables[#,ocp_table_base(#)+ocp_table_one
-
-@d ocp_table_no_end(#)==#*2+1]
-@d ocp_table_no(#)==ocp_tables[#,ocp_table_base(#)+ocp_table_no_end
-
-@ $\Omega$ checks the information of a \.{OCP} 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
-is called |read_ocp_info|. It has three parameters: the user ocp
-identifier~|u|, and the file name and area strings |nom| and |aire|.
-
-The subroutine opens and closes a global file variable called |ocp_file|.
-It returns the value of the internal ocp number that was just loaded.
-If an error is detected, an error message is issued and no ocp
-information is stored; |null_ocp| is returned in this case.
-
-@d bad_ocp=11 {label for |read_ocp_info|}
-@d ocp_abort(#)==begin print("OCP file error (");
- print(#); print(")"); print_ln; goto bad_ocp end
- {do this when the \.{OCP} data is wrong}
-
-@p function read_ocp_info(@!u:pointer;@!nom,@!aire,@!ext:str_number;
- @!external_ocp:boolean)
- :internal_ocp_number; {input a \.{OCP} file}
-label done,bad_ocp,not_found;
-var
-@!file_opened:boolean; {was |ocp_file| successfully opened?}
-@!k:integer;
-@!res:boolean;
-@!callback_id:integer;
-@!fnam:str_number;
-@!f:internal_ocp_number; {the new ocp's number}
-@!g:internal_ocp_number; {the number to return}
-@!ocpword:integer;
-@!ocpmem_run_ptr:ocp_index;
-@!ocp_length,real_ocp_length:integer; {length of ocp file}
-@!previous_address:ocp_index;
-@!temp_ocp_input:integer;
-@!temp_ocp_output:integer;
-@!temp_ocp_no_tables:integer;
-@!temp_ocp_no_states:integer;
-@!i,new_offset,room_for_tables,room_for_states:integer;
-begin g:=null_ocp; f:=null_ocp;@/
-@<Read and check the ocp data; |ocp_abort| if the \.{OCP} file is
- malformed; if there's no room for this ocp, say so and |goto
- done|; otherwise |incr(ocp_ptr)| and |goto done|@>;
-bad_ocp: @<Report that the ocp won't be loaded@>;
-done:
-ocp_name(f):=nom; ocp_area(f):=aire;
-read_ocp_info:=g;
-end;
-
-@ $\Omega$ does not give precise details about why it
-rejects a particular \.{OCP} file.
-
-@d start_ocp_error_message==print_err("Translation process ");
- sprint_cs(u); print_char("="); print_file_name(nom,aire,"");
-
-@<Report that the ocp won't be loaded@>=
-start_ocp_error_message;
-@.Translation process x=xx not loadable...@>
-if file_opened then print(" not loadable: Bad ocp file")
-else print(" not loadable: ocp file not found");
-help2("I wasn't able to read the data for this ocp,")@/
-("so I will ignore the ocp specification.");
-error
-
-@ @<Read and check the ocp data...@>=
-if external_ocp then
- @<Check |ocp_file| exists@>
-else begin
- @<Open |ocp_file| for input@>;
- @<Read the {\.{OCP}} file@>;
- end;
-
-@ @<Check |ocp_file| exists@>=
-begin
-file_opened:=false;
-pack_file_name(nom,aire,ext);
-b_test_in;
-if namelength=0 then ocp_abort("opening file");
-f :=ocp_ptr+1;
-allocate_ocp_table(f,13);
-ocp_file_size(f):=13;
-for i:=1 to namelength do begin
- append_char(nameoffile[i]);
- end;
-ocp_external(f):=make_string;
-scan_string_argument;
-ocp_external_arg(f):=cur_val;
-ocp_name(f):=""; ocp_area(f):="";
-ocp_state_base(f):=0; ocp_table_base(f):=0;
-ocp_input(f):=1; ocp_output(f):=1;
-ocp_info(f)(offset_ocp_info):=0;
-ocp_ptr:=f; g:=f;
-goto done;
-end
-
-@ @<Open |ocp_file| for input@>=
-file_opened:=false;
-pack_file_name(nom,aire,".ocp");
-if ocp_buffer<>0 then libcfree(ocp_buffer);
-ocp_cur:=0; ocp_buffer:=0; ocp_size:=0;
-callback_id:=callback_defined(find_ocp_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
- @<Fixup |nameoffile| after callback@>;
- end;
- end;
-callback_id:=callback_defined(read_ocp_file_callback);
-if callback_id>0 then begin
- res := run_callback(callback_id,'S->bSd',stringcast(nameoffile+1),
- addressof(file_opened), addressof(ocp_buffer),addressof(ocp_size));
- if not res then ocp_abort("callback error");
- if not file_opened then ocp_abort("opening file");
- if not ocp_size then ocp_abort("checking size");
- end
-else begin
- if not ocp_open_in(ocp_file) then ocp_abort("opening file");
- file_opened:=true;
- res := read_ocp_file(ocp_file,addressof(ocp_buffer),addressof(ocp_size));
- b_close(ocp_file);
- if not ocp_size then ocp_abort("checking size");
- if not res then ocp_abort("reading file");
-end
-
-
-@ Note: A malformed \.{OCP} file might be shorter than it claims to be;
-thus |eof(ocp_file)| might be true when |read_ocp_info| refers to
-|ocp_file^| or when it says |get(ocp_file)|. If such circumstances
-cause system error messages, you will have to defeat them somehow,
-for example by defining |ocpget| to be `\ignorespaces|begin get(ocp_file);|
-|if eof(ocp_file) then ocp_abort; end|\unskip'.
-@^system dependencies@>
-
-@d add_to_ocp_info(#)==begin ocp_tables[f,ocpmem_run_ptr]:=#;
- incr(ocpmem_run_ptr);
- end
-@d ocpget==incr(ocp_cur)
-@d ocpbyte==ocp_buffer[ocp_cur]
-@d ocp_read(#)==begin ocpword:=ocpbyte;
- if ocpword>127 then ocp_abort("checking first octet");
- ocpget; ocpword:=ocpword*@'400+ocpbyte;
- ocpget; ocpword:=ocpword*@'400+ocpbyte;
- ocpget; ocpword:=ocpword*@'400+ocpbyte;
- #:=ocpword;
- end
-@d ocp_read_all(#)==begin ocpget; ocp_read(#); end
-@d ocp_read_info==begin ocp_read_all(ocpword);
- add_to_ocp_info(ocpword);
- end
-
-@ @<Read the {\.{OCP}} file@>=
-begin
-f :=ocp_ptr+1;
-ocpmem_run_ptr:=offset_ocp_info;
-ocp_read(ocp_length);
-real_ocp_length:=ocp_length-7;
-ocp_read_all(temp_ocp_input);
-ocp_read_all(temp_ocp_output);
-ocp_read_all(temp_ocp_no_tables);
-ocp_read_all(room_for_tables);
-ocp_read_all(temp_ocp_no_states);
-ocp_read_all(room_for_states);
-if real_ocp_length <>
- (temp_ocp_no_tables + room_for_tables +
- temp_ocp_no_states + room_for_states) then
- ocp_abort("checking size");
-real_ocp_length:=real_ocp_length+12+
- temp_ocp_no_states+temp_ocp_no_tables;
-allocate_ocp_table(f,real_ocp_length);
-ocp_external(f):=0;
-ocp_external_arg(f):=0;
-ocp_file_size(f):=real_ocp_length;
-ocp_input(f):=temp_ocp_input;
-ocp_output(f):=temp_ocp_output;
-ocp_no_tables(f):=temp_ocp_no_tables;
-ocp_no_states(f):=temp_ocp_no_states;
-ocp_table_base(f):=ocpmem_run_ptr;
-if ocp_no_tables(f) <> 0 then begin
- previous_address:=ocpmem_run_ptr+2*(ocp_no_tables(f));
- for i:=1 to ocp_no_tables(f) do begin
- add_to_ocp_info(previous_address);
- ocp_read_all(new_offset);
- add_to_ocp_info(new_offset);
- previous_address:=previous_address+new_offset;
- end
- end;
-if room_for_tables <> 0 then begin
- for i:=1 to room_for_tables do begin
- ocp_read_info;
- end
- end;
-ocp_state_base(f):=ocpmem_run_ptr;
-if ocp_no_states(f) <> 0 then begin
- previous_address:=ocpmem_run_ptr+2*(ocp_no_states(f));
- for i:=1 to ocp_no_states(f) do begin
- add_to_ocp_info(previous_address);
- ocp_read_all(new_offset);
- add_to_ocp_info(new_offset);
- previous_address:=previous_address+new_offset;
- end;
- end;
-if room_for_states <> 0 then begin
- for i:=1 to room_for_states do begin
- ocp_read_info;
- end
- end;
-ocp_ptr:=f; g:=f;
-goto done;
-end
-
-@ Before we forget about the format of these tables, let's deal with
-$\Omega$'s basic scanning routine related to ocp information.
-
-@<Declare procedures that scan ocp-related stuff@>=
-procedure scan_ocp_ident;
-var f:internal_ocp_number;
-begin @<Get the next non-blank non-call...@>;
-if cur_cmd=set_ocp then f:=cur_chr
-else begin print_err("Missing ocp identifier");
-@.Missing ocp identifier@>
- help2("I was looking for a control sequence whose")@/
- ("current meaning has been defined by \ocp.");
- back_error; f:=null_ocp;
- end;
-cur_val:=f;
-end;
-
-
-@ Here we begin the \.{OCP} list handling.
-
-
-@<Types...@>=
-@!internal_ocp_list_number=ocp_list_base..ocp_list_biggest;
-@!ocp_list_index=integer; {index into |ocp_list_info|}
-@!ocp_lstack_index=integer; {index into |ocp_lstack_info|}
-
-@ Here now is the array of ocp arrays.
-@d ocp_list_lnext(#)==ocp_list_info[#].hh.b0
-@d ocp_list_lstack(#)==ocp_list_info[#].hh.b1
-@d ocp_list_lstack_no(#)==ocp_list_info[#+1].sc
-@d ocp_lstack_lnext(#)==ocp_lstack_info[#].hh.b0
-@d ocp_lstack_ocp(#)==ocp_lstack_info[#].hh.b1
-@d make_null_ocp_list==make_ocp_list_node(0,ocp_maxint,0)
-@d is_null_ocp_list(#)==ocp_list_lstack_no(#)=ocp_maxint
-@d make_null_ocp_lstack==0
-@d is_null_ocp_lstack(#)==#=0
-@d add_before_op=1
-@d add_after_op=2
-@d remove_before_op=3
-@d remove_after_op=4
-
-@<Glob...@>=
-@!ocp_list_info:array[ocp_list_index] of memory_word;
- {the big collection of ocp list data}
-@!ocp_listmem_ptr:ocp_list_index; {first unused word of |ocp_list_info|}
-@!ocp_listmem_run_ptr:ocp_list_index; {temp unused word of |ocp_list_info|}
-@!ocp_lstack_info:array[ocp_lstack_index] of memory_word;
- {the big collection of ocp lstack data}
-@!ocp_lstackmem_ptr:ocp_lstack_index; {first unused word of |ocp_lstack_info|}
-@!ocp_lstackmem_run_ptr:ocp_lstack_index; {temp unused word of |ocp_lstack_info|}
-@!ocp_list_ptr:internal_ocp_list_number; {largest internal ocp list number in use}
-@!ocp_list_list:array[internal_ocp_list_number] of ocp_list_index;
-
-@
-@<Initialize table...@>=
-ocp_listmem_ptr:=2;
-ocp_list_lstack(0):=0;
-ocp_list_lstack_no(0):=ocp_maxint;
-ocp_list_lnext(0):=0;
-ocp_list_ptr:=null_ocp_list;
-ocp_list_list[null_ocp_list]:=0;
-ocp_lstackmem_ptr:=1;
-
-@ $\Omega$ always knows at least one ocp list, namely the null ocp list.
-
-@ @<Put each...@>=
-primitive_omega("nullocplist", set_ocp_list, null_ocp_list,0);
-text(frozen_null_ocp_list) := "nullocplist";
-eqtb[frozen_null_ocp_list] := eqtb[cur_val];
-
-@ @p function make_ocp_list_node(llstack:ocp_lstack_index;
- llstack_no:scaled;
- llnext:ocp_list_index):ocp_list_index;
-var p:ocp_list_index;
-begin
-p:=ocp_listmem_run_ptr;
-ocp_list_lstack(p):=llstack;
-ocp_list_lstack_no(p):=llstack_no;
-ocp_list_lnext(p):=llnext;
-ocp_listmem_run_ptr:=ocp_listmem_run_ptr+2;
-if ocp_listmem_run_ptr>=ocp_list_size then
- overflow("ocp_list_size",ocp_list_size);
-make_ocp_list_node:=p;
-end;
-
-function make_ocp_lstack_node(locp:internal_ocp_number;
- llnext:ocp_lstack_index) : ocp_lstack_index;
-var p:ocp_lstack_index;
-begin
-p:=ocp_lstackmem_run_ptr;
-ocp_lstack_ocp(p):=locp;
-ocp_lstack_lnext(p):=llnext;
-incr(ocp_lstackmem_run_ptr);
-if ocp_lstackmem_run_ptr>=ocp_stack_size then
- overflow("ocp_stack_size",ocp_stack_size);
-make_ocp_lstack_node:=p;
-end;
-
-function copy_ocp_lstack(llstack:ocp_lstack_index):ocp_lstack_index;
-var result:ocp_lstack_index;
-begin
-if is_null_ocp_lstack(llstack) then
- result:=make_null_ocp_lstack
-else
- result:=make_ocp_lstack_node(ocp_lstack_ocp(llstack),
- copy_ocp_lstack(ocp_lstack_lnext(llstack)));
-copy_ocp_lstack:=result;
-end;
-
-function copy_ocp_list(list:ocp_list_index):ocp_list_index;
-var result:ocp_list_index;
-begin
-if is_null_ocp_list(list) then
- result:=make_null_ocp_list
-else
- result:=make_ocp_list_node(copy_ocp_lstack(ocp_list_lstack(list)),
- ocp_list_lstack_no(list),
- copy_ocp_list(ocp_list_lnext(list)));
-copy_ocp_list:=result;
-end;
-
-function ocp_ensure_lstack(list:ocp_list_index; llstack_no:scaled):
- ocp_list_index;
-var p:ocp_list_index;
- q:ocp_list_index;
-begin
-p:=list;
-if is_null_ocp_list(p) then begin
- ocp_list_lstack_no(p) := llstack_no;
- ocp_list_lnext(p) := make_null_ocp_list;
- end
-else if ocp_list_lstack_no(p) > llstack_no then begin
- ocp_list_lnext(p):=
- make_ocp_list_node(ocp_list_lstack(p),
- ocp_list_lstack_no(p),
- ocp_list_lnext(p));
- ocp_list_lstack(p):=0;
- ocp_list_lstack_no(p):=llstack_no;
- end
-else begin
- q:=ocp_list_lnext(p);
- while (not (is_null_ocp_list(q))) and
- ocp_list_lstack_no(q) <= llstack_no do begin
- p:=q; q:=ocp_list_lnext(q);
- end;
- if ocp_list_lstack_no(p) < llstack_no then begin
- ocp_list_lnext(p) := make_ocp_list_node(0, llstack_no, q);
- p := ocp_list_lnext(p);
- end;
- end;
-ocp_ensure_lstack := p;
-end;
-
-procedure ocp_apply_add(list_entry:ocp_list_index;
- lbefore:boolean;
- locp:internal_ocp_number);
-var p:ocp_lstack_index;
- q:ocp_lstack_index;
-begin
-p := ocp_list_lstack(list_entry);
-if lbefore or (p=0) then begin
- ocp_list_lstack(list_entry) := make_ocp_lstack_node(locp, p);
- end
-else begin
- q:=ocp_lstack_lnext(p);
- while q<>0 do begin
- p:=q; q:=ocp_lstack_lnext(q);
- end;
- ocp_lstack_lnext(p):=make_ocp_lstack_node(locp,0);
- end;
-end;
-
-procedure ocp_apply_remove(list_entry:ocp_list_index;
- lbefore:boolean);
-var p:ocp_lstack_index;
- q:ocp_lstack_index;
- r:ocp_lstack_index;
-begin
-p := ocp_list_lstack(list_entry);
-if p=0 then begin
- print_err("warning: stack entry already empty"); print_ln
- end
-else begin
- q := ocp_lstack_lnext(p);
- if lbefore or (q=0) then
- ocp_list_lstack(list_entry) := q
- else begin
- r:=ocp_lstack_lnext(q);
- while r <> 0 do begin
- p:=q; q:=r; r:=ocp_lstack_lnext(r);
- end;
- ocp_lstack_lnext(p) := 0;
- end
- end;
-end;
-
-procedure scan_scaled; {sets |cur_val| to a scaled value}
-label done, done1, done2, found, not_found, attach_fraction;
-var negative:boolean; {should the answer be negated?}
-@!f:integer; {numerator of a fraction whose denominator is $2^{16}$}
-@!k,@!kk:small_number; {number of digits in a decimal fraction}
-@!p,@!q:pointer; {top of decimal digit stack}
-begin f:=0; arith_error:=false; negative:=false;
-@<Get the next non-blank non-sign...@>;
-back_input;
-if cur_tok=continental_point_token then cur_tok:=point_token;
-if cur_tok<>point_token then scan_int
-else begin radix:=10; cur_val:=0;
- end;
-if cur_tok=continental_point_token then cur_tok:=point_token;
-if (radix=10)and(cur_tok=point_token) then @<Scan decimal fraction@>;
-if cur_val<0 then {in this case |f=0|}
- begin negative := not negative; negate(cur_val);
- end;
-if cur_val>@'40000 then arith_error:=true
-else cur_val := cur_val*unity +f;
-if arith_error or(abs(cur_val)>=@'10000000000) then
-begin print_err("Stack number too large"); error;
-end;
-if negative then negate(cur_val);
-end;
-
-procedure print_ocp_lstack(lstack_entry:ocp_lstack_index);
-var p:ocp_lstack_index;
-begin
-p:=lstack_entry;
-while (p<>0) do begin
- print_esc(ocp_id_text(ocp_lstack_ocp(p)));
- p:=ocp_lstack_lnext(p);
- if (p<>0) then print(",");
- end;
-end;
-
-procedure print_ocp_list(list_entry:ocp_list_index);
-var p:ocp_list_index;
-begin
-print("["); p:=list_entry;
-while not (is_null_ocp_list(p)) do begin
- print("(");
- print_scaled(ocp_list_lstack_no(p));
- print(" : ");
- print_ocp_lstack(ocp_list_lstack(p));
- print(")");
- p:=ocp_list_lnext(p);
- if not (is_null_ocp_list(p)) then print(", ");
- end;
-print("]");
-end;
-
-function scan_ocp_list: ocp_list_index;
-var llstack_no:scaled;
- lop:quarterword;
- lstack_entry:ocp_list_index;
- other_list:ocp_list_index;
- ocp_ident:internal_ocp_number;
- result:ocp_list_index;
-begin
-get_r_token;
-if cur_cmd = set_ocp_list then
- result := copy_ocp_list(ocp_list_list[cur_chr])
-else if cur_cmd <> ocp_list_op then begin
- print_err("Bad ocp list specification");
-@.Bad ocp list specification@>
- help1("I was looking for a ocp list specification.");
- error;
- result := make_null_ocp_list;
- end
-else begin
- lop:=cur_chr;
- scan_scaled; llstack_no:=cur_val;
- if (llstack_no<=0) or (llstack_no>=ocp_maxint) then begin
- print_err("Stack numbers must be between 0 and 4096 (exclusive)");
- error;
- result := make_null_ocp_list;
- end
- else begin
- if lop <= add_after_op then begin
- scan_ocp_ident; ocp_ident:=cur_val;
- end;
- other_list:=scan_ocp_list;
- lstack_entry:=ocp_ensure_lstack(other_list, llstack_no);
- if lop <= add_after_op then
- ocp_apply_add(lstack_entry, (lop=add_before_op), ocp_ident)
- else
- ocp_apply_remove(lstack_entry, (lop=remove_before_op));
- result:=other_list;
- end;
- end;
-scan_ocp_list:=result;
-end;
-
-function read_ocp_list: internal_ocp_list_number;
-var f:internal_ocp_list_number;
- g:internal_ocp_list_number;
-begin
-g:=null_ocp_list;
-f:=ocp_list_ptr+1;
-ocp_listmem_run_ptr:=ocp_listmem_ptr;
-ocp_lstackmem_run_ptr:=ocp_lstackmem_ptr;
-ocp_list_list[f]:=scan_ocp_list;
-ocp_list_ptr:=f;
-ocp_listmem_ptr:=ocp_listmem_run_ptr;
-ocp_lstackmem_ptr:=ocp_lstackmem_run_ptr;
-g:=f;
-read_ocp_list:=g;
-end;
-
-procedure scan_ocp_list_ident;
-var f:internal_ocp_list_number;
-begin @<Get the next non-blank non-call...@>;
-if cur_cmd=set_ocp_list then f:=cur_chr
-else begin print_err("Missing ocp list identifier");
-@.Missing ocp list identifier@>
- help2("I was looking for a control sequence whose")@/
- ("current meaning has been defined by \ocplist.");
- back_error; f:=null_ocp_list;
- end;
-cur_val:=f;
-end;
-
-
-@* \[31] Device-independent file format.
-The most important output produced by a run of \TeX\ is the ``device
-independent'' (\.{DVI}) file that specifies where characters and rules
-are to appear on printed pages. The form of these files was designed by
-David R. Fuchs in 1979. Almost any reasonable typesetting device can be
-@^Fuchs, David Raymond@>
-@:DVI_files}{\.{DVI} files@>
-driven by a program that takes \.{DVI} files as input, and dozens of such
-\.{DVI}-to-whatever programs have been written. Thus, it is possible to
-print the output of \TeX\ on many different kinds of equipment, using \TeX\
-as a device-independent ``front end.''
-
-A \.{DVI} file is a stream of 8-bit bytes, which may be regarded as a
-series of commands in a machine-like language. The first byte of each command
-is the operation code, and this code is followed by zero or more bytes
-that provide parameters to the command. The parameters themselves may consist
-of several consecutive bytes; for example, the `|set_rule|' command has two
-parameters, each of which is four bytes long. Parameters are usually
-regarded as nonnegative integers; but four-byte-long parameters,
-and shorter parameters that denote distances, can be
-either positive or negative. Such parameters are given in two's complement
-notation. For example, a two-byte-long distance parameter has a value between
-$-2^{15}$ and $2^{15}-1$. As in \.{TFM} files, numbers that occupy
-more than one byte position appear in BigEndian order.
-
-A \.{DVI} file consists of a ``preamble,'' followed by a sequence of one
-or more ``pages,'' followed by a ``postamble.'' The preamble is simply a
-|pre| command, with its parameters that define the dimensions used in the
-file; this must come first. Each ``page'' consists of a |bop| command,
-followed by any number of other commands that tell where characters are to
-be placed on a physical page, followed by an |eop| command. The pages
-appear in the order that \TeX\ generated them. If we ignore |nop| commands
-and \\{fnt\_def} commands (which are allowed between any two commands in
-the file), each |eop| command is immediately followed by a |bop| command,
-or by a |post| command; in the latter case, there are no more pages in the
-file, and the remaining bytes form the postamble. Further details about
-the postamble will be explained later.
-
-Some parameters in \.{DVI} commands are ``pointers.'' These are four-byte
-quantities that give the location number of some other byte in the file;
-the first byte is number~0, then comes number~1, and so on. For example,
-one of the parameters of a |bop| command points to the previous |bop|;
-this makes it feasible to read the pages in backwards order, in case the
-results are being directed to a device that stacks its output face up.
-Suppose the preamble of a \.{DVI} file occupies bytes 0 to 99. Now if the
-first page occupies bytes 100 to 999, say, and if the second
-page occupies bytes 1000 to 1999, then the |bop| that starts in byte 1000
-points to 100 and the |bop| that starts in byte 2000 points to 1000. (The
-very first |bop|, i.e., the one starting in byte 100, has a pointer of~$-1$.)
-
-@ The \.{DVI} format is intended to be both compact and easily interpreted
-by a machine. Compactness is achieved by making most of the information
-implicit instead of explicit. When a \.{DVI}-reading program reads the
-commands for a page, it keeps track of several quantities: (a)~The current
-font |f| is an integer; this value is changed only
-by \\{fnt} and \\{fnt\_num} commands. (b)~The current position on the page
-is given by two numbers called the horizontal and vertical coordinates,
-|h| and |v|. Both coordinates are zero at the upper left corner of the page;
-moving to the right corresponds to increasing the horizontal coordinate, and
-moving down corresponds to increasing the vertical coordinate. Thus, the
-coordinates are essentially Cartesian, except that vertical directions are
-flipped; the Cartesian version of |(h,v)| would be |(h,-v)|. (c)~The
-current spacing amounts are given by four numbers |w|, |x|, |y|, and |z|,
-where |w| and~|x| are used for horizontal spacing and where |y| and~|z|
-are used for vertical spacing. (d)~There is a stack containing
-|(h,v,w,x,y,z)| values; the \.{DVI} commands |push| and |pop| are used to
-change the current level of operation. Note that the current font~|f| is
-not pushed and popped; the stack contains only information about
-positioning.
-
-The values of |h|, |v|, |w|, |x|, |y|, and |z| are signed integers having up
-to 32 bits, including the sign. Since they represent physical distances,
-there is a small unit of measurement such that increasing |h| by~1 means
-moving a certain tiny distance to the right. The actual unit of
-measurement is variable, as explained below; \TeX\ sets things up so that
-its \.{DVI} output is in sp units, i.e., scaled points, in agreement with
-all the |scaled| dimensions in \TeX's data structures.
-
-@ Here is a list of all the commands that may appear in a \.{DVI} file. Each
-command is specified by its symbolic name (e.g., |bop|), its opcode byte
-(e.g., 139), and its parameters (if any). The parameters are followed
-by a bracketed number telling how many bytes they occupy; for example,
-`|p[4]|' means that parameter |p| is four bytes long.
-
-\yskip\hang|set_char_0| 0. Typeset character number~0 from font~|f|
-such that the reference point of the character is at |(h,v)|. Then
-increase |h| by the width of that character. Note that a character may
-have zero or negative width, so one cannot be sure that |h| will advance
-after this command; but |h| usually does increase.
-
-\yskip\hang\\{set\_char\_1} through \\{set\_char\_127} (opcodes 1 to 127).
-Do the operations of |set_char_0|; but use the character whose number
-matches the opcode, instead of character~0.
-
-\yskip\hang|set1| 128 |c[1]|. Same as |set_char_0|, except that character
-number~|c| is typeset. \TeX82 uses this command for characters in the
-range |128<=c<256|.
-
-\yskip\hang|@!set2| 129 |c[2]|. Same as |set1|, except that |c|~is two
-bytes long, so it is in the range |0<=c<65536|. \TeX82 never uses this
-command, but it should come in handy for extensions of \TeX\ that deal
-with oriental languages.
-@^oriental characters@>@^Chinese characters@>@^Japanese characters@>
-
-\yskip\hang|@!set3| 130 |c[3]|. Same as |set1|, except that |c|~is three
-bytes long, so it can be as large as $2^{24}-1$. Not even the Chinese
-language has this many characters, but this command might prove useful
-in some yet unforeseen extension.
-
-\yskip\hang|@!set4| 131 |c[4]|. Same as |set1|, except that |c|~is four
-bytes long. Imagine that.
-
-\yskip\hang|set_rule| 132 |a[4]| |b[4]|. Typeset a solid black rectangle
-of height~|a| and width~|b|, with its bottom left corner at |(h,v)|. Then
-set |h:=h+b|. If either |a<=0| or |b<=0|, nothing should be typeset. Note
-that if |b<0|, the value of |h| will decrease even though nothing else happens.
-See below for details about how to typeset rules so that consistency with
-\MF\ is guaranteed.
-
-\yskip\hang|@!put1| 133 |c[1]|. Typeset character number~|c| from font~|f|
-such that the reference point of the character is at |(h,v)|. (The `put'
-commands are exactly like the `set' commands, except that they simply put out a
-character or a rule without moving the reference point afterwards.)
-
-\yskip\hang|@!put2| 134 |c[2]|. Same as |set2|, except that |h| is not changed.
-
-\yskip\hang|@!put3| 135 |c[3]|. Same as |set3|, except that |h| is not changed.
-
-\yskip\hang|@!put4| 136 |c[4]|. Same as |set4|, except that |h| is not changed.
-
-\yskip\hang|put_rule| 137 |a[4]| |b[4]|. Same as |set_rule|, except that
-|h| is not changed.
-
-\yskip\hang|nop| 138. No operation, do nothing. Any number of |nop|'s
-may occur between \.{DVI} commands, but a |nop| cannot be inserted between
-a command and its parameters or between two parameters.
-
-\yskip\hang|bop| 139 $c_0[4]$ $c_1[4]$ $\ldots$ $c_9[4]$ $p[4]$. Beginning
-of a page: Set |(h,v,w,x,y,z):=(0,0,0,0,0,0)| and set the stack empty. Set
-the current font |f| to an undefined value. The ten $c_i$ parameters hold
-the values of \.{\\count0} $\ldots$ \.{\\count9} in \TeX\ at the time
-\.{\\shipout} was invoked for this page; they can be used to identify
-pages, if a user wants to print only part of a \.{DVI} file. The parameter
-|p| points to the previous |bop| in the file; the first
-|bop| has $p=-1$.
-
-\yskip\hang|eop| 140. End of page: Print what you have read since the
-previous |bop|. At this point the stack should be empty. (The \.{DVI}-reading
-programs that drive most output devices will have kept a buffer of the
-material that appears on the page that has just ended. This material is
-largely, but not entirely, in order by |v| coordinate and (for fixed |v|) by
-|h|~coordinate; so it usually needs to be sorted into some order that is
-appropriate for the device in question.)
-
-\yskip\hang|push| 141. Push the current values of |(h,v,w,x,y,z)| onto the
-top of the stack; do not change any of these values. Note that |f| is
-not pushed.
-
-\yskip\hang|pop| 142. Pop the top six values off of the stack and assign
-them respectively to |(h,v,w,x,y,z)|. The number of pops should never
-exceed the number of pushes, since it would be highly embarrassing if the
-stack were empty at the time of a |pop| command.
-
-\yskip\hang|right1| 143 |b[1]|. Set |h:=h+b|, i.e., move right |b| units.
-The parameter is a signed number in two's complement notation, |-128<=b<128|;
-if |b<0|, the reference point moves left.
-
-\yskip\hang|right2| 144 |b[2]|. Same as |right1|, except that |b| is a
-two-byte quantity in the range |-32768<=b<32768|.
-
-\yskip\hang|right3| 145 |b[3]|. Same as |right1|, except that |b| is a
-three-byte quantity in the range |@t$-2^{23}$@><=b<@t$2^{23}$@>|.
-
-\yskip\hang|right4| 146 |b[4]|. Same as |right1|, except that |b| is a
-four-byte quantity in the range |@t$-2^{31}$@><=b<@t$2^{31}$@>|.
-
-\yskip\hang|w0| 147. Set |h:=h+w|; i.e., move right |w| units. With luck,
-this parameterless command will usually suffice, because the same kind of motion
-will occur several times in succession; the following commands explain how
-|w| gets particular values.
-
-\yskip\hang|w1| 148 |b[1]|. Set |w:=b| and |h:=h+b|. The value of |b| is a
-signed quantity in two's complement notation, |-128<=b<128|. This command
-changes the current |w|~spacing and moves right by |b|.
-
-\yskip\hang|@!w2| 149 |b[2]|. Same as |w1|, but |b| is two bytes long,
-|-32768<=b<32768|.
-
-\yskip\hang|@!w3| 150 |b[3]|. Same as |w1|, but |b| is three bytes long,
-|@t$-2^{23}$@><=b<@t$2^{23}$@>|.
-
-\yskip\hang|@!w4| 151 |b[4]|. Same as |w1|, but |b| is four bytes long,
-|@t$-2^{31}$@><=b<@t$2^{31}$@>|.
-
-\yskip\hang|x0| 152. Set |h:=h+x|; i.e., move right |x| units. The `|x|'
-commands are like the `|w|' commands except that they involve |x| instead
-of |w|.
-
-\yskip\hang|x1| 153 |b[1]|. Set |x:=b| and |h:=h+b|. The value of |b| is a
-signed quantity in two's complement notation, |-128<=b<128|. This command
-changes the current |x|~spacing and moves right by |b|.
-
-\yskip\hang|@!x2| 154 |b[2]|. Same as |x1|, but |b| is two bytes long,
-|-32768<=b<32768|.
-
-\yskip\hang|@!x3| 155 |b[3]|. Same as |x1|, but |b| is three bytes long,
-|@t$-2^{23}$@><=b<@t$2^{23}$@>|.
-
-\yskip\hang|@!x4| 156 |b[4]|. Same as |x1|, but |b| is four bytes long,
-|@t$-2^{31}$@><=b<@t$2^{31}$@>|.
-
-\yskip\hang|down1| 157 |a[1]|. Set |v:=v+a|, i.e., move down |a| units.
-The parameter is a signed number in two's complement notation, |-128<=a<128|;
-if |a<0|, the reference point moves up.
-
-\yskip\hang|@!down2| 158 |a[2]|. Same as |down1|, except that |a| is a
-two-byte quantity in the range |-32768<=a<32768|.
-
-\yskip\hang|@!down3| 159 |a[3]|. Same as |down1|, except that |a| is a
-three-byte quantity in the range |@t$-2^{23}$@><=a<@t$2^{23}$@>|.
-
-\yskip\hang|@!down4| 160 |a[4]|. Same as |down1|, except that |a| is a
-four-byte quantity in the range |@t$-2^{31}$@><=a<@t$2^{31}$@>|.
-
-\yskip\hang|y0| 161. Set |v:=v+y|; i.e., move down |y| units. With luck,
-this parameterless command will usually suffice, because the same kind of motion
-will occur several times in succession; the following commands explain how
-|y| gets particular values.
-
-\yskip\hang|y1| 162 |a[1]|. Set |y:=a| and |v:=v+a|. The value of |a| is a
-signed quantity in two's complement notation, |-128<=a<128|. This command
-changes the current |y|~spacing and moves down by |a|.
-
-\yskip\hang|@!y2| 163 |a[2]|. Same as |y1|, but |a| is two bytes long,
-|-32768<=a<32768|.
-
-\yskip\hang|@!y3| 164 |a[3]|. Same as |y1|, but |a| is three bytes long,
-|@t$-2^{23}$@><=a<@t$2^{23}$@>|.
-
-\yskip\hang|@!y4| 165 |a[4]|. Same as |y1|, but |a| is four bytes long,
-|@t$-2^{31}$@><=a<@t$2^{31}$@>|.
-
-\yskip\hang|z0| 166. Set |v:=v+z|; i.e., move down |z| units. The `|z|' commands
-are like the `|y|' commands except that they involve |z| instead of |y|.
-
-\yskip\hang|z1| 167 |a[1]|. Set |z:=a| and |v:=v+a|. The value of |a| is a
-signed quantity in two's complement notation, |-128<=a<128|. This command
-changes the current |z|~spacing and moves down by |a|.
-
-\yskip\hang|@!z2| 168 |a[2]|. Same as |z1|, but |a| is two bytes long,
-|-32768<=a<32768|.
-
-\yskip\hang|@!z3| 169 |a[3]|. Same as |z1|, but |a| is three bytes long,
-|@t$-2^{23}$@><=a<@t$2^{23}$@>|.
-
-\yskip\hang|@!z4| 170 |a[4]|. Same as |z1|, but |a| is four bytes long,
-|@t$-2^{31}$@><=a<@t$2^{31}$@>|.
-
-\yskip\hang|fnt_num_0| 171. Set |f:=0|. Font 0 must previously have been
-defined by a \\{fnt\_def} instruction, as explained below.
-
-\yskip\hang\\{fnt\_num\_1} through \\{fnt\_num\_63} (opcodes 172 to 234). Set
-|f:=1|, \dots, \hbox{|f:=63|}, respectively.
-
-\yskip\hang|fnt1| 235 |k[1]|. Set |f:=k|. \TeX82 uses this command for font
-numbers in the range |64<=k<256|.
-
-\yskip\hang|@!fnt2| 236 |k[2]|. Same as |fnt1|, except that |k|~is two
-bytes long, so it is in the range |0<=k<65536|. \TeX82 never generates this
-command, but large font numbers may prove useful for specifications of
-color or texture, or they may be used for special fonts that have fixed
-numbers in some external coding scheme.
-
-\yskip\hang|@!fnt3| 237 |k[3]|. Same as |fnt1|, except that |k|~is three
-bytes long, so it can be as large as $2^{24}-1$.
-
-\yskip\hang|@!fnt4| 238 |k[4]|. Same as |fnt1|, except that |k|~is four
-bytes long; this is for the really big font numbers (and for the negative ones).
-
-\yskip\hang|xxx1| 239 |k[1]| |x[k]|. This command is undefined in
-general; it functions as a $(k+2)$-byte |nop| unless special \.{DVI}-reading
-programs are being used. \TeX82 generates |xxx1| when a short enough
-\.{\\special} appears, setting |k| to the number of bytes being sent. It
-is recommended that |x| be a string having the form of a keyword followed
-by possible parameters relevant to that keyword.
-
-\yskip\hang|@!xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0<=k<65536|.
-
-\yskip\hang|@!xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0<=k<@t$2^{24}$@>|.
-
-\yskip\hang|xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be ridiculously
-large. \TeX82 uses |xxx4| when sending a string of length 256 or more.
-
-\yskip\hang|fnt_def1| 243 |k[1]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
-Define font |k|, where |0<=k<256|; font definitions will be explained shortly.
-
-\yskip\hang|@!fnt_def2| 244 |k[2]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
-Define font |k|, where |0<=k<65536|.
-
-\yskip\hang|@!fnt_def3| 245 |k[3]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
-Define font |k|, where |0<=k<@t$2^{24}$@>|.
-
-\yskip\hang|@!fnt_def4| 246 |k[4]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
-Define font |k|, where |@t$-2^{31}$@><=k<@t$2^{31}$@>|.
-
-\yskip\hang|pre| 247 |i[1]| |num[4]| |den[4]| |mag[4]| |k[1]| |x[k]|.
-Beginning of the preamble; this must come at the very beginning of the
-file. Parameters |i|, |num|, |den|, |mag|, |k|, and |x| are explained below.
-
-\yskip\hang|post| 248. Beginning of the postamble, see below.
-
-\yskip\hang|post_post| 249. Ending of the postamble, see below.
-
-\yskip\noindent Commands 250--255 are undefined at the present time.
-
-@ @d set_char_0=0 {typeset character 0 and move right}
-@d set1=128 {typeset a character and move right}
-@d set_rule=132 {typeset a rule and move right}
-@d put1==133 {typeset a character without moving}
-@d put_rule=137 {typeset a rule}
-@d nop=138 {no operation}
-@d bop=139 {beginning of page}
-@d eop=140 {ending of page}
-@d push=141 {save the current positions}
-@d pop=142 {restore previous positions}
-@d right1==143 {move right}
-@d right4==146 {move right, 4 bytes}
-@d w0=147 {move right by |w|}
-@d w1=148 {move right and set |w|}
-@d x0=152 {move right by |x|}
-@d x1=153 {move right and set |x|}
-@d down1=157 {move down}
-@d down4=160 {move down, 4 bytes}
-@d y0=161 {move down by |y|}
-@d y1=162 {move down and set |y|}
-@d z0=166 {move down by |z|}
-@d z1=167 {move down and set |z|}
-@d fnt_num_0=171 {set current font to 0}
-@d fnt1=235 {set current font}
-@d xxx1=239 {extension to \.{DVI} primitives}
-@d xxx4=242 {potentially long extension to \.{DVI} primitives}
-@d fnt_def1=243 {define the meaning of a font number}
-@d pre=247 {preamble}
-@d post=248 {postamble beginning}
-@d post_post=249 {postamble ending}
-
-@ The preamble contains basic information about the file as a whole. As
-stated above, there are six parameters:
-$$\hbox{|@!i[1]| |@!num[4]| |@!den[4]| |@!mag[4]| |@!k[1]| |@!x[k]|.}$$
-The |i| byte identifies \.{DVI} format; currently this byte is always set
-to~2. (The value |i=3| is currently used for an extended format that
-allows a mixture of right-to-left and left-to-right typesetting.
-Some day we will set |i=4|, when \.{DVI} format makes another
-incompatible change---perhaps in the year 2048.)
-
-The next two parameters, |num| and |den|, are positive integers that define
-the units of measurement; they are the numerator and denominator of a
-fraction by which all dimensions in the \.{DVI} file could be multiplied
-in order to get lengths in units of $10^{-7}$ meters. Since $\rm 7227{pt} =
-254{cm}$, and since \TeX\ works with scaled points where there are $2^{16}$
-sp in a point, \TeX\ sets
-$|num|/|den|=(254\cdot10^5)/(7227\cdot2^{16})=25400000/473628672$.
-@^sp@>
-
-The |mag| parameter is what \TeX\ calls \.{\\mag}, i.e., 1000 times the
-desired magnification. The actual fraction by which dimensions are
-multiplied is therefore $|mag|\cdot|num|/1000|den|$. Note that if a \TeX\
-source document does not call for any `\.{true}' dimensions, and if you
-change it only by specifying a different \.{\\mag} setting, the \.{DVI}
-file that \TeX\ creates will be completely unchanged except for the value
-of |mag| in the preamble and postamble. (Fancy \.{DVI}-reading programs allow
-users to override the |mag|~setting when a \.{DVI} file is being printed.)
-
-Finally, |k| and |x| allow the \.{DVI} writer to include a comment, which is not
-interpreted further. The length of comment |x| is |k|, where |0<=k<256|.
-
-@d id_byte=2 {identifies the kind of \.{DVI} files described here}
-
-@ Font definitions for a given font number |k| contain further parameters
-$$\hbox{|c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.}$$
-The four-byte value |c| is the check sum that \TeX\ found in the \.{TFM}
-file for this font; |c| should match the check sum of the font found by
-programs that read this \.{DVI} file.
-@^check sum@>
-
-Parameter |s| contains a fixed-point scale factor that is applied to
-the character widths in font |k|; font dimensions in \.{TFM} files and
-other font files are relative to this quantity, which is called the
-``at size'' elsewhere in this documentation. The value of |s| is
-always positive and less than $2^{27}$. It is given in the same units
-as the other \.{DVI} dimensions, i.e., in sp when \TeX82 has made the
-file. Parameter |d| is similar to |s|; it is the ``design size,'' and
-(like~|s|) it is given in \.{DVI} units. Thus, font |k| is to be used
-at $|mag|\cdot s/1000d$ times its normal size.
-
-The remaining part of a font definition gives the external name of the font,
-which is an ASCII string of length |a+l|. The number |a| is the length
-of the ``area'' or directory, and |l| is the length of the font name itself;
-the standard local system font area is supposed to be used when |a=0|.
-The |n| field contains the area in its first |a| bytes.
-
-Font definitions must appear before the first use of a particular font number.
-Once font |k| is defined, it must not be defined again; however, we
-shall see below that font definitions appear in the postamble as well as
-in the pages, so in this sense each font number is defined exactly twice,
-if at all. Like |nop| commands, font definitions can
-appear before the first |bop|, or between an |eop| and a |bop|.
-
-@ Sometimes it is desirable to make horizontal or vertical rules line up
-precisely with certain features in characters of a font. It is possible to
-guarantee the correct matching between \.{DVI} output and the characters
-generated by \MF\ by adhering to the following principles: (1)~The \MF\
-characters should be positioned so that a bottom edge or left edge that is
-supposed to line up with the bottom or left edge of a rule appears at the
-reference point, i.e., in row~0 and column~0 of the \MF\ raster. This
-ensures that the position of the rule will not be rounded differently when
-the pixel size is not a perfect multiple of the units of measurement in
-the \.{DVI} file. (2)~A typeset rule of height $a>0$ and width $b>0$
-should be equivalent to a \MF-generated character having black pixels in
-precisely those raster positions whose \MF\ coordinates satisfy
-|0<=x<@t$\alpha$@>b| and |0<=y<@t$\alpha$@>a|, where $\alpha$ is the number
-of pixels per \.{DVI} unit.
-@:METAFONT}{\MF@>
-@^alignment of rules with characters@>
-@^rules aligning with characters@>
-
-@ The last page in a \.{DVI} file is followed by `|post|'; this command
-introduces the postamble, which summarizes important facts that \TeX\ has
-accumulated about the file, making it possible to print subsets of the data
-with reasonable efficiency. The postamble has the form
-$$\vbox{\halign{\hbox{#\hfil}\cr
- |post| |p[4]| |num[4]| |den[4]| |mag[4]| |l[4]| |u[4]| |s[2]| |t[2]|\cr
- $\langle\,$font definitions$\,\rangle$\cr
- |post_post| |q[4]| |i[1]| 223's$[{\G}4]$\cr}}$$
-Here |p| is a pointer to the final |bop| in the file. The next three
-parameters, |num|, |den|, and |mag|, are duplicates of the quantities that
-appeared in the preamble.
-
-Parameters |l| and |u| give respectively the height-plus-depth of the tallest
-page and the width of the widest page, in the same units as other dimensions
-of the file. These numbers might be used by a \.{DVI}-reading program to
-position individual ``pages'' on large sheets of film or paper; however,
-the standard convention for output on normal size paper is to position each
-page so that the upper left-hand corner is exactly one inch from the left
-and the top. Experience has shown that it is unwise to design \.{DVI}-to-printer
-software that attempts cleverly to center the output; a fixed position of
-the upper left corner is easiest for users to understand and to work with.
-Therefore |l| and~|u| are often ignored.
-
-Parameter |s| is the maximum stack depth (i.e., the largest excess of
-|push| commands over |pop| commands) needed to process this file. Then
-comes |t|, the total number of pages (|bop| commands) present.
-
-The postamble continues with font definitions, which are any number of
-\\{fnt\_def} commands as described above, possibly interspersed with |nop|
-commands. Each font number that is used in the \.{DVI} file must be defined
-exactly twice: Once before it is first selected by a \\{fnt} command, and once
-in the postamble.
-
-@ The last part of the postamble, following the |post_post| byte that
-signifies the end of the font definitions, contains |q|, a pointer to the
-|post| command that started the postamble. An identification byte, |i|,
-comes next; this currently equals~2, as in the preamble.
-
-The |i| byte is followed by four or more bytes that are all equal to
-the decimal number 223 (i.e., @'337 in octal). \TeX\ puts out four to seven of
-these trailing bytes, until the total length of the file is a multiple of
-four bytes, since this works out best on machines that pack four bytes per
-word; but any number of 223's is allowed, as long as there are at least four
-of them. In effect, 223 is a sort of signature that is added at the very end.
-@^Fuchs, David Raymond@>
-
-This curious way to finish off a \.{DVI} file makes it feasible for
-\.{DVI}-reading programs to find the postamble first, on most computers,
-even though \TeX\ wants to write the postamble last. Most operating
-systems permit random access to individual words or bytes of a file, so
-the \.{DVI} reader can start at the end and skip backwards over the 223's
-until finding the identification byte. Then it can back up four bytes, read
-|q|, and move to byte |q| of the file. This byte should, of course,
-contain the value 248 (|post|); now the postamble can be read, so the
-\.{DVI} reader can discover all the information needed for typesetting the
-pages. Note that it is also possible to skip through the \.{DVI} file at
-reasonably high speed to locate a particular page, if that proves
-desirable. This saves a lot of time, since \.{DVI} files used in production
-jobs tend to be large.
-
-Unfortunately, however, standard \PASCAL\ does not include the ability to
-@^system dependencies@>
-access a random position in a file, or even to determine the length of a file.
-Almost all systems nowadays provide the necessary capabilities, so \.{DVI}
-format has been designed to work most efficiently with modern operating systems.
-But if \.{DVI} files have to be processed under the restrictions of standard
-\PASCAL, one can simply read them from front to back, since the necessary
-header information is present in the preamble and in the font definitions.
-(The |l| and |u| and |s| and |t| parameters, which appear only in the
-postamble, are ``frills'' that are handy but not absolutely necessary.)
-
-@* \[32] Shipping pages out.
-After considering \TeX's eyes and stomach, we come now to the bowels.
-@^bowels@>
-
-The |ship_out| procedure is given a pointer to a box; its mission is
-to describe that box in \.{DVI} form, outputting a ``page'' to |dvi_file|.
-The \.{DVI} coordinates $(h,v)=(0,0)$ should correspond to the upper left
-corner of the box being shipped.
-
-Since boxes can be inside of boxes inside of boxes, the main work of
-|ship_out| is done by two mutually recursive routines, |hlist_out|
-and |vlist_out|, which traverse the hlists and vlists inside of horizontal
-and vertical boxes.
-
-As individual pages are being processed, we need to accumulate
-information about the entire set of pages, since such statistics must be
-reported in the postamble. The global variables |total_pages|, |max_v|,
-|max_h|, |max_push|, and |last_bop| are used to record this information.
-
-The variable |doing_leaders| is |true| while leaders are being output.
-The variable |dead_cycles| contains the number of times an output routine
-has been initiated since the last |ship_out|.
-
-A few additional global variables are also defined here for use in
-|vlist_out| and |hlist_out|. They could have been local variables, but
-that would waste stack space when boxes are deeply nested, since the
-values of these variables are not needed during recursive calls.
-@^recursion@>
-
-@<Glob...@>=
-@!total_pages:integer; {the number of pages that have been shipped out}
-@!max_v:scaled; {maximum height-plus-depth of pages shipped so far}
-@!max_h:scaled; {maximum width of pages shipped so far}
-@!max_push:integer; {deepest nesting of |push| commands encountered so far}
-@!last_bop:integer; {location of previous |bop| in the \.{DVI} output}
-@!dead_cycles:integer; {recent outputs that didn't ship anything out}
-@!doing_leaders:boolean; {are we inside a leader box?}
-@#
-@!c,@!f:integer; {character and font in current |char_node|}
-@!oval,@!ocmd:integer; {used by |out_cmd| for generating
- |set|, |fnt| and |fnt_def| commands}
-@!rule_ht,@!rule_dp,@!rule_wd:scaled; {size of current rule being output}
-@!g:pointer; {current glue specification}
-@!lq,@!lr:integer; {quantities used in calculations for leaders}
-
-@ @<Set init...@>=
-total_pages:=0; max_v:=0; max_h:=0; max_push:=0; last_bop:=-1;
-doing_leaders:=false; dead_cycles:=0; cur_s:=-1;
-
-@ The \.{DVI} bytes are output to a buffer instead of being written directly
-to the output file. This makes it possible to reduce the overhead of
-subroutine calls, thereby measurably speeding up the computation, since
-output of \.{DVI} bytes is part of \TeX's inner loop. And it has another
-advantage as well, since we can change instructions in the buffer in order to
-make the output more compact. For example, a `|down2|' command can be
-changed to a `|y2|', thereby making a subsequent `|y0|' command possible,
-saving two bytes.
-
-The output buffer is divided into two parts of equal size; the bytes found
-in |dvi_buf[0..half_buf-1]| constitute the first half, and those in
-|dvi_buf[half_buf..dvi_buf_size-1]| constitute the second. The global
-variable |dvi_ptr| points to the position that will receive the next
-output byte. When |dvi_ptr| reaches |dvi_limit|, which is always equal
-to one of the two values |half_buf| or |dvi_buf_size|, the half buffer that
-is about to be invaded next is sent to the output and |dvi_limit| is
-changed to its other value. Thus, there is always at least a half buffer's
-worth of information present, except at the very beginning of the job.
-
-Bytes of the \.{DVI} file are numbered sequentially starting with 0;
-the next byte to be generated will be number |dvi_offset+dvi_ptr|.
-A byte is present in the buffer only if its number is |>=dvi_gone|.
-
-@<Types...@>=
-@!dvi_index=0..dvi_buf_size; {an index into the output buffer}
-
-@ Some systems may find it more efficient to make |dvi_buf| a |packed|
-array, since output of four bytes at once may be facilitated.
-@^system dependencies@>
-
-@<Glob...@>=
-@!dvi_buf:array[dvi_index] of real_eight_bits; {buffer for \.{DVI} output}
-@!half_buf:dvi_index; {half of |dvi_buf_size|}
-@!dvi_limit:dvi_index; {end of the current half buffer}
-@!dvi_ptr:dvi_index; {the next available buffer address}
-@!dvi_offset:integer; {|dvi_buf_size| times the number of times the
- output buffer has been fully emptied}
-@!dvi_gone:integer; {the number of bytes already output to |dvi_file|}
-
-@ Initially the buffer is all in one piece; we will output half of it only
-after it first fills up.
-
-@<Set init...@>=
-half_buf:=dvi_buf_size div 2; dvi_limit:=dvi_buf_size; dvi_ptr:=0;
-dvi_offset:=0; dvi_gone:=0;
-
-@ The actual output of |dvi_buf[a..b]| to |dvi_file| is performed by calling
-|write_dvi(a,b)|. For best results, this procedure should be optimized to
-run as fast as possible on each particular system, since it is part of
-\TeX's inner loop. It is safe to assume that |a| and |b+1| will both be
-multiples of 4 when |write_dvi(a,b)| is called; therefore it is possible on
-many machines to use efficient methods to pack four bytes per word and to
-output an array of words with one system call.
-@^system dependencies@>
-@^inner loop@>
-@^defecation@>
-
-@p procedure write_dvi(@!a,@!b:dvi_index);
-var k:dvi_index;
-begin for k:=a to b do write(dvi_file,dvi_buf[k]);
-end;
-
-@ To put a byte in the buffer without paying the cost of invoking a procedure
-each time, we use the macro |dvi_out|.
-
-@d dvi_out(#)==@+begin dvi_buf[dvi_ptr]:=#; incr(dvi_ptr);
- if dvi_ptr=dvi_limit then dvi_swap;
- end
-
-@p procedure dvi_swap; {outputs half of the buffer}
-begin if dvi_limit=dvi_buf_size then
- begin write_dvi(0,half_buf-1); dvi_limit:=half_buf;
- dvi_offset:=dvi_offset+dvi_buf_size; dvi_ptr:=0;
- end
-else begin write_dvi(half_buf,dvi_buf_size-1); dvi_limit:=dvi_buf_size;
- end;
-dvi_gone:=dvi_gone+half_buf;
-end;
-
-@ Here is how we clean out the buffer when \TeX\ is all through; |dvi_ptr|
-will be a multiple of~4.
-
-@<Empty the last bytes out of |dvi_buf|@>=
-if dvi_limit=half_buf then write_dvi(half_buf,dvi_buf_size-1);
-if dvi_ptr>0 then write_dvi(0,dvi_ptr-1)
-
-@ The |dvi_four| procedure outputs four bytes in two's complement notation,
-without risking arithmetic overflow.
-
-@p procedure dvi_four(@!x:integer);
-begin if x>=0 then dvi_out(x div @'100000000)
-else begin x:=x+@'10000000000;
- x:=x+@'10000000000;
- dvi_out((x div @'100000000) + 128);
- end;
-x:=x mod @'100000000; dvi_out(x div @'200000);
-x:=x mod @'200000; dvi_out(x div @'400);
-dvi_out(x mod @'400);
-end;
-
-@ A mild optimization of the output is performed by the |dvi_pop|
-routine, which issues a |pop| unless it is possible to cancel a
-`|push| |pop|' pair. The parameter to |dvi_pop| is the byte address
-following the old |push| that matches the new |pop|.
-
-@p procedure dvi_pop(@!l:integer);
-begin if (l=dvi_offset+dvi_ptr)and(dvi_ptr>0) then decr(dvi_ptr)
-else dvi_out(pop);
-end;
-
-@ Here's a procedure that outputs a font definition. $\Omega$ allows
-more than 256 different fonts per job, so the right font definition
-command must be selected.
-
-@d Incr_Decr(#) == #
-@d Incr(#) == #:=#+Incr_Decr {increase a variable}
-@d Decr(#) == #:=#-Incr_Decr {decrease a variable}
-
-@d dvi_debug_out(#)==begin
-dvi_out(#);
-end
-
-@d out_cmd ==
-begin
-if (oval<@"100)and(oval>=0) then begin
- if (ocmd<>set1)or(oval>127) then begin
- if (ocmd=fnt1)and(oval<64) then Incr(oval)(fnt_num_0) @+ else dvi_debug_out(ocmd);
- end;
- end
-else
- begin if (oval<@"10000)and(oval>=0) then dvi_debug_out(ocmd+1) @+ else @;
- begin if (oval<@"1000000)and(oval>=0) then dvi_debug_out(ocmd+2) @+ else @;
- begin dvi_debug_out(ocmd+3);
- if oval>=0 then dvi_debug_out(oval div @"1000000)
- else begin Incr(oval)(@"40000000); Incr(oval)(@"40000000);
- dvi_debug_out((oval div @"1000000) + 128); oval:=oval mod @"1000000;
- end;
- dvi_debug_out(oval div @"10000); oval:=oval mod @"10000;
- end;
- dvi_debug_out(oval div @"10000); oval:=oval mod @"10000;
- end;
- dvi_debug_out(oval div @"100); oval:=oval mod @"100;
- end;
-dvi_debug_out(oval)
-end
-
-@p procedure dvi_font_def(@!f:internal_font_number);
-var k:pool_pointer; {index into |str_pool|}
-fa:^packed_ASCII_code;
-begin
-oval:=f-font_base-1; ocmd:= fnt_def1; out_cmd;@/
-dvi_out(font_check_0(f));
-dvi_out(font_check_1(f));
-dvi_out(font_check_2(f));
-dvi_out(font_check_3(f));@/
-dvi_four(font_size(f));
-dvi_four(font_dsize(f));@/
-dvi_out(0); { |font_area(f)| is unused }
-dvi_out(strlen(font_name(f)));
-@<Output the font name whose internal number is |f|@>;
-end;
-
-@ @<Output the font name whose internal number is |f|@>=
-fa := get_font_name(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
-the ideas in the next few parts of this program, since it is not really
-necessary to optimize the \.{DVI} code by making use of the |w0|, |x0|,
-|y0|, and |z0| commands. Furthermore, the algorithm that we are about to
-describe does not pretend to give an optimum reduction in the length
-of the \.{DVI} code; after all, speed is more important than compactness.
-But the method is surprisingly effective, and it takes comparatively little
-time.
-
-We can best understand the basic idea by first considering a simpler problem
-that has the same essential characteristics. Given a sequence of digits,
-say $3\,1\,4\,1\,5\,9\,2\,6\,5\,3\,5\,8\,9$, we want to assign subscripts
-$d$, $y$, or $z$ to each digit so as to maximize the number of ``$y$-hits''
-and ``$z$-hits''; a $y$-hit is an instance of two appearances of the same
-digit with the subscript $y$, where no $y$'s intervene between the two
-appearances, and a $z$-hit is defined similarly. For example, the sequence
-above could be decorated with subscripts as follows:
-$$3_z\,1_y\,4_d\,1_y\,5_y\,9_d\,2_d\,6_d\,5_y\,3_z\,5_y\,8_d\,9_d.$$
-There are three $y$-hits ($1_y\ldots1_y$ and $5_y\ldots5_y\ldots5_y$) and
-one $z$-hit ($3_z\ldots3_z$); there are no $d$-hits, since the two appearances
-of $9_d$ have $d$'s between them, but we don't count $d$-hits so it doesn't
-matter how many there are. These subscripts are analogous to the \.{DVI}
-commands called \\{down}, $y$, and $z$, and the digits are analogous to
-different amounts of vertical motion; a $y$-hit or $z$-hit corresponds to
-the opportunity to use the one-byte commands |y0| or |z0| in a \.{DVI} file.
-
-\TeX's method of assigning subscripts works like this: Append a new digit,
-say $\delta$, to the right of the sequence. Now look back through the
-sequence until one of the following things happens: (a)~You see
-$\delta_y$ or $\delta_z$, and this was the first time you encountered a
-$y$ or $z$ subscript, respectively. Then assign $y$ or $z$ to the new
-$\delta$; you have scored a hit. (b)~You see $\delta_d$, and no $y$
-subscripts have been encountered so far during this search. Then change
-the previous $\delta_d$ to $\delta_y$ (this corresponds to changing a
-command in the output buffer), and assign $y$ to the new $\delta$; it's
-another hit. (c)~You see $\delta_d$, and a $y$ subscript has been seen
-but not a $z$. Change the previous $\delta_d$ to $\delta_z$ and assign
-$z$ to the new $\delta$. (d)~You encounter both $y$ and $z$ subscripts
-before encountering a suitable $\delta$, or you scan all the way to the
-front of the sequence. Assign $d$ to the new $\delta$; this assignment may
-be changed later.
-
-The subscripts $3_z\,1_y\,4_d\ldots\,$ in the example above were, in fact,
-produced by this procedure, as the reader can verify. (Go ahead and try it.)
-
-@ In order to implement such an idea, \TeX\ maintains a stack of pointers
-to the \\{down}, $y$, and $z$ commands that have been generated for the
-current page. And there is a similar stack for \\{right}, |w|, and |x|
-commands. These stacks are called the down stack and right stack, and their
-top elements are maintained in the variables |down_ptr| and |right_ptr|.
-
-Each entry in these stacks contains four fields: The |width| field is
-the amount of motion down or to the right; the |location| field is the
-byte number of the \.{DVI} command in question (including the appropriate
-|dvi_offset|); the |vlink| field points to the next item below this one
-on the stack; and the |vinfo| field encodes the options for possible change
-in the \.{DVI} command.
-
-@d location(#)==vmem(#+1).int {\.{DVI} byte number for a movement command}
-
-@<Glob...@>=
-@!down_ptr,@!right_ptr:pointer; {heads of the down and right stacks}
-
-@ @<Set init...@>=
-down_ptr:=null; right_ptr:=null;
-
-@ Here is a subroutine that produces a \.{DVI} command for some specified
-downward or rightward motion. It has two parameters: |w| is the amount
-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_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;
-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
-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;
- @<Look at the other stack entries until deciding what sort of \.{DVI} command
- to generate; |goto found| if node |p| is a ``hit''@>;
-end;
-@<Generate a |down| or |right| command for |w| and |return|@>;
-found: @<Generate a |y0| or |z0| command in order to reuse a previous
- appearance of~|w|@>;
-exit:end;
-
-@ The |vinfo| fields in the entries of the down stack or the right stack
-have six possible settings: |y_here| or |z_here| mean that the \.{DVI}
-command refers to |y| or |z|, respectively (or to |w| or |x|, in the
-case of horizontal motion); |yz_OK| means that the \.{DVI} command is
-\\{down} (or \\{right}) but can be changed to either |y| or |z| (or
-to either |w| or |x|); |y_OK| means that it is \\{down} and can be changed
-to |y| but not |z|; |z_OK| is similar; and |d_fixed| means it must stay
-\\{down}.
-
-The four settings |yz_OK|, |y_OK|, |z_OK|, |d_fixed| would not need to
-be distinguished from each other if we were simply solving the
-digit-subscripting problem mentioned above. But in \TeX's case there is
-a complication because of the nested structure of |push| and |pop|
-commands. Suppose we add parentheses to the digit-subscripting problem,
-redefining hits so that $\delta_y\ldots \delta_y$ is a hit if all $y$'s between
-the $\delta$'s are enclosed in properly nested parentheses, and if the
-parenthesis level of the right-hand $\delta_y$ is deeper than or equal to
-that of the left-hand one. Thus, `(' and `)' correspond to `|push|'
-and `|pop|'. Now if we want to assign a subscript to the final 1 in the
-sequence
-$$2_y\,7_d\,1_d\,(\,8_z\,2_y\,8_z\,)\,1$$
-we cannot change the previous $1_d$ to $1_y$, since that would invalidate
-the $2_y\ldots2_y$ hit. But we can change it to $1_z$, scoring a hit
-since the intervening $8_z$'s are enclosed in parentheses.
-
-The program below removes movement nodes that are introduced after a |push|,
-before it outputs the corresponding |pop|.
-
-@d y_here=1 {|vinfo| when the movement entry points to a |y| command}
-@d z_here=2 {|vinfo| when the movement entry points to a |z| command}
-@d yz_OK=3 {|vinfo| corresponding to an unconstrained \\{down} command}
-@d y_OK=4 {|vinfo| corresponding to a \\{down} that can't become a |z|}
-@d z_OK=5 {|vinfo| corresponding to a \\{down} that can't become a |y|}
-@d d_fixed=6 {|vinfo| corresponding to a \\{down} that can't change}
-
-@ When the |movement| procedure gets to the label |found|, the value of
-|vinfo(p)| will be either |y_here| or |z_here|. If it is, say, |y_here|,
-the procedure generates a |y0| command (or a |w0| command), and marks
-all |vinfo| fields between |q| and |p| so that |y| is not OK in that range.
-
-@<Generate a |y0| or |z0| command...@>=
-vinfo(q):=vinfo(p);
-if vinfo(q)=y_here then
- begin dvi_out(o+y0-down1); {|y0| or |w0|}
- while vlink(q)<>p do
- begin q:=vlink(q);
- case vinfo(q) of
- yz_OK: vinfo(q):=z_OK;
- y_OK: vinfo(q):=d_fixed;
- othercases do_nothing
- endcases;
- end;
- end
-else begin dvi_out(o+z0-down1); {|z0| or |x0|}
- while vlink(q)<>p do
- begin q:=vlink(q);
- case vinfo(q) of
- yz_OK: vinfo(q):=y_OK;
- z_OK: vinfo(q):=d_fixed;
- othercases do_nothing
- endcases;
- end;
- end
-
-@ @<Generate a |down| or |right|...@>=
-if abs(w)>=@'40000000 then
- begin dvi_out(o+3); {|down4| or |right4|}
- dvi_four(w); return;
- end;
-if abs(w)>=@'100000 then
- begin dvi_out(o+2); {|down3| or |right3|}
- if w<0 then w:=w+@'100000000;
- dvi_out(w div @'200000); w:=w mod @'200000; goto 2;
- end;
-if abs(w)>=@'200 then
- begin dvi_out(o+1); {|down2| or |right2|}
- if w<0 then w:=w+@'200000;
- goto 2;
- end;
-dvi_out(o); {|down1| or |right1|}
-if w<0 then w:=w+@'400;
-goto 1;
-2: dvi_out(w div @'400);
-1: dvi_out(w mod @'400); return
-
-@ As we search through the stack, we are in one of three states,
-|y_seen|, |z_seen|, or |none_seen|, depending on whether we have
-encountered |y_here| or |z_here| nodes. These states are encoded as
-multiples of 6, so that they can be added to the |info| fields for quick
-decision-making.
-@^inner loop@>
-
-@d none_seen=0 {no |y_here| or |z_here| nodes have been encountered yet}
-@d y_seen=6 {we have seen |y_here| but not |z_here|}
-@d z_seen=12 {we have seen |z_here| but not |y_here|}
-
-@<Look at the other stack entries until deciding...@>=
-p:=vlink(q); mstate:=none_seen;
-while p<>null do
- begin if width(p)=w then @<Consider a node with matching width;
- |goto found| if it's a hit@>
- else case mstate+vinfo(p) of
- none_seen+y_here: mstate:=y_seen;
- none_seen+z_here: mstate:=z_seen;
- y_seen+z_here,z_seen+y_here: goto not_found;
- othercases do_nothing
- endcases;
- p:=vlink(p);
- end;
-not_found:
-
-@ We might find a valid hit in a |y| or |z| byte that is already gone
-from the buffer. But we can't change bytes that are gone forever; ``the
-moving finger writes, $\ldots\,\,$.''
-
-@<Consider a node with matching width...@>=
-case mstate+vinfo(p) of
-none_seen+yz_OK,none_seen+y_OK,z_seen+yz_OK,z_seen+y_OK:@t@>@;@/
- if location(p)<dvi_gone then goto not_found
- else @<Change buffered instruction to |y| or |w| and |goto found|@>;
-none_seen+z_OK,y_seen+yz_OK,y_seen+z_OK:@t@>@;@/
- if location(p)<dvi_gone then goto not_found
- else @<Change buffered instruction to |z| or |x| and |goto found|@>;
-none_seen+y_here,none_seen+z_here,y_seen+z_here,z_seen+y_here: goto found;
-othercases do_nothing
-endcases
-
-@ @<Change buffered instruction to |y| or |w| and |goto found|@>=
-begin k:=location(p)-dvi_offset;
-if k<0 then k:=k+dvi_buf_size;
-dvi_buf[k]:=dvi_buf[k]+y1-down1;
-vinfo(p):=y_here; goto found;
-end
-
-@ @<Change buffered instruction to |z| or |x| and |goto found|@>=
-begin k:=location(p)-dvi_offset;
-if k<0 then k:=k+dvi_buf_size;
-dvi_buf[k]:=dvi_buf[k]+z1-down1;
-vinfo(p):=z_here; goto found;
-end
-
-@ In case you are wondering when all the movement nodes are removed from
-\TeX's memory, the answer is that they are recycled just before
-|hlist_out| and |vlist_out| finish outputting a box. This restores the
-down and right stacks to the state they were in before the box was output,
-except that some |vinfo|'s may have become more restrictive.
-
-@p procedure prune_movements(@!l:integer);
- {delete movement nodes with |location>=l|}
-label done,exit;
-var p:pointer; {node being deleted}
-begin while down_ptr<>null do
- begin if location(down_ptr)<l then goto done;
- p:=down_ptr; down_ptr:=vlink(p); flush_node(p);
- end;
-done: while right_ptr<>null do
- begin if location(right_ptr)<l then return;
- p:=right_ptr; right_ptr:=vlink(p); flush_node(p);
- end;
-exit:end;
-
-@ The actual distances by which we want to move might be computed as the
-sum of several separate movements. For example, there might be several
-glue nodes in succession, or we might want to move right by the width of
-some box plus some amount of glue. More importantly, the baselineskip
-distances are computed in terms of glue together with the depth and
-height of adjacent boxes, and we want the \.{DVI} file to lump these
-three quantities together into a single motion.
-
-Therefore, \TeX\ maintains two pairs of global variables: |dvi.h| and |dvi.v|
-are the |h| and |v| coordinates corresponding to the commands actually
-output to the \.{DVI} file, while |cur.h| and |cur.v| are the coordinates
-corresponding to the current state of the output routines. Coordinate
-changes will accumulate in |cur.h| and |cur.v| without being reflected
-in the output, until such a change becomes necessary or desirable; we
-can call the |movement| procedure whenever we want to make |dvi.h=pos.h|
-or |dvi.v=pos.v|.
-
-The current font reflected in the \.{DVI} output is called |dvi_f|;
-there is no need for a `\\{cur\_f}' variable.
-
-The depth of nesting of |hlist_out| and |vlist_out| is called |cur_s|;
-this is essentially the depth of |push| commands in the \.{DVI} output.
-
-@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 pos.v <> dvi.v then begin
- movement(dvi.v - pos.v, down1);
- dvi.v := pos.v;
- end
-
-@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;
-
-@ @<Types...@>=
-@!scaledpos = record
- h, v: scaled;
- end;
-
-@ @<Glob...@>=
-@!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$}
-
-@ @<Calculate DVI page dimensions and margins@>=
-if page_width > 0 then
- cur_page_size.h := page_width
-else
- 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_size.v := page_height
-else
- 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
-
-@ @<Initialize variables as |ship_out| begins@>=
-set_to_zero(dvi); set_to_zero(cur); dvi_f:=null_font;
-@<Calculate DVI page dimensions and margins@>;
-ensure_dvi_open;
-if total_pages=0 then
- begin dvi_out(pre); dvi_out(id_byte); {output the preamble}
-@^preamble of \.{DVI} file@>
- dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp}
- prepare_mag; dvi_four(mag); {magnification factor is frozen}
- old_setting:=selector; selector:=new_string;
- print(" LuaTeX output "); print_int(year); print_char(".");
- print_two(month); print_char("."); print_two(day);
- print_char(":"); print_two(time div 60);
- print_two(time mod 60);
- selector:=old_setting; dvi_out(cur_length);
- for s:=str_start_macro(str_ptr) to pool_ptr-1 do dvi_out(so(str_pool[s]));
- pool_ptr:=str_start_macro(str_ptr); {flush the current string}
- end
-
-@ 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)|.
-
-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)|.
-@^recursion@>
-
-@p procedure@?vlist_out; forward; {|hlist_out| and |vlist_out| are mutually
- recursive}
-
-@ 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}
-@d fin_rule=14 {go to this label to finish processing a rule}
-@d next_p=15 {go to this label when finished with node |p|}
-
-@p @t\4@>@<Declare procedures needed in |hlist_out|, |vlist_out|@>@t@>@/
-procedure 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;
-edge_h: scaled;
-effective_horizontal: scaled;
-basepoint_horizontal: scaled;
-basepoint_vertical: scaled;
-save_direction: integer;
-dir_ptr,dir_tmp:pointer;
-@!left_edge: scaled; {the left coordinate for this box}
-@!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}
-@!p,q:pointer; {current position in the hlist}
-@!save_loc:integer; {\.{DVI} byte location upon entry}
-@!leader_box:pointer; {the leader box being replicated}
-@!leader_wd:scaled; {width of leader box being replicated}
-@!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}
-@!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);
-@<DIR: Initialize |dir_ptr| for |ship_out|@>;
-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;
-@<Start hlist {\sl Sync\TeX} information record@>;
-while p<>null do @<Output node |p| for |hlist_out| and move to the next node,
- maintaining the condition |cur.v=base_line|@>;
-@<Finish hlist {\sl Sync\TeX} information record@>;
-prune_movements(save_loc);
-if cur_s>0 then dvi_pop(save_loc);
-decr(cur_s);
-dvi_direction:=save_direction;
-@<DIR: Reset |dir_ptr|@>;
-end;
-
-@ This is a cacheing attempt
-
-@d charinfo_width(#)==#.ci_wd
-@d charinfo_height(#)==#.ci_ht
-@d charinfo_depth(#)==#.ci_dp
-
-@<Types...@>=
-charinfo_short = packed record@;@/
- @!ci_wd:scaled;
- @!ci_ht:scaled;
- @!ci_dp:scaled;
- end;
-
-@ @<Glob...@>=
-ci:charinfo_short;
-
-@ We ought to give special care to the efficiency of one part of |hlist_out|,
-since it belongs to \TeX's inner loop. When a |char_node| is encountered,
-we save a little time by processing several nodes in succession until
-reaching a non-|char_node|. The program uses the fact that |set_char_0=0|.
-@^inner loop@>
-
-@<Output node |p| for |hlist_out|...@>=
-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);
- synch_pos_with_cur; f:=font(p); c:=character(p);
- ci := char_info_short(f,c);
- if f<>dvi_f then @<Change font |dvi_f| to |f|@>;
- 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)(c_wd);
- end;
- dir__RT,dir__RB: begin
- dvi_put(c);
- end;
- dir__TL,dir__TR,dir__BL,dir__BR: begin
- c_wd := c_ht + c_dp;
- dvi_put(c);
- end;
- dir__LL: begin
- pos_right(c_wd);
- dvi_put(c);
- end;
- dir__RR: begin
- pos_left(c_wd);
- dvi_put(c);
- end;
- dir__LR: begin
- dvi_set(c)(c_wd);
- end;
- dir__RL: begin
- dvi_put(c);
- end;
- dir__TT: begin
- c_wd := c_ht + c_dp;
- pos_down(c_wd);
- dvi_put(c);
- end;
- dir__TB: begin
- c_wd := c_ht + c_dp;
- dvi_put(c);
- 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)(c_wd);
- end;
- dir__LB: begin
- pos_down(c_ht);
- dvi_set(c)(c_wd);
- end;
- dir__RT: begin
- pos_left(c_wd);
- dvi_put(c);
- end;
- dir__RB: begin
- pos_down(c_ht);
- pos_left(c_wd);
- dvi_put(c);
- end;
- dir__TL: begin
- pos_down(c_ht);
- pos_left(c_wd);
- dvi_put(c);
- c_wd := c_ht + c_dp;
- end;
- dir__TR: begin
- pos_down(c_ht);
- dvi_put(c);
- c_wd := c_ht + c_dp;
- end;
- dir__BL: begin
- pos_left(c_wd);
- pos_up(c_dp);
- dvi_put(c);
- c_wd := c_ht + c_dp;
- end;
- dir__BR: begin
- pos_up(c_dp);
- dvi_put(c);
- c_wd := c_ht + c_dp;
- end;
- dir__LL,dir__LR: begin
- pos_down((c_ht - c_dp) div 2);
- dvi_set(c)(c_wd);
- end;
- dir__RL,dir__RR: begin
- pos_left(c_wd);
- pos_down((c_ht - c_dp) div 2);
- dvi_put(c);
- end;
- dir__TT,dir__TB: begin
- pos_down(c_ht);
- pos_left(c_wd div 2);
- dvi_put(c);
- c_wd:=c_ht + c_dp;
- end;
- dir__BT,dir__BB: begin
- pos_up(c_dp);
- pos_left(c_wd div 2);
- dvi_put(c);
- c_wd := c_ht + c_dp;
- 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);
- @<Record current point {\sl Sync\TeX} information@>;
- end
-else @<Output the non-|char_node| |p| for |hlist_out|
- and move to the next node@>
-
-@ @<Change font |dvi_f| to |f|@>=
-begin if not font_used(f) then
- begin dvi_font_def(f); set_font_used(f,true);
- end;
-oval:=f-font_base-1; ocmd:=fnt1; out_cmd;@/
-dvi_f:=f;
-end
-
-@ @<Output the non-|char_node| |p| for |hlist_out|...@>=
-begin case type(p) of
-hlist_node_case,vlist_node_case:@<Output a box in an hlist@>;
-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);
- end
- else begin
- rule_ht:=width(p) div 2;
- rule_dp:=width(p) div 2;
- rule_wd:=height(p)+depth(p);
- end;
- goto fin_rule;
- end;
-whatsit_node_case: @<Output the whatsit node |p| in an hlist@>;
-glue_node_case: @<Move right or output leaders@>;
-disc_node_case: if vlink(no_break(p))<>null then if subtype(p)<>select_disc 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_case:cur.h:=cur.h+width(p);
-kern_node_case: begin
- @<Record |kern_node| {\sl Sync\TeX} information@>;
- cur.h:=cur.h+width(p);
-end;
-math_node_case: begin
- @<Record |math_node| {\sl Sync\TeX} information@>;
- cur.h:=cur.h+surround(p);
-end;
-othercases do_nothing
-endcases;@/
-goto next_p;
-fin_rule: @<Output a rule in an hlist@>;
-move_past: begin
- cur.h:=cur.h+rule_wd;
- @<Record horizontal |rule_node| or |glue_node| {\sl Sync\TeX} information@>;
-end;
-next_p:p:=vlink(p);
-end
-
-@ @<Output a box in an hlist@>=
-begin
-if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction]))
- then begin
- effective_horizontal:=width(p);
- basepoint_vertical:=0;
- if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=width(p)
- else
- basepoint_horizontal:=0;
- end
-else begin
- effective_horizontal:=height(p)+depth(p);
- 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
- basepoint_horizontal:=depth(p)
- else
- if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=depth(p)
- else
- basepoint_horizontal:=height(p);
- if dir_eq(dir_secondary[box_dir(p)])(dir_primary[dvi_direction]) then
- basepoint_vertical:= -(width(p) div 2)
- else
- basepoint_vertical:= (width(p) div 2);
- end;
-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
- @<Record void list {\sl Sync\TeX} information@>;
- 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_dvi_with_cur; save_dvi:=dvi;
- save_box_pos:=box_pos;
- if type(p)=vlist_node then vlist_out@+else hlist_out;
- dvi:=save_dvi;
- box_pos:=save_box_pos;
- cur.h:=edge+effective_horizontal; cur.v:=base_line;
- end
-end
-
-@ @<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; synch_pos_with_cur;
- case box_direction(dvi_direction) of
- dir_TL_: begin
- dvi_set_rule(rule_ht)(rule_wd);
- end;
- dir_BL_: begin
- pos_down(rule_ht);
- dvi_set_rule(rule_ht)(rule_wd);
- end;
- dir_TR_: begin
- pos_left(rule_wd);
- dvi_put_rule(rule_ht)(rule_wd);
- end;
- dir_BR_: begin
- pos_left(rule_wd);
- pos_down(rule_ht);
- dvi_put_rule(rule_ht)(rule_wd);
- end;
- dir_LT_: begin
- pos_down(rule_wd);
- pos_left(rule_ht);
- dvi_set_rule(rule_wd)(rule_ht);
- end;
- dir_RT_: begin
- pos_down(rule_wd);
- dvi_put_rule(rule_wd)(rule_ht);
- end;
- dir_LB_: begin
- pos_left(rule_ht);
- dvi_set_rule(rule_wd)(rule_ht);
- end;
- dir_RB_: begin
- dvi_put_rule(rule_wd)(rule_ht);
- end;
- end;
- cur.v:=base_line;
- end
-
-@ @d billion==float_constant(1000000000)
-@d vet_glue(#)== glue_temp:=#;
- if glue_temp>billion then
- glue_temp:=billion
- else if glue_temp<-billion then
- glue_temp:=-billion
-
-@<Move right or output leaders@>=
-begin g:=glue_ptr(p); rule_wd:=width(g)-cur_g;
-if g_sign<>normal then
- begin if g_sign=stretching then
- begin if stretch_order(g)=g_order then
- begin cur_glue:=cur_glue+stretch(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
-@^real multiplication@>
- cur_g:=round(glue_temp);
- end;
- end
- else if shrink_order(g)=g_order then
- begin cur_glue:=cur_glue-shrink(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end;
-rule_wd:=rule_wd+cur_g;
-
-if subtype(p)>=a_leaders then
- @<Output leaders in an hlist, |goto fin_rule| if a rule
- or to |next_p| if done@>;
-goto move_past;
-end
-
-@ @<Output leaders in an hlist...@>=
-begin leader_box:=leader_ptr(p);
-if type(leader_box)=rule_node then
- begin rule_ht:=height(leader_box); rule_dp:=depth(leader_box);
- goto fin_rule;
- end;
-if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction]))
- then leader_wd:=width(leader_box)
-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;
- @<Let |cur.h| be the position of the first box, and set |leader_wd+lx|
- to the spacing between corresponding parts of boxes@>;
- while cur.h+leader_wd<=edge do
- @<Output a leader box at |cur.h|,
- then advance |cur.h| by |leader_wd+lx|@>;
- 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
-|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
-$|left_edge|+|leader_wd|\times\lceil
-(|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|.
-
-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|
-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.
-
-@<Let |cur.h| be the position of the first box, ...@>=
-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<save_h then cur.h:=cur.h+leader_wd;
- end
-else begin lq:=rule_wd div leader_wd; {the number of box copies}
- lr:=rule_wd mod leader_wd; {the remaining space}
- if subtype(p)=c_leaders then cur.h:=cur.h+(lr div 2)
- else begin lx:=lr div (lq+1);
- cur.h:=cur.h+((lr-(lq-1)*lx) div 2);
- end;
- end
-
-@ The `\\{synch}' operations here are intended to decrease the number of
-bytes needed to specify horizontal and vertical motion in the \.{DVI} output.
-
-@<Output a leader box at |cur.h|, ...@>=
-begin
-if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction]))
- then begin
- basepoint_vertical:=0;
- if dir_opposite(dir_secondary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=width(leader_box)
- else
- basepoint_horizontal:=0;
- end
-else begin
- 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
- basepoint_horizontal:=depth(leader_box)
- else
- if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=depth(leader_box)
- else
- basepoint_horizontal:=height(leader_box);
- if dir_eq(dir_secondary[box_dir(leader_box)])(dir_primary[dvi_direction]) then
- basepoint_vertical:= -(width(leader_box) div 2)
- else
- basepoint_vertical:= (width(leader_box) div 2);
- end;
-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_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;
-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.
-
-@p procedure vlist_out; {output a |vlist_node| box}
-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_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}
-@!p:pointer; {current position in the vlist}
-@!save_loc:integer; {\.{DVI} byte location upon entry}
-@!leader_box:pointer; {the leader box being replicated}
-@!leader_ht:scaled; {height of leader box being replicated}
-@!lx:scaled; {extra space between leader boxes}
-@!outer_doing_leaders:boolean; {were we doing leaders?}
-@!edge:scaled; {bottom boundary of leader space}
-@!glue_temp:real; {glue value before rounding}
-@!cur_glue:real; {glue seen so far}
-@!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio}
-@!save_direction: integer;
-@!effective_vertical: scaled;
-@!basepoint_horizontal: scaled;
-@!basepoint_vertical: scaled;
-@!edge_v: 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);}
-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;
-@<Start vlist {\sl Sync\TeX} information record@>;
-cur.v:=cur.v-height(this_box);
-top_edge:=cur.v;
-while p<>null do @<Output node |p| for |vlist_out| and move to the next node,
- maintaining the condition |cur.h=left_edge|@>;
-@<Finish vlist {\sl Sync\TeX} information record@>;
-prune_movements(save_loc);
-if cur_s>0 then dvi_pop(save_loc);
-decr(cur_s);
-dvi_direction:=save_direction;
-end;
-
-@ @<Output node |p| for |vlist_out|...@>=
-begin if is_char_node(p) then begin print_font_and_char(p); confusion("vlistout"); end
-@:this can't happen vlistout}{\quad vlistout@>
-else @<Output the non-|char_node| |p| for |vlist_out|@>;
-next_p:p:=vlink(p);
-end
-
-@ @<Output the non-|char_node| |p| for |vlist_out|@>=
-begin case type(p) of
-hlist_node_case,vlist_node_case:@<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);
- end
- else begin
- rule_ht:=width(p) div 2;
- rule_dp:=width(p) div 2;
- rule_wd:=height(p)+depth(p);
- end;
- goto fin_rule;
- end;
-whatsit_node_case: @<Output the whatsit node |p| in a vlist@>;
-glue_node_case: @<Move down or output leaders@>;
-kern_node_case:cur.v:=cur.v+width(p);
-othercases do_nothing
-endcases;@/
-goto next_p;
-fin_rule: @<Output a rule in a vlist, |goto next_p|@>;
-move_past: cur.v:=cur.v+rule_ht;
-end
-
-@ The |synch_v| here allows the \.{DVI} output to use one-byte commands
-for adjusting |v| in most cases, since the baselineskip distance will
-usually be constant.
-
-@<Output a box in a vlist@>=
-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
- basepoint_vertical:=depth(p)
- else
- basepoint_vertical:=height(p);
- if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=width(p)
- else
- basepoint_horizontal:=0;
- end
-else begin
- effective_vertical:=width(p);
- 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
- basepoint_horizontal:=depth(p)
- else
- if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=depth(p)
- else
- basepoint_horizontal:=height(p);
- if dir_eq(dir_secondary[box_dir(p)])(dir_primary[dvi_direction]) then
- basepoint_vertical:=0
- else
- basepoint_vertical:=width(p);
- end;
-basepoint_horizontal := basepoint_horizontal + shift_amount(p);
- {shift the box `right'}
-if list_ptr(p)=null then begin
- cur.v:=cur.v+effective_vertical;
- @<Record void list {\sl Sync\TeX} information@>;
- end
-else begin
- 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:=save_dvi;
- box_pos:=save_box_pos;
- cur.h:=left_edge; cur.v:=edge_v + effective_vertical;
- end
-end
-
-@ @<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 synch_pos_with_cur;
- case box_direction(dvi_direction) of
- dir_TL_: begin
- dvi_put_rule(rule_ht)(rule_wd);
- end;
- dir_BL_: begin
- pos_down(rule_ht);
- dvi_put_rule(rule_ht)(rule_wd);
- end;
- dir_TR_: begin
- pos_left(rule_wd);
- dvi_set_rule(rule_ht)(rule_wd);
- end;
- dir_BR_: begin
- pos_down(rule_ht);
- pos_left(rule_wd);
- dvi_set_rule(rule_ht)(rule_wd);
- end;
- dir_LT_: begin
- pos_down(rule_wd);
- pos_left(rule_ht);
- dvi_set_rule(rule_wd)(rule_ht);
- end;
- dir_RT_: begin
- pos_down(rule_wd);
- dvi_put_rule(rule_wd)(rule_ht);
- end;
- dir_LB_: begin
- pos_left(rule_ht);
- dvi_set_rule(rule_wd)(rule_ht);
- end;
- dir_RB_: begin
- dvi_put_rule(rule_wd)(rule_ht);
- end;
- end;
- end;
-goto next_p
-
-@ @<Move down or output leaders@>=
-begin g:=glue_ptr(p); rule_ht:=width(g)-cur_g;
-if g_sign<>normal then
- begin if g_sign=stretching then
- begin if stretch_order(g)=g_order then
- begin cur_glue:=cur_glue+stretch(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
-@^real multiplication@>
- cur_g:=round(glue_temp);
- end;
- end
- else if shrink_order(g)=g_order then
- begin cur_glue:=cur_glue-shrink(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end;
-rule_ht:=rule_ht+cur_g;
-if subtype(p)>=a_leaders then
- @<Output leaders in a vlist, |goto fin_rule| if a rule
- or to |next_p| if done@>;
-goto move_past;
-end
-
-@ @<Output leaders in a vlist...@>=
-begin leader_box:=leader_ptr(p);
-if type(leader_box)=rule_node then
- begin rule_wd:=width(leader_box); rule_dp:=0;
- goto fin_rule;
- end;
-if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction]))
- then leader_ht:=height(leader_box)+depth(leader_box)
-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;
- @<Let |cur.v| be the position of the first box, and set |leader_ht+lx|
- to the spacing between corresponding parts of boxes@>;
- while cur.v+leader_ht<=edge do
- @<Output a leader box at |cur.v|,
- then advance |cur.v| by |leader_ht+lx|@>;
- cur.v:=edge-10; goto next_p;
- end;
-end
-
-@ @<Let |cur.v| be the position of the first box, ...@>=
-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<save_v then cur.v:=cur.v+leader_ht;
- end
-else begin lq:=rule_ht div leader_ht; {the number of box copies}
- lr:=rule_ht mod leader_ht; {the remaining space}
- if subtype(p)=c_leaders then cur.v:=cur.v+(lr div 2)
- else begin lx:=lr div (lq+1);
- cur.v:=cur.v+((lr-(lq-1)*lx) div 2);
- end;
- end
-
-@ When we reach this part of the program, |cur.v| indicates the top of a
-leader box, not its baseline.
-
-@<Output a leader box at |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
- basepoint_vertical:=depth(leader_box)
- else
- basepoint_vertical:=height(leader_box);
- if dir_opposite(dir_secondary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=width(leader_box)
- else
- basepoint_horizontal:=0;
- end
-else begin
- effective_vertical:=width(leader_box);
- 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
- basepoint_horizontal:=depth(leader_box)
- else
- if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=depth(leader_box)
- else
- basepoint_horizontal:=height(leader_box);
- if dir_eq(dir_secondary[box_dir(leader_box)])(dir_primary[dvi_direction]) then
- basepoint_vertical:= width(leader_box)
- else
- basepoint_vertical:= 0;
- end;
-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_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;
-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
-ready for the |dvi_ship_out| routine that gets them started in the first place.
-
-@p procedure dvi_ship_out(@!p:pointer); {output the box |p|}
-label done;
-var page_loc:integer; {location of the current |bop|}
-@!j,@!k:0..9; {indices to first ten count registers}
-@!s:pool_pointer; {index into |str_pool|}
-@!old_setting:0..max_selector; {saved |selector| setting}
-pre_callback_id:integer;
-post_callback_id:integer;
-ret:boolean;
-begin
-@<Start sheet {\sl Sync\TeX} information record@>;
-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 pre_callback_id>0 then
- ret:=run_callback(pre_callback_id,'->')
-else if pre_callback_id=0 then begin
- if term_offset>max_print_line-9 then print_ln
- else if (term_offset>0)or(file_offset>0) then print_char(" ");
- print_char("["); j:=9;
- while (count(j)=0)and(j>0) do decr(j);
- for k:=0 to j do
- begin print_int(count(k));
- if k<j then print_char(".");
- end;
- end;
-update_terminal;
-if (tracing_output>0)and(post_callback_id=0) then
- begin print_char("]");
- begin_diagnostic; show_box(p); end_diagnostic(true);
- end;
-@<Ship box |p| out@>;
-if (tracing_output<=0)and(post_callback_id=0) then
- print_char("]");
-dead_cycles:=0;
-update_terminal; {progress report}
-@<Flush the box from memory, showing statistics if requested@>;
-if post_callback_id>0 then
- ret:=run_callback(post_callback_id,'->');
-@<Finish sheet {\sl Sync\TeX} information record@>;
-end;
-
-@ @<Flush the box from memory, showing statistics if requested@>=
-@!stat if (tracing_stats>1)and(pre_callback_id=0) then
- begin print_nl("Memory usage before: ");
-@.Memory usage...@>
- print_int(var_used); print_char("&");
- print_int(dyn_used); print_char(";");
- end;
-tats@/
-flush_node_list(p);
-@!stat if (tracing_stats>1)and(post_callback_id=0) then
- begin print(" after: ");
- print_int(var_used); print_char("&");
- print_int(dyn_used); print_ln;
- end;
-tats
-
-@ @<Ship box |p| out@>=
-if box_dir(p) <> page_direction then
- pdf_warning("\shipout", "\pagedir != \bodydir; \box255 may be placed wrongly on the page.", true, true);
-@<Update the values of |max_h| and |max_v|; but if the page is too large,
- |goto done|@>;
-@<Initialize variables as |ship_out| begins@>;
-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 := h_offset;
- cur.v := v_offset;
- end;
-dir_TR_,dir_RT_: begin
- cur.h := cur_page_size.h - page_right_offset - one_true_inch;
- cur.v := v_offset;
- end;
-dir_BL_,dir_LB_: begin
- cur.h := h_offset;
- cur.v := cur_page_size.v - page_bottom_offset - one_true_inch;
- end;
-dir_RB_,dir_BR_: begin
- cur.h := cur_page_size.h - page_right_offset - one_true_inch;
- cur.v := cur_page_size.v - page_bottom_offset - one_true_inch;
- end;
-end;
-{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;
-done:
-
-@ Sometimes the user will generate a huge page because other error messages
-are being ignored. Such pages are not output to the \.{dvi} file, since they
-may confuse the printing software.
-
-@<Update the values of |max_h| and |max_v|; but if the page is too large...@>=
-if (height(p)>max_dimen)or@|(depth(p)>max_dimen)or@|
- (height(p)+depth(p)+v_offset>max_dimen)or@|
- (width(p)+h_offset>max_dimen) then
- begin print_err("Huge page cannot be shipped out");
-@.Huge page...@>
- help2("The page just created is more than 18 feet tall or")@/
- ("more than 18 feet wide, so I suspect something went wrong.");
- error;
- if tracing_output<=0 then
- begin begin_diagnostic;
- print_nl("The following box has been deleted:");
-@.The following...deleted@>
- show_box(p);
- end_diagnostic(true);
- end;
- goto done;
- end;
-if height(p)+depth(p)+v_offset>max_v then max_v:=height(p)+depth(p)+v_offset;
-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. And if
-|max_push>=65536|, the user deserves whatever chaos might ensue.
-
-An integer variable |k| will be declared for use by this routine.
-
-@<Finish the \.{DVI} file@>=
-while cur_s>-1 do
- begin if cur_s>0 then dvi_out(pop)
- else begin dvi_out(eop); incr(total_pages);
- end;
- decr(cur_s);
- end;
-if total_pages=0 then begin
- if callback_id=0 then
- print_nl("No pages of output.")
- else if callback_id>0 then
- res:=run_callback(callback_id,'->');
- end
-@.No pages of output@>
-else begin dvi_out(post); {beginning of the postamble}
- dvi_four(last_bop); last_bop:=dvi_offset+dvi_ptr-5; {|post| location}
- dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp}
- prepare_mag; dvi_four(mag); {magnification factor}
- dvi_four(max_v); dvi_four(max_h);@/
- dvi_out(max_push div 256); dvi_out(max_push mod 256);@/
- dvi_out((total_pages div 256) mod 256); dvi_out(total_pages mod 256);@/
- @<Output the font definitions for all fonts that were used@>;
- dvi_out(post_post); dvi_four(last_bop); dvi_out(id_byte);@/
- k:=4+((dvi_buf_size-dvi_ptr) mod 4); {the number of 223's}
- while k>0 do
- begin dvi_out(223); decr(k);
- end;
- @<Empty the last bytes out of |dvi_buf|@>;
- if callback_id=0 then begin
- print_nl("Output written on "); slow_print(output_file_name);
-@.Output written on x@>
- print(" ("); print_int(total_pages); print(" page");
- if total_pages<>1 then print_char("s");
- print(", "); print_int(dvi_offset+dvi_ptr); print(" bytes).");
- end
- else if callback_id>0 then
- res:=run_callback(callback_id,'->');
- b_close(dvi_file);
- end
-
-@ @<Output the font definitions...@>=
-k := max_font_id;
-while k>0 do
- begin if font_used(k) then dvi_font_def(k);
- decr(k);
- end
-
-
-@* \[32a] \pdfTeX\ basic.
-
-Initialize \pdfTeX's parameters to some useful default value.
-Helpful in case one forgets to set them during initex run.
-
-@<Initialize table entries...@>=
-pdf_h_origin := one_inch;
-pdf_v_origin := one_inch;
-pdf_compress_level := 9;
-pdf_objcompresslevel := 0;
-pdf_decimal_digits := 3;
-pdf_image_resolution := 72;
-pdf_minor_version := 4;
-pdf_gamma := 1000;
-pdf_image_gamma := 2200;
-pdf_image_hicolor := 1;
-pdf_image_apply_gamma := 0;
-pdf_px_dimen := one_bp;
-pdf_draftmode := 0;
-
-@ The subroutines define the corresponding macros so we can use them
-in C.
-
-@d flushable(#) == (# = str_ptr - 1)
-
-@d is_valid_char(#) == char_exists(f,#)
-
-@p function get_pdf_compress_level: integer;
-begin
- get_pdf_compress_level := pdf_compress_level;
-end;
-
-function get_nullfont: internal_font_number;
-begin
- get_nullfont := null_font;
-end;
-
-function get_luatexversion: integer;
-begin
- get_luatexversion := luatex_version;
-end;
-
-function get_luatexrevision: str_number;
-begin
- get_luatexrevision := luatex_revision;
-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;
-end;
-
-function get_undefined_control_sequence: integer;
-begin
- get_undefined_control_sequence := undefined_control_sequence;
-end;
-
-function get_fontbase: internal_font_number;
-begin
- get_fontbase := font_base;
-end;
-
-function get_nullcs: pointer;
-begin
- get_nullcs := null_cs;
-end;
-
-function get_nullptr: pointer;
-begin
- get_nullptr := null;
-end;
-
-function get_tex_int(code: integer): integer;
-begin
- get_tex_int := int_par(code);
-end;
-
-function get_tex_dimen(code: integer): scaled;
-begin
- get_tex_dimen := dimen_par(code);
-end;
-
-
-function get_x_height(f: internal_font_number): scaled;
-begin
- get_x_height := x_height(f);
-end;
-
-function get_charwidth(f: internal_font_number; c: integer): scaled;
-begin
- if is_valid_char(c) then
- get_charwidth := char_width(f,c)
- else
- get_charwidth := 0;
-end;
-
-function get_charheight(f: internal_font_number; c: integer): scaled;
-begin
- if is_valid_char(c) then
- get_charheight := char_height(f,c)
- else
- get_charheight := 0;
-end;
-
-function get_chardepth(f: internal_font_number; c: integer): scaled;
-begin
- if is_valid_char(c) then
- get_chardepth := char_depth(f,c)
- else
- get_chardepth := 0;
-end;
-
-function get_quad(f: internal_font_number): scaled;
-begin
- get_quad := quad(f);
-end;
-
-function get_slant(f: internal_font_number): scaled;
-begin
- get_slant := slant(f);
-end;
-
-function new_dummy_font: internal_font_number;
-begin
- new_dummy_font := read_font_info(null_cs, "dummy", -1000, -1);
-end;
-
-function get_hash_size: integer;
-begin
- get_hash_size:= hash_size;
-end;
-
-function get_eqtb_size: integer;
-begin
- get_eqtb_size:= eqtb_size;
-end;
-
-function get_hash_base: integer;
-begin
- get_hash_base:= hash_base;
-end;
-
-function get_font_id_base: integer;
-begin
- get_font_id_base:= font_id_base;
-end;
-
-
-function get_cur_font: internal_font_number;
-begin
- get_cur_font:= cur_font;
-end;
-
-procedure set_cur_font (f: internal_font_number);
-var a:small_number;
-begin
- a:=0;
- define(cur_font_loc,data,f);
-end;
-
-function get_current_name: str_number;
-begin
- get_current_name:= name;
-end;
-
-
-@ Helper for debugging purposes
-
-@p procedure short_display_n(@!p, m:integer); {prints highlights of list |p|}
-var i: integer;
-begin
-i := 0;
-font_in_short_display:=null_font;
-if p = null then
- return;
-while p<>null do
- begin if is_char_node(p) then
- begin if p<=max_halfword then
- begin if font(p)<>font_in_short_display then
- begin if not is_valid_font(font(p)) then
- print_char("*")
-@.*\relax@>
- else print_font_identifier(font(p));
- print_char(" "); font_in_short_display:=font(p);
- end;
- print(qo(character(p)));
- end;
- end
- else begin
- if (type(p) = glue_node) or
- (type(p) = disc_node) or
- (type(p) = penalty_node) or
- ((type(p) = kern_node) and (subtype(p) = explicit)) then
- incr(i);
- if i >= m then
- return;
- if (type(p) = disc_node) then begin
- print("|");
- short_display(vlink(pre_break(p)));
- print("|");
- short_display(vlink(post_break(p)));
- print("|");
- end
- else
- @<Print a short indication of the contents of node |p|@>;
- end;
- p:=vlink(p);
- if p = null then
- return;
- end;
- update_terminal;
-end;
-
-@ Sometimes it is neccesary to allocate memory for PDF output that cannot
-be deallocated then, so we use |pdf_mem| for this purpose.
-
-@<Constants...@>=
-@!inf_pdf_mem_size = 10000; {min size of the |pdf_mem| array}
-@!sup_pdf_mem_size = 10000000; {max size of the |pdf_mem| array}
-
-@ @<Glob...@>=
-@!pdf_mem_size: integer;
-@!pdf_mem: ^integer;
-@!pdf_mem_ptr: integer;
-
-@ @<Set init...@>=
-pdf_mem_ptr := 1; {the first word is not used so we can use zero as a value for testing
-whether a pointer to |pdf_mem| is valid}
-pdf_mem_size := inf_pdf_mem_size; {allocated size of |pdf_mem| array}
-
-@ We use |pdf_get_mem| to allocate memory in |pdf_mem|
-
-@p function pdf_get_mem(s: integer): integer; {allocate |s| words in |pdf_mem|}
-var a: integer;
-begin
- if s > sup_pdf_mem_size - pdf_mem_ptr then
- overflow("PDF memory size (pdf_mem_size)", pdf_mem_size);
- if pdf_mem_ptr + s > pdf_mem_size then begin
- a := 0.2 * pdf_mem_size;
- if pdf_mem_ptr + s > pdf_mem_size + a then
- pdf_mem_size := pdf_mem_ptr + s
- else if pdf_mem_size < sup_pdf_mem_size - a then
- pdf_mem_size := pdf_mem_size + a
- else
- pdf_mem_size := sup_pdf_mem_size;
- pdf_mem := xreallocarray(pdf_mem, integer, pdf_mem_size);
- end;
- pdf_get_mem := pdf_mem_ptr;
- pdf_mem_ptr := pdf_mem_ptr + s;
-end;
-
-@* \[32b] \pdfTeX\ output low-level subroutines.
-We use the similiar subroutines to handle the output buffer for
-PDF output. When compress is used, the state of writing to buffer
-is held in |zip_write_state|. We must write the header of PDF
-output file in initialization to ensure that it will be the first
-written bytes.
-
-@<Constants...@>=
-@!pdf_op_buf_size = 16384; {size of the PDF output buffer}
-@!inf_pdf_os_buf_size = 1; {initial value of |pdf_os_buf_size|}
-@!sup_pdf_os_buf_size = 5000000; {arbitrary upper hard limit of |pdf_os_buf_size|}
-@!pdf_os_max_objs = 100; {maximum number of objects in object stream}
-
-@ The following macros are similar as for \.{DVI} buffer handling
-
-@d pdf_offset == (pdf_gone + pdf_ptr) {the file offset of last byte in PDF
-buffer that |pdf_ptr| points to}
-
-@d no_zip == 0 {no \.{ZIP} compression}
-@d zip_writing == 1 {\.{ZIP} compression being used}
-@d zip_finish == 2 {finish \.{ZIP} compression}
-
-@d pdf_quick_out(#) == {output a byte to PDF buffer without checking of
-overflow}
-begin
- pdf_buf[pdf_ptr] := #;
- incr(pdf_ptr);
-end
-
-@d pdf_out(#) == {do the same as |pdf_quick_out| and flush the PDF
-buffer if necessary}
-begin
- pdf_room(1);
- pdf_quick_out(#);
-end
-
-@<Glob...@>=
-@!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: 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}
-@!pdf_os_objnum: ^integer; {array of object numbers within object stream}
-@!pdf_os_objoff: ^integer; {array of object offsets within object stream}
-@!pdf_os_objidx: pointer; {pointer into |pdf_os_objnum| and |pdf_os_objoff|}
-@!pdf_os_cntr: integer; {counter for object stream objects}
-@!pdf_op_ptr: integer; {store for PDF buffer |pdf_ptr| while inside object streams}
-@!pdf_os_ptr: integer; {store for object stream |pdf_ptr| while outside object streams}
-@!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: 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}
-@!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;
-@!page_divert_val: integer;
-
-@ @<Set init...@>=
-pdf_gone := 0;
-pdf_os_mode := false;
-pdf_ptr := 0;
-pdf_op_ptr := 0;
-pdf_os_ptr := 0;
-pdf_os_cur_objnum := 0;
-pdf_os_cntr := 0;
-pdf_buf_size := pdf_op_buf_size;
-pdf_os_buf_size := inf_pdf_os_buf_size;
-pdf_buf := pdf_op_buf;
-pdf_seek_write_length := false;
-zip_write_state := no_zip;
-fixed_pdf_minor_version_set := false;
-fixed_pdfoutput_set := false;
-pdf_page_group_val := -1;
-page_divert_val := 0;
-
-@ @p
-function fix_int(val, min, max: integer): integer;
-begin
- if val < min then
- fix_int := min
- else if val > max then
- fix_int := max
- else
- fix_int := val;
-end;
-
-@ This ensures that |pdfminorversion| is set only before any bytes have
-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
- fix_pdfoutput;
- pdfassert(fixed_pdfoutput > 0);
- if not fixed_pdf_minor_version_set then begin
- fixed_pdf_minor_version_set := true;
- @<Initialize variables for \.{PDF} output@>;
- @<Write \.{PDF} header@>;
- end
- else begin
- @<Check that variables for \.{PDF} output are unchanged@>;
- 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;
-
-@ @<Initialize variables for \.{PDF} output@>=
-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;
-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;
-pdf_page_init
-
-@ @<Check that variables for \.{PDF} output are unchanged@>=
-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");
-
-@ @<Write \.{PDF} header@>=
-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);
- pdf_gone := pdf_gone + pdf_ptr;
- pdf_last_byte := pdf_buf[pdf_ptr - 1];
- end;
- zip_writing:
- if fixed_pdf_draftmode = 0 then write_zip(false);
- zip_finish: begin
- if fixed_pdf_draftmode = 0 then write_zip(true);
- zip_write_state := no_zip;
- 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;
-
-procedure pdf_begin_stream; {begin a stream}
-begin
- pdf_print_ln("/Length ");
- 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(">>");
- pdf_print_ln("stream");
- pdf_flush;
- zip_write_state := zip_writing;
- end
- else begin
- pdf_print_ln(">>");
- pdf_print_ln("stream");
- pdf_save_offset := pdf_offset;
- end;
-end;
-
-procedure pdf_end_stream; {end a stream}
-begin
- if zip_write_state = zip_writing then
- zip_write_state := zip_finish
- else
- pdf_stream_length := pdf_offset - pdf_save_offset;
- pdf_flush;
- if pdf_seek_write_length then
- write_stream_length(pdf_stream_length, pdf_stream_length_offset);
- pdf_seek_write_length := false;
- if pdf_last_byte <> pdf_new_line_char then
- pdf_out(pdf_new_line_char);
- pdf_print_ln("endstream");
- pdf_end_obj;
-end;
-
-@ Basic printing procedures for PDF output are very similiar to \TeX\ basic
-printing ones but the output is going to PDF buffer. Subroutines with
-suffix |_ln| append a new-line character to the PDF output.
-
-@d pdf_new_line_char == 10 {new-line character for UNIX platforms}
-
-@d pdf_print_nl == {output a new-line character to PDF buffer}
-pdf_out(pdf_new_line_char)
-
-@d pdf_print_ln(#) == {print out a string to PDF buffer followed by
-a new-line character}
-begin
- pdf_print(#);
- pdf_print_nl;
-end
-
-@d pdf_print_int_ln(#) == {print out an integer to PDF buffer followed by
-a new-line character}
-begin
- pdf_print_int(#);
- pdf_print_nl;
-end
-
-@<Declare procedures that need to be declared forward for \pdfTeX@>=
-procedure pdf_error(t, p: str_number);
-begin
- normalize_selector;
- print_err("LuaTeX error");
- if t <> 0 then begin
- print(" (");
- print(t);
- print(")");
- end;
- print(": "); print(p);
- succumb;
-end;
-
-procedure pdf_warning(t, p: str_number; prepend_nl, append_nl: boolean);
-begin
- if interaction = error_stop_mode then
- wake_up_terminal;
- if prepend_nl then
- print_ln;
- print("LuaTeX warning");
- if t <> 0 then begin
- print(" (");
- print(t);
- print(")");
- end;
- print(": "); print(p);
- if append_nl then
- print_ln;
- if history=spotless then history:=warning_issued;
-end;
-
-procedure pdf_os_get_os_buf(s: integer); {check that |s| bytes more
-fit into |pdf_os_buf|; increase it if required}
-var a: integer;
-begin
- if s > sup_pdf_os_buf_size - pdf_ptr then
- overflow("PDF object stream buffer", pdf_os_buf_size);
- if pdf_ptr + s > pdf_os_buf_size then begin
- a := 0.2 * pdf_os_buf_size;
- if pdf_ptr + s > pdf_os_buf_size + a then
- pdf_os_buf_size := pdf_ptr + s
- else if pdf_os_buf_size < sup_pdf_os_buf_size - a then
- pdf_os_buf_size := pdf_os_buf_size + a
- else
- pdf_os_buf_size := sup_pdf_os_buf_size;
- pdf_os_buf := xreallocarray(pdf_os_buf, real_eight_bits, pdf_os_buf_size);
- pdf_buf := pdf_os_buf;
- pdf_buf_size := pdf_os_buf_size;
- end;
-end;
-
-procedure pdf_room(n: integer); {make sure that there are at least |n| bytes free in PDF buffer}
-begin
- if pdf_os_mode and (n + pdf_ptr > pdf_buf_size) then
- pdf_os_get_os_buf(n)
- else if not pdf_os_mode and (n > pdf_buf_size) then
- overflow("PDF output buffer", pdf_op_buf_size)
- else if not pdf_os_mode and (n + pdf_ptr > pdf_buf_size) then
- pdf_flush;
-end;
-
-procedure remove_last_space;
-begin
- if (pdf_ptr > 0) and (pdf_buf[pdf_ptr - 1] = 32) then
- decr(pdf_ptr);
-end;
-
-function str_in_str(s, r: str_number; i: integer): boolean;
- {test equality of strings}
-label not_found; {loop exit}
-var j, k: pool_pointer; {running indices}
-begin
- str_in_str := false;
- if length(s) < i + length(r) then
- return;
- j := i + str_start_macro(s);
- k := str_start_macro(r);
- while (j < str_start_macro(s + 1)) and (k < str_start_macro(r + 1)) do begin
- if str_pool[j] <> str_pool[k] then
- return;
- incr(j);
- incr(k);
- end;
- str_in_str := true;
-end;
-
-function tokens_to_string(p: pointer): str_number; {return a string from tokens
-list}
-var old_setting:integer;
-begin
- if selector = new_string then
- pdf_error("tokens", "tokens_to_string() called while selector = new_string");
- old_setting:=selector; selector:=new_string;
- show_token_list(link(p),null,pool_size-pool_ptr);
- selector:=old_setting;
- last_tokens_string := make_string;
- tokens_to_string := last_tokens_string;
-end;
-
-
-@ To print |scaled| value to PDF output we need some subroutines to ensure
-accurary.
-
-@d max_integer == @"7FFFFFFF {$2^{31}-1$}
-@d call_func(#) == begin if # <> 0 then do_nothing end
-
-
-@<Glob...@>=
-@!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$}
-
-@ @<Set init...@>=
-one_hundred_inch := 7227 * 65536; {exact, 473628672}
-one_inch := (one_hundred_inch + 50) div 100; {rounded to 4736287}
-one_true_inch := one_inch;
-one_hundred_bp := one_hundred_inch div 72; {exact, 6578176}
-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];
-
-@ 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
-for optimizations that are not possible in pascal.
-
-@<Declare procedures that need to be declared forward for \pdfTeX@>=
-function round_xn_over_d(@!x:scaled; @!n,@!d:integer):scaled;
-var positive:boolean; {was |x>=0|?}
-@!t,@!u,@!v:nonnegative_integer; {intermediate quantities}
-begin if x>=0 then positive:=true
-else begin negate(x); positive:=false;
- end;
-t:=(x mod @'100000)*n;
-u:=(x div @'100000)*n+(t div @'100000);
-v:=(u mod d)*@'100000 + (t mod @'100000);
-if u div d>=@'100000 then arith_error:=true
-else u:=@'100000*(u div d) + (v div d);
-v := v mod d;
-if 2*v >= d then
- incr(u);
-if positive then
- round_xn_over_d := u
-else
- round_xn_over_d := -u;
-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),
- fixed_decimal_digits);
-end;
-
-procedure pdf_print_mag_bp(s: scaled); {take |mag| into account}
-begin
- prepare_mag;
- if mag <> 1000 then
- s := round_xn_over_d(s, mag, 1000);
- pdf_print_bp(s);
-end;
-
-@* \[32c] PDF page description.
-
-@<Glob...@>=
-@!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;
-
-@ @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
- 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);
- if pdf_move_chars > 0 then begin
- pdf_warning(0,"Primitive \pdfmovechars is obsolete.",true, true);
- pdf_move_chars := 0; {warn only once}
- end;
-end;
-
-@ To set PDF font we need to find out fonts with the same name, because \TeX\
-can load the same font several times for various sizes. For such fonts we
-define only one font resource. The array |pdf_font_num| holds the object
-number of font resource. A negative value of an entry of |pdf_font_num|
-indicates that the corresponding font shares the font resource with the font
-
-@d pdf_print_resname_prefix ==
-if pdf_resname_prefix <> 0 then
- pdf_print(pdf_resname_prefix)
-
-@p procedure pdf_init_font(f: internal_font_number);
-{create a font object}
-var k, b: internal_font_number;
- i: integer;
-begin
- pdfassert(not font_used(f));
-
- {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}
- 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
- pdf_init_font(b);
- set_font_map(f,font_map(b));
- end;
-
- {check whether |f| can share the font object with some |k|: we have 2 cases
- here: 1) |f| and |k| have the same tfm name (so they have been loaded at
- different sizes, eg 'cmr10' and 'cmr10 at 11pt'); 2) |f| has been auto
- expanded from |k|}
- if hasfmentry(f) or true then begin
- i := head_tab[obj_type_font];
- while i <> 0 do begin
- k := obj_info(i);
- if font_shareable(f,k) then
- begin
- pdfassert(pdf_font_num(k) <> 0);
- if pdf_font_num(k) < 0 then
- pdf_use_font(f, pdf_font_num(k))
- else
- pdf_use_font(f, -k);
- return;
- end;
- i := obj_link(i);
- end;
- end;
-
- {create a new font object for |f|}
- pdf_create_obj(obj_type_font, f);
- pdf_use_font(f, obj_ptr);
-end;
-
-procedure pdf_init_font_cur_val;
-begin
- pdf_init_font(cur_val);
-end;
-
-function pdf_set_font(f: internal_font_number): internal_font_number;
-{set the actual font on PDF page}
-label found, found1;
-var p: pointer;
- k: internal_font_number;
-begin
- if not font_used(f) then
- pdf_init_font(f);
- set_ff(f); {set |ff| to the tfm number of the font sharing the font object
- with |f|; |ff| is either |f| or some font with the same tfm name
- at different size and/or expansion}
- k := ff;
- p := pdf_font_list;
- while p <> null do begin
- set_ff(info(p));
- if ff = k then
- goto found;
- p := link(p);
- end;
- pdf_append_list(f)(pdf_font_list); {|f| not found in |pdf_font_list|, append it now}
-found:
- pdf_set_font := k;
-end;
-
-@ @p
-procedure literal(s: str_number; literal_mode: integer; warn: boolean);
-var j: pool_pointer; {current character code position}
-begin
- if s>string_offset then begin { needed for |out_save| }
- j:=str_start_macro(s);
- if literal_mode = scan_special then begin
- if not (str_in_str(s, "PDF:", 0) or str_in_str(s, "pdf:", 0)) then begin
- if warn and not (str_in_str(s, "SRC:", 0)
- or str_in_str(s, "src:", 0)
- or (length(s) = 0)) then
- print_nl("Non-PDF special ignored!");
- return;
- end;
- j := j + length("PDF:");
- if str_in_str(s, "direct:", length("PDF:")) then begin
- j := j + length("direct:");
- literal_mode := direct_always; end
- else if str_in_str(s, "page:", length("PDF:")) then begin
- j := j + length("page:");
- literal_mode := direct_page; end
- else
- literal_mode := set_origin;
- end;
- end;
- case literal_mode of
- set_origin: begin
- pdf_goto_pagemode;
- synch_pos_with_cur;
- pdf_set_pos(pos.h, pos.v);
- end;
- direct_page:
- pdf_goto_pagemode;
- direct_always:
- pdf_end_string_nl;
- othercases confusion("literal1")
- endcases;
- if s>string_offset then
- while j<str_start_macro(s+1) do begin
- pdf_out(str_pool[j]);
- incr(j);
- end
- else
- pdf_out(s);
- pdf_print_nl;
-end;
-
-procedure latelua(s: pointer; r: pointer);
-var b: pool_pointer; {current character code position}
-begin
- b := pool_ptr;
- luacall(s,r);
- if b<pool_ptr then begin
- pdf_goto_pagemode;
- while b<pool_ptr do begin
- pdf_out(str_pool[b]);
- incr(b);
- end;
- pdf_print_nl;
- end;
-end;
-
-@* \[32d] The cross-reference table.
-
-The cross-reference table |obj_tab| is an array of |obj_tab_size| of
-|obj_entry|. Each entry contains five integer fields and represents an object
-in PDF file whose object number is the index of this entry in |obj_tab|.
-Objects in |obj_tab| maybe linked into list; objects in such a linked list have
-the same type.
-
-@<Types...@>=
-@!obj_entry = record@;@/
- int0, int1: integer;
- int2: longinteger;
- int3, int4: integer;
-end;
-
-@ The first field contains information representing identifier of this object.
-It is usally a number for most of object types, but it may be a string number
-for named destination or named thread.
-
-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. 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.
-
-The last field usually represents the pointer to some auxiliary data
-structure depending on the object type; however it may be used as a counter as
-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 {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 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_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 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_ann_left| and |pdf_ann_top| are used for some types of destinations}
-
-@# {coordinates of destinations/threads/annotations (in whatsit node)}
-@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
-@d pdf_height(#) == vmem(# + 3).sc
-@d pdf_depth(#) == vmem(# + 4).sc
-
-@# {data structure for \.{\\pdfliteral}}
-@d pdf_literal_data(#) == vlink(#+2) {data}
-@d pdf_literal_mode(#) == type(#+2) {mode of resetting the text matrix
- while writing data to the page stream}
-@d pdf_literal_type(#) == subtype(#+2) {indicates whether data is a |str_number| or
- something else}
-@# {modes of setting the current transformation matrix (CTM)}
-@d set_origin == 0 {end text (ET) if needed, set CTM to current point}
-@d direct_page == 1 {end text (ET) if needed, but don't change the CTM}
-@d direct_always == 2 {don't end text, don't change the CTM}
-@d scan_special == 3 {look into special text}
-
-@# {data structure for \.{\\pdfcolorstack}}
-@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}
-
-@# {color stack commands}
-@d colorstack_set == 0
-@d colorstack_push == 1
-@d colorstack_data == 1 { last value where data field is set }
-@d colorstack_pop == 2
-@d colorstack_current == 3
-
-@# {data structure for \.{\\pdfsetmatrix}}
-@d pdf_setmatrix_data(#) == vlink(#+2) {data}
-
-@# {data structure for \.{\\pdfsave}}
-
-@# {data structure for \.{\\pdfrestore}}
-
-@# {data structure for \.{\\latelua}}
-@d late_lua_data == write_tokens {data}
-@d late_lua_name(#) == vlink(#+3) {name}
-
-@# {data structure for \.{\\pdfobj} and \.{\\pdfrefobj}}
-@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}
-@d obj_obj_data(#) == pdf_mem[obj_data_ptr(#) + 0] {object data}
-@d obj_obj_is_stream(#) == pdf_mem[obj_data_ptr(#) + 1] {will this object
- be written as a stream instead of a dictionary?}
-@d obj_obj_stream_attr(#) == pdf_mem[obj_data_ptr(#) + 2] {additional
- object attributes for streams}
-@d obj_obj_is_file(#) == pdf_mem[obj_data_ptr(#) + 3] {data should be
- read from an external file?}
-
-@# {data structure for \.{\\pdfxform} and \.{\\pdfrefxform}}
-@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]
-@d obj_xform_box(#) == pdf_mem[obj_data_ptr(#) + 3] {this field holds
- pointer to the corresponding box}
-@d obj_xform_attr(#) == pdf_mem[obj_data_ptr(#) + 4] {additional xform
- attributes}
-@d obj_xform_resources(#) == pdf_mem[obj_data_ptr(#) + 5] {additional xform
- Resources}
-
-@# {data structure for \.{\\pdfximage} and \.{\\pdfrefximage}}
-@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_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}
-@d pdf_annot_objnum(#) == vmem(# + 7).int {object number of corresponding object}
-@d pdf_link_objnum(#) == vmem(# + 7).int {object number of corresponding object}
-
-@# {types of actions}
-@d pdf_action_page == 0 {GoTo action}
-@d pdf_action_goto == 1 {GoTo action}
-@d pdf_action_thread == 2 {Thread action}
-@d pdf_action_user == 3 {user-defined action}
-
-@# {data structure of actions}
-@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}
-@d pdf_action_file(#) == vinfo(# + 2) {file name for external action}
-@d pdf_action_new_window(#) == vlink(# + 2) {open a new window?}
-@d pdf_action_tokens(#) == vinfo(# + 3) {specification of GoTo page or user action}
-@d pdf_action_refcount(#) == vlink(# + 3) {counter of references to this action}
-
-@# {data structure of outlines; it's not able to write out outline entries
-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}
-@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(#)]
-@d obj_outline_parent(#) == pdf_mem[obj_outline_ptr(#) + 1]
-@d obj_outline_prev(#) == pdf_mem[obj_outline_ptr(#) + 2]
-@d obj_outline_next(#) == pdf_mem[obj_outline_ptr(#) + 3]
-@d obj_outline_first(#) == pdf_mem[obj_outline_ptr(#) + 4]
-@d obj_outline_last(#) == pdf_mem[obj_outline_ptr(#) + 5]
-@d obj_outline_action_objnum(#) == pdf_mem[obj_outline_ptr(#) + 6] {object number of
-action}
-@d obj_outline_attr(#) == pdf_mem[obj_outline_ptr(#) + 7]
-
-@# {types of destinations}
-@d pdf_dest_xyz == 0
-@d pdf_dest_fit == 1
-@d pdf_dest_fith == 2
-@d pdf_dest_fitv == 3
-@d pdf_dest_fitb == 4
-@d pdf_dest_fitbh == 5
-@d pdf_dest_fitbv == 6
-@d pdf_dest_fitr == 7
-
-@# {data structure of destinations}
-@d obj_dest_ptr == obj_aux {pointer to |pdf_dest_node|}
-@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}
-@d pdf_dest_xyz_zoom(#) == vinfo(# + 7) {zoom factor for |destxyz| destination}
-@d pdf_dest_objnum(#) == vlink(# + 7) {object number of corresponding
-object}
-
-@# {data structure of threads; words 1..4 represent the coordinates of the
- corners}
-@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}
-@d obj_thread_first == obj_aux {pointer to the first bead}
-
-@# {data structure of beads}
-@d pdfmem_bead_size == 5 {size of memory in |pdf_mem| which
- |obj_bead_ptr| points to}
-@d obj_bead_ptr == obj_aux {pointer to |pdf_mem|}
-@d obj_bead_rect(#) == pdf_mem[obj_bead_ptr(#)]
-@d obj_bead_page(#) == pdf_mem[obj_bead_ptr(#) + 1]
-@d obj_bead_next(#) == pdf_mem[obj_bead_ptr(#) + 2]
-@d obj_bead_prev(#) == pdf_mem[obj_bead_ptr(#) + 3]
-@d obj_bead_attr(#) == pdf_mem[obj_bead_ptr(#) + 4]
-@d obj_bead_data == obj_bead_rect {pointer to the corresponding
-whatsit node; |obj_bead_rect| is needed only when the bead rectangle has
-been written out and after that |obj_bead_data| is not needed any more
-so we can use this field for both}
-
-@<Constants...@>=
-@!inf_obj_tab_size = 1000; {min size of the cross-reference table for PDF output}
-@!sup_obj_tab_size = 8388607; {max size of the cross-reference table for PDF output}
-@!inf_dest_names_size = 1000; {min size of the destination names table for PDF output}
-@!sup_dest_names_size = 131072; {max size of the destination names table for PDF output}
-@!inf_pk_dpi = 72; {min PK pixel density value from \.{texmf.cnf}}
-@!sup_pk_dpi = 8000; {max PK pixel density value from \.{texmf.cnf}}
-@!pdf_objtype_max = head_tab_max;
-
-@ @<Glob...@>=
-@!obj_tab_size:integer;
-@!obj_tab:^obj_entry;
-@!head_tab: array[1..head_tab_max] of integer;
-@!pages_tail: integer;
-@!obj_ptr: integer; {user objects counter}
-@!sys_obj_ptr: integer; {system objects counter, including object streams}
-@!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: 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|}
-@!ff: integer; {for use with |set_ff|}
-@!pdf_box_spec_media: integer;
-@!pdf_box_spec_crop: integer;
-@!pdf_box_spec_bleed: integer;
-@!pdf_box_spec_trim: integer;
-@!pdf_box_spec_art: integer;
-
-@ @<Set init...@>=
-obj_ptr := 0;
-sys_obj_ptr := 0;
-obj_tab_size := inf_obj_tab_size; {allocated size of |obj_tab| array}
-dest_names_size := inf_dest_names_size; {allocated size of |dest_names| array}
-for k := 1 to head_tab_max do
- head_tab[k] := 0;
-pdf_box_spec_media := 1;
-pdf_box_spec_crop := 2;
-pdf_box_spec_bleed := 3;
-pdf_box_spec_trim := 4;
-pdf_box_spec_art := 5;
-
-@ Here we implement subroutines for work with objects and related things.
-Some of them are used in former parts too, so we need to declare them
-forward.
-
-@d pdf_append_list_end(#) == # := append_ptr(#, pdf_append_list_arg); end
-@d pdf_append_list(#) == begin pdf_append_list_arg := #; pdf_append_list_end
-@d set_ff(#) == begin
- if pdf_font_num(#) < 0 then
- ff := -pdf_font_num(#)
- else
- ff := #;
-end
-
-@<Declare procedures that need to be declared forward for \pdfTeX@>=
-procedure append_dest_name(s: str_number; n: integer);
-var a: integer;
-begin
- if pdf_dest_names_ptr = sup_dest_names_size then
- overflow("number of destination names (dest_names_size)", dest_names_size);
- if pdf_dest_names_ptr = dest_names_size then begin
- a := 0.2 * dest_names_size;
- if dest_names_size < sup_dest_names_size - a then
- dest_names_size := dest_names_size + a
- else
- dest_names_size := sup_dest_names_size;
- dest_names := xreallocarray(dest_names, dest_name_entry, dest_names_size);
- end;
- dest_names[pdf_dest_names_ptr].objname := s;
- dest_names[pdf_dest_names_ptr].objnum := n;
- incr(pdf_dest_names_ptr);
-end;
-
-procedure pdf_create_obj(t, i: integer); {create an object with type |t| and
-identifier |i|}
-label done;
-var a, p, q: integer;
-begin
- if sys_obj_ptr = sup_obj_tab_size then
- overflow("indirect objects table size", obj_tab_size);
- if sys_obj_ptr = obj_tab_size then begin
- a := 0.2 * obj_tab_size;
- if obj_tab_size < sup_obj_tab_size - a then
- obj_tab_size := obj_tab_size + a
- else
- obj_tab_size := sup_obj_tab_size;
- obj_tab := xreallocarray(obj_tab, obj_entry, obj_tab_size);
- end;
- incr(sys_obj_ptr);
- obj_ptr := sys_obj_ptr;
- obj_info(obj_ptr) := i;
- set_obj_fresh(obj_ptr);
- obj_aux(obj_ptr) := 0;
- avl_put_obj(obj_ptr, t);
- if t = obj_type_page then begin
- p := head_tab[t];
- {find the right position to insert newly created object}@/
- if (p = 0) or (obj_info(p) < i) then begin
- obj_link(obj_ptr) := p;
- head_tab[t] := obj_ptr;
- end
- else begin
- while p <> 0 do begin
- if obj_info(p) < i then
- goto done;
- q := p;
- p := obj_link(p);
- end;
-done:
- obj_link(q) := obj_ptr;
- obj_link(obj_ptr) := p;
- end;
- end
- else if t <> obj_type_others then begin
- obj_link(obj_ptr) := head_tab[t];
- head_tab[t] := obj_ptr;
- if (t = obj_type_dest) and (i < 0) then
- append_dest_name(-obj_info(obj_ptr), obj_ptr);
- end;
-end;
-
-function pdf_new_objnum: integer; {create a new object and return its number}
-begin
- pdf_create_obj(obj_type_others, 0);
- pdf_new_objnum := obj_ptr;
-end;
-
-procedure pdf_os_switch(pdf_os: boolean); {switch between PDF stream and object stream mode}
-begin
- if pdf_os and pdf_os_enable then begin
- if not pdf_os_mode then begin {back up PDF stream variables}
- pdf_op_ptr := pdf_ptr;
- pdf_ptr := pdf_os_ptr;
- pdf_buf := pdf_os_buf;
- pdf_buf_size := pdf_os_buf_size;
- pdf_os_mode := true; {switch to object stream}
- end;
- end else begin
- if pdf_os_mode then begin {back up object stream variables}
- pdf_os_ptr := pdf_ptr;
- pdf_ptr := pdf_op_ptr;
- pdf_buf := pdf_op_buf;
- pdf_buf_size := pdf_op_buf_size;
- pdf_os_mode := false; {switch to PDF stream}
- end;
- end;
-end;
-
-procedure pdf_os_prepare_obj(i: integer; pdf_os_level: integer); {create new \.{/ObjStm} object
-if required, and set up cross reference info}
-begin
- pdf_os_switch((pdf_os_level > 0) and (fixed_pdf_objcompresslevel >= pdf_os_level));
- if pdf_os_mode then begin
- if pdf_os_cur_objnum = 0 then begin
- pdf_os_cur_objnum := pdf_new_objnum;
- decr(obj_ptr); {object stream is not accessible to user}
- incr(pdf_os_cntr); {only for statistics}
- pdf_os_objidx := 0;
- pdf_ptr := 0; {start fresh object stream}
- end else
- incr(pdf_os_objidx);
- obj_os_idx(i) := pdf_os_objidx;
- obj_offset(i) := pdf_os_cur_objnum;
- pdf_os_objnum[pdf_os_objidx] := i;
- pdf_os_objoff[pdf_os_objidx] := pdf_ptr;
- end else begin
- obj_offset(i) := pdf_offset;
- obj_os_idx(i) := -1; {mark it as not included in object stream}
- end;
-end;
-
-procedure pdf_begin_obj(i: integer; pdf_os_level: integer); {begin a PDF object}
-begin
- check_pdfminorversion;
- pdf_os_prepare_obj(i, pdf_os_level);
- if not pdf_os_mode then begin
- pdf_print_int(i);
- pdf_print_ln(" 0 obj");
- end else if pdf_compress_level = 0 then begin
- pdf_print("% "); {debugging help}
- pdf_print_int(i);
- pdf_print_ln(" 0 obj");
- end;
-end;
-
-procedure pdf_new_obj(t, i: integer; pdf_os: integer); {begin a new PDF object}
-begin
- pdf_create_obj(t, i);
- pdf_begin_obj(obj_ptr, pdf_os);
-end;
-
-procedure pdf_end_obj; {end a PDF object}
-begin
- if pdf_os_mode then begin
- if pdf_os_objidx = pdf_os_max_objs - 1 then
- pdf_os_write_objstream;
- end else
- pdf_print_ln("endobj"); {end a PDF object}
-end;
-
-procedure pdf_begin_dict(i: integer; pdf_os_level: integer); {begin a PDF dictionary object}
-begin
- check_pdfminorversion;
- pdf_os_prepare_obj(i, pdf_os_level);
- if not pdf_os_mode then begin
- pdf_print_int(i);
- pdf_print(" 0 obj ");
- end else if pdf_compress_level = 0 then begin
- pdf_print("% "); {debugging help}
- pdf_print_int(i);
- pdf_print_ln(" 0 obj");
- end;
- pdf_print_ln("<<");
-end;
-
-procedure pdf_new_dict(t, i: integer; pdf_os: integer); {begin a new PDF dictionary object}
-begin
- pdf_create_obj(t, i);
- pdf_begin_dict(obj_ptr, pdf_os);
-end;
-
-procedure pdf_end_dict; {end a PDF dictionary object}
-begin
- if pdf_os_mode then begin
- pdf_print_ln(">>");
- if pdf_os_objidx = pdf_os_max_objs - 1 then
- pdf_os_write_objstream;
- end else
- pdf_print_ln(">> endobj");
-end;
-
-@ Write out an accumulated object stream.
-First the object number and byte offset pairs are generated
-and appended to the ready buffered object stream.
-By this the value of \.{/First} can be calculated.
-Then a new \.{/ObjStm} object is generated, and everything is
-copied to the PDF output buffer, where also compression is done.
-When calling this procedure, |pdf_os_mode| must be |true|.
-
-@<Declare procedures that need to be declared forward for \pdfTeX@>=
-procedure pdf_os_write_objstream;
-var i, j, p, q: pointer;
-begin
- if pdf_os_cur_objnum = 0 then {no object stream started}
- return;
- p := pdf_ptr;
- i := 0;
- j := 0;
- while i <= pdf_os_objidx do begin {assemble object number and byte offset pairs}
- pdf_print_int(pdf_os_objnum[i]);
- pdf_print(" ");
- pdf_print_int(pdf_os_objoff[i]);
- if j = 9 then begin {print out in groups of ten for better readability}
- pdf_out(pdf_new_line_char);
- j := 0;
- end else begin
- pdf_print(" ");
- incr(j);
- end;
- incr(i);
- end;
- pdf_buf[pdf_ptr - 1] := pdf_new_line_char; {no risk of flush, as we are in |pdf_os_mode|}
- q := pdf_ptr;
- pdf_begin_dict(pdf_os_cur_objnum, 0); {switch to PDF stream writing}
- pdf_print_ln("/Type /ObjStm");
- pdf_print("/N ");
- pdf_print_int_ln(pdf_os_objidx + 1);
- pdf_print("/First ");
- pdf_print_int_ln(q - p);
- pdf_begin_stream;
- pdf_room(q - p); {should always fit into the PDF output buffer}
- i := p;
- while i < q do begin {write object number and byte offset pairs}
- pdf_quick_out(pdf_os_buf[i]);
- incr(i);
- end;
- i := 0;
- while i < p do begin
- q := i + pdf_buf_size;
- if q > p then q := p;
- pdf_room(q - i);
- while i < q do begin {write the buffered objects}
- pdf_quick_out(pdf_os_buf[i]);
- incr(i);
- end;
- end;
- pdf_end_stream;
- pdf_os_cur_objnum := 0; {to force object stream generation next time}
-end;
-
-@ @<Declare procedures that need to be declared forward for \pdfTeX@>=
-function append_ptr(p: pointer; i: integer): pointer; {appends a pointer with
-info |i| to the end of linked list with head |p|}
-var q: pointer;
-begin
- append_ptr := p;
- fast_get_avail(q);
- info(q) := i;
- link(q) := null;
- if p = null then begin
- append_ptr := q;
- return;
- end;
- while link(p) <> null do
- p := link(p);
- link(p) := q;
-end;
-
-function pdf_lookup_list(p: pointer; i: integer): pointer; {looks up for pointer
-with info |i| in list |p|}
-begin
- pdf_lookup_list := null;
- while p <> null do begin
- if info(p) = i then begin
- pdf_lookup_list := p;
- return;
- end;
- p := link(p);
- end;
-end;
-
-@ @<Glob...@>=
-@!pdf_image_procset: integer; {collection of image types used in current page/form}
-@!pdf_text_procset: boolean; {mask of used ProcSet's in the current page/form}
-
-@ Subroutines to print out various PDF objects
-
-@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
- k := 0;
- repeat dig[k] := n mod 10; n := n div 10; incr(k);
- until k = w;
- pdf_room(k);
- while k > 0 do begin
- decr(k);
- pdf_quick_out("0" + dig[k]);
- end;
-end;
-
-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..7] of integer; {digits in a number being output}
-begin
- k := 0;
- repeat byte[k] := n mod 256; n := n div 256; incr(k);
- until k = w;
- pdf_room(k);
- while k > 0 do begin
- decr(k);
- pdf_quick_out(byte[k]);
- end;
-end;
-
-procedure pdf_int_entry(s: str_number; v: integer); {print out an entry in
-dictionary with integer value to PDF buffer}
-begin
- pdf_out("/");
- pdf_print(s);
- pdf_out(" ");
- pdf_print_int(v);
-end;
-
-procedure pdf_int_entry_ln(s: str_number; v: integer);
-begin
- pdf_int_entry(s, v);
- pdf_print_nl;
-end;
-
-procedure pdf_indirect(s: str_number; o: integer); {print out an indirect
-entry in dictionary}
-begin
- pdf_out("/");
- pdf_print(s);
- pdf_out(" ");
- pdf_print_int(o);
- pdf_print(" 0 R");
-end;
-
-procedure pdf_indirect_ln(s: str_number; o: integer);
-begin
- pdf_indirect(s, o);
- pdf_print_nl;
-end;
-
-procedure pdf_print_str_ln(s: str_number); {print out |s| as string in PDF
-output}
-begin
- pdf_print_str(s);
- pdf_print_nl;
-end;
-
-procedure pdf_str_entry(s, v: str_number); {print out an entry in
-dictionary with string value to PDF buffer}
-begin
- if v = 0 then
- return;
- pdf_out("/");
- pdf_print(s);
- pdf_out(" ");
- pdf_print_str(v);
-end;
-
-procedure pdf_str_entry_ln(s, v: str_number);
-begin
- if v = 0 then
- return;
- pdf_str_entry(s, v);
- pdf_print_nl;
-end;
-
-@* \[32e] Font processing.
-
-As \pdfTeX{} should also act as a back-end driver, it needs to support virtual
-fonts too. Information about virtual fonts can be found in the source of some
-\.{DVI}-related programs.
-
-Whenever we want to write out a character in a font to PDF output, we
-should check whether the used character is a virtual or read character.
-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);
-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
- 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;
-
-@ @<Declare procedures that need to be declared forward for \pdfTeX@>=
-procedure pdf_check_vf_cur_val; forward;
-procedure pdf_create_font_obj; forward;
-procedure pdf_init_font_cur_val; forward;
-procedure scan_pdf_ext_toks; forward;
-
-@ Here come some subroutines to deal with expanded fonts for HZ-algorithm.
-
-@d non_existent_path == "///..."
-
-@p
-function get_default_hyphen_char:integer;
-begin
- get_default_hyphen_char:=default_hyphen_char;
-end;
-@#
-function get_default_skew_char:integer;
-begin
- 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|}
-begin
- set_pdf_font_expand_ratio(k,e);
- set_pdf_font_step(k,pdf_font_step(f));
- set_pdf_font_auto_expand(k, pdf_font_auto_expand(f));
- set_pdf_font_blink(k,f);
-end;
-
-function tfm_lookup(s: str_number; fs: scaled): internal_font_number;
-{looks up for a TFM with name |s| loaded at |fs| size; if found then flushes |s|}
-label exit;
-var k: internal_font_number;
-begin
- if fs <> 0 then begin
- for k := 1 to max_font_id do
- 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;
- end;
- end
- else begin
- for k := 1 to max_font_id do
- 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;
- end else flush_string;
- end;
- tfm_lookup := null_font;
-exit:
-end;
-
-function load_expand_font(f: internal_font_number; e: integer): internal_font_number;
-{loads font |f| expanded by |e| thousandths into font memory; |e| is nonzero
-and is a multiple of |pdf_font_step(f)|}
-label found;
-var s: str_number; {font name}
- k: internal_font_number;
-begin
- s := expand_font_name(f, e);
- k := tfm_lookup(s, font_size(f));
- 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);
- end
- else
- 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;
-end;
-
-function fix_expand_value(f: internal_font_number; e: integer): integer;
-{return the multiple of |pdf_font_step(f)| that is nearest to |e|}
-var step: integer;
- max_expand: integer;
- neg: boolean;
-begin
- fix_expand_value := 0;
- if e = 0 then
- return;
- if e < 0 then begin
- e := -e;
- neg := true;
- max_expand := -pdf_font_expand_ratio(pdf_font_shrink(f));
- end
- else begin
- neg := false;
- max_expand := pdf_font_expand_ratio(pdf_font_stretch(f));
- end;
- if e > max_expand then
- e := max_expand
- else begin
- step := pdf_font_step(f);
- if e mod step > 0 then
- e := step*round_xn_over_d(e, 1, step);
- end;
- if neg then
- e := -e;
- fix_expand_value := e;
-end;
-
-function get_expand_font(f: internal_font_number; e: integer): internal_font_number;
-{look up and create if not found an expanded version of |f|; |f| is an
-expandable font; |e| is nonzero and is a multiple of |pdf_font_step(f)|}
-var k: internal_font_number;
-begin
- k := pdf_font_elink(f);
- while k <> null_font do begin
- if pdf_font_expand_ratio(k) = e then begin
- get_expand_font := k;
- return;
- end;
- k := pdf_font_elink(k);
- end;
- k := load_expand_font(f, e);
- set_pdf_font_elink(k,pdf_font_elink(f));
- set_pdf_font_elink(f,k);
- {|wterm_ln('get_expand_font ', e:1, ': ',f:1, ' became ', k:1);|}
- get_expand_font := k;
-end;
-
-function expand_font(f: internal_font_number; e: integer): internal_font_number;
-{looks up for font |f| expanded by |e| thousandths, |e| is an arbitrary value
-between max stretch and max shrink of |f|; if not found then creates it}
-begin
- expand_font := f;
- if e = 0 then
- return;
- e := fix_expand_value(f, e);
- if e = 0 then
- return;
- if pdf_font_elink(f) = null_font then
- pdf_error("font expansion", "uninitialized pdf_font_elink");
- expand_font := get_expand_font(f, e);
-end;
-
-procedure set_expand_params(f: internal_font_number; auto_expand: boolean;
- 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 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 shrink_limit, stretch_limit, font_step: integer;
- f: internal_font_number;
- auto_expand: boolean;
-begin
- {read font expansion parameters}
- scan_font_ident;
- f := cur_val;
- 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)");
- scan_optional_equals;
- scan_int;
- stretch_limit := fix_int(cur_val, 0, 1000);
- scan_int;
- 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");
- 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
- auto_expand := true;
- @<Scan an optional space@>;
- end;
-
- {check if the font can be expanded}
- if (pdf_font_expand_ratio(f) <> 0) then
- pdf_error("font expansion", "this font has been expanded by another font so it cannot be used now");
- 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 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)) <> 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)) <> 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, 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);
-{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}
-@!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;
- scan_int;
- f := letter_space_font(u, k, fix_int(cur_val, -1000, 1000));
- 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.
-
-@<Types...@>=
-char_map_array = array[0..32] of eight_bits; {move chars in range 0..32}
-fm_entry_ptr = ^integer;
-
-@ @<Glob...@>=
-@!pdf_font_list: pointer; {list of used fonts in current page}
-@!pdf_resname_prefix: str_number; {global prefix of resources name}
-@!last_tokens_string: str_number; {the number of the most recently string
-created by |tokens_to_string|}
-
-@ @<Set init...@>=
-pdf_resname_prefix := 0;
-last_tokens_string := 0;
-
-@ Reading VF files is done in C, using the procedure |do_vf()|
-
-@* \[32f] PDF shipping out.
-To ship out a \TeX\ box to PDF page description we need to implement
-|pdf_hlist_out|, |pdf_vlist_out| and |pdf_ship_out|, which are equivalent to
-the \TeX' original |hlist_out|, |vlist_out| and |ship_out| resp. But first we
-need to declare some procedures needed in |pdf_hlist_out| and |pdf_vlist_out|.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_out_literal(p:pointer);
-var old_setting:0..max_selector; {holds print |selector|}
- s: str_number;
-begin
- if pdf_literal_type(p)=normal then begin
- old_setting:=selector; selector:=new_string;
- show_token_list(link(pdf_literal_data(p)),null,pool_size-pool_ptr);
- selector:=old_setting;
- s := make_string;
- literal(s, pdf_literal_mode(p), false);
- flush_str(s);
- end
- else begin
- pdfassert(pdf_literal_mode(p)<>scan_special);
- case pdf_literal_mode(p) of
- set_origin: begin
- pdf_goto_pagemode;
- synch_pos_with_cur;
- pdf_set_pos(pos.h, pos.v);
- end;
- direct_page:
- pdf_goto_pagemode;
- direct_always:
- pdf_end_string_nl;
- othercases confusion("literal1")
- endcases;
- lua_pdf_literal(pdf_literal_data(p));
- end;
-end;
-
-procedure pdf_out_colorstack(p:pointer);
-var old_setting: 0..max_selector; {holds print |selector|}
- s: str_number;
- cmd: integer;
- stack_no: integer;
- literal_mode: integer;
-begin
- cmd := pdf_colorstack_cmd(p);
- stack_no := pdf_colorstack_stack(p);
- literal_mode := 0;
- if stack_no >= colorstackused then begin
- print_nl("");
- print("Color stack ");
- print_int(stack_no);
- print(" is not initialized for use!");
- print_nl("");
- return;
- end;
- case cmd of
- colorstack_set, colorstack_push: begin
- old_setting:=selector; selector:=new_string;
- show_token_list(link(pdf_colorstack_data(p)),null,pool_size-pool_ptr);
- selector:=old_setting;
- s := make_string;
- if cmd = colorstack_set then
- literal_mode := colorstackset(stack_no, s)
- else
- literal_mode := colorstackpush(stack_no, s);
- if length(s) > 0 then
- literal(s, literal_mode, false);
- flush_str(s);
- return;
- end;
- colorstack_pop: literal_mode := colorstackpop(stack_no);
- colorstack_current: literal_mode := colorstackcurrent(stack_no);
- othercases do_nothing
- endcases;
- if cur_length > 0 then begin
- s := make_string;
- literal(s, literal_mode, false);
- flush_str(s);
- end
-end;
-
-procedure pdf_out_colorstack_startpage;
-var i: integer;
- max: integer;
- start_status: integer;
- literal_mode: integer;
- s: str_number;
-begin
- i := 0;
- max := colorstackused;
- while i < max do begin
- start_status := colorstackskippagestart(i);
- if start_status = 0 then begin
- literal_mode := colorstackcurrent(i);
- if cur_length > 0 then begin
- s := make_string;
- literal(s, literal_mode, false);
- flush_str(s);
- end;
- end;
- incr(i);
- end;
-end;
-
-procedure pdf_out_setmatrix(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(pdf_setmatrix_data(p)),null,pool_size-pool_ptr);
- selector:=old_setting;
- str_room(7);
- str_pool[pool_ptr] := 0; { make C string for pdfsetmatrix }
- synch_pos_with_cur;
- pdfsetmatrix(str_start_macro(str_ptr), pos);
- str_room(7);
- append_char(" ");
- append_char("0");
- append_char(" ");
- append_char("0");
- append_char(" ");
- append_char("c");
- append_char("m");
- s := make_string;
- literal(s, set_origin, false);
- flush_str(s);
-end;
-
-procedure pdf_out_save;
-begin
- synch_pos_with_cur;
- checkpdfsave(pos);
- literal("q", set_origin, false);
-end;
-
-procedure pdf_out_restore;
-begin
- synch_pos_with_cur;
- checkpdfrestore(pos);
- literal("Q", set_origin, false);
-end;
-
-procedure pdf_special(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(write_tokens(p)),null,pool_size-pool_ptr);
- selector:=old_setting;
- s := make_string;
- literal(s, scan_special, true);
- flush_str(s);
-end;
-
-procedure do_late_lua(p: pointer);
-begin
- 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|}
-var s: str_number;
-begin
- s := tokens_to_string(p);
- if length(s) > 0 then
- pdf_print(s);
- flush_str(s);
-end;
-
-procedure pdf_print_toks_ln(p: pointer); {print tokens list |p|}
-var s: str_number;
-begin
- s := tokens_to_string(p);
- if length(s) > 0 then begin
- pdf_print_ln(s);
- end;
- flush_str(s);
-end;
-
-@ Similiar to |vlist_out|, |pdf_vlist_out| needs to be declared forward
-
-@p procedure@?pdf_vlist_out; forward;
-
-@ The implementation of procedure |pdf_hlist_out| is similiar to |hlist_out|
-
-@p @t\4@>@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>@t@>@/
-
-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}
-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;
-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_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}
-@!p,q:pointer; {current position in the hlist}
-@!leader_box:pointer; {the leader box being replicated}
-@!leader_wd:scaled; {width of leader box being replicated}
-@!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}
-@!prev_p:pointer; {one step behind |p|}
-@!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 }
-@!i: small_number; {index to scan |pdf_link_stack|}
-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;
-@<DIR: Initialize |dir_ptr| for |ship_out|@>;
-incr(cur_s);
-base_line:=cur.v;
-left_edge:=cur.h;
-prev_p:=this_box+list_offset;
-@<Create link annotations for the current hbox if needed@>;
-@<Start hlist {\sl Sync\TeX} information record@>;
-while p<>null do
- @<Output node |p| for |pdf_hlist_out| and move to the next node,
- maintaining the condition |cur.v=base_line|@>;
-@<Finish hlist {\sl Sync\TeX} information record@>;
-decr(cur_s);
-dvi_direction:=save_direction;
-@<DIR: Reset |dir_ptr|@>;
-end;
-
-@ @<Create link annotations for the current hbox if needed@>=
-for i := 1 to pdf_link_stack_ptr do begin
- pdfassert(is_running(pdf_width(pdf_link_stack[i].link_node)));
- if (pdf_link_stack[i].nesting_level = cur_s) then
- append_link(this_box, left_edge, base_line, i);
-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 - (#)
-
-@<Output node |p| for |pdf_hlist_out|...@>=
-begin
-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);
- @<Record current point {\sl Sync\TeX} information@>;
-end
-else @<Output the non-|char_node| |p| for |pdf_hlist_out|
- and move to the next node@>;
-end
-
-@ @<Output the non-|char_node| |p| for |pdf_hlist_out|...@>=
-begin case type(p) of
-hlist_node_case,vlist_node_case:@<(\pdfTeX) Output a box in an hlist@>;
-disc_node_case: if vlink(no_break(p))<>null then if subtype(p)<>select_disc 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_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);
- end
- else begin
- rule_ht:=width(p) div 2;
- rule_dp:=width(p) div 2;
- rule_wd:=height(p)+depth(p);
- end;
- goto fin_rule;
- end;
-whatsit_node_case: @<Output the whatsit node |p| in |pdf_hlist_out|@>;
-glue_node_case: @<(\pdfTeX) Move right or output leaders@>;
-margin_kern_node_case: cur.h := cur.h + width(p);
-kern_node_case: begin
- @<Record |kern_node| {\sl Sync\TeX} information@>;
- cur.h := cur.h + width(p);
- end;
-math_node_case: begin
- @<Record |math_node| {\sl Sync\TeX} information@>;
- 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: begin
- cur.h := cur.h + rule_wd;
- @<Record horizontal |rule_node| or |glue_node| {\sl Sync\TeX} information@>;
- end;
-next_p:prev_p:=p; p:=vlink(p);
-end
-
-@ @<(\pdfTeX) Output a box in an hlist@>=
-begin
-if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction]))
- then begin
- effective_horizontal:=width(p);
- basepoint_vertical:=0;
- if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=width(p)
- else
- basepoint_horizontal:=0;
- end
-else begin
- effective_horizontal:=height(p)+depth(p);
- 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
- basepoint_horizontal:=depth(p)
- else
- if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=depth(p)
- else
- basepoint_horizontal:=height(p);
- if dir_eq(dir_secondary[box_dir(p)])(dir_primary[dvi_direction]) then
- basepoint_vertical:= -(width(p) div 2)
- else
- basepoint_vertical:= (width(p) div 2);
- end;
-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
- @<Record void list {\sl Sync\TeX} information@>;
- 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_pos_with_cur;
- save_box_pos:=box_pos;
- if type(p)=vlist_node then pdf_vlist_out@+else pdf_hlist_out;
- box_pos:=save_box_pos;
- cur.h:=edge+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);
-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;
-if g_sign<>normal then
- begin if g_sign=stretching then
- begin if stretch_order(g)=g_order then
- begin cur_glue:=cur_glue+stretch(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
-@^real multiplication@>
- cur_g:=round(glue_temp);
- end;
- end
- else if shrink_order(g)=g_order then
- begin cur_glue:=cur_glue-shrink(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end;
-rule_wd:=rule_wd+cur_g;
-if subtype(p)>=a_leaders then
- @<(\pdfTeX) Output leaders in an hlist, |goto fin_rule| if a rule
- or to |next_p| if done@>;
-goto move_past;
-end
-
-@ @<(\pdfTeX) Output leaders in an hlist...@>=
-begin leader_box:=leader_ptr(p);
-if type(leader_box)=rule_node then
- begin rule_ht:=height(leader_box); rule_dp:=depth(leader_box);
- goto fin_rule;
- end;
-if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_direction]))
- then leader_wd:=width(leader_box)
-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;
- @<Let |cur.h| be the position of the first box, and set |leader_wd+lx|
- to the spacing between corresponding parts of boxes@>;
- while cur.h+leader_wd<=edge do
- @<(\pdfTeX) Output a leader box at |cur.h|,
- then advance |cur.h| by |leader_wd+lx|@>;
- cur.h:=edge-10; goto next_p;
- end;
-end
-
-@ @<(\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
- basepoint_vertical:=0;
- if dir_opposite(dir_secondary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then begin
- basepoint_horizontal:=width(leader_box)
- end
- else
- basepoint_horizontal:=0;
- end
-else begin
- 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
- basepoint_horizontal:=depth(leader_box)
- else
- if dir_eq(dir_primary[box_dir(leader_box)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=depth(leader_box)
- else
- basepoint_horizontal:=height(leader_box);
- if dir_eq(dir_secondary[box_dir(leader_box)])(dir_primary[dvi_direction]) then
- basepoint_vertical:= -(width(leader_box) div 2)
- else
- basepoint_vertical:= (width(leader_box) div 2);
- end;
-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_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;
-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.
-@p procedure pdf_vlist_out; {output a |pdf_vlist_node| box}
-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_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}
-@!p:pointer; {current position in the vlist}
-@!leader_box:pointer; {the leader box being replicated}
-@!leader_ht:scaled; {height of leader box being replicated}
-@!lx:scaled; {extra space between leader boxes}
-@!outer_doing_leaders:boolean; {were we doing leaders?}
-@!edge:scaled; {bottom boundary of leader space}
-@!glue_temp:real; {glue value before rounding}
-@!cur_glue:real; {glue seen so far}
-@!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio}
-@!save_direction: integer;
-@!effective_vertical: scaled;
-@!basepoint_horizontal: scaled;
-@!basepoint_vertical: scaled;
-@!edge_v: 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);}
-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;
-@<Start vlist {\sl Sync\TeX} information record@>;
-cur.v:=cur.v-height(this_box); top_edge:=cur.v;
-@<Create thread for the current vbox if needed@>;
-while p<>null do
- @<Output node |p| for |pdf_vlist_out| and move to the next node,
- maintaining the condition |cur.h=left_edge|@>;
-@<Finish vlist {\sl Sync\TeX} information record@>;
-decr(cur_s);
-dvi_direction:=save_direction;
-end;
-
-@ @<Create thread for the current vbox if needed@>=
-if (last_thread <> null) and is_running(pdf_thread_dp) and
- (pdf_thread_level = cur_s) then
- append_thread(this_box, left_edge, top_edge + height(this_box))
-
-@ @<Output node |p| for |pdf_vlist_out|...@>=
-begin if is_char_node(p) then confusion("pdfvlistout")
-@:this can't happen pdfvlistout}{\quad pdfvlistout@>
-else @<Output the non-|char_node| |p| for |pdf_vlist_out|@>;
-next_p:p:=vlink(p);
-end
-
-@ @<Output the non-|char_node| |p| for |pdf_vlist_out|@>=
-begin case type(p) of
-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);
- end
- else begin
- rule_ht:=width(p) div 2;
- rule_dp:=width(p) div 2;
- rule_wd:=height(p)+depth(p);
- end;
- goto fin_rule;
- end;
-whatsit_node_case: @<Output the whatsit node |p| in |pdf_vlist_out|@>;
-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;
-end
-
-@ TODO: the direct test to switch between |width(p)| and |-width(p)|
-is definately wrong, because it does not nest properly. But at least
-it fixes a very obvious problem that otherwise occured with
-\.{\\pardir TLT} in a document with \.{\\bodydir TRT}, and so it
-will have to do for now.
-
-@<(\pdfTeX) Output a box in a vlist@>=
-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
- basepoint_vertical:=depth(p)
- else
- basepoint_vertical:=height(p);
- if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=width(p)
- else
- basepoint_horizontal:=0;
- end
-else begin
- effective_vertical:=width(p);
- 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
- basepoint_horizontal:=depth(p)
- else
- if dir_eq(dir_primary[box_dir(p)])(dir_secondary[dvi_direction]) then
- basepoint_horizontal:=depth(p)
- else
- basepoint_horizontal:=height(p);
- if dir_eq(dir_secondary[box_dir(p)])(dir_primary[dvi_direction]) then
- basepoint_vertical:=0
- else
- basepoint_vertical:=width(p);
- end;
-basepoint_horizontal := basepoint_horizontal + shift_amount(p);
- {shift the box `right'}
-if list_ptr(p)=null then begin
- cur.v:=cur.v+effective_vertical;
- @<Record void list {\sl Sync\TeX} information@>;
- end
-else begin
- 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;
- 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}
-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@>=
-begin g:=glue_ptr(p); rule_ht:=width(g)-cur_g;
-if g_sign<>normal then
- begin if g_sign=stretching then
- begin if stretch_order(g)=g_order then
- begin cur_glue:=cur_glue+stretch(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
-@^real multiplication@>
- cur_g:=round(glue_temp);
- end;
- end
- else if shrink_order(g)=g_order then
- begin cur_glue:=cur_glue-shrink(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end;
-rule_ht:=rule_ht+cur_g;
-if subtype(p)>=a_leaders then
- @<(\pdfTeX) Output leaders in a vlist, |goto fin_rule| if a rule
- or to |next_p| if done@>;
-goto move_past;
-end
-
-@ @<(\pdfTeX) Output leaders in a vlist...@>=
-begin leader_box:=leader_ptr(p);
-if type(leader_box)=rule_node then
- begin rule_wd:=width(leader_box); rule_dp:=0;
- goto fin_rule;
- end;
-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;
- @<Let |cur.v| be the position of the first box, and set |leader_ht+lx|
- to the spacing between corresponding parts of boxes@>;
- 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;
-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;
-box_pos:=save_box_pos;
-cur.h:=left_edge;
-cur.v:=save_v-height(leader_box)+leader_ht+lx;
-end
-
-@ |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
- if not fixed_pdfoutput_set then begin
- fixed_pdfoutput := pdf_output;
- fixed_pdfoutput_set := true;
- end
- else if fixed_pdfoutput <> pdf_output then
- pdf_error("setup",
- "\pdfoutput can only be changed before anything is written to the output");
-end;
-
-@ |pdf_ship_out| is used instead of |ship_out| to shipout a box to PDF
-output. If |shipping_page| is not set then the output will be a Form object,
-otherwise it will be a Page object.
-
-@p procedure pdf_ship_out(p: pointer; shipping_page: boolean); {output the box |p|}
-label done, done1;
-var i,j,k:integer; {general purpose accumulators}
-save_font_list: pointer; {to save |pdf_font_list| during flushing pending forms}
-save_obj_list: pointer; {to save |pdf_obj_list|}
-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_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
-@<Start sheet {\sl Sync\TeX} information record@>;
-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;
-check_pdfminorversion;
-is_shipping_page := shipping_page;
-if shipping_page then begin
- if pre_callback_id>0 then
- ret:=run_callback(pre_callback_id,'->')
- else if pre_callback_id=0 then begin
- if term_offset>max_print_line-9 then print_ln
- else if (term_offset>0)or(file_offset>0) then print_char(" ");
- print_char("["); j:=9;
- while (count(j)=0)and(j>0) do decr(j);
- for k:=0 to j do
- begin print_int(count(k));
- if k<j then print_char(".");
- end;
- end;
- update_terminal;
-end;
-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@>;
-if (tracing_output<=0)and(post_callback_id=0) and shipping_page then
- print_char("]");
-dead_cycles:=0;
-update_terminal; {progress report}
-@<Flush the box from memory, showing statistics if requested@>;
-if shipping_page and post_callback_id>0 then
- ret:=run_callback(post_callback_id,'->');
-@<Finish sheet {\sl Sync\TeX} information record@>;
-end;
-
-@ @<(\pdfTeX) Ship box |p| out@>=
-if shipping_page and (box_dir(p) <> page_direction) then
- pdf_warning("\shipout", "\pagedir != \bodydir; \box255 may be placed wrongly on the page.", true, true);
-@<Update the values of |max_h| and |max_v|; but if the page is too large,
- |goto done|@>;
-@<Initialize variables as |pdf_ship_out| begins@>;
-if type(p)=vlist_node then pdf_vlist_out@+else pdf_hlist_out;
-if shipping_page then
- incr(total_pages);
-cur_s:=-1;
-@<Finish shipping@>;
-done:
-
-@ @<Initialize variables as |pdf_ship_out| begins@>=
-prepare_mag;
-temp_ptr:=p;
-pdf_last_resources := pdf_new_objnum;
-@<Reset resource lists@>;
-dvi_direction:=page_direction;
-@<Calculate PDF page dimensions and margins@>;
-if not shipping_page then begin
- pdf_begin_dict(pdf_cur_form, 0);
- pdf_last_stream := pdf_cur_form;
- @<Write out Form stream header@>;
-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 been created}
- pdf_new_dict(obj_type_others, 0, 0);
- pdf_last_stream := obj_ptr;
- @<Reset PDF mark lists@>;
-end;
-@<Start stream of page/form contents@>
-
-@ @<Reset resource lists@>=
-pdf_font_list := null;
-pdf_obj_list := null;
-pdf_xform_list := null;
-pdf_ximage_list := null;
-pdf_text_procset := false;
-pdf_image_procset := 0
-
-@ @<Reset PDF mark lists@>=
-pdf_annot_list := null;
-pdf_link_list := null;
-pdf_dest_list := null;
-pdf_bead_list := null;
-last_thread := null
-
-@ @<Calculate PDF page dimensions and margins@>=
-if is_shipping_page then begin
- @<Calculate DVI page dimensions and margins@>;
- {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
- cur.h := h_offset;
- cur.v := v_offset;
- end;
- dir_TR_,dir_RT_: begin
- cur.h := cur_page_size.h - page_right_offset - one_true_inch;
- cur.v := v_offset;
- end;
- dir_BL_,dir_LB_: begin
- cur.h := h_offset;
- cur.v := cur_page_size.v - page_bottom_offset - one_true_inch;
- end;
- dir_RB_,dir_BR_: begin
- cur.h := cur_page_size.h - page_right_offset - one_true_inch;
- cur.v := cur_page_size.v - page_bottom_offset - one_true_inch;
- end;
- end;
- {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
- 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_page_init;
-
-@ Here we write out the header for Form.
-
-@<Write out Form stream header@>=
-pdf_print_ln("/Type /XObject");
-pdf_print_ln("/Subtype /Form");
-if obj_xform_attr(pdf_cur_form) <> null then begin
- pdf_print_toks_ln(obj_xform_attr(pdf_cur_form));
- delete_toks(obj_xform_attr(pdf_cur_form));
-end;
-pdf_print("/BBox [");
-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)
-
-@ @<Start stream of page/form contents@>=
-pdf_begin_stream;
-if shipping_page then begin
- @<Adjust transformation matrix for the magnification ratio@>;
-end;
-pdfshipoutbegin(shipping_page);
-if shipping_page then
- pdf_out_colorstack_startpage;
-
-
-@ @<Adjust transformation matrix for the magnification ratio@>=
-prepare_mag;
-if mag <> 1000 then begin
- pdf_print_real(mag, 3);
- pdf_print(" 0 0 ");
- pdf_print_real(mag, 3);
- pdf_print_ln(" 0 0 cm");
-end
-
-@ @<Finish shipping@>=
-@<Finish stream of page/form contents@>;
-if shipping_page then begin
- @<Write out page object@>;
-end;
-@<Write out resource lists@>;
-if shipping_page then begin
- @<Write out pending PDF marks@>;
-end;
-@<Write out resources dictionary@>;
-@<Flush resource lists@>;
-if shipping_page then begin
- @<Flush PDF mark lists@>;
-end
-
-@ @<Finish stream of page/form contents@>=
-pdf_goto_pagemode;
-pdfshipoutend(shipping_page);
-pdf_end_stream
-
-@ @<Write out resource lists@>=
-@<Write out pending raw objects@>;
-@<Write out pending forms@>;
-@<Write out pending images@>
-
-@ @<Write out resources dictionary@>=
-pdf_begin_dict(pdf_last_resources, 1);
-@<Print additional resources@>;
-@<Generate font resources@>;
-@<Generate XObject resources@>;
-@<Generate ProcSet@>;
-pdf_end_dict
-
-@ @<Print additional resources@>=
-if shipping_page then begin
- if pdf_page_resources <> null then
- pdf_print_toks_ln(pdf_page_resources);
-end
-else begin
- if obj_xform_resources(pdf_cur_form) <> null then begin
- pdf_print_toks_ln(obj_xform_resources(pdf_cur_form));
- delete_toks(obj_xform_resources(pdf_cur_form));
- end;
-end
-
-@ In the end of shipping out a page we reset all the lists holding objects
-have been created during the page shipping.
-
-@d delete_toks(#) == begin delete_token_ref(#); # := null; end
-
-@<Flush resource lists@>=
-flush_list(pdf_font_list);
-flush_list(pdf_obj_list);
-flush_list(pdf_xform_list);
-flush_list(pdf_ximage_list)
-
-@ @<Flush PDF mark lists@>=
-flush_list(pdf_annot_list);
-flush_list(pdf_link_list);
-flush_list(pdf_dest_list);
-flush_list(pdf_bead_list)
-
-@ @<Generate font resources@>=
-if pdf_font_list <> null then begin
- pdf_print("/Font << ");
- k := pdf_font_list;
- while k <> null do begin
- pdf_print("/F");
- set_ff(info(k));
- pdf_print_int(ff);
- pdf_print_resname_prefix;
- pdf_out(" ");
- pdf_print_int(pdf_font_num(ff));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- pdf_print_ln(">>");
- pdf_text_procset := true;
-end
-
-@ @<Generate XObject resources@>=
-if (pdf_xform_list <> null) or (pdf_ximage_list <> null) then begin
- pdf_print("/XObject << ");
- k := pdf_xform_list;
- while k <> null do begin
- pdf_print("/Fm");
- pdf_print_int(obj_info(info(k)));
- pdf_print_resname_prefix;
- pdf_out(" ");
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- k := pdf_ximage_list;
- while k <> null do begin
- pdf_print("/Im");
- pdf_print_int(image_index(obj_data_ptr(info(k))));
- pdf_print_resname_prefix;
- pdf_out(" ");
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- update_image_procset(obj_data_ptr(info(k)));
- k := link(k);
- end;
- pdf_print_ln(">>");
-end
-
-@ @<Generate ProcSet@>=
-pdf_print("/ProcSet [ /PDF");
-if pdf_text_procset then
- pdf_print(" /Text");
-if check_image_b(pdf_image_procset) then
- pdf_print(" /ImageB");
-if check_image_c(pdf_image_procset) then
- pdf_print(" /ImageC");
-if check_image_i(pdf_image_procset) then
- pdf_print(" /ImageI");
-pdf_print_ln(" ]")
-
-@ @<Write out page object@>=
-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_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;
-@<Generate array of annotations or beads in page@>;
-pdf_end_dict
-
-@ @<Generate array of annotations or beads in page@>=
-if (pdf_annot_list <> null) or (pdf_link_list <> null) then begin
- pdf_print("/Annots [ ");
- k := pdf_annot_list;
- while k <> null do begin
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- k := pdf_link_list;
- while k <> null do begin
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- pdf_print_ln("]");
-end;
-if pdf_bead_list <> null then begin
- k := pdf_bead_list;
- pdf_print("/B [ ");
- while k <> null do begin
- pdf_print_int(info(k));
- pdf_print(" 0 R ");
- k := link(k);
- end;
- pdf_print_ln("]");
-end
-
-@ @<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_write_obj(n: integer); {write a raw PDF object}
-var s: str_number;
- f: byte_file;
- data_size:integer; {total size of the data file}
- data_cur:integer; {index into |data_buffer|}
- data_buffer:^real_eight_bits; {byte buffer for data files}
- file_opened:boolean;
- k:integer;
- res:boolean;
- fnam: str_number;
- callback_id:integer;
-begin
- s := tokens_to_string(obj_obj_data(n));
- delete_toks(obj_obj_data(n));
- if obj_obj_is_stream(n) > 0 then begin
- pdf_begin_dict(n, 0);
- if obj_obj_stream_attr(n) <> null then begin
- pdf_print_toks_ln(obj_obj_stream_attr(n));
- delete_toks(obj_obj_stream_attr(n));
- end;
- pdf_begin_stream;
- end
- else
- pdf_begin_obj(n, 1);
- 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
- @<Fixup |nameoffile| after callback@>;
- end;
- end;
- 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),
- addressof(file_opened), addressof(data_buffer),addressof(data_size));
- if not file_opened then pdf_error("ext5", "cannot open file for embedding");
- end
- else begin
- if not tex_b_open_in(f) then
- pdf_error("ext5", "cannot open file for embedding");
- res := read_data_file(f,addressof(data_buffer),addressof(data_size));
- b_close(f);
- end;
- if not data_size then pdf_error("ext5", "empty file for embedding");
- if not res then pdf_error("ext5", "error reading file for embedding");
- print("<<");
- print(s);
- while data_cur<data_size do begin
- pdf_out(data_buffer[data_cur]);
- incr(data_cur);
- end;
- if data_buffer<>0 then libcfree(data_buffer);
- print(">>");
- end
- else if obj_obj_is_stream(n) > 0 then
- pdf_print(s)
- else
- pdf_print_ln(s);
- if obj_obj_is_stream(n) > 0 then
- pdf_end_stream
- else
- pdf_end_obj;
- flush_str(s);
-end;
-
-@ @<Write out pending raw objects@>=
-if pdf_obj_list <> null then begin
- k := pdf_obj_list;
- while k <> null do begin
- if not is_obj_written(info(k)) then
- pdf_write_obj(info(k));
- k := link(k);
- end;
-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_size| is needed for proper
-writing out pending PDF marks.
-
-@<Write out pending forms@>=
-if pdf_xform_list <> null then begin
- k := pdf_xform_list;
- while k <> null do begin
- if not is_obj_written(info(k)) then begin
- pdf_cur_form := info(k);
- @<Save resource lists@>;
- @<Reset resource lists@>;
- save_cur_page_size := cur_page_size;
- pdf_ship_out(obj_xform_box(pdf_cur_form), false);
- cur_page_size := save_cur_page_size;
- @<Restore resource lists@>;
- end;
- k := link(k);
- end;
-end
-
-@ @<Save resource lists@>=
-save_font_list := pdf_font_list;
-save_obj_list := pdf_obj_list;
-save_xform_list := pdf_xform_list;
-save_ximage_list := pdf_ximage_list;
-save_text_procset := pdf_text_procset;
-save_image_procset := pdf_image_procset
-
-@ @<Restore resource lists@>=
-pdf_font_list := save_font_list;
-pdf_obj_list := save_obj_list;
-pdf_xform_list := save_xform_list;
-pdf_ximage_list := save_ximage_list;
-pdf_text_procset := save_text_procset;
-pdf_image_procset := save_image_procset
-
-@ @<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_write_image(n: integer); {write an image}
-begin
- pdf_begin_dict(n, 0);
- if fixed_pdf_draftmode = 0 then write_image(obj_data_ptr(n));
-end;
-
-@ @<Write out pending images@>=
-if pdf_ximage_list <> null then begin
- k := pdf_ximage_list;
- while k <> null do begin
- if not is_obj_written(info(k)) then
- pdf_write_image(info(k));
- k := link(k);
- end;
-end
-
-@ @<Write out pending PDF marks@>=
-@<Write out PDF annotations@>;
-@<Write out PDF link annotations@>;
-@<Write out PDF mark destinations@>;
-@<Write out PDF bead rectangle specifications@>
-
-@ @<Write out PDF annotations@>=
-if pdf_annot_list <> null then begin
- k := pdf_annot_list;
- while k <> null do begin
- i := obj_annot_ptr(info(k)); {|i| points to |pdf_annot_node|}
- pdf_begin_dict(info(k), 1);
- pdf_print_ln("/Type /Annot");
- pdf_print_toks_ln(pdf_annot_data(i));
- pdf_rectangle(i);
- pdf_end_dict;
- k := link(k);
- end;
-end
-
-@ @<Write out PDF link annotations@>=
-if pdf_link_list <> null then begin
-k := pdf_link_list;
-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(i);
- if pdf_action_type(pdf_link_action(i)) <> pdf_action_user then
- pdf_print("/A ");
- write_action(pdf_link_action(i));
- pdf_end_dict;
- k := link(k);
- end;
- @<Flush |pdf_start_link_node|'s created by |append_link|@>;
-end
-
-@ @<Flush |pdf_start_link_node|'s created by |append_link|@>=
-k := pdf_link_list;
-while k <> null do begin
- i := obj_annot_ptr(info(k));
- {nodes with |subtype = pdf_link_data_node| were created by |append_link| and
- must be flushed here, as they are not linked in any list}
- if subtype(i) = pdf_link_data_node then
- flush_node(i);
- k := link(k);
-end
-
-@ @<Write out PDF mark destinations@>=
-if pdf_dest_list <> null then begin
- k := pdf_dest_list;
- while k <> null do begin
- if is_obj_written(info(k)) then
- pdf_error("ext5",
- "destination has been already written (this shouldn't happen)")
- else begin
- i := obj_dest_ptr(info(k));
- if pdf_dest_named_id(i) > 0 then begin
- pdf_begin_dict(info(k), 1);
- pdf_print("/D ");
- end
- else
- pdf_begin_obj(info(k), 1);
- pdf_out("["); pdf_print_int(pdf_last_page); pdf_print(" 0 R ");
- case pdf_dest_type(i) of
- pdf_dest_xyz: begin
- pdf_print("/XYZ ");
- 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
- pdf_print_int(pdf_dest_xyz_zoom(i) div 1000);
- pdf_out(".");
- pdf_print_int((pdf_dest_xyz_zoom(i) mod 1000));
- end;
- end;
- pdf_dest_fit:
- pdf_print("/Fit");
- pdf_dest_fith: begin
- pdf_print("/FitH ");
- pdf_print_mag_bp(pdf_ann_top(i));
- end;
- pdf_dest_fitv: begin
- pdf_print("/FitV ");
- 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_ann_top(i));
- end;
- pdf_dest_fitbv: begin
- pdf_print("/FitBV ");
- pdf_print_mag_bp(pdf_ann_left(i));
- end;
- pdf_dest_fitr: begin
- pdf_print("/FitR ");
- pdf_print_rect_spec(i);
- end;
- othercases pdf_error("ext5", "unknown dest type");
- endcases;
- pdf_print_ln("]");
- if pdf_dest_named_id(i) > 0 then
- pdf_end_dict
- else
- pdf_end_obj;
- end;
- k := link(k);
- end;
-end
-
-@ @<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure pdf_print_rect_spec(r: pointer); {prints a rect spec}
-begin
- pdf_print_mag_bp(pdf_ann_left(r));
- pdf_out(" ");
- pdf_print_mag_bp(pdf_ann_bottom(r));
- pdf_out(" ");
- pdf_print_mag_bp(pdf_ann_right(r));
- pdf_out(" ");
- 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;
-
-@ @<Write out PDF bead rectangle specifications@>=
-if pdf_bead_list <> null then begin
- k := pdf_bead_list;
- while k <> null do begin
- pdf_new_obj(obj_type_others, 0, 1);
- pdf_out("[");
- i := obj_bead_data(info(k)); {pointer to a whatsit or whatsit-like node}
- pdf_print_rect_spec(i);
- if subtype(i) = pdf_thread_data_node then {thanh says it mis be destroyed here}
- flush_node(i);
- pdf_print_ln("]");
- obj_bead_rect(info(k)) := obj_ptr; {rewrite |obj_bead_data|}
- pdf_end_obj;
- k := link(k);
- end;
-end
-
-@ In the end we must flush PDF objects that cannot be written out
-immediately after shipping out pages.
-
-@ @<Output outlines@>=
-if pdf_first_outline <> 0 then begin
- pdf_new_dict(obj_type_others, 0, 1);
- outlines := obj_ptr;
- l := pdf_first_outline; k := 0;
- repeat
- incr(k);
- a := open_subentries(l);
- if obj_outline_count(l) > 0 then
- k := k + a;
- obj_outline_parent(l) := obj_ptr;
- l := obj_outline_next(l);
- until l = 0;
- pdf_print_ln("/Type /Outlines");
- pdf_indirect_ln("First", pdf_first_outline);
- pdf_indirect_ln("Last", pdf_last_outline);
- pdf_int_entry_ln("Count", k);
- pdf_end_dict;
- @<Output PDF outline entries@>;
-end
-else
- outlines := 0
-
-@ @<Output PDF outline entries@>=
-k := head_tab[obj_type_outline];
-while k <> 0 do begin
- if obj_outline_parent(k) = pdf_parent_outline then begin
- if obj_outline_prev(k) = 0 then
- pdf_first_outline := k;
- if obj_outline_next(k) = 0 then
- pdf_last_outline := k;
- end;
- pdf_begin_dict(k, 1);
- pdf_indirect_ln("Title", obj_outline_title(k));
- pdf_indirect_ln("A", obj_outline_action_objnum(k));
- if obj_outline_parent(k) <> 0 then
- pdf_indirect_ln("Parent", obj_outline_parent(k));
- if obj_outline_prev(k) <> 0 then
- pdf_indirect_ln("Prev", obj_outline_prev(k));
- if obj_outline_next(k) <> 0 then
- pdf_indirect_ln("Next", obj_outline_next(k));
- if obj_outline_first(k) <> 0 then
- pdf_indirect_ln("First", obj_outline_first(k));
- if obj_outline_last(k) <> 0 then
- pdf_indirect_ln("Last", obj_outline_last(k));
- if obj_outline_count(k) <> 0 then
- pdf_int_entry_ln("Count", obj_outline_count(k));
- if obj_outline_attr(k) <> 0 then begin
- pdf_print_toks_ln(obj_outline_attr(k));
- delete_toks(obj_outline_attr(k));
- end;
- pdf_end_dict;
- k := obj_link(k);
-end
-
-@ @<Output article threads@>=
-if head_tab[obj_type_thread] <> 0 then begin
- pdf_new_obj(obj_type_others, 0, 1);
- threads := obj_ptr;
- pdf_out("[");
- k := head_tab[obj_type_thread];
- while k <> 0 do begin
- pdf_print_int(k);
- pdf_print(" 0 R ");
- k := obj_link(k);
- end;
- remove_last_space;
- pdf_print_ln("]");
- pdf_end_obj;
- k := head_tab[obj_type_thread];
- while k <> 0 do begin
- out_thread(k);
- k := obj_link(k);
- end;
-end
-else
- threads := 0
-
-@ Now we are ready to declare our new procedure |ship_out|. It will call
-|pdf_ship_out| if the integer parameter |pdf_output| is positive; otherwise it
-will call |dvi_ship_out|, which is the \TeX\ original |ship_out|.
-
-@p procedure ship_out(p:pointer); {output the box |p|}
-begin
- fix_pdfoutput;
- if pdf_output > 0 then
- pdf_ship_out(p, true)
- else
- dvi_ship_out(p);
-end;
-
-@ Finishing the PDF output file.
-
-The following procedures sort the table of destination names
-@p function str_less_str(s1, s2: str_number): boolean; {compare two strings}
-var c1, c2: pool_pointer;
- l, i: integer;
-begin
- c1 := str_start_macro(s1);
- c2 := str_start_macro(s2);
- if length(s1) < length(s2) then
- l := length(s1)
- else
- l := length(s2);
- i := 0;
- while (i < l) and (str_pool[c1 + i] = str_pool[c2 + i]) do
- incr(i);
- if ((i < l) and (str_pool[c1 + i] < str_pool[c2 + i])) or
- ((i = l) and (length(s1) < length(s2))) then
- str_less_str := true
- else
- str_less_str := false;
-end;
-
-procedure sort_dest_names(l, r: integer); {sorts |dest_names| by names}
-var i, j: integer;
- s: str_number;
- e: dest_name_entry;
-begin
- i := l;
- j := r;
- s := dest_names[(l + r) div 2].objname;
- repeat
- while str_less_str(dest_names[i].objname, s) do
- incr(i);
- while str_less_str(s, dest_names[j].objname) do
- decr(j);
- if i <= j then begin
- e := dest_names[i];
- dest_names[i] := dest_names[j];
- dest_names[j] := e;
- incr(i);
- decr(j);
- end;
- until i > j;
- if l < j then
- sort_dest_names(l, j);
- if i < r then
- sort_dest_names(i, r);
-end;
-
-@ Now the finish of PDF output file. At this moment all Page objects
-are already written completely to PDF output file.
-
-@<Finish the PDF file@>=
-if total_pages=0 then begin
- if callback_id=0 then
- print_nl("No pages of output.")
- else if callback_id>0 then
- 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}
- flush_jbig2_page0_objects; {flush page 0 objects from JBIG2 images, if any}
- @<Check for non-existing pages@>;
- @<Check for non-existing destinations@>;
- @<Output fonts definition@>;
- pdf_last_pages := output_pages_tree;
- @<Output outlines@>;
- @<Output name tree@>;
- @<Output article threads@>;
- @<Output the catalog object@>;
- 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);
- @<Output the cross-reference stream dictionary@>;
- pdf_flush;
- end else begin
- @<Output the |obj_tab|@>;
- end;
- @<Output the trailer@>;
- 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 if callback_id>0 then
- res:=run_callback(callback_id,'->');
- end;
- libpdffinish;
- if fixed_pdf_draftmode = 0 then b_close(pdf_file)
- else pdf_warning(0, "\pdfdraftmode enabled, not changing output pdf", true, true)
-end
-
-@ Destinations that have been referenced but don't exists have
-|obj_dest_ptr=null|. Leaving them undefined might cause troubles for
-PDF browsers, so we need to fix them.
-
-@p procedure pdf_fix_dest(k: integer);
-begin
- if obj_dest_ptr(k) <> null then
- return;
- pdf_warning("dest", "", false, false);
- if obj_info(k) < 0 then begin
- print("name{");
- print(-obj_info(k));
- print("}");
- end
- else begin
- print("num");
- print_int(obj_info(k));
- end;
- print(" has been referenced but does not exist, replaced by a fixed one");
- print_ln; print_ln;
- pdf_begin_obj(k, 1);
- pdf_out("[");
- pdf_print_int(head_tab[obj_type_page]);
- pdf_print_ln(" 0 R /Fit]");
- pdf_end_obj;
-end;
-
-@ @<Check for non-existing destinations@>=
-k := head_tab[obj_type_dest];
-while k <> 0 do begin
- pdf_fix_dest(k);
- k := obj_link(k);
-end
-
-@ @<Check for non-existing pages@>=
-k := head_tab[obj_type_page];
-while obj_aux(k) = 0 do begin
- pdf_warning("dest", "Page ", false, false);
- print_int(obj_info(k));
- print(" has been referenced but does not exist!");
- print_ln; print_ln;
- k := obj_link(k);
-end;
-head_tab[obj_type_page] := k
-
-@ @<Output fonts definition@>=
-for k := 1 to max_font_id do
- if font_used(k) and (pdf_font_num(k) < 0) then begin
- i := -pdf_font_num(k);
- pdfassert(pdf_font_num(i) > 0);
- for j := font_bc(k) to font_ec(k) do
- if pdf_char_marked(k, j) then
- pdf_mark_char(i, j);
- if (pdf_font_attr(i) = 0) and (pdf_font_attr(k) <> 0) then
- set_pdf_font_attr(i, pdf_font_attr(k))
- else if (pdf_font_attr(k) = 0) and (pdf_font_attr(i) <> 0) then
- set_pdf_font_attr(k,pdf_font_attr(i))
- else if (pdf_font_attr(i) <> 0) and (pdf_font_attr(k) <> 0) and
- not str_eq_str(pdf_font_attr(i), pdf_font_attr(k)) then begin
- pdf_warning("\pdffontattr", "fonts ", false, false);
- print_font_identifier(i);
- print(" and ");
- print_font_identifier(k);
- 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;
-k := head_tab[obj_type_font];
-while k <> 0 do begin
- f := obj_info(k);
- pdfassert(pdf_font_num(f) > 0);
- do_pdf_font(k, f);
- k := obj_link(k);
-end;
-write_fontstuff
-
-@ @p
-procedure print_pdf_pages_attr;
-begin
- if pdf_pages_attr <> null then
- pdf_print_toks_ln(pdf_pages_attr);
-end;
-
-@ 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
-the first name and |obj_link| will be the last name in \.{\\Limits} array.
-Note that |pdf_dest_names_ptr| will be less than |obj_ptr|, so we test if
-|k < pdf_dest_names_ptr| then |k| is index of leaf in |dest_names|; else
-|k| will be index in |obj_tab| of some intermediate node.
-
-@<Output name tree@>=
-if pdf_dest_names_ptr = 0 then begin
- dests := 0;
- goto done1;
-end;
-sort_dest_names(0, pdf_dest_names_ptr - 1);
-names_head := 0;
-names_tail := 0;
-k := 0; {index of current child of |l|; if |k < pdf_dest_names_ptr|
- then this is pointer to |dest_names| array;
- otherwise it is the pointer to |obj_tab| (object number)}
-is_names := true; {flag whether Names or Kids}
-b := 0;
-repeat
- repeat
- pdf_create_obj(obj_type_others, 0); {create a new node}
- l := obj_ptr;
- if b = 0 then
- b := l; {first in this level}
- if names_head = 0 then begin
- names_head := l;
- names_tail := l;
- end else begin
- obj_link(names_tail) := l;
- names_tail := l;
- end;
- obj_link(names_tail) := 0;
- @<Output the current node in this level@>;
- until b = 0;
- if k = l then begin
- dests := l;
- goto done1;
- end;
-until false;
-done1:
-if (dests <> 0) or (pdf_names_toks <> null) then begin
- pdf_new_dict(obj_type_others, 0, 1);
- if (dests <> 0) then
- pdf_indirect_ln("Dests", dests);
- if pdf_names_toks <> null then begin
- pdf_print_toks_ln(pdf_names_toks);
- delete_toks(pdf_names_toks);
- end;
- pdf_end_dict;
- names_tree := obj_ptr;
-end
-else
- names_tree := 0
-
-@ @<Output the current node in this level@>=
-pdf_begin_dict(l, 1);
-j := 0;
-if is_names then begin
- obj_info(l) := dest_names[k].objname;
- pdf_print("/Names [");
- repeat
- pdf_print_str(dest_names[k].objname);
- pdf_out(" ");
- pdf_print_int(dest_names[k].objnum);
- pdf_print(" 0 R ");
- incr(j);
- incr(k);
- until (j = name_tree_kids_max) or (k = pdf_dest_names_ptr);
- remove_last_space;
- pdf_print_ln("]");
- obj_aux(l) := dest_names[k - 1].objname;
- if k = pdf_dest_names_ptr then begin
- is_names := false;
- k := names_head;
- b := 0;
- end;
-end
-else begin
- obj_info(l) := obj_info(k);
- pdf_print("/Kids [");
- repeat
- pdf_print_int(k);
- pdf_print(" 0 R ");
- incr(j);
- obj_aux(l) := obj_aux(k);
- k := obj_link(k);
- until (j = name_tree_kids_max) or (k = b) or (obj_link(k) = 0);
- remove_last_space;
- pdf_print_ln("]");
- if k = b then
- b := 0;
-end;
-pdf_print("/Limits [");
-pdf_print_str(obj_info(l));
-pdf_out(" ");
-pdf_print_str(obj_aux(l));
-pdf_print_ln("]");
-pdf_end_dict;
-
-@ @<Output the catalog object@>=
-pdf_new_dict(obj_type_others, 0, 1);
-root := obj_ptr;
-pdf_print_ln("/Type /Catalog");
-pdf_indirect_ln("Pages", pdf_last_pages);
-if threads <> 0 then
- pdf_indirect_ln("Threads", threads);
-if outlines <> 0 then
- pdf_indirect_ln("Outlines", outlines);
-if names_tree <> 0 then
- pdf_indirect_ln("Names", names_tree);
-if pdf_catalog_toks <> null then begin
- pdf_print_toks_ln(pdf_catalog_toks);
- delete_toks(pdf_catalog_toks);
-end;
-if pdf_catalog_openaction <> 0 then
- pdf_indirect_ln("OpenAction", pdf_catalog_openaction);
-pdf_end_dict
-
-@ If the same keys in a dictionary are given several times, then it is not
-defined which value is choosen by an application. Therefore the keys
-|/Producer| and |/Creator| are only set if the token list
-|pdf_info_toks| converted to a string does not contain these key strings.
-
-@p function substr_of_str(s, t: str_number):boolean;
-label continue,exit;
-var j, k, kk: pool_pointer; {running indices}
-begin
- k:=str_start_macro(t);
- while (k < str_start_macro(t+1) - length(s)) do begin
- j:=str_start_macro(s);
- kk:=k;
- while (j < str_start_macro(s+1)) do begin
- if str_pool[j] <> str_pool[kk] then
- goto continue;
- incr(j);
- incr(kk);
- end;
- substr_of_str:=true;
- return;
- continue: incr(k);
- end;
- substr_of_str:=false;
-end;
-
-procedure pdf_print_info; {print info object}
-var s: str_number;
- creator_given, producer_given, creationdate_given, moddate_given, trapped_given: boolean;
-begin
- s:="";
- pdf_new_dict(obj_type_others, 0, 3); {keep Info readable unless explicitely forced}
- creator_given:=false;
- producer_given:=false;
- creationdate_given:=false;
- moddate_given:=false;
- trapped_given:=false;
- if pdf_info_toks <> null then begin
- s:=tokens_to_string(pdf_info_toks);
- creator_given:=substr_of_str("/Creator", s);
- producer_given:=substr_of_str("/Producer", s);
- creationdate_given:=substr_of_str("/CreationDate", s);
- moddate_given:=substr_of_str("/ModDate", s);
- trapped_given:=substr_of_str("/Trapped", s);
- end;
- if not producer_given then begin
- @<Print the Producer key@>;
- end;
- if pdf_info_toks <> null then begin
- if length(s) > 0 then begin
- pdf_print_ln(s);
- end;
- flush_str(s);
- delete_toks(pdf_info_toks);
- end;
- if not creator_given then
- pdf_str_entry_ln("Creator", "TeX");
- if not creationdate_given then begin
- @<Print the CreationDate key@>;
- end;
- if not moddate_given then begin
- @<Print the ModDate key@>;
- end;
- if not trapped_given then begin
- pdf_print_ln("/Trapped /False");
- end;
- pdf_str_entry_ln("PTEX.Fullbanner", pdftex_banner);
- pdf_end_dict;
-end;
-
-@ @<Print the Producer key@>=
-pdf_print("/Producer (LuaTeX-");
-pdf_print_int(luatex_version div 100);
-pdf_out(".");
-pdf_print_int(luatex_version mod 100);
-pdf_out(".");
-pdf_print(luatex_revision);
-pdf_print_ln(")")
-
-@ @<Print the CreationDate key@>=
-print_creation_date;
-
-@ @<Print the ModDate key@>=
-print_mod_date;
-
-@ @<Glob...@>=
-@!pdftex_banner: str_number; {the complete banner}
-
-@ @<Build a linked list of free objects@>=
-l := 0;
-set_obj_fresh(l); {null object at begin of list of free objects}
-for k := 1 to sys_obj_ptr do
- if not is_obj_written(k) then begin
- obj_link(l) := k;
- l := k;
- end;
-obj_link(l) := 0
-
-@ @<Output the |obj_tab|@>=
-@<Build a linked list of free objects@>;
-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 not is_obj_written(k) then begin
- pdf_print_fw_int(obj_link(k), 10);
- pdf_print_ln(" 00000 f ");
- end
- else begin
- pdf_print_fw_int(obj_offset(k), 10);
- pdf_print_ln(" 00000 n ");
- end;
-end
-
-@ @<Output the cross-reference stream dictionary@>=
-pdf_new_dict(obj_type_others, 0, 0);
-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
- xref_offset_width := 2;
-@<Build a linked list of free objects@>;
-pdf_print_ln("/Type /XRef");
-pdf_print("/Index [0 ");
-pdf_print_int(obj_ptr);
-pdf_print_ln("]");
-pdf_int_entry_ln("Size", obj_ptr);
-pdf_print("/W [1 ");
-pdf_print_int(xref_offset_width);
-pdf_print_ln(" 1]");
-pdf_indirect_ln("Root", root);
-pdf_indirect_ln("Info", obj_ptr - 1);
-if pdf_trailer_toks <> null then begin
- pdf_print_toks_ln(pdf_trailer_toks);
- delete_toks(pdf_trailer_toks);
-end;
-print_ID(output_file_name);
-pdf_print_nl;
-pdf_begin_stream;
-for k := 0 to sys_obj_ptr do begin
- 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);
- end else begin
- if obj_os_idx(k) = -1 then begin {object not in object stream}
- pdf_out(1);
- pdf_out_bytes(obj_offset(k), xref_offset_width);
- pdf_out(0);
- end else begin {object in object stream}
- pdf_out(2);
- pdf_out_bytes(obj_offset(k), xref_offset_width);
- pdf_out(obj_os_idx(k));
- end;
- end;
-end;
-pdf_end_stream;
-
-@ @<Output the trailer@>=
-if not pdf_os_enable then begin
- pdf_print_ln("trailer");
- pdf_print("<< ");
- pdf_int_entry_ln("Size", sys_obj_ptr + 1);
- pdf_indirect_ln("Root", root);
- pdf_indirect_ln("Info", sys_obj_ptr);
- if pdf_trailer_toks <> null then begin
- pdf_print_toks_ln(pdf_trailer_toks);
- delete_toks(pdf_trailer_toks);
- end;
- print_ID(output_file_name);
- pdf_print_ln(" >>");
-end;
-pdf_print_ln("startxref");
-if pdf_os_enable then
- pdf_print_int_ln(obj_offset(sys_obj_ptr))
-else
- pdf_print_int_ln(pdf_save_offset);
-pdf_print_ln("%%EOF")
-
-@* \[33] Packaging.
-We're essentially done with the parts of \TeX\ that are concerned with
-the input (|get_next|) and the output (|ship_out|). So it's time to
-get heavily into the remaining part, which does the real work of typesetting.
-
-After lists are constructed, \TeX\ wraps them up and puts them into boxes.
-Two major subroutines are given the responsibility for this task: |hpack|
-applies to horizontal lists (hlists) and |vpack| applies to vertical lists
-(vlists). The main duty of |hpack| and |vpack| is to compute the dimensions
-of the resulting boxes, and to adjust the glue if one of those dimensions
-is pre-specified. The computed sizes normally enclose all of the material
-inside the new box; but some items may stick out if negative glue is used,
-if the box is overfull, or if a \.{\\vbox} includes other boxes that have
-been shifted left.
-
-The subroutine call |hpack(p,w,m)| returns a pointer to an |hlist_node|
-for a box containing the hlist that starts at |p|. Parameter |w| specifies
-a width; and parameter |m| is either `|exactly|' or `|additional|'. Thus,
-|hpack(p,w,exactly)| produces a box whose width is exactly |w|, while
-|hpack(p,w,additional)| yields a box whose width is the natural width plus
-|w|. It is convenient to define a macro called `|natural|' to cover the
-most common case, so that we can say |hpack(p,natural)| to get a box that
-has the natural width of list |p|.
-
-Similarly, |vpack(p,w,m)| returns a pointer to a |vlist_node| for a
-box containing the vlist that starts at |p|. In this case |w| represents
-a height instead of a width; the parameter |m| is interpreted as in |hpack|.
-
-@d exactly=0 {a box dimension is pre-specified}
-@d additional=1 {a box dimension is increased from the natural one}
-@d natural==0,additional {shorthand for parameters to |hpack| and |vpack|}
-
-@<Glob...@>=
-pack_direction:integer;
-spec_direction:integer;
-
-@ The parameters to |hpack| and |vpack| correspond to \TeX's primitives
-like `\.{\\hbox} \.{to} \.{300pt}', `\.{\\hbox} \.{spread} \.{10pt}'; note
-that `\.{\\hbox}' with no dimension following it is equivalent to
-`\.{\\hbox} \.{spread} \.{0pt}'. The |scan_spec| subroutine scans such
-constructions in the user's input, including the mandatory left brace that
-follows them, and it puts the specification onto |save_stack| so that the
-desired box can later be obtained by executing the following code:
-$$\vbox{\halign{#\hfil\cr
-|save_ptr:=save_ptr-2;|\cr
-|hpack(p,saved(1),saved(0)).|\cr}}$$
-Special care is necessary to ensure that the special |save_stack| codes
-are placed just below the new group code, because scanning can change
-|save_stack| when \.{\\csname} appears.
-
-@p procedure scan_spec(@!c:group_code;@!three_codes:boolean);
- {scans a box specification and left brace}
-label found, continue;
-var @!s:integer; {temporarily saved value}
-i:integer; v:integer;
-@!spec_code:exactly..additional;
-attr_list:halfword;
-begin s:=0;
-if attr_list_cache=cache_disabled then update_attribute_cache;
-attr_list:=attr_list_cache;
-if three_codes then begin
- s:=saved(0);
-continue:
- 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
- attr_list:=copy_attribute_list(attr_list_cache);
- 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
- scan_direction; spec_direction:=cur_val;
- goto continue;
- end;
- if attr_list=attr_list_cache then begin add_node_attr_ref(attr_list); end;
- end;
-if scan_keyword('to') then spec_code:=exactly
-@.to@>
-else if scan_keyword('spread') then spec_code:=additional
-@.spread@>
-else begin spec_code:=additional; cur_val:=0;
- goto found;
- end;
-scan_normal_dimen;
-found: if three_codes then begin
- saved(0):=s;
- saved(1):=spec_code;
- saved(2):=cur_val;
- saved(3):=spec_direction;
- @<DIR: Adjust |text_dir_ptr| for |scan_spec|@>;
- saved(5):=attr_list;
- save_ptr:=save_ptr+6;
- new_save_level(c); scan_left_brace;
- eq_word_define(dir_base+body_direction_code,spec_direction);
- eq_word_define(dir_base+par_direction_code,spec_direction);
- eq_word_define(dir_base+text_direction_code,spec_direction);
- eq_word_define(int_base+level_local_dir_code,cur_level);
- end
- else begin
- saved(0):=spec_code;
- saved(1):=cur_val;
- save_ptr:=save_ptr+2;
- new_save_level(c); scan_left_brace;
- end;
-spec_direction:=-1;
-end;
-
-@ To figure out the glue setting, |hpack| and |vpack| determine how much
-stretchability and shrinkability are present, considering all four orders
-of infinity. The highest order of infinity that has a nonzero coefficient
-is then used as if no other orders were present.
-
-For example, suppose that the given list contains six glue nodes with
-the respective stretchabilities 3pt, 8fill, 5fil, 6pt, $-3$fil, $-8$fill.
-Then the total is essentially 2fil; and if a total additional space of 6pt
-is to be achieved by stretching, the actual amounts of stretch will be
-0pt, 0pt, 15pt, 0pt, $-9$pt, and 0pt, since only `fil' glue will be
-considered. (The `fill' glue is therefore not really stretching infinitely
-with respect to `fil'; nobody would actually want that to happen.)
-
-The arrays |total_stretch| and |total_shrink| are used to determine how much
-glue of each kind is present. A global variable |last_badness| is used
-to implement \.{\\badness}.
-
-@<Glob...@>=
-@!total_stretch, @!total_shrink: array[glue_ord] of scaled;
- {glue found by |hpack| or |vpack|}
-@!last_badness:integer; {badness of the most recently packaged box}
-
-@ If the global variable |adjust_tail| is non-null, the |hpack| routine
-also removes all occurrences of |ins_node|, |mark_node|, and |adjust_node|
-items and appends the resulting material onto the list that ends at
-location |adjust_tail|.
-
-@< Glob...@>=
-@!adjust_tail:pointer; {tail of adjustment list}
-
-@ @<Set init...@>=adjust_tail:=null; last_badness:=0;
-
-@ @<Glob...@>=
-@!font_expand_ratio: integer; {current expansion ratio}
-@!last_leftmost_char: pointer;
-@!last_rightmost_char: pointer;
-
-@ @<Glob...@>=
-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}
-
-@ This procedure is called repeatedly from inside the line break algorithm.
-
-@p procedure set_prev_char_p(p:pointer);
-begin prev_char_p:=p;
-end;
-
-@ Here is |hpack|, which is place where we do font substituting when
-font expansion is being used. We define some constants used when calling
-|hpack| to deal with font expansion.
-
-@d cal_expand_ratio == 2 {calculate amount for font expansion after breaking
- paragraph into lines}
-@d subst_ex_font == 3 {substitute fonts}
-
-@d substituted = 3 {|subtype| of kern nodes that should be substituted}
-
-@p function char_stretch(p:halfword): scaled;
-var k: internal_font_number;
- dw: scaled;
- ef: integer;
- f: internal_font_number;
- c: integer;
-begin
- f := font(p);
- c := character(p);
- char_stretch := 0;
- k := pdf_font_stretch(f);
- ef := get_ef_code(f, c);
- if (k <> null_font) and (ef > 0) then begin
- dw := char_width(k,c) - char_width(f,c);
- if dw > 0 then
- char_stretch := round_xn_over_d(dw, ef, 1000);
- end;
-end;
-
-function char_shrink(p:halfword): scaled;
-var k: internal_font_number;
- dw: scaled;
- ef: integer;
- f: internal_font_number;
- c: integer;
-begin
- f := font(p);
- c := character(p);
- char_shrink := 0;
- k := pdf_font_shrink(f);
- ef := get_ef_code(f, c);
- if (k <> null_font) and (ef > 0) then begin
- dw := char_width(f,c) - char_width(k,c);
- if dw > 0 then
- char_shrink := round_xn_over_d(dw, ef, 1000);
- end;
-end;
-
-function kern_stretch(p: pointer): scaled;
-var l, r: pointer;
- d: scaled;
-begin
- kern_stretch := 0;
- if (prev_char_p = null) or (vlink(prev_char_p) <> p) or (vlink(p) = null)
- then
- return;
- l := prev_char_p;
- r := vlink(p);
- if not (is_char_node(l) and is_char_node(r) and
- (font(l) = font(r)) and
- (pdf_font_stretch(font(l)) <> null_font))
- then
- return;
- d := get_kern(pdf_font_stretch(font(l)), character(l), character(r));
- kern_stretch := round_xn_over_d(d - width(p),
- get_ef_code(font(l), character(l)), 1000);
-end;
-
-function kern_shrink(p: pointer): scaled;
-var l, r: pointer;
- d: scaled;
-begin
- kern_shrink := 0;
- if (prev_char_p = null) or (vlink(prev_char_p) <> p) or (vlink(p) = null)
- then
- return;
- l := prev_char_p;
- r := vlink(p);
- if not (is_char_node(l) and is_char_node(r) and
- (font(l) = font(r)) and
- (pdf_font_shrink(font(l)) <> null_font))
- then
- return;
- d := get_kern(pdf_font_shrink(font(l)), character(l), character(r));
- kern_shrink := round_xn_over_d(width(p) - d,
- get_ef_code(font(l), character(l)), 1000);
-end;
-
-procedure do_subst_font(p: pointer; ex_ratio: integer);
-var f, k: internal_font_number;
- r: pointer;
- ef: integer;
-begin
- if not is_char_node(p) and (type(p) = disc_node) then begin
- r := vlink(pre_break(p));
- while r <> null do begin
- if is_char_node(r) then
- do_subst_font(r, ex_ratio);
- r := vlink(r);
- end;
- r := vlink(post_break(p));
- while r <> null do begin
- if is_char_node(r) then
- do_subst_font(r, ex_ratio);
- r := vlink(r);
- end;
- r := vlink(no_break(p));
- while r <> null do begin
- if is_char_node(r) then
- do_subst_font(r, ex_ratio);
- r := vlink(r);
- end;
- return;
- end;
- if is_char_node(p) then
- r := p
- else begin
- {|short_display_n(p, 5);|}
- pdf_error("font expansion", "invalid node type");
- return;
- end;
- f := font(r);
- ef := get_ef_code(f, character(r));
- if ef = 0 then
- return;
- if (pdf_font_expand_ratio(f)=0) and
- (pdf_font_stretch(f) <> null_font) and
- (ex_ratio > 0) then
- k := expand_font(f, ext_xn_over_d(ex_ratio*ef,
- pdf_font_expand_ratio(pdf_font_stretch(f)),
- 1000000))
- else if (pdf_font_expand_ratio(f)=0) and
- (pdf_font_shrink(f) <> null_font) and (ex_ratio < 0) then
- k := expand_font(f, ext_xn_over_d(ex_ratio*ef,
- -pdf_font_expand_ratio(pdf_font_shrink(f)),
- 1000000))
- else
- k := f;
- if k <> f then begin
- font(r) := k;
- if not is_char_node(p) then begin
- r := lig_ptr(p);
- while r <> null do begin
- font(r) := k;
- r := vlink(r);
- end;
- end;
- end;
-end;
-
-function char_pw(p: pointer; side: small_number): scaled;
-var f: internal_font_number;
- c: integer;
-begin
- char_pw := 0;
- if side = left_side then
- last_leftmost_char := null
- else
- last_rightmost_char := null;
- if p = null then
- return;
- if not is_char_node(p) then
- return;
- f := font(p);
- if side = left_side then begin
- c := get_lp_code(f, character(p));
- last_leftmost_char := p;
- end
- else begin
- c := get_rp_code(f, character(p));
- last_rightmost_char := p;
- end;
- if c = 0 then
- return;
- char_pw :=
- round_xn_over_d(quad(f), c, 1000);
-end;
-
-function new_margin_kern(w: scaled; p: pointer; side: small_number): pointer;
-var k,q: pointer;
-begin
- k := new_node(margin_kern_node,side);
- width(k) := w;
- if p = null then
- pdf_error("margin kerning", "invalid pointer to marginal char node");
- q := new_char(font(p), character(p)); margin_char(k):=q;
- new_margin_kern := k;
-end;
-
-function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer;
-label reswitch,common_ending,exit;
-var r:pointer; {the box node that will be returned}
-@!q:pointer; {trails behind |p|}
-@!h,@!d,@!x:scaled; {height, depth, and natural width}
-@!s:scaled; {shift amount}
-@!g:pointer; {points to a glue specification}
-@!o:glue_ord; {order of infinity}
-@!f:internal_font_number; {the font in a |char_node|}
-@!dir_tmp,dir_ptr:pointer; {for managing the direction stack}
-@!hpack_dir:integer; {the current direction}
-@!disc_level:integer;
-pack_interrupt:array[0..255] of halfword;
-font_stretch: scaled;
-font_shrink: scaled;
-k: scaled;
-begin last_badness:=0; r:=new_node(hlist_node,min_quarterword);
-if pack_direction=-1 then
- box_dir(r):=text_direction
-else begin
- box_dir(r):=pack_direction; pack_direction:=-1;
- end;
-hpack_dir:=box_dir(r);
-dir_ptr:=null;
-push_dir(hpack_dir);
-q:=r+list_offset; vlink(q):=p;@/
-if m = cal_expand_ratio then begin
- prev_char_p := null;
- font_stretch := 0;
- font_shrink := 0;
- font_expand_ratio := 0;
-end;
-h:=0; @<Clear dimensions to zero@>;
-disc_level:=0;
-reswitch:
-while (p<>null)or(disc_level>0) do begin
- if p=null then begin
- decr(disc_level);
- p:=pack_interrupt[disc_level];
- goto reswitch;
- end;
- @<Examine node |p| in the hlist, taking account of its effect
- on the dimensions of the new box, or moving it to the adjustment list;
- then advance |p| to the next node@>;
- end;
-if adjust_tail<>null then vlink(adjust_tail):=null;
-if pre_adjust_tail<>null then vlink(pre_adjust_tail):=null;
-height(r):=h; depth(r):=d;@/
-@<Determine the value of |width(r)| and the appropriate glue setting;
- then |return| or |goto common_ending|@>;
-common_ending: @<Finish issuing a diagnostic message
- for an overfull or underfull hbox@>;
-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);
- r:=hpack(q, w, subst_ex_font);
-end;
-while dir_ptr<>null do pop_dir_node;
-hpack:=r;
-end;
-
-function filtered_hpack(@!p:pointer;@!qt:pointer;@!w:scaled;@!m:small_number;@!grp:integer):pointer;
-var q:pointer;
-begin
- new_hyphenation(p,qt);
- call_func(new_ligkern(p,qt)); {don't care about the tail in this case}
- q:=vlink(p);
- q:=lua_hpack_filter(q,w,m,grp);
- filtered_hpack:=hpack(q,w,m);
-end;
-
-@ @<Clear dimensions to zero@>=
-d:=0; x:=0;
-total_stretch[normal]:=0; total_shrink[normal]:=0;
-total_stretch[sfi]:=0; total_shrink[sfi]:=0;
-total_stretch[fil]:=0; total_shrink[fil]:=0;
-total_stretch[fill]:=0; total_shrink[fill]:=0;
-total_stretch[filll]:=0; total_shrink[filll]:=0
-
-@ @<Examine node |p| in the hlist, taking account of its effect...@>=
-@^inner loop@>
-begin while is_char_node(p) do
- @<Incorporate character dimensions into the dimensions of
- the hbox that will contain~it, then move to the next node@>;
-if p<>null then
- begin case type(p) of
- hlist_node_case,vlist_node_case,rule_node_case,unset_node_case:
- @<Incorporate box dimensions into the dimensions of
- the hbox that will contain~it@>;
- ins_node_case,mark_node_case,adjust_node_case: begin if adjust_tail<>null then
- @<Transfer node |p| to the adjustment list@>; end;
- whatsit_node_case:@<Incorporate a whatsit node into an hbox@>;
- glue_node_case:@<Incorporate glue into the horizontal totals@>;
- margin_kern_node_case: begin
- if m = cal_expand_ratio then begin
- f := font(margin_char(p));
- do_subst_font(margin_char(p), 1000);
- if f <> font(margin_char(p)) then
- font_stretch := font_stretch - width(p) -
- char_pw(margin_char(p), subtype(p));
- font(margin_char(p)) := f;
- do_subst_font(margin_char(p), -1000);
- if f <> font(margin_char(p)) then
- font_shrink := font_shrink - width(p) -
- char_pw(margin_char(p), subtype(p));
- font(margin_char(p)) := f;
- end
- else if m = subst_ex_font then begin
- do_subst_font(margin_char(p), font_expand_ratio);
- width(p) := -char_pw(margin_char(p), subtype(p));
- end;
- x := x + width(p);
- end;
- kern_node_case: begin
- if subtype(p) = normal then begin
- if m = cal_expand_ratio then begin
- font_stretch := font_stretch + kern_stretch(p);
- font_shrink := font_shrink + kern_shrink(p);
- end
- else if m = subst_ex_font then begin
- if font_expand_ratio > 0 then
- k := kern_stretch(p)
- else if font_expand_ratio < 0 then
- k := kern_shrink(p)
- else
- pdfassert(0);
- if k <> 0 then
- width(p) := get_kern(font(prev_char_p),
- character(prev_char_p),
- character(vlink(p)))
- end;
- end;
- x := x + width(p);
- end;
- 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 (subtype(p)<>select_disc)and(vlink(no_break(p))<>null) then begin
- pack_interrupt[disc_level]:=vlink(p);
- incr(disc_level);
- p:=no_break(p);
- end;
- end;
- othercases do_nothing
- endcases;@/
- p:=vlink(p);
- end;
-end
-
-
-@ The code here implicitly uses the fact that running dimensions are
-indicated by |null_flag|, which will be ignored in the calculations
-because it is a highly negative number.
-
-@<Incorporate box dimensions into the dimensions of the hbox...@>=
-begin
-if (type(p)=hlist_node) or (type(p)=vlist_node) then begin
- if dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[hpack_dir]) then begin
- x:=x+height(p)+depth(p);
- s:=shift_amount(p);
- 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
- x:=x+width(p);
- s:=shift_amount(p);
- if depth(p)-s>h then h:=depth(p)-s;
- if height(p)+s>d then d:=height(p)+s;
- end
- else begin
- x:=x+width(p);
- s:=shift_amount(p);
- if height(p)-s>h then h:=height(p)-s;
- if depth(p)+s>d then d:=depth(p)+s;
- end
- end
-else begin
- x:=x+width(p);
- if type(p)>=rule_node then s:=0 @+else s:=shift_amount(p);
- if height(p)-s>h then h:=height(p)-s;
- if depth(p)+s>d then d:=depth(p)+s;
- end;
-end
-
-@ The following code is part of \TeX's inner loop; i.e., adding another
-character of text to the user's input will cause each of these instructions
-to be exercised one more time.
-@^inner loop@>
-
-@d add_char_stretch_end(#) == char_stretch(#)
-@d add_char_stretch(#) == # := # + add_char_stretch_end
-
-@d add_char_shrink_end(#) == char_shrink(#)
-@d add_char_shrink(#) == # := # + add_char_shrink_end
-
-@<Incorporate character dimensions into the dimensions of the hbox...@>=
-begin
-if m >= cal_expand_ratio then begin
- prev_char_p := p;
- case m of
- cal_expand_ratio: begin
- add_char_stretch(font_stretch)(p);
- add_char_shrink(font_shrink)(p);
- end;
- subst_ex_font:
- do_subst_font(p, font_expand_ratio);
- endcases;
-end;
-f:=font(p);
-if is_rotated(hpack_dir) then begin
- x:=x+glyph_height(p)+glyph_depth(p);@/
- s:=glyph_width(p) div 2;@+if s>h then h:=s;@+if s>d then d:=s;
- end
-else if dir_opposite(dir_tertiary[hpack_dir])(dir_tertiary[box_dir(r)])
- then begin
- x:=x+glyph_width(p);@/
- s:=glyph_depth(p);@+if s>h then h:=s;
- s:=glyph_height(p);@+if s>d then d:=s;
- end
-else begin
- x:=x+glyph_width(p);@/
- s:=glyph_height(p);@+if s>h then h:=s;
- s:=glyph_depth(p);@+if s>d then d:=s;
- end;
-p:=vlink(p);
-end
-
-@ Although node |q| is not necessarily the immediate predecessor of node |p|,
-it always points to some node in the list preceding |p|. Thus, we can delete
-nodes by moving |q| when necessary. The algorithm takes linear time, and the
-extra computation does not intrude on the inner loop unless it is necessary
-to make a deletion.
-@^inner loop@>
-
-@<Glob...@>=
-@!pre_adjust_tail: pointer;
-
-@ @<Set init...@>=
-pre_adjust_tail := null;
-
-@ Materials in \.{\\vadjust} used with \.{pre} keyword will be appended to
-|pre_adjust_tail| instead of |adjust_tail|.
-
-@d update_adjust_list(#) == begin
- vlink(#) := adjust_ptr(p);
- while vlink(#) <> null do
- # := vlink(#);
-end
-
-@<Transfer node |p| to the adjustment list@>=
-begin while vlink(q)<>p do q:=vlink(q);
- if type(p) = adjust_node then begin
- if adjust_pre(p) <> 0 then
- update_adjust_list(pre_adjust_tail)
- else
- update_adjust_list(adjust_tail);
- p := vlink(p);
- adjust_ptr(vlink(q)):=null; flush_node(vlink(q));
- end
-else begin vlink(adjust_tail):=p; adjust_tail:=p; p:=vlink(p);
- end;
-vlink(q):=p; p:=q;
-end
-
-@ @<Incorporate glue into the horizontal totals@>=
-begin g:=glue_ptr(p); x:=x+width(g);@/
-o:=stretch_order(g); total_stretch[o]:=total_stretch[o]+stretch(g);
-o:=shrink_order(g); total_shrink[o]:=total_shrink[o]+shrink(g);
-if subtype(p)>=a_leaders then
- begin g:=leader_ptr(p);
- if height(g)>h then h:=height(g);
- if depth(g)>d then d:=depth(g);
- end;
-end
-
-@ When we get to the present part of the program, |x| is the natural width
-of the box being packaged.
-
-@<Determine the value of |width(r)| and the appropriate glue setting...@>=
-if m=additional then w:=x+w;
-width(r):=w; x:=w-x; {now |x| is the excess to be made up}
-if x=0 then
- begin glue_sign(r):=normal; glue_order(r):=normal;
- set_glue_ratio_zero(glue_set(r));
- return;
- end
-else if x>0 then @<Determine horizontal glue stretch setting, then |return|
- or \hbox{|goto common_ending|}@>
-else @<Determine horizontal glue shrink setting, then |return|
- or \hbox{|goto common_ending|}@>
-
-@ If |hpack| is called with |m=cal_expand_ratio| we calculate
-|font_expand_ratio| and return without checking for overfull or underfull box.
-
-@<Determine horizontal glue stretch setting...@>=
-begin @<Determine the stretch order@>;
-if (m = cal_expand_ratio) and (o = normal) and (font_stretch > 0) then begin
- font_expand_ratio := divide_scaled_n(x, font_stretch, 1000.0);
- return;
-end;
-glue_order(r):=o; glue_sign(r):=stretching;
-if total_stretch[o]<>0 then glue_set(r):=unfloat(x/total_stretch[o])
-@^real division@>
-else begin glue_sign(r):=normal;
- set_glue_ratio_zero(glue_set(r)); {there's nothing to stretch}
- end;
-if o=normal then if list_ptr(r)<>null then
- @<Report an underfull hbox and |goto common_ending|, if this box
- is sufficiently bad@>;
-return;
-end
-
-@ @<Determine the stretch order@>=
-if total_stretch[filll]<>0 then o:=filll
-else if total_stretch[fill]<>0 then o:=fill
-else if total_stretch[fil]<>0 then o:=fil
-else if total_stretch[sfi]<>0 then o:=sfi
-else o:=normal
-
-@ @<Report an underfull hbox and |goto common_ending|, if...@>=
-begin last_badness:=badness(x,total_stretch[normal]);
-if last_badness>hbadness then
- begin print_ln;
- if last_badness>100 then print_nl("Underfull")@+else print_nl("Loose");
- print(" \hbox (badness "); print_int(last_badness);
-@.Underfull \\hbox...@>
-@.Loose \\hbox...@>
- goto common_ending;
- end;
-end
-
-@ In order to provide a decent indication of where an overfull or underfull
-box originated, we use a global variable |pack_begin_line| that is
-set nonzero only when |hpack| is being called by the paragraph builder
-or the alignment finishing routine.
-
-@<Glob...@>=
-@!pack_begin_line:integer; {source file line where the current paragraph
- or alignment began; a negative value denotes alignment}
-
-@ @<Set init...@>=
-pack_begin_line:=0;
-
-@ @<Finish issuing a diagnostic message for an overfull or underfull hbox@>=
-if output_active then print(") has occurred while \output is active")
-else begin if pack_begin_line<>0 then
- begin if pack_begin_line>0 then print(") in paragraph at lines ")
- else print(") in alignment at lines ");
- print_int(abs(pack_begin_line));
- print("--");
- end
- else print(") detected at line ");
- print_int(line);
- end;
-print_ln;@/
-font_in_short_display:=null_font; short_display(list_ptr(r)); print_ln;@/
-begin_diagnostic; show_box(r); end_diagnostic(true)
-
-@ @<Determine horizontal glue shrink setting...@>=
-begin @<Determine the shrink order@>;
-if (m = cal_expand_ratio) and (o = normal) and (font_shrink > 0) then begin
- font_expand_ratio := divide_scaled_n(x, font_shrink, 1000.0);
- return;
-end;
-glue_order(r):=o; glue_sign(r):=shrinking;
-if total_shrink[o]<>0 then glue_set(r):=unfloat((-x)/total_shrink[o])
-@^real division@>
-else begin glue_sign(r):=normal;
- set_glue_ratio_zero(glue_set(r)); {there's nothing to shrink}
- end;
-if (total_shrink[o]<-x)and(o=normal)and(list_ptr(r)<>null) then
- begin last_badness:=1000000;
- set_glue_ratio_one(glue_set(r)); {use the maximum shrinkage}
- @<Report an overfull hbox and |goto common_ending|, if this box
- is sufficiently bad@>;
- end
-else if o=normal then if list_ptr(r)<>null then
- @<Report a tight hbox and |goto common_ending|, if this box
- is sufficiently bad@>;
-return;
-end
-
-@ @<Determine the shrink order@>=
-if total_shrink[filll]<>0 then o:=filll
-else if total_shrink[fill]<>0 then o:=fill
-else if total_shrink[fil]<>0 then o:=fil
-else if total_shrink[sfi]<>0 then o:=sfi
-else o:=normal
-
-@ @<Report an overfull hbox and |goto common_ending|, if...@>=
-if (-x-total_shrink[normal]>hfuzz)or(hbadness<100) then
- begin if (overfull_rule>0)and(-x-total_shrink[normal]>hfuzz) then
- begin while vlink(q)<>null do q:=vlink(q);
- vlink(q):=new_rule; rule_dir(vlink(q)):=box_dir(r);
- width(vlink(q)):=overfull_rule;
- end;
- print_ln; print_nl("Overfull \hbox (");
-@.Overfull \\hbox...@>
- print_scaled(-x-total_shrink[normal]); print("pt too wide");
- goto common_ending;
- end
-
-@ @<Report a tight hbox and |goto common_ending|, if...@>=
-begin last_badness:=badness(-x,total_shrink[normal]);
-if last_badness>hbadness then
- begin print_ln; print_nl("Tight \hbox (badness "); print_int(last_badness);
-@.Tight \\hbox...@>
- goto common_ending;
- end;
-end
-
-@ The |vpack| subroutine is actually a special case of a slightly more
-general routine called |vpackage|, which has four parameters. The fourth
-parameter, which is |max_dimen| in the case of |vpack|, specifies the
-maximum depth of the page box that is constructed. The depth is first
-computed by the normal rules; if it exceeds this limit, the reference
-point is simply moved down until the limiting depth is attained.
-
-@d vpack(#)==vpackage(#,max_dimen) {special case of unconstrained depth}
-
-@p function vpackage(@!p:pointer;@!h:scaled;@!m:small_number;@!l:scaled):
- pointer;
-label common_ending, exit;
-var r:pointer; {the box node that will be returned}
-@!w,@!d,@!x:scaled; {width, depth, and natural height}
-@!s:scaled; {shift amount}
-@!g:pointer; {points to a glue specification}
-@!o:glue_ord; {order of infinity}
-begin last_badness:=0;
-{pdfassert(p<>0);}
-r:=new_node(vlist_node,0);
-if pack_direction=-1 then
- box_dir(r):=body_direction
-else begin
- box_dir(r):=pack_direction; pack_direction:=-1;
- end;
-subtype(r):=min_quarterword; shift_amount(r):=0;
-list_ptr(r):=p;@/
-w:=0; @<Clear dimensions to zero@>;
-while p<>null do @<Examine node |p| in the vlist, taking account of its effect
- on the dimensions of the new box; then advance |p| to the next node@>;
-width(r):=w;
-if d>l then
- begin x:=x+d-l; depth(r):=l;
- end
-else depth(r):=d;
-@<Determine the value of |height(r)| and the appropriate glue setting;
- then |return| or |goto common_ending|@>;
-common_ending: @<Finish issuing a diagnostic message
- for an overfull or underfull vbox@>;
-exit: vpackage:=r;
-end;
-
-function filtered_vpackage(@!p:pointer;@!h:scaled;@!m:small_number;@!l:scaled;@!grp:integer):pointer;
-var q:pointer;
-begin
- q:=p;
- q:=lua_vpack_filter(q,h,m,l,grp);
- filtered_vpackage:=vpackage(q,h,m,l);
-end;
-
-@ @<Examine node |p| in the vlist, taking account of its effect...@>=
-begin if is_char_node(p) then confusion("vpack")
-@:this can't happen vpack}{\quad vpack@>
-else case type(p) of
- hlist_node_case,vlist_node_case,rule_node_case,unset_node_case:
- @<Incorporate box dimensions into the dimensions of
- the vbox that will contain~it@>;
- whatsit_node_case:@<Incorporate a whatsit node into a vbox@>;
- glue_node_case: @<Incorporate glue into the vertical totals@>;
- kern_node_case: begin x:=x+d+width(p); d:=0;
- end;
- othercases do_nothing
- endcases;
-p:=vlink(p);
-end
-
-@ @<Incorporate box dimensions into the dimensions of the vbox...@>=
-begin
-if (type(p)=hlist_node) or (type(p)=vlist_node) then begin
- if dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[box_dir(r)]) then begin
- x:=x+d+(width(p) div 2); d:=width(p) div 2;
- 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
- x:=x+d+depth(p); d:=height(p);
- s:=shift_amount(p);
- if width(p)+s>w then w:=width(p)+s;
- end
- else begin
- x:=x+d+height(p); d:=depth(p);
- s:=shift_amount(p);
- if width(p)+s>w then w:=width(p)+s;
- end
- end
-else
- begin x:=x+d+height(p); d:=depth(p);
- if type(p)>=rule_node then s:=0 @+else s:=shift_amount(p);
- if width(p)+s>w then w:=width(p)+s;
- end;
-end
-
-@ @<Incorporate glue into the vertical totals@>=
-begin x:=x+d; d:=0;@/
-g:=glue_ptr(p); x:=x+width(g);@/
-o:=stretch_order(g); total_stretch[o]:=total_stretch[o]+stretch(g);
-o:=shrink_order(g); total_shrink[o]:=total_shrink[o]+shrink(g);
-if subtype(p)>=a_leaders then
- begin g:=leader_ptr(p);
- if width(g)>w then w:=width(g);
- end;
-end
-
-@ When we get to the present part of the program, |x| is the natural height
-of the box being packaged.
-
-@<Determine the value of |height(r)| and the appropriate glue setting...@>=
-if m=additional then h:=x+h;
-height(r):=h; x:=h-x; {now |x| is the excess to be made up}
-if x=0 then
- begin glue_sign(r):=normal; glue_order(r):=normal;
- set_glue_ratio_zero(glue_set(r));
- return;
- end
-else if x>0 then @<Determine vertical glue stretch setting, then |return|
- or \hbox{|goto common_ending|}@>
-else @<Determine vertical glue shrink setting, then |return|
- or \hbox{|goto common_ending|}@>
-
-@ @<Determine vertical glue stretch setting...@>=
-begin @<Determine the stretch order@>;
-glue_order(r):=o; glue_sign(r):=stretching;
-if total_stretch[o]<>0 then glue_set(r):=unfloat(x/total_stretch[o])
-@^real division@>
-else begin glue_sign(r):=normal;
- set_glue_ratio_zero(glue_set(r)); {there's nothing to stretch}
- end;
-if o=normal then if list_ptr(r)<>null then
- @<Report an underfull vbox and |goto common_ending|, if this box
- is sufficiently bad@>;
-return;
-end
-
-@ @<Report an underfull vbox and |goto common_ending|, if...@>=
-begin last_badness:=badness(x,total_stretch[normal]);
-if last_badness>vbadness then
- begin print_ln;
- if last_badness>100 then print_nl("Underfull")@+else print_nl("Loose");
- print(" \vbox (badness "); print_int(last_badness);
-@.Underfull \\vbox...@>
-@.Loose \\vbox...@>
- goto common_ending;
- end;
-end
-
-@ @<Finish issuing a diagnostic message for an overfull or underfull vbox@>=
-if output_active then print(") has occurred while \output is active")
-else begin if pack_begin_line<>0 then {it's actually negative}
- begin print(") in alignment at lines ");
- print_int(abs(pack_begin_line));
- print("--");
- end
- else print(") detected at line ");
- print_int(line);
- print_ln;@/
- end;
-begin_diagnostic; show_box(r); end_diagnostic(true)
-
-@ @<Determine vertical glue shrink setting...@>=
-begin @<Determine the shrink order@>;
-glue_order(r):=o; glue_sign(r):=shrinking;
-if total_shrink[o]<>0 then glue_set(r):=unfloat((-x)/total_shrink[o])
-@^real division@>
-else begin glue_sign(r):=normal;
- set_glue_ratio_zero(glue_set(r)); {there's nothing to shrink}
- end;
-if (total_shrink[o]<-x)and(o=normal)and(list_ptr(r)<>null) then
- begin last_badness:=1000000;
- set_glue_ratio_one(glue_set(r)); {use the maximum shrinkage}
- @<Report an overfull vbox and |goto common_ending|, if this box
- is sufficiently bad@>;
- end
-else if o=normal then if list_ptr(r)<>null then
- @<Report a tight vbox and |goto common_ending|, if this box
- is sufficiently bad@>;
-return;
-end
-
-@ @<Report an overfull vbox and |goto common_ending|, if...@>=
-if (-x-total_shrink[normal]>vfuzz)or(vbadness<100) then
- begin print_ln; print_nl("Overfull \vbox (");
-@.Overfull \\vbox...@>
- print_scaled(-x-total_shrink[normal]); print("pt too high");
- goto common_ending;
- end
-
-@ @<Report a tight vbox and |goto common_ending|, if...@>=
-begin last_badness:=badness(-x,total_shrink[normal]);
-if last_badness>vbadness then
- begin print_ln; print_nl("Tight \vbox (badness "); print_int(last_badness);
-@.Tight \\vbox...@>
- goto common_ending;
- end;
-end
-
-@ When a box is being appended to the current vertical list, the
-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 node}
-begin if prev_depth>pdf_ignored_dimen then
- begin
- 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);
- if d<line_skip_limit then p:=new_param_glue(line_skip_code)
- else begin p:=new_skip_param(baseline_skip_code);
- width(temp_ptr):=d; {|temp_ptr=glue_ptr(p)|}
- end;
- vlink(tail):=p; tail:=p;
- end;
-vlink(tail):=b; tail:=b;
-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.
-
-Is done in C.
-
-@* \[35] Subroutines for math mode.
-
-Is one in C.
-
-@* \[36] Typesetting math formulas.
-
-Is done in C.
-
-@* \[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.
-
-@ 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 u_part(#)==vlink(#+depth_offset) {pointer to \<u_j> token list}
-@d v_part(#)==vinfo(#+depth_offset) {pointer to \<v_j> token list}
-@d span_ptr(#)==vinfo(#+1) {column spanning list}
-@d extra_info(#)==vinfo(#+list_offset) {info to remember during template}
-
-@ Alignments can occur within alignments, so a small stack is used to access
-the alignrecord information. At each level we have a |preamble| pointer,
-indicating the beginning of the preamble list; a |cur_align| pointer,
-indicating the current position in the preamble list; a |cur_span| pointer,
-indicating the value of |cur_align| at the beginning of a sequence of
-spanned columns; a |cur_loop| pointer, indicating the tabskip glue before
-an alignrecord that should be copied next if the current list is extended;
-and the |align_state| variable, which indicates the nesting of braces so
-that \.{\\cr} and \.{\\span} and tab marks are properly intercepted.
-There also are pointers |cur_head| and |cur_tail| to the head and tail
-of a list of adjustments being moved out from horizontal mode to
-vertical~mode, and alike |cur_pre_head| and |cur_pre_tail| for pre-adjust
-lists.
-
-The current values of these nine quantities appear in global variables;
-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}
-
-@<Glob...@>=
-@!cur_align:pointer; {current position in preamble list}
-@!cur_span:pointer; {start of currently spanned columns in preamble list}
-@!cur_loop:pointer; {place to copy when extending a periodic preamble}
-@!align_ptr:pointer; {most recently pushed-down alignment stack node}
-@!cur_head,@!cur_tail:pointer; {adjustment list pointers}
-@!cur_pre_head,@!cur_pre_tail:pointer; {pre-adjustment list pointers}
-
-@ The |align_state| and |preamble| variables are initialized elsewhere.
-
-@<Set init...@>=
-align_ptr:=null; cur_align:=null; cur_span:=null; cur_loop:=null;
-cur_head:=null; cur_tail:=null;
-cur_pre_head:=null; cur_pre_tail:=null;
-
-@ Alignment stack maintenance is handled by a pair of trivial routines
-called |push_alignment| and |pop_alignment|.
-
-@p procedure push_alignment;
-var p:pointer; {the new alignment stack node}
-begin p:=new_node(align_stack_node,0);
-vinfo(p+1):=align_ptr; vlink(p+1):=cur_align;
-vinfo(p+2):=preamble; vlink(p+2):=cur_span;
-vinfo(p+3):=cur_loop; vlink(p+3):=align_state;
-vinfo(p+4):=cur_head; vlink(p+4):=cur_tail;
-vinfo(p+5):=cur_pre_head; vlink(p+5):=cur_pre_tail;
-align_ptr:=p;
-cur_head:=new_node(temp_node,0);
-end;
-@#
-procedure pop_alignment;
-var p:pointer; {the top alignment stack node}
-begin flush_node(cur_head);
-p:=align_ptr;
-cur_pre_tail:=vlink(p+5); cur_pre_head:=vinfo(p+5);
-cur_tail :=vlink(p+4); cur_head :=vinfo(p+4);
-align_state :=vlink(p+3); cur_loop :=vinfo(p+3);
-cur_span :=vlink(p+2); preamble :=vinfo(p+2);
-cur_align :=vlink(p+1); align_ptr :=vinfo(p+1);
-flush_node(p);
-end;
-
-@ \TeX\ has eight procedures that govern alignments: |init_align| and
-|fin_align| are used at the very beginning and the very end; |init_row| and
-|fin_row| are used at the beginning and end of individual rows; |init_span|
-is used at the beginning of a sequence of spanned columns (possibly involving
-only one column); |init_col| and |fin_col| are used at the beginning and
-end of individual columns; and |align_peek| is used after \.{\\cr} to see
-whether the next item is \.{\\noalign}.
-
-We shall consider these routines in the order they are first used during
-the course of a complete \.{\\halign}, namely |init_align|, |align_peek|,
-|init_row|, |init_span|, |init_col|, |fin_col|, |fin_row|, |fin_align|.
-
-@ When \.{\\halign} or \.{\\valign} has been scanned in an appropriate
-mode, \TeX\ calls |init_align|, whose task is to get everything off to a
-good start. This mostly involves scanning the preamble and putting its
-information into the preamble list.
-@^preamble@>
-
-@p @t\4@>@<Declare the procedure called |get_preamble_token|@>@t@>@/
-procedure@?align_peek; forward;@t\2@>@/
-procedure@?normal_paragraph; forward;@t\2@>@/
-procedure init_align;
-label done, done1, done2, continue;
-var save_cs_ptr:pointer; {|warning_index| value for error messages}
-@!p,r:pointer; {for short-term temporary use}
-begin save_cs_ptr:=cur_cs; {\.{\\halign} or \.{\\valign}, usually}
-push_alignment; align_state:=-1000000; {enter a new alignment level}
-@<Check for improper alignment in displayed math@>;
-push_nest; {enter a new semantic level}
-@<Change current mode to |-vmode| for \.{\\halign}, |-hmode| for \.{\\valign}@>;
-scan_spec(align_group,false);@/
-@<Scan the preamble and record it in the |preamble| list@>;
-new_save_level(align_group);
-if every_cr<>null then begin_token_list(every_cr,every_cr_text);
-align_peek; {look for \.{\\noalign} or \.{\\omit}}
-end;
-
-@ In vertical modes, |prev_depth| already has the correct value. But
-if we are in |mmode| (displayed formula mode), we reach out to the
-enclosing vertical mode for the |prev_depth| value that produces the
-correct baseline calculations.
-
-@<Change current mode...@>=
-if mode=mmode then
- begin mode:=-vmode; prev_depth:=nest[nest_ptr-2].aux_field.sc;
- end
-else if mode>0 then negate(mode)
-
-@ When \.{\\halign} is used as a displayed formula, there should be
-no other pieces of mlists present.
-
-@<Check for improper alignment in displayed math@>=
-if (mode=mmode)and((tail<>head)or(incompleat_noad<>null)) then
- begin print_err("Improper "); print_esc("halign"); print(" inside $$'s");
-@.Improper \\halign...@>
- help3("Displays can use special alignments (like \eqalignno)")@/
- ("only if nothing but the alignment itself is between $$'s.")@/
- ("So I've deleted the formulas that preceded this alignment.");
- error; flush_math;
- end
-
-@ @<Scan the preamble and record it in the |preamble| list@>=
-preamble:=null; cur_align:=align_head; cur_loop:=null; scanner_status:=aligning;
-warning_index:=save_cs_ptr; align_state:=-1000000;
- {at this point, |cur_cmd=left_brace|}
-loop@+ begin @<Append the current tabskip glue to the preamble list@>;
- if cur_cmd=car_ret then goto done; {\.{\\cr} ends the preamble}
- @<Scan preamble text until |cur_cmd| is |tab_mark| or |car_ret|,
- looking for changes in the tabskip glue; append an
- alignrecord to the preamble list@>;
- end;
-done: scanner_status:=normal
-
-@ @<Append the current tabskip glue to the preamble list@>=
-r:=new_param_glue(tab_skip_code); vlink(cur_align):=r;
-cur_align:=vlink(cur_align)
-
-@ @<Scan preamble text until |cur_cmd| is |tab_mark| or |car_ret|...@>=
-@<Scan the template \<u_j>, putting the resulting token list in |hold_token_head|@>;
-r:=new_node(align_record_node,0); vlink(cur_align):=r;
-cur_align:=vlink(cur_align); {a new alignrecord}
-span_ptr(cur_align):=end_span; width(cur_align):=null_flag;
-u_part(cur_align):=link(hold_token_head);
-@<Scan the template \<v_j>, putting the resulting token list in |hold_token_head|@>;
-v_part(cur_align):=link(hold_token_head)
-
-@ We enter `\.{\\span}' into |eqtb| with |tab_mark| as its command code,
-and with |span_code| as the command modifier. This makes \TeX\ interpret it
-essentially the same as an alignment delimiter like `\.\&', yet it is
-recognizably different when we need to distinguish it from a normal delimiter.
-It also turns out to be useful to give a special |cr_code| to `\.{\\cr}',
-and an even larger |cr_cr_code| to `\.{\\crcr}'.
-
-The end of a template is represented by two ``frozen'' control sequences
-called \.{\\endtemplate}. The first has the command code |end_template|, which
-is |>outer_call|, so it will not easily disappear in the presence of errors.
-The |get_x_token| routine converts the first into the second, which has |endv|
-as its command code.
-
-@d span_code=special_char {distinct from any character}
-@d cr_code=span_code+1 {distinct from |span_code| and from any character}
-@d cr_cr_code=cr_code+1 {this distinguishes \.{\\crcr} from \.{\\cr}}
-@d end_template_token==cs_token_flag+frozen_end_template
-
-@<Put each of \TeX's primitives into the hash table@>=
-primitive_tex("span",tab_mark,span_code,span_code);@/
-@!@:span_}{\.{\\span} primitive@>
-primitive_tex("cr",car_ret,cr_code,cr_code);
-@!@:cr_}{\.{\\cr} primitive@>
-text(frozen_cr):="cr"; eqtb[frozen_cr]:=eqtb[cur_val];@/
-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;
-eq_level(frozen_endv):=level_one;@/
-eqtb[frozen_end_template]:=eqtb[frozen_endv];
-eq_type(frozen_end_template):=end_template;
-
-@ 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.
-
-Note that if the preamble contains `\.{\\global\\tabskip}', the `\.{\\global}'
-token survives in the preamble and the `\.{\\tabskip}' defines new
-tabskip glue (locally).
-
-@<Declare the procedure called |get_preamble_token|@>=
-procedure get_preamble_token;
-label restart;
-begin restart: get_token;
-while (cur_chr=span_code)and(cur_cmd=tab_mark) do
- begin get_token; {this token will be expanded once}
- if cur_cmd>max_command then
- begin expand; get_token;
- end;
- end;
-if cur_cmd=endv then
- fatal_error("(interwoven alignment preambles are not allowed)");
-@.interwoven alignment preambles...@>
-if (cur_cmd=assign_glue)and(cur_chr=glue_base+tab_skip_code) then
- begin scan_optional_equals; scan_glue(glue_val);
- if global_defs>0 then geq_define(glue_base+tab_skip_code,glue_ref,cur_val)
- else eq_define(glue_base+tab_skip_code,glue_ref,cur_val);
- goto restart;
- end;
-end;
-
-@ Spaces are eliminated from the beginning of a template.
-
-@<Scan the template \<u_j>...@>=
-p:=hold_token_head; link(p):=null;
-loop@+ begin get_preamble_token;
- if cur_cmd=mac_param then goto done1;
- if (cur_cmd<=car_ret)and(cur_cmd>=tab_mark)and(align_state=-1000000) then
- if (p=hold_token_head)and(cur_loop=null)and(cur_cmd=tab_mark)
- then cur_loop:=cur_align
- else begin print_err("Missing # inserted in alignment preamble");
-@.Missing \# inserted...@>
- help3("There should be exactly one # between &'s, when an")@/
- ("\halign or \valign is being set up. In this case you had")@/
- ("none, so I've put one in; maybe that will work.");
- back_error; goto done1;
- end
- else if (cur_cmd<>spacer)or(p<>hold_token_head) then
- begin r:=get_avail; link(p):=r; p:=link(p); info(p):=cur_tok;
- end;
- end;
-done1:
-
-@ @<Scan the template \<v_j>...@>=
-p:=hold_token_head; link(p):=null;
-loop@+ begin continue: get_preamble_token;
- if (cur_cmd<=car_ret)and(cur_cmd>=tab_mark)and(align_state=-1000000) then
- goto done2;
- if cur_cmd=mac_param then
- begin print_err("Only one # is allowed per tab");
-@.Only one \# is allowed...@>
- help3("There should be exactly one # between &'s, when an")@/
- ("\halign or \valign is being set up. In this case you had")@/
- ("more than one, so I'm ignoring all but the first.");
- error; goto continue;
- end;
- r:=get_avail; link(p):=r; p:=link(p); info(p):=cur_tok;
- end;
-done2: r:=get_avail; link(p):=r; p:=link(p);
-info(p):=end_template_token {put \.{\\endtemplate} at the end}
-
-@ The tricky part about alignments is getting the templates into the
-scanner at the right time, and recovering control when a row or column
-is finished.
-
-We usually begin a row after each \.{\\cr} has been sensed, unless that
-\.{\\cr} is followed by \.{\\noalign} or by the right brace that terminates
-the alignment. The |align_peek| routine is used to look ahead and do
-the right thing; it either gets a new row started, or gets a \.{\\noalign}
-started, or finishes off the alignment.
-
-@<Declare the procedure called |align_peek|@>=
-procedure align_peek;
-label restart;
-begin restart: align_state:=1000000;
-repeat get_x_or_protected;
-until cur_cmd<>spacer;
-if cur_cmd=no_align then
- begin scan_left_brace; new_save_level(no_align_group);
- if mode=-vmode then normal_paragraph;
- end
-else if cur_cmd=right_brace then fin_align
-else if (cur_cmd=car_ret)and(cur_chr=cr_cr_code) then
- goto restart {ignore \.{\\crcr}}
-else begin init_row; {start a new row}
- init_col; {start a new column and replace what we peeked at}
- end;
-end;
-
-@ To start a row (i.e., a `row' that rhymes with `dough' but not with `bough'),
-we enter a new semantic level, copy the first tabskip glue, and change
-from internal vertical mode to restricted horizontal mode or vice versa.
-The |space_factor| and |prev_depth| are not used on this semantic level,
-but we clear them to zero just to be tidy.
-
-@p @t\4@>@<Declare the procedure called |init_span|@>@t@>@/
-procedure init_row;
-begin push_nest; mode:=(-hmode-vmode)-mode;
-if mode=-hmode then space_factor:=0 @+else prev_depth:=0;
-tail_append(new_glue(glue_ptr(preamble)));
-subtype(tail):=tab_skip_code+1;@/
-cur_align:=vlink(preamble); cur_tail:=cur_head; cur_pre_tail:=cur_pre_head;
-init_span(cur_align);
-end;
-
-@ The parameter to |init_span| is a pointer to the alignrecord where the
-next column or group of columns will begin. A new semantic level is
-entered, so that the columns will generate a list for subsequent packaging.
-
-@<Declare the procedure called |init_span|@>=
-procedure init_span(@!p:pointer);
-begin push_nest;
-if mode=-hmode then space_factor:=1000
-else begin prev_depth:=pdf_ignored_dimen; normal_paragraph;
- end;
-cur_span:=p;
-end;
-
-@ When a column begins, we assume that |cur_cmd| is either |omit| or else
-the current token should be put back into the input until the \<u_j>
-template has been scanned. (Note that |cur_cmd| might be |tab_mark| or
-|car_ret|.) We also assume that |align_state| is approximately 1000000 at
-this time. We remain in the same mode, and start the template if it is
-called for.
-
-@p procedure init_col;
-begin extra_info(cur_align):=cur_cmd;
-if cur_cmd=omit then align_state:=0
-else begin back_input; begin_token_list(u_part(cur_align),u_template);
- end; {now |align_state=1000000|}
-end;
-
-@ The scanner sets |align_state| to zero when the \<u_j> template ends. When
-a subsequent \.{\\cr} or \.{\\span} or tab mark occurs with |align_state=0|,
-the scanner activates the following code, which fires up the \<v_j> template.
-We need to remember the |cur_chr|, which is either |cr_cr_code|, |cr_code|,
-|span_code|, or a character code, depending on how the column text has ended.
-
-This part of the program had better not be activated when the preamble
-to another alignment is being scanned, or when no alignment preamble is active.
-
-@p procedure insert_vj_template;
-begin if (scanner_status=aligning) or (cur_align=null) then
- fatal_error("(interwoven alignment preambles are not allowed)");
-@.interwoven alignment preambles...@>
-cur_cmd:=extra_info(cur_align); extra_info(cur_align):=cur_chr;
-if cur_cmd=omit then begin_token_list(omit_template,v_template)
-else begin_token_list(v_part(cur_align),v_template);
-align_state:=1000000;
-end;
-
-@ The token list |omit_template| just referred to is a constant token
-list that contains the special control sequence \.{\\endtemplate} only.
-
-@<Initialize the special...@>=
-info(omit_template):=end_template_token; {|link(omit_template)=null|}
-
-@ When the |endv| command at the end of a \<v_j> template comes through the
-scanner, things really start to happen; and it is the |fin_col| routine
-that makes them happen. This routine returns |true| if a row as well as a
-column has been finished.
-
-@p function fin_col:boolean;
-label exit;
-var p:pointer; {the alignrecord after the current one}
-@!q,@!r:pointer; {temporary pointers for list manipulation}
-@!s:pointer; {a new span node}
-@!u:pointer; {a new unset box}
-@!w:scaled; {natural width}
-@!o:glue_ord; {order of infinity}
-@!n:halfword; {span counter}
-begin if cur_align=null then confusion("endv");
-q:=vlink(cur_align);@+if q=null then confusion("endv");
-@:this can't happen endv}{\quad endv@>
-if align_state<500000 then
- fatal_error("(interwoven alignment preambles are not allowed)");
-@.interwoven alignment preambles...@>
-p:=vlink(q);
-@<If the preamble list has been traversed, check that the row has ended@>;
-if extra_info(cur_align)<>span_code then
- begin unsave; new_save_level(align_group);@/
- @<Package an unset box for the current column and record its width@>;
- @<Copy the tabskip glue between columns@>;
- if extra_info(cur_align)>=cr_code then
- begin fin_col:=true; return;
- end;
- init_span(p);
- end;
-align_state:=1000000;
-repeat get_x_or_protected;
-until cur_cmd<>spacer;
-cur_align:=p;
-init_col; fin_col:=false;
-exit: end;
-
-@ @<If the preamble list has been traversed, check that the row has ended@>=
-if (p=null)and(extra_info(cur_align)<cr_code) then begin
- if cur_loop<>null then @<Lengthen the preamble periodically@>
- else begin print_err("Extra alignment tab has been changed to ");
-@.Extra alignment tab...@>
- print_esc("cr");
- help3("You have given more \span or & marks than there were")@/
- ("in the preamble to the \halign or \valign now in progress.")@/
- ("So I'll assume that you meant to type \cr instead.");
- extra_info(cur_align):=cr_code; error;
- end;
-end
-
-@ @<Lengthen the preamble...@>=
-begin r:=new_node(align_record_node,0); vlink(q):=r; p:=vlink(q); {a new alignrecord}
-span_ptr(p):=end_span; width(p):=null_flag; cur_loop:=vlink(cur_loop);
-@<Copy the templates from node |cur_loop| into node |p|@>;
-cur_loop:=vlink(cur_loop);
-r:=new_glue(glue_ptr(cur_loop)); vlink(p):=r;
-end
-
-@ @<Copy the templates from node |cur_loop| into node |p|@>=
-q:=hold_token_head; r:=u_part(cur_loop);
-while r<>null do
- begin s:=get_avail; link(q):=s; q:=link(q); info(q):=info(r); r:=link(r);
- end;
-link(q):=null; u_part(p):=link(hold_token_head);
-q:=hold_token_head; r:=v_part(cur_loop);
-while r<>null do
- begin s:=get_avail; link(q):=s; q:=link(q); info(q):=info(r); r:=link(r);
- end;
-link(q):=null; v_part(p):=link(hold_token_head)
-
-@ @<Copy the tabskip glue...@>=
-tail_append(new_glue(glue_ptr(vlink(cur_align))));
-subtype(tail):=tab_skip_code+1
-
-@ @<Package an unset...@>=
-begin if mode=-hmode then
- begin adjust_tail:=cur_tail; pre_adjust_tail:=cur_pre_tail;
- u:=filtered_hpack(head,tail,natural,align_set_group); w:=width(u);
- cur_tail:=adjust_tail; adjust_tail:=null;
- cur_pre_tail:=pre_adjust_tail; pre_adjust_tail:=null;
- end
-else begin u:=filtered_vpackage(vlink(head),natural,0,align_set_group); w:=height(u);
- end;
-n:=min_quarterword; {this represents a span count of 1}
-if cur_span<>cur_align then @<Update width entry for spanned columns@>
-else if w>width(cur_align) then width(cur_align):=w;
-type(u):=unset_node; span_count(u):=n;@/
-@<Determine the stretch order@>;
-glue_order(u):=o; glue_stretch(u):=total_stretch[o];@/
-@<Determine the shrink order@>;
-glue_sign(u):=o; glue_shrink(u):=total_shrink[o];@/
-pop_nest; vlink(tail):=u; tail:=u;
-end
-
-@ A span node is a 3-word record containing |width|, |span_span|, and
-|span_ptr| fields. The |span_span| field indicates the number of
-spanned columns; the |span_ptr| field points to a span node for the same
-starting column, having a greater extent of spanning, or to
-|end_span|, which has the largest possible |span_span| field; the |width|
-field holds the largest natural width corresponding to a particular
-set of spanned columns.
-
-A list of the maximum widths so far, for spanned columns starting at a
-given column, begins with the |span_ptr| field of the alignrecord for
-that column. The code has to make sure that there is room for
-|span_ptr| in both the alignrecord and the span nodes, which is why
-|span_ptr| replaces |node_attr|.
-@^data structure assumptions@>
-
-The |new_span_node| function is defined in |texnodes.c|.
-
-@d span_span(#)==vlink(#+1) {that is normally |alink| }
-
-@<Initialize the special list heads...@>=
-span_span(end_span):=max_quarterword+1; span_ptr(end_span):=null;
-
-@ @<Update width entry for spanned columns@>=
-begin q:=cur_span;
-repeat incr(n); q:=vlink(vlink(q));
-until q=cur_align;
-if n>max_quarterword then confusion("too many spans"); {this can happen, but won't}
-@^system dependencies@>
-@:this can't happen too many spans}{\quad too many spans@>
-q:=cur_span;
-while span_span(span_ptr(q))<n do begin
- q:=span_ptr(q);
- end;
-if span_span(span_ptr(q))>n then begin
- s:=new_span_node(span_ptr(q),n,w);
- span_ptr(q):=s;
- end
-else if width(span_ptr(q))<w then width(span_ptr(q)):=w;
-end
-
-@ At the end of a row, we append an unset box to the current vlist (for
-\.{\\halign}) or the current hlist (for \.{\\valign}). This unset box
-contains the unset boxes for the columns, separated by the tabskip glue.
-Everything will be set later.
-
-@p procedure fin_row;
-var p:pointer; {the new unset box}
-begin if mode=-hmode then
- begin p:=filtered_hpack(head,tail,natural,fin_row_group);
- pop_nest;
- if cur_pre_head <> cur_pre_tail then
- append_list(cur_pre_head)(cur_pre_tail);
- append_to_vlist(p);
- if cur_head <> cur_tail then
- append_list(cur_head)(cur_tail);
- end
-else begin p:=filtered_vpackage(vlink(head),natural,max_depth,fin_row_group);
- pop_nest; vlink(tail):=p; tail:=p; space_factor:=1000;
- end;
-type(p):=unset_node; glue_stretch(p):=0;
-if every_cr<>null then begin_token_list(every_cr,every_cr_text);
-align_peek;
-end; {note that |glue_shrink(p)=0| since |glue_shrink==shift_amount|}
-
-@ Finally, we will reach the end of the alignment, and we can breathe a
-sigh of relief that memory hasn't overflowed. All the unset boxes will now be
-set so that the columns line up, taking due account of spanned columns.
-
-@p procedure@?do_assignments; forward;@t\2@>@/
-procedure@?resume_after_display; forward;@t\2@>@/
-procedure@?build_page; forward;@t\2@>@/
-procedure fin_align;
-var @!p,@!q,@!r,@!s,@!u,@!v,@!rr: pointer; {registers for the list operations}
-@!t,@!w:scaled; {width of column}
-@!o:scaled; {shift offset for unset boxes}
-@!n:halfword; {matching span amount}
-@!rule_save:scaled; {temporary storage for |overfull_rule|}
-@!aux_save:memory_word; {temporary storage for |aux|}
-begin if cur_group<>align_group then confusion("align1");
-@:this can't happen align}{\quad align@>
-unsave; {that |align_group| was for individual entries}
-if cur_group<>align_group then confusion("align0");
-unsave; {that |align_group| was for the whole alignment}
-if nest[nest_ptr-1].mode_field=mmode then o:=display_indent
- else o:=0;
-@<Go through the preamble list, determining the column widths and
- changing the alignrecords to dummy unset boxes@>;
-@<Package the preamble list, to determine the actual tabskip glue amounts,
- and let |p| point to this prototype box@>;
-@<Set the glue in all the unset boxes of the current list@>;
-flush_node_list(p); pop_alignment;
-@<Insert the \(c)current list into its environment@>;
-end;@/
-@t\4@>@<Declare the procedure called |align_peek|@>
-
-@ It's time now to dismantle the preamble list and to compute the column
-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+|min_quarterword|$ in their
-|link| fields. The values of $w_{ii}$ were initialized to |null_flag|, which
-we regard as $-\infty$.
-
-The final column widths are defined by the formula
-$$w_j=\max_{1\L i\L j}\biggl( w_{ij}-\sum_{i\L k<j}(t_k+w_k)\biggr),$$
-where $t_k$ is the natural width of the tabskip glue between columns
-$k$ and~$k+1$. However, if $w_{ij}=-\infty$ for all |i| in the range
-|1<=i<=j| (i.e., if every entry that involved column~|j| also involved
-column~|j+1|), we let $w_j=0$, and we zero out the tabskip glue after
-column~|j|.
-
-\TeX\ computes these values by using the following scheme: First $w_1=w_{11}$.
-Then replace $w_{2j}$ by $\max(w_{2j},w_{1j}-t_1-w_1)$, for all $j>1$.
-Then $w_2=w_{22}$. Then replace $w_{3j}$ by $\max(w_{3j},w_{2j}-t_2-w_2)$
-for all $j>2$; and so on. If any $w_j$ turns out to be $-\infty$, its
-value is changed to zero and so is the next tabskip.
-
-@<Go through the preamble list,...@>=
-q:=vlink(preamble);
-repeat flush_list(u_part(q)); flush_list(v_part(q));
-p:=vlink(vlink(q));
-if width(q)=null_flag then
- @<Nullify |width(q)| and the tabskip glue following this column@>;
-if span_ptr(q)<>end_span then
- @<Merge the widths in the span nodes of |q| with those of |p|,
- destroying the span nodes of |q|@>;
-type(q):=unset_node; span_count(q):=min_quarterword; height(q):=0;
-depth(q):=0; glue_order(q):=normal; glue_sign(q):=normal;
-glue_stretch(q):=0; glue_shrink(q):=0; q:=p;
-until q=null
-
-@ @<Nullify |width(q)| and the tabskip glue following this column@>=
-begin width(q):=0; r:=vlink(q); s:=glue_ptr(r);
-if s<>zero_glue then
- begin add_glue_ref(zero_glue); delete_glue_ref(s);
- glue_ptr(r):=zero_glue;
- end;
-end
-
-@ Merging of two span-node lists is a typical exercise in the manipulation of
-linearly linked data structures. The essential invariant in the following
-|repeat| loop is that we want to dispense with node |r|, in |q|'s list,
-and |u| is its successor; all nodes of |p|'s list up to and including |s|
-have been processed, and the successor of |s| matches |r| or precedes |r|
-or follows |r|, according as |link(r)=n| or |link(r)>n| or |link(r)<n|.
-
-@<Merge the widths...@>=
-begin t:=width(q)+width(glue_ptr(vlink(q)));
-r:=span_ptr(q); s:=end_span; span_ptr(s):=p; n:=min_quarterword+1;
-repeat width(r):=width(r)-t; u:=span_ptr(r);
-while span_span(r)>n do
- begin s:=span_ptr(s); n:=span_span(span_ptr(s))+1;
- end;
-if span_span(r)<n then
- begin span_ptr(r):=span_ptr(s); span_ptr(s):=r; decr(span_span(r)); s:=r;
- end
-else begin if width(r)>width(span_ptr(s)) then width(span_ptr(s)):=width(r);
- flush_node(r);
- end;
-r:=u;
-until r=end_span;
-end
-
-@ Now the preamble list has been converted to a list of alternating unset
-boxes and tabskip glue, where the box widths are equal to the final
-column sizes. In case of \.{\\valign}, we change the widths to heights,
-so that a correct error message will be produced if the alignment is
-overfull or underfull.
-
-@<Package the preamble list...@>=
-save_ptr:=save_ptr-2; pack_begin_line:=-mode_line;
-if mode=-vmode then
- begin rule_save:=overfull_rule;
- overfull_rule:=0; {prevent rule from being packaged}
- p:=hpack(preamble,saved(1),saved(0));
- overfull_rule:=rule_save;
- end
-else begin q:=vlink(preamble);
- repeat height(q):=width(q); width(q):=0; q:=vlink(vlink(q));
- until q=null;
- p:=filtered_vpackage(preamble,saved(1),saved(0),max_depth,preamble_group);
- q:=vlink(preamble);
- repeat width(q):=height(q); height(q):=0; q:=vlink(vlink(q));
- until q=null;
- end;
-pack_begin_line:=0
-
-@ @<Set the glue in all the unset...@>=
-q:=vlink(head); s:=head;
-while q<>null do
- begin if not is_char_node(q) then begin
- if type(q)=unset_node then
- @<Set the unset box |q| and the unset boxes in it@>
- else if type(q)=rule_node then
- @<Make the running dimensions in rule |q| extend to the
- boundaries of the alignment@>;
- end;
- s:=q; q:=vlink(q);
- end
-
-@ @<Make the running dimensions in rule |q| extend...@>=
-begin if is_running(width(q)) then width(q):=width(p);
-if is_running(height(q)) then height(q):=height(p);
-if is_running(depth(q)) then depth(q):=depth(p);
-if o<>0 then
- begin r:=vlink(q); vlink(q):=null; q:=hpack(q,natural);
- shift_amount(q):=o; vlink(q):=r; vlink(s):=q;
- end;
-end
-
-@ The unset box |q| represents a row that contains one or more unset boxes,
-depending on how soon \.{\\cr} occurred in that row.
-
-@<Set the unset box |q| and the unset boxes in it@>=
-begin if mode=-vmode then
- begin type(q):=hlist_node; width(q):=width(p);
- end
-else begin type(q):=vlist_node; height(q):=height(p);
- end;
-glue_order(q):=glue_order(p); glue_sign(q):=glue_sign(p);
-glue_set(q):=glue_set(p); shift_amount(q):=o;
-r:=vlink(list_ptr(q)); s:=vlink(list_ptr(p));
-repeat @<Set the glue in node |r| and change it from an unset node@>;
-r:=vlink(vlink(r)); s:=vlink(vlink(s));
-until r=null;
-end
-
-@ A box made from spanned columns will be followed by tabskip glue nodes and
-by empty boxes as if there were no spanning. This permits perfect alignment
-of subsequent entries, and it prevents values that depend on floating point
-arithmetic from entering into the dimensions of any boxes.
-
-@<Set the glue in node |r|...@>=
-n:=span_count(r); t:=width(s); w:=t; u:=hold_head;
-while n>min_quarterword do
- begin decr(n);
- @<Append tabskip glue and an empty box to list |u|,
- and update |s| and |t| as the prototype nodes are passed@>;
- end;
-if mode=-vmode then
- @<Make the unset node |r| into an |hlist_node| of width |w|,
- setting the glue as if the width were |t|@>
-else @<Make the unset node |r| into a |vlist_node| of height |w|,
- setting the glue as if the height were |t|@>;
-shift_amount(r):=0;
-if u<>hold_head then {append blank boxes to account for spanned nodes}
- begin vlink(u):=vlink(r); vlink(r):=vlink(hold_head); r:=u;
- end
-
-@ @<Append tabskip glue and an empty box to list |u|...@>=
-s:=vlink(s); v:=glue_ptr(s); vlink(u):=new_glue(v); u:=vlink(u);
-subtype(u):=tab_skip_code+1; t:=t+width(v);
-if glue_sign(p)=stretching then
- begin if stretch_order(v)=glue_order(p) then
- t:=t+round(float(glue_set(p))*stretch(v));
-@^real multiplication@>
- end
-else if glue_sign(p)=shrinking then
- begin if shrink_order(v)=glue_order(p) then
- t:=t-round(float(glue_set(p))*shrink(v));
- end;
-s:=vlink(s); rr:=new_null_box; vlink(u):=rr; u:=vlink(u); t:=t+width(s);
-if mode=-vmode then width(u):=width(s)@+else
- begin type(u):=vlist_node; height(u):=width(s);
- end
-
-@ @<Make the unset node |r| into an |hlist_node| of width |w|...@>=
-begin height(r):=height(q); depth(r):=depth(q);
-if t=width(r) then
- begin glue_sign(r):=normal; glue_order(r):=normal;
- set_glue_ratio_zero(glue_set(r));
- end
-else if t>width(r) then
- begin glue_sign(r):=stretching;
- if glue_stretch(r)=0 then set_glue_ratio_zero(glue_set(r))
- else glue_set(r):=unfloat((t-width(r))/glue_stretch(r));
-@^real division@>
- end
-else begin glue_order(r):=glue_sign(r); glue_sign(r):=shrinking;
- if glue_shrink(r)=0 then set_glue_ratio_zero(glue_set(r))
- else if (glue_order(r)=normal)and(width(r)-t>glue_shrink(r)) then
- set_glue_ratio_one(glue_set(r))
- else glue_set(r):=unfloat((width(r)-t)/glue_shrink(r));
- end;
-width(r):=w; type(r):=hlist_node;
-end
-
-@ @<Make the unset node |r| into a |vlist_node| of height |w|...@>=
-begin width(r):=width(q);
-if t=height(r) then
- begin glue_sign(r):=normal; glue_order(r):=normal;
- set_glue_ratio_zero(glue_set(r));
- end
-else if t>height(r) then
- begin glue_sign(r):=stretching;
- if glue_stretch(r)=0 then set_glue_ratio_zero(glue_set(r))
- else glue_set(r):=unfloat((t-height(r))/glue_stretch(r));
-@^real division@>
- end
-else begin glue_order(r):=glue_sign(r); glue_sign(r):=shrinking;
- if glue_shrink(r)=0 then set_glue_ratio_zero(glue_set(r))
- else if (glue_order(r)=normal)and(height(r)-t>glue_shrink(r)) then
- set_glue_ratio_one(glue_set(r))
- else glue_set(r):=unfloat((height(r)-t)/glue_shrink(r));
- end;
-height(r):=w; type(r):=vlist_node;
-end
-
-@ We now have a completed alignment, in the list that starts at |head|
-and ends at |tail|. This list will be merged with the one that encloses
-it. (In case the enclosing mode is |mmode|, for displayed formulas,
-we will need to insert glue before and after the display; that part of the
-program will be deferred until we're more familiar with such operations.)
-
-@<Insert the \(c)current list into its environment@>=
-aux_save:=aux; p:=vlink(head); q:=tail; pop_nest;
-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;
- end
-
-@* \[38] Breaking paragraphs into lines.
-We come now to what is probably the most interesting algorithm of \TeX:
-the mechanism for choosing the ``best possible'' breakpoints that yield
-the individual lines of a paragraph. \TeX's line-breaking algorithm takes
-a given horizontal list and converts it to a sequence of boxes that are
-appended to the current vertical list. In the course of doing this, it
-creates a special data structure containing three kinds of records that are
-not used elsewhere in \TeX. Such nodes are created while a paragraph is
-being processed, and they are destroyed afterwards; thus, the other parts
-of \TeX\ do not need to know anything about how line-breaking is done.
-
-The method used here is based on an approach devised by Michael F. Plass and
-@^Plass, Michael Frederick@>
-@^Knuth, Donald Ervin@>
-the author in 1977, subsequently generalized and improved by the same two
-people in 1980. A detailed discussion appears in {\sl SOFTWARE---Practice
-\AM\ Experience \bf11} (1981), 1119--1184, where it is shown that the
-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
-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
-current point.
-
-@ The |line_break| procedure should be invoked only in horizontal mode; it
-leaves that mode and places its output into the current vlist of the
-enclosing vertical mode (or internal vertical mode).
-There is one explicit parameter: |d| is true for partial paragraphs
-preceding display math mode; in this case the amount of additional
-penalty inserted before the final line is |display_widow_penalty|
-instead of |widow_penalty|.
-
-There are also a number of implicit parameters: The hlist to be broken
-starts at |vlink(head)|, and it is nonempty. The value of |prev_graf| in the
-enclosing semantic level tells where the paragraph should begin in the
-sequence of line numbers, in case hanging indentation or \.{\\parshape}
-are in use; |prev_graf| is zero unless this paragraph is being continued
-after a displayed formula. Other implicit parameters, such as the
-|par_shape_ptr| and various penalties to use for hyphenation, etc., appear
-in |eqtb|.
-
-After |line_break| has acted, it will have updated the current vlist and the
-value of |prev_graf|. Furthermore, the global variable |just_box| will
-point to the final box created by |line_break|, so that the width of this
-line can be ascertained when it is necessary to decide whether to use
-|above_display_skip| or |above_display_short_skip| before a displayed formula.
-
-@<Glob...@>=
-@!just_box:pointer; {the |hlist_node| for the last line of the new paragraph}
-@!paragraph_dir:integer; {main direction of paragraph}
-@!line_break_dir:integer; {current direction within paragraph}
-@!line_break_context:integer; {the surrounding state for |line_break| calls}
-@!break_c_htdp:quarterword; {height-depth entry in |char_info|}
-@!temp_no_whatsits:integer; {used when closing group}
-@!temp_no_dirs:integer; {used when closing group}
-@!temporary_dir:integer;
-@!dir_ptr,@!dir_tmp,@!dir_rover:pointer;
-
-@ @<Set init...@>=
-temp_no_whatsits:=0; temp_no_dirs:=0; temporary_dir:=0;
-dir_ptr:=null; dir_tmp:=null; dir_rover:=null;
-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 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
-the \.{\\parfillskip} glue to the end of the paragraph, removing a
-space (or other glue node) if it was there, since spaces usually
-precede blank lines and instances of `\.{\$\$}'. The |par_fill_skip|
-is preceded by an infinite penalty, so it will never be considered as
-a potential breakpoint.
-
-That code assumes that a |glue_node| and a |penalty_node| occupy the
-same number of |mem|~words.
-@^data structure assumptions@>
-
-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);
-if (not is_char_node(vlink(head))) and ((type(vlink(head))=whatsit_node)
- and (subtype(vlink(head))=local_par_node)) then
- paragraph_dir:=local_par_dir(vlink(head))
-else
- paragraph_dir:=0;
-line_break_dir:=paragraph_dir;
-tail:=new_ligkern(temp_head,tail);
-if is_char_node(tail) then new_tail_append(new_penalty(inf_penalty))
-else if type(tail)<>glue_node then new_tail_append(new_penalty(inf_penalty))
-else begin
- type(tail):=penalty_node;
- delete_glue_ref(glue_ptr(tail));
- if leader_ptr(tail)<>null then
- flush_node_list(leader_ptr(tail));
- penalty(tail):=inf_penalty;
- end;
-final_par_glue:=new_param_glue(par_fill_skip_code);
-couple_nodes(tail,final_par_glue);
-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;
-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;
-@#
-@t\4@>@<Declare \eTeX\ procedures for use by |main_control|@>
-
-@ It is possible that the user wants to interfere at some point.
-
-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_filter(#)==if not output_active then lua_node_filter_s(buildpage_filter_callback,#)
-
-@* \[39] Breaking paragraphs into lines, continued.
-
-Hyphenation and line breaking are now all handled in C. Only the
-section heads are kept here.
-
-@* \[40] Pre-hyphenation.
-
-@* \[41] Post-hyphenation.
-
-@* \[42] Hyphenation.
-
-@ When \TeX\ has scanned `\.{\\hyphenation}', it calls on a procedure named
-|new_hyph_exceptions| to do the right thing.
-
-@p procedure new_hyph_exceptions; {enters new exceptions}
-var p:halfword; {just to catch the return value of |scan_toks|}
-begin p:=scan_toks(false,true);
-load_tex_hyphenation(language,def_ref);
-flush_list(def_ref);
-end;
-
-@ Similarly, when \TeX\ has scanned `\.{\\patterns}', it calls on a
-procedure named |new_patterns|.
-
-@p procedure new_patterns; {initializes the hyphenation pattern data}
-var p:halfword; {just to catch the return value of |scan_toks|}
-begin p:=scan_toks(false,true);
-load_tex_patterns(language,def_ref);
-flush_list(def_ref);
-end;
-
-@ `\.{\\prehyphenchar}', sets the |pre_break| character, and
-`\.{\\posthyphenchar}' the |post_break| character. Their respective
-defaults are ascii hyphen ("-") and zero (nul).
-
-@p procedure new_pre_hyphen_char;
-begin scan_optional_equals; scan_int;
- set_pre_hyphen_char(language,cur_val);
-end;
-@#
-procedure new_post_hyphen_char;
-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.
-
-@* \[44] Breaking vertical lists into pages.
-The |vsplit| procedure, which implements \TeX's \.{\\vsplit} operation,
-is considerably simpler than |line_break| because it doesn't have to
-worry about hyphenation, and because its mission is to discover a single
-break instead of an optimum sequence of breakpoints. But before we get
-into the details of |vsplit|, we need to consider a few more basic things.
-
-@ A subroutine called |prune_page_top| takes a pointer to a vlist and
-returns a pointer to a modified vlist in which all glue, kern, and penalty nodes
-have been deleted before the first box or rule node. However, the first
-box or rule is actually preceded by a newly created glue node designed so that
-the topmost baseline will be at distance |split_top_skip| from the top,
-whenever this is possible without backspacing.
-
-When the second argument |s| is |false| the deleted nodes are destroyed,
-otherwise they are collected in a list starting at |split_disc|.
-
-@d discard_or_move = 60
-@p function prune_page_top(@!p:pointer;@!s:boolean):pointer;
-var prev_p:pointer; {lags one step behind |p|}
-@!q,@!r:pointer; {temporary variables for list manipulation}
-begin prev_p:=temp_head; vlink(temp_head):=p; r:=null;
-while p<>null do
- case type(p) of
- hlist_node_case,vlist_node_case,rule_node_case:@<Insert glue for |split_top_skip|
- and set~|p:=null|@>;
- whatsit_node_case,mark_node_case,ins_node_case: begin
- prev_p:=p; p:=vlink(prev_p);
- end;
- 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
- begin if split_disc=null then split_disc:=q else vlink(r):=q;
- r:=q;
- end
- else flush_node_list(q);
- end;
- othercases confusion("pruning")
-@:this can't happen pruning}{\quad pruning@>
- endcases;
-prune_page_top:=vlink(temp_head);
-end;
-
-@ @<Insert glue for |split_top_skip|...@>=
-begin q:=new_skip_param(split_top_skip_code); vlink(prev_p):=q; vlink(q):=p;
- {now |temp_ptr=glue_ptr(q)|}
-if width(temp_ptr)>height(p) then width(temp_ptr):=width(temp_ptr)-height(p)
-else width(temp_ptr):=0;
-p:=null;
-end
-
-@ The next subroutine finds the best place to break a given vertical list
-so as to obtain a box of height~|h|, with maximum depth~|d|.
-A pointer to the beginning of the vertical list is given,
-and a pointer to the optimum breakpoint is returned. The list is effectively
-followed by a forced break, i.e., a penalty node with the |eject_penalty|;
-if the best break occurs at this artificial node, the value |null| is returned.
-
-@<Glob...@>=
-@!active_height:array[1..9] of scaled;
- {distance from first active node to~|cur_p|}
-
-@ An array of six |scaled| distances is used to keep track of the height
-from the beginning of the list to the current place, just as in |line_break|.
-In fact, we use one of the same arrays, only changing its name to reflect
-its new significance.
-
-@d do_all_six(#)==#(1);#(2);#(3);#(4);#(5);#(6);#(7)
-
-@d cur_height==active_height[1] {the natural height}
-@d set_height_zero(#)==active_height[#]:=0 {initialize the height to zero}
-@#
-@d update_heights=90 {go here to record glue in the |active_height| table}
-@d awful_bad=@'7777777777 { more than a billion demerits }
-
-@p function vert_break(@!p:pointer; @!h,@!d:scaled):pointer;
- {finds optimum page break}
-label done,not_found,update_heights;
-var prev_p:pointer; {if |p| is a glue node, |type(prev_p)| determines
- whether |p| is a legal breakpoint}
-@!q,@!r:pointer; {glue specifications}
-@!pi:integer; {penalty value}
-@!b:integer; {badness at a trial breakpoint}
-@!least_cost:integer; {the smallest badness plus penalties found so far}
-@!best_place:pointer; {the most recent break that leads to |least_cost|}
-@!prev_dp:scaled; {depth of previous box in the list}
-@!t:small_number; {|type| of the node following a kern}
-begin prev_p:=p; {an initial glue node is not a legal breakpoint}
-least_cost:=awful_bad; do_all_six(set_height_zero); prev_dp:=0;
-best_place:=null; pi:=0;
-loop@+ begin @<If node |p| is a legal breakpoint, check if this break is
- the best known, and |goto done| if |p| is null or
- if the page-so-far is already too full to accept more stuff@>;
- prev_p:=p; p:=vlink(prev_p);
- end;
-done: vert_break:=best_place;
-end;
-
-@ A global variable |best_height_plus_depth| will be set to the natural size
-of the box that corresponds to the optimum breakpoint found by |vert_break|.
-(This value is used by the insertion-splitting algorithm of the page builder.)
-
-@<Glob...@>=
-@!best_height_plus_depth:scaled; {height of the best box, without stretching or
- shrinking}
-
-@ A subtle point to be noted here is that the maximum depth~|d| might be
-negative, so |cur_height| and |prev_dp| might need to be corrected even
-after a glue or kern node.
-
-@<If node |p| is a legal breakpoint, check...@>=
-if p=null then pi:=eject_penalty
-else @<Use node |p| to update the current height and depth measurements;
- if this node is not a legal breakpoint, |goto not_found|
- or |update_heights|,
- otherwise set |pi| to the associated penalty at the break@>;
-@<Check if node |p| is a new champion breakpoint; then \(go)|goto done|
- if |p| is a forced break or if the page-so-far is already too full@>;
-if (type(p)<glue_node)or(type(p)>kern_node) then goto not_found;
-update_heights: @<Update the current height and depth measurements with
- respect to a glue or kern node~|p|@>;
-not_found: if prev_dp>d then
- begin cur_height:=cur_height+prev_dp-d;
- prev_dp:=d;
- end;
-
-@ @<Use node |p| to update the current height and depth measurements...@>=
-case type(p) of
-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_case:@<Process whatsit |p| in |vert_break| loop, |goto not_found|@>;
-glue_node_case: if precedes_break(prev_p) then pi:=0
- else goto update_heights;
-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_case: pi:=penalty(p);
-mark_node_case,ins_node_case: goto not_found;
-othercases confusion("vertbreak")
-@:this can't happen vertbreak}{\quad vertbreak@>
-endcases
-
-@ @d deplorable==100000 {more than |inf_bad|, but less than |awful_bad|}
-
-@<Check if node |p| is a new champion breakpoint; then \(go)...@>=
-if pi<inf_penalty then
- begin @<Compute the badness, |b|, using |awful_bad|
- if the box is too full@>;
- if b<awful_bad then begin
- if pi<=eject_penalty then b:=pi
- else if b<inf_bad then b:=b+pi
- else b:=deplorable;
- end;
- if b<=least_cost then
- begin best_place:=p; least_cost:=b;
- best_height_plus_depth:=cur_height+prev_dp;
- end;
- if (b=awful_bad)or(pi<=eject_penalty) then goto done;
- end
-
-@ @<Compute the badness, |b|, using |awful_bad| if the box is too full@>=
-if cur_height<h then
- if (active_height[3]<>0) or (active_height[4]<>0) or
- (active_height[5]<>0) or (active_height[6]<>0) then b:=0
- else b:=badness(h-cur_height,active_height[2])
-else if cur_height-h>active_height[7] then b:=awful_bad
-else b:=badness(cur_height-h,active_height[7])
-
-@ Vertical lists that are subject to the |vert_break| procedure should not
-contain infinite shrinkability, since that would permit any amount of
-information to ``fit'' on one page.
-
-@<Update the current height and depth measurements with...@>=
-if type(p)=kern_node then q:=p
-else begin q:=glue_ptr(p);
- active_height[2+stretch_order(q)]:=@|
- active_height[2+stretch_order(q)]+stretch(q);@/
- active_height[7]:=active_height[7]+shrink(q);
- if (shrink_order(q)<>normal)and(shrink(q)<>0) then
- begin@t@>@;@/
- print_err("Infinite glue shrinkage found in box being split");@/
-@.Infinite glue shrinkage...@>
- help4("The box you are \vsplitting contains some infinitely")@/
- ("shrinkable glue, e.g., `\vss' or `\vskip 0pt minus 1fil'.")@/
- ("Such glue doesn't belong there; but you can safely proceed,")@/
- ("since the offensive shrinkability has been made finite.");
- error; r:=new_spec(q); shrink_order(r):=normal; delete_glue_ref(q);
- glue_ptr(p):=r; q:=r;
- end;
- end;
-cur_height:=cur_height+prev_dp+width(q); prev_dp:=0
-
-@ Now we are ready to consider |vsplit| itself. Most of
-its work is accomplished by the two subroutines that we have just considered.
-
-Given the number of a vlist box |n|, and given a desired page height |h|,
-the |vsplit| function finds the best initial segment of the vlist and
-returns a box for a page of height~|h|. The remainder of the vlist, if
-any, replaces the original box, after removing glue and penalties and
-adjusting for |split_top_skip|. Mark nodes in the split-off box are used to
-set the values of |split_first_mark| and |split_bot_mark|; we use the
-fact that |split_first_mark(x)=null| if and only if |split_bot_mark(x)=null|.
-
-The original box becomes ``void'' if and only if it has been entirely
-extracted. The extracted box is ``void'' if and only if the original
-box was void (or if it was, erroneously, an hlist box).
-
-@p function vsplit(@!n:halfword; @!h:scaled):pointer;
- {extracts a page of height |h| from box |n|}
-label exit,done;
-var v:pointer; {the box to be split}
-vdir:integer; {the direction of the box to be split}
-p:pointer; {runs through the vlist}
-q:pointer; {points to where the break occurs}
-i:halfword; {for traversing marks lists}
-begin v:=box(n); vdir:=box_dir(v);
-flush_node_list(split_disc); split_disc:=null;
-for i:=0 to biggest_used_mark do begin
- delete_split_first_mark(i);
- delete_split_bot_mark(i);
-end;
-@<Dispense with trivial cases of void or bad boxes@>;
-q:=vert_break(list_ptr(v),h,split_max_depth);
-@<Look at all the marks in nodes before the break, and set the final
- link to |null| at the break@>;
-q:=prune_page_top(q,saving_vdiscards>0);
-p:=list_ptr(v); list_ptr(v):=null; flush_node(v);
-pack_direction:=vdir;
-if q=null then box(n):=null {the |eq_level| of the box stays the same}
-else box(n):=filtered_vpackage(q,0,additional,max_depth,split_keep_group);
-vsplit:=filtered_vpackage(p,h,exactly,split_max_depth,split_off_group);
-exit: end;
-
-@ @<Dispense with trivial cases of void or bad boxes@>=
-if v=null then
- begin vsplit:=null; return;
- end;
-if type(v)<>vlist_node then
- begin print_err(""); print_esc("vsplit"); print(" needs a ");
- print_esc("vbox");
-@:vsplit_}{\.{\\vsplit needs a \\vbox}@>
- help2("The box you are trying to split is an \hbox.")@/
- ("I can't split such a box, so I'll leave it alone.");
- error; vsplit:=null; return;
- end
-
-@ It's possible that the box begins with a penalty node that is the
-``best'' break, so we must be careful to handle this special case correctly.
-
-@<Look at all the marks...@>=
-p:=list_ptr(v);
-if p=q then list_ptr(v):=null
-else loop@+begin if type(p)=mark_node then begin
- if split_first_mark(mark_class(p))=null then
- begin split_first_mark(mark_class(p)):=mark_ptr(p);
- split_bot_mark(mark_class(p)):=split_first_mark(mark_class(p));
- token_ref_count(split_first_mark(mark_class(p))):=@|
- token_ref_count(split_first_mark(mark_class(p)))+2;
- end
- else begin delete_token_ref(split_bot_mark(mark_class(p)));
- split_bot_mark(mark_class(p)):=mark_ptr(p);
- add_token_ref(split_bot_mark(mark_class(p)));
- end;
- end;
- if vlink(p)=q then
- begin vlink(p):=null; goto done;
- end;
- p:=vlink(p);
- end;
-done:
-
-@* \[45] The page builder.
-When \TeX\ appends new material to its main vlist in vertical mode, it uses
-a method something like |vsplit| to decide where a page ends, except that
-the calculations are done ``on line'' as new items come in.
-The main complication in this process is that insertions must be put
-into their boxes and removed from the vlist, in a more-or-less optimum manner.
-
-We shall use the term ``current page'' for that part of the main vlist that
-is being considered as a candidate for being broken off and sent to the
-user's output routine. The current page starts at |vlink(page_head)|, and
-it ends at |page_tail|. We have |page_head=page_tail| if this list is empty.
-@^current page@>
-
-Utter chaos would reign if the user kept changing page specifications
-while a page is being constructed, so the page builder keeps the pertinent
-specifications frozen as soon as the page receives its first box or
-insertion. The global variable |page_contents| is |empty| when the
-current page contains only mark nodes and content-less whatsit nodes; it
-is |inserts_only| if the page contains only insertion nodes in addition to
-marks and whatsits. Glue nodes, kern nodes, and penalty nodes are
-discarded until a box or rule node appears, at which time |page_contents|
-changes to |box_there|. As soon as |page_contents| becomes non-|empty|,
-the current |vsize| and |max_depth| are squirreled away into |page_goal|
-and |page_max_depth|; the latter values will be used until the page has
-been forwarded to the user's output routine. The \.{\\topskip} adjustment
-is made when |page_contents| changes to |box_there|.
-
-Although |page_goal| starts out equal to |vsize|, it is decreased by the
-scaled natural height-plus-depth of the insertions considered so far, and by
-the \.{\\skip} corrections for those insertions. Therefore it represents
-the size into which the non-inserted material should fit, assuming that
-all insertions in the current page have been made.
-
-The global variables |best_page_break| and |least_page_cost| correspond
-respectively to the local variables |best_place| and |least_cost| in the
-|vert_break| routine that we have already studied; i.e., they record the
-location and value of the best place currently known for breaking the
-current page. The value of |page_goal| at the time of the best break is
-stored in |best_size|.
-
-@d inserts_only=1
- {|page_contents| when an insert node has been contributed, but no boxes}
-@d box_there=2 {|page_contents| when a box or rule has been contributed}
-
-@<Glob...@>=
-@!page_tail:pointer; {the final node on the current page}
-@!page_contents:empty..box_there; {what is on the current page so far?}
-@!page_max_depth:scaled; {maximum box depth on page being built}
-@!best_page_break:pointer; {break here to get the best page known so far}
-@!least_page_cost:integer; {the score for this currently best page}
-@!best_size:scaled; {its |page_goal|}
-
-@ The page builder has another data structure to keep track of insertions.
-This is a list of four-word nodes, starting and ending at |page_ins_head|.
-That is, the first element of the list is node |r@t$_1$@>=vlink(page_ins_head)|;
-node $r_j$ is followed by |r@t$_{j+1}$@>=vlink(r@t$_j$@>)|; and if there are
-|n| items we have |r@t$_{n+1}$@>=page_ins_head|. The |subtype| field of
-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)=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.
-
-The |type| field in these nodes distinguishes two possibilities that
-might occur as we look ahead before deciding on the optimum page break.
-If |type(r)=inserting_node|, then |height(r)| contains the total of the
-height-plus-depth dimensions of the box and all its inserts seen so far.
-If |type(r)=split_up_node|, then no more insertions will be made into this box,
-because at least one previous insertion was too big to fit on the current
-page; |broken_ptr(r)| points to the node where that insertion will be
-split, if \TeX\ decides to split it, |broken_ins(r)| points to the
-insertion node that was tentatively split, and |height(r)| includes also the
-natural height plus depth of the part that would be split off.
-
-In both cases, |last_ins_ptr(r)| points to the last |ins_node|
-encountered for box |qo(subtype(r))| that would be at least partially
-inserted on the next page; and |best_ins_ptr(r)| points to the last
-such |ins_node| that should actually be inserted, to get the page with
-minimum badness among all page breaks considered so far. We have
-|best_ins_ptr(r)=null| if and only if no insertion for this box should
-be made to produce this optimum page.
-
-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 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|}
-@d last_ins_ptr(#)==vlink(#+3) {the most recent insertion for this |subtype|}
-@d best_ins_ptr(#)==vinfo(#+3) {the optimum most recent insertion}
-
-@<Initialize the special list heads...@>=
-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
-on the current page. This array contains six |scaled| numbers, like the
-similar arrays already considered in |line_break| and |vert_break|; and it
-also contains |page_goal| and |page_depth|, since these values are
-all accessible to the user via |set_page_dimen| commands. The
-value of |page_so_far[1]| is also called |page_total|. The stretch
-and shrink components of the \.{\\skip} corrections for each insertion are
-included in |page_so_far|, but the natural space components of these
-corrections are not, since they have been subtracted from |page_goal|.
-
-The variable |page_depth| records the depth of the current page; it has been
-adjusted so that it is at most |page_max_depth|. The variable
-|last_glue| points to the glue specification of the most recent node
-contributed from the contribution list, if this was a glue node; otherwise
-|last_glue=max_halfword|. (If the contribution list is nonempty,
-however, the value of |last_glue| is not necessarily accurate.)
-The variables |last_penalty|, |last_kern|, and |last_node_type|
-are similar. And
-finally, |insert_penalties| holds the sum of the penalties associated with
-all split and floating insertions.
-
-@d page_goal==page_so_far[0] {desired height of information on page being built}
-@d page_total==page_so_far[1] {height of the current page}
-@d page_shrink==page_so_far[6] {shrinkability of the current page}
-@d page_depth==page_so_far[7] {depth of the current page}
-
-@<Glob...@>=
-@!page_so_far:array [0..7] of scaled; {height and glue of the current page}
-@!last_glue:pointer; {used to implement \.{\\lastskip}}
-@!last_penalty:integer; {used to implement \.{\\lastpenalty}}
-@!last_kern:scaled; {used to implement \.{\\lastkern}}
-@!last_node_type:integer; {used to implement \.{\\lastnodetype}}
-@!insert_penalties:integer; {sum of the penalties for held-over insertions}
-
-@ @<Put each...@>=
-primitive_tex("pagegoal",set_page_dimen,0,0);
-@!@:page_goal_}{\.{\\pagegoal} primitive@>
-primitive_tex("pagetotal",set_page_dimen,1,0);
-@!@:page_total_}{\.{\\pagetotal} primitive@>
-primitive_tex("pagestretch",set_page_dimen,2,0);
-@!@:page_stretch_}{\.{\\pagestretch} primitive@>
-primitive_tex("pagefilstretch",set_page_dimen,3,0);
-@!@:page_fil_stretch_}{\.{\\pagefilstretch} primitive@>
-primitive_tex("pagefillstretch",set_page_dimen,4,0);
-@!@:page_fill_stretch_}{\.{\\pagefillstretch} primitive@>
-primitive_tex("pagefilllstretch",set_page_dimen,5,0);
-@!@:page_filll_stretch_}{\.{\\pagefilllstretch} primitive@>
-primitive_tex("pageshrink",set_page_dimen,6,0);
-@!@:page_shrink_}{\.{\\pageshrink} primitive@>
-primitive_tex("pagedepth",set_page_dimen,7,0);
-@!@:page_depth_}{\.{\\pagedepth} primitive@>
-
-@ @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
-
-@p procedure print_totals;
-begin print_scaled(page_total);
-print_plus(2)("");
-print_plus(3)("fil");
-print_plus(4)("fill");
-print_plus(5)("filll");
-if page_shrink<>0 then
- begin print(" minus "); print_scaled(page_shrink);
- end;
-end;
-
-@ @<Show the status of the current page@>=
-if page_head<>page_tail then
- begin print_nl("### current page:");
- if output_active then print(" (held over for next output)");
-@.held over for next output@>
- show_box(vlink(page_head));
- if page_contents>empty then
- begin print_nl("total height "); print_totals;
-@:total_height}{\.{total height}@>
- print_nl(" goal height "); print_scaled(page_goal);
-@.goal height@>
- r:=vlink(page_ins_head);
- while r<>page_ins_head do
- begin print_ln; print_esc("insert"); t:=qo(subtype(r));
- print_int(t); print(" adds ");
- 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);
- if (type(q)=ins_node)and(subtype(q)=subtype(r)) then incr(t);
- until q=broken_ins(r);
- print(", #"); print_int(t); print(" might split");
- end;
- r:=vlink(r);
- end;
- end;
- end
-
-@ Here is a procedure that is called when the |page_contents| is changing
-from |empty| to |inserts_only| or |box_there|.
-
-@d set_page_so_far_zero(#)==page_so_far[#]:=0
-
-@p procedure freeze_page_specs(@!s:small_number);
-begin page_contents:=s;
-page_goal:=vsize; page_max_depth:=max_depth;
-page_depth:=0; do_all_six(set_page_so_far_zero);
-least_page_cost:=awful_bad;
-@!stat if tracing_pages>0 then
- begin begin_diagnostic;
- print_nl("%% goal height="); print_scaled(page_goal);
-@.goal height@>
- print(", max depth="); print_scaled(page_max_depth);
- end_diagnostic(false);
- end;@;@+tats@;@/
-end;
-
-@ Pages are built by appending nodes to the current list in \TeX's
-vertical mode, which is at the outermost level of the semantic nest. This
-vlist is split into two parts; the ``current page'' that we have been
-talking so much about already, and the ``contribution list'' that receives
-new nodes as they are created. The current page contains everything that
-the page builder has accounted for in its data structures, as described
-above, while the contribution list contains other things that have been
-generated by other parts of \TeX\ but have not yet been
-seen by the page builder.
-The contribution list starts at |vlink(contrib_head)|, and it ends at the
-current node in \TeX's vertical mode.
-
-When \TeX\ has appended new material in vertical mode, it calls the procedure
-|build_page|, which tries to catch up by moving nodes from the contribution
-list to the current page. This procedure will succeed in its goal of
-emptying the contribution list, unless a page break is discovered, i.e.,
-unless the current page has grown to the point where the optimum next
-page break has been determined. In the latter case, the nodes after the
-optimum break will go back onto the contribution list, and control will
-effectively pass to the user's output routine.
-
-We make |type(page_head)=glue_node|, so that an initial glue node on
-the current page will not be considered a valid breakpoint.
-
-@<Initialize the special list...@>=
-type(page_head):=glue_node; subtype(page_head):=normal;
-
-@ The global variable |output_active| is true during the time the
-user's output routine is driving \TeX.
-
-@<Glob...@>=
-@!output_active:boolean; {are we in the midst of an output routine?}
-
-@ @<Set init...@>=
-output_active:=false; insert_penalties:=0;
-
-@ The page builder is ready to start a fresh page if we initialize
-the following state variables. (However, the page insertion list is initialized
-elsewhere.)
-
-@<Start a new current page@>=
-page_contents:=empty; page_tail:=page_head; vlink(page_head):=null;@/
-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 \.{\\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.
-
-@p procedure box_error(@!n:eight_bits);
-begin error; begin_diagnostic;
-print_nl("The following box has been deleted:");
-@.The following...deleted@>
-show_box(box(n)); end_diagnostic(true);
-flush_node_list(box(n)); box(n):=null;
-end;
-
-@ The following procedure guarantees that a given box register
-does not contain an \.{\\hbox}.
-
-@p procedure ensure_vbox(@!n:eight_bits);
-var p:pointer; {the box register contents}
-begin p:=box(n);
-if p<>null then if type(p)=hlist_node then
- begin print_err("Insertions can only be added to a vbox");
-@.Insertions can only...@>
- help3("Tut tut: You're trying to \insert into a")@/
- ("\box register that now contains an \hbox.")@/
- ("Proceed, and I'll discard its present contents.");
- box_error(n);
- end;
-end;
-
-@ \TeX\ is not always in vertical mode at the time |build_page|
-is called; the current mode reflects what \TeX\ should return to, after
-the contribution list has been emptied. A call on |build_page| should
-be immediately followed by `|goto big_switch|', which is \TeX's central
-control point.
-
-@d contribute=80 {go here to link a node into the current page}
-
-@p @t\4@>@<Declare the procedure called |fire_up|@>@;@/
-procedure build_page; {append contributions to the current page}
-label exit,done,done1,continue,contribute,update_heights;
-var p:pointer; {the node being appended}
-@!q,@!r:pointer; {nodes being examined}
-@!b,@!c:integer; {badness and cost of current page}
-@!pi:integer; {penalty to be added to the badness}
-@!n:min_quarterword..255; {insertion box number}
-@!delta,@!h,@!w:scaled; {sizes used for insertion calculations}
-begin pi:=0;
-if (vlink(contrib_head)=null)or output_active then return;
-repeat continue: p:=vlink(contrib_head);@/
-@<Update the values of |last_glue|, |last_penalty|, and |last_kern|@>;
-@<Move node |p| to the current page; if it is time for a page break,
- put the nodes following the break back onto the contribution list,
- and |return| to the user's output routine if there is one@>;
-until vlink(contrib_head)=null;
-@<Make the contribution list empty by setting its tail to |contrib_head|@>;
-exit:end;
-
-@ @d contrib_tail==nest[0].tail_field {tail of the contribution list}
-
-@<Make the contribution list empty...@>=
-if nest_ptr=0 then tail:=contrib_head {vertical mode}
-else contrib_tail:=contrib_head {other modes}
-
-@ @<Update the values of |last_glue|...@>=
-if last_glue<>max_halfword then delete_glue_ref(last_glue);
-last_penalty:=0; last_kern:=0;
-last_node_type:=type(p)+1;
-if type(p)=glue_node then
- begin last_glue:=glue_ptr(p); add_glue_ref(last_glue);
- end
-else begin last_glue:=max_halfword;
- if type(p)=penalty_node then last_penalty:=penalty(p)
- else if type(p)=kern_node then last_kern:=width(p);
- end
-
-@ The code here is an example of a many-way switch into routines that
-merge together in different places. Some people call this unstructured
-programming, but the author doesn't see much wrong with it, as long as
-@^Knuth, Donald Ervin@>
-the various labels have a well-understood meaning.
-
-@<Move node |p| to the current page; ...@>=
-@<If the current page is empty and node |p| is to be deleted, |goto done1|;
- otherwise use node |p| to update the state of the current page;
- if this node is an insertion, |goto contribute|; otherwise if this node
- is not a legal breakpoint, |goto contribute| or |update_heights|;
- otherwise set |pi| to the penalty associated with this breakpoint@>;
-@<Check if node |p| is a new champion breakpoint; then \(if)if it is time for
- a page break, prepare for output, and either fire up the user's
- output routine and |return| or ship out the page and |goto done|@>;
-if (type(p)<glue_node)or(type(p)>kern_node) then goto contribute;
-update_heights:@<Update the current page measurements with respect to the
- glue or kern specified by node~|p|@>;
-contribute: @<Make sure that |page_max_depth| is not exceeded@>;
-@<Link node |p| into the current page and |goto done|@>;
-done1:@<Recycle node |p|@>;
-done:
-
-@ @<Link node |p| into the current page and |goto done|@>=
-vlink(page_tail):=p; page_tail:=p;
-vlink(contrib_head):=vlink(p); vlink(p):=null; goto done
-
-@ @<Recycle node |p|@>=
-vlink(contrib_head):=vlink(p); vlink(p):=null;
-if saving_vdiscards>0 then
- begin if page_disc=null then page_disc:=p@+else vlink(tail_page_disc):=p;
- tail_page_disc:=p;
- end
-else flush_node_list(p)
-
-@ The title of this section is already so long, it seems best to avoid
-making it more accurate but still longer, by mentioning the fact that a
-kern node at the end of the contribution list will not be contributed until
-we know its successor.
-
-@<If the current page is empty...@>=
-case type(p) of
-hlist_node_case,vlist_node_case,rule_node_case: if page_contents<box_there then
- @<Initialize the current page, insert the \.{\\topskip} glue
- ahead of |p|, and |goto continue|@>
- else @<Prepare to move a box or rule node to the current page,
- then |goto contribute|@>;
-whatsit_node_case: @<Prepare to move whatsit |p| to the current page,
- then |goto contribute|@>;
-glue_node_case: if page_contents<box_there then goto done1
- else if precedes_break(page_tail) then pi:=0
- else goto update_heights;
-kern_node_case: if page_contents<box_there then goto done1
- else if vlink(p)=null then return
- else if type(vlink(p))=glue_node then pi:=0
- else goto update_heights;
-penalty_node_case: if page_contents<box_there then goto done1@+else pi:=penalty(p);
-mark_node_case: goto contribute;
-ins_node_case: @<Append an insertion to the current page and |goto contribute|@>;
-othercases confusion("page")
-@:this can't happen page}{\quad page@>
-endcases
-
-@ @<Initialize the current page, insert the \.{\\topskip} glue...@>=
-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 width(temp_ptr)>depth(p) then width(temp_ptr):=width(temp_ptr)-depth(p)
- else width(temp_ptr):=0;
- end
-else begin
- if width(temp_ptr)>height(p) then width(temp_ptr):=width(temp_ptr)-height(p)
- else width(temp_ptr):=0;
- end;
-vlink(q):=p; vlink(contrib_head):=q; goto continue;
-end
-
-@ @<Prepare to move a box or rule node to the current page...@>=
-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
-else begin
- page_total:=page_total+page_depth+height(p);
- page_depth:=depth(p);
- end;
-goto contribute;
-end
-
-@ @<Make sure that |page_max_depth| is not exceeded@>=
-if page_depth>page_max_depth then
- begin page_total:=@|
- page_total+page_depth-page_max_depth;@/
- page_depth:=page_max_depth;
- end;
-
-@ @<Update the current page measurements with respect to the glue...@>=
-if type(p)=kern_node then q:=p
-else begin q:=glue_ptr(p);
-if stretch_order(q)>1 then
- page_so_far[1+stretch_order(q)]:=@|
- page_so_far[1+stretch_order(q)]+stretch(q)@/
-else
- page_so_far[2+stretch_order(q)]:=@|
- page_so_far[2+stretch_order(q)]+stretch(q);@/
- page_shrink:=page_shrink+shrink(q);
- if (shrink_order(q)<>normal)and(shrink(q)<>0) then
- begin@t@>@;@/
- print_err("Infinite glue shrinkage found on current page");@/
-@.Infinite glue shrinkage...@>
- help4("The page about to be output contains some infinitely")@/
- ("shrinkable glue, e.g., `\vss' or `\vskip 0pt minus 1fil'.")@/
- ("Such glue doesn't belong there; but you can safely proceed,")@/
- ("since the offensive shrinkability has been made finite.");
- error;
- r:=new_spec(q); shrink_order(r):=normal; delete_glue_ref(q);
- glue_ptr(p):=r; q:=r;
- end;
- end;
-page_total:=page_total+page_depth+width(q); page_depth:=0
-
-@ @<Check if node |p| is a new champion breakpoint; then \(if)...@>=
-if pi<inf_penalty then
- begin @<Compute the badness, |b|, of the current page,
- using |awful_bad| if the box is too full@>;
- if b<awful_bad then
- if pi<=eject_penalty then c:=pi
- else if b<inf_bad then c:=b+pi+insert_penalties
- else c:=deplorable
- else c:=b;
- if insert_penalties>=10000 then c:=awful_bad;
- @!stat if tracing_pages>0 then @<Display the page break cost@>;@+tats@;@/
- if c<=least_page_cost then
- begin best_page_break:=p; best_size:=page_goal;
- least_page_cost:=c;
- r:=vlink(page_ins_head);
- while r<>page_ins_head do
- begin best_ins_ptr(r):=last_ins_ptr(r);
- r:=vlink(r);
- end;
- end;
- if (c=awful_bad)or(pi<=eject_penalty) then
- begin fire_up(p); {output the current page at the best place}
- if output_active then return; {user's output routine will act}
- goto done; {the page has been shipped out by default output routine}
- end;
- end
-
-@ @<Display the page break cost@>=
-begin begin_diagnostic; print_nl("%");
-print(" t="); print_totals;@/
-print(" g="); print_scaled(page_goal);@/
-print(" b=");
-if b=awful_bad then print_char("*")@+else print_int(b);
-@.*\relax@>
-print(" p="); print_int(pi);
-print(" c=");
-if c=awful_bad then print_char("*")@+else print_int(c);
-if c<=least_page_cost then print_char("#");
-end_diagnostic(false);
-end
-
-@ @<Compute the badness, |b|, of the current page...@>=
-if page_total<page_goal then
- if (page_so_far[3]<>0) or (page_so_far[4]<>0) or@|
- (page_so_far[5]<>0) then b:=0
- else b:=badness(page_goal-page_total,page_so_far[2])
-else if page_total-page_goal>page_shrink then b:=awful_bad
-else b:=badness(page_total-page_goal,page_shrink)
-
-@ @<Append an insertion to the current page and |goto contribute|@>=
-begin if page_contents=empty then freeze_page_specs(inserts_only);
-n:=subtype(p); r:=page_ins_head;
-while n>=subtype(vlink(r)) do r:=vlink(r);
-n:=qo(n);
-if subtype(r)<>qi(n) then
- @<Create a page insertion node with |subtype(r)=qi(n)|, and
- include the glue correction for box |n| in the
- current page state@>;
-if type(r)=split_up_node then insert_penalties:=insert_penalties+float_cost(p)
-else begin last_ins_ptr(r):=p;
- delta:=page_goal-page_total-page_depth+page_shrink;
- {this much room is left if we shrink the maximum}
- if count(n)=1000 then h:=height(p)
- else h:=x_over_n(height(p),1000)*count(n); {this much room is needed}
- if ((h<=0)or(h<=delta))and(height(p)+height(r)<=dimen(n)) then
- begin page_goal:=page_goal-h; height(r):=height(r)+height(p);
- end
- else @<Find the best way to split the insertion, and change
- |type(r)| to |split_up_node|@>;
- end;
-goto contribute;
-end
-
-@ We take note of the value of \.{\\skip} |n| and the height plus depth
-of \.{\\box}~|n| only when the first \.{\\insert}~|n| node is
-encountered for a new page. A user who changes the contents of \.{\\box}~|n|
-after that first \.{\\insert}~|n| had better be either extremely careful
-or extremely lucky, or both.
-
-@<Create a page insertion node...@>=
-begin q:=new_node(inserting_node,n); vlink(q):=vlink(r); vlink(r):=q; r:=q;
-ensure_vbox(n);
-if box(n)=null then height(r):=0
-else height(r):=height(box(n))+depth(box(n));
-best_ins_ptr(r):=null;@/
-q:=skip(n);
-if count(n)=1000 then h:=height(r)
-else h:=x_over_n(height(r),1000)*count(n);
-page_goal:=page_goal-h-width(q);@/
-if stretch_order(q)>1 then
- page_so_far[1+stretch_order(q)]:=@|page_so_far[1+stretch_order(q)]+stretch(q)@/
-else
- page_so_far[2+stretch_order(q)]:=@|page_so_far[2+stretch_order(q)]+stretch(q);@/
-page_shrink:=page_shrink+shrink(q);
-if (shrink_order(q)<>normal)and(shrink(q)<>0) then
- begin print_err("Infinite glue shrinkage inserted from "); print_esc("skip");
-@.Infinite glue shrinkage...@>
- print_int(n);
- help3("The correction glue for page breaking with insertions")@/
- ("must have finite shrinkability. But you may proceed,")@/
- ("since the offensive shrinkability has been made finite.");
- error;
- end;
-end
-
-@ Here is the code that will split a long footnote between pages, in an
-emergency. The current situation deserves to be recapitulated: Node |p|
-is an insertion into box |n|; the insertion will not fit, in its entirety,
-either because it would make the total contents of box |n| greater than
-\.{\\dimen} |n|, or because it would make the incremental amount of growth
-|h| greater than the available space |delta|, or both. (This amount |h| has
-been weighted by the insertion scaling factor, i.e., by \.{\\count} |n|
-over 1000.) Now we will choose the best way to break the vlist of the
-insertion, using the same criteria as in the \.{\\vsplit} operation.
-
-@<Find the best way to split the insertion...@>=
-begin if count(n)<=0 then w:=max_dimen
-else begin w:=page_goal-page_total-page_depth;
- if count(n)<>1000 then w:=x_over_n(w,count(n))*1000;
- end;
-if w>dimen(n)-height(r) then w:=dimen(n)-height(r);
-q:=vert_break(ins_ptr(p),w,depth(p));
-height(r):=height(r)+best_height_plus_depth;
-@!stat if tracing_pages>0 then @<Display the insertion split cost@>;@+tats@;@/
-if count(n)<>1000 then
- best_height_plus_depth:=x_over_n(best_height_plus_depth,1000)*count(n);
-page_goal:=page_goal-best_height_plus_depth;
-type(r):=split_up_node; broken_ptr(r):=q; broken_ins(r):=p;
-if q=null then insert_penalties:=insert_penalties+eject_penalty
-else if type(q)=penalty_node then insert_penalties:=insert_penalties+penalty(q);
-end
-
-@ @<Display the insertion split cost@>=
-begin begin_diagnostic; print_nl("% split"); print_int(n);
-@.split@>
-print(" to "); print_scaled(w);
-print_char(","); print_scaled(best_height_plus_depth);@/
-print(" p=");
-if q=null then print_int(eject_penalty)
-else if type(q)=penalty_node then print_int(penalty(q))
-else print_char("0");
-end_diagnostic(false);
-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 \.{\\outputbox}, with insertions
-appended to their other boxes.
-
-We also set the values of |top_mark|, |first_mark|, and |bot_mark|. The
-program uses the fact that |bot_mark(x)<>null| implies |first_mark(x)<>null|;
-it also knows that |bot_mark(x)=null| implies |top_mark(x)=first_mark(x)=null|.
-
-The |fire_up| subroutine prepares to output the current page at the best
-place; then it fires up the user's output routine, if there is one,
-or it simply ships out the page. There is one parameter, |c|, which represents
-the node that was being contributed to the page when the decision to
-force an output was made.
-
-@<Declare the procedure called |fire_up|@>=
-procedure fire_up(@!c:pointer);
-label exit;
-var p,@!q,@!r,@!s:pointer; {nodes being examined and/or changed}
-@!prev_p:pointer; {predecessor of |p|}
-@!n:min_quarterword..255; {insertion box number}
-@!wait:boolean; {should the present insertion be held over?}
-@!save_vbadness:integer; {saved value of |vbadness|}
-@!save_vfuzz: scaled; {saved value of |vfuzz|}
-@!save_split_top_skip: pointer; {saved value of |split_top_skip|}
-@!i: halfword; { for looping through the marks}
-begin @<Set the value of |output_penalty|@>;
-for i:=0 to biggest_used_mark do begin
- if bot_mark(i)<>null then
- begin if top_mark(i)<>null then delete_token_ref(top_mark(i));
- top_mark(i):=bot_mark(i); add_token_ref(top_mark(i));
- delete_first_mark(i);
- end;
- end;
-@<Put the \(o)optimal current page into box |output_box|, update |first_mark| and
- |bot_mark|, append insertions to their boxes, and put the
- remaining nodes back on the contribution list@>;
-for i:=0 to biggest_used_mark do begin
- if (top_mark(i)<>null)and(first_mark(i)=null) then
- begin first_mark(i):=top_mark(i); add_token_ref(top_mark(i));
- end;
- end;
-if output_routine<>null then begin
- if dead_cycles>=max_dead_cycles then
- @<Explain that too many dead cycles have occurred in a row@>
- else @<Fire up the user's output routine and |return|@>;
- end;
-@<Perform the default output routine@>;
-exit:end;
-
-@ @<Set the value of |output_penalty|@>=
-if type(best_page_break)=penalty_node then
- begin geq_word_define(int_base+output_penalty_code,penalty(best_page_break));
- penalty(best_page_break):=inf_penalty;
- end
-else geq_word_define(int_base+output_penalty_code,inf_penalty)
-
-@ As the page is finally being prepared for output,
-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.
-
-@<Put the \(o)optimal current page into box ...@>=
-if c=best_page_break then best_page_break:=null; {|c| not yet linked in}
-@<Ensure that box |output_box| is empty before output@>;
-insert_penalties:=0; {this will count the number of insertions held over}
-save_split_top_skip:=split_top_skip;
-if holding_inserts<=0 then
- @<Prepare all the boxes involved in insertions to act as queues@>;
-q:=hold_head; vlink(q):=null; prev_p:=page_head; p:=vlink(prev_p);
-while p<>best_page_break do
- begin if type(p)=ins_node then
- begin if holding_inserts<=0 then
- @<Either insert the material specified by node |p| into the
- appropriate box, or hold it for the next page;
- also delete node |p| from the current page@>;
- end
- else if type(p)=mark_node then @<Update the values of
- |first_mark| and |bot_mark|@>;
- prev_p:=p; p:=vlink(prev_p);
- end;
-split_top_skip:=save_split_top_skip;
-@<Break the current page at node |p|, put it in box~|output_box|,
- and put the remaining nodes on the contribution list@>;
-@<Delete \(t)the page-insertion nodes@>
-
-@ @<Ensure that box |output_box| is empty before output@>=
-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(output_box);
- end
-
-@ @<Update the values of |first_mark| and |bot_mark|@>=
-begin if first_mark(mark_class(p))=null then
- begin first_mark(mark_class(p)):=mark_ptr(p);
- add_token_ref(first_mark(mark_class(p)));
- end;
-if bot_mark(mark_class(p))<>null then delete_token_ref(bot_mark(mark_class(p)));
-bot_mark(mark_class(p)):=mark_ptr(p); add_token_ref(bot_mark(mark_class(p)));
-end;
-
-@ When the following code is executed, the current page runs from node
-|vlink(page_head)| to node |prev_p|, and the nodes from |p| to |page_tail|
-are to be placed back at the front of the contribution list. Furthermore
-the heldover insertions appear in a list from |vlink(hold_head)| to |q|; we
-will put them into the current page list for safekeeping while the user's
-output routine is active. We might have |q=hold_head|; and |p=null| if
-and only if |prev_p=page_tail|. Error messages are suppressed within
-|vpackage|, since the box might appear to be overfull or underfull simply
-because the stretch and shrink from the \.{\\skip} registers for inserts
-are not actually present in the box.
-
-@<Break the current page at node |p|, put it...@>=
-if p<>null then
- begin if vlink(contrib_head)=null then begin
- if nest_ptr=0 then tail:=page_tail
- else contrib_tail:=page_tail;
- end;
- vlink(page_tail):=vlink(contrib_head);
- vlink(contrib_head):=p;
- vlink(prev_p):=null;
- end;
-save_vbadness:=vbadness; vbadness:=inf_bad;
-save_vfuzz:=vfuzz; vfuzz:=max_dimen; {inhibit error messages}
-pack_direction:=body_direction;
-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);
-@<Start a new current page@>; {this sets |last_glue:=max_halfword|}
-if q<>hold_head then
- begin vlink(page_head):=vlink(hold_head); page_tail:=q;
- end
-
-@ If many insertions are supposed to go into the same box, we want to know
-the position of the last node in that box, so that we don't need to waste time
-when linking further information into it. The |last_ins_ptr| fields of the
-page insertion nodes are therefore used for this purpose during the
-packaging phase.
-
-@<Prepare all the boxes involved in insertions to act as queues@>=
-begin r:=vlink(page_ins_head);
-while r<>page_ins_head do
- begin if best_ins_ptr(r)<>null then
- begin n:=qo(subtype(r)); ensure_vbox(n);
- if box(n)=null then box(n):=new_null_box;
- p:=box(n)+list_offset;
- while vlink(p)<>null do p:=vlink(p);
- last_ins_ptr(r):=p;
- end;
- r:=vlink(r);
- end;
-end
-
-@ @<Delete \(t)the page-insertion nodes@>=
-r:=vlink(page_ins_head);
-while r<>page_ins_head do
- begin q:=vlink(r); flush_node(r); r:=q;
- end;
-vlink(page_ins_head):=page_ins_head
-
-@ We will set |best_ins_ptr:=null| and package the box corresponding to
-insertion node~|r|, just after making the final insertion into that box.
-If this final insertion is `|split_up_node|', the remainder after splitting
-and pruning (if any) will be carried over to the next page.
-
-@<Either insert the material specified by node |p| into...@>=
-begin r:=vlink(page_ins_head);
-while subtype(r)<>subtype(p) do r:=vlink(r);
-if best_ins_ptr(r)=null then wait:=true
-else begin wait:=false; s:=last_ins_ptr(r); vlink(s):=ins_ptr(p);
- if best_ins_ptr(r)=p then
- @<Wrap up the box specified by node |r|, splitting node |p| if
- called for; set |wait:=true| if node |p| holds a remainder after
- splitting@>
- else begin while vlink(s)<>null do s:=vlink(s);
- last_ins_ptr(r):=s;
- end;
- end;
-@<Either append the insertion node |p| after node |q|, and remove it
- from the current page, or delete |node(p)|@>;
-end
-
-@ @<Wrap up the box specified by node |r|, splitting node |p| if...@>=
-begin if type(r)=split_up_node then
- if (broken_ins(r)=p)and(broken_ptr(r)<>null) then
- begin while vlink(s)<>broken_ptr(r) do s:=vlink(s);
- vlink(s):=null;
- split_top_skip:=split_top_ptr(p);
- ins_ptr(p):=prune_page_top(broken_ptr(r),false);
- if ins_ptr(p)<>null then
- begin temp_ptr:=vpack(ins_ptr(p),natural);
- height(p):=height(temp_ptr)+depth(temp_ptr);
- list_ptr(temp_ptr):=null; flush_node(temp_ptr); wait:=true;
- end;
- end;
-best_ins_ptr(r):=null;
-n:=qo(subtype(r));
-temp_ptr:=list_ptr(box(n));
-list_ptr(box(n)):=null; flush_node(box(n));
-pack_direction:=body_direction;
-box(n):=vpack(temp_ptr,natural);
-end
-
-@ @<Either append the insertion node |p|...@>=
-vlink(prev_p):=vlink(p); vlink(p):=null;
-if wait then
- begin vlink(q):=p; q:=p; incr(insert_penalties);
- end
-else begin ins_ptr(p):=null; flush_node(p);
- end;
-p:=prev_p
-
-@ The list of heldover insertions, running from |vlink(page_head)| to
-|page_tail|, must be moved to the contribution list when the user has
-specified no output routine.
-
-@<Perform the default output routine@>=
-begin if vlink(page_head)<>null then
- begin if vlink(contrib_head)=null then
- if nest_ptr=0 then tail:=page_tail@+else contrib_tail:=page_tail
- else vlink(page_tail):=vlink(contrib_head);
- vlink(contrib_head):=vlink(page_head);
- vlink(page_head):=null; page_tail:=page_head;
- end;
-flush_node_list(page_disc); page_disc:=null;
-ship_out(box(output_box)); box(output_box):=null;
-end
-
-@ @<Explain that too many dead cycles have occurred in a row@>=
-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 \box\outputbox out myself. Next time")@/
-("increase \maxdeadcycles if you want me to be more patient!"); error;
-end
-
-@ @<Fire up the user's output routine and |return|@>=
-begin output_active:=true;
-incr(dead_cycles);
-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;
-return;
-end
-
-@ When the user's output routine finishes, it has constructed a vlist
-in internal vertical mode, and \TeX\ will do the following:
-
-@<Resume the page builder after an output routine has come to an end@>=
-begin if (loc<>null) or
- ((token_type<>output_text)and(token_type<>backed_up)) then
- @<Recover from an unbalanced output routine@>;
-end_token_list; {conserve stack space in case more outputs are triggered}
-end_graf; unsave; output_active:=false; insert_penalties:=0;@/
-@<Ensure that box |output_box| is empty after output@>;
-if tail<>head then {current list goes after heldover insertions}
- begin vlink(page_tail):=vlink(head);
- page_tail:=tail;
- end;
-if vlink(page_head)<>null then {and both go before heldover contributions}
- begin if vlink(contrib_head)=null then contrib_tail:=page_tail;
- vlink(page_tail):=vlink(contrib_head);
- vlink(contrib_head):=vlink(page_head);
- vlink(page_head):=null; page_tail:=page_head;
- end;
-flush_node_list(page_disc); page_disc:=null;
-pop_nest; check_filter('after_output'); build_page;
-end
-
-@ @<Recover from an unbalanced output routine@>=
-begin print_err("Unbalanced output routine");
-@.Unbalanced output routine@>
-help2("Your sneaky output routine has problematic {'s and/or }'s.")@/
-("I can't handle that very well; good luck."); error;
-repeat get_token;
-until loc=null;
-end {loops forever if reading from a file, since |null=min_halfword<=0|}
-
-@ @<Ensure that box |output_box| is empty after output@>=
-if box(output_box)<>null then
- begin print_err("Output routine didn't use all of ");
- print_esc("box"); print_int(output_box);
-@.Output routine didn't use...@>
- help3("Your \output commands should empty \box\outputbox,")@/
- ("e.g., by saying `\shipout\box\outputbox'.")@/
- ("Proceed; I'll discard its present contents.");
- box_error(output_box);
- end
-
-@* \[46] The chief executive.
-We come now to the |main_control| routine, which contains the master
-switch that causes all the various pieces of \TeX\ to do their things,
-in the right order.
-
-In a sense, this is the grand climax of the program: It applies all the
-tools that we have worked so hard to construct. In another sense, this is
-the messiest part of the program: It necessarily refers to other pieces
-of code all over the place, so that a person can't fully understand what is
-going on without paging back and forth to be reminded of conventions that
-are defined elsewhere. We are now at the hub of the web, the central nervous
-system that touches most of the other parts and ties them together.
-@^brain@>
-
-The structure of |main_control| itself is quite simple. There's a label
-called |big_switch|, at which point the next token of input is fetched
-using |get_x_token|. Then the program branches at high speed into one of
-about 100 possible directions, based on the value of the current
-mode and the newly fetched command code; the sum |abs(mode)+cur_cmd|
-indicates what to do next. For example, the case `|vmode+letter|' arises
-when a letter occurs in vertical mode (or internal vertical mode); this
-case leads to instructions that initialize a new paragraph and enter
-horizontal mode.
-
-The big |case| statement that contains this multiway switch has been labeled
-|reswitch|, so that the program can |goto reswitch| when the next token
-has already been fetched. Most of the cases are quite short; they call
-an ``action procedure'' that does the work for that case, and then they
-either |goto reswitch| or they ``fall through'' to the end of the |case|
-statement, which returns control back to |big_switch|. Thus, |main_control|
-is not an extremely large procedure, in spite of the multiplicity of things
-it must do; it is small enough to be handled by \PASCAL\ compilers that put
-severe restrictions on procedure size.
-@!@^action procedure@>
-
-One case is singled out for special treatment, because it accounts for most
-of \TeX's activities in typical applications. The process of reading simple
-text and converting it into |char_node| records, while looking for ligatures
-and kerns, is part of \TeX's ``inner loop''; the whole program runs
-efficiently when its inner loop is fast, so this part has been written
-with particular care.
-
-@ We shall concentrate first on the inner loop of |main_control|, deferring
-consideration of the other cases until later.
-@^inner loop@>
-
-@d big_switch=60 {go here to branch on the next token of input}
-
-@p @t\4@>@<Declare action procedures for use by |main_control|@>@;
-@t\4@>@<Declare the procedure called |handle_right_brace|@>@;
-procedure main_control; {governs \TeX's activities}
-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);
-big_switch: get_x_token;@/
-reswitch: @<Give diagnostic information, if requested@>;
-case abs(mode)+cur_cmd of
-hmode+letter,hmode+other_char,hmode+char_given,hmode+char_num: begin
- if abs(mode)+cur_cmd=hmode+char_num then begin
- scan_char_num; cur_chr:=cur_val;
- end;
- if is_last_ocp(current_ocp_lstack,current_ocp_no) then begin
- @<Append character |cur_chr| and the following characters (if~any)
- to the current hlist in the current font; |goto reswitch| when
- a non-character has been fetched@>;
- end
- else begin
- @<Create a buffer with character |cur_chr| and the following
- characters (if~any) and then apply the current active OCP filter
- to this buffer@>;
- end;
- end;
-hmode+no_boundary: begin @<Append a |cancel_boundary_node| @>;
- end;
-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);
- if t=0 then begin set_is_leftghost(p); end
- else begin set_is_rightghost(p); end;
- tail_append(p);
- end;
- end;
-hmode+spacer,hmode+ex_space,mmode+ex_space:
-if (abs(mode)+cur_cmd=hmode+spacer) and
- (not (space_factor = 1000)) then
- app_space
-else begin
- @<Append a normal inter-word space to the current list@>;
- end;
-@t\4@>@<Cases of |main_control| that are not part of the inner loop@>@;
-end; {of the big |case| statement}
-goto big_switch;
-exit:end;
-
-@ When a new token has just been fetched at |big_switch|, we have an
-ideal place to monitor \TeX's activity.
-@^debugging@>
-
-@<Give diagnostic information, if requested@>=
-if interrupt<>0 then if OK_to_interrupt then
- begin back_input; check_interrupt; goto big_switch;
- end;
-if tracing_commands>0 then show_cur_cmd_chr
-
-@ The following part of the program was first written in a structured
-manner, according to the philosophy that ``premature optimization is
-the root of all evil.'' Then it was rearranged into pieces of
-spaghetti so that the most common actions could proceed with little or
-no redundancy. And finally, it is replaced by a completely standalone
-loop over the node list: luatex does not have a |main+loop| at all.
-@^inner loop@>
-
-@<Glob...@>=
-@!main_p:pointer; {temporary register for list manipulation}
-@!main_s:integer; {space factor value}
-
-@ We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we
-set it equal to |sf_code(cur_chr)|, except that it should never change
-from a value less than 1000 to a value exceeding 1000. The most common
-case is |sf_code(cur_chr)=1000|, so we want that case to be fast.
-
-@d adjust_space_factor==@t@>@;@/
- main_s:=get_sf_code(cur_chr);
- if main_s=1000 then space_factor:=1000
- else if main_s<1000 then
- begin if main_s>0 then space_factor:=main_s;
- end
- else if space_factor<1000 then space_factor:=1000
- else space_factor:=main_s
-
-@<Append character |cur_chr|...@>=
-continue: adjust_space_factor;@/
-chr_stack:=cur_chr;
-tail_append(new_char(cur_font,chr_stack));
-get_x_token;
-if (cur_cmd=letter)or(cur_cmd=other_char)or
- (cur_cmd=char_given)or(cur_cmd=char_num) then begin
- if cur_cmd=char_num then begin
- 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:=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:=compound_word_break(tail,cur_lang);
- subtype(tail):=automatic_disc;
- end;
- chr_stack:=-1;
- goto reswitch;
- end
-
-@ The occurrence of blank spaces is almost part of \TeX's inner loop,
-@^inner loop@>
-since we usually encounter about one space for every five non-blank characters.
-Therefore |main_control| gives second-highest priority to ordinary spaces.
-
-When a glue parameter like \.{\\spaceskip} is set to `\.{0pt}', we will
-see to it later that the corresponding glue specification is precisely
-|zero_glue|, not merely a pointer to some specification that happens
-to be full of zeroes. Therefore it is simple to test whether a glue parameter
-is zero or~not.
-
-@<Append a normal inter-word space...@>=
-if space_skip=zero_glue then
- begin @<Find the glue specification, |main_p|, for
- text spaces in the current font@>;
- temp_ptr:=new_glue(main_p);
- end
-else temp_ptr:=new_param_glue(space_skip_code);
-vlink(tail):=temp_ptr; tail:=temp_ptr
-
-
-@ From Knuth: ``Having |font_glue| allocated for each text font saves
-both time and memory.'' That may be true, but it also punches through
-the API wall for fonts, so I removed that -- Taco. But a bit of caching
-is very welcome, which is why I need to have the next two globals:
-
-@<Glob...@>=
-space_spec_font:internal_font_number;
-space_spec_cache:halfword;
-
-@ @<Set init...@>=
-space_spec_font:=0;
-space_spec_cache:=zero_glue;
-
-@ @<Find the glue specification...@>=
-begin
-if cur_font<>space_spec_font then begin
- if space_spec_cache<>zero_glue then
- delete_glue_ref(space_spec_cache);
- space_spec_cache:=new_spec(zero_glue);
- width(space_spec_cache):=space(cur_font);
- stretch(space_spec_cache):=space_stretch(cur_font);
- shrink(space_spec_cache):=space_shrink(cur_font);
- space_spec_font:=cur_font;
- end;
-main_p:=space_spec_cache;
-end
-
-@ @<Declare act...@>=
-procedure app_space; {handle spaces when |space_factor<>1000|}
-var@!q:pointer; {glue node}
-begin if (space_factor>=2000)and(xspace_skip<>zero_glue) then
- q:=new_param_glue(xspace_skip_code)
-else begin if space_skip<>zero_glue then
- main_p:=new_spec(space_skip)
- else begin
- main_p:=new_spec(zero_glue);
- width(main_p):=space(cur_font);
- stretch(main_p):=space_stretch(cur_font);
- shrink(main_p):=space_shrink(cur_font);
- end;
- @<Modify the glue specification in |main_p| according to the space factor@>;
- q:=new_glue(main_p); glue_ref_count(main_p):=null;
- end;
-vlink(tail):=q; tail:=q;
-end;
-
-@ @<Modify the glue specification in |main_p| according to the space factor@>=
-if space_factor>=2000 then width(main_p):=width(main_p)+extra_space(cur_font);
-stretch(main_p):=xn_over_d(stretch(main_p),space_factor,1000);
-shrink(main_p):=xn_over_d(shrink(main_p),1000,space_factor)
-
-@ Whew---that covers the main loop. We can now proceed at a leisurely
-pace through the other combinations of possibilities.
-
-@d any_mode(#)==vmode+#,hmode+#,mmode+# {for mode-independent commands}
-
-@<Cases of |main_control| that are not part of the inner loop@>=
-any_mode(relax),vmode+spacer,mmode+spacer,mmode+no_boundary:do_nothing;
-any_mode(ignore_spaces): begin
- if cur_chr = 0 then begin
- @<Get the next non-blank non-call...@>;
- goto reswitch;
- end
- else begin
- t:=scanner_status;
- scanner_status:=normal;
- get_filtered_next;
- scanner_status:=t;
- cur_cs := prim_lookup(text(cur_cs));
- if cur_cs<>undefined_primitive then begin
- cur_cmd := get_prim_eq_type(cur_cs);
- cur_chr := get_prim_equiv(cur_cs);
- cur_tok := (cur_cmd*string_offset)+cur_chr;
- goto reswitch;
- end;
- end;
- end;
-vmode+stop: if its_all_over then return; {this is the only way out}
-@t\4@>@<Math cases in non-math modes@>;
-@t\4@>@<Forbidden cases detected in |main_control|@>@+@,any_mode(mac_param):
- report_illegal_case;
-@<Math-only cases in non-math modes, or vice versa@>: insert_dollar_sign;
-@t\4@>@<Cases of |main_control| that build boxes and lists@>@;
-@t\4@>@<Cases of |main_control| that don't depend on |mode|@>@;
-@t\4@>@<Cases of |main_control| that are for extensions to \TeX@>@;
-
-@ Here is a list of cases where the user has probably gotten into or out of math
-mode by mistake. \TeX\ will insert a dollar sign and rescan the current token.
-
-@d non_math(#)==vmode+#,hmode+#
-
-@<Math-only cases in non-math modes...@>=
-non_math(sup_mark), non_math(sub_mark),
-non_math(super_sub_script), 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),
-non_math(non_script), non_math(mkern), non_math(limit_switch),
-non_math(mskip), non_math(math_accent),
-mmode+endv, mmode+par_end, mmode+stop, mmode+vskip, mmode+un_vbox,
-mmode+valign, mmode+hrule
-
-@ @<Math cases in non-math modes@>=
-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
-
-
-
-@ @<Declare action...@>=
-procedure insert_dollar_sign;
-begin back_input; cur_tok:=math_shift_token+"$";
-print_err("Missing $ inserted");
-@.Missing \$ inserted@>
-help2("I've inserted a begin-math/end-math symbol since I think")@/
-("you left one out. Proceed, with fingers crossed."); ins_error;
-end;
-
-@ When erroneous situations arise, \TeX\ usually issues an error message
-specific to the particular error. For example, `\.{\\noalign}' should
-not appear in any mode, since it is recognized by the |align_peek| routine
-in all of its legitimate appearances; a special error message is given
-when `\.{\\noalign}' occurs elsewhere. But sometimes the most appropriate
-error message is simply that the user is not allowed to do what he or she
-has attempted. For example, `\.{\\moveleft}' is allowed only in vertical mode,
-and `\.{\\lower}' only in non-vertical modes. Such cases are enumerated
-here and in the other sections referred to under `See also \dots.'
-
-@<Forbidden cases...@>=
-vmode+vmove,hmode+hmove,mmode+hmove,any_mode(last_item),
-
-@ The `|you_cant|' procedure prints a line saying that the current command
-is illegal in the current mode; it identifies these things symbolically.
-
-@<Declare action...@>=
-procedure you_cant;
-begin print_err("You can't use `");
-@.You can't use x in y mode@>
-print_cmd_chr(cur_cmd,cur_chr);
-print("' in "); print_mode(mode);
-end;
-
-@ @<Declare act...@>=
-procedure report_illegal_case;
-begin you_cant;
-help4("Sorry, but I'm not programmed to handle this case;")@/
-("I'll just pretend that you didn't ask for it.")@/
-("If you're in the wrong mode, you might be able to")@/
-("return to the right one by typing `I}' or `I$' or `I\par'.");@/
-error;
-end;
-
-@ Some operations are allowed only in privileged modes, i.e., in cases
-that |mode>0|. The |privileged| function is used to detect violations
-of this rule; it issues an error message and returns |false| if the
-current |mode| is negative.
-
-@<Declare act...@>=
-function privileged:boolean;
-begin if mode>0 then privileged:=true
-else begin report_illegal_case; privileged:=false;
- end;
-end;
-
-@ Either \.{\\dump} or \.{\\end} will cause |main_control| to enter the
-endgame, since both of them have `|stop|' as their command code.
-
-@<Put each...@>=
-primitive_tex("end",stop,0,0);@/
-@!@:end_}{\.{\\end} primitive@>
-primitive_tex("dump",stop,1,0);@/
-@!@:dump_}{\.{\\dump} primitive@>
-
-@ 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
-might even say `\.{\\gdef\\end\{...\}}', to prolong the life of the job.)
-Therefore |its_all_over| is |true| only when the current page
-and contribution list are empty, and when the last output was not a
-``dead cycle.''
-
-@<Declare act...@>=
-function its_all_over:boolean; {do this when \.{\\end} or \.{\\dump} occurs}
-label exit;
-begin if privileged then
- begin if (page_head=page_tail)and(head=tail)and(dead_cycles=0) then
- begin its_all_over:=true; return;
- end;
- back_input; {we will try to end again after ejecting residual material}
- tail_append(new_null_box);
- width(tail):=hsize;
- tail_append(new_glue(fill_glue));
- tail_append(new_penalty(-@'10000000000));@/
- check_filter('end'); build_page; {append \.{\\hbox to \\hsize\{\}\\vfill\\penalty-'10000000000}}
- end;
-its_all_over:=false;
-exit:end;
-
-@* \[47] Building boxes and lists.
-The most important parts of |main_control| are concerned with \TeX's
-chief mission of box-making. We need to control the activities that put
-entries on vlists and hlists, as well as the activities that convert
-those lists into boxes. All of the necessary machinery has already been
-developed; it remains for us to ``push the buttons'' at the right times.
-
-@ As an introduction to these routines, let's consider one of the simplest
-cases: What happens when `\.{\\hrule}' occurs in vertical mode, or
-`\.{\\vrule}' in horizontal mode or math mode? The code in |main_control|
-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:=pdf_ignored_dimen|.
-
-@<Cases of |main_control| that build...@>=
-vmode+hrule,hmode+vrule,mmode+vrule: begin tail_append(scan_rule_spec);
- if abs(mode)=vmode then prev_depth:=pdf_ignored_dimen
- else if abs(mode)=hmode then space_factor:=1000;
- end;
-
-@ The processing of things like \.{\\hskip} and \.{\\vskip} is slightly
-more complicated. But the code in |main_control| is very short, since
-it simply calls on the action routine |append_glue|. Similarly, \.{\\kern}
-activates |append_kern|.
-
-@<Cases of |main_control| that build...@>=
-vmode+vskip,hmode+hskip,mmode+hskip,mmode+mskip: append_glue;
-any_mode(kern),mmode+mkern: append_kern;
-
-@ The |hskip| and |vskip| command codes are used for control sequences
-like \.{\\hss} and \.{\\vfil} as well as for \.{\\hskip} and \.{\\vskip}.
-The difference is in the value of |cur_chr|.
-
-@d fil_code=0 {identifies \.{\\hfil} and \.{\\vfil}}
-@d fill_code=1 {identifies \.{\\hfill} and \.{\\vfill}}
-@d ss_code=2 {identifies \.{\\hss} and \.{\\vss}}
-@d fil_neg_code=3 {identifies \.{\\hfilneg} and \.{\\vfilneg}}
-@d skip_code=4 {identifies \.{\\hskip} and \.{\\vskip}}
-@d mskip_code=5 {identifies \.{\\mskip}}
-
-@<Put each...@>=
-primitive_tex("hskip",hskip,skip_code,0);@/
-@!@:hskip_}{\.{\\hskip} primitive@>
-primitive_tex("hfil",hskip,fil_code,0);
-@!@:hfil_}{\.{\\hfil} primitive@>
-primitive_tex("hfill",hskip,fill_code,0);@/
-@!@:hfill_}{\.{\\hfill} primitive@>
-primitive_tex("hss",hskip,ss_code,0);
-@!@:hss_}{\.{\\hss} primitive@>
-primitive_tex("hfilneg",hskip,fil_neg_code,0);@/
-@!@:hfil_neg_}{\.{\\hfilneg} primitive@>
-primitive_tex("vskip",vskip,skip_code,0);@/
-@!@:vskip_}{\.{\\vskip} primitive@>
-primitive_tex("vfil",vskip,fil_code,0);
-@!@:vfil_}{\.{\\vfil} primitive@>
-primitive_tex("vfill",vskip,fill_code,0);@/
-@!@:vfill_}{\.{\\vfill} primitive@>
-primitive_tex("vss",vskip,ss_code,0);
-@!@:vss_}{\.{\\vss} primitive@>
-primitive_tex("vfilneg",vskip,fil_neg_code,0);@/
-@!@:vfil_neg_}{\.{\\vfilneg} primitive@>
-primitive_tex("mskip",mskip,mskip_code,0);@/
-@!@:mskip_}{\.{\\mskip} primitive@>
-primitive_tex("kern",kern,explicit,0);
-@!@:kern_}{\.{\\kern} primitive@>
-primitive_tex("mkern",mkern,mu_glue,0);@/
-@!@:mkern_}{\.{\\mkern} primitive@>
-
-@ 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.
-
-@<Declare action...@>=
-procedure append_glue;
-var s:small_number; {modifier of skip command}
-begin s:=cur_chr;
-case s of
-fil_code: cur_val:=fil_glue;
-fill_code: cur_val:=fill_glue;
-ss_code: cur_val:=ss_glue;
-fil_neg_code: cur_val:=fil_neg_glue;
-skip_code: scan_glue(glue_val);
-mskip_code: scan_glue(mu_val);
-end; {now |cur_val| points to the glue specification}
-tail_append(new_glue(cur_val));
-if s>=skip_code then
- begin decr(glue_ref_count(cur_val));
- if s>skip_code then subtype(tail):=mu_glue;
- end;
-end;
-
-@ @<Declare act...@>=
-procedure append_kern;
-var s:quarterword; {|subtype| of the kern node}
-begin s:=cur_chr; scan_dimen(s=mu_glue,false,false);
-tail_append(new_kern(cur_val)); subtype(tail):=s;
-end;
-
-@ Many of the actions related to box-making are triggered by the appearance
-of braces in the input. For example, when the user says `\.{\\hbox}
-\.{to} \.{100pt\{$\langle\,\hbox{hlist}\,\rangle$\}}' in vertical mode,
-the information about the box size (100pt, |exactly|) is put onto |save_stack|
-with a level boundary word just above it, and |cur_group:=adjusted_hbox_group|;
-\TeX\ enters restricted horizontal mode to process the hlist. The right
-brace eventually causes |save_stack| to be restored to its former state,
-at which time the information about the box size (100pt, |exactly|) is
-available once again; a box is packaged and we leave restricted horizontal
-mode, appending the new box to the current list of the enclosing mode
-(in this case to the current list of vertical mode), followed by any
-vertical adjustments that were removed from the box by |hpack|.
-
-The next few sections of the program are therefore concerned with the
-treatment of left and right curly braces.
-
-@ If a left brace occurs in the middle of a page or paragraph, it simply
-introduces a new level of grouping, and the matching right brace will not have
-such a drastic effect. Such grouping affects neither the mode nor the
-current list.
-
-@<Cases of |main_control| that build...@>=
-non_math(left_brace): begin
- new_save_level(simple_group);
- eq_word_define(int_base+no_local_whatsits_code,0);
- eq_word_define(int_base+no_local_dirs_code,0);
- end;
-any_mode(begin_group): begin
- new_save_level(semi_simple_group);
- eq_word_define(int_base+no_local_whatsits_code,0);
- eq_word_define(int_base+no_local_dirs_code,0);
- end;
-any_mode(end_group):
- if cur_group=semi_simple_group then begin
- temp_no_whatsits:=no_local_whatsits;
- temp_no_dirs:=no_local_dirs;
- temporary_dir:=text_direction;
- if dir_level(text_dir_ptr)=cur_level then
- @<DIR: Remove from |text_dir_ptr|@>;
- unsave;
- if abs(mode)=hmode then begin
- if temp_no_dirs<>0 then begin
- @<DIR: Add local dir node@>;
- dir_dir(tail):=temporary_dir-64;
- end;
- if temp_no_whatsits<>0 then
- @<LOCAL: Add local paragraph node@>;
- end
- end
- else off_save;
-
-@ We have to deal with errors in which braces and such things are not
-properly nested. Sometimes the user makes an error of commission by
-inserting an extra symbol, but sometimes the user makes an error of omission.
-\TeX\ can't always tell one from the other, so it makes a guess and tries
-to avoid getting into a loop.
-
-The |off_save| routine is called when the current group code is wrong. It tries
-to insert something into the user's input that will help clean off
-the top level.
-
-@<Declare act...@>=
-procedure off_save;
-var p,q:pointer; {inserted token}
-begin if cur_group=bottom_level then
- @<Drop current token and complain that it was unmatched@>
-else begin back_input; p:=get_avail; link(temp_token_head):=p;
- print_err("Missing ");
- @<Prepare to insert a token that matches |cur_group|,
- and print what it is@>;
- print(" inserted"); ins_list(link(temp_token_head));
- help5("I've inserted something that you may have forgotten.")@/
- ("(See the <inserted text> above.)")@/
- ("With luck, this will get me unwedged. But if you")@/
- ("really didn't forget anything, try typing `2' now; then")@/
- ("my insertion and my current dilemma will both disappear.");
- error;
- end;
-end;
-
-@ At this point, |link(temp_token_head)=p|, a pointer to an empty one-word node.
-
-@<Prepare to insert a token that matches |cur_group|...@>=
-case cur_group of
-semi_simple_group: begin info(p):=cs_token_flag+frozen_end_group;
- print_esc("endgroup");
-@.Missing \\endgroup inserted@>
- end;
-math_shift_group: begin info(p):=math_shift_token+"$"; print_char("$");
-@.Missing \$ inserted@>
- end;
-math_left_group: begin info(p):=cs_token_flag+frozen_right; q:=get_avail; link(p):=q;
- p:=link(p); info(p):=other_token+"."; print_esc("right.");
-@.Missing \\right\hbox{.} inserted@>
-@^null delimiter@>
- end;
-othercases begin info(p):=right_brace_token+"}"; print_char("}");
-@.Missing \} inserted@>
- end
-endcases
-
-@ @<Drop current token and complain that it was unmatched@>=
-begin print_err("Extra "); print_cmd_chr(cur_cmd,cur_chr);
-@.Extra x@>
-help1("Things are pretty mixed up, but I think the worst is over.");@/
-error;
-end
-
-@ The routine for a |right_brace| character branches into many subcases,
-since a variety of things may happen, depending on |cur_group|. Some
-types of groups are not supposed to be ended by a right brace; error
-messages are given in hopes of pinpointing the problem. Most branches
-of this routine will be filled in later, when we are ready to understand
-them; meanwhile, we must prepare ourselves to deal with such errors.
-
-@<Cases of |main_control| that build...@>=
-any_mode(right_brace): handle_right_brace;
-
-@ @<Declare the procedure called |handle_right_brace|@>=
-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 p:=null;
-case cur_group of
-simple_group: begin
- temp_no_whatsits:=no_local_whatsits;
- temp_no_dirs:=no_local_dirs;
- temporary_dir:=text_direction;
- if dir_level(text_dir_ptr)=cur_level then
- @<DIR: Remove from |text_dir_ptr|@>;
- unsave;
- if abs(mode)=hmode then begin
- if temp_no_dirs<>0 then begin
- @<DIR: Add local dir node@>;
- dir_dir(tail):=temporary_dir-64;
- end;
- if temp_no_whatsits<>0 then
- @<LOCAL: Add local paragraph node@>;
- end
- end;
-bottom_level: begin print_err("Too many }'s");
-@.Too many \}'s@>
- help2("You've closed more groups than you opened.")@/
- ("Such booboos are generally harmless, so keep going."); error;
- end;
-semi_simple_group,math_shift_group,math_left_group: extra_right_brace;
-@t\4@>@<Cases of |handle_right_brace| where a |right_brace| triggers
- a delayed action@>@;
-othercases confusion("rightbrace")
-@:this can't happen rightbrace}{\quad rightbrace@>
-endcases;
-end;
-
-@ @<Declare act...@>=
-procedure extra_right_brace;
-begin print_err("Extra }, or forgotten ");
-@.Extra \}, or forgotten x@>
-case cur_group of
-semi_simple_group: print_esc("endgroup");
-math_shift_group: print_char("$");
-math_left_group: print_esc("right");
-end;@/
-help5("I've deleted a group-closing symbol because it seems to be")@/
-("spurious, as in `$x}$'. But perhaps the } is legitimate and")@/
-("you forgot something else, as in `\hbox{$x}'. In such cases")@/
-("the way to recover is to insert both the forgotten and the")@/
-("deleted material, e.g., by typing `I$}'."); error;
-incr(align_state);
-end;
-
-@ Here is where we clear the parameters that are supposed to revert to their
-default values after every paragraph and when internal vertical mode is entered.
-
-@<Declare act...@>=
-procedure normal_paragraph;
-begin if looseness<>0 then eq_word_define(int_base+looseness_code,0);
-if hang_indent<>0 then eq_word_define(dimen_base+hang_indent_code,0);
-if hang_after<>1 then eq_word_define(int_base+hang_after_code,1);
-if par_shape_ptr<>null then eq_define(par_shape_loc,shape_ref,null);
-if inter_line_penalties_ptr<>null then
- eq_define(inter_line_penalties_loc,shape_ref,null);
-end;
-
-@ Now let's turn to the question of how \.{\\hbox} is treated. We actually
-need to consider also a slightly larger context, since constructions like
-`\.{\\setbox3=}\penalty0\.{\\hbox...}' and
-`\.{\\leaders}\penalty0\.{\\hbox...}' and
-`\.{\\lower3.8pt\\hbox...}'
-are supposed to invoke quite
-different actions after the box has been packaged. Conversely,
-constructions like `\.{\\setbox3=}' can be followed by a variety of
-different kinds of boxes, and we would like to encode such things in an
-efficient way.
-
-In other words, there are two problems: To represent the context of a box,
-and to represent its type.
-
-The first problem is solved by putting a ``context code'' on the |save_stack|,
-just below the two entries that give the dimensions produced by |scan_spec|.
-The context code is either a (signed) shift amount, or it is a large
-integer |>=box_flag|, where |box_flag=@t$2^{30}$@>|. Codes |box_flag| through
-|box_flag+biggest_reg| represent `\.{\\setbox0}' through
-`\.{\\setbox}|biggest_reg|'; codes |box_flag+biggest_reg+1| through
-|box_flag+2*biggest_reg| represent `\.{\\global\\setbox0}'
-through `\.{\\global\\setbox}|biggest_reg|'; code |box_flag+2*number_regs|
-represents `\.{\\shipout}'; and codes |box_flag+2*number_regs+1|
-through |box_flag+2*number_regs+3| represent `\.{\\leaders}', `\.{\\cleaders}',
-and `\.{\\xleaders}'.
-
-The second problem is solved by giving the command code |make_box| to all
-control sequences that produce a box, and by using the following |chr_code|
-values to distinguish between them: |box_code|, |copy_code|, |last_box_code|,
-|vsplit_code|, |vtop_code|, |vtop_code+vmode|, and |vtop_code+hmode|,
-where the latter two are used denote \.{\\vbox} and \.{\\hbox}, respectively.
-
-@d box_flag==@'10000000000 {context code for `\.{\\setbox0}'}
-@d global_box_flag==(box_flag+number_regs) {context code for `\.{\\global\\setbox0}'}
-@d max_global_box_flag==(global_box_flag+number_regs)
-@d ship_out_flag==(max_global_box_flag+1) {context code for `\.{\\shipout}'}
-@d leader_flag==ship_out_flag+1 {context code for `\.{\\leaders}'}
-@d box_code=0 {|chr_code| for `\.{\\box}'}
-@d copy_code=1 {|chr_code| for `\.{\\copy}'}
-@d last_box_code=2 {|chr_code| for `\.{\\lastbox}'}
-@d vsplit_code=3 {|chr_code| for `\.{\\vsplit}'}
-@d vtop_code=4 {|chr_code| for `\.{\\vtop}'}
-
-@<Put each...@>=
-primitive_tex("moveleft",hmove,1,0);
-@!@:move_left_}{\.{\\moveleft} primitive@>
-primitive_tex("moveright",hmove,0,0);@/
-@!@:move_right_}{\.{\\moveright} primitive@>
-primitive_tex("raise",vmove,1,0);
-@!@:raise_}{\.{\\raise} primitive@>
-primitive_tex("lower",vmove,0,0);
-@!@:lower_}{\.{\\lower} primitive@>
-@#
-primitive_tex("box",make_box,box_code,0);
-@!@:box_}{\.{\\box} primitive@>
-primitive_tex("copy",make_box,copy_code,0);
-@!@:copy_}{\.{\\copy} primitive@>
-primitive_tex("lastbox",make_box,last_box_code,0);
-@!@:last_box_}{\.{\\lastbox} primitive@>
-primitive_tex("vsplit",make_box,vsplit_code,0);
-@!@:vsplit_}{\.{\\vsplit} primitive@>
-primitive_tex("vtop",make_box,vtop_code,0);@/
-@!@:vtop_}{\.{\\vtop} primitive@>
-primitive_tex("vbox",make_box,vtop_code+vmode,0);
-@!@:vbox_}{\.{\\vbox} primitive@>
-primitive_tex("hbox",make_box,vtop_code+hmode,0);@/
-@!@:hbox_}{\.{\\hbox} primitive@>
-primitive_tex("shipout",leader_ship,a_leaders-1,0); {|ship_out_flag=leader_flag-1|}
-@!@:ship_out_}{\.{\\shipout} primitive@>
-primitive_tex("leaders",leader_ship,a_leaders,0);
-@!@:leaders_}{\.{\\leaders} primitive@>
-primitive_tex("cleaders",leader_ship,c_leaders,0);
-@!@:c_leaders_}{\.{\\cleaders} primitive@>
-primitive_tex("xleaders",leader_ship,x_leaders,0);
-@!@:x_leaders_}{\.{\\xleaders} primitive@>;
-primitive_aleph("boxdir",assign_box_dir,0,0);
-@!@:box_dir}{\.{\\boxdir} primitive@>
-
-@ 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|.
-
-@<Cases of |main_control| that build...@>=
-vmode+hmove,hmode+vmove,mmode+vmove: begin t:=cur_chr;
- scan_normal_dimen;
- if t=0 then scan_box(cur_val)@+else scan_box(-cur_val);
- end;
-any_mode(leader_ship): scan_box(leader_flag-a_leaders+cur_chr);
-any_mode(make_box): begin_box(0);
-any_mode(assign_box_dir): begin scan_register_num;
- cur_box:=box(cur_val);
- scan_optional_equals; scan_direction;
- if cur_box<>null then box_dir(cur_box):=cur_val;
- end;
-
-@ The global variable |cur_box| will point to a newly-made box. If the box
-is void, we will have |cur_box=null|. Otherwise we will have
-|type(cur_box)=hlist_node| or |vlist_node| or |rule_node|; the |rule_node|
-case can occur only with leaders.
-
-@<Glob...@>=
-@!cur_box:pointer; {box to be placed into its context}
-
-@ The |box_end| procedure does the right thing with |cur_box|, if
-|box_context| represents the context as explained above.
-
-@<Declare act...@>=
-procedure box_end(@!box_context:integer);
-begin if box_context<box_flag then @<Append box |cur_box| to the current list,
- shifted by |box_context|@>
-else if box_context<ship_out_flag then @<Store \(c)|cur_box| in a box register@>
-else if cur_box<>null then begin
- if box_context>ship_out_flag then @<Append a new leader node that
- uses |cur_box|@>
- else ship_out(cur_box);
- end;
-end;
-
-@ The global variable |adjust_tail| will be non-null if and only if the
-current box might include adjustments that should be appended to the
-current vertical list.
-
-@<Append box |cur_box| to the current...@>=
-begin if cur_box<>null then
- begin shift_amount(cur_box):=box_context;
- if abs(mode)=vmode then
- begin
- if pre_adjust_tail <> null then begin
- if pre_adjust_head <> pre_adjust_tail then
- append_list(pre_adjust_head)(pre_adjust_tail);
- pre_adjust_tail := null;
- end;
- append_to_vlist(cur_box);
- if adjust_tail <> null then begin
- if adjust_head <> adjust_tail then
- append_list(adjust_head)(adjust_tail);
- adjust_tail := null;
- end;
- if mode>0 then begin check_filter('box'); build_page; end;
- end
- else begin if abs(mode)=hmode then space_factor:=1000
- else cur_box:=new_sub_box(cur_box);
- vlink(tail):=cur_box; tail:=cur_box;
- end;
- end;
-end
-
-@ @<Store \(c)|cur_box| in a box register@>=
-if box_context<global_box_flag then
- eq_define(box_base+box_context-box_flag,box_ref,cur_box)
-else geq_define(box_base+box_context-global_box_flag,box_ref,cur_box)
-
-@ @<Append a new leader node ...@>=
-begin @<Get the next non-blank non-relax...@>;
-if ((cur_cmd=hskip)and(abs(mode)<>vmode))or@|
- ((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
-else begin print_err("Leaders not followed by proper glue");
-@.Leaders not followed by...@>
- help3("You should say `\leaders <box or rule><hskip or vskip>'.")@/
- ("I found the <box or rule>, but there's no suitable")@/
- ("<hskip or vskip>, so I'm ignoring these leaders."); back_error;
- flush_node_list(cur_box);
- end;
-end
-
-@ Now that we can see what eventually happens to boxes, we can consider
-the first steps in their creation. The |begin_box| routine is called when
-|box_context| is a context specification, |cur_chr| specifies the type of
-box desired, and |cur_cmd=make_box|.
-
-@<Declare act...@>=
-procedure begin_box(@!box_context:integer);
-label exit, done;
-var @!p,@!q:pointer; {run through the current list}
-@!k:halfword; {0 or |vmode| or |hmode|}
-@!n:eight_bits; {a box number}
-begin case cur_chr of
-box_code: begin scan_register_num; cur_box:=box(cur_val);
- box(cur_val):=null; {the box becomes void, at the same level}
- end;
-copy_code: begin scan_register_num; cur_box:=copy_node_list(box(cur_val));
- end;
-last_box_code: @<If the current list ends with a box node, delete it from
- the list and make |cur_box| point to it; otherwise set |cur_box:=null|@>;
-vsplit_code: @<Split off part of a vertical box, make |cur_box| point to it@>;
-othercases @<Initiate the construction of an hbox or vbox, then |return|@>
-endcases;@/
-box_end(box_context); {in simple cases, we use the box immediately}
-exit:end;
-
-@ Note that the condition |not is_char_node(tail)| implies that |head<>tail|,
-since |head| is a one-word node.
-
-@<If the current list ends with a box node, delete it...@>=
-begin cur_box:=null;
-if abs(mode)=mmode then
- begin you_cant; help1("Sorry; this \lastbox will be void."); error;
- end
-else if (mode=vmode)and(head=tail) then
- begin you_cant;
- help2("Sorry...I usually can't take things from the current page.")@/
- ("This \lastbox will therefore be void."); error;
- end
-else begin if not is_char_node(tail) then
- if (type(tail)=hlist_node)or(type(tail)=vlist_node) then
- @<Remove the last box, unless it's part of a discretionary@>;
- end;
-end
-
-@ @<Remove the last box...@>=
-begin q:=head;
-repeat p:=q;
-if not is_char_node(q) then if type(q)=disc_node then
- begin
- if p=tail then goto done;
- end;
-q:=vlink(p);
-until q=tail;
-cur_box:=tail; shift_amount(cur_box):=0;
-tail:=p; vlink(p):=null;
-done:end
-
-@ Here we deal with things like `\.{\\vsplit 13 to 100pt}'.
-
-@<Split off part of a vertical box, make |cur_box| point to it@>=
-begin scan_register_num; n:=cur_val;
-if not scan_keyword('to') then
-@.to@>
- begin print_err("Missing `to' inserted");
-@.Missing `to' inserted@>
- help2("I'm working on `\vsplit<box number> to <dimen>';")@/
- ("will look for the <dimen> next."); error;
- end;
-scan_normal_dimen;
-cur_box:=vsplit(n,cur_val);
-end
-
-@ Here is where we enter restricted horizontal mode or internal vertical
-mode, in order to make a box.
-
-@<Initiate the construction of an hbox or vbox, then |return|@>=
-begin k:=cur_chr-vtop_code; saved(0):=box_context;
-case abs(mode) of
-vmode: spec_direction:=body_direction;
-hmode: spec_direction:=text_direction;
-mmode: spec_direction:=math_direction;
-end;
-if k=hmode then
- if (box_context<box_flag)and(abs(mode)=vmode) then
- scan_spec(adjusted_hbox_group,true)
- else scan_spec(hbox_group,true)
-else begin if k=vmode then scan_spec(vbox_group,true)
- else begin scan_spec(vtop_group,true); k:=vmode;
- end;
- normal_paragraph;
- end;
-push_nest; mode:=-k;
-if k=vmode then
- 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;
- if every_hbox<>null then begin_token_list(every_hbox,every_hbox_text);
- end;
-return;
-end
-
-@ @<Declare act...@>=
-procedure scan_box(@!box_context:integer);
- {the next input should specify a box or perhaps a rule}
-begin @<Get the next non-blank non-relax...@>;
-if cur_cmd=make_box then begin_box(box_context)
-else if (box_context>=leader_flag)and((cur_cmd=hrule)or(cur_cmd=vrule)) then
- begin cur_box:=scan_rule_spec; box_end(box_context);
- end
-else begin@t@>@;@/
- print_err("A <box> was supposed to be here");@/
-@.A <box> was supposed to...@>
- help3("I was expecting to see \hbox or \vbox or \copy or \box or")@/
- ("something like that. So you might find something missing in")@/
- ("your output. But keep trying; you can fix this later."); back_error;
- end;
-end;
-
-@ When the right brace occurs at the end of an \.{\\hbox} or \.{\\vbox} or
-\.{\\vtop} construction, the |package| routine comes into action. We might
-also have to finish a paragraph that hasn't ended.
-
-@<Cases of |handle...@>=
-hbox_group: package(0);
-adjusted_hbox_group: begin adjust_tail:=adjust_head;
- pre_adjust_tail:=pre_adjust_head; package(0);
- end;
-vbox_group: begin line_break_context:=vbox_group; end_graf; package(0);
- end;
-vtop_group: begin line_break_context:=vtop_group; end_graf; package(vtop_code);
- end;
-
-@ @<Declare action...@>=
-procedure package(@!c:small_number);
-var h:scaled; {height of box}
-@!p:pointer; {first node in a box}
-@!d:scaled; {max depth}
-@!grp:integer;
-begin grp:=cur_group;
-d:=box_max_depth; unsave; save_ptr:=save_ptr-6;
-pack_direction:=saved(3);
-if mode=-hmode then cur_box:=filtered_hpack(head,tail,saved(2),saved(1),grp)
-else begin cur_box:=filtered_vpackage(vlink(head),saved(2),saved(1),d,grp);
- if c=vtop_code then @<Readjust the height and depth of |cur_box|,
- for \.{\\vtop}@>;
- end;
-if saved(4)<>null then
- @<DIR: Adjust back |text_dir_ptr| for |scan_spec|@>;
-replace_attribute_list(cur_box, saved(5));
-pop_nest; box_end(saved(0));
-end;
-
-@ The height of a `\.{\\vtop}' box is inherited from the first item on its list,
-if that item is an |hlist_node|, |vlist_node|, or |rule_node|; otherwise
-the \.{\\vtop} height is zero.
-
-
-@<Readjust the height...@>=
-begin h:=0; p:=list_ptr(cur_box);
-if p<>null then if type(p)<=rule_node then h:=height(p);
-depth(cur_box):=depth(cur_box)-h+height(cur_box); height(cur_box):=h;
-end
-
-@ Here is a really small patch to add a new primitive called
-\.{\\quitvmode}. In vertical modes, it is identical to \.{\\indent},
-but in horizontal and math modes it is really a no-op (as opposed to
-\.{\\indent}, which executes the |indent_in_hmode| procedure).
-
-A paragraph begins when horizontal-mode material occurs in vertical mode,
-or when the paragraph is explicitly started by `\.{\\quitvmode}',
-`\.{\\indent}' or `\.{\\noindent}'.
-
-@<Put each...@>=
-primitive_tex("indent",start_par,1,0);
-@!@:indent_}{\.{\\indent} primitive@>
-primitive_tex("noindent",start_par,0,0);
-@!@:no_indent_}{\.{\\noindent} primitive@>
-primitive_pdftex("quitvmode",start_par,2,0);
-@!@:quit_vmode_}{\.{\\quitvmode} primitive@>
-
-@ @<Cases of |main_control| that build...@>=
-vmode+start_par: new_graf(cur_chr>0);
-vmode+letter,vmode+other_char,vmode+char_num,vmode+char_given,
- vmode+char_ghost,
- vmode+math_shift,vmode+math_shift_cs,vmode+un_hbox,vmode+vrule,
- vmode+accent,vmode+discretionary,vmode+hskip,vmode+valign,
- vmode+ex_space,vmode+no_boundary:@t@>@;@/
- begin back_input; new_graf(true);
- end;
-
-@ @<Declare act...@>=
-procedure new_graf(@!indented:boolean);
-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));
- end;
-push_nest; mode:=hmode; space_factor:=1000;
-@<LOCAL: Add local paragraph node@>;
-if indented then begin
- p:=new_null_box; box_dir(p):=par_direction;
- width(p):=par_indent;@+
- tail_append(p);
- end;
-q:=tail;
-dir_rover:=text_dir_ptr;
-while dir_rover<>null do
- begin
- if (vlink(dir_rover)<>null) or (dir_dir(dir_rover)<>par_direction) then
- begin
- dir_graf_tmp:=new_dir(dir_dir(dir_rover));
- vlink(dir_graf_tmp):=vlink(q); vlink(q):=dir_graf_tmp;
- end;
- dir_rover:=vlink(dir_rover);
- end;
-q:=head;
-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
- check_filter('new_graf'); build_page; {put |par_skip| glue on current page}
- end;
-end;
-
-@ @<Cases of |main_control| that build...@>=
-hmode+start_par,mmode+start_par: if cur_chr<>2 then indent_in_hmode;
-
-@ @<Declare act...@>=
-procedure indent_in_hmode;
-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 p:=new_sub_box(p);
- tail_append(p);
- end;
-end;
-
-@ A paragraph ends when a |par_end| command is sensed, or when we are in
-horizontal mode when reaching the right brace of vertical-mode routines
-like \.{\\vbox}, \.{\\insert}, or \.{\\output}.
-
-@<Cases of |main_control| that build...@>=
-vmode+par_end: begin normal_paragraph;
- if mode>0 then begin check_filter('vmode_par'); build_page; end;
- end;
-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;
- 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;
-hmode+stop,hmode+vskip,hmode+hrule,hmode+un_vbox,hmode+halign: head_for_vmode;
-
-@ @<Declare act...@>=
-procedure head_for_vmode;
-begin if mode<0 then
- if cur_cmd<>hrule then off_save
- else begin print_err("You can't use `");
- print_esc("hrule"); print("' here except with leaders");
-@.You can't use \\hrule...@>
- help2("To put a horizontal rule in an hbox or an alignment,")@/
- ("you should use \leaders or \hrulefill (see The TeXbook).");
- error;
- end
-else begin back_input; cur_tok:=par_token; back_input; token_type:=inserted;
- end;
-end;
-
-@ TODO (BUG?): |dir_save| would have been set by |line_break| by means
-of |post_line_break|, but this is not done right now, as it introduces
-pretty heavy memory leaks. This means the current code is probably
-wrong in some way that relates to in-paragraph displays.
-
-@<Declare act...@>=
-procedure end_graf;
-begin if mode=hmode then
- begin if (head=tail) or (vlink(head)=tail) then pop_nest
- {null paragraphs are ignored, all contain a |local_paragraph| node}
- else line_break(false);
- if dir_save<>null then
- begin flush_node_list(dir_save); dir_save:=null;
- end;
- normal_paragraph;
- error_count:=0;
- end;
-end;
-
-@ Insertion and adjustment and mark nodes are constructed by the following
-pieces of the program.
-
-@<Cases of |main_control| that build...@>=
-any_mode(insert),hmode+vadjust,mmode+vadjust: begin_insert_or_adjust;
-any_mode(mark): handle_mark;
-
-@ @<Forbidden...@>=
-vmode+vadjust,
-
-@ @<Declare act...@>=
-procedure begin_insert_or_adjust;
-begin if cur_cmd=vadjust then cur_val:=output_box
-else begin scan_register_num;
- 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
- 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:=pdf_ignored_dimen;
-end;
-
-@ @<Cases of |handle...@>=
-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 |output_box| for |vadjust|}
- p:=vpack(vlink(head),natural); pop_nest;
- 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;
- end
- else begin tail_append(new_node(adjust_node,saved(1))); {the |subtype| is used for |adjust_pre|}
- adjust_ptr(tail):=list_ptr(p); delete_glue_ref(q);
- end;
- list_ptr(p):=null; flush_node(p);
- if nest_ptr=0 then begin check_filter('insert'); build_page; end;
- end;
-output_group: @<Resume the page builder...@>;
-
-@ I've renamed the |make_mark| procedure to this, because if the
-current chr code is 1, then the actual command was \.{\\clearmarks},
-which does not generate a mark node but instead destroys the current
-mark tokenlists.
-
-@<Declare act...@>=
-procedure handle_mark;
-var p:pointer; {new node}
-@!c:halfword; {the mark class}
-begin if cur_chr=clear_marks_code then begin
- scan_mark_num; c:=cur_val;
- delete_top_mark(c); delete_bot_mark(c); delete_first_mark(c);
- delete_split_first_mark(c); delete_split_bot_mark(c);
- end
-else begin
-if cur_chr=0 then c:=0
-else begin scan_mark_num; c:=cur_val;
- if c > biggest_used_mark then biggest_used_mark := c;
- end;
-p:=scan_toks(false,true);
-p:=new_node(mark_node,0); {the |subtype| is not used}
-mark_class(p):=c;
-mark_ptr(p):=def_ref; vlink(tail):=p; tail:=p;
-end;
-end;
-
-@ Penalty nodes get into a list via the |break_penalty| command.
-@^penalties@>
-
-@<Cases of |main_control| that build...@>=
-any_mode(break_penalty): append_penalty;
-
-@ @<Declare action...@>=
-procedure append_penalty;
-begin scan_int; tail_append(new_penalty(cur_val));
-if mode=vmode then begin check_filter('penalty'); build_page; end;
-end;
-
-@ The |remove_item| command removes a penalty, kern, or glue node if it
-appears at the tail of the current list, using a brute-force linear scan.
-Like \.{\\lastbox}, this command is not allowed in vertical mode (except
-internal vertical mode), since the current list in vertical mode is sent
-to the page builder. But if we happen to be able to implement it in
-vertical mode, we do.
-
-@<Cases of |main_control| that build...@>=
-any_mode(remove_item): delete_last;
-
-@ When |delete_last| is called, |cur_chr| is the |type| of node that
-will be deleted, if present.
-
-@<Declare action...@>=
-procedure delete_last;
-label exit;
-var @!p,@!q:pointer; {run through the current list}
-begin if (mode=vmode)and(tail=head) then
- @<Apologize for inability to do the operation now,
- unless \.{\\unskip} follows non-glue@>
-else begin if not is_char_node(tail) then if type(tail)=cur_chr then
- begin q:=head;
- repeat p:=q;
- if not is_char_node(q) then if type(q)=disc_node then
- begin
- if p=tail then return;
- end;
- q:=vlink(p);
- until q=tail;
- vlink(p):=null; flush_node_list(tail); tail:=p;
- end;
- end;
-exit:end;
-
-@ @<Apologize for inability to do the operation...@>=
-begin if (cur_chr<>glue_node)or(last_glue<>max_halfword) then
- begin you_cant;
- help2("Sorry...I usually can't take things from the current page.")@/
- ("Try `I\vskip-\lastskip' instead.");
- if cur_chr=kern_node then help_line[0]:=
- ("Try `I\kern-\lastkern' instead.")
- else if cur_chr<>glue_node then help_line[0]:=@|
- ("Perhaps you can make the output routine do it.");
- error;
- end;
-end
-
-@ @<Put each...@>=
-primitive_tex("unpenalty",remove_item,penalty_node,0);@/
-@!@:un_penalty_}{\.{\\unpenalty} primitive@>
-primitive_tex("unkern",remove_item,kern_node,0);@/
-@!@:un_kern_}{\.{\\unkern} primitive@>
-primitive_tex("unskip",remove_item,glue_node,0);@/
-@!@:un_skip_}{\.{\\unskip} primitive@>
-primitive_tex("unhbox",un_hbox,box_code,0);@/
-@!@:un_hbox_}{\.{\\unhbox} primitive@>
-primitive_tex("unhcopy",un_hbox,copy_code,0);@/
-@!@:un_hcopy_}{\.{\\unhcopy} primitive@>
-primitive_tex("unvbox",un_vbox,box_code,0);@/
-@!@:un_vbox_}{\.{\\unvbox} primitive@>
-primitive_tex("unvcopy",un_vbox,copy_code,0);@/
-@!@:un_vcopy_}{\.{\\unvcopy} primitive@>
-
-@ The |un_hbox| and |un_vbox| commands unwrap one of the |number_regs| current boxes.
-
-@<Cases of |main_control| that build...@>=
-vmode+un_vbox,hmode+un_hbox,mmode+un_hbox: unpackage;
-
-@ @<Declare act...@>=
-procedure unpackage;
-label done, exit;
-var p:pointer; {the box}
- r: pointer; {to remove marginal kern nodes}
-@!c:box_code..copy_code; {should we copy?}
-@!s:pointer; {for varmem assignment }
-begin if cur_chr>copy_code then @<Handle saved items and |goto done|@>;
-c:=cur_chr; scan_register_num; p:=box(cur_val);
-if p=null then return;
-if (abs(mode)=mmode)or((abs(mode)=vmode)and(type(p)<>vlist_node))or@|
- ((abs(mode)=hmode)and(type(p)<>hlist_node)) then
- begin print_err("Incompatible list can't be unboxed");
-@.Incompatible list...@>
- help3("Sorry, Pandora. (You sneaky devil.)")@/
- ("I refuse to unbox an \hbox in vertical mode or vice versa.")@/
- ("And I can't open any boxes in math mode.");@/
- error; return;
- end;
-if c=copy_code then begin s:=copy_node_list(list_ptr(p)); vlink(tail):=s; end
-else begin vlink(tail):=list_ptr(p); box(cur_val):=null;
- list_ptr(p):=null; flush_node(p);
- end;
-done:
-while vlink(tail) <> null do begin
- r := vlink(tail);
- if not is_char_node(r) and (type(r) = margin_kern_node) then begin
- vlink(tail) := vlink(r);
- flush_node(r);
- end;
- tail:=vlink(tail);
-end;
-exit:end;
-
-@ @<Forbidden...@>=vmode+ital_corr,
-
-@ Italic corrections are converted to kern nodes when the |ital_corr| command
-follows a character. In math mode the same effect is achieved by appending
-a kern of zero here, since italic corrections are supplied later.
-
-@<Cases of |main_control| that build...@>=
-hmode+ital_corr: append_italic_correction;
-mmode+ital_corr: tail_append(new_kern(0));
-
-@ @<Declare act...@>=
-procedure append_italic_correction;
-label exit;
-var p:pointer; {|char_node| at the tail of the current list}
-@!f:internal_font_number; {the font in the |char_node|}
-begin if tail<>head then
- begin if is_char_node(tail) then p:=tail
- else return;
- f:=font(p);
- tail_append(new_kern(char_italic(f,character(p))));
- subtype(tail):=explicit;
- end;
-exit:end;
-
-@ Discretionary nodes are easy in the common case `\.{\\-}', but in the
-general case we must process three braces full of items.
-
-There are four subtypes of discretionaries, but only the first two are
-generated by primitive commands.
-
-@d discretionary_disc=0
-@d explicit_disc=1
-
-@<Put each...@>=
-primitive_tex("-",discretionary,explicit_disc,0);
-@!@:Single-character primitives -}{\quad\.{\\-}@>
-primitive_tex("discretionary",discretionary,discretionary_disc,0);
-@!@:discretionary_}{\.{\\discretionary} primitive@>
-primitive_omega("localleftbox",assign_local_box,0,0);
-@!@:assign_local_box}{\.{\\localleftbox} primitive@>
-primitive_omega("localrightbox",assign_local_box,1,0);
-@!@:assign_local_box}{\.{\\localrightbox} primitive@>
-
-@ @<Cases of |main_control| that build...@>=
-hmode+discretionary,mmode+discretionary: append_discretionary;
-any_mode(assign_local_box): append_local_box(cur_chr);
-
-@ The space factor does not change when we append a discretionary node,
-but it starts out as 1000 in the subsidiary lists.
-
-@<Declare act...@>=
-procedure append_local_box(kind:integer);
-begin
-incr(save_ptr); saved(-1):=kind; new_save_level(local_box_group);
-scan_left_brace; push_nest; mode:=-hmode; space_factor:=1000;
-end;
-
-procedure append_discretionary;
-var c:integer;
-begin tail_append(new_disc);
-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);
- alink(vlink(pre_break(tail))):=pre_break(tail);
- tlink(pre_break(tail)):=vlink(pre_break(tail));
- end;
- c:=get_post_hyphen_char(cur_lang);
- if c<>0 then begin
- vlink(post_break(tail)):=new_char(cur_font,c);
- alink(vlink(post_break(tail))):=post_break(tail);
- tlink(post_break(tail)):=vlink(post_break(tail));
- end;
- end
-else begin incr(save_ptr); saved(-1):=0; new_save_level(disc_group);
- scan_left_brace; push_nest; mode:=-hmode; space_factor:=1000;
- end;
-end;
-
-@ The three discretionary lists are constructed somewhat as if they were
-hboxes. A~subroutine called |build_discretionary| handles the transitions.
-(This is sort of fun.)
-
-@<Cases of |handle...@>=
-disc_group: build_discretionary;
-local_box_group: build_local_box;
-
-@ @<Declare act...@>=
-procedure build_local_box;
-var p:pointer;
- kind:integer;
-begin
-unsave;
-kind:=saved(-1);
-decr(save_ptr);
-p:=vlink(head); pop_nest;
-if p<>null then
- p:=hpack(p,natural);
-if kind=0 then
- eq_define(local_left_box_base,box_ref,p)
-else
- eq_define(local_right_box_base,box_ref,p);
-if abs(mode)=hmode then
- @<LOCAL: Add local paragraph node@>;
-eq_word_define(int_base+no_local_whatsits_code,no_local_whatsits+1);
-end;
-
-procedure build_discretionary;
-label done,exit;
-var p,@!q:pointer; {for link manipulation}
-@!n:integer; {length of discretionary list}
-begin unsave;
-@<Prune the current list, if necessary, until it contains only
- |char_node|, |kern_node|, |hlist_node|, |vlist_node| and
- |rule_node| items; set |n| to the length of the list,
- and set |q| to the list's tail@>;
-p:=vlink(head); pop_nest;
-case saved(-1) of
-0: if (n>0) then begin
- vlink(pre_break(tail)):=p;
- alink(p):=pre_break(tail);
- tlink(pre_break(tail)):=q;
- end;
-1: if (n>0) then begin
- vlink(post_break(tail)):=p;
- alink(p):=post_break(tail);
- tlink(post_break(tail)):=q;
- end;
-2:@<Attach list |p| to the current list, and record its length;
- then finish up and |return|@>;
-end; {there are no other cases}
-incr(saved(-1)); new_save_level(disc_group); scan_left_brace;
-push_nest; mode:=-hmode; space_factor:=1000;
-exit:end;
-
-@ @<Attach list |p| to the current...@>=
-begin if (n>0)and(abs(mode)=mmode) then
- begin print_err("Illegal math "); print_esc("discretionary");
-@.Illegal math \\disc...@>
- help2("Sorry: The third part of a discretionary break must be")@/
- ("empty, in math formulas. I had to delete your third part.");
- flush_node_list(p); error;
- end
-else begin
- if (n>0) then begin
- vlink(no_break(tail)):=p;
- alink(p):=no_break(tail);
- tlink(no_break(tail)):=q;
- end;
- end;
-decr(save_ptr); return;
-end
-
-@ During this loop, |p=vlink(q)| and there are |n| items preceding |p|.
-
-@<Prune the current list, if necessary...@>=
-q:=head; p:=vlink(q); n:=0;
-while p<>null do
- begin if not is_char_node(p) then
- if type(p)>rule_node then if type(p)<>kern_node then
- begin print_err("Improper discretionary list");
-@.Improper discretionary list@>
- help1("Discretionary lists must contain only boxes and kerns.");@/
- error;
- begin_diagnostic;
- print_nl("The following discretionary sublist has been deleted:");
-@.The following...deleted@>
- show_box(p);
- end_diagnostic(true);
- flush_node_list(p); vlink(q):=null; goto done;
- end;
- alink(p):=q; q:=p; p:=vlink(q); incr(n);
- end;
-done:
-
-@ We need only one more thing to complete the horizontal mode routines, namely
-the \.{\\accent} primitive.
-
-@<Cases of |main_control| that build...@>=
-hmode+accent: make_accent;
-
-@ The positioning of accents is straightforward but tedious. Given an accent
-of width |a|, designed for characters of height |x| and slant |s|;
-and given a character of width |w|, height |h|, and slant |t|: We will shift
-the accent down by |x-h|, and we will insert kern nodes that have the effect of
-centering the accent over the character and shifting the accent to the
-right by $\delta={1\over2}(w-a)+h\cdot t-x\cdot s$. If either character is
-absent from the font, we will simply use the other, without shifting.
-
-@<Declare act...@>=
-procedure make_accent;
-var s,@!t: real; {amount of slant}
-@!p,@!q,@!r:pointer; {character, box, and kern nodes}
-@!f:internal_font_number; {relevant font}
-@!a,@!h,@!x,@!w,@!delta:scaled; {heights and widths, as explained above}
-begin scan_char_num; f:=cur_font; p:=new_glyph(f,cur_val);
-if p<>null then
- begin x:=x_height(f); s:=slant(f)/float_constant(65536);
-@^real division@>
- a:=glyph_width(p);@/
- do_assignments;@/
- @<Create a character node |q| for the next character,
- but set |q:=null| if problems arise@>;
- if q<>null then @<Append the accent with appropriate kerns,
- then set |p:=q|@>;
- vlink(tail):=p; tail:=p; space_factor:=1000;
- end;
-end;
-
-@ @<Create a character node |q| for the next...@>=
-q:=null; f:=cur_font;
-if (cur_cmd=letter)or(cur_cmd=other_char)or(cur_cmd=char_given) then
- q:=new_glyph(f,cur_chr)
-else if cur_cmd=char_num then
- begin scan_char_num; q:=new_glyph(f,cur_val);
- end
-else back_input
-
-@ The kern nodes appended here must be distinguished from other kerns, lest
-they be wiped away by the hyphenation algorithm or by a previous line break.
-
-The two kerns are computed with (machine-dependent) |real| arithmetic, but
-their sum is machine-independent; the net effect is machine-independent,
-because the user cannot remove these nodes nor access them via \.{\\lastkern}.
-
-@<Append the accent with appropriate kerns...@>=
-begin t:=slant(f)/float_constant(65536);
-@^real division@>
-w:=glyph_width(q);
-h:=glyph_height(q);
-if h<>x then {the accent must be shifted up or down}
- begin p:=hpack(p,natural); shift_amount(p):=x-h;
- end;
-delta:=round((w-a)/float_constant(2)+h*t-x*s);
-@^real multiplication@>
-@^real addition@>
-r:=new_kern(delta); subtype(r):=acc_kern; vlink(tail):=r; vlink(r):=p;
-tail:=new_kern(-a-delta); subtype(tail):=acc_kern; vlink(p):=tail; p:=q;
-end
-
-@ When `\.{\\cr}' or `\.{\\span}' or a tab mark comes through the scanner
-into |main_control|, it might be that the user has foolishly inserted
-one of them into something that has nothing to do with alignment. But it is
-far more likely that a left brace or right brace has been omitted, since
-|get_next| takes actions appropriate to alignment only when `\.{\\cr}'
-or `\.{\\span}' or tab marks occur with |align_state=0|. The following
-program attempts to make an appropriate recovery.
-
-@<Cases of |main_control| that build...@>=
-any_mode(car_ret), any_mode(tab_mark): align_error;
-any_mode(no_align): no_align_error;
-any_mode(omit): omit_error;
-
-@ @<Declare act...@>=
-procedure align_error;
-begin if abs(align_state)>2 then
- @<Express consternation over the fact that no alignment is in progress@>
-else begin back_input;
- if align_state<0 then
- begin print_err("Missing { inserted");
-@.Missing \{ inserted@>
- incr(align_state); cur_tok:=left_brace_token+"{";
- end
- else begin print_err("Missing } inserted");
-@.Missing \} inserted@>
- decr(align_state); cur_tok:=right_brace_token+"}";
- end;
- help3("I've put in what seems to be necessary to fix")@/
- ("the current column of the current alignment.")@/
- ("Try to go on, since this might almost work."); ins_error;
- end;
-end;
-
-@ @<Express consternation...@>=
-begin print_err("Misplaced "); print_cmd_chr(cur_cmd,cur_chr);
-@.Misplaced \&@>
-@.Misplaced \\span@>
-@.Misplaced \\cr@>
-if cur_tok=tab_token+"&" then
- begin help6("I can't figure out why you would want to use a tab mark")@/
- ("here. If you just want an ampersand, the remedy is")@/
- ("simple: Just type `I\&' now. But if some right brace")@/
- ("up above has ended a previous alignment prematurely,")@/
- ("you're probably due for more error messages, and you")@/
- ("might try typing `S' now just to see what is salvageable.");
- end
-else begin help5("I can't figure out why you would want to use a tab mark")@/
- ("or \cr or \span just now. If something like a right brace")@/
- ("up above has ended a previous alignment prematurely,")@/
- ("you're probably due for more error messages, and you")@/
- ("might try typing `S' now just to see what is salvageable.");
- end;
-error;
-end
-
-@ The help messages here contain a little white lie, since \.{\\noalign}
-and \.{\\omit} are allowed also after `\.{\\noalign\{...\}}'.
-
-@<Declare act...@>=
-procedure no_align_error;
-begin print_err("Misplaced "); print_esc("noalign");
-@.Misplaced \\noalign@>
-help2("I expect to see \noalign only after the \cr of")@/
- ("an alignment. Proceed, and I'll ignore this case."); error;
-end;
-procedure omit_error;
-begin print_err("Misplaced "); print_esc("omit");
-@.Misplaced \\omit@>
-help2("I expect to see \omit only after tab marks or the \cr of")@/
- ("an alignment. Proceed, and I'll ignore this case."); error;
-end;
-
-@ We've now covered most of the abuses of \.{\\halign} and \.{\\valign}.
-Let's take a look at what happens when they are used correctly.
-
-@<Cases of |main_control| that build...@>=
-vmode+halign,hmode+valign:init_align;
-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|
-during an entire alignment, until |fin_align| removes it.
-
-A devious user might force an |endv| command to occur just about anywhere;
-we must defeat such hacks.
-
-@<Declare act...@>=
-procedure do_endv;
-begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
-while (input_stack[base_ptr].index_field<>v_template) and
- (input_stack[base_ptr].loc_field=null) and
- (input_stack[base_ptr].state_field=token_list) do decr(base_ptr);
-if (input_stack[base_ptr].index_field<>v_template) or
- (input_stack[base_ptr].loc_field<>null) or
- (input_stack[base_ptr].state_field<>token_list) then
- fatal_error("(interwoven alignment preambles are not allowed)");
-@.interwoven alignment preambles...@>
- if cur_group=align_group then
- begin line_break_context:=align_group; end_graf;
- if fin_col then fin_row;
- end
-else off_save;
-end;
-
-@ @<Cases of |handle_right_brace|...@>=
-align_group: begin back_input; cur_tok:=cs_token_flag+frozen_cr;
- print_err("Missing "); print_esc("cr"); print(" inserted");
-@.Missing \\cr inserted@>
- help1("I'm guessing that you meant to end an alignment here.");
- ins_error;
- end;
-
-@ @<Cases of |handle_right_brace|...@>=
-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|.
-
-@<Cases of |main_control| that build...@>=
-any_mode(end_cs_name): cs_error;
-
-@ @<Declare act...@>=
-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.
-
-@ 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|.
-
-@<Put each...@>=
-primitive_luatex("Ustartmath",math_shift_cs,text_style,0);
-@!@:math_shift_cs_}{\.{\\Ustartmath} primitive@>
-primitive_luatex("Ustopmath",math_shift_cs,cramped_text_style,0);
-@!@:math_shift_cs_}{\.{\\Ustopmath} primitive@>
-primitive_luatex("Ustartdisplaymath",math_shift_cs,display_style,0);
-@!@:math_shift_cs_}{\.{\\Ustartdisplaymath} primitive@>
-primitive_luatex("Ustopdisplaymath",math_shift_cs,cramped_display_style,0);
-@!@:math_shift_cs_}{\.{\\Ustopdisplaymath} primitive@>
-
-@
-
-@<Cases of |main_control| that build...@>=
-hmode+math_shift, hmode+math_shift_cs:init_math;
-mmode+eq_no: if privileged then begin
- if cur_group=math_shift_group then start_eq_no
- else off_save;
- end;
-
-@ @<Put each...@>=
-primitive_tex("eqno",eq_no,0,0);
-@!@:eq_no_}{\.{\\eqno} primitive@>
-primitive_tex("leqno",eq_no,1,0);
-@!@:leq_no_}{\.{\\leqno} primitive@>
-
-@ @<Forbidden...@>=non_math(eq_no),
-
-@ @<Cases of |main_control| that build...@>=
-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
- 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
- mval := mathchar_from_integer(cur_chr,tex_mathcode);
- set_math_char(mval);
- end;
-mmode+omath_given: begin
- mval := mathchar_from_integer(cur_chr,aleph_mathcode);
- set_math_char(mval);
- end;
-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;
-
-@ Primitive math operators like \.{\\mathop} and \.{\\underline} are given
-the command code |math_comp|, supplemented by the noad type that they
-generate.
-
-@<Put each...@>=
-primitive_tex("mathord",math_comp,ord_noad_type,0);
-@!@:math_ord_}{\.{\\mathord} primitive@>
-primitive_tex("mathop",math_comp,op_noad_type_normal,0);
-@!@:math_op_}{\.{\\mathop} primitive@>
-primitive_tex("mathbin",math_comp,bin_noad_type,0);
-@!@:math_bin_}{\.{\\mathbin} primitive@>
-primitive_tex("mathrel",math_comp,rel_noad_type,0);
-@!@:math_rel_}{\.{\\mathrel} primitive@>
-primitive_tex("mathopen",math_comp,open_noad_type,0);
-@!@:math_open_}{\.{\\mathopen} primitive@>
-primitive_tex("mathclose",math_comp,close_noad_type,0);
-@!@:math_close_}{\.{\\mathclose} primitive@>
-primitive_tex("mathpunct",math_comp,punct_noad_type,0);
-@!@:math_punct_}{\.{\\mathpunct} primitive@>
-primitive_tex("mathinner",math_comp,inner_noad_type,0);
-@!@:math_inner_}{\.{\\mathinner} primitive@>
-primitive_tex("underline",math_comp,under_noad_type,0);
-@!@:underline_}{\.{\\underline} primitive@>
-primitive_tex("overline",math_comp,over_noad_type,0);@/
-@!@:overline_}{\.{\\overline} primitive@>
-primitive_tex("displaylimits",limit_switch,op_noad_type_normal,0);
-@!@:display_limits_}{\.{\\displaylimits} primitive@>
-primitive_tex("limits",limit_switch,op_noad_type_limits,0);
-@!@:limits_}{\.{\\limits} primitive@>
-primitive_tex("nolimits",limit_switch,op_noad_type_no_limits,0);
-@!@:no_limits_}{\.{\\nolimits} primitive@>
-
-@ @<Cases of |main_control| that build...@>=
-mmode+math_comp: math_math_comp;
-mmode+limit_switch: math_limit_switch;
-mmode+radical: math_radical;
-mmode+accent,mmode+math_accent:math_ac;
-mmode+vcenter: begin scan_spec(vcenter_group,false); normal_paragraph;
- push_nest; mode:=-vmode; prev_depth:=pdf_ignored_dimen;
- if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text);
- end;
-
-@ @<Cases of |handle...@>=
-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;
- p:=math_vcenter_group(p);
- tail_append(p);
- end;
-
-@ The routine that inserts a |style_node| holds no surprises.
-
-@<Put each...@>=
-primitive_tex("displaystyle",math_style,display_style,0);
-@!@:display_style_}{\.{\\displaystyle} primitive@>
-primitive_tex("textstyle",math_style,text_style,0);
-@!@:text_style_}{\.{\\textstyle} primitive@>
-primitive_tex("scriptstyle",math_style,script_style,0);
-@!@:script_style_}{\.{\\scriptstyle} primitive@>
-primitive_tex("scriptscriptstyle",math_style,script_script_style,0);
-@!@:script_script_style_}{\.{\\scriptscriptstyle} primitive@>
-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@>
-
-@ @<Cases of |main_control| that build...@>=
-mmode+math_style: tail_append(new_style(cur_chr));
-mmode+non_script: begin tail_append(new_glue(zero_glue));
- subtype(tail):=cond_math_glue;
- end;
-mmode+math_choice: if cur_chr=0 then append_choices else setup_math_style;
-
-@ @<Cases of |handle_right_brace|...@>=
-math_choice_group: build_choices;
-
-@ Here are two primives for explicit super- or subscript choice.
-
-@<Put each...@>=
-primitive_luatex("Usuperscript",super_sub_script,sup_mark,sup_mark);
-@!@:super_sub_script_}{\.{\\Usuperscript} primitive@>
-primitive_luatex("Usubscript",super_sub_script,sub_mark,sup_mark);
-@!@:super_sub_script_}{\.{\\Usubscript} primitive@>
-
-@ @<Cases of |main_control| that build...@>=
-mmode+sub_mark,mmode+sup_mark,mmode+super_sub_script: sub_sup;
-
-@
-@d above_code=0 { `\.{\\above}' }
-@d over_code=1 { `\.{\\over}' }
-@d atop_code=2 { `\.{\\atop}' }
-@d delimited_code=3 { `\.{\\abovewithdelims}', etc.}
-
-@<Put each...@>=
-primitive_tex("above",above,above_code,0);@/
-@!@:above_}{\.{\\above} primitive@>
-primitive_tex("over",above,over_code,0);@/
-@!@:over_}{\.{\\over} primitive@>
-primitive_tex("atop",above,atop_code,0);@/
-@!@:atop_}{\.{\\atop} primitive@>
-primitive_tex("abovewithdelims",above,delimited_code+above_code,0);@/
-@!@:above_with_delims_}{\.{\\abovewithdelims} primitive@>
-primitive_tex("overwithdelims",above,delimited_code+over_code,0);@/
-@!@:over_with_delims_}{\.{\\overwithdelims} primitive@>
-primitive_tex("atopwithdelims",above,delimited_code+atop_code,0);
-@!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@>
-
-@ @<Cases of |main_control| that build...@>=
-mmode+above: math_fraction;
-
-@ @<Cases of |handle...@>=
-math_group: close_math_group(p);
-
-@
-
-@<Put each...@>=
-primitive_tex("left",left_right,left_noad_side,0);
-@!@:left_}{\.{\\left} primitive@>
-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];
-
-@ @<Cases of |main_control| that build...@>=
-mmode+left_right: math_left_right;
-
-@ Here is the only way out of math mode.
-
-@<Cases of |main_control| that build...@>=
-mmode+math_shift,mmode+math_shift_cs: if cur_group=math_shift_group then after_math
- else off_save;
-
-
-@* \[49] Mode-independent processing.
-The long |main_control| procedure has now been fully specified, except for
-certain activities that are independent of the current mode. These activities
-do not change the current vlist or hlist or mlist; if they change anything,
-it is the value of a parameter or the meaning of a control sequence.
-
-Assignments to values in |eqtb| can be global or local. Furthermore, a
-control sequence can be defined to be `\.{\\long}', `\.{\\protected}',
-or `\.{\\outer}', and it might or might not be expanded. The prefixes
-`\.{\\global}', `\.{\\long}', `\.{\\protected}',
-and `\.{\\outer}' can occur in any order. Therefore we assign binary numeric
-codes, making it possible to accumulate the union of all specified prefixes
-by adding the corresponding codes. (\PASCAL's |set| operations could also
-have been used.)
-
-@<Put each...@>=
-primitive_tex("long",prefix,1,0);
-@!@:long_}{\.{\\long} primitive@>
-primitive_tex("outer",prefix,2,0);
-@!@:outer_}{\.{\\outer} primitive@>
-primitive_tex("global",prefix,4,0);
-@!@:global_}{\.{\\global} primitive@>
-primitive_tex("def",def,0,0);
-@!@:def_}{\.{\\def} primitive@>
-primitive_tex("gdef",def,1,0);
-@!@:gdef_}{\.{\\gdef} primitive@>
-primitive_tex("edef",def,2,0);
-@!@:edef_}{\.{\\edef} primitive@>
-primitive_tex("xdef",def,3,0);
-@!@:xdef_}{\.{\\xdef} primitive@>
-
-@ 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
-the command.
-
-@<Cases of |main_control| that don't...@>=
-any_mode(toks_register),
-any_mode(assign_toks),
-any_mode(assign_int),
-any_mode(assign_attr),
-any_mode(assign_dir),
-any_mode(assign_dimen),
-any_mode(assign_glue),
-any_mode(assign_mu_glue),
-any_mode(assign_font_dimen),
-any_mode(assign_font_int),
-any_mode(set_aux),
-any_mode(set_prev_graf),
-any_mode(set_page_dimen),
-any_mode(set_page_int),
-any_mode(set_box_dimen),
-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),
-any_mode(divide),
-any_mode(prefix),
-any_mode(let),
-any_mode(shorthand_def),
-any_mode(read_to_cs),
-any_mode(def),
-any_mode(set_box),
-any_mode(hyph_data),
-any_mode(set_interaction),
-any_mode(set_ocp),
-any_mode(def_ocp),
-any_mode(set_ocp_list),
-any_mode(def_ocp_list),
-any_mode(clear_ocp_lists),
-any_mode(push_ocp_list),
-any_mode(pop_ocp_list),
-any_mode(ocp_list_op),
-any_mode(ocp_trace_level) : prefixed_command;
-
-@ If the user says, e.g., `\.{\\global\\global}', the redundancy is
-silently accepted.
-
-@<Declare act...@>=
-@t\4@>@<Declare subprocedures for |prefixed_command|@>@t@>@;@/
-procedure prefixed_command;
-label done,exit;
-var a:small_number; {accumulated prefix codes so far}
-@!f:internal_font_number; {identifies a font}
-@!j:halfword; {index into a \.{\\parshape} specification}
-@!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;
- @<Get the next non-blank non-relax...@>;
- if cur_cmd<=max_non_prefixed_command then
- @<Discard erroneous prefixes and |return|@>;
- if tracing_commands>2 then show_cur_cmd_chr;
- end;
-@<Discard the prefixes \.{\\long} and \.{\\outer} if they are irrelevant@>;
-@<Adjust \(f)for the setting of \.{\\globaldefs}@>;
-case cur_cmd of
-@t\4@>@<Assignments@>@;
-othercases confusion("prefix")
-@:this can't happen prefix}{\quad prefix@>
-endcases;
-done: @<Insert a token saved by \.{\\afterassignment}, if any@>;
-exit:end;
-
-@ @<Discard erroneous...@>=
-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 or \protected.");
-back_error; return;
-end
-
-@ @<Discard the prefixes...@>=
-if a>=8 then
- begin j:=protected_token; a:=a-8;
- end
-else j:=0;
-if (cur_cmd<>def)and((a mod 4<>0)or(j<>0)) then
- begin print_err("You can't use `"); print_esc("long"); print("' or `");
- print_esc("outer"); print("' with `");
-@.You can't use \\long...@>
- print_cmd_chr(cur_cmd,cur_chr); print_char("'");
- help1("I'll pretend you didn't say \long or \outer here.");
- error;
- end
-
-@ The previous routine does not have to adjust |a| so that |a mod 4=0|,
-since the following routines test for the \.{\\global} prefix as follows.
-
-@d global==(a>=4)
-@d define(#)==begin if global then geq_define(#)@+else eq_define(#); end
-@d word_define(#)==begin if global then geq_word_define(#)@+else eq_word_define(#); end
-@d define_lc_code(#)==begin if global
- then set_lc_code(#,level_one)@+else set_lc_code(#,cur_level); end
-@d define_uc_code(#)==begin if global
- then set_uc_code(#,level_one)@+else set_uc_code(#,cur_level); end
-@d define_sf_code(#)==begin if global
- then set_sf_code(#,level_one)@+else set_sf_code(#,cur_level); end
-@d define_cat_code(#)==begin if global
- then set_cat_code(cat_code_table,#,level_one)@+else set_cat_code(cat_code_table,#,cur_level); end
-@d define_fam_fnt(#)==begin if global
- then def_fam_fnt(#,level_one)@+else def_fam_fnt(#,cur_level); end
-@d define_math_param(#)==begin if global
- then def_math_param(#,level_one)@+else def_math_param(#,cur_level); end
-
-
-@<Adjust \(f)for the setting of \.{\\globaldefs}@>=
-if global_defs<>0 then begin
- if global_defs<0 then
- begin if global then a:=a-4;
- end
- else begin if not global then a:=a+4;
- end;
- end
-
-@ When a control sequence is to be defined, by \.{\\def} or \.{\\let} or
-something similar, the |get_r_token| routine will substitute a special
-control sequence for a token that is not redefinable.
-
-@<Declare subprocedures for |prefixed_command|@>=
-procedure get_r_token;
-label restart;
-begin restart: repeat get_token;
-until cur_tok<>space_token;
-if (cur_cs=0)or(cur_cs>frozen_control_sequence) then
- begin print_err("Missing control sequence inserted");
-@.Missing control...@>
- help5("Please don't say `\def cs{...}', say `\def\cs{...}'.")@/
- ("I've inserted an inaccessible control sequence so that your")@/
- ("definition will be completed without mixing me up too badly.")@/
- ("You can recover graciously from this error, if you're")@/
- ("careful; see exercise 27.2 in The TeXbook.");
-@:TeXbook}{\sl The \TeX book@>
- if cur_cs=0 then back_input;
- cur_tok:=cs_token_flag+frozen_protection; ins_error; goto restart;
- end;
-end;
-
-@ @<Initialize table entries...@>=
-text(frozen_protection):="inaccessible";
-
-@ Assignments from Lua need helpers.
-
-@p function is_int_assign(cmd:halfword):boolean;
-begin
- is_int_assign := (cmd=assign_int);
-end;
-function is_dim_assign(cmd:halfword):boolean;
-begin
- is_dim_assign := (cmd=assign_dimen);
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure assign_internal_value(a:small_number;p:halfword;cur_val:integer);
-var n:halfword;
-begin
-if (p>=int_base)and(p<attribute_base) then begin
- 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=(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
- @<LOCAL: Add local paragraph node@>;
- 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<eqtb_size) then begin
- if p=(dimen_base+page_left_offset_code) then begin
- n:=cur_val - one_true_inch;
- word_define(dimen_base+h_offset_code, n);
- end
- else if p=(dimen_base+h_offset_code) then begin
- n:=cur_val + one_true_inch;
- word_define(dimen_base+page_left_offset_code, n);
- end
- else if p=(dimen_base+page_top_offset_code) then begin
- n:=cur_val - one_true_inch;
- word_define(dimen_base+v_offset_code, n);
- end
- else if p=(dimen_base+v_offset_code) then begin
- n:=cur_val + one_true_inch;
- word_define(dimen_base+page_top_offset_code, n);
- end;
- word_define(p,cur_val);
- end
-else
- confusion("assign internal value");
-end;
-
-
-@ Here's an example of the way many of the following routines operate.
-(Unfortunately, they aren't all as simple as this.)
-
-@<Assignments@>=
-set_font: define(cur_font_loc,data,cur_chr);
-
-@ When a |def| command has been scanned,
-|cur_chr| is odd if the definition is supposed to be global, and
-|cur_chr>=2| if the definition is supposed to be expanded.
-
-@<Assignments@>=
-def: begin if odd(cur_chr)and not global and(global_defs>=0) then a:=a+4;
- e:=(cur_chr>=2); get_r_token; p:=cur_cs;
- q:=scan_toks(true,e);
- if j<>0 then
- begin q:=get_avail; info(q):=j; link(q):=link(def_ref);
- link(def_ref):=q;
- end;
- define(p,call+(a mod 4),def_ref);
- end;
-
-@ Both \.{\\let} and \.{\\futurelet} share the command code |let|.
-
-@<Put each...@>=
-primitive_tex("let",let,normal,0);@/
-@!@:let_}{\.{\\let} primitive@>
-primitive_tex("futurelet",let,normal+1,0);@/
-@!@:future_let_}{\.{\\futurelet} primitive@>
-
-@ @<Assignments@>=
-let: begin n:=cur_chr;
- get_r_token; p:=cur_cs;
- if n=normal then
- begin repeat get_token;
- until cur_cmd<>spacer;
- if cur_tok=other_token+"=" then
- begin get_token;
- if cur_cmd=spacer then get_token;
- end;
- end
- else begin get_token; q:=cur_tok; get_token; back_input;
- cur_tok:=q; back_input; {look ahead, then back up}
- end; {note that |back_input| doesn't affect |cur_cmd|, |cur_chr|}
- if cur_cmd>=call then add_token_ref(cur_chr);
- define(p,cur_cmd,cur_chr);
- end;
-
-@ A \.{\\chardef} creates a control sequence whose |cmd| is |char_given|;
-a \.{\\mathchardef} creates a control sequence whose |cmd| is |math_given|;
-and the corresponding |chr| is the character code or math code. A \.{\\countdef}
-or \.{\\dimendef} or \.{\\skipdef} or \.{\\muskipdef} creates a control
-sequence whose |cmd| is |assign_int| or \dots\ or |assign_mu_glue|, and the
-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 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}}
-
-@<Put each...@>=
-primitive_tex("chardef",shorthand_def,char_def_code,0);@/
-@!@:char_def_}{\.{\\chardef} primitive@>
-primitive_tex("mathchardef",shorthand_def,math_char_def_code,0);@/
-@!@:math_char_def_}{\.{\\mathchardef} primitive@>
-primitive_omega("omathchardef",shorthand_def,omath_char_def_code,0);@/
-@!@:math_char_def_}{\.{\\omathchardef} primitive@>
-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_luatex("attributedef",shorthand_def,attribute_def_code,0);@/
-@!@:attribute_def_}{\.{\\attributedef} primitive@>
-primitive_tex("dimendef",shorthand_def,dimen_def_code,0);@/
-@!@:dimen_def_}{\.{\\dimendef} primitive@>
-primitive_tex("skipdef",shorthand_def,skip_def_code,0);@/
-@!@:skip_def_}{\.{\\skipdef} primitive@>
-primitive_tex("muskipdef",shorthand_def,mu_skip_def_code,0);@/
-@!@:mu_skip_def_}{\.{\\muskipdef} primitive@>
-primitive_tex("toksdef",shorthand_def,toks_def_code,0);@/
-@!@:toks_def_}{\.{\\toksdef} primitive@>
-
-@ 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
-previous meaning. This allows, for instance, `\.{\\chardef\\foo=123\\foo}'.
-
-@<Assignments@>=
-shorthand_def: begin n:=cur_chr; get_r_token; p:=cur_cs;
- define(p,relax,too_big_char); scan_optional_equals;
- case n of
- char_def_code: begin scan_char_num; define(p,char_given,cur_val);
- end;
- 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
- 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);
- attribute_def_code: define(p,assign_attr,attribute_base+cur_val);
- dimen_def_code: define(p,assign_dimen,scaled_base+cur_val);
- skip_def_code: define(p,assign_glue,skip_base+cur_val);
- mu_skip_def_code: define(p,assign_mu_glue,mu_skip_base+cur_val);
- toks_def_code: define(p,assign_toks,toks_base+cur_val);
- end; {there are no other cases}
- end
- endcases;
- end;
-
-@ @<Assignments@>=
-read_to_cs: begin j:=cur_chr; scan_int; n:=cur_val;
- if not scan_keyword('to') then
-@.to@>
- begin print_err("Missing `to' inserted");
-@.Missing `to'...@>
- help2("You should have said `\read<number> to \cs'.")@/
- ("I'm going to look for the \cs now."); error;
- end;
- get_r_token;
- p:=cur_cs; read_toks(n,p,j); define(p,call,cur_val);
- end;
-
-@ The token-list parameters, \.{\\output} and \.{\\everypar}, etc., receive
-their values in the following way. (For safety's sake, we place an
-enclosing pair of braces around an \.{\\output} list.)
-
-@<Assignments@>=
-toks_register,assign_toks: begin q:=cur_cs;
- if cur_cmd=toks_register then
- begin scan_register_num; p:=toks_base+cur_val;
- end
- else p:=cur_chr; {|p=every_par_loc| or |output_routine_loc| or \dots}
- scan_optional_equals;
- @<Get the next non-blank non-relax non-call token@>;
- if cur_cmd<>left_brace then @<If the right-hand side is a token parameter
- or token register, finish the assignment and |goto done|@>;
- back_input; cur_cs:=q; q:=scan_toks(false,false);
- if link(def_ref)=null then {empty list: revert to the default}
- begin define(p,undefined_cs,null); free_avail(def_ref);
- end
- else begin if p=output_routine_loc then {enclose in curlies}
- begin p:=get_avail; link(q):=p; p:=output_routine_loc;
- q:=link(q);info(q):=right_brace_token+"}";
- q:=get_avail;
- info(q):=left_brace_token+"{";
- link(q):=link(def_ref); link(def_ref):=q;
- end;
- define(p,call,def_ref);
- end;
- end;
-
-@ @<If the right-hand side is a token parameter...@>=
-begin if cur_cmd=toks_register then
- begin scan_register_num; cur_cmd:=assign_toks; cur_chr:=toks_base+cur_val;
- end;
-if cur_cmd=assign_toks then
- begin q:=equiv(cur_chr);
- if q=null then define(p,undefined_cs,null)
- else begin add_token_ref(q); define(p,call,q);
- end;
- goto done;
- end;
-end
-
-@ Similar routines are used to assign values to the numeric parameters.
-
-@<Assignments@>=
-assign_int: begin p:=cur_chr; scan_optional_equals; scan_int;
- 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;
- word_define(p,cur_val); end;
-assign_dir: begin
- @<DIR: Assign direction codes@>
- end;
-assign_dimen: begin p:=cur_chr; scan_optional_equals;
- 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);
- trap_zero_glue;
- define(p,glue_ref,cur_val);
- end;
-
-@ When a glue register or parameter becomes zero, it will always point to
-|zero_glue| because of the following procedure. (Exception: The tabskip
-glue isn't trapped while preambles are being scanned.)
-
-@<Declare subprocedures for |prefixed_command|@>=
-procedure trap_zero_glue;
-begin if (width(cur_val)=0)and(stretch(cur_val)=0)and(shrink(cur_val)=0) then
- begin add_glue_ref(zero_glue);
- delete_glue_ref(cur_val); cur_val:=zero_glue;
- end;
-end;
-
-@ The various character code tables are changed by the |def_code| commands,
-and the font families are declared by |def_family|.
-
-@<Put each...@>=
-primitive_tex("catcode",def_char_code,cat_code_base,cat_code_base);
-@!@:cat_code_}{\.{\\catcode} primitive@>
-primitive_tex("mathcode",def_char_code,math_code_base,cat_code_base);
-@!@:math_code_}{\.{\\mathcode} primitive@>
-primitive_tex("lccode",def_char_code,lc_code_base,cat_code_base);
-@!@:lc_code_}{\.{\\lccode} primitive@>
-primitive_tex("uccode",def_char_code,uc_code_base,cat_code_base);
-@!@:uc_code_}{\.{\\uccode} primitive@>
-primitive_tex("sfcode",def_char_code,sf_code_base,cat_code_base);
-@!@:sf_code_}{\.{\\sfcode} primitive@>
-primitive_tex("delcode",def_del_code,del_code_base,del_code_base);
-@!@:del_code_}{\.{\\delcode} primitive@>
-primitive_tex("textfont",def_family,text_size,0);
-@!@:text_font_}{\.{\\textfont} primitive@>
-primitive_tex("scriptfont",def_family,script_size,0);
-@!@:script_font_}{\.{\\scriptfont} primitive@>
-primitive_tex("scriptscriptfont",def_family,script_script_size,0);
-@!@:script_script_font_}{\.{\\scriptscriptfont} primitive@>
-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("Umathlimitbelowvgap", set_math_param, math_param_limit_below_vgap,0);
-primitive_luatex("Umathlimitbelowbgap", set_math_param, math_param_limit_below_bgap,0);
-primitive_luatex("Umathlimitbelowkern", 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_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@>
-
-
-@ The different types of code values have different legal ranges; the
-following program is careful to check each case properly.
-
-@d check_def_code(#)== if ((cur_val<0)and(p<#))or(cur_val>n) then
- begin print_err("Invalid code ("); print_int(cur_val);
- if p<# then print("), should be in the range 0..")
- else print("), should be at most ");
- print_int(n);
- help1("I'm going to use 0 instead of that illegal code value.");@/
- error; cur_val:=0;
- end
-@.Invalid code@>
-
-
-@<Assignments@>=
-def_char_code,def_del_code: begin
- @<Let |n| be the largest legal code value, based on |cur_chr|@>;
- p:=cur_chr;
- if cur_chr=math_code_base then begin
- 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;
- scan_optional_equals;
- scan_int;
- check_def_code(lc_code_base);
- define_lc_code(p,cur_val);
- end
- else if cur_chr=uc_code_base then begin
- scan_char_num; p:= cur_val;
- scan_optional_equals;
- scan_int;
- check_def_code(uc_code_base);
- define_uc_code(p,cur_val);
- end
- else if cur_chr=sf_code_base then begin
- scan_char_num; p:= cur_val;
- scan_optional_equals;
- scan_int;
- check_def_code(sf_code_base);
- define_sf_code(p,cur_val);
- end
- else if cur_chr=cat_code_base then begin
- scan_char_num; p:= cur_val;
- scan_optional_equals;
- scan_int;
- check_def_code(cat_code_base);
- define_cat_code(p,cur_val);
- end
- else if cur_chr=del_code_base then begin
- 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;
-
-
-@ @<Let |n| be the largest...@>=
-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=sf_code_base then n:=@'77777
-else n:=biggest_char
-
-@ @<Assignments@>=
-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<math_param_first_mu_glue then begin
- if p=math_param_radical_degree_raise then
- scan_int
- else
- scan_dimen(false, false, false);
- end
- else begin
- scan_glue(mu_val); trap_zero_glue;
- if cur_val=thin_mu_skip then cur_val:=thin_mu_skip_code
- else if cur_val=med_mu_skip then cur_val:=med_mu_skip_code
- else if cur_val=thick_mu_skip then cur_val:=thick_mu_skip_code
- end;
- define_math_param(p,cur_val1,cur_val);
- end;
-
-@ Next we consider changes to \TeX's numeric registers.
-
-@<Assignments@>=
-register,advance,multiply,divide: do_register_command(a);
-
-@ We use the fact that |register<advance<multiply<divide|.
-
-@<Declare subprocedures for |prefixed_command|@>=
-procedure do_register_command(@!a:small_number);
-label found,exit;
-var l,@!q,@!r,@!s:pointer; {for list manipulation}
-@!p:int_val..mu_val; {type of register involved}
-begin q:=cur_cmd;
-@<Compute the register location |l| and its type |p|; but |return| if invalid@>;
-if q=register then scan_optional_equals
-else if scan_keyword('by') then do_nothing; {optional `\.{by}'}
-@.by@>
-arith_error:=false;
-if q<multiply then @<Compute result of |register| or
- |advance|, put it in |cur_val|@>
-else @<Compute result of |multiply| or |divide|, put it in |cur_val|@>;
-if arith_error then
- begin print_err("Arithmetic overflow");
-@.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 p<glue_val then begin
- if p=attr_val then begin
- if (l-attribute_base)>max_used_attr then max_used_attr:=(l-attribute_base);
- attr_list_cache:=cache_disabled;
- end;
- 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
-|assign_int..assign_mu_glue| correspond to each other nicely.
-
-@<Compute the register location |l| and its type |p|...@>=
-begin l:=0;
-if q<>register then
- begin get_x_token;
- if (cur_cmd>=assign_int)and(cur_cmd<=assign_mu_glue) then
- begin l:=cur_chr; p:=cur_cmd-assign_int; goto found;
- end;
- if cur_cmd<>register then
- begin print_err("You can't use `"); print_cmd_chr(cur_cmd,cur_chr);
-@.You can't use x after ...@>
- print("' after "); print_cmd_chr(q,0);
- help1("I'm forgetting what you said and not changing anything.");
- error; return;
- end;
- end;
-p:=cur_chr; scan_register_num;
-case p of
-int_val: l:=cur_val+count_base;
-attr_val: l:=cur_val+attribute_base;
-dimen_val: l:=cur_val+scaled_base;
-glue_val: l:=cur_val+skip_base;
-mu_val: l:=cur_val+mu_skip_base;
-end; {there are no other cases}
-end;
-found:
-
-@ @<Compute result of |register| or |advance|...@>=
-if p<glue_val then
- begin if (p=int_val) or (p=attr_val) then scan_int@+else scan_normal_dimen;
- if q=advance then cur_val:=cur_val+eqtb[l].int;
- end
-else begin scan_glue(p);
- if q=advance then @<Compute the sum of two glue specs@>;
- end
-
-@ @<Compute the sum of two glue specs@>=
-begin q:=new_spec(cur_val); r:=equiv(l);
-delete_glue_ref(cur_val);
-width(q):=width(q)+width(r);
-if stretch(q)=0 then stretch_order(q):=normal;
-if stretch_order(q)=stretch_order(r) then stretch(q):=stretch(q)+stretch(r)
-else if (stretch_order(q)<stretch_order(r))and(stretch(r)<>0) then
- begin stretch(q):=stretch(r); stretch_order(q):=stretch_order(r);
- end;
-if shrink(q)=0 then shrink_order(q):=normal;
-if shrink_order(q)=shrink_order(r) then shrink(q):=shrink(q)+shrink(r)
-else if (shrink_order(q)<shrink_order(r))and(shrink(r)<>0) then
- begin shrink(q):=shrink(r); shrink_order(q):=shrink_order(r);
- end;
-cur_val:=q;
-end
-
-@ @<Compute result of |multiply| or |divide|...@>=
-begin scan_int;
-if p<glue_val then
- if q=multiply then
- if (p=int_val)or(p=attr_val) then cur_val:=mult_integers(eqtb[l].int,cur_val)
- else cur_val:=nx_plus_y(eqtb[l].int,cur_val,0)
- else cur_val:=x_over_n(eqtb[l].int,cur_val)
-else begin s:=equiv(l); r:=new_spec(s);
- if q=multiply then
- begin width(r):=nx_plus_y(width(s),cur_val,0);
- stretch(r):=nx_plus_y(stretch(s),cur_val,0);
- shrink(r):=nx_plus_y(shrink(s),cur_val,0);
- end
- else begin width(r):=x_over_n(width(s),cur_val);
- stretch(r):=x_over_n(stretch(s),cur_val);
- shrink(r):=x_over_n(shrink(s),cur_val);
- end;
- cur_val:=r;
- end;
-end
-
-@ The processing of boxes is somewhat different, because we may need
-to scan and create an entire box before we actually change the value of the old
-one.
-
-@<Assignments@>=
-set_box: begin scan_register_num;
- if global then n:=global_box_flag+cur_val@+else n:=box_flag+cur_val;
- scan_optional_equals;
- if set_box_allowed then scan_box(n)
- else begin print_err("Improper "); print_esc("setbox");
-@.Improper \\setbox@>
- help2("Sorry, \setbox is not allowed after \halign in a display,")@/
- ("or between \accent and an accented character."); error;
- end;
- end;
-
-@ The |space_factor| or |prev_depth| settings are changed when a |set_aux|
-command is sensed. Similarly, |prev_graf| is changed in the presence of
-|set_prev_graf|, and |dead_cycles| or |insert_penalties| in the presence of
-|set_page_int|. These definitions are always global.
-
-When some dimension of a box register is changed, the change isn't exactly
-global; but \TeX\ does not look at the \.{\\global} switch.
-
-@<Assignments@>=
-set_aux:alter_aux;
-set_prev_graf:alter_prev_graf;
-set_page_dimen:alter_page_so_far;
-set_page_int:alter_integer;
-set_box_dimen:alter_box_dimen;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure alter_aux;
-var c:halfword; {|hmode| or |vmode|}
-begin if cur_chr<>abs(mode) then report_illegal_case
-else begin c:=cur_chr; scan_optional_equals;
- if c=vmode then
- begin scan_normal_dimen; prev_depth:=cur_val;
- end
- else begin scan_int;
- if (cur_val<=0)or(cur_val>32767) then
- begin print_err("Bad space factor");
-@.Bad space factor@>
- help1("I allow only values in the range 1..32767 here.");
- int_error(cur_val);
- end
- else space_factor:=cur_val;
- end;
- end;
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure alter_prev_graf;
-var p:0..nest_size; {index into |nest|}
-begin nest[nest_ptr]:=cur_list; p:=nest_ptr;
-while abs(nest[p].mode_field)<>vmode do decr(p);
-scan_optional_equals; scan_int;
-if cur_val<0 then
- begin print_err("Bad "); print_esc("prevgraf");
-@.Bad \\prevgraf@>
- help1("I allow only nonnegative values here.");
- int_error(cur_val);
- end
-else begin nest[p].pg_field:=cur_val; cur_list:=nest[nest_ptr];
- end;
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure alter_page_so_far;
-var c:0..7; {index into |page_so_far|}
-begin c:=cur_chr; scan_optional_equals; scan_normal_dimen;
-page_so_far[c]:=cur_val;
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure alter_integer;
-var c:small_number;
- {0 for \.{\\deadcycles}, 1 for \.{\\insertpenalties}, etc.}
-begin c:=cur_chr; scan_optional_equals; scan_int;
-if c=0 then dead_cycles:=cur_val
-@/@<Cases for |alter_integer|@>@/
-else insert_penalties:=cur_val;
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure alter_box_dimen;
-var c:small_number; {|width_offset| or |height_offset| or |depth_offset|}
-@!b:eight_bits; {box number}
-begin c:=cur_chr; scan_register_num; b:=cur_val; scan_optional_equals;
-scan_normal_dimen;
-if box(b)<>null then vmem(box(b)+c).sc:=cur_val;
-end;
-
-@ Paragraph shapes are set up in an obvious way. It needs one word more than in
-\TeX, though.
-
-@<Assignments@>=
-set_tex_shape: begin q:=cur_chr; scan_optional_equals; scan_int; n:=cur_val;
- if n<=0 then p:=null
- 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}
- scan_normal_dimen;
- vmem(p+2*j+1).sc:=cur_val; {width}
- end;
- 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.
-
-@<Put each...@>=
-primitive_tex("hyphenation",hyph_data,0,0);
-@!@:hyphenation_}{\.{\\hyphenation} primitive@>
-primitive_tex("patterns",hyph_data,1,0);
-@!@:patterns_}{\.{\\patterns} primitive@>
-primitive_luatex("prehyphenchar",hyph_data,2,0);
-@!@:prehyphenchar_}{\.{\\prehyphenchar} primitive@>
-primitive_luatex("posthyphenchar",hyph_data,3,0);
-@!@:posthyphenchar_}{\.{\\posthyphenchar} primitive@>
-primitive_luatex("preexhyphenchar",hyph_data,4,0);
-@!@:preexhyphenchar_}{\.{\\preexhyphenchar} primitive@>
-primitive_luatex("postexhyphenchar",hyph_data,5,0);
-@!@:postexhyphenchar_}{\.{\\postexhyphenchar} primitive@>
-
-@ @<Assignments@>=
-hyph_data: begin
- case cur_chr of
- 0: new_hyph_exceptions;
- 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;
-
-@ All of \TeX's parameters are kept in |eqtb| except the font information,
-the interaction mode, and the hyphenation tables; these are strictly global.
-
-@<Assignments@>=
-assign_font_dimen: set_font_dimen;
-assign_font_int: begin
- n:=cur_chr; scan_font_ident; f:=cur_val;
- if n = no_lig_code then set_no_ligatures(f)
- else if n < lp_code_base then begin
- scan_optional_equals; scan_int;
- if n=0 then set_hyphen_char(f,cur_val)@+else set_skew_char(f,cur_val);
- end
- else begin
- scan_char_num; p := cur_val;
- scan_optional_equals; scan_int;
- case n of
- lp_code_base: set_lp_code(f, p, cur_val);
- rp_code_base: set_rp_code(f, p, cur_val);
- ef_code_base: set_ef_code(f, p, cur_val);
- tag_code: set_tag_code(f, p, cur_val);
- end;
- end;
-end;
-
-@ @<Put each...@>=
-primitive_tex("hyphenchar",assign_font_int,0,0);
-@!@:hyphen_char_}{\.{\\hyphenchar} primitive@>
-primitive_tex("skewchar",assign_font_int,1,0);
-@!@:skew_char_}{\.{\\skewchar} primitive@>
-primitive_pdftex("lpcode",assign_font_int,lp_code_base,0);
-@!@:lp_code_}{\.{\\lpcode} primitive@>
-primitive_pdftex("rpcode",assign_font_int,rp_code_base,0);
-@!@:rp_code_}{\.{\\rpcode} primitive@>
-primitive_pdftex("efcode",assign_font_int,ef_code_base,0);
-@!@:ef_code_}{\.{\\efcode} primitive@>
-primitive_pdftex("tagcode",assign_font_int,tag_code,0);
-@!@:tag_code_}{\.{\\tagcode} primitive@>
-primitive_pdftex("pdfnoligatures",assign_font_int,no_lig_code,0);
-@!@:no_lig_code_}{\.{\\pdfnoligatures} primitive@>
-
-@ Here is where the information for a new font gets loaded.
-
-@<Assignments@>=
-def_font: tex_def_font(a); {in C}
-letterspace_font: new_letterspaced_font(a);
-pdf_copy_font: make_font_copy(a);
-
-@ @<Put each...@>=
-primitive_tex("batchmode",set_interaction,batch_mode,0);
-@!@:batch_mode_}{\.{\\batchmode} primitive@>
-primitive_tex("nonstopmode",set_interaction,nonstop_mode,0);
-@!@:nonstop_mode_}{\.{\\nonstopmode} primitive@>
-primitive_tex("scrollmode",set_interaction,scroll_mode,0);
-@!@:scroll_mode_}{\.{\\scrollmode} primitive@>
-primitive_tex("errorstopmode",set_interaction,error_stop_mode,0);
-@!@:error_stop_mode_}{\.{\\errorstopmode} primitive@>
-
-@ @<Assignments@>=
-set_interaction: new_interaction;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure new_interaction;
-begin print_ln;
-interaction:=cur_chr;
-@<Initialize the print |selector| based on |interaction|@>;
-if log_opened then selector:=selector+2;
-end;
-
-@ The \.{\\afterassignment} command puts a token into the global
-variable |after_token|. This global variable is examined just after
-every assignment has been performed.
-
-@<Glob...@>=
-@!after_token:halfword; {zero, or a saved token}
-
-@ @<Set init...@>=
-after_token:=0;
-
-@ @<Cases of |main_control| that don't...@>=
-any_mode(after_assignment):begin get_token; after_token:=cur_tok;
- end;
-
-@ @<Insert a token saved by \.{\\afterassignment}, if any@>=
-if after_token<>0 then
- begin cur_tok:=after_token; back_input; after_token:=0;
- end
-
-@ Here is a procedure that might be called `Get the next non-blank non-relax
-non-call non-assignment token'.
-
-@<Declare act...@>=
-procedure do_assignments;
-label exit;
-begin loop begin @<Get the next non-blank non-relax...@>;
- if cur_cmd<=max_non_prefixed_command then return;
- set_box_allowed:=false; prefixed_command; set_box_allowed:=true;
- end;
-exit:end;
-
-@ @<Cases of |main_control| that don't...@>=
-any_mode(after_group):begin get_token; save_for_after(cur_tok);
- end;
-
-@ Files for \.{\\read} are opened and closed by the |in_stream| command.
-
-@<Put each...@>=
-primitive_tex("openin",in_stream,1,0);
-@!@:open_in_}{\.{\\openin} primitive@>
-primitive_tex("closein",in_stream,0,0);
-@!@:close_in_}{\.{\\closein} primitive@>
-
-@ @<Cases of |main_control| that don't...@>=
-any_mode(in_stream): open_or_close_in;
-
-@ @<Declare act...@>=
-procedure open_or_close_in;
-var c:0..1; {1 for \.{\\openin}, 0 for \.{\\closein}}
-@!n:0..15; {stream number}
-begin c:=cur_chr; scan_four_bit_int; n:=cur_val;
-if read_open[n]<>closed then
- begin lua_a_close_in(read_file[n],(n+1)); read_open[n]:=closed;
- end;
-if c<>0 then
- begin scan_optional_equals; scan_file_name;
- if cur_ext="" then cur_ext:=".tex";
- pack_cur_name;
- if lua_a_open_in(read_file[n],(n+1)) then begin
- read_file[n]:= name_file_pointer;
- read_open[n]:=just_open;
- end;
- end;
-end;
-
-@ The user can issue messages to the terminal, regardless of the
-current mode.
-
-@<Cases of |main_control| that don't...@>=
-any_mode(message):issue_message;
-
-@ @<Put each...@>=
-primitive_tex("message",message,0,0);
-@!@:message_}{\.{\\message} primitive@>
-primitive_tex("errmessage",message,1,0);
-@!@:err_message_}{\.{\\errmessage} primitive@>
-
-@ @<Declare act...@>=
-procedure issue_message;
-var old_setting:0..max_selector; {holds |selector| setting}
-junk:pointer;
-@!c:0..1; {identifies \.{\\message} and \.{\\errmessage}}
-@!s:str_number; {the message}
-begin c:=cur_chr; 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); s:=make_string;
-if c=0 then @<Print string |s| on the terminal@>
-else @<Print string |s| as an error message@>;
-flush_string;
-end;
-
-@ @<Print string |s| on the terminal@>=
-begin if term_offset+length(s)>max_print_line-2 then print_ln
-else if (term_offset>0)or(file_offset>0) then print_char(" ");
-slow_print(s); update_terminal;
-end
-
-@ If \.{\\errmessage} occurs often in |scroll_mode|, without user-defined
-\.{\\errhelp}, we don't want to give a long help message each time. So we
-give a verbose explanation only once.
-
-@<Glob...@>=
-@!long_help_seen:boolean; {has the long \.{\\errmessage} help been used?}
-
-@ @<Set init...@>=long_help_seen:=false;
-
-@ @<Print string |s| as an error message@>=
-begin print_err(""); slow_print(s);
-if err_help<>null then use_err_help:=true
-else if long_help_seen then help1("(That was another \errmessage.)")
-else begin if interaction<error_stop_mode then long_help_seen:=true;
- help4("This error message was generated by an \errmessage")@/
- ("command, so I can't give any explicit help.")@/
- ("Pretend that you're Hercule Poirot: Examine all clues,")@/
-@^Poirot, Hercule@>
- ("and deduce the truth by order and method.");
- end;
-error; use_err_help:=false;
-end
-
-@ The |error| routine calls on |give_err_help| if help is requested from
-the |err_help| parameter.
-
-@p procedure give_err_help;
-begin token_show(err_help);
-end;
-
-@ The \.{\\uppercase} and \.{\\lowercase} commands are implemented by
-building a token list and then changing the cases of the letters in it.
-
-@<Cases of |main_control| that don't...@>=
-any_mode(case_shift):shift_case;
-
-@ @<Put each...@>=
-primitive_tex("lowercase",case_shift,lc_code_base,lc_code_base);
-@!@:lowercase_}{\.{\\lowercase} primitive@>
-primitive_tex("uppercase",case_shift,uc_code_base,lc_code_base);
-@!@:uppercase_}{\.{\\uppercase} primitive@>
-
-@ @<Declare act...@>=
-procedure shift_case;
-var b:pointer; {|lc_code_base| or |uc_code_base|}
-@!p:pointer; {runs through the token list}
-@!t:halfword; {token}
-@!c:halfword; {character code}
-@!i:halfword; {inbetween}
-begin b:=cur_chr; p:=scan_toks(false,false); p:=link(def_ref);
-while p<>null do
- begin @<Change the case of the token in |p|, if a change is appropriate@>;
- p:=link(p);
- end;
-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.
-
-@<Change the case of the token in |p|, if a change is appropriate@>=
-t:=info(p);
-if t<cs_token_flag then begin
- c:=t mod string_offset;
- 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.
-
-@<Cases of |main_control| that don't...@>=
-any_mode(xray): show_whatever;
-
-@ @d show_code=0 { \.{\\show} }
-@d show_box_code=1 { \.{\\showbox} }
-@d show_the_code=2 { \.{\\showthe} }
-@d show_lists=3 { \.{\\showlists} }
-
-@<Put each...@>=
-primitive_tex("show",xray,show_code,0);
-@!@:show_}{\.{\\show} primitive@>
-primitive_tex("showbox",xray,show_box_code,0);
-@!@:show_box_}{\.{\\showbox} primitive@>
-primitive_tex("showthe",xray,show_the_code,0);
-@!@:show_the_}{\.{\\showthe} primitive@>
-primitive_tex("showlists",xray,show_lists,0);
-@!@:show_lists_}{\.{\\showlists} primitive@>
-
-@ @<Declare act...@>=
-procedure show_whatever;
-label common_ending;
-var p:pointer; {tail of a token list to show}
-@!t:small_number; {type of conditional being shown}
-@!m:normal..or_code; {upper bound on |fi_or_else| codes}
-@!l:integer; {line where that conditional began}
-@!n:integer; {level of \.{\\if...\\fi} nesting}
-begin case cur_chr of
-show_lists: begin begin_diagnostic; show_activities;
- end;
-show_box_code: @<Show the current contents of a box@>;
-show_code: @<Show the current meaning of a token, then |goto common_ending|@>;
-@<Cases for |show_whatever|@>@;@/
-othercases @<Show the current value of some parameter or register,
- then |goto common_ending|@>
-endcases;@/
-@<Complete a potentially long \.{\\show} command@>;
-common_ending: if interaction<error_stop_mode then
- begin help0; decr(error_count);
- end
-else if tracing_online>0 then
- begin@t@>@;@/
- help3("This isn't an error message; I'm just \showing something.")@/
- ("Type `I\show...' to show more (e.g., \show\cs,")@/
- ("\showthe\count10, \showbox255, \showlists).");
- end
-else begin@t@>@;@/
- help5("This isn't an error message; I'm just \showing something.")@/
- ("Type `I\show...' to show more (e.g., \show\cs,")@/
- ("\showthe\count10, \showbox255, \showlists).")@/
- ("And type `I\tracingonline=1\show...' to show boxes and")@/
- ("lists on your terminal as well as in the transcript file.");
- end;
-error;
-end;
-
-@ @<Show the current meaning of a token...@>=
-begin get_token;
-if interaction=error_stop_mode then wake_up_terminal;
-print_nl("> ");
-if cur_cs<>0 then
- begin sprint_cs(cur_cs); print_char("=");
- end;
-print_meaning; goto common_ending;
-end
-
-@ @<Show the current contents of a box@>=
-begin scan_register_num; begin_diagnostic;
-print_nl("> \box"); print_int(cur_val); print_char("=");
-if box(cur_val)=null then print("void")
-else show_box(box(cur_val));
-end
-
-@ @<Show the current value of some parameter...@>=
-begin p:=the_toks;
-if interaction=error_stop_mode then wake_up_terminal;
-print_nl("> "); token_show(temp_token_head);
-flush_list(link(temp_token_head)); goto common_ending;
-end
-
-@ @<Complete a potentially long \.{\\show} command@>=
-end_diagnostic(true); print_err("OK");
-@.OK@>
-if selector=term_and_log then if tracing_online<=0 then
- begin selector:=term_only; print(" (see the transcript file)");
- selector:=term_and_log;
- end
-
-@* \[50] Dumping and undumping the tables.
-After \.{INITEX} has seen a collection of fonts and macros, it
-can write all the necessary information on an auxiliary file so
-that production versions of \TeX\ are able to initialize their
-memory at high speed. The present section of the program takes
-care of such output and input. We shall consider simultaneously
-the processes of storing and restoring,
-so that the inverse relation between them is clear.
-@.INITEX@>
-
-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 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.
-
-@<Glob...@>=
-@!format_ident:str_number;
-@!format_name:str_number; {principal file name}
-
-@ @<Set init...@>=
-format_ident:=0;
-format_name:="";
-
-@ @<Initialize table entries...@>=
-format_ident:=" (INITEX)";
-
-@ @<Declare act...@>=
-@!init procedure store_fmt_file;
-label found1,found2,done1,done2;
-var j,@!k,@!l:integer; {all-purpose indices}
-@!p: pointer; {all-purpose pointer}
-@!x: integer; {something to dump}
-@!w: four_quarters; {four ASCII codes}
-begin @<If dumping is not allowed, abort@>;
-@<Create the |format_ident|, open the format file,
- and inform the user that dumping has begun@>;
-@<Dump constants for consistency check@>;
-@<Dump the string pool@>;
-@<Dump the dynamic memory@>;
-@<Dump the table of equivalents@>;
-@<Dump the font information@>;
-@<Dump the active ocp information@>;
-@<Dump the ocp information@>;
-@<Dump the ocp list information@>;
-@<Dump the hyphenation tables@>;
-@<Dump pdftex data@>;
-@<Dump a couple more things and the closing check word@>;
-@<Dump the lua bytecodes@>;
-@<Close the format file@>;
-end;
-tini
-
-@ Corresponding to the procedure that dumps a format file, we have a function
-that reads one in. The function returns |false| if the dumped format is
-incompatible with the present \TeX\ table sizes, etc.
-
-@d bad_fmt=6666 {go here if the format file is unacceptable}
-@d too_small(#)==begin wake_up_terminal;
- wterm_ln('---! Must increase the ',#);
-@.Must increase the x@>
- goto bad_fmt;
- end
-
-@p @t\4@>@<Declare the function called |open_fmt_file|@>@;
-function load_fmt_file:boolean;
-label bad_fmt,exit;
-var j,@!k:integer; {all-purpose indices}
-@!p: pointer; {all-purpose pointer}
-@!x: integer; {something undumped}
-@!w: four_quarters; {four ASCII codes}
-begin @<Undump constants for consistency check@>;
-@<Undump the string pool@>;
-@<Undump the dynamic memory@>;
-@<Undump the table of equivalents@>;
-@<Undump the font information@>;
-@<Undump the active ocp information@>;
-@<Undump the ocp information@>;
-@<Undump the ocp list information@>;
-@<Undump the hyphenation tables@>;
-@<Undump pdftex data@>;
-@<Undump a couple more things and the closing check word@>;
-@<Undump the lua bytecodes@>;
-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)');
-@.Fatal format file error@>
-load_fmt_file:=false;
-exit:end;
-
-@ The user is not allowed to dump a format file unless |save_ptr=0|.
-This condition implies that |cur_level=level_one|, hence
-the |xeq_level| array is constant and it need not be dumped.
-
-@<If dumping is not allowed, abort@>=
-if save_ptr<>0 then
- begin print_err("You can't dump inside a group");
-@.You can't dump...@>
- help1("`{...\dump}' is a no-no."); succumb;
- end
-
-@ Format files consist of |memory_word| items, and we use the following
-macros to dump words of different types:
-
-@d dump_wd(#)==begin fmt_file^:=#; put(fmt_file);@+end
-@d dump_int(#)==begin fmt_file^.int:=#; put(fmt_file);@+end
-@d dump_hh(#)==begin fmt_file^.hh:=#; put(fmt_file);@+end
-@d dump_qqqq(#)==begin fmt_file^.qqqq:=#; put(fmt_file);@+end
-
-@<Glob...@>=
-@!fmt_file:word_file; {for input or output of format information}
-
-@ 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 undump_wd(#)==begin get(fmt_file); #:=fmt_file^;@+end
-@d undump_int(#)==begin get(fmt_file); #:=fmt_file^.int;@+end
-@d undump_hh(#)==begin get(fmt_file); #:=fmt_file^.hh;@+end
-@d undump_qqqq(#)==begin get(fmt_file); #:=fmt_file^.qqqq;@+end
-@d undump_end_end(#)==#:=x;@+end
-@d undump_end(#)==(x>#) then goto bad_fmt@+else undump_end_end
-@d undump(#)==begin undump_int(x); if (x<#) or undump_end
-@d undump_size_end_end(#)==too_small(#)@+else undump_end_end
-@d undump_size_end(#)==if x># then undump_size_end_end
-@d undump_size(#)==begin undump_int(x);
- if x<# then goto bad_fmt; undump_size_end
-
-@ The next few sections of the program should make it clear how we use the
-dump/undump macros.
-
-@<Dump constants for consistency check@>=
-dump_int(@$);@/
-dump_int(eqtb_size);@/
-dump_int(hash_prime)
-
-@ Sections of a \.{WEB} program that are ``commented out'' still contribute
-strings to the string pool; therefore \.{INITEX} and \TeX\ will have
-the same strings. (And it is, of course, a good thing that they do.)
-@.WEB@>
-@^string pool@>
-
-@<Undump constants for consistency check@>=
-x:=fmt_file^.int;
-if x<>@$ then goto bad_fmt; {check that strings are the same}
-undump_int(x);@/
-if x<>eqtb_size then goto bad_fmt;
-undump_int(x);
-if x<>hash_prime then goto bad_fmt
-
-@ @d dump_four_ASCII==
- w.b0:=qi(so(str_pool[k])); w.b1:=qi(so(str_pool[k+1]));
- w.b2:=qi(so(str_pool[k+2])); w.b3:=qi(so(str_pool[k+3]));
- dump_qqqq(w)
-
-@<Dump the string pool@>=
-dump_int(pool_ptr);
-dump_int(str_ptr);
-for k:=string_offset to str_ptr do dump_int(str_start_macro(k));
-k:=0;
-while k+4<pool_ptr do
- begin dump_four_ASCII; k:=k+4;
- end;
-k:=pool_ptr-4; dump_four_ASCII;
-print_ln; print_int(str_ptr-string_offset); print(" strings of total length ");
-print_int(pool_ptr)
-
-@ @d undump_four_ASCII==
- undump_qqqq(w);
- str_pool[k]:=si(qo(w.b0)); str_pool[k+1]:=si(qo(w.b1));
- str_pool[k+2]:=si(qo(w.b2)); str_pool[k+3]:=si(qo(w.b3))
-
-@<Undump the string pool@>=
-undump_size(0)(pool_size)('string pool size')(pool_ptr);
-undump_size(0)(max_strings)('max strings')(str_ptr);
-for k:=string_offset to str_ptr do undump(0)(pool_ptr)(str_start_macro(k));
-k:=0;
-while k+4<pool_ptr do
- begin undump_four_ASCII; k:=k+4;
- end;
-k:=pool_ptr-4; undump_four_ASCII;
-init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr
-
-@ 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 \.{INITEX} dumps valid
-information even when it has not been gathering statistics.
-
-@<Dump the dynamic memory@>=
-dump_node_mem;
-@#
-dump_int(temp_token_head); dump_int(hold_token_head);
-dump_int(omit_template); dump_int(null_list);
-dump_int(backup_head); dump_int(garbage);
-dump_int(fix_mem_min); dump_int(fix_mem_max);
-dump_int(fix_mem_end);
-dump_int(avail);
-dyn_used:=fix_mem_end+1;
-for k:=fix_mem_min to fix_mem_end do dump_wd(mem(k));
-x:=x+(fix_mem_end+1-fix_mem_min);
-p:=avail;
-while p<>null do
- begin decr(dyn_used); p:=link(p);
- end;
-dump_int(dyn_used);
-print_ln; print_int(x);
-print(" memory locations dumped; current usage is ");
-print_int(var_used); print_char("&"); print_int(dyn_used)
-
-@ @<Undump the dynamic memory@>=
-undump_node_mem;
-@#
-undump_int(temp_token_head); undump_int(hold_token_head);
-undump_int(omit_template); undump_int(null_list);
-undump_int(backup_head); undump_int(garbage);
-undump_int(fix_mem_min);undump_int(fix_mem_max);
-fixmem:= xmallocarray (smemory_word, fix_mem_max+1);
-memset (voidcast(fixmem),0,(fix_mem_max+1)*sizeof(smemory_word));
-undump_int(fix_mem_end);
-undump_int(avail);
-for k:=fix_mem_min to fix_mem_end do undump_wd(mem(k));
-undump_int(dyn_used)
-
-@ @<Dump the table of equivalents@>=
-@<Dump regions 1 to 4 of |eqtb|@>;
-@<Dump regions 5 and 6 of |eqtb|@>;
-dump_int(par_loc); dump_int(write_loc);@/
-dump_math_codes;
-dump_text_codes;
-@<Dump the hash table@>
-
-@ @<Undump the table of equivalents@>=
-@<Undump regions 1 to 6 of |eqtb|@>;
-undump(hash_base)(frozen_control_sequence)(par_loc);
-par_token:=cs_token_flag+par_loc;@/
-undump(hash_base)(frozen_control_sequence)(write_loc);@/
-undump_math_codes;
-undump_text_codes;
-@<Undump the hash table@>
-
-@ The table of equivalents usually contains repeated information, so we dump it
-in compressed form: The sequence of $n+2$ values $(n,x_1,\ldots,x_n,m)$ in the
-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)$.
-
-@<Dump regions 1 to 4 of |eqtb|@>=
-k:=null_cs;
-repeat j:=k;
-while j<int_base-1 do
- begin if (equiv(j)=equiv(j+1))and(eq_type(j)=eq_type(j+1))and@|
- (eq_level(j)=eq_level(j+1)) then goto found1;
- incr(j);
- end;
-l:=int_base; goto done1; {|j=int_base-1|}
-found1: incr(j); l:=j;
-while j<int_base-1 do
- begin if (equiv(j)<>equiv(j+1))or(eq_type(j)<>eq_type(j+1))or@|
- (eq_level(j)<>eq_level(j+1)) then goto done1;
- incr(j);
- end;
-done1:
-dump_int(l-k);
-while k<l do
- begin dump_wd(eqtb[k]); incr(k);
- end;
-k:=j+1; dump_int(k-l);
-until k=int_base
-
-@ @<Dump regions 5 and 6 of |eqtb|@>=
-repeat j:=k;
-while j<eqtb_size do
- begin if eqtb[j].int=eqtb[j+1].int then goto found2;
- incr(j);
- end;
-l:=eqtb_size+1; goto done2; {|j=eqtb_size|}
-found2: incr(j); l:=j;
-while j<eqtb_size do
- begin if eqtb[j].int<>eqtb[j+1].int then goto done2;
- incr(j);
- end;
-done2:dump_int(l-k);
-while k<l do
- begin dump_wd(eqtb[k]); incr(k);
- end;
-k:=j+1; dump_int(k-l);
-until k>eqtb_size
-
-@ @<Undump regions 1 to 6 of |eqtb|@>=
-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]);
-k:=k+x;
-undump_int(x);
-if (x<0)or(k+x>eqtb_size+1) then goto bad_fmt;
-for j:=k to k+x-1 do eqtb[j]:=eqtb[k-1];
-k:=k+x;
-until k>eqtb_size
-
-@ 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
-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.
-
-@<Dump the hash table@>=
-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);
- end;
-for p:=hash_used+1 to undefined_control_sequence-1 do dump_hh(hash[p]);
-dump_int(cs_count);@/
-print_ln; print_int(cs_count); print(" multiletter control sequences")
-
-@ @<Undump the hash table@>=
-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;
-for p:=hash_used+1 to undefined_control_sequence-1 do undump_hh(hash[p]);
-undump_int(cs_count)
-
-@ @<Dump the font information@>=
-dump_int(max_font_id);
-for k:=0 to max_font_id do
- @<Dump the array info for internal font number |k|@>;
-print_ln; print_int(max_font_id); print(" preloaded font");
-if max_font_id<>1 then print_char("s");
-dump_math_data
-
-@ @<Undump the font information@>=
-undump_int(x);
-set_max_font_id(x);
-for k:=0 to max_font_id do
- @<Undump the array info for internal font number |k|@>;
-undump_math_data
-
-@ @<Dump the array info for internal font number |k|@>=
-begin dump_font(k);
-print_nl("\font"); print_esc(font_id_text(k)); print_char("=");
-print_file_name(tex_font_name(k),tex_font_area(k),"");
-flush_string; flush_string;
-if font_size(k)<>font_dsize(k) then
- begin print(" at "); print_scaled(font_size(k)); print("pt");
- end;
-end
-
-@ @<Undump the array info for internal font number |k|@>=
-begin undump_font(k);@/
-end
-
-@ @<Dump the active ocp information@>=
-dump_int(active_min_ptr);
-dump_int(active_max_ptr);
-for k:=0 to active_max_ptr-1 do dump_wd(active_info[k]);
-if active_max_ptr>0 then begin
- print_ln; print_int(active_max_ptr); print(" words of active ocps");
- end;
-
-@ @<Undump the active ocp information@>=
-undump_size(0)(active_mem_size)('active start point')(active_min_ptr);
-undump_size(0)(active_mem_size)('active mem size')(active_max_ptr);
-for k:=0 to active_max_ptr-1 do undump_wd(active_info[k]);
-
-@ @<Dump the ocp information@>=
-dump_int(ocp_ptr);
-for k:=null_ocp to ocp_ptr do
- @<Dump the array info for internal ocp number |k|@>;
-if ocp_ptr-ocp_base>0 then begin
- print_ln; print_int(ocp_ptr-ocp_base); print(" preloaded ocp");
- if ocp_ptr<>ocp_base+1 then print_char("s");
- end
-
-@ @<Undump the ocp information@>=
-undump_size(ocp_base)(ocp_biggest)('ocp max')(ocp_ptr);
-for k:=null_ocp to ocp_ptr do
- @<Undump the array info for internal ocp number |k|@>
-
-@ @<Dump the array info for internal ocp number |k|@>=
-begin dump_ocp_table(k);
-if ocp_ptr-ocp_base>0 then begin
- print_nl("\ocp"); print_esc(ocp_id_text(k)); print_char("=");
- print_file_name(ocp_name(k),ocp_area(k),"");
- end;
-end
-
-@ @<Undump the array info for internal ocp number |k|@>=
-begin undump_ocp_table(k);
-end
-
-@ @<Dump the ocp list information@>=
-dump_int(ocp_listmem_ptr);
-for k:=0 to ocp_listmem_ptr-1 do dump_wd(ocp_list_info[k]);
-dump_int(ocp_list_ptr);
-for k:=null_ocp_list to ocp_list_ptr do begin
- dump_int(ocp_list_list[k]);
- if null_ocp_list<>ocp_list_ptr then begin
- print_nl("\ocplist");
- print_esc(ocp_list_id_text(k));
- print_char("=");
- print_ocp_list(ocp_list_list[k]);
- end;
- end;
-dump_int(ocp_lstackmem_ptr);
-for k:=0 to ocp_lstackmem_ptr-1 do dump_wd(ocp_lstack_info[k])
-
-@ @<Undump the ocp list information@>=
-undump_size(1)(1000000)('ocp list mem size')(ocp_listmem_ptr);
-for k:=0 to ocp_listmem_ptr-1 do undump_wd(ocp_list_info[k]);
-undump_size(ocp_list_base)(ocp_list_biggest)('ocp list max')(ocp_list_ptr);
-for k:=null_ocp_list to ocp_list_ptr do
- undump_int(ocp_list_list[k]);
-undump_size(1)(1000000)('ocp lstack mem size')(ocp_lstackmem_ptr);
-for k:=0 to ocp_lstackmem_ptr-1 do undump_wd(ocp_lstack_info[k])
-
-@ This is done in C
-
-@<Dump the hyphenation tables@>=
-dump_language_data
-
-@ @<Undump the hyphenation tables@>=
-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.
-
-@<Dump pdftex data@>=
-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.
-
-@<Undump pdftex data@>=
-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
-
-@<Dump the lua bytecodes@>=
-dump_luac_registers;
-
-@ @<Undump the lua bytecodes@>=
-undump_luac_registers;
-
-@ We have already printed a lot of statistics, so we set |tracing_stats:=0|
-to prevent them from appearing again.
-
-@<Dump a couple more things and the closing check word@>=
-dump_int(interaction); dump_int(format_ident); dump_int(format_name); dump_int(69069);
-tracing_stats:=0
-
-@ @<Undump a couple more things and the closing check word@>=
-undump(batch_mode)(error_stop_mode)(interaction);
-undump(0)(str_ptr)(format_ident);
-undump(0)(str_ptr)(format_name);
-undump_int(x);
-if (x<>69069)or eof(fmt_file) then goto bad_fmt
-
-@ @<Create the |format_ident|...@>=
-selector:=new_string;
-print(" (preloaded format="); print(job_name); print_char(" ");
-print_int(year); print_char(".");
-print_int(month); print_char("."); print_int(day); print_char(")");
-str_room(2);
-format_ident:=make_string;
-print(job_name);
-format_name:=make_string;
-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);
-print_nl("Beginning to dump on file ");
-@.Beginning to dump...@>
-slow_print(w_make_name_string(fmt_file)); flush_string;
-print_nl(""); slow_print(format_ident)
-
-@ @<Close the format file@>=
-w_close(fmt_file)
-
-@* \[51] The main program.
-This is it: the part of \TeX\ that executes all those procedures we have
-written.
-
-Well---almost. Let's leave space for a few more routines that we may
-have forgotten.
-
-@p @<Last-minute procedures@>
-
-@ We have noted that there are two versions of \TeX82. One, called \.{INITEX},
-@.INITEX@>
-has to be run first; it initializes everything from scratch, without
-reading a format file, and it has the capability of dumping a format file.
-The other one is called `\.{VIRTEX}'; it is a ``virgin'' program that needs
-@.VIRTEX@>
-to input a format file in order to get started. \.{VIRTEX} typically has
-more memory capacity than \.{INITEX}, because it does not need the space
-consumed by the auxiliary hyphenation tables and the numerous calls on
-|primitive|, etc.
-
-The \.{VIRTEX} program cannot read a format file instantaneously, of course;
-the best implementations therefore allow for production versions of \TeX\ that
-not only avoid the loading routine for \PASCAL\ object code, they also have
-a format file pre-loaded. This is impossible to do if we stick to standard
-\PASCAL; but there is a simple way to fool many systems into avoiding the
-initialization, as follows:\quad(1)~We declare a global integer variable
-called |ready_already|. The probability is negligible that this
-variable holds any particular value like 314159 when \.{VIRTEX} is first
-loaded.\quad(2)~After we have read in a format file and initialized
-everything, we set |ready_already:=314159|.\quad(3)~Soon \.{VIRTEX}
-will print `\.*', waiting for more input; and at this point we
-interrupt the program and save its core image in some form that the
-operating system can reload speedily.\quad(4)~When that core image is
-activated, the program starts again at the beginning; but now
-|ready_already=314159| and all the other global variables have
-their initial values too. The former chastity has vanished!
-
-In other words, if we allow ourselves to test the condition
-|ready_already=314159|, before |ready_already| has been
-assigned a value, we can avoid the lengthy initialization. Dirty tricks
-rarely pay off so handsomely.
-@^dirty \PASCAL@>
-@^system dependencies@>
-
-On systems that allow such preloading, the standard program called \.{TeX}
-should be the one that has \.{plain} format preloaded, since that agrees
-with {\sl The \TeX book}. Other versions, e.g., \.{AmSTeX}, should also
-@:TeXbook}{\sl The \TeX book@>
-@.AmSTeX@>
-@.plain@>
-be provided for commonly used formats.
-
-@<Glob...@>=
-@!ready_already:integer; {a sacrifice of purity for economy}
-
-@ Now this is really it: \TeX\ starts and ends here.
-
-The initial test involving |ready_already| should be deleted if the
-\PASCAL\ runtime system is smart enough to detect such a ``mistake.''
-@^system dependencies@>
-
-@p begin @!{|start_here|}
-history:=fatal_error_stop; {in case we quit during initialization}
-t_open_out; {open the terminal for output}
-if ready_already=314159 then goto start_of_TEX;
-@<Check the ``constant'' values...@>@;
-if bad>0 then
- begin wterm_ln('Ouch---my internal constants have been clobbered!',
- '---case ',bad:1);
-@.Ouch...clobbered@>
- goto final_end;
- end;
-initialize; {set global variables to their starting values}
-@!init if not get_strings_started then goto final_end;
-init_prim; {call |primitive| for each primitive}
-init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr; fix_date_and_time;
-tini@/
-ready_already:=314159;
-start_of_TEX: @<Initialize the output routines@>;
-@<Get the first line of input and prepare to start@>;
-history:=spotless; {ready to go!}
-@<Initialize synctex primitive@>
-main_control; {come to life}
-final_cleanup; {prepare for death}
-end_of_TEX: close_files_and_terminate;
-final_end: ready_already:=0;
-end.
-
-@ Put this in a function because two extra variables are needed
-for callback testing, and putting those inside the main body is
-ugly
-
-@<Basic print...@>=
-procedure print_banner;
-var res:boolean;
- callback_id:integer;
-begin
-callback_id:=callback_defined(start_run_callback);
-if callback_id=0 then begin
- wterm(banner);
- if format_ident=0 then wterm_ln(' (no format preloaded)')
- else begin slow_print(format_ident); print_ln;
- end;
- end
-else if callback_id>0 then
- res:= run_callback(callback_id,'->');
-update_terminal;
-end;
-@#
-procedure print_version_banner;
-begin
-wterm(banner);
-write_svnversion(luatex_svnversion);
-end;
-
-
-@ Here we do whatever is needed to complete \TeX's job gracefully on the
-local operating system. The code here might come into play after a fatal
-error; it must therefore consist entirely of ``safe'' operations that
-cannot produce error messages. For example, it would be a mistake to call
-|str_room| or |make_string| at this time, because a call on |overflow|
-might lead to an infinite loop.
-@^system dependencies@>
-
-Actually there's one way to get error messages, via |prepare_mag|;
-but that can't cause infinite recursion.
-@^recursion@>
-
-This program doesn't bother to close the input files that may still be open.
-
-@<Last-minute...@>=
-procedure close_files_and_terminate;
-label done, done1;
-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;
-begin
-callback_id:=callback_defined(stop_run_callback);
-@<Finish the extensions@>;
-@!stat if tracing_stats>0 then
- if callback_id=0 then @<Output statistics about this job@>;@;@+tats@/
-wake_up_terminal;
-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
- else begin
- @<Finish the PDF file@>;
- 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;
- end;
- end;
-end
-else begin
- @<Finish the \.{DVI} file@>;
-end;
-@<Close {\sl Sync\TeX} file and write status@>;
-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
- print_nl("Transcript written on ");
-@.Transcript written...@>
- slow_print(log_name); print_char(".");
- end;
- lua_a_close_out(log_file);
- end;
-end;
-
-@ The present section goes directly to the log file instead of using
-|print| commands, because there's no need for these strings to take
-up |str_pool| memory when a non-{\bf stat} version of \TeX\ is being used.
-
-@<Output statistics...@>=
-if log_opened then
- begin wlog_ln(' ');
- wlog_ln('Here is how much of TeX''s memory',' you used:');
-@.Here is how much...@>
- wlog(' ',str_ptr-init_str_ptr:1,' string');
- if str_ptr<>init_str_ptr+1 then wlog('s');
- wlog_ln(' out of ', max_strings-init_str_ptr+string_offset:1);@/
- wlog_ln(' ',pool_ptr-init_pool_ptr:1,' string characters out of ',
- pool_size-init_pool_ptr:1);@/
- wlog_ln(' ',var_mem_max:1,',',fix_mem_max:1,@|
- ' words of node,token memory allocated');@/
- print_node_mem_stats;
- wlog_ln(' ',cs_count:1,' multiletter control sequences out of ',
- hash_size:1);@/
- wlog(' ',max_font_id,' font');
- if max_font_id<>1 then wlog('s');
- wlog_ln(' using ', font_bytes:1, ' bytes');
- wlog_ln(' ',max_in_stack:1,'i,',max_nest_stack:1,'n,',@|
- max_param_stack:1,'p,',@|
- max_buf_stack+1:1,'b,',@|
- max_save_stack+6:1,'s stack positions out of ',@|
- stack_size:1,'i,',
- nest_size:1,'n,',
- param_size:1,'p,',
- buf_size:1,'b,',
- save_size:1,'s');
- end
-
-@ We get to the |final_cleanup| routine when \.{\\end} or \.{\\dump} has
-been scanned and |its_all_over|\kern-2pt.
-
-@<Last-minute...@>=
-procedure final_cleanup;
-label exit;
-var c:small_number; {0 for \.{\\end}, 1 for \.{\\dump}}
-i:halfword; { for looping marks }
-begin c:=cur_chr;
-if job_name=0 then open_log_file;
-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);
- end;
-if cur_level>level_one then
- begin print_nl("("); print_esc("end occurred ");
- print("inside a group at level ");
-@:end_}{\.{(\\end occurred...)}@>
- print_int(cur_level-level_one); print_char(")");
- show_save_groups;
- end;
-while cond_ptr<>null do
- begin print_nl("("); print_esc("end occurred ");
- print("when "); print_cmd_chr(if_test,cur_if);
- if if_line<>0 then
- begin print(" on line "); print_int(if_line);
- end;
- print(" was incomplete)");
- if_line:=if_line_field(cond_ptr);
- cur_if:=subtype(cond_ptr); temp_ptr:=cond_ptr;
- cond_ptr:=vlink(cond_ptr); flush_node(temp_ptr);
- end;
-if callback_defined(stop_run_callback)=0 then
- if history<>spotless then
- if ((history=warning_issued)or(interaction<error_stop_mode)) then
- if selector=term_and_log then
- begin selector:=term_only;
- print_nl("(see the transcript file for additional information)");
-@.see the transcript file...@>
- selector:=term_and_log;
- end;
-if c=1 then
- begin @!init for i:=0 to biggest_used_mark do begin
- delete_top_mark(i); delete_first_mark(i); delete_bot_mark(i);
- 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);
- @<Close the pseudo files@>;
- store_fmt_file; return;@+tini@/
- print_nl("(\dump is performed only by INITEX)"); return;
-@:dump_}{\.{\\dump...only by INITEX}@>
- end;
-exit:end;
-
-@ @<Last-minute...@>=
-@!init procedure init_prim; {initialize all the primitives}
-begin no_new_control_sequence:=false;
-first:=0;
-@<Put each...@>;
-no_new_control_sequence:=true;
-end;
-tini
-
-@ When we begin the following code, \TeX's tables may still contain garbage;
-the strings might not even be present. Thus we must proceed cautiously to get
-bootstrapped in.
-
-But when we finish this part of the program, \TeX\ is ready to call on the
-|main_control| routine to do its work.
-
-@<Get the first line...@>=
-begin @<Initialize the input routines@>;
-@<Enable \eTeX, if requested@>@;@/
-if (format_ident=0)or(buffer[loc]="&") then
- begin if format_ident<>0 then initialize; {erase preloaded format}
- if not open_fmt_file then goto final_end;
- if not load_fmt_file then
- begin w_close(fmt_file); goto final_end;
- end;
- w_close(fmt_file);
- while (loc<limit)and(buffer[loc]=" ") do incr(loc);
- end;
-if (pdf_output_option <> 0) then pdf_output := pdf_output_value;
-if (pdf_draftmode_option <> 0) then pdf_draftmode := pdf_draftmode_value;
-pdf_init_map_file('pdftex.map');
-if false then wterm_ln('entering extended mode');
-if end_line_char_inactive then decr(limit)
-else buffer[limit]:=end_line_char;
-fix_date_and_time;@/
-random_seed :=(microseconds*1000)+(epochseconds mod 1000000);@/
-init_randoms(random_seed);@/
-initialize_math;
-@<Initialize the print |selector|...@>;
-check_texconfig_init;
-if (loc<limit)and(get_cat_code(cat_code_table,buffer[loc])<>escape) then start_input;
- {\.{\\input} assumed}
-@<DIR: Initialize |text_dir_ptr|@>;
-end
-
-@* \[52] Debugging.
-Once \TeX\ is working, you should be able to diagnose most errors with
-the \.{\\show} commands and other diagnostic features. But for the initial
-stages of debugging, and for the revelation of really deep mysteries, you
-can compile \TeX\ with a few more aids, including the \PASCAL\ runtime
-checks and its debugger. An additional routine called |debug_help|
-will also come into play when you type `\.D' after an error message;
-|debug_help| also occurs just before a fatal error causes \TeX\ to succumb.
-@^debugging@>
-@^system dependencies@>
-
-The interface to |debug_help| is primitive, but it is good enough when used
-with a \PASCAL\ debugger that allows you to set breakpoints and to read
-variables and change their values. After getting the prompt `\.{debug \#}', you
-type either a negative number (this exits |debug_help|), or zero (this
-goes to a location where you can set a breakpoint, thereby entering into
-dialog with the \PASCAL\ debugger), or a positive number |m| followed by
-an argument |n|. The meaning of |m| and |n| will be clear from the
-program below. (If |m=13|, there is an additional argument, |l|.)
-@.debug \#@>
-
-@d breakpoint=888 {place where a breakpoint is desirable}
-
-@<Last-minute...@>=
-@!debug procedure debug_help; {routine to display various things}
-label breakpoint,exit;
-var k,@!l,@!m,@!n:integer;
-begin loop begin wake_up_terminal;
- print_nl("debug # (-1 to exit):"); update_terminal;
-@.debug \#@>
- read(term_in,m);
- if m<0 then return
- else if m=0 then
- begin goto breakpoint;@\ {go to every label at least once}
- breakpoint: m:=0; @{'BREAKPOINT'@}@\
- end
- else begin read(term_in,n);
- case m of
- @t\4@>@<Numbered cases for |debug_help|@>@;
- othercases print("?")
- endcases;
- end;
- end;
-exit:end;
-gubed
-
-@ @<Numbered cases...@>=
-1: print_word(mem(n)); {display |mem[n]| in all forms}
-2: print_int(info(n));
-3: print_int(link(n));
-4: print_word(eqtb[n]);
-5: ;
-6: print_word(save_stack[n]);
-7: show_box(n);
- {show a box, abbreviated by |show_box_depth| and |show_box_breadth|}
-8: begin breadth_max:=10000; depth_threshold:=pool_size-pool_ptr-10;
- show_node_list(n); {show a box in its entirety}
- end;
-9: show_token_list(n,null,1000);
-10: slow_print(n);
-13: begin read(term_in,l); print_cmd_chr(n,l);
- end;
-14: for k:=0 to n do print(buffer[k]);
-15: begin font_in_short_display:=null_font; short_display(n);
- end;
-
-@* \[53] Extensions.
-The program above includes a bunch of ``hooks'' that allow further
-capabilities to be added without upsetting \TeX's basic structure.
-Most of these hooks are concerned with ``whatsit'' nodes, which are
-intended to be used for special purposes; whenever a new extension to
-\TeX\ involves a new kind of whatsit node, a corresponding change needs
-to be made to the routines below that deal with such nodes,
-but it will usually be unnecessary to make many changes to the
-other parts of this program.
-
-In order to demonstrate how extensions can be made, we shall treat
-`\.{\\write}', `\.{\\openout}', `\.{\\closeout}', `\.{\\immediate}',
-and `\.{\\special}' as if they were extensions.
-These commands are actually primitives of \TeX, and they should
-appear in all implementations of the system; but let's try to imagine
-that they aren't. Then the program below illustrates how a person
-could add them.
-
-Sometimes, of course, an extension will require changes to \TeX\ itself;
-no system of hooks could be complete enough for all conceivable extensions.
-The features associated with `\.{\\write}' are almost all confined to the
-following paragraphs, but there are small parts of the |print_ln| and
-|print_char| procedures that were introduced specifically to \.{\\write}
-characters. Furthermore one of the token lists recognized by the scanner
-is a |write_text|; and there are a few other miscellaneous places where we
-have already provided for some aspect of \.{\\write}. The goal of a \TeX\
-extender should be to minimize alterations to the standard parts of the
-program, and to avoid them completely if possible. He or she should also
-be quite sure that there's no easy way to accomplish the desired goals
-with the standard features that \TeX\ already has. ``Think thrice before
-extending,'' because that may save a lot of work, and it will also keep
-incompatible extensions of \TeX\ from proliferating.
-@^system dependencies@>
-@^extensions to \TeX@>
-
-@ First let's consider the format of whatsit nodes that are used to represent
-the data associated with \.{\\write} and its relatives. Recall that a whatsit
-has |type=whatsit_node|, and the |subtype| is supposed to distinguish
-different kinds of whatsits. Each node occupies two or more words; the
-exact number is immaterial, as long as it is readily determined from the
-|subtype| or other data.
-
-We shall introduce five |subtype| values here, corresponding to the
-control sequences \.{\\openout}, \.{\\write}, \.{\\closeout}, and \.{\\special}.
-The second word of I/O whatsits has a |write_stream| field
-that identifies the write-stream number (0 to 15, or 16 for out-of-range and
-positive, or 17 for out-of-range and negative).
-In the case of \.{\\write} and \.{\\special}, there is also a field that
-points to the reference count of a token list that should be sent. In the
-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 write_node=1 {|subtype| in whatsits that represent things to \.{\\write}}
-@d close_node=2 {|subtype| in whatsits that represent streams to \.{\\closeout}}
-@d special_node=3 {|subtype| in whatsits that represent \.{\\special} things}
-@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|}
-@d write_tokens(#) == vlink(#+2) {reference count of token list to write}
-@d write_stream(#) == vinfo(#+2) {stream number (0 to 17)}
-@d open_name(#) == vlink(#+2) {string number of file name to open}
-@d open_area(#) == vinfo(#+3) {string number of file area for |open_name|}
-@d open_ext(#) == vlink(#+3) {string number of file extension for |open_name|}
-
-@ The sixteen possible \.{\\write} streams are represented by the |write_file|
-array. The |j|th file is open if and only if |write_open[j]=true|. The last
-two streams are special; |write_open[16]| represents a stream number
-greater than 15, while |write_open[17]| represents a negative stream number,
-and both of these variables are always |false|.
-
-@<Glob...@>=
-@!write_file:array[0..15] of alpha_file;
-@!write_file_mode:array[0..15] of halfword;
-@!write_file_translation:array[0..15] of halfword;
-@!write_open:array[0..17] of boolean;
-@!neg_wd:scaled;
-@!pos_wd:scaled;
-@!neg_ht:scaled;
-@!dvi_direction:integer;
-@!dir_primary:array[0..31] of 0..31;
-@!dir_secondary:array[0..31] of 0..31;
-@!dir_tertiary:array[0..31] of 0..31;
-@!dir_rearrange:array[0..3] of 0..31;
-@!dir_names:array[0..3] of str_number;
-@!text_dir_ptr:pointer;
-@!text_dir_tmp:pointer;
-
-@
-@<Set init...@>=
-for k:=0 to 17 do write_open[k]:=false;
-pack_direction:=-1;
-for k:= 0 to 7 do begin
- dir_primary [k ]:=dir_T;
- dir_primary [k+ 8]:=dir_L;
- dir_primary [k+16]:=dir_B;
- dir_primary [k+24]:=dir_R;
- end;
-for k:= 0 to 3 do begin
- dir_secondary[k ]:=dir_L;
- dir_secondary[k+ 4]:=dir_R;
- dir_secondary[k+ 8]:=dir_T;
- dir_secondary[k+12]:=dir_B;
-
- dir_secondary[k+16]:=dir_L;
- dir_secondary[k+20]:=dir_R;
- dir_secondary[k+24]:=dir_T;
- dir_secondary[k+28]:=dir_B;
- end;
-for k:=0 to 7 do begin
- dir_tertiary[k*4 ]:=dir_T;
- dir_tertiary[k*4+1]:=dir_L;
- dir_tertiary[k*4+2]:=dir_B;
- dir_tertiary[k*4+3]:=dir_R;
- end;
-dir_rearrange[0]:=0;
-dir_rearrange[1]:=0;
-dir_rearrange[2]:=1;
-dir_rearrange[3]:=1;
-dir_names[0]:="T";
-dir_names[1]:="L";
-dir_names[2]:="B";
-dir_names[3]:="R";
-
-@ Extensions might introduce new command codes; but it's best to use
-|extension| with a modifier, whenever possible, so that |main_control|
-stays the same.
-
-@d immediate_code=4 {command modifier for \.{\\immediate}}
-@d local_par_node==6 {|subtype| in whatsits for local paragraph node}
-{|local_par_node| has to be a macro, not numeric }
-@d dir_node=7 {|subtype| in whatsits for change direction node}
-@d pdftex_first_extension_code = 8
-@d pdf_literal_node == pdftex_first_extension_code + 0
-@d pdf_obj_code == pdftex_first_extension_code + 1
-@d pdf_refobj_node == pdftex_first_extension_code + 2
-@d pdf_xform_code == pdftex_first_extension_code + 3
-@d pdf_refxform_node == pdftex_first_extension_code + 4
-@d pdf_ximage_code == pdftex_first_extension_code + 5
-@d pdf_refximage_node == pdftex_first_extension_code + 6
-@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_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_save_pos_node == pdftex_first_extension_code + 15
-@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
-@d pdf_link_data_node == pdftex_first_extension_code + 17
-@d pdf_names_code == pdftex_first_extension_code + 18
-@d pdf_font_attr_code == pdftex_first_extension_code + 19
-@d pdf_include_chars_code == pdftex_first_extension_code + 20
-@d pdf_map_file_code == pdftex_first_extension_code + 21
-@d pdf_map_line_code == pdftex_first_extension_code + 22
-@d pdf_trailer_code == pdftex_first_extension_code + 23
-@d pdf_font_expand_code == pdftex_first_extension_code + 24
-@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 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
-@d pdf_setmatrix_node == pdftex_first_extension_code + 32
-@d pdf_save_node == pdftex_first_extension_code + 33
-@d pdf_restore_node == pdftex_first_extension_code + 34
-@d pdftex_last_extension_code == pdftex_first_extension_code + 34
-
-@<Put each...@>=
-primitive_tex("openout",extension,open_node,0);@/
-@!@:open_out_}{\.{\\openout} primitive@>
-primitive_tex("write",extension,write_node,0); write_loc:=cur_val;@/
-@!@:write_}{\.{\\write} primitive@>
-primitive_tex("closeout",extension,close_node,0);@/
-@!@:close_out_}{\.{\\closeout} primitive@>
-primitive_tex("special",extension,special_node,0);@/
-@!@:special_}{\.{\\special} primitive@>
-text(frozen_special):="special"; eqtb[frozen_special]:=eqtb[cur_val];@/
-primitive_tex("immediate",extension,immediate_code,0);@/
-@!@:immediate_}{\.{\\immediate} primitive@>
-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_pdftex("pdfcolorstack",extension,pdf_colorstack_node,0);@/
-@!@:pdf_colorstack_}{\.{\\pdfcolorstack} primitive@>
-primitive_pdftex("pdfsetmatrix",extension,pdf_setmatrix_node,0);@/
-@!@:pdf_setmatrix_}{\.{\\pdfsetmatrix} primitive@>
-primitive_pdftex("pdfsave",extension,pdf_save_node,0);@/
-@!@:pdf_save_}{\.{\\pdfsave} primitive@>
-primitive_pdftex("pdfrestore",extension,pdf_restore_node,0);@/
-@!@:pdf_restore_}{\.{\\pdfrestore} primitive@>
-primitive_pdftex("pdfobj",extension,pdf_obj_code,0);@/
-@!@:pdf_obj_}{\.{\\pdfobj} primitive@>
-primitive_pdftex("pdfrefobj",extension,pdf_refobj_node,0);@/
-@!@:pdf_refobj_}{\.{\\pdfrefobj} primitive@>
-primitive_pdftex("pdfxform",extension,pdf_xform_code,0);@/
-@!@:pdf_xform_}{\.{\\pdfxform} primitive@>
-primitive_pdftex("pdfrefxform",extension,pdf_refxform_node,0);@/
-@!@:pdf_refxform_}{\.{\\pdfrefxform} primitive@>
-primitive_pdftex("pdfximage",extension,pdf_ximage_code,0);@/
-@!@:pdf_ximage_}{\.{\\pdfximage} primitive@>
-primitive_pdftex("pdfrefximage",extension,pdf_refximage_node,0);@/
-@!@:pdf_refximage_}{\.{\\pdfrefximage} primitive@>
-primitive_pdftex("pdfannot",extension,pdf_annot_node,0);@/
-@!@:pdf_annot_}{\.{\\pdfannot} primitive@>
-primitive_pdftex("pdfstartlink",extension,pdf_start_link_node,0);@/
-@!@:pdf_start_link_}{\.{\\pdfstartlink} primitive@>
-primitive_pdftex("pdfendlink",extension,pdf_end_link_node,0);@/
-@!@:pdf_end_link_}{\.{\\pdfendlink} primitive@>
-primitive_pdftex("pdfoutline",extension,pdf_outline_code,0);@/
-@!@:pdf_outline_}{\.{\\pdfoutline} primitive@>
-primitive_pdftex("pdfdest",extension,pdf_dest_node,0);@/
-@!@:pdf_dest_}{\.{\\pdfdest} primitive@>
-primitive_pdftex("pdfthread",extension,pdf_thread_node,0);@/
-@!@:pdf_thread_}{\.{\\pdfthread} primitive@>
-primitive_pdftex("pdfstartthread",extension,pdf_start_thread_node,0);@/
-@!@:pdf_start_thread_}{\.{\\pdfstartthread} primitive@>
-primitive_pdftex("pdfendthread",extension,pdf_end_thread_node,0);@/
-@!@:pdf_end_thread_}{\.{\\pdfendthread} primitive@>
-primitive_pdftex("pdfsavepos",extension,pdf_save_pos_node,0);@/
-@!@:pdf_save_pos_}{\.{\\pdfsavepos} primitive@>
-primitive_pdftex("pdfinfo",extension,pdf_info_code,0);@/
-@!@:pdf_info_}{\.{\\pdfinfo} primitive@>
-primitive_pdftex("pdfcatalog",extension,pdf_catalog_code,0);@/
-@!@:pdf_catalog_}{\.{\\pdfcatalog} primitive@>
-primitive_pdftex("pdfnames",extension,pdf_names_code,0);@/
-@!@:pdf_names_}{\.{\\pdfnames} primitive@>
-primitive_pdftex("pdfincludechars",extension,pdf_include_chars_code,0);@/
-@!@:pdf_include_chars_}{\.{\\pdfincludechars} primitive@>
-primitive_pdftex("pdffontattr",extension,pdf_font_attr_code,0);@/
-@!@:pdf_font_attr_}{\.{\\pdffontattr} primitive@>
-primitive_pdftex("pdfmapfile",extension,pdf_map_file_code,0);@/
-@!@:pdf_map_file_}{\.{\\pdfmapfile} primitive@>
-primitive_pdftex("pdfmapline",extension,pdf_map_line_code,0);@/
-@!@:pdf_map_line_}{\.{\\pdfmapline} primitive@>
-primitive_pdftex("pdftrailer",extension,pdf_trailer_code,0);@/
-@!@:pdf_trailer_}{\.{\\pdftrailer} primitive@>
-primitive_luatex("savecatcodetable",extension,save_cat_code_table_code,0);@/
-@!@:save_cat_code_table_}{\.{\\savecatcodetable} primitive@>
-primitive_luatex("initcatcodetable",extension,init_cat_code_table_code,0);@/
-@!@:init_cat_code_table_}{\.{\\initcatcodetable} primitive@>
-primitive_pdftex("pdfsetrandomseed",extension,set_random_seed_code,0);@/
-@!@:set_random_seed_code}{\.{\\pdfsetrandomseed} primitive@>
-primitive_luatex("latelua",extension,late_lua_node,0);@/
-@!@:late_lua_node_}{\.{\\latelua} primitive@>
-primitive_pdftex("pdffontexpand",extension,pdf_font_expand_code,0);@/
-@!@:pdf_font_expand_}{\.{\\pdffontexpand} primitive@>
-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
-appropriate error message in case of ``runaway'' write texts.
-
-@<Glob...@>=
-@!write_loc:pointer; {|eqtb| address of \.{\\write}}
-
-@ When an |extension| command occurs in |main_control|, in any mode,
-the |do_extension| routine is called.
-
-@<Cases of |main_control| that are for extensions...@>=
-any_mode(extension):do_extension;
-
-@ @<Declare act...@>=
-@t\4@>@<Declare procedures needed in |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:@<Implement \.{\\openout}@>;
- write_node:@<Implement \.{\\write}@>;
- close_node:@<Implement \.{\\closeout}@>;
- special_node:@<Implement \.{\\special}@>;
- immediate_code:@<Implement \.{\\immediate}@>;
- pdf_annot_node: @<Implement \.{\\pdfannot}@>;
- pdf_catalog_code: @<Implement \.{\\pdfcatalog}@>;
- pdf_dest_node: @<Implement \.{\\pdfdest}@>;
- pdf_end_link_node: @<Implement \.{\\pdfendlink}@>;
- pdf_end_thread_node: @<Implement \.{\\pdfendthread}@>;
- pdf_font_attr_code: @<Implement \.{\\pdffontattr}@>;
- pdf_font_expand_code: @<Implement \.{\\pdffontexpand}@>;
- pdf_include_chars_code: @<Implement \.{\\pdfincludechars}@>;
- pdf_info_code: @<Implement \.{\\pdfinfo}@>;
- pdf_literal_node: @<Implement \.{\\pdfliteral}@>;
- pdf_colorstack_node: @<Implement \.{\\pdfcolorstack}@>;
- pdf_setmatrix_node: @<Implement \.{\\pdfsetmatrix}@>;
- pdf_save_node: @<Implement \.{\\pdfsave}@>;
- pdf_restore_node: @<Implement \.{\\pdfrestore}@>;
- pdf_map_file_code: @<Implement \.{\\pdfmapfile}@>;
- pdf_map_line_code: @<Implement \.{\\pdfmapline}@>;
- pdf_names_code: @<Implement \.{\\pdfnames}@>;
- pdf_obj_code: @<Implement \.{\\pdfobj}@>;
- pdf_outline_code: @<Implement \.{\\pdfoutline}@>;
- pdf_refobj_node: @<Implement \.{\\pdfrefobj}@>;
- pdf_refxform_node: @<Implement \.{\\pdfrefxform}@>;
- pdf_refximage_node: @<Implement \.{\\pdfrefximage}@>;
- pdf_save_pos_node: @<Implement \.{\\pdfsavepos}@>;
- pdf_start_link_node: @<Implement \.{\\pdfstartlink}@>;
- pdf_start_thread_node: @<Implement \.{\\pdfstartthread}@>;
- pdf_thread_node: @<Implement \.{\\pdfthread}@>;
- pdf_trailer_code: @<Implement \.{\\pdftrailer}@>;
- pdf_xform_code: @<Implement \.{\\pdfxform}@>;
- pdf_ximage_code: @<Implement \.{\\pdfximage}@>;
- save_cat_code_table_code: @<Implement \.{\\savecatcodetable}@>;
- init_cat_code_table_code: @<Implement \.{\\initcatcodetable}@>;
- set_random_seed_code: @<Implement \.{\\pdfsetrandomseed}@>;
- pdf_glyph_to_unicode_code: @<Implement \.{\\pdfglyphtounicode}@>;
- late_lua_node: @<Implement \.{\\latelua}@>;
-othercases confusion("ext1")
-@:this can't happen ext1}{\quad ext1@>
-endcases;
-end;
-
-@ Here is a subroutine that creates a whatsit node having a given |subtype|
-and a given number of words. It initializes only the first word of the whatsit,
-and appends it to the current list.
-
-@<Declare procedures needed in |do_extension|@>=
-procedure new_whatsit(@!s:small_number);
-var p:pointer; {the new node}
-begin p:=new_node(whatsit_node,s);
-vlink(tail):=p; tail:=p;
-end;
-
-@ The next subroutine uses |cur_chr| to decide what sort of whatsit is
-involved, and also inserts a |write_stream| number.
-
-@<Declare procedures needed in |do_ext...@>=
-procedure new_write_whatsit(@!w:small_number);
-begin new_whatsit(cur_chr);
-if w<>write_node_size then scan_four_bit_int
-else begin scan_int;
- if cur_val<0 then cur_val:=17
- else if cur_val>15 then cur_val:=16;
- end;
-write_stream(tail):=cur_val;
-end;
-
-@ @<Implement \.{\\openout}@>=
-begin new_write_whatsit(open_node_size);
-scan_optional_equals; scan_file_name;@/
-open_name(tail):=cur_name; open_area(tail):=cur_area; open_ext(tail):=cur_ext;
-end
-
-@ When `\.{\\write 12\{...\}}' appears, we scan the token list `\.{\{...\}}'
-without expanding its macros; the macros will be expanded later when this
-token list is rescanned.
-
-@<Implement \.{\\write}@>=
-begin k:=cur_cs; new_write_whatsit(write_node_size);@/
-cur_cs:=k; p:=scan_toks(false,false); write_tokens(tail):=def_ref;
-end
-
-@ @<Implement \.{\\closeout}@>=
-begin new_write_whatsit(write_node_size); write_tokens(tail):=null;
-end
-
-@ When `\.{\\special\{...\}}' appears, we expand the macros in the token
-list as in \.{\\xdef} and \.{\\mark}.
-
-@<Implement \.{\\special}@>=
-begin new_whatsit(special_node); write_stream(tail):=null;
-p:=scan_toks(false,true); write_tokens(tail):=def_ref;
-end
-
-@ @<Implement \.{\\pdffontexpand}@>=
- read_expand_font
-
-@ The following macros are needed for further manipulation with whatsit nodes
-for \pdfTeX{} extensions (copying, destroying etc.)
-
-@d add_action_ref(#) == incr(pdf_action_refcount(#)) {increase count of
-references to this action}
-
-@d delete_action_ref(#) == {decrease count of references to this
-action; free it if there is no reference to this action}
-begin
- if pdf_action_refcount(#) = null then begin
- if pdf_action_type(#) = pdf_action_user then
- delete_token_ref(pdf_action_tokens(#))
- else begin
- if pdf_action_file(#) <> null then
- delete_token_ref(pdf_action_file(#));
- if pdf_action_type(#) = pdf_action_page then
- delete_token_ref(pdf_action_tokens(#))
- else if pdf_action_named_id(#) > 0 then
- delete_token_ref(pdf_action_id(#));
- end;
- flush_node(#);
- end
- else
- decr(pdf_action_refcount(#));
-end
-
-@ We have to check whether \.{\\pdfoutput} is set for using \pdfTeX{}
- extensions.
-@<Declare procedures needed in |do_ext...@>=
-procedure check_pdfoutput(s: str_number; is_error : boolean);
-begin
- if pdf_output <= 0 then
- begin
- if is_error then
- pdf_error(s, "not allowed in DVI mode (\pdfoutput <= 0)")
- else
- pdf_warning(s, "not allowed in DVI mode (\pdfoutput <= 0); ignoring it", true,true);
- end
-end;
-
-procedure scan_pdf_ext_toks;
-begin
- call_func(scan_toks(false, true)); {like \.{\\special}}
-end;
-
-@ @<Implement \.{\\pdfliteral}@>=
-begin
- check_pdfoutput("\pdfliteral", true);
- new_whatsit(pdf_literal_node);
- if scan_keyword('direct') then
- pdf_literal_mode(tail) := direct_always
- else if scan_keyword('page') then
- pdf_literal_mode(tail) := direct_page
- else
- pdf_literal_mode(tail) := set_origin;
- scan_pdf_ext_toks;
- pdf_literal_type(tail) := normal;
- pdf_literal_data(tail) := def_ref;
-end
-
-@ @<Implement \.{\\pdfcolorstack}@>=
-begin
- check_pdfoutput("\pdfcolorstack", true);
- {Scan and check the stack number and store in |cur_val|}
- scan_int;
- if cur_val >= colorstackused then begin
- print_err("Unknown color stack number ");
- print_int(cur_val);
-@.Unknown color stack@>
- help3("Allocate and initialize a color stack with \\pdfcolorstackinit.")@/
- ("I'll use default color stack 0 here.")@/
- ("Proceed, with fingers crossed.");
- error;
- cur_val := 0;
- end;
- if cur_val < 0 then 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 crossed.");
- error;
- cur_val := 0;
- end;
- if scan_keyword('set') then begin
- i := colorstack_set;
- end
- else if scan_keyword('push') then begin
- i := colorstack_push;
- end
- else if scan_keyword('pop') then begin
- i := colorstack_pop;
- end
- else if scan_keyword('current') then begin
- i := colorstack_current;
- end
- else begin
- i := -1; {error}
- end;
- if i >= 0 then begin
- new_whatsit(pdf_colorstack_node);
- pdf_colorstack_stack(tail) := cur_val;
- pdf_colorstack_cmd(tail) := i;
- pdf_colorstack_data(tail) := null;
- if i <= colorstack_data then begin
- scan_pdf_ext_toks;
- pdf_colorstack_data(tail) := def_ref;
- end;
- end
- else begin
- print_err("Color stack action is missing");
-@.Color stack action is missing@>
- help3("The expected actions for \pdfcolorstack:")@/
- (" set, push, pop, current")@/
- ("I'll ignore the color stack command.");
- error;
- end
-end
-
-@ @<Implement \.{\\pdfsetmatrix}@>=
-begin
- check_pdfoutput("\pdfsetmatrix", true);
- new_whatsit(pdf_setmatrix_node);
- scan_pdf_ext_toks;
- pdf_setmatrix_data(tail) := def_ref;
-end
-
-@ @<Implement \.{\\pdfsave}@>=
-begin
- check_pdfoutput("\pdfsave", true);
- new_whatsit(pdf_save_node);
-end
-
-@ @<Implement \.{\\pdfrestore}@>=
-begin
- check_pdfoutput("\pdfrestore", true);
- new_whatsit(pdf_restore_node);
-end
-
-
-@ @<Implement \.{\\latelua}@>=
-begin
- check_pdfoutput("\latelua", true);
- new_whatsit(late_lua_node);
- if scan_keyword('name') then begin
- scan_pdf_ext_toks;
- late_lua_name(tail) := def_ref;
- end;
- sn:=0;
- @<Parse optional lua state...@>;
- if sn then late_lua_name(tail) := sn;
- call_func(scan_toks(false, false));
- late_lua_data(tail) := def_ref;
-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}
- is used with \.{\\immediate}, the object contents will be written out
- immediately. Objects referenced in the current page are appended into
- |pdf_obj_list|.
-
-@<Glob...@>=
-@!pdf_last_obj: integer;
-
-@ @<Implement \.{\\pdfobj}@>=
-begin
- check_pdfoutput("\pdfobj", true);
- if scan_keyword('reserveobjnum') then begin
- @<Scan an optional space@>;
- incr(pdf_obj_count);
- pdf_create_obj(obj_type_obj, pdf_obj_count);
- pdf_last_obj := obj_ptr;
- end
- else begin
- k := -1;
- 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
- pdf_warning("\pdfobj", "invalid object number being ignored", true, true);
- pdf_retval := -1; {signal the problem}
- k := -1; {will be generated again}
- end;
- end;
- if k < 0 then begin
- incr(pdf_obj_count);
- pdf_create_obj(obj_type_obj, pdf_obj_count);
- k := obj_ptr;
- end;
- obj_data_ptr(k) := pdf_get_mem(pdfmem_obj_size);
- if scan_keyword('stream') then begin
- obj_obj_is_stream(k) := 1;
- if scan_keyword('attr') then begin
- scan_pdf_ext_toks;
- obj_obj_stream_attr(k) := def_ref;
- end
- else
- obj_obj_stream_attr(k) := null;
- end
- else
- obj_obj_is_stream(k) := 0;
- if scan_keyword('file') then
- obj_obj_is_file(k) := 1
- else
- obj_obj_is_file(k) := 0;
- scan_pdf_ext_toks;
- obj_obj_data(k) := def_ref;
- pdf_last_obj := k;
- end;
-end
-
-@ We need to check whether the referenced object exists.
-
-@<Declare procedures that need to be declared forward for \pdfTeX@>=
-function prev_rightmost(s, e: pointer): pointer;
-{finds the node preceding the rightmost node |e|; |s| is some node
-before |e|}
-var p: pointer;
-begin
- prev_rightmost := null;
- p := s;
- if p = null then
- return;
- while vlink(p) <> e do begin
- p := vlink(p);
- if p = null then
- return;
- end;
- prev_rightmost := p;
-end;
-
-procedure pdf_check_obj(t, n: integer);
-var k: integer;
-begin
- k := head_tab[t];
- while (k <> 0) and (k <> n) do
- k := obj_link(k);
- if k = 0 then
- pdf_error("ext1", "cannot find referenced object");
-end;
-
-@ @<Implement \.{\\pdfrefobj}@>=
-begin
- check_pdfoutput("\pdfrefobj", true);
- scan_int;
- pdf_check_obj(obj_type_obj, cur_val);
- new_whatsit(pdf_refobj_node);
- pdf_obj_objnum(tail) := cur_val;
-end
-
-@ \.{\\pdfxform} and \.{\\pdfrefxform} are similiar to \.{\\pdfobj} and
- \.{\\pdfrefobj}
-
-@<Glob...@>=
-@!pdf_last_xform: integer;
-
-@ @<Implement \.{\\pdfxform}@>=
-begin
- check_pdfoutput("\pdfxform", true);
- incr(pdf_xform_count);
- 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
- scan_pdf_ext_toks;
- obj_xform_attr(k) := def_ref;
- end
- else
- obj_xform_attr(k) := null;
- 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);
- 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;
- pdf_last_xform := k;
-end
-
-@ @<Implement \.{\\pdfrefxform}@>=
-begin
- check_pdfoutput("\pdfrefxform", true);
- scan_int;
- pdf_check_obj(obj_type_xform, cur_val);
- new_whatsit(pdf_refxform_node);
- pdf_xform_objnum(tail) := cur_val;
- pdf_width(tail) := obj_xform_width(cur_val);
- pdf_height(tail) := obj_xform_height(cur_val);
- pdf_depth(tail) := obj_xform_depth(cur_val);
-end
-
-@ \.{\\pdfximage} and \.{\\pdfrefximage} are similiar to \.{\\pdfxform} and
- \.{\\pdfrefxform}. As we have to scan |<rule spec>| quite often, it is better
- have a |rule_node| that holds the most recently scanned |<rule spec>|.
-
-@<Glob...@>=
-@!pdf_last_ximage: integer;
-@!pdf_last_ximage_pages: integer;
-@!pdf_last_ximage_colordepth: integer;
-@!alt_rule: pointer;
-@!warn_pdfpagebox: boolean;
-
-@ @<Set init...@>=
-alt_rule := null;
-warn_pdfpagebox := true;
-
-@ @<Declare procedures needed in |do_ext...@>=
-
-function scan_pdf_box_spec: integer; {scans PDF pagebox specification}
-begin
- scan_pdf_box_spec := 0;
- if scan_keyword('mediabox') then
- scan_pdf_box_spec := pdf_box_spec_media
- else if scan_keyword('cropbox') then
- scan_pdf_box_spec := pdf_box_spec_crop
- else if scan_keyword('bleedbox') then
- scan_pdf_box_spec := pdf_box_spec_bleed
- else if scan_keyword('trimbox') then
- scan_pdf_box_spec := pdf_box_spec_trim
- else if scan_keyword('artbox') then
- scan_pdf_box_spec := pdf_box_spec_art
-end;
-
-procedure scan_alt_rule; {scans rule spec to |alt_rule|}
-label reswitch;
-begin
- if alt_rule = null then
- alt_rule := new_rule;
- width(alt_rule) := null_flag;
- height(alt_rule) := null_flag;
- depth(alt_rule) := null_flag;
-reswitch:
- if scan_keyword('width') then begin
- scan_normal_dimen;
- width(alt_rule) := cur_val;
- goto reswitch;
- end;
- if scan_keyword('height') then begin
- scan_normal_dimen;
- height(alt_rule) := cur_val;
- goto reswitch;
- end;
- if scan_keyword('depth') then begin
- scan_normal_dimen;
- depth(alt_rule) := cur_val;
- goto reswitch;
- end;
-end;
-
-procedure scan_image;
-label reswitch;
-var k, img_wd, img_ht, img_dp, ref: integer;
- named, attr: str_number;
- s: str_number;
- page, pagebox, colorspace: integer;
-begin
- incr(pdf_ximage_count);
- pdf_create_obj(obj_type_ximage, pdf_ximage_count);
- k := obj_ptr;
- scan_alt_rule; {scans |<rule spec>| to |alt_rule|}
- img_wd := width(alt_rule);
- img_ht := height(alt_rule);
- img_dp := depth(alt_rule);
- attr := 0;
- named := 0;
- page := 1;
- colorspace := 0;
- 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
- 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
- scan_int;
- page := cur_val;
- end;
- if scan_keyword('colorspace') then begin
- scan_int;
- colorspace := cur_val;
- end;
- pagebox := scan_pdf_box_spec;
- if pagebox = 0 then
- pagebox := pdf_pagebox;
- scan_pdf_ext_toks;
- s := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- if pdf_option_always_use_pdfpagebox <> 0 then begin
- pdf_warning("PDF inclusion", "Primitive \pdfoptionalwaysusepdfpagebox is obsolete; use \pdfpagebox instead.", true, true);
- pdf_force_pagebox := pdf_option_always_use_pdfpagebox;
- pdf_option_always_use_pdfpagebox := 0; {warn once}
- warn_pdfpagebox := false;
- end;
- if pdf_option_pdf_inclusion_errorlevel <> 0 then begin
- pdf_warning("PDF inclusion", "Primitive \pdfoptionpdfinclusionerrorlevel is obsolete; use \pdfinclusionerrorlevel instead.", true, true);
- pdf_inclusion_errorlevel := pdf_option_pdf_inclusion_errorlevel;
- pdf_option_pdf_inclusion_errorlevel := 0; {warn once}
- end;
- if pdf_force_pagebox > 0 then begin
- if warn_pdfpagebox then begin
- pdf_warning("PDF inclusion", "Primitive \pdfforcepagebox is obsolete; use \pdfpagebox instead.", true, true);
- warn_pdfpagebox := false;
- end;
- pagebox := pdf_force_pagebox;
- end;
- if pagebox = 0 then {no pagebox specification given}
- pagebox := pdf_box_spec_crop;
- ref := read_image(k, pdf_ximage_count, s, page, named, attr, colorspace, pagebox,
- pdf_minor_version, pdf_inclusion_errorlevel);
- flush_str(s);
- obj_data_ptr(k) := ref;
- if named <> 0 then flush_str(named);
- set_image_dimensions(ref, img_wd, img_ht, img_dp);
- if attr <> 0 then flush_str(attr);
- scale_image(ref);
- pdf_last_ximage := k;
- pdf_last_ximage_pages := image_pages(ref);
- pdf_last_ximage_colordepth := image_colordepth(ref);
-end;
-
-@ @<Implement \.{\\pdfximage}@>=
-begin
- check_pdfoutput("\pdfximage", true);
- check_pdfminorversion;
- scan_image;
-end
-
-@ @<Implement \.{\\pdfrefximage}@>=
-begin
- check_pdfoutput("\pdfrefximage", true);
- scan_int;
- pdf_check_obj(obj_type_ximage, cur_val);
- new_whatsit(pdf_refximage_node);
- j := obj_data_ptr(cur_val);
- pdf_ximage_idx(tail) := j;
- pdf_width(tail) := image_width(j);
- pdf_height(tail) := image_height(j);
- pdf_depth(tail) := image_depth(j);
-end
-
-@ The following function finds object with identifier |i| and type |t|.
- |i < 0| indicates that |-i| should be treated as a string number. If no
- such object exists then it will be created. This function is used mainly to
- find destination for link annotations and outlines; however it is also used
- in |pdf_ship_out| (to check whether a Page object already exists) so we need
- to declare it together with subroutines needed in |pdf_hlist_out| and
- |pdf_vlist_out|.
-
-@<Declare procedures that need to be declared forward for \pdfTeX@>=
-function find_obj(t, i: integer; byname: boolean): integer;
-begin
- find_obj := avl_find_obj(t, i, byname);
-end;
-
-procedure flush_str(s: str_number); {flush a string if possible}
-begin
- if flushable(s) then
- flush_string;
-end;
-
-function get_obj(t, i: integer; byname: boolean): integer;
-var r: integer;
- s: str_number;
-begin
- if byname > 0 then begin
- s := tokens_to_string(i);
- r := find_obj(t, s, true);
- end
- else begin
- s := 0;
- r := find_obj(t, i, false);
- end;
- if r = 0 then begin
- if byname > 0 then begin
- pdf_create_obj(t, -s);
- s := 0;
- end
- else
- pdf_create_obj(t, i);
- r := obj_ptr;
- if t = obj_type_dest then
- obj_dest_ptr(r) := null;
- end;
- if s <> 0 then
- flush_str(s);
- get_obj := r;
-end;
-
-function get_microinterval:integer;
-var s,@!m:integer; {seconds and microseconds}
-begin
- seconds_and_micros(s,m);
- if (s-epochseconds)>32767 then
- get_microinterval := max_integer
- else if (microseconds>m) then
- get_microinterval := ((s-1-epochseconds)*65536)+ (((m+1000000-microseconds)/100)*65536)/10000
- else
- get_microinterval := ((s-epochseconds)*65536) + (((m-microseconds)/100)*65536)/10000;
-end;
-
-
-@ @<Declare procedures needed in |do_ext...@>=
-function scan_action: pointer; {read an action specification}
-var p: integer;
-begin
- p := new_node(action_node,0);
- scan_action := p;
- if scan_keyword('user') then
- pdf_action_type(p) := pdf_action_user
- else if scan_keyword('goto') then
- pdf_action_type(p) := pdf_action_goto
- else if scan_keyword('thread') then
- pdf_action_type(p) := pdf_action_thread
- else
- pdf_error("ext1", "action type missing");
- if pdf_action_type(p) = pdf_action_user then begin
- scan_pdf_ext_toks;
- pdf_action_tokens(p) := def_ref;
- return;
- end;
- if scan_keyword('file') then begin
- scan_pdf_ext_toks;
- pdf_action_file(p) := def_ref;
- end;
- 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;
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "page number must be positive");
- pdf_action_id(p) := cur_val;
- pdf_action_named_id(p) := 0;
- scan_pdf_ext_toks;
- pdf_action_tokens(p) := def_ref;
- end
- 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
- if (pdf_action_type(p) = pdf_action_goto) and
- (pdf_action_file(p) <> null) then
- pdf_error("ext1",
- "`goto' option cannot be used with both `file' and `num'");
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "num identifier must be positive");
- pdf_action_named_id(p) := 0;
- pdf_action_id(p) := cur_val;
- end
- else
- pdf_error("ext1", "identifier type missing");
- if scan_keyword('newwindow') then begin
- pdf_action_new_window(p) := 1;
- @<Scan an optional space@>; end
- else if scan_keyword('nonewwindow') then begin
- pdf_action_new_window(p) := 2;
- @<Scan an optional space@>; end
- else
- pdf_action_new_window(p) := 0;
- if (pdf_action_new_window(p) > 0) and
- (((pdf_action_type(p) <> pdf_action_goto) and
- (pdf_action_type(p) <> pdf_action_page)) or
- (pdf_action_file(p) = null)) then
- pdf_error("ext1",
- "`newwindow'/`nonewwindow' must be used with `goto' and `file' option");
-end;
-
-procedure new_annot_whatsit(w: small_number); {create a new whatsit node for
-annotation}
-begin
- new_whatsit(w);
- scan_alt_rule; {scans |<rule spec>| to |alt_rule|}
- pdf_width(tail) := width(alt_rule);
- 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
- scan_pdf_ext_toks;
- pdf_thread_attr(tail) := def_ref;
- end
- else
- pdf_thread_attr(tail) := null;
- end;
-end;
-
-@ @<Glob...@>=
-@!pdf_last_annot: integer;
-
-@ @<Implement \.{\\pdfannot}@>=
-begin
- check_pdfoutput("\pdfannot", true);
- if scan_keyword('reserveobjnum') then begin
- pdf_last_annot := pdf_new_objnum;
- @<Scan an optional space@>; end
- else 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
- pdf_error("ext1", "invalid object number");
- end
- else
- k := pdf_new_objnum;
- new_annot_whatsit(pdf_annot_node);
- pdf_annot_objnum(tail) := k;
- scan_pdf_ext_toks;
- pdf_annot_data(tail) := def_ref;
- pdf_last_annot := k;
- end
-end
-
-@ pdflastlink needs an extra global variable
-@<Glob...@>=
-@!pdf_last_link: integer;
-
-@ @<Implement \.{\\pdfstartlink}@>=
-begin
- check_pdfoutput("\pdfstartlink", true);
- if abs(mode) = vmode then
- 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
- scan_pdf_ext_toks;
- pdf_link_attr(tail) := def_ref;
- end;
- r := scan_action; pdf_link_action(tail) := r;
- pdf_link_objnum(tail) := k;
- pdf_last_link := k;
- {N.B.: although it is possible to set |obj_annot_ptr(k) := tail| here, it
- is not safe if nodes are later copied/destroyed/moved; a better place
- to do this is inside |do_link|, when the whatsit node is written out}
-end
-
-@ @<Implement \.{\\pdfendlink}@>=
-begin
- check_pdfoutput("\pdfendlink", true);
- if abs(mode) = vmode then
- pdf_error("ext1", "\pdfendlink cannot be used in vertical mode");
- new_whatsit(pdf_end_link_node);
-end
-
-@ @<Declare procedures needed in |do_ext...@>=
-function outline_list_count(p: pointer): integer; {return number of outline
-entries in the same level with |p|}
-var k: integer;
-begin
- k := 1;
- while obj_outline_prev(p) <> 0 do begin
- incr(k);
- p := obj_outline_prev(p);
- end;
- outline_list_count := k;
-end;
-
-@ @<Implement \.{\\pdfoutline}@>=
-begin
- check_pdfoutput("\pdfoutline", true);
- 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
- scan_int;
- i := cur_val;
- end
- else
- i := 0;
- scan_pdf_ext_toks;
- q := def_ref;
- pdf_new_obj(obj_type_others, 0, 1);
- j := obj_ptr;
- write_action(p);
- pdf_end_obj;
- delete_action_ref(p);
- pdf_create_obj(obj_type_outline, 0);
- k := obj_ptr;
- obj_outline_ptr(k) := pdf_get_mem(pdfmem_outline_size);
- obj_outline_action_objnum(k) := j;
- obj_outline_count(k) := i;
- pdf_new_obj(obj_type_others, 0, 1);
- pdf_print_str_ln(tokens_to_string(q));
- flush_str(last_tokens_string);
- delete_token_ref(q);
- pdf_end_obj;
- obj_outline_title(k) := obj_ptr;
- obj_outline_prev(k) := 0;
- obj_outline_next(k) := 0;
- obj_outline_first(k) := 0;
- obj_outline_last(k) := 0;
- obj_outline_parent(k) := pdf_parent_outline;
- obj_outline_attr(k) := r;
- if pdf_first_outline = 0 then
- pdf_first_outline := k;
- if pdf_last_outline = 0 then begin
- if pdf_parent_outline <> 0 then
- obj_outline_first(pdf_parent_outline) := k;
- end
- else begin
- obj_outline_next(pdf_last_outline) := k;
- obj_outline_prev(k) := pdf_last_outline;
- end;
- pdf_last_outline := k;
- if obj_outline_count(k) <> 0 then begin
- pdf_parent_outline := k;
- pdf_last_outline := 0;
- end
- else if (pdf_parent_outline <> 0) and
- (outline_list_count(k) = abs(obj_outline_count(pdf_parent_outline))) then
- begin
- j := pdf_last_outline;
- repeat
- obj_outline_last(pdf_parent_outline) := j;
- j := pdf_parent_outline;
- pdf_parent_outline := obj_outline_parent(pdf_parent_outline);
- until (pdf_parent_outline = 0) or
- (outline_list_count(j) < abs(obj_outline_count(pdf_parent_outline)));
- if pdf_parent_outline = 0 then
- pdf_last_outline := pdf_first_outline
- else
- pdf_last_outline := obj_outline_first(pdf_parent_outline);
- while obj_outline_next(pdf_last_outline) <> 0 do
- pdf_last_outline := obj_outline_next(pdf_last_outline);
- end;
-end
-
-@ When a destination is created we need to check whether another destination
-with the same identifier already exists and give a warning if needed.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure warn_dest_dup(id: integer; byname: small_number; s1, s2: str_number);
-begin
- pdf_warning(s1, "destination with the same identifier (", false, false);
- if byname > 0 then begin
- print("name");
- print_mark(id);
- end
- else begin
- print("num");
- print_int(id);
- end;
- print(") ");
- print(s2);
- print_ln;
- show_context;
-end;
-
-@ Notice that |scan_keyword| doesn't care if two words have same prefix; so
-we should be careful when scan keywords with same prefix. The main rule: if
-there are two or more keywords with the same prefix, then always test in
-order from the longest one to the shortest one.
-
-@<Implement \.{\\pdfdest}@>=
-begin
- check_pdfoutput("\pdfdest", true);
- q := tail;
- new_whatsit(pdf_dest_node);
- if scan_keyword('num') then begin
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "num identifier must be positive");
- if cur_val > max_halfword then
- pdf_error("ext1", "number too big");
- pdf_dest_id(tail) := cur_val;
- pdf_dest_named_id(tail) := 0;
- end
- 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
- pdf_dest_type(tail) := pdf_dest_xyz;
- if scan_keyword('zoom') then begin
- scan_int;
- if cur_val > max_halfword then
- pdf_error("ext1", "number too big");
- pdf_dest_xyz_zoom(tail) := cur_val;
- end
- else
- pdf_dest_xyz_zoom(tail) := null;
- end
- else if scan_keyword('fitbh') then
- pdf_dest_type(tail) := pdf_dest_fitbh
- else if scan_keyword('fitbv') then
- pdf_dest_type(tail) := pdf_dest_fitbv
- else if scan_keyword('fitb') then
- pdf_dest_type(tail) := pdf_dest_fitb
- else if scan_keyword('fith') then
- pdf_dest_type(tail) := pdf_dest_fith
- else if scan_keyword('fitv') then
- pdf_dest_type(tail) := pdf_dest_fitv
- else if scan_keyword('fitr') then
- pdf_dest_type(tail) := pdf_dest_fitr
- else if scan_keyword('fit') then
- pdf_dest_type(tail) := pdf_dest_fit
- else
- pdf_error("ext1", "destination type missing");
- @<Scan an optional space@>;
- if pdf_dest_type(tail) = pdf_dest_fitr then begin
- scan_alt_rule; {scans |<rule spec>| to |alt_rule|}
- pdf_width(tail) := width(alt_rule);
- pdf_height(tail) := height(alt_rule);
- pdf_depth(tail) := depth(alt_rule);
- end;
- if pdf_dest_named_id(tail) <> 0 then begin
- i := tokens_to_string(pdf_dest_id(tail));
- k := find_obj(obj_type_dest, i, true);
- flush_str(i);
- end
- else
- k := find_obj(obj_type_dest, pdf_dest_id(tail), false);
- if (k <> 0) and (obj_dest_ptr(k) <> null) then begin
- warn_dest_dup(pdf_dest_id(tail), pdf_dest_named_id(tail),
- "ext4", "has been already used, duplicate ignored");
- flush_node_list(tail);
- tail := q;
- vlink(q) := null;
- end;
-end
-
-@ @<Declare procedures needed in |do_ext...@>=
-procedure scan_thread_id;
-begin
- if scan_keyword('num') then begin
- scan_int;
- if cur_val <= 0 then
- pdf_error("ext1", "num identifier must be positive");
- if cur_val > max_halfword then
- pdf_error("ext1", "number too big");
- pdf_thread_id(tail) := cur_val;
- pdf_thread_named_id(tail) := 0;
- end
- else if scan_keyword('name') then begin
- scan_pdf_ext_toks;
- pdf_thread_id(tail) := def_ref;
- pdf_thread_named_id(tail) := 1;
- end
- else
- pdf_error("ext1", "identifier type missing");
-end;
-
-@ @<Implement \.{\\pdfthread}@>=
-begin
- check_pdfoutput("\pdfthread", true);
- new_annot_whatsit(pdf_thread_node);
- scan_thread_id;
-end
-
-@ @<Implement \.{\\pdfstartthread}@>=
-begin
- check_pdfoutput("\pdfstartthread", true);
- new_annot_whatsit(pdf_start_thread_node);
- scan_thread_id;
-end
-
-@ @<Implement \.{\\pdfendthread}@>=
-begin
- check_pdfoutput("\pdfendthread", true);
- new_whatsit(pdf_end_thread_node);
-end
-
-@ @<Glob...@>=
-@!pdf_last_x_pos: integer;
-@!pdf_last_y_pos: integer;
-
-@ @<Implement \.{\\pdfsavepos}@>=
-begin
- new_whatsit(pdf_save_pos_node);
-end
-
-@ To implement primitives as \.{\\pdfinfo}, \.{\\pdfcatalog} or
-\.{\\pdfnames} we need to concatenate tokens lists.
-
-@<Declare procedures needed in |do_ext...@>=
-function concat_tokens(q, r: pointer): pointer; {concat |q| and |r| and
-returns the result tokens list}
-var p: pointer;
-begin
- if q = null then begin
- concat_tokens := r;
- return;
- end;
- p := q;
- while link(p) <> null do
- p := link(p);
- link(p) := link(r);
- free_avail(r);
- concat_tokens := q;
-end;
-
-@ @<Implement \.{\\pdfinfo}@>=
-begin
- check_pdfoutput("\pdfinfo", false);
- scan_pdf_ext_toks;
- if pdf_output > 0 then
- pdf_info_toks := concat_tokens(pdf_info_toks, def_ref);
-end
-
-@ @<Implement \.{\\pdfcatalog}@>=
-begin
- check_pdfoutput("\pdfcatalog", false);
- 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 pdf_catalog_openaction <> 0 then
- pdf_error("ext1", "duplicate of openaction")
- else begin
- p := scan_action;
- pdf_new_obj(obj_type_others, 0, 1);
- if pdf_output > 0 then
- pdf_catalog_openaction := obj_ptr;
- write_action(p);
- pdf_end_obj;
- delete_action_ref(p);
- end;
- end
-end
-
-@ @<Implement \.{\\pdfnames}@>=
-begin
- check_pdfoutput("\pdfnames", true);
- scan_pdf_ext_toks;
- pdf_names_toks := concat_tokens(pdf_names_toks, def_ref);
-end
-
-@ @<Implement \.{\\pdftrailer}@>=
-begin
- check_pdfoutput("\pdftrailer", false);
- scan_pdf_ext_toks;
- if pdf_output > 0 then
- pdf_trailer_toks := concat_tokens(pdf_trailer_toks, def_ref);
-end
-
-@ @<Glob...@>=
-@!pdf_retval: integer; {global multi-purpose return value}
-
-@ @<Set initial values of key variables@>=
- seconds_and_micros(epochseconds,microseconds);
- init_start_time;
-
-@ Negative random seed values are silently converted to positive ones
-
-@<Implement \.{\\pdfsetrandomseed}@>=
-begin
- scan_int;
- if cur_val<0 then negate(cur_val);
- random_seed := cur_val;
- init_randoms(random_seed);
-end
-
-@ @<Implement \.{\\savecatcodetable}@>=
-begin
- scan_int;
- 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;
- end
- else
- copy_cat_codes(cat_code_table,cur_val);
- end;
-end
-
-@ @<Implement \.{\\initcatcodetable}@>=
-begin
- scan_int;
- 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;
- end
- else
- initex_cat_codes(cur_val);
- end;
-end
-
-@ The following subroutines are about PDF-specific font issues.
-
-@<Declare procedures needed in |do_ext...@>=
-procedure pdf_include_chars;
-var s: str_number;
- k: pool_pointer; {running indices}
- f: internal_font_number;
-begin
- scan_font_ident;
- f := cur_val;
- if f = null_font then
- pdf_error("font", "invalid font identifier");
- pdf_check_vf_cur_val;
- if not font_used(f) then
- pdf_init_font(f);
- scan_pdf_ext_toks;
- s := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- k := str_start_macro(s);
- while k < str_start_macro(s + 1) do begin
- pdf_mark_char(f, str_pool[k]);
- incr(k);
- end;
- flush_str(s);
-end;
-
-procedure glyph_to_unicode;
-var s1, s2: str_number;
-begin
- scan_pdf_ext_toks;
- s1 := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- scan_pdf_ext_toks;
- s2 := tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- def_tounicode(s1, s2);
- flush_str(s2);
- flush_str(s1);
-end;
-
-@ @<Implement \.{\\pdfincludechars}@>=
-begin
- check_pdfoutput("\pdfincludechars", true);
- pdf_include_chars;
-end
-
-@ @<Implement \.{\\pdfglyphtounicode}@>=
-begin
- glyph_to_unicode;
-end
-
-@ A change from \THANH's original code: the font attributes are simply
-initialized to zero now, this is easier to deal with from C than an
-empty \TeX{} string, and surely nobody will want to set
-\.{\\pdffontattr} to a string containing a single zero, as that
-would be nonsensical in the PDF output.
-
-@<Implement \.{\\pdffontattr}@>=
-begin
- check_pdfoutput("\pdffontattr", true);
- scan_font_ident;
- k := cur_val;
- if k = null_font then
- pdf_error("font", "invalid font identifier");
- scan_pdf_ext_toks;
- set_pdf_font_attr(k, tokens_to_string(def_ref));
- if length(pdf_font_attr(k)) = 0 then begin
- flush_string;
- set_pdf_font_attr(k,0);
- end;
-end
-
-@ @<Implement \.{\\pdfmapfile}@>=
-begin
- check_pdfoutput("\pdfmapfile", true);
- scan_pdf_ext_toks;
- pdfmapfile(def_ref);
- delete_token_ref(def_ref);
-end
-
-@ @<Implement \.{\\pdfmapline}@>=
-begin
- check_pdfoutput("\pdfmapline", true);
- scan_pdf_ext_toks;
- pdfmapline(def_ref);
- delete_token_ref(def_ref);
-end
-
-@ The following function are needed for outputing article thread.
-
-@<Declare procedures needed in |do_ext...@>=
-procedure thread_title(thread: integer);
-begin
- pdf_print("/Title (");
- if obj_info(thread) < 0 then
- pdf_print(-obj_info(thread))
- else
- pdf_print_int(obj_info(thread));
- pdf_print_ln(")");
-end;
-
-procedure pdf_fix_thread(thread: integer);
-var a: pointer;
-begin
- pdf_warning("thread", "destination ", false, false);
- if obj_info(thread) < 0 then begin
- print("name{");
- print(-obj_info(thread));
- print("}");
- end
- else begin
- print("num");
- print_int(obj_info(thread));
- end;
- print(" has been referenced but does not exist, replaced by a fixed one");
- print_ln; print_ln;
- pdf_new_dict(obj_type_others, 0, 0);
- a := obj_ptr;
- pdf_indirect_ln("T", thread);
- pdf_indirect_ln("V", a);
- pdf_indirect_ln("N", a);
- pdf_indirect_ln("P", head_tab[obj_type_page]);
- pdf_print("/R [0 0 ");
- pdf_print_bp(page_width); pdf_out(" ");
- pdf_print_bp(page_height);
- pdf_print_ln("]");
- pdf_end_dict;
- pdf_begin_dict(thread, 1);
- pdf_print_ln("/I << ");
- thread_title(thread);
- pdf_print_ln(">>");
- pdf_indirect_ln("F", a);
- pdf_end_dict;
-end;
-
-procedure out_thread(thread: integer);
-var a, b: pointer;
- last_attr: integer;
-begin
- if obj_thread_first(thread) = 0 then begin
- pdf_fix_thread(thread);
- return;
- end;
- pdf_begin_dict(thread, 1);
- a := obj_thread_first(thread);
- b := a;
- last_attr := 0;
- repeat
- if obj_bead_attr(a) <> 0 then
- last_attr := obj_bead_attr(a);
- a := obj_bead_next(a);
- until a = b;
- if last_attr <> 0 then
- pdf_print_ln(last_attr)
- else begin
- pdf_print_ln("/I << ");
- thread_title(thread);
- pdf_print_ln(">>");
- end;
- pdf_indirect_ln("F", a);
- pdf_end_dict;
- repeat
- pdf_begin_dict(a, 1);
- if a = b then
- pdf_indirect_ln("T", thread);
- 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;
-
-
-@ 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
-
-@<Append a |cancel_boundary_node| @>=
-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)
-
-
-@ @<Incorporate a whatsit node into a vbox@>=
-if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
-begin x:=x+d+pdf_height(p); d:=pdf_depth(p);
-s:=0;
-if pdf_width(p)+s>w then w:=pdf_width(p)+s;
-end
-
-@ @<Incorporate a whatsit node into an hbox@>=
-begin
-if subtype(p)=dir_node then
- begin
- @<DIR: Adjust the dir stack for the |hpack| routine@>;
- end
-else begin
-if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
-begin x:=x+pdf_width(p);
-s:=0;
-if pdf_height(p)-s>h then h:=pdf_height(p)-s;
-if pdf_depth(p)+s>d then d:=pdf_depth(p)+s;
-end;
-end;
-end
-
-@ @<Prepare to move whatsit |p| to the current page, then |goto contribute|@>=
-begin
- if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
- begin page_total:=page_total+page_depth+pdf_height(p);
- page_depth:=pdf_depth(p);
- end;
- goto contribute;
-end
-
-@ @<Process whatsit |p| in |vert_break| loop, |goto not_found|@>=
-begin
- if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then
- begin cur_height:=cur_height+prev_dp+pdf_height(p); prev_dp:=pdf_depth(p);
- end;
- goto not_found;
-end
-
-@ @<Output the whatsit node |p| in a vlist@>=
-out_what(p)
-
-@ @<Output the whatsit node |p| in an hlist@>=
-if subtype(p)<>dir_node then out_what(p)
-else @<Output a reflection instruction if the direction has changed@>
-
-@ After all this preliminary shuffling, we come finally to the routines
-that actually send out the requested data. Let's do \.{\\special} first
-(it's easier).
-
-@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
-procedure special_out(@!p:pointer);
-var old_setting:0..max_selector; {holds print |selector|}
-@!k:pool_pointer; {index into |str_pool|}
-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;
-str_room(1);
-if cur_length<256 then
- begin dvi_out(xxx1); dvi_out(cur_length);
- end
-else begin dvi_out(xxx4); dvi_four(cur_length);
- end;
-for k:=str_start_macro(str_ptr) to pool_ptr-1 do dvi_out(so(str_pool[k]));
-pool_ptr:=str_start_macro(str_ptr); {erase the string}
-end;
-
-@ To write a token list, we must run it through \TeX's scanner, expanding
-macros and \.{\\the} and \.{\\number}, etc. This might cause runaways,
-if a delimited macro parameter isn't matched, and runaways would be
-extremely confusing since we are calling on \TeX's scanner in the middle
-of a \.{\\shipout} command. Therefore we will put a dummy control sequence as
-a ``stopper,'' right after the token list. This control sequence is
-artificially defined to be \.{\\outer}.
-@:end_write_}{\.{\\endwrite}@>
-
-@<Initialize table...@>=
-text(end_write):="endwrite"; eq_level(end_write):=level_one;
-eq_type(end_write):=outer_call; equiv(end_write):=null;
-
-@ @<Declare procedures needed in |hlist_out|, |vlist_out|@>=
-procedure write_out(@!p:pointer);
-var old_setting:0..max_selector; {holds print |selector|}
-@!old_mode:integer; {saved |mode|}
-@!j:small_number; {write stream number}
-@!q,@!r:pointer; {temporary variables for list manipulation}
-begin @<Expand macros in the token list
- and make |link(def_ref)| point to the result@>;
-old_setting:=selector; j:=write_stream(p);
-if write_open[j] then selector:=j
-else begin {write to the terminal if file isn't open}
- if (j=17)and(selector=term_and_log) then selector:=log_only;
- print_nl("");
- end;
-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 @<Expand macros in the token list
- and make |link(def_ref)| point to the result@>;
-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
-@^Knuth, Donald Ervin@>
-on the stack, namely the one that contained |end_write_token|. (We
-insert this artificial `\.{\\endwrite}' to prevent runaways, as explained
-above.) If it were not removed, and if there were numerous writes on a
-single page, the stack would overflow.
-
-@d end_write_token==cs_token_flag+end_write
-
-@<Expand macros in the token list and...@>=
-q:=get_avail; info(q):=right_brace_token+"}";@/
-r:=get_avail; link(q):=r; info(r):=end_write_token; ins_list(q);@/
-begin_token_list(write_tokens(p),write_text);@/
-q:=get_avail; info(q):=left_brace_token+"{"; ins_list(q);
-{now we're ready to scan
- `\.\{$\langle\,$token list$\,\rangle$\.{\} \\endwrite}'}
-old_mode:=mode; mode:=0;
- {disable \.{\\prevdepth}, \.{\\spacefactor}, \.{\\lastskip}, \.{\\prevgraf}}
-cur_cs:=write_loc; q:=scan_toks(false,true); {expand macros, etc.}
-get_token;@+if cur_tok<>end_write_token then
- @<Recover from an unbalanced write command@>;
-mode:=old_mode;
-end_token_list {conserve stack space}
-
-@ @<Recover from an unbalanced write command@>=
-begin print_err("Unbalanced write command");
-@.Unbalanced write...@>
-help2("On this page there's a \write with fewer real {'s than }'s.")@/
-("I can't handle that very well; good luck."); error;
-repeat get_token;
-until cur_tok=end_write_token;
-end
-
-@ The |out_what| procedure takes care of outputting whatsit nodes for
-|vlist_out| and |hlist_out|\kern-.3pt.
-
-@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
-procedure out_what(@!p:pointer);
-var j:small_number; {write stream number}
-begin case subtype(p) of
-open_node,write_node,close_node:@<Do some work that has been queued up
- for \.{\\write}@>;
-special_node:special_out(p);
-pdf_save_pos_node:
- @<Save current position@>;
-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;
-
-@ @<Save current position@>=
-begin
- 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
-the number of times a leader box appears might be different in different
-implementations, due to machine-dependent rounding in the glue calculations.)
-@^leaders@>
-
-@<Do some work that has been queued up...@>=
-if not doing_leaders then
- begin j:=write_stream(p);
- if subtype(p)=write_node then write_out(p)
- else begin if write_open[j] then lua_a_close_out(write_file[j]);
- if subtype(p)=close_node then write_open[j]:=false
- else if j<16 then
- begin cur_name:=open_name(p); cur_area:=open_area(p);
- cur_ext:=open_ext(p);
- 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');
- write_file[j]:= name_file_pointer;
- write_open[j]:=true;
- end;
- end;
- end
-
-@ The presence of `\.{\\immediate}' causes the |do_extension| procedure
-to descend to one level of recursion. Nothing happens unless \.{\\immediate}
-is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
-@^recursion@>
-
-@<Implement \.{\\immediate}@>=
-begin get_x_token;
-if cur_cmd=extension then begin
- if cur_chr<=close_node then
- begin p:=tail; do_extension; {append a whatsit node}
- out_what(tail); {do the action immediately}
- flush_node_list(tail); tail:=p; vlink(p):=null;
- end
- else case cur_chr of
- 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}
- pdf_error("ext1", "`\pdfobj reserveobjnum' cannot be used with \immediate");
- pdf_write_obj(pdf_last_obj);
- end;
- pdf_xform_code: begin
- do_extension; {scan form and set |pdf_last_xform|}
- pdf_cur_form := pdf_last_xform;
- pdf_ship_out(obj_xform_box(pdf_last_xform), false);
- end;
- pdf_ximage_code: begin
- do_extension; {scan image and set |pdf_last_ximage|}
- pdf_write_image(pdf_last_ximage);
- end;
- othercases back_input
- endcases;
-end
-else
- back_input;
-end
-
-@ @<Finish the extensions@>=
-for k:=0 to 15 do if write_open[k] then lua_a_close_out(write_file[k])
-
-@
-@d local_pen_inter(#)==vinfo(#+2) {\.{\\localinterlinepenalty}}
-@d local_pen_broken(#)==vlink(#+2) {\.{\\localbrokenpenalty}}
-@d local_box_left(#)==vlink(#+3) {\.{\\localleftbox}}
-@d local_box_left_width(#)==vinfo(#+3)
-@d local_box_right(#)==vlink(#+4) {\.{\\localleftbox}}
-@d local_box_right_width(#)==vinfo(#+4)
-@d local_par_dir(#)==vinfo(#+5)
-
-@<LOCAL: Declare |make_local_par_node|@>=
-function make_local_par_node:pointer;
-{This function creates a |local_paragraph| node}
-var p,q:pointer;
-begin
-p:=new_node(whatsit_node,local_par_node);
-local_pen_inter(p):=local_inter_line_penalty;
-local_pen_broken(p):=local_broken_penalty;
-if local_left_box<>null then begin
- q:=copy_node_list(local_left_box); local_box_left(p):=q;
- local_box_left_width(p):=width(local_left_box);
- end;
-if local_right_box<>null then begin
- q:=copy_node_list(local_right_box); local_box_right(p):=q;
- local_box_right_width(p):=width(local_right_box);
- end;
-local_par_dir(p):=par_direction;
-make_local_par_node:=p;
-end
-
-@ @<LOCAL: Add local paragraph node@>=
-begin tail_append(make_local_par_node) end
-
-@ @<DIR: Assign direction codes@>=
-case cur_chr of
-dir_base+page_direction_code: begin
- scan_direction;
- eq_word_define(dir_base+page_direction_code,cur_val);
- end;
-dir_base+body_direction_code: begin
- scan_direction;
- eq_word_define(dir_base+body_direction_code,cur_val);
- end;
-dir_base+par_direction_code: begin
- scan_direction;
- eq_word_define(dir_base+par_direction_code,cur_val);
- end;
-dir_base+text_direction_code: begin scan_direction;
- if (no_local_dirs>0) and (abs(mode)=hmode) then begin
- @<DIR: Add local dir node@>;
- dir_dir(tail):=dir_dir(tail);
- end;
- if dir_level(text_dir_ptr)=cur_level then
- @<DIR: Remove from |text_dir_ptr|@>;
- eq_word_define(dir_base+text_direction_code,cur_val);
- @<DIR: Add to |text_dir_ptr|@>;
- if abs(mode)=hmode then
- begin
- @<DIR: Add local dir node@>;
- dir_level(tail):=cur_level;
- end;
- eq_word_define(int_base+no_local_dirs_code,no_local_dirs+1);
- eq_word_define(int_base+level_local_dir_code,cur_level);
- end;
-dir_base+math_direction_code: begin scan_direction;
- eq_word_define(dir_base+math_direction_code,cur_val);
- end;
-end;
-
-@
-@d push_dir(#)==
-begin dir_tmp:=new_dir(#);
-vlink(dir_tmp):=dir_ptr;
-dir_ptr:=dir_tmp;
-end
-
-@d push_dir_node(#)==
-begin dir_tmp:=copy_node(#);
-vlink(dir_tmp):=dir_ptr;
-dir_ptr:=dir_tmp;
-end
-
-@d pop_dir_node==
-begin dir_tmp:=dir_ptr;
-dir_ptr:=vlink(dir_tmp);
-flush_node(dir_tmp);
-end
-
-@ @<DIR: Declare |new_dir|@>=
-function new_dir(s:small_number): pointer;
-var p:pointer; {the new node}
-begin p:=new_node(whatsit_node,dir_node);
-dir_dir(p):=s; dir_dvi_ptr(p):=-1;
-dir_level(p):=cur_level; new_dir:=p;
-end
-
-@ @<DIR: Add local dir node@>=
-tail_append(new_dir(text_direction))
-
-@ @<DIR: Adjust the dir stack for the |hpack| routine@>=
-begin
-if dir_dir(p)>=0 then begin
- hpack_dir:=dir_dir(p);
- push_dir_node(p);
- end
-else begin
- pop_dir_node;
- if dir_ptr<>null then
- hpack_dir:=dir_dir(dir_ptr);
- end
-end
-
-@ @<DIR: Reset |dir_ptr|@>=
-begin
- while dir_ptr<>null do
- pop_dir_node
-end
-
-@ @<DIR: Adjust |text_dir_ptr| for |scan_spec|@>=
-begin
-if spec_direction<>-1 then begin
- saved(4):=text_dir_ptr;
- text_dir_ptr:=new_dir(spec_direction);
- end
-else saved(4):=null;
-end
-
-@ @<DIR: Adjust back |text_dir_ptr| for |scan_spec|@>=
-begin
-flush_node_list(text_dir_ptr);
-text_dir_ptr:=saved(4);
-end
-
-@ @<DIR: Add to |text_dir_ptr|@>=
-begin
-text_dir_tmp:=new_dir(text_direction);
-vlink(text_dir_tmp):=text_dir_ptr;
-text_dir_ptr:=text_dir_tmp;
-end
-
-@ @<DIR: Remove from |text_dir_ptr|@>=
-begin
-text_dir_tmp:=vlink(text_dir_ptr);
-flush_node(text_dir_ptr);
-text_dir_ptr:=text_dir_tmp;
-end
-
-@ @<DIR: Initialize |text_dir_ptr|@>=
-begin
-text_dir_ptr:=new_dir(0);
-end
-
-@ @<DIR: Initialize |dir_ptr| for |ship_out|@>=
-begin dir_ptr:=null; push_dir(dvi_direction);
-dir_dvi_ptr(dir_ptr):=dvi_ptr;
-end
-
-@ @<Output a reflection instruction if the direction has changed@>=
-begin
- 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
- 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_direction:=0;
- end
-end
-
-@ This code scans forward to the ending |dir_node| while keeping
-track of the needed width in |w|. When it finds the node that will end
-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.
-
-@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;
- save_cur_glue:=cur_glue;
- { to me, it looks like the next is needed. but Aleph doesn't do that,
- so let us not do it either }
- {|w:=w-cur_g; cur_glue:=0;|}
- dir_nest:=1;
- while (q<>null) and (vlink(q)<>null) do begin
- 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_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
- begin if g_sign=stretching then
- begin if stretch_order(g)=g_order then
- begin cur_glue:=cur_glue+stretch(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end
- else if shrink_order(g)=g_order then
- begin cur_glue:=cur_glue-shrink(g);
- vet_glue(float(glue_set(this_box))*cur_glue);
- cur_g:=round(glue_temp);
- end;
- end;
- w:=w+cur_g;
- end;
- 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;
- temp_ptr := q;
- q:=null;
- end;
- end
- else if (subtype(q) = pdf_refxform_node) or
- (subtype(q) = pdf_refximage_node) then
- w:=w+pdf_width(q);
- end;
- othercases do_nothing;
- endcases;
- end;
- end;
- cur_g:=save_cur_g;
- cur_glue:=save_cur_glue;
-end
-
-
-@ Shipping out PDF marks.
-
-@<Types...@>=
-dest_name_entry = record
- objname: str_number; {destination name}
- objnum: integer; {destination object number}
-end;
-
-@ @<Glob...@>=
-@!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}
-@!last_thread: pointer; {pointer to the last thread}
-@!pdf_thread_ht, pdf_thread_dp, pdf_thread_wd: scaled; {dimensions of the last
-thread}
-@!pdf_last_thread_id: halfword; {identifier of the last thread}
-@!pdf_last_thread_named_id: boolean; {is identifier of the last thread named}
-@!pdf_thread_level: integer; {depth of nesting of box containing the last thread}
-@!pdf_annot_list: pointer; {list of annotations in the current page}
-@!pdf_link_list: pointer; {list of link annotations in the current page}
-@!pdf_dest_list: pointer; {list of destinations in the current page}
-@!pdf_bead_list: pointer; {list of thread beads in the current page}
-@!pdf_obj_count: integer; {counter of objects}
-@!pdf_xform_count: integer; {counter of forms}
-@!pdf_ximage_count: integer; {counter of images}
-@!pdf_cur_form: integer; {the form being output}
-@!pdf_first_outline, pdf_last_outline, pdf_parent_outline: integer;
-@!pdf_info_toks: pointer; {additional keys of Info dictionary}
-@!pdf_catalog_toks: pointer; {additional keys of Catalog dictionary}
-@!pdf_catalog_openaction: integer;
-@!pdf_names_toks: pointer; {additional keys of Names dictionary}
-@!pdf_dest_names_ptr: integer; {first unused position in |dest_names|}
-@!dest_names_size: integer; {maximum number of names in name tree of PDF output file}
-@!dest_names: ^dest_name_entry;
-@!pk_dpi: integer; {PK pixel density value from \.{texmf.cnf}}
-@!image_orig_x, image_orig_y: integer; {origin of cropped PDF images}
-@!pdf_trailer_toks: pointer; {additional keys of Trailer dictionary}
-
-@ @<Set init...@>=
-pdf_first_outline:= 0;
-pdf_last_outline:= 0;
-pdf_parent_outline:= 0;
-pdf_obj_count := 0;
-pdf_xform_count := 0;
-pdf_ximage_count := 0;
-pdf_dest_names_ptr := 0;
-pdf_info_toks := null;
-pdf_catalog_toks := null;
-pdf_names_toks := null;
-pdf_catalog_openaction := 0;
-pdf_trailer_toks := null;
-
-@ The following procedures are needed for outputing whatsit nodes for
-\pdfTeX{}.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure write_action(p: pointer); {write an action specification}
-var s: str_number;
- d: integer;
-begin d:=0;
- if pdf_action_type(p) = pdf_action_user then begin
- pdf_print_toks_ln(pdf_action_tokens(p));
- return;
- end;
- pdf_print("<< ");
- if pdf_action_file(p) <> null then begin
- pdf_print("/F ");
- s := tokens_to_string(pdf_action_file(p));
- if (str_pool[str_start_macro(s)] = 40) and
- (str_pool[str_start_macro(s) + length(s) - 1] = 41) then
- pdf_print(s)
- else begin
- pdf_print_str(s);
- end;
- flush_str(s);
- pdf_print(" ");
- if pdf_action_new_window(p) > 0 then begin
- pdf_print("/NewWindow ");
- if pdf_action_new_window(p) = 1 then
- pdf_print("true ")
- else
- pdf_print("false ");
- end;
- end;
- case pdf_action_type(p) of
- pdf_action_page: begin
- if pdf_action_file(p) = null then begin
- pdf_print("/S /GoTo /D [");
- pdf_print_int(get_obj(obj_type_page, pdf_action_id(p), false));
- pdf_print(" 0 R");
- end
- else begin
- pdf_print("/S /GoToR /D [");
- pdf_print_int(pdf_action_id(p) - 1);
- end;
- pdf_out(" ");
- pdf_print(tokens_to_string(pdf_action_tokens(p)));
- flush_str(last_tokens_string);
- pdf_out("]");
- end;
- pdf_action_goto: begin
- if pdf_action_file(p) = null then begin
- pdf_print("/S /GoTo ");
- d := get_obj(obj_type_dest, pdf_action_id(p),
- pdf_action_named_id(p));
- end
- else
- pdf_print("/S /GoToR ");
- if pdf_action_named_id(p) > 0 then begin
- pdf_str_entry("D", tokens_to_string(pdf_action_id(p)));
- flush_str(last_tokens_string);
- end
- else if pdf_action_file(p) = null then
- pdf _indirect("D", d)
- else
- pdf_error("ext4", "`goto' option cannot be used with both `file' and `num'");
- end;
- pdf_action_thread: begin
- pdf_print("/S /Thread ");
- if pdf_action_file(p) = null then
- d := get_obj(obj_type_thread, pdf_action_id(p),
- pdf_action_named_id(p));
- if pdf_action_named_id(p) > 0 then begin
- pdf_str_entry("D", tokens_to_string(pdf_action_id(p)));
- flush_str(last_tokens_string);
- end
- else if pdf_action_file(p) = null then
- pdf_indirect("D", d)
- else
- pdf_int_entry("D", pdf_action_id(p));
- end;
- endcases;
- pdf_print_ln(" >>");
-end;
-
-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
- ll.h := cur.h;
- if is_running(dp) then
- ll.v := y + depth(parent_box)
- else
- ll.v := cur.v + dp;
- if is_running(wd) then
- ur.h := x + width(parent_box)
- else
- ur.h := cur.h + wd;
- if is_running(ht) then
- ur.v := y - height(parent_box)
- else
- 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(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_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);
-begin
- if not is_shipping_page then
- 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 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.
-
-@d pdf_link_stack_top == pdf_link_stack[pdf_link_stack_ptr]
-
-@<Constants...@>=
-@!pdf_max_link_level = 10; {maximum depth of link nesting}
-
-@ @<Types...@>=
-@!pdf_link_stack_record = record
- 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
- case of multi-line link}
-end;
-
-@ @<Glob...@>=
-@!pdf_link_stack: array[1..pdf_max_link_level] of pdf_link_stack_record;
-@!pdf_link_stack_ptr: small_number;
-
-@ @<Set init...@>=
-pdf_link_stack_ptr := 0;
-
-@ @<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure push_link_level(p: pointer);
-begin
- if pdf_link_stack_ptr >= pdf_max_link_level then
- overflow("pdf link stack size", pdf_max_link_level);
- pdfassert((type(p) = whatsit_node) and (subtype(p) = pdf_start_link_node));
- incr(pdf_link_stack_ptr);
- pdf_link_stack_top.nesting_level := cur_s;
- pdf_link_stack_top.link_node := copy_node_list(p);
- pdf_link_stack_top.ref_link_node := p;
-end;
-
-procedure pop_link_level;
-begin
- pdfassert(pdf_link_stack_ptr > 0);
- flush_node_list(pdf_link_stack_top.link_node);
- decr(pdf_link_stack_ptr);
-end;
-
-procedure do_link(p, parent_box: pointer; x, y: scaled);
-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),
- pdf_link_margin);
- 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?");
- if pdf_link_stack_top.nesting_level <> cur_s then
- pdf_error("ext4", "\pdfendlink ended up in different nesting level than \pdfstartlink");
-
- {N.B.: test for running link must be done on |link_node| and not |ref_link_node|,
- as |ref_link_node| can be set by |do_link| or |append_link| already}
-
- 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_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;
-
-@ For ``running'' annotations we must append a new node when the end of
-annotation is in other box than its start. The new created node is identical to
-corresponding whatsit node representing the start of annotation, but its
-|info| field is |max_halfword|. We set |info| field just before destroying the
-node, in order to use |flush_node_list| to do the job.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure append_link(parent_box: pointer; x, y: scaled; i: small_number); {append a new
-pdf annot to |pdf_link_list|}
-var p: pointer;
-begin
- pdfassert(type(parent_box) = hlist_node);
- p := copy_node(pdf_link_stack[i].link_node);
- pdf_link_stack[i].ref_link_node := p;
- subtype(p) := pdf_link_data_node; { this node is not a normal link node}
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_link_margin);
- pdf_create_obj(obj_type_others, 0);
- obj_annot_ptr(obj_ptr) := p;
- pdf_append_list(obj_ptr)(pdf_link_list);
-end;
-
-@ Threads are handled in similar way as link annotations.
-
-@<Declare procedures needed in |pdf_hlist_out|, |pdf_vlist_out|@>=
-procedure append_bead(p: pointer);
-var a, b, c, t: integer;
-begin
- if not is_shipping_page then
- pdf_error("ext4", "threads cannot be inside an XForm");
- t := get_obj(obj_type_thread, pdf_thread_id(p), pdf_thread_named_id(p));
- b := pdf_new_objnum;
- obj_bead_ptr(b) := pdf_get_mem(pdfmem_bead_size);
- obj_bead_page(b) := pdf_last_page;
- obj_bead_data(b) := p;
- if pdf_thread_attr(p) <> null then
- obj_bead_attr(b) := tokens_to_string(pdf_thread_attr(p))
- else
- obj_bead_attr(b) := 0;
- if obj_thread_first(t) = 0 then begin
- obj_thread_first(t) := b;
- obj_bead_next(b) := b;
- obj_bead_prev(b) := b;
- end
- else begin
- a := obj_thread_first(t);
- c := obj_bead_prev(a);
- obj_bead_prev(b) := c;
- obj_bead_next(b) := a;
- obj_bead_prev(a) := b;
- obj_bead_next(c) := b;
- end;
- pdf_append_list(b)(pdf_bead_list);
-end;
-
-procedure do_thread(p, parent_box: pointer; x, y: scaled);
-begin
- if doing_leaders then
- return;
- if subtype(p) = pdf_start_thread_node then begin
- pdf_thread_wd := pdf_width(p);
- pdf_thread_ht := pdf_height(p);
- pdf_thread_dp := pdf_depth(p);
- pdf_last_thread_id := pdf_thread_id(p);
- pdf_last_thread_named_id := (pdf_thread_named_id(p) > 0);
- if pdf_last_thread_named_id then
- add_token_ref(pdf_thread_id(p));
- pdf_thread_level := cur_s;
- end;
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_thread_margin);
- append_bead(p);
- last_thread := p;
-end;
-
-procedure append_thread(parent_box: pointer; x, y: scaled);
-var p: pointer;
-begin
- p := new_node(whatsit_node,pdf_thread_data_node);
- pdf_width(p) := pdf_thread_wd;
- pdf_height(p) := pdf_thread_ht;
- pdf_depth(p) := pdf_thread_dp;
- pdf_thread_attr(p) := null;
- pdf_thread_id(p) := pdf_last_thread_id;
- if pdf_last_thread_named_id then begin
- add_token_ref(pdf_thread_id(p));
- pdf_thread_named_id(p) := 1;
- end
- else
- pdf_thread_named_id(p) := 0;
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_thread_margin);
- append_bead(p);
- last_thread := p;
-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 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;
-end;
-
-function open_subentries(p: pointer): integer;
-var k, c: integer;
- l, r: integer;
-begin
- k := 0;
- if obj_outline_first(p) <> 0 then begin
- l := obj_outline_first(p);
- repeat
- incr(k);
- c := open_subentries(l);
- if obj_outline_count(l) > 0 then
- k := k + c;
- obj_outline_parent(l) := p;
- r := obj_outline_next(l);
- if r = 0 then
- obj_outline_last(p) := l;
- l := r;
- until l = 0;
- end;
- if obj_outline_count(p) > 0 then
- obj_outline_count(p) := k
- else
- obj_outline_count(p) := -k;
- open_subentries := k;
-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");
- if doing_leaders then
- return;
- k := get_obj(obj_type_dest, pdf_dest_id(p), pdf_dest_named_id(p));
- if obj_dest_ptr(k) <> null then begin
- warn_dest_dup(pdf_dest_id(p), pdf_dest_named_id(p),
- "ext4", "has been already used, duplicate ignored");
- return;
- end;
- obj_dest_ptr(k) := p;
- pdf_append_list(k)(pdf_dest_list);
- case pdf_dest_type(p) of
- pdf_dest_xyz:
- if matrixused then
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_dest_margin)
- else begin
- 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:
- if matrixused then
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_dest_margin)
- 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
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_dest_margin)
- 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;
- pdf_dest_fitr:
- set_rect_dimens(p, parent_box, x, y,
- pdf_width(p), pdf_height(p), pdf_depth(p),
- pdf_dest_margin);
- endcases;
-end;
-
-procedure output_form(p: pointer);
-begin
- 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);
-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;
-
-@ @<Output the whatsit node |p| in |pdf_vlist_out|@>=
-case subtype(p) of
-pdf_literal_node:
- pdf_out_literal(p);
-pdf_colorstack_node:
- pdf_out_colorstack(p);
-pdf_setmatrix_node:
- pdf_out_setmatrix(p);
-pdf_save_node:
- pdf_out_save;
-pdf_restore_node:
- pdf_out_restore;
-late_lua_node:
- do_late_lua(p);
-pdf_refobj_node:
- 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:
- @<Output a Form node in a vlist@>;
-pdf_refximage_node:
- @<Output an Image node in a vlist@>;
-pdf_annot_node:
- do_annot(p, this_box, left_edge, top_edge + height(this_box));
-pdf_start_link_node:
- pdf_error("ext4", "\pdfstartlink ended up in vlist");
-pdf_end_link_node:
- pdf_error("ext4", "\pdfendlink ended up in vlist");
-pdf_dest_node:
- do_dest(p, this_box, left_edge, top_edge + height(this_box));
-pdf_thread_node,
-pdf_start_thread_node:
- do_thread(p, this_box, left_edge, top_edge + height(this_box));
-pdf_end_thread_node:
- end_thread;
-pdf_save_pos_node:
- @<Save current position@>;
-special_node:
- pdf_special(p);
-othercases out_what(p);
-endcases
-
-@ @<Glob...@>=
-@!is_shipping_page: boolean; {set to |shipping_page| when |pdf_ship_out| starts}
-
-@ @<Output an Image node in a vlist@>=
-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
-
-@ @<Output a Form node in a vlist@>=
-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
-
-@ @<Output the whatsit node |p| in |pdf_hlist_out|@>=
-case subtype(p) of
-pdf_literal_node:
- pdf_out_literal(p);
-pdf_colorstack_node:
- pdf_out_colorstack(p);
-pdf_setmatrix_node:
- pdf_out_setmatrix(p);
-pdf_save_node:
- pdf_out_save;
-pdf_restore_node:
- pdf_out_restore;
-late_lua_node:
- do_late_lua(p);
-pdf_refobj_node:
- 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:
- @<Output a Form node in a hlist@>;
-pdf_refximage_node:
- @<Output an Image node in a hlist@>;
-pdf_annot_node:
- do_annot(p, this_box, left_edge, base_line);
-pdf_start_link_node:
- do_link(p, this_box, left_edge, base_line);
-pdf_end_link_node:
- end_link;
-pdf_dest_node:
- do_dest(p, this_box, left_edge, base_line);
-pdf_thread_node:
- do_thread(p, this_box, left_edge, base_line);
-pdf_start_thread_node:
- pdf_error("ext4", "\pdfstartthread ended up in hlist");
-pdf_end_thread_node:
- pdf_error("ext4", "\pdfendthread ended up in hlist");
-pdf_save_pos_node:
- @<Save current position@>;
-special_node:
- pdf_special(p);
-othercases if subtype(p)<>dir_node then out_what(p)
-else @<Output a reflection instruction if the direction has changed@>;
-endcases
-
-@ @<Output an Image node in a hlist@>=
-begin
- 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
-
-@ @<Output a Form node in a hlist@>=
-begin
- 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.
-The program has two modes of operation: (1)~In \TeX\ compatibility mode
-it fully deserves the name \TeX\ and there are neither extended features
-nor additional primitive commands. There are, however, a few
-modifications that would be legitimate in any implementation of \TeX\
-such as, e.g., preventing inadequate results of the glue to \.{DVI}
-unit conversion during |ship_out|. (2)~In extended mode there are
-additional primitive commands and the extended features of \eTeX\ are
-available.
-
-The distinction between these two modes of operation initially takes
-place when a `virgin' \.{eINITEX} starts without reading a format file.
-Later on the values of all \eTeX\ state variables are inherited when
-\.{eVIRTEX} (or \.{eINITEX}) reads a format file.
-
-The code below is designed to work for cases where `$|init|\ldots|tini|$'
-is a run-time switch.
-
-@<Enable \eTeX, if requested@>=
-@!init if format_ident=" (INITEX)" then
- begin no_new_control_sequence:=false;
- @<Generate all \eTeX\ primitives@>@;
- if buffer[loc]="*" then incr(loc);
- end;
-tini@;@/
-if not no_new_control_sequence then {just entered extended mode ?}
- no_new_control_sequence:=true@+else
-
-@ The \eTeX\ features available in extended mode are grouped into two
-categories: (1)~Some of them are permanently enabled and have no
-semantic effect as long as none of the additional primitives are
-executed. (2)~The remaining \eTeX\ features are optional and can be
-individually enabled and disabled. For each optional feature there is
-an \eTeX\ state variable named \.{\\...state}; the feature is enabled,
-resp.\ disabled by assigning a positive, resp.\ non-positive value to
-that integer.
-
-
-@d Aleph_version_code=Aleph_int {code for \.{\\Alephversion}}
-@d Omega_version_code=Aleph_int+1 {code for \.{\\Omegaversion}}
-@d Aleph_minor_version_code=Aleph_int+2 {code for \.{\\Alephminorversion}}
-@d Omega_minor_version_code=Aleph_int+3 {code for \.{\\Omegaminorversion}}
-@d eTeX_minor_version_code=Aleph_int+4 {code for \.{\\eTeXminorversion}}
-@d eTeX_version_code=eTeX_int {code for \.{\\eTeXversion}}
-@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)}
-
-@<Generate all \eTeX...@>=
-primitive_etex("lastnodetype",last_item,last_node_type_code,0);
-@!@:last_node_type_}{\.{\\lastnodetype} primitive@>
-primitive_aleph("Alephversion",last_item,Aleph_version_code,0);
-@!@:eTeX_version_}{\.{\\Alephversion} primitive@>
-primitive_aleph("Omegaversion",last_item,Omega_version_code,0);
-@!@:eTeX_version_}{\.{\\Omegaversion} primitive@>
-primitive_etex("eTeXversion",last_item,eTeX_version_code,0);
-@!@:eTeX_version_}{\.{\\eTeXversion} primitive@>
-primitive_aleph("Alephminorversion",last_item,Aleph_minor_version_code,0);
-@!@:eTeX_minor_version_}{\.{\\Alephminorversion} primitive@>
-primitive_aleph("Omegaminorversion",last_item,Omega_minor_version_code,0);
-@!@:eTeX_minor_version_}{\.{\\Omegaminorversion} primitive@>
-primitive_etex("eTeXminorversion",last_item,eTeX_minor_version_code,0);
-@!@:eTeX_minor_version_}{\.{\\eTeXminorversion} primitive@>
-primitive_aleph("Alephrevision",convert,Aleph_revision_code,0);@/
-@!@:eTeX_revision_}{\.{\\Alephrevision} primitive@>
-primitive_aleph("Omegarevision",convert,Omega_revision_code,0);@/
-@!@:eTeX_revision_}{\.{\\Omegarevision} primitive@>
-primitive_etex("eTeXrevision",convert,eTeX_revision_code,0);@/
-@!@:eTeX_revision_}{\.{\\eTeXrevision} primitive@>
-
-@ @<Cases for fetching an integer value@>=
-Aleph_version_code: cur_val:=Aleph_version;
-Omega_version_code: cur_val:=Omega_version;
-eTeX_version_code: cur_val:=eTeX_version;
-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;
-
-@ @<Cases of `Scan the argument for command |c|'@>=
-Aleph_revision_code: do_nothing;
-Omega_revision_code: do_nothing;
-eTeX_revision_code: do_nothing;
-
-@ @<Cases of `Print the result of command |c|'@>=
-Aleph_revision_code: print(Aleph_revision);
-Omega_revision_code: print(Omega_revision);
-eTeX_revision_code: print(eTeX_revision);
-
-@ First we implement the additional \eTeX\ parameters in the table of
-equivalents.
-
-@<Generate all \eTeX...@>=
-primitive_etex("everyeof",assign_toks,every_eof_loc,local_base);
-@!@:every_eof_}{\.{\\everyeof} primitive@>
-primitive_etex("tracingassigns",assign_int,int_base+tracing_assigns_code,int_base);@/
-@!@:tracing_assigns_}{\.{\\tracingassigns} primitive@>
-primitive_etex("tracinggroups",assign_int,int_base+tracing_groups_code,int_base);@/
-@!@:tracing_groups_}{\.{\\tracinggroups} primitive@>
-primitive_etex("tracingifs",assign_int,int_base+tracing_ifs_code,int_base);@/
-@!@:tracing_ifs_}{\.{\\tracingifs} primitive@>
-primitive_etex("tracingscantokens",assign_int,int_base+tracing_scan_tokens_code,int_base);@/
-@!@:tracing_scan_tokens_}{\.{\\tracingscantokens} primitive@>
-primitive_etex("tracingnesting",assign_int,int_base+tracing_nesting_code,int_base);@/
-@!@:tracing_nesting_}{\.{\\tracingnesting} primitive@>
-primitive_etex("predisplaydirection", assign_int,int_base+pre_display_direction_code,int_base);@/
-@!@:pre_display_direction_}{\.{\\predisplaydirection} primitive@>
-primitive_etex("lastlinefit",assign_int,int_base+last_line_fit_code,int_base);@/
-@!@:last_line_fit_}{\.{\\lastlinefit} primitive@>
-primitive_etex("savingvdiscards",assign_int,int_base+saving_vdiscards_code,int_base);@/
-@!@:saving_vdiscards_}{\.{\\savingvdiscards} primitive@>
-primitive_etex("savinghyphcodes",assign_int,int_base+saving_hyph_codes_code,int_base);@/
-@!@:saving_hyph_codes_}{\.{\\savinghyphcodes} 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)
-
-@ @<Cases for |print_param|@>=
-tracing_assigns_code:print_esc("tracingassigns");
-tracing_groups_code:print_esc("tracinggroups");
-tracing_ifs_code:print_esc("tracingifs");
-tracing_scan_tokens_code:print_esc("tracingscantokens");
-tracing_nesting_code:print_esc("tracingnesting");
-pre_display_direction_code:print_esc("predisplaydirection");
-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.
-
-@<Glob...@>=
-@!eof_seen : array[1..max_in_open] of boolean; {has eof been seen?}
-
-@ The |print_group| procedure prints the current level of grouping and
-the name corresponding to |cur_group|.
-
-@<Declare \eTeX\ procedures for tr...@>=
-procedure print_group(@!e:boolean);
-label exit;
-begin case cur_group of
- bottom_level: begin print("bottom level"); return;
- end;
- simple_group,semi_simple_group:
- begin if cur_group=semi_simple_group then print("semi ");
- print("simple");
- end;
- hbox_group,adjusted_hbox_group:
- begin if cur_group=adjusted_hbox_group then print("adjusted ");
- print("hbox");
- end;
- vbox_group: print("vbox");
- vtop_group: print("vtop");
- align_group,no_align_group:
- begin if cur_group=no_align_group then print("no ");
- print("align");
- end;
- output_group: print("output");
- disc_group: print("disc");
- insert_group: print("insert");
- vcenter_group: print("vcenter");
- math_group,math_choice_group,math_shift_group,math_left_group:
- begin print("math");
- if cur_group=math_choice_group then print(" choice")
- else if cur_group=math_shift_group then print(" shift")
- else if cur_group=math_left_group then print(" left");
- end;
- end; {there are no other cases}
-print(" group (level "); print_int(qo(cur_level)); print_char(")");
-if saved(-1)<>0 then
- begin if e then print(" entered at line ") else print(" at line ");
- print_int(saved(-1));
- end;
-exit:end;
-
-@ The |group_trace| procedure is called when a new level of grouping
-begins (|e=false|) or ends (|e=true|) with |saved(-1)| containing the
-line number.
-
-@<Declare \eTeX\ procedures for tr...@>=
-@!stat procedure group_trace(@!e:boolean);
-begin begin_diagnostic; print_char("{");
-if e then print("leaving ") else print("entering ");
-print_group(e); print_char("}"); end_diagnostic(false);
-end;
-tats
-
-@ The \.{\\currentgrouplevel} and \.{\\currentgrouptype} commands return
-the current level of grouping and the type of the current group
-respectively.
-
-@d current_group_level_code=eTeX_int+1 {code for \.{\\currentgrouplevel}}
-@d current_group_type_code=eTeX_int+2 {code for \.{\\currentgrouptype}}
-
-@<Generate all \eTeX...@>=
-primitive_etex("currentgrouplevel",last_item,current_group_level_code,0);
-@!@:current_group_level_}{\.{\\currentgrouplevel} primitive@>
-primitive_etex("currentgrouptype",last_item,current_group_type_code,0);
-@!@:current_group_type_}{\.{\\currentgrouptype} primitive@>
-
-@ @<Cases for fetching an integer value@>=
-current_group_level_code: cur_val:=cur_level-level_one;
-current_group_type_code: cur_val:=cur_group;
-
-@ The \.{\\currentiflevel}, \.{\\currentiftype}, and
-\.{\\currentifbranch} commands return the current level of conditionals
-and the type and branch of the current conditional.
-
-@d current_if_level_code=eTeX_int+3 {code for \.{\\currentiflevel}}
-@d current_if_type_code=eTeX_int+4 {code for \.{\\currentiftype}}
-@d current_if_branch_code=eTeX_int+5 {code for \.{\\currentifbranch}}
-
-@<Generate all \eTeX...@>=
-primitive_etex("currentiflevel",last_item,current_if_level_code,0);
-@!@:current_if_level_}{\.{\\currentiflevel} primitive@>
-primitive_etex("currentiftype",last_item,current_if_type_code,0);
-@!@:current_if_type_}{\.{\\currentiftype} primitive@>
-primitive_etex("currentifbranch",last_item,current_if_branch_code,0);
-@!@:current_if_branch_}{\.{\\currentifbranch} primitive@>
-
-@ @<Cases for fetching an integer value@>=
-current_if_level_code: begin q:=cond_ptr; cur_val:=0;
- while q<>null do
- begin incr(cur_val); q:=vlink(q);
- end;
- end;
-current_if_type_code: if cond_ptr=null then cur_val:=0
- else if cur_if<unless_code then cur_val:=cur_if+1
- else cur_val:=-(cur_if-unless_code+1);
-current_if_branch_code:
- if (if_limit=or_code)or(if_limit=else_code) then cur_val:=1
- else if if_limit=fi_code then cur_val:=-1
- else cur_val:=0;
-
-@ The \.{\\fontcharwd}, \.{\\fontcharht}, \.{\\fontchardp}, and
-\.{\\fontcharic} commands return information about a character in a
-font.
-
-@d font_char_wd_code=eTeX_dim {code for \.{\\fontcharwd}}
-@d font_char_ht_code=eTeX_dim+1 {code for \.{\\fontcharht}}
-@d font_char_dp_code=eTeX_dim+2 {code for \.{\\fontchardp}}
-@d font_char_ic_code=eTeX_dim+3 {code for \.{\\fontcharic}}
-
-@<Generate all \eTeX...@>=
-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_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_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_omega("charit",last_item,font_char_ic_code,0);
-primitive_etex("fontcharic",last_item,font_char_ic_code,0);
-@!@:font_char_ic_}{\.{\\fontcharic} primitive@>
-
-@ @<Cases for fetching a dimension value@>=
-font_char_wd_code,
-font_char_ht_code,
-font_char_dp_code,
-font_char_ic_code: begin scan_font_ident; q:=cur_val; scan_char_num;
- if char_exists(q,cur_val) then
- begin
- case m of
- font_char_wd_code: cur_val:=char_width(q,cur_val);
- font_char_ht_code: cur_val:=char_height(q,cur_val);
- font_char_dp_code: cur_val:=char_depth(q,cur_val);
- font_char_ic_code: cur_val:=char_italic(q,cur_val);
- end; {there are no other cases}
- end
- else cur_val:=0;
- end;
-
-@ The \.{\\parshapedimen}, \.{\\parshapeindent}, and \.{\\parshapelength}
-commands return the indent and length parameters of the current
-\.{\\parshape} specification.
-
-@d par_shape_length_code=eTeX_dim+4 {code for \.{\\parshapelength}}
-@d par_shape_indent_code=eTeX_dim+5 {code for \.{\\parshapeindent}}
-@d par_shape_dimen_code=eTeX_dim+6 {code for \.{\\parshapedimen}}
-
-@<Generate all \eTeX...@>=
-primitive_etex("parshapelength",last_item,par_shape_length_code,0);
-@!@:par_shape_length_}{\.{\\parshapelength} primitive@>
-primitive_etex("parshapeindent",last_item,par_shape_indent_code,0);
-@!@:par_shape_indent_}{\.{\\parshapeindent} primitive@>
-primitive_etex("parshapedimen",last_item,par_shape_dimen_code,0);
-@!@:par_shape_dimen_}{\.{\\parshapedimen} primitive@>
-
-@ @<Cases for fetching a dimension value@>=
-par_shape_length_code,
-par_shape_indent_code,
-par_shape_dimen_code: begin q:=cur_chr-par_shape_length_code; scan_int;
- if (par_shape_ptr=null)or(cur_val<=0) then cur_val:=0
- 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+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;
-
-@ The \.{\\showgroups} command displays all currently active grouping
-levels.
-
-@d show_groups=4 { \.{\\showgroups} }
-
-@<Generate all \eTeX...@>=
-primitive_etex("showgroups",xray,show_groups,0);
-@!@:show_groups_}{\.{\\showgroups} primitive@>
-
-@ @<Cases for |show_whatever|@>=
-show_groups: begin begin_diagnostic; show_save_groups;
- end;
-
-@ @<Types...@>=
-@!save_pointer=0..save_size; {index into |save_stack|}
-
-@ The modifications of \TeX\ required for the display produced by the
-|show_save_groups| procedure were first discussed by Donald~E. Knuth in
-{\sl TUGboat\/} {\bf 11}, 165--170 and 499--511, 1990.
-@^Knuth, Donald Ervin@>
-
-In order to understand a group type we also have to know its mode.
-Since unrestricted horizontal modes are not associated with grouping,
-they are skipped when traversing the semantic nest.
-
-@<Declare \eTeX\ procedures for use...@>=
-procedure show_save_groups;
-label found1,found2,found,done;
-var p:0..nest_size; {index into |nest|}
-@!m:-mmode..mmode; {mode}
-@!v:save_pointer; {saved value of |save_ptr|}
-@!l:quarterword; {saved value of |cur_level|}
-@!c:group_code; {saved value of |cur_group|}
-@!a:-1..1; {to keep track of alignments}
-@!i:integer;
-@!j:quarterword;
-@!s:str_number;
-begin p:=nest_ptr; nest[p]:=cur_list; {put the top level into the array}
-v:=save_ptr; l:=cur_level; c:=cur_group;
-save_ptr:=cur_boundary; decr(cur_level);@/
-a:=1; s:="";
-print_nl(""); print_ln;
-loop@+begin print_nl("### "); print_group(true);
- if cur_group=bottom_level then goto done;
- repeat m:=nest[p].mode_field;
- if p>0 then decr(p) else m:=vmode;
- until m<>hmode;
- print(" (");
- case cur_group of
- simple_group: begin incr(p); goto found2;
- end;
- hbox_group,adjusted_hbox_group: s:="hbox";
- vbox_group: s:="vbox";
- vtop_group: s:="vtop";
- align_group: if a=0 then
- begin if m=-vmode then s:="halign" else s:="valign";
- a:=1; goto found1;
- end
- else begin if a=1 then print("align entry") else print_esc("cr");
- if p>=a then p:=p-a;
- a:=0; goto found;
- end;
- no_align_group:
- begin incr(p); a:=-1; print_esc("noalign"); goto found2;
- end;
- output_group:
- begin print_esc("output"); goto found;
- end;
- math_group: goto found2;
- disc_group,math_choice_group:
- begin if cur_group=disc_group then print_esc("discretionary")
- else print_esc("mathchoice");
- for i:=1 to 3 do if i<=saved(-2) then print("{}");
- goto found2;
- end;
- insert_group:
- begin if saved(-2)=output_box then print_esc("vadjust")
- else begin print_esc("insert"); print_int(saved(-2));
- end;
- goto found2;
- end;
- vcenter_group: begin s:="vcenter"; goto found1;
- end;
- semi_simple_group: begin incr(p); print_esc("begingroup"); goto found;
- end;
- math_shift_group:
- begin if m=mmode then print_char("$")
- else if nest[p].mode_field=mmode then
- begin print_cmd_chr(eq_no,saved(-2)); goto found;
- end;
- print_char("$"); goto found;
- end;
- math_left_group:
- begin if subtype(nest[p+1].eTeX_aux_field)=left_noad_side then print_esc("left")
- else print_esc("middle");
- goto found;
- end;
- end; {there are no other cases}
- @<Show the box context@>;
- found1: print_esc(s); @<Show the box packaging info@>;
- found2: print_char("{");
- found: print_char(")"); decr(cur_level);
- cur_group:=save_level(save_ptr); save_ptr:=save_index(save_ptr)
- end;
-done: save_ptr:=v; cur_level:=l; cur_group:=c;
-end;
-
-@ @<Show the box packaging info@>=
-if saved(-2)<>0 then
- begin print_char(" ");
- if saved(-3)=exactly then print("to") else print("spread");
- print_scaled(saved(-2)); print("pt");
- end
-
-@ @<Show the box context@>=
-i:=saved(-4);
-if i<>0 then begin
- if i<box_flag then
- begin if abs(nest[p].mode_field)=vmode then j:=hmove else j:=vmove;
- if i>0 then print_cmd_chr(j,0) else print_cmd_chr(j,1);
- print_scaled(abs(i)); print("pt");
- end
- else if i<ship_out_flag then
- begin if i>=global_box_flag then
- begin print_esc("global"); i:=i-(global_box_flag-box_flag);
- end;
- print_esc("setbox"); print_int(i-box_flag); print_char("=");
- end
- else print_cmd_chr(leader_ship,i-(leader_flag-a_leaders));
- end
-
-@ The |scan_general_text| procedure is much like |scan_toks(false,false)|,
-but will be invoked via |expand|, i.e., recursively.
-@^recursion@>
-
-@<Declare \eTeX\ procedures for sc...@>=
-procedure@?scan_general_text; forward;@t\2@>
-
-@ The token list (balanced text) created by |scan_general_text| begins
-at |link(temp_token_head)| and ends at |cur_val|. (If |cur_val=temp_token_head|,
-the list is empty.)
-
-@<Declare \eTeX\ procedures for tok...@>=
-procedure scan_general_text;
-label found;
-var s:normal..absorbing; {to save |scanner_status|}
-@!w:pointer; {to save |warning_index|}
-@!d:pointer; {to save |def_ref|}
-@!p:pointer; {tail of the token list being built}
-@!q:pointer; {new node being added to the token list via |store_new_token|}
-@!unbalance:halfword; {number of unmatched left braces}
-begin s:=scanner_status; w:=warning_index; d:=def_ref;
-scanner_status:=absorbing; warning_index:=cur_cs;
-p:=get_avail; def_ref:=p; token_ref_count(def_ref):=0; p:=def_ref;
-scan_left_brace; {remove the compulsory left brace}
-unbalance:=1;
-loop@+ begin get_token;
- if cur_tok<right_brace_limit then begin
- if cur_cmd<right_brace then incr(unbalance)
- else begin decr(unbalance);
- if unbalance=0 then goto found;
- end;
- end;
- store_new_token(cur_tok);
- end;
-found: q:=link(def_ref); free_avail(def_ref); {discard reference count}
-if q=null then cur_val:=temp_token_head @+ else cur_val:=p;
-link(temp_token_head):=q;
-scanner_status:=s; warning_index:=w; def_ref:=d;
-end;
-
-@ The \.{\\showtokens} command displays a token list.
-
-@d show_tokens=5 { \.{\\showtokens} , must be odd! }
-
-@<Generate all \eTeX...@>=
-primitive_etex("showtokens",xray,show_tokens,0);
-@!@:show_tokens_}{\.{\\showtokens} primitive@>
-
-@ 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
-character tokens much as if the token list were written to a file. We
-use the fact that the command modifiers for \.{\\unexpanded} and
-\.{\\detokenize} are odd whereas those for \.{\\the} and \.{\\showthe}
-are even.
-
-@<Generate all \eTeX...@>=
-primitive_etex("unexpanded",the,1,0);@/
-@!@:unexpanded_}{\.{\\unexpanded} primitive@>
-primitive_etex("detokenize",the,show_tokens,0);@/
-@!@:detokenize_}{\.{\\detokenize} primitive@>
-
-@ @<Handle \.{\\unexpanded} or \.{\\detokenize} and |return|@>=
-if odd(cur_chr) then
- begin c:=cur_chr; scan_general_text;
- if c=1 then the_toks:=cur_val
- else begin old_setting:=selector; selector:=new_string; b:=pool_ptr;
- p:=get_avail; link(p):=link(temp_token_head);
- token_show(p); flush_list(p);
- selector:=old_setting; the_toks:=str_toks(b);
- end;
- return;
- end
-
-@ The \.{\\showifs} command displays all currently active conditionals.
-
-@d show_ifs=6 { \.{\\showifs} }
-
-@<Generate all \eTeX...@>=
-primitive_etex("showifs",xray,show_ifs,0);
-@!@:show_ifs_}{\.{\\showifs} primitive@>
-
-@
-@d print_if_line(#)==if #<>0 then
- begin print(" entered on line "); print_int(#);
- end
-
-@<Cases for |show_whatever|@>=
-show_ifs: begin begin_diagnostic; print_nl(""); print_ln;
- if cond_ptr=null then
- begin print_nl("### "); print("no active conditionals");
- end
- else begin p:=cond_ptr; n:=0;
- repeat incr(n); p:=vlink(p);@+until p=null;
- p:=cond_ptr; t:=cur_if; l:=if_line; m:=if_limit;
- repeat print_nl("### level "); print_int(n); print(": ");
- print_cmd_chr(if_test,t);
- if m=fi_code then print_esc("else");
- print_if_line(l);
- decr(n); t:=if_limit_subtype(p); l:=if_line_field(p); m:=if_limit_type(p); p:=vlink(p);
- until p=null;
- end;
- end;
-
-@ The \.{\\interactionmode} primitive allows to query and set the
-interaction mode.
-
-@<Generate all \eTeX...@>=
-primitive_etex("interactionmode",set_page_int,2,0);
-@!@:interaction_mode_}{\.{\\interactionmode} primitive@>
-
-@ @<Cases for `Fetch the |dead_cycles| or the |insert_penalties|'@>=
-else if m=2 then cur_val:=interaction
-
-@ @<Declare \eTeX\ procedures for use...@>=
-procedure@?new_interaction; forward;@t\2@>
-
-@ @<Cases for |alter_integer|@>=
-else if c=2 then
- begin if (cur_val<batch_mode)or(cur_val>error_stop_mode) then
- begin print_err("Bad interaction mode");
-@.Bad interaction mode@>
- help2("Modes are 0=batch, 1=nonstop, 2=scroll, and")@/
- ("3=errorstop. Proceed, and I'll ignore this case.");
- int_error(cur_val);
- end
- else begin cur_chr:=cur_val; new_interaction;
- end;
- end
-
-@ The |scan_tokens| feature of \eTeX\ defines the \.{\\scantokens}
-primitive.
-
-@<Generate all \eTeX...@>=
-primitive_etex("scantokens",input,2,0);
-@!@:scan_tokens_}{\.{\\scantokens} primitive@>
-primitive_luatex("scantextokens",input,3,0);
-@!@:scan_tex_tokens_}{\.{\\scantextokens} primitive@>
-
-@ @<Cases for |input|@>=
-else if cur_chr=2 then pseudo_start
-else if cur_chr=3 then begin pseudo_start; name := 19; end
-
-@ The global variable |pseudo_files| is used to maintain a stack of
-pseudo files. The |pseudo_lines| field of each pseudo file points to
-a linked list of variable size nodes representing lines not yet
-processed: the |subtype| field contains the size of this node,
-all the following words contain ASCII codes.
-
-@<Glob...@>=
-@!pseudo_files:pointer; {stack of pseudo files}
-
-@ @<Set init...@>=
-pseudo_files:=null;
-
-@ The |pseudo_start| procedure initiates reading from a pseudo file.
-
-@<Declare \eTeX\ procedures for ex...@>=
-procedure@?pseudo_start; forward;@t\2@>
-
-@ @<Declare \eTeX\ procedures for tok...@>=
-procedure pseudo_start;
-var old_setting:0..max_selector; {holds |selector| setting}
-@!s:str_number; {string to be converted into a pseudo file}
-@!p:pointer; {for list construction}
-begin scan_general_text;
-old_setting:=selector; selector:=new_string;
-token_show(temp_token_head); selector:=old_setting;
-flush_list(link(temp_token_head));
-str_room(1); s:=make_string;
-@<Convert string |s| into a new pseudo file@>;
-flush_string;
-@<Initiate input from new pseudo file@>;
-end;
-
-procedure pseudo_from_string;
-var @!s:str_number; {string to be converted into a pseudo file}
-@!p:pointer; {for list construction}
-begin
-s:=make_string;
-@<Convert string |s| into a new pseudo file@>;
-flush_string;
-@<Initiate input from new pseudo file@>;
-end;
-
-procedure lua_string_start;
-begin
-begin_file_reading; {set up |cur_file| and new level of input}
-line:=0; limit:=start; loc:=limit+1; {force line read}
-name:=21; luacstring_start(index);
-end;
-
-@ @<Convert string |s| into a new pseudo file@>=
-str_pool[pool_ptr]:=si(" ");
-p:=string_to_pseudo(str_start_macro(s),pool_ptr,new_line_char);
-vlink(p):=pseudo_files; pseudo_files:=p
-
-@ @<Initiate input from new pseudo file@>=
-begin_file_reading; {set up |cur_file| and new level of input}
-line:=0; limit:=start; loc:=limit+1; {force line read}
-if tracing_scan_tokens>0 then
- begin if term_offset>max_print_line-3 then print_ln
- else if (term_offset>0)or(file_offset>0) then print_char(" ");
- name:=20; print("( "); incr(open_parens); update_terminal;
- end
-else begin
- name:=18;
- @<Prepare pseudo file {\sl Sync\TeX} information@>;
-end
-
-@ Here we read a line from the current pseudo file into |buffer|.
-
-@d pseudo_lines(#)==vlink(#+1)
-
-@<Declare \eTeX\ procedures for tr...@>=
-function pseudo_input: boolean; {inputs the next line or returns |false|}
-var p:pointer; {current line from pseudo file}
-@!sz:integer; {size of node |p|}
-@!w:four_quarters; {four ASCII codes}
-@!r:pointer; {loop index}
-begin last:=first; {cf.\ Matthew 19\thinspace:\thinspace30}
-p:=pseudo_lines(pseudo_files);
-if p=null then begin pseudo_input:=false; end
-else begin pseudo_lines(pseudo_files):=vlink(p); sz:=subtype(p);
- if 4*sz-3>=buf_size-last then
- check_buffer_overflow(last+4*sz);
- last:=first;
- for r:=p+1 to p+sz-1 do
- begin w:=vmem(r).qqqq;
- buffer[last]:=w.b0; buffer[last+1]:=w.b1;
- buffer[last+2]:=w.b2; buffer[last+3]:=w.b3;
- last:=last+4;
- end;
- if last>=max_buf_stack then max_buf_stack:=last+1;
- while (last>first)and(buffer[last-1]=" ") do decr(last);
- flush_node(p);
- pseudo_input:=true;
- end;
-end;
-
-@ When we are done with a pseudo file we `close' it.
-
-@<Declare \eTeX\ procedures for tr...@>=
-procedure pseudo_close; {close the top level pseudo file}
-var p: pointer;
-begin p:=vlink(pseudo_files);
-flush_node(pseudo_files);
-pseudo_files:=p;
-end;
-
-@ @<Close the pseudo files@>=
-while pseudo_files<>null do pseudo_close; {flush pseudo files}
-
-@ @<Generate all \eTeX...@>=
-primitive_etex("readline",read_to_cs,1,0);@/
-@!@:read_line_}{\.{\\readline} primitive@>
-
-@ @<Handle \.{\\readline} and |goto done|@>=
-if j=1 then
- begin while loc<=limit do {current line not yet finished}
- begin cur_chr:=buffer[loc]; incr(loc);
- if cur_chr=" " then cur_tok:=space_token
- @+else cur_tok:=cur_chr+other_token;
- store_new_token(cur_tok);
- end;
- goto done;
- end
-
-@ Here we define the additional conditionals of \eTeX\ as well as the
-\.{\\unless} prefix.
-
-@d if_def_code=17 { `\.{\\ifdefined}' }
-@d if_cs_code=18 { `\.{\\ifcsname}' }
-@d if_font_char_code=19 { `\.{\\iffontchar}' }
-@d if_in_csname_code=20 { `\.{\\ifincsname}' }
-@d if_abs_num_code=22 { `\.{\\ifabsnum}' } { 21 = |if_primitive|}
-@d if_abs_dim_code=23 { `\.{\\ifabsdim}' }
-
-@<Generate all \eTeX...@>=
-primitive_etex("unless",expand_after,1,0);@/
-@!@:unless_}{\.{\\unless} primitive@>
-primitive_etex("ifdefined",if_test,if_def_code,0);
-@!@:if_defined_}{\.{\\ifdefined} primitive@>
-primitive_etex("ifcsname",if_test,if_cs_code,0);
-@!@:if_cs_name_}{\.{\\ifcsname} primitive@>
-primitive_etex("iffontchar",if_test,if_font_char_code,0);
-@!@:if_font_char_}{\.{\\iffontchar} primitive@>
-primitive_pdftex("ifincsname",if_test,if_in_csname_code,0);
-@!@:if_in_csname_}{\.{\\ifincsname} primitive@>
-primitive_luatex("ifabsnum",if_test,if_abs_num_code,0);
-@!@:if_abs_num_}{\.{\\ifabsnum} primitive@>
-primitive_luatex("ifabsdim",if_test,if_abs_dim_code,0);
-@!@:if_abs_dim_}{\.{\\ifabsdim} primitive@>
-primitive_pdftex("ifpdfabsnum",if_test,if_abs_num_code,0);
-@!@:if_abs_num_}{\.{\\ifpdfabsnum} primitive@>
-primitive_pdftex("ifpdfabsdim",if_test,if_abs_dim_code,0);
-@!@:if_abs_dim_}{\.{\\ifpdfabsdim} primitive@>
-
-@ The result of a boolean condition is reversed when the conditional is
-preceded by \.{\\unless}.
-
-@<Negate a boolean conditional and |goto reswitch|@>=
-begin get_token;
-if (cur_cmd=if_test)and(cur_chr<>if_case_code) then
- begin cur_chr:=cur_chr+unless_code; goto reswitch;
- end;
-print_err("You can't use `"); print_esc("unless"); print("' before `");
-@.You can't use \\unless...@>
-print_cmd_chr(cur_cmd,cur_chr); print_char("'");
-help1("Continue, and I'll forget that it ever happened.");
-back_error;
-end
-
-@ The conditional \.{\\ifdefined} tests if a control sequence is
-defined.
-
-We need to reset |scanner_status|, since \.{\\outer} control sequences
-are allowed, but we might be scanning a macro definition or preamble.
-
-@<Cases for |conditional|@>=
-if_def_code:begin save_scanner_status:=scanner_status;
- scanner_status:=normal;
- get_filtered_next; b:=(cur_cmd<>undefined_cs);
- scanner_status:=save_scanner_status;
- end;
-
-@ The conditional \.{\\ifcsname} is equivalent to \.{\{\\expandafter}
-\.{\}\\expandafter} \.{\\ifdefined} \.{\\csname}, except that no new
-control sequence will be entered into the hash table (once all tokens
-preceding the mandatory \.{\\endcsname} have been expanded).
-
-@<Cases for |conditional|@>=
-if_cs_code:begin n:=get_avail; p:=n; {head of the list of characters}
- b:=false;
- 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 begin
- if suppress_ifcsname_error then begin
- repeat get_x_token;
- until cur_cmd=end_cs_name;
- end
- else begin
- @<Complain about missing \.{\\endcsname}@>;
- @<Look up the characters of list |n| in the hash table, and set |cur_cs|@>;
- b:=(eq_type(cur_cs)<>undefined_cs);
- end;
- end
- else begin
- @<Look up the characters of list |n| in the hash table, and set |cur_cs|@>;
- b:=(eq_type(cur_cs)<>undefined_cs);
- end;
- flush_list(n);
- end;
-
-@ @<Look up the characters of list |n| in the hash table...@>=
-m:=first; p:=link(n);
-while p<>null do
- begin if m>=max_buf_stack then
- begin max_buf_stack:=m+4;
- if max_buf_stack=buf_size then
- check_buffer_overflow(max_buf_stack);
-@:TeX capacity exceeded buffer size}{\quad buffer size@>
- end;
- s := info(p) mod string_offset;
- if s <= @"7F then begin
- buffer[m]:=s; incr(m);
- end
- else if s<=@"7FF then begin
- buffer[m]:=@"C0 + s div @"40; incr(m);
- buffer[m]:=@"80 + s mod @"40; incr(m);
- end
- else if s<=@"FFFF then begin
- buffer[m]:=@"E0 + s div @"1000; incr(m);
- buffer[m]:=@"80 + (s mod @"1000) div @"40; incr(m);
- buffer[m]:=@"80 + (s mod @"1000) mod @"40; incr(m);
- end
- else begin
- buffer[m]:=@"F0 + s div @"40000; incr(m);
- buffer[m]:=@"80 + (s mod @"40000) div @"1000; incr(m);
- buffer[m]:=@"80 + ((s mod @"40000) mod @"1000) div @"40; incr(m);
- buffer[m]:=@"80 + ((s mod @"40000) mod @"1000) mod @"40; incr(m);
- end;
- p:=link(p);
- end;
-if m>first then
- cur_cs:=id_lookup(first,m-first) {|no_new_control_sequence| is |true|}
-else if m=first then cur_cs:=null_cs {the list is empty}
-
-@ The conditional \.{\\iffontchar} tests the existence of a character in
-a font.
-
-@<Cases for |conditional|@>=
-if_in_csname_code: b := is_in_csname;
-if_abs_dim_code, if_abs_num_code: begin
- if this_if=if_abs_num_code then scan_int@+else scan_normal_dimen;
- n:=cur_val;
- if n < 0 then negate(n);
- @<Get the next non-blank non-call...@>;
- if (cur_tok>=other_token+"<")and(cur_tok<=other_token+">") then
- r:=cur_tok-other_token
- else begin print_err("Missing = inserted for ");
- @.Missing = inserted@>
- print_cmd_chr(if_test,this_if);
- help1("I was expecting to see `<', `=', or `>'. Didn't.");
- back_error; r:="=";
- end;
- if this_if=if_abs_num_code then scan_int@+else scan_normal_dimen;
- if cur_val < 0 then negate(cur_val);
- case r of
- "<": b:=(n<cur_val);
- "=": b:=(n=cur_val);
- ">": b:=(n>cur_val);
- end;
- end;
-if_font_char_code:begin scan_font_ident; n:=cur_val; scan_char_num;
- b:=char_exists(n,cur_val);
- end;
-
-@ The |protected| feature of \eTeX\ defines the \.{\\protected} prefix
-command for macro definitions. Such macros are protected against
-expansions when lists of expanded tokens are built, e.g., for \.{\\edef}
-or during \.{\\write}.
-
-@<Generate all \eTeX...@>=
-primitive_etex("protected",prefix,8,0);
-@!@:protected_}{\.{\\protected} primitive@>
-
-@ The |get_x_or_protected| procedure is like |get_x_token| except that
-protected macros are not expanded.
-
-@<Declare \eTeX\ procedures for sc...@>=
-procedure get_x_or_protected; {sets |cur_cmd|, |cur_chr|, |cur_tok|,
- and expands non-protected macros}
-label exit;
-begin loop@+begin get_token;
- if cur_cmd<=max_command then return;
- if (cur_cmd>=call)and(cur_cmd<end_template) then
- if info(link(cur_chr))=protected_token then return;
- expand;
- end;
-exit:end;
-
-@ A group entered (or a conditional started) in one file may end in a
-different file. Such slight anomalies, although perfectly legitimate,
-may cause errors that are difficult to locate. In order to be able to
-give a warning message when such anomalies occur, \eTeX\ uses the
-|grp_stack| and |if_stack| arrays to record the initial |cur_boundary|
-and |cond_ptr| values for each input file.
-
-@<Glob...@>=
-@!grp_stack : array[0..max_in_open] of save_pointer; {initial |cur_boundary|}
-@!if_stack : array[0..max_in_open] of pointer; {initial |cond_ptr|}
-
-@ When a group ends that was apparently entered in a different input
-file, the |group_warning| procedure is invoked in order to update the
-|grp_stack|. If moreover \.{\\tracingnesting} is positive we want to
-give a warning message. The situation is, however, somewhat complicated
-by two facts: (1)~There may be |grp_stack| elements without a
-corresponding \.{\\input} file or \.{\\scantokens} pseudo file (e.g.,
-error insertions from the terminal); and (2)~the relevant information is
-recorded in the |name_field| of the |input_stack| only loosely
-synchronized with the |in_open| variable indexing |grp_stack|.
-
-@<Declare \eTeX\ procedures for tr...@>=
-procedure group_warning;
-var i:0..max_in_open; {index into |grp_stack|}
-@!w:boolean; {do we need a warning?}
-begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
- {store current state}
-i:=in_open; w:=false;
-while (grp_stack[i]=cur_boundary)and(i>0) do
- begin @<Set variable |w| to indicate if this case should be reported@>;
- grp_stack[i]:=save_index(save_ptr); decr(i);
- end;
-if w then
- begin print_nl("Warning: end of "); print_group(true);
-@.Warning: end of...@>
- print(" of a different file"); print_ln;
- if tracing_nesting>1 then show_context;
- if history=spotless then history:=warning_issued;
- end;
-end;
-
-@ This code scans the input stack in order to determine the type of the
-current input file.
-
-@<Set variable |w| to...@>=
-if tracing_nesting>0 then
- begin while (input_stack[base_ptr].state_field=token_list)or@|
- (input_stack[base_ptr].index_field>i) do decr(base_ptr);
- if input_stack[base_ptr].name_field>17 then w:=true;
- end
-
-@ When a conditional ends that was apparently started in a different
-input file, the |if_warning| procedure is invoked in order to update the
-|if_stack|. If moreover \.{\\tracingnesting} is positive we want to
-give a warning message (with the same complications as above).
-
-@<Declare \eTeX\ procedures for tr...@>=
-procedure if_warning;
-var i:0..max_in_open; {index into |if_stack|}
-@!w:boolean; {do we need a warning?}
-begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
- {store current state}
-i:=in_open; w:=false;
-while if_stack[i]=cond_ptr do
- begin @<Set variable |w| to...@>;
- if_stack[i]:=vlink(cond_ptr); decr(i);
- end;
-if w then
- begin print_nl("Warning: end of "); print_cmd_chr(if_test,cur_if);
-@.Warning: end of...@>
- print_if_line(if_line); print(" of a different file"); print_ln;
- if tracing_nesting>1 then show_context;
- if history=spotless then history:=warning_issued;
- end;
-end;
-
-@ Conversely, the |file_warning| procedure is invoked when a file ends
-and some groups entered or conditionals started while reading from that
-file are still incomplete.
-
-@<Declare \eTeX\ procedures for tr...@>=
-procedure file_warning;
-var p:pointer; {saved value of |save_ptr| or |cond_ptr|}
-@!l:quarterword; {saved value of |cur_level| or |if_limit|}
-@!c:quarterword; {saved value of |cur_group| or |cur_if|}
-@!i:integer; {saved value of |if_line|}
-begin
-p:=save_ptr; l:=cur_level; c:=cur_group; save_ptr:=cur_boundary;
-while grp_stack[in_open]<>save_ptr do
- begin decr(cur_level);
- print_nl("Warning: end of file when ");
-@.Warning: end of file when...@>
- print_group(true); print(" is incomplete");@/
- cur_group:=save_level(save_ptr); save_ptr:=save_index(save_ptr)
- end;
-save_ptr:=p; cur_level:=l; cur_group:=c; {restore old values}
-p:=cond_ptr; l:=if_limit; c:=cur_if; i:=if_line;
-while if_stack[in_open]<>cond_ptr do
- begin print_nl("Warning: end of file when ");
-@.Warning: end of file when...@>
- print_cmd_chr(if_test,cur_if);
- if if_limit=fi_code then print_esc("else");
- print_if_line(if_line); print(" is incomplete");@/
- if_line:=if_line_field(cond_ptr); cur_if:=if_limit_subtype(cond_ptr);
- if_limit:=if_limit_type(cond_ptr); cond_ptr:=vlink(cond_ptr);
- end;
-cond_ptr:=p; if_limit:=l; cur_if:=c; if_line:=i; {restore old values}
-print_ln;
-if tracing_nesting>1 then show_context;
-if history=spotless then history:=warning_issued;
-end;
-
-@ Here are the additional \eTeX\ primitives for expressions.
-
-@<Generate all \eTeX...@>=
-primitive_etex("numexpr",last_item,eTeX_expr-int_val+int_val,0);
-@!@:num_expr_}{\.{\\numexpr} primitive@>
-primitive_etex("dimexpr",last_item,eTeX_expr-int_val+dimen_val,0);
-@!@:dim_expr_}{\.{\\dimexpr} primitive@>
-primitive_etex("glueexpr",last_item,eTeX_expr-int_val+glue_val,0);
-@!@:glue_expr_}{\.{\\glueexpr} primitive@>
-primitive_etex("muexpr",last_item,eTeX_expr-int_val+mu_val,0);
-@!@:mu_expr_}{\.{\\muexpr} primitive@>
-
-@ 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
-already increased the reference count of a glue specification.
-
-@<Process an expression and |return|@>=
-begin if m<eTeX_mu then
- begin case m of
- @/@<Cases for fetching a glue value@>@/
- end; {there are no other cases}
- cur_val_level:=glue_val;
- end
-else if m<eTeX_expr then
- begin case m of
- @/@<Cases for fetching a mu value@>@/
- end; {there are no other cases}
- cur_val_level:=mu_val;
- end
-else begin cur_val_level:=m-eTeX_expr+int_val; scan_expr;
- end;
-while cur_val_level>level do
- begin if cur_val_level=glue_val then
- begin m:=cur_val; cur_val:=width(m); delete_glue_ref(m);
- end
- else if cur_val_level=mu_val then mu_error;
- decr(cur_val_level);
- end;
-if negative then begin
- if cur_val_level>=glue_val then
- begin m:=cur_val; cur_val:=new_spec(m); delete_glue_ref(m);
- @<Negate all three glue components of |cur_val|@>;
- end
- else negate(cur_val);
- end;
-return;
-end
-
-@ @<Declare \eTeX\ procedures for sc...@>=
-procedure@?scan_expr; forward;@t\2@>
-
-@ The |scan_expr| procedure scans and evaluates an expression.
-
-@<Declare procedures needed for expressions@>=
-@t\4@>@<Declare subprocedures for |scan_expr|@>
-procedure scan_expr; {scans and evaluates an expression}
-label restart, continue, found;
-var a,@!b:boolean; {saved values of |arith_error|}
-@!l:small_number; {type of expression}
-@!r:small_number; {state of expression so far}
-@!s:small_number; {state of term so far}
-@!o:small_number; {next operation or type of next factor}
-@!e:integer; {expression so far}
-@!t:integer; {term so far}
-@!f:integer; {current factor}
-@!n:integer; {numerator of combined multiplication and division}
-@!p:pointer; {top of expression stack}
-@!q:pointer; {for stack manipulations}
-begin l:=cur_val_level; a:=arith_error; b:=false; p:=null;
-@<Scan and evaluate an expression |e| of type |l|@>;
-if b then
- begin print_err("Arithmetic overflow");
-@.Arithmetic overflow@>
- help2("I can't evaluate this expression,")@/
- ("since the result is out of range.");
- error;
- if l>=glue_val then
- begin delete_glue_ref(e); e:=zero_glue; add_glue_ref(e);
- end
- else e:=0;
- end;
-arith_error:=a; cur_val:=e; cur_val_level:=l;
-end;
-
-@ Evaluating an expression is a recursive process: When the left
-parenthesis of a subexpression is scanned we descend to the next level
-of recursion; the previous level is resumed with the matching right
-parenthesis.
-
-@d expr_none=0 {\.( seen, or \.( $\langle\it expr\rangle$ \.) seen}
-@d expr_add=1 {\.( $\langle\it expr\rangle$ \.+ seen}
-@d expr_sub=2 {\.( $\langle\it expr\rangle$ \.- seen}
-@d expr_mult=3 {$\langle\it term\rangle$ \.* seen}
-@d expr_div=4 {$\langle\it term\rangle$ \./ seen}
-@d expr_scale=5 {$\langle\it term\rangle$ \.*
- $\langle\it factor\rangle$ \./ seen}
-
-@<Scan and eval...@>=
-restart: r:=expr_none; e:=0; s:=expr_none; t:=0; n:=0;
-continue: if s=expr_none then o:=l@+else o:=int_val;
-@<Scan a factor |f| of type |o| or start a subexpression@>;
-found: @<Scan the next operator and set |o|@>;
-arith_error:=b;
-@<Make sure that |f| is in the proper range@>;
-case s of @<Cases for evaluation of the current term@>@;
-end; {there are no other cases}
-if o>expr_sub then s:=o@+else @<Evaluate the current expression@>;
-b:=arith_error;
-if o<>expr_none then goto continue;
-if p<>null then @<Pop the expression stack and |goto found|@>
-
-@ @<Scan the next op...@>=
-@<Get the next non-blank non-call token@>;
-if cur_tok=other_token+"+" then o:=expr_add
-else if cur_tok=other_token+"-" then o:=expr_sub
-else if cur_tok=other_token+"*" then o:=expr_mult
-else if cur_tok=other_token+"/" then o:=expr_div
-else begin o:=expr_none;
- if p=null then
- begin if cur_cmd<>relax then back_input;
- end
- else if cur_tok<>other_token+")" then
- begin print_err("Missing ) inserted for expression");
-@.Missing ) inserted@>
- help1("I was expecting to see `+', `-', `*', `/', or `)'. Didn't.");
- back_error;
- end;
- end
-
-@ @<Scan a factor...@>=
-@<Get the next non-blank non-call token@>;
-if cur_tok=other_token+"(" then
- @<Push the expression stack and |goto restart|@>;
-back_input;
-if (o=int_val)or(o=attr_val) then scan_int
-else if o=dimen_val then scan_normal_dimen
-else if o=glue_val then scan_normal_glue
-else scan_mu_glue;
-f:=cur_val
-
-@ @<Declare \eTeX\ procedures for sc...@>=
-procedure@?scan_normal_glue; forward;@t\2@>@/
-procedure@?scan_mu_glue; forward;@t\2@>
-
-@ Here we declare to trivial procedures in order to avoid mutually
-recursive procedures with parameters.
-
-@<Declare procedures needed for expressions@>=
-procedure scan_normal_glue;
-begin scan_glue(glue_val);
-end;
-@#
-procedure scan_mu_glue;
-begin scan_glue(mu_val);
-end;
-
-@ Parenthesized subexpressions can be inside expressions, and this
-nesting has a stack. Seven local variables represent the top of the
-expression stack: |p| points to pushed-down entries, if any; |l|
-specifies the type of expression currently beeing evaluated; |e| is the
-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_type(#)==type(#+1)
-@d expr_state(#)==subtype(#+1)
-@d expr_e_field(#)==vlink(#+1) {saved expression so far}
-@d expr_t_field(#)==vlink(#+2) {saved term so far}
-@d expr_n_field(#)==vinfo(#+2) {saved numerator}
-
-@<Push the expression...@>=
-begin q:=new_node(expr_node,0); vlink(q):=p;
-expr_type(q):=l; expr_state(q):=4*s+r;
-expr_e_field(q):=e; expr_t_field(q):=t; expr_n_field(q):=n;
-p:=q; l:=o; goto restart;
-end
-
-@ @<Pop the expression...@>=
-begin f:=e; q:=p;
-e:=expr_e_field(q); t:=expr_t_field(q); n:=expr_n_field(q);
-s:=expr_state(q) div 4; r:=expr_state(q) mod 4;
-l:=expr_type(q); p:=vlink(q); flush_node(q);
-goto found;
-end
-
-@ We want to make sure that each term and (intermediate) result is in
-the proper range. Integer values must not exceed |infinity|
-($2^{31}-1$) in absolute value, dimensions must not exceed |max_dimen|
-($2^{30}-1$). We avoid the absolute value of an integer, because this
-might fail for the value $-2^{31}$ using 32-bit arithmetic.
-
-@d num_error(#)== {clear a number or dimension and set |arith_error|}
- begin arith_error:=true; #:=0;
- end
-@d glue_error(#)== {clear a glue spec and set |arith_error|}
- begin arith_error:=true; delete_glue_ref(#); #:=new_spec(zero_glue);
- end
-
-@<Make sure that |f|...@>=
-if ((l=int_val)or(l=attr_val))or(s>expr_sub) then
- begin if (f>infinity)or(f<-infinity) then num_error(f);
- end
-else if l=dimen_val then
- begin if abs(f)>max_dimen then num_error(f);
- end
-else begin if (abs(width(f))>max_dimen)or@|
- (abs(stretch(f))>max_dimen)or@|
- (abs(shrink(f))>max_dimen) then glue_error(f);
- end
-
-@ Applying the factor |f| to the partial term |t| (with the operator
-|s|) is delayed until the next operator |o| has been scanned. Here we
-handle the first factor of a partial term. A glue spec has to be copied
-unless the next operator is a right parenthesis; this allows us later on
-to simply modify the glue components.
-
-@d normalize_glue(#)==
- if stretch(#)=0 then stretch_order(#):=normal;
- if shrink(#)=0 then shrink_order(#):=normal
-
-@<Cases for evaluation of the current term@>=
-expr_none: if (l>=glue_val)and(o<>expr_none) then
- begin t:=new_spec(f); delete_glue_ref(f); normalize_glue(t);
- end
- else t:=f;
-
-@ When a term |t| has been completed it is copied to, added to, or
-subtracted from the expression |e|.
-
-@d expr_add_sub(#)==add_or_sub(#,r=expr_sub)
-@d expr_a(#)==expr_add_sub(#,max_dimen)
-
-@<Evaluate the current expression@>=
-begin s:=expr_none;
-if r=expr_none then e:=t
-else if (l=int_val)or(l=attr_val) then e:=expr_add_sub(e,t,infinity)
-else if l=dimen_val then e:=expr_a(e,t)
-else @<Compute the sum or difference of two glue specs@>;
-r:=o;
-end
-
-@ The function |add_or_sub(x,y,max_answer,negative)| computes the sum
-(for |negative=false|) or difference (for |negative=true|) of |x| and
-|y|, provided the absolute value of the result does not exceed
-|max_answer|.
-
-@<Declare subprocedures for |scan_expr|@>=
-function add_or_sub(@!x,@!y,@!max_answer:integer;@!negative:boolean):integer;
-var a:integer; {the answer}
-begin if negative then negate(y);
-if x>=0 then
- if y<=max_answer-x then a:=x+y@+else num_error(a)
-else if y>=-max_answer-x then a:=x+y@+else num_error(a);
-add_or_sub:=a;
-end;
-
-@ We know that |stretch_order(e)>normal| implies |stretch(e)<>0| and
-|shrink_order(e)>normal| implies |shrink(e)<>0|.
-
-@<Compute the sum or diff...@>=
-begin width(e):=expr_a(width(e),width(t));
-if stretch_order(e)=stretch_order(t) then
- stretch(e):=expr_a(stretch(e),stretch(t))
-else if (stretch_order(e)<stretch_order(t))and(stretch(t)<>0) then
- begin stretch(e):=stretch(t); stretch_order(e):=stretch_order(t);
- end;
-if shrink_order(e)=shrink_order(t) then
- shrink(e):=expr_a(shrink(e),shrink(t))
-else if (shrink_order(e)<shrink_order(t))and(shrink(t)<>0) then
- begin shrink(e):=shrink(t); shrink_order(e):=shrink_order(t);
- end;
-delete_glue_ref(t); normalize_glue(e);
-end
-
-@ If a multiplication is followed by a division, the two operations are
-combined into a `scaling' operation. Otherwise the term |t| is
-multiplied by the factor |f|.
-
-@d expr_m(#)==#:=nx_plus_y(#,f,0)
-
-@<Cases for evaluation of the current term@>=
-expr_mult: if o=expr_div then
- begin n:=f; o:=expr_scale;
- end
- else if (l=int_val)or(l=attr_val) then t:=mult_integers(t,f)
- else if l=dimen_val then expr_m(t)
- else begin expr_m(width(t)); expr_m(stretch(t)); expr_m(shrink(t));
- end;
-
-@ Here we divide the term |t| by the factor |f|.
-
-@d expr_d(#)==#:=quotient(#,f)
-
-@<Cases for evaluation of the current term@>=
-expr_div: if l<glue_val then expr_d(t)
- else begin expr_d(width(t)); expr_d(stretch(t)); expr_d(shrink(t));
- end;
-
-@ The function |quotient(n,d)| computes the rounded quotient
-$q=\lfloor n/d+{1\over2}\rfloor$, when $n$ and $d$ are positive.
-
-@<Declare subprocedures for |scan_expr|@>=
-function quotient(@!n,@!d:integer):integer;
-var negative:boolean; {should the answer be negated?}
-@!a:integer; {the answer}
-begin if d=0 then num_error(a)
-else begin if d>0 then negative:=false
- else begin negate(d); negative:=true;
- end;
- if n<0 then
- begin negate(n); negative:=not negative;
- end;
- a:=n div d; n:=n-a*d; d:=n-d; {avoid certain compiler optimizations!}
- if d+n>=0 then incr(a);
- if negative then negate(a);
- end;
-quotient:=a;
-end;
-
-@ Here the term |t| is multiplied by the quotient $n/f$.
-
-@d expr_s(#)==#:=fract(#,n,f,max_dimen)
-
-@<Cases for evaluation of the current term@>=
-expr_scale: if (l=int_val)or(l=attr_val) then t:=fract(t,n,f,infinity)
- else if l=dimen_val then expr_s(t)
- else begin expr_s(width(t)); expr_s(stretch(t)); expr_s(shrink(t));
- end;
-
-@ Finally, the function |fract(x,n,d,max_answer)| computes the integer
-$q=\lfloor xn/d+{1\over2}\rfloor$, when $x$, $n$, and $d$ are positive
-and the result does not exceed |max_answer|. We can't use floating
-point arithmetic since the routine must produce identical results in all
-cases; and it would be too dangerous to multiply by~|n| and then divide
-by~|d|, in separate operations, since overflow might well occur. Hence
-this subroutine simulates double precision arithmetic, somewhat
-analogous to \MF's |make_fraction| and |take_fraction| routines.
-
-@d too_big=88 {go here when the result is too big}
-
-@<Declare subprocedures for |scan_expr|@>=
-function fract(@!x,@!n,@!d,@!max_answer:integer):integer;
-label found, found1, too_big, done;
-var negative:boolean; {should the answer be negated?}
-@!a:integer; {the answer}
-@!f:integer; {a proper fraction}
-@!h:integer; {smallest integer such that |2*h>=d|}
-@!r:integer; {intermediate remainder}
-@!t:integer; {temp variable}
-begin if d=0 then goto too_big;
-a:=0;
-if d>0 then negative:=false
-else begin negate(d); negative:=true;
- end;
-if x<0 then
- begin negate(x); negative:=not negative;
- end
-else if x=0 then goto done;
-if n<0 then
- begin negate(n); negative:=not negative;
- end;
-t:=n div d;
-if t>max_answer div x then goto too_big;
-a:=t*x; n:=n-t*d;
-if n=0 then goto found;
-t:=x div d;
-if t>(max_answer-a) div n then goto too_big;
-a:=a+t*n; x:=x-t*d;
-if x=0 then goto found;
-if x<n then
- begin t:=x; x:=n; n:=t;
- end; {now |0<n<=x<d|}
-@<Compute \(f)$f=\lfloor xn/d+{1\over2}\rfloor$@>@;
-if f>(max_answer-a) then goto too_big;
-a:=a+f;
-found: if negative then negate(a);
-goto done;
-too_big: num_error(a);
-done: fract:=a;
-end;
-
-@ The loop here preserves the following invariant relations
-between |f|, |x|, |n|, and~|r|:
-(i)~$f+\lfloor(xn+(r+d))/d\rfloor=\lfloor x_0n_0/d+{1\over2}\rfloor$;
-(ii)~|-d<=r<0<n<=x<d|, where $x_0$, $n_0$ are the original values of~$x$
-and $n$.
-
-Notice that the computation specifies |(x-d)+x| instead of |(x+x)-d|,
-because the latter could overflow.
-
-@<Compute \(f)$f=\lfloor xn/d+{1\over2}\rfloor$@>=
-f:=0; r:=(d div 2)-d; h:=-r;
-loop@+begin if odd(n) then
- begin r:=r+x;
- if r>=0 then
- begin r:=r-d; incr(f);
- end;
- end;
- n:=n div 2;
- if n=0 then goto found1;
- if x<h then x:=x+x
- else begin t:=x-d; x:=t+x; f:=f+n;
- if x<n then
- begin if x=0 then goto found1;
- t:=x; x:=n; n:=t;
- end;
- end;
- end;
-found1:
-
-@ The \.{\\gluestretch}, \.{\\glueshrink}, \.{\\gluestretchorder}, and
-\.{\\glueshrinkorder} commands return the stretch and shrink components
-and their orders of ``infinity'' of a glue specification.
-
-@d glue_stretch_order_code=eTeX_int+6 {code for \.{\\gluestretchorder}}
-@d glue_shrink_order_code=eTeX_int+7 {code for \.{\\glueshrinkorder}}
-@d glue_stretch_code=eTeX_dim+7 {code for \.{\\gluestretch}}
-@d glue_shrink_code=eTeX_dim+8 {code for \.{\\glueshrink}}
-
-@<Generate all \eTeX...@>=
-primitive_etex("gluestretchorder",last_item,glue_stretch_order_code,0);
-@!@:glue_stretch_order_}{\.{\\gluestretchorder} primitive@>
-primitive_etex("glueshrinkorder",last_item,glue_shrink_order_code,0);
-@!@:glue_shrink_order_}{\.{\\glueshrinkorder} primitive@>
-primitive_etex("gluestretch",last_item,glue_stretch_code,0);
-@!@:glue_stretch_}{\.{\\gluestretch} primitive@>
-primitive_etex("glueshrink",last_item,glue_shrink_code,0);
-@!@:glue_shrink_}{\.{\\glueshrink} primitive@>
-
-@ @<Cases for fetching an integer value@>=
-glue_stretch_order_code, glue_shrink_order_code:
- begin scan_normal_glue; q:=cur_val;
- if m=glue_stretch_order_code then cur_val:=stretch_order(q)
- else cur_val:=shrink_order(q);
- delete_glue_ref(q);
- end;
-
-@ @<Cases for fetching a dimension value@>=
-glue_stretch_code, glue_shrink_code:
- begin scan_normal_glue; q:=cur_val;
- if m=glue_stretch_code then cur_val:=stretch(q)
- else cur_val:=shrink(q);
- delete_glue_ref(q);
- end;
-
-@ The \.{\\mutoglue} and \.{\\gluetomu} commands convert ``math'' glue
-into normal glue and vice versa; they allow to manipulate math glue with
-\.{\\gluestretch} etc.
-
-@d mu_to_glue_code=eTeX_glue {code for \.{\\mutoglue}}
-@d glue_to_mu_code=eTeX_mu {code for \.{\\gluetomu}}
-
-@<Generate all \eTeX...@>=
-primitive_etex("mutoglue",last_item,mu_to_glue_code,0);
-@!@:mu_to_glue_}{\.{\\mutoglue} primitive@>
-primitive_etex("gluetomu",last_item,glue_to_mu_code,0);
-@!@:glue_to_mu_}{\.{\\gluetomu} primitive@>
-
-@ @<Cases for fetching a glue value@>=
-mu_to_glue_code: scan_mu_glue;
-
-@ @<Cases for fetching a mu value@>=
-glue_to_mu_code: scan_normal_glue;
-
-@ @<Glob...@>=
-@!last_line_fill:pointer; {the |par_fill_skip| glue node of the new paragraph}
-
-@ When |saving_vdiscards| is positive then the glue, kern, and penalty
-nodes removed by the page builder or by \.{\\vsplit} from the top of a
-vertical list are saved in special lists instead of being discarded.
-
-@d tail_page_disc==disc_ptr[copy_code] {last item removed by page builder}
-@d page_disc==disc_ptr[last_box_code] {first item removed by page builder}
-@d split_disc==disc_ptr[vsplit_code] {first item removed by \.{\\vsplit}}
-
-@<Glob...@>=
-@!disc_ptr:array[copy_code..vsplit_code] of pointer; {list pointers}
-
-@ @<Set init...@>=
-page_disc:=null; split_disc:=null;
-
-@ The \.{\\pagediscards} and \.{\\splitdiscards} commands share the
-command code |un_vbox| with \.{\\unvbox} and \.{\\unvcopy}, they are
-distinguished by their |chr_code| values |last_box_code| and
-|vsplit_code|. These |chr_code| values are larger than |box_code| and
-|copy_code|.
-
-@<Generate all \eTeX...@>=
-primitive_etex("pagediscards",un_vbox,last_box_code,0);@/
-@!@:page_discards_}{\.{\\pagediscards} primitive@>
-primitive_etex("splitdiscards",un_vbox,vsplit_code,0);@/
-@!@:split_discards_}{\.{\\splitdiscards} primitive@>
-
-@ @<Handle saved items and |goto done|@>=
-begin vlink(tail):=disc_ptr[cur_chr]; disc_ptr[cur_chr]:=null;
-goto done;
-end
-
-@ The \.{\\interlinepenalties}, \.{\\clubpenalties}, \.{\\widowpenalties},
-and \.{\\displaywidowpenalties} commands allow to define arrays of
-penalty values to be used instead of the corresponding single values.
-
-@d inter_line_penalties_ptr==equiv(inter_line_penalties_loc)
-@d club_penalties_ptr==equiv(club_penalties_loc)
-@d widow_penalties_ptr==equiv(widow_penalties_loc)
-@d display_widow_penalties_ptr==equiv(display_widow_penalties_loc)
-
-@<Generate all \eTeX...@>=
-primitive_etex("interlinepenalties",set_etex_shape,inter_line_penalties_loc,etex_pen_base);@/
-@!@:inter_line_penalties_}{\.{\\interlinepenalties} primitive@>
-primitive_etex("clubpenalties",set_etex_shape,club_penalties_loc,etex_pen_base);@/
-@!@:club_penalties_}{\.{\\clubpenalties} primitive@>
-primitive_etex("widowpenalties",set_etex_shape,widow_penalties_loc,etex_pen_base);@/
-@!@:widow_penalties_}{\.{\\widowpenalties} primitive@>
-primitive_etex("displaywidowpenalties",set_etex_shape,display_widow_penalties_loc,etex_pen_base);@/
-@!@:display_widow_penalties_}{\.{\\displaywidowpenalties} primitive@>
-
-@ @<Fetch a penalties array element@>=
-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
-
-@<Show the meaning of a mark node@>=
-if (cur_cmd=top_bot_mark)and(cur_chr<marks_code) then
- begin print_char(":"); print_ln;
- case cur_chr of
- first_mark_code: token_show(first_mark(0));
- bot_mark_code: token_show(bot_mark(0));
- split_first_mark_code: token_show(split_first_mark(0));
- split_bot_mark_code: token_show(split_bot_mark(0));
- othercases token_show(top_mark(0));
- endcases;
-end
-
-
-@ The lua interface needs some extra pascal functions. The functions
-themselves are quite boring, but they are handy because otherwise this
-internal stuff has to be accessed from C directly, where lots of the
-pascal defines are not available.
-
-@p function get_tex_dimen_register (j:integer):scaled;
-begin
- get_tex_dimen_register := dimen(j);
-end;
-
-function set_tex_dimen_register (j:integer;v:scaled):integer;
-var a:small_number;
-begin {return non-nil for error}
-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);
-end;
-
-function set_tex_count_register (j:integer;v:scaled):integer;
-var a:small_number;
-begin {return non-nil for error}
- 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;
-begin
- get_tex_attribute_register := attribute(j);
-end;
-
-function set_tex_attribute_register (j:integer;v:scaled):integer;
-var a:small_number;
-begin {return non-nil for error}
-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;
-
-function get_tex_toks_register (j:integer):str_number;
-var s:str_number;
-begin
- s:="";
- if toks(j) <> min_halfword then begin
- s := tokens_to_string(toks(j));
- end;
- get_tex_toks_register := s;
-end;
-
-function set_tex_toks_register (j:integer;s:str_number):integer;
-var s_pool_ptr:pool_pointer;
- ref:pointer;
- a:small_number;
- junk:pointer;
-begin
- set_tex_toks_register := 0;
- s_pool_ptr := pool_ptr;
- pool_ptr := str_start_macro(s+1);
- ref := get_avail;
- junk := str_toks(str_start_macro(s));
- pool_ptr := s_pool_ptr;
- token_ref_count(ref) := 0;
- link(ref) := link(temp_token_head);
- if global_defs>0 then a:=4 else a:=0;
- define(j+toks_base,call,ref);
- flush_str(s);
-end;
-
-function get_tex_box_register (j:integer):integer;
-begin
- get_tex_box_register := box(j);
-end;
-
-function set_tex_box_register (j:integer;v:scaled):integer;
-var a:small_number;
-begin {return non-nil for error}
-if global_defs>0 then a:=4 else a:=0;
-define(j+box_base,box_ref,v);
-set_tex_box_register := 0;
-end;
-
-
-function get_tex_box_width (j:integer):scaled;
-var q:pointer;
-begin
- q := box(j);
- get_tex_box_width := 0;
- if q <> null then
- get_tex_box_width := width(q);
-end;
-
-function set_tex_box_width (j:integer;v:scaled):integer;
-var q:pointer;
-begin
- q := box(j);
- set_tex_box_width := 0;
- if q <> null then
- width(q) := v
- else
- set_tex_box_width := 1;
-end;
-
-function get_tex_box_height (j:integer):scaled;
-var q:pointer;
-begin
- q := box(j);
- get_tex_box_height := 0;
- if q <> null then
- get_tex_box_height := height(q);
-end;
-
-function set_tex_box_height (j:integer;v:scaled):integer;
-var q:pointer;
-begin
- q := box(j);
- set_tex_box_height := 0;
- if q <> null then
- height(q) := v
- else
- set_tex_box_height := 1;
-end;
-
-function get_tex_box_depth (j:integer):scaled;
-var q:pointer;
-begin
- q := box(j);
- get_tex_box_depth := 0;
- if q <> null then
- get_tex_box_depth := depth(q);
-end;
-
-function set_tex_box_depth (j:integer;v:scaled):integer;
-var q:pointer;
-begin
- q := box(j);
- set_tex_box_depth := 0;
- if q <> null then
- depth(q) := v
- else
- set_tex_box_depth := 1;
-end;
-
-function get_cur_v: integer;
-begin
- get_cur_v := cur_page_size.v - cur.v;
-end;
-
-function get_cur_h: integer;
-begin
- get_cur_h := cur.h;
-end;
-
-@* \[54] $\Omega$ changes.
-
-@ Here we do the main work required for reading and interpreting
- $\Omega$ Compiled Translation Processes.
-
-@ Here are all the instructions in our mini-assembler.
-@d otp_right_output=1
-@d otp_right_num=2
-@d otp_right_char=3
-@d otp_right_lchar=4
-@d otp_right_some=5
-
-@d otp_pback_output=6
-@d otp_pback_num=7
-@d otp_pback_char=8
-@d otp_pback_lchar=9
-@d otp_pback_some=10
-
-@d otp_add=11
-@d otp_sub=12
-@d otp_mult=13
-@d otp_div=14
-@d otp_mod=15
-@d otp_lookup=16
-@d otp_push_num=17
-@d otp_push_char=18
-@d otp_push_lchar=19
-
-@d otp_state_change=20
-@d otp_state_push=21
-@d otp_state_pop=22
-
-@d otp_left_start=23
-@d otp_left_return=24
-@d otp_left_backup=25
-
-@d otp_goto=26
-@d otp_goto_ne=27
-@d otp_goto_eq=28
-@d otp_goto_lt=29
-@d otp_goto_le=30
-@d otp_goto_gt=31
-@d otp_goto_ge=32
-@d otp_goto_no_advance=33
-@d otp_goto_beg=34
-@d otp_goto_end=35
-
-@d otp_stop=36
-
-@
-@<Glob...@>=
-@!otp_init_input_start:halfword;
-@!otp_init_input_last:halfword;
-@!otp_init_input_end:halfword;
-@!otp_i:halfword;
-@!otp_init_input_buf:array[0..20000] of quarterword;
-
-@!otp_input_start:halfword;
-@!otp_input_last:halfword;
-@!otp_input_end:halfword;
-@!otp_input_buf:array[0..20000] of quarterword;
-
-@!otp_output_end:halfword;
-@!otp_output_buf:array[0..20000] of quarterword;
-
-@!otp_stack_used:halfword;
-@!otp_stack_last:halfword;
-@!otp_stack_new:halfword;
-@!otp_stack_buf:array[0..1000] of quarterword;
-
-@!otp_pc:halfword;
-
-@!otp_calc_ptr:halfword;
-@!otp_calcs:array[0..1000] of halfword;
-@!otp_state_ptr:halfword;
-@!otp_states:array[0..1000] of halfword;
-
-@!otp_input_char:halfword;
-@!otp_calculated_char:halfword;
-@!otp_no_input_chars:halfword;
-
-@!otp_instruction:halfword;
-@!otp_instr:halfword;
-@!otp_arg:halfword;
-@!otp_first_arg:halfword;
-@!otp_second_arg:halfword;
-
-@!otp_input_ocp:halfword;
-@!otp_counter:halfword;
-
-@!otp_finished:boolean;
-@!otp_ext_str:integer;
-@!otp_ext_str_arg:integer;
-@!otp_ext_i:integer;
-
-@
-@<Initialize table...@>=
-
-@
-@<Create a buffer with character |cur_chr| and the following
- characters (if~any) and then apply the current active OCP filter
- to this buffer@>=
-begin
-@<Read in the buffer for treatment@>;
-@<Apply the OCP to the input buffer@>;
-@<Place the output buffer back on the stream@>;
-goto big_switch;
-end;
-
-@ The OTP input buffer is an array of 16-bit values.
-In the future, the range |@"D800| \dots |@"DFFF| will be used for
-surrogate pairs, so it cannot be used for simple 16-bit values
-like it is in Omega, so a future incompatibility with Aleph is
-unavoidable.
-
-@<Read in the buffer for treatment@>=
-begin
-otp_init_input_end:=0;
-while (cur_cmd=letter) or (cur_cmd=other_char) or
- (cur_cmd=char_given) or (cur_cmd=spacer) do begin
- incr(otp_init_input_end);
- if otp_init_input_end >ocp_buf_size then
- overflow_ocp_buf_size;
- { |cur_chr| can cover the full range |0..0x10FFFF| }
- if cur_chr<@"10000 then
- otp_init_input_buf[otp_init_input_end]:=cur_chr
- else begin
- otp_init_input_buf[otp_init_input_end]:=((cur_chr - @"10000) div @"400) + @"D800;
- incr(otp_init_input_end);
- if otp_init_input_end >ocp_buf_size then
- overflow_ocp_buf_size;
- otp_init_input_buf[otp_init_input_end]:=((cur_chr - @"10000) mod @"400) + @"DC00;
- end;
- get_token;
- if (cur_cmd<>letter) and (cur_cmd<>other_char) and
- (cur_cmd<>char_given) then begin
- x_token;
- if (cur_cmd=char_num) then begin
- scan_char_num; cur_cmd:=other_char; cur_chr:=cur_val;
- end;
- end;
- end;
-back_input;
-otp_input_end:=otp_init_input_end;
-for otp_i:=0 to otp_init_input_end do begin
- otp_input_buf[otp_i]:=otp_init_input_buf[otp_i];
- end;
-end
-
-@
-@<Apply the OCP to the input buffer@>=
-begin
-otp_input_ocp:=active_ocp(active_real);
-if otp_input_ocp=0 then begin
- print_err("Null ocp being used: all input lost");
- error;
- otp_output_end:=0;
- end
-else if ocp_external(otp_input_ocp)=0 then begin
- otp_input_start:=0;
- otp_input_last:=0;
- otp_stack_used:=0;
- otp_stack_last:=0;
- otp_stack_new:=0;
- otp_output_end:=0;
- otp_pc:=0;
- otp_finished:=false;
- otp_calc_ptr:=0;
- otp_calcs[otp_calc_ptr]:=0;
- otp_state_ptr:=0;
- otp_states[otp_state_ptr]:=0;
- while not otp_finished do
- @<Run the OTP program@>;
- end
-else begin
- k:=0;
- if nameoffile then libcfree (nameoffile);
- otp_ext_str:=ocp_external(otp_input_ocp);
- otp_ext_str_arg:=ocp_external_arg(otp_input_ocp);
- nameoffile := xmalloc (4 + length(otp_ext_str) + length(otp_ext_str_arg));
- for otp_ext_i:=str_start_macro(otp_ext_str) to
- str_start_macro(otp_ext_str)+length(otp_ext_str)-1 do
- append_to_name(str_pool[otp_ext_i]);
- append_to_name(" ");
- for otp_ext_i:=str_start_macro(otp_ext_str_arg) to
- str_start_macro(otp_ext_str_arg)+length(otp_ext_str_arg)-1 do
- append_to_name(str_pool[otp_ext_i]);
- nameoffile[length(otp_ext_str)+length(otp_ext_str_arg)+2]:=0;
- run_external_ocp(nameoffile);
- end
-end
-
-@ The OTP output buffer is an array of 16-bit values. To convert back
-to the |buffer| it has to be re-encoded into UTF-8. An incompatibility
-with Aleph is unavoidable here: The range |@"D800| \dots |@"DFFF| is
-used for surrogate pairs, not for simple 16-bit values.
-
-@<Place the output buffer back on the stream@>=
-begin
-if (first+otp_output_end)>=ocp_buf_size then
- overflow_ocp_buf_size;
-push_input;
-current_ocp_lstack:=active_lstack_no(active_real);
-current_ocp_no:=active_counter(active_real);
-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 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
- buffer[last]:=@"C0 + t div @"40;
- incr(last);
- if last=buf_size-2 then
- @<Report overflow of the input buffer, and abort@>;
- buffer[last]:=@"80 + t mod @"40;
- end
- else if t<=@"FFFF then begin
- buffer[last]:=@"E0 + t div @"1000;
- incr(last);
- if last=buf_size-2 then
- @<Report overflow of the input buffer, and abort@>;
- buffer[last]:=@"80 + (t mod @"1000) div @"40;
- incr(last);
- if last=buf_size-2 then
- @<Report overflow of the input buffer, and abort@>;
- buffer[last]:=@"80 + (t mod @"1000) mod @"40;
- end
- else begin
- buffer[last]:=@"F0 + t div @"40000;
- incr(last);
- if last=buf_size-2 then
- @<Report overflow of the input buffer, and abort@>;
- buffer[last]:=@"80 + (t mod @"40000) div @"1000;
- incr(last);
- if last=buf_size-2 then
- @<Report overflow of the input buffer, and abort@>;
- buffer[last]:=@"80 + ((t mod @"40000) mod @"1000) div @"40;
- incr(last);
- if last=buf_size-2 then
- @<Report overflow of the input buffer, and abort@>;
- buffer[last]:=@"80 + ((t mod @"40000) mod @"1000) mod @"40;
- end;
- incr(last);
- if last=buf_size-2 then
- @<Report overflow of the input buffer, and abort@>;
- end;
-limit:=last-1;
-if (t>@"FFFF) then decr(limit);
-if (t>@"7FF) then decr(limit);
-if (t>@"7F) then decr(limit);
-first:=last;
-end
-
-@
-@d otp_cur_state==otp_states[otp_state_ptr]
-@d otp_set_instruction==begin
-if otp_pc>=ocp_state_no(otp_input_ocp)(otp_cur_state) then begin
- print_err("bad OCP program -- PC not valid");
- succumb;
- end;
-otp_instruction:=ocp_state_entry(otp_input_ocp)(otp_cur_state)(otp_pc);
-otp_instr:=otp_instruction div @"1000000;
-otp_arg:=otp_instruction mod @"1000000;
-end
-
-@<Run the OTP program@>=
-begin
-otp_set_instruction;
-case otp_instr of
- @<Run the |otp_right| instructions@>;
- @<Run the |otp_pback| instructions@>;
- @<Run the arithmetic instructions@>;
- @<Run the |otp_state| instructions@>;
- @<Run the |otp_left| instructions@>;
- @<Run the |otp_goto| instructions@>;
- @<Run the |otp_stop| instruction@>;
- othercases begin
- print_err("bad OCP program -- unknown instruction");
- succumb;
- end
- endcases;
-end
-
-@
-
-@d otp_check_char(#)==
-if (1>#) or (#>otp_no_input_chars) then begin
- print_err("right hand side of OCP expression is bad");
- succumb;
- end
-
-@d otp_get_char(#)==begin
-otp_check_char(#);
-if #>otp_stack_last then begin
- otp_calculated_char:=otp_input_buf[otp_input_start+#-otp_stack_last];
- end
-else begin
- otp_calculated_char:=otp_stack_buf[#];
- end;
-end
-
-@<Run the |otp_right| instructions@>=
- otp_right_output: begin
- incr(otp_output_end);
- if otp_output_end >ocp_buf_size then
- overflow_ocp_buf_size;
- otp_output_buf[otp_output_end]:=otp_calcs[otp_calc_ptr];
- decr(otp_calc_ptr);
- incr(otp_pc);
- end;
- otp_right_num: begin
- incr(otp_output_end);
- if otp_output_end >ocp_buf_size then
- overflow_ocp_buf_size;
- otp_output_buf[otp_output_end]:=otp_arg;
- incr(otp_pc);
- end;
- otp_right_char: begin
- otp_get_char(otp_arg);
- incr(otp_output_end);
- if otp_output_end >ocp_buf_size then
- overflow_ocp_buf_size;
- otp_output_buf[otp_output_end]:=otp_calculated_char;
- incr(otp_pc);
- end;
- otp_right_lchar: begin
- otp_get_char(otp_no_input_chars-otp_arg);
- incr(otp_output_end);
- if otp_output_end >ocp_buf_size then
- overflow_ocp_buf_size;
- otp_output_buf[otp_output_end]:=otp_calculated_char;
- incr(otp_pc);
- end;
- otp_right_some: begin
- otp_first_arg:=otp_arg+1;
- incr(otp_pc);
- otp_set_instruction;
- otp_second_arg:=otp_no_input_chars-otp_arg;
- for otp_counter:=otp_first_arg to otp_second_arg do begin
- otp_get_char(otp_counter);
- incr(otp_output_end);
- if otp_output_end >ocp_buf_size then
- overflow_ocp_buf_size;
- otp_output_buf[otp_output_end]:=otp_calculated_char;
- end;
- incr(otp_pc);
- end
-
-@
-@<Run the |otp_pback| instructions@>=
- otp_pback_output: begin
- incr(otp_stack_new);
- if otp_stack_new >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_stack_buf[otp_stack_new]:=otp_calcs[otp_calc_ptr];
- decr(otp_calc_ptr);
- incr(otp_pc);
- end;
- otp_pback_num: begin
- incr(otp_stack_new);
- if otp_stack_new >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_stack_buf[otp_stack_new]:=otp_arg;
- incr(otp_pc);
- end;
- otp_pback_char: begin
- otp_get_char(otp_arg);
- incr(otp_stack_new);
- if otp_stack_new >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_stack_buf[otp_stack_new]:=otp_calculated_char;
- incr(otp_pc);
- end;
- otp_pback_lchar: begin
- otp_get_char(otp_no_input_chars-otp_arg);
- incr(otp_stack_new);
- if otp_stack_new >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_stack_buf[otp_stack_new]:=otp_calculated_char;
- incr(otp_pc);
- end;
- otp_pback_some: begin
- otp_first_arg:=otp_arg+1;
- incr(otp_pc);
- otp_set_instruction;
- otp_second_arg:=otp_no_input_chars-otp_arg;
- for otp_counter:=otp_first_arg to otp_second_arg do begin
- otp_get_char(otp_counter);
- incr(otp_stack_new);
- if otp_stack_new >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_stack_buf[otp_stack_new]:=otp_calculated_char;
- end;
- incr(otp_pc);
- end
-
-@
-@<Run the arithmetic instructions@>=
- otp_add: begin
- otp_calcs[otp_calc_ptr-1] :=
- otp_calcs[otp_calc_ptr-1] + otp_calcs[otp_calc_ptr];
- incr(otp_pc);
- decr(otp_calc_ptr);
- end;
- otp_sub: begin
- otp_calcs[otp_calc_ptr-1] :=
- otp_calcs[otp_calc_ptr-1] - otp_calcs[otp_calc_ptr];
- incr(otp_pc);
- decr(otp_calc_ptr);
- end;
- otp_mult: begin
- otp_calcs[otp_calc_ptr-1] :=
- otp_calcs[otp_calc_ptr-1] * otp_calcs[otp_calc_ptr];
- incr(otp_pc);
- decr(otp_calc_ptr);
- end;
- otp_div: begin
- otp_calcs[otp_calc_ptr-1] :=
- otp_calcs[otp_calc_ptr-1] div otp_calcs[otp_calc_ptr];
- incr(otp_pc);
- decr(otp_calc_ptr);
- end;
- otp_mod: begin
- otp_calcs[otp_calc_ptr-1] :=
- otp_calcs[otp_calc_ptr-1] mod otp_calcs[otp_calc_ptr];
- incr(otp_pc);
- decr(otp_calc_ptr);
- end;
- otp_lookup: begin
- if otp_calcs[otp_calc_ptr]>=
- ocp_table_no(otp_input_ocp)(otp_calcs[otp_calc_ptr-1]) then begin
- print_err("bad OCP program -- table index not valid");
- succumb;
- end;
- otp_calcs[otp_calc_ptr-1]:=
- ocp_table_entry(otp_input_ocp)(otp_calcs[otp_calc_ptr-1])
- (otp_calcs[otp_calc_ptr]);
- incr(otp_pc);
- decr(otp_calc_ptr);
- end;
- otp_push_num: begin
- incr(otp_calc_ptr);
- if otp_calc_ptr >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_calcs[otp_calc_ptr]:=otp_arg;
- incr(otp_pc);
- end;
- otp_push_char: begin
- otp_get_char(otp_arg);
- incr(otp_calc_ptr);
- if otp_calc_ptr >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_calcs[otp_calc_ptr]:=otp_calculated_char;
- incr(otp_pc);
- end;
- otp_push_lchar: begin
- otp_get_char(otp_no_input_chars-otp_arg);
- incr(otp_calc_ptr);
- if otp_calc_ptr >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_calcs[otp_calc_ptr]:=otp_calculated_char;
- incr(otp_pc);
- end
-
-@
-@<Run the |otp_state| instructions@>=
- otp_state_change: begin
- otp_input_start:=otp_input_last;
- for otp_counter:=1 to (otp_stack_new-otp_stack_used) do begin
- otp_stack_buf[otp_counter] :=
- otp_stack_buf[otp_counter+otp_stack_used];
- end;
- otp_stack_new:=otp_stack_new-otp_stack_used;
- otp_stack_last:=otp_stack_new;
- otp_stack_used:=0;
- otp_states[otp_state_ptr]:=otp_arg;
- otp_pc:=0;
- end;
- otp_state_push: begin
- otp_input_start:=otp_input_last;
- for otp_counter:=1 to (otp_stack_new-otp_stack_used) do begin
- otp_stack_buf[otp_counter] :=
- otp_stack_buf[otp_counter+otp_stack_used];
- end;
- otp_stack_new:=otp_stack_new-otp_stack_used;
- otp_stack_last:=otp_stack_new;
- otp_stack_used:=0;
- incr(otp_state_ptr);
- if otp_state_ptr >= ocp_stack_size then
- overflow_ocp_stack_size;
- otp_states[otp_state_ptr]:=otp_arg;
- otp_pc:=0;
- end;
- otp_state_pop: begin
- otp_input_start:=otp_input_last;
- for otp_counter:=1 to (otp_stack_new-otp_stack_used) do begin
- otp_stack_buf[otp_counter] :=
- otp_stack_buf[otp_counter+otp_stack_used];
- end;
- otp_stack_new:=otp_stack_new-otp_stack_used;
- otp_stack_last:=otp_stack_new;
- otp_stack_used:=0;
- if otp_state_ptr>0 then decr(otp_state_ptr);
- otp_pc:=0;
- end
-
-@
-@<Run the |otp_left| instructions@>=
- otp_left_start: begin
- otp_input_start:=otp_input_last;
- otp_input_last:=otp_input_start;
- otp_stack_used:=0;
- if (otp_stack_last=0) and (otp_input_last>=otp_input_end) then
- otp_finished:=true
- else if (otp_stack_used < otp_stack_last) then begin
- incr(otp_stack_used); {no overflow problem}
- otp_input_char:=otp_stack_buf[otp_stack_used];
- otp_no_input_chars:=1;
- incr(otp_pc);
- end
- else begin
- incr(otp_input_last); {no overflow problem}
- otp_input_char:=otp_input_buf[otp_input_last];
- otp_no_input_chars:=1;
- incr(otp_pc);
- end;
- end;
- otp_left_return: begin
- otp_input_last:=otp_input_start;
- otp_stack_used:=0;
- if (otp_stack_used < otp_stack_last) then begin
- incr(otp_stack_used); {no overflow problem}
- otp_input_char:=otp_stack_buf[otp_stack_used];
- otp_no_input_chars:=1;
- incr(otp_pc);
- end
- else begin
- incr(otp_input_last); {no overflow problem}
- otp_input_char:=otp_input_buf[otp_input_last];
- otp_no_input_chars:=1;
- incr(otp_pc);
- end;
- end;
- otp_left_backup: begin
- if otp_input_start < otp_input_last then begin
- decr(otp_input_last); otp_input_char:=otp_input_buf[otp_input_last];
- end
- else begin
- decr(otp_stack_used); otp_input_char:=otp_stack_buf[otp_stack_used];
- end;
- decr(otp_no_input_chars);
- incr(otp_pc);
- end
-
-@
-@<Run the |otp_goto| instructions@>=
- otp_goto: begin
- otp_pc:=otp_arg;
- end;
- otp_goto_ne: begin
- otp_first_arg:=otp_arg;
- incr(otp_pc);
- otp_set_instruction;
- if otp_input_char <> otp_first_arg then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end;
- otp_goto_eq: begin
- otp_first_arg:=otp_arg;
- incr(otp_pc);
- otp_set_instruction;
- if otp_input_char = otp_first_arg then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end;
- otp_goto_lt: begin
- otp_first_arg:=otp_arg;
- incr(otp_pc);
- otp_set_instruction;
- if otp_input_char < otp_first_arg then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end;
- otp_goto_le: begin
- otp_first_arg:=otp_arg;
- incr(otp_pc);
- otp_set_instruction;
- if otp_input_char <= otp_first_arg then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end;
- otp_goto_gt: begin
- otp_first_arg:=otp_arg;
- incr(otp_pc);
- otp_set_instruction;
- if otp_input_char > otp_first_arg then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end;
- otp_goto_ge: begin
- otp_first_arg:=otp_arg;
- incr(otp_pc);
- otp_set_instruction;
- if otp_input_char >= otp_first_arg then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end;
- otp_goto_no_advance: begin
- if (otp_stack_used < otp_stack_last) then begin
- incr(otp_stack_used); {no overflow problem}
- otp_input_char:=otp_stack_buf[otp_stack_used];
- incr(otp_no_input_chars); {no overflow problem}
- incr(otp_pc);
- end
- else if otp_input_last>=otp_input_end then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_input_last); {no overflow problem}
- otp_input_char:=otp_input_buf[otp_input_last];
- incr(otp_no_input_chars); {no overflow problem}
- incr(otp_pc);
- end;
- end;
- otp_goto_beg: begin
- if otp_input_last=0 then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end;
- otp_goto_end: begin
- if otp_input_last>=otp_input_end then begin
- otp_pc:=otp_arg;
- end
- else begin
- incr(otp_pc);
- end;
- end
-
-@
-@<Run the |otp_stop| instruction@>=
- otp_stop: begin
- otp_input_start:=otp_input_last;
- for otp_counter:=1 to (otp_stack_new-otp_stack_used) do begin
- otp_stack_buf[otp_counter] :=
- otp_stack_buf[otp_counter+otp_stack_used];
- end;
- otp_stack_new:=otp_stack_new-otp_stack_used;
- otp_stack_last:=otp_stack_new;
- otp_stack_used:=0;
- otp_pc:=0;
- end
-
-@ @<Put each...@>=
-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;
-
-@ @<Assignments@>=
-set_ocp: begin
- print_err("To use ocps, use the "); print_esc("pushocplist");
- print(" primitive");print_ln
- end;
-def_ocp: new_ocp(a);
-set_ocp_list: begin
- print_err("To use ocp lists, use the ");
- print_esc("pushocplist"); print(" primitive");print_ln
- end;
-def_ocp_list: new_ocp_list(a);
-push_ocp_list: do_push_ocp_list(a);
-pop_ocp_list: do_pop_ocp_list(a);
-clear_ocp_lists: do_clear_ocp_lists(a);
-ocp_list_op: begin
- print_err("To build ocp lists, use the ");
- print_esc("ocplist"); print(" primitive"); print_ln
- end;
-ocp_trace_level: begin scan_optional_equals; scan_int;
- if cur_val<>0 then cur_val:=1;
- define(ocp_trace_level_base, data, cur_val);
- end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure new_ocp(@!a:small_number);
-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}
-@!flushable_string:str_number; {string not yet referenced}
-@!external_ocp:boolean; {external binary file}
-begin if job_name=0 then open_log_file;
- {avoid confusing \.{texput} with the ocp name}
-@.texput@>
-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 t:="OCP";
-define(u,set_ocp,null_ocp); scan_optional_equals; scan_file_name;
-@<If this ocp has already been loaded, set |f| to the internal
- ocp number and |goto common_ending|@>;
-f:=read_ocp_info(u,cur_name,cur_area,cur_ext,external_ocp);
-common_ending:
-equiv(u):=f; eqtb[ocp_id_base+f] := eqtb[u];
-text(ocp_id_base+f) := t;
-if equiv(ocp_trace_level_base)=1 then begin
- print_nl(""); print_esc("ocp"); print_esc(t); print("="); print(cur_name);
- end;
-end;
-
-@ When the user gives a new identifier to a ocp that was previously loaded,
-the new name becomes the ocp identifier of record. OCP names `\.{xyz}' and
-`\.{XYZ}' are considered to be different.
-
-@<If this ocp has already been loaded...@>=
-flushable_string:=str_ptr-1;
-for f:=ocp_base+1 to ocp_ptr do
- if str_eq_str(ocp_name(f),cur_name)and str_eq_str(ocp_area(f),cur_area) then
- begin
- if cur_name=flushable_string then begin
- flush_string; cur_name:=ocp_name(f);
- end;
- goto common_ending
- end
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-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}
-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 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];
- text(ocp_list_id_base+f) := t;
-if equiv(ocp_trace_level_base)=1 then begin
- print_nl(""); print_esc("ocplist"); print_esc(t); print("=");
- print_ocp_list(ocp_list_list[f]);
- end;
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure do_push_ocp_list(@!a:small_number);
-var ocp_list_no:halfword;
- old_number:halfword;
- i:integer;
-begin
-scan_ocp_list_ident; ocp_list_no:=cur_val;
-old_number:=equiv(ocp_active_number_base);
-define(ocp_active_base+old_number, data, ocp_list_no);
-define(ocp_active_number_base, data, (old_number+1));
-
-if equiv(ocp_trace_level_base)=1 then begin
- print_nl("New active ocp list: {");
- for i:=old_number downto 0 do begin
- print_esc(ocp_list_id_text(equiv(ocp_active_base+i)));
- print("="); print_ocp_list(ocp_list_list[equiv(ocp_active_base+i)]);
- if i<>0 then print(",");
- end;
- print("}");
- end;
-
-active_compile;
-define(ocp_active_min_ptr_base, data, active_min_ptr);
-define(ocp_active_max_ptr_base, data, active_max_ptr);
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure do_pop_ocp_list(@!a:small_number);
-var old_number:halfword;
- i:integer;
-begin
-old_number:=equiv(ocp_active_number_base);
-if old_number=0 then begin
- print_err("No active ocp lists to be popped");
- end
-else
- define(ocp_active_number_base, data, (old_number-1));
-
-if equiv(ocp_trace_level_base)=1 then begin
- print_nl("New active ocp list: {");
- for i:=(old_number-2) downto 0 do begin
- print_esc(ocp_list_id_text(equiv(ocp_active_base+i)));
- print("="); print_ocp_list(ocp_list_list[equiv(ocp_active_base+i)]);
- if i<>0 then print(",");
- end;
- print("}");
- end;
-
-active_compile;
-define(ocp_active_min_ptr_base, data, active_min_ptr);
-define(ocp_active_max_ptr_base, data, active_max_ptr);
-end;
-
-@ @<Declare subprocedures for |prefixed_command|@>=
-procedure do_clear_ocp_lists(@!a:small_number);
-begin
-define(ocp_active_number_base, data, 0);
-active_compile;
-define(ocp_active_min_ptr_base, data, active_min_ptr);
-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.
-
-@ @<Glob...@>=
-@!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.
-
-@ @<Glob...@>=
-@!synctexoffset:integer; {holds the true value of |synctex_code|}
-
-@ @<Initialize whatever...@>=
-synctexoffset:=int_base+synctex_code;
-
-@ @<Initialize synctex primitive@>=
-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.
-
-@ @<Prepare new file {\sl Sync\TeX} information@>=
-synctex_start_input; {Give control to the {\sl Sync\TeX} controller}
-
-@ @<Prepare terminal input {\sl Sync\TeX} information@>=
-synctex_tag:=0;
-
-@ @<Prepare pseudo file {\sl Sync\TeX} information@>=
-synctex_tag:=0;
-
-@ @<Close {\sl Sync\TeX} file and write status@>=
-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.
-
-@ @<Start sheet {\sl Sync\TeX} information record@>=
-pdf_output_value:=pdf_output; {{\sl Sync\TeX}: we assume that |pdf_output| is properly set up}
-synctex_sheet(mag);
-
-@ @<Finish sheet {\sl Sync\TeX} information record@>=
-synctex_teehs;
-
-@ @<Start vlist {\sl Sync\TeX} information record@>=
-synctex_vlist(this_box);
-
-@ @<Finish vlist {\sl Sync\TeX} information record@>=
-synctex_tsilv(this_box);
-
-@ @<Start hlist {\sl Sync\TeX} information record@>=
-synctex_hlist(this_box);
-
-@ @<Finish hlist {\sl Sync\TeX} information record@>=
-synctex_tsilh(this_box);
-
-@ @<Record void list {\sl Sync\TeX} information@>=
- if type(p)=vlist_node then begin
- synctex_void_vlist(p,this_box);
- end
- else begin
- synctex_void_hlist(p,this_box);
- end;
-
-@ @<Record current point {\sl Sync\TeX} information@>=
-synctex_current;
-
-@ @<Record horizontal |rule_node| or |glue_node| {\sl Sync\TeX} information@>=
-synctex_horizontal_rule_or_glue(p,this_box);
-
-@ @<Record |kern_node| {\sl Sync\TeX} information@>=
-synctex_kern(p,this_box);
-
-@ @<Record |math_node| {\sl Sync\TeX} information@>=
-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
-that are necessary to make \TeX\ work at a particular installation.
-It is usually best to design your change file so that all changes to
-previous sections preserve the section numbering; then everybody's version
-will be consistent with the published program. More extensive changes,
-which introduce new sections, can be inserted here; then only the index
-itself will get a new section number.
-@^system dependencies@>
-
-@* \[55] Index.
-Here is where you can find all uses of each identifier in the program,
-with underlined entries pointing to where the identifier was defined.
-If the identifier is only one letter long, however, you get to see only
-the underlined entries. {\sl All references are to section numbers instead of
-page numbers.}
-
-This index also lists error messages and other aspects of the program
-that you might want to look up some day. For example, the entry
-for ``system dependencies'' lists all sections that should receive
-special attention from people who are installing \TeX\ in a new
-operating environment. A list of various things that can't happen appears
-under ``this can't happen''. Approximately 40 sections are listed under
-``inner loop''; these account for about 60\pct! of \TeX's running time,
-exclusive of input and output.
diff --git a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h
new file mode 100644
index 00000000000..0a3d66ca9d5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h
@@ -0,0 +1 @@
+#define luatex_svn_revision 3588
diff --git a/Build/source/texk/web2c/luatexdir/makecpool.c b/Build/source/texk/web2c/luatexdir/makecpool.c
deleted file mode 100644
index a3693e695a9..00000000000
--- a/Build/source/texk/web2c/luatexdir/makecpool.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright 2007, 2008 Taco Hoekwater.
- You may freely use, modify and/or distribute this file. */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-static const char __svn_version[] =
- "$Id: makecpool.c 2321 2009-04-18 09:17:13Z hhenkel $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.5/source/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 <stdio.h>\n"
- "#include <string.h>\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"
- " str_number 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/ocp/ocp.h b/Build/source/texk/web2c/luatexdir/ocp/ocp.h
new file mode 100644
index 00000000000..3bdaab0e8c8
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/ocp.h
@@ -0,0 +1,52 @@
+/* ocp.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: ocp.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef OCP_H
+
+# define OCP_H 1
+
+typedef int internal_ocp_number;
+typedef int ocp_index;
+
+extern int **ocp_tables;
+
+extern int ocp_maxint;
+
+extern internal_ocp_number ocp_ptr; /* largest internal ocp number in use */
+
+/* smallest internal ocp number; must not be less than |min_quarterword| */
+# define ocp_base 0
+# define number_ocps 32768
+
+# define null_ocp ocp_base
+
+extern void new_ocp(small_number a);
+
+# define ocp_trace_level equiv(ocp_trace_level_base)
+
+extern void allocate_ocp_table(int ocp_number, int ocp_size);
+
+extern void dump_ocp_info(void);
+extern void undump_ocp_info(void);
+extern void scan_ocp_ident(void);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/ocp/ocp.w b/Build/source/texk/web2c/luatexdir/ocp/ocp.w
new file mode 100644
index 00000000000..60afca0f4c6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/ocp.w
@@ -0,0 +1,201 @@
+% ocp.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: ocp.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/ocp/ocp.w $";
+
+@ @c
+int **ocp_tables;
+
+static int ocp_entries = 0;
+int ocp_maxint = 10000000;
+
+@ When the user defines \.{\\ocp\\f}, say, \TeX\ assigns an internal number
+to the user's ocp~\.{\\f}. Adding this number to |ocp_id_base| gives the
+|eqtb| location of a ``frozen'' control sequence that will always select
+the ocp.
+
+@c
+internal_ocp_number ocp_ptr; /* largest internal ocp number in use */
+
+void new_ocp(small_number a)
+{
+ pointer u; /* user's ocp identifier */
+ internal_ocp_number f; /* runs through existing ocps */
+ str_number t; /* name for the frozen ocp identifier */
+ boolean external_ocp = false; /* external binary file */
+ if (job_name == 0)
+ open_log_file();
+ /* avoid confusing \.{texput} with the ocp name */
+ if (cur_chr == 1)
+ external_ocp = true;
+ get_r_token();
+ u = cur_cs;
+ if (u >= hash_base)
+ t = cs_text(u);
+ else
+ t = maketexstring("OCP");
+ define(u, set_ocp_cmd, null_ocp);
+ scan_optional_equals();
+ scan_file_name();
+ /* If this ocp has already been loaded, set |f| to the internal
+ ocp number and |goto common_ending| */
+ /* When the user gives a new identifier to a ocp that was previously loaded,
+ the new name becomes the ocp identifier of record. OCP names `\.{xyz}' and
+ `\.{XYZ}' are considered to be different.
+ */
+ for (f = ocp_base + 1; f <= ocp_ptr; f++) {
+ if (str_eq_str(ocp_name(f), cur_name)
+ && str_eq_str(ocp_area(f), cur_area)) {
+ flush_str(cur_name);
+ flush_str(cur_area);
+ cur_name = ocp_name(f);
+ cur_area = ocp_area(f);
+ goto COMMON_ENDING;
+ }
+ }
+ {
+ char *nam = makecstring(cur_name);
+ char *are = makecstring(cur_area);
+ char *ext = makecstring(cur_ext);
+ f = read_ocp_info(u, nam, are, ext, external_ocp);
+ free(nam);
+ free(are);
+ free(ext);
+ }
+ COMMON_ENDING:
+ equiv(u) = f;
+ eqtb[ocp_id_base + f] = eqtb[u];
+ cs_text(ocp_id_base + f) = t;
+ if (ocp_trace_level == 1) {
+ tprint_nl("");
+ tprint_esc("ocp");
+ print_esc(t);
+ tprint("=");
+ print(cur_name);
+ }
+}
+
+@ Before we forget about the format of these tables, let's deal with
+$\Omega$'s basic scanning routine related to ocp information.
+
+@c
+void scan_ocp_ident(void)
+{
+ internal_ocp_number f;
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ if (cur_cmd == set_ocp_cmd) {
+ f = cur_chr;
+ } else {
+ const char *hlp[] = { "I was looking for a control sequence whose",
+ "current meaning has been defined by \\ocp.",
+ NULL
+ };
+ back_input();
+ tex_error("Missing ocp identifier", hlp);
+ f = null_ocp;
+ }
+ cur_val = f;
+}
+
+void allocate_ocp_table(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;
+ }
+ ocp_tables[ocp_number] =
+ (int *) xmalloc((unsigned) ((1 + (unsigned) ocp_size) * sizeof(int)));
+ ocp_tables[ocp_number][0] = ocp_size;
+ for (i = 1; i <= ocp_size; i++) {
+ ocp_tables[ocp_number][i] = 0;
+ }
+}
+
+@ @c
+static void dump_ocp_table(int ocp_number)
+{
+ dump_things(ocp_tables[ocp_number][0], ocp_tables[ocp_number][0] + 1);
+}
+
+void dump_ocp_info(void)
+{
+ int k;
+ dump_int(123456);
+ dump_int(ocp_ptr);
+ for (k = null_ocp; k <= ocp_ptr; k++) {
+ dump_ocp_table(k);
+ if (ocp_ptr - ocp_base > 0) {
+ tprint_nl("\\ocp");
+ print_esc(cs_text(ocp_id_base + k));
+ print_char('=');
+ print_file_name(ocp_name(k), ocp_area(k), get_nullstr());
+ }
+ }
+ dump_int(123456);
+ if (ocp_ptr - ocp_base > 0) {
+ print_ln();
+ print_int(ocp_ptr - ocp_base);
+ tprint(" preloaded ocp");
+ if (ocp_ptr != ocp_base + 1)
+ print_char('s');
+ }
+}
+
+static void undump_ocp_table(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;
+ }
+ undump_things(sizeword, 1);
+ ocp_tables[ocp_number] =
+ (int *) xmalloc((unsigned) ((1 + (unsigned) sizeword) * sizeof(int)));
+ ocp_tables[ocp_number][0] = sizeword;
+ undump_things(ocp_tables[ocp_number][1], sizeword);
+}
+
+
+void undump_ocp_info(void)
+{
+ int k;
+ int x;
+ undump_int(x);
+ assert(x == 123456);
+ undump_int(ocp_ptr);
+ for (k = null_ocp; k <= ocp_ptr; k++)
+ undump_ocp_table(k);
+ undump_int(x);
+ assert(x == 123456);
+}
diff --git a/Build/source/texk/web2c/luatexdir/ocp/ocplist.h b/Build/source/texk/web2c/luatexdir/ocp/ocplist.h
new file mode 100644
index 00000000000..f94f29adf03
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/ocplist.h
@@ -0,0 +1,91 @@
+/* ocplist.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: ocplist.h 3302 2009-12-25 12:49:14Z oneiros $ */
+
+#ifndef OCPLIST_H
+
+# define OCPLIST_H 1
+
+# define ocp_list_base 0 /* smallest internal ocp list number; must not be less
+ than |min_quarterword| */
+# define number_ocp_lists 32768
+# define null_ocp_list ocp_list_base
+
+typedef int internal_ocp_list_number;
+typedef int ocp_list_index; /* index into |ocp_list_info| */
+typedef int ocp_lstack_index; /* index into |ocp_lstack_info| */
+
+extern memory_word *ocp_list_info;
+extern memory_word *ocp_lstack_info;
+extern internal_ocp_list_number ocp_list_ptr;
+extern ocp_list_index *ocp_list_list;
+
+# define ocp_list_lnext(A) ocp_list_info[(A)].hh.u.B0
+# define ocp_list_lstack(A) ocp_list_info[(A)].hh.u.B1
+# define ocp_list_lstack_no(A) ocp_list_info[(A)+1].cint
+# define ocp_lstack_lnext(A) ocp_lstack_info[(A)].hh.u.B0
+# define ocp_lstack_ocp(A) ocp_lstack_info[(A)].hh.u.B1
+# define make_null_ocp_list() make_ocp_list_node(0,ocp_maxint,0)
+# define is_null_ocp_list(A) (ocp_list_lstack_no(A)==ocp_maxint)
+
+# define make_null_ocp_lstack() 0
+# define is_null_ocp_lstack(A) ((A)==0)
+
+typedef enum {
+ add_before_op = 1,
+ add_after_op,
+ remove_before_op,
+ remove_after_op
+} ocplist_ops;
+
+
+extern void initialize_init_ocplists(void);
+extern void initialize_ocplist_arrays(int ocp_list_size);
+
+extern ocp_list_index make_ocp_list_node(ocp_lstack_index llstack,
+ scaled llstack_no,
+ ocp_list_index llnext);
+
+extern ocp_lstack_index make_ocp_lstack_node(internal_ocp_number locp,
+ ocp_lstack_index llnext);
+
+extern ocp_lstack_index copy_ocp_lstack(ocp_lstack_index llstack);
+
+extern ocp_list_index copy_ocp_list(ocp_list_index list);
+
+extern ocp_list_index ocp_ensure_lstack(ocp_list_index list, scaled llstack_no);
+
+extern void ocp_apply_add(ocp_list_index list_entry,
+ boolean lbefore, internal_ocp_number locp);
+
+extern void ocp_apply_remove(ocp_list_index list_entry, boolean lbefore);
+
+extern void print_ocp_lstack(ocp_lstack_index lstack_entry);
+extern void print_ocp_list(ocp_list_index list_entry);
+extern ocp_list_index scan_ocp_list(void);
+extern internal_ocp_list_number read_ocp_list(void);
+extern void scan_ocp_list_ident(void);
+
+extern void new_ocp_list(small_number a);
+
+extern void dump_ocplist_info(void);
+extern void undump_ocplist_info(void);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/ocp/ocplist.w b/Build/source/texk/web2c/luatexdir/ocp/ocplist.w
new file mode 100644
index 00000000000..533678fd699
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/ocplist.w
@@ -0,0 +1,357 @@
+% ocplist.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: ocplist.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/ocp/ocplist.w $";
+
+@ @c
+memory_word *ocp_list_info; /* the big collection of ocp list data */
+ocp_list_index ocp_listmem_ptr; /* first unused word of |ocp_list_info| */
+ocp_list_index ocp_listmem_run_ptr; /* temp unused word of |ocp_list_info| */
+memory_word *ocp_lstack_info; /* the big collection of ocp lstack data */
+ocp_lstack_index ocp_lstackmem_ptr; /* first unused word of |ocp_lstack_info| */
+ocp_lstack_index ocp_lstackmem_run_ptr; /* temp unused word of |ocp_lstack_info| */
+internal_ocp_list_number ocp_list_ptr; /* largest internal ocp list number in use */
+ocp_list_index *ocp_list_list;
+
+#define ocp_list_id_text(A) cs_text(ocp_list_id_base+(A))
+
+void initialize_init_ocplists(void)
+{
+ ocp_listmem_ptr = 2;
+ ocp_list_lstack(0) = 0;
+ ocp_list_lstack_no(0) = ocp_maxint;
+ ocp_list_lnext(0) = 0;
+ ocp_list_ptr = null_ocp_list;
+ ocp_list_list[null_ocp_list] = 0;
+ ocp_lstackmem_ptr = 1;
+}
+
+
+void initialize_ocplist_arrays(int ocp_list_size)
+{
+ ocp_list_info = xmallocarray(memory_word, (unsigned) ocp_list_size);
+ memset(ocp_list_info, 0, sizeof(memory_word) * (unsigned) ocp_list_size);
+ ocp_lstack_info = xmallocarray(memory_word, (unsigned) ocp_list_size);
+ memset(ocp_lstack_info, 0, sizeof(memory_word) * (unsigned) ocp_list_size);
+ ocp_list_list = xmallocarray(ocp_list_index, (unsigned) ocp_list_size);
+}
+
+
+@ @c
+ocp_list_index make_ocp_list_node(ocp_lstack_index llstack,
+ scaled llstack_no, ocp_list_index llnext)
+{
+ ocp_list_index p;
+ p = ocp_listmem_run_ptr;
+ ocp_list_lstack(p) = (quarterword) llstack;
+ ocp_list_lstack_no(p) = llstack_no;
+ ocp_list_lnext(p) = (quarterword) llnext;
+ ocp_listmem_run_ptr = ocp_listmem_run_ptr + 2;
+ if (ocp_listmem_run_ptr >= ocp_list_size)
+ overflow("ocp_list_size", (unsigned) ocp_list_size);
+ return p;
+}
+
+ocp_lstack_index make_ocp_lstack_node(internal_ocp_number locp,
+ ocp_lstack_index llnext)
+{
+ ocp_lstack_index p;
+ p = ocp_lstackmem_run_ptr;
+ ocp_lstack_ocp(p) = (quarterword) locp;
+ ocp_lstack_lnext(p) = (quarterword) llnext;
+ incr(ocp_lstackmem_run_ptr);
+ if (ocp_lstackmem_run_ptr >= ocp_stack_size)
+ overflow("ocp_stack_size", (unsigned) ocp_stack_size);
+ return p;
+}
+
+ocp_lstack_index copy_ocp_lstack(ocp_lstack_index llstack)
+{
+ if (is_null_ocp_lstack(llstack))
+ return make_null_ocp_lstack();
+ else
+ return make_ocp_lstack_node(ocp_lstack_ocp(llstack),
+ copy_ocp_lstack(ocp_lstack_lnext(llstack)));
+}
+
+ocp_list_index copy_ocp_list(ocp_list_index list)
+{
+ if (is_null_ocp_list(list))
+ return make_null_ocp_list();
+ else
+ return make_ocp_list_node(copy_ocp_lstack(ocp_list_lstack(list)),
+ ocp_list_lstack_no(list),
+ copy_ocp_list(ocp_list_lnext(list)));
+}
+
+ocp_list_index ocp_ensure_lstack(ocp_list_index list, scaled llstack_no)
+{
+ ocp_list_index p;
+ ocp_list_index q;
+ p = list;
+ if (is_null_ocp_list(p)) {
+ ocp_list_lstack_no(p) = llstack_no;
+ ocp_list_lnext(p) = (quarterword) make_null_ocp_list();
+ } else if (ocp_list_lstack_no(p) > llstack_no) {
+ ocp_list_lnext(p) = (quarterword)
+ make_ocp_list_node(ocp_list_lstack(p),
+ ocp_list_lstack_no(p), ocp_list_lnext(p));
+ ocp_list_lstack(p) = 0;
+ ocp_list_lstack_no(p) = llstack_no;
+ } else {
+ q = ocp_list_lnext(p);
+ while ((!(is_null_ocp_list(q))) && ocp_list_lstack_no(q) <= llstack_no) {
+ p = q;
+ q = ocp_list_lnext(q);
+ }
+ if (ocp_list_lstack_no(p) < llstack_no) {
+ ocp_list_lnext(p) =
+ (quarterword) make_ocp_list_node(0, llstack_no, q);
+ p = ocp_list_lnext(p);
+ }
+ }
+ return p;
+}
+
+void ocp_apply_add(ocp_list_index list_entry,
+ boolean lbefore, internal_ocp_number locp)
+{
+ ocp_lstack_index p;
+ ocp_lstack_index q;
+ p = ocp_list_lstack(list_entry);
+ if (lbefore || (p == 0)) {
+ ocp_list_lstack(list_entry) =
+ (quarterword) make_ocp_lstack_node(locp, p);
+ } else {
+ q = ocp_lstack_lnext(p);
+ while (q != 0) {
+ p = q;
+ q = ocp_lstack_lnext(q);
+ }
+ ocp_lstack_lnext(p) = (quarterword) make_ocp_lstack_node(locp, 0);
+ }
+}
+
+void ocp_apply_remove(ocp_list_index list_entry, boolean lbefore)
+{
+ ocp_lstack_index p;
+ ocp_lstack_index q;
+ ocp_lstack_index r;
+ p = ocp_list_lstack(list_entry);
+ if (p == 0) {
+ print_err("warning: stack entry already empty");
+ print_ln();
+ } else {
+ q = ocp_lstack_lnext(p);
+ if (lbefore || (q == 0)) {
+ ocp_list_lstack(list_entry) = (quarterword) q;
+ } else {
+ r = ocp_lstack_lnext(q);
+ while (r != 0) {
+ p = q;
+ q = r;
+ r = ocp_lstack_lnext(r);
+ }
+ ocp_lstack_lnext(p) = 0;
+ }
+ }
+}
+
+
+void print_ocp_lstack(ocp_lstack_index lstack_entry)
+{
+ ocp_lstack_index p;
+ p = lstack_entry;
+ while (p != 0) {
+ print_esc(cs_text(ocp_id_base + ocp_lstack_ocp(p)));
+ p = ocp_lstack_lnext(p);
+ if (p != 0)
+ print_char(',');
+ }
+}
+
+void print_ocp_list(ocp_list_index list_entry)
+{
+ ocp_list_index p;
+ print_char('[');
+ p = list_entry;
+ while (!(is_null_ocp_list(p))) {
+ print_char('(');
+ print_scaled(ocp_list_lstack_no(p));
+ tprint(" : ");
+ print_ocp_lstack(ocp_list_lstack(p));
+ print_char(')');
+ p = ocp_list_lnext(p);
+ if (!(is_null_ocp_list(p)))
+ tprint(", ");
+ }
+ print_char(']');
+}
+
+@ @c
+ocp_list_index scan_ocp_list(void)
+{
+ scaled llstack_no;
+ quarterword lop;
+ ocp_list_index lstack_entry;
+ ocp_list_index other_list;
+ internal_ocp_number ocp_ident = 0;
+ get_r_token();
+ if (cur_cmd == set_ocp_list_cmd) {
+ return copy_ocp_list(ocp_list_list[cur_chr]);
+ } else if (cur_cmd != ocp_list_op_cmd) {
+ const char *hlp[] =
+ { "I was looking for a ocp list specification.", NULL };
+ tex_error("Bad ocp list specification", hlp);
+ return make_null_ocp_list();
+ } else {
+ lop = (quarterword) cur_chr;
+ scan_scaled();
+ llstack_no = cur_val;
+ if ((llstack_no <= 0) || (llstack_no >= ocp_maxint)) {
+ tex_error("Stack numbers must be between 0 and 4096 (exclusive)",
+ NULL);
+ return make_null_ocp_list();
+ } else {
+ if (lop <= add_after_op) {
+ scan_ocp_ident();
+ ocp_ident = cur_val;
+ }
+ other_list = scan_ocp_list();
+ lstack_entry = ocp_ensure_lstack(other_list, llstack_no);
+ if (lop <= add_after_op) {
+ ocp_apply_add(lstack_entry, (lop = add_before_op), ocp_ident);
+ } else {
+ ocp_apply_remove(lstack_entry, (lop = remove_before_op));
+ }
+ return other_list;
+ }
+ }
+}
+
+@ @c
+internal_ocp_list_number read_ocp_list(void)
+{
+ internal_ocp_list_number f;
+ internal_ocp_list_number g;
+ g = null_ocp_list;
+ f = ocp_list_ptr + 1;
+ ocp_listmem_run_ptr = ocp_listmem_ptr;
+ ocp_lstackmem_run_ptr = ocp_lstackmem_ptr;
+ ocp_list_list[f] = scan_ocp_list();
+ ocp_list_ptr = f;
+ ocp_listmem_ptr = ocp_listmem_run_ptr;
+ ocp_lstackmem_ptr = ocp_lstackmem_run_ptr;
+ g = f;
+ return g;
+}
+
+@ @c
+void scan_ocp_list_ident(void)
+{
+ internal_ocp_list_number f;
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ if (cur_cmd == set_ocp_list_cmd) {
+ f = cur_chr;
+ } else {
+ const char *hlp[] = { "I was looking for a control sequence whose",
+ "current meaning has been defined by \\ocplist.",
+ NULL
+ };
+ back_input();
+ tex_error("Missing ocp list identifier", hlp);
+ f = null_ocp_list;
+ }
+ cur_val = f;
+}
+
+@ @c
+void new_ocp_list(small_number a)
+{
+ pointer u; /* user's ocp list identifier */
+ internal_ocp_list_number f; /* runs through existing ocp lists */
+ str_number t; /* name for the frozen ocp list identifier */
+ if (job_name == 0)
+ open_log_file();
+ /* avoid confusing \.{texput} with the ocp list name */
+ get_r_token();
+ u = cur_cs;
+ if (u >= hash_base)
+ t = cs_text(u);
+ else
+ t = maketexstring("OCPLIST");
+ define(u, set_ocp_list_cmd, null_ocp_list);
+ scan_optional_equals();
+ f = read_ocp_list();
+ equiv(u) = f;
+ eqtb[ocp_list_id_base + f] = eqtb[u];
+ cs_text(ocp_list_id_base + f) = t;
+ if (ocp_trace_level == 1) {
+ tprint_nl("");
+ tprint_esc("ocplist");
+ print_esc(t);
+ tprint("=");
+ print_ocp_list(ocp_list_list[f]);
+ }
+}
+
+@ @c
+void dump_ocplist_info(void)
+{
+ int k;
+ dump_int(ocp_listmem_ptr);
+ for (k = 0; k <= ocp_listmem_ptr - 1; k++)
+ dump_wd(ocp_list_info[k]);
+ dump_int(ocp_list_ptr);
+ for (k = null_ocp_list; k <= ocp_list_ptr; k++) {
+ dump_int(ocp_list_list[k]);
+ if (null_ocp_list != ocp_list_ptr) {
+ tprint_nl("\\ocplist");
+ print_esc(ocp_list_id_text(k));
+ print_char('=');
+ print_ocp_list(ocp_list_list[k]);
+ }
+ }
+ dump_int(ocp_lstackmem_ptr);
+ for (k = 0; k <= ocp_lstackmem_ptr - 1; k++)
+ dump_wd(ocp_lstack_info[k]);
+}
+
+void undump_ocplist_info(void)
+{
+ int k;
+ initialize_ocplist_arrays(ocp_list_size);
+ undump_int(ocp_listmem_ptr);
+ for (k = 0; k <= ocp_listmem_ptr - 1; k++)
+ undump_wd(ocp_list_info[k]);
+ undump_int(ocp_list_ptr);
+ for (k = null_ocp_list; k <= ocp_list_ptr; k++)
+ undump_int(ocp_list_list[k]);
+ undump_int(ocp_lstackmem_ptr);
+ for (k = 0; k <= ocp_lstackmem_ptr - 1; k++)
+ undump_wd(ocp_lstack_info[k]);
+}
diff --git a/Build/source/texk/web2c/luatexdir/ocp/readocp.h b/Build/source/texk/web2c/luatexdir/ocp/readocp.h
new file mode 100644
index 00000000000..f16f464270f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/readocp.h
@@ -0,0 +1,61 @@
+/* readocp.h
+
+ Copyright 2006-2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: readocp.h 3127 2009-11-11 10:14:11Z taco $ */
+
+#ifndef READOCP_H
+
+# define READOCP_H 1
+
+# define ocp_info(A,B) ocp_tables[(A)][(B)]
+
+typedef enum {
+ offset_ocp_file_size = 0,
+ offset_ocp_name,
+ offset_ocp_area,
+ offset_ocp_external,
+ offset_ocp_external_arg,
+ offset_ocp_input,
+ offset_ocp_output,
+ offset_ocp_no_tables,
+ offset_ocp_no_states,
+ offset_ocp_table_base,
+ offset_ocp_state_base,
+ offset_ocp_info /* 11 */
+} ocp_offsets;
+
+# define ocp_file_size(A) ocp_info(A,offset_ocp_file_size)
+# define ocp_name(A) ocp_info(A,offset_ocp_name)
+# define ocp_area(A) ocp_info(A,offset_ocp_area)
+# define ocp_external(A) ocp_info(A,offset_ocp_external)
+# define ocp_external_arg(A) ocp_info(A,offset_ocp_external_arg)
+# define ocp_input(A) ocp_info(A,offset_ocp_input)
+# define ocp_output(A) ocp_info(A,offset_ocp_output)
+# define ocp_no_tables(A) ocp_info(A,offset_ocp_no_tables)
+# define ocp_no_states(A) ocp_info(A,offset_ocp_no_states)
+# define ocp_table_base(A) ocp_info(A,offset_ocp_table_base)
+# define ocp_state_base(A) ocp_info(A,offset_ocp_state_base)
+
+extern internal_ocp_number read_ocp_info(pointer u, char *nom,
+ char *aire, char *ext,
+ boolean external_ocp);
+
+extern void init_null_ocp(str_number a, str_number n);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/ocp/readocp.w b/Build/source/texk/web2c/luatexdir/ocp/readocp.w
new file mode 100644
index 00000000000..7beee600347
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/readocp.w
@@ -0,0 +1,273 @@
+% readocp.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: readocp.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/ocp/readocp.w $";
+
+@ @c
+static char *b_test_in(char *nam)
+{
+ if (program_name_set) {
+ return (char *) kpse_find_file(nam, kpse_program_binary_format, true);
+ }
+ return NULL;
+}
+
+
+static unsigned char *ocp_buffer = NULL; /* byte buffer for ocp files */
+static int ocp_size = 0; /* total size of the ocp file */
+static int ocp_cur = 0; /* index into |ocp_buffer| */
+
+@ @c
+void init_null_ocp(str_number a, str_number n)
+{
+ ocp_ptr = null_ocp;
+ allocate_ocp_table(null_ocp, 17);
+ ocp_file_size(null_ocp) = 17;
+ ocp_name(null_ocp) = n;
+ ocp_area(null_ocp) = a;
+ ocp_external(null_ocp) = 0;
+ ocp_external_arg(null_ocp) = 0;
+ ocp_input(null_ocp) = 1;
+ ocp_output(null_ocp) = 1;
+ ocp_no_tables(null_ocp) = 0;
+ ocp_no_states(null_ocp) = 1;
+ ocp_table_base(f) = offset_ocp_info;
+ ocp_state_base(f) = offset_ocp_info;
+ ocp_info(null_ocp, offset_ocp_info) = offset_ocp_info + 2; /* number of entries */
+ ocp_info(null_ocp, offset_ocp_info + 1) = offset_ocp_info + 5; /* number of entries */
+ ocp_info(null_ocp, offset_ocp_info + 2) = 23; /* |OTP_LEFT_START| */
+ ocp_info(null_ocp, offset_ocp_info + 3) = 3; /* |OTP_RIGHT_CHAR| */
+ ocp_info(null_ocp, offset_ocp_info + 4) = 36; /* |OTP_STOP| */
+}
+
+
+
+@ $\Omega$ checks the information of a \.{OCP} 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
+is called |read_ocp_info|. It has three parameters: the user ocp
+identifier~|u|, and the file name and area strings |nom| and |aire|.
+
+The subroutine opens and closes a global file variable called |ocp_file|.
+It returns the value of the internal ocp number that was just loaded.
+If an error is detected, an error message is issued and no ocp
+information is stored; |null_ocp| is returned in this case.
+
+@c
+/* do this when the \.{OCP} data is wrong */
+#define ocp_abort(A) do { \
+ tprint("OCP file error ("); \
+ tprint(A); tprint(")"); print_ln(); \
+ goto BAD_OCP; \
+} while (0)
+
+/* macros for reading and storing ocp data */
+
+#define add_to_ocp_info(A) ocp_tables[f][ocpmem_run_ptr++]=(A)
+#define ocp_read(A) do { \
+ ocpword=ocp_buffer[ocp_cur++]; \
+ if (ocpword>127) ocp_abort("checking first octet"); \
+ ocpword=ocpword*0400+ocp_buffer[ocp_cur++]; \
+ ocpword=ocpword*0400+ocp_buffer[ocp_cur++]; \
+ ocpword=ocpword*0400+ocp_buffer[ocp_cur++]; \
+ (A)=ocpword; \
+ } while (0)
+
+#define ocp_read_all(A) ocp_read(A)
+#define ocp_read_info do { ocp_read_all(ocpword); add_to_ocp_info(ocpword); } while (0)
+
+
+
+@ Input a \.{OCP} file
+
+@c
+internal_ocp_number
+read_ocp_info(pointer u, char *nom, char *aire, char *ext, boolean external_ocp)
+{
+ boolean file_opened; /* was |ocp_file| successfully opened? */
+ boolean res;
+ int callback_id;
+ char *cnam; /* C version of file name */
+ internal_ocp_number f; /* the new ocp's number */
+ internal_ocp_number g; /* the number to return */
+ int ocpword;
+ ocp_index ocpmem_run_ptr;
+ int ocp_length, real_ocp_length; /* length of ocp file */
+ ocp_index previous_address;
+ int temp_ocp_input;
+ int temp_ocp_output;
+ int temp_ocp_no_tables;
+ int temp_ocp_no_states;
+ int i, new_offset, room_for_tables, room_for_states;
+ g = null_ocp;
+ f = null_ocp;
+ cnam = NULL;
+ file_opened = false;
+ if (external_ocp) {
+ /* Check |ocp_file| exists */
+ cnam =
+ xmalloc((unsigned) (strlen(nom) + strlen(aire) + strlen(ext) + 1));
+ sprintf(cnam, "%s%s%s", aire, nom, ext);
+ cnam = b_test_in(cnam);
+ if (!cnam)
+ ocp_abort("opening file");
+ f = ocp_ptr + 1;
+ allocate_ocp_table(f, 13);
+ ocp_file_size(f) = 13;
+ ocp_external(f) = maketexstring(cnam);
+ scan_string_argument();
+ ocp_external_arg(f) = cur_val;
+ ocp_name(f) = get_nullstr();
+ ocp_area(f) = get_nullstr();
+ ocp_state_base(f) = 0;
+ ocp_table_base(f) = 0;
+ ocp_input(f) = 1;
+ ocp_output(f) = 1;
+ ocp_info(f, offset_ocp_info) = 0;
+ ocp_ptr = f;
+ g = f;
+ goto DONE;
+
+ } else {
+ /* Open |ocp_file| for input */
+ char *cname = xmalloc((unsigned)
+ (strlen(nom) + strlen(aire) + strlen(".ocp") +
+ 1));
+ sprintf(cname, "%s%s.ocp", aire, nom);
+ xfree(ocp_buffer);
+ ocp_cur = 0;
+ ocp_size = 0;
+ cnam = luatex_find_file(cname, find_ocp_file_callback);
+ callback_id = callback_defined(read_ocp_file_callback);
+ if (cnam && callback_id > 0) {
+ res = run_callback(callback_id, "S->bSd", cnam,
+ &file_opened, &ocp_buffer, &ocp_size);
+ if (!res)
+ ocp_abort("callback error");
+ if (!file_opened)
+ ocp_abort("opening file");
+ } else {
+ FILE *ocp_file = NULL;
+ if (!cnam)
+ cnam = cname;
+ if (!luatex_open_input
+ (&ocp_file, cnam, kpse_ocp_format, FOPEN_RBIN_MODE, true))
+ ocp_abort("opening file");
+ file_opened = true;
+ res = read_ocp_file(ocp_file, &ocp_buffer, &ocp_size);
+ close_file(ocp_file);
+ if (!res)
+ ocp_abort("reading file");
+ }
+ if (ocp_size == 0)
+ ocp_abort("checking size");
+
+ /* Read the {\.{OCP}} file */
+ f = ocp_ptr + 1;
+ ocpmem_run_ptr = offset_ocp_info;
+ ocp_read(ocp_length);
+ real_ocp_length = ocp_length - 7;
+ ocp_read_all(temp_ocp_input);
+ ocp_read_all(temp_ocp_output);
+ ocp_read_all(temp_ocp_no_tables);
+ ocp_read_all(room_for_tables);
+ ocp_read_all(temp_ocp_no_states);
+ ocp_read_all(room_for_states);
+ if (real_ocp_length !=
+ (temp_ocp_no_tables + room_for_tables +
+ temp_ocp_no_states + room_for_states))
+ ocp_abort("checking size");
+ real_ocp_length = real_ocp_length + 12 +
+ temp_ocp_no_states + temp_ocp_no_tables;
+ allocate_ocp_table(f, real_ocp_length);
+ ocp_external(f) = 0;
+ ocp_external_arg(f) = 0;
+ ocp_file_size(f) = real_ocp_length;
+ ocp_input(f) = temp_ocp_input;
+ ocp_output(f) = temp_ocp_output;
+ ocp_no_tables(f) = temp_ocp_no_tables;
+ ocp_no_states(f) = temp_ocp_no_states;
+ ocp_table_base(f) = ocpmem_run_ptr;
+ if (ocp_no_tables(f) != 0) {
+ previous_address = ocpmem_run_ptr + 2 * (ocp_no_tables(f));
+ for (i = 1; i <= ocp_no_tables(f); i++) {
+ add_to_ocp_info(previous_address);
+ ocp_read_all(new_offset);
+ add_to_ocp_info(new_offset);
+ previous_address = previous_address + new_offset;
+ }
+ }
+ if (room_for_tables != 0) {
+ for (i = 1; i <= room_for_tables; i++) {
+ ocp_read_info;
+ }
+ }
+ ocp_state_base(f) = ocpmem_run_ptr;
+ if (ocp_no_states(f) != 0) {
+ previous_address = ocpmem_run_ptr + 2 * (ocp_no_states(f));
+ for (i = 1; i <= ocp_no_states(f); i++) {
+ add_to_ocp_info(previous_address);
+ ocp_read_all(new_offset);
+ add_to_ocp_info(new_offset);
+ previous_address = previous_address + new_offset;
+ }
+ }
+ if (room_for_states != 0) {
+ for (i = 1; i <= room_for_states; i++) {
+ ocp_read_info;
+ }
+ }
+ ocp_ptr = f;
+ g = f;
+ goto DONE;
+ }
+ BAD_OCP:
+ {
+ /* Report that the ocp won't be loaded */
+ /* $\Omega$ does not give precise details about why it
+ rejects a particular \.{OCP} file. */
+ const char *hlp[] = {
+ "I wasn't able to read the data for this ocp,",
+ "so I will ignore the ocp specification.",
+ NULL
+ };
+ char errmsg[256];
+ char *c = makecstring(cs_text(u));
+ if (file_opened) {
+ snprintf(errmsg, 255,
+ "Translation process \\%s=%s not loadable: Bad ocp file",
+ c, cnam);
+ } else {
+ snprintf(errmsg, 255,
+ "Translation process \\%s=%s not loadable: ocp file not found",
+ c, cnam);
+ }
+ free(c);
+ tex_error(errmsg, hlp);
+ }
+ DONE:
+ ocp_name(f) = maketexstring(nom);
+ ocp_area(f) = maketexstring(aire);
+ return g;
+}
diff --git a/Build/source/texk/web2c/luatexdir/ocp/runocp.h b/Build/source/texk/web2c/luatexdir/ocp/runocp.h
new file mode 100644
index 00000000000..bf94918dc2e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/runocp.h
@@ -0,0 +1,60 @@
+/* runocp.h
+
+ Copyright 2006-2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: runocp.h 3302 2009-12-25 12:49:14Z oneiros $ */
+
+#ifndef RUNOCP_H
+
+# define RUNOCP_H 1
+
+# define active_mem_size 50000 /* number of words of |active_info| for active ocps */
+
+typedef int active_index;
+
+extern memory_word active_info[(active_mem_size + 1)];
+extern active_index active_min_ptr;
+extern active_index active_max_ptr;
+extern active_index active_real;
+
+# define active_ocp(A) active_info[(A)].hh.u.B0
+# define active_counter(A) active_info[(A)].hh.u.B1
+# define active_lstack_no(A) active_info[(A)+1].cint
+
+extern boolean is_last_ocp(scaled llstack_no, int counter);
+
+extern void print_active_ocps(void);
+extern void add_ocp_stack(int min_index, scaled min_value);
+extern void active_compile(void);
+
+extern void run_ocp(void);
+extern void run_otp(void);
+
+extern void do_push_ocp_list(small_number a);
+extern void do_pop_ocp_list(small_number a);
+extern void do_clear_ocp_lists(small_number a);
+
+extern void dump_active_ocp_info(void);
+extern void undump_active_ocp_info(void);
+
+extern void initialize_ocp_buffers(int ocp_buf_size, int ocp_stack_size);
+
+/* for ocplist.h */
+/* typedef int ocp_list_index ; */
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/ocp/runocp.w b/Build/source/texk/web2c/luatexdir/ocp/runocp.w
new file mode 100644
index 00000000000..51d28c6ebc8
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/ocp/runocp.w
@@ -0,0 +1,1069 @@
+% runocp.w
+%
+% Copyright 2006-2009 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+
+static const char _svn_version[] =
+ "$Id: runocp.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/ocp/runocp.w $";
+
+memory_word active_info[(active_mem_size + 1)];
+active_index active_min_ptr = 0; /* first unused word of |active_info| */
+active_index active_max_ptr = 0; /* last unused word of |active_info| */
+active_index active_real = 0;
+
+static ocp_list_index holding[(active_mem_size + 1)] = { 0 };
+
+@ Here we do the main work required for reading and interpreting
+ $\Omega$ Compiled Translation Processes.
+
+@c
+#define ocp_list_id_text(A) cs_text(ocp_list_id_base+(A))
+
+#define ocp_active_min_ptr_base (ocp_active_number_base+1)
+#define ocp_active_max_ptr_base (ocp_active_min_ptr_base+1)
+#define ocp_active_base (ocp_active_max_ptr_base+1)
+
+
+@ Here are all the instructions in our mini-assembler.
+
+@c
+typedef enum {
+ otp_right_output = 1,
+ otp_right_num = 2,
+ otp_right_char = 3,
+ otp_right_lchar = 4,
+ otp_right_some = 5,
+ otp_pback_output = 6,
+ otp_pback_num = 7,
+ otp_pback_char = 8,
+ otp_pback_lchar = 9,
+ otp_pback_some = 10,
+ otp_add = 11,
+ otp_sub = 12,
+ otp_mult = 13,
+ otp_div = 14,
+ otp_mod = 15,
+ otp_lookup = 16,
+ otp_push_num = 17,
+ otp_push_char = 18,
+ otp_push_lchar = 19,
+ otp_state_change = 20,
+ otp_state_push = 21,
+ otp_state_pop = 22,
+ otp_left_start = 23,
+ otp_left_return = 24,
+ otp_left_backup = 25,
+ otp_goto = 26,
+ otp_goto_ne = 27,
+ otp_goto_eq = 28,
+ otp_goto_lt = 29,
+ otp_goto_le = 30,
+ otp_goto_gt = 31,
+ otp_goto_ge = 32,
+ otp_goto_no_advance = 33,
+ otp_goto_beg = 34,
+ otp_goto_end = 35,
+ otp_stop = 36
+} otp_command_codes;
+
+#define check_buffer() do { \
+ if (last==buf_size-2) { \
+ check_buffer_overflow(buf_size+4); \
+ } \
+ } while (0)
+
+@ Of course we want to define macros that suppress the detail of how ocp
+information is actually packed, so that we don't have to write things like
+$$\hbox{|ocp_info[k+ocp_info[j+ocp_state_base[i]]]|}$$
+too often. The \.{WEB} definitions here make |ocp_state_entry(i)(j)(k)|
+(|ocp_table_entry(i)(j)(k)|) the |k|-th word in the |j|-th state (table)
+of the |i|-th ocp.
+@^inner loop@>
+
+@c
+#define ocp_state_entry(A,B,C) ocp_tables[(A)][ocp_tables[(A)][ocp_state_base((A))+((B)*2)]+(C)]
+
+#define ocp_state_no(A,B) ocp_tables[(A)][ocp_state_base(A)+((B)*2)+1]
+
+#define ocp_table_entry(A,B,C) ocp_tables[(A)][ocp_tables[(A)][ocp_table_base((A))+(B)*2]+(C)]
+
+#define ocp_table_no(A,B) ocp_tables[(A)][ocp_table_base((A))+((B)*2)+1]
+
+#define otp_cur_state otp_states[otp_state_ptr]
+
+#define tsuccumb pdftex_fail
+
+halfword otp_init_input_start;
+halfword otp_init_input_last;
+halfword otp_init_input_end;
+quarterword *otp_init_input_buf;
+
+halfword otp_input_start;
+halfword otp_input_last;
+halfword otp_input_end;
+quarterword *otp_input_buf;
+
+halfword otp_output_end;
+quarterword *otp_output_buf;
+
+halfword otp_stack_used;
+halfword otp_stack_last;
+halfword otp_stack_new;
+quarterword *otp_stack_buf;
+
+halfword otp_pc;
+
+halfword otp_calc_ptr;
+halfword *otp_calcs;
+halfword otp_state_ptr;
+halfword *otp_states;
+
+halfword otp_input_char;
+halfword otp_calculated_char;
+halfword otp_no_input_chars;
+
+halfword otp_instruction;
+halfword otp_instr;
+halfword otp_arg;
+halfword otp_first_arg;
+halfword otp_second_arg;
+
+halfword otp_input_ocp;
+
+boolean otp_finished;
+int otp_ext_str;
+int otp_ext_str_arg;
+int otp_ext_i;
+
+#define otp_set_instruction() do { \
+ if (otp_pc>=ocp_state_no(otp_input_ocp,otp_cur_state)) { \
+ tsuccumb("bad OCP program -- PC not valid"); \
+ } \
+ otp_instruction=ocp_state_entry(otp_input_ocp,otp_cur_state,otp_pc); \
+ otp_instr=otp_instruction / 0x1000000; \
+ otp_arg=otp_instruction % 0x1000000; \
+ } while (0)
+
+
+#define otp_check_char(A) do { \
+ if ((1>(A)) || ((A)>otp_no_input_chars)) { \
+ tsuccumb("right hand side of OCP expression is bad"); \
+ } \
+ } while (0)
+
+
+#define otp_get_char(A) do { \
+ otp_check_char((A)); \
+ if ((A)>otp_stack_last) { \
+ otp_calculated_char=otp_input_buf[otp_input_start+(A)-otp_stack_last]; \
+ } else { \
+ otp_calculated_char=otp_stack_buf[(A)]; \
+ } \
+ } while (0)
+
+
+@ @c
+void overflow_ocp_buf_size(void)
+{
+ overflow("ocp_buf_size", (unsigned) ocp_buf_size);
+}
+
+void overflow_ocp_stack_size(void)
+{
+ overflow("ocp_stack_size", (unsigned) ocp_stack_size);
+}
+
+void run_otp(void)
+{
+ halfword otp_counter;
+ otp_set_instruction();
+ switch (otp_instr) {
+ /* Run the |otp_right| instructions */
+ case otp_right_output:
+ incr(otp_output_end);
+ if (otp_output_end > ocp_buf_size)
+ overflow_ocp_buf_size();
+ otp_output_buf[otp_output_end] = (quarterword) otp_calcs[otp_calc_ptr];
+ decr(otp_calc_ptr);
+ incr(otp_pc);
+ break;
+ case otp_right_num:
+ incr(otp_output_end);
+ if (otp_output_end > ocp_buf_size)
+ overflow_ocp_buf_size();
+ otp_output_buf[otp_output_end] = (quarterword) otp_arg;
+ incr(otp_pc);
+ break;
+ case otp_right_char:
+ otp_get_char(otp_arg);
+ incr(otp_output_end);
+ if (otp_output_end > ocp_buf_size)
+ overflow_ocp_buf_size();
+ otp_output_buf[otp_output_end] = (quarterword) otp_calculated_char;
+ incr(otp_pc);
+ break;
+ case otp_right_lchar:
+ otp_get_char(otp_no_input_chars - otp_arg);
+ incr(otp_output_end);
+ if (otp_output_end > ocp_buf_size)
+ overflow_ocp_buf_size();
+ otp_output_buf[otp_output_end] = (quarterword) otp_calculated_char;
+ incr(otp_pc);
+ break;
+ case otp_right_some:
+ otp_first_arg = otp_arg + 1;
+ incr(otp_pc);
+ otp_set_instruction();
+ otp_second_arg = otp_no_input_chars - otp_arg;
+ for (otp_counter = otp_first_arg; otp_counter <= otp_second_arg;
+ otp_counter++) {
+ otp_get_char(otp_counter);
+ incr(otp_output_end);
+ if (otp_output_end > ocp_buf_size)
+ overflow_ocp_buf_size();
+ otp_output_buf[otp_output_end] = (quarterword) otp_calculated_char;
+ }
+ incr(otp_pc);
+ break;
+
+ /* Run the |otp_pback| instructions */
+ case otp_pback_output:
+ incr(otp_stack_new);
+ if (otp_stack_new >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_stack_buf[otp_stack_new] = (quarterword) otp_calcs[otp_calc_ptr];
+ decr(otp_calc_ptr);
+ incr(otp_pc);
+ break;
+ case otp_pback_num:
+ incr(otp_stack_new);
+ if (otp_stack_new >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_stack_buf[otp_stack_new] = (quarterword) otp_arg;
+ incr(otp_pc);
+ break;
+ case otp_pback_char:
+ otp_get_char(otp_arg);
+ incr(otp_stack_new);
+ if (otp_stack_new >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_stack_buf[otp_stack_new] = (quarterword) otp_calculated_char;
+ incr(otp_pc);
+ break;
+ case otp_pback_lchar:
+ otp_get_char(otp_no_input_chars - otp_arg);
+ incr(otp_stack_new);
+ if (otp_stack_new >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_stack_buf[otp_stack_new] = (quarterword) otp_calculated_char;
+ incr(otp_pc);
+ break;
+ case otp_pback_some:
+ otp_first_arg = otp_arg + 1;
+ incr(otp_pc);
+ otp_set_instruction();
+ otp_second_arg = otp_no_input_chars - otp_arg;
+ for (otp_counter = otp_first_arg; otp_counter <= otp_second_arg;
+ otp_counter++) {
+ otp_get_char(otp_counter);
+ incr(otp_stack_new);
+ if (otp_stack_new >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_stack_buf[otp_stack_new] = (quarterword) otp_calculated_char;
+ }
+ incr(otp_pc);
+ break;
+
+ /* Run the arithmetic instructions */
+ case otp_add:
+ otp_calcs[otp_calc_ptr - 1] =
+ otp_calcs[otp_calc_ptr - 1] + otp_calcs[otp_calc_ptr];
+ incr(otp_pc);
+ decr(otp_calc_ptr);
+ break;
+ case otp_sub:
+ otp_calcs[otp_calc_ptr - 1] =
+ otp_calcs[otp_calc_ptr - 1] - otp_calcs[otp_calc_ptr];
+ incr(otp_pc);
+ decr(otp_calc_ptr);
+ break;
+ case otp_mult:
+ otp_calcs[otp_calc_ptr - 1] =
+ otp_calcs[otp_calc_ptr - 1] * otp_calcs[otp_calc_ptr];
+ incr(otp_pc);
+ decr(otp_calc_ptr);
+ break;
+ case otp_div:
+ otp_calcs[otp_calc_ptr - 1] =
+ otp_calcs[otp_calc_ptr - 1] / otp_calcs[otp_calc_ptr];
+ incr(otp_pc);
+ decr(otp_calc_ptr);
+ break;
+ case otp_mod:
+ otp_calcs[otp_calc_ptr - 1] =
+ otp_calcs[otp_calc_ptr - 1] % otp_calcs[otp_calc_ptr];
+ incr(otp_pc);
+ decr(otp_calc_ptr);
+ break;
+ case otp_lookup:
+ if (otp_calcs[otp_calc_ptr] >=
+ ocp_table_no(otp_input_ocp, otp_calcs[otp_calc_ptr - 1])) {
+ tsuccumb("bad OCP program -- table index not valid");
+ }
+ otp_calcs[otp_calc_ptr - 1] =
+ ocp_table_entry(otp_input_ocp, otp_calcs[otp_calc_ptr - 1],
+ otp_calcs[otp_calc_ptr]);
+ incr(otp_pc);
+ decr(otp_calc_ptr);
+ break;
+ case otp_push_num:
+ incr(otp_calc_ptr);
+ if (otp_calc_ptr >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_calcs[otp_calc_ptr] = otp_arg;
+ incr(otp_pc);
+ break;
+ case otp_push_char:
+ otp_get_char(otp_arg);
+ incr(otp_calc_ptr);
+ if (otp_calc_ptr >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_calcs[otp_calc_ptr] = otp_calculated_char;
+ incr(otp_pc);
+ break;
+ case otp_push_lchar:
+ otp_get_char(otp_no_input_chars - otp_arg);
+ incr(otp_calc_ptr);
+ if (otp_calc_ptr >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_calcs[otp_calc_ptr] = otp_calculated_char;
+ incr(otp_pc);
+ break;
+
+ /* Run the |otp_state| instructions */
+ case otp_state_change:
+ otp_input_start = otp_input_last;
+ for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
+ otp_counter++) {
+ otp_stack_buf[otp_counter] =
+ otp_stack_buf[otp_counter + otp_stack_used];
+ }
+ otp_stack_new = otp_stack_new - otp_stack_used;
+ otp_stack_last = otp_stack_new;
+ otp_stack_used = 0;
+ otp_states[otp_state_ptr] = otp_arg;
+ otp_pc = 0;
+ break;
+ case otp_state_push:
+ otp_input_start = otp_input_last;
+ for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
+ otp_counter++) {
+ otp_stack_buf[otp_counter] =
+ otp_stack_buf[otp_counter + otp_stack_used];
+ };
+ otp_stack_new = otp_stack_new - otp_stack_used;
+ otp_stack_last = otp_stack_new;
+ otp_stack_used = 0;
+ incr(otp_state_ptr);
+ if (otp_state_ptr >= ocp_stack_size)
+ overflow_ocp_stack_size();
+ otp_states[otp_state_ptr] = otp_arg;
+ otp_pc = 0;
+ break;
+ case otp_state_pop:
+ otp_input_start = otp_input_last;
+ for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
+ otp_counter++) {
+ otp_stack_buf[otp_counter] =
+ otp_stack_buf[otp_counter + otp_stack_used];
+ }
+ otp_stack_new = otp_stack_new - otp_stack_used;
+ otp_stack_last = otp_stack_new;
+ otp_stack_used = 0;
+ if (otp_state_ptr > 0)
+ decr(otp_state_ptr);
+ otp_pc = 0;
+ break;
+
+ /* Run the |otp_left| instructions */
+ case otp_left_start:
+ otp_input_start = otp_input_last;
+ otp_input_last = otp_input_start;
+ otp_stack_used = 0;
+ if ((otp_stack_last == 0) && (otp_input_last >= otp_input_end)) {
+ otp_finished = true;
+ } else if ((otp_stack_used < otp_stack_last)) {
+ incr(otp_stack_used); /* no overflow problem */
+ otp_input_char = otp_stack_buf[otp_stack_used];
+ otp_no_input_chars = 1;
+ incr(otp_pc);
+ } else {
+ incr(otp_input_last); /* no overflow problem */
+ otp_input_char = otp_input_buf[otp_input_last];
+ otp_no_input_chars = 1;
+ incr(otp_pc);
+ }
+ break;
+ case otp_left_return:
+ otp_input_last = otp_input_start;
+ otp_stack_used = 0;
+ if ((otp_stack_used < otp_stack_last)) {
+ incr(otp_stack_used); /* no overflow problem */
+ otp_input_char = otp_stack_buf[otp_stack_used];
+ otp_no_input_chars = 1;
+ incr(otp_pc);
+ } else {
+ incr(otp_input_last); /* no overflow problem */
+ otp_input_char = otp_input_buf[otp_input_last];
+ otp_no_input_chars = 1;
+ incr(otp_pc);
+ }
+ break;
+ case otp_left_backup:
+ if (otp_input_start < otp_input_last) {
+ decr(otp_input_last);
+ otp_input_char = otp_input_buf[otp_input_last];
+ } else {
+ decr(otp_stack_used);
+ otp_input_char = otp_stack_buf[otp_stack_used];
+ }
+ decr(otp_no_input_chars);
+ incr(otp_pc);
+ break;
+
+ /* Run the |otp_goto| instructions */
+ case otp_goto:
+ otp_pc = otp_arg;
+ break;
+ case otp_goto_ne:
+ otp_first_arg = otp_arg;
+ incr(otp_pc);
+ otp_set_instruction();
+ if (otp_input_char != otp_first_arg) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_eq:
+ otp_first_arg = otp_arg;
+ incr(otp_pc);
+ otp_set_instruction();
+ if (otp_input_char == otp_first_arg) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_lt:
+ otp_first_arg = otp_arg;
+ incr(otp_pc);
+ otp_set_instruction();
+ if (otp_input_char < otp_first_arg) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_le:
+ otp_first_arg = otp_arg;
+ incr(otp_pc);
+ otp_set_instruction();
+ if (otp_input_char <= otp_first_arg) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_gt:
+ otp_first_arg = otp_arg;
+ incr(otp_pc);
+ otp_set_instruction();
+ if (otp_input_char > otp_first_arg) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_ge:
+ otp_first_arg = otp_arg;
+ incr(otp_pc);
+ otp_set_instruction();
+ if (otp_input_char >= otp_first_arg) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_no_advance:
+ if (otp_stack_used < otp_stack_last) {
+ incr(otp_stack_used); /* no overflow problem */
+ otp_input_char = otp_stack_buf[otp_stack_used];
+ incr(otp_no_input_chars); /* no overflow problem */
+ incr(otp_pc);
+ } else if (otp_input_last >= otp_input_end) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_input_last); /* no overflow problem */
+ otp_input_char = otp_input_buf[otp_input_last];
+ incr(otp_no_input_chars); /* no overflow problem */
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_beg:
+ if (otp_input_last == 0) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+ case otp_goto_end:
+ if (otp_input_last >= otp_input_end) {
+ otp_pc = otp_arg;
+ } else {
+ incr(otp_pc);
+ }
+ break;
+
+ /* Run the |otp_stop| instruction */
+ case otp_stop:
+ otp_input_start = otp_input_last;
+ for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
+ otp_counter++) {
+ otp_stack_buf[otp_counter] =
+ otp_stack_buf[otp_counter + otp_stack_used];
+ }
+ otp_stack_new = otp_stack_new - otp_stack_used;
+ otp_stack_last = otp_stack_new;
+ otp_stack_used = 0;
+ otp_pc = 0;
+ break;
+
+ default:
+ tsuccumb("bad OCP program -- unknown instruction");
+ break;
+ }
+}
+
+@ @c
+#define FPUTC(a,b) fputc((int)(a),b)
+
+void run_external_ocp(char *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;
+#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);
+ in_file = fopen(in_file_name, FOPEN_WBIN_MODE);
+#else
+ int in_file_fd;
+ int out_file_fd;
+ 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 = fopen(out_file_name, FOPEN_RBIN_MODE);
+#else
+ 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);
+ otp_output_end = 0;
+ otp_output_buf[otp_output_end] = 0;
+ while ((c_in = (int) fgetc(out_file)) != -1) {
+ if (c_in >= 0xfc) {
+ c = (unsigned) (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 = (unsigned) (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 = (unsigned) (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 = (unsigned) (c_in & 0xf) << 12;
+ advance_cin;
+ c |= (c_in & 0x3f) << 6;
+ advance_cin;
+ c |= (c_in & 0x3f);
+ } else if (c_in >= 0x80) {
+ c = (unsigned) (c_in & 0x1f) << 6;
+ advance_cin;
+ c |= (c_in & 0x3f);
+ } else {
+ c = (unsigned) (c_in & 0x7f);
+ }
+ otp_output_buf[++otp_output_end] = (quarterword) c;
+ }
+ fclose(out_file);
+
+ end_of_while:
+ remove(in_file_name);
+ remove(out_file_name);
+}
+
+@ @c
+void run_ocp(void)
+{
+ int t = 0;
+ halfword otp_i;
+ halfword otp_counter;
+ /* The OTP input buffer is an array of 16-bit values.
+ The range |0xD800| \dots |0xDFFF| is used for surrogate pairs,
+ so it cannot be used for simple 16-bit values like it is in
+ Omega, and incompatibility with Aleph is unavoidable.
+ */
+
+ otp_init_input_end = 0;
+ while ((cur_cmd == letter_cmd) || (cur_cmd == other_char_cmd) ||
+ (cur_cmd == char_given_cmd) || (cur_cmd == spacer_cmd)) {
+ incr(otp_init_input_end);
+ if (otp_init_input_end > ocp_buf_size)
+ overflow_ocp_buf_size();
+ /* |cur_chr| can cover the full range |0..0x10FFFF| */
+ if (cur_chr < 0x10000) {
+ otp_init_input_buf[otp_init_input_end] = (quarterword) cur_chr;
+ } else {
+ otp_init_input_buf[otp_init_input_end] = (quarterword)
+ (((cur_chr - 0x10000) / 0x400) + 0xD800);
+ incr(otp_init_input_end);
+ if (otp_init_input_end > ocp_buf_size)
+ overflow_ocp_buf_size();
+ otp_init_input_buf[otp_init_input_end] = (quarterword)
+ (((cur_chr - 0x10000) % 0x400) + 0xDC00);
+ }
+ get_token();
+ if ((cur_cmd != letter_cmd) && (cur_cmd != other_char_cmd) &&
+ (cur_cmd != char_given_cmd)) {
+ x_token();
+ if (cur_cmd == char_num_cmd) {
+ scan_char_num();
+ cur_cmd = other_char_cmd;
+ cur_chr = cur_val;
+ }
+ }
+ }
+ back_input();
+ otp_input_end = otp_init_input_end;
+ for (otp_i = 0; otp_i <= otp_init_input_end; otp_i++) {
+ otp_input_buf[otp_i] = otp_init_input_buf[otp_i];
+ }
+
+ otp_input_ocp = active_ocp(active_real);
+ if (otp_input_ocp == 0) {
+ tex_error("Null ocp being used: all input lost", NULL);
+ otp_output_end = 0;
+ } else if (ocp_external(otp_input_ocp) == 0) {
+ otp_input_start = 0;
+ otp_input_last = 0;
+ otp_stack_used = 0;
+ otp_stack_last = 0;
+ otp_stack_new = 0;
+ otp_output_end = 0;
+ otp_pc = 0;
+ otp_finished = false;
+ otp_calc_ptr = 0;
+ otp_calcs[otp_calc_ptr] = 0;
+ otp_state_ptr = 0;
+ otp_states[otp_state_ptr] = 0;
+ while (!otp_finished)
+ run_otp();
+ } else {
+ /* k=0; ? */
+ char *cmd = makecstring(ocp_external(otp_input_ocp));
+ char *arg = makecstring(ocp_external_arg(otp_input_ocp));
+ char *cmdline = xmalloc((unsigned) (strlen(cmd) + strlen(arg) + 3));
+ strcpy(cmdline, cmd);
+ strcat(cmdline, " ");
+ strcat(cmdline, arg);
+ xfree(cmd);
+ xfree(arg);
+ run_external_ocp(cmdline);
+ }
+
+
+ /* The OTP output buffer is an array of 16-bit values. To convert back
+ to the |buffer| it has to be re-encoded into UTF-8.
+ */
+
+ if ((first + otp_output_end) >= ocp_buf_size)
+ overflow_ocp_buf_size();
+ push_input();
+ current_ocp_lstack = active_lstack_no(active_real);
+ current_ocp_no = (short) active_counter(active_real);
+ istate = mid_line;
+ istart = first;
+ last = istart;
+ iloc = istart;
+ line_catcode_table = DEFAULT_CAT_TABLE;
+ line_partial = false;
+ for (otp_counter = 1; otp_counter <= otp_output_end; otp_counter++) {
+ /* convert back to utf-8 */
+ t = otp_output_buf[otp_counter];
+ if (otp_counter < otp_output_end) {
+ if ((t >= 0xD800) && (t < 0xDC00)) {
+ if ((otp_output_buf[otp_counter + 1] >= 0xDC00)
+ && (otp_output_buf[otp_counter + 1] < 0xE000)) {
+ incr(otp_counter);
+ t = (t - 0xD800) * 0x400 + (otp_output_buf[otp_counter] -
+ 0xDC00) + 0x10000;
+ }
+ } else if ((t >= 0xDC00) && (t < 0xE000)) {
+ if ((otp_output_buf[otp_counter + 1] >= 0xD800)
+ && (otp_output_buf[otp_counter + 1] < 0xDC00)) {
+ incr(otp_counter);
+ t = (otp_output_buf[otp_counter] - 0xD800) * 0x400 + (t -
+ 0xDC00)
+ + 0x10000;
+ }
+ }
+ }
+ if (t <= 0x7F) {
+ buffer[last] = (packed_ASCII_code) t;
+ } else if (t <= 0x7FF) {
+ buffer[last] = (packed_ASCII_code) (0xC0 + t / 0x40);
+ incr(last);
+ check_buffer();
+ buffer[last] = (packed_ASCII_code) (0x80 + t % 0x40);
+ } else if (t <= 0xFFFF) {
+ buffer[last] = (packed_ASCII_code) (0xE0 + t / 0x1000);
+ incr(last);
+ check_buffer();
+ buffer[last] = (packed_ASCII_code) (0x80 + (t % 0x1000) / 0x40);
+ incr(last);
+ check_buffer();
+ buffer[last] = (packed_ASCII_code) (0x80 + (t % 0x1000) % 0x40);
+ } else {
+ buffer[last] = (packed_ASCII_code) (0xF0 + t / 0x400000);
+ incr(last);
+ check_buffer();
+ buffer[last] = (packed_ASCII_code) (0x80 + (t % 0x40000) / 0x1000);
+ incr(last);
+ check_buffer();
+ buffer[last] =
+ (packed_ASCII_code) (0x80 + ((t % 0x40000) % 0x1000) / 0x40);
+ incr(last);
+ check_buffer();
+ buffer[last] =
+ (packed_ASCII_code) (0x80 + ((t % 0x40000) % 0x1000) % 0x40);
+ }
+ incr(last);
+ check_buffer();
+ }
+ ilimit = last - 1;
+ if (t > 0xFFFF)
+ decr(ilimit);
+ if (t > 0x7FF)
+ decr(ilimit);
+ if (t > 0x7F)
+ decr(ilimit);
+ first = last;
+
+}
+
+@ @c
+void initialize_ocp_buffers(int ocp_buf_size, int ocp_stack_size)
+{
+ otp_init_input_buf = xmallocarray(quarterword, (unsigned) ocp_buf_size);
+ otp_input_buf = xmallocarray(quarterword, (unsigned) ocp_buf_size);
+ otp_output_buf = xmallocarray(quarterword, (unsigned) ocp_buf_size);
+ otp_stack_buf = xmallocarray(quarterword, (unsigned) ocp_stack_size);
+ otp_calcs = xmallocarray(halfword, (unsigned) ocp_stack_size);
+ otp_states = xmallocarray(halfword, (unsigned) ocp_stack_size);
+}
+
+@ @c
+boolean is_last_ocp(scaled llstack_no, int counter)
+{
+ active_min_ptr = equiv(ocp_active_min_ptr_base);
+ active_max_ptr = equiv(ocp_active_max_ptr_base);
+ active_real = active_min_ptr;
+ while ((active_real < active_max_ptr) &&
+ (active_lstack_no(active_real) < llstack_no)) {
+ active_real = active_real + 2;
+ }
+ while ((active_real < active_max_ptr) &&
+ (active_lstack_no(active_real) == llstack_no) &&
+ (active_counter(active_real) <= counter)) {
+ active_real = active_real + 2;
+ }
+ return (active_real == active_max_ptr);
+}
+
+@ @c
+void print_active_ocps(void)
+{
+ int i;
+ tprint_nl("Active ocps: [");
+ i = active_min_ptr;
+ while (i < active_max_ptr) {
+ tprint("(");
+ print_scaled(active_lstack_no(i));
+ tprint(",");
+ print_int(active_counter(i));
+ tprint(",");
+ print_esc(cs_text(ocp_id_base + active_ocp(i)));
+ tprint(")");
+ if (i != (active_max_ptr - 2))
+ tprint(",");
+ i = i + 2;
+ }
+ tprint("]");
+}
+
+@ @c
+void add_ocp_stack(int min_index, scaled min_value)
+{
+ ocp_lstack_index p;
+ scaled llstack_no;
+ int counter;
+ scaled m;
+ m = min_value; /* TH: whatever this is .. */
+ p = ocp_list_lstack(holding[min_index]);
+ llstack_no = ocp_list_lstack_no(holding[min_index]);
+ counter = 0;
+ while (!(is_null_ocp_lstack(p))) {
+ active_ocp(active_max_ptr) = ocp_lstack_ocp(p);
+ active_counter(active_max_ptr) = (quarterword) counter;
+ active_lstack_no(active_max_ptr) = llstack_no;
+ p = ocp_lstack_lnext(p);
+ active_max_ptr = active_max_ptr + 2;
+ incr(counter); /* no overflow problem */
+ }
+}
+
+@ @c
+void active_compile(void)
+{
+ int i;
+ int min_index;
+ scaled min_stack_ocp;
+ scaled old_min;
+ int max_active;
+ scaled stack_value;
+ active_min_ptr = active_max_ptr;
+ min_stack_ocp = ocp_maxint;
+ max_active = equiv(ocp_active_number_base) - 1;
+ min_index = max_active; /* TH I hope ... */
+ for (i = max_active; i >= 0; i--) {
+ holding[i] = ocp_list_list[ocp_active_base + i];
+ stack_value = ocp_list_lstack_no(holding[i]);
+ if (stack_value < min_stack_ocp) {
+ min_index = i;
+ min_stack_ocp = stack_value;
+ }
+ }
+ while (min_stack_ocp < ocp_maxint) {
+ add_ocp_stack(min_index, min_stack_ocp);
+ old_min = min_stack_ocp;
+ min_stack_ocp = ocp_maxint;
+ for (i = max_active; i >= 0; i--) {
+ stack_value = ocp_list_lstack_no(holding[i]);
+ while (old_min == stack_value) {
+ holding[i] = ocp_list_lnext(holding[i]);
+ stack_value = ocp_list_lstack_no(holding[i]);
+ }
+ if (stack_value < min_stack_ocp) {
+ min_index = i;
+ min_stack_ocp = stack_value;
+ }
+ }
+ }
+}
+
+@ @c
+void do_push_ocp_list(small_number a)
+{
+ halfword ocp_list_no;
+ halfword old_number;
+ int i;
+ scan_ocp_list_ident();
+ ocp_list_no = cur_val;
+ old_number = equiv(ocp_active_number_base);
+ define(ocp_active_base + old_number, data_cmd, ocp_list_no);
+ define(ocp_active_number_base, data_cmd, (old_number + 1));
+ if (ocp_trace_level == 1) {
+ tprint_nl("New active ocp list: {");
+ for (i = old_number; i >= 0; i--) {
+ print_esc(ocp_list_id_text(equiv(ocp_active_base + i)));
+ tprint("=");
+ print_ocp_list(ocp_list_list[equiv(ocp_active_base + i)]);
+ if (i != 0)
+ tprint(",");
+ }
+ tprint("}");
+ }
+ active_compile();
+ define(ocp_active_min_ptr_base, data_cmd, active_min_ptr);
+ define(ocp_active_max_ptr_base, data_cmd, active_max_ptr);
+}
+
+@ @c
+void do_pop_ocp_list(small_number a)
+{
+ halfword old_number;
+ int i;
+ old_number = equiv(ocp_active_number_base);
+ if (old_number == 0) {
+ print_err("No active ocp lists to be popped");
+ } else {
+ define(ocp_active_number_base, data_cmd, (old_number - 1));
+ if (ocp_trace_level == 1) {
+ tprint_nl("New active ocp list: {");
+ for (i = (old_number - 2); i >= 0; i++) {
+ print_esc(ocp_list_id_text(equiv(ocp_active_base + i)));
+ tprint("=");
+ print_ocp_list(ocp_list_list[equiv(ocp_active_base + i)]);
+ if (i != 0)
+ tprint(",");
+ }
+ tprint("}");
+ }
+ active_compile();
+ define(ocp_active_min_ptr_base, data_cmd, active_min_ptr);
+ define(ocp_active_max_ptr_base, data_cmd, active_max_ptr);
+ }
+}
+
+@ @c
+void do_clear_ocp_lists(small_number a)
+{
+ define(ocp_active_number_base, data_cmd, 0);
+ active_compile();
+ define(ocp_active_min_ptr_base, data_cmd, active_min_ptr);
+ define(ocp_active_max_ptr_base, data_cmd, active_max_ptr);
+}
+
+
+@ @c
+void dump_active_ocp_info(void)
+{
+ int k;
+ dump_int(active_min_ptr);
+ dump_int(active_max_ptr);
+ for (k = 0; k <= active_max_ptr - 1; k++)
+ dump_wd(active_info[k]);
+ if (active_max_ptr > 0) {
+ print_ln();
+ print_int(active_max_ptr);
+ tprint(" words of active ocps");
+ }
+}
+
+void undump_active_ocp_info(void)
+{
+ int k;
+ undump_int(active_min_ptr);
+ undump_int(active_max_ptr);
+ for (k = 0; k <= active_max_ptr - 1; k++)
+ undump_wd(active_info[k]);
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pagetree.h b/Build/source/texk/web2c/luatexdir/pdf/pagetree.h
index 488c0cd129b..d4b8a11c134 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pagetree.h
+++ b/Build/source/texk/web2c/luatexdir/pdf/pagetree.h
@@ -17,13 +17,13 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: pagetree.h 2325 2009-04-18 11:24:38Z hhenkel $ */
+/* $Id: pagetree.h 3261 2009-12-18 11:38:21Z taco $ */
#ifndef PAGETREE_H
# define PAGETREE_H
-integer output_pages_tree(void);
-integer pdf_do_page_divert(integer, integer);
-void pdf_do_page_undivert(integer, integer);
+int output_pages_tree(PDF);
+int pdf_do_page_divert(PDF, int, int);
+void pdf_do_page_undivert(int, int);
#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pagetree.c b/Build/source/texk/web2c/luatexdir/pdf/pagetree.w
index 5e738695043..0a24b56ec97 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pagetree.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pagetree.w
@@ -1,40 +1,32 @@
-/* pagetree.c
-
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% pagetree.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
#include "ptexlib.h"
-#include "openbsd-compat.h"
+static const char _svn_version[] =
+ "$Id: pagetree.w 3573 2010-04-02 14:10:54Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pagetree.w $";
-#include "sys/types.h"
-#ifndef __MINGW32__
-# include "sysexits.h"
-#else
-# define EX_SOFTWARE 70
-#endif
-
-static const char __svn_version[] =
- "$Id: pagetree.c 2448 2009-06-08 07:43:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/pdf/pagetree.c $";
-
-/**********************************************************************/
-/* Page diversions */
+@* Page diversions.
+@ @c
#ifdef DEBUG
# define PAGES_TREE_KIDSMAX 3
#else
@@ -44,15 +36,15 @@ static const char __svn_version[] =
static struct avl_table *divert_list_tree = NULL;
typedef struct pages_entry_ {
- integer objnum; /* object number of this /Pages object */
- integer number_of_pages; /* total number of all pages below */
- integer number_of_kids; /* number of direct kid objects */
- integer kids[PAGES_TREE_KIDSMAX]; /* array of kid object numbers */
+ int objnum; /* object number of this /Pages object */
+ int number_of_pages; /* total number of all pages below */
+ int number_of_kids; /* number of direct kid objects */
+ int kids[PAGES_TREE_KIDSMAX]; /* array of kid object numbers */
struct pages_entry_ *next;
} pages_entry;
typedef struct divert_list_entry_ {
- integer divnum;
+ int divnum;
pages_entry *first;
pages_entry *last;
} divert_list_entry;
@@ -69,7 +61,8 @@ static int comp_divert_list_entry(const void *pa, const void *pb, void *p)
return 0;
}
-static pages_entry *new_pages_entry(void)
+@ @c
+static pages_entry *new_pages_entry(PDF pdf)
{
pages_entry *p;
int i;
@@ -78,11 +71,12 @@ static pages_entry *new_pages_entry(void)
for (i = 0; i < PAGES_TREE_KIDSMAX; i++)
p->kids[i] = 0;
p->next = NULL;
- pdf_create_obj(0, 0);
- p->objnum = obj_ptr;
+ pdf_create_obj(pdf, obj_type_pages, 0);
+ p->objnum = pdf->obj_ptr;
return p;
}
+@ @c
static divert_list_entry *new_divert_list_entry(void)
{
divert_list_entry *d;
@@ -91,6 +85,7 @@ static divert_list_entry *new_divert_list_entry(void)
return d;
}
+@ @c
static void ensure_list_tree(void)
{
if (divert_list_tree == NULL) {
@@ -100,7 +95,8 @@ static void ensure_list_tree(void)
}
}
-static divert_list_entry *get_divert_list(integer divnum)
+@ @c
+static divert_list_entry *get_divert_list(int divnum)
{
divert_list_entry *d, tmp;
void **aa;
@@ -115,9 +111,9 @@ static divert_list_entry *get_divert_list(integer divnum)
return d;
}
-/* pdf_do_page_divert() returns the current /Parent object number */
-
-integer pdf_do_page_divert(integer objnum, integer divnum)
+@ |pdf_do_page_divert()| returns the current /Parent object number
+@c
+int pdf_do_page_divert(PDF pdf, int objnum, int divnum)
{
divert_list_entry *d;
pages_entry *p;
@@ -126,13 +122,13 @@ integer pdf_do_page_divert(integer objnum, integer divnum)
struct avl_traverser t;
int i;
#endif
- // initialize the tree
+ /* initialize the tree */
ensure_list_tree();
- // make sure we have a list for this diversion
+ /* make sure we have a list for this diversion */
d = get_divert_list(divnum);
if (d->first == NULL || d->last->number_of_kids == PAGES_TREE_KIDSMAX) {
- // append a new pages_entry
- p = new_pages_entry();
+ /* append a new |pages_entry| */
+ p = new_pages_entry(pdf);
if (d->first == NULL)
d->first = p;
else
@@ -160,6 +156,7 @@ integer pdf_do_page_divert(integer objnum, integer divnum)
return p->objnum;
}
+@ @c
static void movelist(divert_list_entry * d, divert_list_entry * dto)
{
if (d != NULL && d->first != NULL && d->divnum != dto->divnum) { /* no undivert of empty list or into self */
@@ -168,13 +165,13 @@ static void movelist(divert_list_entry * d, divert_list_entry * dto)
else
dto->last->next = d->first;
dto->last = d->last;
- d->first = d->last = NULL; /* one could as well remove this divert_list_entry */
+ d->first = d->last = NULL; /* one could as well remove this |divert_list_entry| */
}
}
-/* undivert from diversion <divnum> into diversion <curdivnum> */
-
-void pdf_do_page_undivert(integer divnum, integer curdivnum)
+@ undivert from diversion |divnum| into diversion |curdivnum|
+@c
+void pdf_do_page_undivert(int divnum, int curdivnum)
{
divert_list_entry *d, *dto, tmp;
struct avl_traverser t;
@@ -182,11 +179,11 @@ void pdf_do_page_undivert(integer divnum, integer curdivnum)
pages_entry *p;
int i;
#endif
- // initialize the tree
+ /* initialize the tree */
ensure_list_tree();
- // find the diversion <curdivnum> list where diversion <divnum> should go
+ /* find the diversion |curdivnum| list where diversion |divnum| should go */
dto = get_divert_list(curdivnum);
- if (divnum == 0) { /* 0 = special case: undivert _all_ lists */
+ if (divnum == 0) { /* 0 = special case: undivert {\it all\/} lists */
avl_t_init(&t, divert_list_tree);
for (d = avl_t_first(&t, divert_list_tree); d != NULL;
d = avl_t_next(&t))
@@ -213,54 +210,60 @@ void pdf_do_page_undivert(integer divnum, integer curdivnum)
#endif
}
-/* write a /Pages object */
+@ write a /Pages object
+@c
+#define pdf_pages_attr equiv(pdf_pages_attr_loc)
-static void write_pages(pages_entry * p, int parent)
+static void write_pages(PDF pdf, pages_entry * p, int parent)
{
int i;
assert(p != NULL);
- pdf_begin_dict(p->objnum, 1);
- pdf_printf("/Type /Pages\n");
- if (parent == 0) /* it's root */
- print_pdf_pages_attr();
- else
- pdf_printf("/Parent %d 0 R\n", parent);
- pdf_printf("/Count %d\n/Kids [", (int) p->number_of_pages);
+ pdf_begin_dict(pdf, p->objnum, 1);
+ pdf_printf(pdf, "/Type /Pages\n");
+ if (parent == 0) { /* it's root */
+ if (pdf_pages_attr != null)
+ pdf_print_toks_ln(pdf, pdf_pages_attr);
+ if (pdf_pagesattributes_toks != null) /* from Lua */
+ pdf_print_toks_ln(pdf, pdf_pagesattributes_toks);
+ } else
+ pdf_printf(pdf, "/Parent %d 0 R\n", parent);
+ pdf_printf(pdf, "/Count %d\n/Kids [", (int) p->number_of_pages);
for (i = 0; i < p->number_of_kids; i++)
- pdf_printf("%d 0 R ", (int) p->kids[i]);
- remove_last_space();
- pdf_printf("]\n");
- pdf_end_dict();
+ pdf_printf(pdf, "%d 0 R ", (int) p->kids[i]);
+ pdf_remove_last_space(pdf);
+ pdf_printf(pdf, "]\n");
+ pdf_end_dict(pdf);
}
-/* loop over all /Pages objects, output them, create their parents,
- * recursing bottom up, return the /Pages root object number */
-
-static integer output_pages_list(pages_entry * pe)
+@ loop over all /Pages objects, output them, create their parents,
+recursing bottom up, return the /Pages root object number
+@c
+static int output_pages_list(PDF pdf, pages_entry * pe)
{
pages_entry *p, *q, *r;
assert(pe != NULL);
- if (pe->next == NULL) { /* everything fits into one pages_entry */
- write_pages(pe, 0); /* --> /Pages root found */
+ if (pe->next == NULL) { /* everything fits into one |pages_entry| */
+ write_pages(pdf, pe, 0); /* --> /Pages root found */
return pe->objnum;
}
- q = r = new_pages_entry(); /* one level higher needed */
+ q = r = new_pages_entry(pdf); /* one level higher needed */
for (p = pe; p != NULL; p = p->next) {
if (q->number_of_kids == PAGES_TREE_KIDSMAX) {
- q->next = new_pages_entry();
+ q->next = new_pages_entry(pdf);
q = q->next;
}
q->kids[q->number_of_kids++] = p->objnum;
q->number_of_pages += p->number_of_pages;
- write_pages(p, q->objnum);
+ write_pages(pdf, p, q->objnum);
}
- return output_pages_list(r); /* recurse through next higher level */
+ return output_pages_list(pdf, r); /* recurse through next higher level */
}
-integer output_pages_tree(void)
+@ @c
+int output_pages_tree(PDF pdf)
{
divert_list_entry *d;
pdf_do_page_undivert(0, 0); /* concatenate all diversions into diversion 0 */
d = get_divert_list(0); /* get diversion 0 */
- return output_pages_list(d->first);
+ return output_pages_list(pdf, d->first);
}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.h b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.h
new file mode 100644
index 00000000000..77944dd3f5b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.h
@@ -0,0 +1,78 @@
+/* pdfaction.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfaction.h 2801 2009-07-10 13:12:59Z taco $ */
+
+#ifndef PDFACTION_H
+# define PDFACTION_H
+
+/* pdf action spec */
+
+# define pdf_action_size 4
+
+typedef enum {
+ pdf_action_page = 0,
+ pdf_action_goto,
+ pdf_action_thread,
+ pdf_action_user
+} pdf_action_type;
+
+typedef enum {
+ pdf_window_notset,
+ pdf_window_new,
+ pdf_window_nonew,
+} pdf_window_type;
+
+
+# define pdf_action_type(a) type((a) + 1) /* enum pdf_action_type */
+# define pdf_action_named_id(a) subtype((a) + 1) /* boolean */
+# define pdf_action_id(a) vlink((a) + 1) /* number or toks */
+# define pdf_action_file(a) vinfo((a) + 2) /* toks */
+# define pdf_action_new_window(a) vlink((a) + 2) /* enum pdf_window_type */
+# define pdf_action_tokens(a) vinfo((a) + 3) /* toks */
+# define pdf_action_refcount(a) vlink((a) + 3) /* number */
+
+/* increase count of references to this action. this is used to speed up copy_node() */
+
+# define add_action_ref(a) pdf_action_refcount((a))++
+
+/* decrease count of references to this
+ action; free it if there is no reference to this action*/
+
+# define delete_action_ref(a) { \
+ if (pdf_action_refcount(a) == null) { \
+ delete_action_node(a); \
+ } else { \
+ decr(pdf_action_refcount(a)); \
+ } \
+ }
+
+
+# define set_pdf_action_type(A,B) pdf_action_type(A)=B
+# define set_pdf_action_tokens(A,B) pdf_action_tokens(A)=B
+# define set_pdf_action_file(A,B) pdf_action_file(A)=B
+# define set_pdf_action_id(A,B) pdf_action_id(A)=B
+# define set_pdf_action_named_id(A,B) pdf_action_named_id(A)=B
+# define set_pdf_action_new_window(A,B) pdf_action_new_window(A)=B
+
+extern halfword scan_action(PDF pdf);
+extern void write_action(PDF pdf, halfword p);
+extern void delete_action_node(halfword a);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w
new file mode 100644
index 00000000000..b6d06ebea9b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w
@@ -0,0 +1,207 @@
+% pdfaction.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: pdfaction.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfaction.w $";
+
+
+@ @c
+halfword new_action_node(void)
+{
+ return new_node(action_node, 0);
+}
+
+@ @c
+void delete_action_node(halfword a)
+{
+ if (pdf_action_type(a) == pdf_action_user) {
+ delete_token_ref(pdf_action_tokens(a));
+ } else {
+ if (pdf_action_file(a) != null)
+ delete_token_ref(pdf_action_file(a));
+ if (pdf_action_type(a) == pdf_action_page)
+ delete_token_ref(pdf_action_tokens(a));
+ else if (pdf_action_named_id(a) > 0)
+ delete_token_ref(pdf_action_id(a));
+ }
+ free_node(a, pdf_action_size);
+}
+
+@ read an action specification
+@c
+halfword scan_action(PDF pdf)
+{
+ int p;
+ (void) pdf;
+ p = new_action_node();
+ if (scan_keyword("user"))
+ set_pdf_action_type(p, pdf_action_user);
+ else if (scan_keyword("goto"))
+ set_pdf_action_type(p, pdf_action_goto);
+ else if (scan_keyword("thread"))
+ set_pdf_action_type(p, pdf_action_thread);
+ else
+ pdf_error("ext1", "action type missing");
+ if (pdf_action_type(p) == pdf_action_user) {
+ scan_pdf_ext_toks();
+ set_pdf_action_tokens(p, def_ref);
+ return p;
+ }
+ if (scan_keyword("file")) {
+ scan_pdf_ext_toks();
+ set_pdf_action_file(p, def_ref);
+ }
+ if (scan_keyword("page")) {
+ if (pdf_action_type(p) != pdf_action_goto)
+ pdf_error("ext1", "only GoTo action can be used with `page'");
+ set_pdf_action_type(p, pdf_action_page);
+ scan_int();
+ if (cur_val <= 0)
+ pdf_error("ext1", "page number must be positive");
+ set_pdf_action_id(p, cur_val);
+ set_pdf_action_named_id(p, 0);
+ scan_pdf_ext_toks();
+ set_pdf_action_tokens(p, def_ref);
+ } else if (scan_keyword("name")) {
+ scan_pdf_ext_toks();
+ set_pdf_action_named_id(p, 1);
+ set_pdf_action_id(p, def_ref);
+ } else if (scan_keyword("num")) {
+ if ((pdf_action_type(p) == pdf_action_goto) &&
+ (pdf_action_file(p) != null))
+ pdf_error("ext1",
+ "`goto' option cannot be used with both `file' and `num'");
+ scan_int();
+ if (cur_val <= 0)
+ pdf_error("ext1", "num identifier must be positive");
+ set_pdf_action_named_id(p, 0);
+ set_pdf_action_id(p, cur_val);
+ } else {
+ pdf_error("ext1", "identifier type missing");
+ }
+ if (scan_keyword("newwindow")) {
+ set_pdf_action_new_window(p, pdf_window_new);
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ } else if (scan_keyword("nonewwindow")) {
+ set_pdf_action_new_window(p, pdf_window_nonew);
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ } else {
+ set_pdf_action_new_window(p, pdf_window_notset);
+ }
+ if ((pdf_action_new_window(p) > pdf_window_notset) &&
+ (((pdf_action_type(p) != pdf_action_goto) &&
+ (pdf_action_type(p) != pdf_action_page)) ||
+ (pdf_action_file(p) == null)))
+ pdf_error("ext1",
+ "`newwindow'/`nonewwindow' must be used with `goto' and `file' option");
+ return p;
+}
+
+@ write an action specification
+@c
+void write_action(PDF pdf, halfword p)
+{
+ char *s;
+ int d = 0;
+ if (pdf_action_type(p) == pdf_action_user) {
+ pdf_print_toks_ln(pdf, pdf_action_tokens(p));
+ return;
+ }
+ pdf_printf(pdf, "<< ");
+ if (pdf_action_file(p) != null) {
+ pdf_printf(pdf, "/F ");
+ s = tokenlist_to_cstring(pdf_action_file(p), true, NULL);
+ pdf_print_str(pdf, s);
+ xfree(s);
+ pdf_printf(pdf, " ");
+ if (pdf_action_new_window(p) > pdf_window_notset) {
+ pdf_printf(pdf, "/NewWindow ");
+ if (pdf_action_new_window(p) == pdf_window_new)
+ pdf_printf(pdf, "true ");
+ else
+ pdf_printf(pdf, "false ");
+ }
+ }
+ switch (pdf_action_type(p)) {
+ case pdf_action_page:
+ if (pdf_action_file(p) == null) {
+ pdf_printf(pdf, "/S /GoTo /D [");
+ pdf_print_int(pdf,
+ get_obj(pdf, obj_type_page, pdf_action_id(p), false));
+ pdf_printf(pdf, " 0 R");
+ } else {
+ pdf_printf(pdf, "/S /GoToR /D [");
+ pdf_print_int(pdf, pdf_action_id(p) - 1);
+ }
+ {
+ char *tokstr =
+ tokenlist_to_cstring(pdf_action_tokens(p), true, NULL);
+ pdf_printf(pdf, " %s]", tokstr);
+ xfree(tokstr);
+ }
+ break;
+ case pdf_action_goto:
+ if (pdf_action_file(p) == null) {
+ pdf_printf(pdf, "/S /GoTo ");
+ d = get_obj(pdf, obj_type_dest, pdf_action_id(p),
+ pdf_action_named_id(p));
+ } else {
+ pdf_printf(pdf, "/S /GoToR ");
+ }
+ if (pdf_action_named_id(p) > 0) {
+ char *tokstr = tokenlist_to_cstring(pdf_action_id(p), true, NULL);
+ pdf_str_entry(pdf, "D", tokstr);
+ xfree(tokstr);
+ } else if (pdf_action_file(p) == null) {
+ pdf_indirect(pdf, "D", d);
+ } else {
+ pdf_error("ext4",
+ "`goto' option cannot be used with both `file' and `num'");
+ }
+ break;
+ case pdf_action_thread:
+ pdf_printf(pdf, "/S /Thread ");
+ if (pdf_action_file(p) == null) {
+ d = get_obj(pdf, obj_type_thread, pdf_action_id(p),
+ pdf_action_named_id(p));
+ if (pdf_action_named_id(p) > 0) {
+ char *tokstr =
+ tokenlist_to_cstring(pdf_action_id(p), true, NULL);
+ pdf_str_entry(pdf, "D", tokstr);
+ xfree(tokstr);
+ } else if (pdf_action_file(p) == null) {
+ pdf_indirect(pdf, "D", d);
+ } else {
+ pdf_int_entry(pdf, "D", pdf_action_id(p));
+ }
+ }
+ break;
+ }
+ pdf_printf(pdf, " >>\n");
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.h b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.h
new file mode 100644
index 00000000000..6372195d16b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.h
@@ -0,0 +1,37 @@
+/* pdfannot.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfannot.h 2772 2009-07-07 22:16:42Z hhenkel $ */
+
+#ifndef PDFANNOT_H
+# define PDFANNOT_H
+
+/* data structure of annotations; words 1..4 represent the coordinates of the annotation */
+
+# define obj_annot_ptr obj_aux /* pointer to corresponding whatsit node */
+
+# define set_pdf_annot_objnum(A,B) pdf_annot_objnum(A)=B
+# define set_pdf_annot_data(A,B) pdf_annot_data(A)=B
+
+extern void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur);
+extern void new_annot_whatsit(small_number w);
+
+extern void scan_annot(PDF pdf);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w
new file mode 100644
index 00000000000..25830556762
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w
@@ -0,0 +1,99 @@
+% pdfannot.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfannot.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfannot.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define tail cur_list.tail_field
+
+void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
+{
+ scaled_whd alt_rule;
+ if (!is_shipping_page)
+ pdf_error("ext4", "annotations cannot be inside an XForm");
+ if (doing_leaders)
+ return;
+ if (is_obj_scheduled(pdf, pdf_annot_objnum(p))) {
+ pdf_create_obj(pdf, obj_type_annot, pdf->sys_obj_ptr + 1);
+ obj_annot_ptr(pdf, pdf_annot_objnum(p)) = p;
+ pdf_annot_objnum(p) = pdf->sys_obj_ptr;
+ }
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, 0);
+ obj_annot_ptr(pdf, pdf_annot_objnum(p)) = p;
+ addto_page_resources(pdf, obj_type_annot, pdf_annot_objnum(p));
+}
+
+@ create a new whatsit node for annotation
+@c
+void new_annot_whatsit(small_number w)
+{
+ scaled_whd alt_rule;
+ new_whatsit(w);
+ alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
+ set_width(tail, alt_rule.wd);
+ set_height(tail, alt_rule.ht);
+ set_depth(tail, alt_rule.dp);
+ if ((w == pdf_thread_node) || (w == pdf_start_thread_node)) {
+ if (scan_keyword("attr")) {
+ scan_pdf_ext_toks();
+ set_pdf_thread_attr(tail, def_ref);
+ } else {
+ set_pdf_thread_attr(tail, null);
+ }
+ }
+}
+
+@ @c
+void scan_annot(PDF pdf)
+{
+ int k;
+ if (scan_keyword("reserveobjnum")) {
+ pdf_create_obj(pdf, obj_type_annot, pdf->sys_obj_ptr + 1);
+ k = pdf->sys_obj_ptr;
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ } else {
+ if (scan_keyword("useobjnum")) {
+ scan_int();
+ k = cur_val;
+ check_obj_exists(pdf, obj_type_annot, k);
+ if (obj_annot_ptr(pdf, k) != 0)
+ pdf_error("ext1", "annot object in use");
+ } else {
+ pdf_create_obj(pdf, obj_type_annot, pdf->sys_obj_ptr + 1);
+ k = pdf->sys_obj_ptr;
+ }
+ new_annot_whatsit(pdf_annot_node);
+ obj_annot_ptr(pdf, k) = tail;
+ set_pdf_annot_objnum(tail, k);
+ scan_pdf_ext_toks();
+ set_pdf_annot_data(tail, def_ref);
+ }
+ pdf_last_annot = k;
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h
new file mode 100644
index 00000000000..20d8e436146
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.h
@@ -0,0 +1,44 @@
+/* pdfcolorstack.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfcolorstack.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFCOLORSTACK_H
+# define PDFCOLORSTACK_H
+
+# define set_pdf_colorstack_stack(A,B) pdf_colorstack_stack(A)=B
+# define set_pdf_colorstack_cmd(A,B) pdf_colorstack_cmd(A)=B
+# define set_pdf_colorstack_data(A,B) pdf_colorstack_data(A)=B
+
+/* remember shipout mode: page/form */
+extern boolean page_mode;
+
+# define STACK_INCREMENT 8
+
+int newcolorstack(int s, int literal_mode, boolean pagestart);
+int colorstackused(void);
+int colorstackpop(int colstack_no);
+int colorstackcurrent(int colstack_no);
+int colorstackskippagestart(int colstack_no);
+void colorstackpagestart(void);
+
+extern void pdf_out_colorstack(PDF pdf, halfword p);
+extern void pdf_out_colorstack_startpage(PDF pdf);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w
new file mode 100644
index 00000000000..1e472c7f713
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w
@@ -0,0 +1,386 @@
+% pdfcolorstack.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: pdfcolorstack.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w $";
+
+
+@* Color Stack and Matrix Transformation Support.
+
+
+@ In the following array and especially stack data structures are used.
+
+They have the following properties:
+
+ \item{-} They automatically grow dynamically.
+ \item{-} The size never decreases.
+ \item{-} The variable with name ending in "size" contains the number how many
+ entries the data structure can hold.
+ \item{-} The variable with name ending in "used" contains the number of
+ actually used entries.
+ \item{-} Memory of strings in stack entries must be allocated and
+ freed if the stack is cleared.
+
+
+@ Color Stack
+@c
+#define MAX_COLORSTACKS 32768
+/* The colorstack number is stored in two bytes (info field of the node) */
+/* Condition (newcolorstack): |MAX_COLORSTACKS mod STACK_INCREMENT = 0| */
+
+#define COLOR_DEFAULT "0 g 0 G"
+/* |literal_mode|s, see pdftex.web */
+#define SET_ORIGIN 0
+#define DIRECT_PAGE 1
+#define DIRECT_ALWAYS 2
+
+/* remember shipout mode: page/form */
+boolean page_mode;
+
+typedef struct {
+ char **page_stack;
+ char **form_stack;
+ char *page_current;
+ char *form_current;
+ char *form_init;
+ int page_size;
+ int form_size;
+ int page_used;
+ int form_used;
+ int literal_mode;
+ boolean page_start;
+} colstack_type;
+
+static colstack_type *colstacks = NULL;
+static int colstacks_size = 0;
+static int colstacks_used = 0;
+
+@ Initialization is done, if the color stacks are used,
+ |init_colorstacks()| is defined as macro to avoid unnecessary
+ procedure calls.
+@c
+#define init_colorstacks() if (colstacks_size == 0) colstacks_first_init();
+
+void colstacks_first_init(void)
+{
+ colstacks_size = STACK_INCREMENT;
+ colstacks = xtalloc((unsigned) colstacks_size, colstack_type);
+ colstacks_used = 1;
+ colstacks[0].page_stack = NULL;
+ colstacks[0].form_stack = NULL;
+ colstacks[0].page_size = 0;
+ colstacks[0].form_size = 0;
+ colstacks[0].page_used = 0;
+ colstacks[0].form_used = 0;
+ colstacks[0].page_current = xstrdup(COLOR_DEFAULT);
+ colstacks[0].form_current = xstrdup(COLOR_DEFAULT);
+ colstacks[0].form_init = xstrdup(COLOR_DEFAULT);
+ colstacks[0].literal_mode = DIRECT_ALWAYS;
+ colstacks[0].page_start = true;
+}
+
+@ @c
+int colorstackused(void)
+{
+ init_colorstacks();
+ return colstacks_used;
+}
+
+@ |newcolorstack()|
+ A new color stack is setup with the given parameters.
+ The stack number is returned or -1 in case of error (no room).
+@c
+int newcolorstack(int s, int literal_mode, boolean page_start)
+{
+ colstack_type *colstack;
+ int colstack_num;
+ char *str;
+
+ init_colorstacks();
+
+ /* make room */
+ if (colstacks_used == MAX_COLORSTACKS) {
+ return -1;
+ }
+ if (colstacks_used == colstacks_size) {
+ colstacks_size += STACK_INCREMENT;
+ /* If |(MAX_COLORSTACKS mod STACK_INCREMENT = 0)| then we don't
+ need to check the case that size overruns |MAX_COLORSTACKS|. */
+ colstacks =
+ xreallocarray(colstacks, colstack_type, (unsigned) colstacks_size);
+ }
+ /* claim new color stack */
+ colstack_num = colstacks_used++;
+ colstack = &colstacks[colstack_num];
+ /* configure the new color stack */
+ colstack->page_stack = NULL;
+ colstack->form_stack = NULL;
+ colstack->page_size = 0;
+ colstack->page_used = 0;
+ colstack->form_size = 0;
+ colstack->form_used = 0;
+ colstack->literal_mode = literal_mode;
+ colstack->page_start = page_start;
+ str = makecstring(s);
+ if (*str == 0) {
+ colstack->page_current = NULL;
+ colstack->form_current = NULL;
+ colstack->form_init = NULL;
+ } else {
+ colstack->page_current = xstrdup(str);
+ colstack->form_current = xstrdup(str);
+ colstack->form_init = xstrdup(str);
+ }
+ free(str);
+ return colstack_num;
+}
+
+@ @c
+#define get_colstack(n) (&colstacks[n])
+
+@ Puts a string on top of the string pool and updates |pool_ptr|.
+@c
+static void put_cstring_on_str_pool(char *str)
+{
+ int save_selector = selector;
+ selector = new_string;
+ if (str == NULL || *str == 0) {
+ return;
+ }
+ tprint(str);
+ selector = save_selector;
+}
+
+@ @c
+int colorstackset(int colstack_no, str_number s)
+{
+ colstack_type *colstack = get_colstack(colstack_no);
+
+ if (page_mode) {
+ xfree(colstack->page_current);
+ colstack->page_current = makecstring(s);
+ } else {
+ xfree(colstack->form_current);
+ colstack->form_current = makecstring(s);
+ }
+ return colstack->literal_mode;
+}
+
+@ @c
+int colorstackcurrent(int colstack_no)
+{
+ colstack_type *colstack = get_colstack(colstack_no);
+
+ if (page_mode) {
+ put_cstring_on_str_pool(colstack->page_current);
+ } else {
+ put_cstring_on_str_pool(colstack->form_current);
+ }
+ return colstack->literal_mode;
+}
+
+@ @c
+static int colorstackpush(int colstack_no, str_number s)
+{
+ colstack_type *colstack = get_colstack(colstack_no);
+ char *str;
+ if (page_mode) {
+ if (colstack->page_used == colstack->page_size) {
+ colstack->page_size += STACK_INCREMENT;
+ colstack->page_stack = xretalloc(colstack->page_stack,
+ (unsigned) colstack->page_size,
+ char *);
+ }
+ colstack->page_stack[colstack->page_used++] = colstack->page_current;
+ str = makecstring(s);
+ if (*str == 0) {
+ colstack->page_current = NULL;
+ } else {
+ colstack->page_current = xstrdup(str);
+ }
+ free(str);
+ } else {
+ if (colstack->form_used == colstack->form_size) {
+ colstack->form_size += STACK_INCREMENT;
+ colstack->form_stack = xretalloc(colstack->form_stack,
+ (unsigned) colstack->form_size,
+ char *);
+ }
+ colstack->form_stack[colstack->form_used++] = colstack->form_current;
+ str = makecstring(s);
+ if (*str == 0) {
+ colstack->form_current = NULL;
+ } else {
+ colstack->form_current = xstrdup(str);
+ }
+ free(str);
+ }
+ return colstack->literal_mode;
+}
+
+@ @c
+int colorstackpop(int colstack_no)
+{
+ colstack_type *colstack = get_colstack(colstack_no);
+
+ if (page_mode) {
+ if (colstack->page_used == 0) {
+ pdftex_warn("pop empty color page stack %u",
+ (unsigned int) colstack_no);
+ return colstack->literal_mode;
+ }
+ xfree(colstack->page_current);
+ colstack->page_current = colstack->page_stack[--colstack->page_used];
+ put_cstring_on_str_pool(colstack->page_current);
+ } else {
+ if (colstack->form_used == 0) {
+ pdftex_warn("pop empty color form stack %u",
+ (unsigned int) colstack_no);
+ return colstack->literal_mode;
+ }
+ xfree(colstack->form_current);
+ colstack->form_current = colstack->form_stack[--colstack->form_used];
+ put_cstring_on_str_pool(colstack->form_current);
+ }
+ return colstack->literal_mode;
+}
+
+@ @c
+void colorstackpagestart(void)
+{
+ int i, j;
+ colstack_type *colstack;
+
+ if (page_mode) {
+ /* see procedure |pdf_out_colorstack_startpage| */
+ return;
+ }
+
+ for (i = 0; i < colstacks_used; i++) {
+ colstack = &colstacks[i];
+ for (j = 0; j < colstack->form_used; j++) {
+ xfree(colstack->form_stack[j]);
+ }
+ colstack->form_used = 0;
+ xfree(colstack->form_current);
+ if (colstack->form_init == NULL) {
+ colstack->form_current = NULL;
+ } else {
+ colstack->form_current = xstrdup(colstack->form_init);
+ }
+ }
+}
+
+@ @c
+int colorstackskippagestart(int colstack_no)
+{
+ colstack_type *colstack = get_colstack(colstack_no);
+
+ if (!colstack->page_start) {
+ return 1;
+ }
+ if (colstack->page_current == NULL) {
+ return 0;
+ }
+ if (strcmp(COLOR_DEFAULT, colstack->page_current) == 0) {
+ return 2;
+ }
+ return 0;
+}
+
+
+@ @c
+void pdf_out_colorstack(PDF pdf, halfword p)
+{
+ int old_setting;
+ str_number s;
+ int cmd;
+ int stack_no;
+ int literal_mode;
+ cmd = pdf_colorstack_cmd(p);
+ stack_no = pdf_colorstack_stack(p);
+ literal_mode = 0;
+ if (stack_no >= colorstackused()) {
+ tprint_nl("");
+ tprint("Color stack ");
+ print_int(stack_no);
+ tprint(" is not initialized for use!");
+ tprint_nl("");
+ return;
+ }
+ switch (cmd) {
+ case colorstack_set:
+ case colorstack_push:
+ old_setting = selector;
+ selector = new_string;
+ show_token_list(token_link(pdf_colorstack_data(p)), null, -1);
+ selector = old_setting;
+ s = make_string();
+ if (cmd == colorstack_set)
+ literal_mode = colorstackset(stack_no, s);
+ else
+ literal_mode = colorstackpush(stack_no, s);
+ if (str_length(s) > 0)
+ pdf_literal(pdf, s, literal_mode, false);
+ flush_str(s);
+ return;
+ break;
+ case colorstack_pop:
+ literal_mode = colorstackpop(stack_no);
+ break;
+ case colorstack_current:
+ literal_mode = colorstackcurrent(stack_no);
+ break;
+ default:
+ break;
+ }
+ if (cur_length > 0) {
+ s = make_string();
+ pdf_literal(pdf, s, literal_mode, false);
+ flush_str(s);
+ }
+}
+
+@ @c
+void pdf_out_colorstack_startpage(PDF pdf)
+{
+ int i;
+ int max;
+ int start_status;
+ int literal_mode;
+ str_number s;
+ i = 0;
+ max = colorstackused();
+ while (i < max) {
+ start_status = colorstackskippagestart(i);
+ if (start_status == 0) {
+ literal_mode = colorstackcurrent(i);
+ if (cur_length > 0) {
+ s = make_string();
+ pdf_literal(pdf, s, literal_mode, false);
+ flush_str(s);
+ }
+ }
+ incr(i);
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h
new file mode 100644
index 00000000000..0e5d9dca457
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.h
@@ -0,0 +1,66 @@
+/* pdfdest.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfdest.h 3386 2010-01-26 06:41:37Z taco $ */
+
+#ifndef PDFDEST_H
+# define PDFDEST_H
+
+/* types of destinations */
+
+typedef enum {
+ pdf_dest_xyz = 0,
+ pdf_dest_fit = 1,
+ pdf_dest_fith = 2,
+ pdf_dest_fitv = 3,
+ pdf_dest_fitb = 4,
+ pdf_dest_fitbh = 5,
+ pdf_dest_fitbv = 6,
+ pdf_dest_fitr = 7
+} pdf_destination_types;
+
+/* max number of kids for balanced trees */
+# define name_tree_kids_max 32 /* max number of kids of node of name tree for name destinations */
+
+/* data structure of destinations */
+
+# define obj_dest_ptr obj_aux /* pointer to |pdf_dest_node| */
+# define set_obj_dest_ptr(pdf,A,B) obj_dest_ptr(pdf,A)=B
+
+# define set_pdf_dest_id(A,B) pdf_dest_id(A)=B
+# define set_pdf_dest_named_id(A,B) pdf_dest_named_id(A)=B
+# define set_pdf_dest_type(A,B) pdf_dest_type(A)=B
+# define set_pdf_dest_xyz_zoom(A,B) pdf_dest_xyz_zoom(A)=B
+
+# define inf_dest_names_size 1000 /* min size of the destination names table for PDF output */
+# define sup_dest_names_size 131072 /* max size of the destination names table for PDF output */
+
+extern void append_dest_name(PDF, char *, int);
+extern void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur);
+extern void warn_dest_dup(int id, small_number byname, const char *s1,
+ const char *s2);
+
+extern void write_out_pdf_mark_destinations(PDF);
+extern void scan_pdfdest(PDF);
+extern void init_dest_names(PDF);
+extern void sort_dest_names(PDF);
+extern int output_name_tree(PDF);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w
new file mode 100644
index 00000000000..2f53f77dca5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w
@@ -0,0 +1,417 @@
+% pdfdest.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfdest.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfdest.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define pdf_dest_margin dimen_par(pdf_dest_margin_code)
+
+@ Here we implement subroutines for work with objects and related things.
+Some of them are used in former parts too, so we need to declare them
+forward.
+
+@c
+void init_dest_names(PDF pdf)
+{
+ pdf->dest_names_size = inf_dest_names_size;
+ pdf->dest_names = xmallocarray(dest_name_entry, inf_dest_names_size); /* will grow dynamically */
+}
+
+@ @c
+void append_dest_name(PDF pdf, char *s, int n)
+{
+ int a;
+ if (pdf->dest_names_ptr == sup_dest_names_size)
+ overflow("number of destination names (dest_names_size)",
+ (unsigned) pdf->dest_names_size);
+ if (pdf->dest_names_ptr == pdf->dest_names_size) {
+ a = pdf->dest_names_size / 5;
+ if (pdf->dest_names_size < sup_dest_names_size - a)
+ pdf->dest_names_size = pdf->dest_names_size + a;
+ else
+ pdf->dest_names_size = sup_dest_names_size;
+ pdf->dest_names =
+ xreallocarray(pdf->dest_names, dest_name_entry,
+ (unsigned) pdf->dest_names_size);
+ }
+ pdf->dest_names[pdf->dest_names_ptr].objname = xstrdup(s);
+ pdf->dest_names[pdf->dest_names_ptr].objnum = n;
+ pdf->dest_names_ptr++;
+}
+
+
+@ When a destination is created we need to check whether another destination
+with the same identifier already exists and give a warning if needed.
+
+@c
+void warn_dest_dup(int id, small_number byname, const char *s1, const char *s2)
+{
+ pdf_warning(s1, "destination with the same identifier (", false, false);
+ if (byname > 0) {
+ tprint("name");
+ print_mark(id);
+ } else {
+ tprint("num");
+ print_int(id);
+ }
+ tprint(") ");
+ tprint(s2);
+ print_ln();
+ show_context();
+}
+
+
+@ @c
+void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
+{
+ scaledpos pos = pdf->posstruct->pos;
+ scaled_whd alt_rule;
+ int k;
+ if (!is_shipping_page)
+ pdf_error("ext4", "destinations cannot be inside an XForm");
+ if (doing_leaders)
+ return;
+ k = get_obj(pdf, obj_type_dest, pdf_dest_id(p), pdf_dest_named_id(p));
+ if (obj_dest_ptr(pdf, k) != null) {
+ warn_dest_dup(pdf_dest_id(p), (small_number) pdf_dest_named_id(p),
+ "ext4", "has been already used, duplicate ignored");
+ return;
+ }
+ obj_dest_ptr(pdf, k) = p;
+ addto_page_resources(pdf, obj_type_dest, k);
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ switch (pdf_dest_type(p)) {
+ case pdf_dest_xyz:
+ if (matrixused())
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ else {
+ pdf_ann_left(p) = pos.h;
+ pdf_ann_top(p) = pos.v;
+ }
+ break;
+ case pdf_dest_fith:
+ case pdf_dest_fitbh:
+ if (matrixused())
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ else
+ pdf_ann_top(p) = pos.v;
+ break;
+ case pdf_dest_fitv:
+ case pdf_dest_fitbv:
+ if (matrixused())
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ else
+ pdf_ann_left(p) = pos.h;
+ break;
+ case pdf_dest_fit:
+ case pdf_dest_fitb:
+ break;
+ case pdf_dest_fitr:
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ }
+}
+
+@ @c
+void write_out_pdf_mark_destinations(PDF pdf)
+{
+ pdf_object_list *k;
+ if ((k = get_page_resources_list(pdf, obj_type_dest)) != NULL) {
+ while (k != NULL) {
+ if (is_obj_written(pdf, k->info)) {
+ pdf_error("ext5",
+ "destination has been already written (this shouldn't happen)");
+ } else {
+ int i;
+ i = obj_dest_ptr(pdf, k->info);
+ if (pdf_dest_named_id(i) > 0) {
+ pdf_begin_dict(pdf, k->info, 1);
+ pdf_printf(pdf, "/D ");
+ } else {
+ pdf_begin_obj(pdf, k->info, 1);
+ }
+ pdf_out(pdf, '[');
+ pdf_print_int(pdf, pdf->last_page);
+ pdf_printf(pdf, " 0 R ");
+ switch (pdf_dest_type(i)) {
+ case pdf_dest_xyz:
+ pdf_printf(pdf, "/XYZ ");
+ pdf_print_mag_bp(pdf, pdf_ann_left(i));
+ pdf_out(pdf, ' ');
+ pdf_print_mag_bp(pdf, pdf_ann_top(i));
+ pdf_out(pdf, ' ');
+ if (pdf_dest_xyz_zoom(i) == null) {
+ pdf_printf(pdf, "null");
+ } else {
+ pdf_print_int(pdf, pdf_dest_xyz_zoom(i) / 1000);
+ pdf_out(pdf, '.');
+ pdf_print_int(pdf, (pdf_dest_xyz_zoom(i) % 1000));
+ }
+ break;
+ case pdf_dest_fit:
+ pdf_printf(pdf, "/Fit");
+ break;
+ case pdf_dest_fith:
+ pdf_printf(pdf, "/FitH ");
+ pdf_print_mag_bp(pdf, pdf_ann_top(i));
+ break;
+ case pdf_dest_fitv:
+ pdf_printf(pdf, "/FitV ");
+ pdf_print_mag_bp(pdf, pdf_ann_left(i));
+ break;
+ case pdf_dest_fitb:
+ pdf_printf(pdf, "/FitB");
+ break;
+ case pdf_dest_fitbh:
+ pdf_printf(pdf, "/FitBH ");
+ pdf_print_mag_bp(pdf, pdf_ann_top(i));
+ break;
+ case pdf_dest_fitbv:
+ pdf_printf(pdf, "/FitBV ");
+ pdf_print_mag_bp(pdf, pdf_ann_left(i));
+ break;
+ case pdf_dest_fitr:
+ pdf_printf(pdf, "/FitR ");
+ pdf_print_rect_spec(pdf, i);
+ break;
+ default:
+ pdf_error("ext5", "unknown dest type");
+ break;
+ }
+ pdf_printf(pdf, "]\n");
+ if (pdf_dest_named_id(i) > 0)
+ pdf_end_dict(pdf);
+ else
+ pdf_end_obj(pdf);
+ }
+ k = k->link;
+ }
+ }
+}
+
+@ @c
+void scan_pdfdest(PDF pdf)
+{
+ halfword q;
+ int k;
+ str_number i;
+ scaled_whd alt_rule;
+ q = cur_list.tail_field;
+ new_whatsit(pdf_dest_node);
+ if (scan_keyword("num")) {
+ scan_int();
+ if (cur_val <= 0)
+ pdf_error("ext1", "num identifier must be positive");
+ if (cur_val > max_halfword)
+ pdf_error("ext1", "number too big");
+ set_pdf_dest_id(cur_list.tail_field, cur_val);
+ set_pdf_dest_named_id(cur_list.tail_field, 0);
+ } else if (scan_keyword("name")) {
+ scan_pdf_ext_toks();
+ set_pdf_dest_id(cur_list.tail_field, def_ref);
+ set_pdf_dest_named_id(cur_list.tail_field, 1);
+ } else {
+ pdf_error("ext1", "identifier type missing");
+ }
+ if (scan_keyword("xyz")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_xyz);
+ if (scan_keyword("zoom")) {
+ scan_int();
+ if (cur_val > max_halfword)
+ pdf_error("ext1", "number too big");
+ set_pdf_dest_xyz_zoom(cur_list.tail_field, cur_val);
+ } else {
+ set_pdf_dest_xyz_zoom(cur_list.tail_field, null);
+ }
+ } else if (scan_keyword("fitbh")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_fitbh);
+ } else if (scan_keyword("fitbv")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_fitbv);
+ } else if (scan_keyword("fitb")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_fitb);
+ } else if (scan_keyword("fith")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_fith);
+ } else if (scan_keyword("fitv")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_fitv);
+ } else if (scan_keyword("fitr")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_fitr);
+ } else if (scan_keyword("fit")) {
+ set_pdf_dest_type(cur_list.tail_field, pdf_dest_fit);
+ } else {
+ pdf_error("ext1", "destination type missing");
+ }
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+
+ if (pdf_dest_type(cur_list.tail_field) == pdf_dest_fitr) {
+ alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
+ set_width(cur_list.tail_field, alt_rule.wd);
+ set_height(cur_list.tail_field, alt_rule.ht);
+ set_depth(cur_list.tail_field, alt_rule.dp);
+ }
+ if (pdf_dest_named_id(cur_list.tail_field) != 0) {
+ i = tokens_to_string(pdf_dest_id(cur_list.tail_field));
+ k = find_obj(pdf, obj_type_dest, i, true);
+ flush_str(i);
+ } else {
+ k = find_obj(pdf, obj_type_dest, pdf_dest_id(cur_list.tail_field),
+ false);
+ }
+ if ((k != 0) && (obj_dest_ptr(pdf, k) != null)) {
+ warn_dest_dup(pdf_dest_id(cur_list.tail_field),
+ (small_number) pdf_dest_named_id(cur_list.tail_field),
+ "ext4", "has been already used, duplicate ignored");
+ flush_node_list(cur_list.tail_field);
+ cur_list.tail_field = q;
+ vlink(q) = null;
+ }
+}
+
+@ sorts |dest_names| by names
+@c
+static int dest_cmp(const void *a, const void *b)
+{
+ dest_name_entry aa = *(const dest_name_entry *) a;
+ dest_name_entry bb = *(const dest_name_entry *) b;
+ return strcmp(aa.objname, bb.objname);
+}
+
+@ @c
+void sort_dest_names(PDF pdf)
+{
+ qsort(pdf->dest_names, (size_t) pdf->dest_names_ptr,
+ sizeof(dest_name_entry), dest_cmp);
+}
+
+
+@ Output the name tree. The tree nature of the destination list forces the
+storing of intermediate data in |obj_info| and |obj_aux| fields, which
+is further uglified by the fact that |obj_tab| entries do not accept char
+pointers.
+
+@c
+int output_name_tree(PDF pdf)
+{
+ boolean is_names = true; /* flag for name tree output: is it Names or Kids? */
+ int b = 0, j, l;
+ int k = 0; /* index of current child of |l|; if |k < pdf_dest_names_ptr|
+ then this is pointer to |dest_names| array;
+ otherwise it is the pointer to |obj_tab| (object number) */
+ int dests = 0;
+ int names_head = 0, names_tail = 0;
+ if (pdf->dest_names_ptr == 0) {
+ goto DONE;
+ }
+ sort_dest_names(pdf);
+
+ while (true) {
+
+ do {
+ pdf_create_obj(pdf, obj_type_others, 0); /* create a new node */
+ l = pdf->obj_ptr;
+ if (b == 0)
+ b = l; /* first in this level */
+ if (names_head == 0) {
+ names_head = l;
+ names_tail = l;
+ } else {
+ set_obj_link(pdf, names_tail, l);
+ names_tail = l;
+ }
+ set_obj_link(pdf, names_tail, 0);
+ /* Output the current node in this level */
+ pdf_begin_dict(pdf, l, 1);
+ j = 0;
+ if (is_names) {
+ set_obj_start(pdf, l, pdf->dest_names[k].objname);
+ pdf_printf(pdf, "/Names [");
+ do {
+ pdf_print_str(pdf, pdf->dest_names[k].objname);
+ pdf_out(pdf, ' ');
+ pdf_print_int(pdf, pdf->dest_names[k].objnum);
+ pdf_printf(pdf, " 0 R ");
+ j++;
+ k++;
+ } while (j != name_tree_kids_max && k != pdf->dest_names_ptr);
+ pdf_remove_last_space(pdf);
+ pdf_printf(pdf, "]\n");
+ set_obj_stop(pdf, l, pdf->dest_names[k - 1].objname); /* for later */
+ if (k == pdf->dest_names_ptr) {
+ is_names = false;
+ k = names_head;
+ b = 0;
+ }
+
+ } else {
+ set_obj_start(pdf, l, obj_start(pdf, k));
+ pdf_printf(pdf, "/Kids [");
+ do {
+ pdf_print_int(pdf, k);
+ pdf_printf(pdf, " 0 R ");
+ set_obj_stop(pdf, l, obj_stop(pdf, k));
+ k = obj_link(pdf, k);
+ j++;
+ } while (j != name_tree_kids_max && k != b
+ && obj_link(pdf, k) != 0);
+ pdf_remove_last_space(pdf);
+ pdf_printf(pdf, "]\n");
+ if (k == b)
+ b = 0;
+ }
+ pdf_printf(pdf, "/Limits [");
+ pdf_print_str(pdf, obj_start(pdf, l));
+ pdf_out(pdf, ' ');
+ pdf_print_str(pdf, obj_stop(pdf, l));
+ pdf_printf(pdf, "]\n");
+ pdf_end_dict(pdf);
+
+
+ } while (b != 0);
+
+ if (k == l) {
+ dests = l;
+ goto DONE;
+ }
+
+ }
+
+ DONE:
+ if ((dests != 0) || (pdf_names_toks != null)) {
+ pdf_new_dict(pdf, obj_type_others, 0, 1);
+ if (dests != 0)
+ pdf_indirect_ln(pdf, "Dests", dests);
+ if (pdf_names_toks != null) {
+ pdf_print_toks_ln(pdf, pdf_names_toks);
+ delete_token_ref(pdf_names_toks);
+ pdf_names_toks = null;
+ }
+ pdf_end_dict(pdf);
+ return pdf->obj_ptr;
+ } else {
+ return 0;
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdffont.h b/Build/source/texk/web2c/luatexdir/pdf/pdffont.h
new file mode 100644
index 00000000000..aabe66a4792
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdffont.h
@@ -0,0 +1,48 @@
+/* pdffont.h
+
+ Copyright 2010 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdffont.h 3430 2010-02-11 21:42:02Z hhenkel $ */
+
+#ifndef PDFFONT_H
+# define PDFFONT_H
+
+extern void output_one_char(PDF pdf, internal_font_number ffi, int c);
+
+extern void pdf_init_font(PDF pdf, internal_font_number f);
+extern internal_font_number pdf_set_font(PDF pdf, internal_font_number f);
+
+extern int pk_dpi; /* PK pixel density value from \.{texmf.cnf} */
+
+extern void copy_expand_params(internal_font_number k, internal_font_number f,
+ int e);
+extern internal_font_number tfm_lookup(char *s, scaled fs, int e);
+extern internal_font_number expand_font(internal_font_number f, int e);
+
+extern void set_expand_params(internal_font_number f, boolean auto_expand,
+ int stretch_limit, int shrink_limit,
+ int font_step, int expand_ratio);
+
+extern void read_expand_font(void);
+extern void new_letterspaced_font(small_number a);
+extern void make_font_copy(small_number a);
+
+extern void pdf_include_chars(PDF);
+extern void glyph_to_unicode(void);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdffont.w b/Build/source/texk/web2c/luatexdir/pdf/pdffont.w
new file mode 100644
index 00000000000..77b817bb61a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdffont.w
@@ -0,0 +1,495 @@
+% pdffont.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+\def\pdfTeX{pdf\TeX}
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdffont.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdffont.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define font_id_text(A) cs_text(font_id_base+(A)) /* a frozen font identifier's name */
+
+int pk_dpi; /* PK pixel density value from \.{texmf.cnf} */
+
+
+@ As \pdfTeX{} should also act as a back-end driver, it needs to support virtual
+fonts too. Information about virtual fonts can be found in the source of some
+\.{DVI}-related programs.
+
+Whenever we want to write out a character in a font to PDF output, we
+should check whether the used character is a virtual or read character.
+The |has_packet()| C macro checks for this condition.
+
+
+@ The following code typesets a character to PDF output
+
+@c
+void output_one_char(PDF pdf, internal_font_number ffi, int c)
+{
+ scaled_whd ci; /* the real width, height and depth of the character */
+ ci = get_charinfo_whd(ffi, c);
+ switch (pdf->posstruct->dir) {
+ case dir_TLT:
+ break;
+ case dir_TRT:
+ pos_left(ci.wd);
+ break;
+ case dir_LTL:
+ pos_down(ci.ht);
+ pos_left(ci.wd);
+ break;
+ case dir_RTT:
+ pos_down(ci.ht);
+ pos_left(ci.wd / 2);
+ break;
+ }
+ if (has_packet(ffi, c)) {
+ assert(pdf->o_mode == OMODE_PDF);
+ do_vf_packet(pdf, ffi, c);
+ } else
+ backend_out[glyph_node] (pdf, ffi, c); /* |pdf_place_glyph(pdf, ffi, c);| */
+}
+
+@ Mark |f| as a used font; set |font_used(f)|, |font_size(f)| and |pdf_font_num(f)|
+@c
+static void pdf_use_font(internal_font_number f, int fontnum)
+{
+ set_font_used(f, true);
+ assert((fontnum > 0) || ((fontnum < 0) && (pdf_font_num(-fontnum) > 0)));
+ set_pdf_font_num(f, fontnum);
+}
+
+@ To set PDF font we need to find out fonts with the same name, because \TeX\
+can load the same font several times for various sizes. For such fonts we
+define only one font resource. The array |pdf_font_num| holds the object
+number of font resource. A negative value of an entry of |pdf_font_num|
+indicates that the corresponding font shares the font resource with the font
+
+@c
+#define same(n,f,k) (n(f) != NULL && n(k) != NULL && strcmp(n(f), n(k)) == 0)
+
+static boolean font_shareable(internal_font_number f, internal_font_number k)
+{
+ int ret = 0;
+ internal_font_number b;
+ /* 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 should use the other branch */
+ if (font_cidregistry(f) == NULL && font_cidregistry(k) == NULL &&
+ font_encodingbytes(f) != 2 && font_encodingbytes(k) != 2) {
+ if (font_map(k) != NULL &&
+ font_map(f) != NULL &&
+ (same(font_name, k, f) ||
+ (font_auto_expand(f) &&
+ (b = pdf_font_blink(f)) != 0 && same(font_name, k, b)))) {
+ ret = 1;
+ }
+#ifdef DEBUG
+ printf("\nfont_shareable(%d:%d, %d:%d): => %d\n", f, pdf_font_blink(f),
+ k, pdf_font_blink(k), ret);
+#endif
+ } else {
+ if ((same(font_filename, k, f) && same(font_fullname, k, f))
+ || (font_auto_expand(f)
+ && (b = pdf_font_blink(f)) != 0 && same(font_name, k, b))) {
+ ret = 1;
+ }
+#ifdef DEBUG
+ printf("\nfont_shareable(%d:%s:%s,%d:%s:%s): => %d\n",
+ f, font_filename(f), font_fullname(f),
+ k, font_filename(k), font_fullname(k), ret);
+#endif
+ }
+ return ret;
+}
+
+@ create a font object
+@c
+void pdf_init_font(PDF pdf, internal_font_number f)
+{
+ internal_font_number k, b;
+ fm_entry *fm;
+ int i;
+ assert(!font_used(f));
+
+ /* if |f| is auto expanded then ensure the base font is initialized */
+
+ if (font_auto_expand(f) && ((b = pdf_font_blink(f)) != 0)) {
+ if (!font_used(b))
+ pdf_init_font(pdf, b);
+ set_font_map(f, font_map(b));
+ /* propagate slant and extend from unexpanded base font */
+ set_font_slant(f, font_slant(b));
+ set_font_extend(f, font_extend(b));
+ }
+ /* check whether |f| can share the font object with some |k|: we have 2 cases
+ here: 1) |f| and |k| have the same tfm name (so they have been loaded at
+ different sizes, eg 'cmr10' and 'cmr10 at 11pt'); 2) |f| has been auto
+ expanded from |k|
+ */
+
+ /* take over slant and extend from map entry, if not already set;
+ this should also be the only place where getfontmap() may be called. */
+
+ fm = getfontmap(font_name(f));
+ if (font_map(f) == NULL && fm != NULL) {
+ font_map(f) = fm;
+ if (is_slantset(fm))
+ font_slant(f) = fm->slant;
+ if (is_extendset(fm))
+ font_extend(f) = fm->extend;
+ }
+ i = pdf->head_tab[obj_type_font];
+ while (i != 0) {
+ k = obj_info(pdf, i);
+ if (font_shareable(f, k)) {
+ assert(pdf_font_num(k) != 0);
+ if (pdf_font_num(k) < 0)
+ pdf_use_font(f, pdf_font_num(k));
+ else
+ pdf_use_font(f, -k);
+ return;
+ }
+ i = obj_link(pdf, i);
+ }
+ /* create a new font object for |f| */
+ pdf_create_obj(pdf, obj_type_font, f);
+ pdf_use_font(f, pdf->obj_ptr);
+}
+
+@ set the actual font on PDF page
+@c
+internal_font_number pdf_set_font(PDF pdf, internal_font_number f)
+{
+ int ff; /* for use with |set_ff| */
+ if (!font_used(f))
+ pdf_init_font(pdf, f);
+ /*
+ set |ff| to the tfm number of the base font sharing the font object with |f|;
+ |ff| is either |f| itself (then it is its own base font),
+ or some font with the same tfm name at different size and/or expansion.
+ */
+ ff = pdf_font_num(f) < 0 ? -pdf_font_num(f) : f; /* aka |set_ff(f)| */
+ addto_page_resources(pdf, obj_type_font, ff);
+ return ff;
+}
+
+@ Here come some subroutines to deal with expanded fonts for HZ-algorithm.
+@c
+void copy_expand_params(internal_font_number k, internal_font_number f, int e)
+{ /* set expansion-related parameters for an expanded font |k|, based on the base
+ font |f| and the expansion amount |e| */
+ set_font_expand_ratio(k, e);
+ set_font_step(k, font_step(f));
+ set_font_auto_expand(k, font_auto_expand(f));
+ set_pdf_font_blink(k, f);
+}
+
+@ return 1 == identical
+@c
+static boolean cmp_font_name(int id, char *tt)
+{
+ char *tid;
+ if (!is_valid_font(id))
+ return 0;
+ tid = font_name(id);
+ if (tt == NULL && tid == NULL)
+ return 1;
+ if (tt == NULL || tid == NULL || strcmp(tid, tt) != 0)
+ return 0;
+ return 1;
+}
+
+@ @c
+internal_font_number tfm_lookup(char *s, scaled fs, int e)
+{ /* looks up for a TFM with name |s| loaded at |fs| size; if found then flushes |s| */
+ internal_font_number k;
+ if (fs != 0) {
+ for (k = 1; k <= max_font_id(); k++) {
+ if (cmp_font_name(k, s) && font_size(k) == fs
+ && font_expand_ratio(k) == e) {
+ return k;
+ }
+ }
+ } else {
+ for (k = 1; k <= max_font_id(); k++) {
+ if (cmp_font_name(k, s) && font_expand_ratio(k) == e) {
+ return k;
+ }
+ }
+ }
+ return null_font;
+}
+
+@ @c
+static internal_font_number load_expand_font(internal_font_number f, int e)
+{ /* loads font |f| expanded by |e| thousandths into font memory; |e| is nonzero
+ and is a multiple of |font_step(f)| */
+ internal_font_number k;
+ k = tfm_lookup(font_name(f), font_size(f), e);
+ if (k == null_font) {
+ if (font_auto_expand(f)) {
+ k = auto_expand_font(f, e);
+ font_id_text(k) = font_id_text(f);
+ } else {
+ k = read_font_info(null_cs, font_name(f), font_size(f),
+ font_natural_dir(f));
+ }
+ }
+ copy_expand_params(k, f, e);
+ return k;
+}
+
+@ @c
+static int fix_expand_value(internal_font_number f, int e)
+{ /* return the multiple of |font_step(f)| that is nearest to |e| */
+ int step;
+ int max_expand;
+ boolean neg;
+ if (e == 0)
+ return 0;
+ if (e < 0) {
+ e = -e;
+ neg = true;
+ max_expand = -font_expand_ratio(font_shrink(f));
+ } else {
+ neg = false;
+ max_expand = font_expand_ratio(font_stretch(f));
+ }
+ if (e > max_expand) {
+ e = max_expand;
+ } else {
+ step = font_step(f);
+ if (e % step > 0)
+ e = step * round_xn_over_d(e, 1, step);
+ }
+ if (neg)
+ e = -e;
+ return e;
+}
+
+@ @c
+static internal_font_number get_expand_font(internal_font_number f, int e)
+{ /* look up and create if not found an expanded version of |f|; |f| is an
+ expandable font; |e| is nonzero and is a multiple of |font_step(f)| */
+ internal_font_number k;
+ k = pdf_font_elink(f);
+ while (k != null_font) {
+ if (font_expand_ratio(k) == e)
+ return k;
+ k = pdf_font_elink(k);
+ }
+ k = load_expand_font(f, e);
+ set_pdf_font_elink(k, pdf_font_elink(f));
+ set_pdf_font_elink(f, k);
+ return k;
+}
+
+@ @c
+internal_font_number expand_font(internal_font_number f, int e)
+{ /* looks up for font |f| expanded by |e| thousandths, |e| is an arbitrary value
+ between max stretch and max shrink of |f|; if not found then creates it */
+ if (e == 0)
+ return f;
+ e = fix_expand_value(f, e);
+ if (e == 0)
+ return f;
+ if (pdf_font_elink(f) == null_font)
+ pdf_error("font expansion", "uninitialized pdf_font_elink");
+ return get_expand_font(f, e);
+}
+
+@ @c
+void set_expand_params(internal_font_number f, boolean auto_expand,
+ int stretch_limit, int shrink_limit,
+ int font_step, int expand_ratio)
+{ /* expand a font with given parameters */
+ set_font_step(f, font_step);
+ set_font_auto_expand(f, auto_expand);
+ if (stretch_limit > 0)
+ set_font_stretch(f, get_expand_font(f, stretch_limit));
+ if (shrink_limit > 0)
+ set_font_shrink(f, get_expand_font(f, -shrink_limit));
+ if (expand_ratio != 0)
+ set_font_expand_ratio(f, expand_ratio);
+}
+
+@ @c
+void read_expand_font(void)
+{ /* read font expansion spec and load expanded font */
+ int shrink_limit, stretch_limit, font_step;
+ internal_font_number f;
+ boolean auto_expand;
+ /* read font expansion parameters */
+ scan_font_ident();
+ f = cur_val;
+ if (f == null_font)
+ pdf_error("font expansion", "invalid font identifier");
+ if (pdf_font_blink(f) != null_font)
+ pdf_error("font expansion",
+ "\\pdffontexpand cannot be used this way (the base font has been expanded)");
+ scan_optional_equals();
+ scan_int();
+ stretch_limit = fix_int(cur_val, 0, 1000);
+ scan_int();
+ shrink_limit = fix_int(cur_val, 0, 500);
+ scan_int();
+ font_step = fix_int(cur_val, 0, 100);
+ if (font_step == 0)
+ pdf_error("font expansion", "invalid step");
+ stretch_limit = stretch_limit - stretch_limit % font_step;
+ if (stretch_limit < 0)
+ stretch_limit = 0;
+ shrink_limit = shrink_limit - shrink_limit % font_step;
+ if (shrink_limit < 0)
+ shrink_limit = 0;
+ if ((stretch_limit == 0) && (shrink_limit == 0))
+ pdf_error("font expansion", "invalid limit(s)");
+ auto_expand = false;
+ if (scan_keyword("autoexpand")) {
+ auto_expand = true;
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ }
+
+ /* check if the font can be expanded */
+ if (font_expand_ratio(f) != 0)
+ pdf_error("font expansion",
+ "this font has been expanded by another font so it cannot be used now");
+ if (font_step(f) != 0) {
+ /* this font has been expanded, ensure the expansion parameters are identical */
+ if (font_step(f) != font_step)
+ pdf_error("font expansion",
+ "font has been expanded with different expansion step");
+
+ if (((font_stretch(f) == null_font) && (stretch_limit != 0)) ||
+ ((font_stretch(f) != null_font)
+ && (font_expand_ratio(font_stretch(f)) != stretch_limit)))
+ pdf_error("font expansion",
+ "font has been expanded with different stretch limit");
+
+ if (((font_shrink(f) == null_font) && (shrink_limit != 0)) ||
+ ((font_shrink(f) != null_font)
+ && (-font_expand_ratio(font_shrink(f)) != shrink_limit)))
+ pdf_error("font expansion",
+ "font has been expanded with different shrink limit");
+
+ if (font_auto_expand(f) != auto_expand)
+ pdf_error("font expansion",
+ "font has been expanded with different auto expansion value");
+ } else {
+ if (font_used(f))
+ pdf_warning("font expansion",
+ "font should be expanded before its first use", true,
+ true);
+ set_expand_params(f, auto_expand, stretch_limit, shrink_limit,
+ font_step, 0);
+ if (font_type(f) == virtual_font_type)
+ vf_expand_local_fonts(f);
+ }
+}
+
+@ @c
+void new_letterspaced_font(small_number a)
+{ /* letter-space a font by creating a virtual font */
+ pointer u; /* user's font identifier */
+ str_number t; /* name for the frozen font identifier */
+ internal_font_number f, k;
+ get_r_token();
+ u = cur_cs;
+ if (u >= hash_base)
+ t = cs_text(u);
+ else
+ t = maketexstring("FONT");
+ define(u, set_font_cmd, null_font);
+ scan_optional_equals();
+ scan_font_ident();
+ k = cur_val;
+ scan_int();
+ f = letter_space_font(u, k, fix_int(cur_val, -1000, 1000));
+ equiv(u) = f;
+ eqtb[font_id_base + f] = eqtb[u];
+ font_id_text(f) = t;
+}
+
+@ @c
+void make_font_copy(small_number a)
+{ /* make a font copy for further use with font expansion */
+ pointer u; /* user's font identifier */
+ str_number t; /* name for the frozen font identifier */
+ internal_font_number f, k;
+ get_r_token();
+ u = cur_cs;
+ if (u >= hash_base)
+ t = cs_text(u);
+ else
+ t = maketexstring("FONT");
+ define(u, set_font_cmd, 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;
+}
+
+@ @c
+void pdf_include_chars(PDF pdf)
+{
+ str_number s;
+ unsigned char *k, *j; /* running index */
+ internal_font_number f;
+ scan_font_ident();
+ f = cur_val;
+ if (f == null_font)
+ pdf_error("font", "invalid font identifier");
+ pdf_check_vf(cur_val);
+ if (!font_used(f))
+ pdf_init_font(pdf, f);
+ scan_pdf_ext_toks();
+ s = tokens_to_string(def_ref);
+ delete_token_ref(def_ref);
+ j = str_string(s) + str_length(s);
+ for (k = str_string(s); k < j; k++) {
+ pdf_mark_char(f, *k);
+ }
+ flush_str(s);
+}
+
+@ @c
+void glyph_to_unicode(void)
+{
+ str_number s1, s2;
+ scan_pdf_ext_toks();
+ s1 = tokens_to_string(def_ref);
+ delete_token_ref(def_ref);
+ scan_pdf_ext_toks();
+ s2 = tokens_to_string(def_ref);
+ delete_token_ref(def_ref);
+ def_tounicode(s1, s2);
+ flush_str(s2);
+ flush_str(s1);
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h
new file mode 100644
index 00000000000..f5840e715db
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.h
@@ -0,0 +1,239 @@
+/* pdfgen.h
+
+ Copyright 2009-2010 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfgen.h 3573 2010-04-02 14:10:54Z hhenkel $ */
+
+#ifndef PDFGEN_H
+# define PDFGEN_H
+
+# define PROCSET_PDF (1 << 0)
+# define PROCSET_TEXT (1 << 1)
+# define PROCSET_IMAGE_B (1 << 2)
+# define PROCSET_IMAGE_C (1 << 3)
+# define PROCSET_IMAGE_I (1 << 4)
+
+# define inf_pdf_mem_size 10000 /* min size of the |mem| array */
+# define sup_pdf_mem_size 10000000 /* max size of the |mem| array */
+
+extern PDF static_pdf;
+
+extern int pdf_get_mem(PDF pdf, int s);
+
+/*
+We use the similiar subroutines to handle the output buffer for
+PDF output. When compress is used, the state of writing to buffer
+is held in |zip_write_state|. We must write the header of PDF
+output file in initialization to ensure that it will be the first
+written bytes.
+*/
+
+# define inf_pdf_op_buf_size 16384 /* size of the PDF output buffer */
+# define sup_pdf_op_buf_size 16384 /* size of the PDF output buffer */
+# define inf_pdf_os_buf_size 1 /* initial value of |pdf_os_buf_size| */
+# define sup_pdf_os_buf_size 5000000 /* arbitrary upper hard limit of |pdf_os_buf_size| */
+# define max_single_pdf_print 8192 /* Max size that can be get from pdf_room() at once.
+ the value is on the conservative side, but should be
+ large enough to cover most uses */
+# define pdf_os_max_objs 100 /* maximum number of objects in object stream */
+
+# define inf_obj_tab_size 1000 /* min size of the cross-reference table for PDF output */
+# define sup_obj_tab_size 8388607 /* max size of the cross-reference table for PDF output */
+
+/* The following macros are similar as for \.{DVI} buffer handling */
+
+# define pdf_offset(pdf) (pdf->gone + pdf->ptr)
+ /* the file offset of last byte in PDF
+ buffer that |pdf_ptr| points to */
+# define pdf_save_offset(pdf) pdf->save_offset=(pdf->gone + pdf->ptr)
+# define pdf_saved_offset(pdf) pdf->save_offset
+
+# define set_ff(A) do { \
+ if (pdf_font_num(A) < 0) \
+ ff = -pdf_font_num(A); \
+ else \
+ ff = A; \
+ } while (0)
+
+typedef enum {
+ no_zip = 0, /* no \.{ZIP} compression */
+ zip_writing = 1, /* \.{ZIP} compression being used */
+ zip_finish = 2 /* finish \.{ZIP} compression */
+} zip_write_states;
+
+extern int pdf_output_option;
+extern int pdf_output_value;
+extern int pdf_draftmode_option;
+extern int pdf_draftmode_value;
+
+extern scaled one_hundred_inch;
+extern scaled one_inch;
+extern scaled one_true_inch;
+extern scaled one_hundred_bp;
+extern scaled one_bp;
+extern int ten_pow[10];
+
+extern void pdf_flush(PDF);
+extern void pdf_room(PDF, int);
+
+extern void fix_pdf_minorversion(PDF);
+
+ /* output a byte to PDF buffer without checking of overflow */
+# define pdf_quick_out(pdf,A) pdf->buf[pdf->ptr++]=(unsigned char)A
+
+/* do the same as |pdf_quick_out| and flush the PDF buffer if necessary */
+# define pdf_out(pdf,A) do { pdf_room(pdf,1); pdf_quick_out(pdf,A); } while (0)
+
+# define pdf_out_block(pdf,A,n) do { \
+ pdf_room(pdf,(int)(n)); \
+ (void)memcpy((pdf->buf+pdf->ptr),(A),(size_t)(n)); \
+ pdf->ptr+=(int)(n); \
+ } while (0)
+
+/*
+Basic printing procedures for PDF output are very similiar to \TeX\ basic
+printing ones but the output is going to PDF buffer. Subroutines with
+suffix |_ln| append a new-line character to the PDF output.
+*/
+
+# define pdf_new_line_char 10 /* new-line character for UNIX platforms */
+
+/* output a new-line character to PDF buffer */
+# define pdf_print_nl(pdf) pdf_out(pdf,pdf_new_line_char)
+
+/* print out a string to PDF buffer followed by a new-line character */
+# define pdf_print_ln(pdf,A) do { \
+ pdf_print(pdf,A); \
+ pdf_print_nl(pdf); \
+ } while (0)
+
+/* print out an integer to PDF buffer followed by a new-line character */
+# define pdf_print_int_ln(pdf,A) do { \
+ pdf_print_int(pdf,A); \
+ pdf_print_nl(pdf); \
+ } while (0)
+
+extern void pdf_puts(PDF, const char *);
+extern __attribute__ ((format(printf, 2, 3)))
+void pdf_printf(PDF, const char *, ...);
+
+extern void pdf_print_char(PDF, int);
+extern void pdf_print_wide_char(PDF, int);
+extern void pdf_print(PDF, str_number);
+extern void pdf_print_int(PDF, longinteger);
+extern void pdf_print_real(PDF, int, int);
+extern void pdf_print_str(PDF, const char *);
+
+extern void pdf_begin_stream(PDF);
+extern void pdf_end_stream(PDF);
+extern void pdf_remove_last_space(PDF);
+
+extern void pdf_print_bp(PDF, scaled);
+extern void pdf_print_mag_bp(PDF, scaled);
+
+/* This is for the resource lists */
+
+extern void addto_page_resources(PDF pdf, pdf_obj_type t, int k);
+extern pdf_object_list *get_page_resources_list(PDF pdf, pdf_obj_type t);
+
+# define pdf_print_resname_prefix(pdf) do { \
+ if (pdf->resname_prefix != NULL) \
+ pdf_puts(pdf,pdf->resname_prefix); \
+ } while (0)
+
+extern void pdf_print_fw_int(PDF, longinteger, int);
+extern void pdf_out_bytes(PDF, longinteger, int);
+extern void pdf_int_entry(PDF, const char *, int);
+extern void pdf_int_entry_ln(PDF, const char *, int);
+extern void pdf_indirect(PDF, const char *, int);
+extern void pdf_indirect_ln(PDF, const char *, int);
+extern void pdf_print_str_ln(PDF, const char *);
+extern void pdf_str_entry(PDF, const char *, const char *);
+extern void pdf_str_entry_ln(PDF, const char *, const char *);
+
+extern void pdf_print_toks(PDF, halfword);
+extern void pdf_print_toks_ln(PDF, halfword);
+
+extern void pdf_print_rect_spec(PDF, halfword);
+extern void pdf_rectangle(PDF, halfword);
+
+extern void pdf_begin_obj(PDF, int, int);
+extern void pdf_new_obj(PDF, int, int, int);
+extern void pdf_end_obj(PDF);
+
+extern void pdf_begin_dict(PDF, int, int);
+extern void pdf_new_dict(PDF, int, int, int);
+extern void pdf_end_dict(PDF);
+
+extern void pdf_os_switch(PDF pdf, boolean pdf_os);
+extern void pdf_os_prepare_obj(PDF pdf, int i, int pdf_os_level);
+extern void pdf_os_write_objstream(PDF);
+
+extern void write_stream_length(PDF, int, longinteger);
+
+extern void print_creation_date(PDF);
+extern void print_mod_date(PDF);
+extern void print_ID(PDF, const char *);
+
+extern void remove_pdffile(PDF);
+
+extern int fb_offset(PDF);
+extern void fb_flush(PDF);
+extern void fb_putchar(PDF, eight_bits);
+extern void fb_seek(PDF, int);
+extern void fb_free(PDF);
+
+extern void write_zip(PDF, boolean);
+extern void zip_free(PDF);
+
+/* functions that do not output stuff */
+
+extern scaled round_xn_over_d(scaled x, int n, int d);
+extern char *convertStringToPDFString(const char *in, int len);
+
+extern void init_start_time(PDF);
+extern char *getcreationdate(PDF);
+
+extern void pdf_error(const char *t, const char *p);
+extern void pdf_warning(const char *t, const char *p, boolean pr, boolean ap);
+extern void check_o_mode(PDF pdf, const char *s, int o_mode, boolean errorflag);
+
+extern void set_job_id(PDF, int, int, int, int);
+extern char *get_resname_prefix(PDF);
+extern void pdf_begin_page(PDF pdf, boolean shipping_page);
+extern void pdf_end_page(PDF pdf, boolean shipping_page);
+
+extern void fix_o_mode(PDF pdf);
+extern void ensure_output_state(PDF pdf, output_state s);
+extern PDF init_pdf_struct(PDF pdf);
+
+extern halfword pdf_info_toks; /* additional keys of Info dictionary */
+extern halfword pdf_catalog_toks; /* additional keys of Catalog dictionary */
+extern halfword pdf_catalog_openaction;
+extern halfword pdf_names_toks; /* additional keys of Names dictionary */
+extern halfword pdf_trailer_toks; /* additional keys of Trailer dictionary */
+extern halfword pdf_pageattributes_toks; /* additional keys of Page dictionary */
+extern halfword pdf_pageresources_toks; /* additional keys of Resources dictionary */
+extern halfword pdf_pagesattributes_toks; /* additional keys of Pages dictionary */
+extern void scan_pdfcatalog(PDF pdf);
+extern void finish_pdf_file(PDF pdf, int luatex_version,
+ str_number luatex_revision);
+
+extern boolean is_shipping_page;
+
+#endif /* PDFGEN_H */
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w
new file mode 100644
index 00000000000..cbb7ccf8b89
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w
@@ -0,0 +1,2479 @@
+% pdfgen.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfgen.w 3573 2010-04-02 14:10:54Z hhenkel $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfgen.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#include <kpathsea/c-dir.h>
+#include <kpathsea/c-ctype.h>
+#include "md5.h"
+
+#define is_hex_char isxdigit
+
+#define check_nprintf(size_get, size_want) \
+ if ((unsigned)(size_get) >= (unsigned)(size_want)) \
+ pdftex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__);
+
+PDF static_pdf = NULL;
+
+static char *jobname_cstr = NULL;
+
+@ commandline interface
+@c
+int pdf_output_option;
+int pdf_output_value;
+int pdf_draftmode_option;
+int pdf_draftmode_value;
+
+halfword pdf_info_toks; /* additional keys of Info dictionary */
+halfword pdf_catalog_toks; /* additional keys of Catalog dictionary */
+halfword pdf_catalog_openaction;
+halfword pdf_names_toks; /* additional keys of Names dictionary */
+halfword pdf_trailer_toks; /* additional keys of Trailer dictionary */
+halfword pdf_pageattributes_toks; /* additional keys of Page dictionary */
+halfword pdf_pageresources_toks; /* additional keys of Resources dictionary */
+halfword pdf_pagesattributes_toks; /* additional keys of Pages dictionary */
+boolean is_shipping_page; /* set to |shipping_page| when |ship_out| starts */
+
+@ |init_pdf_struct()| is called early, only once, from maincontrol.w
+
+@c
+PDF init_pdf_struct(PDF pdf)
+{
+ assert(pdf == NULL);
+ pdf = xmalloc(sizeof(pdf_output_file));
+ memset(pdf, 0, sizeof(pdf_output_file));
+
+ pdf->o_mode = OMODE_NONE; /* will be set by |fix_o_mode()| */
+ pdf->o_state = ST_INITIAL;
+
+ pdf->os_obj = xmalloc(pdf_os_max_objs * sizeof(os_obj_data));
+ pdf->os_buf_size = inf_pdf_os_buf_size;
+ pdf->os_buf = xmalloc((unsigned) pdf->os_buf_size * sizeof(unsigned char));
+ pdf->op_buf_size = inf_pdf_op_buf_size;
+ pdf->op_buf = xmalloc((unsigned) pdf->op_buf_size * sizeof(unsigned char));
+
+ pdf->buf_size = pdf->op_buf_size;
+ pdf->buf = pdf->op_buf;
+
+ /* Sometimes it is neccesary to allocate memory for PDF output that cannot
+ be deallocated then, so we use |mem| for this purpose. */
+ pdf->mem_size = inf_pdf_mem_size; /* allocated size of |mem| array */
+ pdf->mem = xmalloc((unsigned) ((unsigned) pdf->mem_size * sizeof(int)));
+ pdf->mem_ptr = 1; /* the first word is not used so we can use zero as a value for testing
+ whether a pointer to |mem| is valid */
+ pdf->pstruct = NULL;
+
+ pdf->posstruct = xmalloc(sizeof(posstructure));
+ pdf->posstruct->pos.h = 0;
+ pdf->posstruct->pos.v = 0;
+ pdf->posstruct->dir = dir_TLT;
+
+ pdf->obj_tab_size = (unsigned) inf_obj_tab_size; /* allocated size of |obj_tab| array */
+ pdf->obj_tab = xmalloc((unsigned)
+ ((unsigned) (pdf->obj_tab_size + 1) *
+ sizeof(obj_entry)));
+ memset(pdf->obj_tab, 0, sizeof(obj_entry));
+
+ pdf->minor_version = -1; /* unset */
+ pdf->decimal_digits = 4;
+ pdf->gamma = 65536;
+ pdf->image_gamma = 65536;
+ pdf->image_hicolor = 1;
+ pdf->image_apply_gamma = 0;
+ pdf->objcompresslevel = 0;
+ pdf->compress_level = 0;
+ pdf->draftmode = 0;
+ pdf->inclusion_copy_font = 1;
+ pdf->replace_font = 0;
+ pdf->pk_resolution = 0;
+ pdf->pk_scale_factor = 0;
+
+ init_dest_names(pdf);
+ pdf->page_resources = NULL;
+
+ init_pdf_pagecalculations(pdf);
+
+ return pdf;
+}
+
+@ @c
+static void pdf_shipout_begin(boolean shipping_page)
+{
+ pos_stack_used = 0; /* start with empty stack */
+
+ page_mode = shipping_page;
+ if (shipping_page) {
+ colorstackpagestart();
+ }
+}
+
+static void pdf_shipout_end(boolean shipping_page)
+{
+ if (pos_stack_used > 0) {
+ pdftex_fail("%u unmatched \\pdfsave after %s shipout",
+ (unsigned int) pos_stack_used,
+ ((shipping_page) ? "page" : "form"));
+ }
+}
+
+@ We use |pdf_get_mem| to allocate memory in |mem|.
+
+@c
+int pdf_get_mem(PDF pdf, int s)
+{ /* allocate |s| words in |mem| */
+ int a;
+ int ret;
+ if (s > sup_pdf_mem_size - pdf->mem_ptr)
+ overflow("PDF memory size (pdf_mem_size)", (unsigned) pdf->mem_size);
+ if (pdf->mem_ptr + s > pdf->mem_size) {
+ a = pdf->mem_size / 5;
+ if (pdf->mem_ptr + s > pdf->mem_size + a) {
+ pdf->mem_size = pdf->mem_ptr + s;
+ } else if (pdf->mem_size < sup_pdf_mem_size - a) {
+ pdf->mem_size = pdf->mem_size + a;
+ } else {
+ pdf->mem_size = sup_pdf_mem_size;
+ }
+ pdf->mem = xreallocarray(pdf->mem, int, (unsigned) pdf->mem_size);
+ }
+ ret = pdf->mem_ptr;
+ pdf->mem_ptr = pdf->mem_ptr + s;
+ return ret;
+}
+
+
+@ |fix_o_mode| freezes |pdf->o_mode| as soon as anything goes through
+the backend, be it \.{PDF}, \.{DVI}, or \.{Lua}.
+
+@c
+#define pdf_output int_par(pdf_output_code)
+
+void fix_o_mode(PDF pdf)
+{
+ static int fixed_pdf_output = 0;
+ if (pdf->o_mode == OMODE_NONE) {
+ if (pdf_output > 0) {
+ if (pdf_output == 2009)
+ pdf->o_mode = OMODE_LUA;
+ else
+ pdf->o_mode = OMODE_PDF;
+ } else
+ pdf->o_mode = OMODE_DVI;
+ fixed_pdf_output = pdf_output;
+ pdf_output_value = pdf_output;
+ } else if (pdf_output != fixed_pdf_output) {
+ pdf_error("setup",
+ "\\pdfoutput can only be changed before anything is written to the output");
+ }
+}
+
+
+@ This ensures that |pdfminorversion| is set only before any bytes have
+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.
+
+@c
+void fix_pdf_minorversion(PDF pdf)
+{
+ if (pdf->minor_version < 0) { /* unset */
+ if ((pdf_minor_version < 0) || (pdf_minor_version > 9)) {
+ const char *hlp[] =
+ { "The pdfminorversion must be between 0 and 9.",
+ "I changed this to 4.", NULL
+ };
+ char msg[256];
+ (void) snprintf(msg, 255,
+ "LuaTeX error (illegal pdfminorversion %d)",
+ (int) pdf_minor_version);
+ tex_error(msg, hlp);
+ pdf_minor_version = 4;
+ }
+ pdf->minor_version = pdf_minor_version;
+ } else {
+ /* Check that variables for \.{PDF} output are unchanged */
+ if (pdf->minor_version != int_par(pdf_minor_version_code))
+ pdf_error("setup",
+ "\\pdfminorversion cannot be changed after data is written to the PDF file");
+ if (pdf->draftmode != int_par(pdf_draftmode_code))
+ pdf_error("setup",
+ "\\pdfdraftmode cannot be changed after data is written to the PDF file");
+ }
+ if (pdf->draftmode != 0) {
+ pdf->compress_level = 0; /* re-fix it, might have been changed inbetween */
+ pdf->objcompresslevel = 0;
+ }
+}
+
+@ 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.
+
+@c
+static void write_pdf(PDF pdf, int a, int b)
+{
+ (void) fwrite((char *) &pdf->buf[a], sizeof(pdf->buf[a]),
+ (size_t) ((b) - (a) + 1), pdf->file);
+}
+
+@ @c
+void pdf_flush(PDF pdf)
+{ /* flush out the |pdf_buf| */
+
+ off_t saved_pdf_gone;
+ if (!pdf->os_mode) {
+ saved_pdf_gone = pdf->gone;
+ switch (pdf->zip_write_state) {
+ case no_zip:
+ if (pdf->ptr > 0) {
+ if (pdf->draftmode == 0)
+ write_pdf(pdf, 0, pdf->ptr - 1);
+ pdf->gone += pdf->ptr;
+ pdf->last_byte = pdf->buf[pdf->ptr - 1];
+ }
+ break;
+ case zip_writing:
+ if (pdf->draftmode == 0)
+ write_zip(pdf, false);
+ break;
+ case zip_finish:
+ if (pdf->draftmode == 0)
+ write_zip(pdf, true);
+ pdf->zip_write_state = no_zip;
+ break;
+ }
+ pdf->ptr = 0;
+ if (saved_pdf_gone > pdf->gone)
+ pdf_error("file size",
+ "File size exceeds architectural limits (pdf_gone wraps around)");
+ }
+}
+
+@ switch between PDF stream and object stream mode
+
+@c
+void pdf_os_switch(PDF pdf, boolean pdf_os)
+{
+ if (pdf_os && pdf->os_enable) {
+ if (!pdf->os_mode) { /* back up PDF stream variables */
+ pdf->op_ptr = pdf->ptr;
+ pdf->ptr = pdf->os_ptr;
+ pdf->buf = pdf->os_buf;
+ pdf->buf_size = pdf->os_buf_size;
+ pdf->os_mode = true; /* switch to object stream */
+ }
+ } else {
+ if (pdf->os_mode) { /* back up object stream variables */
+ pdf->os_ptr = pdf->ptr;
+ pdf->ptr = pdf->op_ptr;
+ pdf->buf = pdf->op_buf;
+ pdf->buf_size = pdf->op_buf_size;
+ pdf->os_mode = false; /* switch to PDF stream */
+ }
+ }
+}
+
+@ create new \.{/ObjStm} object if required, and set up cross reference info
+
+@c
+void pdf_os_prepare_obj(PDF pdf, int i, int pdf_os_level)
+{
+ pdf_os_switch(pdf, ((pdf_os_level > 0)
+ && (pdf->objcompresslevel >= pdf_os_level)));
+ if (pdf->os_mode) {
+ if (pdf->os_cur_objnum == 0) {
+ pdf_create_obj(pdf, obj_type_objstm, pdf->sys_obj_ptr + 1);
+ pdf->os_cur_objnum = pdf->sys_obj_ptr;
+ pdf->obj_ptr--; /* object stream is not accessible to user */
+ pdf->os_cntr++; /* only for statistics */
+ pdf->os_idx = 0;
+ pdf->ptr = 0; /* start fresh object stream */
+ } else {
+ pdf->os_idx++;
+ }
+ obj_os_idx(pdf, i) = pdf->os_idx;
+ obj_offset(pdf, i) = pdf->os_cur_objnum;
+ pdf->os_obj[pdf->os_idx].num = i;
+ pdf->os_obj[pdf->os_idx].off = pdf->ptr;
+ } else {
+ obj_offset(pdf, i) = pdf_offset(pdf);
+ obj_os_idx(pdf, i) = -1; /* mark it as not included in object stream */
+ }
+}
+
+@* low-level buffer checkers.
+
+@ check that |s| bytes more fit into |pdf_os_buf|; increase it if required
+@c
+static void pdf_os_get_os_buf(PDF pdf, int s)
+{
+ int a;
+ if (s > sup_pdf_os_buf_size - pdf->ptr)
+ overflow("PDF object stream buffer", (unsigned) pdf->os_buf_size);
+ if (pdf->ptr + s > pdf->os_buf_size) {
+ a = pdf->os_buf_size / 5;
+ if (pdf->ptr + s > pdf->os_buf_size + a)
+ pdf->os_buf_size = pdf->ptr + s;
+ else if (pdf->os_buf_size < sup_pdf_os_buf_size - a)
+ pdf->os_buf_size = pdf->os_buf_size + a;
+ else
+ pdf->os_buf_size = sup_pdf_os_buf_size;
+ pdf->os_buf =
+ xreallocarray(pdf->os_buf, unsigned char,
+ (unsigned) pdf->os_buf_size);
+ pdf->buf = pdf->os_buf;
+ pdf->buf_size = pdf->os_buf_size;
+ }
+}
+
+@ make sure that there are at least |n| bytes free in PDF buffer
+@c
+void pdf_room(PDF pdf, int n)
+{
+ if (pdf->os_mode && (n + pdf->ptr > pdf->buf_size))
+ pdf_os_get_os_buf(pdf, n);
+ else if ((!pdf->os_mode) && (n > pdf->buf_size))
+ overflow("PDF output buffer", (unsigned) pdf->op_buf_size);
+ else if ((!pdf->os_mode) && (n + pdf->ptr > pdf->buf_size))
+ pdf_flush(pdf);
+}
+
+
+@ print out a character to PDF buffer; the character will be printed in octal
+ form in the following cases: chars <= 32, backslash (92), left parenthesis
+ (40) and right parenthesis (41)
+
+@c
+#define pdf_print_escaped(c) \
+ if ((c)<=32||(c)=='\\'||(c)=='('||(c)==')'||(c)>127) { \
+ pdf_room(pdf,4); \
+ pdf_quick_out(pdf,'\\'); \
+ pdf_quick_out(pdf,(unsigned char)('0' + (((c)>>6) & 0x3))); \
+ pdf_quick_out(pdf,(unsigned char)('0' + (((c)>>3) & 0x7))); \
+ pdf_quick_out(pdf,(unsigned char)('0' + ( (c) & 0x7))); \
+ } else { \
+ pdf_out(pdf,(c)); \
+ }
+
+void pdf_print_char(PDF pdf, int c)
+{
+ if (c > 255)
+ return;
+ pdf_print_escaped(c);
+}
+
+void pdf_print_wide_char(PDF pdf, int c)
+{
+ char hex[5];
+ snprintf(hex, 5, "%04X", c);
+ pdf_room(pdf, 4);
+ pdf_quick_out(pdf, (unsigned char) hex[0]);
+ pdf_quick_out(pdf, (unsigned char) hex[1]);
+ pdf_quick_out(pdf, (unsigned char) hex[2]);
+ pdf_quick_out(pdf, (unsigned char) hex[3]);
+}
+
+@ @c
+void pdf_puts(PDF pdf, const char *s)
+{
+
+ size_t l = strlen(s);
+ if (l < (size_t) pdf->buf_size) {
+ pdf_room(pdf, (int) l);
+ while (*s != '\0')
+ pdf_quick_out(pdf, *s++);
+ } else {
+ while (*s != '\0')
+ pdf_out(pdf, *s++);
+ }
+}
+
+@ @c
+__attribute__ ((format(printf, 2, 3)))
+void pdf_printf(PDF pdf, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ if (pdf->printf_buf == NULL) {
+ pdf->printf_buf = xtalloc(PRINTF_BUF_SIZE, char);
+ }
+ (void) vsnprintf(pdf->printf_buf, PRINTF_BUF_SIZE, fmt, args);
+ pdf_puts(pdf, pdf->printf_buf);
+ va_end(args);
+}
+
+@ print out a string to PDF buffer
+@c
+void pdf_print(PDF pdf, str_number s)
+{
+ if (s < number_chars) {
+ assert(s < 256);
+ pdf_out(pdf, s);
+ } else {
+ unsigned char *k, *j;
+ j = str_string(s) + str_length(s);
+ for (k = str_string(s); k < j; k++) {
+ pdf_out(pdf, *k);
+ }
+ }
+}
+
+@ print out a integer to PDF buffer
+@c
+void pdf_print_int(PDF pdf, longinteger n)
+{
+ register int k = 0; /* current digit; we assume that $|n|<10^{23}$ */
+ int dig[24];
+ if (n < 0) {
+ pdf_out(pdf, '-');
+ if (n < -0x7FFFFFFF) { /* need to negate |n| more carefully */
+ register longinteger m;
+ k++;
+ m = -1 - n;
+ n = m / 10;
+ m = (m % 10) + 1;
+ if (m < 10) {
+ dig[0] = (int) m;
+ } else {
+ dig[0] = 0;
+ n++;
+ }
+ } else {
+ n = -n;
+ }
+ }
+ do {
+ dig[k++] = (int) (n % 10);
+ n = n / 10;
+ } while (n != 0);
+ pdf_room(pdf, k);
+ while (k-- > 0) {
+ pdf_quick_out(pdf, (unsigned char) ('0' + dig[k]));
+ }
+}
+
+@ print $m/10^d$ as real
+@c
+void pdf_print_real(PDF pdf, int m, int d)
+{
+ if (m < 0) {
+ pdf_out(pdf, '-');
+ m = -m;
+ };
+ pdf_print_int(pdf, m / ten_pow[d]);
+ m = m % ten_pow[d];
+ if (m > 0) {
+ pdf_out(pdf, '.');
+ d--;
+ while (m < ten_pow[d]) {
+ pdf_out(pdf, '0');
+ d--;
+ }
+ while (m % 10 == 0)
+ m = m / 10;
+ pdf_print_int(pdf, m);
+ }
+}
+
+@ print out |s| as string in PDF output
+@c
+void pdf_print_str(PDF pdf, const char *s)
+{
+ const char *orig = s;
+ int l = (int) strlen(s) - 1; /* last string index */
+ if (l < 0) {
+ pdf_puts(pdf, "()");
+ return;
+ }
+ /* the next is not really safe, the string could be "(a)xx(b)" */
+ if ((s[0] == '(') && (s[l] == ')')) {
+ pdf_puts(pdf, s);
+ return;
+ }
+ if ((s[0] != '<') || (s[l] != '>') || odd((l + 1))) {
+ pdf_out(pdf, '(');
+ pdf_puts(pdf, s);
+ pdf_out(pdf, ')');
+ return;
+ }
+ s++;
+ while (is_hex_char(*s))
+ s++;
+ if (s != orig + l) {
+ pdf_out(pdf, '(');
+ pdf_puts(pdf, orig);
+ pdf_out(pdf, ')');
+ return;
+ }
+ pdf_puts(pdf, orig); /* it was a hex string after all */
+}
+
+@ begin a stream
+@c
+void pdf_begin_stream(PDF pdf)
+{
+ assert(pdf->os_mode == false);
+ pdf_puts(pdf, "/Length \n");
+ pdf->seek_write_length = true; /* fill in length at |pdf_end_stream| call */
+ pdf->stream_length_offset = pdf_offset(pdf) - 11;
+ pdf->stream_length = 0;
+ pdf->last_byte = 0;
+ if (pdf->compress_level > 0) {
+ pdf_puts(pdf, "/Filter /FlateDecode\n");
+ pdf_puts(pdf, ">>\n");
+ pdf_puts(pdf, "stream\n");
+ pdf_flush(pdf);
+ pdf->zip_write_state = zip_writing;
+ } else {
+ pdf_puts(pdf, ">>\n");
+ pdf_puts(pdf, "stream\n");
+ pdf_save_offset(pdf);
+ }
+}
+
+@ end a stream
+@c
+void pdf_end_stream(PDF pdf)
+{
+ if (pdf->zip_write_state == zip_writing)
+ pdf->zip_write_state = zip_finish;
+ else
+ pdf->stream_length = pdf_offset(pdf) - pdf_saved_offset(pdf);
+ pdf_flush(pdf);
+ if (pdf->seek_write_length)
+ write_stream_length(pdf, (int) pdf->stream_length,
+ pdf->stream_length_offset);
+ pdf->seek_write_length = false;
+ if (pdf->last_byte != pdf_new_line_char)
+ pdf_out(pdf, pdf_new_line_char);
+ pdf_puts(pdf, "endstream\n");
+ pdf_end_obj(pdf);
+}
+
+void pdf_remove_last_space(PDF pdf)
+{
+ if ((pdf->ptr > 0) && (pdf->buf[pdf->ptr - 1] == ' '))
+ pdf->ptr--;
+}
+
+
+@ To print |scaled| value to PDF output we need some subroutines to ensure
+accurary.
+
+@c
+#define max_integer 0x7FFFFFFF /* $2^{31}-1$ */
+
+/* scaled value corresponds to 100in, exact, 473628672 */
+scaled one_hundred_inch = 7227 * 65536;
+
+/* scaled value corresponds to 1in (rounded to 4736287) */
+scaled one_inch = (7227 * 65536 + 50) / 100;
+
+ /* scaled value corresponds to 1truein (rounded!) */
+scaled one_true_inch = (7227 * 65536 + 50) / 100;
+
+/* scaled value corresponds to 100bp */
+scaled one_hundred_bp = (7227 * 65536) / 72;
+
+/* scaled value corresponds to 1bp (rounded to 65782) */
+scaled one_bp = ((7227 * 65536) / 72 + 50) / 100;
+
+/* $10^0..10^9$ */
+int ten_pow[10] = {
+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
+};
+
+
+@ 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
+for optimizations that are not possible in pascal.
+
+@c
+scaled round_xn_over_d(scaled x, int n, int d)
+{
+ boolean positive; /* was |x>=0|? */
+ unsigned t, u, v; /* intermediate quantities */
+ if (x >= 0) {
+ positive = true;
+ } else {
+ x = -(x);
+ positive = false;
+ }
+ t = (unsigned) ((x % 0100000) * n);
+ u = (unsigned) (((unsigned) (x) / 0100000) * (unsigned) n + (t / 0100000));
+ v = (u % d) * 0100000 + (t % 0100000);
+ if (u / d >= 0100000)
+ arith_error = true;
+ else
+ u = 0100000 * (u / d) + (v / d);
+ v = v % d;
+ if (2 * v >= (unsigned) d)
+ u++;
+ if (positive)
+ return (scaled) u;
+ else
+ return (-(scaled) u);
+}
+
+@ @c
+#define lround(a) (long) floor((a) + 0.5)
+
+void pdf_print_bp(PDF pdf, scaled s)
+{ /* print scaled as |bp| */
+ pdffloat a;
+ pdfstructure *p = pdf->pstruct;
+ assert(p != NULL);
+ a.m = lround(s * p->k1);
+ a.e = pdf->decimal_digits;
+ print_pdffloat(pdf, a);
+}
+
+void pdf_print_mag_bp(PDF pdf, scaled s)
+{ /* take |mag| into account */
+ pdffloat a;
+ pdfstructure *p = pdf->pstruct;
+ prepare_mag();
+ if (int_par(mag_code) != 1000)
+ a.m = lround(s * (double) int_par(mag_code) / 1000.0 * p->k1);
+ else
+ a.m = lround(s * p->k1);
+ a.e = pdf->decimal_digits;
+ print_pdffloat(pdf, a);
+}
+
+#define set_p_or_return(a) do { \
+ p = a; \
+ if (p==NULL) { \
+ a = item; \
+ return; \
+ } \
+ } while (0)
+
+
+@* handling page resources.
+
+@c
+typedef struct {
+ int obj_type;
+ pdf_object_list *list;
+} pr_entry;
+
+@ @c
+static int comp_page_resources(const void *pa, const void *pb, void *p)
+{
+ int a, b;
+ (void) p;
+ a = ((const pr_entry *) pa)->obj_type;
+ b = ((const pr_entry *) pb)->obj_type;
+ if (a > b)
+ return 1;
+ if (a < b)
+ return -1;
+ return 0;
+}
+
+@ @c
+void addto_page_resources(PDF pdf, pdf_obj_type t, int k)
+{
+ pdf_resource_struct *re;
+ pr_entry *pr, tmp;
+ void **pp;
+ pdf_object_list *p, *item = NULL;
+ assert(pdf != NULL);
+ re = pdf->page_resources;
+ assert(re != NULL);
+ assert(t <= PDF_OBJ_TYPE_MAX);
+ if (re->resources_tree == NULL) {
+ re->resources_tree =
+ avl_create(comp_page_resources, NULL, &avl_xallocator);
+ if (re->resources_tree == NULL)
+ pdftex_fail
+ ("addto_page_resources(): avl_create() page_resource_tree failed");
+ }
+ tmp.obj_type = t;
+ pr = (pr_entry *) avl_find(re->resources_tree, &tmp);
+ if (pr == NULL) {
+ pr = xtalloc(1, pr_entry);
+ pr->obj_type = t;
+ pr->list = NULL;
+ pp = avl_probe(re->resources_tree, pr);
+ if (pp == NULL)
+ pdftex_fail
+ ("addto_page_resources(): avl_probe() out of memory in insertion");
+ }
+ if (pr->list == NULL) {
+ item = xmalloc(sizeof(pdf_object_list));
+ item->link = NULL;
+ item->info = k;
+ pr->list = item;
+ set_obj_scheduled(pdf, k);
+ } else {
+ for (p = pr->list; p->info != k && p->link != NULL; p = p->link);
+ if (p->info != k) {
+ item = xmalloc(sizeof(pdf_object_list));
+ item->link = NULL;
+ item->info = k;
+ p->link = item;
+ set_obj_scheduled(pdf, k);
+ }
+ }
+}
+
+@ @c
+pdf_object_list *get_page_resources_list(PDF pdf, pdf_obj_type t)
+{
+ pdf_resource_struct *re = pdf->page_resources;
+ pr_entry *pr, tmp;
+ if (re == NULL || re->resources_tree == NULL)
+ return NULL;
+ tmp.obj_type = t;
+ pr = (pr_entry *) avl_find(re->resources_tree, &tmp);
+ if (pr == NULL)
+ return NULL;
+ return pr->list;
+}
+
+@ @c
+static void reset_page_resources(PDF pdf)
+{
+ pdf_resource_struct *re = pdf->page_resources;
+ pr_entry *p;
+ struct avl_traverser t;
+ pdf_object_list *l1, *l2;
+ if (re == NULL || re->resources_tree == NULL)
+ return;
+ avl_t_init(&t, re->resources_tree);
+ for (p = avl_t_first(&t, re->resources_tree); p != NULL; p = avl_t_next(&t)) {
+ if (p->list != NULL) {
+ for (l1 = p->list; l1 != NULL; l1 = l2) {
+ l2 = l1->link;
+ free(l1);
+ }
+ p->list = NULL; /* but the AVL tree remains */
+ }
+ }
+}
+
+@ @c
+static void destroy_pg_res_tree(void *pa, void *param)
+{
+ (void) param;
+ xfree(pa);
+}
+
+@ @c
+static void destroy_page_resources_tree(PDF pdf)
+{
+ pdf_resource_struct *re = pdf->page_resources;
+ reset_page_resources(pdf);
+ if (re->resources_tree != NULL)
+ avl_destroy(re->resources_tree, destroy_pg_res_tree);
+ re->resources_tree = NULL;
+}
+
+@* Subroutines to print out various PDF objects.
+
+@ print out an integer with fixed width; used for outputting cross-reference table
+@c
+void pdf_print_fw_int(PDF pdf, longinteger n, int w)
+{
+ int k; /* $0\le k\le23$ */
+ int dig[24];
+ k = 0;
+ do {
+ dig[k] = (int) (n % 10);
+ n = n / 10;
+ k++;
+ } while (k != w);
+ pdf_room(pdf, k);
+ while (k-- > 0)
+ pdf_quick_out(pdf, (unsigned char) ('0' + dig[k]));
+}
+
+@ print out an integer as a number of bytes; used for outputting \.{/XRef} cross-reference stream
+@c
+void pdf_out_bytes(PDF pdf, longinteger n, int w)
+{
+ int k;
+ int bytes[8]; /* digits in a number being output */
+ k = 0;
+ do {
+ bytes[k] = (int) (n % 256);
+ n = n / 256;
+ k++;
+ } while (k != w);
+ pdf_room(pdf, k);
+ while (k-- > 0)
+ pdf_quick_out(pdf, bytes[k]);
+}
+
+@ print out an entry in dictionary with integer value to PDF buffer
+@c
+void pdf_int_entry(PDF pdf, const char *s, int v)
+{
+ pdf_printf(pdf, "/%s ", s);
+ pdf_print_int(pdf, v);
+}
+
+void pdf_int_entry_ln(PDF pdf, const char *s, int v)
+{
+
+ pdf_int_entry(pdf, s, v);
+ pdf_print_nl(pdf);
+}
+
+@ print out an indirect entry in dictionary
+@c
+void pdf_indirect(PDF pdf, const char *s, int o)
+{
+ pdf_printf(pdf, "/%s %d 0 R", s, (int) o);
+}
+
+void pdf_indirect_ln(PDF pdf, const char *s, int o)
+{
+
+ pdf_indirect(pdf, s, o);
+ pdf_print_nl(pdf);
+}
+
+@ print out |s| as string in PDF output
+@c
+void pdf_print_str_ln(PDF pdf, const char *s)
+{
+ pdf_print_str(pdf, s);
+ pdf_print_nl(pdf);
+}
+
+@ print out an entry in dictionary with string value to PDF buffer
+@c
+void pdf_str_entry(PDF pdf, const char *s, const char *v)
+{
+ if (v == 0)
+ return;
+ pdf_printf(pdf, "/%s ", s);
+ pdf_print_str(pdf, v);
+}
+
+void pdf_str_entry_ln(PDF pdf, const char *s, const char *v)
+{
+ if (v == 0)
+ return;
+ pdf_str_entry(pdf, s, v);
+ pdf_print_nl(pdf);
+}
+
+@ @c
+void pdf_print_toks(PDF pdf, halfword p)
+{
+ int len = 0;
+ char *s = tokenlist_to_cstring(p, true, &len);
+ if (len > 0)
+ pdf_puts(pdf, s);
+ xfree(s);
+}
+
+void pdf_print_toks_ln(PDF pdf, halfword p)
+{
+ int len = 0;
+ char *s = tokenlist_to_cstring(p, true, &len);
+ if (len > 0) {
+ pdf_puts(pdf, s);
+ pdf_print_nl(pdf);
+ }
+ xfree(s);
+}
+
+@ prints a rect spec
+@c
+void pdf_print_rect_spec(PDF pdf, halfword r)
+{
+ pdf_print_mag_bp(pdf, pdf_ann_left(r));
+ pdf_out(pdf, ' ');
+ pdf_print_mag_bp(pdf, pdf_ann_bottom(r));
+ pdf_out(pdf, ' ');
+ pdf_print_mag_bp(pdf, pdf_ann_right(r));
+ pdf_out(pdf, ' ');
+ pdf_print_mag_bp(pdf, pdf_ann_top(r));
+}
+
+@ output a rectangle specification to PDF file
+@c
+void pdf_rectangle(PDF pdf, halfword r)
+{
+ prepare_mag();
+ pdf_puts(pdf, "/Rect [");
+ pdf_print_rect_spec(pdf, r);
+ pdf_puts(pdf, "]\n");
+}
+
+@ @c
+static void init_pdf_outputparameters(PDF pdf)
+{
+ assert(pdf->o_mode == OMODE_PDF);
+ pdf->draftmode = fix_int(pdf_draftmode, 0, 1);
+ pdf->compress_level = fix_int(pdf_compress_level, 0, 9);
+ pdf->decimal_digits = fix_int(pdf_decimal_digits, 0, 4);
+ pdf->gamma = fix_int(pdf_gamma, 0, 1000000);
+ pdf->image_gamma = fix_int(pdf_image_gamma, 0, 1000000);
+ pdf->image_hicolor = fix_int(pdf_image_hicolor, 0, 1);
+ pdf->image_apply_gamma = fix_int(pdf_image_apply_gamma, 0, 1);
+ pdf->objcompresslevel = fix_int(pdf_objcompresslevel, 0, 3);
+ pdf->inclusion_copy_font = fix_int(pdf_inclusion_copy_font, 0, 1);
+ pdf->replace_font = fix_int(pdf_replace_font, 0, 1);
+ pdf->pk_resolution = fix_int(pdf_pk_resolution, 72, 8000);
+ if ((pdf->minor_version >= 5) && (pdf->objcompresslevel > 0)) {
+ pdf->os_enable = true;
+ } else {
+ if (pdf->objcompresslevel > 0) {
+ pdf_warning("Object streams",
+ "\\pdfobjcompresslevel > 0 requires \\pdfminorversion > 4. Object streams disabled now.",
+ true, true);
+ pdf->objcompresslevel = 0;
+ }
+ pdf->os_enable = false;
+ }
+ if (pdf->pk_resolution == 0) /* if not set from format file or by user */
+ pdf->pk_resolution = pk_dpi; /* take it from \.{texmf.cnf} */
+ pdf->pk_scale_factor =
+ divide_scaled(72, pdf->pk_resolution, 5 + pdf->decimal_digits);
+ if (!callback_defined(read_pk_file_callback)) {
+ if (pdf_pk_mode != null) {
+ char *s = tokenlist_to_cstring(pdf_pk_mode, true, NULL);
+ kpseinitprog("PDFTEX", (unsigned) pdf->pk_resolution, s, nil);
+ xfree(s);
+ } else {
+ kpseinitprog("PDFTEX", (unsigned) pdf->pk_resolution, nil, nil);
+ }
+ if (!kpsevarvalue("MKTEXPK"))
+ kpsesetprogramenabled(kpsepkformat, 1, kpsesrccmdline);
+ }
+ set_job_id(pdf, int_par(year_code),
+ int_par(month_code), int_par(day_code), int_par(time_code));
+ if ((pdf_unique_resname > 0) && (pdf->resname_prefix == NULL))
+ pdf->resname_prefix = get_resname_prefix(pdf);
+}
+
+@ Checks that we have a name for the generated PDF file and that it's open.
+
+@c
+static void ensure_output_file_open(PDF pdf, const char *ext)
+{
+ char *fn;
+ if (pdf->file_name != NULL)
+ return;
+ if (job_name == 0)
+ open_log_file();
+ fn = pack_job_name(ext);
+ if (pdf->draftmode == 0 || pdf->o_mode == OMODE_DVI) {
+ while (!lua_b_open_out(&pdf->file, fn))
+ fn = prompt_file_name("file name for output", ext);
+ }
+ pdf->file_name = fn;
+}
+
+@ @c
+static void ensure_pdf_header_written(PDF pdf)
+{
+ assert(pdf->o_state == ST_FILE_OPEN);
+ assert(pdf->o_mode == OMODE_PDF);
+ /* Initialize variables for \.{PDF} output */
+ fix_pdf_minorversion(pdf);
+ init_pdf_outputparameters(pdf);
+ /* Write \.{PDF} header */
+ pdf_printf(pdf, "%%PDF-1.%d\n", pdf->minor_version);
+ pdf_out(pdf, '%');
+ pdf_out(pdf, 'P' + 128);
+ pdf_out(pdf, 'T' + 128);
+ pdf_out(pdf, 'E' + 128);
+ pdf_out(pdf, 'X' + 128);
+ pdf_print_nl(pdf);
+}
+
+@ @c
+void ensure_output_state(PDF pdf, output_state s)
+{
+ if (pdf->o_state < s) {
+ if (s > ST_INITIAL)
+ ensure_output_state(pdf, s - 1);
+ switch (s - 1) {
+ case ST_INITIAL:
+ fix_o_mode(pdf);
+ break;
+ case ST_OMODE_FIX:
+ switch (pdf->o_mode) {
+ case OMODE_DVI:
+ ensure_output_file_open(pdf, ".dvi");
+ break;
+ case OMODE_PDF:
+ ensure_output_file_open(pdf, ".pdf");
+ break;
+ case OMODE_LUA:
+ break;
+ default:
+ assert(0);
+ }
+ break;
+ case ST_FILE_OPEN:
+ switch (pdf->o_mode) {
+ case OMODE_DVI:
+ ensure_dvi_header_written(pdf);
+ break;
+ case OMODE_PDF:
+ ensure_pdf_header_written(pdf);
+ break;
+ case OMODE_LUA:
+ break;
+ default:
+ assert(0);
+ }
+ break;
+ case ST_HEADER_WRITTEN:
+ break;
+ case ST_FILE_CLOSED:
+ break;
+ default:
+ assert(0);
+ }
+ pdf->o_state++;
+ }
+}
+
+@ begin a PDF dictionary object
+@c
+void pdf_begin_dict(PDF pdf, int i, int pdf_os_level)
+{
+ ensure_output_state(pdf, ST_HEADER_WRITTEN);
+ pdf_os_prepare_obj(pdf, i, pdf_os_level);
+ if (!pdf->os_mode) {
+ pdf_printf(pdf, "%d 0 obj <<\n", (int) i);
+ } else {
+ if (pdf->compress_level == 0)
+ pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */
+ pdf_puts(pdf, "<<\n");
+ }
+}
+
+@ begin a new PDF dictionary object
+@c
+void pdf_new_dict(PDF pdf, int t, int i, int pdf_os)
+{
+ pdf_create_obj(pdf, t, i);
+ pdf_begin_dict(pdf, pdf->obj_ptr, pdf_os);
+}
+
+@ end a PDF dictionary object
+@c
+void pdf_end_dict(PDF pdf)
+{
+ if (pdf->os_mode) {
+ pdf_puts(pdf, ">>\n");
+ if (pdf->os_idx == pdf_os_max_objs - 1)
+ pdf_os_write_objstream(pdf);
+ } else {
+ pdf_puts(pdf, ">> endobj\n");
+ }
+}
+
+@ Write out an accumulated object stream.
+
+First the object number and byte offset pairs are generated
+and appended to the ready buffered object stream.
+By this the value of \.{/First} can be calculated.
+Then a new \.{/ObjStm} object is generated, and everything is
+copied to the PDF output buffer, where also compression is done.
+When calling this procedure, |pdf_os_mode| must be |true|.
+
+@c
+void pdf_os_write_objstream(PDF pdf)
+{
+ halfword i, j, p, q;
+ if (pdf->os_cur_objnum == 0) /* no object stream started */
+ return;
+ p = pdf->ptr;
+ i = 0;
+ j = 0;
+ while (i <= pdf->os_idx) { /* assemble object number and byte offset pairs */
+ pdf_printf(pdf, "%d %d", (int) pdf->os_obj[i].num,
+ (int) pdf->os_obj[i].off);
+ if (j == 9) { /* print out in groups of ten for better readability */
+ pdf_out(pdf, pdf_new_line_char);
+ j = 0;
+ } else {
+ pdf_out(pdf, ' ');
+ j++;
+ }
+ i++;
+ }
+ pdf->buf[pdf->ptr - 1] = pdf_new_line_char; /* no risk of flush, as we are in |pdf_os_mode| */
+ q = pdf->ptr;
+ pdf_begin_dict(pdf, pdf->os_cur_objnum, 0); /* switch to PDF stream writing */
+ pdf_puts(pdf, "/Type /ObjStm\n");
+ pdf_printf(pdf, "/N %d\n", (int) (pdf->os_idx + 1));
+ pdf_printf(pdf, "/First %d\n", (int) (q - p));
+ pdf_begin_stream(pdf);
+ pdf_room(pdf, q - p); /* should always fit into the PDF output buffer */
+ i = p;
+ while (i < q) { /* write object number and byte offset pairs */
+ pdf_quick_out(pdf, pdf->os_buf[i]);
+ i++;
+ }
+ i = 0;
+ while (i < p) {
+ q = i + pdf->buf_size;
+ if (q > p)
+ q = p;
+ pdf_room(pdf, q - i);
+ while (i < q) { /* write the buffered objects */
+ pdf_quick_out(pdf, pdf->os_buf[i]);
+ i++;
+ }
+ }
+ pdf_end_stream(pdf);
+ pdf->os_cur_objnum = 0; /* to force object stream generation next time */
+}
+
+@ begin a PDF object
+@c
+void pdf_begin_obj(PDF pdf, int i, int pdf_os_level)
+{
+ ensure_output_state(pdf, ST_HEADER_WRITTEN);
+ pdf_os_prepare_obj(pdf, i, pdf_os_level);
+ if (!pdf->os_mode) {
+ pdf_printf(pdf, "%d 0 obj\n", (int) i);
+ } else if (pdf->compress_level == 0) {
+ pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */
+ }
+}
+
+@ begin a new PDF object
+@c
+void pdf_new_obj(PDF pdf, int t, int i, int pdf_os)
+{
+ pdf_create_obj(pdf, t, i);
+ pdf_begin_obj(pdf, pdf->obj_ptr, pdf_os);
+}
+
+@ end a PDF object
+@c
+void pdf_end_obj(PDF pdf)
+{
+ if (pdf->os_mode) {
+ if (pdf->os_idx == pdf_os_max_objs - 1)
+ pdf_os_write_objstream(pdf);
+ } else {
+ pdf_puts(pdf, "endobj\n"); /* end a PDF object */
+ }
+}
+
+@ @c
+void write_stream_length(PDF pdf, int length, longinteger offset)
+{
+ if (jobname_cstr == NULL)
+ jobname_cstr = makecstring(job_name);
+ if (pdf->draftmode == 0) {
+ xfseeko(pdf->file, (off_t) offset, SEEK_SET, jobname_cstr);
+ fprintf(pdf->file, "%li", (long int) length);
+ xfseeko(pdf->file, pdf_offset(pdf), SEEK_SET, jobname_cstr);
+ }
+}
+
+@ Converts any string given in in in an allowed PDF string which can be
+ handled by printf et.al.: \.{\\} is escaped to \.{\\\\}, parenthesis are escaped and
+ control characters are octal encoded.
+ This assumes that the string does not contain any already escaped
+ characters!
+
+@c
+char *convertStringToPDFString(const char *in, int len)
+{
+ static char pstrbuf[MAX_PSTRING_LEN];
+ char *out = pstrbuf;
+ int i, j, k;
+ char buf[5];
+ j = 0;
+ for (i = 0; i < len; i++) {
+ check_buf((unsigned) j + sizeof(buf), MAX_PSTRING_LEN);
+ if (((unsigned char) in[i] < '!') || ((unsigned char) in[i] > '~')) {
+ /* convert control characters into oct */
+ k = snprintf(buf, sizeof(buf),
+ "\\%03o", (unsigned int) (unsigned char) in[i]);
+ check_nprintf(k, sizeof(buf));
+ out[j++] = buf[0];
+ out[j++] = buf[1];
+ out[j++] = buf[2];
+ out[j++] = buf[3];
+ } else if ((in[i] == '(') || (in[i] == ')')) {
+ /* escape paranthesis */
+ out[j++] = '\\';
+ out[j++] = in[i];
+ } else if (in[i] == '\\') {
+ /* escape backslash */
+ out[j++] = '\\';
+ out[j++] = '\\';
+ } else {
+ /* copy char :-) */
+ out[j++] = in[i];
+ }
+ }
+ out[j] = '\0';
+ return pstrbuf;
+}
+
+@ Converts any string given in in in an allowed PDF string which is
+ hexadecimal encoded;
+ |sizeof(out)| should be at least $|lin|*2+1$.
+
+@c
+static void convertStringToHexString(const char *in, char *out, int lin)
+{
+ int i, j, k;
+ char buf[3];
+ j = 0;
+ for (i = 0; i < lin; i++) {
+ k = snprintf(buf, sizeof(buf),
+ "%02X", (unsigned int) (unsigned char) in[i]);
+ check_nprintf(k, sizeof(buf));
+ out[j++] = buf[0];
+ out[j++] = buf[1];
+ }
+ out[j] = '\0';
+}
+
+@ Compute the ID string as per PDF1.4 9.3:
+\medskip
+{\obeylines\obeyspaces
+ File identifers are defined by the optional ID entry in a PDF file's
+ trailer dictionary (see Section 3.4.4, "File Trailer"; see also
+ implementation note 105 in Appendix H). The value of this entry is an
+ array of two strings. The first string is a permanent identifier based
+ on the contents of the file at the time it was originally created, and
+ does not change when the file is incrementally updated. The second
+ string is a changing identifier based on the file's contents at the
+ time it was last updated. When a file is first written, both
+ identifiers are set to the same value. If both identifiers match when a
+ file reference is resolved, it is very likely that the correct file has
+ been found; if only the first identifier matches, then a different
+ version of the correct file has been found.
+ To help ensure the uniqueness of file identifiers, it is recommend
+ that they be computed using a message digest algorithm such as MD5
+ (described in Internet RFC 1321, The MD5 Message-Digest Algorithm; see
+ the Bibliography), using the following information (see implementation
+ note 106 in Appendix H):
+ - The current time
+ - A string representation of the file's location, usually a pathname
+ - The size of the file in bytes
+ - The values of all entries in the file's document information
+ dictionary (see Section 9.2.1, Document Information Dictionary )
+}
+\medskip
+ This stipulates only that the two IDs must be identical when the file is
+ created and that they should be reasonably unique. Since it's difficult
+ to get the file size at this point in the execution of pdfTeX and
+ scanning the info dict is also difficult, we start with a simpler
+ implementation using just the first two items.
+
+@c
+void print_ID(PDF pdf, const char *file_name)
+{
+ time_t t;
+ size_t size;
+ char time_str[32];
+ md5_state_t state;
+ md5_byte_t digest[16];
+ char id[64];
+ char pwd[4096];
+ /* start md5 */
+ md5_init(&state);
+ /* get the time */
+ t = time(NULL);
+ size = strftime(time_str, sizeof(time_str), "%Y%m%dT%H%M%SZ", gmtime(&t));
+ md5_append(&state, (const md5_byte_t *) time_str, (int) size);
+ /* get the file name */
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ pdftex_fail("getcwd() failed (%s), (path too long?)", strerror(errno));
+ md5_append(&state, (const md5_byte_t *) pwd, (int) strlen(pwd));
+ md5_append(&state, (const md5_byte_t *) "/", 1);
+ md5_append(&state, (const md5_byte_t *) file_name, (int) strlen(file_name));
+ /* finish md5 */
+ md5_finish(&state, digest);
+ /* write the IDs */
+ convertStringToHexString((char *) digest, id, 16);
+ pdf_printf(pdf, "/ID [<%s> <%s>]", id, id);
+}
+
+@ Print the /CreationDate entry.
+
+ PDF Reference, third edition says about the expected date format:
+\medskip
+{\obeylines\obeyspaces
+ 3.8.2 Dates
+
+ PDF defines a standard date format, which closely follows that of
+ the international standard ASN.1 (Abstract Syntax Notation One),
+ defined in ISO/IEC 8824 (see the Bibliography). A date is a string
+ of the form
+
+ (D:YYYYMMDDHHmmSSOHH'mm')
+
+ where
+
+ YYYY is the year
+ MM is the month
+ DD is the day (01-31)
+ HH is the hour (00-23)
+ mm is the minute (00-59)
+ SS is the second (00-59)
+ O is the relationship of local time to Universal Time (UT),
+ denoted by one of the characters +, -, or Z (see below)
+ HH followed by ' is the absolute value of the offset from UT
+ in hours (00-23)
+ mm followed by ' is the absolute value of the offset from UT
+ in minutes (00-59)
+
+ The apostrophe character (') after HH and mm is part of the syntax.
+ All fields after the year are optional. (The prefix D:, although also
+ optional, is strongly recommended.) The default values for MM and DD
+ are both 01; all other numerical fields default to zero values. A plus
+ sign (+) as the value of the O field signifies that local time is
+ later than UT, a minus sign (-) that local time is earlier than UT,
+ and the letter Z that local time is equal to UT. If no UT information
+ is specified, the relationship of the specified time to UT is
+ considered to be unknown. Whether or not the time zone is known, the
+ rest of the date should be specified in local time.
+
+ For example, December 23, 1998, at 7:52 PM, U.S. Pacific Standard
+ Time, is represented by the string
+
+ D:199812231952-08'00'
+}
+
+ The main difficulty is get the time zone offset. |strftime()| does this in ISO
+ C99 (e.g. newer glibc) with \%z, but we have to work with other systems (e.g.
+ Solaris 2.5).
+
+@c
+#define TIME_STR_SIZE 30 /* minimum size for |time_str| is 24: |"D:YYYYmmddHHMMSS+HH'MM'"| */
+
+static void makepdftime(PDF pdf)
+{
+ struct tm lt, gmt;
+ size_t size;
+ int i, off, off_hours, off_mins;
+ time_t t = pdf->start_time;
+ char *time_str = pdf->start_time_str;
+
+ /* get the time */
+ lt = *localtime(&t);
+ size = strftime(time_str, TIME_STR_SIZE, "D:%Y%m%d%H%M%S", &lt);
+ /* expected format: "YYYYmmddHHMMSS" */
+ if (size == 0) {
+ /* unexpected, contents of |time_str| is undefined */
+ time_str[0] = '\0';
+ return;
+ }
+
+ /* correction for seconds: \%S can be in range 00..61,
+ the PDF reference expects 00..59,
+ therefore we map "60" and "61" to "59" */
+ if (time_str[14] == '6') {
+ time_str[14] = '5';
+ time_str[15] = '9';
+ time_str[16] = '\0'; /* for safety */
+ }
+
+ /* get the time zone offset */
+ gmt = *gmtime(&t);
+
+ /* this calculation method was found in exim's tod.c */
+ off = 60 * (lt.tm_hour - gmt.tm_hour) + lt.tm_min - gmt.tm_min;
+ if (lt.tm_year != gmt.tm_year) {
+ off += (lt.tm_year > gmt.tm_year) ? 1440 : -1440;
+ } else if (lt.tm_yday != gmt.tm_yday) {
+ off += (lt.tm_yday > gmt.tm_yday) ? 1440 : -1440;
+ }
+
+ if (off == 0) {
+ time_str[size++] = 'Z';
+ time_str[size] = 0;
+ } else {
+ off_hours = off / 60;
+ off_mins = abs(off - off_hours * 60);
+ i = snprintf(&time_str[size], 9, "%+03d'%02d'", off_hours, off_mins);
+ check_nprintf(i, 9);
+ }
+ pdf->start_time = t;
+}
+
+@ @c
+void init_start_time(PDF pdf)
+{
+ assert(pdf);
+ if (pdf->start_time == 0) {
+ pdf->start_time = time((time_t *) NULL);
+ pdf->start_time_str = xtalloc(TIME_STR_SIZE, char);
+ makepdftime(pdf);
+ }
+}
+
+@ @c
+void print_creation_date(PDF pdf)
+{
+ init_start_time(pdf);
+ pdf_printf(pdf, "/CreationDate (%s)\n", pdf->start_time_str);
+}
+
+@ @c
+void print_mod_date(PDF pdf)
+{
+ init_start_time(pdf);
+ pdf_printf(pdf, "/ModDate (%s)\n", pdf->start_time_str);
+}
+
+@ @c
+char *getcreationdate(PDF pdf)
+{
+ assert(pdf);
+ init_start_time(pdf);
+ return pdf->start_time_str;
+}
+
+@ @c
+void remove_pdffile(PDF pdf)
+{
+ if (pdf != NULL) {
+ if (!kpathsea_debug && pdf->file_name && (pdf->draftmode != 0)) {
+ xfclose(pdf->file, pdf->file_name);
+ remove(pdf->file_name);
+ }
+ }
+}
+
+@ @c
+static void realloc_fb(PDF pdf)
+{
+ if (pdf->fb_array == NULL) {
+ pdf->fb_limit = SMALL_ARRAY_SIZE;
+ pdf->fb_array = xtalloc(pdf->fb_limit, char);
+ pdf->fb_ptr = pdf->fb_array;
+ } else if ((size_t) (pdf->fb_ptr - pdf->fb_array + 1) > pdf->fb_limit) {
+ size_t last_ptr_index = (size_t) (pdf->fb_ptr - pdf->fb_array);
+ pdf->fb_limit *= 2;
+ if ((size_t) (pdf->fb_ptr - pdf->fb_array + 1) > pdf->fb_limit)
+ pdf->fb_limit = (size_t) (pdf->fb_ptr - pdf->fb_array + 1);
+ xretalloc(pdf->fb_array, pdf->fb_limit, char);
+ pdf->fb_ptr = pdf->fb_array + last_ptr_index;
+ }
+}
+
+@ @c
+int fb_offset(PDF pdf)
+{
+ return (int) (pdf->fb_ptr - pdf->fb_array);
+}
+
+@ @c
+void fb_seek(PDF pdf, int offset)
+{
+ pdf->fb_ptr = pdf->fb_array + offset;
+}
+
+@ @c
+void fb_putchar(PDF pdf, eight_bits b)
+{
+ if ((size_t) (pdf->fb_ptr - pdf->fb_array + 1) > pdf->fb_limit)
+ realloc_fb(pdf);
+ *(pdf->fb_ptr)++ = (char) b;
+}
+
+@ @c
+void fb_flush(PDF pdf)
+{
+ char *p;
+ int n;
+ for (p = pdf->fb_array; p < pdf->fb_ptr;) {
+ n = pdf->buf_size - pdf->ptr;
+ if (pdf->fb_ptr - p < n)
+ n = (int) (pdf->fb_ptr - p);
+ memcpy(pdf->buf + pdf->ptr, p, (unsigned) n);
+ pdf->ptr += n;
+ if (pdf->ptr == pdf->buf_size)
+ pdf_flush(pdf);
+ p += n;
+ }
+ pdf->fb_ptr = pdf->fb_array;
+}
+
+@ @c
+void fb_free(PDF pdf)
+{
+ xfree(pdf->fb_array);
+}
+
+@ @c
+#define ZIP_BUF_SIZE 32768
+
+#define check_err(f, fn) \
+ if (f != Z_OK) \
+ pdftex_fail("zlib: %s() failed (error code %d)", fn, f)
+
+@ @c
+void write_zip(PDF pdf, boolean finish)
+{
+ int err;
+ int level = pdf->compress_level;
+ assert(level > 0);
+ /* This was just to suppress the filename report in |pdftex_fail|
+ but zlib errors are rare enough (especially now that the
+ compress level is fixed) that I don't care about the slightly
+ ugly error message that could result.
+ */
+#if 0
+ cur_file_name = NULL;
+#endif
+ if (pdf->stream_length == 0) {
+ if (pdf->zipbuf == NULL) {
+ pdf->zipbuf = xtalloc(ZIP_BUF_SIZE, char);
+ pdf->c_stream.zalloc = (alloc_func) 0;
+ pdf->c_stream.zfree = (free_func) 0;
+ pdf->c_stream.opaque = (voidpf) 0;
+ check_err(deflateInit(&pdf->c_stream, level), "deflateInit");
+ } else {
+ check_err(deflateReset(&pdf->c_stream), "deflateReset");
+ }
+ pdf->c_stream.next_out = (Bytef *) pdf->zipbuf;
+ pdf->c_stream.avail_out = ZIP_BUF_SIZE;
+ }
+ assert(pdf->zipbuf != NULL);
+ pdf->c_stream.next_in = pdf->buf;
+ pdf->c_stream.avail_in = (uInt) pdf->ptr;
+ for (;;) {
+ if (pdf->c_stream.avail_out == 0) {
+ pdf->gone =
+ pdf->gone + (off_t) xfwrite(pdf->zipbuf, 1, ZIP_BUF_SIZE,
+ pdf->file);
+ pdf->last_byte = pdf->zipbuf[ZIP_BUF_SIZE - 1]; /* not needed */
+ pdf->c_stream.next_out = (Bytef *) pdf->zipbuf;
+ pdf->c_stream.avail_out = ZIP_BUF_SIZE;
+ }
+ err = deflate(&pdf->c_stream, finish ? Z_FINISH : Z_NO_FLUSH);
+ if (finish && err == Z_STREAM_END)
+ break;
+ check_err(err, "deflate");
+ if (!finish && pdf->c_stream.avail_in == 0)
+ break;
+ }
+ if (finish) {
+ if (pdf->c_stream.avail_out < ZIP_BUF_SIZE) { /* at least one byte has been output */
+ pdf->gone = pdf->gone +
+ (off_t) xfwrite(pdf->zipbuf, 1,
+ (size_t) (ZIP_BUF_SIZE -
+ pdf->c_stream.avail_out), pdf->file);
+ pdf->last_byte =
+ pdf->zipbuf[ZIP_BUF_SIZE - pdf->c_stream.avail_out - 1];
+ }
+ xfflush(pdf->file);
+ }
+ pdf->stream_length = (off_t) pdf->c_stream.total_out;
+}
+
+@ @c
+void zip_free(PDF pdf)
+{
+ if (pdf->zipbuf != NULL) {
+ check_err(deflateEnd(&pdf->c_stream), "deflateEnd");
+ free(pdf->zipbuf);
+ }
+}
+
+@ @c
+void pdf_error(const char *t, const char *p)
+{
+ normalize_selector();
+ print_err("LuaTeX error");
+ if (t != NULL) {
+ tprint(" (");
+ tprint(t);
+ tprint(")");
+ }
+ tprint(": ");
+ if (p != NULL)
+ tprint(p);
+ succumb();
+}
+
+@ @c
+void pdf_warning(const char *t, const char *p, boolean prepend_nl,
+ boolean append_nl)
+{
+ if (prepend_nl)
+ print_ln();
+ tprint("LuaTeX warning");
+ if (t != NULL) {
+ tprint(" (");
+ tprint(t);
+ tprint(")");
+ }
+ tprint(": ");
+ if (p != NULL)
+ tprint(p);
+ if (append_nl)
+ print_ln();
+ if (history == spotless)
+ history = warning_issued;
+}
+
+@ Use |check_o_mode()| in the backend-specific "Implement..." chunks
+
+@c
+void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict)
+{
+
+ char warn_string[100];
+ output_mode o_mode;
+ const char *m = NULL;
+
+ /* in warn mode (strict == false):
+ only check, don't do |fix_o_mode()| here! |pdf->o_mode| is left
+ in possibly wrong state until real output, ok.
+ */
+
+ if (pdf->o_mode == OMODE_NONE) {
+ if (pdf_output > 0) {
+ if (pdf_output == 2009)
+ o_mode = OMODE_LUA;
+ else
+ o_mode = OMODE_PDF;
+ } else
+ o_mode = OMODE_DVI;
+ } else
+ o_mode = pdf->o_mode;
+ if (!((1 << o_mode) & o_mode_bitpattern)) { /* warning or error */
+ switch (o_mode) {
+ case OMODE_DVI:
+ m = "DVI";
+ break;
+ case OMODE_PDF:
+ m = "PDF";
+ break;
+ case OMODE_LUA:
+ m = "Lua";
+ break;
+ default:
+ assert(0);
+ }
+ snprintf(warn_string, 99, "not allowed in %s mode (\\pdfpoutput = %d)",
+ m, (int) pdf_output);
+ if (strict)
+ pdf_error(s, warn_string);
+ else
+ pdf_warning(s, warn_string, true, true);
+ } else if (strict)
+ ensure_output_state(pdf, ST_HEADER_WRITTEN);
+}
+
+@ @c
+void set_job_id(PDF pdf, int year, int month, int day, int time)
+{
+ char *name_string, *format_string, *s;
+ size_t slen;
+ int i;
+
+ if (pdf->job_id_string != NULL)
+ return;
+
+ name_string = makecstring(job_name);
+ format_string = makecstring(format_ident);
+ make_pdftex_banner();
+ slen = SMALL_BUF_SIZE +
+ strlen(name_string) + strlen(format_string) + strlen(pdftex_banner);
+ s = xtalloc(slen, char);
+ /* The Web2c version string starts with a space. */
+ i = snprintf(s, slen,
+ "%.4d/%.2d/%.2d %.2d:%.2d %s %s %s",
+ year, month, day, time / 60, time % 60,
+ name_string, format_string, pdftex_banner);
+ check_nprintf(i, slen);
+ pdf->job_id_string = xstrdup(s);
+ xfree(s);
+ xfree(name_string);
+ xfree(format_string);
+}
+
+@ @c
+char *get_resname_prefix(PDF pdf)
+{
+ static char name_str[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ static char prefix[7]; /* make a tag of 6 chars long */
+ unsigned long crc;
+ short i;
+ size_t base = strlen(name_str);
+ crc = crc32(0L, Z_NULL, 0);
+ crc =
+ crc32(crc, (Bytef *) pdf->job_id_string,
+ (uInt) strlen(pdf->job_id_string));
+ for (i = 0; i < 6; i++) {
+ prefix[i] = name_str[crc % base];
+ crc /= base;
+ }
+ prefix[6] = '\0';
+ return prefix;
+}
+
+@ @c
+#define mag int_par(mag_code)
+
+#define pdf_xform_attr equiv(pdf_xform_attr_loc)
+#define pdf_xform_resources equiv(pdf_xform_resources_loc)
+
+void pdf_begin_page(PDF pdf, boolean shipping_page)
+{
+ scaled form_margin = one_bp;
+ ensure_output_state(pdf, ST_HEADER_WRITTEN);
+ init_pdf_pagecalculations(pdf);
+
+ if (pdf->page_resources == NULL) {
+ pdf->page_resources = xmalloc(sizeof(pdf_resource_struct));
+ pdf->page_resources->resources_tree = NULL;
+ }
+ pdf->page_resources->last_resources = pdf_new_objnum(pdf);
+ reset_page_resources(pdf);
+
+ if (shipping_page) {
+ pdf->last_page = get_obj(pdf, obj_type_page, total_pages + 1, 0);
+ set_obj_aux(pdf, pdf->last_page, 1); /* mark that this page has been created */
+ pdf_new_dict(pdf, obj_type_pagestream, 0, 0);
+ pdf->last_stream = pdf->obj_ptr;
+ pdf->last_thread = null;
+ } else {
+ pdf_begin_dict(pdf, pdf_cur_form, 0);
+ pdf->last_stream = pdf_cur_form;
+
+ /* Write out Form stream header */
+ pdf_puts(pdf, "/Type /XObject\n");
+ pdf_puts(pdf, "/Subtype /Form\n");
+ if (pdf_xform_attr != null)
+ pdf_print_toks_ln(pdf, pdf_xform_attr);
+ if (obj_xform_attr(pdf, pdf_cur_form) != null) {
+ pdf_print_toks_ln(pdf, obj_xform_attr(pdf, pdf_cur_form));
+ delete_token_ref(obj_xform_attr(pdf, pdf_cur_form));
+ set_obj_xform_attr(pdf, pdf_cur_form, null);
+ }
+ pdf_puts(pdf, "/BBox [");
+ pdf_print_bp(pdf, -form_margin);
+ pdf_out(pdf, ' ');
+ pdf_print_bp(pdf, -form_margin);
+ pdf_out(pdf, ' ');
+ pdf_print_bp(pdf, cur_page_size.h + form_margin);
+ pdf_out(pdf, ' ');
+ pdf_print_bp(pdf, cur_page_size.v + form_margin);
+ pdf_puts(pdf, "]\n");
+ pdf_puts(pdf, "/FormType 1\n");
+ pdf_puts(pdf, "/Matrix [1 0 0 1 0 0]\n");
+ pdf_indirect_ln(pdf, "Resources", pdf->page_resources->last_resources);
+ }
+ /* Start stream of page/form contents */
+ pdf_begin_stream(pdf);
+ if (shipping_page) {
+ /* Adjust transformation matrix for the magnification ratio */
+ if (mag != 1000) {
+ pdf_print_real(pdf, mag, 3);
+ pdf_puts(pdf, " 0 0 ");
+ pdf_print_real(pdf, mag, 3);
+ pdf_puts(pdf, " 0 0 cm\n");
+ }
+ }
+ pdf_shipout_begin(shipping_page);
+
+ if (shipping_page)
+ pdf_out_colorstack_startpage(pdf);
+}
+
+@ @c
+#define pdf_page_attr equiv(pdf_page_attr_loc)
+#define pdf_page_resources equiv(pdf_page_resources_loc)
+
+void pdf_end_page(PDF pdf, boolean shipping_page)
+{
+ int j;
+ pdf_resource_struct *res_p = pdf->page_resources;
+ pdf_resource_struct local_page_resources;
+ pdf_object_list *ol, *ol1;
+ scaledpos save_cur_page_size; /* to save |cur_page_size| during flushing pending forms */
+ int procset = PROCSET_PDF;
+
+ /* Finish stream of page/form contents */
+ pdf_goto_pagemode(pdf);
+ pdf_shipout_end(shipping_page);
+ pdf_end_stream(pdf);
+
+ if (shipping_page) {
+ /* Write out page object */
+
+ pdf_begin_dict(pdf, pdf->last_page, 1);
+ pdf->last_pages = pdf_do_page_divert(pdf, pdf->last_page, 0);
+ pdf_puts(pdf, "/Type /Page\n");
+ pdf_indirect_ln(pdf, "Contents", pdf->last_stream);
+ pdf_indirect_ln(pdf, "Resources", res_p->last_resources);
+ pdf_puts(pdf, "/MediaBox [0 0 ");
+ pdf_print_mag_bp(pdf, cur_page_size.h);
+ pdf_out(pdf, ' ');
+ pdf_print_mag_bp(pdf, cur_page_size.v);
+ pdf_puts(pdf, "]\n");
+ if (pdf_page_attr != null)
+ pdf_print_toks_ln(pdf, pdf_page_attr);
+ if (pdf_pageattributes_toks != null) /* from Lua */
+ pdf_print_toks_ln(pdf, pdf_pageattributes_toks);
+ pdf_indirect_ln(pdf, "Parent", pdf->last_pages);
+ if (pdf->img_page_group_val > 0) {
+ pdf_printf(pdf, "/Group %d 0 R\n", pdf->img_page_group_val);
+ pdf->img_page_group_val = 0;
+ }
+ /* Generate array of annotations or beads in page */
+ ol = get_page_resources_list(pdf, obj_type_annot);
+ ol1 = get_page_resources_list(pdf, obj_type_link);
+ if (ol != NULL || ol1 != NULL) {
+ pdf_puts(pdf, "/Annots [ ");
+ while (ol != NULL) {
+ assert(ol->info > 0);
+ pdf_print_int(pdf, ol->info);
+ pdf_puts(pdf, " 0 R ");
+ ol = ol->link;
+ }
+ while (ol1 != NULL) {
+ pdf_print_int(pdf, ol1->info);
+ pdf_puts(pdf, " 0 R ");
+ ol1 = ol1->link;
+ }
+ pdf_puts(pdf, "]\n");
+ }
+ print_beads_list(pdf);
+ pdf_end_dict(pdf);
+ }
+
+ /* Write out resource lists */
+ /* Write out pending raw objects */
+ ol = get_page_resources_list(pdf, obj_type_obj);
+ while (ol != NULL) {
+ if (!is_obj_written(pdf, ol->info))
+ pdf_write_obj(pdf, ol->info);
+ ol = ol->link;
+ }
+
+ /* Write out pending forms */
+ /* When flushing pending forms we need to save and restore resource lists
+ which are also used by page shipping.
+ Saving and restoring |cur_page_size| is needed for proper
+ writing out pending PDF marks. */
+ ol = get_page_resources_list(pdf, obj_type_xform);
+ while (ol != NULL) {
+ if (!is_obj_written(pdf, ol->info)) {
+ pdf_cur_form = ol->info;
+ save_cur_page_size = cur_page_size;
+ pdf->page_resources = &local_page_resources;
+ local_page_resources.resources_tree = NULL;
+ ship_out(pdf, obj_xform_box(pdf, pdf_cur_form), false);
+ /* Restore page size and page resources */
+ cur_page_size = save_cur_page_size;
+ destroy_page_resources_tree(pdf);
+ pdf->page_resources = res_p;
+ }
+ ol = ol->link;
+ }
+
+ /* Write out pending images */
+ ol = get_page_resources_list(pdf, obj_type_ximage);
+ while (ol != NULL) {
+ if (!is_obj_written(pdf, ol->info))
+ pdf_write_image(pdf, ol->info);
+ ol = ol->link;
+ }
+
+ if (shipping_page) {
+ /* Write out pending PDF marks */
+ /* Write out PDF annotations */
+ ol = get_page_resources_list(pdf, obj_type_annot);
+ while (ol != NULL) {
+ if (ol->info > 0) {
+ j = obj_annot_ptr(pdf, ol->info); /* |j| points to |pdf_annot_node| */
+ pdf_begin_dict(pdf, ol->info, 1);
+ pdf_puts(pdf, "/Type /Annot\n");
+ pdf_print_toks_ln(pdf, pdf_annot_data(j));
+ pdf_rectangle(pdf, j);
+ pdf_end_dict(pdf);
+ }
+ ol = ol->link;
+ }
+
+ /* Write out PDF link annotations */
+ if ((ol = get_page_resources_list(pdf, obj_type_link)) != NULL) {
+ while (ol != NULL) {
+ j = obj_annot_ptr(pdf, ol->info);
+ pdf_begin_dict(pdf, ol->info, 1);
+ pdf_puts(pdf, "/Type /Annot\n");
+ if (pdf_action_type(pdf_link_action(j)) != pdf_action_user)
+ pdf_puts(pdf, "/Subtype /Link\n");
+ if (pdf_link_attr(j) != null)
+ pdf_print_toks_ln(pdf, pdf_link_attr(j));
+ pdf_rectangle(pdf, j);
+ if (pdf_action_type(pdf_link_action(j)) != pdf_action_user)
+ pdf_puts(pdf, "/A ");
+ write_action(pdf, pdf_link_action(j));
+ pdf_end_dict(pdf);
+ ol = ol->link;
+ }
+ /* Flush |pdf_start_link_node|'s created by |append_link| */
+ ol = get_page_resources_list(pdf, obj_type_link);
+ while (ol != NULL) {
+ j = obj_annot_ptr(pdf, ol->info);
+ /* nodes with |subtype = pdf_link_data_node| were created by |append_link| and
+ must be flushed here, as they are not linked in any list */
+ if (subtype(j) == pdf_link_data_node)
+ flush_node(j);
+ ol = ol->link;
+ }
+ }
+
+ /* Write out PDF mark destinations */
+ write_out_pdf_mark_destinations(pdf);
+ /* Write out PDF bead rectangle specifications */
+ print_bead_rectangles(pdf);
+
+ }
+ /* Write out resources dictionary */
+ pdf_begin_dict(pdf, res_p->last_resources, 1);
+ /* Print additional resources */
+ if (shipping_page) {
+ if (pdf_page_resources != null)
+ pdf_print_toks_ln(pdf, pdf_page_resources);
+ if (pdf_pageresources_toks != null) /* from Lua */
+ pdf_print_toks_ln(pdf, pdf_pageresources_toks);
+ } else {
+ if (pdf_xform_resources != null)
+ pdf_print_toks_ln(pdf, pdf_xform_resources);
+ if (obj_xform_resources(pdf, pdf_cur_form) != null) {
+ pdf_print_toks_ln(pdf, obj_xform_resources(pdf, pdf_cur_form));
+ delete_token_ref(obj_xform_resources(pdf, pdf_cur_form));
+ set_obj_xform_resources(pdf, pdf_cur_form, null);
+ }
+ }
+
+ /* Generate font resources */
+ if ((ol = get_page_resources_list(pdf, obj_type_font)) != NULL) {
+ pdf_puts(pdf, "/Font << ");
+ while (ol != NULL) {
+ assert(pdf_font_num(ol->info) > 0); /* always base font: an object number */
+ pdf_puts(pdf, "/F");
+ pdf_print_int(pdf, ol->info);
+ pdf_print_resname_prefix(pdf);
+ pdf_out(pdf, ' ');
+ pdf_print_int(pdf, pdf_font_num(ol->info));
+ pdf_puts(pdf, " 0 R ");
+ ol = ol->link;
+ }
+ pdf_puts(pdf, ">>\n");
+ procset |= PROCSET_TEXT;
+ }
+
+ /* Generate XObject resources */
+ ol = get_page_resources_list(pdf, obj_type_xform);
+ ol1 = get_page_resources_list(pdf, obj_type_ximage);
+ if (ol != NULL || ol1 != NULL) {
+ pdf_puts(pdf, "/XObject << ");
+ while (ol != NULL) {
+ pdf_printf(pdf, "/Fm");
+ pdf_print_int(pdf, obj_info(pdf, ol->info));
+ pdf_print_resname_prefix(pdf);
+ pdf_out(pdf, ' ');
+ pdf_print_int(pdf, ol->info);
+ pdf_puts(pdf, " 0 R ");
+ ol = ol->link;
+ }
+ while (ol1 != null) {
+ pdf_puts(pdf, "/Im");
+ pdf_print_int(pdf, obj_data_ptr(pdf, ol1->info));
+ pdf_print_resname_prefix(pdf);
+ pdf_out(pdf, ' ');
+ pdf_print_int(pdf, ol1->info);
+ pdf_puts(pdf, " 0 R ");
+ procset |= img_procset(idict_array[obj_data_ptr(pdf, ol1->info)]);
+ ol1 = ol1->link;
+ }
+ pdf_puts(pdf, ">>\n");
+ }
+
+ /* Generate ProcSet */
+ pdf_puts(pdf, "/ProcSet [");
+ if ((procset & PROCSET_PDF) != 0)
+ pdf_puts(pdf, " /PDF");
+ if ((procset & PROCSET_TEXT) != 0)
+ pdf_puts(pdf, " /Text");
+ if ((procset & PROCSET_IMAGE_B) != 0)
+ pdf_puts(pdf, " /ImageB");
+ if ((procset & PROCSET_IMAGE_C) != 0)
+ pdf_puts(pdf, " /ImageC");
+ if ((procset & PROCSET_IMAGE_I) != 0)
+ pdf_puts(pdf, " /ImageI");
+ pdf_puts(pdf, " ]\n");
+
+ pdf_end_dict(pdf);
+}
+
+@* Finishing the PDF output file.
+
+@ @c
+#define pdf_gen_tounicode int_par(pdf_gen_tounicode_code)
+
+@ Destinations that have been referenced but don't exists have
+|obj_dest_ptr=null|. Leaving them undefined might cause troubles for
+PDF browsers, so we need to fix them; they point to the last page.
+
+@c
+static void check_nonexisting_destinations(PDF pdf)
+{
+ int k;
+ for (k = pdf->head_tab[obj_type_dest]; k != 0; k = obj_link(pdf, k)) {
+ if (obj_dest_ptr(pdf, k) == null) {
+ pdf_warning("dest", NULL, false, false);
+ if (obj_info(pdf, k) < 0) {
+ tprint("name{");
+ print(-obj_info(pdf, k));
+ tprint("}");
+ } else {
+ tprint("num");
+ print_int(obj_info(pdf, k));
+ }
+ tprint
+ (" has been referenced but does not exist, replaced by a fixed one");
+ print_ln();
+ print_ln();
+ pdf_begin_obj(pdf, k, 1);
+ pdf_out(pdf, '[');
+ pdf_print_int(pdf, pdf->last_page);
+ pdf_puts(pdf, " 0 R /Fit]\n");
+ pdf_end_obj(pdf);
+ }
+ }
+}
+
+@ @c
+static void check_nonexisting_pages(PDF pdf)
+{
+ struct avl_traverser t;
+ oentry *p;
+ struct avl_table *page_tree = pdf->obj_tree[obj_type_page];
+ avl_t_init(&t, page_tree);
+ /* search from the end backward until the last real page is found */
+ for (p = avl_t_last(&t, page_tree);
+ p != NULL && obj_aux(pdf, p->objptr) == 0; p = avl_t_prev(&t)) {
+ pdf_warning("dest", "Page ", false, false);
+ print_int(obj_info(pdf, p->objptr));
+ tprint(" has been referenced but does not exist!");
+ print_ln();
+ print_ln();
+ }
+}
+
+@ If the same keys in a dictionary are given several times, then it is not
+defined which value is choosen by an application. Therefore the keys
+|/Producer| and |/Creator| are only set if the token list
+|pdf_info_toks| converted to a string does not contain these key strings.
+
+@c
+static boolean substr_of_str(const char *s, const char *t)
+{
+ if (strstr(t, s) == NULL)
+ return false;
+ return true;
+}
+
+void pdf_print_info(PDF pdf, int luatex_version, str_number luatex_revision)
+{ /* print info object */
+ boolean creator_given, producer_given, creationdate_given, moddate_given,
+ trapped_given;
+ char *s = NULL;
+ int len = 0;
+ pdf_new_dict(pdf, obj_type_others, 0, 3); /* keep Info readable unless explicitely forced */
+ creator_given = false;
+ producer_given = false;
+ creationdate_given = false;
+ moddate_given = false;
+ trapped_given = false;
+ if (pdf_info_toks != 0) {
+ s = tokenlist_to_cstring(pdf_info_toks, true, &len);
+ creator_given = substr_of_str("/Creator", s);
+ producer_given = substr_of_str("/Producer", s);
+ creationdate_given = substr_of_str("/CreationDate", s);
+ moddate_given = substr_of_str("/ModDate", s);
+ trapped_given = substr_of_str("/Trapped", s);
+ }
+ if (!producer_given) {
+ /* Print the Producer key */
+ pdf_puts(pdf, "/Producer (LuaTeX-");
+ pdf_print_int(pdf, luatex_version / 100);
+ pdf_out(pdf, '.');
+ pdf_print_int(pdf, luatex_version % 100);
+ pdf_out(pdf, '.');
+ pdf_print(pdf, luatex_revision);
+ pdf_puts(pdf, ")\n");
+
+ }
+ if (pdf_info_toks != null) {
+ if (len > 0) {
+ pdf_puts(pdf, s);
+ pdf_print_nl(pdf);
+ xfree(s);
+ }
+ delete_token_ref(pdf_info_toks);
+ pdf_info_toks = null;
+ }
+ if (!creator_given)
+ pdf_str_entry_ln(pdf, "Creator", "TeX");
+ if (!creationdate_given) {
+ print_creation_date(pdf);
+ }
+ if (!moddate_given) {
+ print_mod_date(pdf);
+ }
+ if (!trapped_given) {
+ pdf_puts(pdf, "/Trapped /False\n");
+ }
+ pdf_str_entry_ln(pdf, "PTEX.Fullbanner", pdftex_banner);
+ pdf_end_dict(pdf);
+}
+
+void build_free_object_list(PDF pdf)
+{
+ int k, l;
+ l = 0;
+ set_obj_fresh(pdf, l); /* null object at begin of list of free objects */
+ for (k = 1; k <= pdf->sys_obj_ptr; k++) {
+ if (!is_obj_written(pdf, k)) {
+ set_obj_link(pdf, l, k);
+ l = k;
+ }
+ }
+ set_obj_link(pdf, l, 0);
+}
+
+@ Now the finish of PDF output file. At this moment all Page objects
+are already written completely to PDF output file.
+
+@c
+void finish_pdf_file(PDF pdf, int luatex_version, str_number luatex_revision)
+{
+ boolean res;
+ int i, j, k;
+ int root, outlines, threads, names_tree;
+ int xref_offset_width;
+ int callback_id = callback_defined(stop_run_callback);
+
+ if (total_pages == 0) {
+ if (callback_id == 0) {
+ tprint_nl("No pages of output.");
+ } else if (callback_id > 0) {
+ res = run_callback(callback_id, "->");
+ }
+ if (pdf->gone > 0)
+ garbage_warning();
+ } else {
+ if (pdf->draftmode == 0) {
+ pdf_flush(pdf); /* to make sure that the output file name has been already created */
+ flush_jbig2_page0_objects(pdf); /* flush page 0 objects from JBIG2 images, if any */
+
+ check_nonexisting_pages(pdf);
+ check_nonexisting_destinations(pdf);
+
+ /* Output fonts definition */
+ for (k = 1; k <= max_font_id(); k++) {
+ if (font_used(k) && (pdf_font_num(k) < 0)) {
+ i = -pdf_font_num(k);
+ assert(pdf_font_num(i) > 0);
+ for (j = font_bc(k); j <= font_ec(k); j++)
+ if (quick_char_exists(k, j) && pdf_char_marked(k, j))
+ pdf_mark_char(i, j);
+ if ((pdf_font_attr(i) == 0) && (pdf_font_attr(k) != 0)) {
+ set_pdf_font_attr(i, pdf_font_attr(k));
+ } else if ((pdf_font_attr(k) == 0)
+ && (pdf_font_attr(i) != 0)) {
+ set_pdf_font_attr(k, pdf_font_attr(i));
+ } else if ((pdf_font_attr(i) != 0)
+ && (pdf_font_attr(k) != 0)
+ &&
+ (!str_eq_str
+ (pdf_font_attr(i), pdf_font_attr(k)))) {
+ pdf_warning("\\pdffontattr", "fonts ", false, false);
+ print_font_identifier(i);
+ tprint(" and ");
+ print_font_identifier(k);
+ tprint
+ (" have conflicting attributes; I will ignore the attributes assigned to ");
+ print_font_identifier(i);
+ print_ln();
+ print_ln();
+ }
+ }
+ }
+ pdf->gen_tounicode = pdf_gen_tounicode;
+ k = pdf->head_tab[obj_type_font];
+ while (k != 0) {
+ f = obj_info(pdf, k);
+ assert(pdf_font_num(f) > 0);
+ assert(pdf_font_num(f) == k);
+ do_pdf_font(pdf, f);
+ k = obj_link(pdf, k);
+ }
+ write_fontstuff(pdf);
+
+ pdf->last_pages = output_pages_tree(pdf);
+ /* Output outlines */
+ outlines = print_outlines(pdf);
+
+ /* Output name tree */
+ /* 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
+ the first name and |obj_link| will be the last name in \.{\\Limits} array.
+ Note that |pdf_dest_names_ptr| will be less than |obj_ptr|, so we test if
+ |k < pdf_dest_names_ptr| then |k| is index of leaf in |dest_names|; else
+ |k| will be index in |obj_tab| of some intermediate node.
+ */
+ names_tree = output_name_tree(pdf);
+
+ /* Output article threads */
+ if (pdf->head_tab[obj_type_thread] != 0) {
+ pdf_new_obj(pdf, obj_type_others, 0, 1);
+ threads = pdf->obj_ptr;
+ pdf_out(pdf, '[');
+ k = pdf->head_tab[obj_type_thread];
+ while (k != 0) {
+ pdf_print_int(pdf, k);
+ pdf_puts(pdf, " 0 R ");
+ k = obj_link(pdf, k);
+ }
+ pdf_remove_last_space(pdf);
+ pdf_puts(pdf, "]\n");
+ pdf_end_obj(pdf);
+ k = pdf->head_tab[obj_type_thread];
+ while (k != 0) {
+ out_thread(pdf, k);
+ k = obj_link(pdf, k);
+ }
+ } else {
+ threads = 0;
+ }
+
+ /* Output the catalog object */
+ pdf_new_dict(pdf, obj_type_others, 0, 1);
+ root = pdf->obj_ptr;
+ pdf_puts(pdf, "/Type /Catalog\n");
+ pdf_indirect_ln(pdf, "Pages", pdf->last_pages);
+ if (threads != 0)
+ pdf_indirect_ln(pdf, "Threads", threads);
+ if (outlines != 0)
+ pdf_indirect_ln(pdf, "Outlines", outlines);
+ if (names_tree != 0)
+ pdf_indirect_ln(pdf, "Names", names_tree);
+ if (pdf_catalog_toks != null) {
+ pdf_print_toks_ln(pdf, pdf_catalog_toks);
+ delete_token_ref(pdf_catalog_toks);
+ pdf_catalog_toks = null;
+ }
+ if (pdf_catalog_openaction != 0)
+ pdf_indirect_ln(pdf, "OpenAction", pdf_catalog_openaction);
+ pdf_end_dict(pdf);
+
+ pdf_print_info(pdf, luatex_version, luatex_revision); /* last candidate for object stream */
+
+ if (pdf->os_enable) {
+ pdf_os_switch(pdf, true);
+ pdf_os_write_objstream(pdf);
+ pdf_flush(pdf);
+ pdf_os_switch(pdf, false);
+ /* Output the cross-reference stream dictionary */
+ pdf_new_dict(pdf, obj_type_others, 0, 0);
+ if ((obj_offset(pdf, pdf->sys_obj_ptr) / 256) > 16777215)
+ xref_offset_width = 5;
+ else if (obj_offset(pdf, pdf->sys_obj_ptr) > 16777215)
+ xref_offset_width = 4;
+ else if (obj_offset(pdf, pdf->sys_obj_ptr) > 65535)
+ xref_offset_width = 3;
+ else
+ xref_offset_width = 2;
+ /* Build a linked list of free objects */
+ build_free_object_list(pdf);
+ pdf_puts(pdf, "/Type /XRef\n");
+ pdf_puts(pdf, "/Index [0 ");
+ pdf_print_int(pdf, pdf->obj_ptr + 1);
+ pdf_puts(pdf, "]\n");
+ pdf_int_entry_ln(pdf, "Size", pdf->obj_ptr + 1);
+ pdf_puts(pdf, "/W [1 ");
+ pdf_print_int(pdf, xref_offset_width);
+ pdf_puts(pdf, " 1]\n");
+ pdf_indirect_ln(pdf, "Root", root);
+ pdf_indirect_ln(pdf, "Info", pdf->obj_ptr - 1);
+ if (pdf_trailer_toks != null) {
+ pdf_print_toks_ln(pdf, pdf_trailer_toks);
+ delete_token_ref(pdf_trailer_toks);
+ pdf_trailer_toks = null;
+ }
+ print_ID(pdf, pdf->file_name);
+ pdf_print_nl(pdf);
+ pdf_begin_stream(pdf);
+ for (k = 0; k <= pdf->sys_obj_ptr; k++) {
+ if (!is_obj_written(pdf, k)) { /* a free object */
+ pdf_out(pdf, 0);
+ pdf_out_bytes(pdf, obj_link(pdf, k), xref_offset_width);
+ pdf_out(pdf, 255);
+ } else if (obj_os_idx(pdf, k) == -1) { /* object not in object stream */
+ pdf_out(pdf, 1);
+ pdf_out_bytes(pdf, obj_offset(pdf, k),
+ xref_offset_width);
+ pdf_out(pdf, 0);
+ } else { /* object in object stream */
+ pdf_out(pdf, 2);
+ pdf_out_bytes(pdf, obj_offset(pdf, k),
+ xref_offset_width);
+ pdf_out(pdf, obj_os_idx(pdf, k));
+ }
+ }
+ pdf_end_stream(pdf);
+ /* TODO: generate a debug version of the crossref */
+
+ pdf_flush(pdf);
+ } else {
+ /* Output the |obj_tab| */
+ /* Build a linked list of free objects */
+ build_free_object_list(pdf);
+
+ pdf_save_offset(pdf);
+ pdf_puts(pdf, "xref\n");
+ pdf_puts(pdf, "0 ");
+ pdf_print_int_ln(pdf, pdf->obj_ptr + 1);
+ pdf_print_fw_int(pdf, obj_link(pdf, 0), 10);
+ pdf_puts(pdf, " 65535 f \n");
+ for (k = 1; k <= pdf->obj_ptr; k++) {
+ if (!is_obj_written(pdf, k)) {
+ pdf_print_fw_int(pdf, obj_link(pdf, k), 10);
+ pdf_puts(pdf, " 00000 f \n");
+ } else {
+ pdf_print_fw_int(pdf, obj_offset(pdf, k), 10);
+ pdf_puts(pdf, " 00000 n \n");
+ }
+ }
+
+ }
+
+ /* Output the trailer */
+ if (!pdf->os_enable) {
+ pdf_puts(pdf, "trailer\n");
+ pdf_puts(pdf, "<< ");
+ pdf_int_entry_ln(pdf, "Size", pdf->sys_obj_ptr + 1);
+ pdf_indirect_ln(pdf, "Root", root);
+ pdf_indirect_ln(pdf, "Info", pdf->sys_obj_ptr);
+ if (pdf_trailer_toks != null) {
+ pdf_print_toks_ln(pdf, pdf_trailer_toks);
+ delete_token_ref(pdf_trailer_toks);
+ pdf_trailer_toks = null;
+ }
+ print_ID(pdf, pdf->file_name);
+ pdf_puts(pdf, " >>\n");
+ }
+ pdf_puts(pdf, "startxref\n");
+ if (pdf->os_enable)
+ pdf_print_int_ln(pdf, obj_offset(pdf, pdf->sys_obj_ptr));
+ else
+ pdf_print_int_ln(pdf, pdf_saved_offset(pdf));
+ pdf_puts(pdf, "%%EOF\n");
+
+ pdf_flush(pdf);
+ if (callback_id == 0) {
+ tprint_nl("Output written on ");
+ tprint(pdf->file_name);
+ tprint(" (");
+ print_int(total_pages);
+ tprint(" page");
+ if (total_pages != 1)
+ print_char('s');
+ tprint(", ");
+ print_int(pdf_offset(pdf));
+ tprint(" bytes).");
+ } else if (callback_id > 0) {
+ res = run_callback(callback_id, "->");
+ }
+ }
+ libpdffinish(pdf);
+ if (pdf->draftmode == 0)
+ close_file(pdf->file);
+ else
+ pdf_warning(NULL,
+ "\\pdfdraftmode enabled, not changing output pdf",
+ true, true);
+ }
+
+ if (callback_id == 0) {
+ if (log_opened) {
+ fprintf(log_file,
+ "\nPDF statistics: %d PDF objects out of %d (max. %d)\n",
+ (int) pdf->obj_ptr, (int) pdf->obj_tab_size,
+ (int) sup_obj_tab_size);
+ if (pdf->os_cntr > 0) {
+ fprintf(log_file,
+ " %d compressed objects within %d object stream%s\n",
+ (int) ((pdf->os_cntr - 1) * pdf_os_max_objs +
+ pdf->os_idx + 1), (int) pdf->os_cntr,
+ (pdf->os_cntr > 1 ? "s" : ""));
+ }
+ fprintf(log_file, " %d named destinations out of %d (max. %d)\n",
+ (int) pdf->dest_names_ptr, (int) pdf->dest_names_size,
+ (int) sup_dest_names_size);
+ fprintf(log_file,
+ " %d words of extra memory for PDF output out of %d (max. %d)\n",
+ (int) pdf->mem_ptr, (int) pdf->mem_size,
+ (int) sup_pdf_mem_size);
+ }
+ }
+}
+
+@ @c
+void scan_pdfcatalog(PDF pdf)
+{
+ halfword p;
+ scan_pdf_ext_toks();
+ pdf_catalog_toks = concat_tokens(pdf_catalog_toks, def_ref);
+ if (scan_keyword("openaction")) {
+ if (pdf_catalog_openaction != 0) {
+ pdf_error("ext1", "duplicate of openaction");
+ } else {
+ check_o_mode(pdf, "\\pdfcatalog", 1 << OMODE_PDF, true);
+ p = scan_action(pdf);
+ pdf_new_obj(pdf, obj_type_others, 0, 1);
+ pdf_catalog_openaction = pdf->obj_ptr;
+ write_action(pdf, p);
+ pdf_end_obj(pdf);
+ delete_action_ref(p);
+ }
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h
new file mode 100644
index 00000000000..6a19556a0f3
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.h
@@ -0,0 +1,30 @@
+/* pdfglyph.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfglyph.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFGLYPH_H
+# define PDFGLYPH_H
+
+void end_chararray(PDF pdf);
+void end_charmode(PDF pdf);
+void pdf_place_glyph(PDF pdf, internal_font_number f, int c);
+void pdf_print_charwidth(PDF pdf, internal_font_number f, int i);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w
new file mode 100644
index 00000000000..ba4911a3698
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w
@@ -0,0 +1,222 @@
+% pdfglyph.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfglyph.w 3584 2010-04-02 17:45:55Z hhenkel $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfglyph.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#include "pdf/pdfpage.h"
+
+#define lround(a) (long) floor((a) + 0.5)
+#define pdf2double(a) ((double) (a).m / ten_pow[(a).e])
+
+@ eternal constants
+@c
+#define one_bp ((double) 65536 * (double) 72.27 / 72) /* number of sp per 1bp */
+#define e_tj 3 /* must be 3; movements in []TJ are in fontsize/$10^3$ units */
+
+@ @c
+static long pdf_char_width(pdfstructure * p, internal_font_number f, int i)
+{
+ /* use exactly this formula also for calculating the /Width array values */
+ return
+ lround((double) char_width(f, i) / font_size(f) *
+ ten_pow[e_tj + p->cw.e]);
+}
+
+@ @c
+void pdf_print_charwidth(PDF pdf, internal_font_number f, int i)
+{
+ pdffloat cw;
+ pdfstructure *p = pdf->pstruct;
+ assert(pdf_font_blink(f) == null_font); /* must use unexpanded font! */
+ cw.m = pdf_char_width(p, f, i);
+ cw.e = p->cw.e;
+ print_pdffloat(pdf, cw);
+}
+
+@ @c
+static void setup_fontparameters(PDF pdf, internal_font_number f)
+{
+ float slant, extend, expand;
+ float u = 1.0;
+ pdfstructure *p = pdf->pstruct;
+ /* fix mantis bug \# 0000200 (acroread "feature") */
+ if ((font_format(f) == opentype_format ||
+ (font_format(f) == type1_format && font_encodingbytes(f) == 2))
+ && font_units_per_em(f) > 0)
+ u = (float) (font_units_per_em(f) / 1000.0);
+ pdf->f_cur = f;
+ p->f_pdf = pdf_set_font(pdf, f);
+ p->fs.m = lround((float) font_size(f) / u / one_bp * ten_pow[p->fs.e]);
+ slant = (float) font_slant(f) / (float) 1000.0;
+ extend = (float) font_extend(f) / (float) 1000.0;
+ expand = (float) 1.0 + (float) font_expand_ratio(f) / (float) 1000.0;
+ p->tj_delta.e = p->cw.e - 1; /* "- 1" makes less corrections inside []TJ */
+ /* no need to be more precise than TeX (1sp) */
+ while (p->tj_delta.e > 0
+ && (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5)
+ p->tj_delta.e--; /* happens for very tiny fonts */
+ assert(p->cw.e >= p->tj_delta.e); /* else we would need, e. g., |ten_pow[-1]| */
+ p->tm[0].m = lround(expand * extend * (float) ten_pow[p->tm[0].e]);
+ p->tm[2].m = lround(slant * (float) ten_pow[p->tm[2].e]);
+ p->k2 =
+ ten_pow[e_tj +
+ p->cw.e] / (ten_pow[p->pdf.h.e] * pdf2double(p->fs) *
+ pdf2double(p->tm[0]));
+}
+
+@ @c
+static void set_font(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ pdf_printf(pdf, "/F%d", (int) p->f_pdf);
+ pdf_print_resname_prefix(pdf);
+ pdf_printf(pdf, " ");
+ print_pdffloat(pdf, p->fs);
+ pdf_printf(pdf, " Tf ");
+ p->f_pdf_cur = p->f_pdf;
+ p->fs_cur.m = p->fs.m;
+}
+
+@ @c
+static void print_tm(PDF pdf, pdffloat * tm)
+{
+ print_pdf_matrix(pdf, tm);
+ pdf_printf(pdf, " Tm ");
+}
+
+@ @c
+static void set_textmatrix(PDF pdf, scaledpos pos)
+{
+ boolean move;
+ pdfstructure *p = pdf->pstruct;
+ assert(is_textmode(p));
+ move = calc_pdfpos(p, pos);
+ if (move == TRUE) {
+ print_tm(pdf, p->tm);
+ p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; /* Tm replaces */
+ p->pdf.v.m = p->pdf_bt_pos.v.m + p->tm[5].m;
+ }
+}
+
+@ @c
+static void begin_charmode(PDF pdf, internal_font_number f, pdfstructure * p)
+{
+ assert(is_chararraymode(p));
+ if (font_encodingbytes(f) == 2) {
+ p->ishex = 1;
+ pdf_printf(pdf, "<");
+ } else {
+ p->ishex = 0;
+ pdf_printf(pdf, "(");
+ }
+ p->mode = PMODE_CHAR;
+}
+
+@ @c
+void end_charmode(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ assert(is_charmode(p));
+ if (p->ishex == 1) {
+ p->ishex = 0;
+ pdf_printf(pdf, ">");
+ } else {
+ pdf_printf(pdf, ")");
+ }
+ p->mode = PMODE_CHARARRAY;
+}
+
+@ @c
+static void begin_chararray(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ assert(is_textmode(p));
+ p->pdf_tj_pos = p->pdf;
+ p->cw.m = 0;
+ pdf_printf(pdf, "[");
+ p->mode = PMODE_CHARARRAY;
+}
+
+@ @c
+void end_chararray(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ assert(is_chararraymode(p));
+ pdf_printf(pdf, "]TJ\n");
+ p->pdf = p->pdf_tj_pos;
+ p->mode = PMODE_TEXT;
+}
+
+@ @c
+void pdf_place_glyph(PDF pdf, internal_font_number f, int c)
+{
+ boolean move;
+ pdfstructure *p = pdf->pstruct;
+ scaledpos pos = pdf->posstruct->pos;
+ if (!char_exists(f, c))
+ return;
+ if (f != pdf->f_cur || is_textmode(p) || is_pagemode(p)) {
+ pdf_goto_textmode(pdf);
+ if (f != pdf->f_cur)
+ setup_fontparameters(pdf, f);
+ if (p->f_pdf != p->f_pdf_cur || p->fs.m != p->fs_cur.m)
+ set_font(pdf);
+ set_textmatrix(pdf, pos);
+ begin_chararray(pdf);
+ }
+ assert(is_charmode(p) || is_chararraymode(p));
+ move = calc_pdfpos(p, pos);
+ if (move == TRUE) {
+ if ((p->wmode == WMODE_H
+ && (p->pdf_bt_pos.v.m + p->tm[5].m) != p->pdf.v.m)
+ || (p->wmode == WMODE_V
+ && (p->pdf_bt_pos.h.m + p->tm[4].m) != p->pdf.h.m)
+ || abs(p->tj_delta.m) >= 1000000) {
+ pdf_goto_textmode(pdf);
+ set_textmatrix(pdf, pos);
+ begin_chararray(pdf);
+ move = calc_pdfpos(p, pos);
+ }
+ if (move == TRUE) {
+ assert((p->wmode == WMODE_H
+ && (p->pdf_bt_pos.v.m + p->tm[5].m) == p->pdf.v.m)
+ || (p->wmode == WMODE_V
+ && (p->pdf_bt_pos.h.m + p->tm[4].m) == p->pdf.h.m));
+ if (is_charmode(p))
+ end_charmode(pdf);
+ assert(p->tj_delta.m != 0);
+ print_pdffloat(pdf, p->tj_delta);
+ p->cw.m -= p->tj_delta.m * ten_pow[p->cw.e - p->tj_delta.e];
+ }
+ }
+ if (is_chararraymode(p))
+ begin_charmode(pdf, f, p);
+ pdf_mark_char(f, c);
+ if (font_encodingbytes(f) == 2)
+ pdf_print_wide_char(pdf, char_index(f, c));
+ else
+ pdf_print_char(pdf, c);
+ p->cw.m += pdf_char_width(p, p->f_pdf, c); /* aka |adv_char_width()| */
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.h b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.h
new file mode 100644
index 00000000000..86b5752bc42
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.h
@@ -0,0 +1,28 @@
+/* pdfimage.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfimage.h 3160 2009-11-16 16:29:11Z hhenkel $ */
+
+#ifndef PDFIMAGE_H
+# define PDFIMAGE_H
+
+void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform);
+void pdf_place_image(PDF pdf, halfword p);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w
new file mode 100644
index 00000000000..be343b37676
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w
@@ -0,0 +1,156 @@
+% pdfimage.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfimage.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfimage.w $";
+
+#include "ptexlib.h"
+
+@ @c
+void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform)
+{
+ float a[6]; /* transformation matrix */
+ float xoff, yoff, tmp;
+ pdfstructure *p = pdf->pstruct;
+ scaledpos pos = pdf->posstruct->pos;
+ int r; /* number of digits after the decimal point */
+ int k;
+ scaledpos tmppos;
+ pdffloat cm[6];
+ int groupref; /* added from web for 1.40.8 */
+ assert(idict != 0);
+ assert(p != NULL);
+ a[0] = a[3] = 1.0e6;
+ a[1] = a[2] = 0;
+ if (img_type(idict) == IMG_TYPE_PDF
+ || img_type(idict) == IMG_TYPE_PDFSTREAM) {
+ a[0] /= (float) img_xsize(idict);
+ a[3] /= (float) img_ysize(idict);
+ xoff = (float) img_xorig(idict) / (float) img_xsize(idict);
+ yoff = (float) img_yorig(idict) / (float) img_ysize(idict);
+ r = 6;
+ } else {
+ /* added from web for 1.40.8 */
+ if (img_type(idict) == IMG_TYPE_PNG) {
+ groupref = img_group_ref(idict);
+ if ((groupref > 0) && (pdf->img_page_group_val == 0))
+ pdf->img_page_group_val = groupref;
+ }
+ /* /added from web */
+ a[0] /= (float) one_hundred_bp;
+ a[3] = a[0];
+ xoff = yoff = 0;
+ r = 4;
+ }
+ if ((transform & 7) > 3) { // mirror cases
+ a[0] *= -1;
+ xoff *= -1;
+ }
+ switch ((transform + img_rotation(idict)) & 3) {
+ case 0: /* no transform */
+ break;
+ case 1: /* rot. 90 deg. (counterclockwise) */
+ a[1] = a[0];
+ a[2] = -a[3];
+ a[3] = a[0] = 0;
+ tmp = yoff;
+ yoff = xoff;
+ xoff = -tmp;
+ break;
+ case 2: /* rot. 180 deg. (counterclockwise) */
+ a[0] *= -1;
+ a[3] *= -1;
+ xoff *= -1;
+ yoff *= -1;
+ break;
+ case 3: /* rot. 270 deg. (counterclockwise) */
+ a[1] = -a[0];
+ a[2] = a[3];
+ a[3] = a[0] = 0;
+ tmp = yoff;
+ yoff = -xoff;
+ xoff = tmp;
+ break;
+ default:;
+ }
+ xoff *= (float) dim.wd;
+ yoff *= (float) (dim.ht + dim.dp);
+ a[0] *= (float) dim.wd;
+ a[1] *= (float) (dim.ht + dim.dp);
+ a[2] *= (float) dim.wd;
+ a[3] *= (float) (dim.ht + dim.dp);
+ a[4] = (float) pos.h - xoff;
+ a[5] = (float) pos.v - yoff;
+ k = transform + img_rotation(idict);
+ if ((transform & 7) > 3)
+ k++;
+ switch (k & 3) {
+ case 0: /* no transform */
+ break;
+ case 1: /* rot. 90 deg. (counterclockwise) */
+ a[4] += (float) dim.wd;
+ break;
+ case 2: /* rot. 180 deg. */
+ a[4] += (float) dim.wd;
+ a[5] += (float) (dim.ht + dim.dp);
+ break;
+ case 3: /* rot. 270 deg. */
+ a[5] += (float) (dim.ht + dim.dp);
+ break;
+ default:;
+ }
+ /* 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]);
+ pdf_goto_pagemode(pdf);
+ (void) calc_pdfpos(p, tmppos);
+ cm[4] = p->cm[4];
+ cm[5] = p->cm[5];
+ if (pdf->img_page_group_val == 0)
+ pdf->img_page_group_val = img_group_ref(idict); /* added from web for 1.40.8 */
+ pdf_printf(pdf, "q\n");
+ pdf_print_cm(pdf, cm);
+ pdf_printf(pdf, "/Im");
+ pdf_print_int(pdf, img_index(idict));
+ pdf_print_resname_prefix(pdf);
+ pdf_printf(pdf, " Do\nQ\n");
+ addto_page_resources(pdf, obj_type_ximage, img_objnum(idict));
+ if (img_state(idict) < DICT_OUTIMG)
+ img_state(idict) = DICT_OUTIMG;
+}
+
+@ for normal output, see \.{pdflistout.w}
+
+@c
+void pdf_place_image(PDF pdf, halfword p)
+{
+ scaled_whd dim;
+ image_dict *idict = idict_array[pdf_ximage_index(p)];
+ assert(idict != NULL);
+ dim.wd = width(p);
+ dim.ht = height(p);
+ dim.dp = depth(p);
+ place_img(pdf, idict, dim, pdf_ximage_transform(p));
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflink.h b/Build/source/texk/web2c/luatexdir/pdf/pdflink.h
new file mode 100644
index 00000000000..c804f038345
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdflink.h
@@ -0,0 +1,39 @@
+/* pdflink.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdflink.h 2978 2009-08-09 09:03:39Z hhenkel $ */
+
+#ifndef PDFLINK_H
+# define PDFLINK_H
+
+# define set_pdf_link_attr(A,B) pdf_link_attr(A)=B
+# define set_pdf_link_action(A,B) pdf_link_action(A)=B
+# define set_pdf_link_objnum(A,B) pdf_link_objnum(A)=B
+
+extern void push_link_level(PDF pdf, halfword p);
+extern void pop_link_level(PDF pdf);
+extern void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur);
+extern void end_link(PDF pdf, halfword p);
+extern void append_link(PDF pdf, halfword parent_box, scaledpos cur,
+ small_number i);
+
+extern void scan_startlink(PDF pdf);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflink.w b/Build/source/texk/web2c/luatexdir/pdf/pdflink.w
new file mode 100644
index 00000000000..66b369d12bd
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdflink.w
@@ -0,0 +1,166 @@
+% pdflink.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdflink.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdflink.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define pdf_link_margin dimen_par(pdf_link_margin_code)
+
+@ 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.
+
+@c
+void push_link_level(PDF pdf, halfword p)
+{
+ if (pdf->link_stack_ptr >= pdf_max_link_level)
+ overflow("pdf link stack size", pdf_max_link_level);
+ assert(((type(p) == whatsit_node) && (subtype(p) == pdf_start_link_node)));
+ incr(pdf->link_stack_ptr);
+ pdf->link_stack[pdf->link_stack_ptr].nesting_level = cur_s;
+ pdf->link_stack[pdf->link_stack_ptr].link_node = copy_node_list(p);
+ pdf->link_stack[pdf->link_stack_ptr].ref_link_node = p;
+}
+
+@ @c
+void pop_link_level(PDF pdf)
+{
+ assert(pdf->link_stack_ptr > 0);
+ flush_node_list(pdf->link_stack[pdf->link_stack_ptr].link_node);
+ decr(pdf->link_stack_ptr);
+}
+
+@ @c
+void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
+{
+ scaled_whd alt_rule;
+ if (type(p) == vlist_node)
+ pdf_error("ext4", "\\pdfstartlink ended up in vlist");
+ if (!is_shipping_page)
+ pdf_error("ext4", "link annotations cannot be inside an XForm");
+ assert(type(parent_box) == hlist_node);
+ if (is_obj_scheduled(pdf, pdf_link_objnum(p)))
+ pdf_link_objnum(p) = pdf_new_objnum(pdf);
+ push_link_level(pdf, p);
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_link_margin);
+ obj_annot_ptr(pdf, pdf_link_objnum(p)) = p; /* the reference for the pdf annot object must be set here */
+ addto_page_resources(pdf, obj_type_link, pdf_link_objnum(p));
+}
+
+@ @c
+void end_link(PDF pdf, halfword p)
+{
+ halfword q;
+ scaledpos pos = pdf->posstruct->pos;
+ if (type(p) == vlist_node)
+ pdf_error("ext4", "\\pdfendlink ended up in vlist");
+ if (pdf->link_stack_ptr < 1)
+ pdf_error("ext4",
+ "pdf link_stack empty, \\pdfendlink used without \\pdfstartlink?");
+ if (pdf->link_stack[pdf->link_stack_ptr].nesting_level != cur_s)
+ pdf_error("ext4",
+ "\\pdfendlink ended up in different nesting level than \\pdfstartlink");
+
+ /* N.B.: test for running link must be done on |link_node| and not |ref_link_node|,
+ as |ref_link_node| can be set by |do_link| or |append_link| already */
+
+ if (is_running(width(pdf->link_stack[pdf->link_stack_ptr].link_node))) {
+ q = pdf->link_stack[pdf->link_stack_ptr].ref_link_node;
+ if (is_shipping_page && matrixused()) {
+ matrixrecalculate(pos.h + pdf_link_margin);
+ pdf_ann_left(q) = getllx() - pdf_link_margin;
+ pdf_ann_top(q) = cur_page_size.v - getury() - pdf_link_margin;
+ pdf_ann_right(q) = geturx() + pdf_link_margin;
+ pdf_ann_bottom(q) = cur_page_size.v - getlly() + pdf_link_margin;
+ } else {
+ switch (pdf->posstruct->dir) {
+ case dir_TLT:
+ pdf_ann_right(q) = pos.h + pdf_link_margin;
+ break;
+ case dir_TRT:
+ pdf_ann_left(q) = pos.h - pdf_link_margin;
+ break;
+ case dir_LTL:
+ case dir_RTT:
+ pdf_ann_bottom(q) = pos.v - pdf_link_margin;
+ break;
+ }
+ }
+ }
+ pop_link_level(pdf);
+}
+
+
+@ For ``running'' annotations we must append a new node when the end of
+annotation is in other box than its start. The new created node is identical to
+corresponding whatsit node representing the start of annotation, but its
+|info| field is |max_halfword|. We set |info| field just before destroying the
+node, in order to use |flush_node_list| to do the job.
+
+
+@ Append a new pdf annot to |pdf_link_list|
+
+@c
+void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i)
+{
+ halfword p;
+ scaled_whd alt_rule;
+ assert(type(parent_box) == hlist_node);
+ p = copy_node(pdf->link_stack[(int) i].link_node);
+ pdf->link_stack[(int) i].ref_link_node = p;
+ subtype(p) = pdf_link_data_node; /* this node is not a normal link node */
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_link_margin);
+ pdf_create_obj(pdf, obj_type_others, 0);
+ obj_annot_ptr(pdf, pdf->obj_ptr) = p;
+ addto_page_resources(pdf, obj_type_link, pdf->obj_ptr);
+}
+
+@ @c
+void scan_startlink(PDF pdf)
+{
+ int k;
+ halfword r;
+ if (abs(cur_list.mode_field) == vmode)
+ pdf_error("ext1", "\\pdfstartlink cannot be used in vertical mode");
+ k = pdf_new_objnum(pdf);
+ new_annot_whatsit(pdf_start_link_node);
+ set_pdf_link_attr(cur_list.tail_field, null);
+ if (scan_keyword("attr")) {
+ scan_pdf_ext_toks();
+ set_pdf_link_attr(cur_list.tail_field, def_ref);
+ }
+ r = scan_action(pdf);
+ set_pdf_link_action(cur_list.tail_field, r);
+ set_pdf_link_objnum(cur_list.tail_field, k);
+ pdf_last_link = k;
+ /* N.B.: although it is possible to set |obj_annot_ptr(k) := tail| here, it
+ is not safe if nodes are later copied/destroyed/moved; a better place
+ to do this is inside |do_link|, when the whatsit node is written out */
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h
new file mode 100644
index 00000000000..41aff73357a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h
@@ -0,0 +1,50 @@
+/* pdflistout.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdflistout.h 3386 2010-01-26 06:41:37Z taco $ */
+
+#ifndef PDFLISTOUT_H
+# define PDFLISTOUT_H
+
+/* a few small helpers */
+# define pos_right(A) pdf->posstruct->pos.h = pdf->posstruct->pos.h + (A)
+# define pos_left(A) pdf->posstruct->pos.h = pdf->posstruct->pos.h - (A)
+# define pos_up(A) pdf->posstruct->pos.v = pdf->posstruct->pos.v + (A)
+# define pos_down(A) pdf->posstruct->pos.v = pdf->posstruct->pos.v - (A)
+
+typedef void (*backend_function) (); /* variadic arguments */
+
+typedef struct {
+ char *name; /* name of the backend */
+ backend_function *node_fu; /* array of node output functions */
+ backend_function *whatsit_fu; /* array of whatsit output functions */
+} backend_struct;
+
+extern pos_info_structure pos_info;
+
+extern backend_function *backend_out;
+extern backend_function *backend_out_whatsit;
+
+extern void init_backend_functionpointers(output_mode o_mode);
+
+extern void hlist_out(PDF pdf, halfword this_box);
+extern void vlist_out(PDF pdf, halfword this_box);
+extern void out_what(PDF pdf, halfword p);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w
new file mode 100644
index 00000000000..2698c47fa32
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w
@@ -0,0 +1,1139 @@
+% pdflistout.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+\def\pdfTeX{pdf\TeX}
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdflistout.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdflistout.w $";
+
+#include "ptexlib.h"
+
+@ @c
+pos_info_structure pos_info; /* to be accessed from Lua */
+
+static backend_struct *backend = NULL;
+backend_function *backend_out, *backend_out_whatsit;
+
+@ @c
+static void missing_backend_function(PDF pdf, halfword p)
+{
+ char *b;
+ const char *s;
+ const char *n;
+ char backend_string[15];
+ char err_string[60];
+ assert(backend != NULL);
+ if (type(p) == whatsit_node)
+ s = "whatsit";
+ else
+ s = "node";
+ n = get_node_name(type(p), subtype(p));
+ b = backend[pdf->o_mode].name;
+ snprintf(backend_string, strlen(b) + 10, "%s back-end", b);
+ snprintf(err_string, 59, "no output function for \"%s\" %s", n, s);
+ pdf_error(backend_string, err_string);
+}
+
+@ @c
+static void init_none_backend_functions()
+{
+ backend_struct *p = &backend[OMODE_NONE];
+ p->name = strdup("(None)");
+}
+
+@ @c
+static void init_pdf_backend_functions()
+{
+ backend_struct *p = &backend[OMODE_PDF];
+ p->name = strdup("PDF");
+ p->node_fu[rule_node] = &pdf_place_rule; /* 2 */
+ p->node_fu[glyph_node] = &pdf_place_glyph; /* 37 */
+ p->whatsit_fu[special_node] = &pdf_special; /* 3 */
+ p->whatsit_fu[pdf_literal_node] = &pdf_out_literal; /* 8 */
+ p->whatsit_fu[pdf_refobj_node] = &pdf_ref_obj; /* 10 */
+ p->whatsit_fu[pdf_refxform_node] = &pdf_place_form; /* 12 */
+ p->whatsit_fu[pdf_refximage_node] = &pdf_place_image; /* 14 */
+ p->whatsit_fu[pdf_annot_node] = &do_annot; /* 15 */
+ p->whatsit_fu[pdf_start_link_node] = &do_link; /* 16 */
+ p->whatsit_fu[pdf_end_link_node] = &end_link; /* 17 */
+ p->whatsit_fu[pdf_dest_node] = &do_dest; /* 19 */
+ p->whatsit_fu[pdf_thread_node] = &do_thread; /* 20 */
+ p->whatsit_fu[pdf_end_thread_node] = &end_thread; /* 22 */
+ p->whatsit_fu[late_lua_node] = &late_lua; /* 35 */
+ p->whatsit_fu[pdf_colorstack_node] = &pdf_out_colorstack; /* 39 */
+ p->whatsit_fu[pdf_setmatrix_node] = &pdf_out_setmatrix; /* 40 */
+ p->whatsit_fu[pdf_save_node] = &pdf_out_save; /* 41 */
+ p->whatsit_fu[pdf_restore_node] = &pdf_out_restore; /* 42 */
+}
+
+@ @c
+static void init_dvi_backend_functions()
+{
+ backend_struct *p = &backend[OMODE_DVI];
+ p->name = strdup("DVI");
+ p->node_fu[rule_node] = &dvi_place_rule; /* 2 */
+ p->node_fu[glyph_node] = &dvi_place_glyph; /* 37 */
+ p->whatsit_fu[special_node] = &dvi_special; /* 3 */
+ p->whatsit_fu[late_lua_node] = &late_lua; /* 35 */
+}
+
+@ @c
+static void init_lua_backend_functions()
+{
+ backend_struct *p = &backend[OMODE_LUA];
+ p->name = strdup("Lua");
+ p->node_fu[rule_node] = &lua_place_rule; /* 2 */
+ p->node_fu[glyph_node] = &lua_place_glyph; /* 37 */
+ p->whatsit_fu[late_lua_node] = &late_lua; /* 35 */
+}
+
+@ @c
+void init_backend_functionpointers(output_mode o_mode)
+{
+ int i, j;
+ if (backend == NULL) {
+ backend = xmalloc((MAX_OMODE + 1) * sizeof(backend_struct));
+ for (i = 0; i <= MAX_OMODE; i++) {
+ backend[i].node_fu =
+ xmalloc((MAX_NODE_TYPE + 1) * sizeof(backend_function));
+ backend[i].whatsit_fu =
+ xmalloc((MAX_WHATSIT_TYPE + 1) * sizeof(backend_function));
+ for (j = 0; j < MAX_NODE_TYPE + 1; j++)
+ backend[i].node_fu[j] = &missing_backend_function;
+ for (j = 0; j < MAX_WHATSIT_TYPE + 1; j++)
+ backend[i].whatsit_fu[j] = &missing_backend_function;
+ }
+ init_none_backend_functions();
+ init_dvi_backend_functions();
+ init_pdf_backend_functions();
+ init_lua_backend_functions();
+ }
+ backend_out = backend[o_mode].node_fu;
+ backend_out_whatsit = backend[o_mode].whatsit_fu;
+}
+
+@ This code scans forward to the ending |dir_node| while keeping
+track of the needed width in |w|. When it finds the node that will end
+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.
+
+@c
+static scaled simple_advance_width(halfword p)
+{
+ halfword q = p;
+ scaled w = 0;
+ while ((q != null) && (vlink(q) != null)) {
+ q = vlink(q);
+ if (is_char_node(q)) {
+ w += glyph_width(q);
+ } else {
+ switch (type(q)) {
+ case hlist_node:
+ case vlist_node:
+ case rule_node:
+ case margin_kern_node:
+ case kern_node:
+ w += width(q);
+ break;
+ case disc_node:
+ if (vlink(no_break(q)) != null)
+ w += simple_advance_width(no_break(q));
+ default:
+ break;
+ }
+ }
+ }
+ return w;
+}
+
+@ @c
+static halfword calculate_width_to_enddir(halfword p, real cur_glue,
+ scaled cur_g, halfword this_box)
+{
+ int dir_nest = 1;
+ halfword q = p, enddir_ptr = p;
+ scaled w = 0;
+ halfword g; /* this is normally a global variable, but that is just too hideous */
+ /* to me, it looks like the next is needed. but Aleph doesn't do that, so let us not do it either */
+ real glue_temp; /* glue value before rounding */
+ /* |w:=w-cur_g; cur_glue:=0;| */
+ int g_sign = glue_sign(this_box);
+ int g_order = glue_order(this_box);
+ while ((q != null) && (vlink(q) != null)) {
+ q = vlink(q);
+ if (is_char_node(q))
+ w += pack_width(box_dir(this_box), dir_TRT, q, true);
+ else {
+ switch (type(q)) {
+ case hlist_node:
+ case vlist_node:
+ w += pack_width(box_dir(this_box), box_dir(q), q, false);
+ break;
+ case rule_node:
+ case margin_kern_node:
+ case kern_node:
+ w += width(q);
+ break;
+ case glue_node:
+ g = glue_ptr(q);
+ w += width(g) - cur_g;
+ if (g_sign != normal) {
+ if (g_sign == stretching) {
+ if (stretch_order(g) == g_order) {
+ cur_glue = cur_glue + stretch(g);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue);
+ cur_g = float_round(glue_temp);
+ }
+ } else if (shrink_order(g) == g_order) {
+ cur_glue = cur_glue - shrink(g);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue);
+ cur_g = float_round(glue_temp);
+ }
+ }
+ w += cur_g;
+ break;
+ case disc_node:
+ if (vlink(no_break(q)) != null)
+ w += simple_advance_width(no_break(q));
+ break;
+ case math_node:
+ w += surround(q);
+ break;
+ case whatsit_node:
+ if (subtype(q) == dir_node) {
+ if (dir_dir(q) >= 0)
+ incr(dir_nest);
+ else
+ decr(dir_nest);
+ if (dir_nest == 0) {
+ enddir_ptr = q;
+ dir_cur_h(enddir_ptr) = w;
+ q = null;
+ }
+ } else if ((subtype(q) == pdf_refxform_node)
+ || (subtype(q) == pdf_refximage_node))
+ w += width(q);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (enddir_ptr == p) /* no enddir found, just transport w by begindir */
+ dir_cur_h(enddir_ptr) = w;
+ return enddir_ptr;
+}
+
+@ The |out_what| procedure takes care of outputting the whatsit nodes for
+|vlist_out| and |hlist_out|, which are similar for either case.
+
+We don't implement \.{\\write} inside of leaders. (The reason is that
+the number of times a leader box appears might be different in different
+implementations, due to machine-dependent rounding in the glue calculations.)
+@^leaders@>
+
+@c
+void out_what(PDF pdf, halfword p)
+{
+ int j; /* write stream number */
+ switch (subtype(p)) {
+ /* function(pdf, p) */
+ case pdf_save_node: /* |pdf_out_save(pdf, p)|; */
+ case pdf_restore_node: /* |pdf_out_restore(pdf, p)|; */
+ case pdf_end_link_node: /* |end_link(pdf, p)|; */
+ case pdf_end_thread_node: /* |end_thread(pdf, p)|; */
+ case pdf_literal_node: /* |pdf_out_literal(pdf, p)|; */
+ case pdf_colorstack_node: /* |pdf_out_colorstack(pdf, p)|; */
+ case pdf_setmatrix_node: /* |pdf_out_setmatrix(pdf, p)|; */
+ case special_node: /* |pdf_special(pdf, p)|; */
+ case late_lua_node: /* |late_lua(pdf, p)|; */
+ case pdf_refobj_node: /* |pdf_ref_obj(pdf, p)| */
+ backend_out_whatsit[subtype(p)] (pdf, p);
+ break;
+ case open_node:
+ case write_node:
+ case close_node:
+ /* Do some work that has been queued up for \.{\\write} */
+ if (!doing_leaders) {
+ j = write_stream(p);
+ if (subtype(p) == write_node) {
+ write_out(p);
+ } else {
+ if (write_open[j])
+ lua_a_close_out(write_file[j]);
+ if (subtype(p) == close_node) {
+ write_open[j] = false;
+ } else if (j < 16) {
+ char *fn;
+ cur_name = open_name(p);
+ cur_area = open_area(p);
+ cur_ext = open_ext(p);
+ if (cur_ext == get_nullstr())
+ cur_ext = maketexstring(".tex");
+ fn = pack_file_name(cur_name, cur_area, cur_ext);
+ while (!lua_a_open_out(&(write_file[j]), fn, (j + 1)))
+ fn = prompt_file_name("output file name", ".tex");
+ write_open[j] = true;
+ }
+ }
+ }
+ break;
+ case dir_node: /* in a vlist */
+ break;
+ case local_par_node:
+ case cancel_boundary_node:
+ case user_defined_node:
+ break;
+ default:
+ /* this should give an error about missing whatsit backend function */
+ backend_out_whatsit[subtype(p)] (pdf, p);
+ }
+}
+
+@ @c
+void hlist_out(PDF pdf, halfword this_box)
+{
+
+ posstructure localpos; /* the position structure local within this function */
+ posstructure *refpos; /* the list origin pos. on the page, provided by the caller */
+
+ scaledpos cur = { 0, 0 }, tmpcur, basepoint;
+ scaledpos size = { 0, 0 }; /* rule dimensions */
+ scaled effective_horizontal;
+ scaled save_h; /* what |cur.h| should pop to */
+ scaled edge; /* right edge of sub-box or leader space */
+ halfword enddir_ptr; /* temporary pointer to enddir node */
+ int g_order; /* applicable order of infinity for glue */
+ int g_sign; /* selects type of glue */
+ halfword p, q; /* current position in the hlist */
+ halfword leader_box; /* the leader box being replicated */
+ scaled leader_wd; /* width of leader box being replicated */
+ scaled lx; /* extra space between leader boxes */
+ boolean outer_doing_leaders; /* were we doing leaders? */
+ halfword prev_p; /* one step behind |p| */
+ real glue_temp; /* glue value before rounding */
+ real cur_glue = 0.0; /* glue seen so far */
+ scaled cur_g = 0; /* rounded equivalent of |cur_glue| times the glue ratio */
+ scaled_whd rule, ci;
+ int i; /* index to scan |pdf_link_stack| */
+ int save_loc = 0; /* DVI! \.{DVI} byte location upon entry */
+ scaledpos save_dvi = { 0, 0 }; /* DVI! what |dvi| should pop to */
+
+ g_order = glue_order(this_box);
+ g_sign = glue_sign(this_box);
+ p = list_ptr(this_box);
+
+ refpos = pdf->posstruct;
+ pdf->posstruct = &localpos; /* use local structure for recursion */
+ localpos.pos = refpos->pos;
+ localpos.dir = box_dir(this_box);
+
+ incr(cur_s);
+ if (cur_s > max_push)
+ max_push = cur_s;
+
+ if (pdf->o_mode == OMODE_DVI) {
+ if (cur_s > 0) { /* DVI! */
+ dvi_push(); /* DVI! */
+ save_dvi = dvi; /* DVI! */
+ }
+ save_loc = dvi_offset + dvi_ptr /* DVI! */ ;
+ }
+
+ prev_p = this_box + list_offset;
+ /* Create link annotations for the current hbox if needed */
+ for (i = 1; i <= pdf->link_stack_ptr; i++) {
+ assert(is_running(width(pdf->link_stack[i].link_node)));
+ if (pdf->link_stack[i].nesting_level == cur_s)
+ append_link(pdf, this_box, cur, (small_number) i);
+ }
+
+ /* Start hlist {\sl Sync\TeX} information record */
+ if (int_par(synctex_code))
+ synctexhlist(this_box);
+
+ while (p != null) {
+ if (is_char_node(p)) {
+ do {
+ if (x_displace(p) != 0 || y_displace(p) != 0) {
+ tmpcur.h = cur.h + x_displace(p);
+ tmpcur.v = cur.v - y_displace(p);
+ synch_pos_with_cur(pdf->posstruct, refpos, tmpcur);
+ }
+ output_one_char(pdf, font(p), character(p));
+ ci = get_charinfo_whd(font(p), character(p));
+ if (textdir_parallel(localpos.dir, dir_TLT))
+ cur.h += ci.wd;
+ else
+ cur.h += ci.ht + ci.dp;
+ synch_pos_with_cur(pdf->posstruct, refpos, cur);
+ p = vlink(p);
+ } while (is_char_node(p));
+ /* Record current point {\sl Sync\TeX} information */
+ if (int_par(synctex_code))
+ synctexcurrent();
+ } else {
+ /* Output the non-|char_node| |p| for |hlist_out|
+ and move to the next node */
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ /* (\pdfTeX) Output a box in an hlist */
+
+ if (textdir_parallel(box_dir(p), localpos.dir)) {
+ effective_horizontal = width(p);
+ basepoint.v = 0;
+ if (textdir_opposite(box_dir(p), localpos.dir))
+ basepoint.h = width(p);
+ else
+ basepoint.h = 0;
+ } else {
+ effective_horizontal = height(p) + depth(p);
+ if (!is_mirrored(box_dir(p))) {
+ if (partextdir_eq(box_dir(p), localpos.dir))
+ basepoint.h = height(p);
+ else
+ basepoint.h = depth(p);
+ } else {
+ if (partextdir_eq(box_dir(p), localpos.dir))
+ basepoint.h = depth(p);
+ else
+ basepoint.h = height(p);
+ }
+ if (is_rotated(localpos.dir)) {
+ if (partextdir_eq(localpos.dir, box_dir(p)))
+ basepoint.v = -width(p) / 2; /* `up' */
+ else
+ basepoint.v = width(p) / 2; /* `down' */
+ } else if (is_mirrored(localpos.dir)) {
+ if (partextdir_eq(localpos.dir, box_dir(p)))
+ basepoint.v = 0;
+ else
+ basepoint.v = width(p); /* `down' */
+ } else {
+ if (partextdir_eq(localpos.dir, box_dir(p)))
+ basepoint.v = -width(p); /* `up' */
+ else
+ basepoint.v = 0;
+ }
+ }
+ if (!is_mirrored(localpos.dir))
+ basepoint.v = basepoint.v + shift_amount(p); /* shift the box `down' */
+ else
+ basepoint.v = basepoint.v - shift_amount(p); /* shift the box `up' */
+ if (list_ptr(p) == null) {
+ /* Record void list {\sl Sync\TeX} information */
+ if (int_par(synctex_code)) {
+ if (type(p) == vlist_node)
+ synctexvoidvlist(p, this_box);
+ else
+ synctexvoidhlist(p, this_box);
+ }
+ } else {
+ assert(cur.v == 0);
+ tmpcur.h = cur.h + basepoint.h;
+ tmpcur.v = basepoint.v;
+ synch_pos_with_cur(pdf->posstruct, refpos, tmpcur);
+ if (type(p) == vlist_node)
+ vlist_out(pdf, p);
+ else
+ hlist_out(pdf, p);
+ }
+ cur.h += effective_horizontal;
+ break;
+ case disc_node:
+ if (vlink(no_break(p)) != null) {
+ if (subtype(p) != select_disc) {
+ 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;
+ }
+ }
+ break;
+ case rule_node:
+ if (rule_dir(p)<0)
+ rule_dir(p) = localpos.dir;
+ if (pardir_parallel(rule_dir(p), localpos.dir)) {
+ rule.ht = height(p);
+ rule.dp = depth(p);
+ rule.wd = width(p);
+ } else {
+ rule.ht = width(p) / 2;
+ rule.dp = width(p) / 2;
+ rule.wd = height(p) + depth(p);
+ }
+ goto FIN_RULE;
+ break;
+ case whatsit_node:
+ /* Output the whatsit node |p| in |hlist_out| */
+ switch (subtype(p)) {
+ case pdf_save_pos_node:
+ pdf_last_pos = pdf->posstruct->pos;
+ pos_info.curpos = pdf->posstruct->pos;
+ pos_info.boxpos.pos = refpos->pos;
+ pos_info.boxpos.dir = localpos.dir;
+ pos_info.boxdim.wd = width(this_box);
+ pos_info.boxdim.ht = height(this_box);
+ pos_info.boxdim.dp = depth(this_box);
+ break;
+ /* |function(pdf, p, this_box, cur)|; too many args for |out_what()| */
+ case pdf_annot_node: /* |do_annot(pdf, p, this_box, cur);| */
+ case pdf_start_link_node: /* |do_link(pdf, p, this_box, cur);| */
+ case pdf_dest_node: /* |do_dest(pdf, p, this_box, cur);| */
+ case pdf_start_thread_node:
+ case pdf_thread_node: /* |do_thread(pdf, p, this_box, cur);| */
+ backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur);
+ break;
+ case pdf_refxform_node: /* |pdf_place_form(pdf, pdf_xform_objnum(p));| */
+ case pdf_refximage_node: /* |pdf_place_image(pdf, pdf_ximage_idx(p));| */
+ /* Output a Form node in a hlist */
+ /* Output an Image node in a hlist */
+ switch (localpos.dir) {
+ case dir_TLT:
+ pos_down(depth(p));
+ break;
+ case dir_TRT:
+ pos_left(width(p));
+ pos_down(depth(p));
+ break;
+ case dir_LTL:
+ pos_left(height(p));
+ pos_down(width(p));
+ break;
+ case dir_RTT:
+ pos_left(depth(p));
+ pos_down(width(p));
+ break;
+ }
+ backend_out_whatsit[subtype(p)] (pdf, p);
+ cur.h += width(p);
+ break;
+ case dir_node:
+ /* Output a reflection instruction if the direction has changed */
+ if (dir_dir(p) >= 0) {
+ /* Calculate the needed width to the matching |enddir|, return the |enddir| node,
+ with width info */
+ enddir_ptr =
+ calculate_width_to_enddir(p, cur_glue, cur_g,
+ this_box);
+ if (textdir_parallel(dir_dir(p), localpos.dir)) {
+ dir_cur_h(enddir_ptr) += cur.h;
+ if (textdir_opposite(dir_dir(p), localpos.dir))
+ cur.h = dir_cur_h(enddir_ptr);
+ } else
+ dir_cur_h(enddir_ptr) = cur.h;
+ if (enddir_ptr != p) { /* only if it is an enddir */
+ dir_cur_v(enddir_ptr) = cur.v;
+ dir_refpos_h(enddir_ptr) = refpos->pos.h;
+ dir_refpos_v(enddir_ptr) = refpos->pos.v;
+ dir_dir(enddir_ptr) = localpos.dir - 64; /* negative: mark it as |enddir| */
+ }
+ /* fake a nested |hlist_out| */
+ synch_pos_with_cur(pdf->posstruct, refpos, cur);
+ refpos->pos = pdf->posstruct->pos;
+ localpos.dir = dir_dir(p);
+ cur.h = 0;
+ cur.v = 0;
+ } else {
+ refpos->pos.h = dir_refpos_h(p);
+ refpos->pos.v = dir_refpos_v(p);
+ localpos.dir = dir_dir(p) + 64;
+ cur.h = dir_cur_h(p);
+ cur.v = dir_cur_v(p);
+ }
+ break;
+ default:
+ out_what(pdf, p);
+ }
+ break;
+ case glue_node:
+ /* (\pdfTeX) Move right or output leaders */
+
+ g = glue_ptr(p);
+ rule.wd = width(g) - cur_g;
+ if (g_sign != normal) {
+ if (g_sign == stretching) {
+ if (stretch_order(g) == g_order) {
+ cur_glue = cur_glue + stretch(g);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue); /* real multiplication */
+ cur_g = float_round(glue_temp);
+ }
+ } else if (shrink_order(g) == g_order) {
+ cur_glue = cur_glue - shrink(g);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue);
+ cur_g = float_round(glue_temp);
+ }
+ }
+ rule.wd = rule.wd + cur_g;
+ if (subtype(p) >= a_leaders) {
+ /* (\pdfTeX) Output leaders in an hlist, |goto fin_rule| if a rule
+ or to |next_p| if done */
+ leader_box = leader_ptr(p);
+ if (type(leader_box) == rule_node) {
+ rule.ht = height(leader_box);
+ rule.dp = depth(leader_box);
+ goto FIN_RULE;
+ }
+ if (textdir_parallel(box_dir(leader_box), localpos.dir))
+ leader_wd = width(leader_box);
+ else
+ leader_wd = height(leader_box) + depth(leader_box);
+ if ((leader_wd > 0) && (rule.wd > 0)) {
+ rule.wd = rule.wd + 10; /* compensate for floating-point rounding */
+ edge = cur.h + rule.wd;
+ lx = 0;
+ /* Let |cur.h| be the position of the first box, and set |leader_wd+lx|
+ to the spacing between corresponding parts of boxes */
+
+ if (subtype(p) == g_leaders) {
+ save_h = cur.h;
+ switch (localpos.dir) {
+ case dir_TLT:
+ cur.h += refpos->pos.h - shipbox_refpos.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ cur.h -= refpos->pos.h - shipbox_refpos.h;
+ break;
+ case dir_TRT:
+ cur.h =
+ refpos->pos.h - shipbox_refpos.h - cur.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ cur.h =
+ refpos->pos.h - shipbox_refpos.h - cur.h;
+ break;
+ case dir_LTL:
+ case dir_RTT:
+ cur.h =
+ refpos->pos.v - shipbox_refpos.v - cur.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ cur.h =
+ refpos->pos.v - shipbox_refpos.v - cur.h;
+ break;
+ }
+ if (cur.h < save_h)
+ cur.h += leader_wd;
+ } else if (subtype(p) == a_leaders) {
+ save_h = cur.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ if (cur.h < save_h)
+ cur.h += leader_wd;
+ } else {
+ lq = rule.wd / leader_wd; /* the number of box copies */
+ lr = rule.wd % leader_wd; /* the remaining space */
+ if (subtype(p) == c_leaders) {
+ cur.h += lr / 2;
+ } else {
+ lx = lr / (lq + 1);
+ cur.h += (lr - (lq - 1) * lx) / 2;
+ }
+ }
+
+ while (cur.h + leader_wd <= edge) {
+ /* (\pdfTeX) Output a leader box at |cur.h|,
+ then advance |cur.h| by |leader_wd+lx| */
+
+ if (pardir_parallel
+ (box_dir(leader_box), localpos.dir)) {
+ basepoint.v = 0;
+ if (textdir_opposite
+ (box_dir(leader_box), localpos.dir))
+ basepoint.h = width(leader_box);
+ else
+ basepoint.h = 0;
+ } else {
+ if (!is_mirrored(box_dir(leader_box))) {
+ if (partextdir_eq
+ (box_dir(leader_box), localpos.dir))
+ basepoint.h = height(leader_box);
+ else
+ basepoint.h = depth(leader_box);
+ } else {
+ if (partextdir_eq
+ (box_dir(leader_box), localpos.dir))
+ basepoint.h = depth(leader_box);
+ else
+ basepoint.h = height(leader_box);
+ }
+ if (partextdir_eq
+ (localpos.dir, box_dir(leader_box)))
+ basepoint.v = -(width(leader_box) / 2);
+ else
+ basepoint.v = (width(leader_box) / 2);
+ }
+ if (!is_mirrored(localpos.dir))
+ basepoint.v = basepoint.v + shift_amount(leader_box); /* shift the box `down' */
+ else
+ basepoint.v = basepoint.v - shift_amount(leader_box); /* shift the box `up' */
+ assert(cur.v == 0);
+ tmpcur.h = cur.h + basepoint.h;
+ tmpcur.v = basepoint.v;
+ synch_pos_with_cur(pdf->posstruct, refpos, tmpcur);
+ outer_doing_leaders = doing_leaders;
+ doing_leaders = true;
+ if (type(leader_box) == vlist_node)
+ vlist_out(pdf, leader_box);
+ else
+ hlist_out(pdf, leader_box);
+ doing_leaders = outer_doing_leaders;
+ cur.h += leader_wd + lx;
+ }
+ cur.h = edge - 10;
+ goto NEXTP;
+ }
+ }
+ goto MOVE_PAST;
+ break;
+ case margin_kern_node:
+ cur.h += width(p);
+ break;
+ case kern_node:
+ /* Record |kern_node| {\sl Sync\TeX} information */
+ if (int_par(synctex_code))
+ synctexkern(p, this_box);
+ cur.h += width(p);
+ break;
+ case math_node:
+ /* Record |math_node| {\sl Sync\TeX} information */
+ if (int_par(synctex_code))
+ synctexmath(p, this_box);
+ cur.h += surround(p);
+ break;
+ default:
+ break;
+ }
+ goto NEXTP;
+ FIN_RULE:
+ /* (\pdfTeX) Output a rule in an hlist */
+ if (is_running(rule.ht))
+ rule.ht = height(this_box);
+ if (is_running(rule.dp))
+ rule.dp = depth(this_box);
+ if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { /* we don't output empty rules */
+ switch (localpos.dir) {
+ case dir_TLT:
+ size.h = rule.wd;
+ size.v = rule.ht + rule.dp;
+ pos_down(rule.dp);
+ break;
+ case dir_TRT:
+ size.h = rule.wd;
+ size.v = rule.ht + rule.dp;
+ pos_left(size.h);
+ pos_down(rule.dp);
+ break;
+ case dir_LTL:
+ size.h = rule.ht + rule.dp;
+ size.v = rule.wd;
+ pos_left(rule.ht);
+ pos_down(size.v);
+ break;
+ case dir_RTT:
+ size.h = rule.ht + rule.dp;
+ size.v = rule.wd;
+ pos_left(rule.dp);
+ pos_down(size.v);
+ break;
+ default:;
+ }
+ backend_out[rule_node] (pdf, p, size); /* |pdf_place_rule(pdf, p, rule.ht + rule.dp, rule.wd);| */
+ }
+ MOVE_PAST:
+ cur.h += rule.wd;
+ /* Record horizontal |rule_node| or |glue_node| {\sl Sync\TeX} information */
+ if (int_par(synctex_code)) {
+ synch_pos_with_cur(pdf->posstruct, refpos, cur);
+ synctexhorizontalruleorglue(p, this_box);
+ }
+ NEXTP:
+ prev_p = p;
+ p = vlink(p);
+ synch_pos_with_cur(pdf->posstruct, refpos, cur);
+ }
+ }
+
+ /* Finish hlist {\sl Sync\TeX} information record */
+ if (int_par(synctex_code))
+ synctextsilh(this_box);
+
+ if (pdf->o_mode == OMODE_DVI) {
+ prune_movements(save_loc); /* DVI! */
+ if (cur_s > 0) { /* DVI! */
+ dvi_pop(save_loc); /* DVI! */
+ dvi = save_dvi; /* DVI! */
+ }
+ }
+ decr(cur_s);
+ pdf->posstruct = refpos;
+}
+
+@ @c
+void vlist_out(PDF pdf, halfword this_box)
+{
+ posstructure localpos; /* the position structure local within this function */
+ posstructure *refpos; /* the list origin pos. on the page, provided by the caller */
+
+ scaledpos cur, tmpcur, basepoint;
+ scaledpos size = { 0, 0 }; /* rule dimensions */
+ scaled effective_vertical;
+ scaled save_v; /* what |cur.v| should pop to */
+ scaled top_edge; /* the top coordinate for this box */
+ scaled edge; /* bottom boundary of leader space */
+ glue_ord g_order; /* applicable order of infinity for glue */
+ int g_sign; /* selects type of glue */
+ halfword p; /* current position in the vlist */
+ halfword leader_box; /* the leader box being replicated */
+ scaled leader_ht; /* height of leader box being replicated */
+ scaled lx; /* extra space between leader boxes */
+ boolean outer_doing_leaders; /* were we doing leaders? */
+ real glue_temp; /* glue value before rounding */
+ real cur_glue = 0.0; /* glue seen so far */
+ scaled cur_g = 0; /* rounded equivalent of |cur_glue| times the glue ratio */
+ scaled_whd rule;
+ int save_loc = 0; /* DVI! \.{DVI} byte location upon entry */
+ scaledpos save_dvi = { 0, 0 }; /* DVI! what |dvi| should pop to */
+
+ g_order = (glue_ord) glue_order(this_box);
+ g_sign = glue_sign(this_box);
+ p = list_ptr(this_box);
+
+ cur.h = 0;
+ cur.v = -height(this_box);
+ top_edge = cur.v;
+
+ refpos = pdf->posstruct;
+ pdf->posstruct = &localpos; /* use local structure for recursion */
+ localpos.dir = box_dir(this_box);
+ synch_pos_with_cur(pdf->posstruct, refpos, cur);
+
+ incr(cur_s);
+ if (cur_s > max_push)
+ max_push = cur_s;
+
+ if (pdf->o_mode == OMODE_DVI) {
+ if (cur_s > 0) { /* DVI! */
+ dvi_push(); /* DVI! */
+ save_dvi = dvi; /* DVI! */
+ }
+ save_loc = dvi_offset + dvi_ptr; /* DVI! */
+ }
+
+ /* Start vlist {\sl Sync\TeX} information record */
+ if (int_par(synctex_code))
+ synctexvlist(this_box);
+
+ /* Create thread for the current vbox if needed */
+ check_running_thread(pdf, this_box, cur);
+
+ while (p != null) {
+ if (is_char_node(p)) {
+ confusion("vlistout"); /* this can't happen */
+ } else {
+ /* Output the non-|char_node| |p| for |vlist_out| */
+
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ /* (\pdfTeX) Output a box in a vlist */
+
+ /* TODO: the direct test to switch between |width(p)| and |-width(p)|
+ is definately wrong, because it does not nest properly. But at least
+ it fixes a very obvious problem that otherwise occured with
+ \.{\\pardir TLT} in a document with \.{\\bodydir TRT}, and so it
+ will have to do for now.
+ */
+ if (pardir_parallel(box_dir(p), localpos.dir)) {
+ effective_vertical = height(p) + depth(p);
+ if ((type(p) == hlist_node) && is_mirrored(box_dir(p)))
+ basepoint.v = depth(p);
+ else
+ basepoint.v = height(p);
+ if (textdir_opposite(box_dir(p), localpos.dir))
+ basepoint.h = width(p);
+ else
+ basepoint.h = 0;
+ } else {
+ effective_vertical = width(p);
+ if (!is_mirrored(box_dir(p))) {
+ if (partextdir_eq(box_dir(p), localpos.dir))
+ basepoint.h = height(p);
+ else
+ basepoint.h = depth(p);
+ } else {
+ if (partextdir_eq(box_dir(p), localpos.dir))
+ basepoint.h = depth(p);
+ else
+ basepoint.h = height(p);
+ }
+ if (partextdir_eq(localpos.dir, box_dir(p)))
+ basepoint.v = 0;
+ else
+ basepoint.v = width(p);
+ }
+ basepoint.h = basepoint.h + shift_amount(p); /* shift the box `right' */
+ if (list_ptr(p) == null) {
+ cur.v += effective_vertical;
+ /* Record void list {\sl Sync\TeX} information */
+ if (int_par(synctex_code)) {
+ synch_pos_with_cur(pdf->posstruct, refpos, cur);
+ if (type(p) == vlist_node)
+ synctexvoidvlist(p, this_box);
+ else
+ synctexvoidhlist(p, this_box);
+ }
+ } else {
+ assert(cur.h == 0);
+ tmpcur.h = basepoint.h;
+ tmpcur.v = cur.v + basepoint.v;
+ synch_pos_with_cur(pdf->posstruct, refpos, tmpcur);
+ if (type(p) == vlist_node)
+ vlist_out(pdf, p);
+ else
+ hlist_out(pdf, p);
+ cur.v += effective_vertical;
+ }
+ break;
+ case rule_node:
+ if (rule_dir(p)<0)
+ rule_dir(p) = localpos.dir;
+ if (pardir_parallel(rule_dir(p), localpos.dir)) {
+ rule.ht = height(p);
+ rule.dp = depth(p);
+ rule.wd = width(p);
+ } else {
+ rule.ht = width(p) / 2;
+ rule.dp = width(p) / 2;
+ rule.wd = height(p) + depth(p);
+ }
+ goto FIN_RULE;
+ break;
+ case whatsit_node:
+ /* Output the whatsit node |p| in |vlist_out| */
+ switch (subtype(p)) {
+ case pdf_save_pos_node:
+ pdf_last_pos = pdf->posstruct->pos;
+ pos_info.curpos = pdf->posstruct->pos;
+ pos_info.boxpos.pos = refpos->pos;
+ pos_info.boxpos.dir = localpos.dir;
+ pos_info.boxdim.wd = width(this_box);
+ pos_info.boxdim.ht = height(this_box);
+ pos_info.boxdim.dp = depth(this_box);
+ break;
+ /* |function(pdf, p, this_box, cur)|; too many args for |out_what()| */
+ case pdf_annot_node: /* |do_annot(pdf, p, this_box, cur);| */
+ case pdf_start_link_node: /* |do_link(pdf, p, this_box, cur);| */
+ case pdf_dest_node: /* |do_dest(pdf, p, this_box, cur);| */
+ case pdf_start_thread_node:
+ case pdf_thread_node: /* |do_thread(pdf, p, this_box, cur);| */
+ backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur);
+ break;
+ case pdf_refxform_node: /* |pdf_place_form(pdf, pdf_xform_objnum(p));| */
+ case pdf_refximage_node: /* |pdf_place_image(pdf, pdf_ximage_idx(p));| */
+ /* Output a Form node in a vlist */
+ /* Output an Image node in a vlist */
+ switch (localpos.dir) {
+ case dir_TLT:
+ pos_down(height(p) + depth(p));
+ break;
+ case dir_TRT:
+ pos_left(width(p));
+ pos_down(height(p) + depth(p));
+ break;
+ case dir_LTL:
+ pos_down(width(p));
+ break;
+ case dir_RTT:
+ pos_left(height(p) + depth(p));
+ pos_down(width(p));
+ break;
+ default:
+ break;
+ }
+ backend_out_whatsit[subtype(p)] (pdf, p);
+ cur.v += height(p) + depth(p);
+ break;
+ default:
+ out_what(pdf, p);
+ }
+ break;
+ case glue_node:
+ /* (\pdfTeX) Move down or output leaders */
+ g = glue_ptr(p);
+ rule.ht = width(g) - cur_g;
+ if (g_sign != normal) {
+ if (g_sign == stretching) {
+ if (stretch_order(g) == g_order) {
+ cur_glue = cur_glue + stretch(g);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue); /* real multiplication */
+ cur_g = float_round(glue_temp);
+ }
+ } else if (shrink_order(g) == g_order) {
+ cur_glue = cur_glue - shrink(g);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue);
+ cur_g = float_round(glue_temp);
+ }
+ }
+ rule.ht = rule.ht + cur_g;
+ if (subtype(p) >= a_leaders) {
+ /* (\pdfTeX) Output leaders in a vlist, |goto fin_rule| if a rule or to |next_p| if done */
+ leader_box = leader_ptr(p);
+ if (type(leader_box) == rule_node) {
+ rule.wd = width(leader_box);
+ rule.dp = 0;
+ goto FIN_RULE;
+ }
+ leader_ht = height(leader_box) + depth(leader_box);
+ if ((leader_ht > 0) && (rule.ht > 0)) {
+ rule.ht = rule.ht + 10; /* compensate for floating-point rounding */
+ edge = cur.v + rule.ht;
+ lx = 0;
+ /* Let |cur.v| be the position of the first box, and set |leader_ht+lx|
+ to the spacing between corresponding parts of boxes */
+
+ if (subtype(p) == g_leaders) {
+ save_v = cur.v;
+ switch (localpos.dir) {
+ case dir_LTL:
+ cur.v += refpos->pos.h - shipbox_refpos.h;
+ cur.v = leader_ht * (cur.v / leader_ht);
+ cur.v -= refpos->pos.h - shipbox_refpos.h;
+ break;
+ case dir_RTT:
+ cur.v =
+ refpos->pos.h - shipbox_refpos.h - cur.v;
+ cur.v = leader_ht * (cur.v / leader_ht);
+ cur.v =
+ refpos->pos.h - shipbox_refpos.h - cur.v;
+ break;
+ case dir_TLT:
+ case dir_TRT:
+ cur.v =
+ refpos->pos.v - shipbox_refpos.v - cur.v;
+ cur.v = leader_ht * (cur.v / leader_ht);
+ cur.v =
+ refpos->pos.v - shipbox_refpos.v - cur.v;
+ break;
+ }
+ if (cur.v < save_v)
+ cur.v += leader_ht;
+ } else if (subtype(p) == a_leaders) {
+ save_v = cur.v;
+ cur.v =
+ top_edge +
+ leader_ht * ((cur.v - top_edge) / leader_ht);
+ if (cur.v < save_v)
+ cur.v += leader_ht;
+ } else {
+ lq = rule.ht / leader_ht; /* the number of box copies */
+ lr = rule.ht % leader_ht; /* the remaining space */
+ if (subtype(p) == c_leaders) {
+ cur.v += lr / 2;
+ } else {
+ lx = lr / (lq + 1);
+ cur.v += (lr - (lq - 1) * lx) / 2;
+ }
+ }
+
+ while (cur.v + leader_ht <= edge) {
+ /* (\pdfTeX) Output a leader box at |cur.v|,
+ then advance |cur.v| by |leader_ht+lx| */
+ assert(cur.h == 0);
+ tmpcur.h = shift_amount(leader_box);
+ tmpcur.v = cur.v + height(leader_box);
+ synch_pos_with_cur(pdf->posstruct, refpos, tmpcur);
+ outer_doing_leaders = doing_leaders;
+ doing_leaders = true;
+ if (type(leader_box) == vlist_node)
+ vlist_out(pdf, leader_box);
+ else
+ hlist_out(pdf, leader_box);
+ doing_leaders = outer_doing_leaders;
+ cur.v += leader_ht + lx;
+ }
+ cur.v = edge - 10;
+ goto NEXTP;
+ }
+ }
+ goto MOVE_PAST;
+ break;
+ case kern_node:
+ cur.v += width(p);
+ break;
+ default:
+ break;
+ }
+ goto NEXTP;
+ FIN_RULE:
+ /* (\pdfTeX) Output a rule in a vlist, |goto next_p| */
+ if (is_running(rule.wd))
+ rule.wd = width(this_box);
+ if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { /* we don't output empty rules */
+ switch (localpos.dir) {
+ case dir_TLT:
+ size.h = rule.wd;
+ size.v = rule.ht + rule.dp;
+ pos_down(size.v);
+ break;
+ case dir_TRT:
+ size.h = rule.wd;
+ size.v = rule.ht + rule.dp;
+ pos_left(size.h);
+ pos_down(size.v);
+ break;
+ case dir_LTL:
+ size.h = rule.ht + rule.dp;
+ size.v = rule.wd;
+ pos_down(size.v);
+ break;
+ case dir_RTT:
+ size.h = rule.ht + rule.dp;
+ size.v = rule.wd;
+ pos_left(size.h);
+ pos_down(size.v);
+ break;
+ default:;
+ }
+ backend_out[rule_node] (pdf, p, size); /* |pdf_place_rule(pdf, rule.ht, rule.wd);| */
+ cur.v += rule.ht + rule.dp;
+ }
+ goto NEXTP;
+ MOVE_PAST:
+ cur.v += rule.ht;
+ NEXTP:
+ p = vlink(p);
+ }
+ synch_pos_with_cur(pdf->posstruct, refpos, cur);
+ }
+ /* Finish vlist {\sl Sync\TeX} information record */
+ if (int_par(synctex_code))
+ synctextsilv(this_box);
+
+ if (pdf->o_mode == OMODE_DVI) {
+ prune_movements(save_loc); /* DVI! */
+ if (cur_s > 0) { /* DVI! */
+ dvi_pop(save_loc); /* DVI! */
+ dvi = save_dvi; /* DVI! */
+ }
+ }
+ decr(cur_s);
+ pdf->posstruct = refpos;
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h
new file mode 100644
index 00000000000..9b698ef9437
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.h
@@ -0,0 +1,34 @@
+/* pdfliteral.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfliteral.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFLITERAL_H
+# define PDFLITERAL_H
+
+
+# define set_pdf_literal_mode(A,B) pdf_literal_mode(A)=B
+# define set_pdf_literal_type(A,B) pdf_literal_type(A)=B
+# define set_pdf_literal_data(A,B) pdf_literal_data(A)=B
+
+extern void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn);
+extern void pdf_special(PDF pdf, halfword p);
+extern void pdf_out_literal(PDF pdf, halfword p);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w
new file mode 100644
index 00000000000..fbbd9b9cb37
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w
@@ -0,0 +1,154 @@
+% pdfliteral.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: pdfliteral.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfliteral.w $";
+
+@ @c
+void pdf_special(PDF pdf, halfword p)
+{
+ int old_setting; /* holds print |selector| */
+ str_number s;
+ old_setting = selector;
+ selector = new_string;
+ show_token_list(token_link(write_tokens(p)), null, -1);
+ selector = old_setting;
+ s = make_string();
+ pdf_literal(pdf, s, scan_special, true);
+ flush_str(s);
+}
+
+
+@ To ship out a \TeX\ box to PDF page description we need to implement
+|hlist_out|, |vlist_out| and |ship_out|, which are equivalent to
+the \TeX' original |hlist_out|, |vlist_out| and |ship_out| resp. But first we
+need to declare some procedures needed in |hlist_out| and |vlist_out|.
+
+@c
+void pdf_out_literal(PDF pdf, halfword p)
+{
+ int old_setting; /* holds print |selector| */
+ str_number s;
+ if (pdf_literal_type(p) == normal) {
+ old_setting = selector;
+ selector = new_string;
+ show_token_list(token_link(pdf_literal_data(p)), null, -1);
+ selector = old_setting;
+ s = make_string();
+ pdf_literal(pdf, s, pdf_literal_mode(p), false);
+ flush_str(s);
+ } else {
+ assert(pdf_literal_mode(p) != scan_special);
+ switch (pdf_literal_mode(p)) {
+ case set_origin:
+ pdf_goto_pagemode(pdf);
+ pdf_set_pos(pdf, pdf->posstruct->pos);
+ break;
+ case direct_page:
+ pdf_goto_pagemode(pdf);
+ break;
+ case direct_always:
+ pdf_end_string_nl(pdf);
+ break;
+ default:
+ confusion("literal1");
+ break;
+ }
+ lua_pdf_literal(pdf, pdf_literal_data(p));
+ }
+}
+
+@ test equality of start of strings
+@c
+static boolean str_in_cstr(str_number s, const char *r, unsigned i)
+{
+ const unsigned char *k, *l;
+ if ((unsigned) str_length(s) < i + strlen(r))
+ return false;
+ k = (const unsigned char *) r;
+ l = str_string(s) + i;
+ while ((*l) && (*k)) {
+ if (*l++ != *k++)
+ return false;
+ }
+ return true;
+}
+
+@ @c
+void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn)
+{
+ pool_pointer j = 0; /* current character code position, initialized to make the compiler happy */
+ if (s >= STRING_OFFSET) { /* needed for |out_save| */
+ j = 0;
+ if (literal_mode == scan_special) {
+ if (!(str_in_cstr(s, "PDF:", 0) || str_in_cstr(s, "pdf:", 0))) {
+ if (warn
+ &&
+ ((!(str_in_cstr(s, "SRC:", 0) || str_in_cstr(s, "src:", 0)))
+ || (str_length(s) == 0)))
+ tprint_nl("Non-PDF special ignored!");
+ return;
+ }
+ j = j + (pool_pointer) strlen("PDF:");
+ if (str_in_cstr(s, "direct:", strlen("PDF:"))) {
+ j = j + (pool_pointer) strlen("direct:");
+ literal_mode = direct_always;
+ } else if (str_in_cstr(s, "page:", strlen("PDF:"))) {
+ j = j + (pool_pointer) strlen("page:");
+ literal_mode = direct_page;
+ } else {
+ literal_mode = set_origin;
+ }
+ }
+ }
+ switch (literal_mode) {
+ case set_origin:
+ pdf_goto_pagemode(pdf);
+ pdf_set_pos(pdf, pdf->posstruct->pos);
+ break;
+ case direct_page:
+ pdf_goto_pagemode(pdf);
+ break;
+ case direct_always:
+ pdf_end_string_nl(pdf);
+ break;
+ default:
+ confusion("literal1");
+ break;
+ }
+ if (s >= STRING_OFFSET) {
+ unsigned char *ss = str_string(s);
+ size_t l = str_length(s) - (size_t) j;
+ if (l < max_single_pdf_print) {
+ pdf_out_block(pdf, (ss + j), l);
+ } else {
+
+ while (l--)
+ pdf_out(pdf, *(ss + j++));
+ }
+ } else {
+ assert(s < 256);
+ pdf_out(pdf, s);
+ }
+ pdf_print_nl(pdf);
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.h b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.h
new file mode 100644
index 00000000000..35325a1e8bb
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.h
@@ -0,0 +1,66 @@
+/* pdfobj.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfobj.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFOBJ_H
+# define PDFOBJ_H
+
+/* data structure for \.{\\pdfobj} and \.{\\pdfrefobj} */
+
+# define set_pdf_obj_objnum(A, B) pdf_obj_objnum(A) = (B)
+
+# define pdfmem_obj_size 5 /* size of memory in |mem| which |obj_data_ptr| holds */
+
+# define obj_obj_data(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 0] /* object data */
+# define obj_obj_stream_attr(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 1] /* additional attributes into stream dict */
+# define obj_obj_flags(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 2] /* stream/file flags */
+# define obj_obj_pdfcompresslevel(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 3] /* overrides \pdfcompresslevel */
+# define obj_obj_pdfoslevel(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 4] /* for object stream compression */
+
+/* define set_obj_obj_data(pdf, A, B) obj_obj_data((pdf), (A)) = (B) */
+/* define set_obj_obj_flags(pdf, A, B) obj_obj_flags((pdf), (A)) = (B) */
+/* define set_obj_obj_stream_attr(pdf, A, B) obj_obj_stream_attr((pdf), (A)) = (B) */
+/* define set_obj_obj_pdfcompresslevel(pdf, A, B) obj_obj_pdfcompresslevel((pdf), (A)) = (B) */
+/* define set_obj_obj_pdfoslevel(pdf, A, B) obj_obj_pdfoslevel((pdf), (A)) = (B) */
+
+/**********************************************************************/
+
+# define OBJ_FLAG_ISSTREAM (1 << 0)
+# define OBJ_FLAG_ISFILE (1 << 1)
+
+# define obj_obj_is_stream(pdf,A) ((obj_obj_flags((pdf), (A)) & OBJ_FLAG_ISSTREAM) != 0)
+# define set_obj_obj_is_stream(pdf,A) ((obj_obj_flags((pdf), (A)) |= OBJ_FLAG_ISSTREAM))
+# define unset_obj_obj_is_stream(pdf,A) ((obj_obj_flags((pdf), (A)) &= ~OBJ_FLAG_ISSTREAM))
+
+# define obj_obj_is_file(pdf,A) ((obj_obj_flags((pdf), (A)) & OBJ_FLAG_ISFILE) != 0)
+# define set_obj_obj_is_file(pdf,A) ((obj_obj_flags((pdf), (A)) |= OBJ_FLAG_ISFILE))
+# define unset_obj_obj_is_file(pdf,A) ((obj_obj_flags((pdf), (A)) &= ~OBJ_FLAG_ISFILE))
+
+/**********************************************************************/
+
+extern int pdf_last_obj;
+
+extern void init_obj_obj(PDF pdf, int k);
+extern void pdf_write_obj(PDF pdf, int n);
+extern void scan_obj(PDF pdf);
+extern void scan_refobj(PDF pdf);
+extern void pdf_ref_obj(PDF pdf, halfword p);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w
new file mode 100644
index 00000000000..ab3d1314024
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w
@@ -0,0 +1,214 @@
+% pdfobj.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfobj.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfobj.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#include "lua/luatex-api.h"
+
+int pdf_last_obj;
+
+@ write a raw PDF object
+
+@c
+void pdf_write_obj(PDF pdf, int k)
+{
+ lstring data;
+ const_lstring st;
+ size_t i, li; /* index into |data.s| */
+ int saved_compress_level = pdf->compress_level;
+ int os_level = 1; /* gives compressed objects for \.{\\pdfobjcompresslevel} $>$ 0 */
+ int l = 0; /* possibly a lua registry reference */
+ int ll = 0;
+ data.s = NULL;
+ if (obj_obj_pdfcompresslevel(pdf, k) > -1) /* -1 = "unset" */
+ pdf->compress_level = obj_obj_pdfcompresslevel(pdf, k);
+ if (obj_obj_pdfoslevel(pdf, k) > -1) /* -1 = "unset" */
+ os_level = obj_obj_pdfoslevel(pdf, k);
+ if (obj_obj_is_stream(pdf, k)) {
+ pdf_begin_dict(pdf, k, 0);
+ l = obj_obj_stream_attr(pdf, k);
+ if (l != LUA_NOREF) {
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, l);
+ assert(lua_isstring(Luas, -1));
+ st.s = lua_tolstring(Luas, -1, &li);
+ st.l = li;
+ for (i = 0; i < st.l; i++)
+ pdf_out(pdf, st.s[i]);
+ if (st.s[st.l - 1] != '\n')
+ pdf_out(pdf, '\n');
+ luaL_unref(Luas, LUA_REGISTRYINDEX, l);
+ obj_obj_stream_attr(pdf, k) = LUA_NOREF;
+ }
+ pdf_begin_stream(pdf);
+ } else
+ pdf_begin_obj(pdf, k, os_level);
+ l = obj_obj_data(pdf, k);
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX, l);
+ assert(lua_isstring(Luas, -1));
+ st.s = lua_tolstring(Luas, -1, &li);
+ st.l = li;
+ if (obj_obj_is_file(pdf, k)) {
+ boolean res = false; /* callback status value */
+ const char *fnam = NULL; /* callback found filename */
+ int callback_id;
+ /* st.s is also |\0|-terminated, even as lstring */
+ fnam = luatex_find_file(st.s, find_data_file_callback);
+ callback_id = callback_defined(read_data_file_callback);
+ if (fnam && callback_id > 0) {
+ boolean file_opened = false;
+ res = run_callback(callback_id, "S->bSd", fnam,
+ &file_opened, &data.s, &ll);
+ data.l = (size_t) ll;
+ if (!file_opened)
+ pdf_error("ext5", "cannot open file for embedding");
+ } else {
+ byte_file f; /* the data file's FILE* */
+ if (!fnam)
+ fnam = st.s;
+ if (!luatex_open_input
+ (&f, fnam, kpse_tex_format, FOPEN_RBIN_MODE, true))
+ pdf_error("ext5", "cannot open file for embedding");
+ res = read_data_file(f, &data.s, &ll);
+ data.l = (size_t) ll;
+ close_file(f);
+ }
+ if (data.l == 0L)
+ pdf_error("ext5", "empty file for embedding");
+ if (!res)
+ pdf_error("ext5", "error reading file for embedding");
+ tprint("<<");
+ tprint(st.s);
+ for (i = 0; i < data.l; i++)
+ pdf_out(pdf, data.s[i]);
+ if (!obj_obj_is_stream(pdf, k) && data.s[data.l - 1] != '\n')
+ pdf_out(pdf, '\n');
+ xfree(data.s);
+ tprint(">>");
+ } else {
+ for (i = 0; i < st.l; i++)
+ pdf_out(pdf, st.s[i]);
+ if (!obj_obj_is_stream(pdf, k) && st.s[st.l - 1] != '\n')
+ pdf_out(pdf, '\n');
+ }
+ if (obj_obj_is_stream(pdf, k))
+ pdf_end_stream(pdf);
+ else
+ pdf_end_obj(pdf);
+ luaL_unref(Luas, LUA_REGISTRYINDEX, l);
+ obj_obj_data(pdf, k) = LUA_NOREF;
+ pdf->compress_level = saved_compress_level;
+}
+
+@ @c
+void init_obj_obj(PDF pdf, int k)
+{
+ obj_obj_stream_attr(pdf, k) = LUA_NOREF;
+ obj_obj_data(pdf, k) = LUA_NOREF;
+ unset_obj_obj_is_stream(pdf, k);
+ unset_obj_obj_is_file(pdf, k);
+ obj_obj_pdfcompresslevel(pdf, k) = -1; /* unset */
+ obj_obj_pdfoslevel(pdf, k) = -1; /* unset */
+}
+
+@ 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}
+ is used with \.{\\immediate}, the object contents will be written out
+ immediately. Objects referenced in the current page are appended into
+ |pdf_obj_list|.
+
+@c
+void scan_obj(PDF pdf)
+{
+ int k;
+ lstring *st = NULL;
+ if (scan_keyword("reserveobjnum")) {
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ incr(pdf->obj_count);
+ pdf_create_obj(pdf, obj_type_obj, pdf->sys_obj_ptr + 1);
+ k = pdf->sys_obj_ptr;
+ } else {
+ if (scan_keyword("useobjnum")) {
+ scan_int();
+ k = cur_val;
+ check_obj_exists(pdf, obj_type_obj, k);
+ if (is_obj_scheduled(pdf, k) || obj_data_ptr(pdf, k) != 0)
+ luaL_error(Luas, "object in use");
+ } else {
+ incr(pdf->obj_count);
+ pdf_create_obj(pdf, obj_type_obj, pdf->sys_obj_ptr + 1);
+ k = pdf->sys_obj_ptr;
+ }
+ obj_data_ptr(pdf, k) = pdf_get_mem(pdf, pdfmem_obj_size);
+ init_obj_obj(pdf, k);
+ if (scan_keyword("uncompressed")) {
+ obj_obj_pdfcompresslevel(pdf, k) = 0; /* \pdfcompresslevel = 0 */
+ obj_obj_pdfoslevel(pdf, k) = 0;
+ }
+ if (scan_keyword("stream")) {
+ set_obj_obj_is_stream(pdf, k);
+ if (scan_keyword("attr")) {
+ scan_pdf_ext_toks();
+ st = tokenlist_to_lstring(def_ref, true);
+ flush_list(def_ref);
+ lua_pushlstring(Luas, (char *) st->s, st->l);
+ obj_obj_stream_attr(pdf, k) = luaL_ref(Luas, LUA_REGISTRYINDEX);
+ free_lstring(st);
+ st = NULL;
+ }
+ }
+ if (scan_keyword("file"))
+ set_obj_obj_is_file(pdf, k);
+ scan_pdf_ext_toks();
+ st = tokenlist_to_lstring(def_ref, true);
+ flush_list(def_ref);
+ lua_pushlstring(Luas, (char *) st->s, st->l);
+ obj_obj_data(pdf, k) = luaL_ref(Luas, LUA_REGISTRYINDEX);
+ free_lstring(st);
+ st = NULL;
+ }
+ pdf_last_obj = k;
+}
+
+@ @c
+#define tail cur_list.tail_field
+
+void scan_refobj(PDF pdf)
+{
+ scan_int();
+ check_obj_exists(pdf, obj_type_obj, cur_val);
+ new_whatsit(pdf_refobj_node);
+ pdf_obj_objnum(tail) = cur_val;
+}
+
+@ @c
+void pdf_ref_obj(PDF pdf, halfword p)
+{
+ if (!is_obj_scheduled(pdf, pdf_obj_objnum(p)))
+ addto_page_resources(pdf, obj_type_obj, pdf_obj_objnum(p));
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h
new file mode 100644
index 00000000000..2b0bd8712a2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.h
@@ -0,0 +1,28 @@
+/* pdfoutline.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfoutline.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFOUTLINE_H
+# define PDFOUTLINE_H
+
+extern void scan_pdfoutline(PDF pdf);
+extern int print_outlines(PDF pdf);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w
new file mode 100644
index 00000000000..90c9675ac5b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w
@@ -0,0 +1,240 @@
+% pdfoutline.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: pdfoutline.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfoutline.w $";
+
+@ Data structure of outlines; it's not able to write out outline entries
+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|
+
+@c
+#define pdfmem_outline_size 8 /* size of memory in |pdf->mem| which |obj_outline_ptr| points to */
+
+#define obj_outline_count obj_info /* count of all opened children */
+#define set_obj_outline_count(pdf,A,B) obj_outline_count(pdf,A)=B
+#define obj_outline_ptr obj_aux /* pointer to |pdf->mem| */
+#define set_obj_outline_ptr(pdf,A,B) obj_outline_ptr(pdf,A)=B
+
+#define obj_outline_title(pdf,A) pdf->mem[obj_outline_ptr(pdf,A)]
+#define obj_outline_parent(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 1]
+#define obj_outline_prev(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 2]
+#define obj_outline_next(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 3]
+#define obj_outline_first(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 4]
+#define obj_outline_last(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 5]
+#define obj_outline_action_objnum(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 6] /* object number of action */
+#define obj_outline_attr(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 7]
+
+#define set_obj_outline_action_objnum(pdf,A,B) obj_outline_action_objnum(pdf,A)=B
+#define set_obj_outline_title(pdf,A,B) obj_outline_title(pdf,A)=B
+#define set_obj_outline_prev(pdf,A,B) obj_outline_prev(pdf,A)=B
+#define set_obj_outline_next(pdf,A,B) obj_outline_next(pdf,A)=B
+#define set_obj_outline_first(pdf,A,B) obj_outline_first(pdf,A)=B
+#define set_obj_outline_last(pdf,A,B) obj_outline_last(pdf,A)=B
+#define set_obj_outline_parent(pdf,A,B) obj_outline_parent(pdf,A)=B
+#define set_obj_outline_attr(pdf,A,B) obj_outline_attr(pdf,A)=B
+
+@ @c
+static int open_subentries(PDF pdf, halfword p)
+{
+ int k, c;
+ int l, r;
+ k = 0;
+ if (obj_outline_first(pdf, p) != 0) {
+ l = obj_outline_first(pdf, p);
+ do {
+ incr(k);
+ c = open_subentries(pdf, l);
+ if (obj_outline_count(pdf, l) > 0)
+ k = k + c;
+ obj_outline_parent(pdf, l) = p;
+ r = obj_outline_next(pdf, l);
+ if (r == 0)
+ obj_outline_last(pdf, p) = l;
+ l = r;
+ } while (l != 0);
+ }
+ if (obj_outline_count(pdf, p) > 0)
+ obj_outline_count(pdf, p) = k;
+ else
+ obj_outline_count(pdf, p) = -k;
+ return k;
+}
+
+@ return number of outline entries in the same level with |p|
+
+@c
+static int outline_list_count(PDF pdf, pointer p)
+{
+ int k = 1;
+ while (obj_outline_prev(pdf, p) != 0) {
+ incr(k);
+ p = obj_outline_prev(pdf, p);
+ }
+ return k;
+}
+
+@ @c
+void scan_pdfoutline(PDF pdf)
+{
+ halfword p, q, r;
+ int i, j, k;
+ if (scan_keyword("attr")) {
+ scan_pdf_ext_toks();
+ r = def_ref;
+ } else {
+ r = 0;
+ }
+ p = scan_action(pdf);
+ if (scan_keyword("count")) {
+ scan_int();
+ i = cur_val;
+ } else {
+ i = 0;
+ }
+ scan_pdf_ext_toks();
+ q = def_ref;
+ pdf_new_obj(pdf, obj_type_others, 0, 1);
+ j = pdf->obj_ptr;
+ write_action(pdf, p);
+ pdf_end_obj(pdf);
+ delete_action_ref(p);
+ pdf_create_obj(pdf, obj_type_outline, 0);
+ k = pdf->obj_ptr;
+ set_obj_outline_ptr(pdf, k, pdf_get_mem(pdf, pdfmem_outline_size));
+ set_obj_outline_action_objnum(pdf, k, j);
+ set_obj_outline_count(pdf, k, i);
+ pdf_new_obj(pdf, obj_type_others, 0, 1);
+ {
+ char *s = tokenlist_to_cstring(q, true, NULL);
+ pdf_print_str_ln(pdf, s);
+ xfree(s);
+ }
+ delete_token_ref(q);
+ pdf_end_obj(pdf);
+ set_obj_outline_title(pdf, k, pdf->obj_ptr);
+ set_obj_outline_prev(pdf, k, 0);
+ set_obj_outline_next(pdf, k, 0);
+ set_obj_outline_first(pdf, k, 0);
+ set_obj_outline_last(pdf, k, 0);
+ set_obj_outline_parent(pdf, k, pdf->parent_outline);
+ set_obj_outline_attr(pdf, k, r);
+ if (pdf->first_outline == 0)
+ pdf->first_outline = k;
+ if (pdf->last_outline == 0) {
+ if (pdf->parent_outline != 0)
+ set_obj_outline_first(pdf, pdf->parent_outline, k);
+ } else {
+ set_obj_outline_next(pdf, pdf->last_outline, k);
+ set_obj_outline_prev(pdf, k, pdf->last_outline);
+ }
+ pdf->last_outline = k;
+ if (obj_outline_count(pdf, k) != 0) {
+ pdf->parent_outline = k;
+ pdf->last_outline = 0;
+ } else if ((pdf->parent_outline != 0) &&
+ (outline_list_count(pdf, k) ==
+ abs(obj_outline_count(pdf, pdf->parent_outline)))) {
+ j = pdf->last_outline;
+ do {
+ set_obj_outline_last(pdf, pdf->parent_outline, j);
+ j = pdf->parent_outline;
+ pdf->parent_outline = obj_outline_parent(pdf, pdf->parent_outline);
+ } while (!((pdf->parent_outline == 0) ||
+ (outline_list_count(pdf, j) <
+ abs(obj_outline_count(pdf, pdf->parent_outline)))));
+ if (pdf->parent_outline == 0)
+ pdf->last_outline = pdf->first_outline;
+ else
+ pdf->last_outline = obj_outline_first(pdf, pdf->parent_outline);
+ while (obj_outline_next(pdf, pdf->last_outline) != 0)
+ pdf->last_outline = obj_outline_next(pdf, pdf->last_outline);
+ }
+}
+
+@ In the end we must flush PDF objects that cannot be written out
+immediately after shipping out pages.
+
+@c
+int print_outlines(PDF pdf)
+{
+ int k, l, a;
+ int outlines;
+ if (pdf->first_outline != 0) {
+ pdf_new_dict(pdf, obj_type_others, 0, 1);
+ outlines = pdf->obj_ptr;
+ l = pdf->first_outline;
+ k = 0;
+ do {
+ incr(k);
+ a = open_subentries(pdf, l);
+ if (obj_outline_count(pdf, l) > 0)
+ k = k + a;
+ set_obj_outline_parent(pdf, l, pdf->obj_ptr);
+ l = obj_outline_next(pdf, l);
+ } while (l != 0);
+ pdf_printf(pdf, "/Type /Outlines\n");
+ pdf_indirect_ln(pdf, "First", pdf->first_outline);
+ pdf_indirect_ln(pdf, "Last", pdf->last_outline);
+ pdf_int_entry_ln(pdf, "Count", k);
+ pdf_end_dict(pdf);
+ /* Output PDF outline entries */
+
+ k = pdf->head_tab[obj_type_outline];
+ while (k != 0) {
+ if (obj_outline_parent(pdf, k) == pdf->parent_outline) {
+ if (obj_outline_prev(pdf, k) == 0)
+ pdf->first_outline = k;
+ if (obj_outline_next(pdf, k) == 0)
+ pdf->last_outline = k;
+ }
+ pdf_begin_dict(pdf, k, 1);
+ pdf_indirect_ln(pdf, "Title", obj_outline_title(pdf, k));
+ pdf_indirect_ln(pdf, "A", obj_outline_action_objnum(pdf, k));
+ if (obj_outline_parent(pdf, k) != 0)
+ pdf_indirect_ln(pdf, "Parent", obj_outline_parent(pdf, k));
+ if (obj_outline_prev(pdf, k) != 0)
+ pdf_indirect_ln(pdf, "Prev", obj_outline_prev(pdf, k));
+ if (obj_outline_next(pdf, k) != 0)
+ pdf_indirect_ln(pdf, "Next", obj_outline_next(pdf, k));
+ if (obj_outline_first(pdf, k) != 0)
+ pdf_indirect_ln(pdf, "First", obj_outline_first(pdf, k));
+ if (obj_outline_last(pdf, k) != 0)
+ pdf_indirect_ln(pdf, "Last", obj_outline_last(pdf, k));
+ if (obj_outline_count(pdf, k) != 0)
+ pdf_int_entry_ln(pdf, "Count", obj_outline_count(pdf, k));
+ if (obj_outline_attr(pdf, k) != 0) {
+ pdf_print_toks_ln(pdf, obj_outline_attr(pdf, k));
+ delete_token_ref(obj_outline_attr(pdf, k));
+ set_obj_outline_attr(pdf, k, null);
+ }
+ pdf_end_dict(pdf);
+ k = obj_link(pdf, k);
+ }
+
+ } else {
+ outlines = 0;
+ }
+ return outlines;
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c
deleted file mode 100644
index cde4f128c4e..00000000000
--- a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/* pdfpage.c
-
- Copyright 2006-2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <math.h>
-
-#include "ptexlib.h"
-
-static const char __svn_version[] =
- "$Id: pdfpage.c 2491 2009-06-14 13:11:08Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/pdf/pdfpage.c $";
-
-#define lround(a) (long) floor((a) + 0.5)
-#define setpdffloat(a,b,c) {(a).m = (b); (a).e = (c);}
-#define pdf2double(a) ((double) (a).m / exp10_arr[(a).e])
-
-/* eternal constants */
-#define one_bp ((double) 65536 * (double) 72.27 / 72) /* number of sp per 1bp */
-#define e_tj 3 /* must be 3; movements in []TJ are in fontsize/10^3 units */
-
-/* definitions from luatex.web */
-#define pdf_font_blink(a) font_tables[a]->_pdf_font_blink
-
-pdfstructure *pstruct = NULL;
-
-static long *exp10_arr = NULL;
-
-/**********************************************************************/
-
-static pdfstructure *new_pdfstructure(void)
-{
- return xmalloc(sizeof(pdfstructure));
-}
-
-static void calc_k1(pdfstructure * p)
-{
- p->k1 = exp10_arr[p->pdf.h.e] / one_bp;
-}
-
-static void calc_k2(pdfstructure * p)
-{
- p->tm[0].m =
- lround(pdf2double(p->hz) * pdf2double(p->ext) * exp10_arr[p->tm[0].e]);
- p->k2 =
- exp10_arr[e_tj +
- p->cw.e] / (exp10_arr[p->pdf.h.e] * pdf2double(p->fs) *
- pdf2double(p->tm[0]));
-}
-
-void pdf_page_init(void)
-{
- pdfstructure *p;
- int i, decimal_digits = fixed_decimal_digits;
- if (exp10_arr == NULL) {
- exp10_arr = xmalloc(10 * sizeof(long));
- exp10_arr[0] = 1;
- for (i = 1; i < 10; i++)
- exp10_arr[i] = 10 * exp10_arr[i - 1];
- }
- if (pstruct == NULL)
- pstruct = new_pdfstructure();
- p = pstruct;
- setpdffloat(p->pdf.h, 0, decimal_digits);
- setpdffloat(p->pdf.v, 0, decimal_digits);
- p->cw.e = 1;
- p->fs.e = decimal_digits + 2; /* "+ 2" makes less corrections inside []TJ */
- setpdffloat(p->hz, 1000, 3); /* m = 1000 = default = unexpanded, e must be 3 */
- setpdffloat(p->ext, 1000, 3); /* m = 1000 = default = unextended, e must be 3 */
- /* for placement outside BT...ET */
- setpdffloat(p->cm[0], 1, 0);
- setpdffloat(p->cm[1], 0, 0);
- setpdffloat(p->cm[2], 0, 0);
- setpdffloat(p->cm[3], 1, 0);
- setpdffloat(p->cm[4], 0, decimal_digits); /* horizontal movement on page */
- setpdffloat(p->cm[5], 0, decimal_digits); /* vertical movement on page */
- /* for placement inside BT...ET */
- setpdffloat(p->tm[0], exp10_arr[6], 6); /* mantissa holds HZ expand * ExtendFont */
- setpdffloat(p->tm[1], 0, 0);
- setpdffloat(p->tm[2], 0, 3); /* mantissa holds SlantFont, 0 = default */
- setpdffloat(p->tm[3], 1, 0);
- setpdffloat(p->tm[4], 0, decimal_digits); /* mantissa holds delta from pdf_bt_pos.h */
- setpdffloat(p->tm[5], 0, decimal_digits); /* mantissa holds delta from pdf_bt_pos.v */
- /* */
- p->f_cur = null_font;
- p->f_pdf = null_font;
- p->wmode = WMODE_H;
- p->mode = PMODE_PAGE;
- calc_k1(p);
-}
-
-/**********************************************************************/
-
-#ifdef SYNCH_POS_WITH_CUR
-/* some time this will be needed */
-void synch_pos_with_cur(scaledpos * pos, scaledpos * cur, scaledpos * box_pos)
-{
- switch (dvi_direction) {
- case dir_TL_:
- pos->h = box_pos->h + cur->h;
- pos->v = box_pos->v - cur->v;
- break;
- case dir_TR_:
- pos->h = box_pos->h - cur->h;
- pos->v = box_pos->v - cur->v;
- break;
- case dir_BL_:
- pos->h = box_pos->h + cur->h;
- pos->v = box_pos->v + cur->v;
- break;
- case dir_BR_:
- pos->h = box_pos->h - cur->h;
- pos->v = box_pos->v + cur->v;
- break;
- case dir_LT_:
- pos->h = box_pos->h + cur->v;
- pos->v = box_pos->v - cur->h;
- break;
- case dir_RT_:
- pos->h = box_pos->h - cur->v;
- pos->v = box_pos->v - cur->h;
- break;
- case dir_LB_:
- pos->h = box_pos->h + cur->v;
- pos->v = box_pos->v + cur->h;
- break;
- case dir_RB_:
- pos->h = box_pos->h - cur->v;
- pos->v = box_pos->v + cur->h;
- break;
- default:;
- }
-}
-#endif
-
-/**********************************************************************/
-
-boolean calc_pdfpos(pdfstructure * p, scaledpos * pos)
-{
- scaledpos new;
- int move_pdfpos = FALSE;
- switch (p->mode) {
- case PMODE_PAGE:
- new.h = lround(pos->h * p->k1);
- new.v = lround(pos->v * p->k1);
- p->cm[4].m = new.h - p->pdf.h.m; /* cm is concatenated */
- p->cm[5].m = new.v - p->pdf.v.m;
- if (new.h != p->pdf.h.m || new.v != p->pdf.v.m)
- move_pdfpos = TRUE;
- break;
- case PMODE_TEXT:
- new.h = lround(pos->h * p->k1);
- new.v = lround(pos->v * p->k1);
- p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* Tm replaces */
- p->tm[5].m = new.v - p->pdf_bt_pos.v.m;
- if (new.h != p->pdf.h.m || new.v != p->pdf.v.m)
- move_pdfpos = TRUE;
- break;
- case PMODE_CHAR:
- case PMODE_CHARARRAY:
- switch (p->wmode) {
- case WMODE_H:
- new.h = lround((pos->h * p->k1 - p->pdf_tj_pos.h.m) * p->k2);
- new.v = lround(pos->v * p->k1);
- p->tj_delta.m =
- -lround((new.h - p->cw.m) / exp10_arr[p->cw.e - p->tj_delta.e]);
- p->tm[5].m = new.v - p->pdf_bt_pos.v.m; /* p->tm[4] is meaningless */
- if (p->tj_delta.m != 0 || new.v != p->pdf.v.m)
- move_pdfpos = TRUE;
- break;
- case WMODE_V:
- new.h = lround(pos->h * p->k1);
- new.v = lround((p->pdf_tj_pos.v.m - pos->v * p->k1) * p->k2);
- p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* p->tm[5] is meaningless */
- p->tj_delta.m =
- -lround((new.v - p->cw.m) / exp10_arr[p->cw.e - p->tj_delta.e]);
- if (p->tj_delta.m != 0 || new.h != p->pdf.h.m)
- move_pdfpos = TRUE;
- break;
- default:
- assert(0);
- }
- break;
- default:
- assert(0);
- }
- return move_pdfpos;
-}
-
-/**********************************************************************/
-
-void print_pdffloat(pdffloat * f)
-{
- char a[24];
- int e = f->e, i, j;
- long l, m = f->m;
- if (m < 0) {
- pdf_printf("-");
- m *= -1;
- }
- l = m / exp10_arr[e];
- pdf_print_int(l);
- l = m % exp10_arr[e];
- if (l != 0) {
- pdf_printf(".");
- j = snprintf(a, 23, "%ld", l + exp10_arr[e]);
- assert(j < 23);
- for (i = e; i > 0; i--) {
- if (a[i] != '0')
- break;
- a[i] = '\0';
- }
- pdf_printf("%s", a + 1);
- }
-}
-
-static void print_pdf_matrix(pdffloat * tm)
-{
- int i;
- for (i = 0; i < 5; i++) {
- print_pdffloat(tm + i);
- pdf_printf(" ");
- }
- print_pdffloat(tm + i);
-}
-
-void pdf_print_cm(pdffloat * cm)
-{
- print_pdf_matrix(cm);
- pdf_printf(" cm\n");
-}
-
-static void pdf_print_tm(pdffloat * tm)
-{
- print_pdf_matrix(tm);
- pdf_printf(" Tm ");
-}
-
-static void set_pos(pdfstructure * p, scaledpos * pos)
-{
- boolean move;
- assert(is_pagemode(p));
- move = calc_pdfpos(p, pos);
- if (move == TRUE) {
- pdf_print_cm(p->cm);
- p->pdf.h.m += p->cm[4].m;
- p->pdf.v.m += p->cm[5].m;
- }
-}
-
-static void set_pos_temp(pdfstructure * p, scaledpos * pos)
-{
- boolean move;
- assert(is_pagemode(p));
- move = calc_pdfpos(p, pos);
- if (move == TRUE)
- pdf_print_cm(p->cm);
-}
-
-void pdf_set_pos(scaled h, scaled v)
-{
- scaledpos pos;
- pos.h = h;
- pos.v = v;
- set_pos(pstruct, &pos);
-}
-
-/**********************************************************************/
-
-static long pdf_char_width(pdfstructure * p, internal_font_number f, int i)
-{
- /* use exactly this formula also for calculating the /Width array values */
- return
- lround((double) char_width(f, i) / font_size(f) *
- exp10_arr[e_tj + p->cw.e]);
-}
-
-void pdf_print_charwidth(internal_font_number f, int i)
-{
- pdffloat cw;
- assert(pdf_font_blink(f) == null_font); /* must use unexpanded font! */
- cw.m = pdf_char_width(pstruct, f, i);
- cw.e = pstruct->cw.e;
- print_pdffloat(&cw);
-}
-
-/**********************************************************************/
-
-static void begin_text(pdfstructure * p)
-{
- assert(is_pagemode(p));
- p->pdf_bt_pos = p->pdf;
- pdf_printf("BT\n");
- p->mode = PMODE_TEXT;
-}
-
-static void end_text(pdfstructure * p)
-{
- assert(is_textmode(p));
- pdf_printf("ET\n");
- p->pdf = p->pdf_bt_pos;
- p->mode = PMODE_PAGE;
-}
-
-static void begin_charmode(pdfstructure * p)
-{
- assert(is_chararraymode(p));
- pdf_printf("(");
- p->mode = PMODE_CHAR;
-}
-
-static void end_charmode(pdfstructure * p)
-{
- assert(is_charmode(p));
- pdf_printf(")");
- p->mode = PMODE_CHARARRAY;
-}
-
-static void begin_chararray(pdfstructure * p)
-{
- assert(is_textmode(p));
- p->pdf_tj_pos = p->pdf;
- p->cw.m = 0;
- pdf_printf("[");
- p->mode = PMODE_CHARARRAY;
-}
-
-static void end_chararray(pdfstructure * p)
-{
- assert(is_chararraymode(p));
- pdf_printf("]TJ\n");
- p->pdf = p->pdf_tj_pos;
- p->mode = PMODE_TEXT;
-}
-
-void pdf_end_string_nl(void)
-{
- if (is_charmode(pstruct))
- end_charmode(pstruct);
- if (is_chararraymode(pstruct))
- end_chararray(pstruct);
-}
-
-/**********************************************************************/
-
-static void goto_pagemode(pdfstructure * p)
-{
- assert(p != NULL);
- if (!is_pagemode(p)) {
- if (is_charmode(p))
- end_charmode(p);
- if (is_chararraymode(p))
- end_chararray(p);
- if (is_textmode(p))
- end_text(p);
- assert(is_pagemode(p));
- }
-}
-
-void pdf_goto_pagemode(void)
-{
- goto_pagemode(pstruct);
-}
-
-static void goto_textmode(pdfstructure * p)
-{
- scaledpos origin = {
- 0, 0
- };
- if (!is_textmode(p)) {
- if (is_pagemode(p)) {
- set_pos(p, &origin); /* reset to page origin */
- begin_text(p);
- } else {
- if (is_charmode(p))
- end_charmode(p);
- if (is_chararraymode(p))
- end_chararray(p);
- }
- assert(is_textmode(p));
- }
-}
-
-void pos_finish(pdfstructure * p)
-{
- goto_pagemode(p);
-}
-
-/**********************************************************************/
-
-static void place_rule(pdfstructure * p, scaledpos * pos, scaled wd, scaled ht)
-{
- pdfpos dim;
- scaledpos tmppos = *pos;
- goto_pagemode(p);
- dim.h.m = lround(wd * p->k1);
- dim.h.e = p->pdf.h.e;
- dim.v.m = lround(ht * p->k1);
- dim.v.e = p->pdf.v.e;
- pdf_printf("q\n");
- if (ht <= one_bp) {
- tmppos.v += lround(0.5 * ht);
- set_pos_temp(p, &tmppos);
- pdf_printf("[]0 d 0 J ");
- print_pdffloat(&(dim.v));
- pdf_printf(" w 0 0 m ");
- print_pdffloat(&(dim.h));
- pdf_printf(" 0 l S\n");
- } else if (wd <= one_bp) {
- tmppos.h += lround(0.5 * wd);
- set_pos_temp(p, &tmppos);
- pdf_printf("[]0 d 0 J ");
- print_pdffloat(&(dim.h));
- pdf_printf(" w 0 0 m 0 ");
- print_pdffloat(&(dim.v));
- pdf_printf(" l S\n");
- } else {
- set_pos_temp(p, &tmppos);
- pdf_printf("0 0 ");
- print_pdffloat(&(dim.h));
- pdf_printf(" ");
- print_pdffloat(&(dim.v));
- pdf_printf(" re f\n");
- }
- pdf_printf("Q\n");
-}
-
-void pdf_place_rule(scaled h, scaled v, scaled wd, scaled ht)
-{
- scaledpos pos;
- pos.h = h;
- pos.v = v;
- place_rule(pstruct, &pos, wd, ht);
-}
-
-/**********************************************************************/
-
-static void setup_fontparameters(pdfstructure * p, internal_font_number f)
-{
- p->f_cur = f;
- p->f_pdf = pdf_set_font(f);
- p->tj_delta.e = p->cw.e - 1; /* "- 1" makes less corrections inside []TJ */
- /* no need to be more precise than TeX (1sp) */
- while (p->tj_delta.e > 0
- && (double) font_size(f) / exp10_arr[p->tj_delta.e + e_tj] < 0.5)
- p->tj_delta.e--; /* happens for very tiny fonts */
- assert(p->cw.e >= p->tj_delta.e); /* else we would need, e. g., exp10_arr[-1] */
- p->fs.m = lround(font_size(f) / one_bp * exp10_arr[p->fs.e]);
- p->hz.m = pdf_font_expand_ratio(f) + exp10_arr[p->hz.e];
- calc_k2(p);
-}
-
-static void set_textmatrix(pdfstructure * p, scaledpos * pos)
-{
- boolean move;
- assert(is_textmode(p));
- move = calc_pdfpos(p, pos);
- if (move == TRUE) {
- pdf_print_tm(p->tm);
- p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; /* Tm replaces */
- p->pdf.v.m = p->pdf_bt_pos.v.m + p->tm[5].m;
- }
-}
-
-static void set_font(pdfstructure * p)
-{
- pdf_printf("/F%d", (int) p->f_pdf);
- pdf_print_resname_prefix();
- pdf_printf(" ");
- print_pdffloat(&(p->fs));
- pdf_printf(" Tf ");
-}
-
-/**********************************************************************/
-
-static void
-place_glyph(pdfstructure * p, scaledpos * pos, internal_font_number f,
- integer c)
-{
- boolean move;
- if (f != p->f_cur || is_textmode(p) || is_pagemode(p)) {
- goto_textmode(p);
- if (f != p->f_cur)
- setup_fontparameters(p, f);
- set_font(p);
- set_textmatrix(p, pos);
- begin_chararray(p);
- }
- assert(is_charmode(p) || is_chararraymode(p));
- move = calc_pdfpos(p, pos);
- if (move == TRUE) {
- if ((p->wmode == WMODE_H
- && (p->pdf_bt_pos.v.m + p->tm[5].m) != p->pdf.v.m)
- || (p->wmode == WMODE_V
- && (p->pdf_bt_pos.h.m + p->tm[4].m) != p->pdf.h.m)
- || abs(p->tj_delta.m) >= 1000000) {
- goto_textmode(p);
- set_textmatrix(p, pos);
- begin_chararray(p);
- move = calc_pdfpos(p, pos);
- }
- if (move == TRUE) {
- assert((p->wmode == WMODE_H
- && (p->pdf_bt_pos.v.m + p->tm[5].m) == p->pdf.v.m)
- || (p->wmode == WMODE_V
- && (p->pdf_bt_pos.h.m + p->tm[4].m) == p->pdf.h.m));
- if (is_charmode(p))
- end_charmode(p);
- assert(p->tj_delta.m != 0);
- print_pdffloat(&(p->tj_delta));
- p->cw.m -= p->tj_delta.m * exp10_arr[p->cw.e - p->tj_delta.e];
- }
- }
- if (is_chararraymode(p))
- begin_charmode(p);
- pdf_print_char(f, c); /* this also does pdf_mark_char() */
- p->cw.m += pdf_char_width(p, p->f_pdf, c); /* aka adv_char_width() */
-}
-
-void pdf_place_glyph(internal_font_number f, integer c)
-{
- if (char_exists(f, c))
- place_glyph(pstruct, &pos, f, c);
-}
-
-/**********************************************************************/
-
-static void place_form(pdfstructure * p, scaledpos * pos, integer i)
-{
- goto_pagemode(p);
- pdf_printf("q\n");
- set_pos_temp(p, pos);
- pdf_printf("/Fm%d", (int) i);
- pdf_print_resname_prefix();
- pdf_printf(" Do\nQ\n");
-}
-
-void pdf_place_form(scaled h, scaled v, integer i)
-{
- scaledpos pos;
- pos.h = h;
- pos.v = v;
- place_form(pstruct, &pos, i);
-}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h
index 1c9ccb02569..39a15ab5ff9 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h
@@ -17,74 +17,37 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: pdfpage.h 2448 2009-06-08 07:43:50Z taco $ */
+/* $Id: pdfpage.h 3003 2009-08-16 19:55:55Z hhenkel $ */
#ifndef PDFPAGE_H
# define PDFPAGE_H
-typedef struct {
- long m; /* mantissa (significand) */
- int e; /* exponent * -1 */
-} pdffloat;
-
-typedef struct {
- pdffloat h;
- pdffloat v;
-} pdfpos;
-
-typedef enum { PMODE_NONE, PMODE_PAGE, PMODE_TEXT, PMODE_CHARARRAY,
- PMODE_CHAR
-} pos_mode;
-
-typedef enum { WMODE_H, WMODE_V } writing_mode; /* []TJ runs horizontal or vertical */
-
# define is_pagemode(p) ((p)->mode == PMODE_PAGE)
# define is_textmode(p) ((p)->mode == PMODE_TEXT)
# define is_chararraymode(p) ((p)->mode == PMODE_CHARARRAY)
# define is_charmode(p) ((p)->mode == PMODE_CHAR)
-# define setpdffloat(a,b,c) {(a).m = (b); (a).e = (c);}
+# define setpdffloat(a,b,c) do {(a).m = (b); (a).e = (c);} while (0)
# ifdef hz
/* AIX 4.3 defines hz as 100 in system headers */
# undef hz
# endif
-typedef struct {
- pdfpos pdf; /* pos. on page (PDF page raster) */
- pdfpos pdf_bt_pos; /* pos. at begin of BT-ET group (PDF page raster) */
- pdfpos pdf_tj_pos; /* pos. at begin of TJ array (PDF page raster) */
- pdffloat cw; /* pos. within [(..)..]TJ array (glyph raster);
- cw.e = fractional digits in /Widths array */
- pdffloat tj_delta; /* rel. movement in [(..)..]TJ array (glyph raster) */
- pdffloat fs; /* font size in PDF units */
- pdffloat hz; /* HZ expansion factor */
- pdffloat ext; /* ExtendFont factor */
- pdffloat cm[6]; /* cm array */
- pdffloat tm[6]; /* Tm array */
- double k1; /* conv. factor from TeX sp to PDF page raster */
- double k2; /* conv. factor from PDF page raster to TJ array raster */
- internal_font_number f_cur; /* TeX font number */
- internal_font_number f_pdf; /* /F* font number, of unexpanded base font! */
- writing_mode wmode; /* PDF writing mode WMode (horizontal/vertical) */
- pos_mode mode; /* current positioning mode */
-} pdfstructure;
-
-extern pdfstructure *pstruct;
-
/**********************************************************************/
-boolean calc_pdfpos(pdfstructure * p, scaledpos * pos);
-void pdf_end_string_nl(void);
-void pdf_goto_pagemode(void);
-void pdf_page_init(void);
-void pdf_place_form(scaled h, scaled v, integer i);
-void pdf_place_glyph(internal_font_number f, integer c);
-void pdf_place_rule(scaled h, scaled v, scaled wd, scaled ht);
-void pdf_print_charwidth(internal_font_number f, int i);
-void pdf_print_cm(pdffloat * cm);
-void pdf_set_pos(scaled h, scaled v);
-void pos_finish(pdfstructure * p);
-void print_pdffloat(pdffloat * f);
+void synch_pos_with_cur(posstructure * pos, posstructure * refpos,
+ scaledpos cur);
+
+boolean calc_pdfpos(pdfstructure * p, scaledpos pos);
+void pdf_end_string_nl(PDF pdf);
+void pdf_goto_pagemode(PDF pdf);
+void pdf_goto_textmode(PDF pdf);
+void init_pdf_pagecalculations(PDF pdf);
+void pdf_print_cm(PDF pdf, pdffloat * cm);
+void pdf_set_pos(PDF pdf, scaledpos pos);
+void pdf_set_pos_temp(PDF pdf, scaledpos pos);
+void print_pdffloat(PDF pdf, pdffloat f);
+void print_pdf_matrix(PDF pdf, pdffloat * tm);
#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w
new file mode 100644
index 00000000000..6b810a5cef6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w
@@ -0,0 +1,292 @@
+% pdfpage.w
+
+% Copyright 2006-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfpage.w 3571 2010-04-02 13:50:45Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfpage.w $";
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <math.h>
+
+#include "ptexlib.h"
+
+#define lround(a) (long) floor((a) + 0.5)
+
+@ eternal constants
+@c
+#define one_bp ((double) 65536 * (double) 72.27 / 72) /* number of sp per 1bp */
+
+@ @c
+void init_pdf_pagecalculations(PDF pdf)
+{
+ pdfstructure *p;
+ int decimal_digits = pdf->decimal_digits;
+ assert(pdf != NULL);
+ if (pdf->pstruct == NULL)
+ pdf->pstruct = xmalloc(sizeof(pdfstructure));
+ p = pdf->pstruct;
+ setpdffloat(p->pdf.h, 0, decimal_digits);
+ setpdffloat(p->pdf.v, 0, decimal_digits);
+ p->cw.e = 1;
+ p->fs_cur.e = p->fs.e = decimal_digits + 2; /* "+ 2" makes less corrections inside []TJ */
+ /* for placement outside BT...ET */
+ setpdffloat(p->cm[0], 1, 0);
+ setpdffloat(p->cm[1], 0, 0);
+ setpdffloat(p->cm[2], 0, 0);
+ setpdffloat(p->cm[3], 1, 0);
+ setpdffloat(p->cm[4], 0, decimal_digits); /* horizontal movement on page */
+ setpdffloat(p->cm[5], 0, decimal_digits); /* vertical movement on page */
+ /* for placement inside BT...ET */
+ setpdffloat(p->tm[0], ten_pow[6], 6); /* mantissa holds HZ expand * ExtendFont */
+ setpdffloat(p->tm[1], 0, 0);
+ setpdffloat(p->tm[2], 0, 3); /* mantissa holds SlantFont, 0 = default */
+ setpdffloat(p->tm[3], 1, 0);
+ setpdffloat(p->tm[4], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.h| */
+ setpdffloat(p->tm[5], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.v| */
+ /* */
+ p->f_pdf_cur = p->f_pdf = null_font;
+ p->fs_cur.m = p->fs.m = 0;
+ p->wmode = WMODE_H;
+ p->mode = PMODE_PAGE;
+ p->ishex = 0;
+ p->k1 = ten_pow[p->pdf.h.e] / one_bp;
+}
+
+@ @c
+void synch_pos_with_cur(posstructure * pos, posstructure * refpos,
+ scaledpos cur)
+{
+ switch (pos->dir) {
+ case dir_TLT:
+ pos->pos.h = refpos->pos.h + cur.h;
+ pos->pos.v = refpos->pos.v - cur.v;
+ break;
+ case dir_TRT:
+ pos->pos.h = refpos->pos.h - cur.h;
+ pos->pos.v = refpos->pos.v - cur.v;
+ break;
+ case dir_LTL:
+ pos->pos.h = refpos->pos.h + cur.v;
+ pos->pos.v = refpos->pos.v - cur.h;
+ break;
+ case dir_RTT:
+ pos->pos.h = refpos->pos.h - cur.v;
+ pos->pos.v = refpos->pos.v - cur.h;
+ break;
+ default:
+ assert(0);
+ }
+}
+
+@ @c
+boolean calc_pdfpos(pdfstructure * p, scaledpos pos)
+{
+ scaledpos new;
+ int move_pdfpos = FALSE;
+ switch (p->mode) {
+ case PMODE_PAGE:
+ new.h = lround(pos.h * p->k1);
+ new.v = lround(pos.v * p->k1);
+ p->cm[4].m = new.h - p->pdf.h.m; /* cm is concatenated */
+ p->cm[5].m = new.v - p->pdf.v.m;
+ if (new.h != p->pdf.h.m || new.v != p->pdf.v.m)
+ move_pdfpos = TRUE;
+ break;
+ case PMODE_TEXT:
+ new.h = lround(pos.h * p->k1);
+ new.v = lround(pos.v * p->k1);
+ p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* Tm replaces */
+ p->tm[5].m = new.v - p->pdf_bt_pos.v.m;
+ if (new.h != p->pdf.h.m || new.v != p->pdf.v.m)
+ move_pdfpos = TRUE;
+ break;
+ case PMODE_CHAR:
+ case PMODE_CHARARRAY:
+ switch (p->wmode) {
+ case WMODE_H:
+ new.h =
+ lround((pos.h * p->k1 - (double) p->pdf_tj_pos.h.m) * p->k2);
+ new.v = lround(pos.v * p->k1);
+ p->tj_delta.m = -lround((double)
+ ((new.h - p->cw.m) / ten_pow[p->cw.e -
+ p->
+ tj_delta.e]));
+ p->tm[5].m = new.v - p->pdf_bt_pos.v.m; /* p->tm[4] is meaningless */
+ if (p->tj_delta.m != 0 || new.v != p->pdf.v.m)
+ move_pdfpos = TRUE;
+ break;
+ case WMODE_V:
+ new.h = lround(pos.h * p->k1);
+ new.v =
+ lround(((double) p->pdf_tj_pos.v.m - pos.v * p->k1) * p->k2);
+ p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* p->tm[5] is meaningless */
+ p->tj_delta.m = -lround((double)
+ ((new.v - p->cw.m) / ten_pow[p->cw.e -
+ p->
+ tj_delta.e]));
+ if (p->tj_delta.m != 0 || new.h != p->pdf.h.m)
+ move_pdfpos = TRUE;
+ break;
+ default:
+ assert(0);
+ }
+ break;
+ default:
+ assert(0);
+ }
+ return move_pdfpos;
+}
+
+@ @c
+void print_pdffloat(PDF pdf, pdffloat f)
+{
+ char a[24];
+ int e = f.e, i, j;
+ long l, m = f.m;
+ if (m < 0) {
+ pdf_puts(pdf, "-");
+ m *= -1;
+ }
+ l = m / ten_pow[e];
+ pdf_print_int(pdf, l);
+ l = m % ten_pow[e];
+ if (l != 0) {
+ pdf_puts(pdf, ".");
+ j = snprintf(a, 23, "%ld", l + ten_pow[e]);
+ assert(j < 23);
+ for (i = e; i > 0; i--) {
+ if (a[i] != '0')
+ break;
+ a[i] = '\0';
+ }
+ pdf_puts(pdf, (a + 1));
+ }
+}
+
+@ @c
+void print_pdf_matrix(PDF pdf, pdffloat * tm)
+{
+ int i;
+ for (i = 0; i < 5; i++) {
+ print_pdffloat(pdf, tm[i]);
+ pdf_puts(pdf, " ");
+ }
+ print_pdffloat(pdf, tm[i]);
+}
+
+@ @c
+void pdf_print_cm(PDF pdf, pdffloat * cm)
+{
+ print_pdf_matrix(pdf, cm);
+ pdf_puts(pdf, " cm\n");
+}
+
+@ @c
+void pdf_set_pos(PDF pdf, scaledpos pos)
+{
+ boolean move;
+ pdfstructure *p = pdf->pstruct;
+ assert(is_pagemode(p));
+ move = calc_pdfpos(p, pos);
+ if (move == TRUE) {
+ pdf_print_cm(pdf, p->cm);
+ p->pdf.h.m += p->cm[4].m;
+ p->pdf.v.m += p->cm[5].m;
+ }
+}
+
+@ @c
+void pdf_set_pos_temp(PDF pdf, scaledpos pos)
+{
+ boolean move;
+ pdfstructure *p = pdf->pstruct;
+ assert(is_pagemode(p));
+ move = calc_pdfpos(p, pos);
+ if (move == TRUE)
+ pdf_print_cm(pdf, p->cm);
+}
+
+@ @c
+static void begin_text(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ assert(is_pagemode(p));
+ p->pdf_bt_pos = p->pdf;
+ pdf_puts(pdf, "BT\n");
+ p->mode = PMODE_TEXT;
+ p->f_pdf_cur = null_font; /* forces Tf operator */
+ p->fs_cur.m = 0;
+}
+
+static void end_text(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ assert(is_textmode(p));
+ pdf_puts(pdf, "ET\n");
+ p->pdf = p->pdf_bt_pos;
+ p->mode = PMODE_PAGE;
+}
+
+void pdf_end_string_nl(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ if (is_charmode(p))
+ end_charmode(pdf);
+ if (is_chararraymode(p))
+ end_chararray(pdf);
+}
+
+@ @c
+void pdf_goto_pagemode(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ assert(p != NULL);
+ if (!is_pagemode(p)) {
+ if (is_charmode(p))
+ end_charmode(pdf);
+ if (is_chararraymode(p))
+ end_chararray(pdf);
+ if (is_textmode(p))
+ end_text(pdf);
+ assert(is_pagemode(p));
+ }
+}
+
+void pdf_goto_textmode(PDF pdf)
+{
+ pdfstructure *p = pdf->pstruct;
+ scaledpos origin = {
+ 0, 0
+ };
+ if (!is_textmode(p)) {
+ if (is_pagemode(p)) {
+ pdf_set_pos(pdf, origin); /* reset to page origin */
+ begin_text(pdf);
+ } else {
+ if (is_charmode(p))
+ end_charmode(pdf);
+ if (is_chararraymode(p))
+ end_chararray(pdf);
+ }
+ assert(is_textmode(p));
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.h b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.h
new file mode 100644
index 00000000000..d1d13b77f00
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.h
@@ -0,0 +1,27 @@
+/* pdfrule.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfrule.h 3003 2009-08-16 19:55:55Z hhenkel $ */
+
+#ifndef PDFRULE_H
+# define PDFRULE_H
+
+void pdf_place_rule(PDF pdf, halfword p, scaledpos size);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w
new file mode 100644
index 00000000000..fc13da2c32e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w
@@ -0,0 +1,70 @@
+% pdfrule.w
+%
+% Copyright 2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfrule.w 3584 2010-04-02 17:45:55Z hhenkel $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfrule.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#include "pdf/pdfpage.h"
+
+#define lround(a) (long) floor((a) + 0.5)
+
+@ @c
+void pdf_place_rule(PDF pdf, halfword q, scaledpos size)
+{
+ pdfpos dim;
+ pdfstructure *p = pdf->pstruct;
+ scaledpos pos = pdf->posstruct->pos;
+ (void) q;
+ pdf_goto_pagemode(pdf);
+ dim.h.m = lround(size.h * p->k1);
+ dim.h.e = p->pdf.h.e;
+ dim.v.m = lround(size.v * p->k1);
+ dim.v.e = p->pdf.v.e;
+ pdf_printf(pdf, "q\n");
+ if (size.v <= one_bp) {
+ pos.v += (int) lround(0.5 * size.v);
+ pdf_set_pos_temp(pdf, pos);
+ pdf_printf(pdf, "[]0 d 0 J ");
+ print_pdffloat(pdf, dim.v);
+ pdf_printf(pdf, " w 0 0 m ");
+ print_pdffloat(pdf, dim.h);
+ pdf_printf(pdf, " 0 l S\n");
+ } else if (size.h <= one_bp) {
+ pos.h += (int) lround(0.5 * size.h);
+ pdf_set_pos_temp(pdf, pos);
+ pdf_printf(pdf, "[]0 d 0 J ");
+ print_pdffloat(pdf, dim.h);
+ pdf_printf(pdf, " w 0 0 m 0 ");
+ print_pdffloat(pdf, dim.v);
+ pdf_printf(pdf, " l S\n");
+ } else {
+ pdf_set_pos_temp(pdf, pos);
+ pdf_printf(pdf, "0 0 ");
+ print_pdffloat(pdf, dim.h);
+ pdf_printf(pdf, " ");
+ print_pdffloat(pdf, dim.v);
+ pdf_printf(pdf, " re f\n");
+ }
+ pdf_printf(pdf, "Q\n");
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h
new file mode 100644
index 00000000000..146b7e7e6c5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.h
@@ -0,0 +1,37 @@
+/* pdfsaverestore.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfsaverestore.h 3003 2009-08-16 19:55:55Z hhenkel $ */
+
+#ifndef PDFSAVERESTORE_H
+# define PDFSAVERESTORE_H
+
+/* stack for positions of \pdfsave */
+typedef struct {
+ scaledpos pos;
+ int matrix_stack;
+} pos_entry;
+extern pos_entry *pos_stack; /* the stack */
+extern int pos_stack_size; /* initially empty */
+extern int pos_stack_used; /* used entries */
+
+extern void pdf_out_save(PDF pdf, halfword p);
+extern void pdf_out_restore(PDF pdf, halfword p);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w
new file mode 100644
index 00000000000..c953b8242a5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w
@@ -0,0 +1,88 @@
+% pdfsaverestore.w
+%
+% Copyright 2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfsaverestore.w 3571 2010-04-02 13:50:45Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w $";
+
+#include "ptexlib.h"
+
+@ @c
+pos_entry *pos_stack = 0; /* the stack */
+int pos_stack_size = 0; /* initially empty */
+int pos_stack_used = 0; /* used entries */
+
+@ @c
+static void checkpdfsave(scaledpos pos)
+{
+ pos_entry *new_stack;
+
+ if (pos_stack_used >= pos_stack_size) {
+ pos_stack_size += STACK_INCREMENT;
+ new_stack = xtalloc((unsigned) pos_stack_size, pos_entry);
+ memcpy((void *) new_stack, (void *) pos_stack,
+ (unsigned) pos_stack_used * sizeof(pos_entry));
+ xfree(pos_stack);
+ pos_stack = new_stack;
+ }
+ pos_stack[pos_stack_used].pos.h = pos.h;
+ pos_stack[pos_stack_used].pos.v = pos.v;
+ if (page_mode) {
+ pos_stack[pos_stack_used].matrix_stack = matrix_stack_used;
+ }
+ pos_stack_used++;
+}
+
+@ @c
+static void checkpdfrestore(scaledpos pos)
+{
+ scaledpos diff;
+ if (pos_stack_used == 0) {
+ pdftex_warn("%s", "\\pdfrestore: missing \\pdfsave");
+ return;
+ }
+ pos_stack_used--;
+ diff.h = pos.h - pos_stack[pos_stack_used].pos.h;
+ diff.v = pos.v - pos_stack[pos_stack_used].pos.v;
+ if (diff.h != 0 || diff.v != 0) {
+ pdftex_warn("Misplaced \\pdfrestore by (%dsp, %dsp)", (int) diff.h,
+ (int) diff.v);
+ }
+ if (page_mode) {
+ matrix_stack_used = pos_stack[pos_stack_used].matrix_stack;
+ }
+}
+
+
+@ @c
+void pdf_out_save(PDF pdf, halfword p)
+{
+ (void) p;
+ checkpdfsave(pdf->posstruct->pos);
+ pdf_literal(pdf, 'q', set_origin, false);
+}
+
+@ @c
+void pdf_out_restore(PDF pdf, halfword p)
+{
+ (void) p;
+ checkpdfrestore(pdf->posstruct->pos);
+ pdf_literal(pdf, 'Q', set_origin, false);
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h
new file mode 100644
index 00000000000..c4900e07046
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.h
@@ -0,0 +1,52 @@
+/* pdfsetmatrix.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfsetmatrix.h 3217 2009-12-03 16:52:01Z taco $ */
+
+#ifndef PDFSETMATRIX_H
+# define PDFSETMATRIX_H
+
+# define set_pdf_setmatrix_data(A,B) pdf_setmatrix_data(A)=B
+
+typedef struct {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+} matrix_entry;
+
+extern matrix_entry *matrix_stack;
+extern int matrix_stack_size;
+extern int matrix_stack_used;
+
+
+scaled getllx(void);
+scaled getlly(void);
+scaled geturx(void);
+scaled getury(void);
+void matrixtransformpoint(scaled x, scaled y);
+void matrixtransformrect(scaled llx, scaled lly, scaled urx, scaled ury);
+boolean matrixused(void);
+void matrixrecalculate(scaled urx);
+
+extern void pdf_out_setmatrix(PDF pdf, halfword p);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w
new file mode 100644
index 00000000000..765ac0fb1e2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w
@@ -0,0 +1,238 @@
+% pdfsetmatrix.w
+%
+% Copyright 2009 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfsetmatrix.w 3571 2010-04-02 13:50:45Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w $";
+
+#include "ptexlib.h"
+
+@ stack for \.{\\pdfsetmatrix}
+
+@c
+matrix_entry *matrix_stack = NULL;
+int matrix_stack_size = 0;
+int matrix_stack_used = 0;
+
+@ @c
+boolean matrixused(void)
+{
+ return matrix_stack_used > 0;
+}
+
+void matrix_stack_room(void)
+{
+ matrix_entry *new_stack;
+
+ if (matrix_stack_used >= matrix_stack_size) {
+ matrix_stack_size += STACK_INCREMENT;
+ new_stack = xtalloc((unsigned) matrix_stack_size, matrix_entry);
+ memcpy((void *) new_stack, (void *) matrix_stack,
+ (unsigned) matrix_stack_used * sizeof(matrix_entry));
+ xfree(matrix_stack);
+ matrix_stack = new_stack;
+ }
+}
+
+@ \.{\\pdfsetmatrix{a b c d}}
+
+ |e| := pos.h
+
+ |f| := pos.v
+
+ |M_top|: current active matrix at the top of
+ the matrix stack
+
+ The origin of \.{\\pdfsetmatrix} is the current point.
+ The annotation coordinate system is the original
+ page coordinate system. When pdfTeX calculates
+ annotation rectangles it does not take into
+ account this transformations, it uses the original
+ coordinate system. To get the corrected values,
+ first we go back to the origin, perform the
+ transformation and go back:
+
+{\obeylines\obeyspaces\tt
+ ( 1 0 0 ) ( a b 0 ) ( 1 0 0 )
+ ( 0 1 0 ) x ( c d 0 ) x ( 0 1 0 ) x M\_top
+ ( -e -f 1 ) ( 0 0 1 ) ( e f 1 )
+
+ ( 1 0 0 ) ( a b 0 )
+ = ( 0 1 0 ) x ( c d 0 ) x M\_top
+ ( e f 1 ) ( -e -f 1 )
+
+ ( a b 0 )
+ = ( c d 0 ) x M\_top
+ ( e(1-a)-fc f(1-d)-eb 1 )
+}
+
+@c
+static void pdfsetmatrix(const char *in, scaledpos pos)
+{
+ /* Argument of \.{\\pdfsetmatrix} starts with |str_pool[in]| and ends
+ before |str_pool[pool_ptr]|. */
+
+ matrix_entry x, *y, *z;
+
+ if (page_mode) {
+ if (sscanf((const char *) in, " %lf %lf %lf %lf ",
+ &x.a, &x.b, &x.c, &x.d) != 4) {
+ pdftex_warn("Unrecognized format of \\pdfsetmatrix{%s}", in);
+ return;
+ }
+ /* calculate this transformation matrix */
+ x.e = (double) pos.h * (1.0 - x.a) - (double) pos.v * x.c;
+ x.f = (double) pos.v * (1.0 - x.d) - (double) pos.h * x.b;
+ matrix_stack_room();
+ z = &matrix_stack[matrix_stack_used];
+ if (matrix_stack_used > 0) {
+ y = &matrix_stack[matrix_stack_used - 1];
+ z->a = x.a * y->a + x.b * y->c;
+ z->b = x.a * y->b + x.b * y->d;
+ z->c = x.c * y->a + x.d * y->c;
+ z->d = x.c * y->b + x.d * y->d;
+ z->e = x.e * y->a + x.f * y->c + y->e;
+ z->f = x.e * y->b + x.f * y->d + y->f;
+ } else {
+ z->a = x.a;
+ z->b = x.b;
+ z->c = x.c;
+ z->d = x.d;
+ z->e = x.e;
+ z->f = x.f;
+ }
+ matrix_stack_used++;
+ }
+}
+
+@ Apply matrix to point (x,y)
+
+{\obeylines\obeyspaces\tt
+ ( a b 0 )
+ ( x y 1 ) x ( c d 0 ) = ( xa+yc+e xb+yd+f 1 )
+ ( e f 1 )
+}
+
+If \.{\\pdfsetmatrix} wasn't used, then return the value unchanged.
+
+@c
+/* Return values for matrix tranform functions */
+static scaled ret_llx;
+static scaled ret_lly;
+static scaled ret_urx;
+static scaled ret_ury;
+
+scaled getllx(void)
+{
+ return ret_llx;
+}
+
+scaled getlly(void)
+{
+ return ret_lly;
+}
+
+scaled geturx(void)
+{
+ return ret_urx;
+}
+
+scaled getury(void)
+{
+ return ret_ury;
+}
+
+@ @c
+static int last_llx;
+static int last_lly;
+static int last_urx;
+static int last_ury;
+
+#define DO_ROUND(x) ((x > 0) ? (x + .5) : (x - .5))
+#define DO_MIN(a, b) ((a < b) ? a : b)
+#define DO_MAX(a, b) ((a > b) ? a : b)
+
+void do_matrixtransform(scaled x, scaled y, scaled * retx, scaled * rety)
+{
+ matrix_entry *m = &matrix_stack[matrix_stack_used - 1];
+ double x_old = x;
+ double y_old = y;
+ double x_new = x_old * m->a + y_old * m->c + m->e;
+ double y_new = x_old * m->b + y_old * m->d + m->f;
+ *retx = (scaled) DO_ROUND(x_new);
+ *rety = (scaled) DO_ROUND(y_new);
+}
+
+void matrixtransformrect(scaled llx, scaled lly, scaled urx, scaled ury)
+{
+ scaled x1, x2, x3, x4, y1, y2, y3, y4;
+
+ if (page_mode && matrix_stack_used > 0) {
+ last_llx = llx;
+ last_lly = lly;
+ last_urx = urx;
+ last_ury = ury;
+ do_matrixtransform(llx, lly, &x1, &y1);
+ do_matrixtransform(llx, ury, &x2, &y2);
+ do_matrixtransform(urx, lly, &x3, &y3);
+ do_matrixtransform(urx, ury, &x4, &y4);
+ ret_llx = DO_MIN(DO_MIN(x1, x2), DO_MIN(x3, x4));
+ ret_lly = DO_MIN(DO_MIN(y1, y2), DO_MIN(y3, y4));
+ ret_urx = DO_MAX(DO_MAX(x1, x2), DO_MAX(x3, x4));
+ ret_ury = DO_MAX(DO_MAX(y1, y2), DO_MAX(y3, y4));
+ } else {
+ ret_llx = llx;
+ ret_lly = lly;
+ ret_urx = urx;
+ ret_ury = ury;
+ }
+}
+
+void matrixtransformpoint(scaled x, scaled y)
+{
+ if (page_mode && matrix_stack_used > 0) {
+ do_matrixtransform(x, y, &ret_llx, &ret_lly);
+ } else {
+ ret_llx = x;
+ ret_lly = y;
+ }
+}
+
+void matrixrecalculate(scaled urx)
+{
+ matrixtransformrect(last_llx, last_lly, urx, last_ury);
+}
+
+@ @c
+void pdf_out_setmatrix(PDF pdf, halfword p)
+{
+ scaledpos pos = pdf->posstruct->pos;
+ int old_setting; /* holds print |selector| */
+ str_number s;
+ old_setting = selector;
+ selector = new_string;
+ show_token_list(token_link(pdf_setmatrix_data(p)), null, -1);
+ pdfsetmatrix((char *) cur_string, pos);
+ tprint(" 0 0 cm");
+ selector = old_setting;
+ s = make_string();
+ pdf_literal(pdf, s, set_origin, false);
+ flush_str(s);
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h
new file mode 100644
index 00000000000..1070996a5ba
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.h
@@ -0,0 +1,30 @@
+/* pdfshipout.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfshipout.h 2977 2009-08-08 12:49:35Z hhenkel $ */
+
+#ifndef PDFSHIPOUT_H
+# define PDFSHIPOUT_H
+
+extern boolean is_shipping_page; /* set to |shipping_page| when |ship_out| starts */
+extern scaledpos shipbox_refpos; /* for \gleaders */
+
+extern void ship_out(PDF pdf, halfword p, boolean shipping_page);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w
new file mode 100644
index 00000000000..70809ef1b0f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w
@@ -0,0 +1,332 @@
+% pdfshipout.w
+
+% Copyright 2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfshipout.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfshipout.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define count(A) eqtb[count_base+(A)].cint
+#define h_offset dimen_par(h_offset_code)
+#define mag int_par(mag_code)
+#define page_bottom_offset dimen_par(page_bottom_offset_code)
+#define page_direction int_par(page_direction_code)
+#define page_height dimen_par(page_height_code)
+#define page_left_offset dimen_par(page_left_offset_code)
+#define page_right_offset dimen_par(page_right_offset_code)
+#define page_top_offset dimen_par(page_top_offset_code)
+#define page_width dimen_par(page_width_code)
+#define pdf_h_origin dimen_par(pdf_h_origin_code)
+#define pdf_v_origin dimen_par(pdf_v_origin_code)
+#define tracing_output int_par(tracing_output_code)
+#define tracing_stats int_par(tracing_stats_code)
+#define v_offset dimen_par(v_offset_code)
+
+scaledpos shipbox_refpos;
+
+@ |ship_out| is used to shipout a box to PDF or DVI mode.
+If |shipping_page| is not set then the output will be a Form object
+(only PDF), otherwise it will be a Page object.
+
+@c
+void ship_out(PDF pdf, halfword p, boolean shipping_page)
+{
+ /* output the box |p| */
+ int j, k; /* indices to first ten count registers */
+ int post_callback_id;
+ int pre_callback_id;
+ posstructure refpoint; /* the origin pos. on the page */
+ scaledpos cur = { 0, 0 };
+ refpoint.pos.h = 0;
+ refpoint.pos.v = 0;
+
+ ensure_output_state(pdf, ST_HEADER_WRITTEN);
+ fix_o_mode(pdf); /* this is only for complaining if \.{\\pdfoutput} has changed */
+ init_backend_functionpointers(pdf->o_mode);
+
+ pdf->f_cur = null_font;
+
+ /* Start sheet {\sl Sync\TeX} information record */
+ /* {\sl Sync\TeX}: we assume that |pdf_output| is properly set up */
+ if (int_par(synctex_code))
+ synctexsheet(mag);
+
+ pre_callback_id = callback_defined(start_page_number_callback);
+ post_callback_id = callback_defined(stop_page_number_callback);
+ if ((tracing_output > 0) && (pre_callback_id == 0)) {
+ tprint_nl("");
+ print_ln();
+ tprint("Completed box being shipped out");
+ }
+ is_shipping_page = shipping_page;
+ if (shipping_page) {
+ if (pre_callback_id > 0)
+ (void) run_callback(pre_callback_id, "->");
+ else if (pre_callback_id == 0) {
+ if (term_offset > max_print_line - 9)
+ print_ln();
+ else if ((term_offset > 0) || (file_offset > 0))
+ print_char(' ');
+ print_char('[');
+ j = 9;
+ while ((count(j) == 0) && (j > 0))
+ decr(j);
+ for (k = 0; k <= j; k++) {
+ print_int(count(k));
+ if (k < j)
+ print_char('.');
+ }
+ }
+ }
+ if ((tracing_output > 0) && shipping_page) {
+ print_char(']');
+ update_terminal();
+ begin_diagnostic();
+ show_box(p);
+ end_diagnostic(true);
+ }
+
+ /* Ship box |p| out */
+ if (shipping_page && box_dir(p) != page_direction)
+ pdf_warning("\\shipout",
+ "\\pagedir != \\bodydir; "
+ "\\box\\outputbox may be placed wrongly on the page.", true,
+ true);
+ /* Update the values of |max_h| and |max_v|; but if the page is too large, |goto done| */
+ /* Sometimes the user will generate a huge page because other error messages
+ are being ignored. Such pages are not output to the \.{dvi} file, since they
+ may confuse the printing software. */
+
+ if ((height(p) > max_dimen) || (depth(p) > max_dimen)
+ || (height(p) + depth(p) + v_offset > max_dimen)
+ || (width(p) + h_offset > max_dimen)) {
+ const char *hlp[] =
+ { "The page just created is more than 18 feet tall or",
+ "more than 18 feet wide, so I suspect something went wrong.",
+ NULL
+ };
+ tex_error("Huge page cannot be shipped out", hlp);
+ if (tracing_output <= 0) {
+ begin_diagnostic();
+ tprint_nl("The following box has been deleted:");
+ show_box(p);
+ end_diagnostic(true);
+ }
+ goto DONE;
+ }
+ if (height(p) + depth(p) + v_offset > max_v)
+ max_v = height(p) + depth(p) + v_offset;
+ if (width(p) + h_offset > max_h)
+ max_h = width(p) + h_offset;
+
+ /* Calculate page dimensions and margins */
+ if (is_shipping_page) {
+ if (page_width > 0)
+ cur_page_size.h = page_width;
+ else {
+ switch (page_direction) {
+ case dir_TLT:
+ cur_page_size.h = width(p) + 2 * page_left_offset;
+ break;
+ case dir_TRT:
+ cur_page_size.h = width(p) + 2 * page_right_offset;
+ break;
+ case dir_LTL:
+ cur_page_size.h = height(p) + depth(p) + 2 * page_left_offset;
+ break;
+ case dir_RTT:
+ cur_page_size.h = height(p) + depth(p) + 2 * page_right_offset;
+ break;
+ }
+ }
+ if (page_height > 0)
+ cur_page_size.v = page_height;
+ else {
+ switch (page_direction) {
+ case dir_TLT:
+ case dir_TRT:
+ cur_page_size.v = height(p) + depth(p) + 2 * page_top_offset;
+ break;
+ case dir_LTL:
+ case dir_RTT:
+ cur_page_size.v = width(p) + 2 * page_top_offset;
+ break;
+ }
+ }
+
+ /* Think in upright page/paper coordinates (page origin = lower left edge).
+ First preset |refpoint.pos| to the DVI origin (near upper left page edge). */
+
+ switch (pdf->o_mode) {
+ case OMODE_DVI:
+ refpoint.pos.h = one_true_inch;
+ refpoint.pos.v = cur_page_size.v - one_true_inch;
+ dvi = refpoint.pos;
+ break;
+ case OMODE_PDF:
+ case OMODE_LUA:
+ refpoint.pos.h = pdf_h_origin;
+ refpoint.pos.v = cur_page_size.v - pdf_v_origin;
+ break;
+ default:
+ assert(0);
+ }
+
+ /* Then shift |refpoint.pos| of the DVI origin depending on the
+ |page_direction| within the upright (TLT) page coordinate system */
+
+ switch (page_direction) {
+ case dir_TLT:
+ case dir_LTL:
+ refpoint.pos.h += h_offset;
+ refpoint.pos.v -= v_offset;
+ break;
+ case dir_TRT:
+ case dir_RTT:
+ refpoint.pos.h +=
+ cur_page_size.h - page_right_offset - one_true_inch;
+ refpoint.pos.v -= v_offset;
+ break;
+ }
+
+ /* Then switch to page box coordinate system; do |height(p)| movement,
+ to get the location of the box origin. */
+
+ pdf->posstruct->dir = page_direction;
+ cur.h = 0;
+ cur.v = height(p);
+ synch_pos_with_cur(pdf->posstruct, &refpoint, cur);
+ } else { /* shipping a /Form */
+ assert(pdf->o_mode == OMODE_PDF);
+ pdf->posstruct->dir = box_dir(p);
+ switch (pdf->posstruct->dir) {
+ case dir_TLT:
+ case dir_TRT:
+ cur_page_size.h = width(p);
+ cur_page_size.v = height(p) + depth(p);
+ break;
+ case dir_LTL:
+ case dir_RTT:
+ cur_page_size.h = height(p) + depth(p);
+ cur_page_size.v = width(p);
+ break;
+ }
+ switch (pdf->posstruct->dir) {
+ case dir_TLT:
+ pdf->posstruct->pos.h = 0;
+ pdf->posstruct->pos.v = depth(p);
+ break;
+ case dir_TRT:
+ pdf->posstruct->pos.h = width(p);
+ pdf->posstruct->pos.v = depth(p);
+ break;
+ case dir_LTL:
+ pdf->posstruct->pos.h = height(p);
+ pdf->posstruct->pos.v = width(p);
+ break;
+ case dir_RTT:
+ pdf->posstruct->pos.h = depth(p);
+ pdf->posstruct->pos.v = width(p);
+ break;
+ }
+ }
+
+ /* Now we are at the point on the page where the origin of the page box should go. */
+
+ shipbox_refpos = pdf->posstruct->pos; /* for \.{\\gleaders} */
+
+ switch (pdf->o_mode) {
+ case OMODE_DVI:
+ assert(shipping_page);
+ dvi_begin_page(pdf);
+ break;
+ case OMODE_PDF:
+ pdf_begin_page(pdf, shipping_page);
+ break;
+ case OMODE_LUA:
+ assert(shipping_page);
+ lua_begin_page(pdf);
+ break;
+ default:
+ assert(0);
+ }
+
+ switch (type(p)) {
+ case vlist_node:
+ vlist_out(pdf, p);
+ break;
+ case hlist_node:
+ hlist_out(pdf, p);
+ break;
+ default:
+ assert(0);
+ }
+
+ if (shipping_page)
+ incr(total_pages);
+ cur_s = -1;
+
+ /* Finish shipping */
+
+ switch (pdf->o_mode) {
+ case OMODE_DVI:
+ dvi_end_page(pdf);
+ break;
+ case OMODE_PDF:
+ pdf_end_page(pdf, shipping_page);
+ break;
+ case OMODE_LUA:
+ lua_end_page(pdf);
+ break;
+ default:
+ assert(0);
+ }
+
+ DONE:
+ if ((tracing_output <= 0) && (post_callback_id == 0) && shipping_page) {
+ print_char(']');
+ update_terminal();
+ }
+ dead_cycles = 0;
+ /* Flush the box from memory, showing statistics if requested */
+ if ((tracing_stats > 1) && (pre_callback_id == 0)) {
+ tprint_nl("Memory usage before: ");
+ print_int(var_used);
+ print_char('&');
+ print_int(dyn_used);
+ print_char(';');
+ }
+ flush_node_list(p);
+ if ((tracing_stats > 1) && (post_callback_id == 0)) {
+ tprint(" after: ");
+ print_int(var_used);
+ print_char('&');
+ print_int(dyn_used);
+ print_ln();
+ }
+ if (shipping_page && (post_callback_id > 0))
+ (void) run_callback(post_callback_id, "->");
+
+ /* Finish sheet {\sl Sync\TeX} information record */
+ if (int_par(synctex_code))
+ synctexteehs();
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.h b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h
new file mode 100644
index 00000000000..f44c6b2a7c6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h
@@ -0,0 +1,136 @@
+/* pdftables.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdftables.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFTABLES_H
+# define PDFTABLES_H
+
+typedef enum {
+ union_type_int,
+ union_type_cstring,
+} union_type;
+
+typedef struct {
+ union {
+ int int0;
+ char *str0;
+ } u;
+ union_type u_type; /* integer or char * in union above */
+ int objptr;
+} oentry;
+
+/*
+The cross-reference table |obj_tab| is an array of |obj_tab_size| of
+|obj_entry|. Each entry contains five integer fields and represents an object
+in PDF file whose object number is the index of this entry in |obj_tab|.
+Objects in |obj_tab| maybe linked into list; objects in such a linked list have
+the same type.
+*/
+
+/*
+The first field contains information representing identifier of this object.
+It is usally a number for most of object types, but it may be a string number
+for named destination or named thread.
+
+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. 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.
+
+The last field usually represents the pointer to some auxiliary data
+structure depending on the object type; however it may be used as a counter as
+well.
+*/
+
+# define obj_info(pdf,A) pdf->obj_tab[(A)].u.int0 /* information representing identifier of this object */
+# define obj_start(pdf,A) pdf->obj_tab[(A)].u.str0
+# define obj_link(pdf,A) pdf->obj_tab[(A)].int1 /* link to the next entry in linked list */
+# define obj_offset(pdf,A) pdf->obj_tab[(A)].int2 /* negative (flags), or byte offset for this object in PDF
+ output file, or object stream number for this object */
+# define obj_os_idx(pdf,A) pdf->obj_tab[(A)].int3 /* index of this object in object stream */
+# define obj_aux(pdf,A) pdf->obj_tab[(A)].v.int4 /* auxiliary pointer */
+# define obj_stop(pdf,A) pdf->obj_tab[(A)].v.str4
+# define obj_type(pdf,A) pdf->obj_tab[(A)].objtype
+
+# define obj_data_ptr obj_aux /* pointer to |pdf->mem| */
+
+# define set_obj_link(pdf,A,B) obj_link(pdf,A)=B
+# define set_obj_start(pdf,A,B) obj_start(pdf,A)=B
+# define set_obj_info(pdf,A,B) obj_info(pdf,A)=B
+# define set_obj_offset(pdf,A,B) obj_offset(pdf,A)=B
+# define set_obj_aux(pdf,A,B) obj_aux(pdf,A)=B
+# define set_obj_stop(pdf,A,B) obj_stop(pdf,A)=B
+# define set_obj_data_ptr(pdf,A,B) obj_data_ptr(pdf,A)=B
+
+# define set_obj_fresh(pdf,A) obj_offset(pdf,(A))=-2
+# define set_obj_scheduled(pdf,A) if (intcast(obj_offset(pdf,A))==-2) obj_offset(pdf,A)=-1
+# define is_obj_scheduled(pdf,A) (intcast(obj_offset(pdf,A))>-2)
+# define is_obj_written(pdf,A) (intcast(obj_offset(pdf,A))>-1)
+
+/* NOTE: The data structure definitions for the nodes on the typesetting side are
+ inside |nodes.h| */
+
+/* Some constants */
+# define inf_pk_dpi 72 /* min PK pixel density value from \.{texmf.cnf} */
+# define sup_pk_dpi 8000 /* max PK pixel density value from \.{texmf.cnf} */
+
+extern int find_obj(PDF pdf, int t, int i, boolean byname);
+extern void check_obj_exists(PDF pdf, int t, int n);
+extern int get_obj(PDF pdf, int t, int i, boolean byname);
+extern void pdf_create_obj(PDF pdf, int t, int i);
+extern int pdf_new_objnum(PDF pdf);
+
+extern void set_rect_dimens(PDF pdf, halfword p, halfword parent_box,
+ scaledpos cur, scaled_whd alt_rule, scaled margin);
+
+extern void libpdffinish(PDF);
+
+extern void dump_pdftex_data(PDF pdf);
+extern void undump_pdftex_data(PDF pdf);
+
+# define set_width(A, B) width(A) = (B)
+# define set_height(A, B) height(A) = (B)
+# define set_depth(A, B) depth(A) = (B)
+
+/* interface definitions for eqtb locations */
+# define pdf_minor_version int_par(pdf_minor_version_code)
+# define pdf_decimal_digits int_par(pdf_decimal_digits_code)
+# define pdf_gamma int_par(pdf_gamma_code)
+# define pdf_image_gamma int_par(pdf_image_gamma_code)
+# define pdf_image_hicolor int_par(pdf_image_hicolor_code)
+# define pdf_image_apply_gamma int_par(pdf_image_apply_gamma_code)
+# define pdf_objcompresslevel int_par(pdf_objcompresslevel_code)
+# define pdf_draftmode int_par(pdf_draftmode_code)
+# define pdf_inclusion_copy_font int_par(pdf_inclusion_copy_font_code)
+# define pdf_inclusion_errorlevel int_par(pdf_inclusion_errorlevel_code)
+# define pdf_replace_font int_par(pdf_replace_font_code)
+# define pdf_pk_resolution int_par(pdf_pk_resolution_code)
+# define pdf_pk_mode equiv(pdf_pk_mode_loc)
+# define pdf_unique_resname int_par(pdf_unique_resname_code)
+# define pdf_compress_level int_par(pdf_compress_level_code)
+# define pdf_move_chars int_par(pdf_move_chars_code)
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.w b/Build/source/texk/web2c/luatexdir/pdf/pdftables.w
new file mode 100644
index 00000000000..ef4787fb3b6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.w
@@ -0,0 +1,456 @@
+% pdftables.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdftables.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdftables.w $";
+
+#include "ptexlib.h"
+
+@ One AVL tree each for a few |obj_type| out of |0...PDF_OBJ_TYPE_MAX|
+
+@c
+/* mark which objects should be searchable through AVL tree */
+
+static int obj_in_tree[PDF_OBJ_TYPE_MAX + 1] = {
+ 0, /* |obj_type_font = 0|, */
+ 0, /* |obj_type_outline = 1|, */
+ 1, /* |obj_type_dest = 2|, */
+ 0, /* |obj_type_obj = 3|, */
+ 0, /* |obj_type_xform = 4|, */
+ 0, /* |obj_type_ximage = 5|, */
+ 1, /* |obj_type_thread = 6|, */
+ /* the ones below don't go into a linked list */
+ 0, /* |obj_type_pagestream = 7|, */
+ 1, /* |obj_type_page = 8|, */
+ 0, /* |obj_type_pages = 9|, */
+ 0, /* |obj_type_link = 10|, */
+ 0, /* |obj_type_bead = 11|, */
+ 0, /* |obj_type_annot = 12|, */
+ 0, /* |obj_type_objstm = 13|, */
+ 0 /* |obj_type_others = 14| */
+};
+
+@ AVL sort oentry into |avl_table[]|
+@c
+static int compare_info(const void *pa, const void *pb, void *param)
+{
+ const oentry *a, *b;
+ (void) param;
+ a = (const oentry *) pa;
+ b = (const oentry *) pb;
+ if (a->u_type == b->u_type) {
+ if (a->u_type == union_type_int)
+ return ((a->u.int0 <
+ b->u.int0 ? -1 : (a->u.int0 > b->u.int0 ? 1 : 0)));
+ else /* string type */
+ return strcmp(a->u.str0, b->u.str0);
+ } else if (a->u_type == union_type_int)
+ return -1;
+ else
+ return 1;
+}
+
+static void avl_put_obj(PDF pdf, int t, oentry * oe)
+{
+ void **pp;
+ assert(t >= 0 || t <= PDF_OBJ_TYPE_MAX || obj_in_tree[t] == 1);
+ if (pdf->obj_tree[t] == NULL) {
+ pdf->obj_tree[t] = avl_create(compare_info, NULL, &avl_xallocator);
+ if (pdf->obj_tree[t] == NULL)
+ pdftex_fail("avlstuff.c: avl_create() pdf->obj_tree failed");
+ }
+ pp = avl_probe(pdf->obj_tree[t], oe);
+ if (pp == NULL)
+ pdftex_fail("avlstuff.c: avl_probe() out of memory in insertion");
+}
+
+static void avl_put_int_obj(PDF pdf, int int0, int objptr, int t)
+{
+ oentry *oe;
+ oe = xtalloc(1, oentry);
+ oe->u.int0 = int0;
+ oe->u_type = union_type_int;
+ oe->objptr = objptr;
+ avl_put_obj(pdf, t, oe);
+}
+
+static void avl_put_str_obj(PDF pdf, char *str0, int objptr, int t)
+{
+ oentry *oe;
+ oe = xtalloc(1, oentry);
+ oe->u.str0 = str0; /* no xstrdup() here */
+ oe->u_type = union_type_cstring;
+ oe->objptr = objptr;
+ avl_put_obj(pdf, t, oe);
+}
+
+static int avl_find_int_obj(PDF pdf, int t, int i)
+{
+ oentry *p;
+ oentry tmp;
+ assert(t >= 0 || t <= PDF_OBJ_TYPE_MAX || obj_in_tree[t] == 1);
+ tmp.u.int0 = i;
+ tmp.u_type = union_type_int;
+ if (pdf->obj_tree[t] == NULL)
+ return 0;
+ p = (oentry *) avl_find(pdf->obj_tree[t], &tmp);
+ if (p == NULL)
+ return 0;
+ return p->objptr;
+}
+
+static int avl_find_str_obj(PDF pdf, int t, char *s)
+{
+ oentry *p;
+ oentry tmp;
+ assert(t >= 0 || t <= PDF_OBJ_TYPE_MAX || obj_in_tree[t] == 1);
+ tmp.u.str0 = s;
+ tmp.u_type = union_type_cstring;
+ if (pdf->obj_tree[t] == NULL)
+ return 0;
+ p = (oentry *) avl_find(pdf->obj_tree[t], &tmp);
+ if (p == NULL)
+ return 0;
+ return p->objptr;
+}
+
+@ Create an object with type |t| and identifier |i|
+
+@c
+void pdf_create_obj(PDF pdf, int t, int i)
+{
+ int a;
+ char *ss = NULL;
+ if (pdf->sys_obj_ptr == sup_obj_tab_size)
+ overflow("indirect objects table size", (unsigned) pdf->obj_tab_size);
+ if (pdf->sys_obj_ptr == pdf->obj_tab_size) {
+ a = pdf->obj_tab_size / 5;
+ if (pdf->obj_tab_size < sup_obj_tab_size - a)
+ pdf->obj_tab_size = pdf->obj_tab_size + a;
+ else
+ pdf->obj_tab_size = sup_obj_tab_size;
+ pdf->obj_tab =
+ xreallocarray(pdf->obj_tab, obj_entry,
+ (unsigned) pdf->obj_tab_size);
+ }
+ incr(pdf->sys_obj_ptr);
+ pdf->obj_ptr = pdf->sys_obj_ptr;
+ obj_info(pdf, pdf->obj_ptr) = i;
+ obj_type(pdf, pdf->obj_ptr) = t;
+ set_obj_fresh(pdf, pdf->obj_ptr);
+ obj_aux(pdf, pdf->obj_ptr) = 0;
+ if (i < 0) {
+ ss = makecstring(-i);
+ avl_put_str_obj(pdf, ss, pdf->obj_ptr, t);
+ } else
+ avl_put_int_obj(pdf, i, pdf->obj_ptr, t);
+ if (t <= HEAD_TAB_MAX) {
+ obj_link(pdf, pdf->obj_ptr) = pdf->head_tab[t];
+ pdf->head_tab[t] = pdf->obj_ptr;
+ if ((t == obj_type_dest) && (i < 0))
+ append_dest_name(pdf, makecstring(-obj_info(pdf, pdf->obj_ptr)),
+ pdf->obj_ptr);
+ }
+}
+@ @c
+int find_obj(PDF pdf, int t, int i, boolean byname)
+{
+ char *ss = NULL;
+ int ret;
+ assert(i >= 0); /* no tricks */
+ if (byname) {
+ ss = makecstring(i);
+ ret = avl_find_str_obj(pdf, t, ss);
+ free(ss);
+ } else {
+ ret = avl_find_int_obj(pdf, t, i);
+ }
+ return ret;
+}
+
+@ The following function finds an object with identifier |i| and type |t|.
+ Identifier |i| is either an integer or a token list index. If no
+ such object exists then it will be created. This function is used mainly to
+ find destination for link annotations and outlines; however it is also used
+ in |ship_out| (to check whether a Page object already exists) so we need
+ to declare it together with subroutines needed in |hlist_out| and
+ |vlist_out|.
+
+@c
+int get_obj(PDF pdf, int t, int i, boolean byname)
+{
+ int r;
+ str_number s;
+ assert(i >= 0);
+ if (byname > 0) {
+ s = tokens_to_string(i);
+ r = find_obj(pdf, t, s, true);
+ } else {
+ s = 0;
+ r = find_obj(pdf, t, i, false);
+ }
+ if (r == 0) {
+ if (byname > 0) {
+ pdf_create_obj(pdf, t, -s);
+ s = 0;
+ } else {
+ pdf_create_obj(pdf, t, i);
+ }
+ r = pdf->obj_ptr;
+ if (t == obj_type_dest)
+ set_obj_dest_ptr(pdf, r, null);
+ }
+ if (s != 0)
+ flush_str(s);
+ return r;
+}
+
+@ create a new object and return its number
+
+@c
+int pdf_new_objnum(PDF pdf)
+{
+ pdf_create_obj(pdf, obj_type_others, 0);
+ return pdf->obj_ptr;
+}
+
+void check_obj_exists(PDF pdf, int t, int objnum)
+{
+ if (objnum < 0 || objnum > pdf->obj_ptr)
+ pdf_error("ext1", "cannot find referenced object");
+ if (t != obj_type(pdf, objnum))
+ pdf_error("ext1", "referenced object has wrong type");
+}
+
+@ @c
+void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur,
+ scaled_whd alt_rule, scaled margin)
+{
+ scaledpos ll, ur; /* positions relative to cur */
+ scaledpos pos_ll, pos_ur, tmp;
+ posstructure localpos;
+ localpos.dir = pdf->posstruct->dir;
+ ll.h = 0; /* pdf contains current point on page */
+ if (is_running(alt_rule.dp))
+ ll.v = depth(parent_box) - cur.v;
+ else
+ ll.v = alt_rule.dp;
+ if (is_running(alt_rule.wd))
+ ur.h = width(parent_box) - cur.h;
+ else
+ ur.h = alt_rule.wd;
+ if (is_running(alt_rule.ht))
+ ur.v = -height(parent_box) - cur.v;
+ else
+ ur.v = -alt_rule.ht;
+
+ synch_pos_with_cur(&localpos, pdf->posstruct, ll);
+ pos_ll = localpos.pos;
+ synch_pos_with_cur(&localpos, pdf->posstruct, ur);
+ pos_ur = localpos.pos;
+
+ if (pos_ll.h > pos_ur.h) {
+ tmp.h = pos_ll.h;
+ pos_ll.h = pos_ur.h;
+ pos_ur.h = tmp.h;
+ }
+ if (pos_ll.v > pos_ur.v) {
+ tmp.v = pos_ll.v;
+ pos_ll.v = pos_ur.v;
+ pos_ur.v = tmp.v;
+ }
+ if (is_shipping_page && matrixused()) {
+ 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();
+ }
+ 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;
+}
+
+@ @c
+void libpdffinish(PDF pdf)
+{
+ fb_free(pdf);
+ xfree(pdf->job_id_string);
+ fm_free();
+ t1_free();
+ enc_free();
+ epdf_free();
+ ttf_free();
+ sfd_free();
+ glyph_unicode_free();
+ zip_free(pdf);
+}
+
+
+@ 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.
+
+@c
+void dump_pdftex_data(PDF pdf)
+{
+ int k, x;
+ pdf_object_list *l;
+ dumpimagemeta(); /* the image information array */
+ dump_int(pdf->mem_size);
+ dump_int(pdf->mem_ptr);
+ for (k = 1; k <= pdf->mem_ptr - 1; k++) {
+ x = pdf->mem[k];
+ dump_int(x);
+ }
+ print_ln();
+ print_int(pdf->mem_ptr - 1);
+ tprint(" words of pdf memory");
+ x = pdf->obj_tab_size;
+ dump_int(x);
+ x = pdf->obj_ptr;
+ dump_int(x);
+ x = pdf->sys_obj_ptr;
+ dump_int(x);
+ for (k = 1; k <= pdf->sys_obj_ptr; k++) {
+ x = obj_info(pdf, k);
+ dump_int(x);
+ x = obj_link(pdf, k);
+ dump_int(x);
+ x = obj_os_idx(pdf, k);
+ dump_int(x);
+ x = obj_aux(pdf, k);
+ dump_int(x);
+ x = obj_type(pdf, k);
+ dump_int(x);
+ }
+ print_ln();
+ print_int(pdf->sys_obj_ptr);
+ tprint(" indirect objects");
+ dump_int(pdf->obj_count);
+ dump_int(pdf->xform_count);
+ dump_int(pdf->ximage_count);
+ if ((l = get_page_resources_list(pdf, obj_type_obj)) != NULL) {
+ while (l != NULL) {
+ dump_int(l->info);
+ l = l->link;
+ }
+ }
+ dump_int(0); /* signal end of |obj_list| */
+ if ((l = get_page_resources_list(pdf, obj_type_xform)) != NULL) {
+ while (l != NULL) {
+ dump_int(l->info);
+ l = l->link;
+ }
+ }
+ dump_int(0); /* signal end of |xform_list| */
+ if ((l = get_page_resources_list(pdf, obj_type_ximage)) != NULL) {
+ while (l != NULL) {
+ dump_int(l->info);
+ l = l->link;
+ }
+ }
+ dump_int(0); /* signal end of |ximage_list| */
+ x = pdf->head_tab[obj_type_obj];
+ dump_int(x);
+ x = pdf->head_tab[obj_type_xform];
+ dump_int(x);
+ x = pdf->head_tab[obj_type_ximage];
+ dump_int(x);
+ dump_int(pdf_last_obj);
+ dump_int(pdf_last_xform);
+ dump_int(pdf_last_ximage);
+}
+
+@ And restoring the pdftex data structures from the format. The
+two function arguments to |undumpimagemeta| have been restored
+already in an earlier module.
+
+@c
+void undump_pdftex_data(PDF pdf)
+{
+ int k, x;
+ undumpimagemeta(pdf, pdf_minor_version, pdf_inclusion_errorlevel); /* the image information array */
+ undump_int(pdf->mem_size);
+ pdf->mem = xreallocarray(pdf->mem, int, (unsigned) pdf->mem_size);
+ undump_int(pdf->mem_ptr);
+ for (k = 1; k <= pdf->mem_ptr - 1; k++) {
+ undump_int(x);
+ pdf->mem[k] = (int) x;
+ }
+ undump_int(x);
+ pdf->obj_tab_size = x;
+ undump_int(x);
+ pdf->obj_ptr = x;
+ undump_int(x);
+ pdf->sys_obj_ptr = x;
+ for (k = 1; k <= pdf->sys_obj_ptr; k++) {
+ undump_int(x);
+ obj_info(pdf, k) = x;
+ undump_int(x);
+ obj_link(pdf, k) = x;
+ set_obj_offset(pdf, k, -1);
+ undump_int(x);
+ obj_os_idx(pdf, k) = x;
+ undump_int(x);
+ obj_aux(pdf, k) = x;
+ undump_int(x);
+ obj_type(pdf, k) = x;
+ }
+
+ undump_int(x);
+ pdf->obj_count = x;
+ undump_int(x);
+ pdf->xform_count = x;
+ undump_int(x);
+ pdf->ximage_count = x;
+ /* todo : the next 3 loops can be done much more efficiently */
+ undump_int(x);
+ while (x != 0) {
+ addto_page_resources(pdf, obj_type_obj, x);
+ undump_int(x);
+ }
+ undump_int(x);
+ while (x != 0) {
+ addto_page_resources(pdf, obj_type_xform, x);
+ undump_int(x);
+ }
+ undump_int(x);
+ while (x != 0) {
+ addto_page_resources(pdf, obj_type_ximage, x);
+ undump_int(x);
+ }
+
+ undump_int(x);
+ pdf->head_tab[obj_type_obj] = x;
+ undump_int(x);
+ pdf->head_tab[obj_type_xform] = x;
+ undump_int(x);
+ pdf->head_tab[obj_type_ximage] = x;
+ undump_int(pdf_last_obj);
+ undump_int(pdf_last_xform);
+ undump_int(pdf_last_ximage);
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.h b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.h
new file mode 100644
index 00000000000..45d50a4551f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.h
@@ -0,0 +1,71 @@
+/* pdfthread.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfthread.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFTHREAD_H
+# define PDFTHREADH
+
+/* data structure of threads; words 1..4 represent the coordinates of the corners */
+
+# define obj_thread_first obj_aux /* pointer to the first bead */
+
+/* data structure of beads */
+# define pdfmem_bead_size 5 /* size of memory in |pdf->mem| which |obj_bead_ptr| points to */
+
+# define set_pdf_thread_attr(A,B) pdf_thread_attr(A)=B
+# define set_pdf_thread_id(A,B) pdf_thread_id(A)=B
+# define set_pdf_thread_named_id(A,B) pdf_thread_named_id(A)=B
+
+# define obj_bead_ptr obj_aux /* pointer to |pdf->mem| */
+# define obj_bead_rect(pdf,A) pdf->mem[obj_bead_ptr(pdf,A)]
+# define obj_bead_page(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 1]
+# define obj_bead_next(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 2]
+# define obj_bead_prev(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 3]
+# define obj_bead_attr(pdf,A) pdf->mem[obj_bead_ptr(pdf,A) + 4]
+
+# define set_obj_bead_rect(pdf,A,B) obj_bead_rect(pdf,A)=B
+# define set_obj_bead_page(pdf,A,B) obj_bead_page(pdf,A)=B
+# define set_obj_bead_next(pdf,A,B) obj_bead_next(pdf,A)=B
+# define set_obj_bead_prev(pdf,A,B) obj_bead_prev(pdf,A)=B
+# define set_obj_bead_attr(pdf,A,B) obj_bead_attr(pdf,A)=B
+
+
+/* pointer to the corresponding whatsit node; |obj_bead_rect| is needed only when the bead
+ rectangle has been written out and after that |obj_bead_data| is not needed any more
+ so we can use this field for both */
+# define obj_bead_data obj_bead_rect
+# define set_obj_bead_data set_obj_bead_rect
+
+extern void append_bead(PDF pdf, halfword p);
+extern void do_thread(PDF pdf, halfword parent_box, halfword p, scaledpos cur);
+extern void append_thread(PDF pdf, halfword parent_box, scaledpos cur);
+extern void end_thread(PDF pdf, halfword p);
+extern void scan_thread_id(void);
+
+extern void thread_title(PDF pdf, int t);
+extern void pdf_fix_thread(PDF pdf, int t);
+extern void out_thread(PDF pdf, int t);
+
+extern void check_running_thread(PDF pdf, halfword this_box, scaledpos cur);
+extern void print_beads_list(PDF pdf);
+extern void print_bead_rectangles(PDF pdf);
+extern void flush_beads_list(void);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w
new file mode 100644
index 00000000000..e788a3cdf4f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w
@@ -0,0 +1,290 @@
+% pdfthread.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfthread.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfthread.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define pdf_thread_margin dimen_par(pdf_thread_margin_code)
+#define page_width dimen_par(page_width_code)
+#define page_height dimen_par(page_height_code)
+
+@ Threads are handled in similar way as link annotations
+@c
+void append_bead(PDF pdf, halfword p)
+{
+ int a, b, c, t;
+ if (!is_shipping_page)
+ pdf_error("ext4", "threads cannot be inside an XForm");
+ t = get_obj(pdf, obj_type_thread, pdf_thread_id(p), pdf_thread_named_id(p));
+ b = pdf_new_objnum(pdf);
+ obj_bead_ptr(pdf, b) = pdf_get_mem(pdf, pdfmem_bead_size);
+ set_obj_bead_page(pdf, b, pdf->last_page);
+ set_obj_bead_data(pdf, b, p);
+ if (pdf_thread_attr(p) != null)
+ set_obj_bead_attr(pdf, b, tokens_to_string(pdf_thread_attr(p)));
+ else
+ set_obj_bead_attr(pdf, b, 0);
+ if (obj_thread_first(pdf, t) == 0) {
+ obj_thread_first(pdf, t) = b;
+ set_obj_bead_next(pdf, b, b);
+ set_obj_bead_prev(pdf, b, b);
+ } else {
+ a = obj_thread_first(pdf, t);
+ c = obj_bead_prev(pdf, a);
+ set_obj_bead_prev(pdf, b, c);
+ set_obj_bead_next(pdf, b, a);
+ set_obj_bead_prev(pdf, a, b);
+ set_obj_bead_next(pdf, c, b);
+ }
+ addto_page_resources(pdf, obj_type_bead, b);
+}
+
+@ @c
+void do_thread(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
+{
+ scaled_whd alt_rule;
+ if ((type(p) == hlist_node) && (subtype(p) == pdf_start_thread_node))
+ pdf_error("ext4", "\\pdfstartthread ended up in hlist");
+ if (doing_leaders)
+ return;
+ if (subtype(p) == pdf_start_thread_node) {
+ pdf->thread.wd = width(p);
+ pdf->thread.ht = height(p);
+ pdf->thread.dp = depth(p);
+ pdf->last_thread_id = pdf_thread_id(p);
+ pdf->last_thread_named_id = (pdf_thread_named_id(p) > 0);
+ if (pdf->last_thread_named_id)
+ add_token_ref(pdf_thread_id(p));
+ pdf->thread_level = cur_s;
+ }
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_thread_margin);
+ append_bead(pdf, p);
+ pdf->last_thread = p;
+}
+
+@ @c
+void append_thread(PDF pdf, halfword parent_box, scaledpos cur)
+{
+ halfword p;
+ scaled_whd alt_rule;
+ p = new_node(whatsit_node, pdf_thread_data_node);
+ width(p) = pdf->thread.wd;
+ height(p) = pdf->thread.ht;
+ depth(p) = pdf->thread.dp;
+ pdf_thread_attr(p) = null;
+ pdf_thread_id(p) = pdf->last_thread_id;
+ if (pdf->last_thread_named_id) {
+ add_token_ref(pdf_thread_id(p));
+ pdf_thread_named_id(p) = 1;
+ } else {
+ pdf_thread_named_id(p) = 0;
+ }
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_thread_margin);
+ append_bead(pdf, p);
+ pdf->last_thread = p;
+}
+
+@ @c
+void end_thread(PDF pdf, halfword p)
+{
+ scaledpos pos = pdf->posstruct->pos;
+ if (type(p) == hlist_node)
+ pdf_error("ext4", "\\pdfendthread ended up in hlist");
+ if (pdf->thread_level != cur_s)
+ pdf_error("ext4",
+ "\\pdfendthread ended up in different nesting level than \\pdfstartthread");
+ if (is_running(pdf->thread.dp) && (pdf->last_thread != null)) {
+ switch (pdf->posstruct->dir) {
+ case dir_TLT:
+ case dir_TRT:
+ pdf_ann_bottom(pdf->last_thread) = pos.v - pdf_thread_margin;
+ break;
+ case dir_LTL:
+ pdf_ann_right(pdf->last_thread) = pos.h + pdf_thread_margin;
+ break;
+ case dir_RTT:
+ pdf_ann_left(pdf->last_thread) = pos.h - pdf_thread_margin;
+ break;
+ }
+ }
+ if (pdf->last_thread_named_id)
+ delete_token_ref(pdf->last_thread_id);
+ pdf->last_thread = null;
+}
+
+@ The following function are needed for outputing article thread.
+@c
+void thread_title(PDF pdf, int t)
+{
+ pdf_printf(pdf, "/Title (");
+ if (obj_info(pdf, t) < 0)
+ pdf_print(pdf, -obj_info(pdf, t));
+ else
+ pdf_print_int(pdf, obj_info(pdf, t));
+ pdf_printf(pdf, ")\n");
+}
+
+void pdf_fix_thread(PDF pdf, int t)
+{
+ halfword a;
+ pdf_warning("thread", "destination", false, false);
+ if (obj_info(pdf, t) < 0) {
+ tprint("name{");
+ print(-obj_info(pdf, t));
+ tprint("}");
+ } else {
+ tprint("num");
+ print_int(obj_info(pdf, t));
+ }
+ tprint(" has been referenced but does not exist, replaced by a fixed one");
+ print_ln();
+ print_ln();
+ pdf_new_dict(pdf, obj_type_others, 0, 0);
+ a = pdf->obj_ptr;
+ pdf_indirect_ln(pdf, "T", t);
+ pdf_indirect_ln(pdf, "V", a);
+ pdf_indirect_ln(pdf, "N", a);
+ pdf_indirect_ln(pdf, "P", pdf->last_page);
+ pdf_printf(pdf, "/R [0 0 ");
+ pdf_print_bp(pdf, page_width);
+ pdf_out(pdf, ' ');
+ pdf_print_bp(pdf, page_height);
+ pdf_printf(pdf, "]\n");
+ pdf_end_dict(pdf);
+ pdf_begin_dict(pdf, t, 1);
+ pdf_printf(pdf, "/I << \n");
+ thread_title(pdf, t);
+ pdf_printf(pdf, ">>\n");
+ pdf_indirect_ln(pdf, "F", a);
+ pdf_end_dict(pdf);
+}
+
+void out_thread(PDF pdf, int t)
+{
+ halfword a, b;
+ int last_attr;
+ if (obj_thread_first(pdf, t) == 0) {
+ pdf_fix_thread(pdf, t);
+ return;
+ }
+ pdf_begin_dict(pdf, t, 1);
+ a = obj_thread_first(pdf, t);
+ b = a;
+ last_attr = 0;
+ do {
+ if (obj_bead_attr(pdf, a) != 0)
+ last_attr = obj_bead_attr(pdf, a);
+ a = obj_bead_next(pdf, a);
+ } while (a != b);
+ if (last_attr != 0) {
+ pdf_print_ln(pdf, last_attr);
+ } else {
+ pdf_printf(pdf, "/I << \n");
+ thread_title(pdf, t);
+ pdf_printf(pdf, ">>\n");
+ }
+ pdf_indirect_ln(pdf, "F", a);
+ pdf_end_dict(pdf);
+ do {
+ pdf_begin_dict(pdf, a, 1);
+ if (a == b)
+ pdf_indirect_ln(pdf, "T", t);
+ pdf_indirect_ln(pdf, "V", obj_bead_prev(pdf, a));
+ pdf_indirect_ln(pdf, "N", obj_bead_next(pdf, a));
+ pdf_indirect_ln(pdf, "P", obj_bead_page(pdf, a));
+ pdf_indirect_ln(pdf, "R", obj_bead_rect(pdf, a));
+ pdf_end_dict(pdf);
+ a = obj_bead_next(pdf, a);
+ } while (a != b);
+}
+
+
+@ @c
+void scan_thread_id(void)
+{
+ if (scan_keyword("num")) {
+ scan_int();
+ if (cur_val <= 0)
+ pdf_error("ext1", "num identifier must be positive");
+ if (cur_val > max_halfword)
+ pdf_error("ext1", "number too big");
+ set_pdf_thread_id(cur_list.tail_field, cur_val);
+ set_pdf_thread_named_id(cur_list.tail_field, 0);
+ } else if (scan_keyword("name")) {
+ scan_pdf_ext_toks();
+ set_pdf_thread_id(cur_list.tail_field, def_ref);
+ set_pdf_thread_named_id(cur_list.tail_field, 1);
+ } else {
+ pdf_error("ext1", "identifier type missing");
+ }
+}
+
+void check_running_thread(PDF pdf, halfword this_box, scaledpos cur)
+{
+ if ((pdf->last_thread != null) && is_running(pdf->thread.dp)
+ && (pdf->thread_level == cur_s))
+ append_thread(pdf, this_box, cur);
+}
+
+@ @c
+void print_beads_list(PDF pdf)
+{
+ pdf_object_list *k;
+ if ((k = get_page_resources_list(pdf, obj_type_bead)) != NULL) {
+ pdf_printf(pdf, "/B [ ");
+ while (k != NULL) {
+ pdf_print_int(pdf, k->info);
+ pdf_printf(pdf, " 0 R ");
+ k = k->link;
+ }
+ pdf_printf(pdf, "]\n");
+ }
+}
+
+@ @c
+void print_bead_rectangles(PDF pdf)
+{
+ halfword i;
+ pdf_object_list *k;
+ if ((k = get_page_resources_list(pdf, obj_type_bead)) != NULL) {
+ while (k != NULL) {
+ pdf_new_obj(pdf, obj_type_others, 0, 1);
+ pdf_out(pdf, '[');
+ i = obj_bead_data(pdf, k->info); /* pointer to a whatsit or whatsit-like node */
+ pdf_print_rect_spec(pdf, i);
+ if (subtype(i) == pdf_thread_data_node) /* thanh says it mis be destroyed here */
+ flush_node(i);
+ pdf_printf(pdf, "]\n");
+ set_obj_bead_rect(pdf, k->info, pdf->obj_ptr); /* rewrite |obj_bead_data| */
+ pdf_end_obj(pdf);
+ k = k->link;
+ }
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h
new file mode 100644
index 00000000000..83b3c89a97e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h
@@ -0,0 +1,291 @@
+/* pdftypes.h
+
+ Copyright 2009-2010 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdftypes.h 3341 2010-01-08 19:52:54Z hhenkel $ */
+
+#ifndef PDFTYPES_H
+# define PDFTYPES_H
+
+# include <zlib.h>
+
+/* This stucture holds everything that is needed for the actual pdf generation.
+
+Because this structure interfaces with C++, it is not wise to use |boolean|
+here (C++ has a boolean type built-in that is not compatible). Also, I have
+plans to convert the backend code into a C library for use with e.g. standalone
+lua. Together, this means that it is best only to use the standard C types and
+the types explicitly defined in this header, and stay away from types like
+|integer| and |eight_bits| that are used elsewhere in the \LUATEX\ sources.
+*/
+
+typedef struct os_obj_data_ {
+ int num;
+ int off;
+} os_obj_data;
+
+typedef struct {
+ long m; /* mantissa (significand) */
+ int e; /* exponent * -1 */
+} pdffloat;
+
+typedef struct {
+ pdffloat h;
+ pdffloat v;
+} pdfpos;
+
+# define scaled int
+
+typedef struct scaledpos_ {
+ scaled h;
+ scaled v;
+} scaledpos;
+
+typedef struct scaled_whd_ {
+ scaled wd; /* TeX width */
+ scaled ht; /* TeX height */
+ scaled dp; /* TeX depth */
+} scaled_whd;
+
+typedef struct posstructure_ {
+ scaledpos pos; /* position on the page */
+ int dir; /* direction of stuff to be put onto the page */
+} posstructure;
+
+typedef struct {
+ scaledpos curpos; /* \pdflastpos position */
+ posstructure boxpos; /* box dir and position of the box origin on the page */
+ scaled_whd boxdim; /* box dimensions (in hlist/vlist coordinate system) */
+} pos_info_structure;
+
+typedef enum { PMODE_NONE, PMODE_PAGE, PMODE_TEXT, PMODE_CHARARRAY, PMODE_CHAR
+} pos_mode;
+
+typedef enum { OMODE_NONE, OMODE_DVI, OMODE_PDF, OMODE_LUA } output_mode;
+
+# define MAX_OMODE 3 /* largest index in enum output_mode */
+
+typedef enum { ST_INITIAL, ST_OMODE_FIX, ST_FILE_OPEN, ST_HEADER_WRITTEN,
+ ST_FILE_CLOSED
+} output_state;
+
+typedef struct pdf_object_list_ {
+ int info;
+ struct pdf_object_list_ *link;
+} pdf_object_list;
+
+typedef enum { WMODE_H, WMODE_V } writing_mode; /* []TJ runs horizontal or vertical */
+
+typedef struct {
+ pdfpos pdf; /* pos. on page (PDF page raster) */
+ pdfpos pdf_bt_pos; /* pos. at begin of BT-ET group (PDF page raster) */
+ pdfpos pdf_tj_pos; /* pos. at begin of TJ array (PDF page raster) */
+ pdffloat cw; /* pos. within [(..)..]TJ array (glyph raster);
+ cw.e = fractional digits in /Widths array */
+ pdffloat tj_delta; /* rel. movement in [(..)..]TJ array (glyph raster) */
+ pdffloat fs; /* font size in PDF units */
+ pdffloat fs_cur; /* to check if fs.m has changed and Tf needed */
+ pdffloat cm[6]; /* cm array */
+ pdffloat tm[6]; /* Tm array */
+ double k1; /* conv. factor from TeX sp to PDF page raster */
+ double k2; /* conv. factor from PDF page raster to TJ array raster */
+ int f_pdf; /* /F* font number, of unexpanded base font! */
+ int f_pdf_cur; /* to check if f_pdf has changed and Tf needed */
+ writing_mode wmode; /* PDF writing mode WMode (horizontal/vertical) */
+ pos_mode mode; /* current positioning mode */
+ int ishex; /* Whether the current char string is <> or () */
+} pdfstructure;
+
+typedef struct obj_entry_ {
+ union {
+ int int0;
+ char *str0;
+ } u;
+ int int1;
+ off_t int2;
+ int int3;
+ union {
+ int int4;
+ char *str4;
+ } v;
+ int objtype; /* integer int5 */
+} obj_entry;
+
+typedef struct dest_name_entry_ {
+ char *objname; /* destination name */
+ int objnum; /* destination object number */
+} dest_name_entry;
+
+# define pdf_max_link_level 10 /* maximum depth of link nesting */
+
+typedef struct pdf_link_stack_record {
+ int nesting_level;
+ int link_node; /* holds a copy of the corresponding |pdf_start_link_node| */
+ int ref_link_node; /* points to original |pdf_start_link_node|, or a
+ copy of |link_node| created by |append_link| in
+ case of multi-line link */
+} pdf_link_stack_record;
+
+/* types of objects */
+typedef enum {
+ obj_type_font = 0, /* index of linked list of Fonts objects */
+ obj_type_outline = 1, /* index of linked list of outline objects */
+ obj_type_dest = 2, /* index of linked list of destination objects */
+ obj_type_obj = 3, /* index of linked list of raw objects */
+ obj_type_xform = 4, /* index of linked list of XObject forms */
+ obj_type_ximage = 5, /* index of linked list of XObject images */
+ obj_type_thread = 6, /* index of linked list of num article threads */
+ /* |obj_type_thread| is the highest entry in |head_tab|, but there are a few
+ more linked lists that are handy: */
+ obj_type_pagestream = 7, /* Page stream objects */
+ obj_type_page = 8, /* Page objects */
+ obj_type_pages = 9, /* Pages objects */
+ obj_type_link = 10, /* link objects */
+ obj_type_bead = 11, /* thread bead objects */
+ obj_type_annot = 12, /* annotation objects */
+ obj_type_objstm = 13, /* /ObjStm objects */
+ obj_type_others = 14 /* any other objects (also not linked in any list) */
+} pdf_obj_type;
+
+# define HEAD_TAB_MAX 6 /* obj_type_thread */
+# define PDF_OBJ_TYPE_MAX 14 /* obj_type_others */
+
+typedef struct pdf_resource_struct_ {
+ struct avl_table *resources_tree;
+ int last_resources; /* halfword to most recently generated Resources object. */
+} pdf_resource_struct;
+
+typedef struct pdf_output_file_ {
+ FILE *file; /* the PDF output file handle */
+ char *file_name; /* the PDF output file name */
+ output_mode o_mode; /* output mode (DVI/PDF/...) */
+ output_state o_state;
+ /* generation parameters */
+ int gamma;
+ int image_gamma;
+ int image_hicolor; /* boolean */
+ int image_apply_gamma;
+ int draftmode;
+ int pk_resolution;
+ int decimal_digits;
+ int gen_tounicode;
+ int inclusion_copy_font;
+ int replace_font;
+ int minor_version; /* fixed minor part of the PDF version */
+ int compress_level; /* level for zlib object stream compression */
+ int objcompresslevel; /* fixed level for activating PDF object streams */
+ char *job_id_string; /* the full job string */
+
+ /* output file buffering */
+ unsigned char *op_buf; /* the PDF output buffer */
+ int op_buf_size; /* output buffer size (static) */
+ int op_ptr; /* store for PDF buffer |pdf_ptr| while inside object streams */
+ unsigned char *os_buf; /* the PDF object stream buffer */
+ int os_buf_size; /* current size of the PDF object stream buffer, grows dynamically */
+ int os_ptr; /* store for object stream |pdf_ptr| while outside object streams */
+
+ os_obj_data *os_obj; /* array of object stream objects */
+ int os_idx; /* pointer into |pdf_os_objnum| and |pdf_os_objoff| */
+ int os_cntr; /* counter for object stream objects */
+ int os_mode; /* true if producing object stream */
+ int os_enable; /* true if object streams are globally enabled */
+ int os_cur_objnum; /* number of current object stream object */
+
+ unsigned char *buf; /* pointer to the PDF output buffer or PDF object stream buffer */
+ int buf_size; /* end of PDF output buffer or PDF object stream buffer */
+ int ptr; /* pointer to the first unused byte in the PDF buffer or object stream buffer */
+ off_t save_offset; /* to save |pdf_offset| */
+ off_t gone; /* number of bytes that were flushed to output */
+
+ char *printf_buf; /* a scratch buffer for |pdf_printf| */
+
+ time_t start_time; /* when this job started */
+ char *start_time_str; /* minimum size for time_str is 24: "D:YYYYmmddHHMMSS+HH'MM'" */
+
+ /* define fb_ptr, fb_array & fb_limit */
+ char *fb_array;
+ char *fb_ptr;
+ size_t fb_limit;
+
+ char *zipbuf;
+ z_stream c_stream; /* compression stream */
+ int zip_write_state; /* which state of compression we are in */
+
+ int pk_scale_factor; /* this is just a preprocessed value that depends on
+ |pk_resolution| and |decimal_digits| */
+
+ int img_page_group_val; /* page group information pointer from included pdf or png images */
+ char *resname_prefix; /* global prefix of resources name */
+
+ int mem_size; /* allocated size of |mem| array */
+ int *mem;
+ int mem_ptr;
+
+ pdfstructure *pstruct; /* utity structure keeping position status in PDF page stream */
+ posstructure *posstruct; /* structure for positioning within page */
+
+ int obj_tab_size; /* allocated size of |obj_tab| array */
+ obj_entry *obj_tab;
+ int head_tab[HEAD_TAB_MAX + 1]; /* heads of the object lists in |obj_tab| */
+ struct avl_table *obj_tree[PDF_OBJ_TYPE_MAX + 1]; /* this is useful for finding the objects back */
+
+ int pages_tail;
+ int obj_ptr; /* user objects counter */
+ int sys_obj_ptr; /* system objects counter, including object streams */
+ int last_pages; /* pointer to most recently generated pages object */
+ int last_page; /* pointer to most recently generated page object */
+ int last_stream; /* pointer to most recently generated stream */
+ off_t stream_length; /* length of most recently generated stream */
+ off_t stream_length_offset; /* file offset of the last stream length */
+ int seek_write_length; /* flag whether to seek back and write \.{/Length} */
+ int last_byte; /* byte most recently written to PDF file; for \.{endstream} in new line */
+
+ /* integer last_resources; halfword to most recently generated Resources object.
+ TH: this used to be a local in pdf_shipout, but I would like to
+ be able to split that function into a pre- and post part */
+
+ int obj_count;
+ int xform_count;
+ int ximage_count;
+
+ pdf_resource_struct *page_resources;
+
+ /* the variables from pdfdest */
+ int dest_names_size;
+ int dest_names_ptr;
+ dest_name_entry *dest_names;
+ /* the (static) variables from pdfoutline */
+ int first_outline;
+ int last_outline;
+ int parent_outline;
+ /* the pdf link stack */
+ pdf_link_stack_record link_stack[(pdf_max_link_level + 1)];
+ int link_stack_ptr;
+ /* the thread data */
+ int last_thread; /* pointer to the last thread */
+ scaled_whd thread;
+ int last_thread_id; /* identifier of the last thread */
+ int last_thread_named_id; /* is identifier of the last thread named */
+ int thread_level; /* depth of nesting of box containing the last thread */
+
+ int f_cur; /* TeX font number */
+} pdf_output_file;
+
+typedef pdf_output_file *PDF;
+
+#endif /* PDFTYPES_H */
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h
new file mode 100644
index 00000000000..c117301ebe2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.h
@@ -0,0 +1,56 @@
+/* pdfxform.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfxform.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PDFXFORM_H
+# define PDFXFORM_H
+
+/* data structure for \.{\\pdfxform} and \.{\\pdfrefxform} */
+
+# define pdfmem_xform_size 6 /* size of memory in |pdf->mem| which |obj_data_ptr| holds */
+
+# define set_pdf_xform_objnum(A,B) pdf_xform_objnum(A)=B
+
+# define obj_xform_width(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 0]
+# define obj_xform_height(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 1]
+# define obj_xform_depth(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 2]
+# define obj_xform_box(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 3] /* this field holds
+ pointer to the corresponding box */
+# define obj_xform_attr(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 4] /* additional xform
+ attributes */
+# define obj_xform_resources(pdf,A) pdf->mem[obj_data_ptr(pdf,A) + 5] /* additional xform
+ Resources */
+
+
+# define set_obj_xform_width(pdf,A,B) obj_xform_width(pdf,A)=B
+# define set_obj_xform_height(pdf,A,B) obj_xform_height(pdf,A)=B
+# define set_obj_xform_depth(pdf,A,B) obj_xform_depth(pdf,A)=B
+# define set_obj_xform_box(pdf,A,B) obj_xform_box(pdf,A)=B
+# define set_obj_xform_attr(pdf,A,B) obj_xform_attr(pdf,A)=B
+# define set_obj_xform_resources(pdf,A,B) obj_xform_resources(pdf,A)=B
+
+extern int pdf_cur_form; /* the form being output */
+
+void pdf_place_form(PDF pdf, halfword p);
+
+void scan_pdfxform(PDF pdf);
+void scan_pdfrefxform(PDF pdf);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w
new file mode 100644
index 00000000000..5f3b5802708
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w
@@ -0,0 +1,128 @@
+% pdfxform.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfxform.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfxform.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#include "pdf/pdfpage.h"
+
+@ @c
+#define box(A) eqtb[box_base+(A)].hh.rh
+
+int pdf_cur_form; /* the form being output */
+
+void pdf_place_form(PDF pdf, halfword p)
+{
+ scaled_whd nat, tex;
+ scaled x, y;
+ pdffloat cm[6];
+ pdfstructure *q = pdf->pstruct;
+ int r = 6, objnum = pdf_xform_objnum(p);
+ nat.wd = obj_xform_width(pdf, objnum);
+ nat.ht = obj_xform_height(pdf, objnum);
+ nat.dp = obj_xform_depth(pdf, objnum);
+ /* no transform yet */
+ tex.wd = width(p);
+ tex.ht = height(p);
+ tex.dp = depth(p);
+ if (nat.wd != tex.wd || nat.ht != tex.ht || nat.dp != tex.dp) {
+ x = ext_xn_over_d(ten_pow[r], tex.wd, nat.wd);
+ y = ext_xn_over_d(ten_pow[r], tex.dp + tex.ht, nat.dp + nat.ht);
+ } else
+ x = y = ten_pow[r];
+ setpdffloat(cm[0], x, r);
+ setpdffloat(cm[1], 0, r);
+ setpdffloat(cm[2], 0, r);
+ setpdffloat(cm[3], y, r);
+ pdf_goto_pagemode(pdf);
+ (void) calc_pdfpos(q, pdf->posstruct->pos);
+ cm[4] = q->cm[4];
+ cm[5] = q->cm[5];
+ pdf_printf(pdf, "q\n");
+ pdf_print_cm(pdf, cm);
+ pdf_printf(pdf, "/Fm%d", (int) obj_info(pdf, objnum));
+ pdf_print_resname_prefix(pdf);
+ pdf_printf(pdf, " Do\nQ\n");
+ addto_page_resources(pdf, obj_type_xform, objnum);
+}
+
+@ @c
+void scan_pdfxform(PDF pdf)
+{
+ int k;
+ halfword p;
+ incr(pdf->xform_count);
+ pdf_create_obj(pdf, obj_type_xform, pdf->xform_count);
+ k = pdf->obj_ptr;
+ set_obj_data_ptr(pdf, k, pdf_get_mem(pdf, pdfmem_xform_size));
+ if (scan_keyword("attr")) {
+ scan_pdf_ext_toks();
+ set_obj_xform_attr(pdf, k, def_ref);
+ } else {
+ set_obj_xform_attr(pdf, k, null);
+ }
+ if (scan_keyword("resources")) {
+ scan_pdf_ext_toks();
+ set_obj_xform_resources(pdf, k, def_ref);
+ } else {
+ set_obj_xform_resources(pdf, k, null);
+ }
+ scan_int();
+ p = box(cur_val);
+ if (p == null)
+ pdf_error("ext1", "\\pdfxform cannot be used with a void box");
+ set_obj_xform_box(pdf, k, p); /* save pointer to the box */
+ set_obj_xform_width(pdf, k, width(p));
+ set_obj_xform_height(pdf, k, height(p));
+ set_obj_xform_depth(pdf, k, depth(p));
+ box(cur_val) = null;
+ pdf_last_xform = k;
+}
+
+@ @c
+#define tail cur_list.tail_field
+
+void scan_pdfrefxform(PDF pdf)
+{
+ int transform = 0;
+ scaled_whd alt_rule, dim, nat;
+ alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
+ scan_int();
+ check_obj_exists(pdf, obj_type_xform, cur_val);
+ new_whatsit(pdf_refxform_node);
+ nat.wd = obj_xform_width(pdf, cur_val);
+ nat.ht = obj_xform_height(pdf, cur_val);
+ nat.dp = obj_xform_depth(pdf, cur_val);
+ if (alt_rule.wd != null_flag || alt_rule.ht != null_flag
+ || alt_rule.dp != null_flag) {
+ dim = tex_scale(nat, alt_rule);
+ } else {
+ dim = nat;
+ }
+ width(tail) = dim.wd;
+ height(tail) = dim.ht;
+ depth(tail) = dim.dp;
+ pdf_xform_transform(tail) = transform; /* not implemented yet */
+ pdf_xform_objnum(tail) = cur_val;
+}
diff --git a/Build/source/texk/web2c/luatexdir/ptexlib.h b/Build/source/texk/web2c/luatexdir/ptexlib.h
index 77f8e1318f2..1f45113f6c9 100644
--- a/Build/source/texk/web2c/luatexdir/ptexlib.h
+++ b/Build/source/texk/web2c/luatexdir/ptexlib.h
@@ -24,223 +24,248 @@
# define PTEXLIB_H
/* WEB2C macros and prototypes */
-# if !defined(LUATEXCOERCE)
-# ifdef luatex
-# undef luatex /* to avoid warning about redefining luatex in luatexd.h */
-# endif /* luatex */
-# define EXTERN extern
-# include "luatexd.h"
-# endif
+# define EXTERN extern
+# include "luatex.h"
# ifdef MSVC
extern double rint(double x);
# endif
-/* pdftexlib macros */
-# include "ptexmac.h"
+extern string fullnameoffile;
+# if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
+extern char **suffixlist;
+# endif
+
+
+/* Replicate these here. They are hardcoded anyway */
+
+# define eTeX_version_string "2.2" /* current \eTeX\ version */
+# define eTeX_version 2 /* \.{\\eTeXversion} */
+# define eTeX_minor_version 2 /* \.{\\eTeXminorversion} */
+# define eTeX_revision ".2" /* \.{\\eTeXrevision} */
+
+# define Omega_version_string "1.15" /* \.{\\OmegaVersion} */
+# define Omega_version 1 /* \.{\\Omegaversion} */
+# define Omega_minor_version 15 /* \.{\\Omegaminorversion} */
+# define Omega_revision ".15" /* \.{\\Omegarevision} */
+
+# define Aleph_version_string "0.0" /* \.{\\AlephVersion} */
+# define Aleph_version 0 /* \.{\\Alephversion} */
+# define Aleph_minor_version 0 /* \.{\\Alephminorversion} */
+# define Aleph_revision ".0" /* \.{\\Alephrevision} */
+
+# define pdftex_version_string "-2.00.0"
+ /* current \pdfTeX\ version */
+# define pdftex_version 200 /* \.{\\pdftexversion} */
+# define pdftex_revision "0" /* \.{\\pdftexrevision} */
+
+# include "lua51/lua.h"
+
+
+/* pdftexlib macros from ptexmac.h */
+
+/* Not all systems define it. */
+# ifndef M_PI
+# define M_PI 3.14159265358979323846 /* pi */
+# endif
+
+# ifdef WIN32
+# define inline __inline
+# endif
+
+/**********************************************************************/
+/* Pascal WEB macros */
+
+# define max_integer 0x7FFFFFFF
+# define max_dimen 0x3FFFFFFF
+
+/**********************************************************************/
+
+# define PRINTF_BUF_SIZE 1024
+# define MAX_CSTRING_LEN 1024 * 1024
+# define MAX_PSTRING_LEN 1024
+# define SMALL_BUF_SIZE 256
+# define SMALL_ARRAY_SIZE 256
+
+# define check_buf(size, buf_size) \
+ if ((unsigned)(size) > (unsigned)(buf_size)) \
+ pdftex_fail("buffer overflow: %d > %d at file %s, line %d", \
+ (int)(size), (int)(buf_size), __FILE__, __LINE__ )
+
+# define append_char_to_buf(c, p, buf, buf_size) do { \
+ if (c == 9) \
+ c = 32; \
+ if (c == 13 || c == EOF) \
+ c = 10; \
+ if (c != ' ' || (p > buf && p[-1] != 32)) { \
+ check_buf(p - buf + 1, (buf_size)); \
+ *p++ = c; \
+ } \
+} while (0)
+
+# define append_eol(p, buf, buf_size) do { \
+ check_buf(p - buf + 2, (buf_size)); \
+ if (p - buf > 1 && p[-1] != 10) \
+ *p++ = 10; \
+ if (p - buf > 2 && p[-2] == 32) { \
+ p[-2] = 10; \
+ p--; \
+ } \
+ *p = 0; \
+} while (0)
+
+# define remove_eol(p, buf) do { \
+ p = strend(buf) - 1; \
+ if (*p == 10) \
+ *p = 0; \
+} while (0)
+
+# define skip(p, c) if (*p == c) p++
+
+# define alloc_array(T, n, s) do { \
+ if (T##_array == NULL) { \
+ T##_limit = (size_t)(s); \
+ if ((unsigned)(n) > (unsigned)T##_limit) \
+ T##_limit = (size_t)(n); \
+ T##_array = xtalloc((unsigned)T##_limit, T##_entry); \
+ T##_ptr = T##_array; \
+ } \
+ else if ((unsigned)(T##_ptr - T##_array + (unsigned)(n)) > (unsigned)(T##_limit)) { \
+ size_t last_ptr_index = (size_t)(T##_ptr - T##_array); \
+ T##_limit *= 2; \
+ if ((unsigned)(T##_ptr - T##_array + (unsigned)(n)) > (unsigned)(T##_limit)) \
+ T##_limit = (size_t)(T##_ptr - T##_array + (unsigned)(n)); \
+ xretalloc(T##_array, (unsigned)T##_limit, T##_entry); \
+ T##_ptr = T##_array + last_ptr_index; \
+ } \
+ } while (0)
+
+# define define_array(T) \
+T##_entry *T##_ptr, *T##_array = NULL; \
+size_t T##_limit
+
+# define xfree(a) do { free(a); a = NULL; } while (0)
+# define dxfree(a,b) do { free(a); a = b; } while (0)
+# define strend(s) strchr(s, 0)
+# define xtalloc XTALLOC
+# define xretalloc XRETALLOC
+
+# define cmp_return(a, b) \
+ if ((a) > (b)) \
+ return 1; \
+ if ((a) < (b)) \
+ return -1
+
+# define str_prefix(s1, s2) (strncmp((s1), (s2), strlen(s2)) == 0)
+
+/* that was ptexmac.h */
+
+# include "tex/mainbody.h"
+# include "tex/expand.h"
+# include "tex/conditional.h"
+# include "pdf/pdftypes.h"
/* synctex */
# include "utils/synctex.h"
# include "utils/avlstuff.h"
+# include "utils/managed-sa.h"
# include "image/writeimg.h"
# include "openbsd-compat.h"
+# include "dvi/dvigen.h"
# include "pdf/pagetree.h"
+# include "pdf/pdfgen.h"
# include "pdf/pdfpage.h"
+# include "pdf/pdftables.h"
+
+# include "pdf/pdfaction.h"
+# include "pdf/pdfannot.h"
+# include "pdf/pdfcolorstack.h"
+# include "pdf/pdfdest.h"
+# include "pdf/pdffont.h"
+# include "pdf/pdfglyph.h"
+# include "pdf/pdfimage.h"
+# include "pdf/pdflink.h"
+# include "pdf/pdflistout.h"
+# include "pdf/pdfliteral.h"
+# include "pdf/pdfobj.h"
+# include "pdf/pdfoutline.h"
+# include "pdf/pdfrule.h"
+# include "pdf/pdfsaverestore.h"
+# include "pdf/pdfsetmatrix.h"
+# include "pdf/pdfshipout.h"
+# include "pdf/pdfthread.h"
+# include "pdf/pdfxform.h"
+
+# include "lua/luagen.h"
+
# include "font/luatexfont.h"
# include "font/mapfile.h"
# include "utils/utils.h"
# include "image/writejbig2.h"
# include "image/pdftoepdf.h"
-/**********************************************************************/
-
-typedef short shalfword;
+# include "ocp/ocp.h"
+# include "ocp/ocplist.h"
+# include "ocp/runocp.h"
+# include "ocp/readocp.h"
+
+# include "lang/texlang.h"
+
+# include "tex/textcodes.h"
+# include "tex/mathcodes.h"
+
+# include "tex/align.h"
+# include "tex/directions.h"
+# include "tex/errors.h"
+# include "tex/inputstack.h"
+# include "tex/stringpool.h"
+# include "tex/textoken.h"
+# include "tex/printing.h"
+# include "tex/texfileio.h"
+# include "tex/arithmetic.h"
+# include "tex/nesting.h"
+# include "tex/packaging.h"
+# include "tex/linebreak.h"
+# include "tex/postlinebreak.h"
+# include "tex/scanning.h"
+# include "tex/buildpage.h"
+# include "tex/maincontrol.h"
+# include "tex/dumpdata.h"
+# include "tex/mainbody.h"
+# include "tex/extensions.h"
+# include "tex/texnodes.h"
+
+# include "tex/texmath.h"
+# include "tex/mlist.h"
+# include "tex/primitive.h"
+# include "tex/commands.h"
+# include "tex/equivalents.h"
-/* loadpool.c */
-int loadpoolstrings(integer spare_size);
+/**********************************************************************/
-/* tex/filename.c */
-extern void scan_file_name(void);
-extern void pack_job_name(const char *s);
-extern void prompt_file_name(const char *s, const char *e);
-extern str_number make_name_string(void);
-extern void print_file_name(str_number, str_number, str_number);
+# include "tex/filename.h"
/* lua/luainit.c */
-extern void write_svnversion(const char *a);
-
-/* utils/writezip.c */
-extern void write_zip(boolean);
-extern void zip_free(void);
+extern void write_svnversion(char *a);
/**********************************************************************/
-typedef enum {
- no_print = 16,
- term_only = 17,
- log_only = 18,
- term_and_log = 19,
- pseudo = 20,
- new_string = 21
-} selector_settings;
-
-/* language stuff */
-
-typedef struct _lang_variables {
- int pre_hyphen_char;
- int post_hyphen_char;
- int pre_exhyphen_char;
- int post_exhyphen_char;
-} lang_variables;
-
-# include "hyphen.h"
-
-struct tex_language {
- HyphenDict *patterns;
- int exceptions; /* lua registry pointer, should be replaced */
- int id;
- int pre_hyphen_char;
- int post_hyphen_char;
- int pre_exhyphen_char;
- int post_exhyphen_char;
-};
-
-# define MAX_WORD_LEN 256 /* in chars */
-
-extern struct tex_language *new_language(int n);
-extern struct tex_language *get_language(int n);
-extern void load_patterns(struct tex_language *lang, const unsigned char *buf);
-extern void load_hyphenation(struct tex_language *lang, const unsigned char *buf);
-extern int hyphenate_string(struct tex_language *lang, char *w, char **ret);
-
-extern void new_hyphenation(halfword h, halfword t);
-extern void clear_patterns(struct tex_language *lang);
-extern void clear_hyphenation(struct tex_language *lang);
-extern const char *clean_hyphenation(const char *buffer, char **cleaned);
-extern void hnj_hyphenation(halfword head, halfword tail);
-
-extern void set_pre_hyphen_char(integer lan, integer val);
-extern void set_post_hyphen_char(integer lan, integer val);
-extern integer get_pre_hyphen_char(integer lan);
-extern integer get_post_hyphen_char(integer lan);
-
-extern void set_pre_exhyphen_char(integer lan, integer val);
-extern void set_post_exhyphen_char(integer lan, integer val);
-extern integer get_pre_exhyphen_char(integer lan);
-extern integer get_post_exhyphen_char(integer lan);
-extern halfword compound_word_break(halfword t, int clang);
-
extern halfword new_ligkern(halfword head, halfword tail);
extern halfword handle_ligaturing(halfword head, halfword tail);
extern halfword handle_kerning(halfword head, halfword tail);
-# define push_dir(a) \
- { dir_tmp=new_dir((a)); \
- vlink(dir_tmp)=dir_ptr; dir_ptr=dir_tmp; \
- dir_ptr=dir_tmp; \
- }
-
-# define push_dir_node(a) \
- { dir_tmp=new_node(whatsit_node,dir_node); \
- dir_dir(dir_tmp)=dir_dir((a)); \
- dir_level(dir_tmp)=dir_level((a)); \
- dir_dvi_h(dir_tmp)=dir_dvi_h((a)); \
- dir_dvi_ptr(dir_tmp)=dir_dvi_ptr((a)); \
- vlink(dir_tmp)=dir_ptr; dir_ptr=dir_tmp; \
- }
-
-# define pop_dir_node() \
- { dir_tmp=dir_ptr; \
- dir_ptr=vlink(dir_tmp); \
- flush_node(dir_tmp); \
- }
-
-# define dir_parallel(a,b) (((a) % 2)==((b) % 2))
-# define dir_orthogonal(a,b) (((a) % 2)!=((b) % 2))
-
-# define is_rotated(a) dir_parallel(dir_secondary[(a)],dir_tertiary[(a)])
-
-void initialize_active(void);
-
-halfword find_protchar_left(halfword l, boolean d);
-halfword find_protchar_right(halfword l, halfword r);
-
-void ext_do_line_break(boolean d,
- int pretolerance,
- int tracing_paragraphs,
- int tolerance,
- scaled emergency_stretch,
- int looseness,
- int hyphen_penalty,
- int ex_hyphen_penalty,
- int pdf_adjust_spacing,
- halfword par_shape_ptr,
- int adj_demerits,
- int pdf_protrude_chars,
- int line_penalty,
- int last_line_fit,
- int double_hyphen_demerits,
- int final_hyphen_demerits,
- int hang_indent,
- int hsize,
- int hang_after,
- halfword left_skip,
- halfword right_skip,
- int pdf_each_line_height,
- int pdf_each_line_depth,
- int pdf_first_line_height,
- int pdf_last_line_depth,
- halfword inter_line_penalties_ptr,
- int inter_line_penalty,
- int club_penalty,
- halfword club_penalties_ptr,
- halfword display_widow_penalties_ptr,
- halfword widow_penalties_ptr,
- int display_widow_penalty,
- int widow_penalty,
- int broken_penalty, halfword final_par_glue,
- halfword pdf_ignored_dimen);
-
-void ext_post_line_break(boolean d,
- int right_skip,
- int left_skip,
- int pdf_protrude_chars,
- halfword par_shape_ptr,
- int pdf_adjust_spacing,
- int pdf_each_line_height,
- int pdf_each_line_depth,
- int pdf_first_line_height,
- int pdf_last_line_depth,
- halfword inter_line_penalties_ptr,
- int inter_line_penalty,
- int club_penalty,
- halfword club_penalties_ptr,
- halfword display_widow_penalties_ptr,
- halfword widow_penalties_ptr,
- int display_widow_penalty,
- int widow_penalty,
- int broken_penalty,
- halfword final_par_glue,
- halfword best_bet,
- halfword last_special_line,
- scaled second_width,
- scaled second_indent,
- scaled first_width,
- scaled first_indent, halfword best_line,
- halfword pdf_ignored_dimen);
-
halfword lua_hpack_filter(halfword head_node, scaled size, int pack_type,
- int extrainfo);
+ int extrainfo, int d);
void lua_node_filter(int filterid, int extrainfo, halfword head_node,
halfword * tail_node);
halfword lua_vpack_filter(halfword head_node, scaled size, int pack_type,
- scaled maxd, int extrainfo);
+ scaled maxd, int extrainfo, int d);
void lua_node_filter_s(int filterid, const char *extrainfo);
int lua_linebreak_callback(int is_broken, halfword head_node,
halfword * new_head);
-void lua_pdf_literal(int i);
+void lua_pdf_literal(PDF pdf, int i);
void copy_pdf_literal(pointer r, pointer p);
void free_pdf_literal(pointer p);
void show_pdf_literal(pointer p);
@@ -248,82 +273,6 @@ void show_pdf_literal(pointer p);
void load_tex_patterns(int curlang, halfword head);
void load_tex_hyphenation(int curlang, halfword head);
-/* textcodes.c */
-void set_lc_code(integer n, halfword v, quarterword gl);
-halfword get_lc_code(integer n);
-void set_uc_code(integer n, halfword v, quarterword gl);
-halfword get_uc_code(integer n);
-void set_sf_code(integer n, halfword v, quarterword gl);
-halfword get_sf_code(integer n);
-void set_cat_code(integer h, integer n, halfword v, quarterword gl);
-halfword get_cat_code(integer h, integer n);
-void unsave_cat_codes(integer h, quarterword gl);
-int valid_catcode_table(int h);
-void initex_cat_codes(int h);
-void unsave_text_codes(quarterword grouplevel);
-void initialize_text_codes(void);
-void dump_text_codes(void);
-void undump_text_codes(void);
-void copy_cat_codes(int from, int to);
-void free_math_codes(void);
-void free_text_codes(void);
-
-/* mathcodes.c */
-
-# define no_mathcode 0 /* this is a flag for |scan_delimiter| */
-# define tex_mathcode 8
-# define aleph_mathcode 16
-# define xetex_mathcode 21
-# define xetexnum_mathcode 22
-
-typedef struct mathcodeval {
- integer class_value;
- integer origin_value;
- integer family_value;
- integer character_value;
-} mathcodeval;
-
-void set_math_code(integer n,
- integer commandorigin,
- integer mathclass,
- integer mathfamily, integer mathcharacter, quarterword gl);
-
-mathcodeval get_math_code(integer n);
-integer get_math_code_num(integer n);
-mathcodeval scan_mathchar(int extcode);
-mathcodeval scan_delimiter_as_mathchar(int extcode);
-
-mathcodeval mathchar_from_integer(integer value, int extcode);
-void show_mathcode_value(mathcodeval d);
-
-typedef struct delcodeval {
- integer class_value;
- integer origin_value;
- integer small_family_value;
- integer small_character_value;
- integer large_family_value;
- integer large_character_value;
-} delcodeval;
-
-void set_del_code(integer n,
- integer commandorigin,
- integer smathfamily,
- integer smathcharacter,
- integer lmathfamily, integer lmathcharacter, quarterword gl);
-
-delcodeval get_del_code(integer n);
-
-void unsave_math_codes(quarterword grouplevel);
-void initialize_math_codes(void);
-void dump_math_codes(void);
-void undump_math_codes(void);
-
-/* lang/texlang.c */
-
-void dump_language_data(void);
-void undump_language_data(void);
-char *exception_strings(struct tex_language *lang);
-
/* lua/llualib.c */
void dump_luac_registers(void);
@@ -332,70 +281,36 @@ void undump_luac_registers(void);
/* lua/ltexlib.c */
void luacstring_start(int n);
void luacstring_close(int n);
-integer luacstring_cattable(void);
+int luacstring_cattable(void);
int luacstring_input(void);
int luacstring_partial(void);
int luacstring_final_line(void);
/* lua/luatoken.c */
-void do_get_token_lua(integer callback_id);
+void do_get_token_lua(int callback_id);
/* lua/luanode.c */
int visible_last_node_type(int n);
void print_node_mem_stats(void);
/* lua/limglib.c */
-void vf_out_image(unsigned i);
+void vf_out_image(PDF pdf, unsigned i);
/* lua/ltexiolib.c */
void flush_loggable_info(void);
/* lua/luastuff.c */
-void luacall(int s, int nameptr);
void luatokencall(int p, int nameptr);
+extern void late_lua(PDF pdf, halfword p);
extern void check_texconfig_init(void);
-scaled divide_scaled(scaled s, scaled m, integer dd);
+scaled divide_scaled(scaled s, scaled m, int dd);
scaled divide_scaled_n(double s, double m, double d);
-/* tex/mlist.c */
-void run_mlist_to_hlist(pointer p, integer m_style, boolean penalties);
-void fixup_math_parameters(integer fam_id, integer size_id, integer f,
- integer lvl);
-
-/* tex/texpdf.c */
-void pdf_print_char(internal_font_number f, integer c);
-void pdf_print(str_number n);
-void pdf_print_str(str_number n);
-void pdf_print_int(longinteger n);
-void pdf_print_real(integer m, integer d);
-
-/* tex/textoken.c */
+# include "tex/texdeffont.h"
-# define NO_CAT_TABLE -2
-# define DEFAULT_CAT_TABLE -1
-
-extern boolean str_eq_cstr(str_number, const char *, size_t);
-void get_next(void);
-extern void check_outer_validity(void);
-boolean scan_keyword(const char *);
-void scan_direction(void);
-halfword active_to_cs(int, int);
-void get_token_lua(void);
-int get_char_cat_code(int);
-
-/* tex/texdeffont.c */
-
-void tex_def_font(small_number a);
-
-/* lua/ltokenlib.c */
-
-extern int get_command_id(const char *);
-
-/* lua/lcallbacklib.c */
-
-# include <../lua51/lua.h>
+/* lcallbacklib.c */
typedef enum {
find_write_file_callback = 1,
@@ -415,7 +330,7 @@ typedef enum {
find_sfd_file_callback, read_sfd_file_callback,
find_pk_file_callback, read_pk_file_callback,
show_error_hook_callback,
- process_input_buffer_callback,
+ process_input_buffer_callback, process_output_buffer_callback,
start_page_number_callback, stop_page_number_callback,
start_run_callback, stop_run_callback,
define_font_callback,
@@ -446,16 +361,85 @@ extern void destroy_saved_callback(int i);
extern boolean get_callback(lua_State * L, int i);
extern void get_saved_lua_boolean(int i, const char *name, boolean * target);
-extern void get_saved_lua_number(int i, const char *name, integer * target);
-extern void get_saved_lua_string(int i, const char *name, const char **target);
+extern void get_saved_lua_number(int i, const char *name, int *target);
+extern void get_saved_lua_string(int i, const char *name, char **target);
-extern void get_lua_boolean(const char *table, const char *name, boolean * target);
-extern void get_lua_number(const char *table, const char *name, integer * target);
-extern void get_lua_string(const char *table, const char *name, const char **target);
+extern void get_lua_boolean(const char *table, const char *name,
+ boolean * target);
+extern void get_lua_number(const char *table, const char *name, int *target);
+extern void get_lua_string(const char *table, const char *name, char **target);
extern char *get_lua_name(int i);
-# include "texmath.h"
-# include "primitive.h"
+/* Additions to texmfmp.h for pdfTeX */
+
+/* mark a char in font */
+# define pdf_mark_char(f,c) set_char_used(f,c,true)
+
+/* test whether a char in font is marked */
+# define pdf_char_marked char_used
+
+# define pdfassert assert
+# define voidcast(a) (void *)(a)
+# define fixmemcast(a) (smemory_word *)(a)
+
+extern void do_vf(internal_font_number tmp_f);
+
+/* This routine has to return four values. */
+# define dateandtime(i,j,k,l) get_date_and_time (&(i), &(j), &(k), &(l))
+extern void get_date_and_time(int *, int *, int *, int *);
+
+/* Get high-res time info. */
+# define seconds_and_micros(i,j) get_seconds_and_micros (&(i), &(j))
+extern void get_seconds_and_micros(int *, int *);
+
+/* This routine has to return a scaled value. */
+extern int getrandomseed(void);
+
+/* Copy command-line arguments into the buffer, despite the name. */
+extern void topenin(void);
+
+/* Can't prototype this since it uses poolpointer and ASCIIcode, which
+ are defined later in mfd.h, and mfd.h uses stuff from here. */
+/* Therefore the department of ugly hacks decided to move this declaration
+ to the *coerce.h files. */
+/* extern void calledit (); */
+
+/* Set an array size from texmf.cnf. */
+extern void setupboundvariable(integer *, const_string, integer);
+
+/* here are a few functions that used to be in coerce.h */
+
+extern str_number getjobname(str_number);
+extern str_number makefullnamestring(void);
+
+
+extern KPSEDLL string kpathsea_version_string; /* from kpathsea/version.c */
+
+extern PDF static_pdf;
+
+extern string normalize_quotes(const_string name, const_string mesg);
+extern string dump_name;
+extern const_string c_job_name;
+
+extern halfword *check_isnode(lua_State * L, int ud);
+extern void lua_nodelib_push_fast(lua_State * L, halfword n);
+
+extern void lua_nodelib_push_fast(lua_State * L, halfword n);
+
+extern halfword list_node_mem_usage(void);
+
+extern halfword *check_isnode(lua_State * L, int ud);
+
+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);
+
+extern int program_name_set; /* in lkpselib.c */
+
+
#endif /* PTEXLIB_H */
diff --git a/Build/source/texk/web2c/luatexdir/ptexmac.h b/Build/source/texk/web2c/luatexdir/ptexmac.h
deleted file mode 100644
index bd95d71a631..00000000000
--- a/Build/source/texk/web2c/luatexdir/ptexmac.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* ptexmac.h
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-/* $Id$ */
-
-#ifndef PTEXMAC_H
-# define PTEXMAC_H
-
-/* Not all systems define it. */
-# ifndef M_PI
-# define M_PI 3.14159265358979323846
- /* pi */
-# define M_PI_2 1.5707963267948966192E0
- /* Hex 2^ 0 * 1.921FB54442D18 */
-# define M_PI_4 7.8539816339744830962E-1
- /* Hex 2^-1 * 1.921FB54442D18 */
-# endif
-
-# ifdef WIN32
-/* Why relying on gmalloc() ???*/
-# define gmalloc(n) xmalloc(n)
-# define gfree(p) free(p)
-# define inline __inline
-# define srandom(n) srand(n)
-# define random() rand()
-# endif
-
-/**********************************************************************/
-/* Pascal WEB macros */
-
-# define max_integer 0x7FFFFFFF
-# define max_dimen 0x3FFFFFFF
-
-# define obj_info(a) obj_tab[(a)].int0
-# define obj_link(a) obj_tab[(a)].int1
-# define obj_offset(a) obj_tab[(a)].int2
-# define obj_os_idx(a) obj_tab[(a)].int3
-# define obj_aux(a) obj_tab[(a)].int4
-# define obj_data_ptr obj_aux
-
-/* types of objects */
-# define obj_type_others 0 /* objects which are not linked in any list */
-# define obj_type_page 1 /* index of linked list of Page objects */
-# define obj_type_font 2 /* index of linked list of Fonts objects */
-# define obj_type_outline 3 /* index of linked list of outline objects */
-# define obj_type_dest 4 /* index of linked list of destination objects */
-# define obj_type_obj 5 /* index of linked list of raw objects */
-# define obj_type_xform 6 /* index of linked list of XObject forms */
-# define obj_type_ximage 7 /* index of linked list of XObject image */
-# define obj_type_thread 8 /* index of linked list of num article threads */
-# define head_tab_max obj_type_thread /* max index of |head_tab| */
-
-# define pdfroom(n) do { \
- if ((unsigned)(n + pdf_ptr) > (unsigned)pdf_buf_size) { \
- if (pdf_os_mode) \
- zpdf_os_get_os_buf(n); \
- else { \
- if ((unsigned)(n) > (unsigned)pdf_buf_size) \
- pdftex_fail("PDF output buffer overflowed"); \
- else \
- pdf_flush(); \
- } \
- } \
-} while (0)
-
-# define pdfout(c) do { \
- pdfroom(1); \
- pdf_buf[pdf_ptr++] = c; \
-} while (0)
-
-# define pdfoffset() (pdf_gone + pdf_ptr)
-
-/**********************************************************************/
-
-# define PRINTF_BUF_SIZE 1024
-# define MAX_CSTRING_LEN 1024 * 1024
-# define MAX_PSTRING_LEN 1024
-# define SMALL_BUF_SIZE 256
-# define SMALL_ARRAY_SIZE 256
-
-# define check_buf(size, buf_size) \
- if ((unsigned)(size) > (unsigned)(buf_size)) \
- pdftex_fail("buffer overflow: %d > %d at file %s, line %d", \
- (int)(size), (int)(buf_size), __FILE__, __LINE__ )
-
-# define append_char_to_buf(c, p, buf, buf_size) do { \
- if (c == 9) \
- c = 32; \
- if (c == 13 || c == EOF) \
- c = 10; \
- if (c != ' ' || (p > buf && p[-1] != 32)) { \
- check_buf(p - buf + 1, (buf_size)); \
- *p++ = c; \
- } \
-} while (0)
-
-# define append_eol(p, buf, buf_size) do { \
- check_buf(p - buf + 2, (buf_size)); \
- if (p - buf > 1 && p[-1] != 10) \
- *p++ = 10; \
- if (p - buf > 2 && p[-2] == 32) { \
- p[-2] = 10; \
- p--; \
- } \
- *p = 0; \
-} while (0)
-
-# define remove_eol(p, buf) do { \
- p = strend(buf) - 1; \
- if (*p == 10) \
- *p = 0; \
-} while (0)
-
-# define skip(p, c) if (*p == c) p++
-
-# define alloc_array(T, n, s) do { \
- if (T##_array == NULL) { \
- T##_limit = (s); \
- if ((unsigned)(n) > T##_limit) \
- T##_limit = (n); \
- T##_array = xtalloc(T##_limit, T##_entry); \
- T##_ptr = T##_array; \
- } \
- else if ((unsigned)(T##_ptr - T##_array + (n)) > (unsigned)(T##_limit)) { \
- last_ptr_index = T##_ptr - T##_array; \
- T##_limit *= 2; \
- if ((unsigned)(T##_ptr - T##_array + (n)) > (unsigned)(T##_limit)) \
- T##_limit = T##_ptr - T##_array + (n); \
- xretalloc(T##_array, T##_limit, T##_entry); \
- T##_ptr = T##_array + last_ptr_index; \
- } \
-} while (0)
-
-# define define_array(T) \
-T##_entry *T##_ptr, *T##_array = NULL; \
-size_t T##_limit
-
-# define xfree(p) do { if (p != NULL) free(p); p = NULL; } while (0)
-# define strend(s) strchr(s, 0)
-# define xtalloc XTALLOC
-# define xretalloc XRETALLOC
-
-# define set_cur_file_name(s) \
- cur_file_name = s; \
- pack_file_name(maketexstring(cur_file_name), get_nullstr(), get_nullstr())
-
-# define cmp_return(a, b) \
- if ((a) > (b)) \
- return 1; \
- if ((a) < (b)) \
- return -1
-
-# define str_prefix(s1, s2) (strncmp((s1), (s2), strlen(s2)) == 0)
-
-#endif /* PTEXMAC_H */
diff --git a/Build/source/texk/web2c/luatexdir/tex/align.h b/Build/source/texk/web2c/luatexdir/tex/align.h
new file mode 100644
index 00000000000..5afa7a754c8
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/align.h
@@ -0,0 +1,55 @@
+/* align.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: align.h 3100 2009-11-04 15:09:57Z taco $ */
+
+#ifndef ALIGN_H
+# define ALIGN_H 1
+
+/* We enter `\.{\\span}' into |eqtb| with |tab_mark| as its command code,
+and with |span_code| as the command modifier. This makes \TeX\ interpret it
+essentially the same as an alignment delimiter like `\.\&', yet it is
+recognizably different when we need to distinguish it from a normal delimiter.
+It also turns out to be useful to give a special |cr_code| to `\.{\\cr}',
+and an even larger |cr_cr_code| to `\.{\\crcr}'.
+
+The end of a template is represented by two ``frozen'' control sequences
+called \.{\\endtemplate}. The first has the command code |end_template|, which
+is |>outer_call|, so it will not easily disappear in the presence of errors.
+The |get_x_token| routine converts the first into the second, which has |endv|
+as its command code.
+*/
+
+# define tab_mark_cmd_code 1114113 /* {|biggest_char+2|} */
+# define span_code 1114114 /* {|biggest_char+3|} */
+# define cr_code (span_code+1) /* distinct from |span_code| and from any character */
+# define cr_cr_code (cr_code+1) /* this distinguishes \.{\\crcr} from \.{\\cr} */
+
+
+extern void init_align(void);
+extern void initialize_alignments(void);
+
+extern boolean fin_col(void);
+extern void fin_row(void);
+
+extern void align_peek(void);
+extern void insert_vj_template(void);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/align.w b/Build/source/texk/web2c/luatexdir/tex/align.w
new file mode 100644
index 00000000000..fd2d46b8f38
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/align.w
@@ -0,0 +1,1153 @@
+% align.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+\def\<#1>{$#1$}
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: align.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/align.w $";
+
+@ @c
+void fin_align(void);
+void init_row(void);
+void init_col(void);
+
+#define noDEBUG
+
+#define end_template_token (cs_token_flag+frozen_end_template)
+
+#define prev_depth cur_list.prev_depth_field
+#define space_factor cur_list.space_factor_field
+#define incompleat_noad cur_list.incompleat_noad_field
+
+#define every_cr equiv(every_cr_loc)
+#define display_indent dimen_par(display_indent_code)
+#define max_depth dimen_par(max_depth_code)
+#define pdf_ignored_dimen dimen_par(pdf_ignored_dimen_code)
+#define overfull_rule dimen_par(overfull_rule_code)
+
+@ 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.
+
+
+
+@ 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.
+
+@c
+#define u_part(A) vlink((A)+depth_offset) /* pointer to \<u_j> token list */
+#define v_part(A) vinfo((A)+depth_offset) /* pointer to \<v_j> token list */
+#define span_ptr(A) vinfo((A)+1) /* column spanning list */
+#define extra_info(A) vinfo((A)+list_offset) /* info to remember during template */
+
+
+@ Alignments can occur within alignments, so a small stack is used to access
+the alignrecord information. At each level we have a |preamble| pointer,
+indicating the beginning of the preamble list; a |cur_align| pointer,
+indicating the current position in the preamble list; a |cur_span| pointer,
+indicating the value of |cur_align| at the beginning of a sequence of
+spanned columns; a |cur_loop| pointer, indicating the tabskip glue before
+an alignrecord that should be copied next if the current list is extended;
+and the |align_state| variable, which indicates the nesting of braces so
+that \.{\\cr} and \.{\\span} and tab marks are properly intercepted.
+There also are pointers |cur_head| and |cur_tail| to the head and tail
+of a list of adjustments being moved out from horizontal mode to
+vertical~mode, and alike |cur_pre_head| and |cur_pre_tail| for pre-adjust
+lists.
+
+The current values of these nine quantities appear in global variables;
+when they have to be pushed down, they are stored in 6-word nodes, and
+|align_ptr| points to the topmost such node.
+
+@c
+#define preamble vlink(align_head) /* the current preamble list */
+
+pointer cur_align = null; /* current position in preamble list */
+pointer cur_span = null; /* start of currently spanned columns in preamble list */
+pointer cur_loop = null; /* place to copy when extending a periodic preamble */
+pointer align_ptr = null; /* most recently pushed-down alignment stack node */
+pointer cur_head = null, cur_tail = null; /* adjustment list pointers */
+pointer cur_pre_head = null, cur_pre_tail = null; /* pre-adjustment list pointers */
+
+/* The |align_state| and |preamble| variables are initialized elsewhere. */
+
+@ Alignment stack maintenance is handled by a pair of trivial routines
+called |push_alignment| and |pop_alignment|.
+
+@c
+void push_alignment(void)
+{
+ pointer p; /* the new alignment stack node */
+ p = new_node(align_stack_node, 0);
+ vinfo(p + 1) = align_ptr;
+ vlink(p + 1) = cur_align;
+ vinfo(p + 2) = preamble;
+ vlink(p + 2) = cur_span;
+ vinfo(p + 3) = cur_loop;
+ vlink(p + 3) = align_state;
+ vinfo(p + 4) = cur_head;
+ vlink(p + 4) = cur_tail;
+ vinfo(p + 5) = cur_pre_head;
+ vlink(p + 5) = cur_pre_tail;
+ align_ptr = p;
+ cur_head = new_node(temp_node, 0);
+}
+
+void pop_alignment(void)
+{
+ pointer p; /* the top alignment stack node */
+ flush_node(cur_head);
+ p = align_ptr;
+ cur_pre_tail = vlink(p + 5);
+ cur_pre_head = vinfo(p + 5);
+ cur_tail = vlink(p + 4);
+ cur_head = vinfo(p + 4);
+ align_state = vlink(p + 3);
+ cur_loop = vinfo(p + 3);
+ cur_span = vlink(p + 2);
+ preamble = vinfo(p + 2);
+ cur_align = vlink(p + 1);
+ align_ptr = vinfo(p + 1);
+ flush_node(p);
+}
+
+
+@ \TeX\ has eight procedures that govern alignments: |init_align| and
+|fin_align| are used at the very beginning and the very end; |init_row| and
+|fin_row| are used at the beginning and end of individual rows; |init_span|
+is used at the beginning of a sequence of spanned columns (possibly involving
+only one column); |init_col| and |fin_col| are used at the beginning and
+end of individual columns; and |align_peek| is used after \.{\\cr} to see
+whether the next item is \.{\\noalign}.
+
+We shall consider these routines in the order they are first used during
+the course of a complete \.{\\halign}, namely |init_align|, |align_peek|,
+|init_row|, |init_span|, |init_col|, |fin_col|, |fin_row|, |fin_align|.
+
+
+@ 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.
+
+Note that if the preamble contains `\.{\\global\\tabskip}', the `\.{\\global}'
+token survives in the preamble and the `\.{\\tabskip}' defines new
+tabskip glue (locally).
+
+@c
+void get_preamble_token(void)
+{
+ RESTART:
+ get_token();
+ while ((cur_chr == span_code) && (cur_cmd == tab_mark_cmd)) {
+ get_token(); /* this token will be expanded once */
+ if (cur_cmd > max_command_cmd) {
+ expand();
+ get_token();
+ }
+ }
+ if (cur_cmd == endv_cmd)
+ fatal_error("(interwoven alignment preambles are not allowed)");
+ if ((cur_cmd == assign_glue_cmd)
+ && (cur_chr == glue_base + tab_skip_code)) {
+ scan_optional_equals();
+ scan_glue(glue_val_level);
+ if (int_par(global_defs_code) > 0)
+ geq_define(glue_base + tab_skip_code, glue_ref_cmd, cur_val);
+ else
+ eq_define(glue_base + tab_skip_code, glue_ref_cmd, cur_val);
+ goto RESTART;
+ }
+}
+
+
+
+@ When \.{\\halign} or \.{\\valign} has been scanned in an appropriate
+mode, \TeX\ calls |init_align|, whose task is to get everything off to a
+good start. This mostly involves scanning the preamble and putting its
+information into the preamble list.
+@^preamble@>
+
+@c
+void init_align(void)
+{
+ /* label done, done1, done2, continue; */
+ pointer save_cs_ptr; /* |warning_index| value for error messages */
+ pointer p, r; /* for short-term temporary use */
+ save_cs_ptr = cur_cs; /* \.{\\halign} or \.{\\valign}, usually */
+ push_alignment();
+ align_state = -1000000; /* enter a new alignment level */
+
+ /* When \.{\\halign} is used as a displayed formula, there should be
+ no other pieces of mlists present. */
+
+ if ((cur_list.mode_field == mmode)
+ && ((cur_list.tail_field != cur_list.head_field)
+ || (incompleat_noad != null))) {
+ const char *hlp[] =
+ { "Displays can use special alignments (like \\eqalignno)",
+ "only if nothing but the alignment itself is between $$'s.",
+ "So I've deleted the formulas that preceded this alignment.",
+ NULL
+ };
+ tex_error("Improper \\halign inside $$'s", hlp);
+ flush_math();
+ }
+ push_nest(); /* enter a new semantic level */
+ /* In vertical modes, |prev_depth| already has the correct value. But
+ if we are in |mmode| (displayed formula mode), we reach out to the
+ enclosing vertical mode for the |prev_depth| value that produces the
+ correct baseline calculations. */
+ if (cur_list.mode_field == mmode) {
+ cur_list.mode_field = -vmode;
+ prev_depth = nest[nest_ptr - 2].prev_depth_field;
+ } else if (cur_list.mode_field > 0) {
+ cur_list.mode_field = -(cur_list.mode_field);
+ }
+ scan_spec(align_group);
+ /* Scan the preamble */
+ preamble = null;
+ cur_align = align_head;
+ cur_loop = null;
+ scanner_status = aligning;
+ warning_index = save_cs_ptr;
+ align_state = -1000000;
+ /* at this point, |cur_cmd=left_brace| */
+ while (true) {
+ /* Append the current tabskip glue to the preamble list */
+ r = new_param_glue(tab_skip_code);
+ vlink(cur_align) = r;
+ cur_align = vlink(cur_align);
+
+ if (cur_cmd == car_ret_cmd)
+ break; /* \.{\\cr} ends the preamble */
+
+ /* Scan preamble text until |cur_cmd| is |tab_mark| or |car_ret| */
+ /* Scan the template \<u_j>, putting the resulting token list in |hold_token_head| */
+ /* Spaces are eliminated from the beginning of a template. */
+
+ p = hold_token_head;
+ token_link(p) = null;
+ while (1) {
+ get_preamble_token();
+ if (cur_cmd == mac_param_cmd)
+ break;
+ if ((cur_cmd <= car_ret_cmd) && (cur_cmd >= tab_mark_cmd)
+ && (align_state == -1000000)) {
+ if ((p == hold_token_head) && (cur_loop == null)
+ && (cur_cmd == tab_mark_cmd)) {
+ cur_loop = cur_align;
+ } else {
+ const char *hlp[] =
+ { "There should be exactly one # between &'s, when an",
+ "\\halign or \\valign is being set up. In this case you had",
+ "none, so I've put one in; maybe that will work.",
+ NULL
+ };
+ back_input();
+ tex_error("Missing # inserted in alignment preamble", hlp);
+ break;
+ }
+ } else if ((cur_cmd != spacer_cmd) || (p != hold_token_head)) {
+ r = get_avail();
+ token_link(p) = r;
+ p = token_link(p);
+ token_info(p) = cur_tok;
+ }
+ }
+ r = new_node(align_record_node, 0);
+ vlink(cur_align) = r;
+ cur_align = vlink(cur_align); /* a new alignrecord */
+ span_ptr(cur_align) = end_span;
+ width(cur_align) = null_flag;
+ u_part(cur_align) = token_link(hold_token_head);
+ /* Scan the template \<v_j>, putting the resulting token list in |hold_token_head| */
+
+ p = hold_token_head;
+ token_link(p) = null;
+ while (1) {
+ CONTINUE:
+ get_preamble_token();
+ if ((cur_cmd <= car_ret_cmd) && (cur_cmd >= tab_mark_cmd)
+ && (align_state == -1000000))
+ break;
+ if (cur_cmd == mac_param_cmd) {
+ const char *hlp[] =
+ { "There should be exactly one # between &'s, when an",
+ "\\halign or \\valign is being set up. In this case you had",
+ "more than one, so I'm ignoring all but the first.",
+ NULL
+ };
+ tex_error("Only one # is allowed per tab", hlp);
+ goto CONTINUE;
+ }
+ r = get_avail();
+ token_link(p) = r;
+ p = token_link(p);
+ token_info(p) = cur_tok;
+ }
+ r = get_avail();
+ token_link(p) = r;
+ p = token_link(p);
+ token_info(p) = end_template_token; /* put \.{\\endtemplate} at the end */
+
+ v_part(cur_align) = token_link(hold_token_head);
+ }
+ scanner_status = normal;
+
+ new_save_level(align_group);
+ if (every_cr != null)
+ begin_token_list(every_cr, every_cr_text);
+ align_peek(); /* look for \.{\\noalign} or \.{\\omit} */
+}
+
+
+@ The tricky part about alignments is getting the templates into the
+scanner at the right time, and recovering control when a row or column
+is finished.
+
+We usually begin a row after each \.{\\cr} has been sensed, unless that
+\.{\\cr} is followed by \.{\\noalign} or by the right brace that terminates
+the alignment. The |align_peek| routine is used to look ahead and do
+the right thing; it either gets a new row started, or gets a \.{\\noalign}
+started, or finishes off the alignment.
+
+@c
+void align_peek(void)
+{
+ RESTART:
+ align_state = 1000000;
+ do {
+ get_x_or_protected();
+ } while (cur_cmd == spacer_cmd);
+ if (cur_cmd == no_align_cmd) {
+ scan_left_brace();
+ new_save_level(no_align_group);
+ if (cur_list.mode_field == -vmode)
+ normal_paragraph();
+ } else if (cur_cmd == right_brace_cmd) {
+ fin_align();
+ } else if ((cur_cmd == car_ret_cmd) && (cur_chr == cr_cr_code)) {
+ goto RESTART; /* ignore \.{\\crcr} */
+ } else {
+ init_row(); /* start a new row */
+ init_col(); /* start a new column and replace what we peeked at */
+ }
+}
+
+
+@ The parameter to |init_span| is a pointer to the alignrecord where the
+next column or group of columns will begin. A new semantic level is
+entered, so that the columns will generate a list for subsequent packaging.
+
+@c
+void init_span(pointer p)
+{
+ push_nest();
+ if (cur_list.mode_field == -hmode) {
+ space_factor = 1000;
+ } else {
+ prev_depth = pdf_ignored_dimen;
+ normal_paragraph();
+ }
+ cur_span = p;
+}
+
+
+@ To start a row (i.e., a `row' that rhymes with `dough' but not with `bough'),
+we enter a new semantic level, copy the first tabskip glue, and change
+from internal vertical mode to restricted horizontal mode or vice versa.
+The |space_factor| and |prev_depth| are not used on this semantic level,
+but we clear them to zero just to be tidy.
+
+@c
+void init_row(void)
+{
+ push_nest();
+ cur_list.mode_field = (-hmode - vmode) - cur_list.mode_field;
+ if (cur_list.mode_field == -hmode)
+ space_factor = 0;
+ else
+ prev_depth = 0;
+ tail_append(new_glue(glue_ptr(preamble)));
+ subtype(cur_list.tail_field) = tab_skip_code + 1;
+ cur_align = vlink(preamble);
+ cur_tail = cur_head;
+ cur_pre_tail = cur_pre_head;
+ init_span(cur_align);
+}
+
+
+@ When a column begins, we assume that |cur_cmd| is either |omit| or else
+the current token should be put back into the input until the \<u_j>
+template has been scanned. (Note that |cur_cmd| might be |tab_mark| or
+|car_ret|.) We also assume that |align_state| is approximately 1000000 at
+this time. We remain in the same mode, and start the template if it is
+called for.
+
+@c
+void init_col(void)
+{
+ extra_info(cur_align) = cur_cmd;
+ if (cur_cmd == omit_cmd)
+ align_state = 0;
+ else {
+ back_input();
+ begin_token_list(u_part(cur_align), u_template);
+ } /* now |align_state=1000000| */
+}
+
+
+@ The scanner sets |align_state| to zero when the \<u_j> template ends. When
+a subsequent \.{\\cr} or \.{\\span} or tab mark occurs with |align_state=0|,
+the scanner activates the following code, which fires up the \<v_j> template.
+We need to remember the |cur_chr|, which is either |cr_cr_code|, |cr_code|,
+|span_code|, or a character code, depending on how the column text has ended.
+
+This part of the program had better not be activated when the preamble
+to another alignment is being scanned, or when no alignment preamble is active.
+
+@c
+void insert_vj_template(void)
+{
+ if ((scanner_status == aligning) || (cur_align == null))
+ fatal_error("(interwoven alignment preambles are not allowed)");
+ cur_cmd = extra_info(cur_align);
+ extra_info(cur_align) = cur_chr;
+ if (cur_cmd == omit_cmd)
+ begin_token_list(omit_template, v_template);
+ else
+ begin_token_list(v_part(cur_align), v_template);
+ align_state = 1000000;
+}
+
+/* Determine the stretch order */
+#define determine_stretch_order() do { \
+ if (total_stretch[filll]!=0) o=filll; \
+ else if (total_stretch[fill]!=0) o=fill; \
+ else if (total_stretch[fil]!=0) o=fil; \
+ else if (total_stretch[sfi]!=0) o=sfi; \
+ else o=normal; \
+ } while (0)
+
+
+/* Determine the shrink order */
+#define determine_shrink_order() do { \
+ if (total_shrink[filll]!=0) o=filll; \
+ else if (total_shrink[fill]!=0) o=fill; \
+ else if (total_shrink[fil]!=0) o=fil; \
+ else if (total_shrink[sfi]!=0) o=sfi; \
+ else o=normal; \
+ } while (0)
+
+
+
+@ When the |endv| command at the end of a \<v_j> template comes through the
+scanner, things really start to happen; and it is the |fin_col| routine
+that makes them happen. This routine returns |true| if a row as well as a
+column has been finished.
+
+@c
+boolean fin_col(void)
+{
+ pointer p; /* the alignrecord after the current one */
+ pointer q, r; /* temporary pointers for list manipulation */
+ pointer s; /* a new span node */
+ pointer u; /* a new unset box */
+ scaled w; /* natural width */
+ unsigned char o; /* order of infinity */
+ halfword n; /* span counter */
+ if (cur_align == null)
+ confusion("endv");
+ q = vlink(cur_align);
+ if (q == null)
+ confusion("endv");
+ if (align_state < 500000)
+ fatal_error("(interwoven alignment preambles are not allowed)");
+ p = vlink(q);
+ /* If the preamble list has been traversed, check that the row has ended */
+ if ((p == null) && (extra_info(cur_align) < cr_code)) {
+ if (cur_loop != null) {
+ /* Lengthen the preamble periodically */
+ r = new_node(align_record_node, 0);
+ vlink(q) = r;
+ p = vlink(q); /* a new alignrecord */
+ span_ptr(p) = end_span;
+ width(p) = null_flag;
+ cur_loop = vlink(cur_loop);
+
+ /* Copy the templates from node |cur_loop| into node |p| */
+ q = hold_token_head;
+ r = u_part(cur_loop);
+ while (r != null) {
+ s = get_avail();
+ token_link(q) = s;
+ q = token_link(q);
+ token_info(q) = token_info(r);
+ r = token_link(r);
+ }
+ token_link(q) = null;
+ u_part(p) = token_link(hold_token_head);
+ q = hold_token_head;
+ r = v_part(cur_loop);
+ while (r != null) {
+ s = get_avail();
+ token_link(q) = s;
+ q = token_link(q);
+ token_info(q) = token_info(r);
+ r = token_link(r);
+ }
+ token_link(q) = null;
+ v_part(p) = token_link(hold_token_head);
+
+ cur_loop = vlink(cur_loop);
+ r = new_glue(glue_ptr(cur_loop));
+ vlink(p) = r;
+ } else {
+ const char *hlp[] =
+ { "You have given more \\span or & marks than there were",
+ "in the preamble to the \\halign or \\valign now in progress.",
+ "So I'll assume that you meant to type \\cr instead.",
+ NULL
+ };
+ extra_info(cur_align) = cr_code;
+ tex_error("Extra alignment tab has been changed to \\cr", hlp);
+ }
+ }
+ if (extra_info(cur_align) != span_code) {
+ unsave();
+ new_save_level(align_group);
+ /* Package an unset box for the current column and record its width */
+ if (cur_list.mode_field == -hmode) {
+ adjust_tail = cur_tail;
+ pre_adjust_tail = cur_pre_tail;
+ u = filtered_hpack(cur_list.head_field, cur_list.tail_field, 0,
+ additional, align_set_group, -1);
+ w = width(u);
+ cur_tail = adjust_tail;
+ adjust_tail = null;
+ cur_pre_tail = pre_adjust_tail;
+ pre_adjust_tail = null;
+ } else {
+ u = filtered_vpackage(vlink(cur_list.head_field), 0, additional, 0,
+ align_set_group, -1);
+ w = height(u);
+ }
+ n = min_quarterword; /* this represents a span count of 1 */
+ if (cur_span != cur_align) {
+ /* Update width entry for spanned columns */
+ q = cur_span;
+ do {
+ incr(n);
+ q = vlink(vlink(q));
+ } while (q != cur_align);
+ if (n > max_quarterword)
+ confusion("too many spans"); /* this can happen, but won't */
+ q = cur_span;
+ while (span_span(span_ptr(q)) < n) {
+ q = span_ptr(q);
+ }
+ if (span_span(span_ptr(q)) > n) {
+ s = new_span_node(span_ptr(q), n, w);
+ span_ptr(q) = s;
+ } else if (width(span_ptr(q)) < w) {
+ width(span_ptr(q)) = w;
+ }
+
+ } else if (w > width(cur_align)) {
+ width(cur_align) = w;
+ }
+ type(u) = unset_node;
+ span_count(u) = (quarterword) n;
+ determine_stretch_order();
+ glue_order(u) = o;
+ glue_stretch(u) = total_stretch[o];
+ determine_shrink_order();
+ glue_sign(u) = o;
+ glue_shrink(u) = total_shrink[o];
+ pop_nest();
+ vlink(cur_list.tail_field) = u;
+ cur_list.tail_field = u;
+
+ /* Copy the tabskip glue between columns */
+ tail_append(new_glue(glue_ptr(vlink(cur_align))));
+ subtype(cur_list.tail_field) = tab_skip_code + 1;
+
+ if (extra_info(cur_align) >= cr_code) {
+ return true;
+ }
+ init_span(p);
+ }
+ align_state = 1000000;
+ do {
+ get_x_or_protected();
+ } while (cur_cmd == spacer_cmd);
+ cur_align = p;
+ init_col();
+ return false;
+}
+
+
+
+@ A span node is a 3-word record containing |width|, |span_span|, and
+|span_ptr| fields. The |span_span| field indicates the number of
+spanned columns; the |span_ptr| field points to a span node for the same
+starting column, having a greater extent of spanning, or to
+|end_span|, which has the largest possible |span_span| field; the |width|
+field holds the largest natural width corresponding to a particular
+set of spanned columns.
+
+A list of the maximum widths so far, for spanned columns starting at a
+given column, begins with the |span_ptr| field of the alignrecord for
+that column. The code has to make sure that there is room for
+|span_ptr| in both the alignrecord and the span nodes, which is why
+|span_ptr| replaces |node_attr|.
+@^data structure assumptions@>
+
+The |new_span_node| function is defined in |texnodes.c|.
+
+@c
+#ifndef span_span
+# define span_span(A) vlink((A)+1) /* that is normally |alink| */
+#endif
+
+
+@ At the end of a row, we append an unset box to the current vlist (for
+\.{\\halign}) or the current hlist (for \.{\\valign}). This unset box
+contains the unset boxes for the columns, separated by the tabskip glue.
+Everything will be set later.
+
+@c
+void fin_row(void)
+{
+ pointer p; /* the new unset box */
+ if (cur_list.mode_field == -hmode) {
+ p = filtered_hpack(cur_list.head_field, cur_list.tail_field, 0,
+ additional, fin_row_group, -1);
+ pop_nest();
+ if (cur_pre_head != cur_pre_tail)
+ append_list(cur_pre_head, cur_pre_tail);
+ append_to_vlist(p);
+ if (cur_head != cur_tail)
+ append_list(cur_head, cur_tail);
+ } else {
+ p = filtered_vpackage(vlink(cur_list.head_field), 0, additional,
+ max_depth, fin_row_group, -1);
+ pop_nest();
+ vlink(cur_list.tail_field) = p;
+ cur_list.tail_field = p;
+ space_factor = 1000;
+ }
+ type(p) = unset_node;
+ glue_stretch(p) = 0;
+ if (every_cr != null)
+ begin_token_list(every_cr, every_cr_text);
+ align_peek();
+ /* note that |glue_shrink(p)=0| since |glue_shrink==shift_amount| */
+}
+
+
+@ Finally, we will reach the end of the alignment, and we can breathe a
+sigh of relief that memory hasn't overflowed. All the unset boxes will now be
+set so that the columns line up, taking due account of spanned columns.
+
+@c
+void fin_align(void)
+{
+ pointer p, q, r, s, u, v, rr; /* registers for the list operations */
+ scaled t, w; /* width of column */
+ scaled o; /* shift offset for unset boxes */
+ halfword n; /* matching span amount */
+ scaled rule_save; /* temporary storage for |overfull_rule| */
+ halfword pd; /* temporary storage for |prev_depth| */
+ if (cur_group != align_group)
+ confusion("align1");
+ unsave(); /* that |align_group| was for individual entries */
+ if (cur_group != align_group)
+ confusion("align0");
+ unsave(); /* that |align_group| was for the whole alignment */
+ if (nest[nest_ptr - 1].mode_field == mmode)
+ o = display_indent;
+ else
+ o = 0;
+ /* Go through the preamble list, determining the column widths and
+ * changing the alignrecords to dummy unset boxes
+ */
+
+/* It's time now to dismantle the preamble list and to compute the column
+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+|min_quarterword|$ in their
+|link| fields. The values of $w_{ii}$ were initialized to |null_flag|, which
+we regard as $-\infty$.
+
+The final column widths are defined by the formula
+$$w_j=\max_{1\L i\L j}\biggl( w_{ij}-\sum_{i\L k<j}(t_k+w_k)\biggr),$$
+where $t_k$ is the natural width of the tabskip glue between columns
+$k$ and~$k+1$. However, if $w_{ij}=-\infty$ for all |i| in the range
+|1<=i<=j| (i.e., if every entry that involved column~|j| also involved
+column~|j+1|), we let $w_j=0$, and we zero out the tabskip glue after
+column~|j|.
+
+\TeX\ computes these values by using the following scheme: First $w_1=w_{11}$.
+Then replace $w_{2j}$ by $\max(w_{2j},w_{1j}-t_1-w_1)$, for all $j>1$.
+Then $w_2=w_{22}$. Then replace $w_{3j}$ by $\max(w_{3j},w_{2j}-t_2-w_2)$
+for all $j>2$; and so on. If any $w_j$ turns out to be $-\infty$, its
+value is changed to zero and so is the next tabskip.
+*/
+ q = vlink(preamble);
+ do {
+ flush_list(u_part(q));
+ flush_list(v_part(q));
+ p = vlink(vlink(q));
+ if (width(q) == null_flag) {
+ /* Nullify |width(q)| and the tabskip glue following this column */
+ width(q) = 0;
+ r = vlink(q);
+ s = glue_ptr(r);
+ if (s != zero_glue) {
+ add_glue_ref(zero_glue);
+ delete_glue_ref(s);
+ glue_ptr(r) = zero_glue;
+ }
+ }
+ if (span_ptr(q) != end_span) {
+ /* Merge the widths in the span nodes of |q| with those of |p|,
+ destroying the span nodes of |q| */
+ /*
+ Merging of two span-node lists is a typical exercise in the manipulation of
+ linearly linked data structures. The essential invariant in the following
+ |repeat| loop is that we want to dispense with node |r|, in |q|'s list,
+ and |u| is its successor; all nodes of |p|'s list up to and including |s|
+ have been processed, and the successor of |s| matches |r| or precedes |r|
+ or follows |r|, according as |link(r)=n| or |link(r)>n| or |link(r)<n|.
+ */
+ t = width(q) + width(glue_ptr(vlink(q)));
+ r = span_ptr(q);
+ s = end_span;
+ span_ptr(s) = p;
+ n = min_quarterword + 1;
+ do {
+ width(r) = width(r) - t;
+ u = span_ptr(r);
+ while (span_span(r) > n) {
+ s = span_ptr(s);
+ n = span_span(span_ptr(s)) + 1;
+ }
+ if (span_span(r) < n) {
+ span_ptr(r) = span_ptr(s);
+ span_ptr(s) = r;
+ decr(span_span(r));
+ s = r;
+ } else {
+ if (width(r) > width(span_ptr(s)))
+ width(span_ptr(s)) = width(r);
+ flush_node(r);
+ }
+ r = u;
+ } while (r != end_span);
+ }
+ type(q) = unset_node;
+ span_count(q) = min_quarterword;
+ height(q) = 0;
+ depth(q) = 0;
+ glue_order(q) = normal;
+ glue_sign(q) = normal;
+ glue_stretch(q) = 0;
+ glue_shrink(q) = 0;
+ q = p;
+ } while (q != null);
+
+ /* Package the preamble list, to determine the actual tabskip glue amounts,
+ and let |p| point to this prototype box */
+ /* Now the preamble list has been converted to a list of alternating unset
+ boxes and tabskip glue, where the box widths are equal to the final
+ column sizes. In case of \.{\\valign}, we change the widths to heights,
+ so that a correct error message will be produced if the alignment is
+ overfull or underfull.
+ */
+
+ decr(save_ptr);
+ pack_begin_line = -cur_list.ml_field;
+ if (cur_list.mode_field == -vmode) {
+ rule_save = overfull_rule;
+ overfull_rule = 0; /* prevent rule from being packaged */
+ p = hpack(preamble, saved_value(0), saved_level(0), -1);
+ overfull_rule = rule_save;
+ } else {
+ q = vlink(preamble);
+ do {
+ height(q) = width(q);
+ width(q) = 0;
+ q = vlink(vlink(q));
+ } while (q != null);
+ p = filtered_vpackage(preamble, saved_value(0), saved_level(0),
+ max_depth, preamble_group, -1);
+ q = vlink(preamble);
+ do {
+ width(q) = height(q);
+ height(q) = 0;
+ q = vlink(vlink(q));
+ } while (q != null);
+ }
+ pack_begin_line = 0;
+
+ /* Set the glue in all the unset boxes of the current list */
+ q = vlink(cur_list.head_field);
+ s = cur_list.head_field;
+ while (q != null) {
+ if (!is_char_node(q)) {
+ if (type(q) == unset_node) {
+ /* Set the unset box |q| and the unset boxes in it */
+ /* The unset box |q| represents a row that contains one or more unset boxes,
+ depending on how soon \.{\\cr} occurred in that row. */
+
+ if (cur_list.mode_field == -vmode) {
+ type(q) = hlist_node;
+ subtype(q) = 0;
+ width(q) = width(p);
+ } else {
+ type(q) = vlist_node;
+ subtype(q) = 0;
+ height(q) = height(p);
+ }
+ glue_order(q) = glue_order(p);
+ glue_sign(q) = glue_sign(p);
+ glue_set(q) = glue_set(p);
+ shift_amount(q) = o;
+ r = vlink(list_ptr(q));
+ s = vlink(list_ptr(p));
+ do {
+ /* Set the glue in node |r| and change it from an unset node */
+ /* A box made from spanned columns will be followed by tabskip glue nodes and
+ by empty boxes as if there were no spanning. This permits perfect alignment
+ of subsequent entries, and it prevents values that depend on floating point
+ arithmetic from entering into the dimensions of any boxes.
+ */
+ n = span_count(r);
+ t = width(s);
+ w = t;
+ u = hold_head;
+ while (n > min_quarterword) {
+ decr(n);
+ /* Append tabskip glue and an empty box to list |u|,
+ and update |s| and |t| as the prototype nodes are passed */
+
+ s = vlink(s);
+ v = glue_ptr(s);
+ vlink(u) = new_glue(v);
+ u = vlink(u);
+ subtype(u) = tab_skip_code + 1;
+ t = t + width(v);
+ if (glue_sign(p) == stretching) {
+ if (stretch_order(v) == glue_order(p))
+ t = t +
+ round(float_cast(glue_set(p)) *
+ float_cast(stretch(v)));
+ } else if (glue_sign(p) == shrinking) {
+ if (shrink_order(v) == glue_order(p))
+ t = t -
+ round(float_cast(glue_set(p)) *
+ float_cast(shrink(v)));
+ }
+ s = vlink(s);
+ rr = new_null_box();
+ vlink(u) = rr;
+ u = vlink(u);
+ t = t + width(s);
+ if (cur_list.mode_field == -vmode) {
+ width(u) = width(s);
+ } else {
+ type(u) = vlist_node;
+ height(u) = width(s);
+ }
+
+ }
+ if (cur_list.mode_field == -vmode) {
+ /* Make the unset node |r| into an |hlist_node| of width |w|,
+ setting the glue as if the width were |t| */
+
+ height(r) = height(q);
+ depth(r) = depth(q);
+ if (t == width(r)) {
+ glue_sign(r) = normal;
+ glue_order(r) = normal;
+ set_glue_ratio_zero(glue_set(r));
+ } else if (t > width(r)) {
+ glue_sign(r) = stretching;
+ if (glue_stretch(r) == 0)
+ set_glue_ratio_zero(glue_set(r));
+ else
+ glue_set(r) =
+ unfloat((double) (t - width(r)) /
+ glue_stretch(r));
+ } else {
+ glue_order(r) = glue_sign(r);
+ glue_sign(r) = shrinking;
+ if (glue_shrink(r) == 0)
+ set_glue_ratio_zero(glue_set(r));
+ else if ((glue_order(r) == normal)
+ && (width(r) - t > glue_shrink(r)))
+ set_glue_ratio_one(glue_set(r));
+ else
+ glue_set(r) =
+ unfloat((double) (width(r) - t) /
+ glue_shrink(r));
+ }
+ width(r) = w;
+ type(r) = hlist_node;
+
+ } else {
+ /* Make the unset node |r| into a |vlist_node| of height |w|,
+ setting the glue as if the height were |t| */
+
+ width(r) = width(q);
+ if (t == height(r)) {
+ glue_sign(r) = normal;
+ glue_order(r) = normal;
+ set_glue_ratio_zero(glue_set(r));
+ } else if (t > height(r)) {
+ glue_sign(r) = stretching;
+ if (glue_stretch(r) == 0)
+ set_glue_ratio_zero(glue_set(r));
+ else
+ glue_set(r) =
+ unfloat((t - height(r)) / glue_stretch(r));
+ } else {
+ glue_order(r) = glue_sign(r);
+ glue_sign(r) = shrinking;
+ if (glue_shrink(r) == 0)
+ set_glue_ratio_zero(glue_set(r));
+ else if ((glue_order(r) == normal)
+ && (height(r) - t > glue_shrink(r)))
+ set_glue_ratio_one(glue_set(r));
+ else
+ glue_set(r) =
+ unfloat((height(r) - t) / glue_shrink(r));
+ }
+ height(r) = w;
+ type(r) = vlist_node;
+
+ }
+ subtype(r) = 0;
+ shift_amount(r) = 0;
+ if (u != hold_head) { /* append blank boxes to account for spanned nodes */
+ vlink(u) = vlink(r);
+ vlink(r) = vlink(hold_head);
+ r = u;
+ }
+
+ r = vlink(vlink(r));
+ s = vlink(vlink(s));
+ } while (r != null);
+
+ } else if (type(q) == rule_node) {
+ /* Make the running dimensions in rule |q| extend to the
+ boundaries of the alignment */
+ if (is_running(width(q)))
+ width(q) = width(p);
+ if (is_running(height(q)))
+ height(q) = height(p);
+ if (is_running(depth(q)))
+ depth(q) = depth(p);
+ if (o != 0) {
+ r = vlink(q);
+ vlink(q) = null;
+ q = hpack(q, 0, additional, -1);
+ shift_amount(q) = o;
+ vlink(q) = r;
+ vlink(s) = q;
+ }
+ }
+ }
+ s = q;
+ q = vlink(q);
+ }
+ flush_node_list(p);
+ pop_alignment();
+ /* Insert the current list into its environment */
+ /* We now have a completed alignment, in the list that starts at |cur_list.head_field|
+ and ends at |cur_list.tail_field|. This list will be merged with the one that encloses
+ it. (In case the enclosing mode is |mmode|, for displayed formulas,
+ we will need to insert glue before and after the display; that part of the
+ program will be deferred until we're more familiar with such operations.)
+ */
+ pd = cur_list.prev_depth_field;
+ p = vlink(cur_list.head_field);
+ q = cur_list.tail_field;
+ pop_nest();
+ if (cur_list.mode_field == mmode) {
+ finish_display_alignment(p, q, pd);
+ } else {
+ vlink(cur_list.tail_field) = p;
+ if (p != null)
+ cur_list.tail_field = q;
+ if (cur_list.mode_field == vmode) {
+ if (!output_active)
+ lua_node_filter_s(buildpage_filter_callback, "alignment");
+ build_page();
+ }
+ }
+}
+
+
+
+@ The token list |omit_template| just referred to is a constant token
+list that contains the special control sequence \.{\\endtemplate} only.
+
+@c
+void initialize_alignments(void)
+{
+ token_info(omit_template) = end_template_token; /* |link(omit_template)=null| */
+ span_span(end_span) = max_quarterword + 1;
+ span_ptr(end_span) = null;
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/arithmetic.h b/Build/source/texk/web2c/luatexdir/tex/arithmetic.h
new file mode 100644
index 00000000000..89dce4e4f74
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/arithmetic.h
@@ -0,0 +1,81 @@
+/* arithmetic.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: arithmetic.h 3477 2010-03-12 13:59:34Z taco $ */
+
+#ifndef ARITHMETIC_H
+# define ARITHMETIC_H
+
+/* |incr| and |decr| are in texmfmp.h */
+
+ /* #define incr(A) (A)++ *//* increase a variable by unity */
+ /* #define decr(A) (A)-- *//* decrease a variable by unity */
+
+# define negate(A) (A)=-(A) /* change the sign of a variable */
+
+# undef half
+extern int half(int x);
+
+/*
+Fixed-point arithmetic is done on {\sl scaled integers\/} that are multiples
+of $2^{-16}$. In other words, a binary point is assumed to be sixteen bit
+positions from the right end of a binary computer word.
+*/
+
+# define unity 0200000 /* $2^{16}$, represents 1.00000 */
+# define two 0400000 /* $2^{17}$, represents 2.00000 */
+
+typedef unsigned int nonnegative_integer; /* $0\L x<2^{31}$ */
+
+extern scaled round_decimals(int k);
+extern void print_scaled(scaled s);
+
+extern boolean arith_error;
+extern scaled tex_remainder;
+
+extern scaled mult_and_add(int n, scaled x, scaled y, scaled max_answer);
+
+# define nx_plus_y(A,B,C) mult_and_add((A),(B),(C),07777777777)
+# define mult_integers(A,B) mult_and_add((A),(B),0,017777777777)
+
+extern scaled x_over_n(scaled x, int n);
+extern scaled xn_over_d(scaled x, int n, int d);
+
+# define inf_bad 10000 /* infinitely bad value */
+
+extern halfword badness(scaled t, scaled s);
+
+# define set_glue_ratio_zero(A) (A)=0.0 /* store the representation of zero ratio */
+# define set_glue_ratio_one(A) (A)=1.0 /* store the representation of unit ratio */
+# define float_cast(A) (float)(A) /* convert from |glue_ratio| to type |real| */
+# define unfloat(A) (glue_ratio)(A) /* convert from |real| to type |glue_ratio| */
+# define float_constant(A) (float)A /* convert |integer| constant to |real| */
+# define float_round round
+
+extern void initialize_arithmetic(void);
+
+extern scaled random_seed; /* the default random seed */
+
+extern void init_randoms(int seed);
+extern int unif_rand(int x);
+extern int norm_rand(void);
+
+extern int fix_int(int val, int min, int max);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/arithmetic.w b/Build/source/texk/web2c/luatexdir/tex/arithmetic.w
new file mode 100644
index 00000000000..eec0b309b7e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/arithmetic.w
@@ -0,0 +1,734 @@
+% arithmetic.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+\def\MP{MetaPost}
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: arithmetic.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/arithmetic.w $";
+
+
+@ The principal computations performed by \TeX\ are done entirely in terms of
+integers less than $2^{31}$ in magnitude; and divisions are done only when both
+dividend and divisor are nonnegative. Thus, the arithmetic specified in this
+program can be carried out in exactly the same way on a wide variety of
+computers, including some small ones. Why? Because the arithmetic
+calculations need to be spelled out precisely in order to guarantee that
+\TeX\ will produce identical output on different machines. If some
+quantities were rounded differently in different implementations, we would
+find that line breaks and even page breaks might occur in different places.
+Hence the arithmetic of \TeX\ has been designed with care, and systems that
+claim to be implementations of \TeX82 should follow precisely the
+@:TeX82}{\TeX82@>
+calculations as they appear in the present program.
+
+(Actually there are three places where \TeX\ uses |div| with a possibly negative
+numerator. These are harmless; see |div| in the index. Also if the user
+sets the \.{\\time} or the \.{\\year} to a negative value, some diagnostic
+information will involve negative-numerator division. The same remarks
+apply for |mod| as well as for |div|.)
+
+Here is a routine that calculates half of an integer, using an
+unambiguous convention with respect to signed odd numbers.
+
+@c
+int half(int x)
+{
+ if (odd(x))
+ return ((x + 1) / 2);
+ else
+ return (x / 2);
+}
+
+
+@ The following function is used to create a scaled integer from a given decimal
+fraction $(.d_0d_1\ldots d_{k-1})$, where |0<=k<=17|. The digit $d_i$ is
+given in |dig[i]|, and the calculation produces a correctly rounded result.
+
+@c
+scaled round_decimals(int k)
+{ /* converts a decimal fraction */
+ int a; /* the accumulator */
+ a = 0;
+ while (k-- > 0) {
+ a = (a + dig[k] * two) / 10;
+ }
+ return ((a + 1) / 2);
+}
+
+
+@ Conversely, here is a procedure analogous to |print_int|. If the output
+of this procedure is subsequently read by \TeX\ and converted by the
+|round_decimals| routine above, it turns out that the original value will
+be reproduced exactly; the ``simplest'' such decimal number is output,
+but there is always at least one digit following the decimal point.
+
+The invariant relation in the \&{repeat} loop is that a sequence of
+decimal digits yet to be printed will yield the original number if and only if
+they form a fraction~$f$ in the range $s-\delta\L10\cdot2^{16}f<s$.
+We can stop if and only if $f=0$ satisfies this condition; the loop will
+terminate before $s$ can possibly become zero.
+
+@c
+void print_scaled(scaled s)
+{ /* prints scaled real, rounded to five digits */
+ scaled delta; /* amount of allowable inaccuracy */
+ if (s < 0) {
+ print_char('-');
+ negate(s); /* print the sign, if negative */
+ }
+ print_int(s / unity); /* print the integer part */
+ print_char('.');
+ s = 10 * (s % unity) + 5;
+ delta = 10;
+ do {
+ if (delta > unity)
+ s = s + 0100000 - 50000; /* round the last digit */
+ print_char('0' + (s / unity));
+ s = 10 * (s % unity);
+ delta = delta * 10;
+ } while (s > delta);
+}
+
+@ Physical sizes that a \TeX\ user specifies for portions of documents are
+represented internally as scaled points. Thus, if we define an `sp' (scaled
+@^sp@>
+point) as a unit equal to $2^{-16}$ printer's points, every dimension
+inside of \TeX\ is an integer number of sp. There are exactly
+4,736,286.72 sp per inch. Users are not allowed to specify dimensions
+larger than $2^{30}-1$ sp, which is a distance of about 18.892 feet (5.7583
+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@>
+dimensions are added or subtracted. This could be done by inserting a
+few dozen tests of the form `\ignorespaces|if x>=010000000000 then
+@t\\{report\_overflow}@>|', but the chance of overflow is so remote that
+such tests do not seem worthwhile.
+
+\TeX\ needs to do only a few arithmetic operations on scaled quantities,
+other than addition and subtraction, and the following subroutines do most of
+the work. A single computation might use several subroutine calls, and it is
+desirable to avoid producing multiple error messages in case of arithmetic
+overflow; so the routines set the global variable |arith_error| to |true|
+instead of reporting errors directly to the user. Another global variable,
+|tex_remainder|, holds the remainder after a division.
+
+@c
+boolean arith_error; /* has arithmetic overflow occurred recently? */
+scaled tex_remainder; /* amount subtracted to get an exact division */
+
+
+@ The first arithmetical subroutine we need computes $nx+y$, where |x|
+and~|y| are |scaled| and |n| is an integer. We will also use it to
+multiply integers.
+
+@c
+scaled mult_and_add(int n, scaled x, scaled y, scaled max_answer)
+{
+ if (n == 0)
+ return y;
+ if (n < 0) {
+ negate(x);
+ negate(n);
+ }
+ if (((x <= (max_answer - y) / n) && (-x <= (max_answer + y) / n))) {
+ return (n * x + y);
+ } else {
+ arith_error = true;
+ return 0;
+ }
+}
+
+@ We also need to divide scaled dimensions by integers.
+@c
+scaled x_over_n(scaled x, int n)
+{
+ boolean negative; /* should |tex_remainder| be negated? */
+ negative = false;
+ if (n == 0) {
+ arith_error = true;
+ tex_remainder = x;
+ return 0;
+ } else {
+ if (n < 0) {
+ negate(x);
+ negate(n);
+ negative = true;
+ }
+ if (x >= 0) {
+ tex_remainder = x % n;
+ if (negative)
+ negate(tex_remainder);
+ return (x / n);
+ } else {
+ tex_remainder = -((-x) % n);
+ if (negative)
+ negate(tex_remainder);
+ return (-((-x) / n));
+ }
+ }
+}
+
+
+@ Then comes the multiplication of a scaled number by a fraction |n/d|,
+where |n| and |d| are nonnegative integers |<=@t$2^{16}$@>| and |d| is
+positive. It would be too dangerous to multiply by~|n| and then divide
+by~|d|, in separate operations, since overflow might well occur; and it
+would be too inaccurate to divide by |d| and then multiply by |n|. Hence
+this subroutine simulates 1.5-precision arithmetic.
+
+@c
+scaled xn_over_d(scaled x, int n, int d)
+{
+ nonnegative_integer t, u, v, xx, dd; /* intermediate quantities */
+ boolean positive = true; /* was |x>=0|? */
+ if (x < 0) {
+ negate(x);
+ positive = false;
+ }
+ xx = (nonnegative_integer) x;
+ dd = (nonnegative_integer) d;
+ t = ((xx % 0100000) * (nonnegative_integer) n);
+ u = ((xx / 0100000) * (nonnegative_integer) n + (t / 0100000));
+ v = (u % dd) * 0100000 + (t % 0100000);
+ if (u / dd >= 0100000)
+ arith_error = true;
+ else
+ u = 0100000 * (u / dd) + (v / dd);
+ if (positive) {
+ tex_remainder = (int) (v % dd);
+ return (scaled) u;
+ } else {
+ /* casts are for ms cl */
+ tex_remainder = -(int) (v % dd);
+ return -(scaled) (u);
+ }
+}
+
+
+@ The next subroutine is used to compute the ``badness'' of glue, when a
+total~|t| is supposed to be made from amounts that sum to~|s|. According
+to {\sl The \TeX book}, the badness of this situation is $100(t/s)^3$;
+however, badness is simply a heuristic, so we need not squeeze out the
+last drop of accuracy when computing it. All we really want is an
+approximation that has similar properties.
+@:TeXbook}{\sl The \TeX book@>
+
+The actual method used to compute the badness is easier to read from the
+program than to describe in words. It produces an integer value that is a
+reasonably close approximation to $100(t/s)^3$, and all implementations
+of \TeX\ should use precisely this method. Any badness of $2^{13}$ or more is
+treated as infinitely bad, and represented by 10000.
+
+It is not difficult to prove that $$\hbox{|badness(t+1,s)>=badness(t,s)
+>=badness(t,s+1)|}.$$ The badness function defined here is capable of
+computing at most 1095 distinct values, but that is plenty.
+
+@c
+halfword badness(scaled t, scaled s)
+{ /* compute badness, given |t>=0| */
+ int r; /* approximation to $\alpha t/s$, where $\alpha^3\approx
+ 100\cdot2^{18}$ */
+ if (t == 0) {
+ return 0;
+ } else if (s <= 0) {
+ return inf_bad;
+ } else {
+ if (t <= 7230584)
+ r = (t * 297) / s; /* $297^3=99.94\times2^{18}$ */
+ else if (s >= 1663497)
+ r = t / (s / 297);
+ else
+ r = t;
+ if (r > 1290)
+ return inf_bad; /* $1290^3<2^{31}<1291^3$ */
+ else
+ return ((r * r * r + 0400000) / 01000000);
+ /* that was $r^3/2^{18}$, rounded to the nearest integer */
+ }
+}
+
+
+@ When \TeX\ ``packages'' a list into a box, it needs to calculate the
+proportionality ratio by which the glue inside the box should stretch
+or shrink. This calculation does not affect \TeX's decision making,
+so the precise details of rounding, etc., in the glue calculation are not
+of critical importance for the consistency of results on different computers.
+
+We shall use the type |glue_ratio| for such proportionality ratios.
+A glue ratio should take the same amount of memory as an
+|integer| (usually 32 bits) if it is to blend smoothly with \TeX's
+other data structures. Thus |glue_ratio| should be equivalent to
+|short_real| in some implementations of PASCAL. Alternatively,
+it is possible to deal with glue ratios using nothing but fixed-point
+arithmetic; see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the
+routines cited there must be modified to allow negative glue ratios.)
+@^system dependencies@>
+
+
+@ This section is (almost) straight from MetaPost. I had to change
+the types (use |integer| instead of |fraction|), but that should
+not have any influence on the actual calculations (the original
+comments refer to quantities like |fraction_four| ($2^{30}$), and
+that is the same as the numeric representation of |max_dimen|).
+
+I've copied the low-level variables and routines that are needed, but
+only those (e.g. |m_log|), not the accompanying ones like |m_exp|. Most
+of the following low-level numeric routines are only needed within the
+calculation of |norm_rand|. I've been forced to rename |make_fraction|
+to |make_frac| because TeX already has a routine by that name with
+a wholly different function (it creates a |fraction_noad| for math
+typesetting) -- Taco
+
+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.
+
+@c
+static int randoms[55]; /* the last 55 random values generated */
+static int j_random; /* the number of unused |randoms| */
+scaled random_seed; /* the default random seed */
+
+@ A small bit of metafont is needed.
+
+@c
+#define fraction_half 01000000000 /* $2^{27}$, represents 0.50000000 */
+#define fraction_one 02000000000 /* $2^{28}$, represents 1.00000000 */
+#define fraction_four 010000000000 /* $2^{30}$, represents 4.00000000 */
+#define el_gordo 017777777777 /* $2^{31}-1$, the largest value that \MP\ likes */
+
+@ The |make_frac| routine produces the |fraction| equivalent of
+|p/q|, given integers |p| and~|q|; it computes the integer
+$f=\lfloor2^{28}p/q+{1\over2}\rfloor$, when $p$ and $q$ are
+positive. If |p| and |q| are both of the same scaled type |t|,
+the ``type relation'' |make_frac(t,t)=fraction| is valid;
+and it's also possible to use the subroutine ``backwards,'' using
+the relation |make_frac(t,fraction)=t| between scaled types.
+
+If the result would have magnitude $2^{31}$ or more, |make_frac|
+sets |arith_error:=true|. Most of \MP's internal computations have
+been designed to avoid this sort of error.
+
+If this subroutine were programmed in assembly language on a typical
+machine, we could simply compute |(@t$2^{28}$@>*p)div q|, since a
+double-precision product can often be input to a fixed-point division
+instruction. But when we are restricted to PASCAL arithmetic it
+is necessary either to resort to multiple-precision maneuvering
+or to use a simple but slow iteration. The multiple-precision technique
+would be about three times faster than the code adopted here, but it
+would be comparatively long and tricky, involving about sixteen
+additional multiplications and divisions.
+
+This operation is part of \MP's ``inner loop''; indeed, it will
+consume nearly 10\%! of the running time (exclusive of input and output)
+if the code below is left unchanged. A machine-dependent recoding
+will therefore make \MP\ run faster. The present implementation
+is highly portable, but slow; it avoids multiplication and division
+except in the initial stage. System wizards should be careful to
+replace it with a routine that is guaranteed to produce identical
+results in all cases.
+@^system dependencies@>
+
+As noted below, a few more routines should also be replaced by machine-dependent
+code, for efficiency. But when a procedure is not part of the ``inner loop,''
+such changes aren't advisable; simplicity and robustness are
+preferable to trickery, unless the cost is too high.
+
+@c
+static int make_frac(int p, int q)
+{
+ int f; /* the fraction bits, with a leading 1 bit */
+ int n; /* the integer part of $\vert p/q\vert$ */
+ register int be_careful; /* disables certain compiler optimizations */
+ boolean negative = false; /* should the result be negated? */
+ if (p < 0) {
+ negate(p);
+ negative = true;
+ }
+ if (q <= 0) {
+#ifdef DEBUG
+ if (q == 0)
+ confusion("/");
+#endif
+ negate(q);
+ negative = !negative;
+ }
+ n = p / q;
+ p = p % q;
+ if (n >= 8) {
+ arith_error = true;
+ if (negative)
+ return (-el_gordo);
+ else
+ return el_gordo;
+ } else {
+ n = (n - 1) * fraction_one;
+ /* Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$ */
+ /* The |repeat| loop here preserves the following invariant relations
+ between |f|, |p|, and~|q|:
+ (i)~|0<=p<q|; (ii)~$fq+p=2^k(q+p_0)$, where $k$ is an integer and
+ $p_0$ is the original value of~$p$.
+
+ Notice that the computation specifies
+ |(p-q)+p| instead of |(p+p)-q|, because the latter could overflow.
+ Let us hope that optimizing compilers do not miss this point; a
+ special variable |be_careful| is used to emphasize the necessary
+ order of computation. Optimizing compilers should keep |be_careful|
+ in a register, not store it in memory.
+ */
+ f = 1;
+ do {
+ be_careful = p - q;
+ p = be_careful + p;
+ if (p >= 0)
+ f = f + f + 1;
+ else {
+ f += f;
+ p = p + q;
+ }
+ } while (f < fraction_one);
+ be_careful = p - q;
+ if (be_careful + p >= 0)
+ incr(f);
+
+ if (negative)
+ return (-(f + n));
+ else
+ return (f + n);
+ }
+}
+
+@ @c
+static int take_frac(int q, int f)
+{
+ int p; /* the fraction so far */
+ int n; /* additional multiple of $q$ */
+ register int be_careful; /* disables certain compiler optimizations */
+ boolean negative = false; /* should the result be negated? */
+ /* Reduce to the case that |f>=0| and |q>0| */
+ if (f < 0) {
+ negate(f);
+ negative = true;
+ }
+ if (q < 0) {
+ negate(q);
+ negative = !negative;
+ }
+
+ if (f < fraction_one) {
+ n = 0;
+ } else {
+ n = f / fraction_one;
+ f = f % fraction_one;
+ if (q <= el_gordo / n) {
+ n = n * q;
+ } else {
+ arith_error = true;
+ n = el_gordo;
+ }
+ }
+ f = f + fraction_one;
+ /* Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$ */
+ /* The invariant relations in this case are (i)~$\lfloor(qf+p)/2^k\rfloor
+ =\lfloor qf_0/2^{28}+{1\over2}\rfloor$, where $k$ is an integer and
+ $f_0$ is the original value of~$f$; (ii)~$2^k\L f<2^{k+1}$.
+ */
+ p = fraction_half; /* that's $2^{27}$; the invariants hold now with $k=28$ */
+ if (q < fraction_four) {
+ do {
+ if (odd(f))
+ p = halfp(p + q);
+ else
+ p = halfp(p);
+ f = halfp(f);
+ } while (f != 1);
+ } else {
+ do {
+ if (odd(f))
+ p = p + halfp(q - p);
+ else
+ p = halfp(p);
+ f = halfp(f);
+ } while (f != 1);
+ }
+
+ be_careful = n - el_gordo;
+ if (be_careful + p > 0) {
+ arith_error = true;
+ n = el_gordo - p;
+ }
+ if (negative)
+ return (-(n + p));
+ else
+ return (n + p);
+}
+
+
+
+@ 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.
+
+@c
+static int two_to_the[31]; /* powers of two */
+static int spec_log[29]; /* special logarithms */
+
+@ @c
+void initialize_arithmetic(void)
+{
+ int k;
+ two_to_the[0] = 1;
+ for (k = 1; k <= 30; k++)
+ two_to_the[k] = 2 * two_to_the[k - 1];
+ spec_log[1] = 93032640;
+ spec_log[2] = 38612034;
+ spec_log[3] = 17922280;
+ spec_log[4] = 8662214;
+ spec_log[5] = 4261238;
+ spec_log[6] = 2113709;
+ spec_log[7] = 1052693;
+ spec_log[8] = 525315;
+ spec_log[9] = 262400;
+ spec_log[10] = 131136;
+ spec_log[11] = 65552;
+ spec_log[12] = 32772;
+ spec_log[13] = 16385;
+ for (k = 14; k <= 27; k++)
+ spec_log[k] = two_to_the[27 - k];
+ spec_log[28] = 1;
+}
+
+@ @c
+static int m_log(int x)
+{
+ int y, z; /* auxiliary registers */
+ int k; /* iteration counter */
+ if (x <= 0) {
+ /* Handle non-positive logarithm */
+ print_err("Logarithm of ");
+ print_scaled(x);
+ tprint(" 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.");
+ error();
+ return 0;
+ } else {
+ y = 1302456956 + 4 - 100; /* $14\times2^{27}\ln2\approx1302456956.421063$ */
+ z = 27595 + 6553600; /* and $2^{16}\times .421063\approx 27595$ */
+ while (x < fraction_four) {
+ x += x;
+ y = y - 93032639;
+ z = z - 48782;
+ } /* $2^{27}\ln2\approx 93032639.74436163$
+ and $2^{16}\times.74436163\approx 48782$ */
+ y = y + (z / unity);
+ k = 2;
+ while (x > fraction_four + 4) {
+ /* Increase |k| until |x| can be multiplied by a
+ factor of $2^{-k}$, and adjust $y$ accordingly */
+ z = ((x - 1) / two_to_the[k]) + 1; /* $z=\lceil x/2^k\rceil$ */
+ while (x < fraction_four + z) {
+ z = halfp(z + 1);
+ k = k + 1;
+ }
+ y = y + spec_log[k];
+ x = x - z;
+ }
+ return (y / 8);
+ }
+}
+
+
+
+@ The following somewhat different subroutine tests rigorously if $ab$ is
+greater than, equal to, or less than~$cd$,
+given integers $(a,b,c,d)$. In most cases a quick decision is reached.
+The result is $+1$, 0, or~$-1$ in the three respective cases.
+
+@c
+static int ab_vs_cd(int a, int b, int c, int d)
+{
+ int q, r; /* temporary registers */
+ /* Reduce to the case that |a,c>=0|, |b,d>0| */
+ if (a < 0) {
+ negate(a);
+ negate(b);
+ }
+ if (c < 0) {
+ negate(c);
+ negate(d);
+ }
+ if (d <= 0) {
+ if (b >= 0)
+ return (((a == 0 || b == 0) && (c == 0 || d == 0)) ? 0 : 1);
+ if (d == 0)
+ return (a == 0 ? 0 : -1);
+ q = a;
+ a = c;
+ c = q;
+ q = -b;
+ b = -d;
+ d = q;
+ } else if (b <= 0) {
+ if (b < 0 && a > 0)
+ return -1;
+ return (c == 0 ? 0 : -1);
+ }
+
+ while (1) {
+ q = a / d;
+ r = c / b;
+ if (q != r)
+ return (q > r ? 1 : -1);
+ q = a % d;
+ r = c % b;
+ if (r == 0)
+ return (q == 0 ? 0 : 1);
+ if (q == 0)
+ return -1;
+ a = b;
+ b = q;
+ c = d;
+ d = r; /* now |a>d>0| and |c>b>0| */
+ }
+}
+
+
+
+@ To consume a random integer, the program below will say `|next_random|'
+and then it will fetch |randoms[j_random]|.
+
+@c
+#define next_random() do { \
+ if (j_random==0) new_randoms(); else decr(j_random); \
+ } while (0)
+
+static void new_randoms(void)
+{
+ int k; /* index into |randoms| */
+ int x; /* accumulator */
+ for (k = 0; k <= 23; k++) {
+ x = randoms[k] - randoms[k + 31];
+ if (x < 0)
+ x = x + fraction_one;
+ randoms[k] = x;
+ }
+ for (k = 24; k <= 54; k++) {
+ x = randoms[k] - randoms[k - 24];
+ if (x < 0)
+ x = x + fraction_one;
+ randoms[k] = x;
+ }
+ j_random = 54;
+}
+
+
+@ To initialize the |randoms| table, we call the following routine.
+
+@c
+void init_randoms(int seed)
+{
+ int j, jj, k; /* more or less random integers */
+ int i; /* index into |randoms| */
+ j = abs(seed);
+ while (j >= fraction_one)
+ j = halfp(j);
+ k = 1;
+ for (i = 0; i <= 54; i++) {
+ jj = k;
+ k = j - k;
+ j = jj;
+ if (k < 0)
+ k = k + fraction_one;
+ randoms[(i * 21) % 55] = j;
+ }
+ new_randoms();
+ new_randoms();
+ new_randoms(); /* ``warm up'' the array */
+}
+
+
+@ To produce a uniform random number in the range |0<=u<x| or |0>=u>x|
+or |0=u=x|, given a |scaled| value~|x|, we proceed as shown here.
+
+Note that the call of |take_frac| will produce the values 0 and~|x|
+with about half the probability that it will produce any other particular
+values between 0 and~|x|, because it rounds its answers.
+
+@c
+int unif_rand(int x)
+{
+ int y; /* trial value */
+ next_random();
+ y = take_frac(abs(x), randoms[j_random]);
+ if (y == abs(x))
+ return 0;
+ else if (x > 0)
+ return y;
+ else
+ return -y;
+}
+
+
+@ Finally, a normal deviate with mean zero and unit standard deviation
+can readily be obtained with the ratio method (Algorithm 3.4.1R in
+{\sl The Art of Computer Programming\/}).
+
+@c
+int norm_rand(void)
+{
+ int x, u, l; /* what the book would call $2^{16}X$, $2^{28}U$, and $-2^{24}\ln U$ */
+ do {
+ do {
+ next_random();
+ x = take_frac(112429, randoms[j_random] - fraction_half);
+ /* $2^{16}\sqrt{8/e}\approx 112428.82793$ */
+ next_random();
+ u = randoms[j_random];
+ } while (abs(x) >= u);
+ x = make_frac(x, u);
+ l = 139548960 - m_log(u); /* $2^{24}\cdot12\ln2\approx139548959.6165$ */
+ } while (ab_vs_cd(1024, l, x, x) < 0);
+ return x;
+}
+
+@ This function could also be expressed as a macro, but it is a useful
+ breakpoint for debugging.
+
+@c
+int fix_int(int val, int min, int max)
+{
+ return (val < min ? min : (val > max ? max : val));
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/buildpage.h b/Build/source/texk/web2c/luatexdir/tex/buildpage.h
new file mode 100644
index 00000000000..f3e8f46abbc
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/buildpage.h
@@ -0,0 +1,75 @@
+/* buildpage.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: buildpage.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef BUILDPAGE_H
+# define BUILDPAGE_H
+
+/* empty = 0 */
+# define inserts_only 1 /* |page_contents| when an insert node has been contributed, but no boxes */
+# define box_there 2 /* |page_contents| when a box or rule has been contributed */
+
+extern halfword page_tail; /* the final node on the current page */
+extern int page_contents; /* what is on the current page so far? */
+extern scaled page_max_depth; /* maximum box depth on page being built */
+extern halfword best_page_break; /* break here to get the best page known so far */
+extern int least_page_cost; /* the score for this currently best page */
+extern scaled best_size; /* its |page_goal| */
+
+/*
+The data structure definitions here use the fact that the |@!height| field
+appears in the fourth word of a box node.
+@^data structure assumptions@>
+*/
+
+# define broken_ptr(A) vlink((A)+2) /* an insertion for this class will break here if anywhere */
+# define broken_ins(A) vinfo((A)+2) /* this insertion might break at |broken_ptr| */
+# define last_ins_ptr(A) vlink((A)+3) /* the most recent insertion for this |subtype| */
+# define best_ins_ptr(A) vinfo((A)+3) /* the optimum most recent insertion */
+
+extern void initialize_buildpage(void);
+
+# define page_goal page_so_far[0] /* desired height of information on page being built */
+# define page_total page_so_far[1] /* height of the current page */
+# define page_shrink page_so_far[6] /* shrinkability of the current page */
+# define page_depth page_so_far[7] /* depth of the current page */
+
+extern scaled page_so_far[8]; /* height and glue of the current page */
+extern halfword last_glue; /* used to implement \.{\\lastskip */
+extern int last_penalty; /* used to implement \.{\\lastpenalty} */
+extern scaled last_kern; /* used to implement \.{\\lastkern} */
+extern int last_node_type; /* used to implement \.{\\lastnodetype} */
+extern int insert_penalties; /* sum of the penalties for held-over insertions */
+
+extern void print_totals(void);
+extern void freeze_page_specs(int s);
+
+extern boolean output_active;
+
+extern void start_new_page(void);
+
+# define contrib_tail nest[0].tail_field
+ /* tail of the contribution list */
+
+extern void build_page(void); /* append contributions to the current page */
+extern void fire_up(halfword c);
+extern void resume_after_output(void);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/buildpage.w b/Build/source/texk/web2c/luatexdir/tex/buildpage.w
new file mode 100644
index 00000000000..de39703c8ae
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/buildpage.w
@@ -0,0 +1,1057 @@
+% buildpage.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: buildpage.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/buildpage.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define box(A) eqtb[box_base+(A)].hh.rh
+#define count(A) eqtb[count_base+(A)].hh.rh
+#undef skip
+#define skip(A) eqtb[skip_base+(A)].hh.rh
+#define dimen(A) eqtb[scaled_base+(A)].hh.rh
+
+#define vbadness int_par(vbadness_code)
+#define max_dead_cycles int_par(max_dead_cycles_code)
+#define output_box int_par(output_box_code)
+#define body_direction int_par(body_direction_code)
+#define holding_inserts int_par(holding_inserts_code)
+
+#define vsize dimen_par(vsize_code)
+#define vfuzz dimen_par(vfuzz_code)
+#define max_depth dimen_par(max_depth_code)
+#define pdf_ignored_dimen dimen_par(pdf_ignored_dimen_code)
+
+#define output_routine equiv(output_routine_loc)
+#define split_top_skip glue_par(split_top_skip_code)
+
+#define prev_depth cur_list.prev_depth_field
+#define mode_line cur_list.ml_field
+#define mode cur_list.mode_field
+#define tail cur_list.tail_field
+#define head cur_list.head_field
+
+@ When \TeX\ appends new material to its main vlist in vertical mode, it uses
+a method something like |vsplit| to decide where a page ends, except that
+the calculations are done ``on line'' as new items come in.
+The main complication in this process is that insertions must be put
+into their boxes and removed from the vlist, in a more-or-less optimum manner.
+
+We shall use the term ``current page'' for that part of the main vlist that
+is being considered as a candidate for being broken off and sent to the
+user's output routine. The current page starts at |vlink(page_head)|, and
+it ends at |page_tail|. We have |page_head=page_tail| if this list is empty.
+@^current page@>
+
+Utter chaos would reign if the user kept changing page specifications
+while a page is being constructed, so the page builder keeps the pertinent
+specifications frozen as soon as the page receives its first box or
+insertion. The global variable |page_contents| is |empty| when the
+current page contains only mark nodes and content-less whatsit nodes; it
+is |inserts_only| if the page contains only insertion nodes in addition to
+marks and whatsits. Glue nodes, kern nodes, and penalty nodes are
+discarded until a box or rule node appears, at which time |page_contents|
+changes to |box_there|. As soon as |page_contents| becomes non-|empty|,
+the current |vsize| and |max_depth| are squirreled away into |page_goal|
+and |page_max_depth|; the latter values will be used until the page has
+been forwarded to the user's output routine. The \.{\\topskip} adjustment
+is made when |page_contents| changes to |box_there|.
+
+Although |page_goal| starts out equal to |vsize|, it is decreased by the
+scaled natural height-plus-depth of the insertions considered so far, and by
+the \.{\\skip} corrections for those insertions. Therefore it represents
+the size into which the non-inserted material should fit, assuming that
+all insertions in the current page have been made.
+
+The global variables |best_page_break| and |least_page_cost| correspond
+respectively to the local variables |best_place| and |least_cost| in the
+|vert_break| routine that we have already studied; i.e., they record the
+location and value of the best place currently known for breaking the
+current page. The value of |page_goal| at the time of the best break is
+stored in |best_size|.
+
+@c
+halfword page_tail; /* the final node on the current page */
+int page_contents; /* what is on the current page so far? */
+scaled page_max_depth; /* maximum box depth on page being built */
+halfword best_page_break; /* break here to get the best page known so far */
+int least_page_cost; /* the score for this currently best page */
+scaled best_size; /* its |page_goal| */
+
+
+@ The page builder has another data structure to keep track of insertions.
+This is a list of four-word nodes, starting and ending at |page_ins_head|.
+That is, the first element of the list is node |r@t$_1$@>=vlink(page_ins_head)|;
+node $r_j$ is followed by |r@t$_{j+1}$@>=vlink(r@t$_j$@>)|; and if there are
+|n| items we have |r@t$_{n+1}$@>=page_ins_head|. The |subtype| field of
+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)=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.
+
+The |type| field in these nodes distinguishes two possibilities that
+might occur as we look ahead before deciding on the optimum page break.
+If |type(r)=inserting_node|, then |height(r)| contains the total of the
+height-plus-depth dimensions of the box and all its inserts seen so far.
+ |type(r)=split_up_node|, then no more insertions will be made into this box,
+because at least one previous insertion was too big to fit on the current
+page; |broken_ptr(r)| points to the node where that insertion will be
+split, if \TeX\ decides to split it, |broken_ins(r)| points to the
+insertion node that was tentatively split, and |height(r)| includes also the
+natural height plus depth of the part that would be split off.
+
+In both cases, |last_ins_ptr(r)| points to the last |ins_node|
+encountered for box |qo(subtype(r))| that would be at least partially
+inserted on the next page; and |best_ins_ptr(r)| points to the last
+such |ins_node| that should actually be inserted, to get the page with
+minimum badness among all page breaks considered so far. We have
+|best_ins_ptr(r)=null| if and only if no insertion for this box should
+be made to produce this optimum page.
+
+
+
+@ Pages are built by appending nodes to the current list in \TeX's
+vertical mode, which is at the outermost level of the semantic nest. This
+vlist is split into two parts; the ``current page'' that we have been
+talking so much about already, and the ``contribution list'' that receives
+new nodes as they are created. The current page contains everything that
+the page builder has accounted for in its data structures, as described
+above, while the contribution list contains other things that have been
+generated by other parts of \TeX\ but have not yet been
+seen by the page builder.
+The contribution list starts at |vlink(contrib_head)|, and it ends at the
+current node in \TeX's vertical mode.
+
+When \TeX\ has appended new material in vertical mode, it calls the procedure
+|build_page|, which tries to catch up by moving nodes from the contribution
+list to the current page. This procedure will succeed in its goal of
+emptying the contribution list, unless a page break is discovered, i.e.,
+unless the current page has grown to the point where the optimum next
+page break has been determined. In the latter case, the nodes after the
+optimum break will go back onto the contribution list, and control will
+effectively pass to the user's output routine.
+
+We make |type(page_head)=glue_node|, so that an initial glue node on
+the current page will not be considered a valid breakpoint.
+
+@c
+void initialize_buildpage(void)
+{
+ subtype(page_ins_head) = 65535;
+ type(page_ins_head) = split_up_node;
+ vlink(page_ins_head) = page_ins_head;
+
+ type(page_head) = glue_node;
+ subtype(page_head) = normal;
+}
+
+
+@ An array |page_so_far| records the heights and depths of everything
+on the current page. This array contains six |scaled| numbers, like the
+similar arrays already considered in |line_break| and |vert_break|; and it
+also contains |page_goal| and |page_depth|, since these values are
+all accessible to the user via |set_page_dimen| commands. The
+value of |page_so_far[1]| is also called |page_total|. The stretch
+and shrink components of the \.{\\skip} corrections for each insertion are
+included in |page_so_far|, but the natural space components of these
+corrections are not, since they have been subtracted from |page_goal|.
+
+The variable |page_depth| records the depth of the current page; it has been
+adjusted so that it is at most |page_max_depth|. The variable
+|last_glue| points to the glue specification of the most recent node
+contributed from the contribution list, if this was a glue node; otherwise
+|last_glue=max_halfword|. (If the contribution list is nonempty,
+however, the value of |last_glue| is not necessarily accurate.)
+The variables |last_penalty|, |last_kern|, and |last_node_type|
+are similar. And
+finally, |insert_penalties| holds the sum of the penalties associated with
+all split and floating insertions.
+
+@c
+scaled page_so_far[8]; /* height and glue of the current page */
+halfword last_glue; /* used to implement \.{\\lastskip} */
+int last_penalty; /* used to implement \.{\\lastpenalty} */
+scaled last_kern; /* used to implement \.{\\lastkern} */
+int last_node_type; /* used to implement \.{\\lastnodetype} */
+int insert_penalties; /* sum of the penalties for held-over insertions */
+
+#define print_plus(A,B) do { \
+ if (page_so_far[(A)]!=0) { \
+ tprint(" plus "); \
+ print_scaled(page_so_far[(A)]); \
+ tprint((B)); \
+ } \
+ } while (0)
+
+void print_totals(void)
+{
+ print_scaled(page_total);
+ print_plus(2, "");
+ print_plus(3, "fil");
+ print_plus(4, "fill");
+ print_plus(5, "filll");
+ if (page_shrink != 0) {
+ tprint(" minus ");
+ print_scaled(page_shrink);
+ }
+}
+
+
+@ Here is a procedure that is called when the |page_contents| is changing
+from |empty| to |inserts_only| or |box_there|.
+
+@c
+#define do_all_six(A) A(1);A(2);A(3);A(4);A(5);A(6);A(7)
+#define set_page_so_far_zero(A) page_so_far[(A)]=0
+
+void freeze_page_specs(int s)
+{
+ page_contents = s;
+ page_goal = vsize;
+ page_max_depth = max_depth;
+ page_depth = 0;
+ do_all_six(set_page_so_far_zero);
+ least_page_cost = awful_bad;
+ if (int_par(tracing_pages_code) > 0) {
+ begin_diagnostic();
+ tprint_nl("%% goal height=");
+ print_scaled(page_goal);
+ tprint(", max depth=");
+ print_scaled(page_max_depth);
+ end_diagnostic(false);
+ }
+}
+
+
+@ The global variable |output_active| is true during the time the
+user's output routine is driving \TeX.
+
+@c
+boolean output_active; /* are we in the midst of an output routine? */
+
+
+@ The page builder is ready to start a fresh page if we initialize
+the following state variables. (However, the page insertion list is initialized
+elsewhere.)
+
+@c
+void start_new_page(void)
+{
+ page_contents = empty;
+ page_tail = page_head;
+ vlink(page_head) = null;
+ 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 \.{\\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.
+
+@c
+static void box_error(int n)
+{
+ error();
+ begin_diagnostic();
+ tprint_nl("The following box has been deleted:");
+ show_box(box(n));
+ end_diagnostic(true);
+ flush_node_list(box(n));
+ box(n) = null;
+}
+
+
+@ The following procedure guarantees that a given box register
+does not contain an \.{\\hbox}.
+
+@c
+static void ensure_vbox(int n)
+{
+ halfword p; /* the box register contents */
+ p = box(n);
+ if (p != null && type(p) == hlist_node) {
+ print_err("Insertions can only be added to a vbox");
+ help3("Tut tut: You're trying to \\insert into a",
+ "\\box register that now contains an \\hbox.",
+ "Proceed, and I'll discard its present contents.");
+ box_error(n);
+ }
+}
+
+
+@ \TeX\ is not always in vertical mode at the time |build_page|
+is called; the current mode reflects what \TeX\ should return to, after
+the contribution list has been emptied. A call on |build_page| should
+be immediately followed by `|goto big_switch|', which is \TeX's central
+control point.
+
+@c
+void build_page(void)
+{ /* append contributions to the current page */
+ halfword p; /* the node being appended */
+ halfword q, r; /* nodes being examined */
+ int b, c; /* badness and cost of current page */
+ int pi; /* penalty to be added to the badness */
+ int n; /* insertion box number */
+ scaled delta, h, w; /* sizes used for insertion calculations */
+ pi = 0;
+ if ((vlink(contrib_head) == null) || output_active)
+ return;
+ do {
+ CONTINUE:
+ p = vlink(contrib_head);
+ /* Update the values of |last_glue|, |last_penalty|, and |last_kern| */
+ if (last_glue != max_halfword) {
+ delete_glue_ref(last_glue);
+ last_glue = max_halfword;
+ }
+ last_penalty = 0;
+ last_kern = 0;
+ last_node_type = type(p) + 1;
+ if (type(p) == glue_node) {
+ last_glue = glue_ptr(p);
+ add_glue_ref(last_glue);
+ } else if (type(p) == penalty_node) {
+ last_penalty = penalty(p);
+ } else if (type(p) == kern_node) {
+ last_kern = width(p);
+ }
+
+ /* Move node |p| to the current page; if it is time for a page break,
+ put the nodes following the break back onto the contribution list,
+ and |return| to the users output routine if there is one */
+
+ /* The code here is an example of a many-way switch into routines that
+ merge together in different places. Some people call this unstructured
+ programming, but the author doesn't see much wrong with it, as long as
+ the various labels have a well-understood meaning.
+ */
+ /* If the current page is empty and node |p| is to be deleted, |goto done1|;
+ otherwise use node |p| to update the state of the current page;
+ if this node is an insertion, |goto contribute|; otherwise if this node
+ is not a legal breakpoint, |goto contribute| or |update_heights|;
+ otherwise set |pi| to the penalty associated with this breakpoint */
+ /* The title of this section is already so long, it seems best to avoid
+ making it more accurate but still longer, by mentioning the fact that a
+ kern node at the end of the contribution list will not be contributed until
+ we know its successor. */
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ case rule_node:
+ if (page_contents < box_there) {
+ /* Initialize the current page, insert the \.{\\topskip} glue
+ ahead of |p|, and |goto continue| */
+ if (page_contents == empty)
+ 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) && is_mirrored(body_direction)) {
+ if (width(temp_ptr) > depth(p))
+ width(temp_ptr) = width(temp_ptr) - depth(p);
+ else
+ width(temp_ptr) = 0;
+ } else {
+ if (width(temp_ptr) > height(p))
+ width(temp_ptr) = width(temp_ptr) - height(p);
+ else
+ width(temp_ptr) = 0;
+ }
+ vlink(q) = p;
+ vlink(contrib_head) = q;
+ goto CONTINUE;
+
+ } else {
+ /* Prepare to move a box or rule node to the current page,
+ then |goto contribute| */
+ if ((type(p) == hlist_node) && is_mirrored(body_direction)) {
+ page_total = page_total + page_depth + depth(p);
+ page_depth = height(p);
+ } else {
+ page_total = page_total + page_depth + height(p);
+ page_depth = depth(p);
+ }
+ goto CONTRIBUTE;
+
+ }
+ break;
+ case whatsit_node:
+ /* Prepare to move whatsit |p| to the current page,
+ then |goto contribute| */
+ if ((subtype(p) == pdf_refxform_node)
+ || (subtype(p) == pdf_refximage_node)) {
+ page_total = page_total + page_depth + height(p);
+ page_depth = depth(p);
+ }
+ goto CONTRIBUTE;
+
+ break;
+ case glue_node:
+ if (page_contents < box_there)
+ goto DONE1;
+ else if (precedes_break(page_tail))
+ pi = 0;
+ else
+ goto UPDATE_HEIGHTS;
+ break;
+ case kern_node:
+ if (page_contents < box_there)
+ goto DONE1;
+ else if (vlink(p) == null)
+ goto EXIT;
+ else if (type(vlink(p)) == glue_node)
+ pi = 0;
+ else
+ goto UPDATE_HEIGHTS;
+ break;
+ case penalty_node:
+ if (page_contents < box_there)
+ goto DONE1;
+ else
+ pi = penalty(p);
+ break;
+ case mark_node:
+ goto CONTRIBUTE;
+ break;
+ case ins_node:
+ /* Append an insertion to the current page and |goto contribute| */
+ if (page_contents == empty)
+ freeze_page_specs(inserts_only);
+ n = subtype(p);
+ r = page_ins_head;
+ while (n >= subtype(vlink(r)))
+ r = vlink(r);
+ if (subtype(r) != n) {
+ /* Create a page insertion node with |subtype(r)=qi(n)|, and
+ include the glue correction for box |n| in the
+ current page state */
+ /* We take note of the value of \.{\\skip} |n| and the height plus depth
+ of \.{\\box}~|n| only when the first \.{\\insert}~|n| node is
+ encountered for a new page. A user who changes the contents of \.{\\box}~|n|
+ after that first \.{\\insert}~|n| had better be either extremely careful
+ or extremely lucky, or both. */
+
+ q = new_node(inserting_node, n);
+ vlink(q) = vlink(r);
+ vlink(r) = q;
+ r = q;
+ ensure_vbox(n);
+ if (box(n) == null)
+ height(r) = 0;
+ else
+ height(r) = height(box(n)) + depth(box(n));
+ best_ins_ptr(r) = null;
+ q = skip(n);
+ if (count(n) == 1000)
+ h = height(r);
+ else
+ h = x_over_n(height(r), 1000) * count(n);
+ page_goal = page_goal - h - width(q);
+ if (stretch_order(q) > 1)
+ page_so_far[1 + stretch_order(q)] =
+ page_so_far[1 + stretch_order(q)] + stretch(q);
+ else
+ page_so_far[2 + stretch_order(q)] =
+ page_so_far[2 + stretch_order(q)] + stretch(q);
+ page_shrink = page_shrink + shrink(q);
+ if ((shrink_order(q) != normal) && (shrink(q) != 0)) {
+ print_err("Infinite glue shrinkage inserted from \\skip");
+ print_int(n);
+ help3
+ ("The correction glue for page breaking with insertions",
+ "must have finite shrinkability. But you may proceed,",
+ "since the offensive shrinkability has been made finite.");
+ error();
+ }
+
+ }
+ if (type(r) == split_up_node) {
+ insert_penalties = insert_penalties + float_cost(p);
+ } else {
+ last_ins_ptr(r) = p;
+ delta = page_goal - page_total - page_depth + page_shrink;
+ /* this much room is left if we shrink the maximum */
+ if (count(n) == 1000)
+ h = height(p);
+ else
+ h = x_over_n(height(p), 1000) * count(n); /* this much room is needed */
+ if (((h <= 0) || (h <= delta))
+ && (height(p) + height(r) <= dimen(n))) {
+ page_goal = page_goal - h;
+ height(r) = height(r) + height(p);
+ } else {
+ /* Find the best way to split the insertion, and change
+ |type(r)| to |split_up_node| */
+ /* Here is the code that will split a long footnote between pages, in an
+ emergency. The current situation deserves to be recapitulated: Node |p|
+ is an insertion into box |n|; the insertion will not fit, in its entirety,
+ either because it would make the total contents of box |n| greater than
+ \.{\\dimen} |n|, or because it would make the incremental amount of growth
+ |h| greater than the available space |delta|, or both. (This amount |h| has
+ been weighted by the insertion scaling factor, i.e., by \.{\\count} |n|
+ over 1000.) Now we will choose the best way to break the vlist of the
+ insertion, using the same criteria as in the \.{\\vsplit} operation.
+ */
+ if (count(n) <= 0) {
+ w = max_dimen;
+ } else {
+ w = page_goal - page_total - page_depth;
+ if (count(n) != 1000)
+ w = x_over_n(w, count(n)) * 1000;
+ }
+ if (w > dimen(n) - height(r))
+ w = dimen(n) - height(r);
+ q = vert_break(ins_ptr(p), w, depth(p));
+ height(r) = height(r) + best_height_plus_depth;
+ if (int_par(tracing_pages_code) > 0) {
+ /* Display the insertion split cost */
+ begin_diagnostic();
+ tprint_nl("% split");
+ print_int(n);
+ tprint(" to ");
+ print_scaled(w);
+ print_char(',');
+ print_scaled(best_height_plus_depth);
+ tprint(" p=");
+ if (q == null)
+ print_int(eject_penalty);
+ else if (type(q) == penalty_node)
+ print_int(penalty(q));
+ else
+ print_char('0');
+ end_diagnostic(false);
+
+ }
+ if (count(n) != 1000)
+ best_height_plus_depth =
+ x_over_n(best_height_plus_depth, 1000) * count(n);
+ page_goal = page_goal - best_height_plus_depth;
+ type(r) = split_up_node;
+ broken_ptr(r) = q;
+ broken_ins(r) = p;
+ if (q == null)
+ insert_penalties = insert_penalties + eject_penalty;
+ else if (type(q) == penalty_node)
+ insert_penalties = insert_penalties + penalty(q);
+ }
+ }
+ goto CONTRIBUTE;
+
+ break;
+ default:
+ confusion("page");
+ break;
+ }
+
+ /* Check if node |p| is a new champion breakpoint; then if it is time for
+ a page break, prepare for output, and either fire up the users
+ output routine and |return| or ship out the page and |goto done| */
+
+ if (pi < inf_penalty) {
+ /* Compute the badness, |b|, of the current page,
+ using |awful_bad| if the box is too full */
+ if (page_total < page_goal) {
+ if ((page_so_far[3] != 0) || (page_so_far[4] != 0) ||
+ (page_so_far[5] != 0))
+ b = 0;
+ else
+ b = badness(page_goal - page_total, page_so_far[2]);
+ } else if (page_total - page_goal > page_shrink) {
+ b = awful_bad;
+ } else {
+ b = badness(page_total - page_goal, page_shrink);
+ }
+
+ if (b < awful_bad) {
+ if (pi <= eject_penalty)
+ c = pi;
+ else if (b < inf_bad)
+ c = b + pi + insert_penalties;
+ else
+ c = deplorable;
+ } else {
+ c = b;
+ }
+ if (insert_penalties >= 10000)
+ c = awful_bad;
+ if (int_par(tracing_pages_code) > 0) {
+ /* Display the page break cost */
+ begin_diagnostic();
+ tprint_nl("%");
+ tprint(" t=");
+ print_totals();
+ tprint(" g=");
+ print_scaled(page_goal);
+ tprint(" b=");
+ if (b == awful_bad)
+ print_char('*');
+ else
+ print_int(b);
+ tprint(" p=");
+ print_int(pi);
+ tprint(" c=");
+ if (c == awful_bad)
+ print_char('*');
+ else
+ print_int(c);
+ if (c <= least_page_cost)
+ print_char('#');
+ end_diagnostic(false);
+
+ }
+ if (c <= least_page_cost) {
+ best_page_break = p;
+ best_size = page_goal;
+ least_page_cost = c;
+ r = vlink(page_ins_head);
+ while (r != page_ins_head) {
+ best_ins_ptr(r) = last_ins_ptr(r);
+ r = vlink(r);
+ }
+ }
+ if ((c == awful_bad) || (pi <= eject_penalty)) {
+ fire_up(p); /* output the current page at the best place */
+ if (output_active)
+ goto EXIT; /* user's output routine will act */
+ goto DONE; /* the page has been shipped out by default output routine */
+ }
+ }
+
+ if ((type(p) < glue_node) || (type(p) > kern_node))
+ goto CONTRIBUTE;
+
+ UPDATE_HEIGHTS: /* go here to record glue in the |active_height| table */
+
+ /* Update the current page measurements with respect to the
+ glue or kern specified by node~|p| */
+ if (type(p) == kern_node) {
+ q = p;
+ } else {
+ q = glue_ptr(p);
+ if (stretch_order(q) > 1)
+ page_so_far[1 + stretch_order(q)] =
+ page_so_far[1 + stretch_order(q)] + stretch(q);
+ else
+ page_so_far[2 + stretch_order(q)] =
+ page_so_far[2 + stretch_order(q)] + stretch(q);
+ page_shrink = page_shrink + shrink(q);
+ if ((shrink_order(q) != normal) && (shrink(q) != 0)) {
+ print_err("Infinite glue shrinkage found on current page");
+ help4("The page about to be output contains some infinitely",
+ "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
+ "Such glue doesn't belong there; but you can safely proceed,",
+ "since the offensive shrinkability has been made finite.");
+ error();
+ r = new_spec(q);
+ shrink_order(r) = normal;
+ delete_glue_ref(q);
+ glue_ptr(p) = r;
+ q = r;
+ }
+ }
+ page_total = page_total + page_depth + width(q);
+ page_depth = 0;
+
+ CONTRIBUTE: /* go here to link a node into the current page */
+
+ /* Make sure that |page_max_depth| is not exceeded */
+ if (page_depth > page_max_depth) {
+ page_total = page_total + page_depth - page_max_depth;
+ page_depth = page_max_depth;
+ }
+
+ /* Link node |p| into the current page and |goto done| */
+ vlink(page_tail) = p;
+ page_tail = p;
+ vlink(contrib_head) = vlink(p);
+ vlink(p) = null;
+ goto DONE;
+ DONE1:
+ /* Recycle node |p| */
+ vlink(contrib_head) = vlink(p);
+ vlink(p) = null;
+ if (int_par(saving_vdiscards_code) > 0) {
+ if (page_disc == null)
+ page_disc = p;
+ else
+ vlink(tail_page_disc) = p;
+ tail_page_disc = p;
+ } else {
+ flush_node_list(p);
+ }
+ DONE:
+ ;
+ } while (vlink(contrib_head) != null);
+ /* Make the contribution list empty by setting its tail to |contrib_head| */
+ contrib_tail = contrib_head;
+ EXIT:
+ ;
+}
+
+@ 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 \.{\\outputbox}, with insertions
+appended to their other boxes.
+
+We also set the values of |top_mark|, |first_mark|, and |bot_mark|. The
+program uses the fact that |bot_mark(x)<>null| implies |first_mark(x)<>null|;
+it also knows that |bot_mark(x)=null| implies |top_mark(x)=first_mark(x)=null|.
+
+The |fire_up| subroutine prepares to output the current page at the best
+place; then it fires up the user's output routine, if there is one,
+or it simply ships out the page. There is one parameter, |c|, which represents
+the node that was being contributed to the page when the decision to
+force an output was made.
+
+@c
+void fire_up(halfword c)
+{
+ halfword p, q, r, s; /* nodes being examined and/or changed */
+ halfword prev_p; /* predecessor of |p| */
+ int n; /* insertion box number */
+ boolean wait; /* should the present insertion be held over? */
+ int save_vbadness; /* saved value of |vbadness| */
+ scaled save_vfuzz; /* saved value of |vfuzz| */
+ halfword save_split_top_skip; /* saved value of |split_top_skip| */
+ halfword i; /* for looping through the marks */
+
+ /* Set the value of |output_penalty| */
+ if (type(best_page_break) == penalty_node) {
+ geq_word_define(int_base + output_penalty_code,
+ penalty(best_page_break));
+ penalty(best_page_break) = inf_penalty;
+ } else {
+ geq_word_define(int_base + output_penalty_code, inf_penalty);
+ }
+
+ for (i = 0; i <= biggest_used_mark; i++) {
+ if (bot_mark(i) != null) {
+ if (top_mark(i) != null)
+ delete_token_ref(top_mark(i));
+ set_top_mark(i, bot_mark(i));
+ add_token_ref(top_mark(i));
+ delete_first_mark(i);
+ }
+ }
+ /* Put the optimal current page into box |output_box|, update |first_mark| and
+ |bot_mark|, append insertions to their boxes, and put the
+ remaining nodes back on the contribution list; */
+
+ /* As the page is finally being prepared for output,
+ 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)
+ best_page_break = null; /* |c| not yet linked in */
+ /* Ensure that box |output_box| is empty before output */
+ if (box(output_box) != null) {
+ print_err("\\box");
+ print_int(output_box);
+ tprint(" is not void");
+ help2("You shouldn't use \\box\\outputbox except in \\output routines.",
+ "Proceed, and I'll discard its present contents.");
+ box_error(output_box);
+ }
+
+ insert_penalties = 0; /* this will count the number of insertions held over */
+ save_split_top_skip = split_top_skip;
+ if (holding_inserts <= 0) {
+ /* Prepare all the boxes involved in insertions to act as queues */
+ /* If many insertions are supposed to go into the same box, we want to know
+ the position of the last node in that box, so that we don't need to waste time
+ when linking further information into it. The |last_ins_ptr| fields of the
+ page insertion nodes are therefore used for this purpose during the
+ packaging phase. */
+
+ r = vlink(page_ins_head);
+ while (r != page_ins_head) {
+ if (best_ins_ptr(r) != null) {
+ n = subtype(r);
+ ensure_vbox(n);
+ if (box(n) == null)
+ box(n) = new_null_box();
+ p = box(n) + list_offset;
+ while (vlink(p) != null)
+ p = vlink(p);
+ last_ins_ptr(r) = p;
+ }
+ r = vlink(r);
+ }
+
+ }
+ q = hold_head;
+ vlink(q) = null;
+ prev_p = page_head;
+ p = vlink(prev_p);
+ while (p != best_page_break) {
+ if (type(p) == ins_node) {
+ if (holding_inserts <= 0) {
+ /* Either insert the material specified by node |p| into the
+ appropriate box, or hold it for the next page;
+ also delete node |p| from the current page */
+ /* We will set |best_ins_ptr:=null| and package the box corresponding to
+ insertion node~|r|, just after making the final insertion into that box.
+ If this final insertion is `|split_up_node|', the remainder after splitting
+ and pruning (if any) will be carried over to the next page. */
+ r = vlink(page_ins_head);
+ while (subtype(r) != subtype(p))
+ r = vlink(r);
+ if (best_ins_ptr(r) == null) {
+ wait = true;
+ } else {
+ wait = false;
+ s = last_ins_ptr(r);
+ vlink(s) = ins_ptr(p);
+ if (best_ins_ptr(r) == p) {
+ /* Wrap up the box specified by node |r|, splitting node |p| if
+ called for; set |wait:=true| if node |p| holds a remainder after
+ splitting */
+ if (type(r) == split_up_node) {
+ if ((broken_ins(r) == p) && (broken_ptr(r) != null)) {
+ while (vlink(s) != broken_ptr(r))
+ s = vlink(s);
+ vlink(s) = null;
+ split_top_skip = split_top_ptr(p);
+ ins_ptr(p) =
+ prune_page_top(broken_ptr(r), false);
+ if (ins_ptr(p) != null) {
+ temp_ptr =
+ vpack(ins_ptr(p), 0, additional, -1);
+ height(p) =
+ height(temp_ptr) + depth(temp_ptr);
+ list_ptr(temp_ptr) = null;
+ flush_node(temp_ptr);
+ wait = true;
+ }
+ }
+ }
+ best_ins_ptr(r) = null;
+ n = subtype(r);
+ temp_ptr = list_ptr(box(n));
+ list_ptr(box(n)) = null;
+ flush_node(box(n));
+ box(n) = vpack(temp_ptr, 0, additional, body_direction);
+
+ } else {
+ while (vlink(s) != null)
+ s = vlink(s);
+ last_ins_ptr(r) = s;
+ }
+ }
+ /* Either append the insertion node |p| after node |q|, and remove it
+ from the current page, or delete |node(p)| */
+ vlink(prev_p) = vlink(p);
+ vlink(p) = null;
+ if (wait) {
+ vlink(q) = p;
+ q = p;
+ incr(insert_penalties);
+ } else {
+ ins_ptr(p) = null;
+ flush_node(p);
+ }
+ p = prev_p;
+
+ }
+ } else if (type(p) == mark_node) {
+ /* Update the values of |first_mark| and |bot_mark| */
+ if (first_mark(mark_class(p)) == null) {
+ set_first_mark(mark_class(p), mark_ptr(p));
+ add_token_ref(first_mark(mark_class(p)));
+ }
+ if (bot_mark(mark_class(p)) != null)
+ delete_token_ref(bot_mark(mark_class(p)));
+ set_bot_mark(mark_class(p), mark_ptr(p));
+ add_token_ref(bot_mark(mark_class(p)));
+
+ }
+ prev_p = p;
+ p = vlink(prev_p);
+ }
+ split_top_skip = save_split_top_skip;
+ /* Break the current page at node |p|, put it in box~|output_box|,
+ and put the remaining nodes on the contribution list */
+ /* When the following code is executed, the current page runs from node
+ |vlink(page_head)| to node |prev_p|, and the nodes from |p| to |page_tail|
+ are to be placed back at the front of the contribution list. Furthermore
+ the heldover insertions appear in a list from |vlink(hold_head)| to |q|; we
+ will put them into the current page list for safekeeping while the user's
+ output routine is active. We might have |q=hold_head|; and |p=null| if
+ and only if |prev_p=page_tail|. Error messages are suppressed within
+ |vpackage|, since the box might appear to be overfull or underfull simply
+ because the stretch and shrink from the \.{\\skip} registers for inserts
+ are not actually present in the box. */
+
+ if (p != null) {
+ if (vlink(contrib_head) == null) {
+ contrib_tail = page_tail;
+ }
+ vlink(page_tail) = vlink(contrib_head);
+ vlink(contrib_head) = p;
+ vlink(prev_p) = null;
+ }
+ save_vbadness = vbadness;
+ vbadness = inf_bad;
+ save_vfuzz = vfuzz;
+ vfuzz = max_dimen; /* inhibit error messages */
+ box(output_box) =
+ filtered_vpackage(vlink(page_head), best_size, exactly, page_max_depth,
+ output_group, body_direction);
+ vbadness = save_vbadness;
+ vfuzz = save_vfuzz;
+ if (last_glue != max_halfword)
+ delete_glue_ref(last_glue);
+ /* Start a new current page */
+ start_new_page(); /* this sets |last_glue:=max_halfword| */
+ if (q != hold_head) {
+ vlink(page_head) = vlink(hold_head);
+ page_tail = q;
+ }
+
+ /* Delete the page-insertion nodes */
+ r = vlink(page_ins_head);
+ while (r != page_ins_head) {
+ q = vlink(r);
+ flush_node(r);
+ r = q;
+ }
+ vlink(page_ins_head) = page_ins_head;
+
+ for (i = 0; i <= biggest_used_mark; i++) {
+ if ((top_mark(i) != null) && (first_mark(i) == null)) {
+ set_first_mark(i, top_mark(i));
+ add_token_ref(top_mark(i));
+ }
+ }
+ if (output_routine != null) {
+ if (dead_cycles >= max_dead_cycles) {
+ /* Explain that too many dead cycles have occurred in a row */
+ print_err("Output loop---");
+ print_int(dead_cycles);
+ tprint(" consecutive dead cycles");
+ help3("I've concluded that your \\output is awry; it never does a",
+ "\\shipout, so I'm shipping \\box\\outputbox out myself. Next time",
+ "increase \\maxdeadcycles if you want me to be more patient!");
+ error();
+
+ } else {
+ /* Fire up the users output routine and |return| */
+ output_active = true;
+ incr(dead_cycles);
+ 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();
+ return;
+
+ }
+ }
+ /* Perform the default output routine */
+ /* The list of heldover insertions, running from |vlink(page_head)| to
+ |page_tail|, must be moved to the contribution list when the user has
+ specified no output routine. */
+ if (vlink(page_head) != null) {
+ if (vlink(contrib_head) == null) {
+ contrib_tail = page_tail;
+ } else {
+ vlink(page_tail) = vlink(contrib_head);
+ }
+ vlink(contrib_head) = vlink(page_head);
+ vlink(page_head) = null;
+ page_tail = page_head;
+ }
+ flush_node_list(page_disc);
+ page_disc = null;
+ ship_out(static_pdf, box(output_box), true);
+ box(output_box) = null;
+}
+
+
+@ When the user's output routine finishes, it has constructed a vlist
+in internal vertical mode, and \TeX\ will do the following:
+
+@c
+void resume_after_output(void)
+{
+ if ((iloc != null)
+ || ((token_type != output_text) && (token_type != backed_up))) {
+ /* Recover from an unbalanced output routine */
+ print_err("Unbalanced output routine");
+ help2("Your sneaky output routine has problematic {'s and/or }'s.",
+ "I can't handle that very well; good luck.");
+ error();
+ do {
+ get_token();
+ } while (iloc != null);
+ /* loops forever if reading from a file, since |null=min_halfword<=0| */
+
+ }
+ end_token_list(); /* conserve stack space in case more outputs are triggered */
+ end_graf(bottom_level);
+ unsave();
+ output_active = false;
+ insert_penalties = 0;
+ /* Ensure that box |output_box| is empty after output */
+ if (box(output_box) != null) {
+ print_err("Output routine didn't use all of \\box");
+ print_int(output_box);
+ help3("Your \\output commands should empty \\box\\outputbox,",
+ "e.g., by saying `\\shipout\\box\\outputbox'.",
+ "Proceed; I'll discard its present contents.");
+ box_error(output_box);
+ }
+
+ if (tail != head) { /* current list goes after heldover insertions */
+ vlink(page_tail) = vlink(head);
+ page_tail = tail;
+ }
+ if (vlink(page_head) != null) { /* and both go before heldover contributions */
+ if (vlink(contrib_head) == null)
+ contrib_tail = page_tail;
+ vlink(page_tail) = vlink(contrib_head);
+ vlink(contrib_head) = vlink(page_head);
+ vlink(page_head) = null;
+ page_tail = page_head;
+ }
+ flush_node_list(page_disc);
+ page_disc = null;
+ pop_nest();
+ lua_node_filter_s(buildpage_filter_callback, "after_output");
+ build_page();
+
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.h b/Build/source/texk/web2c/luatexdir/tex/commands.h
new file mode 100644
index 00000000000..88d012aaa5c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/commands.h
@@ -0,0 +1,355 @@
+/* commands.h
+
+ Copyright 2008 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: commands.h 2899 2009-07-21 23:03:53Z oneiros $ */
+
+#ifndef COMMANDS_H
+# define COMMANDS_H
+
+/*
+Before we can go any further, we need to define symbolic names for the internal
+code numbers that represent the various commands obeyed by \TeX. These codes
+are somewhat arbitrary, but not completely so. For example, the command
+codes for character types are fixed by the language, since a user says,
+e.g., `\.{\\catcode \`\\\${} = 3}' to make \.{\char'44} a math delimiter,
+and the command code |math_shift| is equal to~3. Some other codes have
+been made adjacent so that |case| statements in the program need not consider
+cases that are widely spaced, or so that |case| statements can be replaced
+by |if| statements.
+
+At any rate, here is the list, for future reference. First come the
+``catcode'' commands, several of which share their numeric codes with
+ordinary commands when the catcode cannot emerge from \TeX's scanning routine.
+
+@ Next are the ordinary run-of-the-mill command codes. Codes that are
+|min_internal| or more represent internal quantities that might be
+expanded by `\.{\\the}'.
+
+
+@ The next codes are special; they all relate to mode-independent
+assignment of values to \TeX's internal registers or tables.
+Codes that are |max_internal| or less represent internal quantities
+that might be expanded by `\.{\\the}'.
+
+There is no matching primitive to go with |assign_attr|, but even if
+there was no \.{\\attributedef}, a reserved number would still be
+needed because there is an implied correspondence between the
+|assign_xxx| commands and |xxx_val| expression values. That would
+break down otherwise.
+
+@ The remaining command codes are extra special, since they cannot get through
+\TeX's scanner to the main control routine. They have been given values higher
+than |max_command| so that their special nature is easily discernible.
+The ``expandable'' commands come first.
+
+
+*/
+
+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 \<v_j> 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} ) */
+ super_sub_script_cmd, /* explicit super- or subscript */
+ math_shift_cs_cmd, /* start- and endmath */
+ 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 */
+ 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 */
+} tex_command_code;
+
+# define max_command_cmd ocp_trace_level_cmd /* the largest command code seen at |big_switch| */
+# define last_cmd data_cmd
+# define max_non_prefixed_command last_item_cmd
+
+typedef enum {
+ above_code = 0,
+ over_code = 1,
+ atop_code = 2,
+ delimited_code = 3
+} fraction_codes;
+
+typedef enum {
+ number_code = 0, /* command code for \.{\\number} */
+ roman_numeral_code, /* command code for \.{\\romannumeral} */
+ string_code, /* command code for \.{\\string} */
+ meaning_code, /* command code for \.{\\meaning} */
+ font_name_code, /* command code for \.{\\fontname} */
+ etex_code, /* command code for \.{\\eTeXVersion} */
+ omega_code, /* command code for \.{\\OmegaVersion} */
+ aleph_code, /* command code for \.{\\AlephVersion} */
+ format_name_code, /* command code for \.{\\AlephVersion} */
+ pdftex_revision_code, /* command code for \.{\\pdftexrevision} */
+# define pdftex_first_expand_code pdftex_revision_code /* base for \pdfTeX's command codes */
+ pdftex_banner_code, /* command code for \.{\\pdftexbanner} */
+ pdf_font_name_code, /* command code for \.{\\pdffontname} */
+ pdf_font_objnum_code, /* command code for \.{\\pdffontobjnum} */
+ pdf_font_size_code, /* command code for \.{\\pdffontsize} */
+ pdf_page_ref_code, /* command code for \.{\\pdfpageref} */
+ pdf_xform_name_code, /* command code for \.{\\pdfxformname} */
+ left_margin_kern_code, /* command code for \.{\\leftmarginkern} */
+ right_margin_kern_code, /* command code for \.{\\rightmarginkern} */
+ pdf_creation_date_code, /* command code for \.{\\pdfcreationdate} */
+ uniform_deviate_code, /* command code for \.{\\uniformdeviate} */
+ normal_deviate_code, /* command code for \.{\\normaldeviate} */
+ pdf_insert_ht_code, /* command code for \.{\\pdfinsertht} */
+ pdf_ximage_bbox_code, /* command code for \.{\\pdfximagebbox} */
+ lua_code, /* command code for \.{\\directlua} */
+ lua_escape_string_code, /* command code for \.{\\luaescapestring} */
+ pdf_colorstack_init_code, /* command code for \.{\\pdfcolorstackinit} */
+ luatex_revision_code, /* command code for \.{\\luatexrevision} */
+ luatex_date_code, /* command code for \.{\\luatexdate} */
+ math_style_code, /* command code for \.{\\mathstyle} */
+ expanded_code, /* command code for \.{\\expanded} */
+ job_name_code, /* command code for \.{\\jobname} */
+ Aleph_revision_code, /* command code for \.{\\Alephrevision} */
+ Omega_revision_code, /* command code for \.{\\Omegarevision} */
+ eTeX_revision_code, /* command code for \.{\\eTeXrevision} */
+ font_identifier_code, /* command code for \.{tex.fontidentifier} (virtual) */
+} convert_codes;
+
+typedef enum {
+ lastpenalty_code = 0, /* code for \.{\\lastpenalty} */
+ lastattr_code, /* not used */
+ lastkern_code, /* code for \.{\\lastkern} */
+ lastskip_code, /* code for \.{\\lastskip} */
+ last_node_type_code, /* code for \.{\\lastnodetype} */
+ input_line_no_code, /* code for \.{\\inputlineno} */
+ badness_code, /* code for \.{\\badness} */
+ pdftex_version_code, /* code for \.{\\pdftexversion} */
+# define pdftex_first_rint_code pdftex_version_code /* base for \pdfTeX's command codes */
+ pdf_last_obj_code, /* code for \.{\\pdflastobj} */
+ pdf_last_xform_code, /* code for \.{\\pdflastxform} */
+ pdf_last_ximage_code, /* code for \.{\\pdflastximage} */
+ pdf_last_ximage_pages_code, /* code for \.{\\pdflastximagepages} */
+ pdf_last_annot_code, /* code for \.{\\pdflastannot} */
+ pdf_last_x_pos_code, /* code for \.{\\pdflastxpos} */
+ pdf_last_y_pos_code, /* code for \.{\\pdflastypos} */
+ pdf_retval_code, /* global multi-purpose return value */
+ pdf_last_ximage_colordepth_code, /* code for \.{\\pdflastximagecolordepth} */
+ random_seed_code, /* code for \.{\\pdfrandomseed} */
+ pdf_last_link_code, /* code for \.{\\pdflastlink} */
+ luatex_version_code, /* code for \.{\\luatexversion} */
+ Aleph_version_code, /* code for \.{\\Alephversion} */
+# define Aleph_int Aleph_version_code
+ Omega_version_code, /* code for \.{\\Omegaversion} */
+ Aleph_minor_version_code, /* code for \.{\\Alephminorversion} */
+ Omega_minor_version_code, /* code for \.{\\Omegaminorversion} */
+ eTeX_minor_version_code, /* code for \.{\\eTeXminorversion} */
+ eTeX_version_code, /* code for \.{\\eTeXversion} */
+# define eTeX_int eTeX_version_code /* first of \eTeX\ codes for integers */
+ current_group_level_code, /* code for \.{\\currentgrouplevel} */
+ current_group_type_code, /* code for \.{\\currentgrouptype} */
+ current_if_level_code, /* code for \.{\\currentiflevel} */
+ current_if_type_code, /* code for \.{\\currentiftype} */
+ current_if_branch_code, /* code for \.{\\currentifbranch} */
+ glue_stretch_order_code, /* code for \.{\\gluestretchorder} */
+ glue_shrink_order_code, /* code for \.{\\glueshrinkorder} */
+ font_char_wd_code, /* code for \.{\\fontcharwd} */
+# define eTeX_dim font_char_wd_code /* first of \eTeX\ codes for dimensions */
+ font_char_ht_code, /* code for \.{\\fontcharht} */
+ font_char_dp_code, /* code for \.{\\fontchardp} */
+ font_char_ic_code, /* code for \.{\\fontcharic} */
+ par_shape_length_code, /* code for \.{\\parshapelength} */
+ par_shape_indent_code, /* code for \.{\\parshapeindent} */
+ par_shape_dimen_code, /* code for \.{\\parshapedimen} */
+ glue_stretch_code, /* code for \.{\\gluestretch} */
+ glue_shrink_code, /* code for \.{\\glueshrink} */
+ mu_to_glue_code, /* code for \.{\\mutoglue} */
+# define eTeX_glue mu_to_glue_code /* first of \eTeX\ codes for glue */
+ glue_to_mu_code, /* code for \.{\\gluetomu} */
+# define eTeX_mu glue_to_mu_code
+ /* first of \eTeX\ codes for muglue */
+ numexpr_code, /* code for \.{\\numexpr} */
+# define eTeX_expr numexpr_code /* first of \eTeX\ codes for expressions */
+ attrexpr_code, /* not used */
+ dimexpr_code, /* code for \.{\\dimexpr} */
+ glueexpr_code, /* code for \.{\\glueexpr} */
+ muexpr_code, /* code for \.{\\muexpr} */
+} last_item_codes;
+
+# define explicit 1
+# define acc_kern 2
+# define lp_code_base 2
+# define rp_code_base 3
+# define ef_code_base 4
+# define tag_code 5
+# define auto_kern explicit
+# define no_lig_code 6
+
+# define immediate_code 4 /* command modifier for \.{\\immediate} */
+
+extern void initialize_commands(void);
+
+extern void initialize_etex_commands(void);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.w b/Build/source/texk/web2c/luatexdir/tex/commands.w
new file mode 100644
index 00000000000..343c04fe6b8
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/commands.w
@@ -0,0 +1,1223 @@
+% commands.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+\def\eTeX{e-\TeX}
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: commands.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/commands.w $";
+
+@ The symbolic names for glue parameters are put into \TeX's hash table
+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.
+
+@c
+void initialize_commands(void)
+{
+
+ primitive_tex("lineskip", assign_glue_cmd, glue_base + line_skip_code,
+ glue_base);
+ primitive_tex("baselineskip", assign_glue_cmd,
+ glue_base + baseline_skip_code, glue_base);
+ primitive_tex("parskip", assign_glue_cmd, glue_base + par_skip_code,
+ glue_base);
+ primitive_tex("abovedisplayskip", assign_glue_cmd,
+ glue_base + above_display_skip_code, glue_base);
+ primitive_tex("belowdisplayskip", assign_glue_cmd,
+ glue_base + below_display_skip_code, glue_base);
+ primitive_tex("abovedisplayshortskip", assign_glue_cmd,
+ glue_base + above_display_short_skip_code, glue_base);
+ primitive_tex("belowdisplayshortskip", assign_glue_cmd,
+ glue_base + below_display_short_skip_code, glue_base);
+ primitive_tex("leftskip", assign_glue_cmd, glue_base + left_skip_code,
+ glue_base);
+ primitive_tex("rightskip", assign_glue_cmd, glue_base + right_skip_code,
+ glue_base);
+ primitive_tex("topskip", assign_glue_cmd, glue_base + top_skip_code,
+ glue_base);
+ primitive_tex("splittopskip", assign_glue_cmd,
+ glue_base + split_top_skip_code, glue_base);
+ primitive_tex("tabskip", assign_glue_cmd, glue_base + tab_skip_code,
+ glue_base);
+ primitive_tex("spaceskip", assign_glue_cmd, glue_base + space_skip_code,
+ glue_base);
+ primitive_tex("xspaceskip", assign_glue_cmd, glue_base + xspace_skip_code,
+ glue_base);
+ primitive_tex("parfillskip", assign_glue_cmd,
+ glue_base + par_fill_skip_code, glue_base);
+ primitive_tex("thinmuskip", assign_mu_glue_cmd,
+ glue_base + thin_mu_skip_code, glue_base + thin_mu_skip_code);
+ primitive_tex("medmuskip", assign_mu_glue_cmd, glue_base + med_mu_skip_code,
+ glue_base + thin_mu_skip_code);
+ primitive_tex("thickmuskip", assign_mu_glue_cmd,
+ glue_base + thick_mu_skip_code,
+ glue_base + thin_mu_skip_code);
+ primitive_tex("output", assign_toks_cmd, output_routine_loc, local_base);
+ primitive_tex("everypar", assign_toks_cmd, every_par_loc, local_base);
+ primitive_tex("everymath", assign_toks_cmd, every_math_loc, local_base);
+ primitive_tex("everydisplay", assign_toks_cmd, every_display_loc,
+ local_base);
+ primitive_tex("everyhbox", assign_toks_cmd, every_hbox_loc, local_base);
+ primitive_tex("everyvbox", assign_toks_cmd, every_vbox_loc, local_base);
+ primitive_tex("everyjob", assign_toks_cmd, every_job_loc, local_base);
+ primitive_tex("everycr", assign_toks_cmd, every_cr_loc, local_base);
+ primitive_tex("errhelp", assign_toks_cmd, err_help_loc, local_base);
+ primitive_pdftex("pdfpagesattr", assign_toks_cmd, pdf_pages_attr_loc,
+ local_base);
+ primitive_pdftex("pdfpageattr", assign_toks_cmd, pdf_page_attr_loc,
+ local_base);
+ primitive_pdftex("pdfpageresources", assign_toks_cmd,
+ pdf_page_resources_loc, local_base);
+ primitive_pdftex("pdfxformattr", assign_toks_cmd, pdf_xform_attr_loc,
+ local_base);
+ primitive_pdftex("pdfxformresources", assign_toks_cmd,
+ pdf_xform_resources_loc, local_base);
+ primitive_pdftex("pdfpkmode", assign_toks_cmd, pdf_pk_mode_loc, local_base);
+
+ /* The integer parameter names must be entered into the hash table */
+ primitive_tex("pretolerance", assign_int_cmd, int_base + pretolerance_code,
+ int_base);
+ primitive_tex("tolerance", assign_int_cmd, int_base + tolerance_code,
+ int_base);
+ primitive_tex("linepenalty", assign_int_cmd, int_base + line_penalty_code,
+ int_base);
+ primitive_tex("hyphenpenalty", assign_int_cmd,
+ int_base + hyphen_penalty_code, int_base);
+ primitive_tex("exhyphenpenalty", assign_int_cmd,
+ int_base + ex_hyphen_penalty_code, int_base);
+ primitive_tex("clubpenalty", assign_int_cmd, int_base + club_penalty_code,
+ int_base);
+ primitive_tex("widowpenalty", assign_int_cmd, int_base + widow_penalty_code,
+ int_base);
+ primitive_tex("displaywidowpenalty", assign_int_cmd,
+ int_base + display_widow_penalty_code, int_base);
+ primitive_tex("brokenpenalty", assign_int_cmd,
+ int_base + broken_penalty_code, int_base);
+ primitive_tex("binoppenalty", assign_int_cmd,
+ int_base + bin_op_penalty_code, int_base);
+ primitive_tex("relpenalty", assign_int_cmd, int_base + rel_penalty_code,
+ int_base);
+ primitive_tex("predisplaypenalty", assign_int_cmd,
+ int_base + pre_display_penalty_code, int_base);
+ primitive_tex("postdisplaypenalty", assign_int_cmd,
+ int_base + post_display_penalty_code, int_base);
+ primitive_tex("interlinepenalty", assign_int_cmd,
+ int_base + inter_line_penalty_code, int_base);
+ primitive_tex("doublehyphendemerits", assign_int_cmd,
+ int_base + double_hyphen_demerits_code, int_base);
+ primitive_tex("finalhyphendemerits", assign_int_cmd,
+ int_base + final_hyphen_demerits_code, int_base);
+ primitive_tex("adjdemerits", assign_int_cmd, int_base + adj_demerits_code,
+ int_base);
+ primitive_tex("mag", assign_int_cmd, int_base + mag_code, int_base);
+ primitive_tex("delimiterfactor", assign_int_cmd,
+ int_base + delimiter_factor_code, int_base);
+ primitive_tex("looseness", assign_int_cmd, int_base + looseness_code,
+ int_base);
+ primitive_tex("time", assign_int_cmd, int_base + time_code, int_base);
+ primitive_tex("day", assign_int_cmd, int_base + day_code, int_base);
+ primitive_tex("month", assign_int_cmd, int_base + month_code, int_base);
+ primitive_tex("year", assign_int_cmd, int_base + year_code, int_base);
+ primitive_tex("showboxbreadth", assign_int_cmd,
+ int_base + show_box_breadth_code, int_base);
+ primitive_tex("showboxdepth", assign_int_cmd,
+ int_base + show_box_depth_code, int_base);
+ primitive_tex("hbadness", assign_int_cmd, int_base + hbadness_code,
+ int_base);
+ primitive_tex("vbadness", assign_int_cmd, int_base + vbadness_code,
+ int_base);
+ primitive_tex("pausing", assign_int_cmd, int_base + pausing_code, int_base);
+ primitive_tex("tracingonline", assign_int_cmd,
+ int_base + tracing_online_code, int_base);
+ primitive_tex("tracingmacros", assign_int_cmd,
+ int_base + tracing_macros_code, int_base);
+ primitive_tex("tracingstats", assign_int_cmd, int_base + tracing_stats_code,
+ int_base);
+ primitive_tex("tracingparagraphs", assign_int_cmd,
+ int_base + tracing_paragraphs_code, int_base);
+ primitive_tex("tracingpages", assign_int_cmd, int_base + tracing_pages_code,
+ int_base);
+ primitive_tex("tracingoutput", assign_int_cmd,
+ int_base + tracing_output_code, int_base);
+ primitive_tex("tracinglostchars", assign_int_cmd,
+ int_base + tracing_lost_chars_code, int_base);
+ primitive_tex("tracingcommands", assign_int_cmd,
+ int_base + tracing_commands_code, int_base);
+ primitive_tex("tracingrestores", assign_int_cmd,
+ int_base + tracing_restores_code, int_base);
+ primitive_tex("uchyph", assign_int_cmd, int_base + uc_hyph_code, int_base);
+ primitive_tex("outputpenalty", assign_int_cmd,
+ int_base + output_penalty_code, int_base);
+ primitive_tex("maxdeadcycles", assign_int_cmd,
+ int_base + max_dead_cycles_code, int_base);
+ primitive_tex("hangafter", assign_int_cmd, int_base + hang_after_code,
+ int_base);
+ primitive_tex("floatingpenalty", assign_int_cmd,
+ int_base + floating_penalty_code, int_base);
+ primitive_tex("globaldefs", assign_int_cmd, int_base + global_defs_code,
+ int_base);
+ primitive_tex("fam", assign_int_cmd, int_base + cur_fam_code, int_base);
+ primitive_tex("escapechar", assign_int_cmd, int_base + escape_char_code,
+ int_base);
+ primitive_tex("defaulthyphenchar", assign_int_cmd,
+ int_base + default_hyphen_char_code, int_base);
+ primitive_tex("defaultskewchar", assign_int_cmd,
+ int_base + default_skew_char_code, int_base);
+ primitive_tex("endlinechar", assign_int_cmd, int_base + end_line_char_code,
+ int_base);
+ primitive_tex("newlinechar", assign_int_cmd, int_base + new_line_char_code,
+ int_base);
+ primitive_tex("language", assign_int_cmd, int_base + language_code,
+ int_base);
+ primitive_tex("setlanguage", assign_int_cmd, int_base + cur_lang_code,
+ int_base);
+ primitive_tex("exhyphenchar", assign_int_cmd,
+ int_base + ex_hyphen_char_code, int_base);
+ primitive_tex("lefthyphenmin", assign_int_cmd,
+ int_base + left_hyphen_min_code, int_base);
+ primitive_tex("righthyphenmin", assign_int_cmd,
+ int_base + right_hyphen_min_code, int_base);
+ primitive_tex("holdinginserts", assign_int_cmd,
+ int_base + holding_inserts_code, int_base);
+ primitive_tex("errorcontextlines", assign_int_cmd,
+ int_base + error_context_lines_code, int_base);
+ primitive_luatex("luastartup", assign_int_cmd,
+ int_base + luastartup_id_code, int_base);
+ primitive_luatex("nokerns", assign_int_cmd, int_base + disable_kern_code,
+ int_base);
+ primitive_luatex("noligs", assign_int_cmd, int_base + disable_lig_code,
+ int_base);
+ primitive_luatex("catcodetable", assign_int_cmd,
+ int_base + cat_code_table_code, int_base);
+ primitive_luatex("outputbox", assign_int_cmd, int_base + output_box_code,
+ int_base);
+ primitive_pdftex("pdfoutput", assign_int_cmd, int_base + pdf_output_code,
+ int_base);
+ primitive_pdftex("pdfcompresslevel", assign_int_cmd,
+ int_base + pdf_compress_level_code, int_base);
+ primitive_pdftex("pdfobjcompresslevel", assign_int_cmd,
+ int_base + pdf_objcompresslevel_code, int_base);
+ primitive_pdftex("pdfdecimaldigits", assign_int_cmd,
+ int_base + pdf_decimal_digits_code, int_base);
+ primitive_pdftex("pdfimageresolution", assign_int_cmd,
+ int_base + pdf_image_resolution_code, int_base);
+ primitive_pdftex("pdfpkresolution", assign_int_cmd,
+ int_base + pdf_pk_resolution_code, int_base);
+ primitive_pdftex("pdfuniqueresname", assign_int_cmd,
+ int_base + pdf_unique_resname_code, int_base);
+ primitive_pdftex("pdfoptionpdfminorversion", assign_int_cmd,
+ int_base + pdf_minor_version_code, int_base);
+ primitive_pdftex("pdfminorversion", assign_int_cmd,
+ int_base + pdf_minor_version_code, int_base);
+ primitive_pdftex("pdfpagebox", assign_int_cmd, int_base + pdf_pagebox_code,
+ int_base);
+ primitive_pdftex("pdfinclusionerrorlevel", assign_int_cmd,
+ int_base + pdf_inclusion_errorlevel_code, int_base);
+ primitive_pdftex("pdfgamma", assign_int_cmd, int_base + pdf_gamma_code,
+ int_base);
+ primitive_pdftex("pdfimagegamma", assign_int_cmd,
+ int_base + pdf_image_gamma_code, int_base);
+ primitive_pdftex("pdfimagehicolor", assign_int_cmd,
+ int_base + pdf_image_hicolor_code, int_base);
+ primitive_pdftex("pdfimageapplygamma", assign_int_cmd,
+ int_base + pdf_image_apply_gamma_code, int_base);
+ primitive_pdftex("pdfadjustspacing", assign_int_cmd,
+ int_base + pdf_adjust_spacing_code, int_base);
+ primitive_pdftex("pdfprotrudechars", assign_int_cmd,
+ int_base + pdf_protrude_chars_code, int_base);
+ primitive_pdftex("pdftracingfonts", assign_int_cmd,
+ int_base + pdf_tracing_fonts_code, int_base);
+ primitive_pdftex("pdfgentounicode", assign_int_cmd,
+ int_base + pdf_gen_tounicode_code, int_base);
+ primitive_pdftex("pdfdraftmode", assign_int_cmd,
+ int_base + pdf_draftmode_code, int_base);
+ primitive_pdftex("pdfinclusioncopyfonts", assign_int_cmd,
+ int_base + pdf_inclusion_copy_font_code, int_base);
+ primitive_pdftex("pdfreplacefont", assign_int_cmd,
+ int_base + pdf_replace_font_code, int_base);
+ primitive_tex("parindent", assign_dimen_cmd, dimen_base + par_indent_code,
+ dimen_base);
+ primitive_tex("mathsurround", assign_dimen_cmd,
+ dimen_base + math_surround_code, dimen_base);
+ primitive_tex("lineskiplimit", assign_dimen_cmd,
+ dimen_base + line_skip_limit_code, dimen_base);
+ primitive_tex("hsize", assign_dimen_cmd, dimen_base + hsize_code,
+ dimen_base);
+ primitive_tex("vsize", assign_dimen_cmd, dimen_base + vsize_code,
+ dimen_base);
+ primitive_tex("maxdepth", assign_dimen_cmd, dimen_base + max_depth_code,
+ dimen_base);
+ primitive_tex("splitmaxdepth", assign_dimen_cmd,
+ dimen_base + split_max_depth_code, dimen_base);
+ primitive_tex("boxmaxdepth", assign_dimen_cmd,
+ dimen_base + box_max_depth_code, dimen_base);
+ primitive_tex("hfuzz", assign_dimen_cmd, dimen_base + hfuzz_code,
+ dimen_base);
+ primitive_tex("vfuzz", assign_dimen_cmd, dimen_base + vfuzz_code,
+ dimen_base);
+ primitive_tex("delimitershortfall", assign_dimen_cmd,
+ dimen_base + delimiter_shortfall_code, dimen_base);
+ primitive_tex("nulldelimiterspace", assign_dimen_cmd,
+ dimen_base + null_delimiter_space_code, dimen_base);
+ primitive_tex("scriptspace", assign_dimen_cmd,
+ dimen_base + script_space_code, dimen_base);
+ primitive_tex("predisplaysize", assign_dimen_cmd,
+ dimen_base + pre_display_size_code, dimen_base);
+ primitive_tex("displaywidth", assign_dimen_cmd,
+ dimen_base + display_width_code, dimen_base);
+ primitive_tex("displayindent", assign_dimen_cmd,
+ dimen_base + display_indent_code, dimen_base);
+ primitive_tex("overfullrule", assign_dimen_cmd,
+ dimen_base + overfull_rule_code, dimen_base);
+ primitive_tex("hangindent", assign_dimen_cmd, dimen_base + hang_indent_code,
+ dimen_base);
+ primitive_tex("hoffset", assign_dimen_cmd, dimen_base + h_offset_code,
+ dimen_base);
+ primitive_tex("voffset", assign_dimen_cmd, dimen_base + v_offset_code,
+ dimen_base);
+ primitive_tex("emergencystretch", assign_dimen_cmd,
+ dimen_base + emergency_stretch_code, dimen_base);
+ primitive_pdftex("pdfhorigin", assign_dimen_cmd,
+ dimen_base + pdf_h_origin_code, dimen_base);
+ primitive_pdftex("pdfvorigin", assign_dimen_cmd,
+ dimen_base + pdf_v_origin_code, dimen_base);
+ primitive_omega("pagewidth", assign_dimen_cmd, dimen_base + page_width_code,
+ dimen_base);
+ primitive_pdftex("pdfpagewidth", assign_dimen_cmd,
+ dimen_base + page_width_code, dimen_base);
+ primitive_omega("pageheight", assign_dimen_cmd,
+ dimen_base + page_height_code, dimen_base);
+ primitive_pdftex("pdfpageheight", assign_dimen_cmd,
+ dimen_base + page_height_code, dimen_base);
+ primitive_pdftex("pdflinkmargin", assign_dimen_cmd,
+ dimen_base + pdf_link_margin_code, dimen_base);
+ primitive_pdftex("pdfdestmargin", assign_dimen_cmd,
+ dimen_base + pdf_dest_margin_code, dimen_base);
+ primitive_pdftex("pdfthreadmargin", assign_dimen_cmd,
+ dimen_base + pdf_thread_margin_code, dimen_base);
+ primitive_pdftex("pdffirstlineheight", assign_dimen_cmd,
+ dimen_base + pdf_first_line_height_code, dimen_base);
+ primitive_pdftex("pdflastlinedepth", assign_dimen_cmd,
+ dimen_base + pdf_last_line_depth_code, dimen_base);
+ primitive_pdftex("pdfeachlineheight", assign_dimen_cmd,
+ dimen_base + pdf_each_line_height_code, dimen_base);
+ primitive_pdftex("pdfeachlinedepth", assign_dimen_cmd,
+ dimen_base + pdf_each_line_depth_code, dimen_base);
+ primitive_pdftex("pdfignoreddimen", assign_dimen_cmd,
+ dimen_base + pdf_ignored_dimen_code, dimen_base);
+ primitive_pdftex("pdfpxdimen", assign_dimen_cmd,
+ dimen_base + pdf_px_dimen_code, dimen_base);
+
+ /* 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_tex(" ", ex_space_cmd, 0, 0);
+ primitive_tex("/", ital_corr_cmd, 0, 0);
+ primitive_tex("accent", accent_cmd, 0, 0);
+ primitive_tex("advance", advance_cmd, 0, 0);
+ primitive_tex("afterassignment", after_assignment_cmd, 0, 0);
+ primitive_tex("aftergroup", after_group_cmd, 0, 0);
+ primitive_tex("begingroup", begin_group_cmd, 0, 0);
+ primitive_tex("char", char_num_cmd, 0, 0);
+ primitive_tex("csname", cs_name_cmd, 0, 0);
+ primitive_tex("delimiter", delim_num_cmd, 0, 0);
+ primitive_omega("odelimiter", delim_num_cmd, 1, 0);
+ primitive_luatex("Udelimiter", delim_num_cmd, 2, 0);
+ primitive_tex("divide", divide_cmd, 0, 0);
+ primitive_tex("endcsname", end_cs_name_cmd, 0, 0);
+ primitive_tex("endgroup", end_group_cmd, 0, 0);
+ cs_text(frozen_end_group) = maketexstring("endgroup");
+ eqtb[frozen_end_group] = eqtb[cur_val];
+ primitive_tex("expandafter", expand_after_cmd, 0, 0);
+ primitive_tex("font", def_font_cmd, 0, 0);
+ primitive_pdftex("letterspacefont", letterspace_font_cmd, 0, 0);
+ primitive_pdftex("pdfcopyfont", pdf_copy_font_cmd, 0, 0);
+ primitive_tex("fontdimen", assign_font_dimen_cmd, 0, 0);
+ primitive_tex("halign", halign_cmd, 0, 0);
+ primitive_tex("hrule", hrule_cmd, 0, 0);
+ primitive_tex("ignorespaces", ignore_spaces_cmd, 0, 0);
+ primitive_tex("insert", insert_cmd, 0, 0);
+ primitive_omega("leftghost", char_ghost_cmd, 0, 0);
+ primitive_tex("mark", mark_cmd, 0, 0);
+ primitive_tex("mathaccent", math_accent_cmd, 0, 0);
+ primitive_omega("omathaccent", math_accent_cmd, 1, 0);
+ primitive_luatex("Umathaccent", math_accent_cmd, 2, 0);
+ primitive_luatex("Umathbotaccent", math_accent_cmd, 3, 0);
+ primitive_luatex("Umathaccents", math_accent_cmd, 4, 0);
+ primitive_tex("mathchar", math_char_num_cmd, 0, 0);
+ primitive_omega("omathchar", math_char_num_cmd, 1, 0);
+ primitive_luatex("Umathchar", math_char_num_cmd, 2, 0);
+ primitive_luatex("Umathcharnum", math_char_num_cmd, 3, 0);
+ primitive_tex("mathchoice", math_choice_cmd, 0, 0);
+ primitive_luatex("Ustack", math_choice_cmd, 1, 0);
+ primitive_tex("multiply", multiply_cmd, 0, 0);
+ primitive_tex("noalign", no_align_cmd, 0, 0);
+ primitive_tex("noboundary", no_boundary_cmd, 0, 0);
+ primitive_tex("noexpand", no_expand_cmd, 0, 0);
+ primitive_luatex("primitive", no_expand_cmd, 1, 0);
+ primitive_pdftex("pdfprimitive", no_expand_cmd, 1, 0);
+ primitive_tex("nonscript", non_script_cmd, 0, 0);
+ primitive_tex("omit", omit_cmd, 0, 0);
+ primitive_tex("parshape", set_tex_shape_cmd, par_shape_loc, par_shape_loc);
+ primitive_tex("penalty", break_penalty_cmd, 0, 0);
+ primitive_tex("prevgraf", set_prev_graf_cmd, 0, 0);
+ primitive_tex("radical", radical_cmd, 0, 0);
+ primitive_omega("oradical", radical_cmd, 1, 0);
+ primitive_luatex("Uradical", radical_cmd, 2, 0);
+ primitive_luatex("Uroot", radical_cmd, 3, 0);
+ primitive_luatex("Uunderdelimiter", radical_cmd, 4, 0);
+ primitive_luatex("Uoverdelimiter", radical_cmd, 5, 0);
+ primitive_luatex("Udelimiterunder", radical_cmd, 6, 0);
+ primitive_luatex("Udelimiterover", radical_cmd, 7, 0);
+ primitive_tex("read", read_to_cs_cmd, 0, 0);
+ primitive_tex("relax", relax_cmd, too_big_char, too_big_char);
+ cs_text(frozen_relax) = maketexstring("relax");
+ eqtb[frozen_relax] = eqtb[cur_val];
+ primitive_omega("rightghost", char_ghost_cmd, 1, 0);
+ primitive_tex("setbox", set_box_cmd, 0, 0);
+ primitive_tex("the", the_cmd, 0, 0);
+ primitive_tex("toks", toks_register_cmd, 0, 0);
+ primitive_tex("vadjust", vadjust_cmd, 0, 0);
+ primitive_tex("valign", valign_cmd, 0, 0);
+ primitive_tex("vcenter", vcenter_cmd, 0, 0);
+ primitive_tex("vrule", vrule_cmd, 0, 0);
+ primitive_tex("par", par_end_cmd, too_big_char, too_big_char); /* cf.\ |scan_file_name| */
+ par_loc = cur_val;
+ par_token = cs_token_flag + par_loc;
+ @<Create a bunch of primitives@>;
+ @<Create the math param primitives@>;
+ @<Create another bunch of primitives@>;
+}
+
+
+@ These are in a separate module due to a CWEAVE limitation.
+
+@<Create a bunch of primitives@>=
+ /* The processing of \.{\\input} involves the |start_input| subroutine,
+ which will be declared later; the processing of \.{\\endinput} is trivial. */
+ primitive_tex("input", input_cmd, 0, 0);
+ primitive_tex("endinput", input_cmd, 1, 0);
+ primitive_tex("topmark", top_bot_mark_cmd, top_mark_code, 0);
+ primitive_tex("firstmark", top_bot_mark_cmd, first_mark_code, 0);
+ primitive_tex("botmark", top_bot_mark_cmd, bot_mark_code, 0);
+ primitive_tex("splitfirstmark", top_bot_mark_cmd, split_first_mark_code, 0);
+ primitive_tex("splitbotmark", top_bot_mark_cmd, split_bot_mark_code, 0);
+ primitive_luatex("clearmarks", mark_cmd, clear_marks_code, 0);
+ primitive_etex("marks", mark_cmd, marks_code, 0);
+ primitive_etex("topmarks", top_bot_mark_cmd, top_mark_code + marks_code, 0);
+ primitive_etex("firstmarks", top_bot_mark_cmd, first_mark_code + marks_code,
+ 0);
+ primitive_etex("botmarks", top_bot_mark_cmd, bot_mark_code + marks_code, 0);
+ primitive_etex("splitfirstmarks", top_bot_mark_cmd,
+ split_first_mark_code + marks_code, 0);
+ primitive_etex("splitbotmarks", top_bot_mark_cmd,
+ split_bot_mark_code + marks_code, 0);
+
+ /* The hash table is initialized with `\.{\\count}', `\.{\\attribute}',
+ `\.{\\dimen}', `\.{\\skip}', and `\.{\\muskip}' all having |register|
+ 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_tex("count", register_cmd, int_val_level, 0);
+ primitive_luatex("attribute", register_cmd, attr_val_level, 0);
+ primitive_tex("dimen", register_cmd, dimen_val_level, 0);
+ primitive_tex("skip", register_cmd, glue_val_level, 0);
+ primitive_tex("muskip", register_cmd, mu_val_level, 0);
+
+ primitive_tex("spacefactor", set_aux_cmd, hmode, 0);
+ primitive_tex("prevdepth", set_aux_cmd, vmode, 0);
+ primitive_tex("deadcycles", set_page_int_cmd, 0, 0);
+ primitive_tex("insertpenalties", set_page_int_cmd, 1, 0);
+ primitive_tex("wd", set_box_dimen_cmd, width_offset, 0);
+ primitive_tex("ht", set_box_dimen_cmd, height_offset, 0);
+ primitive_tex("dp", set_box_dimen_cmd, depth_offset, 0);
+ primitive_tex("lastpenalty", last_item_cmd, lastpenalty_code, 0);
+ primitive_tex("lastkern", last_item_cmd, lastkern_code, 0);
+ primitive_tex("lastskip", last_item_cmd, lastskip_code, 0);
+ primitive_tex("inputlineno", last_item_cmd, input_line_no_code, 0);
+ primitive_tex("badness", last_item_cmd, badness_code, 0);
+ primitive_pdftex("pdftexversion", last_item_cmd, pdftex_version_code, 0);
+ primitive_luatex("luatexversion", last_item_cmd, luatex_version_code, 0);
+ primitive_pdftex("pdflastobj", last_item_cmd, pdf_last_obj_code, 0);
+ primitive_pdftex("pdflastxform", last_item_cmd, pdf_last_xform_code, 0);
+ primitive_pdftex("pdflastximage", last_item_cmd, pdf_last_ximage_code, 0);
+ primitive_pdftex("pdflastximagepages", last_item_cmd,
+ pdf_last_ximage_pages_code, 0);
+ primitive_pdftex("pdflastannot", last_item_cmd, pdf_last_annot_code, 0);
+ primitive_pdftex("pdflastxpos", last_item_cmd, pdf_last_x_pos_code, 0);
+ primitive_pdftex("pdflastypos", last_item_cmd, pdf_last_y_pos_code, 0);
+ primitive_pdftex("pdfretval", last_item_cmd, pdf_retval_code, 0);
+ primitive_pdftex("pdflastximagecolordepth", last_item_cmd,
+ pdf_last_ximage_colordepth_code, 0);
+ primitive_pdftex("pdfrandomseed", last_item_cmd, random_seed_code, 0);
+ primitive_pdftex("pdflastlink", last_item_cmd, pdf_last_link_code, 0);
+
+ primitive_tex("number", convert_cmd, number_code, 0);
+ primitive_tex("romannumeral", convert_cmd, roman_numeral_code, 0);
+ primitive_tex("string", convert_cmd, string_code, 0);
+ primitive_tex("meaning", convert_cmd, meaning_code, 0);
+ primitive_etex("eTeXVersion", convert_cmd, etex_code, 0);
+ primitive_omega("OmegaVersion", convert_cmd, omega_code, 0);
+ primitive_aleph("AlephVersion", convert_cmd, aleph_code, 0);
+ primitive_tex("fontname", convert_cmd, font_name_code, 0);
+ primitive_pdftex("pdftexrevision", convert_cmd, pdftex_revision_code, 0);
+ primitive_luatex("luatexrevision", convert_cmd, luatex_revision_code, 0);
+ primitive_luatex("luatexdatestamp", convert_cmd, luatex_date_code, 0);
+ primitive_pdftex("pdftexbanner", convert_cmd, pdftex_banner_code, 0);
+ primitive_pdftex("pdffontname", convert_cmd, pdf_font_name_code, 0);
+ primitive_pdftex("pdffontobjnum", convert_cmd, pdf_font_objnum_code, 0);
+ primitive_pdftex("pdffontsize", convert_cmd, pdf_font_size_code, 0);
+ primitive_pdftex("pdfpageref", convert_cmd, pdf_page_ref_code, 0);
+ primitive_pdftex("leftmarginkern", convert_cmd, left_margin_kern_code, 0);
+ primitive_pdftex("rightmarginkern", convert_cmd, right_margin_kern_code, 0);
+ primitive_pdftex("pdfxformname", convert_cmd, pdf_xform_name_code, 0);
+ primitive_pdftex("pdfcreationdate", convert_cmd, pdf_creation_date_code, 0);
+ primitive_pdftex("pdfuniformdeviate", convert_cmd, uniform_deviate_code, 0);
+ primitive_pdftex("pdfcolorstackinit", convert_cmd, pdf_colorstack_init_code,
+ 0);
+ primitive_pdftex("pdfnormaldeviate", convert_cmd, normal_deviate_code, 0);
+ primitive_core("directlua", convert_cmd, lua_code, 0);
+ primitive_luatex("luaescapestring", convert_cmd, lua_escape_string_code, 0);
+ primitive_luatex("mathstyle", convert_cmd, math_style_code, 0);
+ primitive_pdftex("expanded", convert_cmd, expanded_code, 0);
+ primitive_tex("jobname", convert_cmd, job_name_code, 0);
+ primitive_luatex("formatname", convert_cmd, format_name_code, 0);
+ primitive_pdftex("pdfinsertht", convert_cmd, pdf_insert_ht_code, 0);
+ primitive_pdftex("pdfximagebbox", convert_cmd, pdf_ximage_bbox_code, 0);
+
+ primitive_tex("if", if_test_cmd, if_char_code, 0);
+ primitive_tex("ifcat", if_test_cmd, if_cat_code, 0);
+ primitive_tex("ifnum", if_test_cmd, if_int_code, 0);
+ primitive_tex("ifdim", if_test_cmd, if_dim_code, 0);
+ primitive_tex("ifodd", if_test_cmd, if_odd_code, 0);
+ primitive_tex("ifvmode", if_test_cmd, if_vmode_code, 0);
+ primitive_tex("ifhmode", if_test_cmd, if_hmode_code, 0);
+ primitive_tex("ifmmode", if_test_cmd, if_mmode_code, 0);
+ primitive_tex("ifinner", if_test_cmd, if_inner_code, 0);
+ primitive_tex("ifvoid", if_test_cmd, if_void_code, 0);
+
+ primitive_tex("ifhbox", if_test_cmd, if_hbox_code, 0);
+ primitive_tex("ifvbox", if_test_cmd, if_vbox_code, 0);
+ primitive_tex("ifx", if_test_cmd, ifx_code, 0);
+ primitive_tex("ifeof", if_test_cmd, if_eof_code, 0);
+ primitive_tex("iftrue", if_test_cmd, if_true_code, 0);
+ primitive_tex("iffalse", if_test_cmd, if_false_code, 0);
+ primitive_tex("ifcase", if_test_cmd, if_case_code, 0);
+ primitive_luatex("ifprimitive", if_test_cmd, if_primitive_code, 0);
+ primitive_pdftex("ifpdfprimitive", if_test_cmd, if_primitive_code, 0);
+
+ primitive_tex("fi", fi_or_else_cmd, fi_code, 0);
+ cs_text(frozen_fi) = maketexstring("fi");
+ eqtb[frozen_fi] = eqtb[cur_val];
+ primitive_tex("or", fi_or_else_cmd, or_code, 0);
+ primitive_tex("else", fi_or_else_cmd, else_code, 0);
+
+ /* \TeX\ always knows at least one font, namely the null font. It has no
+ characters, and its seven parameters are all equal to zero. */
+ primitive_tex("nullfont", set_font_cmd, null_font, 0);
+ cs_text(frozen_null_font) = maketexstring("nullfont");
+ eqtb[frozen_null_font] = eqtb[cur_val];
+ /* $\Omega$ always knows at least one ocp, namely the null ocp.
+ It does nothing. */
+ primitive_omega("nullocp", set_ocp_cmd, null_ocp, 0);
+ cs_text(frozen_null_ocp) = maketexstring("nullocp");
+ eqtb[frozen_null_ocp] = eqtb[cur_val];
+ geq_define(ocp_active_number_base, data_cmd, 0);
+ geq_define(ocp_active_min_ptr_base, data_cmd, 0);
+ geq_define(ocp_active_max_ptr_base, data_cmd, 0);
+ /* $\Omega$ always knows at least one ocp list, namely the null ocp list. */
+ primitive_omega("nullocplist", set_ocp_list_cmd, null_ocp_list, 0);
+ cs_text(frozen_null_ocp_list) = maketexstring("nullocplist");
+ eqtb[frozen_null_ocp_list] = eqtb[cur_val];
+
+ primitive_tex("span", tab_mark_cmd, span_code, tab_mark_cmd_code);
+ primitive_luatex("aligntab", tab_mark_cmd, tab_mark_cmd_code,
+ tab_mark_cmd_code);
+ primitive_luatex("alignmark", mac_param_cmd, tab_mark_cmd_code,
+ tab_mark_cmd_code);
+ primitive_tex("cr", car_ret_cmd, cr_code, cr_code);
+ cs_text(frozen_cr) = maketexstring("cr");
+ eqtb[frozen_cr] = eqtb[cur_val];
+ primitive_tex("crcr", car_ret_cmd, cr_cr_code, cr_code);
+ cs_text(frozen_end_template) = maketexstring("endtemplate");
+ cs_text(frozen_endv) = maketexstring("endtemplate");
+ set_eq_type(frozen_endv, endv_cmd);
+ set_equiv(frozen_endv, null_list);
+ set_eq_level(frozen_endv, level_one);
+ eqtb[frozen_end_template] = eqtb[frozen_endv];
+ set_eq_type(frozen_end_template, end_template_cmd);
+
+ primitive_tex("pagegoal", set_page_dimen_cmd, 0, 0);
+ primitive_tex("pagetotal", set_page_dimen_cmd, 1, 0);
+ primitive_tex("pagestretch", set_page_dimen_cmd, 2, 0);
+ primitive_tex("pagefilstretch", set_page_dimen_cmd, 3, 0);
+ primitive_tex("pagefillstretch", set_page_dimen_cmd, 4, 0);
+ primitive_tex("pagefilllstretch", set_page_dimen_cmd, 5, 0);
+ primitive_tex("pageshrink", set_page_dimen_cmd, 6, 0);
+ primitive_tex("pagedepth", set_page_dimen_cmd, 7, 0);
+
+ /* Either \.{\\dump} or \.{\\end} will cause |main_control| to enter the
+ endgame, since both of them have `|stop|' as their command code. */
+
+ primitive_tex("end", stop_cmd, 0, 0);
+ primitive_tex("dump", stop_cmd, 1, 0);
+
+ primitive_tex("hskip", hskip_cmd, skip_code, 0);
+ primitive_tex("hfil", hskip_cmd, fil_code, 0);
+ primitive_tex("hfill", hskip_cmd, fill_code, 0);
+ primitive_tex("hss", hskip_cmd, ss_code, 0);
+ primitive_tex("hfilneg", hskip_cmd, fil_neg_code, 0);
+ primitive_tex("vskip", vskip_cmd, skip_code, 0);
+ primitive_tex("vfil", vskip_cmd, fil_code, 0);
+ primitive_tex("vfill", vskip_cmd, fill_code, 0);
+ primitive_tex("vss", vskip_cmd, ss_code, 0);
+ primitive_tex("vfilneg", vskip_cmd, fil_neg_code, 0);
+ primitive_tex("mskip", mskip_cmd, mskip_code, 0);
+ primitive_tex("kern", kern_cmd, explicit, 0);
+ primitive_tex("mkern", mkern_cmd, mu_glue, 0);
+ primitive_tex("moveleft", hmove_cmd, 1, 0);
+ primitive_tex("moveright", hmove_cmd, 0, 0);
+ primitive_tex("raise", vmove_cmd, 1, 0);
+ primitive_tex("lower", vmove_cmd, 0, 0);
+ primitive_tex("box", make_box_cmd, box_code, 0);
+ primitive_tex("copy", make_box_cmd, copy_code, 0);
+ primitive_tex("lastbox", make_box_cmd, last_box_code, 0);
+ primitive_tex("vsplit", make_box_cmd, vsplit_code, 0);
+ primitive_tex("vtop", make_box_cmd, vtop_code, 0);
+ primitive_tex("vbox", make_box_cmd, vtop_code + vmode, 0);
+ primitive_tex("hbox", make_box_cmd, vtop_code + hmode, 0);
+ primitive_tex("shipout", leader_ship_cmd, a_leaders - 1, 0); /* |ship_out_flag=leader_flag-1| */
+ primitive_tex("leaders", leader_ship_cmd, a_leaders, 0);
+ primitive_tex("cleaders", leader_ship_cmd, c_leaders, 0);
+ primitive_tex("xleaders", leader_ship_cmd, x_leaders, 0);
+ primitive_luatex("gleaders", leader_ship_cmd, g_leaders, 0);
+ primitive_aleph("boxdir", assign_box_dir_cmd, 0, 0);
+ primitive_tex("indent", start_par_cmd, 1, 0);
+ primitive_tex("noindent", start_par_cmd, 0, 0);
+ primitive_pdftex("quitvmode", start_par_cmd, 2, 0);
+ primitive_tex("unpenalty", remove_item_cmd, penalty_node, 0);
+ primitive_tex("unkern", remove_item_cmd, kern_node, 0);
+ primitive_tex("unskip", remove_item_cmd, glue_node, 0);
+ primitive_tex("unhbox", un_hbox_cmd, box_code, 0);
+ primitive_tex("unhcopy", un_hbox_cmd, copy_code, 0);
+ primitive_tex("unvbox", un_vbox_cmd, box_code, 0);
+ primitive_tex("unvcopy", un_vbox_cmd, copy_code, 0);
+ primitive_tex("-", discretionary_cmd, explicit_disc, 0);
+ primitive_tex("discretionary", discretionary_cmd, discretionary_disc, 0);
+ primitive_omega("localleftbox", assign_local_box_cmd, 0, 0);
+ primitive_omega("localrightbox", assign_local_box_cmd, 1, 0);
+
+ primitive_luatex("Ustartmath", math_shift_cs_cmd, text_style, 0);
+ primitive_luatex("Ustopmath", math_shift_cs_cmd, cramped_text_style, 0);
+ primitive_luatex("Ustartdisplaymath", math_shift_cs_cmd, display_style, 0);
+ primitive_luatex("Ustopdisplaymath", math_shift_cs_cmd,
+ cramped_display_style, 0);
+ primitive_tex("eqno", eq_no_cmd, 0, 0);
+ primitive_tex("leqno", eq_no_cmd, 1, 0);
+ primitive_tex("mathord", math_comp_cmd, ord_noad_type, 0);
+ primitive_tex("mathop", math_comp_cmd, op_noad_type_normal, 0);
+ primitive_tex("mathbin", math_comp_cmd, bin_noad_type, 0);
+ primitive_tex("mathrel", math_comp_cmd, rel_noad_type, 0);
+ primitive_tex("mathopen", math_comp_cmd, open_noad_type, 0);
+ primitive_tex("mathclose", math_comp_cmd, close_noad_type, 0);
+ primitive_tex("mathpunct", math_comp_cmd, punct_noad_type, 0);
+ primitive_tex("mathinner", math_comp_cmd, inner_noad_type, 0);
+ primitive_tex("underline", math_comp_cmd, under_noad_type, 0);
+ primitive_tex("overline", math_comp_cmd, over_noad_type, 0);
+ primitive_tex("displaylimits", limit_switch_cmd, op_noad_type_normal, 0);
+ primitive_tex("limits", limit_switch_cmd, op_noad_type_limits, 0);
+ primitive_tex("nolimits", limit_switch_cmd, op_noad_type_no_limits, 0);
+ primitive_tex("displaystyle", math_style_cmd, display_style, 0);
+ primitive_tex("textstyle", math_style_cmd, text_style, 0);
+ primitive_tex("scriptstyle", math_style_cmd, script_style, 0);
+ primitive_tex("scriptscriptstyle", math_style_cmd, script_script_style, 0);
+ primitive_luatex("crampeddisplaystyle", math_style_cmd,
+ cramped_display_style, 0);
+ primitive_luatex("crampedtextstyle", math_style_cmd, cramped_text_style, 0);
+ primitive_luatex("crampedscriptstyle", math_style_cmd, cramped_script_style,
+ 0);
+ primitive_luatex("crampedscriptscriptstyle", math_style_cmd,
+ cramped_script_script_style, 0);
+ primitive_luatex("Usuperscript", super_sub_script_cmd, sup_mark_cmd,
+ sup_mark_cmd);
+ primitive_luatex("Usubscript", super_sub_script_cmd, sub_mark_cmd,
+ sup_mark_cmd);
+ primitive_tex("above", above_cmd, above_code, 0);
+ primitive_tex("over", above_cmd, over_code, 0);
+ primitive_tex("atop", above_cmd, atop_code, 0);
+ primitive_tex("abovewithdelims", above_cmd, delimited_code + above_code, 0);
+ primitive_tex("overwithdelims", above_cmd, delimited_code + over_code, 0);
+ primitive_tex("atopwithdelims", above_cmd, delimited_code + atop_code, 0);
+ primitive_tex("left", left_right_cmd, left_noad_side, 0);
+ primitive_tex("right", left_right_cmd, right_noad_side, 0);
+ primitive_tex("middle", left_right_cmd, middle_noad_side, 0);
+ cs_text(frozen_right) = maketexstring("right");
+ eqtb[frozen_right] = eqtb[cur_val];
+
+ primitive_tex("long", prefix_cmd, 1, 0);
+ primitive_tex("outer", prefix_cmd, 2, 0);
+ primitive_tex("global", prefix_cmd, 4, 0);
+ primitive_tex("def", def_cmd, 0, 0);
+ primitive_tex("gdef", def_cmd, 1, 0);
+ primitive_tex("edef", def_cmd, 2, 0);
+ primitive_tex("xdef", def_cmd, 3, 0);
+ primitive_tex("let", let_cmd, normal, 0);
+ primitive_tex("futurelet", let_cmd, normal + 1, 0);
+ primitive_tex("chardef", shorthand_def_cmd, char_def_code, 0);
+ primitive_tex("mathchardef", shorthand_def_cmd, math_char_def_code, 0);
+ primitive_omega("omathchardef", shorthand_def_cmd, omath_char_def_code, 0);
+ primitive_luatex("Umathchardef", shorthand_def_cmd, xmath_char_def_code, 0);
+ primitive_tex("countdef", shorthand_def_cmd, count_def_code, 0);
+ primitive_luatex("attributedef", shorthand_def_cmd, attribute_def_code, 0);
+ primitive_tex("dimendef", shorthand_def_cmd, dimen_def_code, 0);
+ primitive_tex("skipdef", shorthand_def_cmd, skip_def_code, 0);
+ primitive_tex("muskipdef", shorthand_def_cmd, mu_skip_def_code, 0);
+ primitive_tex("toksdef", shorthand_def_cmd, toks_def_code, 0);
+ primitive_tex("catcode", def_char_code_cmd, cat_code_base, cat_code_base);
+ primitive_tex("mathcode", def_char_code_cmd, math_code_base, cat_code_base);
+ primitive_tex("lccode", def_char_code_cmd, lc_code_base, cat_code_base);
+ primitive_tex("uccode", def_char_code_cmd, uc_code_base, cat_code_base);
+ primitive_tex("sfcode", def_char_code_cmd, sf_code_base, cat_code_base);
+ primitive_tex("delcode", def_del_code_cmd, del_code_base, del_code_base);
+ primitive_tex("textfont", def_family_cmd, text_size, 0);
+ primitive_tex("scriptfont", def_family_cmd, script_size, 0);
+ primitive_tex("scriptscriptfont", def_family_cmd, script_script_size, 0);
+ primitive_luatex("Umathquad", set_math_param_cmd, math_param_quad, 0);
+ primitive_luatex("Umathaxis", set_math_param_cmd, math_param_axis, 0);
+
+
+@ These are in a separate module due to a CWEAVE limitation.
+
+@<Create the math param primitives@>=
+ primitive_luatex("Umathoperatorsize", set_math_param_cmd,
+ math_param_operator_size, 0);
+ primitive_luatex("Umathoverbarkern", set_math_param_cmd,
+ math_param_overbar_kern, 0);
+ primitive_luatex("Umathoverbarrule", set_math_param_cmd,
+ math_param_overbar_rule, 0);
+ primitive_luatex("Umathoverbarvgap", set_math_param_cmd,
+ math_param_overbar_vgap, 0);
+ primitive_luatex("Umathunderbarkern", set_math_param_cmd,
+ math_param_underbar_kern, 0);
+ primitive_luatex("Umathunderbarrule", set_math_param_cmd,
+ math_param_underbar_rule, 0);
+ primitive_luatex("Umathunderbarvgap", set_math_param_cmd,
+ math_param_underbar_vgap, 0);
+ primitive_luatex("Umathradicalkern", set_math_param_cmd,
+ math_param_radical_kern, 0);
+ primitive_luatex("Umathradicalrule", set_math_param_cmd,
+ math_param_radical_rule, 0);
+ primitive_luatex("Umathradicalvgap", set_math_param_cmd,
+ math_param_radical_vgap, 0);
+ primitive_luatex("Umathradicaldegreebefore", set_math_param_cmd,
+ math_param_radical_degree_before, 0);
+ primitive_luatex("Umathradicaldegreeafter", set_math_param_cmd,
+ math_param_radical_degree_after, 0);
+ primitive_luatex("Umathradicaldegreeraise", set_math_param_cmd,
+ math_param_radical_degree_raise, 0);
+ primitive_luatex("Umathstackvgap", set_math_param_cmd,
+ math_param_stack_vgap, 0);
+ primitive_luatex("Umathstacknumup", set_math_param_cmd,
+ math_param_stack_num_up, 0);
+ primitive_luatex("Umathstackdenomdown", set_math_param_cmd,
+ math_param_stack_denom_down, 0);
+ primitive_luatex("Umathfractionrule", set_math_param_cmd,
+ math_param_fraction_rule, 0);
+ primitive_luatex("Umathfractionnumvgap", set_math_param_cmd,
+ math_param_fraction_num_vgap, 0);
+ primitive_luatex("Umathfractionnumup", set_math_param_cmd,
+ math_param_fraction_num_up, 0);
+ primitive_luatex("Umathfractiondenomvgap", set_math_param_cmd,
+ math_param_fraction_denom_vgap, 0);
+ primitive_luatex("Umathfractiondenomdown", set_math_param_cmd,
+ math_param_fraction_denom_down, 0);
+ primitive_luatex("Umathfractiondelsize", set_math_param_cmd,
+ math_param_fraction_del_size, 0);
+ primitive_luatex("Umathlimitabovevgap", set_math_param_cmd,
+ math_param_limit_above_vgap, 0);
+ primitive_luatex("Umathlimitabovebgap", set_math_param_cmd,
+ math_param_limit_above_bgap, 0);
+ primitive_luatex("Umathlimitabovekern", set_math_param_cmd,
+ math_param_limit_above_kern, 0);
+ primitive_luatex("Umathlimitbelowvgap", set_math_param_cmd,
+ math_param_limit_below_vgap, 0);
+ primitive_luatex("Umathlimitbelowbgap", set_math_param_cmd,
+ math_param_limit_below_bgap, 0);
+ primitive_luatex("Umathlimitbelowkern", set_math_param_cmd,
+ math_param_limit_below_kern, 0);
+ primitive_luatex("Umathunderdelimitervgap", set_math_param_cmd,
+ math_param_under_delimiter_vgap, 0);
+ primitive_luatex("Umathunderdelimiterbgap", set_math_param_cmd,
+ math_param_under_delimiter_bgap, 0);
+ primitive_luatex("Umathoverdelimitervgap", set_math_param_cmd,
+ math_param_over_delimiter_vgap, 0);
+ primitive_luatex("Umathoverdelimiterbgap", set_math_param_cmd,
+ math_param_over_delimiter_bgap, 0);
+ primitive_luatex("Umathsubshiftdrop", set_math_param_cmd,
+ math_param_sub_shift_drop, 0);
+ primitive_luatex("Umathsupshiftdrop", set_math_param_cmd,
+ math_param_sup_shift_drop, 0);
+ primitive_luatex("Umathsubshiftdown", set_math_param_cmd,
+ math_param_sub_shift_down, 0);
+ primitive_luatex("Umathsubsupshiftdown", set_math_param_cmd,
+ math_param_sub_sup_shift_down, 0);
+ primitive_luatex("Umathsubtopmax", set_math_param_cmd,
+ math_param_sub_top_max, 0);
+ primitive_luatex("Umathsupshiftup", set_math_param_cmd,
+ math_param_sup_shift_up, 0);
+ primitive_luatex("Umathsupbottommin", set_math_param_cmd,
+ math_param_sup_bottom_min, 0);
+ primitive_luatex("Umathsupsubbottommax", set_math_param_cmd,
+ math_param_sup_sub_bottom_max, 0);
+ primitive_luatex("Umathsubsupvgap", set_math_param_cmd,
+ math_param_subsup_vgap, 0);
+ primitive_luatex("Umathspaceafterscript", set_math_param_cmd,
+ math_param_space_after_script, 0);
+ primitive_luatex("Umathconnectoroverlapmin", set_math_param_cmd,
+ math_param_connector_overlap_min, 0);
+ primitive_luatex("Umathordordspacing", set_math_param_cmd,
+ math_param_ord_ord_spacing, 0);
+ primitive_luatex("Umathordopspacing", set_math_param_cmd,
+ math_param_ord_op_spacing, 0);
+ primitive_luatex("Umathordbinspacing", set_math_param_cmd,
+ math_param_ord_bin_spacing, 0);
+ primitive_luatex("Umathordrelspacing", set_math_param_cmd,
+ math_param_ord_rel_spacing, 0);
+ primitive_luatex("Umathordopenspacing", set_math_param_cmd,
+ math_param_ord_open_spacing, 0);
+ primitive_luatex("Umathordclosespacing", set_math_param_cmd,
+ math_param_ord_close_spacing, 0);
+ primitive_luatex("Umathordpunctspacing", set_math_param_cmd,
+ math_param_ord_punct_spacing, 0);
+ primitive_luatex("Umathordinnerspacing", set_math_param_cmd,
+ math_param_ord_inner_spacing, 0);
+ primitive_luatex("Umathopordspacing", set_math_param_cmd,
+ math_param_op_ord_spacing, 0);
+ primitive_luatex("Umathopopspacing", set_math_param_cmd,
+ math_param_op_op_spacing, 0);
+ primitive_luatex("Umathopbinspacing", set_math_param_cmd,
+ math_param_op_bin_spacing, 0);
+ primitive_luatex("Umathoprelspacing", set_math_param_cmd,
+ math_param_op_rel_spacing, 0);
+ primitive_luatex("Umathopopenspacing", set_math_param_cmd,
+ math_param_op_open_spacing, 0);
+ primitive_luatex("Umathopclosespacing", set_math_param_cmd,
+ math_param_op_close_spacing, 0);
+ primitive_luatex("Umathoppunctspacing", set_math_param_cmd,
+ math_param_op_punct_spacing, 0);
+ primitive_luatex("Umathopinnerspacing", set_math_param_cmd,
+ math_param_op_inner_spacing, 0);
+ primitive_luatex("Umathbinordspacing", set_math_param_cmd,
+ math_param_bin_ord_spacing, 0);
+ primitive_luatex("Umathbinopspacing", set_math_param_cmd,
+ math_param_bin_op_spacing, 0);
+ primitive_luatex("Umathbinbinspacing", set_math_param_cmd,
+ math_param_bin_bin_spacing, 0);
+ primitive_luatex("Umathbinrelspacing", set_math_param_cmd,
+ math_param_bin_rel_spacing, 0);
+ primitive_luatex("Umathbinopenspacing", set_math_param_cmd,
+ math_param_bin_open_spacing, 0);
+ primitive_luatex("Umathbinclosespacing", set_math_param_cmd,
+ math_param_bin_close_spacing, 0);
+ primitive_luatex("Umathbinpunctspacing", set_math_param_cmd,
+ math_param_bin_punct_spacing, 0);
+ primitive_luatex("Umathbininnerspacing", set_math_param_cmd,
+ math_param_bin_inner_spacing, 0);
+ primitive_luatex("Umathrelordspacing", set_math_param_cmd,
+ math_param_rel_ord_spacing, 0);
+ primitive_luatex("Umathrelopspacing", set_math_param_cmd,
+ math_param_rel_op_spacing, 0);
+ primitive_luatex("Umathrelbinspacing", set_math_param_cmd,
+ math_param_rel_bin_spacing, 0);
+ primitive_luatex("Umathrelrelspacing", set_math_param_cmd,
+ math_param_rel_rel_spacing, 0);
+ primitive_luatex("Umathrelopenspacing", set_math_param_cmd,
+ math_param_rel_open_spacing, 0);
+ primitive_luatex("Umathrelclosespacing", set_math_param_cmd,
+ math_param_rel_close_spacing, 0);
+ primitive_luatex("Umathrelpunctspacing", set_math_param_cmd,
+ math_param_rel_punct_spacing, 0);
+ primitive_luatex("Umathrelinnerspacing", set_math_param_cmd,
+ math_param_rel_inner_spacing, 0);
+ primitive_luatex("Umathopenordspacing", set_math_param_cmd,
+ math_param_open_ord_spacing, 0);
+ primitive_luatex("Umathopenopspacing", set_math_param_cmd,
+ math_param_open_op_spacing, 0);
+ primitive_luatex("Umathopenbinspacing", set_math_param_cmd,
+ math_param_open_bin_spacing, 0);
+ primitive_luatex("Umathopenrelspacing", set_math_param_cmd,
+ math_param_open_rel_spacing, 0);
+ primitive_luatex("Umathopenopenspacing", set_math_param_cmd,
+ math_param_open_open_spacing, 0);
+ primitive_luatex("Umathopenclosespacing", set_math_param_cmd,
+ math_param_open_close_spacing, 0);
+ primitive_luatex("Umathopenpunctspacing", set_math_param_cmd,
+ math_param_open_punct_spacing, 0);
+ primitive_luatex("Umathopeninnerspacing", set_math_param_cmd,
+ math_param_open_inner_spacing, 0);
+ primitive_luatex("Umathcloseordspacing", set_math_param_cmd,
+ math_param_close_ord_spacing, 0);
+ primitive_luatex("Umathcloseopspacing", set_math_param_cmd,
+ math_param_close_op_spacing, 0);
+ primitive_luatex("Umathclosebinspacing", set_math_param_cmd,
+ math_param_close_bin_spacing, 0);
+ primitive_luatex("Umathcloserelspacing", set_math_param_cmd,
+ math_param_close_rel_spacing, 0);
+ primitive_luatex("Umathcloseopenspacing", set_math_param_cmd,
+ math_param_close_open_spacing, 0);
+ primitive_luatex("Umathcloseclosespacing", set_math_param_cmd,
+ math_param_close_close_spacing, 0);
+ primitive_luatex("Umathclosepunctspacing", set_math_param_cmd,
+ math_param_close_punct_spacing, 0);
+ primitive_luatex("Umathcloseinnerspacing", set_math_param_cmd,
+ math_param_close_inner_spacing, 0);
+ primitive_luatex("Umathpunctordspacing", set_math_param_cmd,
+ math_param_punct_ord_spacing, 0);
+ primitive_luatex("Umathpunctopspacing", set_math_param_cmd,
+ math_param_punct_op_spacing, 0);
+ primitive_luatex("Umathpunctbinspacing", set_math_param_cmd,
+ math_param_punct_bin_spacing, 0);
+ primitive_luatex("Umathpunctrelspacing", set_math_param_cmd,
+ math_param_punct_rel_spacing, 0);
+ primitive_luatex("Umathpunctopenspacing", set_math_param_cmd,
+ math_param_punct_open_spacing, 0);
+ primitive_luatex("Umathpunctclosespacing", set_math_param_cmd,
+ math_param_punct_close_spacing, 0);
+ primitive_luatex("Umathpunctpunctspacing", set_math_param_cmd,
+ math_param_punct_punct_spacing, 0);
+ primitive_luatex("Umathpunctinnerspacing", set_math_param_cmd,
+ math_param_punct_inner_spacing, 0);
+ primitive_luatex("Umathinnerordspacing", set_math_param_cmd,
+ math_param_inner_ord_spacing, 0);
+ primitive_luatex("Umathinneropspacing", set_math_param_cmd,
+ math_param_inner_op_spacing, 0);
+ primitive_luatex("Umathinnerbinspacing", set_math_param_cmd,
+ math_param_inner_bin_spacing, 0);
+ primitive_luatex("Umathinnerrelspacing", set_math_param_cmd,
+ math_param_inner_rel_spacing, 0);
+ primitive_luatex("Umathinneropenspacing", set_math_param_cmd,
+ math_param_inner_open_spacing, 0);
+ primitive_luatex("Umathinnerclosespacing", set_math_param_cmd,
+ math_param_inner_close_spacing, 0);
+ primitive_luatex("Umathinnerpunctspacing", set_math_param_cmd,
+ math_param_inner_punct_spacing, 0);
+ primitive_luatex("Umathinnerinnerspacing", set_math_param_cmd,
+ math_param_inner_inner_spacing, 0);
+
+@ These are in a separate module due to a CWEAVE limitation.
+
+@<Create another bunch of primitives@>=
+ primitive_omega("omathcode", extdef_math_code_cmd, math_code_base,
+ math_code_base);
+ primitive_omega("odelcode", extdef_del_code_cmd, del_code_base,
+ del_code_base);
+ primitive_luatex("Umathcode", extdef_math_code_cmd, math_code_base + 1,
+ math_code_base);
+ primitive_luatex("Udelcode", extdef_del_code_cmd, del_code_base + 1,
+ del_code_base);
+ primitive_luatex("Umathcodenum", extdef_math_code_cmd, math_code_base + 2,
+ math_code_base);
+ primitive_luatex("Udelcodenum", extdef_del_code_cmd, del_code_base + 2,
+ del_code_base);
+ primitive_tex("hyphenation", hyph_data_cmd, 0, 0);
+ primitive_tex("patterns", hyph_data_cmd, 1, 0);
+ primitive_luatex("prehyphenchar", hyph_data_cmd, 2, 0);
+ primitive_luatex("posthyphenchar", hyph_data_cmd, 3, 0);
+ primitive_luatex("preexhyphenchar", hyph_data_cmd, 4, 0);
+ primitive_luatex("postexhyphenchar", hyph_data_cmd, 5, 0);
+ primitive_tex("hyphenchar", assign_font_int_cmd, 0, 0);
+ primitive_tex("skewchar", assign_font_int_cmd, 1, 0);
+ primitive_pdftex("lpcode", assign_font_int_cmd, lp_code_base, 0);
+ primitive_pdftex("rpcode", assign_font_int_cmd, rp_code_base, 0);
+ primitive_pdftex("efcode", assign_font_int_cmd, ef_code_base, 0);
+ primitive_pdftex("tagcode", assign_font_int_cmd, tag_code, 0);
+ primitive_pdftex("pdfnoligatures", assign_font_int_cmd, no_lig_code, 0);
+ primitive_tex("batchmode", set_interaction_cmd, batch_mode, 0);
+ primitive_tex("nonstopmode", set_interaction_cmd, nonstop_mode, 0);
+ primitive_tex("scrollmode", set_interaction_cmd, scroll_mode, 0);
+ primitive_tex("errorstopmode", set_interaction_cmd, error_stop_mode, 0);
+ primitive_tex("openin", in_stream_cmd, 1, 0);
+ primitive_tex("closein", in_stream_cmd, 0, 0);
+ primitive_tex("message", message_cmd, 0, 0);
+ primitive_tex("errmessage", message_cmd, 1, 0);
+ primitive_tex("lowercase", case_shift_cmd, lc_code_base, lc_code_base);
+ primitive_tex("uppercase", case_shift_cmd, uc_code_base, lc_code_base);
+ primitive_tex("show", xray_cmd, show_code, 0);
+ primitive_tex("showbox", xray_cmd, show_box_code, 0);
+ primitive_tex("showthe", xray_cmd, show_the_code, 0);
+ primitive_tex("showlists", xray_cmd, show_lists, 0);
+
+ primitive_tex("openout", extension_cmd, open_node, 0);
+ primitive_tex("write", extension_cmd, write_node, 0);
+ write_loc = cur_val;
+ primitive_tex("closeout", extension_cmd, close_node, 0);
+ primitive_tex("special", extension_cmd, special_node, 0);
+ cs_text(frozen_special) = maketexstring("special");
+ eqtb[frozen_special] = eqtb[cur_val];
+ primitive_tex("immediate", extension_cmd, immediate_code, 0);
+ primitive_omega("localinterlinepenalty", assign_int_cmd,
+ int_base + local_inter_line_penalty_code, int_base);
+ primitive_omega("localbrokenpenalty", assign_int_cmd,
+ int_base + local_broken_penalty_code, int_base);
+ primitive_omega("pagedir", assign_dir_cmd, int_base + page_direction_code,
+ dir_base);
+ primitive_omega("bodydir", assign_dir_cmd, int_base + body_direction_code,
+ dir_base);
+ primitive_omega("pardir", assign_dir_cmd, int_base + par_direction_code,
+ dir_base);
+ primitive_omega("textdir", assign_dir_cmd, int_base + text_direction_code,
+ dir_base);
+ primitive_omega("mathdir", assign_dir_cmd, int_base + math_direction_code,
+ dir_base);
+ primitive_luatex("pageleftoffset", assign_dimen_cmd,
+ dimen_base + page_left_offset_code, dimen_base);
+ primitive_luatex("pagetopoffset", assign_dimen_cmd,
+ dimen_base + page_top_offset_code, dimen_base);
+ primitive_aleph("pagerightoffset", assign_dimen_cmd,
+ dimen_base + page_right_offset_code, dimen_base);
+ primitive_aleph("pagebottomoffset", assign_dimen_cmd,
+ dimen_base + page_bottom_offset_code, dimen_base);
+ primitive_pdftex("pdfliteral", extension_cmd, pdf_literal_node, 0);
+ primitive_pdftex("pdfcolorstack", extension_cmd, pdf_colorstack_node, 0);
+ primitive_pdftex("pdfsetmatrix", extension_cmd, pdf_setmatrix_node, 0);
+ primitive_pdftex("pdfsave", extension_cmd, pdf_save_node, 0);
+ primitive_pdftex("pdfrestore", extension_cmd, pdf_restore_node, 0);
+ primitive_pdftex("pdfobj", extension_cmd, pdf_obj_code, 0);
+ primitive_pdftex("pdfrefobj", extension_cmd, pdf_refobj_node, 0);
+ primitive_pdftex("pdfxform", extension_cmd, pdf_xform_code, 0);
+ primitive_pdftex("pdfrefxform", extension_cmd, pdf_refxform_node, 0);
+ primitive_pdftex("pdfximage", extension_cmd, pdf_ximage_code, 0);
+ primitive_pdftex("pdfrefximage", extension_cmd, pdf_refximage_node, 0);
+ primitive_pdftex("pdfannot", extension_cmd, pdf_annot_node, 0);
+ primitive_pdftex("pdfstartlink", extension_cmd, pdf_start_link_node, 0);
+ primitive_pdftex("pdfendlink", extension_cmd, pdf_end_link_node, 0);
+ primitive_pdftex("pdfoutline", extension_cmd, pdf_outline_code, 0);
+ primitive_pdftex("pdfdest", extension_cmd, pdf_dest_node, 0);
+ primitive_pdftex("pdfthread", extension_cmd, pdf_thread_node, 0);
+ primitive_pdftex("pdfstartthread", extension_cmd, pdf_start_thread_node, 0);
+ primitive_pdftex("pdfendthread", extension_cmd, pdf_end_thread_node, 0);
+ primitive_pdftex("pdfsavepos", extension_cmd, pdf_save_pos_node, 0);
+ primitive_pdftex("pdfinfo", extension_cmd, pdf_info_code, 0);
+ primitive_pdftex("pdfcatalog", extension_cmd, pdf_catalog_code, 0);
+ primitive_pdftex("pdfnames", extension_cmd, pdf_names_code, 0);
+ primitive_pdftex("pdfincludechars", extension_cmd, pdf_include_chars_code,
+ 0);
+ primitive_pdftex("pdffontattr", extension_cmd, pdf_font_attr_code, 0);
+ primitive_pdftex("pdfmapfile", extension_cmd, pdf_map_file_code, 0);
+ primitive_pdftex("pdfmapline", extension_cmd, pdf_map_line_code, 0);
+ primitive_pdftex("pdftrailer", extension_cmd, pdf_trailer_code, 0);
+ primitive_luatex("savecatcodetable", extension_cmd,
+ save_cat_code_table_code, 0);
+ primitive_luatex("initcatcodetable", extension_cmd,
+ init_cat_code_table_code, 0);
+ primitive_pdftex("pdfsetrandomseed", extension_cmd, set_random_seed_code,
+ 0);
+ primitive_luatex("latelua", extension_cmd, late_lua_node, 0);
+ primitive_pdftex("pdffontexpand", extension_cmd, pdf_font_expand_code, 0);
+ primitive_pdftex("pdfglyphtounicode", extension_cmd,
+ pdf_glyph_to_unicode_code, 0);
+
+ primitive_omega("ocp", def_ocp_cmd, 0, 0);
+ primitive_omega("externalocp", def_ocp_cmd, 1, 0);
+ primitive_omega("ocplist", def_ocp_list_cmd, 0, 0);
+ primitive_omega("pushocplist", push_ocp_list_cmd, 0, 0);
+ primitive_omega("popocplist", pop_ocp_list_cmd, 0, 0);
+ primitive_omega("clearocplists", clear_ocp_lists_cmd, 0, 0);
+ primitive_omega("addbeforeocplist", ocp_list_op_cmd, add_before_op, 0);
+ primitive_omega("addafterocplist", ocp_list_op_cmd, add_after_op, 0);
+ primitive_omega("removebeforeocplist", ocp_list_op_cmd, remove_before_op,
+ 0);
+ primitive_omega("removeafterocplist", ocp_list_op_cmd, remove_after_op, 0);
+ primitive_omega("ocptracelevel", ocp_trace_level_cmd, 0, 0);
+ set_equiv(ocp_trace_level_base, 0);
+
+ /* some of the internal integer parameters are not associated with actual
+ primitives at all. */
+
+ primitive_no("nolocalwhatsits", assign_int_cmd,
+ int_base + no_local_whatsits_code, int_base);
+ primitive_no("nolocaldirs", assign_int_cmd,
+ int_base + no_local_dirs_code, int_base);
+
+
+
+@ @c
+void initialize_etex_commands(void)
+{
+ primitive_etex("lastnodetype", last_item_cmd, last_node_type_code, 0);
+ primitive_aleph("Alephversion", last_item_cmd, Aleph_version_code, 0);
+ primitive_aleph("Omegaversion", last_item_cmd, Omega_version_code, 0);
+ primitive_etex("eTeXversion", last_item_cmd, eTeX_version_code, 0);
+ primitive_aleph("Alephminorversion", last_item_cmd,
+ Aleph_minor_version_code, 0);
+ primitive_aleph("Omegaminorversion", last_item_cmd,
+ Omega_minor_version_code, 0);
+ primitive_etex("eTeXminorversion", last_item_cmd, eTeX_minor_version_code,
+ 0);
+ primitive_aleph("Alephrevision", convert_cmd, Aleph_revision_code, 0);
+ primitive_aleph("Omegarevision", convert_cmd, Omega_revision_code, 0);
+ primitive_etex("eTeXrevision", convert_cmd, eTeX_revision_code, 0);
+
+ /* First we implement the additional \eTeX\ parameters in the table of equivalents. */
+
+ primitive_etex("everyeof", assign_toks_cmd, every_eof_loc, local_base);
+ primitive_etex("tracingassigns", assign_int_cmd,
+ int_base + tracing_assigns_code, int_base);
+ primitive_etex("tracinggroups", assign_int_cmd,
+ int_base + tracing_groups_code, int_base);
+ primitive_etex("tracingifs", assign_int_cmd, int_base + tracing_ifs_code,
+ int_base);
+ primitive_etex("tracingscantokens", assign_int_cmd,
+ int_base + tracing_scan_tokens_code, int_base);
+ primitive_etex("tracingnesting", assign_int_cmd,
+ int_base + tracing_nesting_code, int_base);
+ primitive_etex("predisplaydirection", assign_int_cmd,
+ int_base + pre_display_direction_code, int_base);
+ primitive_etex("lastlinefit", assign_int_cmd, int_base + last_line_fit_code,
+ int_base);
+ primitive_etex("savingvdiscards", assign_int_cmd,
+ int_base + saving_vdiscards_code, int_base);
+ primitive_etex("savinghyphcodes", assign_int_cmd,
+ int_base + saving_hyph_codes_code, int_base);
+ primitive_luatex("suppressfontnotfounderror", assign_int_cmd,
+ int_base + suppress_fontnotfound_error_code, int_base);
+ primitive_luatex("suppresslongerror", assign_int_cmd,
+ int_base + suppress_long_error_code, int_base);
+ primitive_luatex("suppressifcsnameerror", assign_int_cmd,
+ int_base + suppress_ifcsname_error_code, int_base);
+ primitive_luatex("suppressoutererror", assign_int_cmd,
+ int_base + suppress_outer_error_code, int_base);
+ primitive_luatex("synctex", assign_int_cmd, int_base + synctex_code,
+ int_base);
+
+ primitive_etex("currentgrouplevel", last_item_cmd, current_group_level_code,
+ 0);
+ primitive_etex("currentgrouptype", last_item_cmd, current_group_type_code,
+ 0);
+
+ primitive_etex("currentiflevel", last_item_cmd, current_if_level_code, 0);
+ primitive_etex("currentiftype", last_item_cmd, current_if_type_code, 0);
+ primitive_etex("currentifbranch", last_item_cmd, current_if_branch_code, 0);
+
+ primitive_omega("charwd", last_item_cmd, font_char_wd_code, 0);
+ primitive_etex("fontcharwd", last_item_cmd, font_char_wd_code, 0);
+ primitive_omega("charht", last_item_cmd, font_char_ht_code, 0);
+ primitive_etex("fontcharht", last_item_cmd, font_char_ht_code, 0);
+ primitive_omega("chardp", last_item_cmd, font_char_dp_code, 0);
+ primitive_etex("fontchardp", last_item_cmd, font_char_dp_code, 0);
+ primitive_omega("charit", last_item_cmd, font_char_ic_code, 0);
+ primitive_etex("fontcharic", last_item_cmd, font_char_ic_code, 0);
+
+ primitive_etex("parshapelength", last_item_cmd, par_shape_length_code, 0);
+ primitive_etex("parshapeindent", last_item_cmd, par_shape_indent_code, 0);
+ primitive_etex("parshapedimen", last_item_cmd, par_shape_dimen_code, 0);
+
+ primitive_etex("showgroups", xray_cmd, show_groups, 0);
+ /* The \.{\\showtokens} command displays a token list. */
+ primitive_etex("showtokens", xray_cmd, show_tokens, 0);
+ /*
+ 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
+ character tokens much as if the token list were written to a file. We
+ use the fact that the command modifiers for \.{\\unexpanded} and
+ \.{\\detokenize} are odd whereas those for \.{\\the} and \.{\\showthe}
+ are even.
+ */
+ primitive_etex("unexpanded", the_cmd, 1, 0);
+ primitive_etex("detokenize", the_cmd, show_tokens, 0);
+
+ /* The \.{\\showifs} command displays all currently active conditionals. */
+
+ primitive_etex("showifs", xray_cmd, show_ifs, 0);
+
+ /* The \.{\\interactionmode} primitive allows to query and set the interaction mode. */
+
+ primitive_etex("interactionmode", set_page_int_cmd, 2, 0);
+
+ /* The |scan_tokens| feature of \eTeX\ defines the \.{\\scantokens} primitive. */
+
+ primitive_etex("scantokens", input_cmd, 2, 0);
+ primitive_luatex("scantextokens", input_cmd, 3, 0);
+
+ primitive_etex("readline", read_to_cs_cmd, 1, 0);
+
+ primitive_etex("unless", expand_after_cmd, 1, 0);
+ primitive_etex("ifdefined", if_test_cmd, if_def_code, 0);
+ primitive_etex("ifcsname", if_test_cmd, if_cs_code, 0);
+ primitive_etex("iffontchar", if_test_cmd, if_font_char_code, 0);
+ primitive_pdftex("ifincsname", if_test_cmd, if_in_csname_code, 0);
+ primitive_luatex("ifabsnum", if_test_cmd, if_abs_num_code, 0);
+ primitive_luatex("ifabsdim", if_test_cmd, if_abs_dim_code, 0);
+ primitive_pdftex("ifpdfabsnum", if_test_cmd, if_abs_num_code, 0);
+ primitive_pdftex("ifpdfabsdim", if_test_cmd, if_abs_dim_code, 0);
+
+ /* The |protected| feature of \eTeX\ defines the \.{\\protected} prefix
+ command for macro definitions. Such macros are protected against
+ expansions when lists of expanded tokens are built, e.g., for \.{\\edef}
+ or during \.{\\write}. */
+
+ primitive_etex("protected", prefix_cmd, 8, 0);
+
+ /* Here are the additional \eTeX\ primitives for expressions. */
+
+ primitive_etex("numexpr", last_item_cmd,
+ eTeX_expr - int_val_level + int_val_level, 0);
+ primitive_etex("dimexpr", last_item_cmd,
+ eTeX_expr - int_val_level + dimen_val_level, 0);
+ primitive_etex("glueexpr", last_item_cmd,
+ eTeX_expr - int_val_level + glue_val_level, 0);
+ primitive_etex("muexpr", last_item_cmd,
+ eTeX_expr - int_val_level + mu_val_level, 0);
+
+ primitive_etex("gluestretchorder", last_item_cmd, glue_stretch_order_code,
+ 0);
+ primitive_etex("glueshrinkorder", last_item_cmd, glue_shrink_order_code, 0);
+ primitive_etex("gluestretch", last_item_cmd, glue_stretch_code, 0);
+ primitive_etex("glueshrink", last_item_cmd, glue_shrink_code, 0);
+
+ primitive_etex("mutoglue", last_item_cmd, mu_to_glue_code, 0);
+ primitive_etex("gluetomu", last_item_cmd, glue_to_mu_code, 0);
+
+ /* The \.{\\pagediscards} and \.{\\splitdiscards} commands share the
+ command code |un_vbox| with \.{\\unvbox} and \.{\\unvcopy}, they are
+ distinguished by their |chr_code| values |last_box_code| and
+ |vsplit_code|. These |chr_code| values are larger than |box_code| and
+ |copy_code|. */
+
+ primitive_etex("pagediscards", un_vbox_cmd, last_box_code, 0);
+ primitive_etex("splitdiscards", un_vbox_cmd, vsplit_code, 0);
+
+ /* The \.{\\interlinepenalties}, \.{\\clubpenalties}, \.{\\widowpenalties},
+ and \.{\\displaywidowpenalties} commands allow to define arrays of
+ penalty values to be used instead of the corresponding single values. */
+ primitive_etex("interlinepenalties", set_etex_shape_cmd,
+ inter_line_penalties_loc, etex_pen_base);
+ primitive_etex("clubpenalties", set_etex_shape_cmd, club_penalties_loc,
+ etex_pen_base);
+ primitive_etex("widowpenalties", set_etex_shape_cmd, widow_penalties_loc,
+ etex_pen_base);
+ primitive_etex("displaywidowpenalties", set_etex_shape_cmd,
+ display_widow_penalties_loc, etex_pen_base);
+
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.h b/Build/source/texk/web2c/luatexdir/tex/conditional.h
new file mode 100644
index 00000000000..23c79a03d3a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/conditional.h
@@ -0,0 +1,82 @@
+/* conditional.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: conditional.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef CONDITIONAL_H
+# define CONDITIONAL_H
+
+
+# define unless_code 32 /* amount added for `\.{\\unless}' prefix */
+
+typedef enum {
+ if_char_code = 0, /* `\.{\\if}' */
+ if_cat_code = 1, /* `\.{\\ifcat}' */
+ if_int_code = 2, /* `\.{\\ifnum}' */
+ if_dim_code = 3, /* `\.{\\ifdim}' */
+ if_odd_code = 4, /* `\.{\\ifodd}' */
+ if_vmode_code = 5, /* `\.{\\ifvmode}' */
+ if_hmode_code = 6, /* `\.{\\ifhmode}' */
+ if_mmode_code = 7, /* `\.{\\ifmmode}' */
+ if_inner_code = 8, /* `\.{\\ifinner}' */
+ if_void_code = 9, /* `\.{\\ifvoid}' */
+ if_hbox_code = 10, /* `\.{\\ifhbox}' */
+ if_vbox_code = 11, /* `\.{\\ifvbox}' */
+ ifx_code = 12, /* `\.{\\ifx}' */
+ if_eof_code = 13, /* `\.{\\ifeof}' */
+ if_true_code = 14, /* `\.{\\iftrue}' */
+ if_false_code = 15, /* `\.{\\iffalse}' */
+ if_case_code = 16, /* `\.{\\ifcase}' */
+ if_def_code = 17, /* `\.{\\ifdefined}' */
+ if_cs_code = 18, /* `\.{\\ifcsname}' */
+ if_font_char_code = 19, /* `\.{\\iffontchar}' */
+ if_in_csname_code = 20, /* `\.{\\ifincsname}' */
+ if_primitive_code = 21, /* `\.{\\ifprimitive}' */
+ if_abs_num_code = 22, /* `\.{\\ifabsnum}' */
+ if_abs_dim_code = 23, /* `\.{\\ifabsdim}' */
+} if_type_codes;
+
+
+
+
+# define if_limit_subtype(A) subtype((A)+1)
+# define if_limit_type(A) type((A)+1)
+# define if_line_field(A) vlink((A)+1)
+
+typedef enum {
+ if_code = 1, /* code for \.{\\if...} being evaluated */
+ fi_code = 2, /* code for \.{\\fi} */
+ else_code = 3, /* code for \.{\\else} */
+ or_code = 4, /* code for \.{\\or} */
+} else_type_codes;
+
+extern halfword cond_ptr; /* top of the condition stack */
+extern int if_limit; /* upper bound on |fi_or_else| codes */
+extern int cur_if; /* type of conditional being worked on */
+extern int if_line; /* line where that conditional began */
+extern int skip_line; /* skipping began here */
+
+extern void pass_text(void);
+extern void push_condition_stack(void);
+extern void pop_condition_stack(void);
+extern void change_if_limit(int l, halfword p);
+
+extern void conditional(void);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.w b/Build/source/texk/web2c/luatexdir/tex/conditional.w
new file mode 100644
index 00000000000..dd9349ab5ef
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/conditional.w
@@ -0,0 +1,539 @@
+% conditional.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: conditional.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/conditional.w $";
+
+@ @c
+#define box(A) eqtb[box_base+(A)].hh.rh
+
+@* We consider now the way \TeX\ handles various kinds of \.{\\if} commands.
+
+@ Conditions can be inside conditions, and this nesting has a stack
+that is independent of the |save_stack|.
+
+Four global variables represent the top of the condition stack:
+|cond_ptr| points to pushed-down entries, if any; |if_limit| specifies
+the largest code of a |fi_or_else| command that is syntactically legal;
+|cur_if| is the name of the current type of conditional; and |if_line|
+is the line number at which it began.
+
+If no conditions are currently in progress, the condition stack has the
+special state |cond_ptr=null|, |if_limit=normal|, |cur_if=0|, |if_line=0|.
+Otherwise |cond_ptr| points to a two-word node; the |type|, |subtype|, and
+|link| fields of the first word contain |if_limit|, |cur_if|, and
+|cond_ptr| at the next level, and the second word contains the
+corresponding |if_line|.
+
+@c
+halfword cond_ptr; /* top of the condition stack */
+int if_limit; /* upper bound on |fi_or_else| codes */
+int cur_if; /* type of conditional being worked on */
+int if_line; /* line where that conditional began */
+
+
+@ When we skip conditional text, we keep track of the line number
+where skipping began, for use in error messages.
+
+@c
+int skip_line; /* skipping began here */
+
+
+@ Here is a procedure that ignores text until coming to an \.{\\or},
+\.{\\else}, or \.{\\fi} at level zero of $\.{\\if}\ldots\.{\\fi}$
+nesting. After it has acted, |cur_chr| will indicate the token that
+was found, but |cur_tok| will not be set (because this makes the
+procedure run faster).
+
+@c
+void pass_text(void)
+{
+ int l; /* level of $\.{\\if}\ldots\.{\\fi}$ nesting */
+ int save_scanner_status; /* |scanner_status| upon entry */
+ save_scanner_status = scanner_status;
+ scanner_status = skipping;
+ l = 0;
+ skip_line = line;
+ while (1) {
+ get_token_lua();
+ if (cur_cmd == fi_or_else_cmd) {
+ if (l == 0)
+ break;
+ if (cur_chr == fi_code)
+ decr(l);
+ } else if (cur_cmd == if_test_cmd) {
+ incr(l);
+ }
+ }
+ scanner_status = save_scanner_status;
+ if (int_par(tracing_ifs_code) > 0)
+ show_cur_cmd_chr();
+}
+
+
+@ When we begin to process a new \.{\\if}, we set |if_limit:=if_code|; then
+if\/ \.{\\or} or \.{\\else} or \.{\\fi} occurs before the current \.{\\if}
+condition has been evaluated, \.{\\relax} will be inserted.
+For example, a sequence of commands like `\.{\\ifvoid1\\else...\\fi}'
+would otherwise require something after the `\.1'.
+
+@c
+void push_condition_stack(void)
+{
+ halfword p = new_node(if_node, 0);
+ vlink(p) = cond_ptr;
+ if_limit_type(p) = (quarterword) if_limit;
+ if_limit_subtype(p) = (quarterword) cur_if;
+ if_line_field(p) = if_line;
+ cond_ptr = p;
+ cur_if = cur_chr;
+ if_limit = if_code;
+ if_line = line;
+}
+
+void pop_condition_stack(void)
+{
+ halfword p;
+ if (if_stack[in_open] == cond_ptr)
+ if_warning();
+ /* conditionals possibly not properly nested with files */
+ p = cond_ptr;
+ if_line = if_line_field(p);
+ cur_if = if_limit_subtype(p);
+ if_limit = if_limit_type(p);
+ cond_ptr = vlink(p);
+ flush_node(p);
+}
+
+
+@ Here's a procedure that changes the |if_limit| code corresponding to
+a given value of |cond_ptr|.
+
+@c
+void change_if_limit(int l, halfword p)
+{
+ halfword q;
+ if (p == cond_ptr) {
+ if_limit = l; /* that's the easy case */
+ } else {
+ q = cond_ptr;
+ while (1) {
+ if (q == null)
+ confusion("if");
+ if (vlink(q) == p) {
+ if_limit_type(q) = (quarterword) l;
+ return;
+ }
+ q = vlink(q);
+ }
+ }
+}
+
+
+@ The conditional \.{\\ifcsname} is equivalent to \.{\\expandafter}
+\.{\\expandafter} \.{\\ifdefined} \.{\\csname}, except that no new
+control sequence will be entered into the hash table (once all tokens
+preceding the mandatory \.{\\endcsname} have been expanded).
+
+@c
+static boolean test_for_cs(void)
+{
+ boolean b; /*is the condition true? */
+ int m, s; /*to be tested against the second operand */
+ halfword n, p, q; /*for traversing token lists in \.{\\ifx} tests */
+ n = get_avail();
+ p = n; /*head of the list of characters */
+ b = false;
+ while (1) {
+ get_x_token();
+ if (cur_cs != 0)
+ break;
+ store_new_token(cur_tok);
+ }
+ if (cur_cmd != end_cs_name_cmd) {
+ if (int_par(suppress_ifcsname_error_code)) {
+ do {
+ get_x_token();
+ } while (cur_cmd != end_cs_name_cmd);
+ flush_list(n);
+ return b;
+ } else {
+ complain_missing_csname();
+ }
+ }
+ /* Look up the characters of list |n| in the hash table, and set |cur_cs| */
+ m = first;
+ p = token_link(n);
+ while (p != null) {
+ if (m >= max_buf_stack) {
+ max_buf_stack = m + 4;
+ if (max_buf_stack == buf_size)
+ check_buffer_overflow(max_buf_stack);
+ }
+ s = token_chr(token_info(p));
+ if (s <= 0x7F) {
+ buffer[m++] = (packed_ASCII_code) s;
+ } else if (s <= 0x7FF) {
+ buffer[m++] = (packed_ASCII_code) (0xC0 + s / 0x40);
+ buffer[m++] = (packed_ASCII_code) (0x80 + s % 0x40);
+ } else if (s <= 0xFFFF) {
+ buffer[m++] = (packed_ASCII_code) (0xE0 + s / 0x1000);
+ buffer[m++] = (packed_ASCII_code) (0x80 + (s % 0x1000) / 0x40);
+ buffer[m++] = (packed_ASCII_code) (0x80 + (s % 0x1000) % 0x40);
+ } else {
+ buffer[m++] = (packed_ASCII_code) (0xF0 + s / 0x40000);
+ buffer[m++] = (packed_ASCII_code) (0x80 + (s % 0x40000) / 0x1000);
+ buffer[m++] =
+ (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) / 0x40);
+ buffer[m++] =
+ (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) % 0x40);
+ }
+ p = token_link(p);
+ }
+ if (m > first) {
+ cur_cs = id_lookup(first, m - first); /*|no_new_control_sequence| is |true| */
+ } else if (m == first) {
+ cur_cs = null_cs; /*the list is empty */
+ }
+ b = (eq_type(cur_cs) != undefined_cs_cmd);
+ flush_list(n);
+ return b;
+}
+
+
+@ An active character will be treated as category 13 following
+\.{\\if\\noexpand} or following \.{\\ifcat\\noexpand}.
+
+@c
+#define get_x_token_or_active_char() do { \
+ get_x_token(); \
+ if (cur_cmd==relax_cmd && cur_chr==no_expand_flag) { \
+ if (is_active_cs(cs_text(cur_cs))) { \
+ cur_cmd=active_char_cmd; \
+ cur_chr=active_cs_value(cs_text(cur_tok-cs_token_flag)); \
+ } \
+ } \
+ } while (0)
+
+
+
+
+
+@ A condition is started when the |expand| procedure encounters
+an |if_test| command; in that case |expand| reduces to |conditional|,
+which is a recursive procedure.
+@^recursion@>
+
+@c
+void conditional(void)
+{
+ boolean b; /*is the condition true? */
+ int r; /*relation to be evaluated */
+ int m, n; /*to be tested against the second operand */
+ halfword p, q; /*for traversing token lists in \.{\\ifx} tests */
+ int save_scanner_status; /*|scanner_status| upon entry */
+ halfword save_cond_ptr; /*|cond_ptr| corresponding to this conditional */
+ int this_if; /*type of this conditional */
+ boolean is_unless; /*was this if preceded by `\.{\\unless}' ? */
+ b = false; /*default is false, just in case */
+ if (int_par(tracing_ifs_code) > 0)
+ if (int_par(tracing_commands_code) <= 1)
+ show_cur_cmd_chr();
+ push_condition_stack();
+ save_cond_ptr = cond_ptr;
+ is_unless = (cur_chr >= unless_code);
+ this_if = cur_chr % unless_code;
+ /* Either process \.{\\ifcase} or set |b| to the value of a boolean condition */
+ switch (this_if) {
+ case if_char_code:
+ case if_cat_code:
+ /* Test if two characters match */
+ get_x_token_or_active_char();
+ if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) { /*not a character */
+ m = relax_cmd;
+ n = too_big_char;
+ } else {
+ m = cur_cmd;
+ n = cur_chr;
+ }
+ get_x_token_or_active_char();
+ if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) {
+ cur_cmd = relax_cmd;
+ cur_chr = too_big_char;
+ }
+ if (this_if == if_char_code)
+ b = (n == cur_chr);
+ else
+ b = (m == cur_cmd);
+ break;
+ case if_int_code:
+ case if_dim_code:
+ case if_abs_dim_code:
+ case if_abs_num_code:
+ /* Test relation between integers or dimensions */
+ /* Here we use the fact that |"<"|, |"="|, and |">"| are consecutive ASCII
+ codes. */
+ if (this_if == if_int_code || this_if == if_abs_num_code)
+ scan_int();
+ else
+ scan_normal_dimen();
+ n = cur_val;
+ if (n < 0)
+ if (this_if == if_abs_dim_code || this_if == if_abs_num_code)
+ negate(n);
+
+ /* Get the next non-blank non-call... */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>')) {
+ r = cur_tok - other_token;
+ } else {
+ print_err("Missing = inserted for ");
+ print_cmd_chr(if_test_cmd, this_if);
+ help1("I was expecting to see `<', `=', or `>'. Didn't.");
+ back_error();
+ r = '=';
+ }
+ if (this_if == if_int_code || this_if == if_abs_num_code)
+ scan_int();
+ else
+ scan_normal_dimen();
+
+ if (cur_val < 0)
+ if (this_if == if_abs_dim_code || this_if == if_abs_num_code)
+ negate(cur_val);
+
+ switch (r) {
+ case '<':
+ b = (n < cur_val);
+ break;
+ case '=':
+ b = (n == cur_val);
+ break;
+ case '>':
+ b = (n > cur_val);
+ break;
+ default:
+ b = false;
+ break; /*can't happen */
+ }
+ break;
+ case if_odd_code:
+ /* Test if an integer is odd */
+ scan_int();
+ b = odd(cur_val);
+ break;
+ case if_vmode_code:
+ b = (abs(cur_list.mode_field) == vmode);
+ break;
+ case if_hmode_code:
+ b = (abs(cur_list.mode_field) == hmode);
+ break;
+ case if_mmode_code:
+ b = (abs(cur_list.mode_field) == mmode);
+ break;
+ case if_inner_code:
+ b = (cur_list.mode_field < 0);
+ break;
+ case if_void_code:
+ case if_hbox_code:
+ case if_vbox_code:
+ /* Test box register status */
+ scan_register_num();
+ p = box(cur_val);
+ if (this_if == if_void_code)
+ b = (p == null);
+ else if (p == null)
+ b = false;
+ else if (this_if == if_hbox_code)
+ b = (type(p) == hlist_node);
+ else
+ b = (type(p) == vlist_node);
+ break;
+ case ifx_code:
+ /* Test if two tokens match */
+ /* Note that `\.{\\ifx}' will declare two macros different if one is \\{long}
+ or \\{outer} and the other isn't, even though the texts of the macros are
+ the same.
+
+ We need to reset |scanner_status|, since \.{\\outer} control sequences
+ are allowed, but we might be scanning a macro definition or preamble.
+ */
+ save_scanner_status = scanner_status;
+ scanner_status = normal;
+ get_token_lua();
+ n = cur_cs;
+ p = cur_cmd;
+ q = cur_chr;
+ get_token_lua();
+ if (cur_cmd != p) {
+ b = false;
+ } else if (cur_cmd < call_cmd) {
+ b = (cur_chr == q);
+ } else {
+ /* Test if two macro texts match */
+ /* Note also that `\.{\\ifx}' decides that macros \.{\\a} and \.{\\b} are
+ different in examples like this:
+ $$\vbox{\halign{\.{#}\hfil&\qquad\.{#}\hfil\cr
+ {}\\def\\a\{\\c\}&
+ {}\\def\\c\{\}\cr
+ {}\\def\\b\{\\d\}&
+ {}\\def\\d\{\}\cr}}$$ */
+ p = token_link(cur_chr);
+ q = token_link(equiv(n)); /*omit reference counts */
+ if (p == q) {
+ b = true;
+ } else {
+ while ((p != null) && (q != null)) {
+ if (token_info(p) != token_info(q)) {
+ p = null;
+ } else {
+ p = token_link(p);
+ q = token_link(q);
+ }
+ }
+ b = ((p == null) && (q == null));
+ }
+ }
+ scanner_status = save_scanner_status;
+ break;
+ case if_eof_code:
+ scan_four_bit_int_or_18();
+ if (cur_val == 18)
+ b = !shellenabledp;
+ else
+ b = (read_open[cur_val] == closed);
+ break;
+ case if_true_code:
+ b = true;
+ break;
+ case if_false_code:
+ b = false;
+ break;
+ case if_case_code:
+ /* Select the appropriate case
+ and |return| or |goto common_ending| */
+ scan_int();
+ n = cur_val; /*|n| is the number of cases to pass */
+ if (int_par(tracing_commands_code) > 1) {
+ begin_diagnostic();
+ tprint("{case ");
+ print_int(n);
+ print_char('}');
+ end_diagnostic(false);
+ }
+ while (n != 0) {
+ pass_text();
+ if (cond_ptr == save_cond_ptr) {
+ if (cur_chr == or_code)
+ decr(n);
+ else
+ goto COMMON_ENDING;
+ } else if (cur_chr == fi_code) {
+ pop_condition_stack();
+ }
+ }
+ change_if_limit(or_code, save_cond_ptr);
+ return; /*wait for \.{\\or}, \.{\\else}, or \.{\\fi} */
+ break;
+ case if_primitive_code:
+ save_scanner_status = scanner_status;
+ scanner_status = normal;
+ get_token_lua();
+ scanner_status = save_scanner_status;
+ m = prim_lookup(cs_text(cur_cs));
+ b = ((cur_cmd != undefined_cs_cmd) &&
+ (m != undefined_primitive) &&
+ (cur_cmd == get_prim_eq_type(m)) &&
+ (cur_chr == get_prim_equiv(m)));
+ break;
+ case if_def_code:
+ /* The conditional \.{\\ifdefined} tests if a control sequence is defined. */
+ /* We need to reset |scanner_status|, since \.{\\outer} control sequences
+ are allowed, but we might be scanning a macro definition or preamble. */
+ save_scanner_status = scanner_status;
+ scanner_status = normal;
+ get_token_lua();
+ b = (cur_cmd != undefined_cs_cmd);
+ scanner_status = save_scanner_status;
+ break;
+ case if_cs_code:
+ b = test_for_cs();
+ break;
+ case if_in_csname_code:
+ b = is_in_csname;
+ break;
+ case if_font_char_code:
+ /* The conditional \.{\\iffontchar} tests the existence of a character in
+ a font. */
+ scan_font_ident();
+ n = cur_val;
+ scan_char_num();
+ b = char_exists(n, cur_val);
+ break;
+ default: /* there are no other cases, but for -Wall: */
+ b = false;
+ }
+
+ if (is_unless)
+ b = !b;
+ if (int_par(tracing_commands_code) > 1) {
+ /* Display the value of |b| */
+ begin_diagnostic();
+ if (b)
+ tprint("{true}");
+ else
+ tprint("{false}");
+ end_diagnostic(false);
+ }
+ if (b) {
+ change_if_limit(else_code, save_cond_ptr);
+ return; /*wait for \.{\\else} or \.{\\fi} */
+ }
+ /* Skip to \.{\\else} or \.{\\fi}, then |goto common_ending| */
+ /*
+ In a construction like `\.{\\if\\iftrue abc\\else d\\fi}', the first
+ \.{\\else} that we come to after learning that the \.{\\if} is false is
+ not the \.{\\else} we're looking for. Hence the following curious
+ logic is needed.
+ */
+ while (1) {
+ pass_text();
+ if (cond_ptr == save_cond_ptr) {
+ if (cur_chr != or_code)
+ goto COMMON_ENDING;
+ print_err("Extra \\or");
+ help1("I'm ignoring this; it doesn't match any \\if.");
+ error();
+ } else if (cur_chr == fi_code) {
+ pop_condition_stack();
+ }
+ }
+ COMMON_ENDING:
+ if (cur_chr == fi_code)
+ pop_condition_stack();
+ else
+ if_limit = fi_code; /*wait for \.{\\fi} */
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.h b/Build/source/texk/web2c/luatexdir/tex/directions.h
new file mode 100644
index 00000000000..bea50879b64
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/directions.h
@@ -0,0 +1,347 @@
+/* directions.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: directions.h 3523 2010-03-19 13:28:08Z taco $ */
+
+#ifndef DIRECTIONS_H
+# define DIRECTIONS_H
+
+# define dir_T 0
+# define dir_L 1
+# define dir_B 2
+# define dir_R 3
+
+# define dir_TLT 0
+# define dir_TRT 4
+# define dir_LTL 9
+# define dir_RTT 24
+
+
+/* # define dir_array_size 25 */ /* |dir_RTT + 1| */
+
+/* inv(primary) == tertiary */
+/*
+boolean _is_mirrored[dir_array_size];
+_is_mirrored[dir_TLT] = 0;
+_is_mirrored[dir_TRT] = 0;
+_is_mirrored[dir_LTL] = 0;
+_is_mirrored[dir_RTT] = 0;
+*/
+
+#define is_mirrored(a) 0
+
+/* secondary == tertiary */
+/*
+boolean _is_rotated[dir_array_size];
+_is_rotated[dir_TLT] = 0;
+_is_rotated[dir_TRT] = 0;
+_is_rotated[dir_LTL] = 0;
+_is_rotated[dir_RTT] = 1;
+*/
+
+#define is_rotated(a) (a == dir_RTT)
+
+/* secondary == secondary */
+/*
+boolean _textdir_parallel[dir_array_size][dir_array_size];
+_textdir_parallel[dir_TLT][dir_TLT] = 1;
+_textdir_parallel[dir_TLT][dir_TRT] = 1;
+_textdir_parallel[dir_TLT][dir_LTL] = 0;
+_textdir_parallel[dir_TLT][dir_RTT] = 0;
+_textdir_parallel[dir_TRT][dir_TLT] = 1;
+_textdir_parallel[dir_TRT][dir_TRT] = 1;
+_textdir_parallel[dir_TRT][dir_LTL] = 0;
+_textdir_parallel[dir_TRT][dir_RTT] = 0;
+_textdir_parallel[dir_LTL][dir_TLT] = 0;
+_textdir_parallel[dir_LTL][dir_TRT] = 0;
+_textdir_parallel[dir_LTL][dir_LTL] = 1;
+_textdir_parallel[dir_LTL][dir_RTT] = 1;
+_textdir_parallel[dir_RTT][dir_TLT] = 0;
+_textdir_parallel[dir_RTT][dir_TRT] = 0;
+_textdir_parallel[dir_RTT][dir_LTL] = 1;
+_textdir_parallel[dir_RTT][dir_RTT] = 1;
+*/
+
+#define textdir_parallel(a,b) (((a == dir_TLT || a == dir_TRT)&&(b == dir_TLT || b == dir_TRT)) || \
+ ((a == dir_LTL || a == dir_RTT)&&(b == dir_LTL || b == dir_RTT)))
+
+
+/* primary == primary */
+/*
+boolean _pardir_parallel[dir_array_size][dir_array_size];
+_pardir_parallel[dir_TLT][dir_TLT] = 1;
+_pardir_parallel[dir_TLT][dir_TRT] = 1;
+_pardir_parallel[dir_TLT][dir_LTL] = 0;
+_pardir_parallel[dir_TLT][dir_RTT] = 0;
+_pardir_parallel[dir_TRT][dir_TLT] = 1;
+_pardir_parallel[dir_TRT][dir_TRT] = 1;
+_pardir_parallel[dir_TRT][dir_LTL] = 0;
+_pardir_parallel[dir_TRT][dir_RTT] = 0;
+_pardir_parallel[dir_LTL][dir_TLT] = 0;
+_pardir_parallel[dir_LTL][dir_TRT] = 0;
+_pardir_parallel[dir_LTL][dir_LTL] = 1;
+_pardir_parallel[dir_LTL][dir_RTT] = 1;
+_pardir_parallel[dir_RTT][dir_TLT] = 0;
+_pardir_parallel[dir_RTT][dir_TRT] = 0;
+_pardir_parallel[dir_RTT][dir_LTL] = 1;
+_pardir_parallel[dir_RTT][dir_RTT] = 1;
+*/
+
+
+#define pardir_parallel(a,b) (((a == dir_TLT || a == dir_TRT)&&(b == dir_TLT || b == dir_TRT)) || \
+ ((a == dir_LTL || a == dir_RTT)&&(b == dir_LTL || b == dir_RTT)))
+
+
+/* inv(primary) == primary */
+/*
+boolean _pardir_opposite[dir_array_size][dir_array_size];
+_pardir_opposite[dir_TLT][dir_TLT] = 0;
+_pardir_opposite[dir_TLT][dir_TRT] = 0;
+_pardir_opposite[dir_TLT][dir_LTL] = 0;
+_pardir_opposite[dir_TLT][dir_RTT] = 0;
+_pardir_opposite[dir_TRT][dir_TLT] = 0;
+_pardir_opposite[dir_TRT][dir_TRT] = 0;
+_pardir_opposite[dir_TRT][dir_LTL] = 0;
+_pardir_opposite[dir_TRT][dir_RTT] = 0;
+_pardir_opposite[dir_LTL][dir_TLT] = 0;
+_pardir_opposite[dir_LTL][dir_TRT] = 0;
+_pardir_opposite[dir_LTL][dir_LTL] = 0;
+_pardir_opposite[dir_LTL][dir_RTT] = 1;
+_pardir_opposite[dir_RTT][dir_TLT] = 0;
+_pardir_opposite[dir_RTT][dir_TRT] = 0;
+_pardir_opposite[dir_RTT][dir_LTL] = 1;
+_pardir_opposite[dir_RTT][dir_RTT] = 0;
+*/
+
+#define pardir_opposite(a,b) ((a == dir_LTL && b == dir_RTT)||(a == dir_RTT && b == dir_LTL))
+
+
+/* inv(secondary) == secondary */
+/*
+boolean _textdir_opposite[dir_array_size][dir_array_size];
+_textdir_opposite[dir_TLT][dir_TLT] = 0;
+_textdir_opposite[dir_TLT][dir_TRT] = 1;
+_textdir_opposite[dir_TLT][dir_LTL] = 0;
+_textdir_opposite[dir_TLT][dir_RTT] = 0;
+_textdir_opposite[dir_TRT][dir_TLT] = 1;
+_textdir_opposite[dir_TRT][dir_TRT] = 0;
+_textdir_opposite[dir_TRT][dir_LTL] = 0;
+_textdir_opposite[dir_TRT][dir_RTT] = 0;
+_textdir_opposite[dir_LTL][dir_TLT] = 0;
+_textdir_opposite[dir_LTL][dir_TRT] = 0;
+_textdir_opposite[dir_LTL][dir_LTL] = 0;
+_textdir_opposite[dir_LTL][dir_RTT] = 0;
+_textdir_opposite[dir_RTT][dir_TLT] = 0;
+_textdir_opposite[dir_RTT][dir_TRT] = 0;
+_textdir_opposite[dir_RTT][dir_LTL] = 0;
+_textdir_opposite[dir_RTT][dir_RTT] = 0;
+*/
+
+#define textdir_opposite(a,b) ((a == dir_TLT && b == dir_TRT)||(a == dir_TRT && b == dir_TLT))
+
+
+/* inv(tertiary) == tertiary */
+/*
+boolean _glyphdir_opposite[dir_array_size][dir_array_size];
+_glyphdir_opposite[dir_TLT][dir_TLT] = 0;
+_glyphdir_opposite[dir_TLT][dir_TRT] = 0;
+_glyphdir_opposite[dir_TLT][dir_LTL] = 0;
+_glyphdir_opposite[dir_TLT][dir_RTT] = 0;
+_glyphdir_opposite[dir_TRT][dir_TLT] = 0;
+_glyphdir_opposite[dir_TRT][dir_TRT] = 0;
+_glyphdir_opposite[dir_TRT][dir_LTL] = 0;
+_glyphdir_opposite[dir_TRT][dir_RTT] = 0;
+_glyphdir_opposite[dir_LTL][dir_TLT] = 0;
+_glyphdir_opposite[dir_LTL][dir_TRT] = 0;
+_glyphdir_opposite[dir_LTL][dir_LTL] = 0;
+_glyphdir_opposite[dir_LTL][dir_RTT] = 0;
+_glyphdir_opposite[dir_RTT][dir_TLT] = 0;
+_glyphdir_opposite[dir_RTT][dir_TRT] = 0;
+_glyphdir_opposite[dir_RTT][dir_LTL] = 0;
+_glyphdir_opposite[dir_RTT][dir_RTT] = 0;
+*/
+
+#define glyphdir_opposite(a,b) 0
+
+
+/* primary == primary */
+/*
+boolean _pardir_eq[dir_array_size][dir_array_size];
+_pardir_eq[dir_TLT][dir_TLT] = 1;
+_pardir_eq[dir_TLT][dir_TRT] = 1;
+_pardir_eq[dir_TLT][dir_LTL] = 0;
+_pardir_eq[dir_TLT][dir_RTT] = 0;
+_pardir_eq[dir_TRT][dir_TLT] = 1;
+_pardir_eq[dir_TRT][dir_TRT] = 1;
+_pardir_eq[dir_TRT][dir_LTL] = 0;
+_pardir_eq[dir_TRT][dir_RTT] = 0;
+_pardir_eq[dir_LTL][dir_TLT] = 0;
+_pardir_eq[dir_LTL][dir_TRT] = 0;
+_pardir_eq[dir_LTL][dir_LTL] = 1;
+_pardir_eq[dir_LTL][dir_RTT] = 0;
+_pardir_eq[dir_RTT][dir_TLT] = 0;
+_pardir_eq[dir_RTT][dir_TRT] = 0;
+_pardir_eq[dir_RTT][dir_LTL] = 0;
+_pardir_eq[dir_RTT][dir_RTT] = 1;
+*/
+
+#define pardir_eq(a,b) (((a == dir_TLT || a == dir_TRT)&&(b == dir_TLT || b == dir_TRT))|| \
+ (a == dir_LTL && b == dir_LTL) || \
+ (a == dir_RTT && b == dir_RTT))
+
+/* secondary == secondary */
+/*
+boolean _textdir_eq[dir_array_size][dir_array_size];
+_textdir_eq[dir_TLT][dir_TLT] = 1;
+_textdir_eq[dir_TLT][dir_TRT] = 0;
+_textdir_eq[dir_TLT][dir_LTL] = 0;
+_textdir_eq[dir_TLT][dir_RTT] = 0;
+_textdir_eq[dir_TRT][dir_TLT] = 0;
+_textdir_eq[dir_TRT][dir_TRT] = 1;
+_textdir_eq[dir_TRT][dir_LTL] = 0;
+_textdir_eq[dir_TRT][dir_RTT] = 0;
+_textdir_eq[dir_LTL][dir_TLT] = 0;
+_textdir_eq[dir_LTL][dir_TRT] = 0;
+_textdir_eq[dir_LTL][dir_LTL] = 1;
+_textdir_eq[dir_LTL][dir_RTT] = 1;
+_textdir_eq[dir_RTT][dir_TLT] = 0;
+_textdir_eq[dir_RTT][dir_TRT] = 0;
+_textdir_eq[dir_RTT][dir_LTL] = 1;
+_textdir_eq[dir_RTT][dir_RTT] = 1;
+*/
+
+#define textdir_eq(a,b) ((a == dir_TLT && b == dir_TLT) || \
+ (a == dir_TRT && b == dir_TRT) || \
+ (a == dir_LTL && (b == dir_LTL || b == dir_RTT)) || \
+ (a == dir_RTT && (b == dir_LTL || b == dir_RTT))
+
+
+/* tertiary == tertiary */
+/*
+boolean _glyphdir_eq[dir_array_size][dir_array_size];
+_glyphdir_eq[dir_TLT][dir_TLT] = 1;
+_glyphdir_eq[dir_TLT][dir_TRT] = 1;
+_glyphdir_eq[dir_TLT][dir_LTL] = 0;
+_glyphdir_eq[dir_TLT][dir_RTT] = 1;
+_glyphdir_eq[dir_TRT][dir_TLT] = 1;
+_glyphdir_eq[dir_TRT][dir_TRT] = 1;
+_glyphdir_eq[dir_TRT][dir_LTL] = 0;
+_glyphdir_eq[dir_TRT][dir_RTT] = 1;
+_glyphdir_eq[dir_LTL][dir_TLT] = 0;
+_glyphdir_eq[dir_LTL][dir_TRT] = 0;
+_glyphdir_eq[dir_LTL][dir_LTL] = 1;
+_glyphdir_eq[dir_LTL][dir_RTT] = 0;
+_glyphdir_eq[dir_RTT][dir_TLT] = 1;
+_glyphdir_eq[dir_RTT][dir_TRT] = 1;
+_glyphdir_eq[dir_RTT][dir_LTL] = 0;
+_glyphdir_eq[dir_RTT][dir_RTT] = 1;
+*/
+
+#define glyphdir_eq(a,b) ((a != dir_LTL && b != dir_LTL) || \
+ (a == dir_LTL && b == dir_LTL))
+
+
+/* primary == secondary */
+/*
+boolean _partextdir_eq[dir_array_size][dir_array_size];
+_partextdir_eq[dir_TLT][dir_TLT] = 0;
+_partextdir_eq[dir_TLT][dir_TRT] = 0;
+_partextdir_eq[dir_TLT][dir_LTL] = 1;
+_partextdir_eq[dir_TLT][dir_RTT] = 1;
+_partextdir_eq[dir_TRT][dir_TLT] = 0;
+_partextdir_eq[dir_TRT][dir_TRT] = 0;
+_partextdir_eq[dir_TRT][dir_LTL] = 1;
+_partextdir_eq[dir_TRT][dir_RTT] = 1;
+_partextdir_eq[dir_LTL][dir_TLT] = 1;
+_partextdir_eq[dir_LTL][dir_TRT] = 0;
+_partextdir_eq[dir_LTL][dir_LTL] = 0;
+_partextdir_eq[dir_LTL][dir_RTT] = 0;
+_partextdir_eq[dir_RTT][dir_TLT] = 0;
+_partextdir_eq[dir_RTT][dir_TRT] = 1;
+_partextdir_eq[dir_RTT][dir_LTL] = 0;
+_partextdir_eq[dir_RTT][dir_RTT] = 0;
+*/
+
+#define partextdir_eq(a,b) (((a == dir_TLT || a == dir_TRT)&&(b == dir_LTL || b == dir_RTT)) || \
+ (a == dir_LTL && b == dir_TLT) || \
+ (a == dir_RTT && b == dir_TRT))
+
+
+/* secondary != tertiary */
+/*
+boolean _textglyphdir_orthogonal[dir_array_size]
+_textglyphdir_orthogonal[dir_TLT] = 1;
+_textglyphdir_orthogonal[dir_TRT] = 1;
+_textglyphdir_orthogonal[dir_LTL] = 1;
+_textglyphdir_orthogonal[dir_RTT] = 0;
+*/
+
+#define textglyphdir_orthogonal(a) (a != dir_RTT)
+
+/* secondary == L */
+/*
+boolean _textdir_is[dir_array_size];
+_textdir_is[dir_TLT] = 1;
+_textdir_is[dir_TRT] = 1;
+_textdir_is[dir_LTL] = 1;
+_textdir_is[dir_RTT] = 0;
+*/
+
+# define textdir_is_L(a) (a == dir_TLT)
+
+# define push_dir(a) \
+ { halfword dir_tmp=new_dir((a)); \
+ vlink(dir_tmp)=dir_ptr; \
+ dir_ptr=dir_tmp; \
+ }
+
+# define push_dir_node(a) \
+ { halfword dir_tmp=copy_node((a)); \
+ vlink(dir_tmp)=dir_ptr; \
+ dir_ptr=dir_tmp; \
+ }
+
+# define pop_dir_node() \
+ { halfword dir_tmp=dir_ptr; \
+ dir_ptr=vlink(dir_tmp); \
+ flush_node(dir_tmp); \
+ }
+
+extern halfword dir_ptr;
+
+extern halfword text_dir_ptr;
+
+extern void initialize_directions(void);
+extern halfword new_dir(int s);
+
+extern const char *string_dir(int d);
+extern void print_dir(int d);
+
+extern void scan_direction(void);
+
+extern halfword do_push_dir_node(halfword p, halfword a);
+extern halfword do_pop_dir_node(halfword p);
+
+scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph);
+scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p,
+ boolean isglyph);
+
+void update_text_dir_ptr(int val);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.w b/Build/source/texk/web2c/luatexdir/tex/directions.w
new file mode 100644
index 00000000000..4f896b60dbe
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/directions.w
@@ -0,0 +1,202 @@
+% directions.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: directions.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/directions.w $";
+
+@ @c
+void scan_direction(void)
+{
+ int save_cur_cmd = cur_cmd;
+ int save_cur_chr = cur_chr;
+ get_x_token();
+ if (cur_cmd == assign_dir_cmd) {
+ cur_val = eqtb[cur_chr].cint;
+ goto EXIT;
+ } else {
+ back_input();
+ }
+ if (scan_keyword("TLT")) {
+ cur_val = dir_TLT;
+ } else if (scan_keyword("TRT")) {
+ cur_val = dir_TRT;
+ } else if (scan_keyword("LTL")) {
+ cur_val = dir_LTL;
+ } else if (scan_keyword("RTT")) {
+ cur_val = dir_RTT;
+ } else {
+ tex_error("Bad direction", NULL);
+ cur_val = 0;
+ }
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ EXIT:
+ cur_cmd = save_cur_cmd;
+ cur_chr = save_cur_chr;
+}
+
+@ the next two are used by postlinebreak.c
+
+@c
+halfword do_push_dir_node(halfword p, halfword a)
+{
+ halfword n;
+ n = copy_node(a);
+ vlink(n) = p;
+ return n;
+}
+
+halfword do_pop_dir_node(halfword p)
+{
+ halfword n = vlink(p);
+ flush_node(p);
+ return n;
+}
+
+@ @c
+halfword dir_ptr;
+
+halfword text_dir_ptr;
+
+@ There is no need to do anything here at the moment.
+@c
+void initialize_directions(void)
+{
+}
+
+@ @c
+halfword new_dir(int s)
+{
+ halfword p; /* the new node */
+ p = new_node(whatsit_node, dir_node);
+ dir_dir(p) = s;
+ dir_dvi_ptr(p) = -1;
+ dir_level(p) = cur_level;
+ return p;
+}
+
+@ @c
+const char *string_dir(int d)
+{
+ if (d == dir_TLT) {
+ return "TLT";
+ } else if (d == dir_TRT) {
+ return "TRT";
+ } else if (d == dir_LTL) {
+ return "LTL";
+ } else if (d == dir_RTT) {
+ return "RTT";
+ } else {
+ return "???";
+ }
+}
+
+
+@ @c
+void print_dir(int d)
+{
+ tprint(string_dir(d));
+}
+
+@ @c
+scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph)
+{
+ scaled wd = 0;
+ if (isglyph) {
+ if (textdir_parallel(curdir, pdir) ==
+ textglyphdir_orthogonal(pdir))
+ wd = glyph_width(p);
+ else
+ wd = glyph_depth(p) + glyph_height(p);
+ } else { /* hlist, vlist, image, form, rule */
+ if (textdir_parallel(pdir, curdir))
+ wd = width(p);
+ else
+ wd = depth(p) + height(p);
+ }
+ return wd;
+}
+
+@ @c
+scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p,
+ boolean isglyph)
+{
+ scaled_whd whd = { 0, 0, 0 };
+ whd.wd = pack_width(curdir, pdir, p, isglyph);
+ if (isglyph) {
+ if (is_rotated(curdir)) {
+ if (textdir_parallel(curdir, pdir))
+ whd.ht = whd.dp = (glyph_height(p) + glyph_depth(p)) / 2;
+ else
+ whd.ht = whd.dp = glyph_width(p) / 2;
+ } else {
+ if (is_rotated(pdir)) {
+ if (textdir_parallel(curdir, pdir))
+ whd.ht = whd.dp = (glyph_height(p) + glyph_depth(p)) / 2;
+ else
+ whd.ht = glyph_width(p);
+ } else {
+ if (glyphdir_eq(curdir, pdir)) {
+ whd.ht = glyph_height(p);
+ whd.dp = glyph_depth(p);
+ } else if (glyphdir_opposite(curdir, pdir)) {
+ whd.ht = glyph_depth(p);
+ whd.dp = glyph_height(p);
+ } else
+ whd.ht = glyph_width(p);
+ }
+ }
+ } else {
+ if (is_rotated(curdir)) {
+ if (textdir_parallel(curdir, pdir))
+ whd.ht = whd.dp = (height(p) + depth(p)) / 2;
+ else
+ whd.ht = whd.dp = width(p) / 2;
+ } else {
+ if (pardir_eq(curdir, pdir)) {
+ whd.ht = height(p);
+ whd.dp = depth(p);
+ } else if (pardir_opposite(curdir, pdir)) {
+ whd.ht = depth(p);
+ whd.dp = height(p);
+ } else
+ whd.ht = width(p);
+ }
+ }
+ return whd;
+}
+
+@ @c
+void update_text_dir_ptr(int val)
+{
+ if (dir_level(text_dir_ptr) == cur_level) {
+ /* update */
+ dir_dir(text_dir_ptr) = val;
+ } else {
+ /* addition */
+ halfword text_dir_tmp = new_dir(val);
+ vlink(text_dir_tmp) = text_dir_ptr;
+ text_dir_ptr = text_dir_tmp;
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.h b/Build/source/texk/web2c/luatexdir/tex/dumpdata.h
new file mode 100644
index 00000000000..810424b6a40
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.h
@@ -0,0 +1,115 @@
+/* dumpdata.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: dumpdata.h 3388 2010-01-26 10:59:04Z taco $ */
+
+#ifndef DUMPDATA_H
+# define DUMPDATA_H
+
+extern str_number format_ident;
+extern str_number format_name; /* principal file name */
+extern FILE *fmt_file; /* for input or output of format information */
+
+extern void store_fmt_file(void);
+extern boolean load_fmt_file(const char *);
+
+/* (Un)dumping. These are called from the change file. */
+# define dump_things(base, len) \
+ do_zdump ((char *) &(base), sizeof (base), (int) (len), DUMP_FILE)
+# define undump_things(base, len) \
+ do_zundump ((char *) &(base), sizeof (base), (int) (len), DUMP_FILE)
+
+extern void do_zdump(char *, int, int, FILE *);
+extern void do_zundump(char *, int, int, FILE *);
+
+/* Like do_undump, but check each value against LOW and HIGH. The
+ slowdown isn't significant, and this improves the chances of
+ detecting incompatible format files. In fact, Knuth himself noted
+ this problem with Web2c some years ago, so it seems worth fixing. We
+ can't make this a subroutine because then we lose the type of BASE. */
+# define undump_checked_things(low, high, base, len) \
+ do { \
+ unsigned i; \
+ undump_things (base, len); \
+ for (i = 0; i < (len); i++) { \
+ if ((&(base))[i] < (low) || (&(base))[i] > (high)) { \
+ FATAL5 ("Item %u (=%ld) of .fmt array at %lx <%ld or >%ld", \
+ i, (unsigned long) (&(base))[i], (unsigned long) &(base), \
+ (unsigned long) low, (unsigned long) high); \
+ } \
+ } \
+ } while (0)
+
+/* Like undump_checked_things, but only check the upper value. We use
+ this when the base type is unsigned, and thus all the values will be
+ greater than zero by definition. */
+# define undump_upper_check_things(high, base, len) \
+ do { \
+ unsigned i; \
+ undump_things (base, len); \
+ for (i = 0; i < (len); i++) { \
+ if ((&(base))[i] > (high)) { \
+ FATAL4 ("Item %u (=%ld) of .fmt array at %lx >%ld", \
+ i, (unsigned long) (&(base))[i], (unsigned long) &(base), \
+ (unsigned long) high); \
+ } \
+ } \
+ } while (0)
+
+/* Use the above for all the other dumping and undumping. */
+# define generic_dump(x) dump_things (x, 1)
+# define generic_undump(x) undump_things (x, 1)
+
+# define dump_wd generic_dump
+# define dump_hh generic_dump
+# define dump_qqqq generic_dump
+# define undump_wd generic_undump
+# define undump_hh generic_undump
+# define undump_qqqq generic_undump
+
+/* `dump_int' is called with constant integers, so we put them into a
+ variable first. */
+# define dump_int(x) \
+ do \
+ { \
+ int x_val = (x); \
+ generic_dump (x_val); \
+ } \
+ while (0)
+
+/* web2c/regfix puts variables in the format file loading into
+ registers. Some compilers aren't willing to take addresses of such
+ variables. So we must kludge. */
+# if defined(REGFIX) || defined(WIN32)
+# define undump_int(x) \
+ do \
+ { \
+ int x_val; \
+ generic_undump (x_val); \
+ x = x_val; \
+ } \
+ while (0)
+# else
+# define undump_int generic_undump
+# endif /* not (REGFIX || WIN32) */
+
+
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w
new file mode 100644
index 00000000000..8b36e504182
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w
@@ -0,0 +1,527 @@
+% dumpdata.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: dumpdata.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/dumpdata.w $";
+
+#define font_id_text(A) cs_text(font_id_base+(A))
+#define prev_depth cur_list.prev_depth_field
+
+
+@ After \.{INITEX} has seen a collection of fonts and macros, it
+can write all the necessary information on an auxiliary file so
+that production versions of \TeX\ are able to initialize their
+memory at high speed. The present section of the program takes
+care of such output and input. We shall consider simultaneously
+the processes of storing and restoring,
+so that the inverse relation between them is clear.
+@.INITEX@>
+
+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 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.
+
+@c
+str_number format_ident;
+str_number format_name; /* principal file name */
+
+
+@ Format files consist of |memory_word| items, and we use the following
+macros to dump words of different types:
+
+@c
+FILE *fmt_file; /* for input or output of format information */
+
+@ @c
+void store_fmt_file(void)
+{
+ int j, k, l; /* all-purpose indices */
+ halfword p; /* all-purpose pointer */
+ int x; /* something to dump */
+ char *format_engine;
+ char *fmtname = NULL;
+ /* If dumping is not allowed, abort */
+ /* The user is not allowed to dump a format file unless |save_ptr=0|.
+ This condition implies that |cur_level=level_one|, hence
+ the |xeq_level| array is constant and it need not be dumped. */
+ if (save_ptr != 0) {
+ print_err("You can't dump inside a group");
+ help1("`{...\\dump}' is a no-no.");
+ succumb();
+ }
+
+ /* Create the |format_ident|, open the format file, and inform the user
+ that dumping has begun */
+ selector = new_string;
+ tprint(" (format=");
+ print(job_name);
+ print_char(' ');
+ print_int(int_par(year_code));
+ print_char('.');
+ print_int(int_par(month_code));
+ print_char('.');
+ print_int(int_par(day_code));
+ print_char(')');
+ str_room(2);
+ format_ident = make_string();
+ print(job_name);
+ format_name = make_string();
+ if (interaction == batch_mode)
+ selector = log_only;
+ else
+ selector = term_and_log;
+
+ fmtname = pack_job_name(format_extension);
+ while (!zopen_w_output(&fmt_file, fmtname, FOPEN_WBIN_MODE)) {
+ fmtname = prompt_file_name("format file name", format_extension);
+ }
+ tprint_nl("Beginning to dump on file ");
+ tprint(fmtname);
+ free(fmtname);
+ tprint_nl("");
+ slow_print(format_ident);
+
+ /* Dump constants for consistency check */
+ /* The next few sections of the program should make it clear how we use the
+ dump/undump macros. */
+
+ dump_int(0x57325458); /* Web2C \TeX's magic constant: "W2TX" */
+ /* Align engine to 4 bytes with one or more trailing NUL */
+ x = (int) strlen(engine_name);
+ format_engine = xmalloc((unsigned) (x + 4));
+ strcpy(format_engine, engine_name);
+ for (k = x; k <= x + 3; k++)
+ format_engine[k] = 0;
+ x = x + 4 - (x % 4);
+ dump_int(x);
+ dump_things(format_engine[0], x);
+ xfree(format_engine);
+ dump_int(0x57325458); /* TODO HM, what checksum would make sense? */
+ dump_int(max_halfword);
+ dump_int(hash_high);
+ dump_int(eqtb_size);
+ dump_int(hash_prime);
+
+ /* Dump the string pool */
+ k = dump_string_pool();
+ print_ln();
+ print_int(k);
+ tprint(" strings using ");
+ print_int((longinteger) pool_size);
+ tprint(" bytes");
+
+ /* Dump the dynamic memory */
+ /* 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 \.{INITEX} dumps valid
+ information even when it has not been gathering statistics.
+ */
+ dump_node_mem();
+ dump_int(temp_token_head);
+ dump_int(hold_token_head);
+ dump_int(omit_template);
+ dump_int(null_list);
+ dump_int(backup_head);
+ dump_int(garbage);
+ x = (int) fix_mem_min;
+ dump_int(x);
+ x = (int) fix_mem_max;
+ dump_int(x);
+ x = (int) fix_mem_end;
+ dump_int(x);
+ dump_int(avail);
+ dyn_used = (int) fix_mem_end + 1;
+ dump_things(fixmem[fix_mem_min], fix_mem_end - fix_mem_min + 1);
+ x = x + (int) (fix_mem_end + 1 - fix_mem_min);
+ p = avail;
+ while (p != null) {
+ decr(dyn_used);
+ p = token_link(p);
+ }
+ dump_int(dyn_used);
+ print_ln();
+ print_int(x);
+ tprint(" memory locations dumped; current usage is ");
+ print_int(var_used);
+ print_char('&');
+ print_int(dyn_used);
+
+ /* Dump the table of equivalents */
+ /* Dump regions 1 to 4 of |eqtb| */
+ /*The table of equivalents usually contains repeated information, so we dump it
+ in compressed form: The sequence of $n+2$ values $(n,x_1,\ldots,x_n,m)$ in the
+ 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 = null_cs;
+ do {
+ j = k;
+ while (j < int_base - 1) {
+ if ((equiv(j) == equiv(j + 1)) && (eq_type(j) == eq_type(j + 1)) &&
+ (eq_level(j) == eq_level(j + 1)))
+ goto FOUND1;
+ incr(j);
+ }
+ l = int_base;
+ goto DONE1; /* |j=int_base-1| */
+ FOUND1:
+ incr(j);
+ l = j;
+ while (j < int_base - 1) {
+ if ((equiv(j) != equiv(j + 1)) || (eq_type(j) != eq_type(j + 1)) ||
+ (eq_level(j) != eq_level(j + 1)))
+ goto DONE1;
+ incr(j);
+ }
+ DONE1:
+ dump_int(l - k);
+ dump_things(eqtb[k], l - k);
+ k = j + 1;
+ dump_int(k - l);
+ } while (k != int_base);
+
+ /* Dump regions 5 and 6 of |eqtb| */
+ do {
+ j = k;
+ while (j < eqtb_size) {
+ if (eqtb[j].cint == eqtb[j + 1].cint)
+ goto FOUND2;
+ incr(j);
+ }
+ l = eqtb_size + 1;
+ goto DONE2; /* |j=eqtb_size| */
+ FOUND2:
+ incr(j);
+ l = j;
+ while (j < eqtb_size) {
+ if (eqtb[j].cint != eqtb[j + 1].cint)
+ goto DONE2;
+ incr(j);
+ }
+ DONE2:
+ dump_int(l - k);
+ dump_things(eqtb[k], l - k);
+ k = j + 1;
+ dump_int(k - l);
+ } while (k <= eqtb_size);
+ if (hash_high > 0)
+ dump_things(eqtb[eqtb_size + 1], hash_high); /* dump |hash_extra| part */
+
+ dump_int(par_loc);
+ dump_int(write_loc);
+ dump_math_codes();
+ dump_text_codes();
+ /* Dump the hash table */
+ /* 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
+ 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.
+ */
+ dump_primitives();
+ dump_int(hash_used);
+ cs_count = frozen_control_sequence - 1 - hash_used + hash_high;
+ for (p = hash_base; p <= hash_used; p++) {
+ if (cs_text(p) != 0) {
+ dump_int(p);
+ dump_hh(hash[p]);
+ incr(cs_count);
+ }
+ }
+ dump_things(hash[hash_used + 1],
+ undefined_control_sequence - 1 - hash_used);
+ if (hash_high > 0)
+ dump_things(hash[eqtb_size + 1], hash_high);
+ dump_int(cs_count);
+ print_ln();
+ print_int(cs_count);
+ tprint(" multiletter control sequences");
+
+ /* Dump the font information */
+ dump_int(max_font_id());
+ for (k = 0; k <= max_font_id(); k++) {
+ /* Dump the array info for internal font number |k| */
+ dump_font(k);
+ tprint_nl("\\font");
+ print_esc(font_id_text(k));
+ print_char('=');
+ tprint_file_name((unsigned char *) font_name(k),
+ (unsigned char *) font_area(k), NULL);
+ if (font_size(k) != font_dsize(k)) {
+ tprint(" at ");
+ print_scaled(font_size(k));
+ tprint("pt");
+ }
+ }
+ print_ln();
+ print_int(max_font_id());
+ tprint(" preloaded font");
+ if (max_font_id() != 1)
+ print_char('s');
+ dump_math_data();
+
+ /* Dump the ocp information */
+ dump_active_ocp_info();
+ dump_ocp_info();
+ dump_ocplist_info();
+
+ /* Dump the hyphenation tables */
+ dump_language_data();
+
+ /* Dump pdftex data */
+ dump_pdftex_data(static_pdf);
+
+ /* Dump a couple more things and the closing check word */
+ dump_int(interaction);
+ dump_int(format_ident);
+ dump_int(format_name);
+ dump_int(69069);
+ /* We have already printed a lot of statistics, so we set |tracing_stats:=0|
+ to prevent them from appearing again. */
+ int_par(tracing_stats_code) = 0;
+
+ /* Dump the lua bytecodes */
+ dump_luac_registers();
+
+ /* Close the format file */
+ zwclose(fmt_file);
+}
+
+@ Corresponding to the procedure that dumps a format file, we have a function
+that reads one in. The function returns |false| if the dumped format is
+incompatible with the present \TeX\ table sizes, etc.
+
+@c
+#define too_small(A) do { \
+ wake_up_terminal(); \
+ wterm_cr(); \
+ fprintf(term_out,"---! Must increase the %s",(A)); \
+ goto BAD_FMT; \
+ } while (0)
+
+@ 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|.
+
+@c
+#define undump(A,B,C) do { \
+ undump_int(x); \
+ if (x<(A) || x>(B)) goto BAD_FMT; \
+ else (C) = x; \
+ } while (0)
+
+
+#define format_debug(A,B) do { \
+ if (debug_format_file) { \
+ fprintf (stderr, "fmtdebug: %s=%d", (A), (int)(B)); \
+ } \
+ } while (0)
+
+#define undump_size(A,B,C,D) do { \
+ undump_int(x); \
+ if (x<(A)) goto BAD_FMT; \
+ if (x>(B)) too_small(C); \
+ else format_debug (C,x); \
+ (D) = x; \
+ } while (0)
+
+
+@ @c
+boolean load_fmt_file(const char *fmtname)
+{
+ int j, k; /* all-purpose indices */
+ halfword p; /* all-purpose pointer */
+ int x; /* something undumped */
+ char *format_engine;
+ /* Undump constants for consistency check */
+ if (ini_version) {
+ libcfree(hash);
+ libcfree(eqtb);
+ libcfree(fixmem);
+ libcfree(varmem);
+ }
+ undump_int(x);
+ format_debug("format magic number", x);
+ if (x != 0x57325458)
+ goto BAD_FMT; /* not a format file */
+ undump_int(x);
+ format_debug("engine name size", x);
+ if ((x < 0) || (x > 256))
+ goto BAD_FMT; /* corrupted format file */
+
+ format_engine = xmalloc((unsigned) x);
+ undump_things(format_engine[0], x);
+ format_engine[x - 1] = 0; /* force string termination, just in case */
+ if (strcmp(engine_name, format_engine)) {
+ wake_up_terminal();
+ wterm_cr();
+ fprintf(term_out, "---! %s was written by %s", fmtname, format_engine);
+ xfree(format_engine);
+ goto BAD_FMT;
+ }
+ xfree(format_engine);
+ undump_int(x);
+ format_debug("string pool checksum", x);
+ if (x != 0x57325458) { /* todo: @@\$ *//* check that strings are the same */
+ wake_up_terminal();
+ wterm_cr();
+ fprintf(term_out, "---! %s was written by a different version",
+ fmtname);
+ goto BAD_FMT;
+ }
+ undump_int(x);
+ if (x != max_halfword)
+ goto BAD_FMT; /* check |max_halfword| */
+ undump_int(hash_high);
+ if ((hash_high < 0) || (hash_high > sup_hash_extra))
+ goto BAD_FMT;
+ if (hash_extra < hash_high)
+ hash_extra = hash_high;
+ eqtb_top = eqtb_size + hash_extra;
+ if (hash_extra == 0)
+ hash_top = undefined_control_sequence;
+ else
+ hash_top = eqtb_top;
+ hash = xmallocarray(two_halves, (unsigned) (1 + hash_top));
+ memset(hash, 0, sizeof(two_halves) * (unsigned) (hash_top + 1));
+ eqtb = xmallocarray(memory_word, (unsigned) (eqtb_top + 1));
+ set_eq_type(undefined_control_sequence, undefined_cs_cmd);
+ set_equiv(undefined_control_sequence, null);
+ set_eq_level(undefined_control_sequence, level_zero);
+ for (x = eqtb_size + 1; x <= eqtb_top; x++)
+ eqtb[x] = eqtb[undefined_control_sequence];
+ undump_int(x);
+ if (x != eqtb_size)
+ goto BAD_FMT;
+ undump_int(x);
+ if (x != hash_prime)
+ goto BAD_FMT;
+
+ /* Undump the string pool */
+ str_ptr = undump_string_pool();
+ /* Undump the dynamic memory */
+ undump_node_mem();
+ undump_int(temp_token_head);
+ undump_int(hold_token_head);
+ undump_int(omit_template);
+ undump_int(null_list);
+ undump_int(backup_head);
+ undump_int(garbage);
+ undump_int(fix_mem_min);
+ undump_int(fix_mem_max);
+ fixmem = xmallocarray(smemory_word, fix_mem_max + 1);
+ memset(voidcast(fixmem), 0, (fix_mem_max + 1) * sizeof(smemory_word));
+ undump_int(fix_mem_end);
+ undump_int(avail);
+ undump_things(fixmem[fix_mem_min], fix_mem_end - fix_mem_min + 1);
+ undump_int(dyn_used);
+
+ /* Undump the table of equivalents */
+ /* Undump regions 1 to 6 of |eqtb| */
+ k = null_cs;
+ do {
+ undump_int(x);
+ if ((x < 1) || (k + x > eqtb_size + 1))
+ goto BAD_FMT;
+ undump_things(eqtb[k], x);
+ k = k + x;
+ undump_int(x);
+ if ((x < 0) || (k + x > eqtb_size + 1))
+ goto BAD_FMT;
+ for (j = k; j <= k + x - 1; j++)
+ eqtb[j] = eqtb[k - 1];
+ k = k + x;
+ } while (k <= eqtb_size);
+ if (hash_high > 0) /* undump |hash_extra| part */
+ undump_things(eqtb[eqtb_size + 1], hash_high);
+
+ undump(hash_base, hash_top, par_loc);
+ par_token = cs_token_flag + par_loc;
+ undump(hash_base, hash_top, write_loc);
+ undump_math_codes();
+ undump_text_codes();
+ /* Undump the hash table */
+ undump_primitives();
+ undump(hash_base, frozen_control_sequence, hash_used);
+ p = hash_base - 1;
+ do {
+ undump(p + 1, hash_used, p);
+ undump_hh(hash[p]);
+ } while (p != hash_used);
+ undump_things(hash[hash_used + 1],
+ undefined_control_sequence - 1 - hash_used);
+ if (debug_format_file)
+ print_csnames(hash_base, undefined_control_sequence - 1);
+ if (hash_high > 0) {
+ undump_things(hash[eqtb_size + 1], hash_high);
+ if (debug_format_file)
+ print_csnames(eqtb_size + 1, hash_high - (eqtb_size + 1));
+ }
+ undump_int(cs_count);
+
+ /* Undump the font information */
+ undump_int(x);
+ set_max_font_id(x);
+ for (k = 0; k <= max_font_id(); k++) {
+ /* Undump the array info for internal font number |k| */
+ undump_font(k);
+ }
+ undump_math_data();
+ make_pdftex_banner();
+
+ /* Undump the ocp information */
+ undump_active_ocp_info();
+ undump_ocp_info();
+ undump_ocplist_info();
+
+ /* Undump the hyphenation tables */
+ undump_language_data();
+
+ /* Undump pdftex data */
+ undump_pdftex_data(static_pdf);
+
+ /* Undump a couple more things and the closing check word */
+ undump(batch_mode, error_stop_mode, interaction);
+ if (interactionoption != unspecified_mode)
+ interaction = interactionoption;
+ undump(0, str_ptr, format_ident);
+ undump(0, str_ptr, format_name);
+ undump_int(x);
+ if (x != 69069)
+ goto BAD_FMT;
+
+ /* Undump the lua bytecodes */
+ undump_luac_registers();
+
+ prev_depth = dimen_par(pdf_ignored_dimen_code);
+ return true; /* it worked! */
+ BAD_FMT:
+ wake_up_terminal();
+ wterm_cr();
+ fprintf(term_out, "(Fatal format file error; I'm stymied)");
+ return false;
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.h b/Build/source/texk/web2c/luatexdir/tex/equivalents.h
new file mode 100644
index 00000000000..99894d4226a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.h
@@ -0,0 +1,560 @@
+/* equivalents.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: equivalents.h 3385 2010-01-26 05:45:55Z taco $ */
+
+#ifndef EQUIVALENTS_H
+# define EQUIVALENTS_H
+
+/*
+Like the preceding parameters, the following quantities can be changed
+at compile time to extend or reduce \TeX's capacity. But if they are changed,
+it is necessary to rerun the initialization program \.{INITEX}
+@.INITEX@>
+to generate new tables for the production \TeX\ program.
+One can't simply make helter-skelter changes to the following constants,
+since certain rather complex initialization
+numbers are computed from them. They are defined here using
+\.{WEB} macros, instead of being put into \PASCAL's |const| list, in order to
+emphasize this distinction.
+*/
+
+# define font_base 0 /* smallest internal font number; must not be less than |min_quarterword| */
+# define ocp_base 0
+# define number_ocps 32768
+# define ocp_list_base 0
+# define number_ocp_lists 32768
+# define max_active_ocp_lists 32768
+# define biggest_reg 65535 /* the largest allowed register number; must be |< max_quarterword| */
+# define number_regs 65536 /* |biggest_reg+1| */
+# define number_attrs 65536 /* total numbeer of attributes */
+# define biggest_char 1114111 /* the largest allowed character number; must be |< max_halfword| */
+# define too_big_char 1114112 /* |biggest_char+1| */
+# define special_char 1114113 /* |biggest_char+2| */
+# define number_chars 1114112 /* |biggest_char+1| */
+# define number_fonts (5535-font_base+1)
+# define biggest_lang 32767
+# define too_big_lang 32768
+# define text_size 0 /* size code for the largest size in a family */
+# define script_size 1 /* size code for the medium size in a family */
+# define script_script_size 2 /* size code for the smallest size in a family */
+
+
+/*
+Each entry in |eqtb| is a |memory_word|. Most of these words are of type
+|two_halves|, and subdivided into three fields:
+
+\yskip\hangg 1) The |eq_level| (a quarterword) is the level of grouping at
+which this equivalent was defined. If the level is |level_zero|, the
+equivalent has never been defined; |level_one| refers to the outer level
+(outside of all groups), and this level is also used for global
+definitions that never go away. Higher levels are for equivalents that
+will disappear at the end of their group. @^global definitions@>
+
+\yskip\hangg 2) The |eq_type| (another quarterword) specifies what kind of
+entry this is. There are many types, since each \TeX\ primitive like
+\.{\\hbox}, \.{\\def}, etc., has its own special code. The list of
+command codes above includes all possible settings of the |eq_type| field.
+
+\yskip\hangg 3) The |equiv| (a halfword) is the current equivalent value.
+This may be a font number, a pointer into |mem|, or a variety of other
+things.
+*/
+
+
+/*
+Many locations in |eqtb| have symbolic names. The purpose of the next
+paragraphs is to define these names, and to set up the initial values of the
+equivalents.
+
+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
+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).
+*/
+
+
+
+/*
+@ Region 3 of |eqtb| contains the |number_regs| \.{\\skip} registers, as well as the
+glue parameters defined here. It is important that the ``muskip''
+parameters have larger numbers than the others.
+
+@ Region 4 of |eqtb| contains the local quantities defined here. The
+bulk of this region is taken up by five tables that are indexed by eight-bit
+characters; these tables are important to both the syntactic and semantic
+portions of \TeX. There are also a bunch of special things like font and
+token parameters, as well as the tables of \.{\\toks} and \.{\\box}
+registers.
+
+@ Region 5 of |eqtb| contains the integer parameters and registers defined
+here, as well as the |del_code| table. The latter table differs from the
+|cat_code..math_code| tables that precede it, since delimiter codes are
+fullword integers while the other kinds of codes occupy at most a
+halfword. This is what makes region~5 different from region~4. We will
+store the |eq_level| information in an auxiliary array of quarterwords
+that will be defined later.
+
+@ The integer parameters should really be initialized by a macro package;
+the following initialization does the minimum to keep \TeX\ from
+complete failure.
+@^null delimiter@>
+
+@ The final region of |eqtb| contains the dimension parameters defined
+here, and the |number_regs| \.{\\dimen} registers.
+*/
+
+# define null_cs 1 /* equivalent of \.{\\csname\\endcsname} */
+# define hash_base (null_cs+1) /* beginning of region 2, for the hash table */
+# define frozen_control_sequence (hash_base+hash_size) /* for error recovery */
+# define frozen_protection (frozen_control_sequence) /* inaccessible but definable */
+# define frozen_cr (frozen_control_sequence+1) /* permanent `\.{\\cr}' */
+# define frozen_end_group (frozen_control_sequence+2) /* permanent `\.{\\endgroup}' */
+# define frozen_right (frozen_control_sequence+3) /* permanent `\.{\\right}' */
+# define frozen_fi (frozen_control_sequence+4) /* permanent `\.{\\fi}' */
+# define frozen_end_template (frozen_control_sequence+5)
+ /* permanent `\.{\\endtemplate}' */
+# define frozen_endv (frozen_control_sequence+6)
+ /* second permanent `\.{\\endtemplate}' */
+# define frozen_relax (frozen_control_sequence+7) /* permanent `\.{\\relax}' */
+# define end_write (frozen_control_sequence+8) /* permanent `\.{\\endwrite}' */
+# define frozen_dont_expand (frozen_control_sequence+9 )
+ /* permanent `\.{\\notexpanded:}' */
+# define frozen_primitive (frozen_control_sequence+11 ) /* permanent `\.{\\pdfprimitive}' */
+# define frozen_special (frozen_control_sequence+12 ) /* permanent `\.{\\special}' */
+# define frozen_null_font (frozen_control_sequence+13 ) /* permanent `\.{\\nullfont}' */
+# define font_id_base (frozen_null_font-font_base ) /* begins table of |number_fonts| permanent font identifiers */
+# define frozen_null_ocp (frozen_null_font+number_fonts ) /* permanent `\.{\\nullocp}' */
+# define ocp_id_base (frozen_null_ocp-ocp_base )
+ /* begins table of |number_ocps| permanent ocp identifiers */
+# define frozen_null_ocp_list (frozen_null_ocp+number_ocps ) /* permanent `\.{\\nullocplist}' */
+# define ocp_list_id_base (frozen_null_ocp_list-ocp_list_base ) /* begins table of |number_ocp_lists| permanent ocp list identifiers */
+# define undefined_control_sequence (frozen_null_ocp_list+number_ocp_lists)
+# define glue_base (undefined_control_sequence+1) /* beginning of region 3 */
+
+# define line_skip_code 0 /* interline glue if |baseline_skip| is infeasible */
+# define baseline_skip_code 1 /* desired glue between baselines */
+# define par_skip_code 2 /* extra glue just above a paragraph */
+# define above_display_skip_code 3 /* extra glue just above displayed math */
+# define below_display_skip_code 4 /* extra glue just below displayed math */
+# define above_display_short_skip_code 5
+ /* glue above displayed math following short lines */
+# define below_display_short_skip_code 6
+ /* glue below displayed math following short lines */
+# define left_skip_code 7 /* glue at left of justified lines */
+# define right_skip_code 8 /* glue at right of justified lines */
+# define top_skip_code 9 /* glue at top of main pages */
+# define split_top_skip_code 10 /* glue at top of split pages */
+# define tab_skip_code 11 /* glue between aligned entries */
+# define space_skip_code 12 /* glue between words (if not |zero_glue|) */
+# define xspace_skip_code 13 /* glue after sentences (if not |zero_glue|) */
+# define par_fill_skip_code 14 /* glue on last line of paragraph */
+# define thin_mu_skip_code 15 /* thin space in math formula */
+# define med_mu_skip_code 16 /* medium space in math formula */
+# define thick_mu_skip_code 17 /* thick space in math formula */
+# define glue_pars 18 /* total number of glue parameters */
+
+# define skip_base (glue_base+glue_pars)
+ /* table of |number_regs| ``skip'' registers */
+# define mu_skip_base (skip_base+number_regs) /* table of |number_regs| ``muskip'' registers */
+# define local_base (mu_skip_base+number_regs) /* beginning of region 4 */
+
+# define par_shape_loc (local_base) /* specifies paragraph shape */
+# define output_routine_loc (local_base+1) /* points to token list for \.{\\output} */
+# define every_par_loc (local_base+2) /* points to token list for \.{\\everypar} */
+# define every_math_loc (local_base+3) /* points to token list for \.{\\everymath} */
+# define every_display_loc (local_base+4) /* points to token list for \.{\\everydisplay} */
+# define every_hbox_loc (local_base+5) /* points to token list for \.{\\everyhbox} */
+# define every_vbox_loc (local_base+6) /* points to token list for \.{\\everyvbox} */
+# define every_job_loc (local_base+7) /* points to token list for \.{\\everyjob} */
+# define every_cr_loc (local_base+8) /* points to token list for \.{\\everycr} */
+# define err_help_loc (local_base+9) /* points to token list for \.{\\errhelp} */
+# define every_eof_loc (local_base+10) /* points to token list for \.{\\everyeof} */
+# define tex_toks (local_base+11) /* end of (e-)\TeX's token list parameters */
+# define pdftex_first_loc (tex_toks) /* base for \pdfTeX's token list parameters */
+# define pdf_pages_attr_loc (pdftex_first_loc + 0) /* points to token list for \.{\\pdfpagesattr} */
+# define pdf_page_attr_loc (pdftex_first_loc + 1) /* points to token list for \.{\\pdfpageattr} */
+# define pdf_page_resources_loc (pdftex_first_loc + 2) /* points to token list for \.{\\pdfpageresources} */
+# define pdf_xform_attr_loc (pdftex_first_loc + 3) /* points to token list for \.{\\pdfxformattr} */
+# define pdf_xform_resources_loc (pdftex_first_loc + 4) /* points to token list for \.{\\pdfxformresources} */
+# define pdf_pk_mode_loc (pdftex_first_loc + 5) /* points to token list for \.{\\pdfpkmode} */
+# define pdf_toks (pdftex_first_loc+6) /* end of \pdfTeX's token list parameters */
+# define ocp_trace_level_base (pdf_toks)
+# define ocp_active_number_base (ocp_trace_level_base+1)
+# define ocp_active_min_ptr_base (ocp_active_number_base+1)
+# define ocp_active_max_ptr_base (ocp_active_min_ptr_base+1)
+# define ocp_active_base (ocp_active_max_ptr_base+1)
+# define toks_base (ocp_active_base+max_active_ocp_lists) /* table of |number_regs| token list registers */
+# define etex_pen_base (toks_base+number_regs) /* start of table of \eTeX's penalties */
+# define inter_line_penalties_loc (etex_pen_base) /* additional penalties between lines */
+# define club_penalties_loc (etex_pen_base+1) /* penalties for creating club lines */
+# define widow_penalties_loc (etex_pen_base+2) /* penalties for creating widow lines */
+# define display_widow_penalties_loc (etex_pen_base+3) /* ditto, just before a display */
+# define etex_pens (etex_pen_base+4) /* end of table of \eTeX's penalties */
+# define local_left_box_base (etex_pens)
+# define local_right_box_base (local_left_box_base+1)
+# define box_base (local_right_box_base+1) /* table of |number_regs| box registers */
+# define cur_font_loc (box_base+number_regs) /* internal font number outside math mode */
+# define internal_math_param_base (cur_font_loc+1 ) /* current math parameter data index */
+# define cat_code_base (internal_math_param_base+1) /* current category code data index */
+# define lc_code_base (cat_code_base+1) /* table of |number_chars| lowercase mappings */
+# define uc_code_base (lc_code_base+1) /* table of |number_chars| uppercase mappings */
+# define sf_code_base (uc_code_base+1) /* table of |number_chars| spacefactor mappings */
+# define math_code_base (sf_code_base+1)
+ /* table of |number_chars| math mode mappings */
+# define int_base (math_code_base+1) /* beginning of region 5 */
+
+# define pretolerance_code 0 /* badness tolerance before hyphenation */
+# define tolerance_code 1 /* badness tolerance after hyphenation */
+# define line_penalty_code 2 /* added to the badness of every line */
+# define hyphen_penalty_code 3 /* penalty for break after discretionary hyphen */
+# define ex_hyphen_penalty_code 4 /* penalty for break after explicit hyphen */
+# define club_penalty_code 5 /* penalty for creating a club line */
+# define widow_penalty_code 6 /* penalty for creating a widow line */
+# define display_widow_penalty_code 7 /* ditto, just before a display */
+# define broken_penalty_code 8 /* penalty for breaking a page at a broken line */
+# define bin_op_penalty_code 9 /* penalty for breaking after a binary operation */
+# define rel_penalty_code 10 /* penalty for breaking after a relation */
+# define pre_display_penalty_code 11 /* penalty for breaking just before a displayed formula */
+# define post_display_penalty_code 12 /* penalty for breaking just after a displayed formula */
+# define inter_line_penalty_code 13 /* additional penalty between lines */
+# define double_hyphen_demerits_code 14 /* demerits for double hyphen break */
+# define final_hyphen_demerits_code 15 /* demerits for final hyphen break */
+# define adj_demerits_code 16 /* demerits for adjacent incompatible lines */
+# define mag_code 17 /* magnification ratio */
+# define delimiter_factor_code 18 /* ratio for variable-size delimiters */
+# define looseness_code 19 /* change in number of lines for a paragraph */
+# define time_code 20 /* current time of day */
+# define day_code 21 /* current day of the month */
+# define month_code 22 /* current month of the year */
+# define year_code 23 /* current year of our Lord */
+# define show_box_breadth_code 24 /* nodes per level in |show_box| */
+# define show_box_depth_code 25 /* maximum level in |show_box| */
+# define hbadness_code 26 /* hboxes exceeding this badness will be shown by |hpack| */
+# define vbadness_code 27 /* vboxes exceeding this badness will be shown by |vpack| */
+# define pausing_code 28 /* pause after each line is read from a file */
+# define tracing_online_code 29 /* show diagnostic output on terminal */
+# define tracing_macros_code 30 /* show macros as they are being expanded */
+# define tracing_stats_code 31 /* show memory usage if \TeX\ knows it */
+# define tracing_paragraphs_code 32 /* show line-break calculations */
+# define tracing_pages_code 33 /* show page-break calculations */
+# define tracing_output_code 34 /* show boxes when they are shipped out */
+# define tracing_lost_chars_code 35 /* show characters that aren't in the font */
+# define tracing_commands_code 36 /* show command codes at |big_switch| */
+# define tracing_restores_code 37 /* show equivalents when they are restored */
+# define uc_hyph_code 38 /* hyphenate words beginning with a capital letter */
+# define output_penalty_code 39 /* penalty found at current page break */
+# define max_dead_cycles_code 40
+ /* bound on consecutive dead cycles of output */
+# define hang_after_code 41 /* hanging indentation changes after this many lines */
+# define floating_penalty_code 42 /* penalty for insertions heldover after a split */
+# define global_defs_code 43 /* override \.{\\global} specifications */
+# define cur_fam_code 44 /* current family */
+# define escape_char_code 45 /* escape character for token output */
+# define default_hyphen_char_code 46 /* value of \.{\\hyphenchar} when a font is loaded */
+# define default_skew_char_code 47 /* value of \.{\\skewchar} when a font is loaded */
+# define end_line_char_code 48 /* character placed at the right end of the buffer */
+# define new_line_char_code 49 /* character that prints as |print_ln| */
+# define language_code 50 /* current hyphenation table */
+# define left_hyphen_min_code 51
+ /* minimum left hyphenation fragment size */
+# define right_hyphen_min_code 52 /* minimum right hyphenation fragment size */
+# define holding_inserts_code 53
+ /* do not remove insertion nodes from \.{\\box255} */
+# define error_context_lines_code 54 /* maximum intermediate line pairs shown */
+# define local_inter_line_penalty_code 55 /* local \.{\\interlinepenalty} */
+# define local_broken_penalty_code 56 /* local \.{\\brokenpenalty} */
+# define no_local_whatsits_code 57 /* counts local whatsits */
+# define no_local_dirs_code 58
+
+# define luastartup_id_code 60
+# define disable_lig_code 61
+# define disable_kern_code 62
+# define cat_code_table_code 63
+# define output_box_code 64
+# define cur_lang_code 65 /* current language id */
+# define ex_hyphen_char_code 66
+# define pdftex_first_integer_code 67 /*base for \pdfTeX's integer parameters */
+# define pdf_output_code (pdftex_first_integer_code + 0)
+ /*switch on PDF output if positive */
+# define pdf_compress_level_code (pdftex_first_integer_code + 1)
+ /*compress level of streams */
+# define pdf_decimal_digits_code (pdftex_first_integer_code + 2)
+ /*digits after the decimal point of numbers */
+# define pdf_image_resolution_code (pdftex_first_integer_code + 3) /*default image resolution */
+# define pdf_pk_resolution_code (pdftex_first_integer_code + 4) /*default resolution of PK font */
+# define pdf_unique_resname_code (pdftex_first_integer_code + 5)
+ /*generate unique names for resouces */
+# define pdf_minor_version_code (pdftex_first_integer_code + 6) /*fractional part of the PDF version produced */
+# define pdf_pagebox_code (pdftex_first_integer_code + 7) /*default pagebox to use for PDF inclusion */
+# define pdf_inclusion_errorlevel_code (pdftex_first_integer_code + 8) /*if the PDF inclusion should treat pdfs
+ newer than |pdf_minor_version| as an error */
+# define pdf_gamma_code (pdftex_first_integer_code + 9)
+# define pdf_image_gamma_code (pdftex_first_integer_code + 10)
+# define pdf_image_hicolor_code (pdftex_first_integer_code + 11)
+# define pdf_image_apply_gamma_code (pdftex_first_integer_code + 12)
+# define pdf_adjust_spacing_code (pdftex_first_integer_code + 13) /*level of spacing adjusting */
+# define pdf_protrude_chars_code (pdftex_first_integer_code + 14) /*protrude chars at left/right edge of paragraphs */
+# define pdf_tracing_fonts_code (pdftex_first_integer_code + 15)
+ /*level of font detail in log */
+# define pdf_objcompresslevel_code (pdftex_first_integer_code + 16) /*activate object streams */
+# define pdf_gen_tounicode_code (pdftex_first_integer_code + 17)
+ /*generate ToUnicode for fonts? */
+# define pdf_draftmode_code (pdftex_first_integer_code + 18) /*switch on draftmode if positive */
+# define pdf_replace_font_code (pdftex_first_integer_code + 19) /*generate ToUnicode for fonts? */
+# define pdf_inclusion_copy_font_code (pdftex_first_integer_code + 20) /*generate ToUnicode for fonts? */
+# define pdf_int_pars (pdftex_first_integer_code + 21) /*total number of \pdfTeX's integer parameters */
+# define etex_first_integer_code (pdf_int_pars) /*base for \eTeX's integer parameters */
+# define tracing_assigns_code (etex_first_integer_code) /*show assignments */
+# define tracing_groups_code (etex_first_integer_code+1) /*show save/restore groups */
+# define tracing_ifs_code (etex_first_integer_code+2) /*show conditionals */
+# define tracing_scan_tokens_code (etex_first_integer_code+3) /*show pseudo file open and close */
+# define tracing_nesting_code (etex_first_integer_code+4) /*show incomplete groups and ifs within files */
+# define pre_display_direction_code (etex_first_integer_code+5) /*text direction preceding a display */
+# define last_line_fit_code (etex_first_integer_code+6) /*adjustment for last line of paragraph */
+# define saving_vdiscards_code (etex_first_integer_code+7)
+ /*save items discarded from vlists */
+# define saving_hyph_codes_code (etex_first_integer_code+8) /*save hyphenation codes for languages */
+# define suppress_fontnotfound_error_code (etex_first_integer_code+9) /*suppress errors for missing fonts */
+# define suppress_long_error_code (etex_first_integer_code+10) /*suppress errors for missing fonts */
+# define suppress_ifcsname_error_code (etex_first_integer_code+11)
+ /*suppress errors for failed \.{\\ifcsname} */
+# define suppress_outer_error_code (etex_first_integer_code+12) /*suppress errors for \.{\\outer} */
+# define synctex_code (etex_first_integer_code+13) /* is synctex file generation enabled ? */
+# define tex_int_pars (synctex_code+1) /* total number of integer parameters */
+
+# define page_direction_code (tex_int_pars)
+# define body_direction_code (tex_int_pars+1)
+# define par_direction_code (tex_int_pars+2)
+# define text_direction_code (tex_int_pars+3)
+# define math_direction_code (tex_int_pars+4)
+# define int_pars (tex_int_pars+5) /*total number of integer parameters */
+
+# define dir_base (int_base+tex_int_pars)
+# define count_base (int_base+int_pars) /*|number_regs| user \.{\\count} registers */
+# define attribute_base (count_base+number_regs)
+ /*|number_attrs| user \.{\\attribute} registers */
+# define del_code_base (attribute_base+number_attrs) /*|number_chars| delimiter code mappings */
+# define dimen_base (del_code_base+1) /*beginning of region 6 */
+
+# define par_indent_code 0 /* indentation of paragraphs */
+# define math_surround_code 1 /* space around math in text */
+# define line_skip_limit_code 2 /* threshold for |line_skip| instead of |baseline_skip| */
+# define hsize_code 3 /* line width in horizontal mode */
+# define vsize_code 4 /* page height in vertical mode */
+# define max_depth_code 5 /* maximum depth of boxes on main pages */
+# define split_max_depth_code 6 /* maximum depth of boxes on split pages */
+# define box_max_depth_code 7 /* maximum depth of explicit vboxes */
+# define hfuzz_code 8 /* tolerance for overfull hbox messages */
+# define vfuzz_code 9 /* tolerance for overfull vbox messages */
+# define delimiter_shortfall_code 10 /* maximum amount uncovered by variable delimiters */
+# define null_delimiter_space_code 11 /* blank space in null delimiters */
+# define script_space_code 12 /* extra space after subscript or superscript */
+# define pre_display_size_code 13 /* length of text preceding a display */
+# define display_width_code 14 /* length of line for displayed equation */
+# define display_indent_code 15 /* indentation of line for displayed equation */
+# define overfull_rule_code 16 /* width of rule that identifies overfull hboxes */
+# define hang_indent_code 17 /* amount of hanging indentation */
+# define h_offset_code 18 /* amount of horizontal offset when shipping pages out */
+# define v_offset_code 19 /* amount of vertical offset when shipping pages out */
+# define emergency_stretch_code 20 /* reduces badnesses on final pass of line-breaking */
+# define page_left_offset_code 21
+# define page_top_offset_code 22
+# define page_right_offset_code 23
+# define page_bottom_offset_code 24
+# define pdftex_first_dimen_code 25 /* first number defined in this section */
+# define pdf_h_origin_code (pdftex_first_dimen_code + 0) /* horigin of the PDF output */
+# define pdf_v_origin_code (pdftex_first_dimen_code + 1) /* vorigin of the PDF output */
+# define page_width_code (pdftex_first_dimen_code + 2) /* page width of the PDF output */
+# define page_height_code (pdftex_first_dimen_code + 3) /* page height of the PDF output */
+# define pdf_link_margin_code (pdftex_first_dimen_code + 4) /* link margin in the PDF output */
+# define pdf_dest_margin_code (pdftex_first_dimen_code + 5) /* dest margin in the PDF output */
+# define pdf_thread_margin_code (pdftex_first_dimen_code + 6) /* thread margin in the PDF output */
+# define pdf_first_line_height_code (pdftex_first_dimen_code + 7)
+# define pdf_last_line_depth_code (pdftex_first_dimen_code + 8)
+# define pdf_each_line_height_code (pdftex_first_dimen_code + 9)
+# define pdf_each_line_depth_code (pdftex_first_dimen_code + 10)
+# define pdf_ignored_dimen_code (pdftex_first_dimen_code + 11)
+# define pdf_px_dimen_code (pdftex_first_dimen_code + 12)
+# define pdftex_last_dimen_code (pdftex_first_dimen_code + 12) /* last number defined in this section */
+# define dimen_pars (pdftex_last_dimen_code + 1)
+ /* total number of dimension parameters */
+
+# define scaled_base (dimen_base+dimen_pars) /* table of |number_regs| user-defined \.{\\dimen} registers */
+# define eqtb_size (scaled_base+biggest_reg) /* largest subscript of |eqtb| */
+
+extern memory_word *eqtb;
+
+extern halfword eqtb_top; /* maximum of the |eqtb| */
+
+extern quarterword xeq_level[(eqtb_size + 1)];
+extern void initialize_equivalents(void);
+
+# define eq_level_field(A) (A).hh.b1
+# define eq_type_field(A) (A).hh.b0
+# define equiv_field(A) (A).hh.rh
+
+# define eq_level(A) eq_level_field(eqtb[(A)]) /* level of definition */
+# define eq_type(A) eq_type_field(eqtb[(A)]) /* command code for equivalent */
+# define equiv(A) equiv_field(eqtb[(A)])
+ /* equivalent value */
+
+# define set_eq_level(A,B) eq_level((A)) = (B)
+# define set_eq_type(A,B) eq_type((A)) = (B)
+# define set_equiv(A,B) equiv((A)) = (B)
+
+typedef struct save_record_ {
+ quarterword type_;
+ quarterword level_;
+ memory_word word_;
+} save_record;
+
+
+extern save_record *save_stack;
+extern int save_ptr; /* first unused entry on |save_stack| */
+extern int max_save_stack; /* maximum usage of save stack */
+extern quarterword cur_level; /* current nesting level for groups */
+extern group_code cur_group; /* current group type */
+extern int cur_boundary; /* where the current level begins */
+
+
+# define save_type(A) save_stack[(A)].type_ /* classifies a |save_stack| entry */
+# define save_level(A) save_stack[(A)].level_ /* saved level for regions 5 and 6, or group code */
+# define save_value(A) save_stack[(A)].word_.cint /* |eqtb| location or token or |save_stack| location */
+# define save_word(A) save_stack[(A)].word_ /* |eqtb| entry */
+
+/*
+We use the notation |saved(k)| to stand for an item that
+appears in location |save_ptr+k| of the save stack.
+*/
+
+# define saved_type(A) save_stack[save_ptr+(A)].type_
+# define saved_level(A) save_stack[save_ptr+(A)].level_
+# define saved_value(A) save_stack[save_ptr+(A)].word_.cint
+
+# define set_saved_record(A,B,C,D) do { \
+ saved_type(A) = (quarterword)(B); \
+ saved_level(A) = (quarterword)(C); \
+ saved_value(A) = (D); \
+ } while (0)
+
+# define restore_old_value 0 /* |save_type| when a value should be restored later */
+# define restore_zero 1 /* |save_type| when an undefined entry should be restored */
+# define insert_token 2 /* |save_type| when a token is being saved for later use */
+# define level_boundary 3 /* |save_type| corresponding to beginning of group */
+# define saved_line 4
+# define saved_adjust 5
+# define saved_insert 6
+# define saved_disc 7
+# define saved_boxtype 8
+# define saved_textdir 9
+# define saved_eqno 10
+# define saved_choices 11
+# define saved_math 12
+# define saved_boxcontext 13
+# define saved_boxspec 14
+# define saved_boxdir 15
+# define saved_boxattr 16
+# define saved_eqtb 17
+
+extern void print_save_stack(void);
+
+# define assign_trace(A,B) if (int_par(tracing_assigns_code)>0) restore_trace((A),(B))
+
+# define int_par(A) eqtb[int_base+(A)].cint
+# define dimen_par(A) eqtb[dimen_base+(A)].cint
+# define loc_par(A) equiv(local_base+(A))
+# define glue_par(A) equiv(glue_base+(A))
+
+extern int mag_set; /* if nonzero, this magnification should be used henceforth */
+extern void prepare_mag(void);
+
+/*
+@ Here are the group codes that are used to discriminate between different
+kinds of groups. They allow \TeX\ to decide what special actions, if any,
+should be performed when a group ends.
+\def\grp{\.{\char'173...\char'175}}
+
+Some groups are not supposed to be ended by right braces. For example,
+the `\.\$' that begins a math formula causes a |math_shift_group| to
+be started, and this should be terminated by a matching `\.\$'. Similarly,
+a group that starts with \.{\\left} should end with \.{\\right}, and
+one that starts with \.{\\begingroup} should end with \.{\\endgroup}.
+
+*/
+
+
+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}' */
+ 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;
+
+# define max_group_code local_box_group /* which is wrong, but is what the web says */
+
+extern int cur_cmd; /* current command set by |get_next| */
+extern halfword cur_chr; /* operand of current command */
+extern halfword cur_cs; /* control sequence found here, zero if none found */
+extern halfword cur_tok; /* packed representative of |cur_cmd| and |cur_chr| */
+
+extern void show_cur_cmd_chr(void);
+
+extern void new_save_level(group_code c); /* begin a new level of grouping */
+extern void eq_destroy(memory_word w); /* gets ready to forget |w| */
+extern void eq_save(halfword p, quarterword l); /* saves |eqtb[p]| */
+extern void eq_define(halfword p, quarterword t, halfword e); /* new data for |eqtb| */
+extern void eq_word_define(halfword p, int w);
+extern void geq_define(halfword p, quarterword t, halfword e); /* global |eq_define| */
+extern void geq_word_define(halfword p, int w); /* global |eq_word_define| */
+extern void save_for_after(halfword t);
+extern void unsave(void); /* pops the top level off the save stack */
+extern void restore_trace(halfword p, const char *s); /* |eqtb[p]| has just been restored or retained */
+extern void show_save_groups(void);
+
+# define level_zero 0 /* level for undefined quantities */
+# define level_one 1 /* outermost level for defined quantities */
+
+extern void show_eqtb(halfword n);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.w b/Build/source/texk/web2c/luatexdir/tex/equivalents.w
new file mode 100644
index 00000000000..02fa1f48578
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.w
@@ -0,0 +1,1171 @@
+% equivalents.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: equivalents.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/equivalents.w $";
+
+@ @c
+#define par_shape_ptr equiv(par_shape_loc)
+
+void show_eqtb_meaning(halfword n); /* forward */
+
+@ Now that we have studied the data structures for \TeX's semantic routines,
+we ought to consider the data structures used by its syntactic routines. In
+other words, our next concern will be
+the tables that \TeX\ looks at when it is scanning
+what the user has written.
+
+The biggest and most important such table is called |eqtb|. It holds the
+current ``equivalents'' of things; i.e., it explains what things mean
+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\hang 1) |eqtb[null_cs]| holds the current equivalent of the
+zero-length control sequence.
+
+\yskip\hang 2) |eqtb[hash_base..(glue_base-1)]| holds the current
+equivalents of single- and multiletter control sequences.
+
+\yskip\hang 3) |eqtb[glue_base..(local_base-1)]| holds the current
+equivalents of glue parameters like the current baselineskip.
+
+\yskip\hang 4) |eqtb[local_base..(int_base-1)]| holds the current
+equivalents of local halfword quantities like the current box registers,
+the current ``catcodes,'' the current font, and a pointer to the current
+paragraph shape.
+
+\yskip\hang 5) |eqtb[int_base..(dimen_base-1)]| holds the current
+equivalents of fullword integer parameters like the current hyphenation
+penalty.
+
+\yskip\hang 6) |eqtb[dimen_base..eqtb_size]| holds the current equivalents
+of fullword dimension parameters like the current hsize or amount of
+hanging indentation.
+
+\yskip\noindent Note that, for example, the current amount of
+baselineskip glue is determined by the setting of a particular location
+in region~3 of |eqtb|, while the current meaning of the control sequence
+`\.{\\baselineskip}' (which might have been changed by \.{\\def} or
+\.{\\let}) appears in region~2.
+
+@ The last two regions of |eqtb| have fullword values instead of the
+three fields |eq_level|, |eq_type|, and |equiv|. An |eq_type| is unnecessary,
+but \TeX\ needs to store the |eq_level| information in another array
+called |xeq_level|.
+
+@c
+memory_word *eqtb;
+halfword eqtb_top; /* maximum of the |eqtb| */
+quarterword xeq_level[(eqtb_size + 1)];
+
+@ @c
+void initialize_equivalents(void)
+{
+ int k;
+ for (k = int_base; k <= eqtb_size; k++)
+ xeq_level[k] = level_one;
+}
+
+
+@ The nested structure provided by `$\.{\char'173}\ldots\.{\char'175}$' groups
+in \TeX\ means that |eqtb| entries valid in outer groups should be saved
+and restored later if they are overridden inside the braces. When a new |eqtb|
+value is being assigned, the program therefore checks to see if the previous
+entry belongs to an outer level. In such a case, the old value is placed
+on the |save_stack| just before the new value enters |eqtb|. At the
+end of a grouping level, i.e., when the right brace is sensed, the
+|save_stack| is used to restore the outer values, and the inner ones are
+destroyed.
+
+Entries on the |save_stack| are of type |save_record|. The top item on
+this stack is |save_stack[p]|, where |p=save_ptr-1|; it contains three
+fields called |save_type|, |save_level|, and |save_value|, and it is
+interpreted in one of four ways:
+
+\yskip\hang 1) If |save_type(p)=restore_old_value|, then
+|save_value(p)| is a location in |eqtb| whose current value should
+be destroyed at the end of the current group and replaced by |save_word(p-1)|
+(|save_type(p-1)==saved_eqtb|).
+Furthermore if |save_value(p)>=int_base|, then |save_level(p)| should
+replace the corresponding entry in |xeq_level| (if |save_value(p)<int_base|,
+then the level is part of |save_word(p-1)|).
+
+\yskip\hang 2) If |save_type(p)=restore_zero|, then |save_value(p)|
+is a location in |eqtb| whose current value should be destroyed at the end
+of the current group, when it should be
+replaced by the current value of |eqtb[undefined_control_sequence]|.
+
+\yskip\hang 3) If |save_type(p)=insert_token|, then |save_value(p)|
+is a token that should be inserted into \TeX's input when the current
+group ends.
+
+\yskip\hang 4) If |save_type(p)=level_boundary|, then |save_level(p)|
+is a code explaining what kind of group we were previously in, and
+|save_value(p)| points to the level boundary word at the bottom of
+the entries for that group. Furthermore, |save_value(p-1)| contains the
+source line number at which the current level of grouping was entered,
+this field has itself a type: |save_type(p-1)==saved_line|.
+
+
+Besides this `official' use, various subroutines push temporary
+variables on the save stack when it is handy to do so. These all have
+an explicit |save_type|, and they are:
+
+|saved_adjust| signifies an adjustment is beging scanned,
+|saved_insert| an insertion is being scanned,
+|saved_disc| the \.{\\discretionary} sublist we are working on right now,
+|saved_boxtype| whether a \.{\\localbox} is \.{\\left} or \.{\\right},
+|saved_textdir| a text direction to be restored,
+|saved_eqno| diffentiates between \.{\\eqno} and \.{\\leqno},
+|saved_choices| the \.{\\mathchoices} sublist we are working on right now,
+|saved_math| and interrupted math list,
+|saved_boxcontext| the box context value,
+|saved_boxspec| the box \.{to} or \.{spread} specification,
+|saved_boxdir| the box \.{dir} specification,
+|saved_boxattr| the box \.{attr} specification.
+
+@ The global variable |cur_group| keeps track of what sort of group we are
+currently in. Another global variable, |cur_boundary|, points to the
+topmost |level_boundary| word. And |cur_level| is the current depth of
+nesting. The routines are designed to preserve the condition that no entry
+in the |save_stack| or in |eqtb| ever has a level greater than |cur_level|.
+
+@c
+save_record *save_stack;
+int save_ptr; /* first unused entry on |save_stack| */
+int max_save_stack; /* maximum usage of save stack */
+quarterword cur_level = level_one; /* current nesting level for groups */
+group_code cur_group = bottom_level; /* current group type */
+int cur_boundary; /* where the current level begins */
+
+
+@ At this time it might be a good idea for the reader to review the introduction
+to |eqtb| that was given above just before the long lists of parameter names.
+Recall that the ``outer level'' of the program is |level_one|, since
+undefined control sequences are assumed to be ``defined'' at |level_zero|.
+
+
+
+@ The following macro is used to test if there is room for up to eight more
+entries on |save_stack|. By making a conservative test like this, we can
+get by with testing for overflow in only a few places.
+
+@c
+#define check_full_save_stack() do { \
+ if (save_ptr>max_save_stack) { \
+ max_save_stack=save_ptr; \
+ if (max_save_stack>save_size-8) \
+ overflow("save size",(unsigned)save_size); \
+ } \
+ } while (0)
+
+
+@ Procedure |new_save_level| is called when a group begins. The
+argument is a group identification code like `|hbox_group|'. After
+calling this routine, it is safe to put six more entries on |save_stack|.
+
+In some cases integer-valued items are placed onto the
+|save_stack| just below a |level_boundary| word, because this is a
+convenient place to keep information that is supposed to ``pop up'' just
+when the group has finished.
+For example, when `\.{\\hbox to 100pt}' is being treated, the 100pt
+dimension is stored on |save_stack| just before |new_save_level| is
+called.
+
+@c
+void new_save_level(group_code c)
+{ /* begin a new level of grouping */
+ check_full_save_stack();
+ set_saved_record(0, saved_line, 0, line);
+ incr(save_ptr);
+ save_type(save_ptr) = level_boundary;
+ save_level(save_ptr) = cur_group;
+ save_value(save_ptr) = cur_boundary;
+ if (cur_level == max_quarterword)
+ overflow("grouping levels", max_quarterword - min_quarterword);
+ /* quit if |(cur_level+1)| is too big to be stored in |eqtb| */
+ cur_boundary = save_ptr;
+ cur_group = c;
+ if (int_par(tracing_groups_code) > 0)
+ group_trace(false);
+ incr(cur_level);
+ incr(save_ptr);
+}
+
+@ @c
+static const char *save_stack_type(int v)
+{
+ const char *s = "";
+ switch (save_type(v)) {
+/* *INDENT-OFF* */
+ case restore_old_value: s = "restore_old_value"; break;
+ case restore_zero: s = "restore_zero"; break;
+ case insert_token: s = "insert_token"; break;
+ case level_boundary: s = "level_boundary"; break;
+ case saved_line: s = "saved_line"; break;
+ case saved_adjust: s = "saved_adjust"; break;
+ case saved_insert: s = "saved_insert"; break;
+ case saved_disc: s = "saved_disc"; break;
+ case saved_boxtype: s = "saved_boxtype"; break;
+ case saved_textdir: s = "saved_textdir"; break;
+ case saved_eqno: s = "saved_eqno"; break;
+ case saved_choices: s = "saved_choices"; break;
+ case saved_math: s = "saved_math"; break;
+ case saved_boxcontext: s = "saved_boxcontext"; break;
+ case saved_boxspec: s = "saved_boxspec"; break;
+ case saved_boxdir: s = "saved_boxdir"; break;
+ case saved_boxattr: s = "saved_boxattr"; break;
+ case saved_eqtb: s = "saved_eqtb"; break;
+ default: break;
+/* *INDENT-ON* */
+ }
+ return s;
+}
+
+@ @c
+void print_save_stack(void)
+{
+ int i;
+ begin_diagnostic();
+ selector = term_and_log;
+ print_ln();
+ for (i = (save_ptr - 1); i >= 0; i--) {
+ tprint("save_stack[");
+ if (i < 100)
+ print_char(' ');
+ if (i < 10)
+ print_char(' ');
+ print_int(i);
+ tprint("]: ");
+ tprint(save_stack_type(i));
+ switch (save_type(i)) {
+ case restore_old_value:
+ tprint(", ");
+ show_eqtb_meaning(save_value(i));
+ tprint("=");
+ if (save_value(i) >= int_base) {
+ print_int(save_word(i - 1).cint);
+ } else {
+ print_int(eq_type_field(save_word(i - 1)));
+ print_char(','); /* |print_int(eq_level_field(save_word(i-1)));| */
+ print_int(equiv_field(save_word(i - 1)));
+ }
+ i--;
+ break;
+ case restore_zero:
+ tprint(", ");
+ show_eqtb_meaning(save_value(i));
+ break;
+ case insert_token:
+ tprint(", ");
+ {
+ halfword p = get_avail();
+ set_token_info(p, save_value(i));
+ show_token_list(p, null, 1);
+ free_avail(p);
+ }
+ break;
+ case level_boundary:
+ tprint(", old group=");
+ print_int(save_level(i));
+ tprint(", boundary = ");
+ print_int(save_value(i));
+ tprint(", line = ");
+ print_int(save_value(i - 1));
+ i--;
+ break;
+ case saved_adjust:
+ tprint(", ");
+ print_int(save_level(i)); /* vadjust vs vadjust pre */
+ break;
+ case saved_insert:
+ tprint(", ");
+ print_int(save_value(i)); /* insert number */
+ break;
+ case saved_boxtype: /* \.{\\localleftbox} vs \.{\\localrightbox} */
+ tprint(", ");
+ print_int(save_value(i));
+ break;
+ case saved_eqno: /* \.{\\eqno} vs \.{\\leqno} */
+ tprint(", ");
+ print_int(save_value(i));
+ break;
+ case saved_disc:
+ case saved_choices:
+ tprint(", ");
+ print_int(save_value(i));
+ break;
+ case saved_math:
+ tprint(", listptr=");
+ print_int(save_value(i));
+ break;
+ case saved_boxcontext:
+ tprint(", ");
+ print_int(save_value(i));
+ break;
+ case saved_boxspec:
+ tprint(", spec=");
+ print_int(save_level(i));
+ tprint(", dimen=");
+ print_int(save_value(i));
+ break;
+ case saved_textdir:
+ case saved_boxdir:
+ tprint(", ");
+ print_dir(dir_dir(save_value(i)));
+ break;
+ case saved_boxattr:
+ tprint(", ");
+ print_int(save_value(i));
+ break;
+ case saved_line:
+ case saved_eqtb:
+ break;
+ default:
+ break;
+ }
+ print_ln();
+ }
+ end_diagnostic(true);
+}
+
+
+@ The \.{\\showgroups} command displays all currently active grouping
+ levels.
+
+
+@ The modifications of \TeX\ required for the display produced by the
+ |show_save_groups| procedure were first discussed by Donald~E. Knuth in
+ {\sl TUGboat\/} {\bf 11}, 165--170 and 499--511, 1990.
+ @^Knuth, Donald Ervin@>
+
+ In order to understand a group type we also have to know its mode.
+ Since unrestricted horizontal modes are not associated with grouping,
+ they are skipped when traversing the semantic nest.
+
+@c
+void show_save_groups(void)
+{
+ int p; /* index into |nest| */
+ int m; /* mode */
+ save_pointer v; /* saved value of |save_ptr| */
+ quarterword l; /* saved value of |cur_level| */
+ group_code c; /* saved value of |cur_group| */
+ int a; /* to keep track of alignments */
+ int i;
+ quarterword j;
+ const char *s;
+#ifdef DEBUG
+ print_save_stack();
+#endif
+ p = nest_ptr;
+ v = save_ptr;
+ l = cur_level;
+ c = cur_group;
+ save_ptr = cur_boundary;
+ decr(cur_level);
+ a = 1;
+ s = NULL;
+ tprint_nl("");
+ print_ln();
+ while (1) {
+ tprint_nl("### ");
+ print_group(true);
+ if (cur_group == bottom_level)
+ goto DONE;
+ do {
+ m = nest[p].mode_field;
+ if (p > 0)
+ decr(p);
+ else
+ m = vmode;
+ } while (m == hmode);
+ tprint(" (");
+ switch (cur_group) {
+ case simple_group:
+ incr(p);
+ goto FOUND2;
+ break;
+ case hbox_group:
+ case adjusted_hbox_group:
+ s = "hbox";
+ break;
+ case vbox_group:
+ s = "vbox";
+ break;
+ case vtop_group:
+ s = "vtop";
+ break;
+ case align_group:
+ if (a == 0) {
+ if (m == -vmode)
+ s = "halign";
+ else
+ s = "valign";
+ a = 1;
+ goto FOUND1;
+ } else {
+ if (a == 1)
+ tprint("align entry");
+ else
+ tprint_esc("cr");
+ if (p >= a)
+ p = p - a;
+ a = 0;
+ goto FOUND;
+ }
+ break;
+ case no_align_group:
+ incr(p);
+ a = -1;
+ tprint_esc("noalign");
+ goto FOUND2;
+ break;
+ case output_group:
+ tprint_esc("output");
+ goto FOUND;
+ break;
+ case math_group:
+ goto FOUND2;
+ break;
+ case disc_group:
+ tprint_esc("discretionary");
+ for (i = 1; i < 3; i++)
+ if (i <= saved_value(-2))
+ tprint("{}");
+ goto FOUND2;
+ break;
+ case math_choice_group:
+ tprint_esc("mathchoice");
+ for (i = 1; i < 4; i++)
+ if (i <= saved_value(-3)) /* different offset because |-2==saved_textdir| */
+ tprint("{}");
+ goto FOUND2;
+ break;
+ case insert_group:
+ if (saved_type(-1) == saved_adjust) {
+ tprint_esc("vadjust");
+ if (saved_level(-1) != 0)
+ tprint(" pre");
+ } else {
+ tprint_esc("insert");
+ print_int(saved_value(-1));
+ }
+ goto FOUND2;
+ break;
+ case vcenter_group:
+ s = "vcenter";
+ goto FOUND1;
+ break;
+ case semi_simple_group:
+ incr(p);
+ tprint_esc("begingroup");
+ goto FOUND;
+ break;
+ case math_shift_group:
+ if (m == mmode) {
+ print_char('$');
+ } else if (nest[p].mode_field == mmode) {
+ print_cmd_chr(eq_no_cmd, saved_value(-2));
+ goto FOUND;
+ }
+ print_char('$');
+ goto FOUND;
+ break;
+ case math_left_group:
+ if (subtype(nest[p + 1].eTeX_aux_field) == left_noad_side)
+ tprint_esc("left");
+ else
+ tprint_esc("middle");
+ goto FOUND;
+ break;
+ default:
+ confusion("showgroups");
+ break;
+ }
+ /* Show the box context */
+ i = saved_value(-5);
+ if (i != 0) {
+ if (i < box_flag) {
+ if (abs(nest[p].mode_field) == vmode)
+ j = hmove_cmd;
+ else
+ j = vmove_cmd;
+ if (i > 0)
+ print_cmd_chr(j, 0);
+ else
+ print_cmd_chr(j, 1);
+ print_scaled(abs(i));
+ tprint("pt");
+ } else if (i < ship_out_flag) {
+ if (i >= global_box_flag) {
+ tprint_esc("global");
+ i = i - (global_box_flag - box_flag);
+ }
+ tprint_esc("setbox");
+ print_int(i - box_flag);
+ print_char('=');
+ } else {
+ print_cmd_chr(leader_ship_cmd, i - (leader_flag - a_leaders));
+ }
+ }
+ FOUND1:
+ tprint_esc(s);
+ /* Show the box packaging info */
+ {
+ /* offsets may vary */
+ int ii = -1;
+ while (saved_type(ii) != saved_boxspec)
+ ii--;
+ if (saved_value(ii) != 0) {
+ print_char(' ');
+ if (saved_level(ii) == exactly)
+ tprint("to");
+ else
+ tprint("spread");
+ print_scaled(saved_value(ii));
+ tprint("pt");
+ }
+ }
+ FOUND2:
+ print_char('{');
+ FOUND:
+ print_char(')');
+ decr(cur_level);
+ cur_group = save_level(save_ptr);
+ save_ptr = save_value(save_ptr);
+ }
+ DONE:
+ save_ptr = v;
+ cur_level = l;
+ cur_group = c;
+}
+
+
+
+@ Just before an entry of |eqtb| is changed, the following procedure should
+be called to update the other data structures properly. It is important
+to keep in mind that reference counts in |mem| include references from
+within |save_stack|, so these counts must be handled carefully.
+@^reference counts@>
+
+@c
+void eq_destroy(memory_word w)
+{ /* gets ready to forget |w| */
+ halfword q; /* |equiv| field of |w| */
+ switch (eq_type_field(w)) {
+ case call_cmd:
+ case long_call_cmd:
+ case outer_call_cmd:
+ case long_outer_call_cmd:
+ delete_token_ref(equiv_field(w));
+ break;
+ case glue_ref_cmd:
+ delete_glue_ref(equiv_field(w));
+ break;
+ case shape_ref_cmd:
+ q = equiv_field(w); /* we need to free a \.{\\parshape} block */
+ if (q != null)
+ flush_node(q);
+ break; /* such a block is |2n+1| words long, where |n=vinfo(q)| */
+ case box_ref_cmd:
+ flush_node_list(equiv_field(w));
+ break;
+ default:
+ break;
+ }
+}
+
+
+@ To save a value of |eqtb[p]| that was established at level |l|, we
+can use the following subroutine.
+
+@c
+void eq_save(halfword p, quarterword l)
+{ /* saves |eqtb[p]| */
+ check_full_save_stack();
+ if (l == level_zero) {
+ save_type(save_ptr) = restore_zero;
+ } else {
+ save_word(save_ptr) = eqtb[p];
+ save_type(save_ptr) = saved_eqtb;
+ incr(save_ptr);
+ save_type(save_ptr) = restore_old_value;
+ }
+ save_level(save_ptr) = l;
+ save_value(save_ptr) = p;
+ incr(save_ptr);
+}
+
+
+@ The procedure |eq_define| defines an |eqtb| entry having specified
+|eq_type| and |equiv| fields, and saves the former value if appropriate.
+This procedure is used only for entries in the first four regions of |eqtb|,
+i.e., only for entries that have |eq_type| and |equiv| fields.
+After calling this routine, it is safe to put four more entries on
+|save_stack|, provided that there was room for four more entries before
+the call, since |eq_save| makes the necessary test.
+
+@c
+void eq_define(halfword p, quarterword t, halfword e)
+{ /* new data for |eqtb| */
+ if ((eq_type(p) == t) && (equiv(p) == e)) {
+ assign_trace(p, "reassigning");
+ eq_destroy(eqtb[p]);
+ return;
+ }
+ assign_trace(p, "changing");
+ if (eq_level(p) == cur_level)
+ eq_destroy(eqtb[p]);
+ else if (cur_level > level_one)
+ eq_save(p, eq_level(p));
+ set_eq_level(p, cur_level);
+ set_eq_type(p, t);
+ set_equiv(p, e);
+ assign_trace(p, "into");
+}
+
+
+@ The counterpart of |eq_define| for the remaining (fullword) positions in
+|eqtb| is called |eq_word_define|. Since |xeq_level[p]>=level_one| for all
+|p|, a `|restore_zero|' will never be used in this case.
+
+@c
+void eq_word_define(halfword p, int w)
+{
+ if (eqtb[p].cint == w) {
+ assign_trace(p, "reassigning");
+ return;
+ }
+ assign_trace(p, "changing");
+ if (xeq_level[p] != cur_level) {
+ eq_save(p, xeq_level[p]);
+ xeq_level[p] = cur_level;
+ }
+ eqtb[p].cint = w;
+ assign_trace(p, "into");
+}
+
+
+@ The |eq_define| and |eq_word_define| routines take care of local definitions.
+@^global definitions@>
+Global definitions are done in almost the same way, but there is no need
+to save old values, and the new value is associated with |level_one|.
+
+@c
+void geq_define(halfword p, quarterword t, halfword e)
+{ /* global |eq_define| */
+ assign_trace(p, "globally changing");
+ eq_destroy(eqtb[p]);
+ set_eq_level(p, level_one);
+ set_eq_type(p, t);
+ set_equiv(p, e);
+ assign_trace(p, "into");
+}
+
+void geq_word_define(halfword p, int w)
+{ /* global |eq_word_define| */
+ assign_trace(p, "globally changing");
+ eqtb[p].cint = w;
+ xeq_level[p] = level_one;
+ assign_trace(p, "into");
+}
+
+
+@ Subroutine |save_for_after| puts a token on the stack for save-keeping.
+
+@c
+void save_for_after(halfword t)
+{
+ if (cur_level > level_one) {
+ check_full_save_stack();
+ save_type(save_ptr) = insert_token;
+ save_level(save_ptr) = level_zero;
+ save_value(save_ptr) = t;
+ incr(save_ptr);
+ }
+}
+
+
+@ The |unsave| routine goes the other way, taking items off of |save_stack|.
+This routine takes care of restoration when a level ends; everything
+belonging to the topmost group is cleared off of the save stack.
+
+@c
+void unsave(void)
+{ /* pops the top level off the save stack */
+ halfword p; /* position to be restored */
+ quarterword l; /* saved level, if in fullword regions of |eqtb| */
+ boolean a; /* have we already processed an \.{\\aftergroup} ? */
+ a = false;
+ l = level_one; /* just in case */
+ unsave_math_codes(cur_level);
+ unsave_cat_codes(int_par(cat_code_table_code), cur_level);
+ unsave_text_codes(cur_level);
+ unsave_math_data(cur_level);
+ if (cur_level > level_one) {
+ decr(cur_level);
+ /* Clear off top level from |save_stack| */
+ while (true) {
+ decr(save_ptr);
+ if (save_type(save_ptr) == level_boundary)
+ break;
+ p = save_value(save_ptr);
+ if (save_type(save_ptr) == insert_token) {
+ a = reinsert_token(a, p);
+ } else {
+ if (save_type(save_ptr) == restore_old_value) {
+ l = save_level(save_ptr);
+ decr(save_ptr);
+ } else {
+ save_word(save_ptr) = eqtb[undefined_control_sequence];
+ }
+ /* Store |save_stack[save_ptr]| in |eqtb[p]|, unless
+ |eqtb[p]| holds a global value */
+ /* A global definition, which sets the level to |level_one|,
+ will not be undone by |unsave|. If at least one global definition of
+ |eqtb[p]| has been carried out within the group that just ended, the
+ last such definition will therefore survive.
+ */
+ if (p < int_base || p > eqtb_size) {
+ if (eq_level(p) == level_one) {
+ eq_destroy(save_word(save_ptr)); /* destroy the saved value */
+ if (int_par(tracing_restores_code) > 0)
+ restore_trace(p, "retaining");
+ } else {
+ eq_destroy(eqtb[p]); /* destroy the current value */
+ eqtb[p] = save_word(save_ptr); /* restore the saved value */
+ if (int_par(tracing_restores_code) > 0)
+ restore_trace(p, "restoring");
+ }
+ } else if (xeq_level[p] != level_one) {
+ eqtb[p] = save_word(save_ptr);
+ xeq_level[p] = l;
+ if (int_par(tracing_restores_code) > 0)
+ restore_trace(p, "restoring");
+ } else {
+ if (int_par(tracing_restores_code) > 0)
+ restore_trace(p, "retaining");
+ }
+
+ }
+ }
+ if (int_par(tracing_groups_code) > 0)
+ group_trace(true);
+ if (grp_stack[in_open] == cur_boundary)
+ group_warning(); /* groups possibly not properly nested with files */
+ cur_group = save_level(save_ptr);
+ cur_boundary = save_value(save_ptr);
+ decr(save_ptr);
+
+ } else {
+ confusion("curlevel"); /* |unsave| is not used when |cur_group=bottom_level| */
+ }
+ attr_list_cache = cache_disabled;
+}
+
+@ @c
+void restore_trace(halfword p, const char *s)
+{ /* |eqtb[p]| has just been restored or retained */
+ begin_diagnostic();
+ print_char('{');
+ tprint(s);
+ print_char(' ');
+ show_eqtb(p);
+ print_char('}');
+ end_diagnostic(false);
+}
+
+
+@ Most of the parameters kept in |eqtb| can be changed freely, but there's
+an exception: The magnification should not be used with two different
+values during any \TeX\ job, since a single magnification is applied to an
+entire run. The global variable |mag_set| is set to the current magnification
+whenever it becomes necessary to ``freeze'' it at a particular value.
+
+@c
+int mag_set; /* if nonzero, this magnification should be used henceforth */
+
+
+@ The |prepare_mag| subroutine is called whenever \TeX\ wants to use |mag|
+for magnification.
+
+@c
+#define mag int_par(mag_code)
+
+void prepare_mag(void)
+{
+ if ((mag_set > 0) && (mag != mag_set)) {
+ print_err("Incompatible magnification (");
+ print_int(mag);
+ tprint(");");
+ tprint_nl(" the previous value will be retained");
+ help2("I can handle only one magnification ratio per job. So I've",
+ "reverted to the magnification you used earlier on this run.");
+ int_error(mag_set);
+ geq_word_define(int_base + mag_code, mag_set); /* |mag:=mag_set| */
+ }
+ if ((mag <= 0) || (mag > 32768)) {
+ print_err("Illegal magnification has been changed to 1000");
+ help1("The magnification ratio must be between 1 and 32768.");
+ int_error(mag);
+ geq_word_define(int_base + mag_code, 1000);
+ }
+ if ((mag_set == 0) && (mag != mag_set)) {
+ if (mag != 1000)
+ one_true_inch = xn_over_d(one_hundred_inch, 10, mag);
+ else
+ one_true_inch = one_inch;
+ }
+ mag_set = mag;
+}
+
+
+@ Let's pause a moment now and try to look at the Big Picture.
+The \TeX\ program consists of three main parts: syntactic routines,
+semantic routines, and output routines. The chief purpose of the
+syntactic routines is to deliver the user's input to the semantic routines,
+one token at a time. The semantic routines act as an interpreter
+responding to these tokens, which may be regarded as commands. And the
+output routines are periodically called on to convert box-and-glue
+lists into a compact set of instructions that will be sent
+to a typesetter. We have discussed the basic data structures and utility
+routines of \TeX, so we are good and ready to plunge into the real activity by
+considering the syntactic routines.
+
+Our current goal is to come to grips with the |get_next| procedure,
+which is the keystone of \TeX's input mechanism. Each call of |get_next|
+sets the value of three variables |cur_cmd|, |cur_chr|, and |cur_cs|,
+representing the next input token.
+$$\vbox{\halign{#\hfil\cr
+ \hbox{|cur_cmd| denotes a command code from the long list of codes
+ given above;}\cr
+ \hbox{|cur_chr| denotes a character code or other modifier of the command
+ code;}\cr
+ \hbox{|cur_cs| is the |eqtb| location of the current control sequence,}\cr
+ \hbox{\qquad if the current token was a control sequence,
+ otherwise it's zero.}\cr}}$$
+Underlying this external behavior of |get_next| is all the machinery
+necessary to convert from character files to tokens. At a given time we
+may be only partially finished with the reading of several files (for
+which \.{\\input} was specified), and partially finished with the expansion
+of some user-defined macros and/or some macro parameters, and partially
+finished with the generation of some text in a template for \.{\\halign},
+and so on. When reading a character file, special characters must be
+classified as math delimiters, etc.; comments and extra blank spaces must
+be removed, paragraphs must be recognized, and control sequences must be
+found in the hash table. Furthermore there are occasions in which the
+scanning routines have looked ahead for a word like `\.{plus}' but only
+part of that word was found, hence a few characters must be put back
+into the input and scanned again.
+
+To handle these situations, which might all be present simultaneously,
+\TeX\ uses various stacks that hold information about the incomplete
+activities, and there is a finite state control for each level of the
+input mechanism. These stacks record the current state of an implicitly
+recursive process, but the |get_next| procedure is not recursive.
+Therefore it will not be difficult to translate these algorithms into
+low-level languages that do not support recursion.
+
+@c
+int cur_cmd; /* current command set by |get_next| */
+halfword cur_chr; /* operand of current command */
+halfword cur_cs; /* control sequence found here, zero if none found */
+halfword cur_tok; /* packed representative of |cur_cmd| and |cur_chr| */
+
+@ Here is a procedure that displays the current command.
+
+@c
+#define mode cur_list.mode_field
+
+void show_cur_cmd_chr(void)
+{
+ int n; /* level of \.{\\if...\\fi} nesting */
+ int l; /* line where \.{\\if} started */
+ halfword p;
+ begin_diagnostic();
+ tprint_nl("{");
+ if (mode != shown_mode) {
+ print_mode(mode);
+ tprint(": ");
+ shown_mode = mode;
+ }
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ if (int_par(tracing_ifs_code) > 0) {
+ if (cur_cmd >= if_test_cmd) {
+ if (cur_cmd <= fi_or_else_cmd) {
+ tprint(": ");
+ if (cur_cmd == fi_or_else_cmd) {
+ print_cmd_chr(if_test_cmd, cur_if);
+ print_char(' ');
+ n = 0;
+ l = if_line;
+ } else {
+ n = 1;
+ l = line;
+ }
+ p = cond_ptr;
+ while (p != null) {
+ incr(n);
+ p = vlink(p);
+ }
+ tprint("(level ");
+ print_int(n);
+ print_char(')');
+ print_if_line(l);
+ }
+ }
+ }
+ print_char('}');
+ end_diagnostic(false);
+}
+
+
+@ Here is a procedure that displays the contents of |eqtb[n]|
+ symbolically.
+
+@c
+void show_eqtb(halfword n)
+{
+ if (n < null_cs) {
+ print_char('?'); /* this can't happen */
+ } else if ((n < glue_base) || ((n > eqtb_size) && (n <= eqtb_top))) {
+ /* Show equivalent |n|, in region 1 or 2 */
+ /* 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.) */
+
+ sprint_cs(n);
+ print_char('=');
+ print_cmd_chr(eq_type(n), equiv(n));
+ if (eq_type(n) >= call_cmd) {
+ print_char(':');
+ show_token_list(token_link(equiv(n)), null, 32);
+ }
+ } else if (n < local_base) {
+ /* Show equivalent |n|, in region 3 */
+ /* All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'. */
+ if (n < skip_base) {
+ if (n < glue_base + thin_mu_skip_code)
+ print_cmd_chr(assign_glue_cmd, n);
+ else
+ print_cmd_chr(assign_mu_glue_cmd, n);
+ print_char('=');
+ if (n < glue_base + thin_mu_skip_code)
+ print_spec(equiv(n), "pt");
+ else
+ print_spec(equiv(n), "mu");
+ } else if (n < mu_skip_base) {
+ tprint_esc("skip");
+ print_int(n - skip_base);
+ print_char('=');
+ print_spec(equiv(n), "pt");
+ } else {
+ tprint_esc("muskip");
+ print_int(n - mu_skip_base);
+ print_char('=');
+ print_spec(equiv(n), "mu");
+ }
+
+ } else if (n < int_base) {
+ /* Show equivalent |n|, in region 4 */
+ /* We initialize most things to null or undefined values. An undefined font
+ is represented by the internal code |font_base|.
+
+ However, the character code tables are given initial values based on the
+ conventional interpretation of ASCII code. These initial values should
+ not be changed when \TeX\ is adapted for use with non-English languages;
+ all changes to the initialization conventions should be made in format
+ packages, not in \TeX\ itself, so that global interchange of formats is
+ possible. */
+ if ((n == par_shape_loc) || ((n >= etex_pen_base) && (n < etex_pens))) {
+ if (n == par_shape_loc)
+ print_cmd_chr(set_tex_shape_cmd, n);
+ else
+ print_cmd_chr(set_etex_shape_cmd, n);
+ print_char('=');
+ if (equiv(n) == null) {
+ print_char('0');
+ } else if (n > par_shape_loc) {
+ print_int(penalty(equiv(n)));
+ print_char(' ');
+ print_int(penalty(equiv(n) + 1));
+ if (penalty(equiv(n)) > 1)
+ tprint_esc("ETC.");
+ } else {
+ print_int(vinfo(par_shape_ptr + 1));
+ }
+ } else if (n < toks_base) {
+ /* TODO make extra cases for ocps here! */
+ print_cmd_chr(assign_toks_cmd, n);
+ print_char('=');
+ if (equiv(n) != null)
+ show_token_list(token_link(equiv(n)), null, 32);
+ } else if (n < box_base) {
+ tprint_esc("toks");
+ print_int(n - toks_base);
+ print_char('=');
+ if (equiv(n) != null)
+ show_token_list(token_link(equiv(n)), null, 32);
+ } else if (n < cur_font_loc) {
+ tprint_esc("box");
+ print_int(n - box_base);
+ print_char('=');
+ if (equiv(n) == null) {
+ tprint("void");
+ } else {
+ depth_threshold = 0;
+ breadth_max = 1;
+ show_node_list(equiv(n));
+ }
+ } else if (n == cur_font_loc) {
+ /* Show the font identifier in |eqtb[n]| */
+ tprint("current font");
+ print_char('=');
+ print_esc(hash[font_id_base + equiv(n)].rh); /* that's |font_id_text(equiv(n))| */
+ }
+
+ } else if (n < dimen_base) {
+ /* Show equivalent |n|, in region 5 */
+ if (n < dir_base) {
+ print_cmd_chr(assign_int_cmd, n);
+ print_char('=');
+ print_int(eqtb[n].cint);
+ } else if (n < count_base) {
+ print_cmd_chr(assign_dir_cmd, n);
+ print_char(' ');
+ print_dir(eqtb[n].cint);
+ } else if (n < attribute_base) {
+ tprint_esc("count");
+ print_int(n - count_base);
+ print_char('=');
+ print_int(eqtb[n].cint);
+ } else if (n < del_code_base) {
+ tprint_esc("attribute");
+ print_int(n - attribute_base);
+ print_char('=');
+ print_int(eqtb[n].cint);
+ }
+
+ } else if (n <= eqtb_size) {
+ /* Show equivalent |n|, in region 6 */
+ if (n < scaled_base) {
+ print_cmd_chr(assign_dimen_cmd, n);
+ } else {
+ tprint_esc("dimen");
+ print_int(n - scaled_base);
+ }
+ print_char('=');
+ print_scaled(eqtb[n].cint);
+ tprint("pt");
+
+ } else {
+ print_char('?'); /* this can't happen either */
+ }
+}
+
+@ @c
+void show_eqtb_meaning(halfword n)
+{
+ if (n < null_cs) {
+ print_char('?'); /* this can't happen */
+ } else if ((n < glue_base) || ((n > eqtb_size) && (n <= eqtb_top))) {
+ /* Show equivalent |n|, in region 1 or 2 */
+ /* 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.) */
+
+ sprint_cs(n);
+ } else if (n < local_base) {
+ /* Show equivalent |n|, in region 3 */
+ /* All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'. */
+ if (n < skip_base) {
+ if (n < glue_base + thin_mu_skip_code)
+ print_cmd_chr(assign_glue_cmd, n);
+ else
+ print_cmd_chr(assign_mu_glue_cmd, n);
+ } else if (n < mu_skip_base) {
+ tprint_esc("skip");
+ print_int(n - skip_base);
+ } else {
+ tprint_esc("muskip");
+ print_int(n - mu_skip_base);
+ }
+
+ } else if (n < int_base) {
+ /* Show equivalent |n|, in region 4 */
+ /* We initialize most things to null or undefined values. An undefined font
+ is represented by the internal code |font_base|.
+
+ However, the character code tables are given initial values based on the
+ conventional interpretation of ASCII code. These initial values should
+ not be changed when \TeX\ is adapted for use with non-English languages;
+ all changes to the initialization conventions should be made in format
+ packages, not in \TeX\ itself, so that global interchange of formats is
+ possible. */
+ if ((n == par_shape_loc) || ((n >= etex_pen_base) && (n < etex_pens))) {
+ if (n == par_shape_loc)
+ print_cmd_chr(set_tex_shape_cmd, n);
+ else
+ print_cmd_chr(set_etex_shape_cmd, n);
+ } else if (n < toks_base) {
+ /* TODO make extra cases for ocps here! */
+ print_cmd_chr(assign_toks_cmd, n);
+ } else if (n < box_base) {
+ tprint_esc("toks");
+ print_int(n - toks_base);
+ } else if (n < cur_font_loc) {
+ tprint_esc("box");
+ print_int(n - box_base);
+ } else if (n == cur_font_loc) {
+ /* Show the font identifier in |eqtb[n]| */
+ tprint("current font");
+ }
+
+ } else if (n < dimen_base) {
+ /* Show equivalent |n|, in region 5 */
+ if (n < dir_base) {
+ print_cmd_chr(assign_int_cmd, n);
+ } else if (n < count_base) {
+ print_cmd_chr(assign_dir_cmd, n);
+ } else if (n < attribute_base) {
+ tprint_esc("count");
+ print_int(n - count_base);
+ } else if (n < del_code_base) {
+ tprint_esc("attribute");
+ print_int(n - attribute_base);
+ }
+
+ } else if (n <= eqtb_size) {
+ /* Show equivalent |n|, in region 6 */
+ if (n < scaled_base) {
+ print_cmd_chr(assign_dimen_cmd, n);
+ } else {
+ tprint_esc("dimen");
+ print_int(n - scaled_base);
+ }
+ } else {
+ print_char('?'); /* this can't happen either */
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.h b/Build/source/texk/web2c/luatexdir/tex/errors.h
new file mode 100644
index 00000000000..2d55e31aa75
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/errors.h
@@ -0,0 +1,102 @@
+/* errors.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: errors.h 3385 2010-01-26 05:45:55Z taco $ */
+
+#ifndef ERRORS_H
+# define ERRORS_H
+
+/*
+The global variable |interaction| has four settings, representing increasing
+amounts of user interaction:
+*/
+
+typedef enum {
+ batch_mode = 0, /* omits all stops and omits terminal output */
+ nonstop_mode = 1, /* omits all stops */
+ scroll_mode = 2, /* omits error stops */
+ error_stop_mode = 3, /* stops at every opportunity to interact */
+ unspecified_mode = 4, /* extra value for command-line switch */
+} interaction_settings;
+
+extern int interaction; /* current level of interaction */
+extern int interactionoption; /* set from command line */
+extern const char *last_error;
+
+extern void initialize_errors(void);
+extern void print_err(const char *s);
+
+extern void fixup_selector(boolean log_opened);
+
+extern boolean deletions_allowed;
+extern boolean set_box_allowed;
+extern int history;
+extern int error_count;
+extern int interrupt;
+extern boolean OK_to_interrupt;
+
+typedef enum {
+ spotless = 0, /* |history| value when nothing has been amiss yet */
+ warning_issued = 1, /* |history| value when |begin_diagnostic| has been called */
+ error_message_issued = 2, /* |history| value when |error| has been called */
+ fatal_error_stop = 3, /* |history| value when termination was premature */
+} error_states;
+
+extern const char *help_line[7]; /* helps for the next |error| */
+extern boolean use_err_help; /* should the |err_help| list be shown? */
+
+/* these macros are just temporary, until everything is in C */
+
+# define hlp1(A) help_line[0]=A
+# define hlp2(A,B) help_line[1]=A; hlp1(B)
+# define hlp3(A,B,C) help_line[2]=A; hlp2(B,C)
+# define hlp4(A,B,C,D) help_line[3]=A; hlp3(B,C,D)
+# define hlp5(A,B,C,D,E) help_line[4]=A; hlp4(B,C,D,E)
+# define hlp6(A,B,C,D,E,F) help_line[5]=A; hlp5(B,C,D,E,F)
+
+# define help0() help_line[0]=NULL /* sometimes there might be no help */
+# define help1(A) do { help_line[1]=NULL; hlp1(A); } while (0)
+# define help2(A,B) do { help_line[2]=NULL; hlp2(B,A); } while (0)
+# define help3(A,B,C) do { help_line[3]=NULL; hlp3(C,B,A); } while (0)
+# define help4(A,B,C,D) do { help_line[4]=NULL; hlp4(D,C,B,A); } while (0)
+# define help5(A,B,C,D,E) do { help_line[5]=NULL; hlp5(E,D,C,B,A); } while (0)
+# define help6(A,B,C,D,E,F) do { help_line[6]=NULL; hlp6(F,E,D,C,B,A); } while (0)
+
+extern void do_final_end(void);
+extern void jump_out(void);
+extern void error(void);
+extern void int_error(int n);
+extern void normalize_selector(void);
+extern void succumb(void);
+extern void fatal_error(const char *s);
+extern void lua_norm_error(const char *s);
+extern void lua_fatal_error(const char *s);
+extern void overflow(const char *s, unsigned int n);
+extern void confusion(const char *s);
+extern void check_interrupt(void);
+extern void pause_for_instructions(void);
+
+extern void tex_error(const char *msg, const char **hlp);
+
+extern void back_error(void);
+extern void ins_error(void);
+
+extern void char_warning(internal_font_number f, int c);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.w b/Build/source/texk/web2c/luatexdir/tex/errors.w
new file mode 100644
index 00000000000..5565605e6a2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/errors.w
@@ -0,0 +1,625 @@
+% errors.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: errors.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/errors.w $";
+
+@ @c
+#define new_line_char int_par(new_line_char_code)
+
+
+@ When something anomalous is detected, \TeX\ typically does something like this:
+$$\vbox{\halign{#\hfil\cr
+|print_err("Something anomalous has been detected");|\cr
+|help3("This is the first line of my offer to help.")|\cr
+|("This is the second line. I'm trying to")|\cr
+|("explain the best way for you to proceed.");|\cr
+|error;|\cr}}$$
+A two-line help message would be given using |help2|, etc.; these informal
+helps should use simple vocabulary that complements the words used in the
+official error message that was printed. (Outside the U.S.A., the help
+messages should preferably be translated into the local vernacular. Each
+line of help is at most 60 characters long, in the present implementation,
+so that |max_print_line| will not be exceeded.)
+
+The |print_err| procedure supplies a `\.!' before the official message,
+and makes sure that the terminal is awake if a stop is going to occur.
+The |error| procedure supplies a `\..' after the official message, then it
+shows the location of the error; and if |interaction=error_stop_mode|,
+it also enters into a dialog with the user, during which time the help
+message may be printed.
+@^system dependencies@>
+
+@c
+int interaction; /* current level of interaction */
+int interactionoption; /* set from command line */
+const char *last_error;
+
+void print_err(const char *s)
+{
+ if (interaction == error_stop_mode) {
+ wake_up_terminal();
+ }
+ if (filelineerrorstylep)
+ print_file_line();
+ else
+ tprint_nl("! ");
+ tprint(s);
+ last_error = (const char *) s;
+}
+
+
+@ \TeX\ is careful not to call |error| when the print |selector| setting
+might be unusual. The only possible values of |selector| at the time of
+error messages are
+
+\yskip\hang|no_print| (when |interaction=batch_mode|
+ and |log_file| not yet open);
+
+\hang|term_only| (when |interaction>batch_mode| and |log_file| not yet open);
+
+\hang|log_only| (when |interaction=batch_mode| and |log_file| is open);
+
+\hang|term_and_log| (when |interaction>batch_mode| and |log_file| is open).
+
+@c
+void fixup_selector(boolean log_opened)
+{
+ if (interaction == batch_mode)
+ selector = no_print;
+ else
+ selector = term_only;
+ if (log_opened)
+ selector = selector + 2;
+}
+
+
+@ A global variable |deletions_allowed| is set |false| if the |get_next|
+routine is active when |error| is called; this ensures that |get_next|
+and related routines like |get_token| will never be called recursively.
+A similar interlock is provided by |set_box_allowed|.
+@^recursion@>
+
+The global variable |history| records the worst level of error that
+has been detected. It has four possible values: |spotless|, |warning_issued|,
+|error_message_issued|, and |fatal_error_stop|.
+
+Another global variable, |error_count|, is increased by one when an
+|error| occurs without an interactive dialog, and it is reset to zero at
+the end of every paragraph. If |error_count| reaches 100, \TeX\ decides
+that there is no point in continuing further.
+
+@c
+boolean deletions_allowed; /* is it safe for |error| to call |get_token|? */
+boolean set_box_allowed; /* is it safe to do a \.{\\setbox} assignment? */
+int history; /* has the source input been clean so far? */
+int error_count; /* the number of scrolled errors since the last paragraph ended */
+int interrupt; /* should \TeX\ pause for instructions? */
+boolean OK_to_interrupt; /* should interrupts be observed? */
+
+
+
+@ The value of |history| is initially |fatal_error_stop|, but it will
+be changed to |spotless| if \TeX\ survives the initialization process.
+
+@c
+void initialize_errors(void)
+{
+ if (interactionoption == unspecified_mode)
+ interaction = error_stop_mode;
+ else
+ interaction = interactionoption;
+ deletions_allowed = true;
+ set_box_allowed = true;
+ OK_to_interrupt = true;
+ /* |history| is initialized elsewhere */
+}
+
+
+@ It is possible for |error| to be called recursively if some error arises
+when |get_token| is being used to delete a token, and/or if some fatal error
+occurs while \TeX\ is trying to fix a non-fatal one. But such recursion
+@^recursion@>
+is never more than two levels deep.
+
+@ Individual lines of help are recorded in the array |help_line|.
+
+@c
+const char *help_line[7]; /* helps for the next |error| */
+boolean use_err_help; /* should the |err_help| list be shown? */
+
+
+@ The |jump_out| procedure just cuts across all active procedure levels and
+exits the program. It is used when there is no recovery from a particular error.
+
+@c
+__attribute__ ((noreturn))
+void do_final_end(void)
+{
+ update_terminal();
+ ready_already = 0;
+ if ((history != spotless) && (history != warning_issued))
+ uexit(1);
+ else
+ uexit(0);
+}
+
+__attribute__ ((noreturn))
+void jump_out(void)
+{
+ close_files_and_terminate();
+ do_final_end();
+}
+
+@ @c
+void error(void)
+{ /* completes the job of error reporting */
+ ASCII_code c; /* what the user types */
+ int callback_id;
+ int s1, s2, s3, s4; /* used to save global variables when deleting tokens */
+ boolean t;
+ int i;
+ if (history < error_message_issued)
+ history = error_message_issued;
+ print_char('.');
+ callback_id = callback_defined(show_error_hook_callback);
+ if (callback_id > 0)
+ t = run_callback(callback_id, "->");
+ show_context();
+ if (haltonerrorp) {
+ history = fatal_error_stop;
+ jump_out();
+ }
+ if (interaction == error_stop_mode) {
+ /* Get user's advice and |return| */
+ while (1) {
+ CONTINUE:
+ clear_for_error_prompt();
+ prompt_input("? ");
+ if (last == first)
+ return;
+ c = buffer[first];
+ if (c >= 'a')
+ c = c + 'A' - 'a'; /* convert to uppercase */
+ /* Interpret code |c| and |return| if done */
+
+ /* It is desirable to provide an `\.E' option here that gives the user
+ an easy way to return from \TeX\ to the system editor, with the offending
+ 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.
+
+ There is a secret `\.D' option available when the debugging routines haven't
+ been commented~out. */
+
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (deletions_allowed) {
+ /* Delete |c-"0"| tokens and |goto continue| */
+ /* We allow deletion of up to 99 tokens at a time */
+ s1 = cur_tok;
+ s2 = cur_cmd;
+ s3 = cur_chr;
+ s4 = align_state;
+ align_state = 1000000;
+ OK_to_interrupt = false;
+ if ((last > first + 1) && (buffer[first + 1] >= '0')
+ && (buffer[first + 1] <= '9'))
+ c = c * 10 + buffer[first + 1] - '0' * 11;
+ else
+ c = c - '0';
+ while (c > 0) {
+ get_token(); /* one-level recursive call of |error| is possible */
+ decr(c);
+ }
+ cur_tok = s1;
+ cur_cmd = s2;
+ cur_chr = s3;
+ align_state = s4;
+ OK_to_interrupt = true;
+ help2("I have just deleted some text, as you asked.",
+ "You can now delete more, or insert, or whatever.");
+ show_context();
+ goto CONTINUE;
+ }
+ break;
+#ifdef DEBUG
+ case 'D':
+ debug_help();
+ goto CONTINUE;
+ break;
+#endif
+ case 'E':
+ if (base_ptr > 0) {
+ tprint_nl("You want to edit file ");
+ slow_print(input_stack[base_ptr].name_field);
+ tprint(" at line ");
+ print_int(line);
+ interaction = scroll_mode;
+ jump_out();
+ }
+ break;
+ case 'H':
+ /* Print the help information and |goto continue| */
+ if (use_err_help) {
+ give_err_help();
+ use_err_help = false;
+ } else {
+ if (help_line[0] == NULL) {
+ help2
+ ("Sorry, I don't know how to help in this situation.",
+ "Maybe you should try asking a human?");
+ }
+ i = 0;
+ while (help_line[i] != NULL)
+ tprint_nl(help_line[i++]);
+ help4("Sorry, I already gave what help I could...",
+ "Maybe you should try asking a human?",
+ "An error might have occurred before I noticed any problems.",
+ "``If all else fails, read the instructions.''");
+ goto CONTINUE;
+ }
+ break;
+ case 'I':
+ /* Introduce new material from the terminal and |return| */
+ /* When the following code is executed, |buffer[(first+1)..(last-1)]| may
+ contain the material inserted by the user; otherwise another prompt will
+ be given. In order to understand this part of the program fully, you need
+ to be familiar with \TeX's input stacks. */
+
+ begin_file_reading(); /* enter a new syntactic level for terminal input */
+ /* now |state=mid_line|, so an initial blank space will count as a blank */
+ if (last > first + 1) {
+ iloc = first + 1;
+ buffer[first] = ' ';
+ } else {
+ prompt_input("insert>");
+ iloc = first;
+ }
+ first = last;
+ ilimit = last - 1; /* no |end_line_char| ends this line */
+ return;
+ break;
+ case 'Q':
+ case 'R':
+ case 'S':
+ /* Change the interaction level and |return| */
+ /* Here the author of \TeX\ apologizes for making use of the numerical
+ relation between |"Q"|, |"R"|, |"S"|, and the desired interaction settings
+ |batch_mode|, |nonstop_mode|, |scroll_mode|. */
+ error_count = 0;
+ interaction = batch_mode + c - 'Q';
+ tprint("OK, entering ");
+ switch (c) {
+ case 'Q':
+ tprint_esc("batchmode");
+ decr(selector);
+ break;
+ case 'R':
+ tprint_esc("nonstopmode");
+ break;
+ case 'S':
+ tprint_esc("scrollmode");
+ break;
+ }
+ tprint("...");
+ print_ln();
+ update_terminal();
+ return;
+ break;
+ case 'X':
+ interaction = scroll_mode;
+ jump_out();
+ break;
+ default:
+ break;
+ }
+ /* Print the menu of available options */
+ tprint
+ ("Type <return> to proceed, S to scroll future error messages,");
+ tprint_nl("R to run without stopping, Q to run quietly,");
+ tprint_nl("I to insert something, ");
+ if (base_ptr > 0)
+ tprint("E to edit your file,");
+ if (deletions_allowed)
+ tprint_nl
+ ("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
+ tprint_nl("H for help, X to quit.");
+ }
+
+ }
+ incr(error_count);
+ if (error_count == 100) {
+ tprint_nl("(That makes 100 errors; please try again.)");
+ history = fatal_error_stop;
+ jump_out();
+ }
+ /* Put help message on the transcript file */
+ if (interaction > batch_mode)
+ decr(selector); /* avoid terminal output */
+ if (use_err_help) {
+ print_ln();
+ give_err_help();
+ } else {
+ int i = 0;
+ while (help_line[i] != NULL)
+ tprint_nl(help_line[i++]);
+ }
+ print_ln();
+ if (interaction > batch_mode)
+ incr(selector); /* re-enable terminal output */
+ print_ln();
+}
+
+
+
+@ A dozen or so error messages end with a parenthesized integer, so we
+save a teeny bit of program space by declaring the following procedure:
+
+@c
+void int_error(int n)
+{
+ tprint(" (");
+ print_int(n);
+ print_char(')');
+ error();
+}
+
+
+@ In anomalous cases, the print selector might be in an unknown state;
+the following subroutine is called to fix things just enough to keep
+running a bit longer.
+
+@c
+void normalize_selector(void)
+{
+ if (log_opened)
+ selector = term_and_log;
+ else
+ selector = term_only;
+ if (job_name == 0)
+ open_log_file();
+ if (interaction == batch_mode)
+ decr(selector);
+}
+
+@ The following procedure prints \TeX's last words before dying
+@c
+void succumb(void)
+{
+ if (interaction == error_stop_mode)
+ interaction = scroll_mode; /* no more interaction */
+ if (log_opened)
+ error();
+#ifdef DEBUG
+ if (interaction > batch_mode)
+ debug_help();
+#endif
+ history = fatal_error_stop;
+ jump_out(); /* irrecoverable error */
+}
+
+@ @c
+void fatal_error(const char *s)
+{ /* prints |s|, and that's it */
+ normalize_selector();
+ print_err("Emergency stop");
+ help1(s);
+ succumb();
+}
+
+@ @c
+void lua_norm_error(const char *s)
+{ /* lua found a problem */
+ int saved_new_line_char;
+ saved_new_line_char = new_line_char;
+ new_line_char = 10;
+ print_err("LuaTeX error ");
+ tprint(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;
+}
+
+@ @c
+void lua_fatal_error(const char *s)
+{ /* lua found a problem */
+ new_line_char = 10;
+ normalize_selector();
+ print_err("LuaTeX fatal error ");
+ tprint(s);
+ succumb();
+}
+
+@ Here is the most dreaded error message
+@c
+void overflow(const char *s, unsigned int n)
+{ /* stop due to finiteness */
+ normalize_selector();
+ print_err("TeX capacity exceeded, sorry [");
+ tprint(s);
+ print_char('=');
+ print_int((int) n);
+ print_char(']');
+ help2("If you really absolutely need more capacity,",
+ "you can ask a wizard to enlarge me.");
+ succumb();
+}
+
+
+@ The program might sometime run completely amok, at which point there is
+no choice but to stop. If no previous error has been detected, that's bad
+news; a message is printed that is really intended for the \TeX\
+maintenance person instead of the user (unless the user has been
+particularly diabolical). The index entries for `this can't happen' may
+help to pinpoint the problem.
+@^dry rot@>
+
+@c
+void confusion(const char *s)
+{ /* consistency check violated; |s| tells where */
+ normalize_selector();
+ if (history < error_message_issued) {
+ print_err("This can't happen (");
+ tprint(s);
+ print_char(')');
+ help1("I'm broken. Please show this to someone who can fix can fix");
+ } else {
+ print_err("I can't go on meeting you like this");
+ help2("One of your faux pas seems to have wounded me deeply...",
+ "in fact, I'm barely conscious. Please fix it and try again.");
+ }
+ succumb();
+}
+
+
+@ Users occasionally want to interrupt \TeX\ while it's running.
+If the runtime system allows this, one can implement
+a routine that sets the global variable |interrupt| to some nonzero value
+when such an interrupt is signalled. Otherwise there is probably at least
+a way to make |interrupt| nonzero using the debugger.
+@^system dependencies@>
+@^debugging@>
+
+@c
+void check_interrupt(void)
+{
+ if (interrupt != 0)
+ pause_for_instructions();
+}
+
+
+
+@ When an interrupt has been detected, the program goes into its
+highest interaction level and lets the user have nearly the full flexibility of
+the |error| routine. \TeX\ checks for interrupts only at times when it is
+safe to do this.
+
+@c
+void pause_for_instructions(void)
+{
+ if (OK_to_interrupt) {
+ interaction = error_stop_mode;
+ if ((selector == log_only) || (selector == no_print))
+ incr(selector);
+ print_err("Interruption");
+ help3("You rang?",
+ "Try to insert some instructions for me (e.g.,`I\\showlists'),",
+ "unless you just want to quit by typing `X'.");
+ deletions_allowed = false;
+ error();
+ deletions_allowed = true;
+ interrupt = 0;
+ }
+}
+
+@ @c
+void tex_error(const char *msg, const char **hlp)
+{
+ print_err(msg);
+ if (hlp != NULL) {
+ int i;
+ for (i = 0; (hlp[i] != NULL && i <= 5); i++) {
+ help_line[i] = hlp[i];
+ }
+ help_line[i] = NULL;
+ } else {
+ help_line[0] = NULL;
+ }
+ error();
+}
+
+@ The |back_error| routine is used when we want to replace an offending token
+just before issuing an error message. This routine, like |back_input|,
+requires that |cur_tok| has been set. We disable interrupts during the
+call of |back_input| so that the help message won't be lost.
+
+@c
+void back_error(void)
+{ /* back up one token and call |error| */
+ OK_to_interrupt = false;
+ back_input();
+ OK_to_interrupt = true;
+ error();
+}
+
+@ @c
+void ins_error(void)
+{ /* back up one inserted token and call |error| */
+ OK_to_interrupt = false;
+ back_input();
+ token_type = inserted;
+ OK_to_interrupt = true;
+ error();
+}
+
+
+
+@ When \TeX\ wants to typeset a character that doesn't exist, the
+character node is not created; thus the output routine can assume
+that characters exist when it sees them. The following procedure
+prints a warning message unless the user has suppressed it.
+
+@c
+void char_warning(internal_font_number f, int c)
+{
+ int old_setting; /* saved value of |tracing_online| */
+ int k; /* index to current digit; we assume that $0\L n<16^{22}$ */
+ if (int_par(tracing_lost_chars_code) > 0) {
+ old_setting = int_par(tracing_online_code);
+ if (int_par(tracing_lost_chars_code) > 1)
+ int_par(tracing_online_code) = 1;
+ begin_diagnostic();
+ tprint_nl("Missing character: There is no ");
+ print(c);
+ tprint(" (U+");
+ k = 0;
+ if (c < 16)
+ print_char('0');
+ if (c < 256)
+ print_char('0');
+ if (c < 4096)
+ print_char('0');
+ do {
+ dig[k] = c % 16;
+ c = c / 16;
+ incr(k);
+ } while (c != 0);
+ print_the_digs((eight_bits) k);
+ tprint(") in font ");
+ print_font_name(f);
+ print_char('!');
+ end_diagnostic(false);
+ int_par(tracing_online_code) = old_setting;
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.h b/Build/source/texk/web2c/luatexdir/tex/expand.h
new file mode 100644
index 00000000000..ce1af9f552a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/expand.h
@@ -0,0 +1,102 @@
+/* expand.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: expand.h 2728 2009-07-04 11:33:51Z oneiros $ */
+
+#ifndef EXPAND_H
+# define EXPAND_H
+
+extern boolean is_in_csname;
+extern void expand(void);
+extern void complain_missing_csname(void);
+extern void manufacture_csname(void);
+extern void insert_relax(void);
+extern void get_x_token(void);
+extern void x_token(void);
+
+# define top_mark_code 0 /* the mark in effect at the previous page break */
+# define first_mark_code 1 /* the first mark between |top_mark| and |bot_mark| */
+# define bot_mark_code 2 /* the mark in effect at the current page break */
+# define split_first_mark_code 3
+ /* the first mark found by \.{\\vsplit} */
+# define split_bot_mark_code 4 /* the last mark found by \.{\\vsplit} */
+# define marks_code 5
+
+# define top_mark(A) top_marks_array[(A)]
+# define first_mark(A) first_marks_array[(A)]
+# define bot_mark(A) bot_marks_array[(A)]
+# define split_first_mark(A) split_first_marks_array[(A)]
+# define split_bot_mark(A) split_bot_marks_array[(A)]
+
+# define set_top_mark(A,B) top_mark(A)=(B)
+# define set_first_mark(A,B) first_mark(A)=(B)
+# define set_bot_mark(A,B) bot_mark(A)=(B)
+# define set_split_first_mark(A,B) split_first_mark(A)=(B)
+# define set_split_bot_mark(A,B) split_bot_mark(A)=(B)
+
+# define delete_top_mark(A) do { \
+ if (top_mark(A)!=null) \
+ delete_token_ref(top_mark(A)); \
+ top_mark(A)=null; \
+ } while (0)
+
+# define delete_bot_mark(A) do { \
+ if (bot_mark(A)!=null) \
+ delete_token_ref(bot_mark(A)); \
+ bot_mark(A)=null; \
+ } while (0)
+
+# define delete_first_mark(A) do { \
+ if (first_mark(A)!=null) \
+ delete_token_ref(first_mark(A)); \
+ first_mark(A)=null; \
+ } while (0)
+
+# define delete_split_first_mark(A) do { \
+ if (split_first_mark(A)!=null) \
+ delete_token_ref(split_first_mark(A)); \
+ split_first_mark(A)=null; \
+ } while (0)
+
+# define delete_split_bot_mark(A) do { \
+ if (split_bot_mark(A)!=null) \
+ delete_token_ref(split_bot_mark(A)); \
+ split_bot_mark(A)=null; \
+} while (0)
+
+# define clear_marks_code 1
+
+# define biggest_mark 65535
+
+extern halfword top_marks_array[(biggest_mark + 1)];
+extern halfword first_marks_array[(biggest_mark + 1)];
+extern halfword bot_marks_array[(biggest_mark + 1)];
+extern halfword split_first_marks_array[(biggest_mark + 1)];
+extern halfword split_bot_marks_array[(biggest_mark + 1)];
+extern halfword biggest_used_mark;
+
+
+extern void initialize_marks(void);
+
+extern int long_state;
+extern halfword pstack[9];
+extern void macro_call(void);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.w b/Build/source/texk/web2c/luatexdir/tex/expand.w
new file mode 100644
index 00000000000..79072f7021e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/expand.w
@@ -0,0 +1,789 @@
+% expand.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: expand.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/expand.w $";
+
+
+@ Only a dozen or so command codes |>max_command| can possibly be returned by
+|get_next|; in increasing order, they are |undefined_cs|, |expand_after|,
+|no_expand|, |input|, |if_test|, |fi_or_else|, |cs_name|, |convert|, |the|,
+|top_bot_mark|, |call|, |long_call|, |outer_call|, |long_outer_call|, and
+|end_template|.{\emergencystretch=40pt\par}
+
+Sometimes, recursive calls to the following |expand| routine may
+cause exhaustion of the run-time calling stack, resulting in
+forced execution stops by the operating system. To diminish the chance
+of this happening, a counter is used to keep track of the recursion
+depth, in conjunction with a constant called |expand_depth|.
+
+Note that this does not catch all possible infinite recursion loops,
+just the ones that exhaust the application calling stack. The
+actual maximum value of |expand_depth| is outside of our control, but
+the initial setting of |100| should be enough to prevent problems.
+@^system dependencies@>
+
+@c
+static int expand_depth_count = 0;
+
+
+@ The |expand| subroutine is used when |cur_cmd>max_command|. It removes a
+``call'' or a conditional or one of the other special operations just
+listed. It follows that |expand| might invoke itself recursively. In all
+cases, |expand| destroys the current token, but it sets things up so that
+the next |get_next| will deliver the appropriate next token. The value of
+|cur_tok| need not be known when |expand| is called.
+
+Since several of the basic scanning routines communicate via global variables,
+their values are saved as local variables of |expand| so that
+recursive calls don't invalidate them.
+@^recursion@>
+
+@c
+boolean is_in_csname = false;
+
+@ @c
+void expand(void)
+{
+ halfword t; /* token that is being ``expanded after'' */
+ halfword p; /* for list manipulation */
+ halfword cur_ptr; /* for a local token list pointer */
+ int cv_backup; /* to save the global quantity |cur_val| */
+ int cvl_backup, radix_backup, co_backup; /* to save |cur_val_level|, etc. */
+ halfword backup_backup; /* to save |link(backup_head)| */
+ int save_scanner_status; /* temporary storage of |scanner_status| */
+ incr(expand_depth_count);
+ if (expand_depth_count >= expand_depth)
+ overflow("expansion depth", (unsigned) expand_depth);
+ cv_backup = cur_val;
+ cvl_backup = cur_val_level;
+ radix_backup = radix;
+ co_backup = cur_order;
+ backup_backup = token_link(backup_head);
+ RESWITCH:
+ if (cur_cmd < call_cmd) {
+ /* Expand a nonmacro */
+ if (int_par(tracing_commands_code) > 1)
+ show_cur_cmd_chr();
+ switch (cur_cmd) {
+ case top_bot_mark_cmd:
+ /* Insert the appropriate mark text into the scanner */
+ t = cur_chr % marks_code;
+ if (cur_chr >= marks_code)
+ scan_mark_num();
+ else
+ cur_val = 0;
+ switch (t) {
+ case first_mark_code:
+ cur_ptr = first_mark(cur_val);
+ break;
+ case bot_mark_code:
+ cur_ptr = bot_mark(cur_val);
+ break;
+ case split_first_mark_code:
+ cur_ptr = split_first_mark(cur_val);
+ break;
+ case split_bot_mark_code:
+ cur_ptr = split_bot_mark(cur_val);
+ break;
+ default:
+ cur_ptr = top_mark(cur_val);
+ break;
+ }
+ if (cur_ptr != null)
+ begin_token_list(cur_ptr, mark_text);
+ break;
+ case expand_after_cmd:
+ if (cur_chr == 0) {
+ /* Expand the token after the next token */
+ /* It takes only a little shuffling to do what \TeX\ calls \.{\\expandafter}. */
+ get_token();
+ t = cur_tok;
+ get_token();
+ if (cur_cmd > max_command_cmd)
+ expand();
+ else
+ back_input();
+ cur_tok = t;
+ back_input();
+
+ } else { /* \\unless */
+ /* Negate a boolean conditional and |goto reswitch| */
+ /* The result of a boolean condition is reversed when the conditional is
+ preceded by \.{\\unless}. */
+ get_token();
+ if ((cur_cmd == if_test_cmd) && (cur_chr != if_case_code)) {
+ cur_chr = cur_chr + unless_code;
+ goto RESWITCH;
+ }
+ print_err("You can't use `\\unless' before `");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ print_char('\'');
+ help1("Continue, and I'll forget that it ever happened.");
+ back_error();
+ }
+ break;
+ case no_expand_cmd:
+ if (cur_chr == 0) {
+ /* Suppress expansion of the next token */
+ /* The implementation of \.{\\noexpand} is a bit trickier, because it is
+ necessary to insert a special `|dont_expand|' marker into \TeX's reading
+ mechanism. This special marker is processed by |get_next|, but it does
+ not slow down the inner loop.
+
+ Since \.{\\outer} macros might arise here, we must also
+ clear the |scanner_status| temporarily.
+ */
+
+ save_scanner_status = scanner_status;
+ scanner_status = normal;
+ get_token();
+ scanner_status = save_scanner_status;
+ t = cur_tok;
+ back_input(); /* now |start| and |loc| point to the backed-up token |t| */
+ if (t >= cs_token_flag) {
+ p = get_avail();
+ set_token_info(p, cs_token_flag + frozen_dont_expand);
+ set_token_link(p, iloc);
+ istart = p;
+ iloc = p;
+ }
+
+ } else {
+ /* Implement \.{\\primitive} */
+ /*
+ The \.{\\primitive} handling. If the primitive meaning of the next
+ token is an expandable command, it suffices to replace the current
+ token with the primitive one and restart |expand|.
+
+ Otherwise, the token we just read has to be pushed back, as well
+ as a token matching the internal form of \.{\\primitive}, that is
+ sneaked in as an alternate form of |ignore_spaces|.
+
+ An implementation problem surfaces: There really is no |cur_cs|
+ attached to the inserted primitive command, so it is safer to set
+ |cur_cs| to zero. |cur_tok| has a similar problem. And for the
+ non-expanded branch, simply pushing back a token that matches the
+ correct internal command does not work, because that approach would
+ not survive roundtripping to a temporary file or even a token list.
+
+ In a next version, it would be smart to create |frozen_| versions of
+ all the primitives. Then, this problem would not happen, at the
+ expense of a few hundred extra control sequences.
+ */
+ save_scanner_status = scanner_status;
+ scanner_status = normal;
+ get_token();
+ scanner_status = save_scanner_status;
+ cur_cs = prim_lookup(cs_text(cur_cs));
+ if (cur_cs != undefined_primitive) {
+ t = get_prim_eq_type(cur_cs);
+ if (t > max_command_cmd) {
+ cur_cmd = t;
+ cur_chr = get_prim_equiv(cur_cs);
+ cur_tok = token_val(cur_cmd, cur_chr);
+ cur_cs = 0;
+ goto RESWITCH;
+ } else {
+ back_input(); /* now |loc| and |start| point to a one-item list */
+ p = get_avail();
+ set_token_info(p, cs_token_flag + frozen_primitive);
+ set_token_link(p, iloc);
+ iloc = p;
+ istart = p;
+ }
+ } else {
+ print_err("Missing primitive name");
+ help2
+ ("The control sequence marked <to be read again> does not",
+ "represent any known primitive.");
+ back_error();
+ }
+
+ }
+ break;
+ case cs_name_cmd:
+ /* Manufacture a control sequence name; */
+ manufacture_csname();
+ break;
+ case convert_cmd:
+ conv_toks(); /* this procedure is discussed in Part 27 below */
+ break;
+ case the_cmd:
+ ins_the_toks(); /* this procedure is discussed in Part 27 below */
+ break;
+ case if_test_cmd:
+ conditional(); /* this procedure is discussed in Part 28 below */
+ break;
+ case fi_or_else_cmd:
+ /* Terminate the current conditional and skip to \.{\\fi} */
+ /* The processing of conditionals is complete except for the following
+ code, which is actually part of |expand|. It comes into play when
+ \.{\\or}, \.{\\else}, or \.{\\fi} is scanned. */
+
+ if (int_par(tracing_ifs_code) > 0)
+ if (int_par(tracing_commands_code) <= 1)
+ show_cur_cmd_chr();
+ if (cur_chr > if_limit) {
+ if (if_limit == if_code) {
+ insert_relax(); /* condition not yet evaluated */
+ } else {
+ print_err("Extra ");
+ print_cmd_chr(fi_or_else_cmd, cur_chr);
+ help1("I'm ignoring this; it doesn't match any \\if.");
+ error();
+ }
+ } else {
+ while (cur_chr != fi_code)
+ pass_text(); /* skip to \.{\\fi} */
+ pop_condition_stack();
+ }
+
+ break;
+ case input_cmd:
+ /* Initiate or terminate input from a file */
+ if (cur_chr == 1)
+ force_eof = true;
+ else if (cur_chr == 2)
+ pseudo_start();
+ else if (cur_chr == 3) {
+ pseudo_start();
+ iname = 19;
+ } else if (name_in_progress)
+ insert_relax();
+ else
+ start_input();
+ break;
+ default:
+ /* Complain about an undefined macro */
+ print_err("Undefined control sequence");
+ help5("The control sequence at the end of the top line",
+ "of your error message was never \\def'ed. If you have",
+ "misspelled it (e.g., `\\hobx'), type `I' and the correct",
+ "spelling (e.g., `I\\hbox'). Otherwise just continue,",
+ "and I'll forget about whatever was undefined.");
+ error();
+ break;
+ }
+ } else if (cur_cmd < end_template_cmd) {
+ macro_call();
+ } else {
+ /* Insert a token containing |frozen_endv| */
+ /* An |end_template| command is effectively changed to an |endv| command
+ by the following code. (The reason for this is discussed below; the
+ |frozen_end_template| at the end of the template has passed the
+ |check_outer_validity| test, so its mission of error detection has been
+ accomplished.)
+ */
+ cur_tok = cs_token_flag + frozen_endv;
+ back_input();
+
+ }
+ cur_val = cv_backup;
+ cur_val_level = cvl_backup;
+ radix = radix_backup;
+ cur_order = co_backup;
+ set_token_link(backup_head, backup_backup);
+ decr(expand_depth_count);
+}
+
+@ @c
+void complain_missing_csname(void)
+{
+ print_err("Missing \\endcsname inserted");
+ help2("The control sequence marked <to be read again> should",
+ "not appear between \\csname and \\endcsname.");
+ back_error();
+}
+
+@ @c
+void manufacture_csname(void)
+{
+ halfword p, q, r;
+ lstring *ss;
+ r = get_avail();
+ p = r; /* head of the list of characters */
+ is_in_csname = true;
+ do {
+ get_x_token();
+ if (cur_cs == 0)
+ store_new_token(cur_tok);
+ } while (cur_cs == 0);
+ if (cur_cmd != end_cs_name_cmd) {
+ /* Complain about missing \.{\\endcsname} */
+ complain_missing_csname();
+ }
+ is_in_csname = false;
+ /* Look up the characters of list |r| in the hash table, and set |cur_cs| */
+
+ ss = tokenlist_to_lstring(r, true);
+ if (ss->l > 0) {
+ no_new_control_sequence = false;
+ cur_cs = string_lookup((char *) ss->s, ss->l);
+ no_new_control_sequence = true;
+ } else {
+ cur_cs = null_cs; /* the list is empty */
+ }
+ xfree(ss->s);
+ flush_list(r);
+ if (eq_type(cur_cs) == undefined_cs_cmd) {
+ eq_define(cur_cs, relax_cmd, too_big_char); /* N.B.: The |save_stack| might change */
+ }; /* the control sequence will now match `\.{\\relax}' */
+ cur_tok = cur_cs + cs_token_flag;
+ back_input();
+}
+
+
+@ Sometimes the expansion looks too far ahead, so we want to insert
+a harmless \.{\\relax} into the user's input.
+
+@c
+void insert_relax(void)
+{
+ cur_tok = cs_token_flag + cur_cs;
+ back_input();
+ cur_tok = cs_token_flag + frozen_relax;
+ back_input();
+ token_type = inserted;
+}
+
+
+@ Here is a recursive procedure that is \TeX's usual way to get the
+next token of input. It has been slightly optimized to take account of
+common cases.
+
+@c
+void get_x_token(void)
+{ /* sets |cur_cmd|, |cur_chr|, |cur_tok|, and expands macros */
+ RESTART:
+ get_token_lua();
+ if (cur_cmd <= max_command_cmd)
+ goto DONE;
+ if (cur_cmd >= call_cmd) {
+ if (cur_cmd < end_template_cmd) {
+ macro_call();
+ } else {
+ cur_cs = frozen_endv;
+ cur_cmd = endv_cmd;
+ goto DONE; /* |cur_chr=null_list| */
+ }
+ } else {
+ expand();
+ }
+ goto RESTART;
+ DONE:
+ if (cur_cs == 0)
+ cur_tok = token_val(cur_cmd, cur_chr);
+ else
+ cur_tok = cs_token_flag + cur_cs;
+}
+
+
+@ The |get_x_token| procedure is equivalent to two consecutive
+procedure calls: |get_next; x_token|.
+
+@c
+void x_token(void)
+{ /* |get_x_token| without the initial |get_next| */
+ while (cur_cmd > max_command_cmd) {
+ expand();
+ get_token_lua();
+ }
+ if (cur_cs == 0)
+ cur_tok = token_val(cur_cmd, cur_chr);
+ else
+ cur_tok = cs_token_flag + cur_cs;
+}
+
+
+@ A control sequence that has been \.{\\def}'ed by the user is expanded by
+\TeX's |macro_call| procedure.
+
+Before we get into the details of |macro_call|, however, let's consider the
+treatment of primitives like \.{\\topmark}, since they are essentially
+macros without parameters. The token lists for such marks are kept in five
+global arrays of pointers; we refer to the individual entries of these
+arrays by symbolic macros |top_mark|, etc. The value of |top_mark(x)|, etc.
+is either |null| or a pointer to the reference count of a token list.
+
+The variable |biggest_used_mark| is an aid to try and keep the code
+somehwat efficient without too much extra work: it registers the
+highest mark class ever instantiated by the user, so the loops
+in |fire_up| and |vsplit| do not have to traverse the full range
+|0..biggest_mark|.
+
+@c
+halfword top_marks_array[(biggest_mark + 1)];
+halfword first_marks_array[(biggest_mark + 1)];
+halfword bot_marks_array[(biggest_mark + 1)];
+halfword split_first_marks_array[(biggest_mark + 1)];
+halfword split_bot_marks_array[(biggest_mark + 1)];
+halfword biggest_used_mark;
+
+@ @c
+void initialize_marks(void)
+{
+ int i;
+ biggest_used_mark = 0;
+ for (i = 0; i <= biggest_mark; i++) {
+ top_mark(i) = null;
+ first_mark(i) = null;
+ bot_mark(i) = null;
+ split_first_mark(i) = null;
+ split_bot_mark(i) = null;
+ }
+}
+
+
+@ Now let's consider |macro_call| itself, which is invoked when \TeX\ is
+scanning a control sequence whose |cur_cmd| is either |call|, |long_call|,
+|outer_call|, or |long_outer_call|. The control sequence definition
+appears in the token list whose reference count is in location |cur_chr|
+of |mem|.
+
+The global variable |long_state| will be set to |call| or to |long_call|,
+depending on whether or not the control sequence disallows \.{\\par}
+in its parameters. The |get_next| routine will set |long_state| to
+|outer_call| and emit \.{\\par}, if a file ends or if an \.{\\outer}
+control sequence occurs in the midst of an argument.
+
+@c
+int long_state; /* governs the acceptance of \.{\\par} */
+
+@ The parameters, if any, must be scanned before the macro is expanded.
+Parameters are token lists without reference counts. They are placed on
+an auxiliary stack called |pstack| while they are being scanned, since
+the |param_stack| may be losing entries during the matching process.
+(Note that |param_stack| can't be gaining entries, since |macro_call| is
+the only routine that puts anything onto |param_stack|, and it
+is not recursive.)
+
+@c
+halfword pstack[9]; /* arguments supplied to a macro */
+
+
+@ After parameter scanning is complete, the parameters are moved to the
+|param_stack|. Then the macro body is fed to the scanner; in other words,
+|macro_call| places the defined text of the control sequence at the
+top of\/ \TeX's input stack, so that |get_next| will proceed to read it
+next.
+
+The global variable |cur_cs| contains the |eqtb| address of the control sequence
+being expanded, when |macro_call| begins. If this control sequence has not been
+declared \.{\\long}, i.e., if its command code in the |eq_type| field is
+not |long_call| or |long_outer_call|, its parameters are not allowed to contain
+the control sequence \.{\\par}. If an illegal \.{\\par} appears, the macro
+call is aborted, and the \.{\\par} will be rescanned.
+
+@c
+void macro_call(void)
+{ /* invokes a user-defined control sequence */
+ halfword r; /* current node in the macro's token list */
+ halfword p = null; /* current node in parameter token list being built */
+ halfword q; /* new node being put into the token list */
+ halfword s; /* backup pointer for parameter matching */
+ halfword t; /* cycle pointer for backup recovery */
+ halfword u, v; /* auxiliary pointers for backup recovery */
+ halfword rbrace_ptr = null; /* one step before the last |right_brace| token */
+ int n = 0; /* the number of parameters scanned */
+ halfword unbalance; /* unmatched left braces in current parameter */
+ halfword m = 0; /* the number of tokens or groups (usually) */
+ halfword ref_count; /* start of the token list */
+ int save_scanner_status = scanner_status; /* |scanner_status| upon entry */
+ halfword save_warning_index = warning_index; /* |warning_index| upon entry */
+ int match_chr = 0; /* character used in parameter */
+ warning_index = cur_cs;
+ ref_count = cur_chr;
+ r = token_link(ref_count);
+ if (int_par(tracing_macros_code) > 0) {
+ /* Show the text of the macro being expanded */
+ begin_diagnostic();
+ print_ln();
+ print_cs(warning_index);
+ token_show(ref_count);
+ end_diagnostic(false);
+ }
+ if (token_info(r) == protected_token)
+ r = token_link(r);
+ if (token_info(r) != end_match_token) {
+ /* Scan the parameters and make |link(r)| point to the macro body; but
+ |return| if an illegal \.{\\par} is detected */
+ /* At this point, the reader will find it advisable to review the explanation
+ of token list format that was presented earlier, since many aspects of that
+ format are of importance chiefly in the |macro_call| routine.
+
+ The token list might begin with a string of compulsory tokens before the
+ first |match| or |end_match|. In that case the macro name is supposed to be
+ followed by those tokens; the following program will set |s=null| to
+ represent this restriction. Otherwise |s| will be set to the first token of
+ a string that will delimit the next parameter.
+ */
+
+ scanner_status = matching;
+ unbalance = 0;
+ long_state = eq_type(cur_cs);
+ if (long_state >= outer_call_cmd)
+ long_state = long_state - 2;
+ do {
+ set_token_link(temp_token_head, null);
+ if ((token_info(r) >= end_match_token)
+ || (token_info(r) < match_token)) {
+ s = null;
+ } else {
+ match_chr = token_info(r) - match_token;
+ s = token_link(r);
+ r = s;
+ p = temp_token_head;
+ m = 0;
+ }
+ /* Scan a parameter until its delimiter string has been found; or, if |s=null|,
+ simply scan the delimiter string; */
+
+ /* If |info(r)| is a |match| or |end_match| command, it cannot be equal to
+ any token found by |get_token|. Therefore an undelimited parameter---i.e.,
+ a |match| that is immediately followed by |match| or |end_match|---will
+ always fail the test `|cur_tok=info(r)|' in the following algorithm. */
+ CONTINUE:
+ get_token(); /* set |cur_tok| to the next token of input */
+ if (cur_tok == token_info(r)) {
+ /* Advance |r|; |goto found| if the parameter delimiter has been
+ fully matched, otherwise |goto continue| */
+ /* A slightly subtle point arises here: When the parameter delimiter ends
+ with `\.{\#\{}', the token list will have a left brace both before and
+ after the |end_match|\kern-.4pt. Only one of these should affect the
+ |align_state|, but both will be scanned, so we must make a correction.
+ */
+ r = token_link(r);
+ if ((token_info(r) >= match_token)
+ && (token_info(r) <= end_match_token)) {
+ if (cur_tok < left_brace_limit)
+ decr(align_state);
+ goto FOUND;
+ } else {
+ goto CONTINUE;
+ }
+
+ }
+ /* Contribute the recently matched tokens to the current parameter, and
+ |goto continue| if a partial match is still in effect; but abort if |s=null| */
+
+ /* When the following code becomes active, we have matched tokens from |s| to
+ the predecessor of |r|, and we have found that |cur_tok<>info(r)|. An
+ interesting situation now presents itself: If the parameter is to be
+ delimited by a string such as `\.{ab}', and if we have scanned `\.{aa}',
+ we want to contribute one `\.a' to the current parameter and resume
+ looking for a `\.b'. The program must account for such partial matches and
+ for others that can be quite complex. But most of the time we have |s=r|
+ and nothing needs to be done.
+
+ Incidentally, it is possible for \.{\\par} tokens to sneak in to certain
+ parameters of non-\.{\\long} macros. For example, consider a case like
+ `\.{\\def\\a\#1\\par!\{...\}}' where the first \.{\\par} is not followed
+ by an exclamation point. In such situations it does not seem appropriate
+ to prohibit the \.{\\par}, so \TeX\ keeps quiet about this bending of
+ the rules. */
+
+ if (s != r) {
+ if (s == null) {
+ /* Report an improper use of the macro and abort */
+ print_err("Use of ");
+ sprint_cs(warning_index);
+ tprint(" doesn't match its definition");
+ help4
+ ("If you say, e.g., `\\def\\a1{...}', then you must always",
+ "put `1' after `\\a', since control sequence names are",
+ "made up of letters only. The macro here has not been",
+ "followed by the required stuff, so I'm ignoring it.");
+ error();
+ goto EXIT;
+
+ } else {
+ t = s;
+ do {
+ store_new_token(token_info(t));
+ incr(m);
+ u = token_link(t);
+ v = s;
+ while (1) {
+ if (u == r) {
+ if (cur_tok != token_info(v)) {
+ goto DONE;
+ } else {
+ r = token_link(v);
+ goto CONTINUE;
+ }
+ }
+ if (token_info(u) != token_info(v))
+ goto DONE;
+ u = token_link(u);
+ v = token_link(v);
+ }
+ DONE:
+ t = token_link(t);
+ } while (t != r);
+ r = s; /* at this point, no tokens are recently matched */
+ }
+ }
+
+ if (cur_tok == par_token)
+ if (long_state != long_call_cmd)
+ if (!int_par(suppress_long_error_code)) {
+ goto RUNAWAY;
+ }
+ if (cur_tok < right_brace_limit) {
+ if (cur_tok < left_brace_limit) {
+ /* Contribute an entire group to the current parameter */
+ unbalance = 1;
+ while (1) {
+ fast_store_new_token(cur_tok);
+ get_token();
+ if (cur_tok == par_token) {
+ if (long_state != long_call_cmd) {
+ if (!int_par(suppress_long_error_code)) {
+ goto RUNAWAY;
+
+ }
+ }
+ }
+ if (cur_tok < right_brace_limit) {
+ if (cur_tok < left_brace_limit) {
+ incr(unbalance);
+ } else {
+ decr(unbalance);
+ if (unbalance == 0)
+ break;
+ }
+ }
+ }
+ rbrace_ptr = p;
+ store_new_token(cur_tok);
+
+ } else {
+ /* Report an extra right brace and |goto continue| */
+ back_input();
+ print_err("Argument of ");
+ sprint_cs(warning_index);
+ tprint(" has an extra }");
+ help6
+ ("I've run across a `}' that doesn't seem to match anything.",
+ "For example, `\\def\\a#1{...}' and `\\a}' would produce",
+ "this error. If you simply proceed now, the `\\par' that",
+ "I've just inserted will cause me to report a runaway",
+ "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_cmd;
+ cur_tok = par_token;
+ ins_error();
+ goto CONTINUE;
+ /* a white lie; the \.{\\par} won't always trigger a runaway */
+ }
+ } else {
+ /* Store the current token, but |goto continue| if it is
+ a blank space that would become an undelimited parameter */
+ if (cur_tok == space_token)
+ if (token_info(r) <= end_match_token)
+ if (token_info(r) >= match_token)
+ goto CONTINUE;
+ store_new_token(cur_tok);
+
+ }
+ incr(m);
+ if (token_info(r) > end_match_token)
+ goto CONTINUE;
+ if (token_info(r) < match_token)
+ goto CONTINUE;
+ FOUND:
+ if (s != null) {
+ /* Tidy up the parameter just scanned, and tuck it away */
+ /* If the parameter consists of a single group enclosed in braces, we must
+ strip off the enclosing braces. That's why |rbrace_ptr| was introduced. */
+ if ((m == 1) && (token_info(p) < right_brace_limit)
+ && (p != temp_token_head)) {
+ set_token_link(rbrace_ptr, null);
+ free_avail(p);
+ p = token_link(temp_token_head);
+ pstack[n] = token_link(p);
+ free_avail(p);
+ } else {
+ pstack[n] = token_link(temp_token_head);
+ }
+ incr(n);
+ if (int_par(tracing_macros_code) > 0) {
+ begin_diagnostic();
+ print_nl(match_chr);
+ print_int(n);
+ tprint("<-");
+ show_token_list(pstack[n - 1], null, 1000);
+ end_diagnostic(false);
+ }
+
+ }
+
+ /* now |info(r)| is a token whose command code is either |match| or |end_match| */
+ } while (token_info(r) != end_match_token);
+
+ }
+ /* Feed the macro body and its parameters to the scanner */
+ /* Before we put a new token list on the input stack, it is wise to clean off
+ all token lists that have recently been depleted. Then a user macro that ends
+ with a call to itself will not require unbounded stack space. */
+ while ((istate == token_list) && (iloc == null)
+ && (token_type != v_template))
+ end_token_list(); /* conserve stack space */
+ begin_token_list(ref_count, macro);
+ iname = warning_index;
+ iloc = token_link(r);
+ if (n > 0) {
+ if (param_ptr + n > max_param_stack) {
+ max_param_stack = param_ptr + n;
+ if (max_param_stack > param_size)
+ overflow("parameter stack size", (unsigned) param_size);
+ }
+ for (m = 0; m <= n - 1; m++)
+ param_stack[param_ptr + m] = pstack[m];
+ param_ptr = param_ptr + n;
+ }
+ goto EXIT;
+ RUNAWAY:
+ /* Report a runaway argument and abort */
+ /* If |long_state=outer_call|, a runaway argument has already been reported. */
+ if (long_state == call_cmd) {
+ runaway();
+ print_err("Paragraph ended before ");
+ sprint_cs(warning_index);
+ tprint(" was complete");
+ help3("I suspect you've forgotten a `}', causing me to apply this",
+ "control sequence to too much text. How can we recover?",
+ "My plan is to forget the whole thing and hope for the best.");
+ back_error();
+ }
+ pstack[n] = token_link(temp_token_head);
+ align_state = align_state - unbalance;
+ for (m = 0; m <= n; m++)
+ flush_list(pstack[m]);
+
+ EXIT:
+ scanner_status = save_scanner_status;
+ warning_index = save_warning_index;
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.h b/Build/source/texk/web2c/luatexdir/tex/extensions.h
new file mode 100644
index 00000000000..590dec0e6bd
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/extensions.h
@@ -0,0 +1,118 @@
+/* extensions.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: extensions.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef EXTENSIONS_H
+# define EXTENSIONS_H
+
+extern alpha_file write_file[16];
+extern halfword write_file_mode[16];
+extern halfword write_file_translation[16];
+extern boolean write_open[18];
+extern scaled neg_wd;
+extern scaled pos_wd;
+extern scaled neg_ht;
+
+extern halfword write_loc;
+
+extern void do_extension(PDF pdf);
+
+/* Three extra node types carry information from |main_control|. */
+
+/*
+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.
+*/
+
+extern void new_whatsit(int s);
+extern void new_write_whatsit(int w);
+extern void scan_pdf_ext_toks(void);
+extern halfword prev_rightmost(halfword s, halfword e);
+extern int pdf_last_xform;
+extern int pdf_last_ximage;
+extern int pdf_last_ximage_pages;
+extern int pdf_last_ximage_colordepth;
+extern int pdf_last_annot;
+extern int pdf_last_link;
+extern scaledpos pdf_last_pos;
+extern halfword concat_tokens(halfword q, halfword r);
+extern int pdf_retval;
+
+extern halfword make_local_par_node(void);
+
+
+/*
+The \.{\\pagediscards} and \.{\\splitdiscards} commands share the
+command code |un_vbox| with \.{\\unvbox} and \.{\\unvcopy}, they are
+distinguished by their |chr_code| values |last_box_code| and
+|vsplit_code|. These |chr_code| values are larger than |box_code| and
+|copy_code|.
+*/
+
+extern boolean *eof_seen; /* has eof been seen? */
+extern void print_group(boolean e);
+extern void group_trace(boolean e);
+extern save_pointer *grp_stack; /* initial |cur_boundary| */
+extern halfword *if_stack; /* initial |cond_ptr| */
+extern void group_warning(void);
+extern void if_warning(void);
+extern void file_warning(void);
+
+extern halfword last_line_fill; /* the |par_fill_skip| glue node of the new paragraph */
+
+# define get_tex_dimen_register(j) dimen(j)
+# define get_tex_skip_register(j) skip(j)
+# define get_tex_count_register(j) count(j)
+# define get_tex_attribute_register(j) attribute(j)
+# define get_tex_box_register(j) box(j)
+
+extern int set_tex_dimen_register(int j, scaled v);
+extern int set_tex_skip_register(int j, halfword v);
+extern int set_tex_count_register(int j, scaled v);
+extern int set_tex_box_register(int j, scaled v);
+extern int set_tex_attribute_register(int j, scaled v);
+extern int get_tex_toks_register(int l);
+extern int set_tex_toks_register(int j, lstring s);
+extern scaled get_tex_box_width(int j);
+extern int set_tex_box_width(int j, scaled v);
+extern scaled get_tex_box_height(int j);
+extern int set_tex_box_height(int j, scaled v);
+extern scaled get_tex_box_depth(int j);
+extern int set_tex_box_depth(int j, scaled v);
+
+/* Synctex variables */
+
+extern int synctexoption;
+extern int synctexoffset;
+
+/* Here are extra variables for Web2c. */
+
+extern pool_pointer edit_name_start;
+extern int edit_name_length, edit_line;
+extern int ipcon;
+extern boolean stop_at_space;
+extern int shellenabledp;
+extern int restrictedshell;
+extern char *output_comment;
+extern boolean debug_format_file;
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.w b/Build/source/texk/web2c/luatexdir/tex/extensions.w
new file mode 100644
index 00000000000..b8b89512ba2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/extensions.w
@@ -0,0 +1,1217 @@
+% extensions.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+\def\eTeX{e-\TeX}
+\def\pdfTeX{pdf\TeX}
+
+@ @c
+static const char _svn_version[] =
+ "$Id: extensions.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/extensions.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define mode cur_list.mode_field
+#define tail cur_list.tail_field
+#define head cur_list.head_field
+#define prev_graf cur_list.pg_field
+#define dir_save cur_list.dirs_field
+
+#define tracing_nesting int_par(tracing_nesting_code)
+#define box(A) eqtb[box_base+(A)].hh.rh
+#define global_defs int_par(global_defs_code)
+#define cat_code_table int_par(cat_code_table_code)
+#define par_direction int_par(par_direction_code)
+#define toks(A) equiv(toks_base+(A))
+
+#define local_inter_line_penalty int_par(local_inter_line_penalty_code)
+#define local_broken_penalty int_par(local_broken_penalty_code)
+#define local_left_box equiv(local_left_box_base)
+#define local_right_box equiv(local_right_box_base)
+
+
+@ The program above includes a bunch of ``hooks'' that allow further
+capabilities to be added without upsetting \TeX's basic structure.
+Most of these hooks are concerned with ``whatsit'' nodes, which are
+intended to be used for special purposes; whenever a new extension to
+\TeX\ involves a new kind of whatsit node, a corresponding change needs
+to be made to the routines below that deal with such nodes,
+but it will usually be unnecessary to make many changes to the
+other parts of this program.
+
+In order to demonstrate how extensions can be made, we shall treat
+`\.{\\write}', `\.{\\openout}', `\.{\\closeout}', `\.{\\immediate}',
+and `\.{\\special}' as if they were extensions.
+These commands are actually primitives of \TeX, and they should
+appear in all implementations of the system; but let's try to imagine
+that they aren't. Then the program below illustrates how a person
+could add them.
+
+Sometimes, of course, an extension will require changes to \TeX\ itself;
+no system of hooks could be complete enough for all conceivable extensions.
+The features associated with `\.{\\write}' are almost all confined to the
+following paragraphs, but there are small parts of the |print_ln| and
+|print_char| procedures that were introduced specifically to \.{\\write}
+characters. Furthermore one of the token lists recognized by the scanner
+is a |write_text|; and there are a few other miscellaneous places where we
+have already provided for some aspect of \.{\\write}. The goal of a \TeX\
+extender should be to minimize alterations to the standard parts of the
+program, and to avoid them completely if possible. He or she should also
+be quite sure that there's no easy way to accomplish the desired goals
+with the standard features that \TeX\ already has. ``Think thrice before
+extending,'' because that may save a lot of work, and it will also keep
+incompatible extensions of \TeX\ from proliferating.
+@^system dependencies@>
+@^extensions to \TeX@>
+
+First let's consider the format of whatsit nodes that are used to represent
+the data associated with \.{\\write} and its relatives. Recall that a whatsit
+has |type=whatsit_node|, and the |subtype| is supposed to distinguish
+different kinds of whatsits. Each node occupies two or more words; the
+exact number is immaterial, as long as it is readily determined from the
+|subtype| or other data.
+
+We shall introduce five |subtype| values here, corresponding to the
+control sequences \.{\\openout}, \.{\\write}, \.{\\closeout}, and \.{\\special}.
+The second word of I/O whatsits has a |write_stream| field
+that identifies the write-stream number (0 to 15, or 16 for out-of-range and
+positive, or 17 for out-of-range and negative).
+In the case of \.{\\write} and \.{\\special}, there is also a field that
+points to the reference count of a token list that should be sent. In the
+case of \.{\\openout}, we need three words and three auxiliary subfields
+to hold the string numbers for name, area, and extension.
+
+@ Extensions might introduce new command codes; but it's best to use
+|extension| with a modifier, whenever possible, so that |main_control|
+stays the same.
+
+@ The sixteen possible \.{\\write} streams are represented by the |write_file|
+array. The |j|th file is open if and only if |write_open[j]=true|. The last
+two streams are special; |write_open[16]| represents a stream number
+greater than 15, while |write_open[17]| represents a negative stream number,
+and both of these variables are always |false|.
+
+@c
+alpha_file write_file[16];
+halfword write_file_mode[16];
+halfword write_file_translation[16];
+boolean write_open[18];
+scaled neg_wd;
+scaled pos_wd;
+scaled neg_ht;
+
+
+@ The variable |write_loc| just introduced is used to provide an
+appropriate error message in case of ``runaway'' write texts.
+
+@c
+halfword write_loc; /* |eqtb| address of \.{\\write} */
+
+
+@ When an |extension| command occurs in |main_control|, in any mode,
+the |do_extension| routine is called.
+
+@c
+void do_extension(PDF pdf)
+{
+ int i, k; /* all-purpose integers */
+ halfword p; /* all-purpose pointer */
+ switch (cur_chr) {
+ case open_node:
+ /* Implement \.{\\openout} */
+ new_write_whatsit(open_node_size);
+ scan_optional_equals();
+ scan_file_name();
+ open_name(tail) = cur_name;
+ open_area(tail) = cur_area;
+ open_ext(tail) = cur_ext;
+ break;
+ case write_node:
+ /* Implement \.{\\write} */
+ /* When `\.{\\write 12\{...\}}' appears, we scan the token list `\.{\{...\}}'
+ without expanding its macros; the macros will be expanded later when this
+ token list is rescanned. */
+ k = cur_cs;
+ new_write_whatsit(write_node_size);
+ cur_cs = k;
+ p = scan_toks(false, false);
+ write_tokens(tail) = def_ref;
+ break;
+ case close_node:
+ /* Implement \.{\\closeout} */
+ new_write_whatsit(write_node_size);
+ write_tokens(tail) = null;
+ break;
+ case special_node:
+ /* Implement \.{\\special} */
+ /* When `\.{\\special\{...\}}' appears, we expand the macros in the token
+ list as in \.{\\xdef} and \.{\\mark}. */
+ new_whatsit(special_node);
+ write_stream(tail) = null;
+ p = scan_toks(false, true);
+ write_tokens(tail) = def_ref;
+ break;
+ case immediate_code:
+ /* Implement \.{\\immediate} */
+ /* To write a token list, we must run it through \TeX's scanner, expanding
+ macros and \.{\\the} and \.{\\number}, etc. This might cause runaways,
+ if a delimited macro parameter isn't matched, and runaways would be
+ extremely confusing since we are calling on \TeX's scanner in the middle
+ of a \.{\\shipout} command. Therefore we will put a dummy control sequence as
+ a ``stopper,'' right after the token list. This control sequence is
+ artificially defined to be \.{\\outer}.
+
+ The presence of `\.{\\immediate}' causes the |do_extension| procedure
+ to descend to one level of recursion. Nothing happens unless \.{\\immediate}
+ is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
+ */
+ get_x_token();
+ if (cur_cmd == extension_cmd) {
+ if (cur_chr <= close_node) {
+ p = tail;
+ /* |do_extension()| and |out_what()| here can only be open, write, or close */
+ do_extension(pdf); /* append a whatsit node */
+ out_what(pdf, tail); /* do the action immediately */
+ flush_node_list(tail);
+ tail = p;
+ vlink(p) = null;
+ } else {
+ switch (cur_chr) {
+ case pdf_obj_code:
+ check_o_mode(pdf, "\\immediate\\pdfobj", 1 << OMODE_PDF,
+ true);
+ do_extension(pdf); /* scan object and set |pdf_last_obj| */
+ if (obj_data_ptr(pdf, pdf_last_obj) == 0) /* this object has not been initialized yet */
+ pdf_error("ext1",
+ "`\\pdfobj reserveobjnum' cannot be used with \\immediate");
+ pdf_write_obj(pdf, pdf_last_obj);
+ break;
+ case pdf_xform_code:
+ check_o_mode(pdf, "\\immediate\\pdfxform", 1 << OMODE_PDF,
+ true);
+ do_extension(pdf); /* scan form and set |pdf_last_xform| */
+ pdf_cur_form = pdf_last_xform;
+ ship_out(pdf, obj_xform_box(pdf, pdf_last_xform), false);
+ break;
+ case pdf_ximage_code:
+ check_o_mode(pdf, "\\immediate\\pdfximage", 1 << OMODE_PDF,
+ true);
+ do_extension(pdf); /* scan image and set |pdf_last_ximage| */
+ pdf_write_image(pdf, pdf_last_ximage);
+ break;
+ default:
+ back_input();
+ break;
+ }
+ }
+ } else {
+ back_input();
+ }
+ break;
+ case pdf_annot_node:
+ /* Implement \.{\\pdfannot} */
+ check_o_mode(pdf, "\\pdfannot", 1 << OMODE_PDF, false);
+ scan_annot(pdf);
+ break;
+ case pdf_catalog_code:
+ /* Implement \.{\\pdfcatalog} */
+ check_o_mode(pdf, "\\pdfcatalog", 1 << OMODE_PDF, true); /* writes an object */
+ scan_pdfcatalog(pdf);
+ break;
+ case pdf_dest_node:
+ /* Implement \.{\\pdfdest} */
+ check_o_mode(pdf, "\\pdfdest", 1 << OMODE_PDF, false);
+ scan_pdfdest(pdf);
+ break;
+ case pdf_end_link_node:
+ /* Implement \.{\\pdfendlink} */
+ check_o_mode(pdf, "\\pdfendlink", 1 << OMODE_PDF, false);
+ if (abs(mode) == vmode)
+ pdf_error("ext1", "\\pdfendlink cannot be used in vertical mode");
+ new_whatsit(pdf_end_link_node);
+ break;
+ case pdf_end_thread_node:
+ /* Implement \.{\\pdfendthread} */
+ check_o_mode(pdf, "\\pdfendthread", 1 << OMODE_PDF, false);
+ new_whatsit(pdf_end_thread_node);
+ break;
+ case pdf_font_attr_code:
+ /* Implement \.{\\pdffontattr} */
+ /* A change from Thanh's original code: the font attributes are simply
+ initialized to zero now, this is easier to deal with from C than an
+ empty \TeX{} string, and surely nobody will want to set
+ \.{\\pdffontattr} to a string containing a single zero, as that
+ would be nonsensical in the PDF output. */
+ check_o_mode(pdf, "\\pdffontattr", 1 << OMODE_PDF, false);
+ scan_font_ident();
+ k = cur_val;
+ if (k == null_font)
+ pdf_error("font", "invalid font identifier");
+ scan_pdf_ext_toks();
+ set_pdf_font_attr(k, tokens_to_string(def_ref));
+ if (str_length(pdf_font_attr(k)) == 0) {
+ flush_str((str_ptr - 1)); /* from |tokens_to_string| */
+ set_pdf_font_attr(k, 0);
+ }
+ break;
+ case pdf_font_expand_code:
+ /* Implement \.{\\pdffontexpand} */
+ read_expand_font();
+ break;
+ case pdf_include_chars_code:
+ /* Implement \.{\\pdfincludechars} */
+ check_o_mode(pdf, "\\pdfincludechars", 1 << OMODE_PDF, false);
+ pdf_include_chars(pdf);
+ break;
+ case pdf_info_code:
+ /* Implement \.{\\pdfinfo} */
+ check_o_mode(pdf, "\\pdfinfo", 1 << OMODE_PDF, false);
+ scan_pdf_ext_toks();
+ pdf_info_toks = concat_tokens(pdf_info_toks, def_ref);
+ break;
+ case pdf_literal_node:
+ /* Implement \.{\\pdfliteral} */
+ check_o_mode(pdf, "\\pdfliteral", 1 << OMODE_PDF, false);
+ new_whatsit(pdf_literal_node);
+ if (scan_keyword("direct"))
+ set_pdf_literal_mode(tail, direct_always);
+ else if (scan_keyword("page"))
+ set_pdf_literal_mode(tail, direct_page);
+ else
+ set_pdf_literal_mode(tail, set_origin);
+ scan_pdf_ext_toks();
+ set_pdf_literal_type(tail, normal);
+ set_pdf_literal_data(tail, def_ref);
+ break;
+ case pdf_colorstack_node:
+ /* Implement \.{\\pdfcolorstack} */
+ check_o_mode(pdf, "\\pdfcolorstack", 1 << OMODE_PDF, false);
+ /* Scan and check the stack number and store in |cur_val| */
+ scan_int();
+ if (cur_val >= colorstackused()) {
+ print_err("Unknown color stack number ");
+ print_int(cur_val);
+ help3
+ ("Allocate and initialize a color stack with \\pdfcolorstackinit.",
+ "I'll use default color stack 0 here.",
+ "Proceed, with fingers crossed.");
+ error();
+ cur_val = 0;
+ }
+ if (cur_val < 0) {
+ print_err("Invalid negative color stack number");
+ help2("I'll use default color stack 0 here.",
+ "Proceed, with fingers crossed.");
+ error();
+ cur_val = 0;
+ }
+ if (scan_keyword("set"))
+ i = colorstack_set;
+ else if (scan_keyword("push"))
+ i = colorstack_push;
+ else if (scan_keyword("pop"))
+ i = colorstack_pop;
+ else if (scan_keyword("current"))
+ i = colorstack_current;
+ else
+ i = -1; /* error */
+
+ if (i >= 0) {
+ new_whatsit(pdf_colorstack_node);
+ set_pdf_colorstack_stack(tail, cur_val);
+ set_pdf_colorstack_cmd(tail, i);
+ set_pdf_colorstack_data(tail, null);
+ if (i <= colorstack_data) {
+ scan_pdf_ext_toks();
+ set_pdf_colorstack_data(tail, def_ref);
+ }
+ } else {
+ print_err("Color stack action is missing");
+ help3("The expected actions for \\pdfcolorstack:",
+ " set, push, pop, current",
+ "I'll ignore the color stack command.");
+ error();
+ }
+ break;
+ case pdf_setmatrix_node:
+ /* Implement \.{\\pdfsetmatrix} */
+ check_o_mode(pdf, "\\pdfsetmatrix", 1 << OMODE_PDF, false);
+ new_whatsit(pdf_setmatrix_node);
+ scan_pdf_ext_toks();
+ set_pdf_setmatrix_data(tail, def_ref);
+ break;
+ case pdf_save_node:
+ /* Implement \.{\\pdfsave} */
+ check_o_mode(pdf, "\\pdfsave", 1 << OMODE_PDF, false);
+ new_whatsit(pdf_save_node);
+ break;
+ case pdf_restore_node:
+ /* Implement \.{\\pdfrestore} */
+ check_o_mode(pdf, "\\pdfrestore", 1 << OMODE_PDF, false);
+ new_whatsit(pdf_restore_node);
+ break;
+ case pdf_map_file_code:
+ /* Implement \.{\\pdfmapfile} */
+ check_o_mode(pdf, "\\pdfmapfile", 1 << OMODE_PDF, false);
+ scan_pdf_ext_toks();
+ pdfmapfile(def_ref);
+ delete_token_ref(def_ref);
+ break;
+ case pdf_map_line_code:
+ /* Implement \.{\\pdfmapline} */
+ check_o_mode(pdf, "\\pdfmapline", 1 << OMODE_PDF, false);
+ scan_pdf_ext_toks();
+ pdfmapline(def_ref);
+ delete_token_ref(def_ref);
+ break;
+ case pdf_names_code:
+ /* Implement \.{\\pdfnames} */
+ check_o_mode(pdf, "\\pdfnames", 1 << OMODE_PDF, false);
+ scan_pdf_ext_toks();
+ pdf_names_toks = concat_tokens(pdf_names_toks, def_ref);
+ break;
+ case pdf_obj_code:
+ /* Implement \.{\\pdfobj} */
+ check_o_mode(pdf, "\\pdfobj", 1 << OMODE_PDF, false);
+ scan_obj(pdf);
+ break;
+ case pdf_outline_code:
+ /* Implement \.{\\pdfoutline} */
+ check_o_mode(pdf, "\\pdfoutline", 1 << OMODE_PDF, true);
+ scan_pdfoutline(pdf);
+ break;
+ case pdf_refobj_node:
+ /* Implement \.{\\pdfrefobj} */
+ check_o_mode(pdf, "\\pdfrefobj", 1 << OMODE_PDF, false);
+ scan_refobj(pdf);
+ break;
+ case pdf_refxform_node:
+ /* Implement \.{\\pdfrefxform} */
+ check_o_mode(pdf, "\\pdfrefxform", 1 << OMODE_PDF, false);
+ scan_pdfrefxform(pdf);
+ break;
+ case pdf_refximage_node:
+ /* Implement \.{\\pdfrefximage} */
+ check_o_mode(pdf, "\\pdfrefximage", 1 << OMODE_PDF, false);
+ scan_pdfrefximage(pdf);
+ break;
+ case pdf_save_pos_node:
+ /* Implement \.{\\pdfsavepos} */
+ new_whatsit(pdf_save_pos_node);
+ break;
+ case pdf_start_link_node:
+ /* Implement \.{\\pdfstartlink} */
+ check_o_mode(pdf, "\\pdfstartlink", 1 << OMODE_PDF, false);
+ scan_startlink(pdf);
+ break;
+ case pdf_start_thread_node:
+ /* Implement \.{\\pdfstartthread} */
+ check_o_mode(pdf, "\\pdfstartthread", 1 << OMODE_PDF, false);
+ new_annot_whatsit(pdf_start_thread_node);
+ scan_thread_id();
+ break;
+ case pdf_thread_node:
+ /* Implement \.{\\pdfthread} */
+ check_o_mode(pdf, "\\pdfthread", 1 << OMODE_PDF, false);
+ new_annot_whatsit(pdf_thread_node);
+ scan_thread_id();
+ break;
+ case pdf_trailer_code:
+ /* Implement \.{\\pdftrailer} */
+ check_o_mode(pdf, "\\pdftrailer", 1 << OMODE_PDF, false);
+ scan_pdf_ext_toks();
+ pdf_trailer_toks = concat_tokens(pdf_trailer_toks, def_ref);
+ break;
+ case pdf_xform_code:
+ /* Implement \.{\\pdfxform} */
+ check_o_mode(pdf, "\\pdfxform", 1 << OMODE_PDF, false);
+ scan_pdfxform(pdf);
+ break;
+ case pdf_ximage_code:
+ /* Implement \.{\\pdfximage} */
+ check_o_mode(pdf, "\\pdfximage", 1 << OMODE_PDF, false);
+ /* png, jpeg, and pdf image handling depends on this done so early: */
+ fix_pdf_minorversion(pdf);
+ scan_pdfximage(pdf);
+ break;
+ case save_cat_code_table_code:
+ /* Implement \.{\\savecatcodetable} */
+ scan_int();
+ if ((cur_val < 0) || (cur_val > 0xFFFF)) {
+ print_err("Invalid \\catcode table");
+ help1("All \\catcode table ids must be between 0 and 0xFFFF");
+ error();
+ } else {
+ if (cur_val == cat_code_table) {
+ print_err("Invalid \\catcode table");
+ help1("You cannot overwrite the current \\catcode table");
+ error();
+ } else {
+ copy_cat_codes(cat_code_table, cur_val);
+ }
+ }
+ break;
+ case init_cat_code_table_code:
+ /* Implement \.{\\initcatcodetable} */
+ scan_int();
+ if ((cur_val < 0) || (cur_val > 0xFFFF)) {
+ print_err("Invalid \\catcode table");
+ help1("All \\catcode table ids must be between 0 and 0xFFFF");
+ error();
+ } else {
+ if (cur_val == cat_code_table) {
+ print_err("Invalid \\catcode table");
+ help1("You cannot overwrite the current \\catcode table");
+ error();
+ } else {
+ initex_cat_codes(cur_val);
+ }
+ }
+ break;
+ case set_random_seed_code:
+ /* Implement \.{\\pdfsetrandomseed} */
+ /* Negative random seed values are silently converted to positive ones */
+ scan_int();
+ if (cur_val < 0)
+ negate(cur_val);
+ random_seed = cur_val;
+ init_randoms(random_seed);
+ break;
+ case pdf_glyph_to_unicode_code:
+ /* Implement \.{\\pdfglyphtounicode} */
+ glyph_to_unicode();
+ break;
+ case late_lua_node:
+ /* Implement \.{\\latelua} */
+ new_whatsit(late_lua_node);
+ late_lua_name(tail) = scan_lua_state();
+ (void) scan_toks(false, false);
+ late_lua_data(tail) = def_ref;
+ break;
+ default:
+ confusion("ext1");
+ break;
+ }
+}
+
+
+@ Here is a subroutine that creates a whatsit node having a given |subtype|
+and a given number of words. It initializes only the first word of the whatsit,
+and appends it to the current list.
+
+@c
+void new_whatsit(int s)
+{
+ halfword p; /* the new node */
+ p = new_node(whatsit_node, s);
+ couple_nodes(tail, p);
+ tail = p;
+}
+
+
+@ The next subroutine uses |cur_chr| to decide what sort of whatsit is
+involved, and also inserts a |write_stream| number.
+
+@c
+void new_write_whatsit(int w)
+{
+ new_whatsit(cur_chr);
+ if (w != write_node_size) {
+ scan_four_bit_int();
+ } else {
+ scan_int();
+ if (cur_val < 0)
+ cur_val = 17;
+ else if ((cur_val > 15) && (cur_val != 18))
+ cur_val = 16;
+ }
+ write_stream(tail) = cur_val;
+}
+
+
+@ We have to check whether \.{\\pdfoutput} is set for using \pdfTeX{}
+ extensions.
+
+@c
+void scan_pdf_ext_toks(void)
+{
+ (void) scan_toks(false, true); /* like \.{\\special} */
+}
+
+@ We need to check whether the referenced object exists.
+
+finds the node preceding the rightmost node |e|; |s| is some node before |e|
+@c
+halfword prev_rightmost(halfword s, halfword e)
+{
+ halfword p = s;
+ if (p == null)
+ return null;
+ while (vlink(p) != e) {
+ p = vlink(p);
+ if (p == null)
+ return null;
+ }
+ return p;
+}
+
+@ \.{\\pdfxform} and \.{\\pdfrefxform} are similiar to \.{\\pdfobj} and
+ \.{\\pdfrefobj}
+
+@c
+int pdf_last_xform;
+
+@ \.{\\pdfximage} and \.{\\pdfrefximage} are similiar to \.{\\pdfxform} and
+ \.{\\pdfrefxform}. As we have to scan |<rule spec>| quite often, it is better
+ have a |rule_node| that holds the most recently scanned |<rule spec>|.
+
+@c
+int pdf_last_ximage;
+int pdf_last_ximage_pages;
+int pdf_last_ximage_colordepth;
+int pdf_last_annot;
+
+@ pdflastlink needs an extra global variable
+
+@c
+int pdf_last_link;
+scaledpos pdf_last_pos = { 0, 0 };
+
+
+@ To implement primitives as \.{\\pdfinfo}, \.{\\pdfcatalog} or
+\.{\\pdfnames} we need to concatenate tokens lists.
+
+@c
+halfword concat_tokens(halfword q, halfword r)
+{ /* concat |q| and |r| and returns the result tokens list */
+ halfword p;
+ if (q == null)
+ return r;
+ p = q;
+ while (token_link(p) != null)
+ p = token_link(p);
+ set_token_link(p, token_link(r));
+ free_avail(r);
+ return q;
+}
+
+@ @c
+int pdf_retval; /* global multi-purpose return value */
+
+@ @c
+halfword make_local_par_node(void)
+/* This function creates a |local_paragraph| node */
+{
+ halfword p, q;
+ p = new_node(whatsit_node, local_par_node);
+ local_pen_inter(p) = local_inter_line_penalty;
+ local_pen_broken(p) = local_broken_penalty;
+ if (local_left_box != null) {
+ q = copy_node_list(local_left_box);
+ local_box_left(p) = q;
+ local_box_left_width(p) = width(local_left_box);
+ }
+ if (local_right_box != null) {
+ q = copy_node_list(local_right_box);
+ local_box_right(p) = q;
+ local_box_right_width(p) = width(local_right_box);
+ }
+ local_par_dir(p) = par_direction;
+ return p;
+}
+
+
+
+@ The \eTeX\ features available in extended mode are grouped into two
+categories: (1)~Some of them are permanently enabled and have no
+semantic effect as long as none of the additional primitives are
+executed. (2)~The remaining \eTeX\ features are optional and can be
+individually enabled and disabled. For each optional feature there is
+an \eTeX\ state variable named \.{\\...state}; the feature is enabled,
+resp.\ disabled by assigning a positive, resp.\ non-positive value to
+that integer.
+
+
+@ In order to handle \.{\\everyeof} we need an array |eof_seen| of
+boolean variables.
+
+@c
+boolean *eof_seen; /* has eof been seen? */
+
+
+@ The |print_group| procedure prints the current level of grouping and
+the name corresponding to |cur_group|.
+
+@c
+void print_group(boolean e)
+{
+ switch (cur_group) {
+ case bottom_level:
+ tprint("bottom level");
+ return;
+ break;
+ case simple_group:
+ case semi_simple_group:
+ if (cur_group == semi_simple_group)
+ tprint("semi ");
+ tprint("simple");
+ break;;
+ case hbox_group:
+ case adjusted_hbox_group:
+ if (cur_group == adjusted_hbox_group)
+ tprint("adjusted ");
+ tprint("hbox");
+ break;
+ case vbox_group:
+ tprint("vbox");
+ break;
+ case vtop_group:
+ tprint("vtop");
+ break;
+ case align_group:
+ case no_align_group:
+ if (cur_group == no_align_group)
+ tprint("no ");
+ tprint("align");
+ break;
+ case output_group:
+ tprint("output");
+ break;
+ case disc_group:
+ tprint("disc");
+ break;
+ case insert_group:
+ tprint("insert");
+ break;
+ case vcenter_group:
+ tprint("vcenter");
+ break;
+ case math_group:
+ case math_choice_group:
+ case math_shift_group:
+ case math_left_group:
+ tprint("math");
+ if (cur_group == math_choice_group)
+ tprint(" choice");
+ else if (cur_group == math_shift_group)
+ tprint(" shift");
+ else if (cur_group == math_left_group)
+ tprint(" left");
+ break;
+ } /* there are no other cases */
+ tprint(" group (level ");
+ print_int(cur_level);
+ print_char(')');
+ if (saved_value(-1) != 0) { /* |saved_line| */
+ if (e)
+ tprint(" entered at line ");
+ else
+ tprint(" at line ");
+ print_int(saved_value(-1)); /* |saved_line| */
+ }
+}
+
+
+@ The |group_trace| procedure is called when a new level of grouping
+begins (|e=false|) or ends (|e=true|) with |saved_value(-1)| containing the
+line number.
+
+@c
+void group_trace(boolean e)
+{
+ begin_diagnostic();
+ print_char('{');
+ if (e)
+ tprint("leaving ");
+ else
+ tprint("entering ");
+ print_group(e);
+ print_char('}');
+ end_diagnostic(false);
+}
+
+@ A group entered (or a conditional started) in one file may end in a
+different file. Such slight anomalies, although perfectly legitimate,
+may cause errors that are difficult to locate. In order to be able to
+give a warning message when such anomalies occur, \eTeX\ uses the
+|grp_stack| and |if_stack| arrays to record the initial |cur_boundary|
+and |cond_ptr| values for each input file.
+
+@c
+save_pointer *grp_stack; /* initial |cur_boundary| */
+halfword *if_stack; /* initial |cond_ptr| */
+
+
+@ When a group ends that was apparently entered in a different input
+file, the |group_warning| procedure is invoked in order to update the
+|grp_stack|. If moreover \.{\\tracingnesting} is positive we want to
+give a warning message. The situation is, however, somewhat complicated
+by two facts: (1)~There may be |grp_stack| elements without a
+corresponding \.{\\input} file or \.{\\scantokens} pseudo file (e.g.,
+error insertions from the terminal); and (2)~the relevant information is
+recorded in the |name_field| of the |input_stack| only loosely
+synchronized with the |in_open| variable indexing |grp_stack|.
+
+@c
+void group_warning(void)
+{
+ int i; /* index into |grp_stack| */
+ boolean w; /* do we need a warning? */
+ base_ptr = input_ptr;
+ input_stack[base_ptr] = cur_input; /* store current state */
+ i = in_open;
+ w = false;
+ while ((grp_stack[i] == cur_boundary) && (i > 0)) {
+ /* Set variable |w| to indicate if this case should be reported */
+ /* This code scans the input stack in order to determine the type of the
+ current input file. */
+ if (tracing_nesting > 0) {
+ while ((input_stack[base_ptr].state_field == token_list) ||
+ (input_stack[base_ptr].index_field > i))
+ decr(base_ptr);
+ if (input_stack[base_ptr].name_field > 17)
+ w = true;
+ }
+
+ grp_stack[i] = save_value(save_ptr);
+ decr(i);
+ }
+ if (w) {
+ tprint_nl("Warning: end of ");
+ print_group(true);
+ tprint(" of a different file");
+ print_ln();
+ if (tracing_nesting > 1)
+ show_context();
+ if (history == spotless)
+ history = warning_issued;
+ }
+}
+
+
+@ When a conditional ends that was apparently started in a different
+input file, the |if_warning| procedure is invoked in order to update the
+|if_stack|. If moreover \.{\\tracingnesting} is positive we want to
+give a warning message (with the same complications as above).
+
+@c
+void if_warning(void)
+{
+ int i; /* index into |if_stack| */
+ boolean w; /* do we need a warning? */
+ base_ptr = input_ptr;
+ input_stack[base_ptr] = cur_input; /* store current state */
+ i = in_open;
+ w = false;
+ while (if_stack[i] == cond_ptr) {
+ /* Set variable |w| to... */
+ if (tracing_nesting > 0) {
+ while ((input_stack[base_ptr].state_field == token_list) ||
+ (input_stack[base_ptr].index_field > i))
+ decr(base_ptr);
+ if (input_stack[base_ptr].name_field > 17)
+ w = true;
+ }
+
+ if_stack[i] = vlink(cond_ptr);
+ decr(i);
+ }
+ if (w) {
+ tprint_nl("Warning: end of ");
+ print_cmd_chr(if_test_cmd, cur_if);
+ print_if_line(if_line);
+ tprint(" of a different file");
+ print_ln();
+ if (tracing_nesting > 1)
+ show_context();
+ if (history == spotless)
+ history = warning_issued;
+ }
+}
+
+
+@ Conversely, the |file_warning| procedure is invoked when a file ends
+and some groups entered or conditionals started while reading from that
+file are still incomplete.
+
+@c
+void file_warning(void)
+{
+ halfword p; /* saved value of |save_ptr| or |cond_ptr| */
+ int l; /* saved value of |cur_level| or |if_limit| */
+ int c; /* saved value of |cur_group| or |cur_if| */
+ int i; /* saved value of |if_line| */
+ p = save_ptr;
+ l = cur_level;
+ c = cur_group;
+ save_ptr = cur_boundary;
+ while (grp_stack[in_open] != save_ptr) {
+ decr(cur_level);
+ tprint_nl("Warning: end of file when ");
+ print_group(true);
+ tprint(" is incomplete");
+ cur_group = save_level(save_ptr);
+ save_ptr = save_value(save_ptr);
+ }
+ save_ptr = p;
+ cur_level = (quarterword) l;
+ cur_group = (group_code) c; /* restore old values */
+ p = cond_ptr;
+ l = if_limit;
+ c = cur_if;
+ i = if_line;
+ while (if_stack[in_open] != cond_ptr) {
+ tprint_nl("Warning: end of file when ");
+ print_cmd_chr(if_test_cmd, cur_if);
+ if (if_limit == fi_code)
+ tprint_esc("else");
+ print_if_line(if_line);
+ tprint(" is incomplete");
+ if_line = if_line_field(cond_ptr);
+ cur_if = if_limit_subtype(cond_ptr);
+ if_limit = if_limit_type(cond_ptr);
+ cond_ptr = vlink(cond_ptr);
+ }
+ cond_ptr = p;
+ if_limit = l;
+ cur_if = c;
+ if_line = i; /* restore old values */
+ print_ln();
+ if (tracing_nesting > 1)
+ show_context();
+ if (history == spotless)
+ history = warning_issued;
+}
+
+@ @c
+halfword last_line_fill; /* the |par_fill_skip| glue node of the new paragraph */
+
+
+@ The lua interface needs some extra functions. The functions
+themselves are quite boring, but they are handy because otherwise this
+internal stuff has to be accessed from C directly, where lots of the
+defines are not available.
+
+@c
+#define get_tex_dimen_register(j) dimen(j)
+#define get_tex_skip_register(j) skip(j)
+#define get_tex_count_register(j) count(j)
+#define get_tex_attribute_register(j) attribute(j)
+#define get_tex_box_register(j) box(j)
+
+int set_tex_dimen_register(int j, scaled v)
+{
+ int a; /* return non-nil for error */
+ if (global_defs > 0)
+ a = 4;
+ else
+ a = 0;
+ word_define(j + scaled_base, v);
+ return 0;
+}
+
+int set_tex_skip_register(int j, halfword v)
+{
+ int a; /* return non-nil for error */
+ if (global_defs > 0)
+ a = 4;
+ else
+ a = 0;
+ if (type(v) != glue_spec_node)
+ return 1;
+ word_define(j + skip_base, v);
+ return 0;
+}
+
+int set_tex_count_register(int j, scaled v)
+{
+ int a; /* return non-nil for error */
+ if (global_defs > 0)
+ a = 4;
+ else
+ a = 0;
+ word_define(j + count_base, v);
+ return 0;
+}
+
+int set_tex_box_register(int j, scaled v)
+{
+ int a; /* return non-nil for error */
+ if (global_defs > 0)
+ a = 4;
+ else
+ a = 0;
+ define(j + box_base, box_ref_cmd, v);
+ return 0;
+}
+
+int set_tex_attribute_register(int j, scaled v)
+{
+ int a; /* return non-nil for error */
+ if (global_defs > 0)
+ a = 4;
+ else
+ a = 0;
+ if (j > max_used_attr)
+ max_used_attr = j;
+ attr_list_cache = cache_disabled;
+ word_define(j + attribute_base, v);
+ return 0;
+}
+
+int get_tex_toks_register(int j)
+{
+ str_number s;
+ s = get_nullstr();
+ if (toks(j) != null) {
+ s = tokens_to_string(toks(j));
+ }
+ return s;
+}
+
+int set_tex_toks_register(int j, lstring s)
+{
+ halfword ref;
+ int a;
+ ref = get_avail();
+ (void) str_toks(s);
+ set_token_ref_count(ref, 0);
+ set_token_link(ref, token_link(temp_token_head));
+ if (global_defs > 0)
+ a = 4;
+ else
+ a = 0;
+ define(j + toks_base, call_cmd, ref);
+ return 0;
+}
+
+scaled get_tex_box_width(int j)
+{
+ halfword q = box(j);
+ if (q != null)
+ return width(q);
+ return 0;
+}
+
+int set_tex_box_width(int j, scaled v)
+{
+ halfword q = box(j);
+ if (q == null)
+ return 1;
+ width(q) = v;
+ return 0;
+}
+
+scaled get_tex_box_height(int j)
+{
+ halfword q = box(j);
+ if (q != null)
+ return height(q);
+ return 0;
+}
+
+int set_tex_box_height(int j, scaled v)
+{
+ halfword q = box(j);
+ if (q == null)
+ return 1;
+ height(q) = v;
+ return 0;
+}
+
+
+scaled get_tex_box_depth(int j)
+{
+ halfword q = box(j);
+ if (q != null)
+ return depth(q);
+ return 0;
+}
+
+int set_tex_box_depth(int j, scaled v)
+{
+ halfword q = box(j);
+ if (q == null)
+ return 1;
+ depth(q) = v;
+ return 0;
+}
+
+
+@ 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.
+
+@c
+int synctexoption;
+
+
+@ 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.
+
+@c
+int synctexoffset; /* holds the true value of |synctex_code| */
+
+
+@ 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.
+
+
+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.
+
+{\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@>
+
+
+@ Here are extra variables for Web2c. (This numbering of the
+system-dependent section allows easy integration of Web2c and e-\TeX, etc.)
+@^<system dependencies@>
+
+@c
+pool_pointer edit_name_start; /* where the filename to switch to starts */
+int edit_name_length, edit_line; /* what line to start editing at */
+int ipcon; /* level of IPC action, 0 for none [default] */
+boolean stop_at_space; /* whether |more_name| returns false for space */
+
+@ The |edit_name_start| will be set to point into |str_pool| somewhere after
+its beginning if \TeX\ is supposed to switch to an editor on exit.
+
+@c
+int shellenabledp;
+int restrictedshell;
+char *output_comment;
+
+@ Are we printing extra info as we read the format file?
+
+@c
+boolean debug_format_file;
diff --git a/Build/source/texk/web2c/luatexdir/tex/filename.c b/Build/source/texk/web2c/luatexdir/tex/filename.c
deleted file mode 100644
index f6b9746e976..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/filename.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* filename.c
-
- Copyright 2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "tokens.h"
-#include "commands.h"
-
-
-static const char _svn_version[] =
- "$Id: filename.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/filename.c $";
-
-
-#define wake_up_terminal() ;
-#define clear_terminal() ;
-
-#define cur_length (pool_ptr - str_start_macro(str_ptr))
-
-#define batch_mode 0 /* omits all stops and omits terminal output */
-#define nonstop_mode 1 /* omits all stops */
-#define scroll_mode 2 /* omits error stops */
-#define error_stop_mode 3 /* stops at every opportunity to interact */
-#define biggest_char 1114111
-
-/* put |ASCII_code| \# at the end of |str_pool| */
-#define append_char(A) str_pool[pool_ptr++]=(A)
-#define str_room(A) check_pool_overflow((pool_ptr+(A)))
-
-/*
- 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 now is the first of the system-dependent routines for file name scanning.
- @^system dependencies@> */
-
-static void begin_name(void)
-{
- area_delimiter = 0;
- ext_delimiter = 0;
- quoted_filename = false;
-}
-
-/* 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@> */
-
-static boolean more_name(ASCII_code c)
-{
- if (c == ' ' && stop_at_space && (!quoted_filename)) {
- return false;
- } else if (c == '"') {
- quoted_filename = !quoted_filename;
- return true;
- } else {
- str_room(1);
- append_char(c); /* contribute |c| to the current string */
- if (ISDIRSEP(c)) {
- area_delimiter = cur_length;
- ext_delimiter = 0;
- } else if (c == '.')
- ext_delimiter = cur_length;
- return true;
- }
-}
-
-/* The third.
- @^system dependencies@>
-
-*/
-
-static void end_name(void)
-{
- if (str_ptr + 3 > (max_strings + string_offset))
- overflow_string("number of strings", max_strings - init_str_ptr);
- /* @:TeX capacity exceeded number of strings}{\quad number of strings@> */
-
- if (area_delimiter == 0) {
- cur_area = get_nullstr();
- } else {
- cur_area = str_ptr;
- str_start_macro(str_ptr + 1) =
- str_start_macro(str_ptr) + area_delimiter;
- incr(str_ptr);
- }
- if (ext_delimiter == 0) {
- cur_ext = get_nullstr();
- cur_name = make_string();
- } else {
- 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();
- }
-}
-
-/* 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.
-*/
-
-void scan_file_name(void)
-{
- name_in_progress = true;
- begin_name();
- /* @<Get the next non-blank non-call token@>; */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
-
- while (true) {
- if ((cur_cmd > other_char_cmd) || (cur_chr > biggest_char)) { /* not a character */
- back_input();
- break;
- }
- /* 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 == ' ') && (state != token_list) && (loc > limit)
- && !quoted_filename)
- break;
- if (cur_chr > 127) {
- unsigned char *bytes;
- unsigned char thebytes[4];
- unsigned char *end = (unsigned char *)utf8_idpb((char *) thebytes, cur_chr);
- bytes = thebytes;
- while (bytes<end) {
- if (!more_name(*bytes))
- break;
- bytes++;
- }
- } else {
- if (!more_name(cur_chr))
- break;
- }
- get_x_token();
- }
- end_name();
- name_in_progress = 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|.
-*/
-
-#define pack_cur_name() pack_file_name(cur_name,cur_area,cur_ext)
-
-void pack_job_name(const char *s)
-{ /* |s = ".log"|, |".dvi"|, or |format_extension| */
- cur_area = get_nullstr();
- cur_ext = maketexstring(s);
- cur_name = job_name;
- pack_cur_name();
-}
-
-/* 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.
-*/
-
-void prompt_file_name(const char *s, const char *e)
-{
- int k; /* index into |buffer| */
- str_number saved_cur_name; /* to catch empty terminal input */
- char prompt[256];
- str_number texprompt;
- char *ar, *na, *ex;
- saved_cur_name = cur_name;
- if (interaction == scroll_mode) {
- wake_up_terminal();
- }
- ar = xstrdup(makecstring(cur_area));
- na = xstrdup(makecstring(cur_name));
- ex = xstrdup(makecstring(cur_ext));
- if (strcmp(s, "input file name") == 0) { /* @.I can't find file x@> */
- snprintf(prompt, 255, "I can't find file `%s%s%s'.", ar, na, ex);
- } else { /*@.I can't write on file x@> */
- snprintf(prompt, 255, "I can't write on file `%s%s%s'.", ar, na, ex);
- }
- free(ar);
- free(na);
- free(ex);
- texprompt = maketexstring((char *) prompt);
- do_print_err(texprompt);
- flush_str(texprompt);
- if ((strcmp(e, ".tex") == 0) || (strcmp(e, "") == 0))
- show_context();
- tprint_nl("Please type another "); /*@.Please type...@> */
- tprint(s);
- if (interaction < scroll_mode)
- fatal_error(maketexstring
- ("*** (job aborted, file error in nonstop mode)"));
- clear_terminal();
- texprompt = maketexstring(": ");
- prompt_input(texprompt);
- flush_str(texprompt);
- begin_name();
- k = first;
- while ((buffer[k] == ' ') && (k < last))
- k++;
- while (true) {
- if (k == last)
- break;
- if (!more_name(buffer[k]))
- break;
- k++;
- }
- end_name();
- if (cur_ext == get_nullstr())
- cur_ext = maketexstring(e);
- if (length(cur_name) == 0)
- cur_name = saved_cur_name;
- pack_cur_name();
-}
-
-
-str_number make_name_string(void)
-{
- int k; /* index into |nameoffile| */
- pool_pointer save_area_delimiter, save_ext_delimiter;
- boolean save_name_in_progress, save_stop_at_space;
- str_number ret;
- if ((pool_ptr + namelength > pool_size) ||
- (str_ptr == max_strings) || (cur_length > 0)) {
- ret = maketexstring("?");
- } else {
- for (k = 1; k <= namelength; k++)
- append_char(nameoffile[k]);
- ret = make_string();
- }
- /* At this point we also reset |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) && (more_name(nameoffile[k])))
- 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;
- return ret;
-}
-
-
-
-void print_file_name(str_number n, str_number a, str_number e)
-{
- boolean must_quote; /* whether to quote the filename */
- pool_pointer j; /* index into |str_pool| */
- must_quote = false;
- if (a != 0) {
- j = str_start_macro(a);
- while ((!must_quote) && (j < str_start_macro(a + 1))) {
- must_quote = (str_pool[j] == ' ');
- incr(j);
- }
- }
- if (n != 0) {
- j = str_start_macro(n);
- while ((!must_quote) && (j < str_start_macro(n + 1))) {
- must_quote = (str_pool[j] == ' ');
- incr(j);
- }
- }
- if (e != 0) {
- j = str_start_macro(e);
- while ((!must_quote) && (j < str_start_macro(e + 1))) {
- must_quote = (str_pool[j] == ' ');
- incr(j);
- }
- }
- /* FIXME: Alternative is to assume that any filename that has to be quoted has
- at least one quoted component...if we pick this, a number of insertions
- of |print_file_name| should go away.
- |must_quote|:=((|a|<>0)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)
- print_char('"');
- if (a != 0) {
- for (j = str_start_macro(a); j <= str_start_macro(a + 1) - 1; j++)
- if (str_pool[j] != '"')
- print_char(str_pool[j]);
- }
- if (n != 0) {
- for (j = str_start_macro(n); j <= str_start_macro(n + 1) - 1; j++)
- if (str_pool[j] != '"')
- print_char(str_pool[j]);
- }
- if (e != 0) {
- for (j = str_start_macro(e); j <= str_start_macro(e + 1) - 1; j++)
- if (str_pool[j] != '"')
- print_char(str_pool[j]);
- }
- if (must_quote)
- print_char('"');
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/filename.h b/Build/source/texk/web2c/luatexdir/tex/filename.h
new file mode 100644
index 00000000000..d0e54283436
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/filename.h
@@ -0,0 +1,34 @@
+/* filename.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: filename.h 3376 2010-01-25 16:50:23Z taco $ */
+
+#ifndef FILENAME_H
+# define FILENAME_H
+
+extern void scan_file_name(void);
+extern void scan_file_name_toks(void);
+extern char *pack_job_name(const char *s);
+extern char *prompt_file_name(const char *s, const char *e);
+extern void tprint_file_name(unsigned char *n, unsigned char *a,
+ unsigned char *e);
+extern void print_file_name(str_number, str_number, str_number);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/filename.w b/Build/source/texk/web2c/luatexdir/tex/filename.w
new file mode 100644
index 00000000000..239127c5852
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/filename.w
@@ -0,0 +1,349 @@
+% filename.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: filename.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/filename.w $";
+
+
+@ 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 now is the first of the system-dependent routines for file name scanning.
+@^system dependencies@>
+
+@c
+static void begin_name(void)
+{
+ area_delimiter = 0;
+ ext_delimiter = 0;
+ quoted_filename = false;
+}
+
+@ 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@>
+
+@c
+static boolean more_name(ASCII_code c)
+{
+ if (c == ' ' && stop_at_space && (!quoted_filename)) {
+ return false;
+ } else if (c == '"') {
+ quoted_filename = !quoted_filename;
+ return true;
+ } else {
+ str_room(1);
+ append_char(c); /* contribute |c| to the current string */
+ if (ISDIRSEP(c)) {
+ area_delimiter = (pool_pointer) cur_length;
+ ext_delimiter = 0;
+ } else if (c == '.')
+ ext_delimiter = (pool_pointer) cur_length;
+ return true;
+ }
+}
+
+@ The third.
+@^system dependencies@>
+
+@c
+static void end_name(void)
+{
+ unsigned char *s;
+ if (str_ptr + 3 > (max_strings + STRING_OFFSET))
+ overflow("number of strings",
+ (unsigned) (max_strings - init_str_ptr + STRING_OFFSET));
+ /* at this point, the full string lives in |cur_string| */
+ if (area_delimiter == 0) {
+ cur_area = get_nullstr();
+ } else {
+ s = (unsigned char *) xstrdup((char *) (cur_string + area_delimiter));
+ cur_string[area_delimiter] = '\0';
+ cur_length = (unsigned) strlen((char *) cur_string);
+ cur_area = make_string();
+ cur_length = (unsigned) strlen((char *) s);
+ cur_string = s;
+ }
+ if (ext_delimiter == 0) {
+ cur_name = make_string();
+ cur_ext = get_nullstr();
+ } else {
+ int l = (ext_delimiter - area_delimiter - 1);
+ s = (unsigned char *) xstrdup((char *) (cur_string + l));
+ cur_string[l] = '\0';
+ cur_length = (unsigned) strlen((char *) cur_string);
+ cur_name = make_string();
+ cur_length = (unsigned) strlen((char *) s);
+ cur_string = s;
+ cur_ext = make_string();
+ }
+}
+
+@ 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.
+
+@c
+void scan_file_name(void)
+{
+ str_number u = 0;
+ name_in_progress = true;
+ begin_name();
+ /* Get the next non-blank non-call token; */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ while (true) {
+ if ((cur_cmd > other_char_cmd) || (cur_chr > biggest_char)) { /* not a character */
+ back_input();
+ break;
+ }
+ /* 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 == ' ') && (istate != token_list) && (iloc > ilimit)
+ && !quoted_filename)
+ break;
+ if (cur_chr > 127) {
+ unsigned char *bytes;
+ unsigned char *thebytes;
+ thebytes = uni2str((unsigned) cur_chr);
+ bytes = thebytes;
+ while (*bytes) {
+ if (!more_name(*bytes))
+ break;
+ bytes++;
+ }
+ xfree(thebytes);
+ } else {
+ if (!more_name(cur_chr))
+ break;
+ }
+ u = save_cur_string();
+ get_x_token();
+ restore_cur_string(u);
+ }
+ end_name();
+ name_in_progress = false;
+}
+
+@ This function constructs a the three file name strings from a token list
+@c
+void scan_file_name_toks(void)
+{
+ char *a, *n, *e, *s = NULL;
+ int i, l = 0;
+ (void) scan_toks(false, true);
+ s = tokenlist_to_cstring(def_ref, true, &l);
+ a = n = s;
+ e = NULL;
+ for (i = 0; i < l; i++) {
+ if (ISDIRSEP(s[i])) {
+ n = s + i + 1;
+ e = NULL;
+ } else if (s[i] == '.') {
+ e = s + i;
+ }
+ }
+ if (n != s) { /* explicit area */
+ cur_area = maketexlstring(a, (size_t) (n - a));
+ } else {
+ cur_area = get_nullstr();
+ }
+ if (e != NULL) { /* explicit extension */
+ cur_name = maketexlstring(n, (size_t) (e - n));
+ cur_ext = maketexstring(e);
+ } else {
+ cur_name = maketexstring(n);
+ cur_ext = get_nullstr();
+ }
+}
+
+
+
+
+@ 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|.
+
+@c
+char *pack_job_name(const char *s)
+{ /* |s = ".log"|, |".dvi"|, or |format_extension| */
+ cur_area = get_nullstr();
+ cur_ext = maketexstring(s);
+ cur_name = job_name;
+ return pack_file_name(cur_name, cur_area, cur_ext);
+}
+
+@ 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|, and |cur_ext| are
+ ready for another attempt at file opening.
+
+@c
+char *prompt_file_name(const char *s, const char *e)
+{
+ int k; /* index into |buffer| */
+ str_number saved_cur_name; /* to catch empty terminal input */
+ char prompt[256];
+ char *ar, *na, *ex;
+ saved_cur_name = cur_name;
+ if (interaction == scroll_mode) {
+ wake_up_terminal();
+ }
+ ar = makecstring(cur_area);
+ na = makecstring(cur_name);
+ ex = makecstring(cur_ext);
+ if (strcmp(s, "input file name") == 0) {
+ snprintf(prompt, 255, "I can't find file `%s%s%s'.", ar, na, ex);
+ } else {
+ snprintf(prompt, 255, "I can't write on file `%s%s%s'.", ar, na, ex);
+ }
+ free(ar);
+ free(na);
+ free(ex);
+ print_err(prompt);
+ if ((strcmp(e, ".tex") == 0) || (strcmp(e, "") == 0))
+ show_context();
+ tprint_nl("Please type another ");
+ tprint(s);
+ if (interaction < scroll_mode)
+ fatal_error("*** (job aborted, file error in nonstop mode)");
+ clear_terminal();
+ prompt_input(": ");
+ begin_name();
+ k = first;
+ while ((buffer[k] == ' ') && (k < last))
+ k++;
+ while (true) {
+ if (k == last)
+ break;
+ if (!more_name(buffer[k]))
+ break;
+ k++;
+ }
+ end_name();
+ if (cur_ext == get_nullstr())
+ cur_ext = maketexstring(e);
+ if (str_length(cur_name) == 0)
+ cur_name = saved_cur_name;
+ return pack_file_name(cur_name, cur_area, cur_ext);
+}
+
+@ @c
+void tprint_file_name(unsigned char *n, unsigned char *a, unsigned char *e)
+{
+ boolean must_quote; /* whether to quote the filename */
+ unsigned char *j; /* index into string */
+ must_quote = false;
+ if (a != NULL) {
+ j = a;
+ while ((!must_quote) && (*j)) {
+ must_quote = (*j == ' ');
+ j++;
+ }
+ }
+ if (n != NULL) {
+ j = n;
+ while ((!must_quote) && (*j)) {
+ must_quote = (*j == ' ');
+ j++;
+ }
+ }
+ if (e != NULL) {
+ j = e;
+ while ((!must_quote) && (*j)) {
+ must_quote = (*j == ' ');
+ j++;
+ }
+ }
+ /* FIXME: Alternative is to assume that any filename that has to be quoted has
+ at least one quoted component...if we pick this, a number of insertions
+ of |print_file_name| should go away.
+ |must_quote|:=((|a|<>0)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)
+ print_char('"');
+ if (a != NULL) {
+ for (j = a; *j; j++)
+ if (*j != '"')
+ print_char(*j);
+ }
+ if (n != NULL) {
+ for (j = n; *j; j++)
+ if (*j != '"')
+ print_char(*j);
+ }
+ if (e != NULL) {
+ for (j = e; *j; j++)
+ if (*j != '"')
+ print_char(*j);
+ }
+ if (must_quote)
+ print_char('"');
+}
+
+@ @c
+void print_file_name(str_number n, str_number a, str_number e)
+{
+ char *nam, *are, *ext;
+ nam = makecstring(n);
+ are = makecstring(a);
+ ext = makecstring(e);
+ tprint_file_name((unsigned char *) nam, (unsigned char *) are,
+ (unsigned char *) ext);
+ free(nam);
+ free(are);
+ free(ext);
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/inputstack.h b/Build/source/texk/web2c/luatexdir/tex/inputstack.h
new file mode 100644
index 00000000000..e77e9259c8f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/inputstack.h
@@ -0,0 +1,353 @@
+/* inputstack.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: inputstack.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef INPUTSTACK_H
+# define INPUTSTACK_H 1
+
+/*
+ The state of \TeX's input mechanism appears in the input stack, whose
+ entries are records with six fields, called |state|, |index|, |start|, |loc|,
+ |limit|, and |name|.
+*/
+
+typedef struct in_state_record {
+ halfword start_field;
+ halfword loc_field;
+ halfword limit_field;
+ halfword name_field;
+ halfword ocp_lstack_field; /* used for omega translation processes */
+ int synctex_tag_field; /* stack the tag of the current file */
+ halfword ocp_no_field:16; /* used for omega translation processes */
+ int cattable_field:16; /* category table used by the current line (see textoken.c) */
+ quarterword state_field:8;
+ quarterword index_field:8;
+ boolean partial_field:8; /* is the current line partial? (see textoken.c) */
+ boolean nofilter_field:8; /* used by token filtering */
+} in_state_record;
+
+extern in_state_record *input_stack;
+extern int input_ptr;
+extern int max_in_stack;
+extern in_state_record cur_input; /* the ``top'' input state */
+
+# define iloc cur_input.loc_field /* location of first unread character in |buffer| */
+# define istate cur_input.state_field /* current scanner state */
+# define iindex cur_input.index_field /* reference for buffer information */
+# define istart cur_input.start_field /* starting position in |buffer| */
+# define ilimit cur_input.limit_field /* end of current line in |buffer| */
+# define iname cur_input.name_field /* name of the current file */
+# define nofilter cur_input.nofilter_field /* is token filtering explicitly disallowed? */
+# define synctex_tag cur_input.synctex_tag_field /* tag of the current file */
+# define current_ocp_lstack cur_input.ocp_lstack_field /* name of the current ocp */
+# define current_ocp_no cur_input.ocp_no_field /* name of the current ocp */
+# define line_catcode_table cur_input.cattable_field
+# define line_partial cur_input.partial_field
+
+/*
+Let's look more closely now at the control variables
+(|state|,~|index|,~|start|,~|loc|,~|limit|,~|name|),
+assuming that \TeX\ is reading a line of characters that have been input
+from some file or from the user's terminal. There is an array called
+|buffer| that acts as a stack of all lines of characters that are
+currently being read from files, including all lines on subsidiary
+levels of the input stack that are not yet completed. \TeX\ will return to
+the other lines when it is finished with the present input file.
+
+(Incidentally, on a machine with byte-oriented addressing, it might be
+appropriate to combine |buffer| with the |str_pool| array,
+letting the buffer entries grow downward from the top of the string pool
+and checking that these two tables don't bump into each other.)
+
+The line we are currently working on begins in position |start| of the
+buffer; the next character we are about to read is |buffer[loc]|; and
+|limit| is the location of the last character present. If |loc>limit|,
+the line has been completely read. Usually |buffer[limit]| is the
+|end_line_char|, denoting the end of a line, but this is not
+true if the current line is an insertion that was entered on the user's
+terminal in response to an error message.
+
+The |name| variable is a string number that designates the name of
+the current file, if we are reading a text file. It is zero if we
+are reading from the terminal; it is |n+1| if we are reading from
+input stream |n|, where |0<=n<=16|. (Input stream 16 stands for
+an invalid stream number; in such cases the input is actually from
+the terminal, under control of the procedure |read_toks|.)
+Finally |18<=name<=20| indicates that we are reading a pseudo file
+created by the \.{\\scantokens} or \.{\\scantextokens} command.
+
+The |state| variable has one of three values, when we are scanning such
+files:
+$$\baselineskip 15pt\vbox{\halign{#\hfil\cr
+1) |state=mid_line| is the normal state.\cr
+2) |state=skip_blanks| is like |mid_line|, but blanks are ignored.\cr
+3) |state=new_line| is the state at the beginning of a line.\cr}}$$
+These state values are assigned numeric codes so that if we add the state
+code to the next character's command code, we get distinct values. For
+example, `|mid_line+spacer|' stands for the case that a blank
+space character occurs in the middle of a line when it is not being
+ignored; after this case is processed, the next value of |state| will
+be |skip_blanks|.
+*/
+
+# define max_char_code 15 /* largest catcode for individual characters */
+
+typedef enum {
+ mid_line = 1, /* |state| code when scanning a line of characters */
+ skip_blanks = 2 + max_char_code, /* |state| code when ignoring blanks */
+ new_line = 3 + max_char_code + max_char_code, /* |state| code at start of line */
+} state_codes;
+
+/*
+Additional information about the current line is available via the
+|index| variable, which counts how many lines of characters are present
+in the buffer below the current level. We have |index=0| when reading
+from the terminal and prompting the user for each line; then if the user types,
+e.g., `\.{\\input paper}', we will have |index=1| while reading
+the file \.{paper.tex}. However, it does not follow that |index| is the
+same as the input stack pointer, since many of the levels on the input
+stack may come from token lists. For example, the instruction `\.{\\input
+paper}' might occur in a token list.
+
+The global variable |in_open| is equal to the |index|
+value of the highest non-token-list level. Thus, the number of partially read
+lines in the buffer is |in_open+1|, and we have |in_open=index|
+when we are not reading a token list.
+
+If we are not currently reading from the terminal, or from an input
+stream, we are reading from the file variable |input_file[index]|. We use
+the notation |terminal_input| as a convenient abbreviation for |name=0|,
+and |cur_file| as an abbreviation for |input_file[index]|.
+
+The global variable |line| contains the line number in the topmost
+open file, for use in error messages. If we are not reading from
+the terminal, |line_stack[index]| holds the line number for the
+enclosing level, so that |line| can be restored when the current
+file has been read. Line numbers should never be negative, since the
+negative of the current line number is used to identify the user's output
+routine in the |mode_line| field of the semantic nest entries.
+
+If more information about the input state is needed, it can be
+included in small arrays like those shown here. For example,
+the current page or segment number in the input file might be
+put into a variable |@!page|, maintained for enclosing levels in
+`\ignorespaces|@!page_stack:array[1..max_in_open] of integer|\unskip'
+by analogy with |line_stack|.
+@^system dependencies@>
+*/
+
+# define terminal_input (iname==0) /* are we reading from the terminal? */
+# define cur_file input_file[iindex] /* the current |alpha_file| variable */
+
+extern int in_open;
+extern int open_parens;
+extern alpha_file *input_file;
+extern int line;
+extern int *line_stack;
+extern str_number *source_filename_stack;
+extern char **full_source_filename_stack;
+
+/*
+Users of \TeX\ sometimes forget to balance left and right braces properly,
+and one of the ways \TeX\ tries to spot such errors is by considering an
+input file as broken into subfiles by control sequences that
+are declared to be \.{\\outer}.
+
+A variable called |scanner_status| tells \TeX\ whether or not to complain
+when a subfile ends. This variable has six possible values:
+
+\yskip\hang|normal|, means that a subfile can safely end here without incident.
+
+\yskip\hang|skipping|, means that a subfile can safely end here, but not a file,
+because we're reading past some conditional text that was not selected.
+
+\yskip\hang|defining|, means that a subfile shouldn't end now because a
+macro is being defined.
+
+\yskip\hang|matching|, means that a subfile shouldn't end now because a
+macro is being used and we are searching for the end of its arguments.
+
+\yskip\hang|aligning|, means that a subfile shouldn't end now because we are
+not finished with the preamble of an \.{\\halign} or \.{\\valign}.
+
+\yskip\hang|absorbing|, means that a subfile shouldn't end now because we are
+reading a balanced token list for \.{\\message}, \.{\\write}, etc.
+
+\yskip\noindent
+If the |scanner_status| is not |normal|, the variable |warning_index| points
+to the |eqtb| location for the relevant control sequence name to print
+in an error message.
+*/
+
+typedef enum {
+ skipping = 1, /* |scanner_status| when passing conditional text */
+ defining = 2, /* |scanner_status| when reading a macro definition */
+ matching = 3, /* |scanner_status| when reading macro arguments */
+ aligning = 4, /* |scanner_status| when reading an alignment preamble */
+ absorbing = 5, /* |scanner_status| when reading a balanced text */
+} scanner_states;
+
+extern int scanner_status;
+extern pointer warning_index;
+extern pointer def_ref;
+
+extern void runaway(void);
+
+/*
+However, the discussion about input state really applies only to the
+case that we are inputting from a file. There is another important case,
+namely when we are currently getting input from a token list. In this case
+|state=token_list|, and the conventions about the other state variables
+are different:
+
+\yskip\hang|loc| is a pointer to the current node in the token list, i.e.,
+the node that will be read next. If |loc=null|, the token list has been
+fully read.
+
+\yskip\hang|start| points to the first node of the token list; this node
+may or may not contain a reference count, depending on the type of token
+list involved.
+
+\yskip\hang|token_type|, which takes the place of |index| in the
+discussion above, is a code number that explains what kind of token list
+is being scanned.
+
+\yskip\hang|name| points to the |eqtb| address of the control sequence
+being expanded, if the current token list is a macro.
+
+\yskip\hang|param_start|, which takes the place of |limit|, tells where
+the parameters of the current macro begin in the |param_stack|, if the
+current token list is a macro.
+
+\yskip\noindent The |token_type| can take several values, depending on
+where the current token list came from:
+
+\yskip\hang|parameter|, if a parameter is being scanned;
+
+\hang|u_template|, if the \<u_j> part of an alignment
+template is being scanned;
+
+\hang|v_template|, if the \<v_j> part of an alignment
+template is being scanned;
+
+\hang|backed_up|, if the token list being scanned has been inserted as
+`to be read again'.
+
+\hang|inserted|, if the token list being scanned has been inserted as
+the text expansion of a \.{\\count} or similar variable;
+
+\hang|macro|, if a user-defined control sequence is being scanned;
+
+\hang|output_text|, if an \.{\\output} routine is being scanned;
+
+\hang|every_par_text|, if the text of \.{\\everypar} is being scanned;
+
+\hang|every_math_text|, if the text of \.{\\everymath} is being scanned;
+
+\hang|every_display_text|, if the text of \.{\\everydisplay} is being scanned;
+
+\hang|every_hbox_text|, if the text of \.{\\everyhbox} is being scanned;
+
+\hang|every_vbox_text|, if the text of \.{\\everyvbox} is being scanned;
+
+\hang|every_job_text|, if the text of \.{\\everyjob} is being scanned;
+
+\hang|every_cr_text|, if the text of \.{\\everycr} is being scanned;
+
+\hang|mark_text|, if the text of a \.{\\mark} is being scanned;
+
+\hang|write_text|, if the text of a \.{\\write} is being scanned.
+
+\yskip\noindent
+The codes for |output_text|, |every_par_text|, etc., are equal to a constant
+plus the corresponding codes for token list parameters |output_routine_loc|,
+|every_par_loc|, etc.
+
+The token list begins with a reference count if and
+only if |token_type>=macro|.
+@^reference counts@>
+
+Since \eTeX's additional token list parameters precede |toks_base|, the
+corresponding token types must precede |write_text|.
+*/
+
+# define token_list 0 /* |state| code when scanning a token list */
+# define token_type iindex /* type of current token list */
+# define param_start ilimit /* base of macro parameters in |param_stack| */
+
+
+typedef enum {
+ parameter = 0, /* |token_type| code for parameter */
+ u_template = 1, /* |token_type| code for \<u_j> template */
+ v_template = 2, /* |token_type| code for \<v_j> template */
+ backed_up = 3, /* |token_type| code for text to be reread */
+ inserted = 4, /* |token_type| code for inserted texts */
+ macro = 5, /* |token_type| code for defined control sequences */
+ output_text = 6, /* |token_type| code for output routines */
+ every_par_text = 7, /* |token_type| code for \.{\\everypar} */
+ every_math_text = 8, /* |token_type| code for \.{\\everymath} */
+ every_display_text = 9, /* |token_type| code for \.{\\everydisplay} */
+ every_hbox_text = 10, /* |token_type| code for \.{\\everyhbox} */
+ every_vbox_text = 11, /* |token_type| code for \.{\\everyvbox} */
+ every_job_text = 12, /* |token_type| code for \.{\\everyjob} */
+ every_cr_text = 13, /* |token_type| code for \.{\\everycr} */
+ mark_text = 14, /* |token_type| code for \.{\\topmark}, etc. */
+ every_eof_text = 15, /* |token_type| code for \.{\\everyeof} */
+ write_text = 16, /* |token_type| code for \.{\\write} */
+} token_types;
+
+extern pointer *param_stack;
+extern int param_ptr;
+extern int max_param_stack;
+
+extern int align_state;
+
+extern int base_ptr;
+
+extern void show_context(void);
+extern void set_trick_count(void);
+
+/* leave an input level, re-enter the old */
+# define pop_input() cur_input=input_stack[--input_ptr]
+
+extern void push_input(void);
+
+# define back_list(A) begin_token_list(A,backed_up) /* backs up a simple token list */
+# define ins_list(A) begin_token_list(A,inserted) /* inserts a simple token list */
+
+extern void begin_token_list(halfword p, quarterword t);
+extern void end_token_list(void);
+extern void back_input(void);
+extern int reinsert_token(boolean a, halfword pp);
+extern void begin_file_reading(void);
+extern void end_file_reading(void);
+extern void clear_for_error_prompt(void);
+
+extern void initialize_inputstack(void);
+
+extern halfword pseudo_files;
+extern void pseudo_from_string(void);
+extern void pseudo_start(void);
+extern void lua_string_start(void);
+extern boolean pseudo_input(void);
+extern void pseudo_close(void);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/inputstack.w b/Build/source/texk/web2c/luatexdir/tex/inputstack.w
new file mode 100644
index 00000000000..ecb620fb185
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/inputstack.w
@@ -0,0 +1,800 @@
+% inputstack.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: inputstack.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/inputstack.w $";
+
+@ @c
+#define end_line_char int_par(end_line_char_code)
+#define error_context_lines int_par(error_context_lines_code)
+
+
+in_state_record *input_stack = NULL;
+int input_ptr = 0; /* first unused location of |input_stack| */
+int max_in_stack = 0; /* largest value of |input_ptr| when pushing */
+in_state_record cur_input; /* the ``top'' input state */
+
+
+int in_open = 0; /* the number of lines in the buffer, less one */
+int open_parens = 0; /* the number of open text files */
+alpha_file *input_file = NULL;
+int line = 0; /* current line number in the current source file */
+int *line_stack = NULL;
+str_number *source_filename_stack = NULL;
+char **full_source_filename_stack = NULL;
+
+
+int scanner_status = 0; /* can a subfile end now? */
+pointer warning_index = null; /* identifier relevant to non-|normal| scanner status */
+pointer def_ref = null; /* reference count of token list being defined */
+
+
+
+@ Here is a procedure that uses |scanner_status| to print a warning message
+when a subfile has ended, and at certain other crucial times:
+
+@c
+void runaway(void)
+{
+ pointer p = null; /* head of runaway list */
+ if (scanner_status > skipping) {
+ switch (scanner_status) {
+ case defining:
+ tprint_nl("Runaway definition");
+ p = def_ref;
+ break;
+ case matching:
+ tprint_nl("Runaway argument");
+ p = temp_token_head;
+ break;
+ case aligning:
+ tprint_nl("Runaway preamble");
+ p = hold_token_head;
+ break;
+ case absorbing:
+ tprint_nl("Runaway text");
+ p = def_ref;
+ break;
+ default: /* there are no other cases */
+ break;
+ }
+ print_char('?');
+ print_ln();
+ show_token_list(token_link(p), null, error_line - 10);
+ }
+}
+
+
+@ The |param_stack| is an auxiliary array used to hold pointers to the token
+lists for parameters at the current level and subsidiary levels of input.
+This stack is maintained with convention (2), and it grows at a different
+rate from the others.
+
+@c
+pointer *param_stack = NULL; /* token list pointers for parameters */
+int param_ptr = 0; /* first unused entry in |param_stack| */
+int max_param_stack = 0; /* largest value of |param_ptr|, will be |<=param_size+9| */
+
+@ The input routines must also interact with the processing of
+\.{\\halign} and \.{\\valign}, since the appearance of tab marks and
+\.{\\cr} in certain places is supposed to trigger the beginning of special
+$v_j$ template text in the scanner. This magic is accomplished by an
+|align_state| variable that is increased by~1 when a `\.{\char'173}' is
+scanned and decreased by~1 when a `\.{\char'175}' is scanned. The |align_state|
+is nonzero during the $u_j$ template, after which it is set to zero; the
+$v_j$ template begins when a tab mark or \.{\\cr} occurs at a time that
+|align_state=0|.
+
+@c
+int align_state = 0; /* group level with respect to current alignment */
+
+
+@ Thus, the ``current input state'' can be very complicated indeed; there
+can be many levels and each level can arise in a variety of ways. The
+|show_context| procedure, which is used by \TeX's error-reporting routine to
+print out the current input state on all levels down to the most recent
+line of characters from an input file, illustrates most of these conventions.
+The global variable |base_ptr| contains the lowest level that was
+displayed by this procedure.
+
+@c
+int base_ptr = 0; /* shallowest level shown by |show_context| */
+
+
+@ The status at each level is indicated by printing two lines, where the first
+line indicates what was read so far and the second line shows what remains
+to be read. The context is cropped, if necessary, so that the first line
+contains at most |half_error_line| characters, and the second contains
+at most |error_line|. Non-current input levels whose |token_type| is
+`|backed_up|' are shown only if they have not been fully read.
+
+@c
+void print_token_list_type(int t)
+{
+ switch (t) {
+ case parameter:
+ tprint_nl("<argument> ");
+ break;
+ case u_template:
+ case v_template:
+ tprint_nl("<template> ");
+ break;
+ case backed_up:
+ if (iloc == null)
+ tprint_nl("<recently read> ");
+ else
+ tprint_nl("<to be read again> ");
+ break;
+ case inserted:
+ tprint_nl("<inserted text> ");
+ break;
+ case macro:
+ print_ln();
+ print_cs(iname);
+ break;
+ case output_text:
+ tprint_nl("<output> ");
+ break;
+ case every_par_text:
+ tprint_nl("<everypar> ");
+ break;
+ case every_math_text:
+ tprint_nl("<everymath> ");
+ break;
+ case every_display_text:
+ tprint_nl("<everydisplay> ");
+ break;
+ case every_hbox_text:
+ tprint_nl("<everyhbox> ");
+ break;
+ case every_vbox_text:
+ tprint_nl("<everyvbox> ");
+ break;
+ case every_job_text:
+ tprint_nl("<everyjob> ");
+ break;
+ case every_cr_text:
+ tprint_nl("<everycr> ");
+ break;
+ case mark_text:
+ tprint_nl("<mark> ");
+ break;
+ case every_eof_text:
+ tprint_nl("<everyeof> ");
+ break;
+ case write_text:
+ tprint_nl("<write> ");
+ break;
+ default:
+ tprint_nl("?");
+ break; /* this should never happen */
+ }
+}
+
+
+@ Here it is necessary to explain a little trick. We don't want to store a long
+string that corresponds to a token list, because that string might take up
+lots of memory; and we are printing during a time when an error message is
+being given, so we dare not do anything that might overflow one of \TeX's
+tables. So `pseudoprinting' is the answer: We enter a mode of printing
+that stores characters into a buffer of length |error_line|, where character
+$k+1$ is placed into \hbox{|trick_buf[k mod error_line]|} if
+|k<trick_count|, otherwise character |k| is dropped. Initially we set
+|tally:=0| and |trick_count:=1000000|; then when we reach the
+point where transition from line 1 to line 2 should occur, we
+set |first_count:=tally| and |trick_count:=@tmax@>(error_line,
+tally+1+error_line-half_error_line)|. At the end of the
+pseudoprinting, the values of |first_count|, |tally|, and
+|trick_count| give us all the information we need to print the two lines,
+and all of the necessary text is in |trick_buf|.
+
+Namely, let |l| be the length of the descriptive information that appears
+on the first line. The length of the context information gathered for that
+line is |k=first_count|, and the length of the context information
+gathered for line~2 is $m=\min(|tally|, |trick_count|)-k$. If |l+k<=h|,
+where |h=half_error_line|, we print |trick_buf[0..k-1]| after the
+descriptive information on line~1, and set |n:=l+k|; here |n| is the
+length of line~1. If $l+k>h$, some cropping is necessary, so we set |n:=h|
+and print `\.{...}' followed by
+$$\hbox{|trick_buf[(l+k-h+3)..k-1]|,}$$
+where subscripts of |trick_buf| are circular modulo |error_line|. The
+second line consists of |n|~spaces followed by |trick_buf[k..(k+m-1)]|,
+unless |n+m>error_line|; in the latter case, further cropping is done.
+This is easier to program than to explain.
+
+
+
+@ The following code sets up the print routines so that they will gather
+the desired information.
+
+@c
+void set_trick_count(void)
+{
+ first_count = tally;
+ trick_count = tally + 1 + error_line - half_error_line;
+ if (trick_count < error_line)
+ trick_count = error_line;
+}
+
+#define begin_pseudoprint() do { \
+ l=tally; tally=0; selector=pseudo; \
+ trick_count=1000000; \
+ } while (0)
+
+#define PSEUDO_PRINT_THE_LINE() do { \
+ begin_pseudoprint(); \
+ if (buffer[ilimit]==end_line_char) j=ilimit; \
+ else j=ilimit+1; /* determine the effective end of the line */ \
+ if (j>0) { \
+ for (i=istart;i<=j-1;i++) { \
+ if (i==iloc) set_trick_count(); \
+ print_char(buffer[i]); \
+ } \
+ } \
+ } while (0)
+
+@ @c
+void show_context(void)
+{ /* prints where the scanner is */
+ int old_setting; /* saved |selector| setting */
+ int nn; /* number of contexts shown so far, less one */
+ boolean bottom_line; /* have we reached the final context to be shown? */
+ int i; /* index into |buffer| */
+ int j; /* end of current line in |buffer| */
+ int l; /* length of descriptive information on line 1 */
+ int m; /* context information gathered for line 2 */
+ int n; /* length of line 1 */
+ int p; /* starting or ending place in |trick_buf| */
+ int q; /* temporary index */
+
+ base_ptr = input_ptr;
+ input_stack[base_ptr] = cur_input;
+ /* store current state */
+ nn = -1;
+ bottom_line = false;
+ while (true) {
+ cur_input = input_stack[base_ptr]; /* enter into the context */
+ if (istate != token_list) {
+ if ((iname > 21) || (base_ptr == 0))
+ bottom_line = true;
+ }
+ if ((base_ptr == input_ptr) || bottom_line
+ || (nn < error_context_lines)) {
+ /* Display the current context */
+ if ((base_ptr == input_ptr) || (istate != token_list) ||
+ (token_type != backed_up) || (iloc != null)) {
+ /* we omit backed-up token lists that have already been read */
+ tally = 0; /* get ready to count characters */
+ old_setting = selector;
+ if (current_ocp_lstack > 0) {
+ tprint_nl("OCP stack ");
+ print_scaled(current_ocp_lstack);
+ tprint(" entry ");
+ print_int(current_ocp_no);
+ tprint(":");
+ PSEUDO_PRINT_THE_LINE();
+ } else if (istate != token_list) {
+ /* Print location of current line */
+ /*
+ This routine should be changed, if necessary, to give the best possible
+ indication of where the current line resides in the input file.
+ For example, on some systems it is best to print both a page and line number.
+ */
+ if (iname <= 17) {
+ if (terminal_input) {
+ if (base_ptr == 0)
+ tprint_nl("<*>");
+ else
+ tprint_nl("<insert> ");
+ } else {
+ tprint_nl("<read ");
+ if (iname == 17)
+ print_char('*');
+ else
+ print_int(iname - 1);
+ print_char('>');
+ };
+ } else if (iindex != in_open) { /* input from a pseudo file */
+ tprint_nl("l.");
+ print_int(line_stack[iindex + 1]);
+ } else {
+ tprint_nl("l.");
+ print_int(line);
+ }
+ print_char(' ');
+ PSEUDO_PRINT_THE_LINE();
+ } else {
+ print_token_list_type(token_type);
+
+ begin_pseudoprint();
+ if (token_type < macro)
+ show_token_list(istart, iloc, 100000);
+ else
+ show_token_list(token_link(istart), iloc, 100000); /* avoid reference count */
+ }
+ selector = old_setting; /* stop pseudoprinting */
+ /* Print two lines using the tricky pseudoprinted information */
+ if (trick_count == 1000000)
+ set_trick_count();
+ /* |set_trick_count| must be performed */
+ if (tally < trick_count)
+ m = tally - first_count;
+ else
+ m = trick_count - first_count; /* context on line 2 */
+ if (l + first_count <= half_error_line) {
+ p = 0;
+ n = l + first_count;
+ } else {
+ tprint("...");
+ p = l + first_count - half_error_line + 3;
+ n = half_error_line;
+ }
+ for (q = p; q <= first_count - 1; q++)
+ print_char(trick_buf[(q % error_line)]);
+ print_ln();
+ for (q = 1; q <= n; q++)
+ print_char(' '); /* print |n| spaces to begin line~2 */
+ if (m + n <= error_line)
+ p = first_count + m;
+ else
+ p = first_count + (error_line - n - 3);
+ for (q = first_count; q <= p - 1; q++)
+ print_char(trick_buf[(q % error_line)]);
+ if (m + n > error_line)
+ tprint("...");
+
+ incr(nn);
+ }
+ } else if (nn == error_context_lines) {
+ tprint_nl("...");
+ incr(nn); /* omitted if |error_context_lines<0| */
+ }
+ if (bottom_line)
+ break;
+ decr(base_ptr);
+ }
+ cur_input = input_stack[input_ptr]; /* restore original state */
+}
+
+
+@ The following subroutines change the input status in commonly needed ways.
+
+First comes |push_input|, which stores the current state and creates a
+new level (having, initially, the same properties as the old).
+
+@c
+/* enter a new input level, save the old */
+
+void push_input(void)
+{
+ if (input_ptr > max_in_stack) {
+ max_in_stack = input_ptr;
+ if (input_ptr == stack_size)
+ overflow("input stack size", (unsigned) stack_size);
+ }
+ input_stack[input_ptr] = cur_input; /* stack the record */
+ nofilter = false;
+ incr(input_ptr);
+}
+
+@
+Here is a procedure that starts a new level of token-list input, given
+a token list |p| and its type |t|. If |t=macro|, the calling routine should
+set |name| and |loc|.
+
+@c
+void begin_token_list(halfword p, quarterword t)
+{
+ push_input();
+ istate = token_list;
+ istart = p;
+ token_type = (unsigned char) t;
+ if (t >= macro) { /* the token list starts with a reference count */
+ add_token_ref(p);
+ if (t == macro) {
+ param_start = param_ptr;
+ } else {
+ iloc = token_link(p);
+ if (int_par(tracing_macros_code) > 1) {
+ begin_diagnostic();
+ tprint_nl("");
+ if (t == mark_text)
+ tprint_esc("mark");
+ else if (t == write_text)
+ tprint_esc("write");
+ else
+ print_cmd_chr(assign_toks_cmd,
+ t - output_text + output_routine_loc);
+ tprint("->");
+ token_show(p);
+ end_diagnostic(false);
+ }
+ }
+ } else {
+ iloc = p;
+ }
+}
+
+
+@ When a token list has been fully scanned, the following computations
+should be done as we leave that level of input. The |token_type| tends
+to be equal to either |backed_up| or |inserted| about 2/3 of the time.
+@^inner loop@>
+
+@c
+void end_token_list(void)
+{ /* leave a token-list input level */
+ if (token_type >= backed_up) { /* token list to be deleted */
+ if (token_type <= inserted) {
+ flush_list(istart);
+ } else {
+ delete_token_ref(istart); /* update reference count */
+ if (token_type == macro) { /* parameters must be flushed */
+ while (param_ptr > param_start) {
+ decr(param_ptr);
+ flush_list(param_stack[param_ptr]);
+ }
+ }
+ }
+ } else if (token_type == u_template) {
+ if (align_state > 500000)
+ align_state = 0;
+ else
+ fatal_error("(interwoven alignment preambles are not allowed)");
+ }
+ pop_input();
+ check_interrupt();
+}
+
+
+@ Sometimes \TeX\ has read too far and wants to ``unscan'' what it has
+seen. The |back_input| procedure takes care of this by putting the token
+just scanned back into the input stream, ready to be read again. This
+procedure can be used only if |cur_tok| represents the token to be
+replaced. Some applications of \TeX\ use this procedure a lot,
+so it has been slightly optimized for speed.
+@^inner loop@>
+
+@c
+void back_input(void)
+{ /* undoes one token of input */
+ halfword p; /* a token list of length one */
+ while ((istate == token_list) && (iloc == null)
+ && (token_type != v_template))
+ end_token_list(); /* conserve stack space */
+ p = get_avail();
+ set_token_info(p, cur_tok);
+ if (cur_tok < right_brace_limit) {
+ if (cur_tok < left_brace_limit)
+ decr(align_state);
+ else
+ incr(align_state);
+ }
+ push_input();
+ istate = token_list;
+ istart = p;
+ token_type = backed_up;
+ iloc = p; /* that was |back_list(p)|, without procedure overhead */
+}
+
+@ Insert token |p| into \TeX's input
+@c
+int reinsert_token(boolean a, halfword pp)
+{
+ halfword t;
+ t = cur_tok;
+ cur_tok = pp;
+ if (a) {
+ halfword p;
+ p = get_avail();
+ set_token_info(p, cur_tok);
+ set_token_link(p, iloc);
+ iloc = p;
+ istart = p;
+ if (cur_tok < right_brace_limit) {
+ if (cur_tok < left_brace_limit)
+ decr(align_state);
+ else
+ incr(align_state);
+ }
+ } else {
+ back_input();
+ a = true; /* etex is always on */
+ }
+ cur_tok = t;
+ return a;
+}
+
+
+@ The |begin_file_reading| procedure starts a new level of input for lines
+of characters to be read from a file, or as an insertion from the
+terminal. It does not take care of opening the file, nor does it set |loc|
+or |limit| or |line|.
+@^system dependencies@>
+
+@c
+void begin_file_reading(void)
+{
+ if (in_open == max_in_open)
+ overflow("text input levels", (unsigned) max_in_open);
+ if (first == buf_size)
+ check_buffer_overflow(first);
+ incr(in_open);
+ push_input();
+ iindex = (unsigned char) in_open;
+ source_filename_stack[iindex] = 0;
+ full_source_filename_stack[iindex] = NULL;
+ eof_seen[iindex] = false;
+ grp_stack[iindex] = cur_boundary;
+ if_stack[iindex] = cond_ptr;
+ line_stack[iindex] = line;
+ istart = first;
+ istate = mid_line;
+ iname = 0; /* |terminal_input| is now |true| */
+ line_catcode_table = DEFAULT_CAT_TABLE;
+ line_partial = false;
+ /* Prepare terminal input {\sl Sync\TeX} information */
+ synctex_tag = 0;
+}
+
+
+@ Conversely, the variables must be downdated when such a level of input
+is finished:
+
+@c
+void end_file_reading(void)
+{
+ first = istart;
+ line = line_stack[iindex];
+ if ((iname >= 18) && (iname <= 20))
+ pseudo_close();
+ else if (iname == 21)
+ luacstring_close(iindex);
+ else if (iname > 17)
+ lua_a_close_in(cur_file, 0); /* forget it */
+ pop_input();
+ decr(in_open);
+}
+
+
+@ In order to keep the stack from overflowing during a long sequence of
+inserted `\.{\\show}' commands, the following routine removes completed
+error-inserted lines from memory.
+
+@c
+void clear_for_error_prompt(void)
+{
+ while ((istate != token_list) && terminal_input
+ && (input_ptr > 0) && (iloc > ilimit))
+ end_file_reading();
+ print_ln();
+ clear_terminal();
+}
+
+@ To get \TeX's whole input mechanism going, we perform the following
+ actions.
+
+@c
+void initialize_inputstack(void)
+{
+ input_ptr = 0;
+ max_in_stack = 0;
+ source_filename_stack[0] = 0;
+
+ full_source_filename_stack[0] = NULL;
+ in_open = 0;
+ open_parens = 0;
+ max_buf_stack = 0;
+
+ grp_stack[0] = 0;
+ if_stack[0] = null;
+ param_ptr = 0;
+ max_param_stack = 0;
+ first = buf_size;
+ do {
+ buffer[first] = 0;
+ decr(first);
+ } while (first != 0);
+ scanner_status = normal;
+ warning_index = null;
+ first = 1;
+ istate = new_line;
+ istart = 1;
+ iindex = 0;
+ line = 0;
+ iname = 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 (!init_terminal())
+ exit(EXIT_FAILURE); /* |goto final_end|; */
+ ilimit = last;
+ first = last + 1; /* |init_terminal| has set |loc| and |last| */
+}
+
+
+
+
+@ The global variable |pseudo_files| is used to maintain a stack of
+pseudo files. The |pseudo_lines| field of each pseudo file points to
+a linked list of variable size nodes representing lines not yet
+processed: the |subtype| field contains the size of this node,
+all the following words contain ASCII codes.
+
+@c
+halfword pseudo_files; /* stack of pseudo files */
+
+static halfword string_to_pseudo(str_number str, int nl)
+{
+ halfword i, r, q = null;
+ unsigned l, len;
+ four_quarters w;
+ int sz;
+ halfword h = new_node(pseudo_file_node, 0);
+ unsigned char *s = str_string(str);
+ len = (unsigned) str_length(str);
+ l = 0;
+ while (l < len) {
+ unsigned m = l; /* start of current line */
+ while ((l < len) && (s[l] != nl))
+ l++;
+ sz = (int) (l - m + 7) / 4;
+ if (sz == 1)
+ sz = 2;
+ r = new_node(pseudo_line_node, sz);
+ i = r;
+ while (--sz > 1) {
+ w.b0 = s[m++];
+ w.b1 = s[m++];
+ w.b2 = s[m++];
+ w.b3 = s[m++];
+ varmem[++i].qqqq = w;
+ }
+ w.b0 = (quarterword) (l > m ? s[m++] : ' ');
+ w.b1 = (quarterword) (l > m ? s[m++] : ' ');
+ w.b2 = (quarterword) (l > m ? s[m++] : ' ');
+ w.b3 = (quarterword) (l > m ? s[m] : ' ');
+ varmem[++i].qqqq = w;
+ if (pseudo_lines(h) == null) {
+ pseudo_lines(h) = r;
+ q = r;
+ } else {
+ couple_nodes(q, r);
+ }
+ q = vlink(q);
+ if (s[l] == nl)
+ l++;
+ }
+ return h;
+}
+
+
+@ The |pseudo_start| procedure initiates reading from a pseudo file.
+
+@c
+void pseudo_from_string(void)
+{
+ str_number s; /* string to be converted into a pseudo file */
+ halfword p; /* for list construction */
+ s = make_string();
+ /* Convert string |s| into a new pseudo file */
+ p = string_to_pseudo(s, int_par(new_line_char_code));
+ vlink(p) = pseudo_files;
+ pseudo_files = p;
+ flush_str(s);
+ /* Initiate input from new pseudo file */
+ begin_file_reading(); /* set up |cur_file| and new level of input */
+ line = 0;
+ ilimit = istart;
+ iloc = ilimit + 1; /* force line read */
+ if (int_par(tracing_scan_tokens_code) > 0) {
+ if (term_offset > max_print_line - 3)
+ print_ln();
+ else if ((term_offset > 0) || (file_offset > 0))
+ print_char(' ');
+ iname = 20;
+ tprint("( ");
+ incr(open_parens);
+ update_terminal();
+ } else {
+ iname = 18;
+ }
+ /* Prepare pseudo file {\sl Sync\TeX} information */
+ synctex_tag = 0;
+}
+
+void pseudo_start(void)
+{
+ int old_setting; /* holds |selector| setting */
+ scan_general_text();
+ old_setting = selector;
+ selector = new_string;
+ token_show(temp_token_head);
+ selector = old_setting;
+ flush_list(token_link(temp_token_head));
+ str_room(1);
+ pseudo_from_string();
+}
+
+@ @c
+void lua_string_start(void)
+{
+ begin_file_reading(); /* set up |cur_file| and new level of input */
+ line = 0;
+ ilimit = istart;
+ iloc = ilimit + 1; /* force line read */
+ iname = 21;
+ luacstring_start(iindex);
+}
+
+@ Here we read a line from the current pseudo file into |buffer|.
+
+@c
+boolean pseudo_input(void)
+{ /* inputs the next line or returns |false| */
+ halfword p; /* current line from pseudo file */
+ int sz; /* size of node |p| */
+ four_quarters w; /* four ASCII codes */
+ halfword r; /* loop index */
+ last = first; /* cf.\ Matthew 19\thinspace:\thinspace30 */
+ p = pseudo_lines(pseudo_files);
+ if (p == null) {
+ return false;
+ } else {
+ pseudo_lines(pseudo_files) = vlink(p);
+ sz = subtype(p);
+ if (4 * sz - 3 >= buf_size - last)
+ check_buffer_overflow(last + 4 * sz);
+ last = first;
+ for (r = p + 1; r <= p + sz - 1; r++) {
+ w = varmem[r].qqqq;
+ buffer[last] = (packed_ASCII_code) w.b0;
+ buffer[last + 1] = (packed_ASCII_code) w.b1;
+ buffer[last + 2] = (packed_ASCII_code) w.b2;
+ buffer[last + 3] = (packed_ASCII_code) w.b3;
+ last += 4;
+ }
+ if (last >= max_buf_stack)
+ max_buf_stack = last + 1;
+ while ((last > first) && (buffer[last - 1] == ' '))
+ decr(last);
+ flush_node(p);
+ }
+ return true;
+}
+
+@ When we are done with a pseudo file we `close' it
+
+@c
+void pseudo_close(void)
+{ /* close the top level pseudo file */
+ halfword p;
+ p = vlink(pseudo_files);
+ flush_node(pseudo_files);
+ pseudo_files = p;
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.h b/Build/source/texk/web2c/luatexdir/tex/linebreak.h
new file mode 100644
index 00000000000..791a5f0de7c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.h
@@ -0,0 +1,106 @@
+/* linebreak.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: linebreak.h 3526 2010-03-19 20:56:38Z taco $ */
+
+#ifndef LINEBREAK_H
+# define LINEBREAK_H
+
+# define left_side 0
+# define right_side 1
+
+extern halfword just_box; /* the |hlist_node| for the last line of the new paragraph */
+
+extern void line_break(boolean d, int line_break_context);
+
+# define inf_bad 10000 /* infinitely bad value */
+# define awful_bad 07777777777 /* more than a billion demerits */
+
+extern void initialize_active(void);
+
+extern void ext_do_line_break(int paragraph_dir,
+ int pretolerance,
+ int tracing_paragraphs,
+ int tolerance,
+ scaled emergency_stretch,
+ int looseness,
+ int hyphen_penalty,
+ int ex_hyphen_penalty,
+ int pdf_adjust_spacing,
+ halfword par_shape_ptr,
+ int adj_demerits,
+ int pdf_protrude_chars,
+ int line_penalty,
+ int last_line_fit,
+ int double_hyphen_demerits,
+ int final_hyphen_demerits,
+ int hang_indent,
+ int hsize,
+ int hang_after,
+ halfword left_skip,
+ halfword right_skip,
+ int pdf_each_line_height,
+ int pdf_each_line_depth,
+ int pdf_first_line_height,
+ int pdf_last_line_depth,
+ halfword inter_line_penalties_ptr,
+ int inter_line_penalty,
+ int club_penalty,
+ halfword club_penalties_ptr,
+ halfword widow_penalties_ptr,
+ int widow_penalty,
+ int broken_penalty, halfword final_par_glue,
+ halfword pdf_ignored_dimen);
+
+extern void get_linebreak_info (int *, int *) ;
+extern halfword find_protchar_left(halfword l, boolean d);
+extern halfword find_protchar_right(halfword l, halfword r);
+
+/* skipable nodes at the margins during character protrusion */
+
+#define cp_skipable(a) ((! is_char_node((a))) && \
+ ((type((a)) == ins_node) \
+ || (type((a)) == mark_node) \
+ || (type((a)) == adjust_node) \
+ || (type((a)) == penalty_node) \
+ || ((type((a)) == whatsit_node) && \
+ (subtype((a)) != pdf_refximage_node) && \
+ (subtype((a)) != pdf_refxform_node)) \
+ /* reference to an image or XObject form */ \
+ || ((type((a)) == disc_node) && \
+ (vlink_pre_break(a) == null) && \
+ (vlink_post_break(a) == null) && \
+ (vlink_no_break(a) == null)) \
+ /* an empty |disc_node| */ \
+ || ((type((a)) == math_node) && \
+ (surround((a)) == 0)) \
+ || ((type((a)) == kern_node) && \
+ ((width((a)) == 0) || \
+ (subtype((a)) == normal))) \
+ || ((type((a)) == glue_node) && \
+ (glue_ptr((a)) == zero_glue)) \
+ || ((type((a)) == hlist_node) && \
+ (width((a)) == 0) && \
+ (height((a)) == 0) && \
+ (depth((a)) == 0) && \
+ (list_ptr((a)) == null)) \
+ ))
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.c b/Build/source/texk/web2c/luatexdir/tex/linebreak.w
index 5cd5509389d..7c285f94430 100644
--- a/Build/source/texk/web2c/luatexdir/tex/linebreak.c
+++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.w
@@ -1,37 +1,216 @@
-/* linebreak.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% linebreak.w
+%
+% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "nodes.h"
+@ @c
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: linebreak.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/linebreak.c $";
+ "$Id: linebreak.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/linebreak.w $";
+
+@ We come now to what is probably the most interesting algorithm of \TeX:
+the mechanism for choosing the ``best possible'' breakpoints that yield
+the individual lines of a paragraph. \TeX's line-breaking algorithm takes
+a given horizontal list and converts it to a sequence of boxes that are
+appended to the current vertical list. In the course of doing this, it
+creates a special data structure containing three kinds of records that are
+not used elsewhere in \TeX. Such nodes are created while a paragraph is
+being processed, and they are destroyed afterwards; thus, the other parts
+of \TeX\ do not need to know anything about how line-breaking is done.
+
+The method used here is based on an approach devised by Michael F. Plass and
+@^Plass, Michael Frederick@>
+@^Knuth, Donald Ervin@>
+the author in 1977, subsequently generalized and improved by the same two
+people in 1980. A detailed discussion appears in {\sl SOFTWARE---Practice
+\AM\ Experience \bf11} (1981), 1119--1184, where it is shown that the
+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
+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
+current point.
+
+The |line_break| procedure should be invoked only in horizontal mode; it
+leaves that mode and places its output into the current vlist of the
+enclosing vertical mode (or internal vertical mode).
+There is one explicit parameter: |d| is true for partial paragraphs
+preceding display math mode; in this case the amount of additional
+penalty inserted before the final line is |display_widow_penalty|
+instead of |widow_penalty|.
+
+There are also a number of implicit parameters: The hlist to be broken
+starts at |vlink(head)|, and it is nonempty. The value of |prev_graf| in the
+enclosing semantic level tells where the paragraph should begin in the
+sequence of line numbers, in case hanging indentation or \.{\\parshape}
+are in use; |prev_graf| is zero unless this paragraph is being continued
+after a displayed formula. Other implicit parameters, such as the
+|par_shape_ptr| and various penalties to use for hyphenation, etc., appear
+in |eqtb|.
+
+After |line_break| has acted, it will have updated the current vlist and the
+value of |prev_graf|. Furthermore, the global variable |just_box| will
+point to the final box created by |line_break|, so that the width of this
+line can be ascertained when it is necessary to decide whether to use
+|above_display_skip| or |above_display_short_skip| before a displayed formula.
+
+@c
+halfword just_box; /* the |hlist_node| for the last line of the new paragraph */
+
+
+@ 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 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
+the \.{\\parfillskip} glue to the end of the paragraph, removing a
+space (or other glue node) if it was there, since spaces usually
+precede blank lines and instances of `\.{\$\$}'. The |par_fill_skip|
+is preceded by an infinite penalty, so it will never be considered as
+a potential breakpoint.
+
+That code assumes that a |glue_node| and a |penalty_node| occupy the
+same number of |mem|~words.
+@^data structure assumptions@>
+
+Most other processing is delegated to external functions.
+
+@c
+void line_break(boolean d, int line_break_context)
+{
+ int paragraph_dir = 0; /* main direction of paragraph */
+ halfword final_par_glue;
+ halfword start_of_par;
+ int callback_id;
+ pack_begin_line = cur_list.ml_field; /* this is for over/underfull box messages */
+ vlink(temp_head) = vlink(cur_list.head_field);
+ new_hyphenation(temp_head, cur_list.tail_field);
+ if ((!is_char_node(vlink(cur_list.head_field)))
+ && ((type(vlink(cur_list.head_field)) == whatsit_node)
+ && (subtype(vlink(cur_list.head_field)) == local_par_node)))
+ paragraph_dir = local_par_dir(vlink(cur_list.head_field));
+ else {
+ assert(0); /* |paragraph_dir = 0|; */
+ }
+ cur_list.tail_field = new_ligkern(temp_head, cur_list.tail_field);
+ if (is_char_node(cur_list.tail_field)) {
+ tail_append(new_penalty(inf_penalty));
+ } else if (type(cur_list.tail_field) != glue_node) {
+ tail_append(new_penalty(inf_penalty));
+ } else {
+ type(cur_list.tail_field) = penalty_node;
+ delete_glue_ref(glue_ptr(cur_list.tail_field));
+ if (leader_ptr(cur_list.tail_field) != null)
+ flush_node_list(leader_ptr(cur_list.tail_field));
+ penalty(cur_list.tail_field) = inf_penalty;
+ }
+ final_par_glue = new_param_glue(par_fill_skip_code);
+ couple_nodes(cur_list.tail_field, final_par_glue);
+ cur_list.tail_field = vlink(cur_list.tail_field);
+ lua_node_filter(pre_linebreak_filter_callback,
+ line_break_context, temp_head,
+ addressof(cur_list.tail_field));
+ last_line_fill = cur_list.tail_field;
+ pop_nest();
+ start_of_par = cur_list.tail_field;
+ callback_id = callback_defined(linebreak_filter_callback);
+ if (callback_id > 0) {
+ callback_id =
+ lua_linebreak_callback(d, temp_head,
+ addressof(cur_list.tail_field));
+ if (callback_id > 0) {
+ just_box = cur_list.tail_field;
+ if (just_box != null)
+ while (vlink(just_box) != null)
+ just_box = vlink(just_box);
+ if ((just_box == null) || (type(just_box) != hlist_node)) {
+ 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();
+ }
+ } else {
+ if (int_par(tracing_paragraphs_code) > 0) {
+ begin_diagnostic();
+ tprint_nl
+ ("Lua linebreak_filter failed, reverting to default on line ");
+ print_int(line);
+ end_diagnostic(true);
+ }
+ }
+ }
+ if (callback_id == 0) {
+ ext_do_line_break(paragraph_dir,
+ int_par(pretolerance_code),
+ int_par(tracing_paragraphs_code),
+ int_par(tolerance_code),
+ dimen_par(emergency_stretch_code),
+ int_par(looseness_code),
+ int_par(hyphen_penalty_code),
+ int_par(ex_hyphen_penalty_code),
+ int_par(pdf_adjust_spacing_code),
+ equiv(par_shape_loc),
+ int_par(adj_demerits_code),
+ int_par(pdf_protrude_chars_code),
+ int_par(line_penalty_code),
+ int_par(last_line_fit_code),
+ int_par(double_hyphen_demerits_code),
+ int_par(final_hyphen_demerits_code),
+ dimen_par(hang_indent_code),
+ dimen_par(hsize_code),
+ int_par(hang_after_code),
+ glue_par(left_skip_code),
+ glue_par(right_skip_code),
+ dimen_par(pdf_each_line_height_code),
+ dimen_par(pdf_each_line_depth_code),
+ dimen_par(pdf_first_line_height_code),
+ dimen_par(pdf_last_line_depth_code),
+ equiv(inter_line_penalties_loc),
+ int_par(inter_line_penalty_code),
+ int_par(club_penalty_code),
+ equiv(club_penalties_loc),
+ (d ? equiv(display_widow_penalties_loc) : equiv(widow_penalties_loc)),
+ (d ? int_par(display_widow_penalty_code) : int_par(widow_penalty_code)),
+ int_par(broken_penalty_code),
+ final_par_glue, dimen_par(pdf_ignored_dimen_code));
+ }
+ lua_node_filter(post_linebreak_filter_callback,
+ line_break_context, start_of_par,
+ addressof(cur_list.tail_field));
+ pack_begin_line = 0;
+}
-/* Glue nodes in a horizontal list that is being paragraphed are not supposed to
+
+@ Glue nodes in a horizontal list that is being paragraphed are not supposed to
include ``infinite'' shrinkability; that is why the algorithm maintains
four registers for stretching but only one for shrinking. If the user tries to
introduce infinite shrinkability, the shrinkability will be reset to finite
and an error message will be issued. A boolean variable |no_shrink_error_yet|
prevents this error message from appearing more than once per paragraph.
-*/
+@c
#define check_shrinkage(a) \
if ((shrink_order((a))!=normal)&&(shrink((a))!=0)) \
a=finite_shrink((a))
@@ -59,7 +238,7 @@ static halfword finite_shrink(halfword p)
return q;
}
-/* A pointer variable |cur_p| runs through the given horizontal list as we look
+@ A pointer variable |cur_p| runs through the given horizontal list as we look
for breakpoints. This variable is global, since it is used both by |line_break|
and by its subprocedure |try_break|.
@@ -80,41 +259,11 @@ static halfword finite_shrink(halfword p)
|true|, and an attempt is made to hyphenate as many words as possible.
If that fails too, we add |emergency_stretch| to the background
stretchability and set |final_pass=true|.
-*/
+@c
static boolean second_pass; /* is this our second attempt to break this paragraph? */
static boolean final_pass; /*is this our final attempt to break this paragraph? */
-static integer threshold; /* maximum badness on feasible lines */
-
-/* skipable nodes at the margins during character protrusion */
-
-#define cp_skipable(a) ((! is_char_node((a))) && \
- ((type((a)) == ins_node) \
- || (type((a)) == mark_node) \
- || (type((a)) == adjust_node) \
- || (type((a)) == penalty_node) \
- || ((type((a)) == whatsit_node) && \
- (subtype((a)) != pdf_refximage_node) && \
- (subtype((a)) != pdf_refxform_node)) \
- /* reference to an image or XObject form */ \
- || ((type((a)) == disc_node) && \
- (vlink_pre_break(a) == null) && \
- (vlink_post_break(a) == null) && \
- (vlink_no_break(a) == null)) \
- /* an empty |disc_node| */ \
- || ((type((a)) == math_node) && \
- (surround((a)) == 0)) \
- || ((type((a)) == kern_node) && \
- ((width((a)) == 0) || \
- (subtype((a)) == normal))) \
- || ((type((a)) == glue_node) && \
- (glue_ptr((a)) == zero_glue)) \
- || ((type((a)) == hlist_node) && \
- (width((a)) == 0) && \
- (height((a)) == 0) && \
- (depth((a)) == 0) && \
- (list_ptr((a)) == null)) \
- ))
+static int threshold; /* maximum badness on feasible lines */
/* maximum fill level for |hlist_stack|*/
#define max_hlist_stack 512 /* maybe good if larger than |2 *
@@ -127,70 +276,68 @@ static halfword hlist_stack[max_hlist_stack];
/* fill level for |hlist_stack| */
static short hlist_stack_level = 0;
+@ @c
static void push_node(halfword p)
{
if (hlist_stack_level >= max_hlist_stack)
- pdf_error(maketexstring("push_node"), maketexstring("stack overflow"));
+ pdf_error("push_node", "stack overflow");
hlist_stack[hlist_stack_level++] = p;
}
static halfword pop_node(void)
{
if (hlist_stack_level <= 0) /* would point to some bug */
- pdf_error(maketexstring("pop_node"),
- maketexstring("stack underflow (internal error)"));
+ pdf_error("pop_node", "stack underflow (internal error)");
return hlist_stack[--hlist_stack_level];
}
-#define null_font 0
-
-static integer max_stretch_ratio = 0; /*maximal stretch ratio of expanded fonts */
-static integer max_shrink_ratio = 0; /*maximal shrink ratio of expanded fonts */
-static integer cur_font_step = 0; /*the current step of expanded fonts */
+@ @c
+static int max_stretch_ratio = 0; /*maximal stretch ratio of expanded fonts */
+static int max_shrink_ratio = 0; /*maximal shrink ratio of expanded fonts */
+static int cur_font_step = 0; /*the current step of expanded fonts */
static boolean check_expand_pars(internal_font_number f)
{
internal_font_number k;
- if ((pdf_font_step(f) == 0) || ((pdf_font_stretch(f) == null_font) &&
- (pdf_font_shrink(f) == null_font)))
+ if ((font_step(f) == 0) || ((font_stretch(f) == null_font) &&
+ (font_shrink(f) == null_font)))
return false;
if (cur_font_step < 0)
- cur_font_step = pdf_font_step(f);
- else if (cur_font_step != pdf_font_step(f))
- pdf_error(maketexstring("font expansion"),
- maketexstring
- ("using fonts with different step of expansion in one paragraph is not allowed"));
- k = pdf_font_stretch(f);
+ cur_font_step = font_step(f);
+ else if (cur_font_step != font_step(f))
+ pdf_error("font expansion",
+ "using fonts with different step of expansion in one paragraph is not allowed");
+ k = font_stretch(f);
if (k != null_font) {
if (max_stretch_ratio < 0)
- max_stretch_ratio = pdf_font_expand_ratio(k);
- else if (max_stretch_ratio != pdf_font_expand_ratio(k))
- pdf_error(maketexstring("font expansion"),
- maketexstring
- ("using fonts with different limit of expansion in one paragraph is not allowed"));
+ max_stretch_ratio = font_expand_ratio(k);
+ else if (max_stretch_ratio != font_expand_ratio(k))
+ pdf_error("font expansion",
+ "using fonts with different limit of expansion in one paragraph is not allowed");
}
- k = pdf_font_shrink(f);
+ k = font_shrink(f);
if (k != null_font) {
if (max_shrink_ratio < 0)
- max_shrink_ratio = -pdf_font_expand_ratio(k);
- else if (max_shrink_ratio != -pdf_font_expand_ratio(k))
- pdf_error(maketexstring("font expansion"),
- maketexstring
- ("using fonts with different limit of expansion in one paragraph is not allowed"));
+ max_shrink_ratio = -font_expand_ratio(k);
+ else if (max_shrink_ratio != -font_expand_ratio(k))
+ pdf_error("font expansion",
+ "using fonts with different limit of expansion in one paragraph is not allowed");
}
return true;
}
-/* searches left to right from list head |l|, returns 1st non-skipable item*/
+@ searches left to right from list head |l|, returns 1st non-skipable item
+
+@c
/*public*/ halfword find_protchar_left(halfword l, boolean d)
{
halfword t;
boolean run;
if ((vlink(l) != null) && (type(l) == hlist_node) && (width(l) == 0)
&& (height(l) == 0) && (depth(l) == 0) && (list_ptr(l) == null)) {
- l = vlink(l); /*for paragraph start with \.{\\parindent = 0pt */
+ l = vlink(l); /*for paragraph start with \.{\\parindent} = 0pt */
} else if (d) {
while ((vlink(l) != null) && (!(is_char_node(l) || non_discardable(l)))) {
l = vlink(l); /* std.\ discardables at line break, \TeX book, p 95 */
@@ -207,6 +354,7 @@ static boolean check_expand_pars(internal_font_number f)
while (run && cp_skipable(l)) {
while ((vlink(l) == null) && (hlist_stack_level > 0)) {
l = pop_node(); /* don't visit this node again */
+ run = false;
}
if (vlink(l) != null)
l = vlink(l);
@@ -218,7 +366,9 @@ static boolean check_expand_pars(internal_font_number f)
}
-/* searches right to left from list tail |r| to head |l|, returns 1st non-skipable item */
+@ searches right to left from list tail |r| to head |l|, returns 1st non-skipable item
+
+@c
/*public*/ halfword find_protchar_right(halfword l, halfword r)
{
halfword t;
@@ -246,8 +396,12 @@ static boolean check_expand_pars(internal_font_number f)
l = pop_node();
}
if ((r != l) && (r != null)) {
- assert(vlink(alink(r)) == r);
- r = alink(r);
+ if (alink(r) != null) {
+ assert(vlink(alink(r)) == r);
+ r = alink(r);
+ } else { /* this is the input: \.{\\leavevmode\\penalty-10000\\penalty-10000} (bug \#268) */
+ run = false;
+ }
} else if ((r == l) && (hlist_stack_level == 0))
run = false;
}
@@ -255,10 +409,11 @@ static boolean check_expand_pars(internal_font_number f)
return r;
}
+@ @c
#define left_pw(a) char_pw((a), left_side)
#define right_pw(a) char_pw((a), right_side)
-/* When looking for optimal line breaks, \TeX\ creates a ``break node'' for
+@ When looking for optimal line breaks, \TeX\ creates a ``break node'' for
each break that is {\sl feasible}, in the sense that there is a way to end
a line at the given place without requiring any line to stretch more than
a given tolerance. A break node is characterized by three things: the position
@@ -266,8 +421,8 @@ static boolean check_expand_pars(internal_font_number f)
or |disc_node|); the ordinal number of the line that will follow this
breakpoint; and the fitness classification of the line that has just
ended, i.e., |tight_fit|, |decent_fit|, |loose_fit|, or |very_loose_fit|.
-*/
+@c
typedef enum {
very_loose_fit = 0, /* fitness classification for lines stretching more than
their stretchability */
@@ -279,7 +434,7 @@ typedef enum {
} fitness_value;
-/* The algorithm essentially determines the best possible way to achieve
+@ The algorithm essentially determines the best possible way to achieve
each feasible combination of position, line, and fitness. Thus, it answers
questions like, ``What is the best way to break the opening part of the
paragraph so that the fourth line is a tight line ending at such-and-such
@@ -294,9 +449,8 @@ typedef enum {
for breakpoints near the place in the paragraph that is currently being
examined, so they are recycled within a comparatively short time after
they are created.
-*/
-/* An active node for a given breakpoint contains six fields:
+@ An active node for a given breakpoint contains six fields:
|vlink| points to the next node in the list of active nodes; the
last active node has |vlink=active|.
@@ -320,8 +474,8 @@ The value of |vlink(active)| points to the first active node on a vlinked list
of all currently active nodes. This list is in order by |line_number|,
except that nodes with |line_number>easy_line| may be in any order relative
to each other.
-*/
+@c
void initialize_active(void)
{
type(active) = hyphenated_node;
@@ -329,7 +483,7 @@ void initialize_active(void)
subtype(active) = 0; /* the |subtype| is never examined */
}
-/* The passive node for a given breakpoint contains EIGHT fields:
+@ The passive node for a given breakpoint contains EIGHT fields:
|vlink| points to the passive node created just before this one,
if any, otherwise it is |null|.
@@ -352,13 +506,13 @@ There is a global variable called |passive| that points to the most
recently created passive node. Another global variable, |printed_node|,
is used to help print out the paragraph when detailed information about
the line-breaking computation is being displayed.
-*/
+@c
static halfword passive; /* most recent node on passive list */
static halfword printed_node; /*most recent node that has been printed */
static halfword pass_number; /*the number of passive nodes allocated on this pass */
-/*
+
@ The active list also contains ``delta'' nodes that help the algorithm
compute the badness of individual lines. Such nodes appear only between two
active nodes, and they have |type=delta_node|. If |p| and |r| are active nodes
@@ -376,9 +530,9 @@ difference appears in |mem[q+7].sc|. The |subtype| field of a delta node
is not used.
Actually, we have two more fields that are used by |pdftex|.
-*/
-/* As the algorithm runs, it maintains a set of seven delta-like registers
+
+As the algorithm runs, it maintains a set of seven delta-like registers
for the length of the line following the first active breakpoint to the
current position in the given hlist. When it makes a pass through the
active list, it also maintains a similar set of seven registers for the
@@ -391,15 +545,15 @@ $$\hbox{\ignorespaces|for
k:=1 to 7 do cur_active_width[k]:=cur_active_width[k]+mem[q+k].sc|};$$ and we
want to do this without the overhead of |for| loops. The |do_all_six|
macro makes such six-tuples convenient.
-*/
+@c
static scaled active_width[10] = { 0 }; /*distance from first active node to~|cur_p| */
static scaled background[10] = { 0 }; /*length of an ``empty'' line */
static scaled break_width[10] = { 0 }; /*length being computed after current break */
static boolean auto_breaking; /*make |auto_breaking| accessible out of |line_break| */
-/* Let's state the principles of the delta nodes more precisely and concisely,
+@ Let's state the principles of the delta nodes more precisely and concisely,
so that the following programs will be less obscure. For each legal
breakpoint~|p| in the paragraph, we define two quantities $\alpha(p)$ and
$\beta(p)$ such that the length of material in a line from breakpoint~|p|
@@ -437,9 +591,9 @@ static boolean auto_breaking; /*make |auto_breaking| accessible out of |line_b
$a_3$. The |background| array contains $\gamma$. The |break_width| array
will be used to calculate values of new delta nodes when the active
list is being updated.
-*/
-/* The heart of the line-breaking procedure is `|try_break|', a subroutine
+
+@ The heart of the line-breaking procedure is `|try_break|', a subroutine
that tests if the current breakpoint |cur_p| is feasible, by running
through the active list to see what lines of text can be made from active
nodes to~|cur_p|. If feasible breaks are possible, new break nodes are
@@ -454,22 +608,21 @@ static boolean auto_breaking; /*make |auto_breaking| accessible out of |line_b
depending on whether or not the current break is at a |disc_node|. The
end of a paragraph is also regarded as `|hyphenated_node|'; this case is
distinguishable by the condition |cur_p=null|.
-*/
-
-static integer internal_pen_inter; /* running \.{\\localinterlinepenalty} */
-static integer internal_pen_broken; /* running \.{\\localbrokenpenalty} */
+@c
+static int internal_pen_inter; /* running \.{\\localinterlinepenalty} */
+static int internal_pen_broken; /* running \.{\\localbrokenpenalty} */
static halfword internal_left_box; /* running \.{\\localleftbox} */
-static integer internal_left_box_width; /* running \.{\\localleftbox} width */
+static int internal_left_box_width; /* running \.{\\localleftbox} width */
static halfword init_internal_left_box; /* running \.{\\localleftbox} */
-static integer init_internal_left_box_width; /* running \.{\\localleftbox} width */
+static int init_internal_left_box_width; /* running \.{\\localleftbox} width */
static halfword internal_right_box; /* running \.{\\localrightbox} */
-static integer internal_right_box_width; /* running \.{\\localrightbox} width */
+static int internal_right_box_width; /* running \.{\\localrightbox} width */
static scaled disc_width[10] = { 0 }; /* the length of discretionary material preceding a break */
-/* As we consider various ways to end a line at |cur_p|, in a given line number
+@ As we consider various ways to end a line at |cur_p|, in a given line number
class, we keep track of the best total demerits known, in an array with
one entry for each of the fitness classifications. For example,
|minimal_demerits[tight_fit]| contains the fewest total demerits of feasible
@@ -480,19 +633,18 @@ static scaled disc_width[10] = { 0 }; /* the length of discretionary material
sequence is known, the |minimal_demerits| entries will be equal to
|awful_bad|, which is $2^{30}-1$. Another variable, |minimum_demerits|,
keeps track of the smallest value in the |minimal_demerits| array.
-*/
-
-static integer minimal_demerits[4]; /* best total demerits known for current
- line class and position, given the fitness */
-static integer minimum_demerits; /* best total demerits known for current line class
- and position */
+@c
+static int minimal_demerits[4]; /* best total demerits known for current
+ line class and position, given the fitness */
+static int minimum_demerits; /* best total demerits known for current line class
+ and position */
static halfword best_place[4]; /* how to achieve |minimal_demerits| */
static halfword best_pl_line[4]; /*corresponding line number */
-/*
- The length of lines depends on whether the user has specified
+
+@ The length of lines depends on whether the user has specified
\.{\\parshape} or \.{\\hangindent}. If |par_shape_ptr| is not null, it
points to a $(2n+1)$-word record in |mem|, where the |vinfo| in the first
word contains the value of |n|, and the other $2n$ words contain the left
@@ -507,8 +659,8 @@ $|hsize|-\vert|hang_indent|\vert$. The normal setting is
|par_shape_ptr=null|, |hang_after=1|, and |hang_indent=0|.
Note that if |hang_indent=0|, the value of |hang_after| is irrelevant.
@^length of lines@> @^hanging indentation@>
-*/
+@c
static halfword easy_line; /*line numbers |>easy_line| are equivalent in break nodes */
static halfword last_special_line; /*line numbers |>last_special_line| all have the same width */
static scaled first_width; /*the width of all lines |<=last_special_line|, if
@@ -518,23 +670,23 @@ static scaled first_indent; /*left margin to go with |first_width| */
static scaled second_indent; /*left margin to go with |second_width| */
static halfword best_bet; /*use this passive node and its predecessors */
-static integer fewest_demerits; /*the demerits associated with |best_bet| */
+static int fewest_demerits; /*the demerits associated with |best_bet| */
static halfword best_line; /*line number following the last line of the new paragraph */
-static integer actual_looseness; /*the difference between |line_number(best_bet)|
- and the optimum |best_line| */
-static integer line_diff; /*the difference between the current line number and
+static int actual_looseness; /*the difference between |line_number(best_bet)|
+ and the optimum |best_line| */
+static int line_diff; /*the difference between the current line number and
the optimum |best_line| */
-/* \TeX\ makes use of the fact that |hlist_node|, |vlist_node|,
+@ \TeX\ makes use of the fact that |hlist_node|, |vlist_node|,
|rule_node|, |ins_node|, |mark_node|, |adjust_node|,
|disc_node|, |whatsit_node|, and |math_node| are at the low end of the
type codes, by permitting a break at glue in a list if and only if the
|type| of the previous node is less than |math_node|. Furthermore, a
node is discarded after a break if its type is |math_node| or~more.
-*/
+@c
#define do_all_six(a) a(1);a(2);a(3);a(4);a(5);a(6);a(7)
#define do_seven_eight(a) if (pdf_adjust_spacing > 1) { a(8);a(9); }
#define do_all_eight(a) do_all_six(a); do_seven_eight(a)
@@ -545,7 +697,7 @@ static integer line_diff; /*the difference between the current line number
#define kern_break() { \
if ((!is_char_node(vlink(cur_p))) && auto_breaking) \
if (type(vlink(cur_p))==glue_node) \
- ext_try_break(0,unhyphenated_node, pdf_adjust_spacing, \
+ ext_try_break(0,unhyphenated_node, line_break_dir, pdf_adjust_spacing, \
par_shape_ptr, adj_demerits, \
tracing_paragraphs, pdf_protrude_chars, \
line_penalty, last_line_fit, \
@@ -570,18 +722,11 @@ static integer line_diff; /*the difference between the current line number
} \
}
-#define inf_bad 10000 /* infinitely bad value */
-
static boolean do_last_line_fit; /* special algorithm for last line of paragraph? */
static scaled fill_width[4]; /* infinite stretch components of |par_fill_skip| */
static scaled best_pl_short[4]; /* |shortfall| corresponding to |minimal_demerits| */
static scaled best_pl_glue[4]; /*corresponding glue stretch or shrink */
-#define awful_bad 07777777777 /* more than a billion demerits */
-
-#define before 0 /* |subtype| for math node that introduces a formula */
-#define after 1 /* |subtype| for math node that winds up a formula */
-
#define reset_disc_width(a) disc_width[(a)] = 0
#define add_disc_width_to_break_width(a) break_width[(a)] += disc_width[(a)]
@@ -598,24 +743,20 @@ static scaled best_pl_glue[4]; /*corresponding glue stretch or shrink */
#define sub_kern_stretch(a,b) a -= kern_stretch((b))
-/* This function is used to add the width of a list of nodes
- * (from a discretionary) to one of the width arrays.
- */
+@ This function is used to add the width of a list of nodes
+(from a discretionary) to one of the width arrays.
+
-/* Replacement texts and discretionary texts are supposed to contain
- * only character nodes, kern nodes, and box or rule nodes.
- */
+Replacement texts and discretionary texts are supposed to contain
+only character nodes, kern nodes, and box or rule nodes.
-static void add_to_widths(halfword s, integer line_break_dir,
- integer pdf_adjust_spacing, scaled * widths)
+@c
+static void add_to_widths(halfword s, int line_break_dir,
+ int pdf_adjust_spacing, scaled * widths)
{
while (s != null) {
if (is_char_node(s)) {
- if (is_rotated(line_break_dir)) {
- widths[1] += glyph_height(s) + glyph_depth(s);
- } else {
- widths[1] += glyph_width(s);
- }
+ widths[1] += pack_width(line_break_dir, dir_TRT, s, true);
if ((pdf_adjust_spacing > 1) && check_expand_pars(font(s))) {
set_prev_char_p(s);
add_char_stretch(widths[8], s);
@@ -625,11 +766,7 @@ static void add_to_widths(halfword s, integer line_break_dir,
switch (type(s)) {
case hlist_node:
case vlist_node:
- if (!(dir_orthogonal(dir_primary[box_dir(s)],
- dir_primary[line_break_dir])))
- widths[1] += width(s);
- else
- widths[1] += (depth(s) + height(s));
+ widths[1] += pack_width(line_break_dir, box_dir(s), s, false);
break;
case kern_node:
if ((pdf_adjust_spacing > 1) && (subtype(s) == normal)) {
@@ -643,30 +780,26 @@ static void add_to_widths(halfword s, integer line_break_dir,
case disc_node: /* TH temp */
break;
default:
- tconfusion("add_disc_widths");
+ confusion("add_disc_widths");
}
}
s = vlink(s);
}
}
-/* This function is used to substract the width of a list of nodes
- * (from a discretionary) from one of the width arrays.
- * It is used only once, but deserves it own function because of orthogonality
- * with the |add_to_widths| function.
- */
+@ This function is used to substract the width of a list of nodes
+(from a discretionary) from one of the width arrays.
+It is used only once, but deserves it own function because of orthogonality
+with the |add_to_widths| function.
-static void sub_from_widths(halfword s, integer line_break_dir,
- integer pdf_adjust_spacing, scaled * widths)
+@c
+static void sub_from_widths(halfword s, int line_break_dir,
+ int pdf_adjust_spacing, scaled * widths)
{
while (s != null) {
- /* @<Subtract the width of node |s| from |break_width|@>; */
+ /* Subtract the width of node |s| from |break_width|; */
if (is_char_node(s)) {
- if (is_rotated(line_break_dir)) {
- widths[1] -= (glyph_height(s) + glyph_depth(s));
- } else {
- widths[1] -= glyph_width(s);
- }
+ widths[1] -= pack_width(line_break_dir, dir_TRT, s, true);
if ((pdf_adjust_spacing > 1) && check_expand_pars(font(s))) {
set_prev_char_p(s);
sub_char_stretch(widths[8], s);
@@ -676,11 +809,7 @@ static void sub_from_widths(halfword s, integer line_break_dir,
switch (type(s)) {
case hlist_node:
case vlist_node:
- if (!(dir_orthogonal(dir_primary[box_dir(s)],
- dir_primary[line_break_dir])))
- widths[1] -= width(s);
- else
- widths[1] -= (depth(s) + height(s));
+ widths[1] -= pack_width(line_break_dir, box_dir(s), s, false);
break;
case kern_node:
if ((pdf_adjust_spacing > 1) && (subtype(s) == normal)) {
@@ -694,7 +823,7 @@ static void sub_from_widths(halfword s, integer line_break_dir,
case disc_node: /* TH temp */
break;
default:
- tconfusion("sub_disc_widths");
+ confusion("sub_disc_widths");
break;
}
}
@@ -703,7 +832,7 @@ static void sub_from_widths(halfword s, integer line_break_dir,
}
-/* When we insert a new active node for a break at |cur_p|, suppose this
+@ When we insert a new active node for a break at |cur_p|, suppose this
new node is to be placed just before active node |a|; then we essentially
want to insert `$\delta\,|cur_p|\,\delta^\prime$' before |a|, where
$\delta=\alpha(a)-\alpha(|cur_p|)$ and $\delta^\prime=\alpha(|cur_p|)-\alpha(a)$
@@ -721,24 +850,18 @@ static void sub_from_widths(halfword s, integer line_break_dir,
nodes, subtracting their widths as well.
Kern nodes do not disappear at a line break unless they are |explicit|.
-*/
-
-/* assigned-to globals:
- break_width[]
-*/
-/* used globals:
- disc_width[]
- line_break_dir
-*/
+
+@c
static void
-compute_break_width(int break_type, int pdf_adjust_spacing, halfword p
+compute_break_width(int break_type, int line_break_dir, int pdf_adjust_spacing,
+ halfword p
/*, halfword s */ )
{
halfword s; /* glue and other 'whitespace' to be skipped after a break
- * used if unhyphenated, or post_break==empty */
+ * used if unhyphenated, or |post_break==empty| */
s = p;
if (break_type > unhyphenated_node && p != null) {
- /*@<Compute the discretionary |break_width| values@>; */
+ /*Compute the discretionary |break_width| values; */
/* When |p| is a discretionary break, the length of a line
``from |p| to |p|'' has to be defined properly so
that the other calculations work out. Suppose that the
@@ -761,8 +884,8 @@ compute_break_width(int break_type, int pdf_adjust_spacing, halfword p
will put it into the global variable |disc_width| before
calling |try_break|.
*/
- /* In case of nested discretionaries, we always follow the no_break
- path, as we are talking about the breaking on _this_ position.
+ /* In case of nested discretionaries, we always follow the no-break
+ path, as we are talking about the breaking on {\it this} position.
*/
sub_from_widths(vlink_no_break(p), line_break_dir, pdf_adjust_spacing,
@@ -771,7 +894,7 @@ compute_break_width(int break_type, int pdf_adjust_spacing, halfword p
break_width);
do_one_seven_eight(add_disc_width_to_break_width);
if (vlink_post_break(p) == null) {
- s = vlink(p); /* no post_break: 'skip' any 'whitespace' following */
+ s = vlink(p); /* no |post_break|: 'skip' any 'whitespace' following */
} else {
s = null;
}
@@ -781,7 +904,7 @@ compute_break_width(int break_type, int pdf_adjust_spacing, halfword p
while (s != null) {
switch (type(s)) {
case glue_node:
- /*@<Subtract glue from |break_width|@>; */
+ /*Subtract glue from |break_width|; */
{
halfword v = glue_ptr(s);
break_width[1] -= width(v);
@@ -807,13 +930,13 @@ compute_break_width(int break_type, int pdf_adjust_spacing, halfword p
}
}
-
+@ @c
static void
print_break_node(halfword q, fitness_value fit_class,
quarterword break_type, halfword cur_p)
{
- /* @<Print a symbolic description of the new break node@> */
- tprint_nl("@@");
+ /* Print a symbolic description of the new break node */
+ tprint_nl("@@@@");
print_int(serial(passive));
tprint(": line ");
print_int(line_number(q) - 1);
@@ -824,7 +947,7 @@ print_break_node(halfword q, fitness_value fit_class,
tprint(" t=");
print_int(total_demerits(q));
if (do_last_line_fit) {
- /*@<Print additional data in the new active node@>; */
+ /*Print additional data in the new active node; */
tprint(" s=");
print_scaled(active_short(q));
if (cur_p == null)
@@ -840,15 +963,15 @@ print_break_node(halfword q, fitness_value fit_class,
print_int(serial(prev_break(passive)));
}
-
+@ @c
static void
-print_feasible_break(halfword cur_p, pointer r, halfword b, integer pi,
- integer d, boolean artificial_demerits)
+print_feasible_break(halfword cur_p, pointer r, halfword b, int pi,
+ int d, boolean artificial_demerits)
{
- /* @<Print a symbolic description of this feasible break@>; */
+ /* Print a symbolic description of this feasible break; */
if (printed_node != cur_p) {
- /* @<Print the list between |printed_node| and |cur_p|, then
- set |printed_node:=cur_p|@>; */
+ /* Print the list between |printed_node| and |cur_p|, then
+ set |printed_node:=cur_p|; */
tprint_nl("");
if (cur_p == null) {
short_display(vlink(printed_node));
@@ -861,7 +984,7 @@ print_feasible_break(halfword cur_p, pointer r, halfword b, integer pi,
}
printed_node = cur_p;
}
- tprint_nl("@");
+ tprint_nl("@@");
if (cur_p == null) {
tprint_esc("par");
} else if (type(cur_p) != glue_node) {
@@ -893,6 +1016,7 @@ print_feasible_break(halfword cur_p, pointer r, halfword b, integer pi,
print_int(d);
}
+@ @c
#define add_disc_width_to_active_width(a) active_width[a] += disc_width[a]
#define update_width(a) cur_active_width[a] += varmem[(r+(a))].cint
@@ -918,10 +1042,6 @@ print_feasible_break(halfword cur_p, pointer r, halfword b, integer pi,
#define total_font_stretch cur_active_width[8]
#define total_font_shrink cur_active_width[9]
-#define left_side 0
-#define right_side 1
-
-
#define cal_margin_kern_var(a) { \
character(cp) = character((a)); \
font(cp) = font((a)); \
@@ -935,8 +1055,9 @@ print_feasible_break(halfword cur_p, pointer r, halfword b, integer pi,
}
static void
-ext_try_break(integer pi,
+ext_try_break(int pi,
quarterword break_type,
+ int line_break_dir,
int pdf_adjust_spacing,
int par_shape_ptr,
int adj_demerits,
@@ -947,7 +1068,7 @@ ext_try_break(integer pi,
int double_hyphen_demerits,
int final_hyphen_demerits, halfword first_p, halfword cur_p)
{
- /* CONTINUE,DEACTIVATE,FOUND,NOT_FOUND; */
+ /* labels: |CONTINUE,DEACTIVATE,FOUND,NOT_FOUND|; */
pointer r; /* runs through the active list */
scaled margin_kern_stretch;
scaled margin_kern_shrink;
@@ -962,7 +1083,7 @@ ext_try_break(integer pi,
scaled line_width; /*the current line will be justified to this width */
fitness_value fit_class; /*possible fitness class of test line */
halfword b; /*badness of test line */
- integer d; /*demerits of test line */
+ int d; /*demerits of test line */
boolean artificial_demerits; /*has |d| been forced to zero? */
scaled shortfall; /*used in badness calculations */
@@ -972,7 +1093,7 @@ ext_try_break(integer pi,
line_width = 0;
g = 0;
prev_prev_r = null;
- /*@<Make sure that |pi| is in the proper range@>; */
+ /*Make sure that |pi| is in the proper range; */
if (pi >= inf_penalty) {
return; /* this breakpoint is inhibited by infinite penalty */
} else if (pi <= -inf_penalty) {
@@ -986,8 +1107,8 @@ ext_try_break(integer pi,
while (1) {
r = vlink(prev_r);
- /* @<If node |r| is of type |delta_node|, update |cur_active_width|,
- set |prev_r| and |prev_prev_r|, then |goto continue|@>; */
+ /* If node |r| is of type |delta_node|, update |cur_active_width|,
+ set |prev_r| and |prev_prev_r|, then |goto continue|; */
/* The following code uses the fact that |type(active)<>delta_node| */
if (type(r) == delta_node) {
do_all_eight(update_width); /* IMPLICIT ,r */
@@ -995,9 +1116,9 @@ ext_try_break(integer pi,
prev_r = r;
continue;
}
- /* @<If a line number class has ended, create new active nodes for
+ /* If a line number class has ended, create new active nodes for
the best feasible breaks in that class; then |return|
- if |r=active|, otherwise compute the new |line_width|@>; */
+ if |r=active|, otherwise compute the new |line_width|; */
/* The first part of the following code is part of \TeX's inner loop, so
we don't want to waste any time. The current active node, namely node |r|,
contains the line number that will be considered next. At the end of the
@@ -1008,7 +1129,7 @@ ext_try_break(integer pi,
if (l > old_l) { /* now we are no longer in the inner loop */
if ((minimum_demerits < awful_bad)
&& ((old_l != easy_line) || (r == active))) {
- /*@<Create new active nodes for the best feasible breaks just found@> */
+ /*Create new active nodes for the best feasible breaks just found */
/* It is not necessary to create new active nodes having |minimal_demerits|
greater than
|minimum_demerits+abs(adj_demerits)|, since such active nodes will never
@@ -1018,12 +1139,13 @@ ext_try_break(integer pi,
if (no_break_yet) {
no_break_yet = false;
do_all_eight(set_break_width_to_background);
- compute_break_width(break_type, pdf_adjust_spacing, cur_p);
+ compute_break_width(break_type, line_break_dir,
+ pdf_adjust_spacing, cur_p);
}
- /* @<Insert a delta node to prepare for breaks at |cur_p|@>; */
+ /* Insert a delta node to prepare for breaks at |cur_p|; */
/* We use the fact that |type(active)<>delta_node|. */
if (type(prev_r) == delta_node) { /* modify an existing delta node */
- do_all_eight(convert_to_break_width); /* IMPLICIT prev_r */
+ do_all_eight(convert_to_break_width); /* IMPLICIT |prev_r| */
} else if (prev_r == active) { /* no delta node needed at the beginning */
do_all_eight(store_break_width);
} else {
@@ -1042,8 +1164,8 @@ ext_try_break(integer pi,
for (fit_class = very_loose_fit; fit_class <= tight_fit;
fit_class++) {
if (minimal_demerits[fit_class] <= minimum_demerits) {
- /* @<Insert a new active node from |best_place[fit_class]|
- to |cur_p|@>; */
+ /* Insert a new active node from |best_place[fit_class]|
+ to |cur_p|; */
/* When we create an active node, we also create the corresponding
passive node.
*/
@@ -1077,7 +1199,7 @@ ext_try_break(integer pi,
line_number(q) = best_pl_line[fit_class] + 1;
total_demerits(q) = minimal_demerits[fit_class];
if (do_last_line_fit) {
- /*@<Store \(a)additional data in the new active node@> */
+ /*Store additional data in the new active node */
/* Here we save these data in the active node
representing a potential line break. */
active_short(q) = best_pl_short[fit_class];
@@ -1092,7 +1214,7 @@ ext_try_break(integer pi,
minimal_demerits[fit_class] = awful_bad;
}
minimum_demerits = awful_bad;
- /* @<Insert a delta node to prepare for the next active node@>; */
+ /* Insert a delta node to prepare for the next active node; */
/* When the following code is performed, we will have just inserted at
least one active node before |r|, so |type(prev_r)<>delta_node|.
*/
@@ -1107,7 +1229,7 @@ ext_try_break(integer pi,
}
if (r == active)
return;
- /*@<Compute the new line width@>; */
+ /*Compute the new line width; */
/* When we come to the following code, we have just encountered
the first active node~|r| whose |line_number| field contains
|l|. Thus we want to compute the length of the $l\mskip1mu$th
@@ -1131,12 +1253,12 @@ ext_try_break(integer pi,
}
/* /If a line number class has ended, create new active nodes for
the best feasible breaks in that class; then |return|
- if |r=active|, otherwise compute the new |line_width|@>; */
+ if |r=active|, otherwise compute the new |line_width|; */
- /* @<Consider the demerits for a line from |r| to |cur_p|;
+ /* Consider the demerits for a line from |r| to |cur_p|;
deactivate node |r| if it should no longer be active;
then |goto continue| if a line from |r| to |cur_p| is infeasible,
- otherwise record a new feasible break@>; */
+ otherwise record a new feasible break; */
artificial_demerits = false;
shortfall = line_width - cur_active_width[1];
if (break_node(r) == null)
@@ -1149,17 +1271,18 @@ ext_try_break(integer pi,
l = (break_node(r) == null) ? first_p : cur_break(break_node(r));
if (cur_p == null) {
o = null;
- } else { /* TODO if (is_character_node(alink(cur_p))) */
+ } else { /* TODO |if (is_character_node(alink(cur_p)))| */
o = alink(cur_p);
assert(vlink(o) == cur_p);
}
/* MAGIC: the disc could be a SELECT subtype, to we might need
- * to get the last character as 'pre_break' from either the
- * pre_break list (if the previous INIT disc was taken), or the
- * no_break (sic) list (if the previous INIT disc was not taken)
- * BUT:
- * the last characters (hyphenation character) if these two list
- * should always be the same anyway, so we just look at pre_break.
+ to get the last character as |pre_break| from either the
+ |pre_break| list (if the previous INIT disc was taken), or the
+ |no_break| (sic) list (if the previous INIT disc was not taken)
+
+ BUT:
+ the last characters (hyphenation character) if these two list
+ should always be the same anyway, so we just look at |pre_break|.
*/
/* let's look at the right margin first */
if ((cur_p != null) && (type(cur_p) == disc_node)
@@ -1183,7 +1306,7 @@ ext_try_break(integer pi,
margin_kern_stretch = 0;
margin_kern_shrink = 0;
if (pdf_protrude_chars > 1) {
- /* @<Calculate variations of marginal kerns@>; */
+ /* Calculate variations of marginal kerns; */
lp = last_leftmost_char;
rp = last_rightmost_char;
cp = raw_glyph_node();
@@ -1212,8 +1335,8 @@ ext_try_break(integer pi,
}
}
if (shortfall > 0) {
- /* @<Set the value of |b| to the badness for stretching the line,
- and compute the corresponding |fit_class|@> */
+ /* Set the value of |b| to the badness for stretching the line,
+ and compute the corresponding |fit_class| */
/* When a line must stretch, the available stretchability can be
found in the subarray |cur_active_width[2..6]|, in units of
@@ -1223,13 +1346,13 @@ ext_try_break(integer pi,
most often performed when the badness is infinite; therefore
it is worth while to make a quick test for large width excess
and small stretchability, before calling the |badness|
- subroutine. @^inner loop@> */
+ subroutine. */
if ((cur_active_width[3] != 0) || (cur_active_width[4] != 0) ||
(cur_active_width[5] != 0) || (cur_active_width[6] != 0)) {
if (do_last_line_fit) {
if (cur_p == null) { /* the last line of a paragraph */
- /* @<Perform computations for last line and |goto found|@>; */
+ /* Perform computations for last line and |goto found|; */
/* Here we compute the adjustment |g| and badness |b| for
a line from |r| to the end of the paragraph. When any
@@ -1268,9 +1391,9 @@ ext_try_break(integer pi,
g = -max_dimen;
}
if (g > 0) {
- /*@<Set the value of |b| to the badness of the last line
+ /*Set the value of |b| to the badness of the last line
for stretching, compute the corresponding |fit_class,
- and |goto found||@> */
+ and |goto found|| */
/* These badness computations are rather similar to
those of the standard algorithm, with the adjustment
amount |g| replacing the |shortfall|. */
@@ -1293,9 +1416,9 @@ ext_try_break(integer pi,
}
goto FOUND;
} else if (g < 0) {
- /*@<Set the value of |b| to the badness of the last line
+ /*Set the value of |b| to the badness of the last line
for shrinking, compute the corresponding |fit_class,
- and |goto found||@>; */
+ and |goto found||; */
if (-g > cur_active_width[7])
g = -cur_active_width[7];
b = badness(-g, cur_active_width[7]);
@@ -1328,7 +1451,7 @@ ext_try_break(integer pi,
}
} else {
/* Set the value of |b| to the badness for shrinking the line,
- and compute the corresponding |fit_class|@>; */
+ and compute the corresponding |fit_class|; */
/* Shrinkability is never infinite in a paragraph; we can shrink
the line from |r| to |cur_p| by at most
|cur_active_width[7]|. */
@@ -1342,7 +1465,7 @@ ext_try_break(integer pi,
fit_class = decent_fit;
}
if (do_last_line_fit) {
- /* @<Adjust \(t)the additional data for last line@>; */
+ /* Adjust the additional data for last line; */
if (cur_p == null)
shortfall = 0;
if (shortfall > 0) {
@@ -1355,8 +1478,8 @@ ext_try_break(integer pi,
}
FOUND:
if ((b > inf_bad) || (pi == eject_penalty)) {
- /* @<Prepare to deactivate node~|r|, and |goto deactivate| unless
- there is a reason to consider lines of text from |r| to |cur_p|@> */
+ /* Prepare to deactivate node~|r|, and |goto deactivate| unless
+ there is a reason to consider lines of text from |r| to |cur_p| */
/* During the final pass, we dare not lose all active nodes, lest we lose
touch with the line breaks already found. The code shown here makes
sure that such a catastrophe does not happen, by permitting overfull
@@ -1364,7 +1487,6 @@ ext_try_break(integer pi,
several subtle bugs before the correct program logic was finally
discovered; readers who seek to ``improve'' \TeX\ should therefore
think thrice before daring to make any changes here.
- @^overfull boxes@>
*/
if (final_pass && (minimum_demerits == awful_bad) &&
(vlink(r) == active) && (prev_r == active)) {
@@ -1379,7 +1501,7 @@ ext_try_break(integer pi,
continue;
node_r_stays_active = true;
}
- /* @<Record a new feasible break@>; */
+ /* Record a new feasible break; */
/* When we get to this part of the code, the line from |r| to |cur_p| is
feasible, its badness is~|b|, and its fitness classification is
|fit_class|. We don't want to make an active node for this break yet,
@@ -1391,7 +1513,7 @@ ext_try_break(integer pi,
if (artificial_demerits) {
d = 0;
} else {
- /* @<Compute the demerits, |d|, from |r| to |cur_p|@>; */
+ /* Compute the demerits, |d|, from |r| to |cur_p|; */
d = line_penalty + b;
if (abs(d) >= 10000)
d = 100000000;
@@ -1422,7 +1544,7 @@ ext_try_break(integer pi,
best_place[fit_class] = break_node(r);
best_pl_line[fit_class] = l;
if (do_last_line_fit) {
- /* Store \(a)additional data for this feasible break@>; */
+ /* Store additional data for this feasible break; */
/* For each feasible break we record the shortfall and glue stretch or
shrink (or adjustment). */
best_pl_short[fit_class] = shortfall;
@@ -1435,7 +1557,7 @@ ext_try_break(integer pi,
if (node_r_stays_active)
continue; /*|prev_r| has been set to |r| */
DEACTIVATE:
- /* @<Deactivate node |r|@>; */
+ /* Deactivate node |r|; */
/* When an active node disappears, we must delete an adjacent delta node if
the active node was at the beginning or the end of the active list, or
if it was surrounded by delta nodes. We also must preserve the property
@@ -1445,8 +1567,8 @@ ext_try_break(integer pi,
vlink(prev_r) = vlink(r);
flush_node(r);
if (prev_r == active) {
- /*@<Update the active widths, since the first active node has been
- deleted@> */
+ /*Update the active widths, since the first active node has been
+ deleted */
/* The following code uses the fact that |type(active)<>delta_node|.
If the active list has just become empty, we do not need to update the
|active_width| array, since it will be initialized when an active
@@ -1462,13 +1584,13 @@ ext_try_break(integer pi,
} else if (type(prev_r) == delta_node) {
r = vlink(prev_r);
if (r == active) {
- do_all_eight(downdate_width); /* IMPLICIT prev_r */
+ do_all_eight(downdate_width); /* IMPLICIT |prev_r| */
vlink(prev_prev_r) = active;
flush_node(prev_r);
prev_r = prev_prev_r;
} else if (type(r) == delta_node) {
do_all_eight(update_width); /* IMPLICIT ,r */
- do_all_eight(combine_two_deltas); /* IMPLICIT r prev_r */
+ do_all_eight(combine_two_deltas); /* IMPLICIT r |prev_r| */
vlink(prev_r) = vlink(r);
flush_node(r);
}
@@ -1476,8 +1598,9 @@ ext_try_break(integer pi,
}
}
+@ @c
void
-ext_do_line_break(boolean d,
+ext_do_line_break(int paragraph_dir,
int pretolerance,
int tracing_paragraphs,
int tolerance,
@@ -1506,15 +1629,14 @@ ext_do_line_break(boolean d,
int inter_line_penalty,
int club_penalty,
halfword club_penalties_ptr,
- halfword display_widow_penalties_ptr,
halfword widow_penalties_ptr,
- int display_widow_penalty,
int widow_penalty,
int broken_penalty,
halfword final_par_glue, halfword pdf_ignored_dimen)
{
/* DONE,DONE1,DONE2,DONE3,DONE4,DONE5,CONTINUE; */
halfword cur_p, q, r, s; /* miscellaneous nodes of temporary interest */
+ int line_break_dir = paragraph_dir;
/* Get ready to start ... */
minimum_demerits = awful_bad;
@@ -1522,7 +1644,7 @@ ext_do_line_break(boolean d,
minimal_demerits[decent_fit] = awful_bad;
minimal_demerits[loose_fit] = awful_bad;
minimal_demerits[very_loose_fit] = awful_bad;
-
+
/* We compute the values of |easy_line| and the other local variables relating
to line length when the |line_break| procedure is initializing itself. */
if (par_shape_ptr == null) {
@@ -1531,7 +1653,7 @@ ext_do_line_break(boolean d,
second_width = hsize;
second_indent = 0;
} else {
- /* @<Set line length parameters in preparation for hanging indentation@> */
+ /* Set line length parameters in preparation for hanging indentation */
/* We compute the values of |easy_line| and the other local variables relating
to line length when the |line_break| procedure is initializing itself. */
last_special_line = abs(hang_after);
@@ -1587,7 +1709,7 @@ ext_do_line_break(boolean d,
cur_font_step = -1;
set_prev_char_p(null);
}
- /* @<Check for special treatment of last line of paragraph@>; */
+ /* Check for special treatment of last line of paragraph; */
/* The new algorithm for the last line requires that the stretchability
|par_fill_skip| is infinite and the stretchability of |left_skip| plus
|right_skip| is finite.
@@ -1607,19 +1729,21 @@ ext_do_line_break(boolean d,
}
}
}
- /* @<DIR: Initialize |dir_ptr| for |line_break|@> */
+ /* DIR: Initialize |dir_ptr| for |line_break| */
if (dir_ptr != null) {
flush_node_list(dir_ptr);
dir_ptr = null;
}
- /*push_dir(paragraph_dir); *//* TODO what was the point of this? */
+#if 0
+ push_dir(paragraph_dir); /* TODO what was the point of this? */
+#endif
- /* @<Find optimal breakpoints@>; */
+ /* Find optimal breakpoints; */
threshold = pretolerance;
if (threshold >= 0) {
if (tracing_paragraphs > 0) {
begin_diagnostic();
- tprint_nl("@firstpass");
+ tprint_nl("@@firstpass");
}
second_pass = false;
final_pass = false;
@@ -1682,18 +1806,17 @@ ext_do_line_break(boolean d,
/* to access the first node of paragraph as the first active node
has |break_node=null| */
while ((cur_p != null) && (vlink(active) != active)) {
- /* |try_break| if |cur_p| is a legal breakpoint; on the 2nd pass, also look at disc_nodes. */
+ /* |try_break| if |cur_p| is a legal breakpoint; on the 2nd pass, also look at |disc_node|s. */
while (is_char_node(cur_p)) {
- /* Advance \(c)|cur_p| to the node following the present string of characters ; */
+ /* Advance |cur_p| to the node following the present string of characters ; */
/* The code that passes over the characters of words in a paragraph is part of
\TeX's inner loop, so it has been streamlined for speed. We use the fact that
`\.{\\parfillskip}' glue appears at the end of each paragraph; it is therefore
unnecessary to check if |vlink(cur_p)=null| when |cur_p| is a character node.
*/
- active_width[1] += (is_rotated(line_break_dir))
- ? (glyph_height(cur_p) + glyph_depth(cur_p))
- : glyph_width(cur_p);
+ active_width[1] +=
+ pack_width(line_break_dir, dir_TRT, cur_p, true);
if ((pdf_adjust_spacing > 1) && check_expand_pars(font(cur_p))) {
set_prev_char_p(cur_p);
add_char_stretch(active_width[8], cur_p);
@@ -1702,11 +1825,13 @@ ext_do_line_break(boolean d,
cur_p = vlink(cur_p);
while (cur_p == null && nest_index > 0) {
cur_p = nest_stack[--nest_index];
- /* fprintf(stderr,"Node Pop %d [%d]\n",nest_index,(int)cur_p); */
+#ifdef DEBUG
+ fprintf(stderr,"Node Pop %d [%d]\n",nest_index,(int)cur_p);
+#endif
}
}
if (cur_p == null) { /* TODO */
- tconfusion("linebreak_tail");
+ confusion("linebreak_tail");
}
/* Determine legal breaks: As we move through the hlist, we need to keep
the |active_width| array up to date, so that the badness of individual
@@ -1715,22 +1840,18 @@ ext_do_line_break(boolean d,
real width as opposed to glue. */
switch (type(cur_p)) {
-
case hlist_node:
case vlist_node:
active_width[1] +=
- (dir_orthogonal
- (dir_primary[box_dir(cur_p)], dir_primary[line_break_dir]))
- ? (depth(cur_p) + height(cur_p))
- : width(cur_p);
+ pack_width(line_break_dir, box_dir(cur_p), cur_p, false);
break;
case rule_node:
active_width[1] += width(cur_p);
break;
case whatsit_node:
- /* @<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>; */
+ /* Advance past a whatsit node in the |line_break| loop; */
switch (subtype(cur_p)) {
- case local_par_node: /* @<LOCAL: Advance past a |local_paragraph| node@>; */
+ case local_par_node: /* LOCAL: Advance past a |local_paragraph| node; */
internal_pen_inter = local_pen_inter(cur_p);
internal_pen_broken = local_pen_broken(cur_p);
internal_left_box = local_box_left(cur_p);
@@ -1738,10 +1859,10 @@ ext_do_line_break(boolean d,
internal_right_box = local_box_right(cur_p);
internal_right_box_width = local_box_right_width(cur_p);
break;
- case dir_node: /* @<DIR: Adjust the dir stack for the |line_break| routine@>; */
+ case dir_node: /* DIR: Adjust the dir stack for the |line_break| routine; */
if (dir_dir(cur_p) >= 0) {
line_break_dir = dir_dir(cur_p);
- push_dir_node(cur_p); /* adds to dir_ptr */
+ push_dir_node(cur_p); /* adds to |dir_ptr| */
} else {
pop_dir_node();
if (dir_ptr != null)
@@ -1750,14 +1871,14 @@ ext_do_line_break(boolean d,
break;
case pdf_refxform_node:
case pdf_refximage_node:
- active_width[1] += pdf_width(cur_p);
+ active_width[1] += width(cur_p);
}
- /* / Advance \(p)past a whatsit node in the \(l)|line_break| loop/; */
+ /* / Advance past a whatsit node in the |line_break| loop/; */
break;
case glue_node:
- /* @<If node |cur_p| is a legal breakpoint, call |try_break|;
+ /* If node |cur_p| is a legal breakpoint, call |try_break|;
then update the active widths by including the glue in
- |glue_ptr(cur_p)|@>; */
+ |glue_ptr(cur_p)|; */
/* When node |cur_p| is a glue node, we look at the previous to
see whether or not a breakpoint is legal at |cur_p|, as
explained above. */
@@ -1769,7 +1890,7 @@ ext_do_line_break(boolean d,
precedes_break(prev_p) ||
((type(prev_p) == kern_node)
&& (subtype(prev_p) != explicit)))) {
- ext_try_break(0, unhyphenated_node, pdf_adjust_spacing,
+ ext_try_break(0, unhyphenated_node, line_break_dir, pdf_adjust_spacing,
par_shape_ptr, adj_demerits,
tracing_paragraphs, pdf_protrude_chars,
line_penalty, last_line_fit,
@@ -1796,10 +1917,10 @@ ext_do_line_break(boolean d,
}
break;
case disc_node:
- /* select_discs are handled by the leading init_disc */
+ /* |select_disc|s are handled by the leading |init_disc| */
if (subtype(cur_p) == select_disc)
break;
- /* @<Try to break after a discretionary fragment, then |goto done5|@>; */
+ /* Try to break after a discretionary fragment, then |goto done5|; */
/* The following code knows that discretionary texts contain
only character nodes, kern nodes, box nodes, and rule
nodes. */
@@ -1811,27 +1932,29 @@ ext_do_line_break(boolean d,
do_one_seven_eight(reset_disc_width);
if (s == null) { /* trivial pre-break */
ext_try_break(actual_penalty, hyphenated_node,
- pdf_adjust_spacing, par_shape_ptr,
- adj_demerits, tracing_paragraphs,
- pdf_protrude_chars, line_penalty,
- last_line_fit, double_hyphen_demerits,
+ line_break_dir, pdf_adjust_spacing,
+ par_shape_ptr, adj_demerits,
+ tracing_paragraphs, pdf_protrude_chars,
+ line_penalty, last_line_fit,
+ double_hyphen_demerits,
final_hyphen_demerits, first_p, cur_p);
} else {
add_to_widths(s, line_break_dir, pdf_adjust_spacing,
disc_width);
do_one_seven_eight(add_disc_width_to_active_width);
ext_try_break(actual_penalty, hyphenated_node,
- pdf_adjust_spacing, par_shape_ptr,
- adj_demerits, tracing_paragraphs,
- pdf_protrude_chars, line_penalty,
- last_line_fit, double_hyphen_demerits,
+ line_break_dir, pdf_adjust_spacing,
+ par_shape_ptr, adj_demerits,
+ tracing_paragraphs, pdf_protrude_chars,
+ line_penalty, last_line_fit,
+ double_hyphen_demerits,
final_hyphen_demerits, first_p, cur_p);
if (subtype(cur_p) == init_disc) {
/* we should at two break points after the one we
- * added above:
- * 1 which does a possible break in INIT's post_break
- * 2 which means the no_break actually was broken
- * just a character later */
+ added above:
+ \item1 which does a possible break in INIT's |post_break|
+ \item2 which means the |no_break| actually was broken
+ just a character later */
/* do the select-0 case 'f-f-i' */
assert(type(vlink(cur_p)) == disc_node &&
subtype(vlink(cur_p)) == select_disc);
@@ -1839,8 +1962,9 @@ ext_do_line_break(boolean d,
add_to_widths(s, line_break_dir, pdf_adjust_spacing,
disc_width);
ext_try_break(actual_penalty, hyphenated_node,
- pdf_adjust_spacing, par_shape_ptr,
- adj_demerits, tracing_paragraphs,
+ line_break_dir, pdf_adjust_spacing,
+ par_shape_ptr, adj_demerits,
+ tracing_paragraphs,
pdf_protrude_chars, line_penalty,
last_line_fit, double_hyphen_demerits,
final_hyphen_demerits, first_p,
@@ -1851,13 +1975,14 @@ ext_do_line_break(boolean d,
do_one_seven_eight
(sub_disc_width_from_active_width);
do_one_seven_eight(reset_disc_width);
- /* add select no_break to active_width */
+ /* add select |no_break| to |active_width| */
s = vlink_no_break(vlink(cur_p));
add_to_widths(s, line_break_dir, pdf_adjust_spacing,
disc_width);
ext_try_break(actual_penalty, hyphenated_node,
- pdf_adjust_spacing, par_shape_ptr,
- adj_demerits, tracing_paragraphs,
+ line_break_dir, pdf_adjust_spacing,
+ par_shape_ptr, adj_demerits,
+ tracing_paragraphs,
pdf_protrude_chars, line_penalty,
last_line_fit, double_hyphen_demerits,
final_hyphen_demerits, first_p,
@@ -1876,7 +2001,7 @@ ext_do_line_break(boolean d,
kern_break();
break;
case penalty_node:
- ext_try_break(penalty(cur_p), unhyphenated_node,
+ ext_try_break(penalty(cur_p), unhyphenated_node, line_break_dir,
pdf_adjust_spacing, par_shape_ptr, adj_demerits,
tracing_paragraphs, pdf_protrude_chars,
line_penalty, last_line_fit,
@@ -1892,12 +2017,14 @@ ext_do_line_break(boolean d,
break;
default:
fprintf(stdout, "\ntype=%d", type(cur_p));
- tconfusion("paragraph");
+ confusion("paragraph");
}
cur_p = vlink(cur_p);
while (cur_p == null && nest_index > 0) {
cur_p = nest_stack[--nest_index];
- /* fprintf(stderr,"Node Pop %d [%d]\n",nest_index,(int)cur_p); */
+#ifdef DEBUG
+ fprintf(stderr,"Node Pop %d [%d]\n",nest_index,(int)cur_p);
+#endif
}
}
if (cur_p == null) {
@@ -1915,13 +2042,13 @@ ext_do_line_break(boolean d,
help determine what is best.
*/
- ext_try_break(eject_penalty, hyphenated_node, pdf_adjust_spacing,
- par_shape_ptr, adj_demerits, tracing_paragraphs,
- pdf_protrude_chars, line_penalty, last_line_fit,
- double_hyphen_demerits, final_hyphen_demerits,
- first_p, cur_p);
+ ext_try_break(eject_penalty, hyphenated_node, line_break_dir,
+ pdf_adjust_spacing, par_shape_ptr, adj_demerits,
+ tracing_paragraphs, pdf_protrude_chars, line_penalty,
+ last_line_fit, double_hyphen_demerits,
+ final_hyphen_demerits, first_p, cur_p);
if (vlink(active) != active) {
- /* @<Find an active node with fewest demerits@>; */
+ /* Find an active node with fewest demerits; */
r = vlink(active);
fewest_demerits = awful_bad;
do {
@@ -1938,7 +2065,7 @@ ext_do_line_break(boolean d,
/* /Find an active node with fewest demerits; */
if (looseness == 0)
goto DONE;
- /*@<Find the best active node for the desired looseness@>; */
+ /*Find the best active node for the desired looseness; */
/* The adjustment for a desired looseness is a slightly more complicated
version of the loop just considered. Note that if a paragraph is broken
@@ -1979,13 +2106,13 @@ ext_do_line_break(boolean d,
if (!second_pass) {
if (tracing_paragraphs > 0)
- tprint_nl("@secondpass");
+ tprint_nl("@@secondpass");
threshold = tolerance;
second_pass = true;
final_pass = (emergency_stretch <= 0);
} else { /* if at first you do not succeed, \dots */
if (tracing_paragraphs > 0)
- tprint_nl("@emergencypass");
+ tprint_nl("@@emergencypass");
background[2] += emergency_stretch;
final_pass = true;
}
@@ -1997,7 +2124,7 @@ ext_do_line_break(boolean d,
normalize_selector();
}
if (do_last_line_fit) {
- /* Adjust \(t)the final line of the paragraph; */
+ /* Adjust the final line of the paragraph; */
/* Here we either reset |do_last_line_fit| or adjust the |par_fill_skip| glue.
*/
if (active_short(best_bet) == 0) {
@@ -2011,7 +2138,7 @@ ext_do_line_break(boolean d,
}
}
- /* @<Break the paragraph at the chosen...@>; */
+ /* Break the paragraph at the chosen...; */
/* Once the best sequence of breakpoints has been found (hurray), we call on the
procedure |post_line_break| to finish the remainder of the work.
(By introducing this subprocedure, we are able to keep |line_break|
@@ -2021,8 +2148,7 @@ ext_do_line_break(boolean d,
/* first thing |ext_post_line_break| does is reset |dir_ptr| */
flush_node_list(dir_ptr);
dir_ptr = null;
-
- ext_post_line_break(d,
+ ext_post_line_break(paragraph_dir,
right_skip,
left_skip,
pdf_protrude_chars,
@@ -2036,9 +2162,7 @@ ext_do_line_break(boolean d,
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,
@@ -2051,3 +2175,10 @@ ext_do_line_break(boolean d,
/* Clean up the memory by removing the break nodes; */
clean_up_the_memory();
}
+
+@ @c
+void get_linebreak_info (int *f, int *a)
+{
+ *f = fewest_demerits;
+ *a = actual_looseness;
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.h b/Build/source/texk/web2c/luatexdir/tex/mainbody.h
new file mode 100644
index 00000000000..0b108ad896f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.h
@@ -0,0 +1,252 @@
+/* mainbody.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: mainbody.h 3436 2010-02-21 15:34:00Z taco $ */
+
+#ifndef MAINBODY_H
+# define MAINBODY_H
+
+extern int luatex_svn;
+extern int luatex_version;
+extern int luatex_revision;
+extern int luatex_date_info;
+extern const char *luatex_version_string;
+extern const char *engine_name;
+
+/*
+The following parameters can be changed at compile time to extend or
+reduce \TeX's capacity. They may have different values in \.{INITEX} and
+in production versions of \TeX.
+@.INITEX@>
+@^system dependencies@>
+*/
+
+# define ssup_max_strings 262143
+
+# define inf_max_strings 100000
+# define sup_max_strings ssup_max_strings
+# define inf_strings_free 100
+# define sup_strings_free sup_max_strings
+
+# define inf_buf_size 500
+# define sup_buf_size 100000000
+
+# define inf_nest_size 40
+# define sup_nest_size 4000
+
+# define inf_max_in_open 6
+# define sup_max_in_open 127
+
+# define inf_param_size 60
+# define sup_param_size 6000
+
+# define inf_save_size 600
+# define sup_save_size 80000
+
+# define inf_stack_size 200
+# define sup_stack_size 30000
+
+# define inf_dvi_buf_size 800
+# define sup_dvi_buf_size 65536
+
+# define sup_hash_extra sup_max_strings
+# define inf_hash_extra 0
+
+# define sup_ocp_list_size 1000000
+# define inf_ocp_list_size 1000
+# define sup_ocp_buf_size 100000000
+# define inf_ocp_buf_size 1000
+# define sup_ocp_stack_size 1000000
+# define inf_ocp_stack_size 1000
+
+# define inf_expand_depth 100
+# define sup_expand_depth 1000000
+
+
+# include <stdio.h>
+
+/* Types in the outer block */
+typedef int ASCII_code; /* characters */
+typedef unsigned char eight_bits; /* unsigned one-byte quantity */
+typedef FILE *alpha_file; /* files that contain textual data */
+typedef FILE *byte_file; /* files that contain binary data */
+
+typedef int str_number;
+typedef int pool_pointer;
+typedef unsigned char packed_ASCII_code;
+
+typedef int scaled; /* this type is used for scaled integers */
+typedef char small_number; /* this type is self-explanatory */
+
+typedef float glue_ratio; /* one-word representation of a glue expansion factor */
+
+typedef unsigned short quarterword;
+typedef int halfword;
+
+typedef unsigned char glue_ord; /* infinity to the 0, 1, 2, 3, or 4 power */
+
+typedef unsigned short group_code; /* |save_level| for a level boundary */
+
+typedef int internal_font_number; /* |font| in a |char_node| */
+typedef int font_index; /* index into |font_info| */
+
+typedef int save_pointer;
+
+/*
+Characters of text that have been converted to \TeX's internal form
+are said to be of type |ASCII_code|, which is a subrange of the integers.
+
+We are assuming that our runtime system is able to read and write UTF-8.
+
+Some of the ASCII codes without visible characters have been given symbolic
+names in this program because they are used with a special meaning.
+*/
+
+
+# define null_code '\0' /* ASCII code that might disappear */
+# define carriage_return '\r' /* ASCII code used at end of line */
+
+/* Global variables */
+extern int bad; /* is some ``constant'' wrong? */
+extern boolean luainit; /* are we using lua for initializations */
+extern boolean tracefilenames; /* print file open-close info? */
+
+
+extern boolean ini_version; /* are we \.{INITEX}? */
+extern boolean dump_option;
+extern boolean dump_line;
+extern int bound_default;
+extern char *bound_name;
+extern int error_line;
+extern int half_error_line;
+extern int max_print_line;
+extern int ocp_list_size;
+extern int ocp_buf_size;
+extern int ocp_stack_size;
+extern int max_strings;
+extern int strings_free;
+extern int font_k;
+extern int buf_size;
+extern int stack_size;
+extern int max_in_open;
+extern int param_size;
+extern int nest_size;
+extern int save_size;
+extern int expand_depth;
+extern int parsefirstlinep;
+extern int filelineerrorstylep;
+extern int haltonerrorp;
+extern boolean quoted_filename;
+
+/*
+In order to make efficient use of storage space, \TeX\ bases its major data
+structures on a |memory_word|, which contains either a (signed) integer,
+possibly scaled, or a (signed) |glue_ratio|, or a small number of
+fields that are one half or one quarter of the size used for storing
+integers.
+
+If |x| is a variable of type |memory_word|, it contains up to four
+fields that can be referred to as follows:
+$$\vbox{\halign{\hfil#&#\hfil&#\hfil\cr
+|x|&.|int|&(an |integer|)\cr
+|x|&.|sc|\qquad&(a |scaled| integer)\cr
+|x|&.|gr|&(a |glue_ratio|)\cr
+|x.hh.lh|, |x.hh|&.|rh|&(two halfword fields)\cr
+|x.hh.b0|, |x.hh.b1|, |x.hh|&.|rh|&(two quarterword fields, one halfword
+ field)\cr
+|x.qqqq.b0|, |x.qqqq.b1|, |x.qqqq|&.|b2|, |x.qqqq.b3|\hskip-100pt
+ &\qquad\qquad\qquad(four quarterword fields)\cr}}$$
+This is somewhat cumbersome to write, and not very readable either, but
+macros will be used to make the notation shorter and more transparent.
+The \PASCAL\ code below gives a formal definition of |memory_word| and
+its subsidiary types, using packed variant records. \TeX\ makes no
+assumptions about the relative positions of the fields within a word.
+
+We are assuming 32-bit integers, a halfword must contain at least
+32 bits, and a quarterword must contain at least 16 bits.
+@^system dependencies@>
+
+N.B.: Valuable memory space will be dreadfully wasted unless \TeX\ is compiled
+by a \PASCAL\ that packs all of the |memory_word| variants into
+the space of a single integer. This means, for example, that |glue_ratio|
+words should be |short_real| instead of |real| on some computers. Some
+\PASCAL\ compilers will pack an integer whose subrange is `|0..255|' into
+an eight-bit field, but others insist on allocating space for an additional
+sign bit; on such systems you can get 256 values into a quarterword only
+if the subrange is `|-128..127|'.
+
+The present implementation tries to accommodate as many variations as possible,
+so it makes few assumptions. If integers having the subrange
+`|min_quarterword..max_quarterword|' can be packed into a quarterword,
+and if integers having the subrange `|min_halfword..max_halfword|'
+can be packed into a halfword, everything should work satisfactorily.
+
+It is usually most efficient to have |min_quarterword=min_halfword=0|,
+so one should try to achieve this unless it causes a severe problem.
+The values defined here are recommended for most 32-bit computers.
+
+We cannot use the full range of 32 bits in a halfword, because we have
+to allow negative values for potential backend tricks like web2c's
+dynamic allocation, and parshapes pointers have to be able to store at
+least twice the value |max_halfword| (see below). Therefore,
+|max_halfword| is $2^{30}-1$
+*/
+
+# include "tex/memoryword.h"
+
+# define min_quarterword 0 /*smallest allowable value in a |quarterword| */
+# define max_quarterword 65535 /* largest allowable value in a |quarterword| */
+# define min_halfword -0x3FFFFFFF /* smallest allowable value in a |halfword| */
+# define max_halfword 0x3FFFFFFF
+ /* largest allowable value in a |halfword| */
+
+
+/*
+The following procedure, which is called just before \TeX\ initializes its
+input and output, establishes the initial values of the date and time.
+It calls a macro-defined |dateandtime| routine. |dateandtime| in turn is
+also a C macro, which calls |get_date_and_time|, passing it the addresses of
+the day, month, etc., so they can be set by the routine.
+|get_date_and_time| also sets up interrupt catching if that
+is conditionally compiled in the C code.
+@^system dependencies@>
+*/
+
+
+# define fix_date_and_time() dateandtime(int_par(time_code),int_par(day_code),int_par(month_code),int_par(year_code))
+
+extern int get_luatexsvn(void);
+extern int get_luatexversion(void);
+extern str_number get_luatexrevision(void);
+extern int get_luatex_date_info(void);
+
+extern int ready_already;
+
+extern void main_body(void);
+extern void close_files_and_terminate(void);
+
+extern void final_cleanup(void);
+extern void debug_help(void); /* routine to display various things */
+
+/* lazy me */
+# define get_cur_font() equiv(cur_font_loc)
+# define zset_cur_font set_cur_font
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.w b/Build/source/texk/web2c/luatexdir/tex/mainbody.w
new file mode 100644
index 00000000000..abdf1af920b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.w
@@ -0,0 +1,745 @@
+% mainbody.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+\def\eTeX{e-\TeX}
+\def\Aleph{Aleph}
+\def\pdfTeX{pdf\TeX}
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: mainbody.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/mainbody.w $";
+
+@
+pdfTeX is copyright (C) 1996-2006 Han The Thanh, <thanh@@pdftex.org>.
+
+e-TeX is copyright (C) 1994,98 by Peter Breitenlohner.
+
+This is LuaTeX, a continuation of $\pdfTeX$ and $\Aleph$. LuaTeX is a
+document compiler intended to simplify high-quality typesetting for
+many of the world's languages. It is an extension of D. E. Knuth's
+\TeX, which was designed essentially for the typesetting of languages
+using the Latin alphabet.
+
+The $\Aleph$ subsystem loosens many of the restrictions imposed by~\TeX:
+register numbers are no longer limited to 8~bits; fonts may have more
+than 256~characters; more than 256~fonts may be used; etc.
+
+% This program is directly derived from Donald E. Knuth's TeX;
+% the change history which follows and the reward offered for finders of
+% bugs refer specifically to TeX; they should not be taken as referring
+% to LuaTeX, pdfTeX, nor e-TeX, although the change history is relevant in that it
+% demonstrates the evolutionary path followed. This program is not TeX;
+% that name is reserved strictly for the program which is the creation
+% and sole responsibility of Professor Knuth.
+
+% Version 0 was released in September 1982 after it passed a variety of tests.
+% Version 1 was released in November 1983 after thorough testing.
+% Version 1.1 fixed ``disappearing font identifiers'' et alia (July 1984).
+% Version 1.2 allowed `0' in response to an error, et alia (October 1984).
+% Version 1.3 made memory allocation more flexible and local (November 1984).
+% Version 1.4 fixed accents right after line breaks, et alia (April 1985).
+% Version 1.5 fixed \the\toks after other expansion in \edefs (August 1985).
+% Version 2.0 (almost identical to 1.5) corresponds to "Volume B" (April 1986).
+% Version 2.1 corrected anomalies in discretionary breaks (January 1987).
+% Version 2.2 corrected "(Please type...)" with null \endlinechar (April 1987).
+% Version 2.3 avoided incomplete page in premature termination (August 1987).
+% Version 2.4 fixed \noaligned rules in indented displays (August 1987).
+% Version 2.5 saved cur_order when expanding tokens (September 1987).
+% Version 2.6 added 10sp slop when shipping leaders (November 1987).
+% Version 2.7 improved rounding of negative-width characters (November 1987).
+% Version 2.8 fixed weird bug if no \patterns are used (December 1987).
+% Version 2.9 made \csname\endcsname's "relax" local (December 1987).
+% Version 2.91 fixed \outer\def\a0{}\a\a bug (April 1988).
+% Version 2.92 fixed \patterns, also file names with complex macros (May 1988).
+% Version 2.93 fixed negative halving in allocator when mem_min<0 (June 1988).
+% Version 2.94 kept open_log_file from calling fatal_error (November 1988).
+% Version 2.95 solved that problem a better way (December 1988).
+% Version 2.96 corrected bug in "Infinite shrinkage" recovery (January 1989).
+% Version 2.97 corrected blunder in creating 2.95 (February 1989).
+% Version 2.98 omitted save_for_after at outer level (March 1989).
+% Version 2.99 caught $$\begingroup\halign..$$ (June 1989).
+% Version 2.991 caught .5\ifdim.6... (June 1989).
+% Version 2.992 introduced major changes for 8-bit extensions (September 1989).
+% Version 2.993 fixed a save_stack synchronization bug et alia (December 1989).
+% Version 3.0 fixed unusual displays; was more \output robust (March 1990).
+% Version 3.1 fixed nullfont, disabled \write{\the\prevgraf} (September 1990).
+% Version 3.14 fixed unprintable font names and corrected typos (March 1991).
+% Version 3.141 more of same; reconstituted ligatures better (March 1992).
+% 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
+% 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
+% connection with the use or performance of this software. This work has
+% been a ``labor of love'' and the authors hope that users enjoy it.
+
+A large piece of software like \TeX\ 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
+\TeX\ language itself, since the reader is supposed to be familiar with
+{\sl The \TeX book}.
+@.WEB@>
+@:TeXbook}{\sl The \TeX book@>
+
+The present implementation has a long ancestry, beginning in the summer
+of~1977, when Michael~F. Plass and Frank~M. Liang designed and coded
+a prototype
+@^Plass, Michael Frederick@>
+@^Liang, Franklin Mark@>
+@^Knuth, Donald Ervin@>
+based on some specifications that the author had made in May of that year.
+This original proto\TeX\ included macro definitions and elementary
+manipulations on boxes and glue, but it did not have line-breaking,
+page-breaking, mathematical formulas, alignment routines, error recovery,
+or the present semantic nest; furthermore,
+it used character lists instead of token lists, so that a control sequence
+like \.{\\halign} was represented by a list of seven characters. A
+complete version of \TeX\ was designed and coded by the author in late
+1977 and early 1978; that program, like its prototype, was written in the
+{\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@>
+was written by the author during the latter part of 1981 and the early
+part of 1982, also incorporates ideas from the 1979 implementation of
+@^Guibas, Leonidas Ioannis@>
+@^Sedgewick, Robert@>
+@^Wyatt, Douglas Kirk@>
+\TeX\ in {\mc MESA} that was written by Leonidas Guibas, Robert Sedgewick,
+and Douglas Wyatt at the Xerox Palo Alto Research Center. Several hundred
+refinements were introduced into \TeX82 based on the experiences gained with
+the original implementations, so that essentially every part of the system
+has been substantially improved. After the appearance of ``Version 0'' in
+September 1982, this program benefited greatly from the comments of
+many other people, notably David~R. Fuchs and Howard~W. Trickey.
+A final revision in September 1989 extended the input character set to
+eight-bit codes and introduced the ability to hyphenate words from
+different languages, based on some ideas of Michael~J. Ferguson.
+@^Fuchs, David Raymond@>
+@^Trickey, Howard Wellington@>
+@^Ferguson, Michael John@>
+
+No doubt there still is plenty of room for improvement, but the author
+is firmly committed to keeping \TeX82 ``frozen'' from now on; stability
+and reliability are to be its main virtues.
+
+On the other hand, the \.{WEB} description can be extended without changing
+the core of \TeX82 itself, and the program has been designed so that such
+extensions are not extremely difficult to make.
+The |banner| string defined here should be changed whenever \TeX\
+undergoes any modifications, so that it will be clear which version of
+\TeX\ might be the guilty party when a problem arises.
+@^extensions to \TeX@>
+@^system dependencies@>
+
+This program contains code for various features extending \TeX,
+therefore this program is called `\eTeX' and not
+`\TeX'; the official name `\TeX' by itself is reserved
+for software systems that are fully compatible with each other.
+A special test suite called the ``\.{TRIP} test'' is available for
+helping to determine whether a particular implementation deserves to be
+known as `\TeX' [cf.~Stanford Computer Science report CS1027,
+November 1984].
+
+A similar test suite called the ``\.{e-TRIP} test'' is available for
+helping to determine whether a particular implementation deserves to be
+known as `\eTeX'.
+
+@ In case somebody has inadvertently made bad settings of the ``constants,''
+\TeX\ checks them using a global variable called |bad|.
+
+This is the first of many sections of \TeX\ where global variables are
+defined.
+
+@c
+int bad; /* is some ``constant'' wrong? */
+boolean luainit; /* are we using lua for initializations */
+boolean tracefilenames; /* print file open-close info? */
+
+
+@ This program has two important variations: (1) There is a long and slow
+version called \.{INITEX}, which does the extra calculations needed to
+@.INITEX@>
+initialize \TeX's internal tables; and (2)~there is a shorter and faster
+production version, which cuts the initialization to a bare minimum.
+
+@c
+boolean ini_version; /* are we \.{INITEX}? */
+boolean dump_option; /* was the dump name option used? */
+boolean dump_line; /* was a \.{\%\AM format} line seen? */
+int bound_default; /* temporary for setup */
+char *bound_name; /* temporary for setup */
+int error_line; /* width of context lines on terminal error messages */
+int half_error_line; /* width of first lines of contexts in terminal
+ error messages; should be between 30 and |error_line-15| */
+int max_print_line; /* width of longest text lines output; should be at least 60 */
+int ocp_list_size;
+int ocp_buf_size;
+int ocp_stack_size;
+int max_strings; /* maximum number of strings; must not exceed |max_halfword| */
+int strings_free; /* strings available after format loaded */
+int font_k; /* loop variable for initialization */
+int buf_size; /* maximum number of characters simultaneously present in
+ current lines of open files and in control sequences between
+ \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword| */
+int stack_size; /* maximum number of simultaneous input sources */
+int max_in_open; /* maximum number of input files and error insertions that
+ can be going on simultaneously */
+int param_size; /* maximum number of simultaneous macro parameters */
+int nest_size; /* maximum number of semantic levels simultaneously active */
+int save_size; /* space for saving values outside of current group; must be
+ at most |max_halfword| */
+int expand_depth; /* limits recursive calls of the |expand| procedure */
+int parsefirstlinep; /* parse the first line for options */
+int filelineerrorstylep; /* format messages as file:line:error */
+int haltonerrorp; /* stop at first error */
+boolean quoted_filename; /* current filename is quoted */
+
+@ @c
+int get_luatexversion(void)
+{
+ return luatex_version;
+}
+
+int get_luatexsvn(void)
+{
+ return luatex_svn;
+}
+
+str_number get_luatexrevision(void)
+{
+ return luatex_revision;
+}
+
+int get_luatex_date_info(void)
+{
+ return luatex_date_info; /* todo, silly value */
+}
+
+
+@ This is it: the part of \TeX\ that executes all those procedures we have
+written.
+
+We have noted that there are two versions of \TeX82. One, called \.{INITEX},
+@.INITEX@>
+has to be run first; it initializes everything from scratch, without
+reading a format file, and it has the capability of dumping a format file.
+The other one is called `\.{VIRTEX}'; it is a ``virgin'' program that needs
+@.VIRTEX@>
+to input a format file in order to get started.
+
+@c
+#define const_chk(A) do { \
+ if (A < inf_##A) A = inf_##A; \
+ if (A > sup_##A) A = sup_##A; \
+ } while (0)
+
+#define setup_bound_var(A,B,C) do { \
+ if (luainit>0) { \
+ get_lua_number("texconfig",B,&C); \
+ if (C==0) C=A; \
+ } else { \
+ integer x; \
+ setupboundvariable(&x, B, A); \
+ C = (int)x; \
+ } \
+ } while (0)
+
+
+int ready_already = 0;
+
+int main_initialize(void)
+{
+ int bad = 0;
+ /* Bounds that may be set from the configuration file. We want the user to
+ be able to specify the names with underscores, but \.{TANGLE} removes
+ underscores, so we're stuck giving the names twice, once as a string,
+ once as the identifier. How ugly. */
+
+ setup_bound_var(15000, "max_strings", max_strings);
+ setup_bound_var(100, "strings_free", strings_free);
+ setup_bound_var(3000, "buf_size", buf_size);
+ setup_bound_var(50, "nest_size", nest_size);
+ setup_bound_var(15, "max_in_open", max_in_open);
+ setup_bound_var(60, "param_size", param_size);
+ setup_bound_var(4000, "save_size", save_size);
+ setup_bound_var(300, "stack_size", stack_size);
+ setup_bound_var(16384, "dvi_buf_size", dvi_buf_size);
+ setup_bound_var(79, "error_line", error_line);
+ setup_bound_var(50, "half_error_line", half_error_line);
+ setup_bound_var(79, "max_print_line", max_print_line);
+ setup_bound_var(1000, "ocp_list_size", ocp_list_size);
+ setup_bound_var(1000, "ocp_buf_size", ocp_buf_size);
+ setup_bound_var(1000, "ocp_stack_size", ocp_stack_size);
+ setup_bound_var(0, "hash_extra", hash_extra);
+ setup_bound_var(72, "pk_dpi", pk_dpi);
+ setup_bound_var(10000, "expand_depth", expand_depth);
+
+ /* Check other constants against their sup and inf. */
+ const_chk(buf_size);
+ const_chk(nest_size);
+ const_chk(max_in_open);
+ const_chk(param_size);
+ const_chk(save_size);
+ const_chk(stack_size);
+ const_chk(dvi_buf_size);
+ const_chk(max_strings);
+ const_chk(strings_free);
+ const_chk(hash_extra);
+ const_chk(pk_dpi);
+ if (error_line > ssup_error_line)
+ error_line = ssup_error_line;
+
+ /* array memory allocation */
+ buffer = xmallocarray(packed_ASCII_code, (unsigned) buf_size);
+ nest = xmallocarray(list_state_record, (unsigned) nest_size);
+ save_stack = xmallocarray(save_record, (unsigned) save_size);
+ input_stack = xmallocarray(in_state_record, (unsigned) stack_size);
+ input_file = xmallocarray(alpha_file, (unsigned) max_in_open);
+ input_file_callback_id = xmallocarray(int, (unsigned) max_in_open);
+ line_stack = xmallocarray(int, (unsigned) max_in_open);
+ eof_seen = xmallocarray(boolean, (unsigned) max_in_open);
+ grp_stack = xmallocarray(save_pointer, (unsigned) max_in_open);
+ if_stack = xmallocarray(pointer, (unsigned) max_in_open);
+ source_filename_stack = xmallocarray(str_number, (unsigned) max_in_open);
+ full_source_filename_stack = xmallocarray(char *, (unsigned) max_in_open);
+ param_stack = xmallocarray(halfword, (unsigned) param_size);
+ dvi_buf = xmallocarray(eight_bits, (unsigned) dvi_buf_size);
+ initialize_ocplist_arrays(ocp_list_size);
+ initialize_ocp_buffers(ocp_buf_size, ocp_stack_size);
+
+ if (ini_version) {
+ fixmem = xmallocarray(smemory_word, fix_mem_init + 1);
+ memset(voidcast(fixmem), 0, (fix_mem_init + 1) * sizeof(smemory_word));
+ fix_mem_min = 0;
+ fix_mem_max = fix_mem_init;
+ eqtb_top = eqtb_size + hash_extra;
+ if (hash_extra == 0)
+ hash_top = undefined_control_sequence;
+ else
+ hash_top = eqtb_top;
+ hash = xmallocarray(two_halves, (unsigned) (hash_top + 1));
+ memset(hash, 0, sizeof(two_halves) * (unsigned) (hash_top + 1));
+ eqtb = xmallocarray(memory_word, (unsigned) (eqtb_top + 1));
+ memset(eqtb, 0, sizeof(memory_word) * (unsigned) (eqtb_top + 1));
+ init_string_pool_array((unsigned) max_strings);
+ reset_cur_string();
+ }
+ /* Check the ``constant'' values... */
+ if ((half_error_line < 30) || (half_error_line > error_line - 15))
+ bad = 1;
+ if (max_print_line < 60)
+ bad = 2;
+ if (dvi_buf_size % 8 != 0)
+ bad = 3;
+ if (hash_prime > hash_size)
+ bad = 5;
+ if (max_in_open >= 128)
+ bad = 6;
+ /* Here are the inequalities that the quarterword and halfword values
+ must satisfy (or rather, the inequalities that they mustn't satisfy): */
+ if ((min_quarterword > 0) || (max_quarterword < 0x7FFF))
+ bad = 11;
+ if ((min_halfword > 0) || (max_halfword < 0x3FFFFFFF))
+ bad = 12;
+ if ((min_quarterword < min_halfword) || (max_quarterword > max_halfword))
+ bad = 13;
+ if (font_base < min_quarterword)
+ bad = 15;
+ if ((save_size > max_halfword) || (max_strings > max_halfword))
+ bad = 17;
+ if (buf_size > max_halfword)
+ bad = 18;
+ if (max_quarterword - min_quarterword < 0xFFFF)
+ bad = 19;
+ if (cs_token_flag + eqtb_size + hash_extra > max_halfword)
+ bad = 21;
+ if (bad > 0) {
+ wterm_cr();
+ fprintf(term_out,
+ "Ouch---my internal constants have been clobbered! ---case %d",
+ (int) bad);
+ } else {
+ initialize(); /* set global variables to their starting values */
+ if (ini_version) {
+ /* initialize all the primitives */
+ no_new_control_sequence = false;
+ first = 0;
+ initialize_commands();
+ initialize_etex_commands();
+ init_str_ptr = str_ptr;
+ no_new_control_sequence = true;
+ fix_date_and_time();
+ }
+ ready_already = 314159;
+ }
+ return bad;
+}
+
+@ @c
+void main_body(void)
+{
+ static char pdftex_map[] = "pdftex.map";
+ bad = main_initialize();
+ history = fatal_error_stop; /* in case we quit during initialization */
+ t_open_out(); /* open the terminal for output */
+ if (!luainit)
+ tracefilenames = true;
+ if (bad > 0) {
+ goto FINAL_END;
+ }
+ print_banner(luatex_version_string, luatex_date_info, luatex_svn);
+
+ /* Get the first line of input and prepare to start */
+ /* When we begin the following code, \TeX's tables may still contain garbage;
+ the strings might not even be present. Thus we must proceed cautiously to get
+ bootstrapped in.
+
+ But when we finish this part of the program, \TeX\ is ready to call on the
+ |main_control| routine to do its work.
+ */
+ initialize_inputstack(); /* this copies the command-line */
+ if (buffer[iloc] == '*')
+ incr(iloc);
+ if ((format_ident == 0) || (buffer[iloc] == '&') || dump_line) {
+ char *fname = NULL;
+ if (format_ident != 0)
+ initialize(); /* erase preloaded format */
+ if ((fname = open_fmt_file()) == NULL)
+ goto FINAL_END;
+ if (!load_fmt_file(fname)) {
+ zwclose(fmt_file);
+ goto FINAL_END;
+ }
+ zwclose(fmt_file);
+ while ((iloc < ilimit) && (buffer[iloc] == ' '))
+ incr(iloc);
+ }
+ if (pdf_output_option != 0)
+ int_par(pdf_output_code) = pdf_output_value;
+ if (pdf_draftmode_option != 0)
+ int_par(pdf_draftmode_code) = pdf_draftmode_value;
+ pdf_init_map_file((char *) pdftex_map);
+ if (end_line_char_inactive())
+ decr(ilimit);
+ else
+ buffer[ilimit] = (packed_ASCII_code) int_par(end_line_char_code);
+ fix_date_and_time();
+ if (ini_version)
+ make_pdftex_banner();
+ random_seed = (microseconds * 1000) + (epochseconds % 1000000);
+ init_randoms(random_seed);
+ initialize_math();
+ fixup_selector(log_opened);
+ check_texconfig_init();
+ if ((iloc < ilimit) && (get_cat_code(int_par(cat_code_table_code),
+ buffer[iloc]) != escape_cmd))
+ start_input(); /* \.{\\input} assumed */
+ /* DIR: Initialize |text_dir_ptr| */
+ text_dir_ptr = new_dir(0);
+
+ history = spotless; /* ready to go! */
+ /* Initialize synctex primitive */
+ synctexinitcommand();
+ main_control(); /* come to life */
+ flush_node(text_dir_ptr);
+ final_cleanup(); /* prepare for death */
+ close_files_and_terminate();
+ FINAL_END:
+ do_final_end();
+}
+
+
+@ Here we do whatever is needed to complete \TeX's job gracefully on the
+local operating system. The code here might come into play after a fatal
+error; it must therefore consist entirely of ``safe'' operations that
+cannot produce error messages. For example, it would be a mistake to call
+|str_room| or |make_string| at this time, because a call on |overflow|
+might lead to an infinite loop.
+@^system dependencies@>
+
+Actually there's one way to get error messages, via |prepare_mag|;
+but that can't cause infinite recursion.
+@^recursion@>
+
+This program doesn't bother to close the input files that may still be open.
+
+@c
+void close_files_and_terminate(void)
+{
+ int k; /* all-purpose index */
+ int callback_id;
+ PDF pdf = static_pdf;
+ callback_id = callback_defined(stop_run_callback);
+ /* Finish the extensions */
+ for (k = 0; k <= 15; k++)
+ if (write_open[k])
+ lua_a_close_out(write_file[k]);
+ if (int_par(tracing_stats_code) > 0) {
+ if (callback_id == 0) {
+ /* Output statistics about this job */
+ /* The present section goes directly to the log file instead of using
+ |print| commands, because there's no need for these strings to take
+ up |string_pool| memory when a non-{\bf stat} version of \TeX\ is being used.
+ */
+
+ if (log_opened) {
+ fprintf(log_file,
+ "\n\nHere is how much of LuaTeX's memory you used:\n");
+ fprintf(log_file, " %d string%s out of %d\n",
+ (int) (str_ptr - init_str_ptr),
+ (str_ptr == (init_str_ptr + 1) ? "" : "s"),
+ (int) (max_strings - init_str_ptr + STRING_OFFSET));
+ fprintf(log_file, " %d,%d words of node,token memory allocated",
+ (int) var_mem_max, (int) fix_mem_max);
+ print_node_mem_stats();
+ fprintf(log_file,
+ " %d multiletter control sequences out of %ld+%d\n",
+ (int) cs_count, (long) hash_size, (int) hash_extra);
+ fprintf(log_file, " %d font%s using %d bytes\n",
+ (int) max_font_id(), (max_font_id() == 1 ? "" : "s"),
+ (int) font_bytes);
+ fprintf(log_file,
+ " %di,%dn,%dp,%db,%ds stack positions out of %di,%dn,%dp,%db,%ds\n",
+ (int) max_in_stack, (int) max_nest_stack,
+ (int) max_param_stack, (int) max_buf_stack,
+ (int) max_save_stack + 6, (int) stack_size,
+ (int) nest_size, (int) param_size, (int) buf_size,
+ (int) save_size);
+ }
+ }
+ }
+ wake_up_terminal();
+ ensure_output_state(pdf, ST_OMODE_FIX);
+ switch (pdf->o_mode) {
+ case OMODE_NONE: /* during initex run */
+ break;
+ case OMODE_PDF:
+ if (history == fatal_error_stop) {
+ remove_pdffile(pdf);
+ print_err
+ (" ==> Fatal error occurred, no output PDF file produced!");
+ } else
+ finish_pdf_file(pdf, luatex_version, get_luatexrevision());
+ break;
+ case OMODE_DVI:
+ finish_dvi_file(pdf, luatex_version, get_luatexrevision());
+ break;
+ case OMODE_LUA:
+ finish_lua_file(pdf);
+ break;
+ default:
+ assert(0);
+ }
+ /* Close {\sl Sync\TeX} file and write status */
+ synctexterminate(log_opened); /* Let the {\sl Sync\TeX} controller close its files. */
+
+ free_text_codes();
+ free_math_codes();
+ if (log_opened) {
+ wlog_cr();
+ selector = selector - 2;
+ if ((selector == term_only) && (callback_id == 0)) {
+ tprint_nl("Transcript written on ");
+ tprint_file_name(NULL, texmf_log_name, NULL);
+ print_char('.');
+ print_ln();
+ }
+ lua_a_close_out(log_file);
+ }
+}
+
+
+@ We get to the |final_cleanup| routine when \.{\\end} or \.{\\dump} has
+been scanned and |its_all_over|\kern-2pt.
+
+@c
+void final_cleanup(void)
+{
+ int c; /* 0 for \.{\\end}, 1 for \.{\\dump} */
+ halfword i; /* for looping marks */
+ c = cur_chr;
+ if (job_name == 0)
+ open_log_file();
+ while (input_ptr > 0)
+ if (istate == token_list)
+ end_token_list();
+ else
+ end_file_reading();
+ while (open_parens > 0) {
+ if (tracefilenames)
+ tprint(" )");
+ decr(open_parens);
+ }
+ if (cur_level > level_one) {
+ tprint_nl("(\\end occurred inside a group at level ");
+ print_int(cur_level - level_one);
+ print_char(')');
+ show_save_groups();
+ }
+ while (cond_ptr != null) {
+ tprint_nl("(\\end occurred when ");
+ print_cmd_chr(if_test_cmd, cur_if);
+ if (if_line != 0) {
+ tprint(" on line ");
+ print_int(if_line);
+ }
+ tprint(" was incomplete)");
+ if_line = if_line_field(cond_ptr);
+ cur_if = subtype(cond_ptr);
+ temp_ptr = cond_ptr;
+ cond_ptr = vlink(cond_ptr);
+ flush_node(temp_ptr);
+ }
+ if (callback_defined(stop_run_callback) == 0)
+ if (history != spotless)
+ if ((history == warning_issued) || (interaction < error_stop_mode))
+ if (selector == term_and_log) {
+ selector = term_only;
+ tprint_nl
+ ("(see the transcript file for additional information)");
+ selector = term_and_log;
+ }
+ if (c == 1) {
+ if (ini_version) {
+ for (i = 0; i <= biggest_used_mark; i++) {
+ delete_top_mark(i);
+ delete_first_mark(i);
+ delete_bot_mark(i);
+ delete_split_first_mark(i);
+ delete_split_bot_mark(i);
+ }
+ for (c = last_box_code; c <= vsplit_code; c++)
+ flush_node_list(disc_ptr[c]);
+ if (last_glue != max_halfword)
+ delete_glue_ref(last_glue);
+ while (pseudo_files != null)
+ pseudo_close(); /* flush pseudo files */
+ store_fmt_file();
+ return;
+ }
+ tprint_nl("(\\dump is performed only by INITEX)");
+ return;
+ }
+}
+
+@ Once \TeX\ is working, you should be able to diagnose most errors with
+the \.{\\show} commands and other diagnostic features.
+An additional routine called |debug_help|
+will come into play when you type `\.D' after an error message;
+|debug_help| also occurs just before a fatal error causes \TeX\ to succumb.
+@^debugging@>
+@^system dependencies@>
+
+The interface to |debug_help| is primitive, but it is good enough when used
+with a debugger that allows you to set breakpoints and to read
+variables and change their values. After getting the prompt `\.{debug \#}', you
+type either a negative number (this exits |debug_help|), or zero (this
+goes to a location where you can set a breakpoint, thereby entering into
+dialog with the debugger), or a positive number |m| followed by
+an argument |n|. The meaning of |m| and |n| will be clear from the
+program below. (If |m=13|, there is an additional argument, |l|.)
+@.debug \#@>
+
+@c
+#ifdef DEBUG
+void debug_help(void)
+{ /* routine to display various things */
+ int k;
+ int m = 0, n = 0, l = 0;
+ while (1) {
+ wake_up_terminal();
+ tprint_nl("debug # (-1 to exit):");
+ update_terminal();
+ (void) fscanf(term_in, "%d", &m);
+ if (m < 0)
+ return;
+ else if (m == 0)
+ abort(); /* go to every label at least once */
+ else {
+ (void) fscanf(term_in, "%d", &n);
+ switch (m) {
+ case 1:
+ print_word(varmem[n]); /* display |varmem[n]| in all forms */
+ break;
+ case 2:
+ print_int(info(n));
+ break;
+ case 3:
+ print_int(link(n));
+ break;
+ case 4:
+ print_word(eqtb[n]);
+ break;
+ case 6:
+ print_int(save_type(n));
+ print_int(save_level(n));
+ print_word(save_word(n));
+ break;
+ case 7:
+ show_box(n); /* show a box, abbreviated by |show_box_depth| and |show_box_breadth| */
+ break;
+ case 8:
+ breadth_max = 10000;
+ depth_threshold = 0x7FFFFFFF;
+ show_node_list(n); /* show a box in its entirety */
+ break;
+ case 9:
+ show_token_list(n, null, 1000);
+ break;
+ case 10:
+ slow_print(n);
+ break;
+ case 13:
+ (void) fscanf(term_in, "%d", &l);
+ print_cmd_chr(n, l);
+ break;
+ case 14:
+ for (k = 0; k <= n; k++)
+ print(buffer[k]);
+ break;
+ case 15:
+ font_in_short_display = null_font;
+ short_display(n);
+ break;
+ default:
+ tprint("?");
+ break;
+ }
+ }
+ }
+}
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.h b/Build/source/texk/web2c/luatexdir/tex/maincontrol.h
new file mode 100644
index 00000000000..e07f1e23cd9
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.h
@@ -0,0 +1,196 @@
+/* maincontrol.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: maincontrol.h 3354 2010-01-11 08:49:33Z taco $ */
+
+#ifndef MAINCONTROL_H
+# define MAINCONTROL_H
+
+# define fil_code 0 /* identifies \.{\\hfil} and \.{\\vfil} */
+# define fill_code 1 /* identifies \.{\\hfill} and \.{\\vfill} */
+# define ss_code 2 /* identifies \.{\\hss} and \.{\\vss} */
+# define fil_neg_code 3 /* identifies \.{\\hfilneg} and \.{\\vfilneg} */
+# define skip_code 4 /* identifies \.{\\hskip} and \.{\\vskip} */
+# define mskip_code 5 /* identifies \.{\\mskip} */
+
+/* The |prefixed_command| does not have to adjust |a| so that |a mod 4=0|,
+since the following routines test for the \.{\\global} prefix as follows.
+*/
+
+# define is_global(a) (a>=4)
+
+# define define(A,B,C) do { \
+ if (is_global(a)) \
+ geq_define((A),(quarterword)(B),(C)); \
+ else \
+ eq_define((A),(quarterword)(B),(C)); \
+ } while (0)
+
+# define word_define(A,B) do { \
+ if (is_global(a)) \
+ geq_word_define((A),(B)); \
+ else \
+ eq_word_define((A),(B)); \
+ } while (0)
+
+# define define_lc_code(A,B) do { \
+ if (is_global(a)) \
+ set_lc_code((A),(B),level_one); \
+ else \
+ set_lc_code((A),(B),cur_level); \
+ } while (0)
+
+# define define_uc_code(A,B) do { \
+ if (is_global(a)) \
+ set_uc_code((A),(B),level_one); \
+ else \
+ set_uc_code((A),(B),cur_level); \
+} while (0)
+
+# define define_sf_code(A,B) do { \
+ if (is_global(a)) \
+ set_sf_code((A),(B),level_one); \
+ else \
+ set_sf_code((A),(B),cur_level); \
+ } while (0)
+
+# define define_cat_code(A,B) do { \
+ if (is_global(a)) \
+ set_cat_code(int_par(cat_code_table_code),(A),(B),level_one); \
+ else \
+ set_cat_code(int_par(cat_code_table_code),(A),(B),cur_level); \
+ } while (0)
+
+# define define_fam_fnt(A,B,C) do { \
+ if (is_global(a)) \
+ def_fam_fnt((A),(B),(C),level_one); \
+ else \
+ def_fam_fnt((A),(B),(C),cur_level); \
+ } while (0)
+
+# define define_math_param(A,B,C) do { \
+ if (is_global(a)) \
+ def_math_param((A),(B),(C),level_one); \
+ else \
+ def_math_param((A),(B),(C),cur_level); \
+ } while (0)
+
+extern halfword cur_box; /* box to be placed into its context */
+
+/*
+A \.{\\chardef} creates a control sequence whose |cmd| is |char_given|;
+a \.{\\mathchardef} creates a control sequence whose |cmd| is |math_given|;
+and the corresponding |chr| is the character code or math code. A \.{\\countdef}
+or \.{\\dimendef} or \.{\\skipdef} or \.{\\muskipdef} creates a control
+sequence whose |cmd| is |assign_int| or \dots\ or |assign_mu_glue|, and the
+corresponding |chr| is the |eqtb| location of the internal register in question.
+*/
+
+# define char_def_code 0 /* |shorthand_def| for \.{\\chardef} */
+# define math_char_def_code 1 /* |shorthand_def| for \.{\\mathchardef} */
+# define omath_char_def_code 2 /* |shorthand_def| for \.{\\omathchardef} */
+# define xmath_char_def_code 3 /* |shorthand_def| for \.{\\Umathchardef} */
+# define count_def_code 4 /* |shorthand_def| for \.{\\countdef} */
+# define attribute_def_code 5 /* |shorthand_def| for \.{\\attributedef} */
+# define dimen_def_code 6 /* |shorthand_def| for \.{\\dimendef} */
+# define skip_def_code 7 /* |shorthand_def| for \.{\\skipdef} */
+# define mu_skip_def_code 8 /* |shorthand_def| for \.{\\muskipdef} */
+# define toks_def_code 9 /* |shorthand_def| for \.{\\toksdef} */
+
+extern void adjust_space_factor(void);
+extern void main_control(void);
+extern void app_space(void);
+extern void insert_dollar_sign(void);
+extern void you_cant(void);
+extern void report_illegal_case(void);
+extern boolean privileged(void);
+extern boolean its_all_over(void);
+extern void append_glue(void);
+extern void append_kern(void);
+extern void off_save(void);
+extern void handle_right_brace(void);
+extern void extra_right_brace(void);
+extern void normal_paragraph(void);
+extern void box_end(int box_context);
+extern void scan_box(int box_context);
+extern void new_graf(boolean indented);
+extern void indent_in_hmode(void);
+extern void head_for_vmode(void);
+extern void end_graf(int);
+extern void begin_insert_or_adjust(void);
+extern void handle_mark(void);
+extern void append_penalty(void);
+extern void delete_last(void);
+extern void unpackage(void);
+extern void append_italic_correction(void);
+extern void append_local_box(int kind);
+extern void append_discretionary(void);
+extern void build_local_box(void);
+extern void build_discretionary(void);
+extern void make_accent(void);
+extern void align_error(void);
+extern void no_align_error(void);
+extern void omit_error(void);
+extern void do_endv(void);
+extern void cs_error(void);
+extern void prefixed_command(void);
+extern void fixup_directions(void);
+
+
+/* Assignments from Lua need helpers. */
+
+# define is_int_assign(cmd) (cmd==assign_int_cmd)
+# define is_dim_assign(cmd) (cmd==assign_dimen_cmd)
+# define is_toks_assign(cmd) (cmd==assign_toks_cmd)
+
+# define show_code 0 /* \.{\\show} */
+# define show_box_code 1 /* \.{\\showbox} */
+# define show_the_code 2 /* \.{\\showthe} */
+# define show_lists 3 /* \.{\\showlists} */
+# define show_groups 4 /* \.{\\showgroups} */
+# define show_tokens 5 /* \.{\\showtokens} , must be odd! */
+# define show_ifs 6 /* \.{\\showifs} */
+
+# define print_if_line(A) if ((A)!=0) { \
+ tprint(" entered on line "); print_int((A)); \
+ }
+
+extern void get_r_token(void);
+extern void assign_internal_value(int a, halfword p, int cur_val);
+extern void trap_zero_glue(void);
+extern void do_register_command(int a);
+extern void alter_aux(void);
+extern void alter_prev_graf(void);
+extern void alter_page_so_far(void);
+extern void alter_integer(void);
+extern void alter_box_dimen(void);
+extern void new_interaction(void);
+extern halfword after_token;
+extern void do_assignments(void);
+extern void open_or_close_in(void);
+extern boolean long_help_seen;
+extern void issue_message(void);
+extern void give_err_help(void);
+extern void shift_case(void);
+extern void show_whatever(void);
+
+extern void initialize(void); /* this procedure gets things started properly */
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
new file mode 100644
index 00000000000..4e49ea88578
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
@@ -0,0 +1,3610 @@
+% maincontrol.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: maincontrol.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/maincontrol.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define explicit 1
+#define acc_kern 2
+#define lp_code_base 2
+#define rp_code_base 3
+#define ef_code_base 4
+#define tag_code 5
+#define auto_kern explicit
+#define no_lig_code 6
+
+
+#define prev_depth cur_list.prev_depth_field
+#define space_factor cur_list.space_factor_field
+#define par_shape_ptr equiv(par_shape_loc)
+
+#define cur_lang int_par(cur_lang_code)
+#define global_defs int_par(global_defs_code)
+#define output_box int_par(output_box_code)
+#define end_line_char int_par(end_line_char_code)
+#define new_line_char int_par(new_line_char_code)
+#define tracing_online int_par(tracing_online_code)
+#define no_local_whatsits int_par(no_local_whatsits_code)
+#define no_local_dirs int_par(no_local_dirs_code)
+#define err_help equiv(err_help_loc)
+#define text_direction int_par(text_direction_code)
+#define every_par equiv(every_par_loc)
+#define pdf_ignored_dimen dimen_par(pdf_ignored_dimen_code)
+#define par_direction int_par(par_direction_code)
+
+#define pdf_first_line_height dimen_par(pdf_first_line_height_code)
+#define pdf_last_line_depth dimen_par(pdf_last_line_depth_code)
+#define pdf_each_line_height dimen_par(pdf_each_line_height_code)
+#define pdf_each_line_depth dimen_par(pdf_each_line_depth_code)
+#define page_left_offset dimen_par(page_left_offset_code)
+#define page_top_offset dimen_par(page_top_offset_code)
+#define page_right_offset dimen_par(page_right_offset_code)
+#define page_bottom_offset dimen_par(page_bottom_offset_code)
+#define pdf_h_origin dimen_par(pdf_h_origin_code)
+#define pdf_v_origin dimen_par(pdf_v_origin_code)
+#define pdf_px_dimen dimen_par(pdf_px_dimen_code)
+
+#define pdf_image_resolution int_par(pdf_image_resolution_code)
+#define escape_char int_par(escape_char_code)
+#define max_dead_cycles int_par(max_dead_cycles_code)
+#define tolerance int_par(tolerance_code)
+#define mag int_par(mag_code)
+#define cat_code_table int_par(cat_code_table_code)
+
+#define par_indent dimen_par(par_indent_code)
+#define looseness int_par(looseness_code)
+#define space_skip glue_par(space_skip_code)
+#define xspace_skip glue_par(xspace_skip_code)
+#define every_vbox equiv(every_vbox_loc)
+
+#define split_top_skip glue_par(split_top_skip_code)
+#define split_max_depth dimen_par(split_max_depth_code)
+
+#define hang_indent dimen_par(hang_indent_code)
+#define hang_after int_par(hang_after_code)
+#define inter_line_penalties_ptr equiv(inter_line_penalties_loc)
+
+#define box(A) eqtb[box_base+(A)].hh.rh
+#define cur_font equiv(cur_font_loc)
+#define hsize dimen_par(hsize_code)
+#define ex_hyphen_char int_par(ex_hyphen_char_code)
+#define floating_penalty int_par(floating_penalty_code)
+
+#define mode cur_list.mode_field
+#define tail cur_list.tail_field
+#define head cur_list.head_field
+#define prev_graf cur_list.pg_field
+#define dir_save cur_list.dirs_field
+
+#define check_filter(A) if (!output_active) lua_node_filter_s(buildpage_filter_callback,(A))
+
+#define var_code 7 /* math code meaning ``use the current family'' */
+
+@ We come now to the |main_control| routine, which contains the master
+switch that causes all the various pieces of \TeX\ to do their things,
+in the right order.
+
+In a sense, this is the grand climax of the program: It applies all the
+tools that we have worked so hard to construct. In another sense, this is
+the messiest part of the program: It necessarily refers to other pieces
+of code all over the place, so that a person can't fully understand what is
+going on without paging back and forth to be reminded of conventions that
+are defined elsewhere. We are now at the hub of the web, the central nervous
+system that touches most of the other parts and ties them together.
+@^brain@>
+
+The structure of |main_control| itself is quite simple. There's a label
+called |big_switch|, at which point the next token of input is fetched
+using |get_x_token|. Then the program branches at high speed into one of
+about 100 possible directions, based on the value of the current
+mode and the newly fetched command code; the sum |abs(mode)+cur_cmd|
+indicates what to do next. For example, the case `|vmode+letter|' arises
+when a letter occurs in vertical mode (or internal vertical mode); this
+case leads to instructions that initialize a new paragraph and enter
+horizontal mode.
+
+The big |case| statement that contains this multiway switch has been labeled
+|reswitch|, so that the program can |goto reswitch| when the next token
+has already been fetched. Most of the cases are quite short; they call
+an ``action procedure'' that does the work for that case, and then they
+either |goto reswitch| or they ``fall through'' to the end of the |case|
+statement, which returns control back to |big_switch|. Thus, |main_control|
+is not an extremely large procedure, in spite of the multiplicity of things
+it must do; it is small enough to be handled by PASCAL compilers that put
+severe restrictions on procedure size.
+@!@^action procedure@>
+
+One case is singled out for special treatment, because it accounts for most
+of \TeX's activities in typical applications. The process of reading simple
+text and converting it into |char_node| records, while looking for ligatures
+and kerns, is part of \TeX's ``inner loop''; the whole program runs
+efficiently when its inner loop is fast, so this part has been written
+with particular care.
+
+@c
+static halfword main_p; /* temporary register for list manipulation */
+static halfword main_s; /* space factor value */
+
+
+@ We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we
+set it equal to |sf_code(cur_chr)|, except that it should never change
+from a value less than 1000 to a value exceeding 1000. The most common
+case is |sf_code(cur_chr)=1000|, so we want that case to be fast.
+
+@c
+void adjust_space_factor(void)
+{
+ main_s = get_sf_code(cur_chr);
+ if (main_s == 1000) {
+ space_factor = 1000;
+ } else if (main_s < 1000) {
+ if (main_s > 0)
+ space_factor = main_s;
+ } else if (space_factor < 1000) {
+ space_factor = 1000;
+ } else {
+ space_factor = main_s;
+ }
+}
+
+
+@ From Knuth: ``Having |font_glue| allocated for each text font saves
+both time and memory.'' That may be true, but it also punches through
+the API wall for fonts, so I removed that -- Taco. But a bit of caching
+is very welcome, which is why I need to have the next two globals:
+
+@c
+internal_font_number space_spec_font;
+halfword space_spec_cache;
+
+@ for mode-independent commands, the following macros is useful:
+
+@c
+#define any_mode(A) vmode+(A): case hmode+(A): case mmode+(A)
+
+
+@ There is a list of cases where the user has probably gotten into or out of math
+mode by mistake. \TeX\ will insert a dollar sign and rescan the current token.
+
+@c
+#define non_math(A) vmode+(A): case hmode+(A)
+
+@ @c
+void main_control(void)
+{ /* governs \TeX's activities */
+ int t; /* general-purpose temporary variable */
+ halfword p; /* for whatsit nodes and testing whether an auto kern should be inserted */
+ int chr_stack; /* to temporarily save an |cur_chr| to be appended */
+ mathcodeval mval; /* to build up an argument to |set_math_char| */
+ t = 0; /* for -Wall */
+ chr_stack = -1;
+ if (equiv(every_job_loc) != null)
+ begin_token_list(equiv(every_job_loc), every_job_text);
+
+ BIG_SWITCH:
+ get_x_token();
+
+ RESWITCH:
+ /* Give diagnostic information, if requested */
+ /* When a new token has just been fetched at |big_switch|, we have an
+ ideal place to monitor \TeX's activity. */
+ if (interrupt != 0) {
+ if (OK_to_interrupt) {
+ back_input();
+ check_interrupt();
+ goto BIG_SWITCH;
+ }
+ }
+ if (int_par(tracing_commands_code) > 0)
+ show_cur_cmd_chr();
+
+ switch (abs(mode) + cur_cmd) {
+ case hmode + letter_cmd:
+ case hmode + other_char_cmd:
+ case hmode + char_given_cmd:
+ case hmode + char_num_cmd:
+ if (abs(mode) + cur_cmd == hmode + char_num_cmd) {
+ scan_char_num();
+ cur_chr = cur_val;
+ }
+ if (is_last_ocp(current_ocp_lstack, current_ocp_no)) {
+ /* Append character |cur_chr| and the following characters (if~any)
+ to the current hlist in the current font; |goto reswitch| when
+ a non-character has been fetched */
+ CONTINUE:
+ adjust_space_factor();
+ chr_stack = cur_chr;
+ tail_append(new_char(cur_font, chr_stack));
+ get_x_token();
+ if ((cur_cmd == letter_cmd) || (cur_cmd == other_char_cmd) ||
+ (cur_cmd == char_given_cmd) || (cur_cmd == char_num_cmd)) {
+ if (cur_cmd == char_num_cmd) {
+ scan_char_num();
+ cur_chr = cur_val;
+ }
+ if ((chr_stack == ex_hyphen_char) && (cur_chr != ex_hyphen_char)
+ && (mode > 0)) {
+ tail = compound_word_break(tail, cur_lang);
+ subtype(tail) = automatic_disc;
+ }
+ goto CONTINUE;
+ } else {
+ if ((chr_stack == ex_hyphen_char) && (mode > 0)) {
+ tail = compound_word_break(tail, cur_lang);
+ subtype(tail) = automatic_disc;
+ }
+ chr_stack = -1;
+ goto RESWITCH;
+ }
+
+ } else {
+ /* Create a buffer with character |cur_chr| and the following
+ characters (if~any) and then apply the current active OCP filter
+ to this buffer */
+ run_ocp();
+ goto BIG_SWITCH;
+
+ }
+ break;
+ case hmode + spacer_cmd:
+ case hmode + ex_space_cmd:
+ case mmode + ex_space_cmd:
+ if ((abs(mode) + cur_cmd == hmode + spacer_cmd)
+ && (!(space_factor == 1000))) {
+ app_space();
+ } else {
+ /* Append a normal inter-word space to the current list */
+ /* The occurrence of blank spaces is almost part of \TeX's inner loop,
+ since we usually encounter about one space for every five non-blank characters.
+ Therefore |main_control| gives second-highest priority to ordinary spaces.
+
+ When a glue parameter like \.{\\spaceskip} is set to `\.{0pt}', we will
+ see to it later that the corresponding glue specification is precisely
+ |zero_glue|, not merely a pointer to some specification that happens
+ to be full of zeroes. Therefore it is simple to test whether a glue parameter
+ is zero or~not.
+ */
+ if (space_skip == zero_glue) {
+ /* Find the glue specification, |main_p|, for
+ text spaces in the current font */
+ if (cur_font != space_spec_font) {
+ if (space_spec_cache != zero_glue)
+ delete_glue_ref(space_spec_cache);
+ space_spec_cache = new_spec(zero_glue);
+ width(space_spec_cache) = space(cur_font);
+ stretch(space_spec_cache) = space_stretch(cur_font);
+ shrink(space_spec_cache) = space_shrink(cur_font);
+ space_spec_font = cur_font;
+ }
+ main_p = space_spec_cache;
+
+ temp_ptr = new_glue(main_p);
+ } else {
+ temp_ptr = new_param_glue(space_skip_code);
+ }
+ vlink(tail) = temp_ptr;
+ tail = temp_ptr;
+
+ }
+ break;
+
+ case hmode + no_boundary_cmd:
+ /* Append a |cancel_boundary_node| */
+ new_whatsit(cancel_boundary_node);
+ break;
+ case hmode + char_ghost_cmd:
+ t = cur_chr;
+ get_x_token();
+ if ((cur_cmd == letter_cmd) || (cur_cmd == other_char_cmd)
+ || (cur_cmd == char_given_cmd) || (cur_cmd == char_num_cmd)) {
+ p = new_glyph(get_cur_font(), cur_chr);
+ if (t == 0) {
+ set_is_leftghost(p);
+ } else {
+ set_is_rightghost(p);
+ }
+ tail_append(p);
+ }
+ break;
+ /* Cases of |main_control| that are not part of the inner loop */
+ case any_mode(relax_cmd):
+ case vmode + spacer_cmd:
+ case mmode + spacer_cmd:
+ case mmode + no_boundary_cmd:
+ break;
+ case any_mode(ignore_spaces_cmd):
+ if (cur_chr == 0) {
+ /* Get the next non-blank non-call... */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ goto RESWITCH;
+ } else {
+ t = scanner_status;
+ scanner_status = normal;
+ get_token_lua();
+ scanner_status = t;
+ cur_cs = prim_lookup(cs_text(cur_cs));
+ if (cur_cs != undefined_primitive) {
+ cur_cmd = get_prim_eq_type(cur_cs);
+ cur_chr = get_prim_equiv(cur_cs);
+ cur_tok = (cur_cmd * STRING_OFFSET) + cur_chr;
+ goto RESWITCH;
+ }
+ }
+ break;
+ case vmode + stop_cmd:
+ if (its_all_over())
+ return; /* this is the only way out */
+ break;
+ /* Math cases in non-math modes */
+ case vmode + math_char_num_cmd:
+ case vmode + math_given_cmd:
+ case vmode + omath_given_cmd:
+ case vmode + xmath_given_cmd:
+ back_input();
+ new_graf(true);
+ break;
+ case hmode + math_char_num_cmd:
+ if (cur_chr == 0)
+ mval = scan_mathchar(tex_mathcode);
+ else if (cur_chr == 1)
+ mval = scan_mathchar(aleph_mathcode);
+ else if (cur_chr == 2)
+ mval = scan_mathchar(xetex_mathcode);
+ else
+ mval = scan_mathchar(xetexnum_mathcode);
+ math_char_in_text(mval);
+ break;
+ case hmode + math_given_cmd:
+ mval = mathchar_from_integer(cur_chr, tex_mathcode);
+ math_char_in_text(mval);
+ break;
+ case hmode + omath_given_cmd:
+ mval = mathchar_from_integer(cur_chr, aleph_mathcode);
+ math_char_in_text(mval);
+ break;
+ case hmode + xmath_given_cmd:
+ mval = mathchar_from_integer(cur_chr, xetex_mathcode);
+ math_char_in_text(mval);
+ break;
+
+ /* Forbidden cases detected in |main_control| */
+ case vmode + vmove_cmd:
+ case hmode + hmove_cmd:
+ case mmode + hmove_cmd:
+ case any_mode(last_item_cmd):
+ case vmode + vadjust_cmd:
+ case vmode + ital_corr_cmd:
+ case non_math(eq_no_cmd):
+ case any_mode(mac_param_cmd):
+ /* When erroneous situations arise, \TeX\ usually issues an error message
+ specific to the particular error. For example, `\.{\\noalign}' should
+ not appear in any mode, since it is recognized by the |align_peek| routine
+ in all of its legitimate appearances; a special error message is given
+ when `\.{\\noalign}' occurs elsewhere. But sometimes the most appropriate
+ error message is simply that the user is not allowed to do what he or she
+ has attempted. For example, `\.{\\moveleft}' is allowed only in vertical mode,
+ and `\.{\\lower}' only in non-vertical modes. Such cases are enumerated
+ here and in the other sections referred to under `See also \dots.'
+ */
+ report_illegal_case();
+ break;
+
+ /* Math-only cases in non-math modes, or vice versa */
+ case non_math(sup_mark_cmd):
+ case non_math(sub_mark_cmd):
+ case non_math(super_sub_script_cmd):
+ case non_math(math_comp_cmd):
+ case non_math(delim_num_cmd):
+ case non_math(left_right_cmd):
+ case non_math(above_cmd):
+ case non_math(radical_cmd):
+ case non_math(math_style_cmd):
+ case non_math(math_choice_cmd):
+ case non_math(vcenter_cmd):
+ case non_math(non_script_cmd):
+ case non_math(mkern_cmd):
+ case non_math(limit_switch_cmd):
+ case non_math(mskip_cmd):
+ case non_math(math_accent_cmd):
+ case mmode + endv_cmd:
+ case mmode + par_end_cmd:
+ case mmode + stop_cmd:
+ case mmode + vskip_cmd:
+ case mmode + un_vbox_cmd:
+ case mmode + valign_cmd:
+ case mmode + hrule_cmd:
+ insert_dollar_sign();
+ break;
+ /* Cases of |main_control| that build boxes and lists */
+ case vmode + hrule_cmd:
+ case hmode + vrule_cmd:
+ case mmode + vrule_cmd:
+ /* The most important parts of |main_control| are concerned with \TeX's
+ chief mission of box-making. We need to control the activities that put
+ entries on vlists and hlists, as well as the activities that convert
+ those lists into boxes. All of the necessary machinery has already been
+ developed; it remains for us to ``push the buttons'' at the right times.
+
+ As an introduction to these routines, let's consider one of the simplest
+ cases: What happens when `\.{\\hrule}' occurs in vertical mode, or
+ `\.{\\vrule}' in horizontal mode or math mode? The code in |main_control|
+ 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:=pdf_ignored_dimen|.
+ */
+ tail_append(scan_rule_spec());
+ if (abs(mode) == vmode)
+ prev_depth = pdf_ignored_dimen;
+ else if (abs(mode) == hmode)
+ space_factor = 1000;
+ break;
+
+ case vmode + vskip_cmd:
+ case hmode + hskip_cmd:
+ case mmode + hskip_cmd:
+ case mmode + mskip_cmd:
+ /* The processing of things like \.{\\hskip} and \.{\\vskip} is slightly
+ more complicated. But the code in |main_control| is very short, since
+ it simply calls on the action routine |append_glue|. Similarly, \.{\\kern}
+ activates |append_kern|. */
+ append_glue();
+ break;
+ case any_mode(kern_cmd):
+ case mmode + mkern_cmd:
+ append_kern();
+ break;
+
+ case non_math(left_brace_cmd):
+ /* Many of the actions related to box-making are triggered by the appearance
+ of braces in the input. For example, when the user says `\.{\\hbox}
+ \.{to} \.{100pt\{$\langle\,\hbox{hlist}\,\rangle$\}}' in vertical mode,
+ the information about the box size (100pt, |exactly|) is put onto |save_stack|
+ with a level boundary word just above it, and |cur_group:=adjusted_hbox_group|;
+ \TeX\ enters restricted horizontal mode to process the hlist. The right
+ brace eventually causes |save_stack| to be restored to its former state,
+ at which time the information about the box size (100pt, |exactly|) is
+ available once again; a box is packaged and we leave restricted horizontal
+ mode, appending the new box to the current list of the enclosing mode
+ (in this case to the current list of vertical mode), followed by any
+ vertical adjustments that were removed from the box by |hpack|.
+
+ The next few sections of the program are therefore concerned with the
+ treatment of left and right curly braces.
+
+ If a left brace occurs in the middle of a page or paragraph, it simply
+ introduces a new level of grouping, and the matching right brace will not have
+ such a drastic effect. Such grouping affects neither the mode nor the
+ current list. */
+ new_save_level(simple_group);
+ eq_word_define(int_base + no_local_whatsits_code, 0);
+ eq_word_define(int_base + no_local_dirs_code, 0);
+ break;
+ case any_mode(begin_group_cmd):
+ new_save_level(semi_simple_group);
+ eq_word_define(int_base + no_local_whatsits_code, 0);
+ eq_word_define(int_base + no_local_dirs_code, 0);
+ break;
+ case any_mode(end_group_cmd):
+ if (cur_group == semi_simple_group) {
+ fixup_directions();
+ } else {
+ off_save();
+ }
+ break;
+ case any_mode(right_brace_cmd):
+ handle_right_brace();
+ break;
+
+ case vmode + hmove_cmd:
+ case hmode + vmove_cmd:
+ case mmode + vmove_cmd:
+ /* 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|.
+ */
+ t = cur_chr;
+ scan_normal_dimen();
+ if (t == 0)
+ scan_box(cur_val);
+ else
+ scan_box(-cur_val);
+ break;
+ case any_mode(leader_ship_cmd):
+ scan_box(leader_flag - a_leaders + cur_chr);
+ break;
+ case any_mode(make_box_cmd):
+ begin_box(0);
+ break;
+ case any_mode(assign_box_dir_cmd):
+ scan_register_num();
+ cur_box = box(cur_val);
+ scan_optional_equals();
+ scan_direction();
+ if (cur_box != null)
+ box_dir(cur_box) = cur_val;
+ break;
+
+ case vmode + start_par_cmd:
+ /* There is a really small patch to add a new primitive called
+ \.{\\quitvmode}. In vertical modes, it is identical to \.{\\indent},
+ but in horizontal and math modes it is really a no-op (as opposed to
+ \.{\\indent}, which executes the |indent_in_hmode| procedure).
+ */
+ /* A paragraph begins when horizontal-mode material occurs in vertical mode,
+ or when the paragraph is explicitly started by `\.{\\quitvmode}',
+ `\.{\\indent}' or `\.{\\noindent}'.
+ */
+ new_graf((cur_chr > 0));
+ break;
+ case hmode + start_par_cmd:
+ case mmode + start_par_cmd:
+ if (cur_chr != 2)
+ indent_in_hmode();
+ break;
+ case vmode + letter_cmd:
+ case vmode + other_char_cmd:
+ case vmode + char_num_cmd:
+ case vmode + char_given_cmd:
+ case vmode + char_ghost_cmd:
+ case vmode + math_shift_cmd:
+ case vmode + math_shift_cs_cmd:
+ case vmode + un_hbox_cmd:
+ case vmode + vrule_cmd:
+ case vmode + accent_cmd:
+ case vmode + discretionary_cmd:
+ case vmode + hskip_cmd:
+ case vmode + valign_cmd:
+ case vmode + ex_space_cmd:
+ case vmode + no_boundary_cmd:
+ back_input();
+ new_graf(true);
+ break;
+
+ case vmode + par_end_cmd:
+ /* A paragraph ends when a |par_end| command is sensed, or when we are in
+ horizontal mode when reaching the right brace of vertical-mode routines
+ like \.{\\vbox}, \.{\\insert}, or \.{\\output}. */
+ normal_paragraph();
+ if (mode > 0) {
+ check_filter("vmode_par");
+ build_page();
+ }
+ break;
+ case hmode + par_end_cmd:
+ if (align_state < 0)
+ off_save(); /* this tries to recover from an alignment that didn't end properly */
+ end_graf(bottom_level); /* this takes us to the enclosing mode, if |mode>0| */
+ if (mode == vmode) {
+ check_filter("hmode_par");
+ build_page();
+ }
+ break;
+ case hmode + stop_cmd:
+ case hmode + vskip_cmd:
+ case hmode + hrule_cmd:
+ case hmode + un_vbox_cmd:
+ case hmode + halign_cmd:
+ head_for_vmode();
+ break;
+ case any_mode(insert_cmd):
+ case hmode + vadjust_cmd:
+ case mmode + vadjust_cmd:
+ /* Insertion and adjustment and mark nodes are constructed by the following
+ pieces of the program. */
+ begin_insert_or_adjust();
+ break;
+ case any_mode(mark_cmd):
+ handle_mark();
+ break;
+ case any_mode(break_penalty_cmd):
+ /* Penalty nodes get into a list via the |break_penalty| command. */
+ append_penalty();
+ break;
+ case any_mode(remove_item_cmd):
+ /* The |remove_item| command removes a penalty, kern, or glue node if it
+ appears at the tail of the current list, using a brute-force linear scan.
+ Like \.{\\lastbox}, this command is not allowed in vertical mode (except
+ internal vertical mode), since the current list in vertical mode is sent
+ to the page builder. But if we happen to be able to implement it in
+ vertical mode, we do. */
+ delete_last();
+ break;
+ case vmode + un_vbox_cmd:
+ case hmode + un_hbox_cmd:
+ case mmode + un_hbox_cmd:
+ /* The |un_hbox| and |un_vbox| commands unwrap one of the |number_regs|
+ current boxes. */
+ unpackage();
+ break;
+ case hmode + ital_corr_cmd:
+ /* Italic corrections are converted to kern nodes when the |ital_corr| command
+ follows a character. In math mode the same effect is achieved by appending
+ a kern of zero here, since italic corrections are supplied later. */
+ append_italic_correction();
+ break;
+ case mmode + ital_corr_cmd:
+ tail_append(new_kern(0));
+ break;
+ case hmode + discretionary_cmd:
+ case mmode + discretionary_cmd:
+ append_discretionary();
+ break;
+ case any_mode(assign_local_box_cmd):
+ append_local_box(cur_chr);
+ break;
+ case hmode + accent_cmd:
+ /* We need only one more thing to complete the horizontal mode routines, namely
+ the \.{\\accent} primitive. */
+ make_accent();
+ break;
+ case any_mode(car_ret_cmd):
+ case any_mode(tab_mark_cmd):
+ align_error();
+ break;
+ case any_mode(no_align_cmd):
+ no_align_error();
+ break;
+ case any_mode(omit_cmd):
+ omit_error();
+ break;
+ case vmode + halign_cmd:
+ case hmode + valign_cmd:
+ init_align();
+ break;
+ case mmode + halign_cmd:
+ if (privileged()) {
+ if (cur_group == math_shift_group)
+ init_align();
+ else
+ off_save();
+ }
+ break;
+ case vmode + endv_cmd:
+ case hmode + endv_cmd:
+ do_endv();
+ break;
+ case any_mode(end_cs_name_cmd):
+ cs_error();
+ break;
+ case hmode + math_shift_cmd:
+ case hmode + math_shift_cs_cmd:
+ init_math();
+ break;
+ case mmode + eq_no_cmd:
+ if (privileged()) {
+ if (cur_group == math_shift_group)
+ start_eq_no();
+ else
+ off_save();
+ }
+ break;
+ case mmode + left_brace_cmd:
+ math_left_brace();
+ break;
+ case mmode + letter_cmd:
+ case mmode + other_char_cmd:
+ case mmode + char_given_cmd:
+ set_math_char(get_math_code(cur_chr));
+ break;
+ case mmode + char_num_cmd:
+ scan_char_num();
+ cur_chr = cur_val;
+ set_math_char(get_math_code(cur_chr));
+ break;
+ case mmode + math_char_num_cmd:
+ if (cur_chr == 0)
+ mval = scan_mathchar(tex_mathcode);
+ else if (cur_chr == 1)
+ mval = scan_mathchar(aleph_mathcode);
+ else if (cur_chr == 2)
+ mval = scan_mathchar(xetex_mathcode);
+ else
+ mval = scan_mathchar(xetexnum_mathcode);
+ set_math_char(mval);
+ break;
+ case mmode + math_given_cmd:
+ mval = mathchar_from_integer(cur_chr, tex_mathcode);
+ set_math_char(mval);
+ break;
+ case mmode + omath_given_cmd:
+ mval = mathchar_from_integer(cur_chr, aleph_mathcode);
+ set_math_char(mval);
+ break;
+ case mmode + xmath_given_cmd:
+ mval = mathchar_from_integer(cur_chr, xetex_mathcode);
+ set_math_char(mval);
+ break;
+ case mmode + delim_num_cmd:
+ if (cur_chr == 0)
+ mval = scan_delimiter_as_mathchar(tex_mathcode);
+ else if (cur_chr == 1)
+ mval = scan_delimiter_as_mathchar(aleph_mathcode);
+ else
+ mval = scan_delimiter_as_mathchar(xetex_mathcode);
+ set_math_char(mval);
+ break;
+ case mmode + math_comp_cmd:
+ math_math_comp();
+ break;
+ case mmode + limit_switch_cmd:
+ math_limit_switch();
+ break;
+ case mmode + radical_cmd:
+ math_radical();
+ break;
+ case mmode + accent_cmd:
+ case mmode + math_accent_cmd:
+ math_ac();
+ break;
+ case mmode + vcenter_cmd:
+ scan_spec(vcenter_group);
+ normal_paragraph();
+ push_nest();
+ mode = -vmode;
+ prev_depth = pdf_ignored_dimen;
+ if (every_vbox != null)
+ begin_token_list(every_vbox, every_vbox_text);
+ break;
+ case mmode + math_style_cmd:
+ tail_append(new_style((small_number) cur_chr));
+ break;
+ case mmode + non_script_cmd:
+ tail_append(new_glue(zero_glue));
+ subtype(tail) = cond_math_glue;
+ break;
+ case mmode + math_choice_cmd:
+ if (cur_chr == 0)
+ append_choices();
+ else
+ setup_math_style();
+ break;
+ case mmode + above_cmd:
+ math_fraction();
+ break;
+ case mmode + sub_mark_cmd:
+ case mmode + sup_mark_cmd:
+ case mmode + super_sub_script_cmd:
+ sub_sup();
+ break;
+ case mmode + left_right_cmd:
+ math_left_right();
+ break;
+ case mmode + math_shift_cmd:
+ case mmode + math_shift_cs_cmd:
+ if (cur_group == math_shift_group)
+ after_math();
+ else
+ off_save();
+ break;
+
+ /* Cases of |main_control| that do not depend on |mode| */
+ /*
+ The long |main_control| procedure has now been fully specified, except for
+ certain activities that are independent of the current mode. These activities
+ do not change the current vlist or hlist or mlist; if they change anything,
+ it is the value of a parameter or the meaning of a control sequence.
+ */
+ case any_mode(toks_register_cmd):
+ case any_mode(assign_toks_cmd):
+ case any_mode(assign_int_cmd):
+ case any_mode(assign_attr_cmd):
+ case any_mode(assign_dir_cmd):
+ case any_mode(assign_dimen_cmd):
+ case any_mode(assign_glue_cmd):
+ case any_mode(assign_mu_glue_cmd):
+ case any_mode(assign_font_dimen_cmd):
+ case any_mode(assign_font_int_cmd):
+ case any_mode(set_aux_cmd):
+ case any_mode(set_prev_graf_cmd):
+ case any_mode(set_page_dimen_cmd):
+ case any_mode(set_page_int_cmd):
+ case any_mode(set_box_dimen_cmd):
+ case any_mode(set_tex_shape_cmd):
+ case any_mode(set_etex_shape_cmd):
+ case any_mode(def_char_code_cmd):
+ case any_mode(def_del_code_cmd):
+ case any_mode(extdef_math_code_cmd):
+ case any_mode(extdef_del_code_cmd):
+ case any_mode(def_family_cmd):
+ case any_mode(set_math_param_cmd):
+ case any_mode(set_font_cmd):
+ case any_mode(def_font_cmd):
+ case any_mode(letterspace_font_cmd):
+ case any_mode(pdf_copy_font_cmd):
+ case any_mode(register_cmd):
+ case any_mode(advance_cmd):
+ case any_mode(multiply_cmd):
+ case any_mode(divide_cmd):
+ case any_mode(prefix_cmd):
+ case any_mode(let_cmd):
+ case any_mode(shorthand_def_cmd):
+ case any_mode(read_to_cs_cmd):
+ case any_mode(def_cmd):
+ case any_mode(set_box_cmd):
+ case any_mode(hyph_data_cmd):
+ case any_mode(set_interaction_cmd):
+ case any_mode(set_ocp_cmd):
+ case any_mode(def_ocp_cmd):
+ case any_mode(set_ocp_list_cmd):
+ case any_mode(def_ocp_list_cmd):
+ case any_mode(clear_ocp_lists_cmd):
+ case any_mode(push_ocp_list_cmd):
+ case any_mode(pop_ocp_list_cmd):
+ case any_mode(ocp_list_op_cmd):
+ case any_mode(ocp_trace_level_cmd):
+ prefixed_command();
+ break;
+ case any_mode(after_assignment_cmd):
+ get_token();
+ after_token = cur_tok;
+ break;
+ case any_mode(after_group_cmd):
+ get_token();
+ save_for_after(cur_tok);
+ break;
+ case any_mode(in_stream_cmd):
+ open_or_close_in();
+ break;
+ case any_mode(message_cmd):
+ issue_message();
+ break;
+ case any_mode(case_shift_cmd):
+ shift_case();
+ break;
+ case any_mode(xray_cmd):
+ show_whatever();
+ break;
+
+ /* Cases of |main_control| that are for extensions to \TeX */
+ case any_mode(extension_cmd):
+ do_extension(static_pdf);
+ break;
+ } /* end of the big |switch| statement */
+
+ goto BIG_SWITCH; /* restart */
+}
+
+@ @c
+void app_space(void)
+{ /* handle spaces when |space_factor<>1000| */
+ halfword q; /* glue node */
+ if ((space_factor >= 2000) && (xspace_skip != zero_glue)) {
+ q = new_param_glue(xspace_skip_code);
+ } else {
+ if (space_skip != zero_glue) {
+ main_p = new_spec(space_skip);
+ } else {
+ main_p = new_spec(zero_glue);
+ width(main_p) = space(cur_font);
+ stretch(main_p) = space_stretch(cur_font);
+ shrink(main_p) = space_shrink(cur_font);
+ }
+ /* Modify the glue specification in |main_p| according to the space factor */
+ if (space_factor >= 2000)
+ width(main_p) = width(main_p) + extra_space(cur_font);
+ stretch(main_p) = xn_over_d(stretch(main_p), space_factor, 1000);
+ shrink(main_p) = xn_over_d(shrink(main_p), 1000, space_factor);
+
+ q = new_glue(main_p);
+ glue_ref_count(main_p) = null;
+ }
+ couple_nodes(tail, q);
+ tail = q;
+}
+
+@ @c
+void insert_dollar_sign(void)
+{
+ back_input();
+ cur_tok = math_shift_token + '$';
+ print_err("Missing $ inserted");
+ help2("I've inserted a begin-math/end-math symbol since I think",
+ "you left one out. Proceed, with fingers crossed.");
+ ins_error();
+}
+
+
+@ The `|you_cant|' procedure prints a line saying that the current command
+is illegal in the current mode; it identifies these things symbolically.
+
+@c
+void you_cant(void)
+{
+ print_err("You can't use `");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ print_in_mode(mode);
+}
+
+void report_illegal_case(void)
+{
+ you_cant();
+ help4("Sorry, but I'm not programmed to handle this case;",
+ "I'll just pretend that you didn''t ask for it.",
+ "If you're in the wrong mode, you might be able to",
+ "return to the right one by typing `I}' or `I$' or `I\\par'.");
+ error();
+}
+
+
+@ Some operations are allowed only in privileged modes, i.e., in cases
+that |mode>0|. The |privileged| function is used to detect violations
+of this rule; it issues an error message and returns |false| if the
+current |mode| is negative.
+
+@c
+boolean privileged(void)
+{
+ if (mode > 0) {
+ return true;
+ } else {
+ report_illegal_case();
+ return false;
+ }
+}
+
+
+@ 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
+might even say `\.{\\gdef\\end\{...\}}', to prolong the life of the job.)
+Therefore |its_all_over| is |true| only when the current page
+and contribution list are empty, and when the last output was not a
+``dead cycle.''
+
+@c
+boolean its_all_over(void)
+{ /* do this when \.{\\end} or \.{\\dump} occurs */
+ if (privileged()) {
+ if ((page_head == page_tail) && (head == tail) && (dead_cycles == 0)) {
+ return true;
+ }
+ back_input(); /* we will try to end again after ejecting residual material */
+ tail_append(new_null_box());
+ width(tail) = hsize;
+ tail_append(new_glue(fill_glue));
+ tail_append(new_penalty(-010000000000));
+ lua_node_filter_s(buildpage_filter_callback, "end");
+ build_page(); /* append \.{\\hbox to \\hsize\{\}\\vfill\\penalty-'10000000000} */
+ }
+ return false;
+}
+
+
+@ The |hskip| and |vskip| command codes are used for control sequences
+like \.{\\hss} and \.{\\vfil} as well as for \.{\\hskip} and \.{\\vskip}.
+The difference is in the value of |cur_chr|.
+
+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.
+
+@c
+void append_glue(void)
+{
+ int s; /* modifier of skip command */
+ s = cur_chr;
+ switch (s) {
+ case fil_code:
+ cur_val = fil_glue;
+ break;
+ case fill_code:
+ cur_val = fill_glue;
+ break;
+ case ss_code:
+ cur_val = ss_glue;
+ break;
+ case fil_neg_code:
+ cur_val = fil_neg_glue;
+ break;
+ case skip_code:
+ scan_glue(glue_val_level);
+ break;
+ case mskip_code:
+ scan_glue(mu_val_level);
+ break;
+ } /* now |cur_val| points to the glue specification */
+ tail_append(new_glue(cur_val));
+ if (s >= skip_code) {
+ decr(glue_ref_count(cur_val));
+ if (s > skip_code)
+ subtype(tail) = mu_glue;
+ }
+}
+
+@ @c
+void append_kern(void)
+{
+ int s; /* |subtype| of the kern node */
+ s = cur_chr;
+ scan_dimen((s == mu_glue), false, false);
+ tail_append(new_kern(cur_val));
+ subtype(tail) = (quarterword) s;
+}
+
+
+@ We have to deal with errors in which braces and such things are not
+properly nested. Sometimes the user makes an error of commission by
+inserting an extra symbol, but sometimes the user makes an error of omission.
+\TeX\ can't always tell one from the other, so it makes a guess and tries
+to avoid getting into a loop.
+
+The |off_save| routine is called when the current group code is wrong. It tries
+to insert something into the user's input that will help clean off
+the top level.
+
+@c
+void off_save(void)
+{
+ halfword p, q; /* inserted token */
+ if (cur_group == bottom_level) {
+ /* Drop current token and complain that it was unmatched */
+ print_err("Extra ");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ help1("Things are pretty mixed up, but I think the worst is over.");
+ error();
+
+ } else {
+ back_input();
+ p = get_avail();
+ set_token_link(temp_token_head, p);
+ print_err("Missing ");
+ /* Prepare to insert a token that matches |cur_group|, and print what it is */
+ /* At this point, |link(temp_token_head)=p|, a pointer to an empty one-word node. */
+ switch (cur_group) {
+ case semi_simple_group:
+ set_token_info(p, cs_token_flag + frozen_end_group);
+ tprint_esc("endgroup");
+ break;
+ case math_shift_group:
+ set_token_info(p, math_shift_token + '$');
+ print_char('$');
+ break;
+ case math_left_group:
+ set_token_info(p, cs_token_flag + frozen_right);
+ q = get_avail();
+ set_token_link(p, q);
+ p = token_link(p);
+ set_token_info(p, other_token + '.');
+ tprint_esc("right.");
+ break;
+ default:
+ set_token_info(p, right_brace_token + '}');
+ print_char('}');
+ break;
+ }
+
+ tprint(" inserted");
+ ins_list(token_link(temp_token_head));
+ help5("I've inserted something that you may have forgotten.",
+ "(See the <inserted text> above.)",
+ "With luck, this will get me unwedged. But if you",
+ "really didn't forget anything, try typing `2' now; then",
+ "my insertion and my current dilemma will both disappear.");
+ error();
+ }
+}
+
+
+@ The routine for a |right_brace| character branches into many subcases,
+since a variety of things may happen, depending on |cur_group|. Some
+types of groups are not supposed to be ended by a right brace; error
+messages are given in hopes of pinpointing the problem. Most branches
+of this routine will be filled in later, when we are ready to understand
+them; meanwhile, we must prepare ourselves to deal with such errors.
+
+@c
+void handle_right_brace(void)
+{
+ halfword p, q; /* for short-term use */
+ scaled d; /* holds |split_max_depth| in |insert_group| */
+ int f; /* holds |floating_penalty| in |insert_group| */
+ p = null;
+ switch (cur_group) {
+ case simple_group:
+ fixup_directions();
+ break;
+ case bottom_level:
+ print_err("Too many }'s");
+ help2("You've closed more groups than you opened.",
+ "Such booboos are generally harmless, so keep going.");
+ error();
+ break;
+ case semi_simple_group:
+ case math_shift_group:
+ case math_left_group:
+ extra_right_brace();
+ break;
+ case hbox_group:
+ /* When the right brace occurs at the end of an \.{\\hbox} or \.{\\vbox} or
+ \.{\\vtop} construction, the |package| routine comes into action. We might
+ also have to finish a paragraph that hasn't ended. */
+ package(0);
+ break;
+ case adjusted_hbox_group:
+ adjust_tail = adjust_head;
+ pre_adjust_tail = pre_adjust_head;
+ package(0);
+ break;
+ case vbox_group:
+ end_graf(vbox_group);
+ package(0);
+ break;
+ case vtop_group:
+ end_graf(vtop_group);
+ package(vtop_code);
+ break;
+ case insert_group:
+ end_graf(insert_group);
+ q = split_top_skip;
+ add_glue_ref(q);
+ d = split_max_depth;
+ f = floating_penalty;
+ unsave();
+ save_ptr--;
+ /* now |saved_value(0)| is the insertion number, or the |vadjust| subtype */
+ p = vpack(vlink(head), 0, additional, -1);
+ pop_nest();
+ if (saved_type(0) == saved_insert) {
+ tail_append(new_node(ins_node, saved_value(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;
+ } else if (saved_type(0) == saved_adjust) {
+ tail_append(new_node(adjust_node, saved_value(0)));
+ adjust_ptr(tail) = list_ptr(p);
+ delete_glue_ref(q);
+ } else {
+ confusion("insert_group");
+ }
+ list_ptr(p) = null;
+ flush_node(p);
+ if (nest_ptr == 0) {
+ check_filter("insert");
+ build_page();
+ }
+ break;
+ case output_group:
+ /* this is needed in case the \.{\\output} executes a \.{\\textdir} command. */
+ if (dir_level(text_dir_ptr) == cur_level) {
+ /* DIR: Remove from |text_dir_ptr| */
+ halfword text_dir_tmp = vlink(text_dir_ptr);
+ flush_node(text_dir_ptr);
+ text_dir_ptr = text_dir_tmp;
+ }
+ resume_after_output();
+ break;
+ case disc_group:
+ build_discretionary();
+ break;
+ case local_box_group:
+ build_local_box();
+ break;
+ case align_group:
+ back_input();
+ cur_tok = cs_token_flag + frozen_cr;
+ print_err("Missing \\cr inserted");
+ help1("I'm guessing that you meant to end an alignment here.");
+ ins_error();
+ break;
+ case no_align_group:
+ end_graf(no_align_group);
+ unsave();
+ align_peek();
+ break;
+ case vcenter_group:
+ end_graf(vcenter_group);
+ finish_vcenter();
+ break;
+ case math_choice_group:
+ build_choices();
+ break;
+ case math_group:
+ close_math_group(p);
+ break;
+ default:
+ confusion("rightbrace");
+ break;
+ }
+}
+
+@ @c
+void extra_right_brace(void)
+{
+ print_err("Extra }, or forgotten ");
+ switch (cur_group) {
+ case semi_simple_group:
+ tprint_esc("endgroup");
+ break;
+ case math_shift_group:
+ print_char('$');
+ break;
+ case math_left_group:
+ tprint_esc("right");
+ break;
+ }
+ help5("I've deleted a group-closing symbol because it seems to be",
+ "spurious, as in `$x}$'. But perhaps the } is legitimate and",
+ "you forgot something else, as in `\\hbox{$x}'. In such cases",
+ "the way to recover is to insert both the forgotten and the",
+ "deleted material, e.g., by typing `I$}'.");
+ error();
+ incr(align_state);
+}
+
+
+@ Here is where we clear the parameters that are supposed to revert to their
+default values after every paragraph and when internal vertical mode is entered.
+
+@c
+void normal_paragraph(void)
+{
+ if (looseness != 0)
+ eq_word_define(int_base + looseness_code, 0);
+ if (hang_indent != 0)
+ eq_word_define(dimen_base + hang_indent_code, 0);
+ if (hang_after != 1)
+ eq_word_define(int_base + hang_after_code, 1);
+ if (par_shape_ptr != null)
+ eq_define(par_shape_loc, shape_ref_cmd, null);
+ if (inter_line_penalties_ptr != null)
+ eq_define(inter_line_penalties_loc, shape_ref_cmd, null);
+}
+
+
+@ The global variable |cur_box| will point to a newly-made box. If the box
+is void, we will have |cur_box=null|. Otherwise we will have
+|type(cur_box)=hlist_node| or |vlist_node| or |rule_node|; the |rule_node|
+case can occur only with leaders.
+
+@c
+halfword cur_box; /* box to be placed into its context */
+
+
+@ The |box_end| procedure does the right thing with |cur_box|, if
+|box_context| represents the context as explained above.
+
+@c
+void box_end(int box_context)
+{
+ if (box_context < box_flag) {
+ /* Append box |cur_box| to the current list, shifted by |box_context| */
+ /*
+ The global variable |adjust_tail| will be non-null if and only if the
+ current box might include adjustments that should be appended to the
+ current vertical list.
+ */
+ if (cur_box != null) {
+ shift_amount(cur_box) = box_context;
+ if (abs(mode) == vmode) {
+ if (pre_adjust_tail != null) {
+ if (pre_adjust_head != pre_adjust_tail)
+ append_list(pre_adjust_head, pre_adjust_tail);
+ pre_adjust_tail = null;
+ }
+ append_to_vlist(cur_box);
+ if (adjust_tail != null) {
+ if (adjust_head != adjust_tail)
+ append_list(adjust_head, adjust_tail);
+ adjust_tail = null;
+ }
+ if (mode > 0) {
+ check_filter("box");
+ build_page();
+ }
+ } else {
+ if (abs(mode) == hmode)
+ space_factor = 1000;
+ else
+ cur_box = new_sub_box(cur_box);
+ vlink(tail) = cur_box;
+ tail = cur_box;
+ }
+ }
+
+ } else if (box_context < ship_out_flag) {
+ /* Store |cur_box| in a box register */
+ if (box_context < global_box_flag)
+ eq_define(box_base + box_context - box_flag, box_ref_cmd, cur_box);
+ else
+ geq_define(box_base + box_context - global_box_flag, box_ref_cmd,
+ cur_box);
+
+ } else if (cur_box != null) {
+ if (box_context > ship_out_flag) {
+ /* Append a new leader node that uses |cur_box| */
+ /* Get the next non-blank non-relax... */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ if (((cur_cmd == hskip_cmd) && (abs(mode) != vmode)) ||
+ ((cur_cmd == vskip_cmd) && (abs(mode) == vmode))) {
+ append_glue();
+ subtype(tail) =
+ (quarterword) (box_context - (leader_flag - a_leaders));
+ leader_ptr(tail) = cur_box;
+ } else {
+ print_err("Leaders not followed by proper glue");
+ help3
+ ("You should say `\\leaders <box or rule><hskip or vskip>'.",
+ "I found the <box or rule>, but there's no suitable",
+ "<hskip or vskip>, so I'm ignoring these leaders.");
+ back_error();
+ flush_node_list(cur_box);
+ }
+
+ } else
+ ship_out(static_pdf, cur_box, true);
+ }
+}
+
+@ the next input should specify a box or perhaps a rule
+
+@c
+void scan_box(int box_context)
+{
+ /* Get the next non-blank non-relax... */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ if (cur_cmd == make_box_cmd) {
+ begin_box(box_context);
+ } else if ((box_context >= leader_flag)
+ && ((cur_cmd == hrule_cmd) || (cur_cmd == vrule_cmd))) {
+ cur_box = scan_rule_spec();
+ box_end(box_context);
+ } else {
+ print_err("A <box> was supposed to be here");
+ help3("I was expecting to see \\hbox or \\vbox or \\copy or \\box or",
+ "something like that. So you might find something missing in",
+ "your output. But keep trying; you can fix this later.");
+ back_error();
+ }
+}
+
+@ @c
+void new_graf(boolean indented)
+{
+ halfword p, q, dir_graf_tmp;
+ halfword dir_rover;
+ prev_graf = 0;
+ if ((mode == vmode) || (head != tail)) {
+ tail_append(new_param_glue(par_skip_code));
+ }
+ push_nest();
+ mode = hmode;
+ space_factor = 1000;
+ /* LOCAL: Add local paragraph node */
+ tail_append(make_local_par_node());
+
+ if (indented) {
+ p = new_null_box();
+ box_dir(p) = par_direction;
+ width(p) = par_indent;
+ q = tail;
+ tail_append(p);
+ } else {
+ q = tail;
+ }
+ dir_rover = text_dir_ptr;
+ while (dir_rover != null) {
+ if ((vlink(dir_rover) != null) || (dir_dir(dir_rover) != par_direction)) {
+ dir_graf_tmp = new_dir(dir_dir(dir_rover));
+ vlink(dir_graf_tmp) = vlink(q);
+ vlink(q) = dir_graf_tmp;
+ }
+ dir_rover = vlink(dir_rover);
+ }
+ q = head;
+ while (vlink(q) != null)
+ q = vlink(q);
+ tail = q;
+ if (every_par != null)
+ begin_token_list(every_par, every_par_text);
+ if (nest_ptr == 1) {
+ check_filter("new_graf");
+ build_page(); /* put |par_skip| glue on current page */
+ }
+}
+
+@ @c
+void indent_in_hmode(void)
+{
+ halfword p;
+ if (cur_chr > 0) { /* \.{\\indent} */
+ p = new_null_box();
+ width(p) = par_indent;
+ if (abs(mode) == hmode)
+ space_factor = 1000;
+ else
+ p = new_sub_box(p);
+ tail_append(p);
+ }
+}
+
+@ @c
+void head_for_vmode(void)
+{
+ if (mode < 0) {
+ if (cur_cmd != hrule_cmd) {
+ off_save();
+ } else {
+ print_err("You can't use `\\hrule' here except with leaders");
+ help2("To put a horizontal rule in an hbox or an alignment,",
+ "you should use \\leaders or \\hrulefill (see The TeXbook).");
+ error();
+ }
+ } else {
+ back_input();
+ cur_tok = par_token;
+ back_input();
+ token_type = inserted;
+ }
+}
+
+
+@ TODO (BUG?): |dir_save| would have been set by |line_break| by means
+of |post_line_break|, but this is not done right now, as it introduces
+pretty heavy memory leaks. This means the current code is probably
+wrong in some way that relates to in-paragraph displays.
+
+@c
+void end_graf(int line_break_context)
+{
+ if (mode == hmode) {
+ if ((head == tail) || (vlink(head) == tail)) {
+ if (vlink(head) == tail)
+ flush_node(vlink(head));
+ pop_nest(); /* null paragraphs are ignored, all contain a |local_paragraph| node */
+ } else {
+ line_break(false, line_break_context);
+ }
+ if (dir_save != null) {
+ flush_node_list(dir_save);
+ dir_save = null;
+ }
+ normal_paragraph();
+ error_count = 0;
+ }
+}
+
+
+@ @c
+void begin_insert_or_adjust(void)
+{
+ if (cur_cmd != vadjust_cmd) {
+ scan_register_num();
+ if (cur_val == output_box) {
+ print_err("You can't \\insert");
+ print_int(output_box);
+ help1("I'm changing to \\insert0; box \\outputbox is special.");
+ error();
+ cur_val = 0;
+ }
+ set_saved_record(0, saved_insert, 0, cur_val);
+ } else if (scan_keyword("pre")) {
+ set_saved_record(0, saved_adjust, 0, 1);
+ } else {
+ set_saved_record(0, saved_adjust, 0, 0);
+ }
+ save_ptr++;
+ new_save_level(insert_group);
+ scan_left_brace();
+ normal_paragraph();
+ push_nest();
+ mode = -vmode;
+ prev_depth = pdf_ignored_dimen;
+}
+
+
+@ I (TH)'ve renamed the |make_mark| procedure to this, because if the
+current chr code is 1, then the actual command was \.{\\clearmarks},
+which does not generate a mark node but instead destroys the current
+mark tokenlists.
+
+@c
+void handle_mark(void)
+{
+ halfword p; /* new node */
+ halfword c; /* the mark class */
+ if (cur_chr == clear_marks_code) {
+ scan_mark_num();
+ c = cur_val;
+ delete_top_mark(c);
+ delete_bot_mark(c);
+ delete_first_mark(c);
+ delete_split_first_mark(c);
+ delete_split_bot_mark(c);
+ } else {
+ if (cur_chr == 0) {
+ c = 0;
+ } else {
+ scan_mark_num();
+ c = cur_val;
+ if (c > biggest_used_mark)
+ biggest_used_mark = c;
+ }
+ p = scan_toks(false, true);
+ p = new_node(mark_node, 0); /* the |subtype| is not used */
+ mark_class(p) = c;
+ mark_ptr(p) = def_ref;
+ couple_nodes(tail, p);
+ tail = p;
+ }
+}
+
+
+@ @c
+void append_penalty(void)
+{
+ scan_int();
+ tail_append(new_penalty(cur_val));
+ if (mode == vmode) {
+ check_filter("penalty");
+ build_page();
+ }
+}
+
+
+@ When |delete_last| is called, |cur_chr| is the |type| of node that
+will be deleted, if present.
+
+@c
+void delete_last(void)
+{
+ halfword p, q; /* run through the current list */
+ if ((mode == vmode) && (tail == head)) {
+ /* Apologize for inability to do the operation now,
+ unless \.{\\unskip} follows non-glue */
+ if ((cur_chr != glue_node) || (last_glue != max_halfword)) {
+ you_cant();
+ if (cur_chr == kern_node) {
+ help2
+ ("Sorry...I usually can't take things from the current page.",
+ "Try `I\\kern-\\lastkern' instead.");
+ } else if (cur_chr != glue_node) {
+ help2
+ ("Sorry...I usually can't take things from the current page.",
+ "Perhaps you can make the output routine do it.");
+ } else {
+ help2
+ ("Sorry...I usually can't take things from the current page.",
+ "Try `I\\vskip-\\lastskip' instead.");
+ }
+ error();
+ }
+
+ } else {
+ /* todo: clean this up */
+ if (!is_char_node(tail)) {
+ if (type(tail) == cur_chr) {
+ q = head;
+ do {
+ p = q;
+ if (!is_char_node(q)) {
+ if (type(q) == disc_node) {
+ if (p == tail)
+ return;
+ }
+ }
+ q = vlink(p);
+ } while (q != tail);
+ vlink(p) = null;
+ flush_node_list(tail);
+ tail = p;
+ }
+ }
+ }
+}
+
+@ @c
+void unpackage(void)
+{
+ halfword p; /* the box */
+ halfword r; /* to remove marginal kern nodes */
+ int c; /* should we copy? */
+ halfword s; /* for varmem assignment */
+ if (cur_chr > copy_code) {
+ /* Handle saved items and |goto done| */
+ vlink(tail) = disc_ptr[cur_chr];
+ disc_ptr[cur_chr] = null;
+ goto DONE;
+ }
+ c = cur_chr;
+ scan_register_num();
+ p = box(cur_val);
+ if (p == null)
+ return;
+ if ((abs(mode) == mmode)
+ || ((abs(mode) == vmode) && (type(p) != vlist_node))
+ || ((abs(mode) == hmode) && (type(p) != hlist_node))) {
+ print_err("Incompatible list can't be unboxed");
+ help3("Sorry, Pandora. (You sneaky devil.)",
+ "I refuse to unbox an \\hbox in vertical mode or vice versa.",
+ "And I can't open any boxes in math mode.");
+ error();
+ return;
+ }
+ if (c == copy_code) {
+ s = copy_node_list(list_ptr(p));
+ vlink(tail) = s;
+ } else {
+ vlink(tail) = list_ptr(p);
+ box(cur_val) = null;
+ list_ptr(p) = null;
+ flush_node(p);
+ }
+ DONE:
+ while (vlink(tail) != null) {
+ r = vlink(tail);
+ if (!is_char_node(r) && (type(r) == margin_kern_node)) {
+ vlink(tail) = vlink(r);
+ flush_node(r);
+ }
+ tail = vlink(tail);
+ }
+}
+
+@ @c
+void append_italic_correction(void)
+{
+ halfword p; /* |char_node| at the tail of the current list */
+ internal_font_number f; /* the font in the |char_node| */
+ if (tail != head) {
+ if (is_char_node(tail))
+ p = tail;
+ else
+ return;
+ f = font(p);
+ tail_append(new_kern(char_italic(f, character(p))));
+ subtype(tail) = explicit;
+ }
+}
+
+
+@ @c
+void append_local_box(int kind)
+{
+ incr(save_ptr);
+ set_saved_record(-1, saved_boxtype, 0, kind);
+ new_save_level(local_box_group);
+ scan_left_brace();
+ push_nest();
+ mode = -hmode;
+ space_factor = 1000;
+}
+
+
+@ Discretionary nodes are easy in the common case `\.{\\-}', but in the
+general case we must process three braces full of items.
+
+The space factor does not change when we append a discretionary node,
+but it starts out as 1000 in the subsidiary lists.
+
+@c
+void append_discretionary(void)
+{
+ int c;
+ tail_append(new_disc());
+ subtype(tail) = (quarterword) cur_chr;
+ if (cur_chr == explicit_disc) {
+ c = get_pre_hyphen_char(cur_lang);
+ if (c != 0) {
+ vlink(pre_break(tail)) = new_char(equiv(cur_font_loc), c);
+ alink(vlink(pre_break(tail))) = pre_break(tail);
+ tlink(pre_break(tail)) = vlink(pre_break(tail));
+ }
+ c = get_post_hyphen_char(cur_lang);
+ if (c != 0) {
+ vlink(post_break(tail)) = new_char(equiv(cur_font_loc), c);
+ alink(vlink(post_break(tail))) = post_break(tail);
+ tlink(post_break(tail)) = vlink(post_break(tail));
+ }
+ } else {
+ incr(save_ptr);
+ set_saved_record(-1, saved_disc, 0, 0);
+ new_save_level(disc_group);
+ scan_left_brace();
+ push_nest();
+ mode = -hmode;
+ space_factor = 1000;
+ }
+}
+
+@ The test for |p != null| ensures that empty \.{\\localleftbox} and
+ \.{\\localrightbox} commands are not applied.
+
+@c
+void build_local_box(void)
+{
+ halfword p;
+ int kind;
+ unsave();
+ assert(saved_type(-1) == saved_boxtype);
+ kind = saved_value(-1);
+ decr(save_ptr);
+ p = vlink(head);
+ pop_nest();
+ if (p != null)
+ p = hpack(p, 0, additional, -1);
+ if (kind == 0)
+ eq_define(local_left_box_base, box_ref_cmd, p);
+ else
+ eq_define(local_right_box_base, box_ref_cmd, p);
+ if (abs(mode) == hmode) {
+ /* LOCAL: Add local paragraph node */
+ tail_append(make_local_par_node());
+ }
+ eq_word_define(int_base + no_local_whatsits_code, no_local_whatsits + 1);
+}
+
+
+@ The three discretionary lists are constructed somewhat as if they were
+hboxes. A~subroutine called |build_discretionary| handles the transitions.
+(This is sort of fun.)
+
+@c
+void build_discretionary(void)
+{
+ halfword p, q; /* for link manipulation */
+ int n; /* length of discretionary list */
+ unsave();
+ /* Prune the current list, if necessary, until it contains only
+ |char_node|, |kern_node|, |hlist_node|, |vlist_node| and
+ |rule_node| items; set |n| to the length of the list,
+ and set |q| to the lists tail */
+ /* During this loop, |p=vlink(q)| and there are |n| items preceding |p|. */
+ q = head;
+ p = vlink(q);
+ n = 0;
+ while (p != null) {
+ if (!is_char_node(p) && type(p) > rule_node && type(p) != kern_node) {
+ print_err("Improper discretionary list");
+ help1("Discretionary lists must contain only boxes and kerns.");
+ error();
+ begin_diagnostic();
+ tprint_nl("The following discretionary sublist has been deleted:");
+ show_box(p);
+ end_diagnostic(true);
+ flush_node_list(p);
+ vlink(q) = null;
+ break;
+ }
+ alink(p) = q;
+ q = p;
+ p = vlink(q);
+ incr(n);
+ }
+
+ p = vlink(head);
+ pop_nest();
+ assert(saved_type(-1) == saved_disc);
+ switch (saved_value(-1)) {
+ case 0:
+ if (n > 0) {
+ vlink(pre_break(tail)) = p;
+ alink(p) = pre_break(tail);
+ tlink(pre_break(tail)) = q;
+ }
+ break;
+ case 1:
+ if (n > 0) {
+ vlink(post_break(tail)) = p;
+ alink(p) = post_break(tail);
+ tlink(post_break(tail)) = q;
+ }
+ break;
+ case 2:
+ /* Attach list |p| to the current list, and record its length;
+ then finish up and |return| */
+ if ((n > 0) && (abs(mode) == mmode)) {
+ print_err("Illegal math \\discretionary");
+ help2("Sorry: The third part of a discretionary break must be",
+ "empty, in math formulas. I had to delete your third part.");
+ flush_node_list(p);
+ error();
+ } else {
+ if (n > 0) {
+ vlink(no_break(tail)) = p;
+ alink(p) = no_break(tail);
+ tlink(no_break(tail)) = q;
+ }
+ }
+ decr(save_ptr);
+ return;
+ break;
+ } /* there are no other cases */
+ set_saved_record(-1, saved_disc, 0, (saved_value(-1) + 1));
+ new_save_level(disc_group);
+ scan_left_brace();
+ push_nest();
+ mode = -hmode;
+ space_factor = 1000;
+}
+
+
+@ The positioning of accents is straightforward but tedious. Given an accent
+of width |a|, designed for characters of height |x| and slant |s|;
+and given a character of width |w|, height |h|, and slant |t|: We will shift
+the accent down by |x-h|, and we will insert kern nodes that have the effect of
+centering the accent over the character and shifting the accent to the
+right by $\delta={1\over2}(w-a)+h\cdot t-x\cdot s$. If either character is
+absent from the font, we will simply use the other, without shifting.
+
+@c
+void make_accent(void)
+{
+ double s, t; /* amount of slant */
+ halfword p, q, r; /* character, box, and kern nodes */
+ internal_font_number f; /* relevant font */
+ scaled a, h, x, w, delta; /* heights and widths, as explained above */
+ scan_char_num();
+ f = equiv(cur_font_loc);
+ p = new_glyph(f, cur_val);
+ if (p != null) {
+ x = x_height(f);
+ s = float_cast(slant(f)) / float_constant(65536); /* real division */
+ a = glyph_width(p);
+ do_assignments();
+ /* Create a character node |q| for the next character,
+ but set |q:=null| if problems arise */
+ q = null;
+ f = equiv(cur_font_loc);
+ if ((cur_cmd == letter_cmd) ||
+ (cur_cmd == other_char_cmd) || (cur_cmd == char_given_cmd)) {
+ q = new_glyph(f, cur_chr);
+ } else if (cur_cmd == char_num_cmd) {
+ scan_char_num();
+ q = new_glyph(f, cur_val);
+ } else {
+ back_input();
+ }
+
+ if (q != null) {
+ /* Append the accent with appropriate kerns, then set |p:=q| */
+ /* The kern nodes appended here must be distinguished from other kerns, lest
+ they be wiped away by the hyphenation algorithm or by a previous line break.
+
+ The two kerns are computed with (machine-dependent) |real| arithmetic, but
+ their sum is machine-independent; the net effect is machine-independent,
+ because the user cannot remove these nodes nor access them via \.{\\lastkern}.
+ */
+ t = float_cast(slant(f)) / float_constant(65536); /* real division */
+ w = glyph_width(q);
+ h = glyph_height(q);
+ if (h != x) { /* the accent must be shifted up or down */
+ p = hpack(p, 0, additional, -1);
+ shift_amount(p) = x - h;
+ }
+ delta = round(float_cast(w - a) / float_constant(2) + h * t - x * s); /* real multiplication */
+ r = new_kern(delta);
+ subtype(r) = acc_kern;
+ couple_nodes(tail, r);
+ couple_nodes(r, p);
+ tail = new_kern(-a - delta);
+ subtype(tail) = acc_kern;
+ couple_nodes(p, tail);
+ p = q;
+
+ }
+ couple_nodes(tail, p);
+ tail = p;
+ space_factor = 1000;
+ }
+}
+
+
+@ When `\.{\\cr}' or `\.{\\span}' or a tab mark comes through the scanner
+into |main_control|, it might be that the user has foolishly inserted
+one of them into something that has nothing to do with alignment. But it is
+far more likely that a left brace or right brace has been omitted, since
+|get_next| takes actions appropriate to alignment only when `\.{\\cr}'
+or `\.{\\span}' or tab marks occur with |align_state=0|. The following
+program attempts to make an appropriate recovery.
+
+@c
+void align_error(void)
+{
+ if (abs(align_state) > 2) {
+ /* Express consternation over the fact that no alignment is in progress */
+ print_err("Misplaced ");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ if (cur_tok == tab_token + '&') {
+ help6("I can't figure out why you would want to use a tab mark",
+ "here. If you just want an ampersand, the remedy is",
+ "simple: Just type `I\\&' now. But if some right brace",
+ "up above has ended a previous alignment prematurely,",
+ "you're probably due for more error messages, and you",
+ "might try typing `S' now just to see what is salvageable.");
+ } else {
+ help5("I can't figure out why you would want to use a tab mark",
+ "or \\cr or \\span just now. If something like a right brace",
+ "up above has ended a previous alignment prematurely,",
+ "you're probably due for more error messages, and you",
+ "might try typing `S' now just to see what is salvageable.");
+ }
+ error();
+
+ } else {
+ back_input();
+ if (align_state < 0) {
+ print_err("Missing { inserted");
+ incr(align_state);
+ cur_tok = left_brace_token + '{';
+ } else {
+ print_err("Missing } inserted");
+ decr(align_state);
+ cur_tok = right_brace_token + '}';
+ }
+ help3("I've put in what seems to be necessary to fix",
+ "the current column of the current alignment.",
+ "Try to go on, since this might almost work.");
+ ins_error();
+ }
+}
+
+
+@ The help messages here contain a little white lie, since \.{\\noalign}
+and \.{\\omit} are allowed also after `\.{\\noalign\{...\}}'.
+
+@c
+void no_align_error(void)
+{
+ print_err("Misplaced \\noalign");
+ help2("I expect to see \\noalign only after the \\cr of",
+ "an alignment. Proceed, and I'll ignore this case.");
+ error();
+}
+
+void omit_error(void)
+{
+ print_err("Misplaced \\omit");
+ help2("I expect to see \\omit only after tab marks or the \\cr of",
+ "an alignment. Proceed, and I'll ignore this case.");
+ error();
+}
+
+
+@ We've now covered most of the abuses of \.{\\halign} and \.{\\valign}.
+Let's take a look at what happens when they are used correctly.
+
+An |align_group| code is supposed to remain on the |save_stack|
+during an entire alignment, until |fin_align| removes it.
+
+A devious user might force an |endv| command to occur just about anywhere;
+we must defeat such hacks.
+
+@c
+void do_endv(void)
+{
+ base_ptr = input_ptr;
+ input_stack[base_ptr] = cur_input;
+ while ((input_stack[base_ptr].index_field != v_template) &&
+ (input_stack[base_ptr].loc_field == null) &&
+ (input_stack[base_ptr].state_field == token_list))
+ decr(base_ptr);
+ if ((input_stack[base_ptr].index_field != v_template) ||
+ (input_stack[base_ptr].loc_field != null) ||
+ (input_stack[base_ptr].state_field != token_list))
+ fatal_error("(interwoven alignment preambles are not allowed)");
+ /*.interwoven alignment preambles... */
+ if (cur_group == align_group) {
+ end_graf(align_group);
+ if (fin_col())
+ fin_row();
+ } else {
+ off_save();
+ }
+}
+
+@ Finally, \.{\\endcsname} is not supposed to get through to |main_control|.
+
+@c
+void cs_error(void)
+{
+ print_err("Extra \\endcsname");
+ help1("I'm ignoring this, since I wasn't doing a \\csname.");
+ error();
+}
+
+
+@
+ Assignments to values in |eqtb| can be global or local. Furthermore, a
+ control sequence can be defined to be `\.{\\long}', `\.{\\protected}',
+ or `\.{\\outer}', and it might or might not be expanded. The prefixes
+ `\.{\\global}', `\.{\\long}', `\.{\\protected}',
+ and `\.{\\outer}' can occur in any order. Therefore we assign binary numeric
+ codes, making it possible to accumulate the union of all specified prefixes
+ by adding the corresponding codes. (PASCAL's |set| operations could also
+ have been used.)
+
+ 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
+ the command.
+
+
+
+@ If the user says, e.g., `\.{\\global\\global}', the redundancy is
+silently accepted.
+
+
+@ The different types of code values have different legal ranges; the
+following program is careful to check each case properly.
+
+@c
+#define check_def_code(A) do { \
+ if (((cur_val<0)&&(p<(A)))||(cur_val>n)) { \
+ print_err("Invalid code ("); \
+ print_int(cur_val); \
+ if (p<(A)) \
+ tprint("), should be in the range 0.."); \
+ else \
+ tprint("), should be at most "); \
+ print_int(n); \
+ help1("I'm going to use 0 instead of that illegal code value."); \
+ error(); \
+ cur_val=0; \
+ } \
+ } while (0)
+
+
+@ @c
+void prefixed_command(void)
+{
+ int a; /* accumulated prefix codes so far */
+ internal_font_number f; /* identifies a font */
+ halfword j; /* index into a \.{\\parshape} specification */
+ halfword p, q; /* for temporary short-term use */
+ int n; /* ditto */
+ boolean e; /* should a definition be expanded? or was \.{\\let} not done? */
+ mathcodeval mval; /* for handling of \.{\\mathchardef}s */
+ a = 0;
+ while (cur_cmd == prefix_cmd) {
+ if (!odd(a / cur_chr))
+ a = a + cur_chr;
+ /* Get the next non-blank non-relax... */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ if (cur_cmd <= max_non_prefixed_command) {
+ /* Discard erroneous prefixes and |return| */
+ print_err("You can't use a prefix with `");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ print_char('\'');
+ help2
+ ("I'll pretend you didn't say \\long or \\outer or \\global or",
+ "\\protected.");
+ back_error();
+ return;
+ }
+ if (int_par(tracing_commands_code) > 2)
+ show_cur_cmd_chr();
+ }
+ /* Discard the prefixes \.{\\long} and \.{\\outer} if they are irrelevant */
+ if (a >= 8) {
+ j = protected_token;
+ a = a - 8;
+ } else {
+ j = 0;
+ }
+ if ((cur_cmd != def_cmd) && ((a % 4 != 0) || (j != 0))) {
+ print_err("You can't use `\\long' or `\\outer' with `");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ print_char('\'');
+ help1("I'll pretend you didn't say \\long or \\outer here.");
+ error();
+ }
+
+ /* Adjust for the setting of \.{\\globaldefs} */
+ if (global_defs != 0) {
+ if (global_defs < 0) {
+ if (is_global(a))
+ a = a - 4;
+ } else {
+ if (!is_global(a))
+ a = a + 4;
+ }
+ }
+ switch (cur_cmd) {
+ case set_font_cmd:
+ /* Here's an example of the way many of the following routines operate.
+ (Unfortunately, they aren't all as simple as this.) */
+ define(cur_font_loc, data_cmd, cur_chr);
+ break;
+ case def_cmd:
+ /* When a |def| command has been scanned,
+ |cur_chr| is odd if the definition is supposed to be global, and
+ |cur_chr>=2| if the definition is supposed to be expanded. */
+
+ if (odd(cur_chr) && !is_global(a) && (global_defs >= 0))
+ a = a + 4;
+ e = (cur_chr >= 2);
+ get_r_token();
+ p = cur_cs;
+ q = scan_toks(true, e);
+ if (j != 0) {
+ q = get_avail();
+ set_token_info(q, j);
+ set_token_link(q, token_link(def_ref));
+ set_token_link(def_ref, q);
+ }
+ define(p, call_cmd + (a % 4), def_ref);
+ break;
+ case let_cmd:
+ n = cur_chr;
+ get_r_token();
+ p = cur_cs;
+ if (n == normal) {
+ do {
+ get_token();
+ } while (cur_cmd == spacer_cmd);
+ if (cur_tok == other_token + '=') {
+ get_token();
+ if (cur_cmd == spacer_cmd)
+ get_token();
+ }
+ } else {
+ get_token();
+ q = cur_tok;
+ get_token();
+ back_input();
+ cur_tok = q;
+ back_input(); /* look ahead, then back up */
+ } /* note that |back_input| doesn't affect |cur_cmd|, |cur_chr| */
+ if (cur_cmd >= call_cmd)
+ add_token_ref(cur_chr);
+ define(p, cur_cmd, cur_chr);
+ break;
+ case shorthand_def_cmd:
+ /* 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
+ previous meaning. This allows, for instance, `\.{\\chardef\\foo=123\\foo}'.
+ */
+ n = cur_chr;
+ get_r_token();
+ p = cur_cs;
+ define(p, relax_cmd, too_big_char);
+ scan_optional_equals();
+ switch (n) {
+ case char_def_code:
+ scan_char_num();
+ define(p, char_given_cmd, cur_val);
+ break;
+ case math_char_def_code:
+ mval = scan_mathchar(tex_mathcode);
+ cur_val =
+ (mval.class_value * 16 + mval.family_value) * 256 +
+ mval.character_value;
+ define(p, math_given_cmd, cur_val);
+ break;
+ case omath_char_def_code:
+ mval = scan_mathchar(aleph_mathcode);
+ cur_val =
+ (mval.class_value * 256 + mval.family_value) * 65536 +
+ mval.character_value;
+ define(p, omath_given_cmd, cur_val);
+ break;
+ case xmath_char_def_code:
+ mval = scan_mathchar(xetex_mathcode);
+ cur_val =
+ (mval.class_value + (8 * mval.family_value)) * (65536 * 32) +
+ mval.character_value;
+ define(p, xmath_given_cmd, cur_val);
+ break;
+ default:
+ scan_register_num();
+ switch (n) {
+ case count_def_code:
+ define(p, assign_int_cmd, count_base + cur_val);
+ break;
+ case attribute_def_code:
+ define(p, assign_attr_cmd, attribute_base + cur_val);
+ break;
+ case dimen_def_code:
+ define(p, assign_dimen_cmd, scaled_base + cur_val);
+ break;
+ case skip_def_code:
+ define(p, assign_glue_cmd, skip_base + cur_val);
+ break;
+ case mu_skip_def_code:
+ define(p, assign_mu_glue_cmd, mu_skip_base + cur_val);
+ break;
+ case toks_def_code:
+ define(p, assign_toks_cmd, toks_base + cur_val);
+ break;
+ default:
+ confusion("shorthand_def");
+ break;
+ }
+ break;
+ }
+ break;
+ case read_to_cs_cmd:
+ j = cur_chr;
+ scan_int();
+ n = cur_val;
+ if (!scan_keyword("to")) {
+ print_err("Missing `to' inserted");
+ help2("You should have said `\\read<number> to \\cs'.",
+ "I'm going to look for the \\cs now.");
+ error();
+ }
+ get_r_token();
+ p = cur_cs;
+ read_toks(n, p, j);
+ define(p, call_cmd, cur_val);
+ break;
+ case toks_register_cmd:
+ case assign_toks_cmd:
+ /* The token-list parameters, \.{\\output} and \.{\\everypar}, etc., receive
+ their values in the following way. (For safety's sake, we place an
+ enclosing pair of braces around an \.{\\output} list.) */
+ q = cur_cs;
+ if (cur_cmd == toks_register_cmd) {
+ scan_register_num();
+ p = toks_base + cur_val;
+ } else {
+ p = cur_chr; /* |p=every_par_loc| or |output_routine_loc| or \dots */
+ }
+ scan_optional_equals();
+ /* Get the next non-blank non-relax non-call token */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ if (cur_cmd != left_brace_cmd) {
+ /* If the right-hand side is a token parameter
+ or token register, finish the assignment and |goto done| */
+ if (cur_cmd == toks_register_cmd) {
+ scan_register_num();
+ cur_cmd = assign_toks_cmd;
+ cur_chr = toks_base + cur_val;
+ }
+ if (cur_cmd == assign_toks_cmd) {
+ q = equiv(cur_chr);
+ if (q == null) {
+ define(p, undefined_cs_cmd, null);
+ } else {
+ add_token_ref(q);
+ define(p, call_cmd, q);
+ }
+ goto DONE;
+ }
+ }
+ back_input();
+ cur_cs = q;
+ q = scan_toks(false, false);
+ if (token_link(def_ref) == null) { /* empty list: revert to the default */
+ define(p, undefined_cs_cmd, null);
+ free_avail(def_ref);
+ } else {
+ if (p == output_routine_loc) { /* enclose in curlies */
+ p = get_avail();
+ set_token_link(q, p);
+ p = output_routine_loc;
+ q = token_link(q);
+ set_token_info(q, right_brace_token + '}');
+ q = get_avail();
+ set_token_info(q, left_brace_token + '{');
+ set_token_link(q, token_link(def_ref));
+ set_token_link(def_ref, q);
+ }
+ define(p, call_cmd, def_ref);
+ }
+ break;
+ case assign_int_cmd:
+ /* Similar routines are used to assign values to the numeric parameters. */
+ p = cur_chr;
+ scan_optional_equals();
+ scan_int();
+ assign_internal_value(a, p, cur_val);
+ break;
+ case assign_attr_cmd:
+ p = cur_chr;
+ scan_optional_equals();
+ scan_int();
+ if ((p - attribute_base) > max_used_attr)
+ max_used_attr = (p - attribute_base);
+ attr_list_cache = cache_disabled;
+ word_define(p, cur_val);
+ break;
+ case assign_dir_cmd:
+ /* DIR: Assign direction codes */
+ scan_direction();
+ switch (cur_chr) {
+ case int_base + page_direction_code:
+ eq_word_define(int_base + page_direction_code, cur_val);
+ break;
+ case int_base + body_direction_code:
+ eq_word_define(int_base + body_direction_code, cur_val);
+ break;
+ case int_base + par_direction_code:
+ eq_word_define(int_base + par_direction_code, cur_val);
+ break;
+ case int_base + math_direction_code:
+ eq_word_define(int_base + math_direction_code, cur_val);
+ break;
+ case int_base + text_direction_code:
+ if ((no_local_dirs > 0) && (abs(mode) == hmode)) {
+ /* DIR: Add local dir node */
+ tail_append(new_dir(text_direction));
+ }
+ update_text_dir_ptr(cur_val);
+ if (abs(mode) == hmode) {
+ /* DIR: Add local dir node */
+ tail_append(new_dir(cur_val));
+ dir_level(tail) = cur_level;
+ }
+ eq_word_define(int_base + text_direction_code, cur_val);
+ eq_word_define(int_base + no_local_dirs_code, no_local_dirs + 1);
+ break;
+ }
+ break;
+ case assign_dimen_cmd:
+ p = cur_chr;
+ scan_optional_equals();
+ scan_normal_dimen();
+ assign_internal_value(a, p, cur_val);
+ break;
+ case assign_glue_cmd:
+ case assign_mu_glue_cmd:
+ p = cur_chr;
+ n = cur_cmd;
+ scan_optional_equals();
+ if (n == assign_mu_glue_cmd)
+ scan_glue(mu_val_level);
+ else
+ scan_glue(glue_val_level);
+ trap_zero_glue();
+ define(p, glue_ref_cmd, cur_val);
+ break;
+ case def_char_code_cmd:
+ case def_del_code_cmd:
+ /* Let |n| be the largest legal code value, based on |cur_chr| */
+ if (cur_chr == cat_code_base)
+ n = max_char_code;
+ else if (cur_chr == sf_code_base)
+ n = 077777;
+ else
+ n = biggest_char;
+
+ p = cur_chr;
+ if (cur_chr == math_code_base) {
+ if (is_global(a))
+ cur_val1 = level_one;
+ else
+ cur_val1 = cur_level;
+ scan_extdef_math_code(cur_val1, tex_mathcode);
+ } else if (cur_chr == lc_code_base) {
+ scan_char_num();
+ p = cur_val;
+ scan_optional_equals();
+ scan_int();
+ check_def_code(lc_code_base);
+ define_lc_code(p, cur_val);
+ } else if (cur_chr == uc_code_base) {
+ scan_char_num();
+ p = cur_val;
+ scan_optional_equals();
+ scan_int();
+ check_def_code(uc_code_base);
+ define_uc_code(p, cur_val);
+ } else if (cur_chr == sf_code_base) {
+ scan_char_num();
+ p = cur_val;
+ scan_optional_equals();
+ scan_int();
+ check_def_code(sf_code_base);
+ define_sf_code(p, cur_val);
+ } else if (cur_chr == cat_code_base) {
+ scan_char_num();
+ p = cur_val;
+ scan_optional_equals();
+ scan_int();
+ check_def_code(cat_code_base);
+ define_cat_code(p, cur_val);
+ } else if (cur_chr == del_code_base) {
+ if (is_global(a))
+ cur_val1 = level_one;
+ else
+ cur_val1 = cur_level;
+ scan_extdef_del_code(cur_val1, tex_mathcode);
+ }
+ break;
+ case extdef_math_code_cmd:
+ case extdef_del_code_cmd:
+ if (is_global(a))
+ cur_val1 = level_one;
+ else
+ cur_val1 = cur_level;
+ if (cur_chr == math_code_base)
+ scan_extdef_math_code(cur_val1, aleph_mathcode);
+ else if (cur_chr == math_code_base + 1)
+ scan_extdef_math_code(cur_val1, xetex_mathcode);
+ else if (cur_chr == math_code_base + 2)
+ scan_extdef_math_code(cur_val1, xetexnum_mathcode);
+ else if (cur_chr == del_code_base)
+ scan_extdef_del_code(cur_val1, aleph_mathcode);
+ else if (cur_chr == del_code_base + 1)
+ scan_extdef_del_code(cur_val1, xetex_mathcode);
+ else if (cur_chr == del_code_base + 2)
+ scan_extdef_del_code(cur_val1, xetexnum_mathcode);
+ break;
+ case def_family_cmd:
+ 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);
+ break;
+ case set_math_param_cmd:
+ p = cur_chr;
+ get_token();
+ if (cur_cmd != math_style_cmd) {
+ print_err("Missing math style, treated as \\displaystyle");
+ help1
+ ("A style should have been here; I inserted `\\displaystyle'.");
+ cur_val1 = display_style;
+ back_error();
+ } else {
+ cur_val1 = cur_chr;
+ }
+ scan_optional_equals();
+ if (p < math_param_first_mu_glue) {
+ if (p == math_param_radical_degree_raise)
+ scan_int();
+ else
+ scan_dimen(false, false, false);
+ } else {
+ scan_glue(mu_val_level);
+ trap_zero_glue();
+ if (cur_val == glue_par(thin_mu_skip_code))
+ cur_val = thin_mu_skip_code;
+ else if (cur_val == glue_par(med_mu_skip_code))
+ cur_val = med_mu_skip_code;
+ else if (cur_val == glue_par(thick_mu_skip_code))
+ cur_val = thick_mu_skip_code;
+ }
+ define_math_param(p, cur_val1, cur_val);
+ break;
+ case register_cmd:
+ case advance_cmd:
+ case multiply_cmd:
+ case divide_cmd:
+ do_register_command(a);
+ break;
+ case set_box_cmd:
+ /* The processing of boxes is somewhat different, because we may need
+ to scan and create an entire box before we actually change the value
+ of the old one. */
+ scan_register_num();
+ if (is_global(a))
+ n = global_box_flag + cur_val;
+ else
+ n = box_flag + cur_val;
+ scan_optional_equals();
+ if (set_box_allowed) {
+ scan_box(n);
+ } else {
+ print_err("Improper \\setbox");
+ help2("Sorry, \\setbox is not allowed after \\halign in a display,",
+ "or between \\accent and an accented character.");
+ error();
+ }
+ break;
+ case set_aux_cmd:
+ /* The |space_factor| or |prev_depth| settings are changed when a |set_aux|
+ command is sensed. Similarly, |prev_graf| is changed in the presence of
+ |set_prev_graf|, and |dead_cycles| or |insert_penalties| in the presence of
+ |set_page_int|. These definitions are always global. */
+ alter_aux();
+ break;
+ case set_prev_graf_cmd:
+ alter_prev_graf();
+ break;
+ case set_page_dimen_cmd:
+ alter_page_so_far();
+ break;
+ case set_page_int_cmd:
+ alter_integer();
+ break;
+ case set_box_dimen_cmd:
+ /* When some dimension of a box register is changed, the change isn't exactly
+ global; but \TeX\ does not look at the \.{\\global} switch. */
+ alter_box_dimen();
+ break;
+ case set_tex_shape_cmd:
+ q = cur_chr;
+ scan_optional_equals();
+ scan_int();
+ n = cur_val;
+ if (n <= 0) {
+ p = null;
+ } else {
+ p = new_node(shape_node, 2 * (n + 1) + 1);
+ vinfo(p + 1) = n;
+ for (j = 1; j <= n; j++) {
+ scan_normal_dimen();
+ varmem[p + 2 * j].cint = cur_val; /* indentation */
+ scan_normal_dimen();
+ varmem[p + 2 * j + 1].cint = cur_val; /* width */
+ }
+ }
+ define(q, shape_ref_cmd, p);
+ break;
+ case set_etex_shape_cmd:
+ q = cur_chr;
+ scan_optional_equals();
+ scan_int();
+ n = cur_val;
+ if (n <= 0) {
+ p = null;
+ } else {
+ n = (cur_val / 2) + 1;
+ p = new_node(shape_node, 2 * n + 1 + 1);
+ vinfo(p + 1) = n;
+ n = cur_val;
+ varmem[p + 2].cint = n; /* number of penalties */
+ for (j = p + 3; j <= p + n + 2; j++) {
+ scan_int();
+ varmem[j].cint = cur_val; /* penalty values */
+ }
+ if (!odd(n))
+ varmem[p + n + 3].cint = 0; /* unused */
+ }
+ define(q, shape_ref_cmd, p);
+ break;
+ case hyph_data_cmd:
+ /* All of \TeX's parameters are kept in |eqtb| except the font information,
+ the interaction mode, and the hyphenation tables; these are strictly global.
+ */
+ switch (cur_chr) {
+ case 0:
+ new_hyph_exceptions();
+ break;
+ case 1:
+ new_patterns();
+ break;
+ case 2:
+ new_pre_hyphen_char();
+ break;
+ case 3:
+ new_post_hyphen_char();
+ break;
+ case 4:
+ new_pre_exhyphen_char();
+ break;
+ case 5:
+ new_post_exhyphen_char();
+ break;
+ }
+ break;
+ case assign_font_dimen_cmd:
+ set_font_dimen();
+ break;
+ case assign_font_int_cmd:
+ n = cur_chr;
+ scan_font_ident();
+ f = cur_val;
+ if (n == no_lig_code) {
+ set_no_ligatures(f);
+ } else if (n < lp_code_base) {
+ scan_optional_equals();
+ scan_int();
+ if (n == 0)
+ set_hyphen_char(f, cur_val);
+ else
+ set_skew_char(f, cur_val);
+ } else {
+ scan_char_num();
+ p = cur_val;
+ scan_optional_equals();
+ scan_int();
+ switch (n) {
+ case lp_code_base:
+ set_lp_code(f, p, cur_val);
+ break;
+ case rp_code_base:
+ set_rp_code(f, p, cur_val);
+ break;
+ case ef_code_base:
+ set_ef_code(f, p, cur_val);
+ break;
+ case tag_code:
+ set_tag_code(f, p, cur_val);
+ break;
+ }
+ }
+ break;
+ case def_font_cmd:
+ /* Here is where the information for a new font gets loaded. */
+ tex_def_font((small_number) a);
+ break;
+ case letterspace_font_cmd:
+ new_letterspaced_font((small_number) a);
+ break;
+ case pdf_copy_font_cmd:
+ make_font_copy((small_number) a);
+ break;
+ case set_interaction_cmd:
+ new_interaction();
+ break;
+ case set_ocp_cmd:
+ print_err("To use ocps, use the \\pushocplist primitive");
+ print_ln();
+ break;
+ case def_ocp_cmd:
+ new_ocp((small_number) a);
+ break;
+ case set_ocp_list_cmd:
+ print_err("To use ocp lists, use the \\pushocplist primitive");
+ print_ln();
+ break;
+ case def_ocp_list_cmd:
+ new_ocp_list((small_number) a);
+ break;
+ case push_ocp_list_cmd:
+ do_push_ocp_list((small_number) a);
+ break;
+ case pop_ocp_list_cmd:
+ do_pop_ocp_list((small_number) a);
+ break;
+ case clear_ocp_lists_cmd:
+ do_clear_ocp_lists((small_number) a);
+ break;
+ case ocp_list_op_cmd:
+ print_err("To build ocp lists, use the \\ocplist primitive");
+ print_ln();
+ break;
+ case ocp_trace_level_cmd:
+ scan_optional_equals();
+ scan_int();
+ if (cur_val != 0)
+ cur_val = 1;
+ define(ocp_trace_level_base, data_cmd, cur_val);
+ break;
+ default:
+ confusion("prefix");
+ break;
+ } /* end of Assignments cases */
+ DONE:
+ /* Insert a token saved by \.{\\afterassignment}, if any */
+ if (after_token != 0) {
+ cur_tok = after_token;
+ back_input();
+ after_token = 0;
+ }
+}
+
+@ @c
+void fixup_directions(void)
+{
+ int temp_no_whatsits;
+ int temp_no_dirs;
+ int temporary_dir;
+ temp_no_whatsits = no_local_whatsits;
+ temp_no_dirs = no_local_dirs;
+ temporary_dir = text_direction;
+ if (dir_level(text_dir_ptr) == cur_level) {
+ /* DIR: Remove from |text_dir_ptr| */
+ halfword text_dir_tmp = vlink(text_dir_ptr);
+ flush_node(text_dir_ptr);
+ text_dir_ptr = text_dir_tmp;
+
+ }
+ unsave();
+ if (abs(mode) == hmode) {
+ if (temp_no_dirs != 0) {
+ /* DIR: Add local dir node */
+ tail_append(new_dir(text_direction));
+
+ dir_dir(tail) = temporary_dir - 64;
+ }
+ if (temp_no_whatsits != 0) {
+ /* LOCAL: Add local paragraph node */
+ tail_append(make_local_par_node());
+
+ }
+ }
+}
+
+
+@ When a control sequence is to be defined, by \.{\\def} or \.{\\let} or
+something similar, the |get_r_token| routine will substitute a special
+control sequence for a token that is not redefinable.
+
+@c
+void get_r_token(void)
+{
+ RESTART:
+ do {
+ get_token();
+ } while (cur_tok == space_token);
+ if ((cur_cs == 0) || (cur_cs > eqtb_top) ||
+ ((cur_cs > frozen_control_sequence) && (cur_cs <= eqtb_size))) {
+ print_err("Missing control sequence inserted");
+ help5("Please don't say `\\def cs{...}', say `\\def\\cs{...}'.",
+ "I've inserted an inaccessible control sequence so that your",
+ "definition will be completed without mixing me up too badly.",
+ "You can recover graciously from this error, if you're",
+ "careful; see exercise 27.2 in The TeXbook.");
+ if (cur_cs == 0)
+ back_input();
+ cur_tok = cs_token_flag + frozen_protection;
+ ins_error();
+ goto RESTART;
+ }
+}
+
+@ @c
+void assign_internal_value(int a, halfword p, int cur_val)
+{
+ halfword n;
+ if ((p >= int_base) && (p < attribute_base)) {
+ switch ((p - int_base)) {
+ case cat_code_table_code:
+ if (valid_catcode_table(cur_val)) {
+ if (cur_val != int_par(cat_code_table_code))
+ word_define(p, cur_val);
+ } else {
+ 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();
+ }
+ break;
+ case output_box_code:
+ if ((cur_val > 65535) | (cur_val < 0)) {
+ print_err("Invalid \\outputbox");
+ help1
+ ("The value for \\outputbox has to be between 0 and 65535.");
+ error();
+ } else {
+ word_define(p, cur_val);
+ }
+ break;
+ case new_line_char_code:
+ if (cur_val > 127) {
+ print_err("Invalid \\newlinechar");
+ help2
+ ("The value for \\newlinechar has to be between 0 and 127.",
+ "Your invalid assignment will be ignored.");
+ error();
+ } else if (cur_val < 0) {
+ word_define(p, -1);
+ } else {
+ word_define(p, cur_val);
+ }
+ break;
+ case end_line_char_code:
+ if (cur_val < 0) {
+ word_define(p, -1);
+ } else if (cur_val > 127) {
+ print_err("Invalid \\endlinechar");
+ help2
+ ("The value for \\endlinechar has to be no higher than 127.",
+ "Your invalid assignment will be ignored.");
+ error();
+ } else {
+ word_define(p, cur_val);
+ }
+ break;
+ case pdf_compress_level_code:
+ static_pdf->compress_level = cur_val;
+ word_define(p, cur_val);
+ break;
+ case pdf_objcompresslevel_code:
+ static_pdf->objcompresslevel = cur_val;
+ word_define(p, cur_val);
+ break;
+ case language_code:
+ word_define(int_base + cur_lang_code, cur_val);
+ word_define(p, cur_val);
+ break;
+ default:
+ word_define(p, cur_val);
+ break;
+ }
+ /* 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) &&
+ ((p == (int_base + local_inter_line_penalty_code)) ||
+ (p == (int_base + local_broken_penalty_code)))) {
+ /* LOCAL: Add local paragraph node */
+ tail_append(make_local_par_node());
+
+ eq_word_define(int_base + no_local_whatsits_code,
+ no_local_whatsits + 1);
+ }
+
+ } else if ((p >= dimen_base) && (p < eqtb_size)) {
+ if (p == (dimen_base + page_left_offset_code)) {
+ n = cur_val - one_true_inch;
+ word_define(dimen_base + h_offset_code, n);
+ } else if (p == (dimen_base + h_offset_code)) {
+ n = cur_val + one_true_inch;
+ word_define(dimen_base + page_left_offset_code, n);
+ } else if (p == (dimen_base + page_top_offset_code)) {
+ n = cur_val - one_true_inch;
+ word_define(dimen_base + v_offset_code, n);
+ } else if (p == (dimen_base + v_offset_code)) {
+ n = cur_val + one_true_inch;
+ word_define(dimen_base + page_top_offset_code, n);
+ }
+ word_define(p, cur_val);
+
+ } else if ((p >= local_base) && (p < toks_base)) { /* internal locals */
+ define(p, call_cmd, cur_val);
+ } else {
+ confusion("assign internal value");
+ }
+}
+
+
+@ When a glue register or parameter becomes zero, it will always point to
+|zero_glue| because of the following procedure. (Exception: The tabskip
+glue isn't trapped while preambles are being scanned.)
+
+@c
+void trap_zero_glue(void)
+{
+ if ((width(cur_val) == 0) && (stretch(cur_val) == 0)
+ && (shrink(cur_val) == 0)) {
+ add_glue_ref(zero_glue);
+ delete_glue_ref(cur_val);
+ cur_val = zero_glue;
+ }
+}
+
+@ We use the fact that |register<advance<multiply<divide|
+
+@c
+void do_register_command(int a)
+{
+ halfword l, q, r, s; /* for list manipulation */
+ int p; /* type of register involved */
+ q = cur_cmd;
+ /* Compute the register location |l| and its type |p|; but |return| if invalid */
+ /* Here we use the fact that the consecutive codes |int_val..mu_val| and
+ |assign_int..assign_mu_glue| correspond to each other nicely. */
+ l = 0;
+ if (q != register_cmd) {
+ get_x_token();
+ if ((cur_cmd >= assign_int_cmd) && (cur_cmd <= assign_mu_glue_cmd)) {
+ l = cur_chr;
+ p = cur_cmd - assign_int_cmd;
+ goto FOUND;
+ }
+ if (cur_cmd != register_cmd) {
+ print_err("You can't use `");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ tprint("' after ");
+ print_cmd_chr((quarterword) q, 0);
+ help1("I'm forgetting what you said and not changing anything.");
+ error();
+ return;
+ }
+ }
+ p = cur_chr;
+ scan_register_num();
+ if (p == int_val_level)
+ l = cur_val + count_base;
+ else if (p == attr_val_level)
+ l = cur_val + attribute_base;
+ else if (p == dimen_val_level)
+ l = cur_val + scaled_base;
+ else if (p == glue_val_level)
+ l = cur_val + skip_base;
+ else if (p == mu_val_level)
+ l = cur_val + mu_skip_base;
+
+ FOUND:
+ if (q == register_cmd) {
+ scan_optional_equals();
+ } else if (scan_keyword("by")) {
+ ; /* optional `\.{by}' */
+ }
+ arith_error = false;
+ if (q < multiply_cmd) {
+ /* Compute result of |register| or |advance|, put it in |cur_val| */
+ if (p < glue_val_level) {
+ if ((p == int_val_level) || (p == attr_val_level))
+ scan_int();
+ else
+ scan_normal_dimen();
+ if (q == advance_cmd)
+ cur_val = cur_val + eqtb[l].cint;
+ } else {
+ scan_glue(p);
+ if (q == advance_cmd) {
+ /* Compute the sum of two glue specs */
+ q = new_spec(cur_val);
+ r = equiv(l);
+ delete_glue_ref(cur_val);
+ width(q) = width(q) + width(r);
+ if (stretch(q) == 0) {
+ stretch_order(q) = normal;
+ }
+ if (stretch_order(q) == stretch_order(r)) {
+ stretch(q) = stretch(q) + stretch(r);
+ } else if ((stretch_order(q) < stretch_order(r))
+ && (stretch(r) != 0)) {
+ stretch(q) = stretch(r);
+ stretch_order(q) = stretch_order(r);
+ }
+ if (shrink(q) == 0) {
+ shrink_order(q) = normal;
+ }
+ if (shrink_order(q) == shrink_order(r)) {
+ shrink(q) = shrink(q) + shrink(r);
+ } else if ((shrink_order(q) < shrink_order(r))
+ && (shrink(r) != 0)) {
+ shrink(q) = shrink(r);
+ shrink_order(q) = shrink_order(r);
+ }
+ cur_val = q;
+ }
+ }
+
+ } else {
+ /* Compute result of |multiply| or |divide|, put it in |cur_val| */
+ scan_int();
+ if (p < glue_val_level) {
+ if (q == multiply_cmd) {
+ if ((p == int_val_level) || (p == attr_val_level)) {
+ cur_val = mult_integers(eqtb[l].cint, cur_val);
+ } else {
+ cur_val = nx_plus_y(eqtb[l].cint, cur_val, 0);
+ }
+ } else {
+ cur_val = x_over_n(eqtb[l].cint, cur_val);
+ }
+ } else {
+ s = equiv(l);
+ r = new_spec(s);
+ if (q == multiply_cmd) {
+ width(r) = nx_plus_y(width(s), cur_val, 0);
+ stretch(r) = nx_plus_y(stretch(s), cur_val, 0);
+ shrink(r) = nx_plus_y(shrink(s), cur_val, 0);
+ } else {
+ width(r) = x_over_n(width(s), cur_val);
+ stretch(r) = x_over_n(stretch(s), cur_val);
+ shrink(r) = x_over_n(shrink(s), cur_val);
+ }
+ cur_val = r;
+ }
+
+ }
+ if (arith_error) {
+ print_err("Arithmetic overflow");
+ help2("I can't carry out that multiplication or division,",
+ "since the result is out of range.");
+ if (p >= glue_val_level)
+ delete_glue_ref(cur_val);
+ error();
+ return;
+ }
+ if (p < glue_val_level) {
+ if (p == attr_val_level) {
+ if ((l - attribute_base) > max_used_attr)
+ max_used_attr = (l - attribute_base);
+ attr_list_cache = cache_disabled;
+ }
+ if ((p == int_val_level) || (p == dimen_val_level))
+ assign_internal_value(a, l, cur_val);
+ else
+ word_define(l, cur_val);
+ } else {
+ trap_zero_glue();
+ define(l, glue_ref_cmd, cur_val);
+ }
+}
+
+
+@ @c
+void alter_aux(void)
+{
+ halfword c; /* |hmode| or |vmode| */
+ if (cur_chr != abs(mode)) {
+ report_illegal_case();
+ } else {
+ c = cur_chr;
+ scan_optional_equals();
+ if (c == vmode) {
+ scan_normal_dimen();
+ prev_depth = cur_val;
+ } else {
+ scan_int();
+ if ((cur_val <= 0) || (cur_val > 32767)) {
+ print_err("Bad space factor");
+ help1("I allow only values in the range 1..32767 here.");
+ int_error(cur_val);
+ } else {
+ space_factor = cur_val;
+ }
+ }
+ }
+}
+
+@ @c
+void alter_prev_graf(void)
+{
+ int p; /* index into |nest| */
+ p = nest_ptr;
+ while (abs(nest[p].mode_field) != vmode)
+ decr(p);
+ scan_optional_equals();
+ scan_int();
+ if (cur_val < 0) {
+ print_err("Bad \\prevgraf");
+ help1("I allow only nonnegative values here.");
+ int_error(cur_val);
+ } else {
+ nest[p].pg_field = cur_val;
+ }
+}
+
+@ @c
+void alter_page_so_far(void)
+{
+ int c; /* index into |page_so_far| */
+ c = cur_chr;
+ scan_optional_equals();
+ scan_normal_dimen();
+ page_so_far[c] = cur_val;
+}
+
+@ @c
+void alter_integer(void)
+{
+ int c; /* 0 for \.{\\deadcycles}, 1 for \.{\\insertpenalties}, etc. */
+ c = cur_chr;
+ scan_optional_equals();
+ scan_int();
+ if (c == 0) {
+ dead_cycles = cur_val;
+ } else if (c == 2) {
+ if ((cur_val < batch_mode) || (cur_val > error_stop_mode)) {
+ print_err("Bad interaction mode");
+ help2("Modes are 0=batch, 1=nonstop, 2=scroll, and",
+ "3=errorstop. Proceed, and I'll ignore this case.");
+ int_error(cur_val);
+ } else {
+ cur_chr = cur_val;
+ new_interaction();
+ }
+ } else {
+ insert_penalties = cur_val;
+ }
+}
+
+@ @c
+void alter_box_dimen(void)
+{
+ int c; /* |width_offset| or |height_offset| or |depth_offset| */
+ int b; /* box number */
+ c = cur_chr;
+ scan_register_num();
+ b = cur_val;
+ scan_optional_equals();
+ scan_normal_dimen();
+ if (box(b) != null)
+ varmem[box(b) + c].cint = cur_val;
+}
+
+
+@ @c
+void new_interaction(void)
+{
+ print_ln();
+ interaction = cur_chr;
+ if (interaction == batch_mode)
+ kpsemaketexdiscarderrors = 1;
+ else
+ kpsemaketexdiscarderrors = 0;
+ fixup_selector(log_opened);
+}
+
+
+@ The \.{\\afterassignment} command puts a token into the global
+variable |after_token|. This global variable is examined just after
+every assignment has been performed.
+
+@c
+halfword after_token; /* zero, or a saved token */
+
+
+@ Here is a procedure that might be called `Get the next non-blank non-relax
+non-call non-assignment token'.
+
+@c
+void do_assignments(void)
+{
+ while (true) {
+ /* Get the next non-blank non-relax... */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ if (cur_cmd <= max_non_prefixed_command)
+ return;
+ set_box_allowed = false;
+ prefixed_command();
+ set_box_allowed = true;
+ }
+}
+
+@ @c
+void open_or_close_in(void)
+{
+ int c; /* 1 for \.{\\openin}, 0 for \.{\\closein} */
+ int n; /* stream number */
+ char *fn;
+ c = cur_chr;
+ scan_four_bit_int();
+ n = cur_val;
+ if (read_open[n] != closed) {
+ lua_a_close_in(read_file[n], (n + 1));
+ read_open[n] = closed;
+ }
+ if (c != 0) {
+ scan_optional_equals();
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+ back_input();
+ if (cur_cmd != left_brace_cmd) {
+ scan_file_name(); /* set |cur_name| to desired file name */
+ if (cur_ext == get_nullstr())
+ cur_ext = maketexstring(".tex");
+ } else {
+ scan_file_name_toks();
+ }
+ fn = pack_file_name(cur_name, cur_area, cur_ext);
+ if (lua_a_open_in(&(read_file[n]), fn, (n + 1))) {
+ read_open[n] = just_open;
+ }
+ }
+}
+
+@ @c
+boolean long_help_seen; /* has the long \.{\\errmessage} help been used? */
+
+void issue_message(void)
+{
+ int old_setting; /* holds |selector| setting */
+ int c; /* identifies \.{\\message} and \.{\\errmessage} */
+ str_number s; /* the message */
+ c = cur_chr;
+ (void) scan_toks(false, true);
+ old_setting = selector;
+ selector = new_string;
+ token_show(def_ref);
+ selector = old_setting;
+ flush_list(def_ref);
+ str_room(1);
+ s = make_string();
+ if (c == 0) {
+ /* Print string |s| on the terminal */
+ if (term_offset + (int) str_length(s) > max_print_line - 2)
+ print_ln();
+ else if ((term_offset > 0) || (file_offset > 0))
+ print_char(' ');
+ print(s);
+ update_terminal();
+
+ } else {
+ /* Print string |s| as an error message */
+ /* If \.{\\errmessage} occurs often in |scroll_mode|, without user-defined
+ \.{\\errhelp}, we don't want to give a long help message each time. So we
+ give a verbose explanation only once. */
+ print_err("");
+ print(s);
+ if (err_help != null) {
+ use_err_help = true;
+ } else if (long_help_seen) {
+ help1("(That was another \\errmessage.)");
+ } else {
+ if (interaction < error_stop_mode)
+ long_help_seen = true;
+ help4("This error message was generated by an \\errmessage",
+ "command, so I can't give any explicit help.",
+ "Pretend that you're Hercule Poirot: Examine all clues,",
+ "and deduce the truth by order and method.");
+ }
+ error();
+ use_err_help = false;
+
+ }
+ flush_str(s);
+}
+
+
+@ The |error| routine calls on |give_err_help| if help is requested from
+the |err_help| parameter.
+
+@c
+void give_err_help(void)
+{
+ token_show(err_help);
+}
+
+
+
+@ The \.{\\uppercase} and \.{\\lowercase} commands are implemented by
+building a token list and then changing the cases of the letters in it.
+
+@c
+void shift_case(void)
+{
+ halfword b; /* |lc_code_base| or |uc_code_base| */
+ halfword p; /* runs through the token list */
+ halfword t; /* token */
+ halfword c; /* character code */
+ halfword i; /* inbetween */
+ b = cur_chr;
+ p = scan_toks(false, false);
+ p = token_link(def_ref);
+ while (p != null) {
+ /* Change the case of the token in |p|, if a change is appropriate */
+ /*
+ When the case of a |chr_code| changes, we don't change the |cmd|.
+ We also change active characters.
+ */
+ t = token_info(p);
+ if (t < cs_token_flag) {
+ c = t % STRING_OFFSET;
+ if (b == uc_code_base)
+ i = get_uc_code(c);
+ else
+ i = get_lc_code(c);
+ if (i != 0)
+ set_token_info(p, t - c + i);
+ } else if (is_active_cs(cs_text(t - cs_token_flag))) {
+ c = active_cs_value(cs_text(t - cs_token_flag));
+ if (b == uc_code_base)
+ i = get_uc_code(c);
+ else
+ i = get_lc_code(c);
+ if (i != 0)
+ set_token_info(p, active_to_cs(i, true) + cs_token_flag);
+ }
+ p = token_link(p);
+ }
+ back_list(token_link(def_ref));
+ free_avail(def_ref); /* omit reference count */
+}
+
+
+@ We come finally to the last pieces missing from |main_control|, namely the
+`\.{\\show}' commands that are useful when debugging.
+
+@c
+void show_whatever(void)
+{
+ halfword p; /* tail of a token list to show */
+ int t; /* type of conditional being shown */
+ int m; /* upper bound on |fi_or_else| codes */
+ int l; /* line where that conditional began */
+ int n; /* level of \.{\\if...\\fi} nesting */
+ switch (cur_chr) {
+ case show_lists:
+ begin_diagnostic();
+ show_activities();
+ break;
+ case show_box_code:
+ /* Show the current contents of a box */
+ scan_register_num();
+ begin_diagnostic();
+ tprint_nl("> \\box");
+ print_int(cur_val);
+ print_char('=');
+ if (box(cur_val) == null)
+ tprint("void");
+ else
+ show_box(box(cur_val));
+ break;
+ case show_code:
+ /* Show the current meaning of a token, then |goto common_ending| */
+ get_token();
+ if (interaction == error_stop_mode)
+ wake_up_terminal();
+ tprint_nl("> ");
+ if (cur_cs != 0) {
+ sprint_cs(cur_cs);
+ print_char('=');
+ }
+ print_meaning();
+ goto COMMON_ENDING;
+ break;
+ /* Cases for |show_whatever| */
+ case show_groups:
+ begin_diagnostic();
+ show_save_groups();
+ break;
+ case show_ifs:
+ begin_diagnostic();
+ tprint_nl("");
+ print_ln();
+ if (cond_ptr == null) {
+ tprint_nl("### ");
+ tprint("no active conditionals");
+ } else {
+ p = cond_ptr;
+ n = 0;
+ do {
+ incr(n);
+ p = vlink(p);
+ } while (p != null);
+ p = cond_ptr;
+ t = cur_if;
+ l = if_line;
+ m = if_limit;
+ do {
+ tprint_nl("### level ");
+ print_int(n);
+ tprint(": ");
+ print_cmd_chr(if_test_cmd, t);
+ if (m == fi_code)
+ tprint_esc("else");
+ print_if_line(l);
+ decr(n);
+ t = if_limit_subtype(p);
+ l = if_line_field(p);
+ m = if_limit_type(p);
+ p = vlink(p);
+ } while (p != null);
+ }
+ break;
+
+ default:
+ /* Show the current value of some parameter or register,
+ then |goto common_ending| */
+ p = the_toks();
+ if (interaction == error_stop_mode)
+ wake_up_terminal();
+ tprint_nl("> ");
+ token_show(temp_token_head);
+ flush_list(token_link(temp_token_head));
+ goto COMMON_ENDING;
+ break;
+ }
+ /* Complete a potentially long \.{\\show} command */
+ end_diagnostic(true);
+ print_err("OK");
+ if (selector == term_and_log) {
+ if (tracing_online <= 0) {
+ selector = term_only;
+ tprint(" (see the transcript file)");
+ selector = term_and_log;
+ }
+ }
+
+ COMMON_ENDING:
+ if (interaction < error_stop_mode) {
+ help0();
+ decr(error_count);
+ } else if (tracing_online > 0) {
+ help3("This isn't an error message; I'm just \\showing something.",
+ "Type `I\\show...' to show more (e.g., \\show\\cs,",
+ "\\showthe\\count10, \\showbox255, \\showlists).");
+ } else {
+ help5("This isn't an error message; I'm just \\showing something.",
+ "Type `I\\show...' to show more (e.g., \\show\\cs,",
+ "\\showthe\\count10, \\showbox255, \\showlists).",
+ "And type `I\\tracingonline=1\\show...' to show boxes and",
+ "lists on your terminal as well as in the transcript file.");
+ }
+ error();
+}
+
+
+@ @c
+void initialize(void)
+{ /* this procedure gets things started properly */
+ int k; /* index into |mem|, |eqtb|, etc. */
+ /* Initialize whatever \TeX\ might access */
+ /* Set initial values of key variables */
+ initialize_errors();
+ initialize_arithmetic();
+ max_used_attr = -1;
+ attr_list_cache = cache_disabled;
+ initialize_nesting();
+
+ /* Start a new current page */
+ page_contents = empty;
+ page_tail = page_head;
+#if 0
+ vlink(page_head) = null;
+#endif
+ last_glue = max_halfword;
+ last_penalty = 0;
+ last_kern = 0;
+ last_node_type = -1;
+ page_depth = 0;
+ page_max_depth = 0;
+
+ initialize_equivalents();
+ no_new_control_sequence = true; /* new identifiers are usually forbidden */
+ init_primitives();
+
+ mag_set = 0;
+ initialize_marks();
+ initialize_read();
+
+ assert(static_pdf == NULL);
+ static_pdf = init_pdf_struct(static_pdf);
+
+ format_ident = 0;
+ format_name = get_nullstr();
+ for (k = 0; k <= 17; k++)
+ write_open[k] = false;
+ initialize_directions();
+ seconds_and_micros(epochseconds, microseconds);
+ init_start_time(static_pdf);
+
+ edit_name_start = 0;
+ stop_at_space = true;
+
+ if (ini_version) {
+ /* Initialize table entries (done by \.{INITEX} only) */
+
+ init_node_mem(500);
+ initialize_tokens();
+ /* Initialize the special list heads and constant nodes */
+ initialize_alignments();
+ initialize_buildpage();
+
+ initialize_active();
+
+ set_eq_type(undefined_control_sequence, undefined_cs_cmd);
+ set_equiv(undefined_control_sequence, null);
+ set_eq_level(undefined_control_sequence, level_zero);
+ for (k = null_cs; k <= (eqtb_top - 1); k++)
+ eqtb[k] = eqtb[undefined_control_sequence];
+ set_equiv(glue_base, zero_glue);
+ set_eq_level(glue_base, level_one);
+ set_eq_type(glue_base, glue_ref_cmd);
+ for (k = glue_base + 1; k <= local_base - 1; k++)
+ eqtb[k] = eqtb[glue_base];
+ glue_ref_count(zero_glue) =
+ glue_ref_count(zero_glue) + local_base - glue_base;
+
+ par_shape_ptr = null;
+ set_eq_type(par_shape_loc, shape_ref_cmd);
+ set_eq_level(par_shape_loc, level_one);
+ for (k = etex_pen_base; k <= (etex_pens - 1); k++)
+ eqtb[k] = eqtb[par_shape_loc];
+ for (k = output_routine_loc; k <= toks_base + biggest_reg; k++)
+ eqtb[k] = eqtb[undefined_control_sequence];
+ box(0) = null;
+ set_eq_type(box_base, box_ref_cmd);
+ set_eq_level(box_base, level_one);
+ for (k = box_base + 1; k <= (box_base + biggest_reg); k++)
+ eqtb[k] = eqtb[box_base];
+ cur_font = null_font;
+ set_eq_type(cur_font_loc, data_cmd);
+ set_eq_level(cur_font_loc, level_one);
+ set_equiv(cat_code_base, 0);
+ set_eq_type(cat_code_base, data_cmd);
+ set_eq_level(cat_code_base, level_one);
+ eqtb[internal_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'; k <= '9'; k++)
+ set_math_code(k, tex_mathcode, var_code, 0, k, level_one);
+ for (k = 'A'; k <= 'Z'; k++) {
+ 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);
+ }
+ for (k = int_base; k <= attribute_base - 1; k++)
+ eqtb[k].cint = 0;
+ for (k = attribute_base; k <= del_code_base - 1; k++)
+ eqtb[k].cint = UNUSED_ATTRIBUTE;
+ mag = 1000;
+ tolerance = 10000;
+ hang_after = 1;
+ max_dead_cycles = 25;
+ escape_char = '\\';
+ end_line_char = carriage_return;
+ set_del_code('.', tex_mathcode, 0, 0, 0, 0, level_one); /* this null delimiter is used in error recovery */
+ ex_hyphen_char = '-';
+ output_box = 255;
+ for (k = dimen_base; k <= eqtb_size; k++)
+ eqtb[k].cint = 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;
+ ini_init_primitives();
+ hash_used = frozen_control_sequence; /* nothing is used */
+ hash_high = 0;
+ cs_count = 0;
+ set_eq_type(frozen_dont_expand, dont_expand_cmd);
+ cs_text(frozen_dont_expand) = maketexstring("notexpanded:");
+ set_eq_type(frozen_primitive, ignore_spaces_cmd);
+ set_equiv(frozen_primitive, 1);
+ set_eq_level(frozen_primitive, level_one);
+ cs_text(frozen_primitive) = maketexstring("primitive");
+ create_null_font();
+ font_bytes = 0;
+ init_null_ocp(get_nullstr(), maketexstring("nullocp"));
+ initialize_init_ocplists();
+ pdf_h_origin = one_inch;
+ pdf_v_origin = one_inch;
+ pdf_compress_level = 9;
+ pdf_objcompresslevel = 0;
+ pdf_decimal_digits = 3;
+ pdf_image_resolution = 72;
+ pdf_minor_version = 4;
+ pdf_gamma = 1000;
+ pdf_image_gamma = 2200;
+ pdf_image_hicolor = 1;
+ pdf_image_apply_gamma = 0;
+ pdf_px_dimen = one_bp;
+ pdf_draftmode = 0;
+ cs_text(frozen_protection) = maketexstring("inaccessible");
+ format_ident = maketexstring(" (INITEX)");
+ cs_text(end_write) = maketexstring("endwrite");
+ set_eq_level(end_write, level_one);
+ set_eq_type(end_write, outer_call_cmd);
+ set_equiv(end_write, null);
+
+ }
+ synctexoffset = int_base + synctex_code;
+
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/mathcodes.h b/Build/source/texk/web2c/luatexdir/tex/mathcodes.h
new file mode 100644
index 00000000000..676c50f7b3c
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/mathcodes.h
@@ -0,0 +1,76 @@
+/* mathcodes.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: mathcodes.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef MATHCODES_H
+# define MATHCODES_H
+
+/* mathcodes.c */
+
+# define no_mathcode 0 /* this is a flag for |scan_delimiter| */
+# define tex_mathcode 8
+# define aleph_mathcode 16
+# define xetex_mathcode 21
+# define xetexnum_mathcode 22
+
+typedef struct mathcodeval {
+ int class_value;
+ int origin_value;
+ int family_value;
+ int character_value;
+} mathcodeval;
+
+void set_math_code(int n,
+ int commandorigin,
+ int mathclass,
+ int mathfamily, int mathcharacter, quarterword gl);
+
+mathcodeval get_math_code(int n);
+int get_math_code_num(int n);
+int get_del_code_num(int n);
+mathcodeval scan_mathchar(int extcode);
+mathcodeval scan_delimiter_as_mathchar(int extcode);
+
+mathcodeval mathchar_from_integer(int value, int extcode);
+void show_mathcode_value(mathcodeval d);
+
+typedef struct delcodeval {
+ int class_value;
+ int origin_value;
+ int small_family_value;
+ int small_character_value;
+ int large_family_value;
+ int large_character_value;
+} delcodeval;
+
+void set_del_code(int n,
+ int commandorigin,
+ int smathfamily,
+ int smathcharacter,
+ int lmathfamily, int lmathcharacter, quarterword gl);
+
+delcodeval get_del_code(int n);
+
+void unsave_math_codes(quarterword grouplevel);
+void initialize_math_codes(void);
+void dump_math_codes(void);
+void undump_math_codes(void);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/mathcodes.c b/Build/source/texk/web2c/luatexdir/tex/mathcodes.w
index 78145e343f3..ef5772b6b33 100644
--- a/Build/source/texk/web2c/luatexdir/mathcodes.c
+++ b/Build/source/texk/web2c/luatexdir/tex/mathcodes.w
@@ -1,60 +1,59 @@
-/* mathnodes.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% mathnodes.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
+@ @c
+#include "ptexlib.h"
-#include "managed-sa.h"
-#include "commands.h"
-
-static const char __svn_version[] =
- "$Id$ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.5/source/texk/web2c/luatexdir/mathcodes.c $";
-
-/* math codes */
+static const char _svn_version[] =
+ "$Id: mathcodes.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/mathcodes.w $";
+@ math codes
+@c
static sa_tree mathcode_head = NULL;
#define MATHCODEHEAP 8
static mathcodeval *mathcode_heap = NULL;
-static integer mathcode_heapsize = MATHCODEHEAP;
-static integer mathcode_heapptr = 0;
+static int mathcode_heapsize = MATHCODEHEAP;
+static int mathcode_heapptr = 0;
/* the 0xFFFFFFFF is a flag value */
#define MATHCODESTACK 8
#define MATHCODEDEFAULT 0xFFFFFFFF
-/* delcodes */
-
+@ delcodes
+@c
static sa_tree delcode_head = NULL;
#define DELCODEHEAP 8
static delcodeval *delcode_heap = NULL;
-static integer delcode_heapsize = DELCODEHEAP;
-static integer delcode_heapptr = 0;
+static int delcode_heapsize = DELCODEHEAP;
+static int delcode_heapptr = 0;
#define DELCODESTACK 4
#define DELCODEDEFAULT 0xFFFFFFFF
-/* some helpers for mathcode printing */
+@ some helpers for mathcode printing
+@c
#define print_hex_digit(A) do { \
if ((A)>=10) print_char('A'+(A)-10); \
else print_char('0'+(A)); \
@@ -76,6 +75,7 @@ static integer delcode_heapptr = 0;
two_hex((A)%256); \
} while (0)
+@ @c
void show_mathcode_value(mathcodeval c)
{
if (c.origin_value == aleph_mathcode) {
@@ -103,8 +103,8 @@ void show_mathcode_value(mathcodeval c)
}
}
-
-static void show_mathcode(integer n)
+@ @c
+void show_mathcode(int n)
{
mathcodeval c = get_math_code(n);
if (c.origin_value == aleph_mathcode) {
@@ -121,19 +121,20 @@ static void show_mathcode(integer n)
show_mathcode_value(c);
}
-static void unsavemathcode(quarterword gl)
+@ @c
+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) {
+ >= (int) 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) {
+ if (int_par(tracing_restores_code) > 0) {
begin_diagnostic();
print_char('{');
tprint("restoring");
@@ -147,10 +148,11 @@ static void unsavemathcode(quarterword gl)
}
}
-void set_math_code(integer n,
- integer commandorigin,
- integer mathclass,
- integer mathfamily, integer mathcharacter, quarterword level)
+@ @c
+void set_math_code(int n,
+ int commandorigin,
+ int mathclass,
+ int mathfamily, int mathcharacter, quarterword level)
{
mathcodeval d;
d.origin_value = commandorigin;
@@ -163,9 +165,9 @@ void set_math_code(integer n,
Mxrealloc_array(mathcode_heap, mathcodeval, mathcode_heapsize);
}
mathcode_heap[mathcode_heapptr] = d;
- set_sa_item(mathcode_head, n, mathcode_heapptr, level);
+ set_sa_item(mathcode_head, n, (sa_tree_item) mathcode_heapptr, level);
mathcode_heapptr++;
- if (int_par(param_tracing_assigns_code) > 0) {
+ if (int_par(tracing_assigns_code) > 0) {
begin_diagnostic();
print_char('{');
tprint("assigning");
@@ -176,7 +178,8 @@ void set_math_code(integer n,
}
}
-mathcodeval get_math_code(integer n)
+@ @c
+mathcodeval get_math_code(int n)
{
unsigned int ret;
ret = get_sa_item(mathcode_head, n);
@@ -194,7 +197,8 @@ mathcodeval get_math_code(integer n)
}
-integer get_math_code_num(integer n)
+@ @c
+int get_math_code_num(int n)
{
mathcodeval mval;
mval = get_math_code(n);
@@ -212,15 +216,17 @@ integer get_math_code_num(integer n)
return 0;
}
-static void initializemathcode(void)
+@ @c
+void initializemathcode(void)
{
mathcode_head = new_sa_tree(MATHCODESTACK, MATHCODEDEFAULT);
mathcode_heap = Mxmalloc_array(mathcodeval, MATHCODEHEAP);
}
-static void dumpmathcode(void)
+@ @c
+void dumpmathcode(void)
{
- integer k;
+ int k;
mathcodeval d;
dump_sa_tree(mathcode_head);
dump_int(mathcode_heapsize);
@@ -234,9 +240,9 @@ static void dumpmathcode(void)
}
}
-static void undumpmathcode(void)
+void undumpmathcode(void)
{
- integer k, x;
+ int k, x;
mathcodeval d;
mathcode_head = undump_sa_tree();
undump_int(mathcode_heapsize);
@@ -262,8 +268,8 @@ static void undumpmathcode(void)
}
}
-
-static void show_delcode(integer n)
+@ @c
+void show_delcode(int n)
{
delcodeval c;
c = get_del_code(n);
@@ -309,21 +315,21 @@ static void show_delcode(integer n)
-/* TODO: clean up the heap */
-
-static void unsavedelcode(quarterword gl)
+@ TODO: clean up the heap
+@c
+void unsavedelcode(quarterword gl)
{
sa_stack_item st;
if (delcode_head->stack == NULL)
return;
while (delcode_head->stack_ptr > 0 &&
abs(delcode_head->stack[delcode_head->stack_ptr].level)
- >= (integer) gl) {
+ >= (int) 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) {
+ if (int_par(tracing_restores_code) > 0) {
begin_diagnostic();
print_char('{');
tprint("restoring");
@@ -338,11 +344,12 @@ static void unsavedelcode(quarterword gl)
}
-void set_del_code(integer n,
- integer commandorigin,
- integer smathfamily,
- integer smathcharacter,
- integer lmathfamily, integer lmathcharacter, quarterword gl)
+@ @c
+void set_del_code(int n,
+ int commandorigin,
+ int smathfamily,
+ int smathcharacter,
+ int lmathfamily, int lmathcharacter, quarterword gl)
{
delcodeval d;
d.class_value = 0;
@@ -357,8 +364,8 @@ void set_del_code(integer n,
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) {
+ set_sa_item(delcode_head, n, (sa_tree_item) delcode_heapptr, gl);
+ if (int_par(tracing_assigns_code) > 0) {
begin_diagnostic();
print_char('{');
tprint("assigning");
@@ -370,7 +377,8 @@ void set_del_code(integer n,
delcode_heapptr++;
}
-delcodeval get_del_code(integer n)
+@ @c
+delcodeval get_del_code(int n)
{
unsigned ret;
ret = get_sa_item(delcode_head, n);
@@ -388,15 +396,38 @@ delcodeval get_del_code(integer n)
}
}
-static void initializedelcode(void)
+@ this really only works for old-style delcodes!
+
+@c
+int get_del_code_num(int n)
+{
+ unsigned ret;
+ ret = get_sa_item(delcode_head, n);
+ if (ret == DELCODEDEFAULT) {
+ return -1;
+ } else {
+ delcodeval d = delcode_heap[ret];
+ if (d.origin_value == tex_mathcode) {
+ return ((d.small_family_value * 256 +
+ d.small_character_value) * 4096 +
+ (d.large_family_value * 256) + d.large_character_value);
+ } else {
+ return -1;
+ }
+ }
+}
+
+@ @c
+void initializedelcode(void)
{
delcode_head = new_sa_tree(DELCODESTACK, DELCODEDEFAULT);
delcode_heap = Mxmalloc_array(delcodeval, DELCODEHEAP);
}
-static void dumpdelcode(void)
+@ @c
+void dumpdelcode(void)
{
- integer k;
+ int k;
delcodeval d;
dump_sa_tree(delcode_head);
dump_int(delcode_heapsize);
@@ -412,9 +443,9 @@ static void dumpdelcode(void)
}
}
-static void undumpdelcode(void)
+void undumpdelcode(void)
{
- integer k;
+ int k;
delcodeval d;
delcode_head = undump_sa_tree();
undump_int(delcode_heapsize);
@@ -440,18 +471,21 @@ static void undumpdelcode(void)
}
}
+@ @c
void unsave_math_codes(quarterword grouplevel)
{
unsavemathcode(grouplevel);
unsavedelcode(grouplevel);
}
+@ @c
void initialize_math_codes(void)
{
initializemathcode();
initializedelcode();
}
+@ @c
void free_math_codes(void)
{
destroy_sa_tree(mathcode_head);
@@ -460,6 +494,7 @@ void free_math_codes(void)
xfree(delcode_heap);
}
+@ @c
void dump_math_codes(void)
{
dumpmathcode();
diff --git a/Build/source/texk/web2c/luatexdir/tex/memoryword.h b/Build/source/texk/web2c/luatexdir/tex/memoryword.h
new file mode 100644
index 00000000000..8c44a7e4e0d
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/memoryword.h
@@ -0,0 +1,129 @@
+/* memoryword.h
+
+ Copyright 2009-2010 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: memoryword.h 3352 2010-01-10 15:35:31Z hhenkel $ */
+
+/* This header file is extra special because it is read in from
+ within the pascal source */
+
+#ifndef MEMORYWORD_H
+# define MEMORYWORD_H
+
+/* texmfmem.h: the memory_word type, which is too hard to translate
+ automatically from Pascal. We have to make sure the byte-swapping
+ that the (un)dumping routines do suffices to put things in the right
+ place in memory.
+
+ A memory_word can be broken up into a `twohalves' or a
+ `fourquarters', and a `twohalves' can be further broken up. Here is
+ a picture. ..._M = most significant byte, ..._L = least significant
+ byte.
+
+
+ BigEndian:
+ twohalves.v: RH_MM RH_ML RH_LM RH_LL LH_MM LH_ML LH_LM LH_LL
+ twohalves.u: ---------JUNK---------- ----B0----- ----B1-----
+ fourquarters: ----B0----- ----B1----- ----B2----- ----B3-----
+ twoints: ---------CINT0--------- ---------CINT1---------
+
+ LittleEndian:
+ twohalves.v: LH_LL LH_LM LH_ML LH_MM RH_LL RH_LM RH_ML RH_MM
+ twohalves.u: ----B1----- ----B0-----
+ fourquarters: ----B3----- ----B2----- ----B1----- ----B0-----
+ twoints: ---------CINT1--------- ---------CINT0---------
+
+*/
+
+
+typedef union {
+ struct {
+# ifdef WORDS_BIGENDIAN
+ halfword RH, LH;
+# else
+ halfword LH, RH;
+# endif
+ } v;
+
+ struct { /* Make B0,B1 overlap the most significant bytes of LH. */
+# ifdef WORDS_BIGENDIAN
+ halfword junk;
+ quarterword B0, B1;
+# else /* not WORDS_BIGENDIAN */
+ /* If 32-bit memory words, have to do something. */
+ quarterword B1, B0;
+# endif /* LittleEndian */
+ } u;
+} two_halves;
+
+typedef struct {
+ struct {
+# ifdef WORDS_BIGENDIAN
+ quarterword B0, B1, B2, B3;
+# else
+ quarterword B3, B2, B1, B0;
+# endif
+ } u;
+} four_quarters;
+
+typedef struct {
+# ifdef WORDS_BIGENDIAN
+ int CINT0, CINT1;
+# else
+ int CINT1, CINT0;
+# endif
+} two_ints;
+
+typedef struct {
+ glue_ratio GLUE;
+} glues;
+
+typedef union {
+ two_halves hh;
+ four_quarters qqqq;
+ two_ints ii;
+ glues gg;
+} memory_word;
+
+# define b0 u.B0
+# define b1 u.B1
+# define b2 u.B2
+# define b3 u.B3
+
+# define rh v.RH
+# define lhfield v.LH
+
+# define cint ii.CINT0
+# define cint1 ii.CINT1
+
+# define gr gg.GLUE
+
+/* the next five defines are needed for the prototypes in web2c's coerce.h */
+
+# define memoryword memory_word
+# define strnumber str_number
+# define packedASCIIcode packed_ASCII_code
+# define poolpointer pool_pointer
+
+typedef FILE *word_file;
+
+# ifdef DEBUG
+extern procedure print_word(memory_word w);
+# endif
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/memoryword.w b/Build/source/texk/web2c/luatexdir/tex/memoryword.w
new file mode 100644
index 00000000000..a1ede056dc5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/memoryword.w
@@ -0,0 +1,58 @@
+% memoryword.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: memoryword.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/memoryword.w $";
+
+
+@ When debugging, we may want to print a |memory_word| without knowing
+what type it is; so we print it in all modes.
+
+@c
+#ifdef DEBUG
+void print_word(memory_word w)
+{
+ /* prints |w| in all ways */
+ print_int(w.cint);
+ print_char(' ');
+ print_scaled(w.cint);
+ print_char(' ');
+ print_scaled(round(unity * float_cast(w.gr)));
+ print_ln();
+ print_int(w.hh.lhfield);
+ print_char('=');
+ print_int(w.hh.b0);
+ print_char(':');
+ print_int(w.hh.b1);
+ print_char(';');
+ print_int(w.hh.rh);
+ print_char(' ');
+ print_int(w.qqqq.b0);
+ print_char(':');
+ print_int(w.qqqq.b1);
+ print_char(':');
+ print_int(w.qqqq.b2);
+ print_char(':');
+ print_int(w.qqqq.b3);
+}
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/luatexextra.in b/Build/source/texk/web2c/luatexdir/tex/mlist.h
index faa2ef972d8..c3c8a08b1be 100644
--- a/Build/source/texk/web2c/luatexdir/luatexextra.in
+++ b/Build/source/texk/web2c/luatexdir/tex/mlist.h
@@ -1,7 +1,7 @@
-/* luatexextra.in: banner etc. for luaTeX.
+/* mlist.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -18,23 +18,18 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id$ */
-
-/*
- This is included by luaTeX, from ../luatexextra.c
- (generated from ../lib/texmfmp.c).
-*/
-
-#define BANNER "This is LuaTeX, Version LUATEX-VERSION"
-#define COPYRIGHT_HOLDER "Taco Hoekwater"
-#define AUTHOR NULL
-#define PROGRAM_HELP LUATEXHELP
-#define BUG_ADDRESS "dev-luatex@ntg.nl"
-#define DUMP_VAR TEX_format_default
-#define DUMP_LENGTH_VAR format_default_length
-#define DUMP_OPTION "fmt"
-#define DUMP_EXT ".fmt"
-#define INPUT_FORMAT kpse_tex_format
-#define INI_PROGRAM "luainitex"
-#define VIR_PROGRAM "luavirtex"
-#define TEXMFENGINENAME "luatex"
+/* $Id: mlist.h 3265 2009-12-18 16:21:40Z taco $ */
+
+#ifndef MLIST_H
+# define MLIST_H 1
+
+extern int cur_size;
+
+extern void run_mlist_to_hlist(halfword, int, boolean);
+extern void fixup_math_parameters(int fam_id, int size_id, int f, int lvl);
+
+extern scaled get_math_quad(int a);
+
+extern void mlist_to_hlist_args(halfword, int, boolean);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.c b/Build/source/texk/web2c/luatexdir/tex/mlist.w
index a1a07e4bee7..0b9e80802b1 100644
--- a/Build/source/texk/web2c/luatexdir/tex/mlist.c
+++ b/Build/source/texk/web2c/luatexdir/tex/mlist.w
@@ -1,44 +1,42 @@
-/* mlist.c
+% mlist.w
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
+\def\LuaTeX{Lua\TeX}
-#include "nodes.h"
-#include "commands.h"
+@ @c
+#include "ptexlib.h"
+
+#include "lua/luatex-api.h"
static const char _svn_version[] =
- "$Id: mlist.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/mlist.c $";
-
-#define delimiter_factor int_par(param_delimiter_factor_code)
-#define delimiter_shortfall dimen_par(param_delimiter_shortfall_code)
-#define bin_op_penalty int_par(param_bin_op_penalty_code)
-#define rel_penalty int_par(param_rel_penalty_code)
-#define null_delimiter_space dimen_par(param_null_delimiter_space_code)
-#define script_space dimen_par(param_script_space_code)
-#define disable_lig int_par(param_disable_lig_code)
-#define disable_kern int_par(param_disable_kern_code)
-
-#define level_one 1
-#define thin_mu_skip param_thin_mu_skip_code
-#define med_mu_skip param_med_mu_skip_code
-#define thick_mu_skip param_thick_mu_skip_code
+ "$Id: mlist.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/mlist.w $";
+
+@ @c
+#define delimiter_factor int_par(delimiter_factor_code)
+#define delimiter_shortfall dimen_par(delimiter_shortfall_code)
+#define bin_op_penalty int_par(bin_op_penalty_code)
+#define rel_penalty int_par(rel_penalty_code)
+#define null_delimiter_space dimen_par(null_delimiter_space_code)
+#define script_space dimen_par(script_space_code)
+#define disable_lig int_par(disable_lig_code)
+#define disable_kern int_par(disable_kern_code)
#define nDEBUG
@@ -81,9 +79,8 @@ static const char _svn_version[] =
(font_math_params(a)>=b ? font_math_param(a,b) : undefined_math_parameter)
-/* here are the math parameters that are font-dependant */
+@ here are the math parameters that are font-dependant
-/*
@ 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
@@ -92,8 +89,8 @@ 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@>
-*/
+@c
#define total_mathsy_params 22
#define total_mathex_params 13
@@ -116,13 +113,13 @@ following macros, which take a size code as their parameter; for example,
#define delim2(A) mathsy(A,21) /* size of \.{\\atopwithdelims} delimiters in non-displays */
#define axis_height(A) mathsy(A,22) /* height of fraction lines above the baseline */
-/*
-The math-extension parameters have similar macros, but the size code is
+
+@ 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@>
-*/
+@c
#define mathex(A,B) font_param(fam_fnt(3,A),B)
#define default_rule_thickness(A) mathex(A,8) /* thickness of \.{\\over} bars */
#define big_op_spacing1(A) mathex(A,9) /* minimum clearance above a displayed op */
@@ -131,7 +128,7 @@ omitted (since it is always |cur_size| when we refer to such parameters).
#define big_op_spacing4(A) mathex(A,12) /* minimum baselineskip below displayed op */
#define big_op_spacing5(A) mathex(A,13) /* padding above and below displayed limits */
-/* I made a bunch of extensions cf. the MATH table in OpenType, but some of
+@ I (TH) made a bunch of extensions cf. the MATH table in OpenType, but some of
the MathConstants values have no matching usage in \LuaTeX\ right now.
ScriptPercentScaleDown,
@@ -162,10 +159,9 @@ Also still TODO for OpenType Math:
* extensible large operators
* prescripts
-*/
-
-/* this is not really a math parameter at all */
+@ this is not really a math parameter at all
+@c
static void math_param_error(const char *param, int style)
{
char s[256];
@@ -179,12 +175,15 @@ static void math_param_error(const char *param, int style)
snprintf(s, 256, "Math error: parameter \\Umath%s\\%sstyle is not set",
param, math_style_names[style]);
tex_error(s, hlp);
- /* flush_math(); */
+#if 0
+ flush_math();
+#endif
return;
}
-static scaled accent_base_height(integer f)
+@ @c
+static scaled accent_base_height(int f)
{
scaled a;
a = x_height(f);
@@ -196,8 +195,9 @@ static scaled accent_base_height(integer f)
return a;
}
-/* the non-staticness of this function is for the benefit of |math.c| */
+@ the non-staticness of this function is for the benefit of |texmath.w|
+@c
scaled get_math_quad(int var)
{
scaled a = get_math_param(math_param_quad, var);
@@ -208,9 +208,10 @@ scaled get_math_quad(int var)
return a;
}
-/* this parameter is different because it is called with a size
- specifier instead of a style specifier. */
+@ this parameter is different because it is called with a size
+ specifier instead of a style specifier.
+@c
static scaled math_axis(int b)
{
scaled a;
@@ -229,6 +230,7 @@ static scaled math_axis(int b)
return a;
}
+@ @c
static scaled get_math_quad_size(int b)
{
int var;
@@ -242,452 +244,95 @@ static scaled get_math_quad_size(int b)
}
+@ @c
static scaled minimum_operator_size(int var)
{
scaled a = get_math_param(math_param_operator_size, var);
return a;
}
-/* Old-style fonts do not define the radical_rule. This allows |make_radical| to select
- * the backward compatibility code, and it means that we can't raise an error here.
- */
+@ Old-style fonts do not define the |radical_rule|. This allows |make_radical| to select
+ the backward compatibility code, and it means that we can't raise an error here.
+@c
static scaled radical_rule(int var)
{
scaled a = get_math_param(math_param_radical_rule, var);
return a;
}
-static scaled radical_degree_before(int var)
-{
- scaled a = get_math_param(math_param_radical_degree_before, var);
- if (a == undefined_math_parameter) {
- math_param_error("radicaldegreebefore", var);
- a = 0;
- }
- return a;
-}
-
-static scaled connector_overlap_min(int var)
-{
- scaled a = get_math_param(math_param_connector_overlap_min, var);
- if (a == undefined_math_parameter) {
- math_param_error("connectoroverlapmin", var);
- a = 0;
- }
- return a;
-}
-
+@ now follow all the trivial math parameters
-static scaled radical_degree_after(int var)
-{
- scaled a = get_math_param(math_param_radical_degree_after, var);
- if (a == undefined_math_parameter) {
- math_param_error("radicaldegreeafter", var);
- a = 0;
- }
- return a;
-}
-
-static scaled radical_degree_raise(int var)
-{
- scaled a = get_math_param(math_param_radical_degree_raise, var);
- if (a == undefined_math_parameter) {
- math_param_error("radicaldegreeraise", var);
- a = 0;
- }
- return a;
-}
-
-
-/* now follow all the trivial functions for the math parameters */
-
-static scaled overbar_kern(int var)
-{
- scaled a = get_math_param(math_param_overbar_kern, var);
- if (a == undefined_math_parameter) {
- math_param_error("overbarkern", var);
- a = 0;
- }
- return a;
-}
-
-static scaled overbar_rule(int var)
-{
- scaled a = get_math_param(math_param_overbar_rule, var);
- if (a == undefined_math_parameter) {
- math_param_error("overbarrule", var);
- a = 0;
- }
- return a;
-}
-
-static scaled overbar_vgap(int var)
-{
- scaled a = get_math_param(math_param_overbar_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("overbarvgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled underbar_rule(int var)
-{
- scaled a = get_math_param(math_param_underbar_rule, var);
- if (a == undefined_math_parameter) {
- math_param_error("underbarrule", var);
- a = 0;
- }
- return a;
-}
+@c
+#define get_math_param_or_error(a,b) do_get_math_param_or_error(a, math_param_##b, #b)
-static scaled underbar_vgap(int var)
+static scaled do_get_math_param_or_error(int var, int param, const char *name)
{
- scaled a = get_math_param(math_param_underbar_vgap, var);
+ scaled a = get_math_param(param, var);
if (a == undefined_math_parameter) {
- math_param_error("underbarvgap", var);
+ math_param_error(name, var);
a = 0;
}
return a;
}
-static scaled underbar_kern(int var)
-{
- scaled a = get_math_param(math_param_underbar_kern, var);
- if (a == undefined_math_parameter) {
- math_param_error("underbarkern", var);
- a = 0;
- }
- return a;
-}
+@ @c
+#define radical_degree_before(a) get_math_param_or_error(a, radical_degree_before)
+#define radical_degree_after(a) get_math_param_or_error(a, radical_degree_after)
+#define radical_degree_raise(a) get_math_param_or_error(a, radical_degree_raise)
-static scaled under_delimiter_vgap(int var)
-{
- scaled a = get_math_param(math_param_under_delimiter_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("underdelimitervgap", var);
- a = 0;
- }
- return a;
-}
+#define connector_overlap_min(a) get_math_param_or_error(a, connector_overlap_min)
-static scaled under_delimiter_bgap(int var)
-{
- scaled a = get_math_param(math_param_under_delimiter_bgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("underdelimiterbgap", var);
- a = 0;
- }
- return a;
-}
+#define overbar_rule(a) get_math_param_or_error(a, overbar_rule)
+#define overbar_kern(a) get_math_param_or_error(a, overbar_kern)
+#define overbar_vgap(a) get_math_param_or_error(a, overbar_vgap)
+#define underbar_rule(a) get_math_param_or_error(a, underbar_rule)
+#define underbar_kern(a) get_math_param_or_error(a, underbar_kern)
+#define underbar_vgap(a) get_math_param_or_error(a, underbar_vgap)
-static scaled over_delimiter_vgap(int var)
-{
- scaled a = get_math_param(math_param_over_delimiter_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("overdelimitervgap", var);
- a = 0;
- }
- return a;
-}
+#define under_delimiter_vgap(a) get_math_param_or_error(a, under_delimiter_vgap)
+#define under_delimiter_bgap(a) get_math_param_or_error(a, under_delimiter_bgap)
-static scaled over_delimiter_bgap(int var)
-{
- scaled a = get_math_param(math_param_over_delimiter_bgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("overdelimiterbgap", var);
- a = 0;
- }
- return a;
-}
+#define over_delimiter_vgap(a) get_math_param_or_error(a, over_delimiter_vgap)
+#define over_delimiter_bgap(a) get_math_param_or_error(a, over_delimiter_bgap)
+#define radical_vgap(a) get_math_param_or_error(a, radical_vgap)
+#define radical_kern(a) get_math_param_or_error(a, radical_kern)
+#define stack_vgap(a) get_math_param_or_error(a, stack_vgap)
+#define stack_num_up(a) get_math_param_or_error(a, stack_num_up)
+#define stack_denom_down(a) get_math_param_or_error(a, stack_denom_down)
-static scaled radical_vgap(int var)
-{
- scaled a = get_math_param(math_param_radical_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("radicalvgap", var);
- a = 0;
- }
- return a;
-}
+#define fraction_rule(a) get_math_param_or_error(a, fraction_rule)
+#define fraction_num_vgap(a) get_math_param_or_error(a, fraction_num_vgap)
+#define fraction_denom_vgap(a) get_math_param_or_error(a, fraction_denom_vgap)
+#define fraction_num_up(a) get_math_param_or_error(a, fraction_num_up)
+#define fraction_denom_down(a) get_math_param_or_error(a, fraction_denom_down)
+#define fraction_del_size(a) get_math_param_or_error(a, fraction_del_size)
+#define limit_above_vgap(a) get_math_param_or_error(a, limit_above_vgap)
+#define limit_above_bgap(a) get_math_param_or_error(a, limit_above_bgap)
+#define limit_above_kern(a) get_math_param_or_error(a, limit_above_kern)
-static scaled radical_kern(int var)
-{
- scaled a = get_math_param(math_param_radical_kern, var);
- if (a == undefined_math_parameter) {
- math_param_error("radicalkern", var);
- a = 0;
- }
- return a;
-}
+#define limit_below_vgap(a) get_math_param_or_error(a, limit_below_vgap)
+#define limit_below_bgap(a) get_math_param_or_error(a, limit_below_bgap)
+#define limit_below_kern(a) get_math_param_or_error(a, limit_below_kern)
-static scaled stack_vgap(int var)
-{
- scaled a = get_math_param(math_param_stack_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("stackvgap", var);
- a = 0;
- }
- return a;
-}
+#define sub_shift_drop(a) get_math_param_or_error(a, sub_shift_drop)
+#define sup_shift_drop(a) get_math_param_or_error(a, sup_shift_drop)
+#define sub_shift_down(a) get_math_param_or_error(a, sub_shift_down)
+#define sub_sup_shift_down(a) get_math_param_or_error(a, sub_sup_shift_down)
+#define sup_shift_up(a) get_math_param_or_error(a, sup_shift_up)
+#define sub_top_max(a) get_math_param_or_error(a, sub_top_max)
+#define sup_bottom_min(a) get_math_param_or_error(a, sup_bottom_min)
+#define sup_sub_bottom_max(a) get_math_param_or_error(a, sup_sub_bottom_max)
+#define subsup_vgap(a) get_math_param_or_error(a, subsup_vgap)
-static scaled stack_num_up(int var)
-{
- scaled a = get_math_param(math_param_stack_num_up, var);
- if (a == undefined_math_parameter) {
- math_param_error("stacknumup", var);
- a = 0;
- }
- return a;
-}
+#define space_after_script(a) get_math_param_or_error(a, space_after_script)
-static scaled stack_denom_down(int var)
-{
- scaled a = get_math_param(math_param_stack_denom_down, var);
- if (a == undefined_math_parameter) {
- math_param_error("stackdenomdown", var);
- a = 0;
- }
- return a;
-}
-
-static scaled fraction_rule(int var)
-{
- scaled a = get_math_param(math_param_fraction_rule, var);
- if (a == undefined_math_parameter) {
- math_param_error("fractionrule", var);
- a = 0;
- }
- return a;
-}
-
-
-static scaled fraction_num_vgap(int var)
-{
- scaled a = get_math_param(math_param_fraction_num_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("fractionnumvgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled fraction_denom_vgap(int var)
-{
- scaled a = get_math_param(math_param_fraction_denom_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("fractiondenomvgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled fraction_num_up(int var)
-{
- scaled a = get_math_param(math_param_fraction_num_up, var);
- if (a == undefined_math_parameter) {
- math_param_error("fractionnumup", var);
- a = 0;
- }
- return a;
-}
-
-static scaled fraction_denom_down(int var)
-{
- scaled a = get_math_param(math_param_fraction_denom_down, var);
- if (a == undefined_math_parameter) {
- math_param_error("fractiondenomdown", var);
- a = 0;
- }
- return a;
-}
-
-static scaled fraction_del_size(int var)
-{
- scaled a = get_math_param(math_param_fraction_del_size, var);
- if (a == undefined_math_parameter) {
- math_param_error("fractiondelsize", var);
- a = 0;
- }
- return a;
-}
-
-static scaled limit_above_vgap(int var)
-{
- scaled a = get_math_param(math_param_limit_above_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("limitabovevgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled limit_above_bgap(int var)
-{
- scaled a = get_math_param(math_param_limit_above_bgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("limitabovebgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled limit_above_kern(int var)
-{
- scaled a = get_math_param(math_param_limit_above_kern, var);
- if (a == undefined_math_parameter) {
- math_param_error("limitabovekern", var);
- a = 0;
- }
- return a;
-}
-
-static scaled limit_below_vgap(int var)
-{
- scaled a = get_math_param(math_param_limit_below_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("limitbelowvgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled limit_below_bgap(int var)
-{
- scaled a = get_math_param(math_param_limit_below_bgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("limitbelowbgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled limit_below_kern(int var)
-{
- scaled a = get_math_param(math_param_limit_below_kern, var);
- if (a == undefined_math_parameter) {
- math_param_error("limitbelowkern", var);
- a = 0;
- }
- return a;
-}
-
-
-static scaled sub_shift_drop(int var)
-{
- scaled a = get_math_param(math_param_sub_shift_drop, var);
- if (a == undefined_math_parameter) {
- math_param_error("subshiftdrop", var);
- a = 0;
- }
- return a;
-}
-
-static scaled sup_shift_drop(int var)
-{
- scaled a = get_math_param(math_param_sup_shift_drop, var);
- if (a == undefined_math_parameter) {
- math_param_error("supshiftdrop", var);
- a = 0;
- }
- return a;
-}
-
-static scaled sub_shift_down(int var)
-{
- scaled a = get_math_param(math_param_sub_shift_down, var);
- if (a == undefined_math_parameter) {
- math_param_error("subshiftdown", var);
- a = 0;
- }
- return a;
-}
-
-static scaled sub_sup_shift_down(int var)
-{
- scaled a = get_math_param(math_param_sub_sup_shift_down, var);
- if (a == undefined_math_parameter) {
- math_param_error("subsupshiftdown", var);
- a = 0;
- }
- return a;
-}
-
-static scaled sub_top_max(int var)
-{
- scaled a = get_math_param(math_param_sub_top_max, var);
- if (a == undefined_math_parameter) {
- math_param_error("subtopmax", var);
- a = 0;
- }
- return a;
-}
-
-static scaled sup_shift_up(int var)
-{
- scaled a = get_math_param(math_param_sup_shift_up, var);
- if (a == undefined_math_parameter) {
- math_param_error("supshiftup", var);
- a = 0;
- }
- return a;
-}
-
-static scaled sup_bottom_min(int var)
-{
- scaled a = get_math_param(math_param_sup_bottom_min, var);
- if (a == undefined_math_parameter) {
- math_param_error("supbottommin", var);
- a = 0;
- }
- return a;
-}
-
-static scaled sup_sub_bottom_max(int var)
-{
- scaled a = get_math_param(math_param_sup_sub_bottom_max, var);
- if (a == undefined_math_parameter) {
- math_param_error("supsubbottommax", var);
- a = 0;
- }
- return a;
-}
-
-static scaled subsup_vgap(int var)
-{
- scaled a = get_math_param(math_param_subsup_vgap, var);
- if (a == undefined_math_parameter) {
- math_param_error("subsupvgap", var);
- a = 0;
- }
- return a;
-}
-
-static scaled space_after_script(int var)
-{
- scaled a = get_math_param(math_param_space_after_script, var);
- if (a == undefined_math_parameter) {
- math_param_error("spaceafterscript", var);
- a = 0;
- }
- return a;
-}
-
-
-/* This function is no longer useful */
-
-boolean check_necessary_fonts(void)
-{
- return false; /* temp */
-}
-
-void fixup_math_parameters(integer fam_id, integer size_id, integer f,
- integer lvl)
+@ @c
+void fixup_math_parameters(int fam_id, int size_id, int f, int lvl)
{
if (is_new_mathfont(f)) { /* fix all known parameters */
@@ -924,8 +569,13 @@ void fixup_math_parameters(integer fam_id, integer size_id, integer f,
font_MATH_par(f,
FractionDenominatorDisplayStyleShiftDown),
lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_del_size, size_id, 0, lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_del_size, size_id, 0, lvl);
+
+ DEFINE_MATH_PARAMETERS(math_param_fraction_del_size, size_id,
+ font_MATH_par(f, FractionDelimiterSize), lvl);
+ DEFINE_DMATH_PARAMETERS(math_param_fraction_del_size, size_id,
+ font_MATH_par(f,
+ FractionDelimiterDisplayStyleSize),
+ lvl);
DEFINE_MATH_PARAMETERS(math_param_space_after_script, size_id,
font_MATH_par(f, SpaceAfterScript), lvl);
@@ -1041,7 +691,7 @@ void fixup_math_parameters(integer fam_id, integer size_id, integer f,
DEFINE_DMATH_PARAMETERS(math_param_sup_sub_bottom_max, size_id,
(abs(math_x_height(size_id) * 4) / 5), lvl);
- /* The display-size radical_vgap is done twice because it needs
+ /* The display-size |radical_vgap| is done twice because it needs
values from both the sy and the ex font. */
DEFINE_DMATH_PARAMETERS(math_param_radical_vgap, size_id,
(default_rule_thickness(size_id) +
@@ -1144,7 +794,7 @@ void fixup_math_parameters(integer fam_id, integer size_id, integer f,
4 * default_rule_thickness(size_id), lvl);
DEFINE_DMATH_PARAMETERS(math_param_subsup_vgap, size_id,
4 * default_rule_thickness(size_id), lvl);
- /* All of the |space_after_script|s are done in finalize_math_parameters because the
+ /* All of the |space_after_script|s are done in |finalize_math_parameters| because the
\.{\\scriptspace} may have been altered by the user
*/
DEFINE_MATH_PARAMETERS(math_param_connector_overlap_min, size_id, 0,
@@ -1169,7 +819,7 @@ void fixup_math_parameters(integer fam_id, integer size_id, integer f,
DEFINE_DMATH_PARAMETERS(math_param_over_delimiter_bgap, size_id,
big_op_spacing3(size_id), lvl);
- /* The display-size radical_vgap is done twice because it needs
+ /* The display-size |radical_vgap| is done twice because it needs
values from both the sy and the ex font. */
DEFINE_DMATH_PARAMETERS(math_param_radical_vgap, size_id,
(default_rule_thickness(size_id) +
@@ -1177,11 +827,14 @@ void fixup_math_parameters(integer fam_id, integer size_id, integer f,
}
}
-/* this needs to be called just at the start of |mlist_to_hlist| */
-static void finalize_math_parameters(void)
+@ This needs to be called just at the start of |mlist_to_hlist|, for
+backward compatibility with \.{\\scriptspace}.
+
+@c
+void finalize_math_parameters(void)
{
- integer saved_trace = int_par(param_tracing_assigns_code);
- int_par(param_tracing_assigns_code) = 0;
+ int saved_trace = int_par(tracing_assigns_code);
+ int_par(tracing_assigns_code) = 0;
if (get_math_param(math_param_space_after_script, display_style) ==
undefined_math_parameter) {
def_math_param(math_param_space_after_script, display_style,
@@ -1201,13 +854,12 @@ static void finalize_math_parameters(void)
def_math_param(math_param_space_after_script,
cramped_script_script_style, script_space, level_one);
}
- int_par(param_tracing_assigns_code) = saved_trace;
+ int_par(tracing_assigns_code) = saved_trace;
}
-/*
-In order to convert mlists to hlists, i.e., noads to nodes, we need several
+@ In order to convert mlists to hlists, i.e., noads to nodes, we need several
subroutines that are conveniently dealt with now.
Let us first introduce the macros that make it easy to get at the parameters and
@@ -1215,10 +867,9 @@ other font information. A size code, which is a multiple of 256, 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.)
-*/
-
-static const char *math_size_string(integer s)
+@c
+const char *math_size_string(int s)
{
if (s == text_size)
return "textfont";
@@ -1228,25 +879,24 @@ static const char *math_size_string(integer s)
return "scriptscriptfont";
}
-/*
- @ When the style changes, the following piece of program computes associated
- information:
-*/
-
-#define setup_cur_size_and_mu() do { \
- if (cur_style==script_style || \
- cur_style==cramped_script_style) \
- cur_size=script_size; \
- else if (cur_style==script_script_style || \
- cur_style==cramped_script_script_style) \
- cur_size=script_script_size; \
- else cur_size=text_size; \
- cur_mu=x_over_n(get_math_quad(cur_size),18); \
- } while (0)
+@ When the style changes, the following piece of program computes associated
+information:
+
+@c
+#define setup_cur_size(a) do { \
+ if (a==script_style || \
+ a==cramped_script_style) \
+ cur_size=script_size; \
+ else if (a==script_script_style || \
+ a==cramped_script_script_style) \
+ cur_size=script_script_size; \
+ else cur_size=text_size; \
+ } while (0)
-/* a simple routine that creates a flat copy of a nucleus */
-static pointer math_clone(pointer q)
+@ a simple routine that creates a flat copy of a nucleus
+@c
+pointer math_clone(pointer q)
{
pointer x;
if (q == null)
@@ -1265,13 +915,12 @@ static pointer math_clone(pointer q)
-/*
- @ Here is a function that returns a pointer to a rule node having a given
+@ Here is a function that returns a pointer to a rule node having a given
thickness |t|. The rule will extend horizontally to the boundary of the vlist
that eventually contains it.
-*/
-static pointer do_fraction_rule(scaled t, pointer att)
+@c
+pointer do_fraction_rule(scaled t, pointer att)
{
pointer p; /* the new node */
p = new_rule();
@@ -1282,13 +931,13 @@ static pointer do_fraction_rule(scaled t, pointer att)
return p;
}
-/*
- @ The |overbar| function returns a pointer to a vlist box that consists of
+
+@ The |overbar| function returns a pointer to a vlist box that consists of
a given box |b|, above which has been placed a kern of height |k| under a
fraction rule of thickness |t| under additional space of height |ht|.
-*/
-static pointer overbar(pointer b, scaled k, scaled t, scaled ht, pointer att)
+@c
+pointer overbar(pointer b, scaled k, scaled t, scaled ht, pointer att)
{
pointer p, q; /* nodes being constructed */
p = new_kern(k);
@@ -1299,21 +948,19 @@ static pointer overbar(pointer b, scaled k, scaled t, scaled ht, pointer att)
p = new_kern(ht);
reset_attributes(p, att);
vlink(p) = q;
- pack_direction = math_direction;
- q = vpackage(p, 0, additional, max_dimen);
+ q = vpackage(p, 0, additional, max_dimen, math_direction);
reset_attributes(q, att);
return q;
}
-/*
- Here is a subroutine that creates a new box, whose list contains a
+@ 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.
-*/
-static pointer char_box(internal_font_number f, integer c, pointer bb)
+@c
+static pointer char_box(internal_font_number f, int c, pointer bb)
{
pointer b, p; /* the new box and its character node */
b = new_null_box();
@@ -1327,24 +974,22 @@ static pointer char_box(internal_font_number f, integer c, pointer bb)
return b;
}
-/*
- Another handy subroutine computes the height plus depth of
+@ Another handy subroutine computes the height plus depth of
a given character:
-*/
-static scaled height_plus_depth(internal_font_number f, integer c)
+@c
+scaled height_plus_depth(internal_font_number f, int c)
{
return (char_height(f, c) + char_depth(f, c));
}
-/*
- When we build an extensible character, it's handy to have the
+@ 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|:
-*/
-static scaled stack_into_box(pointer b, internal_font_number f, integer c)
+@c
+scaled stack_into_box(pointer b, internal_font_number f, int c)
{
pointer p; /* new node placed into |b| */
p = char_box(f, c, node_attr(b));
@@ -1355,7 +1000,7 @@ static scaled stack_into_box(pointer b, internal_font_number f, integer c)
}
-static scaled stack_into_hbox(pointer b, internal_font_number f, integer c)
+scaled stack_into_hbox(pointer b, internal_font_number f, int c)
{
pointer p, q; /* new node placed into |b| */
p = char_box(f, c, node_attr(b));
@@ -1375,8 +1020,8 @@ static scaled stack_into_hbox(pointer b, internal_font_number f, integer c)
}
-
-static void add_delim_kern(pointer b, scaled s)
+@ @c
+void add_delim_kern(pointer b, scaled s)
{
pointer p; /* new node placed into |b| */
p = new_kern(s);
@@ -1385,7 +1030,7 @@ static void add_delim_kern(pointer b, scaled s)
list_ptr(b) = p;
}
-static void add_delim_hkern(pointer b, scaled s)
+void add_delim_hkern(pointer b, scaled s)
{
pointer p, q; /* new node placed into |b| */
p = new_kern(s);
@@ -1400,12 +1045,28 @@ static void add_delim_hkern(pointer b, scaled s)
}
}
+@ \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. The
+ explicit parameter |cur_mlist| points to the first node or noad in
+ the given mlist (and it might be |null|); the parameter |penalties|
+ is |true| if penalty nodes for potential line breaks are to be
+ inserted into the resulting hlist, the parameter |cur_style| is a
+ style code. 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@>
-/* */
+@c
+int cur_size; /* size code corresponding to |cur_style| */
+@ @c
static pointer get_delim_box(extinfo * ext, internal_font_number f, scaled v,
- pointer att, int boxtype)
+ pointer att, int boxtype, int cur_style)
{
pointer b;
extinfo *cur;
@@ -1413,15 +1074,15 @@ static pointer get_delim_box(extinfo * ext, internal_font_number f, scaled v,
scaled b_max; /* natural (maximum) height of the stack */
scaled s_max; /* amount of possible shrink in the stack */
scaled a, wd, ht, dp, last_ht;
- integer cc; /* a temporary character code for extensibles */
- integer i; /* a temporary counter number of extensible pieces */
+ int cc; /* a temporary character code for extensibles */
+ int i; /* a temporary counter number of extensible pieces */
int with_extenders;
int num_extenders, num_normal, num_total;
scaled c, d, u;
scaled *max_shrinks = NULL;
assert(ext != NULL);
b = new_null_box();
- type(b) = boxtype;
+ type(b) = (quarterword) boxtype;
reset_attributes(b, att);
min_overlap = connector_overlap_min(cur_style);
assert(min_overlap >= 0);
@@ -1586,7 +1247,7 @@ static pointer get_delim_box(extinfo * ext, internal_font_number f, scaled v,
depth(b) = char_depth(f, cc);
return b;
}
- max_shrinks = xcalloc(num_total, sizeof(scaled));
+ max_shrinks = xcalloc((unsigned) num_total, sizeof(scaled));
cur = ext;
prev_overlap = -1;
c = 0;
@@ -1672,17 +1333,19 @@ static pointer get_delim_box(extinfo * ext, internal_font_number f, scaled v,
height(b) = ht;
depth(b) = 0;
/* the next correction is needed for radicals */
- if (list_ptr(b) != null && type(list_ptr(b)) == hlist_node && list_ptr(list_ptr(b)) != null && type(list_ptr(list_ptr(b))) == glyph_node) { /* and it should be */
+ if (list_ptr(b) != null &&
+ type(list_ptr(b)) == hlist_node && list_ptr(list_ptr(b)) != null
+ && type(list_ptr(list_ptr(b))) == glyph_node) { /* and it should be */
last_ht =
char_height(font(list_ptr(list_ptr(b))),
character(list_ptr(list_ptr(b))));
height(b) = last_ht;
depth(b) = ht - last_ht;
}
- /*
+#if 0
fprintf (stdout,"v=%f,b_max=%f,ht=%f,n=%d\n", (float)v/65536.0,
(float)b_max/65536.0,(float)height(b)/65536.0,num_total);
- */
+#endif
width(b) = wd;
} else {
/* horizontal version */
@@ -1733,21 +1396,20 @@ static pointer get_delim_box(extinfo * ext, internal_font_number f, scaled v,
}
static pointer get_delim_vbox(extinfo * ext, internal_font_number f, scaled v,
- pointer att)
+ pointer att, int cur_style)
{
- return get_delim_box(ext, f, v, att, vlist_node);
+ return get_delim_box(ext, f, v, att, vlist_node, cur_style);
}
static pointer get_delim_hbox(extinfo * ext, internal_font_number f, scaled v,
- pointer att)
+ pointer att, int cur_style)
{
- return get_delim_box(ext, f, v, att, hlist_node);
+ return get_delim_box(ext, f, v, att, hlist_node, cur_style);
}
-/*
- @ The |var_delimiter| function, which finds or constructs a sufficiently
+@ The |var_delimiter| function, which finds or constructs a sufficiently
large delimiter, is the most interesting of the auxiliary functions that
currently concern us. Given a pointer |d| to a delimiter field in some noad,
together with a size code |s| and a vertical distance |v|, this function
@@ -1761,9 +1423,9 @@ static pointer get_delim_hbox(extinfo * ext, internal_font_number f, scaled v,
the box is vertically centered with respect to the axis in the given size.
If a built-up symbol is returned, the height of the box before shifting
will be the height of its topmost component.
-*/
-static void endless_loop_error(internal_font_number g, integer y)
+@c
+static void endless_loop_error(internal_font_number g, int y)
{
char s[256];
const char *hlp[] = {
@@ -1777,15 +1439,16 @@ static void endless_loop_error(internal_font_number g, integer y)
tex_error(s, hlp);
}
-static pointer var_delimiter(pointer d, integer s, scaled v)
+static pointer do_var_delimiter(pointer d, int s, scaled v, scaled * ic,
+ boolean flat, int cur_style)
{
/* label found,continue; */
pointer b; /* the box that will be constructed */
internal_font_number f, g; /* best-so-far and tentative font codes */
- integer c, i, x, y; /* best-so-far and tentative character codes */
+ int c, i, x, y; /* best-so-far and tentative character codes */
scaled u; /* height-plus-depth of a tentative character */
scaled w; /* largest height-plus-depth so far */
- integer z; /* runs through font family members */
+ int z; /* runs through font family members */
boolean large_attempt; /* are we trying the ``large'' variant? */
pointer att; /* to save the current attribute list */
extinfo *ext;
@@ -1815,7 +1478,10 @@ static pointer var_delimiter(pointer d, integer s, scaled v)
c = y;
goto FOUND;
}
- u = height_plus_depth(g, y);
+ if (flat)
+ u = char_width(g, y);
+ else
+ u = height_plus_depth(g, y);
if (u > w) {
f = g;
c = y;
@@ -1853,116 +1519,56 @@ static pointer var_delimiter(pointer d, integer s, scaled v)
*/
ext = NULL;
if ((char_tag(f, c) == ext_tag) &&
- ((ext = get_charinfo_vert_variants(char_info(f, c))) != NULL)) {
- b = get_delim_vbox(ext, f, v, att);
- width(b) += char_italic(f, c);
+ ((!flat
+ && (ext = get_charinfo_vert_variants(char_info(f, c))) != NULL)
+ || (flat
+ && (ext =
+ get_charinfo_hor_variants(char_info(f, c))) != NULL))) {
+ b = (flat ? get_delim_hbox(ext, f, v, att, cur_style) :
+ get_delim_vbox(ext, f, v, att, cur_style));
} else {
b = char_box(f, c, att);
}
- } else {
- b = new_null_box();
- reset_attributes(b, att);
- width(b) = null_delimiter_space; /* use this width if no delimiter was found */
- }
- shift_amount(b) = half(height(b) - depth(b)) - math_axis(s);
- delete_attribute_ref(att);
- return b;
-}
-
-static pointer flat_var_delimiter(pointer d, integer s, scaled v)
-{
- /* label found,continue; */
- pointer b; /* the box that will be constructed */
- internal_font_number f, g; /* best-so-far and tentative font codes */
- integer c, i, x, y; /* best-so-far and tentative character codes */
- scaled u; /* height-plus-depth of a tentative character */
- scaled w; /* largest height-plus-depth so far */
- integer z; /* runs through font family members */
- boolean large_attempt; /* are we trying the ``large'' variant? */
- pointer att; /* to save the current attribute list */
- extinfo *ext;
- f = null_font;
- c = 0;
- w = 0;
- att = null;
- large_attempt = false;
- if (d == null)
- goto FOUND;
- z = small_fam(d);
- x = small_char(d);
- i = 0;
- while (true) {
- /* 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) || (x != 0)) {
- g = fam_fnt(z, s);
- if (g != null_font) {
- y = x;
- CONTINUE:
- i++;
- if (char_exists(g, y)) {
- if (char_tag(g, y) == ext_tag) {
- f = g;
- c = y;
- goto FOUND;
- }
- u = char_width(g, y);
- if (u > w) {
- f = g;
- c = y;
- w = u;
- if (u >= v)
- goto FOUND;
- }
- if (i > 10000) {
- /* endless loop */
- endless_loop_error(g, y);
- goto FOUND;
- }
- if (char_tag(g, y) == list_tag) {
- y = char_remainder(g, y);
- goto CONTINUE;
- }
- }
- }
- }
- if (large_attempt)
- goto FOUND; /* there were none large enough */
- large_attempt = true;
- z = large_fam(d);
- x = large_char(d);
- }
- FOUND:
- if (d != null) {
- att = node_attr(d);
- node_attr(d) = null;
- flush_node(d);
- }
- if (f != null_font) {
- /* 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.
+ /* This next test is because for OT MATH fonts, the italic correction of an
+ extensible character is only used for the placement of a subscript
+ (in negated form), and it is not supposed to be added to the
+ width of the character box at all.
+
+ This has an effect later on in |make_op| as well, where it has to do
+ an extra correction for |make_script|'s addition of yet another italic
+ correction.
*/
- ext = NULL;
- if ((char_tag(f, c) == ext_tag) &&
- ((ext = get_charinfo_hor_variants(char_info(f, c))) != NULL)) {
- b = get_delim_hbox(ext, f, v, att);
+ if (!is_new_mathfont(f)) {
width(b) += char_italic(f, c);
- } else {
- b = char_box(f, c, att);
}
+ if (ic != NULL)
+ *ic = char_italic(f, c);
} else {
b = new_null_box();
reset_attributes(b, att);
- width(b) = 0; /* use this width if no delimiter was found */
+ width(b) = (flat ? 0 : null_delimiter_space); /* use this width if no delimiter was found */
+ if (ic != NULL)
+ *ic = 0;
}
+ if (!flat)
+ shift_amount(b) = half(height(b) - depth(b)) - math_axis(s);
delete_attribute_ref(att);
return b;
}
-/*
-The next subroutine is much simpler; it is used for numerators and
+static pointer var_delimiter(pointer d, int s, scaled v, scaled * ic,
+ int cur_style)
+{
+ return do_var_delimiter(d, s, v, ic, false, cur_style);
+}
+
+static pointer flat_delimiter(pointer d, int s, scaled v, int cur_style)
+{
+ return do_var_delimiter(d, s, v, NULL, true, cur_style);
+}
+
+@ 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|.
@@ -1975,8 +1581,8 @@ 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.
-*/
+@c
static pointer rebox(pointer b, scaled w)
{
pointer p, q, r, att; /* temporary registers for list manipulation */
@@ -1985,7 +1591,7 @@ static pointer rebox(pointer b, scaled w)
if ((width(b) != w) && (list_ptr(b) != null)) {
if (type(b) == vlist_node) {
- p = hpack(b, 0, additional);
+ p = hpack(b, 0, additional, -1);
reset_attributes(p, node_attr(b));
b = p;
}
@@ -2011,7 +1617,7 @@ static pointer rebox(pointer b, scaled w)
q = new_glue(ss_glue);
reset_attributes(q, att);
vlink(p) = q;
- r = hpack(b, w, exactly);
+ r = hpack(b, w, exactly, -1);
reset_attributes(r, att);
delete_attribute_ref(att);
return r;
@@ -2021,17 +1627,16 @@ static pointer rebox(pointer b, scaled w)
}
}
-/*
- Here is a subroutine that creates a new glue specification from another
+@ 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.
-*/
+@c
#define mu_mult(A) mult_and_add(n,(A),xn_over_d((A),f,unity),max_dimen)
static pointer math_glue(pointer g, scaled m)
{
pointer p; /* the new glue specification */
- integer n; /* integer part of |m| */
+ int n; /* integer part of |m| */
scaled f; /* fraction part of |m| */
n = x_over_n(m, unity);
f = tex_remainder;
@@ -2054,14 +1659,13 @@ static pointer math_glue(pointer g, scaled m)
return p;
}
-/*
-The |math_kern| subroutine removes |mu_glue| from a kern node, given
+@ The |math_kern| subroutine removes |mu_glue| from a kern node, given
the value of the math unit.
-*/
+@c
static void math_kern(pointer p, scaled m)
{
- integer n; /* integer part of |m| */
+ int n; /* integer part of |m| */
scaled f; /* fraction part of |m| */
if (subtype(p) == mu_glue) {
n = x_over_n(m, unity);
@@ -2075,30 +1679,8 @@ static void math_kern(pointer p, scaled m)
}
}
-/*
- \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@>
-*/
-
-pointer cur_mlist; /* beginning of mlist to be translated */
-integer cur_style; /* style code at current place in the list */
-integer cur_size; /* size code corresponding to |cur_style| */
-scaled cur_mu; /* the math unit width corresponding to |cur_size| */
-boolean mlist_penalties; /* should |mlist_to_hlist| insert penalties? */
-
-void run_mlist_to_hlist(pointer p, integer mstyle, boolean penalties)
+@ @c
+void run_mlist_to_hlist(halfword p, int mstyle, boolean penalties)
{
int callback_id;
int a, sfix;
@@ -2128,17 +1710,12 @@ void run_mlist_to_hlist(pointer p, integer mstyle, boolean penalties)
lua_settop(L, sfix);
vlink(temp_head) = a;
} else if (callback_id == 0) {
- cur_mlist = p;
- cur_style = mstyle;
- mlist_penalties = penalties;
- mlist_to_hlist();
+ mlist_to_hlist_args(p, mstyle, penalties);
} else {
vlink(temp_head) = null;
}
}
-
-/*
@ 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
@@ -2148,46 +1725,42 @@ math style; |mlist_to_hlist| can call |clean_box|, which can call
The box returned by |clean_box| is ``clean'' in the
sense that its |shift_amount| is zero.
-*/
-static pointer clean_box(pointer p, integer s)
+@c
+static pointer clean_box(pointer p, int s, int cur_style)
{
pointer q; /* beginning of a list to be boxed */
- integer save_style; /* |cur_style| to be restored */
pointer x; /* box to be returned */
pointer r; /* temporary pointer */
+ pointer mlist = null; /* beginning of mlist to be translated */
switch (type(p)) {
case math_char_node:
- cur_mlist = new_noad();
+ mlist = new_noad();
r = math_clone(p);
- nucleus(cur_mlist) = r;
+ nucleus(mlist) = r;
break;
case sub_box_node:
q = math_list(p);
goto FOUND;
break;
case sub_mlist_node:
- cur_mlist = math_list(p);
+ mlist = math_list(p);
break;
default:
q = new_null_box();
goto FOUND;
}
- save_style = cur_style;
- cur_style = s;
- mlist_penalties = false;
- mlist_to_hlist();
+ mlist_to_hlist_args(mlist, s, false);
q = vlink(temp_head); /* recursive call */
- cur_style = save_style; /* restore the style */
- setup_cur_size_and_mu();
+ setup_cur_size(cur_style);
FOUND:
if (is_char_node(q) || (q == null))
- x = hpack(q, 0, additional);
+ x = hpack(q, 0, additional, -1);
else if ((vlink(q) == null) && (type(q) <= vlist_node)
&& (shift_amount(q) == 0))
x = q; /* it's already clean */
else
- x = hpack(q, 0, additional);
+ x = hpack(q, 0, additional, -1);
if (x != q && q != null)
reset_attributes(x, node_attr(q));
/* Here we save memory space in a common case. */
@@ -2209,18 +1782,18 @@ static pointer clean_box(pointer p, integer s)
return x;
}
-/*
- It is convenient to have a procedure that converts a |math_char|
+@ 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 |null|.
-*/
-/* The outputs of |fetch| are placed in global variables. */
+The outputs of |fetch| are placed in global variables.
+
+@c
internal_font_number cur_f; /* the |font| field of a |math_char| */
-integer cur_c; /* the |character| field of a |math_char| */
+int cur_c; /* the |character| field of a |math_char| */
static void fetch(pointer a)
{ /* unpack the |math_char| field |a| */
@@ -2248,8 +1821,7 @@ static void fetch(pointer a)
}
-/*
-We need to do a lot of different things, so |mlist_to_hlist| makes two
+@ 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
@@ -2264,8 +1836,8 @@ field, an integer field that replaces the |nucleus| or |thickness|.
The second pass eliminates all noads and inserts the correct glue and
penalties between nodes.
-*/
+@c
static void assign_new_hlist(pointer q, pointer r)
{
switch (type(q)) {
@@ -2290,20 +1862,21 @@ static void assign_new_hlist(pointer q, pointer r)
new_hlist(q) = r;
}
+@ @c
#define choose_mlist(A) do { p=A(q); A(q)=null; } while (0)
-/*
-Most of the actual construction work of |mlist_to_hlist| is done
+
+@ 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.
-*/
-static void make_over(pointer q)
+@c
+static void make_over(pointer q, int cur_style)
{
pointer p;
- p = overbar(clean_box(nucleus(q), cramped_style(cur_style)),
+ p = overbar(clean_box(nucleus(q), cramped_style(cur_style), cur_style),
overbar_vgap(cur_style),
overbar_rule(cur_style),
overbar_kern(cur_style), node_attr(nucleus(q)));
@@ -2311,18 +1884,17 @@ static void make_over(pointer q)
type(nucleus(q)) = sub_box_node;
}
-static void make_under(pointer q)
+static void make_under(pointer q, int cur_style)
{
pointer p, x, y, r; /* temporary registers for box construction */
scaled delta; /* overall height plus depth */
- x = clean_box(nucleus(q), cur_style);
+ x = clean_box(nucleus(q), cur_style, cur_style);
p = new_kern(underbar_vgap(cur_style));
reset_attributes(p, node_attr(q));
vlink(x) = p;
r = do_fraction_rule(underbar_rule(cur_style), node_attr(q));
vlink(p) = r;
- pack_direction = math_direction;
- y = vpackage(x, 0, additional, max_dimen);
+ y = vpackage(x, 0, additional, max_dimen, math_direction);
reset_attributes(y, node_attr(q));
delta = height(y) + depth(y) + underbar_kern(cur_style);
height(y) = height(x);
@@ -2337,13 +1909,12 @@ static void make_vcenter(pointer q)
scaled delta; /* its height plus depth */
v = math_list(nucleus(q));
if (type(v) != vlist_node)
- tconfusion("vcenter"); /* this can't happen vcenter */
+ confusion("vcenter"); /* this can't happen vcenter */
delta = height(v) + depth(v);
height(v) = math_axis(cur_size) + half(delta);
depth(v) = delta - height(v);
}
-/*
@ 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
@@ -2352,23 +1923,23 @@ 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~|psi|. The symbol will be
placed so that the actual clearance is |psi| plus half the excess.
-*/
-static void make_radical(pointer q)
+@c
+static void make_radical(pointer q, int cur_style)
{
pointer x, y, p; /* temporary registers for box construction */
scaled delta, clr, theta, h; /* dimensions involved in the calculation */
- x = clean_box(nucleus(q), cramped_style(cur_style));
+ x = clean_box(nucleus(q), cramped_style(cur_style), cur_style);
clr = radical_vgap(cur_style);
theta = radical_rule(cur_style);
if (theta == undefined_math_parameter) {
theta = fraction_rule(cur_style);
y = var_delimiter(left_delimiter(q), cur_size,
- height(x) + depth(x) + clr + theta);
+ height(x) + depth(x) + clr + theta, NULL, cur_style);
theta = height(y);
} else {
y = var_delimiter(left_delimiter(q), cur_size,
- height(x) + depth(x) + clr + theta);
+ height(x) + depth(x) + clr + theta, NULL, cur_style);
}
left_delimiter(q) = null;
delta = (depth(y) + height(y) - theta) - (height(x) + depth(x) + clr);
@@ -2380,7 +1951,7 @@ static void make_radical(pointer q)
vlink(y) = p;
if (degree(q) != null) {
scaled wr, br, ar;
- pointer r = clean_box(degree(q), script_script_style);
+ pointer r = clean_box(degree(q), script_script_style, cur_style);
reset_attributes(r, node_attr(degree(q)));
wr = width(r);
if (wr == 0) {
@@ -2402,17 +1973,18 @@ static void make_radical(pointer q)
vlink(x) = r;
y = x;
}
- math_list(degree(q)) = null; /* for \Uroot ..{<list>}{} */
+ math_list(degree(q)) = null; /* for \.{\\Uroot ..{<list>}{}} */
flush_node(degree(q));
}
- p = hpack(y, 0, additional);
+ p = hpack(y, 0, additional, -1);
reset_attributes(p, node_attr(q));
math_list(nucleus(q)) = p;
type(nucleus(q)) = sub_box_node;
}
-/* Construct a vlist box */
+@ Construct a vlist box
+@c
static pointer
wrapup_delimiter(pointer x, pointer y, pointer q,
scaled shift_up, scaled shift_down)
@@ -2431,6 +2003,7 @@ wrapup_delimiter(pointer x, pointer y, pointer q,
return v;
}
+@ @c
#define fixup_widths(x,y) do { \
if (width(y) >= width(x)) { \
width(x) = width(y); \
@@ -2439,18 +2012,19 @@ wrapup_delimiter(pointer x, pointer y, pointer q,
} \
} while (0)
-/* this has the |nucleus| box |x| as a limit above an extensible delimiter |y| */
+@ this has the |nucleus| box |x| as a limit above an extensible delimiter |y|
-static void make_over_delimiter(pointer q)
+@c
+static void make_over_delimiter(pointer q, int cur_style)
{
pointer x, y, v; /* temporary registers for box construction */
scaled shift_up, shift_down, clr, delta;
- x = clean_box(nucleus(q), sub_style(cur_style));
- y = flat_var_delimiter(left_delimiter(q), cur_size, width(x));
+ x = clean_box(nucleus(q), sub_style(cur_style), cur_style);
+ y = flat_delimiter(left_delimiter(q), cur_size, width(x), cur_style);
left_delimiter(q) = null;
fixup_widths(x, y);
shift_up = over_delimiter_bgap(cur_style);
- shift_down = 0; /* under_delimiter_bgap(cur_style); */
+ shift_down = 0;
clr = over_delimiter_vgap(cur_style);
delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down));
if (delta > 0) {
@@ -2462,16 +2036,17 @@ static void make_over_delimiter(pointer q)
type(nucleus(q)) = sub_box_node;
}
-/* this has the extensible delimiter |x| as a limit above |nucleus| box |y| */
+@ this has the extensible delimiter |x| as a limit above |nucleus| box |y|
-static void make_delimiter_over(pointer q)
+@c
+static void make_delimiter_over(pointer q, int cur_style)
{
pointer x, y, v; /* temporary registers for box construction */
scaled shift_up, shift_down, clr, delta;
- y = clean_box(nucleus(q), cur_style);
- x = flat_var_delimiter(left_delimiter(q),
- cur_size + (cur_size == script_script_size ? 0 : 1),
- width(y));
+ y = clean_box(nucleus(q), cur_style, cur_style);
+ x = flat_delimiter(left_delimiter(q),
+ cur_size + (cur_size == script_script_size ? 0 : 1),
+ width(y), cur_style);
left_delimiter(q) = null;
fixup_widths(x, y);
shift_up = over_delimiter_bgap(cur_style);
@@ -2488,19 +2063,20 @@ static void make_delimiter_over(pointer q)
}
-/* this has the extensible delimiter |y| as a limit below a |nucleus| box |x| */
+@ this has the extensible delimiter |y| as a limit below a |nucleus| box |x|
-static void make_delimiter_under(pointer q)
+@c
+static void make_delimiter_under(pointer q, int cur_style)
{
pointer x, y, v; /* temporary registers for box construction */
scaled shift_up, shift_down, clr, delta;
- x = clean_box(nucleus(q), cur_style);
- y = flat_var_delimiter(left_delimiter(q),
- cur_size + (cur_size == script_script_size ? 0 : 1),
- width(x));
+ x = clean_box(nucleus(q), cur_style, cur_style);
+ y = flat_delimiter(left_delimiter(q),
+ cur_size + (cur_size == script_script_size ? 0 : 1),
+ width(x), cur_style);
left_delimiter(q) = null;
fixup_widths(x, y);
- shift_up = 0; /* over_delimiter_bgap(cur_style); */
+ shift_up = 0;
shift_down = under_delimiter_bgap(cur_style);
clr = under_delimiter_vgap(cur_style);
delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down));
@@ -2514,17 +2090,18 @@ static void make_delimiter_under(pointer q)
}
-/* this has the extensible delimiter |x| as a limit below |nucleus| box |y| */
+@ this has the extensible delimiter |x| as a limit below |nucleus| box |y|
-static void make_under_delimiter(pointer q)
+@c
+static void make_under_delimiter(pointer q, int cur_style)
{
pointer x, y, v; /* temporary registers for box construction */
scaled shift_up, shift_down, clr, delta;
- y = clean_box(nucleus(q), sup_style(cur_style));
- x = flat_var_delimiter(left_delimiter(q), cur_size, width(y));
+ y = clean_box(nucleus(q), sup_style(cur_style), cur_style);
+ x = flat_delimiter(left_delimiter(q), cur_size, width(y), cur_style);
left_delimiter(q) = null;
fixup_widths(x, y);
- shift_up = 0; /* over_delimiter_bgap(cur_style); */
+ shift_up = 0;
shift_down = under_delimiter_bgap(cur_style);
clr = under_delimiter_vgap(cur_style);
delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down));
@@ -2538,17 +2115,17 @@ static void make_under_delimiter(pointer q)
}
-/*
-Slants are not considered when placing accents in math mode. The accenter is
+
+@ 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.
-*/
+@c
#define TOP_CODE 1
#define BOT_CODE 2
-static void do_make_math_accent(pointer q, internal_font_number f, integer c,
- int top_or_bot)
+static void do_make_math_accent(pointer q, internal_font_number f, int c,
+ int top_or_bot, int cur_style)
{
pointer p, r, x, y; /* temporary registers for box construction */
scaled s; /* amount to skew the accent to the right */
@@ -2583,7 +2160,7 @@ static void do_make_math_accent(pointer q, internal_font_number f, integer c,
}
}
}
- x = clean_box(nucleus(q), cramped_style(cur_style));
+ x = clean_box(nucleus(q), cramped_style(cur_style), cur_style);
w = width(x);
h = height(x);
/* Switch to a larger accent if available and appropriate */
@@ -2595,12 +2172,12 @@ static void do_make_math_accent(pointer q, internal_font_number f, integer c,
scaled w1 = xn_over_d(w, delimiter_factor, 1000);
if (w - w1 > delimiter_shortfall)
w1 = w - delimiter_shortfall;
- y = get_delim_hbox(ext, f, w1, node_attr(attr_p));
+ y = get_delim_hbox(ext, f, w1, node_attr(attr_p), cur_style);
break;
} else if (char_tag(f, c) != list_tag) {
break;
} else {
- integer yy = char_remainder(f, c);
+ int yy = char_remainder(f, c);
if (!char_exists(f, yy))
break;
if (char_width(f, yy) > w)
@@ -2632,7 +2209,7 @@ static void do_make_math_accent(pointer q, internal_font_number f, integer c,
subscr(q) = null;
type(nucleus(q)) = sub_mlist_node;
math_list(nucleus(q)) = x;
- x = clean_box(nucleus(q), cur_style);
+ x = clean_box(nucleus(q), cur_style, cur_style);
delta = delta + height(x) - h;
h = height(x);
}
@@ -2656,17 +2233,16 @@ static void do_make_math_accent(pointer q, internal_font_number f, integer c,
vlink(p) = x;
vlink(y) = p;
} else {
- /*
+#if 0
p = new_kern(-delta);
vlink(x) = p;
vlink(p) = y;
y = x;
- */
+#endif
vlink(x) = y;
y = x;
}
- pack_direction = math_direction;
- r = vpackage(y, 0, additional, max_dimen);
+ r = vpackage(y, 0, additional, max_dimen, math_direction);
reset_attributes(r, node_attr(q));
width(r) = width(x);
y = r;
@@ -2686,12 +2262,12 @@ static void do_make_math_accent(pointer q, internal_font_number f, integer c,
type(nucleus(q)) = sub_box_node;
}
-static void make_math_accent(pointer q)
+static void make_math_accent(pointer q, int cur_style)
{
if (accent_chr(q) != null) {
fetch(accent_chr(q));
if (char_exists(cur_f, cur_c)) {
- do_make_math_accent(q, cur_f, cur_c, TOP_CODE);
+ do_make_math_accent(q, cur_f, cur_c, TOP_CODE, cur_style);
}
flush_node(accent_chr(q));
accent_chr(q) = null;
@@ -2699,19 +2275,18 @@ static void make_math_accent(pointer q)
if (bot_accent_chr(q) != null) {
fetch(bot_accent_chr(q));
if (char_exists(cur_f, cur_c)) {
- do_make_math_accent(q, cur_f, cur_c, BOT_CODE);
+ do_make_math_accent(q, cur_f, cur_c, BOT_CODE, cur_style);
}
flush_node(bot_accent_chr(q));
bot_accent_chr(q) = null;
}
}
-/*
-The |make_fraction| procedure is a bit different because it sets
+@ The |make_fraction| procedure is a bit different because it sets
|new_hlist(q)| directly rather than making a sub-box.
-*/
-static void make_fraction(pointer q)
+@c
+static void make_fraction(pointer q, int cur_style)
{
pointer p, v, x, y, z; /* temporary registers for box construction */
scaled delta, delta1, delta2, shift_up, shift_down, clr;
@@ -2721,8 +2296,8 @@ static void make_fraction(pointer q)
/* Create equal-width boxes |x| and |z| for the numerator and denominator,
and compute the default amounts |shift_up| and |shift_down| by which they
are displaced from the baseline */
- x = clean_box(numerator(q), num_style(cur_style));
- z = clean_box(denominator(q), denom_style(cur_style));
+ x = clean_box(numerator(q), num_style(cur_style), cur_style);
+ z = clean_box(denominator(q), denom_style(cur_style), cur_style);
if (width(x) < width(z))
x = rebox(x, width(z));
else
@@ -2782,20 +2357,19 @@ static void make_fraction(pointer q)
/* Put the fraction into a box with its delimiters, and make |new_hlist(q)|
point to it */
delta = fraction_del_size(cur_style);
- x = var_delimiter(left_delimiter(q), cur_size, delta);
+ x = var_delimiter(left_delimiter(q), cur_size, delta, NULL, cur_style);
left_delimiter(q) = null;
vlink(x) = v;
- z = var_delimiter(right_delimiter(q), cur_size, delta);
+ z = var_delimiter(right_delimiter(q), cur_size, delta, NULL, cur_style);
right_delimiter(q) = null;
vlink(v) = z;
- y = hpack(x, 0, additional);
+ y = hpack(x, 0, additional, -1);
reset_attributes(y, node_attr(q));
assign_new_hlist(q, y);
}
-/*
-If the nucleus of an |op_noad| is a single character, it is to be
+@ If the nucleus of an |op_noad| is a single character, it is to be
centered vertically with respect to the axis, after first being enlarged
(via a character list in the font) if we are in display style. The normal
convention for placing displayed limits is to put them above and below the
@@ -2809,13 +2383,13 @@ subscript and superscript.
After |make_op| has acted, |subtype(q)| will be |limits| if and only if
the limits have been set above and below the operator. In that case,
|new_hlist(q)| will already contain the desired final box.
-*/
-static scaled make_op(pointer q)
+@c
+static scaled make_op(pointer q, int cur_style)
{
scaled delta; /* offset between subscript and superscript */
pointer p, v, x, y, z; /* temporary registers for box construction */
- integer c; /* register for character examination */
+ int c; /* register for character examination */
scaled shift_up, shift_down; /* dimensions for box calculation */
scaled ok_size;
if ((subtype(q) == op_noad_type_normal) && (cur_style < text_style))
@@ -2829,8 +2403,21 @@ static scaled make_op(pointer q)
y = new_node(delim_node, 0);
small_fam(y) = math_fam(nucleus(q));
small_char(y) = math_character(nucleus(q));
- x = var_delimiter(y, text_size, ok_size);
- delta = 0;
+ x = var_delimiter(y, text_size, ok_size, &delta, cur_style);
+ if ((subscr(q) != null) && (subtype(q) != op_noad_type_limits)) {
+ width(x) -= delta; /* remove italic correction */
+ }
+ /* For an OT MATH font, we may have to get rid of yet another italic
+ correction because |make_scripts()| will add one.
+ This test is somewhat more complicated because |x| can be a null
+ delimiter */
+ if ((subscr(q) != null || supscr(q) != null)
+ && (subtype(q) != op_noad_type_limits)
+ && ((list_ptr(x) != null)
+ && (type(list_ptr(x)) == glyph_node)
+ && is_new_mathfont(font(list_ptr(x))))) {
+ width(x) -= delta; /* remove another italic correction */
+ }
} else {
ok_size = height_plus_depth(cur_f, cur_c) + 1;
while ((char_tag(cur_f, cur_c) == list_tag) &&
@@ -2842,7 +2429,7 @@ static scaled make_op(pointer q)
math_character(nucleus(q)) = c;
}
delta = char_italic(cur_f, cur_c);
- x = clean_box(nucleus(q), cur_style);
+ x = clean_box(nucleus(q), cur_style, cur_style);
if ((subscr(q) != null) && (subtype(q) != op_noad_type_limits))
width(x) = width(x) - delta; /* remove italic correction */
shift_amount(x) =
@@ -2854,7 +2441,7 @@ static scaled make_op(pointer q)
} else { /* normal size */
delta = char_italic(cur_f, cur_c);
- x = clean_box(nucleus(q), cur_style);
+ x = clean_box(nucleus(q), cur_style, cur_style);
if ((subscr(q) != null) && (subtype(q) != op_noad_type_limits))
width(x) = width(x) - delta; /* remove italic correction */
shift_amount(x) = half(height(x) - depth(x)) - math_axis(cur_size);
@@ -2868,9 +2455,9 @@ static scaled make_op(pointer q)
if (subtype(q) == op_noad_type_limits) {
/* 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. */
- 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));
+ x = clean_box(supscr(q), sup_style(cur_style), cur_style);
+ y = clean_box(nucleus(q), cur_style, cur_style);
+ z = clean_box(subscr(q), sub_style(cur_style), cur_style);
v = new_null_box();
reset_attributes(v, node_attr(q));
type(v) = vlist_node;
@@ -2945,8 +2532,7 @@ static scaled make_op(pointer q)
return delta;
}
-/*
-A ligature found in a math formula does not create a ligature, because
+@ A ligature found in a math formula does not create a ligature, because
there is no question of hyphenation afterwards; the ligature will simply be
stored in an ordinary |glyph_node|, after residing in an |ord_noad|.
@@ -2955,11 +2541,11 @@ apply an italic correction to the current character unless it belongs
to a math font (i.e., a font with |space=0|).
No boundary characters enter into these ligatures.
-*/
+@c
static void make_ord(pointer q)
{
- integer a; /* the left-side character for lig/kern testing */
+ int a; /* the left-side character for lig/kern testing */
pointer p, r, s; /* temporary registers for list manipulation */
scaled k; /* a kern */
liginfo lig; /* a ligature */
@@ -2995,16 +2581,16 @@ static void make_ord(pointer q)
switch (lig_type(lig)) {
case 1:
case 5:
- math_character(nucleus(q)) = lig_replacement(lig); /* \.{=:|}, \.{=:|>} */
+ math_character(nucleus(q)) = lig_replacement(lig); /* \.{=:\char`\|}, \.{=:\char`\|>} */
break;
case 2:
case 6:
- math_character(nucleus(p)) = lig_replacement(lig); /* \.{|=:}, \.{|=:>} */
+ math_character(nucleus(p)) = lig_replacement(lig); /* \.{\char`\|=:}, \.{\char`\|=:>} */
break;
case 3:
case 7:
case 11:
- r = new_noad(); /* \.{|=:|}, \.{|=:|>}, \.{|=:|>>} */
+ r = new_noad(); /* \.{\char`\|=:\char`\|}, \.{\char`\|=:\char`\|>}, \.{\char`\|=:\char`\|>>} */
reset_attributes(r, node_attr(q));
s = new_node(math_char_node, 0);
reset_attributes(s, node_attr(q));
@@ -3051,23 +2637,23 @@ static void make_ord(pointer q)
}
}
-/* If the fonts for the left and right bits of a mathkern are not
- * both new-style fonts, then return a sentinel value meaning:
- * please use old-style italic correction placement
- */
+@ If the fonts for the left and right bits of a mathkern are not
+both new-style fonts, then return a sentinel value meaning:
+please use old-style italic correction placement
+@c
#define MATH_KERN_NOT_FOUND 0x7FFFFFFF
-/* This function tries to find the kern needed for proper cut-ins.
+@ This function tries to find the kern needed for proper cut-ins.
The left side doesn't move, but the right side does, so the first
order of business is to create a staggered fence line on the
left side of the right character.
The microsoft spec says that there are four quadrants, but the
actual images say
-*/
-static scaled math_kern_at(internal_font_number f, integer c, int side, int v)
+@c
+static scaled math_kern_at(internal_font_number f, int c, int side, int v)
{
int h, k, numkerns;
scaled *kerns_heights;
@@ -3088,7 +2674,7 @@ static scaled math_kern_at(internal_font_number f, integer c, int side, int v)
} else if (side == bottom_right_kern) {
kerns_heights = co->bottom_right_math_kern_array;
} else {
- tconfusion("math_kern_at");
+ confusion("math_kern_at");
kerns_heights = NULL; /* not reached */
}
#ifdef DEBUG
@@ -3110,10 +2696,10 @@ static scaled math_kern_at(internal_font_number f, integer c, int side, int v)
return kern;
}
-
+@ @c
static scaled
-find_math_kern(internal_font_number l_f, integer l_c,
- internal_font_number r_f, integer r_c, int cmd, scaled shift)
+find_math_kern(internal_font_number l_f, int l_c,
+ internal_font_number r_f, int r_c, int cmd, scaled shift)
{
scaled corr_height_top = 0, corr_height_bot = 0;
scaled krn_l = 0, krn_r = 0, krn = 0;
@@ -3159,12 +2745,13 @@ find_math_kern(internal_font_number l_f, integer l_c,
return (krn);
} else {
- tconfusion("find_math_kern");
+ confusion("find_math_kern");
}
return 0; /* not reached */
}
-/* just a small helper */
+@ just a small helper
+@c
static pointer attach_hkern_to_new_hlist(pointer q, scaled delta2)
{
pointer y;
@@ -3180,27 +2767,71 @@ static pointer attach_hkern_to_new_hlist(pointer q, scaled delta2)
return new_hlist(q);
}
+@
+@c
+#ifdef DEBUG
+void dump_simple_field(pointer q)
+{
+ pointer p;
+ printf(" [%d, type=%d, vlink=%d] ", q, type(q), vlink(q));
+ switch (type(q)) {
+ case math_char_node:
+ printf("mathchar ");
+ break;
+ case math_text_char_node:
+ printf("texchar ");
+ break;
+ case sub_box_node:
+ printf("box ");
+ break;
+ case sub_mlist_node:
+ printf("mlist ");
+ p = math_list(q);
+ while (p != null) {
+ dump_simple_field(p);
+ p = vlink(p);
+ }
+ break;
+ }
+}
+void dump_simple_node(pointer q)
+{
+ printf("node %d, type=%d, vlink=%d\n", q, type(q), vlink(q));
+ printf("nucleus: ");
+ dump_simple_field(nucleus(q));
+ printf("\n");
+ printf("sub: ");
+ dump_simple_field(subscr(q));
+ printf("\n");
+ printf("sup: ");
+ dump_simple_field(supscr(q));
+ printf("\n\n");
+}
+#endif
-/*
-The purpose of |make_scripts(q,it)| is to attach the subscript and/or
+@ The purpose of |make_scripts(q,it)| 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 be horizontally shifted over |delta1|, the subscript over |delta2|.
We set |shift_down| and |shift_up| to the minimum amounts to shift the
baseline of subscripts and superscripts based on the given nucleus.
-*/
-
-static void make_scripts(pointer q, pointer p, scaled it)
+@c
+static void make_scripts(pointer q, pointer p, scaled it, int cur_style)
{
pointer x, y, z; /* temporary registers for box construction */
scaled shift_up, shift_down, clr; /* dimensions in the calculation */
scaled delta1, delta2;
delta1 = it;
delta2 = 0;
+#ifdef DEBUG
+ printf("it: %d\n", it);
+ dump_simple_node(q);
+ printf("p: node %d, type=%d, subtype=%d\n", p, type(p), subtype(p));
+#endif
switch (type(nucleus(q))) {
case math_char_node:
case math_text_char_node:
@@ -3216,7 +2847,7 @@ static void make_scripts(pointer q, pointer p, scaled it)
shift_up = 0;
shift_down = 0;
} else {
- z = hpack(p, 0, additional);
+ z = hpack(p, 0, additional, -1);
shift_up = height(z) - sup_shift_drop(cur_style); /* r18 */
shift_down = depth(z) + sub_shift_drop(cur_style); /* r19 */
list_ptr(z) = null;
@@ -3226,7 +2857,7 @@ static void make_scripts(pointer q, pointer p, scaled it)
/* Construct a subscript box |x| when there is no superscript */
/* 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. */
- x = clean_box(subscr(q), sub_style(cur_style));
+ x = clean_box(subscr(q), sub_style(cur_style), cur_style);
width(x) = width(x) + space_after_script(cur_style);
if (shift_down < sub_shift_down(cur_style))
shift_down = sub_shift_down(cur_style);
@@ -3253,7 +2884,7 @@ static void make_scripts(pointer q, pointer p, scaled it)
/* Construct a superscript box |x| */
/*The bottom of a superscript should never descend below the baseline plus
one-fourth of the x-height. */
- x = clean_box(supscr(q), sup_style(cur_style));
+ x = clean_box(supscr(q), sup_style(cur_style), cur_style);
width(x) = width(x) + space_after_script(cur_style);
clr = sup_shift_up(cur_style);
if (shift_up < clr)
@@ -3285,7 +2916,7 @@ static void make_scripts(pointer q, pointer p, scaled it)
both subscript and superscript move up so that the bottom of the superscript
is at least as high as the baseline plus four-fifths of the x-height. */
- y = clean_box(subscr(q), sub_style(cur_style));
+ y = clean_box(subscr(q), sub_style(cur_style), cur_style);
width(y) = width(y) + space_after_script(cur_style);
if (shift_down < sub_sup_shift_down(cur_style))
shift_down = sub_sup_shift_down(cur_style);
@@ -3316,7 +2947,7 @@ static void make_scripts(pointer q, pointer p, scaled it)
/* the superscript is also to be shifted by |delta1| (the italic correction) */
clr = MATH_KERN_NOT_FOUND;
if (is_char_node(p) && supscr(q) != null
- && type(subscr(q)) == math_char_node) {
+ && type(supscr(q)) == math_char_node) {
fetch(supscr(q));
if (char_exists(cur_f, cur_c)) {
clr =
@@ -3335,8 +2966,7 @@ static void make_scripts(pointer q, pointer p, scaled it)
reset_attributes(p, node_attr(q));
vlink(x) = p;
vlink(p) = y;
- pack_direction = math_direction;
- x = vpackage(x, 0, additional, max_dimen);
+ x = vpackage(x, 0, additional, max_dimen, math_direction);
reset_attributes(x, node_attr(q));
shift_amount(x) = shift_down;
}
@@ -3364,20 +2994,18 @@ static void make_scripts(pointer q, pointer p, scaled it)
}
-/*
-The |make_left_right| function constructs a left or right delimiter of
+@ 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
|left_noad_side| and |right_noad_side| will both be based on the original |style|,
so they will have consistent sizes.
-*/
-static small_number make_left_right(pointer q, integer style, scaled max_d,
- scaled max_hv)
+@c
+static small_number make_left_right(pointer q, int style, scaled max_d,
+ scaled max_hv)
{
scaled delta, delta1, delta2; /* dimensions used in the calculation */
pointer tmp;
- cur_style = style;
- setup_cur_size_and_mu();
+ setup_cur_size(style);
delta2 = max_d + math_axis(cur_size);
delta1 = max_hv + max_d - delta2;
if (delta2 > delta1)
@@ -3386,7 +3014,7 @@ static small_number make_left_right(pointer q, integer style, scaled max_d,
delta2 = delta1 + delta1 - delimiter_shortfall;
if (delta < delta2)
delta = delta2;
- tmp = var_delimiter(delimiter(q), cur_size, delta);
+ tmp = var_delimiter(delimiter(q), cur_size, delta, NULL, style);
delimiter(q) = null;
assign_new_hlist(q, tmp);
if (subtype(q) == left_noad_side)
@@ -3395,7 +3023,7 @@ static small_number make_left_right(pointer q, integer style, scaled max_d,
return close_noad_type;
}
-
+@ @c
#define TEXT_STYLES(A,B) do { \
def_math_param(A,display_style,(B),level_one); \
def_math_param(A,cramped_display_style,(B),level_one); \
@@ -3425,40 +3053,40 @@ void initialize_math_spacing(void)
{
/* *INDENT-OFF* */
ALL_STYLES (math_param_ord_ord_spacing, 0);
- ALL_STYLES (math_param_ord_op_spacing, thin_mu_skip);
- SPLIT_STYLES (math_param_ord_bin_spacing, med_mu_skip, 0);
- SPLIT_STYLES (math_param_ord_rel_spacing, thick_mu_skip, 0);
+ ALL_STYLES (math_param_ord_op_spacing, thin_mu_skip_code);
+ SPLIT_STYLES (math_param_ord_bin_spacing, med_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_ord_rel_spacing, thick_mu_skip_code, 0);
ALL_STYLES (math_param_ord_open_spacing, 0);
ALL_STYLES (math_param_ord_close_spacing, 0);
ALL_STYLES (math_param_ord_punct_spacing, 0);
- SPLIT_STYLES (math_param_ord_inner_spacing, thin_mu_skip, 0);
+ SPLIT_STYLES (math_param_ord_inner_spacing, thin_mu_skip_code, 0);
- ALL_STYLES (math_param_op_ord_spacing, thin_mu_skip);
- ALL_STYLES (math_param_op_op_spacing, thin_mu_skip);
+ ALL_STYLES (math_param_op_ord_spacing, thin_mu_skip_code);
+ ALL_STYLES (math_param_op_op_spacing, thin_mu_skip_code);
ALL_STYLES (math_param_op_bin_spacing, 0);
- SPLIT_STYLES (math_param_op_rel_spacing, thick_mu_skip, 0);
+ SPLIT_STYLES (math_param_op_rel_spacing, thick_mu_skip_code, 0);
ALL_STYLES (math_param_op_open_spacing, 0);
ALL_STYLES (math_param_op_close_spacing, 0);
ALL_STYLES (math_param_op_punct_spacing, 0);
- SPLIT_STYLES (math_param_op_inner_spacing, thin_mu_skip, 0);
+ SPLIT_STYLES (math_param_op_inner_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_bin_ord_spacing, med_mu_skip, 0);
- SPLIT_STYLES (math_param_bin_op_spacing, med_mu_skip, 0);
+ SPLIT_STYLES (math_param_bin_ord_spacing, med_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_bin_op_spacing, med_mu_skip_code, 0);
ALL_STYLES (math_param_bin_bin_spacing, 0);
ALL_STYLES (math_param_bin_rel_spacing, 0);
- SPLIT_STYLES (math_param_bin_open_spacing, med_mu_skip, 0);
+ SPLIT_STYLES (math_param_bin_open_spacing, med_mu_skip_code, 0);
ALL_STYLES (math_param_bin_close_spacing, 0);
ALL_STYLES (math_param_bin_punct_spacing, 0);
- SPLIT_STYLES (math_param_bin_inner_spacing, med_mu_skip, 0);
+ SPLIT_STYLES (math_param_bin_inner_spacing, med_mu_skip_code, 0);
- SPLIT_STYLES (math_param_rel_ord_spacing, thick_mu_skip, 0);
- SPLIT_STYLES (math_param_rel_op_spacing, thick_mu_skip, 0);
+ SPLIT_STYLES (math_param_rel_ord_spacing, thick_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_rel_op_spacing, thick_mu_skip_code, 0);
ALL_STYLES (math_param_rel_bin_spacing, 0);
ALL_STYLES (math_param_rel_rel_spacing, 0);
- SPLIT_STYLES (math_param_rel_open_spacing, thick_mu_skip, 0);
+ SPLIT_STYLES (math_param_rel_open_spacing, thick_mu_skip_code, 0);
ALL_STYLES (math_param_rel_close_spacing, 0);
ALL_STYLES (math_param_rel_punct_spacing, 0);
- SPLIT_STYLES (math_param_rel_inner_spacing, thick_mu_skip, 0);
+ SPLIT_STYLES (math_param_rel_inner_spacing, thick_mu_skip_code, 0);
ALL_STYLES (math_param_open_ord_spacing, 0);
ALL_STYLES (math_param_open_op_spacing, 0);
@@ -3470,38 +3098,39 @@ void initialize_math_spacing(void)
ALL_STYLES (math_param_open_inner_spacing, 0);
ALL_STYLES (math_param_close_ord_spacing, 0);
- ALL_STYLES (math_param_close_op_spacing, thin_mu_skip);
- SPLIT_STYLES (math_param_close_bin_spacing, med_mu_skip, 0);
- SPLIT_STYLES (math_param_close_rel_spacing, thick_mu_skip, 0);
+ ALL_STYLES (math_param_close_op_spacing, thin_mu_skip_code);
+ SPLIT_STYLES (math_param_close_bin_spacing, med_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_close_rel_spacing, thick_mu_skip_code, 0);
ALL_STYLES (math_param_close_open_spacing, 0);
ALL_STYLES (math_param_close_close_spacing, 0);
ALL_STYLES (math_param_close_punct_spacing, 0);
- SPLIT_STYLES (math_param_close_inner_spacing, thin_mu_skip, 0);
+ SPLIT_STYLES (math_param_close_inner_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_punct_ord_spacing, thin_mu_skip, 0);
- SPLIT_STYLES (math_param_punct_op_spacing, thin_mu_skip, 0);
+ SPLIT_STYLES (math_param_punct_ord_spacing, thin_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_punct_op_spacing, thin_mu_skip_code, 0);
ALL_STYLES (math_param_punct_bin_spacing, 0);
- SPLIT_STYLES (math_param_punct_rel_spacing, thin_mu_skip, 0);
- SPLIT_STYLES (math_param_punct_open_spacing, thin_mu_skip, 0);
- SPLIT_STYLES (math_param_punct_close_spacing, thin_mu_skip, 0);
- SPLIT_STYLES (math_param_punct_punct_spacing, thin_mu_skip, 0);
- SPLIT_STYLES (math_param_punct_inner_spacing, thin_mu_skip, 0);
-
- SPLIT_STYLES (math_param_inner_ord_spacing, thin_mu_skip, 0);
- ALL_STYLES (math_param_inner_op_spacing, thin_mu_skip);
- SPLIT_STYLES (math_param_inner_bin_spacing, med_mu_skip, 0);
- SPLIT_STYLES (math_param_inner_rel_spacing, thick_mu_skip, 0);
- SPLIT_STYLES (math_param_inner_open_spacing, thin_mu_skip, 0);
+ SPLIT_STYLES (math_param_punct_rel_spacing, thin_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_punct_open_spacing, thin_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_punct_close_spacing, thin_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_punct_punct_spacing, thin_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_punct_inner_spacing, thin_mu_skip_code, 0);
+
+ SPLIT_STYLES (math_param_inner_ord_spacing, thin_mu_skip_code, 0);
+ ALL_STYLES (math_param_inner_op_spacing, thin_mu_skip_code);
+ SPLIT_STYLES (math_param_inner_bin_spacing, med_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_inner_rel_spacing, thick_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_inner_open_spacing, thin_mu_skip_code, 0);
ALL_STYLES (math_param_inner_close_spacing, 0);
- SPLIT_STYLES (math_param_inner_punct_spacing, thin_mu_skip, 0);
- SPLIT_STYLES (math_param_inner_inner_spacing, thin_mu_skip, 0);
+ SPLIT_STYLES (math_param_inner_punct_spacing, thin_mu_skip_code, 0);
+ SPLIT_STYLES (math_param_inner_inner_spacing, thin_mu_skip_code, 0);
/* *INDENT-ON* */
}
+@ @c
#define both_types(A,B) ((A)*16+(B))
-static pointer math_spacing_glue(int l_type, int r_type, int mstyle)
+static pointer math_spacing_glue(int l_type, int r_type, int mstyle, scaled mmu)
{
int x = -1;
pointer z = null;
@@ -3521,7 +3150,9 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle)
case both_types(ord_noad_type, inner_noad_type): x = get_math_param(math_param_ord_inner_spacing,mstyle); break;
case both_types(op_noad_type_normal, ord_noad_type ): x = get_math_param(math_param_op_ord_spacing,mstyle); break;
case both_types(op_noad_type_normal, op_noad_type_normal ): x = get_math_param(math_param_op_op_spacing,mstyle); break;
- /*case both_types(op_noad_type_normal, bin_noad_type ): x = get_math_param(math_param_op_bin_spacing,mstyle); break;*/
+#if 0
+ case both_types(op_noad_type_normal, bin_noad_type ): x = get_math_param(math_param_op_bin_spacing,mstyle); break;
+#endif
case both_types(op_noad_type_normal, rel_noad_type ): x = get_math_param(math_param_op_rel_spacing,mstyle); break;
case both_types(op_noad_type_normal, open_noad_type ): x = get_math_param(math_param_op_open_spacing,mstyle); break;
case both_types(op_noad_type_normal, close_noad_type): x = get_math_param(math_param_op_close_spacing,mstyle); break;
@@ -3529,15 +3160,21 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle)
case both_types(op_noad_type_normal, inner_noad_type): x = get_math_param(math_param_op_inner_spacing,mstyle); break;
case both_types(bin_noad_type, ord_noad_type ): x = get_math_param(math_param_bin_ord_spacing,mstyle); break;
case both_types(bin_noad_type, op_noad_type_normal ): x = get_math_param(math_param_bin_op_spacing,mstyle); break;
- /*case both_types(bin_noad_type, bin_noad_type ): x = get_math_param(math_param_bin_bin_spacing,mstyle); break;*/
- /*case both_types(bin_noad_type, rel_noad_type ): x = get_math_param(math_param_bin_rel_spacing,mstyle); break;*/
+#if 0
+ case both_types(bin_noad_type, bin_noad_type ): x = get_math_param(math_param_bin_bin_spacing,mstyle); break;
+ case both_types(bin_noad_type, rel_noad_type ): x = get_math_param(math_param_bin_rel_spacing,mstyle); break;
+#endif
case both_types(bin_noad_type, open_noad_type ): x = get_math_param(math_param_bin_open_spacing,mstyle); break;
- /*case both_types(bin_noad_type, close_noad_type): x = get_math_param(math_param_bin_close_spacing,mstyle); break;*/
- /*case both_types(bin_noad_type, punct_noad_type): x = get_math_param(math_param_bin_punct_spacing,mstyle); break;*/
+#if 0
+ case both_types(bin_noad_type, close_noad_type): x = get_math_param(math_param_bin_close_spacing,mstyle); break;
+ case both_types(bin_noad_type, punct_noad_type): x = get_math_param(math_param_bin_punct_spacing,mstyle); break;
+#endif
case both_types(bin_noad_type, inner_noad_type): x = get_math_param(math_param_bin_inner_spacing,mstyle); break;
case both_types(rel_noad_type, ord_noad_type ): x = get_math_param(math_param_rel_ord_spacing,mstyle); break;
case both_types(rel_noad_type, op_noad_type_normal ): x = get_math_param(math_param_rel_op_spacing,mstyle); break;
- /*case both_types(rel_noad_type, bin_noad_type ): x = get_math_param(math_param_rel_bin_spacing,mstyle); break;*/
+#if 0
+ case both_types(rel_noad_type, bin_noad_type ): x = get_math_param(math_param_rel_bin_spacing,mstyle); break;
+#endif
case both_types(rel_noad_type, rel_noad_type ): x = get_math_param(math_param_rel_rel_spacing,mstyle); break;
case both_types(rel_noad_type, open_noad_type ): x = get_math_param(math_param_rel_open_spacing,mstyle); break;
case both_types(rel_noad_type, close_noad_type): x = get_math_param(math_param_rel_close_spacing,mstyle); break;
@@ -3545,7 +3182,9 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle)
case both_types(rel_noad_type, inner_noad_type): x = get_math_param(math_param_rel_inner_spacing,mstyle); break;
case both_types(open_noad_type, ord_noad_type ): x = get_math_param(math_param_open_ord_spacing,mstyle); break;
case both_types(open_noad_type, op_noad_type_normal ): x = get_math_param(math_param_open_op_spacing,mstyle); break;
- /*case both_types(open_noad_type, bin_noad_type ): x = get_math_param(math_param_open_bin_spacing,mstyle); break;*/
+#if 0
+ case both_types(open_noad_type, bin_noad_type ): x = get_math_param(math_param_open_bin_spacing,mstyle); break;
+#endif
case both_types(open_noad_type, rel_noad_type ): x = get_math_param(math_param_open_rel_spacing,mstyle); break;
case both_types(open_noad_type, open_noad_type ): x = get_math_param(math_param_open_open_spacing,mstyle); break;
case both_types(open_noad_type, close_noad_type): x = get_math_param(math_param_open_close_spacing,mstyle); break;
@@ -3561,7 +3200,9 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle)
case both_types(close_noad_type,inner_noad_type): x = get_math_param(math_param_close_inner_spacing,mstyle); break;
case both_types(punct_noad_type,ord_noad_type ): x = get_math_param(math_param_punct_ord_spacing,mstyle); break;
case both_types(punct_noad_type,op_noad_type_normal ): x = get_math_param(math_param_punct_op_spacing,mstyle); break;
- /*case both_types(punct_noad_type,bin_noad_type ): x = get_math_param(math_param_punct_bin_spacing,mstyle); break;*/
+#if 0
+ case both_types(punct_noad_type,bin_noad_type ): x = get_math_param(math_param_punct_bin_spacing,mstyle); break;
+#endif
case both_types(punct_noad_type,rel_noad_type ): x = get_math_param(math_param_punct_rel_spacing,mstyle); break;
case both_types(punct_noad_type,open_noad_type ): x = get_math_param(math_param_punct_open_spacing,mstyle); break;
case both_types(punct_noad_type,close_noad_type): x = get_math_param(math_param_punct_close_spacing,mstyle); break;
@@ -3578,17 +3219,17 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle)
/* *INDENT-ON* */
}
if (x < 0) {
- tconfusion("mathspacing");
+ confusion("mathspacing");
}
if (x != 0) {
pointer y;
- if (x <= thick_mu_skip) { /* trap thin/med/thick settings cf. old TeX */
- y = math_glue(glue_par(x), cur_mu);
+ if (x <= thick_mu_skip_code) { /* trap thin/med/thick settings cf. old TeX */
+ y = math_glue(glue_par(x), mmu);
z = new_glue(y);
glue_ref_count(y) = null;
- subtype(z) = x + 1; /* store a symbolic subtype */
+ subtype(z) = (quarterword) (x + 1); /* store a symbolic subtype */
} else {
- y = math_glue(x, cur_mu);
+ y = math_glue(x, mmu);
z = new_glue(y);
glue_ref_count(y) = null;
}
@@ -3596,32 +3237,66 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle)
return z;
}
+@ @c
+static pointer check_nucleus_complexity(halfword q, scaled * delta,
+ int cur_style)
+{
+ pointer p = null;
+ switch (type(nucleus(q))) {
+ case math_char_node:
+ case math_text_char_node:
+ fetch(nucleus(q));
+ if (char_exists(cur_f, cur_c)) {
+ *delta = char_italic(cur_f, cur_c);
+ p = new_glyph(cur_f, cur_c);
+ reset_attributes(p, node_attr(nucleus(q)));
+ if ((is_new_mathfont(cur_f) && get_char_cat_code(cur_c) == 11) ||
+ (!is_new_mathfont(cur_f) && type(nucleus(q)) == math_text_char_node && space(cur_f)) != 0) {
+ *delta = 0; /* no italic correction in mid-word of text font */
+ }
+ if ((subscr(q) == null) && (supscr(q) == null) && (*delta != 0)) {
+ pointer x = new_kern(*delta);
+ reset_attributes(x, node_attr(nucleus(q)));
+ vlink(p) = x;
+ *delta = 0;
+ }
+ }
+ break;
+ case sub_box_node:
+ p = math_list(nucleus(q));
+ break;
+ case sub_mlist_node:
+ mlist_to_hlist_args(math_list(nucleus(q)), cur_style, false); /* recursive call */
+ setup_cur_size(cur_style);
+ p = hpack(vlink(temp_head), 0, additional, -1);
+ reset_attributes(p, node_attr(nucleus(q)));
+ break;
+ default:
+ confusion("mlist2"); /* this can't happen mlist2 */
+ }
+ return p;
+}
-
-/* Here is the overall plan of |mlist_to_hlist|, and the list of its
+@ Here is the overall plan of |mlist_to_hlist|, and the list of its
local variables.
-*/
-void mlist_to_hlist(void)
+@c
+static void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style)
{
- pointer mlist; /* beginning of the given list */
- boolean penalties; /* should penalty nodes be inserted? */
- integer style; /* the given style */
- integer save_style; /* holds |cur_style| during recursion */
pointer q; /* runs through the mlist */
pointer r; /* the most recent noad preceding |q| */
- integer r_type; /* the |type| of noad |r|, or |op_noad| if |r=null| */
- integer r_subtype; /* the |subtype| of noad |r| if |r_type| is |fence_noad| */
- integer t; /* the effective |type| of noad |q| during the second pass */
- integer t_subtype; /* the effective |subtype| of noad |q| during the second pass */
+ int style;
+ int r_type; /* the |type| of noad |r|, or |op_noad| if |r=null| */
+ int r_subtype; /* the |subtype| of noad |r| if |r_type| is |fence_noad| */
+ int t; /* the effective |type| of noad |q| during the second pass */
+ int t_subtype; /* the effective |subtype| of noad |q| during the second pass */
pointer p, x, y, z; /* temporary registers for list construction */
- integer pen; /* a penalty to be inserted */
- integer s; /* the size of a noad to be deleted */
+ int pen; /* a penalty to be inserted */
+ int s; /* the size of a noad to be deleted */
scaled max_hl, max_d; /* maximum height and depth of the list translated so far */
scaled delta; /* italic correction offset for subscript and superscript */
- mlist = cur_mlist;
- penalties = mlist_penalties;
- style = cur_style; /* tuck global parameters away as local variables */
+ scaled cur_mu; /* the math unit width corresponding to |cur_size| */
+ style = cur_style; /* tuck global parameter away as local variable */
q = mlist;
r = null;
r_type = simple_noad;
@@ -3630,7 +3305,8 @@ void mlist_to_hlist(void)
max_d = 0;
x = null;
p = null;
- setup_cur_size_and_mu();
+ setup_cur_size(cur_style);
+ cur_mu = x_over_n(get_math_quad(cur_size), 18);
while (q != null) {
/* We use the fact that no character nodes appear in an mlist, hence
the field |type(q)| is always present. */
@@ -3668,10 +3344,10 @@ void mlist_to_hlist(void)
}
break;
case over_noad_type:
- make_over(q);
+ make_over(q, cur_style);
break;
case under_noad_type:
- make_under(q);
+ make_under(q, cur_style);
break;
case vcenter_noad_type:
make_vcenter(q);
@@ -3687,7 +3363,7 @@ void mlist_to_hlist(void)
case op_noad_type_normal:
case op_noad_type_limits:
case op_noad_type_no_limits:
- delta = make_op(q);
+ delta = make_op(q, cur_style);
if (subtype(q) == op_noad_type_limits)
goto CHECK_DIMENSIONS;
break;
@@ -3708,27 +3384,28 @@ void mlist_to_hlist(void)
goto DONE_WITH_NOAD;
break;
case fraction_noad:
- make_fraction(q);
+ make_fraction(q, cur_style);
goto CHECK_DIMENSIONS;
break;
case radical_noad:
if (subtype(q) == 4)
- make_under_delimiter(q);
+ make_under_delimiter(q, cur_style);
else if (subtype(q) == 5)
- make_over_delimiter(q);
+ make_over_delimiter(q, cur_style);
else if (subtype(q) == 6)
- make_delimiter_under(q);
+ make_delimiter_under(q, cur_style);
else if (subtype(q) == 7)
- make_delimiter_over(q);
+ make_delimiter_over(q, cur_style);
else
- make_radical(q);
+ make_radical(q, cur_style);
break;
case accent_noad:
- make_math_accent(q);
+ make_math_accent(q, cur_style);
break;
case style_node:
cur_style = subtype(q);
- setup_cur_size_and_mu();
+ setup_cur_size(cur_style);
+ cur_mu = x_over_n(get_math_quad(cur_size), 18);
goto DONE_WITH_NODE;
break;
case choice_node:
@@ -3751,7 +3428,7 @@ void mlist_to_hlist(void)
flush_node_list(script_mlist(q));
flush_node_list(script_script_mlist(q));
type(q) = style_node;
- subtype(q) = cur_style;
+ subtype(q) = (quarterword) cur_style;
if (p != null) {
z = vlink(q);
vlink(q) = p;
@@ -3783,8 +3460,7 @@ void mlist_to_hlist(void)
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@>
+ by |cur_mu|.
*/
if (subtype(q) == mu_glue) {
x = glue_ptr(q);
@@ -3809,7 +3485,7 @@ void mlist_to_hlist(void)
goto DONE_WITH_NODE;
break;
default:
- tconfusion("mlist1"); /* this can't happen mlist1 */
+ confusion("mlist1"); /* this can't happen mlist1 */
}
/* 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
@@ -3820,59 +3496,22 @@ void mlist_to_hlist(void)
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@>
*/
- switch (type(nucleus(q))) {
- case math_char_node:
- case math_text_char_node:
- fetch(nucleus(q));
- if (char_exists(cur_f, cur_c)) {
- delta = char_italic(cur_f, cur_c);
- p = new_glyph(cur_f, cur_c);
- reset_attributes(p, node_attr(nucleus(q)));
- if ((type(nucleus(q)) == math_text_char_node)
- && (space(cur_f) != 0))
- delta = 0; /* no italic correction in mid-word of text font */
- if ((subscr(q) == null) && (supscr(q) == null) && (delta != 0)) {
- x = new_kern(delta);
- reset_attributes(x, node_attr(nucleus(q)));
- vlink(p) = x;
- delta = 0;
- }
- } else {
- p = null;
- }
- break;
- case sub_box_node:
- p = math_list(nucleus(q));
- break;
- case sub_mlist_node:
- cur_mlist = math_list(nucleus(q));
- save_style = cur_style;
- mlist_penalties = false;
- mlist_to_hlist(); /* recursive call */
- cur_style = save_style;
- setup_cur_size_and_mu();
- p = hpack(vlink(temp_head), 0, additional);
- reset_attributes(p, node_attr(nucleus(q)));
- break;
- default:
- tconfusion("mlist2"); /* this can't happen mlist2 */
- }
+ p = check_nucleus_complexity(q, &delta, cur_style);
+
if ((subscr(q) == null) && (supscr(q) == null)) {
assign_new_hlist(q, p);
- goto CHECK_DIMENSIONS;
+ } else {
+ make_scripts(q, p, delta, cur_style); /* top, bottom */
}
- make_scripts(q, p, delta); /* top, bottom */
CHECK_DIMENSIONS:
- z = hpack(new_hlist(q), 0, additional);
+ z = hpack(new_hlist(q), 0, additional, -1);
if (height(z) > max_hl)
max_hl = height(z);
if (depth(z) > max_d)
max_d = depth(z);
list_ptr(z) = null;
- flush_node(z); /* only drop the \hbox */
+ flush_node(z); /* only drop the \.{\\hbox} */
DONE_WITH_NOAD:
r = q;
r_type = type(r);
@@ -3880,7 +3519,8 @@ void mlist_to_hlist(void)
if (r_type == fence_noad) {
r_subtype = left_noad_side;
cur_style = style;
- setup_cur_size_and_mu();
+ setup_cur_size(cur_style);
+ cur_mu = x_over_n(get_math_quad(cur_size), 18);
}
DONE_WITH_NODE:
q = vlink(q);
@@ -3904,7 +3544,8 @@ void mlist_to_hlist(void)
r_type = 0;
r_subtype = 0;
cur_style = style;
- setup_cur_size_and_mu();
+ setup_cur_size(cur_style);
+ cur_mu = x_over_n(get_math_quad(cur_size), 18);
NEXT_NODE:
while (q != null) {
/* If node |q| is a style node, change the style and |goto delete_q|;
@@ -3952,7 +3593,8 @@ void mlist_to_hlist(void)
/* Change the current style and |goto delete_q| */
cur_style = subtype(q);
s = style_node_size;
- setup_cur_size_and_mu();
+ setup_cur_size(cur_style);
+ cur_mu = x_over_n(get_math_quad(cur_size), 18);
goto DELETE_Q;
break;
case whatsit_node:
@@ -3971,11 +3613,11 @@ void mlist_to_hlist(void)
goto NEXT_NODE;
break;
default:
- tconfusion("mlist3"); /* this can't happen mlist3 */
+ confusion("mlist3"); /* this can't happen mlist3 */
}
/* Append inter-element spacing based on |r_type| and |t| */
if (r_type > 0) { /* not the first noad */
- z = math_spacing_glue(r_subtype, t_subtype, cur_style);
+ z = math_spacing_glue(r_subtype, t_subtype, cur_style, cur_mu);
if (z != null) {
reset_attributes(z, node_attr(p));
vlink(p) = z;
@@ -4026,3 +3668,12 @@ void mlist_to_hlist(void)
free_node(r, get_node_size(type(r), subtype(r)));
}
}
+
+@ This used to be needed when |mlist_to_hlist| communicated via global
+variables.
+
+@c
+void mlist_to_hlist_args(pointer n, int w, boolean m)
+{
+ mlist_to_hlist(n, m, w);
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/nesting.h b/Build/source/texk/web2c/luatexdir/tex/nesting.h
new file mode 100644
index 00000000000..c46875ad8c6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/nesting.h
@@ -0,0 +1,71 @@
+/* nesting.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: nesting.h 3477 2010-03-12 13:59:34Z taco $ */
+
+#ifndef NESTING_H
+# define NESTING_H
+
+# define vmode 1 /* vertical mode */
+# define hmode (vmode+max_command_cmd+1)
+ /* horizontal mode */
+# define mmode (hmode+max_command_cmd+1)
+ /* math mode */
+
+extern void print_mode(int m);
+extern void print_in_mode(int m);
+extern int get_mode_id(void);
+
+# define ignore_depth -65536000 /* magic dimension value to mean `ignore me' */
+
+typedef struct list_state_record_ {
+ int mode_field;
+ halfword head_field;
+ halfword tail_field;
+ halfword eTeX_aux_field;
+ int pg_field;
+ int ml_field;
+ halfword prev_depth_field;
+ halfword space_factor_field;
+ halfword incompleat_noad_field;
+ halfword dirs_field;
+ int math_field;
+ int math_style_field;
+} list_state_record;
+
+extern list_state_record *nest;
+extern int nest_ptr;
+extern int max_nest_stack;
+# define cur_list nest[nest_ptr]
+ /* the ``top'' semantic state */
+extern int shown_mode;
+extern halfword save_tail;
+
+extern void push_nest(void);
+extern void pop_nest(void);
+extern void initialize_nesting(void);
+
+extern void tail_append(halfword p);
+extern halfword pop_tail(void);
+
+
+extern void show_activities(void);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/nesting.w b/Build/source/texk/web2c/luatexdir/tex/nesting.w
new file mode 100644
index 00000000000..28ae086d461
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/nesting.w
@@ -0,0 +1,447 @@
+% nesting.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: nesting.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/nesting.w $";
+
+
+@ these are for |show_activities|
+@c
+#define page_goal page_so_far[0]
+#define pdf_ignored_dimen dimen_par(pdf_ignored_dimen_code)
+#define count(A) eqtb[count_base+(A)].cint
+
+
+@ \TeX\ is typically in the midst of building many lists at once. For example,
+when a math formula is being processed, \TeX\ is in math mode and
+working on an mlist; this formula has temporarily interrupted \TeX\ from
+being in horizontal mode and building the hlist of a paragraph; and this
+paragraph has temporarily interrupted \TeX\ from being in vertical mode
+and building the vlist for the next page of a document. Similarly, when a
+\.{\\vbox} occurs inside of an \.{\\hbox}, \TeX\ is temporarily
+interrupted from working in restricted horizontal mode, and it enters
+internal vertical mode. The ``semantic nest'' is a stack that
+keeps track of what lists and modes are currently suspended.
+
+At each level of processing we are in one of six modes:
+
+\yskip\hang|vmode| stands for vertical mode (the page builder);
+
+\hang|hmode| stands for horizontal mode (the paragraph builder);
+
+\hang|mmode| stands for displayed formula mode;
+
+\hang|-vmode| stands for internal vertical mode (e.g., in a \.{\\vbox});
+
+\hang|-hmode| stands for restricted horizontal mode (e.g., in an \.{\\hbox});
+
+\hang|-mmode| stands for math formula mode (not displayed).
+
+\yskip\noindent The mode is temporarily set to zero while processing \.{\\write}
+texts in the |ship_out| routine.
+
+Numeric values are assigned to |vmode|, |hmode|, and |mmode| so that
+\TeX's ``big semantic switch'' can select the appropriate thing to
+do by computing the value |abs(mode)+cur_cmd|, where |mode| is the current
+mode and |cur_cmd| is the current command code.
+
+@c
+const char *string_mode(int m)
+{ /* prints the mode represented by |m| */
+ if (m > 0) {
+ switch (m / (max_command_cmd + 1)) {
+ case 0:
+ return "vertical mode";
+ break;
+ case 1:
+ return "horizontal mode";
+ break;
+ case 2:
+ return "display math mode";
+ break;
+ default:
+ break;
+ }
+ } else if (m == 0) {
+ return "no mode";
+ } else {
+ switch ((-m) / (max_command_cmd + 1)) {
+ case 0:
+ return "internal vertical mode";
+ break;
+ case 1:
+ return "restricted horizontal mode";
+ break;
+ case 2:
+ return "math mode";
+ break;
+ default:
+ break;
+ }
+ }
+ return "unknown mode";
+}
+
+@ @c
+void print_mode(int m)
+{ /* prints the mode represented by |m| */
+ tprint(string_mode(m));
+}
+
+@ @c
+void print_in_mode(int m)
+{ /* prints the mode represented by |m| */
+ tprint("' in ");
+ tprint(string_mode(m));
+}
+
+@ @c
+int get_mode_id(void)
+{ /* returns the mode represented by |m| */
+ int m = cur_list.mode_field;
+ if (m > 0) {
+ switch (m / (max_command_cmd + 1)) {
+ case 0:
+ return 'v';
+ break;
+ case 1:
+ return 'h';
+ break;
+ case 2:
+ return 'm';
+ break;
+ default:
+ return '\0';
+ break;
+ }
+ } else if (m == 0) {
+ return 'n';;
+ } else {
+ switch ((-m) / (max_command_cmd + 1)) {
+ case 0:
+ return 'V';
+ break;
+ case 1:
+ return 'H';
+ break;
+ case 2:
+ return 'M';
+ break;
+ default:
+ return '\0';
+ break;
+ }
+ }
+}
+
+
+@ The state of affairs at any semantic level can be represented by
+five values:
+
+\yskip\hang|mode| is the number representing the semantic mode, as
+just explained.
+
+\yskip\hang|head| is a |pointer| to a list head for the list being built;
+|link(head)| therefore points to the first element of the list, or
+to |null| if the list is empty.
+
+\yskip\hang|tail| is a |pointer| to the final node of the list being
+built; thus, |tail=head| if and only if the list is empty.
+
+\yskip\hang|prev_graf| is the number of lines of the current paragraph that
+have already been put into the present vertical list.
+
+\yskip\hang|aux| is an auxiliary |memory_word| that gives further information
+that is needed to characterize the situation.
+
+\yskip\noindent
+In vertical mode, |aux| is also known as |prev_depth|; it is the scaled
+value representing the depth of the previous box, for use in baseline
+calculations, or it is |<=-1000|pt if the next box on the vertical list is to
+be exempt from baseline calculations. In horizontal mode, |aux| is also
+known as |space_factor|; it holds the current space factor used in
+spacing calculations. In math mode, |aux| is also known as |incompleat_noad|;
+if not |null|, it points to a record that represents the numerator of a
+generalized fraction for which the denominator is currently being formed
+in the current list.
+
+There is also a sixth quantity, |mode_line|, which correlates
+the semantic nest with the user's input; |mode_line| contains the source
+line number at which the current level of nesting was entered. The negative
+of this line number is the |mode_line| at the level of the
+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 |fence_noad| of a |math_left_group|.
+
+In horizontal mode, the |prev_graf| field is used for initial language data.
+
+The semantic nest is an array called |nest| that holds the |mode|, |head|,
+|tail|, |prev_graf|, |aux|, and |mode_line| values for all semantic levels
+below the currently active one. Information about the currently active
+level is kept in the global quantities |mode|, |head|, |tail|, |prev_graf|,
+|aux|, and |mode_line|, which live in a struct that is ready to
+be pushed onto |nest| if necessary.
+
+The math field is used by various bits and pieces in |texmath.w|
+
+@ This implementation of
+\TeX\ uses two different conventions for representing sequential stacks.
+@^stack conventions@>@^conventions for representing stacks@>
+
+\yskip\hang 1) If there is frequent access to the top entry, and if the
+stack is essentially never empty, then the top entry is kept in a global
+variable (even better would be a machine register), and the other entries
+appear in the array $\\{stack}[0\to(\\{ptr}-1)]$. The
+semantic stack is handled this way.
+
+\yskip\hang 2) If there is infrequent top access, the entire stack contents
+are in the array $\\{stack}[0\to(\\{ptr}-1)]$. For example, the |save_stack|
+is treated this way, as we have seen.
+
+@c
+list_state_record *nest;
+int nest_ptr; /* first unused location of |nest| */
+int max_nest_stack; /* maximum of |nest_ptr| when pushing */
+int shown_mode; /* most recent mode shown by \.{\\tracingcommands} */
+halfword save_tail; /* save |tail| so we can examine whether we have an auto
+ kern before a glue */
+
+@ We will see later that the vertical list at the bottom semantic level is split
+into two parts; the ``current page'' runs from |page_head| to |page_tail|,
+and the ``contribution list'' runs from |contrib_head| to |tail| of
+semantic level zero. The idea is that contributions are first formed in
+vertical mode, then ``contributed'' to the current page (during which time
+the page-breaking decisions are made). For now, we don't need to know
+any more details about the page-building process.
+
+@c
+void initialize_nesting(void)
+{
+ nest_ptr = 0;
+ max_nest_stack = 0;
+ shown_mode = 0;
+ cur_list.mode_field = vmode;
+ cur_list.head_field = contrib_head;
+ cur_list.tail_field = contrib_head;
+ cur_list.eTeX_aux_field = null;
+ cur_list.prev_depth_field = ignore_depth;
+ cur_list.space_factor_field = 1000;
+ cur_list.incompleat_noad_field = null;
+ cur_list.ml_field = 0;
+ cur_list.pg_field = 0;
+ cur_list.dirs_field = null;
+ init_math_fields();
+}
+
+
+
+@ Here is a common way to make the current list grow:
+
+@c
+void tail_append(halfword p)
+{
+ couple_nodes(cur_list.tail_field, p);
+ cur_list.tail_field = vlink(cur_list.tail_field);
+}
+
+
+@ @c
+halfword pop_tail(void)
+{
+ halfword n, r;
+ if (cur_list.tail_field != cur_list.head_field) {
+ r = cur_list.tail_field;
+ if (vlink(alink(cur_list.tail_field)) == cur_list.tail_field) {
+ n = alink(cur_list.tail_field);
+ } else {
+ n = cur_list.head_field;
+ while (vlink(n) != cur_list.tail_field)
+ n = vlink(n);
+ }
+ flush_node(cur_list.tail_field);
+ cur_list.tail_field = n;
+ vlink(n) = null;
+ return r;
+ } else {
+ return null;
+ }
+}
+
+@ When \TeX's work on one level is interrupted, the state is saved by
+calling |push_nest|. This routine changes |head| and |tail| so that
+a new (empty) list is begun; it does not change |mode| or |aux|.
+
+@c
+void push_nest(void)
+{ /* enter a new semantic level, save the old */
+ if (nest_ptr > max_nest_stack) {
+ max_nest_stack = nest_ptr;
+ if (nest_ptr == nest_size)
+ overflow("semantic nest size", (unsigned) nest_size);
+ }
+ incr(nest_ptr);
+ cur_list.mode_field = nest[nest_ptr - 1].mode_field;
+ cur_list.head_field = new_node(temp_node, 0);
+ cur_list.tail_field = cur_list.head_field;
+ cur_list.eTeX_aux_field = null;
+ cur_list.ml_field = line;
+ cur_list.pg_field = 0;
+ cur_list.dirs_field = null;
+ cur_list.prev_depth_field = nest[nest_ptr - 1].prev_depth_field;
+ cur_list.space_factor_field = nest[nest_ptr - 1].space_factor_field;
+ cur_list.incompleat_noad_field = nest[nest_ptr - 1].incompleat_noad_field;
+ init_math_fields();
+}
+
+
+@ Conversely, when \TeX\ is finished on the current level, the former
+state is restored by calling |pop_nest|. This routine will never be
+called at the lowest semantic level, nor will it be called unless |head|
+is a node that should be returned to free memory.
+
+@c
+void pop_nest(void)
+{ /* leave a semantic level, re-enter the old */
+ flush_node(cur_list.head_field);
+ decr(nest_ptr);
+}
+
+@ Here is a procedure that displays what \TeX\ is working on, at all levels.
+
+@c
+void show_activities(void)
+{
+ int p; /* index into |nest| */
+ int m; /* mode */
+ halfword q, r; /* for showing the current page */
+ int t; /* ditto */
+ tprint_nl("");
+ print_ln();
+ for (p = nest_ptr; p >= 0; p--) {
+ m = nest[p].mode_field;
+ tprint_nl("### ");
+ print_mode(m);
+ tprint(" entered at line ");
+ print_int(abs(nest[p].ml_field));
+ /* we dont do this any more */
+#if 0
+
+ if (m == hmode)
+ if (nest[p].pg_field != 040600000) {
+ tprint(" (language");
+ print_int(nest[p].pg_field % 0200000);
+ tprint(":hyphenmin");
+ print_int(nest[p].pg_field / 020000000);
+ print_char(',');
+ print_int((nest[p].pg_field / 0200000) % 0100);
+ print_char(')');
+ }
+#endif
+ if (nest[p].ml_field < 0)
+ tprint(" (\\output routine)");
+ if (p == 0) {
+ /* Show the status of the current page */
+ if (page_head != page_tail) {
+ tprint_nl("### current page:");
+ if (output_active)
+ tprint(" (held over for next output)");
+ show_box(vlink(page_head));
+ if (page_contents > empty) {
+ tprint_nl("total height ");
+ print_totals();
+ tprint_nl(" goal height ");
+ print_scaled(page_goal);
+ r = vlink(page_ins_head);
+ while (r != page_ins_head) {
+ print_ln();
+ tprint_esc("insert");
+ t = subtype(r);
+ print_int(t);
+ tprint(" adds ");
+ if (count(t) == 1000)
+ t = height(r);
+ else
+ t = x_over_n(height(r), 1000) * count(t);
+ print_scaled(t);
+ if (type(r) == split_up_node) {
+ q = page_head;
+ t = 0;
+ do {
+ q = vlink(q);
+ if ((type(q) == ins_node)
+ && (subtype(q) == subtype(r)))
+ incr(t);
+ } while (q != broken_ins(r));
+ tprint(", #");
+ print_int(t);
+ tprint(" might split");
+ }
+ r = vlink(r);
+ }
+ }
+ }
+ if (vlink(contrib_head) != null)
+ tprint_nl("### recent contributions:");
+ }
+ show_box(vlink(nest[p].head_field));
+ /* Show the auxiliary field, |a| */
+ switch (abs(m) / (max_command_cmd + 1)) {
+ case 0:
+ tprint_nl("prevdepth ");
+ if (nest[p].prev_depth_field <= pdf_ignored_dimen)
+ tprint("ignored");
+ else
+ print_scaled(nest[p].prev_depth_field);
+ if (nest[p].pg_field != 0) {
+ tprint(", prevgraf ");
+ print_int(nest[p].pg_field);
+ if (nest[p].pg_field != 1)
+ tprint(" lines");
+ else
+ tprint(" line");
+ }
+ break;
+ case 1:
+ tprint_nl("spacefactor ");
+ print_int(nest[p].space_factor_field);
+ /* we dont do this any more, this was aux.rh originally */
+#if 0
+ if (m > 0) {
+ if (nest[p].current_language_field > 0) {
+ tprint(", current language ");
+ print_int(nest[p].current_language_field);
+ }
+ }
+#endif
+ break;
+ case 2:
+ if (nest[p].incompleat_noad_field != null) {
+ tprint("this will be denominator of:");
+ show_box(nest[p].incompleat_noad_field);
+ }
+ } /* there are no other cases */
+
+ }
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.h b/Build/source/texk/web2c/luatexdir/tex/packaging.h
new file mode 100644
index 00000000000..af1f18a265f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/packaging.h
@@ -0,0 +1,150 @@
+/* nesting.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: packaging.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef PACKAGING_H
+# define PACKAGING_H
+
+/* We define some constants used when calling |hpack| to deal with font expansion. */
+
+typedef enum {
+ exactly = 0, /*a box dimension is pre-specified */
+ additional, /*a box dimension is increased from the natural one */
+ cal_expand_ratio, /* calculate amount for font expansion after breaking
+ paragraph into lines */
+ subst_ex_font /* substitute fonts */
+} hpack_subtypes;
+
+# define substituted 3 /* |subtype| of kern nodes that should be substituted */
+
+extern void scan_spec(group_code c);
+extern void scan_full_spec(group_code c, int spec_direction);
+
+extern scaled total_stretch[5];
+extern scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */
+extern int last_badness; /* badness of the most recently packaged box */
+extern halfword adjust_tail; /* tail of adjustment list */
+extern halfword pre_adjust_tail;
+extern int font_expand_ratio; /* current expansion ratio */
+extern halfword last_leftmost_char;
+extern halfword last_rightmost_char;
+extern halfword next_char_p; /* pointer to the next char of an implicit kern */
+extern halfword prev_char_p; /* pointer to the previous char of an implicit kern */
+
+extern void set_prev_char_p(halfword p);
+extern scaled char_stretch(halfword p);
+extern scaled char_shrink(halfword p);
+extern scaled kern_stretch(halfword p);
+extern scaled kern_shrink(halfword p);
+extern void do_subst_font(halfword p, int ex_ratio);
+extern scaled char_pw(halfword p, int side);
+extern halfword new_margin_kern(scaled w, halfword p, int side);
+
+# define update_adjust_list(A) do { \
+ vlink(A) = adjust_ptr(p); \
+ while (vlink(A) != null) \
+ A = vlink(A); \
+ } while (0)
+
+extern halfword hpack(halfword p, scaled w, int m, int d);
+extern halfword filtered_hpack(halfword p, halfword qt, scaled w, int m,
+ int grp, int d);
+
+extern scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult,
+ int g_sign, int g_order, int d);
+
+extern int pack_begin_line;
+
+# define vpack(A,B,C,D) vpackage(A,B,C,max_dimen,D) /* special case of unconstrained depth */
+
+extern halfword vpackage(halfword p, scaled h, int m, scaled l, int d);
+extern halfword filtered_vpackage(halfword p, scaled h, int m, scaled l,
+ int grp, int d);
+extern void finish_vcenter(void);
+extern void package(int c);
+extern void append_to_vlist(halfword b);
+
+extern halfword prune_page_top(halfword p, boolean s);
+extern scaled active_height[10]; /* distance from first active node to~|cur_p| */
+
+# define cur_height active_height[1] /* the natural height */
+# define awful_bad 07777777777 /* more than a billion demerits */
+# define deplorable 100000 /* more than |inf_bad|, but less than |awful_bad| */
+
+extern scaled best_height_plus_depth; /* height of the best box, without stretching or shrinking */
+
+extern halfword vert_break(halfword p, scaled h, scaled d);
+extern halfword vsplit(halfword n, scaled h); /* extracts a page of height |h| from box |n| */
+
+# define box_code 0 /* |chr_code| for `\.{\\box}' */
+# define copy_code 1 /* |chr_code| for `\.{\\copy}' */
+# define last_box_code 2 /* |chr_code| for `\.{\\lastbox}' */
+# define vsplit_code 3 /* |chr_code| for `\.{\\vsplit}' */
+# define vtop_code 4 /* |chr_code| for `\.{\\vtop}' */
+
+# define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */
+# define page_disc disc_ptr[last_box_code] /* first item removed by page builder */
+# define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */
+
+extern halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */
+
+/*
+Now let's turn to the question of how \.{\\hbox} is treated. We actually
+need to consider also a slightly larger context, since constructions like
+`\.{\\setbox3=}\penalty0\.{\\hbox...}' and
+`\.{\\leaders}\penalty0\.{\\hbox...}' and
+`\.{\\lower3.8pt\\hbox...}'
+are supposed to invoke quite
+different actions after the box has been packaged. Conversely,
+constructions like `\.{\\setbox3=}' can be followed by a variety of
+different kinds of boxes, and we would like to encode such things in an
+efficient way.
+
+In other words, there are two problems: To represent the context of a box,
+and to represent its type.
+
+The first problem is solved by putting a ``context code'' on the |save_stack|,
+just below the two entries that give the dimensions produced by |scan_spec|.
+The context code is either a (signed) shift amount, or it is a large
+integer |>=box_flag|, where |box_flag=@t$2^{30}$@>|. Codes |box_flag| through
+|box_flag+biggest_reg| represent `\.{\\setbox0}' through
+`\.{\\setbox}|biggest_reg|'; codes |box_flag+biggest_reg+1| through
+|box_flag+2*biggest_reg| represent `\.{\\global\\setbox0}'
+through `\.{\\global\\setbox}|biggest_reg|'; code |box_flag+2*number_regs|
+represents `\.{\\shipout}'; and codes |box_flag+2*number_regs+1|
+through |box_flag+2*number_regs+3| represent `\.{\\leaders}', `\.{\\cleaders}',
+and `\.{\\xleaders}'.
+
+The second problem is solved by giving the command code |make_box| to all
+control sequences that produce a box, and by using the following |chr_code|
+values to distinguish between them: |box_code|, |copy_code|, |last_box_code|,
+|vsplit_code|, |vtop_code|, |vtop_code+vmode|, and |vtop_code+hmode|,
+where the latter two are used denote \.{\\vbox} and \.{\\hbox}, respectively.
+*/
+
+# define box_flag 010000000000 /* context code for `\.{\\setbox0}' */
+# define global_box_flag (box_flag+number_regs) /* context code for `\.{\\global\\setbox0}' */
+# define max_global_box_flag (global_box_flag+number_regs)
+# define ship_out_flag (max_global_box_flag+1) /* context code for `\.{\\shipout}' */
+# define leader_flag ship_out_flag+1 /* context code for `\.{\\leaders}' */
+
+extern void begin_box(int box_context);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.w b/Build/source/texk/web2c/luatexdir/tex/packaging.w
new file mode 100644
index 00000000000..16c030a5944
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/packaging.w
@@ -0,0 +1,1789 @@
+% packaging.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: packaging.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/packaging.w $";
+
+@ @c
+#define scan_normal_dimen() scan_dimen(false,false,false)
+
+#define prev_depth cur_list.prev_depth_field
+#define space_factor cur_list.space_factor_field
+#define box(A) eqtb[box_base+(A)].hh.rh
+
+#define text_direction int_par(text_direction_code)
+#define body_direction int_par(body_direction_code)
+#define every_hbox equiv(every_hbox_loc)
+#define every_vbox equiv(every_vbox_loc)
+#define box_max_depth dimen_par(box_max_depth_code)
+
+
+@ We're essentially done with the parts of \TeX\ that are concerned with
+the input (|get_next|) and the output (|ship_out|). So it's time to
+get heavily into the remaining part, which does the real work of typesetting.
+
+After lists are constructed, \TeX\ wraps them up and puts them into boxes.
+Two major subroutines are given the responsibility for this task: |hpack|
+applies to horizontal lists (hlists) and |vpack| applies to vertical lists
+(vlists). The main duty of |hpack| and |vpack| is to compute the dimensions
+of the resulting boxes, and to adjust the glue if one of those dimensions
+is pre-specified. The computed sizes normally enclose all of the material
+inside the new box; but some items may stick out if negative glue is used,
+if the box is overfull, or if a \.{\\vbox} includes other boxes that have
+been shifted left.
+
+The subroutine call |hpack(p,w,m)| returns a pointer to an |hlist_node|
+for a box containing the hlist that starts at |p|. Parameter |w| specifies
+a width; and parameter |m| is either `|exactly|' or `|additional|'. Thus,
+|hpack(p,w,exactly)| produces a box whose width is exactly |w|, while
+|hpack(p,w,additional)| yields a box whose width is the natural width plus
+|w|. It is convenient to define a macro called `|natural|' to cover the
+most common case, so that we can say |hpack(p,natural)| to get a box that
+has the natural width of list |p|.
+
+Similarly, |vpack(p,w,m)| returns a pointer to a |vlist_node| for a
+box containing the vlist that starts at |p|. In this case |w| represents
+a height instead of a width; the parameter |m| is interpreted as in |hpack|.
+
+
+@ The parameters to |hpack| and |vpack| correspond to \TeX's primitives
+like `\.{\\hbox} \.{to} \.{300pt}', `\.{\\hbox} \.{spread} \.{10pt}'; note
+that `\.{\\hbox}' with no dimension following it is equivalent to
+`\.{\\hbox} \.{spread} \.{0pt}'. The |scan_spec| subroutine scans such
+constructions in the user's input, including the mandatory left brace that
+follows them, and it puts the specification onto |save_stack| so that the
+desired box can later be obtained by executing the following code:
+$$\vbox{\halign{#\hfil\cr
+|save_ptr:=save_ptr-1;|\cr
+|hpack(p,saved_value(0),saved_level(0)).|\cr}}$$
+
+@c
+void scan_spec(group_code c)
+{ /* scans a box specification and left brace */
+ int spec_code;
+ if (scan_keyword("to")) {
+ spec_code = exactly;
+ scan_normal_dimen();
+ } else if (scan_keyword("spread")) {
+ spec_code = additional;
+ scan_normal_dimen();
+ } else {
+ spec_code = additional;
+ cur_val = 0;
+ }
+ set_saved_record(0, saved_boxspec, spec_code, cur_val);
+ save_ptr++;
+ new_save_level(c);
+ scan_left_brace();
+}
+
+
+@ When scanning, special care is necessary to ensure that the special
+|save_stack| codes are placed just below the new group code, because
+scanning can change |save_stack| when \.{\\csname} appears.
+
+This coincides with the text on |dir| and |attr| keywords, as these
+are exaclty the uses of \.{\\hbox}, \.{\\vbox}, and \.{\\vtop} in the
+input stream (the others are \.{\\vcenter}, \.{\\valign}, and
+\.{\\halign}).
+
+@c
+void scan_full_spec(group_code c, int spec_direction)
+{ /* scans a box specification and left brace */
+ int s; /* temporarily saved value */
+ int i;
+ int v;
+ int spec_code;
+ halfword attr_list;
+ s = 0;
+ if (attr_list_cache == cache_disabled)
+ update_attribute_cache();
+ attr_list = attr_list_cache;
+ assert(saved_type(0) == saved_boxcontext);
+ s = saved_value(0); /* the box context */
+ CONTINUE:
+ while (cur_cmd == relax_cmd || cur_cmd == spacer_cmd) {
+ get_x_token();
+ if (cur_cmd != relax_cmd && cur_cmd != spacer_cmd)
+ back_input();
+ }
+ if (scan_keyword("attr")) {
+ scan_register_num();
+ i = cur_val;
+ scan_optional_equals();
+ scan_int();
+ v = cur_val;
+ if ((attr_list != null) && (attr_list == attr_list_cache)) {
+ attr_list = copy_attribute_list(attr_list_cache);
+ add_node_attr_ref(attr_list); /* will be used once */
+ }
+ attr_list = do_set_attribute(attr_list, i, v);
+ goto CONTINUE;
+ }
+ if (scan_keyword("dir")) {
+ scan_direction();
+ spec_direction = cur_val;
+ goto CONTINUE;
+ }
+ if (attr_list == attr_list_cache) {
+ add_node_attr_ref(attr_list);
+ }
+ if (scan_keyword("to")) {
+ spec_code = exactly;
+ } else if (scan_keyword("spread")) {
+ spec_code = additional;
+ } else {
+ spec_code = additional;
+ cur_val = 0;
+ goto FOUND;
+ }
+ scan_normal_dimen();
+ FOUND:
+ set_saved_record(0, saved_boxcontext, 0, s);
+ set_saved_record(1, saved_boxspec, spec_code, cur_val);
+ /* DIR: Adjust |text_dir_ptr| for |scan_spec| */
+ if (spec_direction != -1) {
+ set_saved_record(2, saved_boxdir, spec_direction, text_dir_ptr);
+ text_dir_ptr = new_dir(spec_direction);
+ } else {
+ set_saved_record(2, saved_boxdir, spec_direction, null);
+ }
+ set_saved_record(3, saved_boxattr, 0, attr_list);
+ save_ptr += 4;
+ new_save_level(c);
+ scan_left_brace();
+ eq_word_define(int_base + body_direction_code, spec_direction);
+ eq_word_define(int_base + par_direction_code, spec_direction);
+ eq_word_define(int_base + text_direction_code, spec_direction);
+}
+
+
+@ To figure out the glue setting, |hpack| and |vpack| determine how much
+stretchability and shrinkability are present, considering all four orders
+of infinity. The highest order of infinity that has a nonzero coefficient
+is then used as if no other orders were present.
+
+For example, suppose that the given list contains six glue nodes with
+the respective stretchabilities 3pt, 8fill, 5fil, 6pt, $-3$fil, $-8$fill.
+Then the total is essentially 2fil; and if a total additional space of 6pt
+is to be achieved by stretching, the actual amounts of stretch will be
+0pt, 0pt, 15pt, 0pt, $-9$pt, and 0pt, since only `fil' glue will be
+considered. (The `fill' glue is therefore not really stretching infinitely
+with respect to `fil'; nobody would actually want that to happen.)
+
+The arrays |total_stretch| and |total_shrink| are used to determine how much
+glue of each kind is present. A global variable |last_badness| is used
+to implement \.{\\badness}.
+
+@c
+scaled total_stretch[5];
+scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */
+int last_badness; /* badness of the most recently packaged box */
+
+
+@ If the global variable |adjust_tail| is non-null, the |hpack| routine
+also removes all occurrences of |ins_node|, |mark_node|, and |adjust_node|
+items and appends the resulting material onto the list that ends at
+location |adjust_tail|.
+
+@c
+halfword adjust_tail; /* tail of adjustment list */
+
+
+@ Materials in \.{\\vadjust} used with \.{pre} keyword will be appended to
+|pre_adjust_tail| instead of |adjust_tail|.
+
+@c
+halfword pre_adjust_tail;
+
+int font_expand_ratio; /* current expansion ratio */
+halfword last_leftmost_char;
+halfword last_rightmost_char;
+
+halfword next_char_p; /* pointer to the next char of an implicit kern */
+halfword prev_char_p; /* pointer to the previous char of an implicit kern */
+
+@ This procedure is called repeatedly from inside the line break algorithm.
+@c
+void set_prev_char_p(halfword p)
+{
+ prev_char_p = p;
+}
+
+@ @c
+scaled char_stretch(halfword p)
+{
+ internal_font_number k;
+ scaled dw;
+ int ef;
+ internal_font_number f;
+ int c;
+ f = font(p);
+ c = character(p);
+ k = font_stretch(f);
+ ef = get_ef_code(f, c);
+ if ((k != null_font) && (ef > 0)) {
+ dw = char_width(k, c) - char_width(f, c);
+ if (dw > 0)
+ return round_xn_over_d(dw, ef, 1000);
+ }
+ return 0;
+}
+
+@ @c
+scaled char_shrink(halfword p)
+{
+ internal_font_number k;
+ scaled dw;
+ int ef;
+ internal_font_number f;
+ int c;
+ f = font(p);
+ c = character(p);
+ k = font_shrink(f);
+ ef = get_ef_code(f, c);
+ if ((k != null_font) && (ef > 0)) {
+ dw = char_width(f, c) - char_width(k, c);
+ if (dw > 0)
+ return round_xn_over_d(dw, ef, 1000);
+ }
+ return 0;
+}
+
+@ @c
+scaled kern_stretch(halfword p)
+{
+ halfword l, r;
+ scaled d;
+ if ((prev_char_p == null) || (vlink(prev_char_p) != p)
+ || (vlink(p) == null))
+ return 0;
+ l = prev_char_p;
+ r = vlink(p);
+ if (!((is_char_node(l) && is_char_node(r) &&
+ (font(l) == font(r)) && (font_stretch(font(l)) != null_font))))
+ return 0;
+ d = get_kern(font_stretch(font(l)), character(l), character(r));
+ return round_xn_over_d(d - width(p),
+ get_ef_code(font(l), character(l)), 1000);
+}
+
+@ @c
+scaled kern_shrink(halfword p)
+{
+ halfword l, r;
+ scaled d;
+ if ((prev_char_p == null) || (vlink(prev_char_p) != p)
+ || (vlink(p) == null))
+ return 0;
+ l = prev_char_p;
+ r = vlink(p);
+ if (!((is_char_node(l) && is_char_node(r) &&
+ (font(l) == font(r)) && (font_shrink(font(l)) != null_font))))
+ return 0;
+ d = get_kern(font_shrink(font(l)), character(l), character(r));
+ return round_xn_over_d(width(p) - d,
+ get_ef_code(font(l), character(l)), 1000);
+}
+
+@ @c
+void do_subst_font(halfword p, int ex_ratio)
+{
+ internal_font_number f, k;
+ halfword r;
+ int ef;
+ if (type(p) == disc_node) {
+ r = vlink(pre_break(p));
+ while (r != null) {
+ if (is_char_node(r))
+ do_subst_font(r, ex_ratio);
+ r = vlink(r);
+ }
+ r = vlink(post_break(p));
+ while (r != null) {
+ if (is_char_node(r))
+ do_subst_font(r, ex_ratio);
+ r = vlink(r);
+ }
+ r = vlink(no_break(p));
+ while (r != null) {
+ if (is_char_node(r))
+ do_subst_font(r, ex_ratio);
+ r = vlink(r);
+ }
+ return;
+ }
+ if (is_char_node(p)) {
+ r = p;
+ } else {
+ pdf_error("font expansion", "invalid node type");
+ return;
+ }
+ f = font(r);
+ ef = get_ef_code(f, character(r));
+ if (ef == 0)
+ return;
+ if ((font_expand_ratio(f) == 0) &&
+ (font_stretch(f) != null_font) && (ex_ratio > 0)) {
+ k = expand_font(f,
+ ext_xn_over_d(ex_ratio * ef,
+ font_expand_ratio(font_stretch(f)),
+ 1000000));
+ } else if ((font_expand_ratio(f) == 0)
+ && (font_shrink(f) != null_font) && (ex_ratio < 0)) {
+ k = expand_font(f,
+ ext_xn_over_d(ex_ratio * ef,
+ -font_expand_ratio(font_shrink(f)),
+ 1000000));
+ } else {
+ k = f;
+ }
+ if (k != f) {
+ font(r) = k;
+ if (!is_char_node(p)) { /* todo: this should be: |if(is_ligature())| */
+ r = lig_ptr(p);
+ while (r != null) {
+ font(r) = k;
+ r = vlink(r);
+ }
+ }
+ }
+}
+
+@ @c
+scaled char_pw(halfword p, int side)
+{
+ internal_font_number f;
+ int c;
+ if (side == left_side)
+ last_leftmost_char = null;
+ else
+ last_rightmost_char = null;
+ if (p == null)
+ return 0;
+ if (!is_char_node(p))
+ return 0;
+ f = font(p);
+ if (side == left_side) {
+ c = get_lp_code(f, character(p));
+ last_leftmost_char = p;
+ } else {
+ c = get_rp_code(f, character(p));
+ last_rightmost_char = p;
+ }
+ if (c == 0)
+ return 0;
+ return round_xn_over_d(quad(f), c, 1000);
+}
+
+@ @c
+halfword new_margin_kern(scaled w, halfword p, int side)
+{
+ halfword k, q;
+ k = new_node(margin_kern_node, side);
+ width(k) = w;
+ if (p == null)
+ pdf_error("margin kerning", "invalid pointer to marginal char node");
+ q = new_char(font(p), character(p));
+ margin_char(k) = q;
+ return k;
+}
+
+
+@ Here is |hpack|, which is place where we do font substituting when
+font expansion is being used.
+
+@c
+halfword hpack(halfword p, scaled w, int m, int pack_direction)
+{
+ halfword r; /* the box node that will be returned */
+ halfword q; /* trails behind |p| */
+ scaled h, d, x; /* height, depth, and natural width */
+ scaled_whd whd;
+ scaled s; /* shift amount */
+ halfword g; /* points to a glue specification */
+ int o; /* order of infinity */
+ internal_font_number f; /* the font in a |char_node| */
+ halfword dir_ptr; /* for managing the direction stack */
+ /* BEWARE: this shadows a global |dir_ptr| */
+ int hpack_dir; /* the current direction */
+ int disc_level;
+ halfword pack_interrupt[8];
+ scaled font_stretch = 0;
+ scaled font_shrink = 0;
+ scaled k = 0;
+ last_badness = 0;
+ r = new_node(hlist_node, min_quarterword);
+ if (pack_direction == -1) {
+ box_dir(r) = text_direction;
+ } else {
+ box_dir(r) = pack_direction;
+ pack_direction = -1;
+ }
+ hpack_dir = box_dir(r);
+ dir_ptr = null;
+ push_dir(hpack_dir);
+ q = r + list_offset;
+ vlink(q) = p;
+ if (m == cal_expand_ratio) {
+ prev_char_p = null;
+ font_stretch = 0;
+ font_shrink = 0;
+ font_expand_ratio = 0;
+ }
+ h = 0;
+ /* Clear dimensions to zero */
+ d = 0;
+ x = 0;
+ total_stretch[normal] = 0;
+ total_shrink[normal] = 0;
+ total_stretch[sfi] = 0;
+ total_shrink[sfi] = 0;
+ total_stretch[fil] = 0;
+ total_shrink[fil] = 0;
+ total_stretch[fill] = 0;
+ total_shrink[fill] = 0;
+ total_stretch[filll] = 0;
+ total_shrink[filll] = 0;
+
+ disc_level = 0;
+ RESWITCH:
+ while ((p != null) || (disc_level > 0)) {
+ if (p == null) {
+ decr(disc_level);
+ p = pack_interrupt[disc_level];
+ goto RESWITCH;
+ }
+ /* Examine node |p| in the hlist, taking account of its effect
+ on the dimensions of the new box, or moving it to the adjustment list;
+ then advance |p| to the next node */
+ while (is_char_node(p)) {
+ /* Incorporate character dimensions into the dimensions of
+ the hbox that will contain~it, then move to the next node */
+ /* The following code is part of \TeX's inner loop; i.e., adding another
+ character of text to the user's input will cause each of these instructions
+ to be exercised one more time.
+ */
+ if (m >= cal_expand_ratio) {
+ prev_char_p = p;
+ if (m == cal_expand_ratio) {
+ font_stretch += char_stretch(p);
+ font_shrink += char_shrink(p);
+ } else if (m == subst_ex_font) {
+ do_subst_font(p, font_expand_ratio);
+ }
+ }
+ f = font(p);
+ whd = pack_width_height_depth(hpack_dir, dir_TRT, p, true);
+ x += whd.wd;
+ if (whd.ht > h)
+ h = whd.ht;
+ if (whd.dp > d)
+ d = whd.dp;
+ p = vlink(p);
+ }
+ if (p != null) {
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ /* Incorporate box dimensions into the dimensions of the hbox that will contain~it */
+ /* The code here implicitly uses the fact that running dimensions are
+ indicated by |null_flag|, which will be ignored in the calculations
+ because it is a highly negative number. */
+ s = shift_amount(p);
+ whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false);
+ x += whd.wd;
+ if (whd.ht - s > h)
+ h = whd.ht - s;
+ if (whd.dp + s > d)
+ d = whd.dp + s;
+ break;
+ case rule_node:
+ case unset_node:
+ x += width(p);
+ if (type(p) >= rule_node)
+ s = 0;
+ else
+ s = shift_amount(p);
+ if (height(p) - s > h)
+ h = height(p) - s;
+ if (depth(p) + s > d)
+ d = depth(p) + s;
+ break;
+ case ins_node:
+ case mark_node:
+ case adjust_node:
+ if (adjust_tail != null) {
+ /* Transfer node |p| to the adjustment list */
+ /*
+ Although node |q| is not necessarily the immediate predecessor of node |p|,
+ it always points to some node in the list preceding |p|. Thus, we can delete
+ nodes by moving |q| when necessary. The algorithm takes linear time, and the
+ extra computation does not intrude on the inner loop unless it is necessary
+ to make a deletion.
+ */
+ while (vlink(q) != p)
+ q = vlink(q);
+ if (type(p) == adjust_node) {
+ if (adjust_pre(p) != 0)
+ update_adjust_list(pre_adjust_tail);
+ else
+ update_adjust_list(adjust_tail);
+ p = vlink(p);
+ adjust_ptr(vlink(q)) = null;
+ flush_node(vlink(q));
+ } else {
+ vlink(adjust_tail) = p;
+ adjust_tail = p;
+ p = vlink(p);
+ }
+ vlink(q) = p;
+ p = q;
+ }
+ break;
+ case whatsit_node:
+ /* Incorporate a whatsit node into an hbox */
+ if (subtype(p) == dir_node) {
+ /* DIR: Adjust the dir stack for the |hpack| routine */
+ if (dir_dir(p) >= 0) {
+ hpack_dir = dir_dir(p);
+ push_dir_node(p);
+ } else {
+ pop_dir_node();
+ if (dir_ptr != null)
+ hpack_dir = dir_dir(dir_ptr);
+ }
+
+ } else {
+ if ((subtype(p) == pdf_refxform_node)
+ || (subtype(p) == pdf_refximage_node)) {
+ x += width(p);
+ s = 0;
+ if (height(p) - s > h)
+ h = height(p) - s;
+ if (depth(p) + s > d)
+ d = depth(p) + s;
+ }
+ }
+ break;
+ case glue_node:
+ /* Incorporate glue into the horizontal totals */
+ g = glue_ptr(p);
+ x += width(g);
+ o = stretch_order(g);
+ total_stretch[o] = total_stretch[o] + stretch(g);
+ o = shrink_order(g);
+ total_shrink[o] = total_shrink[o] + shrink(g);
+ if (subtype(p) >= a_leaders) {
+ g = leader_ptr(p);
+ if (height(g) > h)
+ h = height(g);
+ if (depth(g) > d)
+ d = depth(g);
+ }
+ break;
+ case margin_kern_node:
+ if (m == cal_expand_ratio) {
+ f = font(margin_char(p));
+ do_subst_font(margin_char(p), 1000);
+ if (f != font(margin_char(p)))
+ font_stretch =
+ font_stretch - width(p) - char_pw(margin_char(p),
+ subtype(p));
+ font(margin_char(p)) = f;
+ do_subst_font(margin_char(p), -1000);
+ if (f != font(margin_char(p)))
+ font_shrink =
+ font_shrink - width(p) - char_pw(margin_char(p),
+ subtype(p));
+ font(margin_char(p)) = f;
+ } else if (m == subst_ex_font) {
+ do_subst_font(margin_char(p), font_expand_ratio);
+ width(p) = -char_pw(margin_char(p), subtype(p));
+ }
+ x += width(p);
+ break;
+ case kern_node:
+ if (subtype(p) == normal) {
+ if (m == cal_expand_ratio) {
+ font_stretch = font_stretch + kern_stretch(p);
+ font_shrink = font_shrink + kern_shrink(p);
+ } else if (m == subst_ex_font) {
+ if (font_expand_ratio > 0)
+ k = kern_stretch(p);
+ else if (font_expand_ratio < 0)
+ k = kern_shrink(p);
+ else
+ pdfassert(0);
+ if (k != 0)
+ width(p) = get_kern(font(prev_char_p),
+ character(prev_char_p),
+ character(vlink(p)));
+ }
+ }
+ x += width(p);
+ break;
+ case math_node:
+ x += surround(p);
+ break;
+ case disc_node:
+ if (m == subst_ex_font)
+ do_subst_font(p, font_expand_ratio);
+ if ((subtype(p) != select_disc) && (vlink(no_break(p)) != null)) {
+ pack_interrupt[disc_level] = vlink(p);
+ incr(disc_level);
+ p = no_break(p);
+ }
+ break;
+ default:
+ break;
+ }
+ p = vlink(p);
+ }
+
+ }
+
+ if (adjust_tail != null)
+ vlink(adjust_tail) = null;
+ if (pre_adjust_tail != null)
+ vlink(pre_adjust_tail) = null;
+ height(r) = h;
+ depth(r) = d;
+ /* Determine the value of |width(r)| and the appropriate glue setting;
+ then |return| or |goto common_ending| */
+ /* When we get to the present part of the program, |x| is the natural width
+ of the box being packaged. */
+ if (m == additional)
+ w = x + w;
+ width(r) = w;
+ x = w - x; /* now |x| is the excess to be made up */
+ if (x == 0) {
+ glue_sign(r) = normal;
+ glue_order(r) = normal;
+ set_glue_ratio_zero(glue_set(r));
+ goto EXIT;
+ } else if (x > 0) {
+ /* Determine horizontal glue stretch setting, then |return|
+ or \hbox{|goto common_ending|} */
+
+ /* If |hpack| is called with |m=cal_expand_ratio| we calculate
+ |font_expand_ratio| and return without checking for overfull or underfull box. */
+
+ /* Determine the stretch order */
+ if (total_stretch[filll] != 0)
+ o = filll;
+ else if (total_stretch[fill] != 0)
+ o = fill;
+ else if (total_stretch[fil] != 0)
+ o = fil;
+ else if (total_stretch[sfi] != 0)
+ o = sfi;
+ else
+ o = normal;
+
+ if ((m == cal_expand_ratio) && (o == normal) && (font_stretch > 0)) {
+ font_expand_ratio = divide_scaled_n(x, font_stretch, 1000.0);
+ goto EXIT;
+ }
+ glue_order(r) = (quarterword) o;
+ glue_sign(r) = stretching;
+ if (total_stretch[o] != 0) {
+ glue_set(r) = unfloat((double) x / total_stretch[o]);
+ } else {
+ glue_sign(r) = normal;
+ set_glue_ratio_zero(glue_set(r)); /* there's nothing to stretch */
+ }
+ if (o == normal) {
+ if (list_ptr(r) != null) {
+ /* Report an underfull hbox and |goto common_ending|, if this box
+ is sufficiently bad */
+ last_badness = badness(x, total_stretch[normal]);
+ if (last_badness > int_par(hbadness_code)) {
+ print_ln();
+ if (last_badness > 100)
+ tprint_nl("Underfull \\hbox (badness ");
+ else
+ tprint_nl("Loose \\hbox (badness ");
+ print_int(last_badness);
+ goto COMMON_ENDING;
+ }
+ }
+ }
+ goto EXIT;
+ } else {
+ /* Determine horizontal glue shrink setting, then |return|
+ or \hbox{|goto common_ending|} */
+ /* Determine the shrink order */
+ if (total_shrink[filll] != 0)
+ o = filll;
+ else if (total_shrink[fill] != 0)
+ o = fill;
+ else if (total_shrink[fil] != 0)
+ o = fil;
+ else if (total_shrink[sfi] != 0)
+ o = sfi;
+ else
+ o = normal;
+
+ if ((m == cal_expand_ratio) && (o == normal) && (font_shrink > 0)) {
+ font_expand_ratio = divide_scaled_n(x, font_shrink, 1000.0);
+ goto EXIT;
+ }
+ glue_order(r) = (quarterword) o;
+ glue_sign(r) = shrinking;
+ if (total_shrink[o] != 0) {
+ glue_set(r) = unfloat((double) (-x) / (double) total_shrink[o]);
+ } else {
+ glue_sign(r) = normal;
+ set_glue_ratio_zero(glue_set(r)); /* there's nothing to shrink */
+ }
+ if ((total_shrink[o] < -x) && (o == normal) && (list_ptr(r) != null)) {
+ last_badness = 1000000;
+ set_glue_ratio_one(glue_set(r)); /* use the maximum shrinkage */
+ /* Report an overfull hbox and |goto common_ending|, if this box
+ is sufficiently bad */
+ if ((-x - total_shrink[normal] > dimen_par(hfuzz_code))
+ || (int_par(hbadness_code) < 100)) {
+ if ((dimen_par(overfull_rule_code) > 0)
+ && (-x - total_shrink[normal] > dimen_par(hfuzz_code))) {
+ while (vlink(q) != null)
+ q = vlink(q);
+ vlink(q) = new_rule();
+ rule_dir(vlink(q)) = box_dir(r);
+ width(vlink(q)) = dimen_par(overfull_rule_code);
+ }
+ print_ln();
+ tprint_nl("Overfull \\hbox (");
+ print_scaled(-x - total_shrink[normal]);
+ tprint("pt too wide");
+ goto COMMON_ENDING;
+ }
+ } else if (o == normal) {
+ if (list_ptr(r) != null) {
+ /* Report a tight hbox and |goto common_ending|, if this box is sufficiently bad */
+ last_badness = badness(-x, total_shrink[normal]);
+ if (last_badness > int_par(hbadness_code)) {
+ print_ln();
+ tprint_nl("Tight \\hbox (badness ");
+ print_int(last_badness);
+ goto COMMON_ENDING;
+ }
+ }
+ }
+ goto EXIT;
+ }
+
+ COMMON_ENDING:
+ /* Finish issuing a diagnostic message for an overfull or underfull hbox */
+ if (output_active) {
+ tprint(") has occurred while \\output is active");
+ } else {
+ if (pack_begin_line != 0) {
+ if (pack_begin_line > 0)
+ tprint(") in paragraph at lines ");
+ else
+ tprint(") in alignment at lines ");
+ print_int(abs(pack_begin_line));
+ tprint("--");
+ } else {
+ tprint(") detected at line ");
+ }
+ print_int(line);
+ }
+
+ print_ln();
+ font_in_short_display = null_font;
+ short_display(list_ptr(r));
+ print_ln();
+ begin_diagnostic();
+ show_box(r);
+ end_diagnostic(true);
+
+ EXIT:
+ if ((m == cal_expand_ratio) && (font_expand_ratio != 0)) {
+ font_expand_ratio = fix_int(font_expand_ratio, -1000, 1000);
+ q = list_ptr(r);
+ list_ptr(r) = null;
+ flush_node(r);
+ r = hpack(q, w, subst_ex_font, hpack_dir);
+ }
+ while (dir_ptr != null)
+ pop_dir_node();
+ return r;
+}
+
+@ @c
+halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp,
+ int pac)
+{
+ halfword q;
+ new_hyphenation(p, qt);
+ (void) new_ligkern(p, qt); /* don't care about the tail in this case */
+ q = vlink(p);
+ q = lua_hpack_filter(q, w, m, grp, pac);
+ return hpack(q, w, m, pac);
+}
+
+@ here is a function to calculate the natural whd of a (horizontal) node list
+
+@c
+scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult,
+ int g_sign, int g_order, int pack_direction)
+{
+ scaled s; /* shift amount */
+ halfword g; /* points to a glue specification */
+ internal_font_number f; /* the font in a |char_node| */
+ int hpack_dir;
+ scaled_whd xx; /* for recursion */
+ scaled_whd whd, siz = { 0, 0, 0 };
+ if (pack_direction == -1) {
+ hpack_dir = text_direction;
+ } else {
+ hpack_dir = pack_direction;
+ }
+ while (p != pp && p != null) {
+ while (is_char_node(p) && p != pp) {
+ f = font(p);
+ whd = pack_width_height_depth(hpack_dir, dir_TRT, p, true);
+ siz.wd += whd.wd;
+ if (whd.ht > siz.ht)
+ siz.ht = whd.ht;
+ if (whd.dp > siz.dp)
+ siz.dp = whd.dp;
+ p = vlink(p);
+ }
+ if (p != pp && p != null) {
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ s = shift_amount(p);
+ whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false);
+ siz.wd += whd.wd;
+ if (whd.ht - s > siz.ht)
+ siz.ht = whd.ht - s;
+ if (whd.dp + s > siz.dp)
+ siz.dp = whd.dp + s;
+ break;
+ case rule_node:
+ case unset_node:
+ siz.wd += width(p);
+ if (type(p) >= rule_node)
+ s = 0;
+ else
+ s = shift_amount(p);
+ if (height(p) - s > siz.ht)
+ siz.ht = height(p) - s;
+ if (depth(p) + s > siz.dp)
+ siz.dp = depth(p) + s;
+ break;
+ case whatsit_node:
+ if ((subtype(p) == pdf_refxform_node)
+ || (subtype(p) == pdf_refximage_node)) {
+ siz.wd += width(p);
+ s = 0;
+ if (height(p) - s > siz.ht)
+ siz.ht = height(p) - s;
+ if (depth(p) + s > siz.dp)
+ siz.dp = depth(p) + s;
+ }
+ break;
+ case glue_node:
+ g = glue_ptr(p);
+ siz.wd += width(g);
+ if (g_sign != normal) {
+ if (g_sign == stretching) {
+ if (stretch_order(g) == g_order) {
+ siz.wd +=
+ float_round(float_cast(g_mult) *
+ float_cast(stretch(g)));
+ }
+ } else if (shrink_order(g) == g_order) {
+ siz.wd -=
+ float_round(float_cast(g_mult) *
+ float_cast(shrink(g)));
+ }
+ }
+ if (subtype(p) >= a_leaders) {
+ g = leader_ptr(p);
+ if (height(g) > siz.ht)
+ siz.ht = height(g);
+ if (depth(g) > siz.dp)
+ siz.dp = depth(g);
+ }
+ break;
+ case margin_kern_node:
+ case kern_node:
+ siz.wd += width(p);
+ break;
+ case math_node:
+ siz.wd += surround(p);
+ break;
+ case disc_node:
+ xx = natural_sizes(no_break(p), null, g_mult, g_sign, g_order,
+ hpack_dir);
+ siz.wd += xx.wd;
+ if (xx.ht > siz.ht)
+ siz.ht = xx.ht;
+ if (xx.dp > siz.dp)
+ siz.dp = xx.dp;
+ break;
+ default:
+ break;
+ }
+ p = vlink(p);
+ }
+
+ }
+ return siz;
+}
+
+
+@ In order to provide a decent indication of where an overfull or underfull
+box originated, we use a global variable |pack_begin_line| that is
+set nonzero only when |hpack| is being called by the paragraph builder
+or the alignment finishing routine.
+
+@c
+int pack_begin_line; /* source file line where the current paragraph
+ or alignment began; a negative value denotes alignment */
+
+
+@ The |vpack| subroutine is actually a special case of a slightly more
+general routine called |vpackage|, which has four parameters. The fourth
+parameter, which is |max_dimen| in the case of |vpack|, specifies the
+maximum depth of the page box that is constructed. The depth is first
+computed by the normal rules; if it exceeds this limit, the reference
+point is simply moved down until the limiting depth is attained.
+
+@c
+halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction)
+{
+ halfword r; /* the box node that will be returned */
+ scaled w, d, x; /* width, depth, and natural height */
+ scaled_whd whd;
+ scaled s; /* shift amount */
+ halfword g; /* points to a glue specification */
+ int o; /* order of infinity */
+ last_badness = 0;
+ r = new_node(vlist_node, 0);
+ if (pack_direction == -1) {
+ box_dir(r) = body_direction;
+ } else {
+ box_dir(r) = pack_direction;
+ }
+ subtype(r) = min_quarterword;
+ shift_amount(r) = 0;
+ list_ptr(r) = p;
+ w = 0;
+ /* Clear dimensions to zero */
+ d = 0;
+ x = 0;
+ total_stretch[normal] = 0;
+ total_shrink[normal] = 0;
+ total_stretch[sfi] = 0;
+ total_shrink[sfi] = 0;
+ total_stretch[fil] = 0;
+ total_shrink[fil] = 0;
+ total_stretch[fill] = 0;
+ total_shrink[fill] = 0;
+ total_stretch[filll] = 0;
+ total_shrink[filll] = 0;
+
+ while (p != null) {
+ /* Examine node |p| in the vlist, taking account of its effect
+ on the dimensions of the new box; then advance |p| to the next node */
+ if (is_char_node(p)) {
+ confusion("vpack");
+ } else {
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ /* Incorporate box dimensions into the dimensions of
+ the vbox that will contain~it */
+ s = shift_amount(p);
+ whd = pack_width_height_depth(box_dir(r), box_dir(p), p, false);
+ if (whd.wd + s > w)
+ w = whd.wd + s;
+ x += d + whd.ht;
+ d = whd.dp;
+ break;
+ case rule_node:
+ case unset_node:
+ x += d + height(p);
+ d = depth(p);
+ if (type(p) >= rule_node)
+ s = 0;
+ else
+ s = shift_amount(p);
+ if (width(p) + s > w)
+ w = width(p) + s;
+ break;
+ case whatsit_node:
+ /* Incorporate a whatsit node into a vbox */
+ if ((subtype(p) == pdf_refxform_node)
+ || (subtype(p) == pdf_refximage_node)) {
+ x += d + height(p);
+ d = depth(p);
+ s = 0;
+ if (width(p) + s > w)
+ w = width(p) + s;
+ }
+ break;
+ case glue_node:
+ /* Incorporate glue into the vertical totals */
+ x += d;
+ d = 0;
+ g = glue_ptr(p);
+ x += width(g);
+ o = stretch_order(g);
+ total_stretch[o] = total_stretch[o] + stretch(g);
+ o = shrink_order(g);
+ total_shrink[o] = total_shrink[o] + shrink(g);
+ if (subtype(p) >= a_leaders) {
+ g = leader_ptr(p);
+ if (width(g) > w)
+ w = width(g);
+ }
+ break;
+ case kern_node:
+ x += d + width(p);
+ d = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ p = vlink(p);
+ }
+ width(r) = w;
+ if (d > l) {
+ x += d - l;
+ depth(r) = l;
+ } else {
+ depth(r) = d;
+ }
+ /* Determine the value of |height(r)| and the appropriate glue setting;
+ then |return| or |goto common_ending| */
+ /* When we get to the present part of the program, |x| is the natural height
+ of the box being packaged. */
+ if (m == additional)
+ h = x + h;
+ height(r) = h;
+ x = h - x; /* now |x| is the excess to be made up */
+ if (x == 0) {
+ glue_sign(r) = normal;
+ glue_order(r) = normal;
+ set_glue_ratio_zero(glue_set(r));
+ return r;
+ } else if (x > 0) {
+ /* Determine vertical glue stretch setting, then |return|
+ or \hbox{|goto common_ending|} */
+ /* Determine the stretch order */
+ if (total_stretch[filll] != 0)
+ o = filll;
+ else if (total_stretch[fill] != 0)
+ o = fill;
+ else if (total_stretch[fil] != 0)
+ o = fil;
+ else if (total_stretch[sfi] != 0)
+ o = sfi;
+ else
+ o = normal;
+
+ glue_order(r) = (quarterword) o;
+ glue_sign(r) = stretching;
+ if (total_stretch[o] != 0) {
+ glue_set(r) = unfloat((double) x / total_stretch[o]);
+ } else {
+ glue_sign(r) = normal;
+ set_glue_ratio_zero(glue_set(r)); /* there's nothing to stretch */
+ }
+ if (o == normal) {
+ if (list_ptr(r) != null) {
+ /* Report an underfull vbox and |goto common_ending|, if this box
+ is sufficiently bad */
+ last_badness = badness(x, total_stretch[normal]);
+ if (last_badness > int_par(vbadness_code)) {
+ print_ln();
+ if (last_badness > 100)
+ tprint_nl("Underfull \\vbox (badness ");
+ else
+ tprint_nl("Loose \\vbox (badness ");
+ print_int(last_badness);
+ goto COMMON_ENDING;
+ }
+ }
+ }
+ return r;
+
+ } else {
+ /* Determine vertical glue shrink setting, then |return|
+ or \hbox{|goto common_ending|} */
+ /* Determine the shrink order */
+ if (total_shrink[filll] != 0)
+ o = filll;
+ else if (total_shrink[fill] != 0)
+ o = fill;
+ else if (total_shrink[fil] != 0)
+ o = fil;
+ else if (total_shrink[sfi] != 0)
+ o = sfi;
+ else
+ o = normal;
+
+ glue_order(r) = (quarterword) o;
+ glue_sign(r) = shrinking;
+ if (total_shrink[o] != 0) {
+ glue_set(r) = unfloat((double) (-x) / total_shrink[o]);
+ } else {
+ glue_sign(r) = normal;
+ set_glue_ratio_zero(glue_set(r)); /* there's nothing to shrink */
+ }
+ if ((total_shrink[o] < -x) && (o == normal) && (list_ptr(r) != null)) {
+ last_badness = 1000000;
+ set_glue_ratio_one(glue_set(r)); /* use the maximum shrinkage */
+ /* Report an overfull vbox and |goto common_ending|, if this box is sufficiently bad */
+ if ((-x - total_shrink[normal] > dimen_par(vfuzz_code))
+ || (int_par(vbadness_code) < 100)) {
+ print_ln();
+ tprint_nl("Overfull \\vbox (");
+ print_scaled(-x - total_shrink[normal]);
+ tprint("pt too high");
+ goto COMMON_ENDING;
+ }
+ } else if (o == normal) {
+ if (list_ptr(r) != null) {
+ /* Report a tight vbox and |goto common_ending|, if this box is sufficiently bad */
+ last_badness = badness(-x, total_shrink[normal]);
+ if (last_badness > int_par(vbadness_code)) {
+ print_ln();
+ tprint_nl("Tight \\vbox (badness ");
+ print_int(last_badness);
+ goto COMMON_ENDING;
+ }
+ }
+ }
+ return r;
+ }
+
+ COMMON_ENDING:
+ /* Finish issuing a diagnostic message or an overfull or underfull vbox */
+ if (output_active) {
+ tprint(") has occurred while \\output is active");
+ } else {
+ if (pack_begin_line != 0) { /* it's actually negative */
+ tprint(") in alignment at lines ");
+ print_int(abs(pack_begin_line));
+ tprint("--");
+ } else {
+ tprint(") detected at line ");
+ }
+ print_int(line);
+ print_ln();
+ }
+ begin_diagnostic();
+ show_box(r);
+ end_diagnostic(true);
+ return r;
+}
+
+@ @c
+halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, int grp,
+ int pack_direction)
+{
+ halfword q;
+ q = p;
+ q = lua_vpack_filter(q, h, m, l, grp, pack_direction);
+ return vpackage(q, h, m, l, pack_direction);
+}
+
+@ @c
+void finish_vcenter(void)
+{
+ halfword p;
+ unsave();
+ save_ptr--;
+ p = vpack(vlink(cur_list.head_field), saved_value(0), saved_level(0), -1);
+ pop_nest();
+ p = math_vcenter_group(p);
+ tail_append(p);
+}
+
+@ @c
+void package(int c)
+{
+ scaled h; /* height of box */
+ halfword p; /* first node in a box */
+ scaled d; /* max depth */
+ int grp;
+ grp = cur_group;
+ d = box_max_depth;
+ unsave();
+ save_ptr -= 4;
+ if (cur_list.mode_field == -hmode) {
+ cur_box = filtered_hpack(cur_list.head_field,
+ cur_list.tail_field, saved_value(1),
+ saved_level(1), grp, saved_level(2));
+ subtype(cur_box) = HLIST_SUBTYPE_HBOX;
+ } else {
+ cur_box = filtered_vpackage(vlink(cur_list.head_field),
+ saved_value(1), saved_level(1), d, grp,
+ saved_level(2));
+ if (c == vtop_code) {
+ /* Readjust the height and depth of |cur_box|, for \.{\\vtop} */
+ /* The height of a `\.{\\vtop}' box is inherited from the first item on its list,
+ if that item is an |hlist_node|, |vlist_node|, or |rule_node|; otherwise
+ the \.{\\vtop} height is zero.
+ */
+
+ h = 0;
+ p = list_ptr(cur_box);
+ if (p != null)
+ if (type(p) <= rule_node)
+ h = height(p);
+ depth(cur_box) = depth(cur_box) - h + height(cur_box);
+ height(cur_box) = h;
+
+ }
+ }
+ if (saved_value(2) != null) {
+ /* DIR: Adjust back |text_dir_ptr| for |scan_spec| */
+ flush_node_list(text_dir_ptr);
+ text_dir_ptr = saved_value(2);
+
+ }
+ replace_attribute_list(cur_box, saved_value(3));
+ pop_nest();
+ box_end(saved_value(0));
+}
+
+
+
+@ When a box is being appended to the current vertical list, the
+baselineskip calculation is handled by the |append_to_vlist| routine.
+
+@c
+void append_to_vlist(halfword b)
+{
+ scaled d; /* deficiency of space between baselines */
+ halfword p; /* a new glue node */
+ if (prev_depth > dimen_par(pdf_ignored_dimen_code)) {
+ if ((type(b) == hlist_node) && is_mirrored(box_dir(b))) {
+ d = width(glue_par(baseline_skip_code)) - prev_depth - depth(b);
+ } else {
+ d = width(glue_par(baseline_skip_code)) - prev_depth - height(b);
+ }
+ if (d < dimen_par(line_skip_limit_code)) {
+ p = new_param_glue(line_skip_code);
+ } else {
+ p = new_skip_param(baseline_skip_code);
+ width(temp_ptr) = d; /* |temp_ptr=glue_ptr(p)| */
+ }
+ couple_nodes(cur_list.tail_field, p);
+ cur_list.tail_field = p;
+ }
+ couple_nodes(cur_list.tail_field, b);
+ cur_list.tail_field = b;
+ if ((type(b) == hlist_node) && is_mirrored(box_dir(b)))
+ prev_depth = height(b);
+ else
+ prev_depth = depth(b);
+}
+
+
+@ When |saving_vdiscards| is positive then the glue, kern, and penalty
+nodes removed by the page builder or by \.{\\vsplit} from the top of a
+vertical list are saved in special lists instead of being discarded.
+
+@c
+#define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */
+#define page_disc disc_ptr[last_box_code] /* first item removed by page builder */
+#define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */
+
+halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */
+
+
+@ The |vsplit| procedure, which implements \TeX's \.{\\vsplit} operation,
+is considerably simpler than |line_break| because it doesn't have to
+worry about hyphenation, and because its mission is to discover a single
+break instead of an optimum sequence of breakpoints. But before we get
+into the details of |vsplit|, we need to consider a few more basic things.
+
+A subroutine called |prune_page_top| takes a pointer to a vlist and
+returns a pointer to a modified vlist in which all glue, kern, and penalty nodes
+have been deleted before the first box or rule node. However, the first
+box or rule is actually preceded by a newly created glue node designed so that
+the topmost baseline will be at distance |split_top_skip| from the top,
+whenever this is possible without backspacing.
+
+When the second argument |s| is |false| the deleted nodes are destroyed,
+otherwise they are collected in a list starting at |split_disc|.
+
+@c
+halfword prune_page_top(halfword p, boolean s)
+{
+ halfword prev_p; /* lags one step behind |p| */
+ halfword q, r; /* temporary variables for list manipulation */
+ prev_p = temp_head;
+ vlink(temp_head) = p;
+ r = null;
+ while (p != null) {
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ case rule_node:
+ /* Insert glue for |split_top_skip| and set~|p:=null| */
+ q = new_skip_param(split_top_skip_code);
+ vlink(prev_p) = q;
+ vlink(q) = p; /* now |temp_ptr=glue_ptr(q)| */
+ if (width(temp_ptr) > height(p))
+ width(temp_ptr) = width(temp_ptr) - height(p);
+ else
+ width(temp_ptr) = 0;
+ p = null;
+ break;
+ case whatsit_node:
+ case mark_node:
+ case ins_node:
+ prev_p = p;
+ p = vlink(prev_p);
+ break;
+ case glue_node:
+ case kern_node:
+ case penalty_node:
+ q = p;
+ p = vlink(q);
+ vlink(q) = null;
+ vlink(prev_p) = p;
+ if (s) {
+ if (split_disc == null)
+ split_disc = q;
+ else
+ vlink(r) = q;
+ r = q;
+ } else {
+ flush_node_list(q);
+ }
+ break;
+ default:
+ confusion("pruning");
+ break;
+ }
+ }
+ return vlink(temp_head);
+}
+
+
+@ The next subroutine finds the best place to break a given vertical list
+so as to obtain a box of height~|h|, with maximum depth~|d|.
+A pointer to the beginning of the vertical list is given,
+and a pointer to the optimum breakpoint is returned. The list is effectively
+followed by a forced break, i.e., a penalty node with the |eject_penalty|;
+if the best break occurs at this artificial node, the value |null| is returned.
+
+@c
+scaled active_height[10]; /* distance from first active node to~|cur_p| */
+
+
+@ An array of six |scaled| distances is used to keep track of the height
+from the beginning of the list to the current place, just as in |line_break|.
+In fact, we use one of the same arrays, only changing its name to reflect
+its new significance.
+
+@c
+#define do_all_six(A) A(1);A(2);A(3);A(4);A(5);A(6);A(7)
+#define set_height_zero(A) active_height[A]=0 /* initialize the height to zero */
+
+
+@ A global variable |best_height_plus_depth| will be set to the natural size
+of the box that corresponds to the optimum breakpoint found by |vert_break|.
+(This value is used by the insertion-splitting algorithm of the page builder.)
+
+@c
+scaled best_height_plus_depth; /* height of the best box, without stretching or shrinking */
+
+halfword vert_break(halfword p, scaled h, scaled d)
+{ /* finds optimum page break */
+ halfword prev_p; /* if |p| is a glue node, |type(prev_p)| determines
+ whether |p| is a legal breakpoint */
+ halfword q, r; /* glue specifications */
+ int pi; /* penalty value */
+ int b; /* badness at a trial breakpoint */
+ int least_cost; /* the smallest badness plus penalties found so far */
+ halfword best_place; /* the most recent break that leads to |least_cost| */
+ scaled prev_dp; /* depth of previous box in the list */
+ int t; /* |type| of the node following a kern */
+ prev_p = p; /* an initial glue node is not a legal breakpoint */
+ least_cost = awful_bad;
+ do_all_six(set_height_zero);
+ prev_dp = 0;
+ best_place = null;
+ pi = 0;
+ while (1) {
+ /* If node |p| is a legal breakpoint, check if this break is
+ the best known, and |goto done| if |p| is null or
+ if the page-so-far is already too full to accept more stuff */
+ /* A subtle point to be noted here is that the maximum depth~|d| might be
+ negative, so |cur_height| and |prev_dp| might need to be corrected even
+ after a glue or kern node. */
+
+ if (p == null) {
+ pi = eject_penalty;
+ } else {
+ /* Use node |p| to update the current height and depth measurements;
+ if this node is not a legal breakpoint, |goto not_found|
+ or |update_heights|,
+ otherwise set |pi| to the associated penalty at the break */
+ switch (type(p)) {
+ case hlist_node:
+ case vlist_node:
+ case rule_node:
+ cur_height = cur_height + prev_dp + height(p);
+ prev_dp = depth(p);
+ goto NOT_FOUND;
+ break;
+ case whatsit_node:
+ /* Process whatsit |p| in |vert_break| loop, |goto not_found| */
+ if ((subtype(p) == pdf_refxform_node)
+ || (subtype(p) == pdf_refximage_node)) {
+ cur_height = cur_height + prev_dp + height(p);
+ prev_dp = depth(p);
+ }
+ goto NOT_FOUND;
+ break;
+ case glue_node:
+ if (precedes_break(prev_p))
+ pi = 0;
+ else
+ goto UPDATE_HEIGHTS;
+ break;
+ case kern_node:
+ if (vlink(p) == null)
+ t = penalty_node;
+ else
+ t = type(vlink(p));
+ if (t == glue_node)
+ pi = 0;
+ else
+ goto UPDATE_HEIGHTS;
+ break;
+ case penalty_node:
+ pi = penalty(p);
+ break;
+ case mark_node:
+ case ins_node:
+ goto NOT_FOUND;
+ break;
+ default:
+ confusion("vertbreak");
+ break;
+ }
+ }
+ /* Check if node |p| is a new champion breakpoint; then |goto done|
+ if |p| is a forced break or if the page-so-far is already too full */
+ if (pi < inf_penalty) {
+ /* Compute the badness, |b|, using |awful_bad| if the box is too full */
+ if (cur_height < h) {
+ if ((active_height[3] != 0) || (active_height[4] != 0) ||
+ (active_height[5] != 0) || (active_height[6] != 0))
+ b = 0;
+ else
+ b = badness(h - cur_height, active_height[2]);
+ } else if (cur_height - h > active_height[7]) {
+ b = awful_bad;
+ } else {
+ b = badness(cur_height - h, active_height[7]);
+ }
+
+ if (b < awful_bad) {
+ if (pi <= eject_penalty)
+ b = pi;
+ else if (b < inf_bad)
+ b = b + pi;
+ else
+ b = deplorable;
+ }
+ if (b <= least_cost) {
+ best_place = p;
+ least_cost = b;
+ best_height_plus_depth = cur_height + prev_dp;
+ }
+ if ((b == awful_bad) || (pi <= eject_penalty))
+ goto DONE;
+ }
+
+ if ((type(p) < glue_node) || (type(p) > kern_node))
+ goto NOT_FOUND;
+ UPDATE_HEIGHTS:
+ /* Update the current height and depth measurements with
+ respect to a glue or kern node~|p| */
+ /* Vertical lists that are subject to the |vert_break| procedure should not
+ contain infinite shrinkability, since that would permit any amount of
+ information to ``fit'' on one page. */
+
+ if (type(p) == kern_node) {
+ q = p;
+ } else {
+ q = glue_ptr(p);
+ active_height[2 + stretch_order(q)] += stretch(q);
+ active_height[7] += shrink(q);
+ if ((shrink_order(q) != normal) && (shrink(q) != 0)) {
+ print_err("Infinite glue shrinkage found in box being split");
+ help4("The box you are \\vsplitting contains some infinitely",
+ "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
+ "Such glue doesn't belong there; but you can safely proceed,",
+ "since the offensive shrinkability has been made finite.");
+ error();
+ r = new_spec(q);
+ shrink_order(r) = normal;
+ delete_glue_ref(q);
+ glue_ptr(p) = r;
+ q = r;
+ }
+ }
+ cur_height = cur_height + prev_dp + width(q);
+ prev_dp = 0;
+
+ NOT_FOUND:
+ if (prev_dp > d) {
+ cur_height = cur_height + prev_dp - d;
+ prev_dp = d;
+ }
+
+ prev_p = p;
+ p = vlink(prev_p);
+ }
+ DONE:
+ return best_place;
+}
+
+
+@ Now we are ready to consider |vsplit| itself. Most of
+its work is accomplished by the two subroutines that we have just considered.
+
+Given the number of a vlist box |n|, and given a desired page height |h|,
+the |vsplit| function finds the best initial segment of the vlist and
+returns a box for a page of height~|h|. The remainder of the vlist, if
+any, replaces the original box, after removing glue and penalties and
+adjusting for |split_top_skip|. Mark nodes in the split-off box are used to
+set the values of |split_first_mark| and |split_bot_mark|; we use the
+fact that |split_first_mark(x)=null| if and only if |split_bot_mark(x)=null|.
+
+The original box becomes ``void'' if and only if it has been entirely
+extracted. The extracted box is ``void'' if and only if the original
+box was void (or if it was, erroneously, an hlist box).
+
+@c
+halfword vsplit(halfword n, scaled h)
+{ /* extracts a page of height |h| from box |n| */
+ halfword v; /* the box to be split */
+ int vdir; /* the direction of the box to be split */
+ halfword p; /* runs through the vlist */
+ halfword q; /* points to where the break occurs */
+ halfword i; /* for traversing marks lists */
+ v = box(n);
+ vdir = box_dir(v);
+ flush_node_list(split_disc);
+ split_disc = null;
+ for (i = 0; i <= biggest_used_mark; i++) {
+ delete_split_first_mark(i);
+ delete_split_bot_mark(i);
+ }
+ /* Dispense with trivial cases of void or bad boxes */
+ if (v == null) {
+ return null;
+ }
+ if (type(v) != vlist_node) {
+ print_err("\\vsplit needs a \\vbox");
+ help2("The box you are trying to split is an \\hbox.",
+ "i can't split such a box, so I''ll leave it alone.");
+ error();
+ return null;
+ }
+
+ q = vert_break(list_ptr(v), h, dimen_par(split_max_depth_code));
+ /* Look at all the marks in nodes before the break, and set the final
+ link to |null| at the break */
+ /* It's possible that the box begins with a penalty node that is the
+ ``best'' break, so we must be careful to handle this special case correctly. */
+
+ p = list_ptr(v);
+ if (p == q) {
+ list_ptr(v) = null;
+ } else {
+ while (1) {
+ if (type(p) == mark_node) {
+ if (split_first_mark(mark_class(p)) == null) {
+ set_split_first_mark(mark_class(p), mark_ptr(p));
+ set_split_bot_mark(mark_class(p),
+ split_first_mark(mark_class(p)));
+ set_token_ref_count(split_first_mark(mark_class(p)),
+ token_ref_count(split_first_mark
+ (mark_class(p))) + 2);
+ } else {
+ delete_token_ref(split_bot_mark(mark_class(p)));
+ set_split_bot_mark(mark_class(p), mark_ptr(p));
+ add_token_ref(split_bot_mark(mark_class(p)));
+ }
+ }
+ if (vlink(p) == q) {
+ vlink(p) = null;
+ break;
+ }
+ p = vlink(p);
+ }
+ }
+
+ q = prune_page_top(q, int_par(saving_vdiscards_code) > 0);
+ p = list_ptr(v);
+ list_ptr(v) = null;
+ flush_node(v);
+ if (q == null)
+ box(n) = null; /* the |eq_level| of the box stays the same */
+ else
+ box(n) =
+ filtered_vpackage(q, 0, additional, dimen_par(max_depth_code),
+ split_keep_group, vdir);
+ return filtered_vpackage(p, h, exactly,
+ dimen_par(split_max_depth_code), split_off_group,
+ vdir);
+}
+
+
+@ Now that we can see what eventually happens to boxes, we can consider
+the first steps in their creation. The |begin_box| routine is called when
+|box_context| is a context specification, |cur_chr| specifies the type of
+box desired, and |cur_cmd=make_box|.
+
+@c
+void begin_box(int box_context)
+{
+ halfword q; /* run through the current list */
+ halfword k; /* 0 or |vmode| or |hmode| */
+ int n; /* a box number */
+ int spec_direction = -1;
+ switch (cur_chr) {
+ case box_code:
+ scan_register_num();
+ cur_box = box(cur_val);
+ box(cur_val) = null; /* the box becomes void, at the same level */
+ break;
+ case copy_code:
+ scan_register_num();
+ cur_box = copy_node_list(box(cur_val));
+ break;
+ case last_box_code:
+ /* If the current list ends with a box node, delete it from
+ the list and make |cur_box| point to it; otherwise set |cur_box:=null| */
+ cur_box = null;
+ if (abs(cur_list.mode_field) == mmode) {
+ you_cant();
+ help1("Sorry; this \\lastbox will be void.");
+ error();
+ } else if ((cur_list.mode_field == vmode)
+ && (cur_list.head_field == cur_list.tail_field)) {
+ you_cant();
+ help2("Sorry...I usually can't take things from the current page.",
+ "This \\lastbox will therefore be void.");
+ error();
+ } else {
+ if (cur_list.head_field != cur_list.tail_field) { /* todo: new code, needs testing */
+ if ((type(cur_list.tail_field) == hlist_node)
+ || (type(cur_list.tail_field) == vlist_node)) {
+ /* Remove the last box ... */
+ q = alink(cur_list.tail_field);
+ if (q == null || vlink(q) != cur_list.tail_field) {
+ q = cur_list.head_field;
+ while (vlink(q) != cur_list.tail_field)
+ q = vlink(q);
+ }
+ uncouple_node(cur_list.tail_field);
+ cur_box = cur_list.tail_field;
+ shift_amount(cur_box) = 0;
+ cur_list.tail_field = q;
+ vlink(cur_list.tail_field) = null;
+ }
+ }
+ }
+ break;
+ case vsplit_code:
+ /* Split off part of a vertical box, make |cur_box| point to it */
+ /* Here we deal with things like `\.{\\vsplit 13 to 100pt}'. */
+ scan_register_num();
+ n = cur_val;
+ if (!scan_keyword("to")) {
+ print_err("Missing `to' inserted");
+ help2("I'm working on `\\vsplit<box number> to <dimen>';",
+ "will look for the <dimen> next.");
+ error();
+ }
+ scan_normal_dimen();
+ cur_box = vsplit(n, cur_val);
+ break;
+ default:
+ /* Initiate the construction of an hbox or vbox, then |return| */
+ /* Here is where we enter restricted horizontal mode or internal vertical
+ mode, in order to make a box. */
+ k = cur_chr - vtop_code;
+ set_saved_record(0, saved_boxcontext, 0, box_context);
+ switch (abs(cur_list.mode_field)) {
+ case vmode:
+ spec_direction = body_direction;
+ break;
+ case hmode:
+ spec_direction = text_direction;
+ break;
+ case mmode:
+ spec_direction = math_direction;
+ break;
+ }
+ if (k == hmode) {
+ if ((box_context < box_flag) && (abs(cur_list.mode_field) == vmode))
+ scan_full_spec(adjusted_hbox_group, spec_direction);
+ else
+ scan_full_spec(hbox_group, spec_direction);
+ } else {
+ if (k == vmode) {
+ scan_full_spec(vbox_group, spec_direction);
+ } else {
+ scan_full_spec(vtop_group, spec_direction);
+ k = vmode;
+ }
+ normal_paragraph();
+ }
+ push_nest();
+ cur_list.mode_field = -k;
+ if (k == vmode) {
+ prev_depth = dimen_par(pdf_ignored_dimen_code);
+ if (every_vbox != null)
+ begin_token_list(every_vbox, every_vbox_text);
+ } else {
+ space_factor = 1000;
+ if (every_hbox != null)
+ begin_token_list(every_hbox, every_hbox_text);
+ }
+ return;
+ break;
+ }
+ box_end(box_context); /* in simple cases, we use the box immediately */
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h
new file mode 100644
index 00000000000..fb0e4d9ca6d
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h
@@ -0,0 +1,59 @@
+/* postlinebreak.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: postlinebreak.h 3493 2010-03-15 11:49:49Z taco $ */
+
+#ifndef POSTLINEBREAK_H
+# define POSTLINEBREAK_H
+
+/* todo: check this macro, especially values of alink() */
+
+# define append_list(A,B) do { \
+ vlink(cur_list.tail_field) = vlink((A)); \
+ cur_list.tail_field = (B); \
+ } while (0)
+
+
+void ext_post_line_break(int paragraph_dir,
+ int right_skip,
+ int left_skip,
+ int pdf_protrude_chars,
+ halfword par_shape_ptr,
+ int pdf_adjust_spacing,
+ int pdf_each_line_height,
+ int pdf_each_line_depth,
+ int pdf_first_line_height,
+ int pdf_last_line_depth,
+ halfword inter_line_penalties_ptr,
+ int inter_line_penalty,
+ int club_penalty,
+ halfword club_penalties_ptr,
+ halfword widow_penalties_ptr,
+ int widow_penalty,
+ int broken_penalty,
+ halfword final_par_glue,
+ halfword best_bet,
+ halfword last_special_line,
+ scaled second_width,
+ scaled second_indent,
+ scaled first_width,
+ scaled first_indent, halfword best_line,
+ halfword pdf_ignored_dimen);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w
index f27094ea5f8..908224f0b47 100644
--- a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c
+++ b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w
@@ -1,30 +1,30 @@
-/* postlinebreak.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% postlinebreak.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "nodes.h"
+@ @c
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: postlinebreak.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/postlinebreak.c $";
+ "$Id: postlinebreak.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/postlinebreak.w $";
-/* So far we have gotten a little way into the |line_break| routine, having
+@ So far we have gotten a little way into the |line_break| routine, having
covered its important |try_break| subroutine. Now let's consider the
rest of the process.
@@ -40,25 +40,7 @@ meaning of |prev_p| is this: If |type(cur_p)=glue_node| then |cur_p| is a legal
breakpoint if and only if |auto_breaking| is true and |prev_p| does not
point to a glue node, penalty node, explicit kern node, or math node.
-*/
-
-static halfword do_push_dir_node(halfword p, halfword a)
-{
- halfword n;
- n = copy_node(a);
- vlink(n) = p;
- return n;
-}
-
-static halfword do_pop_dir_node(halfword p)
-{
- halfword n = vlink(p);
- flush_node(p);
- return n;
-}
-
-
-/* The total number of lines that will be set by |post_line_break|
+@ The total number of lines that will be set by |post_line_break|
is |best_line-prev_graf-1|. The last breakpoint is specified by
|break_node(best_bet)|, and this passive node points to the other breakpoints
via the |prev_break| links. The finishing-up phase starts by linking the
@@ -71,18 +53,11 @@ The |post_line_break| must also keep an dir stack, so that it can
output end direction instructions at the ends of lines
and begin direction instructions at the beginnings of lines.
-*/
-
+@c
#define next_break prev_break /*new name for |prev_break| after links are reversed */
-#define append_list(a,b) \
- { vlink(cur_list.tail_field)=vlink((a)); cur_list.tail_field = b; }
-
-#define left_skip_code 7 /*glue at left of justified lines */
-#define right_skip_code 8 /*glue at right of justified lines */
-
/* the ints are actually halfwords */
-void ext_post_line_break(boolean d,
+void ext_post_line_break(int paragraph_dir,
int right_skip,
int left_skip,
int pdf_protrude_chars,
@@ -96,9 +71,7 @@ void ext_post_line_break(boolean d,
int inter_line_penalty,
int club_penalty,
halfword club_penalties_ptr,
- halfword display_widow_penalties_ptr,
halfword widow_penalties_ptr,
- int display_widow_penalty,
int widow_penalty,
int broken_penalty,
halfword final_par_glue,
@@ -120,13 +93,13 @@ void ext_post_line_break(boolean d,
boolean post_disc_break; /*and did it have a nonempty post-break part? */
scaled cur_width; /*width of line number |cur_line| */
scaled cur_indent; /*left margin of line number |cur_line| */
- integer pen; /*use when calculating penalties between lines */
- halfword cur_p; /* cur_p, but localized */
+ int pen; /*use when calculating penalties between lines */
+ halfword cur_p; /* |cur_p|, but localized */
halfword cur_line; /*the current line number being justified */
dir_ptr = cur_list.dirs_field;
- /* @<Reverse the links of the relevant passive nodes, setting |cur_p| to
- the first breakpoint@>; */
+ /* Reverse the links of the relevant passive nodes, setting |cur_p| to
+ the first breakpoint; */
/* The job of reversing links in a list is conveniently regarded as the job
of taking items off one stack and putting them on another. In this case we
take them off a stack pointed to by |q| and having |prev_break| fields;
@@ -134,8 +107,10 @@ void ext_post_line_break(boolean d,
Node |r| is the passive node being moved from stack to stack.
*/
q = break_node(best_bet);
- /*used_discs = used_disc(best_bet); */
- /*has_direction */
+#if 0
+ used_discs = used_disc(best_bet);
+#endif
+ /* |has_direction| */
cur_p = null;
do {
r = q;
@@ -148,9 +123,9 @@ void ext_post_line_break(boolean d,
cur_line = cur_list.pg_field + 1; /* prevgraf+1 */
do {
- /* @<Justify the line ending at breakpoint |cur_p|, and append it to the
+ /* Justify the line ending at breakpoint |cur_p|, and append it to the
current vertical list, together with associated penalties and other
- insertions@>; */
+ insertions; */
/* The current line to be justified appears in a horizontal list starting
at |vlink(temp_head)| and ending at |cur_break(cur_p)|. If |cur_break(cur_p)| is
a glue node, we reset the glue to equal the |right_skip| glue; otherwise
@@ -171,8 +146,11 @@ void ext_post_line_break(boolean d,
for (q = dir_ptr; q != null; q = vlink(q)) {
halfword tmp = new_dir(dir_dir(q));
halfword nxt = vlink(temp_head);
+ delete_attribute_ref(node_attr(tmp));
+ node_attr(tmp) = node_attr(temp_head);
+ add_node_attr_ref(node_attr(tmp));
couple_nodes(temp_head, tmp);
- try_couple_nodes(tmp, nxt); /* \break\par */
+ try_couple_nodes(tmp, nxt); /* \.{\\break}\.{\\par} */
}
if (dir_ptr != null) {
flush_node_list(dir_ptr);
@@ -296,10 +274,13 @@ void ext_post_line_break(boolean d,
}
assert(e == cur_break(cur_p));
- /* @<DIR: Insert dir nodes at the end of the current line@>; */
+ /* DIR: Insert dir nodes at the end of the current line; */
e = vlink(r);
for (p = dir_ptr; p != null; p = vlink(p)) {
halfword s = new_dir(dir_dir(p) - 64);
+ delete_attribute_ref(node_attr(s));
+ node_attr(s) = node_attr(r);
+ add_node_attr_ref(node_attr(s));
couple_nodes(r, s);
try_couple_nodes(s, e);
r = s;
@@ -334,11 +315,14 @@ void ext_post_line_break(boolean d,
p = alink(q); /* get |vlink(p) = q| */
assert(vlink(p) == q);
ptmp = p;
- p = find_protchar_right(vlink(temp_head), p);
}
+ p = find_protchar_right(vlink(temp_head), p);
w = char_pw(p, right_side);
if (w != 0) { /* we have found a marginal kern, append it after |ptmp| */
k = new_margin_kern(-w, last_rightmost_char, right_side);
+ delete_attribute_ref(node_attr(k));
+ node_attr(k) = node_attr(p);
+ add_node_attr_ref(node_attr(k));
vlink(k) = vlink(ptmp);
vlink(ptmp) = k;
if (ptmp == q)
@@ -348,17 +332,23 @@ void ext_post_line_break(boolean d,
/* if |q| was not a breakpoint at glue and has been reset to |rightskip|
then we append |rightskip| after |q| now */
if (!glue_break) {
- /* @<Put the \(r)\.{\\rightskip} glue after node |q|@>; */
- halfword r = new_param_glue(right_skip_code);
+ /* Put the \.{\\rightskip} glue after node |q|; */
+ halfword r = new_glue((right_skip == null ? null : copy_node(right_skip)));
+ glue_ref_count(glue_ptr(r)) = null;
+ subtype(r) = right_skip_code;
vlink(r) = vlink(q);
+ delete_attribute_ref(node_attr(r));
+ node_attr(r) = node_attr(q);
+ add_node_attr_ref(node_attr(r));
vlink(q) = r;
+ alink(r) = q;
q = r;
}
/* /Modify the end of the line to reflect the nature of the break and to
include \.{\\rightskip}; also set the proper value of |disc_break|; */
- /* Put the \(l)\.{\\leftskip} glue at the left and detach this line; */
+ /* Put the \.{\\leftskip} glue at the left and detach this line; */
/* The following code begins with |q| at the end of the list to be
justified. It ends with |q| at the beginning of that list, and with
|vlink(temp_head)| pointing to the remainder of the paragraph, if any. */
@@ -390,16 +380,25 @@ void ext_post_line_break(boolean d,
w = char_pw(p, left_side);
if (w != 0) {
k = new_margin_kern(-w, last_leftmost_char, left_side);
+ delete_attribute_ref(node_attr(k));
+ node_attr(k) = node_attr(q);
+ add_node_attr_ref(node_attr(k));
vlink(k) = q;
q = k;
}
};
if (left_skip != zero_glue) {
- r = new_param_glue(left_skip_code);
+ r = new_glue(copy_node(left_skip));
+ glue_ref_count(glue_ptr(r)) = null;
+ subtype(r) = left_skip_code;
+ delete_attribute_ref(node_attr(r));
+ node_attr(r) = node_attr(q);
+ add_node_attr_ref(node_attr(r));
vlink(r) = q;
+ alink(q) = r;
q = r;
}
- /* /Put the \(l)\.{\\leftskip} glue at the left and detach this line; */
+ /* /Put the \.{\\leftskip} glue at the left and detach this line; */
/* Call the packaging subroutine, setting |just_box| to the justified box; */
/* Now |q| points to the hlist that represents the current line of the
@@ -417,14 +416,14 @@ void ext_post_line_break(boolean d,
cur_width = varmem[(par_shape_ptr + 2 * cur_line + 1)].cint;
}
adjust_tail = adjust_head;
- pack_direction = paragraph_dir;
pre_adjust_tail = pre_adjust_head;
if (pdf_adjust_spacing > 0) {
- just_box = hpack(q, cur_width, cal_expand_ratio);
+ just_box = hpack(q, cur_width, cal_expand_ratio, paragraph_dir);
} else {
- just_box = hpack(q, cur_width, exactly);
+ just_box = hpack(q, cur_width, exactly, paragraph_dir);
}
shift_amount(just_box) = cur_indent;
+ subtype(just_box) = HLIST_SUBTYPE_LINE;
/* /Call the packaging subroutine, setting |just_box| to the justified box; */
/* Append the new box to the current vertical list, followed by the list of
@@ -440,12 +439,23 @@ void ext_post_line_break(boolean d,
&& (cur_line + 1 == best_line))
depth(just_box) = pdf_last_line_depth;
- if (pre_adjust_head != pre_adjust_tail)
+ if ((vlink(contrib_head) != null))
+ if (!output_active)
+ lua_node_filter_s(buildpage_filter_callback, "pre_box");
+ if (pre_adjust_head != pre_adjust_tail) {
append_list(pre_adjust_head, pre_adjust_tail);
+ if (!output_active)
+ lua_node_filter_s(buildpage_filter_callback, "pre_adjust");
+ }
pre_adjust_tail = null;
append_to_vlist(just_box);
- if (adjust_head != adjust_tail)
+ if (!output_active)
+ lua_node_filter_s(buildpage_filter_callback, "box");
+ if (adjust_head != adjust_tail) {
append_list(adjust_head, adjust_tail);
+ if (!output_active)
+ lua_node_filter_s(buildpage_filter_callback, "adjust");
+ }
adjust_tail = null;
/* /Append the new box to the current vertical list, followed by the list of
@@ -481,20 +491,14 @@ void ext_post_line_break(boolean d,
} else if (cur_line == cur_list.pg_field + 1) { /* prevgraf */
pen += club_penalty;
}
- if (d)
- q = display_widow_penalties_ptr;
- else
- q = widow_penalties_ptr;
+ q = widow_penalties_ptr;
if (q != null) {
r = best_line - cur_line - 1;
if (r > penalty(q))
r = penalty(q);
pen += penalty(q + r);
} else if (cur_line + 2 == best_line) {
- if (d)
- pen += display_widow_penalty;
- else
- pen += widow_penalty;
+ pen += widow_penalty;
}
if (disc_break) {
if (passive_pen_broken(cur_p) != 0) {
@@ -513,11 +517,11 @@ void ext_post_line_break(boolean d,
/* /Justify the line ending at breakpoint |cur_p|, and append it to the
current vertical list, together with associated penalties and other
- insertions@>; */
+ insertions; */
incr(cur_line);
cur_p = next_break(cur_p);
if (cur_p != null && !post_disc_break) {
- /* @<Prune unwanted nodes at the beginning of the next line@>; */
+ /* Prune unwanted nodes at the beginning of the next line; */
/* Glue and penalty and kern and math nodes are deleted at the
beginning of a line, except in the anomalous case that the
node to be deleted is actually one of the chosen
@@ -546,8 +550,8 @@ void ext_post_line_break(boolean d,
}
} while (cur_p != null);
if ((cur_line != best_line) || (vlink(temp_head) != null))
- tconfusion("line breaking");
+ confusion("line breaking");
cur_list.pg_field = best_line - 1; /* prevgraf */
- cur_list.dirs_field = dir_ptr; /* dir_save */
+ cur_list.dirs_field = dir_ptr; /* |dir_save| */
dir_ptr = null;
}
diff --git a/Build/source/texk/web2c/luatexdir/primitive.h b/Build/source/texk/web2c/luatexdir/tex/primitive.h
index 75e6b3cffe5..08459aa014f 100644
--- a/Build/source/texk/web2c/luatexdir/primitive.h
+++ b/Build/source/texk/web2c/luatexdir/tex/primitive.h
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: primitive.h 2271 2009-04-12 23:42:21Z oneiros $ */
+/* $Id: primitive.h 3385 2010-01-26 05:45:55Z taco $ */
#ifndef LUATEX_PRIMITIVE_H
# define LUATEX_PRIMITIVE_H 1
@@ -32,19 +32,29 @@ typedef enum {
pdftex_command = 16,
luatex_command = 32,
core_command = 64,
+ no_command = 128,
} command_origin;
-# define eq_level(a) zeqtb[a].hh.u.B1
-# define eq_type(a) zeqtb[a].hh.u.B0
-# define equiv(a) zeqtb[a].hh.v.RH
+# define hash_size 65536 /* maximum number of control sequences; it should be at most about |(fix_mem_max-fix_mem_min)/10| */
+
+# define hash_prime 55711 /* a prime number equal to about 85\pct! of |hash_size| */
+
+extern two_halves *hash; /* the hash table */
+extern halfword hash_used; /* allocation pointer for |hash| */
+extern int hash_extra; /* |hash_extra=hash| above |eqtb_size| */
+extern halfword hash_top; /* maximum of the hash array */
+extern halfword hash_high; /* pointer to next high hash location */
+extern boolean no_new_control_sequence; /* are new identifiers legal? */
+extern int cs_count; /* total number of known identifiers */
+
+# define cs_next(a) hash[(a)].lhfield /* link for coalesced lists */
+# define cs_text(a) hash[(a)].rh
+ /* string number for control sequence name */
# define undefined_primitive 0
# define prim_size 2100 /* maximum number of primitives */
# define prim_prime 1777 /* about 85\pct! of |primitive_size| */
-# define hash_prime 55711 /* a prime number equal to about 85\pct! of |hash_size| */
-# define hash_base 2
-
extern void init_primitives(void);
extern void ini_init_primitives(void);
@@ -54,10 +64,10 @@ extern pointer prim_lookup(str_number s);
extern boolean is_primitive(str_number csname);
-extern quarterword get_prim_eq_type(integer p);
-extern halfword get_prim_equiv(integer p);
-extern str_number get_prim_text(integer p);
-extern quarterword get_prim_origin(integer p);
+extern quarterword get_prim_eq_type(int p);
+extern halfword get_prim_equiv(int p);
+extern str_number get_prim_text(int p);
+extern quarterword get_prim_origin(int p);
extern void dump_primitives(void);
extern void undump_primitives(void);
@@ -69,14 +79,14 @@ extern void undump_primitives(void);
# define primitive_pdftex(a,b,c,d) primitive((a),(b),(c),(d),pdftex_command)
# define primitive_luatex(a,b,c,d) primitive((a),(b),(c),(d),luatex_command)
# define primitive_core(a,b,c,d) primitive((a),(b),(c),(d),core_command)
+# define primitive_no(a,b,c,d) primitive((a),(b),(c),(d),no_command)
-extern void primitive(str_number ss, quarterword c, halfword o, halfword off,
+extern void primitive(const char *ss, quarterword c, halfword o, halfword off,
int cmd_origin);
-extern void primitive_def(char *s, size_t l, quarterword c, halfword o);
+extern void primitive_def(const char *s, size_t l, quarterword c, halfword o);
extern void print_cmd_chr(quarterword cmd, halfword chr_code);
extern pointer string_lookup(const char *s, size_t l);
-extern pointer id_lookup(integer j, integer l);
-
+extern pointer id_lookup(int j, int l);
#endif /* LUATEX_PRIMITIVE_H */
diff --git a/Build/source/texk/web2c/luatexdir/tex/primitive.c b/Build/source/texk/web2c/luatexdir/tex/primitive.w
index f98fbcd4e89..89db63fbeaa 100644
--- a/Build/source/texk/web2c/luatexdir/tex/primitive.c
+++ b/Build/source/texk/web2c/luatexdir/tex/primitive.w
@@ -1,72 +1,77 @@
-/* primitive.c
+% primitive.w
- Copyright 2008-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 2008-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
+@ @c
+#include "ptexlib.h"
-#include "commands.h"
-#include "primitive.h"
-#include "tokens.h"
static const char _svn_version[] =
- "$Id: primitive.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/primitive.c $";
+ "$Id: primitive.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/primitive.w $";
+
+
+@ Control sequences are stored and retrieved by means of a fairly standard hash
+table algorithm called the method of ``coalescing lists'' (cf.\ Algorithm 6.4C
+in {\sl The Art of Computer Programming\/}). Once a control sequence enters the
+table, it is never removed, because there are complicated situations
+involving \.{\\gdef} where the removal of a control sequence at the end of
+a group would be a mistake preventable only by the introduction of a
+complicated reference-count mechanism.
+
+The actual sequence of letters forming a control sequence identifier is
+stored in the |str_pool| array together with all the other strings. An
+auxiliary array |hash| consists of items with two halfword fields per
+word. The first of these, called |next(p)|, points to the next identifier
+belonging to the same coalesced list as the identifier corresponding to~|p|;
+and the other, called |text(p)|, points to the |str_start| entry for
+|p|'s identifier. If position~|p| of the hash table is empty, we have
+|text(p)=0|; if position |p| is either empty or the end of a coalesced
+hash list, we have |next(p)=0|. An auxiliary pointer variable called
+|hash_used| is maintained in such a way that all locations |p>=hash_used|
+are nonempty. The global variable |cs_count| tells how many multiletter
+control sequences have been defined, if statistics are being kept.
+
+A global boolean variable called |no_new_control_sequence| is set to
+|true| during the time that new hash table entries are forbidden.
+
+@c
+two_halves *hash; /* the hash table */
+halfword hash_used; /* allocation pointer for |hash| */
+int hash_extra; /* |hash_extra=hash| above |eqtb_size| */
+halfword hash_top; /* maximum of the hash array */
+halfword hash_high; /* pointer to next high hash location */
+boolean no_new_control_sequence; /* are new identifiers legal? */
+int cs_count; /* total number of known identifiers */
-/* as usual, the file starts with a bunch of #defines that mimic pascal @ds */
-
-#define level_one 1
-#define flush_string() do { decr(str_ptr); pool_ptr=str_start_macro(str_ptr); } while (0)
-#define cur_length (pool_ptr - str_start_macro(str_ptr))
-#define append_char(a) str_pool[pool_ptr++]=(a)
-
-#define next(a) hash[(a)].lhfield /* link for coalesced lists */
-#define text(a) hash[(a)].rh /* string number for control sequence name */
#define hash_is_full (hash_used==hash_base) /* test if all positions are occupied */
-#define hash_size 65536
-
-#define span_code 1114113
-#define unless_code 32 /* amount added for `\.{\\unless}' prefix */
-#define protected_token 0x1C00001 /* $2^{21}\cdot|end_match|+1$ */
-#define offset_ocp_name 1
-#define ocp_name(A) ocp_tables[(A)][offset_ocp_name]
-
-#define skip_base get_skip_base()
-#define mu_skip_base get_mu_skip_base()
-#define glue_base static_glue_base
-#define toks_base get_toks_base()
-#define count_base get_count_base()
-#define int_base static_int_base
-#define attribute_base get_attribute_base()
-#define scaled_base get_scaled_base()
-#define dimen_base get_dimen_base()
+@ \.{\\primitive} support needs a few extra variables and definitions
-
-/* \primitive support needs a few extra variables and definitions */
-
+@c
#define prim_base 1
-/* The arrays |prim| and |prim_eqtb| are used for name -> cmd,chr lookups.
- *
- * The are modelled after |hash| and |eqtb|, except that primitives do not
- * have an |eq_level|, that field is replaced by |origin|.
- */
+@ The arrays |prim| and |prim_eqtb| are used for name -> cmd,chr lookups.
+
+ The are modelled after |hash| and |eqtb|, except that primitives do not
+ have an |eq_level|, that field is replaced by |origin|.
+@c
#define prim_next(a) prim[(a)].lhfield /* link for coalesced lists */
#define prim_text(a) prim[(a)].rh /* string number for control sequence name */
#define prim_is_full (prim_used==prim_base) /* test if all positions are occupied */
@@ -82,9 +87,10 @@ static pointer prim_used; /* allocation pointer for |prim| */
static two_halves prim[(prim_size + 1)]; /* the primitives table */
static memory_word prim_eqtb[(prim_size + 1)];
-/* The array |prim_data| works the other way around, it is used for
- cmd,chr -> name lookups. */
+@ The array |prim_data| works the other way around, it is used for
+ cmd,chr -> name lookups.
+@c
typedef struct prim_info {
halfword subids; /* number of name entries */
halfword offset; /* offset to be used for |chr_code|s */
@@ -93,8 +99,8 @@ typedef struct prim_info {
static prim_info prim_data[(last_cmd + 1)];
-/* initialize the memory arrays */
-
+@ initialize the memory arrays
+@c
void init_primitives(void)
{
int k;
@@ -111,16 +117,17 @@ void ini_init_primitives(void)
}
-/* The value of |hash_prime| should be roughly 85\pct! of |hash_size|, and it
+@ The value of |hash_prime| should be roughly 85\%! 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@>
-*/
-static halfword compute_hash(const char *j, pool_pointer l, halfword prime_number)
+@c
+static halfword compute_hash(const char *j, unsigned int l,
+ halfword prime_number)
{
- pool_pointer k;
+ unsigned int k;
halfword h = (unsigned char) *j;
for (k = 1; k <= l - 1; k++) {
h = h + h + (unsigned char) *(j + k);
@@ -131,29 +138,27 @@ static halfword compute_hash(const char *j, pool_pointer l, halfword prime_numbe
}
-/* Here is the subroutine that searches the primitive table for an identifier */
-
+@ Here is the subroutine that searches the primitive table for an identifier
+@c
pointer prim_lookup(str_number s)
{
- integer h; /* hash code */
+ int h; /* hash code */
pointer p; /* index in |hash| array */
- pool_pointer j, l;
- if (s < string_offset) {
+ unsigned char *j;
+ unsigned l;
+ if (s < STRING_OFFSET) {
p = s;
if ((p < 0) || (get_prim_eq_type(p) == undefined_cs_cmd)) {
p = undefined_primitive;
}
} else {
- j = str_start_macro(s);
- if (s == str_ptr)
- l = cur_length;
- else
- l = length(s);
- h = compute_hash((char *) (str_pool + j), l, prim_prime);
+ j = str_string(s);
+ l = (unsigned) str_length(s);
+ h = compute_hash((char *) j, l, prim_prime);
p = h + prim_base; /* we start searching here; note that |0<=h<hash_prime| */
while (1) {
if (prim_text(p) > 0)
- if (length(prim_text(p)) == l)
+ if (str_length(prim_text(p)) == l)
if (str_eq_str(prim_text(p), s))
goto FOUND;
if (prim_next(p) == 0) {
@@ -164,7 +169,7 @@ pointer prim_lookup(str_number s)
if (prim_text(p) > 0) {
do { /* search for an empty location in |prim| */
if (prim_is_full)
- overflow_string("primitive size", prim_size);
+ overflow("primitive size", prim_size);
decr(prim_used);
} while (prim_text(prim_used) != 0);
prim_next(p) = prim_used;
@@ -181,44 +186,47 @@ pointer prim_lookup(str_number s)
return p;
}
-/* how to test a csname for primitive-ness */
-
+@ how to test a csname for primitive-ness
+@c
boolean is_primitive(str_number csname)
{
- integer n, m;
+ int n, m;
+ char *ss;
m = prim_lookup(csname);
- n = string_lookup(makecstring(csname), length(csname));
+ ss = makecstring(csname);
+ n = string_lookup(ss, str_length(csname));
+ free(ss);
return ((n != undefined_cs_cmd) &&
(m != undefined_primitive) &&
(eq_type(n) == prim_eq_type(m)) && (equiv(n) == prim_equiv(m)));
}
-/* a few simple accessors */
-
-quarterword get_prim_eq_type(integer p)
+@ a few simple accessors
+@c
+quarterword get_prim_eq_type(int p)
{
return prim_eq_type(p);
}
-quarterword get_prim_origin(integer p)
+quarterword get_prim_origin(int p)
{
return prim_origin(p);
}
-halfword get_prim_equiv(integer p)
+halfword get_prim_equiv(int p)
{
return prim_equiv(p);
}
-str_number get_prim_text(integer p)
+str_number get_prim_text(int p)
{
return prim_text(p);
}
-/* dumping and undumping */
-
+@ dumping and undumping
+@c
void dump_primitives(void)
{
int p, q;
@@ -247,30 +255,29 @@ void undump_primitives(void)
undump_int(prim_data[p].offset);
undump_int(prim_data[p].subids);
if (prim_data[p].subids > 0) {
- prim_data[p].names =
- (str_number *) xcalloc((prim_data[p].subids),
- sizeof(str_number *));
- }
- for (q = 0; q < prim_data[p].subids; q++) {
- undump_int(prim_data[p].names[q]);
+ prim_data[p].names = (str_number *)
+ xmalloc((unsigned)
+ ((unsigned) prim_data[p].subids *
+ sizeof(str_number *)));
+ for (q = 0; q < prim_data[p].subids; q++)
+ undump_int(prim_data[p].names[q]);
}
}
}
-/*
- We need to put \TeX's ``primitive'' control sequences into the hash
+@ We need to put \TeX's ``primitive'' control sequences into the hash
table, together with their command code (which will be the |eq_type|)
and an operand (which will be the |equiv|). The |primitive| procedure
does this, in a way that no \TeX\ user can. The global value |cur_val|
contains the new |eqtb| pointer after |primitive| has acted.
-*/
-/* Because the definitions of the actual user-accessible name of a
+
+@ Because the definitions of the actual user-accessible name of a
primitive can be postponed until runtime, the function |primitive_def|
is needed that does nothing except creating the control sequence name.
-*/
-void primitive_def(char *s, size_t l, quarterword c, halfword o)
+@c
+void primitive_def(const char *s, size_t l, quarterword c, halfword o)
{
int nncs = no_new_control_sequence;
no_new_control_sequence = false;
@@ -281,7 +288,7 @@ void primitive_def(char *s, size_t l, quarterword c, halfword o)
equiv(cur_val) = o;
}
-/* The function |store_primitive_name| sets up the bookkeeping for the
+@ The function |store_primitive_name| sets up the bookkeeping for the
reverse lookup. It is quite paranoid, because it is easy to mess this up
accidentally.
@@ -292,9 +299,9 @@ void primitive_def(char *s, size_t l, quarterword c, halfword o)
wasted room, so |offset| is substracted from |o| because creating
or accessing the array. The |assert(idx<=0xFFFF)| is not strictly
needed, but it helps catch errors of this kind.
-*/
-static void
+@c
+void
store_primitive_name(str_number s, quarterword c, halfword o, halfword offset)
{
int idx;
@@ -307,11 +314,11 @@ store_primitive_name(str_number s, quarterword c, halfword o, halfword offset)
assert(idx <= 0xFFFF);
if (prim_data[c].subids < (idx + 1)) {
str_number *new =
- (str_number *) xcalloc((idx + 1), sizeof(str_number *));
+ (str_number *) xcalloc((unsigned) (idx + 1), sizeof(str_number *));
if (prim_data[c].names != NULL) {
assert(prim_data[c].subids);
memcpy(new, (prim_data[c].names),
- (prim_data[c].subids * sizeof(str_number)));
+ (unsigned) (prim_data[c].subids) * sizeof(str_number));
free(prim_data[c].names);
}
prim_data[c].names = new;
@@ -320,151 +327,149 @@ store_primitive_name(str_number s, quarterword c, halfword o, halfword offset)
prim_data[c].names[idx] = s;
}
-/* Compared to tex82, |primitive| has two extra parameters. The |off| is an offset
+@ Compared to tex82, |primitive| has two extra parameters. The |off| is an offset
that will be passed on to |store_primitive_name|, the |cmd_origin| is the bit
that is used to group primitives by originator.
-*/
+@c
void
-primitive(str_number ss, quarterword c, halfword o, halfword off,
+primitive(const char *thes, quarterword c, halfword o, halfword off,
int cmd_origin)
{
- str_number s; /* actual |str_number| used */
- integer prim_val; /* needed to fill |prim_eqtb| */
- char *thes;
+ int prim_val; /* needed to fill |prim_eqtb| */
+ str_number ss;
assert(o >= off);
- if (ss < string_offset) {
- if (ss > 127)
- tconfusion("prim"); /* should be ASCII */
- append_char(ss);
- s = make_string();
- } else {
- s = ss;
- }
- thes = makecstring(s);
+ ss = maketexstring(thes);
if (cmd_origin == tex_command || cmd_origin == core_command) {
primitive_def(thes, strlen(thes), c, o);
}
- prim_val = prim_lookup(s);
- prim_origin(prim_val) = cmd_origin;
+ prim_val = prim_lookup(ss);
+ prim_origin(prim_val) = (quarterword) cmd_origin;
prim_eq_type(prim_val) = c;
prim_equiv(prim_val) = o;
- store_primitive_name(s, c, o, off);
+ store_primitive_name(ss, c, o, off);
}
-/*
- * Here is a helper that does the actual hash insertion.
- */
-static halfword insert_id(halfword p, const unsigned char *j, pool_pointer l)
+@ Here is a helper that does the actual hash insertion.
+
+@c
+static halfword insert_id(halfword p, const unsigned char *j, unsigned int l)
{
- integer d;
+ unsigned saved_cur_length;
+ unsigned saved_cur_string_size;
+ unsigned char *saved_cur_string;
const unsigned char *k;
/* This code far from ideal: the existance of |hash_extra| changes
all the potential (short) coalesced lists into a single (long)
one. This will create a slowdown. */
- if (text(p) > 0) {
+ if (cs_text(p) > 0) {
if (hash_high < hash_extra) {
incr(hash_high);
- /* can't use eqtb_top here (perhaps because that is not finalized
+ /* can't use |eqtb_top| here (perhaps because that is not finalized
yet when called from |primitive|?) */
- next(p) = hash_high + get_eqtb_size();
- p = next(p);
+ cs_next(p) = hash_high + eqtb_size;
+ p = cs_next(p);
} else {
do {
if (hash_is_full)
- overflow_string("hash size", hash_size + hash_extra);
+ overflow("hash size", (unsigned) (hash_size + hash_extra));
decr(hash_used);
- } while (text(hash_used) != 0); /* search for an empty location in |hash| */
- next(p) = hash_used;
+ } while (cs_text(hash_used) != 0); /* search for an empty location in |hash| */
+ cs_next(p) = hash_used;
p = hash_used;
}
}
- check_pool_overflow((pool_ptr + l));
- d = cur_length;
- while (pool_ptr > str_start_macro(str_ptr)) {
- /* move current string up to make room for another */
- decr(pool_ptr);
- str_pool[pool_ptr + l] = str_pool[pool_ptr];
- }
+ saved_cur_length = cur_length;
+ saved_cur_string = cur_string;
+ saved_cur_string_size = cur_string_size;
+ reset_cur_string();
for (k = j; k <= j + l - 1; k++)
append_char(*k);
- text(p) = make_string();
- pool_ptr = pool_ptr + d;
+ cs_text(p) = make_string();
+ cur_length = saved_cur_length;
+ cur_string = saved_cur_string;
+ cur_string_size = saved_cur_string_size;
incr(cs_count);
return p;
}
-/*
- Here is the subroutine that searches the hash table for an identifier
+@ 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.
-*/
-
-pointer id_lookup(integer j, integer l)
+@c
+pointer id_lookup(int j, int l)
{ /* search the hash table */
- integer h; /* hash code */
+ int h; /* hash code */
pointer p; /* index in |hash| array */
- h = compute_hash((char *) (buffer + j), l, hash_prime);
+ h = compute_hash((char *) (buffer + j), (unsigned) l, hash_prime);
+#ifdef VERBOSE
+ {
+ unsigned char *todo = xmalloc(l + 2);
+ strncpy(todo, (buffer + j), l);
+ todo[l] = '\0';
+ todo[l + 1] = '\0';
+ fprintf(stdout, "id_lookup(%s)\n", todo);
+ free(todo);
+ }
+#endif
p = h + hash_base; /* we start searching here; note that |0<=h<hash_prime| */
while (1) {
- if (text(p) > 0)
- if (length(text(p)) == l)
- if (str_eq_buf(text(p), j))
+ if (cs_text(p) > 0)
+ if (str_length(cs_text(p)) == (unsigned) l)
+ if (str_eq_buf(cs_text(p), j))
goto FOUND;
- if (next(p) == 0) {
+ if (cs_next(p) == 0) {
if (no_new_control_sequence) {
- p = static_undefined_control_sequence;
+ p = undefined_control_sequence;
} else {
- p = insert_id(p, (buffer + j), l);
+ p = insert_id(p, (buffer + j), (unsigned) l);
}
goto FOUND;
}
- p = next(p);
+ p = cs_next(p);
}
FOUND:
return p;
}
-/*
- * Here is a similar subroutine for finding a primitive in the hash.
- * This one is based on a C string.
- */
-
+@ Here is a similar subroutine for finding a primitive in the hash.
+This one is based on a C string.
+@c
pointer string_lookup(const char *s, size_t l)
{ /* search the hash table */
- integer h; /* hash code */
+ int h; /* hash code */
pointer p; /* index in |hash| array */
- h = compute_hash(s, l, hash_prime);
+ h = compute_hash(s, (unsigned) l, hash_prime);
p = h + hash_base; /* we start searching here; note that |0<=h<hash_prime| */
while (1) {
- if (text(p) > 0)
- if (str_eq_cstr(text(p), s, l))
+ if (cs_text(p) > 0)
+ if (str_eq_cstr(cs_text(p), s, l))
goto FOUND;
- if (next(p) == 0) {
+ if (cs_next(p) == 0) {
if (no_new_control_sequence) {
- p = static_undefined_control_sequence;
+ p = undefined_control_sequence;
} else {
- p = insert_id(p, (const unsigned char *) s, l);
+ p = insert_id(p, (const unsigned char *) s, (unsigned) l);
}
goto FOUND;
}
- p = next(p);
+ p = cs_next(p);
}
FOUND:
return p;
}
-/* The |print_cmd_chr| routine prints a symbolic interpretation of a
+@ 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}.
@@ -476,11 +481,11 @@ pointer string_lookup(const char *s, size_t l)
Thanks to |prim_data|, there is no need for all that tediousness. What
is left of |primt_cnd_chr| are just the exceptions to the general rule
that the |cmd,chr_code| pair represents in a single primitive command.
-*/
+@c
#define chr_cmd(A) do { tprint(A); print(chr_code); } while (0)
-static void prim_cmd_chr(quarterword cmd, halfword chr_code)
+void prim_cmd_chr(quarterword cmd, halfword chr_code)
{
int idx = chr_code - prim_data[cmd].offset;
if (cmd <= last_cmd &&
@@ -500,7 +505,7 @@ static void prim_cmd_chr(quarterword cmd, halfword chr_code)
void print_cmd_chr(quarterword cmd, halfword chr_code)
{
- integer n; /* temp variable */
+ int n; /* temp variable */
switch (cmd) {
case left_brace_cmd:
chr_cmd("begin-group character ");
@@ -512,7 +517,10 @@ void print_cmd_chr(quarterword cmd, halfword chr_code)
chr_cmd("math shift character ");
break;
case mac_param_cmd:
- chr_cmd("macro parameter character ");
+ if (chr_code == tab_mark_cmd_code)
+ tprint_esc("alignmark");
+ else
+ chr_cmd("macro parameter character ");
break;
case sup_mark_cmd:
chr_cmd("superscript character ");
@@ -535,6 +543,8 @@ void print_cmd_chr(quarterword cmd, halfword chr_code)
case tab_mark_cmd:
if (chr_code == span_code)
tprint_esc("span");
+ else if (chr_code == tab_mark_cmd_code)
+ tprint_esc("aligntab");
else
chr_cmd("alignment tab character ");
break;
@@ -576,7 +586,7 @@ void print_cmd_chr(quarterword cmd, halfword chr_code)
case outer_call_cmd:
case long_outer_call_cmd:
n = cmd - call_cmd;
- if (info(link(chr_code)) == protected_token)
+ if (token_info(token_link(chr_code)) == protected_token)
n = n + 4;
if (odd(n / 4))
tprint_esc("protected");
@@ -609,7 +619,7 @@ void print_cmd_chr(quarterword cmd, halfword chr_code)
case assign_glue_cmd:
case assign_mu_glue_cmd:
if (chr_code < skip_base) {
- print_skip_param(chr_code - glue_base);
+ prim_cmd_chr(cmd, chr_code);
} else if (chr_code < mu_skip_base) {
tprint_esc("skip");
print_int(chr_code - skip_base);
@@ -628,7 +638,7 @@ void print_cmd_chr(quarterword cmd, halfword chr_code)
break;
case assign_int_cmd:
if (chr_code < count_base) {
- print_param(chr_code - int_base);
+ prim_cmd_chr(cmd, chr_code);
} else {
tprint_esc("count");
print_int(chr_code - count_base);
@@ -640,7 +650,7 @@ void print_cmd_chr(quarterword cmd, halfword chr_code)
break;
case assign_dimen_cmd:
if (chr_code < scaled_base) {
- print_length_param(chr_code - dimen_base);
+ prim_cmd_chr(cmd, chr_code);
} else {
tprint_esc("dimen");
print_int(chr_code - scaled_base);
diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.h b/Build/source/texk/web2c/luatexdir/tex/printing.h
new file mode 100644
index 00000000000..b104fd142cc
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/printing.h
@@ -0,0 +1,124 @@
+/* printing.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: printing.h 3436 2010-02-21 15:34:00Z taco $ */
+
+#ifndef PRINTING_H
+# define PRINTING_H
+
+typedef enum {
+ no_print = 16, /* |selector| setting that makes data disappear */
+ term_only = 17, /* printing is destined for the terminal only */
+ log_only = 18, /* printing is destined for the transcript file only */
+ term_and_log = 19, /* normal |selector| setting */
+ pseudo = 20, /* special |selector| setting for |show_context| */
+ new_string = 21, /* printing is deflected to the string pool */
+} selector_settings;
+
+# define ssup_error_line 255
+# define max_selector new_string
+ /* highest selector setting */
+
+extern alpha_file log_file;
+extern int selector;
+extern int dig[23];
+extern int tally;
+extern int term_offset;
+extern int file_offset;
+extern packed_ASCII_code trick_buf[(ssup_error_line + 1)];
+extern int trick_count;
+extern int first_count;
+extern boolean inhibit_par_tokens;
+
+/*
+Macro abbreviations for output to the terminal and to the log file are
+defined here for convenience. Some systems need special conventions
+for terminal output, and it is possible to adhere to those conventions
+by changing |wterm|, |wterm_ln|, and |wterm_cr| in this section.
+@^system dependencies@>
+*/
+
+# define wterm_cr() fprintf(term_out,"\n")
+# define wlog_cr() fprintf(log_file,"\n")
+
+extern void print_ln(void);
+extern void print_char(int s);
+extern void print(int s);
+extern void print_nl(str_number s);
+extern void print_nlp(void);
+extern void slow_print(int s);
+extern void print_banner(const char *, int, int);
+extern void log_banner(const char *, int, int);
+extern void print_version_banner(void);
+extern void print_esc(str_number s);
+extern void print_the_digs(eight_bits k);
+extern void print_int(longinteger n);
+extern void print_two(int n);
+extern void print_hex(int n);
+extern void print_roman_int(int n);
+extern void print_current_string(void);
+
+# define print_font_name(A) tprint(font_name(A))
+
+extern void print_cs(int p);
+extern void sprint_cs(pointer p);
+extern void tprint(const char *s);
+extern void tprint_nl(const char *s);
+extern void tprint_esc(const char *s);
+
+extern void prompt_input(const char *s);
+
+
+# define single_letter(A) \
+ ((str_length(A)==1)|| \
+ ((str_length(A)==4)&&*(str_string((A)))>=0xF0)|| \
+ ((str_length(A)==3)&&*(str_string((A)))>=0xE0)|| \
+ ((str_length(A)==2)&&*(str_string((A)))>=0xC0))
+
+# define is_active_cs(a) (str_length(a)>3 && \
+ (*str_string(a) == 0xEF) && \
+ (*(str_string(a)+1) == 0xBF) && \
+ (*(str_string(a)+2) == 0xBF))
+
+
+# define active_cs_value(A) pool_to_unichar((str_string((A))+3))
+
+extern void print_glue(scaled d, int order, const char *s); /* prints a glue component */
+extern void print_spec(int p, const char *s); /* prints a glue specification */
+
+extern int font_in_short_display; /* an internal font number */
+extern void print_font_identifier(internal_font_number f);
+extern void short_display(int p); /* prints highlights of list |p| */
+extern void print_font_and_char(int p); /* prints |char_node| data */
+extern void print_mark(int p); /* prints token list data in braces */
+extern void print_rule_dimen(scaled d); /* prints dimension in rule node */
+extern int depth_threshold; /* maximum nesting depth in box displays */
+extern int breadth_max; /* maximum number of items shown at the same list level */
+extern void show_box(halfword p);
+extern void short_display_n(int p, int m); /* prints highlights of list |p| */
+
+extern void print_csnames(int hstart, int hfinish);
+extern void print_file_line(void);
+
+extern void begin_diagnostic(void);
+extern void end_diagnostic(boolean blank_line);
+extern int global_old_setting;
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.w b/Build/source/texk/web2c/luatexdir/tex/printing.w
new file mode 100644
index 00000000000..cb4199841e8
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/printing.w
@@ -0,0 +1,984 @@
+% printing.w
+
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "lua/luatex-api.h" /* for ptexbanner */
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: printing.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/printing.w $";
+
+@ @c
+#define font_id_text(A) cs_text(font_id_base+(A))
+
+#define wlog(A) fputc(A,log_file)
+#define wterm(A) fputc(A,term_out)
+
+
+@ Messages that are sent to a user's terminal and to the transcript-log file
+are produced by several `|print|' procedures. These procedures will
+direct their output to a variety of places, based on the setting of
+the global variable |selector|, which has the following possible
+values:
+
+\yskip
+\hang |term_and_log|, the normal setting, prints on the terminal and on the
+ transcript file.
+
+\hang |log_only|, prints only on the transcript file.
+
+\hang |term_only|, prints only on the terminal.
+
+\hang |no_print|, doesn't print at all. This is used only in rare cases
+ before the transcript file is open.
+
+\hang |pseudo|, puts output into a cyclic buffer that is used
+ by the |show_context| routine; when we get to that routine we shall discuss
+ the reasoning behind this curious mode.
+
+\hang |new_string|, appends the output to the current string in the
+ string pool.
+
+\hang 0 to 15, prints on one of the sixteen files for \.{\\write} output.
+
+\yskip
+\noindent The symbolic names `|term_and_log|', etc., have been assigned
+numeric codes that satisfy the convenient relations |no_print+1=term_only|,
+|no_print+2=log_only|, |term_only+2=log_only+1=term_and_log|.
+
+Three additional global variables, |tally| and |term_offset| and
+|file_offset|, record the number of characters that have been printed
+since they were most recently cleared to zero. We use |tally| to record
+the length of (possibly very long) stretches of printing; |term_offset|
+and |file_offset|, on the other hand, keep track of how many characters
+have appeared so far on the current line that has been output to the
+terminal or to the transcript file, respectively.
+
+@c
+alpha_file log_file; /* transcript of \TeX\ session */
+int selector = term_only; /* where to print a message */
+int dig[23]; /* digits in a number being output */
+int tally = 0; /* the number of characters recently printed */
+int term_offset = 0; /* the number of characters on the current terminal line */
+int file_offset = 0; /* the number of characters on the current file line */
+packed_ASCII_code trick_buf[(ssup_error_line + 1)]; /* circular buffer for pseudoprinting */
+int trick_count; /* threshold for pseudoprinting, explained later */
+int first_count; /* another variable for pseudoprinting */
+boolean inhibit_par_tokens = false; /* for minor adjustments to |show_token_list| */
+
+@ To end a line of text output, we call |print_ln|
+@c
+void print_ln(void)
+{ /* prints an end-of-line */
+ switch (selector) {
+ case term_and_log:
+ wterm_cr();
+ wlog_cr();
+ term_offset = 0;
+ file_offset = 0;
+ break;
+ case log_only:
+ wlog_cr();
+ file_offset = 0;
+ break;
+ case term_only:
+ wterm_cr();
+ term_offset = 0;
+ break;
+ case no_print:
+ case pseudo:
+ case new_string:
+ break;
+ default:
+ fprintf(write_file[selector], "\n");
+ break;
+ }
+} /* |tally| is not affected */
+
+
+@ The |print_char| procedure sends one byte to the desired destination.
+ All printing comes through |print_ln| or |print_char|.
+
+@c
+#define wterm_char(A) do { \
+ if ((A>=0x20)||(A==0x0A)||(A==0x0D)||(A==0x09)) { \
+ wterm(A); \
+ } else { \
+ if (term_offset+2>=max_print_line) { \
+ wterm_cr(); term_offset=0; \
+ } \
+ incr(term_offset); wterm('^'); \
+ incr(term_offset); wterm('^'); \
+ wterm(A+64); \
+ } \
+ } while (0)
+
+#define needs_wrapping(A,B) \
+ (((A>=0xC0)&&(A<=0xDF)&&(B+2>=max_print_line))|| \
+ ((A>=0xE0)&&(A<=0xEF)&&(B+3>=max_print_line))|| \
+ ((A>=0xF0)&&(B+4>=max_print_line)))
+
+#define fix_term_offset(A) do { \
+ if (needs_wrapping(A,term_offset)){ \
+ wterm_cr(); term_offset=0; \
+ } \
+ } while (0)
+
+#define fix_log_offset(A) do { \
+ if (needs_wrapping(A,file_offset)){ \
+ wlog_cr(); file_offset=0; \
+ } \
+ } while (0)
+
+void print_char(int s)
+{ /* prints a single byte */
+ assert(s >= 0 && s < 256);
+ if (s == int_par(new_line_char_code)) {
+ if (selector < pseudo) {
+ print_ln();
+ return;
+ }
+ }
+ switch (selector) {
+ case term_and_log:
+ fix_term_offset(s);
+ fix_log_offset(s);
+ wterm_char(s);
+ wlog(s);
+ incr(term_offset);
+ incr(file_offset);
+ if (term_offset == max_print_line) {
+ wterm_cr();
+ term_offset = 0;
+ }
+ if (file_offset == max_print_line) {
+ wlog_cr();
+ file_offset = 0;
+ }
+ break;
+ case log_only:
+ fix_log_offset(s);
+ wlog(s);
+ incr(file_offset);
+ if (file_offset == max_print_line) {
+ wlog_cr();
+ file_offset = 0;
+ }
+ break;
+ case term_only:
+ fix_term_offset(s);
+ wterm_char(s);
+ incr(term_offset);
+ if (term_offset == max_print_line) {
+ wterm_cr();
+ term_offset = 0;
+ }
+ break;
+ case no_print:
+ break;
+ case pseudo:
+ if (tally < trick_count)
+ trick_buf[tally % error_line] = (packed_ASCII_code) s;
+ break;
+ case new_string:
+ append_char(s);
+ break; /* we drop characters if the string space is full */
+ default:
+ fprintf(write_file[selector], "%c", s);
+ }
+ incr(tally);
+}
+
+
+@ An entire string is output by calling |print|. Note that if we are outputting
+the single standard ASCII character \.c, we could call |print("c")|, since
+|"c"=99| is the number of a single-character string, as explained above. But
+|print_char("c")| is quicker, so \TeX\ goes directly to the |print_char|
+routine when it knows that this is safe. (The present implementation
+assumes that it is always safe to print a visible ASCII character.)
+@^system dependencies@>
+
+The first 256 entries above the 17th unicode plane are used for a
+special trick: when \TeX\ has to print items in that range, it will
+instead print the character that results from substracting 0x110000
+from that value. This allows byte-oriented output to things like
+\.{\\specials} and \.{\\pdfliterals}. Todo: Perhaps it would be useful
+to do the same substraction while typesetting.
+
+@c
+void print(int s)
+{ /* prints string |s| */
+ unsigned char *j, *l; /* current character code position */
+
+ if (s >= str_ptr) {
+ /* this can't happen */
+ print_char('?');
+ print_char('?');
+ print_char('?');
+ return;
+ } else if (s < STRING_OFFSET) {
+ if (s < 0) {
+ /* can't happen */
+ print_char('?');
+ print_char('?');
+ print_char('?');
+ } else {
+ /* TH not sure about this, disabled for now! */
+ if ((false) && (selector > pseudo)) {
+ print_char(s);
+ return; /* internal strings are not expanded */
+ }
+ if (s == int_par(new_line_char_code)) {
+ if (selector < pseudo) {
+ print_ln();
+ return;
+ }
+ }
+ 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 >= 0x110000) {
+ int c = s - 0x110000;
+ if (c >= 256) {
+ pdf_warning("print", "bad raw byte to print (c=",
+ true, false);
+ print_int(c);
+ tprint("), skipped.");
+ print_ln();
+ } else {
+ print_char(c);
+ }
+ } 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));
+ }
+ }
+ return;
+ }
+ if (selector == new_string) {
+ append_string(str_string(s), (unsigned) str_length(s));
+ return;
+ }
+ j = str_string(s);
+ l = j + str_length(s);
+ while (j < l) {
+ /* 0x110000 in utf=8: 0xF4 0x90 0x80 0x80 */
+ /* I don't bother checking the last two bytes explicitly */
+ if ((j < l - 4) && (*j == 0xF4) && (*(j + 1) == 0x90)) {
+ int c = (*(j + 2) - 128) * 64 + (*(j + 3) - 128);
+ assert(c >= 0 && c < 256);
+ print_char(c);
+ j = j + 4;
+ } else {
+ print_char(*j);
+ incr(j);
+ }
+ }
+}
+
+
+@ The procedure |print_nl| is like |print|, but it makes sure that the
+string appears at the beginning of a new line.
+
+@c
+void print_nlp(void)
+{ /* move to beginning of a line */
+ if (((term_offset > 0) && (odd(selector))) ||
+ ((file_offset > 0) && (selector >= log_only)))
+ print_ln();
+}
+
+void print_nl(str_number s)
+{ /* prints string |s| at beginning of line */
+ print_nlp();
+ print(s);
+}
+
+@ |char *| versions of the same procedures
+
+@c
+void tprint(const char *s)
+{
+ const unsigned char *ss = (const unsigned char *) s;
+ if (selector == new_string) {
+ append_string(ss, (unsigned) strlen(s));
+ return;
+ }
+ while (*ss)
+ print_char(*ss++);
+}
+
+void tprint_nl(const char *s)
+{
+ print_nlp();
+ tprint(s);
+}
+
+@ |slow_print| is the same as |print| nowadays, but the name is kept for now.
+
+@c
+void slow_print(int s)
+{ /* prints string |s| */
+ print(s);
+}
+
+@ Here is the very first thing that \TeX\ prints: a headline that identifies
+the version number and format package. The |term_offset| variable is temporarily
+incorrect, but the discrepancy is not serious since we assume that the banner
+and format identifier together will occupy at most |max_print_line|
+character positions.
+
+@c
+void print_banner(const char *v, int e, int ver)
+{
+ boolean res;
+ int callback_id;
+ callback_id = callback_defined(start_run_callback);
+ if (callback_id == 0) {
+ if (ver < 0)
+ fprintf(term_out, "This is LuaTeX, Version %s-%d ", v, e);
+ else
+ fprintf(term_out, "This is LuaTeX, Version %s-%d (rev %d) ", v, e,
+ ver);
+ if (format_ident > 0)
+ slow_print(format_ident);
+ print_ln();
+ if (shellenabledp) {
+ wterm(' ');
+ if (restrictedshell)
+ fprintf(term_out, "restricted ");
+ fprintf(term_out, "\\write18 enabled.\n");
+ }
+ } else if (callback_id > 0) {
+ res = run_callback(callback_id, "->");
+ }
+}
+
+@ @c
+void log_banner(const char *v, int e, int ver)
+{
+ const char *months[] = { " ",
+ "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
+ "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
+ };
+ unsigned month = (unsigned) int_par(month_code);
+ if (month > 12)
+ month = 0;
+ if (ver < 0)
+ fprintf(log_file, "This is LuaTeX, Version %s-%d ", v, e);
+ else
+ fprintf(log_file, "This is LuaTeX, Version %s-%d (rev %d) ", v, e, ver);
+ slow_print(format_ident);
+ print_char(' ');
+ print_char(' ');
+ print_int(int_par(day_code));
+ print_char(' ');
+ fprintf(log_file, months[month]);
+ print_char(' ');
+ print_int(int_par(year_code));
+ print_char(' ');
+ print_two(int_par(time_code) / 60);
+ print_char(':');
+ print_two(int_par(time_code) % 60);
+ if (shellenabledp) {
+ wlog_cr();
+ wlog(' ');
+ if (restrictedshell)
+ fprintf(log_file, "restricted ");
+ fprintf(log_file, "\\write18 enabled.");
+ }
+ if (filelineerrorstylep) {
+ wlog_cr();
+ fprintf(log_file, " file:line:error style messages enabled.");
+ }
+ if (parsefirstlinep) {
+ wlog_cr();
+ fprintf(log_file, " %%&-line parsing enabled.");
+ }
+}
+
+@ @c
+void print_version_banner(void)
+{
+ fprintf(term_out, ptexbanner);
+}
+
+@ The procedure |print_esc| prints a string that is preceded by
+the user's escape character (which is usually a backslash).
+
+@c
+void print_esc(str_number s)
+{ /* prints escape character, then |s| */
+ int c; /* the escape character code */
+ /* Set variable |c| to the current escape character */
+ c = int_par(escape_char_code);
+ if (c >= 0 && c < STRING_OFFSET)
+ print(c);
+ print(s);
+}
+
+@ @c
+void tprint_esc(const char *s)
+{ /* prints escape character, then |s| */
+ int c; /* the escape character code */
+ /* Set variable |c| to the current escape character */
+ c = int_par(escape_char_code);
+ if (c >= 0 && c < STRING_OFFSET)
+ print(c);
+ tprint(s);
+}
+
+@ An array of digits in the range |0..15| is printed by |print_the_digs|.
+
+@c
+void print_the_digs(eight_bits k)
+{
+ /* prints |dig[k-1]|$\,\ldots\,$|dig[0]| */
+ while (k-- > 0) {
+ if (dig[k] < 10)
+ print_char('0' + dig[k]);
+ else
+ print_char('A' - 10 + dig[k]);
+ }
+}
+
+@ The following procedure, which prints out the decimal representation of a
+given integer |n|, has been written carefully so that it works properly
+if |n=0| or if |(-n)| would cause overflow. It does not apply |mod| or |div|
+to negative arguments, since such operations are not implemented consistently
+by all PASCAL compilers.
+
+@c
+void print_int(longinteger n)
+{ /* prints an integer in decimal form */
+ int k; /* index to current digit; we assume that $|n|<10^{23}$ */
+ longinteger m; /* used to negate |n| in possibly dangerous cases */
+ k = 0;
+ if (n < 0) {
+ print_char('-');
+ if (n > -100000000) {
+ n = -n;
+ } else {
+ m = -1 - n;
+ n = m / 10;
+ m = (m % 10) + 1;
+ k = 1;
+ if (m < 10)
+ dig[0] = (int) m;
+ else {
+ dig[0] = 0;
+ incr(n);
+ }
+ }
+ }
+ do {
+ dig[k] = (int) (n % 10);
+ n = n / 10;
+ incr(k);
+ } while (n != 0);
+ print_the_digs((eight_bits) k);
+}
+
+
+@ Here is a trivial procedure to print two digits; it is usually called with
+a parameter in the range |0<=n<=99|.
+
+@c
+void print_two(int n)
+{ /* prints two least significant digits */
+ n = abs(n) % 100;
+ print_char('0' + (n / 10));
+ print_char('0' + (n % 10));
+}
+
+
+@ Hexadecimal printing of nonnegative integers is accomplished by |print_hex|.
+
+@c
+void print_hex(int n)
+{ /* prints a positive integer in hexadecimal form */
+ int k; /* index to current digit; we assume that $0\L n<16^{22}$ */
+ k = 0;
+ print_char('"');
+ do {
+ dig[k] = n % 16;
+ n = n / 16;
+ incr(k);
+ } while (n != 0);
+ print_the_digs((eight_bits) k);
+}
+
+
+@ Roman numerals are produced by the |print_roman_int| routine. Readers
+who like puzzles might enjoy trying to figure out how this tricky code
+works; therefore no explanation will be given. Notice that 1990 yields
+\.{mcmxc}, not \.{mxm}.
+
+@c
+void print_roman_int(int n)
+{
+ char *j, *k; /* mysterious indices */
+ nonnegative_integer u, v; /* mysterious numbers */
+ char mystery[] = "m2d5c2l5x2v5i";
+ j = (char *) mystery;
+ v = 1000;
+ while (1) {
+ while (n >= (int) v) {
+ print_char(*j);
+ n = n - (int) v;
+ }
+ if (n <= 0)
+ return; /* nonpositive input produces no output */
+ k = j + 2;
+ u = v / (*(k - 1) - '0');
+ if (*(k - 1) == '2') {
+ k = k + 2;
+ u = u / (*(k - 1) - '0');
+ }
+ if (n + (int) u >= (int) v) {
+ print_char(*k);
+ n = n + (int) u;
+ } else {
+ j = j + 2;
+ v = v / (*(j - 1) - '0');
+ }
+ }
+}
+
+
+@ The |print| subroutine will not print a string that is still being
+created. The following procedure will.
+
+@c
+void print_current_string(void)
+{ /* prints a yet-unmade string */
+ unsigned j = 0; /* points to current character code */
+ while (j < cur_length)
+ print_char(cur_string[j++]);
+}
+
+@ 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
+unless it is a single nonletter or an active character. This procedure
+might be invoked with invalid data, so it is ``extra robust.'' The
+individual characters must be printed one at a time using |print|, since
+they may be unprintable.
+
+@c
+void print_cs(int p)
+{ /* prints a purported control sequence */
+ str_number t = cs_text(p);
+ if (p < hash_base) { /* nullcs */
+ if (p == null_cs) {
+ tprint_esc("csname");
+ tprint_esc("endcsname");
+ } else {
+ tprint_esc("IMPOSSIBLE.");
+ }
+ } else if ((p >= undefined_control_sequence) &&
+ ((p <= eqtb_size) || p > eqtb_size + hash_extra)) {
+ tprint_esc("IMPOSSIBLE.");
+ } else if (t >= str_ptr) {
+ tprint_esc("NONEXISTENT.");
+ } else {
+ if (is_active_cs(t)) {
+ print(active_cs_value(t));
+ } else {
+ print_esc(t);
+ if (single_letter(t)) {
+ if (get_cat_code(int_par(cat_code_table_code),
+ pool_to_unichar(str_string(t))) == letter_cmd)
+ print_char(' ');
+ } else {
+ print_char(' ');
+ }
+ }
+ }
+}
+
+
+@ Here is a similar procedure; it avoids the error checks, and it never
+prints a space after the control sequence.
+
+@c
+void sprint_cs(pointer p)
+{ /* prints a control sequence */
+ str_number t;
+ if (p == null_cs) {
+ tprint_esc("csname");
+ tprint_esc("endcsname");
+ } else {
+ t = cs_text(p);
+ if (is_active_cs(t))
+ print(active_cs_value(t));
+ else
+ print_esc(t);
+ }
+}
+
+
+@ This procedure is never called when |interaction<scroll_mode|.
+@c
+void prompt_input(const char *s)
+{
+ wake_up_terminal();
+ tprint(s);
+ term_input();
+}
+
+
+@ Then there is a subroutine that prints glue stretch and shrink, possibly
+followed by the name of finite units:
+
+@c
+void print_glue(scaled d, int order, const char *s)
+{ /* prints a glue component */
+ print_scaled(d);
+ if ((order < normal) || (order > filll)) {
+ tprint("foul");
+ } else if (order > normal) {
+ tprint("fi");
+ while (order > sfi) {
+ print_char('l');
+ decr(order);
+ }
+ } else if (s != NULL) {
+ tprint(s);
+ }
+}
+
+@ The next subroutine prints a whole glue specification
+@c
+void print_spec(int p, const char *s)
+{ /* prints a glue specification */
+ if (p < 0) {
+ print_char('*');
+ } else {
+ print_scaled(width(p));
+ if (s != NULL)
+ tprint(s);
+ if (stretch(p) != 0) {
+ tprint(" plus ");
+ print_glue(stretch(p), stretch_order(p), s);
+ }
+ if (shrink(p) != 0) {
+ tprint(" minus ");
+ print_glue(shrink(p), shrink_order(p), s);
+ }
+ }
+}
+
+
+@ We can reinforce our knowledge of the data structures just introduced
+by considering two procedures that display a list in symbolic form.
+The first of these, called |short_display|, is used in ``overfull box''
+messages to give the top-level description of a list. The other one,
+called |show_node_list|, prints a detailed description of exactly what
+is in the data structure.
+
+The philosophy of |short_display| is to ignore the fine points about exactly
+what is inside boxes, except that ligatures and discretionary breaks are
+expanded. As a result, |short_display| is a recursive procedure, but the
+recursion is never more than one level deep.
+@^recursion@>
+
+A global variable |font_in_short_display| keeps track of the font code that
+is assumed to be present when |short_display| begins; deviations from this
+font will be printed.
+
+@c
+int font_in_short_display; /* an internal font number */
+
+
+@ Boxes, rules, inserts, whatsits, marks, and things in general that are
+sort of ``complicated'' are indicated only by printing `\.{[]}'.
+
+@c
+void print_font_identifier(internal_font_number f)
+{
+ str_number fonttext;
+ if (pdf_font_blink(f) == null_font)
+ fonttext = font_id_text(f);
+ else
+ fonttext = font_id_text(pdf_font_blink(f));
+ if (fonttext > 0) {
+ print_esc(fonttext);
+ } else {
+ tprint_esc("FONT");
+ if (pdf_font_blink(f) == null_font)
+ print_int(f);
+ else
+ print_int(pdf_font_blink(f));
+ }
+ if (int_par(pdf_tracing_fonts_code) > 0) {
+ tprint(" (");
+ print_font_name(f);
+ if (font_size(f) != font_dsize(f)) {
+ tprint("@@");
+ print_scaled(font_size(f));
+ tprint("pt");
+ }
+ print_char(')');
+ } else if (font_expand_ratio(f) != 0) {
+ tprint(" (");
+ if (font_expand_ratio(f) > 0)
+ print_char('+');
+ print_int(font_expand_ratio(f));
+ print_char(')');
+ }
+}
+
+@ @c
+void short_display(int p)
+{ /* prints highlights of list |p| */
+ while (p != null) {
+ if (is_char_node(p)) {
+ if (lig_ptr(p) != null) {
+ short_display(lig_ptr(p));
+ } else {
+ if (font(p) != font_in_short_display) {
+ if (!is_valid_font(font(p)))
+ print_char('*');
+ else
+ print_font_identifier(font(p));
+ print_char(' ');
+ font_in_short_display = font(p);
+ }
+ print(character(p));
+ }
+ } else {
+ /* Print a short indication of the contents of node |p| */
+ print_short_node_contents(p);
+ }
+ p = vlink(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
+its reference count, and one to print a rule dimension.
+
+@c
+void print_font_and_char(int p)
+{ /* prints |char_node| data */
+ if (!is_valid_font(font(p)))
+ print_char('*');
+ else
+ print_font_identifier(font(p));
+ print_char(' ');
+ print(character(p));
+}
+
+@ @c
+void print_mark(int p)
+{ /* prints token list data in braces */
+ print_char('{');
+ if ((p < (int) fix_mem_min) || (p > (int) fix_mem_end))
+ tprint_esc("CLOBBERED.");
+ else
+ show_token_list(token_link(p), null, max_print_line - 10);
+ print_char('}');
+}
+
+@ @c
+void print_rule_dimen(scaled d)
+{ /* prints dimension in rule node */
+ if (is_running(d))
+ print_char('*');
+ else
+ print_scaled(d);
+}
+
+
+@ Since boxes can be inside of boxes, |show_node_list| is inherently recursive,
+@^recursion@>
+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.
+
+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
+be given and no sublists will be traversed. Another global variable, called
+|breadth_max|, tells the maximum number of items to show at each level;
+|breadth_max| had better be positive, or you won't see anything.
+
+@c
+int depth_threshold; /* maximum nesting depth in box displays */
+int breadth_max; /* maximum number of items shown at the same list level */
+
+
+@ The recursive machinery is started by calling |show_box|.
+
+@c
+void show_box(halfword p)
+{
+ /* Assign the values |depth_threshold:=show_box_depth| and
+ |breadth_max:=show_box_breadth| */
+ depth_threshold = int_par(show_box_depth_code);
+ breadth_max = int_par(show_box_breadth_code);
+
+ if (breadth_max <= 0)
+ breadth_max = 5;
+ show_node_list(p); /* the show starts at |p| */
+ print_ln();
+}
+
+
+@ Helper for debugging purposes
+
+@c
+void short_display_n(int p, int m)
+{ /* prints highlights of list |p| */
+ int i = 0;
+ font_in_short_display = null_font;
+ if (p == null)
+ return;
+ while (p != null) {
+ if (is_char_node(p)) {
+ if (p <= max_halfword) {
+ if (font(p) != font_in_short_display) {
+ if (!is_valid_font(font(p)))
+ print_char('*');
+ else
+ print_font_identifier(font(p));
+ print_char(' ');
+ font_in_short_display = font(p);
+ }
+ print(character(p));
+ }
+ } else {
+ if ((type(p) == glue_node) ||
+ (type(p) == disc_node) ||
+ (type(p) == penalty_node) ||
+ ((type(p) == kern_node) && (subtype(p) == explicit)))
+ incr(i);
+ if (i >= m)
+ return;
+ if (type(p) == disc_node) {
+ print_char('|');
+ short_display(vlink(pre_break(p)));
+ print_char('|');
+ short_display(vlink(post_break(p)));
+ print_char('|');
+ } else {
+ /* Print a short indication of the contents of node |p| */
+ print_short_node_contents(p);
+ }
+ }
+ p = vlink(p);
+ if (p == null)
+ return;
+ }
+ update_terminal();
+}
+
+
+@ When debugging a macro package, it can be useful to see the exact
+control sequence names in the format file. For example, if ten new
+csnames appear, it's nice to know what they are, to help pinpoint where
+they came from. (This isn't a truly ``basic'' printing procedure, but
+that's a convenient module in which to put it.)
+
+@c
+void print_csnames(int hstart, int hfinish)
+{
+ int h;
+ unsigned char *c, *l;
+ fprintf(stderr, "fmtdebug:csnames from %d to %d:", (int) hstart,
+ (int) hfinish);
+ for (h = hstart; h <= hfinish; h++) {
+ if (cs_text(h) > 0) { /* if have anything at this position */
+ c = str_string(cs_text(h));
+ l = c + str_length(cs_text(h));
+ while (c < l) {
+ fputc(*c++, stderr); /* print the characters */
+ }
+ fprintf(stderr, "|");
+ }
+ }
+}
+
+
+@ A helper for printing file:line:error style messages. Look for a
+filename in |full_source_filename_stack|, and if we fail to find
+one fall back on the non-file:line:error style.
+
+@c
+void print_file_line(void)
+{
+ int level;
+ level = in_open;
+ while ((level > 0) && (full_source_filename_stack[level] == 0))
+ decr(level);
+ if (level == 0) {
+ tprint_nl("! ");
+ } else {
+ tprint_nl("");
+ tprint(full_source_filename_stack[level]);
+ print_char(':');
+ if (level == in_open)
+ print_int(line);
+ else
+ print_int(line_stack[iindex + 1 - (in_open - level)]);
+ tprint(": ");
+ }
+}
+
+
+@ \TeX\ is occasionally supposed to print diagnostic information that
+goes only into the transcript file, unless |tracing_online| is positive.
+Here are two routines that adjust the destination of print commands:
+
+@c
+void begin_diagnostic(void)
+{ /* prepare to do some tracing */
+ global_old_setting = selector;
+ if ((int_par(tracing_online_code) <= 0) && (selector == term_and_log)) {
+ decr(selector);
+ if (history == spotless)
+ history = warning_issued;
+ }
+}
+
+@ @c
+void end_diagnostic(boolean blank_line)
+{ /* restore proper conditions after tracing */
+ tprint_nl("");
+ if (blank_line)
+ print_ln();
+ selector = global_old_setting;
+}
+
+
+@ Of course we had better declare another global variable, if the previous
+routines are going to work.
+
+@c
+int global_old_setting;
diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.h b/Build/source/texk/web2c/luatexdir/tex/scanning.h
new file mode 100644
index 00000000000..853a22a9a46
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/scanning.h
@@ -0,0 +1,111 @@
+/* scanning.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: scanning.h 3376 2010-01-25 16:50:23Z taco $ */
+
+#ifndef SCANNING_H
+# define SCANNING_H
+
+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;
+
+extern void scan_left_brace(void);
+extern void scan_optional_equals(void);
+
+extern int cur_val; /* value returned by numeric scanners */
+extern int cur_val1; /* delcodes are sometimes 51 digits */
+extern int cur_val_level; /* the ``level'' of this value */
+
+extern void scan_something_simple(halfword cmd, halfword subitem);
+extern void scan_something_internal(int level, boolean negative);
+
+
+extern void scan_limited_int(int max, const char *name);
+
+# define scan_register_num() scan_limited_int(65535,"register code")
+# define scan_mark_num() scan_limited_int(65535,"marks code")
+# define scan_char_num() scan_limited_int(biggest_char,"character code")
+# define scan_four_bit_int() scan_limited_int(15,NULL)
+# define scan_math_family_int() scan_limited_int(265,"math family")
+# define scan_real_fifteen_bit_int() scan_limited_int(32767,"mathchar")
+# define scan_big_fifteen_bit_int() scan_limited_int(0x7FFFFFF,"extended mathchar")
+# define scan_twenty_seven_bit_int() scan_limited_int(0777777777,"delimiter code")
+
+extern void scan_fifteen_bit_int(void);
+extern void scan_fifty_one_bit_int(void);
+extern void scan_string_argument(void);
+extern void scan_four_bit_int_or_18(void);
+
+# define octal_token (other_token+'\'') /* apostrophe, indicates an octal constant */
+# define hex_token (other_token+'"') /* double quote, indicates a hex constant */
+# define alpha_token (other_token+'`') /* reverse apostrophe, precedes alpha constants */
+# define point_token (other_token+'.') /* decimal point */
+# define continental_point_token (other_token+',') /* decimal point, Eurostyle */
+# define infinity 017777777777 /* the largest positive value that \TeX\ knows */
+# define zero_token (other_token+'0') /* zero, the smallest digit */
+# define A_token (letter_token+'A') /* the smallest special hex digit */
+# define other_A_token (other_token+'A')
+ /* special hex digit of type |other_char| */
+
+extern int radix;
+
+extern void scan_int(void);
+
+extern int cur_order;
+
+# define scan_normal_dimen() scan_dimen(false,false,false)
+
+extern void scan_dimen(boolean mu, boolean inf, boolean shortcut);
+extern void scan_glue(int level);
+extern void scan_scaled(void);
+
+extern halfword the_toks(void);
+extern str_number the_scanned_result(void);
+extern void set_font_dimen(void);
+extern void get_font_dimen(void);
+
+# define default_rule 26214 /* 0.4\thinspace pt */
+
+extern halfword scan_rule_spec(void);
+
+extern void scan_font_ident(void);
+extern void scan_general_text(void);
+extern void get_x_or_protected(void);
+extern halfword scan_toks(boolean macrodef, boolean xpand);
+
+
+extern void scan_normal_glue(void);
+extern void scan_mu_glue(void);
+
+extern int add_or_sub(int x, int y, int max_answer, boolean negative);
+extern int quotient(int n, int d);
+extern int fract(int x, int n, int d, int max_answer);
+extern void scan_expr(void);
+
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.w b/Build/source/texk/web2c/luatexdir/tex/scanning.w
new file mode 100644
index 00000000000..43466f400d8
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/scanning.w
@@ -0,0 +1,2641 @@
+% scanning.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: scanning.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/scanning.w $";
+
+
+@ @c
+#define prev_depth cur_list.prev_depth_field
+#define space_factor cur_list.space_factor_field
+#define par_shape_ptr equiv(par_shape_loc)
+#define font_id_text(A) cs_text(font_id_base+(A))
+
+#define attribute(A) eqtb[attribute_base+(A)].hh.rh
+#define dimen(A) eqtb[scaled_base+(A)].hh.rh
+#undef skip
+#define skip(A) eqtb[skip_base+(A)].hh.rh
+#define mu_skip(A) eqtb[mu_skip_base+(A)].hh.rh
+#define count(A) eqtb[count_base+(A)].hh.rh
+#define box(A) equiv(box_base+(A))
+
+#define text_direction int_par(text_direction_code)
+#define body_direction int_par(body_direction_code)
+
+
+@ Let's turn now to some procedures that \TeX\ calls upon frequently to digest
+certain kinds of patterns in the input. Most of these are quite simple;
+some are quite elaborate. Almost all of the routines call |get_x_token|,
+which can cause them to be invoked recursively.
+
+The |scan_left_brace| routine is called when a left brace is supposed to be
+the next non-blank token. (The term ``left brace'' means, more precisely,
+a character whose catcode is |left_brace|.) \TeX\ allows \.{\\relax} to
+appear before the |left_brace|.
+
+@c
+void scan_left_brace(void)
+{ /* reads a mandatory |left_brace| */
+ /* Get the next non-blank non-relax non-call token */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ if (cur_cmd != left_brace_cmd) {
+ print_err("Missing { inserted");
+ help4("A left brace was mandatory here, so I've put one in.",
+ "You might want to delete and/or insert some corrections",
+ "so that I will find a matching right brace soon.",
+ "If you're confused by all this, try typing `I}' now.");
+ back_error();
+ cur_tok = left_brace_token + '{';
+ cur_cmd = left_brace_cmd;
+ cur_chr = '{';
+ incr(align_state);
+ }
+}
+
+
+@ The |scan_optional_equals| routine looks for an optional `\.=' sign preceded
+by optional spaces; `\.{\\relax}' is not ignored here.
+
+@c
+void scan_optional_equals(void)
+{
+ /* Get the next non-blank non-call token */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+ if (cur_tok != other_token + '=')
+ back_input();
+}
+
+
+@ Here is a procedure that sounds an alarm when mu and non-mu units
+are being switched.
+
+@c
+static void mu_error(void)
+{
+ print_err("Incompatible glue units");
+ help1("I'm going to assume that 1mu=1pt when they're mixed.");
+ error();
+}
+
+
+@ The next routine `|scan_something_internal|' is used to fetch internal
+numeric quantities like `\.{\\hsize}', and also to handle the `\.{\\the}'
+when expanding constructions like `\.{\\the\\toks0}' and
+`\.{\\the\\baselineskip}'. Soon we will be considering the |scan_int|
+procedure, which calls |scan_something_internal|; on the other hand,
+|scan_something_internal| also calls |scan_int|, for constructions like
+`\.{\\catcode\`\\\$}' or `\.{\\fontdimen} \.3 \.{\\ff}'. So we
+have to declare |scan_int| as a |forward| procedure. A few other
+procedures are also declared at this point.
+
+\TeX\ doesn't know exactly what to expect when
+|scan_something_internal| begins. For example, an integer or
+dimension or glue value could occur immediately after `\.{\\hskip}';
+and one can even say \.{\\the} with respect to token lists in
+constructions like `\.{\\xdef\\o\{\\the\\output\}}'. On the other
+hand, only integers are allowed after a construction like
+`\.{\\count}'. To handle the various possibilities,
+|scan_something_internal| has a |level| parameter, which tells the
+``highest'' kind of quantity that |scan_something_internal| is allowed
+to produce. Eight levels are distinguished, namely |int_val|,
+|attr_val|, |dimen_val|, |glue_val|, |mu_val|, |dir_val|, |ident_val|,
+and |tok_val|.
+
+The output of |scan_something_internal| (and of the other routines
+|scan_int|, |scan_dimen|, and |scan_glue| below) is put into the global
+variable |cur_val|, and its level is put into |cur_val_level|. The highest
+values of |cur_val_level| are special: |mu_val| is used only when
+|cur_val| points to something in a ``muskip'' register, or to one of the
+three parameters \.{\\thinmuskip}, \.{\\medmuskip}, \.{\\thickmuskip};
+|ident_val| is used only when |cur_val| points to a font identifier;
+|tok_val| is used only when |cur_val| points to |null| or to the reference
+count of a token list. The last two cases are allowed only when
+|scan_something_internal| is called with |level=tok_val|.
+
+If the output is glue, |cur_val| will point to a glue specification, and
+the reference count of that glue will have been updated to reflect this
+reference; if the output is a nonempty token list, |cur_val| will point to
+its reference count, but in this case the count will not have been updated.
+Otherwise |cur_val| will contain the integer or scaled value in question.
+
+@c
+int cur_val; /* value returned by numeric scanners */
+int cur_val1; /* delcodes are sometimes 51 digits */
+int cur_val_level; /* the ``level'' of this value */
+
+#define scanned_result(A,B) do { \
+ cur_val=A; \
+ cur_val_level=B; \
+ } while (0)
+
+
+@ When a |glue_val| changes to a |dimen_val|, we use the width component
+of the glue; there is no need to decrease the reference count, since it
+has not yet been increased. When a |dimen_val| changes to an |int_val|,
+we use scaled points so that the value doesn't actually change. And when a
+|mu_val| changes to a |glue_val|, the value doesn't change either.
+
+@c
+static void downgrade_cur_val(boolean delete_glue)
+{
+ halfword m;
+ if (cur_val_level == glue_val_level) {
+ m = cur_val;
+ cur_val = width(m);
+ if (delete_glue)
+ delete_glue_ref(m);
+ } else if (cur_val_level == mu_val_level) {
+ mu_error();
+ }
+ decr(cur_val_level);
+}
+
+static void negate_cur_val(boolean delete_glue)
+{
+ halfword m;
+ if (cur_val_level >= glue_val_level) {
+ m = cur_val;
+ cur_val = new_spec(m);
+ if (delete_glue)
+ delete_glue_ref(m);
+ /* Negate all three glue components of |cur_val| */
+ negate(width(cur_val));
+ negate(stretch(cur_val));
+ negate(shrink(cur_val));
+
+ } else {
+ negate(cur_val);
+ }
+}
+
+
+@ Some of the internal items can be fetched both routines,
+and these have been split off into the next routine, that
+returns true if the command code was understood
+
+@c
+static boolean short_scan_something_internal(int cmd, int chr, int level,
+ boolean negative)
+{
+ halfword m; /* |chr_code| part of the operand token */
+ halfword q; /* general purpose index */
+ int p; /* index into |nest| */
+ int save_cur_chr;
+ boolean succeeded = true;
+ m = chr;
+ switch (cmd) {
+ case assign_toks_cmd:
+ scanned_result(equiv(m), tok_val_level);
+ break;
+ case assign_int_cmd:
+ scanned_result(eqtb[m].cint, int_val_level);
+ break;
+ case assign_attr_cmd:
+ scanned_result(eqtb[m].cint, int_val_level);
+ break;
+ case assign_dir_cmd:
+ scanned_result(eqtb[m].cint, dir_val_level);
+ break;
+ case assign_dimen_cmd:
+ scanned_result(eqtb[m].cint, dimen_val_level);
+ break;
+ case assign_glue_cmd:
+ scanned_result(equiv(m), glue_val_level);
+ break;
+ case assign_mu_glue_cmd:
+ scanned_result(equiv(m), mu_val_level);
+ break;
+ case math_style_cmd:
+ scanned_result(m, int_val_level);
+ break;
+ case set_aux_cmd:
+ /* Fetch the |space_factor| or the |prev_depth| */
+ if (abs(cur_list.mode_field) != m) {
+ print_err("Improper ");
+ print_cmd_chr(set_aux_cmd, m);
+ help4("You can refer to \\spacefactor only in horizontal mode;",
+ "you can refer to \\prevdepth only in vertical mode; and",
+ "neither of these is meaningful inside \\write. So",
+ "I'm forgetting what you said and using zero instead.");
+ error();
+ if (level != tok_val_level)
+ scanned_result(0, dimen_val_level);
+ else
+ scanned_result(0, int_val_level);
+ } else if (m == vmode) {
+ scanned_result(prev_depth, dimen_val_level);
+ } else {
+ scanned_result(space_factor, int_val_level);
+ }
+ break;
+ case set_prev_graf_cmd:
+ /* Fetch the |prev_graf| */
+ if (cur_list.mode_field == 0) {
+ scanned_result(0, int_val_level); /* |prev_graf=0| within \.{\\write} */
+ } else {
+ p = nest_ptr;
+ while (abs(nest[p].mode_field) != vmode)
+ decr(p);
+ scanned_result(nest[p].pg_field, int_val_level);
+ }
+ break;
+ case set_page_int_cmd:
+ /* Fetch the |dead_cycles| or the |insert_penalties| */
+ if (m == 0)
+ cur_val = dead_cycles;
+ else if (m == 2)
+ cur_val = interaction; /* interactionmode */
+ else
+ cur_val = insert_penalties;
+ cur_val_level = int_val_level;
+ break;
+ case set_page_dimen_cmd:
+ /* Fetch something on the |page_so_far| */
+ if ((page_contents == empty) && (!output_active)) {
+ if (m == 0)
+ cur_val = max_dimen;
+ else
+ cur_val = 0;
+ } else {
+ cur_val = page_so_far[m];
+ }
+ cur_val_level = dimen_val_level;
+ break;
+ case set_tex_shape_cmd:
+ /* Fetch the |par_shape| size */
+ if (par_shape_ptr == null)
+ cur_val = 0;
+ else
+ cur_val = vinfo(par_shape_ptr + 1);
+ cur_val_level = int_val_level;
+ break;
+ case set_etex_shape_cmd:
+ /* Fetch a penalties array element */
+ scan_int();
+ if ((equiv(m) == null) || (cur_val < 0)) {
+ cur_val = 0;
+ } else {
+ if (cur_val > penalty(equiv(m)))
+ cur_val = penalty(equiv(m));
+ cur_val = penalty(equiv(m) + cur_val);
+ }
+ cur_val_level = int_val_level;
+ break;
+ case char_given_cmd:
+ case math_given_cmd:
+ case omath_given_cmd:
+ case xmath_given_cmd:
+ scanned_result(cur_chr, int_val_level);
+ break;
+ case last_item_cmd:
+ /* Because the items in this case directly refer to |cur_chr|,
+ it needs to be saved and restored */
+ save_cur_chr = cur_chr;
+ cur_chr = chr;
+ /* Fetch an item in the current node, if appropriate */
+ /* Here is where \.{\\lastpenalty}, \.{\\lastkern}, and \.{\\lastskip} are
+ implemented. The reference count for \.{\\lastskip} will be updated later.
+
+ We also handle \.{\\inputlineno} and \.{\\badness} here, because they are
+ legal in similar contexts. */
+
+ if (m >= input_line_no_code) {
+ if (m >= eTeX_glue) {
+ /* Process an expression and |return| */
+ if (m < eTeX_mu) {
+ switch (m) {
+ case mu_to_glue_code:
+ scan_mu_glue();
+ break;
+ }; /* there are no other cases */
+ cur_val_level = glue_val_level;
+ } else if (m < eTeX_expr) {
+ switch (m) {
+ case glue_to_mu_code:
+ scan_normal_glue();
+ break;
+ } /* there are no other cases */
+ cur_val_level = mu_val_level;
+ } else {
+ cur_val_level = m - eTeX_expr + int_val_level;
+ scan_expr();
+ }
+ /* 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
+ already increased the reference count of a glue specification.
+ */
+ while (cur_val_level > level) {
+ downgrade_cur_val(true);
+ }
+ if (negative) {
+ negate_cur_val(true);
+ }
+ return succeeded;
+
+ } else if (m >= eTeX_dim) {
+ switch (m) {
+ case font_char_wd_code:
+ case font_char_ht_code:
+ case font_char_dp_code:
+ case font_char_ic_code:
+ scan_font_ident();
+ q = cur_val;
+ scan_char_num();
+ if (char_exists(q, cur_val)) {
+ switch (m) {
+ case font_char_wd_code:
+ cur_val = char_width(q, cur_val);
+ break;
+ case font_char_ht_code:
+ cur_val = char_height(q, cur_val);
+ break;
+ case font_char_dp_code:
+ cur_val = char_depth(q, cur_val);
+ break;
+ case font_char_ic_code:
+ cur_val = char_italic(q, cur_val);
+ break;
+ } /* there are no other cases */
+ } else {
+ cur_val = 0;
+ }
+ break;
+ case par_shape_length_code:
+ case par_shape_indent_code:
+ case par_shape_dimen_code:
+ q = cur_chr - par_shape_length_code;
+ scan_int();
+ if ((par_shape_ptr == null) || (cur_val <= 0)) {
+ cur_val = 0;
+ } else {
+ if (q == 2) {
+ q = cur_val % 2;
+ cur_val = (cur_val + q) / 2;
+ }
+ if (cur_val > vinfo(par_shape_ptr + 1))
+ cur_val = vinfo(par_shape_ptr + 1);
+ cur_val =
+ varmem[par_shape_ptr + 2 * cur_val - q + 1].cint;
+ }
+ cur_val_level = dimen_val_level;
+ break;
+ case glue_stretch_code:
+ case glue_shrink_code:
+ scan_normal_glue();
+ q = cur_val;
+ if (m == glue_stretch_code)
+ cur_val = stretch(q);
+ else
+ cur_val = shrink(q);
+ delete_glue_ref(q);
+ break;
+ } /* there are no other cases */
+ cur_val_level = dimen_val_level;
+ } else {
+ switch (m) {
+ case input_line_no_code:
+ cur_val = line;
+ break;
+ case badness_code:
+ cur_val = last_badness;
+ break;
+ case pdftex_version_code:
+ cur_val = pdftex_version;
+ break;
+ case luatex_version_code:
+ cur_val = get_luatexversion();
+ break;
+ case pdf_last_obj_code:
+ cur_val = pdf_last_obj;
+ break;
+ case pdf_last_xform_code:
+ cur_val = pdf_last_xform;
+ break;
+ case pdf_last_ximage_code:
+ cur_val = pdf_last_ximage;
+ break;
+ case pdf_last_ximage_pages_code:
+ cur_val = pdf_last_ximage_pages;
+ break;
+ case pdf_last_annot_code:
+ cur_val = pdf_last_annot;
+ break;
+ case pdf_last_x_pos_code:
+ cur_val = pdf_last_pos.h;
+ break;
+ case pdf_last_y_pos_code:
+ cur_val = pdf_last_pos.v;
+ break;
+ case pdf_retval_code:
+ cur_val = pdf_retval;
+ break;
+ case pdf_last_ximage_colordepth_code:
+ cur_val = pdf_last_ximage_colordepth;
+ break;
+ case random_seed_code:
+ cur_val = random_seed;
+ break;
+ case pdf_last_link_code:
+ cur_val = pdf_last_link;
+ break;
+ case Aleph_version_code:
+ cur_val = Aleph_version;
+ break;
+ case Omega_version_code:
+ cur_val = Omega_version;
+ break;
+ case eTeX_version_code:
+ cur_val = eTeX_version;
+ break;
+ case Aleph_minor_version_code:
+ cur_val = Aleph_minor_version;
+ break;
+ case Omega_minor_version_code:
+ cur_val = Omega_minor_version;
+ break;
+ case eTeX_minor_version_code:
+ cur_val = eTeX_minor_version;
+ break;
+ case current_group_level_code:
+ cur_val = cur_level - level_one;
+ break;
+ case current_group_type_code:
+ cur_val = cur_group;
+ break;
+ case current_if_level_code:
+ q = cond_ptr;
+ cur_val = 0;
+ while (q != null) {
+ incr(cur_val);
+ q = vlink(q);
+ }
+ break;
+ case current_if_type_code:
+ if (cond_ptr == null)
+ cur_val = 0;
+ else if (cur_if < unless_code)
+ cur_val = cur_if + 1;
+ else
+ cur_val = -(cur_if - unless_code + 1);
+ break;
+ case current_if_branch_code:
+ if ((if_limit == or_code) || (if_limit == else_code))
+ cur_val = 1;
+ else if (if_limit == fi_code)
+ cur_val = -1;
+ else
+ cur_val = 0;
+ break;
+ case glue_stretch_order_code:
+ case glue_shrink_order_code:
+ scan_normal_glue();
+ q = cur_val;
+ if (m == glue_stretch_order_code)
+ cur_val = stretch_order(q);
+ else
+ cur_val = shrink_order(q);
+ delete_glue_ref(q);
+ break;
+
+ } /* there are no other cases */
+ cur_val_level = int_val_level;
+ }
+ } else {
+ if (cur_chr == glue_val_level)
+ cur_val = zero_glue;
+ else
+ cur_val = 0;
+ if (cur_chr == last_node_type_code) {
+ cur_val_level = int_val_level;
+ if ((cur_list.tail_field == cur_list.head_field)
+ || (cur_list.mode_field == 0))
+ cur_val = -1;
+ } else {
+ cur_val_level = cur_chr; /* assumes identical values */
+ }
+ if ((cur_list.tail_field != contrib_head) &&
+ !is_char_node(cur_list.tail_field) &&
+ (cur_list.mode_field != 0)) {
+ switch (cur_chr) {
+ case lastpenalty_code:
+ if (type(cur_list.tail_field) == penalty_node)
+ cur_val = penalty(cur_list.tail_field);
+ break;
+ case lastkern_code:
+ if (type(cur_list.tail_field) == kern_node)
+ cur_val = width(cur_list.tail_field);
+ break;
+ case lastskip_code:
+ if (type(cur_list.tail_field) == glue_node)
+ cur_val = glue_ptr(cur_list.tail_field);
+ if (subtype(cur_list.tail_field) == mu_glue)
+ cur_val_level = mu_val_level;
+ break;
+ case last_node_type_code:
+ cur_val = visible_last_node_type(cur_list.tail_field);
+ break;
+ } /* there are no other cases */
+ } else if ((cur_list.mode_field == vmode)
+ && (cur_list.tail_field == cur_list.head_field)) {
+ switch (cur_chr) {
+ case lastpenalty_code:
+ cur_val = last_penalty;
+ break;
+ case lastkern_code:
+ cur_val = last_kern;
+ break;
+ case lastskip_code:
+ if (last_glue != max_halfword)
+ cur_val = last_glue;
+ break;
+ case last_node_type_code:
+ cur_val = last_node_type;
+ break;
+ } /* there are no other cases */
+ }
+ }
+ cur_chr = save_cur_chr;
+ break;
+ default:
+ succeeded = false;
+ }
+ if (succeeded) {
+ while (cur_val_level > level) {
+ /* Convert |cur_val| to a lower level */
+ downgrade_cur_val(false);
+ }
+ /* Fix the reference count, if any, and negate |cur_val| if |negative| */
+ /* If |cur_val| points to a glue specification at this point, the reference
+ count for the glue does not yet include the reference by |cur_val|.
+ If |negative| is |true|, |cur_val_level| is known to be |<=mu_val|.
+ */
+ if (negative) {
+ negate_cur_val(false);
+ } else if ((cur_val_level >= glue_val_level)
+ && (cur_val_level <= mu_val_level)) {
+ add_glue_ref(cur_val);
+ }
+ }
+ return succeeded;
+}
+
+@ First, here is a short routine that is called from lua code. All
+the real work is delegated to |short_scan_something_internal| that
+is shared between this routine and |scan_something_internal|.
+
+@c
+void scan_something_simple(halfword cmd, halfword subitem)
+{
+ /* negative is never true */
+ if (!short_scan_something_internal(cmd, subitem, tok_val_level, false)) {
+ /* Complain that |texlib| can not do this; give zero result */
+ print_err("You can't use `");
+ print_cmd_chr((quarterword) cmd, subitem);
+ tprint("' as tex library index");
+ help1("I'm forgetting what you said and using zero instead.");
+ error();
+ scanned_result(0, int_val_level);
+ }
+}
+
+
+
+@ 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.
+It is assumed that |cur_cmd| and |cur_chr| represent the first token of
+the internal quantity to be scanned; an error will be signalled if
+|cur_cmd<min_internal| or |cur_cmd>max_internal|.
+
+@c
+void scan_something_internal(int level, boolean negative)
+{
+ /* fetch an internal parameter */
+ halfword m; /* |chr_code| part of the operand token */
+ int n, k; /* accumulators */
+ RESTART:
+ m = cur_chr;
+ if (!short_scan_something_internal(cur_cmd, cur_chr, level, negative)) {
+ switch (cur_cmd) {
+ case def_char_code_cmd:
+ /* Fetch a character code from some table */
+ scan_char_num();
+ if (m == math_code_base) {
+ cur_val1 = get_math_code_num(cur_val);
+ scanned_result(cur_val1, int_val_level);
+ } else if (m == lc_code_base) {
+ cur_val1 = get_lc_code(cur_val);
+ scanned_result(cur_val1, int_val_level);
+ } else if (m == uc_code_base) {
+ cur_val1 = get_uc_code(cur_val);
+ scanned_result(cur_val1, int_val_level);
+ } else if (m == sf_code_base) {
+ cur_val1 = get_sf_code(cur_val);
+ scanned_result(cur_val1, int_val_level);
+ } else if (m == cat_code_base) {
+ cur_val1 = get_cat_code(int_par(cat_code_table_code), cur_val);
+ scanned_result(cur_val1, int_val_level);
+ } else {
+ confusion("def_char");
+ }
+ break;
+ case def_del_code_cmd:
+ /* Fetch a character code from some table */
+ scan_char_num();
+ cur_val1 = get_del_code_num(cur_val);
+ scanned_result(cur_val1, int_val_level);
+ break;
+ case extdef_math_code_cmd:
+ /* Fetch an extended math code table value */
+ scan_char_num();
+ cur_val1 = get_math_code_num(cur_val);
+ scanned_result(cur_val1, int_val_level);
+ break;
+ case toks_register_cmd:
+ case set_font_cmd:
+ case def_font_cmd:
+ case letterspace_font_cmd:
+ case pdf_copy_font_cmd:
+ /* Fetch a token list or font identifier, provided that |level=tok_val| */
+ if (level != tok_val_level) {
+ print_err("Missing number, treated as zero");
+ help3("A number should have been here; I inserted `0'.",
+ "(If you can't figure out why I needed to see a number,",
+ "look up `weird error' in the index to The TeXbook.)");
+ back_error();
+ scanned_result(0, dimen_val_level);
+ } else if (cur_cmd == toks_register_cmd) {
+ scan_register_num();
+ m = toks_base + cur_val;
+ scanned_result(equiv(m), tok_val_level);
+ } else {
+ back_input();
+ scan_font_ident();
+ scanned_result(font_id_base + cur_val, ident_val_level);
+ }
+ break;
+ case def_family_cmd:
+ /* Fetch a math font identifier */
+ scan_char_num();
+ cur_val1 = fam_fnt(cur_val, m);
+ scanned_result(font_id_base + cur_val1, ident_val_level);
+ break;
+ case set_math_param_cmd:
+ /* Fetch a math param */
+ cur_val1 = cur_chr;
+ get_token();
+ if (cur_cmd != math_style_cmd) {
+ print_err("Missing math style, treated as \\displaystyle");
+ help1
+ ("A style should have been here; I inserted `\\displaystyle'.");
+ cur_val = display_style;
+ back_error();
+ } else {
+ cur_val = cur_chr;
+ }
+ if (cur_val1 < math_param_first_mu_glue) {
+ if (cur_val1 == math_param_radical_degree_raise) {
+ cur_val1 = get_math_param(cur_val1, cur_chr);
+ scanned_result(cur_val1, int_val_level);
+ } else {
+ cur_val1 = get_math_param(cur_val1, cur_chr);
+ scanned_result(cur_val1, dimen_val_level);
+ }
+ } else {
+ cur_val1 = get_math_param(cur_val1, cur_chr);
+ if (cur_val1 == thin_mu_skip_code)
+ cur_val1 = glue_par(thin_mu_skip_code);
+ else if (cur_val1 == med_mu_skip_code)
+ cur_val1 = glue_par(med_mu_skip_code);
+ else if (cur_val1 == thick_mu_skip_code)
+ cur_val1 = glue_par(thick_mu_skip_code);
+ scanned_result(cur_val1, mu_val_level);
+ }
+ break;
+ case assign_box_dir_cmd:
+ scan_register_num();
+ m = cur_val;
+ if (box(m) != null)
+ cur_val = box_dir(box(m));
+ else
+ cur_val = 0;
+ cur_val_level = dir_val_level;
+ break;
+ case set_box_dimen_cmd:
+ /* Fetch a box dimension */
+ scan_register_num();
+ if (box(cur_val) == null)
+ cur_val = 0;
+ else
+ cur_val = varmem[box(cur_val) + m].cint;
+ cur_val_level = dimen_val_level;
+ break;
+ case assign_font_dimen_cmd:
+ /* Fetch a font dimension */
+ get_font_dimen();
+ break;
+ case assign_font_int_cmd:
+ /* Fetch a font integer */
+ scan_font_ident();
+ if (m == 0) {
+ scanned_result(hyphen_char(cur_val), int_val_level);
+ } else if (m == 1) {
+ scanned_result(skew_char(cur_val), int_val_level);
+ } else if (m == no_lig_code) {
+ scanned_result(test_no_ligatures(cur_val), int_val_level);
+ } else {
+ n = cur_val;
+ scan_char_num();
+ k = cur_val;
+ switch (m) {
+ case lp_code_base:
+ scanned_result(get_lp_code(n, k), int_val_level);
+ break;
+ case rp_code_base:
+ scanned_result(get_rp_code(n, k), int_val_level);
+ break;
+ case ef_code_base:
+ scanned_result(get_ef_code(n, k), int_val_level);
+ break;
+ case tag_code:
+ scanned_result(get_tag_code(n, k), int_val_level);
+ break;
+ }
+ }
+ break;
+ case register_cmd:
+ /* Fetch a register */
+ scan_register_num();
+ switch (m) {
+ case int_val_level:
+ cur_val = count(cur_val);
+ break;
+ case attr_val_level:
+ cur_val = attribute(cur_val);
+ break;
+ case dimen_val_level:
+ cur_val = dimen(cur_val);
+ break;
+ case glue_val_level:
+ cur_val = skip(cur_val);
+ break;
+ case mu_val_level:
+ cur_val = mu_skip(cur_val);
+ break;
+ } /* there are no other cases */
+ cur_val_level = m;
+ break;
+ case ignore_spaces_cmd: /* trap unexpandable primitives */
+ if (cur_chr == 1) {
+ /* Reset |cur_tok| for unexpandable primitives, goto restart */
+ /* This block deals with unexpandable \.{\\primitive} appearing at a spot where
+ an integer or an internal values should have been found. It fetches the
+ next token then resets |cur_cmd|, |cur_cs|, and |cur_tok|, based on the
+ primitive value of that token. No expansion takes place, because the
+ next token may be all sorts of things. This could trigger further
+ expansion creating new errors.
+ */
+ get_token();
+ cur_cs = prim_lookup(cs_text(cur_cs));
+ if (cur_cs != undefined_primitive) {
+ cur_cmd = get_prim_eq_type(cur_cs);
+ cur_chr = get_prim_equiv(cur_cs);
+ cur_tok = token_val(cur_cmd, cur_chr);
+ } else {
+ cur_cmd = relax_cmd;
+ cur_chr = 0;
+ cur_tok = cs_token_flag + frozen_relax;
+ cur_cs = frozen_relax;
+ }
+ goto RESTART;
+ }
+ break;
+ default:
+ /* Complain that \.{\\the} can not do this; give zero result */
+ print_err("You can't use `");
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ tprint("' after \\the");
+ help1("I'm forgetting what you said and using zero instead.");
+ error();
+ if (level != tok_val_level)
+ scanned_result(0, dimen_val_level);
+ else
+ scanned_result(0, int_val_level);
+ break;
+ }
+ while (cur_val_level > level) {
+ /* Convert |cur_val| to a lower level */
+ downgrade_cur_val(false);
+ }
+ /* Fix the reference count, if any, and negate |cur_val| if |negative| */
+ /* If |cur_val| points to a glue specification at this point, the reference
+ count for the glue does not yet include the reference by |cur_val|.
+ If |negative| is |true|, |cur_val_level| is known to be |<=mu_val|.
+ */
+ if (negative) {
+ negate_cur_val(false);
+ } else if ((cur_val_level >= glue_val_level) &&
+ (cur_val_level <= mu_val_level)) {
+ add_glue_ref(cur_val);
+ }
+ }
+}
+
+
+@ 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.
+
+Many of the |restricted classes| routines are the essentially
+the same except for the upper limit and the error message, so it makes
+sense to combine these all into one function.
+
+@c
+void scan_limited_int(int max, const char *name)
+{
+ char hlp[80];
+ scan_int();
+ if ((cur_val < 0) || (cur_val > max)) {
+ if (name == NULL) {
+ snprintf(hlp, 80,
+ "Since I expected to read a number between 0 and %d,",
+ max);
+ print_err("Bad number");
+ } else {
+ char msg[80];
+ snprintf(hlp, 80, "A %s must be between 0 and %d.", name, max);
+ snprintf(msg, 80, "Bad %s", name);
+ print_err(msg);
+ }
+ help2(hlp, "I changed this one to zero.");
+ int_error(cur_val);
+ cur_val = 0;
+ }
+}
+
+@ @c
+void scan_fifteen_bit_int(void)
+{
+ scan_real_fifteen_bit_int();
+ cur_val = ((cur_val / 0x1000) * 0x1000000) +
+ (((cur_val % 0x1000) / 0x100) * 0x10000) + (cur_val % 0x100);
+}
+
+@ @c
+void scan_fifty_one_bit_int(void)
+{
+ int iiii;
+ scan_int();
+ if ((cur_val < 0) || (cur_val > 0777777777)) {
+ print_err("Bad delimiter code");
+ help2
+ ("A numeric delimiter (first part) must be between 0 and 2^{27}-1.",
+ "I changed this one to zero.");
+ int_error(cur_val);
+ cur_val = 0;
+ }
+ iiii = cur_val;
+ scan_int();
+ if ((cur_val < 0) || (cur_val > 0xFFFFFF)) {
+ print_err("Bad delimiter code");
+ help2
+ ("A numeric delimiter (second part) must be between 0 and 2^{24}-1.",
+ "I changed this one to zero.");
+ int_error(cur_val);
+ cur_val = 0;
+ }
+ cur_val1 = cur_val;
+ cur_val = iiii;
+}
+
+
+@ To be able to determine whether \.{\\write18} is enabled from within
+\TeX\ we also implement \.{\\eof18}. We sort of cheat by having an
+additional route |scan_four_bit_int_or_18| which is the same as
+|scan_four_bit_int| except it also accepts the value 18.
+
+@c
+void scan_four_bit_int_or_18(void)
+{
+ scan_int();
+ if ((cur_val < 0) || ((cur_val > 15) && (cur_val != 18))) {
+ print_err("Bad number");
+ help2("Since I expected to read a number between 0 and 15,",
+ "I changed this one to zero.");
+ int_error(cur_val);
+ cur_val = 0;
+ }
+}
+
+
+@ @c
+void scan_string_argument(void)
+{
+ int s;
+ scan_left_brace();
+ get_x_token();
+ while ((cur_cmd != right_brace_cmd)) {
+ if ((cur_cmd == letter_cmd) || (cur_cmd == other_char_cmd)) {
+ str_room(1);
+ append_char(cur_chr);
+ } else if (cur_cmd == spacer_cmd) {
+ str_room(1);
+ append_char(' ');
+ } else {
+ tprint("Bad token appearing in string argument");
+ }
+ get_x_token();
+ }
+ s = make_string();
+ /* todo: this was just conserving the string pool: */
+#if 0
+ if (str_eq_str("mi",s)) s="mi";
+ if (str_eq_str("mo",s)) s="mo";
+ if (str_eq_str("mn",s)) s="mn";
+#endif
+ cur_val = s;
+}
+
+
+@ An integer number can be preceded by any number of spaces and `\.+' or
+`\.-' signs. Then comes either a decimal constant (i.e., radix 10), an
+octal constant (i.e., radix 8, preceded by~'), a hexadecimal constant
+(radix 16, preceded by~"), an alphabetic constant (preceded by~`), or
+an internal variable. After scanning is complete,
+|cur_val| will contain the answer, which must be at most
+$2^{31}-1=2147483647$ in absolute value. The value of |radix| is set to
+10, 8, or 16 in the cases of decimal, octal, or hexadecimal constants,
+otherwise |radix| is set to zero. An optional space follows a constant.
+
+@c
+int radix; /* |scan_int| sets this to 8, 10, 16, or zero */
+
+
+@ 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
+ |scan_int|. The |scan_dimen| routine assumes that |cur_tok=point_token|
+ after the integer part of such a fraction has been scanned by |scan_int|,
+ and that the decimal point has been backed up to be scanned again.
+
+@c
+void scan_int(void)
+{ /* sets |cur_val| to an integer */
+ boolean negative; /* should the answer be negated? */
+ int m; /* |$2^{31}$ / radix|, the threshold of danger */
+ int d; /* the digit just scanned */
+ boolean vacuous; /* have no digits appeared? */
+ boolean OK_so_far; /* has an error message been issued? */
+ radix = 0;
+ OK_so_far = true;
+ /* Get the next non-blank non-sign token; set |negative| appropriately */
+ negative = false;
+ do {
+ /* Get the next non-blank non-call token */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+ if (cur_tok == other_token + '-') {
+ negative = !negative;
+ cur_tok = other_token + '+';
+ }
+ } while (cur_tok == other_token + '+');
+
+ RESTART:
+ if (cur_tok == alpha_token) {
+ /* Scan an alphabetic character code into |cur_val| */
+ /* A space is ignored after an alphabetic character constant, so that
+ such constants behave like numeric ones. */
+ get_token(); /* suppress macro expansion */
+ if (cur_tok < cs_token_flag) {
+ cur_val = cur_chr;
+ if (cur_cmd <= right_brace_cmd) {
+ if (cur_cmd == right_brace_cmd)
+ incr(align_state);
+ else
+ decr(align_state);
+ }
+ } else { /* the value of a csname in this context is its name */
+ str_number txt = cs_text(cur_tok - cs_token_flag);
+ if (is_active_cs(txt))
+ cur_val = active_cs_value(txt);
+ else if (single_letter(txt))
+ cur_val = pool_to_unichar(str_string(txt));
+ else
+ cur_val = (biggest_char + 1);
+ }
+ if (cur_val > biggest_char) {
+ print_err("Improper alphabetic constant");
+ help2("A one-character control sequence belongs after a ` mark.",
+ "So I'm essentially inserting \\0 here.");
+ cur_val = '0';
+ back_error();
+ } else {
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ }
+
+ } else if (cur_tok == cs_token_flag + frozen_primitive) {
+ /* Reset |cur_tok| for unexpandable primitives, goto restart */
+ /* This block deals with unexpandable \.{\\primitive} appearing at a spot where
+ an integer or an internal values should have been found. It fetches the
+ next token then resets |cur_cmd|, |cur_cs|, and |cur_tok|, based on the
+ primitive value of that token. No expansion takes place, because the
+ next token may be all sorts of things. This could trigger further
+ expansion creating new errors.
+ */
+ get_token();
+ cur_cs = prim_lookup(cs_text(cur_cs));
+ if (cur_cs != undefined_primitive) {
+ cur_cmd = get_prim_eq_type(cur_cs);
+ cur_chr = get_prim_equiv(cur_cs);
+ cur_tok = token_val(cur_cmd, cur_chr);
+ } else {
+ cur_cmd = relax_cmd;
+ cur_chr = 0;
+ cur_tok = cs_token_flag + frozen_relax;
+ cur_cs = frozen_relax;
+ }
+ goto RESTART;
+ } else if (cur_cmd == math_style_cmd) {
+ cur_val = cur_chr;
+ } else if ((cur_cmd >= min_internal_cmd) && (cur_cmd <= max_internal_cmd)) {
+ scan_something_internal(int_val_level, false);
+ } else {
+ /* Scan a numeric constant */
+ radix = 10;
+ m = 214748364;
+ if (cur_tok == octal_token) {
+ radix = 8;
+ m = 02000000000;
+ get_x_token();
+ } else if (cur_tok == hex_token) {
+ radix = 16;
+ m = 01000000000;
+ get_x_token();
+ }
+ vacuous = true;
+ cur_val = 0;
+ /* Accumulate the constant until |cur_tok| is not a suitable digit */
+ while (1) {
+ if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token)
+ && (cur_tok <= zero_token + 9)) {
+ d = cur_tok - zero_token;
+ } else if (radix == 16) {
+ if ((cur_tok <= A_token + 5) && (cur_tok >= A_token)) {
+ d = cur_tok - A_token + 10;
+ } else if ((cur_tok <= other_A_token + 5)
+ && (cur_tok >= other_A_token)) {
+ d = cur_tok - other_A_token + 10;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ vacuous = false;
+ if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10))) {
+ if (OK_so_far) {
+ print_err("Number too big");
+ help2
+ ("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
+ "so I'm using that number instead of yours.");
+ error();
+ cur_val = infinity;
+ OK_so_far = false;
+ }
+ } else {
+ cur_val = cur_val * radix + d;
+ }
+ get_x_token();
+ }
+ if (vacuous) {
+ /* Express astonishment that no number was here */
+ print_err("Missing number, treated as zero");
+ help3("A number should have been here; I inserted `0'.",
+ "(If you can't figure out why I needed to see a number,",
+ "look up `weird error' in the index to The TeXbook.)");
+ back_error();
+ } else if (cur_cmd != spacer_cmd) {
+ back_input();
+ }
+ }
+ if (negative)
+ negate(cur_val);
+}
+
+
+@ The following code is executed when |scan_something_internal| was
+called asking for |mu_val|, when we really wanted a ``mudimen'' instead
+of ``muglue.''
+
+@c
+static void coerce_glue(void)
+{
+ int v;
+ if (cur_val_level >= glue_val_level) {
+ v = width(cur_val);
+ delete_glue_ref(cur_val);
+ cur_val = v;
+ }
+}
+
+
+
+@ The |scan_dimen| routine is similar to |scan_int|, but it sets |cur_val| to
+a |scaled| value, i.e., an integral number of sp. One of its main tasks
+is therefore to interpret the abbreviations for various kinds of units and
+to convert measurements to scaled points.
+
+There are three parameters: |mu| is |true| if the finite units must be
+`\.{mu}', while |mu| is |false| if `\.{mu}' units are disallowed;
+|inf| is |true| if the infinite units `\.{fil}', `\.{fill}', `\.{filll}'
+are permitted; and |shortcut| is |true| if |cur_val| already contains
+an integer and only the units need to be considered.
+
+The order of infinity that was found in the case of infinite glue is returned
+in the global variable |cur_order|.
+
+@c
+int cur_order; /* order of infinity found by |scan_dimen| */
+
+
+@ Constructions like `\.{-\'77 pt}' are legal dimensions, so |scan_dimen|
+may begin with |scan_int|. This explains why it is convenient to use
+|scan_int| also for the integer part of a decimal fraction.
+
+Several branches of |scan_dimen| work with |cur_val| as an integer and
+with an auxiliary fraction |f|, so that the actual quantity of interest is
+$|cur_val|+|f|/2^{16}$. At the end of the routine, this ``unpacked''
+representation is put into the single word |cur_val|, which suddenly
+switches significance from |integer| to |scaled|.
+
+@c
+void scan_dimen(boolean mu, boolean inf, boolean shortcut)
+/* sets |cur_val| to a dimension */
+{
+ boolean negative; /* should the answer be negated? */
+ int f; /* numerator of a fraction whose denominator is $2^{16}$ */
+ /* Local variables for dimension calculations */
+ int num, denom; /* conversion ratio for the scanned units */
+ int k, kk; /* number of digits in a decimal fraction */
+ halfword p, q; /* top of decimal digit stack */
+ scaled v; /* an internal dimension */
+ int save_cur_val; /* temporary storage of |cur_val| */
+
+ f = 0;
+ arith_error = false;
+ cur_order = normal;
+ negative = false;
+ if (!shortcut) {
+ /* Get the next non-blank non-sign... */
+ negative = false;
+ do {
+ /* Get the next non-blank non-call token */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+ if (cur_tok == other_token + '-') {
+ negative = !negative;
+ cur_tok = other_token + '+';
+ }
+ } while (cur_tok == other_token + '+');
+
+ if ((cur_cmd >= min_internal_cmd) && (cur_cmd <= max_internal_cmd)) {
+ /* Fetch an internal dimension and |goto attach_sign|,
+ or fetch an internal integer */
+ if (mu) {
+ scan_something_internal(mu_val_level, false);
+ coerce_glue();
+ if (cur_val_level == mu_val_level)
+ goto ATTACH_SIGN;
+ if (cur_val_level != int_val_level)
+ mu_error();
+ } else {
+ scan_something_internal(dimen_val_level, false);
+ if (cur_val_level == dimen_val_level)
+ goto ATTACH_SIGN;
+ }
+
+ } else {
+ back_input();
+ if (cur_tok == continental_point_token) {
+ cur_tok = point_token;
+ }
+ if (cur_tok != point_token) {
+ scan_int();
+ } else {
+ radix = 10;
+ cur_val = 0;
+ }
+ if (cur_tok == continental_point_token)
+ cur_tok = point_token;
+ if ((radix == 10) && (cur_tok == point_token)) {
+ /* Scan decimal fraction */
+ /* When the following code is executed, we have |cur_tok=point_token|, but this
+ token has been backed up using |back_input|; we must first discard it.
+
+ It turns out that a decimal point all by itself is equivalent to `\.{0.0}'.
+ Let's hope people don't use that fact. */
+
+ k = 0;
+ p = null;
+ get_token(); /* |point_token| is being re-scanned */
+ while (1) {
+ get_x_token();
+ if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))
+ break;
+ if (k < 17) { /* digits for |k>=17| cannot affect the result */
+ q = get_avail();
+ set_token_link(q, p);
+ set_token_info(q, cur_tok - zero_token);
+ p = q;
+ incr(k);
+ }
+ }
+ for (kk = k; kk >= 1; kk--) {
+ dig[kk - 1] = token_info(p);
+ q = p;
+ p = token_link(p);
+ free_avail(q);
+ }
+ f = round_decimals(k);
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ }
+ }
+ }
+ if (cur_val < 0) { /* in this case |f=0| */
+ negative = !negative;
+ negate(cur_val);
+ }
+ /* Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^{16})$, where there
+ are |x| sp per unit; |goto attach_sign| if the units are internal */
+ /* Now comes the harder part: At this point in the program, |cur_val| is a
+ nonnegative integer and $f/2^{16}$ is a nonnegative fraction less than 1;
+ we want to multiply the sum of these two quantities by the appropriate
+ factor, based on the specified units, in order to produce a |scaled|
+ result, and we want to do the calculation with fixed point arithmetic that
+ does not overflow.
+ */
+
+ if (inf) {
+ /* Scan for (f)\.{fil} units; |goto attach_fraction| if found */
+ /* In traditional TeX, a specification like `\.{filllll}' or `\.{fill L L
+ L}' will lead to two error messages (one for each additional keyword
+ \.{"l"}).
+ Not so for luatex, it just parses the construct in reverse. */
+ if (scan_keyword("filll")) {
+ cur_order = filll;
+ goto ATTACH_FRACTION;
+ } else if (scan_keyword("fill")) {
+ cur_order = fill;
+ goto ATTACH_FRACTION;
+ } else if (scan_keyword("fil")) {
+ cur_order = fil;
+ goto ATTACH_FRACTION;
+ } else if (scan_keyword("fi")) {
+ cur_order = sfi;
+ goto ATTACH_FRACTION;
+ }
+
+ }
+ /* Scan for (u)units that are internal dimensions;
+ |goto attach_sign| with |cur_val| set if found */
+ save_cur_val = cur_val;
+ /* Get the next non-blank non-call... */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ if ((cur_cmd < min_internal_cmd) || (cur_cmd > max_internal_cmd)) {
+ back_input();
+ } else {
+ if (mu) {
+ scan_something_internal(mu_val_level, false);
+ coerce_glue();
+ if (cur_val_level != mu_val_level)
+ mu_error();
+ } else {
+ scan_something_internal(dimen_val_level, false);
+ }
+ v = cur_val;
+ goto FOUND;
+ }
+ if (mu)
+ goto NOT_FOUND;
+ if (scan_keyword("em")) {
+ v = (quad(get_cur_font()));
+ } else if (scan_keyword("ex")) {
+ v = (x_height(get_cur_font()));
+ } else if (scan_keyword("px")) {
+ v = dimen_par(pdf_px_dimen_code);
+ } else {
+ goto NOT_FOUND;
+ }
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+
+ FOUND:
+ cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000));
+ goto ATTACH_SIGN;
+ NOT_FOUND:
+
+ if (mu) {
+ /* Scan for (m)\.{mu} units and |goto attach_fraction| */
+ if (scan_keyword("mu")) {
+ goto ATTACH_FRACTION;
+ } else {
+ print_err("Illegal unit of measure (mu inserted)");
+ help4("The unit of measurement in math glue must be mu.",
+ "To recover gracefully from this error, it's best to",
+ "delete the erroneous units; e.g., type `2' to delete",
+ "two letters. (See Chapter 27 of The TeXbook.)");
+ error();
+ goto ATTACH_FRACTION;
+ }
+ }
+ if (scan_keyword("true")) {
+ /* Adjust (f)for the magnification ratio */
+ prepare_mag();
+ if (int_par(mag_code) != 1000) {
+ cur_val = xn_over_d(cur_val, 1000, int_par(mag_code));
+ f = (1000 * f + 0200000 * tex_remainder) / int_par(mag_code);
+ cur_val = cur_val + (f / 0200000);
+ f = f % 0200000;
+ }
+ }
+ if (scan_keyword("pt"))
+ goto ATTACH_FRACTION; /* the easy case */
+ /* Scan for (a)all other units and adjust |cur_val| and |f| accordingly;
+ |goto done| in the case of scaled points */
+
+ /* The necessary conversion factors can all be specified exactly as
+ fractions whose numerator and denominator add to 32768 or less.
+ According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;
+ this agrees well with the value $\rm1000.333\,mm$ cited by Bosshard
+ \^{Bosshard, Hans Rudolf}
+ 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 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.
+ */
+
+#define set_conversion(A,B) do { num=(A); denom=(B); } while(0)
+
+ if (scan_keyword("in")) {
+ set_conversion(7227, 100);
+ } else if (scan_keyword("pc")) {
+ set_conversion(12, 1);
+ } else if (scan_keyword("cm")) {
+ set_conversion(7227, 254);
+ } else if (scan_keyword("mm")) {
+ set_conversion(7227, 2540);
+ } else if (scan_keyword("bp")) {
+ set_conversion(7227, 7200);
+ } else if (scan_keyword("dd")) {
+ set_conversion(1238, 1157);
+ } else if (scan_keyword("cc")) {
+ set_conversion(14856, 1157);
+ } else if (scan_keyword("nd")) {
+ set_conversion(685, 642);
+ } else if (scan_keyword("nc")) {
+ set_conversion(1370, 107);
+ } else if (scan_keyword("sp")) {
+ goto DONE;
+ } else {
+ /* Complain about unknown unit and |goto done2| */
+ print_err("Illegal unit of measure (pt inserted)");
+ help6("Dimensions can be in units of em, ex, in, pt, pc,",
+ "cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!",
+ "I'll assume that you meant to say pt, for printer's points.",
+ "To recover gracefully from this error, it's best to",
+ "delete the erroneous units; e.g., type `2' to delete",
+ "two letters. (See Chapter 27 of The TeXbook.)");
+ error();
+ goto DONE2;
+ }
+ cur_val = xn_over_d(cur_val, num, denom);
+ f = (num * f + 0200000 * tex_remainder) / denom;
+ cur_val = cur_val + (f / 0200000);
+ f = f % 0200000;
+ DONE2:
+ ATTACH_FRACTION:
+ if (cur_val >= 040000)
+ arith_error = true;
+ else
+ cur_val = cur_val * unity + f;
+ DONE:
+ /* Scan an optional space */
+ get_x_token();
+ if (cur_cmd != spacer_cmd)
+ back_input();
+ ATTACH_SIGN:
+ if (arith_error || (abs(cur_val) >= 010000000000)) {
+ /* Report that this dimension is out of range */
+ print_err("Dimension too large");
+ help2("I can't work with sizes bigger than about 19 feet.",
+ "Continue and I'll use the largest value I can.");
+ error();
+ cur_val = max_dimen;
+ arith_error = false;
+ }
+ if (negative)
+ negate(cur_val);
+}
+
+
+@ The final member of \TeX's value-scanning trio is |scan_glue|, which
+makes |cur_val| point to a glue specification. The reference count of that
+glue spec will take account of the fact that |cur_val| is pointing to~it.
+
+The |level| parameter should be either |glue_val| or |mu_val|.
+
+Since |scan_dimen| was so much more complex than |scan_int|, we might expect
+|scan_glue| to be even worse. But fortunately, it is very simple, since
+most of the work has already been done.
+
+@c
+void scan_glue(int level)
+{ /* sets |cur_val| to a glue spec pointer */
+ boolean negative; /* should the answer be negated? */
+ halfword q; /* new glue specification */
+ boolean mu; /* does |level=mu_val|? */
+ mu = (level == mu_val_level);
+ /* Get the next non-blank non-sign... */
+ negative = false;
+ do {
+ /* Get the next non-blank non-call token */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+ if (cur_tok == other_token + '-') {
+ negative = !negative;
+ cur_tok = other_token + '+';
+ }
+ } while (cur_tok == other_token + '+');
+
+ if ((cur_cmd >= min_internal_cmd) && (cur_cmd <= max_internal_cmd)) {
+ scan_something_internal(level, negative);
+ if (cur_val_level >= glue_val_level) {
+ if (cur_val_level != level)
+ mu_error();
+ return;
+ }
+ if (cur_val_level == int_val_level)
+ scan_dimen(mu, false, true);
+ else if (level == mu_val_level)
+ mu_error();
+ } else {
+ back_input();
+ scan_dimen(mu, false, false);
+ if (negative)
+ negate(cur_val);
+ }
+ /* Create a new glue specification whose width is |cur_val|; scan for its
+ stretch and shrink components */
+ q = new_spec(zero_glue);
+ width(q) = cur_val;
+ if (scan_keyword("plus")) {
+ scan_dimen(mu, true, false);
+ stretch(q) = cur_val;
+ stretch_order(q) = (quarterword) cur_order;
+ }
+ if (scan_keyword("minus")) {
+ scan_dimen(mu, true, false);
+ shrink(q) = cur_val;
+ shrink_order(q) = (quarterword) cur_order;
+ }
+ cur_val = q;
+}
+
+@ This is an omega routine
+@c
+void scan_scaled(void)
+{ /* sets |cur_val| to a scaled value */
+ boolean negative; /* should the answer be negated? */
+ int f; /* numerator of a fraction whose denominator is $2^{16}$ */
+ int k, kk; /* number of digits in a decimal fraction */
+ halfword p, q; /* top of decimal digit stack */
+ f = 0;
+ arith_error = false;
+ negative = false;
+ /* Get the next non-blank non-sign... */
+ negative = false;
+ do {
+ /* Get the next non-blank non-call token */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+ if (cur_tok == other_token + '-') {
+ negative = !negative;
+ cur_tok = other_token + '+';
+ }
+ } while (cur_tok == other_token + '+');
+
+ back_input();
+ if (cur_tok == continental_point_token)
+ cur_tok = point_token;
+ if (cur_tok != point_token) {
+ scan_int();
+ } else {
+ radix = 10;
+ cur_val = 0;
+ }
+ if (cur_tok == continental_point_token)
+ cur_tok = point_token;
+ if ((radix == 10) && (cur_tok == point_token)) {
+ /* Scan decimal fraction */
+ /* TODO: merge this with the same block in |scan_dimen| */
+ /* When the following code is executed, we have |cur_tok=point_token|, but this
+ token has been backed up using |back_input|; we must first discard it.
+
+ It turns out that a decimal point all by itself is equivalent to `\.{0.0}'.
+ Let's hope people don't use that fact. */
+
+ k = 0;
+ p = null;
+ get_token(); /* |point_token| is being re-scanned */
+ while (1) {
+ get_x_token();
+ if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))
+ break;
+ if (k < 17) { /* digits for |k>=17| cannot affect the result */
+ q = get_avail();
+ set_token_link(q, p);
+ set_token_info(q, cur_tok - zero_token);
+ p = q;
+ incr(k);
+ }
+ }
+ for (kk = k; kk >= 1; kk--) {
+ dig[kk - 1] = token_info(p);
+ q = p;
+ p = token_link(p);
+ free_avail(q);
+ }
+ f = round_decimals(k);
+ if (cur_cmd != spacer_cmd)
+ back_input();
+
+ }
+ if (cur_val < 0) { /* in this case |f=0| */
+ negative = !negative;
+ negate(cur_val);
+ }
+ if (cur_val > 040000)
+ arith_error = true;
+ else
+ cur_val = cur_val * unity + f;
+ if (arith_error || (abs(cur_val) >= 010000000000)) {
+ print_err("Stack number too large");
+ error();
+ }
+ if (negative)
+ negate(cur_val);
+}
+
+
+@ This procedure is supposed to scan something like `\.{\\skip\\count12}',
+i.e., whatever can follow `\.{\\the}', and it constructs a token list
+containing something like `\.{-3.0pt minus 0.5fill}'.
+
+@c
+halfword the_toks(void)
+{
+ int old_setting; /* holds |selector| setting */
+ halfword p, q, r; /* used for copying a token list */
+ int c; /* value of |cur_chr| */
+ str_number s;
+ halfword retval;
+ /* Handle \.{\\unexpanded} or \.{\\detokenize} and |return| */
+ if (odd(cur_chr)) {
+ c = cur_chr;
+ scan_general_text();
+ if (c == 1) {
+ return cur_val;
+ } else {
+ old_setting = selector;
+ selector = new_string;
+ p = get_avail();
+ set_token_link(p, token_link(temp_token_head));
+ token_show(p);
+ flush_list(p);
+ selector = old_setting;
+ s = make_string();
+ retval = str_toks(str_lstring(s));
+ flush_str(s);
+ return retval;
+ }
+ }
+ get_x_token();
+ scan_something_internal(tok_val_level, false);
+ if (cur_val_level >= ident_val_level) {
+ /* Copy the token list */
+ p = temp_token_head;
+ set_token_link(p, null);
+ if (cur_val_level == ident_val_level) {
+ store_new_token(cs_token_flag + cur_val);
+ } else if (cur_val != null) {
+ r = token_link(cur_val); /* do not copy the reference count */
+ while (r != null) {
+ fast_store_new_token(token_info(r));
+ r = token_link(r);
+ }
+ }
+ return p;
+ } else {
+ old_setting = selector;
+ selector = new_string;
+ switch (cur_val_level) {
+ case int_val_level:
+ print_int(cur_val);
+ break;
+ case attr_val_level:
+ print_int(cur_val);
+ break;
+ case dir_val_level:
+ print_dir(cur_val);
+ break;
+ case dimen_val_level:
+ print_scaled(cur_val);
+ tprint("pt");
+ break;
+ case glue_val_level:
+ print_spec(cur_val, "pt");
+ delete_glue_ref(cur_val);
+ break;
+ case mu_val_level:
+ print_spec(cur_val, "mu");
+ delete_glue_ref(cur_val);
+ break;
+ } /* there are no other cases */
+ selector = old_setting;
+ s = make_string();
+ retval = str_toks(str_lstring(s));
+ flush_str(s);
+ return retval;
+ }
+}
+
+@ @c
+str_number the_scanned_result(void)
+{
+ int old_setting; /* holds |selector| setting */
+ str_number r; /* return value * */
+ old_setting = selector;
+ selector = new_string;
+ if (cur_val_level >= ident_val_level) {
+ if (cur_val != null) {
+ show_token_list(token_link(cur_val), null, -1);
+ r = make_string();
+ } else {
+ r = get_nullstr();
+ }
+ } else {
+ switch (cur_val_level) {
+ case int_val_level:
+ print_int(cur_val);
+ break;
+ case attr_val_level:
+ print_int(cur_val);
+ break;
+ case dir_val_level:
+ print_dir(cur_val);
+ break;
+ case dimen_val_level:
+ print_scaled(cur_val);
+ tprint("pt");
+ break;
+ case glue_val_level:
+ print_spec(cur_val, "pt");
+ delete_glue_ref(cur_val);
+ break;
+ case mu_val_level:
+ print_spec(cur_val, "mu");
+ delete_glue_ref(cur_val);
+ break;
+ } /* there are no other cases */
+ r = make_string();
+ }
+ selector = old_setting;
+ return r;
+}
+
+
+
+@ The following routine is used to implement `\.{\\fontdimen} |n| |f|'.
+The boolean parameter |writing| is set |true| if the calling program
+intends to change the parameter value.
+
+@c
+static void font_param_error(int f)
+{
+ print_err("Font ");
+ print_esc(font_id_text(f));
+ tprint(" has only ");
+ print_int(font_params(f));
+ tprint(" fontdimen parameters");
+ help2("To increase the number of font parameters, you must",
+ "use \\fontdimen immediately after the \\font is loaded.");
+ error();
+}
+
+void set_font_dimen(void)
+{
+ internal_font_number f;
+ int n; /* the parameter number */
+ scan_int();
+ n = cur_val;
+ scan_font_ident();
+ f = cur_val;
+ if (n <= 0) {
+ font_param_error(f);
+ } else {
+ if (n > font_params(f)) {
+ if (font_touched(f)) {
+ font_param_error(f);
+ } else {
+ /* Increase the number of parameters in the font */
+ do {
+ set_font_param(f, (font_params(f) + 1), 0);
+ } while (n != font_params(f));
+ }
+ }
+ }
+ scan_optional_equals();
+ scan_normal_dimen();
+ set_font_param(f, n, cur_val);
+}
+
+void get_font_dimen(void)
+{
+ internal_font_number f;
+ int n; /* the parameter number */
+ scan_int();
+ n = cur_val;
+ scan_font_ident();
+ f = cur_val;
+ cur_val = 0; /* initialize return value */
+ if (n <= 0) {
+ font_param_error(f);
+ goto EXIT;
+ } else {
+ if (n > font_params(f)) {
+ if (font_touched(f)) {
+ font_param_error(f);
+ goto EXIT;
+ } else {
+ /* Increase the number of parameters in the font */
+ do {
+ set_font_param(f, (font_params(f) + 1), 0);
+ } while (n != font_params(f));
+
+ }
+ }
+ }
+ cur_val = font_param(f, n);
+ EXIT:
+ scanned_result(cur_val, dimen_val_level);
+}
+
+
+@ Here's a similar procedure that returns a pointer to a rule node. This
+routine is called just after \TeX\ has seen \.{\\hrule} or \.{\\vrule};
+therefore |cur_cmd| will be either |hrule| or |vrule|. The idea is to store
+the default rule dimensions in the node, then to override them if
+`\.{height}' or `\.{width}' or `\.{depth}' specifications are
+found (in any order).
+
+@c
+halfword scan_rule_spec(void)
+{
+ halfword q; /* the rule node being created */
+ q = new_rule(); /* |width|, |depth|, and |height| all equal |null_flag| now */
+ if (cur_cmd == vrule_cmd) {
+ width(q) = default_rule;
+ rule_dir(q) = body_direction;
+ } else {
+ height(q) = default_rule;
+ depth(q) = 0;
+ rule_dir(q) = text_direction;
+ }
+ RESWITCH:
+ if (scan_keyword("width")) {
+ scan_normal_dimen();
+ width(q) = cur_val;
+ goto RESWITCH;
+ }
+ if (scan_keyword("height")) {
+ scan_normal_dimen();
+ height(q) = cur_val;
+ goto RESWITCH;
+ }
+ if (scan_keyword("depth")) {
+ scan_normal_dimen();
+ depth(q) = cur_val;
+ goto RESWITCH;
+ }
+ return q;
+}
+
+
+@ Declare procedures that scan font-related stuff
+
+@c
+void scan_font_ident(void)
+{
+ internal_font_number f;
+ halfword m;
+ /* Get the next non-blank non-call... */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ if ((cur_cmd == def_font_cmd) || (cur_cmd == letterspace_font_cmd)
+ || (cur_cmd == pdf_copy_font_cmd)) {
+ f = get_cur_font();
+ } else if (cur_cmd == set_font_cmd) {
+ f = cur_chr;
+ set_font_touched(f, 1);
+ } else if (cur_cmd == def_family_cmd) {
+ m = cur_chr;
+ scan_math_family_int();
+ f = fam_fnt(cur_val, m);
+ set_font_touched(f, 1);
+ } else {
+ print_err("Missing font identifier");
+ help2("I was looking for a control sequence whose",
+ "current meaning has been defined by \\font.");
+ back_error();
+ f = null_font;
+ }
+ cur_val = f;
+}
+
+@ The |scan_general_text| procedure is much like |scan_toks(false,false)|,
+but will be invoked via |expand|, i.e., recursively.
+
+The token list (balanced text) created by |scan_general_text| begins
+at |link(temp_token_head)| and ends at |cur_val|. (If |cur_val=temp_token_head|,
+the list is empty.)
+
+@c
+void scan_general_text(void)
+{
+ int s; /* to save |scanner_status| */
+ halfword w; /* to save |warning_index| */
+ halfword d; /* to save |def_ref| */
+ halfword p; /* tail of the token list being built */
+ halfword q; /* new node being added to the token list via |store_new_token| */
+ halfword unbalance; /* number of unmatched left braces */
+ s = scanner_status;
+ w = warning_index;
+ d = def_ref;
+ scanner_status = absorbing;
+ warning_index = cur_cs;
+ p = get_avail();
+ def_ref = p;
+ set_token_ref_count(def_ref, 0);
+ p = def_ref;
+ scan_left_brace(); /* remove the compulsory left brace */
+ unbalance = 1;
+ while (1) {
+ get_token();
+ if (cur_tok < right_brace_limit) {
+ if (cur_cmd < right_brace_cmd) {
+ incr(unbalance);
+ } else {
+ decr(unbalance);
+ if (unbalance == 0)
+ break;
+ }
+ }
+ store_new_token(cur_tok);
+ }
+ q = token_link(def_ref);
+ free_avail(def_ref); /* discard reference count */
+ if (q == null)
+ cur_val = temp_token_head;
+ else
+ cur_val = p;
+ set_token_link(temp_token_head, q);
+ scanner_status = s;
+ warning_index = w;
+ def_ref = d;
+}
+
+
+@ The |get_x_or_protected| procedure is like |get_x_token| except that
+protected macros are not expanded.
+
+@c
+void get_x_or_protected(void)
+{ /* sets |cur_cmd|, |cur_chr|, |cur_tok|,
+ and expands non-protected macros */
+ while (1) {
+ get_token();
+ if (cur_cmd <= max_command_cmd)
+ return;
+ if ((cur_cmd >= call_cmd) && (cur_cmd < end_template_cmd)) {
+ if (token_info(token_link(cur_chr)) == protected_token)
+ return;
+ }
+ expand();
+ }
+}
+
+
+@ |scan_toks|. This function returns a pointer to the tail of a new token
+list, and it also makes |def_ref| point to the reference count at the
+head of that list.
+
+There are two boolean parameters, |macro_def| and |xpand|. If |macro_def|
+is true, the goal is to create the token list for a macro definition;
+otherwise the goal is to create the token list for some other \TeX\
+primitive: \.{\\mark}, \.{\\output}, \.{\\everypar}, \.{\\lowercase},
+\.{\\uppercase}, \.{\\message}, \.{\\errmessage}, \.{\\write}, or
+\.{\\special}. In the latter cases a left brace must be scanned next; this
+left brace will not be part of the token list, nor will the matching right
+brace that comes at the end. If |xpand| is false, the token list will
+simply be copied from the input using |get_token|. Otherwise all expandable
+tokens will be expanded until unexpandable tokens are left, except that
+the results of expanding `\.{\\the}' are not expanded further.
+If both |macro_def| and |xpand| are true, the expansion applies
+only to the macro body (i.e., to the material following the first
+|left_brace| character).
+
+The value of |cur_cs| when |scan_toks| begins should be the |eqtb|
+address of the control sequence to display in ``runaway'' error
+messages.
+
+@c
+halfword scan_toks(boolean macro_def, boolean xpand)
+{
+ halfword t; /* token representing the highest parameter number */
+ halfword s; /* saved token */
+ halfword p; /* tail of the token list being built */
+ halfword q; /* new node being added to the token list via |store_new_token| */
+ halfword unbalance; /* number of unmatched left braces */
+ halfword hash_brace; /* possible `\.{\#\{}' token */
+ if (macro_def)
+ scanner_status = defining;
+ else
+ scanner_status = absorbing;
+ warning_index = cur_cs;
+ p = get_avail();
+ def_ref = p;
+ set_token_ref_count(def_ref, 0);
+ p = def_ref;
+ hash_brace = 0;
+ t = zero_token;
+ if (macro_def) {
+ /* Scan and build the parameter part of the macro definition */
+ while (1) {
+ get_token(); /* set |cur_cmd|, |cur_chr|, |cur_tok| */
+ if (cur_tok < right_brace_limit)
+ break;
+ if (cur_cmd == mac_param_cmd) {
+ /* If the next character is a parameter number, make |cur_tok|
+ a |match| token; but if it is a left brace, store
+ `|left_brace|, |end_match|', set |hash_brace|, and |goto done|;
+ */
+ s = match_token + cur_chr;
+ get_token();
+ if (cur_cmd == left_brace_cmd) {
+ hash_brace = cur_tok;
+ store_new_token(cur_tok);
+ store_new_token(end_match_token);
+ goto DONE;
+ }
+ if (t == zero_token + 9) {
+ print_err("You already have nine parameters");
+ help1("I'm going to ignore the # sign you just used.");
+ error();
+ } else {
+ incr(t);
+ if (cur_tok != t) {
+ print_err("Parameters must be numbered consecutively");
+ help2
+ ("I've inserted the digit you should have used after the #.",
+ "Type `1' to delete what you did use.");
+ back_error();
+ }
+ cur_tok = s;
+ }
+ }
+ store_new_token(cur_tok);
+ }
+ store_new_token(end_match_token);
+ if (cur_cmd == right_brace_cmd) {
+ /* Express shock at the missing left brace; |goto found| */
+ print_err("Missing { inserted");
+ incr(align_state);
+ help2
+ ("Where was the left brace? You said something like `\\def\\a}',",
+ "which I'm going to interpret as `\\def\\a{}'.");
+ error();
+ goto FOUND;
+ }
+
+ } else {
+ scan_left_brace(); /* remove the compulsory left brace */
+ }
+ DONE:
+ /* Scan and build the body of the token list; |goto found| when finished */
+ unbalance = 1;
+ while (1) {
+ if (xpand) {
+ /* Expand the next part of the input */
+ /* Here we insert an entire token list created by |the_toks| without
+ expanding it further. */
+ while (1) {
+ get_token_lua();
+ if (cur_cmd >= call_cmd) {
+ if (token_info(token_link(cur_chr)) == protected_token) {
+ cur_cmd = relax_cmd;
+ cur_chr = no_expand_flag;
+ }
+ }
+ if (cur_cmd <= max_command_cmd)
+ break;
+ if (cur_cmd != the_cmd) {
+ expand();
+ } else {
+ q = the_toks();
+ if (token_link(temp_token_head) != null) {
+ set_token_link(p, token_link(temp_token_head));
+ p = q;
+ }
+ }
+ }
+ x_token();
+
+ } else {
+ get_token();
+ }
+ if (cur_tok < right_brace_limit) {
+ if (cur_cmd < right_brace_cmd) {
+ incr(unbalance);
+ } else {
+ decr(unbalance);
+ if (unbalance == 0)
+ goto FOUND;
+ }
+ } else if (cur_cmd == mac_param_cmd) {
+ if (macro_def) {
+ /* Look for parameter number or \.{\#\#} */
+ s = cur_tok;
+ if (xpand)
+ get_x_token();
+ else
+ get_token();
+ if (cur_cmd != mac_param_cmd) {
+ if ((cur_tok <= zero_token) || (cur_tok > t)) {
+ print_err("Illegal parameter number in definition of ");
+ sprint_cs(warning_index);
+ help3("You meant to type ## instead of #, right?",
+ "Or maybe a } was forgotten somewhere earlier, and things",
+ "are all screwed up? I''m going to assume that you meant ##.");
+ back_error();
+ cur_tok = s;
+ } else {
+ cur_tok = out_param_token - '0' + cur_chr;
+ }
+ }
+ }
+ }
+ store_new_token(cur_tok);
+ }
+ FOUND:
+ scanner_status = normal;
+ if (hash_brace != 0)
+ store_new_token(hash_brace);
+ return p;
+}
+
+
+@ Here we declare two trivial procedures in order to avoid mutually
+recursive procedures with parameters.
+
+@c
+void scan_normal_glue(void)
+{
+ scan_glue(glue_val_level);
+}
+
+void scan_mu_glue(void)
+{
+ scan_glue(mu_val_level);
+}
+
+@ The |scan_expr| procedure scans and evaluates an expression.
+
+@ Evaluating an expression is a recursive process: When the left
+parenthesis of a subexpression is scanned we descend to the next level
+of recursion; the previous level is resumed with the matching right
+parenthesis.
+
+@c
+typedef enum {
+ expr_none = 0, /* \.( seen, or \.( $\langle\it expr\rangle$ \.) seen */
+ expr_add = 1, /* \.( $\langle\it expr\rangle$ \.+ seen */
+ expr_sub = 2, /* \.( $\langle\it expr\rangle$ \.- seen */
+ expr_mult = 3, /* $\langle\it term\rangle$ \.* seen */
+ expr_div = 4, /* $\langle\it term\rangle$ \./ seen */
+ expr_scale = 5, /* $\langle\it term\rangle$ \.* $\langle\it factor\rangle$ \./ seen */
+} expression_states;
+
+
+@ We want to make sure that each term and (intermediate) result is in
+ the proper range. Integer values must not exceed |infinity|
+ ($2^{31}-1$) in absolute value, dimensions must not exceed |max_dimen|
+ ($2^{30}-1$). We avoid the absolute value of an integer, because this
+ might fail for the value $-2^{31}$ using 32-bit arithmetic.
+
+@ clear a number or dimension and set |arith_error|
+
+@c
+#define num_error(A) do { \
+ arith_error=true; \
+ A=0; \
+ } while (0)
+
+
+@ clear a glue spec and set |arith_error|
+
+@c
+#define glue_error(A) do { \
+ arith_error=true; \
+ delete_glue_ref(A); \
+ A=new_spec(zero_glue); \
+ } while (0)
+
+
+#define normalize_glue(A) do { \
+ if (stretch(A)==0) stretch_order(A)=normal; \
+ if (shrink(A)==0) shrink_order(A)=normal; \
+ } while (0)
+
+
+@ Parenthesized subexpressions can be inside expressions, and this
+nesting has a stack. Seven local variables represent the top of the
+expression stack: |p| points to pushed-down entries, if any; |l|
+specifies the type of expression currently beeing evaluated; |e| is the
+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.
+
+@c
+#define expr_type(A) type((A)+1)
+#define expr_state(A) subtype((A)+1)
+#define expr_e_field(A) vlink((A)+1) /* saved expression so far */
+#define expr_t_field(A) vlink((A)+2) /* saved term so far */
+#define expr_n_field(A) vinfo((A)+2) /* saved numerator */
+
+
+#define expr_add_sub(A,B,C) add_or_sub((A),(B),(C),(r==expr_sub))
+#define expr_a(A,B) expr_add_sub((A),(B),max_dimen)
+
+@
+ The function |add_or_sub(x,y,max_answer,negative)| computes the sum
+ (for |negative=false|) or difference (for |negative=true|) of |x| and
+ |y|, provided the absolute value of the result does not exceed
+ |max_answer|.
+
+@c
+int add_or_sub(int x, int y, int max_answer, boolean negative)
+{
+ int a; /* the answer */
+ if (negative)
+ negate(y);
+ if (x >= 0) {
+ if (y <= max_answer - x)
+ a = x + y;
+ else
+ num_error(a);
+ } else if (y >= -max_answer - x) {
+ a = x + y;
+ } else {
+ num_error(a);
+ }
+ return a;
+}
+
+
+#define expr_m(A) A = nx_plus_y((A),f,0)
+
+#define expr_d(A) A=quotient((A),f)
+
+
+@ The function |quotient(n,d)| computes the rounded quotient
+$q=\lfloor n/d+{1\over2}\rfloor$, when $n$ and $d$ are positive.
+
+@c
+int quotient(int n, int d)
+{
+ boolean negative; /* should the answer be negated? */
+ int a; /* the answer */
+ if (d == 0) {
+ num_error(a);
+ } else {
+ if (d > 0) {
+ negative = false;
+ } else {
+ negate(d);
+ negative = true;
+ }
+ if (n < 0) {
+ negate(n);
+ negative = !negative;
+ }
+ a = n / d;
+ n = n - a * d;
+ d = n - d; /* avoid certain compiler optimizations! */
+ if (d + n >= 0)
+ incr(a);
+ if (negative)
+ negate(a);
+ }
+ return a;
+}
+
+#define expr_s(A) A=fract((A),n,f,max_dimen)
+
+
+@ Finally, the function |fract(x,n,d,max_answer)| computes the integer
+$q=\lfloor xn/d+{1\over2}\rfloor$, when $x$, $n$, and $d$ are positive
+and the result does not exceed |max_answer|. We can't use floating
+point arithmetic since the routine must produce identical results in all
+cases; and it would be too dangerous to multiply by~|n| and then divide
+by~|d|, in separate operations, since overflow might well occur. Hence
+this subroutine simulates double precision arithmetic, somewhat
+analogous to Metafont's |make_fraction| and |take_fraction| routines.
+
+@c
+int fract(int x, int n, int d, int max_answer)
+{
+ boolean negative; /* should the answer be negated? */
+ int a; /* the answer */
+ int f; /* a proper fraction */
+ int h; /* smallest integer such that |2*h>=d| */
+ int r; /* intermediate remainder */
+ int t; /* temp variable */
+ if (d == 0)
+ goto TOO_BIG;
+ a = 0;
+ if (d > 0) {
+ negative = false;
+ } else {
+ negate(d);
+ negative = true;
+ }
+ if (x < 0) {
+ negate(x);
+ negative = !negative;
+ } else if (x == 0) {
+ goto DONE;
+ }
+ if (n < 0) {
+ negate(n);
+ negative = !negative;
+ }
+ t = n / d;
+ if (t > max_answer / x)
+ goto TOO_BIG;
+ a = t * x;
+ n = n - t * d;
+ if (n == 0)
+ goto FOUND;
+ t = x / d;
+ if (t > (max_answer - a) / n)
+ goto TOO_BIG;
+ a = a + t * n;
+ x = x - t * d;
+ if (x == 0)
+ goto FOUND;
+ if (x < n) {
+ t = x;
+ x = n;
+ n = t;
+ }
+
+
+ /* now |0<n<=x<d| */
+ /* Compute $f=\lfloor xn/d+{1\over2}\rfloor$; */
+ /* The loop here preserves the following invariant relations
+ between |f|, |x|, |n|, and~|r|:
+ (i)~$f+\lfloor(xn+(r+d))/d\rfloor=\lfloor x_0n_0/d+{1\over2}\rfloor$;
+ (ii)~|-d<=r<0<n<=x<d|, where $x_0$, $n_0$ are the original values of~$x$
+ and $n$. */
+ /* Notice that the computation specifies |(x-d)+x| instead of |(x+x)-d|,
+ because the latter could overflow. */
+ f = 0;
+ r = (d / 2) - d;
+ h = -r;
+ while (1) {
+ if (odd(n)) {
+ r = r + x;
+ if (r >= 0) {
+ r = r - d;
+ incr(f);
+ }
+ }
+ n = n / 2;
+ if (n == 0)
+ break;
+ if (x < h) {
+ x = x + x;
+ } else {
+ t = x - d;
+ x = t + x;
+ f = f + n;
+ if (x < n) {
+ if (x == 0)
+ break;
+ t = x;
+ x = n;
+ n = t;
+ }
+ }
+ }
+
+ if (f > (max_answer - a))
+ goto TOO_BIG;
+ a = a + f;
+ FOUND:
+ if (negative)
+ negate(a);
+ goto DONE;
+ TOO_BIG:
+ num_error(a);
+ DONE:
+ return a;
+}
+
+@ @c
+void scan_expr(void)
+{ /* scans and evaluates an expression */
+ boolean a, b; /* saved values of |arith_error| */
+ int l; /* type of expression */
+ int r; /* state of expression so far */
+ int s; /* state of term so far */
+ int o; /* next operation or type of next factor */
+ int e; /* expression so far */
+ int t; /* term so far */
+ int f; /* current factor */
+ int n; /* numerator of combined multiplication and division */
+ halfword p; /* top of expression stack */
+ halfword q; /* for stack manipulations */
+ l = cur_val_level;
+ a = arith_error;
+ b = false;
+ p = null;
+ /* Scan and evaluate an expression |e| of type |l| */
+ RESTART:
+ r = expr_none;
+ e = 0;
+ s = expr_none;
+ t = 0;
+ n = 0;
+ CONTINUE:
+ if (s == expr_none)
+ o = l;
+ else
+ o = int_val_level;
+ /* Scan a factor |f| of type |o| or start a subexpression */
+ /* Get the next non-blank non-call token */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ if (cur_tok == other_token + '(') {
+ /* Push the expression stack and |goto restart| */
+ q = new_node(expr_node, 0);
+ vlink(q) = p;
+ expr_type(q) = (quarterword) l;
+ expr_state(q) = (quarterword) (4 * s + r);
+ expr_e_field(q) = e;
+ expr_t_field(q) = t;
+ expr_n_field(q) = n;
+ p = q;
+ l = o;
+ goto RESTART;
+ }
+ back_input();
+ if ((o == int_val_level) || (o == attr_val_level))
+ scan_int();
+ else if (o == dimen_val_level)
+ scan_normal_dimen();
+ else if (o == glue_val_level)
+ scan_normal_glue();
+ else
+ scan_mu_glue();
+ f = cur_val;
+
+ FOUND:
+ /* Scan the next operator and set |o| */
+ /* Get the next non-blank non-call token */
+ do {
+ get_x_token();
+ } while (cur_cmd == spacer_cmd);
+
+ if (cur_tok == other_token + '+') {
+ o = expr_add;
+ } else if (cur_tok == other_token + '-') {
+ o = expr_sub;
+ } else if (cur_tok == other_token + '*') {
+ o = expr_mult;
+ } else if (cur_tok == other_token + '/') {
+ o = expr_div;
+ } else {
+ o = expr_none;
+ if (p == null) {
+ if (cur_cmd != relax_cmd)
+ back_input();
+ } else if (cur_tok != other_token + ')') {
+ print_err("Missing ) inserted for expression");
+ help1("I was expecting to see `+', `-', `*', `/', or `)'. Didn't.");
+ back_error();
+ }
+ }
+
+ arith_error = b;
+ /* Make sure that |f| is in the proper range */
+ if (((l == int_val_level) || (l == attr_val_level)) || (s > expr_sub)) {
+ if ((f > infinity) || (f < -infinity))
+ num_error(f);
+ } else if (l == dimen_val_level) {
+ if (abs(f) > max_dimen)
+ num_error(f);
+ } else {
+ if ((abs(width(f)) > max_dimen) ||
+ (abs(stretch(f)) > max_dimen) || (abs(shrink(f)) > max_dimen))
+ glue_error(f);
+ }
+
+ switch (s) {
+ /* Cases for evaluation of the current term */
+ case expr_none:
+ /*
+ Applying the factor |f| to the partial term |t| (with the operator
+ |s|) is delayed until the next operator |o| has been scanned. Here we
+ handle the first factor of a partial term. A glue spec has to be copied
+ unless the next operator is a right parenthesis; this allows us later on
+ to simply modify the glue components.
+ */
+ if ((l >= glue_val_level) && (o != expr_none)) {
+ t = new_spec(f);
+ delete_glue_ref(f);
+ normalize_glue(t);
+ } else {
+ t = f;
+ }
+ break;
+ case expr_mult:
+ /* If a multiplication is followed by a division, the two operations are
+ combined into a `scaling' operation. Otherwise the term |t| is
+ multiplied by the factor |f|. */
+ if (o == expr_div) {
+ n = f;
+ o = expr_scale;
+ } else if ((l == int_val_level) || (l == attr_val_level)) {
+ t = mult_integers(t, f);
+ } else if (l == dimen_val_level) {
+ expr_m(t);
+ } else {
+ expr_m(width(t));
+ expr_m(stretch(t));
+ expr_m(shrink(t));
+ }
+ break;
+ case expr_div:
+ /* Here we divide the term |t| by the factor |f| */
+ if (l < glue_val_level) {
+ expr_d(t);
+ } else {
+ expr_d(width(t));
+ expr_d(stretch(t));
+ expr_d(shrink(t));
+ }
+ break;
+ case expr_scale:
+ /* Here the term |t| is multiplied by the quotient $n/f$. */
+ if ((l == int_val_level) || (l == attr_val_level)) {
+ t = fract(t, n, f, infinity);
+ } else if (l == dimen_val_level) {
+ expr_s(t);
+ } else {
+ expr_s(width(t));
+ expr_s(stretch(t));
+ expr_s(shrink(t));
+ }
+ break;
+
+ } /* there are no other cases */
+ if (o > expr_sub) {
+ s = o;
+ } else {
+ /* Evaluate the current expression */
+ /* When a term |t| has been completed it is copied to, added to, or
+ subtracted from the expression |e|. */
+ s = expr_none;
+ if (r == expr_none) {
+ e = t;
+ } else if ((l == int_val_level) || (l == attr_val_level)) {
+ e = expr_add_sub(e, t, infinity);
+ } else if (l == dimen_val_level) {
+ e = expr_a(e, t);
+ } else {
+ /* Compute the sum or difference of two glue specs */
+ /* We know that |stretch_order(e)>normal| implies |stretch(e)<>0| and
+ |shrink_order(e)>normal| implies |shrink(e)<>0|. */
+ width(e) = expr_a(width(e), width(t));
+ if (stretch_order(e) == stretch_order(t)) {
+ stretch(e) = expr_a(stretch(e), stretch(t));
+ } else if ((stretch_order(e) < stretch_order(t))
+ && (stretch(t) != 0)) {
+ stretch(e) = stretch(t);
+ stretch_order(e) = stretch_order(t);
+ }
+ if (shrink_order(e) == shrink_order(t)) {
+ shrink(e) = expr_a(shrink(e), shrink(t));
+ } else if ((shrink_order(e) < shrink_order(t)) && (shrink(t) != 0)) {
+ shrink(e) = shrink(t);
+ shrink_order(e) = shrink_order(t);
+ }
+ delete_glue_ref(t);
+ normalize_glue(e);
+ }
+ r = o;
+ }
+ b = arith_error;
+ if (o != expr_none)
+ goto CONTINUE;
+ if (p != null) {
+ /* Pop the expression stack and |goto found| */
+ f = e;
+ q = p;
+ e = expr_e_field(q);
+ t = expr_t_field(q);
+ n = expr_n_field(q);
+ s = expr_state(q) / 4;
+ r = expr_state(q) % 4;
+ l = expr_type(q);
+ p = vlink(q);
+ flush_node(q);
+ goto FOUND;
+ }
+
+ if (b) {
+ print_err("Arithmetic overflow");
+ help2("I can't evaluate this expression,",
+ "since the result is out of range.");
+ error();
+ if (l >= glue_val_level) {
+ delete_glue_ref(e);
+ e = zero_glue;
+ add_glue_ref(e);
+ } else {
+ e = 0;
+ }
+ }
+ arith_error = a;
+ cur_val = e;
+ cur_val_level = l;
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/stringpool.h b/Build/source/texk/web2c/luatexdir/tex/stringpool.h
new file mode 100644
index 00000000000..51eb4fd7195
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/stringpool.h
@@ -0,0 +1,146 @@
+/* stringpool.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: stringpool.h 3395 2010-01-27 11:40:08Z taco $ */
+
+#ifndef STRINGPOOL_H
+# define STRINGPOOL_H
+
+/* Both lua and tex strings can contains null, but C strings cannot, so: */
+
+typedef struct {
+ unsigned char *s;
+ size_t l;
+} lstring;
+
+typedef struct {
+ const char *s;
+ size_t l;
+} const_lstring;
+
+extern lstring *string_pool;
+
+extern str_number str_ptr;
+extern str_number init_str_ptr;
+
+# define STRING_OFFSET 0x200000
+# define STRING_OFFSET_BITS 21
+
+# define get_nullstr() STRING_OFFSET
+
+# define biggest_char 1114111
+# define number_chars 1114112
+# define special_char 1114113 /* |biggest_char+2| */
+
+/*
+ Several of the elementary string operations are performed using
+ macros instead of procedures, because many of the
+ operations are done quite frequently and we want to avoid the
+ overhead of procedure calls. For example, here is
+ a simple macro that computes the length of a string.
+*/
+
+# define utf8_size(a) (a>0xFFFF ? 4 : (a>0x7FF ? 3 : (a>0x7F? 2 : 1)))
+
+# define str_length(a) string_pool[(a)-STRING_OFFSET].l
+# define str_string(a) string_pool[(a)-STRING_OFFSET].s
+# define str_lstring(a) string_pool[(a)-STRING_OFFSET]
+
+/* Strings are created by appending character codes to |str_pool|.
+ The |append_char| macro, defined here, does not check to see if the
+ value of |pool_ptr| has gotten too high; this test is supposed to be
+ made before |append_char| is used. There is also a |flush_char|
+ macro, which erases the last character appended.
+
+ To test if there is room to append |l| more characters to |str_pool|,
+ we shall write |str_room(l)|, which aborts \TeX\ and gives an
+ apologetic error message if there isn't enough room.
+*/
+
+/* The length of the current string is called |cur_length|: */
+
+extern unsigned char *cur_string;
+extern unsigned cur_length;
+extern unsigned cur_string_size;
+extern unsigned pool_size;
+
+# define EXTRA_STRING 500
+
+/* put |ASCII_code| \# at the end of |str_pool| */
+# define append_char(A) do { \
+ if (cur_string==NULL) reset_cur_string(); \
+ else str_room(1); \
+ cur_string[cur_length++]=(unsigned char)(A); \
+ } while (0)
+
+# define str_room(wsize) do { \
+ unsigned nsize; \
+ if ((cur_length+wsize) > cur_string_size) { \
+ nsize = cur_string_size + cur_string_size / 5 + EXTRA_STRING; \
+ if (nsize < (unsigned)(wsize)) { \
+ nsize = wsize + EXTRA_STRING; \
+ } \
+ cur_string = (unsigned char *) xreallocarray(cur_string, unsigned char, nsize); \
+ memset (cur_string+cur_length,0,nsize-cur_length); \
+ cur_string_size = nsize; \
+ } \
+ } while (0)
+
+# define flush_char() --cur_length /* forget the last character in the pool */
+
+extern str_number make_string(void);
+extern boolean str_eq_buf(str_number s, int k);
+extern boolean str_eq_str(str_number s, str_number t);
+extern boolean str_eq_cstr(str_number, const char *, size_t);
+extern boolean get_strings_started(void);
+extern void reset_cur_string(void);
+
+# define save_cur_string() (cur_length>0 ? make_string() : 0)
+
+# define restore_cur_string(u) if (u!=0) { \
+ unsigned l = (unsigned)str_length(u); \
+ reset_cur_string(); \
+ str_room(l); \
+ memcpy(cur_string, str_string(u),l); \
+ cur_length = l; \
+ flush_str(u); \
+ u=0; \
+ }
+
+
+extern str_number search_string(str_number search);
+extern int pool_to_unichar(unsigned char *t);
+
+extern unsigned char *uni2str(unsigned);
+extern unsigned str2uni(const unsigned char *);
+
+extern str_number maketexstring(const char *);
+extern str_number maketexlstring(const char *, size_t);
+extern void append_string(const unsigned char *s, unsigned l);
+
+extern char *makecstring(int);
+extern char *makeclstring(int, size_t *);
+
+extern int dump_string_pool(void);
+extern int undump_string_pool(void);
+
+extern void init_string_pool_array(unsigned s);
+extern void flush_str(str_number s);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/stringpool.w b/Build/source/texk/web2c/luatexdir/tex/stringpool.w
new file mode 100644
index 00000000000..dbea33554ac
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/stringpool.w
@@ -0,0 +1,492 @@
+% stringpool.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: stringpool.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/stringpool.w $";
+
+@ Control sequence names and diagnostic messages are variable-length strings
+of eight-bit characters. Since PASCAL did not have a well-developed string
+mechanism, \TeX\ did all of its string processing by homegrown methods.
+
+Elaborate facilities for dynamic strings are not needed, so all of the
+necessary operations can be handled with a simple data structure.
+The array |str_pool| contains all of the (eight-bit) bytes off all
+of the strings, and the array |str_start| contains indices of the starting
+points of each string. Strings are referred to by integer numbers, so that
+string number |s| comprises the characters |str_pool[j]| for
+|str_start_macro(s)<=j<str_start_macro(s+1)|. Additional integer variables
+|pool_ptr| and |str_ptr| indicate the number of entries used so far
+in |str_pool| and |str_start|, respectively; locations
+|str_pool[pool_ptr]| and |str_start_macro(str_ptr)| are
+ready for the next string to be allocated.
+
+String numbers 0 to |biggest_char| are reserved for strings that correspond to
+single UNICODE characters. This is in accordance with the conventions of \.{WEB}
+which converts single-character strings into the ASCII code number of the
+single character involved.
+
+@c
+lstring *string_pool; /* the array of strings */
+lstring *_string_pool; /* this variable lives |STRING_OFFSET| below |string_pool|
+ (handy for debugging:
+ |_string_pool[str_ptr] == str_string(str_ptr)| */
+
+str_number str_ptr = (STRING_OFFSET + 1); /* number of the current string being created */
+str_number init_str_ptr; /* the starting value of |str_ptr| */
+
+unsigned char *cur_string; /* current string buffer */
+unsigned cur_length; /* current index in that buffer */
+unsigned cur_string_size; /* malloced size of |cur_string| */
+unsigned pool_size; /* occupied byte count */
+
+
+@ Once a sequence of characters has been appended to |cur_string|, it
+officially becomes a string when the function |make_string| is called.
+This function returns the identification number of the new string as its
+value.
+
+@c
+void reset_cur_string(void)
+{
+ cur_length = 0;
+ cur_string_size = 255;
+ cur_string = (unsigned char *) xmalloc(256);
+ memset(cur_string, 0, 256);
+}
+
+@ current string enters the pool
+@c
+str_number make_string(void)
+{
+ if (str_ptr == (max_strings + STRING_OFFSET))
+ overflow("number of strings",
+ (unsigned) (max_strings - init_str_ptr + STRING_OFFSET));
+ str_room(1);
+ cur_string[cur_length] = '\0'; /* now |lstring.s| is always a valid C string */
+ str_string(str_ptr) = (unsigned char *) cur_string;
+ str_length(str_ptr) = cur_length;
+ pool_size += cur_length;
+ reset_cur_string();
+#if 0
+ printf("Made a string: %s (s=%d)\n", (char *)str_string(str_ptr), (int)str_ptr);
+#endif
+ str_ptr++;
+ return (str_ptr - 1);
+}
+
+@ @c
+static void utf_error(void)
+{
+ const char *hlp[] =
+ { "A funny symbol that I can't read has just been (re)read.",
+ "Just continue, I'll change it to 0xFFFD.",
+ NULL
+ };
+ deletions_allowed = false;
+ tex_error("String contains an invalid utf-8 sequence", hlp);
+ deletions_allowed = true;
+}
+
+@ @c
+unsigned str2uni(const unsigned char *k)
+{
+ register int ch;
+ unsigned val = 0xFFFD;
+ const unsigned char *text = k;
+ if ((ch = *text++) < 0x80) {
+ val = (unsigned) ch;
+ } else if (ch <= 0xbf) { /* error */
+ } else if (ch <= 0xdf) {
+ if (*text >= 0x80 && *text < 0xc0)
+ val = (unsigned) (((ch & 0x1f) << 6) | (*text++ & 0x3f));
+ } else if (ch <= 0xef) {
+ if (*text >= 0x80 && *text < 0xc0 && text[1] >= 0x80 && text[1] < 0xc0) {
+ val = (unsigned)
+ (((ch & 0xf) << 12) | ((text[0] & 0x3f) << 6) |
+ (text[1] & 0x3f));
+ }
+ } else {
+ int w = (((ch & 0x7) << 2) | ((text[0] & 0x30) >> 4)) - 1, w2;
+ w = (w << 6) | ((text[0] & 0xf) << 2) | ((text[1] & 0x30) >> 4);
+ w2 = ((text[1] & 0xf) << 6) | (text[2] & 0x3f);
+ val = (unsigned) (w * 0x400 + w2 + 0x10000);
+ if (*text < 0x80 || text[1] < 0x80 || text[2] < 0x80 ||
+ *text >= 0xc0 || text[1] >= 0xc0 || text[2] >= 0xc0)
+ val = 0xFFFD;
+ }
+ if (val == 0xFFFD)
+ utf_error();
+ return (val);
+}
+
+@ This is a very basic helper
+@c
+unsigned char *uni2str(unsigned unic)
+{
+ unsigned char *buf = xmalloc(5);
+ unsigned char *pt = buf;
+ if (unic < 0x80)
+ *pt++ = (unsigned char) unic;
+ else if (unic < 0x800) {
+ *pt++ = (unsigned char) (0xc0 | (unic >> 6));
+ *pt++ = (unsigned char) (0x80 | (unic & 0x3f));
+ } else if (unic >= 0x110000) {
+ *pt++ = (unsigned char) (unic - 0x110000);
+ } else if (unic < 0x10000) {
+ *pt++ = (unsigned char) (0xe0 | (unic >> 12));
+ *pt++ = (unsigned char) (0x80 | ((unic >> 6) & 0x3f));
+ *pt++ = (unsigned char) (0x80 | (unic & 0x3f));
+ } else {
+ int u, z, y, x;
+ unsigned val = unic - 0x10000;
+ u = (int) (((val & 0xf0000) >> 16) + 1);
+ z = (int) ((val & 0x0f000) >> 12);
+ y = (int) ((val & 0x00fc0) >> 6);
+ x = (int) (val & 0x0003f);
+ *pt++ = (unsigned char) (0xf0 | (u >> 2));
+ *pt++ = (unsigned char) (0x80 | ((u & 3) << 4) | z);
+ *pt++ = (unsigned char) (0x80 | y);
+ *pt++ = (unsigned char) (0x80 | x);
+ }
+ *pt = '\0';
+ return buf;
+}
+
+
+@ |buffer_to_unichar| converts a sequence of bytes in the |buffer|
+into a unicode character value. It does not check for overflow
+of the |buffer|, but it is careful to check the validity of the
+UTF-8 encoding.
+
+@c
+#define test_sequence_byte(A) do { \
+ if (((A)<0x80) || ((A)>=0xC0)) { \
+ utf_error(); \
+ return 0xFFFD; \
+ } \
+ } while (0)
+
+
+static int buffer_to_unichar(int k)
+{
+ int a; /* a utf char */
+ int b; /* a utf nibble */
+ b = buffer[k];
+ if (b < 0x80) {
+ a = b;
+ } else if (b >= 0xF8) {
+ /* the 5- and 6-byte UTF-8 sequences generate integers
+ that are outside of the valid UCS range, and therefore
+ unsupported
+ */
+ test_sequence_byte(-1);
+ } else if (b >= 0xF0) {
+ a = (b - 0xF0) * 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);
+ } else if (b >= 0xE0) {
+ a = (b - 0xE0) * 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);
+ } else if (b >= 0xC0) {
+ a = (b - 0xC0) * 64;
+ b = buffer[k + 1];
+ test_sequence_byte(b);
+ a = a + (b - 128);
+ } else {
+ /* This is an encoding error */
+ test_sequence_byte(-1);
+ }
+ return a;
+}
+
+@ @c
+int pool_to_unichar(unsigned char *t)
+{
+ return (int) str2uni(t);
+}
+
+
+
+@ The following subroutine compares string |s| with another string of the
+same length that appears in |buffer| starting at position |k|;
+the result is |true| if and only if the strings are equal.
+Empirical tests indicate that |str_eq_buf| is used in such a way that
+it tends to return |true| about 80 percent of the time.
+
+@c
+boolean str_eq_buf(str_number s, int k)
+{ /* test equality of strings */
+ int a; /* a unicode character */
+ if (s < STRING_OFFSET) {
+ a = buffer_to_unichar(k);
+ if (a != s)
+ return false;
+ } else {
+ unsigned char *j = str_string(s);
+ unsigned char *l = j + str_length(s);
+ while (j < l) {
+ if (*j++ != buffer[k++])
+ return false;
+ }
+ }
+ return true;
+}
+
+
+@ Here is a similar routine, but it compares two strings in the string pool,
+and it does not assume that they have the same length.
+
+@c
+boolean str_eq_str(str_number s, str_number t)
+{ /* test equality of strings */
+ int a = 0; /* a utf char */
+ unsigned char *j, *k, *l; /* running indices */
+ if (s < STRING_OFFSET) {
+ if (t >= STRING_OFFSET) {
+ k = str_string(t);
+ if (s <= 0x7F && (str_length(t) == 1) && *k == s)
+ return true;
+ a = pool_to_unichar(k);
+ if (a != s)
+ return false;
+ } else {
+ if (t != s)
+ return false;
+ }
+ } else if (t < STRING_OFFSET) {
+ j = str_string(s);
+ if (t <= 0x7F && (str_length(s) == 1) && *j == t)
+ return true;
+ a = pool_to_unichar(j);
+ if (a != t)
+ return false;
+ } else {
+ if (str_length(s) != str_length(t))
+ return false;
+ k = str_string(t);
+ j = str_string(s);
+ l = j + str_length(s);
+ while (j < l) {
+ if (*j++ != *k++)
+ return false;
+ }
+ }
+ return true;
+}
+
+@ string compare
+@c
+boolean str_eq_cstr(str_number r, const char *s, size_t l)
+{
+ if (l != (size_t) str_length(r))
+ return false;
+ return (strncmp((const char *) (str_string(r)), s, l) == 0);
+}
+
+
+@ The initial values of |str_pool|, |str_start|, |pool_ptr|,
+and |str_ptr| are computed by the \.{INITEX} program, based in part
+on the information that \.{WEB} has output while processing \TeX.
+
+The first |string_offset| strings are single-characters strings matching
+Unicode. There is no point in generating all of these. But |str_ptr| has
+initialized properly, otherwise |print_char| cannot see the difference
+between characters and strings.
+
+
+@ initializes the string pool, but returns |false| if something goes wrong
+@c
+boolean get_strings_started(void)
+{
+ reset_cur_string();
+ return true;
+}
+
+@ The string recycling routines. \TeX{} uses 2
+ upto 4 {\it new\/} strings when scanning a filename in an \.{\\input},
+ \.{\\openin}, or \.{\\openout} operation. These strings are normally
+ lost because the reference to them are not saved after finishing the
+ operation. |search_string| searches through the string pool for the
+ given string and returns either 0 or the found string number.
+
+@c
+str_number search_string(str_number search)
+{
+ str_number s; /* running index */
+ size_t len; /* length of searched string */
+ len = str_length(search);
+ if (len == 0) {
+ return get_nullstr();
+ } else {
+ s = search - 1; /* start search with newest string below |s|; |search>1|! */
+ while (s >= STRING_OFFSET) {
+ /* first |string_offset| strings depend on implementation!! */
+ if (str_length(s) == len)
+ if (str_eq_str(s, search))
+ return s;
+ s--;
+ }
+ }
+ return 0;
+}
+
+@ @c
+str_number maketexstring(const char *s)
+{
+ if (s == NULL || *s == 0)
+ return get_nullstr();
+ return maketexlstring(s, strlen(s));
+}
+
+@ @c
+str_number maketexlstring(const char *s, size_t l)
+{
+ if (s == NULL || l == 0)
+ return get_nullstr();
+ str_string(str_ptr) = xmalloc((unsigned) (l + 1));
+ memcpy(str_string(str_ptr), s, (l + 1));
+ str_length(str_ptr) = (unsigned) l;
+ str_ptr++;
+ return (str_ptr - 1);
+}
+
+@ append a C string to a TeX string
+@c
+void append_string(const unsigned char *s, unsigned l)
+{
+ if (s == NULL || *s == 0)
+ return;
+ l = (unsigned) strlen((const char *) s);
+ str_room(l);
+ memcpy(cur_string + cur_length, s, l);
+ cur_length += l;
+ return;
+}
+
+@ @c
+char *makecstring(int s)
+{
+ size_t l;
+ return makeclstring(s, &l);
+}
+
+@ @c
+char *makeclstring(int s, size_t * len)
+{
+ if (s < STRING_OFFSET) {
+ *len = (size_t) utf8_size(s);
+ return (char *) uni2str((unsigned) s);
+ } else {
+ unsigned l = (unsigned) str_length(s);
+ char *cstrbuf = xmalloc(l + 1);
+ memcpy(cstrbuf, str_string(s), l);
+ cstrbuf[l] = '\0';
+ *len = (size_t) l;
+ return cstrbuf;
+ }
+}
+
+@ @c
+int dump_string_pool(void)
+{
+ int j;
+ int l;
+ int k = str_ptr;
+ dump_int(k - STRING_OFFSET);
+ for (j = STRING_OFFSET + 1; j < k; j++) {
+ l = (int) str_length(j);
+ if (str_string(j) == NULL)
+ l = -1;
+ dump_int(l);
+ if (l > 0)
+ dump_things(*str_string(j), str_length(j));
+ }
+ return (k - STRING_OFFSET);
+}
+
+@ @c
+int undump_string_pool(void)
+{
+ int j;
+ int x;
+ undump_int(str_ptr);
+ if (max_strings < str_ptr + strings_free)
+ max_strings = str_ptr + strings_free;
+ str_ptr += STRING_OFFSET;
+ if (ini_version)
+ libcfree(string_pool);
+ init_string_pool_array((unsigned) max_strings);
+ for (j = STRING_OFFSET + 1; j < str_ptr; j++) {
+ undump_int(x);
+ if (x >= 0) {
+ str_length(j) = (unsigned) x;
+ pool_size += (unsigned) x;
+ str_string(j) = xmallocarray(unsigned char, (unsigned) (x + 1));
+ undump_things(*str_string(j), (unsigned) x);
+ *(str_string(j) + str_length(j)) = '\0';
+ } else {
+ str_length(j) = 0;
+ }
+ }
+ init_str_ptr = str_ptr;
+ return str_ptr;
+}
+
+@ @c
+void init_string_pool_array(unsigned s)
+{
+ string_pool = xmallocarray(lstring, s);
+ _string_pool = string_pool - STRING_OFFSET;
+ memset(string_pool, 0, s * sizeof(lstring));
+ /* seed the null string */
+ string_pool[0].s = xmalloc(1);
+ string_pool[0].s[0] = '\0';
+}
+
+@ To destroy an already made string, we say |flush_str|.
+@c
+void flush_str(str_number s)
+{
+#if 0
+ printf("Flushing a string: %s (s=%d,str_ptr=%d)\n", (char *)str_string(s), (int)s, (int)str_ptr);
+#endif
+ if (s > STRING_OFFSET) { /* don't ever delete the null string */
+ pool_size -= (unsigned) str_length(s);
+ str_length(s) = 0;
+ xfree(str_string(s));
+ }
+ while (str_string((str_ptr - 1)) == NULL)
+ str_ptr--;
+}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texdeffont.h b/Build/source/texk/web2c/luatexdir/tex/texdeffont.h
new file mode 100644
index 00000000000..e2ce6f91cc0
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/texdeffont.h
@@ -0,0 +1,31 @@
+/* texdeffont.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: texdeffont.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef TEXDEFFONT_H
+# define TEXDEFFONT_H
+
+extern int font_bytes;
+
+extern void set_cur_font(internal_font_number f);
+
+extern void tex_def_font(small_number a);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c b/Build/source/texk/web2c/luatexdir/tex/texdeffont.w
index 016f12ab200..ecb4f9fe29f 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c
+++ b/Build/source/texk/web2c/luatexdir/tex/texdeffont.w
@@ -1,37 +1,46 @@
-/* texdeffont.c
+% texdeffont.w
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 2008-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-
-#include "tokens.h"
-#include "nodes.h"
-#include "commands.h"
+@ @c
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: texdeffont.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/texdeffont.c $";
+ "$Id: texdeffont.w 3587 2010-04-03 14:32:25Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/texdeffont.w $";
+
+
+
+@ When the user defines \.{\\font\\f}, say, \TeX\ assigns an internal number
+to the user's font~\.{\\f}. Adding this number to |font_id_base| gives the
+|eqtb| location of a ``frozen'' control sequence that will always select
+the font.
-#define text(a) hash[(a)].rh /* string number for control sequence name */
-#define null_cs 1 /* equivalent of \.{\\csname\\endcsname} */
-#define scan_normal_dimen() scan_dimen(false,false,false)
+@c
+int font_bytes;
-static char *scaled_to_string(scaled s)
+void set_cur_font(internal_font_number f)
+{
+ int a = 0; /* never global */
+ define(cur_font_loc, data_cmd, f);
+}
+
+@ @c
+char *scaled_to_string(scaled s)
{ /* prints scaled real, rounded to five digits */
static char result[16];
int n, k;
@@ -47,11 +56,11 @@ static char *scaled_to_string(scaled s)
n = s / unity;
/* process the integer part */
do {
- dig[l++] = n % 10;
+ dig[l++] = (char) (n % 10);
n = n / 10;;
} while (n > 0);
while (l > 0) {
- result[k++] = (dig[--l] + '0');
+ result[k++] = (char) (dig[--l] + '0');
}
}
result[k++] = '.';
@@ -60,7 +69,7 @@ static char *scaled_to_string(scaled s)
do {
if (delta > unity)
s = s + 0100000 - 050000; /* round the last digit */
- result[k++] = '0' + (s / unity);
+ result[k++] = (char) ('0' + (s / unity));
s = 10 * (s % unity);
delta = delta * 10;
} while (s > delta);
@@ -69,21 +78,23 @@ static char *scaled_to_string(scaled s)
return (char *) result;
}
+@ @c
void tex_def_font(small_number a)
{
pointer u; /* user's font identifier */
internal_font_number f; /* runs through existing fonts */
str_number t; /* name for the frozen font identifier */
int old_setting; /* holds |selector| setting */
- integer offset = 0;
+ int offset = 0;
scaled s = -1000; /* stated ``at'' size, or negative of scaled magnification */
- integer natural_dir = -1; /* the natural direction of the font */
+ int natural_dir = -1; /* the natural direction of the font */
+ char *fn;
if (job_name == 0)
open_log_file(); /* avoid confusing \.{texput} with the font name */
get_r_token();
u = cur_cs;
if (u >= null_cs)
- t = text(u);
+ t = cs_text(u);
else
t = maketexstring("FONT");
if (a >= 4) {
@@ -92,7 +103,7 @@ void tex_def_font(small_number a)
eq_define(u, set_font_cmd, null_font);
}
scan_optional_equals();
- /* @<Get the next non-blank non-call token@>; */
+ /* Get the next non-blank non-call token; */
do {
get_x_token();
} while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
@@ -127,15 +138,15 @@ void tex_def_font(small_number a)
token_show(def_ref);
selector = old_setting;
flush_list(def_ref);
- /* str_room(1); *//* what did that do ? */
+ /* |str_room(1)|; *//* what did that do ? */
cur_name = make_string();
cur_ext = get_nullstr();
cur_area = get_nullstr();
}
- /* @<Scan the font size specification@>; */
+ /* Scan the font size specification; */
name_in_progress = true; /* this keeps |cur_name| from being changed */
if (scan_keyword("at")) {
- /* @<Put the \(p)(positive) `at' size into |s|@> */
+ /* Put the positive `at' size into |s| */
scan_normal_dimen();
s = cur_val;
if ((s <= 0) || (s >= 01000000000)) {
@@ -171,7 +182,8 @@ void tex_def_font(small_number a)
offset = cur_val;
if (cur_val < 0) {
char err[256];
- const char *errhelp[] = { "The offset must be bigger than 0.", NULL };
+ const char *errhelp[] =
+ { "The offset must be bigger than 0.", NULL };
snprintf(err, 255, "Illegal offset has been changed to 0 (%d)",
(int) cur_val);
tex_error(err, errhelp);
@@ -183,8 +195,10 @@ void tex_def_font(small_number a)
natural_dir = cur_val;
}
name_in_progress = false;
- f = read_font_info(u, cur_name, s, natural_dir);
+ fn = makecstring(cur_name);
+ f = read_font_info(u, fn, s, natural_dir);
+ xfree(fn);
equiv(u) = f;
- zeqtb[get_font_id_base() + f] = zeqtb[u];
- text(get_font_id_base() + f) = t;
+ eqtb[font_id_base + f] = eqtb[u];
+ cs_text(font_id_base + f) = t;
}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.h b/Build/source/texk/web2c/luatexdir/tex/texfileio.h
new file mode 100644
index 00000000000..77b7a6dd5b5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/texfileio.h
@@ -0,0 +1,144 @@
+/* texfileio.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: texfileio.h 3395 2010-01-27 11:40:08Z taco $ */
+
+#ifndef TEXFILEIO_H
+# define TEXFILEIO_H
+
+extern int *input_file_callback_id;
+extern int read_file_callback_id[17];
+
+extern char *luatex_find_file(const char *s, int callback_index);
+extern char *luatex_find_read_file(const char *s, int n, int callback_index);
+extern boolean luatex_open_input(FILE ** f_ptr, const char *fn, int filefmt,
+ const_string fopen_mode, boolean must_exist);
+extern boolean luatex_open_output(FILE ** f_ptr, const char *fn,
+ const_string fopen_mode);
+
+extern boolean lua_a_open_in(alpha_file * f, char *fn, int n);
+extern boolean lua_a_open_out(alpha_file * f, char *fn, int n);
+extern boolean lua_b_open_out(alpha_file * f, char *fn);
+extern void lua_a_close_in(alpha_file f, int n);
+extern void lua_a_close_out(alpha_file f);
+
+extern packed_ASCII_code *buffer;
+extern int first;
+extern int last;
+extern int max_buf_stack;
+
+extern boolean lua_input_ln(alpha_file f, int n, boolean bypass_eoln);
+
+/*
+The user's terminal acts essentially like other files of text, except
+that it is used both for input and for output. When the terminal is
+considered an input file, the file variable is called |term_in|, and when it
+is considered an output file the file variable is |term_out|.
+@^system dependencies@>
+*/
+
+# define term_in stdin /* the terminal as an input file */
+# define term_out stdout /* the terminal as an output file */
+
+
+/*
+Here is how to open the terminal files. |t_open_out| does nothing.
+|t_open_in|, on the other hand, does the work of ``rescanning,'' or getting
+any command line arguments the user has provided. It's defined in C.
+*/
+
+# define t_open_out() /* output already open for text output */
+
+/*
+Sometimes it is necessary to synchronize the input/output mixture that
+happens on the user's terminal, and three system-dependent
+procedures are used for this
+purpose. The first of these, |update_terminal|, is called when we want
+to make sure that everything we have output to the terminal so far has
+actually left the computer's internal buffers and been sent.
+The second, |clear_terminal|, is called when we wish to cancel any
+input that the user may have typed ahead (since we are about to
+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 with {\mc UNIX}. |update_terminal|
+does an |fflush|. |clear_terminal| is redefined
+to do nothing, since the user should control the terminal.
+@^system dependencies@>
+*/
+
+# define update_terminal() fflush (term_out)
+# define clear_terminal() do { ; } while (0)
+# define wake_up_terminal() do { ; } while (0) /* cancel the user's cancellation of output */
+
+extern boolean init_terminal(void);
+extern void term_input(void);
+
+extern str_number cur_name;
+extern str_number cur_area;
+extern str_number cur_ext;
+extern pool_pointer area_delimiter;
+extern pool_pointer ext_delimiter;
+
+extern char *pack_file_name(str_number n, str_number a, str_number e);
+
+# define file_name_size 512
+
+# define format_area_length 0 /* length of its area part */
+# define format_ext_length 4 /* length of its `\.{.fmt}' part */
+# define format_extension ".fmt"
+ /* the extension, as a constant */
+
+extern char *TEX_format_default;
+
+extern char *open_fmt_file(void);
+
+extern boolean name_in_progress; /* is a file name being scanned? */
+extern str_number job_name; /* principal file name */
+extern boolean log_opened; /* has the transcript file been opened? */
+
+extern unsigned char *texmf_log_name; /* full name of the log file */
+
+extern void open_log_file(void);
+extern void start_input(void);
+
+extern int open_outfile(FILE ** f, const char *name, const char *mode);
+
+extern boolean zopen_w_input(FILE **, const char *, int,
+ const_string fopen_mode);
+extern boolean zopen_w_output(FILE **, const char *, const_string fopen_mode);
+extern void zwclose(FILE *);
+
+extern int readbinfile(FILE * f, unsigned char **b, int *s);
+
+# define read_tfm_file readbinfile
+# define read_vf_file readbinfile
+# define read_ocp_file readbinfile
+# define read_data_file readbinfile
+
+extern boolean openinnameok(const_string);
+extern boolean openoutnameok(const_string);
+
+extern boolean open_in_or_pipe(FILE **, char *, int, const_string fopen_mode,
+ boolean must_exist);
+extern boolean open_out_or_pipe(FILE **, char *, const_string fopen_mode);
+extern void close_file_or_pipe(FILE *);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.w b/Build/source/texk/web2c/luatexdir/tex/texfileio.w
new file mode 100644
index 00000000000..c577dbad17a
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/texfileio.w
@@ -0,0 +1,1368 @@
+% texfileio.w
+%
+% Copyright 2009-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+#include <string.h>
+#include "ptexlib.h"
+#include <kpathsea/absolute.h>
+
+static const char _svn_version[] =
+ "$Id: texfileio.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/texfileio.w $";
+
+@ @c
+#define end_line_char int_par(end_line_char_code)
+
+@ The bane of portability is the fact that different operating systems treat
+input and output quite differently, perhaps because computer scientists
+have not given sufficient attention to this problem. People have felt somehow
+that input and output are not part of ``real'' programming. Well, it is true
+that some kinds of programming are more fun than others. With existing
+input/output conventions being so diverse and so messy, the only sources of
+joy in such parts of the code are the rare occasions when one can find a
+way to make the program a little less bad than it might have been. We have
+two choices, either to attack I/O now and get it over with, or to postpone
+I/O until near the end. Neither prospect is very attractive, so let's
+get it over with.
+
+The basic operations we need to do are (1)~inputting and outputting of
+text, to or from a file or the user's terminal; (2)~inputting and
+outputting of eight-bit bytes, to or from a file; (3)~instructing the
+operating system to initiate (``open'') or to terminate (``close'') input or
+output from a specified file; (4)~testing whether the end of an input
+file has been reached.
+
+\TeX\ needs to deal with two kinds of files.
+We shall use the term |alpha_file| for a file that contains textual data,
+and the term |byte_file| for a file that contains eight-bit binary information.
+These two types turn out to be the same on many computers, but
+sometimes there is a significant distinction, so we shall be careful to
+distinguish between them. Standard protocols for transferring
+such files from computer to computer, via high-speed networks, are
+now becoming available to more and more communities of users.
+
+The program actually makes use also of a third kind of file, called a
+|word_file|, when dumping and reloading base information for its own
+initialization. We shall define a word file later; but it will be possible
+for us to specify simple operations on word files before they are defined.
+
+@ We finally did away with |nameoffile| and |namelength|, but the variables
+have to be kept otherwise there will be link errors from |openclose.c| in
+the web2c library
+
+@c
+char *nameoffile;
+int namelength;
+
+
+@ When input files are opened via a callback, they will also be read using
+callbacks. for that purpose, the |open_read_file_callback| returns an
+integer to uniquely identify a callback table. This id replaces the file
+point |f| in this case, because the input does not have to be a file
+in the traditional sense.
+
+Signalling this fact is achieved by having two arrays of integers.
+
+@c
+int *input_file_callback_id;
+int read_file_callback_id[17];
+
+@ Handle -output-directory.
+
+We assume that it is OK to look here first. Possibly it
+would be better to replace lookups in "." with lookups in the
+|output_directory| followed by "." but to do this requires much more
+invasive surgery in libkpathsea.
+
+@c
+static char *find_in_output_directory(const char *s)
+{
+ if (output_directory && !kpse_absolute_p(s, false)) {
+ FILE *f_ptr;
+ char *ftemp = concat3(output_directory, DIR_SEP_STRING, s);
+ f_ptr = fopen(ftemp, "rb"); /* this code is used for input files only */
+ if (f_ptr) {
+ fclose(f_ptr);
+ return ftemp;
+ } else {
+ free(ftemp);
+
+ }
+ }
+ return NULL;
+}
+
+@ find an \.{\\input} or \.{\\read} file. |n| differentiates between those case.
+
+@c
+char *luatex_find_read_file(const char *s, int n, int callback_index)
+{
+ char *ftemp = NULL;
+ int callback_id = callback_defined(callback_index);
+ if (callback_id > 0) {
+ (void) run_callback(callback_id, "dS->S", n, s, &ftemp);
+ } else {
+ /* use kpathsea here */
+ ftemp = find_in_output_directory(s);
+ if (!ftemp)
+ ftemp = kpse_find_file(s, kpse_tex_format, 1);
+ }
+ if (ftemp) {
+ if (fullnameoffile)
+ free(fullnameoffile);
+ fullnameoffile = xstrdup(ftemp);
+ }
+ return ftemp;
+}
+
+@ find other files types
+@c
+char *luatex_find_file(const char *s, int callback_index)
+{
+ char *ftemp = NULL;
+ int callback_id = callback_defined(callback_index);
+ if (callback_id > 0) {
+ (void) run_callback(callback_id, "S->S", s, &ftemp);
+
+ } else {
+ /* use kpathsea here */
+ switch (callback_index) {
+ case find_enc_file_callback:
+ ftemp = kpse_find_file(s, kpse_enc_format, 0);
+ break;
+ case find_sfd_file_callback:
+ ftemp = kpse_find_file(s, kpse_sfd_format, 0);
+ break;
+ case find_map_file_callback:
+ ftemp = kpse_find_file(s, kpse_fontmap_format, 0);
+ break;
+ case find_type1_file_callback:
+ ftemp = kpse_find_file(s, kpse_type1_format, 0);
+ break;
+ case find_truetype_file_callback:
+ ftemp = kpse_find_file(s, kpse_truetype_format, 0);
+ break;
+ case find_opentype_file_callback:
+ ftemp = kpse_find_file(s, kpse_opentype_format, 0);
+ if (ftemp == NULL)
+ ftemp = kpse_find_file(s, kpse_truetype_format, 0);
+ break;
+ case find_ocp_file_callback:
+ ftemp = kpse_find_file(s, kpse_ocp_format, 0);
+ break;
+ case find_data_file_callback:
+ ftemp = find_in_output_directory(s);
+ if (!ftemp)
+ ftemp = kpse_find_file(s, kpse_tex_format, 0);
+ break;
+ case find_font_file_callback:
+ ftemp = kpse_find_file(s, kpse_ofm_format, 0);
+ if (ftemp == NULL)
+ ftemp = kpse_find_file(s, kpse_tfm_format, 0);
+ break;
+ case find_vf_file_callback:
+ ftemp = kpse_find_file(s, kpse_ovf_format, 0);
+ if (ftemp == NULL)
+ ftemp = kpse_find_file(s, kpse_vf_format, 0);
+ break;
+ default:
+ printf
+ ("luatex_find_file(): do not know how to handle file %s of type %d\n",
+ s, callback_index);
+ break;
+ }
+ }
+ return ftemp;
+}
+
+
+@ Open an input file F, using the kpathsea format FILEFMT and passing
+ |FOPEN_MODE| to fopen. The filename is in `fn'. We return whether or
+ not the open succeeded.
+
+@c
+boolean
+luatex_open_input(FILE ** f_ptr, const char *fn, int filefmt,
+ const_string fopen_mode, boolean must_exist)
+{
+ string fname = NULL;
+ /* We havent found anything yet. */
+ *f_ptr = NULL;
+ if (fullnameoffile)
+ free(fullnameoffile);
+ fullnameoffile = NULL;
+ fname = kpse_find_file(fn, (kpse_file_format_type) filefmt, must_exist);
+ if (fname) {
+ fullnameoffile = xstrdup(fname);
+ /* If we found the file in the current directory, don't leave
+ the `./' at the beginning of `fn', since it looks
+ dumb when `tex foo' says `(./foo.tex ... )'. On the other
+ hand, if the user said `tex ./foo', and that's what we
+ opened, then keep it -- the user specified it, so we
+ shouldn't remove it. */
+ if (fname[0] == '.' && IS_DIR_SEP(fname[1])
+ && (fn[0] != '.' || !IS_DIR_SEP(fn[1]))) {
+ unsigned i = 0;
+ while (fname[i + 2] != 0) {
+ fname[i] = fname[i + 2];
+ i++;
+ }
+ fname[i] = 0;
+ }
+ /* This fopen is not allowed to fail. */
+ *f_ptr = xfopen(fname, fopen_mode);
+ }
+ if (*f_ptr) {
+ recorder_record_input(fname);
+ }
+ return *f_ptr != NULL;
+}
+
+@ @c
+boolean luatex_open_output(FILE ** f_ptr, const char *fn,
+ const_string fopen_mode)
+{
+ char *fname;
+ boolean absolute = kpse_absolute_p(fn, false);
+
+ /* If we have an explicit output directory, use it. */
+ if (output_directory && !absolute) {
+ fname = concat3(output_directory, DIR_SEP_STRING, fn);
+ } else {
+ fname = xstrdup(fn);
+ }
+
+ /* Is the filename openable as given? */
+ *f_ptr = fopen(fname, fopen_mode);
+
+ if (!*f_ptr) {
+ /* Can't open as given. Try the envvar. */
+ string texmfoutput = kpse_var_value("TEXMFOUTPUT");
+
+ if (texmfoutput && *texmfoutput && !absolute) {
+ fname = concat3(texmfoutput, DIR_SEP_STRING, fn);
+ *f_ptr = fopen(fname, fopen_mode);
+ }
+ }
+ if (*f_ptr) {
+ recorder_record_output(fname);
+ }
+ free(fname);
+ return *f_ptr != NULL;
+}
+
+
+@ @c
+boolean lua_a_open_in(alpha_file * f, char *fn, int n)
+{
+ int k;
+ char *fnam; /* string returned by find callback */
+ int callback_id;
+ boolean ret = true; /* return value */
+ boolean file_ok = true; /* the status so far */
+ if (n == 0) {
+ input_file_callback_id[iindex] = 0;
+ } else {
+ read_file_callback_id[n] = 0;
+ }
+ fnam = luatex_find_read_file(fn, n, find_read_file_callback);
+ if (!fnam)
+ return false;
+ callback_id = callback_defined(open_read_file_callback);
+ if (callback_id > 0) {
+ k = run_and_save_callback(callback_id, "S->", fnam);
+ if (k > 0) {
+ ret = true;
+ if (n == 0)
+ input_file_callback_id[iindex] = k;
+ else
+ read_file_callback_id[n] = k;
+ } else {
+ file_ok = false; /* read failed */
+ }
+ } else { /* no read callback */
+ if (openinnameok(fnam)) {
+ ret =
+ open_in_or_pipe(f, fnam, kpse_tex_format, FOPEN_RBIN_MODE,
+ (n == 0 ? true : false));
+ } else {
+ file_ok = false; /* open failed */
+ }
+ }
+ if (!file_ok) {
+ ret = false;
+ }
+ return ret;
+}
+
+@ @c
+boolean lua_a_open_out(alpha_file * f, char *fn, int n)
+{
+ boolean test;
+ str_number fnam;
+ int callback_id;
+ boolean ret = false;
+ callback_id = callback_defined(find_write_file_callback);
+ if (callback_id > 0) {
+ fnam = 0;
+ test = run_callback(callback_id, "dS->s", n, fn, &fnam);
+ if ((test) && (fnam != 0) && (str_length(fnam) > 0)) {
+ ret = open_outfile(f, fn, FOPEN_W_MODE);
+ }
+ } else {
+ if (openoutnameok(fn)) {
+ ret = open_out_or_pipe(f, fn, FOPEN_W_MODE);
+ }
+ }
+ return ret;
+}
+
+@ @c
+boolean lua_b_open_out(alpha_file * f, char *fn)
+{
+ boolean test;
+ str_number fnam;
+ int callback_id;
+ boolean ret = false;
+ callback_id = callback_defined(find_output_file_callback);
+ if (callback_id > 0) {
+ fnam = 0;
+ test = run_callback(callback_id, "S->s", fn, &fnam);
+ if ((test) && (fnam != 0) && (str_length(fnam) > 0)) {
+ ret = open_outfile(f, fn, FOPEN_WBIN_MODE);
+ }
+ } else {
+ if (openoutnameok(fn)) {
+ ret = luatex_open_output(f, fn, FOPEN_WBIN_MODE);
+ }
+ }
+ return ret;
+}
+
+@ @c
+void lua_a_close_in(alpha_file f, int n)
+{ /* close a text file */
+ boolean ret;
+ int callback_id;
+ if (n == 0)
+ callback_id = input_file_callback_id[iindex];
+ else
+ callback_id = read_file_callback_id[n];
+ if (callback_id > 0) {
+ ret = run_saved_callback(callback_id, "close", "->");
+ destroy_saved_callback(callback_id);
+ if (n == 0)
+ input_file_callback_id[iindex] = 0;
+ else
+ read_file_callback_id[n] = 0;
+ } else {
+ close_file_or_pipe(f);
+ }
+}
+
+@ @c
+void lua_a_close_out(alpha_file f)
+{ /* close a text file */
+ close_file_or_pipe(f);
+}
+
+
+@ Binary input and output are done with C's ordinary
+procedures, so we don't have to make any other special arrangements for
+binary~I/O. Text output is also easy to do with standard routines.
+The treatment of text input is more difficult, however, because
+of the necessary translation to |ASCII_code| values.
+\TeX's conventions should be efficient, and they should
+blend nicely with the user's operating environment.
+
+Input from text files is read one line at a time, using a routine called
+|lua_input_ln|. This function is defined in terms of global variables called
+|buffer|, |first|, and |last| that will be described in detail later; for
+now, it suffices for us to know that |buffer| is an array of |ASCII_code|
+values, and that |first| and |last| are indices into this array
+representing the beginning and ending of a line of text.
+
+@c
+packed_ASCII_code *buffer; /* lines of characters being read */
+int first; /* the first unused position in |buffer| */
+int last; /* end of the line just input to |buffer| */
+int max_buf_stack; /* largest index used in |buffer| */
+
+
+@ The |lua_input_ln| function brings the next line of input from the specified
+file into available positions of the buffer array and returns the value
+|true|, unless the file has already been entirely read, in which case it
+returns |false| and sets |last:=first|. In general, the |ASCII_code|
+numbers that represent the next line of the file are input into
+|buffer[first]|, |buffer[first+1]|, \dots, |buffer[last-1]|; and the
+global variable |last| is set equal to |first| plus the length of the
+line. Trailing blanks are removed from the line; thus, either |last=first|
+(in which case the line was entirely blank) or |buffer[last-1]<>" "|.
+
+An overflow error is given, however, if the normal actions of |lua_input_ln|
+would make |last>=buf_size|; this is done so that other parts of \TeX\
+can safely look at the contents of |buffer[last+1]| without overstepping
+the bounds of the |buffer| array. Upon entry to |lua_input_ln|, the condition
+|first<buf_size| will always hold, so that there is always room for an
+``empty'' line.
+
+The variable |max_buf_stack|, which is used to keep track of how large
+the |buf_size| parameter must be to accommodate the present job, is
+also kept up to date by |lua_input_ln|.
+
+If the |bypass_eoln| parameter is |true|, |lua_input_ln| will do a |get|
+before looking at the first character of the line; this skips over
+an |eoln| that was in |f^|. The procedure does not do a |get| when it
+reaches the end of the line; therefore it can be used to acquire input
+from the user's terminal as well as from ordinary text files.
+
+Since the inner loop of |lua_input_ln| is part of \TeX's ``inner loop''---each
+character of input comes in at this place---it is wise to reduce system
+overhead by making use of special routines that read in an entire array
+of characters at once, if such routines are available.
+@^inner loop@>
+
+@c
+boolean lua_input_ln(alpha_file f, int n, boolean bypass_eoln)
+{
+ boolean lua_result;
+ int last_ptr;
+ int callback_id;
+ (void) bypass_eoln; /* todo: variable can be removed */
+ if (n == 0)
+ callback_id = input_file_callback_id[iindex];
+ else
+ callback_id = read_file_callback_id[n];
+ if (callback_id > 0) {
+ last = first;
+ last_ptr = first;
+ lua_result =
+ run_saved_callback(callback_id, "reader", "->l", &last_ptr);
+ if ((lua_result == true) && (last_ptr != 0)) {
+ last = last_ptr;
+ if (last > max_buf_stack)
+ max_buf_stack = last;
+ } else {
+ lua_result = false;
+ }
+ } else {
+ lua_result = input_ln(f, bypass_eoln);
+ }
+ if (lua_result == true) {
+ /* Fix up the input buffer using callbacks */
+ if (last >= first) {
+ callback_id = callback_defined(process_input_buffer_callback);
+ if (callback_id > 0) {
+ last_ptr = first;
+ lua_result =
+ run_callback(callback_id, "l->l", (last - first),
+ &last_ptr);
+ if ((lua_result == true) && (last_ptr != 0)) {
+ last = last_ptr;
+ if (last > max_buf_stack)
+ max_buf_stack = last;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+
+@ We need a special routine to read the first line of \TeX\ input from
+the user's terminal. This line is different because it is read before we
+have opened the transcript file; there is sort of a ``chicken and
+egg'' problem here. If the user types `\.{\\input paper}' on the first
+line, or if some macro invoked by that line does such an \.{\\input},
+the transcript file will be named `\.{paper.log}'; but if no \.{\\input}
+commands are performed during the first line of terminal input, the transcript
+file will acquire its default name `\.{texput.log}'. (The transcript file
+will not contain error messages generated by the first line before the
+first \.{\\input} command.)
+@.texput@>
+
+The first line is special also because it may be read before \TeX\ has
+input a format file. In such cases, normal error messages cannot yet
+be given. The following code uses concepts that will be explained later.
+
+@ Different systems have different ways to get started. But regardless of
+what conventions are adopted, the routine that initializes the terminal
+should satisfy the following specifications:
+
+\yskip\textindent{1)}It should open file |term_in| for input from the
+ terminal. (The file |term_out| will already be open for output to the
+ terminal.)
+
+\textindent{2)}If the user has given a command line, this line should be
+ considered the first line of terminal input. Otherwise the
+ user should be prompted with `\.{**}', and the first line of input
+ should be whatever is typed in response.
+
+\textindent{3)}The first line of input, which might or might not be a
+ command line, should appear in locations |first| to |last-1| of the
+ |buffer| array.
+
+\textindent{4)}The global variable |loc| should be set so that the
+ character to be read next by \TeX\ is in |buffer[loc]|. This
+ character should not be blank, and we should have |loc<last|.
+
+\yskip\noindent(It may be necessary to prompt the user several times
+before a non-blank line comes in. The prompt is `\.{**}' instead of the
+later `\.*' because the meaning is slightly different: `\.{\\input}' need
+not be typed immediately after~`\.{**}'.)
+
+The following program does the required initialization.
+Iff anything has been specified on the command line, then |t_open_in|
+will return with |last > first|.
+@^system dependencies@>
+
+@c
+boolean init_terminal(void)
+{ /* gets the terminal input started */
+ t_open_in();
+ if (last > first) {
+ iloc = first;
+ while ((iloc < last) && (buffer[iloc] == ' '))
+ incr(iloc);
+ if (iloc < last) {
+ return true;
+ }
+ }
+ while (1) {
+ wake_up_terminal();
+ fputs("**", term_out);
+ update_terminal();
+ if (!input_ln(term_in, true)) {
+ /* this shouldn't happen */
+ fputs("\n! End of file on the terminal... why?\n", term_out);
+ return false;
+ }
+ iloc = first;
+ while ((iloc < last) && (buffer[iloc] == ' '))
+ incr(iloc);
+ if (iloc < last) {
+ return true; /* return unless the line was all blank */
+ }
+ fputs("Please type the name of your input file.\n", term_out);
+ }
+}
+
+
+@ Here is a procedure that asks the user to type a line of input,
+assuming that the |selector| setting is either |term_only| or |term_and_log|.
+The input is placed into locations |first| through |last-1| of the
+|buffer| array, and echoed on the transcript file if appropriate.
+
+@c
+void term_input(void)
+{ /* gets a line from the terminal */
+ int k; /* index into |buffer| */
+ update_terminal(); /* now the user sees the prompt for sure */
+ if (!input_ln(term_in, true))
+ fatal_error("End of file on the terminal!");
+ term_offset = 0; /* the user's line ended with \.{<return>} */
+ decr(selector); /* prepare to echo the input */
+ if (last != first) {
+ for (k = first; k <= last - 1; k++)
+ print_char(buffer[k]);
+ }
+ print_ln();
+ incr(selector); /* restore previous status */
+}
+
+
+@ It's time now to fret about file names. Besides the fact that different
+operating systems treat files in different ways, we must cope with the
+fact that completely different naming conventions are used by different
+groups of people. The following programs show what is required for one
+particular operating system; similar routines for other systems are not
+difficult to devise.
+@^fingers@>
+@^system dependencies@>
+
+\TeX\ assumes that a file name has three parts: the name proper; its
+``extension''; and a ``file area'' where it is found in an external file
+system. The extension of an input file or a write file is assumed to be
+`\.{.tex}' unless otherwise specified; it is `\.{.log}' on the
+transcript file that records each run of \TeX; it is `\.{.tfm}' on the font
+metric files that describe characters in the fonts \TeX\ uses; it is
+`\.{.dvi}' on the output files that specify typesetting information; and it
+is `\.{.fmt}' on the format files written by \.{INITEX} to initialize \TeX.
+The file area can be arbitrary on input files, but files are usually
+output to the user's current area. If an input file cannot be
+found on the specified area, \TeX\ will look for it on a special system
+area; this special area is intended for commonly used input files like
+\.{webmac.tex}.
+
+Simple uses of \TeX\ refer only to file names that have no explicit
+extension or area. For example, a person usually says `\.{\\input} \.{paper}'
+or `\.{\\font\\tenrm} \.= \.{helvetica}' instead of `\.{\\input}
+\.{paper.new}' or `\.{\\font\\tenrm} \.= \.{<csd.knuth>test}'. Simple file
+names are best, because they make the \TeX\ source files portable;
+whenever a file name consists entirely of letters and digits, it should be
+treated in the same way by all implementations of \TeX. However, users
+need the ability to refer to other files in their environment, especially
+when responding to error messages concerning unopenable files; therefore
+we want to let them use the syntax that appears in their favorite
+operating system.
+
+The following procedures don't allow spaces to be part of
+file names; but some users seem to like names that are spaced-out.
+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.
+
+Here are the global values that file names will be scanned into.
+
+@c
+str_number cur_name; /* name of file just scanned */
+str_number cur_area; /* file area just scanned, or \.{""} */
+str_number cur_ext; /* file extension just scanned, or \.{""} */
+
+
+@ The file names we shall deal with have the
+following structure: If the name contains `\./' or `\.:'
+(for Amiga only), the file area
+consists of all characters up to and including the final such character;
+otherwise the file area is null. If the remaining file name contains
+`\..', the file extension consists of all such characters from the last
+`\..' to the end, otherwise the file extension is null.
+
+We can scan such file names easily by using two global variables that keep track
+of the occurrences of area and extension delimiters:
+
+@c
+pool_pointer area_delimiter; /* the most recent `\./', if any */
+pool_pointer ext_delimiter; /* the relevant `\..', if any */
+
+
+@ Input files that can't be found in the user's area may appear in a standard
+system area called |TEX_area|. Font metric files whose areas are not given
+explicitly are assumed to appear in a standard system area called
+|TEX_font_area|. $\Omega$'s compiled translation process files whose areas
+are not given explicitly are assumed to appear in a standard system area.
+These system area names will, of course, vary from place to place.
+
+@c
+#define append_to_fn(A) do { \
+ c=(A); \
+ if (c!='"') { \
+ if (k<file_name_size) fn[k++]=(unsigned char)(c); \
+ } \
+ } while (0)
+
+
+char *pack_file_name(str_number n, str_number a, str_number e)
+{
+ ASCII_code c; /* character being packed */
+ unsigned char *j; /* index into |str_pool| */
+ int k = 0; /* number of positions filled in |fn| */
+ unsigned char *fn = xmallocarray(packed_ASCII_code,
+ str_length(a) + str_length(n) +
+ str_length(e) + 1);
+ for (j = str_string(a); j < str_string(a) + str_length(a); j++)
+ append_to_fn(*j);
+ for (j = str_string(n); j < str_string(n) + str_length(n); j++)
+ append_to_fn(*j);
+ for (j = str_string(e); j < str_string(e) + str_length(e); j++)
+ append_to_fn(*j);
+ fn[k] = 0;
+ return (char *) fn;
+}
+
+
+
+@ A messier routine is also needed, since format file names must be scanned
+before \TeX's string mechanism has been initialized. We shall use the
+global variable |TEX_format_default| to supply the text for default system areas
+and extensions related to format files.
+@^system dependencies@>
+
+Under {\mc UNIX} we don't give the area part, instead depending
+on the path searching that will happen during file opening. Also, the
+length will be set in the main program.
+
+@c
+char *TEX_format_default;
+
+
+@ This part of the program becomes active when a ``virgin'' \TeX\ is trying to get going,
+just after the preliminary initialization, or when the user is substituting another
+format file by typing `\.\&' after the initial `\.{**}' prompt. The buffer
+contains the first line of input in |buffer[loc..(last-1)]|, where
+|loc<last| and |buffer[loc]<>" "|.
+
+@c
+char *open_fmt_file(void)
+{
+ int j; /* the first space after the format file name */
+ char *fmt = NULL;
+ int dist;
+ j = iloc;
+ if (buffer[iloc] == '&') {
+ incr(iloc);
+ j = iloc;
+ buffer[last] = ' ';
+ while (buffer[j] != ' ')
+ incr(j);
+ fmt = xmalloc((unsigned) (j - iloc + 1));
+ strncpy(fmt, (char *) (buffer + iloc), (size_t) (j - iloc));
+ fmt[j - iloc] = 0;
+ dist = (int) (strlen(fmt) - strlen(DUMP_EXT));
+ if (!(strstr(fmt, DUMP_EXT) == fmt + dist))
+ fmt = concat(fmt, DUMP_EXT);
+ if (zopen_w_input(&fmt_file, fmt, DUMP_FORMAT, FOPEN_RBIN_MODE))
+ goto FOUND;
+ wake_up_terminal();
+ fprintf(stdout, "Sorry, I can't find the format `%s'; will try `%s'.\n",
+ fmt, TEX_format_default);
+ update_terminal();
+ }
+ /* now pull out all the stops: try for the system \.{plain} file */
+ fmt = TEX_format_default;
+ if (!zopen_w_input(&fmt_file, fmt, DUMP_FORMAT, FOPEN_RBIN_MODE)) {
+ wake_up_terminal();
+ fprintf(stdout, "I can't find the format file `%s'!\n",
+ TEX_format_default);
+ return NULL;
+ }
+ FOUND:
+ iloc = j;
+ return fmt;
+}
+
+
+@ The global variable |name_in_progress| is used to prevent recursive
+use of |scan_file_name|, since the |begin_name| and other procedures
+communicate via global variables. Recursion would arise only by
+devious tricks like `\.{\\input\\input f}'; such attempts at sabotage
+must be thwarted. Furthermore, |name_in_progress| prevents \.{\\input}
+@^recursion@>
+from being initiated when a font size specification is being scanned.
+
+Another global variable, |job_name|, contains the file name that was first
+\.{\\input} by the user. This name is extended by `\.{.log}' and `\.{.dvi}'
+and `\.{.fmt}' in the names of \TeX's output files.
+
+@c
+boolean name_in_progress; /* is a file name being scanned? */
+str_number job_name; /* principal file name */
+boolean log_opened; /* has the transcript file been opened? */
+
+
+@ Initially |job_name=0|; it becomes nonzero as soon as the true name is known.
+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.
+
+@c
+unsigned char *texmf_log_name; /* full name of the log file */
+
+
+@ The |open_log_file| routine is used to open the transcript file and to help
+it catch up to what has previously been printed on the terminal.
+
+@c
+void open_log_file(void)
+{
+ int old_setting; /* previous |selector| setting */
+ int k; /* index into |buffer| */
+ int l; /* end of first input line */
+ char *fn;
+ old_setting = selector;
+ if (job_name == 0)
+ job_name = getjobname(maketexstring("texput")); /* TODO */
+ fn = pack_job_name(".fls");
+ recorder_change_filename(fn);
+ fn = pack_job_name(".log");
+ while (!lua_a_open_out(&log_file, fn, 0)) {
+ /* Try to get a different log file name */
+ /* Sometimes |open_log_file| is called at awkward moments when \TeX\ is
+ unable to print error messages or even to |show_context|.
+ The |prompt_file_name| routine can result in a |fatal_error|, but the |error|
+ routine will not be invoked because |log_opened| will be false.
+
+ The normal idea of |batch_mode| is that nothing at all should be written
+ on the terminal. However, in the unusual case that
+ no log file could be opened, we make an exception and allow
+ an explanatory message to be seen.
+
+ Incidentally, the program always refers to the log file as a `\.{transcript
+ file}', because some systems cannot use the extension `\.{.log}' for
+ this file.
+ */
+ selector = term_only;
+ fn = prompt_file_name("transcript file name", ".log");
+ }
+ texmf_log_name = (unsigned char *) xstrdup(fn);
+ selector = log_only;
+ log_opened = true;
+ if (callback_defined(start_run_callback) == 0) {
+ /* Print the banner line, including the date and time */
+ log_banner(luatex_version_string, luatex_date_info, luatex_svn);
+
+ input_stack[input_ptr] = cur_input; /* make sure bottom level is in memory */
+ tprint_nl("**");
+ l = input_stack[0].limit_field; /* last position of first line */
+ if (buffer[l] == end_line_char)
+ decr(l); /* TODO: multichar endlinechar */
+ for (k = 1; k <= l; k++)
+ print_char(buffer[k]);
+ print_ln(); /* now the transcript file contains the first line of input */
+ }
+ flush_loggable_info(); /* should be done always */
+ selector = old_setting + 2; /* |log_only| or |term_and_log| */
+}
+
+
+@ Let's turn now to the procedure that is used to initiate file reading
+when an `\.{\\input}' command is being processed.
+
+@c
+void start_input(void)
+{ /* \TeX\ will \.{\\input} something */
+ str_number temp_str;
+ char *fn;
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ back_input();
+ if (cur_cmd != left_brace_cmd) {
+ scan_file_name(); /* set |cur_name| to desired file name */
+ } else {
+ scan_file_name_toks();
+ }
+ fn = pack_file_name(cur_name, cur_area, cur_ext);
+ while (1) {
+ begin_file_reading(); /* set up |cur_file| and new level of input */
+ if (lua_a_open_in(&cur_file, fn, 0))
+ break;
+ end_file_reading(); /* remove the level that didn't work */
+ fn = prompt_file_name("input file name", "");
+ }
+ iname = maketexstring(fullnameoffile);
+ source_filename_stack[in_open] = iname;
+ full_source_filename_stack[in_open] = xstrdup(fullnameoffile);
+ /* we can try to conserve string pool space now */
+ temp_str = search_string(iname);
+ if (temp_str > 0) {
+ flush_str(iname);
+ iname = temp_str;
+ }
+ if (job_name == 0) {
+ job_name = getjobname(cur_name);
+ open_log_file();
+ }
+ /* |open_log_file| doesn't |show_context|, so |limit|
+ and |loc| needn't be set to meaningful values yet */
+ if (tracefilenames) {
+ if (term_offset + (int) str_length(iname) > max_print_line - 2)
+ print_ln();
+ else if ((term_offset > 0) || (file_offset > 0))
+ print_char(' ');
+ print_char('(');
+ tprint_file_name(NULL, (unsigned char *) fullnameoffile, NULL);
+ }
+ incr(open_parens);
+ update_terminal();
+ istate = new_line;
+ /* Prepare new file {\sl Sync\TeX} information */
+ synctexstartinput(); /* Give control to the {\sl Sync\TeX} controller */
+
+ /* Read the first line of the new file */
+ /* Here we have to remember to tell the |lua_input_ln| routine not to
+ start with a |get|. If the file is empty, it is considered to
+ contain a single blank line. */
+
+ line = 1;
+ if (lua_input_ln(cur_file, 0, false)) {
+ ;
+ }
+ firm_up_the_line();
+ if (end_line_char_inactive())
+ decr(ilimit);
+ else
+ buffer[ilimit] = (packed_ASCII_code) end_line_char;
+ first = ilimit + 1;
+ iloc = istart;
+}
+
+@ Read and write dump files through zlib
+
+@ Earlier versions recast |*f| from |FILE *| to |gzFile|, but there is
+no guarantee that these have the same size, so a static variable
+is needed.
+
+@c
+static gzFile gz_fmtfile = NULL;
+
+@ @c
+void do_zdump(char *p, int item_size, int nitems, FILE * out_file)
+{
+ int err;
+ (void) out_file;
+ if (nitems == 0)
+ return;
+ if (gzwrite(gz_fmtfile, (void *) p, (unsigned) (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);
+ }
+}
+
+@ @c
+void do_zundump(char *p, int item_size, int nitems, FILE * in_file)
+{
+ int err;
+ (void) in_file;
+ if (nitems == 0)
+ return;
+ if (gzread(gz_fmtfile, (void *) p, (unsigned) (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);
+ }
+}
+
+@ @c
+#define COMPRESSION "R3"
+
+boolean zopen_w_input(FILE ** f, const char *fname, 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", fname, &fnam);
+ if (res && fnam && strlen(fnam) > 0) {
+ *f = xfopen(fnam, fopen_mode);
+ if (*f == NULL) {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ } else {
+ res = luatex_open_input(f, fname, format, fopen_mode, true);
+ }
+ if (res) {
+ gz_fmtfile = gzdopen(fileno(*f), "rb" COMPRESSION);
+ }
+ return res;
+}
+
+@ @c
+boolean zopen_w_output(FILE ** f, const char *s, const_string fopen_mode)
+{
+ int res = 1;
+ if (luainit) {
+ *f = fopen(s, fopen_mode);
+ if (*f == NULL) {
+ return 0;
+ }
+ } else {
+ res = luatex_open_output(f, s, fopen_mode);
+ }
+ if (res) {
+ gz_fmtfile = gzdopen(fileno(*f), "wb" COMPRESSION);
+ }
+ return res;
+}
+
+@ @c
+void zwclose(FILE * f)
+{
+ (void) f;
+ gzclose(gz_fmtfile);
+}
+
+@ create the dvi or pdf file
+@c
+int open_outfile(FILE ** f, const char *name, const char *mode)
+{
+ FILE *res;
+ res = fopen(name, mode);
+ if (res != NULL) {
+ *f = res;
+ return 1;
+ }
+ return 0;
+}
+
+
+@ the caller should set |tfm_buffer=NULL| and |tfm_size=0|
+@c
+int readbinfile(FILE * f, unsigned char **tfm_buffer, int *tfm_size)
+{
+ void *buf;
+ int size;
+ if (fseek(f, 0, SEEK_END) == 0) {
+ size = (int) ftell(f);
+ if (size > 0) {
+ buf = xmalloc((unsigned) size);
+ if (fseek(f, 0, SEEK_SET) == 0) {
+ if (fread((void *) buf, (size_t) size, 1, f) == 1) {
+ *tfm_buffer = (unsigned char *) buf;
+ *tfm_size = size;
+ return 1;
+ }
+ }
+ } else {
+ *tfm_buffer = NULL;
+ *tfm_size = 0;
+ return 1;
+ }
+ } /* seek failed, or zero-sized file */
+ return 0;
+}
+
+
+@ Like |runsystem()|, the |runpopen()| function is called only when
+ |shellenabledp == 1|. Unlike |runsystem()|, here we write errors to
+ stderr, since we have nowhere better to use; and of course we return
+ a file handle (or NULL) instead of a status indicator.
+
+@c
+static FILE *runpopen(char *cmd, const char *mode)
+{
+ FILE *f = NULL;
+ char *safecmd = NULL;
+ char *cmdname = NULL;
+ int allow;
+
+ /* If restrictedshell == 0, any command is allowed. */
+ if (restrictedshell == 0) {
+ allow = 1;
+ } else {
+ const char *thecmd = cmd;
+ allow = shell_cmd_is_allowed(&thecmd, &safecmd, &cmdname);
+ }
+ if (allow == 1)
+ f = popen(cmd, mode);
+ else if (allow == 2)
+ f = popen(safecmd, mode);
+ else if (allow == -1)
+ fprintf(stderr, "\nrunpopen quotation error in command line: %s\n",
+ cmd);
+ else
+ fprintf(stderr, "\nrunpopen command not allowed: %s\n", cmdname);
+
+ if (safecmd)
+ free(safecmd);
+ if (cmdname)
+ free(cmdname);
+ return f;
+}
+
+@ Return true if FNAME is acceptable as a name for \.{\\openout}, \.{\\openin}, or
+ \.{\\input}.
+
+@c
+typedef enum ok_type {
+ ok_reading,
+ ok_writing
+} ok_type;
+
+static const_string ok_type_name[] = {
+ "reading",
+ "writing"
+};
+
+static boolean
+opennameok(const_string fname, const_string check_var,
+ const_string default_choice, ok_type action)
+{
+ /* We distinguish three cases:
+ 'a' (any) allows any file to be opened.
+ 'r' (restricted) means disallowing special file names.
+ 'p' (paranoid) means being really paranoid: disallowing special file
+ names and restricting output files to be in or below
+ the working directory or $TEXMFOUTPUT, while input files
+ must be below the current directory, $TEXMFOUTPUT, or
+ (implicitly) in the system areas.
+ We default to "paranoid". The error messages from TeX will be somewhat
+ puzzling...
+ This function contains several return statements... */
+
+ const_string open_choice = kpse_var_value(check_var);
+
+ if (!open_choice)
+ open_choice = default_choice;
+
+ if (*open_choice == 'a' || *open_choice == 'y' || *open_choice == '1')
+ return true;
+
+#if defined (unix) && !defined (MSDOS)
+ {
+ const_string base = xbasename(fname);
+ /* Disallow .rhosts, .login, etc. Allow .tex (for LaTeX). */
+ if (base[0] == 0 ||
+ (base[0] == '.' && !IS_DIR_SEP(base[1]) && !STREQ(base, ".tex"))) {
+ fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
+ program_invocation_name, ok_type_name[action], fname,
+ check_var, open_choice);
+ return false;
+ }
+ }
+#else
+ /* Other OSs don't have special names? */
+#endif
+
+ if (*open_choice == 'r' || *open_choice == 'n' || *open_choice == '0')
+ return true;
+
+ /* Paranoia supplied by Charles Karney... */
+ if (kpse_absolute_p(fname, false)) {
+ const_string texmfoutput = kpse_var_value("TEXMFOUTPUT");
+ /* Absolute pathname is only OK if TEXMFOUTPUT is set, it's not empty,
+ fname begins the TEXMFOUTPUT, and is followed by / */
+ if (!texmfoutput || *texmfoutput == '\0'
+ || fname != strstr(fname, texmfoutput)
+ || !IS_DIR_SEP(fname[strlen(texmfoutput)])) {
+ fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
+ program_invocation_name, ok_type_name[action], fname,
+ check_var, open_choice);
+ return false;
+ }
+ }
+ /* For all pathnames, we disallow "../" at the beginning or "/../"
+ anywhere. */
+ if (fname[0] == '.' && fname[1] == '.' && IS_DIR_SEP(fname[2])) {
+ fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
+ program_invocation_name, ok_type_name[action], fname,
+ check_var, open_choice);
+ return false;
+ } else {
+ /* Check for "/../". Since more than one characted can be matched
+ by |IS_DIR_SEP|, we cannot use "/../" itself. */
+ const_string dotpair = strstr(fname, "..");
+ while (dotpair) {
+ /* If dotpair[2] == |DIR_SEP|, then dotpair[-1] is well-defined,
+ because the "../" case was handled above. */
+ if (IS_DIR_SEP(dotpair[2]) && IS_DIR_SEP(dotpair[-1])) {
+ fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
+ program_invocation_name, ok_type_name[action], fname,
+ check_var, open_choice);
+ return false;
+ }
+ /* Continue after the dotpair. */
+ dotpair = strstr(dotpair + 2, "..");
+ }
+ }
+
+ /* We passed all tests. */
+ return true;
+}
+
+boolean openinnameok(const_string fname)
+{
+ /* For input default to all. */
+ return opennameok(fname, "openin_any", "a", ok_reading);
+}
+
+#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
+
+static int Isspace(char c)
+{
+ return (c == ' ' || c == '\t');
+}
+
+static boolean executable_filep(const_string fname)
+{
+ string p, q, base;
+ string *pp;
+
+ /* check |openout_any| */
+ p = kpse_var_value("openout_any");
+ if (p && *p == 'p') {
+ free(p);
+/* get base name
+ we cannot use xbasename() for abnormal names.
+*/
+ base = xstrdup(fname);
+ p = strrchr(fname, '/');
+ if (p) {
+ p++;
+ strcpy(base, p);
+ }
+ p = strrchr(base, '\\');
+ if (p) {
+ p++;
+ strcpy(base, p);
+ }
+# if defined(__CYGWIN__)
+ for (p = base; *p; p++)
+ *p = tolower(*p);
+ p = base;
+# else
+ p = (char *) strlwr(base);
+# endif
+ for (q = p + strlen(p) - 1;
+ (q >= p) && ((*q == '.') || (Isspace(*q))); q--) {
+ *q = '\0'; /* remove trailing '.' , ' ' and '\t' */
+ }
+ q = strrchr(p, '.'); /* get extension part */
+ pp = suffixlist;
+ if (pp && q) {
+ while (*pp) {
+ if (strchr(fname, ':') || !strcmp(q, *pp)) {
+ fprintf(stderr,
+ "\nThe name %s is forbidden to open for writing.\n",
+ fname);
+ free(base);
+ return true;
+ }
+ pp++;
+ }
+ }
+ free(base);
+ } else if (p) {
+ free(p);
+ }
+ return false;
+}
+#endif
+
+boolean openoutnameok(const_string fname)
+{
+#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
+ /* Output of an executable file is restricted on Windows */
+ if (executable_filep(fname))
+ return false;
+#endif
+ /* For output, default to paranoid. */
+ return opennameok(fname, "openout_any", "p", ok_writing);
+}
+
+
+@ piped I/O
+
+
+@ The code that implements |popen()| needs an array for tracking
+ possible pipe file pointers, because these need to be
+ closed using |pclose()|.
+
+@c
+static FILE *pipes[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+boolean open_in_or_pipe(FILE ** f_ptr, char *fn, int filefmt,
+ const_string fopen_mode, boolean must_exist)
+{
+ string fname = NULL;
+ int i; /* iterator */
+
+ /* opening a read pipe is straightforward, only have to
+ skip past the pipe symbol in the file name. filename
+ quoting is assumed to happen elsewhere (it does :-)) */
+
+ if (shellenabledp && *fn == '|') {
+ /* the user requested a pipe */
+ *f_ptr = NULL;
+ fname = (string) xmalloc((unsigned) (strlen(fn) + 1));
+ strcpy(fname, fn);
+ if (fullnameoffile)
+ free(fullnameoffile);
+ fullnameoffile = xstrdup(fname);
+ recorder_record_input(fname + 1);
+ *f_ptr = runpopen(fname + 1, "r");
+ free(fname);
+ for (i = 0; i <= 15; i++) {
+ if (pipes[i] == NULL) {
+ pipes[i] = *f_ptr;
+ break;
+ }
+ }
+ if (*f_ptr)
+ setvbuf(*f_ptr, (char *) NULL, _IOLBF, 0);
+
+ return *f_ptr != NULL;
+ }
+
+ return luatex_open_input(f_ptr, fn, filefmt, fopen_mode, must_exist);
+}
+
+
+boolean open_out_or_pipe(FILE ** f_ptr, char *fn, const_string fopen_mode)
+{
+ string fname;
+ int i; /* iterator */
+
+ /* opening a write pipe takes a little bit more work, because TeX
+ will perhaps have appended ".tex". To avoid user confusion as
+ much as possible, this extension is stripped only when the command
+ is a bare word. Some small string trickery is needed to make
+ sure the correct number of bytes is free()-d afterwards */
+
+ if (shellenabledp && *fn == '|') {
+ /* the user requested a pipe */
+ fname = (string) xmalloc((unsigned) (strlen(fn) + 1));
+ strcpy(fname, fn);
+ if (strchr(fname, ' ') == NULL && strchr(fname, '>') == NULL) {
+ /* mp and mf currently do not use this code, but it
+ is better to be prepared */
+ if (STREQ((fname + strlen(fname) - 3), "tex"))
+ *(fname + strlen(fname) - 4) = 0;
+ *f_ptr = runpopen(fname + 1, "w");
+ *(fname + strlen(fname)) = '.';
+ } else {
+ *f_ptr = runpopen(fname + 1, "w");
+ }
+ recorder_record_output(fname + 1);
+ free(fname);
+
+ for (i = 0; i <= 15; i++) {
+ if (pipes[i] == NULL) {
+ pipes[i] = *f_ptr;
+ break;
+ }
+ }
+
+ if (*f_ptr)
+ setvbuf(*f_ptr, (char *) NULL, _IOLBF, 0);
+
+ return *f_ptr != NULL;
+ }
+
+ return luatex_open_output(f_ptr, fn, fopen_mode);
+}
+
+
+void close_file_or_pipe(FILE * f)
+{
+ int i; /* iterator */
+
+ if (shellenabledp) {
+ for (i = 0; i <= 15; i++) {
+ /* if this file was a pipe, |pclose()| it and return */
+ if (pipes[i] == f) {
+ if (f)
+ pclose(f);
+ pipes[i] = NULL;
+ return;
+ }
+ }
+ }
+ close_file(f);
+}
diff --git a/Build/source/texk/web2c/luatexdir/texmath.h b/Build/source/texk/web2c/luatexdir/tex/texmath.h
index 9f9717f1ecd..75a595e545f 100644
--- a/Build/source/texk/web2c/luatexdir/texmath.h
+++ b/Build/source/texk/web2c/luatexdir/tex/texmath.h
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: texmath.h 2448 2009-06-08 07:43:50Z taco $ */
+/* $Id: texmath.h 3461 2010-03-09 10:20:54Z taco $ */
#ifndef TEXMATH_H
# define TEXMATH_H 1
@@ -30,7 +30,7 @@ extern pointer new_noad(void);
extern void show_math_node(halfword);
extern void flush_math(void);
extern void math_left_brace(void);
-extern void finish_display_alignment(halfword, halfword, memory_word);
+extern void finish_display_alignment(halfword, halfword, halfword);
extern halfword new_sub_box(halfword);
# define math_reset(p) do { if (p!=null) flush_node(p); p = null; } while (0)
@@ -78,20 +78,11 @@ extern void after_math(void);
extern void scan_extdef_del_code(int level, int extcode);
extern void scan_extdef_math_code(int level, int extcode);
-extern integer fam_fnt(integer fam_id, integer size_id);
-extern void def_fam_fnt(integer fam_id, integer size_id, integer f,
- integer lvl);
+extern int fam_fnt(int fam_id, int size_id);
+extern void def_fam_fnt(int fam_id, int size_id, int f, int lvl);
extern void dump_math_data(void);
extern void undump_math_data(void);
-void unsave_math_data(integer lvl);
-
-extern pointer cur_mlist;
-extern integer cur_style;
-extern boolean mlist_penalties;
-extern integer cur_size;
-
-scaled get_math_quad(int a);
-boolean check_necessary_fonts(void);
+void unsave_math_data(int lvl);
/*
@ We also need to compute the change in style between mlists and their
@@ -123,8 +114,6 @@ extern const char *math_style_names[];
# define denom_style(A) 2*((A)/2)+cramped+2-2*((A)/6) /* smaller, cramped */
# define sup_sup_style(A) sup_style(sup_style((A))) /* smaller */
-void mlist_to_hlist(void);
-
void setup_math_style(void);
void print_math_style(void);
@@ -132,7 +121,7 @@ void print_math_style(void);
# define script_size 1
# define script_script_size 2
-# define math_direction int_par(param_math_direction_code)
+# define math_direction int_par(math_direction_code)
# define dir_math_save cur_list.math_field
# define m_style cur_list.math_style_field
@@ -328,6 +317,8 @@ typedef enum {
RadicalDegreeBottomRaisePercent,
MinConnectorOverlap,
SubscriptShiftDownWithSuperscript,
+ FractionDelimiterSize,
+ FractionDelimiterDisplayStyleSize,
MATH_param_last,
} MATH_param_codes;
diff --git a/Build/source/texk/web2c/luatexdir/tex/math.c b/Build/source/texk/web2c/luatexdir/tex/texmath.w
index a3a2a154f7a..2e76aec61dc 100644
--- a/Build/source/texk/web2c/luatexdir/tex/math.c
+++ b/Build/source/texk/web2c/luatexdir/tex/texmath.w
@@ -1,66 +1,46 @@
-/* math.c
+% texmath.w
- Copyright 2008-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 2008-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-
-#include "nodes.h"
-#include "commands.h"
-#include "managed-sa.h"
-
-#include "tokens.h"
+@ @c
+#include "ptexlib.h"
static const char _svn_version[] =
- "$Id: math.c 2594 2009-06-25 09:24:57Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/math.c $";
+ "$Id: texmath.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/texmath.w $";
+@ @c
#define mode cur_list.mode_field
#define head cur_list.head_field
#define tail cur_list.tail_field
#define prev_graf cur_list.pg_field
#define eTeX_aux cur_list.eTeX_aux_field
#define delim_ptr eTeX_aux
-#define aux cur_list.aux_field
-#define prev_depth aux.cint
-#define space_factor aux.hh.lhfield
-#define incompleat_noad aux.cint
-
-#define stretching 1
-#define shrinking 2
-
-#define append_char(A) str_pool[pool_ptr++]=(A)
-#define flush_char pool_ptr-- /* forget the last character in the pool */
-#define cur_length (pool_ptr - str_start_macro(str_ptr))
-#define saved(A) save_stack[save_ptr+(A)].cint
+#define space_factor cur_list.space_factor_field
+#define incompleat_noad cur_list.incompleat_noad_field
-#define vmode 1
-#define hmode (vmode+max_command_cmd+1)
-#define mmode (hmode+max_command_cmd+1)
-
-#define cur_fam int_par(param_cur_fam_code)
-#define text_direction zeqtb[static_int_base + param_text_direction_code].cint
-
-#define scan_normal_dimen() scan_dimen(false,false,false)
+#define cur_fam int_par(cur_fam_code)
+#define text_direction int_par(text_direction_code)
#define var_code 7
-/* TODO: not sure if this is the right order */
+@ TODO: not sure if this is the right order
+@c
#define back_error(A,B) do { \
OK_to_interrupt=false; \
back_input(); \
@@ -68,22 +48,23 @@ static const char _svn_version[] =
tex_error(A,B); \
} while (0)
+@ @c
int scan_math(pointer, int);
pointer fin_mlist(pointer);
-#define pre_display_size dimen_par(param_pre_display_size_code)
-#define hsize dimen_par(param_hsize_code)
-#define display_width dimen_par(param_display_width_code)
-#define display_indent dimen_par(param_display_indent_code)
-#define math_surround dimen_par(param_math_surround_code)
-#define hang_indent dimen_par(param_hang_indent_code)
-#define hang_after int_par(param_hang_after_code)
-#define every_math loc_par(param_every_math_code)
-#define every_display loc_par(param_every_display_code)
-#define par_shape_ptr loc_par(param_par_shape_code)
-
-/*
-When \TeX\ reads a formula that is enclosed between \.\$'s, it constructs an
+#define pre_display_size dimen_par(pre_display_size_code)
+#define hsize dimen_par(hsize_code)
+#define display_width dimen_par(display_width_code)
+#define display_indent dimen_par(display_indent_code)
+#define math_surround dimen_par(math_surround_code)
+#define hang_indent dimen_par(hang_indent_code)
+#define hang_after int_par(hang_after_code)
+#define every_math equiv(every_math_loc)
+#define every_display equiv(every_display_loc)
+#define par_shape_ptr equiv(par_shape_loc)
+
+
+@ 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
@@ -118,7 +99,7 @@ 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
+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
@@ -161,23 +142,21 @@ 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).
-*/
-
-
-static void unsave_math(void)
+@c
+void unsave_math(void)
{
unsave();
decr(save_ptr);
flush_node_list(text_dir_ptr);
- text_dir_ptr = saved(0);
+ assert(saved_type(0) == saved_textdir);
+ text_dir_ptr = saved_value(0);
}
-/*
-Sometimes it is necessary to destroy an mlist. The following
+@ Sometimes it is necessary to destroy an mlist. The following
subroutine empties the current list, assuming that |abs(mode)=mmode|.
-*/
+@c
void flush_math(void)
{
flush_node_list(vlink(head));
@@ -187,25 +166,27 @@ void flush_math(void)
incompleat_noad = null;
}
-/* Before we can do anything in math mode, we need fonts. */
+@ Before we can do anything in math mode, we need fonts.
+@c
#define MATHFONTSTACK 8
#define MATHFONTDEFAULT 0 /* == nullfont */
static sa_tree math_fam_head = NULL;
-integer fam_fnt(integer fam_id, integer size_id)
+@ @c
+int fam_fnt(int fam_id, int size_id)
{
- integer n = fam_id + (256 * size_id);
- return (integer) get_sa_item(math_fam_head, n);
+ int n = fam_id + (256 * size_id);
+ return (int) get_sa_item(math_fam_head, n);
}
-void def_fam_fnt(integer fam_id, integer size_id, integer f, integer lvl)
+void def_fam_fnt(int fam_id, int size_id, int f, int lvl)
{
- integer n = fam_id + (256 * size_id);
- set_sa_item(math_fam_head, n, f, lvl);
+ int n = fam_id + (256 * size_id);
+ set_sa_item(math_fam_head, n, (sa_tree_item) f, lvl);
fixup_math_parameters(fam_id, size_id, f, lvl);
- if (int_par(param_tracing_assigns_code) > 0) {
+ if (int_par(tracing_assigns_code) > 0) {
begin_diagnostic();
tprint("{assigning");
print_char(' ');
@@ -218,19 +199,20 @@ void def_fam_fnt(integer fam_id, integer size_id, integer f, integer lvl)
}
}
-static void unsave_math_fam_data(integer gl)
+@ @c
+void unsave_math_fam_data(int gl)
{
sa_stack_item st;
if (math_fam_head->stack == NULL)
return;
while (math_fam_head->stack_ptr > 0 &&
abs(math_fam_head->stack[math_fam_head->stack_ptr].level)
- >= (integer) gl) {
+ >= (int) gl) {
st = math_fam_head->stack[math_fam_head->stack_ptr];
if (st.level > 0) {
rawset_sa_item(math_fam_head, st.code, st.value);
/* now do a trace message, if requested */
- if (int_par(param_tracing_restores_code) > 0) {
+ if (int_par(tracing_restores_code) > 0) {
int size_id = st.code / 256;
int fam_id = st.code % 256;
begin_diagnostic();
@@ -250,18 +232,20 @@ static void unsave_math_fam_data(integer gl)
-/* and parameters */
+@ and parameters
+@c
#define MATHPARAMSTACK 8
#define MATHPARAMDEFAULT undefined_math_parameter
static sa_tree math_param_head = NULL;
+@ @c
void def_math_param(int param_id, int style_id, scaled value, int lvl)
{
- integer n = param_id + (256 * style_id);
- set_sa_item(math_param_head, n, value, lvl);
- if (int_par(param_tracing_assigns_code) > 0) {
+ int n = param_id + (256 * style_id);
+ set_sa_item(math_param_head, n, (sa_tree_item) value, lvl);
+ if (int_par(tracing_assigns_code) > 0) {
begin_diagnostic();
tprint("{assigning");
print_char(' ');
@@ -276,24 +260,25 @@ void def_math_param(int param_id, int style_id, scaled value, int lvl)
scaled get_math_param(int param_id, int style_id)
{
- integer n = param_id + (256 * style_id);
+ int n = param_id + (256 * style_id);
return (scaled) get_sa_item(math_param_head, n);
}
-static void unsave_math_param_data(integer gl)
+@ @c
+void unsave_math_param_data(int gl)
{
sa_stack_item st;
if (math_param_head->stack == NULL)
return;
while (math_param_head->stack_ptr > 0 &&
abs(math_param_head->stack[math_param_head->stack_ptr].level)
- >= (integer) gl) {
+ >= (int) gl) {
st = math_param_head->stack[math_param_head->stack_ptr];
if (st.level > 0) {
rawset_sa_item(math_param_head, st.code, st.value);
/* now do a trace message, if requested */
- if (int_par(param_tracing_restores_code) > 0) {
+ if (int_par(tracing_restores_code) > 0) {
int param_id = st.code % 256;
int style_id = st.code / 256;
begin_diagnostic();
@@ -312,14 +297,17 @@ static void unsave_math_param_data(integer gl)
}
-/* saving and unsaving of both */
+@ saving and unsaving of both
-void unsave_math_data(integer gl)
+@c
+void unsave_math_data(int gl)
{
unsave_math_fam_data(gl);
unsave_math_param_data(gl);
}
+@ Dumping and undumping
+@c
void dump_math_data(void)
{
if (math_fam_head == NULL)
@@ -336,8 +324,7 @@ void undump_math_data(void)
math_param_head = undump_sa_tree();
}
-/* */
-
+@ @c
void initialize_math(void)
{
if (math_fam_head == NULL)
@@ -350,14 +337,14 @@ void initialize_math(void)
}
-/*
+
@ 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}
+(usually |fam=0|, |character=075|). 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|)
@@ -394,11 +381,12 @@ 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}.
-*/
-/* The |new_noad| function creates an |ord_noad| that is completely null */
+@ The |new_noad| function creates an |ord_noad| that is completely null
+
+@c
pointer new_noad(void)
{
pointer p;
@@ -407,6 +395,7 @@ pointer new_noad(void)
return p;
}
+@ @c
pointer new_sub_box(pointer cur_box)
{
pointer p, q;
@@ -417,7 +406,7 @@ pointer new_sub_box(pointer cur_box)
return p;
}
-/*
+
@ 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
@@ -426,7 +415,7 @@ centers its nucleus vertically with respect to the axis of the formula;
in such noads we always have |type(nucleus(p))=sub_box|.
And finally, we have the |fence_noad| type, to implement
-\TeX's \.{\\left} and \.{\\right} as well as \eTeX's \.{\\middle}.
+\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 |fence_noad| such that |delimiter(p)| holds the family and character
@@ -435,9 +424,9 @@ never appears in an mlist except as the first element, and a |fence_noad|
with subtype |right_noad_side| never appears in an mlist
except as the last element; furthermore, we either have both a |left_noad_side|
and a |right_noad_side|, or neither one is present.
-*/
-/*
+
+
@ Math formulas can also contain instructions like \.{\\textstyle} that
override \TeX's normal style rules. A |style_node| is inserted into the
data structure to record such instructions; it is three words long, so it
@@ -452,8 +441,8 @@ present because a |choice_node| is converted to a |style_node|.
is backwards from the convention of Appendix~G in {\sl The \TeX book\/};
i.e., a smaller style has a larger numerical value.
@:TeXbook}{\sl The \TeX book@>
-*/
+@c
const char *math_style_names[] = {
"display", "crampeddisplay",
"text", "crampedtext",
@@ -489,37 +478,37 @@ const char *math_param_names[] = {
"relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing",
"openordspacing", "openopspacing", "openbinspacing", "openrelspacing",
"openopenspacing", "openclosespacing", "openpunctspacing",
- "openinnerspacing",
+ "openinnerspacing",
"closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing",
"closeopenspacing", "closeclosespacing", "closepunctspacing",
- "closeinnerspacing",
+ "closeinnerspacing",
"punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing",
"punctopenspacing", "punctclosespacing", "punctpunctspacing",
- "punctinnerspacing",
+ "punctinnerspacing",
"innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing",
"inneropenspacing", "innerclosespacing", "innerpunctspacing",
- "innerinnerspacing",
+ "innerinnerspacing",
NULL
};
+@ @c
pointer new_style(small_number s)
{ /* create a style node */
m_style = s;
return new_node(style_node, s);
}
-/* Finally, the \.{\\mathchoice} primitive creates a |choice_node|, which
+@ 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.
-*/
-
-static pointer new_choice(void)
+@c
+pointer new_choice(void)
{ /* create a choice node */
return new_node(choice_node, 0); /* the |subtype| is not used */
}
-/*
+
@ 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.
@@ -534,9 +523,8 @@ 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\}\}\}\}\$}'.
-*/
-
+@c
void display_normal_noad(pointer p); /* forward */
void display_fence_noad(pointer p); /* forward */
void display_fraction_noad(pointer p); /* forward */
@@ -551,16 +539,16 @@ void show_math_node(pointer p)
tprint_esc("mathchoice");
append_char('D');
show_node_list(display_mlist(p));
- flush_char;
+ flush_char();
append_char('T');
show_node_list(text_mlist(p));
- flush_char;
+ flush_char();
append_char('S');
show_node_list(script_mlist(p));
- flush_char;
+ flush_char();
append_char('s');
show_node_list(script_script_mlist(p));
- flush_char;
+ flush_char();
break;
case simple_noad:
case radical_noad:
@@ -580,9 +568,10 @@ void show_math_node(pointer p)
}
-/* Here are some simple routines used in the display of noads. */
+@ Here are some simple routines used in the display of noads.
-static void print_fam_and_char(pointer p)
+@c
+void print_fam_and_char(pointer p)
{ /* prints family and character */
tprint_esc("fam");
print_int(math_fam(p));
@@ -590,9 +579,10 @@ static void print_fam_and_char(pointer p)
print(math_character(p));
}
-static void print_delimiter(pointer p)
+@ @c
+void print_delimiter(pointer p)
{
- integer a;
+ int a;
if (small_fam(p) < 0) {
print_int(-1); /* this should never happen */
} else if (small_fam(p) < 16 && large_fam(p) < 16 &&
@@ -615,19 +605,18 @@ static void print_delimiter(pointer p)
}
}
-/*
+
@ 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 missing field, because these are not equivalent
(as explained above).
@^recursion@>
-*/
-
-static void print_subsidiary_data(pointer p, ASCII_code c)
+@c
+void print_subsidiary_data(pointer p, ASCII_code c)
{ /* display a noad field */
- if (cur_length >= depth_threshold) {
+ if ((int) cur_length >= depth_threshold) {
if (p != null)
tprint(" []");
} else {
@@ -653,10 +642,11 @@ static void print_subsidiary_data(pointer p, ASCII_code c)
break;
}
}
- flush_char; /* remove |c| from the recursion history */
+ flush_char(); /* remove |c| from the recursion history */
}
}
+@ @c
void display_normal_noad(pointer p)
{
switch (type(p)) {
@@ -745,6 +735,7 @@ void display_normal_noad(pointer p)
print_subsidiary_data(subscr(p), '_');
}
+@ @c
void display_fence_noad(pointer p)
{
if (subtype(p) == right_noad_side)
@@ -756,6 +747,7 @@ void display_fence_noad(pointer p)
print_delimiter(delimiter(p));
}
+@ @c
void display_fraction_noad(pointer p)
{
tprint_esc("fraction, thickness ");
@@ -783,8 +775,8 @@ void display_fraction_noad(pointer p)
print_subsidiary_data(denominator(p), '/');
}
-/*
-The routines that \TeX\ uses to create mlists are similar to those we have
+
+@ 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
@@ -792,21 +784,21 @@ 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|.
-*/
-static void new_save_level_math(group_code c)
+@c
+void new_save_level_math(group_code c)
{
- saved(0) = text_dir_ptr;
+ set_saved_record(0, saved_textdir, 0, text_dir_ptr);
text_dir_ptr = new_dir(math_direction);
incr(save_ptr);
new_save_level(c);
- eq_word_define(static_int_base + param_body_direction_code, math_direction);
- eq_word_define(static_int_base + param_par_direction_code, math_direction);
- eq_word_define(static_int_base + param_text_direction_code, math_direction);
- eq_word_define(static_int_base + param_level_local_dir_code, cur_level);
+ eq_word_define(int_base + body_direction_code, math_direction);
+ eq_word_define(int_base + par_direction_code, math_direction);
+ eq_word_define(int_base + text_direction_code, math_direction);
}
-static void push_math(group_code c, int mstyle)
+@ @c
+void push_math(group_code c, int mstyle)
{
if (math_direction != text_direction)
dir_math_save = true;
@@ -817,22 +809,24 @@ static void push_math(group_code c, int mstyle)
new_save_level_math(c);
}
-static void enter_ordinary_math(void)
+@ @c
+void enter_ordinary_math(void)
{
push_math(math_shift_group, text_style);
- eq_word_define(static_int_base + param_cur_fam_code, -1);
+ eq_word_define(int_base + cur_fam_code, -1);
if (every_math != null)
begin_token_list(every_math, every_math_text);
}
-static void enter_display_math(void);
+@ @c
+void enter_display_math(void);
-/* We get into math mode from horizontal mode when a `\.\$' (i.e., a
+@ 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.
-*/
+@c
void init_math(void)
{
if (cur_cmd == math_shift_cmd) {
@@ -852,28 +846,25 @@ void init_math(void)
}
}
-/*
-We get into ordinary math mode from display math mode when `\.{\\eqno}' or
+
+@ 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.
-*/
-/*
-When \TeX\ is in display math mode, |cur_group=math_shift_group|,
+@ 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.
-*/
+@c
void start_eq_no(void)
{
- saved(0) = cur_chr;
+ set_saved_record(0, saved_eqno, 0, cur_chr);
incr(save_ptr);
enter_ordinary_math();
}
-/*
-Subformulas of math formulas cause a new level of math mode to be entered,
+@ 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
@@ -886,8 +877,8 @@ The group codes placed on |save_stack| in these three cases are
Here is the code that handles case (1); the other cases are not quite as
trivial, so we shall consider them later.
-*/
+@c
void math_left_brace(void)
{
pointer q;
@@ -898,26 +889,34 @@ void math_left_brace(void)
(void) scan_math(nucleus(tail), m_style);
}
-/*
-When we enter display math mode, we need to call |line_break| to
+
+@ 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|.
-*/
-
-static void enter_display_math(void)
+@c
+void enter_display_math(void)
{
scaled w; /* new or partial |pre_display_size| */
scaled l; /* new |display_width| */
scaled s; /* new |display_indent| */
pointer p;
- integer n; /* scope of paragraph shape specification */
- if (head == tail) { /* `\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}' */
+ int n; /* scope of paragraph shape specification */
+ if (head == tail || /* `\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}' */
+ (vlink(head) == tail && /* the 2nd of \.{\$\${ }\$\$} \.{\$\${ }\$\$} */
+ type(tail) == whatsit_node &&
+ subtype(tail) == local_par_node && vlink(tail) == null)) {
+ if (vlink(head) == tail) {
+ /* bug \#270: |resume_after_display| inserts a |local_par_node|, but if
+ there is another display immediately following, we have to get rid
+ of that node */
+ flush_node(tail);
+ }
pop_nest();
w = -max_dimen;
} else {
- line_break(true);
+ line_break(true, math_shift_group);
w = actual_box_width(just_box, (2 * quad(get_cur_font())));
}
/* now we are in vertical mode, working on the list that will contain the display */
@@ -948,10 +947,10 @@ static void enter_display_math(void)
push_math(math_shift_group, display_style);
mode = mmode;
- eq_word_define(static_int_base + param_cur_fam_code, -1);
- eq_word_define(static_dimen_base + param_pre_display_size_code, w);
- eq_word_define(static_dimen_base + param_display_width_code, l);
- eq_word_define(static_dimen_base + param_display_indent_code, s);
+ 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)
begin_token_list(every_display, every_display_text);
if (nest_ptr == 1) {
@@ -961,25 +960,25 @@ static void enter_display_math(void)
}
}
-/* The next routine parses all variations of a delimiter code. The |extcode|
- * tells what syntax form to use (\TeX, \Aleph, \XeTeX, \XeTeXnum, ...) , the
- * |doclass| tells whether or not read a math class also (for \delimiter c.s.).
- * (the class is passed on for conversion to |\mathchar|).
- */
+@ The next routine parses all variations of a delimiter code. The |extcode|
+ tells what syntax form to use (\TeX, Aleph, XeTeX, XeTeXnum, ...) , the
+ |doclass| tells whether or not read a math class also (for \.{\\delimiter} c.s.).
+ (the class is passed on for conversion to \.{\\mathchar}).
+@c
#define fam_in_range ((cur_fam>=0)&&(cur_fam<256))
-static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
+delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
{
const char *hlp[] = {
"I'm going to use 0 instead of that illegal code value.",
NULL
};
delcodeval d;
- integer cur_val1; /* and the global |cur_val| */
- integer mcls, msfam = 0, mschr = 0, mlfam = 0, mlchr = 0;
+ int cur_val1; /* and the global |cur_val| */
+ int mcls, msfam = 0, mschr = 0, mlfam = 0, mlchr = 0;
mcls = 0;
- if (extcode == tex_mathcode) { /* \delcode, this is the easiest */
+ if (extcode == tex_mathcode) { /* \.{\\delcode}, this is the easiest */
scan_int();
/* "MFCCFCC or "FCCFCC */
if (doclass) {
@@ -994,7 +993,7 @@ static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
mschr = (cur_val % 0x100000) / 0x1000;
mlfam = (cur_val & 0xFFF) / 0x100;
mlchr = (cur_val % 0x100);
- } else if (extcode == aleph_mathcode) { /* \odelcode */
+ } else if (extcode == aleph_mathcode) { /* \.{\\odelcode} */
/* "MFFCCCC"FFCCCC or "FFCCCC"FFCCCC */
scan_int();
if (doclass) {
@@ -1012,7 +1011,7 @@ static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
mschr = (cur_val1 % 0x10000);
mlfam = (cur_val / 0x10000);
mlchr = (cur_val % 0x10000);
- } else if (extcode == xetex_mathcode) { /* \Udelcode */
+ } else if (extcode == xetex_mathcode) { /* \.{\\Udelcode} */
/* <0-7>,<0-0xFF>,<0-0x10FFFF> or <0-0xFF>,<0-0x10FFFF> */
if (doclass) {
scan_int();
@@ -1029,13 +1028,13 @@ static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
}
mlfam = 0;
mlchr = 0;
- } else if (extcode == xetexnum_mathcode) { /* \Udelcodenum */
+ } else if (extcode == xetexnum_mathcode) { /* \.{\\Udelcodenum} */
/* "FF<21bits> */
/* the largest numeric value is $2^29-1$, but
the top of bit 21 can't be used as it contains invalid USV's
*/
if (doclass) { /* such a primitive doesn't exist */
- tconfusion("xetexnum_mathcode");
+ confusion("xetexnum_mathcode");
}
scan_int();
msfam = (cur_val / 0x200000);
@@ -1049,7 +1048,7 @@ static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
mlchr = 0;
} else {
/* something's gone wrong */
- tconfusion("unknown_extcode");
+ confusion("unknown_extcode");
}
d.origin_value = extcode;
d.class_value = mcls;
@@ -1060,18 +1059,21 @@ static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
return d;
}
+@ @c
void scan_extdef_del_code(int level, int extcode)
{
delcodeval d;
- integer p;
+ int p;
scan_char_num();
p = cur_val;
scan_optional_equals();
d = do_scan_extdef_del_code(extcode, false);
set_del_code(p, extcode, d.small_family_value, d.small_character_value,
- d.large_family_value, d.large_character_value, level);
+ d.large_family_value, d.large_character_value,
+ (quarterword) (level));
}
+@ @c
mathcodeval scan_mathchar(int extcode)
{
const char *hlp[] = {
@@ -1079,8 +1081,8 @@ mathcodeval scan_mathchar(int extcode)
NULL
};
mathcodeval d;
- integer mcls = 0, mfam = 0, mchr = 0;
- if (extcode == tex_mathcode) { /* \mathcode */
+ int mcls = 0, mfam = 0, mchr = 0;
+ if (extcode == tex_mathcode) { /* \.{\\mathcode} */
/* "TFCC */
scan_int();
if (cur_val > 0x8000) {
@@ -1090,7 +1092,7 @@ mathcodeval scan_mathchar(int extcode)
mcls = (cur_val / 0x1000);
mfam = ((cur_val % 0x1000) / 0x100);
mchr = (cur_val % 0x100);
- } else if (extcode == aleph_mathcode) { /* \omathcode */
+ } else if (extcode == aleph_mathcode) { /* \.{\\omathcode} */
/* "TFFCCCC */
scan_int();
if (cur_val > 0x8000000) {
@@ -1133,7 +1135,7 @@ mathcodeval scan_mathchar(int extcode)
}
} else {
/* something's gone wrong */
- tconfusion("unknown_extcode");
+ confusion("unknown_extcode");
}
d.class_value = mcls;
d.family_value = mfam;
@@ -1142,22 +1144,22 @@ mathcodeval scan_mathchar(int extcode)
return d;
}
-
+@ @c
void scan_extdef_math_code(int level, int extcode)
{
mathcodeval d;
- integer p;
+ int p;
scan_char_num();
p = cur_val;
scan_optional_equals();
d = scan_mathchar(extcode);
set_math_code(p, extcode, d.class_value,
- d.family_value, d.character_value, level);
+ d.family_value, d.character_value, (quarterword) (level));
}
-/* this reads in a delcode when actually a mathcode is needed */
-
+@ this reads in a delcode when actually a mathcode is needed
+@c
mathcodeval scan_delimiter_as_mathchar(int extcode)
{
delcodeval dval;
@@ -1170,11 +1172,11 @@ mathcodeval scan_delimiter_as_mathchar(int extcode)
return mval;
}
-/* this has to match the inverse routine in the pascal code
- * where the |\Umathchardef| is executed
- */
-
-mathcodeval mathchar_from_integer(integer value, int extcode)
+@ this has to match the inverse routine in the pascal code
+ where the \.{\\Umathchardef} is executed
+
+@c
+mathcodeval mathchar_from_integer(int value, int extcode)
{
mathcodeval mval;
mval.origin_value = extcode;
@@ -1195,22 +1197,21 @@ mathcodeval mathchar_from_integer(integer value, int extcode)
return mval;
}
-/* Recall that the |nucleus|, |subscr|, and |supscr| fields in a noad
+@ Recall that the |nucleus|, |subscr|, and |supscr| fields in a noad
are broken down into subfields called |type| and either |math_list| or
|(math_fam,math_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|.
-*/
-
+@c
#define get_next_nb_nr() do { get_x_token(); } while (cur_cmd==spacer_cmd||cur_cmd==relax_cmd)
int scan_math(pointer p, int mstyle)
{
/* label restart,reswitch,exit; */
- mathcodeval mval;
+ mathcodeval mval = { 0, 0, 0, 0 };
assert(p != null);
RESTART:
get_next_nb_nr();
@@ -1246,7 +1247,7 @@ int scan_math(pointer p, int mstyle)
else if (cur_chr == 3)
mval = scan_mathchar(xetexnum_mathcode);
else
- tconfusion("scan_math");
+ confusion("scan_math");
break;
case math_given_cmd:
mval = mathchar_from_integer(cur_chr, tex_mathcode);
@@ -1265,14 +1266,14 @@ int scan_math(pointer p, int mstyle)
else if (cur_chr == 2)
mval = scan_delimiter_as_mathchar(xetex_mathcode);
else
- tconfusion("scan_math");
+ confusion("scan_math");
break;
default:
/* The pointer |p| is placed on |save_stack| while a complex subformula
is being scanned. */
back_input();
scan_left_brace();
- saved(0) = p;
+ set_saved_record(0, saved_math, 0, p);
incr(save_ptr);
push_math(math_group, mstyle);
return 1;
@@ -1287,13 +1288,13 @@ int scan_math(pointer p, int mstyle)
}
-/*
- The |set_math_char| procedure creates a new noad appropriate to a given
+
+@ 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.
-*/
+@c
void set_math_char(mathcodeval mval)
{
pointer p; /* the new noad */
@@ -1334,13 +1335,13 @@ void set_math_char(mathcodeval mval)
}
-/*
- The |math_char_in_text| procedure creates a new node representing a math char
+
+@ The |math_char_in_text| procedure creates a new node representing a math char
in text code, and appends it to the current list. However, if the math code
is sufficiently large, the |cur_chr| is treated as an active character and
nothing is appended.
-*/
+@c
void math_char_in_text(mathcodeval mval)
{
pointer p; /* the new node */
@@ -1360,11 +1361,12 @@ void math_char_in_text(mathcodeval mval)
}
+@ @c
void math_math_comp(void)
{
pointer q;
tail_append(new_noad());
- subtype(tail) = cur_chr;
+ subtype(tail) = (quarterword) cur_chr;
q = new_node(math_char_node, 0);
nucleus(tail) = q;
if (cur_chr == over_noad_type)
@@ -1374,6 +1376,7 @@ void math_math_comp(void)
}
+@ @c
void math_limit_switch(void)
{
const char *hlp[] = {
@@ -1382,29 +1385,28 @@ void math_limit_switch(void)
};
if (head != tail) {
if (type(tail) == simple_noad) {
- subtype(tail) = cur_chr;
+ subtype(tail) = (quarterword) cur_chr;
return;
}
}
tex_error("Limit controls must follow a math operator", hlp);
}
-/*
- Delimiter fields of noads are filled in by the |scan_delimiter| routine.
+
+@ 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.
-*/
-
-static void scan_delimiter(pointer p, integer r)
+@c
+void scan_delimiter(pointer p, int r)
{
- delcodeval dval;
- if (r == tex_mathcode) { /* \radical */
+ delcodeval dval = { 0, 0, 0, 0, 0, 0 };
+ if (r == tex_mathcode) { /* \.{\\radical} */
dval = do_scan_extdef_del_code(tex_mathcode, true);
- } else if (r == aleph_mathcode) { /* \oradical */
+ } else if (r == aleph_mathcode) { /* \.{\\oradical} */
dval = do_scan_extdef_del_code(aleph_mathcode, true);
- } else if (r == xetex_mathcode) { /* \Uradical */
+ } else if (r == xetex_mathcode) { /* \.{\\Uradical} */
dval = do_scan_extdef_del_code(xetex_mathcode, false);
} else if (r == no_mathcode) {
get_next_nb_nr();
@@ -1414,21 +1416,21 @@ static void scan_delimiter(pointer p, integer r)
dval = get_del_code(cur_chr);
break;
case delim_num_cmd:
- if (cur_chr == 0) /* \delimiter */
+ if (cur_chr == 0) /* \.{\\delimiter} */
dval = do_scan_extdef_del_code(tex_mathcode, true);
- else if (cur_chr == 1) /* \odelimiter */
+ else if (cur_chr == 1) /* \.{\\odelimiter} */
dval = do_scan_extdef_del_code(aleph_mathcode, true);
- else if (cur_chr == 2) /* \Udelimiter */
+ else if (cur_chr == 2) /* \.{\\Udelimiter} */
dval = do_scan_extdef_del_code(xetex_mathcode, true);
else
- tconfusion("scan_delimiter1");
+ confusion("scan_delimiter1");
break;
default:
dval.small_family_value = -1;
break;
}
} else {
- tconfusion("scan_delimiter2");
+ confusion("scan_delimiter2");
}
if (p == null)
return;
@@ -1457,6 +1459,7 @@ static void scan_delimiter(pointer p, integer r)
}
+@ @c
void math_radical(void)
{
halfword q;
@@ -1464,24 +1467,24 @@ void math_radical(void)
tail_append(new_node(radical_noad, chr_code));
q = new_node(delim_node, 0);
left_delimiter(tail) = q;
- if (chr_code == 0) /* \radical */
+ if (chr_code == 0) /* \.{\\radical} */
scan_delimiter(left_delimiter(tail), tex_mathcode);
- else if (chr_code == 1) /* \oradical */
+ else if (chr_code == 1) /* \.{\\oradical} */
scan_delimiter(left_delimiter(tail), aleph_mathcode);
- else if (chr_code == 2) /* \Uradical */
+ else if (chr_code == 2) /* \.{\\Uradical} */
scan_delimiter(left_delimiter(tail), xetex_mathcode);
- else if (chr_code == 3) /* \Uroot */
+ else if (chr_code == 3) /* \.{\\Uroot} */
scan_delimiter(left_delimiter(tail), xetex_mathcode);
- else if (chr_code == 4) /* \Uunderdelimiter */
+ else if (chr_code == 4) /* \.{\\Uunderdelimiter} */
scan_delimiter(left_delimiter(tail), xetex_mathcode);
- else if (chr_code == 5) /* \Uoverdelimiter */
+ else if (chr_code == 5) /* \.{\\Uoverdelimiter} */
scan_delimiter(left_delimiter(tail), xetex_mathcode);
- else if (chr_code == 6) /* \Udelimiterunder */
+ else if (chr_code == 6) /* \.{\\Udelimiterunder} */
scan_delimiter(left_delimiter(tail), xetex_mathcode);
- else if (chr_code == 7) /* \Udelimiterover */
+ else if (chr_code == 7) /* \.{\\Udelimiterover} */
scan_delimiter(left_delimiter(tail), xetex_mathcode);
else
- tconfusion("math_radical");
+ confusion("math_radical");
if (chr_code == 3) {
/* the trick with the |vlink(q)| is used by |scan_math|
to decide whether it needs to go on */
@@ -1501,14 +1504,12 @@ void math_radical(void)
}
}
+@ @c
void math_ac(void)
{
halfword q;
- mathcodeval t, b;
- t.character_value = 0;
- t.family_value = 0;
- b.character_value = 0;
- b.family_value = 0;
+ mathcodeval t = { 0, 0, 0, 0 }, b = {
+ 0, 0, 0, 0};
if (cur_cmd == accent_cmd) {
const char *hlp[] = {
"I'm changing \\accent to \\mathaccent here; wish me luck.",
@@ -1518,19 +1519,19 @@ void math_ac(void)
tex_error("Please use \\mathaccent for accents in math mode", hlp);
}
tail_append(new_node(accent_noad, 0));
- if (cur_chr == 0) { /* \mathaccent */
+ if (cur_chr == 0) { /* \.{\\mathaccent} */
t = scan_mathchar(tex_mathcode);
- } else if (cur_chr == 1) { /* \omathaccent */
+ } else if (cur_chr == 1) { /* \.{\\omathaccent} */
t = scan_mathchar(aleph_mathcode);
- } else if (cur_chr == 2) { /* \Umathaccent */
+ } else if (cur_chr == 2) { /* \.{\\Umathaccent} */
t = scan_mathchar(xetex_mathcode);
- } else if (cur_chr == 3) { /* \Umathbotaccent */
+ } else if (cur_chr == 3) { /* \.{\\Umathbotaccent} */
b = scan_mathchar(xetex_mathcode);
- } else if (cur_chr == 4) { /* \Umathaccents */
+ } else if (cur_chr == 4) { /* \.{\\Umathaccents} */
t = scan_mathchar(xetex_mathcode);
b = scan_mathchar(xetex_mathcode);
} else {
- tconfusion("math_ac");
+ confusion("math_ac");
}
if (!(t.character_value == 0 && t.family_value == 0)) {
q = new_node(math_char_node, 0);
@@ -1555,6 +1556,7 @@ void math_ac(void)
(void) scan_math(nucleus(tail), cramped_style(m_style));
}
+@ @c
pointer math_vcenter_group(pointer p)
{
pointer q, r;
@@ -1566,19 +1568,21 @@ pointer math_vcenter_group(pointer p)
return q;
}
-/*
-The routine that scans the four mlists of a \.{\\mathchoice} is very
+
+@ The routine that scans the four mlists of a \.{\\mathchoice} is very
much like the routine that builds discretionary nodes.
-*/
+@c
void append_choices(void)
{
tail_append(new_choice());
incr(save_ptr);
- saved(-1) = 0;
+ set_saved_record(-1, saved_choices, 0, 0);
push_math(math_choice_group, display_style);
scan_left_brace();
}
+
+@ @c
void build_choices(void)
{
pointer p; /* the current mlist */
@@ -1586,7 +1590,8 @@ void build_choices(void)
prev_style = m_style;
unsave_math();
p = fin_mlist(null);
- switch (saved(-1)) {
+ assert(saved_type(-1) == saved_choices);
+ switch (saved_value(-1)) {
case 0:
display_mlist(tail) = p;
break;
@@ -1602,16 +1607,16 @@ void build_choices(void)
return;
break;
} /* there are no other cases */
- incr(saved(-1));
+ set_saved_record(-1, saved_choices, 0, (saved_value(-1) + 1));
push_math(math_choice_group, (prev_style + 2));
scan_left_brace();
}
-/*
- Subscripts and superscripts are attached to the previous nucleus by the
- action procedure called |sub_sup|.
-*/
+@ Subscripts and superscripts are attached to the previous nucleus by the
+action procedure called |sub_sup|.
+
+@c
void sub_sup(void)
{
pointer q;
@@ -1620,7 +1625,7 @@ void sub_sup(void)
q = new_node(sub_mlist_node, 0);
nucleus(tail) = q;
}
- if (cur_cmd == sup_mark_cmd || cur_chr == sup_mark_cmd) { /* super_sub_script */
+ if (cur_cmd == sup_mark_cmd || cur_chr == sup_mark_cmd) { /* |super_sub_script| */
if (supscr(tail) != null) {
const char *hlp[] = {
"I treat `x^1^2' essentially like `x^1{}^2'.", NULL
@@ -1649,19 +1654,19 @@ void sub_sup(void)
}
}
-/*
-An operation like `\.{\\over}' causes the current mlist to go into a
+
+@ 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.
-*/
+@c
void math_fraction(void)
{
- small_number c; /* the type of generalized fraction we are scanning */
+ halfword c; /* the type of generalized fraction we are scanning */
pointer q;
c = cur_chr;
if (incompleat_noad != null) {
@@ -1711,14 +1716,13 @@ void math_fraction(void)
-/* At the end of a math formula or subformula, the |fin_mlist| routine is
+@ 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 |fence_noad| that ends the
current mlist; this |fence_noad| has not yet been appended.
-*/
-
+@c
pointer fin_mlist(pointer p)
{
pointer q; /* the mlist to return */
@@ -1736,7 +1740,7 @@ pointer fin_mlist(pointer p)
q = math_list(numerator(incompleat_noad));
if ((type(q) != fence_noad) || (subtype(q) != left_noad_side)
|| (delim_ptr == null))
- tconfusion("right"); /* this can't happen */
+ confusion("right"); /* this can't happen */
math_list(numerator(incompleat_noad)) = vlink(delim_ptr);
vlink(delim_ptr) = incompleat_noad;
vlink(incompleat_noad) = p;
@@ -1750,12 +1754,12 @@ pointer fin_mlist(pointer p)
}
-/* Now at last we're ready to see what happens when a right brace occurs
+@ 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.
-*/
+@c
void close_math_group(pointer p)
{
pointer q;
@@ -1763,28 +1767,30 @@ void close_math_group(pointer p)
unsave_math();
decr(save_ptr);
- type(saved(0)) = sub_mlist_node;
+ assert(saved_type(0) == saved_math);
+ type(saved_value(0)) = sub_mlist_node;
p = fin_mlist(null);
- math_list(saved(0)) = p;
+ math_list(saved_value(0)) = p;
if (p != null) {
if (vlink(p) == null) {
if (type(p) == simple_noad && subtype(p) == ord_noad_type) {
if (subscr(p) == null && supscr(p) == null) {
- type(saved(0)) = type(nucleus(p));
+ type(saved_value(0)) = type(nucleus(p));
if (type(nucleus(p)) == math_char_node) {
- math_fam(saved(0)) = math_fam(nucleus(p));
- math_character(saved(0)) = math_character(nucleus(p));
+ math_fam(saved_value(0)) = math_fam(nucleus(p));
+ math_character(saved_value(0)) =
+ math_character(nucleus(p));
} else {
- math_list(saved(0)) = math_list(nucleus(p));
+ math_list(saved_value(0)) = math_list(nucleus(p));
math_list(nucleus(p)) = null;
}
- delete_attribute_ref(node_attr(saved(0)));
- node_attr(saved(0)) = node_attr(nucleus(p));
+ delete_attribute_ref(node_attr(saved_value(0)));
+ node_attr(saved_value(0)) = node_attr(nucleus(p));
node_attr(nucleus(p)) = null;
flush_node(p);
}
} else if (type(p) == accent_noad) {
- if (saved(0) == nucleus(tail)) {
+ if (saved_value(0) == nucleus(tail)) {
if (type(tail) == simple_noad
&& subtype(tail) == ord_noad_type) {
q = head;
@@ -1804,27 +1810,27 @@ void close_math_group(pointer p)
}
}
}
- if (vlink(saved(0)) > 0) {
+ if (vlink(saved_value(0)) > 0) {
pointer q;
q = new_node(math_char_node, 0);
- nucleus(vlink(saved(0))) = q;
- vlink(saved(0)) = null;
- saved(0) = q;
- (void) scan_math(saved(0), old_style);
+ nucleus(vlink(saved_value(0))) = q;
+ vlink(saved_value(0)) = null;
+ saved_value(0) = q;
+ (void) scan_math(saved_value(0), old_style);
/* restart */
}
}
-/*
-We have dealt with all constructions of math mode except `\.{\\left}' and
+
+@ 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. The |middle| feature of \eTeX\ allows one ore several \.{\\middle}
+the program. The |middle| feature of eTeX allows one ore several \.{\\middle}
delimiters to appear between \.{\\left} and \.{\\right}.
-*/
+@c
void math_left_right(void)
{
- small_number t; /* |left_noad_side| .. |right_noad_side| */
+ halfword t; /* |left_noad_side| .. |right_noad_side| */
pointer p; /* new noad */
pointer q; /* resulting mlist */
pointer r; /* temporary */
@@ -1851,7 +1857,7 @@ void math_left_right(void)
} else {
p = new_noad();
type(p) = fence_noad;
- subtype(p) = t;
+ subtype(p) = (quarterword) t;
r = new_node(delim_node, 0);
delimiter(p) = r;
scan_delimiter(delimiter(p), no_mathcode);
@@ -1862,7 +1868,7 @@ void math_left_right(void)
unsave_math();
}
if (t != right_noad_side) {
- push_math(math_left_group, cur_style);
+ push_math(math_left_group, m_style);
vlink(head) = q;
tail = p;
delim_ptr = p;
@@ -1877,10 +1883,10 @@ void math_left_right(void)
}
-/* \TeX\ gets to the following part of the program when
+@ \TeX\ gets to the following part of the program when
the first `\.\$' ending a display has been scanned.
-*/
+@c
static void check_second_math_shift(void)
{
get_x_token();
@@ -1916,89 +1922,18 @@ static void check_inline_math_end(void)
}
}
-
-
-void finish_displayed_math(boolean l, boolean danger, pointer a);
-
-void after_math(void)
-{
- boolean danger; /* not enough symbol fonts are present */
- integer m; /* |mmode| or |-mmode| */
- pointer p; /* the formula */
- pointer a = null; /* box containing equation number */
- boolean l = false; /* `\.{\\leqno}' instead of `\.{\\eqno}' */
- danger = check_necessary_fonts();
- m = mode;
- p = fin_mlist(null); /* this pops the nest */
- if (cur_cmd == math_shift_cs_cmd &&
- (cur_chr == text_style || cur_chr == display_style)) {
- you_cant();
- }
- if (mode == -m) { /* end of equation number */
- if (cur_cmd == math_shift_cmd) {
- check_second_math_shift();
- } else {
- check_display_math_end();
- }
- run_mlist_to_hlist(p, text_style, false);
- a = hpack(vlink(temp_head), 0, additional);
- unsave_math();
- decr(save_ptr); /* now |cur_group=math_shift_group| */
- if (saved(0) == 1)
- l = true;
- danger = check_necessary_fonts();
- m = mode;
- p = fin_mlist(null);
- }
- if (m < 0) {
- /* The |unsave| is done after everything else here; hence an appearance of
- `\.{\\mathsurround}' inside of `\.{\$...\$}' affects the spacing at these
- particular \.\$'s. This is consistent with the conventions of
- `\.{\$\$...\$\$}', since `\.{\\abovedisplayskip}' inside a display affects the
- space above that display.
- */
- if (cur_cmd == math_shift_cs_cmd) {
- check_inline_math_end();
- }
- tail_append(new_math(math_surround, before));
- if (dir_math_save) {
- tail_append(new_dir(math_direction));
- }
- run_mlist_to_hlist(p, text_style, (mode > 0));
- vlink(tail) = vlink(temp_head);
- while (vlink(tail) != null)
- tail = vlink(tail);
- if (dir_math_save) {
- tail_append(new_dir(math_direction - 64));
- }
- dir_math_save = false;
- tail_append(new_math(math_surround, after));
- space_factor = 1000;
- unsave_math();
- } else {
- if (a == null) {
- if (cur_cmd == math_shift_cmd) {
- check_second_math_shift();
- } else {
- check_display_math_end();
- }
- }
- run_mlist_to_hlist(p, display_style, false);
- finish_displayed_math(l, danger, a);
- }
-}
-
-
-static void resume_after_display(void)
+@ @c
+void resume_after_display(void)
{
if (cur_group != math_shift_group)
- tconfusion("display");
+ confusion("display");
unsave_math();
prev_graf = prev_graf + 3;
push_nest();
mode = hmode;
space_factor = 1000;
- tail_append(make_local_par_node());
+ tail_append(make_local_par_node()); /* this needs to be intercepted in
+ the display math start ! */
get_x_token();
if (cur_cmd != spacer_cmd)
back_input();
@@ -2009,68 +1944,102 @@ static void resume_after_display(void)
}
-/*
-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.
-*/
-/* 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).
-*/
+@ If the inline directions of \.{\\pardir} and \.{\\mathdir} are
+opposite, then this function will return true. Discovering that fact
+is somewhat odd because it needs traversal of the |save_stack|.
+The occurance of displayed equations is weird enough that this is
+probably still better than having yet another field in the |input_stack|
+structures.
+
+None of this makes much sense if the inline direction of either one of
+\.{\\pardir} or \.{\\mathdir} is vertical, but in that case the current
+math machinery is ill suited anyway so I do not bother to test that.
+
+@c
+static boolean math_and_text_reversed_p(void)
+{
+ int i = save_ptr - 1;
+ while (save_type(i) != level_boundary)
+ i--;
+ while (i < save_ptr) {
+ if (save_type(i) == restore_old_value &&
+ save_value(i) == int_base + par_direction_code) {
+ if (textdir_opposite(math_direction, save_value(i - 1)))
+ return true;
+ }
+ i++;
+ }
+ return false;
+}
+
+
-void finish_displayed_math(boolean l, boolean danger, pointer a)
+@ The fussiest part of math mode processing occurs when a displayed formula is
+being centered and placed with an optional equation number.
+
+
+At this time we are in vertical mode (or internal vertical mode).
+
+ |p| points to the mlist for the formula.
+ |a| is either |null| or it points to a box containing the equation number.
+ |l| is true if there was an \.{\\leqno}/ (so |a| is a horizontal box).
+
+
+@c
+static void finish_displayed_math(boolean l, pointer a, pointer p)
{
- pointer b; /* box containing the equation */
- scaled w; /* width of the equation */
- scaled z; /* width of the line */
- scaled e; /* width of equation number */
- scaled q; /* width of equation number plus space to separate from equation */
+ pointer eq_box; /* box containing the equation */
+ scaled eq_w; /* width of the equation */
+ scaled line_w; /* width of the line */
+ scaled eqno_w; /* width of equation number */
+ scaled eqno_w2; /* width of equation number plus space to separate from equation */
+ scaled line_s; /* move the line right this much */
scaled d; /* displacement of equation in the line */
- scaled s; /* move the line right this much */
small_number g1, g2; /* glue parameter codes for before and after */
pointer r; /* kern node used to position the display */
pointer t; /* tail of adjustment list */
pointer pre_t; /* tail of pre-adjustment list */
- pointer p;
- p = vlink(temp_head);
+ boolean swap_dir; /* true if the math and surrounding text dirs are opposed */
+ swap_dir = math_and_text_reversed_p();
+
adjust_tail = adjust_head;
pre_adjust_tail = pre_adjust_head;
- b = hpack(p, 0, additional);
- p = list_ptr(b);
+ eq_box = hpack(p, 0, additional, -1);
+ p = list_ptr(eq_box);
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) || danger) {
- e = 0;
- q = 0;
+ eq_w = width(eq_box);
+ line_w = display_width;
+ line_s = display_indent;
+ if (a == null) {
+ eqno_w = 0;
+ eqno_w2 = 0;
} else {
- e = width(a);
- q = e + get_math_quad(text_size);
+ eqno_w = width(a);
+ eqno_w2 = eqno_w + get_math_quad(text_size);
}
- if (w + q > z) {
+ if (eq_w + eqno_w2 > line_w) {
/* The user can force the equation number to go on a separate line
by causing its width to be zero. */
- if ((e != 0) && ((w - total_shrink[normal] + q <= z) ||
- (total_shrink[sfi] != 0) || (total_shrink[fil] != 0) ||
- (total_shrink[fill] != 0)
- || (total_shrink[filll] != 0))) {
- list_ptr(b) = null;
- flush_node(b);
- b = hpack(p, z - q, exactly);
+ if ((eqno_w != 0)
+ && ((eq_w - total_shrink[normal] + eqno_w2 <= line_w)
+ || (total_shrink[sfi] != 0) || (total_shrink[fil] != 0)
+ || (total_shrink[fill] != 0)
+ || (total_shrink[filll] != 0))) {
+ list_ptr(eq_box) = null;
+ flush_node(eq_box);
+ eq_box = hpack(p, line_w - eqno_w2, exactly, -1);
} else {
- e = 0;
- if (w > z) {
- list_ptr(b) = null;
- flush_node(b);
- b = hpack(p, z, exactly);
+ eqno_w = 0;
+ if (eq_w > line_w) {
+ list_ptr(eq_box) = null;
+ flush_node(eq_box);
+ eq_box = hpack(p, line_w, exactly, -1);
}
}
- w = width(b);
+ eq_w = width(eq_box);
}
/* 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''
@@ -2080,9 +2049,9 @@ void finish_displayed_math(boolean l, boolean danger, pointer a)
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) && (d < 2 * e)) { /* too close */
- d = half(z - w - e);
+ d = half(line_w - eq_w);
+ if ((eqno_w > 0) && (d < 2 * eqno_w)) { /* too close */
+ d = half(line_w - eq_w - eqno_w);
if (p != null)
if (!is_char_node(p))
if (type(p) == glue_node)
@@ -2095,41 +2064,62 @@ void finish_displayed_math(boolean l, boolean danger, pointer a)
displacement for all three potential lines of the display, even though
`\.{\\parshape}' may specify them differently.
*/
- tail_append(new_penalty(int_par(param_pre_display_penalty_code)));
- if ((d + s <= pre_display_size) || l) { /* not enough clearance */
- g1 = param_above_display_skip_code;
- g2 = param_below_display_skip_code;
+ tail_append(new_penalty(int_par(pre_display_penalty_code)));
+ if ((d + line_s <= pre_display_size) || l) { /* not enough clearance */
+ g1 = above_display_skip_code;
+ g2 = below_display_skip_code;
} else {
- g1 = param_above_display_short_skip_code;
- g2 = param_below_display_short_skip_code;
+ g1 = above_display_short_skip_code;
+ g2 = below_display_short_skip_code;
}
- if (l && (e == 0)) { /* it follows that |type(a)=hlist_node| */
- shift_amount(a) = s;
+
+ if (l && (eqno_w == 0)) { /* \.{\\leqno} on a forced single line due to |width=0| */
+ /* it follows that |type(a)=hlist_node| */
+ if (swap_dir) {
+ shift_amount(a) = line_w + line_s;
+ } else {
+ shift_amount(a) = line_s;
+ }
append_to_vlist(a);
tail_append(new_penalty(inf_penalty));
} else {
tail_append(new_param_glue(g1));
}
- if (e != 0) {
- r = new_kern(z - w - e - d);
+ if (eqno_w != 0) {
+ r = new_kern(line_w - eq_w - eqno_w - d);
if (l) {
vlink(a) = r;
- vlink(r) = b;
- b = a;
+ vlink(r) = eq_box;
+ eq_box = a;
d = 0;
} else {
- vlink(b) = r;
+ vlink(eq_box) = r;
vlink(r) = a;
}
- b = hpack(b, 0, additional);
+ eq_box = hpack(eq_box, 0, additional, -1);
+ }
+ if (swap_dir) {
+ /* |d = line_w - d;| */
+ if (eqno_w != 0) {
+ if (l)
+ d = line_w - width(eq_box);
+ else
+ d = 0;
+ } else {
+ d = line_w - eq_w - eqno_w - d;
+ }
}
- shift_amount(b) = s + d;
- append_to_vlist(b);
+ shift_amount(eq_box) = line_s + d;
+ append_to_vlist(eq_box);
- if ((a != null) && (e == 0) && !l) {
+ if ((a != null) && (eqno_w == 0) && !l) {
tail_append(new_penalty(inf_penalty));
- shift_amount(a) = s + z - width(a);
+ if (!swap_dir) {
+ shift_amount(a) = line_s + line_w - width(a);
+ } else {
+ shift_amount(a) = line_s;
+ }
append_to_vlist(a);
g2 = 0;
}
@@ -2141,23 +2131,88 @@ void finish_displayed_math(boolean l, boolean danger, pointer a)
vlink(tail) = vlink(pre_adjust_head);
tail = pre_t;
}
- tail_append(new_penalty(int_par(param_post_display_penalty_code)));
+ tail_append(new_penalty(int_par(post_display_penalty_code)));
if (g2 > 0)
tail_append(new_param_glue(g2));
resume_after_display();
}
+@ @c
+void after_math(void)
+{
+ int m; /* |mmode| or |-mmode| */
+ pointer p; /* the formula */
+ pointer a = null; /* box containing equation number */
+ boolean l = false; /* `\.{\\leqno}' instead of `\.{\\eqno}' */
+ m = mode;
+ p = fin_mlist(null); /* this pops the nest */
+ if (cur_cmd == math_shift_cs_cmd &&
+ (cur_chr == text_style || cur_chr == display_style)) {
+ you_cant();
+ }
+ if (mode == -m) { /* end of equation number */
+ if (cur_cmd == math_shift_cmd) {
+ check_second_math_shift();
+ } else {
+ check_display_math_end();
+ }
+ run_mlist_to_hlist(p, text_style, false);
+ a = hpack(vlink(temp_head), 0, additional, -1);
+ unsave_math();
+ decr(save_ptr); /* now |cur_group=math_shift_group| */
+ assert(saved_type(0) == saved_eqno);
+ if (saved_value(0) == 1)
+ l = true;
+ m = mode;
+ p = fin_mlist(null);
+ }
+ if (m < 0) {
+ /* The |unsave| is done after everything else here; hence an appearance of
+ `\.{\\mathsurround}' inside of `\.{\$...\$}' affects the spacing at these
+ particular \.\$'s. This is consistent with the conventions of
+ `\.{\$\$...\$\$}', since `\.{\\abovedisplayskip}' inside a display affects the
+ space above that display.
+ */
+ if (cur_cmd == math_shift_cs_cmd) {
+ check_inline_math_end();
+ }
+ tail_append(new_math(math_surround, before));
+ if (dir_math_save) {
+ tail_append(new_dir(math_direction));
+ }
+ run_mlist_to_hlist(p, text_style, (mode > 0));
+ vlink(tail) = vlink(temp_head);
+ while (vlink(tail) != null)
+ tail = vlink(tail);
+ if (dir_math_save) {
+ tail_append(new_dir(math_direction - 64));
+ }
+ dir_math_save = false;
+ tail_append(new_math(math_surround, after));
+ space_factor = 1000;
+ unsave_math();
+ } else {
+ if (a == null) {
+ if (cur_cmd == math_shift_cmd) {
+ check_second_math_shift();
+ } else {
+ check_display_math_end();
+ }
+ }
+ run_mlist_to_hlist(p, display_style, false);
+ finish_displayed_math(l, a, vlink(temp_head));
+ }
+}
+
-/*
- When \.{\\halign} appears in a display, the alignment routines operate
+@ 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.
-*/
-
-void finish_display_alignment(pointer p, pointer q, memory_word aux_save)
+@c
+void finish_display_alignment(pointer p, pointer q, halfword saved_prevdepth)
{
do_assignments();
if (cur_cmd != math_shift_cmd) {
@@ -2171,19 +2226,20 @@ void finish_display_alignment(pointer p, pointer q, memory_word aux_save)
check_second_math_shift();
}
pop_nest();
- tail_append(new_penalty(int_par(param_pre_display_penalty_code)));
- tail_append(new_param_glue(param_above_display_skip_code));
+ tail_append(new_penalty(int_par(pre_display_penalty_code)));
+ tail_append(new_param_glue(above_display_skip_code));
vlink(tail) = p;
if (p != null)
tail = q;
- tail_append(new_penalty(int_par(param_post_display_penalty_code)));
- tail_append(new_param_glue(param_below_display_skip_code));
- prev_depth = aux_save.cint;
+ tail_append(new_penalty(int_par(post_display_penalty_code)));
+ tail_append(new_param_glue(below_display_skip_code));
+ cur_list.prev_depth_field = saved_prevdepth;
resume_after_display();
}
-/* Interface to \.{\\Umath} and \.{\\mathstyle} */
+@ Interface to \.{\\Umath} and \.{\\mathstyle}
+@c
void setup_math_style(void)
{
pointer q;
@@ -2194,6 +2250,7 @@ void setup_math_style(void)
}
+@ @c
void print_math_style(void)
{
if (abs(mode) == mmode)
diff --git a/Build/source/texk/web2c/luatexdir/nodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
index 6a1c79171cf..556f8fb2c72 100644
--- a/Build/source/texk/web2c/luatexdir/nodes.h
+++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
@@ -17,19 +17,13 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id$ */
+/* $Id: texnodes.h 3552 2010-03-26 15:30:08Z taco $ */
#include <stdarg.h>
#ifndef __NODES_H__
# define __NODES_H__
-/* these don't really belong here */
-
-# define token_ref_count(a) info((a)) /* reference count preceding a token list */
-# define add_token_ref(a) token_ref_count(a)++ /* new reference to a token list */
-
-
/* these are in texlang.c */
# define set_vlink(a,b) vlink(a)=b
@@ -46,6 +40,16 @@ extern halfword insert_complex_discretionary(halfword t, lang_variables * lan,
extern halfword insert_character(halfword t, int n);
extern void set_disc_field(halfword f, halfword t);
+# define varmemcast(a) (memory_word *)(a)
+extern memory_word *volatile varmem;
+extern halfword var_mem_max;
+
+extern halfword get_node(int s);
+extern void free_node(halfword p, int s);
+extern void init_node_mem(int s);
+extern void dump_node_mem(void);
+extern void undump_node_mem(void);
+
# define max_halfword 0x3FFFFFFF
# define max_dimen 0x3FFFFFFF
@@ -113,59 +117,20 @@ extern halfword do_set_attribute(halfword p, int i, int val);
# define shrink_order(a) subtype((a)+3)
# define glue_ref_count(a) vlink((a)+3)
+# define width_offset 2
+# define depth_offset 3
+# define height_offset 4
+# define list_offset 6
+
typedef enum {
cond_math_glue = 98, /* special |subtype| to suppress glue in the next node */
mu_glue, /* |subtype| for math glue */
a_leaders, /* |subtype| for aligned leaders */
c_leaders, /* |subtype| for centered leaders */
- x_leaders /* |subtype| for expanded leaders */
+ x_leaders, /* |subtype| for expanded leaders */
+ g_leaders /* |subtype| for global (page) leaders */
} glue_subtype_codes;
-/* pdf action spec */
-
-# define pdf_action_size 4
-
-typedef enum {
- pdf_action_page = 0,
- pdf_action_goto,
- pdf_action_thread,
- pdf_action_user
-} pdf_action_types;
-
-# define pdf_action_type(a) type((a) + 1)
-# define pdf_action_named_id(a) subtype((a) + 1)
-# define pdf_action_id(a) vlink((a) + 1)
-# define pdf_action_file(a) vinfo((a) + 2)
-# define pdf_action_new_window(a) vlink((a) + 2)
-# define pdf_action_tokens(a) vinfo((a) + 3)
-# define pdf_action_refcount(a) vlink((a) + 3)
-
-/*increase count of references to this action*/
-# define add_action_ref(a) pdf_action_refcount((a))++
-
-/* decrease count of references to this
- action; free it if there is no reference to this action*/
-
-# define delete_action_ref(a) { \
- if (pdf_action_refcount(a) == null) { \
- if (pdf_action_type(a) == pdf_action_user) { \
- delete_token_ref(pdf_action_tokens(a)); \
- } else { \
- if (pdf_action_file(a) != null) \
- delete_token_ref(pdf_action_file(a)); \
- if (pdf_action_type(a) == pdf_action_page) \
- delete_token_ref(pdf_action_tokens(a)); \
- else if (pdf_action_named_id(a) > 0) \
- delete_token_ref(pdf_action_id(a)); \
- } \
- free_node(a, pdf_action_size); \
- } else { \
- decr(pdf_action_refcount(a)); \
- } \
- }
-
-
-
/* normal nodes */
# define inf_bad 10000 /* infinitely bad value */
@@ -213,22 +178,28 @@ typedef enum {
# define tlink_post_break(a) tlink(post_break_head(a))
# define tlink_no_break(a) tlink(no_break_head(a))
-# define kern_node_size 4
+# define kern_node_size 5
# define explicit 1 /*|subtype| of kern nodes from \.{\\kern} and \.{\\/} */
# define acc_kern 2 /*|subtype| of kern nodes from accents */
# define synctex_tag_kern(a) vinfo((a)+3)
# define synctex_line_kern(a) vlink((a)+3)
+# define ex_kern(a) vinfo((a)+4) /* expansion factor (hz) */
# define box_node_size 9
-# define width(a) varmem[(a+2)].cint
-# define depth(a) varmem[(a+3)].cint
-# define height(a) varmem[(a+4)].cint
+
+# define HLIST_SUBTYPE_UNKNOWN 0
+# define HLIST_SUBTYPE_LINE 1
+# define HLIST_SUBTYPE_HBOX 2
+
+# define width(a) varmem[(a)+2].cint
+# define depth(a) varmem[(a)+3].cint
+# define height(a) varmem[(a)+4].cint
# define shift_amount(a) vlink((a)+5)
# define box_dir(a) vinfo((a)+5)
# define list_ptr(a) vlink((a)+6)
# define glue_order(a) subtype((a)+6)
# define glue_sign(a) type((a)+6)
-# define glue_set(a) varmem[(a+7)].gr
+# define glue_set(a) varmem[(a)+7].gr
# define synctex_tag_box(a) vinfo((a)+8)
# define synctex_line_box(a) vlink((a)+8)
@@ -248,9 +219,10 @@ typedef enum {
# define mark_class(a) vinfo((a)+2)
# define adjust_node_size 3
+# define adjust_pre subtype
# define adjust_ptr(a) vlink(a+2)
-# define glyph_node_size 5
+# define glyph_node_size 6
# define character(a) vinfo((a)+2)
# define font(a) vlink((a)+2)
@@ -258,9 +230,10 @@ typedef enum {
# define lig_ptr(a) vlink((a)+3)
# define x_displace(a) vinfo((a)+4)
# define y_displace(a) vlink((a)+4)
+# define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */
# define is_char_node(a) (a!=null && type(a)==glyph_node)
-# define char_lang(a) ((const int)(((unsigned)lang_data(a) & 0x7FFF0000)>>16))
+# define char_lang(a) ((const int)(signed short)(((signed int)((unsigned)lang_data(a)&0x7FFF0000)<<1)>>17))
# define char_lhmin(a) ((const int)(((unsigned)lang_data(a) & 0x0000FF00)>>8))
# define char_rhmin(a) ((const int)(((unsigned)lang_data(a) & 0x000000FF)))
# define char_uchyph(a) ((const int)(((unsigned)lang_data(a) & 0x80000000)>>31))
@@ -297,10 +270,6 @@ typedef enum {
# define page_ins_node_size 5
-# define broken_ptr(a) vlink((a)+2) /* an insertion for this class will break here if anywhere */
-# define broken_ins(a) vinfo((a)+2) /* this insertion might break at |broken_ptr| */
-# define last_ins_ptr(a) vlink((a)+3) /*the most recent insertion for this |subtype| */
-# define best_ins_ptr(a) vinfo((a)+3) /*the optimum most recent insertion */
/* height = 4 */
typedef enum {
@@ -349,22 +318,24 @@ typedef enum {
split_up_node,
expr_node,
nesting_node,
- span_node,
+ span_node, /* 45 */
attribute_node,
glue_spec_node,
attribute_list_node,
action_node,
- temp_node,
+ temp_node, /* 50 */
align_stack_node,
movement_node,
if_node,
unhyphenated_node,
- hyphenated_node,
+ hyphenated_node, /* 55 */
delta_node,
passive_node,
shape_node,
} node_types;
+# define MAX_NODE_TYPE 58
+
# define last_known_node temp_node /* used by \lastnodetype */
# define movement_node_size 3
@@ -499,6 +470,7 @@ typedef enum {
user_defined_node /* 44 */
} whatsit_types;
+# define MAX_WHATSIT_TYPE 44
# define get_node_size(i,j) (i!=whatsit_node ? node_data[i].size : whatsit_node_data[j].size)
# define get_node_name(i,j) (i!=whatsit_node ? node_data[i].name : whatsit_node_data[j].name)
@@ -507,7 +479,6 @@ typedef enum {
# define pdf_info_code pdf_thread_data_node
# define pdf_catalog_code pdf_link_data_node
-
# define GLYPH_CHARACTER (1 << 0)
# define GLYPH_LIGATURE (1 << 1)
# define GLYPH_GHOST (1 << 2)
@@ -525,15 +496,15 @@ typedef enum {
# define is_leftghost(p) (is_ghost(p) && ((subtype(p)) & GLYPH_LEFT ))
# define is_rightghost(p) (is_ghost(p) && ((subtype(p)) & GLYPH_RIGHT ))
-# define set_is_glyph(p) subtype(p) &= ~GLYPH_CHARACTER
-# define set_is_character(p) subtype(p) |= GLYPH_CHARACTER
-# define set_is_ligature(p) subtype(p) |= GLYPH_LIGATURE
-# define set_is_ghost(p) subtype(p) |= GLYPH_GHOST
+# define set_is_glyph(p) subtype(p) = (quarterword) (subtype(p) & ~GLYPH_CHARACTER)
+# define set_is_character(p) subtype(p) = (quarterword) (subtype(p) | GLYPH_CHARACTER)
+# define set_is_ligature(p) subtype(p) = (quarterword) (subtype(p) | GLYPH_LIGATURE)
+# define set_is_ghost(p) subtype(p) = (quarterword) (subtype(p) |GLYPH_GHOST)
-# define set_to_glyph(p) subtype(p) = (subtype(p) & 0xFF00)
-# define set_to_character(p) subtype(p) = (subtype(p) & 0xFF00) | GLYPH_CHARACTER
-# define set_to_ligature(p) subtype(p) = (subtype(p) & 0xFF00) | GLYPH_LIGATURE
-# define set_to_ghost(p) subtype(p) = (subtype(p) & 0xFF00) | GLYPH_GHOST
+# define set_to_glyph(p) subtype(p) = (quarterword)(subtype(p) & 0xFF00)
+# define set_to_character(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_CHARACTER)
+# define set_to_ligature(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_LIGATURE)
+# define set_to_ghost(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_GHOST)
# define set_is_leftboundary(p) { set_to_ligature(p); subtype(p) |= GLYPH_LEFT; }
# define set_is_rightboundary(p) { set_to_ligature(p); subtype(p) |= GLYPH_RIGHT; }
@@ -547,9 +518,9 @@ typedef enum {
# define dir_dir(a) vinfo((a)+2)
# define dir_level(a) vlink((a)+2)
# define dir_dvi_ptr(a) vinfo((a)+3)
-# define dir_dvi_h(a) vlink((a)+3)
-# define dir_box_pos_h(a) vinfo((a)+4)
-# define dir_box_pos_v(a) vlink((a)+4)
+# define dir_dvi_h(a) vlink((a)+3) /* obsolete */
+# define dir_refpos_h(a) vinfo((a)+4)
+# define dir_refpos_v(a) vlink((a)+4)
# define dir_cur_h(a) vinfo((a)+5)
# define dir_cur_v(a) vlink((a)+5)
@@ -579,10 +550,6 @@ typedef enum {
# define local_par_dir(a) vinfo((a)+5)
-# define pdf_literal_data(a) vlink((a)+2)
-# define pdf_literal_mode(a) type((a)+2)
-# define pdf_literal_type(a) subtype((a)+2)
-
/* type of literal data */
# define lua_refid_literal 1 /* not a |normal| string */
@@ -592,6 +559,7 @@ typedef enum {
set_origin = 0,
direct_page,
direct_always,
+ scan_special,
} ctm_transform_modes;
@@ -605,13 +573,27 @@ typedef enum {
# define pdf_dest_node_size 8
# define pdf_thread_node_size 8
-# define pdf_width(a) varmem[(a) + 2].cint
-# define pdf_height(a) varmem[(a) + 3].cint
-# define pdf_depth(a) varmem[(a) + 4].cint
+/*
+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_ann_left| and |pdf_ann_top| are used for some types of destinations
+*/
+
+/* coordinates of destinations/threads/annotations (in whatsit node) */
+# define pdf_ann_left(a) varmem[(a) + 2].cint
+# define pdf_ann_top(a) varmem[(a) + 3].cint
+# define pdf_ann_right(a) varmem[(a) + 4].cint
+# define pdf_ann_bottom(a) varmem[(a) + 5].cint
+
+# define pdf_literal_data(a) vlink((a)+2)
+# define pdf_literal_mode(a) type((a)+2)
+# define pdf_literal_type(a) subtype((a)+2)
-# define pdf_ximage_objnum(a) vinfo((a) + 5) /* this will be removed soon */
-# define pdf_ximage_ref(a) vinfo((a) + 5)
-# define pdf_xform_objnum(a) vinfo((a) + 5)
+# define pdf_ximage_index(a) vinfo((a) + 5) /* /Im* number and image index in array */
+# define pdf_ximage_transform(a) vlink((a) + 5)
+# define pdf_xform_objnum(a) vinfo((a) + 5)
+# define pdf_xform_transform(a) vlink((a) + 5)
# define pdf_annot_data(a) vinfo((a) + 6)
# define pdf_link_attr(a) vinfo((a) + 6)
@@ -660,14 +642,6 @@ typedef enum {
# define cancel_boundary_size 3
-typedef enum {
- exactly = 0, /*a box dimension is pre-specified */
- additional, /*a box dimension is increased from the natural one */
- cal_expand_ratio, /* calculate amount for font expansion after breaking
- paragraph into lines */
- subst_ex_font /* substitute fonts */
-} hpack_subtypes;
-
# define active_node_size 4 /*number of words in extended active nodes */
# define fitness subtype /*|very_loose_fit..tight_fit| on final line for this break */
# define break_node(a) vlink((a)+1) /*pointer to the corresponding passive node */
@@ -705,10 +679,9 @@ extern void set_attribute(halfword n, int c, int w);
extern int has_attribute(halfword n, int c, int w);
extern halfword new_span_node(halfword n, int c, scaled w);
-extern halfword string_to_pseudo(integer l, integer pool_ptr, integer nl);
extern void print_short_node_contents(halfword n);
-extern void show_node_list(integer i);
+extern void show_node_list(int i);
extern pointer actual_box_width(pointer r, scaled base_width);
/* TH: these two defines still need checking. The node ordering in luatex is not
@@ -731,8 +704,9 @@ extern node_info whatsit_node_data[];
extern halfword new_node(int i, int j);
extern void flush_node_list(halfword);
extern void flush_node(halfword);
+extern halfword do_copy_node_list(halfword, halfword);
extern halfword copy_node_list(halfword);
-extern halfword copy_node(halfword);
+extern halfword copy_node(const halfword);
extern void check_node(halfword);
extern void check_node_mem(void);
extern void fix_node_list(halfword);
@@ -742,7 +716,6 @@ extern halfword raw_glyph_node(void);
extern halfword new_glyph_node(void);
extern int valid_node(halfword);
-# define unity 0x10000
typedef enum {
normal_g = 0,
sfi,
@@ -771,8 +744,37 @@ typedef enum {
# define end_point begin_point+glyph_node_size
# define var_mem_stat_max (end_point+glyph_node_size-1)
-/* from tex/texnodes.c */
+# define stretching 1
+# define shrinking 2
+
+# define is_running(A) ((A)==null_flag) /* tests for a running dimension */
+
+extern halfword tail_of_list(halfword p);
+extern void delete_glue_ref(halfword p);
+
+extern int var_used;
+extern halfword temp_ptr;
+
+# define cache_disabled max_halfword
-extern halfword list_node_mem_usage(void);
+extern int max_used_attr;
+extern halfword attr_list_cache;
+
+extern halfword new_null_box(void);
+extern halfword new_rule(void);
+extern halfword new_glyph(int f, int c);
+extern quarterword norm_min(int h);
+extern halfword new_char(int f, int c);
+extern scaled glyph_width(halfword p);
+extern scaled glyph_height(halfword p);
+extern scaled glyph_depth(halfword p);
+extern halfword new_disc(void);
+extern halfword new_math(scaled w, int s);
+extern halfword new_spec(halfword p);
+extern halfword new_param_glue(int n);
+extern halfword new_glue(halfword q);
+extern halfword new_skip_param(int n);
+extern halfword new_kern(scaled w);
+extern halfword new_penalty(int m);
#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.c b/Build/source/texk/web2c/luatexdir/tex/texnodes.w
index ca6af731ef1..45241b0ac29 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.c
+++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.w
@@ -1,68 +1,49 @@
-/* texnodes.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% texnodes.w
- This file is part of LuaTeX.
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% 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.
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "nodes.h"
-#include "commands.h"
-
-#include "tokens.h"
-#undef name
-
-#define noDEBUG
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+@ @c
static const char _svn_version[] =
- "$Id: texnodes.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/texnodes.c $";
-
-#define append_char(A) str_pool[pool_ptr++]=(A)
-#define cur_length (pool_ptr - str_start_macro(str_ptr))
-#define flush_char() pool_ptr--
+ "$Id: texnodes.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/texnodes.w $";
-#define stretching 1
-#define shrinking 2
+#include "ptexlib.h"
+#include "lua/luatex-api.h"
-#define adjust_pre subtype
+@ @c
+#undef name
-typedef enum {
- pdf_dest_xyz = 0,
- pdf_dest_fit,
- pdf_dest_fith,
- pdf_dest_fitv,
- pdf_dest_fitb,
- pdf_dest_fitbh,
- pdf_dest_fitbv,
- pdf_dest_fitr,
-} pdf_destination_types;
+#define noDEBUG
+#define DEBUG_OUT stdout
+#define adjust_pre subtype
+#define attribute(A) eqtb[attribute_base+(A)].cint
-#define obj_obj_data(A) pdf_mem[obj_data_ptr((A)) + 0]
-#define obj_obj_is_stream(A) pdf_mem[obj_data_ptr((A)) + 1]
-#define obj_obj_stream_attr(A) pdf_mem[obj_data_ptr((A)) + 2]
-#define obj_obj_is_file(A) pdf_mem[obj_data_ptr((A)) + 3]
-#define obj_xform_width(A) pdf_mem[obj_data_ptr((A)) + 0]
-#define obj_xform_height(A) pdf_mem[obj_data_ptr((A)) + 1]
-#define obj_xform_depth(A) pdf_mem[obj_data_ptr((A)) + 2]
+#define uc_hyph int_par(uc_hyph_code)
+#define cur_lang int_par(cur_lang_code)
+#define left_hyphen_min int_par(left_hyphen_min_code)
+#define right_hyphen_min int_par(right_hyphen_min_code)
+#define text_direction int_par(text_direction_code)
#define MAX_CHAIN_SIZE 13
-volatile memory_word *varmem = NULL;
+memory_word *volatile varmem = NULL;
#ifndef NDEBUG
char *varmem_sizes = NULL;
@@ -73,31 +54,28 @@ halfword rover = 0;
halfword free_chain[MAX_CHAIN_SIZE] = { null };
-static integer my_prealloc = 0;
+static int my_prealloc = 0;
int fix_node_lists = 1;
int free_error_seen = 0;
int copy_error_seen = 0;
-halfword slow_get_node(integer s); /* defined below */
+halfword slow_get_node(int s); /* defined below */
int copy_error(halfword p); /* define below */
-#undef link /* defined by cpascal.h */
-#define info(a) fixmem[(a)].hhlh
-#define link(a) fixmem[(a)].hhrh
-
#define fake_node 100
#define fake_node_size 2
#define fake_node_name "fake"
#define variable_node_size 2
-
-const char *node_fields_list[] = { "attr", "width", "depth", "height", "dir", "shift",
+const char *node_fields_list[] =
+ { "attr", "width", "depth", "height", "dir", "shift",
"glue_order", "glue_sign", "glue_set", "list", NULL
};
-const char *node_fields_rule[] = { "attr", "width", "depth", "height", "dir", NULL };
+const char *node_fields_rule[] =
+ { "attr", "width", "depth", "height", "dir", NULL };
const char *node_fields_insert[] =
{ "attr", "cost", "depth", "height", "spec", "list", NULL };
const char *node_fields_mark[] = { "attr", "class", "mark", NULL };
@@ -105,16 +83,18 @@ const char *node_fields_adjust[] = { "attr", "list", NULL };
const char *node_fields_disc[] = { "attr", "pre", "post", "replace", NULL };
const char *node_fields_math[] = { "attr", "surround", NULL };
const char *node_fields_glue[] = { "attr", "spec", "leader", NULL };
-const char *node_fields_kern[] = { "attr", "kern", NULL };
+const char *node_fields_kern[] = { "attr", "kern", "expansion_factor", NULL };
const char *node_fields_penalty[] = { "attr", "penalty", NULL };
+
const char *node_fields_unset[] =
{ "attr", "width", "depth", "height", "dir", "shrink",
"glue_order", "glue_sign", "stretch", "span", "list", NULL
};
const char *node_fields_margin_kern[] = { "attr", "width", "glyph", NULL };
+
const char *node_fields_glyph[] =
{ "attr", "char", "font", "lang", "left", "right", "uchyph",
- "components", "xoffset", "yoffset", NULL
+ "components", "xoffset", "yoffset", "width", "height", "depth", "expansion_factor", NULL
};
const char *node_fields_style[] = { "attr", "style", NULL };
const char *node_fields_choice[] =
@@ -155,8 +135,9 @@ const char *node_fields_action[] = { "action_type", "named_id", "action_id",
"file", "new_window", "data", "ref_count", NULL
};
const char *node_fields_attribute[] = { "number", "value", NULL };
+
const char *node_fields_glue_spec[] = { "width", "stretch", "shrink",
- "stretch_order", "shrink_order", "ref_count", NULL
+ "stretch_order", "shrink_order", "ref_count", "writable", NULL
};
const char *node_fields_attribute_list[] = { NULL };
@@ -173,32 +154,39 @@ const char *node_fields_whatsit_local_par[] =
const char *node_fields_whatsit_dir[] =
{ "attr", "dir", "level", "dvi_ptr", "dvi_h", NULL };
-const char *node_fields_whatsit_pdf_literal[] = { "attr", "mode", "data", NULL };
+const char *node_fields_whatsit_pdf_literal[] =
+ { "attr", "mode", "data", NULL };
const char *node_fields_whatsit_pdf_refobj[] = { "attr", "objnum", NULL };
const char *node_fields_whatsit_pdf_refxform[] =
- { "attr", "width", "height", "depth", "objnum", NULL };
+ { "attr", "width", "depth", "height", "objnum", NULL };
const char *node_fields_whatsit_pdf_refximage[] =
- { "attr", "width", "height", "depth", "objnum", NULL };
+ { "attr", "width", "depth", "height", "transform", "index", NULL };
const char *node_fields_whatsit_pdf_annot[] =
- { "attr", "width", "height", "depth", "objnum", "data", NULL };
+ { "attr", "width", "depth", "height", "objnum", "data", NULL };
const char *node_fields_whatsit_pdf_start_link[] =
- { "attr", "width", "height", "depth",
+ { "attr", "width", "depth", "height",
"objnum", "link_attr", "action", NULL
};
const char *node_fields_whatsit_pdf_end_link[] = { "attr", NULL };
-const char *node_fields_whatsit_pdf_dest[] = { "attr", "width", "height", "depth",
+
+const char *node_fields_whatsit_pdf_dest[] =
+ { "attr", "width", "depth", "height",
"named_id", "dest_id", "dest_type", "xyz_zoom", "objnum", NULL
};
-const char *node_fields_whatsit_pdf_thread[] = { "attr", "width", "height", "depth",
+
+const char *node_fields_whatsit_pdf_thread[] =
+ { "attr", "width", "depth", "height",
"named_id", "thread_id", "thread_attr", NULL
};
+
const char *node_fields_whatsit_pdf_start_thread[] =
- { "attr", "width", "height", "depth",
+ { "attr", "width", "depth", "height",
"named_id", "thread_id", "thread_attr", NULL
};
const char *node_fields_whatsit_pdf_end_thread[] = { "attr", NULL };
const char *node_fields_whatsit_pdf_save_pos[] = { "attr", NULL };
-const char *node_fields_whatsit_late_lua[] = { "attr", "reg", "data", "name", NULL };
+const char *node_fields_whatsit_late_lua[] =
+ { "attr", "reg", "data", "name", NULL };
const char *node_fields_whatsit_close_lua[] = { "attr", "reg", NULL };
const char *node_fields_whatsit_pdf_colorstack[] =
{ "attr", "stack", "cmd", "data", NULL };
@@ -349,18 +337,19 @@ node_info whatsit_node_data[] = {
#define last_whatsit_node user_defined_node
+@ @c
halfword new_node(int i, int j)
{
- register int s;
- register halfword n;
+ int s;
+ halfword n;
s = get_node_size(i, j);
n = get_node(s);
- /* it should be possible to do this memset at free_node() */
- /* type() and subtype() will be set below, and vlink() is
- set to null by get_node(), so we can do we clearing one
+ /* it should be possible to do this memset at |free_node()| */
+ /* type() and subtype() will be set below, and vlink() is
+ set to null by |get_node()|, so we can do we clearing one
word less than |s| */
(void) memset((void *) (varmem + n + 1), 0,
- (sizeof(memory_word) * (s - 1)));
+ (sizeof(memory_word) * ((unsigned) s - 1)));
switch (i) {
case glyph_node:
init_lang_data(n);
@@ -397,14 +386,14 @@ halfword new_node(int i, int j)
break;
case pseudo_line_node:
case shape_node:
- /* this is a trick that makes pseudo_files slightly slower,
- * but the overall allocation faster then an explicit test
- * at the top of new_node().
+ /* this is a trick that makes |pseudo_files| slightly slower,
+ but the overall allocation faster then an explicit test
+ at the top of |new_node()|.
*/
free_node(n, variable_node_size);
n = slow_get_node(j);
(void) memset((void *) (varmem + n + 1), 0,
- (sizeof(memory_word) * (j - 1)));
+ (sizeof(memory_word) * ((unsigned) j - 1)));
break;
default:
break;
@@ -441,10 +430,10 @@ halfword new_node(int i, int j)
if (nodetype_has_attributes(i)) {
build_attribute_list(n);
}
- type(n) = i;
- subtype(n) = j;
+ type(n) = (quarterword) i;
+ subtype(n) = (quarterword) j;
#ifdef DEBUG
- fprintf(stderr, "Alloc-ing %s node %d\n",
+ fprintf(DEBUG_OUT, "Alloc-ing %s node %d\n",
get_node_name(type(n), subtype(n)), (int) n);
#endif
return n;
@@ -474,15 +463,15 @@ halfword new_glyph_node(void)
}
-/* makes a duplicate of the node list that starts at |p| and returns a
- pointer to the new list */
-
-halfword copy_node_list(halfword p)
+@ makes a duplicate of the node list that starts at |p| and returns a
+ pointer to the new list
+@c
+halfword do_copy_node_list(halfword p, halfword end)
{
halfword q = null; /* previous position in new list */
halfword h = null; /* head of the list */
copy_error_seen = 0;
- while (p != null) {
+ while (p != end) {
register halfword s = copy_node(p);
if (h == null) {
h = s;
@@ -495,7 +484,13 @@ halfword copy_node_list(halfword p)
return h;
}
- /* make a dupe of a single node */
+halfword copy_node_list(halfword p)
+{
+ return do_copy_node_list(p, null);
+}
+
+@ make a dupe of a single node
+@c
halfword copy_node(const halfword p)
{
halfword r; /* current node being fabricated for new list */
@@ -509,7 +504,7 @@ halfword copy_node(const halfword p)
r = get_node(i);
(void) memcpy((void *) (varmem + r), (void *) (varmem + p),
- (sizeof(memory_word) * i));
+ (sizeof(memory_word) * (unsigned) i));
/* handle synctex extension */
switch (type(p)) {
@@ -627,13 +622,6 @@ halfword copy_node(const halfword p)
s = copy_node(delimiter(p));
delimiter(r) = s;
break;
- /*
- case style_node:
- case delim_node:
- case math_char_node:
- case math_text_char_node:
- break;
- */
case sub_box_node:
case sub_mlist_node:
s = copy_node_list(math_list(p));
@@ -712,18 +700,27 @@ halfword copy_node(const halfword p)
break;
}
break;
+#if 0
+ case style_node:
+ case delim_node:
+ case math_char_node:
+ case math_text_char_node:
+ break;
+#else
default:
+#endif
break;
}
break;
}
#ifdef DEBUG
- fprintf(stderr, "Alloc-ing %s node %d (copy of %d)\n",
+ fprintf(DEBUG_OUT, "Alloc-ing %s node %d (copy of %d)\n",
get_node_name(type(r), subtype(r)), (int) r, (int) p);
#endif
return r;
}
+@ @c
int valid_node(halfword p)
{
if (p > my_prealloc) {
@@ -734,11 +731,12 @@ int valid_node(halfword p)
return 1;
}
} else {
- return 1;
+ return 0;
}
return 0;
}
+@ @c
static void do_free_error(halfword p)
{
halfword r;
@@ -830,7 +828,7 @@ static void do_free_error(halfword p)
#endif
}
-static int free_error(halfword p)
+int free_error(halfword p)
{
assert(p > my_prealloc);
assert(p < var_mem_max);
@@ -844,6 +842,7 @@ static int free_error(halfword p)
}
+@ @c
static void do_copy_error(halfword p)
{
char errstr[255] = { 0 };
@@ -885,7 +884,7 @@ int copy_error(halfword p)
}
-
+@ @c
void flush_node(halfword p)
{
@@ -893,8 +892,8 @@ void flush_node(halfword p)
return;
#ifdef DEBUG
- fprintf(stderr, "Free-ing %s node %d\n", get_node_name(type(p), subtype(p)),
- (int) p);
+ fprintf(DEBUG_OUT, "Free-ing %s node %d\n",
+ get_node_name(type(p), subtype(p)), (int) p);
#endif
if (free_error(p))
return;
@@ -1021,7 +1020,7 @@ void flush_node(halfword p)
break;
default:
- tconfusion("ext3");
+ confusion("ext3");
return;
}
@@ -1116,6 +1115,7 @@ void flush_node(halfword p)
return;
}
+@ @c
void flush_node_list(halfword pp)
{ /* erase list of nodes starting at |p| */
register halfword p = pp;
@@ -1132,20 +1132,21 @@ void flush_node_list(halfword pp)
}
}
+@ @c
static int test_count = 1;
#define dorangetest(a,b,c) do { \
if (!(b>=0 && b<c)) { \
fprintf(stdout,"For node p:=%d, 0<=%d<%d (l.%d,r.%d)\n", \
(int)a, (int)b, (int)c, __LINE__,test_count); \
- tconfusion("dorangetest"); \
+ confusion("dorangetest"); \
} } while (0)
#define dotest(a,b,c) do { \
if (b!=c) { \
fprintf(stdout,"For node p:=%d, %d==%d (l.%d,r.%d)\n", \
(int)a, (int)b, (int)c, __LINE__,test_count); \
- tconfusion("dotest"); \
+ confusion("dotest"); \
} } while (0)
#define check_action_ref(a) { dorangetest(p,a,var_mem_max); }
@@ -1229,7 +1230,7 @@ void check_node(halfword p)
case 'd':
break;
default:
- tconfusion("extuser");
+ confusion("extuser");
break;
}
break;
@@ -1250,7 +1251,7 @@ void check_node(halfword p)
case local_par_node:
break;
default:
- tconfusion("ext3");
+ confusion("ext3");
}
break;
case margin_kern_node:
@@ -1330,7 +1331,8 @@ void check_node(halfword p)
}
}
-static void check_static_node_mem(void)
+@ @c
+void check_static_node_mem(void)
{
dotest(zero_glue, width(zero_glue), 0);
dotest(zero_glue, type(zero_glue), glue_spec_node);
@@ -1381,6 +1383,7 @@ static void check_static_node_mem(void)
dotest(fil_neg_glue, shrink_order(fil_neg_glue), normal);
}
+@ @c
void check_node_mem(void)
{
int i;
@@ -1395,6 +1398,7 @@ void check_node_mem(void)
test_count++;
}
+@ @c
void fix_node_list(halfword head)
{
halfword p, q;
@@ -1409,18 +1413,20 @@ void fix_node_list(halfword head)
}
}
-halfword get_node(integer s)
+@ @c
+halfword get_node(int s)
{
register halfword r;
-
- /*check_static_node_mem(); */
+#if 0
+ check_static_node_mem();
+#endif
assert(s < MAX_CHAIN_SIZE);
r = free_chain[s];
if (r != null) {
free_chain[s] = vlink(r);
#ifndef NDEBUG
- varmem_sizes[r] = s;
+ varmem_sizes[r] = (char) s;
#endif
vlink(r) = null;
var_used += s; /* maintain usage statistics */
@@ -1430,8 +1436,8 @@ halfword get_node(integer s)
return slow_get_node(s);
}
-#if 0 /* unused */
-static void print_free_chain(int c)
+@ @c
+void print_free_chain(int c)
{
halfword p = free_chain[c];
fprintf(stdout, "\nfree chain[%d] =\n ", c);
@@ -1441,9 +1447,9 @@ static void print_free_chain(int c)
}
fprintf(stdout, "null;\n");
}
-#endif
-void free_node(halfword p, integer s)
+@ @c
+void free_node(halfword p, int s)
{
if (p <= my_prealloc) {
@@ -1469,7 +1475,8 @@ void free_node(halfword p, integer s)
var_used -= s; /* maintain statistics */
}
-static void free_node_chain(halfword q, integer s)
+@ @c
+void free_node_chain(halfword q, int s)
{
register halfword p = q;
while (vlink(p) != null) {
@@ -1488,24 +1495,27 @@ static void free_node_chain(halfword q, integer s)
}
-void init_node_mem(halfword t)
+@ @c
+void init_node_mem(int t)
{
my_prealloc = var_mem_stat_max;
assert(whatsit_node_data[user_defined_node].id == user_defined_node);
assert(node_data[passive_node].id == passive_node);
- varmem = (memory_word *) realloc((void *) varmem, sizeof(memory_word) * t);
+ varmem =
+ (memory_word *) realloc((void *) varmem,
+ sizeof(memory_word) * (unsigned) t);
if (varmem == NULL) {
- overflow_string("node memory size", var_mem_max);
+ overflow("node memory size", (unsigned) var_mem_max);
}
- memset((void *) (varmem), 0, t * sizeof(memory_word));
+ memset((void *) (varmem), 0, (unsigned) t * sizeof(memory_word));
#ifndef NDEBUG
- varmem_sizes = (char *) realloc(varmem_sizes, sizeof(char) * t);
+ varmem_sizes = (char *) realloc(varmem_sizes, sizeof(char) * (unsigned) t);
if (varmem_sizes == NULL) {
- overflow_string("node memory size", var_mem_max);
+ overflow("node memory size", (unsigned) var_mem_max);
}
- memset((void *) varmem_sizes, 0, sizeof(char) * t);
+ memset((void *) varmem_sizes, 0, sizeof(char) * (unsigned) t);
#endif
var_mem_max = t;
rover = var_mem_stat_max + 1;
@@ -1616,6 +1626,7 @@ void init_node_mem(halfword t)
vlink(end_point + 4) = 0;
}
+@ @c
void dump_node_mem(void)
{
dump_int(var_mem_max);
@@ -1629,20 +1640,22 @@ void dump_node_mem(void)
dump_int(my_prealloc);
}
-/* it makes sense to enlarge the varmem array immediately */
-
+@ it makes sense to enlarge the varmem array immediately
+@c
void undump_node_mem(void)
{
- integer x;
+ int x;
undump_int(x);
undump_int(rover);
var_mem_max = (x < 100000 ? 100000 : x);
- varmem = xmallocarray(memory_word, var_mem_max);
- /*memset ((void *)varmem,0,x*sizeof(memory_word)); */
+ varmem = xmallocarray(memory_word, (unsigned) var_mem_max);
+#if 0
+ memset ((void *)varmem,0,x*sizeof(memory_word));
+#endif
undump_things(varmem[0], x);
#ifndef NDEBUG
- varmem_sizes = xmallocarray(char, var_mem_max);
- memset((void *) varmem_sizes, 0, var_mem_max * sizeof(char));
+ varmem_sizes = xmallocarray(char, (unsigned) var_mem_max);
+ memset((void *) varmem_sizes, 0, (unsigned) var_mem_max * sizeof(char));
undump_things(varmem_sizes[0], x);
#endif
undump_things(free_chain[0], MAX_CHAIN_SIZE);
@@ -1677,7 +1690,8 @@ void test_rovers(char *s)
# define test_rovers(a)
#endif
-halfword slow_get_node(integer s)
+@ @c
+halfword slow_get_node(int s)
{
register int t;
@@ -1705,7 +1719,7 @@ halfword slow_get_node(integer s)
test_rovers("taken");
assert(vlink(rover) < var_mem_max);
#ifndef NDEBUG
- varmem_sizes[r] = (s > 127 ? 127 : s);
+ varmem_sizes[r] = (char) (s > 127 ? 127 : s);
#endif
vlink(r) = null;
var_used += s; /* maintain usage statistics */
@@ -1739,19 +1753,23 @@ halfword slow_get_node(integer s)
x = (var_mem_max >> 2) + s;
varmem =
(memory_word *) realloc((void *) varmem,
- sizeof(memory_word) * (var_mem_max + x));
+ sizeof(memory_word) *
+ (unsigned) (var_mem_max + x));
if (varmem == NULL) {
- overflow_string("node memory size", var_mem_max);
+ overflow("node memory size", (unsigned) var_mem_max);
}
- memset((void *) (varmem + var_mem_max), 0, x * sizeof(memory_word));
+ memset((void *) (varmem + var_mem_max), 0,
+ (unsigned) x * sizeof(memory_word));
#ifndef NDEBUG
varmem_sizes =
- (char *) realloc(varmem_sizes, sizeof(char) * (var_mem_max + x));
+ (char *) realloc(varmem_sizes,
+ sizeof(char) * (unsigned) (var_mem_max + x));
if (varmem_sizes == NULL) {
- overflow_string("node memory size", var_mem_max);
+ overflow("node memory size", (unsigned) var_mem_max);
}
- memset((void *) (varmem_sizes + var_mem_max), 0, x * sizeof(char));
+ memset((void *) (varmem_sizes + var_mem_max), 0,
+ (unsigned) (x) * sizeof(char));
#endif
/* todo ? it is perhaps possible to merge the new memory with an existing rover */
@@ -1768,6 +1786,7 @@ halfword slow_get_node(integer s)
}
}
+@ @c
char *sprint_node_mem_usage(void)
{
int i, b;
@@ -1797,7 +1816,7 @@ char *sprint_node_mem_usage(void)
snprintf(msg, 255, "%s%d %s", (b ? ", " : ""), (int) node_counts[i],
get_node_name((i > last_normal_node ? whatsit_node : i),
j));
- ss = xmalloc(strlen(s) + strlen(msg) + 1);
+ ss = xmalloc((unsigned) (strlen(s) + strlen(msg) + 1));
strcpy(ss, s);
strcat(ss, msg);
free(s);
@@ -1811,13 +1830,14 @@ char *sprint_node_mem_usage(void)
return s;
}
+@ @c
halfword list_node_mem_usage(void)
{
halfword i, j;
halfword p = null, q = null;
#ifndef NDEBUG
- char *saved_varmem_sizes = xmallocarray(char, var_mem_max);
- memcpy(saved_varmem_sizes, varmem_sizes, var_mem_max);
+ char *saved_varmem_sizes = xmallocarray(char, (unsigned) var_mem_max);
+ memcpy(saved_varmem_sizes, varmem_sizes, (size_t) var_mem_max);
for (i = my_prealloc + 1; i < (var_mem_max - 1); i++) {
if (saved_varmem_sizes[i] > 0) {
j = copy_node(i);
@@ -1834,34 +1854,34 @@ halfword list_node_mem_usage(void)
return q;
}
+@ @c
void print_node_mem_stats(void)
{
int i, b;
halfword j;
char msg[256];
char *s;
- integer free_chain_counts[MAX_CHAIN_SIZE] = { 0 };
- snprintf(msg, 255, "node memory in use: %d words out of %d",
- (int) (var_used + my_prealloc), (int) var_mem_max);
+ int free_chain_counts[MAX_CHAIN_SIZE] = { 0 };
+ snprintf(msg, 255, " %d words of node memory still in use:",
+ (int) (var_used + my_prealloc));
tprint_nl(msg);
- tprint_nl("rapidly available: ");
+ s = sprint_node_mem_usage();
+ tprint_nl(" ");
+ tprint(s);
+ free(s);
+ tprint(" nodes");
+ tprint_nl(" avail lists: ");
b = 0;
for (i = 1; i < MAX_CHAIN_SIZE; i++) {
for (j = free_chain[i]; j != null; j = vlink(j))
free_chain_counts[i]++;
if (free_chain_counts[i] > 0) {
- snprintf(msg, 255, "%s%d:%d", (b ? ", " : ""), i,
+ snprintf(msg, 255, "%s%d:%d", (b ? "," : ""), i,
(int) free_chain_counts[i]);
tprint(msg);
b = 1;
}
}
- tprint(" nodes");
- s = sprint_node_mem_usage();
- tprint_nl("current usage: ");
- tprint(s);
- free(s);
- tprint(" nodes");
print_nlp(); /* newline, if needed */
}
@@ -1876,57 +1896,19 @@ halfword new_span_node(halfword n, int s, scaled w)
return p;
}
-halfword string_to_pseudo(integer l, integer pool_ptr, integer nl)
-{
- halfword i, r, q = null;
- four_quarters w;
- int sz;
- halfword h = new_node(pseudo_file_node, 0);
- while (l < pool_ptr) {
- int m = l;
- while ((l < pool_ptr) && (str_pool[l] != nl))
- l++;
- sz = (l - m + 7) / 4;
- if (sz == 1)
- sz = 2;
- r = new_node(pseudo_line_node, sz);
- i = r;
- while (--sz > 1) {
- w.b0 = str_pool[m++];
- w.b1 = str_pool[m++];
- w.b2 = str_pool[m++];
- w.b3 = str_pool[m++];
- varmem[++i].qqqq = w;
- }
- w.b0 = (l > m ? str_pool[m++] : ' ');
- w.b1 = (l > m ? str_pool[m++] : ' ');
- w.b2 = (l > m ? str_pool[m++] : ' ');
- w.b3 = (l > m ? str_pool[m] : ' ');
- varmem[++i].qqqq = w;
- if (pseudo_lines(h) == null) {
- pseudo_lines(h) = r;
- q = r;
- } else {
- couple_nodes(q, r);
- }
- q = vlink(q);
- if (str_pool[l] == nl)
- l++;
- }
- return h;
-}
-
-/* attribute stuff */
+@* Attribute stuff.
+@c
static halfword new_attribute_node(unsigned int i, int v)
{
register halfword r = get_node(attribute_node_size);
type(r) = attribute_node;
- attribute_id(r) = i;
+ attribute_id(r) = (halfword) i;
attribute_value(r) = v;
return r;
}
+@ @c
halfword copy_attribute_list(halfword n)
{
halfword q = get_node(attribute_node_size);
@@ -1946,6 +1928,7 @@ halfword copy_attribute_list(halfword n)
return q;
}
+@ @c
void update_attribute_cache(void)
{
halfword p;
@@ -1955,9 +1938,9 @@ void update_attribute_cache(void)
attr_list_ref(attr_list_cache) = 0;
p = attr_list_cache;
for (i = 0; i <= max_used_attr; i++) {
- register int v = get_attribute(i);
+ register int v = attribute(i);
if (v > UNUSED_ATTRIBUTE) {
- register halfword r = new_attribute_node(i, v);
+ register halfword r = new_attribute_node((unsigned) i, v);
vlink(p) = r;
p = r;
}
@@ -1969,6 +1952,7 @@ void update_attribute_cache(void)
return;
}
+@ @c
void build_attribute_list(halfword b)
{
if (max_used_attr >= 0) {
@@ -1980,19 +1964,20 @@ void build_attribute_list(halfword b)
attr_list_ref(attr_list_cache)++;
node_attr(b) = attr_list_cache;
#ifdef DEBUG
- fprintf(stderr, "Added attrlist (%d) to node %d (count=%d)\n",
+ fprintf(DEBUG_OUT, "Added attrlist (%d) to node %d (count=%d)\n",
node_attr(b), b, attr_list_ref(attr_list_cache));
#endif
}
}
+@ @c
void delete_attribute_ref(halfword b)
{
if (b != null) {
assert(type(b) == attribute_list_node);
attr_list_ref(b)--;
#ifdef DEBUG
- fprintf(stderr, "Removed attrlistref (%d) (count=%d)\n", b,
+ fprintf(DEBUG_OUT, "Removed attrlistref (%d) (count=%d)\n", b,
attr_list_ref(b));
#endif
if (attr_list_ref(b) == 0) {
@@ -2006,17 +1991,17 @@ void delete_attribute_ref(halfword b)
}
}
-/* |p| is an attr list head, or zero */
-
+@ |p| is an attr list head, or zero
+@c
halfword do_set_attribute(halfword p, int i, int val)
{
register halfword q;
register int j = 0;
- if (p == null) { /* add a new head & node */
+ if (p == null) { /* add a new head \& node */
q = get_node(attribute_node_size);
type(q) = attribute_list_node;
attr_list_ref(q) = 1;
- p = new_attribute_node(i, val);
+ p = new_attribute_node((unsigned) i, val);
vlink(q) = p;
return q;
}
@@ -2038,13 +2023,14 @@ halfword do_set_attribute(halfword p, int i, int val)
if (attribute_id(vlink(p)) == i) {
attribute_value(vlink(p)) = val;
} else { /* add a new node */
- halfword r = new_attribute_node(i, val);
+ halfword r = new_attribute_node((unsigned) i, val);
vlink(r) = vlink(p);
vlink(p) = r;
}
return q;
}
+@ @c
void set_attribute(halfword n, int i, int val)
{
register halfword p;
@@ -2052,12 +2038,12 @@ void set_attribute(halfword n, int i, int val)
if (!nodetype_has_attributes(type(n)))
return;
p = node_attr(n);
- if (p == null) { /* add a new head & node */
+ if (p == null) { /* add a new head \& node */
p = get_node(attribute_node_size);
type(p) = attribute_list_node;
attr_list_ref(p) = 1;
node_attr(n) = p;
- p = new_attribute_node(i, val);
+ p = new_attribute_node((unsigned) i, val);
vlink(node_attr(n)) = p;
return;
}
@@ -2090,7 +2076,7 @@ void set_attribute(halfword n, int i, int val)
if (attribute_id(vlink(p)) == i) {
attribute_value(vlink(p)) = val;
} else { /* add a new node */
- halfword r = new_attribute_node(i, val);
+ halfword r = new_attribute_node((unsigned) i, val);
vlink(r) = vlink(p);
vlink(p) = r;
}
@@ -2098,6 +2084,7 @@ void set_attribute(halfword n, int i, int val)
}
+@ @c
int unset_attribute(halfword n, int i, int val)
{
register halfword p;
@@ -2109,6 +2096,12 @@ int unset_attribute(halfword n, int i, int val)
p = node_attr(n);
if (p == null)
return UNUSED_ATTRIBUTE;
+ if (attr_list_ref(p) == 0) {
+ fprintf(stdout,
+ "Node %d has an attribute list that is free already\n",
+ (int) n);
+ return UNUSED_ATTRIBUTE;
+ }
assert(vlink(p) != null);
while (vlink(p) != null) {
t = attribute_id(vlink(p));
@@ -2125,19 +2118,15 @@ int unset_attribute(halfword n, int i, int val)
return UNUSED_ATTRIBUTE;
/* if we are still here, the attribute exists */
p = node_attr(n);
- if (attr_list_ref(p) != 1) {
+ if (attr_list_ref(p) > 1 || p == attr_list_cache) {
+ halfword q = copy_attribute_list(p);
if (attr_list_ref(p) > 1) {
- p = copy_attribute_list(p);
delete_attribute_ref(node_attr(n));
- node_attr(n) = p;
- } else {
- fprintf(stdout,
- "Node %d has an attribute list that is free already\n",
- (int) n);
}
- attr_list_ref(p) = 1;
+ attr_list_ref(q) = 1;
+ node_attr(n) = q;
}
- p = vlink(p);
+ p = vlink(node_attr(n));
while (j-- > 0)
p = vlink(p);
t = attribute_value(p);
@@ -2147,6 +2136,7 @@ int unset_attribute(halfword n, int i, int val)
return t;
}
+@ @c
int has_attribute(halfword n, int i, int val)
{
register halfword p;
@@ -2170,6 +2160,7 @@ int has_attribute(halfword n, int i, int val)
return UNUSED_ATTRIBUTE;
}
+@ @c
void print_short_node_contents(halfword p)
{
switch (type(p)) {
@@ -2204,25 +2195,25 @@ void print_short_node_contents(halfword p)
}
-static void show_pdftex_whatsit_rule_spec(integer p)
+@ @c
+void show_pdftex_whatsit_rule_spec(int p)
{
tprint("(");
- print_rule_dimen(pdf_height(p));
+ print_rule_dimen(height(p));
print_char('+');
- print_rule_dimen(pdf_depth(p));
+ print_rule_dimen(depth(p));
tprint(")x");
- print_rule_dimen(pdf_width(p));
+ print_rule_dimen(width(p));
}
-/*
-Each new type of node that appears in our data structure must be capable
+
+@ 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.
-*/
-
+@c
static void print_write_whatsit(const char *s, pointer p)
{
tprint_esc(s);
@@ -2235,7 +2226,8 @@ static void print_write_whatsit(const char *s, pointer p)
}
-static void show_whatsit_node(integer p)
+@ @c
+void show_whatsit_node(int p)
{
switch (subtype(p)) {
case open_node:
@@ -2264,6 +2256,7 @@ static void show_whatsit_node(integer p)
print_char(' ');
print_dir(dir_dir(p));
}
+ break;
case local_par_node:
tprint_esc("whatsit");
append_char('.');
@@ -2285,7 +2278,7 @@ static void show_whatsit_node(integer p)
} else {
append_char('.');
show_node_list(local_box_left(p));
- decr(pool_ptr);
+ decr(cur_length);
}
print_ln();
print_current_string();
@@ -2295,9 +2288,9 @@ static void show_whatsit_node(integer p)
} else {
append_char('.');
show_node_list(local_box_right(p));
- decr(pool_ptr);
+ decr(cur_length);
}
- decr(pool_ptr);
+ decr(cur_length);
break;
case pdf_literal_node:
show_pdf_literal(p);
@@ -2319,7 +2312,7 @@ static void show_whatsit_node(integer p)
tprint(" current");
break;
default:
- tconfusion("pdfcolorstack");
+ confusion("pdfcolorstack");
break;
}
if (pdf_colorstack_cmd(p) <= colorstack_data)
@@ -2349,34 +2342,39 @@ static void show_whatsit_node(integer p)
break;
case pdf_refobj_node:
tprint_esc("pdfrefobj");
- if (obj_obj_is_stream(pdf_obj_objnum(p)) > 0) {
- if (obj_obj_stream_attr(pdf_obj_objnum(p)) != null) {
+ if (obj_obj_is_stream(static_pdf, pdf_obj_objnum(p))) {
+ if (obj_obj_stream_attr(static_pdf, pdf_obj_objnum(p)) != LUA_NOREF) {
tprint(" attr");
- print_mark(obj_obj_stream_attr(pdf_obj_objnum(p)));
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX,
+ obj_obj_stream_attr(static_pdf, pdf_obj_objnum(p)));
+ print_char(' ');
+ tprint((const char *) lua_tostring(Luas, -1));
+ lua_pop(Luas, 1);
}
tprint(" stream");
}
- if (obj_obj_is_file(pdf_obj_objnum(p)) > 0)
+ if (obj_obj_is_file(static_pdf, pdf_obj_objnum(p)))
tprint(" file");
- print_mark(obj_obj_data(pdf_obj_objnum(p)));
+ if (obj_obj_data(static_pdf, pdf_obj_objnum(p)) != LUA_NOREF) {
+ lua_rawgeti(Luas, LUA_REGISTRYINDEX,
+ obj_obj_data(static_pdf, pdf_obj_objnum(p)));
+ print_char(' ');
+ tprint((const char *) lua_tostring(Luas, -1));
+ lua_pop(Luas, 1);
+ }
break;
case pdf_refxform_node:
- tprint_esc("pdfrefxform");
- print_char('(');
- print_scaled(obj_xform_height(pdf_xform_objnum(p)));
- print_char('+');
- print_scaled(obj_xform_depth(pdf_xform_objnum(p)));
- tprint(")x");
- print_scaled(obj_xform_width(pdf_xform_objnum(p)));
- break;
case pdf_refximage_node:
- tprint_esc("pdfrefximage");
+ if (subtype(p) == pdf_refxform_node)
+ tprint_esc("pdfrefxform");
+ else
+ tprint_esc("pdfrefximage");
tprint("(");
- print_scaled(pdf_height(p));
+ print_scaled(height(p));
print_char('+');
- print_scaled(pdf_depth(p));
+ print_scaled(depth(p));
tprint(")x");
- print_scaled(pdf_width(p));
+ print_scaled(width(p));
break;
case pdf_annot_node:
tprint_esc("pdfannot");
@@ -2425,8 +2423,7 @@ static void show_whatsit_node(integer p)
}
break;
default:
- pdf_error(maketexstring("displaying"),
- maketexstring("unknown action type"));
+ pdf_error("displaying", "unknown action type");
break;
}
break;
@@ -2485,11 +2482,11 @@ static void show_whatsit_node(integer p)
else
tprint_esc("pdfstartthread");
tprint("(");
- print_rule_dimen(pdf_height(p));
+ print_rule_dimen(height(p));
print_char('+');
- print_rule_dimen(pdf_depth(p));
+ print_rule_dimen(depth(p));
tprint(")x");
- print_rule_dimen(pdf_width(p));
+ print_rule_dimen(width(p));
if (pdf_thread_attr(p) != null) {
tprint(" attr");
print_mark(pdf_thread_attr(p));
@@ -2541,8 +2538,8 @@ static void show_whatsit_node(integer p)
}
-/*
- Now we are ready for |show_node_list| itself. This procedure has been
+
+@ 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
@@ -2552,23 +2549,23 @@ static void show_whatsit_node(integer p)
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.
-*/
-/* |str_room| need not be checked; see |show_box| */
-/* Recursive calls on |show_node_list| therefore use the following pattern: */
+@ |str_room| need not be checked; see |show_box|
+@ Recursive calls on |show_node_list| therefore use the following pattern:
+@c
#define node_list_display(A) do { \
append_char('.'); \
show_node_list(A); \
flush_char(); \
} while (0)
-void show_node_list(integer p)
+void show_node_list(int p)
{ /* prints a node list symbolically */
- integer n; /* the number of items already printed at this level */
+ int n; /* the number of items already printed at this level */
real g; /* a glue ratio, as a floating point number */
- if (cur_length > depth_threshold) {
+ if ((int) cur_length > depth_threshold) {
if (p > null)
tprint(" []"); /* indicate that there's been some truncation */
return;
@@ -2577,18 +2574,18 @@ void show_node_list(integer p)
while (p != null) {
print_ln();
print_current_string(); /* display the nesting history */
- if (int_par(param_tracing_online_code) < -2)
+ if (int_par(tracing_online_code) < -2)
print_int(p);
incr(n);
if (n > breadth_max) { /* time to stop */
tprint("etc.");
return;
}
- /* @<Display node |p|@> */
+ /* Display node |p| */
if (is_char_node(p)) {
print_font_and_char(p);
if (is_ligature(p)) {
- /* @<Display ligature |p|@>; */
+ /* Display ligature |p|; */
tprint(" (ligature ");
if (is_leftboundary(p))
print_char('|');
@@ -2603,7 +2600,7 @@ void show_node_list(integer p)
case hlist_node:
case vlist_node:
case unset_node:
- /* @<Display box |p|@>; */
+ /* Display box |p|; */
if (type(p) == hlist_node)
tprint_esc("h");
else if (type(p) == vlist_node)
@@ -2617,7 +2614,7 @@ void show_node_list(integer p)
tprint(")x");
print_scaled(width(p));
if (type(p) == unset_node) {
- /* @<Display special fields of the unset node |p|@>; */
+ /* Display special fields of the unset node |p|; */
if (span_count(p) != min_quarterword) {
tprint(" (");
print_int(span_count(p) + 1);
@@ -2625,14 +2622,14 @@ void show_node_list(integer p)
}
if (glue_stretch(p) != 0) {
tprint(", stretch ");
- print_glue(glue_stretch(p), glue_order(p), 0);
+ print_glue(glue_stretch(p), glue_order(p), NULL);
}
if (glue_shrink(p) != 0) {
tprint(", shrink ");
- print_glue(glue_shrink(p), glue_sign(p), 0);
+ print_glue(glue_shrink(p), glue_sign(p), NULL);
}
} else {
- /*<Display the value of |glue_set(p)|@> */
+ /* Display the value of |glue_set(p)| */
/* 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
@@ -2652,9 +2649,9 @@ void show_node_list(integer p)
print_char('>');
else
tprint("< -");
- print_glue(20000 * unity, glue_order(p), 0);
+ print_glue(20000 * unity, glue_order(p), NULL);
} else {
- print_glue(round(unity * g), glue_order(p), 0);
+ print_glue(round(unity * g), glue_order(p), NULL);
}
}
@@ -2668,7 +2665,7 @@ void show_node_list(integer p)
node_list_display(list_ptr(p)); /* recursive call */
break;
case rule_node:
- /* @<Display rule |p|@>; */
+ /* Display rule |p|; */
tprint_esc("rule(");
print_rule_dimen(height(p));
print_char('+');
@@ -2677,13 +2674,13 @@ void show_node_list(integer p)
print_rule_dimen(width(p));
break;
case ins_node:
- /* @<Display insertion |p|@>; */
+ /* Display insertion |p|; */
tprint_esc("insert");
print_int(subtype(p));
tprint(", natural size ");
print_scaled(height(p));
tprint("; split(");
- print_spec(split_top_ptr(p), 0);
+ print_spec(split_top_ptr(p), NULL);
print_char(',');
print_scaled(depth(p));
tprint("); float cost ");
@@ -2694,35 +2691,51 @@ void show_node_list(integer p)
show_whatsit_node(p);
break;
case glue_node:
- /* @<Display glue |p|@>; */
+ /* Display glue |p|; */
if (subtype(p) >= a_leaders) {
- /* @<Display leaders |p|@>; */
+ /* Display leaders |p|; */
tprint_esc("");
- if (subtype(p) == c_leaders)
+ switch (subtype(p)) {
+ case a_leaders:
+ break;
+ case c_leaders:
print_char('c');
- else if (subtype(p) == x_leaders)
+ break;
+ case x_leaders:
print_char('x');
+ break;
+ case g_leaders:
+ print_char('g');
+ break;
+ default:
+ assert(0);
+ }
tprint("leaders ");
- print_spec(glue_ptr(p), 0);
+ print_spec(glue_ptr(p), NULL);
node_list_display(leader_ptr(p)); /* recursive call */
} else {
tprint_esc("glue");
if (subtype(p) != normal) {
print_char('(');
- if (subtype(p) < cond_math_glue)
- print_skip_param(subtype(p) - 1);
- else if (subtype(p) == cond_math_glue)
+ if ((subtype(p) - 1) < thin_mu_skip_code) {
+ print_cmd_chr(assign_glue_cmd,
+ glue_base + (subtype(p) - 1));
+ } else if (subtype(p) < cond_math_glue) {
+ print_cmd_chr(assign_mu_glue_cmd,
+ glue_base + (subtype(p) - 1));
+ } else if (subtype(p) == cond_math_glue) {
tprint_esc("nonscript");
- else
+ } else {
tprint_esc("mskip");
+ }
print_char(')');
}
if (subtype(p) != cond_math_glue) {
print_char(' ');
if (subtype(p) < cond_math_glue)
- print_spec(glue_ptr(p), 0);
+ print_spec(glue_ptr(p), NULL);
else
- print_spec(glue_ptr(p), maketexstring("mu"));
+ print_spec(glue_ptr(p), "mu");
}
}
break;
@@ -2735,7 +2748,7 @@ void show_node_list(integer p)
tprint(" (right margin)");
break;
case kern_node:
- /* @<Display kern |p|@>; */
+ /* Display kern |p|; */
/* An ``explicit'' kern value is indicated implicitly by an explicit space. */
if (subtype(p) != mu_glue) {
tprint_esc("kern");
@@ -2751,7 +2764,7 @@ void show_node_list(integer p)
}
break;
case math_node:
- /* @<Display math node |p|@>; */
+ /* Display math node |p|; */
tprint_esc("math");
if (subtype(p) == before)
tprint("on");
@@ -2763,12 +2776,12 @@ void show_node_list(integer p)
}
break;
case penalty_node:
- /* @<Display penalty |p|@>; */
+ /* Display penalty |p|; */
tprint_esc("penalty ");
print_int(penalty(p));
break;
case disc_node:
- /* @<Display discretionary |p|@>; */
+ /* Display discretionary |p|; */
/* The |post_break| list of a discretionary node is indicated by a prefixed
`\.{\char'174}' instead of the `\..' before the |pre_break| list. */
tprint_esc("discretionary");
@@ -2782,7 +2795,7 @@ void show_node_list(integer p)
flush_char(); /* recursive call */
break;
case mark_node:
- /* @<Display mark |p|@>; */
+ /* Display mark |p|; */
tprint_esc("mark");
if (mark_class(p) != 0) {
print_char('s');
@@ -2791,7 +2804,7 @@ void show_node_list(integer p)
print_mark(mark_ptr(p));
break;
case adjust_node:
- /* @<Display adjustment |p|@>; */
+ /* Display adjustment |p|; */
tprint_esc("vadjust");
if (adjust_pre(p) != 0)
tprint(" pre ");
@@ -2806,9 +2819,10 @@ void show_node_list(integer p)
}
}
-/* This routine finds the 'base' width of a horizontal box, using the same logic
+@ This routine finds the 'base' width of a horizontal box, using the same logic
that \TeX82 used for \.{\\predisplaywidth} */
+@c
pointer actual_box_width(pointer r, scaled base_width)
{
scaled w; /* calculated |size| */
@@ -2866,7 +2880,7 @@ pointer actual_box_width(pointer r, scaled base_width)
case whatsit_node:
if ((subtype(p) == pdf_refxform_node)
|| (subtype(p) == pdf_refximage_node))
- d = pdf_width(p);
+ d = width(p);
else
d = 0;
break;
@@ -2890,3 +2904,488 @@ pointer actual_box_width(pointer r, scaled base_width)
}
return w;
}
+
+
+@ @c
+halfword tail_of_list(halfword p)
+{
+ halfword q = p;
+ while (vlink(q) != null)
+ q = vlink(q);
+ return q;
+}
+
+
+@ |delete_glue_ref| is called when a pointer to a glue
+ specification is being withdrawn.
+
+@c
+#define fast_delete_glue_ref(A) do { \
+ if (glue_ref_count(A)==null) { \
+ flush_node(A); \
+ } else { \
+ decr(glue_ref_count(A)); \
+ } \
+ } while (0)
+
+void delete_glue_ref(halfword p)
+{ /* |p| points to a glue specification */
+ assert(type(p) == glue_spec_node);
+ fast_delete_glue_ref(p);
+}
+
+@ @c
+int var_used;
+halfword temp_ptr; /* a pointer variable for occasional emergency use */
+
+
+@ Attribute lists need two extra globals to increase processing efficiency.
+|max_used_attr| limits the test loop that checks for set attributes, and
+|attr_list_cache| contains a pointer to an already created attribute list. It is
+set to the special value |cache_disabled| when the current value can no longer be
+trusted: after an assignment to an attribute register, and after a group has
+ended.
+
+@c
+int max_used_attr; /* maximum assigned attribute id */
+halfword attr_list_cache;
+
+@ From the computer's standpoint, \TeX's chief mission is to create
+horizontal and vertical lists. We shall now investigate how the elements
+of these lists are represented internally as nodes in the dynamic memory.
+
+A horizontal or vertical list is linked together by |link| fields in
+the first word of each node. Individual nodes represent boxes, glue,
+penalties, or special things like discretionary hyphens; because of this
+variety, some nodes are longer than others, and we must distinguish different
+kinds of nodes. We do this by putting a `|type|' field in the first word,
+together with the link and an optional `|subtype|'.
+
+
+@ Character nodes appear only in horizontal lists, never in vertical lists.
+
+An |hlist_node| stands for a box that was made from a horizontal list.
+Each |hlist_node| is seven words long, and contains the following fields
+(in addition to the mandatory |type| and |link|, which we shall not
+mention explicitly when discussing the other node types): The |height| and
+|width| and |depth| are scaled integers denoting the dimensions of the
+box. There is also a |shift_amount| field, a scaled integer indicating
+how much this box should be lowered (if it appears in a horizontal list),
+or how much it should be moved to the right (if it appears in a vertical
+list). There is a |list_ptr| field, which points to the beginning of the
+list from which this box was fabricated; if |list_ptr| is |null|, the box
+is empty. Finally, there are three fields that represent the setting of
+the glue: |glue_set(p)| is a word of type |glue_ratio| that represents
+the proportionality constant for glue setting; |glue_sign(p)| is
+|stretching| or |shrinking| or |normal| depending on whether or not the
+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.
+
+@ The |new_null_box| function returns a pointer to an |hlist_node| in
+which all subfields have the values corresponding to `\.{\\hbox\{\}}'.
+The |subtype| field is set to |min_quarterword|, since that's the desired
+|span_count| value if this |hlist_node| is changed to an |unset_node|.
+
+@c
+halfword new_null_box(void)
+{ /* creates a new box node */
+ halfword p; /* the new node */
+ p = new_node(hlist_node, min_quarterword);
+ box_dir(p) = text_direction;
+ return p;
+}
+
+
+@ A |vlist_node| is like an |hlist_node| in all respects except that it
+contains a vertical list.
+
+
+@ 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
+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.
+
+@ A new rule node is delivered by the |new_rule| function. It
+makes all the dimensions ``running,'' so you have to change the
+ones that are not allowed to run.
+
+@c
+halfword new_rule(void)
+{
+ halfword p; /* the new node */
+ p = new_node(rule_node, 0); /* the |subtype| is not used */
+ return p;
+}
+
+
+@ Insertions are represented by |ins_node| records, where the |subtype|
+indicates the corresponding box number. For example, `\.{\\insert 250}'
+leads to an |ins_node| whose |subtype| is |250+min_quarterword|.
+The |height| field of an |ins_node| is slightly misnamed; it actually holds
+the natural height plus depth of the vertical list being inserted.
+The |depth| field holds the |split_max_depth| to be used in case this
+insertion is split, and the |split_top_ptr| points to the corresponding
+|split_top_skip|. The |float_cost| field holds the |floating_penalty| that
+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.
+
+@ A |mark_node| has a |mark_ptr| field that points to the reference count
+of a token list that contains the user's \.{\\mark} text.
+In addition there is a |mark_class| field that contains the mark class.
+
+@ An |adjust_node|, which occurs only in horizontal lists,
+specifies material that will be moved out into the surrounding
+vertical list; i.e., it is used to implement \TeX's `\.{\\vadjust}'
+operation. The |adjust_ptr| field points to the vlist containing this
+material.
+
+@ A |glyph_node|, which occurs only in horizontal lists, specifies a
+glyph in a particular font, along with its attribute list. Older
+versions of \TeX\ could use token memory for characters, because the
+font,char combination would fit in a single word (both values were
+required to be strictly less than $2^{16}$). In LuaTeX, room is
+needed for characters that are larger than that, as well as a pointer
+to a potential attribute list, and the two displacement values.
+
+In turn, that made the node so large that it made sense to merge
+ligature glyphs as well, as that requires only one extra pointer. A
+few extra classes of glyph nodes will be introduced later. The
+unification of all those types makes it easier to manipulate lists of
+glyphs. The subtype differentiates various glyph kinds.
+
+First, here is a function that returns a pointer to a glyph node for a given
+glyph in a given font. If that glyph doesn't exist, |null| is returned
+instead. Nodes of this subtype are directly created only for accents
+and their base (through |make_accent|), and math nucleus items (in the
+conversion from |mlist| to |hlist|).
+
+@c
+halfword new_glyph(int f, int c)
+{
+ halfword p = null; /* the new node */
+ if ((f == 0) || (char_exists(f, c))) {
+ p = new_glyph_node();
+ set_to_glyph(p);
+ font(p) = f;
+ character(p) = c;
+ }
+ return p;
+}
+
+
+@ A subset of the glyphs nodes represent ligatures: characters
+fabricated from the interaction of two or more actual characters. The
+characters that generated the ligature have not been forgotten, since
+they are needed for diagnostic messages; the |lig_ptr| field points to
+a linked list of character nodes for all original characters that have
+been deleted. (This list might be empty if the characters that
+generated the ligature were retained in other nodes.)
+
+The |subtype| field of these |glyph_node|s is 1, plus 2 and/or 1 if
+the original source of the ligature included implicit left and/or
+right boundaries. These nodes are created by the C function |new_ligkern|.
+
+A third general type of glyphs could be called a character, as it
+only appears in lists that are not yet processed by the ligaturing and
+kerning steps of the program.
+
+|main_control| inserts these, and they are later converted to
+|subtype_normal| by |new_ligkern|.
+
+@c
+quarterword norm_min(int h)
+{
+ if (h <= 0)
+ return 1;
+ else if (h >= 255)
+ return 255;
+ else
+ return (quarterword) h;
+}
+
+halfword new_char(int f, int c)
+{
+ halfword p; /* the new node */
+ p = new_glyph_node();
+ set_to_character(p);
+ font(p) = f;
+ character(p) = c;
+ lang_data(p) =
+ make_lang_data(uc_hyph, cur_lang, left_hyphen_min, right_hyphen_min);
+ return p;
+}
+
+
+@ Left and right ghost glyph nodes are the result of \.{\\leftghost}
+and \.{\\rightghost}, respectively. They are going to be removed by
+|new_ligkern|, at the end of which they are no longer needed.
+
+@ Here are a few handy helpers used by the list output routines.
+
+@c
+scaled glyph_width(halfword p)
+{
+ scaled w;
+ w = char_width(font(p), character(p));
+ return w;
+}
+
+scaled glyph_height(halfword p)
+{
+ scaled w;
+ w = char_height(font(p), character(p)) + y_displace(p);
+ if (w < 0)
+ w = 0;
+ return w;
+}
+
+scaled glyph_depth(halfword p)
+{
+ scaled w;
+ w = char_depth(font(p), character(p));
+ if (y_displace(p) > 0)
+ w = w - y_displace(p);
+ if (w < 0)
+ w = 0;
+ return w;
+}
+
+
+@ A |disc_node|, which occurs only in horizontal lists, specifies a
+``dis\-cretion\-ary'' line break. If such a break occurs at node |p|, the text
+that starts at |pre_break(p)| will precede the break, the text that starts at
+|post_break(p)| will follow the break, and text that appears in
+|no_break(p)| nodes will be ignored. For example, an ordinary
+discretionary hyphen, indicated by `\.{\\-}', yields a |disc_node| with
+|pre_break| pointing to a |char_node| containing a hyphen, |post_break=null|,
+and |no_break=null|.
+
+{TODO: Knuth said: All three of the discretionary texts must be lists
+that consist entirely of character, kern, box and rule nodes.}
+
+If |subtype(p)=automatic_disc|, the |ex_hyphen_penalty| will be charged for this
+break. Otherwise the |hyphen_penalty| will be charged. The texts will
+actually be substituted into the list by the line-breaking algorithm if it
+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.
+
+@c
+halfword new_disc(void)
+{ /* creates an empty |disc_node| */
+ halfword p; /* the new node */
+ p = new_node(disc_node, 0);
+ return p;
+}
+
+@ A |whatsit_node| is a wild card reserved for extensions to \TeX. The
+|subtype| field in its first word says what `\\{whatsit}' it is, and
+implicitly determines the node size (which must be 2 or more) and the
+format of the remaining words. When a |whatsit_node| is encountered
+in a list, special actions are invoked; knowledgeable people who are
+careful not to mess up the rest of \TeX\ are able to make \TeX\ do new
+things by adding code at the end of the program. For example, there
+might be a `\TeX nicolor' extension to specify different colors of ink,
+@^extensions to \TeX@>
+and the whatsit node might contain the desired parameters.
+
+The present implementation of \TeX\ treats the features associated with
+`\.{\\write}' and `\.{\\special}' as if they were extensions, in order to
+illustrate how such routines might be coded. We shall defer further
+discussion of extensions until the end of this program.
+
+@ 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}.
+
+@c
+halfword new_math(scaled w, int s)
+{
+ halfword p; /* the new node */
+ p = new_node(math_node, s);
+ surround(p) = w;
+ return p;
+}
+
+@ \TeX\ makes use of the fact that |hlist_node|, |vlist_node|,
+|rule_node|, |ins_node|, |mark_node|, |adjust_node|,
+|disc_node|, |whatsit_node|, and |math_node| are at the low end of the
+type codes, by permitting a break at glue in a list if and only if the
+|type| of the previous node is less than |math_node|. Furthermore, a
+node is discarded after a break if its type is |math_node| or~more.
+
+@ A |glue_node| represents glue in a list. However, it is really only
+a pointer to a separate glue specification, since \TeX\ makes use of the
+fact that many essentially identical nodes of glue are usually present.
+If |p| points to a |glue_node|, |glue_ptr(p)| points to
+another packet of words that specify the stretch and shrink components, etc.
+
+Glue nodes also serve to represent leaders; the |subtype| is used to
+distinguish between ordinary glue (which is called |normal|) and the three
+kinds of leaders (which are called |a_leaders|, |c_leaders|, and |x_leaders|).
+The |leader_ptr| field points to a rule node or to a box node containing the
+leaders; it is set to |null| in ordinary glue nodes.
+
+Many kinds of glue are computed from \TeX's ``skip'' parameters, and
+it is helpful to know which parameter has led to a particular glue node.
+Therefore the |subtype| is set to indicate the source of glue, whenever
+it originated as a parameter. We will be defining symbolic names for the
+parameter numbers later (e.g., |line_skip_code=0|, |baseline_skip_code=1|,
+etc.); it suffices for now to say that the |subtype| of parametric glue
+will be the same as the parameter number, plus~one.
+
+@ In math formulas there are two more possibilities for the |subtype| in a
+glue node: |mu_glue| denotes an \.{\\mskip} (where the units are scaled \.{mu}
+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.
+
+@ A glue specification has a halfword reference count in its first word,
+@^reference counts@>
+representing |null| plus the number of glue nodes that point to it (less one).
+Note that the reference count appears in the same position as
+the |link| field in list nodes; this is the field that is initialized
+to |null| when a node is allocated, and it is also the field that is flagged
+by |empty_flag| in empty nodes.
+
+Glue specifications also contain three |scaled| fields, for the |width|,
+|stretch|, and |shrink| dimensions. Finally, there are two one-byte
+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.
+
+@ Here is a function that returns a pointer to a copy of a glue spec.
+The reference count in the copy is |null|, because there is assumed
+to be exactly one reference to the new specification.
+
+@c
+halfword new_spec(halfword p)
+{ /* duplicates a glue specification */
+ halfword q; /* the new spec */
+ q = copy_node(p);
+ glue_ref_count(q) = null;
+ return q;
+}
+
+@ And here's a function that creates a glue node for a given parameter
+identified by its code number; for example,
+|new_param_glue(line_skip_code)| returns a pointer to a glue node for the
+current \.{\\lineskip}.
+
+@c
+halfword new_param_glue(int n)
+{
+ halfword p; /* the new node */
+ halfword q; /* the glue specification */
+ p = new_node(glue_node, n + 1);
+ q = glue_par(n);
+ glue_ptr(p) = q;
+ incr(glue_ref_count(q));
+ return p;
+}
+
+@ Glue nodes that are more or less anonymous are created by |new_glue|,
+whose argument points to a glue specification.
+
+@c
+halfword new_glue(halfword q)
+{
+ halfword p; /* the new node */
+ p = new_node(glue_node, normal);
+ glue_ptr(p) = q;
+ incr(glue_ref_count(q));
+ return p;
+}
+
+@ 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,
+while the parameter will stay put. The global variable |temp_ptr| is
+set to the address of the new spec.
+
+@c
+halfword new_skip_param(int n)
+{
+ halfword p; /* the new node */
+ temp_ptr = new_spec(glue_par(n));
+ p = new_glue(temp_ptr);
+ glue_ref_count(temp_ptr) = null;
+ subtype(p) = (quarterword) (n + 1);
+ return p;
+}
+
+@ A |kern_node| has a |width| field to specify a (normally negative)
+amount of spacing. This spacing correction appears in horizontal lists
+between letters like A and V when the font designer said that it looks
+better to move them closer together or further apart. A kern node can
+also appear in a vertical list, when its `|width|' denotes additional
+spacing in the vertical direction. The |subtype| is either |normal| (for
+kerns inserted from font information or math mode calculations) or |explicit|
+(for kerns inserted from \.{\\kern} and \.{\\/} commands) or |acc_kern|
+(for kerns inserted from non-math accents) or |mu_glue| (for kerns
+inserted from \.{\\mkern} specifications in math formulas).
+
+@ The |new_kern| function creates a kern node having a given width.
+
+@c
+halfword new_kern(scaled w)
+{
+ halfword p; /* the new node */
+ p = new_node(kern_node, normal);
+ width(p) = w;
+ return p;
+}
+
+@ A |penalty_node| specifies the penalty associated with line or page
+breaking, in its |penalty| field. This field is a fullword integer, but
+the full range of integer values is not used: Any penalty |>=10000| is
+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.
+
+@ Anyone who has been reading the last few sections of the program will
+be able to guess what comes next.
+
+@c
+halfword new_penalty(int m)
+{
+ halfword p; /* the new node */
+ p = new_node(penalty_node, 0); /* the |subtype| is not used */
+ penalty(p) = m;
+ return p;
+}
+
+@ You might think that we have introduced enough node types by now. Well,
+almost, but there is one more: An |unset_node| has nearly the same format
+as an |hlist_node| or |vlist_node|; it is used for entries in \.{\\halign}
+or \.{\\valign} that are not yet in their final form, since the box
+dimensions are their ``natural'' sizes before any glue adjustment has been
+made. The |glue_set| word is not present; instead, we have a |glue_stretch|
+field, which contains the total stretch of order |glue_order| that is
+present in the hlist or vlist being boxed.
+Similarly, the |shift_amount| field is replaced by a |glue_shrink| field,
+containing the total shrink of order |glue_sign| that is present.
+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.
+
+In fact, there are still more types coming. When we get to math formula
+processing we will see that a |style_node| has |type=14|; and a number
+of larger type codes will also be defined, for use in math mode only.
+
+Warning: If any changes are made to these data structure layouts, such as
+changing any of the node sizes or even reordering the words of nodes,
+the |copy_node_list| procedure and the memory initialization code
+below may have to be changed. Such potentially dangerous parts of the
+program are listed in the index under `data structure assumptions'.
+@!@^data structure assumptions@>
+However, other references to the nodes are made symbolically in terms of
+the \.{WEB} macro definitions above, so that format changes will leave
+\TeX's other algorithms intact.
+@^system dependencies@>
diff --git a/Build/source/texk/web2c/luatexdir/tex/texpdf.c b/Build/source/texk/web2c/luatexdir/tex/texpdf.c
deleted file mode 100644
index 2494e71442b..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texpdf.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* texpdf.c
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include <ctype.h>
-
-static const char _svn_version[] =
- "$Id: texpdf.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/texpdf.c $";
-
-#define number_chars 1114112
-#define string_offset 2097152
-#define str_start_macro(a) str_start[(a) - string_offset]
-#define str_length(a) (str_start_macro((a)+1)-str_start_macro(a)) /* the number of characters in string number (a) */
-
-#define is_hex_char isxdigit
-
-/* output a byte to PDF buffer without checking of overflow */
-
-#define pdf_quick_out(a) pdf_buf[pdf_ptr++] = a
-
-/* do the same as |pdf_quick_out| and flush the PDF buffer if necessary */
-
-#define pdf_out(a) do { \
- pdf_room(1); \
- pdf_quick_out(a); \
- } while (0)
-
-
-/* print out a character to PDF buffer; the character will be printed in octal
- * form in the following cases: chars <= 32, backslash (92), left parenthesis
- * (40) and right parenthesis (41)
- */
-
-#define pdf_print_escaped(c) \
- if ((c)<=32||(c)=='\\'||(c)=='('||(c)==')'||(c)>127) { \
- pdf_room(4); \
- pdf_quick_out('\\'); \
- pdf_quick_out('0' + (((c)>>6) & 0x3)); \
- pdf_quick_out('0' + (((c)>>3) & 0x7)); \
- pdf_quick_out('0' + ( (c) & 0x7)); \
- } else { \
- pdf_out((c)); \
- }
-
-void pdf_print_char(internal_font_number f, integer cc)
-{
- register int c;
- pdf_mark_char(f, cc);
- if (font_encodingbytes(f) == 2) {
- register int chari;
- chari = char_index(f, cc);
- c = chari >> 8;
- pdf_print_escaped(c);
- c = chari & 0xFF;
- } else {
- if (cc > 255)
- return;
- c = cc;
- }
- pdf_print_escaped(c);
-}
-
-/* print out a string to PDF buffer */
-
-void pdf_print(str_number s)
-{
- if (s < number_chars) {
- assert(s < 256);
- pdf_out(s);
- } else {
- register pool_pointer j = str_start_macro(s);
- while (j < str_start_macro(s + 1)) {
- pdf_out(str_pool[j++]);
- }
- }
-}
-
-/* print out a integer to PDF buffer */
-
-void pdf_print_int(longinteger n)
-{
- register integer k = 0; /* current digit; we assume that $|n|<10^{23}$ */
- if (n < 0) {
- pdf_out('-');
- if (n < -0x7FFFFFFF) { /* need to negate |n| more carefully */
- register longinteger m;
- k++;
- m = -1 - n;
- n = m / 10;
- m = (m % 10) + 1;
- if (m < 10) {
- dig[0] = m;
- } else {
- dig[0] = 0;
- incr(n);
- }
- } else {
- n = -n;
- }
- }
- do {
- dig[k++] = n % 10;
- n = n / 10;
- } while (n != 0);
- pdf_room(k);
- while (k-- > 0) {
- pdf_quick_out('0' + dig[k]);
- }
-}
-
-
-/* print $m/10^d$ as real */
-void pdf_print_real(integer m, integer d)
-{
- if (m < 0) {
- pdf_out('-');
- m = -m;
- };
- pdf_print_int(m / ten_pow[d]);
- m = m % ten_pow[d];
- if (m > 0) {
- pdf_out('.');
- d--;
- while (m < ten_pow[d]) {
- pdf_out('0');
- d--;
- }
- while (m % 10 == 0)
- m = m / 10;
- pdf_print_int(m);
- }
-}
-
-/* print out |s| as string in PDF output */
-
-void pdf_print_str(str_number s)
-{
- pool_pointer i, j;
- i = str_start_macro(s);
- j = str_start_macro(s + 1) - 1;
- if (i > j) {
- pdf_room(2);
- pdf_quick_out('(');
- pdf_quick_out(')');
- return;
- }
- /* the next is not really safe, the string could be "(a)xx(b)" */
- if ((str_pool[i] == '(') && (str_pool[j] == ')')) {
- pdf_print(s);
- return;
- }
- if ((str_pool[i] != '<') || (str_pool[j] != '>') || odd(str_length(s))) {
- pdf_out('(');
- pdf_print(s);
- pdf_out(')');
- return;
- }
- i++;
- j--;
- while (i < j) {
- if (!is_hex_char(str_pool[i++])) {
- pdf_out('(');
- pdf_print(s);
- pdf_out(')');
- return;
- }
- }
- pdf_print(s); /* it was a hex string after all */
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/textcodes.h b/Build/source/texk/web2c/luatexdir/tex/textcodes.h
new file mode 100644
index 00000000000..f81db2dd0a6
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/textcodes.h
@@ -0,0 +1,46 @@
+/* textcodes.h
+
+ Copyright 2009 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: textcodes.h 3261 2009-12-18 11:38:21Z taco $ */
+
+#ifndef TEXTCODES_H
+# define TEXTCODES_H
+
+
+void set_lc_code(int n, halfword v, quarterword gl);
+halfword get_lc_code(int n);
+void set_uc_code(int n, halfword v, quarterword gl);
+halfword get_uc_code(int n);
+void set_sf_code(int n, halfword v, quarterword gl);
+halfword get_sf_code(int n);
+void set_cat_code(int h, int n, halfword v, quarterword gl);
+halfword get_cat_code(int h, int n);
+void unsave_cat_codes(int h, quarterword gl);
+int valid_catcode_table(int h);
+void initex_cat_codes(int h);
+void unsave_text_codes(quarterword grouplevel);
+void initialize_text_codes(void);
+void dump_text_codes(void);
+void undump_text_codes(void);
+void copy_cat_codes(int from, int to);
+void free_math_codes(void);
+void free_text_codes(void);
+
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/textcodes.c b/Build/source/texk/web2c/luatexdir/tex/textcodes.w
index e2d8c2c824a..ea2f1f73698 100644
--- a/Build/source/texk/web2c/luatexdir/textcodes.c
+++ b/Build/source/texk/web2c/luatexdir/tex/textcodes.w
@@ -1,32 +1,30 @@
-/* textcodes.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% textcodes.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include <stdarg.h>
+@ @c
+#include "ptexlib.h"
-#include "managed-sa.h"
-#include "commands.h"
-
-static const char __svn_version[] =
- "$Id$ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.5/source/texk/web2c/luatexdir/textcodes.c $";
+static const char _svn_version[] =
+ "$Id: textcodes.w 3587 2010-04-03 14:32:25Z taco $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/textcodes.w $";
+@ @c
#define LCCODESTACK 8
#define LCCODEDEFAULT 0
@@ -46,12 +44,12 @@ static sa_tree sfcode_head = NULL;
#define CATCODEDEFAULT 12
-void set_lc_code(integer n, halfword v, quarterword gl)
+void set_lc_code(int n, halfword v, quarterword gl)
{
- set_sa_item(lccode_head, n, v, gl);
+ set_sa_item(lccode_head, n, (sa_tree_item) v, gl);
}
-halfword get_lc_code(integer n)
+halfword get_lc_code(int n)
{
return (halfword) get_sa_item(lccode_head, n);
}
@@ -76,12 +74,12 @@ static void undumplccodes(void)
lccode_head = undump_sa_tree();
}
-void set_uc_code(integer n, halfword v, quarterword gl)
+void set_uc_code(int n, halfword v, quarterword gl)
{
- set_sa_item(uccode_head, n, v, gl);
+ set_sa_item(uccode_head, n, (sa_tree_item) v, gl);
}
-halfword get_uc_code(integer n)
+halfword get_uc_code(int n)
{
return (halfword) get_sa_item(uccode_head, n);
}
@@ -106,12 +104,12 @@ static void undumpuccodes(void)
uccode_head = undump_sa_tree();
}
-void set_sf_code(integer n, halfword v, quarterword gl)
+void set_sf_code(int n, halfword v, quarterword gl)
{
- set_sa_item(sfcode_head, n, v, gl);
+ set_sa_item(sfcode_head, n, (sa_tree_item) v, gl);
}
-halfword get_sf_code(integer n)
+halfword get_sf_code(int n)
{
return (halfword) get_sa_item(sfcode_head, n);
}
@@ -138,14 +136,14 @@ static void undumpsfcodes(void)
static sa_tree *catcode_heads = NULL;
-static integer catcode_max = 0;
+static int catcode_max = 0;
static unsigned char *catcode_valid = NULL;
#define CATCODE_MAX 65535
#define update_catcode_max(h) if (h > catcode_max) catcode_max = h
-void set_cat_code(integer h, integer n, halfword v, quarterword gl)
+void set_cat_code(int h, int n, halfword v, quarterword gl)
{
sa_tree s = catcode_heads[h];
update_catcode_max(h);
@@ -153,10 +151,10 @@ void set_cat_code(integer h, integer n, halfword v, quarterword gl)
s = new_sa_tree(CATCODESTACK, CATCODEDEFAULT);
catcode_heads[h] = s;
}
- set_sa_item(s, n, v, gl);
+ set_sa_item(s, n, (sa_tree_item) v, gl);
}
-halfword get_cat_code(integer h, integer n)
+halfword get_cat_code(int h, int n)
{
sa_tree s = catcode_heads[h];
update_catcode_max(h);
@@ -167,7 +165,7 @@ halfword get_cat_code(integer h, integer n)
return (halfword) get_sa_item(s, n);
}
-void unsave_cat_codes(integer h, quarterword gl)
+void unsave_cat_codes(int h, quarterword gl)
{
int k;
update_catcode_max(h);
@@ -177,18 +175,18 @@ void unsave_cat_codes(integer h, quarterword gl)
}
}
-#if 0 /* unused */
-static void clearcatcodestack(integer h)
+void clearcatcodestack(int h)
{
clear_sa_stack(catcode_heads[h]);
}
-#endif
static void initializecatcodes(void)
{
catcode_max = 0;
- /* xfree(catcode_heads); *//* not needed */
- /* xfree(catcode_valid); */
+#if 0
+ xfree(catcode_heads); /* not needed */
+ xfree(catcode_valid);
+#endif
catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1));
catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1));
memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1));
@@ -218,7 +216,7 @@ static void dumpcatcodes(void)
static void undumpcatcodes(void)
{
- integer total, k, x;
+ int total, k, x;
xfree(catcode_heads);
xfree(catcode_valid);
catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1));
diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.c b/Build/source/texk/web2c/luatexdir/tex/textoken.c
deleted file mode 100644
index a961966a1a1..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/textoken.c
+++ /dev/null
@@ -1,1173 +0,0 @@
-/* textoken.c
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "luatex-api.h"
-#include <ptexlib.h>
-
-#include "tokens.h"
-#include "commands.h"
-
-static const char _svn_version[] =
- "$Id: textoken.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/textoken.c $";
-
-#define skipping 1 /* |scanner_status| when passing conditional text */
-#define defining 2 /* |scanner_status| when reading a macro definition */
-#define matching 3 /* |scanner_status| when reading macro arguments */
-#define aligning 4 /* |scanner_status| when reading an alignment preamble */
-#define absorbing 5 /* |scanner_status| when reading a balanced text */
-
-#define right_brace_token 0x400000 /* $2^{21}\cdot|right_brace|$ */
-
-#define cat_code_table int_par(param_cat_code_table_code)
-#define tracing_nesting int_par(param_tracing_nesting_code)
-#define end_line_char int_par(param_end_line_char_code)
-#define suppress_outer_error int_par(param_suppress_outer_error_code)
-
-#define every_eof get_every_eof()
-
-#define null_cs 1 /* equivalent of \.{\\csname\\endcsname} */
-
-#define eq_level(a) zeqtb[a].hh.u.B1
-#define eq_type(a) zeqtb[a].hh.u.B0
-#define equiv(a) zeqtb[a].hh.v.RH
-
-/* leave an input level, re-enter the old */
-#define pop_input() cur_input=input_stack[--input_ptr]
-
-#define nonstop_mode 1
-
-#define terminal_input (name==0) /* are we reading from the terminal? */
-#define special_char 1114113 /* |biggest_char+2| */
-#define cur_file input_file[index] /* the current |alpha_file| variable */
-
-#define no_expand_flag special_char /*this characterizes a special variant of |relax| */
-
-#define detokenized_line() (line_catcode_table==NO_CAT_TABLE)
-
-#define do_get_cat_code(a) do { \
- if (line_catcode_table!=DEFAULT_CAT_TABLE) \
- a=get_cat_code(line_catcode_table,cur_chr); \
- else \
- a=get_cat_code(cat_code_table,cur_chr); \
- } while (0)
-
-
-
-/* string compare */
-
-boolean str_eq_cstr(str_number r, const char *s, size_t l)
-{
- if (l != (size_t) length(r))
- return false;
- return (strncmp((const char *) (str_pool + str_start_macro(r)), s, l) == 0);
-}
-
-
-
-int get_char_cat_code(int cur_chr)
-{
- int a;
- do_get_cat_code(a);
- return a;
-}
-
-static void invalid_character_error(void)
-{
- const char *hlp[] = { "A funny symbol that I can't read has just been input.",
- "Continue, and I'll forget that it ever happened.",
- NULL
- };
- deletions_allowed = false;
- tex_error("Text line contains an invalid character", hlp);
- deletions_allowed = true;
-}
-
-static boolean process_sup_mark(void); /* below */
-
-static int scan_control_sequence(void); /* below */
-
-typedef enum { next_line_ok, next_line_return,
- next_line_restart
-} next_line_retval;
-
-static next_line_retval next_line(void); /* below */
-
-/* @^inner loop@>*/
-
-static void utf_error(void)
-{
- const char *hlp[] = { "A funny symbol that I can't read has just been input.",
- "Just continue, I'll change it to 0xFFFD.",
- NULL
- };
- deletions_allowed = false;
- tex_error("Text line contains an invalid utf-8 sequence", hlp);
- deletions_allowed = true;
-}
-
-#define do_buffer_to_unichar(a,b) a = buffer[b] < 0x80 ? buffer[b++] : qbuffer_to_unichar(&b)
-
-static integer qbuffer_to_unichar(integer * k)
-{
- register int ch;
- int val = 0xFFFD;
- unsigned char *text = buffer + *k;
- if ((ch = *text++) < 0x80) {
- val = ch;
- *k += 1;
- } else if (ch <= 0xbf) { /* error */
- *k += 1;
- } else if (ch <= 0xdf) {
- if (*text >= 0x80 && *text < 0xc0)
- val = ((ch & 0x1f) << 6) | (*text++ & 0x3f);
- *k += 2;
- } else if (ch <= 0xef) {
- if (*text >= 0x80 && *text < 0xc0 && text[1] >= 0x80 && text[1] < 0xc0) {
- val =
- ((ch & 0xf) << 12) | ((text[0] & 0x3f) << 6) | (text[1] & 0x3f);
- *k += 3;
- }
- } else {
- int w = (((ch & 0x7) << 2) | ((text[0] & 0x30) >> 4)) - 1, w2;
- w = (w << 6) | ((text[0] & 0xf) << 2) | ((text[1] & 0x30) >> 4);
- w2 = ((text[1] & 0xf) << 6) | (text[2] & 0x3f);
- val = w * 0x400 + w2 + 0x10000;
- if (*text < 0x80 || text[1] < 0x80 || text[2] < 0x80 ||
- *text >= 0xc0 || text[1] >= 0xc0 || text[2] >= 0xc0)
- val = 0xFFFD;
- *k += 4;
- }
- if (val == 0xFFFD)
- utf_error();
- return (val);
-}
-
-/* This is a very basic helper */
-
-static char *u2s(unsigned unic)
-{
- char *buf = xmalloc(5);
- char *pt = buf;
- if (unic < 0x80)
- *pt++ = unic;
- else if (unic < 0x800) {
- *pt++ = 0xc0 | (unic >> 6);
- *pt++ = 0x80 | (unic & 0x3f);
- } else if (unic >= 0x110000) {
- *pt++ = unic - 0x110000;
- } else if (unic < 0x10000) {
- *pt++ = 0xe0 | (unic >> 12);
- *pt++ = 0x80 | ((unic >> 6) & 0x3f);
- *pt++ = 0x80 | (unic & 0x3f);
- } else {
- int u, z, y, x;
- unsigned val = unic - 0x10000;
- u = ((val & 0xf0000) >> 16) + 1;
- z = (val & 0x0f000) >> 12;
- y = (val & 0x00fc0) >> 6;
- x = val & 0x0003f;
- *pt++ = 0xf0 | (u >> 2);
- *pt++ = 0x80 | ((u & 3) << 4) | z;
- *pt++ = 0x80 | y;
- *pt++ = 0x80 | x;
- }
- *pt = '\0';
- return buf;
-}
-
-
-/*
- 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@>
-*/
-
-boolean scan_keyword(const char *s)
-{ /* look for a given string */
- pointer p; /* tail of the backup list */
- pointer q; /* new node being added to the token list via |store_new_token| */
- const char *k; /* index into |str_pool| */
- pointer save_cur_cs = cur_cs;
- if (strlen(s) == 1) {
- /* @<Get the next non-blank non-call token@>; */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if ((cur_cs == 0) && ((cur_chr == *s) || (cur_chr == *s - 'a' + 'A'))) {
- return true;
- } else {
- cur_cs = save_cur_cs;
- back_input();
- return false;
- }
- } else {
- p = backup_head;
- link(p) = null;
- k = s;
- while (*k) {
- get_x_token(); /* recursion is possible here */
- if ((cur_cs == 0) &&
- ((cur_chr == *k) || (cur_chr == *k - 'a' + 'A'))) {
- store_new_token(cur_tok);
- k++;
- } else if ((cur_cmd != spacer_cmd) || (p != backup_head)) {
- if (p != backup_head) {
- q = get_avail();
- info(q) = cur_tok;
- link(q) = null;
- link(p) = q;
- begin_token_list(link(backup_head), backed_up);
- } else {
- back_input();
- }
- cur_cs = save_cur_cs;
- return false;
- }
- }
- flush_list(link(backup_head));
- }
- return true;
-}
-
-/* |scan_direction| has to be defined here because luatangle will output
- a character constant when it sees a string literal of length 1 */
-
-#define dir_T 0
-#define dir_L 1
-#define dir_B 2
-#define dir_R 3
-
-#define scan_single_dir(A) do { \
- if (scan_keyword("T")) A=dir_T; \
- else if (scan_keyword("L")) A=dir_L; \
- else if (scan_keyword("B")) A=dir_B; \
- else if (scan_keyword("R")) A=dir_R; \
- else { \
- tex_error("Bad direction", NULL); \
- cur_val=0; \
- return; \
- } \
- } while (0)
-
-void scan_direction(void)
-{
- integer d1, d2, d3;
- get_x_token();
- if (cur_cmd == assign_dir_cmd) {
- cur_val = zeqtb[cur_chr].cint;
- return;
- } else {
- back_input();
- }
- scan_single_dir(d1);
- scan_single_dir(d2);
- if (dir_parallel(d1, d2)) {
- tex_error("Bad direction", NULL);
- cur_val = 0;
- return;
- }
- scan_single_dir(d3);
- get_x_token();
- if (cur_cmd != spacer_cmd)
- back_input();
- cur_val = d1 * 8 + dir_rearrange[d2] * 4 + d3;
-}
-
-
-/* We can not return |undefined_control_sequence| under some conditions
- * (inside |shift_case|, for example). This needs thinking.
- */
-
-halfword active_to_cs(int curchr, int force)
-{
- halfword curcs;
- char *a, *b;
- char *utfbytes = xmalloc(10);
- int nncs = no_new_control_sequence;
- a = u2s(0xFFFF);
- utfbytes = strcpy(utfbytes, a);
- if (force)
- no_new_control_sequence = false;
- if (curchr > 0) {
- b = u2s(curchr);
- utfbytes = strcat(utfbytes, b);
- free(b);
- curcs = string_lookup(utfbytes, strlen(utfbytes));
- } else {
- utfbytes[3] = '\0';
- curcs = string_lookup(utfbytes, 4);
- }
- no_new_control_sequence = nncs;
- free(a);
- free(utfbytes);
- return curcs;
-}
-
-/* TODO this function should listen to \.{\\escapechar} */
-
-#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))
-
-
-static char *cs_to_string(pointer p)
-{ /* prints a control sequence */
- const char *s;
- int k = 0;
- static char ret[256] = { 0 };
- if (p == null_cs) {
- ret[k++] = '\\';
- s = "csname";
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k++] = '\\';
- s = "endcsname";
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k] = 0;
-
- } else {
- str_number txt = zget_cs_text(p);
- s = makecstring(txt);
- if (is_active_cs(txt)) {
- s = s + 3;
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k] = 0;
- } else {
- ret[k++] = '\\';
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k] = 0;
- }
- }
- return (char *) ret;
-}
-
-/* TODO this is a quick hack, will be solved differently soon */
-
-static char *cmd_chr_to_string(int cmd, int chr)
-{
- char *s;
- str_number str;
- int sel = selector;
- selector = new_string;
- print_cmd_chr(cmd, chr);
- str = make_string();
- s = makecstring(str);
- selector = sel;
- flush_str(str);
- return s;
-}
-
-/* Before getting into |get_next|, let's consider the subroutine that
- is called when an `\.{\\outer}' control sequence has been scanned or
- when the end of a file has been reached. These two cases are distinguished
- by |cur_cs|, which is zero at the end of a file.
-*/
-
-static int frozen_control_sequence = 0;
-
-#define frozen_cr (frozen_control_sequence+1) /* permanent `\.{\\cr}' */
-#define frozen_fi (frozen_control_sequence+4) /* permanent `\.{\\fi}' */
-
-void check_outer_validity(void)
-{
- pointer p; /* points to inserted token list */
- pointer q; /* auxiliary pointer */
- if (suppress_outer_error)
- return;
- if (frozen_control_sequence == 0) {
- frozen_control_sequence = get_nullcs() + 1 + get_hash_size(); /* hashbase=nullcs+1 */
- }
- if (scanner_status != normal) {
- deletions_allowed = false;
- /* @<Back up an outer control sequence so that it can be reread@>; */
- /* An outer control sequence that occurs in a \.{\\read} will not be reread,
- since the error recovery for \.{\\read} is not very powerful. */
- if (cur_cs != 0) {
- if ((state == token_list) || (name < 1) || (name > 17)) {
- p = get_avail();
- info(p) = cs_token_flag + cur_cs;
- begin_token_list(p, backed_up); /* prepare to read the control sequence again */
- }
- cur_cmd = spacer_cmd;
- cur_chr = ' '; /* replace it by a space */
- }
- if (scanner_status > skipping) {
- const char *errhlp[] = { "I suspect you have forgotten a `}', causing me",
- "to read past where you wanted me to stop.",
- "I'll try to recover; but if the error is serious,",
- "you'd better type `E' or `X' now and fix your file.",
- NULL
- };
- char errmsg[256];
- const char *startmsg, *scannermsg;
- /* @<Tell the user what has run away and try to recover@> */
- runaway(); /* print a definition, argument, or preamble */
- if (cur_cs == 0) {
- startmsg = "File ended";
- } else {
- cur_cs = 0;
- startmsg = "Forbidden control sequence found";
- }
- /* @<Print either `\.{definition}' or `\.{use}' or `\.{preamble}' or `\.{text}',
- and insert tokens that should lead to recovery@>; */
- /* The recovery procedure can't be fully understood without knowing more
- about the \TeX\ routines that should be aborted, but we can sketch the
- ideas here: For a runaway definition we will insert a right brace; for a
- runaway preamble, we will insert a special \.{\\cr} token and a right
- brace; and for a runaway argument, we will set |long_state| to
- |outer_call| and insert \.{\\par}. */
- p = get_avail();
- switch (scanner_status) {
- case defining:
- scannermsg = "definition";
- info(p) = right_brace_token + '}';
- break;
- case matching:
- scannermsg = "use";
- info(p) = par_token;
- long_state = outer_call_cmd;
- break;
- case aligning:
- scannermsg = "preamble";
- info(p) = right_brace_token + '}';
- q = p;
- p = get_avail();
- link(p) = q;
- info(p) = cs_token_flag + frozen_cr;
- align_state = -1000000;
- break;
- case absorbing:
- scannermsg = "text";
- info(p) = right_brace_token + '}';
- break;
- default: /* can't happen */
- scannermsg = "unknown";
- break;
- } /*there are no other cases */
- begin_token_list(p, inserted);
- snprintf(errmsg, 255, "%s while scanning %s of %s",
- startmsg, scannermsg, cs_to_string(warning_index));
- tex_error(errmsg, errhlp);
- } else {
- char errmsg[256];
- const char *errhlp_no[] =
- { "The file ended while I was skipping conditional text.",
- "This kind of error happens when you say `\\if...' and forget",
- "the matching `\\fi'. I've inserted a `\\fi'; this might work.",
- NULL
- };
- const char *errhlp_cs[] =
- { "A forbidden control sequence occurred in skipped text.",
- "This kind of error happens when you say `\\if...' and forget",
- "the matching `\\fi'. I've inserted a `\\fi'; this might work.",
- NULL
- };
- const char **errhlp = (const char **) errhlp_no;
- if (cur_cs != 0) {
- errhlp = errhlp_cs;
- cur_cs = 0;
- }
- snprintf(errmsg, 255,
- "Incomplete %s; all text was ignored after line %d",
- cmd_chr_to_string(if_test_cmd, cur_if), (int) skip_line);
- /* @.Incomplete \\if...@> */
- cur_tok = cs_token_flag + frozen_fi;
- /* back up one inserted token and call |error| */
- {
- OK_to_interrupt = false;
- back_input();
- token_type = inserted;
- OK_to_interrupt = true;
- tex_error(errmsg, errhlp);
- }
- }
- deletions_allowed = true;
- }
-}
-
-static boolean get_next_file(void)
-{
- SWITCH:
- if (loc <= limit) { /* current line not yet finished */
- do_buffer_to_unichar(cur_chr, loc);
-
- RESWITCH:
- if (detokenized_line()) {
- cur_cmd = (cur_chr == ' ' ? 10 : 12);
- } else {
- do_get_cat_code(cur_cmd);
- }
- /*
- @<Change state if necessary, and |goto switch| if the current
- character should be ignored, or |goto reswitch| if the current
- character changes to another@>;
- */
- /* The following 48-way switch accomplishes the scanning quickly, assuming
- that a decent \PASCAL\ compiler has translated the code. Note that the numeric
- values for |mid_line|, |skip_blanks|, and |new_line| are spaced
- apart from each other by |max_char_code+1|, so we can add a character's
- command code to the state to get a single number that characterizes both.
- */
- switch (state + cur_cmd) {
- case mid_line + ignore_cmd:
- case skip_blanks + ignore_cmd:
- case new_line + ignore_cmd:
- case skip_blanks + spacer_cmd:
- case new_line + spacer_cmd: /* @<Cases where character is ignored@> */
- goto SWITCH;
- break;
- case mid_line + escape_cmd:
- case new_line + escape_cmd:
- case skip_blanks + escape_cmd: /* @<Scan a control sequence ...@>; */
- state = scan_control_sequence();
- if (cur_cmd >= outer_call_cmd)
- check_outer_validity();
- break;
- case mid_line + active_char_cmd:
- case new_line + active_char_cmd:
- case skip_blanks + active_char_cmd: /* @<Process an active-character */
- cur_cs = active_to_cs(cur_chr, false);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- state = mid_line;
- if (cur_cmd >= outer_call_cmd)
- check_outer_validity();
- break;
- case mid_line + sup_mark_cmd:
- case new_line + sup_mark_cmd:
- case skip_blanks + sup_mark_cmd: /* @<If this |sup_mark| starts */
- if (process_sup_mark())
- goto RESWITCH;
- else
- state = mid_line;
- break;
- case mid_line + invalid_char_cmd:
- case new_line + invalid_char_cmd:
- case skip_blanks + invalid_char_cmd: /* @<Decry the invalid character and |goto restart|@>; */
- invalid_character_error();
- return false; /* because state may be token_list now */
- break;
- case mid_line + spacer_cmd: /* @<Enter |skip_blanks| state, emit a space@>; */
- state = skip_blanks;
- cur_chr = ' ';
- break;
- case mid_line + car_ret_cmd: /* @<Finish line, emit a space@>; */
- /* When a character of type |spacer| gets through, its character code is
- changed to $\.{"\ "}=@'40$. This means that the ASCII codes for tab and space,
- and for the space inserted at the end of a line, will
- be treated alike when macro parameters are being matched. We do this
- since such characters are indistinguishable on most computer terminal displays.
- */
- loc = limit + 1;
- cur_cmd = spacer_cmd;
- cur_chr = ' ';
- break;
- case skip_blanks + car_ret_cmd:
- case mid_line + comment_cmd:
- case new_line + comment_cmd:
- case skip_blanks + comment_cmd: /* @<Finish line, |goto switch|@>; */
- loc = limit + 1;
- goto SWITCH;
- break;
- case new_line + car_ret_cmd: /* @<Finish line, emit a \.{\\par}@>; */
- loc = limit + 1;
- cur_cs = par_loc;
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- if (cur_cmd >= outer_call_cmd)
- check_outer_validity();
- break;
- case skip_blanks + left_brace_cmd:
- case new_line + left_brace_cmd:
- state = mid_line; /* fall through */
- case mid_line + left_brace_cmd:
- align_state++;
- break;
- case skip_blanks + right_brace_cmd:
- case new_line + right_brace_cmd:
- state = mid_line; /* fall through */
- case mid_line + right_brace_cmd:
- align_state--;
- break;
- case mid_line + math_shift_cmd:
- case mid_line + tab_mark_cmd:
- case mid_line + mac_param_cmd:
- case mid_line + sub_mark_cmd:
- case mid_line + letter_cmd:
- case mid_line + other_char_cmd:
- break;
- default:
- /*
- case skip_blanks + math_shift:
- case skip_blanks + tab_mark:
- case skip_blanks + mac_param:
- case skip_blanks + sub_mark:
- case skip_blanks + letter:
- case skip_blanks + other_char:
- case new_line + math_shift:
- case new_line + tab_mark:
- case new_line + mac_param:
- case new_line + sub_mark:
- case new_line + letter:
- case new_line + other_char:
- */
- state = mid_line;
- break;
- }
- } else {
- if (current_ocp_lstack > 0) {
- pop_input();
- return false;
- }
- if (name != 21)
- state = new_line;
-
- /*
- @<Move to next line of file,
- or |goto restart| if there is no next line,
- or |return| if a \.{\\read} line has finished@>;
- */
- do {
- next_line_retval r = next_line();
- if (r == next_line_return) {
- return true;
- } else if (r == next_line_restart) {
- return false;
- }
- } while (0);
- check_interrupt();
- goto SWITCH;
- }
- return true;
-}
-
-#define is_hex(a) ((a>='0'&&a<='9')||(a>='a'&&a<='f'))
-
-#define add_nybble(a) do { \
- if (a<='9') cur_chr=(cur_chr<<4)+a-'0'; \
- else cur_chr=(cur_chr<<4)+a-'a'+10; \
- } while (0)
-
-#define hex_to_cur_chr do { \
- if (c<='9') cur_chr=c-'0'; \
- else cur_chr=c-'a'+10; \
- add_nybble(cc); \
- } while (0)
-
-#define four_hex_to_cur_chr do { \
- hex_to_cur_chr; \
- add_nybble(ccc); add_nybble(cccc); \
- } while (0)
-
-#define five_hex_to_cur_chr do { \
- four_hex_to_cur_chr; \
- add_nybble(ccccc); \
- } while (0)
-
-#define six_hex_to_cur_chr do { \
- five_hex_to_cur_chr; \
- add_nybble(cccccc); \
- } while (0)
-
-
-/* Notice that a code like \.{\^\^8} becomes \.x if not followed by a hex digit.*/
-
-static boolean process_sup_mark(void)
-{
- if (cur_chr == buffer[loc]) {
- int c, cc;
- if (loc < limit) {
- if ((cur_chr == buffer[loc + 1]) && (cur_chr == buffer[loc + 2])
- && (cur_chr == buffer[loc + 3]) && (cur_chr == buffer[loc + 4])
- && ((loc + 10) <= limit)) {
- int ccc, cccc, ccccc, cccccc; /* constituents of a possible expanded code */
- c = buffer[loc + 5];
- cc = buffer[loc + 6];
- ccc = buffer[loc + 7];
- cccc = buffer[loc + 8];
- ccccc = buffer[loc + 9];
- cccccc = buffer[loc + 10];
- if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc))
- && (is_hex(cccc))
- && (is_hex(ccccc)) && (is_hex(cccccc))) {
- loc = loc + 11;
- six_hex_to_cur_chr;
- return true;
- }
- }
- if ((cur_chr == buffer[loc + 1]) && (cur_chr == buffer[loc + 2])
- && (cur_chr == buffer[loc + 3]) && ((loc + 8) <= limit)) {
- int ccc, cccc, ccccc; /* constituents of a possible expanded code */
- c = buffer[loc + 4];
- cc = buffer[loc + 5];
- ccc = buffer[loc + 6];
- cccc = buffer[loc + 7];
- ccccc = buffer[loc + 8];
- if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc))
- && (is_hex(cccc)) && (is_hex(ccccc))) {
- loc = loc + 9;
- five_hex_to_cur_chr;
- return true;
- }
- }
- if ((cur_chr == buffer[loc + 1]) && (cur_chr == buffer[loc + 2])
- && ((loc + 6) <= limit)) {
- int ccc, cccc; /* constituents of a possible expanded code */
- c = buffer[loc + 3];
- cc = buffer[loc + 4];
- ccc = buffer[loc + 5];
- cccc = buffer[loc + 6];
- if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc))
- && (is_hex(cccc))) {
- loc = loc + 7;
- four_hex_to_cur_chr;
- return true;
- }
- }
- c = buffer[loc + 1];
- if (c < 0200) { /* yes we have an expanded char */
- loc = loc + 2;
- if (is_hex(c) && loc <= limit) {
- cc = buffer[loc];
- if (is_hex(cc)) {
- incr(loc);
- hex_to_cur_chr;
- return true;
- }
- }
- cur_chr = (c < 0100 ? c + 0100 : c - 0100);
- return true;
- }
- }
- }
- return false;
-}
-
-/* Control sequence names are scanned only when they appear in some line of
- a file; once they have been scanned the first time, their |eqtb| location
- serves as a unique identification, so \TeX\ doesn't need to refer to the
- original name any more except when it prints the equivalent in symbolic form.
-
- The program that scans a control sequence has been written carefully
- in order to avoid the blowups that might otherwise occur if a malicious
- user tried something like `\.{\\catcode\'15=0}'. The algorithm might
- look at |buffer[limit+1]|, but it never looks at |buffer[limit+2]|.
-
- If expanded characters like `\.{\^\^A}' or `\.{\^\^df}'
- appear in or just following
- a control sequence name, they are converted to single characters in the
- buffer and the process is repeated, slowly but surely.
-*/
-
-static boolean check_expanded_code(integer * kk); /* below */
-
-static int scan_control_sequence(void)
-{
- int retval = mid_line;
- if (loc > limit) {
- cur_cs = null_cs; /* |state| is irrelevant in this case */
- } else {
- register int cat; /* |cat_code(cur_chr)|, usually */
- while (1) {
- integer k = loc;
- do_buffer_to_unichar(cur_chr, k);
- do_get_cat_code(cat);
- if (cat != letter_cmd || k > limit) {
- retval = (cat == spacer_cmd ? skip_blanks : mid_line);
- if (cat == sup_mark_cmd && check_expanded_code(&k)) /* @<If an expanded...@>; */
- continue;
- } else {
- retval = skip_blanks;
- do {
- do_buffer_to_unichar(cur_chr, k);
- do_get_cat_code(cat);
- } while (cat == letter_cmd && k <= limit);
-
- if (cat == sup_mark_cmd && check_expanded_code(&k)) /* @<If an expanded...@>; */
- continue;
- if (cat != letter_cmd) {
- decr(k);
- if (cur_chr > 0xFFFF)
- decr(k);
- if (cur_chr > 0x7FF)
- decr(k);
- if (cur_chr > 0x7F)
- decr(k);
- } /* now |k| points to first nonletter */
- }
- cur_cs = id_lookup(loc, k - loc);
- loc = k;
- break;
- }
- }
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- return retval;
-}
-
-/* Whenever we reach the following piece of code, we will have
- |cur_chr=buffer[k-1]| and |k<=limit+1| and |cat=get_cat_code(cat_code_table,cur_chr)|. If an
- expanded code like \.{\^\^A} or \.{\^\^df} appears in |buffer[(k-1)..(k+1)]|
- or |buffer[(k-1)..(k+2)]|, we
- will store the corresponding code in |buffer[k-1]| and shift the rest of
- the buffer left two or three places.
-*/
-
-static boolean check_expanded_code(integer * kk)
-{
- int l;
- int k = *kk;
- int d = 1; /* number of excess characters in an expanded code */
- int c, cc, ccc, cccc, ccccc, cccccc; /* constituents of a possible expanded code */
- if (buffer[k] == cur_chr && k < limit) {
- if ((cur_chr == buffer[k + 1]) && (cur_chr == buffer[k + 2])
- && ((k + 6) <= limit)) {
- d = 4;
- if ((cur_chr == buffer[k + 3]) && ((k + 8) <= limit))
- d = 5;
- if ((cur_chr == buffer[k + 4]) && ((k + 10) <= limit))
- d = 6;
- c = buffer[k + d - 1];
- cc = buffer[k + d];
- ccc = buffer[k + d + 1];
- cccc = buffer[k + d + 2];
- if (d == 6) {
- ccccc = buffer[k + d + 3];
- cccccc = buffer[k + d + 4];
- if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc)
- && is_hex(ccccc) && is_hex(cccccc))
- six_hex_to_cur_chr;
- } else if (d == 5) {
- ccccc = buffer[k + d + 3];
- if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc)
- && is_hex(ccccc))
- five_hex_to_cur_chr;
- } else {
- if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc))
- four_hex_to_cur_chr;
- }
- } else {
- c = buffer[k + 1];
- if (c < 0200) {
- d = 1;
- if (is_hex(c) && (k + 2) <= limit) {
- cc = buffer[k + 2];
- if (is_hex(c) && is_hex(cc)) {
- d = 2;
- hex_to_cur_chr;
- }
- } else if (c < 0100) {
- cur_chr = c + 0100;
- } else {
- cur_chr = c - 0100;
- }
- }
- }
- if (d > 2)
- d = 2 * d - 1;
- else
- d++;
- if (cur_chr <= 0x7F) {
- buffer[k - 1] = cur_chr;
- } else if (cur_chr <= 0x7FF) {
- buffer[k - 1] = 0xC0 + cur_chr / 0x40;
- k++;
- d--;
- buffer[k - 1] = 0x80 + cur_chr % 0x40;
- } else if (cur_chr <= 0xFFFF) {
- buffer[k - 1] = 0xE0 + cur_chr / 0x1000;
- k++;
- d--;
- buffer[k - 1] = 0x80 + (cur_chr % 0x1000) / 0x40;
- k++;
- d--;
- buffer[k - 1] = 0x80 + (cur_chr % 0x1000) % 0x40;
- } else {
- buffer[k - 1] = 0xF0 + cur_chr / 0x40000;
- k++;
- d--;
- buffer[k - 1] = 0x80 + (cur_chr % 0x40000) / 0x1000;
- k++;
- d--;
- buffer[k - 1] = 0x80 + ((cur_chr % 0x40000) % 0x1000) / 0x40;
- k++;
- d--;
- buffer[k - 1] = 0x80 + ((cur_chr % 0x40000) % 0x1000) % 0x40;
- }
- l = k;
- limit = limit - d;
- while (l <= limit) {
- buffer[l] = buffer[l + d];
- l++;
- }
- *kk = k;
- return true;
- }
- return false;
-}
-
-#define end_line_char_inactive ((end_line_char<0)||(end_line_char>127))
-
-/* The global variable |force_eof| is normally |false|; it is set |true|
- by an \.{\\endinput} command.
-
- @<Glob...@>=
- @!force_eof:boolean; {should the next \.{\\input} be aborted early?}
-
-*/
-
-
-/* All of the easy branches of |get_next| have now been taken care of.
- There is one more branch.
-*/
-
-static next_line_retval next_line(void)
-{
- boolean inhibit_eol = false; /* a way to end a pseudo file without trailing space */
- if (name > 17) {
- /* @<Read next line of file into |buffer|, or |goto restart| if the file has ended@> */
- incr(line);
- first = start;
- if (!force_eof) {
- if (name <= 20) {
- if (pseudo_input()) { /* not end of file */
- firm_up_the_line(); /* this sets |limit| */
- line_catcode_table = DEFAULT_CAT_TABLE;
- if ((name == 19) && (pseudo_lines(pseudo_files) == null))
- inhibit_eol = true;
- } else if ((every_eof != null) && !eof_seen[index]) {
- limit = first - 1;
- eof_seen[index] = true; /* fake one empty line */
- if (name != 19)
- begin_token_list(every_eof, every_eof_text);
- return next_line_restart;
- } else {
- force_eof = true;
- }
- } else {
- if (name == 21) {
- if (luacstring_input()) { /* not end of strings */
- firm_up_the_line();
- line_catcode_table = luacstring_cattable();
- line_partial = luacstring_partial();
- if (luacstring_final_line() || line_partial
- || line_catcode_table == NO_CAT_TABLE)
- inhibit_eol = true;
- if (!line_partial)
- state = new_line;
- } else {
- force_eof = true;
- }
- } else {
- if (lua_input_ln(cur_file, 0, true)) { /* not end of file */
- firm_up_the_line(); /* this sets |limit| */
- line_catcode_table = DEFAULT_CAT_TABLE;
- } else if ((every_eof != null) && (!eof_seen[index])) {
- limit = first - 1;
- eof_seen[index] = true; /* fake one empty line */
- begin_token_list(every_eof, every_eof_text);
- return next_line_restart;
- } else {
- force_eof = true;
- }
- }
- }
- }
- if (force_eof) {
- if (tracing_nesting > 0)
- if ((grp_stack[in_open] != cur_boundary)
- || (if_stack[in_open] != cond_ptr))
- if (!((name == 19) || (name = 21)))
- file_warning(); /* give warning for some unfinished groups and/or conditionals */
- if ((name > 21) || (name == 20)) {
- if (tracefilenames)
- print_char(')');
- open_parens--;
- /* update_terminal(); *//* show user that file has been read */
- }
- force_eof = false;
- if (name == 21 || /* lua input */
- name == 19) { /* \scantextokens */
- end_file_reading();
- } else {
- end_file_reading();
- check_outer_validity();
- }
- return next_line_restart;
- }
- if (inhibit_eol || end_line_char_inactive)
- limit--;
- else
- buffer[limit] = end_line_char;
- first = limit + 1;
- loc = start; /* ready to read */
- } else {
- if (!terminal_input) { /* \.{\\read} line has ended */
- cur_cmd = 0;
- cur_chr = 0;
- return next_line_return; /* OUTER */
- }
- if (input_ptr > 0) { /* text was inserted during error recovery */
- end_file_reading();
- return next_line_restart; /* resume previous level */
- }
- if (selector < log_only)
- open_log_file();
- if (interaction > nonstop_mode) {
- if (end_line_char_inactive)
- limit++;
- if (limit == start) { /* previous line was empty */
- tprint_nl("(Please type a command or say `\\end')");
- }
- print_ln();
- first = start;
- prompt_input((str_number) '*'); /* input on-line into |buffer| */
- limit = last;
- if (end_line_char_inactive)
- limit--;
- else
- buffer[limit] = end_line_char;
- first = limit + 1;
- loc = start;
- } else {
- fatal_error(maketexstring
- ("*** (job aborted, no legal \\end found)"));
- /* nonstop mode, which is intended for overnight batch processing,
- never waits for on-line input */
- }
- }
- return next_line_ok;
-}
-
-
-
-
-/* Let's consider now what happens when |get_next| is looking at a token list. */
-
-static boolean get_next_tokenlist(void)
-{
- register halfword t; /* a token */
- t = info(loc);
- loc = link(loc); /* move to next */
- if (t >= cs_token_flag) { /* a control sequence token */
- cur_cs = t - cs_token_flag;
- cur_cmd = eq_type(cur_cs);
- if (cur_cmd >= outer_call_cmd) {
- if (cur_cmd == dont_expand_cmd) { /* @<Get the next token, suppressing expansion@> */
- /* The present point in the program is reached only when the |expand|
- routine has inserted a special marker into the input. In this special
- case, |info(loc)| is known to be a control sequence token, and |link(loc)=null|.
- */
- cur_cs = info(loc) - cs_token_flag;
- loc = null;
- cur_cmd = eq_type(cur_cs);
- if (cur_cmd > max_command_cmd) {
- cur_cmd = relax_cmd;
- cur_chr = no_expand_flag;
- return true;
- }
- } else {
- check_outer_validity();
- }
- }
- cur_chr = equiv(cur_cs);
- } else {
- cur_cmd = t >> string_offset_bits; /* cur_cmd=t / string_offset; */
- cur_chr = t & (string_offset - 1); /* cur_chr=t % string_offset; */
- switch (cur_cmd) {
- case left_brace_cmd:
- align_state++;
- break;
- case right_brace_cmd:
- align_state--;
- break;
- case out_param_cmd: /* @<Insert macro parameter and |goto restart|@>; */
- begin_token_list(param_stack[param_start + cur_chr - 1], parameter);
- return false;
- break;
- }
- }
- return true;
-}
-
-/* Now we're ready to take the plunge into |get_next| itself. Parts of
- this routine are executed more often than any other instructions of \TeX.
- @^mastication@>@^inner loop@>
-*/
-
-/* sets |cur_cmd|, |cur_chr|, |cur_cs| to next token */
-
-void get_next(void)
-{
- RESTART:
- cur_cs = 0;
- if (state != token_list) {
- /* Input from external file, |goto restart| if no input found */
- if (!get_next_file())
- goto RESTART;
- } else {
- if (loc == null) {
- end_token_list();
- goto RESTART; /* list exhausted, resume previous level */
- } else if (!get_next_tokenlist()) {
- goto RESTART; /* parameter needs to be expanded */
- }
- }
- /* @<If an alignment entry has just ended, take appropriate action@> */
- if ((cur_cmd == tab_mark_cmd || cur_cmd == car_ret_cmd) && align_state == 0) {
- insert_vj_template();
- goto RESTART;
- }
-}
-
-void get_token_lua(void)
-{
- register int callback_id;
- callback_id = callback_defined(token_filter_callback);
- if (callback_id > 0) {
- while (state == token_list && loc == null && index != v_template)
- end_token_list();
- /* there is some stuff we don't want to see inside the callback */
- if (!(state == token_list &&
- ((nofilter == true) || (index == backed_up && loc != null)))) {
- do_get_token_lua(callback_id);
- return;
- }
- }
- get_next();
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.h b/Build/source/texk/web2c/luatexdir/tex/textoken.h
new file mode 100644
index 00000000000..1cb4533a5d2
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/textoken.h
@@ -0,0 +1,179 @@
+/* textoken.h
+
+ Copyright 2006-2008 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.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+/* $Id: textoken.h 3376 2010-01-25 16:50:23Z taco $ */
+
+#ifndef TEXTOKEN_H
+# define TEXTOKEN_H
+
+# define token_list 0
+# define null 0
+# define cs_token_flag 0x1FFFFFFF
+
+# define left_brace_token 0x200000 /* $2^{21}\cdot|left_brace|$ */
+# define right_brace_token 0x400000 /* $2^{21}\cdot|right_brace|$ */
+# define left_brace_token 0x200000 /* $2^{21}\cdot|left_brace|$ */
+# define left_brace_limit 0x400000 /* $2^{21}\cdot(|left_brace|+1)$ */
+# define right_brace_token 0x400000 /* $2^{21}\cdot|right_brace|$ */
+# define right_brace_limit 0x600000 /* $2^{21}\cdot(|right_brace|+1)$ */
+# define math_shift_token 0x600000 /* $2^{21}\cdot|math_shift|$ */
+# define tab_token 0x800000 /* $2^{21}\cdot|tab_mark|$ */
+# define out_param_token 0xA00000 /* $2^{21}\cdot|out_param|$ */
+# define space_token 0x1400020 /* $2^{21}\cdot|spacer|+|" "|$ */
+# define letter_token 0x1600000 /* $2^{21}\cdot|letter|$ */
+# define other_token 0x1800000 /* $2^{21}\cdot|other_char|$ */
+# define match_token 0x1A00000 /* $2^{21}\cdot|match|$ */
+# define end_match_token 0x1C00000 /* $2^{21}\cdot|end_match|$ */
+# define protected_token 0x1C00001 /* $2^{21}\cdot|end_match|+1$ */
+
+# include "tex/stringpool.h"
+
+typedef struct smemory_word_ {
+ halfword hhrh;
+ halfword hhlh;
+} smemory_word;
+
+# define fix_mem_init 10000
+
+extern smemory_word *fixmem;
+extern unsigned fix_mem_min;
+extern unsigned fix_mem_max;
+
+extern halfword garbage; /* head of a junk list, write only */
+extern halfword temp_token_head; /* head of a temporary list of some kind */
+extern halfword hold_token_head; /* head of a temporary list of another kind */
+extern halfword omit_template; /* a constant token list */
+extern halfword null_list; /* permanently empty list */
+extern halfword backup_head; /* head of token list built by |scan_keyword| */
+
+extern void initialize_tokens(void);
+
+extern int dyn_used;
+
+# define token_info(a) fixmem[(a)].hhlh
+# define token_link(a) fixmem[(a)].hhrh
+# define set_token_info(a,b) fixmem[(a)].hhlh=(b)
+# define set_token_link(a,b) fixmem[(a)].hhrh=(b)
+
+extern halfword avail; /* head of the list of available one-word nodes */
+extern unsigned fix_mem_end; /* the last one-word node used in |mem| */
+
+extern halfword get_avail(void);
+
+/* A one-word node is recycled by calling |free_avail|.
+This routine is part of \TeX's ``inner loop,'' so we want it to be fast.
+*/
+
+# define free_avail(A) do { /* single-word node liberation */ \
+ token_link(A)=avail; avail=(A); decr(dyn_used); \
+ } while (0)
+
+/*
+There's also a |fast_get_avail| routine, which saves the procedure-call
+overhead at the expense of extra programming. This routine is used in
+the places that would otherwise account for the most calls of |get_avail|.
+*/
+
+# define fast_get_avail(A) do { \
+ (A)=avail; /* avoid |get_avail| if possible, to save time */ \
+ if ((A)==null) { (A)=get_avail(); } \
+ else { avail=token_link((A)); token_link((A))=null; incr(dyn_used); } \
+ } while (0)
+
+extern void print_meaning(void);
+
+extern void flush_list(halfword p);
+extern void show_token_list(int p, int q, int l);
+extern void token_show(halfword p);
+
+# define token_ref_count(a) token_info((a)) /* reference count preceding a token list */
+# define set_token_ref_count(a,b) token_info((a))=b
+# define add_token_ref(a) token_ref_count(a)++ /* new reference to a token list */
+
+# define store_new_token(a) do { \
+ q=get_avail(); token_link(p)=q; token_info(q)=(a); p=q; \
+ } while (0)
+
+# define fast_store_new_token(a) do { \
+ fast_get_avail(q); token_link(p)=q; token_info(q)=(a); p=q; \
+ } while (0)
+
+extern void delete_token_ref(halfword p);
+
+extern void make_token_table(lua_State * L, int cmd, int chr, int cs);
+
+# define NO_CAT_TABLE -2
+# define DEFAULT_CAT_TABLE -1
+
+extern void get_next(void);
+extern void check_outer_validity(void);
+extern boolean scan_keyword(const char *);
+extern halfword active_to_cs(int, int);
+extern void get_token_lua(void);
+halfword string_to_toks(char *);
+extern int get_char_cat_code(int);
+
+/*
+|no_expand_flag| is a special character value that is inserted by
+|get_next| if it wants to suppress expansion.
+*/
+
+# define no_expand_flag special_char
+
+extern boolean end_line_char_inactive(void);
+
+extern halfword par_loc;
+extern halfword par_token;
+extern boolean force_eof;
+extern int luacstrings;
+
+extern void firm_up_the_line(void);
+extern void get_token(void);
+
+extern halfword str_toks(lstring b);
+extern void ins_the_toks(void);
+
+extern int scan_lua_state(void);
+extern void conv_toks(void);
+
+extern boolean in_lua_escape;
+extern boolean is_convert(halfword c);
+extern str_number the_convert_string(halfword c, int i);
+
+# define closed 2 /* not open, or at end of file */
+# define just_open 1 /* newly opened, first line not yet read */
+
+extern FILE *read_file[16]; /* used for \.{\\read} */
+extern int read_open[17]; /* state of |read_file[n]| */
+
+extern void initialize_read(void);
+
+extern void read_toks(int n, halfword r, halfword j);
+
+extern str_number tokens_to_string(halfword p); /* return a string from tokens list */
+
+extern char *tokenlist_to_cstring(int p, int inhibit_par, int *siz);
+extern lstring *tokenlist_to_lstring(int pp, int inhibit_par);
+extern void free_lstring(lstring * ls);
+
+# define token_cmd(A) ((A) >> STRING_OFFSET_BITS)
+# define token_chr(A) ((A) & (STRING_OFFSET - 1))
+# define token_val(A,B) (((A)<<STRING_OFFSET_BITS)+(B))
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.w b/Build/source/texk/web2c/luatexdir/tex/textoken.w
new file mode 100644
index 00000000000..ac9ad1e1013
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/tex/textoken.w
@@ -0,0 +1,2410 @@
+% textoken.w
+%
+% Copyright 2006-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: textoken.w 3587 2010-04-03 14:32:25Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/tex/textoken.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define pausing int_par(pausing_code)
+#define cat_code_table int_par(cat_code_table_code)
+#define tracing_nesting int_par(tracing_nesting_code)
+#define end_line_char int_par(end_line_char_code)
+#define suppress_outer_error int_par(suppress_outer_error_code)
+
+#define every_eof equiv(every_eof_loc)
+#define box(A) equiv(box_base+(A))
+
+#define detokenized_line() (line_catcode_table==NO_CAT_TABLE)
+
+#define do_get_cat_code(a) do { \
+ if (line_catcode_table!=DEFAULT_CAT_TABLE) \
+ a=get_cat_code(line_catcode_table,cur_chr); \
+ else \
+ a=get_cat_code(cat_code_table,cur_chr); \
+ } while (0)
+
+
+@ The \TeX\ system does nearly all of its own memory allocation, so that it
+can readily be transported into environments that do not have automatic
+facilities for strings, garbage collection, etc., and so that it can be in
+control of what error messages the user receives. The dynamic storage
+requirements of \TeX\ are handled by providing two large arrays called
+|fixmem| and |varmem| in which consecutive blocks of words are used as
+nodes by the \TeX\ routines.
+
+Pointer variables are indices into this array, or into another array
+called |eqtb| that will be explained later. A pointer variable might
+also be a special flag that lies outside the bounds of |mem|, so we
+allow pointers to assume any |halfword| value. The minimum halfword
+value represents a null pointer. \TeX\ does not assume that |mem[null]| exists.
+
+
+
+@ Locations in |fixmem| are used for storing one-word records; a conventional
+\.{AVAIL} stack is used for allocation in this array.
+
+@c
+smemory_word *fixmem; /* the big dynamic storage area */
+unsigned fix_mem_min; /* the smallest location of one-word memory in use */
+unsigned fix_mem_max; /* the largest location of one-word memory in use */
+
+
+@ In order to study the memory requirements of particular applications, it
+is possible to prepare a version of \TeX\ that keeps track of current and
+maximum memory usage. When code between the delimiters |@!stat| $\ldots$
+|tats| is not ``commented out,'' \TeX\ will run a bit slower but it will
+report these statistics when |tracing_stats| is sufficiently large.
+
+@c
+int var_used, dyn_used; /* how much memory is in use */
+
+halfword avail; /* head of the list of available one-word nodes */
+unsigned fix_mem_end; /* the last one-word node used in |mem| */
+
+halfword garbage; /* head of a junk list, write only */
+halfword temp_token_head; /* head of a temporary list of some kind */
+halfword hold_token_head; /* head of a temporary list of another kind */
+halfword omit_template; /* a constant token list */
+halfword null_list; /* permanently empty list */
+halfword backup_head; /* head of token list built by |scan_keyword| */
+
+@ @c
+void initialize_tokens(void)
+{
+ halfword p;
+ avail = null;
+ fix_mem_end = 0;
+ p = get_avail();
+ temp_token_head = p;
+ set_token_info(temp_token_head, 0);
+ p = get_avail();
+ hold_token_head = p;
+ set_token_info(hold_token_head, 0);
+ p = get_avail();
+ omit_template = p;
+ set_token_info(omit_template, 0);
+ p = get_avail();
+ null_list = p;
+ set_token_info(null_list, 0);
+ p = get_avail();
+ backup_head = p;
+ set_token_info(backup_head, 0);
+ p = get_avail();
+ garbage = p;
+ set_token_info(garbage, 0);
+ dyn_used = 0; /* initialize statistics */
+}
+
+@ The function |get_avail| returns a pointer to a new one-word node whose
+|link| field is null. However, \TeX\ will halt if there is no more room left.
+@^inner loop@>
+
+If the available-space list is empty, i.e., if |avail=null|,
+we try first to increase |fix_mem_end|. If that cannot be done, i.e., if
+|fix_mem_end=fix_mem_max|, we try to reallocate array |fixmem|.
+If, that doesn't work, we have to quit.
+
+@c
+halfword get_avail(void)
+{ /* single-word node allocation */
+ unsigned p; /* the new node being got */
+ unsigned t;
+ p = (unsigned) avail; /* get top location in the |avail| stack */
+ if (p != null) {
+ avail = token_link(avail); /* and pop it off */
+ } else if (fix_mem_end < fix_mem_max) { /* or go into virgin territory */
+ incr(fix_mem_end);
+ p = fix_mem_end;
+ } else {
+ smemory_word *new_fixmem; /* the big dynamic storage area */
+ t = (fix_mem_max / 5);
+ new_fixmem =
+ fixmemcast(realloc
+ (fixmem, sizeof(smemory_word) * (fix_mem_max + t + 1)));
+ if (new_fixmem == NULL) {
+ runaway(); /* if memory is exhausted, display possible runaway text */
+ overflow("token memory size", fix_mem_max);
+ } else {
+ fixmem = new_fixmem;
+ }
+ memset(voidcast(fixmem + fix_mem_max + 1), 0, t * sizeof(smemory_word));
+ fix_mem_max += t;
+ p = ++fix_mem_end;
+ }
+ token_link(p) = null; /* provide an oft-desired initialization of the new node */
+ incr(dyn_used); /* maintain statistics */
+ return (halfword) p;
+}
+
+
+@ The procedure |flush_list(p)| frees an entire linked list of
+one-word nodes that starts at position |p|.
+@^inner loop@>
+
+@c
+void flush_list(halfword p)
+{ /* makes list of single-word nodes available */
+ halfword q, r; /* list traversers */
+ if (p != null) {
+ r = p;
+ do {
+ q = r;
+ r = token_link(r);
+ decr(dyn_used);
+ } while (r != null); /* now |q| is the last node on the list */
+ token_link(q) = avail;
+ avail = p;
+ }
+}
+
+@ A \TeX\ token is either a character or a control sequence, and it is
+@^token@>
+represented internally in one of two ways: (1)~A character whose ASCII
+code number is |c| and whose command code is |m| is represented as the
+number $2^{21}m+c$; the command code is in the range |1<=m<=14|. (2)~A control
+sequence whose |eqtb| address is |p| is represented as the number
+|cs_token_flag+p|. Here |cs_token_flag=@t$2^{25}-1$@>| is larger than
+$2^{21}m+c$, yet it is small enough that |cs_token_flag+p< max_halfword|;
+thus, a token fits comfortably in a halfword.
+
+A token |t| represents a |left_brace| command if and only if
+|t<left_brace_limit|; it represents a |right_brace| command if and only if
+we have |left_brace_limit<=t<right_brace_limit|; and it represents a |match| or
+|end_match| command if and only if |match_token<=t<=end_match_token|.
+The following definitions take care of these token-oriented constants
+and a few others.
+
+@ A token list is a singly linked list of one-word nodes in |mem|, where
+each word contains a token and a link. Macro definitions, output-routine
+definitions, marks, \.{\\write} texts, and a few other things
+are remembered by \TeX\ in the form
+of token lists, usually preceded by a node with a reference count in its
+|token_ref_count| field. The token stored in location |p| is called
+|info(p)|.
+
+Three special commands appear in the token lists of macro definitions.
+When |m=match|, it means that \TeX\ should scan a parameter
+for the current macro; when |m=end_match|, it means that parameter
+matching should end and \TeX\ should start reading the macro text; and
+when |m=out_param|, it means that \TeX\ should insert parameter
+number |c| into the text at this point.
+
+The enclosing \.{\char'173} and \.{\char'175} characters of a macro
+definition are omitted, but the final right brace of an output routine
+is included at the end of its token list.
+
+Here is an example macro definition that illustrates these conventions.
+After \TeX\ processes the text
+$$\.{\\def\\mac a\#1\#2 \\b \{\#1\\-a \#\#1\#2 \#2\}}$$
+the definition of \.{\\mac} is represented as a token list containing
+$$\def\,{\hskip2pt}
+\vbox{\halign{\hfil#\hfil\cr
+(reference count), |letter|\,\.a, |match|\,\#, |match|\,\#, |spacer|\,\.\ ,
+\.{\\b}, |end_match|,\cr
+|out_param|\,1, \.{\\-}, |letter|\,\.a, |spacer|\,\.\ , |mac_param|\,\#,
+|other_char|\,\.1,\cr
+|out_param|\,2, |spacer|\,\.\ , |out_param|\,2.\cr}}$$
+The procedure |scan_toks| builds such token lists, and |macro_call|
+does the parameter matching.
+@^reference counts@>
+
+Examples such as
+$$\.{\\def\\m\{\\def\\m\{a\}\ b\}}$$
+explain why reference counts would be needed even if \TeX\ had no \.{\\let}
+operation: When the token list for \.{\\m} is being read, the redefinition of
+\.{\\m} changes the |eqtb| entry before the token list has been fully
+consumed, so we dare not simply destroy a token list when its
+control sequence is being redefined.
+
+If the parameter-matching part of a definition ends with `\.{\#\{}',
+the corresponding token list will have `\.\{' just before the `|end_match|'
+and also at the very end. The first `\.\{' is used to delimit the parameter; the
+second one keeps the first from disappearing.
+
+The |print_meaning| subroutine displays |cur_cmd| and |cur_chr| in
+symbolic form, including the expansion of a macro or mark.
+
+@c
+void print_meaning(void)
+{
+ print_cmd_chr((quarterword) cur_cmd, cur_chr);
+ if (cur_cmd >= call_cmd) {
+ print_char(':');
+ print_ln();
+ token_show(cur_chr);
+ } else {
+ /* Show the meaning of a mark node */
+ if ((cur_cmd == top_bot_mark_cmd) && (cur_chr < marks_code)) {
+ print_char(':');
+ print_ln();
+ switch (cur_chr) {
+ case first_mark_code:
+ token_show(first_mark(0));
+ break;
+ case bot_mark_code:
+ token_show(bot_mark(0));
+ break;
+ case split_first_mark_code:
+ token_show(split_first_mark(0));
+ break;
+ case split_bot_mark_code:
+ token_show(split_bot_mark(0));
+ break;
+ default:
+ token_show(top_mark(0));
+ break;
+ }
+ }
+ }
+}
+
+
+@ The procedure |show_token_list|, which prints a symbolic form of
+the token list that starts at a given node |p|, illustrates these
+conventions. The token list being displayed should not begin with a reference
+count. However, the procedure is intended to be robust, so that if the
+memory links are awry or if |p| is not really a pointer to a token list,
+nothing catastrophic will happen.
+
+An additional parameter |q| is also given; this parameter is either null
+or it points to a node in the token list where a certain magic computation
+takes place that will be explained later. (Basically, |q| is non-null when
+we are printing the two-line context information at the time of an error
+message; |q| marks the place corresponding to where the second line
+should begin.)
+
+For example, if |p| points to the node containing the first \.a in the
+token list above, then |show_token_list| will print the string
+$$\hbox{`\.{a\#1\#2\ \\b\ ->\#1\\-a\ \#\#1\#2\ \#2}';}$$
+and if |q| points to the node containing the second \.a,
+the magic computation will be performed just before the second \.a is printed.
+
+The generation will stop, and `\.{\\ETC.}' will be printed, if the length
+of printing exceeds a given limit~|l|. Anomalous entries are printed in the
+form of control sequences that are not followed by a blank space, e.g.,
+`\.{\\BAD.}'; this cannot be confused with actual control sequences because
+a real control sequence named \.{BAD} would come out `\.{\\BAD\ }'.
+
+@c
+void show_token_list(int p, int q, int l)
+{
+ int m, c; /* pieces of a token */
+ ASCII_code match_chr; /* character used in a `|match|' */
+ ASCII_code n; /* the highest parameter number, as an ASCII digit */
+ match_chr = '#';
+ n = '0';
+ tally = 0;
+ if (l < 0)
+ l = 0x3FFFFFFF;
+ while ((p != null) && (tally < l)) {
+ if (p == q) {
+ /* Do magic computation */
+ set_trick_count();
+ }
+ /* Display token |p|, and |return| if there are problems */
+ if ((p < (int) fix_mem_min) || (p > (int) fix_mem_end)) {
+ tprint_esc("CLOBBERED.");
+ return;
+ }
+ if (token_info(p) >= cs_token_flag) {
+ if (!((inhibit_par_tokens) && (token_info(p) == par_token)))
+ print_cs(token_info(p) - cs_token_flag);
+ } else {
+ m = token_cmd(token_info(p));
+ c = token_chr(token_info(p));
+ if (token_info(p) < 0) {
+ tprint_esc("BAD.");
+ } else {
+ /* Display the token $(|m|,|c|)$ */
+ /* The procedure usually ``learns'' the character code used for macro
+ parameters by seeing one in a |match| command before it runs into any
+ |out_param| commands. */
+ switch (m) {
+ case left_brace_cmd:
+ case right_brace_cmd:
+ case math_shift_cmd:
+ case tab_mark_cmd:
+ case sup_mark_cmd:
+ case sub_mark_cmd:
+ case spacer_cmd:
+ case letter_cmd:
+ case other_char_cmd:
+ print(c);
+ break;
+ case mac_param_cmd:
+ if (!in_lua_escape)
+ print(c);
+ print(c);
+ break;
+ case out_param_cmd:
+ print(match_chr);
+ if (c <= 9) {
+ print_char(c + '0');
+ } else {
+ print_char('!');
+ return;
+ }
+ break;
+ case match_cmd:
+ match_chr = c;
+ print(c);
+ incr(n);
+ print_char(n);
+ if (n > '9')
+ return;
+ break;
+ case end_match_cmd:
+ if (c == 0)
+ tprint("->");
+ break;
+ default:
+ tprint_esc("BAD.");
+ break;
+ }
+ }
+ }
+ p = token_link(p);
+ }
+ if (p != null)
+ tprint_esc("ETC.");
+}
+
+@ @c
+#define do_buffer_to_unichar(a,b) do { \
+ a = (halfword)str2uni(buffer+b); \
+ b += utf8_size(a); \
+ } while (0)
+
+
+@ Here's the way we sometimes want to display a token list, given a pointer
+to its reference count; the pointer may be null.
+
+@c
+void token_show(halfword p)
+{
+ if (p != null)
+ show_token_list(token_link(p), null, 10000000);
+}
+
+
+
+@ |delete_token_ref|, is called when
+a pointer to a token list's reference count is being removed. This means
+that the token list should disappear if the reference count was |null|,
+otherwise the count should be decreased by one.
+@^reference counts@>
+
+@c
+void delete_token_ref(halfword p)
+{ /* |p| points to the reference count
+ of a token list that is losing one reference */
+ assert(token_ref_count(p) >= 0);
+ if (token_ref_count(p) == 0)
+ flush_list(p);
+ else
+ decr(token_ref_count(p));
+}
+
+@ @c
+int get_char_cat_code(int cur_chr)
+{
+ int a;
+ do_get_cat_code(a);
+ return a;
+}
+
+@ @c
+static void invalid_character_error(void)
+{
+ const char *hlp[] =
+ { "A funny symbol that I can't read has just been input.",
+ "Continue, and I'll forget that it ever happened.",
+ NULL
+ };
+ deletions_allowed = false;
+ tex_error("Text line contains an invalid character", hlp);
+ deletions_allowed = true;
+}
+
+@ @c
+static boolean process_sup_mark(void); /* below */
+
+static int scan_control_sequence(void); /* below */
+
+typedef enum { next_line_ok, next_line_return,
+ next_line_restart
+} next_line_retval;
+
+static next_line_retval next_line(void); /* below */
+
+
+@ 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@>
+
+@c
+boolean scan_keyword(const char *s)
+{ /* look for a given string */
+ halfword p; /* tail of the backup list */
+ halfword q; /* new node being added to the token list via |store_new_token| */
+ const char *k; /* index into |str_pool| */
+ halfword save_cur_cs = cur_cs;
+ if (strlen(s) == 1) {
+ /* Get the next non-blank non-call token; */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+ if ((cur_cs == 0) && ((cur_chr == *s) || (cur_chr == *s - 'a' + 'A'))) {
+ return true;
+ } else {
+ cur_cs = save_cur_cs;
+ back_input();
+ return false;
+ }
+ } else {
+ p = backup_head;
+ token_link(p) = null;
+ k = s;
+ while (*k) {
+ get_x_token(); /* recursion is possible here */
+ if ((cur_cs == 0) &&
+ ((cur_chr == *k) || (cur_chr == *k - 'a' + 'A'))) {
+ store_new_token(cur_tok);
+ k++;
+ } else if ((cur_cmd != spacer_cmd) || (p != backup_head)) {
+ if (p != backup_head) {
+ q = get_avail();
+ token_info(q) = cur_tok;
+ token_link(q) = null;
+ token_link(p) = q;
+ begin_token_list(token_link(backup_head), backed_up);
+ } else {
+ back_input();
+ }
+ cur_cs = save_cur_cs;
+ return false;
+ }
+ }
+ flush_list(token_link(backup_head));
+ }
+ cur_cs = save_cur_cs;
+ return true;
+}
+
+@ We can not return |undefined_control_sequence| under some conditions
+ (inside |shift_case|, for example). This needs thinking.
+
+@c
+halfword active_to_cs(int curchr, int force)
+{
+ halfword curcs;
+ char *a, *b;
+ char *utfbytes = xmalloc(10);
+ int nncs = no_new_control_sequence;
+ a = (char *) uni2str(0xFFFF);
+ utfbytes = strcpy(utfbytes, a);
+ if (force)
+ no_new_control_sequence = false;
+ if (curchr > 0) {
+ b = (char *) uni2str((unsigned) curchr);
+ utfbytes = strcat(utfbytes, b);
+ free(b);
+ curcs = string_lookup(utfbytes, strlen(utfbytes));
+ } else {
+ utfbytes[3] = '\0';
+ curcs = string_lookup(utfbytes, 4);
+ }
+ no_new_control_sequence = nncs;
+ free(a);
+ free(utfbytes);
+ return curcs;
+}
+
+@ TODO this function should listen to \.{\\escapechar}
+
+@c
+char *cs_to_string(halfword p)
+{ /* prints a control sequence */
+ const char *s;
+ char *sh;
+ int k = 0;
+ static char ret[256] = { 0 };
+ if (p == 0 || p == null_cs) {
+ ret[k++] = '\\';
+ s = "csname";
+ while (*s) {
+ ret[k++] = *s++;
+ }
+ ret[k++] = '\\';
+ s = "endcsname";
+ while (*s) {
+ ret[k++] = *s++;
+ }
+ ret[k] = 0;
+
+ } else {
+ str_number txt = cs_text(p);
+ sh = makecstring(txt);
+ s = sh;
+ if (is_active_cs(txt)) {
+ s = s + 3;
+ while (*s) {
+ ret[k++] = *s++;
+ }
+ ret[k] = 0;
+ } else {
+ ret[k++] = '\\';
+ while (*s) {
+ ret[k++] = *s++;
+ }
+ ret[k] = 0;
+ }
+ free(sh);
+ }
+ return (char *) ret;
+}
+
+@ TODO this is a quick hack, will be solved differently soon
+
+@c
+char *cmd_chr_to_string(int cmd, int chr)
+{
+ char *s;
+ str_number str;
+ int sel = selector;
+ selector = new_string;
+ print_cmd_chr((quarterword) cmd, chr);
+ str = make_string();
+ s = makecstring(str);
+ selector = sel;
+ flush_str(str);
+ return s;
+}
+
+@ The heart of \TeX's input mechanism is the |get_next| procedure, which
+we shall develop in the next few sections of the program. Perhaps we
+shouldn't actually call it the ``heart,'' however, because it really acts
+as \TeX's eyes and mouth, reading the source files and gobbling them up.
+And it also helps \TeX\ to regurgitate stored token lists that are to be
+processed again.
+@^eyes and mouth@>
+
+The main duty of |get_next| is to input one token and to set |cur_cmd|
+and |cur_chr| to that token's command code and modifier. Furthermore, if
+the input token is a control sequence, the |eqtb| location of that control
+sequence is stored in |cur_cs|; otherwise |cur_cs| is set to zero.
+
+Underlying this simple description is a certain amount of complexity
+because of all the cases that need to be handled.
+However, the inner loop of |get_next| is reasonably short and fast.
+
+When |get_next| is asked to get the next token of a \.{\\read} line,
+it sets |cur_cmd=cur_chr=cur_cs=0| in the case that no more tokens
+appear on that line. (There might not be any tokens at all, if the
+|end_line_char| has |ignore| as its catcode.)
+
+
+@ The value of |par_loc| is the |eqtb| address of `\.{\\par}'. This quantity
+is needed because a blank line of input is supposed to be exactly equivalent
+to the appearance of \.{\\par}; we must set |cur_cs:=par_loc|
+when detecting a blank line.
+
+@c
+halfword par_loc; /* location of `\.{\\par}' in |eqtb| */
+halfword par_token; /* token representing `\.{\\par}' */
+
+
+@ Parts |get_next| are executed more often than any other instructions of \TeX.
+@^mastication@>@^inner loop@>
+
+
+
+@ The global variable |force_eof| is normally |false|; it is set |true|
+by an \.{\\endinput} command. |luacstrings| is the number of lua print
+statements waiting to be input, it is changed by |luatokencall|.
+
+@c
+boolean force_eof; /* should the next \.{\\input} be aborted early? */
+int luacstrings; /* how many lua strings are waiting to be input? */
+
+
+@ If the user has set the |pausing| parameter to some positive value,
+and if nonstop mode has not been selected, each line of input is displayed
+on the terminal and the transcript file, followed by `\.{=>}'.
+\TeX\ waits for a response. If the response is simply |carriage_return|, the
+line is accepted as it stands, otherwise the line typed is
+used instead of the line in the file.
+
+@c
+void firm_up_the_line(void)
+{
+ int k; /* an index into |buffer| */
+ ilimit = last;
+ if (pausing > 0) {
+ if (interaction > nonstop_mode) {
+ wake_up_terminal();
+ print_ln();
+ if (istart < ilimit) {
+ for (k = istart; k <= ilimit - 1; k++)
+ print_char(buffer[k]);
+ }
+ first = ilimit;
+ prompt_input("=>"); /* wait for user response */
+ if (last > first) {
+ for (k = first; k < +last - 1; k++) /* move line down in buffer */
+ buffer[k + istart - first] = buffer[k];
+ ilimit = istart + last - first;
+ }
+ }
+ }
+}
+
+
+
+@ Before getting into |get_next|, let's consider the subroutine that
+ is called when an `\.{\\outer}' control sequence has been scanned or
+ when the end of a file has been reached. These two cases are distinguished
+ by |cur_cs|, which is zero at the end of a file.
+
+@c
+void check_outer_validity(void)
+{
+ halfword p; /* points to inserted token list */
+ halfword q; /* auxiliary pointer */
+ if (suppress_outer_error)
+ return;
+ if (scanner_status != normal) {
+ deletions_allowed = false;
+ /* Back up an outer control sequence so that it can be reread; */
+ /* An outer control sequence that occurs in a \.{\\read} will not be reread,
+ since the error recovery for \.{\\read} is not very powerful. */
+ if (cur_cs != 0) {
+ if ((istate == token_list) || (iname < 1) || (iname > 17)) {
+ p = get_avail();
+ token_info(p) = cs_token_flag + cur_cs;
+ begin_token_list(p, backed_up); /* prepare to read the control sequence again */
+ }
+ cur_cmd = spacer_cmd;
+ cur_chr = ' '; /* replace it by a space */
+ }
+ if (scanner_status > skipping) {
+ const char *errhlp[] =
+ { "I suspect you have forgotten a `}', causing me",
+ "to read past where you wanted me to stop.",
+ "I'll try to recover; but if the error is serious,",
+ "you'd better type `E' or `X' now and fix your file.",
+ NULL
+ };
+ char errmsg[256];
+ const char *startmsg;
+ const char *scannermsg;
+ /* Tell the user what has run away and try to recover */
+ runaway(); /* print a definition, argument, or preamble */
+ if (cur_cs == 0) {
+ startmsg = "File ended";
+ } else {
+ cur_cs = 0;
+ startmsg = "Forbidden control sequence found";
+ }
+ /* Print either `\.{definition}' or `\.{use}' or `\.{preamble}' or `\.{text}',
+ and insert tokens that should lead to recovery; */
+ /* The recovery procedure can't be fully understood without knowing more
+ about the \TeX\ routines that should be aborted, but we can sketch the
+ ideas here: For a runaway definition we will insert a right brace; for a
+ runaway preamble, we will insert a special \.{\\cr} token and a right
+ brace; and for a runaway argument, we will set |long_state| to
+ |outer_call| and insert \.{\\par}. */
+ p = get_avail();
+ switch (scanner_status) {
+ case defining:
+ scannermsg = "definition";
+ token_info(p) = right_brace_token + '}';
+ break;
+ case matching:
+ scannermsg = "use";
+ token_info(p) = par_token;
+ long_state = outer_call_cmd;
+ break;
+ case aligning:
+ scannermsg = "preamble";
+ token_info(p) = right_brace_token + '}';
+ q = p;
+ p = get_avail();
+ token_link(p) = q;
+ token_info(p) = cs_token_flag + frozen_cr;
+ align_state = -1000000;
+ break;
+ case absorbing:
+ scannermsg = "text";
+ token_info(p) = right_brace_token + '}';
+ break;
+ default: /* can't happen */
+ scannermsg = "unknown";
+ break;
+ } /*there are no other cases */
+ begin_token_list(p, inserted);
+ snprintf(errmsg, 255, "%s while scanning %s of %s",
+ startmsg, scannermsg, cs_to_string(warning_index));
+ tex_error(errmsg, errhlp);
+ } else {
+ char errmsg[256];
+ const char *errhlp_no[] =
+ { "The file ended while I was skipping conditional text.",
+ "This kind of error happens when you say `\\if...' and forget",
+ "the matching `\\fi'. I've inserted a `\\fi'; this might work.",
+ NULL
+ };
+ const char *errhlp_cs[] =
+ { "A forbidden control sequence occurred in skipped text.",
+ "This kind of error happens when you say `\\if...' and forget",
+ "the matching `\\fi'. I've inserted a `\\fi'; this might work.",
+ NULL
+ };
+ const char **errhlp = (const char **) errhlp_no;
+ char *ss;
+ if (cur_cs != 0) {
+ errhlp = errhlp_cs;
+ cur_cs = 0;
+ }
+ ss = cmd_chr_to_string(if_test_cmd, cur_if);
+ snprintf(errmsg, 255,
+ "Incomplete %s; all text was ignored after line %d",
+ ss, (int) skip_line);
+ free(ss);
+ /* Incomplete \\if... */
+ cur_tok = cs_token_flag + frozen_fi;
+ /* back up one inserted token and call |error| */
+ {
+ OK_to_interrupt = false;
+ back_input();
+ token_type = inserted;
+ OK_to_interrupt = true;
+ tex_error(errmsg, errhlp);
+ }
+ }
+ deletions_allowed = true;
+ }
+}
+
+@ @c
+static boolean get_next_file(void)
+{
+ SWITCH:
+ if (iloc <= ilimit) { /* current line not yet finished */
+ do_buffer_to_unichar(cur_chr, iloc);
+
+ RESWITCH:
+ if (detokenized_line()) {
+ cur_cmd = (cur_chr == ' ' ? 10 : 12);
+ } else {
+ do_get_cat_code(cur_cmd);
+ }
+ /*
+ Change state if necessary, and |goto switch| if the current
+ character should be ignored, or |goto reswitch| if the current
+ character changes to another;
+ */
+ /* The following 48-way switch accomplishes the scanning quickly, assuming
+ that a decent C compiler has translated the code. Note that the numeric
+ values for |mid_line|, |skip_blanks|, and |new_line| are spaced
+ apart from each other by |max_char_code+1|, so we can add a character's
+ command code to the state to get a single number that characterizes both.
+ */
+ switch (istate + cur_cmd) {
+ case mid_line + ignore_cmd:
+ case skip_blanks + ignore_cmd:
+ case new_line + ignore_cmd:
+ case skip_blanks + spacer_cmd:
+ case new_line + spacer_cmd: /* Cases where character is ignored */
+ goto SWITCH;
+ break;
+ case mid_line + escape_cmd:
+ case new_line + escape_cmd:
+ case skip_blanks + escape_cmd: /* Scan a control sequence ...; */
+ istate = (unsigned char) scan_control_sequence();
+ if (cur_cmd >= outer_call_cmd)
+ check_outer_validity();
+ break;
+ case mid_line + active_char_cmd:
+ case new_line + active_char_cmd:
+ case skip_blanks + active_char_cmd: /* Process an active-character */
+ cur_cs = active_to_cs(cur_chr, false);
+ cur_cmd = eq_type(cur_cs);
+ cur_chr = equiv(cur_cs);
+ istate = mid_line;
+ if (cur_cmd >= outer_call_cmd)
+ check_outer_validity();
+ break;
+ case mid_line + sup_mark_cmd:
+ case new_line + sup_mark_cmd:
+ case skip_blanks + sup_mark_cmd: /* If this |sup_mark| starts */
+ if (process_sup_mark())
+ goto RESWITCH;
+ else
+ istate = mid_line;
+ break;
+ case mid_line + invalid_char_cmd:
+ case new_line + invalid_char_cmd:
+ case skip_blanks + invalid_char_cmd: /* Decry the invalid character and |goto restart|; */
+ invalid_character_error();
+ return false; /* because state may be |token_list| now */
+ break;
+ case mid_line + spacer_cmd: /* Enter |skip_blanks| state, emit a space; */
+ istate = skip_blanks;
+ cur_chr = ' ';
+ break;
+ case mid_line + car_ret_cmd: /* Finish line, emit a space; */
+ /* When a character of type |spacer| gets through, its character code is
+ changed to $\.{"\ "}=040$. This means that the ASCII codes for tab and space,
+ and for the space inserted at the end of a line, will
+ be treated alike when macro parameters are being matched. We do this
+ since such characters are indistinguishable on most computer terminal displays.
+ */
+ iloc = ilimit + 1;
+ cur_cmd = spacer_cmd;
+ cur_chr = ' ';
+ break;
+ case skip_blanks + car_ret_cmd:
+ case mid_line + comment_cmd:
+ case new_line + comment_cmd:
+ case skip_blanks + comment_cmd: /* Finish line, |goto switch|; */
+ iloc = ilimit + 1;
+ goto SWITCH;
+ break;
+ case new_line + car_ret_cmd: /* Finish line, emit a \.{\\par}; */
+ iloc = ilimit + 1;
+ cur_cs = par_loc;
+ cur_cmd = eq_type(cur_cs);
+ cur_chr = equiv(cur_cs);
+ if (cur_cmd >= outer_call_cmd)
+ check_outer_validity();
+ break;
+ case skip_blanks + left_brace_cmd:
+ case new_line + left_brace_cmd:
+ istate = mid_line; /* fall through */
+ case mid_line + left_brace_cmd:
+ align_state++;
+ break;
+ case skip_blanks + right_brace_cmd:
+ case new_line + right_brace_cmd:
+ istate = mid_line; /* fall through */
+ case mid_line + right_brace_cmd:
+ align_state--;
+ break;
+ case mid_line + math_shift_cmd:
+ case mid_line + tab_mark_cmd:
+ case mid_line + mac_param_cmd:
+ case mid_line + sub_mark_cmd:
+ case mid_line + letter_cmd:
+ case mid_line + other_char_cmd:
+ break;
+#if 0
+ case skip_blanks + math_shift:
+ case skip_blanks + tab_mark:
+ case skip_blanks + mac_param:
+ case skip_blanks + sub_mark:
+ case skip_blanks + letter:
+ case skip_blanks + other_char:
+ case new_line + math_shift:
+ case new_line + tab_mark:
+ case new_line + mac_param:
+ case new_line + sub_mark:
+ case new_line + letter:
+ case new_line + other_char:
+#else
+ default:
+#endif
+ istate = mid_line;
+ break;
+ }
+ } else {
+ if (current_ocp_lstack > 0) {
+ pop_input();
+ return false;
+ }
+ if (iname != 21)
+ istate = new_line;
+
+ /*
+ Move to next line of file,
+ or |goto restart| if there is no next line,
+ or |return| if a \.{\\read} line has finished;
+ */
+ do {
+ next_line_retval r = next_line();
+ if (r == next_line_return) {
+ return true;
+ } else if (r == next_line_restart) {
+ return false;
+ }
+ } while (0);
+ check_interrupt();
+ goto SWITCH;
+ }
+ return true;
+}
+
+@ @c
+#define is_hex(a) ((a>='0'&&a<='9')||(a>='a'&&a<='f'))
+
+#define add_nybble(a) do { \
+ if (a<='9') cur_chr=(cur_chr<<4)+a-'0'; \
+ else cur_chr=(cur_chr<<4)+a-'a'+10; \
+ } while (0)
+
+#define hex_to_cur_chr do { \
+ if (c<='9') cur_chr=c-'0'; \
+ else cur_chr=c-'a'+10; \
+ add_nybble(cc); \
+ } while (0)
+
+#define four_hex_to_cur_chr do { \
+ hex_to_cur_chr; \
+ add_nybble(ccc); add_nybble(cccc); \
+ } while (0)
+
+#define five_hex_to_cur_chr do { \
+ four_hex_to_cur_chr; \
+ add_nybble(ccccc); \
+ } while (0)
+
+#define six_hex_to_cur_chr do { \
+ five_hex_to_cur_chr; \
+ add_nybble(cccccc); \
+ } while (0)
+
+
+@ Notice that a code like \.{\^\^8} becomes \.x if not followed by a hex digit.
+
+@c
+static boolean process_sup_mark(void)
+{
+ if (cur_chr == buffer[iloc]) {
+ int c, cc;
+ if (iloc < ilimit) {
+ if ((cur_chr == buffer[iloc + 1]) && (cur_chr == buffer[iloc + 2])
+ && (cur_chr == buffer[iloc + 3])
+ && (cur_chr == buffer[iloc + 4])
+ && ((iloc + 10) <= ilimit)) {
+ int ccc, cccc, ccccc, cccccc; /* constituents of a possible expanded code */
+ c = buffer[iloc + 5];
+ cc = buffer[iloc + 6];
+ ccc = buffer[iloc + 7];
+ cccc = buffer[iloc + 8];
+ ccccc = buffer[iloc + 9];
+ cccccc = buffer[iloc + 10];
+ if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc))
+ && (is_hex(cccc))
+ && (is_hex(ccccc)) && (is_hex(cccccc))) {
+ iloc = iloc + 11;
+ six_hex_to_cur_chr;
+ return true;
+ }
+ }
+ if ((cur_chr == buffer[iloc + 1]) && (cur_chr == buffer[iloc + 2])
+ && (cur_chr == buffer[iloc + 3]) && ((iloc + 8) <= ilimit)) {
+ int ccc, cccc, ccccc; /* constituents of a possible expanded code */
+ c = buffer[iloc + 4];
+ cc = buffer[iloc + 5];
+ ccc = buffer[iloc + 6];
+ cccc = buffer[iloc + 7];
+ ccccc = buffer[iloc + 8];
+ if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc))
+ && (is_hex(cccc)) && (is_hex(ccccc))) {
+ iloc = iloc + 9;
+ five_hex_to_cur_chr;
+ return true;
+ }
+ }
+ if ((cur_chr == buffer[iloc + 1]) && (cur_chr == buffer[iloc + 2])
+ && ((iloc + 6) <= ilimit)) {
+ int ccc, cccc; /* constituents of a possible expanded code */
+ c = buffer[iloc + 3];
+ cc = buffer[iloc + 4];
+ ccc = buffer[iloc + 5];
+ cccc = buffer[iloc + 6];
+ if ((is_hex(c)) && (is_hex(cc)) && (is_hex(ccc))
+ && (is_hex(cccc))) {
+ iloc = iloc + 7;
+ four_hex_to_cur_chr;
+ return true;
+ }
+ }
+ c = buffer[iloc + 1];
+ if (c < 0200) { /* yes we have an expanded char */
+ iloc = iloc + 2;
+ if (is_hex(c) && iloc <= ilimit) {
+ cc = buffer[iloc];
+ if (is_hex(cc)) {
+ incr(iloc);
+ hex_to_cur_chr;
+ return true;
+ }
+ }
+ cur_chr = (c < 0100 ? c + 0100 : c - 0100);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+@ Control sequence names are scanned only when they appear in some line of
+ a file; once they have been scanned the first time, their |eqtb| location
+ serves as a unique identification, so \TeX\ doesn't need to refer to the
+ original name any more except when it prints the equivalent in symbolic form.
+
+ The program that scans a control sequence has been written carefully
+ in order to avoid the blowups that might otherwise occur if a malicious
+ user tried something like `\.{\\catcode\'15=0}'. The algorithm might
+ look at |buffer[ilimit+1]|, but it never looks at |buffer[ilimit+2]|.
+
+ If expanded characters like `\.{\^\^A}' or `\.{\^\^df}'
+ appear in or just following
+ a control sequence name, they are converted to single characters in the
+ buffer and the process is repeated, slowly but surely.
+
+@c
+static boolean check_expanded_code(int *kk); /* below */
+
+static int scan_control_sequence(void)
+{
+ int retval = mid_line;
+ if (iloc > ilimit) {
+ cur_cs = null_cs; /* |state| is irrelevant in this case */
+ } else {
+ register int cat; /* |cat_code(cur_chr)|, usually */
+ while (1) {
+ int k = iloc;
+ do_buffer_to_unichar(cur_chr, k);
+ do_get_cat_code(cat);
+ if (cat != letter_cmd || k > ilimit) {
+ retval = (cat == spacer_cmd ? skip_blanks : mid_line);
+ if (cat == sup_mark_cmd && check_expanded_code(&k)) /* If an expanded...; */
+ continue;
+ } else {
+ retval = skip_blanks;
+ do {
+ do_buffer_to_unichar(cur_chr, k);
+ do_get_cat_code(cat);
+ } while (cat == letter_cmd && k <= ilimit);
+
+ if (cat == sup_mark_cmd && check_expanded_code(&k)) /* If an expanded...; */
+ continue;
+ if (cat != letter_cmd) {
+ decr(k);
+ if (cur_chr > 0xFFFF)
+ decr(k);
+ if (cur_chr > 0x7FF)
+ decr(k);
+ if (cur_chr > 0x7F)
+ decr(k);
+ } /* now |k| points to first nonletter */
+ }
+ cur_cs = id_lookup(iloc, k - iloc);
+ iloc = k;
+ break;
+ }
+ }
+ cur_cmd = eq_type(cur_cs);
+ cur_chr = equiv(cur_cs);
+ return retval;
+}
+
+@ Whenever we reach the following piece of code, we will have
+ |cur_chr=buffer[k-1]| and |k<=ilimit+1| and |cat=get_cat_code(cat_code_table,cur_chr)|. If an
+ expanded code like \.{\^\^A} or \.{\^\^df} appears in |buffer[(k-1)..(k+1)]|
+ or |buffer[(k-1)..(k+2)]|, we
+ will store the corresponding code in |buffer[k-1]| and shift the rest of
+ the buffer left two or three places.
+
+@c
+static boolean check_expanded_code(int *kk)
+{
+ int l;
+ int k = *kk;
+ int d = 1; /* number of excess characters in an expanded code */
+ int c, cc, ccc, cccc, ccccc, cccccc; /* constituents of a possible expanded code */
+ if (buffer[k] == cur_chr && k < ilimit) {
+ if ((cur_chr == buffer[k + 1]) && (cur_chr == buffer[k + 2])
+ && ((k + 6) <= ilimit)) {
+ d = 4;
+ if ((cur_chr == buffer[k + 3]) && ((k + 8) <= ilimit))
+ d = 5;
+ if ((cur_chr == buffer[k + 4]) && ((k + 10) <= ilimit))
+ d = 6;
+ c = buffer[k + d - 1];
+ cc = buffer[k + d];
+ ccc = buffer[k + d + 1];
+ cccc = buffer[k + d + 2];
+ if (d == 6) {
+ ccccc = buffer[k + d + 3];
+ cccccc = buffer[k + d + 4];
+ if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc)
+ && is_hex(ccccc) && is_hex(cccccc))
+ six_hex_to_cur_chr;
+ } else if (d == 5) {
+ ccccc = buffer[k + d + 3];
+ if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc)
+ && is_hex(ccccc))
+ five_hex_to_cur_chr;
+ } else {
+ if (is_hex(c) && is_hex(cc) && is_hex(ccc) && is_hex(cccc))
+ four_hex_to_cur_chr;
+ }
+ } else {
+ c = buffer[k + 1];
+ if (c < 0200) {
+ d = 1;
+ if (is_hex(c) && (k + 2) <= ilimit) {
+ cc = buffer[k + 2];
+ if (is_hex(c) && is_hex(cc)) {
+ d = 2;
+ hex_to_cur_chr;
+ }
+ } else if (c < 0100) {
+ cur_chr = c + 0100;
+ } else {
+ cur_chr = c - 0100;
+ }
+ }
+ }
+ if (d > 2)
+ d = 2 * d - 1;
+ else
+ d++;
+ if (cur_chr <= 0x7F) {
+ buffer[k - 1] = (packed_ASCII_code) cur_chr;
+ } else if (cur_chr <= 0x7FF) {
+ buffer[k - 1] = (packed_ASCII_code) (0xC0 + cur_chr / 0x40);
+ k++;
+ d--;
+ buffer[k - 1] = (packed_ASCII_code) (0x80 + cur_chr % 0x40);
+ } else if (cur_chr <= 0xFFFF) {
+ buffer[k - 1] = (packed_ASCII_code) (0xE0 + cur_chr / 0x1000);
+ k++;
+ d--;
+ buffer[k - 1] =
+ (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) / 0x40);
+ k++;
+ d--;
+ buffer[k - 1] =
+ (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) % 0x40);
+ } else {
+ buffer[k - 1] = (packed_ASCII_code) (0xF0 + cur_chr / 0x40000);
+ k++;
+ d--;
+ buffer[k - 1] =
+ (packed_ASCII_code) (0x80 + (cur_chr % 0x40000) / 0x1000);
+ k++;
+ d--;
+ buffer[k - 1] =
+ (packed_ASCII_code) (0x80 +
+ ((cur_chr % 0x40000) % 0x1000) / 0x40);
+ k++;
+ d--;
+ buffer[k - 1] =
+ (packed_ASCII_code) (0x80 +
+ ((cur_chr % 0x40000) % 0x1000) % 0x40);
+ }
+ l = k;
+ ilimit = ilimit - d;
+ while (l <= ilimit) {
+ buffer[l] = buffer[l + d];
+ l++;
+ }
+ *kk = k;
+ return true;
+ }
+ return false;
+}
+
+@ todo: this is a function because it is still used from the converted pascal.
+ once that is gone, it can be a \#define again
+
+@c
+boolean end_line_char_inactive(void)
+{
+ return ((end_line_char < 0) || (end_line_char > 127));
+}
+
+@ All of the easy branches of |get_next| have now been taken care of.
+ There is one more branch.
+
+@c
+static next_line_retval next_line(void)
+{
+ boolean inhibit_eol = false; /* a way to end a pseudo file without trailing space */
+ if (iname > 17) {
+ /* Read next line of file into |buffer|, or |goto restart| if the file has ended */
+ incr(line);
+ first = istart;
+ if (!force_eof) {
+ if (iname <= 20) {
+ if (pseudo_input()) { /* not end of file */
+ firm_up_the_line(); /* this sets |ilimit| */
+ line_catcode_table = DEFAULT_CAT_TABLE;
+ if ((iname == 19) && (pseudo_lines(pseudo_files) == null))
+ inhibit_eol = true;
+ } else if ((every_eof != null) && !eof_seen[iindex]) {
+ ilimit = first - 1;
+ eof_seen[iindex] = true; /* fake one empty line */
+ if (iname != 19)
+ begin_token_list(every_eof, every_eof_text);
+ return next_line_restart;
+ } else {
+ force_eof = true;
+ }
+ } else {
+ if (iname == 21) {
+ if (luacstring_input()) { /* not end of strings */
+ firm_up_the_line();
+ line_catcode_table = (short) luacstring_cattable();
+ line_partial = (signed char) luacstring_partial();
+ if (luacstring_final_line() || line_partial
+ || line_catcode_table == NO_CAT_TABLE)
+ inhibit_eol = true;
+ if (!line_partial)
+ istate = new_line;
+ } else {
+ force_eof = true;
+ }
+ } else {
+ if (lua_input_ln(cur_file, 0, true)) { /* not end of file */
+ firm_up_the_line(); /* this sets |ilimit| */
+ line_catcode_table = DEFAULT_CAT_TABLE;
+ } else if ((every_eof != null) && (!eof_seen[iindex])) {
+ ilimit = first - 1;
+ eof_seen[iindex] = true; /* fake one empty line */
+ begin_token_list(every_eof, every_eof_text);
+ return next_line_restart;
+ } else {
+ force_eof = true;
+ }
+ }
+ }
+ }
+ if (force_eof) {
+ if (tracing_nesting > 0)
+ if ((grp_stack[in_open] != cur_boundary)
+ || (if_stack[in_open] != cond_ptr))
+ if (!((iname == 19) || (iname == 21)))
+ file_warning(); /* give warning for some unfinished groups and/or conditionals */
+ if ((iname > 21) || (iname == 20)) {
+ if (tracefilenames)
+ print_char(')');
+ open_parens--;
+#if 0
+ update_terminal(); /* show user that file has been read */
+#endif
+ }
+ force_eof = false;
+ if (iname == 21 || /* lua input */
+ iname == 19) { /* \.{\\scantextokens} */
+ end_file_reading();
+ } else {
+ end_file_reading();
+ check_outer_validity();
+ }
+ return next_line_restart;
+ }
+ if (inhibit_eol || end_line_char_inactive())
+ ilimit--;
+ else
+ buffer[ilimit] = (packed_ASCII_code) end_line_char;
+ first = ilimit + 1;
+ iloc = istart; /* ready to read */
+ } else {
+ if (!terminal_input) { /* \.{\\read} line has ended */
+ cur_cmd = 0;
+ cur_chr = 0;
+ return next_line_return; /* OUTER */
+ }
+ if (input_ptr > 0) { /* text was inserted during error recovery */
+ end_file_reading();
+ return next_line_restart; /* resume previous level */
+ }
+ if (selector < log_only)
+ open_log_file();
+ if (interaction > nonstop_mode) {
+ if (end_line_char_inactive())
+ ilimit++;
+ if (ilimit == istart) { /* previous line was empty */
+ tprint_nl("(Please type a command or say `\\end')");
+ }
+ print_ln();
+ first = istart;
+ prompt_input("*"); /* input on-line into |buffer| */
+ ilimit = last;
+ if (end_line_char_inactive())
+ ilimit--;
+ else
+ buffer[ilimit] = (packed_ASCII_code) end_line_char;
+ first = ilimit + 1;
+ iloc = istart;
+ } else {
+ fatal_error("*** (job aborted, no legal \\end found)");
+ /* nonstop mode, which is intended for overnight batch processing,
+ never waits for on-line input */
+ }
+ }
+ return next_line_ok;
+}
+
+@ Let's consider now what happens when |get_next| is looking at a token list.
+
+@c
+static boolean get_next_tokenlist(void)
+{
+ register halfword t; /* a token */
+ t = token_info(iloc);
+ iloc = token_link(iloc); /* move to next */
+ if (t >= cs_token_flag) { /* a control sequence token */
+ cur_cs = t - cs_token_flag;
+ cur_cmd = eq_type(cur_cs);
+ if (cur_cmd >= outer_call_cmd) {
+ if (cur_cmd == dont_expand_cmd) { /* Get the next token, suppressing expansion */
+ /* The present point in the program is reached only when the |expand|
+ routine has inserted a special marker into the input. In this special
+ case, |token_info(iloc)| is known to be a control sequence token, and |token_link(iloc)=null|.
+ */
+ cur_cs = token_info(iloc) - cs_token_flag;
+ iloc = null;
+ cur_cmd = eq_type(cur_cs);
+ if (cur_cmd > max_command_cmd) {
+ cur_cmd = relax_cmd;
+ cur_chr = no_expand_flag;
+ return true;
+ }
+ } else {
+ check_outer_validity();
+ }
+ }
+ cur_chr = equiv(cur_cs);
+ } else {
+ cur_cmd = token_cmd(t);
+ cur_chr = token_chr(t);
+ switch (cur_cmd) {
+ case left_brace_cmd:
+ align_state++;
+ break;
+ case right_brace_cmd:
+ align_state--;
+ break;
+ case out_param_cmd: /* Insert macro parameter and |goto restart|; */
+ begin_token_list(param_stack[param_start + cur_chr - 1], parameter);
+ return false;
+ break;
+ }
+ }
+ return true;
+}
+
+@ Now we're ready to take the plunge into |get_next| itself. Parts of
+ this routine are executed more often than any other instructions of \TeX.
+ @^mastication@>@^inner loop@>
+
+@ sets |cur_cmd|, |cur_chr|, |cur_cs| to next token
+
+@c
+void get_next(void)
+{
+ RESTART:
+ cur_cs = 0;
+ if (istate != token_list) {
+ /* Input from external file, |goto restart| if no input found */
+ if (!get_next_file())
+ goto RESTART;
+ } else {
+ if (iloc == null) {
+ end_token_list();
+ goto RESTART; /* list exhausted, resume previous level */
+ } else if (!get_next_tokenlist()) {
+ goto RESTART; /* parameter needs to be expanded */
+ }
+ }
+ /* If an alignment entry has just ended, take appropriate action */
+ if ((cur_cmd == tab_mark_cmd || cur_cmd == car_ret_cmd) && align_state == 0) {
+ insert_vj_template();
+ goto RESTART;
+ }
+}
+
+
+@ Since |get_next| is used so frequently in \TeX, it is convenient
+to define three related procedures that do a little more:
+
+\yskip\hang|get_token| not only sets |cur_cmd| and |cur_chr|, it
+also sets |cur_tok|, a packed halfword version of the current token.
+
+\yskip\hang|get_x_token|, meaning ``get an expanded token,'' is like
+|get_token|, but if the current token turns out to be a user-defined
+control sequence (i.e., a macro call), or a conditional,
+or something like \.{\\topmark} or \.{\\expandafter} or \.{\\csname},
+it is eliminated from the input by beginning the expansion of the macro
+or the evaluation of the conditional.
+
+\yskip\hang|x_token| is like |get_x_token| except that it assumes that
+|get_next| has already been called.
+
+\yskip\noindent
+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
+|no_new_control_sequence| is always |true| at other times.
+
+@c
+void get_token(void)
+{ /* sets |cur_cmd|, |cur_chr|, |cur_tok| */
+ no_new_control_sequence = false;
+ get_token_lua();
+ no_new_control_sequence = true;
+ if (cur_cs == 0)
+ cur_tok = token_val(cur_cmd, cur_chr);
+ else
+ cur_tok = cs_token_flag + cur_cs;
+}
+
+@ @c
+void get_token_lua(void)
+{
+ register int callback_id;
+ callback_id = callback_defined(token_filter_callback);
+ if (callback_id > 0) {
+ while (istate == token_list && iloc == null && iindex != v_template)
+ end_token_list();
+ /* there is some stuff we don't want to see inside the callback */
+ if (!(istate == token_list &&
+ ((nofilter == true) || (iindex == backed_up && iloc != null)))) {
+ do_get_token_lua(callback_id);
+ return;
+ }
+ }
+ get_next();
+}
+
+
+@ changes the string |s| to a token list
+@c
+halfword string_to_toks(char *ss)
+{
+ halfword p; /* tail of the token list */
+ halfword q; /* new node being added to the token list via |store_new_token| */
+ halfword t; /* token being appended */
+ char *s = ss, *se = ss + strlen(s);
+ p = temp_token_head;
+ set_token_link(p, null);
+ while (s < se) {
+ t = (halfword) str2uni((unsigned char *) s);
+ s += utf8_size(t);
+ if (t == ' ')
+ t = space_token;
+ else
+ t = other_token + t;
+ fast_store_new_token(t);
+ }
+ return token_link(temp_token_head);
+}
+
+@ The token lists for macros and for other things like \.{\\mark} and \.{\\output}
+and \.{\\write} are produced by a procedure called |scan_toks|.
+
+Before we get into the details of |scan_toks|, let's consider a much
+simpler task, that of converting the current string into a token list.
+The |str_toks| function does this; it classifies spaces as type |spacer|
+and everything else as type |other_char|.
+
+The token list created by |str_toks| begins at |link(temp_token_head)| and ends
+at the value |p| that is returned. (If |p=temp_token_head|, the list is empty.)
+
+|lua_str_toks| is almost identical, but it also escapes the three
+symbols that |lua| considers special while scanning a literal string
+
+@c
+static halfword lua_str_toks(lstring b)
+{ /* changes the string |str_pool[b..pool_ptr]| to a token list */
+ halfword p; /* tail of the token list */
+ halfword q; /* new node being added to the token list via |store_new_token| */
+ halfword t; /* token being appended */
+ unsigned char *k; /* index into string */
+ p = temp_token_head;
+ set_token_link(p, null);
+ k = (unsigned char *) b.s;
+ while (k < (unsigned char *) b.s + b.l) {
+ t = pool_to_unichar(k);
+ k += utf8_size(t);
+ if (t == ' ') {
+ t = space_token;
+ } else {
+ if ((t == '\\') || (t == '"') || (t == '\'') || (t == 10)
+ || (t == 13))
+ fast_store_new_token(other_token + '\\');
+ if (t == 10)
+ t = 'n';
+ if (t == 13)
+ t = 'r';
+ t = other_token + t;
+ }
+ fast_store_new_token(t);
+ }
+ return p;
+}
+
+
+@ Incidentally, the main reason for wanting |str_toks| is the function |the_toks|,
+which has similar input/output characteristics.
+
+@c
+halfword str_toks(lstring s)
+{ /* changes the string |str_pool[b..pool_ptr]| to a token list */
+ halfword p; /* tail of the token list */
+ halfword q; /* new node being added to the token list via |store_new_token| */
+ halfword t; /* token being appended */
+ unsigned char *k, *l; /* index into string */
+ p = temp_token_head;
+ set_token_link(p, null);
+ k = s.s;
+ l = k + s.l;
+ while (k < l) {
+ t = pool_to_unichar(k);
+ k += utf8_size(t);
+ if (t == ' ')
+ t = space_token;
+ else
+ t = other_token + t;
+ fast_store_new_token(t);
+ }
+ return p;
+}
+
+@ Here's part of the |expand| subroutine that we are now ready to complete:
+@c
+void ins_the_toks(void)
+{
+ (void) the_toks();
+ ins_list(token_link(temp_token_head));
+}
+
+
+@ Here is a routine that print the result of a convert command, using
+ the argument |i|. It returns |false | if it does not know to print
+ the code |c|. The function exists because lua code and tex code can
+ both call it to convert something.
+
+@c
+static boolean print_convert_string(halfword c, int i)
+{
+ int ff; /* for use with |set_ff| */
+ boolean ret = true;
+ switch (c) {
+ case number_code:
+ print_int(i);
+ break;
+ case roman_numeral_code:
+ print_roman_int(i);
+ break;
+ case etex_code:
+ tprint(eTeX_version_string);
+ break;
+ case omega_code:
+ tprint(Omega_version_string);
+ break;
+ case aleph_code:
+ tprint(Aleph_version_string);
+ break;
+ case pdftex_revision_code:
+ tprint(pdftex_revision);
+ break;
+ case luatex_revision_code:
+ print(get_luatexrevision());
+ break;
+ case luatex_date_code:
+ print_int(get_luatex_date_info());
+ break;
+ case pdftex_banner_code:
+ tprint(pdftex_banner);
+ break;
+ case uniform_deviate_code:
+ print_int(unif_rand(i));
+ break;
+ case normal_deviate_code:
+ print_int(norm_rand());
+ break;
+ case format_name_code:
+ print(format_name);
+ break;
+ case job_name_code:
+ print(job_name);
+ break;
+ case font_name_code:
+ append_string((unsigned char *) font_name(i),
+ (unsigned) strlen(font_name(i)));
+ if (font_size(i) != font_dsize(i)) {
+ tprint(" at ");
+ print_scaled(font_size(i));
+ tprint("pt");
+ }
+ break;
+ case math_style_code:
+ print_math_style();
+ break;
+ case pdf_font_name_code:
+ case pdf_font_objnum_code:
+ set_ff(i);
+ if (c == pdf_font_name_code)
+ print_int(obj_info(static_pdf, pdf_font_num(ff)));
+ else
+ print_int(pdf_font_num(ff));
+ break;
+ case pdf_font_size_code:
+ print_scaled(font_size(i));
+ tprint("pt");
+ break;
+ case pdf_page_ref_code:
+ print_int(get_obj(static_pdf, obj_type_page, i, false));
+ break;
+ case pdf_xform_name_code:
+ print_int(obj_info(static_pdf, i));
+ break;
+ case Aleph_revision_code:
+ tprint(Aleph_revision);
+ break;
+ case Omega_revision_code:
+ tprint(Omega_revision);
+ break;
+ case eTeX_revision_code:
+ tprint(eTeX_revision);
+ break;
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+@ @c
+int scan_lua_state(void)
+{
+ int sn = 0;
+ if (scan_keyword("name")) {
+ scan_pdf_ext_toks();
+ sn = def_ref;
+ }
+ /* Parse optional lua state integer, or an instance name to be stored in |sn| */
+ /* Get the next non-blank non-relax non-call token */
+ do {
+ get_x_token();
+ } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
+
+ back_input(); /* have to push it back, whatever it is */
+ if (cur_cmd != left_brace_cmd) {
+ scan_register_num();
+ if (get_lua_name(cur_val))
+ sn = (cur_val - 65536);
+ }
+ return sn;
+}
+
+
+@ 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}'.
+
+The extra temp string |u| is needed because |pdf_scan_ext_toks| incorporates
+any pending string in its output. In order to save such a pending string,
+we have to create a temporary string that is destroyed immediately after.
+
+@c
+void conv_toks(void)
+{
+ int old_setting; /* holds |selector| setting */
+ halfword p, q;
+ int save_scanner_status; /* |scanner_status| upon entry */
+ halfword save_def_ref; /* |def_ref| upon entry, important if inside `\.{\\message}' */
+ halfword save_warning_index;
+ boolean bool; /* temp boolean */
+ str_number s; /* first temp string */
+ int sn; /* lua chunk name */
+ str_number u = 0; /* third temp string, will become non-nil if a string is already being built */
+ int i = 0; /* first temp integer */
+ int j = 0; /* second temp integer */
+ int c = cur_chr; /* desired type of conversion */
+ str_number str;
+ /* Scan the argument for command |c| */
+ switch (c) {
+ case number_code:
+ case roman_numeral_code:
+ scan_int();
+ break;
+ case string_code:
+ case meaning_code:
+ save_scanner_status = scanner_status;
+ scanner_status = normal;
+ get_token();
+ scanner_status = save_scanner_status;
+ break;
+ case etex_code:
+ case omega_code:
+ case aleph_code:
+ break;
+ case font_name_code:
+ scan_font_ident();
+ break;
+ case pdftex_revision_code:
+ case luatex_revision_code:
+ case luatex_date_code:
+ case pdftex_banner_code:
+ break;
+ case pdf_font_name_code:
+ case pdf_font_objnum_code:
+ case pdf_font_size_code:
+ scan_font_ident();
+ if (cur_val == null_font)
+ pdf_error("font", "invalid font identifier");
+ if (c != pdf_font_size_code) {
+ pdf_check_vf(cur_val);
+ if (!font_used(cur_val))
+ pdf_init_font(static_pdf, cur_val);
+ }
+ break;
+ case pdf_page_ref_code:
+ scan_int();
+ if (cur_val <= 0)
+ pdf_error("pageref", "invalid page number");
+ break;
+ case left_margin_kern_code:
+ case right_margin_kern_code:
+ scan_int();
+ if ((box(cur_val) == null) || (type(box(cur_val)) != hlist_node))
+ pdf_error("marginkern", "a non-empty hbox expected");
+ break;
+ case pdf_xform_name_code:
+ scan_int();
+ check_obj_exists(static_pdf, obj_type_xform, cur_val);
+ break;
+ case pdf_creation_date_code:
+ ins_list(string_to_toks(getcreationdate(static_pdf)));
+ return;
+ break;
+ case format_name_code:
+ case job_name_code:
+ if (job_name == 0)
+ open_log_file();
+ break;
+ case pdf_colorstack_init_code:
+ bool = scan_keyword("page");
+ if (scan_keyword("direct"))
+ cur_val = direct_always;
+ else if (scan_keyword("page"))
+ cur_val = direct_page;
+ else
+ cur_val = set_origin;
+ save_scanner_status = scanner_status;
+ save_warning_index = warning_index;
+ save_def_ref = def_ref;
+ u = save_cur_string();
+ scan_pdf_ext_toks();
+ s = tokens_to_string(def_ref);
+ delete_token_ref(def_ref);
+ def_ref = save_def_ref;
+ warning_index = save_warning_index;
+ scanner_status = save_scanner_status;
+ cur_val = newcolorstack(s, cur_val, bool);
+ flush_str(s);
+ cur_val_level = int_val_level;
+ if (cur_val < 0) {
+ print_err("Too many color stacks");
+ help2("The number of color stacks is limited to 32768.",
+ "I'll use the default color stack 0 here.");
+ error();
+ cur_val = 0;
+ restore_cur_string(u);
+ }
+ break;
+ case uniform_deviate_code:
+ scan_int();
+ break;
+ case normal_deviate_code:
+ break;
+ case lua_escape_string_code:
+ {
+ lstring str;
+ int l = 0;
+ save_scanner_status = scanner_status;
+ save_def_ref = def_ref;
+ save_warning_index = warning_index;
+ scan_pdf_ext_toks();
+ bool = in_lua_escape;
+ in_lua_escape = true;
+ str.s = (unsigned char *) tokenlist_to_cstring(def_ref, false, &l);
+ str.l = (unsigned) l;
+ in_lua_escape = bool;
+ delete_token_ref(def_ref);
+ def_ref = save_def_ref;
+ warning_index = save_warning_index;
+ scanner_status = save_scanner_status;
+ (void) lua_str_toks(str);
+ ins_list(token_link(temp_token_head));
+ free(str.s);
+ return;
+ }
+ break;
+ case math_style_code:
+ break;
+ case expanded_code:
+ save_scanner_status = scanner_status;
+ save_warning_index = warning_index;
+ save_def_ref = def_ref;
+ u = save_cur_string();
+ scan_pdf_ext_toks();
+ warning_index = save_warning_index;
+ scanner_status = save_scanner_status;
+ ins_list(token_link(def_ref));
+ def_ref = save_def_ref;
+ restore_cur_string(u);
+ return;
+ break;
+ case lua_code:
+ u = save_cur_string();
+ save_scanner_status = scanner_status;
+ save_def_ref = def_ref;
+ save_warning_index = warning_index;
+ sn = scan_lua_state();
+ 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(s, sn);
+ delete_token_ref(s);
+ restore_cur_string(u); /* TODO: check this, was different */
+ if (luacstrings > 0)
+ lua_string_start();
+ return;
+ break;
+ case pdf_insert_ht_code:
+ scan_register_num();
+ break;
+ case pdf_ximage_bbox_code:
+ scan_int();
+ check_obj_exists(static_pdf, obj_type_ximage, cur_val);
+ i = obj_data_ptr(static_pdf, cur_val);
+ scan_int();
+ j = cur_val;
+ if ((j < 1) || (j > 4))
+ pdf_error("pdfximagebbox", "invalid parameter");
+ break;
+ /* Cases of 'Scan the argument for command |c|' */
+ case Aleph_revision_code:
+ case Omega_revision_code:
+ case eTeX_revision_code:
+ break;
+ default:
+ confusion("convert");
+ break;
+ }
+
+ old_setting = selector;
+ selector = new_string;
+
+ /* Print the result of command |c| */
+ if (!print_convert_string(c, cur_val)) {
+ switch (c) {
+ case string_code:
+ if (cur_cs != 0)
+ sprint_cs(cur_cs);
+ else
+ print(cur_chr);
+ break;
+ case meaning_code:
+ print_meaning();
+ break;
+ case left_margin_kern_code:
+ p = list_ptr(box(cur_val));
+ if ((p != null) && (!is_char_node(p)) &&
+ (type(p) == glue_node) && (subtype(p) == left_skip_code + 1))
+ p = vlink(p);
+ if ((p != null) && (!is_char_node(p)) &&
+ (type(p) == margin_kern_node) && (subtype(p) == left_side))
+ print_scaled(width(p));
+ else
+ print_char('0');
+ tprint("pt");
+ break;
+ case right_margin_kern_code:
+ q = list_ptr(box(cur_val));
+ p = null;
+ if (q != null) {
+ p = prev_rightmost(q, null);
+ if ((p != null) && (!is_char_node(p)) && (type(p) == glue_node)
+ && (subtype(p) == right_skip_code + 1))
+ p = prev_rightmost(q, p);
+ }
+ if ((p != null) && (!is_char_node(p)) &&
+ (type(p) == margin_kern_node) && (subtype(p) == right_side))
+ print_scaled(width(p));
+ else
+ print_char('0');
+ tprint("pt");
+ break;
+ case pdf_colorstack_init_code:
+ print_int(cur_val);
+ break;
+ case pdf_insert_ht_code:
+ i = cur_val;
+ p = page_ins_head;
+ while (i >= subtype(vlink(p)))
+ p = vlink(p);
+ if (subtype(p) == i)
+ print_scaled(height(p));
+ else
+ print_char('0');
+ tprint("pt");
+ break;
+ case pdf_ximage_bbox_code:
+ if (is_pdf_image(i)) {
+ switch (j) {
+ case 1:
+ print_scaled(epdf_orig_x(i));
+ break;
+ case 2:
+ print_scaled(epdf_orig_y(i));
+ break;
+ case 3:
+ print_scaled(epdf_orig_x(i) + epdf_xsize(i));
+ break;
+ case 4:
+ print_scaled(epdf_orig_y(i) + epdf_ysize(i));
+ break;
+ }
+ } else {
+ print_scaled(0);
+ }
+ tprint("pt");
+ break;
+ case pdf_creation_date_code:
+ case lua_escape_string_code:
+ case lua_code:
+ case expanded_code:
+ break;
+ default:
+ confusion("convert");
+ break;
+ }
+ }
+
+ selector = old_setting;
+ str = make_string();
+ (void) str_toks(str_lstring(str));
+ flush_str(str);
+ ins_list(token_link(temp_token_head));
+}
+
+@ This boolean is keeping track of the lua string escape state
+@c
+boolean in_lua_escape;
+
+@ probably not needed anymore
+@c
+boolean is_convert(halfword c)
+{
+ return (c == convert_cmd);
+}
+
+str_number the_convert_string(halfword c, int i)
+{
+ int old_setting; /* saved |selector| setting */
+ str_number ret = 0;
+ old_setting = selector;
+ selector = new_string;
+ if (print_convert_string(c, i)) {
+ ret = make_string();
+ } else if (c == font_identifier_code) {
+ print_font_identifier(i);
+ ret = make_string();
+ }
+ selector = old_setting;
+ return ret;
+}
+
+@ Another way to create a token list is via the \.{\\read} command. The
+sixteen files potentially usable for reading appear in the following
+global variables. The value of |read_open[n]| will be |closed| if
+stream number |n| has not been opened or if it has been fully read;
+|just_open| if an \.{\\openin} but not a \.{\\read} has been done;
+and |normal| if it is open and ready to read the next line.
+
+@c
+FILE *read_file[16]; /* used for \.{\\read} */
+int read_open[17]; /* state of |read_file[n]| */
+
+void initialize_read(void)
+{
+ int k;
+ for (k = 0; k <= 16; k++)
+ read_open[k] = closed;
+}
+
+@ The |read_toks| procedure constructs a token list like that for any
+macro definition, and makes |cur_val| point to it. Parameter |r| points
+to the control sequence that will receive this token list.
+
+@c
+void read_toks(int n, halfword r, halfword j)
+{
+ halfword p; /* tail of the token list */
+ halfword q; /* new node being added to the token list via |store_new_token| */
+ int s; /* saved value of |align_state| */
+ int m; /* stream number */
+ scanner_status = defining;
+ warning_index = r;
+ p = get_avail();
+ def_ref = p;
+ set_token_ref_count(def_ref, 0);
+ p = def_ref; /* the reference count */
+ store_new_token(end_match_token);
+ if ((n < 0) || (n > 15))
+ m = 16;
+ else
+ m = n;
+ s = align_state;
+ align_state = 1000000; /* disable tab marks, etc. */
+ do {
+ /* Input and store tokens from the next line of the file */
+ begin_file_reading();
+ iname = m + 1;
+ if (read_open[m] == closed) {
+ /* Input for \.{\\read} from the terminal */
+ /* Here we input on-line into the |buffer| array, prompting the user explicitly
+ if |n>=0|. The value of |n| is set negative so that additional prompts
+ will not be given in the case of multi-line input. */
+ if (interaction > nonstop_mode) {
+ if (n < 0) {
+ prompt_input("");
+ } else {
+ wake_up_terminal();
+ print_ln();
+ sprint_cs(r);
+ prompt_input(" =");
+ n = -1;
+ }
+ } else {
+ fatal_error
+ ("*** (cannot \\read from terminal in nonstop modes)");
+ }
+
+ } else if (read_open[m] == just_open) {
+ /* Input the first line of |read_file[m]| */
+ /* The first line of a file must be treated specially, since |lua_input_ln|
+ must be told not to start with |get|. */
+ if (lua_input_ln(read_file[m], (m + 1), false)) {
+ read_open[m] = normal;
+ } else {
+ lua_a_close_in(read_file[m], (m + 1));
+ read_open[m] = closed;
+ }
+
+ } else {
+ /* Input the next line of |read_file[m]| */
+ /* An empty line is appended at the end of a |read_file|. */
+ if (!lua_input_ln(read_file[m], (m + 1), true)) {
+ lua_a_close_in(read_file[m], (m + 1));
+ read_open[m] = closed;
+ if (align_state != 1000000) {
+ runaway();
+ print_err("File ended within \\read");
+ help1("This \\read has unbalanced braces.");
+ align_state = 1000000;
+ error();
+ }
+ }
+
+ }
+ ilimit = last;
+ if (end_line_char_inactive())
+ decr(ilimit);
+ else
+ buffer[ilimit] = (packed_ASCII_code) int_par(end_line_char_code);
+ first = ilimit + 1;
+ iloc = istart;
+ istate = new_line;
+ /* Handle \.{\\readline} and |goto done|; */
+ if (j == 1) {
+ while (iloc <= ilimit) { /* current line not yet finished */
+ cur_chr = buffer[iloc];
+ incr(iloc);
+ if (cur_chr == ' ')
+ cur_tok = space_token;
+ else
+ cur_tok = cur_chr + other_token;
+ store_new_token(cur_tok);
+ }
+ } else {
+ while (1) {
+ get_token();
+ if (cur_tok == 0)
+ break; /* |cur_cmd=cur_chr=0| will occur at the end of the line */
+ if (align_state < 1000000) { /* unmatched `\.\}' aborts the line */
+ do {
+ get_token();
+ } while (cur_tok != 0);
+ align_state = 1000000;
+ break;
+ }
+ store_new_token(cur_tok);
+ }
+ }
+ end_file_reading();
+
+ } while (align_state != 1000000);
+ cur_val = def_ref;
+ scanner_status = normal;
+ align_state = s;
+}
+
+@ @c
+str_number tokens_to_string(halfword p)
+{ /* return a string from tokens list */
+ int old_setting;
+ if (selector == new_string)
+ pdf_error("tokens",
+ "tokens_to_string() called while selector = new_string");
+ old_setting = selector;
+ selector = new_string;
+ show_token_list(token_link(p), null, -1);
+ selector = old_setting;
+ return make_string();
+}
+
+@ @c
+#define make_room(a) \
+ if ((unsigned)i+a+1>alloci) { \
+ ret = xrealloc(ret,(alloci+64)); \
+ alloci = alloci + 64; \
+ }
+
+
+#define append_i_byte(a) ret[i++] = (char)(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) { \
+ const char *v = b; \
+ if (e>0 && e<STRING_OFFSET) { \
+ Print_uchar (e); \
+ } \
+ make_room(strlen(v)); \
+ while (*v) { append_i_byte(*v); v++; } \
+ }
+
+#define is_cat_letter(a) \
+ (get_char_cat_code(pool_to_unichar(str_string((a)))) == 11)
+
+@ the actual token conversion in this function is now functionally
+ equivalent to |show_token_list|, except that it always prints the
+ whole token list.
+ TODO: check whether this causes problems in the lua library.
+
+@c
+char *tokenlist_to_cstring(int pp, int inhibit_par, int *siz)
+{
+ register int p, c, m;
+ int q;
+ int infop;
+ char *s, *sh;
+ int e = 0;
+ char *ret;
+ int match_chr = '#';
+ int n = '0';
+ unsigned alloci = 1024;
+ int i = 0;
+ p = pp;
+ if (p == null) {
+ if (siz != NULL)
+ *siz = 0;
+ return NULL;
+ }
+ ret = xmalloc(alloci);
+ p = token_link(p); /* skip refcount */
+ if (p != null) {
+ e = int_par(escape_char_code);
+ }
+ while (p != null) {
+ if (p < (int) fix_mem_min || p > (int) fix_mem_end) {
+ Print_esc("CLOBBERED.");
+ break;
+ }
+ infop = token_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 {
+ Print_esc("IMPOSSIBLE.");
+ }
+ } else if ((q >= undefined_control_sequence)
+ && ((q <= eqtb_size)
+ || (q > eqtb_size + hash_extra))) {
+ Print_esc("IMPOSSIBLE.");
+ } else if ((cs_text(q) < 0) || (cs_text(q) >= str_ptr)) {
+ Print_esc("NONEXISTENT.");
+ } else {
+ str_number txt = cs_text(q);
+ sh = makecstring(txt);
+ s = sh;
+ 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(txt)) || is_cat_letter(txt)) {
+ Print_char(' ');
+ }
+ }
+ free(sh);
+ }
+ }
+ } else {
+ if (infop < 0) {
+ Print_esc("BAD.");
+ } else {
+ m = token_cmd(infop);
+ c = token_chr(infop);
+ switch (m) {
+ case left_brace_cmd:
+ case right_brace_cmd:
+ case math_shift_cmd:
+ case tab_mark_cmd:
+ case sup_mark_cmd:
+ case sub_mark_cmd:
+ case spacer_cmd:
+ case letter_cmd:
+ case other_char_cmd:
+ Print_uchar(c);
+ break;
+ case mac_param_cmd:
+ if (!in_lua_escape)
+ Print_uchar(c);
+ Print_uchar(c);
+ break;
+ case out_param_cmd:
+ Print_uchar(match_chr);
+ if (c <= 9) {
+ Print_char(c + '0');
+ } else {
+ Print_char('!');
+ goto EXIT;
+ }
+ break;
+ case match_cmd:
+ match_chr = c;
+ Print_uchar(c);
+ n++;
+ Print_char(n);
+ if (n > '9')
+ goto EXIT;
+ break;
+ case end_match_cmd:
+ if (c == 0) {
+ Print_char('-');
+ Print_char('>');
+ }
+ break;
+ default:
+ Print_esc("BAD.");
+ break;
+ }
+ }
+ }
+ p = token_link(p);
+ }
+ EXIT:
+ ret[i] = '\0';
+ if (siz != NULL)
+ *siz = i;
+ return ret;
+}
+
+@ @c
+lstring *tokenlist_to_lstring(int pp, int inhibit_par)
+{
+ int siz;
+ lstring *ret = xmalloc(sizeof(lstring));
+ ret->s = (unsigned char *) tokenlist_to_cstring(pp, inhibit_par, &siz);
+ ret->l = (size_t) siz;
+ return ret;
+}
+
+@ @c
+void free_lstring(lstring * ls)
+{
+ if (ls == NULL)
+ return;
+ if (ls->s != NULL)
+ free(ls->s);
+ free(ls);
+}
diff --git a/Build/source/texk/web2c/luatexdir/tokens.h b/Build/source/texk/web2c/luatexdir/tokens.h
deleted file mode 100644
index 92902ec4126..00000000000
--- a/Build/source/texk/web2c/luatexdir/tokens.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* tokens.h
-
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-/* $Id$ */
-
-#define token_list 0
-#define cs_token_flag 0x1FFFFFFF
-#define string_offset 0x200000
-#define string_offset_bits 21
-
-#define token_type index /* type of current token list */
-#define param_start limit /* base of macro parameters in |param_stack| */
-
-typedef enum {
- parameter = 0, /* code for parameter */
- u_template = 1, /* code for \<u_j> template */
- v_template = 2, /* code for \<v_j> template */
- backed_up = 3, /* code for text to be reread */
- inserted = 4, /* code for inserted texts */
- macro = 5, /* code for defined control sequences */
- output_text = 6, /* code for output routines */
- every_par_text = 7, /* code for \.{\\everypar} */
- every_math_text = 8, /* code for \.{\\everymath} */
- every_display_text = 9, /* code for \.{\\everydisplay} */
- every_hbox_text = 10, /* code for \.{\\everyhbox} */
- every_vbox_text = 11, /* code for \.{\\everyvbox} */
- every_job_text = 12, /* code for \.{\\everyjob}/ */
- every_cr_text = 13, /* code for \.{\\everycr} */
- mark_text = 14, /* code for \.{\\topmark}, etc. */
- every_eof_text = 19 /* was calculated, value fetched from the generated C */
-} token_types;
-
-#undef link /* defined by cpascal.h */
-#define info(a) fixmem[(a)].hhlh
-#define link(a) fixmem[(a)].hhrh
-
-#define store_new_token(a) { q=get_avail(); link(p)=q; info(q)=(a); p=q; }
-#define free_avail(a) { link((a))=avail; avail=(a); decr(dyn_used); }
-
-
-#define str_start_macro(a) str_start[(a) - string_offset]
-
-#define length(a) (str_start_macro((a)+1)-str_start_macro(a))
-
-#if defined(index)
-# undef index
-#endif
-
-#define loc cur_input.loc_field /* location of first unread character in |buffer| */
-#define state cur_input.state_field /* current scanner state */
-#define index cur_input.index_field /* reference for buffer information */
-#define start cur_input.start_field /* starting position in |buffer| */
-#define limit cur_input.limit_field /* end of current line in |buffer| */
-#define nofilter cur_input.nofilter_field /* is token filtering explicitly disallowed? */
-#define name cur_input.name_field /* name of the current file */
-#define current_ocp_lstack cur_input.ocp_lstack_field /* name of the current ocp */
-#define current_ocp_no cur_input.ocp_no_field /* name of the current ocp */
-#define line_catcode_table cur_input.cattable_field /* catcode table to use for this line */
-#define line_partial cur_input.partial_field
-
-#define max_char_code 15 /* largest catcode for individual characters */
-
-typedef enum {
- mid_line = 1, /* |state| code when scanning a line of characters */
- skip_blanks = 2 + max_char_code, /* |state| code when ignoring blanks */
- new_line = 3 + max_char_code + max_char_code, /* |state| code at start of line */
-} state_codes;
-
-
-extern void make_token_table(lua_State * L, int cmd, int chr, int cs);
diff --git a/Build/source/texk/web2c/luatexdir/utils/avl.c b/Build/source/texk/web2c/luatexdir/utils/avl.c
index 0c322f12071..894203d476e 100644
--- a/Build/source/texk/web2c/luatexdir/utils/avl.c
+++ b/Build/source/texk/web2c/luatexdir/utils/avl.c
@@ -1,4 +1,5 @@
/* Produced by texiweb from libavl.w. */
+/* *INDENT-OFF* */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
@@ -105,7 +106,8 @@ void **avl_probe(struct avl_table *tree, void *item)
if (p->avl_balance != 0)
z = q, y = p, k = 0;
- da[k++] = dir = cmp > 0;
+ dir = cmp > 0;
+ da[k++] = (unsigned char)dir;
}
n = q->avl_link[dir] =
@@ -227,7 +229,7 @@ void *avl_delete(struct avl_table *tree, const void *item)
int dir = cmp > 0;
pa[k] = p;
- da[k++] = dir;
+ da[k++] = (unsigned char)dir;
p = p->avl_link[dir];
if (p == NULL)
@@ -794,3 +796,4 @@ void *(avl_assert_delete) (struct avl_table * table, void *item) {
assert(p != NULL);
return p;
}
+/* *INDENT-ON* */
diff --git a/Build/source/texk/web2c/luatexdir/utils/avl.h b/Build/source/texk/web2c/luatexdir/utils/avl.h
index b9f9e3c01a9..1501ef0b271 100644
--- a/Build/source/texk/web2c/luatexdir/utils/avl.h
+++ b/Build/source/texk/web2c/luatexdir/utils/avl.h
@@ -1,4 +1,5 @@
/* Produced by texiweb from libavl.w. */
+/* *INDENT-OFF* */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
@@ -113,3 +114,4 @@ void *avl_t_cur (struct avl_traverser *);
void *avl_t_replace (struct avl_traverser *, void *);
#endif /* avl.h */
+/* *INDENT-ON* */
diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.c b/Build/source/texk/web2c/luatexdir/utils/avlstuff.c
deleted file mode 100644
index c2f2537cbd6..00000000000
--- a/Build/source/texk/web2c/luatexdir/utils/avlstuff.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* avlstuff.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "ptexlib.h"
-#include "avl.h"
-
-static const char __svn_version[] =
- "$Id: avlstuff.c 2599 2009-06-25 10:35:26Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/utils/avlstuff.c $";
-
-static struct avl_table **PdfObjTree = NULL;
-
-/**********************************************************************/
-/* memory management functions for AVL */
-
-static void *avl_xmalloc(struct libavl_allocator *allocator, size_t size)
-{
- assert(allocator != NULL && size > 0);
- return xmalloc(size);
-}
-
-static 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)
-{
- (void) p;
- cmp_return(*(const int *) pa, *(const int *) pb);
- return 0;
-}
-
-int comp_string_entry(const void *pa, const void *pb, void *p)
-{
- (void) p;
- return strcmp((const char *) pa, (const char *) pb);
-}
-
-/**********************************************************************/
-/* One AVL tree for each obj_type 0...pdf_objtype_max */
-
-typedef struct oentry_ {
- integer int0;
- integer objptr;
-} oentry;
-
-/* AVL sort oentry into avl_table[] */
-
-static int compare_info(const void *pa, const void *pb, void *param)
-{
- integer a, b;
- int as, ae, bs, be, al, bl;
- (void) param;
- 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;
- int i;
-
- if (PdfObjTree == NULL) {
- PdfObjTree = xtalloc(pdf_objtype_max + 1, struct avl_table *);
- for (i = 0; i <= pdf_objtype_max; i++)
- PdfObjTree[i] = NULL;
- }
- 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_info(objptr);
- oe->objptr = objptr; /* allows to relocate obj_tab */
- 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 == NULL || PdfObjTree[t] == NULL)
- return 0;
- p = (oentry *) avl_find(PdfObjTree[t], &tmp);
- if (p == NULL)
- return 0;
- return p->objptr;
-}
-
-/**********************************************************************/
-/* cleaning up... */
-
-static void destroy_oentry(void *pa, void *pb)
-{
- oentry *p = (oentry *) pa;
- (void) pb;
- xfree(p);
-}
-
-void PdfObjTree_free(void)
-{
- int i;
-
- if (PdfObjTree == NULL)
- return;
- for (i = 0; i <= pdf_objtype_max; i++) {
- if (PdfObjTree[i] != NULL)
- avl_destroy(PdfObjTree[i], destroy_oentry);
- }
- xfree(PdfObjTree);
- PdfObjTree = NULL;
-}
diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.h b/Build/source/texk/web2c/luatexdir/utils/avlstuff.h
index a7b565c5152..2b694c05efa 100644
--- a/Build/source/texk/web2c/luatexdir/utils/avlstuff.h
+++ b/Build/source/texk/web2c/luatexdir/utils/avlstuff.h
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: avlstuff.h 2328 2009-04-18 12:50:26Z hhenkel $ */
+/* $Id: avlstuff.h 2684 2009-06-29 13:01:53Z taco $ */
#ifndef AVLSTUFF_H
# define AVLSTUFF_H
@@ -29,8 +29,5 @@ extern struct libavl_allocator avl_xallocator;
int comp_int_entry(const void *, const void *, void *);
int comp_string_entry(const void *, const void *, void *);
-integer avl_find_obj(integer, integer, integer);
-void avl_put_obj(integer, integer);
-void PdfObjTree_free(void);
#endif /* AVLSTUFF_H */
diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.w b/Build/source/texk/web2c/luatexdir/utils/avlstuff.w
new file mode 100644
index 00000000000..b122d187d45
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/utils/avlstuff.w
@@ -0,0 +1,63 @@
+% avlstuff.w
+
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@* AVL helper functions.
+
+@ @c
+#include "ptexlib.h"
+#include "utils/avl.h"
+
+static const char _svn_version[] =
+ "$Id: avlstuff.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/utils/avlstuff.w $";
+
+@ memory management functions for AVL
+@c
+static void *avl_xmalloc(struct libavl_allocator *allocator, size_t size)
+{
+ assert(allocator != NULL && size > 0);
+ return xmalloc((unsigned) size);
+}
+
+static 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
+@c
+int comp_int_entry(const void *pa, const void *pb, void *p)
+{
+ (void) p;
+ cmp_return(*(const int *) pa, *(const int *) pb);
+ return 0;
+}
+
+int comp_string_entry(const void *pa, const void *pb, void *p)
+{
+ (void) p;
+ return strcmp((const char *) pa, (const char *) pb);
+}
diff --git a/Build/source/texk/web2c/luatexdir/managed-sa.h b/Build/source/texk/web2c/luatexdir/utils/managed-sa.h
index 3ba044ca0bb..185303a2e2c 100644
--- a/Build/source/texk/web2c/luatexdir/managed-sa.h
+++ b/Build/source/texk/web2c/luatexdir/utils/managed-sa.h
@@ -1,6 +1,6 @@
/* managed-sa.h
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id$ */
+/* $Id: managed-sa.h 3378 2010-01-25 20:46:26Z hhenkel $ */
#ifndef MANAGED_SA_H
# define MANAGED_SA_H 1
@@ -33,9 +33,9 @@
# 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((unsigned)((unsigned)(b)*sizeof(a)))
+# define Mxcalloc_array(a,b) xcalloc((b),sizeof(a))
+# define Mxrealloc_array(a,b,c) xrealloc((a),(unsigned)((unsigned)(c)*sizeof(b)))
typedef unsigned int sa_tree_item;
@@ -50,17 +50,18 @@ 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 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 int n);
+extern void set_sa_item(sa_tree head, int n, sa_tree_item v, int gl);
+extern void rawset_sa_item(sa_tree head, int n, sa_tree_item v);
-extern sa_tree new_sa_tree(integer size, sa_tree_item dflt);
+extern sa_tree new_sa_tree(int size, sa_tree_item dflt);
extern sa_tree copy_sa_tree(sa_tree head);
extern void destroy_sa_tree(sa_tree head);
@@ -68,9 +69,7 @@ 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 restore_sa_stack(sa_tree a, integer gl);
+extern void restore_sa_stack(sa_tree a, int gl);
extern void clear_sa_stack(sa_tree a);
-extern void rawset_sa_item(sa_tree hed, integer n, integer v);
-
#endif
diff --git a/Build/source/texk/web2c/luatexdir/managed-sa.c b/Build/source/texk/web2c/luatexdir/utils/managed-sa.w
index 8b1049bebca..c451a23c0c8 100644
--- a/Build/source/texk/web2c/luatexdir/managed-sa.c
+++ b/Build/source/texk/web2c/luatexdir/utils/managed-sa.w
@@ -1,30 +1,33 @@
-/* managed-sa.c
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+% managed-sa.w
+%
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- 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 Lesser 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, see <http://www.gnu.org/licenses/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-#include "luatex-api.h"
-#include <ptexlib.h>
-#include "managed-sa.h"
+@* Sparse arrays with an embedded save stack.
-static const char __svn_version[] =
- "$Id$ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.5/source/texk/web2c/luatexdir/managed-sa.c $";
+@ @c
+#include "ptexlib.h"
-static void store_sa_stack(sa_tree a, integer n, integer v, integer gl)
+static const char _svn_version[] =
+ "$Id: managed-sa.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/utils/managed-sa.w $";
+
+@ @c
+static void store_sa_stack(sa_tree a, int n, sa_tree_item v, int gl)
{
sa_stack_item st;
st.code = n;
@@ -40,7 +43,8 @@ static void store_sa_stack(sa_tree a, integer n, integer v, integer gl)
a->stack[a->stack_ptr] = st;
}
-static void skip_in_stack(sa_tree a, integer n)
+@ @c
+static void skip_in_stack(sa_tree a, int n)
{
int p = a->stack_ptr;
if (a->stack == NULL)
@@ -53,7 +57,8 @@ static void skip_in_stack(sa_tree a, integer n)
}
}
-sa_tree_item get_sa_item(const sa_tree head, const integer n)
+@ @c
+sa_tree_item get_sa_item(const sa_tree head, const int n)
{
register int h;
register int m;
@@ -69,7 +74,8 @@ sa_tree_item get_sa_item(const sa_tree head, const integer n)
return head->dflt;
}
-void set_sa_item(sa_tree head, integer n, sa_tree_item v, integer gl)
+@ @c
+void set_sa_item(sa_tree head, int n, sa_tree_item v, int gl)
{
int h, m, l;
int i;
@@ -78,17 +84,11 @@ void set_sa_item(sa_tree head, integer n, sa_tree_item v, integer gl)
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;
- }
+ (sa_tree_item ***) Mxcalloc_array(sa_tree_item **, HIGHPART);
}
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;
- }
+ (sa_tree_item **) Mxcalloc_array(sa_tree_item *, MIDPART);
}
if (head->tree[h][m] == NULL) {
head->tree[h][m] =
@@ -105,21 +105,21 @@ void set_sa_item(sa_tree head, integer n, sa_tree_item v, integer gl)
head->tree[h][m][l] = v;
}
-void rawset_sa_item(sa_tree head, integer n, integer v)
+@ @c
+void rawset_sa_item(sa_tree head, int n, sa_tree_item v)
{
head->tree[HIGHPART_PART(n)][MIDPART_PART(n)][LOWPART_PART(n)] = v;
}
+@ @c
void clear_sa_stack(sa_tree a)
{
- if (a->stack != NULL) {
- Mxfree(a->stack);
- }
- a->stack = NULL;
+ xfree(a->stack);
a->stack_ptr = 0;
a->stack_size = a->stack_step;
}
+@ @c
void destroy_sa_tree(sa_tree a)
{
int h, m;
@@ -129,25 +129,21 @@ void destroy_sa_tree(sa_tree a)
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]);
- }
+ xfree(a->tree[h][m]);
}
- Mxfree(a->tree[h]);
+ xfree(a->tree[h]);
}
}
- Mxfree(a->tree);
+ xfree(a->tree);
}
- if (a->stack != NULL) {
- Mxfree(a->stack);
- }
- Mxfree(a);
+ xfree(a->stack);
+ xfree(a);
}
-
+@ @c
sa_tree copy_sa_tree(sa_tree b)
{
- int h, m, l;
+ int h, m;
sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1);
a->stack_step = b->stack_step;
a->stack_size = b->stack_size;
@@ -156,43 +152,46 @@ sa_tree copy_sa_tree(sa_tree b)
a->stack_ptr = 0;
a->tree = NULL;
if (b->tree != NULL) {
- a->tree = (sa_tree_item ***) Mxmalloc_array(void *, HIGHPART);
+ a->tree = (sa_tree_item ***) Mxcalloc_array(void *, HIGHPART);
for (h = 0; h < HIGHPART; h++) {
if (b->tree[h] != NULL) {
- a->tree[h] = (sa_tree_item **) Mxmalloc_array(void *, MIDPART);
+ a->tree[h] = (sa_tree_item **) Mxcalloc_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;
+ memcpy(a->tree[h][m], b->tree[h][m],
+ sizeof(sa_tree_item) * LOWPART);
}
}
- } else {
- a->tree[h] = NULL;
}
}
}
return a;
}
+@ The main reason to fill in the lowest entry branches here immediately
+is that most of the sparse arrays have a bias toward ASCII values.
+
+Allocating those here immediately improves the chance of the structure
+|a->tree[0][0][x]| being close together in actual memory locations
-sa_tree new_sa_tree(integer size, sa_tree_item dflt)
+@c
+sa_tree new_sa_tree(int 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->tree = (sa_tree_item ***) Mxcalloc_array(sa_tree_item **, HIGHPART);
+ a->tree[0] = (sa_tree_item **) Mxcalloc_array(sa_tree_item *, MIDPART);
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)
+@ @c
+void restore_sa_stack(sa_tree head, int gl)
{
sa_stack_item st;
if (head->stack == NULL)
@@ -207,14 +206,16 @@ void restore_sa_stack(sa_tree head, integer gl)
}
+@ @c
void dump_sa_tree(sa_tree a)
{
boolean f;
- unsigned int x;
+ int x;
int h, m, l;
assert(a != NULL);
dump_int(a->stack_step);
- dump_int(a->dflt);
+ x = (int) a->dflt;
+ dump_int(x);
if (a->tree != NULL) {
dump_int(1);
for (h = 0; h < HIGHPART; h++) {
@@ -226,7 +227,7 @@ void dump_sa_tree(sa_tree a)
f = 1;
dump_qqqq(f);
for (l = 0; l < LOWPART; l++) {
- x = a->tree[h][m][l];
+ x = (int) a->tree[h][m][l];
dump_int(x);
}
} else {
@@ -244,10 +245,10 @@ void dump_sa_tree(sa_tree a)
}
}
-
+@ @c
sa_tree undump_sa_tree(void)
{
- integer x;
+ int x;
int h, m, l;
boolean f;
sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1);
@@ -255,18 +256,18 @@ sa_tree undump_sa_tree(void)
a->stack_step = x;
a->stack_size = x;
undump_int(x);
- a->dflt = x;
+ a->dflt = (sa_tree_item) 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);
+ a->tree = (sa_tree_item ***) Mxcalloc_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);
+ a->tree[h] = (sa_tree_item **) Mxcalloc_array(void *, MIDPART);
for (m = 0; m < MIDPART; m++) {
undump_qqqq(f);
if (f > 0) {
@@ -275,12 +276,8 @@ sa_tree undump_sa_tree(void)
undump_int(x);
a->tree[h][m][l] = (unsigned int) x;
}
- } else {
- a->tree[h][m] = NULL;
}
}
- } else {
- a->tree[h] = NULL;
}
}
return a;
diff --git a/Build/source/texk/web2c/luatexdir/utils/synctex-common.h b/Build/source/texk/web2c/luatexdir/utils/synctex-common.h
new file mode 100644
index 00000000000..82d1199ece5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/utils/synctex-common.h
@@ -0,0 +1,51 @@
+/* synctex-common.h
+
+This file is part of the SyncTeX package.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE
+
+Acknowledgments:
+----------------
+The author received useful remarks from the pdfTeX developers, especially Hahn The Thanh,
+and significant help from XeTeX developer Jonathan Kew
+
+Nota Bene:
+----------
+If you include or use a significant part of the synctex package into a software,
+I would appreciate to be listed as contributor and see "SyncTeX" highlighted.
+
+Version 1
+Latest Revision: Wed Jul 1 08:07:50 UTC 2009
+
+*/
+
+#ifndef __SYNCTEX_COMMON_HEADER__
+# define __SYNCTEX_COMMON_HEADER__
+
+/* Send this message to init the synctex command value to the command line option.
+ * Sending this message too early will cause a bus error. */
+extern void synctexinitcommand(void);
+
+/* Send this message to clean memory, and close the file. */
+extern void synctexterminate(int log_opened);
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/utils/synctex-luatex.h b/Build/source/texk/web2c/luatexdir/utils/synctex-luatex.h
new file mode 100644
index 00000000000..1ebcaa5738b
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/utils/synctex-luatex.h
@@ -0,0 +1,99 @@
+/* synctex-luatex.h
+
+ Copyright (c) 2010 Taco Hoekwater <taco@luatex.org>
+
+ This file is part of LuaTeX.
+
+License:
+--------
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE
+
+Except as contained in this notice, the name of the copyright holder
+shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in this Software without prior written
+authorization from the copyright holder.
+
+*/
+
+/* $Id: synctex-luatex.h 3536 2010-03-22 13:07:39Z taco $ */
+
+#undef synchronization_field_size
+#define synchronization_field_size 1
+
+#undef width_offset
+#undef height_offset
+#undef depth_offset
+#undef box_node_size
+#undef rule_node
+#undef glue_node
+#undef kern_node
+
+#undef SYNCTEX_TYPE
+#undef SYNCTEX_SUBTYPE
+#undef SYNCTEX_WIDTH
+#undef SYNCTEX_DEPTH
+#undef SYNCTEX_HEIGHT
+#undef SYNCTEX_TAG_MODEL
+#undef SYNCTEX_LINE_MODEL
+#undef SYNCTEX_VALUE
+
+#define SYNCTEX_TAG_MODEL(NODE,SIZE)\
+ vinfo(NODE+SIZE-synchronization_field_size)
+#define SYNCTEX_LINE_MODEL(NODE,SIZE)\
+ vlink(NODE+SIZE-synchronization_field_size)
+
+#define SYNCTEX_TYPE(NODE) type(NODE)
+#define SYNCTEX_SUBTYPE(NODE) subtype(NODE)
+#define SYNCTEX_WIDTH(NODE) width(NODE)
+#define SYNCTEX_DEPTH(NODE) depth(NODE)
+#define SYNCTEX_HEIGHT(NODE) height(NODE)
+#define SYNCTEX_VALUE int_par(synctex_code)
+
+
+#define CURV (dimen_par(page_height_code)-static_pdf->posstruct->pos.v)
+#define CURH static_pdf->posstruct->pos.h
+
+#define GETJOBNAME() makecstring(job_name)
+#define GETLOGNAME() (char *)xstrdup((const char*)texmf_log_name)
+#define gettexstring(a) makecstring(a)
+
+#define rulewd width(p)
+#define ruleht height(p)
+#define ruledp depth(p)
+
+#define curinput cur_input
+#define totalpages total_pages
+#define synctextagfield synctex_tag_field
+#define namefield name_field
+
+#include "ptexlib.h"
+
+/* We observe pdfoutputvalue in order to determine whether output mode is
+ * pdf or dvi.
+ * We will assume that pdf_output_value equals pdf_output before entering
+ * the synctex_sheet function below. */
+#undef SYNCTEX_OFFSET_IS_PDF
+#define SYNCTEX_OFFSET_IS_PDF (pdf_output_value>0)
+#undef SYNCTEX_OUTPUT
+#define SYNCTEX_OUTPUT ((pdf_output_value>0)?"pdf":"dvi")
+
+#define __SyncTeX__ 1
diff --git a/Build/source/texk/web2c/luatexdir/utils/synctex.c b/Build/source/texk/web2c/luatexdir/utils/synctex.c
index de51a4c8ec5..c64c8518365 100644
--- a/Build/source/texk/web2c/luatexdir/utils/synctex.c
+++ b/Build/source/texk/web2c/luatexdir/utils/synctex.c
@@ -1,8 +1,10 @@
/*
-Copyright (c) 2008 jerome DOT laurens AT u-bourgogne DOT fr
+Copyright (c) 2008, 2009 jerome DOT laurens AT u-bourgogne DOT fr
This file is part of the SyncTeX package.
+Latest Revision: Wed Jul 1 11:18:09 UTC 2009
+
License:
--------
Permission is hereby granted, free of charge, to any person
@@ -65,7 +67,7 @@ Versioning:
-----------
As synctex is embedded into different TeX implementation, there is an independent
versionning system.
-For TeX implementations, the actual version is: 1
+For TeX implementations, the actual version is: 2
For .synctex file format, the actual version is SYNCTEX_VERSION below
Please, do not remove these explanations.
@@ -80,39 +82,51 @@ Nota Bene:
If you include or use a significant part of the synctex package into a software,
I would appreciate to be listed as contributor and see "SyncTeX" highlighted.
+History:
+--------
+Version 2
+Fri Sep 19 14:55:31 UTC 2008
+- support for file names containing spaces.
+ This is one thing that xetex and pdftex do not manage the same way.
+ When the input file name contains a space character ' ',
+ pdftex will automatically enclose this name between two quote characters '"',
+ making programs believe that these quotes are really part of the name.
+ xetex does nothing special.
+ For that reason, running the command line
+ xetex --synctex=-1 "my file.tex"
+ is producing the expected file named <my file.synctex>, (the '<' and '>' are not part of the name)
+ whereas running the command line
+ pdftex --synctex=-1 "my file.tex"
+ was producing the unexpected file named <"my file".synctex> where the two '"' chracters were part of the name.
+ Of course, that was breaking the typesetting mechanism when pdftex was involved.
+ To solve this problem, we prefer to rely on the output_file_name instead of the jobname.
+ In the case when no output_file_name is available, we use jobname and test if the file name
+ starts and ends with a quote character. Every synctex output file is removed because we consider
+ TeX encontered a problem.
+ There is some conditional coding.
+
Version 1
-Tue Jul 1 15:23:00 UTC 2008
+Latest Revision: Wed Jul 1 08:15:44 UTC 2009
*/
-# define SYNCTEX_VERSION 1
+#define SYNCTEX_VERSION 1
-# define SYNCTEX_DEBUG 0
+#define SYNCTEX_DEBUG 0
/* Debugging: define the next macro to "return;" in order to disable the synctex code
* only suplemental function calls will be used. The compiler may optimize them. */
-# define SYNCTEX_RETURN_IF_DISABLED ;
+#define SYNCTEX_RETURN_IF_DISABLED ;
-# define SYNCTEX_NOERR 0
+#define SYNCTEX_NOERR 0
-# define EXTERN extern
+#define EXTERN extern
-# ifdef xfree
-# define SYNCTEX_FREE xfree
-# else
-# define SYNCTEX_FREE(x) free(x)
-# endif
-
-#define ruleht rule_ht
-#define ruledp rule_dp
-#define rulewd rule_wd
-#define jobname job_name
-#define totalpages total_pages
-#define curinput cur_input
-#define synctextagfield synctex_tag_field
-#define namefield name_field
-
-#define gettexstring(a) xstrdup(makecstring(a))
+#ifdef xfree
+# define SYNCTEX_FREE xfree
+#else
+# define SYNCTEX_FREE(x) free(x)
+#endif
/* the macros defined below do the same job than their almost eponym
* counterparts of *tex.web, the memory access is sometimes more direct
@@ -122,20 +136,26 @@ Tue Jul 1 15:23:00 UTC 2008
* and *tex.web for details, the synctex_ prefix prevents name conflicts, it
* is some kind of namespace
*/
+
/* synctexoption is a global integer variable defined in *tex.web
* it is set to 1 by texmfmp.c if the command line has the '-synctex=1'
* option. */
-# define synctex_options synctexoption
-# define SYNCTEX_NO_OPTION INT_MAX
+#define synctex_options synctexoption
+#define SYNCTEX_NO_OPTION INT_MAX
/* if synctex_options is set to SYNCTEX_NO_OPTION, no command line option was provided. */
-# define SYNCTEX_VALUE int_par(param_synctex_code)
-
+/* glue code: really define the main memory,
+ * this is exactly the same "mem" as in *tex.web. */
+#define mem zmem
+/* glue code: synctexoffset is a global integer variable defined in *tex.web
+ * it is set to the offset where the primitive \synctex reads and writes its
+ * value. */
+#define SYNCTEX_VALUE zeqtb[synctexoffset].cint
/* if there were a mean to share the value of synctex_code between *tex.web
* and this file, it would be great. */
-# define SYNCTEX_UNIT_FACTOR 1
-# define UNIT / synctex_ctxt.unit
+#define SYNCTEX_UNIT_FACTOR 1
+#define UNIT / synctex_ctxt.unit
/* UNIT is the scale. TeX coordinates are very accurate and client won't need
* that, at leat in a first step. 1.0 <-> 2^16 = 65536.
* The TeX unit is sp (scaled point) or pt/65536 which means that the scale
@@ -148,7 +168,7 @@ Tue Jul 1 15:23:00 UTC 2008
* IMPORTANT: We can say that the natural unit of .synctex files is SYNCTEX_UNIT_FACTOR sp.
* To retrieve the proper bp unit, we'll have to divide by 8.03. To reduce
* rounding errors, we'll certainly have to add 0.5 for non negative integers
- * and ±0.5 for negative integers. This trick is mainly to gain speed and
+ * and ±0.5 for negative integers. This trick is mainly to gain speed and
* size. A binary file would be more appropriate in that respect, but I guess
* that some clients like auctex would not like it very much. we cannot use
* "<<13" instead of "/SYNCTEX_UNIT_FACTOR" because the integers are signed and we do not
@@ -162,7 +182,7 @@ Tue Jul 1 15:23:00 UTC 2008
The 9 definitions below must be in sync with their eponym declarations in
the proper synctex-*.ch* file.
*/
-# define synchronization_field_size 1
+#define synchronization_field_size 2
/* The default value is 2, it is suitable for original TeX and alike,
* but it is too big for XeTeX.
* The tag and the line are just the two last words of the node. This is a
@@ -171,21 +191,35 @@ Tue Jul 1 15:23:00 UTC 2008
* XeTeX redefines synchronization_field_size,
* SYNCTEX_TAG_MODEL and SYNCTEX_LINE_MODEL
* All the default values are targeted to TeX or e-TeX. */
-# define SYNCTEX_TAG_MODEL(NODE,SIZE)\
- vinfo(NODE+SIZE-synchronization_field_size)
-# define SYNCTEX_LINE_MODEL(NODE,SIZE)\
- vlink(NODE+SIZE-synchronization_field_size)
+#define SYNCTEX_TAG_MODEL(NODE,SIZE)\
+ mem[NODE+SIZE-synchronization_field_size].cint
+#define SYNCTEX_LINE_MODEL(NODE,SIZE)\
+ mem[NODE+SIZE-synchronization_field_size+1].cint
/* SYNCTEX_TAG_MODEL and SYNCTEX_LINE_MODEL are used to define
* SYNCTEX_TAG and SYNCTEX_LINE in a model independant way
* Both are tag and line accessors */
+#define box_node_size (7+synchronization_field_size)
+/* see: @d box_node_size=...
+ * There should be an automatic process here because these definitions
+ * are redundant. However, this process would certainly be overcomplicated
+ * (building then parsing the *tex.web file would be a pain) */
+#define width_offset 1
+/* see: @d width_offset=... */
+#define depth_offset 2
+/* see: @d depth_offset=... */
+#define height_offset 3
+/* see: @d height_offset=... */
/* Now define the local version of width(##), height(##) and depth(##) macros
These only depend on the 3 macros above. */
-# define SYNCTEX_TYPE(NODE) type(NODE)
-# define SYNCTEX_SUBTYPE(NODE) subtype(NODE)
-# define SYNCTEX_WIDTH(NODE) width(NODE)
-# define SYNCTEX_DEPTH(NODE) depth(NODE)
-# define SYNCTEX_HEIGHT(NODE) height(NODE)
+#define SYNCTEX_TYPE(NODE) mem[NODE].hh.b0
+#define rule_node 2
+#define glue_node 10
+#define kern_node 11
+#define SYNCTEX_SUBTYPE(NODE) mem[NODE].hh.b1
+#define SYNCTEX_WIDTH(NODE) mem[NODE+width_offset].cint
+#define SYNCTEX_DEPTH(NODE) mem[NODE+depth_offset].cint
+#define SYNCTEX_HEIGHT(NODE) mem[NODE+height_offset].cint
/* When an hlist ships out, it can contain many different kern/glue nodes with
* exactly the same sync tag and line. To reduce the size of the .synctex
@@ -198,128 +232,128 @@ Tue Jul 1 15:23:00 UTC 2008
* a change in the context, this is the macro SYNCTEX_CONTEXT_DID_CHANGE. The
* SYNCTEX_IGNORE macro is used to detect unproperly initialized nodes. See
* details in the implementation of the functions below. */
-# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE
+#define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE
/* Some parts of the code may differ depending on the ouput mode,
* dvi or xdv vs pdf, in particular the management of magnification.
* The default is dvi mode.
* Also, if pdftex is used, the origin of the coordinates is at 0, not at 1in
* Default values are suitable for TeX */
-# define SYNCTEX_OUTPUT "dvi"
-# define SYNCTEX_OFFSET_IS_PDF 0
-
-# define SYNCTEX_YES (-1)
-# define SYNCTEX_NO (0)
-# define SYNCTEX_NO_ERROR (0)
+#define SYNCTEX_OUTPUT "dvi"
+#define SYNCTEX_OFFSET_IS_PDF 0
-# include "luatexd.h"
-# include "nodes.h"
-# include "commands.h"
-# undef SYNCTEX_OFFSET_IS_PDF
-# define SYNCTEX_OFFSET_IS_PDF (pdf_output_value>0)
-# undef SYNCTEX_OUTPUT
-# define SYNCTEX_OUTPUT ((pdf_output_value>0)?"pdf":"dvi")
+#define SYNCTEX_TRUE 1
+#define SYNCTEX_YES (-1)
+#define SYNCTEX_NO (0)
+#define SYNCTEX_NO_ERROR (0)
-#define __SyncTeX__ 1
+#include "synctex-luatex.h"
-# include "synctex.h"
+#include "synctex.h"
-# if defined(__SyncTeX__)
+#if defined(__SyncTeX__)
-# include <stdio.h>
-# include <stdarg.h>
-# include "zlib.h"
+# include <stdio.h>
+# include <stdarg.h>
+# include "zlib.h"
-typedef void (*synctex_recorder_t)(halfword); /* recorders know how to record a node */
-typedef int (*synctex_fprintf_t)(void *, const char * , ...); /* print formatted to either FILE * or gzFile */
+typedef void (*synctex_recorder_t) (halfword); /* recorders know how to record a node */
+typedef int (*synctex_fprintf_t) (void *, const char *, ...); /* print formatted to either FILE * or gzFile */
-# define SYNCTEX_BITS_PER_BYTE 8
+# define SYNCTEX_BITS_PER_BYTE 8
/* Here are all the local variables gathered in one "synchronization context" */
static struct {
void *file; /* the foo.synctex or foo.synctex.gz I/O identifier */
- synctex_fprintf_t fprintf; /* either fprintf or gzprintf */
+ synctex_fprintf_t fprintf; /* either fprintf or gzprintf */
char *busy_name; /* the real "foo.synctex(busy)" or "foo.synctex.gz(busy)" name */
char *root_name; /* in general jobname.tex */
integer count; /* The number of interesting records in "foo.synctex" */
/* next concern the last sync record encountered */
halfword node; /* the last synchronized node, must be set
* before the recorder */
- synctex_recorder_t recorder;/* the recorder of the node above, the
- * routine that knows how to record the
- * node to the .synctex file */
+ synctex_recorder_t recorder; /* the recorder of the node above, the
+ * routine that knows how to record the
+ * node to the .synctex file */
integer tag, line; /* current tag and line */
integer curh, curv; /* current point */
integer magnification; /* The magnification as given by \mag */
integer unit; /* The unit, defaults to 1, use 8192 to produce shorter but less accurate info */
integer total_length; /* The total length of the bytes written since the last check point */
struct _flags {
- unsigned int option_read:1; /* Command line option read (in case of problem or at the end) */
- unsigned int off:1; /* Definitely turn off synctex, corresponds to cli option -synctex=0 */
- unsigned int no_gz:1; /* Whether zlib is used or not */
- unsigned int not_void:1; /* Whether it really contains synchronization material */
- unsigned int warn:1; /* One shot warning flag */
- unsigned int reserved:SYNCTEX_BITS_PER_BYTE*sizeof(int)-5; /* Align */
- } flags;
+ unsigned int option_read:1; /* Command line option read (in case of problem or at the end) */
+ unsigned int off:1; /* Definitely turn off synctex, corresponds to cli option -synctex=0 */
+ unsigned int no_gz:1; /* Whether zlib is used or not */
+ unsigned int not_void:1; /* Whether it really contains synchronization material */
+ unsigned int warn:1; /* One shot warning flag */
+ unsigned int quoted:1; /* Whether the input file name was quoted by tex or not, for example "\"my input file.tex\"", unused by XeTeX */
+ unsigned int reserved:SYNCTEX_BITS_PER_BYTE * sizeof(int) - 6; /* Align */
+ } flags;
} synctex_ctxt = {
-NULL, NULL, NULL, NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0}};
+ NULL, NULL, NULL, NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, {
+0, 0, 0, 0, 0, 0, 0}};
-#define SYNCTEX_FILE synctex_ctxt.file
-#define SYNCTEX_IS_OFF (synctex_ctxt.flags.off)
-#define SYNCTEX_NO_GZ (synctex_ctxt.flags.no_gz)
-#define SYNCTEX_NOT_VOID (synctex_ctxt.flags.not_void)
-#define SYNCTEX_WARNING_DISABLE (synctex_ctxt.flags.warn)
-#define SYNCTEX_fprintf (*synctex_ctxt.fprintf)
+# define SYNCTEX_FILE synctex_ctxt.file
+# define SYNCTEX_IS_OFF (synctex_ctxt.flags.off)
+# define SYNCTEX_NO_GZ (synctex_ctxt.flags.no_gz)
+# define SYNCTEX_NOT_VOID (synctex_ctxt.flags.not_void)
+# define SYNCTEX_WARNING_DISABLE (synctex_ctxt.flags.warn)
+# define SYNCTEX_fprintf (*synctex_ctxt.fprintf)
/* Initialize the options, synchronize the variables.
* This is sent by *tex.web before any TeX macro is used.
* */
-void synctex_init_command(void)
+void synctexinitcommand(void)
{
- /* This is a one shot function, any subsequent call is void */
- if (synctex_ctxt.flags.option_read) {
- return;
- }
+ /* This is a one shot function, any subsequent call is void */
+ if (synctex_ctxt.flags.option_read) {
+ return;
+ }
if (SYNCTEX_NO_OPTION == synctex_options) {
/* No option given from the command line */
SYNCTEX_VALUE = 0;
} else if (synctex_options == 0) {
/* -synctex=0 was given: SyncTeX must be definitely disabled,
- * any subsequent \synctex=1 will have no effect at all */
- SYNCTEX_IS_OFF = SYNCTEX_YES;
+ * any subsequent \synctex=1 will have no effect at all */
+ SYNCTEX_IS_OFF = SYNCTEX_TRUE;
SYNCTEX_VALUE = 0;
} else {
/* the command line options are not ignored */
- if(synctex_options < 0) {
- SYNCTEX_NO_GZ = SYNCTEX_YES;
- }
- /* Initialize the content of the \synctex primitive */
- SYNCTEX_VALUE = synctex_options;
+ if (synctex_options < 0) {
+ SYNCTEX_NO_GZ = SYNCTEX_TRUE;
+ }
+ /* Initialize the content of the \synctex primitive */
+ SYNCTEX_VALUE = synctex_options;
}
- synctex_ctxt.flags.option_read = SYNCTEX_YES;
- return;
+ synctex_ctxt.flags.option_read = SYNCTEX_TRUE;
+ return;
}
-/* Free all memory used and close the file,
- * It is sent locally when there is a problem with synctex output. */
-static void synctex_abort(void)
+/* Free all memory used, close and remove the file if any,
+ * It is sent locally when there is a problem with synctex output.
+ * It is sent by pdftex when a fatal error occurred in pdftex.web. */
+void synctexabort(boolean log_opened __attribute__ ((unused)))
{
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctex_abort\n");
-#endif
+# endif
if (SYNCTEX_FILE) {
- if (SYNCTEX_NO_GZ) {
- xfclose((FILE *)SYNCTEX_FILE, synctex_ctxt.busy_name);
- } else {
- gzclose((gzFile)SYNCTEX_FILE);
- }
+ if (SYNCTEX_NO_GZ) {
+ xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name);
+ } else {
+ gzclose((gzFile) SYNCTEX_FILE);
+ }
+ SYNCTEX_FILE = NULL;
+ remove(synctex_ctxt.busy_name);
SYNCTEX_FREE(synctex_ctxt.busy_name);
synctex_ctxt.busy_name = NULL;
}
- SYNCTEX_FREE(synctex_ctxt.root_name);
- synctex_ctxt.root_name = NULL;
- SYNCTEX_IS_OFF = SYNCTEX_YES; /* disable synctex */
+ if (NULL != synctex_ctxt.root_name) {
+ SYNCTEX_FREE(synctex_ctxt.root_name);
+ synctex_ctxt.root_name = NULL;
+ }
+ SYNCTEX_IS_OFF = SYNCTEX_TRUE; /* disable synctex */
}
static inline int synctex_record_preamble(void);
@@ -339,90 +373,119 @@ static const char *synctex_suffix_busy = "(busy)";
*/
static void *synctex_dot_open(void)
{
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nwarning: Synchronize DEBUG: synctex_dot_open\n");
printf("\nwarning: SYNCTEX_VALUE=%0X\n", SYNCTEX_VALUE);
printf("\nwarning: synctex_options=%0X\n", synctex_options);
-# endif
+# endif
if (SYNCTEX_IS_OFF || !SYNCTEX_VALUE) {
- return NULL; /* synchronization is disabled: do nothing */
+ return NULL; /* synchronization is disabled: do nothing */
}
if (SYNCTEX_FILE) {
- return SYNCTEX_FILE; /* synchronization is alerady enabled */
+ return SYNCTEX_FILE; /* synchronization is alerady enabled */
}
-#if SYNCTEX_DEBUG
+# if SYNCTEX_DEBUG
printf("\nwarning: Synchronize DEBUG: synctex_dot_open 1\n");
-# endif
- /* this is the first time we are asked to open the file
- this part of code is executed only once:
- either SYNCTEX_FILE is nonnegative or synchronization is
- definitely disabled. */
- {
- char *tmp = gettexstring(jobname);
- /* jobname was set by the \jobname command on the *TeX side */
- char * the_busy_name = xmalloc(strlen(tmp) + strlen(synctex_suffix) + strlen(synctex_suffix_gz) + strlen(synctex_suffix_busy) + 1);
- if(!the_busy_name) {
- SYNCTEX_FREE(tmp);
- synctex_abort();
- return NULL;
- }
- strcpy(the_busy_name, tmp);
- SYNCTEX_FREE(tmp);
- tmp = NULL;
- strcat(the_busy_name, synctex_suffix);
- /* Initialize SYNCTEX_NO_GZ with the content of \synctex to let the user choose the format. */
- SYNCTEX_NO_GZ = SYNCTEX_VALUE<0?SYNCTEX_YES:SYNCTEX_NO;
- if (!SYNCTEX_NO_GZ) {
- strcat(the_busy_name, synctex_suffix_gz);
- }
- strcat(the_busy_name, synctex_suffix_busy);
- if (SYNCTEX_NO_GZ) {
- SYNCTEX_FILE = xfopen(the_busy_name, FOPEN_WBIN_MODE);
- synctex_ctxt.fprintf = (synctex_fprintf_t)(&fprintf);
- } else {
- SYNCTEX_FILE = gzopen(the_busy_name, FOPEN_WBIN_MODE);
- synctex_ctxt.fprintf = (synctex_fprintf_t)(&gzprintf);
- }
-#if SYNCTEX_DEBUG
- printf("\nwarning: Synchronize DEBUG: synctex_dot_open 2\n");
-#endif
- if (SYNCTEX_FILE) {
- if(SYNCTEX_NO_ERROR != synctex_record_preamble()) {
- synctex_abort();
- return NULL;
- }
- /* Initialization of the context */
- synctex_ctxt.magnification = 1000;
- synctex_ctxt.unit = SYNCTEX_UNIT_FACTOR;
- /* synctex_ctxt.busy_name was NULL before, it now owns the_busy_name */
- synctex_ctxt.busy_name = the_busy_name;
- the_busy_name = NULL;
- /* print the preamble, this is an quite an UTF8 file */
- if (NULL != synctex_ctxt.root_name) {
- synctex_record_input(1,synctex_ctxt.root_name);
- SYNCTEX_FREE(synctex_ctxt.root_name);
- synctex_ctxt.root_name = NULL;
- }
- synctex_ctxt.count = 0;
-#if SYNCTEX_DEBUG
- fprintf(stdout,
- "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX AVAILABLE\n");
-#endif
- } else {
- /* no .synctex file available, so disable synchronization */
- SYNCTEX_IS_OFF = SYNCTEX_YES;
- SYNCTEX_VALUE = 0;
- printf("\nSyncTeX warning: no synchronization, problem with %s\n",the_busy_name);
- /* and free the_busy_name */
- SYNCTEX_FREE(the_busy_name);
- the_busy_name = NULL;
-#if SYNCTEX_DEBUG
- fprintf(stdout,
- "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX DISABLED\n");
-#endif
- }
- }
+# endif
+ /* this is the first time we are asked to open the file
+ this part of code is executed only once:
+ either SYNCTEX_FILE is nonnegative or synchronization is
+ definitely disabled. */
+ {
+ size_t len;
+ char *tmp = GETJOBNAME();
+ /* jobname was set by the \jobname command on the *TeX side */
+ char *the_busy_name = xmalloc((unsigned)
+ (strlen(tmp) + strlen(synctex_suffix) +
+ strlen(synctex_suffix_gz) +
+ strlen(synctex_suffix_busy) + 1));
+ if (!the_busy_name) {
+ SYNCTEX_FREE(tmp);
+ synctexabort(0);
+ return NULL;
+ }
+# if defined(XeTeX)
+ synctex_ctxt.flags.quoted = 0;
+ strcpy(the_busy_name, tmp);
+# else
+ len = strlen(tmp);
+ if (len > 0 && tmp[0] == '"' && tmp[len - 1] == '"') {
+ /* We are certainly on a pdftex like engine and the input file name did contain spaces inside.
+ Quotes where added around that file name. We prefer to remove the quotes to have a human readable name.
+ As of Fri Sep 19 14:00:01 UTC 2008, the file names containing quotes are not supported by pdfTeX
+ nor SyncTeX. */
+ synctex_ctxt.flags.quoted = 1; /* we will have to add quotes around the file name in the log file. */
+ strcpy(the_busy_name, tmp + 1); /* only copy what follows the leading " character */
+ len = strlen(the_busy_name);
+ if ((len > 0) && (the_busy_name[len - 1] == '"')) {
+ the_busy_name[len - 1] = '\0';
+ }
+ } else {
+ synctex_ctxt.flags.quoted = 0;
+ strcpy(the_busy_name, tmp);
+ }
+# endif
+ SYNCTEX_FREE(tmp);
+ tmp = NULL;
+ strcat(the_busy_name, synctex_suffix);
+ /* Initialize SYNCTEX_NO_GZ with the content of \synctex to let the user choose the format. */
+ if (SYNCTEX_VALUE < 0) {
+ SYNCTEX_NO_GZ = SYNCTEX_TRUE;
+ } else {
+ SYNCTEX_NO_GZ = SYNCTEX_NO;
+ }
+ if (!SYNCTEX_NO_GZ) {
+ strcat(the_busy_name, synctex_suffix_gz);
+ }
+ strcat(the_busy_name, synctex_suffix_busy);
+ if (SYNCTEX_NO_GZ) {
+ SYNCTEX_FILE = xfopen(the_busy_name, FOPEN_WBIN_MODE);
+ synctex_ctxt.fprintf = (synctex_fprintf_t) (&fprintf);
+ } else {
+ SYNCTEX_FILE = gzopen(the_busy_name, FOPEN_WBIN_MODE);
+ synctex_ctxt.fprintf = (synctex_fprintf_t) (&gzprintf);
+ }
+# if SYNCTEX_DEBUG
+ printf("\nwarning: Synchronize DEBUG: synctex_dot_open 2\n");
+# endif
+ if (SYNCTEX_FILE) {
+ if (SYNCTEX_NO_ERROR != synctex_record_preamble()) {
+ synctexabort(0);
+ return NULL;
+ }
+ /* Initialization of the context */
+ synctex_ctxt.magnification = 1000;
+ synctex_ctxt.unit = SYNCTEX_UNIT_FACTOR;
+ /* synctex_ctxt.busy_name was NULL before, it now owns the_busy_name */
+ synctex_ctxt.busy_name = the_busy_name;
+ the_busy_name = NULL;
+ /* print the preamble, this is an quite an UTF8 file */
+ if (NULL != synctex_ctxt.root_name) {
+ synctex_record_input(1, synctex_ctxt.root_name);
+ SYNCTEX_FREE(synctex_ctxt.root_name);
+ synctex_ctxt.root_name = NULL;
+ }
+ synctex_ctxt.count = 0;
+# if SYNCTEX_DEBUG
+ fprintf(stdout,
+ "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX AVAILABLE\n");
+# endif
+ } else {
+ /* no .synctex file available, so disable synchronization */
+ SYNCTEX_IS_OFF = SYNCTEX_TRUE;
+ SYNCTEX_VALUE = 0;
+ printf("\nSyncTeX warning: no synchronization, problem with %s\n",
+ the_busy_name);
+ /* and free the_busy_name */
+ SYNCTEX_FREE(the_busy_name);
+ the_busy_name = NULL;
+# if SYNCTEX_DEBUG
+ fprintf(stdout,
+ "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX DISABLED\n");
+# endif
+ }
+ }
return SYNCTEX_FILE;
}
@@ -444,17 +507,17 @@ static void *synctex_dot_open(void)
* treats the same way .tex, .aux, .sty ... files, even if many of them do not
* contain any material meant to be typeset.
*/
-void synctex_start_input(void)
+void synctexstartinput(void)
{
static unsigned int synctex_tag_counter = 0;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nwarning: Synchronize DEBUG: synctexstartinput %i",
- synctex_tag_counter);
+ synctex_tag_counter);
printf("\nwarning: SYNCTEX_VALUE=%i", SYNCTEX_VALUE);
printf("\nwarning: synctex_options=%0X", synctex_options);
-#endif
+# endif
if (SYNCTEX_IS_OFF) {
return;
@@ -472,35 +535,36 @@ void synctex_start_input(void)
curinput.synctextagfield = 0;
return;
}
- curinput.synctextagfield = synctex_tag_counter; /* -> *TeX.web */
+ curinput.synctextagfield = (int) synctex_tag_counter; /* -> *TeX.web */
if (synctex_tag_counter == 1) {
/* this is the first file TeX ever opens, in general \jobname.tex we
* do not know yet if synchronization will ever be enabled so we have
* to store the file name, because we will need it later.
- * This is necessary because \jobname can be different */
+ * This is necessary because \jobname can be different */
synctex_ctxt.root_name = gettexstring(curinput.namefield);
- /* we could initialize the unit field to 1 to avoid floating point exception
- * when accidentaly dividing by the unit.
- * This occurs when some SYNCTEX_IGNORE macro is not used.
- * But this must not happen unexpectedly, so we leave the unit to 0 */
-#if SYNCTEX_DEBUG
+ /* we could initialize the unit field to 1 to avoid floating point exception
+ * when accidentaly dividing by the unit.
+ * This occurs when some SYNCTEX_IGNORE macro is not used.
+ * But this must not happen unexpectedly, so we leave the unit to 0 */
+# if SYNCTEX_DEBUG
printf("\nwarning: Synchronize DEBUG: synctexstartinput first END\n");
-# endif
+# endif
return;
}
- if (SYNCTEX_FILE || (SYNCTEX_VALUE && (SYNCTEX_NO_ERROR != synctex_dot_open()))) {
+ if (SYNCTEX_FILE
+ || (SYNCTEX_VALUE && (SYNCTEX_NO_ERROR != synctex_dot_open()))) {
char *tmp = gettexstring(curinput.namefield);
- synctex_record_input(curinput.synctextagfield,tmp);
+ synctex_record_input(curinput.synctextagfield, tmp);
SYNCTEX_FREE(tmp);
}
-#if SYNCTEX_DEBUG
+# if SYNCTEX_DEBUG
printf("\nwarning: Synchronize DEBUG: synctexstartinput END\n");
-# endif
+# endif
return;
}
/* All the synctex... functions below have the smallest set of parameters. It
- * appears to be either the address of a node, or nothing at all. Using varmem,
+ * appears to be either the address of a node, or nothing at all. Using zmem,
* which is the place where all the nodes are stored, one can retrieve every
* information about a node. The other information is obtained through the
* global context variable.
@@ -520,71 +584,135 @@ static inline int synctex_record_postamble(void);
* However, it does not mean that it will be in sync with the pdf, especially
* when the output is dvi or xdv and the dvi (or xdv) to pdf driver has not been applied.
*/
-void synctex_terminate(boolean log_opened)
+void synctexterminate(boolean log_opened)
{
- char *tmp = NULL;
- char * the_real_syncname = NULL;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ char *tmp = NULL;
+ char *the_real_syncname = NULL;
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexterminate\n");
-#endif
- tmp = gettexstring(jobname);
- the_real_syncname = xmalloc(strlen(tmp) + strlen(synctex_suffix) + strlen(synctex_suffix_gz) + 1);
- if(!the_real_syncname) {
- SYNCTEX_FREE(tmp);
- synctex_abort();
- return;
- }
- strcpy(the_real_syncname, tmp);
- strcat(the_real_syncname, synctex_suffix);
- if (!SYNCTEX_NO_GZ) {
- /* Remove any uncompressed synctex file, from a previous build. */
- remove(the_real_syncname);
- strcat(the_real_syncname, synctex_suffix_gz);
- }
- /* allways remove the synctex output file before renaming it, windows requires it. */
- if(0 != remove(the_real_syncname) && errno == EACCES) {
- fprintf(stderr,"SyncTeX: Can't remove %s (file is open or read only)\n",the_real_syncname);
- }
- if (SYNCTEX_FILE) {
- if (SYNCTEX_NOT_VOID) {
- synctex_record_postamble();
- /* close the synctex file*/
- if (SYNCTEX_NO_GZ) {
- xfclose((FILE *)SYNCTEX_FILE, synctex_ctxt.busy_name);
- } else {
- gzclose((gzFile)SYNCTEX_FILE);
- }
- /* renaming the working synctex file */
- if(0 == rename(synctex_ctxt.busy_name,the_real_syncname)) {
- if(log_opened) {
- printf("\nSyncTeX written on %s",the_real_syncname); /* SyncTeX also refers to the contents */
- }
- } else {
- fprintf(stderr,"SyncTeX: Can't rename %s to %s\n",synctex_ctxt.busy_name,the_real_syncname);
- remove(synctex_ctxt.busy_name);
- }
- } else {
- /* close and remove the synctex file because there are no pages of output */
- if (SYNCTEX_NO_GZ) {
- xfclose((FILE *)SYNCTEX_FILE, synctex_ctxt.busy_name);
- } else {
- gzclose((gzFile)SYNCTEX_FILE);
- }
- remove(synctex_ctxt.busy_name);
- }
- SYNCTEX_FILE = NULL;
- }
- if (SYNCTEX_NO_GZ) {
- /* Remove any compressed synctex file, from a previous build. */
- strcat(the_real_syncname, synctex_suffix_gz);
- remove(the_real_syncname);
- }
- SYNCTEX_FREE(synctex_ctxt.busy_name);
- synctex_ctxt.busy_name = NULL;
- SYNCTEX_FREE(the_real_syncname);
- SYNCTEX_FREE(tmp);
- synctex_abort();
+# endif
+ if (log_opened && (tmp = GETLOGNAME())) {
+ /* In version 1, the jobname was used but it caused problems regarding spaces in file names. */
+ the_real_syncname = xmalloc((unsigned)
+ (strlen(tmp) + strlen(synctex_suffix) +
+ strlen(synctex_suffix_gz) + 1));
+ if (!the_real_syncname) {
+ SYNCTEX_FREE(tmp);
+ synctexabort(0);
+ return;
+ }
+ strcpy(the_real_syncname, tmp);
+ SYNCTEX_FREE(tmp);
+ tmp = NULL;
+ /* now remove the last path extension which is in general log */
+ tmp = the_real_syncname + strlen(the_real_syncname);
+ while (tmp > the_real_syncname) {
+ --tmp;
+ if (*tmp == '.') {
+ *tmp = '\0'; /* end the string here */
+ break;
+ }
+ }
+ strcat(the_real_syncname, synctex_suffix);
+ if (!SYNCTEX_NO_GZ) {
+ /* Remove any uncompressed synctex file, from a previous build. */
+ remove(the_real_syncname);
+ strcat(the_real_syncname, synctex_suffix_gz);
+ }
+ /* allways remove the synctex output file before renaming it, windows requires it. */
+ if (0 != remove(the_real_syncname) && errno == EACCES) {
+ fprintf(stderr,
+ "SyncTeX: Can't remove %s (file is open or read only)\n",
+ the_real_syncname);
+ }
+ if (SYNCTEX_FILE) {
+ if (SYNCTEX_NOT_VOID) {
+ synctex_record_postamble();
+ /* close the synctex file */
+ if (SYNCTEX_NO_GZ) {
+ xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name);
+ } else {
+ gzclose((gzFile) SYNCTEX_FILE);
+ }
+ SYNCTEX_FILE = NULL;
+ /* renaming the working synctex file */
+ if (0 == rename(synctex_ctxt.busy_name, the_real_syncname)) {
+ if (log_opened) {
+ printf((synctex_ctxt.flags.quoted ? "\nSyncTeX written on \"%s\"" : "\nSyncTeX written on %s"), the_real_syncname); /* SyncTeX also refers to the contents */
+ }
+ } else {
+ fprintf(stderr, "SyncTeX: Can't rename %s to %s\n",
+ synctex_ctxt.busy_name, the_real_syncname);
+ remove(synctex_ctxt.busy_name);
+ }
+ } else {
+ /* close and remove the synctex file because there are no pages of output */
+ if (SYNCTEX_NO_GZ) {
+ xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name);
+ } else {
+ gzclose((gzFile) SYNCTEX_FILE);
+ }
+ SYNCTEX_FILE = NULL;
+ remove(synctex_ctxt.busy_name);
+ }
+ }
+ if (SYNCTEX_NO_GZ) {
+ /* Remove any compressed synctex file, from a previous build. */
+ strcat(the_real_syncname, synctex_suffix_gz);
+ remove(the_real_syncname);
+ }
+ } else if ((tmp = GETJOBNAME())) {
+ size_t len;
+ /* There was a problem with the output.
+ We just try to remove existing synctex output files
+ including the busy one. */
+ the_real_syncname = xmalloc((unsigned)
+ (strlen(tmp) + strlen(synctex_suffix) +
+ strlen(synctex_suffix_gz) + 1));
+ if (!the_real_syncname) {
+ SYNCTEX_FREE(tmp);
+ synctexabort(0);
+ return;
+ }
+# if defined(XeTeX)
+ strcpy(the_real_syncname, tmp);
+# else
+ len = strlen(tmp);
+ if (len > 0 && tmp[0] == '"' && tmp[len - 1] == '"') {
+ /* See above a similar situation. */
+ strcpy(the_real_syncname, tmp + 1); /* only copy what follows the leading " character */
+ len = strlen(the_real_syncname);
+ if ((len > 0) && (the_real_syncname[len - 1] == '"')) {
+ the_real_syncname[len - 1] = '\0';
+ }
+ } else {
+ strcpy(the_real_syncname, tmp);
+ }
+# endif
+ SYNCTEX_FREE(tmp);
+ tmp = NULL;
+ strcat(the_real_syncname, synctex_suffix);
+ remove(the_real_syncname);
+ strcat(the_real_syncname, synctex_suffix_gz);
+ remove(the_real_syncname);
+ if (SYNCTEX_FILE) {
+ /* close the synctex file */
+ if (SYNCTEX_NO_GZ) {
+ xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name);
+ } else {
+ gzclose((gzFile) SYNCTEX_FILE);
+ }
+ SYNCTEX_FILE = NULL;
+ /* removing the working synctex file */
+ remove(synctex_ctxt.busy_name);
+ }
+ }
+ SYNCTEX_FREE(synctex_ctxt.busy_name);
+ synctex_ctxt.busy_name = NULL;
+ SYNCTEX_FREE(the_real_syncname);
+ the_real_syncname = NULL;
+ synctexabort(0);
}
static inline int synctex_record_content(void);
@@ -594,41 +722,43 @@ static inline int synctex_record_sheet(integer sheet);
/* Recording the "{..." line. In *tex.web, use synctex_sheet(pdf_output) at
* the very beginning of the ship_out procedure.
*/
-void synctex_sheet(integer mag)
+void synctexsheet(integer mag)
{
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
- printf("\nSynchronize DEBUG: synctexsheet %i\n",mag);
-#endif
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
+ printf("\nSynchronize DEBUG: synctexsheet %i\n", mag);
+# endif
if (SYNCTEX_IS_OFF) {
- if(SYNCTEX_VALUE && !SYNCTEX_WARNING_DISABLE) {
- SYNCTEX_WARNING_DISABLE = SYNCTEX_YES;
- printf("\nSyncTeX warning: Synchronization was disabled from\nthe command line with -synctex=0\nChanging the value of \\synctex has no effect.");
- }
+ if (SYNCTEX_VALUE && !SYNCTEX_WARNING_DISABLE) {
+ SYNCTEX_WARNING_DISABLE = SYNCTEX_TRUE;
+ printf
+ ("\nSyncTeX warning: Synchronization was disabled from\nthe command line with -synctex=0\nChanging the value of \\synctex has no effect.");
+ }
return;
}
- if (SYNCTEX_FILE || (SYNCTEX_VALUE && (SYNCTEX_NO_ERROR != synctex_dot_open()))) {
+ if (SYNCTEX_FILE
+ || (SYNCTEX_VALUE && (SYNCTEX_NO_ERROR != synctex_dot_open()))) {
/* First possibility: the .synctex file is already open because SyncTeX was activated on the CLI
- * or it was activated with the \synctex macro and the first page is already shipped out.
- * Second possibility: tries to open the .synctex, useful if synchronization was enabled
+ * or it was activated with the \synctex macro and the first page is already shipped out.
+ * Second possibility: tries to open the .synctex, useful if synchronization was enabled
* from the source file and not from the CLI.
* totalpages is defined in tex.web */
if (totalpages == 0) {
/* Now it is time to properly set up the scale factor. */
- if(mag>0) {
+ if (mag > 0) {
synctex_ctxt.magnification = mag;
}
- if(SYNCTEX_NO_ERROR != synctex_record_settings()
- || SYNCTEX_NO_ERROR != synctex_record_content()) {
- synctex_abort();
- return;
- }
+ if (SYNCTEX_NO_ERROR != synctex_record_settings()
+ || SYNCTEX_NO_ERROR != synctex_record_content()) {
+ synctexabort(0);
+ return;
+ }
}
- synctex_record_sheet(totalpages+1);
+ synctex_record_sheet(totalpages + 1);
}
-#if SYNCTEX_DEBUG
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexsheet END\n");
-#endif
+# endif
return;
}
@@ -637,19 +767,19 @@ static inline int synctex_record_teehs(integer sheet);
/* Recording the "}..." line. In *tex.web, use synctex_teehs at
* the very end of the ship_out procedure.
*/
-void synctex_teehs(void)
+void synctexteehs(void)
{
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexteehs\n");
-#endif
- if (SYNCTEX_IS_OFF || !SYNCTEX_FILE ) {
+# endif
+ if (SYNCTEX_IS_OFF || !SYNCTEX_FILE) {
return;
}
- synctex_record_teehs(totalpages);/* not totalpages+1*/
-#if SYNCTEX_DEBUG
+ synctex_record_teehs(totalpages); /* not totalpages+1 */
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexteehs END\n");
-#endif
+# endif
return;
}
@@ -659,23 +789,21 @@ static inline void synctex_record_vlist(halfword p);
* the beginning of the vliSYNCTEX_out procedure in *TeX.web. It will be balanced
* by a synctex_tsilv, sent at the end of the vliSYNCTEX_out procedure. p is the
* address of the vlist We assume that p is really a vlist node! */
-void synctex_vlist(halfword this_box)
+void synctexvlist(halfword this_box)
{
- scaledpos pos;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexhlist\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(this_box)) {
return;
}
- synctex_ctxt.node = this_box; /* 0 to reset */
- synctex_ctxt.recorder = NULL; /* reset */
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size);
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
+ synctex_ctxt.node = this_box; /* 0 to reset */
+ synctex_ctxt.recorder = NULL; /* reset */
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size);
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
synctex_record_vlist(this_box);
}
@@ -685,23 +813,21 @@ static inline void synctex_record_tsilv(halfword p);
* has been shipped out. It is used to close the vlist nesting level. It is
* sent at the end of the vliSYNCTEX_out procedure in *TeX.web to balance a former
* synctex_vlist sent at the beginning of that procedure. */
-void synctex_tsilv(halfword this_box)
+void synctextsilv(halfword this_box)
{
- scaledpos pos;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctextsilv\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(this_box)) {
return;
}
/* Ignoring any pending info to be recorded */
- synctex_ctxt.node = this_box; /* 0 to reset */
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size);
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
+ synctex_ctxt.node = this_box; /* 0 to reset */
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size);
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
synctex_ctxt.recorder = NULL;
synctex_record_tsilv(this_box);
}
@@ -710,24 +836,21 @@ static inline void synctex_record_void_vlist(halfword p);
/* This message is sent when a void vlist will be shipped out.
* There is no need to balance a void vlist. */
-void synctex_void_vlist(halfword p, halfword this_box)
+void synctexvoidvlist(halfword p, halfword this_box __attribute__ ((unused)))
{
- scaledpos pos;
- (void)this_box;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexvoidvlist\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(p)) {
return;
}
- synctex_ctxt.node = p; /* reset */
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,box_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,box_node_size);
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
- synctex_ctxt.recorder = NULL; /* reset */
+ synctex_ctxt.node = p; /* reset */
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, box_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, box_node_size);
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
+ synctex_ctxt.recorder = NULL; /* reset */
synctex_record_void_vlist(p);
}
@@ -737,23 +860,21 @@ static inline void synctex_record_hlist(halfword p);
* the beginning of the hliSYNCTEX_out procedure in *TeX.web. It will be balanced
* by a synctex_tsilh, sent at the end of the hliSYNCTEX_out procedure. p is the
* address of the hlist We assume that p is really an hlist node! */
-void synctex_hlist(halfword this_box)
+void synctexhlist(halfword this_box)
{
- scaledpos pos;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexhlist\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(this_box)) {
return;
}
- synctex_ctxt.node = this_box; /* 0 to reset */
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size);
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
- synctex_ctxt.recorder = NULL; /* reset */
+ synctex_ctxt.node = this_box; /* 0 to reset */
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size);
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
+ synctex_ctxt.recorder = NULL; /* reset */
synctex_record_hlist(this_box);
}
@@ -763,24 +884,22 @@ static inline void synctex_record_tsilh(halfword p);
* has been shipped out it is used to close the hlist nesting level. It is
* sent at the end of the hliSYNCTEX_out procedure in *TeX.web to balance a former
* synctex_hlist sent at the beginning of that procedure. */
-void synctex_tsilh(halfword this_box)
+void synctextsilh(halfword this_box)
{
- scaledpos pos;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctextsilh\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(this_box)) {
return;
}
/* Ignoring any pending info to be recorded */
- synctex_ctxt.node = this_box; /* 0 to force next node to be recorded! */
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size);
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
- synctex_ctxt.recorder = NULL; /* reset */
+ synctex_ctxt.node = this_box; /* 0 to force next node to be recorded! */
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size);
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
+ synctex_ctxt.recorder = NULL; /* reset */
synctex_record_tsilh(this_box);
}
@@ -788,42 +907,39 @@ static inline void synctex_record_void_hlist(halfword p);
/* This message is sent when a void hlist will be shipped out.
* There is no need to balance a void hlist. */
-void synctex_void_hlist(halfword p, halfword this_box)
+void synctexvoidhlist(halfword p, halfword this_box __attribute__ ((unused)))
{
- scaledpos pos;
- (void)this_box;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexvoidhlist\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(p)) {
return;
}
- /* the sync context has changed */
- if (synctex_ctxt.recorder != NULL) {
- /* but was not yet recorded */
- (*synctex_ctxt.recorder) (synctex_ctxt.node);
- }
- synctex_ctxt.node = p; /* 0 to reset */
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,box_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,box_node_size);
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
- synctex_ctxt.recorder = NULL; /* reset */
+ /* the sync context has changed */
+ if (synctex_ctxt.recorder != NULL) {
+ /* but was not yet recorded */
+ (*synctex_ctxt.recorder) (synctex_ctxt.node);
+ }
+ synctex_ctxt.node = p; /* 0 to reset */
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, box_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, box_node_size);
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
+ synctex_ctxt.recorder = NULL; /* reset */
synctex_record_void_hlist(p);
}
/* glue code: these only work with nodes of size medium_node_size */
-# define small_node_size 3
+# define small_node_size 3
/* see: @d small_node_size=2 {number of words to allocate for most node types} */
-# define medium_node_size (small_node_size+synchronization_field_size)
+# define medium_node_size (small_node_size+synchronization_field_size)
/* see: @d rule_node_size=4 */
-# /* define rule_node_size (4+synchronization_field_size)*/
+/* # define rule_node_size (4+synchronization_field_size) */
/* IN THE SEQUEL, ALL NODE ARE medium_node_size'd, UNTIL THE CONTRARY IS MENTIONNED */
-# undef SYNCTEX_IGNORE
-# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE \
+# undef SYNCTEX_IGNORE
+# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE \
|| (0 >= SYNCTEX_TAG_MODEL(NODE,medium_node_size)) \
|| (0 >= SYNCTEX_LINE_MODEL(NODE,medium_node_size))
@@ -831,7 +947,7 @@ void synctex_void_hlist(halfword p, halfword this_box)
* the synchronization context remains the same, there is no need to write
* synchronization info: it would not help more. The synchronization context
* has changed when either the line number or the file tag has changed. */
-# define SYNCTEX_CONTEXT_DID_CHANGE(NODE) ((0 == synctex_ctxt.node)\
+# define SYNCTEX_CONTEXT_DID_CHANGE(NODE) ((0 == synctex_ctxt.node)\
|| (SYNCTEX_TAG_MODEL(NODE,medium_node_size) != synctex_ctxt.tag)\
|| (SYNCTEX_LINE_MODEL(NODE,medium_node_size) != synctex_ctxt.line))
@@ -839,14 +955,12 @@ void synctex_math_recorder(halfword p);
/* glue code this message is sent whenever an inline math node will ship out
See: @ @<Output the non-|char_node| |p| for... */
-void synctex_math(halfword p, halfword this_box)
+void synctexmath(halfword p, halfword this_box __attribute__ ((unused)))
{
- scaledpos pos;
- (void)this_box;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexmath\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(p)) {
return;
}
@@ -855,13 +969,12 @@ void synctex_math(halfword p, halfword this_box)
(*synctex_ctxt.recorder) (synctex_ctxt.node);
}
synctex_ctxt.node = p;
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size);
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
- synctex_ctxt.recorder = NULL;/* no need to record once more */
- synctex_math_recorder(p);/* always record synchronously */
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size);
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
+ synctex_ctxt.recorder = NULL; /* no need to record once more */
+ synctex_math_recorder(p); /* always record synchronously */
}
static inline void synctex_record_glue(halfword p);
@@ -870,63 +983,60 @@ static inline void synctex_record_rule(halfword p);
/* this message is sent whenever an horizontal glue node or rule node ships out
See: move_past:... */
-# define SYNCTEX_IGNORE_RULE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE \
+# define SYNCTEX_IGNORE_RULE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE \
|| (0 >= SYNCTEX_TAG_MODEL(NODE,rule_node_size)) \
|| (0 >= SYNCTEX_LINE_MODEL(NODE,rule_node_size))
-void synctex_horizontal_rule_or_glue(halfword p, halfword this_box)
+void synctexhorizontalruleorglue(halfword p, halfword this_box
+ __attribute__ ((unused)))
{
- scaledpos pos;
- (void)this_box;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexglue\n");
-#endif
- if (SYNCTEX_TYPE(p) == rule_node) { /* not medium_node_size so we can't use SYNCTEX_IGNORE */
- if (SYNCTEX_IGNORE_RULE(p)) {
- return;
- }
- }
- else {
- if (SYNCTEX_IGNORE(p)) {
- return;
- }
- }
- synctex_ctxt.node = p;
- pos = synch_p_with_c(cur);
- synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287);
- synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v;
- synctex_ctxt.recorder = NULL;
- switch(SYNCTEX_TYPE(p)) {
- case rule_node:
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,rule_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,rule_node_size);
- synctex_record_rule(p);/* always record synchronously: maybe some text is outside the box */
- break;
- case glue_node:
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size);
- synctex_record_glue(p);/* always record synchronously: maybe some text is outside the box */
- break;
- case kern_node:
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size);
- synctex_record_kern(p);/* always record synchronously: maybe some text is outside the box */
- break;
- default:
- printf("\nSynchronize ERROR: unknown node type %i\n",SYNCTEX_TYPE(p));
- }
+# endif
+ if (SYNCTEX_TYPE(p) == rule_node) { /* not medium_node_size so we can't use SYNCTEX_IGNORE */
+ if (SYNCTEX_IGNORE_RULE(p)) {
+ return;
+ }
+ } else {
+ if (SYNCTEX_IGNORE(p)) {
+ return;
+ }
+ }
+ synctex_ctxt.node = p;
+ synctex_ctxt.curh = CURH;
+ synctex_ctxt.curv = CURV;
+ synctex_ctxt.recorder = NULL;
+ switch (SYNCTEX_TYPE(p)) {
+ case rule_node:
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, rule_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, rule_node_size);
+ synctex_record_rule(p); /* always record synchronously: maybe some text is outside the box */
+ break;
+ case glue_node:
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size);
+ synctex_record_glue(p); /* always record synchronously: maybe some text is outside the box */
+ break;
+ case kern_node:
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size);
+ synctex_record_kern(p); /* always record synchronously: maybe some text is outside the box */
+ break;
+ default:
+ printf("\nSynchronize ERROR: unknown node type %i\n", SYNCTEX_TYPE(p));
+ }
}
void synctex_kern_recorder(halfword p);
/* this message is sent whenever a kern node ships out
See: @ @<Output the non-|char_node| |p| for... */
-void synctex_kern(halfword p, halfword this_box)
+void synctexkern(halfword p, halfword this_box)
{
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexkern\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(p)) {
return;
}
@@ -935,47 +1045,46 @@ void synctex_kern(halfword p, halfword this_box)
if (synctex_ctxt.recorder != NULL) {
/* but was not yet recorded */
(*synctex_ctxt.recorder) (synctex_ctxt.node);
- }
- if(synctex_ctxt.node == this_box) {
+ }
+ if (synctex_ctxt.node == this_box) {
/* first node in the list */
synctex_ctxt.node = p;
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size);
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size);
synctex_ctxt.recorder = &synctex_kern_recorder;
} else {
synctex_ctxt.node = p;
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size);
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size);
synctex_ctxt.recorder = NULL;
/* always record when the context has just changed
* and when not the first node */
synctex_kern_recorder(p);
}
} else {
- /* just update the geometry and type (for future improvements) */
+ /* just update the geometry and type (for future improvements) */
synctex_ctxt.node = p;
- synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size);
- synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size);
+ synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size);
+ synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size);
synctex_ctxt.recorder = &synctex_kern_recorder;
}
}
/* This last part is used as a tool to infer TeX behaviour,
* but not for direct synchronization. */
-# undef SYNCTEX_IGNORE
-# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE \
+# undef SYNCTEX_IGNORE
+# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE \
|| (synctex_ctxt.count>2000)
void synctex_char_recorder(halfword p);
/* this message is sent whenever a char node ships out */
-void synctex_char(halfword p, halfword this_box)
+void synctexchar(halfword p, halfword this_box __attribute__ ((unused)))
{
- (void)this_box;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexchar\n");
-#endif
+# endif
if (SYNCTEX_IGNORE(p)) {
return;
}
@@ -993,19 +1102,18 @@ void synctex_char(halfword p, halfword this_box)
void synctex_node_recorder(halfword p);
-# undef SYNCTEX_IGNORE
-# define SYNCTEX_IGNORE(NODE) (SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE)
+# undef SYNCTEX_IGNORE
+# define SYNCTEX_IGNORE(NODE) (SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE)
/* this message should be sent to record information
for a node of an unknown type */
-void synctex_node(halfword p, halfword this_box)
+void synctexnode(halfword p, halfword this_box __attribute__ ((unused)))
{
- (void)this_box;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexnode\n");
-#endif
- if (SYNCTEX_IGNORE(p)) {
+# endif
+ if (SYNCTEX_IGNORE(p)) {
return;
}
/* always record, not very usefull yet */
@@ -1014,468 +1122,461 @@ void synctex_node(halfword p, halfword this_box)
/* this message should be sent to record information
synchronously for the current location */
-void synctex_current(void)
+void synctexcurrent(void)
{
- scaledpos pos;
- SYNCTEX_RETURN_IF_DISABLED;
-#if SYNCTEX_DEBUG
+ SYNCTEX_RETURN_IF_DISABLED;
+# if SYNCTEX_DEBUG
printf("\nSynchronize DEBUG: synctexcurrent\n");
-#endif
- if (SYNCTEX_IGNORE(nothing)) {
+# endif
+ if (SYNCTEX_IGNORE(nothing)) {
return;
} else {
- size_t len;
- pos = synch_p_with_c(cur);
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"x%i,%i:%i,%i\n",
- synctex_ctxt.tag,synctex_ctxt.line,
- pos.h UNIT,pos.v UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
- return;
- }
- }
- synctex_abort();
- return;
+ integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "x%i,%i:%i,%i\n",
+ synctex_ctxt.tag, synctex_ctxt.line,
+ CURH UNIT, CURV UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ return;
+ }
+ }
+ synctexabort(0);
+ return;
}
/* Recording the settings */
static inline int synctex_record_settings(void)
{
-#if SYNCTEX_DEBUG > 999
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_settings\n");
-#endif
- if(NULL == SYNCTEX_FILE) {
+# endif
+ if (NULL == SYNCTEX_FILE) {
return SYNCTEX_NOERR;
}
- if(SYNCTEX_FILE) {
- size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"Output:%s\nMagnification:%i\nUnit:%i\nX Offset:%i\nY Offset:%i\n",
- SYNCTEX_OUTPUT,synctex_ctxt.magnification,synctex_ctxt.unit,
- ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287 UNIT),
- ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287 UNIT));
- if(len>0) {
- synctex_ctxt.total_length += len;
- return SYNCTEX_NOERR;
- }
- }
- synctex_abort();
- return -1;
+ if (SYNCTEX_FILE) {
+ integer len = SYNCTEX_fprintf(SYNCTEX_FILE,
+ "Output:%s\nMagnification:%i\nUnit:%i\nX Offset:%i\nY Offset:%i\n",
+ SYNCTEX_OUTPUT,
+ synctex_ctxt.magnification,
+ synctex_ctxt.unit,
+ ((SYNCTEX_OFFSET_IS_PDF !=
+ 0) ? 0 : 4736287 UNIT),
+ ((SYNCTEX_OFFSET_IS_PDF !=
+ 0) ? 0 : 4736287 UNIT));
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ return SYNCTEX_NOERR;
+ }
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "SyncTeX..." line */
static inline int synctex_record_preamble(void)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_preamble\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"SyncTeX Version:%i\n",SYNCTEX_VERSION);
- if(len>0) {
- synctex_ctxt.total_length = len;
- return SYNCTEX_NOERR;
- }
- synctex_abort();
- return -1;
+# endif
+ len =
+ SYNCTEX_fprintf(SYNCTEX_FILE, "SyncTeX Version:%i\n", SYNCTEX_VERSION);
+ if (len > 0) {
+ synctex_ctxt.total_length = len;
+ return SYNCTEX_NOERR;
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "Input:..." line */
static inline int synctex_record_input(integer tag, char *name)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_input\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"Input:%i:%s\n",tag,name);
- if(len>0) {
- synctex_ctxt.total_length += len;
- return SYNCTEX_NOERR;
- }
- synctex_abort();
- return -1;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "Input:%i:%s\n", tag, name);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ return SYNCTEX_NOERR;
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "!..." line */
static inline int synctex_record_anchor(void)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_anchor\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"!%i\n",synctex_ctxt.total_length);
- if(len>0) {
- synctex_ctxt.total_length = len;
- ++synctex_ctxt.count;
- return SYNCTEX_NOERR;
- }
- synctex_abort();
- return -1;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "!%i\n", synctex_ctxt.total_length);
+ if (len > 0) {
+ synctex_ctxt.total_length = len;
+ ++synctex_ctxt.count;
+ return SYNCTEX_NOERR;
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "Content" line */
static inline int synctex_record_content(void)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_content\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"Content:\n");
- if(len>0) {
- synctex_ctxt.total_length += len;
- return SYNCTEX_NOERR;
- }
- synctex_abort();
- return -1;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "Content:\n");
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ return SYNCTEX_NOERR;
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "{..." line */
static inline int synctex_record_sheet(integer sheet)
{
-#if SYNCTEX_DEBUG > 999
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_sheet\n");
-#endif
- if(SYNCTEX_NOERR == synctex_record_anchor()) {
- size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"{%i\n",sheet);
- if(len>0) {
- synctex_ctxt.total_length += len;
- ++synctex_ctxt.count;
- return SYNCTEX_NOERR;
- }
- }
- synctex_abort();
- return -1;
+# endif
+ if (SYNCTEX_NOERR == synctex_record_anchor()) {
+ integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "{%i\n", sheet);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ ++synctex_ctxt.count;
+ return SYNCTEX_NOERR;
+ }
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "}..." line */
static inline int synctex_record_teehs(integer sheet)
{
-#if SYNCTEX_DEBUG > 999
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_teehs\n");
-#endif
- if(SYNCTEX_NOERR == synctex_record_anchor()) {
- size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"}%i\n",sheet);
- if(len>0) {
- synctex_ctxt.total_length += len;
- ++synctex_ctxt.count;
- return SYNCTEX_NOERR;
- }
- }
- synctex_abort();
- return -1;
+# endif
+ if (SYNCTEX_NOERR == synctex_record_anchor()) {
+ integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "}%i\n", sheet);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ ++synctex_ctxt.count;
+ return SYNCTEX_NOERR;
+ }
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "v..." line */
static inline void synctex_record_void_vlist(halfword p)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_void_vlist\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"v%i,%i:%i,%i:%i,%i,%i\n",
- SYNCTEX_TAG_MODEL(p,box_node_size),
- SYNCTEX_LINE_MODEL(p,box_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- SYNCTEX_WIDTH(p) UNIT,
- SYNCTEX_HEIGHT(p) UNIT,
- SYNCTEX_DEPTH(p) UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "v%i,%i:%i,%i:%i,%i,%i\n",
+ SYNCTEX_TAG_MODEL(p, box_node_size),
+ SYNCTEX_LINE_MODEL(p, box_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ SYNCTEX_WIDTH(p) UNIT,
+ SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "[..." line */
static inline void synctex_record_vlist(halfword p)
{
- size_t len = 0;
- SYNCTEX_NOT_VOID = SYNCTEX_YES;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+ SYNCTEX_NOT_VOID = SYNCTEX_TRUE;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_vlist\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"[%i,%i:%i,%i:%i,%i,%i\n",
- SYNCTEX_TAG_MODEL(p,box_node_size),
- SYNCTEX_LINE_MODEL(p,box_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- SYNCTEX_WIDTH(p) UNIT,
- SYNCTEX_HEIGHT(p) UNIT,
- SYNCTEX_DEPTH(p) UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "[%i,%i:%i,%i:%i,%i,%i\n",
+ SYNCTEX_TAG_MODEL(p, box_node_size),
+ SYNCTEX_LINE_MODEL(p, box_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ SYNCTEX_WIDTH(p) UNIT,
+ SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "]..." line */
-static inline void synctex_record_tsilv(halfword p)
+static inline void synctex_record_tsilv(halfword p __attribute__ ((unused)))
{
- size_t len = 0;
- (void)p;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_tsilv\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"]\n");
- if(len>0) {
- synctex_ctxt.total_length += len;
- return;
- }
- synctex_abort();
- return;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "]\n");
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "h..." line */
static inline void synctex_record_void_hlist(halfword p)
{
- size_t len = 0;
- (void)p;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_void_hlist\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"h%i,%i:%i,%i:%i,%i,%i\n",
- SYNCTEX_TAG_MODEL(p,box_node_size),
- SYNCTEX_LINE_MODEL(p,box_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- SYNCTEX_WIDTH(p) UNIT,
- SYNCTEX_HEIGHT(p) UNIT,
- SYNCTEX_DEPTH(p) UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "h%i,%i:%i,%i:%i,%i,%i\n",
+ SYNCTEX_TAG_MODEL(p, box_node_size),
+ SYNCTEX_LINE_MODEL(p, box_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ SYNCTEX_WIDTH(p) UNIT,
+ SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "(..." line */
static inline void synctex_record_hlist(halfword p)
{
- size_t len = 0;
- SYNCTEX_NOT_VOID = SYNCTEX_YES;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+ SYNCTEX_NOT_VOID = SYNCTEX_TRUE;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_hlist\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"(%i,%i:%i,%i:%i,%i,%i\n",
- SYNCTEX_TAG_MODEL(p,box_node_size),
- SYNCTEX_LINE_MODEL(p,box_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- SYNCTEX_WIDTH(p) UNIT,
- SYNCTEX_HEIGHT(p) UNIT,
- SYNCTEX_DEPTH(p) UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "(%i,%i:%i,%i:%i,%i,%i\n",
+ SYNCTEX_TAG_MODEL(p, box_node_size),
+ SYNCTEX_LINE_MODEL(p, box_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ SYNCTEX_WIDTH(p) UNIT,
+ SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a ")..." line */
-static inline void synctex_record_tsilh(halfword p)
+static inline void synctex_record_tsilh(halfword p __attribute__ ((unused)))
{
- size_t len = 0;
- (void)p;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_tsilh\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,")\n");
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, ")\n");
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "Count..." line */
-static inline int synctex_record_count(void) {
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+static inline int synctex_record_count(void)
+{
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_count\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"Count:%i\n",synctex_ctxt.count);
- if(len>0) {
- synctex_ctxt.total_length += len;
- return SYNCTEX_NOERR;
- }
- synctex_abort();
- return -1;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "Count:%i\n", synctex_ctxt.count);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ return SYNCTEX_NOERR;
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "Postamble" section */
static inline int synctex_record_postamble(void)
{
-#if SYNCTEX_DEBUG > 999
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_postamble\n");
-#endif
- if(SYNCTEX_NOERR == synctex_record_anchor()) {
- size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"Postamble:\n");
- if(len>0) {
- synctex_ctxt.total_length += len;
- if(synctex_record_count() || synctex_record_anchor()) {
- } else {
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"Post scriptum:\n");
- if(len>0) {
- synctex_ctxt.total_length += len;
- return SYNCTEX_NOERR;
- }
- }
- }
- }
- synctex_abort();
- return -1;
+# endif
+ if (SYNCTEX_NOERR == synctex_record_anchor()) {
+ integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "Postamble:\n");
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ if (synctex_record_count() || synctex_record_anchor()) {
+ } else {
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "Post scriptum:\n");
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
+ return SYNCTEX_NOERR;
+ }
+ }
+ }
+ }
+ synctexabort(0);
+ return -1;
}
/* Recording a "g..." line */
static inline void synctex_record_glue(halfword p)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_glue_recorder\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"g%i,%i:%i,%i\n",
- SYNCTEX_TAG_MODEL(p,medium_node_size),
- SYNCTEX_LINE_MODEL(p,medium_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "g%i,%i:%i,%i\n",
+ SYNCTEX_TAG_MODEL(p, medium_node_size),
+ SYNCTEX_LINE_MODEL(p, medium_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "k..." line */
static inline void synctex_record_kern(halfword p)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_kern_recorder\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"k%i,%i:%i,%i:%i\n",
- SYNCTEX_TAG_MODEL(p,medium_node_size),
- SYNCTEX_LINE_MODEL(p,medium_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- SYNCTEX_WIDTH(p) UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "k%i,%i:%i,%i:%i\n",
+ SYNCTEX_TAG_MODEL(p, medium_node_size),
+ SYNCTEX_LINE_MODEL(p, medium_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ SYNCTEX_WIDTH(p) UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "r..." line */
static inline void synctex_record_rule(halfword p)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_record_tsilh\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"r%i,%i:%i,%i:%i,%i,%i\n",
- SYNCTEX_TAG_MODEL(p,rule_node_size),
- SYNCTEX_LINE_MODEL(p,rule_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- rulewd UNIT,
- ruleht UNIT,
- ruledp UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "r%i,%i:%i,%i:%i,%i,%i\n",
+ SYNCTEX_TAG_MODEL(p, rule_node_size),
+ SYNCTEX_LINE_MODEL(p, rule_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ rulewd UNIT, ruleht UNIT, ruledp UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "$..." line */
void synctex_math_recorder(halfword p)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_math_recorder\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"$%i,%i:%i,%i\n",
- SYNCTEX_TAG_MODEL(p,medium_node_size),
- SYNCTEX_LINE_MODEL(p,medium_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "$%i,%i:%i,%i\n",
+ SYNCTEX_TAG_MODEL(p, medium_node_size),
+ SYNCTEX_LINE_MODEL(p, medium_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "k..." line */
void synctex_kern_recorder(halfword p)
{
- size_t len = 0;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_kern_recorder\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"k%i,%i:%i,%i:%i\n",
- SYNCTEX_TAG_MODEL(p,medium_node_size),
- SYNCTEX_LINE_MODEL(p,medium_node_size),
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- SYNCTEX_WIDTH(p) UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "k%i,%i:%i,%i:%i\n",
+ SYNCTEX_TAG_MODEL(p, medium_node_size),
+ SYNCTEX_LINE_MODEL(p, medium_node_size),
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ SYNCTEX_WIDTH(p) UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "c..." line */
-void synctex_char_recorder(halfword p)
+void synctex_char_recorder(halfword p __attribute__ ((unused)))
{
- size_t len = 0;
- (void)p;
-#if SYNCTEX_DEBUG > 999
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
printf("\nSynchronize DEBUG: synctex_char_recorder\n");
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"c%i,%i\n",
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT);
- if(len>0) {
- synctex_ctxt.total_length += len;
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "c%i,%i\n",
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT);
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
/* Recording a "?..." line, type, subtype and position */
void synctex_node_recorder(halfword p)
{
- size_t len = 0;
- (void)p;
-#if SYNCTEX_DEBUG > 999
- printf("\nSynchronize DEBUG: synctex_node_recorder(0x%x)\n",p);
-#endif
- len = SYNCTEX_fprintf(SYNCTEX_FILE,"?%i,%i:%i,%i\n",
- synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
- type(p),subtype(p));
- if(len>0) {
- synctex_ctxt.total_length += len;
+ integer len = 0;
+# if SYNCTEX_DEBUG > 999
+ printf("\nSynchronize DEBUG: synctex_node_recorder(0x%x)\n", p);
+# endif
+ len = SYNCTEX_fprintf(SYNCTEX_FILE, "?%i,%i:%i,%i\n",
+ synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT,
+ type(p), subtype(p));
+ if (len > 0) {
+ synctex_ctxt.total_length += len;
++synctex_ctxt.count;
- return;
- }
- synctex_abort();
- return;
+ return;
+ }
+ synctexabort(0);
+ return;
}
-# else
-# warning "SyncTeX is disabled"
-# endif
+#else
+# warning "SyncTeX is disabled"
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/utils/synctex.h b/Build/source/texk/web2c/luatexdir/utils/synctex.h
index 98b11447f20..70d8b805866 100644
--- a/Build/source/texk/web2c/luatexdir/utils/synctex.h
+++ b/Build/source/texk/web2c/luatexdir/utils/synctex.h
@@ -1,5 +1,7 @@
/* synctex.h
+Copyright (c) 2008, 2009 jerome DOT laurens AT u-bourgogne DOT fr
+
This file is part of the SyncTeX package.
Permission is hereby granted, free of charge, to any person
@@ -34,80 +36,78 @@ If you include or use a significant part of the synctex package into a software,
I would appreciate to be listed as contributor and see "SyncTeX" highlighted.
Version 1
-Thu Jun 19 09:39:21 UTC 2008
+Latest Revision: Wed Jul 1 08:17:50 UTC 2009
*/
-# ifndef __SYNCTEX_HEADER__
-# define __SYNCTEX_HEADER__
+#ifndef __SYNCTEX_HEADER__
+# define __SYNCTEX_HEADER__
-/* Send this message to init the synctex command value to the command line option.
- * Sending this message too early will cause a bus error. */
-extern void synctex_init_command(void);
+# include "synctex-common.h"
-/* Send this message to clean memory, and close the file. */
-extern void synctex_terminate(int log_opened);
+/* Free all memory used, close and remove the file if any. */
+void synctexabort(boolean log_opened);
/* Send this message when starting a new input. */
-extern void synctex_start_input(void);
+extern void synctexstartinput(void);
/* Recording the "{..." line. In *tex.web, use synctex_sheet(pdf_output) at
* the very beginning of the ship_out procedure.
*/
-extern void synctex_sheet(integer mag);
+extern void synctexsheet(integer mag);
/* Recording the "}..." line. In *tex.web, use synctex_teehs at
* the very end of the ship_out procedure.
*/
-extern void synctex_teehs(void);
+extern void synctexteehs(void);
/* This message is sent when a vlist will be shipped out, more precisely at
* the beginning of the vlist_out procedure in *TeX.web. It will be balanced
* by a synctex_tsilv, sent at the end of the vlist_out procedure. p is the
* address of the vlist We assume that p is really a vlist node! */
-extern void synctex_vlist(halfword this_box);
+extern void synctexvlist(halfword this_box);
/* Recording a "}" line ending a vbox: this message is sent whenever a vlist
* has been shipped out. It is used to close the vlist nesting level. It is
* sent at the end of each vlist_out procedure in *TeX.web to balance a former
* synctex_vlist sent at the beginning of that procedure. */
-extern void synctex_tsilv(halfword this_box);
+extern void synctextsilv(halfword this_box);
/* This message is sent when a void vlist will be shipped out.
* There is no need to balance a void vlist. */
-extern void synctex_void_vlist(halfword p, halfword this_box);
+extern void synctexvoidvlist(halfword p, halfword this_box);
/* Send this message when an hlist will be shipped out, more precisely at
* the beginning of the hlist_out procedure in *TeX.web. It must be balanced
* by a synctex_tsilh, sent at the end of the hlist_out procedure. p is the
* address of the hlist. */
-extern void synctex_hlist(halfword this_box);
+extern void synctexhlist(halfword this_box);
/* Send this message at the end of the various hlist_out procedure in *TeX.web
* to balance a former synctex_hlist. */
-extern void synctex_tsilh(halfword this_box);
+extern void synctextsilh(halfword this_box);
/* This message is sent when a void hlist will be shipped out.
* There is no need to balance a void hlist. */
-extern void synctex_void_hlist(halfword p, halfword this_box);
+extern void synctexvoidhlist(halfword p, halfword this_box);
/* Send this message whenever an inline math node will ship out. */
-extern void synctex_math(halfword p, halfword this_box);
+extern void synctexmath(halfword p, halfword this_box);
/* Send this message whenever an horizontal rule or glue node will ship out. */
-extern void synctex_horizontal_rule_or_glue(halfword p, halfword this_box);
+extern void synctexhorizontalruleorglue(halfword p, halfword this_box);
/* Send this message whenever a kern node will ship out. */
-extern void synctex_kern(halfword p, halfword this_box);
+extern void synctexkern(halfword p, halfword this_box);
/* this message is sent whenever a char node ships out */
-extern void synctex_char(halfword p, halfword this_box);
+extern void synctexchar(halfword p, halfword this_box);
/* this message should be sent to record information
for a node of an unknown type */
-extern void synctex_node(halfword p, halfword this_box);
+extern void synctexnode(halfword p, halfword this_box);
/* For debugging purpose only */
-extern void synctex_current(void);
+extern void synctexcurrent(void);
-# endif
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.c b/Build/source/texk/web2c/luatexdir/utils/utils.c
deleted file mode 100644
index b8e715a4a64..00000000000
--- a/Build/source/texk/web2c/luatexdir/utils/utils.c
+++ /dev/null
@@ -1,1809 +0,0 @@
-/* utils.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "openbsd-compat.h"
-
-#include "sys/types.h"
-#ifndef __MINGW32__
-# include "sysexits.h"
-#else
-# define EX_SOFTWARE 70
-#endif
-#include "md5.h"
-#include <kpathsea/c-proto.h>
-#include <kpathsea/c-stat.h>
-#include <kpathsea/c-fopen.h>
-#include <kpathsea/version.h>
-#include <string.h>
-#include <time.h>
-#include <float.h> /* for DBL_EPSILON */
-#include "zlib.h"
-#include "ptexlib.h"
-#include "utils.h"
-
-#include "png.h"
-#ifdef POPPLER_VERSION
-# define xpdfString "poppler"
-# include "poppler-config.h"
-# define xpdfVersion POPPLER_VERSION
-#else
-# define xpdfString "xpdf"
-# include "xpdf/config.h" /* just to get the xpdf version */
-#endif
-
-static const char __svn_version[] =
- "$Id: utils.c 2492 2009-06-14 13:14:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/utils/utils.c $";
-
-#define check_nprintf(size_get, size_want) \
- if ((unsigned)(size_get) >= (unsigned)(size_want)) \
- pdftex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__);
-
-char *cur_file_name = NULL;
-str_number last_tex_string;
-static char print_buf[PRINTF_BUF_SIZE];
-static char *jobname_cstr = NULL;
-static char *job_id_string = NULL;
-
-size_t last_ptr_index; /* for use with alloc_array */
-
-/* define fb_ptr, fb_array & fb_limit */
-typedef char fb_entry;
-define_array(fb);
-
-/* define char_ptr, char_array & char_limit */
-typedef char char_entry;
-define_array(char);
-
-integer fb_offset(void)
-{
- return fb_ptr - fb_array;
-}
-
-void fb_seek(integer offset)
-{
- fb_ptr = fb_array + offset;
-}
-
-void fb_putchar(eight_bits b)
-{
- alloc_array(fb, 1, SMALL_ARRAY_SIZE);
- *fb_ptr++ = b;
-}
-
-void fb_flush(void)
-{
- fb_entry *p;
- integer n;
- for (p = fb_array; p < fb_ptr;) {
- n = pdf_buf_size - pdf_ptr;
- if (fb_ptr - p < n)
- n = fb_ptr - p;
- memcpy(pdf_buf + pdf_ptr, p, (unsigned) n);
- pdf_ptr += n;
- if (pdf_ptr == pdf_buf_size)
- pdf_flush();
- p += n;
- }
- fb_ptr = fb_array;
-}
-
-#define SUBSET_TAG_LENGTH 6
-void make_subset_tag(fd_entry * fd)
-{
- int i, j = 0, a[SUBSET_TAG_LENGTH];
- md5_state_t pms;
- char *glyph;
- glw_entry *glw_glyph;
- struct avl_traverser t;
- md5_byte_t digest[16];
- void **aa;
- static struct avl_table *st_tree = NULL;
- if (st_tree == NULL)
- st_tree = avl_create(comp_string_entry, NULL, &avl_xallocator);
- assert(fd != NULL);
- assert(fd->gl_tree != NULL);
- assert(fd->fontname != NULL);
- assert(fd->subset_tag == NULL);
- fd->subset_tag = xtalloc(SUBSET_TAG_LENGTH + 1, char);
- do {
- md5_init(&pms);
- avl_t_init(&t, fd->gl_tree);
- if (is_cidkeyed(fd->fm)) { /* glw_entry items */
- for (glw_glyph = (glw_entry *) avl_t_first(&t, fd->gl_tree);
- glw_glyph != NULL; glw_glyph = (glw_entry *) avl_t_next(&t)) {
- glyph = malloc(24);
- sprintf(glyph, "%05u%05u ", glw_glyph->id, glw_glyph->wd);
- md5_append(&pms, (md5_byte_t *) glyph, strlen(glyph));
- free(glyph);
- }
- } else {
- for (glyph = (char *) avl_t_first(&t, fd->gl_tree); glyph != NULL;
- glyph = (char *) avl_t_next(&t)) {
- md5_append(&pms, (md5_byte_t *) glyph, strlen(glyph));
- md5_append(&pms, (const md5_byte_t *) " ", 1);
- }
- }
- md5_append(&pms, (md5_byte_t *) fd->fontname, strlen(fd->fontname));
- md5_append(&pms, (md5_byte_t *) & j, sizeof(int)); /* to resolve collision */
- md5_finish(&pms, digest);
- for (a[0] = 0, i = 0; i < 13; i++)
- a[0] += digest[i];
- for (i = 1; i < SUBSET_TAG_LENGTH; i++)
- a[i] = a[i - 1] - digest[i - 1] + digest[(i + 12) % 16];
- for (i = 0; i < SUBSET_TAG_LENGTH; i++)
- fd->subset_tag[i] = a[i] % 26 + 'A';
- fd->subset_tag[SUBSET_TAG_LENGTH] = '\0';
- j++;
- assert(j < 100);
- }
- while ((char *) avl_find(st_tree, fd->subset_tag) != NULL);
- aa = avl_probe(st_tree, fd->subset_tag);
- assert(aa != NULL);
- if (j > 2)
- pdftex_warn
- ("\nmake_subset_tag(): subset-tag collision, resolved in round %d.\n",
- j);
-}
-
-void pdf_puts(const char *s)
-{
- pdfroom(strlen(s) + 1);
- while (*s)
- pdf_buf[pdf_ptr++] = *s++;
-}
-
-__attribute__ ((format(printf, 1, 2)))
-void pdf_printf(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
- pdf_puts(print_buf);
- va_end(args);
-}
-
-str_number maketexstring(const char *s)
-{
- if (s == NULL || *s == 0)
- return get_nullstr();
- return maketexlstring(s, strlen(s));
-}
-
-str_number maketexlstring(const char *s, size_t l)
-{
- if (s == NULL || l == 0)
- return get_nullstr();
- check_pool_overflow(pool_ptr + l);
- while (l-- > 0)
- str_pool[pool_ptr++] = *s++;
- last_tex_string = make_string();
- return last_tex_string;
-}
-
-/* print a C string through TeX */
-void print_string(const char *j)
-{
- while (*j) {
- print_char(*j);
- j++;
- }
-}
-
-/* append a C string to a TeX string */
-void append_string(const char *s)
-{
- if (s == NULL || *s == 0)
- return;
- check_buf(pool_ptr + strlen(s), pool_size);
- while (*s)
- str_pool[pool_ptr++] = *s++;
- return;
-}
-
-__attribute__ ((format(printf, 1, 2)))
-void tex_printf(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
- print_string(print_buf);
- xfflush(stdout);
- va_end(args);
-}
-
-/* Helper for pdftex_fail. */
-static void safe_print(const char *str)
-{
- const char *c;
- for (c = str; *c; ++c)
- print(*c);
-}
-
-void remove_pdffile(void)
-{
- if (!kpathsea_debug && output_file_name && !fixed_pdf_draftmode) {
- xfclose(pdf_file, makecstring(output_file_name));
- remove(makecstring(output_file_name));
- }
-}
-
-/* pdftex_fail may be called when a buffer overflow has happened/is
- happening, therefore may not call mktexstring. However, with the
- current implementation it appears that error messages are misleading,
- possibly because pool overflows are detected too late.
-
- The output format of this fuction must be the same as pdf_error in
- pdftex.web! */
-
-__attribute__ ((noreturn, format(printf, 1, 2)))
-void pdftex_fail(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- print_ln();
- safe_print("!LuaTeX error");
- if (cur_file_name) {
- safe_print(" (file ");
- safe_print(cur_file_name);
- safe_print(")");
- }
- safe_print(": ");
- vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
- safe_print(print_buf);
- va_end(args);
- print_ln();
- remove_pdffile();
- safe_print(" ==> Fatal error occurred, no output PDF file produced!");
- print_ln();
- if (kpathsea_debug) {
- abort();
- } else {
- exit(EX_SOFTWARE);
- }
-}
-
-/* The output format of this fuction must be the same as pdf_warn in
- pdftex.web! */
-
-__attribute__ ((format(printf, 1, 2)))
-void pdftex_warn(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- print_ln();
- tex_printf("LuaTeX warning");
- if (cur_file_name)
- tex_printf(" (file %s)", cur_file_name);
- tex_printf(": ");
- vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
- print_string(print_buf);
- va_end(args);
- print_ln();
-}
-
-void tex_error(const char *msg, const char **hlp)
-{
- str_number aa = 0, bb = 0, cc = 0, dd = 0, ee = 0;
- int k = 0;
- if (hlp != NULL) {
- while (hlp[k] != NULL)
- k++;
- if (k > 0)
- aa = maketexstring(hlp[0]);
- if (k > 1)
- bb = maketexstring(hlp[1]);
- if (k > 2)
- cc = maketexstring(hlp[2]);
- if (k > 3)
- dd = maketexstring(hlp[3]);
- if (k > 4)
- ee = maketexstring(hlp[4]);
- }
- do_print_err(maketexstring(msg));
- flush_str(last_tex_string);
-
-/* *INDENT-OFF* */
- switch (k) {
- case 0: dohelp0(); break;
- case 1: dohelp1(aa); break;
- case 2: dohelp2(aa, bb); break;
- case 3: dohelp3(aa, bb, cc); break;
- case 4: dohelp4(aa, bb, cc, dd); break;
- case 5: dohelp5(aa, bb, cc, dd, ee); break;
- }
-/* *INDENT-ON* */
- error();
-
- if (ee)
- flush_str(ee);
- if (dd)
- flush_str(dd);
- if (cc)
- flush_str(cc);
- if (bb)
- flush_str(bb);
- if (aa)
- flush_str(aa);
-}
-
-void garbage_warning(void)
-{
- pdftex_warn("dangling objects discarded, no output file produced.");
- remove_pdffile();
-}
-
-char *makecstring(integer s)
-{
- size_t l;
- return makeclstring(s, &l);
-}
-
-char *makeclstring(integer s, size_t * len)
-{
- static char *cstrbuf = NULL;
- char *p;
- static int allocsize;
- int allocgrow, i, l;
- if (s >= 2097152) {
- s -= 2097152;
- l = str_start[s + 1] - str_start[s];
- *len = l;
- check_buf(l + 1, MAX_CSTRING_LEN);
- if (cstrbuf == NULL) {
- allocsize = l + 1;
- cstrbuf = xmallocarray(char, allocsize);
- } else if (l + 1 > allocsize) {
- allocgrow = allocsize * 0.2;
- if (l + 1 - allocgrow > allocsize)
- allocsize = l + 1;
- else if (allocsize < MAX_CSTRING_LEN - allocgrow)
- allocsize += allocgrow;
- else
- allocsize = MAX_CSTRING_LEN;
- cstrbuf = xreallocarray(cstrbuf, char, allocsize);
- }
- p = cstrbuf;
- for (i = 0; i < l; i++)
- *p++ = str_pool[i + str_start[s]];
- *p = 0;
- } else {
- if (cstrbuf == NULL) {
- allocsize = 5;
- cstrbuf = xmallocarray(char, allocsize);
- }
- if (s <= 0x7F) {
- cstrbuf[0] = s;
- cstrbuf[1] = 0;
- *len = 1;
- } else if (s <= 0x7FF) {
- cstrbuf[0] = 0xC0 + (s / 0x40);
- cstrbuf[1] = 0x80 + (s % 0x40);
- cstrbuf[2] = 0;
- *len = 2;
- } else if (s <= 0xFFFF) {
- cstrbuf[0] = 0xE0 + (s / 0x1000);
- cstrbuf[1] = 0x80 + ((s % 0x1000) / 0x40);
- cstrbuf[2] = 0x80 + ((s % 0x1000) % 0x40);
- cstrbuf[3] = 0;
- *len = 3;
- } else {
- if (s >= 0x10FF00) {
- cstrbuf[0] = s - 0x10FF00;
- cstrbuf[1] = 0;
- *len = 1;
- } else {
- cstrbuf[0] = 0xF0 + (s / 0x40000);
- cstrbuf[1] = 0x80 + ((s % 0x40000) / 0x1000);
- cstrbuf[2] = 0x80 + (((s % 0x40000) % 0x1000) / 0x40);
- cstrbuf[3] = 0x80 + (((s % 0x40000) % 0x1000) % 0x40);
- cstrbuf[4] = 0;
- *len = 4;
- }
- }
- }
- return cstrbuf;
-}
-
-void set_job_id(int year, int month, int day, int time)
-{
- char *name_string, *format_string, *s;
- size_t slen;
- int i;
-
- if (job_id_string != NULL)
- return;
-
- name_string = xstrdup(makecstring(job_name));
- format_string = xstrdup(makecstring(format_ident));
- slen = SMALL_BUF_SIZE +
- strlen(name_string) +
- strlen(format_string) +
- strlen(ptexbanner) +
- strlen(versionstring) + strlen(kpathsea_version_string);
- s = xtalloc(slen, char);
- /* The Web2c version string starts with a space. */
- i = snprintf(s, slen,
- "%.4d/%.2d/%.2d %.2d:%.2d %s %s %s%s %s",
- year, month, day, time / 60, time % 60,
- name_string, format_string, ptexbanner,
- versionstring, kpathsea_version_string);
- check_nprintf(i, slen);
- job_id_string = xstrdup(s);
- xfree(s);
- xfree(name_string);
- xfree(format_string);
-}
-
-void make_pdftex_banner(void)
-{
- static boolean pdftexbanner_init = false;
- char *s;
- size_t slen;
- int i;
-
- if (pdftexbanner_init)
- return;
-
- slen = SMALL_BUF_SIZE +
- strlen(ptexbanner) +
- strlen(versionstring) + strlen(kpathsea_version_string);
- s = xtalloc(slen, char);
- /* The Web2c version string starts with a space. */
- i = snprintf(s, slen,
- "%s%s %s", ptexbanner, versionstring, kpathsea_version_string);
- check_nprintf(i, slen);
- pdftex_banner = maketexstring(s);
- xfree(s);
- pdftexbanner_init = true;
-}
-
-str_number get_resname_prefix(void)
-{
-/* static char name_str[] = */
-/* "!\"$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\" */
-/* "^_`abcdefghijklmnopqrstuvwxyz|~"; */
- static char name_str[] =
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- char prefix[7]; /* make a tag of 6 chars long */
- unsigned long crc;
- short i;
- size_t base = strlen(name_str);
- crc = crc32(0L, Z_NULL, 0);
- crc = crc32(crc, (Bytef *) job_id_string, strlen(job_id_string));
- for (i = 0; i < 6; i++) {
- prefix[i] = name_str[crc % base];
- crc /= base;
- }
- prefix[6] = 0;
- return maketexstring(prefix);
-}
-
-size_t xfwrite(void *ptr, size_t size, size_t nmemb, FILE * stream)
-{
- if (fwrite(ptr, size, nmemb, stream) != nmemb)
- pdftex_fail("fwrite() failed");
- return nmemb;
-}
-
-int xfflush(FILE * stream)
-{
- if (fflush(stream) != 0)
- pdftex_fail("fflush() failed (%s)", strerror(errno));
- return 0;
-}
-
-int xgetc(FILE * stream)
-{
- int c = getc(stream);
- if (c < 0 && c != EOF)
- pdftex_fail("getc() failed (%s)", strerror(errno));
- return c;
-}
-
-int xputc(int c, FILE * stream)
-{
- int i = putc(c, stream);
- if (i < 0)
- pdftex_fail("putc() failed (%s)", strerror(errno));
- return i;
-}
-
-void write_stream_length(integer length, longinteger offset)
-{
- if (jobname_cstr == NULL)
- jobname_cstr = xstrdup(makecstring(job_name));
- if (fixed_pdf_draftmode == 0) {
- xfseeko(pdf_file, (off_t) offset, SEEK_SET, jobname_cstr);
- fprintf(pdf_file, "%li", (long int) length);
- xfseeko(pdf_file, (off_t) pdfoffset(), SEEK_SET, jobname_cstr);
- }
-}
-
-scaled ext_xn_over_d(scaled x, scaled n, scaled d)
-{
- double r = (((double) x) * ((double) n)) / ((double) d);
- if (r > DBL_EPSILON)
- r += 0.5;
- else
- r -= 0.5;
- if (r >= (double) max_integer || r <= -(double) max_integer)
- pdftex_warn("arithmetic: number too big");
- return (scaled) r;
-}
-
-void libpdffinish(void)
-{
- xfree(fb_array);
- xfree(char_array);
- xfree(job_id_string);
- fm_free();
- t1_free();
- enc_free();
- epdf_free();
- ttf_free();
- sfd_free();
- glyph_unicode_free();
- zip_free();
-}
-
-/* Converts any string given in in in an allowed PDF string which can be
- * handled by printf et.al.: \ is escaped to \\, parenthesis are escaped and
- * control characters are octal encoded.
- * This assumes that the string does not contain any already escaped
- * characters!
- */
-char *convertStringToPDFString(const char *in, int len)
-{
- static char pstrbuf[MAX_PSTRING_LEN];
- char *out = pstrbuf;
- int i, j, k;
- char buf[5];
- j = 0;
- for (i = 0; i < len; i++) {
- check_buf(j + sizeof(buf), MAX_PSTRING_LEN);
- if (((unsigned char) in[i] < '!') || ((unsigned char) in[i] > '~')) {
- /* convert control characters into oct */
- k = snprintf(buf, sizeof(buf),
- "\\%03o", (unsigned int) (unsigned char) in[i]);
- check_nprintf(k, sizeof(buf));
- out[j++] = buf[0];
- out[j++] = buf[1];
- out[j++] = buf[2];
- out[j++] = buf[3];
- } else if ((in[i] == '(') || (in[i] == ')')) {
- /* escape paranthesis */
- out[j++] = '\\';
- out[j++] = in[i];
- } else if (in[i] == '\\') {
- /* escape backslash */
- out[j++] = '\\';
- out[j++] = '\\';
- } else {
- /* copy char :-) */
- out[j++] = in[i];
- }
- }
- out[j] = '\0';
- return pstrbuf;
-}
-
-/* Converts any string given in in in an allowed PDF string which can be
- * handled by printf et.al.: \ is escaped to \\, parenthesis are escaped and
- * control characters are octal encoded.
- * This assumes that the string does not contain any already escaped
- * characters!
- *
- * See escapename for parameter description.
- */
-void escapestring(poolpointer in)
-{
- const poolpointer out = pool_ptr;
- unsigned char ch;
- int i;
- while (in < out) {
- if (pool_ptr + 4 >= pool_size) {
- pool_ptr = pool_size;
- /* error by str_toks that calls str_room(1) */
- return;
- }
-
- ch = (unsigned char) str_pool[in++];
-
- if ((ch < '!') || (ch > '~')) {
- /* convert control characters into oct */
- i = snprintf((char *) &str_pool[pool_ptr], 5,
- "\\%.3o", (unsigned int) ch);
- check_nprintf(i, 5);
- pool_ptr += i;
- continue;
- }
- if ((ch == '(') || (ch == ')') || (ch == '\\')) {
- /* escape parenthesis and backslash */
- str_pool[pool_ptr++] = '\\';
- }
- /* copy char :-) */
- str_pool[pool_ptr++] = ch;
- }
-}
-
-/* Convert any given string in a PDF name using escaping mechanism
- of PDF 1.2. The result does not include the leading slash.
-
- PDF specification 1.6, section 3.2.6 "Name Objects" explains:
- <blockquote>
- Beginning with PDF 1.2, any character except null (character code 0) may
- be included in a name by writing its 2-digit hexadecimal code, preceded
- by the number sign character (#); see implementation notes 3 and 4 in
- Appendix H. This syntax is required to represent any of the delimiter or
- white-space characters or the number sign character itself; it is
- recommended but not required for characters whose codes are outside the
- range 33 (!) to 126 (~).
- </blockquote>
- The following table shows the conversion that are done by this
- function:
- code result reason
- -----------------------------------
- 0 ignored not allowed
- 1..32 escaped must for white-space:
- 9 (tab), 10 (lf), 12 (ff), 13 (cr), 32 (space)
- recommended for the other control characters
- 35 escaped escape char "#"
- 37 escaped delimiter "%"
- 40..41 escaped delimiters "(" and ")"
- 47 escaped delimiter "/"
- 60 escaped delimiter "<"
- 62 escaped delimiter ">"
- 91 escaped delimiter "["
- 93 escaped delimiter "]"
- 123 escaped delimiter "{"
- 125 escaped delimiter "}"
- 127..255 escaped recommended
- else copy regular characters
-
- Parameter "in" is a pointer into the string pool where
- the input string is located. The output string is written
- as temporary string right after the input string.
- Thus at the begin of the procedure the global variable
- "pool_ptr" points to the start of the output string and
- after the end when the procedure returns.
-*/
-void escapename(poolpointer in)
-{
- const poolpointer out = pool_ptr;
- unsigned char ch;
- int i;
-
- while (in < out) {
- if (pool_ptr + 3 >= pool_size) {
- pool_ptr = pool_size;
- /* error by str_toks that calls str_room(1) */
- return;
- }
-
- ch = (unsigned char) str_pool[in++];
-
- if ((ch >= 1 && ch <= 32) || ch >= 127) {
- /* escape */
- i = snprintf((char *) &str_pool[pool_ptr], 4,
- "#%.2X", (unsigned int) ch);
- check_nprintf(i, 4);
- pool_ptr += i;
- continue;
- }
- switch (ch) {
- case 0:
- /* ignore */
- break;
- case 35:
- case 37:
- case 40:
- case 41:
- case 47:
- case 60:
- case 62:
- case 91:
- case 93:
- case 123:
- case 125:
- /* escape */
- i = snprintf((char *) &str_pool[pool_ptr], 4,
- "#%.2X", (unsigned int) ch);
- check_nprintf(i, 4);
- pool_ptr += i;
- break;
- default:
- /* copy */
- str_pool[pool_ptr++] = ch;
- }
- }
-}
-
-/* Convert any given string in a PDF hexadecimal string. The
- result does not include the angle brackets.
-
- This procedure uses uppercase hexadecimal letters.
-
- See escapename for description of parameters.
-*/
-void escapehex(poolpointer in)
-{
- const poolpointer out = pool_ptr;
- unsigned char ch;
- int i;
-
- while (in < out) {
- if (pool_ptr + 2 >= pool_size) {
- pool_ptr = pool_size;
- /* error by str_toks that calls str_room(1) */
- return;
- }
-
- ch = (unsigned char) str_pool[in++];
-
- i = snprintf((char *) &str_pool[pool_ptr], 3, "%.2X",
- (unsigned int) ch);
- check_nprintf(i, 3);
- pool_ptr += 2;
- }
-}
-
-/* Unescape any given hexadecimal string.
-
- Last hex digit can be omitted, it is replaced by zero, see
- PDF specification.
-
- Invalid digits are silently ignored.
-
- See escapename for description of parameters.
-*/
-void unescapehex(poolpointer in)
-{
- const poolpointer out = pool_ptr;
- unsigned char ch;
- boolean first = true;
- unsigned char a = 0; /* to avoid warning about uninitialized use of a */
- while (in < out) {
- if (pool_ptr + 1 >= pool_size) {
- pool_ptr = pool_size;
- /* error by str_toks that calls str_room(1) */
- return;
- }
-
- ch = (unsigned char) str_pool[in++];
-
- if ((ch >= '0') && (ch <= '9')) {
- ch -= '0';
- } else if ((ch >= 'A') && (ch <= 'F')) {
- ch -= 'A' - 10;
- } else if ((ch >= 'a') && (ch <= 'f')) {
- ch -= 'a' - 10;
- } else {
- continue; /* ignore wrong character */
- }
-
- if (first) {
- a = ch << 4;
- first = false;
- continue;
- }
-
- str_pool[pool_ptr++] = a + ch;
- first = true;
- }
- if (!first) { /* last hex digit is omitted */
- str_pool[pool_ptr++] = a;
- }
-}
-
-/* Converts any string given in in in an allowed PDF string which is
- * hexadecimal encoded;
- * sizeof(out) should be at least lin*2+1.
- */
-
-static void convertStringToHexString(const char *in, char *out, int lin)
-{
- int i, j, k;
- char buf[3];
- j = 0;
- for (i = 0; i < lin; i++) {
- k = snprintf(buf, sizeof(buf),
- "%02X", (unsigned int) (unsigned char) in[i]);
- check_nprintf(k, sizeof(buf));
- out[j++] = buf[0];
- out[j++] = buf[1];
- }
- out[j] = '\0';
-}
-
-/* Compute the ID string as per PDF1.4 9.3:
- <blockquote>
- File identifers are defined by the optional ID entry in a PDF file's
- trailer dictionary (see Section 3.4.4, "File Trailer"; see also
- implementation note 105 in Appendix H). The value of this entry is an
- array of two strings. The first string is a permanent identifier based
- on the contents of the file at the time it was originally created, and
- does not change when the file is incrementally updated. The second
- string is a changing identifier based on the file's contents at the
- time it was last updated. When a file is first written, both
- identifiers are set to the same value. If both identifiers match when a
- file reference is resolved, it is very likely that the correct file has
- been found; if only the first identifier matches, then a different
- version of the correct file has been found.
- To help ensure the uniqueness of file identifiers, it is recommend
- that they be computed using a message digest algorithm such as MD5
- (described in Internet RFC 1321, The MD5 Message-Digest Algorithm; see
- the Bibliography), using the following information (see implementation
- note 106 in Appendix H):
- - The current time
- - A string representation of the file's location, usually a pathname
- - The size of the file in bytes
- - The values of all entries in the file's document information
- dictionary (see Section 9.2.1, Document Information Dictionary )
- </blockquote>
- This stipulates only that the two IDs must be identical when the file is
- created and that they should be reasonably unique. Since it's difficult
- to get the file size at this point in the execution of pdfTeX and
- scanning the info dict is also difficult, we start with a simpler
- implementation using just the first two items.
- */
-void print_ID(str_number filename)
-{
- time_t t;
- size_t size;
- char time_str[32];
- md5_state_t state;
- md5_byte_t digest[16];
- char id[64];
- char *file_name;
- char pwd[4096];
- /* start md5 */
- md5_init(&state);
- /* get the time */
- t = time(NULL);
- size = strftime(time_str, sizeof(time_str), "%Y%m%dT%H%M%SZ", gmtime(&t));
- md5_append(&state, (const md5_byte_t *) time_str, size);
- /* get the file name */
- if (getcwd(pwd, sizeof(pwd)) == NULL)
- pdftex_fail("getcwd() failed (%s), (path too long?)", strerror(errno));
- file_name = makecstring(filename);
- md5_append(&state, (const md5_byte_t *) pwd, strlen(pwd));
- md5_append(&state, (const md5_byte_t *) "/", 1);
- md5_append(&state, (const md5_byte_t *) file_name, strlen(file_name));
- /* finish md5 */
- md5_finish(&state, digest);
- /* write the IDs */
- convertStringToHexString((char *) digest, id, 16);
- pdf_printf("/ID [<%s> <%s>]", id, id);
-}
-
-/* Print the /CreationDate entry.
-
- PDF Reference, third edition says about the expected date format:
- <blockquote>
- 3.8.2 Dates
-
- PDF defines a standard date format, which closely follows that of
- the international standard ASN.1 (Abstract Syntax Notation One),
- defined in ISO/IEC 8824 (see the Bibliography). A date is a string
- of the form
-
- (D:YYYYMMDDHHmmSSOHH'mm')
-
- where
-
- YYYY is the year
- MM is the month
- DD is the day (01-31)
- HH is the hour (00-23)
- mm is the minute (00-59)
- SS is the second (00-59)
- O is the relationship of local time to Universal Time (UT),
- denoted by one of the characters +, -, or Z (see below)
- HH followed by ' is the absolute value of the offset from UT
- in hours (00-23)
- mm followed by ' is the absolute value of the offset from UT
- in minutes (00-59)
-
- The apostrophe character (') after HH and mm is part of the syntax.
- All fields after the year are optional. (The prefix D:, although also
- optional, is strongly recommended.) The default values for MM and DD
- are both 01; all other numerical fields default to zero values. A plus
- sign (+) as the value of the O field signifies that local time is
- later than UT, a minus sign (-) that local time is earlier than UT,
- and the letter Z that local time is equal to UT. If no UT information
- is specified, the relationship of the specified time to UT is
- considered to be unknown. Whether or not the time zone is known, the
- rest of the date should be specified in local time.
-
- For example, December 23, 1998, at 7:52 PM, U.S. Pacific Standard
- Time, is represented by the string
-
- D:199812231952-08'00'
- </blockquote>
-
- The main difficulty is get the time zone offset. strftime() does this in ISO
- C99 (e.g. newer glibc) with %z, but we have to work with other systems (e.g.
- Solaris 2.5).
-*/
-
-static time_t start_time = 0;
-#define TIME_STR_SIZE 30
-static char start_time_str[TIME_STR_SIZE]; /* minimum size for time_str is 24: "D:YYYYmmddHHMMSS+HH'MM'" */
-
-static void makepdftime(time_t t, char *time_str)
-{
- struct tm lt, gmt;
- size_t size;
- int i, off, off_hours, off_mins;
-
- /* get the time */
- lt = *localtime(&t);
- size = strftime(time_str, TIME_STR_SIZE, "D:%Y%m%d%H%M%S", &lt);
- /* expected format: "YYYYmmddHHMMSS" */
- if (size == 0) {
- /* unexpected, contents of time_str is undefined */
- time_str[0] = '\0';
- return;
- }
-
- /* correction for seconds: %S can be in range 00..61,
- the PDF reference expects 00..59,
- therefore we map "60" and "61" to "59" */
- if (time_str[14] == '6') {
- time_str[14] = '5';
- time_str[15] = '9';
- time_str[16] = '\0'; /* for safety */
- }
-
- /* get the time zone offset */
- gmt = *gmtime(&t);
-
- /* this calculation method was found in exim's tod.c */
- off = 60 * (lt.tm_hour - gmt.tm_hour) + lt.tm_min - gmt.tm_min;
- if (lt.tm_year != gmt.tm_year) {
- off += (lt.tm_year > gmt.tm_year) ? 1440 : -1440;
- } else if (lt.tm_yday != gmt.tm_yday) {
- off += (lt.tm_yday > gmt.tm_yday) ? 1440 : -1440;
- }
-
- if (off == 0) {
- time_str[size++] = 'Z';
- time_str[size] = 0;
- } else {
- off_hours = off / 60;
- off_mins = abs(off - off_hours * 60);
- i = snprintf(&time_str[size], 9, "%+03d'%02d'", off_hours, off_mins);
- check_nprintf(i, 9);
- }
-}
-
-void init_start_time(void)
-{
- if (start_time == 0) {
- start_time = time((time_t *) NULL);
- makepdftime(start_time, start_time_str);
- }
-}
-
-void print_creation_date(void)
-{
- init_start_time();
- pdf_printf("/CreationDate (%s)\n", start_time_str);
-}
-
-void print_mod_date(void)
-{
- init_start_time();
- pdf_printf("/ModDate (%s)\n", start_time_str);
-}
-
-void getcreationdate(void)
-{
- /* put creation date on top of string pool and update pool_ptr */
- size_t len = strlen(start_time_str);
-
- init_start_time();
-
- if ((unsigned) (pool_ptr + len) >= (unsigned) pool_size) {
- pool_ptr = pool_size;
- /* error by str_toks that calls str_room(1) */
- return;
- }
-
- memcpy(&str_pool[pool_ptr], start_time_str, len);
- pool_ptr += len;
-}
-
-/* makecfilename
- input/ouput same as makecstring:
- input: string number
- output: C string with quotes removed.
- That means, file names that are legal on some operation systems
- cannot any more be used since pdfTeX version 1.30.4.
-*/
-char *makecfilename(str_number s)
-{
- char *name = makecstring(s);
- char *p = name;
- char *q = name;
-
- while (*p) {
- if (*p != '"')
- *q++ = *p;
- p++;
- }
- *q = '\0';
- return name;
-}
-
-/* function strips trailing zeros in string with numbers; */
-/* leading zeros are not stripped (as in real life) */
-char *stripzeros(char *a)
-{
- enum { NONUM, DOTNONUM, INT, DOT, LEADDOT, FRAC } s = NONUM, t = NONUM;
- char *p, *q, *r;
- for (p = q = r = a; *p != '\0';) {
- switch (s) {
- case NONUM:
- if (*p >= '0' && *p <= '9')
- s = INT;
- else if (*p == '.')
- s = LEADDOT;
- break;
- case DOTNONUM:
- if (*p != '.' && (*p < '0' || *p > '9'))
- s = NONUM;
- break;
- case INT:
- if (*p == '.')
- s = DOT;
- else if (*p < '0' || *p > '9')
- s = NONUM;
- break;
- case DOT:
- case LEADDOT:
- if (*p >= '0' && *p <= '9')
- s = FRAC;
- else if (*p == '.')
- s = DOTNONUM;
- else
- s = NONUM;
- break;
- case FRAC:
- if (*p == '.')
- s = DOTNONUM;
- else if (*p < '0' || *p > '9')
- s = NONUM;
- break;
- default:;
- }
- switch (s) {
- case DOT:
- r = q;
- break;
- case LEADDOT:
- r = q + 1;
- break;
- case FRAC:
- if (*p > '0')
- r = q + 1;
- break;
- case NONUM:
- if ((t == FRAC || t == DOT) && r != a) {
- q = r--;
- if (*r == '.') /* was a LEADDOT */
- *r = '0';
- r = a;
- }
- break;
- default:;
- }
- *q++ = *p++;
- t = s;
- }
- *q = '\0';
- return a;
-}
-
-void initversionstring(char **versions)
-{
- (void) asprintf(versions,
- "Compiled with libpng %s; using libpng %s\n"
- "Compiled with zlib %s; using zlib %s\n"
- "Compiled with %s version %s\n",
- PNG_LIBPNG_VER_STRING, png_libpng_ver,
- ZLIB_VERSION, zlib_version, xpdfString, xpdfVersion);
-}
-
-/*************************************************/
-/* Color Stack and Matrix Transformation Support */
-/*************************************************/
-
-/*
- In the following array and especially stack data structures are used.
- They have the following properties:
- - They automatically grow dynamically.
- - The size never decreases.
- - The variable with name ending in "size" contains the number how many
- entries the data structure can hold.
- - The variable with name ending in "used" contains the number of
- actually used entries.
- - Memory of strings in stack entries must be allocated and
- freed if the stack is cleared.
-*/
-
-/* Color Stack */
-
-#define STACK_INCREMENT 8
-#define MAX_COLORSTACKS 32768
-/* The colorstack number is stored in two bytes (info field of the node) */
-/* Condition (newcolorstack): MAX_COLORSTACKS mod STACK_INCREMENT = 0 */
-
-#define COLOR_DEFAULT "0 g 0 G"
-/* literal_modes, see pdftex.web */
-#define SET_ORIGIN 0
-#define DIRECT_PAGE 1
-#define DIRECT_ALWAYS 2
-
-/* remember shipout mode: page/form */
-static boolean page_mode;
-
-typedef struct {
- char **page_stack;
- char **form_stack;
- char *page_current;
- char *form_current;
- char *form_init;
- int page_size;
- int form_size;
- int page_used;
- int form_used;
- int literal_mode;
- boolean page_start;
-} colstack_type;
-
-static colstack_type *colstacks = NULL;
-static int colstacks_size = 0;
-static int colstacks_used = 0;
-
-/* Initialization is done, if the color stacks are used,
- init_colorstacks() is defined as macro to avoid unnecessary
- procedure calls.
-*/
-#define init_colorstacks() if (colstacks_size == 0) colstacks_first_init();
-static void colstacks_first_init(void)
-{
- colstacks_size = STACK_INCREMENT;
- colstacks = xtalloc(colstacks_size, colstack_type);
- colstacks_used = 1;
- colstacks[0].page_stack = NULL;
- colstacks[0].form_stack = NULL;
- colstacks[0].page_size = 0;
- colstacks[0].form_size = 0;
- colstacks[0].page_used = 0;
- colstacks[0].form_used = 0;
- colstacks[0].page_current = xstrdup(COLOR_DEFAULT);
- colstacks[0].form_current = xstrdup(COLOR_DEFAULT);
- colstacks[0].form_init = xstrdup(COLOR_DEFAULT);
- colstacks[0].literal_mode = DIRECT_ALWAYS;
- colstacks[0].page_start = true;
-}
-
-int colorstackused(void)
-{
- init_colorstacks();
- return colstacks_used;
-}
-
-/* newcolorstack()
- A new color stack is setup with the given parameters.
- The stack number is returned or -1 in case of error (no room).
-*/
-int newcolorstack(integer s, integer literal_mode, boolean page_start)
-{
- colstack_type *colstack;
- int colstack_num;
- char *str;
-
- init_colorstacks();
-
- /* make room */
- if (colstacks_used == MAX_COLORSTACKS) {
- return -1;
- }
- if (colstacks_used == colstacks_size) {
- colstacks_size += STACK_INCREMENT;
- /* If (MAX_COLORSTACKS mod STACK_INCREMENT = 0) then we don't
- need to check the case that size overruns MAX_COLORSTACKS. */
- colstacks = xreallocarray(colstacks, colstack_type, colstacks_size);
- }
- /* claim new color stack */
- colstack_num = colstacks_used++;
- colstack = &colstacks[colstack_num];
- /* configure the new color stack */
- colstack->page_stack = NULL;
- colstack->form_stack = NULL;
- colstack->page_size = 0;
- colstack->page_used = 0;
- colstack->form_size = 0;
- colstack->form_used = 0;
- colstack->literal_mode = literal_mode;
- colstack->page_start = page_start;
- str = makecstring(s);
- if (*str == 0) {
- colstack->page_current = NULL;
- colstack->form_current = NULL;
- colstack->form_init = NULL;
- } else {
- colstack->page_current = xstrdup(str);
- colstack->form_current = xstrdup(str);
- colstack->form_init = xstrdup(str);
- }
- return colstack_num;
-}
-
-#define get_colstack(n) (&colstacks[n])
-
-/* Puts a string on top of the string pool and updates pool_ptr. */
-static void put_cstring_on_str_pool(poolpointer start, char *str)
-{
- size_t len;
-
- if (str == NULL || *str == 0) {
- return;
- }
-
- len = strlen(str);
- pool_ptr = start + len;
- if (pool_ptr >= pool_size) {
- pool_ptr = pool_size;
- /* error by str_toks that calls str_room(1) */
- return;
- }
- memcpy(&str_pool[start], str, len);
-}
-
-integer colorstackset(int colstack_no, integer s)
-{
- colstack_type *colstack = get_colstack(colstack_no);
-
- if (page_mode) {
- xfree(colstack->page_current);
- colstack->page_current = xstrdup(makecstring(s));
- } else {
- xfree(colstack->form_current);
- colstack->form_current = xstrdup(makecstring(s));
- }
- return colstack->literal_mode;
-}
-
-integer colorstackcurrent(int colstack_no)
-{
- colstack_type *colstack = get_colstack(colstack_no);
-
- if (page_mode) {
- put_cstring_on_str_pool(pool_ptr, colstack->page_current);
- } else {
- put_cstring_on_str_pool(pool_ptr, colstack->form_current);
- }
- return colstack->literal_mode;
-}
-
-integer colorstackpush(int colstack_no, integer s)
-{
- colstack_type *colstack = get_colstack(colstack_no);
- char *str;
-
- if (page_mode) {
- if (colstack->page_used == colstack->page_size) {
- colstack->page_size += STACK_INCREMENT;
- colstack->page_stack = xretalloc(colstack->page_stack,
- colstack->page_size, char *);
- }
- colstack->page_stack[colstack->page_used++] = colstack->page_current;
- str = makecstring(s);
- if (*str == 0) {
- colstack->page_current = NULL;
- } else {
- colstack->page_current = xstrdup(str);
- }
- } else {
- if (colstack->form_used == colstack->form_size) {
- colstack->form_size += STACK_INCREMENT;
- colstack->form_stack = xretalloc(colstack->form_stack,
- colstack->form_size, char *);
- }
- colstack->form_stack[colstack->form_used++] = colstack->form_current;
- str = makecstring(s);
- if (*str == 0) {
- colstack->form_current = NULL;
- } else {
- colstack->form_current = xstrdup(str);
- }
- }
- return colstack->literal_mode;
-}
-
-integer colorstackpop(int colstack_no)
-{
- colstack_type *colstack = get_colstack(colstack_no);
-
- if (page_mode) {
- if (colstack->page_used == 0) {
- pdftex_warn("pop empty color page stack %u",
- (unsigned int) colstack_no);
- return colstack->literal_mode;
- }
- xfree(colstack->page_current);
- colstack->page_current = colstack->page_stack[--colstack->page_used];
- put_cstring_on_str_pool(pool_ptr, colstack->page_current);
- } else {
- if (colstack->form_used == 0) {
- pdftex_warn("pop empty color form stack %u",
- (unsigned int) colstack_no);
- return colstack->literal_mode;
- }
- xfree(colstack->form_current);
- colstack->form_current = colstack->form_stack[--colstack->form_used];
- put_cstring_on_str_pool(pool_ptr, colstack->form_current);
- }
- return colstack->literal_mode;
-}
-
-static void colorstackpagestart(void)
-{
- int i, j;
- colstack_type *colstack;
-
- if (page_mode) {
- /* see procedure pdf_out_colorstack_startpage */
- return;
- }
-
- for (i = 0; i < colstacks_used; i++) {
- colstack = &colstacks[i];
- for (j = 0; j < colstack->form_used; j++) {
- xfree(colstack->form_stack[j]);
- }
- colstack->form_used = 0;
- xfree(colstack->form_current);
- if (colstack->form_init == NULL) {
- colstack->form_current = NULL;
- } else {
- colstack->form_current = xstrdup(colstack->form_init);
- }
- }
-}
-
-integer colorstackskippagestart(int colstack_no)
-{
- colstack_type *colstack = get_colstack(colstack_no);
-
- if (!colstack->page_start) {
- return 1;
- }
- if (colstack->page_current == NULL) {
- return 0;
- }
- if (strcmp(COLOR_DEFAULT, colstack->page_current) == 0) {
- return 2;
- }
- return 0;
-}
-
-/* stack for \pdfsetmatrix */
-
-typedef struct {
- double a;
- double b;
- double c;
- double d;
- double e;
- double f;
-} matrix_entry;
-static matrix_entry *matrix_stack = 0;
-static int matrix_stack_size = 0;
-static int matrix_stack_used = 0;
-
-boolean matrixused(void)
-{
- return matrix_stack_used > 0;
-}
-
-/* stack for positions of \pdfsave */
-typedef struct {
- scaledpos pos;
- int matrix_stack;
-} pos_entry;
-static pos_entry *pos_stack = 0; /* the stack */
-static int pos_stack_size = 0; /* initially empty */
-static int pos_stack_used = 0; /* used entries */
-
-static void matrix_stack_room(void)
-{
- matrix_entry *new_stack;
-
- if (matrix_stack_used >= matrix_stack_size) {
- matrix_stack_size += STACK_INCREMENT;
- new_stack = xtalloc(matrix_stack_size, matrix_entry);
- memcpy((void *) new_stack, (void *) matrix_stack,
- matrix_stack_used * sizeof(matrix_entry));
- xfree(matrix_stack);
- matrix_stack = new_stack;
- }
-}
-
-void checkpdfsave(scaledpos pos)
-{
- pos_entry *new_stack;
-
- if (pos_stack_used >= pos_stack_size) {
- pos_stack_size += STACK_INCREMENT;
- new_stack = xtalloc(pos_stack_size, pos_entry);
- memcpy((void *) new_stack, (void *) pos_stack,
- pos_stack_used * sizeof(pos_entry));
- xfree(pos_stack);
- pos_stack = new_stack;
- }
- pos_stack[pos_stack_used].pos.h = pos.h;
- pos_stack[pos_stack_used].pos.v = pos.v;
- if (page_mode) {
- pos_stack[pos_stack_used].matrix_stack = matrix_stack_used;
- }
- pos_stack_used++;
-}
-
-void checkpdfrestore(scaledpos pos)
-{
- scaledpos diff;
- if (pos_stack_used == 0) {
- pdftex_warn("%s", "\\pdfrestore: missing \\pdfsave");
- return;
- }
- pos_stack_used--;
- diff.h = pos.h - pos_stack[pos_stack_used].pos.h;
- diff.v = pos.v - pos_stack[pos_stack_used].pos.v;
- if (diff.h != 0 || diff.v != 0) {
- pdftex_warn("Misplaced \\pdfrestore by (%dsp, %dsp)", (int) diff.h,
- (int) diff.v);
- }
- if (page_mode) {
- matrix_stack_used = pos_stack[pos_stack_used].matrix_stack;
- }
-}
-
-void pdfshipoutbegin(boolean shipping_page)
-{
- pos_stack_used = 0; /* start with empty stack */
-
- page_mode = shipping_page;
- if (shipping_page) {
- colorstackpagestart();
- }
-}
-
-void pdfshipoutend(boolean shipping_page)
-{
- if (pos_stack_used > 0) {
- pdftex_fail("%u unmatched \\pdfsave after %s shipout",
- (unsigned int) pos_stack_used,
- ((shipping_page) ? "page" : "form"));
- }
-}
-
-/* \pdfsetmatrix{a b c d}
- e := pos.h
- f := pos.v
- M_top: current active matrix at the top of
- the matrix stack
-
- The origin of \pdfsetmatrix is the current point.
- The annotation coordinate system is the original
- page coordinate system. When pdfTeX calculates
- annotation rectangles it does not take into
- account this transformations, it uses the original
- coordinate system. To get the corrected values,
- first we go back to the origin, perform the
- transformation and go back:
-
- ( 1 0 0 ) ( a b 0 ) ( 1 0 0 )
- ( 0 1 0 ) x ( c d 0 ) x ( 0 1 0 ) x M_top
- ( -e -f 1 ) ( 0 0 1 ) ( e f 1 )
-
- ( 1 0 0 ) ( a b 0 )
- = ( 0 1 0 ) x ( c d 0 ) x M_top
- ( e f 1 ) ( -e -f 1 )
-
- ( a b 0 )
- = ( c d 0 ) x M_top
- ( e(1-a)-fc f(1-d)-eb 1 )
-
-*/
-
-void pdfsetmatrix(poolpointer in, scaledpos pos)
-{
- /* Argument of \pdfsetmatrix starts with str_pool[in] and ends
- before str_pool[pool_ptr]. */
-
- matrix_entry x, *y, *z;
-
- if (page_mode) {
- if (sscanf((const char *) &str_pool[in], " %lf %lf %lf %lf ",
- &x.a, &x.b, &x.c, &x.d) != 4) {
- pdftex_warn("Unrecognized format of \\pdfsetmatrix{%s}",
- &str_pool[pool_ptr]);
- return;
- }
- /* calculate this transformation matrix */
- x.e = (double) pos.h * (1.0 - x.a) - (double) pos.v * x.c;
- x.f = (double) pos.v * (1.0 - x.d) - (double) pos.h * x.b;
- matrix_stack_room();
- z = &matrix_stack[matrix_stack_used];
- if (matrix_stack_used > 0) {
- y = &matrix_stack[matrix_stack_used - 1];
- z->a = x.a * y->a + x.b * y->c;
- z->b = x.a * y->b + x.b * y->d;
- z->c = x.c * y->a + x.d * y->c;
- z->d = x.c * y->b + x.d * y->d;
- z->e = x.e * y->a + x.f * y->c + y->e;
- z->f = x.e * y->b + x.f * y->d + y->f;
- } else {
- z->a = x.a;
- z->b = x.b;
- z->c = x.c;
- z->d = x.d;
- z->e = x.e;
- z->f = x.f;
- }
- matrix_stack_used++;
- }
-}
-
-/* Apply matrix to point (x,y)
-
- ( a b 0 )
- ( x y 1 ) x ( c d 0 ) = ( xa+yc+e xb+yd+f 1 )
- ( e f 1 )
-
- If \pdfsetmatrix wasn't used, then return the value unchanged.
-*/
-
-/* Return valeus for matrix tranform functions */
-static scaled ret_llx;
-static scaled ret_lly;
-static scaled ret_urx;
-static scaled ret_ury;
-
-scaled getllx(void)
-{
- return ret_llx;
-}
-
-scaled getlly(void)
-{
- return ret_lly;
-}
-
-scaled geturx(void)
-{
- return ret_urx;
-}
-
-scaled getury(void)
-{
- return ret_ury;
-}
-
-static int last_llx;
-static int last_lly;
-static int last_urx;
-static int last_ury;
-
-#define DO_ROUND(x) ((x > 0) ? (x + .5) : (x - .5))
-#define DO_MIN(a, b) ((a < b) ? a : b)
-#define DO_MAX(a, b) ((a > b) ? a : b)
-
-static void do_matrixtransform(scaled x, scaled y, scaled * retx, scaled * rety)
-{
- matrix_entry *m = &matrix_stack[matrix_stack_used - 1];
- double x_old = x;
- double y_old = y;
- double x_new = x_old * m->a + y_old * m->c + m->e;
- double y_new = x_old * m->b + y_old * m->d + m->f;
- *retx = (scaled) DO_ROUND(x_new);
- *rety = (scaled) DO_ROUND(y_new);
-}
-
-void matrixtransformrect(scaled llx, scaled lly, scaled urx, scaled ury)
-{
- scaled x1, x2, x3, x4, y1, y2, y3, y4;
-
- if (page_mode && matrix_stack_used > 0) {
- last_llx = llx;
- last_lly = lly;
- last_urx = urx;
- last_ury = ury;
- do_matrixtransform(llx, lly, &x1, &y1);
- do_matrixtransform(llx, ury, &x2, &y2);
- do_matrixtransform(urx, lly, &x3, &y3);
- do_matrixtransform(urx, ury, &x4, &y4);
- ret_llx = DO_MIN(DO_MIN(x1, x2), DO_MIN(x3, x4));
- ret_lly = DO_MIN(DO_MIN(y1, y2), DO_MIN(y3, y4));
- ret_urx = DO_MAX(DO_MAX(x1, x2), DO_MAX(x3, x4));
- ret_ury = DO_MAX(DO_MAX(y1, y2), DO_MAX(y3, y4));
- } else {
- ret_llx = llx;
- ret_lly = lly;
- ret_urx = urx;
- ret_ury = ury;
- }
-}
-
-void matrixtransformpoint(scaled x, scaled y)
-{
- if (page_mode && matrix_stack_used > 0) {
- do_matrixtransform(x, y, &ret_llx, &ret_lly);
- } else {
- ret_llx = x;
- ret_lly = y;
- }
-}
-
-void matrixrecalculate(scaled urx)
-{
- matrixtransformrect(last_llx, last_lly, urx, last_ury);
-}
-
-void check_buffer_overflow(int wsize)
-{
- int nsize;
- if (wsize > buf_size) {
- nsize = buf_size + buf_size / 5 + 5;
- if (nsize < wsize) {
- nsize = wsize + 5;
- }
- buffer = (unsigned char *) xreallocarray(buffer, char, nsize);
- buf_size = nsize;
- }
-}
-
-#define EXTRA_STRING 500
-
-void check_pool_overflow(int wsize)
-{
- int nsize;
- if ((wsize - 1) > pool_size) {
- nsize = pool_size + pool_size / 5 + EXTRA_STRING;
- if (nsize < wsize) {
- nsize = wsize + EXTRA_STRING;
- }
- str_pool = (unsigned char *) xreallocarray(str_pool, char, nsize);
- pool_size = nsize;
- }
-}
-
-#define max_integer 0x7FFFFFFF
-
-/* the return value is a decimal number with the point |dd| places from the back,
- |scaled_out| is the number of scaled points corresponding to that.
-*/
-
-scaled divide_scaled(scaled s, scaled m, integer dd)
-{
- register scaled q;
- register scaled r;
- int i;
- int sign = 1;
- if (s < 0) {
- sign = -sign;
- s = -s;
- }
- if (m < 0) {
- sign = -sign;
- m = -m;
- }
- if (m == 0) {
- pdf_error(maketexstring("arithmetic"),
- maketexstring("divided by zero"));
- } else if (m >= (max_integer / 10)) {
- pdf_error(maketexstring("arithmetic"), maketexstring("number too big"));
- }
- q = s / m;
- r = s % m;
- for (i = 1; i <= (int) dd; i++) {
- q = 10 * q + (10 * r) / m;
- r = (10 * r) % m;
- }
- /* rounding */
- if (2 * r >= m) {
- q++;
- r -= m;
- }
- return sign * q;
-}
-
-/* Same function, but using doubles instead of integers (faster) */
-
-scaled divide_scaled_n(double sd, double md, double n)
-{
- double dd, di = 0.0;
- dd = sd / md * n;
- if (dd > 0.0)
- di = floor(dd + 0.5);
- else if (dd < 0.0)
- di = -floor((-dd) + 0.5);
- return (scaled) di;
-}
-
-
-/* C print interface */
-
-void tprint(const char *s)
-{
- const unsigned char *ss = (const unsigned char*) s;
- while (*ss)
- print_char(*ss++);
-}
-
-void tprint_nl(const char *s)
-{
- print_nlp();
- tprint(s);
-}
-
-#define escape_char_code 45 /* escape character for token output */
-#define int_par(a) zeqtb[static_int_base+(a)].cint /* an integer parameter */
-#define escape_char int_par(escape_char_code)
-
-void tprint_esc(const char *s)
-{ /* prints escape character, then |s| */
- int c = -1; /* the escape character code */
- if (zeqtb != NULL) {
- c = escape_char;
- if (c >= 0)
- print_char(c);
- }
- tprint(s);
-}
-
-void tconfusion(const char *s)
-{
- confusion(maketexstring(s));
-}
-
-#ifdef MSVC
-
-# include <math.h>
-double rint(double x)
-{
- double c, f, d1, d2;
-
- c = ceil(x);
- f = floor(x);
- d1 = fabs(c - x);
- d2 = fabs(x - f);
- if (d1 > d2)
- return f;
- else
- return c;
-}
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.h b/Build/source/texk/web2c/luatexdir/utils/utils.h
index eaa928387f0..82420025eaa 100644
--- a/Build/source/texk/web2c/luatexdir/utils/utils.h
+++ b/Build/source/texk/web2c/luatexdir/utils/utils.h
@@ -18,93 +18,36 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: utils.h 2333 2009-04-18 17:45:46Z hhenkel $ */
+/* $Id: utils.h 3261 2009-12-18 11:38:21Z taco $ */
#ifndef UTILS_H
# define UTILS_H
-# define overflow_string(a,b) { overflow(maketexstring(a),b); flush_str(last_tex_string); }
+extern int epochseconds;
+extern int microseconds;
+extern char *pdftex_banner;
-integer fb_offset(void);
-void fb_flush(void);
-void fb_putchar(eight_bits b);
-void fb_seek(integer);
void make_subset_tag(fd_entry *);
-void pdf_puts(const char *);
-__attribute__ ((format(printf, 1, 2)))
-void pdf_printf(const char *, ...);
-str_number maketexstring(const char *);
-str_number maketexlstring(const char *, size_t);
-void print_string(const char *j);
-void append_string(const char *s);
+
__attribute__ ((format(printf, 1, 2)))
void tex_printf(const char *, ...);
-void remove_pdffile(void);
+
__attribute__ ((noreturn, format(printf, 1, 2)))
void pdftex_fail(const char *, ...);
__attribute__ ((format(printf, 1, 2)))
void pdftex_warn(const char *, ...);
-void tex_error(const char *msg, const char **hlp);
void garbage_warning(void);
-char *makecstring(integer);
-char *makeclstring(integer, size_t *);
-void set_job_id(int, int, int, int);
void make_pdftex_banner(void);
-str_number get_resname_prefix(void);
size_t xfwrite(void *, size_t size, size_t nmemb, FILE *);
int xfflush(FILE *);
int xgetc(FILE *);
int xputc(int, FILE *);
-void write_stream_length(integer, longinteger);
scaled ext_xn_over_d(scaled, scaled, scaled);
-void libpdffinish(void);
-char *convertStringToPDFString(const char *in, int len);
-void escapestring(poolpointer in);
-void escapename(poolpointer in);
-void escapehex(poolpointer in);
-void unescapehex(poolpointer in);
-void print_ID(str_number);
-void init_start_time(void);
-void print_creation_date(void);
-void print_mod_date(void);
-void getcreationdate(void);
-char *makecfilename(str_number s);
char *stripzeros(char *);
void initversionstring(char **versions);
extern void check_buffer_overflow(int wsize);
extern void check_pool_overflow(int wsize);
-extern str_number last_tex_string;
extern char *cur_file_name;
-extern size_t last_ptr_index;
-extern char *fb_array;
-
-/**********************************************************************/
-/* color stack and matrix transformation support */
-
-int newcolorstack(integer s, integer literal_mode, boolean pagestart);
-int colorstackused(void);
-integer colorstackset(int colstack_no, integer s);
-integer colorstackpush(int colstack_no, integer s);
-integer colorstackpop(int colstack_no);
-integer colorstackcurrent(int colstack_no);
-integer colorstackskippagestart(int colstack_no);
-void checkpdfsave(scaledpos pos);
-void checkpdfrestore(scaledpos pos);
-void pdfshipoutbegin(boolean shipping_page);
-void pdfshipoutend(boolean shipping_page);
-void pdfsetmatrix(poolpointer in, scaledpos pos);
-scaled getllx(void);
-scaled getlly(void);
-scaled geturx(void);
-scaled getury(void);
-void tconfusion(const char *s);
-void tprint(const char *s);
-void tprint_nl(const char *s);
-void tprint_esc(const char *s);
-void matrixtransformpoint(scaled x, scaled y);
-void matrixtransformrect(scaled llx, scaled lly, scaled urx, scaled ury);
-boolean matrixused(void);
-void matrixrecalculate(scaled urx);
#endif /* UTILS_H */
diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.w b/Build/source/texk/web2c/luatexdir/utils/utils.w
new file mode 100644
index 00000000000..777f153ddf4
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/utils/utils.w
@@ -0,0 +1,465 @@
+% utils.w
+
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 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.
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: utils.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/utils/utils.w $";
+
+@ @c
+#include "openbsd-compat.h"
+#include <kpathsea/config.h> /* this is a trick to load mingw32's io.h early,
+ using a macro redefinition of |eof()|. */
+#ifdef HAVE_ASPRINTF /* asprintf is not defined in openbsd-compat.h, but in stdio.h */
+# include <stdio.h>
+#endif
+
+#include "sys/types.h"
+#ifndef __MINGW32__
+# include "sysexits.h"
+#else
+# define EX_SOFTWARE 70
+#endif
+#include <kpathsea/c-stat.h>
+#include <kpathsea/c-fopen.h>
+#include <string.h>
+#include <time.h>
+#include <float.h> /* for |DBL_EPSILON| */
+#include "zlib.h"
+#include "ptexlib.h"
+#include "md5.h"
+
+#include "lua/luatex-api.h" /* for ptexbanner */
+
+#include "png.h"
+#ifdef POPPLER_VERSION
+# define xpdfString "poppler"
+# include "poppler-config.h"
+# define xpdfVersion POPPLER_VERSION
+#else
+# define xpdfString "xpdf"
+# include "xpdf/config.h" /* just to get the xpdf version */
+#endif
+
+@ @c
+#define check_nprintf(size_get, size_want) \
+ if ((unsigned)(size_get) >= (unsigned)(size_want)) \
+ pdftex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__);
+
+char *cur_file_name = NULL;
+static char print_buf[PRINTF_BUF_SIZE];
+int epochseconds;
+int microseconds;
+
+/* define |char_ptr|, |char_array|, and |char_limit| */
+typedef char char_entry;
+define_array(char);
+
+@ @c
+#define SUBSET_TAG_LENGTH 6
+void make_subset_tag(fd_entry * fd)
+{
+ int i, j = 0, a[SUBSET_TAG_LENGTH];
+ md5_state_t pms;
+ char *glyph;
+ glw_entry *glw_glyph;
+ struct avl_traverser t;
+ md5_byte_t digest[16];
+ void **aa;
+ static struct avl_table *st_tree = NULL;
+ if (st_tree == NULL)
+ st_tree = avl_create(comp_string_entry, NULL, &avl_xallocator);
+ assert(fd != NULL);
+ assert(fd->gl_tree != NULL);
+ assert(fd->fontname != NULL);
+ assert(fd->subset_tag == NULL);
+ fd->subset_tag = xtalloc(SUBSET_TAG_LENGTH + 1, char);
+ do {
+ md5_init(&pms);
+ avl_t_init(&t, fd->gl_tree);
+ if (is_cidkeyed(fd->fm)) { /* |glw_entry| items */
+ for (glw_glyph = (glw_entry *) avl_t_first(&t, fd->gl_tree);
+ glw_glyph != NULL; glw_glyph = (glw_entry *) avl_t_next(&t)) {
+ glyph = malloc(24);
+ sprintf(glyph, "%05u%05u ", glw_glyph->id, glw_glyph->wd);
+ md5_append(&pms, (md5_byte_t *) glyph, (int) strlen(glyph));
+ free(glyph);
+ }
+ } else {
+ for (glyph = (char *) avl_t_first(&t, fd->gl_tree); glyph != NULL;
+ glyph = (char *) avl_t_next(&t)) {
+ md5_append(&pms, (md5_byte_t *) glyph, (int) strlen(glyph));
+ md5_append(&pms, (const md5_byte_t *) " ", 1);
+ }
+ }
+ md5_append(&pms, (md5_byte_t *) fd->fontname,
+ (int) strlen(fd->fontname));
+ md5_append(&pms, (md5_byte_t *) & j, sizeof(int)); /* to resolve collision */
+ md5_finish(&pms, digest);
+ for (a[0] = 0, i = 0; i < 13; i++)
+ a[0] += digest[i];
+ for (i = 1; i < SUBSET_TAG_LENGTH; i++)
+ a[i] = a[i - 1] - digest[i - 1] + digest[(i + 12) % 16];
+ for (i = 0; i < SUBSET_TAG_LENGTH; i++)
+ fd->subset_tag[i] = (char) (a[i] % 26 + 'A');
+ fd->subset_tag[SUBSET_TAG_LENGTH] = '\0';
+ j++;
+ assert(j < 100);
+ }
+ while ((char *) avl_find(st_tree, fd->subset_tag) != NULL);
+ aa = avl_probe(st_tree, fd->subset_tag);
+ assert(aa != NULL);
+ if (j > 2)
+ pdftex_warn
+ ("\nmake_subset_tag(): subset-tag collision, resolved in round %d.\n",
+ j);
+}
+
+@ @c
+__attribute__ ((format(printf, 1, 2)))
+void tex_printf(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
+ tprint(print_buf);
+ xfflush(stdout);
+ va_end(args);
+}
+
+@ |pdftex_fail| may be called when a buffer overflow has happened/is
+ happening, therefore may not call mktexstring. However, with the
+ current implementation it appears that error messages are misleading,
+ possibly because pool overflows are detected too late.
+
+ The output format of this fuction must be the same as |pdf_error| in
+ pdftex.web!
+
+@c
+__attribute__ ((noreturn, format(printf, 1, 2)))
+void pdftex_fail(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ print_ln();
+ tprint("!LuaTeX error");
+ if (cur_file_name) {
+ tprint(" (file ");
+ tprint(cur_file_name);
+ tprint(")");
+ }
+ tprint(": ");
+ vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
+ tprint(print_buf);
+ va_end(args);
+ print_ln();
+ remove_pdffile(static_pdf);
+ tprint(" ==> Fatal error occurred, no output PDF file produced!");
+ print_ln();
+ if (kpathsea_debug) {
+ abort();
+ } else {
+ exit(EX_SOFTWARE);
+ }
+}
+
+@ The output format of this fuction must be the same as |pdf_warn| in
+ pdftex.web!
+@c
+__attribute__ ((format(printf, 1, 2)))
+void pdftex_warn(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ print_ln();
+ tex_printf("LuaTeX warning");
+ if (cur_file_name)
+ tex_printf(" (file %s)", cur_file_name);
+ tex_printf(": ");
+ vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
+ tprint(print_buf);
+ va_end(args);
+ print_ln();
+}
+
+@ @c
+void garbage_warning(void)
+{
+ pdftex_warn("dangling objects discarded, no output file produced.");
+ remove_pdffile(static_pdf);
+}
+
+@ @c
+char *pdftex_banner = NULL;
+
+@ @c
+void make_pdftex_banner(void)
+{
+ char *s;
+ unsigned int slen;
+ int i;
+
+ if (pdftex_banner != NULL)
+ return;
+
+ slen = (unsigned int) (SMALL_BUF_SIZE +
+ strlen(ptexbanner) +
+ strlen(versionstring) +
+ strlen(kpathsea_version_string));
+ s = xtalloc(slen, char);
+ /* The Web2c version string starts with a space. */
+ i = snprintf(s, slen,
+ "%s%s %s", ptexbanner, versionstring, kpathsea_version_string);
+ check_nprintf(i, slen);
+ pdftex_banner = s;
+}
+
+@ @c
+size_t xfwrite(void *ptr, size_t size, size_t nmemb, FILE * stream)
+{
+ if (fwrite(ptr, size, nmemb, stream) != nmemb)
+ pdftex_fail("fwrite() failed");
+ return nmemb;
+}
+
+@ @c
+int xfflush(FILE * stream)
+{
+ if (fflush(stream) != 0)
+ pdftex_fail("fflush() failed (%s)", strerror(errno));
+ return 0;
+}
+
+@ @c
+int xgetc(FILE * stream)
+{
+ int c = getc(stream);
+ if (c < 0 && c != EOF)
+ pdftex_fail("getc() failed (%s)", strerror(errno));
+ return c;
+}
+
+@ @c
+int xputc(int c, FILE * stream)
+{
+ int i = putc(c, stream);
+ if (i < 0)
+ pdftex_fail("putc() failed (%s)", strerror(errno));
+ return i;
+}
+
+@ @c
+scaled ext_xn_over_d(scaled x, scaled n, scaled d)
+{
+ double r = (((double) x) * ((double) n)) / ((double) d);
+ if (r > DBL_EPSILON)
+ r += 0.5;
+ else
+ r -= 0.5;
+ if (r >= (double) max_integer || r <= -(double) max_integer)
+ pdftex_warn("arithmetic: number too big");
+ return (scaled) r;
+}
+
+@ function strips trailing zeros in string with numbers;
+leading zeros are not stripped (as in real life)
+@c
+char *stripzeros(char *a)
+{
+ enum { NONUM, DOTNONUM, INT, DOT, LEADDOT, FRAC } s = NONUM, t = NONUM;
+ char *p, *q, *r;
+ for (p = q = r = a; *p != '\0';) {
+ switch (s) {
+ case NONUM:
+ if (*p >= '0' && *p <= '9')
+ s = INT;
+ else if (*p == '.')
+ s = LEADDOT;
+ break;
+ case DOTNONUM:
+ if (*p != '.' && (*p < '0' || *p > '9'))
+ s = NONUM;
+ break;
+ case INT:
+ if (*p == '.')
+ s = DOT;
+ else if (*p < '0' || *p > '9')
+ s = NONUM;
+ break;
+ case DOT:
+ case LEADDOT:
+ if (*p >= '0' && *p <= '9')
+ s = FRAC;
+ else if (*p == '.')
+ s = DOTNONUM;
+ else
+ s = NONUM;
+ break;
+ case FRAC:
+ if (*p == '.')
+ s = DOTNONUM;
+ else if (*p < '0' || *p > '9')
+ s = NONUM;
+ break;
+ default:;
+ }
+ switch (s) {
+ case DOT:
+ r = q;
+ break;
+ case LEADDOT:
+ r = q + 1;
+ break;
+ case FRAC:
+ if (*p > '0')
+ r = q + 1;
+ break;
+ case NONUM:
+ if ((t == FRAC || t == DOT) && r != a) {
+ q = r--;
+ if (*r == '.') /* was a LEADDOT */
+ *r = '0';
+ r = a;
+ }
+ break;
+ default:;
+ }
+ *q++ = *p++;
+ t = s;
+ }
+ *q = '\0';
+ return a;
+}
+
+@ @c
+void initversionstring(char **versions)
+{
+ (void) asprintf(versions,
+ "Compiled with libpng %s; using libpng %s\n"
+ "Compiled with zlib %s; using zlib %s\n"
+ "Compiled with %s version %s\n",
+ PNG_LIBPNG_VER_STRING, png_libpng_ver,
+ ZLIB_VERSION, zlib_version, xpdfString, xpdfVersion);
+}
+
+@ @c
+void check_buffer_overflow(int wsize)
+{
+ if (wsize > buf_size) {
+ int nsize = buf_size + buf_size / 5 + 5;
+ if (nsize < wsize) {
+ nsize = wsize + 5;
+ }
+ buffer =
+ (unsigned char *) xreallocarray(buffer, char, (unsigned) nsize);
+ buf_size = nsize;
+ }
+}
+
+@ the return value is a decimal number with the point |dd| places from the back,
+ |scaled_out| is the number of scaled points corresponding to that.
+
+@c
+#define max_integer 0x7FFFFFFF
+
+scaled divide_scaled(scaled s, scaled m, int dd)
+{
+ register scaled q;
+ register scaled r;
+ int i;
+ int sign = 1;
+ if (s < 0) {
+ sign = -sign;
+ s = -s;
+ }
+ if (m < 0) {
+ sign = -sign;
+ m = -m;
+ }
+ if (m == 0) {
+ pdf_error("arithmetic", "divided by zero");
+ } else if (m >= (max_integer / 10)) {
+ pdf_error("arithmetic", "number too big");
+ }
+ q = s / m;
+ r = s % m;
+ for (i = 1; i <= (int) dd; i++) {
+ q = 10 * q + (10 * r) / m;
+ r = (10 * r) % m;
+ }
+ /* rounding */
+ if (2 * r >= m) {
+ q++;
+ r -= m;
+ }
+ return sign * q;
+}
+
+@ Same function, but using doubles instead of integers (faster)
+@c
+scaled divide_scaled_n(double sd, double md, double n)
+{
+ double dd, di = 0.0;
+ dd = sd / md * n;
+ if (dd > 0.0)
+ di = floor(dd + 0.5);
+ else if (dd < 0.0)
+ di = -floor((-dd) + 0.5);
+ return (scaled) di;
+}
+
+@ @c
+int do_zround(double r)
+{
+ int i;
+
+ if (r > 2147483647.0)
+ i = 2147483647;
+ else if (r < -2147483647.0)
+ i = -2147483647;
+ else if (r >= 0.0)
+ i = (int) (r + 0.5);
+ else
+ i = (int) (r - 0.5);
+
+ return i;
+}
+
+
+@ MSVC doesn't have |rind|.
+@c
+#ifdef MSVC
+
+# include <math.h>
+double rint(double x)
+{
+ double c, f, d1, d2;
+
+ c = ceil(x);
+ f = floor(x);
+ d1 = fabs(c - x);
+ d2 = fabs(x - f);
+ if (d1 > d2)
+ return f;
+ else
+ return c;
+}
+
+#endif
diff --git a/Build/source/texk/web2c/luatexdir/utils/writezip.c b/Build/source/texk/web2c/luatexdir/utils/writezip.c
deleted file mode 100644
index 312623093ef..00000000000
--- a/Build/source/texk/web2c/luatexdir/utils/writezip.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* writezip.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 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.
-
- 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 <http://www.gnu.org/licenses/>. */
-
-#include "ptexlib.h"
-#include "zlib.h"
-#include <assert.h>
-
-static const char __svn_version[] =
- "$Id: writezip.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/utils/writezip.c $";
-
-#define ZIP_BUF_SIZE 32768
-
-#define check_err(f, fn) \
- if (f != Z_OK) \
- pdftex_fail("zlib: %s() failed (error code %d)", fn, f)
-
-static char *zipbuf = NULL;
-static z_stream c_stream; /* compression stream */
-
-void write_zip(boolean finish)
-{
- int err;
- static int level_old = 0;
- int level = get_pdf_compress_level();
- assert(level > 0);
- cur_file_name = NULL;
- if (pdf_stream_length == 0) {
- if (zipbuf == NULL) {
- zipbuf = xtalloc(ZIP_BUF_SIZE, char);
- c_stream.zalloc = (alloc_func) 0;
- c_stream.zfree = (free_func) 0;
- c_stream.opaque = (voidpf) 0;
- check_err(deflateInit(&c_stream, level), "deflateInit");
- } else {
- if (level != level_old) { /* \pdfcompresslevel change in mid document */
- check_err(deflateEnd(&c_stream), "deflateEnd");
- c_stream.zalloc = (alloc_func) 0; /* these 3 lines no need, just to be safe */
- c_stream.zfree = (free_func) 0;
- c_stream.opaque = (voidpf) 0;
- check_err(deflateInit(&c_stream, level), "deflateInit");
- } else
- check_err(deflateReset(&c_stream), "deflateReset");
- }
- level_old = level;
- c_stream.next_out = (Bytef *) zipbuf;
- c_stream.avail_out = ZIP_BUF_SIZE;
- }
- assert(zipbuf != NULL);
- c_stream.next_in = pdf_buf;
- c_stream.avail_in = pdf_ptr;
- for (;;) {
- if (c_stream.avail_out == 0) {
- pdf_gone += xfwrite(zipbuf, 1, ZIP_BUF_SIZE, pdf_file);
- pdf_last_byte = zipbuf[ZIP_BUF_SIZE - 1]; /* not needed */
- c_stream.next_out = (Bytef *) zipbuf;
- c_stream.avail_out = ZIP_BUF_SIZE;
- }
- err = deflate(&c_stream, finish ? Z_FINISH : Z_NO_FLUSH);
- if (finish && err == Z_STREAM_END)
- break;
- check_err(err, "deflate");
- if (!finish && c_stream.avail_in == 0)
- break;
- }
- if (finish) {
- if (c_stream.avail_out < ZIP_BUF_SIZE) { /* at least one byte has been output */
- pdf_gone +=
- xfwrite(zipbuf, 1, ZIP_BUF_SIZE - c_stream.avail_out, pdf_file);
- pdf_last_byte = zipbuf[ZIP_BUF_SIZE - c_stream.avail_out - 1];
- }
- xfflush(pdf_file);
- }
- pdf_stream_length = c_stream.total_out;
-}
-
-void zip_free(void)
-{
- if (zipbuf != NULL) {
- check_err(deflateEnd(&c_stream), "deflateEnd");
- free(zipbuf);
- }
-}
diff --git a/Build/source/texk/web2c/man/Makefile.in b/Build/source/texk/web2c/man/Makefile.in
index ad76c3d71e2..45566e21c2e 100644
--- a/Build/source/texk/web2c/man/Makefile.in
+++ b/Build/source/texk/web2c/man/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -175,6 +175,10 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBOBJS = @LIBOBJS@
LIBPNG_DEPEND = @LIBPNG_DEPEND@
LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
@@ -184,6 +188,8 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
LUATANGLE = @LUATANGLE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
diff --git a/Build/source/texk/web2c/omegafonts/Makefile.in b/Build/source/texk/web2c/omegafonts/Makefile.in
index de808cc971d..1369f4d1475 100644
--- a/Build/source/texk/web2c/omegafonts/Makefile.in
+++ b/Build/source/texk/web2c/omegafonts/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -179,6 +179,10 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBOBJS = @LIBOBJS@
LIBPNG_DEPEND = @LIBPNG_DEPEND@
LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
@@ -188,6 +192,8 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
LUATANGLE = @LUATANGLE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
diff --git a/Build/source/texk/web2c/otps/Makefile.in b/Build/source/texk/web2c/otps/Makefile.in
index 93a8c936c28..f077c163817 100644
--- a/Build/source/texk/web2c/otps/Makefile.in
+++ b/Build/source/texk/web2c/otps/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -205,6 +205,10 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBOBJS = @LIBOBJS@
LIBPNG_DEPEND = @LIBPNG_DEPEND@
LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
@@ -214,6 +218,8 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
LUATANGLE = @LUATANGLE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
diff --git a/Build/source/texk/web2c/web2c/Makefile.in b/Build/source/texk/web2c/web2c/Makefile.in
index 3f45a76ae1b..2f7d19bbfd1 100644
--- a/Build/source/texk/web2c/web2c/Makefile.in
+++ b/Build/source/texk/web2c/web2c/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -504,8 +504,7 @@ distdir: $(DISTFILES)
fi; \
done
-test -n "$(am__skip_mode_fix)" \
- || find "$(distdir)" -type d ! -perm -755 \
- -exec chmod u+rwx,go+rx {} \; -o \
+ || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
@@ -549,17 +548,17 @@ dist dist-all: distdir
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
- bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
diff --git a/Build/source/texk/web2c/web2c/aclocal.m4 b/Build/source/texk/web2c/web2c/aclocal.m4
index de2eee116a4..9f5b37d0928 100644
--- a/Build/source/texk/web2c/web2c/aclocal.m4
+++ b/Build/source/texk/web2c/web2c/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.11 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
@@ -34,7 +34,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
+m4_if([$1], [1.11], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -50,7 +50,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
+[AM_AUTOMAKE_VERSION([1.11])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
diff --git a/Build/source/texk/web2c/web2c/configure b/Build/source/texk/web2c/web2c/configure
index f6f108bbde5..b935fef7182 100755
--- a/Build/source/texk/web2c/web2c/configure
+++ b/Build/source/texk/web2c/web2c/configure
@@ -12748,9 +12748,9 @@ esac
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-config_commands="$ac_config_commands"
+config_files="`echo $ac_config_files`"
+config_headers="`echo $ac_config_headers`"
+config_commands="`echo $ac_config_commands`"
_ACEOF
diff --git a/Build/source/texk/web2c/window/Makefile.in b/Build/source/texk/web2c/window/Makefile.in
index 0e133d95e39..4c2302b711d 100644
--- a/Build/source/texk/web2c/window/Makefile.in
+++ b/Build/source/texk/web2c/window/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -166,6 +166,10 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBOBJS = @LIBOBJS@
LIBPNG_DEPEND = @LIBPNG_DEPEND@
LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
@@ -175,6 +179,8 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
LUATANGLE = @LUATANGLE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@