diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2009-04-16 07:56:44 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2009-04-16 07:56:44 +0000 |
commit | 40c2ba944e1cee0677734608263cbc7ba3a729bf (patch) | |
tree | 6da3acbd4e74eb5854f90416313fb56a4eb29824 | |
parent | 79e9c535970a1887e1b6b2196cd90775955ea486 (diff) |
Import luatex 0.39.0
git-svn-id: svn://tug.org/texlive/trunk@12733 c570f23f-e606-0410-a88d-b1316a301751
149 files changed, 5333 insertions, 3391 deletions
diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog index e14ca3a191d..4091aff8cdb 100644 --- a/Build/source/texk/web2c/luatexdir/ChangeLog +++ b/Build/source/texk/web2c/luatexdir/ChangeLog @@ -1,3 +1,8 @@ +2009-04-16 Taco Hoekwater <taco@luatex.org> + + * luatexdir: import of the current state of luatex, 0.39.0. + This affects many files in subdirectories. + 2009-03-27 Peter Breitenlohner <peb@mppmu.mpg.de> * am/luatex.am (luatex_c_h): avoid to split the C code diff --git a/Build/source/texk/web2c/luatexdir/NEWS b/Build/source/texk/web2c/luatexdir/NEWS index 9f151037197..09adf33455c 100644 --- a/Build/source/texk/web2c/luatexdir/NEWS +++ b/Build/source/texk/web2c/luatexdir/NEWS @@ -1,4 +1,164 @@ ============================================================== +Luatex beta-0.39.0 was released 20090415 +============================================================== + +* iniluatex will from now on start up with only the TeX82 primitives + and \directlua, everything else has to be bootstrapped via + tex.enableprimitives(). This change was planned for 0.40.0, + but *now* is the time to test it. + +* A bugfix for \primitive in various expandable contexts, + and \primitive now generates an error message when the + argument is not actually a primitive's name. + +* There was a bug found in the math accent handling. + +* Large math operators are now treated like extensible characters + in the sense that they can be composed of segments. + +* The extra assign- and restore tracing information from eTeX + had a massive bug because of a dangling else in the pascal web. + As a side-effect of fixing this bugs, all such potential errors + in the pascal web have been fixed (for now). + +* The math parameters can now be set and queried from lua code + via the new tex.setmath() and tex.getmath() functions. + +* Reflection in a \hbox was broken. + +* There was a leak of direction nodes in the paragraph builder. + +* The font backend now does a small peek to differentiate + truetype and postscript style opentype fonts. This fixes + the "Can't find CFF table" bug for otf's with truetype outlines. + +* Parameters and registers can now also be assinged to globally + from lua (see the manual for details). + +* It is now possible to query the current math style while a + formula is still being constructed by using the new read-only + value \mathstyle. Associated is the new command \Ustack that + is to be used as a prefix for {.. \over ..} and friends. + See the manual for more information. + +* The embedded MPLib is brought up to date with the current + metapost repository (version 1.110 and a few small patches). + +* Luatex can now handle two breakpoints inside a single ligature + (like for the functional word of-f-ice). The solution is not + perfect yet, but the chance of missed hyphenation points in + actual documents should now be negligible. + +* Some speedups in the font loading code, and in the handling of + pdf_literal nodes that are set from within Lua code. + +* Some source code and manual cleanup, as usual. + +============================================================== +Luatex beta-0.38.0 was released 20090410 +============================================================== + +* tex.enableprimitives() had a bug were previously defined (but + currently undefined) control sequences prevented the creation + of the new csname. + +* The special calling format callback.register('name', false) + not only disables the callback, but also the builtin code it + is supposed to replace. + +* Empty \localleftbox and \localrightbox -es are now suppressed. + +* Support for <f>.MathConstants.SubscriptShiftDownWithSuperscript + was added, to solve the lack of "sub2" in OpenType math. + +* Luatex now supports horizontal super- and subscript placement + corrections via the OpenType MATH mathkern table. See the + manual for details. + +* node.write() no longer copies its argument node list before + appending it. + +* There are six new primitives that are verbose forms + of one and two byte special tokens: + \Usuperscript \Usubscript + \Ustartmath \Ustopmath + \Ustartdisplaymath \Ustopdisplaymath + +* The attribute node leaks in math mode and alignmetns have been + fixed. + +* The 11 simple math noads are now combined into a single "noad" + node type. + +* Static linking against libstdc++ is working once again. + +* There is a small fix in the keyword scanner to solve the + problem of 'Runaway ... while scanning ???' that could happen + for some primitives. + +* Lua now also has the "architecture independent bytecode" + patch applied. + +* Lua is updated to version 5.1.4 with coco patches 1.1.5, and + lpeg is now 0.9. + +* Some TRT/TLT backend bugs are fixed. + +* Various manual updates. + +============================================================== +Luatex beta-0.37.0 was released 20090331 +============================================================== + +* Luatex now implements shell_escape = 'p', a new feature + in web2c that intends to make \write18 more secure. As + a side-effect, if luatex is used for typesetting, it will + now also apply shell_escape = 'p' and shell_escape = 'f' + to the lua functions io.popen(), os.execute(), os.exec(), + and os.spawn(). + Nothing has changed for the case where luatex is used as + a script interpreter. + +* Attributes can now have negative values. The special value + for 'unset' is lowered to -0x7FFFFFFF (it used to be -1). + +* The lua 'kpse' library now has an object-oriented interface + as companion to the procedural interface. This is useful for + e.g. controlling the discovery of mplib files. + +* The new internal integer parameter \outputbox allows setting + of the output box number (default: 255, max: 65535) + +* The new primitives \Udelimiterunder and \Udelimiterover + complete the set of 'StretchStacks' for OpenType Math. + +* Fixed a bug in font string conversions on the Macintosh that + resulted in warnings about 'unaligned pointers being freed'. + +* Khaled Hosny spotted a bunch of manual errors. + +* There was bug in the width of math_accent objects when + there were super- or subscripts attached to the accentee. + +* In PDF mode, TRT \leaders were bugged. + +* The source tree now uses the new texlive build system that + Peter Breitenlohner created. + +* There is now a single build.sh instead of four separate + ones. It has a few options: + --make : only make, no make distclean; configure + --parallel : make -j 2 -l 3.0 + --nostrip : do not strip binary + --mingw : crosscompile for mingw32 from i386-linux + --ppc : crosscompile for ppc osx on intel osx + + Note: --parallel still sometimes causes crashes due to + timing errors, so use that option with care. + +* Many compiler warnings have been removed (but not all yet). + +============================================================== Luatex beta-0.36.0 was released 20090323 ============================================================== @@ -538,7 +698,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$ into the object file. + and link in $Id$ and $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/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/am/luatex.am b/Build/source/texk/web2c/luatexdir/am/luatex.am index cbaf040e13d..77c20a36b36 100644 --- a/Build/source/texk/web2c/luatexdir/am/luatex.am +++ b/Build/source/texk/web2c/luatexdir/am/luatex.am @@ -14,15 +14,18 @@ luatex_tangle = WEBINPUTS=$(srcdir)/luatexdir $(buildenv) $(LUATANGLE) luatex_CPPFLAGS = $(ZLIB_INCLUDES) $(LIBPNG_INCLUDES) $(XPDF_INCLUDES) luatex_CPPFLAGS += $(OBSDCOMPAT_INCLUDES) -I$(srcdir)/libmd5 -luatex_CPPFLAGS += -Iluatexdir -I$(srcdir)/luatexdir -I$(srcdir)/luatexdir/lua51 -I$(srcdir)/luatexdir/mp +luatex_CPPFLAGS += -Iluatexdir -I$(srcdir)/luatexdir -I$(srcdir)/luatexdir/lua51 -I$(srcdir)/mplibdir luatex_CPPFLAGS += -Dextra_version_info=`date +-%Y%m%d%H` luatex_ldadd = libluatex.a libff.a libluamisc.a libzzip.a libluasocket.a liblua51.a luatex_ldadd += $(LIBPNG_LIBS) $(ZLIB_LIBS) $(XPDF_LIBS) -luatex_ldadd += $(OBSDCOMPAT_LIBS) libmd5.a +luatex_ldadd += $(OBSDCOMPAT_LIBS) libmd5.a libmplib.a luatex_LDADD = $(luatex_ldadd) $(LDADD) $(socketlibs) +## We must have created libmplib.a already +$(luatex_OBJECTS): libmplib.a + luatex_DEPENDENCIES = $(proglib) libluatex.a luatex_DEPENDENCIES += $(LIBPNG_DEPEND) $(ZLIB_DEPEND) $(XPDF_DEPEND) luatex_DEPENDENCIES += $(OBSDCOMPAT_DEPEND) libmd5.a @@ -107,7 +110,6 @@ liblua51_a_SOURCES = \ luatexdir/lua51/lgc.c \ luatexdir/lua51/lgc.h \ luatexdir/lua51/linit.c \ - luatexdir/lua51/liolib.c \ luatexdir/lua51/llex.c \ luatexdir/lua51/llex.h \ luatexdir/lua51/llimits.h \ @@ -148,6 +150,7 @@ EXTRA_DIST += \ luatexdir/lua51/Makefile \ luatexdir/lua51/lua.c \ luatexdir/lua51/luac.c \ + luatexdir/lua51/liolib.c \ luatexdir/lua51/print.c ## zziplib @@ -237,7 +240,7 @@ EXTRA_LIBRARIES += libluasocket.a libluasocket_a_DEPENDENCIES = $(ZLIB_DEPEND) libzzip.a libluasocket_a_CPPFLAGS = \ - -I$(top_srcdir)/luatexdir/luasocket -I$(srcdir)/luatexdir/lua51 + -DLUASOCKET_DEBUG -I$(top_srcdir)/luatexdir/luasocket -I$(srcdir)/luatexdir/lua51 libluasocket_a_SOURCES = \ luatexdir/luasocket/src/auxiliar.c \ @@ -272,13 +275,13 @@ libluasocket_a_SOURCES = \ EXTRA_DIST += \ luatexdir/luasocket/src/socket_lua.c \ - luatexdir/luasocket/src/ftp_lua.c \ - luatexdir/luasocket/src/http_lua.c \ - luatexdir/luasocket/src/smtp_lua.c \ - luatexdir/luasocket/src/tp_lua.c \ - luatexdir/luasocket/src/url_lua.c \ - luatexdir/luasocket/src/ltn12_lua.c \ - luatexdir/luasocket/src/mime_lua.c + luatexdir/luasocket/src/ftp_lua.c \ + luatexdir/luasocket/src/http_lua.c \ + luatexdir/luasocket/src/smtp_lua.c \ + luatexdir/luasocket/src/tp_lua.c \ + luatexdir/luasocket/src/url_lua.c \ + luatexdir/luasocket/src/ltn12_lua.c \ + luatexdir/luasocket/src/mime_lua.c ## Not used ## @@ -289,63 +292,63 @@ EXTRA_DIST += \ luatexdir/luasocket/src/usocket.c \ luatexdir/luasocket/src/wsocket.c \ luatexdir/luasocket/src/wsocket.h \ - luatexdir/luasocket/src/ftp.lua \ - luatexdir/luasocket/src/http.lua \ - luatexdir/luasocket/src/smtp.lua \ - luatexdir/luasocket/src/socket.lua \ - luatexdir/luasocket/src/tp.lua \ - luatexdir/luasocket/src/url.lua \ - luatexdir/luasocket/src/ltn12.lua \ - luatexdir/luasocket/src/mime.lua \ - luatexdir/luasocket/LICENSE \ - luatexdir/luasocket/NEW \ - luatexdir/luasocket/README \ - luatexdir/luasocket/config \ - luatexdir/luasocket/luasocket.sln \ - luatexdir/luasocket/makefile \ - luatexdir/luasocket/mime.vcproj \ - luatexdir/luasocket/socket.vcproj \ - luatexdir/luasocket/doc/dns.html \ - luatexdir/luasocket/doc/ftp.html \ - luatexdir/luasocket/doc/http.html \ - luatexdir/luasocket/doc/index.html \ - luatexdir/luasocket/doc/installation.html \ - luatexdir/luasocket/doc/introduction.html \ - luatexdir/luasocket/doc/ltn12.html \ - luatexdir/luasocket/doc/luasocket.png \ - luatexdir/luasocket/doc/mime.html \ - luatexdir/luasocket/doc/reference.css \ - luatexdir/luasocket/doc/reference.html \ - luatexdir/luasocket/doc/smtp.html \ - luatexdir/luasocket/doc/socket.html \ - luatexdir/luasocket/doc/tcp.html \ - luatexdir/luasocket/doc/udp.html \ - luatexdir/luasocket/doc/url.html \ - luatexdir/luasocket/etc/README \ - luatexdir/luasocket/etc/b64.lua \ - luatexdir/luasocket/etc/check-links.lua \ - luatexdir/luasocket/etc/check-memory.lua \ - luatexdir/luasocket/etc/dict.lua \ - luatexdir/luasocket/etc/dispatch.lua \ - luatexdir/luasocket/etc/eol.lua \ - luatexdir/luasocket/etc/forward.lua \ - luatexdir/luasocket/etc/get.lua \ - luatexdir/luasocket/etc/lp.lua \ - luatexdir/luasocket/etc/qp.lua \ - luatexdir/luasocket/etc/tftp.lua \ - luatexdir/luasocket/samples/README \ - luatexdir/luasocket/samples/cddb.lua \ - luatexdir/luasocket/samples/daytimeclnt.lua \ - luatexdir/luasocket/samples/echoclnt.lua \ - luatexdir/luasocket/samples/echosrvr.lua \ - luatexdir/luasocket/samples/listener.lua \ - luatexdir/luasocket/samples/lpr.lua \ - luatexdir/luasocket/samples/talker.lua \ - luatexdir/luasocket/samples/tinyirc.lua \ - luatexdir/luasocket/test/README \ - luatexdir/luasocket/test/testclnt.lua \ - luatexdir/luasocket/test/testsrvr.lua \ - luatexdir/luasocket/test/testsupport.lua + luatexdir/luasocket/src/ftp.lua \ + luatexdir/luasocket/src/http.lua \ + luatexdir/luasocket/src/smtp.lua \ + luatexdir/luasocket/src/socket.lua \ + luatexdir/luasocket/src/tp.lua \ + luatexdir/luasocket/src/url.lua \ + luatexdir/luasocket/src/ltn12.lua \ + luatexdir/luasocket/src/mime.lua \ + luatexdir/luasocket/LICENSE \ + luatexdir/luasocket/NEW \ + luatexdir/luasocket/README \ + luatexdir/luasocket/config \ + luatexdir/luasocket/luasocket.sln \ + luatexdir/luasocket/makefile \ + luatexdir/luasocket/mime.vcproj \ + luatexdir/luasocket/socket.vcproj \ + luatexdir/luasocket/doc/dns.html \ + luatexdir/luasocket/doc/ftp.html \ + luatexdir/luasocket/doc/http.html \ + luatexdir/luasocket/doc/index.html \ + luatexdir/luasocket/doc/installation.html \ + luatexdir/luasocket/doc/introduction.html \ + luatexdir/luasocket/doc/ltn12.html \ + luatexdir/luasocket/doc/luasocket.png \ + luatexdir/luasocket/doc/mime.html \ + luatexdir/luasocket/doc/reference.css \ + luatexdir/luasocket/doc/reference.html \ + luatexdir/luasocket/doc/smtp.html \ + luatexdir/luasocket/doc/socket.html \ + luatexdir/luasocket/doc/tcp.html \ + luatexdir/luasocket/doc/udp.html \ + luatexdir/luasocket/doc/url.html \ + luatexdir/luasocket/etc/README \ + luatexdir/luasocket/etc/b64.lua \ + luatexdir/luasocket/etc/check-links.lua \ + luatexdir/luasocket/etc/check-memory.lua \ + luatexdir/luasocket/etc/dict.lua \ + luatexdir/luasocket/etc/dispatch.lua \ + luatexdir/luasocket/etc/eol.lua \ + luatexdir/luasocket/etc/forward.lua \ + luatexdir/luasocket/etc/get.lua \ + luatexdir/luasocket/etc/lp.lua \ + luatexdir/luasocket/etc/qp.lua \ + luatexdir/luasocket/etc/tftp.lua \ + luatexdir/luasocket/samples/README \ + luatexdir/luasocket/samples/cddb.lua \ + luatexdir/luasocket/samples/daytimeclnt.lua \ + luatexdir/luasocket/samples/echoclnt.lua \ + luatexdir/luasocket/samples/echosrvr.lua \ + luatexdir/luasocket/samples/listener.lua \ + luatexdir/luasocket/samples/lpr.lua \ + luatexdir/luasocket/samples/talker.lua \ + luatexdir/luasocket/samples/tinyirc.lua \ + luatexdir/luasocket/test/README \ + luatexdir/luasocket/test/testclnt.lua \ + luatexdir/luasocket/test/testsrvr.lua \ + luatexdir/luasocket/test/testsupport.lua ## libluamisc (luafilesystem, luamd5, luapeg, luazip, luazlib, luaprofiler, ## and slnunicode) @@ -366,11 +369,11 @@ libluamisc_a_SOURCES = \ luatexdir/luamd5/md5lib.c \ luatexdir/luapeg/lpeg.c \ luatexdir/luaprofiler/clocks.h \ - luatexdir/luaprofiler/core_profiler.h \ - luatexdir/luaprofiler/function_meter.h \ - luatexdir/luaprofiler/luaprofiler.h \ - luatexdir/luaprofiler/stack.h \ - luatexdir/luaprofiler/clocks.c \ + luatexdir/luaprofiler/core_profiler.h \ + luatexdir/luaprofiler/function_meter.h \ + luatexdir/luaprofiler/luaprofiler.h \ + luatexdir/luaprofiler/stack.h \ + luatexdir/luaprofiler/clocks.c \ luatexdir/luaprofiler/core_profiler.c \ luatexdir/luaprofiler/function_meter.c \ luatexdir/luaprofiler/lua50_profiler.c \ @@ -431,107 +434,107 @@ libff_a_CPPFLAGS = \ -I$(top_srcdir)/luatexdir/luafontloader/fontforge/fontforge 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 \ - luatexdir/luafontloader/fontforge/fontforge/autohint.c \ - luatexdir/luafontloader/fontforge/fontforge/baseviews.h \ - luatexdir/luafontloader/fontforge/fontforge/clipnoui.c \ - luatexdir/luafontloader/fontforge/fontforge/configure-pfaedit.h \ - luatexdir/luafontloader/fontforge/fontforge/cvundoes.c \ - luatexdir/luafontloader/fontforge/fontforge/dumppfa.c \ - luatexdir/luafontloader/fontforge/fontforge/edgelist.h \ - luatexdir/luafontloader/fontforge/fontforge/edgelist2.h \ - luatexdir/luafontloader/fontforge/fontforge/encoding.c \ - luatexdir/luafontloader/fontforge/fontforge/encoding.h \ - luatexdir/luafontloader/fontforge/fontforge/featurefile.c \ - luatexdir/luafontloader/fontforge/fontforge/fontforgevw.h \ - luatexdir/luafontloader/fontforge/fontforge/fontviewbase.c \ - luatexdir/luafontloader/fontforge/fontforge/fvcomposit.c \ - luatexdir/luafontloader/fontforge/fontforge/fvfonts.c \ - luatexdir/luafontloader/fontforge/fontforge/libffstamp.h \ - luatexdir/luafontloader/fontforge/fontforge/libstamp.pre \ - luatexdir/luafontloader/fontforge/fontforge/lookups.c \ - luatexdir/luafontloader/fontforge/fontforge/lookups.h \ - luatexdir/luafontloader/fontforge/fontforge/macbinary.c \ - luatexdir/luafontloader/fontforge/fontforge/macenc.c \ - luatexdir/luafontloader/fontforge/fontforge/mathconstants.c \ - luatexdir/luafontloader/fontforge/fontforge/mm.c \ - luatexdir/luafontloader/fontforge/fontforge/mm.h \ - luatexdir/luafontloader/fontforge/fontforge/namelist.c \ - luatexdir/luafontloader/fontforge/fontforge/noprefs.c \ - luatexdir/luafontloader/fontforge/fontforge/nouiutil.c \ - luatexdir/luafontloader/fontforge/fontforge/parsepfa.c \ - luatexdir/luafontloader/fontforge/fontforge/parsettf.c \ - luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c \ - luatexdir/luafontloader/fontforge/fontforge/parsettfvar.c \ - luatexdir/luafontloader/fontforge/fontforge/pfaedit.h \ - luatexdir/luafontloader/fontforge/fontforge/plugins.h \ - luatexdir/luafontloader/fontforge/fontforge/psfont.h \ - luatexdir/luafontloader/fontforge/fontforge/psread.c \ - luatexdir/luafontloader/fontforge/fontforge/pua.c \ - luatexdir/luafontloader/fontforge/fontforge/python.c \ - luatexdir/luafontloader/fontforge/fontforge/scripting.h \ - luatexdir/luafontloader/fontforge/fontforge/sd.h \ - luatexdir/luafontloader/fontforge/fontforge/sfd1.c \ - luatexdir/luafontloader/fontforge/fontforge/sfd1.h \ - luatexdir/luafontloader/fontforge/fontforge/splinechar.c \ - luatexdir/luafontloader/fontforge/fontforge/splinefill.c \ - luatexdir/luafontloader/fontforge/fontforge/splinefont.c \ - luatexdir/luafontloader/fontforge/fontforge/splinefont.h \ - luatexdir/luafontloader/fontforge/fontforge/splineorder2.c \ - luatexdir/luafontloader/fontforge/fontforge/splineoverlap.c \ - luatexdir/luafontloader/fontforge/fontforge/splinerefigure.c \ - luatexdir/luafontloader/fontforge/fontforge/splinesave.c \ - luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c \ - luatexdir/luafontloader/fontforge/fontforge/splinestroke.c \ - luatexdir/luafontloader/fontforge/fontforge/splineutil.c \ - luatexdir/luafontloader/fontforge/fontforge/splineutil2.c \ - luatexdir/luafontloader/fontforge/fontforge/start.c \ - luatexdir/luafontloader/fontforge/fontforge/stemdb.c \ - luatexdir/luafontloader/fontforge/fontforge/stemdb.h \ - luatexdir/luafontloader/fontforge/fontforge/tottf.c \ - luatexdir/luafontloader/fontforge/fontforge/tottfaat.c \ - luatexdir/luafontloader/fontforge/fontforge/tottfgpos.c \ - luatexdir/luafontloader/fontforge/fontforge/ttf.h \ - luatexdir/luafontloader/fontforge/fontforge/ttfspecial.c \ - luatexdir/luafontloader/fontforge/fontforge/uiinterface.h \ - luatexdir/luafontloader/fontforge/fontforge/unicoderange.h \ - luatexdir/luafontloader/fontforge/fontforge/views.h \ - luatexdir/luafontloader/fontforge/gutils/fsys.c \ - luatexdir/luafontloader/fontforge/gutils/gwwintl.c \ - luatexdir/luafontloader/fontforge/inc/basics.h \ - luatexdir/luafontloader/fontforge/inc/chardata.h \ - luatexdir/luafontloader/fontforge/inc/charset.h \ - luatexdir/luafontloader/fontforge/inc/dynamic.h \ - luatexdir/luafontloader/fontforge/inc/fileutil.h \ - luatexdir/luafontloader/fontforge/inc/gdraw.h \ - luatexdir/luafontloader/fontforge/inc/gfile.h \ - luatexdir/luafontloader/fontforge/inc/ggadget.h \ - luatexdir/luafontloader/fontforge/inc/gicons.h \ - luatexdir/luafontloader/fontforge/inc/gimage.h \ - luatexdir/luafontloader/fontforge/inc/gio.h \ - luatexdir/luafontloader/fontforge/inc/gkeysym.h \ - luatexdir/luafontloader/fontforge/inc/gprogress.h \ - luatexdir/luafontloader/fontforge/inc/gresource.h \ - luatexdir/luafontloader/fontforge/inc/gwidget.h \ - luatexdir/luafontloader/fontforge/inc/gwwiconv.h \ - luatexdir/luafontloader/fontforge/inc/intl.h \ - luatexdir/luafontloader/fontforge/inc/ustring.h \ - luatexdir/luafontloader/fontforge/inc/utype.h \ - luatexdir/luafontloader/src/ffdummies.c \ - luatexdir/luafontloader/src/luafflib.c + luatexdir/luafontloader/fontforge/Unicode/ArabicForms.c \ + luatexdir/luafontloader/fontforge/Unicode/alphabet.c \ + luatexdir/luafontloader/fontforge/Unicode/backtrns.c \ + luatexdir/luafontloader/fontforge/Unicode/char.c \ + luatexdir/luafontloader/fontforge/Unicode/cjk.c \ + luatexdir/luafontloader/fontforge/Unicode/combiners.h \ + luatexdir/luafontloader/fontforge/Unicode/dump.c \ + luatexdir/luafontloader/fontforge/Unicode/gwwiconv.c \ + luatexdir/luafontloader/fontforge/Unicode/memory.c \ + luatexdir/luafontloader/fontforge/Unicode/ucharmap.c \ + luatexdir/luafontloader/fontforge/Unicode/unialt.c \ + luatexdir/luafontloader/fontforge/Unicode/ustring.c \ + luatexdir/luafontloader/fontforge/Unicode/utype.c \ + luatexdir/luafontloader/fontforge/fontforge/PfEd.h \ + luatexdir/luafontloader/fontforge/fontforge/autohint.c \ + luatexdir/luafontloader/fontforge/fontforge/baseviews.h \ + luatexdir/luafontloader/fontforge/fontforge/clipnoui.c \ + luatexdir/luafontloader/fontforge/fontforge/configure-pfaedit.h \ + luatexdir/luafontloader/fontforge/fontforge/cvundoes.c \ + luatexdir/luafontloader/fontforge/fontforge/dumppfa.c \ + luatexdir/luafontloader/fontforge/fontforge/edgelist.h \ + luatexdir/luafontloader/fontforge/fontforge/edgelist2.h \ + luatexdir/luafontloader/fontforge/fontforge/encoding.c \ + luatexdir/luafontloader/fontforge/fontforge/encoding.h \ + luatexdir/luafontloader/fontforge/fontforge/featurefile.c \ + luatexdir/luafontloader/fontforge/fontforge/fontforgevw.h \ + luatexdir/luafontloader/fontforge/fontforge/fontviewbase.c \ + luatexdir/luafontloader/fontforge/fontforge/fvcomposit.c \ + luatexdir/luafontloader/fontforge/fontforge/fvfonts.c \ + luatexdir/luafontloader/fontforge/fontforge/libffstamp.h \ + luatexdir/luafontloader/fontforge/fontforge/libstamp.pre \ + luatexdir/luafontloader/fontforge/fontforge/lookups.c \ + luatexdir/luafontloader/fontforge/fontforge/lookups.h \ + luatexdir/luafontloader/fontforge/fontforge/macbinary.c \ + luatexdir/luafontloader/fontforge/fontforge/macenc.c \ + luatexdir/luafontloader/fontforge/fontforge/mathconstants.c \ + luatexdir/luafontloader/fontforge/fontforge/mm.c \ + luatexdir/luafontloader/fontforge/fontforge/mm.h \ + luatexdir/luafontloader/fontforge/fontforge/namelist.c \ + luatexdir/luafontloader/fontforge/fontforge/noprefs.c \ + luatexdir/luafontloader/fontforge/fontforge/nouiutil.c \ + luatexdir/luafontloader/fontforge/fontforge/parsepfa.c \ + luatexdir/luafontloader/fontforge/fontforge/parsettf.c \ + luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c \ + luatexdir/luafontloader/fontforge/fontforge/parsettfvar.c \ + luatexdir/luafontloader/fontforge/fontforge/pfaedit.h \ + luatexdir/luafontloader/fontforge/fontforge/plugins.h \ + luatexdir/luafontloader/fontforge/fontforge/psfont.h \ + luatexdir/luafontloader/fontforge/fontforge/psread.c \ + luatexdir/luafontloader/fontforge/fontforge/pua.c \ + luatexdir/luafontloader/fontforge/fontforge/python.c \ + luatexdir/luafontloader/fontforge/fontforge/scripting.h \ + luatexdir/luafontloader/fontforge/fontforge/sd.h \ + luatexdir/luafontloader/fontforge/fontforge/sfd1.c \ + luatexdir/luafontloader/fontforge/fontforge/sfd1.h \ + luatexdir/luafontloader/fontforge/fontforge/splinechar.c \ + luatexdir/luafontloader/fontforge/fontforge/splinefill.c \ + luatexdir/luafontloader/fontforge/fontforge/splinefont.c \ + luatexdir/luafontloader/fontforge/fontforge/splinefont.h \ + luatexdir/luafontloader/fontforge/fontforge/splineorder2.c \ + luatexdir/luafontloader/fontforge/fontforge/splineoverlap.c \ + luatexdir/luafontloader/fontforge/fontforge/splinerefigure.c \ + luatexdir/luafontloader/fontforge/fontforge/splinesave.c \ + luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c \ + luatexdir/luafontloader/fontforge/fontforge/splinestroke.c \ + luatexdir/luafontloader/fontforge/fontforge/splineutil.c \ + luatexdir/luafontloader/fontforge/fontforge/splineutil2.c \ + luatexdir/luafontloader/fontforge/fontforge/start.c \ + luatexdir/luafontloader/fontforge/fontforge/stemdb.c \ + luatexdir/luafontloader/fontforge/fontforge/stemdb.h \ + luatexdir/luafontloader/fontforge/fontforge/tottf.c \ + luatexdir/luafontloader/fontforge/fontforge/tottfaat.c \ + luatexdir/luafontloader/fontforge/fontforge/tottfgpos.c \ + luatexdir/luafontloader/fontforge/fontforge/ttf.h \ + luatexdir/luafontloader/fontforge/fontforge/ttfspecial.c \ + luatexdir/luafontloader/fontforge/fontforge/uiinterface.h \ + luatexdir/luafontloader/fontforge/fontforge/unicoderange.h \ + luatexdir/luafontloader/fontforge/fontforge/views.h \ + luatexdir/luafontloader/fontforge/gutils/fsys.c \ + luatexdir/luafontloader/fontforge/gutils/gwwintl.c \ + luatexdir/luafontloader/fontforge/inc/basics.h \ + luatexdir/luafontloader/fontforge/inc/chardata.h \ + luatexdir/luafontloader/fontforge/inc/charset.h \ + luatexdir/luafontloader/fontforge/inc/dynamic.h \ + luatexdir/luafontloader/fontforge/inc/fileutil.h \ + luatexdir/luafontloader/fontforge/inc/gdraw.h \ + luatexdir/luafontloader/fontforge/inc/gfile.h \ + luatexdir/luafontloader/fontforge/inc/ggadget.h \ + luatexdir/luafontloader/fontforge/inc/gicons.h \ + luatexdir/luafontloader/fontforge/inc/gimage.h \ + luatexdir/luafontloader/fontforge/inc/gio.h \ + luatexdir/luafontloader/fontforge/inc/gkeysym.h \ + luatexdir/luafontloader/fontforge/inc/gprogress.h \ + luatexdir/luafontloader/fontforge/inc/gresource.h \ + luatexdir/luafontloader/fontforge/inc/gwidget.h \ + luatexdir/luafontloader/fontforge/inc/gwwiconv.h \ + luatexdir/luafontloader/fontforge/inc/intl.h \ + luatexdir/luafontloader/fontforge/inc/ustring.h \ + luatexdir/luafontloader/fontforge/inc/utype.h \ + luatexdir/luafontloader/src/ffdummies.c \ + luatexdir/luafontloader/src/luafflib.c EXTRA_DIST += \ luatexdir/luafontloader/ChangeLog \ @@ -543,15 +546,15 @@ EXTRA_DIST += \ ## Not used ## EXTRA_DIST += \ - luatexdir/luafontloader/fontforge/Makefile.in \ - luatexdir/luafontloader/fontforge/Unicode/Makefile.in \ - luatexdir/luafontloader/fontforge/configure-options \ - luatexdir/luafontloader/fontforge/configure.in \ - luatexdir/luafontloader/fontforge/fontforge/Makefile.in \ - luatexdir/luafontloader/fontforge/gdraw/Makefile.in \ - luatexdir/luafontloader/fontforge/gutils/Makefile.in \ - luatexdir/luafontloader/fontforge/inc/config.h.in \ - luatexdir/luafontloader/fontforge/plugins/Makefile.in + luatexdir/luafontloader/fontforge/Makefile.in \ + luatexdir/luafontloader/fontforge/Unicode/Makefile.in \ + luatexdir/luafontloader/fontforge/configure-options \ + luatexdir/luafontloader/fontforge/configure.in \ + luatexdir/luafontloader/fontforge/fontforge/Makefile.in \ + luatexdir/luafontloader/fontforge/gdraw/Makefile.in \ + luatexdir/luafontloader/fontforge/gutils/Makefile.in \ + luatexdir/luafontloader/fontforge/inc/config.h.in \ + luatexdir/luafontloader/fontforge/plugins/Makefile.in ## libluatex ## @@ -617,6 +620,7 @@ libluatex_a_SOURCES = \ 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 \ @@ -634,7 +638,7 @@ libluatex_a_SOURCES = \ luatexdir/managed-sa.c \ luatexdir/managed-sa.h \ luatexdir/mathcodes.c \ - luatexdir/mp/lmplib.c \ + mplibdir/lmplib.c \ luatexdir/nodes.h \ luatexdir/pdf/pagetree.c \ luatexdir/pdf/pdfpage.c \ @@ -662,34 +666,6 @@ libluatex_a_SOURCES = \ luatexdir/utils/utils.c \ luatexdir/utils/writezip.c -nodist_libluatex_a_SOURCES = $(lua_mp_c_h) - -## We must create lua_mp_c_h before building the libluatex_a_SOURCES. -$(libluatex_a_OBJECTS): $(lua_mp_c_h) - -## These files are mutually dependent -lua_mp_c_h = luatexdir/mp.c luatexdir/mplib.h luatexdir/mpmp.h -lua_mp_c_h += luatexdir/mppsout.h luatexdir/psout.c luatexdir/mplibps.h -lua_mp_c_h += luatexdir/memio.c luatexdir/tfmin.c -lua_mp_web = luatexdir/mp/avl.h luatexdir/mp/avl.c luatexdir/mp/mp.w luatexdir/mp/psout.w -lua_mp_web += luatexdir/mp/memio.w luatexdir/mp/tfmin.w -libluatex_a_CPPFLAGS += -I$(srcdir)/luatexdir/mp -$(lua_mp_c_h): mp-ctangle -mp-ctangle: ctangle$(EXEEXT) $(lua_mp_web) luatexd.h - $(mkdir_p) luatexdir - CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) mp.w - CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) psout.w - CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) tfmin.w - CWEBINPUTS=$(srcdir)/luatexdir/mp $(ctangle) memio.w - rm -f $(lua_mp_c_h) - mv mp.c mplib.h mpmp.h mppsout.h psout.c mplibps.h memio.c tfmin.c luatexdir - echo timestamp >$@ - touch $(lua_mp_c_h) - -EXTRA_DIST += $(lua_mp_web) - -DISTCLEANFILES += $(lua_mp_c_h) mp-ctangle - ## included by luatexdir/font/writettf.c EXTRA_libluatex_a_SOURCES = luatexdir/font/macnames.c diff --git a/Build/source/texk/web2c/luatexdir/commands.h b/Build/source/texk/web2c/luatexdir/commands.h index 2ee3b8f28b4..567ded7b46e 100644 --- a/Build/source/texk/web2c/luatexdir/commands.h +++ b/Build/source/texk/web2c/luatexdir/commands.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: commands.h 2094 2009-03-23 14:13:54Z taco $ */ +/* $Id: commands.h 2280 2009-04-14 09:49:01Z taco $ */ typedef enum { @@ -98,6 +98,8 @@ typedef enum { 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} */ @@ -233,6 +235,7 @@ typedef enum { 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 */ diff --git a/Build/source/texk/web2c/luatexdir/font/dofont.c b/Build/source/texk/web2c/luatexdir/font/dofont.c index 14d785b8a9f..7033dc7be0c 100644 --- a/Build/source/texk/web2c/luatexdir/font/dofont.c +++ b/Build/source/texk/web2c/luatexdir/font/dofont.c @@ -22,7 +22,7 @@ #include "luatex-api.h" static const char _svn_version[] = - "$Id: dofont.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/dofont.c $"; + "$Id: dofont.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/dofont.c $"; #define TIMERS 0 @@ -121,7 +121,7 @@ do_define_font(integer f, char *cnom, char *caire, scaled s, return 0; } } - } else { + } else if (callback_id==0) { res = read_tfm_info(f, cnom, caire, s); if (res) { set_hyphen_char(f, get_default_hyphen_char()); diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.c b/Build/source/texk/web2c/luatexdir/font/luafont.c index d9fd6273b06..0de7725c8dd 100644 --- a/Build/source/texk/web2c/luatexdir/font/luafont.c +++ b/Build/source/texk/web2c/luatexdir/font/luafont.c @@ -23,7 +23,7 @@ #include "nodes.h" static const char _svn_version[] = - "$Id: luafont.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/luafont.c $"; + "$Id: luafont.c 2293 2009-04-15 16:55:18Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/luafont.c $"; #define noVERBOSE @@ -97,6 +97,7 @@ const char *MATH_param_names[] = { "RadicalKernAfterDegree", "RadicalDegreeBottomRaisePercent", "MinConnectorOverlap", + "SubscriptShiftDownWithSuperscript", NULL, }; @@ -108,10 +109,31 @@ static void dump_intfield(lua_State * L, char *n, int c) } +void dump_math_kerns (lua_State *L, charinfo *co, int l, int id) { + int i; + for (i=0; i<l;i++) { + lua_newtable(L); + if (id==top_left_kern) { + dump_intfield(L, "height", co->top_left_math_kern_array[(2*i)]); + dump_intfield(L, "kern", co->top_left_math_kern_array[(2*i)+1]); + } else if (id==top_right_kern) { + dump_intfield(L, "height", co->top_right_math_kern_array[(2*i)]); + dump_intfield(L, "kern", co->top_right_math_kern_array[(2*i)+1]); + } else if (id==bottom_right_kern) { + dump_intfield(L, "height", co->bottom_right_math_kern_array[(2*i)]); + dump_intfield(L, "kern", co->bottom_right_math_kern_array[(2*i)+1]); + } else if (id==bottom_left_kern) { + dump_intfield(L, "height", co->bottom_left_math_kern_array[(2*i)]); + dump_intfield(L, "kern", co->bottom_left_math_kern_array[(2*i)+1]); + } + lua_rawseti(L,-2, (i+1)); + } +} + void font_char_to_lua(lua_State * L, internalfontnumber f, charinfo * co) { - int i; + int i, j; liginfo *l; kerninfo *ki; @@ -262,6 +284,43 @@ void font_char_to_lua(lua_State * L, internalfontnumber f, charinfo * co) } lua_rawset(L, -3); } + + lua_newtable(L); + + i = get_charinfo_math_kerns(co, top_right_kern); + j = 0; + if (i>0) { + j++; + lua_newtable(L); + dump_math_kerns(L, co, i, top_right_kern); + lua_setfield(L, -2, "top_right"); + } + i = get_charinfo_math_kerns(co, top_left_kern); + if (i>0) { + j++; + lua_newtable(L); + dump_math_kerns(L, co, i, top_left_kern); + lua_setfield(L, -2, "top_left"); + } + i = get_charinfo_math_kerns(co, bottom_right_kern); + if (i>0) { + j++; + lua_newtable(L); + dump_math_kerns(L, co, i, bottom_right_kern); + lua_setfield(L, -2, "bottom_right"); + } + i = get_charinfo_math_kerns(co, bottom_left_kern); + if (i>0) { + j++; + lua_newtable(L); + dump_math_kerns(L, co, i, bottom_left_kern); + lua_setfield(L, -2, "bottom_left"); + } + if (j>0) + lua_setfield(L, -2, "mathkern"); + else + lua_pop(L,1); + } static void write_lua_parameters(lua_State * L, int f) @@ -656,6 +715,11 @@ make_luaS_index(start); make_luaS_index(end); make_luaS_index(advance); make_luaS_index(glyph); +make_luaS_index(extensible); +make_luaS_index(horiz_variants); +make_luaS_index(vert_variants); +make_luaS_index(mathkern); +make_luaS_index(commands); void init_font_string_pointers(lua_State * L) { @@ -709,6 +773,13 @@ void init_font_string_pointers(lua_State * L) init_luaS_index(end); init_luaS_index(advance); init_luaS_index(glyph); + + init_luaS_index(extensible); + init_luaS_index(horiz_variants); + init_luaS_index(vert_variants); + init_luaS_index(mathkern); + init_luaS_index(commands); + } static int count_char_packet_bytes(lua_State * L) @@ -1045,7 +1116,40 @@ static void read_lua_math_parameters(lua_State * L, int f) lua_pop(L, 1); } +#define MIN_INF -0x7FFFFFFF + +static void +store_math_kerns (lua_State * L, charinfo *co, int id ) +{ + int l, k; + scaled ht, krn; + if (lua_istable(L, -1) && ((k=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); + } else { + ht = MIN_INF; + } + lua_pop(L,1); + lua_getfield(L, -1, "kern"); + if (lua_isnumber(L,-1)) { + krn = (scaled)lua_tonumber(L,-1); + } else { + krn = MIN_INF; + } + lua_pop(L,1); + if (krn>MIN_INF && ht>MIN_INF) + add_charinfo_math_kern(co,id,ht,krn); + } + lua_pop(L,1); + } + } +} + void font_char_from_lua(lua_State * L, internal_font_number f, integer i, integer * l_fonts) @@ -1094,7 +1198,9 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i, set_charinfo_tag(co, list_tag); set_charinfo_remainder(co, k); } - lua_getfield(L, -1, "extensible"); + + 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); @@ -1112,7 +1218,8 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i, } lua_pop(L, 1); - lua_getfield(L, -1, "horiz_variants"); + 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; @@ -1138,8 +1245,8 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i, } lua_pop(L, 1); - - lua_getfield(L, -1, "vert_variants"); + 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; @@ -1165,6 +1272,32 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i, } 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_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); + nk = count_hash_items(L, luaS_index(kerns)); if (nk > 0) { ckerns = xcalloc((nk + 1), sizeof(kerninfo)); @@ -1214,7 +1347,8 @@ font_char_from_lua(lua_State * L, internal_font_number f, integer i, } /* packet commands */ - lua_getfield(L, -1, "commands"); + lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_commands_index); + lua_rawget(L, -2); if (lua_istable(L, -1)) { lua_pushnil(L); /* first key */ if (lua_next(L, -2) != 0) { @@ -1583,6 +1717,24 @@ static void nesting_prepend(halfword nest, halfword newn) } +static void nesting_prepend_list(halfword nest, halfword newn) +{ + halfword head = vlink(nest); + assert(alink(nest) == null); + assert(alink(newn) == null); + couple_nodes(nest, newn); + if (head == null) { + assert(tlink(nest) == null); + tlink(nest) = tail_of_list(newn); + } else { + halfword tail = tail_of_list(newn); + assert(alink(head) == nest); + assert(tail_of_list(head) == tlink(nest)); + couple_nodes(tail, head); + } +} + + static int test_ligature(liginfo * lig, halfword left, halfword right) { if (type(left) != glyph_node) @@ -1702,6 +1854,18 @@ static halfword handle_lig_nest(halfword root, halfword cur) } +static void print_disc(halfword cur) +{ + halfword n; + fprintf (stdout, "cur(%d,%d) {", cur, subtype(cur)); + n = vlink_pre_break(cur); show_node_list(n); + fprintf (stdout, "}{"); + n = vlink_post_break(cur); show_node_list(n); + fprintf (stdout, "}{"); + n = vlink_no_break(cur); show_node_list(n); + fprintf (stdout, "}\n"); +} + static halfword handle_lig_word(halfword cur) { halfword right = null; @@ -1819,88 +1983,75 @@ static halfword handle_lig_word(halfword cur) } /* A discretionary followed by ... */ } else if (type(cur) == disc_node) { + assert_disc(cur); /* If {?}{x}{?} or {?}{?}{y} then ... */ if (vlink_no_break(cur) != null || vlink_post_break(cur) != null) { halfword fwd; - halfword lists[511]; /* max 8 levels */ - - int i, max_depth = 0; - lists[max_depth++] = - handle_lig_nest(post_break(cur), vlink_post_break(cur)); - lists[max_depth++] = - handle_lig_nest(no_break(cur), vlink_no_break(cur)); - while (1) { - if ((fwd = vlink(cur)) == null) - return cur; - if (type(fwd) == glyph_node) { - halfword next; - for (i = 0; i < max_depth; i++) { - liginfo lig; - halfword tail = tlink(lists[i]); - if (tail != null && test_ligature(&lig, tail, fwd)) - goto add_glyph_to_all; - } - /* if we get here, nothing had a ligature, so we stop */ + liginfo lig; + if (vlink_post_break(cur)!=null) + handle_lig_nest(post_break(cur),vlink_post_break(cur)); + if (vlink_no_break(cur)!=null) + handle_lig_nest(no_break(cur),vlink_no_break(cur)); + while ((fwd = vlink(cur)) != null ) { + if (type(fwd) != glyph_node) break; + halfword nob = tlink_no_break(cur); + halfword pst = tlink_post_break(cur); + if ((nob == null || !test_ligature(&lig, nob, fwd)) && + (pst == null || !test_ligature(&lig, pst, fwd)) ) break; - add_glyph_to_all: - for (i = 0; i < max_depth; i++) { - halfword copy = copy_node(fwd); - halfword tail = tlink(lists[i]); - nesting_append(lists[i], copy); - if (tail == null) - continue; /* first character - never a ligature */ - handle_lig_nest(lists[i], tail); + nesting_append(no_break(cur),copy_node(fwd)); + handle_lig_nest(no_break(cur),nob); + halfword next = vlink(fwd); + uncouple_node(fwd); + try_couple_nodes(cur, next); + nesting_append(post_break(cur),fwd); + handle_lig_nest(post_break(cur),pst); + } + if (fwd != null && type(fwd) == disc_node) { + halfword next = vlink(fwd); + if (vlink_no_break(fwd)==null && + vlink_post_break(fwd)==null && + next != null && + type(next) == glyph_node && + ((tlink_post_break(cur)!= null && + 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' + */ + halfword last = vlink(next); + uncouple_node(next); + try_couple_nodes(fwd, last); + /* {a-}{b}{AB} {-}{c}{} */ + nesting_append(post_break(fwd),copy_node(next)); + /* {a-}{b}{AB} {-}{c}{-} */ + if (vlink_no_break(cur)!=null) { + nesting_prepend(no_break(fwd),copy_node(vlink_pre_break(fwd))); } - next = vlink(fwd); - uncouple_node(fwd); - try_couple_nodes(cur, next); - flush_node(fwd); - } else if (type(fwd) == disc_node) { - halfword next; - /* MAGIC WARNING - * A disc followed by a disc can have different kernings - * depending on which path is choosen, and it is impossible to - * store the possible kernings: fe {}{A}{W} {V}{}{A} - * So we _always_ add discs so only a simple path remains. */ - int m = max_depth; /* as max_depth changes in this loop */ - for (i = 0; i < m; i++) { - halfword copy = copy_node(fwd); - halfword tail = tlink(lists[i]); - if (tail != null) { - halfword prev = alink(tail); - assert(alink(tail) != null); - uncouple_node(tail); - vlink(prev) = null; - if (prev == lists[i]) { - tlink(prev) = null; - } else { - tlink(lists[i]) = prev; - } - nesting_prepend(pre_break(copy), tail); - nesting_prepend(no_break(copy), - copy_node(tail)); - } - nesting_append(lists[i], copy); - handle_lig_nest(pre_break(copy), - vlink_pre_break(copy)); - assert(max_depth < 256); - lists[max_depth++] = - handle_lig_nest(no_break(copy), - vlink_no_break(copy)); - lists[i] = - handle_lig_nest(post_break(copy), - vlink_post_break(copy)); + /* {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-} */ + if (vlink_no_break(cur)!=null) { + nesting_prepend_list(no_break(fwd),copy_node_list(vlink_no_break(cur))); } - next = vlink(fwd); - uncouple_node(fwd); - try_couple_nodes(cur, next); - flush_node(fwd); - } else { - return cur; + /* {a-}{b}{ABC} {b-}{c}{AB-} */ + halfword 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-} */ + tail = tlink_post_break(cur); + nesting_append(post_break(cur),next); + handle_lig_nest(post_break(cur),tail); + /* and set the subtypes */ + subtype(cur) = init_disc; + subtype(fwd) = select_disc; } } } + } 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? */ @@ -2131,7 +2282,7 @@ halfword new_ligkern(halfword head, halfword tail) tail = run_lua_ligkern_callback(head, tail, callback_id); if (tail == null) tail = tail_of_list(head); - } else { + } else if (callback_id == 0) { tail = handle_ligaturing(head, tail); } @@ -2140,7 +2291,7 @@ halfword new_ligkern(halfword head, halfword tail) tail = run_lua_ligkern_callback(head, tail, callback_id); if (tail == null) tail = tail_of_list(head); - } else { + } else if (callback_id == 0) { halfword nest = new_node(nesting_node, 1); halfword cur = vlink(head); halfword aft = vlink(tail); diff --git a/Build/source/texk/web2c/luatexdir/font/luatexfont.h b/Build/source/texk/web2c/luatexdir/font/luatexfont.h index ceee8bf69f3..c3a9e8aeada 100644 --- a/Build/source/texk/web2c/luatexdir/font/luatexfont.h +++ b/Build/source/texk/web2c/luatexdir/font/luatexfont.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: luatexfont.h 1783 2009-01-18 12:51:01Z oneiros $ */ +/* $Id: luatexfont.h 2271 2009-04-12 23:42:21Z oneiros $ */ #ifndef LUATEXFONT_H # define LUATEXFONT_H 1 diff --git a/Build/source/texk/web2c/luatexdir/font/macnames.c b/Build/source/texk/web2c/luatexdir/font/macnames.c index ae7720cc8dd..367c1d231c3 100644 --- a/Build/source/texk/web2c/luatexdir/font/macnames.c +++ b/Build/source/texk/web2c/luatexdir/font/macnames.c @@ -19,7 +19,7 @@ with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ static const char __svn_version[] = - "$Id: macnames.c 1223 2008-05-02 13:39:55Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/macnames.c $"; + "$Id: macnames.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/macnames.c $"; const char notdef[] = ".notdef"; diff --git a/Build/source/texk/web2c/luatexdir/font/mapfile.c b/Build/source/texk/web2c/luatexdir/font/mapfile.c index c97cdf59782..551ff59e49e 100644 --- a/Build/source/texk/web2c/luatexdir/font/mapfile.c +++ b/Build/source/texk/web2c/luatexdir/font/mapfile.c @@ -26,7 +26,8 @@ #include "luatex-api.h" static const char _svn_version[] = - "$Id: mapfile.c 1870 2009-02-19 10:03:13Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/mapfile.c $"; + "$Id: mapfile.c 2271 2009-04-12 23:42:21Z oneiros $ " + "$URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/mapfile.c $"; #define FM_BUF_SIZE 1024 diff --git a/Build/source/texk/web2c/luatexdir/font/mapfile.h b/Build/source/texk/web2c/luatexdir/font/mapfile.h new file mode 100644 index 00000000000..e07c70047ec --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/mapfile.h @@ -0,0 +1,66 @@ +/* mapfile.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: mapfile.h 2271 2009-04-12 23:42:21Z oneiros $ */ + +#ifndef MAPFILE_H +# define MAPFILE_H +/**********************************************************************/ + +typedef struct { + /* parameters scanned from the map file: */ + 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 */ + char *encname; /* encoding file name */ + char *ff_name; /* font file name */ + unsigned short type; /* various flags */ + short pid; /* Pid for truetype fonts */ + 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 { + char *ff_name; /* base name of font file */ + char *ff_path; /* full path to font file */ +} ff_entry; + +/**********************************************************************/ + +fm_entry *lookup_fontmap(char *); +boolean hasfmentry(internalfontnumber); +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); +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); + +/**********************************************************************/ +#endif diff --git a/Build/source/texk/web2c/luatexdir/font/pkin.c b/Build/source/texk/web2c/luatexdir/font/pkin.c index 99f64f29c11..46118e17505 100644 --- a/Build/source/texk/web2c/luatexdir/font/pkin.c +++ b/Build/source/texk/web2c/luatexdir/font/pkin.c @@ -45,7 +45,7 @@ #include "luatexfont.h" static const char _svn_version[] = - "$Id: pkin.c 1712 2009-01-02 10:54:55Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/pkin.c $"; + "$Id: pkin.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/pkin.c $"; /* * Now we have some routines to get stuff from the pk file. pkbyte returns diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.c b/Build/source/texk/web2c/luatexdir/font/sfnt.c index b705ef7240b..da3eacf76f4 100644 --- a/Build/source/texk/web2c/luatexdir/font/sfnt.c +++ b/Build/source/texk/web2c/luatexdir/font/sfnt.c @@ -40,7 +40,7 @@ #include "sfnt.h" static const char _svn_version[] = - "$Id: sfnt.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/sfnt.c $"; + "$Id: sfnt.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/sfnt.c $"; #ifdef XETEX UNSIGNED_BYTE ft_unsigned_byte(sfnt * f) diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.h b/Build/source/texk/web2c/luatexdir/font/sfnt.h index 87b373730be..5d9bd2c973f 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 1223 2008-05-02 13:39:55Z oneiros $ */ +/* $Id: sfnt.h 2271 2009-04-12 23:42:21Z oneiros $ */ #ifndef _SFNT_H_ # define _SFNT_H_ diff --git a/Build/source/texk/web2c/luatexdir/font/subfont.c b/Build/source/texk/web2c/luatexdir/font/subfont.c index fecd5ed7857..33620092321 100644 --- a/Build/source/texk/web2c/luatexdir/font/subfont.c +++ b/Build/source/texk/web2c/luatexdir/font/subfont.c @@ -22,7 +22,7 @@ #include <string.h> static const char _svn_version[] = - "$Id: subfont.c 1783 2009-01-18 12:51:01Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/subfont.c $"; + "$Id: subfont.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/subfont.c $"; static struct avl_table *sfd_tree = NULL; diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.c b/Build/source/texk/web2c/luatexdir/font/texfont.c index 1daf6a5b56b..7eac52c7d06 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.c +++ b/Build/source/texk/web2c/luatexdir/font/texfont.c @@ -35,7 +35,7 @@ #include "luatex-api.h" static const char _svn_version[] = - "$Id: texfont.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/texfont.c $"; + "$Id: texfont.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/texfont.c $"; #define proper_char_index(c) (c<=font_ec(f) && c>=font_bc(f)) #define dxfree(a,b) { xfree(a); a = b ; } @@ -129,6 +129,7 @@ integer new_font(void) ci = xcalloc(1, sizeof(charinfo)); set_charinfo_name(ci, xstrdup(".notdef")); font_tables[id]->charinfo = ci; + font_tables[id]->charinfo_size = 1; font_tables[id]->charinfo_cache = NULL; return id; @@ -147,13 +148,15 @@ charinfo *get_charinfo(internal_font_number f, integer c) if (proper_char_index(c)) { glyph = get_sa_item(Characters(f), c); if (!glyph) { - /* this could be optimized using controlled growth */ - font_bytes += sizeof(charinfo); + glyph = ++font_tables[f]->charinfo_count; - do_realloc(font_tables[f]->charinfo, (glyph + 1), charinfo); - memset(&(font_tables[f]->charinfo[glyph]), 0, sizeof(charinfo)); + if (glyph>=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; + } font_tables[f]->charinfo[glyph].ef = 1000; /* init */ - font_tables[f]->charinfo_size = glyph; set_sa_item(font_tables[f]->characters, c, glyph, 1); /* 1= global */ } return &(font_tables[f]->charinfo[glyph]); @@ -256,6 +259,53 @@ 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); + 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)]; + co->top_left_math_kern_array[(2 * k) + 1] = + ci->top_left_math_kern_array[(2 * k) + 1]; + } + } + 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); + 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)]; + co->top_right_math_kern_array[(2 * k) + 1] = + ci->top_right_math_kern_array[(2 * k) + 1]; + } + } + 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); + 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)]; + co->bottom_right_math_kern_array[(2 * k) + 1] = + ci->bottom_right_math_kern_array[(2 * k) + 1]; + } + } + 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); + 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)]; + co->bottom_left_math_kern_array[(2 * k) + 1] = + ci->bottom_left_math_kern_array[(2 * k) + 1]; + } + } + + return co; } @@ -365,7 +415,7 @@ void dump_variant(extinfo * ext) extinfo *undump_variant(void) { - int x; + integer x; extinfo *ext; undump_int(x); if (x == 0) @@ -570,6 +620,136 @@ void set_charinfo_hor_variants(charinfo * ci, extinfo * ext) } +int get_charinfo_math_kerns(charinfo * ci, int id) +{ + + 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) { + k = ci->bottom_left_math_kerns; + } else if (id == bottom_right_kern) { + k = ci->bottom_right_math_kerns; + } else if (id == top_right_kern) { + k = ci->top_right_math_kerns; + } else { + tconfusion("get_charinfo_math_kerns"); + } + return k; +} + +void add_charinfo_math_kern(charinfo * ci, int id, scaled ht, scaled krn) +{ + int k; + if (id == top_left_kern) { + k = ci->top_left_math_kerns; + do_realloc(ci->top_left_math_kern_array, ((k + 1) * 2), sizeof(scaled)); + ci->top_left_math_kern_array[(2 * (k))] = ht; + ci->top_left_math_kern_array[((2 * (k)) + 1)] = krn; + ci->top_left_math_kerns++; + } else if (id == bottom_left_kern) { + k = ci->bottom_left_math_kerns; + do_realloc(ci->bottom_left_math_kern_array, ((k + 1) * 2), + sizeof(scaled)); + ci->bottom_left_math_kern_array[(2 * (k))] = ht; + ci->bottom_left_math_kern_array[(2 * (k)) + 1] = krn; + ci->bottom_left_math_kerns++; + } else if (id == bottom_right_kern) { + k = ci->bottom_right_math_kerns; + do_realloc(ci->bottom_right_math_kern_array, ((k + 1) * 2), + sizeof(scaled)); + ci->bottom_right_math_kern_array[(2 * (k))] = ht; + ci->bottom_right_math_kern_array[(2 * (k)) + 1] = krn; + ci->bottom_right_math_kerns++; + } else if (id == top_right_kern) { + k = ci->top_right_math_kerns; + do_realloc(ci->top_right_math_kern_array, ((k + 1) * 2), + sizeof(scaled)); + ci->top_right_math_kern_array[(2 * (k))] = ht; + ci->top_right_math_kern_array[(2 * (k)) + 1] = krn; + ci->top_right_math_kerns++; + } else { + tconfusion("add_charinfo_math_kern"); + } +} + + +static void dump_math_kerns(charinfo * ci) +{ + integer k, l; + l = ci->top_left_math_kerns; + dump_int(l); + for (k = 0; k < l; k++) { + dump_int(ci->top_left_math_kern_array[(2 * k)]); + dump_int(ci->top_left_math_kern_array[(2 * k) + 1]); + } + l = ci->bottom_left_math_kerns; + dump_int(l); + for (k = 0; k < l; k++) { + dump_int(ci->bottom_left_math_kern_array[(2 * k)]); + dump_int(ci->bottom_left_math_kern_array[(2 * k) + 1]); + } + l = ci->bottom_right_math_kerns; + dump_int(l); + for (k = 0; k < l; k++) { + dump_int(ci->bottom_right_math_kern_array[(2 * k)]); + dump_int(ci->bottom_right_math_kern_array[(2 * k) + 1]); + } + l = ci->top_right_math_kerns; + dump_int(l); + for (k = 0; k < l; k++) { + dump_int(ci->bottom_left_math_kern_array[(2 * k)]); + dump_int(ci->bottom_left_math_kern_array[(2 * k) + 1]); + } +} + +static void undump_math_kerns(charinfo * ci) +{ + int k; + integer x; + undump_int(x); + ci->top_left_math_kerns = (int) x; + if (x > 0) + ci->top_left_math_kern_array = xmalloc(2 * 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; + undump_int(x); + ci->top_left_math_kern_array[(2 * k) + 1] = (scaled) x; + } + undump_int(x); + ci->bottom_left_math_kerns = (int) x; + if (x > 0) + ci->bottom_left_math_kern_array = xmalloc(2 * 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; + undump_int(x); + ci->bottom_left_math_kern_array[(2 * k) + 1] = (scaled) x; + } + undump_int(x); + ci->bottom_right_math_kerns = (int) x; + if (x > 0) + ci->bottom_right_math_kern_array = xmalloc(2 * 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; + undump_int(x); + ci->bottom_right_math_kern_array[(2 * k) + 1] = (scaled) x; + } + undump_int(x); + ci->top_right_math_kerns = (int) x; + if (x > 0) + ci->top_right_math_kern_array = xmalloc(2 * 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; + undump_int(x); + ci->top_right_math_kern_array[(2 * k) + 1] = (scaled) x; + } +} + + /* 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 @@ -1041,7 +1221,9 @@ boolean font_shareable(internal_font_number f, internal_font_number k) } } else { if ((font_filename(k) != NULL && font_filename(f) != NULL && - strcmp(font_filename(k), font_filename(f)) == 0) + 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)))) { @@ -1244,7 +1426,7 @@ scaled get_kern(internal_font_number f, integer lc, integer rc) void dump_charinfo(int f, int c) { charinfo *co; - int x; + integer x; liginfo *lig; kerninfo *kern; dump_int(c); @@ -1301,15 +1483,53 @@ void dump_charinfo(int f, int c) dump_charinfo_variants(get_charinfo_vert_variants(co)); dump_charinfo_variants(get_charinfo_hor_variants(co)); } + dump_math_kerns(co); +} + +void dump_font_entry(texfont * f) +{ + 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); + 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_tounicode); + dump_int(f->_font_type); + dump_int(f->_font_format); + dump_int(f->_font_embedding); + dump_int(f->_font_bc); + dump_int(f->_hyphen_char); + dump_int(f->_skew_char); + dump_int(f->_font_natural_dir); + dump_int(f->_font_params); + 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) { - int i, x; + integer i, x; set_font_used(f, 0); font_tables[f]->charinfo_cache = NULL; - dump_things(*(font_tables[f]), 1); + dump_font_entry(font_tables[f]); dump_string(font_name(f)); dump_string(font_area(f)); dump_string(font_filename(f)); @@ -1346,7 +1566,7 @@ void dump_font(int f) int undump_charinfo(int f) { charinfo *co; - int x, i; + integer x, i; char *s = NULL; liginfo *lig = NULL; kerninfo *kern = NULL; @@ -1427,6 +1647,7 @@ int undump_charinfo(int f) set_charinfo_vert_variants(co, undump_charinfo_variants()); set_charinfo_hor_variants(co, undump_charinfo_variants()); } + undump_math_kerns(co); return i; } @@ -1437,25 +1658,59 @@ int undump_charinfo(int f) a(f,s); } +void undump_font_entry(texfont * f) +{ + integer 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_cache_id = x; + undump_int(x); f->_font_encodingbytes = 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_type = x; + undump_int(x); f->_font_format = x; + undump_int(x); f->_font_embedding = x; + undump_int(x); f->_font_bc = x; + undump_int(x); f->_hyphen_char = x; + undump_int(x); f->_skew_char = x; + undump_int(x); f->_font_natural_dir = x; + undump_int(x); f->_font_params = x; + 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* */ +} + + + void undump_font(int f) { - int x, i; + integer x, i; texfont *tt; charinfo *ci; char *s; grow_font_table(f); - font_tables[f] = NULL; - font_bytes += sizeof(texfont); tt = xmalloc(sizeof(texfont)); - undump_things(*tt, 1); - /* these |char *| need resetting */ - tt->_font_name = NULL; - tt->_font_area = NULL; - tt->_font_filename = NULL; - tt->_font_fullname = NULL; - tt->_font_encodingname = NULL; - tt->_font_cidregistry = NULL; - tt->_font_cidordering = NULL; + memset(tt, 0, sizeof(texfont)); + font_bytes += sizeof(texfont); + undump_font_entry(tt); font_tables[f] = tt; undump_font_string(set_font_name); @@ -1476,23 +1731,16 @@ void undump_font(int f) font_bytes += i; math_param_base(f) = xmalloc(i); undump_things(*math_param_base(f), (font_math_params(f) + 1)); - } else { - math_param_base(f) = NULL; } - font_tables[f]->_left_boundary = NULL; undump_int(x); if (x) { i = undump_charinfo(f); - } - /* left boundary */ - font_tables[f]->_right_boundary = NULL; + } /* left boundary */ undump_int(x); if (x) { i = undump_charinfo(f); - } - - /* right boundary */ + } /* right boundary */ font_tables[f]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ ci = xcalloc(1, sizeof(charinfo)); set_charinfo_name(ci, xstrdup(".notdef")); diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.h b/Build/source/texk/web2c/luatexdir/font/texfont.h index f91d00dc2b1..8723364a96c 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.h +++ b/Build/source/texk/web2c/luatexdir/font/texfont.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: texfont.h 2057 2009-03-19 15:45:47Z taco $ */ +/* $Id: texfont.h 2271 2009-04-12 23:42:21Z oneiros $ */ /* 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 @@ -75,6 +75,14 @@ typedef struct charinfo { char *tounicode; /* unicode equivalent */ extinfo *hor_variants; /* horizontal variants */ extinfo *vert_variants; /* vertical variants */ + int top_left_math_kerns; + int top_right_math_kerns; + int bottom_right_math_kerns; + int bottom_left_math_kerns; + scaled *top_left_math_kern_array; + scaled *top_right_math_kern_array; + scaled *bottom_right_math_kern_array; + scaled *bottom_left_math_kern_array; } charinfo; @@ -394,11 +402,17 @@ typedef enum { /* now for characters */ +typedef enum { + top_right_kern = 1, + bottom_right_kern = 2, + bottom_left_kern = 3, + 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 void set_charinfo_width(charinfo * ci, scaled val); extern void set_charinfo_height(charinfo * ci, scaled val); extern void set_charinfo_depth(charinfo * ci, scaled val); @@ -419,6 +433,9 @@ extern void set_charinfo_ef(charinfo * ci, scaled val); extern void set_charinfo_lp(charinfo * ci, scaled val); extern void set_charinfo_rp(charinfo * ci, scaled val); +extern void add_charinfo_math_kern(charinfo *ci, int type, scaled ht, scaled krn); +extern int get_charinfo_math_kerns(charinfo * ci, int id); + # define set_char_used(f,a,b) do { \ if (char_exists(f,a)) \ set_charinfo_used(char_info(f,a),b); \ diff --git a/Build/source/texk/web2c/luatexdir/font/tfmofm.c b/Build/source/texk/web2c/luatexdir/font/tfmofm.c index 36364ba6d44..2e373e71081 100644 --- a/Build/source/texk/web2c/luatexdir/font/tfmofm.c +++ b/Build/source/texk/web2c/luatexdir/font/tfmofm.c @@ -22,7 +22,7 @@ #include "luatexfont.h" static const char _svn_version[] = - "$Id: tfmofm.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tfmofm.c $"; + "$Id: tfmofm.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/tfmofm.c $"; /* Here are some macros that help process ligatures and kerns */ diff --git a/Build/source/texk/web2c/luatexdir/font/tounicode.c b/Build/source/texk/web2c/luatexdir/font/tounicode.c index 29ee8c9bd0b..31f07c9a253 100644 --- a/Build/source/texk/web2c/luatexdir/font/tounicode.c +++ b/Build/source/texk/web2c/luatexdir/font/tounicode.c @@ -20,7 +20,7 @@ #include "ptexlib.h" static const char _svn_version[] = - "$Id: tounicode.c 2029 2009-03-14 19:10:25Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tounicode.c $"; + "$Id: tounicode.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/tounicode.c $"; #define isXdigit(c) (isdigit(c) || ('A' <= (c) && (c) <= 'F')) #define UNI_UNDEF -1 diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c index b024897f82d..bb7a344e049 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.c +++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c @@ -32,7 +32,7 @@ #include "writettf.h" static const char _svn_version[] = - "$Id: tt_glyf.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tt_glyf.c $"; + "$Id: tt_glyf.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/tt_glyf.c $"; #define NUM_GLYPH_LIMIT 65534 #define TABLE_DATA_ALLOC_SIZE 40960 diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.h b/Build/source/texk/web2c/luatexdir/font/tt_glyf.h index 0ca8465c33d..1a82f936af9 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.h +++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.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: tt_glyf.h 1223 2008-05-02 13:39:55Z oneiros $ */ +/* $Id: tt_glyf.h 2271 2009-04-12 23:42:21Z oneiros $ */ #ifndef _TT_GLYF_H_ # define _TT_GLYF_H_ diff --git a/Build/source/texk/web2c/luatexdir/font/tt_table.c b/Build/source/texk/web2c/luatexdir/font/tt_table.c index 3df19723c2b..908a85cfdb9 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_table.c +++ b/Build/source/texk/web2c/luatexdir/font/tt_table.c @@ -34,7 +34,7 @@ #include "tt_table.h" static const char _svn_version[] = - "$Id: tt_table.c 1588 2008-11-28 13:18:54Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/tt_table.c $"; + "$Id: tt_table.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/tt_table.c $"; /* tables contains information refered by other tables diff --git a/Build/source/texk/web2c/luatexdir/font/tt_table.h b/Build/source/texk/web2c/luatexdir/font/tt_table.h index 5dcd17d5b66..7fae8515646 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_table.h +++ b/Build/source/texk/web2c/luatexdir/font/tt_table.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: tt_table.h 1223 2008-05-02 13:39:55Z oneiros $ */ +/* $Id: tt_table.h 2271 2009-04-12 23:42:21Z oneiros $ */ #ifndef _TT_TABLE_H_ # define _TT_TABLE_H_ diff --git a/Build/source/texk/web2c/luatexdir/font/vfovf.c b/Build/source/texk/web2c/luatexdir/font/vfovf.c index fefcd16b756..b52596f68e3 100644 --- a/Build/source/texk/web2c/luatexdir/font/vfovf.c +++ b/Build/source/texk/web2c/luatexdir/font/vfovf.c @@ -23,7 +23,7 @@ #include "luatexfont.h" static const char _svn_version[] = - "$Id: vfovf.c 2057 2009-03-19 15:45:47Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/vfovf.c $"; + "$Id: vfovf.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/vfovf.c $"; /* this is a hack! */ #define font_max 5000 diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.c b/Build/source/texk/web2c/luatexdir/font/vfpacket.c index e4fa429b4ef..f8f4bad02f7 100644 --- a/Build/source/texk/web2c/luatexdir/font/vfpacket.c +++ b/Build/source/texk/web2c/luatexdir/font/vfpacket.c @@ -21,7 +21,7 @@ #include "ptexlib.h" static const char _svn_version[] = - "$Id: vfpacket.c 2048 2009-03-17 22:04:00Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/vfpacket.c $"; + "$Id: vfpacket.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/vfpacket.c $"; /* The |do_vf_packet| procedure is called in order to interpret the diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.c b/Build/source/texk/web2c/luatexdir/font/writecff.c index 274c4ad1567..d2b038785b0 100644 --- a/Build/source/texk/web2c/luatexdir/font/writecff.c +++ b/Build/source/texk/web2c/luatexdir/font/writecff.c @@ -22,7 +22,7 @@ #include "writecff.h" static const char _svn_version[] = - "$Id: writecff.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writecff.c $"; + "$Id: writecff.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writecff.c $"; #define get_offset(s,n) get_unsigned(s, (n)) #define get_card8(a) a->stream[a->offset++] diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.h b/Build/source/texk/web2c/luatexdir/font/writecff.h index 2d92a8723ae..8f3fdac675a 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 1518 2008-09-30 08:18:10Z taco $ */ +/* $Id: writecff.h 2271 2009-04-12 23:42:21Z oneiros $ */ #ifndef _CFF_LIMITS_H_ # define _CFF_LIMITS_H_ diff --git a/Build/source/texk/web2c/luatexdir/font/writeenc.c b/Build/source/texk/web2c/luatexdir/font/writeenc.c index 648992ba6cd..575d5b61c3d 100644 --- a/Build/source/texk/web2c/luatexdir/font/writeenc.c +++ b/Build/source/texk/web2c/luatexdir/font/writeenc.c @@ -21,7 +21,7 @@ #include "ptexlib.h" static const char _svn_version[] = - "$Id: writeenc.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writeenc.c $"; + "$Id: writeenc.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writeenc.c $"; /**********************************************************************/ /* All encoding entries go into AVL tree for fast search by name. */ diff --git a/Build/source/texk/web2c/luatexdir/font/writefont.c b/Build/source/texk/web2c/luatexdir/font/writefont.c index 5c6b2d905a0..b15b71489e8 100644 --- a/Build/source/texk/web2c/luatexdir/font/writefont.c +++ b/Build/source/texk/web2c/luatexdir/font/writefont.c @@ -22,7 +22,7 @@ #include "luatexfont.h" static const char _svn_version[] = - "$Id: writefont.c 2097 2009-03-23 22:45:03Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writefont.c $"; + "$Id: writefont.c 2274 2009-04-13 12:10:20Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writefont.c $"; void write_cid_fontdictionary(fo_entry * fo, internalfontnumber f); void create_cid_fontdictionary(fm_entry * fm, integer font_objnum, @@ -713,6 +713,21 @@ void create_fontdictionary(fm_entry * fm, integer font_objnum, /**********************************************************************/ +static int has_ttf_outlines(fm_entry *fm) +{ + FILE *f = fopen(fm->ff_name,"rb"); + if (f!=NULL) { + int ch1 = getc(f); + int ch2 = getc(f); + int ch3 = getc(f); + int ch4 = getc(f); + fclose (f); + if (ch1=='O' && ch2=='T' && ch3=='T' && ch4=='O') + return 0; + return 1; + } + return 0; +} void do_pdf_font(integer font_objnum, internalfontnumber f) { @@ -740,7 +755,11 @@ void do_pdf_font(integer font_objnum, internalfontnumber f) switch (font_format(f)) { case opentype_format: - set_opentype(fm); + if (has_ttf_outlines(fm)) { + set_truetype(fm); + } else { + set_opentype(fm); + } break; case truetype_format: set_truetype(fm); diff --git a/Build/source/texk/web2c/luatexdir/font/writet1.c b/Build/source/texk/web2c/luatexdir/font/writet1.c index 809ec3db014..46563a6fb76 100644 --- a/Build/source/texk/web2c/luatexdir/font/writet1.c +++ b/Build/source/texk/web2c/luatexdir/font/writet1.c @@ -25,7 +25,7 @@ #include "luatex-api.h" static const char _svn_version[] = - "$Id: writet1.c 2078 2009-03-22 00:17:18Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writet1.c $"; + "$Id: writet1.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/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 @@ -837,6 +837,8 @@ static void t1_scan_param(void) return; if (t1_prefix(lenIV)) { t1_lenIV = 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(); @@ -1224,10 +1226,44 @@ 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 */ +static void append_cs_return(cs_entry * ptr) +{ + unsigned short cr; + int i; + byte *p, *q, *data, *new_data; + assert(ptr != NULL && ptr->valid && ptr->used); + + /* decrypt the cs data to t1_buf_array, append CS_RETURN */ + p = (byte *) t1_buf_array; + data = ptr->data + 4; + cr = 4330; + for (i = 0; i < ptr->cslen; i++) + *p++ = cs_getchar(); + *p = CS_RETURN; + + /* encrypt the new cs data to new_data */ + new_data = xtalloc(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); + + /* update *ptr */ + xfree(ptr->data); + ptr->data = new_data; + ptr->len++; + ptr->cslen++; +} + 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; unsigned short cr; static integer lastargOtherSubr3 = 3; /* the argument of last call to @@ -1312,6 +1348,7 @@ static void cs_mark(const char *cs_name, int subr) "more arguments on stack (%i) than required (%i)", (int) (stack_ptr - cc_stack), (int) cc->nargs); } + last_cmd = b; switch (cc - cc_tab) { case CS_CALLSUBR: a1 = cc_get(-1); @@ -1352,6 +1389,12 @@ static void cs_mark(const char *cs_name, int subr) } } } + if (cs_name == NULL && last_cmd != CS_RETURN) { + pdftex_warn("last command in subr `%i' is not a RETURN; " + "I will add it now but please consider fixing the font", + (int) subr); + append_cs_return(ptr); + } return; cs_error: /* an error occured during parsing */ cc_clear(); @@ -1596,14 +1639,12 @@ static void t1_flush_cs(boolean is_subr) 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); - if (t1_lenIV >= 0) { - for (cs_len = 0, r = return_cs; cs_len < t1_lenIV; cs_len++, r++) - *r = cencrypt(0x00, &cr); - *r = cencrypt(CS_RETURN, &cr); - } else { - *return_cs = CS_RETURN; - } + for (cs_len = 0, r = return_cs; cs_len < t1_lenIV; cs_len++, r++) + *r = cencrypt(0x00, &cr); + *r = cencrypt(CS_RETURN, &cr); cs_len++; } diff --git a/Build/source/texk/web2c/luatexdir/font/writet3.c b/Build/source/texk/web2c/luatexdir/font/writet3.c index 4e349860d22..3d3f46fe2c6 100644 --- a/Build/source/texk/web2c/luatexdir/font/writet3.c +++ b/Build/source/texk/web2c/luatexdir/font/writet3.c @@ -25,7 +25,7 @@ #include "luatexfont.h" static const char _svn_version[] = - "$Id: writet3.c 1712 2009-01-02 10:54:55Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writet3.c $"; + "$Id: writet3.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writet3.c $"; #define T3_BUF_SIZE 1024 diff --git a/Build/source/texk/web2c/luatexdir/font/writettf.c b/Build/source/texk/web2c/luatexdir/font/writettf.c index fafd7c6eab4..6a989db833f 100644 --- a/Build/source/texk/web2c/luatexdir/font/writettf.c +++ b/Build/source/texk/web2c/luatexdir/font/writettf.c @@ -23,7 +23,7 @@ #include <string.h> static const char _svn_version[] = - "$Id: writettf.c 1592 2008-11-28 13:23:51Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writettf.c $"; + "$Id: writettf.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writettf.c $"; #define DEFAULT_NTABS 14 #define NEW_CMAP_SIZE 2 diff --git a/Build/source/texk/web2c/luatexdir/font/writettf.h b/Build/source/texk/web2c/luatexdir/font/writettf.h index 42a57a72c8f..b0db58ef2f1 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 1592 2008-11-28 13:23:51Z oneiros $ */ +/* $Id: writettf.h 2271 2009-04-12 23:42:21Z oneiros $ */ #ifndef WRITETTF_H # define WRITETTF_H 1 diff --git a/Build/source/texk/web2c/luatexdir/font/writetype0.c b/Build/source/texk/web2c/luatexdir/font/writetype0.c index 846314bedab..ea7c7822a2f 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype0.c +++ b/Build/source/texk/web2c/luatexdir/font/writetype0.c @@ -22,7 +22,7 @@ #include "writecff.h" static const char _svn_version[] = - "$Id: writetype0.c 1783 2009-01-18 12:51:01Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writetype0.c $"; + "$Id: writetype0.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writetype0.c $"; void writetype0(fd_entry * fd) { diff --git a/Build/source/texk/web2c/luatexdir/font/writetype2.c b/Build/source/texk/web2c/luatexdir/font/writetype2.c index ba98772b931..7eb84d8f5de 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype2.c +++ b/Build/source/texk/web2c/luatexdir/font/writetype2.c @@ -25,7 +25,7 @@ #include "tt_glyf.h" static const char _svn_version[] = - "$Id: writetype2.c 1783 2009-01-18 12:51:01Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/writetype2.c $"; + "$Id: writetype2.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writetype2.c $"; /* forward*/ void make_tt_subset(fd_entry * fd, unsigned char *buffer, integer buflen); diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.c b/Build/source/texk/web2c/luatexdir/image/epdf.c index 05ba93fdcf2..dd61a166738 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.c +++ b/Build/source/texk/web2c/luatexdir/image/epdf.c @@ -25,7 +25,7 @@ #include <string.h> static const char _svn_version[] = - "$Id: epdf.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/epdf.c $"; + "$Id: epdf.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/epdf.c $"; extern void epdf_check_mem(void); extern void register_fd_entry(fd_entry *); diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc index 663e37d073b..ff5c48b9e56 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc @@ -45,7 +45,7 @@ #include "epdf.h" static const char _svn_version[] = - "$Id: pdftoepdf.cc 1539 2008-10-06 09:52:07Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/pdftoepdf.cc $"; + "$Id: pdftoepdf.cc 2195 2009-03-31 14:09:50Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/pdftoepdf.cc $"; #define one_hundred_bp 6578176 /* 7227 * 65536 / 72 */ @@ -872,15 +872,15 @@ static void write_epdf1(image_dict * idict) // 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", epdf_lastGroupObjectNum); - pdf_puts("\n"); + 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"); + } } - } } // write the page Metadata if it's there if (page->getMetadata() != NULL) { diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.c b/Build/source/texk/web2c/luatexdir/image/writeimg.c index b105f507b42..c824bdbe079 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.c +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.c @@ -29,7 +29,7 @@ #include <../lua51/lauxlib.h> static const char _svn_version[] = - "$Id: writeimg.c 2019 2009-03-14 00:15:58Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writeimg.c $"; + "$Id: writeimg.c 2019 2009-03-14 00:15:58Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writeimg.c $"; extern void pdf_print_real(integer m, integer d); diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.c b/Build/source/texk/web2c/luatexdir/image/writejbig2.c index c2f01d1bfca..ea3363ef02c 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.c +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.c @@ -83,7 +83,7 @@ object exists, reference it. Else create fresh one. #include "writejbig2.h" static const char _svn_version[] = - "$Id: writejbig2.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writejbig2.c $"; + "$Id: writejbig2.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writejbig2.c $"; #undef DEBUG diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.c b/Build/source/texk/web2c/luatexdir/image/writejpg.c index 8e439c76ca5..bff9b0ed61a 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.c +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.c @@ -23,7 +23,7 @@ #include "image.h" static const char _svn_version[] = - "$Id: writejpg.c 1224 2008-05-02 15:26:27Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writejpg.c $"; + "$Id: writejpg.c 1224 2008-05-02 15:26:27Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writejpg.c $"; #define JPG_GRAY 1 /* Gray color space, use /DeviceGray */ #define JPG_RGB 3 /* RGB color space, use /DeviceRGB */ diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.c b/Build/source/texk/web2c/luatexdir/image/writepng.c index 1981d002218..a1f160bf7fa 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.c +++ b/Build/source/texk/web2c/luatexdir/image/writepng.c @@ -23,7 +23,7 @@ #include "image.h" static const char _svn_version[] = - "$Id: writepng.c 2029 2009-03-14 19:10:25Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writepng.c $"; + "$Id: writepng.c 2029 2009-03-14 19:10:25Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writepng.c $"; static int transparent_page_group = -1; diff --git a/Build/source/texk/web2c/luatexdir/lang/texlang.c b/Build/source/texk/web2c/luatexdir/lang/texlang.c index c37350f146f..d451e302e6b 100644 --- a/Build/source/texk/web2c/luatexdir/lang/texlang.c +++ b/Build/source/texk/web2c/luatexdir/lang/texlang.c @@ -27,7 +27,7 @@ #include "hyphen.h" static const char _svn_version[] = - "$Id: texlang.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $"; + "$Id: texlang.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lang/texlang.c $"; /* functions from the fontforge unicode library */ @@ -839,7 +839,7 @@ void hnj_hyphenation(halfword head, halfword tail) wordstart = r; assert(is_simple_character(wordstart)); hyf_font = font(wordstart); - if (hyphen_char(hyf_font)<0) /* for backward compat */ + if (hyphen_char(hyf_font) < 0) /* for backward compat */ hyf_font = 0; clang = char_lang(wordstart); lhmin = char_lhmin(wordstart); @@ -927,7 +927,7 @@ void new_hyphenation(halfword head, halfword tail) return; } lua_pop(L, 1); - } else { + } else if (callback_id == 0) { hnj_hyphenation(head, tail); } } @@ -946,7 +946,7 @@ void new_hyphenation(halfword head, halfword tail) void dump_one_language(int i) { char *s = NULL; - unsigned x = 0; + integer x = 0; struct tex_language *lang; lang = tex_languages[i]; dump_int(lang->id); @@ -973,7 +973,7 @@ void dump_one_language(int i) void dump_language_data(void) { - int i; + integer i; dump_int(next_lang_id); for (i = 0; i < next_lang_id; i++) { if (tex_languages[i]) { @@ -989,7 +989,7 @@ void dump_language_data(void) void undump_one_language(int i) { char *s = NULL; - unsigned x = 0; + integer x = 0; struct tex_language *lang = get_language(i); undump_int(x); lang->id = x; @@ -1021,7 +1021,7 @@ void undump_one_language(int i) void undump_language_data(void) { - unsigned i, x, numlangs; + integer i, x, numlangs; undump_int(numlangs); next_lang_id = numlangs; for (i = 0; i < numlangs; i++) { diff --git a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c index c85a1912e49..f06445e62fe 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lcallbacklib.c @@ -21,7 +21,7 @@ #include <ptexlib.h> static const char _svn_version[] = - "$Id: lcallbacklib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lcallbacklib.c $"; + "$Id: lcallbacklib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lcallbacklib.c $"; extern int do_run_callback(int special, char *values, va_list vl); extern int lua_traceback(lua_State * L); @@ -430,7 +430,10 @@ static int callback_register(lua_State * L) { int cb; char *s; - if (!lua_isstring(L, 1) || ((!lua_isfunction(L, 2)) && !lua_isnil(L, 2))) { + if (!lua_isstring(L, 1) || + ((!lua_isfunction(L, 2)) && + (!lua_isnil(L, 2)) && + (!(lua_isboolean(L, 2) && lua_toboolean(L,2)==0)))) { lua_pushnil(L); lua_pushstring(L, "Invalid arguments to callback.register."); return 2; @@ -447,6 +450,8 @@ static int callback_register(lua_State * L) } if (lua_isfunction(L, 2)) { callback_set[cb] = cb; + } else if (lua_isboolean(L, 2)) { + callback_set[cb] = -1; } else { callback_set[cb] = 0; } diff --git a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c index 6dd698ffe0a..266553aef45 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lfontlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lfontlib.c @@ -22,7 +22,14 @@ #include "nodes.h" static const char _svn_version[] = - "$Id: lfontlib.c 1226 2008-05-02 16:11:02Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lfontlib.c $"; + "$Id: lfontlib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lfontlib.c $"; + +#define TIMERS 0 + +#if TIMERS +# include <sys/time.h> +#endif + /* this function is in vfovf.c for the moment */ extern int make_vf_table(lua_State * L, char *name, scaled s); @@ -188,10 +195,27 @@ static int setfont(lua_State * L) static int deffont(lua_State * L) { int i; +#if TIMERS + struct timeval tva; + struct timeval tvb; + double tvdiff; +#endif luaL_checktype(L, -1, LUA_TTABLE); - i = new_font(); +#if TIMERS + gettimeofday(&tva, NULL); +#endif if (font_from_lua(L, i)) { +#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.define(%s,%i): %f seconds\n", + font_fullname(i),i, tvdiff); +#endif lua_pushnumber(L, i); return 1; } else { diff --git a/Build/source/texk/web2c/luatexdir/lua/limglib.c b/Build/source/texk/web2c/luatexdir/lua/limglib.c index 44b3a04712d..1054a03a779 100644 --- a/Build/source/texk/web2c/luatexdir/lua/limglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/limglib.c @@ -27,7 +27,7 @@ #include "../luatex-api.h" static const char _svn_version[] = - "$Id: limglib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/limglib.c $"; + "$Id: limglib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/limglib.c $"; /**********************************************************************/ @@ -729,7 +729,7 @@ static const struct luaL_Reg imglib[] = { void vf_out_image(unsigned i) { image *a, **aa; - lua_State *L = Luas; /* ... */ + lua_State *L = Luas; /* ... */ lua_rawgeti(L, LUA_GLOBALSINDEX, i); /* image ... */ aa = (image **) luaL_checkudata(L, -1, TYPE_IMG); a = *aa; diff --git a/Build/source/texk/web2c/luatexdir/lua/liolib.c b/Build/source/texk/web2c/luatexdir/lua/liolib.c new file mode 100644 index 00000000000..5d10744c10b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/lua/liolib.c @@ -0,0 +1,667 @@ +/* +** $Id: liolib.c 2271 2009-04-12 23:42:21Z oneiros $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define liolib_c +#define LUA_LIB + +#ifndef MINGW32 +# define LUA_USE_POSIX 1 +#endif + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + +#include <ptexlib.h> + +#define IO_INPUT 1 +#define IO_OUTPUT 2 + +extern int shell_cmd_is_allowed(char **cmd, char **safecmd, char **cmdname); + +static const char *const fnames[] = { "input", "output" }; + + +static int pushresult(lua_State * L, int i, const char *filename) +{ + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + else + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static void fileerror(lua_State * L, int arg, const char *filename) +{ + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + luaL_argerror(L, arg, lua_tostring(L, -1)); +} + + +#define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + + +static int io_type(lua_State * L) +{ + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((FILE **) ud) == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static FILE *tofile(lua_State * L) +{ + FILE **f = topfile(L); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static FILE **newfile(lua_State * L) +{ + FILE **pf = (FILE **) lua_newuserdata(L, sizeof(FILE *)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ +static int io_pclose(lua_State * L) +{ + FILE **p = topfile(L); + int ok = lua_pclose(L, *p); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int io_fclose(lua_State * L) +{ + FILE **p = topfile(L); + int ok = (fclose(*p) == 0); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int aux_close(lua_State * L) +{ + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1)) (L); +} + + +static int io_close(lua_State * L) +{ + if (lua_isnone(L, 1)) + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); +} + + +static int io_gc(lua_State * L) +{ + FILE *f = *topfile(L); + /* ignore closed files and standard files */ + if (f != NULL && f != stdin && f != stdout && f != stderr) + aux_close(L); + return 0; +} + + +static int io_tostring(lua_State * L) +{ + FILE *f = *topfile(L); + if (f == NULL) + lua_pushstring(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", f); + return 1; +} + + +static int io_open(lua_State * L) +{ + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + +static int io_open_ro(lua_State * L) +{ + FILE **pf; + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + if ((strcmp(mode, "r") != 0) && (strcmp(mode, "rb") != 0)) + return pushresult(L, 0, filename); + pf = newfile(L); + *pf = fopen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + + + + +static int io_popen(lua_State * L) +{ + int ret = 1; + char *safecmd = NULL; + char *cmdname = NULL; + int allow = 0; + char *cmd = (char *) luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + + if (shellenabledp <= 0) { + lua_pushnil(L); + lua_pushliteral(L, "All command execution is disabled"); + return 2; + } + /* If restrictedshell == 0, any command is allowed. */ + if (restrictedshell == 0) + allow = 1; + else + allow = shell_cmd_is_allowed(&cmd, &safecmd, &cmdname); + + if (allow == 1) { + *pf = lua_popen(L, cmd, mode); + ret = (*pf == NULL) ? pushresult(L, 0, cmd) : 1; + } else if (allow == 2) { + *pf = lua_popen(L, safecmd, mode); + ret = (*pf == NULL) ? pushresult(L, 0, safecmd) : 1; + } else if (allow == 0) { + lua_pushnil(L); + lua_pushliteral(L, "Command execution disabled via shell_escape='p'"); + ret = 2; + } else { + lua_pushnil(L); + lua_pushliteral(L, "Bad command line quoting"); + ret = 2; + } + return ret; +} + + +static int io_tmpfile(lua_State * L) +{ + FILE **pf = newfile(L); + *pf = tmpfile(); + return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile(lua_State * L, int findex) +{ + FILE *f; + lua_rawgeti(L, LUA_ENVIRONINDEX, findex); + f = *(FILE **) lua_touserdata(L, -1); + if (f == NULL) + luaL_error(L, "standard %s file is closed", fnames[findex - 1]); + return f; +} + + +static int g_iofile(lua_State * L, int f, const char *mode) +{ + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) { + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + if (*pf == NULL) + fileerror(L, 1, filename); + } else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawseti(L, LUA_ENVIRONINDEX, f); + } + /* return current value */ + lua_rawgeti(L, LUA_ENVIRONINDEX, f); + return 1; +} + + +static int io_input(lua_State * L) +{ + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output(lua_State * L) +{ + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline(lua_State * L); + + +static void aux_lines(lua_State * L, int idx, int toclose) +{ + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); +} + + +static int f_lines(lua_State * L) +{ + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines(lua_State * L) +{ + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + /* will iterate over default input */ + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); + return f_lines(L); + } else { + const char *filename = luaL_checkstring(L, 1); + FILE **pf = newfile(L); + *pf = fopen(filename, "r"); + if (*pf == NULL) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number(lua_State * L, FILE * f) +{ + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } else + return 0; /* read fails */ +} + + +static int test_eof(lua_State * L, FILE * f) +{ + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + +#if 0 +static int read_line(lua_State * L, FILE * f) +{ + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_strlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l - 1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} +#endif + +/* this new version does not care wether the file has + line endings using an 'alien' convention */ + +static int new_read_line(lua_State * L, FILE * f) +{ + luaL_Buffer buf; + int c, d; + luaL_buffinit(L, &buf); + while (1) { + c = fgetc(f); + if (c == EOF) { + luaL_pushresult(&buf); /* close buffer */ + return (lua_strlen(L, -1) > 0); /* check whether read something */ + }; + if (c == '\n') { + break; + } else if (c == '\r') { + d = fgetc(f); + if (d != EOF && d != '\n') + ungetc(d, f); + break; + } else { + luaL_addchar(&buf, c); + } + } + luaL_pushresult(&buf); /* close buffer */ + return 1; +} + + +static int read_chars(lua_State * L, FILE * f, size_t n) +{ + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + char *p = luaL_prepbuffer(&b); + if (rlen > n) + rlen = n; /* cannot read more than asked */ + nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_strlen(L, -1) > 0); +} + +static int read_all(lua_State * L, FILE * f) +{ + /* attempt to speed up reading whole files */ + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + size_t 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); + if (p != NULL) { + nr = fread(p, sizeof(char), rlen, f); + lua_pushlstring(L, p, nr); + free(p); + return 1; + } + } + if (old > 0) + fseek(f, old, SEEK_SET); + return read_chars(L, f, ~((size_t) 0)); +} + + +static int g_read(lua_State * L, FILE * f, int first) +{ + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = new_read_line(L, f); + n = first + 1; /* to return 1 result */ + } else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs + LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t) lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = new_read_line(L, f); + break; + case 'a': /* file */ + read_all(L, f); + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return pushresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + +static int io_read(lua_State * L) +{ + return g_read(L, getiofile(L, IO_INPUT), 1); +} + +static int f_read(lua_State * L) +{ + return g_read(L, tofile(L), 2); +} + +static int io_readline(lua_State * L) +{ + FILE *f = *(FILE **) lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + sucess = new_read_line(L, f); + if (ferror(f)) + return luaL_error(L, "%s", strerror(errno)); + if (sucess) + return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write(lua_State * L, FILE * f, int arg) +{ + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write(lua_State * L) +{ + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write(lua_State * L) +{ + return g_write(L, tofile(L), 2); +} + + +static int f_seek(lua_State * L) +{ + static const int mode[] = { SEEK_SET, SEEK_CUR, SEEK_END }; + static const char *const modenames[] = { "set", "cur", "end", NULL }; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, ftell(f)); + return 1; + } +} + + +static int f_setvbuf(lua_State * L) +{ + 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); + return pushresult(L, res == 0, NULL); +} + + + +static int io_flush(lua_State * L) +{ + return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush(lua_State * L) +{ + return pushresult(L, fflush(tofile(L)) == 0, NULL); +} + + +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"open_ro", io_open_ro}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta(lua_State * L) +{ + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ +} + + +static void createstdfile(lua_State * L, FILE * f, int k, const char *fname) +{ + *newfile(L) = f; + if (k > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_setfield(L, -2, fname); +} + + +LUALIB_API int luaopen_io(lua_State * L) +{ + createmeta(L); + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ + lua_createtable(L, 2, 1); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + /* create (and set) default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, 0, "stderr"); + /* create environment for 'popen' */ + lua_getfield(L, -1, "popen"); + lua_createtable(L, 0, 1); + lua_pushcfunction(L, io_pclose); + lua_setfield(L, -2, "__close"); + lua_setfenv(L, -2); + lua_pop(L, 1); /* pop 'popen' */ + /* set default close function */ + lua_pushcfunction(L, io_fclose); + lua_setfield(L, LUA_ENVIRONINDEX, "__close"); + return 1; +} diff --git a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c index 23bd37e2f5f..37a5d96cddd 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lkpselib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lkpselib.c @@ -25,7 +25,7 @@ #include <kpathsea/readable.h> static const char _svn_version[] = - "$Id: lkpselib.c 2093 2009-03-23 11:44:13Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lkpselib.c $"; + "$Id: lkpselib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lkpselib.c $"; static const int filetypes[] = { kpse_gf_format, @@ -197,7 +197,7 @@ static int lua_kpathsea_find_file(lua_State * L) int i; int ftype = kpse_tex_format; int mexist = 0; - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); char *st = (char *) luaL_checkstring(L, 2); i = lua_gettop(L); while (i > 2) { @@ -240,10 +240,10 @@ static int show_path(lua_State * L) static int lua_kpathsea_show_path(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); int op = luaL_checkoption(L, -1, "tex", filetypenames); int user_format = filetypes[op]; - if (!(*kp)->format_info[user_format].type) /* needed if arg was numeric */ + if (!(*kp)->format_info[user_format].type) /* needed if arg was numeric */ kpathsea_init_format(*kp, user_format); lua_pushstring(L, (*kp)->format_info[user_format].path); return 1; @@ -259,7 +259,7 @@ static int expand_path(lua_State * L) static int lua_kpathsea_expand_path(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *st = luaL_checkstring(L, 2); lua_pushstring(L, kpathsea_path_expand(*kp, st)); return 1; @@ -275,7 +275,7 @@ static int expand_braces(lua_State * L) static int lua_kpathsea_expand_braces(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *st = luaL_checkstring(L, 2); lua_pushstring(L, kpathsea_brace_expand(*kp, st)); return 1; @@ -292,7 +292,7 @@ static int expand_var(lua_State * L) static int lua_kpathsea_expand_var(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *st = luaL_checkstring(L, 2); lua_pushstring(L, kpathsea_var_expand(*kp, st)); return 1; @@ -309,7 +309,7 @@ static int var_value(lua_State * L) static int lua_kpathsea_var_value(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *st = luaL_checkstring(L, 2); lua_pushstring(L, kpathsea_var_value(*kp, st)); return 1; @@ -358,12 +358,12 @@ static int init_prog(lua_State * L) static int lua_kpathsea_init_prog(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *prefix = luaL_checkstring(L, 2); unsigned dpi = luaL_checkinteger(L, 3); const char *mode = luaL_checkstring(L, 4); const char *fallback = luaL_optstring(L, 5, NULL); - kpathsea_init_prog(*kp,prefix, dpi, mode, fallback); + kpathsea_init_prog(*kp, prefix, dpi, mode, fallback); return 0; } @@ -377,16 +377,16 @@ static int readable_file(lua_State * L) static int lua_kpathsea_readable_file(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); const char *name = luaL_checkstring(L, 2); - lua_pushstring(L, (char *) kpathsea_readable_file(*kp,name)); + lua_pushstring(L, (char *) kpathsea_readable_file(*kp, name)); return 1; } static int lua_kpathsea_finish(lua_State * L) { - kpathsea *kp = (kpathsea *)luaL_checkudata(L, 1, KPATHSEA_METATABLE); + kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); kpathsea_finish(*kp); return 0; } @@ -395,41 +395,41 @@ static int lua_kpathsea_new(lua_State * L) { kpathsea kpse = NULL; kpathsea *kp = NULL; - char *argv = (char *)luaL_checkstring(L,1); - char *liar = (char *)luaL_optstring(L,2,argv); + char *argv = (char *) luaL_checkstring(L, 1); + char *liar = (char *) luaL_optstring(L, 2, argv); kpse = kpathsea_new(); kpathsea_set_program_name(kpse, argv, liar); - kp = (kpathsea *)lua_newuserdata(L, sizeof(kpathsea *)); + kp = (kpathsea *) lua_newuserdata(L, sizeof(kpathsea *)); *kp = kpse; luaL_getmetatable(L, KPATHSEA_METATABLE); - lua_setmetatable(L, -2); + lua_setmetatable(L, -2); return 1; } static const struct luaL_reg kpselib_m[] = { - {"__gc", lua_kpathsea_finish }, - {"init_prog", lua_kpathsea_init_prog }, - {"readable_file", lua_kpathsea_readable_file }, - {"find_file", lua_kpathsea_find_file }, - {"expand_path", lua_kpathsea_expand_path }, - {"expand_var", lua_kpathsea_expand_var }, - {"expand_braces", lua_kpathsea_expand_braces }, - {"var_value", lua_kpathsea_var_value }, - {"show_path", lua_kpathsea_show_path }, + {"__gc", lua_kpathsea_finish}, + {"init_prog", lua_kpathsea_init_prog}, + {"readable_file", lua_kpathsea_readable_file}, + {"find_file", lua_kpathsea_find_file}, + {"expand_path", lua_kpathsea_expand_path}, + {"expand_var", lua_kpathsea_expand_var}, + {"expand_braces", lua_kpathsea_expand_braces}, + {"var_value", lua_kpathsea_var_value}, + {"show_path", lua_kpathsea_show_path}, {NULL, NULL} /* sentinel */ }; static const struct luaL_reg kpselib_l[] = { - {"new", lua_kpathsea_new }, - {"set_program_name", set_program_name }, - {"init_prog", init_prog }, - {"readable_file", readable_file }, - {"find_file", find_file }, - {"expand_path", expand_path }, - {"expand_var", expand_var }, - {"expand_braces", expand_braces }, - {"var_value", var_value }, - {"show_path", show_path }, + {"new", lua_kpathsea_new}, + {"set_program_name", set_program_name}, + {"init_prog", init_prog}, + {"readable_file", readable_file}, + {"find_file", find_file}, + {"expand_path", expand_path}, + {"expand_var", expand_var}, + {"expand_braces", expand_braces}, + {"var_value", var_value}, + {"show_path", show_path}, {NULL, NULL} /* sentinel */ }; @@ -437,7 +437,7 @@ int luaopen_kpse(lua_State * L) { luaL_newmetatable(L, KPATHSEA_METATABLE); lua_pushvalue(L, -1); - lua_setfield(L, -2,"__index"); + lua_setfield(L, -2, "__index"); luaL_register(L, NULL, kpselib_m); luaL_register(L, "kpse", kpselib_l); return 1; diff --git a/Build/source/texk/web2c/luatexdir/lua/llanglib.c b/Build/source/texk/web2c/luatexdir/lua/llanglib.c index 6aa634525b5..6ca78933d3a 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llanglib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llanglib.c @@ -23,7 +23,7 @@ #include "nodes.h" static const char _svn_version[] = - "$Id: llanglib.c 1594 2008-11-28 13:32:48Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/llanglib.c $"; + "$Id: llanglib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/llanglib.c $"; #define LANG_METATABLE "luatex.lang" diff --git a/Build/source/texk/web2c/luatexdir/lua/llualib.c b/Build/source/texk/web2c/luatexdir/lua/llualib.c index 7efff052754..cfd3b783ed6 100644 --- a/Build/source/texk/web2c/luatexdir/lua/llualib.c +++ b/Build/source/texk/web2c/luatexdir/lua/llualib.c @@ -21,7 +21,7 @@ #include <ptexlib.h> static const char _svn_version[] = - "$Id: llualib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/llualib.c $"; + "$Id: llualib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/llualib.c $"; #define LOAD_BUF_SIZE 256 #define UINT_MAX32 0xFFFFFFFF @@ -35,17 +35,16 @@ typedef struct { static bytecode *lua_bytecode_registers = NULL; -int luabytecode_max = -1; +integer luabytecode_max = -1; unsigned int luabytecode_bytes = 0; -char *luanames[65536] = {NULL}; +char *luanames[65536] = { NULL }; extern char *luanames[]; -char * -get_lua_name (int i) +char *get_lua_name(int i) { - if (i<0 || i>65535) + if (i < 0 || i > 65535) return NULL; return luanames[i]; } @@ -53,7 +52,7 @@ get_lua_name (int i) void dump_luac_registers(void) { integer x; - int k, n; + integer k, n; bytecode b; dump_int(luabytecode_max); if (lua_bytecode_registers != NULL) { @@ -74,12 +73,12 @@ void dump_luac_registers(void) } for (k = 0; k < 65536; k++) { char *a = luanames[k]; - if (a!=NULL) { - x = strlen(a)+1; - dump_int(x); + if (a != NULL) { + x = strlen(a) + 1; + dump_int(x); dump_things(*a, x); } else { - x = 0; + x = 0; dump_int(x); } } @@ -88,7 +87,7 @@ void dump_luac_registers(void) void undump_luac_registers(void) { integer x; - int k, n; + integer k, n; unsigned int i; bytecode b; undump_int(luabytecode_max); @@ -107,7 +106,8 @@ void undump_luac_registers(void) undump_int(n); for (i = 0; i < (unsigned) n; i++) { undump_int(k); - undump_int(b.size); + undump_int(x); + b.size = x; b.buf = xmalloc(b.size); luabytecode_bytes += b.size; memset(b.buf, 0, b.size); @@ -162,7 +162,7 @@ static int bytecode_register_shadow_get(lua_State * L, int k) int writer(lua_State * L, const void *b, size_t size, void *B) { bytecode *buf = (bytecode *) B; - (void)L; /* for -Wunused */ + (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; @@ -176,7 +176,7 @@ int writer(lua_State * L, const void *b, size_t size, void *B) const char *reader(lua_State * L, void *ud, size_t * size) { bytecode *buf = (bytecode *) ud; - (void)L; /* for -Wunused */ + (void) L; /* for -Wunused */ if (buf->done == buf->size) { *size = 0; buf->done = 0; @@ -269,9 +269,9 @@ int set_luaname(lua_State * L) { int k; char *s; - if (lua_gettop(L)==3) { + if (lua_gettop(L) == 3) { k = (int) luaL_checkinteger(L, 2); - if (k>65535 || k<0) { + if (k > 65535 || k < 0) { /* error */ } else { if (luanames[k] != NULL) { @@ -279,8 +279,8 @@ int set_luaname(lua_State * L) luanames[k] = NULL; } if (lua_isstring(L, 3)) { - s = (char *) lua_tostring(L,3); - if (s!=NULL) + s = (char *) lua_tostring(L, 3); + if (s != NULL) luanames[k] = xstrdup(s); } } @@ -292,13 +292,13 @@ int get_luaname(lua_State * L) { int k; k = (int) luaL_checkinteger(L, 2); - if (k>65535 || k<0) { + if (k > 65535 || k < 0) { /* error */ lua_pushnil(L); } else { - if (luanames[k]!=NULL) + if (luanames[k] != NULL) lua_pushstring(L, luanames[k]); - else + else lua_pushnil(L); } return 1; diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index 0bbbc021987..65f39ca21b3 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -25,7 +25,7 @@ #include "commands.h" static const char _svn_version[] = - "$Id: lnodelib.c 2027 2009-03-14 18:47:32Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lnodelib.c $"; + "$Id: lnodelib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lnodelib.c $"; #define init_luaS_index(a) do { \ lua_pushliteral(L,#a); \ @@ -450,7 +450,7 @@ static int lua_nodelib_append(lua_State * L) j = lua_gettop(L); for (i = 1; i <= j; i++) { n = check_isnode(L, i); - m = copy_node_list(*n); + m = *n; new_tail_append(m); while (vlink(m) != null) { m = vlink(m); @@ -786,8 +786,8 @@ static int lua_nodelib_has_attribute(lua_State * L) n = check_isnode(L, 1); if (n != NULL) { i = lua_tointeger(L, 2); - val = luaL_optinteger(L, 3, -1); - if ((val = has_attribute(*n, i, val)) >= 0) { + val = luaL_optinteger(L, 3, UNUSED_ATTRIBUTE); + if ((val = has_attribute(*n, i, val)) > UNUSED_ATTRIBUTE) { lua_pushnumber(L, val); return 1; } @@ -804,7 +804,7 @@ static int lua_nodelib_set_attribute(lua_State * L) i = lua_tointeger(L, 2); val = lua_tointeger(L, 3); n = check_isnode(L, 1); - if (val < 0) { + if (val == UNUSED_ATTRIBUTE) { (void) unset_attribute(*n, i, val); } else { set_attribute(*n, i, val); @@ -823,10 +823,10 @@ static int lua_nodelib_unset_attribute(lua_State * L) int i, val, ret; if (lua_gettop(L) <= 3) { i = luaL_checknumber(L, 2); - val = luaL_optnumber(L, 3, -1); + val = luaL_optnumber(L, 3, UNUSED_ATTRIBUTE); n = check_isnode(L, 1); ret = unset_attribute(*n, i, val); - if (ret >= 0) { + if (ret > UNUSED_ATTRIBUTE) { lua_pushnumber(L, ret); } else { lua_pushnil(L); @@ -1093,7 +1093,11 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, int field) lua_pushnumber(L, pdf_literal_mode(n)); break; case 5: - tokenlist_to_luastring(L, pdf_literal_data(n)); + if (pdf_literal_type(n)==lua_refid_literal) { + lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(n)); + } else { + tokenlist_to_luastring(L, pdf_literal_data(n)); + } break; default: lua_pushnil(L); @@ -1680,17 +1684,7 @@ static int lua_nodelib_getfield(lua_State * L) lua_pushnil(L); } break; - case ord_noad: - case op_noad: - case bin_noad: - case rel_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: - case under_noad: - case over_noad: - case vcenter_noad: + case simple_noad: switch (field) { case 2: lua_pushnumber(L, subtype(n)); @@ -2169,8 +2163,14 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, int field) pdf_literal_mode(n) = lua_tointeger(L, 3); break; case 5: - pdf_literal_data(n) = nodelib_gettoks(L, 3); - break; + if (ini_version) { + pdf_literal_data(n) = nodelib_gettoks(L, 3); + } else { + lua_pushvalue(L,3); + pdf_literal_data(n) = luaL_ref(L,LUA_REGISTRYINDEX); + pdf_literal_type(n) = lua_refid_literal; + } + break; default: return nodelib_cantset(L, field, n); } @@ -2786,17 +2786,7 @@ static int lua_nodelib_setfield(lua_State * L) return nodelib_cantset(L, field, n); } break; - case ord_noad: - case op_noad: - case bin_noad: - case rel_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: - case under_noad: - case over_noad: - case vcenter_noad: + case simple_noad: switch (field) { case 2: subtype(n) = lua_tointeger(L, 3); diff --git a/Build/source/texk/web2c/luatexdir/lua/loslibext.c b/Build/source/texk/web2c/luatexdir/lua/loslibext.c index 5f5da8dd6f5..eebb4e8e49e 100644 --- a/Build/source/texk/web2c/luatexdir/lua/loslibext.c +++ b/Build/source/texk/web2c/luatexdir/lua/loslibext.c @@ -25,14 +25,16 @@ #include <time.h> static const char _svn_version[] = - "$Id: loslibext.c 1594 2008-11-28 13:32:48Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/loslibext.c $"; + "$Id: loslibext.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/loslibext.c $"; #if defined(_WIN32) || defined(WIN32) || defined(__NT__) -#define MKDIR(a,b) mkdir(a) +# define MKDIR(a,b) mkdir(a) #else -#define MKDIR(a,b) mkdir(a,b) +# define MKDIR(a,b) mkdir(a,b) #endif +extern int shell_cmd_is_allowed(char **cmd, char **safecmd, char **cmdname); + /* An attempt to figure out the basic platform, does not care about niceties like version numbers yet, and ignores platforms where luatex is unlikely to @@ -351,7 +353,9 @@ static char **do_flatten_command(lua_State * L, char **runcmd) static int os_exec(lua_State * L) { - char *maincmd, *runcmd; + int allow = 0; + char *maincmd = NULL, *runcmd = NULL; + char *safecmd = NULL, *cmdname = NULL; char **cmdline = NULL; if (lua_gettop(L) != 1) { @@ -359,6 +363,11 @@ static int os_exec(lua_State * L) lua_pushliteral(L, "invalid arguments passed"); return 2; } + if (shellenabledp <= 0) { + lua_pushnil(L); + lua_pushliteral(L, "All command execution disabled."); + return 2; + } if (lua_type(L, 1) == LUA_TSTRING) { maincmd = (char *) lua_tostring(L, 1); cmdline = do_split_command(maincmd); @@ -366,33 +375,65 @@ static int os_exec(lua_State * L) } else if (lua_type(L, 1) == LUA_TTABLE) { cmdline = do_flatten_command(L, &runcmd); } - if (cmdline != NULL) { + /* If restrictedshell == 0, any command is allowed. */ + /* this is a little different from \write18/ os.execute processing + * because it does not test for commands with fixed arguments, + * but I am not so eager to attempt to fix that. Just document + * that os.exec() checks only the command name. + */ + if (restrictedshell == 0) + allow = 1; + else + allow = shell_cmd_is_allowed(&runcmd, &safecmd, &cmdname); + + if (allow > 0 && cmdline != NULL && runcmd != NULL) { #if defined(WIN32) && DONT_REALLY_EXIT - exec_command(runcmd, cmdline, environ); + if (allow == 2) + exec_command(safecmd, cmdline, environ); + else + exec_command(runcmd, cmdline, environ); #else - if (exec_command(runcmd, cmdline, environ) == -1) { - lua_pushnil(L); - lua_pushfstring(L, "%s: %s", runcmd, strerror(errno)); - lua_pushnumber(L, errno); - return 3; + { + int r; + if (allow == 2) + r = exec_command(safecmd, cmdline, environ); + else + r = exec_command(runcmd, cmdline, environ); + if (r == -1) { + lua_pushnil(L); + lua_pushfstring(L, "%s: %s", runcmd, strerror(errno)); + lua_pushnumber(L, errno); + return 3; + } } #endif } + if (safecmd) + free(safecmd); + if (cmdname) + free(cmdname); + if (allow == 0) { + lua_pushnil(L); + lua_pushliteral(L, "Command execution disabled via shell_escape='p'"); + return 2; + } lua_pushnil(L); lua_pushliteral(L, "invalid command line passed"); return 2; } #define do_error_return(A,B) do { \ - lua_pushnil(L); \ - lua_pushfstring(L,"%s: %s",runcmd,(A)); \ - lua_pushnumber(L, B); \ - return 3; \ - } while (0) + lua_pushnil(L); \ + lua_pushfstring(L,"%s: %s",runcmd,(A)); \ + lua_pushnumber(L, B); \ + return 3; \ + } while (0) static int os_spawn(lua_State * L) { - char *maincmd, *runcmd; + int allow = 0; + char *maincmd = NULL, *runcmd = NULL; + char *safecmd = NULL, *cmdname = NULL; char **cmdline = NULL; int i; @@ -401,6 +442,11 @@ static int os_spawn(lua_State * L) lua_pushliteral(L, "invalid arguments passed"); return 2; } + if (shellenabledp <= 0) { + lua_pushnil(L); + lua_pushliteral(L, "All command execution disabled."); + return 2; + } if (lua_type(L, 1) == LUA_TSTRING) { maincmd = (char *) lua_tostring(L, 1); cmdline = do_split_command(maincmd); @@ -408,8 +454,25 @@ static int os_spawn(lua_State * L) } else if (lua_type(L, 1) == LUA_TTABLE) { cmdline = do_flatten_command(L, &runcmd); } - if (cmdline != NULL) { - i = spawn_command(runcmd, cmdline, environ); + /* If restrictedshell == 0, any command is allowed. */ + /* this is a little different from \write18/ os.execute processing + * because it does not test for commands with fixed arguments, + * but I am not so eager to attempt to fix that. Just document + * that os.exec() checks only the command name. + */ + if (restrictedshell == 0) + allow = 1; + else + allow = shell_cmd_is_allowed(&runcmd, &safecmd, &cmdname); + if (allow > 0 && cmdline != NULL && runcmd != NULL) { + if (allow == 2) + i = spawn_command(safecmd, cmdline, environ); + else + i = spawn_command(runcmd, cmdline, environ); + if (safecmd) + free(safecmd); + if (cmdname) + free(cmdname); if (i == 0) { lua_pushnumber(L, i); return 1; @@ -437,6 +500,15 @@ static int os_spawn(lua_State * L) return 1; } } + if (safecmd) + free(safecmd); + if (cmdname) + free(cmdname); + if (allow == 0) { + lua_pushnil(L); + lua_pushliteral(L, "Command execution disabled via shell_escape='p'"); + return 2; + } lua_pushnil(L); lua_pushliteral(L, "invalid command line passed"); return 2; @@ -808,6 +880,46 @@ static int os_tmpdir(lua_State * L) } +static int os_execute(lua_State * L) +{ + int allow = 0; + int ret = 1; + char *safecmd = NULL; + char *cmdname = NULL; + char *cmd = (char *) luaL_optstring(L, 1, NULL); + + if (shellenabledp <= 0) { + lua_pushnil(L); + lua_pushstring(L, "All command execution disabled."); + return 2; + } + /* If restrictedshell == 0, any command is allowed. */ + if (restrictedshell == 0) + allow = 1; + else + allow = shell_cmd_is_allowed(&cmd, &safecmd, &cmdname); + + if (allow == 1) { + lua_pushinteger(L, system(cmd)); + } else if (allow == 2) { + lua_pushinteger(L, system(safecmd)); + } else { + lua_pushnil(L); + ret = 2; + if (allow == 0) + lua_pushstring(L, + "Command execution disabled via shell_escape='p'"); + else /* allow == -1 */ + lua_pushstring(L, "Quoting error in system command line."); + } + if (safecmd) + free(safecmd); + if (cmdname) + free(cmdname); + return ret; +} + + void open_oslibext(lua_State * L, int safer_option) { @@ -816,40 +928,32 @@ void open_oslibext(lua_State * L, int safer_option) lua_getglobal(L, "os"); lua_pushcfunction(L, ex_sleep); lua_setfield(L, -2, "sleep"); - lua_getglobal(L, "os"); lua_pushliteral(L, OS_PLATTYPE); lua_setfield(L, -2, "type"); - lua_getglobal(L, "os"); lua_pushliteral(L, OS_PLATNAME); lua_setfield(L, -2, "name"); - lua_getglobal(L, "os"); lua_pushcfunction(L, ex_uname); lua_setfield(L, -2, "uname"); #if (! defined (WIN32)) && (! defined (__SUNOS__)) - lua_getglobal(L, "os"); lua_pushcfunction(L, os_times); lua_setfield(L, -2, "times"); #endif #if ! defined (__SUNOS__) - lua_getglobal(L, "os"); lua_pushcfunction(L, os_gettimeofday); lua_setfield(L, -2, "gettimeofday"); #endif + if (!safer_option) { - lua_getglobal(L, "os"); lua_pushcfunction(L, os_setenv); lua_setfield(L, -2, "setenv"); - lua_getglobal(L, "os"); lua_pushcfunction(L, os_exec); lua_setfield(L, -2, "exec"); - lua_getglobal(L, "os"); lua_pushcfunction(L, os_spawn); lua_setfield(L, -2, "spawn"); - lua_getglobal(L, "os"); + lua_pushcfunction(L, os_execute); + lua_setfield(L, -2, "execute"); lua_pushcfunction(L, os_tmpdir); lua_setfield(L, -2, "tmpdir"); - } - - + lua_pop(L, 1); /* pop the table */ } diff --git a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c index 6c1558e47a6..da9f4328a04 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lpdflib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lpdflib.c @@ -21,7 +21,7 @@ #include <ptexlib.h> static const char _svn_version[] = - "$Id: lpdflib.c 2072 2009-03-21 08:50:20Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lpdflib.c $"; + "$Id: lpdflib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lpdflib.c $"; static int findcurv(lua_State * L) { @@ -39,15 +39,13 @@ static int findcurh(lua_State * L) return 1; } -typedef enum { set_origin, direct_page, direct_always } pdf_lit_mode; - int luapdfprint(lua_State * L) { int n; unsigned i; size_t len; const char *outputstr, *st; - pdf_lit_mode literal_mode; + ctm_transform_modes literal_mode; n = lua_gettop(L); if (!lua_isstring(L, -1)) { lua_pushstring(L, "no string to print"); diff --git a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c index 586ded0db4f..d98cfadfcb4 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lstatslib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lstatslib.c @@ -22,7 +22,7 @@ static const char _svn_version[] = - "$Id: lstatslib.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/lstatslib.c $"; + "$Id: lstatslib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lstatslib.c $"; typedef struct statistic { const char *name; @@ -57,10 +57,14 @@ char *getlasterror(void) return makecstring(last_error); } +char *luatexrevision(void) +{ + return makecstring(get_luatexrevision()); +} extern int luabytecode_max; extern int luabytecode_bytes; -static int luastate_max = 1; /* fixed value */ +static int luastate_max = 1; /* fixed value */ extern int luastate_bytes; extern int callback_count; extern int saved_callback_count; @@ -75,6 +79,9 @@ static struct statistic stats[] = { {"log_name", 's', &texmf_log_name}, /* weird */ {"banner", 'S', &getbanner}, {"pdftex_banner", 's', &pdftex_banner}, + {"luatex_version", 'G', &get_luatexversion}, + {"luatex_revision", 'S', &luatexrevision}, + {"ini_version", 'b', &ini_version}, /* * mem stat */ @@ -182,7 +189,10 @@ static int do_getstat(lua_State * L, int i) lua_pushboolean(L, g()); break; case 'n': - lua_nodelib_push_fast(L, *(halfword *) (stats[i].value)); + if (*(halfword *) (stats[i].value)!=0) + lua_nodelib_push_fast(L, *(halfword *) (stats[i].value)); + else + lua_pushnil(L); break; case 'b': lua_pushboolean(L, *(integer *) (stats[i].value)); diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c index c07d3cac696..28d6a1e1a22 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexiolib.c @@ -21,7 +21,7 @@ #include <ptexlib.h> static const char _svn_version[] = - "$Id: ltexiolib.c 2027 2009-03-14 18:47:32Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/ltexiolib.c $"; + "$Id: ltexiolib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/ltexiolib.c $"; typedef void (*texio_printer) (strnumber s); diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c index a847d89f12e..e7384a40ec2 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -24,7 +24,7 @@ #include "tokens.h" static const char _svn_version[] = - "$Id: ltexlib.c 2079 2009-03-22 10:15:03Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/ltexlib.c $"; + "$Id: ltexlib.c 2282 2009-04-14 11:00:47Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/ltexlib.c $"; extern halfword *check_isnode(lua_State * L, int ud); extern void lua_nodelib_push_fast(lua_State * L, halfword n); @@ -53,8 +53,7 @@ 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, integer cattable) { char *st, *sttemp; size_t tsize; @@ -82,8 +81,7 @@ luac_store (lua_State *L, int i, int partial, integer cattable) } -static int -do_luacprint(lua_State * L, int partial, int deftable) +static int do_luacprint(lua_State * L, int partial, int deftable) { int i, n; integer cattable = (integer) deftable; @@ -96,11 +94,11 @@ do_luacprint(lua_State * L, int partial, int deftable) } } if (lua_type(L, startstrings) == LUA_TTABLE) { - for (i = 1; ; i++) { - lua_rawgeti(L,startstrings, i); + for (i = 1;; i++) { + lua_rawgeti(L, startstrings, i); if (lua_isstring(L, -1)) { luac_store(L, -1, partial, cattable); - lua_pop(L,1); + lua_pop(L, 1); } else { break; } @@ -111,7 +109,7 @@ do_luacprint(lua_State * L, int partial, int deftable) lua_pushstring(L, "no string to print"); lua_error(L); } - luac_store(L,i, partial, cattable); + luac_store(L, i, partial, cattable); } } return 0; @@ -229,10 +227,10 @@ void luacstring_close(int n) #define depth_offset 2 #define height_offset 3 -#define check_index_range(j) \ - if (j > 65535) { \ - lua_pushstring(L, "incorrect index value"); \ - lua_error(L); } +#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); } int dimen_to_number(lua_State * L, char *s) @@ -271,12 +269,37 @@ int dimen_to_number(lua_State * L, char *s) return j; } -int setdimen(lua_State * L) + +integer +get_item_index (lua_State *L, int i, integer base) { - int i, j; - size_t k; + size_t kk; + integer k; int cur_cs; char *s; + if (lua_type(L, i) == LUA_TSTRING) { + s = (char *) lua_tolstring(L, i , &kk); + cur_cs = string_lookup(s, kk); + if (cur_cs==static_undefined_control_sequence || + is_undefined_cs(cur_cs)) { + k = -1; /* guarandeed invalid */ + } else { + k = (zget_equiv(cur_cs) - base); + } + } else { + k = (integer) luaL_checkinteger(L, i ); + } + return k; +} + + +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); + if (is_global) + int_par(param_global_defs_code) = 1; i = lua_gettop(L); j = 0; /* find the value */ @@ -288,92 +311,79 @@ int setdimen(lua_State * L) lua_error(L); } else j = (int) lua_tonumber(L, i); - /* find the index */ - if (lua_type(L, i - 1) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i - 1, &k); - cur_cs = string_lookup(s, k); - k = zget_equiv(cur_cs) - get_scaled_base(); - } else { - k = (int) luaL_checkinteger(L, i - 1); - } - check_index_range(k); - if (set_tex_dimen_register(k, j)) { + k = get_item_index(L, (i-1), get_scaled_base()); + check_index_range(k, "setdimen"); + err = set_tex_dimen_register(k, j); + int_par(param_global_defs_code) = save_global_defs; + if (err) { lua_pushstring(L, "incorrect value"); lua_error(L); } return 0; } -int getdimen(lua_State * L) +static int setdimen(lua_State * L) { - int i, j; - size_t k; - int cur_cs; - char *s; - i = lua_gettop(L); - if (lua_type(L, i) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i, &k); - cur_cs = string_lookup(s, k); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs) - get_scaled_base(); - } else { - k = (int) luaL_checkinteger(L, i); - } - check_index_range(k); + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; + } + return vsetdimen (L, isglobal); +} + +static int getdimen(lua_State * L) +{ + int j; + integer k; + k = get_item_index(L, lua_gettop(L), get_scaled_base()); + check_index_range(k, "getdimen"); j = get_tex_dimen_register(k); lua_pushnumber(L, j); return 1; } - -int setskip(lua_State * L) +static int vsetskip(lua_State * L, int is_global) { - int i; + int i, err; halfword *j; - size_t k; - int cur_cs; - char *s; + integer k; + integer save_global_defs = int_par(param_global_defs_code); + if (is_global) + int_par(param_global_defs_code) = 1; i = lua_gettop(L); j = check_isnode(L, i); /* the value */ - - if (lua_type(L, i - 1) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i - 1, &k); - cur_cs = string_lookup(s, k); - k = zget_equiv(cur_cs) - get_scaled_base(); - } else { - k = (int) luaL_checkinteger(L, i - 1); - } - check_index_range(k); /* the index */ - if (set_tex_skip_register(k, *j)) { + k = get_item_index(L, (i-1), get_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; + if (err) { lua_pushstring(L, "incorrect value"); lua_error(L); } return 0; } +static int setskip(lua_State * L) +{ + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; + } + return vsetskip (L, isglobal); +} + int getskip(lua_State * L) { - int i; halfword j; - size_t k; - int cur_cs; - char *s; - i = lua_gettop(L); - if (lua_type(L, i) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i, &k); - cur_cs = string_lookup(s, k); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs) - get_scaled_base(); - } else { - k = (int) luaL_checkinteger(L, i); - } - check_index_range(k); + integer k; + k = get_item_index(L, lua_gettop(L), get_skip_base()); + check_index_range(k, "getskip"); j = get_tex_skip_register(k); lua_nodelib_push_fast(L, j); return 1; @@ -381,125 +391,114 @@ int getskip(lua_State * L) -int setcount(lua_State * L) +static int vsetcount(lua_State * L, int is_global) { - int i, j; - size_t k; - int cur_cs; - char *s; + int i, j, err; + integer k; + integer save_global_defs = int_par(param_global_defs_code); + if (is_global) + int_par(param_global_defs_code) = 1; i = lua_gettop(L); j = (int) luaL_checkinteger(L, i); - if (lua_type(L, i - 1) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i - 1, &k); - cur_cs = string_lookup(s, k); - k = zget_equiv(cur_cs) - get_count_base(); - } else { - k = (int) luaL_checkinteger(L, i - 1); - } - check_index_range(k); - if (set_tex_count_register(k, j)) { + k = get_item_index(L, (i-1), get_count_base()); + check_index_range(k, "setcount"); + err = set_tex_count_register(k, j); + int_par(param_global_defs_code) = save_global_defs; + if (err) { lua_pushstring(L, "incorrect value"); lua_error(L); } return 0; } -int getcount(lua_State * L) +static int setcount(lua_State * L) { - int i, j; - size_t k; - int cur_cs; - char *s; - i = lua_gettop(L); - if (lua_type(L, i) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i, &k); - cur_cs = string_lookup(s, k); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs) - get_count_base(); - } else { - k = (int) luaL_checkinteger(L, i); + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; } - check_index_range(k); + return vsetcount (L, isglobal); +} + +static int getcount(lua_State * L) +{ + int j; + integer k; + k = get_item_index(L, lua_gettop(L), get_count_base()); + check_index_range(k,"getcount"); j = get_tex_count_register(k); lua_pushnumber(L, j); return 1; } -int setattribute(lua_State * L) +static int vsetattribute(lua_State * L, int is_global) { - int i, j; - size_t k; - int cur_cs; - char *s; + int i, j, err; + integer k; + integer save_global_defs = int_par(param_global_defs_code); + if (is_global) + int_par(param_global_defs_code) = 1; i = lua_gettop(L); j = (int) luaL_checkinteger(L, i); - if (lua_type(L, i - 1) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i - 1, &k); - cur_cs = string_lookup(s, k); - k = zget_equiv(cur_cs) - get_attribute_base(); - } else { - k = (int) luaL_checkinteger(L, i - 1); - } - check_index_range(k); - if (set_tex_attribute_register(k, j)) { + k = get_item_index(L, (i-1), get_attribute_base()); + check_index_range(k,"setattribute"); + err = set_tex_attribute_register(k, j); + int_par(param_global_defs_code) = save_global_defs; + if (err) { lua_pushstring(L, "incorrect value"); lua_error(L); } return 0; } -int getattribute(lua_State * L) +static int setattribute(lua_State * L) { - int i, j; - size_t k; - int cur_cs; - char *s; - i = lua_gettop(L); - if (lua_type(L, i) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i, &k); - cur_cs = string_lookup(s, k); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs) - get_attribute_base(); - } else { - k = (int) luaL_checkinteger(L, i); + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; } - check_index_range(k); + return vsetattribute (L, isglobal); +} + +static int getattribute(lua_State * L) +{ + int j; + integer k; + k = get_item_index(L, lua_gettop(L), get_attribute_base()); + check_index_range(k,"getattribute"); j = get_tex_attribute_register(k); lua_pushnumber(L, j); return 1; } -int settoks(lua_State * L) +int vsettoks(lua_State * L, int is_global) { - int i, j; - size_t k, len; - int cur_cs; - char *s, *st; + int i, j, err; + size_t len; + integer k; + char *st; + integer save_global_defs = int_par(param_global_defs_code); + if (is_global) + int_par(param_global_defs_code) = 1; i = lua_gettop(L); if (!lua_isstring(L, i)) { lua_pushstring(L, "unsupported value type"); lua_error(L); } st = (char *) lua_tolstring(L, i, &len); - - if (lua_type(L, i - 1) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i - 1, &k); - cur_cs = string_lookup(s, k); - k = zget_equiv(cur_cs) - get_toks_base(); - } else { - k = (int) luaL_checkinteger(L, i - 1); - } - check_index_range(k); + k = get_item_index (L, (i-1), get_toks_base()); + check_index_range(k,"settoks"); j = maketexlstring(st, len); - - if (zset_tex_toks_register(k, j)) { + err = zset_tex_toks_register(k, j); + int_par(param_global_defs_code) = save_global_defs; + if (err) { flush_str(j); lua_pushstring(L, "incorrect value"); lua_error(L); @@ -507,27 +506,24 @@ int settoks(lua_State * L) return 0; } -int gettoks(lua_State * L) +static int settoks (lua_State * L) { - int i; - size_t k; - strnumber t; - int cur_cs; - char *s; - i = lua_gettop(L); - if (lua_type(L, i) == LUA_TSTRING) { - s = (char *) lua_tolstring(L, i, &k); - cur_cs = string_lookup(s, k); - if (is_undefined_cs(cur_cs)) { - lua_pushnil(L); - return 1; - } - k = zget_equiv(cur_cs) - get_toks_base(); - } else { - k = (int) luaL_checkinteger(L, i); + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; } + return vsettoks (L, isglobal); +} - check_index_range(k); +static int gettoks(lua_State * L) +{ + integer k; + strnumber t; + k = get_item_index (L, lua_gettop(L), get_toks_base()); + check_index_range(k,"gettoks"); t = get_tex_toks_register(k); lua_pushstring(L, makecstring(t)); flush_str(t); @@ -554,21 +550,24 @@ static int get_box_id(lua_State * L, int i) return j; } -int getbox(lua_State * L) +static int getbox(lua_State * L) { int k, t; k = get_box_id(L, -1); - check_index_range(k); + check_index_range(k,"getbox"); t = get_tex_box_register(k); nodelist_to_lua(L, t); return 1; } -int setbox(lua_State * L) +static int vsetbox(lua_State * L, int is_global) { - int i, j, k; + int i, j, k, err; + integer save_global_defs = int_par(param_global_defs_code); + if (is_global) + int_par(param_global_defs_code) = 1; k = get_box_id(L, -2); - check_index_range(k); + check_index_range(k,"setbox"); i = get_tex_box_register(k); if (lua_isboolean(L, -1)) { j = lua_toboolean(L, -1); @@ -579,13 +578,27 @@ int setbox(lua_State * L) } else { j = nodelist_from_lua(L); } - if (set_tex_box_register(k, j)) { + err = set_tex_box_register(k, j); + int_par(param_global_defs_code) = save_global_defs; + if (err) { lua_pushstring(L, "incorrect value"); lua_error(L); } return 0; } +static int setbox(lua_State * L) +{ + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; + } + return vsetbox (L, isglobal); +} + static int getboxdim(lua_State * L, int whichdim) { int i, j; @@ -624,9 +637,12 @@ int getboxdp(lua_State * L) return getboxdim(L, depth_offset); } -static int setboxdim(lua_State * L, int whichdim) +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); + if (is_global) + int_par(param_global_defs_code) = 1; i = lua_gettop(L); if (!lua_isnumber(L, i)) { j = dimen_to_number(L, (char *) lua_tostring(L, i)); @@ -650,6 +666,7 @@ static int setboxdim(lua_State * L, int whichdim) case depth_offset: err = set_tex_box_depth(k, j); } + int_par(param_global_defs_code) = save_global_defs; if (err) { lua_pushstring(L, "not a box"); lua_error(L); @@ -657,19 +674,40 @@ static int setboxdim(lua_State * L, int whichdim) return 0; } -int setboxwd(lua_State * L) +static int setboxwd(lua_State * L) { - return setboxdim(L, width_offset); + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; + } + return vsetboxdim(L, width_offset, isglobal); } -int setboxht(lua_State * L) +static int setboxht(lua_State * L) { - return setboxdim(L, height_offset); + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; + } + return vsetboxdim(L, height_offset, isglobal); } -int setboxdp(lua_State * L) +static int setboxdp(lua_State * L) { - return setboxdim(L, depth_offset); + int isglobal = 0; + int n = lua_gettop(L); + if (n==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; + } + return vsetboxdim(L, depth_offset, isglobal); } int settex(lua_State * L) @@ -678,33 +716,41 @@ int settex(lua_State * L) int i, j, texstr; size_t k; int cur_cs, cur_cmd; + int isglobal = 0; j = 0; i = lua_gettop(L); if (lua_isstring(L, (i - 1))) { st = (char *) lua_tolstring(L, (i - 1), &k); texstr = maketexlstring(st, k); if (is_primitive(texstr)) { + if (i==3 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + isglobal = 1; + } cur_cs = string_lookup(st, k); flush_str(texstr); cur_cmd = zget_eq_type(cur_cs); if (is_int_assign(cur_cmd)) { if (lua_isnumber(L, i)) { - assign_internal_value(0, zget_equiv(cur_cs), + assign_internal_value((isglobal?4:0), zget_equiv(cur_cs), lua_tonumber(L, i)); } else { lua_pushstring(L, "unsupported value type"); lua_error(L); } } else if (is_dim_assign(cur_cmd)) { - if (!lua_isnumber(L, i)) + if (!lua_isnumber(L, i)) { if (lua_isstring(L, i)) { j = dimen_to_number(L, (char *) lua_tostring(L, i)); } else { lua_pushstring(L, "unsupported value type"); lua_error(L); - } else - j = (int) lua_tonumber(L, i); - assign_internal_value(0, zget_equiv(cur_cs), j); + } + } else { + j = (int) lua_tonumber(L, i); + } + assign_internal_value((isglobal?4:0), zget_equiv(cur_cs), j); } else { lua_pushstring(L, "unsupported tex internal assignment"); lua_error(L); @@ -888,6 +934,40 @@ int do_lastitem(lua_State * L, int cur_code) return retval; } +static int tex_setmathparm (lua_State *L) +{ + int i, j; + scaled k; + int n; + int l = cur_level; + n = lua_gettop(L); + + if ((n == 3) || (n == 4)) { + if (n==4 && lua_isstring(L,1)) { + char *s = (char *)lua_tostring(L,1); + if (strcmp(s,"global")==0) + l = 1; + } + 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); + } + return 0; +} + +static int tex_getmathparm (lua_State *L) +{ + int i, j; + scaled k; + if ((lua_gettop(L) == 2)) { + i = luaL_checkoption(L, 1, NULL, math_param_names); + j = luaL_checkoption(L, 2, NULL, math_style_names); + k = get_math_param (i,j); + lua_pushnumber(L, k); + } + return 1; +} static int getfontname(lua_State * L) { @@ -1310,45 +1390,48 @@ static int tex_enableprimitives(lua_State * L) size_t l; int i; char *pre = (char *) luaL_checklstring(L, 1, &l); - if (lua_istable(L,2)) { + if (lua_istable(L, 2)) { int nncs = no_new_control_sequence; no_new_control_sequence = true; i = 1; while (1) { - lua_rawgeti(L,2,i); - if (lua_isstring(L,3)) { - char *prim = (char *) lua_tostring(L,3); + lua_rawgeti(L, 2, i); + if (lua_isstring(L, 3)) { + char *prim = (char *) lua_tostring(L, 3); str_number s = maketexstring(prim); halfword prim_val = prim_lookup(s); if (prim_val != undefined_primitive) { char *newprim; + integer 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); - strcpy(newprim,pre); - strcat(newprim+l,prim); + if (strncmp(pre, prim, l) != 0) { /* not a prefix */ + newl = strlen(prim) + l; + newprim = (char *) xmalloc(newl + 1); + strcpy(newprim, pre); + strcat(newprim + l, prim); } else { newl = strlen(prim); - newprim = (char *) xmalloc (newl+1); - strcpy(newprim,prim); + newprim = (char *) xmalloc(newl + 1); + strcpy(newprim, prim); } - if (string_lookup(newprim, newl) == static_undefined_control_sequence ) { + 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); } - free (newprim); + free(newprim); } flush_str(s); } else { - lua_pop(L,1); + lua_pop(L, 1); break; } - lua_pop(L,1); + lua_pop(L, 1); i++; } - lua_pop(L,1); /* the table */ + lua_pop(L, 1); /* the table */ no_new_control_sequence = nncs; } else { lua_pushstring(L, "Expected an array of names as second argument"); @@ -1359,11 +1442,12 @@ static int tex_enableprimitives(lua_State * L) } - static const struct luaL_reg texlib[] = { {"write", luacwrite}, {"print", luacprint}, {"sprint", luacsprint}, + {"set", settex}, + {"get", gettex}, {"setdimen", setdimen}, {"getdimen", getdimen}, {"setskip", setskip}, @@ -1401,22 +1485,26 @@ static const struct luaL_reg texlib[] = { {"primitives", tex_primitives}, {"extraprimitives", tex_extraprimitives}, {"enableprimitives", tex_enableprimitives}, + {"setmath", tex_setmathparm}, + {"getmath", tex_getmathparm}, {NULL, NULL} /* sentinel */ }; int luaopen_tex(lua_State * L) { luaL_register(L, "tex", texlib); - make_table(L, "attribute", "getattribute", "setattribute"); - make_table(L, "skip", "getskip", "setskip"); - make_table(L, "dimen", "getdimen", "setdimen"); - make_table(L, "count", "getcount", "setcount"); - make_table(L, "toks", "gettoks", "settoks"); - make_table(L, "box", "getbox", "setbox"); - make_table(L, "lists", "getlist", "setlist"); - make_table(L, "wd", "getboxwd", "setboxwd"); - make_table(L, "ht", "getboxht", "setboxht"); - make_table(L, "dp", "getboxdp", "setboxdp"); + /* *INDENT-OFF* */ + make_table(L, "attribute", "getattribute", "setattribute"); + make_table(L, "skip", "getskip", "setskip"); + make_table(L, "dimen", "getdimen", "setdimen"); + make_table(L, "count", "getcount", "setcount"); + make_table(L, "toks", "gettoks", "settoks"); + make_table(L, "box", "getbox", "setbox"); + make_table(L, "wd", "getboxwd", "setboxwd"); + make_table(L, "ht", "getboxht", "setboxht"); + make_table(L, "dp", "getboxdp", "setboxdp"); + make_table(L, "lists", "getlist", "setlist"); + /* *INDENT-ON* */ /* make the meta entries */ /* fetch it back */ luaL_newmetatable(L, "tex_meta"); diff --git a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c index b81c61f4023..06d1f72359f 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltokenlib.c @@ -22,7 +22,7 @@ #include "tokens.h" static const char _svn_version[] = - "$Id: ltokenlib.c 2015 2009-03-13 19:06:34Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/ltokenlib.c $"; + "$Id: ltokenlib.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/ltokenlib.c $"; extern int get_command_id(char *); diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.c b/Build/source/texk/web2c/luatexdir/lua/luainit.c index f89607530ac..5aecc526921 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luainit.c +++ b/Build/source/texk/web2c/luatexdir/lua/luainit.c @@ -25,7 +25,7 @@ #include <luatexdir/luatexextra.h> static const char _svn_version[] = - "$Id: luainit.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luainit.c $"; + "$Id: luainit.c 2288 2009-04-14 22:56:09Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/luainit.c $"; /* TH: TODO * @@ -43,6 +43,9 @@ static const char _svn_version[] = * SELFAUTOLOC SELFAUTODIR SELFAUTOPARENT progname * */ +extern void mk_shellcmdlist(char *v); +extern int shell_cmd_is_allowed(char **cmd, char **safecmd, char **cmdname); +extern void init_shell_escape(void); extern string normalize_quotes(const_string name, const_string mesg); @@ -172,6 +175,11 @@ 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}, {"debug-format", 0, &debug_format_file, 1}, {"file-line-error-style", 0, &filelineerrorstylep, 1}, {"no-file-line-error-style", 0, &filelineerrorstylep, -1}, @@ -243,6 +251,10 @@ static void parse_options(int argc, char **argv) output_comment[255] = 0; } + } else if (ARGUMENT_IS("shell-restricted")) { + shellenabledp = 1; + restrictedshell = 1; + } else if (ARGUMENT_IS("output-format")) { pdf_output_option = 1; if (strcmp(optarg, "dvi") == 0) { @@ -314,7 +326,7 @@ static void parse_options(int argc, char **argv) "lua by Roberto Ierusalimschy, Waldemar Celes,\n" " Luiz Henrique de Figueiredo\n" "metapost by John Hobby, Taco Hoekwater and friends.\n" - "xpdf by Derek Noonberg (partial)\n" + "xpdf by Derek Noonburg (partial)\n" "fontforge by George Williams (partial)\n\n" "Some extensions to lua and additional lua libraries are used, as well as\n" "libraries for graphic inclusion. More details can be found in the source.\n" @@ -444,6 +456,7 @@ void init_kpse(void) kpse_src_compile); kpse_set_program_name(argv[0], user_progname); + init_shell_escape(); /* set up 'restrictedshell' */ program_name_set = 1; } @@ -504,6 +517,8 @@ void lua_initialize(int ac, char **av) /* parse commandline */ parse_options(ac, av); + if (lua_only) + shellenabledp = true; /* make sure that the locale is 'sane' (for lua) */ putenv("LC_CTYPE=C"); @@ -515,7 +530,7 @@ void lua_initialize(int ac, char **av) luainterpreter(); - prepare_cmdline(Luas, argv, argc, lua_offset); /* collect arguments */ + prepare_cmdline(Luas, argv, argc, lua_offset); /* collect arguments */ if (startup_filename != NULL) { given_file = xstrdup(startup_filename); @@ -577,7 +592,28 @@ void lua_initialize(int ac, char **av) haltonerrorp = false; get_lua_boolean("texconfig", "halt_on_error", &haltonerrorp); + /* restrictedshell */ + char *v1 = NULL; + get_lua_string("texconfig", "shell_escape", &v1); + if (v1) { + if (*v1 == 't' || *v1 == 'y' || *v1 == '1') { + shellenabledp = 1; + } else if (*v1 == 'p') { + shellenabledp = 1; + restrictedshell = 1; + } + } + /* If shell escapes are restricted, get allowed cmds from cnf. */ + if (shellenabledp && restrictedshell == 1) { + v1 = NULL; + get_lua_string("texconfig", "shell_escape_commands", &v1); + if (v1) { + mk_shellcmdlist(v1); + } + } + fix_dumpname(); + } else { if (luainit) { if (given_file) { @@ -596,3 +632,39 @@ void lua_initialize(int ac, char **av) } } } + +void +check_texconfig_init (void) { + if (Luas!=NULL) { + lua_getglobal(Luas, "texconfig"); + if (lua_istable(Luas, -1)) { + lua_getfield(Luas, -1, "init"); + if (lua_isfunction(Luas, -1)) { + int i = lua_pcall(Luas, 0, 0, 0); + if (i != 0) { + /* Can't be more precise here, called before TeX initialization */ + fprintf(stderr, "This went wrong: %s\n", lua_tostring(Luas, -1)); + error(); + } + } + } + } +} + +void write_svnversion(char *v) +{ + char *a_head, *n; + char *a = strdup(v); + int l = strlen("$Id: luatex.web "); + if (a != NULL) { + a_head = a; + if (strlen(a)>l) + a+=l; + n = a; + while (*n!='\0' && *n!=' ') + n++; + *n = '\0'; + fprintf(stdout, " luatex.web v%s", a); + free (a_head); + } +} diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.c b/Build/source/texk/web2c/luatexdir/lua/luanode.c index 0be6547446f..49d46b258f6 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luanode.c +++ b/Build/source/texk/web2c/luatexdir/lua/luanode.c @@ -22,7 +22,7 @@ #include "nodes.h" static const char _svn_version[] = - "$Id: luanode.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luanode.c $"; + "$Id: luanode.c 2284 2009-04-14 12:58:45Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/luanode.c $"; #undef link /* defined by cpascal.h */ #define info(a) fixmem[(a)].hhlh @@ -61,7 +61,10 @@ void lua_node_filter_s(int filterid, char *extrainfo) { lua_State *L = Luas; int s_top = lua_gettop(L); - if (!get_callback(L, callback_defined(filterid))) { + int callback_id = callback_defined(filterid); + if (callback_id<=0) + return; + if (!get_callback(L, callback_id)) { lua_settop(L, s_top); return; } @@ -85,7 +88,7 @@ lua_node_filter(int filterid, int xextrainfo, halfword head_node, lua_State *L = Luas; char *extrainfo = group_code_names[xextrainfo]; int callback_id = callback_defined(filterid); - if (head_node == null || vlink(head_node) == null || callback_id == 0) + if (head_node == null || vlink(head_node) == null || callback_id <= 0) return; if (!get_callback(L, callback_id)) { lua_pop(L, 2); @@ -131,7 +134,7 @@ lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head) int ret = 0; /* failure */ lua_State *L = Luas; int callback_id = callback_defined(linebreak_filter_callback); - if (head_node == null || vlink(head_node) == null || callback_id == 0) + if (head_node == null || vlink(head_node) == null || callback_id <= 0) return ret; if (!get_callback(L, callback_id)) { lua_pop(L, 2); @@ -164,7 +167,7 @@ lua_hpack_filter(halfword head_node, scaled size, int pack_type, int extrainfo) halfword ret; lua_State *L = Luas; int callback_id = callback_defined(hpack_filter_callback); - if (head_node == null || callback_id == 0) + if (head_node == null || callback_id <= 0) return head_node; if (!get_callback(L, callback_id)) { lua_pop(L, 2); @@ -210,7 +213,7 @@ lua_vpack_filter(halfword head_node, scaled size, int pack_type, scaled maxd, } else { callback_id = callback_defined(vpack_filter_callback); } - if (callback_id == 0) { + if (callback_id <= 0) { return head_node; } if (!get_callback(L, callback_id)) { @@ -263,3 +266,69 @@ int visible_last_node_type(int n) return -1; /* this is not right, probably dir nodes! */ return last_known_node + 1; } + +void +lua_pdf_literal (int i) +{ + char *s = NULL; + size_t l = 0; + lua_rawgeti(Luas, LUA_REGISTRYINDEX, i); + s = (char *)lua_tolstring(Luas,-1,&l); + while (l--) { + pdf_room(1); + pdf_buf[pdf_ptr++] = *s++; + } + pdf_buf[pdf_ptr++] = 10; /* pdf_print_nl */ + lua_pop(Luas,1); +} + +void +copy_pdf_literal (pointer r, pointer p) +{ + pdf_literal_type(r) = pdf_literal_type(p); + pdf_literal_mode(r) = pdf_literal_mode(p); + if (pdf_literal_type(p)==normal) { + pdf_literal_data(r) = pdf_literal_data(p); + add_token_ref(pdf_literal_data(p)); + } else { + lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p)); + pdf_literal_data(r) = luaL_ref(Luas, LUA_REGISTRYINDEX); + } +} + + +void +free_pdf_literal (pointer p) +{ + if (pdf_literal_type(p)==normal) { + delete_token_ref(pdf_literal_data(p)); + } else { + luaL_unref(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p)); + } +} + +void +show_pdf_literal (pointer p) +{ + tprint_esc("pdfliteral"); + switch (pdf_literal_mode(p)) { + case set_origin: + break; + case direct_page: + tprint(" page"); + break; + case direct_always: + tprint(" direct"); + break; + default: + tconfusion("literal2"); + break; + } + if (pdf_literal_type(p)==normal) { + print_mark(pdf_literal_data(p)); + } else { + lua_rawgeti(Luas, LUA_REGISTRYINDEX, pdf_literal_data(p)); + tprint((char *)lua_tostring(Luas,-1)); + lua_pop(Luas,1); + } +} diff --git a/Build/source/texk/web2c/luatexdir/lua/luastuff.c b/Build/source/texk/web2c/luatexdir/lua/luastuff.c index 49298ea2fc5..a8ac317b5f1 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luastuff.c +++ b/Build/source/texk/web2c/luatexdir/lua/luastuff.c @@ -21,7 +21,7 @@ #include <ptexlib.h> static const char _svn_version[] = - "$Id: luastuff.c 2064 2009-03-20 13:13:14Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luastuff.c $"; + "$Id: luastuff.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/luastuff.c $"; lua_State *Luas = NULL; @@ -71,7 +71,7 @@ const char *getS(lua_State * L, void *ud, size_t * size) void *my_luaalloc(void *ud, void *ptr, size_t osize, size_t nsize) { void *ret = NULL; - (void)ud; /* for -Wunused */ + (void) ud; /* for -Wunused */ if (nsize == 0) free(ptr); else @@ -88,6 +88,34 @@ static int my_luapanic(lua_State * L) return 0; } +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, + {"package", luaopen_package}, + {"table", luaopen_table}, + {"io", luaopen_io}, + {"os", luaopen_os}, + {"string", luaopen_string}, + {"math", luaopen_math}, + {"debug", luaopen_debug}, + {"unicode", luaopen_unicode}, + {"zip", luaopen_zip}, + {"lpeg", luaopen_lpeg}, + {"md5", luaopen_md5}, + {"lfs", luaopen_lfs}, + {"profiler", luaopen_profiler}, + {NULL, NULL} +}; + + +static void do_openlibs(lua_State * L) +{ + const luaL_Reg *lib = lualibs; + for (; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } +} void luainterpreter(void) { @@ -99,7 +127,7 @@ void luainterpreter(void) } lua_atpanic(L, &my_luapanic); - luaL_openlibs(L); + do_openlibs(L); /* does all the 'simple' libraries */ open_oslibext(L, safer_option); @@ -108,16 +136,6 @@ void luainterpreter(void) lua_setfield(L, -2, "cpath"); lua_pop(L, 1); /* pop the table */ - /*luaopen_unicode(L); */ - lua_pushcfunction(L, luaopen_unicode); - lua_pushstring(L, "unicode"); - lua_call(L, 1, 0); - - /*luaopen_zip(L); */ - lua_pushcfunction(L, luaopen_zip); - lua_pushstring(L, "zip"); - lua_call(L, 1, 0); - /* luasockets */ /* socket and mime are a bit tricky to open because * they use a load-time dependency that has to be @@ -145,53 +163,33 @@ void luainterpreter(void) luatex_socketlua_open(L); /* preload the pure lua modules */ } - - /*luaopen_lpeg(L); */ - lua_pushcfunction(L, luaopen_lpeg); - lua_pushstring(L, "lpeg"); - lua_call(L, 1, 0); - - /*luaopen_md5(L); */ - lua_pushcfunction(L, luaopen_md5); - lua_pushstring(L, "md5"); - lua_call(L, 1, 0); - - /*luaopen_lfs(L); */ - lua_pushcfunction(L, luaopen_lfs); - lua_pushstring(L, "lfs"); - lua_call(L, 1, 0); - /* zlib. slightly odd calling convention */ luaopen_zlib(L); lua_setglobal(L, "zlib"); luaopen_gzip(L); - /* fontforge */ - luaopen_ff(L); - /* profiler, from kepler */ - luaopen_profiler(L); + /* our own libraries */ + luaopen_ff(L); luaopen_pdf(L); luaopen_tex(L); luaopen_token(L); luaopen_node(L); luaopen_texio(L); luaopen_kpse(L); - luaopen_callback(L); - lua_createtable(L, 0, 0); - lua_setglobal(L, "texconfig"); - luaopen_lua(L, startup_filename); luaopen_stats(L); luaopen_font(L); luaopen_lang(L); + luaopen_mplib(L); /* luaopen_img(L); */ lua_pushcfunction(L, luaopen_img); lua_pushstring(L, "img"); lua_call(L, 1, 0); - luaopen_mplib(L); + lua_createtable(L, 0, 0); + lua_setglobal(L, "texconfig"); if (safer_option) { /* disable some stuff if --safer */ @@ -295,27 +293,27 @@ void luacall(int p, int nameptr) if (ls.size > 0) { if (nameptr > 0) { lua_id = tokenlist_to_cstring(nameptr, 1, &l); - } else if (nameptr<0) { - char *tmp = get_lua_name((nameptr+65536)); - if (tmp!=NULL) + } else if (nameptr < 0) { + char *tmp = get_lua_name((nameptr + 65536)); + if (tmp != NULL) lua_id = xstrdup(tmp); else lua_id = xstrdup("\\latelua "); } else { lua_id = xmalloc(20); - snprintf((char *) lua_id, 20, "\\latelua ") ; + snprintf((char *) lua_id, 20, "\\latelua "); } i = lua_load(Luas, getS, &ls, lua_id); if (i != 0) { Luas = luatex_error(Luas, (i == LUA_ERRSYNTAX ? 0 : 1)); } else { - int base = lua_gettop(Luas); /* function index */ + int base = lua_gettop(Luas); /* function index */ lua_checkstack(Luas, 1); - lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ - lua_insert(Luas, base); /* put it under chunk */ + lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ + lua_insert(Luas, base); /* put it under chunk */ i = lua_pcall(Luas, 0, 0, base); - lua_remove(Luas, base); /* remove traceback function */ + lua_remove(Luas, base); /* remove traceback function */ if (i != 0) { lua_gc(Luas, LUA_GCCOLLECT, 0); Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1)); @@ -332,7 +330,7 @@ void luatokencall(int p, int nameptr) int i, l; char *s = NULL; char *lua_id; - assert (Luas); + assert(Luas); l = 0; lua_active++; s = tokenlist_to_cstring(p, 1, &l); @@ -341,9 +339,9 @@ void luatokencall(int p, int nameptr) if (ls.size > 0) { if (nameptr > 0) { lua_id = tokenlist_to_cstring(nameptr, 1, &l); - } else if (nameptr<0) { - char *tmp = get_lua_name((nameptr+65536)); - if (tmp!=NULL) + } else if (nameptr < 0) { + char *tmp = get_lua_name((nameptr + 65536)); + if (tmp != NULL) lua_id = xstrdup(tmp); else lua_id = xstrdup("\\directlua "); @@ -355,12 +353,12 @@ void luatokencall(int p, int nameptr) if (i != 0) { Luas = luatex_error(Luas, (i == LUA_ERRSYNTAX ? 0 : 1)); } else { - int base = lua_gettop(Luas); /* function index */ + int base = lua_gettop(Luas); /* function index */ lua_checkstack(Luas, 1); - lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ - lua_insert(Luas, base); /* put it under chunk */ + lua_pushcfunction(Luas, lua_traceback); /* push traceback function */ + lua_insert(Luas, base); /* put it under chunk */ i = lua_pcall(Luas, 0, 0, base); - lua_remove(Luas, base); /* remove traceback function */ + lua_remove(Luas, base); /* remove traceback function */ if (i != 0) { lua_gc(Luas, LUA_GCCOLLECT, 0); Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1)); diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex.c b/Build/source/texk/web2c/luatexdir/lua/luatex.c index 24b928fba45..41987c681cc 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatex.c @@ -22,7 +22,7 @@ #include <zlib.h> static const char _svn_version[] = - "$Id: luatex.c 2028 2009-03-14 18:50:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luatex.c $"; + "$Id: luatex.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/luatex.c $"; /* do this aleph stuff here, for now */ diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.c b/Build/source/texk/web2c/luatexdir/lua/luatoken.c index 4182d94e6fe..c77b2a5f049 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatoken.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.c @@ -24,7 +24,7 @@ #include "commands.h" static const char _svn_version[] = - "$Id: luatoken.c 2079 2009-03-22 10:15:03Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/luatoken.c $"; + "$Id: luatoken.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/luatoken.c $"; command_item command_names[] = { {"relax", relax_cmd, NULL}, @@ -94,6 +94,8 @@ command_item command_names[] = { {"ex_space", ex_space_cmd, NULL}, {"no_boundary", no_boundary_cmd, NULL}, {"radical", radical_cmd, NULL}, + {"super_sub_script", super_sub_script_cmd, NULL}, + {"math_shift_cs", math_shift_cs_cmd, NULL}, {"end_cs_name", end_cs_name_cmd, NULL}, {"char_ghost", char_ghost_cmd, NULL}, {"assign_local_box", assign_local_box_cmd, NULL}, diff --git a/Build/source/texk/web2c/luatexdir/lua/texluac.c b/Build/source/texk/web2c/luatexdir/lua/texluac.c index d4295aba6ae..bac9559741f 100644 --- a/Build/source/texk/web2c/luatexdir/lua/texluac.c +++ b/Build/source/texk/web2c/luatexdir/lua/texluac.c @@ -46,7 +46,7 @@ #include <../lua51/lundump.h> static const char _svn_version[] = - "$Id: texluac.c 1226 2008-05-02 16:11:02Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/lua/texluac.c $"; + "$Id: texluac.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/texluac.c $"; #define PROGNAME "texluac" /* default program name */ #define OUTPUT PROGNAME ".out" /* default output file */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/Makefile b/Build/source/texk/web2c/luatexdir/lua51/Makefile index 55bdc11178f..301c703b503 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/Makefile +++ b/Build/source/texk/web2c/luatexdir/lua51/Makefile @@ -7,11 +7,12 @@ # Your platform. See PLATS for possible values. PLAT= none -LOCALCFLAGS= $(MYCFLAGS) $(COCOCFLAGS) +CC= gcc +CFLAGS= -O2 -Wall $(MYCFLAGS) $(COCOCFLAGS) AR= ar rcu RANLIB= ranlib RM= rm -f -LIBS= $(XLDFLAGS) -lm $(MYLIBS) +LIBS= -lm $(MYLIBS) MYCFLAGS= MYLDFLAGS= @@ -28,10 +29,9 @@ COCOCFLAGS= #COCOCFLAGS= -DCOCO_DISABLE # -- Coco ========= - # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= -PLATS= aix ansi bsd generic linux macosx mingw posix solaris +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris # ++ Coco ========= COCO_O= lcoco.o @@ -76,14 +76,12 @@ clean: $(RM) $(ALL_T) $(ALL_O) depend: - @$(CC) $(LOCALCFLAGS) $(CFLAGS) $(XCFLAGS) -MM l*.c print.c + @$(CC) $(CFLAGS) -MM l*.c print.c echo: @echo "PLAT = $(PLAT)" @echo "CC = $(CC)" - @echo "LOCALCFLAGS = $(LOCALCFLAGS)" @echo "CFLAGS = $(CFLAGS)" - @echo "XCFLAGS = $(XCFLAGS)" @echo "AR = $(AR)" @echo "RANLIB = $(RANLIB)" @echo "RM = $(RM)" @@ -94,47 +92,43 @@ echo: # convenience targets for popular platforms none: - @echo "Please choose a platform: $(PLATS)" + @echo "Please choose a platform:" + @echo " $(PLATS)" aix: - $(MAKE) a CC="xlc" LOCALCFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" + $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" ansi: - $(MAKE) a MYCFLAGS=-DLUA_ANSI + $(MAKE) all MYCFLAGS=-DLUA_ANSI bsd: - $(MAKE) a MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" + +freebsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" generic: - $(MAKE) a MYCFLAGS= + $(MAKE) all MYCFLAGS= linux: - $(MAKE) a MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" macosx: - $(MAKE) a MYCFLAGS=-DLUA_USE_MACOSX -# use this on Mac OS X 10.4 -# $(MAKE) a MYCFLAGS="-DLUA_USE_MACOSX -DLUA_USE_READLINE" MYLIBS="-lreadline" + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" +# use this on Mac OS X 10.3- +# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX mingw: $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe - -mingwcross: - $(MAKE) "LUA_A=liblua.a" "LUA_T=lua.exe" \ - MYCFLAGS= MYLIBS= lua.exe - + $(MAKE) "LUAC_T=luac.exe" luac.exe posix: - $(MAKE) a MYCFLAGS=-DLUA_USE_POSIX + $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX solaris: - $(MAKE) a MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" - -.c.o: - $(CC) $(LOCALCFLAGS) $(CFLAGS) $(XCFLAGS) -c $< - + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" # list targets that do not create files (but not all makes understand .PHONY) .PHONY: all $(PLATS) default o a clean depend echo none @@ -171,8 +165,7 @@ llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ ltm.h lzio.h lmem.h lcoco.h ldo.h -loadlib.o: loadlib.c lauxlib.h lua.h luaconf.h lobject.h llimits.h \ - lualib.h +loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ ltm.h lzio.h lmem.h lcoco.h lstring.h lgc.h lvm.h lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h diff --git a/Build/source/texk/web2c/luatexdir/lua51/lapi.c b/Build/source/texk/web2c/luatexdir/lua51/lapi.c index e99ea7a31e6..e8347a28c4d 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lapi.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.55 2006/06/07 12:37:17 roberto Exp $ +** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -93,15 +93,14 @@ void luaA_pushobject (lua_State *L, const TValue *o) { LUA_API int lua_checkstack (lua_State *L, int size) { - int res; + int res = 1; lua_lock(L); - if ((L->top - L->base + size) > LUAI_MAXCSTACK) + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) res = 0; /* stack overflow */ - else { + else if (size > 0) { luaD_checkstack(L, size); if (L->ci->top < L->top + size) L->ci->top = L->top + size; - res = 1; } lua_unlock(L); return res; @@ -749,7 +748,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { res = 0; break; } - luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); L->top--; lua_unlock(L); return res; @@ -925,10 +924,13 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g->GCthreshold = g->totalbytes - a; else g->GCthreshold = 0; - while (g->GCthreshold <= g->totalbytes) + while (g->GCthreshold <= g->totalbytes) { luaC_step(L); - if (g->gcstate == GCSpause) /* end of cycle? */ - res = 1; /* signal it */ + if (g->gcstate == GCSpause) { /* end of cycle? */ + res = 1; /* signal it */ + break; + } + } break; } case LUA_GCSETPAUSE: { diff --git a/Build/source/texk/web2c/luatexdir/lua51/lapi.h b/Build/source/texk/web2c/luatexdir/lua51/lapi.h index 9d1d435649c..2c3fab244ef 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lapi.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lapi.h @@ -1,5 +1,5 @@ /* -** $Id: lapi.h,v 2.2 2005/04/25 19:24:10 roberto Exp $ +** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions from Lua API ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lauxlib.c b/Build/source/texk/web2c/luatexdir/lua51/lauxlib.c index 96a6b85237a..10f14e2c088 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lauxlib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.159 2006/03/21 19:31:09 roberto Exp $ +** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -244,7 +244,7 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname, if (libname) { int size = libsize(l); /* check whether lib already exists */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", size); + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); lua_getfield(L, -1, libname); /* get _LOADED[libname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ @@ -535,7 +535,7 @@ static const char *getF (lua_State *L, void *ud, size_t *size) { return "\n"; } if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f); + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); return (*size > 0) ? lf->buff : NULL; } @@ -570,9 +570,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ if (c == '\n') c = getc(lf.f); } - if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */ - fclose(lf.f); - lf.f = fopen(filename, "rb"); /* reopen in binary mode */ + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ if (lf.f == NULL) return errfile(L, "reopen", fnameindex); /* skip eventual `#!...' */ while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; @@ -581,7 +580,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { ungetc(c, lf.f); status = lua_load(L, getF, &lf, lua_tostring(L, -1)); readstatus = ferror(lf.f); - if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ + if (filename) fclose(lf.f); /* close file (even in case of errors) */ if (readstatus) { lua_settop(L, fnameindex); /* ignore results from `lua_load' */ return errfile(L, "read", fnameindex); diff --git a/Build/source/texk/web2c/luatexdir/lua51/lauxlib.h b/Build/source/texk/web2c/luatexdir/lua51/lauxlib.h index 1f3430863e4..34258235dbe 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lauxlib.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.88 2006/04/12 20:31:15 roberto Exp $ +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lbaselib.c b/Build/source/texk/web2c/luatexdir/lua51/lbaselib.c index a1208d670b4..2366a021abf 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lbaselib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.191a 2006/06/02 15:34:00 roberto Exp $ +** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -347,10 +347,12 @@ static int luaB_unpack (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); i = luaL_optint(L, 2, 1); e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ n = e - i + 1; /* number of elements */ - if (n <= 0) return 0; /* empty range */ - luaL_checkstack(L, n, "table too big to unpack"); - for (; i<=e; i++) /* push arg[i...e] */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ lua_rawgeti(L, 1, i); return n; } @@ -480,19 +482,55 @@ static const luaL_Reg base_funcs[] = { ** ======================================================= */ +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = + {"running", "suspended", "normal", "dead"}; + +static int costatus (lua_State *L, lua_State *co) { + if (L == co) return CO_RUN; + switch (lua_status(co)) { + case LUA_YIELD: + return CO_SUS; + case 0: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} + + static int auxresume (lua_State *L, lua_State *co, int narg) { - int status; + int status = costatus(L, co); if (!lua_checkstack(co, narg)) luaL_error(L, "too many arguments to resume"); - if (lua_status(co) == 0 && lua_gettop(co) == 0) { - lua_pushliteral(L, "cannot resume dead coroutine"); + if (status != CO_SUS) { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); return -1; /* error flag */ } lua_xmove(L, co, narg); status = lua_resume(co, narg); if (status == 0 || status == LUA_YIELD) { int nres = lua_gettop(co); - if (!lua_checkstack(L, nres)) + if (!lua_checkstack(L, nres + 1)) luaL_error(L, "too many results to resume"); lua_xmove(co, L, nres); /* move yielded values */ return nres; @@ -576,39 +614,10 @@ static int luaB_yield (lua_State *L) { } -static int luaB_costatus (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); - if (L == co) lua_pushliteral(L, "running"); - else { - switch (lua_status(co)) { - case LUA_YIELD: - lua_pushliteral(L, "suspended"); - break; - case 0: { - lua_Debug ar; - if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ - lua_pushliteral(L, "normal"); /* it is running */ - else if (lua_gettop(co) == 0) - lua_pushliteral(L, "dead"); - else - lua_pushliteral(L, "suspended"); /* initial state */ - break; - } - default: /* some error occured */ - lua_pushliteral(L, "dead"); - break; - } - } - return 1; -} - - static int luaB_corunning (lua_State *L) { if (lua_pushthread(L)) - return 0; /* main thread is not a coroutine */ - else - return 1; + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua51/lcoco.c b/Build/source/texk/web2c/luatexdir/lua51/lcoco.c index f7a4b86c5bc..3399ef8aedf 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lcoco.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lcoco.c @@ -1,5 +1,5 @@ /* -** Copyright (C) 2004-2007 Mike Pall. All rights reserved. +** Copyright (C) 2004-2008 Mike Pall. All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining ** a copy of this software and associated documentation files (the @@ -144,6 +144,52 @@ static inline void coco_switch(coco_ctx from, coco_ctx to) coco->arg0 = (size_t)(a0); #define COCO_STATE_HEAD size_t arg0; +#elif defined(__x86_64__) + +void coco_wrap_main(void); +__asm__ ( +"\t.text\n" +#ifdef __MACH__ +"\t.private_extern _coco_wrap_main\n" +"_coco_wrap_main:\n" +#else +".local coco_wrap_main\n" +"\t.type coco_wrap_main, @function\n" +"coco_wrap_main:\n" +#endif +"\tmovq %r12, %rax\n" +"\tmovq %r13, %rdi\n" +"\tjmpq *%rax\n" +); + +typedef void *coco_ctx[8]; /* rip, rsp, rbp, rbx, r12, r13, r14, r15 */ +static inline void coco_switch(coco_ctx from, coco_ctx to) +{ + __asm__ __volatile__ ( + "leaq 1f(%%rip), %%rax\n\t" + "movq %%rax, (%0)\n\t" "movq %%rsp, 8(%0)\n\t" "movq %%rbp, 16(%0)\n\t" + "movq %%rbx, 24(%0)\n\t" "movq %%r12, 32(%0)\n\t" "movq %%r13, 40(%0)\n\t" + "movq %%r14, 48(%0)\n\t" "movq %%r15, 56(%0)\n\t" + "movq 56(%1), %%r15\n\t" "movq 48(%1), %%r14\n\t" "movq 40(%1), %%r13\n\t" + "movq 32(%1), %%r12\n\t" "movq 24(%1), %%rbx\n\t" "movq 16(%1), %%rbp\n\t" + "movq 8(%1), %%rsp\n\t" "jmpq *(%1)\n" "1:\n" + : "+S" (from), "+D" (to) : + : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "memory", "cc"); +} + +#define COCO_CTX coco_ctx +#define COCO_SWITCH(from, to) coco_switch(from, to); +#define COCO_MAKECTX(coco, buf, func, stack, a0) \ + buf[0] = (void *)(coco_wrap_main); \ + buf[1] = (void *)(stack); \ + buf[2] = (void *)0; \ + buf[3] = (void *)0; \ + buf[4] = (void *)(func); \ + buf[5] = (void *)(a0); \ + buf[6] = (void *)0; \ + buf[7] = (void *)0; \ + stack[0] = 0xdeadc0c0deadc0c0; /* Dummy return address. */ \ + #elif __mips && _MIPS_SIM == _MIPS_SIM_ABI32 && !defined(__mips_eabi) /* No way to avoid the function prologue with inline assembler. So use this: */ @@ -233,7 +279,7 @@ typedef void *coco_ctx[2]; /* ra, sp */ buf[4] = (int)(stack); \ buf[3] = 0; \ COCO_SETJMP_X86(coco, stack, a0) -#elif defined(__MACH__) && defined(_BSD_I386_SETJMP_H_) /* x86-macosx */ +#elif defined(__MACH__) && defined(_BSD_I386_SETJMP_H) /* x86-macosx */ #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ buf[12] = (int)(func); \ buf[9] = (int)(stack); \ @@ -248,14 +294,7 @@ typedef void *coco_ctx[2]; /* ra, sp */ #define COCO_MAIN_PARAM \ int _a, int _b, int _c, int _d, int _e, int _f, lua_State *L -#if __GLIBC__ == 2 && defined(JB_RSP) /* x64-linux-glibc2 */ -#define COCO_PATCHCTX(coco, buf, func, stack, a0) \ - buf->__jmpbuf[JB_PC] = (long)(func); \ - buf->__jmpbuf[JB_RSP] = (long)(stack); \ - buf->__jmpbuf[JB_RBP] = 0; \ - stack[0] = 0xdeadc0c0; /* Dummy return address. */ \ - coco->arg0 = (size_t)(a0); -#elif defined(__solaris__) && _JBLEN == 8 /* x64-solaris */ +#if defined(__solaris__) && _JBLEN == 8 /* x64-solaris */ #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ buf[7] = (long)(func); \ buf[6] = (long)(stack); \ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lcoco.h b/Build/source/texk/web2c/luatexdir/lua51/lcoco.h index 6e87a8d3c19..4fb6bca4b32 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lcoco.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lcoco.h @@ -1,6 +1,6 @@ /* ** Lua/Coco glue. -** Copyright (C) 2004-2007 Mike Pall. See copyright notice in lcoco.c +** Copyright (C) 2004-2008 Mike Pall. See copyright notice in lcoco.c */ #if defined(__OpenBSD__) @@ -16,8 +16,8 @@ #ifndef lcoco_h #define lcoco_h -#define LUACOCO_VERSION "Coco 1.1.3" -#define LUACOCO_VERSION_NUM 10103 +#define LUACOCO_VERSION "Coco 1.1.5" +#define LUACOCO_VERSION_NUM 10105 /* Exported C API to add a C stack to a coroutine. */ LUA_API lua_State *lua_newcthread(lua_State *L, int cstacksize); diff --git a/Build/source/texk/web2c/luatexdir/lua51/lcode.c b/Build/source/texk/web2c/luatexdir/lua51/lcode.c index 9ce515ab648..cff626b7fa6 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lcode.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.25a 2006/03/21 19:28:49 roberto Exp $ +** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -699,7 +699,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; switch (op) { case OPR_MINUS: { - if (e->k == VK) + if (!isnumeral(e)) luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ codearith(fs, OP_UNM, e, &e2); break; diff --git a/Build/source/texk/web2c/luatexdir/lua51/lcode.h b/Build/source/texk/web2c/luatexdir/lua51/lcode.h index c02cb2b726f..b941c607212 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lcode.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.48 2006/03/21 19:28:03 roberto Exp $ +** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/ldblib.c b/Build/source/texk/web2c/luatexdir/lua51/ldblib.c index 26a19b6a6f6..67de1222a94 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ldblib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.104 2005/12/29 15:32:11 roberto Exp $ +** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -255,24 +255,25 @@ static void gethooktable (lua_State *L) { static int db_sethook (lua_State *L) { - int arg; + int arg, mask, count; + lua_Hook func; lua_State *L1 = getthread(L, &arg); if (lua_isnoneornil(L, arg+1)) { lua_settop(L, arg+1); - lua_sethook(L1, NULL, 0, 0); /* turn off hooks */ + func = NULL; mask = 0; count = 0; /* turn off hooks */ } else { const char *smask = luaL_checkstring(L, arg+2); - int count = luaL_optint(L, arg+3, 0); luaL_checktype(L, arg+1, LUA_TFUNCTION); - lua_sethook(L1, hookf, makemask(smask, count), count); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); } - gethooktable(L1); - lua_pushlightuserdata(L1, L1); + gethooktable(L); + lua_pushlightuserdata(L, L1); lua_pushvalue(L, arg+1); - lua_xmove(L, L1, 1); - lua_rawset(L1, -3); /* set new hook */ - lua_pop(L1, 1); /* remove hook table */ + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ return 0; } @@ -286,11 +287,10 @@ static int db_gethook (lua_State *L) { if (hook != NULL && hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { - gethooktable(L1); - lua_pushlightuserdata(L1, L1); - lua_rawget(L1, -2); /* get hook */ - lua_remove(L1, -2); /* remove hook table */ - lua_xmove(L1, L, 1); + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ } lua_pushstring(L, unmakemask(mask, buff)); lua_pushinteger(L, lua_gethookcount(L1)); diff --git a/Build/source/texk/web2c/luatexdir/lua51/ldebug.c b/Build/source/texk/web2c/luatexdir/lua51/ldebug.c index d956f3df058..abb3da4a021 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ldebug.c +++ b/Build/source/texk/web2c/luatexdir/lua51/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.29a 2005/12/22 16:19:56 roberto Exp $ +** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -277,12 +277,12 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { static int precheck (const Proto *pt) { check(pt->maxstacksize <= MAXSTACK); - lua_assert(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); - lua_assert(!(pt->is_vararg & VARARG_NEEDSARG) || + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + check(!(pt->is_vararg & VARARG_NEEDSARG) || (pt->is_vararg & VARARG_HASARG)); check(pt->sizeupvalues <= pt->nups); check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); - check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); return 1; } @@ -348,9 +348,18 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { int dest = pc+1+b; check(0 <= dest && dest < pt->sizecode); if (dest > 0) { - /* cannot jump to a setlist count */ - Instruction d = pt->code[dest-1]; - check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)); + int j; + /* check that it does not jump to a setlist count; this + is tricky, because the count from a previous setlist may + have the same value of an invalid setlist; so, we must + go all the way back to the first of them (if any) */ + for (j = 0; j < dest; j++) { + Instruction d = pt->code[dest-1-j]; + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; + } + /* if 'j' is even, previous value is not a setlist (even if + it looks like one) */ + check((j&1) == 0); } } break; @@ -365,7 +374,11 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { } switch (op) { case OP_LOADBOOL: { - check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ + if (c == 1) { /* does it jump? */ + check(pc+2 < pt->sizecode); /* check its jump */ + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || + GETARG_C(pt->code[pc+1]) != 0); + } break; } case OP_LOADNIL: { @@ -430,7 +443,10 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { } case OP_SETLIST: { if (b > 0) checkreg(pt, a + b); - if (c == 0) pc++; + if (c == 0) { + pc++; + check(pc < pt->sizecode - 1); + } break; } case OP_CLOSURE: { @@ -565,8 +581,8 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { - if (ttisstring(p1)) p1 = p2; - lua_assert(!ttisstring(p1)); + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); luaG_typeerror(L, p1, "concatenate"); } diff --git a/Build/source/texk/web2c/luatexdir/lua51/ldebug.h b/Build/source/texk/web2c/luatexdir/lua51/ldebug.h index 9c76aa10f0a..ba28a97248e 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ldebug.h +++ b/Build/source/texk/web2c/luatexdir/lua51/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 2.3 2005/04/25 19:24:10 roberto Exp $ +** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/ldo.c b/Build/source/texk/web2c/luatexdir/lua51/ldo.c index ab86fb70e8d..91144137788 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ldo.c +++ b/Build/source/texk/web2c/luatexdir/lua51/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.38 2006/06/05 19:36:14 roberto Exp $ +** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -332,7 +332,7 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ luaD_callhook(L, LUA_HOOKRET, -1); if (f_isLua(L->ci)) { /* Lua function? */ - while (L->ci->tailcalls--) /* call hook for eventual tail calls */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ luaD_callhook(L, LUA_HOOKTAILRET, -1); } return restorestack(L, fr); @@ -417,12 +417,8 @@ static int resume_error (lua_State *L, const char *msg) { LUA_API int lua_resume (lua_State *L, int nargs) { int status; lua_lock(L); - if (L->status != LUA_YIELD) { - if (L->status != 0) - return resume_error(L, "cannot resume dead coroutine"); - else if (L->ci != L->base_ci) + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) return resume_error(L, "cannot resume non-suspended coroutine"); - } luai_userstateresume(L, nargs); lua_assert(L->errfunc == 0 && L->nCcalls == 0); status = luaD_rawrunprotected(L, resume, L->top - nargs); diff --git a/Build/source/texk/web2c/luatexdir/lua51/ldo.h b/Build/source/texk/web2c/luatexdir/lua51/ldo.h index b2de92bb807..98fddac59fb 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ldo.h +++ b/Build/source/texk/web2c/luatexdir/lua51/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 2.7 2005/08/24 16:15:49 roberto Exp $ +** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/ldump.c b/Build/source/texk/web2c/luatexdir/lua51/ldump.c index f08277d3ac4..7ff01cc565a 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ldump.c +++ b/Build/source/texk/web2c/luatexdir/lua51/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 1.15 2006/02/16 15:53:49 lhf Exp $ +** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -62,12 +62,12 @@ static void DumpString(const TString* s, DumpState* D) { if (s==NULL || getstr(s)==NULL) { - size_t size=0; + unsigned int size=0; DumpVar(size,D); } else { - size_t size=s->tsv.len+1; /* include trailing '\0' */ + unsigned int size=s->tsv.len+1; /* include trailing '\0' */ DumpVar(size,D); DumpBlock(getstr(s),size,D); } diff --git a/Build/source/texk/web2c/luatexdir/lua51/lfunc.c b/Build/source/texk/web2c/luatexdir/lua51/lfunc.c index 05bd5ff50fa..813e88f5831 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lfunc.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.12a 2005/12/22 16:19:56 roberto Exp $ +** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lfunc.h b/Build/source/texk/web2c/luatexdir/lua51/lfunc.h index 2e02419bd6b..a68cf5151cb 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lfunc.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 2.4 2005/04/25 19:24:10 roberto Exp $ +** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lgc.c b/Build/source/texk/web2c/luatexdir/lua51/lgc.c index 2d24a127ac6..d9e0b78294e 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lgc.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.38 2006/05/24 14:34:06 roberto Exp $ +** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lgc.h b/Build/source/texk/web2c/luatexdir/lua51/lgc.h index 5f69acb1e3b..5a8dc605b31 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lgc.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.15 2005/08/24 16:15:49 roberto Exp $ +** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/linit.c b/Build/source/texk/web2c/luatexdir/lua51/linit.c index 483d9c8c282..c1f90dfab71 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/linit.c +++ b/Build/source/texk/web2c/luatexdir/lua51/linit.c @@ -1,5 +1,5 @@ /* -** $Id: linit.c,v 1.14 2005/12/29 15:32:11 roberto Exp $ +** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ ** Initialization of libraries for lua.c ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/liolib.c b/Build/source/texk/web2c/luatexdir/lua51/liolib.c index b98fd9a0448..e79ed1cb2e2 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/liolib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.73 2006/05/08 20:14:16 roberto Exp $ +** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -51,7 +51,7 @@ static void fileerror (lua_State *L, int arg, const char *filename) { } -#define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) static int io_type (lua_State *L) { @@ -70,7 +70,7 @@ static int io_type (lua_State *L) { static FILE *tofile (lua_State *L) { - FILE **f = topfile(L); + FILE **f = tofilep(L); if (*f == NULL) luaL_error(L, "attempt to use a closed file"); return *f; @@ -93,19 +93,31 @@ static FILE **newfile (lua_State *L) { /* -** this function has a separated environment, which defines the -** correct __close for 'popen' files +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close 'popen' files */ static int io_pclose (lua_State *L) { - FILE **p = topfile(L); + FILE **p = tofilep(L); int ok = lua_pclose(L, *p); *p = NULL; return pushresult(L, ok, NULL); } +/* +** function to close regular files +*/ static int io_fclose (lua_State *L) { - FILE **p = topfile(L); + FILE **p = tofilep(L); int ok = (fclose(*p) == 0); *p = NULL; return pushresult(L, ok, NULL); @@ -128,18 +140,18 @@ static int io_close (lua_State *L) { static int io_gc (lua_State *L) { - FILE *f = *topfile(L); - /* ignore closed files and standard files */ - if (f != NULL && f != stdin && f != stdout && f != stderr) + FILE *f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) aux_close(L); return 0; } static int io_tostring (lua_State *L) { - FILE *f = *topfile(L); + FILE *f = *tofilep(L); if (f == NULL) - lua_pushstring(L, "file (closed)"); + lua_pushliteral(L, "file (closed)"); else lua_pushfstring(L, "file (%p)", f); return 1; @@ -154,21 +166,11 @@ static int io_open (lua_State *L) { return (*pf == NULL) ? pushresult(L, 0, filename) : 1; } -static int io_open_ro (lua_State *L) { - FILE **pf; - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - if ((strcmp(mode,"r")!= 0)&&(strcmp(mode,"rb")!=0)) - return pushresult(L, 0, filename); - pf = newfile(L); - *pf = fopen(filename, mode); - return (*pf == NULL) ? pushresult(L, 0, filename) : 1; -} - - - - +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); @@ -285,7 +287,7 @@ static int test_eof (lua_State *L, FILE *f) { return (c != EOF); } -#if 0 + static int read_line (lua_State *L, FILE *f) { luaL_Buffer b; luaL_buffinit(L, &b); @@ -294,7 +296,7 @@ static int read_line (lua_State *L, FILE *f) { char *p = luaL_prepbuffer(&b); if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ luaL_pushresult(&b); /* close buffer */ - return (lua_strlen(L, -1) > 0); /* check whether read something */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ } l = strlen(p); if (l == 0 || p[l-1] != '\n') @@ -306,35 +308,6 @@ static int read_line (lua_State *L, FILE *f) { } } } -#endif - -/* this new version does not care wether the file has - line endings using an 'alien' convention */ - -static int new_read_line (lua_State *L, FILE *f) { - luaL_Buffer buf; - int c, d; - luaL_buffinit(L, &buf); - while (1) { - c = fgetc(f); - if (c == EOF) { - luaL_pushresult(&buf); /* close buffer */ - return (lua_strlen(L, -1) > 0); /* check whether read something */ - }; - if (c == '\n') { - break; - } else if (c == '\r') { - d = fgetc(f); - if (d != EOF && d != '\n') - ungetc(d,f); - break; - } else { - luaL_addchar(&buf,c); - } - } - luaL_pushresult(&buf); /* close buffer */ - return 1; -} static int read_chars (lua_State *L, FILE *f, size_t n) { @@ -351,32 +324,7 @@ static int read_chars (lua_State *L, FILE *f, size_t n) { n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ - return (n == 0 || lua_strlen(L, -1) > 0); -} - -static int read_all (lua_State *L, FILE *f) { - /* attempt to speed up reading whole files */ - size_t rlen; /* how much to read */ - size_t nr; /* number of chars actually read */ - size_t 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); - if (p != NULL) { - nr = fread(p, sizeof(char), rlen, f); - lua_pushlstring(L,p,nr); - free(p); - return 1; - } - } - if (old>0) - fseek(f,old,SEEK_SET); - return read_chars(L,f, ~((size_t)0)); + return (n == 0 || lua_objlen(L, -1) > 0); } @@ -386,7 +334,7 @@ static int g_read (lua_State *L, FILE *f, int first) { int n; clearerr(f); if (nargs == 0) { /* no arguments? */ - success = new_read_line(L, f); + success = read_line(L, f); n = first+1; /* to return 1 result */ } else { /* ensure stack space for all results and for auxlib's buffer */ @@ -405,10 +353,10 @@ static int g_read (lua_State *L, FILE *f, int first) { success = read_number(L, f); break; case 'l': /* line */ - success = new_read_line(L, f); + success = read_line(L, f); break; case 'a': /* file */ - read_all(L, f); + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ success = 1; /* always success */ break; default: @@ -426,20 +374,23 @@ static int g_read (lua_State *L, FILE *f, int first) { return n - first; } + static int io_read (lua_State *L) { return g_read(L, getiofile(L, IO_INPUT), 1); } + static int f_read (lua_State *L) { return g_read(L, tofile(L), 2); } + static int io_readline (lua_State *L) { FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); int sucess; if (f == NULL) /* file is already closed? */ luaL_error(L, "file is already closed"); - sucess = new_read_line(L, f); + sucess = read_line(L, f); if (ferror(f)) return luaL_error(L, "%s", strerror(errno)); if (sucess) return 1; @@ -529,7 +480,6 @@ static const luaL_Reg iolib[] = { {"input", io_input}, {"lines", io_lines}, {"open", io_open}, - {"open_ro", io_open_ro}, {"output", io_output}, {"popen", io_popen}, {"read", io_read}, @@ -568,31 +518,36 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { lua_pushvalue(L, -1); lua_rawseti(L, LUA_ENVIRONINDEX, k); } - lua_setfield(L, -2, fname); + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); } LUALIB_API int luaopen_io (lua_State *L) { createmeta(L); /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ - lua_createtable(L, 2, 1); + newfenv(L, io_fclose); lua_replace(L, LUA_ENVIRONINDEX); /* open library */ luaL_register(L, LUA_IOLIBNAME, iolib); /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ createstdfile(L, stdin, IO_INPUT, "stdin"); createstdfile(L, stdout, IO_OUTPUT, "stdout"); createstdfile(L, stderr, 0, "stderr"); - /* create environment for 'popen' */ + lua_pop(L, 1); /* pop environment for default files */ lua_getfield(L, -1, "popen"); - lua_createtable(L, 0, 1); - lua_pushcfunction(L, io_pclose); - lua_setfield(L, -2, "__close"); - lua_setfenv(L, -2); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ lua_pop(L, 1); /* pop 'popen' */ - /* set default close function */ - lua_pushcfunction(L, io_fclose); - lua_setfield(L, LUA_ENVIRONINDEX, "__close"); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua51/llex.c b/Build/source/texk/web2c/luatexdir/lua51/llex.c index 1c07cad9bb6..6dc319358c0 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/llex.c +++ b/Build/source/texk/web2c/luatexdir/lua51/llex.c @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.20 2006/03/09 18:14:31 roberto Exp $ +** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/llex.h b/Build/source/texk/web2c/luatexdir/lua51/llex.h index ff07e83d318..a9201cee484 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/llex.h +++ b/Build/source/texk/web2c/luatexdir/lua51/llex.h @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.58 2006/03/23 18:23:32 roberto Exp $ +** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/llimits.h b/Build/source/texk/web2c/luatexdir/lua51/llimits.h index 26e7c4f8cf8..a20e22146bd 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/llimits.h +++ b/Build/source/texk/web2c/luatexdir/lua51/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.69 2005/12/27 17:12:00 roberto Exp $ +** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lmathlib.c b/Build/source/texk/web2c/luatexdir/lua51/lmathlib.c index d181a731943..441fbf736c2 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lmathlib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.67 2005/08/26 17:36:32 roberto Exp $ +** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lmem.c b/Build/source/texk/web2c/luatexdir/lua51/lmem.c index cef2bc5f851..ae7d8c965f6 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lmem.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.70 2005/12/26 13:35:47 roberto Exp $ +** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lmem.h b/Build/source/texk/web2c/luatexdir/lua51/lmem.h index 19df1fbb6c9..7c2dcb32207 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lmem.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lmem.h @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.31 2005/04/25 19:24:10 roberto Exp $ +** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/loadlib.c b/Build/source/texk/web2c/luatexdir/lua51/loadlib.c index 808368ba431..0d401eba1cf 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/loadlib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.54a 2006/07/03 20:16:49 roberto Exp $ +** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -506,8 +506,10 @@ static int ll_require (lua_State *L) { static void setfenv (lua_State *L) { lua_Debug ar; - lua_getstack(L, 1, &ar); - lua_getinfo(L, "f", &ar); + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); lua_pushvalue(L, -2); lua_setfenv(L, -2); lua_pop(L, 1); diff --git a/Build/source/texk/web2c/luatexdir/lua51/lobject.c b/Build/source/texk/web2c/luatexdir/lua51/lobject.c index 9fb81f637b2..aec4ec450a7 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lobject.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.22 2006/02/10 17:43:52 roberto Exp $ +** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lobject.h b/Build/source/texk/web2c/luatexdir/lua51/lobject.h index 8ce4405b6ae..f1e447ef3ba 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lobject.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.20 2006/01/18 11:37:34 roberto Exp $ +** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -208,7 +208,7 @@ typedef union TString { #define getstr(ts) cast(const char *, (ts) + 1) -#define svalue(o) getstr(tsvalue(o)) +#define svalue(o) getstr(rawtsvalue(o)) diff --git a/Build/source/texk/web2c/luatexdir/lua51/lopcodes.c b/Build/source/texk/web2c/luatexdir/lua51/lopcodes.c index bf9cd522c26..4cc745230b7 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lopcodes.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.37 2005/11/08 19:45:36 roberto Exp $ +** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lopcodes.h b/Build/source/texk/web2c/luatexdir/lua51/lopcodes.h index 48105f1e722..41224d6ee14 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lopcodes.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.125 2006/03/14 19:04:44 roberto Exp $ +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/loslib.c b/Build/source/texk/web2c/luatexdir/lua51/loslib.c index fdda47414d0..da06a572acf 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/loslib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.20 2006/09/19 13:57:08 roberto Exp $ +** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -215,7 +215,6 @@ static int os_setlocale (lua_State *L) { static int os_exit (lua_State *L) { exit(luaL_optint(L, 1, EXIT_SUCCESS)); - return 0; /* to avoid warnings */ } static const luaL_Reg syslib[] = { diff --git a/Build/source/texk/web2c/luatexdir/lua51/lparser.c b/Build/source/texk/web2c/luatexdir/lua51/lparser.c index 6c473c41d2f..1e2a9a88b79 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lparser.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.42a 2006/06/05 15:57:59 roberto Exp $ +** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -938,6 +938,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, + "variables in assignment"); assignment(ls, &nv, nvars+1); } else { /* assignment -> `=' explist1 */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lparser.h b/Build/source/texk/web2c/luatexdir/lua51/lparser.h index e5b5b57e850..18836afd1cd 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lparser.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.57 2006/03/09 18:14:31 roberto Exp $ +** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lstate.c b/Build/source/texk/web2c/luatexdir/lua51/lstate.c index 4bcb7594ce8..8d8e512e2d4 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lstate.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.36 2006/05/24 14:15:50 roberto Exp $ +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lstate.h b/Build/source/texk/web2c/luatexdir/lua51/lstate.h index 5209e95c8ac..441c475e12a 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lstate.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.24 2006/02/06 18:27:59 roberto Exp $ +** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lstring.c b/Build/source/texk/web2c/luatexdir/lua51/lstring.c index 4319930c96d..49113151cc7 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lstring.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 2.8 2005/12/22 16:19:56 roberto Exp $ +** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lstring.h b/Build/source/texk/web2c/luatexdir/lua51/lstring.h index 1d2e91ea13a..73a2ff8b380 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lstring.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.43 2005/04/25 19:24:10 roberto Exp $ +** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lstrlib.c b/Build/source/texk/web2c/luatexdir/lua51/lstrlib.c index 51a2e09e034..9ff4165248b 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lstrlib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.132 2006/04/26 20:41:19 roberto Exp $ +** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -35,7 +35,8 @@ static int str_len (lua_State *L) { static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { /* relative string position: negative means back from end */ - return (pos>=0) ? pos : (ptrdiff_t)len+pos+1; + if (pos < 0) pos += (ptrdiff_t)len + 1; + return (pos >= 0) ? pos : 0; } @@ -852,10 +853,6 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, lua_gettable(L, 3); break; } - default: { - luaL_argerror(L, 3, "string/function/table expected"); - return; - } } if (!lua_toboolean(L, -1)) { /* nil or false? */ lua_pop(L, 1); @@ -871,11 +868,15 @@ static int str_gsub (lua_State *L) { size_t srcl; const char *src = luaL_checklstring(L, 1, &srcl); const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); int max_s = luaL_optint(L, 4, srcl+1); int anchor = (*p == '^') ? (p++, 1) : 0; int n = 0; MatchState ms; luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); luaL_buffinit(L, &b); ms.L = L; ms.src_init = src; @@ -1055,7 +1056,7 @@ static int str_split (lua_State *L) { } p = malloc(l+1); if (p==NULL) { - fprintf(stderr, "fatal: memory exhausted (malloc of %u bytes).\n",l+1); + fprintf(stderr, "fatal: memory exhausted (malloc of %u bytes).\n",(int)(l+1)); exit(EXIT_FAILURE); } strcpy(p,s); diff --git a/Build/source/texk/web2c/luatexdir/lua51/ltable.c b/Build/source/texk/web2c/luatexdir/lua51/ltable.c index bc91cacd637..ec84f4fabc5 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ltable.c +++ b/Build/source/texk/web2c/luatexdir/lua51/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.32 2006/01/18 11:49:02 roberto Exp $ +** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -84,8 +84,8 @@ static const Node dummynode_ = { static Node *hashnum (const Table *t, lua_Number n) { unsigned int a[numints]; int i; - n += 1; /* normalize number (avoid -0) */ - lua_assert(sizeof(a) <= sizeof(n)); + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); memcpy(a, &n, sizeof(a)); for (i = 1; i < numints; i++) a[0] += a[i]; return hashmod(t, a[0]); diff --git a/Build/source/texk/web2c/luatexdir/lua51/ltable.h b/Build/source/texk/web2c/luatexdir/lua51/ltable.h index 09193cdbe04..f5b9d5ead0f 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ltable.h +++ b/Build/source/texk/web2c/luatexdir/lua51/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 2.10 2006/01/10 13:13:06 roberto Exp $ +** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/ltablib.c b/Build/source/texk/web2c/luatexdir/lua51/ltablib.c index 453b23b378b..b6d9cb4ac74 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ltablib.c +++ b/Build/source/texk/web2c/luatexdir/lua51/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.38 2005/10/23 17:38:15 roberto Exp $ +** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -118,7 +118,8 @@ static int tinsert (lua_State *L) { static int tremove (lua_State *L) { int e = aux_getn(L, 1); int pos = luaL_optint(L, 2, e); - if (e == 0) return 0; /* table is `empty' */ + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ + return 0; /* nothing to remove */ luaL_setn(L, 1, e - 1); /* t.n = n-1 */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;pos<e; pos++) { @@ -131,6 +132,15 @@ static int tremove (lua_State *L) { } +static void addfield (lua_State *L, luaL_Buffer *b, int i) { + lua_rawgeti(L, 1, i); + if (!lua_isstring(L, -1)) + luaL_error(L, "invalid value (%s) at index %d in table for " + LUA_QL("concat"), luaL_typename(L, -1), i); + luaL_addvalue(b); +} + + static int tconcat (lua_State *L) { luaL_Buffer b; size_t lsep; @@ -140,13 +150,12 @@ static int tconcat (lua_State *L) { i = luaL_optint(L, 3, 1); last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1)); luaL_buffinit(L, &b); - for (; i <= last; i++) { - lua_rawgeti(L, 1, i); - luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings"); - luaL_addvalue(&b); - if (i != last) - luaL_addlstring(&b, sep, lsep); + for (; i < last; i++) { + addfield(L, &b, i); + luaL_addlstring(&b, sep, lsep); } + if (i == last) /* add last value (if interval was not empty) */ + addfield(L, &b, i); luaL_pushresult(&b); return 1; } diff --git a/Build/source/texk/web2c/luatexdir/lua51/ltm.c b/Build/source/texk/web2c/luatexdir/lua51/ltm.c index 097b815ad3a..c27f0f6fab8 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ltm.c +++ b/Build/source/texk/web2c/luatexdir/lua51/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 2.8 2006/01/10 12:50:00 roberto Exp $ +** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/ltm.h b/Build/source/texk/web2c/luatexdir/lua51/ltm.h index 866c79668d8..64343b781b6 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/ltm.h +++ b/Build/source/texk/web2c/luatexdir/lua51/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 2.6 2005/06/06 13:30:25 roberto Exp $ +** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lua.c b/Build/source/texk/web2c/luatexdir/lua51/lua.c index 5cee7fa9f0b..3a46609328c 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lua.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.160 2006/06/02 15:34:00 roberto Exp $ +** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -74,6 +74,8 @@ static int report (lua_State *L, int status) { static int traceback (lua_State *L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ lua_getfield(L, LUA_GLOBALSINDEX, "debug"); if (!lua_istable(L, -1)) { lua_pop(L, 1); @@ -144,7 +146,7 @@ static int dostring (lua_State *L, const char *s, const char *name) { static int dolibrary (lua_State *L, const char *name) { lua_getglobal(L, "require"); lua_pushstring(L, name); - return report(L, lua_pcall(L, 1, 0, 0)); + return report(L, docall(L, 1, 1)); } diff --git a/Build/source/texk/web2c/luatexdir/lua51/lua.h b/Build/source/texk/web2c/luatexdir/lua51/lua.h index 2865a7fae96..e4bdfd3b94f 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lua.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.218a 2006/06/02 15:34:00 roberto Exp $ +** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ ** Lua - An Extensible Extension Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -17,9 +17,9 @@ #define LUA_VERSION "Lua 5.1" -#define LUA_RELEASE "Lua 5.1.2" +#define LUA_RELEASE "Lua 5.1.4" #define LUA_VERSION_NUM 501 -#define LUA_COPYRIGHT "Copyright (C) 1994-2007 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" @@ -294,6 +294,9 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); #define lua_Chunkwriter lua_Writer +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + /* ** {====================================================================== @@ -359,7 +362,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved. +* Copyright (C) 1994-2008 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 diff --git a/Build/source/texk/web2c/luatexdir/lua51/luaconf.h b/Build/source/texk/web2c/luatexdir/lua51/luaconf.h index 11b002ca925..0650f2c7f64 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/luaconf.h +++ b/Build/source/texk/web2c/luatexdir/lua51/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.82 2006/04/10 18:27:23 roberto Exp $ +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -440,9 +440,10 @@ @* can use. ** CHANGE it if you need lots of (Lua) stack space for your C ** functions. This limit is arbitrary; its only purpose is to stop C -** functions to consume unlimited stack space. +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) */ -#define LUAI_MAXCSTACK 2048 +#define LUAI_MAXCSTACK 8000 @@ -674,7 +675,7 @@ union luai_Cast { double l_d; long l_l; }; */ #if defined(LUA_USE_POPEN) -#define lua_popen(L,c,m) ((void)L, popen(c,m)) +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) #define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) #elif defined(LUA_WIN) diff --git a/Build/source/texk/web2c/luatexdir/lua51/lualib.h b/Build/source/texk/web2c/luatexdir/lua51/lualib.h index 0c76232c0dd..469417f6703 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lualib.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.36 2005/12/27 17:12:00 roberto Exp $ +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua standard libraries ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lundump.c b/Build/source/texk/web2c/luatexdir/lua51/lundump.c index 7fc635eeb7b..dea1996dcc5 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lundump.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 1.60 2006/02/16 15:53:49 lhf Exp $ +** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -25,10 +25,12 @@ typedef struct { ZIO* Z; Mbuffer* b; const char* name; + int swap; } LoadState; #ifdef LUAC_TRUST_BINARIES #define IF(c,s) +#define error(S,s) #else #define IF(c,s) if (c) error(S,s) @@ -39,7 +41,6 @@ static void error(LoadState* S, const char* why) } #endif -#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) #define LoadByte(S) (lu_byte)LoadChar(S) #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) @@ -50,6 +51,49 @@ static void LoadBlock(LoadState* S, void* b, size_t size) IF (r!=0, "unexpected end"); } +static void LoadMem (LoadState* S, void* b, int n, size_t size) +{ + LoadBlock(S,b,n*size); + if (S->swap) + { + char* p=(char*) b; + char c; + switch (size) + { + case 1: + break; + case 2: + while (n--) + { + c=p[0]; p[0]=p[1]; p[1]=c; + p+=2; + } + break; + case 4: + while (n--) + { + c=p[0]; p[0]=p[3]; p[3]=c; + c=p[1]; p[1]=p[2]; p[2]=c; + p+=4; + } + break; + case 8: + while (n--) + { + c=p[0]; p[0]=p[7]; p[7]=c; + c=p[1]; p[1]=p[6]; p[6]=c; + c=p[2]; p[2]=p[5]; p[5]=c; + c=p[3]; p[3]=p[4]; p[4]=c; + p+=8; + } + break; + default: + IF(1, "bad size"); + break; + } + } +} + static int LoadChar(LoadState* S) { char x; @@ -74,7 +118,7 @@ static lua_Number LoadNumber(LoadState* S) static TString* LoadString(LoadState* S) { - size_t size; + unsigned int size; LoadVar(S,size); if (size==0) return NULL; @@ -113,7 +157,7 @@ static void LoadConstants(LoadState* S, Proto* f) setnilvalue(o); break; case LUA_TBOOLEAN: - setbvalue(o,LoadChar(S)); + setbvalue(o,LoadChar(S)!=0); break; case LUA_TNUMBER: setnvalue(o,LoadNumber(S)); @@ -122,7 +166,7 @@ static void LoadConstants(LoadState* S, Proto* f) setsvalue2n(S->L,o,LoadString(S)); break; default: - IF (1, "bad constant"); + error(S,"bad constant"); break; } } @@ -159,7 +203,9 @@ static void LoadDebug(LoadState* S, Proto* f) static Proto* LoadFunction(LoadState* S, TString* p) { - Proto* f=luaF_newproto(S->L); + Proto* f; + if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); + f=luaF_newproto(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L); f->source=LoadString(S); if (f->source==NULL) f->source=p; f->linedefined=LoadInt(S); @@ -173,6 +219,7 @@ static Proto* LoadFunction(LoadState* S, TString* p) LoadDebug(S,f); IF (!luaG_checkcode(f), "bad code"); S->L->top--; + S->L->nCcalls--; return f; } @@ -182,6 +229,7 @@ static void LoadHeader(LoadState* S) char s[LUAC_HEADERSIZE]; luaU_header(h); LoadBlock(S,s,LUAC_HEADERSIZE); + S->swap=(s[6]!=h[6]); s[6]=h[6]; IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); } @@ -216,7 +264,7 @@ void luaU_header (char* h) *h++=(char)LUAC_FORMAT; *h++=(char)*(char*)&x; /* endianness */ *h++=(char)sizeof(int); - *h++=(char)sizeof(size_t); + *h++=(char)sizeof(unsigned int); *h++=(char)sizeof(Instruction); *h++=(char)sizeof(lua_Number); *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lundump.h b/Build/source/texk/web2c/luatexdir/lua51/lundump.h index 58cca5d1908..c80189dbffc 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lundump.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lundump.h @@ -1,5 +1,5 @@ /* -** $Id: lundump.h,v 1.40 2005/11/11 14:03:13 lhf Exp $ +** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lvm.c b/Build/source/texk/web2c/luatexdir/lua51/lvm.c index 08802f440f3..ee3256ab94d 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lvm.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.63a 2006/06/05 15:58:59 roberto Exp $ +** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -61,11 +61,9 @@ static void traceexec (lua_State *L, const Instruction *pc) { lu_byte mask = L->hookmask; const Instruction *oldpc = L->savedpc; L->savedpc = pc; - if (mask > LUA_MASKLINE) { /* instruction-hook set? */ - if (L->hookcount == 0) { - resethookcount(L); - luaD_callhook(L, LUA_HOOKCOUNT, -1); - } + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); } if (mask & LUA_MASKLINE) { Proto *p = ci_func(L->ci)->l.p; diff --git a/Build/source/texk/web2c/luatexdir/lua51/lvm.h b/Build/source/texk/web2c/luatexdir/lua51/lvm.h index 788423f8e31..bfe4f5678d0 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lvm.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.5 2005/08/22 18:54:49 roberto Exp $ +** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lzio.c b/Build/source/texk/web2c/luatexdir/lua51/lzio.c index 5121ada8466..293edd59b08 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lzio.c +++ b/Build/source/texk/web2c/luatexdir/lua51/lzio.c @@ -1,5 +1,5 @@ /* -** $Id: lzio.c,v 1.31 2005/06/03 20:15:29 roberto Exp $ +** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ ** a generic input stream interface ** See Copyright Notice in lua.h */ diff --git a/Build/source/texk/web2c/luatexdir/lua51/lzio.h b/Build/source/texk/web2c/luatexdir/lua51/lzio.h index 8f403b8e74f..51d695d8c1d 100644 --- a/Build/source/texk/web2c/luatexdir/lua51/lzio.h +++ b/Build/source/texk/web2c/luatexdir/lua51/lzio.h @@ -1,5 +1,5 @@ /* -** $Id: lzio.h,v 1.21 2005/05/17 19:49:15 roberto Exp $ +** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ ** Buffered streams ** See Copyright Notice in lua.h */ 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 b66a8f39333..1f75c22cddc 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c @@ -33,9 +33,6 @@ #include <gwidget.h> #include "ttf.h" -#undef getsid -#define getsid FFgetsid - #ifdef LUA_FF_LIB SplineFont *_SFReadTTFInfo(FILE *ttf, int flags,enum openflags openflags, char *filename,struct fontdict *fd); void THPatchSplineChar(SplineChar *sc); @@ -3269,7 +3266,7 @@ return( NULL ); return( dicts ); } -static const char *getsid(int sid,char **strings,int scnt,struct ttfinfo *info) { +static const char *FFgetsid(int sid,char **strings,int scnt,struct ttfinfo *info) { if ( sid==-1 ) return( NULL ); else if ( sid<nStdStrings ) @@ -3345,7 +3342,7 @@ return; /* Use cids instead */ for ( i=0; i<cnt; ++i ) { dupenc = getc(ttf); sid = getushort(ttf); - name = getsid(sid,strings,scnt,info); + name = FFgetsid(sid,strings,scnt,info); if ( name==NULL ) /* Table is erroneous */ break; for ( j=0; j<info->glyph_cnt; ++j ) @@ -3601,7 +3598,7 @@ static SplineFont *cffsffillup(struct topdicts *subdict, char **strings, int emsize; static int nameless; - sf->fontname = utf8_verify_copy(getsid(subdict->sid_fontname,strings,scnt,info)); + sf->fontname = utf8_verify_copy(FFgetsid(subdict->sid_fontname,strings,scnt,info)); if ( sf->fontname==NULL ) { char buffer[40]; sprintf(buffer,"UntitledSubFont_%d", ++nameless ); @@ -3615,13 +3612,13 @@ static SplineFont *cffsffillup(struct topdicts *subdict, char **strings, sf->ascent = .8*emsize; sf->descent = emsize - sf->ascent; if ( subdict->copyright!=-1 ) - sf->copyright = utf8_verify_copy(getsid(subdict->copyright,strings,scnt,info)); + sf->copyright = utf8_verify_copy(FFgetsid(subdict->copyright,strings,scnt,info)); else - sf->copyright = utf8_verify_copy(getsid(subdict->notice,strings,scnt,info)); - sf->familyname = utf8_verify_copy(getsid(subdict->familyname,strings,scnt,info)); - sf->fullname = utf8_verify_copy(getsid(subdict->fullname,strings,scnt,info)); - sf->weight = utf8_verify_copy(getsid(subdict->weight,strings,scnt,info)); - sf->version = utf8_verify_copy(getsid(subdict->version,strings,scnt,info)); + sf->copyright = utf8_verify_copy(FFgetsid(subdict->notice,strings,scnt,info)); + sf->familyname = utf8_verify_copy(FFgetsid(subdict->familyname,strings,scnt,info)); + sf->fullname = utf8_verify_copy(FFgetsid(subdict->fullname,strings,scnt,info)); + sf->weight = utf8_verify_copy(FFgetsid(subdict->weight,strings,scnt,info)); + sf->version = utf8_verify_copy(FFgetsid(subdict->version,strings,scnt,info)); sf->italicangle = subdict->italicangle; sf->upos = subdict->underlinepos; sf->uwidth = subdict->underlinewidth; @@ -3656,24 +3653,24 @@ static void cffinfofillup(struct ttfinfo *info, struct topdicts *dict, if ( dict->copyright!=-1 || dict->notice!=-1 ) free( info->copyright ); if ( dict->copyright!=-1 ) - info->copyright = utf8_verify_copy(getsid(dict->copyright,strings,scnt,info)); + info->copyright = utf8_verify_copy(FFgetsid(dict->copyright,strings,scnt,info)); else if ( dict->notice!=-1 ) - info->copyright = utf8_verify_copy(getsid(dict->notice,strings,scnt,info)); + info->copyright = utf8_verify_copy(FFgetsid(dict->notice,strings,scnt,info)); if ( dict->familyname!=-1 ) { free(info->familyname); - info->familyname = utf8_verify_copy(getsid(dict->familyname,strings,scnt,info)); + info->familyname = utf8_verify_copy(FFgetsid(dict->familyname,strings,scnt,info)); } if ( dict->fullname!=-1 ) { free(info->fullname); - info->fullname = utf8_verify_copy(getsid(dict->fullname,strings,scnt,info)); + info->fullname = utf8_verify_copy(FFgetsid(dict->fullname,strings,scnt,info)); } if ( dict->weight!=-1 ) { free(info->weight); - info->weight = utf8_verify_copy(getsid(dict->weight,strings,scnt,info)); + info->weight = utf8_verify_copy(FFgetsid(dict->weight,strings,scnt,info)); } if ( dict->version!=-1 ) { free(info->version); - info->version = utf8_verify_copy(getsid(dict->version,strings,scnt,info)); + info->version = utf8_verify_copy(FFgetsid(dict->version,strings,scnt,info)); } if ( dict->fontname!=NULL ) { free(info->fontname); @@ -3692,8 +3689,8 @@ static void cffinfofillup(struct ttfinfo *info, struct topdicts *dict, cffprivatefillup(info->private,dict); } if ( dict->ros_registry!=-1 ) { - info->cidregistry = copy(getsid(dict->ros_registry,strings,scnt,info)); - info->ordering = copy(getsid(dict->ros_ordering,strings,scnt,info)); + info->cidregistry = copy(FFgetsid(dict->ros_registry,strings,scnt,info)); + info->ordering = copy(FFgetsid(dict->ros_ordering,strings,scnt,info)); info->supplement = dict->ros_supplement; info->cidfontversion = dict->cidfontversion; } @@ -3727,7 +3724,7 @@ static void cfffigure(struct ttfinfo *info, struct topdicts *dict, for ( i=0; i<info->glyph_cnt; ++i ) { info->chars[i] = PSCharStringToSplines( dict->glyphs.values[i], dict->glyphs.lens[i],&pscontext, - subrs,gsubrs,getsid(dict->charset[i],strings,scnt,info)); + subrs,gsubrs,FFgetsid(dict->charset[i],strings,scnt,info)); info->chars[i]->vwidth = info->emsize; if ( cstype==2 ) { if ( info->chars[i]->width == (int16) 0x8000 ) diff --git a/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c b/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c index 969ef9d1433..07cbf341d59 100644 --- a/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c +++ b/Build/source/texk/web2c/luatexdir/luapeg/lpeg.c @@ -1,5 +1,5 @@ /* -** $Id: lpeg.c,v 1.86 2008/03/07 17:20:19 roberto Exp $ +** $Id: lpeg.c,v 1.98 2008/10/11 20:20:43 roberto Exp $ ** LPeg - PEG pattern matching for Lua ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) ** written by Roberto Ierusalimschy @@ -7,6 +7,7 @@ #include <assert.h> +#include <ctype.h> #include <limits.h> #include <stdio.h> #include <string.h> @@ -15,7 +16,7 @@ #include "lauxlib.h" -#define VERSION "0.8" +#define VERSION "0.9" #define PATTERN_T "pattern" /* maximum call/backtrack levels */ @@ -32,7 +33,7 @@ #define FIXEDARGS 3 /* index, on Lua stack, for substitution value cache */ -#define subscache(ptop) ((ptop) + 1) +#define subscache(cs) ((cs)->ptop + 1) /* index, on Lua stack, for capture list */ #define caplistidx(ptop) ((ptop) + 2) @@ -59,9 +60,7 @@ typedef const char *(*PattFunc) (const void *ud, /* Virtual Machine's instructions */ typedef enum Opcode { - IAny, IChar, ISet, IZSet, - ITestAny, ITestChar, ITestSet, ITestZSet, - ISpan, ISpanZ, + IAny, IChar, ISet, ISpan, IRet, IEnd, IChoice, IJmp, ICall, IOpenCall, ICommit, IPartialCommit, IBackCommit, IFailTwice, IFail, IGiveup, @@ -72,25 +71,18 @@ typedef enum Opcode { #define ISJMP 1 -#define ISCHECK 2 -#define ISTEST 4 -#define ISNOFAIL 8 -#define ISCAPTURE 16 -#define ISMOVABLE 32 -#define ISFENVOFF 64 -#define HASCHARSET 128 +#define ISCHECK (ISJMP << 1) +#define ISNOFAIL (ISCHECK << 1) +#define ISCAPTURE (ISNOFAIL << 1) +#define ISMOVABLE (ISCAPTURE << 1) +#define ISFENVOFF (ISMOVABLE << 1) +#define HASCHARSET (ISFENVOFF << 1) static const byte opproperties[] = { /* IAny */ ISCHECK, /* IChar */ ISCHECK, /* ISet */ ISCHECK | HASCHARSET, - /* IZSet */ ISCHECK | HASCHARSET, - /* ITestAny */ ISJMP | ISTEST | ISNOFAIL, - /* ITestChar */ ISJMP | ISTEST | ISNOFAIL, - /* ITestSet */ ISJMP | ISTEST | ISNOFAIL | HASCHARSET, - /* ITestZSet */ ISJMP | ISTEST | ISNOFAIL | HASCHARSET, /* ISpan */ ISNOFAIL | HASCHARSET, - /* ISpanZ */ ISNOFAIL | HASCHARSET, /* IRet */ 0, /* IEnd */ 0, /* IChoice */ ISJMP, @@ -135,8 +127,8 @@ static const Instruction giveup = {{IGiveup, 0, 0}}; #define isprop(op,p) (opproperties[(op)->i.code] & (p)) #define isjmp(op) isprop(op, ISJMP) #define iscapture(op) isprop(op, ISCAPTURE) -#define ischeck(op) isprop(op, ISCHECK) -#define istest(op) isprop(op, ISTEST) +#define ischeck(op) (isprop(op, ISCHECK) && (op)->i.offset == 0) +#define istest(op) (isprop(op, ISCHECK) && (op)->i.offset != 0) #define isnofail(op) isprop(op, ISNOFAIL) #define ismovable(op) isprop(op, ISMOVABLE) #define isfenvoff(op) isprop(op, ISFENVOFF) @@ -146,7 +138,7 @@ static const Instruction giveup = {{IGiveup, 0, 0}}; /* kinds of captures */ typedef enum CapKind { Cclose, Cposition, Cconst, Cbackref, Carg, Csimple, Ctable, Cfunction, - Cquery, Cstring, Csubst, Caccum, Cruntime + Cquery, Cstring, Csubst, Cfold, Cruntime, Cgroup } CapKind; #define iscapnosize(k) ((k) == Cposition || (k) == Cconst) @@ -239,22 +231,22 @@ static void printcapkind (int kind) { const char *const modes[] = { "close", "position", "constant", "backref", "argument", "simple", "table", "function", - "query", "string", "substitution", "accumulator", - "runtime"}; + "query", "string", "substitution", "fold", + "runtime", "group"}; printf("%s", modes[kind]); } static void printjmp (const Instruction *op, const Instruction *p) { - printf("-> %ld", (long)(dest(0, p) - op)); + printf("-> "); + if (p->i.offset == 0) printf("FAIL"); + else printf("%d", (int)(dest(0, p) - op)); } static void printinst (const Instruction *op, const Instruction *p) { const char *const names[] = { - "any", "char", "set", "zset", - "testany", "testchar", "testset", "testzset", - "span", "spanz", + "any", "char", "set", "span", "ret", "end", "choice", "jmp", "call", "open_call", "commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup", @@ -266,19 +258,11 @@ static void printinst (const Instruction *op, const Instruction *p) { switch ((Opcode)p->i.code) { case IChar: { printf("'%c'", p->i.aux); - break; - } - case ITestChar: { - printf("'%c'", p->i.aux); printjmp(op, p); break; } case IAny: { printf("* %d", p->i.aux); - break; - } - case ITestAny: { - printf("* %d", p->i.aux); printjmp(op, p); break; } @@ -289,13 +273,13 @@ static void printinst (const Instruction *op, const Instruction *p) { printf("(n = %d) (off = %d)", getoff(p), p->i.offset); break; } - case ISet: case IZSet: case ISpan: case ISpanZ: { + case ISet: { printcharset((p+1)->buff); + printjmp(op, p); break; } - case ITestSet: case ITestZSet: { + case ISpan: { printcharset((p+1)->buff); - printjmp(op, p); break; } case IOpenCall: { @@ -388,6 +372,9 @@ static void adddyncaptures (const char *s, Capture *base, int n, int fd) { } +#define condfailed(p) { int f = p->i.offset; if (f) p+=f; else goto fail; } + + static const char *match (lua_State *L, const char *o, const char *s, const char *e, Instruction *op, Capture *capture, int ptop) { @@ -421,61 +408,25 @@ static const char *match (lua_State *L, } case IAny: { int n = p->i.aux; - if (n > e - s) goto fail; - else { p++; s += n; } - continue; - } - case ITestAny: { - int n = p->i.aux; - if (n > e - s) p += p->i.offset; - else { p++; s += n; } + if (n <= e - s) { p++; s += n; } + else condfailed(p); continue; } case IChar: { - if ((byte)*s != p->i.aux || s >= e) goto fail; - else { p++; s++; } - continue; - } - case ITestChar: { - if ((byte)*s != p->i.aux || s >= e) p += p->i.offset; - else { p++; s++; } + if ((byte)*s == p->i.aux && s < e) { p++; s++; } + else condfailed(p); continue; } case ISet: { - int c = (unsigned char)*s; - if (!testchar((p+1)->buff, c)) goto fail; - else { p += CHARSETINSTSIZE; s++; } - continue; - } - case ITestSet: { - int c = (unsigned char)*s; - if (!testchar((p+1)->buff, c)) p += p->i.offset; - else { p += CHARSETINSTSIZE; s++; } - continue; - } - case IZSet: { - int c = (unsigned char)*s; - if (!testchar((p+1)->buff, c) || s >= e) goto fail; - else { p += CHARSETINSTSIZE; s++; } - continue; - } - case ITestZSet: { - int c = (unsigned char)*s; - if (!testchar((p+1)->buff, c) || s >= e) p += p->i.offset; - else { p += CHARSETINSTSIZE; s++; } + int c = (byte)*s; + if (testchar((p+1)->buff, c) && s < e) + { p += CHARSETINSTSIZE; s++; } + else condfailed(p); continue; } case ISpan: { - for (;; s++) { - int c = (unsigned char)*s; - if (!testchar((p+1)->buff, c)) break; - } - p += CHARSETINSTSIZE; - continue; - } - case ISpanZ: { for (; s < e; s++) { - int c = (unsigned char)*s; + int c = (byte)*s; if (!testchar((p+1)->buff, c)) break; } p += CHARSETINSTSIZE; @@ -682,28 +633,25 @@ static int verify (lua_State *L, Instruction *op, const Instruction *p, continue; } } - case ITestAny: - case ITestChar: /* all these cases jump for empty subject */ - case ITestSet: - case ITestZSet: + case IAny: + case IChar: + case ISet: { + if (p->i.offset == 0) goto fail; + /* else goto dojmp; go through */ + } case IJmp: dojmp: { p += p->i.offset; continue; } - case IAny: - case IChar: - case ISet: - case IZSet: - case IFailTwice: /* assume that first level failed; try to backtrack */ - goto fail; + case IFailTwice: /* 'not' predicate */ + goto fail; /* body could have failed; try to backtrack it */ case IFail: { - if (p->i.aux) { /* is an 'and' predicate? */ - assert((p - 1)->i.code == IBackCommit && (p - 1)->i.offset == 2); + if (p > op && (p - 1)->i.code == IBackCommit) { /* 'and' predicate? */ p++; /* pretend it succeeded and go ahead */ continue; } - /* else go through */ + /* else failed: go through */ } fail: { /* pattern failed: try to backtrack */ do { @@ -713,7 +661,7 @@ static int verify (lua_State *L, Instruction *op, const Instruction *p, p = back[backtop].p; continue; } - case ISpan: case ISpanZ: + case ISpan: case IOpenCapture: case ICloseCapture: case IEmptyCapture: case IEmptyCaptureIdx: case IFullCapture: { @@ -784,8 +732,7 @@ static Instruction *getpatt (lua_State *L, int idx, int *size); static void check2test (Instruction *p, int n) { - assert(ischeck(p)); - p->i.code += ITestAny - IAny; + assert(ischeck(p) && n != 0); p->i.offset = n; } @@ -989,14 +936,11 @@ static Instruction *newpatt (lua_State *L, size_t n) { static void fillcharset (Instruction *p, Charset cs) { switch (p[0].i.code) { - case IZSet: case ITestZSet: - assert(testchar(p[1].buff, '\0')); - /* go through */ - case ISet: case ITestSet: { + case ISet: { loopset(i, cs[i] = p[1].buff[i]); break; } - case IChar: case ITestChar: { + case IChar: { loopset(i, cs[i] = 0); setchar(cs, p[0].i.aux); break; @@ -1042,12 +986,10 @@ static int exclusive (CharsetTag *c1, CharsetTag *c2) { } -#define correctset(p) { if (testchar(p[1].buff, '\0')) p->i.code++; } - - static Instruction *newcharset (lua_State *L) { Instruction *p = newpatt(L, CHARSETINSTSIZE); p[0].i.code = ISet; + p[0].i.offset = 0; loopset(i, p[1].buff[i] = 0); return p; } @@ -1061,10 +1003,9 @@ static int set_l (lua_State *L) { else { Instruction *p = newcharset(L); while (l--) { - setchar(p[1].buff, (unsigned char)(*s)); + setchar(p[1].buff, (byte)(*s)); s++; } - correctset(p); } return 1; } @@ -1082,7 +1023,6 @@ static int range_l (lua_State *L) { for (c = (byte)r[0]; c <= (byte)r[1]; c++) setchar(p[1].buff, c); } - correctset(p); return 1; } @@ -1198,7 +1138,7 @@ static Instruction *getpatt (lua_State *L, int idx, int *size) { const char *s = lua_tolstring(L, idx, &len); p = newpatt(L, len); for (i = 0; i < len; i++) - setinstaux(p + i, IChar, 0, (unsigned char)s[i]); + setinstaux(p + i, IChar, 0, (byte)s[i]); lua_replace(L, idx); break; } @@ -1210,13 +1150,13 @@ static Instruction *getpatt (lua_State *L, int idx, int *size) { p = any(L, n, 0, NULL); else if (-n <= UCHAR_MAX) { p = newpatt(L, 2); - setinstaux(p, ITestAny, 2, -n); + setinstaux(p, IAny, 2, -n); setinst(p + 1, IFail, 0); } else { int offset = 2; /* space for ITestAny & IChoice */ p = any(L, -n - UCHAR_MAX, 3, &offset); - setinstaux(p, ITestAny, offset + 1, UCHAR_MAX); + setinstaux(p, IAny, offset + 1, UCHAR_MAX); setinstaux(p + 1, IChoice, offset, UCHAR_MAX); setinst(p + offset, IFailTwice, 0); } @@ -1269,14 +1209,19 @@ static int pattern_l (lua_State *L) { #define isany(p) ((p)->i.code == IAny && ((p) + 1)->i.code == IEnd) - +#define isfail(p) ((p)->i.code == IFail) +#define issucc(p) ((p)->i.code == IEnd) static int concat_l (lua_State *L) { /* p1; p2; */ int l1, l2; Instruction *p1 = getpatt(L, 1, &l1); Instruction *p2 = getpatt(L, 2, &l2); - if (isany(p1) && isany(p2)) + if (isfail(p1) || issucc(p2)) + lua_pushvalue(L, 1); /* fail * x == fail; x * true == x */ + else if (isfail(p2) || issucc(p1)) + lua_pushvalue(L, 2); /* x * fail == fail; true * x == x */ + else if (isany(p1) && isany(p2)) any(L, p1->i.aux + p2->i.aux, 0, NULL); else { Instruction *op = newpatt(L, l1 + l2); @@ -1296,7 +1241,6 @@ static int diff_l (lua_State *L) { if (tocharset(p1, &st1) == ISCHARSET && tocharset(p2, &st2) == ISCHARSET) { Instruction *p = newcharset(L); loopset(i, p[1].buff[i] = st1.cs[i] & ~st2.cs[i]); - correctset(p); } else if (isheadfail(p2)) { Instruction *p = newpatt(L, l2 + 1 + l1); @@ -1320,20 +1264,43 @@ static int diff_l (lua_State *L) { static int unm_l (lua_State *L) { - lua_pushliteral(L, ""); - lua_insert(L, 1); - return diff_l(L); + Instruction *p = getpatt(L, 1, NULL); + if (isfail(p)) { /* -false? */ + newpatt(L, 0); /* true */ + return 1; + } + else if (issucc(p)) { /* -true? */ + Instruction *p1 = newpatt(L, 1); /* false */ + setinst(p1, IFail, 0); + return 1; + } + else { /* -A == '' - A */ + lua_pushliteral(L, ""); + lua_insert(L, 1); + return diff_l(L); + } } static int pattand_l (lua_State *L) { - /* &e -> choice L1; e; backcommit L2; L1: fail; L2: ... */ - int l1 = getpattl(L, 1); - Instruction *p = newpatt(L, 1 + l1 + 2); - setinst(p++, IChoice, 1 + l1 + 1); - p += addpatt(L, p, 1); - setinst(p++, IBackCommit, 2); - setinstaux(p, IFail, 0, 1); + int l1; + Instruction *p1 = getpatt(L, 1, &l1); + CharsetTag st1; + if (isfail(p1) || issucc(p1)) + lua_pushvalue(L, 1); /* &fail == fail; &true == true */ + else if (tocharset(p1, &st1) == ISCHARSET) { + Instruction *p = newpatt(L, CHARSETINSTSIZE + 1); + setinst(p, ISet, CHARSETINSTSIZE + 1); + loopset(i, p[1].buff[i] = ~st1.cs[i]); + setinst(p + CHARSETINSTSIZE, IFail, 0); + } + else { + Instruction *p = newpatt(L, 1 + l1 + 2); + setinst(p++, IChoice, 1 + l1 + 1); + p += addpatt(L, p, 1); + setinst(p++, IBackCommit, 2); + setinst(p, IFail, 0); + } return 1; } @@ -1376,10 +1343,11 @@ static int interfere (Instruction *p1, int l1, CharsetTag *st2) { if (nofail(p1, l1)) /* p1 cannot fail? */ return 0; /* nothing can intefere with it */ if (st2->tag == NOINFO) return 1; + assert(p1->i.offset != 0); switch (p1->i.code) { - case ITestChar: return testchar(st2->cs, p1->i.aux); - case ITestSet: return !exclusiveset(st2->cs, (p1 + 1)->buff); - default: assert(p1->i.code == ITestAny); return 1; + case IChar: return testchar(st2->cs, p1->i.aux); + case ISet: return !exclusiveset(st2->cs, (p1 + 1)->buff); + default: assert(p1->i.code == IAny); return 1; } } @@ -1393,7 +1361,6 @@ static Instruction *basicUnion (lua_State *L, Instruction *p1, int l1, Instruction *p = auxnew(L, &op, size, CHARSETINSTSIZE); setinst(p, ISet, 0); loopset(i, p[1].buff[i] = st1.cs[i] | st2->cs[i]); - correctset(p); } else if (exclusive(&st1, st2) || isheadfail(p1)) { Instruction *p = auxnew(L, &op, size, l1 + 1 + l2); @@ -1456,10 +1423,10 @@ static int union_l (lua_State *L) { Instruction *p1 = getpatt(L, 1, &l1); Instruction *p2 = getpatt(L, 2, &l2); CharsetTag st2; - if (p1->i.code == IFail) /* check for identity element */ - lua_pushvalue(L, 2); - else if (p2->i.code == IFail) - lua_pushvalue(L, 1); + if (isfail(p1)) /* check for simple identities */ + lua_pushvalue(L, 2); /* fail / a == a */ + else if (isfail(p2) || issucc(p1)) + lua_pushvalue(L, 1); /* a / fail == a; true / a == true */ else { tocharset(p2, &st2); separateparts(L, p1, l1, l2, &size, &st2); @@ -1477,7 +1444,6 @@ static int repeatcharset (lua_State *L, Charset cs, int l1, int n) { } setinst(p, ISpan, 0); loopset(k, p[1].buff[k] = cs[k]); - correctset(p); return 1; } @@ -1598,7 +1564,6 @@ static int capture_aux (lua_State *L, int kind, int labelidx) { static int capture_l (lua_State *L) { return capture_aux(L, Csimple, 0); } static int tcapture_l (lua_State *L) { return capture_aux(L, Ctable, 0); } static int capsubst_l (lua_State *L) { return capture_aux(L, Csubst, 0); } -static int capaccum_l (lua_State *L) { return capture_aux(L, Caccum, 0); } static int rcapture_l (lua_State *L) { switch (lua_type(L, 2)) { @@ -1610,29 +1575,43 @@ static int rcapture_l (lua_State *L) { } -static int position_l (lua_State *L) { - Instruction *p = newpatt(L, 1); - setinstcap(p, IEmptyCapture, 0, Cposition, 0); - return 1; +static int fold_l (lua_State *L) { + luaL_checktype(L, 2, LUA_TFUNCTION); + return capture_aux(L, Cfold, 2); } -static int emptycap_aux (lua_State *L, int kind, const char *msg) { - int n = luaL_checkint(L, 1); +static int group_l (lua_State *L) { + if (lua_isnoneornil(L, 2)) + return capture_aux(L, Cgroup, 0); + else { + luaL_checkstring(L, 2); + return capture_aux(L, Cgroup, 2); + } +} + + +static int position_l (lua_State *L) { Instruction *p = newpatt(L, 1); - luaL_argcheck(L, 0 < n && n <= SHRT_MAX, 1, msg); - setinstcap(p, IEmptyCapture, n, kind, 0); + setinstcap(p, IEmptyCapture, 0, Cposition, 0); return 1; } static int backref_l (lua_State *L) { - return emptycap_aux(L, Cbackref, "invalid back reference"); + Instruction *p = newpatt(L, 1); + int n = getlabel(L, 1); + setinstcap(p, IEmptyCaptureIdx, n, Cbackref, 0); + return 1; } static int argcap_l (lua_State *L) { - return emptycap_aux(L, Carg, "invalid argument index"); + int n = luaL_checkint(L, 1); + Instruction *p = newpatt(L, 1); + luaL_argcheck(L, 0 < n && n <= SHRT_MAX, 1, "invalid argument index"); + setinstcap(p, IEmptyCapture, n, Carg, 0); + return 1; } @@ -1652,8 +1631,9 @@ static int matchtime_l (lua_State *L) { static int capconst_l (lua_State *L) { int i, j; int n = lua_gettop(L); - Instruction *p = newpatt(L, n); + Instruction *p = newpatt(L, n > 1 ? n + 2 : n); lua_createtable(L, n, 0); /* new environment for the new pattern */ + if (n > 1) setinstcap(p++, IOpenCapture, 0, Cgroup, 0); for (i = j = 1; i <= n; i++) { if (lua_isnil(L, i)) setinstcap(p++, IEmptyCaptureIdx, 0, Cconst, 0); @@ -1663,6 +1643,7 @@ static int capconst_l (lua_State *L) { lua_rawseti(L, -2, j++); } } + if (n > 1) setinstcap(p++, ICloseCapture, 0, Cclose, 0); lua_setfenv(L, -2); /* set environment */ return 1; } @@ -1734,7 +1715,8 @@ typedef struct CapState { #define isfullcap(cap) ((cap)->siz != 0) -#define pushluaval(cs) lua_rawgeti((cs)->L, penvidx((cs)->ptop), (cs)->cap->idx) +#define getfromenv(cs,v) lua_rawgeti((cs)->L, penvidx((cs)->ptop), v) +#define pushluaval(cs) getfromenv(cs, (cs)->cap->idx) #define pushsubject(cs, c) lua_pushlstring((cs)->L, (c)->s, (c)->siz - 1) @@ -1743,8 +1725,8 @@ typedef struct CapState { static void updatecache_ (CapState *cs, int v) { - lua_rawgeti(cs->L, penvidx(cs->ptop), v); - lua_replace(cs->L, subscache(cs->ptop)); + getfromenv(cs, v); + lua_replace(cs->L, subscache(cs)); cs->valuecached = v; } @@ -1763,23 +1745,22 @@ static Capture *findopen (Capture *cap) { } -static Capture *findback (CapState *cs, Capture *cap, int n) { - int i; - for (i = 0; i < n; i++) { - if (cap == cs->ocap) - luaL_error(cs->L, "invalid back reference (%d)", n); - cap--; - if (isclosecap(cap)) - cap = findopen(cap); - else if (!isfullcap(cap)) - i--; /* does not count enclosing captures */ +static Capture *nextcap (Capture *cap) { + if (isfullcap(cap)) return cap + 1; + else { + int n = 0; + for (;;) { + cap++; + if (isclosecap(cap)) { + if (n-- == 0) return cap + 1; + } + else if (!isfullcap(cap)) n++; + } } - assert(!isclosecap(cap)); - return cap; } -static int pushallcaptures (CapState *cs, int addextra) { +static int pushallvalues (CapState *cs, int addextra) { Capture *co = cs->cap; int n = 0; if (isfullcap(cs->cap++)) { @@ -1797,37 +1778,68 @@ static int pushallcaptures (CapState *cs, int addextra) { } -static int simplecap (CapState *cs) { - int n; - lua_pushnil(cs->L); /* open space */ - n = pushallcaptures(cs, 1); - lua_replace(cs->L, -(n + 1)); /* put extra in previously opened slot */ - return n; +static Capture *findback (CapState *cs, Capture *cap) { + lua_State *L = cs->L; + for (;;) { + if (cap == cs->ocap) { /* not found */ + const char *s = lua_tostring(L, -1); + if (s == NULL) s = lua_pushfstring(L, "(a %s)", luaL_typename(L, -1)); + luaL_error(L, "back reference '%s' not found", s); + } + cap--; + if (isclosecap(cap)) + cap = findopen(cap); + else if (!isfullcap(cap)) + continue; /* opening an enclosing capture: skip and get previous */ + if (captype(cap) == Cgroup) { + getfromenv(cs, cap->idx); /* get group name */ + if (lua_equal(L, -2, -1)) { /* right group? */ + lua_pop(L, 2); /* remove reference name and group name */ + return cap; + } + else lua_pop(L, 1); /* remove group name */ + } + } } static int backrefcap (CapState *cs) { - int n = (cs->cap)->idx; + int n; Capture *curr = cs->cap; - Capture *backref = findback(cs, curr, n); - cs->cap = backref; - n = pushcapture(cs); + pushluaval(cs); /* reference name */ + cs->cap = findback(cs, curr); + n = pushallvalues(cs, 0); cs->cap = curr + 1; return n; } static int tablecap (CapState *cs) { + lua_State *L = cs->L; int n = 0; - lua_newtable(cs->L); + lua_newtable(L); if (isfullcap(cs->cap++)) return 1; /* table is empty */ while (!isclosecap(cs->cap)) { - int i; - int k = pushcapture(cs); - for (i = k; i > 0; i--) - lua_rawseti(cs->L, -(i + 1), n + i); - n += k; + if (captype(cs->cap) == Cgroup && cs->cap->idx != 0) { /* named group? */ + int k; + pushluaval(cs); /* push group name */ + k = pushallvalues(cs, 0); + if (k == 0) { /* no value? */ + lua_pop(L, 1); /* remove group name */ + continue; /* and go on */ + } + else if (k > 1) + lua_pop(L, k - 1); /* keep just one value */ + lua_settable(L, -3); + } + else { + int i; + int k = pushcapture(cs); + for (i = k; i > 0; i--) + lua_rawseti(L, -(i + 1), n + i); + n += k; + } } cs->cap++; /* skip close entry */ return 1; @@ -1836,11 +1848,11 @@ static int tablecap (CapState *cs) { static int querycap (CapState *cs) { int idx = cs->cap->idx; - int n = pushallcaptures(cs, 0); + int n = pushallvalues(cs, 0); if (n > 1) /* extra captures? */ lua_pop(cs->L, n - 1); /* throw them away */ updatecache(cs, idx); - lua_gettable(cs->L, subscache(cs->ptop)); + lua_gettable(cs->L, subscache(cs)); if (!lua_isnil(cs->L, -1)) return 1; else { @@ -1850,20 +1862,22 @@ static int querycap (CapState *cs) { } -static int accumcap (CapState *cs) { +static int foldcap (CapState *cs) { + int n; lua_State *L = cs->L; - if (isfullcap(cs->cap++) || isclosecap(cs->cap) || pushcapture(cs) != 1) - return luaL_error(L, "no initial value for accumulator capture"); + int idx = cs->cap->idx; + if (isfullcap(cs->cap++) || isclosecap(cs->cap) || (n = pushcapture(cs)) == 0) + return luaL_error(L, "no initial value for fold capture"); + if (n > 1) + lua_pop(L, n - 1); /* leave only one result */ while (!isclosecap(cs->cap)) { - int n; - if (captype(cs->cap) != Cfunction) - return luaL_error(L, "invalid (non function) capture to accumulate"); - pushluaval(cs); - lua_insert(L, -2); /* put function before previous capture */ - n = pushallcaptures(cs, 0); - lua_call(L, n + 1, 1); - } - cs->cap++; + updatecache(cs, idx); + lua_pushvalue(L, subscache(cs)); /* get folding function */ + lua_insert(L, -2); /* put it before accumulator */ + n = pushcapture(cs); /* get other captures */ + lua_call(L, n + 1, 1); /* call folding function */ + } + cs->cap++; /* skip close entry */ return 1; } @@ -1872,7 +1886,7 @@ static int functioncap (CapState *cs) { int n; int top = lua_gettop(cs->L); pushluaval(cs); - n = pushallcaptures(cs, 0); + n = pushallvalues(cs, 0); lua_call(cs->L, n, LUA_MULTRET); return lua_gettop(cs->L) - top; } @@ -1892,7 +1906,7 @@ static int runtimecap (lua_State *L, Capture *close, Capture *ocap, pushluaval(&cs); lua_pushvalue(L, SUBJIDX); /* push original subject */ lua_pushinteger(L, s - o + 1); /* current position */ - n = pushallcaptures(&cs, 0); + n = pushallvalues(&cs, 0); lua_call(L, n + 2, LUA_MULTRET); return close - open; } @@ -1900,36 +1914,55 @@ static int runtimecap (lua_State *L, Capture *close, Capture *ocap, typedef struct StrAux { - const char *s; - const char *e; + int isstring; + union { + Capture *cp; + struct { + const char *s; + const char *e; + } s; + } u; } StrAux; #define MAXSTRCAPS 10 static int getstrcaps (CapState *cs, StrAux *cps, int n) { int k = n++; - if (k < MAXSTRCAPS) cps[k].s = cs->cap->s; + cps[k].isstring = 1; + cps[k].u.s.s = cs->cap->s; if (!isfullcap(cs->cap++)) { while (!isclosecap(cs->cap)) { - if (captype(cs->cap) != Csimple) - return luaL_error(cs->L, - "invalid capture #%d in replacement pattern", n); - n = getstrcaps(cs, cps, n); + if (n >= MAXSTRCAPS) /* too many captures? */ + cs->cap = nextcap(cs->cap); /* skip it */ + else if (captype(cs->cap) == Csimple) + n = getstrcaps(cs, cps, n); + else { + cps[n].isstring = 0; + cps[n].u.cp = cs->cap; + cs->cap = nextcap(cs->cap); + n++; + } } cs->cap++; /* skip close */ } - if (k < MAXSTRCAPS) cps[k].e = closeaddr(cs->cap - 1); + cps[k].u.s.e = closeaddr(cs->cap - 1); return n; } +/* +** add next capture (which should be a string) to buffer +*/ +static int addonestring (luaL_Buffer *b, CapState *cs, const char *what); + + static void stringcap (luaL_Buffer *b, CapState *cs) { StrAux cps[MAXSTRCAPS]; int n; size_t len, i; const char *c; updatecache(cs, cs->cap->idx); - c = lua_tolstring(cs->L, subscache(cs->ptop), &len); + c = lua_tolstring(cs->L, subscache(cs), &len); n = getstrcaps(cs, cps, 0) - 1; for (i = 0; i < len; i++) { if (c[i] != '%' || c[++i] < '0' || c[i] > '9') @@ -1937,45 +1970,66 @@ static void stringcap (luaL_Buffer *b, CapState *cs) { else { int l = c[i] - '0'; if (l > n) - luaL_error(cs->L, "invalid capture index (%c)", c[i]); - luaL_addlstring(b, cps[l].s, cps[l].e - cps[l].s); + luaL_error(cs->L, "invalid capture index (%d)", l); + else if (cps[l].isstring) + luaL_addlstring(b, cps[l].u.s.s, cps[l].u.s.e - cps[l].u.s.s); + else { + Capture *curr = cs->cap; + cs->cap = cps[l].u.cp; + if (addonestring(b, cs, "capture") == 0) + luaL_error(cs->L, "no values in capture index %d", l); + cs->cap = curr; + } } } } -static void substcap (CapState *cs) { - luaL_Buffer b; - const char *curr = (cs->cap - 1)->s; - luaL_buffinit(cs->L, &b); - while (!isclosecap(cs->cap)) { - int n; - const char *next = cs->cap->s; - luaL_addlstring(&b, curr, next - curr); - if (captype(cs->cap) == Cstring) - stringcap(&b, cs); /* add capture directly to buffer */ - else if ((n = pushcapture(cs)) == 0) { /* no capture? */ - curr = next; /* result keeps the original text */ - continue; +static void substcap (luaL_Buffer *b, CapState *cs) { + const char *curr = cs->cap->s; + if (isfullcap(cs->cap)) /* no nested captures? */ + luaL_addlstring(b, curr, cs->cap->siz - 1); /* keep original text */ + else { + cs->cap++; + while (!isclosecap(cs->cap)) { + const char *next = cs->cap->s; + luaL_addlstring(b, curr, next - curr); /* add text up to capture */ + if (addonestring(b, cs, "replacement") == 0) /* no capture value? */ + curr = next; /* keep original text in final result */ + else + curr = closeaddr(cs->cap - 1); /* continue after match */ } - else { - if (n > 1) lua_pop(cs->L, n - 1); /* ignore extra values */ - if (!lua_isstring(cs->L, -1)) - luaL_error(cs->L, "invalid replacement value (a %s)", - luaL_typename(cs->L, -1)); - luaL_addvalue(&b); /* add result to accumulator */ + luaL_addlstring(b, curr, cs->cap->s - curr); /* add last piece of text */ + } + cs->cap++; /* go to next capture */ +} + + +static int addonestring (luaL_Buffer *b, CapState *cs, const char *what) { + switch (captype(cs->cap)) { + case Cstring: + stringcap(b, cs); /* add capture directly to buffer */ + return 1; + case Csubst: + substcap(b, cs); /* add capture directly to buffer */ + return 1; + default: { + lua_State *L = cs->L; + int n = pushcapture(cs); + if (n > 0) { + if (n > 1) lua_pop(L, n - 1); /* only one result */ + if (!lua_isstring(L, -1)) + luaL_error(L, "invalid %s value (a %s)", what, luaL_typename(L, -1)); + luaL_addvalue(b); + } + return n; } - /* continue after match */ - curr = closeaddr(cs->cap - 1); } - luaL_addlstring(&b, curr, cs->cap->s - curr); - luaL_pushresult(&b); - cs->cap++; } static int pushcapture (CapState *cs) { - luaL_checkstack(cs->L, 4, "too many unstored captures"); + luaL_checkstack(cs->L, 4, "too many captures"); switch (captype(cs->cap)) { case Cposition: { lua_pushinteger(cs->L, cs->cap->s - cs->s + 1); @@ -1995,21 +2049,19 @@ static int pushcapture (CapState *cs) { return 1; } case Csimple: { - if (isfullcap(cs->cap)) { - pushsubject(cs, cs->cap); - cs->cap++; - return 1; - } - else return simplecap(cs); + int k = pushallvalues(cs, 1); + if (k > 1) + lua_insert(cs->L, -k); /* whole match is first result */ + return k; } case Cruntime: { - int i = 0; + int n = 0; while (!isclosecap(cs->cap++)) { - luaL_checkstack(cs->L, 4, "too many unstored captures"); + luaL_checkstack(cs->L, 4, "too many captures"); lua_pushvalue(cs->L, (cs->cap - 1)->idx); - i++; + n++; } - return i; + return n; } case Cstring: { luaL_Buffer b; @@ -2019,17 +2071,25 @@ static int pushcapture (CapState *cs) { return 1; } case Csubst: { - if (isfullcap(cs->cap++)) /* no changes? */ - pushsubject(cs, cs->cap - 1); /* push original subject */ - else - substcap(cs); + luaL_Buffer b; + luaL_buffinit(cs->L, &b); + substcap(&b, cs); + luaL_pushresult(&b); return 1; } + case Cgroup: { + if (cs->cap->idx == 0) /* anonymous group? */ + return pushallvalues(cs, 0); /* add all nested values */ + else { /* named group: add no values */ + cs->cap = nextcap(cs->cap); /* skip capture */ + return 0; + } + } case Cbackref: return backrefcap(cs); case Ctable: return tablecap(cs); case Cfunction: return functioncap(cs); case Cquery: return querycap(cs); - case Caccum: return accumcap(cs); + case Cfold: return foldcap(cs); default: assert(0); return 0; } } @@ -2071,6 +2131,37 @@ static int type_l (lua_State *L) { } +static void createcat (lua_State *L, const char *catname, int (catf) (int)) { + Instruction *p = newcharset(L); + int i; + for (i = 0; i < CHAR_MAX; i++) + if (catf(i)) setchar(p[1].buff, i); + lua_setfield(L, -2, catname); +} + + +static int locale_l (lua_State *L) { + if (lua_isnoneornil(L, 1)) { + lua_settop(L, 0); + lua_createtable(L, 0, 12); + } + else + luaL_checktype(L, 1, LUA_TTABLE); + createcat(L, "alnum", isalnum); + createcat(L, "alpha", isalpha); + createcat(L, "cntrl", iscntrl); + createcat(L, "digit", isdigit); + createcat(L, "graph", isgraph); + createcat(L, "lower", islower); + createcat(L, "print", isprint); + createcat(L, "punct", ispunct); + createcat(L, "space", isspace); + createcat(L, "upper", isupper); + createcat(L, "xdigit", isxdigit); + return 1; +} + + static int printpat_l (lua_State *L) { Instruction *p = getpatt(L, 1, NULL); int n, i; @@ -2118,9 +2209,11 @@ static int matchl (lua_State *L) { static struct luaL_reg pattreg[] = { {"match", matchl}, {"print", printpat_l}, + {"locale", locale_l}, {"C", capture_l}, - {"Ca", capaccum_l}, + {"Cf", fold_l}, {"Cc", capconst_l}, + {"Cg", group_l}, {"Cp", position_l}, {"Cb", backref_l}, {"Carg", argcap_l}, diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c b/Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c index 8e27995a414..ddb26d476ee 100644 --- a/Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c +++ b/Build/source/texk/web2c/luatexdir/luasocket/src/lua_preload.c @@ -13,61 +13,17 @@ #include "mime_lua.c" -void luatex_socketlua_open (lua_State *L) { - lua_getglobal(L, "package"); - lua_getfield(L, -1, "loaded"); - if (!lua_istable(L,-1)) { - lua_newtable(L); - lua_setfield(L, -2, "loaded"); - lua_getfield(L, -1, "loaded"); - } - if(!luatex_socket_lua_open(L)) { - lua_setfield(L, -2, "socket"); - } else { - fprintf(stderr,"FATAL error while preloading lua modules"); - exit(1); - } - if(!luatex_ltn12_lua_open(L)) { - lua_setfield(L, -2, "ltn12"); - } else { - fprintf(stderr,"FATAL error while preloading lua modules"); - exit(1); - } - if(!luatex_mime_lua_open(L)) { - lua_setfield(L, -2, "mime"); - } else { - fprintf(stderr,"FATAL error while preloading lua modules"); - exit(1); - } - if(!luatex_url_lua_open(L)) { - lua_setfield(L, -2, "socket.url"); - } else { - fprintf(stderr,"FATAL error while preloading lua modules"); - exit(1); - } - if(!luatex_tp_lua_open(L)) { - lua_setfield(L, -2, "socket.tp"); - } else { - fprintf(stderr,"FATAL error while preloading lua modules"); - exit(1); - } - if(!luatex_smtp_lua_open(L)) { - lua_setfield(L, -2, "socket.smtp"); - } else { - fprintf(stderr,"FATAL error while preloading lua modules"); - exit(1); - } - if(!luatex_http_lua_open(L)) { - lua_setfield(L, -2, "socket.http"); - } else { - fprintf(stderr,"FATAL error while preloading lua modules"); - exit(1); - } - if(!luatex_ftp_lua_open(L)) { - lua_setfield(L, -2, "socket.ftp"); - } else { +void +luatex_socketlua_open (lua_State *L) { + if(luatex_socket_lua_open(L) || + luatex_ltn12_lua_open(L) || + luatex_mime_lua_open(L) || + luatex_url_lua_open(L) || + luatex_tp_lua_open(L) || + luatex_smtp_lua_open(L) || + luatex_http_lua_open(L) || + luatex_ftp_lua_open(L)) { fprintf(stderr,"FATAL error while preloading lua modules"); exit(1); } - lua_pop(L,2); } diff --git a/Build/source/texk/web2c/luatexdir/luatex-api.h b/Build/source/texk/web2c/luatexdir/luatex-api.h index 8cb7363e216..9e7ba2a16b0 100644 --- a/Build/source/texk/web2c/luatexdir/luatex-api.h +++ b/Build/source/texk/web2c/luatexdir/luatex-api.h @@ -126,3 +126,4 @@ extern command_item command_names[]; extern int callback_callbacks_id; extern void luainterpreter(void); + diff --git a/Build/source/texk/web2c/luatexdir/luatex.defines b/Build/source/texk/web2c/luatexdir/luatex.defines index b4e5baeba34..49795fdffd7 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.defines +++ b/Build/source/texk/web2c/luatexdir/luatex.defines @@ -37,6 +37,7 @@ @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(); @@ -76,6 +77,7 @@ @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(); @@ -172,6 +174,10 @@ @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 ; @@ -202,6 +208,10 @@ @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; @@ -240,8 +250,7 @@ @define procedure flush_loggable_info; @define var extra_version_info; -@define var SVN_REV; -@define procedure do_write_wterm(); +@define procedure write_svnversion(); { bits and pieces from aleph } @@ -648,9 +657,6 @@ @define procedure initialize_math; @define procedure show_math_node(); -@define procedure print_math_comp(); -@define procedure print_limit_switch(); -@define procedure print_style(); @define procedure scan_extdef_math_code(); @define procedure scan_extdef_del_code(); @@ -661,19 +667,18 @@ @define procedure undump_math_data; @define procedure unsave_math_data(); -@define const fence_noad; -@define const ord_noad; -@define const op_noad; -@define const bin_noad; -@define const rel_noad; -@define const open_noad; -@define const close_noad; -@define const punct_noad; -@define const inner_noad; -@define const limits; -@define const no_limits; -@define const under_noad; -@define const over_noad; +@define const 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; @@ -681,7 +686,6 @@ @define const middle_noad_side ; @define const right_noad_side ; -@define procedure print_size(); @define procedure finish_display_alignment(); @define function new_sub_box(); @define function math_vcenter_group(); diff --git a/Build/source/texk/web2c/luatexdir/luatex.web b/Build/source/texk/web2c/luatexdir/luatex.web index df2a5372c85..5fd9825a867 100644 --- a/Build/source/texk/web2c/luatexdir/luatex.web +++ b/Build/source/texk/web2c/luatexdir/luatex.web @@ -1,5 +1,5 @@ % luatex.web -% +% % Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org> % Copyright 2006-2009 Hartmut Henkel <hartmut@@luatex.org> % @@ -249,11 +249,12 @@ known as `\eTeX'. @d pdftex_revision=="0" { \.{\\pdftexrevision} } @d pdftex_version_string=='-2.00.0' {current \pdfTeX\ version} @# -@d luatex_version==37 { \.{\\luatexversion} } +@d luatex_version==39 { \.{\\luatexversion} } @d luatex_revision=="0" { \.{\\luatexrevision} } -@d luatex_version_string=='snapshot-0.37.0' {current \LuaTeX\ version} +@d luatex_version_string=='snapshot-0.39.0' {current \LuaTeX\ version} @d luatex_date_info==-extra_version_info { the compile date is negated } -@d luatex_svnversion==SVN_REV { as proposed by Peter M\"unster } +@d luatex_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} @@ -337,7 +338,7 @@ procedure initialize; {this procedure gets things started properly} @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. +doesn't know how to deal with symbolic case labels. @d hlist_node_case==0 @d vlist_node_case==1 @@ -998,20 +999,20 @@ Signalling this fact is achieved by having two arrays of integers. @!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 +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; + texinputtype:=0; read_file_callback_id[n] := 0; end; callback_id:=callback_defined(find_read_file_callback); @@ -1020,8 +1021,8 @@ begin 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 + end + else file_ok:=false; {file not found} end; if file_ok then begin @@ -1032,10 +1033,10 @@ begin lua_a_open_in := true; if n=0 then input_file_callback_id[index] := k - else + else read_file_callback_id[n] := k; end - else + else file_ok:=false; {read failed} end else begin {no read callback} @@ -1043,7 +1044,7 @@ begin lua_a_open_in := a_open_in(f,kpsetexformat); name_file_pointer := f; end - else + else file_ok:=false; {open failed} end; end; @@ -1069,9 +1070,9 @@ begin lua_a_open_out := do_a_open_out(f); name_file_pointer := f; end - else + else lua_a_open_out := false; - end + end else begin if openoutnameok(stringcast(nameoffile+1)) then begin lua_a_open_out := a_open_out(f); @@ -1097,9 +1098,9 @@ begin lua_b_open_out := do_b_open_out(f); name_file_pointer := f; end - else + else lua_b_open_out := false; - end + end else begin if openoutnameok(stringcast(nameoffile+1)) then begin lua_b_open_out := b_open_out(f); @@ -1110,7 +1111,7 @@ begin end; end; -@ +@ @<Fixup |nameoffile| after callback@>= libcfree (nameoffile); nameoffile := xmallocarray (packed_ASCII_code, length(fnam)+2); @@ -1145,7 +1146,7 @@ end; @ - + @p procedure lua_a_close_in(var f:alpha_file; n:quarterword); {close a text file} var ret:boolean; callback_id:integer; @@ -1262,7 +1263,7 @@ var lua_result:boolean; begin if n=0 then callback_id:=input_file_callback_id[index] -else +else callback_id:=read_file_callback_id[n]; if callback_id>0 then begin last:=first; @@ -1270,11 +1271,11 @@ if callback_id>0 then begin 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; + if last>max_buf_stack then max_buf_stack:=last; lua_input_ln := true; - @<Fix up the input buffer using callbacks@>; + @<Fix up the input buffer using callbacks@>; end - else + else lua_input_ln := false; end else begin @@ -1282,23 +1283,23 @@ if callback_id>0 then begin lua_result := input_ln(f,bypass_p); if lua_result=true then begin lua_input_ln := true; - @<Fix up the input buffer using callbacks@>; + @<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)); + 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; + if last>max_buf_stack then max_buf_stack:=last; end; end; end @@ -1375,7 +1376,7 @@ if format_ident=0 then begin writeln(term_out,'Buffer size exceeded!'); goto final_end; @.Buffer size exceeded@> end -else +else check_buffer_overflow(buf_size+10) { need a little bit more} @ Different systems have different ways to get started. But regardless of @@ -1459,7 +1460,7 @@ 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|. +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 @@ -1540,7 +1541,7 @@ 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. +buffer, and returns its character value. @d flush_string==begin decr(str_ptr); pool_ptr:=str_start_macro(str_ptr); end @@ -1573,7 +1574,7 @@ begin b := buffer[k+3]; test_sequence_byte(b); a := a + (b-128); - end + end else if b>=@"E0 then begin a := (b-@"E0) * 64; b := buffer[k+1]; @@ -1582,7 +1583,7 @@ begin b := buffer[k+2]; test_sequence_byte(b); a := a + (b-128); - end + end else if b>=@"C0 then begin a := (b-@"C0) * 64; b := buffer[k+1]; @@ -1597,7 +1598,7 @@ begin deletions_allowed:=false; error; deletions_allowed:=true; a:=@"FFFD; end; -exit: +exit: buffer_to_unichar := a; end ; @@ -1615,9 +1616,9 @@ 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; +begin result:=false; if s<string_offset then begin - a := buffer_to_unichar(k); + a := buffer_to_unichar(k); if a<>s then goto not_found; end else begin @@ -1652,7 +1653,7 @@ if s<string_offset then begin goto found; a := pool_to_unichar(str_start_macro(t)); if a<>s then goto not_found; - end + end else if t<>s then goto not_found; end @@ -1663,8 +1664,8 @@ else if t<string_offset then begin goto found; a := pool_to_unichar(str_start_macro(s)); if a<>t then goto not_found; - end -else begin + 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 @@ -1846,8 +1847,8 @@ using the |xchr| array to map it into an external character compatible with 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]); + 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 @@ -1870,7 +1871,7 @@ begin if @<Character |s| is the current new-line character@> then begin print_ln; return; end; case selector of -term_and_log: begin +term_and_log: begin fix_term_offset(s); fix_log_offset(s); wterm_char(s); wlog(xchr[s]); incr(term_offset); incr(file_offset); @@ -1881,13 +1882,13 @@ term_and_log: begin begin wlog_cr; file_offset:=0; end; end; -log_only: begin +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); +term_only: begin + fix_term_offset(s); wterm_char(s); incr(term_offset); if term_offset=max_print_line then print_ln; end; @@ -1912,9 +1913,9 @@ 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 +\.{\\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"); @@ -1941,7 +1942,7 @@ begin a := (a + (b-128)) * 64; b := str_pool[t+2]; a := a + (b-128); - end + end else if b>=@"C0 then begin a := (b-@"C0) * 64; b := str_pool[t+1]; @@ -1966,9 +1967,9 @@ 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 +else if s<string_offset then begin if s<0 then s:="???" {can't happen} - else begin + 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} @@ -1987,9 +1988,9 @@ else if s<string_offset then 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 + end + else begin + if s>=@"110000 then print_char(s-@"110000) else begin print_char(@"F0 + (s div @"40000)); @@ -2000,6 +2001,7 @@ else if s<string_offset then 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 } @@ -2126,7 +2128,7 @@ 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 @@ -2172,11 +2174,11 @@ The input is placed into locations |first| through |last-1| of the This procedure is never called when |interaction<scroll_mode|. @<Basic print...@>= -procedure prompt_input(s:str_number); +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} @@ -2325,7 +2327,7 @@ in reverse order, i.e., with |help_line[0]| appearing last. @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 +@p procedure dohelp5 (@!a,b,c,d,e:str_number); begin help5(a)(b)(c)(d)(e); @@ -2395,7 +2397,7 @@ callback_id:integer; {used to save global variables when deleting tokens} @!t:boolean; begin if history<error_message_issued then history:=error_message_issued; -print_char("."); +print_char("."); callback_id := callback_defined(show_error_hook_callback) ; if callback_id>0 then t := run_callback(callback_id,'->'); show_context; @@ -2663,7 +2665,7 @@ a way to make |interrupt| nonzero using the \PASCAL\ debugger. @!static_local_base:integer; {C version of |local_base|} @ @p procedure check_interrupt; -begin +begin if interrupt<>0 then pause_for_instructions; end; @@ -3180,11 +3182,13 @@ 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 + 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 + 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|} @@ -3198,11 +3202,13 @@ if c<0 then begin negate(c); negate(d); end; if d<=0 then - begin if b>=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); - if d=0 then + 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 @@ -3426,7 +3432,7 @@ 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 +|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 @@ -3448,15 +3454,15 @@ value represents a null pointer. \TeX\ does not assume that |mem[null]| exists. end; -@ The |mem| array is divided into two items that are allocated separately; +@ 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 +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 @@ -3510,7 +3516,7 @@ pinpoint the trouble. 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|. +|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} @@ -3645,7 +3651,7 @@ 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; @@ -3654,7 +3660,7 @@ attr_list_cache:pointer; 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. +attributes in eqtb. @p function get_attribute(i:halfword):halfword; begin @@ -3705,7 +3711,7 @@ The |subtype| field is set to |min_quarterword|, since that's the desired @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; +box_dir(p):=text_direction; new_null_box:=p; end; @@ -3727,7 +3733,7 @@ an hlist; the |height| and |depth| are never running in a~vlist. makes all the dimensions ``running,'' so you have to change the ones that are not allowed to run. -@p +@p function new_rule:pointer; var p:pointer; {the new node} begin p:=new_node(rule_node,0); {the |subtype| is not used} @@ -3776,7 +3782,7 @@ 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. +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 @@ -3804,7 +3810,7 @@ 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; + set_to_glyph(p); font(p):=f; character(p):=c; end; new_glyph:=p; end; @@ -3877,11 +3883,11 @@ 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 +|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|. +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.} @@ -3942,7 +3948,7 @@ 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|, +|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 @@ -4018,7 +4024,7 @@ 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); +begin q:=copy_node(p); glue_ref_count(q):=null; new_spec:=q; end; @@ -4155,7 +4161,7 @@ the \.{WEB} macro definitions above, so that format changes will leave \TeX's other algorithms intact. @^system dependencies@> -@* \[11] Memory layout. +@* \[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 @@ -4169,7 +4175,7 @@ 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 +|hpack|), |align_head| (head of alignment preamble), and |end_span| (tail of spanned-width lists). @@ -4189,7 +4195,7 @@ initializing itself the slow~way. @ @<Initialize table entries...@>= procedure init_link_heads;forward; -init_node_mem(500); +init_node_mem(500); avail:=null; fix_mem_end:=0; init_list_heads; @<Initialize the special list heads and constant nodes@>; @@ -4201,8 +4207,8 @@ 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; 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; @@ -4248,7 +4254,7 @@ begin print_esc("FONT"); if pdf_font_blink(f) = null_font then print_int(f) - else + else print_int(pdf_font_blink(f)); end; if pdf_tracing_fonts > 0 then begin @@ -4273,7 +4279,7 @@ 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 + begin if lig_ptr(p)<>null then short_display(lig_ptr(p)) else begin if font(p)<>font_in_short_display then @@ -4420,7 +4426,7 @@ end; specification is being withdrawn. @^reference counts@> @d fast_delete_glue_ref(#)==@t@>@;@/ - begin if glue_ref_count(#)=null then begin + begin if glue_ref_count(#)=null then begin flush_node(#); end else decr(glue_ref_count(#)); @@ -4551,7 +4557,7 @@ expanded by `\.{\\the}'. @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} )} +@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}~)} @@ -4564,7 +4570,9 @@ expanded by `\.{\\the}'. @d ex_space=64 {explicit space ( \.{\\\ } )} @d no_boundary=65 {suppress boundary ligatures ( \.{\\noboundary} )} @d radical=66 {square root and similar signs ( \.{\\radical} )} -@d end_cs_name=67 {end control sequence ( \.{\\endcsname} )} +@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 @@ -4587,7 +4595,7 @@ 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 +|assign_xxx| commands and |xxx_val| expression values. That would break down otherwise. @d toks_register=max_non_prefixed_command+1 @@ -4688,7 +4696,7 @@ break down otherwise. {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 +@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 @@ -4774,13 +4782,13 @@ print(" mode"); end; function get_mode_id:integer; {returns the mode represented by |m|} var m:integer ; -begin +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"; + 2:get_mode_id := "m"; othercases get_mode_id := ""; end else if m=0 then get_mode_id := "n" @@ -4817,7 +4825,7 @@ 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|; +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. @@ -4841,6 +4849,8 @@ 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...@>= @@ -4851,13 +4861,13 @@ be pushed onto |nest| if necessary. @!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 delim_ptr==eTeX_aux {most recent left or right noad of a math left group} @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} @@ -4865,8 +4875,6 @@ be pushed onto |nest| if necessary. @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} -@d dir_math_save==cur_list.math_field - {should begin/end dir nodes be placed around mathematics?} @<Glob...@>= @!nest:array[0..nest_size] of list_state_record; @@ -4879,24 +4887,24 @@ be pushed onto |nest| if necessary. @ Here is a common way to make the current list grow: -@p +@p procedure tail_append(p:pointer); -begin +begin vlink(tail):=p; tail:=vlink(tail); end; @# procedure new_tail_append(p:pointer); -begin +begin couple_nodes(tail,p); tail:=vlink(tail); end; @# function pop_tail:pointer; label exit; var n,r:pointer; -begin +begin if tail<>head then begin r:=tail; - if vlink(alink(tail))=tail then + if vlink(alink(tail))=tail then n:=alink(tail) else begin n:=head; @@ -4907,7 +4915,7 @@ begin vlink(n):=null; pop_tail:=r; end - else + else pop_tail:=null; exit:end; @@ -4926,7 +4934,7 @@ 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; dir_math_save:=false; +dir_save:=null; init_math_fields; @<Start a new current page@>; @ @p @<LOCAL: Declare |make_local_par_node|@>; @@ -4945,7 +4953,7 @@ begin if nest_ptr>max_nest_stack then 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; dir_math_save:=false; +dir_save:=null; init_math_fields; eTeX_aux:=null; end; @@ -5025,7 +5033,7 @@ 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 +\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 @@ -5125,7 +5133,7 @@ locations for control sequences that are perpetually defined {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 undefined_control_sequence=frozen_null_ocp_list+number_ocp_lists @d glue_base=undefined_control_sequence+1 {beginning of region 3} @<Initialize table entries...@>= @@ -5291,6 +5299,7 @@ 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") @@ -5302,7 +5311,8 @@ else if n<mu_skip_base then end else begin print_esc("muskip"); print_int(n-mu_skip_base); print_char("="); print_spec(equiv(n),"mu"); - end + 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 @@ -5448,7 +5458,7 @@ 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 +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);@/ @@ -5460,6 +5470,7 @@ for k:="A" to "Z" do begin 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); @@ -5487,7 +5498,8 @@ else if n<cur_font_loc then 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]|@> +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("=");@/ @@ -6047,7 +6059,7 @@ complete failure. @<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:=-1; +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; @@ -6398,7 +6410,7 @@ A global boolean variable called |no_new_control_sequence| is set to @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+#) +@d ocp_list_id_text(#) == text(ocp_list_id_base+#) {a frozen ocp list identifier's name} @<Glob...@>= @@ -6411,7 +6423,7 @@ A global boolean variable called |no_new_control_sequence| is set to @ The extra set of functions make sure we can query the primitive meanings of thing s from C code -@p +@p function get_eq_type(p:integer):quarterword; begin get_eq_type := eq_type(p); @@ -6544,7 +6556,7 @@ begin if p<hash_base then { nullcs} 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 +else begin if is_active_csname(p) then print(active_csname_value(p)) else begin @@ -6656,6 +6668,8 @@ 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);@/ @@ -7398,7 +7412,7 @@ convention~(1), so it is declared in the following way: @!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} + @!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)} @@ -7759,7 +7773,7 @@ begin if (base_ptr=input_ptr) or (state<>token_list) or 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); + begin print_nl("OCP stack "); print_scaled(current_ocp_lstack); print(" entry "); print_int(current_ocp_no); print(":"); @<Pseudoprint the line@>; end @@ -7981,10 +7995,11 @@ begin if token_type>=backed_up then {token list to be deleted} end; end; end -else if token_type=u_template then +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; @@ -8002,9 +8017,10 @@ 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 +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; @@ -8013,9 +8029,10 @@ end; 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 + 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; @@ -8138,9 +8155,9 @@ 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 +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. @@ -8212,11 +8229,11 @@ Only a dozen or so command codes |>max_command| can possibly be returned by |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 +@ 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|. +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 @@ -8263,7 +8280,7 @@ var t:halfword; {token that is being ``expanded after''} {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 +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; @@ -8289,7 +8306,7 @@ 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@> +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} @@ -8327,9 +8344,9 @@ if t>=cs_token_flag then end; end -@ The \.{\\primitive} handling. If the primitive meaning of the next +@ 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|. +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 @@ -8359,13 +8376,45 @@ if cur_cs<>undefined_primitive then begin cur_tok := (cur_cmd*string_offset)+cur_chr; cur_cs := 0; goto reswitch; - end + 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; + 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@>= @@ -8435,14 +8484,14 @@ while p<>null do 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 + 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); + p:=link(p); end; if j>first then begin no_new_control_sequence:=false; cur_cs:=id_lookup(first,j-first); @@ -8517,7 +8566,7 @@ 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 +@ 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|. @@ -8553,7 +8602,7 @@ in |fire_up| and |vsplit| do not have to traverse the full range @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 +@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 @@ -8753,7 +8802,7 @@ if cur_tok=info(r) then @<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 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 @@ -8836,21 +8885,23 @@ 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 +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 + 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; + end @ @<Report an improper use...@>= begin print_err("Use of "); sprint_cs(warning_index); @@ -8870,11 +8921,12 @@ 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 + 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 @@ -8928,25 +8980,6 @@ if cur_cmd<>left_brace then end; end; -@ The |scan_right_brace| routine is called when a right brace is supposed to be -the next non-blank token. (The term ``right brace'' means, more precisely, -a character whose catcode is |right_brace|.) \TeX\ allows \.{\\relax} to -appear before the |right_brace|. - -@p procedure scan_right_brace; {reads a mandatory |right_brace|} -begin @<Get the next non-blank non-relax non-call token@>; -if cur_cmd<>right_brace then - begin print_err("Missing { inserted"); -@.Missing \{ inserted@> - help4("A right 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:=right_brace_token+"}"; cur_cmd:=right_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) @@ -9060,18 +9093,18 @@ the internal quantity to be scanned; an error will be signalled if @p procedure scan_something_internal(@!level:small_number;@!negative:boolean); {fetch an internal parameter} -label exit; +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 m:=cur_chr; +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: +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@>; @@ -9090,6 +9123,7 @@ 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|@>; @@ -9102,6 +9136,8 @@ 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@>; @@ -9117,7 +9153,7 @@ var m:halfword; {|chr_code| part of the operand token} @!level:small_number; { allowed level} @!negative:boolean; @!save_cur_chr:integer; -begin m:=subitem; level:=tok_val; +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); @@ -9127,6 +9163,7 @@ 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|@>; @@ -9139,7 +9176,7 @@ last_item: begin @<Fetch an item in the current node, if appropriate@>; cur_chr:=save_cur_chr; end; -char_given,math_given,omath_given,xmath_given: +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;@/ @@ -9173,7 +9210,7 @@ end @ @<Fetch an ext character code from some table@>= begin scan_char_num; -if m=math_code_base then begin +if m=math_code_base then begin cur_val1:=get_math_code_num(cur_val); scanned_result(cur_val1)(int_val); end @@ -9213,7 +9250,7 @@ begin cur_val1:=cur_chr; get_token; 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; + cur_val:=display_style; back_error; end else @@ -9425,7 +9462,7 @@ else begin if cur_chr=glue_val then cur_val:=zero_glue@+else cur_val:=0; 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 + {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 @@ -9517,12 +9554,13 @@ 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 +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) + else negate(cur_val); + end else if (cur_val_level>=glue_val)and(cur_val_level<=mu_val) then add_glue_ref(cur_val) @@ -9775,7 +9813,7 @@ 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; +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} @@ -9783,7 +9821,12 @@ var negative:boolean; {should the answer be negated?} @!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@>; @@ -9805,9 +9848,10 @@ such constants behave like numeric ones. begin get_token; {suppress macro expansion} if cur_tok<cs_token_flag then begin cur_val:=cur_chr; - if cur_cmd<=right_brace then + 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 @@ -10020,15 +10064,17 @@ 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"}). +\.{"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 +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; @@ -10055,6 +10101,7 @@ 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)"); @@ -10065,7 +10112,8 @@ else begin print_err("Illegal unit of measure ("); print("mu inserted)"); ("two letters. (See Chapter 27 of The TeXbook.)"); @:TeXbook}{\sl The \TeX book@> error; goto attach_fraction; - end + end; +end @ @<Adjust \(f)for the magnification ratio@>= begin prepare_mag; @@ -10245,7 +10293,7 @@ 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 +@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(#) @@ -10415,8 +10463,9 @@ such that |job_name_code| remains last. @d pdf_colorstack_init_code = pdftex_first_expand_code + 16 {command code for \.{\\pdfcolorstackinit}} @d luatex_revision_code = pdftex_first_expand_code + 17 {command code for \.{\\luatexrevision}} @d luatex_date_code = pdftex_first_expand_code + 18 {command code for \.{\\luatexdate}} -@d expanded_code = pdftex_first_expand_code + 19 {command code for \.{\\luatexdate}} -@d pdftex_convert_codes = pdftex_first_expand_code + 20 {end of \pdfTeX's command codes} +@d 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}} @@ -10471,6 +10520,8 @@ 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@> @# @@ -10629,9 +10680,10 @@ lua_escape_string_code: 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; + 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; @@ -10650,7 +10702,7 @@ 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 + 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; @@ -10671,7 +10723,7 @@ lua_code: luatokencall(s,sn); delete_token_ref(s); if u<>0 then begin - if str_ptr=u+1 then + if str_ptr=u+1 then decr(str_ptr) else begin {copy old string to the top location} i:=0; @@ -10679,7 +10731,7 @@ lua_code: while i<length(u) do str_pool[pool_ptr+i]:=str_pool[str_start_macro(u)+i]; end; - end; + end; if luacstrings>0 then lua_string_start; return; @@ -10715,7 +10767,7 @@ begin tracing_online:=i; end; end; -end +end @ @<Print the result of command |c|@>= case c of @@ -10782,6 +10834,7 @@ 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; @@ -10810,7 +10863,7 @@ 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); @@ -10820,7 +10873,7 @@ 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; + old_setting:=selector; selector:=new_string; is_known:=true; case c of @@ -10837,6 +10890,7 @@ begin 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 @@ -10961,11 +11015,12 @@ end unbalance:=1; loop@+ begin if xpand then @<Expand the next part of the input@> else get_token; - if cur_tok<right_brace_limit then + 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; + end else if cur_cmd=mac_param then if macro_def then @<Look for parameter number or \.{\#\#}@>; store_new_token(cur_tok); @@ -10994,7 +11049,7 @@ end @ @<Look for parameter number...@>= begin s:=cur_tok; if xpand then get_x_token else get_token; -if cur_cmd<>mac_param then +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...@> @@ -11005,6 +11060,7 @@ if cur_cmd<>mac_param then 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 @@ -11022,7 +11078,7 @@ and |normal| if it is open and ready to read the next line. @!read_open:array[0..16] of normal..closed; {state of |read_file[n]|} @ @<Set init...@>= -for k:=0 to 16 do begin +for k:=0 to 16 do begin read_open[k]:=closed; end; @@ -11249,9 +11305,9 @@ 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; +begin p:=new_node(if_node,0); vlink(p):=cond_ptr; if_limit_type(p):=if_limit; -if_limit_subtype(p):=cur_if; +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 @@ -11261,8 +11317,8 @@ 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); +cur_if:=if_limit_subtype(p); +if_limit:=if_limit_type(p); cond_ptr:=vlink(p); flush_node(p); end @@ -11410,7 +11466,7 @@ else b:=(type(p)=vlist_node); end @ An active character will be treated as category 13 following -\.{\\if\\noexpand} or following \.{\\ifcat\\noexpand}. +\.{\\if\\noexpand} or following \.{\\ifcat\\noexpand}. @d get_x_token_or_active_char==@t@>@; begin get_x_token; @@ -11770,7 +11826,7 @@ while not lua_a_open_out(addressof(log_file),0) do @<Try to get a different log log_file := name_file_pointer; log_name:=a_make_name_string(log_file); selector:=log_only; log_opened:=true; -if not callback_defined(start_run_callback) then begin +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("**"); @@ -11827,7 +11883,7 @@ loop@+ begin begin_file_reading; {set up |cur_file| and new level of input} end_file_reading; {remove the level that didn't work} prompt_file_name('input file name','.tex'); end; -done: +done: cur_file := name_file_pointer; name:=a_make_name_string(cur_file); if job_name=0 then @@ -11837,10 +11893,10 @@ if job_name=0 then 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("("); - slow_print(name); + print_char("("); + slow_print(name); end; -incr(open_parens); +incr(open_parens); update_terminal; state:=new_line; if name=str_ptr-1 then {we can conserve string pool space now} @@ -11909,11 +11965,11 @@ 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; +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 +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 @@ -11943,9 +11999,10 @@ 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 + 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); @@ -11958,12 +12015,13 @@ 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 + if n<=0 then @<Issue a font parameter error message, and return@> else begin - if n>font_params(f) then + 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: @@ -12010,7 +12068,7 @@ begin if tracing_lost_chars>0 then repeat dig[k]:=c mod 16; c:=c div 16; incr(k); until c=0; print_the_digs(k); - print(") in font "); + print(") in font "); print_font_name(f); print_char("!"); end_diagnostic(false); end; @@ -12167,7 +12225,7 @@ 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 +(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(#)==#] @@ -12200,7 +12258,7 @@ added to |i|, |j| and |k|, since $\Omega$ stores its quarterwords that way.) It does nothing. @<Initialize table...@>= -ocp_ptr:=null_ocp; +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):=""; @@ -12228,7 +12286,7 @@ 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)| +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@> @@ -12267,7 +12325,7 @@ information is stored; |null_ocp| is returned in this case. @!external_ocp:boolean) :internal_ocp_number; {input a \.{OCP} file} label done,bad_ocp,not_found; -var +var @!file_opened:boolean; {was |ocp_file| successfully opened?} @!k:integer; @!res:boolean; @@ -12284,12 +12342,12 @@ var @!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;@/ +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: +done: ocp_name(f):=nom; ocp_area(f):=aire; read_ocp_info:=g; end; @@ -12297,7 +12355,7 @@ end; @ $\Omega$ does not give precise details about why it rejects a particular \.{OCP} file. -@d start_ocp_error_message==print_err("Translation process "); +@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@>= @@ -12310,7 +12368,7 @@ help2("I wasn't able to read the data for this ocp,")@/ error @ @<Read and check the ocp data...@>= -if external_ocp then +if external_ocp then @<Check |ocp_file| exists@> else begin @<Open |ocp_file| for input@>; @@ -12455,7 +12513,7 @@ ocp_ptr:=f; g:=f; goto done; end -@ Before we forget about the format of these tables, let's deal with +@ 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@>= @@ -12522,14 +12580,14 @@ ocp_lstackmem_ptr:=1; @ @<Put each...@>= primitive_omega("nullocplist", set_ocp_list, null_ocp_list,0); -text(frozen_null_ocp_list) := "nullocplist"; +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; +@ @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 +begin p:=ocp_listmem_run_ptr; ocp_list_lstack(p):=llstack; ocp_list_lstack_no(p):=llstack_no; @@ -12543,7 +12601,7 @@ end; function make_ocp_lstack_node(locp:internal_ocp_number; llnext:ocp_lstack_index) : ocp_lstack_index; var p:ocp_lstack_index; -begin +begin p:=ocp_lstackmem_run_ptr; ocp_lstack_ocp(p):=locp; ocp_lstack_lnext(p):=llnext; @@ -12587,7 +12645,7 @@ if is_null_ocp_list(p) then begin ocp_list_lnext(p) := make_null_ocp_list; end else if ocp_list_lstack_no(p) > llstack_no then begin - ocp_list_lnext(p):= + ocp_list_lnext(p):= make_ocp_list_node(ocp_list_lstack(p), ocp_list_lstack_no(p), ocp_list_lnext(p)); @@ -12596,7 +12654,7 @@ else if ocp_list_lstack_no(p) > llstack_no then begin end else begin q:=ocp_list_lnext(p); - while (not (is_null_ocp_list(q))) and + 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; @@ -12646,7 +12704,7 @@ else begin while r <> 0 do begin p:=q; q:=r; r:=ocp_lstack_lnext(r); end; - ocp_lstack_lnext(p) := 0; + ocp_lstack_lnext(p) := 0; end end; end; @@ -12705,14 +12763,14 @@ print("]"); end; function scan_ocp_list: ocp_list_index; -var llstack_no:scaled; +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; +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 @@ -13433,7 +13491,7 @@ 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 +more than 256 different fonts per job, so the right font definition command must be selected. @d Incr_Decr(#) == # @@ -13447,8 +13505,9 @@ end @d out_cmd == begin if (oval<@"100)and(oval>=0) then begin - if (ocmd<>set1)or(oval>127) then + 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 @; @@ -13564,7 +13623,7 @@ and |z1-down1=x1-right1|. @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_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); @@ -14123,11 +14182,11 @@ rule_node_case: begin 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 begin +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)); + q:=vlink(no_break(p)); vlink(no_break(p)):=null; - vlink(p):=q; + vlink(p):=q; end; margin_kern_node_case:cur.h:=cur.h+width(p); kern_node_case: begin @@ -14411,7 +14470,7 @@ 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; +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; @@ -14497,7 +14556,7 @@ if list_ptr(p)=null then begin cur.v:=cur.v+effective_vertical; @<Record void list {\sl Sync\TeX} information@>; end -else begin +else begin edge_v:=cur.v; cur.h:=left_edge + basepoint_horizontal; cur.v:=cur.v + basepoint_vertical; @@ -14678,8 +14737,8 @@ 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); +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"); @@ -14687,7 +14746,7 @@ if (tracing_output>0)and(pre_callback_id=0) then end; if pre_callback_id>0 then ret:=run_callback(pre_callback_id,'->') -else begin +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; @@ -14698,17 +14757,17 @@ else begin end; end; update_terminal; -if (tracing_output>0)and(post_callback_id=0) then +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 +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 +if post_callback_id>0 then ret:=run_callback(post_callback_id,'->'); @<Finish sheet {\sl Sync\TeX} information record@>; end; @@ -14817,10 +14876,10 @@ while cur_s>-1 do end; decr(cur_s); end; -if total_pages=0 then begin +if total_pages=0 then begin if callback_id=0 then print_nl("No pages of output.") - else + else if callback_id>0 then res:=run_callback(callback_id,'->'); end @.No pages of output@> @@ -14845,7 +14904,7 @@ else begin dvi_out(post); {beginning of the postamble} if total_pages<>1 then print_char("s"); print(", "); print_int(dvi_offset+dvi_ptr); print(" bytes)."); end - else + else if callback_id>0 then res:=run_callback(callback_id,'->'); b_close(dvi_file); end @@ -14895,6 +14954,16 @@ 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; @@ -15133,16 +15202,6 @@ begin incr(pdf_ptr); end -@d pdf_room(#) == {make sure that there are at least |n| bytes free in PDF buffer} -begin - if pdf_os_mode and (# + pdf_ptr > pdf_buf_size) then - pdf_os_get_os_buf(#) - else if not pdf_os_mode and (# > pdf_buf_size) then - overflow("PDF output buffer", pdf_op_buf_size) - else if not pdf_os_mode and (# + pdf_ptr > pdf_buf_size) then - pdf_flush; -end - @d pdf_out(#) == {do the same as |pdf_quick_out| and flush the PDF buffer if necessary} begin @@ -15462,6 +15521,16 @@ begin 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 @@ -15713,13 +15782,13 @@ begin pdf_end_string_nl; othercases confusion("literal1") endcases; - if s>string_offset then + 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); + end + else + pdf_out(s); pdf_print_nl; end; @@ -15817,8 +15886,10 @@ destination |pdf_ann_left| and |pdf_ann_top| are used for some types of destinat @# {data structure for \.{\\pdfliteral}} @d pdf_literal_data(#) == vlink(#+2) {data} -@d pdf_literal_mode(#) == vinfo(#+2) {mode of resetting the text matrix +@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} @@ -16384,7 +16455,7 @@ fonts too. Information about virtual fonts can be found in the source of some 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 |has_packet()| C macro checks for this condition. @ The following code typesets a character to PDF output. @@ -16498,12 +16569,12 @@ procedure scan_pdf_ext_toks; forward; @p function get_default_hyphen_char:integer; begin - get_default_hyphen_char:=default_hyphen_char; + get_default_hyphen_char:=default_hyphen_char; end; @# function get_default_skew_char:integer; begin - get_default_skew_char:=default_skew_char; + get_default_skew_char:=default_skew_char; end; @# procedure copy_expand_params(k, f: internal_font_number; e: integer); @@ -16560,7 +16631,7 @@ begin font_id_text(k) := font_id_text(f); end else - k := read_font_info(null_cs, s, font_size(f), font_natural_dir(f)); + k := read_font_info(null_cs, s, font_size(f), font_natural_dir(f)); end; copy_expand_params(k, f, e); load_expand_font := k; @@ -16677,7 +16748,7 @@ begin auto_expand := false; if scan_keyword('autoexpand') then begin auto_expand := true; - @<Scan an optional space@>; + @<Scan an optional space@>; end; {check if the font can be expanded} @@ -16688,12 +16759,12 @@ begin 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 @@ -16712,7 +16783,7 @@ begin end; end; -procedure new_letterspaced_font(a: small_number); +procedure new_letterspaced_font(a: small_number); {letter-space a font by creating a virtual font} var u:pointer; {user's font identifier} @!t:str_number; {name for the frozen font identifier} @@ -16774,12 +16845,30 @@ procedure pdf_out_literal(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_literal_data(p)),null,pool_size-pool_ptr); - selector:=old_setting; - s := make_string; - literal(s, pdf_literal_mode(p), false); - flush_str(s); + 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); @@ -16904,7 +16993,7 @@ begin if not doing_leaders then begin expand_late_lua(p); latelua(def_ref, late_lua_name(p)); - flush_list(def_ref); + flush_list(def_ref); end; end; @@ -16997,7 +17086,7 @@ for i := 1 to pdf_link_stack_ptr do begin append_link(this_box, left_edge, base_line, i); end -@ +@ @d pos_right(#) == pos.h := pos.h + (#) @d pos_left(#) == pos.h := pos.h - (#) @@ -17024,14 +17113,14 @@ 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 begin +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)); + q:=vlink(no_break(p)); vlink(no_break(p)):=null; - vlink(p):=q; + vlink(p):=q; end; -rule_node_case: begin +rule_node_case: begin if not (dir_orthogonal(dir_primary[rule_dir(p)])(dir_primary[dvi_direction])) then begin rule_ht:=height(p); rule_dp:=depth(p); rule_wd:=width(p); @@ -17050,7 +17139,7 @@ kern_node_case: begin @<Record |kern_node| {\sl Sync\TeX} information@>; cur.h := cur.h + width(p); end; -math_node_case: begin +math_node_case: begin @<Record |math_node| {\sl Sync\TeX} information@>; cur.h := cur.h + surround(p); end; @@ -17099,20 +17188,18 @@ if not is_mirrored(dvi_direction) then else basepoint_vertical := basepoint_vertical - shift_amount(p); {shift the box `up'} -if list_ptr(p)=null then begin +if list_ptr(p)=null then begin @<Record void list {\sl Sync\TeX} information@>; - cur.h := cur.h + effective_horizontal; + cur.h:=cur.h + effective_horizontal; end else begin - temp_ptr:=p; - edge:=cur.h; cur.h := cur.h + basepoint_horizontal; + 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; cur.h := cur.h + effective_horizontal; - cur.v:=base_line; + cur.h:=edge+effective_horizontal; cur.v:=base_line; end end @@ -17168,31 +17255,14 @@ if not (dir_orthogonal(dir_primary[box_dir(leader_box)])(dir_primary[dvi_directi else leader_wd:=height(leader_box)+depth(leader_box); if (leader_wd>0)and(rule_wd>0) then - begin - {TODO this double |case| is a hack, and not quite the proper - solution, but it produces the correct output for |xleaders| - in TRT mode, which is important for KASHIDAH fills.} - case box_direction(dvi_direction) of - dir_TR_,dir_RT_: begin - border:=cur.h+leader_wd; - cur.h:=cur.h-rule_wd+leader_wd; - edge:=cur.h-leader_wd; - end; - othercases begin { |dir_TL_,dir_LT_| } - edge:=cur.h+rule_wd; - border:=edge; - end; - end; + 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<=border do + while cur.h+leader_wd<=edge do @<(\pdfTeX) Output a leader box at |cur.h|, then advance |cur.h| by |leader_wd+lx|@>; - case box_direction(dvi_direction) of - dir_TR_,dir_RT_: cur.h:=edge; - dir_TL_,dir_LT_: cur.h:=edge; - end; - goto next_p; + cur.h:=edge-10; goto next_p; end; end @@ -17338,12 +17408,8 @@ if not (dir_orthogonal(dir_primary[box_dir(p)])(dir_primary[dvi_direction])) basepoint_vertical:=depth(p) else basepoint_vertical:=height(p); - if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then begin - if dvi_direction=dir_TL_ then - basepoint_horizontal:=width(p) - else - basepoint_horizontal:=-width(p); - end + if dir_opposite(dir_secondary[box_dir(p)])(dir_secondary[dvi_direction]) then + basepoint_horizontal:=width(p) else basepoint_horizontal:=0; end @@ -17365,14 +17431,15 @@ else begin 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 +else begin edge_v:=cur.v; cur.h:=left_edge + basepoint_horizontal; - cur.v:=cur.v + basepoint_vertical; + cur.v:=cur.v + basepoint_vertical; synch_pos_with_cur; save_box_pos:=box_pos; temp_ptr:=p; @@ -17494,8 +17561,8 @@ 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); +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"); @@ -17504,9 +17571,9 @@ if (tracing_output>0)and(pre_callback_id=0) then check_pdfminorversion; is_shipping_page := shipping_page; if shipping_page then begin - if pre_callback_id>0 then + if pre_callback_id>0 then ret:=run_callback(pre_callback_id,'->') - else begin + 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; @@ -17528,7 +17595,7 @@ if (tracing_output<=0)and(post_callback_id=0) and shipping_page then dead_cycles:=0; update_terminal; {progress report} @<Flush the box from memory, showing statistics if requested@>; -if post_callback_id>0 then +if post_callback_id>0 then ret:=run_callback(post_callback_id,'->'); @<Finish sheet {\sl Sync\TeX} information record@>; end; @@ -17922,7 +17989,7 @@ begin if not file_opened then pdf_error("ext5", "cannot open file for embedding"); end else begin - if not tex_b_open_in(f) then + 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); @@ -18320,7 +18387,7 @@ are already written completely to PDF output file. if total_pages=0 then begin if callback_id=0 then print_nl("No pages of output.") - else + else if callback_id>0 then res:=run_callback(callback_id,'->'); @.No pages of output@> if pdf_gone > 0 then @@ -18358,7 +18425,7 @@ else begin if total_pages<>1 then print_char("s"); print(", "); print_int(pdf_offset); print(" bytes)."); end - else + else if callback_id>0 then res:=run_callback(callback_id,'->'); end; libpdffinish; @@ -18811,9 +18878,9 @@ label found, continue; var @!s:integer; {temporarily saved value} i:integer; v:integer; @!spec_code:exactly..additional; -attr_list:halfword; +attr_list:halfword; begin s:=0; -if attr_list_cache=cache_disabled then update_attribute_cache; +if attr_list_cache=cache_disabled then update_attribute_cache; attr_list:=attr_list_cache; if three_codes then begin s:=saved(0); @@ -18833,8 +18900,8 @@ continue: 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 attr_list=attr_list_cache then begin add_node_attr_ref(attr_list); end; if scan_keyword('to') then spec_code:=exactly @.to@> else if scan_keyword('spread') then spec_code:=additional @@ -18843,8 +18910,8 @@ else begin spec_code:=additional; cur_val:=0; goto found; end; scan_normal_dimen; -found: if three_codes then begin - saved(0):=s; +found: if three_codes then begin + saved(0):=s; saved(1):=spec_code; saved(2):=cur_val; saved(3):=spec_direction; @@ -18856,9 +18923,9 @@ found: if three_codes then begin 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 + end else begin - saved(0):=spec_code; + saved(0):=spec_code; saved(1):=cur_val; save_ptr:=save_ptr+2; new_save_level(c); scan_left_brace; @@ -18927,7 +18994,7 @@ font expansion is being used. We define some constants used when calling var k: internal_font_number; dw: scaled; ef: integer; - f: internal_font_number; + f: internal_font_number; c: integer; begin f := font(p); @@ -18946,7 +19013,7 @@ function char_shrink(p:halfword): scaled; var k: internal_font_number; dw: scaled; ef: integer; - f: internal_font_number; + f: internal_font_number; c: integer; begin f := font(p); @@ -19038,13 +19105,13 @@ begin 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 + 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 + 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)), @@ -19074,7 +19141,7 @@ begin last_rightmost_char := null; if p = null then return; - if not is_char_node(p) then + if not is_char_node(p) then return; f := font(p); if side = left_side then begin @@ -19134,11 +19201,6 @@ if m = cal_expand_ratio then begin font_shrink := 0; font_expand_ratio := 0; end; -@{ -if m = subst_ex_font then begin - wterm_ln('replacing ', font_expand_ratio:1); -end; -@} h:=0; @<Clear dimensions to zero@>; disc_level:=0; reswitch: @@ -19159,7 +19221,7 @@ height(r):=h; depth(r):=d;@/ then |return| or |goto common_ending|@>; common_ending: @<Finish issuing a diagnostic message for an overfull or underfull hbox@>; -exit: +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); @@ -19247,7 +19309,7 @@ if p<>null then disc_node_case: begin if m = subst_ex_font then do_subst_font(p, font_expand_ratio); - if vlink(no_break(p))<>null then begin + 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); @@ -19366,7 +19428,7 @@ begin while vlink(q)<>p do q:=vlink(q); update_adjust_list(pre_adjust_tail) else update_adjust_list(adjust_tail); - p := vlink(p); + 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); @@ -19538,7 +19600,7 @@ var r:pointer; {the box node that will be returned} @!s:scaled; {shift amount} @!g:pointer; {points to a glue specification} @!o:glue_ord; {order of infinity} -begin last_badness:=0; +begin last_badness:=0; {pdfassert(p<>0);} r:=new_node(vlist_node,0); if pack_direction=-1 then @@ -19605,7 +19667,7 @@ if (type(p)=hlist_node) or (type(p)=vlist_node) then begin s:=shift_amount(p); if width(p)+s>w then w:=width(p)+s; end - 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); @@ -19735,7 +19797,7 @@ begin if prev_depth>pdf_ignored_dimen then vlink(tail):=p; tail:=p; end; vlink(tail):=b; tail:=b; -if (type(b)=hlist_node) and is_mirrored(box_dir(b)) then +if (type(b)=hlist_node) and is_mirrored(box_dir(b)) then prev_depth:=height(b) else prev_depth:=depth(b); @@ -19905,7 +19967,7 @@ 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 +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; @@ -19946,7 +20008,7 @@ end; @# procedure pop_alignment; var p:pointer; {the top alignment stack node} -begin flush_node(cur_head); +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); @@ -20278,7 +20340,7 @@ 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 +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...@> @@ -20287,7 +20349,8 @@ if (p=null)and(extra_info(cur_align)<cr_code) then ("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; +end @ @<Lengthen the preamble...@>= begin r:=new_node(align_record_node,0); vlink(q):=r; p:=vlink(q); {a new alignrecord} @@ -20363,12 +20426,12 @@ if n>max_quarterword then confusion("too many spans"); {this can happen, but won @^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 +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; + 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 @@ -20389,7 +20452,7 @@ begin if mode=-hmode then 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); +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; @@ -20508,7 +20571,7 @@ 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)); + p:=hpack(preamble,saved(1),saved(0)); overfull_rule:=rule_save; end else begin q:=vlink(preamble); @@ -20524,12 +20587,13 @@ 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 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 @@ -20747,16 +20811,16 @@ 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)) + 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; +else begin + type(tail):=penalty_node; delete_glue_ref(glue_ptr(tail)); if leader_ptr(tail)<>null then flush_node_list(leader_ptr(tail)); @@ -20770,13 +20834,13 @@ last_line_fill:=vlink(tail); pop_nest; start_of_par:=tail; callback_id:=callback_defined(linebreak_filter_callback); -if callback_id<>0 then begin +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); + 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.") @@ -20787,7 +20851,7 @@ if callback_id<>0 then begin end else begin if tracing_paragraphs>0 then begin - begin_diagnostic; + begin_diagnostic; print_nl("Lua linebreak_filter failed, reverting to default on line "); print_int(line); end_diagnostic(true); end; @@ -20797,7 +20861,7 @@ 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, + 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, @@ -20815,7 +20879,7 @@ end; @# @t\4@>@<Declare \eTeX\ procedures for use by |main_control|@> -@ It is possible that the user wants to interfere at some point. +@ 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. @@ -20840,7 +20904,7 @@ section heads are kept here. 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); +flush_list(def_ref); end; @ Similarly, when \TeX\ has scanned `\.{\\patterns}', it calls on a @@ -20850,7 +20914,7 @@ procedure named |new_patterns|. 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); +flush_list(def_ref); end; @ `\.{\\prehyphenchar}', sets the |pre_break| character, and @@ -20868,7 +20932,7 @@ begin scan_optional_equals; scan_int; end; @ `\.{\\preexhyphenchar}', sets the |pre_break| character, and -`\.{\\postexhyphenchar}' the |post_break| character. Their +`\.{\\postexhyphenchar}' the |post_break| character. Their defaults are both zero (nul). @p procedure new_pre_exhyphen_char; @@ -21038,10 +21102,11 @@ endcases if pi<inf_penalty then begin @<Compute the badness, |b|, using |awful_bad| if the box is too full@>; - if b<awful_bad then + 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; @@ -21141,7 +21206,7 @@ if type(v)<>vlist_node then @<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 +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)); @@ -21152,6 +21217,7 @@ else loop@+begin if type(p)=mark_node then 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; @@ -21219,7 +21285,7 @@ node $r_j$ is followed by |r@t$_{j+1}$@>=vlink(r@t$_j$@>)|; and if there are each node in this list refers to an insertion number; for example, `\.{\\insert 250}' would correspond to a node whose |subtype| is |qi(250)| (the same as the |subtype| field of the relevant |ins_node|). These |subtype| -fields are in increasing order, and |subtype(page_ins_head)=65535, so +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. @@ -21803,10 +21869,11 @@ for i:=0 to biggest_used_mark do begin begin first_mark(i):=top_mark(i); add_token_ref(top_mark(i)); end; end; -if output_routine<>null then +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; @@ -21877,9 +21944,10 @@ 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 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; @@ -22110,14 +22178,14 @@ p:pointer; {for whatsit nodes and testing whether an auto kern should be inserte 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; +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; +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) @@ -22134,19 +22202,19 @@ 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 + (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 +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@>; + @<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} @@ -22195,18 +22263,18 @@ 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; + (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 + 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 + end else begin - if (chr_stack=ex_hyphen_char) and (mode>0) then begin + if (chr_stack=ex_hyphen_char) and (mode>0) then begin tail:=compound_word_break(tail,cur_lang); subtype(tail):=automatic_disc; end; @@ -22249,7 +22317,7 @@ space_spec_font:=0; space_spec_cache:=zero_glue; @ @<Find the glue specification...@>= -begin +begin if cur_font<>space_spec_font then begin if space_spec_cache<>zero_glue then delete_glue_ref(space_spec_cache); @@ -22267,9 +22335,9 @@ 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 +else begin if space_skip<>zero_glue then main_p:=new_spec(space_skip) - else begin + else begin main_p:=new_spec(zero_glue); width(main_p):=space(cur_font); stretch(main_p):=space_stretch(cur_font); @@ -22328,7 +22396,7 @@ mode by mistake. \TeX\ will insert a dollar sign and rescan the current token. @<Math-only cases in non-math modes...@>= non_math(sup_mark), non_math(sub_mark), -non_math(math_comp), non_math(delim_num), +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), @@ -22338,7 +22406,7 @@ 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); + back_input; new_graf(true); end; hmode+math_char_num: begin if cur_chr=0 then @@ -22850,10 +22918,11 @@ 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 +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 @@ -22954,7 +23023,7 @@ end begin q:=head; repeat p:=q; if not is_char_node(q) then if type(q)=disc_node then - begin + begin if p=tail then goto done; end; q:=vlink(p); @@ -23055,7 +23124,7 @@ else begin cur_box:=filtered_vpackage(vlink(head),saved(2),saved(1),d,grp); end; if saved(4)<>null then @<DIR: Adjust back |text_dir_ptr| for |scan_spec|@>; -replace_attribute_list(cur_box, saved(5)); +replace_attribute_list(cur_box, saved(5)); pop_nest; box_end(saved(0)); end; @@ -23091,7 +23160,7 @@ primitive_pdftex("quitvmode",start_par,2,0); 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+un_hbox,vmode+vrule, + 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); @@ -23104,7 +23173,7 @@ 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; +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; @@ -23126,7 +23195,7 @@ 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 +if nest_ptr=1 then begin check_filter('new_graf'); build_page; {put |par_skip| glue on current page} end; end; @@ -23181,7 +23250,7 @@ end; 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 @@ -23229,13 +23298,13 @@ end; @ @<Cases of |handle...@>= insert_group: begin - line_break_context:=insert_group; + 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))); + 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 @@ -23266,7 +23335,7 @@ 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:=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; @@ -23439,7 +23508,7 @@ but it starts out as 1000 in the subsidiary lists. @<Declare act...@>= procedure append_local_box(kind:integer); -begin +begin incr(save_ptr); saved(-1):=kind; new_save_level(local_box_group); scan_left_brace; push_nest; mode:=-hmode; space_factor:=1000; end; @@ -23448,9 +23517,9 @@ procedure append_discretionary; var c:integer; begin tail_append(new_disc); subtype(tail):=cur_chr; -if cur_chr=explicit_disc then begin +if cur_chr=explicit_disc then begin c:=get_pre_hyphen_char(cur_lang); - if c<>0 then begin + 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)); @@ -23484,9 +23553,10 @@ unsave; kind:=saved(-1); decr(save_ptr); p:=vlink(head); pop_nest; -p:=hpack(p,natural); +if p<>null then + p:=hpack(p,natural); if kind=0 then - eq_define(local_left_box_base,box_ref,p) + eq_define(local_left_box_base,box_ref,p) else eq_define(local_right_box_base,box_ref,p); if abs(mode)=hmode then @@ -23500,20 +23570,20 @@ 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 + |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; +0: if (n>0) then begin + vlink(pre_break(tail)):=p; alink(p):=pre_break(tail); - tlink(pre_break(tail)):=q; + 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; + tlink(post_break(tail)):=q; end; 2:@<Attach list |p| to the current list, and record its length; then finish up and |return|@>; @@ -23530,11 +23600,11 @@ begin if (n>0)and(abs(mode)=mmode) then ("empty, in math formulas. I had to delete your third part."); flush_node_list(p); error; end -else begin - if (n>0) then begin +else begin + if (n>0) then begin vlink(no_break(tail)):=p; alink(p):=no_break(tail); - tlink(no_break(tail)):=q; + tlink(no_break(tail)):=q; end; end; decr(save_ptr); return; @@ -23545,8 +23615,8 @@ end @<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)<>disc_node then - if type(p)>rule_node then if type(p)<>kern_node then + 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.");@/ @@ -23615,7 +23685,7 @@ 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); +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; @@ -23762,11 +23832,23 @@ 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|, +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:init_math; +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; @@ -23815,7 +23897,7 @@ mmode+delim_num: begin mval := scan_delimiter_as_mathchar(tex_mathcode) else if cur_chr=1 then mval := scan_delimiter_as_mathchar(aleph_mathcode) - else + else mval := scan_delimiter_as_mathchar(xetex_mathcode); set_math_char(mval); end; @@ -23825,31 +23907,31 @@ the command code |math_comp|, supplemented by the noad type that they generate. @<Put each...@>= -primitive_tex("mathord",math_comp,ord_noad,0); +primitive_tex("mathord",math_comp,ord_noad_type,0); @!@:math_ord_}{\.{\\mathord} primitive@> -primitive_tex("mathop",math_comp,op_noad,0); +primitive_tex("mathop",math_comp,op_noad_type_normal,0); @!@:math_op_}{\.{\\mathop} primitive@> -primitive_tex("mathbin",math_comp,bin_noad,0); +primitive_tex("mathbin",math_comp,bin_noad_type,0); @!@:math_bin_}{\.{\\mathbin} primitive@> -primitive_tex("mathrel",math_comp,rel_noad,0); +primitive_tex("mathrel",math_comp,rel_noad_type,0); @!@:math_rel_}{\.{\\mathrel} primitive@> -primitive_tex("mathopen",math_comp,open_noad,0); +primitive_tex("mathopen",math_comp,open_noad_type,0); @!@:math_open_}{\.{\\mathopen} primitive@> -primitive_tex("mathclose",math_comp,close_noad,0); +primitive_tex("mathclose",math_comp,close_noad_type,0); @!@:math_close_}{\.{\\mathclose} primitive@> -primitive_tex("mathpunct",math_comp,punct_noad,0); +primitive_tex("mathpunct",math_comp,punct_noad_type,0); @!@:math_punct_}{\.{\\mathpunct} primitive@> -primitive_tex("mathinner",math_comp,inner_noad,0); +primitive_tex("mathinner",math_comp,inner_noad_type,0); @!@:math_inner_}{\.{\\mathinner} primitive@> -primitive_tex("underline",math_comp,under_noad,0); +primitive_tex("underline",math_comp,under_noad_type,0); @!@:underline_}{\.{\\underline} primitive@> -primitive_tex("overline",math_comp,over_noad,0);@/ +primitive_tex("overline",math_comp,over_noad_type,0);@/ @!@:overline_}{\.{\\overline} primitive@> -primitive_tex("displaylimits",limit_switch,normal,0); +primitive_tex("displaylimits",limit_switch,op_noad_type_normal,0); @!@:display_limits_}{\.{\\displaylimits} primitive@> -primitive_tex("limits",limit_switch,limits,0); +primitive_tex("limits",limit_switch,op_noad_type_limits,0); @!@:limits_}{\.{\\limits} primitive@> -primitive_tex("nolimits",limit_switch,no_limits,0); +primitive_tex("nolimits",limit_switch,op_noad_type_no_limits,0); @!@:no_limits_}{\.{\\nolimits} primitive@> @ @<Cases of |main_control| that build...@>= @@ -23894,15 +23976,23 @@ 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: append_choices; +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: sub_sup; +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}' } @@ -23928,7 +24018,7 @@ mmode+above: math_fraction; @ @<Cases of |handle...@>= math_group: close_math_group(p); -@ +@ @<Put each...@>= primitive_tex("left",left_right,left_noad_side,0); @@ -23945,7 +24035,7 @@ mmode+left_right: math_left_right; @ Here is the only way out of math mode. @<Cases of |main_control| that build...@>= -mmode+math_shift: if cur_group=math_shift_group then after_math +mmode+math_shift,mmode+math_shift_cs: if cur_group=math_shift_group then after_math else off_save; @@ -24093,29 +24183,30 @@ if (cur_cmd<>def)and((a mod 4<>0)or(j<>0)) then since the following routines test for the \.{\\global} prefix as follows. @d global==(a>=4) -@d define(#)==if global then geq_define(#)@+else eq_define(#) -@d word_define(#)==if global then geq_word_define(#)@+else eq_word_define(#) -@d define_lc_code(#)==if global - then set_lc_code(#,level_one)@+else set_lc_code(#,cur_level) -@d define_uc_code(#)==if global - then set_uc_code(#,level_one)@+else set_uc_code(#,cur_level) -@d define_sf_code(#)==if global - then set_sf_code(#,level_one)@+else set_sf_code(#,cur_level) -@d define_cat_code(#)==if global - then set_cat_code(cat_code_table,#,level_one)@+else set_cat_code(cat_code_table,#,cur_level) -@d define_fam_fnt(#)==if global - then def_fam_fnt(#,level_one)@+else def_fam_fnt(#,cur_level) -@d define_math_param(#)==if global - then def_math_param(#,level_one)@+else def_math_param(#,cur_level) +@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 +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; + 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 @@ -24143,7 +24234,7 @@ end; @ @<Initialize table entries...@>= text(frozen_protection):="inaccessible"; -@ Assignments from Lua need helpers. +@ Assignments from Lua need helpers. @p function is_int_assign(cmd:halfword):boolean; begin @@ -24187,7 +24278,7 @@ if (p>=int_base)and(p<attribute_base) then begin else word_define(p,13); end - else + 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 @@ -24206,7 +24297,7 @@ 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_inch; word_define(dimen_base+h_offset_code, n); - end + end else if p=(dimen_base+h_offset_code) then begin n:=cur_val + one_inch; word_define(dimen_base+page_left_offset_code, n); @@ -24220,7 +24311,7 @@ else if (p>=dimen_base)and(p<eqtb_size) then begin word_define(dimen_base+page_top_offset_code, n); end; word_define(p,cur_val); - end + end else confusion("assign internal value"); end; @@ -24319,7 +24410,7 @@ 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; +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); @@ -24329,7 +24420,7 @@ shorthand_def: begin n:=cur_chr; get_r_token; p:=cur_cs; 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 + 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); @@ -24384,9 +24475,9 @@ toks_register,assign_toks: begin q:=cur_cs; 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; + begin p:=get_avail; link(q):=p; p:=output_routine_loc; q:=link(q);info(q):=right_brace_token+"}"; - q:=get_avail; + q:=get_avail; info(q):=left_brace_token+"{"; link(q):=link(def_ref); link(def_ref):=q; end; @@ -24506,8 +24597,8 @@ primitive_luatex("Umathsupshiftup", set_math_param, math_param_sup_shift_u 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("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); @@ -24610,28 +24701,28 @@ def_char_code,def_del_code: begin end else if cur_chr=lc_code_base then begin scan_char_num; p:= cur_val; - scan_optional_equals; + 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_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_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_optional_equals; scan_int; check_def_code(cat_code_base); define_cat_code(p,cur_val); @@ -24640,7 +24731,7 @@ def_char_code,def_del_code: begin if global then cur_val1:=level_one else cur_val1:=cur_level; scan_extdef_del_code(cur_val1,tex_mathcode); end; - 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 @@ -24667,21 +24758,21 @@ 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; + 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 + 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; + cur_val1:=display_style; back_error; end else cur_val1:=cur_chr; - scan_optional_equals; - if p<math_param_first_mu_glue then begin + scan_optional_equals; + if p<math_param_first_mu_glue then begin if p=math_param_radical_degree_raise then scan_int else @@ -24708,7 +24799,7 @@ 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; +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}'} @@ -24908,7 +24999,7 @@ 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 +@ Paragraph shapes are set up in an obvious way. It needs one word more than in \TeX, though. @<Assignments@>= @@ -24953,13 +25044,13 @@ 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; +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; + 4: new_pre_exhyphen_char; 5: new_post_exhyphen_char; endcases; goto done; @@ -24970,7 +25061,7 @@ the interaction mode, and the hyphenation tables; these are strictly global. @<Assignments@>= assign_font_dimen: set_font_dimen; -assign_font_int: begin +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 @@ -25194,21 +25285,21 @@ 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 +if t<cs_token_flag then begin c:=t mod string_offset; - if b=uc_code_base then + 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; + if i<>0 then info(p):=t-c+i; end -else if is_active_csname(t-cs_token_flag) then begin +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; + 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 @@ -25518,7 +25609,7 @@ print_int(var_used); print_char("&"); print_int(dyn_used) undump_node_mem; @# undump_int(temp_token_head); undump_int(hold_token_head); -undump_int(omit_template); undump_int(null_list); +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); @@ -25702,8 +25793,8 @@ 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_nl("\ocplist"); + print_esc(ocp_list_id_text(k)); print_char("="); print_ocp_list(ocp_list_list[k]); end; @@ -25741,7 +25832,7 @@ 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 +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"); @@ -25773,7 +25864,7 @@ 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); +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 @@ -25785,7 +25876,7 @@ 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; + obj_tab[k].int2 := -1; undump_int(obj_tab[k].int3); undump_int(obj_tab[k].int4); end; @@ -25949,7 +26040,7 @@ if callback_id=0 then begin else begin slow_print(format_ident); print_ln; end; end -else +else if callback_id>0 then res:= run_callback(callback_id,'->'); update_terminal; end; @@ -25957,8 +26048,7 @@ end; procedure print_version_banner; begin wterm(banner); -wterm(', build '); -do_write_wterm(luatex_svnversion); +write_svnversion(luatex_svnversion); end; @@ -25985,7 +26075,7 @@ var a, b, i, j, k, l: integer; {all-purpose index} xref_offset_width, names_head, names_tail: integer; callback_id:integer; res:boolean; -begin +begin callback_id:=callback_defined(stop_run_callback); @<Finish the extensions@>; @!stat if tracing_stats>0 then @@ -26084,8 +26174,8 @@ 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(" )"); + begin + if tracefilenames then print(" )"); decr(open_parens); end; if cur_level>level_one then @@ -26106,7 +26196,7 @@ while cond_ptr<>null do cur_if:=subtype(cond_ptr); temp_ptr:=cond_ptr; cond_ptr:=vlink(cond_ptr); flush_node(temp_ptr); end; -if not callback_defined(stop_run_callback) then +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 @@ -26168,6 +26258,7 @@ 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|@>; @@ -26282,7 +26373,7 @@ 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}. +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). @@ -26335,7 +26426,7 @@ and both of these variables are always |false|. @!text_dir_ptr:pointer; @!text_dir_tmp:pointer; -@ +@ @<Set init...@>= for k:=0 to 17 do write_open[k]:=false; pack_direction:=-1; @@ -26684,6 +26775,7 @@ begin else pdf_literal_mode(tail) := set_origin; scan_pdf_ext_toks; + pdf_literal_type(tail) := normal; pdf_literal_data(tail) := def_ref; end @@ -27608,7 +27700,7 @@ begin print_err("Invalid \catcode table"); help1("All \catcode table ids must be between 0 and 0xFFFF"); error; - end + end else begin if cur_val=cat_code_table then begin print_err("Invalid \catcode table"); help1("You cannot overwrite the current \catcode table"); @@ -27626,7 +27718,7 @@ begin print_err("Invalid \catcode table"); help1("All \catcode table ids must be between 0 and 0xFFFF"); error; - end + end else begin if cur_val=cat_code_table then begin print_err("Invalid \catcode table"); help1("You cannot overwrite the current \catcode table"); @@ -27828,7 +27920,7 @@ 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. +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) @@ -27845,10 +27937,10 @@ end @ @<Incorporate a whatsit node into an hbox@>= begin -if subtype(p)=dir_node then +if subtype(p)=dir_node then begin @<DIR: Adjust the dir stack for the |hpack| routine@>; - end + end else begin if (subtype(p) = pdf_refxform_node) or (subtype(p) = pdf_refximage_node) then begin x:=x+pdf_width(p); @@ -28067,7 +28159,7 @@ 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}} @@ -28116,7 +28208,7 @@ dir_base+par_direction_code: begin 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)-64; + dir_dir(tail):=dir_dir(tail); end; if dir_level(text_dir_ptr)=cur_level then @<DIR: Remove from |text_dir_ptr|@>; @@ -28144,7 +28236,7 @@ end @d push_dir_node(#)== begin dir_tmp:=copy_node(#); -vlink(dir_tmp):=dir_ptr; +vlink(dir_tmp):=dir_ptr; dir_ptr:=dir_tmp; end @@ -28269,7 +28361,7 @@ function simple_advance_width(p:halfword):scaled; var q:halfword; @!w:scaled; begin - q:=p; w:=0; + q:=p; w:=0; while (q<>null) and (vlink(q)<>null) do begin q:=vlink(q); if is_char_node(q) then begin @@ -28286,14 +28378,14 @@ begin othercases do_nothing; endcases; end; - end; - simple_advance_width:=w; + end; + simple_advance_width:=w; end; @ @<(PDF) Calculate the needed width to the matching |enddir|...@>= begin - q:=p; w:=0; + 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, @@ -28304,14 +28396,14 @@ begin q:=vlink(q); if is_char_node(q) then begin w:=w+glyph_width(q); {TODO no vertical support for now} - end + 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 + glue_node_case: begin g:=glue_ptr(q); - w:=w+width(g)-cur_g; + 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 @@ -28326,22 +28418,22 @@ begin cur_g:=round(glue_temp); end; end; - w:=w+cur_g; + 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 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 + end + else if (subtype(q) = pdf_refxform_node) or (subtype(q) = pdf_refximage_node) then w:=w+pdf_width(q); end; @@ -29079,7 +29171,7 @@ is a run-time switch. @!init if format_ident=" (INITEX)" then begin no_new_control_sequence:=false; @<Generate all \eTeX\ primitives@>@; - if buffer[loc]="*" then incr(loc); + if buffer[loc]="*" then incr(loc); end; tini@;@/ if not no_new_control_sequence then {just entered extended mode ?} @@ -29490,7 +29582,7 @@ if saved(-2)<>0 then @ @<Show the box context@>= i:=saved(-4); -if i<>0 then +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); @@ -29502,7 +29594,8 @@ if i<>0 then end; print_esc("setbox"); print_int(i-box_flag); print_char("="); end - else print_cmd_chr(leader_ship,i-(leader_flag-a_leaders)) + 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. @@ -29530,11 +29623,12 @@ 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 + 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} @@ -29649,7 +29743,7 @@ 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, +processed: the |subtype| field contains the size of this node, all the following words contain ASCII codes. @<Glob...@>= @@ -29681,7 +29775,7 @@ end; procedure pseudo_from_string; var @!s:str_number; {string to be converted into a pseudo file} @!p:pointer; {for list construction} -begin +begin s:=make_string; @<Convert string |s| into a new pseudo file@>; flush_string; @@ -29689,7 +29783,7 @@ flush_string; end; procedure lua_string_start; -begin +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); @@ -29708,7 +29802,7 @@ if tracing_scan_tokens>0 then else if (term_offset>0)or(file_offset>0) then print_char(" "); name:=20; print("( "); incr(open_parens); update_terminal; end -else begin +else begin name:=18; @<Prepare pseudo file {\sl Sync\TeX} information@>; end @@ -29749,7 +29843,7 @@ end; procedure pseudo_close; {close the top level pseudo file} var p: pointer; begin p:=vlink(pseudo_files); -flush_node(pseudo_files); +flush_node(pseudo_files); pseudo_files:=p; end; @@ -29879,14 +29973,14 @@ while p<>null do 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 + 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); + p:=link(p); end; if m>first then cur_cs:=id_lookup(first,m-first) {|no_new_control_sequence| is |true|} @@ -30032,7 +30126,7 @@ 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 +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); @@ -30097,12 +30191,13 @@ while cur_val_level>level do else if cur_val_level=mu_val then mu_error; decr(cur_val_level); end; -if negative then +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 @@ -30229,7 +30324,7 @@ numerator for a combined multiplication and division, if any. @d expr_n_field(#)==vinfo(#+2) {saved numerator} @<Push the expression...@>= -begin q:=new_node(expr_node,0); vlink(q):=p; +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; @@ -30612,7 +30707,7 @@ 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; +if global_defs>0 then a:=4 else a:=0; word_define(j+scaled_base,v); set_tex_dimen_register := 0; end; @@ -30625,7 +30720,7 @@ 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 global_defs>0 then a:=4 else a:=0; if type(v) <> glue_spec_node then set_tex_skip_register := 1 else begin @@ -30642,7 +30737,7 @@ 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; + if global_defs>0 then a:=4 else a:=0; word_define(j+count_base,v); set_tex_count_register := 0; end; @@ -30655,7 +30750,7 @@ 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 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); @@ -30686,7 +30781,7 @@ begin 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; + if global_defs>0 then a:=4 else a:=0; define(j+toks_base,call,ref); flush_str(s); end; @@ -30699,7 +30794,7 @@ 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; +if global_defs>0 then a:=4 else a:=0; define(j+box_base,box_ref,v); set_tex_box_register := 0; end; @@ -30884,10 +30979,10 @@ begin 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 +@ 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 +like it is in Omega, so a future incompatibility with Aleph is unavoidable. @<Read in the buffer for treatment@>= @@ -30976,7 +31071,7 @@ used for surrogate pairs, not for simple 16-bit values. begin if (first+otp_output_end)>=ocp_buf_size then overflow_ocp_buf_size; -push_input; +push_input; current_ocp_lstack:=active_lstack_no(active_real); current_ocp_no:=active_counter(active_real); state:=mid_line; @@ -30994,7 +31089,7 @@ for otp_counter:=1 to otp_output_end do begin incr(otp_counter); t := (t-@"D800) * @"400 + (otp_output_buf[otp_counter]-@"DC00) + @"10000; end - else if ((t>=@"DC00) and (t<@"E000)) then + 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); @@ -31006,7 +31101,7 @@ for otp_counter:=1 to otp_output_end do begin buffer[last]:= t else if t<=@"7FF then begin buffer[last]:=@"C0 + t div @"40; - incr(last); + incr(last); if last=buf_size-2 then @<Report overflow of the input buffer, and abort@>; buffer[last]:=@"80 + t mod @"40; @@ -31190,7 +31285,7 @@ end end; incr(otp_pc); end - + @ @<Run the arithmetic instructions@>= otp_add: begin @@ -31258,13 +31353,13 @@ end 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_buf[otp_counter+otp_stack_used]; end; otp_stack_new:=otp_stack_new-otp_stack_used; @@ -31276,7 +31371,7 @@ 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_buf[otp_counter+otp_stack_used]; end; otp_stack_new:=otp_stack_new-otp_stack_used; @@ -31291,7 +31386,7 @@ 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_buf[otp_counter+otp_stack_used]; end; otp_stack_new:=otp_stack_new-otp_stack_used; @@ -31300,7 +31395,7 @@ end if otp_state_ptr>0 then decr(otp_state_ptr); otp_pc:=0; end - + @ @<Run the |otp_left| instructions@>= otp_left_start: begin @@ -31348,7 +31443,7 @@ end decr(otp_no_input_chars); incr(otp_pc); end - + @ @<Run the |otp_goto| instructions@>= otp_goto: begin @@ -31453,13 +31548,13 @@ end 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_buf[otp_counter+otp_stack_used]; end; otp_stack_new:=otp_stack_new-otp_stack_used; @@ -31467,7 +31562,7 @@ end otp_stack_used:=0; otp_pc:=0; end - + @ @<Put each...@>= primitive_omega("ocp", def_ocp, 0,0); primitive_omega("externalocp", def_ocp, 1,0); @@ -31484,12 +31579,12 @@ equiv(ocp_trace_level_base):=0; @ @<Assignments@>= set_ocp: begin - print_err("To use ocps, use the "); print_esc("pushocplist"); + 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_err("To use ocp lists, use the "); print_esc("pushocplist"); print(" primitive");print_ln end; def_ocp_list: new_ocp_list(a); @@ -31524,7 +31619,7 @@ 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: +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 @@ -31557,7 +31652,7 @@ begin if job_name=0 then open_log_file; @.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; +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; diff --git a/Build/source/texk/web2c/luatexdir/makecpool.c b/Build/source/texk/web2c/luatexdir/makecpool.c index dd5b31f0b92..dd3d6fab5d1 100644 --- a/Build/source/texk/web2c/luatexdir/makecpool.c +++ b/Build/source/texk/web2c/luatexdir/makecpool.c @@ -6,7 +6,7 @@ #include <stdlib.h> static const char __svn_version[] = - "$Id: makecpool.c 1230 2008-05-03 11:11:32Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/makecpool.c $"; + "$Id: makecpool.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/makecpool.c $"; int main(int argc, char *argv[]) { diff --git a/Build/source/texk/web2c/luatexdir/managed-sa.c b/Build/source/texk/web2c/luatexdir/managed-sa.c index 97872c1efe3..ecdaa19d1ef 100644 --- a/Build/source/texk/web2c/luatexdir/managed-sa.c +++ b/Build/source/texk/web2c/luatexdir/managed-sa.c @@ -22,7 +22,7 @@ #include "managed-sa.h" static const char __svn_version[] = - "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/managed-sa.c $"; + "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/managed-sa.c $"; static void store_sa_stack(sa_tree a, integer n, integer v, integer gl) { @@ -247,7 +247,7 @@ void dump_sa_tree(sa_tree a) sa_tree undump_sa_tree(void) { - unsigned int x; + integer x; int h, m, l; boolean f; sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1); @@ -273,7 +273,7 @@ sa_tree undump_sa_tree(void) a->tree[h][m] = Mxmalloc_array(sa_tree_item, LOWPART); for (l = 0; l < LOWPART; l++) { undump_int(x); - a->tree[h][m][l] = x; + a->tree[h][m][l] = (unsigned int) x; } } else { a->tree[h][m] = NULL; diff --git a/Build/source/texk/web2c/luatexdir/mathcodes.c b/Build/source/texk/web2c/luatexdir/mathcodes.c index ef5af17afc0..2158f9d47b6 100644 --- a/Build/source/texk/web2c/luatexdir/mathcodes.c +++ b/Build/source/texk/web2c/luatexdir/mathcodes.c @@ -26,7 +26,7 @@ extern void rawset_sa_item(sa_tree head, integer n, integer v); static const char __svn_version[] = - "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/mathcodes.c $"; + "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/mathcodes.c $"; /* math codes */ @@ -35,8 +35,8 @@ static sa_tree mathcode_head = NULL; #define MATHCODEHEAP 8 static mathcodeval *mathcode_heap = NULL; -static int mathcode_heapsize = MATHCODEHEAP; -static int mathcode_heapptr = 0; +static integer mathcode_heapsize = MATHCODEHEAP; +static integer mathcode_heapptr = 0; /* the 0xFFFFFFFF is a flag value */ #define MATHCODESTACK 8 @@ -49,8 +49,8 @@ static sa_tree delcode_head = NULL; #define DELCODEHEAP 8 static delcodeval *delcode_heap = NULL; -static int delcode_heapsize = DELCODEHEAP; -static int delcode_heapptr = 0; +static integer delcode_heapsize = DELCODEHEAP; +static integer delcode_heapptr = 0; #define DELCODESTACK 4 #define DELCODEDEFAULT 0xFFFFFFFF @@ -222,7 +222,7 @@ void initializemathcode(void) void dumpmathcode(void) { - int k; + integer k; mathcodeval d; dump_sa_tree(mathcode_head); dump_int(mathcode_heapsize); @@ -238,17 +238,21 @@ void dumpmathcode(void) void undumpmathcode(void) { - int k; + integer k, x; mathcodeval d; mathcode_head = undump_sa_tree(); undump_int(mathcode_heapsize); undump_int(mathcode_heapptr); mathcode_heap = Mxmalloc_array(mathcodeval, mathcode_heapsize); for (k = 0; k < mathcode_heapptr; k++) { - undump_int(d.origin_value); - undump_int(d.class_value); - undump_int(d.family_value); - undump_int(d.character_value); + undump_int(x); + d.origin_value = x; + undump_int(x); + d.class_value = x; + undump_int(x); + d.family_value = x; + undump_int(x); + d.character_value = x; mathcode_heap[k] = d; } d.origin_value = 0; @@ -394,7 +398,7 @@ void initializedelcode(void) void dumpdelcode(void) { - int k; + integer k; delcodeval d; dump_sa_tree(delcode_head); dump_int(delcode_heapsize); @@ -412,7 +416,7 @@ void dumpdelcode(void) void undumpdelcode(void) { - int k; + integer k; delcodeval d; delcode_head = undump_sa_tree(); undump_int(delcode_heapsize); diff --git a/Build/source/texk/web2c/luatexdir/nodes.h b/Build/source/texk/web2c/luatexdir/nodes.h index 16cfc3f258d..36488e1031c 100644 --- a/Build/source/texk/web2c/luatexdir/nodes.h +++ b/Build/source/texk/web2c/luatexdir/nodes.h @@ -78,6 +78,8 @@ extern void set_disc_field(halfword f, halfword t); /* attribute lists */ +# define UNUSED_ATTRIBUTE -0x7FFFFFFF /* as low as it goes */ + /* it is convenient to have attribute list nodes and attribute node * be the same size */ @@ -189,7 +191,9 @@ typedef enum { discretionary_disc = 0, explicit_disc, automatic_disc, - syllable_disc + syllable_disc, + init_disc, /* first of a duo of syllable_discs */ + select_disc, /* second of a duo of syllable_discs */ } discretionary_types; # define pre_break_head(a) ((a)+4) @@ -316,20 +320,20 @@ typedef enum { unset_node, style_node, choice_node, /* 15 */ - ord_noad, - op_noad, - bin_noad, - rel_noad, - open_noad, /* 20 */ - close_noad, - punct_noad, - inner_noad, + simple_noad, + old_op_noad, + old_bin_noad, + old_rel_noad, + old_open_noad, /* 20 */ + old_close_noad, + old_punct_noad, + old_inner_noad, radical_noad, fraction_noad, /* 25 */ - under_noad, - over_noad, + old_under_noad, + old_over_noad, accent_noad, - vcenter_noad, + old_vcenter_noad, fence_noad, /* 30 */ math_char_node, /* kernel fields */ sub_box_node, @@ -575,8 +579,21 @@ typedef enum { # define local_par_dir(a) vinfo((a)+5) -# define pdf_literal_data(a) vlink(a+2) -# define pdf_literal_mode(a) vinfo(a+2) +# 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 */ + +/* literal ctm types */ + +typedef enum { + set_origin = 0, + direct_page, + direct_always, +} ctm_transform_modes; + # define pdf_refobj_node_size 3 diff --git a/Build/source/texk/web2c/luatexdir/pdf/pagetree.c b/Build/source/texk/web2c/luatexdir/pdf/pagetree.c index d88bdea51e8..676b657c0af 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pagetree.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pagetree.c @@ -17,8 +17,6 @@ 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.c 2031 2009-03-16 10:30:47Z taco $ */ - #include "ptexlib.h" #include "openbsd-compat.h" @@ -33,7 +31,9 @@ # define EX_SOFTWARE 70 #endif -static const char __svn_version[] = "$Id: pagetree.c 2031 2009-03-16 10:30:47Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/pdf/pagetree.c $"; +static const char __svn_version[] = + "$Id: pagetree.c 2143 2009-03-28 10:28:15Z hhenkel $ " + "$URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/pdf/pagetree.c $"; /**********************************************************************/ /* Page diversions */ diff --git a/Build/source/texk/web2c/luatexdir/pdf/pagetree.h b/Build/source/texk/web2c/luatexdir/pdf/pagetree.h new file mode 100644 index 00000000000..84bb41dc600 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/pdf/pagetree.h @@ -0,0 +1,31 @@ +/* pagetree.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: pagetree.h 2267 2009-04-12 18:23:21Z oneiros $ */ + +#ifndef PAGETREE_H +# define PAGETREE_H +/**********************************************************************/ + +integer output_pages_tree(); +integer pdf_do_page_divert(integer, integer); +void pdf_do_page_undivert(integer, integer); + +/**********************************************************************/ +#endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c index 783eabda742..944da4dbfaa 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c @@ -17,8 +17,6 @@ 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.c 2046 2009-03-17 20:06:05Z hhenkel $ */ - #include <stdlib.h> #include <stdio.h> #include <assert.h> @@ -27,7 +25,8 @@ #include "ptexlib.h" static const char __svn_version[] = - "$Id: pdfpage.c 2046 2009-03-17 20:06:05Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/pdf/pdfpage.c $"; + "$Id: pdfpage.c 2264 2009-04-12 17:54:48Z hhenkel $ " + "$URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/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);} @@ -111,7 +110,7 @@ void pdf_page_init() #ifdef SYNCH_POS_WITH_CUR /* some time this will be needed */ -synch_pos_with_cur(scaledpos * pos, scaledpos * cur, scaledpos * box_pos) +void synch_pos_with_cur(scaledpos * pos, scaledpos * cur, scaledpos * box_pos) { switch (dvi_direction) { case dir_TL_: @@ -163,7 +162,7 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos * pos) 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 (abs(p->cm[4].m) >= 1 || abs(p->cm[5].m) >= 1) + if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) move_pdfpos = TRUE; break; case PMODE_TEXT: @@ -171,7 +170,7 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos * pos) 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 (abs(p->tm[4].m) >= 1 || abs(p->tm[5].m) >= 1) + if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) move_pdfpos = TRUE; break; case PMODE_CHAR: @@ -182,17 +181,17 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos * pos) new.v = lround(pos->v * p->k1); p->tj_delta.m = -lround((new.h - p->cw.m) / exp10[p->cw.e - p->tj_delta.e]); - p->tm[5].m = new.v - p->pdf.v.m; /* p->tm[4] is meaningless */ - if (abs(p->tj_delta.m) >= 1 || abs(p->tm[5].m) >= 1) + 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.h.m; /* p->tm[5] is meaningless */ + 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[p->cw.e - p->tj_delta.e]); - if (abs(p->tj_delta.m) >= 1 || abs(p->tm[4].m) >= 1) + if (p->tj_delta.m != 0 || new.h != p->pdf.h.m) move_pdfpos = TRUE; break; default: @@ -283,14 +282,6 @@ void pdf_set_pos(scaled h, scaled v) set_pos(pstruct, &pos); } -void pdf_set_pos_temp(scaled h, scaled v) -{ - scaledpos pos; - pos.h = h; - pos.v = v; - set_pos_temp(pstruct, &pos); -} - /**********************************************************************/ static long pdf_char_width(pdfstructure * p, internal_font_number f, int i) @@ -489,7 +480,7 @@ static void set_textmatrix(pdfstructure * p, scaledpos * pos) static void set_font(pdfstructure * p) { - pdf_printf("/F%d", p->f_pdf); + pdf_printf("/F%d", (int) p->f_pdf); pdf_print_resname_prefix(); pdf_printf(" "); print_pdffloat(&(p->fs)); @@ -514,20 +505,24 @@ place_glyph(pdfstructure * p, scaledpos * pos, internal_font_number f, assert(is_charmode(p) || is_chararraymode(p)); move = calc_pdfpos(p, pos); if (move == TRUE) { - if ((p->wmode == WMODE_H && abs(p->tm[5].m) >= 1) - || (p->wmode == WMODE_V && abs(p->tm[4].m) >= 1) + 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); } - assert((p->wmode == WMODE_H && p->tm[5].m == 0) - || (p->wmode == WMODE_V && p->tm[4].m == 0)); 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(abs(p->tj_delta.m) >= 1); + assert(p->tj_delta.m != 0); print_pdffloat(&(p->tj_delta)); p->cw.m -= p->tj_delta.m * exp10[p->cw.e - p->tj_delta.e]; } @@ -551,7 +546,7 @@ 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", i); + pdf_printf("/Fm%d", (int) i); pdf_print_resname_prefix(); pdf_printf(" Do\nQ\n"); } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h new file mode 100644 index 00000000000..5cae6a0f601 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.h @@ -0,0 +1,85 @@ +/* pdfpage.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: pdfpage.h 2267 2009-04-12 18:23:21Z oneiros $ */ + +#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);} + +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; + +/**********************************************************************/ + +boolean calc_pdfpos(pdfstructure * p, scaledpos * pos); +void pdf_end_string_nl(); +void pdf_goto_pagemode(); +void pdf_page_init(); +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); + +/**********************************************************************/ +#endif diff --git a/Build/source/texk/web2c/luatexdir/primitive.h b/Build/source/texk/web2c/luatexdir/primitive.h index b3d202a8e59..74d1cea4b04 100644 --- a/Build/source/texk/web2c/luatexdir/primitive.h +++ b/Build/source/texk/web2c/luatexdir/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 2086 2009-03-22 15:32:08Z oneiros $ */ +/* $Id: primitive.h 2271 2009-04-12 23:42:21Z oneiros $ */ #ifndef LUATEX_PRIMITIVE_H # define LUATEX_PRIMITIVE_H 1 diff --git a/Build/source/texk/web2c/luatexdir/ptexlib.h b/Build/source/texk/web2c/luatexdir/ptexlib.h index 90b16589ed0..104e68b2c41 100644 --- a/Build/source/texk/web2c/luatexdir/ptexlib.h +++ b/Build/source/texk/web2c/luatexdir/ptexlib.h @@ -23,8 +23,6 @@ #ifndef LUATEXLIB # define LUATEXLIB -#define SVN_REV "unknown" /* temp hack */ - /* WEB2C macros and prototypes */ # if !defined(LUATEXCOERCE) # ifdef luatex @@ -49,53 +47,8 @@ extern double rint(double x); # include "openbsd-compat.h" -/***********************************************************************/ -/* from pdfpage.c */ - -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);} - -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; - -/***********************************************************************/ +# include "pdf/pagetree.h" +# include "pdf/pdfpage.h" /* pdftexlib type declarations */ typedef struct { @@ -104,20 +57,19 @@ typedef struct { boolean valid; } key_entry; -struct _subfont_entry; -typedef struct _subfont_entry subfont_entry; - -struct _subfont_entry { +typedef struct _subfont_entry { char *infix; /* infix for this subfont, eg "01" */ long charcodes[256]; /* the mapping for this subfont as read from sfd */ - subfont_entry *next; -}; + struct _subfont_entry *next; +} subfont_entry; typedef struct { char *name; /* sfd name, eg "Unicode" */ subfont_entry *subfont; /* linked list of subfonts */ } sfd_entry; +# include "font/mapfile.h" + typedef struct { integer fe_objnum; /* object number */ char *name; /* encoding file name */ @@ -137,25 +89,6 @@ typedef struct { # define FD_FLAGS_DEFAULT_NON_EMBED 0x22 /* a nonsymbolic serif font */ -typedef struct { - /* parameters scanned from the map file: */ - 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 */ - char *encname; /* encoding file name */ - char *ff_name; /* font file name */ - unsigned short type; /* various flags */ - short pid; /* Pid for truetype fonts */ - 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 glw_entry_ { /* subset glyphs for inclusion in CID-based fonts */ unsigned int id; /* glyph CID */ signed int wd; /* glyph width in 1/1000 em parts */ @@ -200,11 +133,6 @@ typedef struct fo_entry_ { /**********************************************************************/ -typedef struct { - char *ff_name; /* base name of font file */ - char *ff_path; /* full path to font file */ -} ff_entry; - typedef short shalfword; typedef struct { integer charcode, cwidth, cheight, xoff, yoff, xescape, rastersize; @@ -232,8 +160,8 @@ extern void prompt_file_name(char *s, char *e); extern str_number make_name_string(void); extern void print_file_name(str_number, str_number, str_number); -/* A hack to counter fixwrites */ -# define do_write_wterm(a) fprintf(stdout, "%s", a) +/* luainit.c */ +extern void write_svnversion(char *a); /* pdftexlib function prototypes */ @@ -242,20 +170,6 @@ extern integer get_fontfile_num(int); extern integer get_fontname_num(int); extern void epdf_free(void); -/* mapfile.c */ -extern fm_entry *lookup_fontmap(char *); -extern boolean hasfmentry(internalfontnumber); -extern void fm_free(void); -extern void fm_read_info(void); -extern ff_entry *check_ff_exist(char *, boolean); -extern void pdfmapfile(integer); -extern void pdfmapline(integer); -extern void pdf_init_map_file(string map_name); -extern fm_entry *new_fm_entry(void); -extern void delete_fm_entry(fm_entry *); -extern int avl_do_entry(fm_entry *, int); -extern int check_std_t1font(char *s); - /* papersiz.c */ extern integer myatodim(char **); extern integer myatol(char **); @@ -346,24 +260,6 @@ extern scaled getlly(); extern scaled geturx(); extern scaled getury(); -/* pdf/pdfpage.c */ -void pdf_place_rule(scaled h, scaled v, scaled wd, scaled ht); -void pdf_place_glyph(internal_font_number f, integer c); -void pdf_place_form(scaled h, scaled v, integer i); -void pdf_goto_pagemode(); -void pdf_page_init(); -void pdf_set_pos(scaled h, scaled v); -void pdf_end_string_nl(); -void pdf_print_charwidth(internal_font_number f, int i); -boolean calc_pdfpos(pdfstructure * p, scaledpos * pos); -void print_pdffloat(pdffloat * f); -void pdf_print_cm(pdffloat * cm); - -/* pdf/pagetree.c */ -extern integer pdf_do_page_divert(integer, integer); -extern void pdf_do_page_undivert(integer, integer); -extern integer output_pages_tree(); - /* writeenc.c */ extern fe_entry *get_fe_entry(char *); extern void enc_free(void); @@ -619,6 +515,11 @@ void lua_node_filter_s(int filterid, char *extrainfo); int lua_linebreak_callback(int is_broken, halfword head_node, halfword * new_head); +void lua_pdf_literal(int i); +void copy_pdf_literal(pointer r, pointer p); +void free_pdf_literal(pointer p); +void show_pdf_literal(pointer p); + void load_tex_patterns(int curlang, halfword head); void load_tex_hyphenation(int curlang, halfword head); @@ -744,6 +645,8 @@ void flush_loggable_info(void); void luacall(int s, int nameptr); void luatokencall(int p, int nameptr); +extern void check_texconfig_init(void); + void tex_error(char *msg, char **hlp); scaled divide_scaled(scaled s, scaled m, integer dd); diff --git a/Build/source/texk/web2c/luatexdir/tex/filename.c b/Build/source/texk/web2c/luatexdir/tex/filename.c index ed347c4ff55..de0c00a78c6 100644 --- a/Build/source/texk/web2c/luatexdir/tex/filename.c +++ b/Build/source/texk/web2c/luatexdir/tex/filename.c @@ -23,7 +23,7 @@ #include "commands.h" static const char _svn_version[] = - "$Id: filename.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/filename.c $"; + "$Id: filename.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/filename.c $"; #define wake_up_terminal() ; #define clear_terminal() ; diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.c b/Build/source/texk/web2c/luatexdir/tex/linebreak.c index 6f86577dc20..f1b6e87a6b3 100644 --- a/Build/source/texk/web2c/luatexdir/tex/linebreak.c +++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.c @@ -22,7 +22,7 @@ #include "nodes.h" static const char _svn_version[] = - "$Id: linebreak.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/linebreak.c $"; + "$Id: linebreak.c 2294 2009-04-15 19:40:11Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/linebreak.c $"; /* Glue nodes in a horizontal list that is being paragraphed are not supposed to include ``infinite'' shrinkability; that is why the algorithm maintains @@ -258,40 +258,6 @@ boolean check_expand_pars(internal_font_number f) #define left_pw(a) char_pw((a), left_side) #define right_pw(a) char_pw((a), right_side) -#if 0 -/* returns the total width of character protrusion of a line; - |cur_break(break_node(q))| and |p| is the leftmost resp. rightmost - node in the horizontal list representing the actual line */ - -scaled total_pw(halfword first_p, halfword q, halfword p) -{ - halfword l, r; - l = (break_node(q) == null) ? first_p : cur_break(break_node(q)); - assert(vlink(alink(p)) == p); - r = alink(r); - /* let's look at the right margin first */ - if ((p != null) && (type(p) == disc_node) && (vlink(pre_break(p)) != null)) { - /* a |disc_node| with non-empty |pre_break|, protrude the last char of |pre_break| */ - r = vlink(pre_break(p)); - while (vlink(r) != null) - r = vlink(r); - } else { - r = find_protchar_right(l, r); - } - /* now the left margin */ - if ((l != null) && (type(l) == disc_node)) { - if (vlink(post_break(l)) != null) { - l = vlink(post_break(l)); /* protrude the first char */ - goto DONE; - } - } - l = find_protchar_left(l, true); - DONE: - return (left_pw(l) + right_pw(r)); -} -#endif - - /* 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 @@ -576,8 +542,6 @@ static integer line_diff; /*the difference between the current line number #define store_background(a) {active_width[a]=background[a];} -#define act_width active_width[1] /*length from first active node to current node */ - #define kern_break() { \ if ((!is_char_node(vlink(cur_p))) && auto_breaking) \ if (type(vlink(cur_p))==glue_node) \ @@ -586,8 +550,8 @@ static integer line_diff; /*the difference between the current line number tracing_paragraphs, pdf_protrude_chars, \ line_penalty, last_line_fit, \ double_hyphen_demerits, final_hyphen_demerits,first_p,cur_p); \ - if (type(cur_p)!=math_node) act_width+=width(cur_p); \ - else act_width+=surround(cur_p); \ + if (type(cur_p)!=math_node) active_width[1]+=width(cur_p); \ + else active_width[1]+=surround(cur_p); \ } #define clean_up_the_memory() { \ @@ -634,6 +598,109 @@ 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. + */ + +/* Replacement texts and discretionary texts are supposed to contain + * only character nodes, kern nodes, and box or rule nodes. + */ + +void add_to_widths(halfword s,integer line_break_dir,integer 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); + } + if ((pdf_adjust_spacing > 1) && check_expand_pars(font(s))) { + set_prev_char_p(s); + add_char_stretch(widths[8], s); + add_char_shrink(widths[9], s); + }; + } else { + 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)); + break; + case kern_node: + if ((pdf_adjust_spacing > 1) && (subtype(s) == normal)) { + add_kern_stretch(widths[8], s); + add_kern_shrink(widths[9], s); + } + /* fall through */ + case rule_node: + widths[1] += width(s); + break; + case disc_node: /* TH temp */ + break; + default: + tconfusion("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. + */ + +void sub_from_widths(halfword s,integer line_break_dir,integer pdf_adjust_spacing, scaled *widths) +{ + while (s != null) { + /* @<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); + } + if ((pdf_adjust_spacing > 1) && check_expand_pars(font(s))) { + set_prev_char_p(s); + sub_char_stretch(widths[8], s); + sub_char_shrink(widths[9], s); + } + } else { + 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)); + break; + case kern_node: + if ((pdf_adjust_spacing > 1) && (subtype(s) == normal)) { + sub_kern_stretch(widths[8], s); + sub_kern_shrink(widths[9], s); + } + /* fall through */ + case rule_node: + widths[1] -= width(s); + break; + case disc_node: /* TH temp */ + break; + default: + tconfusion("sub_disc_widths"); + break; + } + } + s = vlink(s); + } +} + + /* 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 @@ -696,93 +763,8 @@ compute_break_width(int break_type, int pdf_adjust_spacing, halfword p path, as we are talking about the breaking on _this_ position. */ - halfword v; - for (v = vlink_no_break(p); v != null; v = vlink(v)) { - /* @<Subtract the width of node |v| from |break_width|@>; */ - /* Replacement texts and discretionary texts are supposed to contain - only character nodes, kern nodes, and box or rule nodes. */ - if (is_char_node(v)) { - if (is_rotated(line_break_dir)) { - break_width[1] -= (glyph_height(v) + glyph_depth(v)); - } else { - break_width[1] -= glyph_width(v); - } - if ((pdf_adjust_spacing > 1) && check_expand_pars(font(v))) { - set_prev_char_p(v); - sub_char_stretch(break_width[8], v); - sub_char_shrink(break_width[9], v); - } - } else { - switch (type(v)) { - case hlist_node: - case vlist_node: - if (!(dir_orthogonal(dir_primary[box_dir(v)], - dir_primary[line_break_dir]))) - break_width[1] -= width(v); - else - break_width[1] -= (depth(v) + height(v)); - break; - case kern_node: - if ((pdf_adjust_spacing > 1) && (subtype(v) == normal)) { - sub_kern_stretch(break_width[8], v); - sub_kern_shrink(break_width[9], v); - } - /* fall through */ - case rule_node: - break_width[1] -= width(v); - break; - case disc_node: - assert(vlink(v) == null); /* discs are _always_ last */ - v = no_break(v); - break; - default: - tconfusion("disc1"); - break; - } - } - } - - for (v = vlink_post_break(p); v != null; v = vlink(v)) { - /* @<Add the width of node |v| to |break_width|@>; */ - if (is_char_node(v)) { - if (is_rotated(line_break_dir)) - break_width[1] += (glyph_height(v) + glyph_depth(v)); - else - break_width[1] += glyph_width(v); - if ((pdf_adjust_spacing > 1) && check_expand_pars(font(v))) { - set_prev_char_p(v); - add_char_stretch(break_width[8], v); - add_char_shrink(break_width[9], v); - } - } else { - switch (type(v)) { - case hlist_node: - case vlist_node: - if (!(dir_orthogonal(dir_primary[box_dir(v)], - dir_primary[line_break_dir]))) - break_width[1] += width(v); - else - break_width[1] += (depth(v) + height(v)); - break; - case kern_node: - if ((pdf_adjust_spacing > 1) && (subtype(v) == normal)) { - add_kern_stretch(break_width[8], v); - add_kern_shrink(break_width[9], v); - } - /* fall through */ - case rule_node: - break_width[1] += width(v); - break; - case disc_node: - assert(vlink(v) == null); - v = no_break(v); - break; - default: - tconfusion("disc2"); - } - } - } - + sub_from_widths(vlink_no_break(p), line_break_dir, pdf_adjust_spacing, break_width); + add_to_widths (vlink_post_break(p), line_break_dir, pdf_adjust_spacing, 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 */ @@ -1167,6 +1149,14 @@ ext_try_break(integer pi, 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. + */ /* let's look at the right margin first */ if ((cur_p != null) && (type(cur_p) == disc_node) && (vlink_pre_break(cur_p) != null)) { @@ -1482,7 +1472,6 @@ ext_try_break(integer pi, } } - void ext_do_line_break(boolean d, int pretolerance, @@ -1698,7 +1687,7 @@ ext_do_line_break(boolean d, `\.{\\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. */ - act_width += (is_rotated(line_break_dir)) + active_width[1] += (is_rotated(line_break_dir)) ? (glyph_height(cur_p) + glyph_depth(cur_p)) : glyph_width(cur_p); if ((pdf_adjust_spacing > 1) && check_expand_pars(font(cur_p))) { @@ -1718,21 +1707,21 @@ ext_do_line_break(boolean d, /* 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 lines is readily calculated by |try_break|. It is convenient to use the - short name |act_width| for the component of active width that represents + short name |active_width[1]| for the component of active width that represents real width as opposed to glue. */ switch (type(cur_p)) { case hlist_node: case vlist_node: - act_width += + 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); break; case rule_node: - act_width += width(cur_p); + active_width[1] += width(cur_p); break; case whatsit_node: /* @<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>; */ @@ -1748,7 +1737,7 @@ ext_do_line_break(boolean d, 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); + push_dir_node(cur_p); /* adds to dir_ptr */ } else { pop_dir_node(); if (dir_ptr != null) @@ -1757,7 +1746,7 @@ ext_do_line_break(boolean d, break; case pdf_refxform_node: case pdf_refximage_node: - act_width += pdf_width(cur_p); + active_width[1] += pdf_width(cur_p); } /* / Advance \(p)past a whatsit node in the \(l)|line_break| loop/; */ break; @@ -1787,7 +1776,7 @@ ext_do_line_break(boolean d, /* *INDENT-ON* */ check_shrinkage(glue_ptr(cur_p)); q = glue_ptr(cur_p); - act_width += width(q); + active_width[1] += width(q); active_width[2 + stretch_order(q)] += stretch(q); active_width[7] += shrink(q); break; @@ -1795,7 +1784,7 @@ ext_do_line_break(boolean d, if (subtype(cur_p) == explicit) { kern_break(); } else { - act_width += width(cur_p); + active_width[1] += width(cur_p); if ((pdf_adjust_spacing > 1) && (subtype(cur_p) == normal)) { add_kern_stretch(active_width[8], cur_p); add_kern_shrink(active_width[9], cur_p); @@ -1803,6 +1792,8 @@ ext_do_line_break(boolean d, } break; case disc_node: + /* select_discs are handled by the leading init_disc */ + if (subtype(cur_p)==select_disc) break; /* @<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 @@ -1821,54 +1812,7 @@ ext_do_line_break(boolean d, last_line_fit, double_hyphen_demerits, final_hyphen_demerits, first_p, cur_p); } else { - do { - /* @<Add the width of node |s| to |disc_width|@>; */ - if (is_char_node(s)) { - if (is_rotated(line_break_dir)) { - disc_width[1] += - (glyph_height(s) + glyph_depth(s)); - } else { - disc_width[1] += glyph_width(s); - } - if ((pdf_adjust_spacing > 1) - && check_expand_pars(font(s))) { - set_prev_char_p(s); - add_char_stretch(disc_width[8], s); - add_char_shrink(disc_width[9], s); - } - } else { - switch (type(s)) { - case hlist_node: - case vlist_node: - if (! - (dir_orthogonal - (dir_primary[box_dir(s)], - dir_primary[line_break_dir]))) { - disc_width[1] += width(s); - } else { - disc_width[1] += (depth(s) + height(s)); - } - break; - case kern_node: - if ((pdf_adjust_spacing > 1) - && (subtype(s) == normal)) { - add_kern_stretch(disc_width[8], s); - add_kern_shrink(disc_width[9], s); - } - /* fall through */ - case rule_node: - disc_width[1] += width(s); - break; - case disc_node: - tconfusion("pre_break_disc"); - break; - default: - tconfusion("disc3"); - } - } - /* /Add the width of node |s| to |disc_width| */ - s = vlink(s); - } while (s != null); + 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, @@ -1876,157 +1820,76 @@ ext_do_line_break(boolean d, pdf_protrude_chars, line_penalty, last_line_fit, double_hyphen_demerits, final_hyphen_demerits, first_p, cur_p); - do_one_seven_eight(sub_disc_width_from_active_width); - } -#define FOO 1 -#if FOO -# if 0 - if (vlink(cur_p) != null) - nest_stack[nest_index++] = vlink(cur_p); - cur_p = no_break(cur_p); -# else - s = vlink_no_break(cur_p); - while (s != null) { - /* @<Add the width of node |s| to |act_width|@>; */ - if (is_char_node(s)) { - if (is_rotated(line_break_dir)) { - act_width += glyph_height(s) + glyph_depth(s); - } else { - act_width += glyph_width(s); - } - if ((pdf_adjust_spacing > 1) - && check_expand_pars(font(s))) { - set_prev_char_p(s); - add_char_stretch(active_width[8], s); - add_char_shrink(active_width[9], s); - }; - } else { - switch (type(s)) { - case hlist_node: - case vlist_node: - if (!(dir_orthogonal(dir_primary[box_dir(s)], - dir_primary - [line_break_dir]))) - act_width += width(s); - else - act_width += (depth(s) + height(s)); - break; - case kern_node: - if ((pdf_adjust_spacing > 1) - && (subtype(s) == normal)) { - add_kern_stretch(active_width[8], s); - add_kern_shrink(active_width[9], s); - } - /* fall through */ - case rule_node: - act_width += width(s); - break; - case disc_node: - /* what now */ - assert(vlink(s) == null); /* discs are _always_ last */ - /* NB: temporary solution: not good, but not bad either */ - s = no_break(s); - break; - default: - tconfusion("disc5"); - } + 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 */ + /* do the select-0 case 'f-f-i' */ + assert(type(vlink(cur_p))==disc_node && + subtype(vlink(cur_p))==select_disc); + s = vlink_pre_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, + pdf_protrude_chars, line_penalty, + last_line_fit, double_hyphen_demerits, + final_hyphen_demerits, first_p, + vlink(cur_p)); +#if 0 + /* TODO this does not work */ + /* go back to the starting situation */ + do_one_seven_eight(sub_disc_width_from_active_width); + do_one_seven_eight(reset_disc_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, + pdf_protrude_chars, line_penalty, + last_line_fit, double_hyphen_demerits, + final_hyphen_demerits, first_p, + vlink(cur_p)); +#endif } - /* /Add the width of node |s| to |act_width|; */ - s = vlink(s); + do_one_seven_eight(sub_disc_width_from_active_width); } -# endif - } else { /* first pass, just take the no_break path */ -#else /* FOO */ } -#endif /* FOO */ -#if 0 - if (vlink_no_break(cur_p) != null) { - if (vlink(cur_p) != null) - nest_stack[nest_index++] = vlink(cur_p); - /* fprintf(stderr,"Node Push %d [%d]->[%d] / [%d]\n",(nest_index-1),(int)cur_p,(int)vlink(cur_p),(int)vlink_no_break(cur_p)); */ - cur_p = no_break(cur_p); - } -#else s = vlink_no_break(cur_p); - while (s != null) { - /* @<Add the width of node |s| to |act_width|@>; */ - if (is_char_node(s)) { - if (is_rotated(line_break_dir)) { - act_width += glyph_height(s) + glyph_depth(s); - } else { - act_width += glyph_width(s); - } - if ((pdf_adjust_spacing > 1) - && check_expand_pars(font(s))) { - set_prev_char_p(s); - add_char_stretch(active_width[8], s); - add_char_shrink(active_width[9], s); - }; - } else { - switch (type(s)) { - case hlist_node: - case vlist_node: - if (!(dir_orthogonal(dir_primary[box_dir(s)], - dir_primary[line_break_dir]))) - act_width += width(s); - else - act_width += (depth(s) + height(s)); - break; - case kern_node: - if ((pdf_adjust_spacing > 1) - && (subtype(s) == normal)) { - add_kern_stretch(active_width[8], s); - add_kern_shrink(active_width[9], s); - } - /* fall through */ - case rule_node: - act_width += width(s); - break; - case disc_node: - assert(vlink(s) == null); /* discs are _always_ last */ - s = no_break(s); - break; - default: - tconfusion("disc4"); - } - } - /* /Add the width of node |s| to |act_width|; */ - s = vlink(s); - } -#endif -#if FOO - } -#endif /* FOO */ - break; -case math_node: - auto_breaking = (subtype(cur_p) == after); - kern_break(); - break; -case penalty_node: - ext_try_break(penalty(cur_p), unhyphenated_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); - break; -case mark_node: -case ins_node: -case adjust_node: - break; -case glue_spec_node: - fprintf(stdout, "\nfound a glue_spec in a paragraph!"); + add_to_widths(s,line_break_dir,pdf_adjust_spacing,active_width); break; -default: - fprintf(stdout, "\ntype=%d", type(cur_p)); - tconfusion("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); */ + case math_node: + auto_breaking = (subtype(cur_p) == after); + kern_break(); + break; + case penalty_node: + ext_try_break(penalty(cur_p), unhyphenated_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); + break; + case mark_node: + case ins_node: + case adjust_node: + break; + case glue_spec_node: + fprintf(stdout, "\nfound a glue_spec in a paragraph!"); + break; + default: + fprintf(stdout, "\ntype=%d", type(cur_p)); + tconfusion("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); */ + } } - } - if (cur_p == null) { + if (cur_p == null) { /* Try the final line break at the end of the paragraph, and |goto done| if the desired breakpoints have been found */ @@ -2041,139 +1904,139 @@ default: 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); - if (vlink(active) != active) { + 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); + if (vlink(active) != active) { /* @<Find an active node with fewest demerits@>; */ - r = vlink(active); - fewest_demerits = awful_bad; - do { - if (type(r) != delta_node) { - if (total_demerits(r) < fewest_demerits) { + r = vlink(active); + fewest_demerits = awful_bad; + do { + if (type(r) != delta_node) { + if (total_demerits(r) < fewest_demerits) { fewest_demerits = total_demerits(r); best_bet = r; + } } - } - r = vlink(r); - } while (r != active); - best_line = line_number(best_bet); - - /* /Find an active node with fewest demerits; */ - if (looseness == 0) - goto DONE; - /*@<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 - into segments by displayed equations, each segment will be subject to the - looseness calculation, independently of the other segments. - */ - r = vlink(active); - actual_looseness = 0; - do { - if (type(r) != delta_node) { - line_diff = line_number(r) - best_line; - if (((line_diff < actual_looseness) - && (looseness <= line_diff)) - || ((line_diff > actual_looseness) - && (looseness >= line_diff))) { - best_bet = r; - actual_looseness = line_diff; - fewest_demerits = total_demerits(r); - } else if ((line_diff == actual_looseness) && - (total_demerits(r) < fewest_demerits)) { - best_bet = r; - fewest_demerits = total_demerits(r); + r = vlink(r); + } while (r != active); + best_line = line_number(best_bet); + + /* /Find an active node with fewest demerits; */ + if (looseness == 0) + goto DONE; + /*@<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 + into segments by displayed equations, each segment will be subject to the + looseness calculation, independently of the other segments. + */ + r = vlink(active); + actual_looseness = 0; + do { + if (type(r) != delta_node) { + line_diff = line_number(r) - best_line; + if (((line_diff < actual_looseness) + && (looseness <= line_diff)) + || ((line_diff > actual_looseness) + && (looseness >= line_diff))) { + best_bet = r; + actual_looseness = line_diff; + fewest_demerits = total_demerits(r); + } else if ((line_diff == actual_looseness) && + (total_demerits(r) < fewest_demerits)) { + best_bet = r; + fewest_demerits = total_demerits(r); + } } - } - r = vlink(r); - } while (r != active); - best_line = line_number(best_bet); - - /* /Find the best active node for the desired looseness; */ - if ((actual_looseness == looseness) || final_pass) - goto DONE; + r = vlink(r); + } while (r != active); + best_line = line_number(best_bet); + + /* /Find the best active node for the desired looseness; */ + if ((actual_looseness == looseness) || final_pass) + goto DONE; + } + } + + /* Clean up the memory by removing the break nodes; */ + clean_up_the_memory(); + /* /Clean up the memory by removing the break nodes; */ + + if (!second_pass) { + if (tracing_paragraphs > 0) + 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"); + background[2] += emergency_stretch; + final_pass = true; } } - - /* Clean up the memory by removing the break nodes; */ - clean_up_the_memory(); - /* /Clean up the memory by removing the break nodes; */ - - if (!second_pass) { - if (tracing_paragraphs > 0) - 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"); - background[2] += emergency_stretch; - final_pass = true; - } -} - + DONE: -if (tracing_paragraphs > 0) { - end_diagnostic(true); - normalize_selector(); -} -if (do_last_line_fit) { + if (tracing_paragraphs > 0) { + end_diagnostic(true); + normalize_selector(); + } + if (do_last_line_fit) { /* Adjust \(t)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) { - do_last_line_fit = false; - } else { - q = new_spec(glue_ptr(last_line_fill)); - delete_glue_ref(glue_ptr(last_line_fill)); - width(q) += (active_short(best_bet) - active_glue(best_bet)); - stretch(q) = 0; - glue_ptr(last_line_fill) = q; + if (active_short(best_bet) == 0) { + do_last_line_fit = false; + } else { + q = new_spec(glue_ptr(last_line_fill)); + delete_glue_ref(glue_ptr(last_line_fill)); + width(q) += (active_short(best_bet) - active_glue(best_bet)); + stretch(q) = 0; + glue_ptr(last_line_fill) = q; + } } - /* /Adjust \(t)the final line of the paragraph; */ -} - - /* @<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| - from getting extremely long.) - */ -ext_post_line_break(d, - right_skip, - left_skip, - pdf_protrude_chars, - par_shape_ptr, - pdf_adjust_spacing, - 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, - best_bet, - last_special_line, - second_width, - second_indent, first_width, first_indent, best_line, - pdf_ignored_dimen); - /* /Break the paragraph at the chosen... */ - /* Clean up the memory by removing the break nodes; */ -clean_up_the_memory(); - /* - flush_node_list(dir_ptr); - dir_ptr=null; - */ + + /* @<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| + from getting extremely long.) + */ + + /* first thing |ext_post_line_break| does is reset |dir_ptr| */ + flush_node_list(dir_ptr); + dir_ptr=null; + + ext_post_line_break(d, + right_skip, + left_skip, + pdf_protrude_chars, + par_shape_ptr, + pdf_adjust_spacing, + 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, + best_bet, + last_special_line, + second_width, + second_indent, first_width, first_indent, best_line, + pdf_ignored_dimen); + /* /Break the paragraph at the chosen... */ + /* Clean up the memory by removing the break nodes; */ + clean_up_the_memory(); } diff --git a/Build/source/texk/web2c/luatexdir/tex/math.c b/Build/source/texk/web2c/luatexdir/tex/math.c index d1e2c2a773b..79d88c20f39 100644 --- a/Build/source/texk/web2c/luatexdir/tex/math.c +++ b/Build/source/texk/web2c/luatexdir/tex/math.c @@ -27,7 +27,7 @@ #include "tokens.h" static const char _svn_version[] = - "$Id: math.c 2099 2009-03-24 10:35:01Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/math.c $"; + "$Id: math.c 2280 2009-04-14 09:49:01Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/math.c $"; #define mode cur_list.mode_field #define head cur_list.head_field @@ -69,7 +69,7 @@ extern void rawset_sa_item(sa_tree hed, integer n, integer v); tex_error(A,B); \ } while (0) -int scan_math(pointer); +int scan_math(pointer, int); pointer fin_mlist(pointer); #define pre_display_size dimen_par(param_pre_display_size_code) @@ -210,7 +210,7 @@ void def_fam_fnt(integer fam_id, integer size_id, integer f, integer lvl) begin_diagnostic(); tprint("{assigning"); print_char(' '); - print_size(size_id); + print_cmd_chr(def_family_cmd,size_id); print_int(fam_id); print_char('='); print_font_identifier(fam_fnt(fam_id, size_id)); @@ -237,7 +237,7 @@ void unsave_math_fam_data(integer gl) begin_diagnostic(); tprint("{restoring"); print_char(' '); - print_size(size_id); + print_cmd_chr(def_family_cmd,size_id); print_int(fam_id); print_char('='); print_font_identifier(fam_fnt(fam_id, size_id)); @@ -253,132 +253,11 @@ void unsave_math_fam_data(integer gl) /* and parameters */ -static char *math_param_names[] = { - "Umathquad", - "Umathaxis", - "Umathoperatorsize", - "Umathoverbarkern", - "Umathoverbarrule", - "Umathoverbarvgap", - "Umathunderbarkern", - "Umathunderbarrule", - "Umathunderbarvgap", - "Umathradicalkern", - "Umathradicalrule", - "Umathradicalvgap", - "Umathradicaldegreebefore", - "Umathradicaldegreeafter", - "Umathradicaldegreeraise", - "Umathstackvgap", - "Umathstacknumup", - "Umathstackdenomdown", - "Umathfractionrule", - "Umathfractionnumvgap", - "Umathfractionnumup", - "Umathfractiondenomvgap", - "Umathfractiondenomdown", - "Umathfractiondelsize", - "Umathlimitabovevgap", - "Umathlimitabovebgap", - "Umathlimitabovekern", - "Umathlimitdownvgap", - "Umathlimitdownbgap", - "Umathlimitdownkern", - "Umathunderdelimitervgap", - "Umathunderdelimiterbgap", - "Umathoverdelimitervgap", - "Umathoverdelimiterbgap", - "Umathsubshiftdrop", - "Umathsupshiftdrop", - "Umathsubshiftdown", - "Umathsubsupshiftdown", - "Umathsubtopmax", - "Umathsupshiftup", - "Umathsupbottommin", - "Umathsupsubbottommax", - "Umathsubsupvgap", - "Umathspaceafterscript", - "Umathconnectoroverlapmin", - "Umathordordspacing", - "Umathordopspacing", - "Umathordbinspacing", - "Umathordrelspacing", - "Umathordopenspacing", - "Umathordclosespacing", - "Umathordpunctspacing", - "Umathordinnerspacing", - "Umathopordspacing", - "Umathopopspacing", - "Umathopbinspacing", - "Umathoprelspacing", - "Umathopopenspacing", - "Umathopclosespacing", - "Umathoppunctspacing", - "Umathopinnerspacing", - "Umathbinordspacing", - "Umathbinopspacing", - "Umathbinbinspacing", - "Umathbinrelspacing", - "Umathbinopenspacing", - "Umathbinclosespacing", - "Umathbinpunctspacing", - "Umathbininnerspacing", - "Umathrelordspacing", - "Umathrelopspacing", - "Umathrelbinspacing", - "Umathrelrelspacing", - "Umathrelopenspacing", - "Umathrelclosespacing", - "Umathrelpunctspacing", - "Umathrelinnerspacing", - "Umathopenordspacing", - "Umathopenopspacing", - "Umathopenbinspacing", - "Umathopenrelspacing", - "Umathopenopenspacing", - "Umathopenclosespacing", - "Umathopenpunctspacing", - "Umathopeninnerspacing", - "Umathcloseordspacing", - "Umathcloseopspacing", - "Umathclosebinspacing", - "Umathcloserelspacing", - "Umathcloseopenspacing", - "Umathcloseclosespacing", - "Umathclosepunctspacing", - "Umathcloseinnerspacing", - "Umathpunctordspacing", - "Umathpunctopspacing", - "Umathpunctbinspacing", - "Umathpunctrelspacing", - "Umathpunctopenspacing", - "Umathpunctclosespacing", - "Umathpunctpunctspacing", - "Umathpunctinnerspacing", - "Umathinnerordspacing", - "Umathinneropspacing", - "Umathinnerbinspacing", - "Umathinnerrelspacing", - "Umathinneropenspacing", - "Umathinnerclosespacing", - "Umathinnerpunctspacing", - "Umathinnerinnerspacing", - NULL -}; - #define MATHPARAMSTACK 8 #define MATHPARAMDEFAULT undefined_math_parameter static sa_tree math_param_head = NULL; -void print_math_param(int param_code) -{ - if (param_code >= 0 && param_code < math_param_last) - tprint_esc(math_param_names[param_code]); - else - tprint("Unknown math parameter code!"); -} - void def_math_param(int param_id, int style_id, scaled value, int lvl) { integer n = param_id + (256 * style_id); @@ -387,8 +266,8 @@ void def_math_param(int param_id, int style_id, scaled value, int lvl) begin_diagnostic(); tprint("{assigning"); print_char(' '); - print_math_param(param_id); - print_style(style_id); + print_cmd_chr(set_math_param_cmd,param_id); + print_cmd_chr(math_style_cmd,style_id); print_char('='); print_int(value); print_char('}'); @@ -421,8 +300,8 @@ void unsave_math_param_data(integer gl) begin_diagnostic(); tprint("{restoring"); print_char(' '); - print_math_param(param_id); - print_style(style_id); + print_cmd_chr(set_math_param_cmd,param_id); + print_cmd_chr(math_style_cmd,style_id); print_char('='); print_int(get_math_param(param_id, style_id)); print_char('}'); @@ -524,7 +403,7 @@ be placed at the left and right of the fraction. In this way, a pointer new_noad(void) { pointer p; - p = new_node(ord_noad, normal); + p = new_node(simple_noad, ord_noad_type); /* all noad fields are zero after this */ return p; } @@ -576,15 +455,52 @@ i.e., a smaller style has a larger numerical value. @:TeXbook}{\sl The \TeX book@> */ -const char *math_style_names[] = { "display", "crampeddisplay", +const char *math_style_names[] = { + "display", "crampeddisplay", "text", "crampedtext", "script", "crampedscript", "scriptscript", "crampedscriptscript", NULL }; +const char *math_param_names[] = { + "quad", "axis", "operatorsize", + "overbarkern", "overbarrule", "overbarvgap", + "underbarkern","underbarrule", "underbarvgap", + "radicalkern", "radicalrule", "radicalvgap", + "radicaldegreebefore", "radicaldegreeafter", "radicaldegreeraise", + "stackvgap", "stacknumup", "stackdenomdown", + "fractionrule", "fractionnumvgap", "fractionnumup", + "fractiondenomvgap","fractiondenomdown", "fractiondelsize", + "limitabovevgap", "limitabovebgap", "limitabovekern", + "limitdownvgap", "limitdownbgap", "limitdownkern", + "underdelimitervgap", "underdelimiterbgap", + "overdelimitervgap", "overdelimiterbgap", + "subshiftdrop", "supshiftdrop", "subshiftdown", + "subsupshiftdown","subtopmax", "supshiftup", + "supbottommin", "supsubbottommax", "subsupvgap", + "spaceafterscript", "connectoroverlapmin", + "ordordspacing", "ordopspacing","ordbinspacing","ordrelspacing", + "ordopenspacing","ordclosespacing", "ordpunctspacing","ordinnerspacing", + "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", + "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", + "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", + "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", + "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", + "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", + "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", + "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", + "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", + "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", + "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", + "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", + "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", + "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", + NULL }; + pointer new_style(small_number s) { /* create a style node */ + m_style = s; return new_node(style_node, s); } @@ -625,7 +541,7 @@ void show_math_node(pointer p) { switch (type(p)) { case style_node: - print_style(subtype(p)); + print_cmd_chr(math_style_cmd,subtype(p)); break; case choice_node: tprint_esc("mathchoice"); @@ -642,18 +558,8 @@ void show_math_node(pointer p) show_node_list(script_script_mlist(p)); flush_char; break; - case ord_noad: - case op_noad: - case bin_noad: - case rel_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: + case simple_noad: case radical_noad: - case over_noad: - case under_noad: - case vcenter_noad: case accent_noad: display_normal_noad(p); break; @@ -747,56 +653,54 @@ void print_subsidiary_data(pointer p, ASCII_code c) } } -void print_style(integer c) -{ - if (c <= cramped_script_script_style) { - tprint_esc((char *) math_style_names[c]); - tprint("style"); - } else { - tprint("Unknown style!"); - } -} - - void display_normal_noad(pointer p) { switch (type(p)) { - case ord_noad: - tprint_esc("mathord"); - break; - case op_noad: - tprint_esc("mathop"); - if (subtype(p) == limits) - tprint_esc("limits"); - else if (subtype(p) == no_limits) - tprint_esc("nolimits"); - break; - case bin_noad: - tprint_esc("mathbin"); - break; - case rel_noad: - tprint_esc("mathrel"); - break; - case open_noad: - tprint_esc("mathopen"); - break; - case close_noad: - tprint_esc("mathclose"); - break; - case punct_noad: - tprint_esc("mathpunct"); - break; - case inner_noad: - tprint_esc("mathinner"); - break; - case over_noad: - tprint_esc("overline"); - break; - case under_noad: - tprint_esc("underline"); - break; - case vcenter_noad: - tprint_esc("vcenter"); + case simple_noad: + switch (subtype(p)) { + case ord_noad_type: + tprint_esc("mathord"); + break; + case op_noad_type_normal: + case op_noad_type_limits: + case op_noad_type_no_limits: + tprint_esc("mathop"); + if (subtype(p) == op_noad_type_limits) + tprint_esc("limits"); + else if (subtype(p) == op_noad_type_no_limits) + tprint_esc("nolimits"); + break; + case bin_noad_type: + tprint_esc("mathbin"); + break; + case rel_noad_type: + tprint_esc("mathrel"); + break; + case open_noad_type: + tprint_esc("mathopen"); + break; + case close_noad_type: + tprint_esc("mathclose"); + break; + case punct_noad_type: + tprint_esc("mathpunct"); + break; + case inner_noad_type: + tprint_esc("mathinner"); + break; + case over_noad_type: + tprint_esc("overline"); + break; + case under_noad_type: + tprint_esc("underline"); + break; + case vcenter_noad_type: + tprint_esc("vcenter"); + break; + default: + tprint("<unknown noad type!>"); + break; + } break; case radical_noad: if (subtype(p) == 7) @@ -875,55 +779,6 @@ void display_fraction_noad(pointer p) print_subsidiary_data(denominator(p), '/'); } -/* This function is for |print_cmd_chr| only */ - -void print_math_comp(halfword chr_code) -{ - switch (chr_code) { - case ord_noad: - tprint_esc("mathord"); - break; - case op_noad: - tprint_esc("mathop"); - break; - case bin_noad: - tprint_esc("mathbin"); - break; - case rel_noad: - tprint_esc("mathrel"); - break; - case open_noad: - tprint_esc("mathopen"); - break; - case close_noad: - tprint_esc("mathclose"); - break; - case punct_noad: - tprint_esc("mathpunct"); - break; - case inner_noad: - tprint_esc("mathinner"); - break; - case under_noad: - tprint_esc("underline"); - break; - default: - tprint_esc("overline"); - break; - } -} - -void print_limit_switch(halfword chr_code) -{ - if (chr_code == limits) - tprint_esc("limits"); - else if (chr_code == no_limits) - tprint_esc("nolimits"); - else - tprint_esc("displaylimits"); -} - - /* 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 @@ -947,19 +802,20 @@ void new_save_level_math(group_code c) eq_word_define(static_int_base + param_level_local_dir_code, cur_level); } -void push_math(group_code c) +void push_math(group_code c, int mstyle) { if (math_direction != text_direction) dir_math_save = true; push_nest(); mode = -mmode; incompleat_noad = null; + m_style = mstyle; new_save_level_math(c); } void enter_ordinary_math(void) { - push_math(math_shift_group); + push_math(math_shift_group, text_style); eq_word_define(static_int_base + param_cur_fam_code, -1); if (every_math != null) begin_token_list(every_math, every_math_text); @@ -975,12 +831,20 @@ called for. void init_math(void) { - get_token(); /* |get_x_token| would fail on \.{\\ifmmode}\thinspace! */ - if ((cur_cmd == math_shift_cmd) && (mode > 0)) { + if ( cur_cmd == math_shift_cmd ) { + get_token(); /* |get_x_token| would fail on \.{\\ifmmode}\thinspace! */ + if ((cur_cmd == math_shift_cmd) && (mode > 0)) { + enter_display_math(); + } else { + back_input(); + enter_ordinary_math(); + } + } else if (cur_cmd==math_shift_cs_cmd && cur_chr == display_style ) { enter_display_math(); - } else { - back_input(); + } else if (cur_cmd==math_shift_cs_cmd && cur_chr == text_style ) { enter_ordinary_math(); + } else { + you_cant(); } } @@ -1027,7 +891,7 @@ void math_left_brace(void) q = new_node(math_char_node, 0); nucleus(tail) = q; back_input(); - (void) scan_math(nucleus(tail)); + (void) scan_math(nucleus(tail), m_style); } /* @@ -1078,7 +942,7 @@ void enter_display_math(void) l = varmem[p].cint; } - push_math(math_shift_group); + 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); @@ -1339,7 +1203,7 @@ that subformula into a given word of |mem|. #define get_next_nb_nr() do { get_x_token(); } while (cur_cmd==spacer_cmd||cur_cmd==relax_cmd) -int scan_math(pointer p) +int scan_math(pointer p, int mstyle) { /* label restart,reswitch,exit; */ mathcodeval mval; @@ -1406,7 +1270,7 @@ int scan_math(pointer p) scan_left_brace(); saved(0) = p; incr(save_ptr); - push_math(math_group); + push_math(math_group, mstyle); return 1; } type(p) = math_char_node; @@ -1446,9 +1310,17 @@ void set_math_char(mathcodeval mval) if (mval.class_value == var_code) { if (fam_in_range) math_fam(nucleus(p)) = cur_fam; - type(p) = ord_noad; + subtype(p) = ord_noad_type; } else { - type(p) = ord_noad + mval.class_value; + switch (mval.class_value) { + case 0: subtype(p) = ord_noad_type; break; + case 1: subtype(p) = op_noad_type_normal; break; + case 2: subtype(p) = bin_noad_type; break; + case 3: subtype(p) = rel_noad_type; break; + case 4: subtype(p) = open_noad_type; break; + case 5: subtype(p) = close_noad_type; break; + case 6: subtype(p) = inner_noad_type; break; + } } vlink(tail) = p; tail = p; @@ -1486,10 +1358,13 @@ void math_math_comp(void) { pointer q; tail_append(new_noad()); - type(tail) = cur_chr; + subtype(tail) = cur_chr; q = new_node(math_char_node, 0); nucleus(tail) = q; - (void) scan_math(nucleus(tail)); + if (cur_chr==over_noad_type) + (void) scan_math(nucleus(tail), cramped_style(m_style)); + else + (void) scan_math(nucleus(tail), m_style); } @@ -1500,7 +1375,7 @@ void math_limit_switch(void) NULL }; if (head != tail) { - if (type(tail) == op_noad) { + if (type(tail) == simple_noad) { subtype(tail) = cur_chr; return; } @@ -1602,18 +1477,21 @@ void math_radical(void) else tconfusion("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 */ q = new_node(math_char_node, 0); vlink(q) = tail; degree(tail) = q; - if (!scan_math(degree(tail))) { + if (!scan_math(degree(tail), sup_sup_style(m_style))) { + vlink(degree(tail)) = null; q = new_node(math_char_node, 0); nucleus(tail) = q; - (void) scan_math(nucleus(tail)); + (void) scan_math(nucleus(tail), cramped_style(m_style)); } } else { q = new_node(math_char_node, 0); nucleus(tail) = q; - (void) scan_math(nucleus(tail)); + (void) scan_math(nucleus(tail), cramped_style(m_style)); } } @@ -1633,7 +1511,7 @@ void math_ac(void) }; tex_error("Please use \\mathaccent for accents in math mode", hlp); } - tail_append(new_node(accent_noad, normal)); + tail_append(new_node(accent_noad, 0)); if (cur_chr == 0) { /* \mathaccent */ t = scan_mathchar(tex_mathcode); } else if (cur_chr == 1) { /* \omathaccent */ @@ -1668,14 +1546,14 @@ void math_ac(void) } q = new_node(math_char_node, 0); nucleus(tail) = q; - (void) scan_math(nucleus(tail)); + (void) scan_math(nucleus(tail), cramped_style(m_style)); } pointer math_vcenter_group(pointer p) { pointer q, r; q = new_noad(); - type(q) = vcenter_noad; + subtype(q) = vcenter_noad_type; r = new_node(sub_box_node, 0); nucleus(q) = r; math_list(nucleus(q)) = p; @@ -1692,12 +1570,14 @@ void append_choices(void) tail_append(new_choice()); incr(save_ptr); saved(-1) = 0; - push_math(math_choice_group); + push_math(math_choice_group, display_style); scan_left_brace(); } void build_choices(void) { pointer p; /* the current mlist */ + int prev_style; + prev_style = m_style; unsave_math(); p = fin_mlist(null); switch (saved(-1)) { @@ -1717,7 +1597,7 @@ void build_choices(void) break; } /* there are no other cases */ incr(saved(-1)); - push_math(math_choice_group); + push_math(math_choice_group, (prev_style+2)); scan_left_brace(); } @@ -1734,7 +1614,8 @@ void sub_sup(void) q = new_node(sub_mlist_node, 0); nucleus(tail) = q; } - if (cur_cmd == sup_mark_cmd) { + if (cur_cmd == sup_mark_cmd || + cur_chr == sup_mark_cmd ) { /* super_sub_script */ if (supscr(tail) != null) { char *hlp[] = { "I treat `x^1^2' essentially like `x^1{}^2'.", NULL @@ -1746,8 +1627,9 @@ void sub_sup(void) } q = new_node(math_char_node, 0); supscr(tail) = q; - (void) scan_math(supscr(tail)); - } else { + (void) scan_math(supscr(tail), sup_style(m_style)); + } else if (cur_cmd == sub_mark_cmd || + cur_chr == sub_mark_cmd ) { if (subscr(tail) != null) { char *hlp[] = { "I treat `x_1_2' essentially like `x_1{}_2'.", NULL @@ -1759,7 +1641,7 @@ void sub_sup(void) } q = new_node(math_char_node, 0); subscr(tail) = q; - (void) scan_math(subscr(tail)); + (void) scan_math(subscr(tail), sub_style(m_style)); } } @@ -1793,11 +1675,12 @@ void math_fraction(void) scan_normal_dimen(); tex_error("Ambiguous; you need another { and }", hlp); } else { - incompleat_noad = new_node(fraction_noad, normal); + incompleat_noad = new_node(fraction_noad, 0); numerator(incompleat_noad) = new_node(sub_mlist_node, 0); math_list(numerator(incompleat_noad)) = vlink(head); vlink(head) = null; tail = head; + m_style = cramped_style(m_style); if (c >= delimited_code) { q = new_node(delim_node, 0); @@ -1872,6 +1755,7 @@ surround an accent that is the nucleus of an Ord atom. void close_math_group(pointer p) { pointer q; + int old_style = m_style; unsave_math(); decr(save_ptr); @@ -1880,7 +1764,7 @@ void close_math_group(pointer p) math_list(saved(0)) = p; if (p != null) { if (vlink(p) == null) { - if (type(p) == ord_noad) { + if (type(p) == simple_noad && subtype(p) == ord_noad_type ) { if (subscr(p) == null && supscr(p) == null) { type(saved(0)) = type(nucleus(p)); if (type(nucleus(p)) == math_char_node) { @@ -1890,16 +1774,14 @@ void close_math_group(pointer p) math_list(saved(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)); node_attr(nucleus(p)) = null; flush_node(p); } - } - } else { - if (type(p) == accent_noad) { - if (saved(0) == nucleus(tail)) { - /* todo: check this branch */ - if (type(tail) == ord_noad) { + } else if (type(p) == accent_noad) { + if (saved(0) == nucleus(tail)) { + if (type(tail) == simple_noad && subtype(tail) == ord_noad_type) { q = head; while (vlink(q) != tail) q = vlink(q); @@ -1907,6 +1789,7 @@ void close_math_group(pointer p) nucleus(tail) = null; subscr(tail) = null; supscr(tail) = null; + delete_attribute_ref(node_attr(p)); node_attr(p) = node_attr(tail); node_attr(tail) = null; flush_node(tail); @@ -1922,7 +1805,7 @@ void close_math_group(pointer p) nucleus(vlink(saved(0))) = q; vlink(saved(0)) = null; saved(0) = q; - (void) scan_math(saved(0)); + (void) scan_math(saved(0), old_style); /* restart */ } } @@ -1974,13 +1857,13 @@ void math_left_right(void) unsave_math(); } if (t != right_noad_side) { - push_math(math_left_group); + push_math(math_left_group, cur_style); vlink(head) = q; tail = p; delim_ptr = p; } else { tail_append(new_noad()); - type(tail) = inner_noad; + subtype(tail) = inner_noad_type; r = new_node(sub_mlist_node, 0); nucleus(tail) = r; math_list(nucleus(tail)) = q; @@ -2006,6 +1889,30 @@ static void check_second_math_shift(void) } } +static void check_display_math_end(void) +{ + if (cur_chr != cramped_display_style) { + char *hlp[] = { + "I shall assume that you typed that.", + NULL + }; + tex_error("Display math should end with \\Ustopdisplaymath", hlp); + } +} + +static void check_inline_math_end(void) +{ + if (cur_chr != cramped_text_style) { + char *hlp[] = { + "I shall assume that you typed that.", + NULL + }; + tex_error("Inline math should end with \\Ustopmath", hlp); + } +} + + + void finish_displayed_math(boolean l, boolean danger, pointer a); void after_math(void) @@ -2018,8 +1925,16 @@ void after_math(void) 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 */ - check_second_math_shift(); + 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(); @@ -2037,6 +1952,9 @@ void after_math(void) `\.{\$\$...\$\$}', 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)); @@ -2053,8 +1971,13 @@ void after_math(void) space_factor = 1000; unsave_math(); } else { - if (a == null) - check_second_math_shift(); + 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); } @@ -2253,3 +2176,23 @@ void finish_display_alignment(pointer p, pointer q, memory_word aux_save) prev_depth = aux_save.cint; resume_after_display(); } + +/* Interface to \.{\\Umath} and \.{\\mathstyle} */ + +void setup_math_style (void) +{ + pointer q; + tail_append(new_noad()); + q = new_node(math_char_node, 0); + nucleus(tail) = q; + (void) scan_math(nucleus(tail), num_style(m_style)); +} + + +void print_math_style (void) +{ + if (abs(mode)==mmode) + print_int(m_style); + else + print_int(-1); +} diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.c b/Build/source/texk/web2c/luatexdir/tex/mlist.c index 51858c42899..dd1bf5a1b39 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mlist.c +++ b/Build/source/texk/web2c/luatexdir/tex/mlist.c @@ -24,7 +24,7 @@ #include "commands.h" static const char _svn_version[] = - "$Id: mlist.c 2099 2009-03-24 10:35:01Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/mlist.c $"; + "$Id: mlist.c 2280 2009-04-14 09:49:01Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/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) @@ -35,6 +35,8 @@ static const char _svn_version[] = #define disable_lig int_par(param_disable_lig_code) #define disable_kern int_par(param_disable_kern_code) +#define nDEBUG + #define reset_attributes(p,newatt) do { \ delete_attribute_ref(node_attr(p)); \ node_attr(p) = newatt; \ @@ -152,9 +154,7 @@ SkewedFractionVerticalGap: so I would like to see an example first Also still TODO for OpenType Math: - * cutins (math_kern) * extensible large operators - * bottom accents * prescripts */ @@ -812,10 +812,19 @@ void fixup_math_parameters(integer fam_id, integer size_id, integer f, font_MATH_par(f, SubscriptShiftDown), lvl); DEFINE_DMATH_PARAMETERS(math_param_sub_shift_down, size_id, font_MATH_par(f, SubscriptShiftDown), lvl); - DEFINE_MATH_PARAMETERS(math_param_sub_sup_shift_down, size_id, - font_MATH_par(f, SubscriptShiftDown), lvl); - DEFINE_DMATH_PARAMETERS(math_param_sub_sup_shift_down, size_id, - font_MATH_par(f, SubscriptShiftDown), lvl); + + if (font_MATH_par(f, SubscriptShiftDownWithSuperscript)!=undefined_math_parameter) { + DEFINE_MATH_PARAMETERS(math_param_sub_sup_shift_down, size_id, + font_MATH_par(f, SubscriptShiftDownWithSuperscript), lvl); + DEFINE_DMATH_PARAMETERS(math_param_sub_sup_shift_down, size_id, + font_MATH_par(f, SubscriptShiftDownWithSuperscript), lvl); + } else { + DEFINE_MATH_PARAMETERS(math_param_sub_sup_shift_down, size_id, + font_MATH_par(f, SubscriptShiftDown), lvl); + DEFINE_DMATH_PARAMETERS(math_param_sub_sup_shift_down, size_id, + font_MATH_par(f, SubscriptShiftDown), lvl); + } + DEFINE_MATH_PARAMETERS(math_param_sub_top_max, size_id, font_MATH_par(f, SubscriptTopMax), lvl); DEFINE_DMATH_PARAMETERS(math_param_sub_top_max, size_id, @@ -1246,17 +1255,6 @@ char *math_size_string(integer s) return "scriptscriptfont"; } -void print_size(integer s) -{ - if (s == text_size) - tprint_esc("textfont"); - else if (s == script_size) - tprint_esc("scriptfont"); - else - tprint_esc("scriptscriptfont"); -} - - /* @ When the style changes, the following piece of program computes associated information: @@ -2127,21 +2125,25 @@ 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 m_style, boolean penalties) +void run_mlist_to_hlist(pointer p, integer mstyle, boolean penalties) { int callback_id; int a, sfix; lua_State *L = Luas; + if (p == null) { + vlink(temp_head) = null; + return; + } finalize_math_parameters(); callback_id = callback_defined(mlist_to_hlist_callback); - if (p != null && callback_id > 0) { + if (callback_id > 0) { sfix = lua_gettop(L); if (!get_callback(L, callback_id)) { lua_settop(L, sfix); return; } nodelist_to_lua(L, p); /* arg 1 */ - lua_pushstring(L, math_style_names[m_style]); /* arg 2 */ + lua_pushstring(L, math_style_names[mstyle]); /* arg 2 */ lua_pushboolean(L, penalties); /* arg 3 */ if (lua_pcall(L, 3, 1, 0) != 0) { /* 3 args, 1 result */ fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); @@ -2152,11 +2154,13 @@ void run_mlist_to_hlist(pointer p, integer m_style, boolean penalties) a = nodelist_from_lua(L); lua_settop(L, sfix); vlink(temp_head) = a; - } else { + } else if (callback_id==0) { cur_mlist = p; - cur_style = m_style; + cur_style = mstyle; mlist_penalties = penalties; mlist_to_hlist(); + } else { + vlink(temp_head) = null; } } @@ -2301,17 +2305,7 @@ void assign_new_hlist(pointer q, pointer r) denominator(q) = null; break; case radical_noad: - case ord_noad: - case op_noad: - case bin_noad: - case rel_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: - case over_noad: - case under_noad: - case vcenter_noad: + case simple_noad: case accent_noad: if (nucleus(q) != null) { math_list(nucleus(q)) = null; @@ -2438,7 +2432,7 @@ void make_radical(pointer q) vlink(x) = r; y = x; } - degree(q) = null; + flush_node(degree(q)); } p = hpack(y, 0, additional); reset_attributes(p, node_attr(q)); @@ -2448,10 +2442,11 @@ void make_radical(pointer q) /* Construct a vlist box */ -static pointer -wrapup_delimiter (pointer x, pointer y, pointer q, - scaled shift_up, scaled shift_down) { - pointer p; /* temporary register for box construction */ +static pointer +wrapup_delimiter(pointer x, pointer y, pointer q, + scaled shift_up, scaled shift_down) +{ + pointer p; /* temporary register for box construction */ pointer v = new_null_box(); type(v) = vlist_node; height(v) = shift_up + height(x); @@ -2477,12 +2472,12 @@ wrapup_delimiter (pointer x, pointer y, pointer q, void make_over_delimiter(pointer q) { - pointer x, y, v; /* temporary registers for box construction */ + 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)); left_delimiter(q) = null; - fixup_widths(x,y); + fixup_widths(x, y); shift_up = over_delimiter_bgap(cur_style); shift_down = 0; /* under_delimiter_bgap(cur_style); */ clr = over_delimiter_vgap(cur_style); @@ -2490,7 +2485,7 @@ void make_over_delimiter(pointer q) if (delta > 0) { shift_up = shift_up + delta; } - v = wrapup_delimiter (x, y, q, shift_up, shift_down); + v = wrapup_delimiter(x, y, q, shift_up, shift_down); width(v) = width(x); /* this also equals |width(y)| */ math_list(nucleus(q)) = v; type(nucleus(q)) = sub_box_node; @@ -2500,20 +2495,22 @@ void make_over_delimiter(pointer q) void make_delimiter_over(pointer q) { - pointer x, y, v; /* temporary registers for box construction */ + 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)); + x = flat_var_delimiter(left_delimiter(q), + cur_size + (cur_size == script_script_size ? 0 : 1), + width(y)); left_delimiter(q) = null; - fixup_widths(x,y); + fixup_widths(x, y); shift_up = over_delimiter_bgap(cur_style); - shift_down = 0; + shift_down = 0; clr = over_delimiter_vgap(cur_style); delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down)); if (delta > 0) { shift_up = shift_up + delta; } - v = wrapup_delimiter (x, y, q, shift_up, shift_down); + v = wrapup_delimiter(x, y, q, shift_up, shift_down); width(v) = width(x); /* this also equals |width(y)| */ math_list(nucleus(q)) = v; type(nucleus(q)) = sub_box_node; @@ -2524,12 +2521,14 @@ void make_delimiter_over(pointer q) void make_delimiter_under(pointer q) { - pointer x, y, v; /* temporary registers for box construction */ + 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)); + y = flat_var_delimiter(left_delimiter(q), + cur_size + (cur_size == script_script_size ? 0 : 1), + width(x)); left_delimiter(q) = null; - fixup_widths(x,y); + fixup_widths(x, y); shift_up = 0; /* over_delimiter_bgap(cur_style); */ shift_down = under_delimiter_bgap(cur_style); clr = under_delimiter_vgap(cur_style); @@ -2537,7 +2536,7 @@ void make_delimiter_under(pointer q) if (delta > 0) { shift_down = shift_down + delta; } - v = wrapup_delimiter (x, y, q, shift_up, shift_down); + v = wrapup_delimiter(x, y, q, shift_up, shift_down); width(v) = width(y); /* this also equals |width(y)| */ math_list(nucleus(q)) = v; type(nucleus(q)) = sub_box_node; @@ -2548,12 +2547,12 @@ void make_delimiter_under(pointer q) void make_under_delimiter(pointer q) { - pointer x, y, v; /* temporary registers for box construction */ + 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)); left_delimiter(q) = null; - fixup_widths(x,y); + fixup_widths(x, y); shift_up = 0; /* over_delimiter_bgap(cur_style); */ shift_down = under_delimiter_bgap(cur_style); clr = under_delimiter_vgap(cur_style); @@ -2561,7 +2560,7 @@ void make_under_delimiter(pointer q) if (delta > 0) { shift_down = shift_down + delta; } - v = wrapup_delimiter (x, y, q, shift_up, shift_down); + v = wrapup_delimiter(x, y, q, shift_up, shift_down); width(v) = width(y); /* this also equals |width(y)| */ math_list(nucleus(q)) = v; type(nucleus(q)) = sub_box_node; @@ -2695,7 +2694,7 @@ void do_make_math_accent(pointer q, internal_font_number f, integer c, pack_direction = math_direction; r = vpackage(y, 0, additional, max_dimen); reset_attributes(r, node_attr(q)); - width(r) = w; + width(r) = width(x); y = r; if (top_or_bot == TOP_CODE) { if (height(y) < h) { @@ -2845,36 +2844,53 @@ scaled make_op(pointer q) integer c; /* register for character examination */ scaled shift_up, shift_down; /* dimensions for box calculation */ scaled ok_size; - if ((subtype(q) == normal) && (cur_style < text_style)) - subtype(q) = limits; + if ((subtype(q) == op_noad_type_normal) && (cur_style < text_style)) + subtype(q) = op_noad_type_limits; if (type(nucleus(q)) == math_char_node) { fetch(nucleus(q)); if (cur_style < text_style) { /* try to make it larger */ - if (minimum_operator_size(cur_style) != undefined_math_parameter) - ok_size = minimum_operator_size(cur_style); - else + ok_size = minimum_operator_size(cur_style); + if (ok_size != undefined_math_parameter) { + /* creating a temporary delimiter is the cleanest way */ + 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; + } else { ok_size = height_plus_depth(cur_f, cur_c) + 1; - while ((char_tag(cur_f, cur_c) == list_tag) && - height_plus_depth(cur_f, cur_c) < ok_size) { - c = char_remainder(cur_f, cur_c); - if (!char_exists(cur_f, c)) - break; - cur_c = c; - math_character(nucleus(q)) = c; - } - } - delta = char_italic(cur_f, cur_c); - x = clean_box(nucleus(q), cur_style); - if ((subscr(q) != null) && (subtype(q) != limits)) - width(x) = width(x) - delta; /* remove italic correction */ - shift_amount(x) = half(height(x) - depth(x)) - math_axis(cur_size); - /* center vertically */ - type(nucleus(q)) = sub_box_node; - math_list(nucleus(q)) = x; + while ((char_tag(cur_f, cur_c) == list_tag) && + height_plus_depth(cur_f, cur_c) < ok_size) { + c = char_remainder(cur_f, cur_c); + if (!char_exists(cur_f, c)) + break; + cur_c = c; + math_character(nucleus(q)) = c; + } + delta = char_italic(cur_f, cur_c); + x = clean_box(nucleus(q), 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); + /* center vertically */ + } + type(nucleus(q)) = sub_box_node; + math_list(nucleus(q)) = x; + + } else { /* normal size */ + delta = char_italic(cur_f, cur_c); + x = clean_box(nucleus(q), 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); + /* center vertically */ + type(nucleus(q)) = sub_box_node; + math_list(nucleus(q)) = x; + } } else { delta = 0; } - if (subtype(q) == limits) { + 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)); @@ -2977,7 +2993,8 @@ void make_ord(pointer q) supscr(q) == null && type(nucleus(q)) == math_char_node) { p = vlink(q); if ((p != null) && - (type(p) >= ord_noad) && (type(p) <= punct_noad) && + (type(p) == simple_noad) && + (subtype(p) <= punct_noad_type) && (type(nucleus(p)) == math_char_node) && (math_fam(nucleus(p)) == math_fam(nucleus(q)))) { type(nucleus(q)) = math_text_char_node; @@ -3045,7 +3062,7 @@ void make_ord(pointer q) } } if (disable_kern == 0 && has_kern(cur_f, a)) { - k = get_kern(cur_f, a, cur_c); + k = get_kern(cur_f, a, cur_c); /* todo: should this use mathkerns? */ if (k != 0) { p = new_kern(k); reset_attributes(p, node_attr(q)); @@ -3059,22 +3076,167 @@ 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 + */ + +#define MATH_KERN_NOT_FOUND 0x7FFFFFFF + +/* 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 +*/ + +scaled math_kern_at(internal_font_number f, integer c, int side, int v) +{ + int h, k, numkerns; + scaled *kerns_heights; + scaled kern = 0; + charinfo *co = char_info(f, c); /* known to exist */ + numkerns = get_charinfo_math_kerns(co, side); +#ifdef DEBUG + fprintf(stderr, " entries = %d, height = %d\n", numkerns, v); +#endif + if (numkerns == 0) + return kern; + if (side == top_left_kern) { + kerns_heights = co->top_left_math_kern_array; + } else if (side == bottom_left_kern) { + kerns_heights = co->bottom_left_math_kern_array; + } else if (side == top_right_kern) { + kerns_heights = co->top_right_math_kern_array; + } else if (side == bottom_right_kern) { + kerns_heights = co->bottom_right_math_kern_array; + } else { + tconfusion("math_kern_at"); + kerns_heights = NULL; /* not reached */ + } +#ifdef DEBUG + fprintf(stderr, " entry 0: %d,%d\n", kerns_heights[0], kerns_heights[1]); +#endif + if (v < kerns_heights[0]) + return kerns_heights[1]; + for (k = 0; k < numkerns; k++) { + h = kerns_heights[(k * 2)]; + kern = kerns_heights[(k * 2) + 1]; +#ifdef DEBUG + if (k > 0) + fprintf(stderr, " entry %d: %d,%d\n", k, h, kern); +#endif + if (h > v) { + return kern; + } + } + return kern; +} + + +scaled +find_math_kern(internal_font_number l_f, integer l_c, + internal_font_number r_f, integer r_c, int cmd, scaled shift) +{ + scaled corr_height_top = 0, corr_height_bot = 0; + scaled krn_l = 0, krn_r = 0, krn = 0; + if ((!is_new_mathfont(l_f)) || (!is_new_mathfont(r_f)) + || (!char_exists(l_f, l_c)) || (!char_exists(r_f, r_c))) + return MATH_KERN_NOT_FOUND; + + if (cmd == sup_mark_cmd) { + corr_height_top = char_height(l_f, l_c); + corr_height_bot = -char_depth(r_f, r_c) + shift; /* bottom of superscript */ + krn_l = math_kern_at(l_f, l_c, top_right_kern, corr_height_top); + krn_r = math_kern_at(r_f, r_c, bottom_left_kern, corr_height_top); +#ifdef DEBUG + fprintf(stderr, "SUPER Top LR = %d,%d (shift %d)\n", krn_l, krn_r, + shift); +#endif + krn = (krn_l + krn_r); + krn_l = math_kern_at(l_f, l_c, top_right_kern, corr_height_bot); + krn_r = math_kern_at(r_f, r_c, bottom_left_kern, corr_height_bot); +#ifdef DEBUG + fprintf(stderr, "SUPER Bot LR = %d,%d\n", krn_l, krn_r); +#endif + if ((krn_l + krn_r) < krn) + krn = (krn_l + krn_r); + return (krn); + + } else if (cmd == sub_mark_cmd) { + corr_height_top = char_height(r_f, r_c) - shift; /* top of subscript */ + corr_height_bot = -char_depth(l_f, l_c); + krn_l = math_kern_at(l_f, l_c, bottom_right_kern, corr_height_top); + krn_r = math_kern_at(r_f, r_c, top_left_kern, corr_height_top); +#ifdef DEBUG + fprintf(stderr, "SUB Top LR = %d,%d\n", krn_l, krn_r); +#endif + krn = (krn_l + krn_r); + krn_l = math_kern_at(l_f, l_c, bottom_right_kern, corr_height_bot); + krn_r = math_kern_at(r_f, r_c, top_left_kern, corr_height_bot); +#ifdef DEBUG + fprintf(stderr, "SUB Bot LR = %d,%d\n", krn_l, krn_r); +#endif + if ((krn_l + krn_r) < krn) + krn = (krn_l + krn_r); + return (krn); + + } else { + tconfusion("find_math_kern"); + } + return 0; /* not reached */ +} + +/* just a small helper */ +pointer attach_hkern_to_new_hlist(pointer q, scaled delta2) +{ + pointer y; + pointer z = new_kern(delta2); + if (new_hlist(q) == null) { /* this is somewhat weird */ + new_hlist(q) = z; + } else { + y = new_hlist(q); + while (vlink(y) != null) + y = vlink(y); + vlink(y) = z; + } + return new_hlist(q); +} + + + /* -The purpose of |make_scripts(q,delta)| 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 appear to the right of the subscript by a given distance |delta|. +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. */ -void make_scripts(pointer q, scaled delta) + +void make_scripts(pointer q, pointer p, scaled it) { - pointer p, x, y, z; /* temporary registers for box construction */ + pointer x, y, z; /* temporary registers for box construction */ scaled shift_up, shift_down, clr; /* dimensions in the calculation */ - p = new_hlist(q); + scaled delta1, delta2; + delta1 = it; + delta2 = 0; + switch (type(nucleus(q))) { + case math_char_node: + case math_text_char_node: + if ((subscr(q) == null) && (delta1 != 0)) { + x = new_kern(delta1); + reset_attributes(x, node_attr(nucleus(q))); + vlink(p) = x; + delta1 = 0; + } + } + assign_new_hlist(q, p); if (is_char_node(p)) { shift_up = 0; shift_down = 0; @@ -3097,6 +3259,21 @@ void make_scripts(pointer q, scaled delta) if (shift_down < clr) shift_down = clr; shift_amount(x) = shift_down; + + /* now find and correct for horizontal shift */ + if (is_char_node(p) && subscr(q) != null + && type(subscr(q)) == math_char_node) { + fetch(subscr(q)); + if (char_exists(cur_f, cur_c)) { + delta2 = + find_math_kern(font(p), character(p), cur_f, cur_c, + sub_mark_cmd, shift_down); + if (delta2 != MATH_KERN_NOT_FOUND && delta2 != 0) { + p = attach_hkern_to_new_hlist(q, delta2); + } + } + } + } else { /* Construct a superscript box |x| */ /*The bottom of a superscript should never descend below the baseline plus @@ -3112,6 +3289,18 @@ void make_scripts(pointer q, scaled delta) if (subscr(q) == null) { shift_amount(x) = -shift_up; + /* now find and correct for horizontal shift */ + if (is_char_node(p) && type(supscr(q)) == math_char_node) { + fetch(supscr(q)); + if (char_exists(cur_f, cur_c)) { + clr = + find_math_kern(font(p), character(p), cur_f, cur_c, + sup_mark_cmd, shift_up); + if (clr != MATH_KERN_NOT_FOUND && clr != 0) { + p = attach_hkern_to_new_hlist(q, clr); + } + } + } } else { /* Construct a sub/superscript combination box |x|, with the superscript offset by |delta| */ @@ -3135,7 +3324,38 @@ void make_scripts(pointer q, scaled delta) shift_down = shift_down - clr; } } - shift_amount(x) = delta; /* superscript is |delta| to the right of the subscript */ + /* now find and correct for horizontal shift */ + if (is_char_node(p) && subscr(q) != null + && type(subscr(q)) == math_char_node) { + fetch(subscr(q)); + if (char_exists(cur_f, cur_c)) { + delta2 = + find_math_kern(font(p), character(p), cur_f, cur_c, + sub_mark_cmd, shift_down); + if (delta2 != MATH_KERN_NOT_FOUND && delta2 != 0) { + p = attach_hkern_to_new_hlist(q, delta2); + } + } + } + /* now the horizontal shift for the superscript. */ + /* 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) { + fetch(supscr(q)); + if (char_exists(cur_f, cur_c)) { + clr = + find_math_kern(font(p), character(p), cur_f, cur_c, + sup_mark_cmd, shift_up); + } + } + if (delta2 == MATH_KERN_NOT_FOUND) + delta2=0; + if (clr != MATH_KERN_NOT_FOUND) { + shift_amount(x) = clr + delta1 - delta2; + } else { + shift_amount(x) = delta1 - delta2; + } p = new_kern((shift_up - depth(x)) - (height(y) - shift_down)); reset_attributes(p, node_attr(q)); vlink(x) = p; @@ -3146,6 +3366,8 @@ void make_scripts(pointer q, scaled delta) shift_amount(x) = shift_down; } } + + if (new_hlist(q) == null) { new_hlist(q) = x; } else { @@ -3193,33 +3415,12 @@ small_number make_left_right(pointer q, integer style, scaled max_d, delimiter(q) = null; assign_new_hlist(q, tmp); if (subtype(q) == left_noad_side) - return open_noad; + return open_noad_type; else - return close_noad; + return close_noad_type; } -/* -The inter-element spacing in math formulas depends on a $8\times8$ table that -\TeX\ preloads as a 64-digit string. The elements of this string have the -following significance: -$$\vbox{\halign{#\hfil\cr -\.0 means no space;\cr -\.1 means a conditional thin space (\.{\\nonscript\\mskip\\thinmuskip});\cr -\.2 means a thin space (\.{\\mskip\\thinmuskip});\cr -\.3 means a conditional medium space - (\.{\\nonscript\\mskip\\medmuskip});\cr -\.4 means a conditional thick space - (\.{\\nonscript\\mskip\\thickmuskip});\cr -\.* means an impossible case.\cr}}$$ -This is all pretty cryptic, but {\sl The \TeX book\/} explains what is -supposed to happen, and the string makes it happen. -@:TeXbook}{\sl The \TeX book@> -*/ - -char math_spacing[] = - "0234000122*4000133**3**344*0400400*000000234000111*1111112341011"; - #define level_one 1 #define thin_mu_skip param_thin_mu_skip_code #define med_mu_skip param_med_mu_skip_code @@ -3329,113 +3530,82 @@ void initialize_math_spacing(void) } -pointer math_spacing_glue_old(int l_type, int r_type, int m_style) -{ - pointer y, z; - int x; - z = null; - switch (math_spacing[l_type * 8 + r_type - 9 * ord_noad]) { - case '0': - x = 0; - break; - case '1': - x = (m_style < script_style ? param_thin_mu_skip_code : 0); - break; - case '2': - x = param_thin_mu_skip_code; - break; - case '3': - x = (m_style < script_style ? param_med_mu_skip_code : 0); - break; - case '4': - x = (m_style < script_style ? param_thick_mu_skip_code : 0); - break; - default: - tconfusion("mlist4"); /* this can't happen mlist4 */ - x = -1; - break; - } - if (x != 0) { - y = math_glue(glue_par(x), cur_mu); - z = new_glue(y); - glue_ref_count(y) = null; - subtype(z) = x + 1; /* store a symbolic subtype */ - } - return z; -} - -#define both_types(A,B) ((A)*8+B) +#define both_types(A,B) ((A)*16+(B)) -pointer math_spacing_glue(int l_type, int r_type, int m_style) +pointer math_spacing_glue(int l_type, int r_type, int mstyle) { int x = -1; pointer z = null; + if (l_type == op_noad_type_limits || l_type == op_noad_type_no_limits) + l_type = op_noad_type_normal; + if (r_type == op_noad_type_limits || r_type == op_noad_type_no_limits) + r_type = op_noad_type_normal; switch (both_types(l_type, r_type)) { /* *INDENT-OFF* */ - case both_types(ord_noad, ord_noad ): x = get_math_param(math_param_ord_ord_spacing,m_style); break; - case both_types(ord_noad, op_noad ): x = get_math_param(math_param_ord_op_spacing,m_style); break; - case both_types(ord_noad, bin_noad ): x = get_math_param(math_param_ord_bin_spacing,m_style); break; - case both_types(ord_noad, rel_noad ): x = get_math_param(math_param_ord_rel_spacing,m_style); break; - case both_types(ord_noad, open_noad ): x = get_math_param(math_param_ord_open_spacing,m_style); break; - case both_types(ord_noad, close_noad): x = get_math_param(math_param_ord_close_spacing,m_style); break; - case both_types(ord_noad, punct_noad): x = get_math_param(math_param_ord_punct_spacing,m_style); break; - case both_types(ord_noad, inner_noad): x = get_math_param(math_param_ord_inner_spacing,m_style); break; - case both_types(op_noad, ord_noad ): x = get_math_param(math_param_op_ord_spacing,m_style); break; - case both_types(op_noad, op_noad ): x = get_math_param(math_param_op_op_spacing,m_style); break; - /*case both_types(op_noad, bin_noad ): x = get_math_param(math_param_op_bin_spacing,m_style); break;*/ - case both_types(op_noad, rel_noad ): x = get_math_param(math_param_op_rel_spacing,m_style); break; - case both_types(op_noad, open_noad ): x = get_math_param(math_param_op_open_spacing,m_style); break; - case both_types(op_noad, close_noad): x = get_math_param(math_param_op_close_spacing,m_style); break; - case both_types(op_noad, punct_noad): x = get_math_param(math_param_op_punct_spacing,m_style); break; - case both_types(op_noad, inner_noad): x = get_math_param(math_param_op_inner_spacing,m_style); break; - case both_types(bin_noad, ord_noad ): x = get_math_param(math_param_bin_ord_spacing,m_style); break; - case both_types(bin_noad, op_noad ): x = get_math_param(math_param_bin_op_spacing,m_style); break; - /*case both_types(bin_noad, bin_noad ): x = get_math_param(math_param_bin_bin_spacing,m_style); break;*/ - /*case both_types(bin_noad, rel_noad ): x = get_math_param(math_param_bin_rel_spacing,m_style); break;*/ - case both_types(bin_noad, open_noad ): x = get_math_param(math_param_bin_open_spacing,m_style); break; - /*case both_types(bin_noad, close_noad): x = get_math_param(math_param_bin_close_spacing,m_style); break;*/ - /*case both_types(bin_noad, punct_noad): x = get_math_param(math_param_bin_punct_spacing,m_style); break;*/ - case both_types(bin_noad, inner_noad): x = get_math_param(math_param_bin_inner_spacing,m_style); break; - case both_types(rel_noad, ord_noad ): x = get_math_param(math_param_rel_ord_spacing,m_style); break; - case both_types(rel_noad, op_noad ): x = get_math_param(math_param_rel_op_spacing,m_style); break; - /*case both_types(rel_noad, bin_noad ): x = get_math_param(math_param_rel_bin_spacing,m_style); break;*/ - case both_types(rel_noad, rel_noad ): x = get_math_param(math_param_rel_rel_spacing,m_style); break; - case both_types(rel_noad, open_noad ): x = get_math_param(math_param_rel_open_spacing,m_style); break; - case both_types(rel_noad, close_noad): x = get_math_param(math_param_rel_close_spacing,m_style); break; - case both_types(rel_noad, punct_noad): x = get_math_param(math_param_rel_punct_spacing,m_style); break; - case both_types(rel_noad, inner_noad): x = get_math_param(math_param_rel_inner_spacing,m_style); break; - case both_types(open_noad, ord_noad ): x = get_math_param(math_param_open_ord_spacing,m_style); break; - case both_types(open_noad, op_noad ): x = get_math_param(math_param_open_op_spacing,m_style); break; - /*case both_types(open_noad, bin_noad ): x = get_math_param(math_param_open_bin_spacing,m_style); break;*/ - case both_types(open_noad, rel_noad ): x = get_math_param(math_param_open_rel_spacing,m_style); break; - case both_types(open_noad, open_noad ): x = get_math_param(math_param_open_open_spacing,m_style); break; - case both_types(open_noad, close_noad): x = get_math_param(math_param_open_close_spacing,m_style); break; - case both_types(open_noad, punct_noad): x = get_math_param(math_param_open_punct_spacing,m_style); break; - case both_types(open_noad, inner_noad): x = get_math_param(math_param_open_inner_spacing,m_style); break; - case both_types(close_noad,ord_noad ): x = get_math_param(math_param_close_ord_spacing,m_style); break; - case both_types(close_noad,op_noad ): x = get_math_param(math_param_close_op_spacing,m_style); break; - case both_types(close_noad,bin_noad ): x = get_math_param(math_param_close_bin_spacing,m_style); break; - case both_types(close_noad,rel_noad ): x = get_math_param(math_param_close_rel_spacing,m_style); break; - case both_types(close_noad,open_noad ): x = get_math_param(math_param_close_open_spacing,m_style); break; - case both_types(close_noad,close_noad): x = get_math_param(math_param_close_close_spacing,m_style); break; - case both_types(close_noad,punct_noad): x = get_math_param(math_param_close_punct_spacing,m_style); break; - case both_types(close_noad,inner_noad): x = get_math_param(math_param_close_inner_spacing,m_style); break; - case both_types(punct_noad,ord_noad ): x = get_math_param(math_param_punct_ord_spacing,m_style); break; - case both_types(punct_noad,op_noad ): x = get_math_param(math_param_punct_op_spacing,m_style); break; - /*case both_types(punct_noad,bin_noad ): x = get_math_param(math_param_punct_bin_spacing,m_style); break;*/ - case both_types(punct_noad,rel_noad ): x = get_math_param(math_param_punct_rel_spacing,m_style); break; - case both_types(punct_noad,open_noad ): x = get_math_param(math_param_punct_open_spacing,m_style); break; - case both_types(punct_noad,close_noad): x = get_math_param(math_param_punct_close_spacing,m_style); break; - case both_types(punct_noad,punct_noad): x = get_math_param(math_param_punct_punct_spacing,m_style); break; - case both_types(punct_noad,inner_noad): x = get_math_param(math_param_punct_inner_spacing,m_style); break; - case both_types(inner_noad,ord_noad ): x = get_math_param(math_param_inner_ord_spacing,m_style); break; - case both_types(inner_noad,op_noad ): x = get_math_param(math_param_inner_op_spacing,m_style); break; - case both_types(inner_noad,bin_noad ): x = get_math_param(math_param_inner_bin_spacing,m_style); break; - case both_types(inner_noad,rel_noad ): x = get_math_param(math_param_inner_rel_spacing,m_style); break; - case both_types(inner_noad,open_noad ): x = get_math_param(math_param_inner_open_spacing,m_style); break; - case both_types(inner_noad,close_noad): x = get_math_param(math_param_inner_close_spacing,m_style); break; - case both_types(inner_noad,punct_noad): x = get_math_param(math_param_inner_punct_spacing,m_style); break; - case both_types(inner_noad,inner_noad): x = get_math_param(math_param_inner_inner_spacing,m_style); break; + case both_types(ord_noad_type, ord_noad_type ): x = get_math_param(math_param_ord_ord_spacing,mstyle); break; + case both_types(ord_noad_type, op_noad_type_normal ): x = get_math_param(math_param_ord_op_spacing,mstyle); break; + case both_types(ord_noad_type, bin_noad_type ): x = get_math_param(math_param_ord_bin_spacing,mstyle); break; + case both_types(ord_noad_type, rel_noad_type ): x = get_math_param(math_param_ord_rel_spacing,mstyle); break; + case both_types(ord_noad_type, open_noad_type ): x = get_math_param(math_param_ord_open_spacing,mstyle); break; + case both_types(ord_noad_type, close_noad_type): x = get_math_param(math_param_ord_close_spacing,mstyle); break; + case both_types(ord_noad_type, punct_noad_type): x = get_math_param(math_param_ord_punct_spacing,mstyle); break; + 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;*/ + 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; + case both_types(op_noad_type_normal, punct_noad_type): x = get_math_param(math_param_op_punct_spacing,mstyle); break; + 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;*/ + 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;*/ + 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;*/ + 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; + case both_types(rel_noad_type, punct_noad_type): x = get_math_param(math_param_rel_punct_spacing,mstyle); break; + 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;*/ + 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; + case both_types(open_noad_type, punct_noad_type): x = get_math_param(math_param_open_punct_spacing,mstyle); break; + case both_types(open_noad_type, inner_noad_type): x = get_math_param(math_param_open_inner_spacing,mstyle); break; + case both_types(close_noad_type,ord_noad_type ): x = get_math_param(math_param_close_ord_spacing,mstyle); break; + case both_types(close_noad_type,op_noad_type_normal ): x = get_math_param(math_param_close_op_spacing,mstyle); break; + case both_types(close_noad_type,bin_noad_type ): x = get_math_param(math_param_close_bin_spacing,mstyle); break; + case both_types(close_noad_type,rel_noad_type ): x = get_math_param(math_param_close_rel_spacing,mstyle); break; + case both_types(close_noad_type,open_noad_type ): x = get_math_param(math_param_close_open_spacing,mstyle); break; + case both_types(close_noad_type,close_noad_type): x = get_math_param(math_param_close_close_spacing,mstyle); break; + case both_types(close_noad_type,punct_noad_type): x = get_math_param(math_param_close_punct_spacing,mstyle); break; + 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;*/ + 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; + case both_types(punct_noad_type,punct_noad_type): x = get_math_param(math_param_punct_punct_spacing,mstyle); break; + case both_types(punct_noad_type,inner_noad_type): x = get_math_param(math_param_punct_inner_spacing,mstyle); break; + case both_types(inner_noad_type,ord_noad_type ): x = get_math_param(math_param_inner_ord_spacing,mstyle); break; + case both_types(inner_noad_type,op_noad_type_normal ): x = get_math_param(math_param_inner_op_spacing,mstyle); break; + case both_types(inner_noad_type,bin_noad_type ): x = get_math_param(math_param_inner_bin_spacing,mstyle); break; + case both_types(inner_noad_type,rel_noad_type ): x = get_math_param(math_param_inner_rel_spacing,mstyle); break; + case both_types(inner_noad_type,open_noad_type ): x = get_math_param(math_param_inner_open_spacing,mstyle); break; + case both_types(inner_noad_type,close_noad_type): x = get_math_param(math_param_inner_close_spacing,mstyle); break; + case both_types(inner_noad_type,punct_noad_type): x = get_math_param(math_param_inner_punct_spacing,mstyle); break; + case both_types(inner_noad_type,inner_noad_type): x = get_math_param(math_param_inner_inner_spacing,mstyle); break; /* *INDENT-ON* */ } if (x < 0) { @@ -3474,18 +3644,19 @@ void mlist_to_hlist(void) 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 */ 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 */ scaled max_hl, max_d; /* maximum height and depth of the list translated so far */ - scaled delta; /* offset between subscript and superscript */ + 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 */ q = mlist; r = null; - r_type = op_noad; - r_subtype = 0; + r_type = simple_noad; + r_subtype = op_noad_type_normal; max_hl = 0; max_d = 0; x = null; @@ -3501,50 +3672,76 @@ void mlist_to_hlist(void) RESWITCH: delta = 0; switch (type(q)) { - case bin_noad: - switch (r_type) { - case bin_noad: - case op_noad: - case rel_noad: - case open_noad: - case punct_noad: - type(q) = ord_noad; - goto RESWITCH; + case simple_noad: + switch (subtype(q)) { + case bin_noad_type: + switch (r_type) { + case simple_noad: + switch (r_subtype) { + case bin_noad_type: + case op_noad_type_normal: + case op_noad_type_limits: + case op_noad_type_no_limits: + case rel_noad_type: + case open_noad_type: + case punct_noad_type: + subtype(q) = ord_noad_type; + goto RESWITCH; + break; + } + break; + case fence_noad: + if (r_subtype == left_noad_side) { + subtype(q) = ord_noad_type; + goto RESWITCH; + } + break; + } + break; + case over_noad_type: + make_over(q); break; - case fence_noad: - if (r_subtype == left_noad_side) { - type(q) = ord_noad; - goto RESWITCH; + case under_noad_type: + make_under(q); + break; + case vcenter_noad_type: + make_vcenter(q); + break; + case rel_noad_type: + case close_noad_type: + case punct_noad_type: + if (r_type == simple_noad && r_subtype == bin_noad_type) { + type(r) = simple_noad; + subtype(r) = ord_noad_type; } + break; + case op_noad_type_normal: + case op_noad_type_limits: + case op_noad_type_no_limits: + delta = make_op(q); + if (subtype(q) == op_noad_type_limits) + goto CHECK_DIMENSIONS; + break; + case ord_noad_type: + make_ord(q); + break; + case open_noad_type: + case inner_noad_type: + break; } break; - case rel_noad: - case close_noad: - case punct_noad: - if (r_type == bin_noad) - type(r) = ord_noad; - break; case fence_noad: if (subtype(q) != left_noad_side) - if (r_type == bin_noad) - type(r) = ord_noad; + if (r_type == simple_noad && r_subtype == bin_noad_type) { + type(r) = simple_noad; + subtype(r) = ord_noad_type; + } goto DONE_WITH_NOAD; break; case fraction_noad: make_fraction(q); goto CHECK_DIMENSIONS; break; - case op_noad: - delta = make_op(q); - if (subtype(q) == limits) - goto CHECK_DIMENSIONS; - break; - case ord_noad: - make_ord(q); - break; - case open_noad: - case inner_noad: - break; case radical_noad: if (subtype(q) == 4) make_under_delimiter(q); @@ -3557,18 +3754,9 @@ void mlist_to_hlist(void) else make_radical(q); break; - case over_noad: - make_over(q); - break; - case under_noad: - make_under(q); - break; case accent_noad: make_math_accent(q); break; - case vcenter_noad: - make_vcenter(q); - break; case style_node: cur_style = subtype(q); setup_cur_size_and_mu(); @@ -3677,7 +3865,7 @@ void mlist_to_hlist(void) 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) && (delta != 0)) { + if ((subscr(q) == null) && (supscr(q) == null) && (delta != 0)) { x = new_kern(delta); reset_attributes(x, node_attr(nucleus(q))); vlink(p) = x; @@ -3703,10 +3891,11 @@ void mlist_to_hlist(void) default: tconfusion("mlist2"); /* this can't happen mlist2 */ } - assign_new_hlist(q, p); - if ((subscr(q) == null) && (supscr(q) == null)) + if ((subscr(q) == null) && (supscr(q) == null)) { + assign_new_hlist(q, p); goto CHECK_DIMENSIONS; - make_scripts(q, delta); + } + make_scripts(q, p, delta); /* top, bottom */ CHECK_DIMENSIONS: z = hpack(new_hlist(q), 0, additional); if (height(z) > max_hl) @@ -3718,6 +3907,7 @@ void mlist_to_hlist(void) DONE_WITH_NOAD: r = q; r_type = type(r); + r_subtype = subtype(r); if (r_type == fence_noad) { r_subtype = left_noad_side; cur_style = style; @@ -3726,8 +3916,10 @@ void mlist_to_hlist(void) DONE_WITH_NODE: q = vlink(q); } - if (r_type == bin_noad) - type(r) = ord_noad; + if (r_type == simple_noad && r_subtype == bin_noad_type) { + type(r) = simple_noad; + subtype(r) = ord_noad_type; + } /* Make a second pass over the mlist, removing all noads and inserting the proper spacing and penalties */ @@ -3741,6 +3933,7 @@ void mlist_to_hlist(void) vlink(p) = null; q = mlist; r_type = 0; + r_subtype = 0; cur_style = style; setup_cur_size_and_mu(); NEXT_NODE: @@ -3752,30 +3945,26 @@ void mlist_to_hlist(void) inner_noad|), and set |pen| to the associated penalty */ /* Just before doing the big |case| switch in the second pass, the program sets up default values so that most of the branches are short. */ - t = ord_noad; + t = simple_noad; + t_subtype = ord_noad_type; s = noad_size; pen = inf_penalty; switch (type(q)) { - case op_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: - t = type(q); - break; - case bin_noad: - t = bin_noad; - pen = bin_op_penalty; - break; - case rel_noad: - t = rel_noad; - pen = rel_penalty; - break; - case ord_noad: - case vcenter_noad: - case over_noad: - case under_noad: - break; + case simple_noad: + t_subtype = subtype(q); + switch (t_subtype) { + case bin_noad_type: + pen = bin_op_penalty; + break; + case rel_noad_type: + pen = rel_penalty; + break; + case vcenter_noad_type: + case over_noad_type: + case under_noad_type: + t_subtype = ord_noad_type; + break; + } case radical_noad: s = radical_noad_size; break; @@ -3783,11 +3972,12 @@ void mlist_to_hlist(void) s = accent_noad_size; break; case fraction_noad: - t = inner_noad; + t = simple_noad; + t_subtype = inner_noad_type; s = fraction_noad_size; break; case fence_noad: - t = make_left_right(q, style, max_d, max_hl); + t_subtype = make_left_right(q, style, max_d, max_hl); break; case style_node: /* Change the current style and |goto delete_q| */ @@ -3816,7 +4006,7 @@ void mlist_to_hlist(void) } /* Append inter-element spacing based on |r_type| and |t| */ if (r_type > 0) { /* not the first noad */ - z = math_spacing_glue(r_type, t, cur_style); + z = math_spacing_glue(r_subtype, t_subtype, cur_style); if (z != null) { reset_attributes(z, node_attr(p)); vlink(p) = z; @@ -3837,16 +4027,21 @@ void mlist_to_hlist(void) } if (penalties && vlink(q) != null && pen < inf_penalty) { r_type = type(vlink(q)); - if (r_type != penalty_node && r_type != rel_noad) { + r_subtype = subtype(vlink(q)); + if (r_type != penalty_node + && (r_type != simple_noad || r_subtype != rel_noad_type)) { z = new_penalty(pen); reset_attributes(z, node_attr(q)); vlink(p) = z; p = z; } } - if (type(q) == fence_noad && subtype(q) == right_noad_side) - t = open_noad; + if (type(q) == fence_noad && subtype(q) == right_noad_side) { + t = simple_noad; + t_subtype = open_noad_type; + } r_type = t; + r_subtype = t_subtype; DELETE_Q: r = q; q = vlink(q); diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c index 2711f53d25e..f9341eabe14 100644 --- a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c +++ b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c @@ -22,7 +22,7 @@ #include "nodes.h" static const char _svn_version[] = - "$Id: postlinebreak.c 1694 2008-12-28 20:53:16Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/postlinebreak.c $"; + "$Id: postlinebreak.c 2294 2009-04-15 19:40:11Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/postlinebreak.c $"; /* 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 @@ -216,42 +216,53 @@ void ext_post_line_break(boolean d, halfword a = alink(r); halfword v = vlink(r); assert(a != null); - if (v == null) { /* nested disc, let's unfold */ - fprintf(stderr, "Nested disc [%d]<-[%d]->null\n", (int) a, - (int) r); - do { - halfword d; - while (alink(a) != null) - a = alink(a); - assert(type(a) == nesting_node); - assert(subtype(a) == no_break_head(0)); /* No_break */ - d = a - subtype(a); /* MAGIC subtype is offset of nesting with disc */ - assert(type(d) == disc_node); - v = vlink(d); - a = alink(d); - fprintf(stderr, "Up to disc [%d]<-[%d]->[%d] & link [%d]\n", - (int) a, (int) d, (int) v, (int) vlink_no_break(d)); - assert(a != null); - couple_nodes(a, vlink_no_break(d)); - vlink_no_break(d) = null; - tlink_no_break(d) = null; - flush_node(d); - } while (v == null); - couple_nodes(r, v); - fprintf(stderr, "Close list [%d]<->[%d] a=[%d]\n", (int) r, - (int) v, (int) alink(r)); - a = alink(r); - } - if (vlink_no_break(r) != null) { - flush_node_list(vlink_no_break(r)); - vlink_no_break(r) = null; - tlink_no_break(r) = null; - } - if (vlink_pre_break(r) != null) { - couple_nodes(a, vlink_pre_break(r)); - couple_nodes(tlink_pre_break(r), r); - vlink_pre_break(r) = null; - tlink_pre_break(r) = null; + assert(v != null); + switch (subtype(r)) { + case select_disc: + if (vlink_pre_break(r) != null) { + flush_node_list(vlink_pre_break(r)); + vlink_pre_break(r) = null; + tlink_pre_break(r) = null; + } + if (vlink_no_break(r) != null) { + couple_nodes(a, vlink_no_break(r)); + couple_nodes(tlink_no_break(r), r); + vlink_no_break(r) = null; + tlink_no_break(r) = null; + } + + assert(type(a)==disc_node && subtype(a)==init_disc); + flush_node_list(vlink_no_break(a)); + vlink_no_break(a) = null; + tlink_no_break(a) = null; + flush_node_list(vlink_pre_break(a)); + vlink_pre_break(a) = null; + tlink_pre_break(a) = null; + flush_node_list(vlink_post_break(a)); + vlink_post_break(a) = null; + tlink_post_break(a) = null; + + break; + case init_disc: + assert(type(v)==disc_node && subtype(v)==select_disc); + subtype(v) = syllable_disc; /* not special any more */ + flush_node_list(vlink_no_break(v)); + vlink_no_break(v) = vlink_post_break(r); + tlink_no_break(v) = tlink_post_break(r); + vlink_post_break(r) = null; + tlink_post_break(r) = null; + default: + if (vlink_no_break(r) != null) { + flush_node_list(vlink_no_break(r)); + vlink_no_break(r) = null; + tlink_no_break(r) = null; + } + if (vlink_pre_break(r) != null) { + couple_nodes(a, vlink_pre_break(r)); + couple_nodes(tlink_pre_break(r), r); + vlink_pre_break(r) = null; + tlink_pre_break(r) = null; + } } if (vlink_post_break(r) != null) { couple_nodes(r, vlink_post_break(r)); diff --git a/Build/source/texk/web2c/luatexdir/tex/primitive.c b/Build/source/texk/web2c/luatexdir/tex/primitive.c index 9f2f4e84d36..15f44646745 100644 --- a/Build/source/texk/web2c/luatexdir/tex/primitive.c +++ b/Build/source/texk/web2c/luatexdir/tex/primitive.c @@ -25,7 +25,7 @@ #include "tokens.h" static const char _svn_version[] = - "$Id: primitive.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/primitive.c $"; + "$Id: primitive.c 2297 2009-04-15 20:16:38Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/primitive.c $"; /* as usual, the file starts with a bunch of #defines that mimic pascal @ds */ @@ -341,7 +341,7 @@ primitive(str_number ss, quarterword c, halfword o, halfword off, s = ss; } char *thes = makecstring(s); - if (true || cmd_origin == tex_command || cmd_origin == core_command) { + if (cmd_origin == tex_command || cmd_origin == core_command) { primitive_def(thes, strlen(thes), c, o); } prim_val = prim_lookup(s); @@ -542,15 +542,6 @@ void print_cmd_chr(quarterword cmd, halfword chr_code) tprint_esc("unless"); prim_cmd_chr(cmd, (chr_code % unless_code)); break; - case math_comp_cmd: - print_math_comp(chr_code); - break; - case limit_switch_cmd: - print_limit_switch(chr_code); - break; - case math_style_cmd: - print_style(chr_code); - break; case char_given_cmd: tprint_esc("char"); print_hex(chr_code); @@ -567,12 +558,6 @@ void print_cmd_chr(quarterword cmd, halfword chr_code) tprint_esc("Umathchar"); show_mathcode_value(mathchar_from_integer(chr_code, xetex_mathcode)); break; - case def_family_cmd: - print_size(chr_code); - break; - case set_math_param_cmd: - print_math_param(chr_code); - break; case set_font_cmd: tprint("select font "); tprint(font_name(chr_code)); diff --git a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c b/Build/source/texk/web2c/luatexdir/tex/texdeffont.c index 5be7d084781..003b3528d7e 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c +++ b/Build/source/texk/web2c/luatexdir/tex/texdeffont.c @@ -25,7 +25,7 @@ #include "commands.h" static const char _svn_version[] = - "$Id: texdeffont.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/texdeffont.c $"; + "$Id: texdeffont.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/texdeffont.c $"; #define text(a) hash[(a)].rh /* string number for control sequence name */ #define null_cs 1 /* equivalent of \.{\\csname\\endcsname} */ @@ -157,7 +157,8 @@ void tex_def_font(small_number a) char err[256]; char *errhelp[] = { "The magnification ratio must be between 1 and 32768.", - NULL }; + NULL + }; snprintf(err, 255, "Illegal magnification has been changed to 1000 (%d)", (int) cur_val); diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.c b/Build/source/texk/web2c/luatexdir/tex/texnodes.c index 8dcdec2e1ad..bef21431ecd 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.c +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.c @@ -25,10 +25,10 @@ #include "tokens.h" #undef name -#define nDEBUG +#define noDEBUG static const char _svn_version[] = - "$Id: texnodes.c 2029 2009-03-14 19:10:25Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/texnodes.c $"; + "$Id: texnodes.c 2273 2009-04-13 09:52:04Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/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)) @@ -51,13 +51,6 @@ typedef enum { } pdf_destination_types; -typedef enum { - set_origin = 0, - direct_page, - direct_always, -} ctm_transform_modes; - - #define obj_aux(A) obj_tab[(A)].int4 #define obj_data_ptr obj_aux #define obj_obj_data(A) pdf_mem[obj_data_ptr((A)) + 0] @@ -82,7 +75,7 @@ halfword rover = 0; halfword free_chain[MAX_CHAIN_SIZE] = { null }; -static int my_prealloc = 0; +static integer my_prealloc = 0; int fix_node_lists = 1; @@ -235,20 +228,20 @@ node_info node_data[] = { {unset_node, box_node_size, node_fields_unset, "unset"}, {style_node, style_node_size, node_fields_style, "style"}, {choice_node, style_node_size, node_fields_choice, "choice"}, - {ord_noad, noad_size, node_fields_ord, "ord"}, - {op_noad, noad_size, node_fields_op, "op"}, - {bin_noad, noad_size, node_fields_bin, "bin"}, - {rel_noad, noad_size, node_fields_rel, "rel"}, - {open_noad, noad_size, node_fields_open, "open"}, - {close_noad, noad_size, node_fields_close, "close"}, - {punct_noad, noad_size, node_fields_punct, "punct"}, - {inner_noad, noad_size, node_fields_inner, "inner"}, + {simple_noad, noad_size, node_fields_ord, "noad"}, + {old_op_noad, noad_size, node_fields_op, "op"}, + {old_bin_noad, noad_size, node_fields_bin, "bin"}, + {old_rel_noad, noad_size, node_fields_rel, "rel"}, + {old_open_noad, noad_size, node_fields_open, "open"}, + {old_close_noad, noad_size, node_fields_close, "close"}, + {old_punct_noad, noad_size, node_fields_punct, "punct"}, + {old_inner_noad, noad_size, node_fields_inner, "inner"}, {radical_noad, radical_noad_size, node_fields_radical, "radical"}, {fraction_noad, fraction_noad_size, node_fields_fraction, "fraction"}, - {under_noad, noad_size, node_fields_under, "under"}, - {over_noad, noad_size, node_fields_over, "over"}, + {old_under_noad, noad_size, node_fields_under, "under"}, + {old_over_noad, noad_size, node_fields_over, "over"}, {accent_noad, accent_noad_size, node_fields_accent, "accent"}, - {vcenter_noad, noad_size, node_fields_vcenter, "vcenter"}, + {old_vcenter_noad, noad_size, node_fields_vcenter, "vcenter"}, {fence_noad, fence_noad_size, node_fields_fence, "fence"}, {math_char_node, math_kernel_node_size, node_fields_math_char, "math_char"}, {sub_box_node, math_kernel_node_size, node_fields_sub_box, "sub_box"}, @@ -611,17 +604,7 @@ halfword copy_node(const halfword p) s = copy_node_list(script_script_mlist(p)); script_script_mlist(r) = s; break; - case ord_noad: - case op_noad: - case bin_noad: - case rel_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: - case over_noad: - case under_noad: - case vcenter_noad: + case simple_noad: case radical_noad: case accent_noad: s = copy_node_list(nucleus(p)); @@ -681,7 +664,7 @@ halfword copy_node(const halfword p) add_token_ref(write_tokens(p)); break; case pdf_literal_node: - add_token_ref(pdf_literal_data(p)); + copy_pdf_literal(r,p); break; case pdf_colorstack_node: if (pdf_colorstack_cmd(p) <= colorstack_data) @@ -736,6 +719,10 @@ halfword copy_node(const halfword p) } break; } +#ifdef DEBUG + fprintf(stderr, "Alloc-ing %s node %d (copy of %d)\n", + get_node_name(type(r), subtype(r)), (int) r, (int) p); +#endif return r; } @@ -963,7 +950,7 @@ void flush_node(halfword p) delete_token_ref(write_tokens(p)); break; case pdf_literal_node: - delete_token_ref(pdf_literal_data(p)); + free_pdf_literal(p); break; case pdf_colorstack_node: if (pdf_colorstack_cmd(p) <= colorstack_data) @@ -1067,17 +1054,7 @@ void flush_node(halfword p) flush_node_list(script_mlist(p)); flush_node_list(script_script_mlist(p)); break; - case ord_noad: - case op_noad: - case bin_noad: - case rel_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: - case over_noad: - case under_noad: - case vcenter_noad: + case simple_noad: case radical_noad: case accent_noad: flush_node_list(nucleus(p)); @@ -1205,7 +1182,8 @@ void check_node(halfword p) check_token_ref(write_tokens(p)); break; case pdf_literal_node: - check_token_ref(pdf_literal_data(p)); + if (pdf_literal_type(p)==normal) + check_token_ref(pdf_literal_data(p)); break; case pdf_colorstack_node: if (pdf_colorstack_cmd(p) <= colorstack_data) @@ -1306,17 +1284,7 @@ void check_node(halfword p) dorangetest(p, left_delimiter(p), var_mem_max); dorangetest(p, right_delimiter(p), var_mem_max); break; - case ord_noad: - case op_noad: - case bin_noad: - case rel_noad: - case open_noad: - case close_noad: - case punct_noad: - case inner_noad: - case over_noad: - case under_noad: - case vcenter_noad: + case simple_noad: dorangetest(p, nucleus(p), var_mem_max); dorangetest(p, subscr(p), var_mem_max); dorangetest(p, supscr(p), var_mem_max); @@ -1665,7 +1633,7 @@ void dump_node_mem(void) void undump_node_mem(void) { - int x; + integer x; undump_int(x); undump_int(rover); var_mem_max = (x < 100000 ? 100000 : x); @@ -1988,7 +1956,7 @@ void update_attribute_cache(void) p = attr_list_cache; for (i = 0; i <= max_used_attr; i++) { register int v = get_attribute(i); - if (v >= 0) { + if (v > UNUSED_ATTRIBUTE) { register halfword r = new_attribute_node(i, v); vlink(p) = r; p = r; @@ -2011,6 +1979,9 @@ 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", node_attr(b), b, attr_list_ref(attr_list_cache)) ; +#endif } } @@ -2019,6 +1990,9 @@ 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, attr_list_ref(b)) ; +#endif if (attr_list_ref(b) == 0) { if (b == attr_list_cache) attr_list_cache = cache_disabled; @@ -2132,12 +2106,12 @@ int unset_attribute(halfword n, int i, int val) return null; p = node_attr(n); if (p == null) - return -1; + return UNUSED_ATTRIBUTE; assert(vlink(p) != null); while (vlink(p) != null) { t = attribute_id(vlink(p)); if (t > i) - return -1; + return UNUSED_ATTRIBUTE; if (t == i) { p = vlink(p); break; @@ -2146,7 +2120,7 @@ int unset_attribute(halfword n, int i, int val) p = vlink(p); } if (attribute_id(p) != i) - return -1; + return UNUSED_ATTRIBUTE; /* if we are still here, the attribute exists */ p = node_attr(n); if (attr_list_ref(p) != 1) { @@ -2165,8 +2139,8 @@ int unset_attribute(halfword n, int i, int val) while (j-- > 0) p = vlink(p); t = attribute_value(p); - if (val == -1 || t == val) { - attribute_value(p) = -1; + if (val == UNUSED_ATTRIBUTE || t == val) { + attribute_value(p) = UNUSED_ATTRIBUTE; } return t; } @@ -2175,23 +2149,23 @@ int has_attribute(halfword n, int i, int val) { register halfword p; if (!nodetype_has_attributes(type(n))) - return -1; + return UNUSED_ATTRIBUTE; p = node_attr(n); if (p == null || vlink(p) == null) - return -1; + return UNUSED_ATTRIBUTE; p = vlink(p); while (p != null) { if (attribute_id(p) == i) { int ret = attribute_value(p); - if (val == -1 || val == ret) + if (val == UNUSED_ATTRIBUTE || val == ret) return ret; - return -1; + return UNUSED_ATTRIBUTE; } else if (attribute_id(p) > i) { - return -1; + return UNUSED_ATTRIBUTE; } p = vlink(p); } - return -1; + return UNUSED_ATTRIBUTE; } void print_short_node_contents(halfword p) @@ -2324,21 +2298,7 @@ void show_whatsit_node(integer p) decr(pool_ptr); break; case pdf_literal_node: - tprint_esc("pdfliteral"); - switch (pdf_literal_mode(p)) { - case set_origin: - break; - case direct_page: - tprint(" page"); - break; - case direct_always: - tprint(" direct"); - break; - default: - tconfusion("literal2"); - break; - } - print_mark(pdf_literal_data(p)); + show_pdf_literal(p); break; case pdf_colorstack_node: tprint_esc("pdfcolorstack "); diff --git a/Build/source/texk/web2c/luatexdir/tex/texpdf.c b/Build/source/texk/web2c/luatexdir/tex/texpdf.c index c539bbae968..46bed8de505 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texpdf.c +++ b/Build/source/texk/web2c/luatexdir/tex/texpdf.c @@ -22,7 +22,7 @@ #include <ctype.h> static const char _svn_version[] = - "$Id: texpdf.c 1436 2008-07-17 09:27:08Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/texpdf.c $"; + "$Id: texpdf.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/texpdf.c $"; #define number_chars 1114112 #define string_offset 2097152 @@ -35,17 +35,6 @@ static const char _svn_version[] = #define pdf_quick_out(a) pdf_buf[pdf_ptr++] = a -/* make sure that there are at least |n| bytes free in PDF buffer */ - -#define pdf_room(a) do { \ - if ((pdf_os_mode) && ((a) + pdf_ptr > pdf_buf_size)) \ - pdf_os_get_os_buf(a); \ - else if ((!pdf_os_mode) && ((a) > pdf_buf_size) ) \ - overflow(maketexstring("PDF output buffer"), pdf_op_buf_size); \ - else if ((!pdf_os_mode) && ((a) + pdf_ptr > pdf_buf_size)) \ - pdf_flush(); \ - } while (0) - /* do the same as |pdf_quick_out| and flush the PDF buffer if necessary */ #define pdf_out(a) do { \ diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.c b/Build/source/texk/web2c/luatexdir/tex/textoken.c index 1cfbd56b291..216fb1c7381 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textoken.c +++ b/Build/source/texk/web2c/luatexdir/tex/textoken.c @@ -24,7 +24,7 @@ #include "commands.h" static const char _svn_version[] = - "$Id: textoken.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/tex/textoken.c $"; + "$Id: textoken.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/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 */ @@ -216,6 +216,7 @@ boolean scan_keyword(char *s) pointer p; /* tail of the backup list */ pointer q; /* new node being added to the token list via |store_new_token| */ 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 { @@ -224,6 +225,7 @@ boolean scan_keyword(char *s) if ((cur_cs == 0) && ((cur_chr == *s) || (cur_chr == *s - 'a' + 'A'))) { return true; } else { + cur_cs = save_cur_cs; back_input(); return false; } @@ -247,6 +249,7 @@ boolean scan_keyword(char *s) } else { back_input(); } + cur_cs = save_cur_cs; return false; } } @@ -503,7 +506,7 @@ void check_outer_validity(void) } snprintf(errmsg, 255, "Incomplete %s; all text was ignored after line %d", - cmd_chr_to_string(if_test_cmd, cur_if), skip_line); + 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| */ @@ -1158,7 +1161,7 @@ void get_token_lua(void) { register int callback_id; callback_id = callback_defined(token_filter_callback); - if (callback_id != 0) { + 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 */ diff --git a/Build/source/texk/web2c/luatexdir/texmath.h b/Build/source/texk/web2c/luatexdir/texmath.h index fb0ae4a679e..233904cae8c 100644 --- a/Build/source/texk/web2c/luatexdir/texmath.h +++ b/Build/source/texk/web2c/luatexdir/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 1893 2009-02-23 11:30:05Z taco $ */ +/* $Id: texmath.h 2280 2009-04-14 09:49:01Z taco $ */ #ifndef TEXMATH_H # define TEXMATH_H 1 @@ -28,10 +28,6 @@ extern pointer new_noad(void); extern void show_math_node(halfword); -extern void print_math_comp(halfword); -extern void print_limit_switch(halfword); -extern void print_style(halfword); -extern void print_size(halfword); extern void flush_math(void); extern void math_left_brace(void); extern void finish_display_alignment(halfword, halfword, memory_word); @@ -39,12 +35,25 @@ extern halfword new_sub_box(halfword); # define math_reset(p) do { if (p!=null) flush_node(p); p = null; } while (0) -# define scripts_allowed(A) ((type((A))>=ord_noad)&&(type((A))<fence_noad)) +# define scripts_allowed(A) ((type((A))>=simple_noad)&&(type((A))<fence_noad)) # define default_code 010000000000 /* denotes |default_rule_thickness| */ -# define limits 1 /* |subtype| of |op_noad| whose scripts are to be above, below */ -# define no_limits 2 /* |subtype| of |op_noad| whose scripts are to be normal */ +typedef enum { + ord_noad_type = 0, + op_noad_type_normal, + op_noad_type_limits, + op_noad_type_no_limits, + bin_noad_type, + rel_noad_type, + open_noad_type, + close_noad_type, + punct_noad_type, + inner_noad_type, + under_noad_type, + over_noad_type, + vcenter_noad_type, +} noad_types; extern void initialize_math(void); extern void initialize_math_spacing(void); @@ -112,9 +121,13 @@ extern const char *math_style_names[]; # define sup_style(A) 2*((A)/4)+script_style+((A)%2) /* smaller */ # define num_style(A) (A)+2-2*((A)/6) /* smaller unless already script-script */ # 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); + # define text_size 0 # define script_size 1 # define script_script_size 2 @@ -122,6 +135,12 @@ void mlist_to_hlist(void); # define math_direction int_par(param_math_direction_code) # define dir_math_save cur_list.math_field +# define m_style cur_list.math_style_field +# define init_math_fields() do { \ + dir_math_save=false; \ + m_style=-1; \ + } while (0) + # define null_font 0 # define min_quarterword 0 @@ -241,9 +260,10 @@ typedef enum { math_param_last } math_parameters; +extern const char *math_param_names[]; + # define math_param_first_mu_glue math_param_ord_ord_spacing -extern void print_math_param(int param_code); extern void def_math_param(int param_code, int style_code, scaled value, int lvl); extern scaled get_math_param(int param_code, int style_code); @@ -307,9 +327,11 @@ typedef enum { RadicalKernAfterDegree, RadicalDegreeBottomRaisePercent, MinConnectorOverlap, + SubscriptShiftDownWithSuperscript, + MATH_param_last, } MATH_param_codes; -# define MATH_param_max MinConnectorOverlap +# define MATH_param_max MATH_param_last extern const char *MATH_param_names[]; diff --git a/Build/source/texk/web2c/luatexdir/textcodes.c b/Build/source/texk/web2c/luatexdir/textcodes.c index 2257f360446..fc637887e22 100644 --- a/Build/source/texk/web2c/luatexdir/textcodes.c +++ b/Build/source/texk/web2c/luatexdir/textcodes.c @@ -25,7 +25,7 @@ #include "commands.h" static const char __svn_version[] = - "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/textcodes.c $"; + "$Id$ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/textcodes.c $"; #define LCCODESTACK 8 #define LCCODEDEFAULT 0 @@ -138,7 +138,7 @@ static void undumpsfcodes(void) static sa_tree *catcode_heads = NULL; -static int catcode_max = 0; +static integer catcode_max = 0; static unsigned char *catcode_valid = NULL; #define CATCODE_MAX 65535 @@ -216,7 +216,7 @@ static void dumpcatcodes(void) static void undumpcatcodes(void) { - int total, h, k; + integer total, k, x; xfree(catcode_heads); xfree(catcode_valid); catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1)); @@ -226,9 +226,9 @@ static void undumpcatcodes(void) undump_int(catcode_max); undump_int(total); for (k = 0; k < total; k++) { - undump_int(h); - catcode_heads[h] = undump_sa_tree(); - catcode_valid[h] = 1; + undump_int(x); + catcode_heads[x] = undump_sa_tree(); + catcode_valid[x] = 1; } } diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.c b/Build/source/texk/web2c/luatexdir/utils/avlstuff.c index aa8522bf9dc..2afeed93d62 100644 --- a/Build/source/texk/web2c/luatexdir/utils/avlstuff.c +++ b/Build/source/texk/web2c/luatexdir/utils/avlstuff.c @@ -24,7 +24,7 @@ #include "avl.h" static const char __svn_version[] = - "$Id: avlstuff.c 2073 2009-03-21 10:06:50Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/utils/avlstuff.c $"; + "$Id: avlstuff.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/utils/avlstuff.c $"; static struct avl_table **PdfObjTree = NULL; diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.h b/Build/source/texk/web2c/luatexdir/utils/avlstuff.h index 6690d5036b8..5dd90bb5df2 100644 --- a/Build/source/texk/web2c/luatexdir/utils/avlstuff.h +++ b/Build/source/texk/web2c/luatexdir/utils/avlstuff.h @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with pdfTeX; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -$Id: avlstuff.h 2073 2009-03-21 10:06:50Z hhenkel $ +$Id: avlstuff.h 2271 2009-04-12 23:42:21Z oneiros $ */ #include "avl.h" diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.c b/Build/source/texk/web2c/luatexdir/utils/utils.c index 1096d9c08e9..d743bb240ae 100644 --- a/Build/source/texk/web2c/luatexdir/utils/utils.c +++ b/Build/source/texk/web2c/luatexdir/utils/utils.c @@ -43,7 +43,7 @@ #include "xpdf/config.h" /* just to get the xpdf version */ static const char __svn_version[] = - "$Id: utils.c 2085 2009-03-22 15:21:50Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/utils/utils.c $"; + "$Id: utils.c 2195 2009-03-31 14:09:50Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/utils/utils.c $"; #define check_nprintf(size_get, size_want) \ if ((unsigned)(size_get) >= (unsigned)(size_want)) \ @@ -1477,7 +1477,8 @@ void checkpdfrestore(scaledpos pos) 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)", diff.h, diff.v); + 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; diff --git a/Build/source/texk/web2c/luatexdir/utils/writezip.c b/Build/source/texk/web2c/luatexdir/utils/writezip.c index 8fb0a1a651b..4bbcd3a2531 100644 --- a/Build/source/texk/web2c/luatexdir/utils/writezip.c +++ b/Build/source/texk/web2c/luatexdir/utils/writezip.c @@ -23,7 +23,7 @@ #include <assert.h> static const char __svn_version[] = - "$Id: writezip.c 2073 2009-03-21 10:06:50Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/utils/writezip.c $"; + "$Id: writezip.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/utils/writezip.c $"; #define ZIP_BUF_SIZE 32768 |